mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-03 19:36:20 +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