diff --git a/packages/core/strapi/lib/core/app-configuration/index.js b/packages/core/strapi/lib/core/app-configuration/index.js index d7d642c29c..63a8f683f9 100644 --- a/packages/core/strapi/lib/core/app-configuration/index.js +++ b/packages/core/strapi/lib/core/app-configuration/index.js @@ -9,11 +9,11 @@ dotenv.config({ path: process.env.ENV_PATH }); process.env.NODE_ENV = process.env.NODE_ENV || 'development'; +const createConfigProvider = require('../../utils/config-provider'); const getPrefixedDeps = require('../../utils/get-prefixed-dependencies'); const loadPolicies = require('../load-policies'); const loadFunctions = require('../load-functions'); const loadConfigDir = require('./config-loader'); -const createConfigProvider = require('./config-provider'); const { version: strapiVersion } = require(path.join(__dirname, '../../../package.json')); diff --git a/packages/core/strapi/lib/core/domain/config.js b/packages/core/strapi/lib/core/domain/config.js new file mode 100644 index 0000000000..72149e46bb --- /dev/null +++ b/packages/core/strapi/lib/core/domain/config.js @@ -0,0 +1,26 @@ +'use strict' + +const { defaultsDeep, getOr, set, has } = require('lodash/fp'); + +const createConfig = (config = {}, defaultConfig = {}) => { + const currentConfig = defaultsDeep(defaultConfig, config); + + return Object.assign(currentConfig, { + get(path, defaultValue) { + return getOr(defaultValue, path, currentConfig); + }, + + set(path, val) { + set(path, val, currentConfig); + return this; + }, + + has(path) { + return has(path, currentConfig); + }, + }); +}; + +module.exports = { + createConfig, +}; diff --git a/packages/core/strapi/lib/core/domain/content-type.js b/packages/core/strapi/lib/core/domain/content-type.js new file mode 100644 index 0000000000..a84be16b92 --- /dev/null +++ b/packages/core/strapi/lib/core/domain/content-type.js @@ -0,0 +1,49 @@ +'use strict' + +const { cloneDeep, camelCase } = require('lodash/fp'); + +const createContentType = (model, { apiName, pluginName } = {}) => { + // todo : validate schema with yup + const createdContentType = cloneDeep(model); + const singularModelName = camelCase(model.singularName); + const pluralModelName = camelCase(model.pluralName); + + if (apiName) { + Object.assign(createdContentType, { + uid: `application::${apiName}.${singularModelName}`, + apiName, + collectionName: model.collectionName || singularModelName, + }); + } else if (pluginName) { + Object.assign(createdContentType, { + uid: `plugins::${pluginName}.${singularModelName}`, + plugin: pluginName, + collectionName: + createdContentType.collectionName || `${pluginName}_${singularModelName}`.toLowerCase(), + }); + } else { + Object.assign(createdContentType, { + uid: `strapi::${singularModelName}`, + plugin: 'admin', + }); + } + + Object.assign(createdContentType, { + kind: createdContentType.kind || 'collectionType', + modelType: 'contentType', + modelName: singularModelName, + singularName: singularModelName, + pluralName: pluralModelName, + }); + Object.defineProperty(createdContentType, 'privateAttributes', { + get() { + return strapi.getModel(createdContentType.uid).privateAttributes; + }, + }); + + return createdContentType; +}; + +module.exports = { + createContentType, +} diff --git a/packages/core/strapi/lib/core/index.js b/packages/core/strapi/lib/core/index.js index 2f89b565ea..da6e6e22f0 100644 --- a/packages/core/strapi/lib/core/index.js +++ b/packages/core/strapi/lib/core/index.js @@ -1,21 +1,21 @@ -'use strict'; - -const loadApis = require('./load-apis'); -const loadAdmin = require('./load-admin'); -// const loadPlugins = require('./load-plugins'); -const loadMiddlewares = require('./load-middlewares'); -const loadExtensions = require('./load-extensions'); -const loadHooks = require('./load-hooks'); -const bootstrap = require('./bootstrap'); -const loadComponents = require('./load-components'); - -module.exports = { - loadApis, - loadAdmin, - // loadPlugins, - loadMiddlewares, - loadHooks, - loadExtensions, - loadComponents, - bootstrap, -}; +// 'use strict'; +// +// const loadApis = require('./load-apis'); +// const loadAdmin = require('./load-admin'); +// // const loadPlugins = require('./load-plugins'); +// const loadMiddlewares = require('./load-middlewares'); +// const loadExtensions = require('./load-extensions'); +// const loadHooks = require('./load-hooks'); +// const bootstrap = require('./bootstrap'); +// const loadComponents = require('./load-components'); +// +// module.exports = { +// loadApis, +// loadAdmin, +// // loadPlugins, +// loadMiddlewares, +// loadHooks, +// loadExtensions, +// loadComponents, +// bootstrap, +// }; diff --git a/packages/core/strapi/lib/core/bootstrap.js b/packages/core/strapi/lib/core/old-to-delete/bootstrap.js similarity index 100% rename from packages/core/strapi/lib/core/bootstrap.js rename to packages/core/strapi/lib/core/old-to-delete/bootstrap.js diff --git a/packages/core/strapi/lib/core/load-apis.js b/packages/core/strapi/lib/core/old-to-delete/load-apis.js similarity index 100% rename from packages/core/strapi/lib/core/load-apis.js rename to packages/core/strapi/lib/core/old-to-delete/load-apis.js diff --git a/packages/core/strapi/lib/core/load-components.js b/packages/core/strapi/lib/core/old-to-delete/load-components.js similarity index 100% rename from packages/core/strapi/lib/core/load-components.js rename to packages/core/strapi/lib/core/old-to-delete/load-components.js diff --git a/packages/core/strapi/lib/core/load-extensions.js b/packages/core/strapi/lib/core/old-to-delete/load-extensions.js similarity index 100% rename from packages/core/strapi/lib/core/load-extensions.js rename to packages/core/strapi/lib/core/old-to-delete/load-extensions.js diff --git a/packages/core/strapi/lib/core/load-functions.js b/packages/core/strapi/lib/core/old-to-delete/load-functions.js similarity index 100% rename from packages/core/strapi/lib/core/load-functions.js rename to packages/core/strapi/lib/core/old-to-delete/load-functions.js diff --git a/packages/core/strapi/lib/core/load-hooks.js b/packages/core/strapi/lib/core/old-to-delete/load-hooks.js similarity index 100% rename from packages/core/strapi/lib/core/load-hooks.js rename to packages/core/strapi/lib/core/old-to-delete/load-hooks.js diff --git a/packages/core/strapi/lib/core/load-middlewares.js b/packages/core/strapi/lib/core/old-to-delete/load-middlewares.js similarity index 100% rename from packages/core/strapi/lib/core/load-middlewares.js rename to packages/core/strapi/lib/core/old-to-delete/load-middlewares.js diff --git a/packages/core/strapi/lib/core/load-modules.js b/packages/core/strapi/lib/core/old-to-delete/load-modules.js similarity index 100% rename from packages/core/strapi/lib/core/load-modules.js rename to packages/core/strapi/lib/core/old-to-delete/load-modules.js diff --git a/packages/core/strapi/lib/core/load-policies.js b/packages/core/strapi/lib/core/old-to-delete/load-policies.js similarity index 100% rename from packages/core/strapi/lib/core/load-policies.js rename to packages/core/strapi/lib/core/old-to-delete/load-policies.js diff --git a/packages/core/strapi/lib/core/walk.js b/packages/core/strapi/lib/core/old-to-delete/walk.js similarity index 100% rename from packages/core/strapi/lib/core/walk.js rename to packages/core/strapi/lib/core/old-to-delete/walk.js diff --git a/packages/core/strapi/lib/core/plugins/config-provider.js b/packages/core/strapi/lib/core/plugins/config-provider.js new file mode 100644 index 0000000000..d7824882b6 --- /dev/null +++ b/packages/core/strapi/lib/core/plugins/config-provider.js @@ -0,0 +1,15 @@ +'use strict' + +const { env } = require('@strapi/utils'); +const { isFunction } = require('lodash/fp'); +const createConfig = require('../domain/config'); + +module.exports = async (pluginName, pluginDefaultConfig) => { + const defaultConfig = isFunction(pluginDefaultConfig) + ? await pluginDefaultConfig({ env }) + : pluginDefaultConfig; + + const userPluginConfig = strapi.config.get(`plugins.${pluginName}`); + + return createConfig(userPluginConfig, defaultConfig); +}; diff --git a/packages/core/strapi/lib/core/plugins/content-type-provider.js b/packages/core/strapi/lib/core/plugins/content-type-provider.js new file mode 100644 index 0000000000..fa6d86ca3c --- /dev/null +++ b/packages/core/strapi/lib/core/plugins/content-type-provider.js @@ -0,0 +1,23 @@ +'use strict' + +const { createContentType } = require('@strapi/utils').contentTypes; + +module.exports = (pluginName, contentTypeDefinitions) => { + const contentTypes = contentTypeDefinitions.map(ct => + createContentType(ct, { pluginName }) + ); + + const contentTypesMap = contentTypes.reduce((map, ct) => { + map[ct.info.singularName] = ct; + map[ct.info.pluralName] = ct; + }, {}); + + return { + get(ctName) { + return contentTypesMap[ctName]; + }, + getAll() { + return contentTypes; + } + } +}; diff --git a/packages/core/strapi/lib/core/plugins/create-plugin.js b/packages/core/strapi/lib/core/plugins/create-plugin.js index ee004f1051..82f0017a13 100644 --- a/packages/core/strapi/lib/core/plugins/create-plugin.js +++ b/packages/core/strapi/lib/core/plugins/create-plugin.js @@ -1,39 +1,29 @@ 'use strict'; const { join } = require('path'); -const { isFunction, defaultsDeep } = require('lodash/fp'); -const { env } = require('@strapi/utils'); -const { createContentType } = require('@strapi/utils').contentTypes; const { validateStrapiServer } = require('./validation'); +const createConfigProvider = require('./config-provider'); +const createServiceProvider = require('./service-provider'); +const createContentTypeProvider = require('./content-type-provider'); const createPlugin = async (strapi, name, path) => { const loadPluginServer = require(join(path, 'strapi-server.js')); - const userPluginConfig = strapi.config.get(`plugins.${name}`); const pluginServer = await loadPluginServer(strapi); + const cleanPluginServer = await validateStrapiServer(pluginServer); - await validateStrapiServer(pluginServer); - - const defaultConfig = isFunction(pluginServer.config) - ? await pluginServer.config({ env }) - : pluginServer.config; - - const contentTypes = pluginServer.contentTypes.map(ct => - createContentType(ct, { pluginName: name }) - ); - const contentTypesMap = contentTypes.reduce((map, ct) => { - map[ct.info.singularName] = ct; - map[ct.info.pluralName] = ct; - }, {}); + const configProvider = await createConfigProvider(name, cleanPluginServer.config); + const serviceProvider = await createServiceProvider(cleanPluginServer.services); + const contentTypeProvider = await createContentTypeProvider(name, cleanPluginServer.contentTypes); return { - bootstrap: pluginServer.bootstrap, - destroy: pluginServer.destroy, - config: defaultsDeep(defaultConfig, userPluginConfig), - // routes: pluginServer.routes, - // controller: (name) => pluginServer.controllers[name], - service: name => pluginServer.services[name], - contentType: name => contentTypesMap[name], - getAllContentTypes: () => Object.values(contentTypes), + bootstrap: cleanPluginServer.bootstrap, + destroy: cleanPluginServer.destroy, + config: configProvider, + service: serviceProvider.get, + contentType: contentTypeProvider.get, + getAllContentTypes: contentTypeProvider.getAll, + // routes: cleanPluginServer.routes, + // controller: (name) => cleanPluginServer.controllers[name], }; }; diff --git a/packages/core/strapi/lib/core/plugins/service-provider.js b/packages/core/strapi/lib/core/plugins/service-provider.js new file mode 100644 index 0000000000..32e29bbc93 --- /dev/null +++ b/packages/core/strapi/lib/core/plugins/service-provider.js @@ -0,0 +1,8 @@ +'use strict' +module.exports = (services) => { + return { + get(serviceName) { + return services[serviceName]; + } + } +}; diff --git a/packages/core/strapi/lib/core/plugins/validation.js b/packages/core/strapi/lib/core/plugins/validation.js index ea326da513..a851d33a4b 100644 --- a/packages/core/strapi/lib/core/plugins/validation.js +++ b/packages/core/strapi/lib/core/plugins/validation.js @@ -5,21 +5,21 @@ const { yup } = require('@strapi/utils'); const strapiServerSchema = yup .object() .shape({ - bootstrap: yup.mixed().isFunction(), - destroy: yup.mixed().isFunction(), - config: yup.object(), - routes: yup.array(), // may be removed later + bootstrap: yup.mixed().isFunction().default(() => {}), + destroy: yup.mixed().isFunction().default(() => {}), + config: yup.object().default({}), + routes: yup.array().default([]), // may be removed later controllers: yup.object(), // may be removed later - services: yup.object(), - policies: yup.object(), - middlewares: yup.object(), // may be removed later - hooks: yup.object(), // may be removed later - contentTypes: yup.array().of(yup.object()), + services: yup.object().default({}), + policies: yup.object().default({}), + middlewares: yup.object().default({}), // may be removed later + hooks: yup.object().default({}), // may be removed later + contentTypes: yup.array().of(yup.object()).default([]), }) .noUnknown(); const validateStrapiServer = data => { - return strapiServerSchema.validate(data, { strict: true, abortEarly: false }); + return strapiServerSchema.validate(data, { strict: false, abortEarly: false }); }; module.exports = { diff --git a/packages/core/strapi/lib/core/app-configuration/config-provider.js b/packages/core/strapi/lib/utils/config-provider.js similarity index 65% rename from packages/core/strapi/lib/core/app-configuration/config-provider.js rename to packages/core/strapi/lib/utils/config-provider.js index 1c00093fe6..4648ec030b 100644 --- a/packages/core/strapi/lib/core/app-configuration/config-provider.js +++ b/packages/core/strapi/lib/utils/config-provider.js @@ -1,15 +1,9 @@ 'use strict'; -const assert = require('assert'); const _ = require('lodash'); module.exports = (initialConfig = {}) => { - assert( - typeof initialConfig === 'object' && initialConfig !== null, - 'Initial config must be an object' - ); - - const _config = initialConfig; + const _config = _.cloneDeep(initialConfig); return Object.assign(_config, { get(path, defaultValue) { diff --git a/packages/core/utils/lib/content-types.js b/packages/core/utils/lib/content-types.js index 11a49eb63a..7aaeff698e 100644 --- a/packages/core/utils/lib/content-types.js +++ b/packages/core/utils/lib/content-types.js @@ -2,7 +2,6 @@ const _ = require('lodash'); const pluralize = require('pluralize'); -const { nameToSlug } = require('./string-formatting'); const SINGLE_TYPE = 'singleType'; const COLLECTION_TYPE = 'collectionType'; @@ -124,76 +123,6 @@ const isMediaAttribute = attr => { return (attr.collection || attr.model) === 'file' && attr.plugin === 'upload'; }; -const getKind = obj => obj.kind || 'collectionType'; - -const pickSchema = model => { - const schema = _.cloneDeep( - _.pick(model, [ - 'connection', - 'collectionName', - 'info', - 'options', - 'pluginOptions', - 'attributes', - ]) - ); - - schema.kind = getKind(model); - return schema; -}; - -const createContentType = (model, { apiName, pluginName } = {}) => { - // todo : validate schema with yup - const createdContentType = _.cloneDeep(model); - const singularModelName = nameToSlug(model.singularName); - const pluralModelName = nameToSlug(model.pluralName); - - if (apiName) { - Object.assign(createdContentType, { - uid: `application::${apiName}.${singularModelName}`, - apiName, - collectionName: model.collectionName || singularModelName, - globalId: getGlobalId(createdContentType, singularModelName), - }); - } else if (pluginName) { - Object.assign(createdContentType, { - uid: `plugins::${pluginName}.${singularModelName}`, - plugin: pluginName, - collectionName: - createdContentType.collectionName || `${pluginName}_${singularModelName}`.toLowerCase(), - globalId: getGlobalId(createdContentType, singularModelName, pluginName), - }); - } else { - Object.assign(createdContentType, { - uid: `strapi::${singularModelName}`, - plugin: 'admin', - globalId: getGlobalId(createdContentType, singularModelName, 'admin'), - }); - } - - Object.assign(createdContentType, { - __schema__: pickSchema(createdContentType), - kind: getKind(createdContentType), - modelType: 'contentType', - modelName: singularModelName, - singularName: singularModelName, - pluralName: pluralModelName, - }); - Object.defineProperty(createdContentType, 'privateAttributes', { - get() { - return strapi.getModel(createdContentType.uid).privateAttributes; - }, - }); - - return createdContentType; -}; - -const getGlobalId = (model, modelName, prefix) => { - let globalId = prefix ? `${prefix}-${modelName}` : modelName; - - return model.globalId || _.upperFirst(_.camelCase(globalId)); -}; - const isRelationalAttribute = attribute => _.has(attribute, 'model') || _.has(attribute, 'collection'); @@ -237,7 +166,5 @@ module.exports = { isSingleType, isCollectionType, isKind, - createContentType, - getGlobalId, getContentTypeRoutePrefix, };