@strapi/strapi 4.10.0-beta.0 → 4.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.js +4 -0
  3. package/bin/strapi.js +2 -455
  4. package/ee/LICENSE.txt +21 -0
  5. package/ee/index.js +42 -5
  6. package/ee/license.js +11 -8
  7. package/lib/Strapi.js +14 -7
  8. package/lib/commands/{admin-create.js → actions/admin/create-user/action.js} +2 -2
  9. package/lib/commands/actions/admin/create-user/command.js +19 -0
  10. package/lib/commands/{admin-reset.js → actions/admin/reset-user-password/action.js} +2 -2
  11. package/lib/commands/actions/admin/reset-user-password/command.js +17 -0
  12. package/lib/commands/{configurationDump.js → actions/configuration/dump/action.js} +1 -1
  13. package/lib/commands/actions/configuration/dump/command.js +17 -0
  14. package/lib/commands/{configurationRestore.js → actions/configuration/restore/action.js} +1 -1
  15. package/lib/commands/actions/configuration/restore/command.js +17 -0
  16. package/lib/commands/{console.js → actions/console/action.js} +2 -2
  17. package/lib/commands/actions/console/command.js +14 -0
  18. package/lib/commands/{content-types/list.js → actions/content-types/list/action.js} +2 -2
  19. package/lib/commands/actions/content-types/list/command.js +14 -0
  20. package/lib/commands/{controllers/list.js → actions/controllers/list/action.js} +2 -2
  21. package/lib/commands/actions/controllers/list/command.js +14 -0
  22. package/lib/commands/{develop.js → actions/develop/action.js} +3 -3
  23. package/lib/commands/actions/develop/command.js +19 -0
  24. package/lib/commands/{transfer/export.js → actions/export/action.js} +27 -19
  25. package/lib/commands/actions/export/command.js +45 -0
  26. package/lib/commands/actions/generate/command.js +18 -0
  27. package/lib/commands/{hooks/list.js → actions/hooks/list/action.js} +2 -2
  28. package/lib/commands/actions/hooks/list/command.js +14 -0
  29. package/lib/commands/{transfer/import.js → actions/import/action.js} +39 -18
  30. package/lib/commands/actions/import/command.js +97 -0
  31. package/lib/commands/{install.js → actions/install/action.js} +1 -1
  32. package/lib/commands/actions/install/command.js +14 -0
  33. package/lib/commands/{middlewares/list.js → actions/middlewares/list/action.js} +2 -2
  34. package/lib/commands/actions/middlewares/list/command.js +14 -0
  35. package/lib/commands/{new.js → actions/new/action.js} +1 -1
  36. package/lib/commands/actions/new/command.js +35 -0
  37. package/lib/commands/{policies/list.js → actions/policies/list/action.js} +2 -2
  38. package/lib/commands/actions/policies/list/command.js +14 -0
  39. package/lib/commands/actions/report/action.js +35 -0
  40. package/lib/commands/actions/report/command.js +17 -0
  41. package/lib/commands/{routes/list.js → actions/routes/list/action.js} +2 -2
  42. package/lib/commands/actions/routes/list/command.js +14 -0
  43. package/lib/commands/{services/list.js → actions/services/list/action.js} +2 -2
  44. package/lib/commands/actions/services/list/command.js +14 -0
  45. package/lib/commands/{start.js → actions/start/action.js} +1 -1
  46. package/lib/commands/actions/start/command.js +14 -0
  47. package/lib/commands/{opt-out-telemetry.js → actions/telemetry/disable/action.js} +1 -1
  48. package/lib/commands/actions/telemetry/disable/command.js +14 -0
  49. package/lib/commands/{opt-in-telemetry.js → actions/telemetry/enable/action.js} +1 -1
  50. package/lib/commands/actions/telemetry/enable/command.js +14 -0
  51. package/lib/commands/actions/templates/generate/command.js +14 -0
  52. package/lib/commands/{transfer/transfer.js → actions/transfer/action.js} +61 -14
  53. package/lib/commands/actions/transfer/command.js +115 -0
  54. package/lib/commands/{ts/generate-types.js → actions/ts/generate-types/action.js} +2 -2
  55. package/lib/commands/actions/ts/generate-types/command.js +21 -0
  56. package/lib/commands/{uninstall.js → actions/uninstall/action.js} +1 -1
  57. package/lib/commands/actions/uninstall/command.js +15 -0
  58. package/lib/commands/actions/version/command.js +19 -0
  59. package/lib/commands/{watchAdmin.js → actions/watch-admin/action.js} +4 -4
  60. package/lib/commands/actions/watch-admin/command.js +15 -0
  61. package/lib/commands/index.js +66 -0
  62. package/lib/commands/utils/commander.js +14 -0
  63. package/lib/commands/{transfer/utils.js → utils/data-transfer.js} +54 -5
  64. package/lib/commands/utils/helpers.js +54 -3
  65. package/lib/core/domain/content-type/validator.js +1 -1
  66. package/lib/core/loaders/plugins/index.js +7 -2
  67. package/lib/core/registries/custom-fields.js +19 -2
  68. package/lib/core/registries/policies.d.ts +3 -3
  69. package/lib/core-api/controller/collection-type.js +0 -1
  70. package/lib/core-api/controller/index.js +1 -1
  71. package/lib/factories.js +3 -4
  72. package/lib/middlewares/logger.js +1 -17
  73. package/lib/middlewares/security.js +1 -1
  74. package/lib/services/event-hub.js +6 -1
  75. package/lib/services/metrics/index.js +1 -0
  76. package/lib/services/metrics/sender.js +1 -14
  77. package/lib/services/server/index.js +2 -2
  78. package/lib/services/server/register-routes.js +1 -1
  79. package/lib/services/utils/dynamic-zones.js +13 -0
  80. package/lib/services/webhook-runner.js +4 -4
  81. package/lib/types/core/commands/index.d.ts +6 -0
  82. package/lib/utils/fetch.js +23 -0
  83. package/package.json +22 -21
  84. package/lib/commands/build.js +0 -18
  85. /package/lib/commands/{generate-template.js → actions/templates/generate/action.js} +0 -0
