use webpack for all builds
This commit is contained in:
parent
040dd6859c
commit
2f95d8c4fc
57
.babelrc
57
.babelrc
@ -1,57 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
"react",
|
||||
["env", {
|
||||
"modules": false,
|
||||
}],
|
||||
],
|
||||
"plugins": [
|
||||
"lodash",
|
||||
["babel-plugin-transform-builtin-extend", {
|
||||
"globals": ["Error"]
|
||||
}],
|
||||
["transform-runtime", {
|
||||
"useBuiltIns": true,
|
||||
"useESModules": true,
|
||||
}],
|
||||
["module-resolver", {
|
||||
"root": [
|
||||
"./src/components"
|
||||
],
|
||||
"alias": {
|
||||
"Actions": "./src/actions/",
|
||||
"Backends": "./src/backends/",
|
||||
"Constants": "./src/constants/",
|
||||
"Formats": "./src/formats/",
|
||||
"Integrations": "./src/integrations/",
|
||||
"Lib": "./src/lib/",
|
||||
"Reducers": "./src/reducers/",
|
||||
"Redux": "./src/redux/",
|
||||
"Routing": "./src/routing/",
|
||||
"ValueObjects": "./src/valueObjects/",
|
||||
}
|
||||
}],
|
||||
"transform-export-extensions",
|
||||
"transform-class-properties",
|
||||
"transform-object-rest-spread",
|
||||
["inline-svg", {
|
||||
"svgo": {
|
||||
"plugins": [
|
||||
{"removeViewBox": false},
|
||||
],
|
||||
},
|
||||
}],
|
||||
],
|
||||
"env": {
|
||||
"production": {
|
||||
"plugins": [
|
||||
["emotion", {"hoist": true}],
|
||||
],
|
||||
},
|
||||
"development": {
|
||||
"plugins": [
|
||||
["emotion", {"sourceMap": true, "autoLabel": true }],
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,3 +11,4 @@ manifest.yml
|
||||
website/data/contributors.json
|
||||
/coverage/
|
||||
.cache
|
||||
*.log
|
||||
|
54
babel.config.js
Normal file
54
babel.config.js
Normal file
@ -0,0 +1,54 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@babel/preset-react',
|
||||
['@babel/preset-env', {
|
||||
modules: false,
|
||||
}],
|
||||
],
|
||||
plugins: [
|
||||
'lodash',
|
||||
['babel-plugin-transform-builtin-extend', {
|
||||
globals: ['Error']
|
||||
}],
|
||||
['module-resolver', {
|
||||
root: [
|
||||
'./src/components'
|
||||
],
|
||||
alias: {
|
||||
Actions: './src/actions/',
|
||||
Backends: './src/backends/',
|
||||
Constants: './src/constants/',
|
||||
Formats: './src/formats/',
|
||||
Integrations: './src/integrations/',
|
||||
Lib: './src/lib/',
|
||||
Reducers: './src/reducers/',
|
||||
Redux: './src/redux/',
|
||||
Routing: './src/routing/',
|
||||
ValueObjects: './src/valueObjects/',
|
||||
}
|
||||
}],
|
||||
'transform-export-extensions',
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
'@babel/plugin-proposal-object-rest-spread',
|
||||
'@babel/plugin-proposal-export-default-from',
|
||||
['inline-svg', {
|
||||
svgo: {
|
||||
plugins: [
|
||||
{removeViewBox: false},
|
||||
],
|
||||
},
|
||||
}],
|
||||
],
|
||||
env: {
|
||||
production: {
|
||||
plugins: [
|
||||
['emotion', {hoist: true}],
|
||||
],
|
||||
},
|
||||
development: {
|
||||
plugins: [
|
||||
['emotion', {sourceMap: true, autoLabel: true}],
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
24
package.json
24
package.json
@ -17,9 +17,11 @@
|
||||
"pre-commit": "lint:staged",
|
||||
"scripts": {
|
||||
"bootstrap": "lerna bootstrap && lerna link --force-local",
|
||||
"start": "yarn bootstrap && yarn watch",
|
||||
"start": "npm run bootstrap && npm run watch",
|
||||
"watch": "lerna run watch --parallel",
|
||||
"clean": "cd packages && rimraf */.cache */*.js */*.css */*.svg */*.map"
|
||||
"build": "npm run clean && cross-env NODE_ENV=production lerna run build",
|
||||
"clean": "rimraf packages/*/dist",
|
||||
"reset": "npm run clean && lerna clean --yes"
|
||||
},
|
||||
"jest": {
|
||||
"moduleNameMapper": {
|
||||
@ -58,6 +60,11 @@
|
||||
"last 2 ChromeAndroid versions"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.0.0-beta.54",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.0.0-beta.54",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.54",
|
||||
"@babel/preset-env": "^7.0.0-beta.54",
|
||||
"@babel/preset-react": "^7.0.0-beta.54",
|
||||
"all-contributors-cli": "^4.4.0",
|
||||
"babel-plugin-emotion": "^9.2.4",
|
||||
"babel-plugin-inline-import": "^3.0.0",
|
||||
@ -65,13 +72,8 @@
|
||||
"babel-plugin-lodash": "^3.3.4",
|
||||
"babel-plugin-module-resolver": "^3.0.0",
|
||||
"babel-plugin-transform-builtin-extend": "^1.1.2",
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
"babel-plugin-transform-export-extensions": "^6.22.0",
|
||||
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-preset-env": "^1.6.0",
|
||||
"babel-preset-react": "^6.23.0",
|
||||
"cross-env": "^5.1.4",
|
||||
"deep-equal": "^1.0.1",
|
||||
"enzyme": "^3.1.0",
|
||||
@ -84,10 +86,14 @@
|
||||
"postcss-loader": "^2.1.3",
|
||||
"raf": "^3.4.0",
|
||||
"react-test-renderer": "^16.0.0",
|
||||
"rimraf": "^2.6.2"
|
||||
"rimraf": "^2.6.2",
|
||||
"rollup-plugin-babel": "^3.0.7"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
],
|
||||
"private": true
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"friendly-errors-webpack-plugin": "^1.7.0"
|
||||
}
|
||||
}
|
||||
|
3
packages/netlify-cms-backend-github/babel.config.js
Normal file
3
packages/netlify-cms-backend-github/babel.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
const config = require('../../babel.config.js');
|
||||
|
||||
module.exports = config;
|
@ -3,28 +3,38 @@
|
||||
"description": "GitHub backend for Netlify CMS",
|
||||
"version": "2.0.0-alpha.0",
|
||||
"license": "MIT",
|
||||
"main": "dist/netlify-cms-backend-github.js",
|
||||
"keywords": [
|
||||
"netlify",
|
||||
"netlify-cms",
|
||||
"backend",
|
||||
"github"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"watch": "parcel watch src/*.js --out-dir . --no-cache",
|
||||
"build": "parcel build src/*.js --out-dir . --no-cache"
|
||||
"watch": "webpack -w",
|
||||
"build": "cross-env NODE_ENV=production webpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"js-base64": "^2.4.8",
|
||||
"lodash": "^4.17.10",
|
||||
"netlify-cms-lib-auth": "file:../netlify-cms-lib-auth",
|
||||
"netlify-cms-lib-util": "file:../netlify-cms-lib-util",
|
||||
"netlify-cms-ui-default": "file:../netlify-cms-ui-default",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^16.4.1",
|
||||
"react-emotion": "^9.2.6",
|
||||
"semaphore": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"parcel-bundler": "^1.9.4"
|
||||
"@babel/cli": "^7.0.0-beta.54",
|
||||
"@babel/core": "^7.0.0-beta.54",
|
||||
"cross-env": "^5.2.0",
|
||||
"rollup": "^0.63.2",
|
||||
"rollup-plugin-babel": "^4.0.0-beta.7",
|
||||
"webpack": "^4.16.1",
|
||||
"webpack-cli": "^3.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"netlify-cms-lib-auth": "2.0.0-alpha.0",
|
||||
"netlify-cms-lib-util": "2.0.0-alpha.0",
|
||||
"netlify-cms-ui-default": "2.0.0-alpha.0",
|
||||
"lodash": "^4.17.10",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^16.4.1",
|
||||
"react-emotion": "^9.2.6"
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
import localForage from "netlify-cms-lib-util/localForage";
|
||||
import { localForage } from "netlify-cms-lib-util";
|
||||
import { Base64 } from "js-base64";
|
||||
import { uniq, initial, last, get, find, hasIn, partial } from "lodash";
|
||||
import { filterPromises, resolvePromiseProperties } from "netlify-cms-lib-util/promise";
|
||||
import APIError from "netlify-cms-lib-util/APIError";
|
||||
import EditorialWorkflowError from "netlify-cms-lib-util/EditorialWorkflowError";
|
||||
import { filterPromises, resolvePromiseProperties } from "netlify-cms-lib-util";
|
||||
import { APIError, EditorialWorkflowError } from "netlify-cms-lib-util";
|
||||
|
||||
const CMS_BRANCH_PREFIX = 'cms/';
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'react-emotion';
|
||||
import Authenticator from 'netlify-cms-lib-auth/netlify-auth';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { buttons, shadows } from 'netlify-cms-ui-default/styles';
|
||||
import { NetlifyAuthenticator } from 'netlify-cms-lib-auth';
|
||||
import { Icon, buttons, shadows } from 'netlify-cms-ui-default';
|
||||
|
||||
const StyledAuthenticationPage = styled.section`
|
||||
display: flex;
|
||||
@ -53,7 +52,7 @@ export default class AuthenticationPage extends React.Component {
|
||||
site_id: (document.location.host.split(':')[0] === 'localhost') ? 'cms.netlify.com' : this.props.siteId,
|
||||
auth_endpoint: this.props.authEndpoint,
|
||||
};
|
||||
const auth = new Authenticator(cfg);
|
||||
const auth = new NetlifyAuthenticator(cfg);
|
||||
|
||||
auth.authenticate({ provider: 'github', scope: 'repo' }, (err, data) => {
|
||||
if (err) {
|
||||
|
197
packages/netlify-cms-backend-github/src/implementation.js
Normal file
197
packages/netlify-cms-backend-github/src/implementation.js
Normal file
@ -0,0 +1,197 @@
|
||||
import trimStart from 'lodash/trimStart';
|
||||
import semaphore from "semaphore";
|
||||
import AuthenticationPage from "./AuthenticationPage";
|
||||
import API from "./API";
|
||||
|
||||
const MAX_CONCURRENT_DOWNLOADS = 10;
|
||||
|
||||
export default class GitHub {
|
||||
constructor(config, options={}) {
|
||||
this.config = config;
|
||||
this.options = {
|
||||
proxied: false,
|
||||
API: null,
|
||||
...options,
|
||||
};
|
||||
|
||||
if (!this.options.proxied && config.getIn(["backend", "repo"]) == null) {
|
||||
throw new Error("The GitHub backend needs a \"repo\" in the backend configuration.");
|
||||
}
|
||||
|
||||
this.api = this.options.API || null;
|
||||
|
||||
this.repo = config.getIn(["backend", "repo"], "");
|
||||
this.branch = config.getIn(["backend", "branch"], "master").trim();
|
||||
this.api_root = config.getIn(["backend", "api_root"], "https://api.github.com");
|
||||
this.token = '';
|
||||
this.squash_merges = config.getIn(["backend", "squash_merges"]);
|
||||
}
|
||||
|
||||
authComponent() {
|
||||
return AuthenticationPage;
|
||||
}
|
||||
|
||||
restoreUser(user) {
|
||||
return this.authenticate(user);
|
||||
}
|
||||
|
||||
authenticate(state) {
|
||||
this.token = state.token;
|
||||
this.api = new API({ token: this.token, branch: this.branch, repo: this.repo, api_root: this.api_root, squash_merges: this.squash_merges });
|
||||
return this.api.user().then(user =>
|
||||
this.api.hasWriteAccess().then((isCollab) => {
|
||||
// Unauthorized user
|
||||
if (!isCollab) throw new Error("Your GitHub user account does not have access to this repo.");
|
||||
// Authorized user
|
||||
user.token = state.token;
|
||||
return user;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.token = null;
|
||||
return;
|
||||
}
|
||||
|
||||
getToken() {
|
||||
return Promise.resolve(this.token);
|
||||
}
|
||||
|
||||
entriesByFolder(collection, extension) {
|
||||
return this.api.listFiles(collection.get("folder"))
|
||||
.then(files => files.filter(file => file.name.endsWith('.' + extension)))
|
||||
.then(this.fetchFiles);
|
||||
}
|
||||
|
||||
entriesByFiles(collection) {
|
||||
const files = collection.get("files").map(collectionFile => ({
|
||||
path: collectionFile.get("file"),
|
||||
label: collectionFile.get("label"),
|
||||
}));
|
||||
return this.fetchFiles(files);
|
||||
}
|
||||
|
||||
fetchFiles = (files) => {
|
||||
const sem = semaphore(MAX_CONCURRENT_DOWNLOADS);
|
||||
const promises = [];
|
||||
files.forEach((file) => {
|
||||
promises.push(new Promise((resolve, reject) => (
|
||||
sem.take(() => this.api.readFile(file.path, file.sha).then((data) => {
|
||||
resolve({ file, data });
|
||||
sem.leave();
|
||||
}).catch((err = true) => {
|
||||
sem.leave();
|
||||
console.error(`failed to load file from GitHub: ${file.path}`);
|
||||
resolve({ error: err });
|
||||
}))
|
||||
)));
|
||||
});
|
||||
return Promise.all(promises)
|
||||
.then(loadedEntries => loadedEntries.filter(loadedEntry => !loadedEntry.error));
|
||||
};
|
||||
|
||||
// Fetches a single entry.
|
||||
getEntry(collection, slug, path) {
|
||||
return this.api.readFile(path).then(data => ({
|
||||
file: { path },
|
||||
data,
|
||||
}));
|
||||
}
|
||||
|
||||
getMedia() {
|
||||
return this.api.listFiles(this.config.get('media_folder'))
|
||||
.then(files => files.map(({ sha, name, size, download_url, path }) => {
|
||||
const url = new URL(download_url);
|
||||
if (url.pathname.match(/.svg$/)) {
|
||||
url.search += (url.search.slice(1) === '' ? '?' : '&') + 'sanitize=true';
|
||||
}
|
||||
return { id: sha, name, size, url: url.href, path };
|
||||
}));
|
||||
}
|
||||
|
||||
persistEntry(entry, mediaFiles = [], options = {}) {
|
||||
return this.api.persistFiles(entry, mediaFiles, options);
|
||||
}
|
||||
|
||||
async persistMedia(mediaFile, options = {}) {
|
||||
try {
|
||||
const response = await this.api.persistFiles(null, [mediaFile], options);
|
||||
|
||||
const { sha, value, size, path, fileObj } = mediaFile;
|
||||
const url = URL.createObjectURL(fileObj);
|
||||
return { id: sha, name: value, size: fileObj.size, url, path: trimStart(path, '/') };
|
||||
}
|
||||
catch(error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
deleteFile(path, commitMessage, options) {
|
||||
return this.api.deleteFile(path, commitMessage, options);
|
||||
}
|
||||
|
||||
unpublishedEntries() {
|
||||
return this.api.listUnpublishedBranches().then((branches) => {
|
||||
const sem = semaphore(MAX_CONCURRENT_DOWNLOADS);
|
||||
const promises = [];
|
||||
branches.map((branch) => {
|
||||
promises.push(new Promise((resolve, reject) => {
|
||||
const slug = branch.ref.split("refs/heads/cms/").pop();
|
||||
return sem.take(() => this.api.readUnpublishedBranchFile(slug).then((data) => {
|
||||
if (data === null || data === undefined) {
|
||||
resolve(null);
|
||||
sem.leave();
|
||||
} else {
|
||||
const path = data.metaData.objects.entry.path;
|
||||
resolve({
|
||||
slug,
|
||||
file: { path },
|
||||
data: data.fileData,
|
||||
metaData: data.metaData,
|
||||
isModification: data.isModification,
|
||||
});
|
||||
sem.leave();
|
||||
}
|
||||
}).catch((err) => {
|
||||
sem.leave();
|
||||
resolve(null);
|
||||
}));
|
||||
}));
|
||||
});
|
||||
return Promise.all(promises);
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.message === "Not Found") {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
return error;
|
||||
});
|
||||
}
|
||||
|
||||
unpublishedEntry(collection, slug) {
|
||||
return this.api.readUnpublishedBranchFile(slug)
|
||||
.then((data) => {
|
||||
if (!data) return null;
|
||||
return {
|
||||
slug,
|
||||
file: { path: data.metaData.objects.entry.path },
|
||||
data: data.fileData,
|
||||
metaData: data.metaData,
|
||||
isModification: data.isModification,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
updateUnpublishedEntryStatus(collection, slug, newStatus) {
|
||||
return this.api.updateUnpublishedEntryStatus(collection, slug, newStatus);
|
||||
}
|
||||
|
||||
deleteUnpublishedEntry(collection, slug) {
|
||||
return this.api.deleteUnpublishedEntry(collection, slug);
|
||||
}
|
||||
publishUnpublishedEntry(collection, slug) {
|
||||
return this.api.publishUnpublishedEntry(collection, slug);
|
||||
}
|
||||
}
|
@ -1,197 +1,4 @@
|
||||
import trimStart from 'lodash/trimStart';
|
||||
import semaphore from "semaphore";
|
||||
import AuthenticationPage from "./AuthenticationPage";
|
||||
import API from "./API";
|
||||
export GitHubBackend from './implementation';
|
||||
export API from './API';
|
||||
export AuthenticationPage from './AuthenticationPage';
|
||||
|
||||
const MAX_CONCURRENT_DOWNLOADS = 10;
|
||||
|
||||
export default class GitHub {
|
||||
constructor(config, options={}) {
|
||||
this.config = config;
|
||||
this.options = {
|
||||
proxied: false,
|
||||
API: null,
|
||||
...options,
|
||||
};
|
||||
|
||||
if (!this.options.proxied && config.getIn(["backend", "repo"]) == null) {
|
||||
throw new Error("The GitHub backend needs a \"repo\" in the backend configuration.");
|
||||
}
|
||||
|
||||
this.api = this.options.API || null;
|
||||
|
||||
this.repo = config.getIn(["backend", "repo"], "");
|
||||
this.branch = config.getIn(["backend", "branch"], "master").trim();
|
||||
this.api_root = config.getIn(["backend", "api_root"], "https://api.github.com");
|
||||
this.token = '';
|
||||
this.squash_merges = config.getIn(["backend", "squash_merges"]);
|
||||
}
|
||||
|
||||
authComponent() {
|
||||
return AuthenticationPage;
|
||||
}
|
||||
|
||||
restoreUser(user) {
|
||||
return this.authenticate(user);
|
||||
}
|
||||
|
||||
authenticate(state) {
|
||||
this.token = state.token;
|
||||
this.api = new API({ token: this.token, branch: this.branch, repo: this.repo, api_root: this.api_root, squash_merges: this.squash_merges });
|
||||
return this.api.user().then(user =>
|
||||
this.api.hasWriteAccess().then((isCollab) => {
|
||||
// Unauthorized user
|
||||
if (!isCollab) throw new Error("Your GitHub user account does not have access to this repo.");
|
||||
// Authorized user
|
||||
user.token = state.token;
|
||||
return user;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.token = null;
|
||||
return;
|
||||
}
|
||||
|
||||
getToken() {
|
||||
return Promise.resolve(this.token);
|
||||
}
|
||||
|
||||
entriesByFolder(collection, extension) {
|
||||
return this.api.listFiles(collection.get("folder"))
|
||||
.then(files => files.filter(file => file.name.endsWith('.' + extension)))
|
||||
.then(this.fetchFiles);
|
||||
}
|
||||
|
||||
entriesByFiles(collection) {
|
||||
const files = collection.get("files").map(collectionFile => ({
|
||||
path: collectionFile.get("file"),
|
||||
label: collectionFile.get("label"),
|
||||
}));
|
||||
return this.fetchFiles(files);
|
||||
}
|
||||
|
||||
fetchFiles = (files) => {
|
||||
const sem = semaphore(MAX_CONCURRENT_DOWNLOADS);
|
||||
const promises = [];
|
||||
files.forEach((file) => {
|
||||
promises.push(new Promise((resolve, reject) => (
|
||||
sem.take(() => this.api.readFile(file.path, file.sha).then((data) => {
|
||||
resolve({ file, data });
|
||||
sem.leave();
|
||||
}).catch((err = true) => {
|
||||
sem.leave();
|
||||
console.error(`failed to load file from GitHub: ${file.path}`);
|
||||
resolve({ error: err });
|
||||
}))
|
||||
)));
|
||||
});
|
||||
return Promise.all(promises)
|
||||
.then(loadedEntries => loadedEntries.filter(loadedEntry => !loadedEntry.error));
|
||||
};
|
||||
|
||||
// Fetches a single entry.
|
||||
getEntry(collection, slug, path) {
|
||||
return this.api.readFile(path).then(data => ({
|
||||
file: { path },
|
||||
data,
|
||||
}));
|
||||
}
|
||||
|
||||
getMedia() {
|
||||
return this.api.listFiles(this.config.get('media_folder'))
|
||||
.then(files => files.map(({ sha, name, size, download_url, path }) => {
|
||||
const url = new URL(download_url);
|
||||
if (url.pathname.match(/.svg$/)) {
|
||||
url.search += (url.search.slice(1) === '' ? '?' : '&') + 'sanitize=true';
|
||||
}
|
||||
return { id: sha, name, size, url: url.href, path };
|
||||
}));
|
||||
}
|
||||
|
||||
persistEntry(entry, mediaFiles = [], options = {}) {
|
||||
return this.api.persistFiles(entry, mediaFiles, options);
|
||||
}
|
||||
|
||||
async persistMedia(mediaFile, options = {}) {
|
||||
try {
|
||||
const response = await this.api.persistFiles(null, [mediaFile], options);
|
||||
|
||||
const { sha, value, size, path, fileObj } = mediaFile;
|
||||
const url = URL.createObjectURL(fileObj);
|
||||
return { id: sha, name: value, size: fileObj.size, url, path: trimStart(path, '/') };
|
||||
}
|
||||
catch(error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
deleteFile(path, commitMessage, options) {
|
||||
return this.api.deleteFile(path, commitMessage, options);
|
||||
}
|
||||
|
||||
unpublishedEntries() {
|
||||
return this.api.listUnpublishedBranches().then((branches) => {
|
||||
const sem = semaphore(MAX_CONCURRENT_DOWNLOADS);
|
||||
const promises = [];
|
||||
branches.map((branch) => {
|
||||
promises.push(new Promise((resolve, reject) => {
|
||||
const slug = branch.ref.split("refs/heads/cms/").pop();
|
||||
return sem.take(() => this.api.readUnpublishedBranchFile(slug).then((data) => {
|
||||
if (data === null || data === undefined) {
|
||||
resolve(null);
|
||||
sem.leave();
|
||||
} else {
|
||||
const path = data.metaData.objects.entry.path;
|
||||
resolve({
|
||||
slug,
|
||||
file: { path },
|
||||
data: data.fileData,
|
||||
metaData: data.metaData,
|
||||
isModification: data.isModification,
|
||||
});
|
||||
sem.leave();
|
||||
}
|
||||
}).catch((err) => {
|
||||
sem.leave();
|
||||
resolve(null);
|
||||
}));
|
||||
}));
|
||||
});
|
||||
return Promise.all(promises);
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.message === "Not Found") {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
return error;
|
||||
});
|
||||
}
|
||||
|
||||
unpublishedEntry(collection, slug) {
|
||||
return this.api.readUnpublishedBranchFile(slug)
|
||||
.then((data) => {
|
||||
if (!data) return null;
|
||||
return {
|
||||
slug,
|
||||
file: { path: data.metaData.objects.entry.path },
|
||||
data: data.fileData,
|
||||
metaData: data.metaData,
|
||||
isModification: data.isModification,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
updateUnpublishedEntryStatus(collection, slug, newStatus) {
|
||||
return this.api.updateUnpublishedEntryStatus(collection, slug, newStatus);
|
||||
}
|
||||
|
||||
deleteUnpublishedEntry(collection, slug) {
|
||||
return this.api.deleteUnpublishedEntry(collection, slug);
|
||||
}
|
||||
publishUnpublishedEntry(collection, slug) {
|
||||
return this.api.publishUnpublishedEntry(collection, slug);
|
||||
}
|
||||
}
|
||||
|
1
packages/netlify-cms-backend-github/webpack.config.js
Normal file
1
packages/netlify-cms-backend-github/webpack.config.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('../../webpack.config.js');
|
3
packages/netlify-cms-backend-test/babel.config.js
Normal file
3
packages/netlify-cms-backend-test/babel.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
const config = require('../../babel.config.js');
|
||||
|
||||
module.exports = config;
|
@ -3,28 +3,37 @@
|
||||
"description": "Development testing backend for Netlify CMS",
|
||||
"version": "2.0.0-alpha.0",
|
||||
"license": "MIT",
|
||||
"main": "dist/netlify-cms-backend-test.js",
|
||||
"keywords": [
|
||||
"netlify",
|
||||
"netlify-cms",
|
||||
"backend"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"watch": "parcel watch src/*.js --out-dir . --no-cache",
|
||||
"build": "parcel build src/*.js --out-dir . --no-cache"
|
||||
"watch": "webpack -w",
|
||||
"build": "cross-env NODE_ENV=production webpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"immutable": "^3.8.2",
|
||||
"lodash": "^4.17.10",
|
||||
"netlify": "^1.2.0",
|
||||
"netlify-cms-lib-util": "file:../netlify-cms-lib-util",
|
||||
"netlify-cms-ui-default": "file:../netlify-cms-ui-default",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^16.4.1",
|
||||
"react-emotion": "^9.2.6",
|
||||
"react-immutable-proptypes": "^2.1.0",
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"parcel-bundler": "^1.9.4"
|
||||
"@babel/cli": "^7.0.0-beta.54",
|
||||
"@babel/core": "^7.0.0-beta.54",
|
||||
"cross-env": "^5.2.0",
|
||||
"rollup": "^0.63.2",
|
||||
"rollup-plugin-babel": "^4.0.0-beta.7",
|
||||
"webpack": "^4.16.1",
|
||||
"webpack-cli": "^3.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"immutable": "^3.8.2",
|
||||
"lodash": "^4.17.10",
|
||||
"netlify-cms-lib-util": "2.0.0-alpha.0",
|
||||
"netlify-cms-ui-default": "2.0.0-alpha.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^16.4.1",
|
||||
"react-emotion": "^9.2.6",
|
||||
"react-immutable-proptypes": "^2.1.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { Icon } from 'netlify-cms-ui-default';
|
||||
|
||||
export default class AuthenticationPage extends React.Component {
|
||||
static propTypes = {
|
||||
|
225
packages/netlify-cms-backend-test/src/implementation.js
Normal file
225
packages/netlify-cms-backend-test/src/implementation.js
Normal file
@ -0,0 +1,225 @@
|
||||
import { fromJS } from 'immutable';
|
||||
import { remove, attempt, isError, take } from 'lodash';
|
||||
import uuid from 'uuid/v4';
|
||||
import { EditorialWorkflowError } from 'netlify-cms-lib-util';
|
||||
import { Cursor, CURSOR_COMPATIBILITY_SYMBOL } from 'netlify-cms-lib-util';
|
||||
import AuthenticationPage from './AuthenticationPage';
|
||||
|
||||
window.repoFiles = window.repoFiles || {};
|
||||
window.repoFilesUnpublished = window.repoFilesUnpublished || [];
|
||||
|
||||
function getFile(path) {
|
||||
const segments = path.split('/');
|
||||
let obj = window.repoFiles;
|
||||
while (obj && segments.length) {
|
||||
obj = obj[segments.shift()];
|
||||
}
|
||||
return obj || {};
|
||||
}
|
||||
|
||||
const pageSize = 10;
|
||||
|
||||
const getCursor = (collection, extension, entries, index) => {
|
||||
const count = entries.length;
|
||||
const pageCount = Math.floor(count / pageSize);
|
||||
return Cursor.create({
|
||||
actions: [
|
||||
...(index < pageCount ? ["next", "last"] : []),
|
||||
...(index > 0 ? ["prev", "first"] : []),
|
||||
],
|
||||
meta: { index, count, pageSize, pageCount },
|
||||
data: { collection, extension, index, pageCount },
|
||||
});
|
||||
};
|
||||
|
||||
const getFolderEntries = (folder, extension) => {
|
||||
return Object.keys(window.repoFiles[folder] || {})
|
||||
.filter(path => path.endsWith(`.${ extension }`))
|
||||
.map(path => ({
|
||||
file: { path: `${ folder }/${ path }` },
|
||||
data: window.repoFiles[folder][path].content,
|
||||
}))
|
||||
.reverse();
|
||||
};
|
||||
|
||||
export default class TestRepo {
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
this.assets = [];
|
||||
this.initialStatus = config.initialStatus;
|
||||
}
|
||||
|
||||
authComponent() {
|
||||
return AuthenticationPage;
|
||||
}
|
||||
|
||||
restoreUser(user) {
|
||||
return this.authenticate(user);
|
||||
}
|
||||
|
||||
authenticate() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
logout() {
|
||||
return null;
|
||||
}
|
||||
|
||||
getToken() {
|
||||
return Promise.resolve('');
|
||||
}
|
||||
|
||||
traverseCursor(cursor, action) {
|
||||
const { collection, extension, index, pageCount } = cursor.data.toObject();
|
||||
const newIndex = (() => {
|
||||
if (action === "next") { return index + 1; }
|
||||
if (action === "prev") { return index - 1; }
|
||||
if (action === "first") { return 0; }
|
||||
if (action === "last") { return pageCount; }
|
||||
})();
|
||||
// TODO: stop assuming cursors are for collections
|
||||
const allEntries = getFolderEntries(collection.get('folder'), extension);
|
||||
const entries = allEntries.slice(newIndex * pageSize, (newIndex * pageSize) + pageSize);
|
||||
const newCursor = getCursor(collection, extension, allEntries, newIndex);
|
||||
return Promise.resolve({ entries, cursor: newCursor });
|
||||
}
|
||||
|
||||
entriesByFolder(collection, extension) {
|
||||
const folder = collection.get('folder');
|
||||
const entries = folder ? getFolderEntries(folder, extension) : [];
|
||||
const cursor = getCursor(collection, extension, entries, 0);
|
||||
const ret = take(entries, pageSize);
|
||||
ret[CURSOR_COMPATIBILITY_SYMBOL] = cursor;
|
||||
return Promise.resolve(ret);
|
||||
}
|
||||
|
||||
entriesByFiles(collection) {
|
||||
const files = collection.get('files').map(collectionFile => ({
|
||||
path: collectionFile.get('file'),
|
||||
label: collectionFile.get('label'),
|
||||
}));
|
||||
return Promise.all(files.map(file => ({
|
||||
file,
|
||||
data: getFile(file.path).content,
|
||||
})));
|
||||
}
|
||||
|
||||
getEntry(collection, slug, path) {
|
||||
return Promise.resolve({
|
||||
file: { path },
|
||||
data: getFile(path).content,
|
||||
});
|
||||
}
|
||||
|
||||
unpublishedEntries() {
|
||||
return Promise.resolve(window.repoFilesUnpublished);
|
||||
}
|
||||
|
||||
unpublishedEntry(collection, slug) {
|
||||
const entry = window.repoFilesUnpublished.find(e => (
|
||||
e.metaData.collection === collection.get('name') && e.slug === slug
|
||||
));
|
||||
if (!entry) {
|
||||
return Promise.reject(new EditorialWorkflowError('content is not under editorial workflow', true));
|
||||
}
|
||||
return Promise.resolve(entry);
|
||||
}
|
||||
|
||||
deleteUnpublishedEntry(collection, slug) {
|
||||
const unpubStore = window.repoFilesUnpublished;
|
||||
const existingEntryIndex = unpubStore.findIndex(e => (
|
||||
e.metaData.collection === collection && e.slug === slug
|
||||
));
|
||||
unpubStore.splice(existingEntryIndex, 1);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
persistEntry({ path, raw, slug }, mediaFiles = [], options = {}) {
|
||||
if (options.useWorkflow) {
|
||||
const unpubStore = window.repoFilesUnpublished;
|
||||
const existingEntryIndex = unpubStore.findIndex(e => e.file.path === path);
|
||||
if (existingEntryIndex >= 0) {
|
||||
const unpubEntry = { ...unpubStore[existingEntryIndex], data: raw };
|
||||
unpubEntry.title = options.parsedData && options.parsedData.title;
|
||||
unpubEntry.description = options.parsedData && options.parsedData.description;
|
||||
unpubStore.splice(existingEntryIndex, 1, unpubEntry);
|
||||
} else {
|
||||
const unpubEntry = {
|
||||
data: raw,
|
||||
file: {
|
||||
path,
|
||||
},
|
||||
metaData: {
|
||||
collection: options.collectionName,
|
||||
status: this.initialStatus,
|
||||
title: options.parsedData && options.parsedData.title,
|
||||
description: options.parsedData && options.parsedData.description,
|
||||
},
|
||||
slug,
|
||||
};
|
||||
unpubStore.push(unpubEntry);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const newEntry = options.newEntry || false;
|
||||
const folder = path.substring(0, path.lastIndexOf('/'));
|
||||
const fileName = path.substring(path.lastIndexOf('/') + 1);
|
||||
window.repoFiles[folder] = window.repoFiles[folder] || {};
|
||||
window.repoFiles[folder][fileName] = window.repoFiles[folder][fileName] || {};
|
||||
if (newEntry) {
|
||||
window.repoFiles[folder][fileName] = { content: raw };
|
||||
} else {
|
||||
window.repoFiles[folder][fileName].content = raw;
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
updateUnpublishedEntryStatus(collection, slug, newStatus) {
|
||||
const unpubStore = window.repoFilesUnpublished;
|
||||
const entryIndex = unpubStore.findIndex(e => (
|
||||
e.metaData.collection === collection && e.slug === slug
|
||||
));
|
||||
unpubStore[entryIndex].metaData.status = newStatus;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
publishUnpublishedEntry(collection, slug) {
|
||||
const unpubStore = window.repoFilesUnpublished;
|
||||
const unpubEntryIndex = unpubStore.findIndex(e => (
|
||||
e.metaData.collection === collection && e.slug === slug
|
||||
));
|
||||
const unpubEntry = unpubStore[unpubEntryIndex];
|
||||
const entry = { raw: unpubEntry.data, slug: unpubEntry.slug, path: unpubEntry.file.path };
|
||||
unpubStore.splice(unpubEntryIndex, 1);
|
||||
return this.persistEntry(entry);
|
||||
}
|
||||
getMedia() {
|
||||
return Promise.resolve(this.assets);
|
||||
}
|
||||
|
||||
persistMedia({ fileObj }) {
|
||||
const { name, size } = fileObj;
|
||||
const objectUrl = attempt(window.URL.createObjectURL, fileObj);
|
||||
const url = isError(objectUrl) ? '' : objectUrl;
|
||||
const normalizedAsset = { id: uuid(), name, size, path: url, url };
|
||||
|
||||
this.assets.push(normalizedAsset);
|
||||
return Promise.resolve(normalizedAsset);
|
||||
}
|
||||
|
||||
deleteFile(path, commitMessage) {
|
||||
const assetIndex = this.assets.findIndex(asset => asset.path === path);
|
||||
if (assetIndex > -1) {
|
||||
this.assets.splice(assetIndex, 1);
|
||||
}
|
||||
|
||||
else {
|
||||
const folder = path.substring(0, path.lastIndexOf('/'));
|
||||
const fileName = path.substring(path.lastIndexOf('/') + 1);
|
||||
delete window.repoFiles[folder][fileName];
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
@ -1,225 +1,2 @@
|
||||
import { fromJS } from 'immutable';
|
||||
import { remove, attempt, isError, take } from 'lodash';
|
||||
import uuid from 'uuid/v4';
|
||||
import EditorialWorkflowError from 'netlify-cms-lib-util/EditorialWorkflowError';
|
||||
import Cursor, { CURSOR_COMPATIBILITY_SYMBOL } from 'netlify-cms-lib-util/Cursor'
|
||||
import AuthenticationPage from './AuthenticationPage';
|
||||
|
||||
window.repoFiles = window.repoFiles || {};
|
||||
window.repoFilesUnpublished = window.repoFilesUnpublished || [];
|
||||
|
||||
function getFile(path) {
|
||||
const segments = path.split('/');
|
||||
let obj = window.repoFiles;
|
||||
while (obj && segments.length) {
|
||||
obj = obj[segments.shift()];
|
||||
}
|
||||
return obj || {};
|
||||
}
|
||||
|
||||
const pageSize = 10;
|
||||
|
||||
const getCursor = (collection, extension, entries, index) => {
|
||||
const count = entries.length;
|
||||
const pageCount = Math.floor(count / pageSize);
|
||||
return Cursor.create({
|
||||
actions: [
|
||||
...(index < pageCount ? ["next", "last"] : []),
|
||||
...(index > 0 ? ["prev", "first"] : []),
|
||||
],
|
||||
meta: { index, count, pageSize, pageCount },
|
||||
data: { collection, extension, index, pageCount },
|
||||
});
|
||||
};
|
||||
|
||||
const getFolderEntries = (folder, extension) => {
|
||||
return Object.keys(window.repoFiles[folder] || {})
|
||||
.filter(path => path.endsWith(`.${ extension }`))
|
||||
.map(path => ({
|
||||
file: { path: `${ folder }/${ path }` },
|
||||
data: window.repoFiles[folder][path].content,
|
||||
}))
|
||||
.reverse();
|
||||
};
|
||||
|
||||
export default class TestRepo {
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
this.assets = [];
|
||||
this.initialStatus = config.initialStatus;
|
||||
}
|
||||
|
||||
authComponent() {
|
||||
return AuthenticationPage;
|
||||
}
|
||||
|
||||
restoreUser(user) {
|
||||
return this.authenticate(user);
|
||||
}
|
||||
|
||||
authenticate() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
logout() {
|
||||
return null;
|
||||
}
|
||||
|
||||
getToken() {
|
||||
return Promise.resolve('');
|
||||
}
|
||||
|
||||
traverseCursor(cursor, action) {
|
||||
const { collection, extension, index, pageCount } = cursor.data.toObject();
|
||||
const newIndex = (() => {
|
||||
if (action === "next") { return index + 1; }
|
||||
if (action === "prev") { return index - 1; }
|
||||
if (action === "first") { return 0; }
|
||||
if (action === "last") { return pageCount; }
|
||||
})();
|
||||
// TODO: stop assuming cursors are for collections
|
||||
const allEntries = getFolderEntries(collection.get('folder'), extension);
|
||||
const entries = allEntries.slice(newIndex * pageSize, (newIndex * pageSize) + pageSize);
|
||||
const newCursor = getCursor(collection, extension, allEntries, newIndex);
|
||||
return Promise.resolve({ entries, cursor: newCursor });
|
||||
}
|
||||
|
||||
entriesByFolder(collection, extension) {
|
||||
const folder = collection.get('folder');
|
||||
const entries = folder ? getFolderEntries(folder, extension) : [];
|
||||
const cursor = getCursor(collection, extension, entries, 0);
|
||||
const ret = take(entries, pageSize);
|
||||
ret[CURSOR_COMPATIBILITY_SYMBOL] = cursor;
|
||||
return Promise.resolve(ret);
|
||||
}
|
||||
|
||||
entriesByFiles(collection) {
|
||||
const files = collection.get('files').map(collectionFile => ({
|
||||
path: collectionFile.get('file'),
|
||||
label: collectionFile.get('label'),
|
||||
}));
|
||||
return Promise.all(files.map(file => ({
|
||||
file,
|
||||
data: getFile(file.path).content,
|
||||
})));
|
||||
}
|
||||
|
||||
getEntry(collection, slug, path) {
|
||||
return Promise.resolve({
|
||||
file: { path },
|
||||
data: getFile(path).content,
|
||||
});
|
||||
}
|
||||
|
||||
unpublishedEntries() {
|
||||
return Promise.resolve(window.repoFilesUnpublished);
|
||||
}
|
||||
|
||||
unpublishedEntry(collection, slug) {
|
||||
const entry = window.repoFilesUnpublished.find(e => (
|
||||
e.metaData.collection === collection.get('name') && e.slug === slug
|
||||
));
|
||||
if (!entry) {
|
||||
return Promise.reject(new EditorialWorkflowError('content is not under editorial workflow', true));
|
||||
}
|
||||
return Promise.resolve(entry);
|
||||
}
|
||||
|
||||
deleteUnpublishedEntry(collection, slug) {
|
||||
const unpubStore = window.repoFilesUnpublished;
|
||||
const existingEntryIndex = unpubStore.findIndex(e => (
|
||||
e.metaData.collection === collection && e.slug === slug
|
||||
));
|
||||
unpubStore.splice(existingEntryIndex, 1);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
persistEntry({ path, raw, slug }, mediaFiles = [], options = {}) {
|
||||
if (options.useWorkflow) {
|
||||
const unpubStore = window.repoFilesUnpublished;
|
||||
const existingEntryIndex = unpubStore.findIndex(e => e.file.path === path);
|
||||
if (existingEntryIndex >= 0) {
|
||||
const unpubEntry = { ...unpubStore[existingEntryIndex], data: raw };
|
||||
unpubEntry.title = options.parsedData && options.parsedData.title;
|
||||
unpubEntry.description = options.parsedData && options.parsedData.description;
|
||||
unpubStore.splice(existingEntryIndex, 1, unpubEntry);
|
||||
} else {
|
||||
const unpubEntry = {
|
||||
data: raw,
|
||||
file: {
|
||||
path,
|
||||
},
|
||||
metaData: {
|
||||
collection: options.collectionName,
|
||||
status: this.initialStatus,
|
||||
title: options.parsedData && options.parsedData.title,
|
||||
description: options.parsedData && options.parsedData.description,
|
||||
},
|
||||
slug,
|
||||
};
|
||||
unpubStore.push(unpubEntry);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const newEntry = options.newEntry || false;
|
||||
const folder = path.substring(0, path.lastIndexOf('/'));
|
||||
const fileName = path.substring(path.lastIndexOf('/') + 1);
|
||||
window.repoFiles[folder] = window.repoFiles[folder] || {};
|
||||
window.repoFiles[folder][fileName] = window.repoFiles[folder][fileName] || {};
|
||||
if (newEntry) {
|
||||
window.repoFiles[folder][fileName] = { content: raw };
|
||||
} else {
|
||||
window.repoFiles[folder][fileName].content = raw;
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
updateUnpublishedEntryStatus(collection, slug, newStatus) {
|
||||
const unpubStore = window.repoFilesUnpublished;
|
||||
const entryIndex = unpubStore.findIndex(e => (
|
||||
e.metaData.collection === collection && e.slug === slug
|
||||
));
|
||||
unpubStore[entryIndex].metaData.status = newStatus;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
publishUnpublishedEntry(collection, slug) {
|
||||
const unpubStore = window.repoFilesUnpublished;
|
||||
const unpubEntryIndex = unpubStore.findIndex(e => (
|
||||
e.metaData.collection === collection && e.slug === slug
|
||||
));
|
||||
const unpubEntry = unpubStore[unpubEntryIndex];
|
||||
const entry = { raw: unpubEntry.data, slug: unpubEntry.slug, path: unpubEntry.file.path };
|
||||
unpubStore.splice(unpubEntryIndex, 1);
|
||||
return this.persistEntry(entry);
|
||||
}
|
||||
getMedia() {
|
||||
return Promise.resolve(this.assets);
|
||||
}
|
||||
|
||||
persistMedia({ fileObj }) {
|
||||
const { name, size } = fileObj;
|
||||
const objectUrl = attempt(window.URL.createObjectURL, fileObj);
|
||||
const url = isError(objectUrl) ? '' : objectUrl;
|
||||
const normalizedAsset = { id: uuid(), name, size, path: url, url };
|
||||
|
||||
this.assets.push(normalizedAsset);
|
||||
return Promise.resolve(normalizedAsset);
|
||||
}
|
||||
|
||||
deleteFile(path, commitMessage) {
|
||||
const assetIndex = this.assets.findIndex(asset => asset.path === path);
|
||||
if (assetIndex > -1) {
|
||||
this.assets.splice(assetIndex, 1);
|
||||
}
|
||||
|
||||
else {
|
||||
const folder = path.substring(0, path.lastIndexOf('/'));
|
||||
const fileName = path.substring(path.lastIndexOf('/') + 1);
|
||||
delete window.repoFiles[folder][fileName];
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
export TestBackend from './implementation';
|
||||
export AuthenticationPage from './AuthenticationPage';
|
||||
|
1
packages/netlify-cms-backend-test/webpack.config.js
Normal file
1
packages/netlify-cms-backend-test/webpack.config.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('../../webpack.config.js');
|
3
packages/netlify-cms-core/babel.config.js
Normal file
3
packages/netlify-cms-core/babel.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
const config = require('../../babel.config.js');
|
||||
|
||||
module.exports = config;
|
@ -1,4 +0,0 @@
|
||||
import { init } from '../src/index';
|
||||
import config from './config.yml';
|
||||
|
||||
init({ config });
|
@ -1,5 +1,6 @@
|
||||
backend:
|
||||
name: test-repo
|
||||
name: github
|
||||
repo: erquhart/blank
|
||||
|
||||
display_url: https://example.com
|
||||
media_folder: "assets/uploads"
|
||||
|
@ -5,10 +5,7 @@
|
||||
|
||||
<title>Netlify CMS Development Test</title>
|
||||
|
||||
<link rel="stylesheet" href="../src/index.css"/>
|
||||
|
||||
<script>
|
||||
window.CMS_MANUAL_INIT = true;
|
||||
window.repoFiles = {
|
||||
_posts: {
|
||||
"2015-02-14-this-is-a-post.md": {
|
||||
@ -82,7 +79,7 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script src='cms-test.js'></script>
|
||||
<script src="dist/netlify-cms-core.js"></script>
|
||||
<script>
|
||||
var PostPreview = createClass({
|
||||
render: function() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "netlify-cms-core",
|
||||
"description": "Netlify CMS lets content editors work on structured content stored in git",
|
||||
"version": "2.0.0-alpha.0",
|
||||
"main": "dist/cms.js",
|
||||
"main": "dist/netlify-cms-core.js",
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"eslint --fix",
|
||||
@ -15,8 +15,8 @@
|
||||
"dist/"
|
||||
],
|
||||
"scripts": {
|
||||
"watch": "cross-env NETLIFY_CMS_VERSION=$npm_package_version parcel example/index.html --no-cache --open",
|
||||
"build": "cross-env NETLIFY_CMS_VERSION=$npm_package_version parcel build example/index.html --no-cache "
|
||||
"watch": "cross-env NETLIFY_CMS_VERSION=$npm_package_version webpack-dev-server --hot --open",
|
||||
"build": "cross-env NETLIFY_CMS_VERSION=$npm_package_version webpack"
|
||||
},
|
||||
"keywords": [
|
||||
"netlify",
|
||||
@ -46,10 +46,10 @@
|
||||
"mdast-util-definitions": "^1.2.2",
|
||||
"mdast-util-to-string": "^1.0.4",
|
||||
"moment": "^2.11.2",
|
||||
"netlify-cms-editor-component-image": "file:../netlify-cms-editor-component-image",
|
||||
"netlify-cms-lib-auth": "file:../netlify-cms-lib-auth",
|
||||
"netlify-cms-lib-util": "file:../netlify-cms-lib-util",
|
||||
"netlify-cms-ui-default": "file:../netlify-cms-ui-default",
|
||||
"netlify-cms-editor-component-image": "2.0.0-alpha.0",
|
||||
"netlify-cms-lib-auth": "2.0.0-alpha.0",
|
||||
"netlify-cms-lib-util": "2.0.0-alpha.0",
|
||||
"netlify-cms-ui-default": "2.0.0-alpha.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.4.1",
|
||||
"react-aria-menubutton": "^5.1.0",
|
||||
@ -104,7 +104,11 @@
|
||||
"what-input": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.0.0-beta.54",
|
||||
"babel-loader": "^8.0.0-beta",
|
||||
"cross-env": "^5.2.0",
|
||||
"parcel-bundler": "^1.9.4"
|
||||
"webpack": "^4.16.1",
|
||||
"webpack-cli": "^3.1.0",
|
||||
"webpack-dev-server": "^3.1.4"
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import { currentBackend } from 'Backends/backend';
|
||||
import { getAsset } from 'Reducers';
|
||||
import { selectFields } from 'Reducers/collections';
|
||||
import { status, EDITORIAL_WORKFLOW } from 'Constants/publishModes';
|
||||
import EditorialWorkflowError from 'netlify-cms-lib-util/EditorialWorkflowError';
|
||||
import { EditorialWorkflowError } from 'netlify-cms-lib-util';
|
||||
import { loadEntry } from './entries';
|
||||
import ValidationErrorTypes from 'Constants/validationErrorTypes';
|
||||
|
||||
|
@ -6,7 +6,7 @@ import { getIntegrationProvider } from 'Integrations';
|
||||
import { getAsset, selectIntegration } from 'Reducers';
|
||||
import { selectFields } from 'Reducers/collections';
|
||||
import { selectCollectionEntriesCursor } from 'Reducers/cursors';
|
||||
import Cursor from 'netlify-cms-lib-util/Cursor'
|
||||
import { Cursor } from 'netlify-cms-lib-util';
|
||||
import { createEntry } from 'ValueObjects/Entry';
|
||||
import ValidationErrorTypes from 'Constants/validationErrorTypes';
|
||||
import isArray from 'lodash/isArray';
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { attempt, flatten, isError } from 'lodash';
|
||||
import { fromJS, Map } from 'immutable';
|
||||
import fuzzy from 'fuzzy';
|
||||
import GitHubBackend from "netlify-cms-backend-github";
|
||||
import TestRepoBackend from "netlify-cms-backend-test";
|
||||
import { GitHubBackend } from "netlify-cms-backend-github";
|
||||
import { TestBackend } from "netlify-cms-backend-test";
|
||||
import { resolveFormat } from "Formats/formats";
|
||||
import { selectIntegration } from 'Reducers/integrations';
|
||||
import {
|
||||
@ -21,7 +21,7 @@ import GitLabBackend from "./gitlab/implementation";
|
||||
import BitBucketBackend from "./bitbucket/implementation";
|
||||
import GitGatewayBackend from "./git-gateway/implementation";
|
||||
import { registerBackend, getBackend } from 'Lib/registry';
|
||||
import Cursor, { CURSOR_COMPATIBILITY_SYMBOL } from 'netlify-cms-lib-util/Cursor'
|
||||
import { Cursor, CURSOR_COMPATIBILITY_SYMBOL } from 'netlify-cms-lib-util';
|
||||
import { EDITORIAL_WORKFLOW, status } from 'Constants/publishModes';
|
||||
|
||||
/**
|
||||
@ -31,7 +31,7 @@ registerBackend('git-gateway', GitGatewayBackend);
|
||||
registerBackend('github', GitHubBackend);
|
||||
registerBackend('gitlab', GitLabBackend);
|
||||
registerBackend('bitbucket', BitBucketBackend);
|
||||
registerBackend('test-repo', TestRepoBackend);
|
||||
registerBackend('test-repo', TestBackend);
|
||||
|
||||
|
||||
class LocalStorageAuthStore {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import GithubAPI from "netlify-cms-backend-github/API";
|
||||
import APIError from "netlify-cms-lib-util/APIError";
|
||||
import { API as GithubAPI } from "netlify-cms-backend-github";
|
||||
import { APIError } from "netlify-cms-lib-util";
|
||||
|
||||
export default class API extends GithubAPI {
|
||||
constructor(config) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from "react";
|
||||
import { partial } from 'lodash';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { Icon } from 'netlify-cms-ui-default';
|
||||
|
||||
let component = null;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import GithubAPI from "netlify-cms-backend-github/API";
|
||||
import APIError from "netlify-cms-lib-util/APIError";
|
||||
import { API as GithubAPI } from "netlify-cms-backend-github";
|
||||
import { APIError } from "netlify-cms-lib-util";
|
||||
|
||||
export default class API extends GithubAPI {
|
||||
constructor(config) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { flow } from "lodash";
|
||||
import unsentRequest from "netlify-cms-lib-util/unsentRequest";
|
||||
import { then } from "netlify-cms-lib-util/promise";
|
||||
import { unsentRequest, then } from "netlify-cms-lib-util";
|
||||
import GitlabAPI from "Backends/gitlab/API";
|
||||
|
||||
export default class API extends GitlabAPI {
|
||||
|
@ -3,7 +3,7 @@ import jwtDecode from 'jwt-decode';
|
||||
import {List} from 'immutable';
|
||||
import { get, pick, intersection } from "lodash";
|
||||
import { unsentRequest } from "netlify-cms-lib-util";
|
||||
import GitHubBackend from "netlify-cms-backend-github";
|
||||
import { GitHubBackend } from "netlify-cms-backend-github";
|
||||
import GitLabBackend from "Backends/gitlab/implementation";
|
||||
import BitBucketBackend from "Backends/bitbucket/implementation";
|
||||
import GitHubAPI from "./GitHubAPI";
|
||||
|
@ -1,11 +1,7 @@
|
||||
import localForage from "netlify-cms-lib-util/localForage";
|
||||
import { localForage, unsentRequest, then, APIError, Cursor } from "netlify-cms-lib-util";
|
||||
import { Base64 } from "js-base64";
|
||||
import { fromJS, List, Map } from "immutable";
|
||||
import { cond, flow, isString, partial, partialRight, pick, omit, set, update, get } from "lodash";
|
||||
import unsentRequest from "netlify-cms-lib-util/unsentRequest";
|
||||
import { then } from "netlify-cms-lib-util/promise";
|
||||
import APIError from "netlify-cms-lib-util/APIError";
|
||||
import Cursor from 'netlify-cms-lib-util/Cursor'
|
||||
import AssetProxy from "ValueObjects/AssetProxy";
|
||||
|
||||
export default class API {
|
||||
|
@ -1,8 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import NetlifyAuthenticator from 'netlify-cms-lib-auth/netlify-auth';
|
||||
import ImplicitAuthenticator from 'netlify-cms-lib-auth/implicit-oauth';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import PropTypes from 'prop-types';
|
||||
import { NetlifyAuthenticator, ImplicitAuthenticator } from 'netlify-cms-lib-auth';
|
||||
import { Icon } from 'netlify-cms-ui-default';
|
||||
|
||||
export default class AuthenticationPage extends React.Component {
|
||||
static propTypes = {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import trimStart from 'lodash/trimStart';
|
||||
import semaphore from "semaphore";
|
||||
import { fileExtension } from 'netlify-cms-lib-util/path';
|
||||
import Cursor, { CURSOR_COMPATIBILITY_SYMBOL } from 'netlify-cms-lib-util/Cursor'
|
||||
import { fileExtension, Cursor, CURSOR_COMPATIBILITY_SYMBOL } from 'netlify-cms-lib-util';
|
||||
import AuthenticationPage from "./AuthenticationPage";
|
||||
import API from "./API";
|
||||
import { EDITORIAL_WORKFLOW } from "Constants/publishModes";
|
||||
|
1
packages/netlify-cms-core/src/bootstrap.js
vendored
1
packages/netlify-cms-core/src/bootstrap.js
vendored
@ -11,7 +11,6 @@ import { ErrorBoundary } from 'UI'
|
||||
import App from 'App/App';
|
||||
import 'EditorWidgets';
|
||||
import 'MarkdownPlugins';
|
||||
import './index.css';
|
||||
import 'what-input';
|
||||
|
||||
const ROOT_ID = 'nc-root';
|
||||
|
@ -14,8 +14,7 @@ import { showCollection, createNewEntry } from 'Actions/collections';
|
||||
import { openMediaLibrary as actionOpenMediaLibrary } from 'Actions/mediaLibrary';
|
||||
import MediaLibrary from 'MediaLibrary/MediaLibrary';
|
||||
import { Toast } from 'UI';
|
||||
import Loader from 'netlify-cms-ui-default/Loader';
|
||||
import { colors } from 'netlify-cms-ui-default/styles';
|
||||
import { Loader, colors } from 'netlify-cms-ui-default';
|
||||
import history from 'Routing/history';
|
||||
import { getCollectionUrl, getNewEntryUrl } from 'Lib/urlHelper';
|
||||
import { SIMPLE, EDITORIAL_WORKFLOW } from 'Constants/publishModes';
|
||||
|
@ -4,9 +4,17 @@ import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import styled, { css } from 'react-emotion';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import uuid from 'uuid/v4';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import Dropdown, { DropdownItem, StyledDropdownButton } from 'netlify-cms-ui-default/Dropdown'
|
||||
import { colors, colorsRaw, lengths, shadows, buttons } from 'netlify-cms-ui-default/styles'
|
||||
import {
|
||||
Icon,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
StyledDropdownButton,
|
||||
colors,
|
||||
colorsRaw,
|
||||
lengths,
|
||||
shadows,
|
||||
buttons,
|
||||
} from 'netlify-cms-ui-default';
|
||||
import SettingsDropdown from 'UI/SettingsDropdown';
|
||||
|
||||
const styles = {
|
||||
@ -132,7 +140,7 @@ export default class Header extends React.Component {
|
||||
</AppHeaderNavLink>
|
||||
{
|
||||
hasWorkflow
|
||||
? <AppHeaderNavLink to="/workflow" activeClassName={this.activeClassName}>
|
||||
? <AppHeaderNavLink to="/workflow" activeClassName={Header.activeClassName}>
|
||||
<Icon type="workflow"/>
|
||||
Workflow
|
||||
</AppHeaderNavLink>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import styled from 'react-emotion';
|
||||
import { lengths } from 'netlify-cms-ui-default/styles';
|
||||
import { lengths } from 'netlify-cms-ui-default';
|
||||
|
||||
|
||||
const NotFoundContainer = styled.div`
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import styled from 'react-emotion';
|
||||
import { connect } from 'react-redux';
|
||||
import { lengths } from 'netlify-cms-ui-default/styles';
|
||||
import { lengths } from 'netlify-cms-ui-default';
|
||||
import { getNewEntryUrl } from 'Lib/urlHelper';
|
||||
import Sidebar from './Sidebar';
|
||||
import CollectionTop from './CollectionTop';
|
||||
|
@ -2,8 +2,7 @@ import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import styled from 'react-emotion';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { components, buttons, shadows, colors } from 'netlify-cms-ui-default/styles';
|
||||
import { Icon, components, buttons, shadows, colors } from 'netlify-cms-ui-default';
|
||||
import { VIEW_STYLE_LIST, VIEW_STYLE_GRID } from 'Constants/collectionViews';
|
||||
|
||||
const CollectionTopContainer = styled.div`
|
||||
|
@ -1,7 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import Loader from 'netlify-cms-ui-default/Loader';
|
||||
import { Loader } from 'netlify-cms-ui-default';
|
||||
import EntryListing from './EntryListing';
|
||||
|
||||
const Entries = ({
|
||||
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { connect } from 'react-redux';
|
||||
import { partial } from 'lodash';
|
||||
import Cursor from 'netlify-cms-lib-util/Cursor'
|
||||
import { Cursor } from 'netlify-cms-lib-util'
|
||||
import {
|
||||
loadEntries as actionLoadEntries,
|
||||
traverseCollectionCursor as actionTraverseCollectionCursor,
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { connect } from 'react-redux';
|
||||
import Cursor from 'netlify-cms-lib-util/Cursor'
|
||||
import { Cursor } from 'netlify-cms-lib-util';
|
||||
import { selectSearchedEntries } from 'Reducers';
|
||||
import {
|
||||
searchEntries as actionSearchEntries,
|
||||
|
@ -3,11 +3,10 @@ import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import styled from 'react-emotion';
|
||||
import { Link } from 'react-router-dom';
|
||||
import c from 'classnames';
|
||||
import { resolvePath } from 'netlify-cms-lib-util';
|
||||
import { colors, colorsRaw, components, lengths } from 'netlify-cms-ui-default';
|
||||
import history from 'Routing/history';
|
||||
import { resolvePath } from 'netlify-cms-lib-util/path';
|
||||
import { VIEW_STYLE_LIST, VIEW_STYLE_GRID } from 'Constants/collectionViews';
|
||||
import { colors, colorsRaw, components, lengths } from 'netlify-cms-ui-default/styles';
|
||||
|
||||
const ListCardLink = styled(Link)`
|
||||
${components.card};
|
||||
|
@ -4,7 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import styled from 'react-emotion';
|
||||
import Waypoint from 'react-waypoint';
|
||||
import { Map } from 'immutable';
|
||||
import Cursor from 'netlify-cms-lib-util/Cursor';
|
||||
import { Cursor } from 'netlify-cms-lib-util';
|
||||
import { selectFields, selectInferedField } from 'Reducers/collections';
|
||||
import EntryCard from './EntryCard';
|
||||
|
||||
|
@ -4,8 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import styled, { css } from 'react-emotion';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import uuid from 'uuid/v4';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { components, colors, colorsRaw, lengths } from 'netlify-cms-ui-default/styles';
|
||||
import { Icon, components, colors, colorsRaw, lengths } from 'netlify-cms-ui-default';
|
||||
import { searchCollections } from 'Actions/collections';
|
||||
import { getCollectionUrl } from 'Lib/urlHelper';
|
||||
|
||||
|
@ -4,7 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { Map } from 'immutable';
|
||||
import { get } from 'lodash';
|
||||
import { connect } from 'react-redux';
|
||||
import Loader from 'netlify-cms-ui-default/Loader';
|
||||
import { Loader } from 'netlify-cms-ui-default';
|
||||
import history from 'Routing/history';
|
||||
import { logoutUser } from 'Actions/auth';
|
||||
import {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import styled, { css, cx } from 'react-emotion';
|
||||
import { partial, uniqueId } from 'lodash';
|
||||
import { colors, colorsRaw, transitions, lengths, borders } from 'netlify-cms-ui-default/styles';
|
||||
import { colors, colorsRaw, transitions, lengths, borders } from 'netlify-cms-ui-default';
|
||||
import { resolveWidget } from 'Lib/registry';
|
||||
import Widget from './Widget';
|
||||
|
||||
|
@ -3,10 +3,8 @@ import React, { Component } from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import styled, { css, injectGlobal } from 'react-emotion';
|
||||
import SplitPane from 'react-split-pane';
|
||||
import classnames from 'classnames';
|
||||
import { Icon, colors, colorsRaw, components, transitions } from 'netlify-cms-ui-default';
|
||||
import { ScrollSync, ScrollSyncPane } from './EditorScrollSync';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { colors, colorsRaw, components, transitions } from 'netlify-cms-ui-default/styles';
|
||||
import EditorControlPane from './EditorControlPane/EditorControlPane';
|
||||
import EditorPreviewPane from './EditorPreviewPane/EditorPreviewPane';
|
||||
import EditorToolbar from './EditorToolbar';
|
||||
|
@ -4,7 +4,7 @@ import styled from 'react-emotion';
|
||||
import { List, Map } from 'immutable';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import Frame from 'react-frame-component';
|
||||
import { lengths } from 'netlify-cms-ui-default/styles';
|
||||
import { lengths } from 'netlify-cms-ui-default';
|
||||
import { resolveWidget, getPreviewTemplate, getPreviewStyles } from 'Lib/registry';
|
||||
import { ErrorBoundary } from 'UI';
|
||||
import { selectTemplateName, selectInferedField } from 'Reducers/collections';
|
||||
|
@ -1,8 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'react-emotion';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { colors, colorsRaw, shadows, buttons } from 'netlify-cms-ui-default/styles';
|
||||
import { Icon, colors, colorsRaw, shadows, buttons } from 'netlify-cms-ui-default';
|
||||
|
||||
const EditorToggleButton = styled.button`
|
||||
${buttons.button};
|
||||
|
@ -3,11 +3,19 @@ import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import styled, { css } from 'react-emotion';
|
||||
import { Link } from 'react-router-dom';
|
||||
import {
|
||||
Icon,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
StyledDropdownButton,
|
||||
colorsRaw,
|
||||
colors,
|
||||
components,
|
||||
buttons,
|
||||
lengths,
|
||||
} from 'netlify-cms-ui-default';
|
||||
import { status } from 'Constants/publishModes';
|
||||
import SettingsDropdown from 'UI/SettingsDropdown';
|
||||
import Dropdown, { DropdownItem, StyledDropdownButton } from 'netlify-cms-ui-default/Dropdown';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { colorsRaw, colors, components, buttons, lengths } from 'netlify-cms-ui-default/styles';
|
||||
import { stripProtocol } from 'Lib/urlHelper';
|
||||
|
||||
const styles = {
|
||||
|
@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import { isBoolean } from 'lodash';
|
||||
import Toggle from 'netlify-cms-ui-default/Toggle';
|
||||
import { Toggle } from 'netlify-cms-ui-default';
|
||||
|
||||
export default class BooleanControl extends React.Component {
|
||||
render() {
|
||||
|
@ -5,8 +5,7 @@ import { List, Map } from 'immutable';
|
||||
import { partial } from 'lodash';
|
||||
import c from 'classnames';
|
||||
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import ListItemTopBar from 'netlify-cms-ui-default/ListItemTopBar';
|
||||
import { Icon, ListItemTopBar } from 'netlify-cms-ui-default';
|
||||
import ObjectControl from 'EditorWidgets/Object/ObjectControl';
|
||||
|
||||
function ListItem(props) {
|
||||
|
@ -3,9 +3,7 @@ import React from 'react';
|
||||
import { List } from 'immutable';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import c from 'classnames';
|
||||
import Dropdown, { DropdownItem, DropdownButton } from 'netlify-cms-ui-default/Dropdown';
|
||||
import Toggle from 'netlify-cms-ui-default/Toggle';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { Icon, Toggle, Dropdown, DropdownItem, DropdownButton } from 'netlify-cms-ui-default';
|
||||
import ToolbarButton from './ToolbarButton';
|
||||
|
||||
export default class Toolbar extends React.Component {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import c from 'classnames';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { Icon } from 'netlify-cms-ui-default';
|
||||
|
||||
const ToolbarButton = ({ type, label, icon, onClick, isActive, isHidden, disabled }) => {
|
||||
const active = isActive && type && isActive(type);
|
||||
|
@ -7,7 +7,7 @@ import { resolveWidget, getEditorComponents } from 'Lib/registry';
|
||||
import { openMediaLibrary, removeInsertedMedia } from 'Actions/mediaLibrary';
|
||||
import { addAsset } from 'Actions/media';
|
||||
import { getAsset } from 'Reducers';
|
||||
import ListItemTopBar from 'netlify-cms-ui-default/ListItemTopBar';
|
||||
import { ListItemTopBar } from 'netlify-cms-ui-default';
|
||||
import { getEditorControl } from '../index';
|
||||
|
||||
class Shortcode extends React.Component {
|
||||
|
@ -4,8 +4,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { Map } from 'immutable';
|
||||
import { partial } from 'lodash';
|
||||
import c from 'classnames';
|
||||
import { Icon } from 'netlify-cms-ui-default';
|
||||
import { resolveWidget } from 'Lib/registry';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
|
||||
const TopBar = ({ collapsed, onCollapseToggle }) => (
|
||||
<div className="nc-objectControl-topBar">
|
||||
|
@ -6,7 +6,7 @@ import { List, Map } from 'immutable';
|
||||
import { connect } from 'react-redux';
|
||||
import { debounce } from 'lodash';
|
||||
import { query, clearSearch } from 'Actions/search';
|
||||
import Loader from 'netlify-cms-ui-default/Loader';
|
||||
import { Loader } from 'netlify-cms-ui-default';
|
||||
|
||||
function escapeRegexCharacters(str) {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'react-emotion';
|
||||
import { colors } from 'netlify-cms-ui-default/styles';
|
||||
import { colors } from 'netlify-cms-ui-default';
|
||||
|
||||
const EmptyMessageContainer= styled.div`
|
||||
height: 100%;
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { orderBy, map } from 'lodash';
|
||||
import fuzzy from 'fuzzy';
|
||||
import { resolvePath, fileExtension } from 'netlify-cms-lib-util/path';
|
||||
import { resolvePath, fileExtension } from 'netlify-cms-lib-util';
|
||||
import { changeDraftField } from 'Actions/entries';
|
||||
import {
|
||||
loadMedia as loadMediaAction,
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled, { css } from 'react-emotion';
|
||||
import { FileUploadButton } from 'UI';
|
||||
import { buttons, shadows } from 'netlify-cms-ui-default/styles';
|
||||
import { buttons, shadows } from 'netlify-cms-ui-default';
|
||||
|
||||
const styles = {
|
||||
button: css`
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'react-emotion';
|
||||
import { colors, borders, lengths } from 'netlify-cms-ui-default/styles';
|
||||
import { colors, borders, lengths } from 'netlify-cms-ui-default';
|
||||
|
||||
const Card = styled.div`
|
||||
width: ${props => props.width};
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'react-emotion'
|
||||
import MediaLibraryCard from './MediaLibraryCard';
|
||||
import { colors } from 'netlify-cms-ui-default/styles';
|
||||
import { colors } from 'netlify-cms-ui-default';
|
||||
|
||||
const CardGridContainer = styled.div`
|
||||
overflow-y: auto;
|
||||
|
@ -1,8 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'react-emotion';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { shadows, colors } from 'netlify-cms-ui-default/styles';
|
||||
import { Icon, shadows, colors } from 'netlify-cms-ui-default';
|
||||
|
||||
const CloseButton = styled.button`
|
||||
${shadows.dropMiddle};
|
||||
|
@ -9,7 +9,7 @@ import MediaLibraryHeader from './MediaLibraryHeader';
|
||||
import MediaLibraryActions from './MediaLibraryActions';
|
||||
import MediaLibraryCardGrid from './MediaLibraryCardGrid';
|
||||
import EmptyMessage from './EmptyMessage';
|
||||
import { buttons, shadows, colors, borders, lengths } from 'netlify-cms-ui-default/styles';
|
||||
import { buttons, shadows, colors, borders, lengths } from 'netlify-cms-ui-default';
|
||||
|
||||
/**
|
||||
* Responsive styling needs to be overhauled. Current setup requires specifying
|
||||
|
@ -1,8 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'react-emotion';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { lengths, colors } from 'netlify-cms-ui-default/styles';
|
||||
import { Icon, lengths, colors } from 'netlify-cms-ui-default';
|
||||
|
||||
const SearchContainer = styled.div`
|
||||
height: 37px;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { css } from 'react-emotion';
|
||||
import { colors } from 'netlify-cms-ui-default/styles';
|
||||
import { colors } from 'netlify-cms-ui-default';
|
||||
|
||||
const DefaultErrorComponent = () => {
|
||||
};
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { css, cx, injectGlobal } from 'react-emotion';
|
||||
import ReactModal from 'react-modal';
|
||||
import { transitions, shadows, lengths } from 'netlify-cms-ui-default/styles';
|
||||
import { transitions, shadows, lengths } from 'netlify-cms-ui-default';
|
||||
|
||||
injectGlobal`
|
||||
.ReactModal__Body--open {
|
||||
|
@ -1,8 +1,6 @@
|
||||
import React from 'react';
|
||||
import styled, { css } from 'react-emotion';
|
||||
import Dropdown, { DropdownItem, DropdownButton } from 'netlify-cms-ui-default/Dropdown';
|
||||
import Icon from 'netlify-cms-ui-default/Icon';
|
||||
import { colors } from 'netlify-cms-ui-default/styles';
|
||||
import { Icon, Dropdown, DropdownItem, DropdownButton, colors } from 'netlify-cms-ui-default';
|
||||
import { stripProtocol } from 'Lib/urlHelper';
|
||||
|
||||
const styles = {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { css, injectGlobal, cx } from 'react-emotion';
|
||||
import 'redux-notifications/lib/styles.css'; // Import default redux-notifications styles into global scope.
|
||||
import { shadows, colors, lengths } from 'netlify-cms-ui-default/styles';
|
||||
//import 'redux-notifications/lib/styles.css'; // Import default redux-notifications styles into global scope.
|
||||
import { shadows, colors, lengths } from 'netlify-cms-ui-default';
|
||||
|
||||
injectGlobal`
|
||||
.notif__container {
|
||||
|
@ -4,9 +4,15 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import styled from 'react-emotion';
|
||||
import { OrderedMap } from 'immutable';
|
||||
import { connect } from 'react-redux';
|
||||
import Dropdown, { DropdownItem, StyledDropdownButton } from 'netlify-cms-ui-default/Dropdown';
|
||||
import Loader from 'netlify-cms-ui-default/Loader';
|
||||
import { lengths, components, shadows } from 'netlify-cms-ui-default/styles';
|
||||
import {
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
StyledDropdownButton,
|
||||
Loader,
|
||||
lengths,
|
||||
components,
|
||||
shadows,
|
||||
} from 'netlify-cms-ui-default';
|
||||
import { createNewEntry } from 'Actions/collections';
|
||||
import {
|
||||
loadUnpublishedEntries,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import styled, { css } from 'react-emotion';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { components, colors, colorsRaw, transitions, buttons } from 'netlify-cms-ui-default/styles';
|
||||
import { components, colors, colorsRaw, transitions, buttons } from 'netlify-cms-ui-default';
|
||||
|
||||
const styles = {
|
||||
text: css`
|
||||
|
@ -4,7 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import styled, { css, cx } from 'react-emotion';
|
||||
import moment from 'moment';
|
||||
import { capitalize } from 'lodash'
|
||||
import { colors, colorsRaw, lengths } from 'netlify-cms-ui-default/styles';
|
||||
import { colors, colorsRaw, lengths } from 'netlify-cms-ui-default';
|
||||
import { status } from 'Constants/publishModes';
|
||||
import { DragSource, DropTarget, HTML5DragDrop } from 'UI'
|
||||
import WorkflowCard from './WorkflowCard';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { fromJS, Map } from 'immutable';
|
||||
import Cursor from 'netlify-cms-lib-util/Cursor'
|
||||
import { Cursor } from 'netlify-cms-lib-util';
|
||||
import {
|
||||
ENTRIES_SUCCESS,
|
||||
} from 'Actions/entries';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Map } from 'immutable';
|
||||
import { resolvePath } from 'netlify-cms-lib-util/path';
|
||||
import { resolvePath } from 'netlify-cms-lib-util';
|
||||
import { ADD_ASSET, REMOVE_ASSET } from 'Actions/media';
|
||||
import AssetProxy from 'ValueObjects/AssetProxy';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { resolvePath } from 'netlify-cms-lib-util/path';
|
||||
import { resolvePath } from 'netlify-cms-lib-util';
|
||||
import { currentBackend } from 'Backends/backend';
|
||||
import { getIntegrationProvider } from 'Integrations';
|
||||
import { selectIntegration } from 'Reducers';
|
||||
|
27
packages/netlify-cms-core/webpack.config.js
Normal file
27
packages/netlify-cms-core/webpack.config.js
Normal file
@ -0,0 +1,27 @@
|
||||
const path = require('path');
|
||||
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
|
||||
const baseConfig = require('../../webpack.config.js');
|
||||
|
||||
module.exports = {
|
||||
...baseConfig,
|
||||
context: path.join(__dirname, 'src'),
|
||||
entry: './index.js',
|
||||
module: {
|
||||
noParse: /\.css$/,
|
||||
...baseConfig.module,
|
||||
},
|
||||
devServer: {
|
||||
contentBase: './example',
|
||||
watchContentBase: true,
|
||||
quiet: true,
|
||||
host: 'localhost',
|
||||
port: 8080,
|
||||
},
|
||||
plugins: [
|
||||
new FriendlyErrorsWebpackPlugin({
|
||||
compilationSuccessInfo: {
|
||||
messages: ['Netlify CMS is now running at http://localhost:8080'],
|
||||
},
|
||||
}),
|
||||
],
|
||||
};
|
@ -0,0 +1,3 @@
|
||||
const config = require('../../babel.config.js');
|
||||
|
||||
module.exports = config;
|
@ -2,6 +2,7 @@
|
||||
"name": "netlify-cms-editor-component-image",
|
||||
"description": "Image component for Netlify CMS editor widget",
|
||||
"version": "2.0.0-alpha.0",
|
||||
"main": "dist/netlify-cms-editor-component-image.js",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"netlify",
|
||||
@ -9,14 +10,21 @@
|
||||
"editor",
|
||||
"component"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"watch": "parcel watch src/*.js --out-dir . --no-cache",
|
||||
"build": "parcel build src/*.js --out-dir . --no-cache"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^16.4.1"
|
||||
"watch": "webpack -w",
|
||||
"build": "cross-env NODE_ENV=production webpack"
|
||||
},
|
||||
"devDependencies": {
|
||||
"parcel-bundler": "^1.9.4"
|
||||
"@babel/cli": "^7.0.0-beta.54",
|
||||
"@babel/core": "^7.0.0-beta.54",
|
||||
"cross-env": "^5.2.0",
|
||||
"rollup": "^0.63.2",
|
||||
"rollup-plugin-babel": "^4.0.0-beta.7",
|
||||
"webpack": "^4.16.1",
|
||||
"webpack-cli": "^3.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.4.1"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
module.exports = require('../../webpack.config.js');
|
3
packages/netlify-cms-lib-auth/babel.config.js
Normal file
3
packages/netlify-cms-lib-auth/babel.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
const config = require('../../babel.config.js');
|
||||
|
||||
module.exports = config;
|
@ -2,8 +2,8 @@
|
||||
"name": "netlify-cms-lib-auth",
|
||||
"description": "Shared authentication functionality for Netlify CMS.",
|
||||
"version": "2.0.0-alpha.0",
|
||||
"main": "dist/netlify-cms-lib-auth.js",
|
||||
"license": "MIT",
|
||||
"main": "src/index.js",
|
||||
"files": [
|
||||
"src/",
|
||||
"dist/"
|
||||
@ -11,18 +11,25 @@
|
||||
"keywords": [
|
||||
"netlify-cms"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"watch": "parcel watch src/*.js --out-dir . --no-cache",
|
||||
"build": "parcel build src/*.js --out-dir . --no-cache"
|
||||
"watch": "webpack -w",
|
||||
"build": "cross-env NODE_ENV=production webpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"immutable": "^3.7.6",
|
||||
"lodash": "^4.13.1",
|
||||
"uuid": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.3",
|
||||
"parcel-bundler": "^1.9.4"
|
||||
"@babel/cli": "^7.0.0-beta.54",
|
||||
"@babel/core": "^7.0.0-beta.54",
|
||||
"cross-env": "^5.2.0",
|
||||
"rollup": "^0.63.2",
|
||||
"rollup-plugin-babel": "^4.0.0-beta.7",
|
||||
"webpack": "^4.16.1",
|
||||
"webpack-cli": "^3.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"immutable": "^3.7.6",
|
||||
"lodash": "^4.13.1"
|
||||
}
|
||||
}
|
||||
|
2
packages/netlify-cms-lib-auth/src/index.js
Normal file
2
packages/netlify-cms-lib-auth/src/index.js
Normal file
@ -0,0 +1,2 @@
|
||||
export NetlifyAuthenticator from './netlify-auth';
|
||||
export ImplicitAuthenticator from './implicit-oauth';
|
1
packages/netlify-cms-lib-auth/webpack.config.js
Normal file
1
packages/netlify-cms-lib-auth/webpack.config.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('../../webpack.config.js');
|
3
packages/netlify-cms-lib-util/babel.config.js
Normal file
3
packages/netlify-cms-lib-util/babel.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
const config = require('../../babel.config.js');
|
||||
|
||||
module.exports = config;
|
@ -2,23 +2,30 @@
|
||||
"name": "netlify-cms-lib-util",
|
||||
"description": "Shared utilities for Netlify CMS.",
|
||||
"version": "2.0.0-alpha.0",
|
||||
"main": "dist/netlify-cms-lib-util.js",
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"netlify-cms"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"watch": "parcel watch src/*.js --out-dir . --no-cache",
|
||||
"build": "parcel build src/*.js --out-dir . --no-cache"
|
||||
"watch": "webpack -w",
|
||||
"build": "cross-env NODE_ENV=production webpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"immutable": "^3.7.6",
|
||||
"localforage": "^1.4.2",
|
||||
"lodash": "^4.13.1"
|
||||
"localforage": "^1.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.3",
|
||||
"parcel-bundler": "^1.9.4"
|
||||
"@babel/cli": "^7.0.0-beta.54",
|
||||
"@babel/core": "^7.0.0-beta.54",
|
||||
"cross-env": "^5.2.0",
|
||||
"rollup": "^0.63.2",
|
||||
"rollup-plugin-babel": "^4.0.0-beta.7",
|
||||
"webpack": "^4.16.1",
|
||||
"webpack-cli": "^3.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"immutable": "^3.7.6",
|
||||
"lodash": "^4.13.1"
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { fileExtensionWithSeparator, fileExtension } from '../pathHelper';
|
||||
import { fileExtensionWithSeparator, fileExtension } from '../path';
|
||||
|
||||
describe('fileExtensionWithSeparator', () => {
|
||||
it('should return the extension of a file', () => {
|
7
packages/netlify-cms-lib-util/src/index.js
Normal file
7
packages/netlify-cms-lib-util/src/index.js
Normal file
@ -0,0 +1,7 @@
|
||||
export APIError from './APIError';
|
||||
export Cursor, { CURSOR_COMPATIBILITY_SYMBOL } from './Cursor';
|
||||
export EditorialWorkflowError from './EditorialWorkflowError';
|
||||
export localForage from './localForage';
|
||||
export { resolvePath, basename, fileExtensionWithSeparator, fileExtension } from './path';
|
||||
export { filterPromises, resolvePromiseProperties, then } from './promise';
|
||||
export unsentRequest from './unsentRequest';
|
1
packages/netlify-cms-lib-util/webpack.config.js
Normal file
1
packages/netlify-cms-lib-util/webpack.config.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('../../webpack.config.js');
|
3
packages/netlify-cms-ui-default/babel.config.js
Normal file
3
packages/netlify-cms-ui-default/babel.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
const config = require('../../babel.config.js');
|
||||
|
||||
module.exports = config;
|
@ -3,29 +3,33 @@
|
||||
"description": "Default UI components for Netlify CMS.",
|
||||
"version": "2.0.0-alpha.0",
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"main": "dist/netlify-cms-ui-default.js",
|
||||
"keywords": [
|
||||
"netlify-cms"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"watch": "parcel watch src/*.js --out-dir . --no-cache",
|
||||
"build": "parcel build src/*.js --out-dir . --no-cache"
|
||||
"watch": "webpack -w",
|
||||
"build": "cross-env NODE_ENV=production webpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"emotion": "^9.1.3",
|
||||
"lodash": "^4.13.1",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.4.1",
|
||||
"react-aria-menubutton": "^5.1.0",
|
||||
"react-emotion": "^9.2.6",
|
||||
"react-toggled": "^1.1.2",
|
||||
"react-transition-group": "^2.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-plugin-inline-svg": "^1.0.0",
|
||||
"parcel-bundler": "^1.9.4"
|
||||
"@babel/cli": "^7.0.0-beta.54",
|
||||
"@babel/core": "^7.0.0-beta.54",
|
||||
"cross-env": "^5.2.0",
|
||||
"rollup": "^0.63.2",
|
||||
"rollup-plugin-babel": "^4.0.0-beta.7",
|
||||
"webpack": "^4.16.1",
|
||||
"webpack-cli": "^3.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"lodash": "^4.13.1",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.4.1",
|
||||
"react-emotion": "^9.2.6"
|
||||
}
|
||||
}
|
||||
|
16
packages/netlify-cms-ui-default/src/index.js
Normal file
16
packages/netlify-cms-ui-default/src/index.js
Normal file
@ -0,0 +1,16 @@
|
||||
export Dropdown, { DropdownItem, DropdownButton, StyledDropdownButton } from './Dropdown';
|
||||
export Icon from './Icon';
|
||||
export ListItemTopBar from './ListItemTopBar';
|
||||
export Loader from './Loader';
|
||||
export Toggle from './Toggle';
|
||||
export {
|
||||
fonts,
|
||||
colorsRaw,
|
||||
colors,
|
||||
lengths,
|
||||
components,
|
||||
buttons,
|
||||
shadows,
|
||||
borders,
|
||||
transitions,
|
||||
} from './styles';
|
@ -1,9 +1,21 @@
|
||||
import { css, injectGlobal } from 'react-emotion';
|
||||
|
||||
export {
|
||||
fonts,
|
||||
colorsRaw,
|
||||
colors,
|
||||
lengths,
|
||||
components,
|
||||
buttons,
|
||||
shadows,
|
||||
borders,
|
||||
transitions,
|
||||
};
|
||||
|
||||
/**
|
||||
* Font Stacks
|
||||
*/
|
||||
export const fonts = {
|
||||
const fonts = {
|
||||
primary: `
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
@ -29,7 +41,7 @@ export const fonts = {
|
||||
/**
|
||||
* Theme Colors
|
||||
*/
|
||||
export const colorsRaw = {
|
||||
const colorsRaw = {
|
||||
white: '#fff',
|
||||
grayLight: '#eff0f4',
|
||||
gray: '#798291',
|
||||
@ -48,7 +60,7 @@ export const colorsRaw = {
|
||||
tealLight: '#ddf5f9',
|
||||
};
|
||||
|
||||
export const colors = {
|
||||
const colors = {
|
||||
statusDraftText: colorsRaw.purple,
|
||||
statusDraftBackground: colorsRaw.purpleLight,
|
||||
statusReviewText: colorsRaw.Brown,
|
||||
@ -78,7 +90,7 @@ export const colors = {
|
||||
controlLabel: '#7a8291',
|
||||
};
|
||||
|
||||
export const lengths = {
|
||||
const lengths = {
|
||||
topBarHeight: '56px',
|
||||
inputPadding: '16px 20px',
|
||||
borderRadius: '5px',
|
||||
@ -88,15 +100,15 @@ export const lengths = {
|
||||
pageMargin: '84px 18px',
|
||||
};
|
||||
|
||||
export const borders = {
|
||||
const borders = {
|
||||
textField: `solid ${lengths.borderWidth} ${colors.textFieldBorder}`,
|
||||
};
|
||||
|
||||
export const transitions = {
|
||||
const transitions = {
|
||||
main: '.2s ease',
|
||||
};
|
||||
|
||||
export const shadows = {
|
||||
const shadows = {
|
||||
drop: css`
|
||||
box-shadow: 0 2px 4px 0 rgba(19, 39, 48, .12);
|
||||
`,
|
||||
@ -129,7 +141,7 @@ const card = css`
|
||||
background-color: #fff;
|
||||
`;
|
||||
|
||||
export const buttons = {
|
||||
const buttons = {
|
||||
button: css`
|
||||
border: 0;
|
||||
border-radius: ${lengths.borderRadius};
|
||||
@ -191,7 +203,7 @@ export const buttons = {
|
||||
`,
|
||||
};
|
||||
|
||||
export const components = {
|
||||
const components = {
|
||||
card,
|
||||
caretDown: css`
|
||||
color: ${colorsRaw.white};
|
||||
|
1
packages/netlify-cms-ui-default/webpack.config.js
Normal file
1
packages/netlify-cms-ui-default/webpack.config.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('../../webpack.config.js');
|
38
webpack.config.js
Normal file
38
webpack.config.js
Normal file
@ -0,0 +1,38 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
|
||||
const pkg = require(path.join(process.cwd(), 'package.json'));
|
||||
|
||||
module.exports = {
|
||||
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
|
||||
entry: './src/index.js',
|
||||
output: {
|
||||
path: process.cwd(),
|
||||
filename: pkg.main,
|
||||
library: pkg.name,
|
||||
libraryTarget: 'umd',
|
||||
umdNamedDefine: true,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: 'babel-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new FriendlyErrorsWebpackPlugin(),
|
||||
],
|
||||
devtool: 'source-map',
|
||||
target: 'web',
|
||||
externals: (context, request, cb) => {
|
||||
const peerDeps = Object.keys(pkg.peerDependencies || {});
|
||||
const isPeerDep = dep => new RegExp(`^${dep}/?`).test(request);
|
||||
return peerDeps.some(isPeerDep) ? cb(null, request) : cb();
|
||||
},
|
||||
stats: {
|
||||
all: false,
|
||||
},
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user