@strapi/strapi 4.8.2 → 4.9.0-beta.1
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
|
@@ -24,13 +24,10 @@ const { exitWith, ifOptions, assertUrlHasProtocol } = require('../lib/commands/u
|
|
|
24
24
|
const {
|
|
25
25
|
excludeOption,
|
|
26
26
|
onlyOption,
|
|
27
|
+
throttleOption,
|
|
27
28
|
validateExcludeOnly,
|
|
28
29
|
} = require('../lib/commands/transfer/utils');
|
|
29
30
|
|
|
30
|
-
process.on('SIGINT', () => {
|
|
31
|
-
process.exit();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
31
|
const checkCwdIsStrapiApp = (name) => {
|
|
35
32
|
const logErrorAndExit = () => {
|
|
36
33
|
console.log(
|
|
@@ -279,13 +276,12 @@ program
|
|
|
279
276
|
.description('Transfer data from one source to another')
|
|
280
277
|
.allowExcessArguments(false)
|
|
281
278
|
.addOption(
|
|
282
|
-
new Option(
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
.addOption(
|
|
287
|
-
new Option('--from-token <token>', `Transfer token for the remote Strapi source`).hideHelp() // Hidden until pull feature is released
|
|
279
|
+
new Option(
|
|
280
|
+
'--from <sourceURL>',
|
|
281
|
+
`URL of the remote Strapi instance to get data from`
|
|
282
|
+
).argParser(parseURL)
|
|
288
283
|
)
|
|
284
|
+
.addOption(new Option('--from-token <token>', `Transfer token for the remote Strapi source`))
|
|
289
285
|
.addOption(
|
|
290
286
|
new Option(
|
|
291
287
|
'--to <destinationURL>',
|
|
@@ -296,7 +292,16 @@ program
|
|
|
296
292
|
.addOption(forceOption)
|
|
297
293
|
.addOption(excludeOption)
|
|
298
294
|
.addOption(onlyOption)
|
|
295
|
+
.addOption(throttleOption)
|
|
299
296
|
.hook('preAction', validateExcludeOnly)
|
|
297
|
+
.hook(
|
|
298
|
+
'preAction',
|
|
299
|
+
ifOptions(
|
|
300
|
+
(opts) => !(opts.from || opts.to) || (opts.from && opts.to),
|
|
301
|
+
() =>
|
|
302
|
+
exitWith(1, 'Exactly one remote source (from) or destination (to) option must be provided')
|
|
303
|
+
)
|
|
304
|
+
)
|
|
300
305
|
// If --from is used, validate the URL and token
|
|
301
306
|
.hook(
|
|
302
307
|
'preAction',
|
|
@@ -313,7 +318,7 @@ program
|
|
|
313
318
|
},
|
|
314
319
|
]);
|
|
315
320
|
if (!answers.fromToken?.length) {
|
|
316
|
-
exitWith(1, 'No token
|
|
321
|
+
exitWith(1, 'No token provided for remote source, aborting transfer.');
|
|
317
322
|
}
|
|
318
323
|
thisCommand.opts().fromToken = answers.fromToken;
|
|
319
324
|
}
|
|
@@ -336,7 +341,7 @@ program
|
|
|
336
341
|
},
|
|
337
342
|
]);
|
|
338
343
|
if (!answers.toToken?.length) {
|
|
339
|
-
exitWith(1, 'No token
|
|
344
|
+
exitWith(1, 'No token provided for remote destination, aborting transfer.');
|
|
340
345
|
}
|
|
341
346
|
thisCommand.opts().toToken = answers.toToken;
|
|
342
347
|
}
|
|
@@ -348,13 +353,6 @@ program
|
|
|
348
353
|
}
|
|
349
354
|
)
|
|
350
355
|
)
|
|
351
|
-
// .hook(
|
|
352
|
-
// 'preAction',
|
|
353
|
-
// ifOptions(
|
|
354
|
-
// (opts) => !opts.from && !opts.to,
|
|
355
|
-
// () => exitWith(1, 'At least one source (from) or destination (to) option must be provided')
|
|
356
|
-
// )
|
|
357
|
-
// )
|
|
358
356
|
.action(getLocalScript('transfer/transfer'));
|
|
359
357
|
|
|
360
358
|
// `$ strapi export`
|
|
@@ -375,6 +373,7 @@ program
|
|
|
375
373
|
.addOption(new Option('-f, --file <file>', 'name to use for exported file (without extensions)'))
|
|
376
374
|
.addOption(excludeOption)
|
|
377
375
|
.addOption(onlyOption)
|
|
376
|
+
.addOption(throttleOption)
|
|
378
377
|
.hook('preAction', validateExcludeOnly)
|
|
379
378
|
.hook('preAction', promptEncryptionKey)
|
|
380
379
|
.action(getLocalScript('transfer/export'));
|
|
@@ -397,6 +396,7 @@ program
|
|
|
397
396
|
.addOption(forceOption)
|
|
398
397
|
.addOption(excludeOption)
|
|
399
398
|
.addOption(onlyOption)
|
|
399
|
+
.addOption(throttleOption)
|
|
400
400
|
.hook('preAction', validateExcludeOnly)
|
|
401
401
|
.hook('preAction', async (thisCommand) => {
|
|
402
402
|
const opts = thisCommand.opts();
|
|
@@ -22,15 +22,20 @@ const {
|
|
|
22
22
|
createStrapiInstance,
|
|
23
23
|
formatDiagnostic,
|
|
24
24
|
loadersFactory,
|
|
25
|
+
exitMessageText,
|
|
26
|
+
abortTransfer,
|
|
25
27
|
} = require('./utils');
|
|
26
28
|
const { exitWith } = require('../utils/helpers');
|
|
27
29
|
/**
|
|
28
30
|
* @typedef ExportCommandOptions Options given to the CLI import command
|
|
29
31
|
*
|
|
30
|
-
* @property {string} [file] The file path to
|
|
32
|
+
* @property {string} [file] The file path to export to
|
|
31
33
|
* @property {boolean} [encrypt] Used to encrypt the final archive
|
|
32
|
-
* @property {string} [key] Encryption key, only
|
|
34
|
+
* @property {string} [key] Encryption key, used only when encryption is enabled
|
|
33
35
|
* @property {boolean} [compress] Used to compress the final archive
|
|
36
|
+
* @property {(keyof import('@strapi/data-transfer/src/engine').TransferGroupFilter)[]} [only] If present, only include these filtered groups of data
|
|
37
|
+
* @property {(keyof import('@strapi/data-transfer/src/engine').TransferGroupFilter)[]} [exclude] If present, exclude these filtered groups of data
|
|
38
|
+
* @property {number|undefined} [throttle] Delay in ms after each record
|
|
34
39
|
*/
|
|
35
40
|
|
|
36
41
|
const BYTES_IN_MB = 1024 * 1024;
|
|
@@ -58,6 +63,7 @@ module.exports = async (opts) => {
|
|
|
58
63
|
schemaStrategy: 'ignore', // for an export to file, schemaStrategy will always be skipped
|
|
59
64
|
exclude: opts.exclude,
|
|
60
65
|
only: opts.only,
|
|
66
|
+
throttle: opts.throttle,
|
|
61
67
|
transforms: {
|
|
62
68
|
links: [
|
|
63
69
|
{
|
|
@@ -108,12 +114,19 @@ module.exports = async (opts) => {
|
|
|
108
114
|
|
|
109
115
|
progress.on('transfer::start', async () => {
|
|
110
116
|
console.log(`Starting export...`);
|
|
117
|
+
|
|
111
118
|
await strapi.telemetry.send('didDEITSProcessStart', getTelemetryPayload());
|
|
112
119
|
});
|
|
113
120
|
|
|
114
121
|
let results;
|
|
115
122
|
let outFile;
|
|
116
123
|
try {
|
|
124
|
+
// Abort transfer if user interrupts process
|
|
125
|
+
['SIGTERM', 'SIGINT', 'SIGQUIT'].forEach((signal) => {
|
|
126
|
+
process.removeAllListeners(signal);
|
|
127
|
+
process.on(signal, () => abortTransfer({ engine, strapi }));
|
|
128
|
+
});
|
|
129
|
+
|
|
117
130
|
results = await engine.transfer();
|
|
118
131
|
outFile = results.destination.file.path;
|
|
119
132
|
const outFileExists = await fs.pathExists(outFile);
|
|
@@ -122,7 +135,7 @@ module.exports = async (opts) => {
|
|
|
122
135
|
}
|
|
123
136
|
} catch {
|
|
124
137
|
await strapi.telemetry.send('didDEITSProcessFail', getTelemetryPayload());
|
|
125
|
-
exitWith(1, '
|
|
138
|
+
exitWith(1, exitMessageText('export', true));
|
|
126
139
|
}
|
|
127
140
|
|
|
128
141
|
await strapi.telemetry.send('didDEITSProcessFinish', getTelemetryPayload());
|
|
@@ -133,8 +146,8 @@ module.exports = async (opts) => {
|
|
|
133
146
|
console.error('There was an error displaying the results of the transfer.');
|
|
134
147
|
}
|
|
135
148
|
|
|
136
|
-
console.log(
|
|
137
|
-
exitWith(0,
|
|
149
|
+
console.log(`Export archive is in ${chalk.green(outFile)}`);
|
|
150
|
+
exitWith(0, exitMessageText('export'));
|
|
138
151
|
};
|
|
139
152
|
|
|
140
153
|
/**
|
|
@@ -18,13 +18,32 @@ const {
|
|
|
18
18
|
createStrapiInstance,
|
|
19
19
|
formatDiagnostic,
|
|
20
20
|
loadersFactory,
|
|
21
|
+
exitMessageText,
|
|
22
|
+
abortTransfer,
|
|
21
23
|
} = require('./utils');
|
|
22
24
|
const { exitWith } = require('../utils/helpers');
|
|
23
25
|
|
|
24
26
|
/**
|
|
25
|
-
* @typedef {import('@strapi/data-transfer').ILocalFileSourceProviderOptions} ILocalFileSourceProviderOptions
|
|
27
|
+
* @typedef {import('@strapi/data-transfer/src/file/providers').ILocalFileSourceProviderOptions} ILocalFileSourceProviderOptions
|
|
26
28
|
*/
|
|
27
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @typedef ImportCommandOptions Options given to the CLI import command
|
|
32
|
+
*
|
|
33
|
+
* @property {string} [file] The file path to import
|
|
34
|
+
* @property {string} [key] Encryption key, used when encryption is enabled
|
|
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
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Import command.
|
|
42
|
+
*
|
|
43
|
+
* It transfers data from a file to a local Strapi instance
|
|
44
|
+
*
|
|
45
|
+
* @param {ImportCommandOptions} opts
|
|
46
|
+
*/
|
|
28
47
|
module.exports = async (opts) => {
|
|
29
48
|
// validate inputs from Commander
|
|
30
49
|
if (!isObject(opts)) {
|
|
@@ -63,6 +82,7 @@ module.exports = async (opts) => {
|
|
|
63
82
|
schemaStrategy: opts.schemaStrategy || DEFAULT_SCHEMA_STRATEGY,
|
|
64
83
|
exclude: opts.exclude,
|
|
65
84
|
only: opts.only,
|
|
85
|
+
throttle: opts.throttle,
|
|
66
86
|
rules: {
|
|
67
87
|
links: [
|
|
68
88
|
{
|
|
@@ -118,11 +138,16 @@ module.exports = async (opts) => {
|
|
|
118
138
|
|
|
119
139
|
let results;
|
|
120
140
|
try {
|
|
141
|
+
// Abort transfer if user interrupts process
|
|
142
|
+
['SIGTERM', 'SIGINT', 'SIGQUIT'].forEach((signal) => {
|
|
143
|
+
process.removeAllListeners(signal);
|
|
144
|
+
process.on(signal, () => abortTransfer({ engine, strapi }));
|
|
145
|
+
});
|
|
146
|
+
|
|
121
147
|
results = await engine.transfer();
|
|
122
148
|
} catch (e) {
|
|
123
149
|
await strapiInstance.telemetry.send('didDEITSProcessFail', getTelemetryPayload());
|
|
124
|
-
|
|
125
|
-
process.exit(1);
|
|
150
|
+
exitWith(1, exitMessageText('import', true));
|
|
126
151
|
}
|
|
127
152
|
|
|
128
153
|
try {
|
|
@@ -135,7 +160,7 @@ module.exports = async (opts) => {
|
|
|
135
160
|
await strapiInstance.telemetry.send('didDEITSProcessFinish', getTelemetryPayload());
|
|
136
161
|
await strapiInstance.destroy();
|
|
137
162
|
|
|
138
|
-
exitWith(0, '
|
|
163
|
+
exitWith(0, exitMessageText('import'));
|
|
139
164
|
};
|
|
140
165
|
|
|
141
166
|
/**
|
|
@@ -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,6 +19,8 @@ const {
|
|
|
19
19
|
DEFAULT_IGNORED_CONTENT_TYPES,
|
|
20
20
|
formatDiagnostic,
|
|
21
21
|
loadersFactory,
|
|
22
|
+
exitMessageText,
|
|
23
|
+
abortTransfer,
|
|
22
24
|
} = require('./utils');
|
|
23
25
|
const { exitWith } = require('../utils/helpers');
|
|
24
26
|
|
|
@@ -29,6 +31,9 @@ const { exitWith } = require('../utils/helpers');
|
|
|
29
31
|
* @property {URL|undefined} [from] The url of a remote Strapi to use as remote source
|
|
30
32
|
* @property {string|undefined} [toToken] The transfer token for the remote Strapi destination
|
|
31
33
|
* @property {string|undefined} [fromToken] The transfer token for the remote Strapi source
|
|
34
|
+
* @property {(keyof import('@strapi/data-transfer/src/engine').TransferGroupFilter)[]} [only] If present, only include these filtered groups of data
|
|
35
|
+
* @property {(keyof import('@strapi/data-transfer/src/engine').TransferGroupFilter)[]} [exclude] If present, exclude these filtered groups of data
|
|
36
|
+
* @property {number|undefined} [throttle] Delay in ms after each record
|
|
32
37
|
*/
|
|
33
38
|
|
|
34
39
|
/**
|
|
@@ -44,15 +49,14 @@ module.exports = async (opts) => {
|
|
|
44
49
|
exitWith(1, 'Could not parse command arguments');
|
|
45
50
|
}
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
if (!(opts.from || opts.to) || (opts.from && opts.to)) {
|
|
53
|
+
exitWith(1, 'Exactly one source (from) or destination (to) option must be provided');
|
|
54
|
+
}
|
|
48
55
|
|
|
56
|
+
const strapi = await createStrapiInstance();
|
|
49
57
|
let source;
|
|
50
58
|
let destination;
|
|
51
59
|
|
|
52
|
-
if (!opts.from && !opts.to) {
|
|
53
|
-
exitWith(1, 'At least one source (from) or destination (to) option must be provided');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
60
|
// if no URL provided, use local Strapi
|
|
57
61
|
if (!opts.from) {
|
|
58
62
|
source = createLocalStrapiSourceProvider({
|
|
@@ -61,13 +65,28 @@ module.exports = async (opts) => {
|
|
|
61
65
|
}
|
|
62
66
|
// if URL provided, set up a remote source provider
|
|
63
67
|
else {
|
|
64
|
-
|
|
68
|
+
if (!opts.fromToken) {
|
|
69
|
+
exitWith(1, 'Missing token for remote destination');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
source = createRemoteStrapiSourceProvider({
|
|
73
|
+
getStrapi: () => strapi,
|
|
74
|
+
url: opts.from,
|
|
75
|
+
auth: {
|
|
76
|
+
type: 'token',
|
|
77
|
+
token: opts.fromToken,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
65
80
|
}
|
|
66
81
|
|
|
67
82
|
// if no URL provided, use local Strapi
|
|
68
83
|
if (!opts.to) {
|
|
69
84
|
destination = createLocalStrapiDestinationProvider({
|
|
70
85
|
getStrapi: () => strapi,
|
|
86
|
+
strategy: 'restore',
|
|
87
|
+
restore: {
|
|
88
|
+
entities: { exclude: DEFAULT_IGNORED_CONTENT_TYPES },
|
|
89
|
+
},
|
|
71
90
|
});
|
|
72
91
|
}
|
|
73
92
|
// if URL provided, set up a remote destination provider
|
|
@@ -96,6 +115,9 @@ module.exports = async (opts) => {
|
|
|
96
115
|
const engine = createTransferEngine(source, destination, {
|
|
97
116
|
versionStrategy: 'exact',
|
|
98
117
|
schemaStrategy: 'strict',
|
|
118
|
+
exclude: opts.exclude,
|
|
119
|
+
only: opts.only,
|
|
120
|
+
throttle: opts.throttle,
|
|
99
121
|
transforms: {
|
|
100
122
|
links: [
|
|
101
123
|
{
|
|
@@ -135,15 +157,26 @@ module.exports = async (opts) => {
|
|
|
135
157
|
updateLoader(stage, data);
|
|
136
158
|
});
|
|
137
159
|
|
|
160
|
+
progress.on('stage::error', ({ stage, data }) => {
|
|
161
|
+
updateLoader(stage, data).fail();
|
|
162
|
+
});
|
|
163
|
+
|
|
138
164
|
let results;
|
|
139
165
|
try {
|
|
140
166
|
console.log(`Starting transfer...`);
|
|
167
|
+
|
|
168
|
+
// Abort transfer if user interrupts process
|
|
169
|
+
['SIGTERM', 'SIGINT', 'SIGQUIT'].forEach((signal) => {
|
|
170
|
+
process.removeAllListeners(signal);
|
|
171
|
+
process.on(signal, () => abortTransfer({ engine, strapi }));
|
|
172
|
+
});
|
|
173
|
+
|
|
141
174
|
results = await engine.transfer();
|
|
142
175
|
} catch (e) {
|
|
143
|
-
exitWith(1, '
|
|
176
|
+
exitWith(1, exitMessageText('transfer', true));
|
|
144
177
|
}
|
|
145
178
|
|
|
146
179
|
const table = buildTransferTable(results.engine);
|
|
147
180
|
console.log(table.toString());
|
|
148
|
-
exitWith(0,
|
|
181
|
+
exitWith(0, exitMessageText('transfer'));
|
|
149
182
|
};
|
|
@@ -14,7 +14,19 @@ const {
|
|
|
14
14
|
const ora = require('ora');
|
|
15
15
|
const { readableBytes, exitWith } = require('../utils/helpers');
|
|
16
16
|
const strapi = require('../../index');
|
|
17
|
-
const { getParseListWithChoices } = require('../utils/commander');
|
|
17
|
+
const { getParseListWithChoices, parseInteger } = require('../utils/commander');
|
|
18
|
+
|
|
19
|
+
const exitMessageText = (process, error = false) => {
|
|
20
|
+
const processCapitalized = process[0].toUpperCase() + process.slice(1);
|
|
21
|
+
|
|
22
|
+
if (!error) {
|
|
23
|
+
return chalk.bold(
|
|
24
|
+
chalk.green(`${processCapitalized} process has been completed successfully!`)
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return chalk.bold(chalk.red(`${processCapitalized} process failed.`));
|
|
29
|
+
};
|
|
18
30
|
|
|
19
31
|
const pad = (n) => {
|
|
20
32
|
return (n < 10 ? '0' : '') + String(n);
|
|
@@ -90,12 +102,23 @@ const DEFAULT_IGNORED_CONTENT_TYPES = [
|
|
|
90
102
|
'admin::audit-log',
|
|
91
103
|
];
|
|
92
104
|
|
|
93
|
-
const
|
|
105
|
+
const abortTransfer = async ({ engine, strapi }) => {
|
|
106
|
+
try {
|
|
107
|
+
await engine.abortTransfer();
|
|
108
|
+
await strapi.destroy();
|
|
109
|
+
} catch (e) {
|
|
110
|
+
// ignore because there's not much else we can do
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
return true;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const createStrapiInstance = async (opts = {}) => {
|
|
94
117
|
try {
|
|
95
118
|
const appContext = await strapi.compile();
|
|
96
|
-
const app = strapi(appContext);
|
|
119
|
+
const app = strapi({ ...opts, ...appContext });
|
|
97
120
|
|
|
98
|
-
app.log.level = logLevel;
|
|
121
|
+
app.log.level = opts.logLevel || 'error';
|
|
99
122
|
return await app.load();
|
|
100
123
|
} catch (err) {
|
|
101
124
|
if (err.code === 'ECONNREFUSED') {
|
|
@@ -107,6 +130,13 @@ const createStrapiInstance = async (logLevel = 'error') => {
|
|
|
107
130
|
|
|
108
131
|
const transferDataTypes = Object.keys(TransferGroupPresets);
|
|
109
132
|
|
|
133
|
+
const throttleOption = new Option(
|
|
134
|
+
'--throttle <delay after each entity>',
|
|
135
|
+
`Add a delay in milliseconds between each transferred entity`
|
|
136
|
+
)
|
|
137
|
+
.argParser(parseInteger)
|
|
138
|
+
.hideHelp(); // This option is not publicly documented
|
|
139
|
+
|
|
110
140
|
const excludeOption = new Option(
|
|
111
141
|
'--exclude <comma-separated data types>',
|
|
112
142
|
`Exclude data using comma-separated types. Available types: ${transferDataTypes.join(',')}`
|
|
@@ -219,7 +249,10 @@ module.exports = {
|
|
|
219
249
|
DEFAULT_IGNORED_CONTENT_TYPES,
|
|
220
250
|
createStrapiInstance,
|
|
221
251
|
excludeOption,
|
|
252
|
+
exitMessageText,
|
|
222
253
|
onlyOption,
|
|
254
|
+
throttleOption,
|
|
223
255
|
validateExcludeOnly,
|
|
224
256
|
formatDiagnostic,
|
|
257
|
+
abortTransfer,
|
|
225
258
|
};
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
const inquirer = require('inquirer');
|
|
8
8
|
const { InvalidOptionArgumentError, Option } = require('commander');
|
|
9
9
|
const { bold, green, cyan } = require('chalk');
|
|
10
|
+
const { isNaN } = require('lodash/fp');
|
|
10
11
|
const { exitWith } = require('./helpers');
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -40,6 +41,18 @@ const getParseListWithChoices = (choices, errorMessage = 'Invalid options:') =>
|
|
|
40
41
|
};
|
|
41
42
|
};
|
|
42
43
|
|
|
44
|
+
/**
|
|
45
|
+
* argParser: Parse a string as an integer
|
|
46
|
+
*/
|
|
47
|
+
const parseInteger = (value) => {
|
|
48
|
+
// parseInt takes a string and a radix
|
|
49
|
+
const parsedValue = parseInt(value, 10);
|
|
50
|
+
if (isNaN(parsedValue)) {
|
|
51
|
+
throw new InvalidOptionArgumentError(`Not an integer: ${value}`);
|
|
52
|
+
}
|
|
53
|
+
return parsedValue;
|
|
54
|
+
};
|
|
55
|
+
|
|
43
56
|
/**
|
|
44
57
|
* argParser: Parse a string as a URL object
|
|
45
58
|
*/
|
|
@@ -131,6 +144,7 @@ module.exports = {
|
|
|
131
144
|
getParseListWithChoices,
|
|
132
145
|
parseList,
|
|
133
146
|
parseURL,
|
|
147
|
+
parseInteger,
|
|
134
148
|
promptEncryptionKey,
|
|
135
149
|
confirmMessage,
|
|
136
150
|
forceOption,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/strapi",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.9.0-beta.1",
|
|
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.9.0-beta.1",
|
|
85
|
+
"@strapi/data-transfer": "4.9.0-beta.1",
|
|
86
|
+
"@strapi/database": "4.9.0-beta.1",
|
|
87
|
+
"@strapi/generate-new": "4.9.0-beta.1",
|
|
88
|
+
"@strapi/generators": "4.9.0-beta.1",
|
|
89
|
+
"@strapi/logger": "4.9.0-beta.1",
|
|
90
|
+
"@strapi/permissions": "4.9.0-beta.1",
|
|
91
|
+
"@strapi/plugin-content-manager": "4.9.0-beta.1",
|
|
92
|
+
"@strapi/plugin-content-type-builder": "4.9.0-beta.1",
|
|
93
|
+
"@strapi/plugin-email": "4.9.0-beta.1",
|
|
94
|
+
"@strapi/plugin-upload": "4.9.0-beta.1",
|
|
95
|
+
"@strapi/typescript-utils": "4.9.0-beta.1",
|
|
96
|
+
"@strapi/utils": "4.9.0-beta.1",
|
|
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": "ff37d666d0634fc84827e3d6419d916618275572"
|
|
146
146
|
}
|