@@ -0,0 +1,97 @@
1
+ 'use strict';
2
+
3
+ const { Option } = require('commander');
4
+ const path = require('path');
5
+ const inquirer = require('inquirer');
6
+ const {
7
+ excludeOption,
8
+ onlyOption,
9
+ throttleOption,
10
+ validateExcludeOnly,
11
+ } = require('../../utils/data-transfer');
12
+ const { confirmMessage, forceOption } = require('../../utils/commander');
13
+ const { getLocalScript, exitWith } = require('../../utils/helpers');
14
+
15
+ /**
16
+ * `$ strapi import`
17
+ * @param {import('../../../types/core/commands').AddCommandOptions} options
18
+ */
19
+ module.exports = ({ command }) => {
20
+ command
21
+ .command('import')
22
+ .description('Import data from file to Strapi')
23
+ .allowExcessArguments(false)
24
+ .requiredOption(
25
+ '-f, --file <file>',
26
+ 'path and filename for the Strapi export file you want to import'
27
+ )
28
+ .addOption(
29
+ new Option(
30
+ '-k, --key <string>',
31
+ 'Provide encryption key in command instead of using the prompt'
32
+ )
33
+ )
34
+ .addOption(forceOption)
35
+ .addOption(excludeOption)
36
+ .addOption(onlyOption)
37
+ .addOption(throttleOption)
38
+ .hook('preAction', validateExcludeOnly)
39
+ .hook('preAction', async (thisCommand) => {
40
+ const opts = thisCommand.opts();
41
+ const ext = path.extname(String(opts.file));
42
+
43
+ // check extension to guess if we should prompt for key
44
+ if (ext === '.enc') {
45
+ if (!opts.key) {
46
+ const answers = await inquirer.prompt([
47
+ {
48
+ type: 'password',
49
+ message: 'Please enter your decryption key',
50
+ name: 'key',
51
+ },
52
+ ]);
53
+ if (!answers.key?.length) {
54
+ exitWith(1, 'No key entered, aborting import.');
55
+ }
56
+ opts.key = answers.key;
57
+ }
58
+ }
59
+ })
60
+ // set decrypt and decompress options based on filename
61
+ .hook('preAction', (thisCommand) => {
62
+ const opts = thisCommand.opts();
63
+
64
+ const { extname, parse } = path;
65
+
66
+ let file = opts.file;
67
+
68
+ if (extname(file) === '.enc') {
69
+ file = parse(file).name; // trim the .enc extension
70
+ thisCommand.opts().decrypt = true;
71
+ } else {
72
+ thisCommand.opts().decrypt = false;
73
+ }
74
+
75
+ if (extname(file) === '.gz') {
76
+ file = parse(file).name; // trim the .gz extension
77
+ thisCommand.opts().decompress = true;
78
+ } else {
79
+ thisCommand.opts().decompress = false;
80
+ }
81
+
82
+ if (extname(file) !== '.tar') {
83
+ exitWith(
84
+ 1,
85
+ `The file '${opts.file}' does not appear to be a valid Strapi data file. It must have an extension ending in .tar[.gz][.enc]`
86
+ );
87
+ }
88
+ })
89
+ .hook(
90
+ 'preAction',
91
+ confirmMessage(
92
+ 'The import will delete all assets and data in your database. Are you sure you want to proceed?',
93
+ { failMessage: 'Import process aborted' }
94
+ )
95
+ )
96
+ .action(getLocalScript('import'));
97
+ };
@@ -4,7 +4,7 @@ const { join } = require('path');
4
4
  const { existsSync } = require('fs-extra');
