169 lines
4.6 KiB
JavaScript

const _ = require('lodash');
const pluralize = require('pluralize');
module.exports = async cb => {
const pickData = (model) => _.pick(model, [
'info',
'connection',
'collectionName',
'attributes',
'identity',
'globalId',
'globalName',
'orm',
'loadedModel',
'primaryKey',
'associations'
]);
const models = _.mapValues(strapi.models, pickData);
delete models['core_store'];
const pluginsModel = Object.keys(strapi.plugins).reduce((acc, current) => {
acc[current] = {
models: _.mapValues(strapi.plugins[current].models, pickData),
};
return acc;
}, {});
// Init schema
const schema = {
generalSettings: {
search: true,
filters: true,
bulkActions: true,
pageEntries: 10,
},
models: {
plugins: {},
},
};
const buildSchema = (model, name, plugin = false) => {
// Model data
const schemaModel = Object.assign({
label: _.upperFirst(name),
labelPlural: _.upperFirst(pluralize(name)),
orm: model.orm || 'mongoose',
search: true,
filters: true,
bulkActions: true,
pageEntries: 10,
defaultSort: model.primaryKey,
sort: 'ASC',
}, model);
// Fields (non relation)
schemaModel.fields = _.mapValues(_.pickBy(model.attributes, attribute =>
!attribute.model && !attribute.collection
), (value, attribute) => ({
label: _.upperFirst(attribute),
description: '',
type: value.type || 'string',
}));
// Select fields displayed in list view
// schemaModel.list = _.slice(_.keys(schemaModel.fields), 0, 4);
schemaModel.listDisplay = Object.keys(schemaModel.fields)
// Construct Array of attr ex { type: 'string', label: 'Foo', name: 'Foo', description: '' }
// NOTE: Do we allow sort on boolean?
.map(attr => {
const attrType = schemaModel.fields[attr].type;
const sortable = attrType !== 'json' && attrType !== 'array';
return Object.assign(schemaModel.fields[attr], { name: attr, sortable, searchable: sortable });
})
// Retrieve only the fourth first items
.slice(0, 4);
schemaModel.listDisplay.splice(0, 0, {
name: model.primaryKey || 'id',
label: 'Id',
type: 'string',
sortable: true,
searchable: true,
});
if (model.associations) {
// Model relations
schemaModel.relations = model.associations.reduce((acc, current) => {
const displayedAttribute = current.plugin ?
_.get(pluginsModel, [current.plugin, 'models', current.model || current.collection, 'info', 'mainField']) ||
_.findKey(_.get(pluginsModel, [current.plugin, 'models', current.model || current.collection, 'attributes']), { type : 'string'}) ||
'id' :
_.get(models, [current.model || current.collection, 'info', 'mainField']) ||
_.findKey(_.get(models, [current.model || current.collection, 'attributes']), { type : 'string'}) ||
'id';
acc[current.alias] = {
...current,
description: '',
displayedAttribute,
};
return acc;
}, {});
}
if (plugin) {
return _.set(schema.models.plugins, `${plugin}.${name}`, schemaModel);
}
// Set the formatted model to the schema
schema.models[name] = schemaModel;
};
_.forEach(pluginsModel, (plugin, pluginName) => {
_.forEach(plugin.models, (model, name) => {
buildSchema(model, name, pluginName);
});
});
// Generate schema for models.
_.forEach(models, (model, name) => {
buildSchema(model, name);
});
const pluginStore = strapi.store({
environment: '',
type: 'plugin',
name: 'content-manager'
});
const buildSchemaKeys = (data) => Object.keys(data).reduce((acc, curr) => {
if (curr !== 'plugins') {
if (!data[curr].fields && _.isObject(data[curr])) {
return buildSchemaKeys(data[curr]);
}
return acc.concat([{ [curr]: Object.keys(data[curr].fields) }]);
}
return buildSchemaKeys(data[curr]);
}, []);
try {
const prevSchema = await pluginStore.get({ key: 'schema' });
if (!prevSchema) {
pluginStore.set({ key: 'schema', value: schema });
return cb();
}
const prevSchemaKeys = buildSchemaKeys(prevSchema.models);
const schemaKeys = buildSchemaKeys(schema.models);
// Update the store with the new created APIs
if (!_.isEqual(prevSchemaKeys, schemaKeys)) {
pluginStore.set({ key: 'schema', value: _.merge(schema, prevSchema) });
}
} catch(err) {
console.log('error', err);
}
cb();
};