improve joinTable customization + test collectionName duplicates

Signed-off-by: Pierre Noël <pierre.noel@strapi.io>
This commit is contained in:
Pierre Noël 2020-03-27 15:51:23 +01:00
parent a63c692fca
commit f2663eb1f7
5 changed files with 184 additions and 270 deletions

View File

@ -364,7 +364,8 @@ A `product` can be related to many `categories`, so a `category` can have many `
"categories": { "categories": {
"collection": "category", "collection": "category",
"via": "products", "via": "products",
"dominant": true "dominant": true,
"collectionName": "products_categories__categories_products" // optional
} }
} }
} }
@ -373,6 +374,9 @@ A `product` can be related to many `categories`, so a `category` can have many `
**NOTE**: **NOTE**:
(NoSQL databases only) The `dominant` key defines which table/collection should store the array that defines the relationship. Because there are no join tables in NoSQL, this key is required for NoSQL databases (e.g. MongoDB). (NoSQL databases only) The `dominant` key defines which table/collection should store the array that defines the relationship. Because there are no join tables in NoSQL, this key is required for NoSQL databases (e.g. MongoDB).
**NOTE**:
(NoSQL databases only) The `collectionName` key defines the name of the join table. It has to be specified once, in the `dominant` attribute of the relation. If it is not specified, Strapi will use a generated default one. It is useful to define the name of the join table when the name generated by Strapi is too long for the database you use.
**Path —** `./api/category/models/Category.settings.json`. **Path —** `./api/category/models/Category.settings.json`.
```json ```json
@ -666,9 +670,7 @@ module.exports = {
*/ */
beforeCreate: async model => { beforeCreate: async model => {
// Hash password. // Hash password.
const passwordHashed = await strapi.api.user.services.user.hashPassword( const passwordHashed = await strapi.api.user.services.user.hashPassword(model.password);
model.password
);
// Set the password. // Set the password.
model.password = passwordHashed; model.password = passwordHashed;

View File

@ -228,7 +228,8 @@ module.exports = ({ models, target }, ctx) => {
details.isVirtual = true; details.isVirtual = true;
if (nature === 'manyWay') { if (nature === 'manyWay') {
const joinTableName = `${definition.collectionName}__${_.snakeCase(name)}`; const joinTableName =
details.collectionName || `${definition.collectionName}__${_.snakeCase(name)}`;
const foreignKey = `${singular(definition.collectionName)}_${definition.primaryKey}`; const foreignKey = `${singular(definition.collectionName)}_${definition.primaryKey}`;
@ -255,9 +256,10 @@ module.exports = ({ models, target }, ctx) => {
return collection; return collection;
}; };
} else { } else {
const joinTableName = const joinTableName = utilsModels.getCollectionName(
_.get(details, 'collectionName') || targetModel.attributes[details.via],
utilsModels.getCollectionName(targetModel.attributes[details.via], details); details
);
const relationship = targetModel.attributes[details.via]; const relationship = targetModel.attributes[details.via];
@ -641,7 +643,6 @@ module.exports = ({ models, target }, ctx) => {
'columnName' 'columnName'
) )
); );
GLOBALS[definition.globalId] = ORM.Model.extend(loadedModel); GLOBALS[definition.globalId] = ORM.Model.extend(loadedModel);
// Expose ORM functions through the `strapi.models[xxx]` // Expose ORM functions through the `strapi.models[xxx]`
@ -665,6 +666,13 @@ module.exports = ({ models, target }, ctx) => {
if (err instanceof TypeError || err instanceof ReferenceError) { if (err instanceof TypeError || err instanceof ReferenceError) {
strapi.stopWithError(err, `Impossible to register the '${model}' model.`); strapi.stopWithError(err, `Impossible to register the '${model}' model.`);
} }
if (['ER_TOO_LONG_IDENT'].includes(err.code)) {
strapi.stopWithError(
err,
'A table name is too long. If it is the name of a join table automatically generated by Strapi, you can customise it by adding `collectionName: "customName"` in the corresponding attribute model (on the dominant side if it\'s a many-to-many relation).'
);
}
strapi.stopWithError(err); strapi.stopWithError(err);
} }
}); });

View File