5
5
  const ora = require('ora');
6
6
  const execa = require('execa');
7
- const findPackagePath = require('../load/package-path');
7
+ const findPackagePath = require('../../../load/package-path');
8
8
 
9
9
  module.exports = async (plugins) => {
10
10
  const loader = ora();
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const { getLocalScript } = require('../../utils/helpers');
4
+
5
+ /**
6
+ * `$ strapi install`
7
+ * @param {import('../../../types/core/commands').AddCommandOptions} options
8
+ */
9
+ module.exports = ({ command }) => {
10
+ command
11
+ .command('install [plugins...]')
12
+ .description('Install a Strapi plugin')
13
+ .action(getLocalScript('install'));
14
+ };
@@ -3,9 +3,9 @@
3
3
  const CLITable = require('cli-table3');
4
4
  const chalk = require('chalk');
5
5
 
6
- const strapi = require('../../index');
6
+ const strapi = require('../../../../index');
7
7
 
8
- module.exports = async function () {
8
+ module.exports = async () => {
9
9
  const appContext = await strapi.compile();
10
10
  const app = await strapi(appContext).register();
11
11
 
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const { getLocalScript } = require('../../../utils/helpers');
4
+
5
+ /**
6
+ * `$ strapi middlewares:list`
7
+ * @param {import('../../../../types/core/commands').AddCommandOptions} options
8
+ */
9
+ module.exports = ({ command }) => {
10
+ command
11
+ .command('middlewares:list')
12
+ .description('List all the application middlewares')
13
+ .action(getLocalScript('middlewares/list'));
14
+ };
@@ -8,6 +8,6 @@ const { generateNewApp } = require('@strapi/generate-new');
8
8
  * Generate a new Strapi application.
9
9
  */
10
10
 
11
- module.exports = function (...args) {
11
+ module.exports = (...args) => {
12
12
  return generateNewApp(...args);
13
13
  };
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ const { yellow } = require('chalk');
4
+
5
+ /**
6
+ * `$ strapi new`
7
+ * @param {import('../../../types/core/commands').AddCommandOptions} options
8
+ */
9
+ module.exports = ({ command }) => {
10
+ command
11
+ .command('new <directory>')
12
+ .option('--no-run', 'Do not start the application after it is created')
13
+ .option('--use-npm', 'Force usage of npm instead of yarn to create the project')
14
+ .option('--debug', 'Display database connection errors')
15
+ .option('--quickstart', 'Create quickstart app')
16
+ .option('--dbclient <dbclient>', 'Database client')
17
+ .option('--dbhost <dbhost>', 'Database host')
18
+ .option('--dbport <dbport>', 'Database port')
19
+ .option('--dbname <dbname>', 'Database name')
20
+ .option('--dbusername <dbusername>', 'Database username')
21
+ .option('--dbpassword <dbpassword>', 'Database password')
22
+ .option('--dbssl <dbssl>', 'Database SSL')
23
+ .option('--dbfile <dbfile>', 'Database file path for sqlite')
24
+ .option('--dbforce', 'Allow overwriting existing database content')
25
+ .option('-ts, --typescript', 'Create a typescript project')
26
+ .description('Create a new application')
27
+ .hook('preAction', () => {
28
+ console.warn(
29
+ yellow(
30
+ 'The `strapi new` command has been deprecated in v4 and will be removed in v5. `create-strapi-app` should be used to create a new Strapi project.'
31
+ )
32
+ );
33
+ })
34
+ .action(require('./action'));
35
+ };
@@ -3,9 +3,9 @@
3
3
  const CLITable = require('cli-table3');
4
4
  const chalk = require('chalk');
5
5
 
6
- const strapi = require('../../index');
6
+ const strapi = require('../../../../index');
7
7
 
8
- module.exports = async function () {
8
+ module.exports = async () => {
9
9
  const appContext = await strapi.compile();
10
10
  const app = await strapi(appContext).register();
11
11
 
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const { getLocalScript } = require('../../../utils/helpers');
4
+
5
+ /**
6
+ * `$ strapi policies:list`
7
+ * @param {import('../../../../types/core/commands').AddCommandOptions} options
8
+ */
9
+ module.exports = ({ command }) => {
10
+ command
11
+ .command('policies:list')
12
+ .description('List all the application policies')
13
+ .action(getLocalScript('policies/list'));
14
+ };
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ const { EOL } = require('os');
4
+ const strapi = require('../../../index');
5
+
6
+ module.exports = async ({ uuid, dependencies, all }) => {
7
+ const config = {
8
+ reportUUID: Boolean(all || uuid),
9
+ reportDependencies: Boolean(all || dependencies),
10
+ };
11
+
12
+ const appContext = await strapi.compile();
13
+ const app = await strapi(appContext).register();
14
+
15
+ let debugInfo = `Launched In: ${Date.now() - app.config.launchedAt} ms
16
+ Environment: ${app.config.environment}
17
+ OS: ${process.platform}-${process.arch}
18
+ Strapi Version: ${app.config.info.strapi}
19
+ Node/Yarn Version: ${process.env.npm_config_user_agent}
20
+ Edition: ${app.EE ? 'Enterprise' : 'Community'}
21
+ Database: ${app?.config?.database?.connection?.client ?? 'unknown'}`;
22
+
23
+ if (config.reportUUID) {
24
+ debugInfo += `${EOL}UUID: ${app.config.uuid}`;
25
+ }
26
+
27
+ if (config.reportDependencies) {
28
+ debugInfo += `${EOL}Dependencies: ${JSON.stringify(app.config.info.dependencies, null, 2)}
29
+ Dev Dependencies: ${JSON.stringify(app.config.info.devDependencies, null, 2)}`;
30
+ }
31
+
32
+ console.log(debugInfo);
33
+
34
+ await app.destroy();
35
+ };
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ const { getLocalScript } = require('../../utils/helpers');
4
+
5
+ /**
6
+ * `$ strapi report`
7
+ * @param {import('../../../types/core/commands').AddCommandOptions} options
8
+ */
9
+ module.exports = ({ command }) => {
10
+ command
11
+ .command('report')
12
+ .description('Get system stats for debugging and submitting issues')
13
+ .option('-u, --uuid', 'Include Project UUID')
14
+ .option('-d, --dependencies', 'Include Project Dependencies')
15
+ .option('--all', 'Include All Information')
16
+ .action(getLocalScript('report'));
17
+ };
@@ -4,9 +4,9 @@ const CLITable = require('cli-table3');
4
4
  const chalk = require('chalk');
5
5
  const { toUpper } = require('lodash/fp');
6
6
 
7
- const strapi = require('../../index');
7
+ const strapi = require('../../../../index');
8
8
 
9
- module.exports = async function () {
9
+ module.exports = async () => {
10
10
  const appContext = await strapi.compile();
11
11
  const app = await strapi(appContext).load();
12
12
 
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const { getLocalScript } = require('../../../utils/helpers');
4
+
5
+ /**
6
+ * `$ strapi routes:list``
7
+ * @param {import('../../../../types/core/commands').AddCommandOptions} options
8
+ */
9
+ module.exports = ({ command }) => {
10
+ command
11
+ .command('routes:list')
12
+ .description('List all the application routes')
13
+ .action(getLocalScript('routes/list'));
14
+ };
@@ -3,9 +3,9 @@
3
3
  const CLITable = require('cli-table3');
4
4
  const chalk = require('chalk');
5
5
 
6
- const strapi = require('../../index');
6
+ const strapi = require('../../../../index');
7
7
 
8
- module.exports = async function () {
8
+ module.exports = async () => {
9
9
  const appContext = await strapi.compile();
10
10
  const app = await strapi(appContext).register();
11
11
 
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const { getLocalScript } = require('../../../utils/helpers');
4
+
5
+ /**
6
+ * `$ strapi services:list`
7
+ * @param {import('../../../../types/core/commands').AddCommandOptions} options
8
+ */
9
+ module.exports = ({ command }) => {
10
+ command
11
+ .command('services:list')
12
+ .description('List all the application services')
13
+ .action(getLocalScript('services/list'));
14
+ };
@@ -2,7 +2,7 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const tsUtils = require('@strapi/typescript-utils');
5
- const strapi = require('../index');
5
+ const strapi = require('../../../index');
6
6
 
7
7
  /**
8
8
  * `$ strapi start`
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const { getLocalScript } = require('../../utils/helpers');
4
+
5
+ /**
6
+ * `$ strapi start`
7
+ * @param {import('../../../types/core/commands').AddCommandOptions} options
8
+ */
9
+ module.exports = ({ command }) => {
10
+ command
11
+ .command('start')
12
+ .description('Start your Strapi application')
13
+ .action(getLocalScript('start'));
14
+ };
@@ -4,7 +4,7 @@ const { resolve } = require('path');
4
4
  const fse = require('fs-extra');
5
5
  const chalk = require('chalk');
6
6
  const fetch = require('node-fetch');
7
- const machineID = require('../utils/machine-id');
7
+ const machineID = require('../../../../utils/machine-id');
8
8
 
9
9
  const readPackageJSON = async (path) => {
10
10
  try {
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const { getLocalScript } = require('../../../utils/helpers');
4
+
5
+ /**
6
+ * `$ strapi telemetry:disable`
7
+ * @param {import('../../../../types/core/commands').AddCommandOptions} options
8
+ */
9
+ module.exports = ({ command }) => {
10
+ command
11
+ .command('telemetry:disable')
12
+ .description('Disable anonymous telemetry and metadata sending to Strapi analytics')
13
+ .action(getLocalScript('telemetry/disable'));
14
+ };
@@ -5,7 +5,7 @@ const fse = require('fs-extra');
5
5
  const chalk = require('chalk');
6
6
  const fetch = require('node-fetch');
7
7
  const { v4: uuidv4 } = require('uuid');
8
- const machineID = require('../utils/machine-id');
8
+ const machineID = require('../../../../utils/machine-id');
9
9
 
10
10
  const readPackageJSON = async (path) => {
11
11
  try {
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const { getLocalScript } = require('../../../utils/helpers');
4
+
5
+ /**
6
+ * `$ strapi telemetry:enable`
7
+ * @param {import('../../../../types/core/commands').AddCommandOptions} options
8
+ */
9
+ module.exports = ({ command }) => {
10
+ command
11
+ .command('telemetry:enable')
12
+ .description('Enable anonymous telemetry and metadata sending to Strapi analytics')
13
+ .action(getLocalScript('telemetry/enable'));
14
+ };
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const { getLocalScript } = require('../../../utils/helpers');
4
+
5
+ /**
6
+ *`$ strapi templates:generate <directory>`
7
+ * @param {import('../../../../types/core/commands').AddCommandOptions} options
8
+ */
9
+ module.exports = ({ command }) => {
10
+ command
11
+ .command('templates:generate <directory>')
12
+ .description('Generate template from Strapi project')
13
+ .action(getLocalScript('templates/generate'));
14
+ };
@@ -7,11 +7,11 @@ const {
7
7
  createRemoteStrapiDestinationProvider,
8
8
  createLocalStrapiSourceProvider,
9
9
  createLocalStrapiDestinationProvider,
10
+ createRemoteStrapiSourceProvider,
10
11
  },
11
12
  },
12
13
  } = require('@strapi/data-transfer');
13
14
  const { isObject } = require('lodash/fp');
14
- const chalk = require('chalk');
15
15
 
16
16
  const {
17
17
  buildTransferTable,
@@ -19,8 +19,11 @@ const {
19
19
  DEFAULT_IGNORED_CONTENT_TYPES,
20
20
  formatDiagnostic,
21
21
  loadersFactory,
22
- } = require('./utils');
23
- const { exitWith } = require('../utils/helpers');
22
+ exitMessageText,
23
+ abortTransfer,
24
+ getTransferTelemetryPayload,
25
+ } = require('../../utils/data-transfer');
26
+ const { exitWith } = require('../../utils/helpers');
24
27
 
25
28
  /**
26
29
  * @typedef TransferCommandOptions Options given to the CLI transfer command
@@ -29,6 +32,9 @@ const { exitWith } = require('../utils/helpers');
29
32
  * @property {URL|undefined} [from] The url of a remote Strapi to use as remote source
30
33
  * @property {string|undefined} [toToken] The transfer token for the remote Strapi destination
31
34
  * @property {string|undefined} [fromToken] The transfer token for the remote Strapi source
35
+ * @property {(keyof import('@strapi/data-transfer/src/engine').TransferGroupFilter)[]} [only] If present, only include these filtered groups of data
36
+ * @property {(keyof import('@strapi/data-transfer/src/engine').TransferGroupFilter)[]} [exclude] If present, exclude these filtered groups of data
37
+ * @property {number|undefined} [throttle] Delay in ms after each record
32
38
  */
33
39
 
34
40
  /**
@@ -44,15 +50,14 @@ module.exports = async (opts) => {
44
50
  exitWith(1, 'Could not parse command arguments');
45
51
  }
46
52
 
47
- const strapi = await createStrapiInstance();
53
+ if (!(opts.from || opts.to) || (opts.from && opts.to)) {
54
+ exitWith(1, 'Exactly one source (from) or destination (to) option must be provided');
55
+ }
48
56
 
57
+ const strapi = await createStrapiInstance();
49
58
  let source;
50
59
  let destination;
51
60
 
52
- if (!opts.from && !opts.to) {
53
- exitWith(1, 'At least one source (from) or destination (to) option must be provided');
54
- }
55
-
56
61
  // if no URL provided, use local Strapi
57
62
  if (!opts.from) {
58
63
  source = createLocalStrapiSourceProvider({
@@ -61,13 +66,28 @@ module.exports = async (opts) => {
61
66
  }
62
67
  // if URL provided, set up a remote source provider
63
68
  else {
64
- exitWith(1, `Remote Strapi source provider not yet implemented`);
69
+ if (!opts.fromToken) {
70
+ exitWith(1, 'Missing token for remote destination');
71
+ }
72
+
73
+ source = createRemoteStrapiSourceProvider({
74
+ getStrapi: () => strapi,
75
+ url: opts.from,
76
+ auth: {
77
+ type: 'token',
78
+ token: opts.fromToken,
79
+ },
80
+ });
65
81
  }
66
82
 
67
83
  // if no URL provided, use local Strapi
68
84
  if (!opts.to) {
69
85
  destination = createLocalStrapiDestinationProvider({
70
86
  getStrapi: () => strapi,
87
+ strategy: 'restore',
88
+ restore: {
89
+ entities: { exclude: DEFAULT_IGNORED_CONTENT_TYPES },
90
+ },
71
91
  });
72
92
  }
73
93
  // if URL provided, set up a remote destination provider
@@ -96,6 +116,9 @@ module.exports = async (opts) => {
96
116
  const engine = createTransferEngine(source, destination, {
97
117
  versionStrategy: 'exact',
98
118
  schemaStrategy: 'strict',
119
+ exclude: opts.exclude,
120
+ only: opts.only,
121
+ throttle: opts.throttle,
99
122
  transforms: {
100
123
  links: [
101
124
  {
@@ -135,15 +158,39 @@ module.exports = async (opts) => {
135
158
  updateLoader(stage, data);
136
159
  });
137
160
 
161
+ progress.on('stage::error', ({ stage, data }) => {
162
+ updateLoader(stage, data).fail();
163
+ });
164
+
165
+ progress.on('transfer::start', async () => {
166
+ console.log(`Starting transfer...`);
167
+
168
+ await strapi.telemetry.send('didDEITSProcessStart', getTransferTelemetryPayload(engine));
169
+ });
170
+
138
171
  let results;
139
172
  try {
140
- console.log(`Starting transfer...`);
173
+ // Abort transfer if user interrupts process
174
+ ['SIGTERM', 'SIGINT', 'SIGQUIT'].forEach((signal) => {
175
+ process.removeAllListeners(signal);
176
+ process.on(signal, () => abortTransfer({ engine, strapi }));
177
+ });
178
+
141
179
  results = await engine.transfer();
142
180
  } catch (e) {
143
- exitWith(1, 'Transfer process failed.');
181
+ await strapi.telemetry.send('didDEITSProcessFail', getTransferTelemetryPayload(engine));
182
+ exitWith(1, exitMessageText('transfer', true));
183
+ }
184
+
185
+ // Note: we need to await telemetry or else the process ends before it is sent
186
+ await strapi.telemetry.send('didDEITSProcessFinish', getTransferTelemetryPayload(engine));
187
+
188
+ try {
189
+ const table = buildTransferTable(results.engine);
190
+ console.log(table.toString());
191
+ } catch (e) {
192
+ console.error('There was an error displaying the results of the transfer.');
144
193
  }
145
194
 
146
- const table = buildTransferTable(results.engine);
147
- console.log(table.toString());
148
- exitWith(0, `${chalk.bold('Transfer process has been completed successfully!')}`);
195
+ exitWith(0, exitMessageText('transfer'));
149
196
  };