Handle switching between single type and collection type. This rebuilds the api entierly

Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
Alexandre Bodin 2020-02-10 22:44:50 +01:00
parent 9b415eda0f
commit fc8d72baaa
5 changed files with 53 additions and 16 deletions

View File

@ -1,4 +1,7 @@
{
"kind": "singleType",
"connection": "default",
"collectionName": "homepages",
"info": {
"name": "Homepage"
},
@ -10,8 +13,5 @@
"title": {
"type": "string"
}
},
"connection": "default",
"kind": "singleType",
"collectionName": "homepages"
}
}

View File

@ -5,7 +5,7 @@ const pluralize = require('pluralize');
const generator = require('strapi-generate');
const createBuilder = require('./schema-builder');
const apiCleaner = require('./clear-api');
const apiHandler = require('./api-handler');
const {
formatAttributes,
replaceTemporaryUIDs,
@ -34,7 +34,7 @@ const formatContentType = contentType => {
};
/**
* Creates a component and handle the nested components sent with it
* Creates a content type and handle the nested components sent with it
* @param {Object} params params object
* @param {Object} params.contentType Main component to create
* @param {Array<Object>} params.components List of nested components to created or edit
@ -113,10 +113,12 @@ const generateAPI = ({ name, kind = 'collectionType' }) => {
const editContentType = async (uid, { contentType, components = [] }) => {
const builder = createBuilder();
const previousKind = builder.contentTypes.get(uid).schema.kind;
const uidMap = builder.createNewComponentUIDMap(components);
const replaceTmpUIDs = replaceTemporaryUIDs(uidMap);
const updatedComponent = builder.editContentType({
const updatedContentType = builder.editContentType({
uid,
...replaceTmpUIDs(contentType),
});
@ -129,8 +131,31 @@ const editContentType = async (uid, { contentType, components = [] }) => {
return builder.editComponent(replaceTmpUIDs(component));
});
const newKind = updatedContentType.schema.kind;
if (newKind !== previousKind) {
await apiHandler.backup(uid);
try {
await apiHandler.clear(uid);
// generate new api squeleton
await generateAPI({
name: updatedContentType.schema.info.name,
kind: updatedContentType.schema.kind,
});
await builder.writeFiles();
} catch (error) {
strapi.log.error(error);
await apiHandler.rollback(uid);
}
return updatedContentType;
}
await builder.writeFiles();
return updatedComponent;
return updatedContentType;
};
/**
@ -141,15 +166,15 @@ const deleteContentType = async uid => {
const builder = createBuilder();
// make a backup
await apiCleaner.backup(uid);
await apiHandler.backup(uid);
const component = builder.deleteContentType(uid);
try {
await builder.writeFiles();
await apiCleaner.clear(uid);
await apiHandler.clear(uid);
} catch (error) {
await apiCleaner.rollback(uid);
await apiHandler.rollback(uid);
}
return component;

View File

@ -78,6 +78,8 @@ async function rollback(uid) {
* @param {string} baseName
*/
const createDeleteApiFunction = baseName => {
const startWithBaseName = startWithName(baseName + '.');
/**
* Delets a file in an api.
* Will only update routes.json instead of deleting it if other routes are present
@ -85,7 +87,6 @@ const createDeleteApiFunction = baseName => {
*/
return async filePath => {
const fileName = path.basename(filePath);
const startWithBaseName = startWithName(baseName + '.');
if (startWithBaseName(fileName)) return fse.remove(filePath);

View File

@ -179,7 +179,8 @@ module.exports = function createComponentBuilder() {
this.unsetRelation(oldAttribute);
}
newAttribute.autoPopulate = newAttribute.autoPopulate || oldAttribute.autoPopulate;
newAttribute.autoPopulate =
newAttribute.autoPopulate || oldAttribute.autoPopulate;
return this.setRelation({
key,
@ -204,8 +205,6 @@ module.exports = function createComponentBuilder() {
}
});
// TODO: handle kind change => update routes.json file somehow
contentType
.set('connection', infos.connection)
.set('collectionName', infos.collectionName)

View File

@ -213,7 +213,19 @@ module.exports = function createSchemaHandler(infos) {
}
if (modified === true) {
await fse.ensureFile(filePath);
await fse.writeJSON(filePath, state.schema, { spaces: 2 });
await fse.writeJSON(
filePath,
{
kind: state.schema.kind,
connection: state.schema.connection,
collectionName: state.schema.collectionName,
info: state.schema.info,
options: state.schema.options,
attributes: state.schema.attributes,
},
{ spaces: 2 }
);
// remove from oldPath
if (initialPath !== filePath) {