mirror of
https://github.com/strapi/strapi.git
synced 2025-11-09 22:59:14 +00:00
Handle directory change
This commit is contained in:
parent
1605997045
commit
ca10e972e2
@ -32,51 +32,6 @@ const formatComponent = component => {
|
||||
};
|
||||
};
|
||||
|
||||
// /**
|
||||
// * Updates a component schema file
|
||||
// * @param {Object} component
|
||||
// * @param {Object} infos
|
||||
// */
|
||||
// async function updateComponent({ component, infos }) {
|
||||
// const { uid, __schema__: oldSchema } = component;
|
||||
|
||||
// // don't update collectionName if not provided
|
||||
// const updatedSchema = {
|
||||
// ...oldSchema,
|
||||
// connection: infos.connection || oldSchema.connection,
|
||||
// collectionName: infos.collectionName || oldSchema.collectionName,
|
||||
// info: {
|
||||
// name: infos.name || oldSchema.info.name,
|
||||
// icon: infos.icon || oldSchema.info.icon,
|
||||
// description: infos.description || oldSchema.info.description,
|
||||
// },
|
||||
// attributes: convertAttributes(infos.attributes),
|
||||
// };
|
||||
|
||||
// await editSchema({ uid, schema: updatedSchema });
|
||||
|
||||
// if (component.category !== infos.category) {
|
||||
// const oldDir = path.join(strapi.dir, 'components', component.category);
|
||||
// const newDir = path.join(strapi.dir, 'components', infos.category);
|
||||
|
||||
// await fse.move(
|
||||
// path.join(oldDir, component.__filename__),
|
||||
// path.join(newDir, component.__filename__)
|
||||
// );
|
||||
|
||||
// const list = await fse.readdir(oldDir);
|
||||
// if (list.length === 0) {
|
||||
// await fse.remove(oldDir);
|
||||
// }
|
||||
|
||||
// return {
|
||||
// uid: `${infos.category}.${component.modelName}`,
|
||||
// };
|
||||
// }
|
||||
|
||||
// return { uid };
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns a uid from a string
|
||||
* @param {string} str - string to slugify
|
||||
@ -183,7 +138,7 @@ const updateComponentInModels = (oldUID, newUID) => {
|
||||
* @param {Object} params.component Main component to create
|
||||
* @param {Array<Object>} params.components List of nested components to created or edit
|
||||
*/
|
||||
const createComponent = ({ component, components }) => {
|
||||
const createComponent = ({ component, components = [] }) => {
|
||||
const componentsToCreate = components.filter(compo => !_.has(compo, 'uid'));
|
||||
const componentsToEdit = components.filter(compo => _.has(compo, 'uid'));
|
||||
|
||||
@ -203,7 +158,7 @@ const createComponent = ({ component, components }) => {
|
||||
* @param {Object} params.component Main component to create
|
||||
* @param {Array<Object>} params.components List of nested components to created or edit
|
||||
*/
|
||||
const editComponent = (uid, { component, components }) => {
|
||||
const editComponent = (uid, { component, components = [] }) => {
|
||||
const componentsToCreate = components.filter(compo => !_.has(compo, 'uid'));
|
||||
const componentsToEdit = components.filter(compo => _.has(compo, 'uid'));
|
||||
|
||||
|
||||
@ -42,8 +42,8 @@ module.exports = function createComponentBuilder({ tmpComponents }) {
|
||||
infos.category
|
||||
)}_${nameToCollectionName(pluralize(infos.name))}`;
|
||||
|
||||
handler.uid = uid;
|
||||
handler
|
||||
.setUID(uid)
|
||||
.set('connection', infos.connection || defaultConnection)
|
||||
.set('collectionName', infos.collectionName || defaultCollectionName)
|
||||
.set(['info', 'name'], infos.name)
|
||||
@ -52,6 +52,7 @@ module.exports = function createComponentBuilder({ tmpComponents }) {
|
||||
.set('attributes', convertAttributes(infos.attributes));
|
||||
|
||||
tmpComponents.set(uid, handler);
|
||||
|
||||
return handler;
|
||||
},
|
||||
|
||||
@ -67,9 +68,20 @@ module.exports = function createComponentBuilder({ tmpComponents }) {
|
||||
|
||||
const handler = tmpComponents.get(uid);
|
||||
|
||||
// TODO: handle category change to move the file
|
||||
const [, nameUID] = uid.split('.');
|
||||
|
||||
const newCategory = nameToSlug(infos.category);
|
||||
const newUID = `${newCategory}.${nameUID}`;
|
||||
|
||||
if (newUID !== uid && tmpComponents.has(newUID)) {
|
||||
throw new Error('component.edit.alreadyExists');
|
||||
}
|
||||
|
||||
const newDir = path.join(strapi.dir, 'components', newCategory);
|
||||
|
||||
handler
|
||||
.setUID(newUID)
|
||||
.setDir(newDir)
|
||||
.set('connection', infos.connection)
|
||||
.set('collectionName', infos.collectionName)
|
||||
.set(['info', 'name'], infos.name)
|
||||
@ -77,8 +89,15 @@ module.exports = function createComponentBuilder({ tmpComponents }) {
|
||||
.set(['info', 'description'], infos.description)
|
||||
.set('attributes', convertAttributes(infos.attributes));
|
||||
|
||||
// TODO: update relations if uid changed
|
||||
// TODO: update relations if uid changed
|
||||
if (newUID !== uid) {
|
||||
this.components.forEach(compo => {
|
||||
compo.updateComponent(uid, newUID);
|
||||
});
|
||||
|
||||
this.contentTypes.forEach(ct => {
|
||||
ct.updateComponent(uid, newUID);
|
||||
});
|
||||
}
|
||||
|
||||
return handler;
|
||||
},
|
||||
|
||||
@ -59,14 +59,15 @@ function createSchemaManager() {
|
||||
await builder
|
||||
.flush()
|
||||
.catch(error => {
|
||||
strapi.log.error('Error writing schema files', error);
|
||||
strapi.log.error('Error writing schema files');
|
||||
strapi.log.error(error);
|
||||
return builder.rollback();
|
||||
})
|
||||
.catch(error => {
|
||||
strapi.log.error(
|
||||
'Error rolling back schema files. You might need to fix your files manually',
|
||||
error
|
||||
'Error rolling back schema files. You might need to fix your files manually'
|
||||
);
|
||||
strapi.log.error(error);
|
||||
|
||||
throw new Error('Invalid schema edition');
|
||||
});
|
||||
|
||||
@ -5,48 +5,61 @@ const fse = require('fs-extra');
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = function createSchemaHandler(infos) {
|
||||
const uid = infos.uid;
|
||||
const dir = infos.dir;
|
||||
const filename = infos.filename;
|
||||
const initialState = {
|
||||
uid: infos.uid,
|
||||
dir: infos.dir,
|
||||
filename: infos.filename,
|
||||
schema: infos.schema || {},
|
||||
};
|
||||
|
||||
const state = _.cloneDeep(initialState);
|
||||
|
||||
// always keep it the same to rollback
|
||||
let initialSchema = Object.freeze(infos.schema);
|
||||
let schema = _.cloneDeep(infos.schema) || {};
|
||||
Object.freeze(initialState.schema);
|
||||
|
||||
let modified = false;
|
||||
let deleted = false;
|
||||
|
||||
return {
|
||||
uid,
|
||||
dir,
|
||||
filename,
|
||||
|
||||
// Flag schema for deletion
|
||||
delete() {
|
||||
deleted = true;
|
||||
get uid() {
|
||||
return state.uid;
|
||||
},
|
||||
|
||||
// get a copy of the full schema
|
||||
get schema() {
|
||||
return _.cloneDeep(schema);
|
||||
},
|
||||
|
||||
// set a new schema object
|
||||
set schema(val) {
|
||||
setUID(val) {
|
||||
modified = true;
|
||||
schema = _.cloneDeep(val);
|
||||
|
||||
state.uid = val;
|
||||
return this;
|
||||
},
|
||||
|
||||
setDir(val) {
|
||||
modified = true;
|
||||
|
||||
state.dir = val;
|
||||
return this;
|
||||
},
|
||||
|
||||
get schema() {
|
||||
return _.cloneDeep(state.schema);
|
||||
},
|
||||
|
||||
setSchema(val) {
|
||||
modified = true;
|
||||
|
||||
state.schema = _.cloneDeep(val);
|
||||
return this;
|
||||
},
|
||||
|
||||
// get a particuar path inside the schema
|
||||
get(path) {
|
||||
return _.get(schema, path);
|
||||
return _.get(state.schema, path);
|
||||
},
|
||||
|
||||
// set a particuar path inside the schema
|
||||
set(path, val) {
|
||||
modified = true;
|
||||
|
||||
_.set(schema, path, val || _.get(schema, path));
|
||||
_.set(state.schema, path, val || _.get(state.schema, path));
|
||||
|
||||
return this;
|
||||
},
|
||||
@ -55,15 +68,22 @@ module.exports = function createSchemaHandler(infos) {
|
||||
unset(path) {
|
||||
modified = true;
|
||||
|
||||
_.unset(schema, path);
|
||||
_.unset(state.schema, path);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
delete() {
|
||||
deleted = true;
|
||||
return this;
|
||||
},
|
||||
|
||||
// utils
|
||||
removeComponent(uid) {
|
||||
Object.keys(schema.attributes).forEach(key => {
|
||||
const attr = schema.attributes[key];
|
||||
const { attributes } = state.schema;
|
||||
|
||||
Object.keys(attributes).forEach(key => {
|
||||
const attr = attributes[key];
|
||||
|
||||
if (attr.type === 'component' && attr.component === uid) {
|
||||
this.unset(['attributes', key]);
|
||||
@ -74,7 +94,7 @@ module.exports = function createSchemaHandler(infos) {
|
||||
Array.isArray(attr.components) &&
|
||||
attr.components.includes(uid)
|
||||
) {
|
||||
const updatedComponentList = schema.attributes[key].components.filter(
|
||||
const updatedComponentList = attributes[key].components.filter(
|
||||
val => val !== uid
|
||||
);
|
||||
this.set(['attributes', key, 'components'], updatedComponentList);
|
||||
@ -84,22 +104,58 @@ module.exports = function createSchemaHandler(infos) {
|
||||
return this;
|
||||
},
|
||||
|
||||
updateComponent(uid, newUID) {
|
||||
const { attributes } = state.schema;
|
||||
|
||||
Object.keys(attributes).forEach(key => {
|
||||
const attr = attributes[key];
|
||||
|
||||
if (attr.type === 'component' && attr.component === uid) {
|
||||
this.set(['attributes', key, 'component'], newUID);
|
||||
}
|
||||
|
||||
if (
|
||||
attr.type === 'dynamiczone' &&
|
||||
Array.isArray(attr.components) &&
|
||||
attr.components.includes(uid)
|
||||
) {
|
||||
const updatedComponentList = attributes[key].components.map(val =>
|
||||
val === uid ? newUID : uid
|
||||
);
|
||||
|
||||
this.set(['attributes', key, 'components'], updatedComponentList);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// save the schema to disk
|
||||
async flush() {
|
||||
const filePath = path.join(dir, filename);
|
||||
const initialPath = path.join(initialState.dir, initialState.filename);
|
||||
const filePath = path.join(state.dir, state.filename);
|
||||
|
||||
if (deleted === true) {
|
||||
await fse.remove(filePath);
|
||||
await fse.remove(initialPath);
|
||||
|
||||
const list = await fse.readdir(dir);
|
||||
const list = await fse.readdir(initialState.dir);
|
||||
if (list.length === 0) {
|
||||
await fse.remove(dir);
|
||||
await fse.remove(initialState.dir);
|
||||
}
|
||||
}
|
||||
|
||||
if (modified === true) {
|
||||
await fse.ensureFile(filePath);
|
||||
return fse.writeJSON(filePath, schema, { spaces: 2 });
|
||||
await fse.writeJSON(filePath, state.schema, { spaces: 2 });
|
||||
|
||||
// remove from oldPath
|
||||
if (initialPath !== filePath) {
|
||||
await fse.remove(initialPath);
|
||||
|
||||
const list = await fse.readdir(initialState.dir);
|
||||
if (list.length === 0) {
|
||||
await fse.remove(initialState.dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
@ -107,22 +163,33 @@ module.exports = function createSchemaHandler(infos) {
|
||||
|
||||
// reset the schema to its initial value
|
||||
async rollback() {
|
||||
const filePath = path.join(dir, filename);
|
||||
const initialPath = path.join(initialState.dir, initialState.filename);
|
||||
const filePath = path.join(state.dir, state.filename);
|
||||
|
||||
// it was a creation so it needs to be deleted
|
||||
if (!uid) {
|
||||
if (!initialState.uid) {
|
||||
await fse.remove(filePath);
|
||||
|
||||
const list = await fse.readdir(dir);
|
||||
const list = await fse.readdir(state.dir);
|
||||
if (list.length === 0) {
|
||||
await fse.remove(dir);
|
||||
await fse.remove(state.dir);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (modified === true || deleted === true) {
|
||||
await fse.ensureFile(filePath);
|
||||
return fse.writeJSON(filePath, initialSchema, { spaces: 2 });
|
||||
await fse.ensureFile(initialPath);
|
||||
await fse.writeJSON(initialPath, initialState.schema, { spaces: 2 });
|
||||
|
||||
// remove
|
||||
if (initialPath !== filePath) {
|
||||
await fse.remove(filePath);
|
||||
|
||||
const list = await fse.readdir(state.dir);
|
||||
if (list.length === 0) {
|
||||
await fse.remove(state.dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user