Merge pull request #14984 from strapi/deits/import-cli-update

[DEITS] CLI updates and fixes
This commit is contained in:
Ben Irvin 2022-11-24 14:34:48 +01:00 committed by GitHub
commit b7a87dcffc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 17 deletions

View File

@ -56,7 +56,7 @@ class LocalFileDestinationProvider implements IDestinationProvider {
results: ILocalFileDestinationProviderTransferResults = {}; results: ILocalFileDestinationProviderTransferResults = {};
#providersMetadata: { source?: IMetadata; destination?: IMetadata } = {}; #providersMetadata: { source?: IMetadata; destination?: IMetadata } = {};
#archive: { stream?: tar.Pack } = {}; #archive: { stream?: tar.Pack; pipeline?: Stream } = {};
constructor(options: ILocalFileDestinationProviderOptions) { constructor(options: ILocalFileDestinationProviderOptions) {
this.options = options; this.options = options;
@ -117,25 +117,24 @@ class LocalFileDestinationProvider implements IDestinationProvider {
archiveTransforms.push(createEncryptionCipher(encryption.key)); archiveTransforms.push(createEncryptionCipher(encryption.key));
} }
chain([this.#archive.stream, ...archiveTransforms, outStream]); this.#archive.pipeline = chain([this.#archive.stream, ...archiveTransforms, outStream]);
this.results.file = { path: this.#archivePath }; this.results.file = { path: this.#archivePath };
} }
async close() { async close() {
const { stream } = this.#archive; const { stream, pipeline } = this.#archive;
if (!stream) { if (!stream) {
return; return;
} }
await this.#writeMetadata(); await this.#writeMetadata();
stream.finalize(); stream.finalize();
if (!stream.closed) { if (pipeline && !pipeline.closed) {
await new Promise<void>((resolve, reject) => { await new Promise<void>((resolve, reject) => {
stream.on('close', resolve).on('error', reject); pipeline.on('close', resolve).on('error', reject);
}); });
} }
} }

View File

@ -8,6 +8,7 @@ const _ = require('lodash');
const resolveCwd = require('resolve-cwd'); const resolveCwd = require('resolve-cwd');
const { yellow } = require('chalk'); const { yellow } = require('chalk');
const { Command, Option } = require('commander'); const { Command, Option } = require('commander');
const inquirer = require('inquirer');
const program = new Command(); const program = new Command();
@ -285,7 +286,9 @@ program
.default(true) .default(true)
.argParser(parseInputBool) .argParser(parseInputBool)
) )
.addOption(new Option('--key', 'Provide encryption key in command instead of using a prompt')) .addOption(
new Option('--key <string>', 'Provide encryption key in command instead of using a prompt')
)
.addOption( .addOption(
new Option('--max-size <max MB per file>', 'split final file when exceeding size in MB') new Option('--max-size <max MB per file>', 'split final file when exceeding size in MB')
) )
@ -295,8 +298,8 @@ program
'split internal jsonl files when exceeding max size in MB' 'split internal jsonl files when exceeding max size in MB'
) )
) )
.addOption(new Option('-f, --file <file>', 'name to use for exported file (without extensions)'))
.addOption(excludeOption) .addOption(excludeOption)
.arguments('[filename]')
.allowExcessArguments(false) .allowExcessArguments(false)
.hook('preAction', promptEncryptionKey) .hook('preAction', promptEncryptionKey)
.action(getLocalScript('transfer/export')); .action(getLocalScript('transfer/export'));
@ -320,11 +323,35 @@ program
.choices(['exact', 'strict', 'subset', 'bypass']) .choices(['exact', 'strict', 'subset', 'bypass'])
.default('exact') .default('exact')
) )
.addOption( .requiredOption(
new Option('--key [encryptionKey]', 'prompt for [or provide directly] the decryption key') '-f, --file <file>',
'path and filename to the Strapi export file you want to import'
)
.addOption(
new Option('--key <string>', 'Provide encryption key in command instead of using a prompt')
) )
.arguments('<filename>')
.allowExcessArguments(false) .allowExcessArguments(false)
.hook('preAction', async (thisCommand) => {
const opts = thisCommand.opts();
// check extension to guess if we should prompt for key
if (String(opts.file).endsWith('.enc')) {
if (!opts.key) {
const answers = await inquirer.prompt([
{
type: 'password',
message: 'Please enter your decryption key',
name: 'key',
},
]);
if (!answers.key?.length) {
console.log('No key entered, aborting import.');
process.exit(0);
}
opts.key = answers.key;
}
}
})
.hook( .hook(
'preAction', 'preAction',
confirmKeyValue( confirmKeyValue(

View File

@ -40,12 +40,14 @@ const logger = console;
const BYTES_IN_MB = 1024 * 1024; const BYTES_IN_MB = 1024 * 1024;
module.exports = async (filename, opts) => { module.exports = async (opts) => {
// validate inputs from Commander // validate inputs from Commander
if (!_.isObject(opts)) { if (!_.isObject(opts)) {
logger.error('Could not parse arguments'); logger.error('Could not parse arguments');
process.exit(1); process.exit(1);
} }
const filename = opts.file;
/** /**
* From local Strapi instance * From local Strapi instance
*/ */

View File

@ -7,18 +7,18 @@ const {
// TODO: we need to solve this issue with typescript modules // TODO: we need to solve this issue with typescript modules
// eslint-disable-next-line import/no-unresolved, node/no-missing-require // eslint-disable-next-line import/no-unresolved, node/no-missing-require
} = require('@strapi/data-transfer'); } = require('@strapi/data-transfer');
const _ = require('lodash/fp'); const { isObject } = require('lodash/fp');
const strapi = require('../../index'); const strapi = require('../../index');
const logger = console; const logger = console;
module.exports = async (filename, opts) => { module.exports = async (opts) => {
// validate inputs from Commander // validate inputs from Commander
if (!_.isString(filename) || !_.isObject(opts)) { if (!isObject(opts)) {
logger.error('Could not parse arguments'); logger.error('Could not parse arguments');
process.exit(1); process.exit(1);
} }
const filename = opts.file;
/** /**
* From strapi backup file * From strapi backup file
@ -59,7 +59,7 @@ module.exports = async (filename, opts) => {
logger.log('Results:', result); logger.log('Results:', result);
process.exit(0); process.exit(0);
} catch (e) { } catch (e) {
logger.log('Import process failed unexpectedly'); logger.log(`Import process failed unexpectedly: ${e.message}`);
process.exit(1); process.exit(1);
} }
}; };