Merge pull request #93 from PhilippPaoli/master
Feat: Import/export for types with populated componentspull/104/head
commit
4581bf1751
15
README.md
15
README.md
|
@ -354,6 +354,21 @@ This property can accept an array of field names from the type. It is meant to s
|
||||||
|
|
||||||
> `required:` NO | `type:` array
|
> `required:` NO | `type:` array
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
|
||||||
|
This property can accept an array of component names from the type. Strapi Components can be included in the export/import process. With "." nested components can also be included in the process.
|
||||||
|
```
|
||||||
|
customTypes: [{
|
||||||
|
configName: 'webhook',
|
||||||
|
queryString: 'webhook',
|
||||||
|
uid: 'name',
|
||||||
|
components: ['ParentComponentA', 'ParentComponentA.ChildComponent', 'ParentComponentB']
|
||||||
|
}],
|
||||||
|
|
||||||
|
###### Key: `components`
|
||||||
|
|
||||||
|
> `required:` NO | `type:` array
|
||||||
|
|
||||||
|
|
||||||
## 🔍 Naming convention
|
## 🔍 Naming convention
|
||||||
All the config files written in the sync directory have the same naming convention. It goes as follows:
|
All the config files written in the sync directory have the same naming convention. It goes as follows:
|
||||||
|
|
|
@ -3,4 +3,5 @@ PORT=1337
|
||||||
APP_KEYS=SIwLyqu+IpSHIuUBDQfPZg==,Nzqbq2C3ATsR19u5XEAJQA==,/Agk5Sn8M4EzfoSiIHcDlQ==,gSxT2T0k2zbQatKXUV0zCA==
|
APP_KEYS=SIwLyqu+IpSHIuUBDQfPZg==,Nzqbq2C3ATsR19u5XEAJQA==,/Agk5Sn8M4EzfoSiIHcDlQ==,gSxT2T0k2zbQatKXUV0zCA==
|
||||||
API_TOKEN_SALT=reQcUBbGXD2KWG2QpRn7DA==
|
API_TOKEN_SALT=reQcUBbGXD2KWG2QpRn7DA==
|
||||||
ADMIN_JWT_SECRET= 69mzgwRGfEBUhPEaas8EBA==
|
ADMIN_JWT_SECRET= 69mzgwRGfEBUhPEaas8EBA==
|
||||||
|
TRANSFER_TOKEN_SALT=/LTsSGpC5afHICjZu0oEuQ==
|
||||||
JWT_SECRET=E0TTVdsr+M/FXAjfrNIgXA==
|
JWT_SECRET=E0TTVdsr+M/FXAjfrNIgXA==
|
||||||
|
|
|
@ -5,4 +5,12 @@ module.exports = ({ env }) => ({
|
||||||
watchIgnoreFiles: [
|
watchIgnoreFiles: [
|
||||||
'**/config/sync/**',
|
'**/config/sync/**',
|
||||||
],
|
],
|
||||||
|
apiToken: {
|
||||||
|
salt: env('API_TOKEN_SALT'),
|
||||||
|
},
|
||||||
|
transfer: {
|
||||||
|
token: {
|
||||||
|
salt: env('TRANSFER_TOKEN_SALT'),
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@ const { logMessage, sanitizeConfig, dynamicSort, noLimit, getCombinedUid, getCom
|
||||||
const { difference, same } = require('../utils/getArrayDiff');
|
const { difference, same } = require('../utils/getArrayDiff');
|
||||||
|
|
||||||
const ConfigType = class ConfigType {
|
const ConfigType = class ConfigType {
|
||||||
constructor({ queryString, configName, uid, jsonFields, relations }) {
|
constructor({ queryString, configName, uid, jsonFields, relations, components }) {
|
||||||
if (!configName) {
|
if (!configName) {
|
||||||
strapi.log.error(logMessage('A config type was registered without a config name.'));
|
strapi.log.error(logMessage('A config type was registered without a config name.'));
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
|
@ -25,6 +25,7 @@ const ConfigType = class ConfigType {
|
||||||
this.configPrefix = configName;
|
this.configPrefix = configName;
|
||||||
this.jsonFields = jsonFields || [];
|
this.jsonFields = jsonFields || [];
|
||||||
this.relations = relations || [];
|
this.relations = relations || [];
|
||||||
|
this.components = components || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,15 +69,11 @@ const ConfigType = class ConfigType {
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all(relations.map(async (relation) => {
|
await Promise.all(relations.map(async (relation) => {
|
||||||
await strapi.query(queryString).delete({
|
await strapi.entityService.delete(queryString, relation.id);
|
||||||
where: { id: relation.id },
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await queryAPI.delete({
|
await strapi.entityService.delete(this.queryString, existingConfig.id);
|
||||||
where: { id: existingConfig.id },
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -89,15 +86,17 @@ const ConfigType = class ConfigType {
|
||||||
|
|
||||||
// Create entity.
|
// Create entity.
|
||||||
this.relations.map(({ relationName }) => delete query[relationName]);
|
this.relations.map(({ relationName }) => delete query[relationName]);
|
||||||
const newEntity = await queryAPI.create({ data: query });
|
const newEntity = await strapi.entityService.create(this.queryString, {
|
||||||
|
data: query,
|
||||||
|
});
|
||||||
|
|
||||||
// Create relation entities.
|
// Create relation entities.
|
||||||
await Promise.all(this.relations.map(async ({ queryString, relationName, parentName }) => {
|
await Promise.all(this.relations.map(async ({ queryString, relationName, parentName }) => {
|
||||||
const relationQueryApi = strapi.query(queryString);
|
|
||||||
|
|
||||||
await Promise.all(configContent[relationName].map(async (relationEntity) => {
|
await Promise.all(configContent[relationName].map(async (relationEntity) => {
|
||||||
const relationQuery = { ...relationEntity, [parentName]: newEntity };
|
const relationQuery = { ...relationEntity, [parentName]: newEntity };
|
||||||
await relationQueryApi.create({ data: relationQuery });
|
await strapi.entityService.create(queryString, {
|
||||||
|
data: relationQuery,
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
} else { // Config does exist in DB --> update config in DB
|
} else { // Config does exist in DB --> update config in DB
|
||||||
|
@ -111,7 +110,16 @@ const ConfigType = class ConfigType {
|
||||||
|
|
||||||
// Update entity.
|
// Update entity.
|
||||||
this.relations.map(({ relationName }) => delete query[relationName]);
|
this.relations.map(({ relationName }) => delete query[relationName]);
|
||||||
const entity = await queryAPI.update({ where: combinedUidWhereFilter, data: query });
|
|
||||||
|
const entity = await queryAPI.findOne({ where: combinedUidWhereFilter });
|
||||||
|
try {
|
||||||
|
await strapi.entityService.update(this.queryString, entity.id, {
|
||||||
|
data: query,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(logMessage(`Use Query Engine API instead of Entity Service API for type ${this.configPrefix}`));
|
||||||
|
await queryAPI.update({ where: combinedUidWhereFilter, data: query });
|
||||||
|
}
|
||||||
|
|
||||||
// Delete/create relations.
|
// Delete/create relations.
|
||||||
await Promise.all(this.relations.map(async ({ queryString, relationName, parentName, relationSortFields }) => {
|
await Promise.all(this.relations.map(async ({ queryString, relationName, parentName, relationSortFields }) => {
|
||||||
|
@ -137,7 +145,7 @@ const ConfigType = class ConfigType {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await Promise.all(configToAdd.map(async (config) => {
|
await Promise.all(configToAdd.map(async (config) => {
|
||||||
await relationQueryApi.create({
|
await strapi.entityService.create(queryString, {
|
||||||
data: { ...config, [parentName]: entity.id },
|
data: { ...config, [parentName]: entity.id },
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
@ -192,7 +200,9 @@ const ConfigType = class ConfigType {
|
||||||
* @returns {object} Object with key value pairs of configs.
|
* @returns {object} Object with key value pairs of configs.
|
||||||
*/
|
*/
|
||||||
getAllFromDatabase = async () => {
|
getAllFromDatabase = async () => {
|
||||||
const AllConfig = await noLimit(strapi.query(this.queryString), {});
|
const AllConfig = await noLimit(strapi.query(this.queryString), {
|
||||||
|
populate: this.components,
|
||||||
|
});
|
||||||
const configs = {};
|
const configs = {};
|
||||||
|
|
||||||
await Promise.all(Object.values(AllConfig).map(async (config) => {
|
await Promise.all(Object.values(AllConfig).map(async (config) => {
|
||||||
|
|
|
@ -47,11 +47,6 @@ const dynamicSort = (property) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const sanitizeConfig = (config, relation, relationSortFields) => {
|
const sanitizeConfig = (config, relation, relationSortFields) => {
|
||||||
delete config._id;
|
|
||||||
delete config.id;
|
|
||||||
delete config.updatedAt;
|
|
||||||
delete config.createdAt;
|
|
||||||
|
|
||||||
if (relation) {
|
if (relation) {
|
||||||
const formattedRelations = [];
|
const formattedRelations = [];
|
||||||
|
|
||||||
|
@ -74,6 +69,20 @@ const sanitizeConfig = (config, relation, relationSortFields) => {
|
||||||
config[relation] = formattedRelations;
|
config[relation] = formattedRelations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const recursiveSanitizeConfig = (recursivedSanitizedConfig) => {
|
||||||
|
delete recursivedSanitizedConfig._id;
|
||||||
|
delete recursivedSanitizedConfig.id;
|
||||||
|
delete recursivedSanitizedConfig.updatedAt;
|
||||||
|
delete recursivedSanitizedConfig.createdAt;
|
||||||
|
|
||||||
|
Object.keys(recursivedSanitizedConfig).map((key, index) => {
|
||||||
|
if (recursivedSanitizedConfig[key] && typeof recursivedSanitizedConfig[key] === "object") {
|
||||||
|
recursiveSanitizeConfig(recursivedSanitizedConfig[key]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
recursiveSanitizeConfig(config);
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue