This commit is contained in:
Pierre Noël 2021-06-02 14:59:33 +02:00
parent f97c775566
commit bdd75d9154
21 changed files with 169 additions and 137 deletions

View File

@ -9,11 +9,11 @@ dotenv.config({ path: process.env.ENV_PATH });
process.env.NODE_ENV = process.env.NODE_ENV || 'development'; process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const createConfigProvider = require('../../utils/config-provider');
const getPrefixedDeps = require('../../utils/get-prefixed-dependencies'); const getPrefixedDeps = require('../../utils/get-prefixed-dependencies');
const loadPolicies = require('../load-policies'); const loadPolicies = require('../load-policies');
const loadFunctions = require('../load-functions'); const loadFunctions = require('../load-functions');
const loadConfigDir = require('./config-loader'); const loadConfigDir = require('./config-loader');
const createConfigProvider = require('./config-provider');
const { version: strapiVersion } = require(path.join(__dirname, '../../../package.json')); const { version: strapiVersion } = require(path.join(__dirname, '../../../package.json'));

View File

@ -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,
};

View File

@ -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,
}

View File

@ -1,21 +1,21 @@
'use strict'; // 'use strict';
//
const loadApis = require('./load-apis'); // const loadApis = require('./load-apis');
const loadAdmin = require('./load-admin'); // const loadAdmin = require('./load-admin');
// const loadPlugins = require('./load-plugins'); // // const loadPlugins = require('./load-plugins');
const loadMiddlewares = require('./load-middlewares'); // const loadMiddlewares = require('./load-middlewares');
const loadExtensions = require('./load-extensions'); // const loadExtensions = require('./load-extensions');
const loadHooks = require('./load-hooks'); // const loadHooks = require('./load-hooks');
const bootstrap = require('./bootstrap'); // const bootstrap = require('./bootstrap');
const loadComponents = require('./load-components'); // const loadComponents = require('./load-components');
//
module.exports = { // module.exports = {
loadApis, // loadApis,
loadAdmin, // loadAdmin,
// loadPlugins, // // loadPlugins,
loadMiddlewares, // loadMiddlewares,
loadHooks, // loadHooks,
loadExtensions, // loadExtensions,
loadComponents, // loadComponents,
bootstrap, // bootstrap,
}; // };

View File

@ -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);
};

View File

@ -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;
}
}
};

View File

@ -1,39 +1,29 @@
'use strict'; 'use strict';
const { join } = require('path'); 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 { 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 createPlugin = async (strapi, name, path) => {
const loadPluginServer = require(join(path, 'strapi-server.js')); const loadPluginServer = require(join(path, 'strapi-server.js'));
const userPluginConfig = strapi.config.get(`plugins.${name}`);
const pluginServer = await loadPluginServer(strapi); const pluginServer = await loadPluginServer(strapi);
const cleanPluginServer = await validateStrapiServer(pluginServer);
await validateStrapiServer(pluginServer); const configProvider = await createConfigProvider(name, cleanPluginServer.config);
const serviceProvider = await createServiceProvider(cleanPluginServer.services);
const defaultConfig = isFunction(pluginServer.config) const contentTypeProvider = await createContentTypeProvider(name, cleanPluginServer.contentTypes);
? 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;
}, {});
return { return {
bootstrap: pluginServer.bootstrap, bootstrap: cleanPluginServer.bootstrap,
destroy: pluginServer.destroy, destroy: cleanPluginServer.destroy,
config: defaultsDeep(defaultConfig, userPluginConfig), config: configProvider,
// routes: pluginServer.routes, service: serviceProvider.get,
// controller: (name) => pluginServer.controllers[name], contentType: contentTypeProvider.get,
service: name => pluginServer.services[name], getAllContentTypes: contentTypeProvider.getAll,
contentType: name => contentTypesMap[name], // routes: cleanPluginServer.routes,
getAllContentTypes: () => Object.values(contentTypes), // controller: (name) => cleanPluginServer.controllers[name],
}; };
}; };

View File

@ -0,0 +1,8 @@
'use strict'
module.exports = (services) => {
return {
get(serviceName) {
return services[serviceName];
}
}
};

View File

@ -5,21 +5,21 @@ const { yup } = require('@strapi/utils');
const strapiServerSchema = yup const strapiServerSchema = yup
.object() .object()
.shape({ .shape({
bootstrap: yup.mixed().isFunction(), bootstrap: yup.mixed().isFunction().default(() => {}),
destroy: yup.mixed().isFunction(), destroy: yup.mixed().isFunction().default(() => {}),
config: yup.object(), config: yup.object().default({}),
routes: yup.array(), // may be removed later routes: yup.array().default([]), // may be removed later
controllers: yup.object(), // may be removed later controllers: yup.object(), // may be removed later
services: yup.object(), services: yup.object().default({}),
policies: yup.object(), policies: yup.object().default({}),
middlewares: yup.object(), // may be removed later middlewares: yup.object().default({}), // may be removed later
hooks: yup.object(), // may be removed later hooks: yup.object().default({}), // may be removed later
contentTypes: yup.array().of(yup.object()), contentTypes: yup.array().of(yup.object()).default([]),
}) })
.noUnknown(); .noUnknown();
const validateStrapiServer = data => { const validateStrapiServer = data => {
return strapiServerSchema.validate(data, { strict: true, abortEarly: false }); return strapiServerSchema.validate(data, { strict: false, abortEarly: false });
}; };
module.exports = { module.exports = {

View File

@ -1,15 +1,9 @@
'use strict'; 'use strict';
const assert = require('assert');
const _ = require('lodash'); const _ = require('lodash');
module.exports = (initialConfig = {}) => { module.exports = (initialConfig = {}) => {
assert( const _config = _.cloneDeep(initialConfig);
typeof initialConfig === 'object' && initialConfig !== null,
'Initial config must be an object'
);
const _config = initialConfig;
return Object.assign(_config, { return Object.assign(_config, {
get(path, defaultValue) { get(path, defaultValue) {

View File

@ -2,7 +2,6 @@
const _ = require('lodash'); const _ = require('lodash');
const pluralize = require('pluralize'); const pluralize = require('pluralize');
const { nameToSlug } = require('./string-formatting');
const SINGLE_TYPE = 'singleType'; const SINGLE_TYPE = 'singleType';
const COLLECTION_TYPE = 'collectionType'; const COLLECTION_TYPE = 'collectionType';
@ -124,76 +123,6 @@ const isMediaAttribute = attr => {
return (attr.collection || attr.model) === 'file' && attr.plugin === 'upload'; 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 => const isRelationalAttribute = attribute =>
_.has(attribute, 'model') || _.has(attribute, 'collection'); _.has(attribute, 'model') || _.has(attribute, 'collection');
@ -237,7 +166,5 @@ module.exports = {
isSingleType, isSingleType,
isCollectionType, isCollectionType,
isKind, isKind,
createContentType,
getGlobalId,
getContentTypeRoutePrefix, getContentTypeRoutePrefix,
}; };