@strapi/strapi 4.7.0-beta.0 → 4.9.0-alpha.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.
package/bin/strapi.js CHANGED
@@ -18,9 +18,8 @@ const {
18
18
  promptEncryptionKey,
19
19
  confirmMessage,
20
20
  forceOption,
21
- parseURL,
22
21
  } = require('../lib/commands/utils/commander');
23
- const { exitWith, ifOptions, assertUrlHasProtocol } = require('../lib/commands/utils/helpers');
22
+ const { exitWith } = require('../lib/commands/utils/helpers');
24
23
  const {
25
24
  excludeOption,
26
25
  onlyOption,
@@ -273,88 +272,59 @@ program
273
272
  .option('-s, --silent', `Run the generation silently, without any output`, false)
274
273
  .action(getLocalScript('ts/generate-types'));
275
274
 
276
- // `$ strapi transfer`
277
- program
278
- .command('transfer')
279
- .description('Transfer data from one source to another')
280
- .allowExcessArguments(false)
281
- .addOption(
282
- new Option('--from <sourceURL>', `URL of the remote Strapi instance to get data from`)
283
- .argParser(parseURL)
284
- .hideHelp() // Hidden until pull feature is released
285
- )
286
- .addOption(
287
- new Option('--from-token <token>', `Transfer token for the remote Strapi source`).hideHelp() // Hidden until pull feature is released
288
- )
289
- .addOption(
290
- new Option(
291
- '--to <destinationURL>',
292
- `URL of the remote Strapi instance to send data to`
293
- ).argParser(parseURL)
294
- )
295
- .addOption(new Option('--to-token <token>', `Transfer token for the remote Strapi destination`))
296
- .addOption(forceOption)
297
- .addOption(excludeOption)
298
- .addOption(onlyOption)
299
- .hook('preAction', validateExcludeOnly)
300
- // If --from is used, validate the URL and token
301
- .hook(
302
- 'preAction',
303
- ifOptions(
304
- (opts) => opts.from,
305
- async (thisCommand) => {
306
- assertUrlHasProtocol(thisCommand.opts().from, ['https:', 'http:']);
307
- if (!thisCommand.opts().fromToken) {
308
- const answers = await inquirer.prompt([
309
- {
310
- type: 'password',
311
- message: 'Please enter your transfer token for the remote Strapi source',
312
- name: 'fromToken',
313
- },
314
- ]);
315
- if (!answers.fromToken?.length) {
316
- exitWith(0, 'No token entered, aborting transfer.');
317
- }
318
- thisCommand.opts().fromToken = answers.fromToken;
319
- }
320
- }
321
- )
322
- )
323
- // If --to is used, validate the URL, token, and confirm restore
324
- .hook(
325
- 'preAction',
326
- ifOptions(
327
- (opts) => opts.to,
328
- async (thisCommand) => {
329
- assertUrlHasProtocol(thisCommand.opts().to, ['https:', 'http:']);
330
- if (!thisCommand.opts().toToken) {
331
- const answers = await inquirer.prompt([
332
- {
333
- type: 'password',
334
- message: 'Please enter your transfer token for the remote Strapi destination',
335
- name: 'toToken',
336
- },
337
- ]);
338
- if (!answers.toToken?.length) {
339
- exitWith(0, 'No token entered, aborting transfer.');
340
- }
341
- thisCommand.opts().toToken = answers.toToken;
342
- }
343
-
344
- await confirmMessage(
345
- 'The transfer will delete all data in the remote database and media files. Are you sure you want to proceed?'
346
- )(thisCommand);
347
- }
348
- )
349
- )
350
- // .hook(
351
- // 'preAction',
352
- // ifOptions(
353
- // (opts) => !opts.from && !opts.to,
354
- // () => exitWith(1, 'At least one source (from) or destination (to) option must be provided')
355
- // )
356
- // )
357
- .action(getLocalScript('transfer/transfer'));
275
+ // if (process.env.STRAPI_EXPERIMENTAL === 'true') {
276
+ // // `$ strapi transfer`
277
+ // program
278
+ // .command('transfer')
279
+ // .description('Transfer data from one source to another')
280
+ // .allowExcessArguments(false)
281
+ // .addOption(
282
+ // new Option(
283
+ // '--from <sourceURL>',
284
+ // `URL of the remote Strapi instance to get data from`
285
+ // ).argParser(parseURL)
286
+ // )
287
+ // .addOption(
288
+ // new Option(
289
+ // '--to <destinationURL>',
290
+ // `URL of the remote Strapi instance to send data to`
291
+ // ).argParser(parseURL)
292
+ // )
293
+ // .addOption(forceOption)
294
+ // // Validate URLs
295
+ // .hook(
296
+ // 'preAction',
297
+ // ifOptions(
298
+ // (opts) => opts.from,
299
+ // (thisCommand) => assertUrlHasProtocol(thisCommand.opts().from, ['https:', 'http:'])
300
+ // )
301
+ // )
302
+ // .hook(
303
+ // 'preAction',
304
+ // ifOptions(
305
+ // (opts) => opts.to,
306
+ // (thisCommand) => assertUrlHasProtocol(thisCommand.opts().to, ['https:', 'http:'])
307
+ // )
308
+ // )
309
+ // .hook(
310
+ // 'preAction',
311
+ // ifOptions(
312
+ // (opts) => !opts.from && !opts.to,
313
+ // () => exitWith(1, 'At least one source (from) or destination (to) option must be provided')
314
+ // )
315
+ // )
316
+ // .addOption(forceOption)
317
+ // .addOption(excludeOption)
318
+ // .addOption(onlyOption)
319
+ // .hook('preAction', validateExcludeOnly)
320
+ // .hook(
321
+ // 'preAction',
322
+ // confirmMessage(
323
+ // 'The import will delete all data in the remote database. Are you sure you want to proceed?'
324
+ // )
325
+ // )
326
+ // .action(getLocalScript('transfer/transfer'));
327
+ // }
358
328
 
359
329
  // `$ strapi export`
360
330
  program
@@ -450,7 +420,7 @@ program
450
420
  .hook(
451
421
  'preAction',
452
422
  confirmMessage(
453
- 'The import will delete all data in your database and media files. Are you sure you want to proceed?'
423
+ 'The import will delete all data in your database. Are you sure you want to proceed?'
454
424
  )
455
425
  )
456
426
  .action(getLocalScript('transfer/import'));
package/ee/license.js CHANGED
@@ -10,7 +10,7 @@ const machineId = require('../lib/utils/machine-id');
10
10
  const DEFAULT_FEATURES = {
11
11
  bronze: [],
12
12
  silver: [],
13
- gold: ['sso', { name: 'audit-logs', options: { retentionDays: 90 } }],
13
+ gold: ['sso', { name: 'audit-logs', options: { retentionDays: 90 } }, 'review-workflows'],
14
14
  };
15
15
 
16
16
  const publicKey = fs.readFileSync(join(__dirname, 'resources/key.pub'));
@@ -19,7 +19,6 @@ const {
19
19
  createStrapiInstance,
20
20
  formatDiagnostic,
21
21
  } = require('./utils');
22
- const { exitWith } = require('../utils/helpers');
23
22
 
24
23
  /**
25
24
  * @typedef ExportCommandOptions Options given to the CLI import command
@@ -30,6 +29,8 @@ const { exitWith } = require('../utils/helpers');
30
29
  * @property {boolean} [compress] Used to compress the final archive
31
30
  */
32
31
 
32
+ const logger = console;
33
+
33
34
  const BYTES_IN_MB = 1024 * 1024;
34
35
 
35
36
  /**
@@ -42,7 +43,8 @@ const BYTES_IN_MB = 1024 * 1024;
42
43
  module.exports = async (opts) => {
43
44
  // Validate inputs from Commander
44
45
  if (!isObject(opts)) {
45
- exitWith(1, 'Could not parse command arguments');
46
+ logger.error('Could not parse command arguments');
47
+ process.exit(1);
46
48
  }
47
49
 
48
50
  const strapi = await createStrapiInstance();
@@ -90,34 +92,33 @@ module.exports = async (opts) => {
90
92
  };
91
93
 
92
94
  progress.on('transfer::start', async () => {
93
- console.log(`Starting export...`);
95
+ logger.log(`Starting export...`);
94
96
  await strapi.telemetry.send('didDEITSProcessStart', getTelemetryPayload());
95
97
  });
96
98
 
97
- let results;
98
- let outFile;
99
99
  try {
100
- results = await engine.transfer();
101
- outFile = results.destination.file.path;
100
+ const results = await engine.transfer();
101
+ const outFile = results.destination.file.path;
102
+
103
+ const table = buildTransferTable(results.engine);
104
+ logger.log(table.toString());
105
+
102
106
  const outFileExists = await fs.pathExists(outFile);
103
107
  if (!outFileExists) {
104
108
  throw new TransferEngineTransferError(`Export file not created "${outFile}"`);
105
109
  }
110
+
111
+ logger.log(`${chalk.bold('Export process has been completed successfully!')}`);
112
+ logger.log(`Export archive is in ${chalk.green(outFile)}`);
106
113
  } catch {
107
114
  await strapi.telemetry.send('didDEITSProcessFail', getTelemetryPayload());
108
- exitWith(1, 'Export process failed.');
115
+ logger.error('Export process failed.');
116
+ process.exit(1);
109
117
  }
110
118
 
119
+ // Note: Telemetry can't be sent in a finish event, because it runs async after this block but we can't await it, so if process.exit is used it won't send
111
120
  await strapi.telemetry.send('didDEITSProcessFinish', getTelemetryPayload());
112
- try {
113
- const table = buildTransferTable(results.engine);
114
- console.log(table.toString());
115
- } catch (e) {
116
- console.error('There was an error displaying the results of the transfer.');
117
- }
118
-
119
- console.log(`${chalk.bold('Export process has been completed successfully!')}`);
120
- exitWith(0, `Export archive is in ${chalk.green(outFile)}`);
121
+ process.exit(0);
121
122
  };
122
123
 
123
124
  /**
@@ -20,16 +20,18 @@ const {
20
20
  createStrapiInstance,
21
21
  formatDiagnostic,
22
22
  } = require('./utils');
23
- const { exitWith } = require('../utils/helpers');
24
23
 
25
24
  /**
26
25
  * @typedef {import('@strapi/data-transfer').ILocalFileSourceProviderOptions} ILocalFileSourceProviderOptions
27
26
  */
28
27
 
28
+ const logger = console;
29
+
29
30
  module.exports = async (opts) => {
30
31
  // validate inputs from Commander
31
32
  if (!isObject(opts)) {
32
- exitWith(1, 'Could not parse arguments');
33
+ logger.error('Could not parse arguments');
34
+ process.exit(1);
33
35
  }
34
36
 
35
37
  /**
@@ -98,30 +100,27 @@ module.exports = async (opts) => {
98
100
  };
99
101
 
100
102
  progress.on('transfer::start', async () => {
101
- console.log('Starting import...');
103
+ logger.info('Starting import...');
102
104
  await strapiInstance.telemetry.send('didDEITSProcessStart', getTelemetryPayload());
103
105
  });
104
106
 
105
- let results;
106
107
  try {
107
- results = await engine.transfer();
108
+ const results = await engine.transfer();
109
+ const table = buildTransferTable(results.engine);
110
+ logger.info(table.toString());
111
+
112
+ logger.info('Import process has been completed successfully!');
108
113
  } catch (e) {
109
114
  await strapiInstance.telemetry.send('didDEITSProcessFail', getTelemetryPayload());
110
- console.error('Import process failed.');
115
+ logger.error('Import process failed.');
111
116
  process.exit(1);
112
117
  }
113
118
 
114
- try {
115
- const table = buildTransferTable(results.engine);
116
- console.log(table.toString());
117
- } catch (e) {
118
- console.error('There was an error displaying the results of the transfer.');
119
- }
120
-
119
+ // Note: Telemetry can't be sent in a finish event, because it runs async after this block but we can't await it, so if process.exit is used it won't send
121
120
  await strapiInstance.telemetry.send('didDEITSProcessFinish', getTelemetryPayload());
122
121
  await strapiInstance.destroy();
123
122
 
124
- exitWith(0, 'Import process has been completed successfully!');
123
+ process.exit(0);
125
124
  };
126
125
 
127
126
  /**
@@ -17,28 +17,28 @@ const {
17
17
  DEFAULT_IGNORED_CONTENT_TYPES,
18
18
  formatDiagnostic,
19
19
  } = require('./utils');
20
- const { exitWith } = require('../utils/helpers');
20
+
21
+ const logger = console;
21
22
 
22
23
  /**
23
24
  * @typedef TransferCommandOptions Options given to the CLI transfer command
24
25
  *
25
26
  * @property {URL|undefined} [to] The url of a remote Strapi to use as remote destination
26
27
  * @property {URL|undefined} [from] The url of a remote Strapi to use as remote source
27
- * @property {string|undefined} [toToken] The transfer token for the remote Strapi destination
28
- * @property {string|undefined} [fromToken] The transfer token for the remote Strapi source
29
28
  */
30
29
 
31
30
  /**
32
31
  * Transfer command.
33
32
  *
34
- * Transfers data between local Strapi and remote Strapi instances
33
+ * It transfers data from a local file to a local strapi instance
35
34
  *
36
35
  * @param {TransferCommandOptions} opts
37
36
  */
38
37
  module.exports = async (opts) => {
39
38
  // Validate inputs from Commander
40
39
  if (!isObject(opts)) {
41
- exitWith(1, 'Could not parse command arguments');
40
+ logger.error('Could not parse command arguments');
41
+ process.exit(1);
42
42
  }
43
43
 
44
44
  const strapi = await createStrapiInstance();
@@ -47,7 +47,8 @@ module.exports = async (opts) => {
47
47
  let destination;
48
48
 
49
49
  if (!opts.from && !opts.to) {
50
- exitWith(1, 'At least one source (from) or destination (to) option must be provided');
50
+ logger.error('At least one source (from) or destination (to) option must be provided');
51
+ process.exit(1);
51
52
  }
52
53
 
53
54
  // if no URL provided, use local Strapi
@@ -58,7 +59,8 @@ module.exports = async (opts) => {
58
59
  }
59
60
  // if URL provided, set up a remote source provider
60
61
  else {
61
- exitWith(1, `Remote Strapi source provider not yet implemented`);
62
+ logger.error(`Remote Strapi source provider not yet implemented`);
63
+ process.exit(1);
62
64
  }
63
65
 
64
66
  // if no URL provided, use local Strapi
@@ -69,16 +71,9 @@ module.exports = async (opts) => {
69
71
  }
70
72
  // if URL provided, set up a remote destination provider
71
73
  else {
72
- if (!opts.toToken) {
73
- exitWith(1, 'Missing token for remote destination');
74
- }
75
-
76
74
  destination = createRemoteStrapiDestinationProvider({
77
75
  url: opts.to,
78
- auth: {
79
- type: 'token',
80
- token: opts.toToken,
81
- },
76
+ auth: false,
82
77
  strategy: 'restore',
83
78
  restore: {
84
79
  entities: { exclude: DEFAULT_IGNORED_CONTENT_TYPES },
@@ -87,11 +82,12 @@ module.exports = async (opts) => {
87
82
  }
88
83
 
89
84
  if (!source || !destination) {
90
- exitWith(1, 'Could not create providers');
85
+ logger.error('Could not create providers');
86
+ process.exit(1);
91
87
  }
92
88
 
93
89
  const engine = createTransferEngine(source, destination, {
94
- versionStrategy: 'exact',
90
+ versionStrategy: 'strict',
95
91
  schemaStrategy: 'strict',
96
92
  transforms: {
97
93
  links: [
@@ -116,15 +112,18 @@ module.exports = async (opts) => {
116
112
 
117
113
  engine.diagnostics.onDiagnostic(formatDiagnostic('transfer'));
118
114
 
119
- let results;
120
115
  try {
121
- console.log(`Starting transfer...`);
122
- results = await engine.transfer();
116
+ logger.log(`Starting transfer...`);
117
+
118
+ const results = await engine.transfer();
119
+
120
+ const table = buildTransferTable(results.engine);
121
+ logger.log(table.toString());
122
+
123
+ logger.log(`${chalk.bold('Transfer process has been completed successfully!')}`);
124
+ process.exit(0);
123
125
  } catch (e) {
124
- exitWith(1, 'Transfer process failed.');
126
+ logger.error('Transfer process failed.');
127
+ process.exit(1);
125
128
  }
126
-
127
- const table = buildTransferTable(results.engine);
128
- console.log(table.toString());
129
- exitWith(0, `${chalk.bold('Transfer process has been completed successfully!')}`);
130
129
  };
@@ -82,8 +82,6 @@ const DEFAULT_IGNORED_CONTENT_TYPES = [
82
82
  'admin::role',
83
83
  'admin::api-token',
84
84
  'admin::api-token-permission',
85
- 'admin::transfer-token',
86
- 'admin::transfer-token-permission',
87
85
  'admin::audit-log',
88
86
  ];
89
87
 
@@ -36,29 +36,22 @@ const readableBytes = (bytes, decimals = 1, padStart = 0) => {
36
36
  *
37
37
  * @param {number} code Code to exit process with
38
38
  * @param {string | Array} message Message(s) to display before exiting
39
- * @param {Object} options
40
- * @param {console} options.logger - logger object, defaults to console
41
- * @param {process} options.prc - process object, defaults to process
42
- *
43
39
  */
44
- const exitWith = (code, message = undefined, options = {}) => {
45
- const { logger = console, prc = process } = options;
46
-
47
- const log = (message) => {
40
+ const exitWith = (code, message = undefined) => {
41
+ const logger = (message) => {
48
42
  if (code === 0) {
49
- logger.log(chalk.green(message));
43
+ console.log(chalk.green(message));
50
44
  } else {
51
- logger.error(chalk.red(message));
45
+ console.error(chalk.red(message));
52
46
  }
53
47
  };
54
48
 
55
49
  if (isString(message)) {
56
- log(message);
50
+ logger(message);
57
51
  } else if (isArray(message)) {
58
- message.forEach((msg) => log(msg));
52
+ message.forEach((msg) => logger(msg));
59
53
  }
60
-
61
- prc.exit(code);
54
+ process.exit(code);
62
55
  };
63
56
 
64
57
  /**
@@ -19,6 +19,14 @@ module.exports = (config) => {
19
19
  const { origin, expose, maxAge, credentials, methods, headers, keepHeadersOnError } =
20
20
  defaultsDeep(defaults, config);
21
21
 
22
+ if (config.enabled !== undefined) {
23
+ strapi.log.warn(
24
+ 'The strapi::cors middleware no longer supports the `enabled` option. Using it' +
25
+ ' to conditionally enable CORS might cause an insecure default. To disable strapi::cors, remove it from' +
26
+ ' the exported array in config/middleware.js'
27
+ );
28
+ }
29
+
22
30
  return cors({
23
31
  async origin(ctx) {
24
32
  let originList;
@@ -77,9 +77,10 @@ module.exports = (config, { strapi }) => {
77
77
  }),
78
78
  config: { auth: false },
79
79
  },
80
+ // All other public GET-routes except /uploads/(.*) which is handled in upload middleware
80
81
  {
81
82
  method: 'GET',
82
- path: '/(.*)',
83
+ path: '/((?!uploads/).+)',
83
84
  handler: koaStatic(strapi.dirs.static.public, {
84
85
  maxage: maxAge,
85
86
  defer: true,
@@ -43,28 +43,7 @@ const createAuthentication = () => {
43
43
  return next();
44
44
  }
45
45
 
46
- const routeStrategies = strategies[route.info.type];
47
- const configStrategies = config?.strategies ?? routeStrategies ?? [];
48
-
49
- const strategiesToUse = configStrategies.reduce((acc, strategy) => {
50
- // Resolve by strategy name
51
- if (typeof strategy === 'string') {
52
- const routeStrategy = routeStrategies.find((rs) => rs.name === strategy);
53
-
54
- if (routeStrategy) {
55
- acc.push(routeStrategy);
56
- }
57
- }
58
-
59
- // Use the given strategy as is
60
- else if (typeof strategy === 'object') {
61
- validStrategy(strategy);
62
-
63
- acc.push(strategy);
64
- }
65
-
66
- return acc;
67
- }, []);
46
+ const strategiesToUse = strategies[route.info.type];
68
47
 
69
48
  for (const strategy of strategiesToUse) {
70
49
  const result = await strategy.authenticate(ctx);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/strapi",
3
- "version": "4.7.0-beta.0",
3
+ "version": "4.9.0-alpha.0",
4
4
  "description": "An open source headless CMS solution to create and manage your own API. It provides a powerful dashboard and features to make your life easier. Databases supported: MySQL, MariaDB, PostgreSQL, SQLite",
5
5
  "keywords": [
6
6
  "strapi",
@@ -81,19 +81,19 @@
81
81
  "dependencies": {
82
82
  "@koa/cors": "3.4.3",
83
83
  "@koa/router": "10.1.1",
84
- "@strapi/admin": "4.7.0-beta.0",
85
- "@strapi/data-transfer": "4.7.0-beta.0",
86
- "@strapi/database": "4.7.0-beta.0",
87
- "@strapi/generate-new": "4.7.0-beta.0",
88
- "@strapi/generators": "4.7.0-beta.0",
89
- "@strapi/logger": "4.7.0-beta.0",
90
- "@strapi/permissions": "4.7.0-beta.0",
91
- "@strapi/plugin-content-manager": "4.7.0-beta.0",
92
- "@strapi/plugin-content-type-builder": "4.7.0-beta.0",
93
- "@strapi/plugin-email": "4.7.0-beta.0",
94
- "@strapi/plugin-upload": "4.7.0-beta.0",
95
- "@strapi/typescript-utils": "4.7.0-beta.0",
96
- "@strapi/utils": "4.7.0-beta.0",
84
+ "@strapi/admin": "4.9.0-alpha.0",
85
+ "@strapi/data-transfer": "4.9.0-alpha.0",
86
+ "@strapi/database": "4.9.0-alpha.0",
87
+ "@strapi/generate-new": "4.9.0-alpha.0",
88
+ "@strapi/generators": "4.9.0-alpha.0",
89
+ "@strapi/logger": "4.9.0-alpha.0",
90
+ "@strapi/permissions": "4.9.0-alpha.0",
91
+ "@strapi/plugin-content-manager": "4.9.0-alpha.0",
92
+ "@strapi/plugin-content-type-builder": "4.9.0-alpha.0",
93
+ "@strapi/plugin-email": "4.9.0-alpha.0",
94
+ "@strapi/plugin-upload": "4.9.0-alpha.0",
95
+ "@strapi/typescript-utils": "4.9.0-alpha.0",
96
+ "@strapi/utils": "4.9.0-alpha.0",
97
97
  "bcryptjs": "2.4.3",
98
98
  "boxen": "5.1.2",
99
99
  "chalk": "4.1.2",
@@ -118,7 +118,7 @@
118
118
  "koa-favicon": "2.1.0",
119
119
  "koa-helmet": "6.1.0",
120
120
  "koa-ip": "^2.1.2",
121
- "koa-session": "6.2.0",
121
+ "koa-session": "6.4.0",
122
122
  "koa-static": "5.0.0",
123
123
  "lodash": "4.17.21",
124
124
  "mime-types": "2.1.35",
@@ -135,12 +135,12 @@
135
135
  "uuid": "^8.3.2"
136
136
  },
137
137
  "devDependencies": {
138
- "supertest": "6.2.4",
138
+ "supertest": "6.3.3",
139
139
  "typescript": "4.6.2"
140
140
  },
141
141
  "engines": {
142
142
  "node": ">=14.19.1 <=18.x.x",
143
143
  "npm": ">=6.0.0"
144
144
  },
145
- "gitHead": "880ba7af867ad43c4cc45b47467b76a9b5606b6e"
145
+ "gitHead": "35f783d0dc07db101e7e62cb4d682f751551f452"
146
146
  }