diff --git a/babel.config.js b/babel.config.js index 9974bb8e..90242cab 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,3 +1,4 @@ +const path = require('path'); const isProduction = process.env.NODE_ENV === 'production'; const isTest = process.env.NODE_ENV === 'test'; @@ -29,6 +30,24 @@ const plugins = () => { '@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-proposal-export-default-from', + [ + 'module-resolver', + { + root: path.join(__dirname, 'packages/netlify-cms-core/src/components'), + alias: { + coreSrc: path.join(__dirname, 'packages/netlify-cms-core/src'), + Actions: path.join(__dirname, 'packages/netlify-cms-core/src/actions/'), + Constants: path.join(__dirname, 'packages/netlify-cms-core/src/constants/'), + Formats: path.join(__dirname, 'packages/netlify-cms-core/src/formats/'), + Integrations: path.join(__dirname, 'packages/netlify-cms-core/src/integrations/'), + Lib: path.join(__dirname, 'packages/netlify-cms-core/src/lib/'), + Reducers: path.join(__dirname, 'packages/netlify-cms-core/src/reducers/'), + Redux: path.join(__dirname, 'packages/netlify-cms-core/src/redux/'), + Routing: path.join(__dirname, 'packages/netlify-cms-core/src/routing/'), + ValueObjects: path.join(__dirname, 'packages/netlify-cms-core/src/valueObjects/'), + }, + }, + ], ]; if (isProduction) { @@ -65,6 +84,7 @@ const plugins = () => { ]; } + defaultPlugins.push('react-hot-loader/babel'); return [ ...defaultPlugins, [ diff --git a/custom-preprocessor.js b/custom-preprocessor.js index 43a27e2a..55708a3c 100644 --- a/custom-preprocessor.js +++ b/custom-preprocessor.js @@ -1,4 +1,4 @@ const babelJest = require('babel-jest'); -const babelConfig = require('./packages/netlify-cms-core/babel.config.js'); +const babelConfig = require('./babel.config.js'); module.exports = babelJest.createTransformer(babelConfig); diff --git a/package.json b/package.json index fab8491e..b7fe6f17 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,9 @@ "babel-plugin-transform-export-extensions": "^6.22.0", "babel-plugin-transform-inline-environment-variables": "^0.4.3", "cache-me-outside": "^0.0.4", - "cross-env": "^5.1.4", + "copy-webpack-plugin": "^5.0.1", + "cross-env": "^5.2.0", + "css-loader": "^2.1.1", "cypress": "^3.1.5", "dom-testing-library": "^3.17.1", "eslint": "^5.15.1", @@ -92,18 +94,24 @@ "http-server": "^0.11.1", "jest": "^24.5.0", "jest-cli": "^24.5.0", + "jest-dom": "^3.1.3", "jest-emotion": "^10.0.9", "lerna": "^3.13.1", "npm-run-all": "^4.1.5", "prettier": "1.16.4", "react-test-renderer": "^16.8.4", + "react-testing-library": "^6.0.0", "rimraf": "^2.6.3", "start-server-and-test": "^1.7.11", "stylelint": "^9.10.1", "stylelint-config-recommended": "^2.1.0", "stylelint-config-styled-components": "^0.1.1", "stylelint-processor-styled-components": "^1.5.2", - "svg-inline-loader": "^0.8.0" + "svg-inline-loader": "^0.8.0", + "to-string-loader": "^1.1.5", + "webpack": "^4.29.6", + "webpack-cli": "^3.2.3", + "webpack-dev-server": "^3.2.1" }, "workspaces": [ "packages/*" diff --git a/packages/netlify-cms-backend-bitbucket/package.json b/packages/netlify-cms-backend-bitbucket/package.json index 3b626f5d..e65af9cb 100644 --- a/packages/netlify-cms-backend-bitbucket/package.json +++ b/packages/netlify-cms-backend-bitbucket/package.json @@ -22,20 +22,15 @@ "js-base64": "^2.5.1", "semaphore": "^1.1.0" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", "immutable": "^3.7.6", - "lodash": "^4.17.10", - "netlify-cms-lib-auth": "^2.0.4", - "netlify-cms-lib-util": "^2.1.0", - "netlify-cms-ui-default": "^2.0.6", - "prop-types": "^15.6.2", - "react": "^16.4.1" + "lodash": "^4.17.11", + "netlify-cms-lib-auth": "^2.0.6-beta.0", + "netlify-cms-lib-util": "^2.1.3-beta.0", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4" } } diff --git a/packages/netlify-cms-backend-bitbucket/src/implementation.js b/packages/netlify-cms-backend-bitbucket/src/implementation.js index 798cd404..6c28cacd 100644 --- a/packages/netlify-cms-backend-bitbucket/src/implementation.js +++ b/packages/netlify-cms-backend-bitbucket/src/implementation.js @@ -15,7 +15,7 @@ import API from './API'; const MAX_CONCURRENT_DOWNLOADS = 10; // Implementation wrapper class -export default class Bitbucket { +export default class BitbucketBackend { constructor(config, options = {}) { this.config = config; this.options = { diff --git a/packages/netlify-cms-backend-bitbucket/src/index.js b/packages/netlify-cms-backend-bitbucket/src/index.js index d5bebfa2..45139e5c 100644 --- a/packages/netlify-cms-backend-bitbucket/src/index.js +++ b/packages/netlify-cms-backend-bitbucket/src/index.js @@ -1,3 +1,10 @@ -export BitbucketBackend from './implementation'; -export API from './API'; -export AuthenticationPage from './AuthenticationPage'; +import Control from './implementation'; +import API from './API'; +import AuthenticationPage from './AuthenticationPage'; + +export const NetlifyCmsBackendBitbucket = { + Control, + API, + AuthenticationPage, +}; +export { Control, API, AuthenticationPage }; diff --git a/packages/netlify-cms-backend-git-gateway/package.json b/packages/netlify-cms-backend-git-gateway/package.json index 777ef14c..08c401be 100644 --- a/packages/netlify-cms-backend-git-gateway/package.json +++ b/packages/netlify-cms-backend-git-gateway/package.json @@ -25,23 +25,18 @@ "jwt-decode": "^2.2.0", "minimatch": "^3.0.4" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", "immutable": "^3.7.6", - "lodash": "^4.17.10", - "netlify-cms-backend-bitbucket": "^2.0.0", - "netlify-cms-backend-github": "^2.0.0", - "netlify-cms-backend-gitlab": "^2.0.0", - "netlify-cms-lib-auth": "^2.0.0", - "netlify-cms-lib-util": "^2.0.0", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.6.2", - "react": "^16.4.1" + "lodash": "^4.17.11", + "netlify-cms-backend-bitbucket": "^2.1.3-beta.0", + "netlify-cms-backend-github": "^2.2.3-beta.0", + "netlify-cms-backend-gitlab": "^2.1.4-beta.0", + "netlify-cms-lib-auth": "^2.0.6-beta.0", + "netlify-cms-lib-util": "^2.1.3-beta.0", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4" } } diff --git a/packages/netlify-cms-backend-git-gateway/src/implementation.js b/packages/netlify-cms-backend-git-gateway/src/implementation.js index 97e7e7dd..5324fa91 100644 --- a/packages/netlify-cms-backend-git-gateway/src/implementation.js +++ b/packages/netlify-cms-backend-git-gateway/src/implementation.js @@ -5,7 +5,7 @@ import ini from 'ini'; import { APIError, getBlobSHA, unsentRequest } from 'netlify-cms-lib-util'; import { GitHubBackend } from 'netlify-cms-backend-github'; import { GitLabBackend } from 'netlify-cms-backend-gitlab'; -import { BitBucketBackend, API as BitBucketAPI } from 'netlify-cms-backend-bitbucket'; +import { BitbucketBackend, API as BitBucketAPI } from 'netlify-cms-backend-bitbucket'; import GitHubAPI from './GitHubAPI'; import GitLabAPI from './GitLabAPI'; import AuthenticationPage from './AuthenticationPage'; @@ -168,7 +168,7 @@ export default class GitGateway { requestFunction: this.requestFunction, hasWriteAccess: async () => true, }); - this.backend = new BitBucketBackend(this.config, { ...this.options, API: this.api }); + this.backend = new BitbucketBackend(this.config, { ...this.options, API: this.api }); } if (!(await this.api.hasWriteAccess())) { diff --git a/packages/netlify-cms-backend-git-gateway/src/index.js b/packages/netlify-cms-backend-git-gateway/src/index.js index 59b7f092..20d203e7 100644 --- a/packages/netlify-cms-backend-git-gateway/src/index.js +++ b/packages/netlify-cms-backend-git-gateway/src/index.js @@ -1,2 +1,8 @@ -export GitGatewayBackend from './implementation'; -export AuthenticationPage from './AuthenticationPage'; +import Control from './implementation'; +import AuthenticationPage from './AuthenticationPage'; + +export const NetlifyCmsBackendGitGateway = { + Control, + AuthenticationPage, +}; +export { Control, AuthenticationPage }; diff --git a/packages/netlify-cms-backend-github/package.json b/packages/netlify-cms-backend-github/package.json index c3bc8084..cdd723e0 100644 --- a/packages/netlify-cms-backend-github/package.json +++ b/packages/netlify-cms-backend-github/package.json @@ -23,19 +23,14 @@ "js-base64": "^2.5.1", "semaphore": "^1.1.0" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", - "lodash": "^4.17.10", - "netlify-cms-lib-auth": "^2.0.0", - "netlify-cms-lib-util": "^2.0.0", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.6.2", - "react": "^16.4.1" + "lodash": "^4.17.11", + "netlify-cms-lib-auth": "^2.0.6-beta.0", + "netlify-cms-lib-util": "^2.1.3-beta.0", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4" } } diff --git a/packages/netlify-cms-backend-github/src/index.js b/packages/netlify-cms-backend-github/src/index.js index 6ccfbd0f..16d2b858 100644 --- a/packages/netlify-cms-backend-github/src/index.js +++ b/packages/netlify-cms-backend-github/src/index.js @@ -1,3 +1,10 @@ -export GitHubBackend from './implementation'; -export API from './API'; -export AuthenticationPage from './AuthenticationPage'; +import Control from './implementation'; +import API from './API'; +import AuthenticationPage from './AuthenticationPage'; + +export const NetlifyCmsBackendGithub = { + Control, + API, + AuthenticationPage, +}; +export { Control, API, AuthenticationPage }; diff --git a/packages/netlify-cms-backend-gitlab/package.json b/packages/netlify-cms-backend-gitlab/package.json index 01756ad6..ceb0de17 100644 --- a/packages/netlify-cms-backend-gitlab/package.json +++ b/packages/netlify-cms-backend-gitlab/package.json @@ -22,20 +22,15 @@ "js-base64": "^2.5.1", "semaphore": "^1.1.0" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", "immutable": "^3.7.6", - "lodash": "^4.17.10", - "netlify-cms-lib-auth": "^2.0.0", - "netlify-cms-lib-util": "^2.0.0", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.6.2", - "react": "^16.4.1" + "lodash": "^4.17.11", + "netlify-cms-lib-auth": "^2.0.6-beta.0", + "netlify-cms-lib-util": "^2.1.3-beta.0", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4" } } diff --git a/packages/netlify-cms-backend-gitlab/src/index.js b/packages/netlify-cms-backend-gitlab/src/index.js index a87fc489..30b047e7 100644 --- a/packages/netlify-cms-backend-gitlab/src/index.js +++ b/packages/netlify-cms-backend-gitlab/src/index.js @@ -1,3 +1,10 @@ -export GitLabBackend from './implementation'; -export API from './API'; -export AuthenticationPage from './AuthenticationPage'; +import Control from './implementation'; +import API from './API'; +import AuthenticationPage from './AuthenticationPage'; + +export const NetlifyCmsBackendGitlab = { + Control, + API, + AuthenticationPage, +}; +export { Control, API, AuthenticationPage }; diff --git a/packages/netlify-cms-backend-test/package.json b/packages/netlify-cms-backend-test/package.json index bd22da50..ad9bc151 100644 --- a/packages/netlify-cms-backend-test/package.json +++ b/packages/netlify-cms-backend-test/package.json @@ -17,23 +17,16 @@ "develop": "npm run watch", "build": "cross-env NODE_ENV=production webpack" }, - "dependencies": { - "uuid": "^3.3.2" - }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", "immutable": "^3.8.2", - "lodash": "^4.17.10", - "netlify-cms-lib-util": "^2.0.0", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.6.2", - "react": "^16.4.1", - "react-immutable-proptypes": "^2.1.0" + "lodash": "^4.17.11", + "netlify-cms-lib-util": "^2.1.3-beta.0", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4", + "react-immutable-proptypes": "^2.1.0", + "uuid": "^3.3.2" } } diff --git a/packages/netlify-cms-backend-test/src/implementation.js b/packages/netlify-cms-backend-test/src/implementation.js index db1f852d..770c51fa 100644 --- a/packages/netlify-cms-backend-test/src/implementation.js +++ b/packages/netlify-cms-backend-test/src/implementation.js @@ -40,7 +40,7 @@ const getFolderEntries = (folder, extension) => { .reverse(); }; -export default class TestRepo { +export default class TestBackend { constructor(config, options = {}) { this.config = config; this.assets = []; diff --git a/packages/netlify-cms-backend-test/src/index.js b/packages/netlify-cms-backend-test/src/index.js index 7cf84be9..5d35d8cb 100644 --- a/packages/netlify-cms-backend-test/src/index.js +++ b/packages/netlify-cms-backend-test/src/index.js @@ -1,2 +1,8 @@ -export TestBackend from './implementation'; -export AuthenticationPage from './AuthenticationPage'; +import Control from './implementation'; +import AuthenticationPage from './AuthenticationPage'; + +export const NetlifyCmsBackendTest = { + Control, + AuthenticationPage, +}; +export { Control, AuthenticationPage }; diff --git a/packages/netlify-cms-core/babel.config.js b/packages/netlify-cms-core/babel.config.js deleted file mode 100644 index bf48e647..00000000 --- a/packages/netlify-cms-core/babel.config.js +++ /dev/null @@ -1,28 +0,0 @@ -const path = require('path'); -const babelConfig = require('../../babel.config.js'); - -module.exports = { - ...babelConfig, - plugins: [ - ...babelConfig.plugins, - 'react-hot-loader/babel', - [ - 'module-resolver', - { - root: path.join(__dirname, 'src/components'), - alias: { - src: path.join(__dirname, 'src'), - Actions: path.join(__dirname, 'src/actions/'), - Constants: path.join(__dirname, 'src/constants/'), - Formats: path.join(__dirname, 'src/formats/'), - Integrations: path.join(__dirname, 'src/integrations/'), - Lib: path.join(__dirname, 'src/lib/'), - Reducers: path.join(__dirname, 'src/reducers/'), - Redux: path.join(__dirname, 'src/redux/'), - Routing: path.join(__dirname, 'src/routing/'), - ValueObjects: path.join(__dirname, 'src/valueObjects/'), - }, - }, - ], - ], -}; diff --git a/packages/netlify-cms-core/package.json b/packages/netlify-cms-core/package.json index e6d9334f..5fb83198 100644 --- a/packages/netlify-cms-core/package.json +++ b/packages/netlify-cms-core/package.json @@ -19,8 +19,6 @@ ], "license": "MIT", "dependencies": { - "@emotion/core": "^10.0.9", - "@emotion/styled": "^10.0.9", "ajv": "^6.10.0", "ajv-errors": "^1.0.1", "copy-text-to-clipboard": "^2.0.0", @@ -29,16 +27,9 @@ "gotrue-js": "^0.9.24", "gray-matter": "^4.0.2", "history": "^4.7.2", - "immutable": "^3.7.6", "js-base64": "^2.5.1", "js-yaml": "^3.12.2", "jwt-decode": "^2.1.0", - "lodash": "^4.17.11", - "moment": "^2.24.0", - "netlify-cms-editor-component-image": "^2.2.1-beta.0", - "netlify-cms-lib-auth": "^2.0.6-beta.0", - "netlify-cms-lib-util": "^2.1.3-beta.0", - "netlify-cms-ui-default": "^2.4.1-beta.0", "node-polyglot": "^2.3.0", "prop-types": "^15.7.2", "react": "^16.8.4", @@ -70,11 +61,19 @@ "url": "^0.11.0", "what-input": "^5.1.4" }, - "devDependencies": { - "cross-env": "^5.2.0", - "css-loader": "^2.1.1", - "to-string-loader": "^1.1.5", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" + "peerDependencies": { + "@emotion/core": "^10.0.9", + "@emotion/styled": "^10.0.9", + "lodash": "^4.17.11", + "netlify-cms-editor-component-image": "^2.2.1-beta.0", + "netlify-cms-lib-auth": "^2.0.6-beta.0", + "netlify-cms-lib-util": "^2.1.3-beta.0", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "moment": "^2.24.0", + "immutable": "^3.7.6", + "prop-types": "^15.7.2", + "react-immutable-proptypes": "^2.1.0", + "react": "^16.8.4", + "react-dom": "^16.8.4" } } diff --git a/packages/netlify-cms-core/src/actions/auth.js b/packages/netlify-cms-core/src/actions/auth.js index ce7479b2..ef7a19c6 100644 --- a/packages/netlify-cms-core/src/actions/auth.js +++ b/packages/netlify-cms-core/src/actions/auth.js @@ -1,5 +1,5 @@ import { actions as notifActions } from 'redux-notifications'; -import { currentBackend } from 'src/backend'; +import { currentBackend } from 'coreSrc/backend'; const { notifSend } = notifActions; diff --git a/packages/netlify-cms-core/src/actions/deploys.js b/packages/netlify-cms-core/src/actions/deploys.js index 31fbc0dd..a956d196 100644 --- a/packages/netlify-cms-core/src/actions/deploys.js +++ b/packages/netlify-cms-core/src/actions/deploys.js @@ -1,5 +1,5 @@ import { actions as notifActions } from 'redux-notifications'; -import { currentBackend } from 'src/backend'; +import { currentBackend } from 'coreSrc/backend'; import { selectDeployPreview } from 'Reducers'; const { notifSend } = notifActions; diff --git a/packages/netlify-cms-core/src/actions/editorialWorkflow.js b/packages/netlify-cms-core/src/actions/editorialWorkflow.js index 8f264c62..664489a1 100644 --- a/packages/netlify-cms-core/src/actions/editorialWorkflow.js +++ b/packages/netlify-cms-core/src/actions/editorialWorkflow.js @@ -2,7 +2,7 @@ import uuid from 'uuid/v4'; import { actions as notifActions } from 'redux-notifications'; import { BEGIN, COMMIT, REVERT } from 'redux-optimist'; import { serializeValues } from 'Lib/serializeEntryValues'; -import { currentBackend } from 'src/backend'; +import { currentBackend } from 'coreSrc/backend'; import { getAsset } from 'Reducers'; import { selectFields } from 'Reducers/collections'; import { EDITORIAL_WORKFLOW } from 'Constants/publishModes'; diff --git a/packages/netlify-cms-core/src/actions/entries.js b/packages/netlify-cms-core/src/actions/entries.js index 46edf959..9529ce25 100644 --- a/packages/netlify-cms-core/src/actions/entries.js +++ b/packages/netlify-cms-core/src/actions/entries.js @@ -1,7 +1,7 @@ import { fromJS, List, Map } from 'immutable'; import { actions as notifActions } from 'redux-notifications'; import { serializeValues } from 'Lib/serializeEntryValues'; -import { currentBackend } from 'src/backend'; +import { currentBackend } from 'coreSrc/backend'; import { getIntegrationProvider } from 'Integrations'; import { getAsset, selectIntegration } from 'Reducers'; import { selectFields } from 'Reducers/collections'; diff --git a/packages/netlify-cms-core/src/actions/mediaLibrary.js b/packages/netlify-cms-core/src/actions/mediaLibrary.js index 1b469e8d..1f2ed61d 100644 --- a/packages/netlify-cms-core/src/actions/mediaLibrary.js +++ b/packages/netlify-cms-core/src/actions/mediaLibrary.js @@ -1,7 +1,7 @@ import { Map } from 'immutable'; import { actions as notifActions } from 'redux-notifications'; import { getBlobSHA } from 'netlify-cms-lib-util'; -import { currentBackend } from 'src/backend'; +import { currentBackend } from 'coreSrc/backend'; import { createAssetProxy } from 'ValueObjects/AssetProxy'; import { selectIntegration } from 'Reducers'; import { getIntegrationProvider } from 'Integrations'; diff --git a/packages/netlify-cms-core/src/actions/search.js b/packages/netlify-cms-core/src/actions/search.js index eacb0905..16c92dee 100644 --- a/packages/netlify-cms-core/src/actions/search.js +++ b/packages/netlify-cms-core/src/actions/search.js @@ -1,4 +1,4 @@ -import { currentBackend } from 'src/backend'; +import { currentBackend } from 'coreSrc/backend'; import { getIntegrationProvider } from 'Integrations'; import { selectIntegration } from 'Reducers'; diff --git a/packages/netlify-cms-core/src/bootstrap.js b/packages/netlify-cms-core/src/bootstrap.js index a7e5c72d..e35a8afb 100644 --- a/packages/netlify-cms-core/src/bootstrap.js +++ b/packages/netlify-cms-core/src/bootstrap.js @@ -12,7 +12,7 @@ import { GlobalStyles } from 'netlify-cms-ui-default'; import { ErrorBoundary } from 'UI'; import App from 'App/App'; import 'EditorWidgets'; -import 'src/mediaLibrary'; +import 'coreSrc/mediaLibrary'; import 'what-input'; const ROOT_ID = 'nc-root'; diff --git a/packages/netlify-cms-core/src/components/App/App.js b/packages/netlify-cms-core/src/components/App/App.js index e7a42d6f..e0d06b7f 100644 --- a/packages/netlify-cms-core/src/components/App/App.js +++ b/packages/netlify-cms-core/src/components/App/App.js @@ -10,7 +10,7 @@ import { Notifs } from 'redux-notifications'; import TopBarProgress from 'react-topbar-progress-indicator'; import { loadConfig } from 'Actions/config'; import { loginUser, logoutUser } from 'Actions/auth'; -import { currentBackend } from 'src/backend'; +import { currentBackend } from 'coreSrc/backend'; import { createNewEntry } from 'Actions/collections'; import { openMediaLibrary } from 'Actions/mediaLibrary'; import MediaLibrary from 'MediaLibrary/MediaLibrary'; diff --git a/packages/netlify-cms-core/src/index.js b/packages/netlify-cms-core/src/index.js index b74d5d4f..36c4307f 100644 --- a/packages/netlify-cms-core/src/index.js +++ b/packages/netlify-cms-core/src/index.js @@ -1,4 +1,55 @@ import bootstrap from './bootstrap'; -import registry from 'Lib/registry'; +import { + registerPreviewStyle, + getPreviewStyles, + registerPreviewTemplate, + getPreviewTemplate, + registerWidget, + getWidget, + resolveWidget, + registerEditorComponent, + getEditorComponents, + registerWidgetValueSerializer, + getWidgetValueSerializer, + registerBackend, + getBackend, + registerMediaLibrary, + getMediaLibrary, +} from 'Lib/registry'; -export { registry as default, bootstrap as init }; +export const NetlifyCmsCore = { + registerPreviewStyle, + getPreviewStyles, + registerPreviewTemplate, + getPreviewTemplate, + registerWidget, + getWidget, + resolveWidget, + registerEditorComponent, + getEditorComponents, + registerWidgetValueSerializer, + getWidgetValueSerializer, + registerBackend, + getBackend, + registerMediaLibrary, + getMediaLibrary, + init: bootstrap, +}; +export { + registerPreviewStyle, + getPreviewStyles, + registerPreviewTemplate, + getPreviewTemplate, + registerWidget, + getWidget, + resolveWidget, + registerEditorComponent, + getEditorComponents, + registerWidgetValueSerializer, + getWidgetValueSerializer, + registerBackend, + getBackend, + registerMediaLibrary, + getMediaLibrary, + bootstrap as init, +}; diff --git a/packages/netlify-cms-core/src/valueObjects/AssetProxy.js b/packages/netlify-cms-core/src/valueObjects/AssetProxy.js index 79d69f73..98b86ec1 100644 --- a/packages/netlify-cms-core/src/valueObjects/AssetProxy.js +++ b/packages/netlify-cms-core/src/valueObjects/AssetProxy.js @@ -1,5 +1,5 @@ import { resolvePath } from 'netlify-cms-lib-util'; -import { currentBackend } from 'src/backend'; +import { currentBackend } from 'coreSrc/backend'; import store from 'Redux'; import { getIntegrationProvider } from 'Integrations'; import { selectIntegration } from 'Reducers'; diff --git a/packages/netlify-cms-core/webpack.config.js b/packages/netlify-cms-core/webpack.config.js index 92a5d71b..8dd01cad 100644 --- a/packages/netlify-cms-core/webpack.config.js +++ b/packages/netlify-cms-core/webpack.config.js @@ -1,43 +1,21 @@ -const path = require('path'); const webpack = require('webpack'); const pkg = require('./package.json'); -const { getConfig, rules } = require('../../scripts/webpack.js'); +const { getConfig } = require('../../scripts/webpack.js'); const isProduction = process.env.NODE_ENV === 'production'; -const baseConfig = getConfig(); +const versionPlugin = new webpack.DefinePlugin({ + NETLIFY_CMS_VERSION: null, + NETLIFY_CMS_CORE_VERSION: JSON.stringify(`${pkg.version}${isProduction ? '' : '-dev'}`), +}); -module.exports = { - ...baseConfig, - context: path.join(__dirname, 'src'), - entry: ['./index.js'], - module: { - rules: [ - ...Object.entries(rules) - .filter(([key]) => key !== 'js') - .map(([, rule]) => rule()), - { - test: /\.js$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - configFile: path.join(__dirname, 'babel.config.js'), - }, - }, - }, - { - test: /\.css$/, - include: [/(ol|redux-notifications|react-datetime)/], - use: ['to-string-loader', 'css-loader'], - }, - ], - }, - plugins: [ - ...baseConfig.plugins, - new webpack.DefinePlugin({ - NETLIFY_CMS_VERSION: null, - NETLIFY_CMS_CORE_VERSION: JSON.stringify(`${pkg.version}${isProduction ? '' : '-dev'}`), - }), - ], +const configs = () => { + return getConfig().map(config => { + return { + ...config, + plugins: [...config.plugins, versionPlugin], + }; + }); }; + +module.exports = configs(); diff --git a/packages/netlify-cms-default-exports/package.json b/packages/netlify-cms-default-exports/package.json new file mode 100644 index 00000000..5f394a62 --- /dev/null +++ b/packages/netlify-cms-default-exports/package.json @@ -0,0 +1,36 @@ +{ + "name": "netlify-cms-default-exports", + "version": "2.0.1", + "description": "NetlifyCMS default exports", + "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports", + "bugs": "https://github.com/netlify/netlify-cms/issues", + "main": "dist/netlify-cms-editor-component-image.js", + "license": "MIT", + "keywords": [ + "netlify", + "netlify-cms", + "editor", + "component" + ], + "sideEffects": false, + "scripts": { + "watch": "webpack -w", + "develop": "npm run watch", + "build": "cross-env NODE_ENV=production webpack", + "build:dev": "cross-env NODE_ENV=development webpack" + }, + "dependencies": { + "@emotion/core": "^10.0.9", + "@emotion/styled": "^10.0.9", + "immutable": "^3.7.6", + "lodash": "^4.17.11", + "moment": "^2.24.0", + "prop-types": "^15.7.2", + "react-immutable-proptypes": "^2.1.0", + "uuid": "^3.3.2" + }, + "peerDependencies": { + "react": "^16.8.4", + "react-dom": "^16.8.4" + } +} diff --git a/packages/netlify-cms-default-exports/src/index.js b/packages/netlify-cms-default-exports/src/index.js new file mode 100644 index 00000000..35864f85 --- /dev/null +++ b/packages/netlify-cms-default-exports/src/index.js @@ -0,0 +1,54 @@ +import css from '@emotion/css'; +import { + withEmotionCache, + CacheProvider, + ThemeContext, + jsx, + Global, + keyframes, + ClassNames, +} from '@emotion/core'; +import EmotionStyled from '@emotion/styled'; +import Immutable from 'immutable'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import Lodash from 'lodash/lodash'; +import Moment from 'moment'; +import PropTypes from 'prop-types'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import * as UUId from 'uuid'; + +const EmotionCore = { + css, + withEmotionCache, + CacheProvider, + ThemeContext, + jsx, + Global, + keyframes, + ClassNames, +}; +export const NetlifyCmsDefaultExports = { + EmotionCore, + EmotionStyled, + Immutable, + ImmutablePropTypes, + Lodash, + Moment, + PropTypes, + React, + ReactDOM, + UUId, +}; +export { + EmotionCore, + EmotionStyled, + Immutable, + ImmutablePropTypes, + Lodash, + Moment, + PropTypes, + React, + ReactDOM, + UUId, +}; diff --git a/packages/netlify-cms-default-exports/webpack.config.js b/packages/netlify-cms-default-exports/webpack.config.js new file mode 100644 index 00000000..42edd361 --- /dev/null +++ b/packages/netlify-cms-default-exports/webpack.config.js @@ -0,0 +1,3 @@ +const { getConfig } = require('../../scripts/webpack.js'); + +module.exports = getConfig(); diff --git a/packages/netlify-cms-editor-component-image/package.json b/packages/netlify-cms-editor-component-image/package.json index bf993821..67dfe834 100644 --- a/packages/netlify-cms-editor-component-image/package.json +++ b/packages/netlify-cms-editor-component-image/package.json @@ -24,6 +24,6 @@ "webpack-cli": "^3.2.3" }, "peerDependencies": { - "react": "^16.4.1" + "react": "^16.8.4" } } diff --git a/packages/netlify-cms-editor-component-image/src/index.js b/packages/netlify-cms-editor-component-image/src/index.js index 10dd83d8..bf57d56f 100644 --- a/packages/netlify-cms-editor-component-image/src/index.js +++ b/packages/netlify-cms-editor-component-image/src/index.js @@ -36,4 +36,5 @@ const image = { ], }; +export const NetlifyCmsEditorComponentImage = image; export default image; diff --git a/packages/netlify-cms-lib-auth/package.json b/packages/netlify-cms-lib-auth/package.json index 5efbfcd8..a6f5ece1 100644 --- a/packages/netlify-cms-lib-auth/package.json +++ b/packages/netlify-cms-lib-auth/package.json @@ -22,13 +22,8 @@ "dependencies": { "uuid": "^3.1.0" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "immutable": "^3.7.6", - "lodash": "^4.13.1" + "lodash": "^4.17.11" } } diff --git a/packages/netlify-cms-lib-auth/src/index.js b/packages/netlify-cms-lib-auth/src/index.js index 98c601fc..0cd6f7ee 100644 --- a/packages/netlify-cms-lib-auth/src/index.js +++ b/packages/netlify-cms-lib-auth/src/index.js @@ -1,2 +1,4 @@ -export NetlifyAuthenticator from './netlify-auth'; -export ImplicitAuthenticator from './implicit-oauth'; +import NetlifyAuthenticator from './netlify-auth'; +import ImplicitAuthenticator from './implicit-oauth'; +export const NetlifyCmsLibAuth = { NetlifyAuthenticator, ImplicitAuthenticator }; +export { NetlifyAuthenticator, ImplicitAuthenticator }; diff --git a/packages/netlify-cms-lib-util/package.json b/packages/netlify-cms-lib-util/package.json index 29ded504..223a4731 100644 --- a/packages/netlify-cms-lib-util/package.json +++ b/packages/netlify-cms-lib-util/package.json @@ -19,13 +19,8 @@ "js-sha256": "^0.9.0", "localforage": "^1.7.3" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "immutable": "^3.7.6", - "lodash": "^4.13.1" + "lodash": "^4.17.11" } } diff --git a/packages/netlify-cms-lib-util/src/index.js b/packages/netlify-cms-lib-util/src/index.js index 81cedfb7..5ff3b8a1 100644 --- a/packages/netlify-cms-lib-util/src/index.js +++ b/packages/netlify-cms-lib-util/src/index.js @@ -1,10 +1,53 @@ -export APIError from './APIError'; -export Cursor, { CURSOR_COMPATIBILITY_SYMBOL } from './Cursor'; -export EditorialWorkflowError, { EDITORIAL_WORKFLOW_ERROR } from './EditorialWorkflowError'; -export localForage from './localForage'; -export { resolvePath, basename, fileExtensionWithSeparator, fileExtension } from './path'; -export { filterPromises, resolvePromiseProperties, then } from './promise'; -export unsentRequest from './unsentRequest'; -export { filterByPropExtension, parseResponse, responseParser } from './backendUtil'; -export loadScript from './loadScript'; -export getBlobSHA from './getBlobSHA'; +import APIError from './APIError'; +import Cursor, { CURSOR_COMPATIBILITY_SYMBOL } from './Cursor'; +import EditorialWorkflowError, { EDITORIAL_WORKFLOW_ERROR } from './EditorialWorkflowError'; +import localForage from './localForage'; +import { resolvePath, basename, fileExtensionWithSeparator, fileExtension } from './path'; +import { filterPromises, resolvePromiseProperties, then } from './promise'; +import unsentRequest from './unsentRequest'; +import { filterByPropExtension, parseResponse, responseParser } from './backendUtil'; +import loadScript from './loadScript'; +import getBlobSHA from './getBlobSHA'; + +export const NetlifyCmsLibUtil = { + APIError, + Cursor, + CURSOR_COMPATIBILITY_SYMBOL, + EditorialWorkflowError, + EDITORIAL_WORKFLOW_ERROR, + localForage, + resolvePath, + basename, + fileExtensionWithSeparator, + fileExtension, + filterPromises, + resolvePromiseProperties, + then, + unsentRequest, + filterByPropExtension, + parseResponse, + responseParser, + loadScript, + getBlobSHA, +}; +export { + APIError, + Cursor, + CURSOR_COMPATIBILITY_SYMBOL, + EditorialWorkflowError, + EDITORIAL_WORKFLOW_ERROR, + localForage, + resolvePath, + basename, + fileExtensionWithSeparator, + fileExtension, + filterPromises, + resolvePromiseProperties, + then, + unsentRequest, + filterByPropExtension, + parseResponse, + responseParser, + loadScript, + getBlobSHA, +}; diff --git a/packages/netlify-cms-media-library-cloudinary/package.json b/packages/netlify-cms-media-library-cloudinary/package.json index 3e65d9cf..ac241cbe 100644 --- a/packages/netlify-cms-media-library-cloudinary/package.json +++ b/packages/netlify-cms-media-library-cloudinary/package.json @@ -23,12 +23,7 @@ "develop": "npm run watch", "build": "cross-env NODE_ENV=production webpack" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { - "netlify-cms-lib-util": "^2.0.4" + "netlify-cms-lib-util": "^2.1.3-beta.0" } } diff --git a/packages/netlify-cms-media-library-cloudinary/src/index.js b/packages/netlify-cms-media-library-cloudinary/src/index.js index 62fbaff3..e9b9b350 100644 --- a/packages/netlify-cms-media-library-cloudinary/src/index.js +++ b/packages/netlify-cms-media-library-cloudinary/src/index.js @@ -83,4 +83,5 @@ async function init({ options = {}, handleInsert } = {}) { const cloudinaryMediaLibrary = { name: 'cloudinary', init }; +export const NetlifyCmsMediaLibraryCloudinary = cloudinaryMediaLibrary; export default cloudinaryMediaLibrary; diff --git a/packages/netlify-cms-media-library-uploadcare/package.json b/packages/netlify-cms-media-library-uploadcare/package.json index 47ec7ce6..8fb4e0cb 100644 --- a/packages/netlify-cms-media-library-uploadcare/package.json +++ b/packages/netlify-cms-media-library-uploadcare/package.json @@ -21,11 +21,6 @@ "develop": "npm run watch", "build": "cross-env NODE_ENV=production webpack" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "dependencies": { "uploadcare-widget": "^3.7.0", "uploadcare-widget-tab-effects": "^1.4.0" diff --git a/packages/netlify-cms-media-library-uploadcare/src/index.js b/packages/netlify-cms-media-library-uploadcare/src/index.js index 479f1c22..8904f57f 100644 --- a/packages/netlify-cms-media-library-uploadcare/src/index.js +++ b/packages/netlify-cms-media-library-uploadcare/src/index.js @@ -140,4 +140,5 @@ async function init({ options = { config: {} }, handleInsert } = {}) { */ const uploadcareMediaLibrary = { name: 'uploadcare', init }; +export const NetlifyCmsMediaLibraryUploadcare = uploadcareMediaLibrary; export default uploadcareMediaLibrary; diff --git a/packages/netlify-cms-ui-default/package.json b/packages/netlify-cms-ui-default/package.json index e1eecc9c..94c55d86 100644 --- a/packages/netlify-cms-ui-default/package.json +++ b/packages/netlify-cms-ui-default/package.json @@ -20,16 +20,11 @@ "react-toggled": "^1.1.2", "react-transition-group": "^2.6.0" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", - "lodash": "^4.13.1", - "prop-types": "^15.5.10", - "react": "^16.4.1" + "lodash": "^4.17.11", + "prop-types": "^15.7.2", + "react": "^16.8.4" } } diff --git a/packages/netlify-cms-ui-default/src/index.js b/packages/netlify-cms-ui-default/src/index.js index 481a4636..02f9f2b5 100644 --- a/packages/netlify-cms-ui-default/src/index.js +++ b/packages/netlify-cms-ui-default/src/index.js @@ -1,12 +1,12 @@ -export Dropdown, { DropdownItem, DropdownButton, StyledDropdownButton } from './Dropdown'; -export Icon from './Icon'; -export ListItemTopBar from './ListItemTopBar'; -export Loader from './Loader'; -export Toggle, { ToggleContainer, ToggleBackground, ToggleHandle } from './Toggle'; -export AuthenticationPage from './AuthenticationPage'; -export WidgetPreviewContainer from './WidgetPreviewContainer'; -export ObjectWidgetTopBar from './ObjectWidgetTopBar'; -export { +import Dropdown, { DropdownItem, DropdownButton, StyledDropdownButton } from './Dropdown'; +import Icon from './Icon'; +import ListItemTopBar from './ListItemTopBar'; +import Loader from './Loader'; +import Toggle, { ToggleContainer, ToggleBackground, ToggleHandle } from './Toggle'; +import AuthenticationPage from './AuthenticationPage'; +import WidgetPreviewContainer from './WidgetPreviewContainer'; +import ObjectWidgetTopBar from './ObjectWidgetTopBar'; +import { fonts, colorsRaw, colors, @@ -20,3 +20,60 @@ export { reactSelectStyles, GlobalStyles, } from './styles'; + +export const NetlifyCmsUiDefault = { + Dropdown, + DropdownItem, + DropdownButton, + StyledDropdownButton, + ListItemTopBar, + Icon, + Loader, + Toggle, + ToggleContainer, + ToggleBackground, + ToggleHandle, + AuthenticationPage, + WidgetPreviewContainer, + ObjectWidgetTopBar, + fonts, + colorsRaw, + colors, + lengths, + components, + buttons, + shadows, + borders, + transitions, + effects, + reactSelectStyles, + GlobalStyles, +}; +export { + Dropdown, + DropdownItem, + DropdownButton, + StyledDropdownButton, + ListItemTopBar, + Icon, + Loader, + Toggle, + ToggleContainer, + ToggleBackground, + ToggleHandle, + AuthenticationPage, + WidgetPreviewContainer, + ObjectWidgetTopBar, + fonts, + colorsRaw, + colors, + lengths, + components, + buttons, + shadows, + borders, + transitions, + effects, + reactSelectStyles, + GlobalStyles, +}; diff --git a/packages/netlify-cms-widget-boolean/package.json b/packages/netlify-cms-widget-boolean/package.json index e0f4d53d..06d76574 100644 --- a/packages/netlify-cms-widget-boolean/package.json +++ b/packages/netlify-cms-widget-boolean/package.json @@ -19,17 +19,12 @@ "develop": "npm run watch", "build": "cross-env NODE_ENV=production webpack" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", - "lodash": "^4.17.10", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1", + "lodash": "^4.17.11", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4", "react-immutable-proptypes": "^2.1.0" } } diff --git a/packages/netlify-cms-widget-boolean/src/index.js b/packages/netlify-cms-widget-boolean/src/index.js index 3b172e90..a5634e66 100644 --- a/packages/netlify-cms-widget-boolean/src/index.js +++ b/packages/netlify-cms-widget-boolean/src/index.js @@ -1 +1,3 @@ -export BooleanControl from './BooleanControl'; +import controlComponent from './BooleanControl'; +export const NetlifyCmsWidgetBoolean = { controlComponent }; +export { controlComponent }; diff --git a/packages/netlify-cms-widget-date/package.json b/packages/netlify-cms-widget-date/package.json index 24254290..3e774e49 100644 --- a/packages/netlify-cms-widget-date/package.json +++ b/packages/netlify-cms-widget-date/package.json @@ -23,19 +23,13 @@ "dependencies": { "react-datetime": "^2.16.3" }, - "devDependencies": { - "cross-env": "^5.2.0", - "css-loader": "^2.1.1", - "to-string-loader": "^1.1.5", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", - "moment": "^2.11.2", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1" + "moment": "^2.24.0", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4", + "react-dom": "^16.8.4" } } diff --git a/packages/netlify-cms-widget-date/src/index.js b/packages/netlify-cms-widget-date/src/index.js index 5e6d2b9a..fb3d1883 100644 --- a/packages/netlify-cms-widget-date/src/index.js +++ b/packages/netlify-cms-widget-date/src/index.js @@ -8,4 +8,5 @@ const Widget = (opts = {}) => ({ ...opts, }); +export const NetlifyCmsWidgetDate = { Widget, controlComponent, previewComponent }; export { Widget as default, controlComponent, previewComponent }; diff --git a/packages/netlify-cms-widget-date/webpack.config.js b/packages/netlify-cms-widget-date/webpack.config.js index d39ce069..42edd361 100644 --- a/packages/netlify-cms-widget-date/webpack.config.js +++ b/packages/netlify-cms-widget-date/webpack.config.js @@ -1,17 +1,3 @@ const { getConfig } = require('../../scripts/webpack.js'); -const baseWebpackConfig = getConfig(); - -module.exports = { - ...baseWebpackConfig, - module: { - rules: [ - ...baseWebpackConfig.module.rules, - { - test: /\.css$/, - include: [/react-datetime/], - use: ['to-string-loader', 'css-loader'], - }, - ], - }, -}; +module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-datetime/package.json b/packages/netlify-cms-widget-datetime/package.json index a8681666..352c58cb 100644 --- a/packages/netlify-cms-widget-datetime/package.json +++ b/packages/netlify-cms-widget-datetime/package.json @@ -21,19 +21,9 @@ "develop": "npm run watch", "build": "cross-env NODE_ENV=production webpack" }, - "dependencies": { - "netlify-cms-widget-date": "^2.1.1-beta.0" - }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", - "react": "^16.4.1" - }, - "localExternals": [ - "netlify-cms-widget-date" - ] + "netlify-cms-widget-date": "^2.1.1-beta.0", + "react": "^16.8.4" + } } diff --git a/packages/netlify-cms-widget-datetime/src/index.js b/packages/netlify-cms-widget-datetime/src/index.js index bcdcb67a..01bb74bd 100644 --- a/packages/netlify-cms-widget-datetime/src/index.js +++ b/packages/netlify-cms-widget-datetime/src/index.js @@ -8,4 +8,5 @@ const Widget = (opts = {}) => ({ ...opts, }); +export const NetlifyCmsWidgetDatetime = { Widget, controlComponent, previewComponent }; export { Widget as default, controlComponent, previewComponent }; diff --git a/packages/netlify-cms-widget-file/package.json b/packages/netlify-cms-widget-file/package.json index 915d9fc8..ba297d93 100644 --- a/packages/netlify-cms-widget-file/package.json +++ b/packages/netlify-cms-widget-file/package.json @@ -25,18 +25,13 @@ "common-tags": "^1.8.0", "uuid": "^3.3.2" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", "immutable": "^3.7.6", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4", "react-immutable-proptypes": "^2.1.0" } } diff --git a/packages/netlify-cms-widget-file/src/index.js b/packages/netlify-cms-widget-file/src/index.js index 68141579..42d382e1 100644 --- a/packages/netlify-cms-widget-file/src/index.js +++ b/packages/netlify-cms-widget-file/src/index.js @@ -1,5 +1,6 @@ import withFileControl from './withFileControl'; +import previewComponent from './FilePreview'; -export { withFileControl }; -export const FileControl = withFileControl(); -export FilePreview from './FilePreview'; +const controlComponent = withFileControl(); +export const NetlifyCmsWidgetFile = { controlComponent, previewComponent, withFileControl }; +export { controlComponent, previewComponent, withFileControl }; diff --git a/packages/netlify-cms-widget-image/package.json b/packages/netlify-cms-widget-image/package.json index 24476553..1820a0d9 100644 --- a/packages/netlify-cms-widget-image/package.json +++ b/packages/netlify-cms-widget-image/package.json @@ -21,23 +21,13 @@ "develop": "npm run watch", "build": "cross-env NODE_ENV=production webpack" }, - "dependencies": { - "netlify-cms-widget-file": "^2.2.1-beta.0" - }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", "immutable": "^3.7.6", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1" - }, - "localExternals": [ - "netlify-cms-widget-file" - ] + "netlify-cms-ui-default": "^2.4.1-beta.0", + "netlify-cms-widget-file": "^2.2.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4" + } } diff --git a/packages/netlify-cms-widget-image/src/index.js b/packages/netlify-cms-widget-image/src/index.js index b437a158..4f54db31 100644 --- a/packages/netlify-cms-widget-image/src/index.js +++ b/packages/netlify-cms-widget-image/src/index.js @@ -1,4 +1,6 @@ import { withFileControl } from 'netlify-cms-widget-file'; -export const ImageControl = withFileControl({ forImage: true }); -export ImagePreview from './ImagePreview'; +const controlComponent = withFileControl({ forImage: true }); +import previewComponent from './ImagePreview'; +export const NetlifyCmsWidgetImage = { controlComponent, previewComponent }; +export { controlComponent, previewComponent }; diff --git a/packages/netlify-cms-widget-list/package.json b/packages/netlify-cms-widget-list/package.json index b79144ca..69e2a6b4 100644 --- a/packages/netlify-cms-widget-list/package.json +++ b/packages/netlify-cms-widget-list/package.json @@ -21,25 +21,17 @@ "build": "cross-env NODE_ENV=production webpack" }, "dependencies": { - "netlify-cms-widget-object": "^2.0.7-beta.0", "react-sortable-hoc": "^1.0.0" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", "immutable": "^3.7.6", - "lodash": "^4.17.10", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1", + "lodash": "^4.17.11", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "netlify-cms-widget-object": "^2.0.7-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4", "react-immutable-proptypes": "^2.1.0" - }, - "localExternals": [ - "netlify-cms-widget-object" - ] + } } diff --git a/packages/netlify-cms-widget-list/src/ListControl.js b/packages/netlify-cms-widget-list/src/ListControl.js index 0bd0f44f..192df0d2 100644 --- a/packages/netlify-cms-widget-list/src/ListControl.js +++ b/packages/netlify-cms-widget-list/src/ListControl.js @@ -7,7 +7,7 @@ import { jsx, css, ClassNames } from '@emotion/core'; import { List, Map } from 'immutable'; import { partial } from 'lodash'; import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc'; -import { ObjectControl } from 'netlify-cms-widget-object'; +import { controlComponent as ObjectControl } from 'netlify-cms-widget-object'; import { TYPES_KEY, getTypedFieldForValue, diff --git a/packages/netlify-cms-widget-list/src/index.js b/packages/netlify-cms-widget-list/src/index.js index 1ed5ac45..0821dfd8 100644 --- a/packages/netlify-cms-widget-list/src/index.js +++ b/packages/netlify-cms-widget-list/src/index.js @@ -1,2 +1,4 @@ -export ListControl from './ListControl'; -export { ObjectPreview as ListPreview } from 'netlify-cms-widget-object'; +import controlComponent from './ListControl'; +import { previewComponent } from 'netlify-cms-widget-object'; +export const NetlifyCmsWidgetList = { controlComponent, previewComponent }; +export { controlComponent, previewComponent }; diff --git a/packages/netlify-cms-widget-map/package.json b/packages/netlify-cms-widget-map/package.json index b7958559..544292f6 100644 --- a/packages/netlify-cms-widget-map/package.json +++ b/packages/netlify-cms-widget-map/package.json @@ -20,19 +20,12 @@ "develop": "npm run watch", "build": "cross-env NODE_ENV=production webpack" }, - "devDependencies": { - "cross-env": "^5.2.0", - "css-loader": "^2.1.1", - "to-string-loader": "^1.1.5", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", - "lodash": "^4.17.10", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1", + "lodash": "^4.17.11", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4", "react-immutable-proptypes": "^2.1.0" }, "dependencies": { diff --git a/packages/netlify-cms-widget-map/src/index.js b/packages/netlify-cms-widget-map/src/index.js index c5ae4dbe..79fb26b1 100644 --- a/packages/netlify-cms-widget-map/src/index.js +++ b/packages/netlify-cms-widget-map/src/index.js @@ -1,5 +1,6 @@ import withMapControl from './withMapControl'; +import previewComponent from './MapPreview'; +const controlComponent = withMapControl(); -export { withMapControl }; -export const MapControl = withMapControl(); -export MapPreview from './MapPreview'; +export const NetlifyCmsWidgetMap = { controlComponent, previewComponent }; +export { controlComponent, previewComponent }; diff --git a/packages/netlify-cms-widget-map/webpack.config.js b/packages/netlify-cms-widget-map/webpack.config.js index ca6a676d..42edd361 100644 --- a/packages/netlify-cms-widget-map/webpack.config.js +++ b/packages/netlify-cms-widget-map/webpack.config.js @@ -1,17 +1,3 @@ const { getConfig } = require('../../scripts/webpack.js'); -const baseWebpackConfig = getConfig(); - -module.exports = { - ...baseWebpackConfig, - module: { - rules: [ - ...baseWebpackConfig.module.rules, - { - test: /\.css$/, - include: [/ol/], - use: ['to-string-loader', 'css-loader'], - }, - ], - }, -}; +module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-markdown/package.json b/packages/netlify-cms-widget-markdown/package.json index 82d73e48..3e98084c 100644 --- a/packages/netlify-cms-widget-markdown/package.json +++ b/packages/netlify-cms-widget-markdown/package.json @@ -40,20 +40,15 @@ "unist-builder": "^1.0.2", "unist-util-visit-parents": "^1.1.1" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", "immutable": "^3.7.6", - "lodash": "^4.17.10", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1", - "react-dom": "^16.0.0", + "lodash": "^4.17.11", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4", + "react-dom": "^16.8.4", "react-immutable-proptypes": "^2.1.0" } } diff --git a/packages/netlify-cms-widget-markdown/src/index.js b/packages/netlify-cms-widget-markdown/src/index.js index df1c2ad9..92eb8147 100644 --- a/packages/netlify-cms-widget-markdown/src/index.js +++ b/packages/netlify-cms-widget-markdown/src/index.js @@ -1,2 +1,4 @@ -export MarkdownControl from './MarkdownControl'; -export MarkdownPreview from './MarkdownPreview'; +import controlComponent from './MarkdownControl'; +import previewComponent from './MarkdownPreview'; +export const NetlifyCmsWidgetMarkdown = { controlComponent, previewComponent }; +export { controlComponent, previewComponent }; diff --git a/packages/netlify-cms-widget-number/package.json b/packages/netlify-cms-widget-number/package.json index cc91ebed..bbcba6e2 100644 --- a/packages/netlify-cms-widget-number/package.json +++ b/packages/netlify-cms-widget-number/package.json @@ -19,14 +19,9 @@ "develop": "npm run watch", "build": "cross-env NODE_ENV=production webpack" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1" + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4" } } diff --git a/packages/netlify-cms-widget-number/src/__tests__/number.spec.js b/packages/netlify-cms-widget-number/src/__tests__/number.spec.js index 00fc8f04..716041f6 100644 --- a/packages/netlify-cms-widget-number/src/__tests__/number.spec.js +++ b/packages/netlify-cms-widget-number/src/__tests__/number.spec.js @@ -3,7 +3,7 @@ import { fromJS } from 'immutable'; import { render, fireEvent } from 'react-testing-library'; import 'react-testing-library/cleanup-after-each'; import 'jest-dom/extend-expect'; -import { NumberControl } from '../'; +import { controlComponent as NumberControl } from '../'; const fieldSettings = { min: -20, diff --git a/packages/netlify-cms-widget-number/src/index.js b/packages/netlify-cms-widget-number/src/index.js index c9aab310..3d8aa6ae 100644 --- a/packages/netlify-cms-widget-number/src/index.js +++ b/packages/netlify-cms-widget-number/src/index.js @@ -1,2 +1,4 @@ -export NumberControl from './NumberControl'; -export NumberPreview from './NumberPreview'; +import controlComponent from './NumberControl'; +import previewComponent from './NumberPreview'; +export const NetlifyCmsWidgetNumber = { controlComponent, previewComponent }; +export { controlComponent, previewComponent }; diff --git a/packages/netlify-cms-widget-object/package.json b/packages/netlify-cms-widget-object/package.json index c29c12c6..e0df3164 100644 --- a/packages/netlify-cms-widget-object/package.json +++ b/packages/netlify-cms-widget-object/package.json @@ -21,19 +21,14 @@ "develop": "npm run watch", "build": "cross-env NODE_ENV=production webpack" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", "immutable": "^3.7.6", - "lodash": "^4.17.10", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1", + "lodash": "^4.17.11", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4", "react-immutable-proptypes": "^2.1.0" } } diff --git a/packages/netlify-cms-widget-object/src/index.js b/packages/netlify-cms-widget-object/src/index.js index ea1f17ea..2995beaa 100644 --- a/packages/netlify-cms-widget-object/src/index.js +++ b/packages/netlify-cms-widget-object/src/index.js @@ -1,2 +1,4 @@ -export ObjectControl from './ObjectControl'; -export ObjectPreview from './ObjectPreview'; +import controlComponent from './ObjectControl'; +import previewComponent from './ObjectPreview'; +export const NetlifyCmsWidgetObject = { controlComponent, previewComponent }; +export { controlComponent, previewComponent }; diff --git a/packages/netlify-cms-widget-relation/package.json b/packages/netlify-cms-widget-relation/package.json index 0813920a..7679ff35 100644 --- a/packages/netlify-cms-widget-relation/package.json +++ b/packages/netlify-cms-widget-relation/package.json @@ -23,19 +23,14 @@ "dependencies": { "react-select": "^2.4.2" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", "immutable": "^3.7.6", - "lodash": "^4.17.10", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1", + "lodash": "^4.17.11", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4", "uuid": "^3.1.0" } } diff --git a/packages/netlify-cms-widget-relation/src/__tests__/relation.spec.js b/packages/netlify-cms-widget-relation/src/__tests__/relation.spec.js index cb51b685..fb42c103 100644 --- a/packages/netlify-cms-widget-relation/src/__tests__/relation.spec.js +++ b/packages/netlify-cms-widget-relation/src/__tests__/relation.spec.js @@ -1,206 +1,206 @@ -import React from 'react'; -import { fromJS, Map } from 'immutable'; -import { last } from 'lodash'; -import { render, fireEvent, wait } from 'react-testing-library'; -import 'react-testing-library/cleanup-after-each'; -import 'jest-dom/extend-expect'; -import { RelationControl } from '../'; - -const fieldConfig = { - name: 'post', - collection: 'posts', - displayFields: ['title', 'slug'], - searchFields: ['title', 'body'], - valueField: 'title', -}; - -const generateHits = length => { - const hits = Array.from({ length }, (val, idx) => { - const title = `Post # ${idx + 1}`; - const slug = `post-number-${idx + 1}`; - return { collection: 'posts', data: { title, slug } }; - }); - - return [ - ...hits, - { - collection: 'posts', - data: { title: 'YAML post', slug: 'post-yaml', body: 'Body yaml' }, - }, - ]; -}; - -class RelationController extends React.Component { - state = { - value: this.props.value, - queryHits: Map(), - }; - - handleOnChange = jest.fn(value => { - this.setState({ ...this.state, value }); - }); - - setQueryHits = jest.fn(hits => { - const queryHits = Map().set('relation-field', hits); - this.setState({ ...this.state, queryHits }); - }); - - query = jest.fn((...args) => { - const queryHits = generateHits(25); - if (last(args) === 'YAML') { - return Promise.resolve({ payload: { response: { hits: [last(queryHits)] } } }); - } - return Promise.resolve({ payload: { response: { hits: queryHits } } }); - }); - - render() { - return this.props.children({ - value: this.state.value, - handleOnChange: this.handleOnChange, - query: this.query, - queryHits: this.state.queryHits, - setQueryHits: this.setQueryHits, - }); - } -} - -function setup({ field, value }) { - let renderArgs; - const setActiveSpy = jest.fn(); - const setInactiveSpy = jest.fn(); - - const helpers = render( - - {({ handleOnChange, value, query, queryHits, setQueryHits }) => { - renderArgs = { value, onChangeSpy: handleOnChange, setQueryHitsSpy: setQueryHits }; - return ( - - ); - }} - , - ); - - const input = helpers.container.querySelector('input'); - - return { - ...helpers, - ...renderArgs, - setActiveSpy, - setInactiveSpy, - input, - }; -} - -describe('Relation widget', () => { - it('should list the first 20 option hits on initial load', async () => { - const field = fromJS(fieldConfig); - const { getAllByText, input } = setup({ field }); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - - await wait(() => { - expect(getAllByText(/^Post # (\d{1,2}) post-number-\1$/)).toHaveLength(20); - }); - }); - - it('should update option list based on search term', async () => { - const field = fromJS(fieldConfig); - const { getAllByText, input } = setup({ field }); - fireEvent.change(input, { target: { value: 'YAML' } }); - - await wait(() => { - expect(getAllByText('YAML post post-yaml')).toHaveLength(1); - }); - }); - - it('should call onChange with correct selectedItem value and metadata', async () => { - const field = fromJS(fieldConfig); - const { getByText, input, onChangeSpy } = setup({ field }); - const value = 'Post # 1'; - const label = 'Post # 1 post-number-1'; - const metadata = { - post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } }, - }; - - await wait(() => { - fireEvent.keyDown(input, { key: 'ArrowDown' }); - fireEvent.click(getByText(label)); - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(value, metadata); - }); - }); - - it('should update metadata for initial preview', async () => { - const field = fromJS(fieldConfig); - const value = 'Post # 1'; - const { getByText, onChangeSpy, setQueryHitsSpy } = setup({ field, value }); - const label = 'Post # 1 post-number-1'; - const metadata = { - post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } }, - }; - - setQueryHitsSpy(generateHits(1)); - - await wait(() => { - expect(getByText(label)).toBeInTheDocument(); - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(value, metadata); - }); - }); - - describe('with multiple', () => { - it('should call onChange with correct selectedItem value and metadata', async () => { - const field = fromJS({ ...fieldConfig, multiple: true }); - const { getByText, input, onChangeSpy } = setup({ field }); - const metadata1 = { - post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } }, - }; - const metadata2 = { - post: { posts: { 'Post # 2': { title: 'Post # 2', slug: 'post-number-2' } } }, - }; - - await wait(() => { - fireEvent.keyDown(input, { key: 'ArrowDown' }); - fireEvent.click(getByText('Post # 1 post-number-1')); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - fireEvent.click(getByText('Post # 2 post-number-2')); - - expect(onChangeSpy).toHaveBeenCalledTimes(2); - expect(onChangeSpy).toHaveBeenCalledWith(fromJS(['Post # 1']), metadata1); - expect(onChangeSpy).toHaveBeenCalledWith(fromJS(['Post # 1', 'Post # 2']), metadata2); - }); - }); - - it('should update metadata for initial preview', async () => { - const field = fromJS({ ...fieldConfig, multiple: true }); - const value = fromJS(['Post # 1', 'Post # 2']); - const { getByText, onChangeSpy, setQueryHitsSpy } = setup({ field, value }); - const metadata1 = { - post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } }, - }; - const metadata2 = { - post: { posts: { 'Post # 2': { title: 'Post # 2', slug: 'post-number-2' } } }, - }; - - setQueryHitsSpy(generateHits(2)); - - await wait(() => { - expect(getByText('Post # 1 post-number-1')).toBeInTheDocument(); - expect(getByText('Post # 2 post-number-2')).toBeInTheDocument(); - - expect(onChangeSpy).toHaveBeenCalledTimes(2); - expect(onChangeSpy).toHaveBeenCalledWith(value, metadata1); - expect(onChangeSpy).toHaveBeenCalledWith(value, metadata2); - }); - }); - }); -}); +import React from 'react'; +import { fromJS, Map } from 'immutable'; +import { last } from 'lodash'; +import { render, fireEvent, wait } from 'react-testing-library'; +import 'react-testing-library/cleanup-after-each'; +import 'jest-dom/extend-expect'; +import { controlComponent as RelationControl } from '../'; + +const fieldConfig = { + name: 'post', + collection: 'posts', + displayFields: ['title', 'slug'], + searchFields: ['title', 'body'], + valueField: 'title', +}; + +const generateHits = length => { + const hits = Array.from({ length }, (val, idx) => { + const title = `Post # ${idx + 1}`; + const slug = `post-number-${idx + 1}`; + return { collection: 'posts', data: { title, slug } }; + }); + + return [ + ...hits, + { + collection: 'posts', + data: { title: 'YAML post', slug: 'post-yaml', body: 'Body yaml' }, + }, + ]; +}; + +class RelationController extends React.Component { + state = { + value: this.props.value, + queryHits: Map(), + }; + + handleOnChange = jest.fn(value => { + this.setState({ ...this.state, value }); + }); + + setQueryHits = jest.fn(hits => { + const queryHits = Map().set('relation-field', hits); + this.setState({ ...this.state, queryHits }); + }); + + query = jest.fn((...args) => { + const queryHits = generateHits(25); + if (last(args) === 'YAML') { + return Promise.resolve({ payload: { response: { hits: [last(queryHits)] } } }); + } + return Promise.resolve({ payload: { response: { hits: queryHits } } }); + }); + + render() { + return this.props.children({ + value: this.state.value, + handleOnChange: this.handleOnChange, + query: this.query, + queryHits: this.state.queryHits, + setQueryHits: this.setQueryHits, + }); + } +} + +function setup({ field, value }) { + let renderArgs; + const setActiveSpy = jest.fn(); + const setInactiveSpy = jest.fn(); + + const helpers = render( + + {({ handleOnChange, value, query, queryHits, setQueryHits }) => { + renderArgs = { value, onChangeSpy: handleOnChange, setQueryHitsSpy: setQueryHits }; + return ( + + ); + }} + , + ); + + const input = helpers.container.querySelector('input'); + + return { + ...helpers, + ...renderArgs, + setActiveSpy, + setInactiveSpy, + input, + }; +} + +describe('Relation widget', () => { + it('should list the first 20 option hits on initial load', async () => { + const field = fromJS(fieldConfig); + const { getAllByText, input } = setup({ field }); + fireEvent.keyDown(input, { key: 'ArrowDown' }); + + await wait(() => { + expect(getAllByText(/^Post # (\d{1,2}) post-number-\1$/)).toHaveLength(20); + }); + }); + + it('should update option list based on search term', async () => { + const field = fromJS(fieldConfig); + const { getAllByText, input } = setup({ field }); + fireEvent.change(input, { target: { value: 'YAML' } }); + + await wait(() => { + expect(getAllByText('YAML post post-yaml')).toHaveLength(1); + }); + }); + + it('should call onChange with correct selectedItem value and metadata', async () => { + const field = fromJS(fieldConfig); + const { getByText, input, onChangeSpy } = setup({ field }); + const value = 'Post # 1'; + const label = 'Post # 1 post-number-1'; + const metadata = { + post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } }, + }; + + await wait(() => { + fireEvent.keyDown(input, { key: 'ArrowDown' }); + fireEvent.click(getByText(label)); + expect(onChangeSpy).toHaveBeenCalledTimes(1); + expect(onChangeSpy).toHaveBeenCalledWith(value, metadata); + }); + }); + + it('should update metadata for initial preview', async () => { + const field = fromJS(fieldConfig); + const value = 'Post # 1'; + const { getByText, onChangeSpy, setQueryHitsSpy } = setup({ field, value }); + const label = 'Post # 1 post-number-1'; + const metadata = { + post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } }, + }; + + setQueryHitsSpy(generateHits(1)); + + await wait(() => { + expect(getByText(label)).toBeInTheDocument(); + expect(onChangeSpy).toHaveBeenCalledTimes(1); + expect(onChangeSpy).toHaveBeenCalledWith(value, metadata); + }); + }); + + describe('with multiple', () => { + it('should call onChange with correct selectedItem value and metadata', async () => { + const field = fromJS({ ...fieldConfig, multiple: true }); + const { getByText, input, onChangeSpy } = setup({ field }); + const metadata1 = { + post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } }, + }; + const metadata2 = { + post: { posts: { 'Post # 2': { title: 'Post # 2', slug: 'post-number-2' } } }, + }; + + await wait(() => { + fireEvent.keyDown(input, { key: 'ArrowDown' }); + fireEvent.click(getByText('Post # 1 post-number-1')); + fireEvent.keyDown(input, { key: 'ArrowDown' }); + fireEvent.click(getByText('Post # 2 post-number-2')); + + expect(onChangeSpy).toHaveBeenCalledTimes(2); + expect(onChangeSpy).toHaveBeenCalledWith(fromJS(['Post # 1']), metadata1); + expect(onChangeSpy).toHaveBeenCalledWith(fromJS(['Post # 1', 'Post # 2']), metadata2); + }); + }); + + it('should update metadata for initial preview', async () => { + const field = fromJS({ ...fieldConfig, multiple: true }); + const value = fromJS(['Post # 1', 'Post # 2']); + const { getByText, onChangeSpy, setQueryHitsSpy } = setup({ field, value }); + const metadata1 = { + post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } }, + }; + const metadata2 = { + post: { posts: { 'Post # 2': { title: 'Post # 2', slug: 'post-number-2' } } }, + }; + + setQueryHitsSpy(generateHits(2)); + + await wait(() => { + expect(getByText('Post # 1 post-number-1')).toBeInTheDocument(); + expect(getByText('Post # 2 post-number-2')).toBeInTheDocument(); + + expect(onChangeSpy).toHaveBeenCalledTimes(2); + expect(onChangeSpy).toHaveBeenCalledWith(value, metadata1); + expect(onChangeSpy).toHaveBeenCalledWith(value, metadata2); + }); + }); + }); +}); diff --git a/packages/netlify-cms-widget-relation/src/index.js b/packages/netlify-cms-widget-relation/src/index.js index 2bdf5132..9be2fa60 100644 --- a/packages/netlify-cms-widget-relation/src/index.js +++ b/packages/netlify-cms-widget-relation/src/index.js @@ -1,2 +1,4 @@ -export RelationControl from './RelationControl'; -export RelationPreview from './RelationPreview'; +import controlComponent from './RelationControl'; +import previewComponent from './RelationPreview'; +export const NetlifyCmsWidgetRelation = { controlComponent, previewComponent }; +export { controlComponent, previewComponent }; diff --git a/packages/netlify-cms-widget-select/package.json b/packages/netlify-cms-widget-select/package.json index e04fcf39..bb2f8dc6 100644 --- a/packages/netlify-cms-widget-select/package.json +++ b/packages/netlify-cms-widget-select/package.json @@ -21,18 +21,11 @@ "develop": "npm run watch", "build": "cross-env NODE_ENV=production webpack" }, - "devDependencies": { - "cross-env": "^5.2.0", - "jest-dom": "^3.1.3", - "react-testing-library": "^6.0.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { "immutable": "^3.7.6", - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1", + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4", "react-immutable-proptypes": "^2.1.0" }, "dependencies": { diff --git a/packages/netlify-cms-widget-select/src/__tests__/select.spec.js b/packages/netlify-cms-widget-select/src/__tests__/select.spec.js index 2dc333bf..f51a6d42 100644 --- a/packages/netlify-cms-widget-select/src/__tests__/select.spec.js +++ b/packages/netlify-cms-widget-select/src/__tests__/select.spec.js @@ -3,7 +3,7 @@ import { fromJS } from 'immutable'; import { render, fireEvent } from 'react-testing-library'; import 'react-testing-library/cleanup-after-each'; import 'jest-dom/extend-expect'; -import { SelectControl } from '../'; +import { controlComponent as SelectControl } from '../'; const options = [ { value: 'foo', label: 'Foo' }, diff --git a/packages/netlify-cms-widget-select/src/index.js b/packages/netlify-cms-widget-select/src/index.js index d0c60def..5b2228cd 100644 --- a/packages/netlify-cms-widget-select/src/index.js +++ b/packages/netlify-cms-widget-select/src/index.js @@ -1,2 +1,4 @@ -export SelectControl from './SelectControl'; -export SelectPreview from './SelectPreview'; +import controlComponent from './SelectControl'; +import previewComponent from './SelectPreview'; +export const NetlifyCmsWidgetSelect = { controlComponent, previewComponent }; +export { controlComponent, previewComponent }; diff --git a/packages/netlify-cms-widget-string/package.json b/packages/netlify-cms-widget-string/package.json index a145c944..407fbcc7 100644 --- a/packages/netlify-cms-widget-string/package.json +++ b/packages/netlify-cms-widget-string/package.json @@ -19,14 +19,9 @@ "develop": "npm run watch", "build": "cross-env NODE_ENV=production webpack" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1" + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4" } } diff --git a/packages/netlify-cms-widget-string/src/index.js b/packages/netlify-cms-widget-string/src/index.js index ccd90572..d0c95dd4 100644 --- a/packages/netlify-cms-widget-string/src/index.js +++ b/packages/netlify-cms-widget-string/src/index.js @@ -1,2 +1,4 @@ -export StringControl from './StringControl'; -export StringPreview from './StringPreview'; +import controlComponent from './StringControl'; +import previewComponent from './StringPreview'; +export const NetlifyCmsWidgetString = { controlComponent, previewComponent }; +export { controlComponent, previewComponent }; diff --git a/packages/netlify-cms-widget-text/package.json b/packages/netlify-cms-widget-text/package.json index 2278bde0..275a8af5 100644 --- a/packages/netlify-cms-widget-text/package.json +++ b/packages/netlify-cms-widget-text/package.json @@ -25,14 +25,9 @@ "dependencies": { "react-textarea-autosize": "^7.1.0" }, - "devDependencies": { - "cross-env": "^5.2.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3" - }, "peerDependencies": { - "netlify-cms-ui-default": "^2.0.0", - "prop-types": "^15.5.10", - "react": "^16.4.1" + "netlify-cms-ui-default": "^2.4.1-beta.0", + "prop-types": "^15.7.2", + "react": "^16.8.4" } } diff --git a/packages/netlify-cms-widget-text/src/index.js b/packages/netlify-cms-widget-text/src/index.js index 54082cab..b8941d01 100644 --- a/packages/netlify-cms-widget-text/src/index.js +++ b/packages/netlify-cms-widget-text/src/index.js @@ -1,2 +1,5 @@ -export TextControl from './TextControl'; -export TextPreview from './TextPreview'; +import controlComponent from './TextControl'; +import previewComponent from './TextPreview'; + +export const NetlifyCmsWidgetText = { controlComponent, previewComponent }; +export { controlComponent, previewComponent }; diff --git a/packages/netlify-cms/package.json b/packages/netlify-cms/package.json index d3acfd1b..8973b59e 100644 --- a/packages/netlify-cms/package.json +++ b/packages/netlify-cms/package.json @@ -21,7 +21,12 @@ ], "license": "MIT", "dependencies": { + "@emotion/core": "^10.0.9", + "@emotion/styled": "^10.0.9", "create-react-class": "^15.6.0", + "immutable": "^3.7.6", + "lodash": "^4.17.11", + "moment": "^2.24.0", "netlify-cms-backend-bitbucket": "^2.1.3-beta.0", "netlify-cms-backend-git-gateway": "^2.2.5-beta.0", "netlify-cms-backend-github": "^2.2.3-beta.0", @@ -29,6 +34,7 @@ "netlify-cms-backend-test": "^2.0.7-beta.0", "netlify-cms-core": "^2.8.1-beta.0", "netlify-cms-editor-component-image": "^2.2.1-beta.0", + "netlify-cms-media-library-cloudinary": "^1.1.3-beta.0", "netlify-cms-media-library-uploadcare": "^0.3.5-beta.0", "netlify-cms-widget-boolean": "^2.0.6-beta.0", "netlify-cms-widget-date": "^2.1.1-beta.0", @@ -43,14 +49,10 @@ "netlify-cms-widget-relation": "^2.1.3-beta.0", "netlify-cms-widget-select": "^2.2.1-beta.0", "netlify-cms-widget-string": "^2.0.5-beta.0", - "netlify-cms-widget-text": "^2.0.7-beta.0" - }, - "devDependencies": { - "copy-webpack-plugin": "^5.0.1", - "cross-env": "^5.2.0", - "friendly-errors-webpack-plugin": "^1.7.0", - "webpack": "^4.29.6", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.2.1" + "netlify-cms-widget-text": "^2.0.7-beta.0", + "prop-types": "^15.7.2", + "react-immutable-proptypes": "^2.1.0", + "react": "^16.8.4", + "react-dom": "^16.8.4" } } diff --git a/packages/netlify-cms/src/backends.js b/packages/netlify-cms/src/backends.js index a13085d7..fc4bf96c 100644 --- a/packages/netlify-cms/src/backends.js +++ b/packages/netlify-cms/src/backends.js @@ -1,14 +1,12 @@ -import cms from 'netlify-cms-core/src'; -import { GitHubBackend } from 'netlify-cms-backend-github/src'; -import { GitLabBackend } from 'netlify-cms-backend-gitlab/src'; -import { GitGatewayBackend } from 'netlify-cms-backend-git-gateway/src'; -import { BitbucketBackend } from 'netlify-cms-backend-bitbucket/src'; -import { TestBackend } from 'netlify-cms-backend-test/src'; +import { registerBackend } from 'netlify-cms-core/src'; +import { Control as NetlifyCmsBackendGithub } from 'netlify-cms-backend-github/src'; +import { Control as NetlifyCmsBackendGitlab } from 'netlify-cms-backend-gitlab/src'; +import { Control as NetlifyCmsBackendGitGateway } from 'netlify-cms-backend-git-gateway/src'; +import { Control as NetlifyCmsBackendBitbucket } from 'netlify-cms-backend-bitbucket/src'; +import { Control as NetlifyCmsBackendTest } from 'netlify-cms-backend-test/src'; -const { registerBackend } = cms; - -registerBackend('git-gateway', GitGatewayBackend); -registerBackend('github', GitHubBackend); -registerBackend('gitlab', GitLabBackend); -registerBackend('bitbucket', BitbucketBackend); -registerBackend('test-repo', TestBackend); +registerBackend('git-gateway', NetlifyCmsBackendGitGateway); +registerBackend('github', NetlifyCmsBackendGithub); +registerBackend('gitlab', NetlifyCmsBackendGitlab); +registerBackend('bitbucket', NetlifyCmsBackendBitbucket); +registerBackend('test-repo', NetlifyCmsBackendTest); diff --git a/packages/netlify-cms/src/editor-components.js b/packages/netlify-cms/src/editor-components.js index abb2b9fe..e28bebe8 100644 --- a/packages/netlify-cms/src/editor-components.js +++ b/packages/netlify-cms/src/editor-components.js @@ -1,6 +1,4 @@ -import cms from 'netlify-cms-core/src'; +import { registerEditorComponent } from 'netlify-cms-core/src'; import image from 'netlify-cms-editor-component-image/src'; -const { registerEditorComponent } = cms; - registerEditorComponent(image); diff --git a/packages/netlify-cms/src/index.js b/packages/netlify-cms/src/index.js index 6149c990..c7872237 100644 --- a/packages/netlify-cms/src/index.js +++ b/packages/netlify-cms/src/index.js @@ -1,6 +1,6 @@ import createReactClass from 'create-react-class'; import React from 'react'; -import CMS, { init } from 'netlify-cms-core/src'; +import * as CMS from 'netlify-cms-core/src'; import './backends'; import './widgets'; import './editor-components'; @@ -10,7 +10,7 @@ import './media-libraries'; * Load Netlify CMS automatically if `window.CMS_MANUAL_INIT` is set. */ if (!window.CMS_MANUAL_INIT) { - init(); + CMS.init(); } else { console.log('`window.CMS_MANUAL_INIT` flag set, skipping automatic initialization.'); } @@ -20,9 +20,10 @@ if (!window.CMS_MANUAL_INIT) { */ if (typeof window !== 'undefined') { window.CMS = CMS; - window.initCMS = init; + window.initCMS = CMS.init; window.createClass = window.createClass || createReactClass; window.h = window.h || React.createElement; } -export { CMS as default, init }; +export const NetlifyCms = CMS; +export { CMS as default }; diff --git a/packages/netlify-cms/src/media-libraries.js b/packages/netlify-cms/src/media-libraries.js index 076e80af..204d518c 100644 --- a/packages/netlify-cms/src/media-libraries.js +++ b/packages/netlify-cms/src/media-libraries.js @@ -1,8 +1,6 @@ -import cms from 'netlify-cms-core/src'; +import { registerMediaLibrary } from 'netlify-cms-core/src'; import uploadcare from 'netlify-cms-media-library-uploadcare/src'; import cloudinary from 'netlify-cms-media-library-cloudinary/src'; -const { registerMediaLibrary } = cms; - registerMediaLibrary(uploadcare); registerMediaLibrary(cloudinary); diff --git a/packages/netlify-cms/src/widgets.js b/packages/netlify-cms/src/widgets.js index 45e4ebff..263e18e6 100644 --- a/packages/netlify-cms/src/widgets.js +++ b/packages/netlify-cms/src/widgets.js @@ -1,31 +1,69 @@ -import cms from 'netlify-cms-core/src'; -import { StringControl, StringPreview } from 'netlify-cms-widget-string/src'; -import { NumberControl, NumberPreview } from 'netlify-cms-widget-number/src'; -import { TextControl, TextPreview } from 'netlify-cms-widget-text/src'; -import { ImageControl, ImagePreview } from 'netlify-cms-widget-image/src'; -import { FileControl, FilePreview } from 'netlify-cms-widget-file/src'; -import { SelectControl, SelectPreview } from 'netlify-cms-widget-select/src'; -import { MarkdownControl, MarkdownPreview } from 'netlify-cms-widget-markdown/src'; -import { ListControl, ListPreview } from 'netlify-cms-widget-list/src'; -import { ObjectControl, ObjectPreview } from 'netlify-cms-widget-object/src'; -import { RelationControl, RelationPreview } from 'netlify-cms-widget-relation/src'; -import { BooleanControl } from 'netlify-cms-widget-boolean/src'; -import { MapControl, MapPreview } from 'netlify-cms-widget-map/src'; +import { registerWidget } from 'netlify-cms-core/src'; +import * as NetlifyCmsWidgetString from 'netlify-cms-widget-string/src'; +import * as NetlifyCmsWidgetNumber from 'netlify-cms-widget-number/src'; +import * as NetlifyCmsWidgetText from 'netlify-cms-widget-text/src'; +import * as NetlifyCmsWidgetImage from 'netlify-cms-widget-image/src'; +import * as NetlifyCmsWidgetFile from 'netlify-cms-widget-file/src'; +import * as NetlifyCmsWidgetSelect from 'netlify-cms-widget-select/src'; +import * as NetlifyCmsWidgetMarkdown from 'netlify-cms-widget-markdown/src'; +import * as NetlifyCmsWidgetList from 'netlify-cms-widget-list/src'; +import * as NetlifyCmsWidgetObject from 'netlify-cms-widget-object/src'; +import * as NetlifyCmsWidgetRelation from 'netlify-cms-widget-relation/src'; +import * as NetlifyCmsWidgetBoolean from 'netlify-cms-widget-boolean/src'; +import * as NetlifyCmsWidgetMap from 'netlify-cms-widget-map/src'; import DateWidget from 'netlify-cms-widget-date/src'; import DateTimeWidget from 'netlify-cms-widget-datetime/src'; -const { registerWidget } = cms; - -registerWidget('string', StringControl, StringPreview); -registerWidget('text', TextControl, TextPreview); -registerWidget('number', NumberControl, NumberPreview); -registerWidget('list', ListControl, ListPreview); -registerWidget('markdown', MarkdownControl, MarkdownPreview); -registerWidget('image', ImageControl, ImagePreview); -registerWidget('file', FileControl, FilePreview); -registerWidget('select', SelectControl, SelectPreview); -registerWidget('object', ObjectControl, ObjectPreview); -registerWidget('relation', RelationControl, RelationPreview); -registerWidget('boolean', BooleanControl); -registerWidget('map', MapControl, MapPreview); +registerWidget( + 'string', + NetlifyCmsWidgetString.controlComponent, + NetlifyCmsWidgetString.previewComponent, +); +registerWidget( + 'number', + NetlifyCmsWidgetNumber.controlComponent, + NetlifyCmsWidgetNumber.previewComponent, +); +registerWidget( + 'text', + NetlifyCmsWidgetText.controlComponent, + NetlifyCmsWidgetText.previewComponent, +); +registerWidget( + 'list', + NetlifyCmsWidgetList.controlComponent, + NetlifyCmsWidgetList.previewComponent, +); +registerWidget( + 'markdown', + NetlifyCmsWidgetMarkdown.controlComponent, + NetlifyCmsWidgetMarkdown.previewComponent, +); +registerWidget( + 'image', + NetlifyCmsWidgetImage.controlComponent, + NetlifyCmsWidgetImage.previewComponent, +); +registerWidget( + 'file', + NetlifyCmsWidgetFile.controlComponent, + NetlifyCmsWidgetFile.previewComponent, +); +registerWidget( + 'select', + NetlifyCmsWidgetSelect.controlComponent, + NetlifyCmsWidgetSelect.previewComponent, +); +registerWidget( + 'object', + NetlifyCmsWidgetObject.controlComponent, + NetlifyCmsWidgetObject.previewComponent, +); +registerWidget( + 'relation', + NetlifyCmsWidgetRelation.controlComponent, + NetlifyCmsWidgetRelation.previewComponent, +); +registerWidget('boolean', NetlifyCmsWidgetBoolean.controlComponent); +registerWidget('map', NetlifyCmsWidgetMap.controlComponent, NetlifyCmsWidgetMap.previewComponent); registerWidget([DateWidget(), DateTimeWidget()]); diff --git a/packages/netlify-cms/webpack.config.js b/packages/netlify-cms/webpack.config.js index 4202c9c2..561b26c6 100644 --- a/packages/netlify-cms/webpack.config.js +++ b/packages/netlify-cms/webpack.config.js @@ -3,13 +3,14 @@ const webpack = require('webpack'); const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const pkg = require('./package.json'); -const { plugins } = require('../../scripts/webpack'); -const coreWebpackConfig = require('../netlify-cms-core/webpack.config.js'); +const { getConfig, plugins } = require('../../scripts/webpack'); +const baseWebpackConfig = getConfig({ baseOnly: true }); const isProduction = process.env.NODE_ENV === 'production'; +console.log(`${pkg.version}${isProduction ? '' : '-dev'}`); const baseConfig = { - ...coreWebpackConfig, + ...baseWebpackConfig, context: path.join(__dirname, 'src'), entry: './index.js', plugins: [ @@ -25,7 +26,7 @@ const baseConfig = { messages: ['Netlify CMS is now running at http://localhost:8080'], }, }), - new CopyWebpackPlugin([{ from: '../shims/cms.css', to: 'dist/' }]), + new CopyWebpackPlugin([{ from: '../shims/cms.css', to: './' }]), ], devServer: { contentBase: '../../dev-test', @@ -49,7 +50,7 @@ if (isProduction) { entry: [path.join(__dirname, 'shims/deprecate-old-dist.js'), baseConfig.entry], output: { ...baseConfig.output, - filename: 'dist/cms.js', + filename: 'cms.js', }, }, ]; diff --git a/scripts/externals.js b/scripts/externals.js new file mode 100644 index 00000000..74a95a27 --- /dev/null +++ b/scripts/externals.js @@ -0,0 +1,108 @@ +const fs = require('fs'); +const path = require('path'); + +/** + * Takes a dash [-] separated name and makes it camel-cased + * netlify-cms-something to NetlifyCmsSomething + * @param {} string + */ +const toGlobalName = name => + `${name}` + .replace(new RegExp(/[-_/]+/, 'g'), ' ') + .replace(new RegExp(/[^\w\s]/, 'g'), '') + .replace( + new RegExp(/\s+(.)(\w+)/, 'g'), + ($1, $2, $3) => `${$2.toUpperCase() + $3.toLowerCase()}`, + ) + .replace(new RegExp(/\s/, 'g'), '') + .replace(new RegExp(/\w/), s => s.toUpperCase()); + +const packages = fs.readdirSync(path.resolve(__dirname, '../packages')); + +const packageExports = {}; +packages.map(name => { + packageExports[name] = { + root: `${toGlobalName(name)}`.split('.'), + commonjs2: name, + commonjs: name, + amd: name, + umd: name, + }; +}); + +module.exports = { + toGlobalName, + externals: { + ...packageExports, + lodash: { + root: ['NetlifyCmsDefaultExports', 'Lodash'], + commonjs2: 'lodash', + commonjs: 'lodash', + amd: 'lodash', + umd: 'lodash', + }, + '@emotion/core': { + root: ['NetlifyCmsDefaultExports', 'EmotionCore'], + commonjs2: '@emotion/core', + commonjs: '@emotion/core', + amd: '@emotion/core', + umd: '@emotion/core', + }, + '@emotion/styled': { + root: ['NetlifyCmsDefaultExports', 'EmotionStyled'], + commonjs2: '@emotion/styled', + commonjs: '@emotion/styled', + amd: '@emotion/styled', + umd: '@emotion/styled', + }, + immutable: { + root: ['NetlifyCmsDefaultExports', 'Immutable'], + commonjs2: 'immutable', + commonjs: 'immutable', + amd: 'immutable', + umd: 'immutable', + }, + moment: { + root: ['NetlifyCmsDefaultExports', 'Moment'], + commonjs2: 'moment', + commonjs: 'moment', + amd: 'moment', + umd: 'moment', + }, + 'prop-types': { + root: ['NetlifyCmsDefaultExports', 'PropTypes'], + commonjs2: 'prop-types', + commonjs: 'prop-types', + amd: 'prop-types', + umd: 'prop-types', + }, + 'react-immutable-proptypes': { + root: ['NetlifyCmsDefaultExports', 'ImmutablePropTypes'], + commonjs2: 'react-immutable-proptypes', + commonjs: 'react-immutable-proptypes', + amd: 'react-immutable-proptypes', + umd: 'react-immutable-proptypes', + }, + react: { + root: 'React', + commonjs2: 'react', + commonjs: 'react', + amd: 'react', + umd: 'react', + }, + 'react-dom': { + root: 'ReactDOM', + commonjs2: 'react-dom', + commonjs: 'react-dom', + amd: 'react-dom', + umd: 'react-dom', + }, + uuid: { + root: ['NetlifyCmsDefaultExports', 'UUId'], + commonjs2: 'uuid', + commonjs: 'uuid', + amd: 'uuid', + umd: 'uuid', + }, + }, +}; diff --git a/scripts/webpack.js b/scripts/webpack.js index b57845a0..eaa00e0b 100644 --- a/scripts/webpack.js +++ b/scripts/webpack.js @@ -1,6 +1,7 @@ const path = require('path'); const webpack = require('webpack'); const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin'); +const { toGlobalName, externals } = require('./externals'); const pkg = require(path.join(process.cwd(), 'package.json')); const isProduction = process.env.NODE_ENV === 'production'; @@ -16,6 +17,11 @@ const rules = () => ({ }, }, }), + css: () => ({ + test: /\.css$/, + include: [/(ol|redux-notifications|react-datetime)/], + use: ['to-string-loader', 'css-loader'], + }), svg: () => ({ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, exclude: [/node_modules/], @@ -51,16 +57,54 @@ const stats = () => { }; }; -const getConfig = () => ({ +const umdPath = path.resolve(process.cwd(), 'dist'); +const umdDirPath = path.resolve(process.cwd(), 'dist/umd'); +const cjsPath = path.resolve(process.cwd(), 'dist/cjs'); +const targetOutputs = () => { + console.log(`Building [${pkg.name}, library: ${toGlobalName(pkg.name)}]`); + return { + umd: { + path: umdPath, + filename: `${pkg.name}.js`, + library: toGlobalName(pkg.name), + libraryTarget: 'umd', + libraryExport: toGlobalName(pkg.name), + umdNamedDefine: true, + globalObject: 'window', + }, + umddir: { + path: umdDirPath, + filename: `index.js`, + library: toGlobalName(pkg.name), + libraryTarget: 'umd', + libraryExport: toGlobalName(pkg.name), + umdNamedDefine: true, + globalObject: 'window', + }, + cjs: { + path: cjsPath, + filename: 'index.js', + library: toGlobalName(pkg.name), + libraryTarget: 'window', + }, + }; +}; + +const umdExternals = Object.keys(pkg.peerDependencies || {}).reduce((previous, key) => { + if (!externals[key]) throw `Missing external [${key}]`; + previous[key] = externals[key] || null; + return previous; +}, {}); + +/** + * Use [getConfig({ target:'umd' }), getConfig({ target:'cjs' })] for + * getting multiple configs and add the new output in targetOutputs if needed. + * Default: umd + */ +const baseConfig = ({ target = isProduction ? 'umd' : 'umddir' } = {}) => ({ mode: isProduction ? 'production' : 'development', entry: './src/index.js', - output: { - path: process.cwd(), - filename: pkg.main, - library: pkg.name, - libraryTarget: 'umd', - umdNamedDefine: true, - }, + output: targetOutputs()[target], module: { rules: Object.values(rules()).map(rule => rule()), }, @@ -71,16 +115,25 @@ const getConfig = () => ({ /** * Exclude peer dependencies from package bundles. */ - externals: (context, request, cb) => { - const localExternals = pkg.localExternals || []; - const peerDeps = Object.keys(pkg.peerDependencies || {}); - const externals = isProduction ? peerDeps : [...localExternals, ...peerDeps]; - const isPeerDep = dep => new RegExp(`^${dep}($|/)`).test(request); - return externals.some(isPeerDep) ? cb(null, request) : cb(); - }, + externals: + target.substr(0, 3) === 'umd' + ? umdExternals + : (context, request, cb) => { + const externals = Object.keys(pkg.peerDependencies || {}); + const isPeerDep = dep => new RegExp(`^${dep}($|/)`).test(request); + return externals.some(isPeerDep) ? cb(null, request) : cb(); + }, stats: stats(), }); +const getConfig = ({ baseOnly = false } = {}) => { + if (baseOnly) { + // netlify-cms build + return baseConfig({ target: 'umd' }); + } + return [baseConfig({ target: 'umd' })]; +}; + module.exports = { getConfig, rules: rules(), diff --git a/website/package.json b/website/package.json index b81cb7fc..a031ca92 100755 --- a/website/package.json +++ b/website/package.json @@ -28,7 +28,7 @@ "gatsby-transformer-remark": "next", "gatsby-transformer-yaml": "next", "github-buttons": "git+https://github.com/ntkme/github-buttons.git", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "netlify-cms": "^2.0.11", "postcss-at2x": "^2.0.0", "postcss-cssnext": "^2.7.0", diff --git a/yarn.lock b/yarn.lock index 695bf5a4..e8675ced 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3957,7 +3957,7 @@ create-react-class@^15.5.1, create-react-class@^15.5.2, create-react-class@^15.6 loose-envify "^1.3.1" object-assign "^4.1.1" -cross-env@^5.1.4, cross-env@^5.2.0: +cross-env@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2" integrity sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg==