@strapi/strapi 4.9.0 → 4.9.2
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 +8 -0
- package/lib/Strapi.js +11 -7
- package/lib/commands/report.js +35 -0
- package/lib/commands/transfer/export.js +6 -12
- package/lib/commands/transfer/import.js +8 -12
- package/lib/commands/transfer/transfer.js +18 -4
- package/lib/commands/transfer/utils.js +16 -0
- package/lib/core/domain/content-type/validator.js +1 -1
- package/lib/middlewares/security.js +1 -1
- package/lib/services/metrics/sender.js +0 -12
- package/lib/services/server/index.js +2 -2
- package/lib/services/utils/dynamic-zones.js +13 -0
- package/package.json +18 -18
package/bin/strapi.js
CHANGED
|
@@ -258,6 +258,14 @@ program
|
|
|
258
258
|
.description('Enable anonymous telemetry and metadata sending to Strapi analytics')
|
|
259
259
|
.action(getLocalScript('opt-in-telemetry'));
|
|
260
260
|
|
|
261
|
+
program
|
|
262
|
+
.command('report')
|
|
263
|
+
.description('Get system stats for debugging and submitting issues')
|
|
264
|
+
.option('-u, --uuid', 'Include Project UUID')
|
|
265
|
+
.option('-d, --dependencies', 'Include Project Dependencies')
|
|
266
|
+
.option('--all', 'Include All Information')
|
|
267
|
+
.action(getLocalScript('report'));
|
|
268
|
+
|
|
261
269
|
program
|
|
262
270
|
.command('ts:generate-types')
|
|
263
271
|
.description(`Generate TypeScript typings for your schemas`)
|
package/lib/Strapi.js
CHANGED
|
@@ -43,6 +43,7 @@ const apisRegistry = require('./core/registries/apis');
|
|
|
43
43
|
const bootstrap = require('./core/bootstrap');
|
|
44
44
|
const loaders = require('./core/loaders');
|
|
45
45
|
const { destroyOnSignal } = require('./utils/signals');
|
|
46
|
+
const getNumberOfDynamicZones = require('./services/utils/dynamic-zones');
|
|
46
47
|
const sanitizersRegistry = require('./core/registries/sanitizers');
|
|
47
48
|
const convertCustomFieldType = require('./utils/convert-custom-field-type');
|
|
48
49
|
|
|
@@ -249,6 +250,9 @@ class Strapi {
|
|
|
249
250
|
groupProperties: {
|
|
250
251
|
database: strapi.config.get('database.connection.client'),
|
|
251
252
|
plugins: Object.keys(strapi.plugins),
|
|
253
|
+
numberOfAllContentTypes: _.size(this.contentTypes), // TODO: V5: This event should be renamed numberOfContentTypes in V5 as the name is already taken to describe the number of content types using i18n.
|
|
254
|
+
numberOfComponents: _.size(this.components),
|
|
255
|
+
numberOfDynamicZones: getNumberOfDynamicZones(),
|
|
252
256
|
// TODO: to add back
|
|
253
257
|
// providers: this.config.installedProviders,
|
|
254
258
|
},
|
|
@@ -468,7 +472,7 @@ class Strapi {
|
|
|
468
472
|
await this.startWebhooks();
|
|
469
473
|
|
|
470
474
|
await this.server.initMiddlewares();
|
|
471
|
-
|
|
475
|
+
this.server.initRouting();
|
|
472
476
|
|
|
473
477
|
await this.contentAPI.permissions.registerActions();
|
|
474
478
|
|
|
@@ -536,17 +540,17 @@ class Strapi {
|
|
|
536
540
|
// plugins
|
|
537
541
|
await this.container.get('modules')[lifecycleName]();
|
|
538
542
|
|
|
539
|
-
// user
|
|
540
|
-
const userLifecycleFunction = this.app && this.app[lifecycleName];
|
|
541
|
-
if (isFunction(userLifecycleFunction)) {
|
|
542
|
-
await userLifecycleFunction({ strapi: this });
|
|
543
|
-
}
|
|
544
|
-
|
|
545
543
|
// admin
|
|
546
544
|
const adminLifecycleFunction = this.admin && this.admin[lifecycleName];
|
|
547
545
|
if (isFunction(adminLifecycleFunction)) {
|
|
548
546
|
await adminLifecycleFunction({ strapi: this });
|
|
549
547
|
}
|
|
548
|
+
|
|
549
|
+
// user
|
|
550
|
+
const userLifecycleFunction = this.app && this.app[lifecycleName];
|
|
551
|
+
if (isFunction(userLifecycleFunction)) {
|
|
552
|
+
await userLifecycleFunction({ strapi: this });
|
|
553
|
+
}
|
|
550
554
|
}
|
|
551
555
|
|
|
552
556
|
getModel(uid) {
|
|
@@ -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
|
+
};
|
|
@@ -24,6 +24,7 @@ const {
|
|
|
24
24
|
loadersFactory,
|
|
25
25
|
exitMessageText,
|
|
26
26
|
abortTransfer,
|
|
27
|
+
getTransferTelemetryPayload,
|
|
27
28
|
} = require('./utils');
|
|
28
29
|
const { exitWith } = require('../utils/helpers');
|
|
29
30
|
/**
|
|
@@ -103,19 +104,10 @@ module.exports = async (opts) => {
|
|
|
103
104
|
updateLoader(stage, data);
|
|
104
105
|
});
|
|
105
106
|
|
|
106
|
-
const getTelemetryPayload = (/* payload */) => {
|
|
107
|
-
return {
|
|
108
|
-
eventProperties: {
|
|
109
|
-
source: engine.sourceProvider.name,
|
|
110
|
-
destination: engine.destinationProvider.name,
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
};
|
|
114
|
-
|
|
115
107
|
progress.on('transfer::start', async () => {
|
|
116
108
|
console.log(`Starting export...`);
|
|
117
109
|
|
|
118
|
-
await strapi.telemetry.send('didDEITSProcessStart',
|
|
110
|
+
await strapi.telemetry.send('didDEITSProcessStart', getTransferTelemetryPayload(engine));
|
|
119
111
|
});
|
|
120
112
|
|
|
121
113
|
let results;
|
|
@@ -134,11 +126,13 @@ module.exports = async (opts) => {
|
|
|
134
126
|
throw new TransferEngineTransferError(`Export file not created "${outFile}"`);
|
|
135
127
|
}
|
|
136
128
|
} catch {
|
|
137
|
-
await strapi.telemetry.send('didDEITSProcessFail',
|
|
129
|
+
await strapi.telemetry.send('didDEITSProcessFail', getTransferTelemetryPayload(engine));
|
|
138
130
|
exitWith(1, exitMessageText('export', true));
|
|
139
131
|
}
|
|
140
132
|
|
|
141
|
-
await
|
|
133
|
+
// Note: we need to await telemetry or else the process ends before it is sent
|
|
134
|
+
await strapi.telemetry.send('didDEITSProcessFinish', getTransferTelemetryPayload(engine));
|
|
135
|
+
|
|
142
136
|
try {
|
|
143
137
|
const table = buildTransferTable(results.engine);
|
|
144
138
|
console.log(table.toString());
|
|
@@ -20,6 +20,7 @@ const {
|
|
|
20
20
|
loadersFactory,
|
|
21
21
|
exitMessageText,
|
|
22
22
|
abortTransfer,
|
|
23
|
+
getTransferTelemetryPayload,
|
|
23
24
|
} = require('./utils');
|
|
24
25
|
const { exitWith } = require('../utils/helpers');
|
|
25
26
|
|
|
@@ -122,18 +123,12 @@ module.exports = async (opts) => {
|
|
|
122
123
|
updateLoader(stage, data);
|
|
123
124
|
});
|
|
124
125
|
|
|
125
|
-
const getTelemetryPayload = () => {
|
|
126
|
-
return {
|
|
127
|
-
eventProperties: {
|
|
128
|
-
source: engine.sourceProvider.name,
|
|
129
|
-
destination: engine.destinationProvider.name,
|
|
130
|
-
},
|
|
131
|
-
};
|
|
132
|
-
};
|
|
133
|
-
|
|
134
126
|
progress.on('transfer::start', async () => {
|
|
135
127
|
console.log('Starting import...');
|
|
136
|
-
await strapiInstance.telemetry.send(
|
|
128
|
+
await strapiInstance.telemetry.send(
|
|
129
|
+
'didDEITSProcessStart',
|
|
130
|
+
getTransferTelemetryPayload(engine)
|
|
131
|
+
);
|
|
137
132
|
});
|
|
138
133
|
|
|
139
134
|
let results;
|
|
@@ -146,7 +141,7 @@ module.exports = async (opts) => {
|
|
|
146
141
|
|
|
147
142
|
results = await engine.transfer();
|
|
148
143
|
} catch (e) {
|
|
149
|
-
await strapiInstance.telemetry.send('didDEITSProcessFail',
|
|
144
|
+
await strapiInstance.telemetry.send('didDEITSProcessFail', getTransferTelemetryPayload(engine));
|
|
150
145
|
exitWith(1, exitMessageText('import', true));
|
|
151
146
|
}
|
|
152
147
|
|
|
@@ -157,7 +152,8 @@ module.exports = async (opts) => {
|
|
|
157
152
|
console.error('There was an error displaying the results of the transfer.');
|
|
158
153
|
}
|
|
159
154
|
|
|
160
|
-
await
|
|
155
|
+
// Note: we need to await telemetry or else the process ends before it is sent
|
|
156
|
+
await strapiInstance.telemetry.send('didDEITSProcessFinish', getTransferTelemetryPayload(engine));
|
|
161
157
|
await strapiInstance.destroy();
|
|
162
158
|
|
|
163
159
|
exitWith(0, exitMessageText('import'));
|
|
@@ -21,6 +21,7 @@ const {
|
|
|
21
21
|
loadersFactory,
|
|
22
22
|
exitMessageText,
|
|
23
23
|
abortTransfer,
|
|
24
|
+
getTransferTelemetryPayload,
|
|
24
25
|
} = require('./utils');
|
|
25
26
|
const { exitWith } = require('../utils/helpers');
|
|
26
27
|
|
|
@@ -161,10 +162,14 @@ module.exports = async (opts) => {
|
|
|
161
162
|
updateLoader(stage, data).fail();
|
|
162
163
|
});
|
|
163
164
|
|
|
164
|
-
|
|
165
|
-
try {
|
|
165
|
+
progress.on('transfer::start', async () => {
|
|
166
166
|
console.log(`Starting transfer...`);
|
|
167
167
|
|
|
168
|
+
await strapi.telemetry.send('didDEITSProcessStart', getTransferTelemetryPayload(engine));
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
let results;
|
|
172
|
+
try {
|
|
168
173
|
// Abort transfer if user interrupts process
|
|
169
174
|
['SIGTERM', 'SIGINT', 'SIGQUIT'].forEach((signal) => {
|
|
170
175
|
process.removeAllListeners(signal);
|
|
@@ -173,10 +178,19 @@ module.exports = async (opts) => {
|
|
|
173
178
|
|
|
174
179
|
results = await engine.transfer();
|
|
175
180
|
} catch (e) {
|
|
181
|
+
await strapi.telemetry.send('didDEITSProcessFail', getTransferTelemetryPayload(engine));
|
|
176
182
|
exitWith(1, exitMessageText('transfer', true));
|
|
177
183
|
}
|
|
178
184
|
|
|
179
|
-
|
|
180
|
-
|
|
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.');
|
|
193
|
+
}
|
|
194
|
+
|
|
181
195
|
exitWith(0, exitMessageText('transfer'));
|
|
182
196
|
};
|
|
@@ -242,10 +242,26 @@ const loadersFactory = (defaultLoaders = {}) => {
|
|
|
242
242
|
};
|
|
243
243
|
};
|
|
244
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Get the telemetry data to be sent for a didDEITSProcess* event from an initialized transfer engine object
|
|
247
|
+
*
|
|
248
|
+
* @param {import('@strapi/data-transfer/types').ITransferEngine} engine Initialized transfer engine
|
|
249
|
+
* @returns {object} Telemetry properties object
|
|
250
|
+
*/
|
|
251
|
+
const getTransferTelemetryPayload = (engine) => {
|
|
252
|
+
return {
|
|
253
|
+
eventProperties: {
|
|
254
|
+
source: engine?.sourceProvider?.name,
|
|
255
|
+
destination: engine?.destinationProvider?.name,
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
};
|
|
259
|
+
|
|
245
260
|
module.exports = {
|
|
246
261
|
loadersFactory,
|
|
247
262
|
buildTransferTable,
|
|
248
263
|
getDefaultExportName,
|
|
264
|
+
getTransferTelemetryPayload,
|
|
249
265
|
DEFAULT_IGNORED_CONTENT_TYPES,
|
|
250
266
|
createStrapiInstance,
|
|
251
267
|
excludeOption,
|
|
@@ -61,7 +61,7 @@ const contentTypeSchemaValidator = yup.object().shape({
|
|
|
61
61
|
|
|
62
62
|
// should match the GraphQL regex
|
|
63
63
|
if (!regressedValues.every((value) => GRAPHQL_ENUM_REGEX.test(value))) {
|
|
64
|
-
const message = `Invalid enumeration value. Values should have at least one alphabetical character
|
|
64
|
+
const message = `Invalid enumeration value. Values should have at least one alphabetical character preceding the first occurence of a number. Update your enumeration '${attrName}'.`;
|
|
65
65
|
|
|
66
66
|
return this.createError({ message });
|
|
67
67
|
}
|
|
@@ -12,7 +12,7 @@ const defaults = {
|
|
|
12
12
|
useDefaults: true,
|
|
13
13
|
directives: {
|
|
14
14
|
'connect-src': ["'self'", 'https:'],
|
|
15
|
-
'img-src': ["'self'", 'data:', 'blob:', 'https://
|
|
15
|
+
'img-src': ["'self'", 'data:', 'blob:', 'https://market-assets.strapi.io'],
|
|
16
16
|
'media-src': ["'self'", 'data:', 'blob:'],
|
|
17
17
|
upgradeInsecureRequests: null,
|
|
18
18
|
},
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const os = require('os');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const _ = require('lodash');
|
|
6
|
-
const { map, values, sumBy, pipe, flatMap, propEq } = require('lodash/fp');
|
|
7
6
|
const isDocker = require('is-docker');
|
|
8
7
|
const fetch = require('node-fetch');
|
|
9
8
|
const ciEnv = require('ci-info');
|
|
@@ -41,14 +40,6 @@ module.exports = (strapi) => {
|
|
|
41
40
|
const serverRootPath = strapi.dirs.app.root;
|
|
42
41
|
const adminRootPath = path.join(strapi.dirs.app.root, 'src', 'admin');
|
|
43
42
|
|
|
44
|
-
const getNumberOfDynamicZones = () => {
|
|
45
|
-
return pipe(
|
|
46
|
-
map('attributes'),
|
|
47
|
-
flatMap(values),
|
|
48
|
-
sumBy(propEq('type', 'dynamiczone'))
|
|
49
|
-
)(strapi.contentTypes);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
43
|
const anonymousUserProperties = {
|
|
53
44
|
environment: strapi.config.environment,
|
|
54
45
|
os: os.type(),
|
|
@@ -66,9 +57,6 @@ module.exports = (strapi) => {
|
|
|
66
57
|
useTypescriptOnAdmin: isUsingTypeScriptSync(adminRootPath),
|
|
67
58
|
projectId: uuid,
|
|
68
59
|
isHostedOnStrapiCloud: env('STRAPI_HOSTING', null) === 'strapi.cloud',
|
|
69
|
-
numberOfAllContentTypes: _.size(strapi.contentTypes), // TODO: V5: This event should be renamed numberOfContentTypes in V5 as the name is already taken to describe the number of content types using i18n.
|
|
70
|
-
numberOfComponents: _.size(strapi.components),
|
|
71
|
-
numberOfDynamicZones: getNumberOfDynamicZones(),
|
|
72
60
|
};
|
|
73
61
|
|
|
74
62
|
addPackageJsonStrapiMetadata(anonymousGroupProperties, strapi);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { map, values, sumBy, pipe, flatMap, propEq } = require('lodash/fp');
|
|
4
|
+
|
|
5
|
+
const getNumberOfDynamicZones = () => {
|
|
6
|
+
return pipe(
|
|
7
|
+
map('attributes'),
|
|
8
|
+
flatMap(values),
|
|
9
|
+
sumBy(propEq('type', 'dynamiczone'))
|
|
10
|
+
)(strapi.contentTypes);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
module.exports = getNumberOfDynamicZones;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/strapi",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.2",
|
|
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",
|
|
@@ -74,26 +74,26 @@
|
|
|
74
74
|
},
|
|
75
75
|
"scripts": {
|
|
76
76
|
"postinstall": "node lib/utils/success.js",
|
|
77
|
-
"test:unit": "jest",
|
|
78
|
-
"test:unit:watch": "jest --watch",
|
|
79
|
-
"lint": "eslint ."
|
|
77
|
+
"test:unit": "run -T jest",
|
|
78
|
+
"test:unit:watch": "run -T jest --watch",
|
|
79
|
+
"lint": "run -T eslint ."
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"@koa/cors": "3.4.3",
|
|
83
83
|
"@koa/router": "10.1.1",
|
|
84
|
-
"@strapi/admin": "4.9.
|
|
85
|
-
"@strapi/data-transfer": "4.9.
|
|
86
|
-
"@strapi/database": "4.9.
|
|
87
|
-
"@strapi/generate-new": "4.9.
|
|
88
|
-
"@strapi/generators": "4.9.
|
|
89
|
-
"@strapi/logger": "4.9.
|
|
90
|
-
"@strapi/permissions": "4.9.
|
|
91
|
-
"@strapi/plugin-content-manager": "4.9.
|
|
92
|
-
"@strapi/plugin-content-type-builder": "4.9.
|
|
93
|
-
"@strapi/plugin-email": "4.9.
|
|
94
|
-
"@strapi/plugin-upload": "4.9.
|
|
95
|
-
"@strapi/typescript-utils": "4.9.
|
|
96
|
-
"@strapi/utils": "4.9.
|
|
84
|
+
"@strapi/admin": "4.9.2",
|
|
85
|
+
"@strapi/data-transfer": "4.9.2",
|
|
86
|
+
"@strapi/database": "4.9.2",
|
|
87
|
+
"@strapi/generate-new": "4.9.2",
|
|
88
|
+
"@strapi/generators": "4.9.2",
|
|
89
|
+
"@strapi/logger": "4.9.2",
|
|
90
|
+
"@strapi/permissions": "4.9.2",
|
|
91
|
+
"@strapi/plugin-content-manager": "4.9.2",
|
|
92
|
+
"@strapi/plugin-content-type-builder": "4.9.2",
|
|
93
|
+
"@strapi/plugin-email": "4.9.2",
|
|
94
|
+
"@strapi/plugin-upload": "4.9.2",
|
|
95
|
+
"@strapi/typescript-utils": "4.9.2",
|
|
96
|
+
"@strapi/utils": "4.9.2",
|
|
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": "91e0be2708e4d1e8ec731c75e73e54c0dfacb67d"
|
|
146
146
|
}
|