feat: Abstract types

pull/25/head
Boaz Poolman 2021-10-14 16:37:32 +02:00
parent 8c3c2e7e3f
commit 75711f7da4
9 changed files with 251 additions and 569 deletions

View File

@ -1,127 +0,0 @@
'use strict';
const coreStoreQueryString = 'core_store';
const configPrefix = 'core-store'; // Should be the same as the filename.
const difference = require('../utils/getObjectDiff');
/**
* Import/Export for core-store configs.
*/
module.exports = {
/**
* Export all core-store config to files.
*
* @returns {void}
*/
exportAll: async () => {
const formattedDiff = {
fileConfig: {},
databaseConfig: {},
diff: {},
};
const fileConfig = await strapi.plugins['config-sync'].services.main.getAllConfigFromFiles(configPrefix);
const databaseConfig = await strapi.plugins['config-sync'].services.main.getAllConfigFromDatabase(configPrefix);
const diff = difference(databaseConfig, fileConfig);
formattedDiff.diff = diff;
Object.keys(diff).map((changedConfigName) => {
formattedDiff.fileConfig[changedConfigName] = fileConfig[changedConfigName];
formattedDiff.databaseConfig[changedConfigName] = databaseConfig[changedConfigName];
});
await Promise.all(Object.entries(diff).map(async ([configName, config]) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configName}`);
if (shouldExclude) return;
const currentConfig = formattedDiff.databaseConfig[configName];
if (
!currentConfig
&& formattedDiff.fileConfig[configName]
) {
await strapi.plugins['config-sync'].services.main.deleteConfigFile(configName);
} else {
await strapi.plugins['config-sync'].services.main.writeConfigFile(configPrefix, currentConfig.key.replace('::', '##'), currentConfig);
}
}));
},
/**
* Import a single core-store config file into the db.
*
* @param {string} configName - The name of the config file.
* @param {string} configContent - The JSON content of the config file.
* @returns {void}
*/
importSingle: async (configName, configContent) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configPrefix}.${configName}`);
if (shouldExclude) return;
const coreStoreAPI = strapi.query(coreStoreQueryString);
const configExists = await coreStoreAPI
.findOne({ key: configName });
if (configExists && configContent === null) {
await coreStoreAPI.delete({ key: configName });
return;
}
const { value, ...fileContent } = configContent;
if (!configExists) {
await coreStoreAPI.create({ value: JSON.stringify(value), ...fileContent });
} else {
await coreStoreAPI.update({ key: configName }, { value: JSON.stringify(value), ...fileContent });
}
},
/**
* Get all core-store config from the db.
*
* @returns {object} Object with key value pairs of configs.
*/
getAllFromDatabase: async () => {
const coreStore = await strapi.query(coreStoreQueryString).find({ _limit: -1 });
const configs = {};
Object.values(coreStore).map(({ id, value, key, ...config }) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configPrefix}.${key}`);
if (shouldExclude) return;
// Do not export the _id field, as it is immutable
delete config._id;
configs[`${configPrefix}.${key}`] = { key, value: JSON.parse(value), ...config };
});
return configs;
},
/**
* Import all core-store config files into the db.
*
* @returns {void}
*/
importAll: async () => {
// The main.importAllConfig service will loop the core-store.importSingle service.
await strapi.plugins['config-sync'].services.main.importAllConfig(configPrefix);
},
/**
* Export a single core-store config to a file.
*
* @param {string} configName - The name of the config file.
* @returns {void}
*/
exportSingle: async (configName) => {
// @TODO: write export for a single core-store config.
},
};

View File

@ -1,138 +0,0 @@
'use strict';
const { sanitizeEntity } = require('@strapi/utils');
// const i18nQueryString = 'i18n_locales';
const configPrefix = 'i18n-locale'; // Should be the same as the filename.
const difference = require('../utils/getObjectDiff');
/**
* Import/Export for i18n-locale configs.
*/
module.exports = {
/**
* Export all i18n-locale config to files.
*
* @returns {void}
*/
exportAll: async () => {
const formattedDiff = {
fileConfig: {},
databaseConfig: {},
diff: {},
};
const fileConfig = await strapi.plugins['config-sync'].services.main.getAllConfigFromFiles(configPrefix);
const databaseConfig = await strapi.plugins['config-sync'].services.main.getAllConfigFromDatabase(configPrefix);
const diff = difference(databaseConfig, fileConfig);
formattedDiff.diff = diff;
Object.keys(diff).map((changedConfigName) => {
formattedDiff.fileConfig[changedConfigName] = fileConfig[changedConfigName];
formattedDiff.databaseConfig[changedConfigName] = databaseConfig[changedConfigName];
});
await Promise.all(Object.entries(diff).map(async ([configName, config]) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configName}`);
if (shouldExclude) return;
const currentConfig = formattedDiff.databaseConfig[configName];
if (
!currentConfig
&& formattedDiff.fileConfig[configName]
) {
await strapi.plugins['config-sync'].services.main.deleteConfigFile(configName);
} else {
await strapi.plugins['config-sync'].services.main.writeConfigFile(configPrefix, currentConfig.code, currentConfig);
}
}));
},
/**
* Import a single i18n-locale config file into the db.
*
* @param {string} configName - The name of the config file.
* @param {string} configContent - The JSON content of the config file.
* @returns {void}
*/
importSingle: async (configName, configContent) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configPrefix}.${configName}`);
if (shouldExclude) return;
const service = strapi.plugins['i18n'].services.locales;
const locale = await service.findByCode(configName);
if (locale && configContent === null) {
await service.deleteFn(locale);
return;
}
if (!locale) {
await service.create(configContent);
} else {
await service.update({ id: locale.id }, configContent);
}
},
/**
* Get all i18n-locale config from the db.
*
* @returns {object} Object with code value pairs of configs.
*/
getAllFromDatabase: async () => {
const service = strapi.plugins['i18n'].services.locales;
const locales = await service.find({ _limit: -1 });
const configs = {};
const sanitizedLocalesArray = locales.map((locale) => {
sanitizeEntity(locale, {
model: strapi.plugins['i18n'].models.locale,
});
});
Object.values(sanitizedLocalesArray).map(({ id, code, ...config }) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configPrefix}.${code}`);
if (shouldExclude) return;
// Do not export timestamp fields
delete config.created_at;
delete config.updated_at;
// Do not export the _id field, as it is immutable
delete config._id;
configs[`${configPrefix}.${code}`] = { code, ...config };
});
return configs;
},
/**
* Import all i18n-locale config files into the db.
*
* @returns {void}
*/
importAll: async () => {
// The main.importAllConfig service will loop the i18n-locale.importSingle service.
await strapi.plugins['config-sync'].services.main.importAllConfig(configPrefix);
},
/**
* Export a single i18n-locale config to a file.
*
* @param {string} configName - The name of the config file.
* @returns {void}
*/
exportSingle: async (configName) => {
// @TODO: write export for a single i18n-locale config.
},
};

