use format schema, actions, lifecycles

This commit is contained in:
Pierre Noël 2021-06-21 12:02:10 +02:00
parent 323bf21f43
commit dee087a9be
13 changed files with 190 additions and 114 deletions

View File

@ -335,8 +335,13 @@ class Strapi {
} }
}); });
const pluginProvider = await createPluginProvider(this); try {
this.plugin = pluginProvider; const pluginProvider = await createPluginProvider(this);
this.plugin = pluginProvider;
console.log(this.plugin('i18n').contentType.getAll());
} catch (e) {
console.log(e);
}
// const modules = await loadModules(this); // const modules = await loadModules(this);

View File

@ -4,37 +4,37 @@ const { cloneDeep } = require('lodash/fp');
const { validateContentTypeDefinition } = require('./validator'); const { validateContentTypeDefinition } = require('./validator');
const createContentType = (definition, { apiName, pluginName } = {}) => { const createContentType = (definition, { apiName, pluginName } = {}) => {
const createdContentType = cloneDeep(definition);
validateContentTypeDefinition(definition); validateContentTypeDefinition(definition);
const createdContentType = cloneDeep(definition);
if (apiName) { if (apiName) {
Object.assign(createdContentType, { Object.assign(createdContentType.schema, {
uid: `application::${apiName}.${definition.info.singularName}`, uid: `application::${apiName}.${definition.schema.info.singularName}`,
apiName, apiName,
collectionName: definition.collectionName || definition.info.singularName, collectionName: definition.schema.collectionName || definition.schema.info.singularName,
}); });
} else if (pluginName) { } else if (pluginName) {
Object.assign(createdContentType, { Object.assign(createdContentType.schema, {
uid: `plugins::${pluginName}.${definition.info.singularName}`, uid: `plugins::${pluginName}.${definition.schema.info.singularName}`,
plugin: pluginName, plugin: pluginName,
collectionName: collectionName:
createdContentType.collectionName || createdContentType.schema.collectionName ||
`${pluginName}_${definition.info.singularName}`.toLowerCase(), `${pluginName}_${definition.schema.info.singularName}`.toLowerCase(),
}); });
} else { } else {
Object.assign(createdContentType, { Object.assign(createdContentType.schema, {
uid: `strapi::${definition.info.singularName}`, uid: `strapi::${definition.schema.info.singularName}`,
plugin: 'admin', plugin: 'admin',
}); });
} }
Object.assign(createdContentType, { Object.assign(createdContentType.schema, {
kind: createdContentType.kind || 'collectionType', kind: createdContentType.schema.kind || 'collectionType',
}); });
Object.defineProperty(createdContentType, 'privateAttributes', { Object.defineProperty(createdContentType.schema, 'privateAttributes', {
get() { get() {
return strapi.getModel(createdContentType.uid).privateAttributes; return strapi.getModel(createdContentType.schema.uid).privateAttributes;
}, },
}); });

View File

@ -1,22 +1,34 @@
'use strict'; 'use strict';
const { keyBy, mapValues } = require('lodash');
const { yup } = require('@strapi/utils'); const { yup } = require('@strapi/utils');
// To replace by directly using implemented lifecycles
const lifecycles = ['beforeCreate', 'afterCreate'];
const lifecyclesShape = mapValues(keyBy(lifecycles), () => yup.mixed().isFunction());
const contentTypeSchemaValidator = yup.object().shape({ const contentTypeSchemaValidator = yup.object().shape({
info: yup schema: yup.object().shape({
info: yup
.object()
.shape({
singularName: yup
.string()
.isCamelCase()
.required(),
pluralName: yup
.string()
.isCamelCase()
.required(),
displayName: yup.string().required(),
})
.required(),
}),
actions: yup.object().onlyContainsFunctions(),
lifecycles: yup
.object() .object()
.shape({ .shape(lifecyclesShape)
singularName: yup .noUnknown(),
.string()
.isCamelCase()
.required(),
pluralName: yup
.string()
.isCamelCase()
.required(),
displayName: yup.string().required(),
})
.required(),
}); });
const validateContentTypeDefinition = data => { const validateContentTypeDefinition = data => {

View File

@ -5,8 +5,8 @@ const { createContentType } = require('../domain/content-type');
module.exports = (pluginName, contentTypeDefinitions) => { module.exports = (pluginName, contentTypeDefinitions) => {
const contentTypes = contentTypeDefinitions.map(ct => createContentType(ct, { pluginName })); const contentTypes = contentTypeDefinitions.map(ct => createContentType(ct, { pluginName }));
const contentTypesMap = contentTypes.reduce((map, ct) => { const contentTypesMap = contentTypes.reduce((map, ct) => {
map[ct.info.singularName] = ct; map[ct.schema.info.singularName] = ct;
map[ct.info.pluralName] = ct; map[ct.schema.info.pluralName] = ct;
return map; return map;
}, {}); }, {});

View File

@ -1,6 +1,7 @@
'use strict'; 'use strict';
const { yup, kebabCase } = require('@strapi/utils'); const { kebabCase } = require('lodash/fp');
const { yup } = require('@strapi/utils');
const strapiServerSchema = yup const strapiServerSchema = yup
.object() .object()
@ -38,14 +39,14 @@ const validateStrapiServer = data => {
const validateContentTypesUnicity = contentTypes => { const validateContentTypesUnicity = contentTypes => {
const names = []; const names = [];
contentTypes.forEach(ct => { contentTypes.forEach(ct => {
const singularName = kebabCase(ct.info.singularName); const singularName = kebabCase(ct.schema.info.singularName);
const pluralName = kebabCase(ct.info.pluralName); const pluralName = kebabCase(ct.schema.info.pluralName);
if (names.includes(singularName)) { if (names.includes(singularName)) {
throw new Error(`The singular name "${ct.info.singularName}" should be unique`); throw new Error(`The singular name "${ct.schema.info.singularName}" should be unique`);
} }
names.push(singularName); names.push(singularName);
if (names.includes(pluralName)) { if (names.includes(pluralName)) {
throw new Error(`The plural name "${ct.info.pluralName}" should be unique`); throw new Error(`The plural name "${ct.schema.info.pluralName}" should be unique`);
} }
names.push(pluralName); names.push(pluralName);
}); });

View File

@ -28,11 +28,20 @@ function isCamelCase(message = '${path} is not in camel case (anExampleOfCamelCa
return this.test('is in camelCase', message, value => value === _.camelCase(value)); return this.test('is in camelCase', message, value => value === _.camelCase(value));
} }
function onlyContainsFunctions(message = '${path} contains values that are not functions') {
return this.test(
'only contains functions',
message,
value => value && Object.values(value).every(_.isFunction)
);
}
yup.addMethod(yup.mixed, 'notNil', isNotNill); yup.addMethod(yup.mixed, 'notNil', isNotNill);
yup.addMethod(yup.mixed, 'notNull', isNotNull); yup.addMethod(yup.mixed, 'notNull', isNotNull);
yup.addMethod(yup.array, 'requiredAllowEmpty', arrayRequiredAllowEmpty); yup.addMethod(yup.array, 'requiredAllowEmpty', arrayRequiredAllowEmpty);
yup.addMethod(yup.mixed, 'isFunction', isFunction); yup.addMethod(yup.mixed, 'isFunction', isFunction);
yup.addMethod(yup.string, 'isCamelCase', isCamelCase); yup.addMethod(yup.string, 'isCamelCase', isCamelCase);
yup.addMethod(yup.object, 'onlyContainsFunctions', onlyContainsFunctions);
class StrapiIDSchema extends MixedSchemaType { class StrapiIDSchema extends MixedSchemaType {
constructor() { constructor() {

View File

@ -0,0 +1,14 @@
'use strict';
module.exports = {
// find() {},
// create() {},
// findPage() {},
// findWithRelationCounts() {},
// findOne() {},
// update() {},
// delete() {},
// search() {},
// searchWithRelationCounts() {},
// searchPage() {},
};

View File

@ -0,0 +1,11 @@
'use strict';
const schema = require('./schema');
const actions = require('./actions');
const lifecycles = require('./lifecycles');
module.exports = {
schema,
actions,
lifecycles,
};

View File

@ -0,0 +1,5 @@
'use strict';
module.exports = {
beforeCreate() {},
afterCreate() {},
};

View File

@ -1,64 +0,0 @@
{
"routes": [
{
"method": "GET",
"path": "/iso-locales",
"handler": "iso-locales.listIsoLocales",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["plugins::content-manager.hasPermissions", ["plugins::i18n.locale.read"]]
]
}
},
{
"method": "GET",
"path": "/locales",
"handler": "locales.listLocales",
"config": {
"policies": ["admin::isAuthenticatedAdmin"]
}
},
{
"method": "POST",
"path": "/locales",
"handler": "locales.createLocale",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["plugins::content-manager.hasPermissions", ["plugins::i18n.locale.create"]]
]
}
},
{
"method": "PUT",
"path": "/locales/:id",
"handler": "locales.updateLocale",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["plugins::content-manager.hasPermissions", ["plugins::i18n.locale.update"]]
]
}
},
{
"method": "DELETE",
"path": "/locales/:id",
"handler": "locales.deleteLocale",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["plugins::content-manager.hasPermissions", ["plugins::i18n.locale.delete"]]
]
}
},
{
"method": "POST",
"path": "/content-manager/actions/get-non-localized-fields",
"handler": "content-types.getNonLocalizedAttributes",
"config": {
"policies": ["admin::isAuthenticatedAdmin"]
}
}
]
}

View File

@ -0,0 +1,64 @@
'use strict';
module.exports = [
{
method: 'GET',
path: '/iso-locales',
handler: 'iso-locales.listIsoLocales',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['plugins::content-manager.hasPermissions', ['plugins::i18n.locale.read']],
],
},
},
{
method: 'GET',
path: '/locales',
handler: 'locales.listLocales',
config: {
policies: ['admin::isAuthenticatedAdmin'],
},
},
{
method: 'POST',
path: '/locales',
handler: 'locales.createLocale',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['plugins::content-manager.hasPermissions', ['plugins::i18n.locale.create']],
],
},
},
{
method: 'PUT',
path: '/locales/:id',
handler: 'locales.updateLocale',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['plugins::content-manager.hasPermissions', ['plugins::i18n.locale.update']],
],
},
},
{
method: 'DELETE',
path: '/locales/:id',
handler: 'locales.deleteLocale',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['plugins::content-manager.hasPermissions', ['plugins::i18n.locale.delete']],
],
},
},
{
method: 'POST',
path: '/content-manager/actions/get-non-localized-fields',
handler: 'content-types.getNonLocalizedAttributes',
config: {
policies: ['admin::isAuthenticatedAdmin'],
},
},
];

