createComponent

This commit is contained in:
Alexandre Bodin 2019-11-18 17:37:52 +01:00
parent 6b9ca4f794
commit ca3113ffb9
2 changed files with 91 additions and 79 deletions

View File

@ -1,6 +1,5 @@
'use strict'; 'use strict';
const path = require('path');
const _ = require('lodash'); const _ = require('lodash');
const { const {
@ -65,48 +64,14 @@ module.exports = {
return ctx.send({ error: 'component.alreadyExists' }, 400); return ctx.send({ error: 'component.alreadyExists' }, 400);
} }
const manager = createSchemaManager({ strapi.reload.isWatching = false;
components: Object.keys(strapi.components).map(key => {
const compo = strapi.components[key];
return {
uid: compo.uid,
filename: compo.__filename__,
dir: path.join(strapi.dir, 'components'),
schema: compo.__schema__,
};
}),
contentTypes: Object.keys(strapi.contentTypes).map(key => {
const contentType = strapi.contentTypes[key];
let dir;
if (contentType.plugin) {
dir = `./extensions/${contentType.plugin}/models`;
} else {
dir = `./api/${contentType.apiName}/models`;
}
return {
uid: contentType.uid,
filename: contentType.__filename__,
dir: path.join(strapi.dir, dir),
schema: contentType.__schema__,
};
}),
});
const manager = createSchemaManager();
await manager.edit(ctx => { await manager.edit(ctx => {
ctx.createComponent(uid, body.component); ctx.createComponent(uid, body.component);
}); });
// strapi.reload.isWatching = false; strapi.reload();
// const newComponent = await componentService.createComponent({
// uid,
// infos: body.component,
// });
// strapi.reload();
ctx.send({ data: uid }, 201); ctx.send({ data: uid }, 201);
}, },

View File

@ -9,7 +9,7 @@ const pluralize = require('pluralize');
const { convertAttributes } = require('../../utils/attributes'); const { convertAttributes } = require('../../utils/attributes');
const { nameToSlug, nameToCollectionName } = require('../../utils/helpers'); const { nameToSlug, nameToCollectionName } = require('../../utils/helpers');
const createSchema = infos => { const createSchemaHandler = infos => {
const uid = infos.uid; const uid = infos.uid;
const dir = infos.dir; const dir = infos.dir;
const filename = infos.filename; const filename = infos.filename;
@ -50,23 +50,33 @@ const createSchema = infos => {
return this; return this;
}, },
flush() { async flush() {
if (modified === true) { if (modified === true) {
return fse.writeJSON(path.join(dir, filename), schema, { spaces: 2 }); const filePath = path.join(dir, filename);
await fse.ensureFile(filePath);
return fse.writeJSON(filePath, schema, { spaces: 2 });
} }
return Promise.resolve(); return Promise.resolve();
}, },
rollback() {
async rollback() {
const filePath = path.join(dir, filename);
// it is a creating // it is a creating
if (!uid) { if (!uid) {
return fse.remove(path.join(dir, filename)); await fse.remove(filePath);
const list = await fse.readdir(dir);
if (list.length === 0) {
await fse.remove(dir);
}
return;
} }
if (modified === true) { if (modified === true) {
return fse.writeJSON(path.join(dir, filename), initialSchema, { await fse.ensureFile(filePath);
spaces: 2, return fse.writeJSON(filePath, initialSchema, { spaces: 2 });
});
} }
return Promise.resolve(); return Promise.resolve();
@ -80,24 +90,20 @@ const createTransaction = ({ components, contentTypes }) => {
// init temporary ContentTypes: // init temporary ContentTypes:
Object.keys(contentTypes).forEach(key => { Object.keys(contentTypes).forEach(key => {
tmpContentTypes.set(key, createSchema(contentTypes[key])); tmpContentTypes.set(key, createSchemaHandler(contentTypes[key]));
}); });
// init temporary components: // init temporary components:
Object.keys(components).forEach(key => { Object.keys(components).forEach(key => {
tmpComponents.set(key, createSchema(components[key])); tmpComponents.set(key, createSchemaHandler(components[key]));
}); });
const ctx = { const ctx = {
get components() { get components() {
return Array.from(tmpComponents.values()); return tmpComponents;
}, },
get contentTypes() { get contentTypes() {
return Array.from(tmpComponents.values()); return tmpComponents;
},
get allSchemas() {
return [...this.components, ...this.contentTypes];
}, },
/** /**
@ -118,7 +124,12 @@ const createTransaction = ({ components, contentTypes }) => {
attributes, attributes,
} = infos; } = infos;
const componentSchema = { const handler = createSchemaHandler({
dir: path.join(strapi.dir, 'components', nameToSlug(category)),
filename: `${nameToSlug(name)}.json`,
});
handler.schema = {
info: { info: {
name, name,
description, description,
@ -133,35 +144,62 @@ const createTransaction = ({ components, contentTypes }) => {
attributes: convertAttributes(attributes), attributes: convertAttributes(attributes),
}; };
const schema = createSchema({ tmpComponents.set(uid, handler);
dir: path.join(strapi.dir, 'components', nameToSlug(category)),
filename: `${nameToSlug(name)}.json`,
scehma: componentSchema,
});
tmpComponents.set(uid, schema); return this;
}, },
flush() { flush() {
const flushOps = this.allSchemas.map(schema => { return Promise.all(
return schema.flush(); [
}); ...Array.from(tmpComponents.values()),
...Array.from(tmpContentTypes.values()),
return Promise.all(flushOps); ].map(schema => schema.flush())
);
}, },
rollback() { rollback() {
const rollbackOps = this.allSchemas.map(schema => { return Promise.all(
return schema.rollback(); [
}); ...Array.from(tmpComponents.values()),
...Array.from(tmpContentTypes.values()),
return Promise.all(rollbackOps); ].map(schema => schema.rollback())
);
}, },
}; };
return ctx; return ctx;
}; };
module.exports = function createSchemasManager({ components, contentTypes }) { module.exports = function createSchemasManager() {
const components = Object.keys(strapi.components).map(key => {
const compo = strapi.components[key];
return {
uid: compo.uid,
filename: compo.__filename__,
dir: path.join(strapi.dir, 'components'),
schema: compo.__schema__,
};
});
const contentTypes = Object.keys(strapi.contentTypes).map(key => {
const contentType = strapi.contentTypes[key];
let dir;
if (contentType.plugin) {
dir = `./extensions/${contentType.plugin}/models`;
} else {
dir = `./api/${contentType.apiName}/models`;
}
return {
uid: contentType.uid,
filename: contentType.__filename__,
dir: path.join(strapi.dir, dir),
schema: contentType.__schema__,
};
});
return { return {
async edit(editorFn) { async edit(editorFn) {
const trx = createTransaction({ const trx = createTransaction({
@ -169,13 +207,22 @@ module.exports = function createSchemasManager({ components, contentTypes }) {
contentTypes, contentTypes,
}); });
try {
await editorFn(trx); await editorFn(trx);
await trx.flush();
} catch (error) { await trx
await trx.rollback(); .flush()
throw error; .catch(error => {
} console.error('Error writing schema files', error);
return trx.rollback();
})
.catch(error => {
console.error(
'Error rolling back schema files. You might need to fix your files manually',
error
);
throw new Error('Invalid schema edition');
});
}, },
}; };
}; };