From 187a090866072f70db03c352bbda3a0c461576a5 Mon Sep 17 00:00:00 2001 From: Boaz Poolman Date: Sat, 20 Nov 2021 14:28:17 +0100 Subject: [PATCH] feat: Partial export in CLI --- server/cli.js | 17 +++++++----- server/config/type.js | 59 ++++++++++++++++++++--------------------- server/services/main.js | 31 +++++++++++++++++++--- 3 files changed, 66 insertions(+), 41 deletions(-) diff --git a/server/cli.js b/server/cli.js index 4396ed6..78376ab 100644 --- a/server/cli.js +++ b/server/cli.js @@ -135,11 +135,14 @@ const handleAction = async (syncType, skipConfirm, configType, partials) => { } } if (syncType === 'export') { + const onSuccess = (name) => console.log(`${chalk.bgGreen.bold('[success]')} Exported ${name}`); + try { - await app.plugin('config-sync').service('main').exportAllConfig(); - console.log(`${chalk.bgGreen.bold('[success]')} Config was exported`); + await Promise.all(Object.keys(finalDiff).map(async (name) => { + await app.plugin('config-sync').service('main').exportSingleConfig(name, onSuccess); + })); } catch (e) { - console.log(`${chalk.bgRed.bold('[error]')} Something went wrong during the export. ${e}`); + console.log(`${chalk.bgRed.bold('[error]')} Something went wrong during the import. ${e}`); } } } @@ -167,8 +170,8 @@ program program .command('import') .alias('i') - .option('-t, --type ', 'The type of config') // TODO: partial import - .option('-p, --partial ', 'A comma separated string of configs') // TODO: partial import + .option('-t, --type ', 'The type of config') + .option('-p, --partial ', 'A comma separated string of configs') .option('-y', 'Skip the confirm prompt') .description('Import the config') .action(async ({ y, type, partial }) => { @@ -179,8 +182,8 @@ program program .command('export') .alias('e') - .option('-t, --type ', 'The type of config') // TODO: partial export - .option('-p, --partial ', 'A comma separated string of configs') // TODO: partial import + .option('-t, --type ', 'The type of config') + .option('-p, --partial ', 'A comma separated string of configs') .option('-y', 'Skip the confirm prompt') .description('Export the config') .action(async ({ y, type, partial }) => { diff --git a/server/config/type.js b/server/config/type.js index 71baefa..6db9adb 100644 --- a/server/config/type.js +++ b/server/config/type.js @@ -13,32 +13,6 @@ const ConfigType = class ConfigType { this.relations = relations || []; } - /** - * Export all core-store config to files. - * - * @returns {void} - */ - exportAll = async () => { - const formattedDiff = await strapi.plugin('config-sync').service('main').getFormattedDiff(this.configPrefix); - - await Promise.all(Object.entries(formattedDiff.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], currentConfig); - } - })); - } - /** * Import a single role-permissions config file into the db. * @@ -141,6 +115,31 @@ const ConfigType = class ConfigType { } } + /** + * Export a single core-store config to a file. + * + * @param {string} configName - The name of the config file. + * @returns {void} + */ + exportSingle = async (configName) => { + const formattedDiff = await strapi.plugin('config-sync').service('main').getFormattedDiff(this.configPrefix); + + // 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], currentConfig); + } + } + /** * Get all role-permissions config from the db. * @@ -185,13 +184,13 @@ const ConfigType = class ConfigType { } /** - * Export a single core-store config to a file. + * Export all core-store config to files. * - * @param {string} configName - The name of the config file. * @returns {void} */ - exportSingle = async (configName) => { - // @TODO: write export for a single core-store config. + exportAll = async () => { + // The main.importAllConfig service will loop the core-store.importSingle service. + await strapi.plugin('config-sync').service('main').exportAllConfig(this.configPrefix); } }; diff --git a/server/services/main.js b/server/services/main.js index ca68574..0779414 100644 --- a/server/services/main.js +++ b/server/services/main.js @@ -169,15 +169,24 @@ module.exports = () => ({ * Export all config files. * * @param {string} configType - Type of config to export. Leave empty to export all config. + * @param {object} onSuccess - Success callback to run on each single successfull import. * @returns {void} */ - exportAllConfig: async (configType = null) => { - await Promise.all(strapi.config.get('plugin.config-sync.include').map(async (type) => { + exportAllConfig: async (configType = null, onSuccess) => { + const fileConfig = await strapi.plugin('config-sync').service('main').getAllConfigFromFiles(); + const databaseConfig = await strapi.plugin('config-sync').service('main').getAllConfigFromDatabase(); + + const diff = difference(databaseConfig, fileConfig); + + await Promise.all(Object.keys(diff).map(async (file) => { + const type = file.split('.')[0]; // Grab the first part of the filename. + const name = file.split(/\.(.+)/)[1]; // Grab the rest of the filename minus the file extension. + if (configType && configType !== type) { return; } - await types[type].exportAll(); + await strapi.plugin('config-sync').service('main').exportSingleConfig(`${type}.${name}`, onSuccess); })); }, @@ -210,10 +219,24 @@ module.exports = () => ({ * Export a single config file. * * @param {string} configName - The name of the config file. + * @param {object} onSuccess - Success callback to run on each single successfull import. * @returns {void} */ - exportSingleConfig: async (configName) => { + exportSingleConfig: async (configName, onSuccess) => { + // Check if the config should be excluded. + const shouldExclude = strapi.config.get('plugin.config-sync.exclude').includes(configName); + if (shouldExclude) return; + const [type, name] = configName.split('.'); // Split the configName. + + try { + await types[type].exportSingle(configName); + if (onSuccess) { + onSuccess(`${type}.${name}`); + } + } catch (e) { + throw new Error(e); + } }, /**