View File

@ -1,15 +1,9 @@
'use strict'; 'use strict';
const main = require('./main'); const main = require('./main');
const coreStore = require('./core-store'); const type = require('./type');
const i18nLocale = require('./i18n-locale');
const rolePermissions = require('./role-permissions');
const webhooks = require('./webhooks');
module.exports = { module.exports = {
type,
main, main,
'role-permissions': rolePermissions,
'i18n-locale': i18nLocale,
'core-store': coreStore,
webhooks,
}; };

View File

@ -2,13 +2,14 @@
const fs = require('fs'); const fs = require('fs');
const util = require('util'); const util = require('util');
const types = require('../types');
const difference = require('../utils/getObjectDiff'); const difference = require('../utils/getObjectDiff');
/** /**
* Main services for config import/export. * Main services for config import/export.
*/ */
module.exports = { module.exports = () => ({
/** /**
* Write a single config file. * Write a single config file.
* *
@ -19,20 +20,20 @@ module.exports = {
*/ */
writeConfigFile: async (configType, configName, fileContents) => { writeConfigFile: async (configType, configName, fileContents) => {
// Check if the config should be excluded. // Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configType}.${configName}`); const shouldExclude = strapi.config.get('plugin.config-sync.exclude').includes(`${configType}.${configName}`);
if (shouldExclude) return; if (shouldExclude) return;
// Check if the JSON content should be minified. // Check if the JSON content should be minified.
const json = !strapi.plugins['config-sync'].config.minify const json = !strapi.config.get('plugin.config-sync').minify
? JSON.stringify(fileContents, null, 2) ? JSON.stringify(fileContents, null, 2)
: JSON.stringify(fileContents); : JSON.stringify(fileContents);
if (!fs.existsSync(strapi.plugins['config-sync'].config.destination)) { if (!fs.existsSync(strapi.config.get('plugin.config-sync').destination)) {
fs.mkdirSync(strapi.plugins['config-sync'].config.destination, { recursive: true }); fs.mkdirSync(strapi.config.get('plugin.config-sync').destination, { recursive: true });
} }
const writeFile = util.promisify(fs.writeFile); const writeFile = util.promisify(fs.writeFile);
await writeFile(`${strapi.plugins['config-sync'].config.destination}${configType}.${configName}.json`, json) await writeFile(`${strapi.config.get('plugin.config-sync').destination}${configType}.${configName}.json`, json)
.then(() => { .then(() => {
// @TODO: // @TODO:
// Add logging for successfull config export. // Add logging for successfull config export.
@ -51,10 +52,10 @@ module.exports = {
*/ */
deleteConfigFile: async (configName) => { deleteConfigFile: async (configName) => {
// Check if the config should be excluded. // Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configName}`); const shouldExclude = strapi.config.get('plugin.config-sync.exclude').includes(`${configName}`);
if (shouldExclude) return; if (shouldExclude) return;
fs.unlinkSync(`${strapi.plugins['config-sync'].config.destination}${configName}.json`); fs.unlinkSync(`${strapi.config.get('plugin.config-sync').destination}${configName}.json`);
}, },
/** /**
@ -66,7 +67,7 @@ module.exports = {
*/ */
readConfigFile: async (configType, configName) => { readConfigFile: async (configType, configName) => {
const readFile = util.promisify(fs.readFile); const readFile = util.promisify(fs.readFile);
return readFile(`${strapi.plugins['config-sync'].config.destination}${configType}.${configName}.json`) return readFile(`${strapi.config.get('plugin.config-sync').destination}${configType}.${configName}.json`)
.then((data) => { .then((data) => {
return JSON.parse(data); return JSON.parse(data);
}) })
@ -83,11 +84,11 @@ module.exports = {
* @returns {object} Object with key value pairs of configs. * @returns {object} Object with key value pairs of configs.
*/ */
getAllConfigFromFiles: async (configType = null) => { getAllConfigFromFiles: async (configType = null) => {
if (!fs.existsSync(strapi.plugins['config-sync'].config.destination)) { if (!fs.existsSync(strapi.config.get('plugin.config-sync').destination)) {
return {}; return {};
} }
const configFiles = fs.readdirSync(strapi.plugins['config-sync'].config.destination); const configFiles = fs.readdirSync(strapi.config.get('plugin.config-sync').destination);
const getConfigs = async () => { const getConfigs = async () => {
const fileConfigs = {}; const fileConfigs = {};
@ -98,13 +99,13 @@ module.exports = {
if ( if (
configType && configType !== type configType && configType !== type
|| !strapi.plugins['config-sync'].config.include.includes(type) || !strapi.config.get('plugin.config-sync.include').includes(type)
|| strapi.plugins['config-sync'].config.exclude.includes(`${type}.${name}`) || strapi.config.get('plugin.config-sync.exclude').includes(`${type}.${name}`)
) { ) {
return; return;
} }
const fileContents = await strapi.plugins['config-sync'].services.main.readConfigFile(type, name); const fileContents = await strapi.plugin('config-sync').service('main').readConfigFile(type, name);
fileConfigs[`${type}.${name}`] = fileContents; fileConfigs[`${type}.${name}`] = fileContents;
})); }));
@ -124,12 +125,12 @@ module.exports = {
const getConfigs = async () => { const getConfigs = async () => {
let databaseConfigs = {}; let databaseConfigs = {};
await Promise.all(strapi.plugins['config-sync'].config.include.map(async (type) => { await Promise.all(strapi.config.get('plugin.config-sync.include').map(async (type) => {
if (configType && configType !== type) { if (configType && configType !== type) {
return; return;
} }
const config = await strapi.plugins['config-sync'].services[type].getAllFromDatabase(); const config = await types[type].getAllFromDatabase();
databaseConfigs = Object.assign(config, databaseConfigs); databaseConfigs = Object.assign(config, databaseConfigs);
})); }));
@ -146,8 +147,8 @@ module.exports = {
* @returns {void} * @returns {void}
*/ */
importAllConfig: async (configType = null) => { importAllConfig: async (configType = null) => {
const fileConfig = await strapi.plugins['config-sync'].services.main.getAllConfigFromFiles(); const fileConfig = await strapi.plugin('config-sync').service('main').getAllConfigFromFiles();
const databaseConfig = await strapi.plugins['config-sync'].services.main.getAllConfigFromDatabase(); const databaseConfig = await strapi.plugin('config-sync').service('main').getAllConfigFromDatabase();
const diff = difference(databaseConfig, fileConfig); const diff = difference(databaseConfig, fileConfig);
@ -159,7 +160,7 @@ module.exports = {
return; return;
} }
strapi.plugins['config-sync'].services.main.importSingleConfig(type, name); strapi.plugin('config-sync').service('main').importSingleConfig(type, name);
}); });
}, },
@ -170,12 +171,12 @@ module.exports = {
* @returns {void} * @returns {void}
*/ */
exportAllConfig: async (configType = null) => { exportAllConfig: async (configType = null) => {
await Promise.all(strapi.plugins['config-sync'].config.include.map(async (type) => { await Promise.all(strapi.config.get('plugin.config-sync.include').map(async (type) => {
if (configType && configType !== type) { if (configType && configType !== type) {
return; return;
} }
await strapi.plugins['config-sync'].services[type].exportAll(); await types[type].exportAll();
})); }));
}, },
@ -188,12 +189,12 @@ module.exports = {
*/ */
importSingleConfig: async (configType, configName) => { importSingleConfig: async (configType, configName) => {
// Check if the config should be excluded. // Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configType}.${configName}`); const shouldExclude = strapi.config.get('plugin.config-sync.exclude').includes(`${configType}.${configName}`);
if (shouldExclude) return; if (shouldExclude) return;
const fileContents = await strapi.plugins['config-sync'].services.main.readConfigFile(configType, configName); const fileContents = await strapi.plugin('config-sync').service('main').readConfigFile(configType, configName);
await strapi.plugins['config-sync'].services[configType].importSingle(configName, fileContents); await types[configType].importSingle(configName, fileContents);
}, },
/** /**
@ -206,4 +207,4 @@ module.exports = {
exportSingleConfig: async (configType, configName) => { exportSingleConfig: async (configType, configName) => {
}, },
}; });

View File

@ -1,150 +0,0 @@
'use strict';
const { sanitizeEntity } = require('@strapi/utils');
const difference = require('../utils/getObjectDiff');
const configPrefix = 'role-permissions'; // Should be the same as the filename.
/**
* Import/Export for role-permissions configs.
*/
module.exports = {
/**
* Export all role-permissions config to files.
*
* @returns {void}
*/
exportAll: async () => {
const formattedDiff = {
fileConfig: {},
databaseConfig: {},
diff: {},
};
const fileConfig = await strapi.plugins['config-sync'].services.main.getAllConfigFromFiles(configPrefix);
const databaseConfig = await strapi.plugins['config-sync'].services.main.getAllConfigFromDatabase(configPrefix);
const diff = difference(databaseConfig, fileConfig);
formattedDiff.diff = diff;
Object.keys(diff).map((changedConfigName) => {
formattedDiff.fileConfig[changedConfigName] = fileConfig[changedConfigName];
formattedDiff.databaseConfig[changedConfigName] = databaseConfig[changedConfigName];
});
await Promise.all(Object.entries(diff).map(async ([configName, config]) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configName}`);
if (shouldExclude) return;
const currentConfig = formattedDiff.databaseConfig[configName];
if (
!currentConfig
&& formattedDiff.fileConfig[configName]
) {
await strapi.plugins['config-sync'].services.main.deleteConfigFile(configName);
} else {
await strapi.plugins['config-sync'].services.main.writeConfigFile(configPrefix, currentConfig.type, currentConfig);
}
}));
},
/**
* Import a single role-permissions config file into the db.
*
* @param {string} configName - The name of the config file.
* @param {string} configContent - The JSON content of the config file.
* @returns {void}
*/
importSingle: async (configName, configContent) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configPrefix}.${configName}`);
if (shouldExclude) return;
const service = strapi.plugins['users-permissions'].services.userspermissions;
const role = await strapi
.query('role', 'users-permissions')
.findOne({ type: configName });
if (role && configContent === null) {
const publicRole = await strapi.query('role', 'users-permissions').findOne({ type: 'public' });
const publicRoleID = publicRole.id;
await service.deleteRole(role.id, publicRoleID);
return;
}
const users = role ? role.users : [];
configContent.users = users;
if (!role) {
await service.createRole(configContent);
} else {
await service.updateRole(role.id, configContent);
}
},
/**
* Get all role-permissions config from the db.
*
* @returns {object} Object with key value pairs of configs.
*/
getAllFromDatabase: async () => {
const service = strapi.plugins['users-permissions'].services.userspermissions;
const [roles, plugins] = await Promise.all([
service.getRoles(),
service.getPlugins(),
]);
const rolesWithPermissions = await Promise.all(
roles.map(async (role) => service.getRole(role.id, plugins))
);
const sanitizedRolesArray = rolesWithPermissions.map((role) => {
sanitizeEntity(role, {
model: strapi.plugins['users-permissions'].models.role,
});
});
const configs = {};
Object.values(sanitizedRolesArray).map(({ id, ...config }) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configPrefix}.${config.type}`);
if (shouldExclude) return;
// Do not export the _id field, as it is immutable
delete config._id;
configs[`${configPrefix}.${config.type}`] = config;
});
return configs;
},
/**
* Import all role-permissions config files into the db.
*
* @returns {void}
*/
importAll: async () => {
// The main.importAllConfig service will loop the role-permissions.importSingle service.
await strapi.plugins['config-sync'].services.main.importAllConfig(configPrefix);
},
/**
* Export a single role-permissions config to a file.
*
* @param {string} configName - The name of the config file.
* @returns {void}
*/
exportSingle: async (configName) => {
// @TODO: write export for a single role-permissions config.
},
};

137
server/services/type.js Normal file
View File

@ -0,0 +1,137 @@
const { logMessage } = require('../utils');
const difference = require('../utils/getObjectDiff');
const ConfigType = class ConfigType {
constructor(queryString, configPrefix, uid, fieldsToStringify) {
if (!queryString) {
strapi.log.error(logMessage('Query string is missing for ConfigType'));
}
this.queryString = queryString;
this.configPrefix = configPrefix;
this.uid = uid;
this.fieldsToStringify = fieldsToStringify || [];
}
/**
* Export all core-store config to files.
*
* @returns {void}
*/
exportAll = async () => {
const formattedDiff = {
fileConfig: {},
databaseConfig: {},
diff: {},
};
const fileConfig = await strapi.plugin('config-sync').service('main').getAllConfigFromFiles(this.configPrefix);
const databaseConfig = await strapi.plugin('config-sync').service('main').getAllConfigFromDatabase(this.configPrefix);
const diff = difference(databaseConfig, fileConfig);
formattedDiff.diff = diff;
Object.keys(diff).map((changedConfigName) => {
formattedDiff.fileConfig[changedConfigName] = fileConfig[changedConfigName];
formattedDiff.databaseConfig[changedConfigName] = databaseConfig[changedConfigName];
});
await Promise.all(Object.entries(diff).map(async ([configName, config]) => {
// Check if the config should be excluded.
const shouldExclude = strapi.config.get('plugin.config-sync.exclude').includes(`${configName}`);
if (shouldExclude) return;
const currentConfig = formattedDiff.databaseConfig[configName];
if (
!currentConfig
&& formattedDiff.fileConfig[configName]
) {
await strapi.plugin('config-sync').service('main').deleteConfigFile(configName);
} else {
await strapi.plugin('config-sync').service('main').writeConfigFile(this.configPrefix, currentConfig[this.uid].replace('::', '##'), currentConfig);
}
}));
}
/**
* Import a single core-store config file into the db.
*
* @param {string} configName - The name of the config file.
* @param {string} configContent - The JSON content of the config file.
* @returns {void}
*/
importSingle = async (configName, configContent) => {
// Check if the config should be excluded.
const shouldExclude = strapi.config.get('plugin.config-sync.exclude').includes(`${this.configPrefix}.${configName}`);
if (shouldExclude) return;
const queryAPI = strapi.query(this.queryString);
const configExists = await queryAPI
.findOne({ [this.uid]: configName });
if (configExists && configContent === null) {
await queryAPI.delete({ where: { [this.uid]: configName } });
return;
}
if (!configExists) {
const query = { ...configContent };
this.fieldsToStringify.map((field) => query[field] = JSON.stringify(configContent[field]));
await queryAPI.create(query);
} else {
const query = { ...configContent };
this.fieldsToStringify.map((field) => query[field] = JSON.stringify(configContent[field]));
await queryAPI.update({ where: { [this.uid]: configName }, data: { ...query } });
}
}
/**
* Get all core-store config from the db.
*
* @returns {object} Object with key value pairs of configs.
*/
getAllFromDatabase = async () => {
const AllConfig = await strapi.query(this.queryString).findMany({ _limit: -1 });
const configs = {};
Object.values(AllConfig).map((config) => {
// Check if the config should be excluded.
const shouldExclude = strapi.config.get('plugin.config-sync.exclude').includes(`${this.configPrefix}.${config[this.uid]}`);
if (shouldExclude) return;
// Do not export the _id field, as it is immutable
delete config._id;
const formattedObject = { ...config };
this.fieldsToStringify.map((field) => formattedObject[field] = JSON.parse(config[field]));
configs[`${this.configPrefix}.${config[this.uid]}`] = formattedObject;
});
return configs;
}
/**
* Import all core-store config files into the db.
*
* @returns {void}
*/
importAll = async () => {
// The main.importAllConfig service will loop the core-store.importSingle service.
await strapi.plugin('config-sync').service('main').importAllConfig(this.configPrefix);
}
/**
* Export a single core-store config to a file.
*
* @param {string} configName - The name of the config file.
* @returns {void}
*/
exportSingle = async (configName) => {
// @TODO: write export for a single core-store config.
}
};
module.exports = ConfigType;

View File

@ -1,121 +0,0 @@
'use strict';
/**
* Import/Export for webhook configs.
*/
const webhookQueryString = 'strapi_webhooks';
const configPrefix = 'webhooks'; // Should be the same as the filename.
const difference = require('../utils/getObjectDiff');
module.exports = {
/**
* Export all webhooks to config files.
*
* @returns {void}
*/
exportAll: async () => {
const formattedDiff = {
fileConfig: {},
databaseConfig: {},
diff: {}
};
const fileConfig = await strapi.plugins['config-sync'].services.main.getAllConfigFromFiles(configPrefix);
const databaseConfig = await strapi.plugins['config-sync'].services.main.getAllConfigFromDatabase(configPrefix);
const diff = difference(databaseConfig, fileConfig);
formattedDiff.diff = diff;
Object.keys(diff).map((changedConfigName) => {
formattedDiff.fileConfig[changedConfigName] = fileConfig[changedConfigName];
formattedDiff.databaseConfig[changedConfigName] = databaseConfig[changedConfigName];
})
await Promise.all(Object.entries(diff).map(async ([configName, config]) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configName}`);
if (shouldExclude) return;
const currentConfig = formattedDiff.databaseConfig[configName];
if (
!currentConfig &&
formattedDiff.fileConfig[configName]
) {
await strapi.plugins['config-sync'].services.main.deleteConfigFile(configName);
} else {
await strapi.plugins['config-sync'].services.main.writeConfigFile(configPrefix, currentConfig.id, currentConfig);
}
}));
},
/**
* Import a single webhook config file into the db.
*
* @param {string} configName - The name of the config file.
* @param {string} configContent - The JSON content of the config file.
* @returns {void}
*/
importSingle: async (configName, configContent) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configPrefix}.${configName}`);
if (shouldExclude) return;
const webhookAPI = strapi.query(webhookQueryString);
const configExists = await webhookAPI.findOne({ id: configName });
if (!configExists) {
await webhookAPI.create(configContent);
} else {
if (configContent === null) {
await webhookAPI.delete({ id: configName });
}
await webhookAPI.update({ id: configName }, configContent);
}
},
/**
* Get all webhook config from the db.
*
* @returns {object} Object with key value pairs of configs.
*/
getAllFromDatabase: async () => {
const webhooks = await strapi.query(webhookQueryString).find({ _limit: -1 });
let configs = {};
Object.values(webhooks).map( (config) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${configPrefix}.${config.id}`);
if (shouldExclude) return;
// Do not export the _id field, as it is immutable
delete config._id;
configs[`${configPrefix}.${config.id}`] = config;
});
return configs;
},
/**
* Import all webhook config files into the db.
*
* @returns {void}
*/
importAll: async () => {
// The main.importAllConfig service will loop the webhooks.importSingle service.
await strapi.plugins['config-sync'].services.main.importAllConfig(configPrefix);
},
/**
* Export a single webhook into a config file.
*
* @param {string} configName - The name of the config file.
* @returns {void}
*/
exportSingle: async (configName) => {
// @TODO: write export for a single webhook config.
},
};

10
server/types/index.js Normal file
View File

@ -0,0 +1,10 @@
'use strict';
const ConfigType = require("../services/type");
const RolePermissionsConfigType = require("./role-permissions");
module.exports = {
'i18n-locale': new ConfigType('plugin::i18n.locale', 'i18n-locale', 'code'),
'core-store': new ConfigType('strapi::core-store', 'core-store', 'key', ['value']),
'role-permissions': new RolePermissionsConfigType('plugin::users-permissions.role', 'role-permissions', 'type'),
};

View File

@ -0,0 +1,76 @@
const ConfigType = require("../services/type");
const RolePermissionsConfigType = class RolePermissionsConfigType extends ConfigType {
/**
* Import a single role-permissions config file into the db.
*
* @param {string} configName - The name of the config file.
* @param {string} configContent - The JSON content of the config file.
* @returns {void}
*/
importSingle = async (configName, configContent) => {
// Check if the config should be excluded.
const shouldExclude = strapi.plugins['config-sync'].config.exclude.includes(`${this.configPrefix}.${configName}`);
if (shouldExclude) return;
const roleService = strapi.plugin('users-permissions').service('role');
const role = await strapi
.query(this.queryString)
.findOne({ where: { type: configName } });
if (role && configContent === null) {
const publicRole = await strapi.query(this.queryString).findOne({ where: { type: 'public' } });
const publicRoleID = publicRole.id;
await roleService.deleteRole(role.id, publicRoleID);
return;
}
const users = role ? role.users : [];
configContent.users = users;
if (!role) {
await roleService.createRole(configContent);
} else {
await roleService.updateRole(role.id, configContent);
}
}
/**
* Get all role-permissions config from the db.
*
* @returns {object} Object with key value pairs of configs.
*/
getAllFromDatabase = async () => {
const UPService = strapi.plugin('users-permissions').service('users-permissions');
const roleService = strapi.plugin('users-permissions').service('role');
const [roles, plugins] = await Promise.all([
roleService.getRoles(),
UPService.getPlugins(),
]);
const rolesWithPermissions = await Promise.all(
roles.map(async (role) => roleService.getRole(role.id, plugins))
);
const configs = {};
rolesWithPermissions.map(({ id, ...config }) => {
// Check if the config should be excluded.
const shouldExclude = strapi.config.get('plugin.config-sync.exclude').includes(`${this.configPrefix}.${config.type}`);
if (shouldExclude) return;
// Do not export the _id field, as it is immutable
delete config._id;
configs[`${this.configPrefix}.${config.type}`] = config;
});
return configs;
}
};
module.exports = RolePermissionsConfigType;