From 27e4fbb0fff7a51d0f7cb35bcf1eb1d6ba30ed3f Mon Sep 17 00:00:00 2001 From: Alexandre Bodin Date: Thu, 18 Jan 2024 11:55:00 +0100 Subject: [PATCH] chore: move dts commands back into strapi/strapi without circular dep issue --- packages/core/data-transfer/package.json | 1 - .../data-transfer/src/commands/commander.ts | 154 ------------------ .../data-transfer/src/commands/helpers.ts | 106 ------------ .../commands/import/__tests__/import.test.ts | 146 ----------------- .../core/data-transfer/src/commands/index.ts | 5 - packages/core/data-transfer/src/index.ts | 1 - packages/core/data-transfer/tsconfig.json | 7 +- .../commands/__tests__/commands.test.utils.ts | 0 .../commands/export/__tests__/export.test.ts | 140 ++++++++-------- .../src/cli}/commands/export/action.ts | 29 ++-- .../src/cli}/commands/export/command.ts | 10 +- .../commands/import/__tests__/import.test.ts | 142 ++++++++++++++++ .../src/cli}/commands/import/action.ts | 30 ++-- .../src/cli}/commands/import/command.ts | 11 +- .../core/strapi/src/cli/commands/index.ts | 6 + .../transfer/__tests__/transfer.test.ts | 79 ++++----- .../src/cli}/commands/transfer/action.ts | 15 +- .../src/cli}/commands/transfer/command.ts | 12 +- packages/core/strapi/src/cli/index.ts | 9 - .../src/cli/utils}/data-transfer.ts | 49 +++--- yarn.lock | 1 - 21 files changed, 352 insertions(+), 601 deletions(-) delete mode 100644 packages/core/data-transfer/src/commands/commander.ts delete mode 100644 packages/core/data-transfer/src/commands/helpers.ts delete mode 100644 packages/core/data-transfer/src/commands/import/__tests__/import.test.ts delete mode 100644 packages/core/data-transfer/src/commands/index.ts rename packages/core/{data-transfer/src => strapi/src/cli}/commands/__tests__/commands.test.utils.ts (100%) rename packages/core/{data-transfer/src => strapi/src/cli}/commands/export/__tests__/export.test.ts (60%) rename packages/core/{data-transfer/src => strapi/src/cli}/commands/export/action.ts (86%) rename packages/core/{data-transfer/src => strapi/src/cli}/commands/export/command.ts (86%) create mode 100644 packages/core/strapi/src/cli/commands/import/__tests__/import.test.ts rename packages/core/{data-transfer/src => strapi/src/cli}/commands/import/action.ts (88%) rename packages/core/{data-transfer/src => strapi/src/cli}/commands/import/command.ts (91%) rename packages/core/{data-transfer/src => strapi/src/cli}/commands/transfer/__tests__/transfer.test.ts (76%) rename packages/core/{data-transfer/src => strapi/src/cli}/commands/transfer/action.ts (92%) rename packages/core/{data-transfer/src => strapi/src/cli}/commands/transfer/command.ts (94%) rename packages/core/{data-transfer/src/commands => strapi/src/cli/utils}/data-transfer.ts (90%) diff --git a/packages/core/data-transfer/package.json b/packages/core/data-transfer/package.json index 300c4b50a2..7ff79d2a56 100644 --- a/packages/core/data-transfer/package.json +++ b/packages/core/data-transfer/package.json @@ -40,7 +40,6 @@ "watch": "pack-up watch" }, "dependencies": { - "@strapi/core": "4.17.1", "@strapi/logger": "4.17.1", "@strapi/types": "4.17.1", "@strapi/utils": "4.17.1", diff --git a/packages/core/data-transfer/src/commands/commander.ts b/packages/core/data-transfer/src/commands/commander.ts deleted file mode 100644 index 2b31024936..0000000000 --- a/packages/core/data-transfer/src/commands/commander.ts +++ /dev/null @@ -1,154 +0,0 @@ -/** - * This file includes hooks to use for commander.hook and argParsers for commander.argParser - */ - -import inquirer from 'inquirer'; -import { Command, InvalidOptionArgumentError, Option } from 'commander'; -import chalk from 'chalk'; -import { isNaN } from 'lodash/fp'; -import { exitWith } from './helpers'; - -/** - * argParser: Parse a comma-delimited string as an array - */ -const parseList = (value: string) => { - try { - return value.split(',').map((item) => item.trim()); // trim shouldn't be necessary but might help catch unexpected whitespace characters - } catch (e) { - exitWith(1, `Unrecognized input: ${value}`); - } - - return []; -}; - -/** - * Returns an argParser that returns a list - */ -const getParseListWithChoices = (choices: string[], errorMessage = 'Invalid options:') => { - return (value: string) => { - const list = parseList(value); - const invalid = list.filter((item) => { - return !choices.includes(item); - }); - - if (invalid.length > 0) { - exitWith(1, `${errorMessage}: ${invalid.join(',')}`); - } - - return list; - }; -}; - -/** - * argParser: Parse a string as an integer - */ -const parseInteger = (value: string) => { - // parseInt takes a string and a radix - const parsedValue = parseInt(value, 10); - if (isNaN(parsedValue)) { - throw new InvalidOptionArgumentError(`Not an integer: ${value}`); - } - return parsedValue; -}; - -/** - * argParser: Parse a string as a URL object - */ -const parseURL = (value: string) => { - try { - const url = new URL(value); - if (!url.host) { - throw new InvalidOptionArgumentError(`Could not parse url ${value}`); - } - - return url; - } catch (e) { - throw new InvalidOptionArgumentError(`Could not parse url ${value}`); - } -}; - -/** - * hook: if encrypt==true and key not provided, prompt for it - */ -const promptEncryptionKey = async (thisCommand: Command) => { - const opts = thisCommand.opts(); - - if (!opts.encrypt && opts.key) { - return exitWith(1, 'Key may not be present unless encryption is used'); - } - - // if encrypt==true but we have no key, prompt for it - if (opts.encrypt && !(opts.key && opts.key.length > 0)) { - try { - const answers = await inquirer.prompt([ - { - type: 'password', - message: 'Please enter an encryption key', - name: 'key', - validate(key) { - if (key.length > 0) return true; - - return 'Key must be present when using the encrypt option'; - }, - }, - ]); - opts.key = answers.key; - } catch (e) { - return exitWith(1, 'Failed to get encryption key'); - } - if (!opts.key) { - return exitWith(1, 'Failed to get encryption key'); - } - } -}; - -/** - * hook: require a confirmation message to be accepted unless forceOption (-f,--force) is used - */ -const getCommanderConfirmMessage = ( - message: string, - { failMessage }: { failMessage?: string } = {} -) => { - return async (command: Command) => { - const confirmed = await confirmMessage(message, { force: command.opts().force }); - if (!confirmed) { - exitWith(1, failMessage); - } - }; -}; - -const confirmMessage = async (message: string, { force }: { force?: boolean } = {}) => { - // if we have a force option, respond yes - if (force === true) { - // attempt to mimic the inquirer prompt exactly - console.log(`${chalk.green('?')} ${chalk.bold(message)} ${chalk.cyan('Yes')}`); - return true; - } - - const answers = await inquirer.prompt([ - { - type: 'confirm', - message, - name: `confirm`, - default: false, - }, - ]); - - return answers.confirm; -}; - -const forceOption = new Option( - '--force', - `Automatically answer "yes" to all prompts, including potentially destructive requests, and run non-interactively.` -); - -export { - getParseListWithChoices, - parseList, - parseURL, - parseInteger, - promptEncryptionKey, - getCommanderConfirmMessage, - confirmMessage, - forceOption, -}; diff --git a/packages/core/data-transfer/src/commands/helpers.ts b/packages/core/data-transfer/src/commands/helpers.ts deleted file mode 100644 index 4b4187ff30..0000000000 --- a/packages/core/data-transfer/src/commands/helpers.ts +++ /dev/null @@ -1,106 +0,0 @@ -import chalk from 'chalk'; -import { isString, isArray } from 'lodash/fp'; -import type { Command } from 'commander'; - -const bytesPerKb = 1024; -const sizes = ['B ', 'KB', 'MB', 'GB', 'TB', 'PB']; - -/** - * Convert bytes to a human readable formatted string, for example "1024" becomes "1KB" - */ -const readableBytes = (bytes: number, decimals = 1, padStart = 0) => { - if (!bytes) { - return '0'; - } - const i = Math.floor(Math.log(bytes) / Math.log(bytesPerKb)); - const result = `${parseFloat((bytes / bytesPerKb ** i).toFixed(decimals))} ${sizes[i].padStart( - 2 - )}`; - - return result.padStart(padStart); -}; - -interface ExitWithOptions { - logger?: Console; - prc?: NodeJS.Process; -} - -/** - * - * Display message(s) to console and then call process.exit with code. - * If code is zero, console.log and green text is used for messages, otherwise console.error and red text. - * - */ -const exitWith = (code: number, message?: string | string[], options: ExitWithOptions = {}) => { - const { logger = console, prc = process } = options; - - const log = (message: string) => { - if (code === 0) { - logger.log(chalk.green(message)); - } else { - logger.error(chalk.red(message)); - } - }; - - if (isString(message)) { - log(message); - } else if (isArray(message)) { - message.forEach((msg) => log(msg)); - } - - prc.exit(code); -}; - -/** - * assert that a URL object has a protocol value - * - */ -const assertUrlHasProtocol = (url: URL, protocol?: string | string[]) => { - if (!url.protocol) { - exitWith(1, `${url.toString()} does not have a protocol`); - } - - // if just checking for the existence of a protocol, return - if (!protocol) { - return; - } - - if (isString(protocol)) { - if (protocol !== url.protocol) { - exitWith(1, `${url.toString()} must have the protocol ${protocol}`); - } - return; - } - - // assume an array - if (!protocol.some((protocol) => url.protocol === protocol)) { - return exitWith( - 1, - `${url.toString()} must have one of the following protocols: ${protocol.join(',')}` - ); - } -}; - -type ConditionCallback = (opts: Record) => Promise; -type IsMetCallback = (command: Command) => Promise; -type IsNotMetCallback = (command: Command) => Promise; - -/** - * Passes commander options to conditionCallback(). If it returns true, call isMetCallback otherwise call isNotMetCallback - */ -const ifOptions = ( - conditionCallback: ConditionCallback, - isMetCallback: IsMetCallback = async () => {}, - isNotMetCallback: IsNotMetCallback = async () => {} -) => { - return async (command: Command) => { - const opts = command.opts(); - if (await conditionCallback(opts)) { - await isMetCallback(command); - } else { - await isNotMetCallback(command); - } - }; -}; - -export { exitWith, assertUrlHasProtocol, ifOptions, readableBytes }; diff --git a/packages/core/data-transfer/src/commands/import/__tests__/import.test.ts b/packages/core/data-transfer/src/commands/import/__tests__/import.test.ts deleted file mode 100644 index f70b746826..0000000000 --- a/packages/core/data-transfer/src/commands/import/__tests__/import.test.ts +++ /dev/null @@ -1,146 +0,0 @@ -import importAction from '../action'; -import { expectExit } from '../../__tests__/commands.test.utils'; -import * as engineDatatransfer from '../../../engine'; -import * as strapiDatatransfer from '../../../strapi'; -import * as fileDatatransfer from '../../../file'; - -jest.mock('../../data-transfer', () => { - return { - ...jest.requireActual('../../data-transfer'), - getTransferTelemetryPayload: jest.fn().mockReturnValue({}), - loadersFactory: jest.fn().mockReturnValue({ updateLoader: jest.fn() }), - formatDiagnostic: jest.fn(), - createStrapiInstance: jest.fn().mockReturnValue({ - telemetry: { - send: jest.fn(), - }, - destroy: jest.fn(), - }), - buildTransferTable: jest.fn(() => { - return { - toString() { - return 'table'; - }, - }; - }), - exitMessageText: jest.fn(), - getDiffHandler: jest.fn(), - setSignalHandler: jest.fn(), - }; -}); - -jest.mock('../../../engine', () => { - const actual = jest.requireActual('../../../engine'); - - return { - ...actual, - createTransferEngine: jest.fn(() => { - return { - transfer: jest.fn(() => { - return { - engine: {}, - }; - }), - progress: { - on: jest.fn(), - stream: { - on: jest.fn(), - }, - }, - sourceProvider: { name: 'testFileSource', type: 'source', getMetadata: jest.fn() }, - destinationProvider: { - name: 'testStrapiDest', - type: 'destination', - getMetadata: jest.fn(), - }, - diagnostics: { - on: jest.fn().mockReturnThis(), - onDiagnostic: jest.fn().mockReturnThis(), - }, - onSchemaDiff: jest.fn(), - }; - }), - }; -}); - -jest.mock('../../../file', () => { - const actual = jest.requireActual('../../../file'); - - return { - ...actual, - providers: { - ...actual.providers, - createLocalFileSourceProvider: jest - .fn() - .mockReturnValue({ name: 'testFileSource', type: 'source', getMetadata: jest.fn() }), - }, - }; -}); - -jest.mock('../../../strapi', () => { - const actual = jest.requireActual('../../../strapi'); - - return { - ...actual, - providers: { - ...actual.providers, - createLocalStrapiDestinationProvider: jest - .fn() - .mockReturnValue({ name: 'testStrapiDest', type: 'destination', getMetadata: jest.fn() }), - }, - }; -}); - -describe('Import', () => { - // mock command utils - - // console spies - jest.spyOn(console, 'log').mockImplementation(() => {}); - jest.spyOn(console, 'warn').mockImplementation(() => {}); - jest.spyOn(console, 'info').mockImplementation(() => {}); - jest.spyOn(console, 'error').mockImplementation(() => {}); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('creates providers with correct options ', async () => { - const options = { - file: 'test.tar.gz.enc', - decrypt: true, - decompress: true, - exclude: [], - only: [], - }; - - await expectExit(0, async () => { - await importAction(options); - }); - - // strapi options - expect(strapiDatatransfer.providers.createLocalStrapiDestinationProvider).toHaveBeenCalledWith( - expect.objectContaining({ - strategy: strapiDatatransfer.providers.DEFAULT_CONFLICT_STRATEGY, - }) - ); - - // file options - expect(fileDatatransfer.providers.createLocalFileSourceProvider).toHaveBeenCalledWith( - expect.objectContaining({ - file: { path: 'test.tar.gz.enc' }, - encryption: { enabled: options.decrypt }, - compression: { enabled: options.decompress }, - }) - ); - - // engine options - expect(engineDatatransfer.createTransferEngine).toHaveBeenCalledWith( - expect.objectContaining({ name: 'testFileSource' }), - expect.objectContaining({ name: 'testStrapiDest' }), - expect.objectContaining({ - schemaStrategy: engineDatatransfer.DEFAULT_SCHEMA_STRATEGY, - versionStrategy: engineDatatransfer.DEFAULT_VERSION_STRATEGY, - }) - ); - }); -}); diff --git a/packages/core/data-transfer/src/commands/index.ts b/packages/core/data-transfer/src/commands/index.ts deleted file mode 100644 index 4ed9d3903d..0000000000 --- a/packages/core/data-transfer/src/commands/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import exportCmd from './export/command'; -import importCmd from './import/command'; -import transferCmd from './transfer/command'; - -export const commands = [exportCmd, importCmd, transferCmd]; diff --git a/packages/core/data-transfer/src/index.ts b/packages/core/data-transfer/src/index.ts index 77df25705d..f6c4c97772 100644 --- a/packages/core/data-transfer/src/index.ts +++ b/packages/core/data-transfer/src/index.ts @@ -2,4 +2,3 @@ export * as engine from './engine'; export * as strapi from './strapi'; export * as file from './file'; export * as utils from './utils'; -export { commands } from './commands'; diff --git a/packages/core/data-transfer/tsconfig.json b/packages/core/data-transfer/tsconfig.json index 31ca80c6d0..6b1c241708 100644 --- a/packages/core/data-transfer/tsconfig.json +++ b/packages/core/data-transfer/tsconfig.json @@ -1,5 +1,10 @@ { "extends": "tsconfig/base.json", - "include": ["types", "src", "packup.config.ts"], + "include": [ + "types", + "src", + "packup.config.ts", + "../strapi/src/cli/commands/__tests__/commands.test.utils.ts" + ], "exclude": ["node_modules"] } diff --git a/packages/core/data-transfer/src/commands/__tests__/commands.test.utils.ts b/packages/core/strapi/src/cli/commands/__tests__/commands.test.utils.ts similarity index 100% rename from packages/core/data-transfer/src/commands/__tests__/commands.test.utils.ts rename to packages/core/strapi/src/cli/commands/__tests__/commands.test.utils.ts diff --git a/packages/core/data-transfer/src/commands/export/__tests__/export.test.ts b/packages/core/strapi/src/cli/commands/export/__tests__/export.test.ts similarity index 60% rename from packages/core/data-transfer/src/commands/export/__tests__/export.test.ts rename to packages/core/strapi/src/cli/commands/export/__tests__/export.test.ts index a381965b5e..716af381f6 100644 --- a/packages/core/data-transfer/src/commands/export/__tests__/export.test.ts +++ b/packages/core/strapi/src/cli/commands/export/__tests__/export.test.ts @@ -1,7 +1,8 @@ +import { file as fileDataTransfer } from '@strapi/data-transfer'; + import exportAction from '../action'; -import * as mockUtils from '../../data-transfer'; +import * as mockUtils from '../../../utils/data-transfer'; import { expectExit } from '../../__tests__/commands.test.utils'; -import * as fileDatatransfer from '../../../file'; jest.mock('fs-extra', () => ({ ...jest.requireActual('fs-extra'), @@ -10,9 +11,9 @@ jest.mock('fs-extra', () => ({ const defaultFileName = 'defaultFilename'; -jest.mock('../../data-transfer', () => { +jest.mock('../../../utils/data-transfer', () => { return { - ...jest.requireActual('../../data-transfer'), + ...jest.requireActual('../../../utils/data-transfer'), getTransferTelemetryPayload: jest.fn().mockReturnValue({}), loadersFactory: jest.fn().mockReturnValue({ updateLoader: jest.fn() }), formatDiagnostic: jest.fn(), @@ -36,75 +37,68 @@ jest.mock('../../data-transfer', () => { }; }); -jest.mock('../../../engine', () => { - const actual = jest.requireActual('../../../engine'); +jest.mock('@strapi/data-transfer', () => { + const actual = jest.requireActual('@strapi/data-transfer'); return { ...actual, - createTransferEngine: jest.fn(() => { - return { - transfer: jest.fn(() => { - return { - engine: {}, - destination: { - file: { - path: 'path', - }, - }, - }; - }), - progress: { - on: jest.fn(), - stream: { - on: jest.fn(), - }, - }, - sourceProvider: { name: 'testFileSource', type: 'source', getMetadata: jest.fn() }, - destinationProvider: { - name: 'testStrapiDest', + file: { + ...actual.file, + providers: { + ...actual.file.providers, + createLocalFileSourceProvider: jest + .fn() + .mockReturnValue({ name: 'testFileSource', type: 'source', getMetadata: jest.fn() }), + createLocalFileDestinationProvider: jest.fn().mockReturnValue({ + name: 'testFileDestination', type: 'destination', getMetadata: jest.fn(), - }, - diagnostics: { - on: jest.fn().mockReturnThis(), - onDiagnostic: jest.fn().mockReturnThis(), - }, - onSchemaDiff: jest.fn(), - addErrorHandler: jest.fn(), - }; - }), - }; -}); - -jest.mock('../../../file', () => { - const actual = jest.requireActual('../../../file'); - - return { - ...actual, - providers: { - ...actual.providers, - createLocalFileSourceProvider: jest - .fn() - .mockReturnValue({ name: 'testFileSource', type: 'source', getMetadata: jest.fn() }), - createLocalFileDestinationProvider: jest.fn().mockReturnValue({ - name: 'testFileDestination', - type: 'destination', - getMetadata: jest.fn(), - }), + }), + }, }, - }; -}); - -jest.mock('../../../strapi', () => { - const actual = jest.requireActual('../../../strapi'); - - return { - ...actual, - providers: { - ...actual.providers, - createLocalStrapiDestinationProvider: jest - .fn() - .mockReturnValue({ name: 'testStrapiDest', type: 'destination', getMetadata: jest.fn() }), + strapi: { + ...actual.strapi, + providers: { + ...actual.strapi.providers, + createLocalStrapiDestinationProvider: jest + .fn() + .mockReturnValue({ name: 'testStrapiDest', type: 'destination', getMetadata: jest.fn() }), + }, + }, + engine: { + ...actual.engine, + createTransferEngine: jest.fn(() => { + return { + transfer: jest.fn(() => { + return { + engine: {}, + destination: { + file: { + path: 'path', + }, + }, + }; + }), + progress: { + on: jest.fn(), + stream: { + on: jest.fn(), + }, + }, + sourceProvider: { name: 'testFileSource', type: 'source', getMetadata: jest.fn() }, + destinationProvider: { + name: 'testStrapiDest', + type: 'destination', + getMetadata: jest.fn(), + }, + diagnostics: { + on: jest.fn().mockReturnThis(), + onDiagnostic: jest.fn().mockReturnThis(), + }, + onSchemaDiff: jest.fn(), + addErrorHandler: jest.fn(), + }; + }), }, }; }); @@ -130,7 +124,7 @@ describe('Export', () => { }); expect(console.error).not.toHaveBeenCalled(); - expect(fileDatatransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( + expect(fileDataTransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( expect.objectContaining({ file: { path: filename }, }) @@ -144,7 +138,7 @@ describe('Export', () => { }); expect(mockUtils.getDefaultExportName).toHaveBeenCalledTimes(1); - expect(fileDatatransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( + expect(fileDataTransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( expect.objectContaining({ file: { path: defaultFileName }, }) @@ -157,7 +151,7 @@ describe('Export', () => { await exportAction({ encrypt }); }); - expect(fileDatatransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( + expect(fileDataTransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( expect.objectContaining({ encryption: { enabled: encrypt }, }) @@ -171,7 +165,7 @@ describe('Export', () => { await exportAction({ encrypt, key }); }); - expect(fileDatatransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( + expect(fileDataTransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( expect.objectContaining({ encryption: { enabled: encrypt, key }, }) @@ -183,7 +177,7 @@ describe('Export', () => { await exportAction({ compress: false }); }); - expect(fileDatatransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( + expect(fileDataTransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( expect.objectContaining({ compression: { enabled: false }, }) @@ -191,7 +185,7 @@ describe('Export', () => { await expectExit(0, async () => { await exportAction({ compress: true }); }); - expect(fileDatatransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( + expect(fileDataTransfer.providers.createLocalFileDestinationProvider).toHaveBeenCalledWith( expect.objectContaining({ compression: { enabled: true }, }) diff --git a/packages/core/data-transfer/src/commands/export/action.ts b/packages/core/strapi/src/cli/commands/export/action.ts similarity index 86% rename from packages/core/data-transfer/src/commands/export/action.ts rename to packages/core/strapi/src/cli/commands/export/action.ts index 96767f9c17..7cb8e22f84 100644 --- a/packages/core/data-transfer/src/commands/export/action.ts +++ b/packages/core/strapi/src/cli/commands/export/action.ts @@ -3,6 +3,12 @@ import fs from 'fs-extra'; import chalk from 'chalk'; import type { LoadedStrapi } from '@strapi/types'; +import { + engine as engineDataTransfer, + strapi as strapiDataTransfer, + file as fileDataTransfer, +} from '@strapi/data-transfer'; + import { getDefaultExportName, buildTransferTable, @@ -14,18 +20,15 @@ import { abortTransfer, getTransferTelemetryPayload, setSignalHandler, -} from '../data-transfer'; -import { exitWith } from '../helpers'; -import { TransferGroupFilter, createTransferEngine, ITransferResults, errors } from '../../engine'; -import * as strapiDatatransfer from '../../strapi'; -import * as file from '../../file'; +} from '../../utils/data-transfer'; +import { exitWith } from '../../utils/helpers'; const { providers: { createLocalFileDestinationProvider }, -} = file; +} = fileDataTransfer; const { providers: { createLocalStrapiSourceProvider }, -} = strapiDatatransfer; +} = strapiDataTransfer; const BYTES_IN_MB = 1024 * 1024; @@ -34,8 +37,8 @@ interface CmdOptions { encrypt?: boolean; key?: string; compress?: boolean; - only?: (keyof TransferGroupFilter)[]; - exclude?: (keyof TransferGroupFilter)[]; + only?: (keyof engineDataTransfer.TransferGroupFilter)[]; + exclude?: (keyof engineDataTransfer.TransferGroupFilter)[]; throttle?: number; maxSizeJsonl?: number; } @@ -58,7 +61,7 @@ export default async (opts: CmdOptions) => { const source = createSourceProvider(strapi); const destination = createDestinationProvider(opts); - const engine = createTransferEngine(source, destination, { + const engine = engineDataTransfer.createTransferEngine(source, destination, { versionStrategy: 'ignore', // for an export to file, versionStrategy will always be skipped schemaStrategy: 'ignore', // for an export to file, schemaStrategy will always be skipped exclude: opts.exclude, @@ -109,7 +112,7 @@ export default async (opts: CmdOptions) => { await strapi.telemetry.send('didDEITSProcessStart', getTransferTelemetryPayload(engine)); }); - let results: ITransferResults; + let results: engineDataTransfer.ITransferResults; let outFile: string; try { // Abort transfer if user interrupts process @@ -119,7 +122,9 @@ export default async (opts: CmdOptions) => { outFile = results.destination?.file?.path ?? ''; const outFileExists = await fs.pathExists(outFile); if (!outFileExists) { - throw new errors.TransferEngineTransferError(`Export file not created "${outFile}"`); + throw new engineDataTransfer.errors.TransferEngineTransferError( + `Export file not created "${outFile}"` + ); } // Note: we need to await telemetry or else the process ends before it is sent diff --git a/packages/core/data-transfer/src/commands/export/command.ts b/packages/core/strapi/src/cli/commands/export/command.ts similarity index 86% rename from packages/core/data-transfer/src/commands/export/command.ts rename to packages/core/strapi/src/cli/commands/export/command.ts index 28592918d7..25188496aa 100644 --- a/packages/core/data-transfer/src/commands/export/command.ts +++ b/packages/core/strapi/src/cli/commands/export/command.ts @@ -1,6 +1,12 @@ import { createCommand, Option } from 'commander'; -import { excludeOption, onlyOption, throttleOption, validateExcludeOnly } from '../data-transfer'; -import { promptEncryptionKey } from '../commander'; + +import { + excludeOption, + onlyOption, + throttleOption, + validateExcludeOnly, +} from '../../utils/data-transfer'; +import { promptEncryptionKey } from '../../utils/commander'; import action from './action'; /** diff --git a/packages/core/strapi/src/cli/commands/import/__tests__/import.test.ts b/packages/core/strapi/src/cli/commands/import/__tests__/import.test.ts new file mode 100644 index 0000000000..5cea9d473b --- /dev/null +++ b/packages/core/strapi/src/cli/commands/import/__tests__/import.test.ts @@ -0,0 +1,142 @@ +import { + engine as engineDataTransfer, + strapi as strapiDataTransfer, + file as fileDataTransfer, +} from '@strapi/data-transfer'; + +import importAction from '../action'; +import { expectExit } from '../../__tests__/commands.test.utils'; + +jest.mock('../../../utils/data-transfer', () => { + return { + ...jest.requireActual('../../../utils/data-transfer'), + getTransferTelemetryPayload: jest.fn().mockReturnValue({}), + loadersFactory: jest.fn().mockReturnValue({ updateLoader: jest.fn() }), + formatDiagnostic: jest.fn(), + createStrapiInstance: jest.fn().mockReturnValue({ + telemetry: { + send: jest.fn(), + }, + destroy: jest.fn(), + }), + buildTransferTable: jest.fn(() => { + return { + toString() { + return 'table'; + }, + }; + }), + exitMessageText: jest.fn(), + getDiffHandler: jest.fn(), + setSignalHandler: jest.fn(), + }; +}); + +jest.mock('@strapi/data-transfer', () => { + const actual = jest.requireActual('@strapi/data-transfer'); + + return { + ...actual, + file: { + ...actual.file, + providers: { + ...actual.file.providers, + createLocalFileSourceProvider: jest + .fn() + .mockReturnValue({ name: 'testFileSource', type: 'source', getMetadata: jest.fn() }), + }, + }, + strapi: { + ...actual.strapi, + providers: { + ...actual.strapi.providers, + createLocalStrapiDestinationProvider: jest + .fn() + .mockReturnValue({ name: 'testStrapiDest', type: 'destination', getMetadata: jest.fn() }), + }, + }, + engine: { + ...actual.engine, + createTransferEngine: jest.fn(() => { + return { + transfer: jest.fn(() => { + return { + engine: {}, + }; + }), + progress: { + on: jest.fn(), + stream: { + on: jest.fn(), + }, + }, + sourceProvider: { name: 'testFileSource', type: 'source', getMetadata: jest.fn() }, + destinationProvider: { + name: 'testStrapiDest', + type: 'destination', + getMetadata: jest.fn(), + }, + diagnostics: { + on: jest.fn().mockReturnThis(), + onDiagnostic: jest.fn().mockReturnThis(), + }, + onSchemaDiff: jest.fn(), + }; + }), + }, + }; +}); + +describe('Import', () => { + // mock command utils + + // console spies + jest.spyOn(console, 'log').mockImplementation(() => {}); + jest.spyOn(console, 'warn').mockImplementation(() => {}); + jest.spyOn(console, 'info').mockImplementation(() => {}); + jest.spyOn(console, 'error').mockImplementation(() => {}); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('creates providers with correct options ', async () => { + const options = { + file: 'test.tar.gz.enc', + decrypt: true, + decompress: true, + exclude: [], + only: [], + }; + + await expectExit(0, async () => { + await importAction(options); + }); + + // strapi options + expect(strapiDataTransfer.providers.createLocalStrapiDestinationProvider).toHaveBeenCalledWith( + expect.objectContaining({ + strategy: strapiDataTransfer.providers.DEFAULT_CONFLICT_STRATEGY, + }) + ); + + // file options + expect(fileDataTransfer.providers.createLocalFileSourceProvider).toHaveBeenCalledWith( + expect.objectContaining({ + file: { path: 'test.tar.gz.enc' }, + encryption: { enabled: options.decrypt }, + compression: { enabled: options.decompress }, + }) + ); + + // engine options + expect(engineDataTransfer.createTransferEngine).toHaveBeenCalledWith( + expect.objectContaining({ name: 'testFileSource' }), + expect.objectContaining({ name: 'testStrapiDest' }), + expect.objectContaining({ + schemaStrategy: engineDataTransfer.DEFAULT_SCHEMA_STRATEGY, + versionStrategy: engineDataTransfer.DEFAULT_VERSION_STRATEGY, + }) + ); + }); +}); diff --git a/packages/core/data-transfer/src/commands/import/action.ts b/packages/core/strapi/src/cli/commands/import/action.ts similarity index 88% rename from packages/core/data-transfer/src/commands/import/action.ts rename to packages/core/strapi/src/cli/commands/import/action.ts index d9e1e6cb7a..3402f76442 100644 --- a/packages/core/data-transfer/src/commands/import/action.ts +++ b/packages/core/strapi/src/cli/commands/import/action.ts @@ -1,7 +1,13 @@ import type { LoadedStrapi } from '@strapi/types'; import { isObject } from 'lodash/fp'; - import chalk from 'chalk'; + +import { + engine as engineDataTransfer, + strapi as strapiDataTransfer, + file as fileDataTransfer, +} from '@strapi/data-transfer'; + import { buildTransferTable, DEFAULT_IGNORED_CONTENT_TYPES, @@ -14,21 +20,19 @@ import { setSignalHandler, getDiffHandler, parseRestoreFromOptions, -} from '../data-transfer'; -import { exitWith } from '../helpers'; -import * as engine from '../../engine'; -import * as strapiDatatransfer from '../../strapi'; -import * as file from '../../file'; +} from '../../utils/data-transfer'; +import { exitWith } from '../../utils/helpers'; const { providers: { createLocalFileSourceProvider }, -} = file; +} = fileDataTransfer; const { providers: { createLocalStrapiDestinationProvider, DEFAULT_CONFLICT_STRATEGY }, -} = strapiDatatransfer; +} = strapiDataTransfer; -const { createTransferEngine, DEFAULT_VERSION_STRATEGY, DEFAULT_SCHEMA_STRATEGY } = engine; +const { createTransferEngine, DEFAULT_VERSION_STRATEGY, DEFAULT_SCHEMA_STRATEGY } = + engineDataTransfer; interface CmdOptions { file?: string; @@ -37,8 +41,8 @@ interface CmdOptions { key?: string; conflictStrategy?: 'restore'; force?: boolean; - only?: (keyof engine.TransferGroupFilter)[]; - exclude?: (keyof engine.TransferGroupFilter)[]; + only?: (keyof engineDataTransfer.TransferGroupFilter)[]; + exclude?: (keyof engineDataTransfer.TransferGroupFilter)[]; throttle?: number; } @@ -137,7 +141,7 @@ export default async (opts: CmdOptions) => { ); }); - let results: engine.ITransferResults; + let results: engineDataTransfer.ITransferResults; try { // Abort transfer if user interrupts process setSignalHandler(() => abortTransfer({ engine, strapi: strapi as LoadedStrapi })); @@ -174,7 +178,7 @@ const getLocalFileSourceOptions = (opts: { decrypt?: boolean; key?: string; }) => { - const options: file.providers.ILocalFileSourceProviderOptions = { + const options: fileDataTransfer.providers.ILocalFileSourceProviderOptions = { file: { path: opts.file ?? '' }, compression: { enabled: !!opts.decompress }, encryption: { enabled: !!opts.decrypt, key: opts.key }, diff --git a/packages/core/data-transfer/src/commands/import/command.ts b/packages/core/strapi/src/cli/commands/import/command.ts similarity index 91% rename from packages/core/data-transfer/src/commands/import/command.ts rename to packages/core/strapi/src/cli/commands/import/command.ts index c5413c1e8c..1008abe494 100644 --- a/packages/core/data-transfer/src/commands/import/command.ts +++ b/packages/core/strapi/src/cli/commands/import/command.ts @@ -1,9 +1,14 @@ import path from 'path'; import { createCommand, Option } from 'commander'; import inquirer from 'inquirer'; -import { excludeOption, onlyOption, throttleOption, validateExcludeOnly } from '../data-transfer'; -import { getCommanderConfirmMessage, forceOption } from '../commander'; -import { exitWith } from '../helpers'; +import { + excludeOption, + onlyOption, + throttleOption, + validateExcludeOnly, +} from '../../utils/data-transfer'; +import { getCommanderConfirmMessage, forceOption } from '../../utils/commander'; +import { exitWith } from '../../utils/helpers'; import action from './action'; /** diff --git a/packages/core/strapi/src/cli/commands/index.ts b/packages/core/strapi/src/cli/commands/index.ts index a988e0c622..973797ce92 100644 --- a/packages/core/strapi/src/cli/commands/index.ts +++ b/packages/core/strapi/src/cli/commands/index.ts @@ -21,6 +21,9 @@ import { command as generateCommand } from './generate'; import { command as reportCommand } from './report'; import { command as startCommand } from './start'; import { command as versionCommand } from './version'; +import exportCommand from './export/command'; +import importCommand from './import/command'; +import transferCommand from './transfer/command'; import { command as buildPluginCommand } from './plugin/build'; import { command as initPluginCommand } from './plugin/init'; @@ -53,6 +56,9 @@ export const commands: StrapiCommand[] = [ versionCommand, buildCommand, developCommand, + exportCommand, + importCommand, + transferCommand, /** * Plugins */ diff --git a/packages/core/data-transfer/src/commands/transfer/__tests__/transfer.test.ts b/packages/core/strapi/src/cli/commands/transfer/__tests__/transfer.test.ts similarity index 76% rename from packages/core/data-transfer/src/commands/transfer/__tests__/transfer.test.ts rename to packages/core/strapi/src/cli/commands/transfer/__tests__/transfer.test.ts index df2ba88d93..7e42310724 100644 --- a/packages/core/data-transfer/src/commands/transfer/__tests__/transfer.test.ts +++ b/packages/core/strapi/src/cli/commands/transfer/__tests__/transfer.test.ts @@ -1,10 +1,11 @@ +import * as mockDataTransfer from '@strapi/data-transfer'; + import transferAction from '../action'; import { expectExit } from '../../__tests__/commands.test.utils'; -import * as mockDataTransfer from '../../..'; -jest.mock('../../data-transfer', () => { +jest.mock('../../../utils/data-transfer', () => { return { - ...jest.requireActual('../../data-transfer'), + ...jest.requireActual('../../../utils/data-transfer'), getTransferTelemetryPayload: jest.fn().mockReturnValue({}), loadersFactory: jest.fn().mockReturnValue({ updateLoader: jest.fn() }), formatDiagnostic: jest.fn(), @@ -31,44 +32,46 @@ jest.mock('../../data-transfer', () => { }); // mock data transfer -jest.mock('../../../engine', () => { - const acutal = jest.requireActual('../../../engine'); +jest.mock('@strapi/data-transfer', () => { + const acutal = jest.requireActual('@strapi/data-transfer'); return { ...acutal, - createTransferEngine() { - return { - transfer: jest.fn(() => { - return { - engine: {}, - }; - }), - progress: { - on: jest.fn(), - stream: { - on: jest.fn(), - }, - }, - sourceProvider: { name: 'testSource' }, - destinationProvider: { name: 'testDestination' }, - diagnostics: { - on: jest.fn().mockReturnThis(), - onDiagnostic: jest.fn().mockReturnThis(), - }, - onSchemaDiff: jest.fn(), - addErrorHandler: jest.fn(), - }; + strapi: { + ...acutal.strapi, + providers: { + ...acutal.strapi.providers, + createLocalStrapiSourceProvider: jest.fn().mockReturnValue({ name: 'testLocalSource' }), + createLocalStrapiDestinationProvider: jest.fn().mockReturnValue({ name: 'testLocalDest' }), + createRemoteStrapiDestinationProvider: jest + .fn() + .mockReturnValue({ name: 'testRemoteDest' }), + }, }, - }; -}); - -jest.mock('../../../strapi', () => { - const actual = jest.requireActual('../../../strapi'); - return { - ...actual, - providers: { - createLocalStrapiSourceProvider: jest.fn().mockReturnValue({ name: 'testLocalSource' }), - createLocalStrapiDestinationProvider: jest.fn().mockReturnValue({ name: 'testLocalDest' }), - createRemoteStrapiDestinationProvider: jest.fn().mockReturnValue({ name: 'testRemoteDest' }), + engine: { + ...acutal.engine, + createTransferEngine() { + return { + transfer: jest.fn(() => { + return { + engine: {}, + }; + }), + progress: { + on: jest.fn(), + stream: { + on: jest.fn(), + }, + }, + sourceProvider: { name: 'testSource' }, + destinationProvider: { name: 'testDestination' }, + diagnostics: { + on: jest.fn().mockReturnThis(), + onDiagnostic: jest.fn().mockReturnThis(), + }, + onSchemaDiff: jest.fn(), + addErrorHandler: jest.fn(), + }; + }, }, }; }); diff --git a/packages/core/data-transfer/src/commands/transfer/action.ts b/packages/core/strapi/src/cli/commands/transfer/action.ts similarity index 92% rename from packages/core/data-transfer/src/commands/transfer/action.ts rename to packages/core/strapi/src/cli/commands/transfer/action.ts index 8575351bf4..d5f7c6b476 100644 --- a/packages/core/data-transfer/src/commands/transfer/action.ts +++ b/packages/core/strapi/src/cli/commands/transfer/action.ts @@ -1,6 +1,5 @@ import { isObject } from 'lodash/fp'; -import * as engineDatatransfer from '../../engine'; -import * as strapiDatatransfer from '../../strapi'; +import { engine as engineDataTransfer, strapi as strapiDataTransfer } from '@strapi/data-transfer'; import { buildTransferTable, @@ -15,10 +14,10 @@ import { getDiffHandler, getAssetsBackupHandler, parseRestoreFromOptions, -} from '../data-transfer'; -import { exitWith } from '../helpers'; +} from '../../utils/data-transfer'; +import { exitWith } from '../../utils/helpers'; -const { createTransferEngine } = engineDatatransfer; +const { createTransferEngine } = engineDataTransfer; const { providers: { createRemoteStrapiDestinationProvider, @@ -26,15 +25,15 @@ const { createLocalStrapiDestinationProvider, createRemoteStrapiSourceProvider, }, -} = strapiDatatransfer; +} = strapiDataTransfer; interface CmdOptions { from?: URL; fromToken: string; to: URL; toToken: string; - only?: (keyof engineDatatransfer.TransferGroupFilter)[]; - exclude?: (keyof engineDatatransfer.TransferGroupFilter)[]; + only?: (keyof engineDataTransfer.TransferGroupFilter)[]; + exclude?: (keyof engineDataTransfer.TransferGroupFilter)[]; throttle?: number; force?: boolean; } diff --git a/packages/core/data-transfer/src/commands/transfer/command.ts b/packages/core/strapi/src/cli/commands/transfer/command.ts similarity index 94% rename from packages/core/data-transfer/src/commands/transfer/command.ts rename to packages/core/strapi/src/cli/commands/transfer/command.ts index a7874053d4..2f39d706c2 100644 --- a/packages/core/data-transfer/src/commands/transfer/command.ts +++ b/packages/core/strapi/src/cli/commands/transfer/command.ts @@ -1,8 +1,14 @@ import inquirer from 'inquirer'; import { createCommand, Option } from 'commander'; -import { getCommanderConfirmMessage, forceOption, parseURL } from '../commander'; -import { exitWith, assertUrlHasProtocol, ifOptions } from '../helpers'; -import { excludeOption, onlyOption, throttleOption, validateExcludeOnly } from '../data-transfer'; +import { getCommanderConfirmMessage, forceOption, parseURL } from '../../utils/commander'; +import { exitWith, assertUrlHasProtocol, ifOptions } from '../../utils/helpers'; +import { + excludeOption, + onlyOption, + throttleOption, + validateExcludeOnly, +} from '../../utils/data-transfer'; + import action from './action'; /** diff --git a/packages/core/strapi/src/cli/index.ts b/packages/core/strapi/src/cli/index.ts index 250ca48d6c..2c9d64f048 100644 --- a/packages/core/strapi/src/cli/index.ts +++ b/packages/core/strapi/src/cli/index.ts @@ -7,15 +7,6 @@ import { loadTsConfig } from './utils/tsconfig'; import { CLIContext } from './types'; const createCLI = async (argv: string[], command = new Command()) => { - try { - // NOTE: this is a hack to allow loading dts commands without make dts a dependency of strapi and thus avoiding circular dependencies - // eslint-disable-next-line @typescript-eslint/no-var-requires - const dtsCommands = require(require.resolve('@strapi/data-transfer')).commands; - strapiCommands.push(...dtsCommands); - } catch (e) { - // noop - } - // Initial program setup command.storeOptionsAsProperties(false).allowUnknownOption(true); diff --git a/packages/core/data-transfer/src/commands/data-transfer.ts b/packages/core/strapi/src/cli/utils/data-transfer.ts similarity index 90% rename from packages/core/data-transfer/src/commands/data-transfer.ts rename to packages/core/strapi/src/cli/utils/data-transfer.ts index 62a705af88..96485d52de 100644 --- a/packages/core/data-transfer/src/commands/data-transfer.ts +++ b/packages/core/strapi/src/cli/utils/data-transfer.ts @@ -6,15 +6,14 @@ import { strapiFactory } from '@strapi/core'; import ora from 'ora'; import { merge } from 'lodash/fp'; import type { LoadedStrapi, Strapi } from '@strapi/types'; +import { engine as engineDataTransfer, strapi as strapiDataTransfer } from '@strapi/data-transfer'; import { readableBytes, exitWith } from './helpers'; import { getParseListWithChoices, parseInteger, confirmMessage } from './commander'; -import * as engineDatatransfer from '../engine'; -import * as strapiDataTransfer from '../strapi'; const { errors: { TransferEngineInitializationError }, -} = engineDatatransfer; +} = engineDataTransfer; const exitMessageText = (process: string, error = false) => { const processCapitalized = process[0].toUpperCase() + process.slice(1); @@ -49,9 +48,9 @@ const getDefaultExportName = () => { return `export_${yyyymmddHHMMSS()}`; }; -type ResultData = engineDatatransfer.ITransferResults< - engineDatatransfer.ISourceProvider, - engineDatatransfer.IDestinationProvider +type ResultData = engineDataTransfer.ITransferResults< + engineDataTransfer.ISourceProvider, + engineDataTransfer.IDestinationProvider >['engine']; const buildTransferTable = (resultData: ResultData) => { @@ -66,7 +65,7 @@ const buildTransferTable = (resultData: ResultData) => { let totalBytes = 0; let totalItems = 0; - (Object.keys(resultData) as engineDatatransfer.TransferStage[]).forEach((stage) => { + (Object.keys(resultData) as engineDataTransfer.TransferStage[]).forEach((stage) => { const item = resultData[stage]; if (!item) { @@ -123,7 +122,7 @@ const abortTransfer = async ({ engine, strapi, }: { - engine: engineDatatransfer.TransferEngine; + engine: engineDataTransfer.TransferEngine; strapi: LoadedStrapi; }) => { try { @@ -166,7 +165,7 @@ const createStrapiInstance = async ( } }; -const transferDataTypes = Object.keys(engineDatatransfer.TransferGroupPresets); +const transferDataTypes = Object.keys(engineDataTransfer.TransferGroupPresets); const throttleOption = new Option( '--throttle ', @@ -213,7 +212,7 @@ const errorColors = { const formatDiagnostic = ( operation: string - ): Parameters[0] => + ): Parameters[0] => ({ details, kind }) => { const logger = createLogger( configs.createOutputFileConfiguration(`${operation}_error_log_${Date.now()}.log`) @@ -245,11 +244,11 @@ const formatDiagnostic = }; type Loaders = { - [key in engineDatatransfer.TransferStage]: ora.Ora; + [key in engineDataTransfer.TransferStage]: ora.Ora; }; type Data = { - [key in engineDatatransfer.TransferStage]?: { + [key in engineDataTransfer.TransferStage]?: { startTime?: number; endTime?: number; bytes?: number; @@ -259,7 +258,7 @@ type Data = { const loadersFactory = (defaultLoaders: Loaders = {} as Loaders) => { const loaders = defaultLoaders; - const updateLoader = (stage: engineDatatransfer.TransferStage, data: Data) => { + const updateLoader = (stage: engineDataTransfer.TransferStage, data: Data) => { if (!(stage in loaders)) { createLoader(stage); } @@ -280,12 +279,12 @@ const loadersFactory = (defaultLoaders: Loaders = {} as Loaders) => { return loaders[stage]; }; - const createLoader = (stage: engineDatatransfer.TransferStage) => { + const createLoader = (stage: engineDataTransfer.TransferStage) => { Object.assign(loaders, { [stage]: ora() }); return loaders[stage]; }; - const getLoader = (stage: engineDatatransfer.TransferStage) => { + const getLoader = (stage: engineDataTransfer.TransferStage) => { return loaders[stage]; }; @@ -299,7 +298,7 @@ const loadersFactory = (defaultLoaders: Loaders = {} as Loaders) => { /** * Get the telemetry data to be sent for a didDEITSProcess* event from an initialized transfer engine object */ -const getTransferTelemetryPayload = (engine: engineDatatransfer.TransferEngine) => { +const getTransferTelemetryPayload = (engine: engineDataTransfer.TransferEngine) => { return { eventProperties: { source: engine?.sourceProvider?.name, @@ -312,7 +311,7 @@ const getTransferTelemetryPayload = (engine: engineDatatransfer.TransferEngine) * Get a transfer engine schema diff handler that confirms with the user before bypassing a schema check */ const getDiffHandler = ( - engine: engineDatatransfer.TransferEngine, + engine: engineDataTransfer.TransferEngine, { force, action, @@ -322,8 +321,8 @@ const getDiffHandler = ( } ) => { return async ( - context: engineDatatransfer.SchemaDiffHandlerContext, - next: (ctx: engineDatatransfer.SchemaDiffHandlerContext) => void + context: engineDataTransfer.SchemaDiffHandlerContext, + next: (ctx: engineDataTransfer.SchemaDiffHandlerContext) => void ) => { // if we abort here, we need to actually exit the process because of conflict with inquirer prompt setSignalHandler(async () => { @@ -395,7 +394,7 @@ const getDiffHandler = ( }; const getAssetsBackupHandler = ( - engine: engineDatatransfer.TransferEngine, + engine: engineDataTransfer.TransferEngine, { force, action, @@ -405,8 +404,8 @@ const getAssetsBackupHandler = ( } ) => { return async ( - context: engineDatatransfer.ErrorHandlerContext, - next: (ctx: engineDatatransfer.ErrorHandlerContext) => void + context: engineDataTransfer.ErrorHandlerContext, + next: (ctx: engineDataTransfer.ErrorHandlerContext) => void ) => { // if we abort here, we need to actually exit the process because of conflict with inquirer prompt setSignalHandler(async () => { @@ -435,8 +434,8 @@ const getAssetsBackupHandler = ( }; const shouldSkipStage = ( - opts: Partial, - dataKind: engineDatatransfer.TransferFilterPreset + opts: Partial, + dataKind: engineDataTransfer.TransferFilterPreset ) => { if (opts.exclude?.includes(dataKind)) { return true; @@ -453,7 +452,7 @@ type RestoreConfig = NonNullable< >; // Based on exclude/only from options, create the restore object to match -const parseRestoreFromOptions = (opts: Partial) => { +const parseRestoreFromOptions = (opts: Partial) => { const entitiesOptions: RestoreConfig['entities'] = { exclude: DEFAULT_IGNORED_CONTENT_TYPES, include: undefined, diff --git a/yarn.lock b/yarn.lock index 9c7ccd5689..0a9defd722 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9439,7 +9439,6 @@ __metadata: version: 0.0.0-use.local resolution: "@strapi/data-transfer@workspace:packages/core/data-transfer" dependencies: - "@strapi/core": "npm:4.17.1" "@strapi/logger": "npm:4.17.1" "@strapi/pack-up": "npm:4.17.1" "@strapi/types": "npm:4.17.1"