View File

@ -4,27 +4,46 @@ const bootstrap = require('./server/bootstrap');
const contentTypes = require('./server/content-types'); const contentTypes = require('./server/content-types');
const policies = require('./server/policies'); const policies = require('./server/policies');
const services = require('./server/services'); const services = require('./server/services');
// const routes = require('./server/routes');
// object or function. If function then pass strapi. // object or function. If function then pass strapi.
module.exports = () => { module.exports = () => {
return { return {
bootstrap, register: () => {
// register, // extend entityService
destroy: () => console.log('i18n DESTROY'), // route.add('/giveBestCountries', { action: giveBestCountries });
config: { // route.add('/giveBestCountries', [policies.get('plugins::users-permissions.permissions')],
default: () => ({ // handler: giveBestCountries,
olala: 'olala', // });
pouet: 'pouet', // route.add('/giveBestCountries', (ctx, { }) => {
featureA: true, // ctx.entityService('countries').giveBestCountries();
}), // });
validator: () => {}, //
// addQuery('giveBestCountries', {
// args: ,
// resolve: ,
// type: ,
// });
//
// registerRoute('/countries', {
// method: 'get',
// handler: () => {},
// })
}, },
routes: [], bootstrap,
controllers: {}, // routes,
// controllers: {},
middlewares: {}, middlewares: {},
contentTypes, contentTypes,
policies, policies,
services, services,
hooks: {}, // middlewares,
}; };
}; };
// create, update, delete, read
// modifier une route existance CRUD
// Ajouter des nouvelles routes / query graphql
//