mirror of
https://github.com/strapi/strapi.git
synced 2025-09-08 08:08:18 +00:00
init edit and delete content type with schema manager
This commit is contained in:
parent
22ca3c476a
commit
f255d0d700
@ -127,9 +127,10 @@ module.exports = (scope, cb) => {
|
||||
|
||||
// Get default connection
|
||||
try {
|
||||
scope.connection =
|
||||
_.get(scope.args, 'connection') ||
|
||||
JSON.parse(
|
||||
scope.connection = scope.args.connection;
|
||||
if (!scope.args.connection) {
|
||||
try {
|
||||
scope.connection = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.resolve(
|
||||
scope.rootPath,
|
||||
@ -139,8 +140,11 @@ module.exports = (scope, cb) => {
|
||||
'database.json'
|
||||
)
|
||||
)
|
||||
).defaultConnection ||
|
||||
'';
|
||||
).defaultConnection;
|
||||
} catch (err) {
|
||||
scope.connection = 'default';
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
return cb.invalid(err);
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ module.exports = {
|
||||
|
||||
ctx.send({ data: { uid: component.uid } }, 201);
|
||||
} catch (error) {
|
||||
strapi.log.error(error);
|
||||
ctx.send({ error: error.message }, 400);
|
||||
}
|
||||
},
|
||||
@ -98,6 +99,7 @@ module.exports = {
|
||||
|
||||
ctx.send({ data: { uid: component.uid } });
|
||||
} catch (error) {
|
||||
strapi.log.error(error);
|
||||
ctx.send({ error: error.message }, 400);
|
||||
}
|
||||
},
|
||||
@ -119,6 +121,7 @@ module.exports = {
|
||||
|
||||
ctx.send({ data: { uid: component.uid } });
|
||||
} catch (error) {
|
||||
strapi.log.error(error);
|
||||
ctx.send({ error: error.message }, 400);
|
||||
}
|
||||
},
|
||||
|
@ -66,127 +66,53 @@ module.exports = {
|
||||
|
||||
ctx.send({ data: { uid: component.uid } }, 201);
|
||||
} catch (error) {
|
||||
strapi.log.error(error);
|
||||
strapi.emit('didNotCreateContentType', error);
|
||||
ctx.send({ error: error.message }, 400);
|
||||
}
|
||||
|
||||
// strapi.reload.isWatching = false;
|
||||
|
||||
// try {
|
||||
// const contentTypeSchema = contentTypeService.createContentTypeSchema(
|
||||
// body.contentType
|
||||
// );
|
||||
|
||||
// await contentTypeService.generateAPI(modelName, contentTypeSchema);
|
||||
|
||||
// await contentTypeService.generateReversedRelations({
|
||||
// attributes: body.contentType.attributes,
|
||||
// modelName,
|
||||
// });
|
||||
|
||||
// if (_.isEmpty(strapi.api)) {
|
||||
// strapi.emit('didCreateFirstContentType');
|
||||
// } else {
|
||||
// strapi.emit('didCreateContentType');
|
||||
// }
|
||||
// } catch (e) {
|
||||
// strapi.log.error(e);
|
||||
// strapi.emit('didNotCreateContentType', e);
|
||||
// return ctx.badRequest(null, [
|
||||
// { messages: [{ id: 'request.error.model.write' }] },
|
||||
// ]);
|
||||
// }
|
||||
|
||||
// setImmediate(() => strapi.reload());
|
||||
|
||||
// ctx.send(
|
||||
// {
|
||||
// data: {
|
||||
// uid,
|
||||
// },
|
||||
// },
|
||||
// 201
|
||||
// );
|
||||
},
|
||||
|
||||
async updateContentType(ctx) {
|
||||
const { uid } = ctx.params;
|
||||
const { body } = ctx.request;
|
||||
|
||||
const contentType = strapi.contentTypes[uid];
|
||||
|
||||
if (!contentType) {
|
||||
return ctx.send({ error: 'contentType.notFound' }, 404);
|
||||
}
|
||||
|
||||
try {
|
||||
await validateUpdateContentTypeInput(body);
|
||||
} catch (error) {
|
||||
return ctx.send({ error }, 400);
|
||||
}
|
||||
|
||||
try {
|
||||
strapi.reload.isWatching = false;
|
||||
|
||||
try {
|
||||
const newSchema = contentTypeService.updateContentTypeSchema(
|
||||
contentType.__schema__,
|
||||
body.contentType
|
||||
);
|
||||
|
||||
await contentTypeService.writeContentType({ uid, schema: newSchema });
|
||||
|
||||
// delete all relations directed to the updated ct except for oneWay and manyWay
|
||||
await contentTypeService.deleteBidirectionalRelations(contentType);
|
||||
|
||||
await contentTypeService.generateReversedRelations({
|
||||
attributes: body.contentType.attributes,
|
||||
modelName: contentType.modelName,
|
||||
plugin: contentType.plugin,
|
||||
const component = await contentTypeService.editContentType(uid, {
|
||||
contentType: body.contentType,
|
||||
components: body.components,
|
||||
});
|
||||
|
||||
if (_.isEmpty(strapi.api)) {
|
||||
strapi.emit('didCreateFirstContentType');
|
||||
} else {
|
||||
strapi.emit('didCreateContentType');
|
||||
}
|
||||
} catch (error) {
|
||||
strapi.emit('didNotCreateContentType', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
setImmediate(() => strapi.reload());
|
||||
|
||||
ctx.send({
|
||||
data: {
|
||||
uid,
|
||||
},
|
||||
});
|
||||
ctx.send({ data: { uid: component.uid } }, 201);
|
||||
} catch (error) {
|
||||
strapi.log.error(error);
|
||||
ctx.send({ error: error.message }, 400);
|
||||
}
|
||||
},
|
||||
|
||||
async deleteContentType(ctx) {
|
||||
const { uid } = ctx.params;
|
||||
|
||||
const contentType = strapi.contentTypes[uid];
|
||||
|
||||
if (!contentType) {
|
||||
return ctx.send({ error: 'contentType.notFound' }, 404);
|
||||
}
|
||||
|
||||
if (!_.has(contentType, 'apiName')) {
|
||||
return ctx.send({ error: 'contentType.not.deletable' }, 400);
|
||||
}
|
||||
|
||||
try {
|
||||
strapi.reload.isWatching = false;
|
||||
|
||||
await contentTypeService.deleteAllRelations(contentType);
|
||||
await contentTypeService.removeContentType(contentType);
|
||||
const component = await contentTypeService.deleteContentType(uid);
|
||||
|
||||
setImmediate(() => strapi.reload());
|
||||
|
||||
ctx.send({
|
||||
data: {
|
||||
uid,
|
||||
},
|
||||
});
|
||||
ctx.send({ data: { uid: component.uid } });
|
||||
} catch (error) {
|
||||
strapi.log.error(error);
|
||||
ctx.send({ error: error.message }, 400);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -1,8 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const pluralize = require('pluralize');
|
||||
const generator = require('strapi-generate');
|
||||
|
||||
const { formatAttributes } = require('../utils/attributes');
|
||||
const getSchemaManager = require('./schema-manager');
|
||||
const { nameToSlug } = require('../utils/helpers');
|
||||
|
||||
/**
|
||||
* Creates a component and handle the nested components sent with it
|
||||
@ -10,7 +14,10 @@ const getSchemaManager = require('./schema-manager');
|
||||
* @param {Object} params.component Main component to create
|
||||
* @param {Array<Object>} params.components List of nested components to created or edit
|
||||
*/
|
||||
const createContentType = ({ contentType, components = [] }) => {
|
||||
const createContentType = async ({ contentType, components = [] }) => {
|
||||
// generate api squeleton
|
||||
await generateAPI(contentType.name);
|
||||
|
||||
const componentsToCreate = components.filter(compo => !_.has(compo, 'uid'));
|
||||
const componentsToEdit = components.filter(compo => _.has(compo, 'uid'));
|
||||
|
||||
@ -24,8 +31,81 @@ const createContentType = ({ contentType, components = [] }) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a squeleton API
|
||||
* @param {*} name
|
||||
* @param {*} contentType
|
||||
*/
|
||||
const generateAPI = name => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const scope = {
|
||||
generatorType: 'api',
|
||||
id: nameToSlug(name),
|
||||
name: nameToSlug(name),
|
||||
rootPath: strapi.dir,
|
||||
args: {
|
||||
attributes: {},
|
||||
},
|
||||
};
|
||||
|
||||
generator(scope, {
|
||||
success: () => resolve(),
|
||||
error: err => reject(err),
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Edits a contentType and handle the nested contentTypes sent with it
|
||||
* @param {Object} params params object
|
||||
* @param {Object} params.contentType Main contentType to create
|
||||
* @param {Array<Object>} params.components List of nested components to created or edit
|
||||
*/
|
||||
const editContentType = (uid, { contentType, components = [] }) => {
|
||||
const componentsToCreate = components.filter(compo => !_.has(compo, 'uid'));
|
||||
const componentsToEdit = components.filter(compo => _.has(compo, 'uid'));
|
||||
|
||||
return getSchemaManager().edit(ctx => {
|
||||
const updatedComponent = ctx.editContentType({
|
||||
uid,
|
||||
...contentType,
|
||||
});
|
||||
|
||||
componentsToCreate.forEach(ctx.createComponent);
|
||||
componentsToEdit.forEach(ctx.editComponent);
|
||||
|
||||
return updatedComponent;
|
||||
});
|
||||
};
|
||||
|
||||
const deleteContentType = uid => {
|
||||
return getSchemaManager().edit(ctx => {
|
||||
return ctx.deleteContentType(uid);
|
||||
});
|
||||
};
|
||||
|
||||
const formatContentType = contentType => {
|
||||
const { uid, plugin, connection, collectionName, info } = contentType;
|
||||
|
||||
return {
|
||||
uid,
|
||||
plugin,
|
||||
schema: {
|
||||
name: _.get(info, 'name') || _.upperFirst(pluralize(uid)),
|
||||
description: _.get(info, 'description', ''),
|
||||
connection,
|
||||
collectionName,
|
||||
attributes: formatAttributes(contentType),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createContentType,
|
||||
editContentType,
|
||||
deleteContentType,
|
||||
|
||||
formatContentType,
|
||||
};
|
||||
|
||||
// const path = require('path');
|
||||
@ -267,51 +347,6 @@ module.exports = {
|
||||
// return fse.writeFile(filePath, JSON.stringify(schema, null, 2));
|
||||
// };
|
||||
|
||||
// const formatContentType = contentType => {
|
||||
// const { uid, plugin, connection, collectionName, info } = contentType;
|
||||
|
||||
// return {
|
||||
// uid,
|
||||
// plugin,
|
||||
// schema: {
|
||||
// name: _.get(info, 'name') || _.upperFirst(pluralize(uid)),
|
||||
// description: _.get(info, 'description', ''),
|
||||
// connection,
|
||||
// collectionName,
|
||||
// attributes: formatAttributes(contentType),
|
||||
// },
|
||||
// };
|
||||
// };
|
||||
|
||||
// const createContentTypeSchema = infos => ({
|
||||
// connection:
|
||||
// infos.connection ||
|
||||
// _.get(
|
||||
// strapi,
|
||||
// ['config', 'currentEnvironment', 'database', 'defaultConnection'],
|
||||
// 'default'
|
||||
// ),
|
||||
// collectionName:
|
||||
// infos.collectionName || `${nameToCollectionName(pluralize(infos.name))}`,
|
||||
// info: {
|
||||
// name: infos.name,
|
||||
// description: infos.description,
|
||||
// },
|
||||
// attributes: convertAttributes(infos.attributes),
|
||||
// });
|
||||
|
||||
// const updateContentTypeSchema = (old, infos) => ({
|
||||
// ...old,
|
||||
// connection: infos.connection || old.connection,
|
||||
// collectionName: infos.collectionName || old.collectionName,
|
||||
// info: {
|
||||
// name: infos.name || old.info.name,
|
||||
// description: infos.description || old.info.description,
|
||||
// },
|
||||
// // TODO: keep old params like autoMigration, private, configurable
|
||||
// attributes: convertAttributes(infos.attributes),
|
||||
// });
|
||||
|
||||
// const generateAPI = (name, contentType) => {
|
||||
// // create api
|
||||
// return new Promise((resolve, reject) => {
|
||||
|
@ -15,7 +15,7 @@ const createSchemaHandler = require('./schema-handler');
|
||||
const createComponentUID = ({ category, name }) =>
|
||||
`${nameToSlug(category)}.${nameToSlug(name)}`;
|
||||
|
||||
module.exports = function createComponentBuilder({ tmpComponents }) {
|
||||
module.exports = function createComponentBuilder() {
|
||||
return {
|
||||
/**
|
||||
* create a component in the tmpComponent map
|
||||
@ -23,7 +23,7 @@ module.exports = function createComponentBuilder({ tmpComponents }) {
|
||||
createComponent(infos) {
|
||||
const uid = createComponentUID(infos);
|
||||
|
||||
if (tmpComponents.has(uid)) {
|
||||
if (this.components.has(uid)) {
|
||||
throw new Error('component.alreadyExists');
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ module.exports = function createComponentBuilder({ tmpComponents }) {
|
||||
.set(['info', 'description'], infos.description)
|
||||
.set('attributes', convertAttributes(infos.attributes));
|
||||
|
||||
tmpComponents.set(uid, handler);
|
||||
this.components.set(uid, handler);
|
||||
|
||||
return handler;
|
||||
},
|
||||
@ -62,18 +62,18 @@ module.exports = function createComponentBuilder({ tmpComponents }) {
|
||||
editComponent(infos) {
|
||||
const { uid } = infos;
|
||||
|
||||
if (!tmpComponents.has(uid)) {
|
||||
if (!this.components.has(uid)) {
|
||||
throw new Error('component.notFound');
|
||||
}
|
||||
|
||||
const handler = tmpComponents.get(uid);
|
||||
const handler = this.components.get(uid);
|
||||
|
||||
const [, nameUID] = uid.split('.');
|
||||
|
||||
const newCategory = nameToSlug(infos.category);
|
||||
const newUID = `${newCategory}.${nameUID}`;
|
||||
|
||||
if (newUID !== uid && tmpComponents.has(newUID)) {
|
||||
if (newUID !== uid && this.components.has(newUID)) {
|
||||
throw new Error('component.edit.alreadyExists');
|
||||
}
|
||||
|
||||
@ -87,6 +87,7 @@ module.exports = function createComponentBuilder({ tmpComponents }) {
|
||||
.set(['info', 'name'], infos.name)
|
||||
.set(['info', 'icon'], infos.icon)
|
||||
.set(['info', 'description'], infos.description)
|
||||
// TODO: keep configurable args etc...
|
||||
.set('attributes', convertAttributes(infos.attributes));
|
||||
|
||||
if (newUID !== uid) {
|
||||
@ -103,7 +104,7 @@ module.exports = function createComponentBuilder({ tmpComponents }) {
|
||||
},
|
||||
|
||||
deleteComponent(uid) {
|
||||
if (!tmpComponents.has(uid)) {
|
||||
if (!this.components.has(uid)) {
|
||||
throw new Error('component.notFound');
|
||||
}
|
||||
|
||||
@ -115,7 +116,7 @@ module.exports = function createComponentBuilder({ tmpComponents }) {
|
||||
ct.removeComponent(uid);
|
||||
});
|
||||
|
||||
return tmpComponents.get(uid).delete();
|
||||
return this.components.get(uid).delete();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -15,7 +15,7 @@ const createSchemaHandler = require('./schema-handler');
|
||||
const createContentTypeUID = ({ name }) =>
|
||||
`application::${nameToSlug(name)}.${nameToSlug(name)}`;
|
||||
|
||||
module.exports = function createComponentBuilder({ tmpContentTypes }) {
|
||||
module.exports = function createComponentBuilder() {
|
||||
return {
|
||||
/**
|
||||
* create a component in the tmpComponent map
|
||||
@ -23,13 +23,13 @@ module.exports = function createComponentBuilder({ tmpContentTypes }) {
|
||||
createContentType(infos) {
|
||||
const uid = createContentTypeUID(infos);
|
||||
|
||||
if (tmpContentTypes.has(uid)) {
|
||||
if (this.contentTypes.has(uid)) {
|
||||
throw new Error('contentType.alreadyExists');
|
||||
}
|
||||
|
||||
const handler = createSchemaHandler({
|
||||
dir: path.join(strapi.dir, 'api', nameToSlug(infos.name), 'models'),
|
||||
filename: `${nameToSlug(infos.name)}.json`,
|
||||
filename: `${nameToSlug(infos.name)}.settings.json`,
|
||||
});
|
||||
|
||||
const defaultConnection = _.get(
|
||||
@ -50,9 +50,51 @@ module.exports = function createComponentBuilder({ tmpContentTypes }) {
|
||||
.set(['info', 'description'], infos.description)
|
||||
.set('attributes', convertAttributes(infos.attributes));
|
||||
|
||||
tmpContentTypes.set(uid, handler);
|
||||
this.contentTypes.set(uid, handler);
|
||||
|
||||
// TODO: add reversed relations
|
||||
|
||||
return handler;
|
||||
},
|
||||
|
||||
editContentType(infos) {
|
||||
const { uid } = infos;
|
||||
|
||||
if (!this.contentTypes.has(uid)) {
|
||||
throw new Error('contentType.notFound');
|
||||
}
|
||||
|
||||
const handler = this.contentTypes.get(uid);
|
||||
|
||||
handler
|
||||
.set('connection', infos.connection)
|
||||
.set('collectionName', infos.collectionName)
|
||||
.set(['info', 'name'], infos.name)
|
||||
.set(['info', 'description'], infos.description)
|
||||
// TODO: keep configurable args etc...
|
||||
.set('attributes', convertAttributes(infos.attributes));
|
||||
|
||||
// TODO: clear old relations
|
||||
// TODO: build new reversed relations
|
||||
|
||||
return handler;
|
||||
},
|
||||
|
||||
deleteContentType(uid) {
|
||||
if (!this.contentTypes.has(uid)) {
|
||||
throw new Error('contentType.notFound');
|
||||
}
|
||||
|
||||
this.components.forEach(compo => {
|
||||
compo.removeContentType(uid);
|
||||
});
|
||||
|
||||
this.contentTypes.forEach(ct => {
|
||||
ct.removeContentType(uid);
|
||||
});
|
||||
|
||||
// TODO: clear api when a contentType is deleted
|
||||
return this.contentTypes.get(uid).delete();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -78,6 +78,21 @@ module.exports = function createSchemaHandler(infos) {
|
||||
return this;
|
||||
},
|
||||
|
||||
removeContentType(uid) {
|
||||
const { attributes } = state.schema;
|
||||
|
||||
Object.keys(attributes).forEach(key => {
|
||||
const attr = attributes[key];
|
||||
const target = attr.model || attr.collection;
|
||||
|
||||
if (target === uid) {
|
||||
this.unset(['attributes', key]);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// utils
|
||||
removeComponent(uid) {
|
||||
const { attributes } = state.schema;
|
||||
|
Loading…
x
Reference in New Issue
Block a user