@ -46,9 +46,7 @@ module.exports = {
}; };
if (_.isUndefined(models)) { if (_.isUndefined(models)) {
models = association.plugin models = association.plugin ? strapi.plugins[association.plugin].models : strapi.models;
? strapi.plugins[association.plugin].models
: strapi.models;
} }
if ( if (
@ -61,17 +59,13 @@ module.exports = {
types.current = 'morphTo'; types.current = 'morphTo';
} }
const flattenedPluginsModels = Object.keys(strapi.plugins).reduce( const flattenedPluginsModels = Object.keys(strapi.plugins).reduce((acc, current) => {
(acc, current) => { Object.keys(strapi.plugins[current].models).forEach(model => {
Object.keys(strapi.plugins[current].models).forEach(model => { acc[`${current}_${model}`] = strapi.plugins[current].models[model];
acc[`${current}_${model}`] = });
strapi.plugins[current].models[model];
});
return acc; return acc;
}, }, {});
{}
);
const allModels = _.merge({}, strapi.models, flattenedPluginsModels); const allModels = _.merge({}, strapi.models, flattenedPluginsModels);
@ -97,22 +91,14 @@ module.exports = {
} }
}); });
}); });
} else if ( } else if (_.has(association, 'via') && _.has(association, 'collection')) {
_.has(association, 'via') && const relatedAttribute = models[association.collection].attributes[association.via];
_.has(association, 'collection')
) {
const relatedAttribute =
models[association.collection].attributes[association.via];
if (!relatedAttribute) { if (!relatedAttribute) {
throw new Error( throw new Error(
`The attribute \`${ `The attribute \`${association.via}\` is missing in the model ${_.upperFirst(
association.via
}\` is missing in the model ${_.upperFirst(
association.collection association.collection
)} ${ )} ${association.plugin ? '(plugin - ' + association.plugin + ')' : ''}`
association.plugin ? '(plugin - ' + association.plugin + ')' : ''
}`
); );
} }
@ -130,15 +116,9 @@ module.exports = {
!_.has(relatedAttribute, 'via') !_.has(relatedAttribute, 'via')
) { ) {
types.other = 'collectionD'; types.other = 'collectionD';
} else if ( } else if (_.has(relatedAttribute, 'model') && relatedAttribute.model !== '*') {
_.has(relatedAttribute, 'model') &&
relatedAttribute.model !== '*'
) {
types.other = 'model'; types.other = 'model';
} else if ( } else if (_.has(relatedAttribute, 'collection') || _.has(relatedAttribute, 'model')) {
_.has(relatedAttribute, 'collection') ||
_.has(relatedAttribute, 'model')
) {
types.other = 'morphTo'; types.other = 'morphTo';
} }
} else if (_.has(association, 'via') && _.has(association, 'model')) { } else if (_.has(association, 'via') && _.has(association, 'model')) {
@ -158,10 +138,7 @@ module.exports = {
types.other = 'collection'; types.other = 'collection';
} else if (_.has(attribute, 'model') && attribute.model !== '*') { } else if (_.has(attribute, 'model') && attribute.model !== '*') {
types.other = 'model'; types.other = 'model';
} else if ( } else if (_.has(attribute, 'collection') || _.has(attribute, 'model')) {
_.has(attribute, 'collection') ||
_.has(attribute, 'model')
) {
types.other = 'morphTo'; types.other = 'morphTo';
} }
} else if (_.has(association, 'model')) { } else if (_.has(association, 'model')) {
@ -171,18 +148,12 @@ module.exports = {
_.forIn(models, model => { _.forIn(models, model => {
_.forIn(model.attributes, attribute => { _.forIn(model.attributes, attribute => {
if (_.has(attribute, 'via') && attribute.via === key) { if (_.has(attribute, 'via') && attribute.via === key) {
if ( if (_.has(attribute, 'collection') && attribute.collection === currentModelName) {
_.has(attribute, 'collection') &&
attribute.collection === currentModelName
) {
types.other = 'collection'; types.other = 'collection';
// Break loop // Break loop
return false; return false;
} else if ( } else if (_.has(attribute, 'model') && attribute.model === currentModelName) {
_.has(attribute, 'model') &&
attribute.model === currentModelName
) {
types.other = 'modelD'; types.other = 'modelD';
// Break loop // Break loop
@ -198,18 +169,12 @@ module.exports = {
_.forIn(models, model => { _.forIn(models, model => {
_.forIn(model.attributes, attribute => { _.forIn(model.attributes, attribute => {
if (_.has(attribute, 'via') && attribute.via === key) { if (_.has(attribute, 'via') && attribute.via === key) {
if ( if (_.has(attribute, 'collection') && attribute.collection === currentModelName) {
_.has(attribute, 'collection') &&
attribute.collection === currentModelName
) {
types.other = 'collection'; types.other = 'collection';
// Break loop // Break loop
return false; return false;
} else if ( } else if (_.has(attribute, 'model') && attribute.model === currentModelName) {
_.has(attribute, 'model') &&
attribute.model === currentModelName
) {
types.other = 'modelD'; types.other = 'modelD';
// Break loop // Break loop
@ -294,10 +259,7 @@ module.exports = {
nature: 'oneToMany', nature: 'oneToMany',
verbose: 'hasMany', verbose: 'hasMany',
}; };
} else if ( } else if (types.current === 'collection' && types.other === 'collection') {
types.current === 'collection' &&
types.other === 'collection'
) {
return { return {
nature: 'manyToMany', nature: 'manyToMany',
verbose: 'belongsToMany', verbose: 'belongsToMany',
@ -338,6 +300,14 @@ module.exports = {
* Return table name for a collection many-to-many * Return table name for a collection many-to-many
*/ */
getCollectionName: (associationA, associationB) => { getCollectionName: (associationA, associationB) => {
if (associationA.dominant && _.has(associationA, 'collectionName')) {
return associationA.collectionName;
}
if (associationB.dominant && _.has(associationB, 'collectionName')) {
return associationB.collectionName;
}
return [associationA, associationB] return [associationA, associationB]
.sort((a, b) => { .sort((a, b) => {
if (a.collection === b.collection) { if (a.collection === b.collection) {
@ -347,9 +317,7 @@ module.exports = {
return a.collection < b.collection ? -1 : 1; return a.collection < b.collection ? -1 : 1;
}) })
.map(table => .map(table =>
_.snakeCase( _.snakeCase(`${pluralize.plural(table.collection)} ${pluralize.plural(table.via)}`)
`${pluralize.plural(table.collection)} ${pluralize.plural(table.via)}`
)
) )
.join('__'); .join('__');
}, },
@ -373,32 +341,17 @@ module.exports = {
// Get relation nature // Get relation nature
let details; let details;
const targetName = association.model || association.collection || ''; const targetName = association.model || association.collection || '';
const infos = this.getNature( const infos = this.getNature(association, key, undefined, model.toLowerCase());
association,
key,
undefined,
model.toLowerCase()
);
if (targetName !== '*') { if (targetName !== '*') {
if (association.plugin) { if (association.plugin) {
details = _.get( details = _.get(
strapi.plugins, strapi.plugins,
[ [association.plugin, 'models', targetName, 'attributes', association.via],
association.plugin,
'models',
targetName,
'attributes',
association.via,
],
{} {}
); );
} else { } else {
details = _.get( details = _.get(strapi.models, [targetName, 'attributes', association.via], {});
strapi.models,
[targetName, 'attributes', association.via],
{}
);
} }
} }
@ -417,17 +370,14 @@ module.exports = {
}; };
if (infos.nature === 'manyToMany' && definition.orm === 'bookshelf') { if (infos.nature === 'manyToMany' && definition.orm === 'bookshelf') {
ast.tableCollectionName = ast.tableCollectionName = this.getCollectionName(details, association);
_.get(association, 'collectionName') ||
this.getCollectionName(details, association);
} }
if (infos.nature === 'manyWay' && definition.orm === 'bookshelf') { if (infos.nature === 'manyWay' && definition.orm === 'bookshelf') {
ast.tableCollectionName = `${ ast.tableCollectionName =
definition.collectionName _.get(association, 'collectionName') ||
}__${_.snakeCase(key)}`; `${definition.collectionName}__${_.snakeCase(key)}`;
} }
definition.associations.push(ast); definition.associations.push(ast);
return; return;
} }
@ -447,37 +397,25 @@ module.exports = {
return; return;
} }
const pluginsModels = Object.keys(strapi.plugins).reduce( const pluginsModels = Object.keys(strapi.plugins).reduce((acc, current) => {
(acc, current) => { Object.keys(strapi.plugins[current].models).forEach(entity => {
Object.keys(strapi.plugins[current].models).forEach(entity => { Object.keys(strapi.plugins[current].models[entity].attributes).forEach(attribute => {
Object.keys( const attr = strapi.plugins[current].models[entity].attributes[attribute];
strapi.plugins[current].models[entity].attributes
).forEach(attribute => {
const attr =
strapi.plugins[current].models[entity].attributes[attribute];
if ( if ((attr.collection || attr.model || '').toLowerCase() === model.toLowerCase()) {
(attr.collection || attr.model || '').toLowerCase() === acc.push(strapi.plugins[current].models[entity].globalId);
model.toLowerCase() }
) {
acc.push(strapi.plugins[current].models[entity].globalId);
}
});
}); });
});
return acc; return acc;
}, }, []);
[]
);
const appModels = Object.keys(strapi.models).reduce((acc, entity) => { const appModels = Object.keys(strapi.models).reduce((acc, entity) => {
Object.keys(strapi.models[entity].attributes).forEach(attribute => { Object.keys(strapi.models[entity].attributes).forEach(attribute => {
const attr = strapi.models[entity].attributes[attribute]; const attr = strapi.models[entity].attributes[attribute];
if ( if ((attr.collection || attr.model || '').toLowerCase() === model.toLowerCase()) {
(attr.collection || attr.model || '').toLowerCase() ===
model.toLowerCase()
) {
acc.push(strapi.models[entity].globalId); acc.push(strapi.models[entity].globalId);
} }
}); });
@ -485,29 +423,19 @@ module.exports = {
return acc; return acc;
}, []); }, []);
const componentModels = Object.keys(strapi.components).reduce( const componentModels = Object.keys(strapi.components).reduce((acc, entity) => {
(acc, entity) => { Object.keys(strapi.components[entity].attributes).forEach(attribute => {
Object.keys(strapi.components[entity].attributes).forEach( const attr = strapi.components[entity].attributes[attribute];
attribute => {
const attr = strapi.components[entity].attributes[attribute];
if ( if ((attr.collection || attr.model || '').toLowerCase() === model.toLowerCase()) {
(attr.collection || attr.model || '').toLowerCase() === acc.push(strapi.components[entity].globalId);
model.toLowerCase() }
) { });
acc.push(strapi.components[entity].globalId);
}
}
);
return acc; return acc;
}, }, []);
[]
);
const models = _.uniq( const models = _.uniq(appModels.concat(pluginsModels).concat(componentModels));
appModels.concat(pluginsModels).concat(componentModels)
);
definition.associations.push({ definition.associations.push({
alias: key, alias: key,
@ -519,9 +447,7 @@ module.exports = {
}); });
} catch (e) { } catch (e) {
strapi.log.error( strapi.log.error(
`Something went wrong in the model \`${_.upperFirst( `Something went wrong in the model \`${_.upperFirst(model)}\` with the attribute \`${key}\``
model
)}\` with the attribute \`${key}\``
); );
strapi.log.error(e); strapi.log.error(e);
strapi.stop(); strapi.stop();
@ -559,9 +485,7 @@ module.exports = {
const connector = models[model].orm; const connector = models[model].orm;
if (!connector) { if (!connector) {
throw new Error( throw new Error(`Impossible to determine the ORM used for the model ${model}.`);
`Impossible to determine the ORM used for the model ${model}.`
);
} }
const convertor = strapi.db.connectors.get(connector).getQueryParams; const convertor = strapi.db.connectors.get(connector).getQueryParams;
@ -614,17 +538,7 @@ module.exports = {
if ( if (
_.includes( _.includes(
[ ['ne', 'lt', 'gt', 'lte', 'gte', 'contains', 'containss', 'in', 'nin'],
'ne',
'lt',
'gt',
'lte',
'gte',
'contains',
'containss',
'in',
'nin',
],
_.last(suffix) _.last(suffix)
) )
) { ) {

View File

@ -9,13 +9,7 @@ const getKind = obj => obj.kind || 'collectionType';
const pickSchema = model => { const pickSchema = model => {
const schema = _.cloneDeep( const schema = _.cloneDeep(
_.pick(model, [ _.pick(model, ['connection', 'collectionName', 'info', 'options', 'attributes'])
'connection',
'collectionName',
'info',
'options',
'attributes',
])
); );
schema.kind = getKind(model); schema.kind = getKind(model);
@ -26,36 +20,74 @@ module.exports = function(strapi) {
// Retrieve Strapi version. // Retrieve Strapi version.
strapi.config.uuid = _.get(strapi.config.info, 'strapi.uuid', ''); strapi.config.uuid = _.get(strapi.config.info, 'strapi.uuid', '');
strapi.config.info.customs = _.get(strapi.config.info, 'strapi', {}); strapi.config.info.customs = _.get(strapi.config.info, 'strapi', {});
strapi.config.info.strapi = ( strapi.config.info.strapi = (_.get(strapi.config, 'info.dependencies.strapi') || '').replace(
_.get(strapi.config, 'info.dependencies.strapi') || '' /(\^|~)/g,
).replace(/(\^|~)/g, ''); ''
);
strapi.config.info.node = process.versions.node; strapi.config.info.node = process.versions.node;
// Set connections. // Set connections.
strapi.connections = {}; strapi.connections = {};
// Set current environment config. // Set current environment config.
strapi.config.currentEnvironment = strapi.config.currentEnvironment = strapi.config.environments[strapi.config.environment] || {};
strapi.config.environments[strapi.config.environment] || {};
const defaultConnection = const defaultConnection = strapi.config.currentEnvironment.database.defaultConnection;
strapi.config.currentEnvironment.database.defaultConnection;
// Set current connections. // Set current connections.
strapi.config.connections = _.get( strapi.config.connections = _.get(strapi.config.currentEnvironment, 'database.connections', {});
strapi.config.currentEnvironment,
'database.connections',
{}
);
if (_.get(strapi.config, 'language.enabled')) { if (_.get(strapi.config, 'language.enabled')) {
strapi.config.language.locales = Object.keys( strapi.config.language.locales = Object.keys(_.get(strapi.config, 'locales', {}));
_.get(strapi.config, 'locales', {})
);
} }
strapi.contentTypes = {}; strapi.contentTypes = {};
// Check if all collection names are unique
const createErrorMessage = (
indexA,
indexB,
name
) => `The same collection name can't be used for two different ${name}.
First found in ${collectionNames[indexA].origin} \`${collectionNames[indexA].apiOrPluginName}\`, model \`${collectionNames[indexA].modelName}\`.
Second found in ${collectionNames[indexB].origin} \`${collectionNames[indexB].apiOrPluginName}\`, model \`${collectionNames[indexB].modelName}\`.
If you just created a relation between 2 content type, just rename one
`;
const collectionNames = [];
_.forIn(strapi.api, (api, apiName) => {
_.forIn(api.models, (model, modelName) => {
collectionNames.push({
origin: 'API',
collectionName: model.collectionName || `${modelName}`.toLocaleLowerCase(),
apiOrPluginName: apiName,
modelName,
});
});
});
_.forIn(strapi.plugins, (plugin, pluginName) => {
_.forIn(plugin.models, (model, modelName) => {
collectionNames.push({
origin: 'Plugin',
collectionName: model.collectionName || `${modelName}`.toLocaleLowerCase(),
apiOrPluginName: pluginName,
modelName,
});
});
});
for (let indexA = 0; indexA < collectionNames.length; indexA += 1) {
for (let indexB = indexA + 1; indexB < collectionNames.length; indexB += 1) {
if (collectionNames[indexA].collectionName === collectionNames[indexB].collectionName) {
strapi.stopWithError(
new Error(`Duplicated collection name: \`${collectionNames[indexA].collectionName}\`.`),
createErrorMessage(indexA, indexB, 'model')
);
}
}
}
// Set models. // Set models.
strapi.models = Object.keys(strapi.api || []).reduce((acc, apiName) => { strapi.models = Object.keys(strapi.api || []).reduce((acc, apiName) => {
const api = strapi.api[apiName]; const api = strapi.api[apiName];
@ -71,8 +103,7 @@ module.exports = function(strapi) {
apiName, apiName,
modelName, modelName,
globalId: model.globalId || _.upperFirst(_.camelCase(modelName)), globalId: model.globalId || _.upperFirst(_.camelCase(modelName)),
collectionName: collectionName: model.collectionName || `${modelName}`.toLocaleLowerCase(),
model.collectionName || `${modelName}`.toLocaleLowerCase(),
connection: model.connection || defaultConnection, connection: model.connection || defaultConnection,
}); });
@ -133,9 +164,7 @@ module.exports = function(strapi) {
modelName: key, modelName: key,
identity: model.identity || _.upperFirst(key), identity: model.identity || _.upperFirst(key),
globalId: model.globalId || _.upperFirst(_.camelCase(`admin-${key}`)), globalId: model.globalId || _.upperFirst(_.camelCase(`admin-${key}`)),
connection: connection: model.connection || strapi.config.currentEnvironment.database.defaultConnection,
model.connection ||
strapi.config.currentEnvironment.database.defaultConnection,
}); });
strapi.contentTypes[model.uid] = model; strapi.contentTypes[model.uid] = model;
@ -167,13 +196,9 @@ module.exports = function(strapi) {
modelName: key, modelName: key,
uid: `plugins::${pluginName}.${key}`, uid: `plugins::${pluginName}.${key}`,
plugin: pluginName, plugin: pluginName,
collectionName: collectionName: model.collectionName || `${pluginName}_${key}`.toLowerCase(),
model.collectionName || `${pluginName}_${key}`.toLowerCase(), globalId: model.globalId || _.upperFirst(_.camelCase(`${pluginName}-${key}`)),
globalId: connection: model.connection || strapi.config.currentEnvironment.database.defaultConnection,
model.globalId || _.upperFirst(_.camelCase(`${pluginName}-${key}`)),
connection:
model.connection ||
strapi.config.currentEnvironment.database.defaultConnection,
}); });
strapi.contentTypes[model.uid] = model; strapi.contentTypes[model.uid] = model;
@ -259,68 +284,54 @@ module.exports = function(strapi) {
} }
// Preset config in alphabetical order. // Preset config in alphabetical order.
strapi.config.middleware.settings = Object.keys(strapi.middleware).reduce( strapi.config.middleware.settings = Object.keys(strapi.middleware).reduce((acc, current) => {
(acc, current) => { // Try to find the settings in the current environment, then in the main configurations.
// Try to find the settings in the current environment, then in the main configurations. const currentSettings = _.merge(
const currentSettings = _.merge( _.get(_.cloneDeep(strapi.middleware[current]), ['defaults', current], {}),
_.get( flattenMiddlewaresConfig[current] ||
_.cloneDeep(strapi.middleware[current]), strapi.config.currentEnvironment[current] ||
['defaults', current], strapi.config[current]
{} );
), acc[current] = !_.isObject(currentSettings) ? {} : currentSettings;
flattenMiddlewaresConfig[current] ||
strapi.config.currentEnvironment[current] || if (!_.has(acc[current], 'enabled')) {
strapi.config[current] strapi.log.warn(
`(middleware:${current}) wasn't loaded due to missing key \`enabled\` in the configuration`
); );
acc[current] = !_.isObject(currentSettings) ? {} : currentSettings; }
if (!_.has(acc[current], 'enabled')) { // Ensure that enabled key exist by forcing to false.
strapi.log.warn( _.defaults(acc[current], { enabled: false });
`(middleware:${current}) wasn't loaded due to missing key \`enabled\` in the configuration`
);
}
// Ensure that enabled key exist by forcing to false. return acc;
_.defaults(acc[current], { enabled: false }); }, {});
return acc; strapi.config.hook.settings = Object.keys(strapi.hook).reduce((acc, current) => {
}, // Try to find the settings in the current environment, then in the main configurations.
{} const currentSettings = _.merge(
); _.get(_.cloneDeep(strapi.hook[current]), ['defaults', current], {}),
flattenHooksConfig[current] ||
_.get(strapi.config.currentEnvironment, ['hook', current]) ||
_.get(strapi.config, ['hook', current])
);
strapi.config.hook.settings = Object.keys(strapi.hook).reduce( acc[current] = !_.isObject(currentSettings) ? {} : currentSettings;
(acc, current) => {
// Try to find the settings in the current environment, then in the main configurations. if (!_.has(acc[current], 'enabled')) {
const currentSettings = _.merge( strapi.log.warn(
_.get(_.cloneDeep(strapi.hook[current]), ['defaults', current], {}), `(hook:${current}) wasn't loaded due to missing key \`enabled\` in the configuration`
flattenHooksConfig[current] ||
_.get(strapi.config.currentEnvironment, ['hook', current]) ||
_.get(strapi.config, ['hook', current])
); );
}
acc[current] = !_.isObject(currentSettings) ? {} : currentSettings; // Ensure that enabled key exist by forcing to false.
_.defaults(acc[current], { enabled: false });
if (!_.has(acc[current], 'enabled')) { return acc;
strapi.log.warn( }, {});
`(hook:${current}) wasn't loaded due to missing key \`enabled\` in the configuration`
);
}
// Ensure that enabled key exist by forcing to false.
_.defaults(acc[current], { enabled: false });
return acc;
},
{}
);
// default settings // default settings
strapi.config.port = strapi.config.port = _.get(strapi.config.currentEnvironment, 'server.port') || strapi.config.port;
_.get(strapi.config.currentEnvironment, 'server.port') || strapi.config.host = _.get(strapi.config.currentEnvironment, 'server.host') || strapi.config.host;
strapi.config.port;
strapi.config.host =
_.get(strapi.config.currentEnvironment, 'server.host') ||
strapi.config.host;
// proxy settings // proxy settings
const proxy = _.get(strapi.config.currentEnvironment, 'server.proxy', {}); const proxy = _.get(strapi.config.currentEnvironment, 'server.proxy', {});
@ -338,11 +349,7 @@ module.exports = function(strapi) {
port: strapi.config.port, port: strapi.config.port,
}); });
const adminPath = _.get( const adminPath = _.get(strapi.config.currentEnvironment.server, 'admin.path', 'admin');
strapi.config.currentEnvironment.server,
'admin.path',
'admin'
);
// check if we should serve admin panel // check if we should serve admin panel
const shouldServeAdmin = _.get( const shouldServeAdmin = _.get(
@ -357,36 +364,19 @@ module.exports = function(strapi) {
strapi.config.admin.url = new URL(adminPath, strapi.config.url).toString(); strapi.config.admin.url = new URL(adminPath, strapi.config.url).toString();
}; };
const enableHookNestedDependencies = function( const enableHookNestedDependencies = function(strapi, name, flattenHooksConfig, force = false) {
strapi,
name,
flattenHooksConfig,
force = false
) {
// Couldn't find configurations for this hook. // Couldn't find configurations for this hook.
if (_.isEmpty(_.get(flattenHooksConfig, name, true))) { if (_.isEmpty(_.get(flattenHooksConfig, name, true))) {
// Check if database connector is used // Check if database connector is used
const modelsUsed = Object.keys( const modelsUsed = Object.keys(_.assign(_.clone(strapi.api) || {}, strapi.plugins))
_.assign(_.clone(strapi.api) || {}, strapi.plugins)
)
.filter(x => .filter(x =>
_.isObject( _.isObject(_.get(strapi.api, [x, 'models']) || _.get(strapi.plugins, [x, 'models']))
_.get(strapi.api, [x, 'models']) ||
_.get(strapi.plugins, [x, 'models'])
)
) // Filter API with models ) // Filter API with models
.map( .map(x => _.get(strapi.api, [x, 'models']) || _.get(strapi.plugins, [x, 'models'])) // Keep models
x =>
_.get(strapi.api, [x, 'models']) ||
_.get(strapi.plugins, [x, 'models'])
) // Keep models
.filter(models => { .filter(models => {
const apiModelsUsed = Object.keys(models).filter(model => { const apiModelsUsed = Object.keys(models).filter(model => {
const connector = _.get( const connector = _.get(strapi.config.connections, models[model].connection, {})
strapi.config.connections, .connector;
models[model].connection,
{}
).connector;
if (connector) { if (connector) {
return connector.replace('strapi-hook-', '') === name; return connector.replace('strapi-hook-', '') === name;

View File

@ -8,7 +8,7 @@ const checkReservedFilename = require('./check-reserved-filename');
* @param {string} dir - directory from which to load configs * @param {string} dir - directory from which to load configs
* @param {string} pattern - glob pattern to search for config files * @param {string} pattern - glob pattern to search for config files
*/ */
const laodConfigFiles = (dir, pattern = 'config/**/*.+(js|json)') => const loadConfigFiles = (dir, pattern = 'config/**/*.+(js|json)') =>
loadFiles(dir, pattern, { loadFiles(dir, pattern, {
requireFn: requireFileAndParse, requireFn: requireFileAndParse,
shouldUseFileNameAsKey: checkReservedFilename, shouldUseFileNameAsKey: checkReservedFilename,
@ -18,4 +18,4 @@ const laodConfigFiles = (dir, pattern = 'config/**/*.+(js|json)') =>
}, },
}); });
module.exports = laodConfigFiles; module.exports = loadConfigFiles;