@strapi/strapi 4.6.2 → 4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d
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 +85 -55
- package/lib/commands/transfer/export.js +32 -19
- package/lib/commands/transfer/import.js +30 -13
- package/lib/commands/transfer/transfer.js +40 -22
- package/lib/commands/transfer/utils.js +42 -0
- package/lib/commands/utils/helpers.js +14 -7
- package/lib/services/auth/index.js +22 -1
- package/package.json +15 -15
package/bin/strapi.js
CHANGED
|
@@ -18,8 +18,9 @@ const {
|
|
|
18
18
|
promptEncryptionKey,
|
|
19
19
|
confirmMessage,
|
|
20
20
|
forceOption,
|
|
21
|
+
parseURL,
|
|
21
22
|
} = require('../lib/commands/utils/commander');
|
|
22
|
-
const { exitWith } = require('../lib/commands/utils/helpers');
|
|
23
|
+
const { exitWith, ifOptions, assertUrlHasProtocol } = require('../lib/commands/utils/helpers');
|
|
23
24
|
const {
|
|
24
25
|
excludeOption,
|
|
25
26
|
onlyOption,
|
|
@@ -272,59 +273,88 @@ program
|
|
|
272
273
|
.option('-s, --silent', `Run the generation silently, without any output`, false)
|
|
273
274
|
.action(getLocalScript('ts/generate-types'));
|
|
274
275
|
|
|
275
|
-
//
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
//
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
//
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
//
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
//
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
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'));
|
|
328
358
|
|
|
329
359
|
// `$ strapi export`
|
|
330
360
|
program
|
|
@@ -420,7 +450,7 @@ program
|
|
|
420
450
|
.hook(
|
|
421
451
|
'preAction',
|
|
422
452
|
confirmMessage(
|
|
423
|
-
'The import will delete all data in your database. Are you sure you want to proceed?'
|
|
453
|
+
'The import will delete all data in your database and media files. Are you sure you want to proceed?'
|
|
424
454
|
)
|
|
425
455
|
)
|
|
426
456
|
.action(getLocalScript('transfer/import'));
|
|
@@ -18,8 +18,9 @@ const {
|
|
|
18
18
|
DEFAULT_IGNORED_CONTENT_TYPES,
|
|
19
19
|
createStrapiInstance,
|
|
20
20
|
formatDiagnostic,
|
|
21
|
+
loadersFactory,
|
|
21
22
|
} = require('./utils');
|
|
22
|
-
|
|
23
|
+
const { exitWith } = require('../utils/helpers');
|
|
23
24
|
/**
|
|
24
25
|
* @typedef ExportCommandOptions Options given to the CLI import command
|
|
25
26
|
*
|
|
@@ -29,8 +30,6 @@ const {
|
|
|
29
30
|
* @property {boolean} [compress] Used to compress the final archive
|
|
30
31
|
*/
|
|
31
32
|
|
|
32
|
-
const logger = console;
|
|
33
|
-
|
|
34
33
|
const BYTES_IN_MB = 1024 * 1024;
|
|
35
34
|
|
|
36
35
|
/**
|
|
@@ -43,8 +42,7 @@ const BYTES_IN_MB = 1024 * 1024;
|
|
|
43
42
|
module.exports = async (opts) => {
|
|
44
43
|
// Validate inputs from Commander
|
|
45
44
|
if (!isObject(opts)) {
|
|
46
|
-
|
|
47
|
-
process.exit(1);
|
|
45
|
+
exitWith(1, 'Could not parse command arguments');
|
|
48
46
|
}
|
|
49
47
|
|
|
50
48
|
const strapi = await createStrapiInstance();
|
|
@@ -82,6 +80,20 @@ module.exports = async (opts) => {
|
|
|
82
80
|
|
|
83
81
|
const progress = engine.progress.stream;
|
|
84
82
|
|
|
83
|
+
const { updateLoader } = loadersFactory();
|
|
84
|
+
|
|
85
|
+
progress.on(`stage::start`, ({ stage, data }) => {
|
|
86
|
+
updateLoader(stage, data).start();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
progress.on('stage::finish', ({ stage, data }) => {
|
|
90
|
+
updateLoader(stage, data).succeed();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
progress.on('stage::progress', ({ stage, data }) => {
|
|
94
|
+
updateLoader(stage, data);
|
|
95
|
+
});
|
|
96
|
+
|
|
85
97
|
const getTelemetryPayload = (/* payload */) => {
|
|
86
98
|
return {
|
|
87
99
|
eventProperties: {
|
|
@@ -92,33 +104,34 @@ module.exports = async (opts) => {
|
|
|
92
104
|
};
|
|
93
105
|
|
|
94
106
|
progress.on('transfer::start', async () => {
|
|
95
|
-
|
|
107
|
+
console.log(`Starting export...`);
|
|
96
108
|
await strapi.telemetry.send('didDEITSProcessStart', getTelemetryPayload());
|
|
97
109
|
});
|
|
98
110
|
|
|
111
|
+
let results;
|
|
112
|
+
let outFile;
|
|
99
113
|
try {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const table = buildTransferTable(results.engine);
|
|
104
|
-
logger.log(table.toString());
|
|
105
|
-
|
|
114
|
+
results = await engine.transfer();
|
|
115
|
+
outFile = results.destination.file.path;
|
|
106
116
|
const outFileExists = await fs.pathExists(outFile);
|
|
107
117
|
if (!outFileExists) {
|
|
108
118
|
throw new TransferEngineTransferError(`Export file not created "${outFile}"`);
|
|
109
119
|
}
|
|
110
|
-
|
|
111
|
-
logger.log(`${chalk.bold('Export process has been completed successfully!')}`);
|
|
112
|
-
logger.log(`Export archive is in ${chalk.green(outFile)}`);
|
|
113
120
|
} catch {
|
|
114
121
|
await strapi.telemetry.send('didDEITSProcessFail', getTelemetryPayload());
|
|
115
|
-
|
|
116
|
-
process.exit(1);
|
|
122
|
+
exitWith(1, 'Export process failed.');
|
|
117
123
|
}
|
|
118
124
|
|
|
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
|
|
120
125
|
await strapi.telemetry.send('didDEITSProcessFinish', getTelemetryPayload());
|
|
121
|
-
|
|
126
|
+
try {
|
|
127
|
+
const table = buildTransferTable(results.engine);
|
|
128
|
+
console.log(table.toString());
|
|
129
|
+
} catch (e) {
|
|
130
|
+
console.error('There was an error displaying the results of the transfer.');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
console.log(`${chalk.bold('Export process has been completed successfully!')}`);
|
|
134
|
+
exitWith(0, `Export archive is in ${chalk.green(outFile)}`);
|
|
122
135
|
};
|
|
123
136
|
|
|
124
137
|
/**
|
|
@@ -19,19 +19,18 @@ const {
|
|
|
19
19
|
DEFAULT_IGNORED_CONTENT_TYPES,
|
|
20
20
|
createStrapiInstance,
|
|
21
21
|
formatDiagnostic,
|
|
22
|
+
loadersFactory,
|
|
22
23
|
} = require('./utils');
|
|
24
|
+
const { exitWith } = require('../utils/helpers');
|
|
23
25
|
|
|
24
26
|
/**
|
|
25
27
|
* @typedef {import('@strapi/data-transfer').ILocalFileSourceProviderOptions} ILocalFileSourceProviderOptions
|
|
26
28
|
*/
|
|
27
29
|
|
|
28
|
-
const logger = console;
|
|
29
|
-
|
|
30
30
|
module.exports = async (opts) => {
|
|
31
31
|
// validate inputs from Commander
|
|
32
32
|
if (!isObject(opts)) {
|
|
33
|
-
|
|
34
|
-
process.exit(1);
|
|
33
|
+
exitWith(1, 'Could not parse arguments');
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
/**
|
|
@@ -90,6 +89,21 @@ module.exports = async (opts) => {
|
|
|
90
89
|
engine.diagnostics.onDiagnostic(formatDiagnostic('import'));
|
|
91
90
|
|
|
92
91
|
const progress = engine.progress.stream;
|
|
92
|
+
|
|
93
|
+
const { updateLoader } = loadersFactory();
|
|
94
|
+
|
|
95
|
+
progress.on(`stage::start`, ({ stage, data }) => {
|
|
96
|
+
updateLoader(stage, data).start();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
progress.on('stage::finish', ({ stage, data }) => {
|
|
100
|
+
updateLoader(stage, data).succeed();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
progress.on('stage::progress', ({ stage, data }) => {
|
|
104
|
+
updateLoader(stage, data);
|
|
105
|
+
});
|
|
106
|
+
|
|
93
107
|
const getTelemetryPayload = () => {
|
|
94
108
|
return {
|
|
95
109
|
eventProperties: {
|
|
@@ -100,27 +114,30 @@ module.exports = async (opts) => {
|
|
|
100
114
|
};
|
|
101
115
|
|
|
102
116
|
progress.on('transfer::start', async () => {
|
|
103
|
-
|
|
117
|
+
console.log('Starting import...');
|
|
104
118
|
await strapiInstance.telemetry.send('didDEITSProcessStart', getTelemetryPayload());
|
|
105
119
|
});
|
|
106
120
|
|
|
121
|
+
let results;
|
|
107
122
|
try {
|
|
108
|
-
|
|
109
|
-
const table = buildTransferTable(results.engine);
|
|
110
|
-
logger.info(table.toString());
|
|
111
|
-
|
|
112
|
-
logger.info('Import process has been completed successfully!');
|
|
123
|
+
results = await engine.transfer();
|
|
113
124
|
} catch (e) {
|
|
114
125
|
await strapiInstance.telemetry.send('didDEITSProcessFail', getTelemetryPayload());
|
|
115
|
-
|
|
126
|
+
console.error('Import process failed.');
|
|
116
127
|
process.exit(1);
|
|
117
128
|
}
|
|
118
129
|
|
|
119
|
-
|
|
130
|
+
try {
|
|
131
|
+
const table = buildTransferTable(results.engine);
|
|
132
|
+
console.log(table.toString());
|
|
133
|
+
} catch (e) {
|
|
134
|
+
console.error('There was an error displaying the results of the transfer.');
|
|
135
|
+
}
|
|
136
|
+
|
|
120
137
|
await strapiInstance.telemetry.send('didDEITSProcessFinish', getTelemetryPayload());
|
|
121
138
|
await strapiInstance.destroy();
|
|
122
139
|
|
|
123
|
-
|
|
140
|
+
exitWith(0, 'Import process has been completed successfully!');
|
|
124
141
|
};
|
|
125
142
|
|
|
126
143
|
/**
|
|
@@ -16,29 +16,30 @@ const {
|
|
|
16
16
|
createStrapiInstance,
|
|
17
17
|
DEFAULT_IGNORED_CONTENT_TYPES,
|
|
18
18
|
formatDiagnostic,
|
|
19
|
+
loadersFactory,
|
|
19
20
|
} = require('./utils');
|
|
20
|
-
|
|
21
|
-
const logger = console;
|
|
21
|
+
const { exitWith } = require('../utils/helpers');
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* @typedef TransferCommandOptions Options given to the CLI transfer command
|
|
25
25
|
*
|
|
26
26
|
* @property {URL|undefined} [to] The url of a remote Strapi to use as remote destination
|
|
27
27
|
* @property {URL|undefined} [from] The url of a remote Strapi to use as remote source
|
|
28
|
+
* @property {string|undefined} [toToken] The transfer token for the remote Strapi destination
|
|
29
|
+
* @property {string|undefined} [fromToken] The transfer token for the remote Strapi source
|
|
28
30
|
*/
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
33
|
* Transfer command.
|
|
32
34
|
*
|
|
33
|
-
*
|
|
35
|
+
* Transfers data between local Strapi and remote Strapi instances
|
|
34
36
|
*
|
|
35
37
|
* @param {TransferCommandOptions} opts
|
|
36
38
|
*/
|
|
37
39
|
module.exports = async (opts) => {
|
|
38
40
|
// Validate inputs from Commander
|
|
39
41
|
if (!isObject(opts)) {
|
|
40
|
-
|
|
41
|
-
process.exit(1);
|
|
42
|
+
exitWith(1, 'Could not parse command arguments');
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
const strapi = await createStrapiInstance();
|
|
@@ -47,8 +48,7 @@ module.exports = async (opts) => {
|
|
|
47
48
|
let destination;
|
|
48
49
|
|
|
49
50
|
if (!opts.from && !opts.to) {
|
|
50
|
-
|
|
51
|
-
process.exit(1);
|
|
51
|
+
exitWith(1, 'At least one source (from) or destination (to) option must be provided');
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
// if no URL provided, use local Strapi
|
|
@@ -59,8 +59,7 @@ module.exports = async (opts) => {
|
|
|
59
59
|
}
|
|
60
60
|
// if URL provided, set up a remote source provider
|
|
61
61
|
else {
|
|
62
|
-
|
|
63
|
-
process.exit(1);
|
|
62
|
+
exitWith(1, `Remote Strapi source provider not yet implemented`);
|
|
64
63
|
}
|
|
65
64
|
|
|
66
65
|
// if no URL provided, use local Strapi
|
|
@@ -71,9 +70,16 @@ module.exports = async (opts) => {
|
|
|
71
70
|
}
|
|
72
71
|
// if URL provided, set up a remote destination provider
|
|
73
72
|
else {
|
|
73
|
+
if (!opts.toToken) {
|
|
74
|
+
exitWith(1, 'Missing token for remote destination');
|
|
75
|
+
}
|
|
76
|
+
|
|
74
77
|
destination = createRemoteStrapiDestinationProvider({
|
|
75
78
|
url: opts.to,
|
|
76
|
-
auth:
|
|
79
|
+
auth: {
|
|
80
|
+
type: 'token',
|
|
81
|
+
token: opts.toToken,
|
|
82
|
+
},
|
|
77
83
|
strategy: 'restore',
|
|
78
84
|
restore: {
|
|
79
85
|
entities: { exclude: DEFAULT_IGNORED_CONTENT_TYPES },
|
|
@@ -82,12 +88,11 @@ module.exports = async (opts) => {
|
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
if (!source || !destination) {
|
|
85
|
-
|
|
86
|
-
process.exit(1);
|
|
91
|
+
exitWith(1, 'Could not create providers');
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
const engine = createTransferEngine(source, destination, {
|
|
90
|
-
versionStrategy: '
|
|
95
|
+
versionStrategy: 'exact',
|
|
91
96
|
schemaStrategy: 'strict',
|
|
92
97
|
transforms: {
|
|
93
98
|
links: [
|
|
@@ -112,18 +117,31 @@ module.exports = async (opts) => {
|
|
|
112
117
|
|
|
113
118
|
engine.diagnostics.onDiagnostic(formatDiagnostic('transfer'));
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
logger.log(`Starting transfer...`);
|
|
120
|
+
const progress = engine.progress.stream;
|
|
117
121
|
|
|
118
|
-
|
|
122
|
+
const { updateLoader } = loadersFactory();
|
|
119
123
|
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
progress.on(`stage::start`, ({ stage, data }) => {
|
|
125
|
+
updateLoader(stage, data).start();
|
|
126
|
+
});
|
|
122
127
|
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
progress.on('stage::finish', ({ stage, data }) => {
|
|
129
|
+
updateLoader(stage, data).succeed();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
progress.on('stage::progress', ({ stage, data }) => {
|
|
133
|
+
updateLoader(stage, data);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
let results;
|
|
137
|
+
try {
|
|
138
|
+
console.log(`Starting transfer...`);
|
|
139
|
+
results = await engine.transfer();
|
|
125
140
|
} catch (e) {
|
|
126
|
-
|
|
127
|
-
process.exit(1);
|
|
141
|
+
exitWith(1, 'Transfer process failed.');
|
|
128
142
|
}
|
|
143
|
+
|
|
144
|
+
const table = buildTransferTable(results.engine);
|
|
145
|
+
console.log(table.toString());
|
|
146
|
+
exitWith(0, `${chalk.bold('Transfer process has been completed successfully!')}`);
|
|
129
147
|
};
|
|
@@ -9,6 +9,7 @@ const {
|
|
|
9
9
|
configs: { createOutputFileConfiguration },
|
|
10
10
|
createLogger,
|
|
11
11
|
} = require('@strapi/logger');
|
|
12
|
+
const ora = require('ora');
|
|
12
13
|
const { readableBytes, exitWith } = require('../utils/helpers');
|
|
13
14
|
const strapi = require('../../index');
|
|
14
15
|
const { getParseListWithChoices } = require('../utils/commander');
|
|
@@ -82,6 +83,8 @@ const DEFAULT_IGNORED_CONTENT_TYPES = [
|
|
|
82
83
|
'admin::role',
|
|
83
84
|
'admin::api-token',
|
|
84
85
|
'admin::api-token-permission',
|
|
86
|
+
'admin::transfer-token',
|
|
87
|
+
'admin::transfer-token-permission',
|
|
85
88
|
'admin::audit-log',
|
|
86
89
|
];
|
|
87
90
|
|
|
@@ -169,7 +172,46 @@ const formatDiagnostic =
|
|
|
169
172
|
}
|
|
170
173
|
};
|
|
171
174
|
|
|
175
|
+
const loadersFactory = (defaultLoaders = {}) => {
|
|
176
|
+
const loaders = defaultLoaders;
|
|
177
|
+
const updateLoader = (stage, data) => {
|
|
178
|
+
if (!(stage in loaders)) {
|
|
179
|
+
createLoader(stage);
|
|
180
|
+
}
|
|
181
|
+
const stageData = data[stage];
|
|
182
|
+
const elapsedTime = stageData?.startTime
|
|
183
|
+
? (stageData?.endTime || Date.now()) - stageData.startTime
|
|
184
|
+
: 0;
|
|
185
|
+
const size = `size: ${readableBytes(stageData?.bytes ?? 0)}`;
|
|
186
|
+
const elapsed = `elapsed: ${elapsedTime} ms`;
|
|
187
|
+
const speed =
|
|
188
|
+
elapsedTime > 0 ? `(${readableBytes(((stageData?.bytes ?? 0) * 1000) / elapsedTime)}/s)` : '';
|
|
189
|
+
|
|
190
|
+
loaders[stage].text = `${stage}: ${stageData?.count ?? 0} transfered (${size}) (${elapsed}) ${
|
|
191
|
+
!stageData?.endTime ? speed : ''
|
|
192
|
+
}`;
|
|
193
|
+
|
|
194
|
+
return loaders[stage];
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const createLoader = (stage) => {
|
|
198
|
+
Object.assign(loaders, { [stage]: ora() });
|
|
199
|
+
return loaders[stage];
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const getLoader = (stage) => {
|
|
203
|
+
return loaders[stage];
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
updateLoader,
|
|
208
|
+
createLoader,
|
|
209
|
+
getLoader,
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
|
|
172
213
|
module.exports = {
|
|
214
|
+
loadersFactory,
|
|
173
215
|
buildTransferTable,
|
|
174
216
|
getDefaultExportName,
|
|
175
217
|
DEFAULT_IGNORED_CONTENT_TYPES,
|
|
@@ -36,22 +36,29 @@ 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
|
+
*
|
|
39
43
|
*/
|
|
40
|
-
const exitWith = (code, message = undefined) => {
|
|
41
|
-
const logger =
|
|
44
|
+
const exitWith = (code, message = undefined, options = {}) => {
|
|
45
|
+
const { logger = console, prc = process } = options;
|
|
46
|
+
|
|
47
|
+
const log = (message) => {
|
|
42
48
|
if (code === 0) {
|
|
43
|
-
|
|
49
|
+
logger.log(chalk.green(message));
|
|
44
50
|
} else {
|
|
45
|
-
|
|
51
|
+
logger.error(chalk.red(message));
|
|
46
52
|
}
|
|
47
53
|
};
|
|
48
54
|
|
|
49
55
|
if (isString(message)) {
|
|
50
|
-
|
|
56
|
+
log(message);
|
|
51
57
|
} else if (isArray(message)) {
|
|
52
|
-
message.forEach((msg) =>
|
|
58
|
+
message.forEach((msg) => log(msg));
|
|
53
59
|
}
|
|
54
|
-
|
|
60
|
+
|
|
61
|
+
prc.exit(code);
|
|
55
62
|
};
|
|
56
63
|
|
|
57
64
|
/**
|
|
@@ -43,7 +43,28 @@ const createAuthentication = () => {
|
|
|
43
43
|
return next();
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
const
|
|
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
|
+
}, []);
|
|
47
68
|
|
|
48
69
|
for (const strategy of strategiesToUse) {
|
|
49
70
|
const result = await strategy.authenticate(ctx);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/strapi",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
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.
|
|
85
|
-
"@strapi/data-transfer": "4.
|
|
86
|
-
"@strapi/database": "4.
|
|
87
|
-
"@strapi/generate-new": "4.
|
|
88
|
-
"@strapi/generators": "4.
|
|
89
|
-
"@strapi/logger": "4.
|
|
90
|
-
"@strapi/permissions": "4.
|
|
91
|
-
"@strapi/plugin-content-manager": "4.
|
|
92
|
-
"@strapi/plugin-content-type-builder": "4.
|
|
93
|
-
"@strapi/plugin-email": "4.
|
|
94
|
-
"@strapi/plugin-upload": "4.
|
|
95
|
-
"@strapi/typescript-utils": "4.
|
|
96
|
-
"@strapi/utils": "4.
|
|
84
|
+
"@strapi/admin": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
85
|
+
"@strapi/data-transfer": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
86
|
+
"@strapi/database": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
87
|
+
"@strapi/generate-new": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
88
|
+
"@strapi/generators": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
89
|
+
"@strapi/logger": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
90
|
+
"@strapi/permissions": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
91
|
+
"@strapi/plugin-content-manager": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
92
|
+
"@strapi/plugin-content-type-builder": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
93
|
+
"@strapi/plugin-email": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
94
|
+
"@strapi/plugin-upload": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
95
|
+
"@strapi/typescript-utils": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
96
|
+
"@strapi/utils": "4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d",
|
|
97
97
|
"bcryptjs": "2.4.3",
|
|
98
98
|
"boxen": "5.1.2",
|
|
99
99
|
"chalk": "4.1.2",
|
|
@@ -142,5 +142,5 @@
|
|
|
142
142
|
"node": ">=14.19.1 <=18.x.x",
|
|
143
143
|
"npm": ">=6.0.0"
|
|
144
144
|
},
|
|
145
|
-
"gitHead": "
|
|
145
|
+
"gitHead": "117579f4c13806c2cd518e7d7d2f9d0c8a20107d"
|
|
146
146
|
}
|