mirror of
https://github.com/strapi/strapi.git
synced 2025-08-16 04:34:40 +00:00
Merge pull request #14984 from strapi/deits/import-cli-update
[DEITS] CLI updates and fixes
This commit is contained in:
commit
b7a87dcffc
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user