@strapi/strapi 4.0.0-beta.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/LICENSE +22 -0
- package/README.md +144 -0
- package/bin/strapi.js +186 -0
- package/lib/Strapi.js +470 -0
- package/lib/commands/admin-reset.js +51 -0
- package/lib/commands/build.js +56 -0
- package/lib/commands/configurationDump.js +50 -0
- package/lib/commands/configurationRestore.js +169 -0
- package/lib/commands/console.js +26 -0
- package/lib/commands/develop.js +157 -0
- package/lib/commands/generate-template.js +97 -0
- package/lib/commands/install.js +48 -0
- package/lib/commands/new.js +11 -0
- package/lib/commands/start.js +8 -0
- package/lib/commands/uninstall.js +68 -0
- package/lib/commands/watchAdmin.js +45 -0
- package/lib/container.js +45 -0
- package/lib/core/app-configuration/config-loader.js +20 -0
- package/lib/core/app-configuration/index.js +75 -0
- package/lib/core/app-configuration/load-config-file.js +43 -0
- package/lib/core/app-configuration/load-functions.js +28 -0
- package/lib/core/bootstrap.js +60 -0
- package/lib/core/domain/component/index.js +24 -0
- package/lib/core/domain/component/validator.js +29 -0
- package/lib/core/domain/content-type/index.js +140 -0
- package/lib/core/domain/content-type/validator.js +64 -0
- package/lib/core/domain/module/index.js +106 -0
- package/lib/core/domain/module/validation.js +36 -0
- package/lib/core/loaders/admin.js +16 -0
- package/lib/core/loaders/apis.js +157 -0
- package/lib/core/loaders/components.js +41 -0
- package/lib/core/loaders/index.js +11 -0
- package/lib/core/loaders/middlewares.js +86 -0
- package/lib/core/loaders/plugins/get-enabled-plugins.js +100 -0
- package/lib/core/loaders/plugins/index.js +109 -0
- package/lib/core/loaders/policies.js +28 -0
- package/lib/core/loaders/src-index.js +38 -0
- package/lib/core/registries/apis.js +43 -0
- package/lib/core/registries/config.js +21 -0
- package/lib/core/registries/content-types.js +53 -0
- package/lib/core/registries/controllers.js +43 -0
- package/lib/core/registries/hooks.js +37 -0
- package/lib/core/registries/middlewares.js +30 -0
- package/lib/core/registries/modules.js +44 -0
- package/lib/core/registries/plugins.js +28 -0
- package/lib/core/registries/policies.js +38 -0
- package/lib/core/registries/services.js +58 -0
- package/lib/core/utils.js +35 -0
- package/lib/core-api/controller/collection-type.js +84 -0
- package/lib/core-api/controller/index.js +26 -0
- package/lib/core-api/controller/single-type.js +44 -0
- package/lib/core-api/controller/transform.js +97 -0
- package/lib/core-api/index.js +39 -0
- package/lib/core-api/service/collection-type.js +84 -0
- package/lib/core-api/service/index.js +55 -0
- package/lib/core-api/service/pagination.js +125 -0
- package/lib/core-api/service/single-type.js +58 -0
- package/lib/index.d.ts +26 -0
- package/lib/index.js +3 -0
- package/lib/load/filepath-to-prop-path.js +22 -0
- package/lib/load/glob.js +15 -0
- package/lib/load/index.js +9 -0
- package/lib/load/load-files.js +56 -0
- package/lib/load/package-path.js +9 -0
- package/lib/middlewares/cors/index.js +66 -0
- package/lib/middlewares/error/defaults.json +5 -0
- package/lib/middlewares/error/index.js +147 -0
- package/lib/middlewares/favicon/defaults.json +7 -0
- package/lib/middlewares/favicon/index.js +31 -0
- package/lib/middlewares/gzip/defaults.json +6 -0
- package/lib/middlewares/gzip/index.js +19 -0
- package/lib/middlewares/helmet/defaults.json +18 -0
- package/lib/middlewares/helmet/index.js +9 -0
- package/lib/middlewares/index.js +120 -0
- package/lib/middlewares/ip/defaults.json +7 -0
- package/lib/middlewares/ip/index.js +25 -0
- package/lib/middlewares/logger/defaults.json +5 -0
- package/lib/middlewares/logger/index.js +37 -0
- package/lib/middlewares/parser/defaults.json +11 -0
- package/lib/middlewares/parser/index.js +75 -0
- package/lib/middlewares/poweredBy/defaults.json +5 -0
- package/lib/middlewares/poweredBy/index.js +16 -0
- package/lib/middlewares/public/assets/images/group_people_1.png +0 -0
- package/lib/middlewares/public/assets/images/group_people_2.png +0 -0
- package/lib/middlewares/public/assets/images/group_people_3.png +0 -0
- package/lib/middlewares/public/assets/images/logo_login.png +0 -0
- package/lib/middlewares/public/defaults.json +8 -0
- package/lib/middlewares/public/index.html +66 -0
- package/lib/middlewares/public/index.js +130 -0
- package/lib/middlewares/public/serve-static.js +23 -0
- package/lib/middlewares/responseTime/defaults.json +5 -0
- package/lib/middlewares/responseTime/index.js +25 -0
- package/lib/middlewares/responses/defaults.json +5 -0
- package/lib/middlewares/responses/index.js +19 -0
- package/lib/middlewares/router/defaults.json +7 -0
- package/lib/middlewares/router/index.js +97 -0
- package/lib/middlewares/session/defaults.json +18 -0
- package/lib/middlewares/session/index.js +140 -0
- package/lib/migrations/draft-publish.js +57 -0
- package/lib/services/auth/index.js +92 -0
- package/lib/services/core-store.js +145 -0
- package/lib/services/cron.js +54 -0
- package/lib/services/entity-service/components.js +365 -0
- package/lib/services/entity-service/index.d.ts +91 -0
- package/lib/services/entity-service/index.js +244 -0
- package/lib/services/entity-service/params.js +145 -0
- package/lib/services/entity-validator/index.js +187 -0
- package/lib/services/entity-validator/validators.js +123 -0
- package/lib/services/event-hub.js +15 -0
- package/lib/services/fs.js +58 -0
- package/lib/services/metrics/index.js +104 -0
- package/lib/services/metrics/is-truthy.js +9 -0
- package/lib/services/metrics/middleware.js +33 -0
- package/lib/services/metrics/rate-limiter.js +27 -0
- package/lib/services/metrics/sender.js +76 -0
- package/lib/services/metrics/stringify-deep.js +22 -0
- package/lib/services/server/admin-api.js +14 -0
- package/lib/services/server/api.js +32 -0
- package/lib/services/server/compose-endpoint.js +112 -0
- package/lib/services/server/content-api.js +16 -0
- package/lib/services/server/http-server.js +64 -0
- package/lib/services/server/index.js +108 -0
- package/lib/services/server/middleware.js +28 -0
- package/lib/services/server/policy.js +34 -0
- package/lib/services/server/routing.js +107 -0
- package/lib/services/utils/upload-files.js +79 -0
- package/lib/services/webhook-runner.js +155 -0
- package/lib/services/webhook-store.js +91 -0
- package/lib/services/worker-queue.js +58 -0
- package/lib/utils/addSlash.js +10 -0
- package/lib/utils/ee.js +123 -0
- package/lib/utils/get-dirs.js +15 -0
- package/lib/utils/get-prefixed-dependencies.js +7 -0
- package/lib/utils/index.js +11 -0
- package/lib/utils/is-initialized.js +23 -0
- package/lib/utils/open-browser.js +12 -0
- package/lib/utils/resources/key.pub +9 -0
- package/lib/utils/run-checks.js +22 -0
- package/lib/utils/startup-logger.js +90 -0
- package/lib/utils/success.js +31 -0
- package/lib/utils/update-notifier/index.js +97 -0
- package/lib/utils/url-from-segments.js +12 -0
- package/package.json +133 -0
package/lib/Strapi.js
ADDED
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const { createLogger } = require('@strapi/logger');
|
|
5
|
+
const { Database } = require('@strapi/database');
|
|
6
|
+
const { createAsyncParallelHook } = require('@strapi/utils').hooks;
|
|
7
|
+
|
|
8
|
+
const loadConfiguration = require('./core/app-configuration');
|
|
9
|
+
|
|
10
|
+
const { createContainer } = require('./container');
|
|
11
|
+
const utils = require('./utils');
|
|
12
|
+
const initializeMiddlewares = require('./middlewares');
|
|
13
|
+
const createStrapiFs = require('./services/fs');
|
|
14
|
+
const createEventHub = require('./services/event-hub');
|
|
15
|
+
const { createServer } = require('./services/server');
|
|
16
|
+
const createWebhookRunner = require('./services/webhook-runner');
|
|
17
|
+
const { webhookModel, createWebhookStore } = require('./services/webhook-store');
|
|
18
|
+
const { createCoreStore, coreStoreModel } = require('./services/core-store');
|
|
19
|
+
const createEntityService = require('./services/entity-service');
|
|
20
|
+
const createCronService = require('./services/cron');
|
|
21
|
+
const entityValidator = require('./services/entity-validator');
|
|
22
|
+
const createTelemetry = require('./services/metrics');
|
|
23
|
+
const createAuth = require('./services/auth');
|
|
24
|
+
const createUpdateNotifier = require('./utils/update-notifier');
|
|
25
|
+
const createStartupLogger = require('./utils/startup-logger');
|
|
26
|
+
const ee = require('./utils/ee');
|
|
27
|
+
const contentTypesRegistry = require('./core/registries/content-types');
|
|
28
|
+
const servicesRegistry = require('./core/registries/services');
|
|
29
|
+
const policiesRegistry = require('./core/registries/policies');
|
|
30
|
+
const middlewaresRegistry = require('./core/registries/middlewares');
|
|
31
|
+
const hooksRegistry = require('./core/registries/hooks');
|
|
32
|
+
const controllersRegistry = require('./core/registries/controllers');
|
|
33
|
+
const modulesRegistry = require('./core/registries/modules');
|
|
34
|
+
const pluginsRegistry = require('./core/registries/plugins');
|
|
35
|
+
const createConfigProvider = require('./core/registries/config');
|
|
36
|
+
const apisRegistry = require('./core/registries/apis');
|
|
37
|
+
const bootstrap = require('./core/bootstrap');
|
|
38
|
+
const loaders = require('./core/loaders');
|
|
39
|
+
|
|
40
|
+
// TODO: move somewhere else
|
|
41
|
+
const draftAndPublishSync = require('./migrations/draft-publish');
|
|
42
|
+
|
|
43
|
+
const LIFECYCLES = {
|
|
44
|
+
REGISTER: 'register',
|
|
45
|
+
BOOTSTRAP: 'bootstrap',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
class Strapi {
|
|
49
|
+
constructor(opts = {}) {
|
|
50
|
+
this.dirs = utils.getDirs(opts.dir || process.cwd());
|
|
51
|
+
const appConfig = loadConfiguration(this.dirs.root, opts);
|
|
52
|
+
this.container = createContainer(this);
|
|
53
|
+
this.container.register('config', createConfigProvider(appConfig));
|
|
54
|
+
this.container.register('content-types', contentTypesRegistry(this));
|
|
55
|
+
this.container.register('services', servicesRegistry(this));
|
|
56
|
+
this.container.register('policies', policiesRegistry(this));
|
|
57
|
+
this.container.register('middlewares', middlewaresRegistry(this));
|
|
58
|
+
this.container.register('hooks', hooksRegistry(this));
|
|
59
|
+
this.container.register('controllers', controllersRegistry(this));
|
|
60
|
+
this.container.register('modules', modulesRegistry(this));
|
|
61
|
+
this.container.register('plugins', pluginsRegistry(this));
|
|
62
|
+
this.container.register('apis', apisRegistry(this));
|
|
63
|
+
this.container.register('auth', createAuth(this));
|
|
64
|
+
|
|
65
|
+
this.isLoaded = false;
|
|
66
|
+
this.reload = this.reload();
|
|
67
|
+
this.server = createServer(this);
|
|
68
|
+
|
|
69
|
+
this.fs = createStrapiFs(this);
|
|
70
|
+
this.eventHub = createEventHub();
|
|
71
|
+
this.startupLogger = createStartupLogger(this);
|
|
72
|
+
this.log = createLogger(this.config.get('logger', {}));
|
|
73
|
+
this.cron = createCronService();
|
|
74
|
+
|
|
75
|
+
createUpdateNotifier(this).notify();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
get config() {
|
|
79
|
+
return this.container.get('config');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
get EE() {
|
|
83
|
+
return ee({ dir: this.dirs.root, logger: this.log });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
service(uid) {
|
|
87
|
+
return this.container.get('services').get(uid);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
controller(uid) {
|
|
91
|
+
return this.container.get('controllers').get(uid);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
contentType(name) {
|
|
95
|
+
return this.container.get('content-types').get(name);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
get contentTypes() {
|
|
99
|
+
return this.container.get('content-types').getAll();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
policy(name) {
|
|
103
|
+
return this.container.get('policies').get(name);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
middleware(name) {
|
|
107
|
+
return this.container.get('middlewares').get(name);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
plugin(name) {
|
|
111
|
+
return this.container.get('plugins').get(name);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get plugins() {
|
|
115
|
+
return this.container.get('plugins').getAll();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
hook(name) {
|
|
119
|
+
return this.container.get('hooks').get(name);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
get hooks() {
|
|
123
|
+
return this.container.get('hooks');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// api(name) {
|
|
127
|
+
// return this.container.get('apis').get(name);
|
|
128
|
+
// }
|
|
129
|
+
|
|
130
|
+
get api() {
|
|
131
|
+
return this.container.get('apis').getAll();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
get auth() {
|
|
135
|
+
return this.container.get('auth');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async start() {
|
|
139
|
+
try {
|
|
140
|
+
if (!this.isLoaded) {
|
|
141
|
+
await this.load();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
await this.listen();
|
|
145
|
+
|
|
146
|
+
return this;
|
|
147
|
+
} catch (error) {
|
|
148
|
+
return this.stopWithError(error);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async destroy() {
|
|
153
|
+
await this.server.destroy();
|
|
154
|
+
|
|
155
|
+
await Promise.all(
|
|
156
|
+
Object.values(this.plugins).map(plugin => {
|
|
157
|
+
if (_.has(plugin, 'destroy') && typeof plugin.destroy === 'function') {
|
|
158
|
+
return plugin.destroy();
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
if (_.has(this, 'admin')) {
|
|
164
|
+
await this.admin.destroy();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
this.eventHub.removeAllListeners();
|
|
168
|
+
|
|
169
|
+
if (_.has(this, 'db')) {
|
|
170
|
+
await this.db.destroy();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
this.telemetry.destroy();
|
|
174
|
+
this.cron.destroy();
|
|
175
|
+
|
|
176
|
+
delete global.strapi;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
sendStartupTelemetry() {
|
|
180
|
+
// Get database clients
|
|
181
|
+
const databaseClients = _.map(this.config.get('connections'), _.property('settings.client'));
|
|
182
|
+
|
|
183
|
+
// Emit started event.
|
|
184
|
+
// do not await to avoid slower startup
|
|
185
|
+
this.telemetry.send('didStartServer', {
|
|
186
|
+
database: databaseClients,
|
|
187
|
+
plugins: this.config.installedPlugins,
|
|
188
|
+
providers: this.config.installedProviders,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async openAdmin({ isInitialized }) {
|
|
193
|
+
const shouldOpenAdmin =
|
|
194
|
+
this.config.get('environment') === 'development' &&
|
|
195
|
+
this.config.get('server.admin.autoOpen', true) !== false;
|
|
196
|
+
|
|
197
|
+
if (shouldOpenAdmin && !isInitialized) {
|
|
198
|
+
await utils.openBrowser(this.config);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async postListen() {
|
|
203
|
+
const isInitialized = await utils.isInitialized(this);
|
|
204
|
+
|
|
205
|
+
this.startupLogger.logStartupMessage({ isInitialized });
|
|
206
|
+
|
|
207
|
+
this.sendStartupTelemetry();
|
|
208
|
+
this.openAdmin({ isInitialized });
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Add behaviors to the server
|
|
213
|
+
*/
|
|
214
|
+
async listen() {
|
|
215
|
+
return new Promise((resolve, reject) => {
|
|
216
|
+
const onListen = async error => {
|
|
217
|
+
if (error) {
|
|
218
|
+
return reject(error);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
await this.postListen();
|
|
223
|
+
|
|
224
|
+
resolve();
|
|
225
|
+
} catch (error) {
|
|
226
|
+
reject(error);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
const listenSocket = this.config.get('server.socket');
|
|
231
|
+
|
|
232
|
+
if (listenSocket) {
|
|
233
|
+
return this.server.listen(listenSocket, onListen);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const { host, port } = this.config.get('server');
|
|
237
|
+
return this.server.listen(port, host, onListen);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
stopWithError(err, customMessage) {
|
|
242
|
+
this.log.debug(`⛔️ Server wasn't able to start properly.`);
|
|
243
|
+
if (customMessage) {
|
|
244
|
+
this.log.error(customMessage);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
this.log.error(err);
|
|
248
|
+
return this.stop();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
stop(exitCode = 1) {
|
|
252
|
+
this.server.destroy();
|
|
253
|
+
|
|
254
|
+
if (this.config.get('autoReload')) {
|
|
255
|
+
process.send('stop');
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Kill process
|
|
259
|
+
process.exit(exitCode);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async loadAdmin() {
|
|
263
|
+
await loaders.loadAdmin(this);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async loadPlugins() {
|
|
267
|
+
await loaders.loadPlugins(this);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async loadPolicies() {
|
|
271
|
+
await loaders.loadPolicies(this);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async loadAPIs() {
|
|
275
|
+
await loaders.loadAPIs(this);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async loadComponents() {
|
|
279
|
+
this.components = await loaders.loadComponents(this);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async loadMiddlewares() {
|
|
283
|
+
this.middleware = await loaders.loadMiddlewares(this);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
async loadApp() {
|
|
287
|
+
this.app = await loaders.loadSrcIndex(this);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
registerInternalHooks() {
|
|
291
|
+
this.hooks.set('strapi::content-types.beforeSync', createAsyncParallelHook());
|
|
292
|
+
this.hooks.set('strapi::content-types.afterSync', createAsyncParallelHook());
|
|
293
|
+
|
|
294
|
+
this.hook('strapi::content-types.beforeSync').register(draftAndPublishSync.disable);
|
|
295
|
+
this.hook('strapi::content-types.afterSync').register(draftAndPublishSync.enable);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async load() {
|
|
299
|
+
await Promise.all([
|
|
300
|
+
this.loadApp(),
|
|
301
|
+
this.loadPlugins(),
|
|
302
|
+
this.loadAdmin(),
|
|
303
|
+
this.loadAPIs(),
|
|
304
|
+
this.loadComponents(),
|
|
305
|
+
this.loadMiddlewares(),
|
|
306
|
+
this.loadPolicies(),
|
|
307
|
+
]);
|
|
308
|
+
|
|
309
|
+
await bootstrap({ strapi: this });
|
|
310
|
+
|
|
311
|
+
// init webhook runner
|
|
312
|
+
this.webhookRunner = createWebhookRunner({
|
|
313
|
+
eventHub: this.eventHub,
|
|
314
|
+
logger: this.log,
|
|
315
|
+
configuration: this.config.get('server.webhooks', {}),
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
this.registerInternalHooks();
|
|
319
|
+
|
|
320
|
+
await this.runLifecyclesFunctions(LIFECYCLES.REGISTER);
|
|
321
|
+
|
|
322
|
+
const contentTypes = [
|
|
323
|
+
coreStoreModel,
|
|
324
|
+
webhookModel,
|
|
325
|
+
...Object.values(strapi.contentTypes),
|
|
326
|
+
...Object.values(strapi.components),
|
|
327
|
+
];
|
|
328
|
+
|
|
329
|
+
this.db = await Database.init({
|
|
330
|
+
...this.config.get('database'),
|
|
331
|
+
models: Database.transformContentTypes(contentTypes),
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
this.store = createCoreStore({ db: this.db });
|
|
335
|
+
this.webhookStore = createWebhookStore({ db: this.db });
|
|
336
|
+
|
|
337
|
+
this.entityValidator = entityValidator;
|
|
338
|
+
this.entityService = createEntityService({
|
|
339
|
+
strapi: this,
|
|
340
|
+
db: this.db,
|
|
341
|
+
eventHub: this.eventHub,
|
|
342
|
+
entityValidator: this.entityValidator,
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
const cronTasks = this.config.get('server.cron.tasks', {});
|
|
346
|
+
this.cron.add(cronTasks);
|
|
347
|
+
|
|
348
|
+
this.telemetry = createTelemetry(this);
|
|
349
|
+
|
|
350
|
+
let oldContentTypes;
|
|
351
|
+
if (await this.db.connection.schema.hasTable(coreStoreModel.collectionName)) {
|
|
352
|
+
oldContentTypes = await this.store.get({
|
|
353
|
+
type: 'strapi',
|
|
354
|
+
name: 'content_types',
|
|
355
|
+
key: 'schema',
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
await this.hook('strapi::content-types.beforeSync').call({
|
|
360
|
+
oldContentTypes,
|
|
361
|
+
contentTypes: strapi.contentTypes,
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
await this.db.schema.sync();
|
|
365
|
+
|
|
366
|
+
await this.hook('strapi::content-types.afterSync').call({
|
|
367
|
+
oldContentTypes,
|
|
368
|
+
contentTypes: strapi.contentTypes,
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
await this.store.set({
|
|
372
|
+
type: 'strapi',
|
|
373
|
+
name: 'content_types',
|
|
374
|
+
key: 'schema',
|
|
375
|
+
value: strapi.contentTypes,
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
await this.startWebhooks();
|
|
379
|
+
|
|
380
|
+
// Initialize middlewares.
|
|
381
|
+
await initializeMiddlewares(this);
|
|
382
|
+
|
|
383
|
+
await this.runLifecyclesFunctions(LIFECYCLES.BOOTSTRAP);
|
|
384
|
+
|
|
385
|
+
this.cron.start();
|
|
386
|
+
|
|
387
|
+
this.isLoaded = true;
|
|
388
|
+
|
|
389
|
+
return this;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
async startWebhooks() {
|
|
393
|
+
const webhooks = await this.webhookStore.findWebhooks();
|
|
394
|
+
webhooks.forEach(webhook => this.webhookRunner.add(webhook));
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
reload() {
|
|
398
|
+
const state = {
|
|
399
|
+
shouldReload: 0,
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
const reload = function() {
|
|
403
|
+
if (state.shouldReload > 0) {
|
|
404
|
+
// Reset the reloading state
|
|
405
|
+
state.shouldReload -= 1;
|
|
406
|
+
reload.isReloading = false;
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (this.config.get('autoReload')) {
|
|
411
|
+
this.server.destroy();
|
|
412
|
+
process.send('reload');
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
Object.defineProperty(reload, 'isWatching', {
|
|
417
|
+
configurable: true,
|
|
418
|
+
enumerable: true,
|
|
419
|
+
set(value) {
|
|
420
|
+
// Special state when the reloader is disabled temporarly (see GraphQL plugin example).
|
|
421
|
+
if (state.isWatching === false && value === true) {
|
|
422
|
+
state.shouldReload += 1;
|
|
423
|
+
}
|
|
424
|
+
state.isWatching = value;
|
|
425
|
+
},
|
|
426
|
+
get() {
|
|
427
|
+
return state.isWatching;
|
|
428
|
+
},
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
reload.isReloading = false;
|
|
432
|
+
reload.isWatching = true;
|
|
433
|
+
|
|
434
|
+
return reload;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async runLifecyclesFunctions(lifecycleName) {
|
|
438
|
+
// plugins
|
|
439
|
+
await this.container.get('modules')[lifecycleName]();
|
|
440
|
+
|
|
441
|
+
// user
|
|
442
|
+
const lifecycleFunction = this.app[lifecycleName];
|
|
443
|
+
if (lifecycleFunction) {
|
|
444
|
+
await lifecycleFunction({ strapi: this });
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// admin
|
|
448
|
+
await this.admin[lifecycleName]({ strapi: this });
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
getModel(uid) {
|
|
452
|
+
return this.contentTypes[uid] || this.components[uid];
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Binds queries with a specific model
|
|
457
|
+
* @param {string} uid
|
|
458
|
+
*/
|
|
459
|
+
query(uid) {
|
|
460
|
+
return this.db.query(uid);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
module.exports = options => {
|
|
465
|
+
const strapi = new Strapi(options);
|
|
466
|
+
global.strapi = strapi;
|
|
467
|
+
return strapi;
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
module.exports.Strapi = Strapi;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const inquirer = require('inquirer');
|
|
5
|
+
const strapi = require('../index');
|
|
6
|
+
|
|
7
|
+
const promptQuestions = [
|
|
8
|
+
{ type: 'input', name: 'email', message: 'User email?' },
|
|
9
|
+
{ type: 'password', name: 'password', message: 'New password?' },
|
|
10
|
+
{
|
|
11
|
+
type: 'confirm',
|
|
12
|
+
name: 'confirm',
|
|
13
|
+
message: "Do you really want to reset this user's password?",
|
|
14
|
+
},
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Reset user's password
|
|
19
|
+
* @param {Object} cmdOptions - command options
|
|
20
|
+
* @param {string} cmdOptions.email - user's email
|
|
21
|
+
* @param {string} cmdOptions.password - user's new password
|
|
22
|
+
*/
|
|
23
|
+
module.exports = async function(cmdOptions = {}) {
|
|
24
|
+
const { email, password } = cmdOptions;
|
|
25
|
+
|
|
26
|
+
if (_.isEmpty(email) && _.isEmpty(password) && process.stdin.isTTY) {
|
|
27
|
+
const inquiry = await inquirer.prompt(promptQuestions);
|
|
28
|
+
|
|
29
|
+
if (!inquiry.confirm) {
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return changePassword(inquiry);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (_.isEmpty(email) || _.isEmpty(password)) {
|
|
37
|
+
console.error('Missing required options `email` or `password`');
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return changePassword({ email, password });
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
async function changePassword({ email, password }) {
|
|
45
|
+
const app = await strapi().load();
|
|
46
|
+
|
|
47
|
+
await app.admin.services.user.resetPasswordByEmail(email, password);
|
|
48
|
+
|
|
49
|
+
console.log(`Successfully reset user's password`);
|
|
50
|
+
process.exit(0);
|
|
51
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { green } = require('chalk');
|
|
3
|
+
|
|
4
|
+
const strapiAdmin = require('@strapi/admin');
|
|
5
|
+
const { getConfigUrls } = require('@strapi/utils');
|
|
6
|
+
|
|
7
|
+
const ee = require('../utils/ee');
|
|
8
|
+
const addSlash = require('../utils/addSlash');
|
|
9
|
+
const strapi = require('../index');
|
|
10
|
+
const getEnabledPlugins = require('../core/loaders/plugins/get-enabled-plugins');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* `$ strapi build`
|
|
14
|
+
*/
|
|
15
|
+
module.exports = async ({ clean, optimization }) => {
|
|
16
|
+
const dir = process.cwd();
|
|
17
|
+
|
|
18
|
+
const strapiInstance = strapi({
|
|
19
|
+
dir,
|
|
20
|
+
autoReload: true,
|
|
21
|
+
serveAdminPanel: false,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const plugins = await getEnabledPlugins(strapiInstance);
|
|
25
|
+
|
|
26
|
+
const env = strapiInstance.config.get('environment');
|
|
27
|
+
const { serverUrl, adminPath } = getConfigUrls(strapiInstance.config.get('server'), true);
|
|
28
|
+
|
|
29
|
+
console.log(`Building your admin UI with ${green(env)} configuration ...`);
|
|
30
|
+
|
|
31
|
+
if (clean) {
|
|
32
|
+
await strapiAdmin.clean({ dir });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
ee({ dir });
|
|
36
|
+
|
|
37
|
+
return strapiAdmin
|
|
38
|
+
.build({
|
|
39
|
+
dir,
|
|
40
|
+
plugins,
|
|
41
|
+
// front end build env is always production for now
|
|
42
|
+
env: 'production',
|
|
43
|
+
optimize: optimization,
|
|
44
|
+
options: {
|
|
45
|
+
backend: serverUrl,
|
|
46
|
+
adminPath: addSlash(adminPath),
|
|
47
|
+
},
|
|
48
|
+
})
|
|
49
|
+
.then(() => {
|
|
50
|
+
process.exit();
|
|
51
|
+
})
|
|
52
|
+
.catch(err => {
|
|
53
|
+
console.error(err);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
});
|
|
56
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const strapi = require('../index');
|
|
5
|
+
|
|
6
|
+
const CHUNK_SIZE = 100;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Will dump configurations to a file or stdout
|
|
10
|
+
* @param {string} file filepath to use as output
|
|
11
|
+
*/
|
|
12
|
+
module.exports = async function({ file: filePath, pretty }) {
|
|
13
|
+
const output = filePath ? fs.createWriteStream(filePath) : process.stdout;
|
|
14
|
+
|
|
15
|
+
const app = await strapi().load();
|
|
16
|
+
|
|
17
|
+
const count = await app.query('strapi::core-store').count();
|
|
18
|
+
|
|
19
|
+
const exportData = [];
|
|
20
|
+
|
|
21
|
+
const pageCount = Math.ceil(count / CHUNK_SIZE);
|
|
22
|
+
|
|
23
|
+
for (let page = 0; page < pageCount; page++) {
|
|
24
|
+
const results = await app
|
|
25
|
+
.query('strapi::core-store')
|
|
26
|
+
.findMany({ limit: CHUNK_SIZE, offset: page * CHUNK_SIZE, orderBy: 'key' });
|
|
27
|
+
|
|
28
|
+
results
|
|
29
|
+
.filter(result => result.key.startsWith('plugin_'))
|
|
30
|
+
.forEach(result => {
|
|
31
|
+
exportData.push({
|
|
32
|
+
key: result.key,
|
|
33
|
+
value: result.value,
|
|
34
|
+
type: result.type,
|
|
35
|
+
environment: result.environment,
|
|
36
|
+
tag: result.tag,
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
output.write(JSON.stringify(exportData, null, pretty ? 2 : null));
|
|
42
|
+
output.write('\n');
|
|
43
|
+
output.end();
|
|
44
|
+
|
|
45
|
+
// log success only when writting to file
|
|
46
|
+
if (filePath) {
|
|
47
|
+
console.log(`Successfully exported ${exportData.length} configuration entries`);
|
|
48
|
+
}
|
|
49
|
+
process.exit(0);
|
|
50
|
+
};
|