@strapi/strapi 4.0.0-next.6 → 4.0.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.
Files changed (166) hide show
  1. package/README.md +12 -12
  2. package/bin/strapi.js +41 -60
  3. package/lib/Strapi.js +234 -114
  4. package/lib/commands/build.js +16 -6
  5. package/lib/commands/console.js +1 -1
  6. package/lib/commands/content-types/list.js +22 -0
  7. package/lib/commands/develop.js +17 -18
  8. package/lib/commands/generate-template.js +4 -5
  9. package/lib/commands/hooks/list.js +22 -0
  10. package/lib/commands/middlewares/list.js +22 -0
  11. package/lib/commands/new.js +3 -1
  12. package/lib/commands/policies/list.js +22 -0
  13. package/lib/commands/routes/list.js +28 -0
  14. package/lib/commands/services/list.js +22 -0
  15. package/lib/commands/watchAdmin.js +18 -8
  16. package/lib/container.js +6 -6
  17. package/lib/core/app-configuration/config-loader.js +1 -37
  18. package/lib/core/app-configuration/index.js +6 -46
  19. package/lib/core/app-configuration/load-config-file.js +43 -0
  20. package/lib/core/bootstrap.js +5 -117
  21. package/lib/core/domain/component/index.js +24 -0
  22. package/lib/core/domain/component/validator.js +29 -0
  23. package/lib/core/domain/content-type/index.js +140 -0
  24. package/lib/core/domain/content-type/validator.js +64 -0
  25. package/lib/core/domain/module/index.js +108 -0
  26. package/lib/core/domain/module/validation.js +33 -0
  27. package/lib/core/loaders/admin.js +16 -0
  28. package/lib/core/loaders/apis.js +159 -0
  29. package/lib/core/{load-components.js → loaders/components.js} +5 -7
  30. package/lib/core/loaders/index.js +11 -0
  31. package/lib/core/loaders/middlewares.js +36 -0
  32. package/lib/core/loaders/plugins/get-enabled-plugins.js +116 -0
  33. package/lib/core/loaders/plugins/index.js +123 -0
  34. package/lib/core/loaders/policies.js +28 -0
  35. package/lib/core/loaders/src-index.js +39 -0
  36. package/lib/core/registries/apis.js +29 -0
  37. package/lib/core/{app-configuration/config-provider.js → registries/config.js} +4 -11
  38. package/lib/core/registries/content-types.js +97 -0
  39. package/lib/core/registries/controllers.d.ts +7 -0
  40. package/lib/core/registries/controllers.js +114 -0
  41. package/lib/core/registries/hooks.d.ts +20 -0
  42. package/lib/core/registries/hooks.js +87 -0
  43. package/lib/core/registries/middlewares.d.ts +5 -0
  44. package/lib/core/registries/middlewares.js +89 -0
  45. package/lib/core/registries/modules.js +44 -0
  46. package/lib/core/registries/plugins.js +28 -0
  47. package/lib/core/registries/policies.d.ts +9 -0
  48. package/lib/core/registries/policies.js +89 -0
  49. package/lib/core/registries/services.d.ts +7 -0
  50. package/lib/core/registries/services.js +114 -0
  51. package/lib/core/utils.js +35 -0
  52. package/lib/core-api/controller/collection-type.js +45 -26
  53. package/lib/core-api/controller/index.d.ts +25 -0
  54. package/lib/core-api/controller/index.js +33 -11
  55. package/lib/core-api/controller/single-type.js +29 -15
  56. package/lib/core-api/controller/transform.js +62 -6
  57. package/lib/core-api/routes/index.js +71 -0
  58. package/lib/core-api/service/collection-type.js +43 -21
  59. package/lib/core-api/service/index.d.ts +21 -0
  60. package/lib/core-api/service/index.js +8 -67
  61. package/lib/core-api/service/pagination.js +130 -0
  62. package/lib/core-api/service/single-type.js +17 -19
  63. package/lib/factories.d.ts +48 -0
  64. package/lib/factories.js +84 -0
  65. package/lib/index.d.ts +10 -31
  66. package/lib/index.js +5 -1
  67. package/lib/middlewares/body.js +33 -0
  68. package/lib/middlewares/compression.js +8 -0
  69. package/lib/middlewares/cors.js +58 -0
  70. package/lib/middlewares/errors.js +40 -0
  71. package/lib/middlewares/favicon.js +19 -0
  72. package/lib/middlewares/index.d.ts +5 -0
  73. package/lib/middlewares/index.js +30 -117
  74. package/lib/middlewares/ip.js +8 -0
  75. package/lib/middlewares/logger.js +27 -0
  76. package/lib/middlewares/powered-by.js +20 -0
  77. package/lib/middlewares/public/index.js +98 -73
  78. package/lib/middlewares/query.js +46 -0
  79. package/lib/middlewares/response-time.js +15 -0
  80. package/lib/middlewares/responses.js +19 -0
  81. package/lib/middlewares/security.js +51 -0
  82. package/lib/middlewares/session/index.js +6 -6
  83. package/lib/migrations/draft-publish.js +57 -0
  84. package/lib/services/auth/index.js +87 -0
  85. package/lib/services/core-store.js +64 -51
  86. package/lib/services/cron.js +54 -0
  87. package/lib/services/entity-service/attributes/index.js +31 -0
  88. package/lib/services/entity-service/attributes/transforms.js +20 -0
  89. package/lib/services/entity-service/components.js +39 -15
  90. package/lib/services/entity-service/index.d.ts +91 -0
  91. package/lib/services/entity-service/index.js +120 -59
  92. package/lib/services/entity-service/params.js +52 -94
  93. package/lib/services/entity-validator/index.js +76 -43
  94. package/lib/services/entity-validator/validators.js +129 -43
  95. package/lib/services/errors.js +77 -0
  96. package/lib/{core → services}/fs.js +10 -2
  97. package/lib/services/metrics/index.js +41 -38
  98. package/lib/services/metrics/sender.js +2 -2
  99. package/lib/services/server/admin-api.js +14 -0
  100. package/lib/services/server/api.js +36 -0
  101. package/lib/services/server/compose-endpoint.js +141 -0
  102. package/lib/services/server/content-api.js +16 -0
  103. package/lib/{server.js → services/server/http-server.js} +0 -0
  104. package/lib/services/server/index.js +127 -0
  105. package/lib/services/server/koa.js +64 -0
  106. package/lib/services/server/middleware.js +122 -0
  107. package/lib/services/server/policy.js +32 -0
  108. package/lib/services/server/register-middlewares.js +110 -0
  109. package/lib/services/server/register-routes.js +106 -0
  110. package/lib/services/server/routing.js +120 -0
  111. package/lib/services/utils/upload-files.js +1 -1
  112. package/lib/services/webhook-runner.js +1 -1
  113. package/lib/utils/ee.js +3 -3
  114. package/lib/utils/get-dirs.js +17 -0
  115. package/lib/utils/index.js +2 -0
  116. package/lib/utils/is-initialized.js +1 -1
  117. package/lib/utils/run-checks.js +0 -15
  118. package/lib/utils/signals.js +24 -0
  119. package/lib/utils/startup-logger.js +2 -2
  120. package/lib/utils/update-notifier/index.js +3 -2
  121. package/package.json +93 -96
  122. package/lib/commands/generate.js +0 -76
  123. package/lib/core/index.js +0 -17
  124. package/lib/core/load-apis.js +0 -20
  125. package/lib/core/load-extensions.js +0 -71
  126. package/lib/core/load-functions.js +0 -21
  127. package/lib/core/load-middlewares.js +0 -130
  128. package/lib/core/load-modules.js +0 -55
  129. package/lib/core/load-plugins.js +0 -68
  130. package/lib/core/load-policies.js +0 -36
  131. package/lib/core/walk.js +0 -27
  132. package/lib/core-api/index.js +0 -39
  133. package/lib/load/check-reserved-filename.js +0 -10
  134. package/lib/load/load-config-files.js +0 -22
  135. package/lib/load/require-file-parse.js +0 -15
  136. package/lib/middlewares/boom/defaults.json +0 -5
  137. package/lib/middlewares/boom/index.js +0 -147
  138. package/lib/middlewares/cors/index.js +0 -66
  139. package/lib/middlewares/cron/defaults.json +0 -5
  140. package/lib/middlewares/cron/index.js +0 -43
  141. package/lib/middlewares/favicon/defaults.json +0 -7
  142. package/lib/middlewares/favicon/index.js +0 -32
  143. package/lib/middlewares/gzip/defaults.json +0 -6
  144. package/lib/middlewares/gzip/index.js +0 -19
  145. package/lib/middlewares/helmet/defaults.json +0 -18
  146. package/lib/middlewares/helmet/index.js +0 -9
  147. package/lib/middlewares/ip/defaults.json +0 -7
  148. package/lib/middlewares/ip/index.js +0 -25
  149. package/lib/middlewares/language/defaults.json +0 -9
  150. package/lib/middlewares/language/index.js +0 -40
  151. package/lib/middlewares/logger/defaults.json +0 -5
  152. package/lib/middlewares/logger/index.js +0 -37
  153. package/lib/middlewares/parser/defaults.json +0 -11
  154. package/lib/middlewares/parser/index.js +0 -71
  155. package/lib/middlewares/poweredBy/defaults.json +0 -5
  156. package/lib/middlewares/poweredBy/index.js +0 -16
  157. package/lib/middlewares/public/defaults.json +0 -8
  158. package/lib/middlewares/responseTime/defaults.json +0 -5
  159. package/lib/middlewares/responseTime/index.js +0 -25
  160. package/lib/middlewares/responses/defaults.json +0 -5
  161. package/lib/middlewares/responses/index.js +0 -18
  162. package/lib/middlewares/router/defaults.json +0 -7
  163. package/lib/middlewares/router/index.js +0 -64
  164. package/lib/middlewares/router/utils/composeEndpoint.js +0 -25
  165. package/lib/middlewares/router/utils/routerChecker.js +0 -92
  166. package/lib/utils/get-prefixed-dependencies.js +0 -7
package/lib/Strapi.js CHANGED
@@ -1,68 +1,158 @@
1
1
  'use strict';
2
2
 
3
- const Koa = require('koa');
4
- const Router = require('koa-router');
5
3
  const _ = require('lodash');
4
+ const { isFunction } = require('lodash/fp');
6
5
  const { createLogger } = require('@strapi/logger');
7
6
  const { Database } = require('@strapi/database');
7
+ const { createAsyncParallelHook } = require('@strapi/utils').hooks;
8
8
 
9
9
  const loadConfiguration = require('./core/app-configuration');
10
- const { createHTTPServer } = require('./server');
10
+
11
11
  const { createContainer } = require('./container');
12
- const loadModules = require('./core/load-modules');
13
12
  const utils = require('./utils');
14
- const bootstrap = require('./core/bootstrap');
15
- const initializeMiddlewares = require('./middlewares');
16
- const createStrapiFs = require('./core/fs');
13
+ const createStrapiFs = require('./services/fs');
17
14
  const createEventHub = require('./services/event-hub');
15
+ const { createServer } = require('./services/server');
18
16
  const createWebhookRunner = require('./services/webhook-runner');
19
17
  const { webhookModel, createWebhookStore } = require('./services/webhook-store');
20
18
  const { createCoreStore, coreStoreModel } = require('./services/core-store');
21
19
  const createEntityService = require('./services/entity-service');
20
+ const createCronService = require('./services/cron');
22
21
  const entityValidator = require('./services/entity-validator');
23
22
  const createTelemetry = require('./services/metrics');
23
+ const createAuth = require('./services/auth');
24
24
  const createUpdateNotifier = require('./utils/update-notifier');
25
25
  const createStartupLogger = require('./utils/startup-logger');
26
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
+ const { destroyOnSignal } = require('./utils/signals');
40
+
41
+ // TODO: move somewhere else
42
+ const draftAndPublishSync = require('./migrations/draft-publish');
27
43
 
28
44
  const LIFECYCLES = {
29
45
  REGISTER: 'register',
30
46
  BOOTSTRAP: 'bootstrap',
47
+ DESTROY: 'destroy',
31
48
  };
32
49
 
33
50
  class Strapi {
34
51
  constructor(opts = {}) {
52
+ destroyOnSignal(this);
53
+ this.dirs = utils.getDirs(opts.dir || process.cwd());
54
+ const appConfig = loadConfiguration(this.dirs.root, opts);
35
55
  this.container = createContainer(this);
36
-
37
- this.dir = opts.dir || process.cwd();
38
- this.config = loadConfiguration(this.dir, opts);
39
-
40
- this.reload = this.reload();
41
-
42
- // Expose `koa`.
43
- this.app = new Koa();
44
- this.router = new Router();
45
-
46
- this.server = createHTTPServer(this, this.app);
47
-
48
- this.app.proxy = this.config.get('server.proxy');
49
-
50
- // Logger.
51
- const loggerUserConfiguration = this.config.get('logger', {});
52
- this.log = createLogger(loggerUserConfiguration);
56
+ this.container.register('config', createConfigProvider(appConfig));
57
+ this.container.register('content-types', contentTypesRegistry(this));
58
+ this.container.register('services', servicesRegistry(this));
59
+ this.container.register('policies', policiesRegistry(this));
60
+ this.container.register('middlewares', middlewaresRegistry(this));
61
+ this.container.register('hooks', hooksRegistry(this));
62
+ this.container.register('controllers', controllersRegistry(this));
63
+ this.container.register('modules', modulesRegistry(this));
64
+ this.container.register('plugins', pluginsRegistry(this));
65
+ this.container.register('apis', apisRegistry(this));
66
+ this.container.register('auth', createAuth(this));
53
67
 
54
68
  this.isLoaded = false;
69
+ this.reload = this.reload();
70
+ this.server = createServer(this);
55
71
 
56
- // internal services.
57
72
  this.fs = createStrapiFs(this);
58
73
  this.eventHub = createEventHub();
59
74
  this.startupLogger = createStartupLogger(this);
75
+ this.log = createLogger(this.config.get('logger', {}));
76
+ this.cron = createCronService();
77
+ this.telemetry = createTelemetry(this);
60
78
 
61
79
  createUpdateNotifier(this).notify();
62
80
  }
63
81
 
82
+ get config() {
83
+ return this.container.get('config');
84
+ }
85
+
64
86
  get EE() {
65
- return ee({ dir: this.dir, logger: this.log });
87
+ return ee({ dir: this.dirs.root, logger: this.log });
88
+ }
89
+
90
+ get services() {
91
+ return this.container.get('services').getAll();
92
+ }
93
+
94
+ service(uid) {
95
+ return this.container.get('services').get(uid);
96
+ }
97
+
98
+ get controllers() {
99
+ return this.container.get('controllers').getAll();
100
+ }
101
+
102
+ controller(uid) {
103
+ return this.container.get('controllers').get(uid);
104
+ }
105
+
106
+ get contentTypes() {
107
+ return this.container.get('content-types').getAll();
108
+ }
109
+
110
+ contentType(name) {
111
+ return this.container.get('content-types').get(name);
112
+ }
113
+
114
+ get policies() {
115
+ return this.container.get('policies').getAll();
116
+ }
117
+
118
+ policy(name) {
119
+ return this.container.get('policies').get(name);
120
+ }
121
+
122
+ get middlewares() {
123
+ return this.container.get('middlewares').getAll();
124
+ }
125
+
126
+ middleware(name) {
127
+ return this.container.get('middlewares').get(name);
128
+ }
129
+
130
+ get plugins() {
131
+ return this.container.get('plugins').getAll();
132
+ }
133
+
134
+ plugin(name) {
135
+ return this.container.get('plugins').get(name);
136
+ }
137
+
138
+ get hooks() {
139
+ return this.container.get('hooks').getAll();
140
+ }
141
+
142
+ hook(name) {
143
+ return this.container.get('hooks').get(name);
144
+ }
145
+
146
+ // api(name) {
147
+ // return this.container.get('apis').get(name);
148
+ // }
149
+
150
+ get api() {
151
+ return this.container.get('apis').getAll();
152
+ }
153
+
154
+ get auth() {
155
+ return this.container.get('auth');
66
156
  }
67
157
 
68
158
  async start() {
@@ -71,31 +161,18 @@ class Strapi {
71
161
  await this.load();
72
162
  }
73
163
 
74
- this.app.use(this.router.routes()).use(this.router.allowedMethods());
75
-
76
- // Launch server.
77
164
  await this.listen();
78
165
 
79
166
  return this;
80
167
  } catch (error) {
81
- return this.stopWithError(error.message);
168
+ return this.stopWithError(error);
82
169
  }
83
170
  }
84
171
 
85
172
  async destroy() {
86
173
  await this.server.destroy();
87
174
 
88
- await Promise.all(
89
- Object.values(this.plugins).map(plugin => {
90
- if (_.has(plugin, 'destroy') && typeof plugin.destroy === 'function') {
91
- return plugin.destroy();
92
- }
93
- })
94
- );
95
-
96
- if (_.has(this, 'admin')) {
97
- await this.admin.destroy();
98
- }
175
+ await this.runLifecyclesFunctions(LIFECYCLES.DESTROY);
99
176
 
100
177
  this.eventHub.removeAllListeners();
101
178
 
@@ -104,6 +181,9 @@ class Strapi {
104
181
  }
105
182
 
106
183
  this.telemetry.destroy();
184
+ this.cron.destroy();
185
+
186
+ process.removeAllListeners();
107
187
 
108
188
  delete global.strapi;
109
189
  }
@@ -123,10 +203,10 @@ class Strapi {
123
203
 
124
204
  async openAdmin({ isInitialized }) {
125
205
  const shouldOpenAdmin =
126
- this.config.environment === 'development' &&
127
- this.config.get('server.admin.autoOpen', true) !== false;
206
+ this.config.get('environment') === 'development' &&
207
+ this.config.get('admin.autoOpen', true) !== false;
128
208
 
129
- if (shouldOpenAdmin || !isInitialized) {
209
+ if (shouldOpenAdmin && !isInitialized) {
130
210
  await utils.openBrowser(this.config);
131
211
  }
132
212
  }
@@ -181,9 +261,9 @@ class Strapi {
181
261
  }
182
262
 
183
263
  stop(exitCode = 1) {
184
- this.server.destroy();
264
+ this.destroy();
185
265
 
186
- if (this.config.autoReload) {
266
+ if (this.config.get('autoReload')) {
187
267
  process.send('stop');
188
268
  }
189
269
 
@@ -191,35 +271,54 @@ class Strapi {
191
271
  process.exit(exitCode);
192
272
  }
193
273
 
194
- loadAdmin() {
195
- this.admin = require('@strapi/admin/strapi-server');
274
+ async loadAdmin() {
275
+ await loaders.loadAdmin(this);
276
+ }
196
277
 
197
- // TODO: rename into just admin and ./config/admin.js
198
- const userAdminConfig = strapi.config.get('server.admin');
199
- this.config.set('server.admin', _.merge(this.admin.config, userAdminConfig));
278
+ async loadPlugins() {
279
+ await loaders.loadPlugins(this);
200
280
  }
201
281
 
202
- async load() {
203
- this.app.use(async (ctx, next) => {
204
- if (ctx.request.url === '/_health' && ['HEAD', 'GET'].includes(ctx.request.method)) {
205
- ctx.set('strapi', 'You are so French!');
206
- ctx.status = 204;
207
- } else {
208
- await next();
209
- }
210
- });
282
+ async loadPolicies() {
283
+ await loaders.loadPolicies(this);
284
+ }
285
+
286
+ async loadAPIs() {
287
+ await loaders.loadAPIs(this);
288
+ }
289
+
290
+ async loadComponents() {
291
+ this.components = await loaders.loadComponents(this);
292
+ }
211
293
 
212
- const modules = await loadModules(this);
294
+ async loadMiddlewares() {
295
+ await loaders.loadMiddlewares(this);
296
+ }
297
+
298
+ async loadApp() {
299
+ this.app = await loaders.loadSrcIndex(this);
300
+ }
213
301
 
214
- this.loadAdmin();
302
+ registerInternalHooks() {
303
+ this.container.get('hooks').set('strapi::content-types.beforeSync', createAsyncParallelHook());
304
+ this.container.get('hooks').set('strapi::content-types.afterSync', createAsyncParallelHook());
215
305
 
216
- this.api = modules.api;
217
- this.components = modules.components;
218
- this.plugins = modules.plugins;
219
- this.middleware = modules.middlewares;
220
- this.hook = modules.hook;
306
+ this.hook('strapi::content-types.beforeSync').register(draftAndPublishSync.disable);
307
+ this.hook('strapi::content-types.afterSync').register(draftAndPublishSync.enable);
308
+ }
221
309
 
222
- await bootstrap(this);
310
+ async register() {
311
+ await Promise.all([
312
+ this.loadApp(),
313
+ this.loadPlugins(),
314
+ this.loadAdmin(),
315
+ this.loadAPIs(),
316
+ this.loadComponents(),
317
+ this.loadMiddlewares(),
318
+ this.loadPolicies(),
319
+ ]);
320
+
321
+ await bootstrap({ strapi: this });
223
322
 
224
323
  // init webhook runner
225
324
  this.webhookRunner = createWebhookRunner({
@@ -228,8 +327,16 @@ class Strapi {
228
327
  configuration: this.config.get('server.webhooks', {}),
229
328
  });
230
329
 
330
+ this.registerInternalHooks();
331
+
332
+ this.telemetry.register();
333
+
231
334
  await this.runLifecyclesFunctions(LIFECYCLES.REGISTER);
232
335
 
336
+ return this;
337
+ }
338
+
339
+ async bootstrap() {
233
340
  const contentTypes = [
234
341
  coreStoreModel,
235
342
  webhookModel,
@@ -242,19 +349,10 @@ class Strapi {
242
349
  models: Database.transformContentTypes(contentTypes),
243
350
  });
244
351
 
245
- await this.db.schema.sync();
246
-
247
- this.store = createCoreStore({
248
- environment: this.config.environment,
249
- db: this.db,
250
- });
251
-
352
+ this.store = createCoreStore({ db: this.db });
252
353
  this.webhookStore = createWebhookStore({ db: this.db });
253
354
 
254
- await this.startWebhooks();
255
-
256
355
  this.entityValidator = entityValidator;
257
-
258
356
  this.entityService = createEntityService({
259
357
  strapi: this,
260
358
  db: this.db,
@@ -262,14 +360,57 @@ class Strapi {
262
360
  entityValidator: this.entityValidator,
263
361
  });
264
362
 
265
- this.telemetry = createTelemetry(this);
363
+ const cronTasks = this.config.get('server.cron.tasks', {});
364
+ this.cron.add(cronTasks);
365
+
366
+ this.telemetry.bootstrap();
266
367
 
267
- // Initialize middlewares.
268
- await initializeMiddlewares.call(this);
368
+ let oldContentTypes;
369
+ if (await this.db.getSchemaConnection().hasTable(coreStoreModel.collectionName)) {
370
+ oldContentTypes = await this.store.get({
371
+ type: 'strapi',
372
+ name: 'content_types',
373
+ key: 'schema',
374
+ });
375
+ }
376
+
377
+ await this.hook('strapi::content-types.beforeSync').call({
378
+ oldContentTypes,
379
+ contentTypes: strapi.contentTypes,
380
+ });
381
+
382
+ await this.db.schema.sync();
383
+
384
+ await this.hook('strapi::content-types.afterSync').call({
385
+ oldContentTypes,
386
+ contentTypes: strapi.contentTypes,
387
+ });
388
+
389
+ await this.store.set({
390
+ type: 'strapi',
391
+ name: 'content_types',
392
+ key: 'schema',
393
+ value: strapi.contentTypes,
394
+ });
395
+
396
+ await this.startWebhooks();
397
+
398
+ await this.server.initMiddlewares();
399
+ await this.server.initRouting();
269
400
 
270
401
  await this.runLifecyclesFunctions(LIFECYCLES.BOOTSTRAP);
271
402
 
403
+ this.cron.start();
404
+
405
+ return this;
406
+ }
407
+
408
+ async load() {
409
+ await this.register();
410
+ await this.bootstrap();
411
+
272
412
  this.isLoaded = true;
413
+
273
414
  return this;
274
415
  }
275
416
 
@@ -291,8 +432,7 @@ class Strapi {
291
432
  return;
292
433
  }
293
434
 
294
- if (this.config.autoReload) {
295
- this.server.destroy();
435
+ if (this.config.get('autoReload')) {
296
436
  process.send('reload');
297
437
  }
298
438
  };
@@ -300,14 +440,14 @@ class Strapi {
300
440
  Object.defineProperty(reload, 'isWatching', {
301
441
  configurable: true,
302
442
  enumerable: true,
303
- set: value => {
443
+ set(value) {
304
444
  // Special state when the reloader is disabled temporarly (see GraphQL plugin example).
305
445
  if (state.isWatching === false && value === true) {
306
446
  state.shouldReload += 1;
307
447
  }
308
448
  state.isWatching = value;
309
449
  },
310
- get: () => {
450
+ get() {
311
451
  return state.isWatching;
312
452
  },
313
453
  });
@@ -319,39 +459,20 @@ class Strapi {
319
459
  }
320
460
 
321
461
  async runLifecyclesFunctions(lifecycleName) {
322
- const execLifecycle = async fn => {
323
- if (!fn) {
324
- return;
325
- }
326
-
327
- return fn();
328
- };
329
-
330
- const configPath = `functions.${lifecycleName}`;
331
-
332
462
  // plugins
333
- await Promise.all(
334
- Object.keys(this.plugins).map(plugin => {
335
- const pluginFunc = _.get(this.plugins[plugin], `config.${configPath}`);
336
-
337
- return execLifecycle(pluginFunc).catch(err => {
338
- strapi.log.error(`${lifecycleName} function in plugin "${plugin}" failed`);
339
- console.error(err);
340
- strapi.stop();
341
- });
342
- })
343
- );
463
+ await this.container.get('modules')[lifecycleName]();
344
464
 
345
465
  // user
346
- await execLifecycle(_.get(this.config, configPath));
466
+ const userLifecycleFunction = this.app && this.app[lifecycleName];
467
+ if (isFunction(userLifecycleFunction)) {
468
+ await userLifecycleFunction({ strapi: this });
469
+ }
347
470
 
348
471
  // admin
349
- const adminFunc = _.get(this.admin.config, configPath);
350
- return execLifecycle(adminFunc).catch(err => {
351
- strapi.log.error(`${lifecycleName} function in admin failed`);
352
- console.error(err);
353
- strapi.stop();
354
- });
472
+ const adminLifecycleFunction = this.admin && this.admin[lifecycleName];
473
+ if (isFunction(adminLifecycleFunction)) {
474
+ await adminLifecycleFunction({ strapi: this });
475
+ }
355
476
  }
356
477
 
357
478
  getModel(uid) {
@@ -361,7 +482,6 @@ class Strapi {
361
482
  /**
362
483
  * Binds queries with a specific model
363
484
  * @param {string} uid
364
- * @returns {}
365
485
  */
366
486
  query(uid) {
367
487
  return this.db.query(uid);
@@ -1,23 +1,32 @@
1
1
  'use strict';
2
2
  const { green } = require('chalk');
3
3
 
4
- // eslint-disable-next-line node/no-extraneous-require
5
4
  const strapiAdmin = require('@strapi/admin');
6
5
  const { getConfigUrls } = require('@strapi/utils');
7
- const loadConfiguration = require('../core/app-configuration');
8
- const ee = require('../utils/ee');
9
6
 
7
+ const ee = require('../utils/ee');
10
8
  const addSlash = require('../utils/addSlash');
9
+ const strapi = require('../index');
10
+ const getEnabledPlugins = require('../core/loaders/plugins/get-enabled-plugins');
11
+
11
12
  /**
12
13
  * `$ strapi build`
13
14
  */
14
15
  module.exports = async ({ clean, optimization }) => {
15
16
  const dir = process.cwd();
16
- const config = loadConfiguration(dir);
17
17
 
18
- const { serverUrl, adminPath } = getConfigUrls(config.get('server'), true);
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, true);
19
28
 
20
- console.log(`Building your admin UI with ${green(config.environment)} configuration ...`);
29
+ console.log(`Building your admin UI with ${green(env)} configuration ...`);
21
30
 
22
31
  if (clean) {
23
32
  await strapiAdmin.clean({ dir });
@@ -28,6 +37,7 @@ module.exports = async ({ clean, optimization }) => {
28
37
  return strapiAdmin
29
38
  .build({
30
39
  dir,
40
+ plugins,
31
41
  // front end build env is always production for now
32
42
  env: 'production',
33
43
  optimize: optimization,
@@ -10,7 +10,7 @@ module.exports = () => {
10
10
  // Now load up the Strapi framework for real.
11
11
  const app = strapi();
12
12
 
13
- app.start(() => {
13
+ app.start().then(() => {
14
14
  const repl = REPL.start(app.config.info.name + ' > ' || 'strapi > '); // eslint-disable-line prefer-template
15
15
 
16
16
  repl.on('exit', function(err) {
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ const CLITable = require('cli-table3');
4
+ const chalk = require('chalk');
5
+
6
+ const strapi = require('../../index');
7
+
8
+ module.exports = async function() {
9
+ const app = await strapi().register();
10
+
11
+ const list = app.container.get('content-types').keys();
12
+
13
+ const infoTable = new CLITable({
14
+ head: [chalk.blue('Name')],
15
+ });
16
+
17
+ list.forEach(name => infoTable.push([name]));
18
+
19
+ console.log(infoTable.toString());
20
+
21
+ await app.destroy();
22
+ };
@@ -5,6 +5,7 @@ const cluster = require('cluster');
5
5
  const fs = require('fs-extra');
6
6
  const chokidar = require('chokidar');
7
7
  const execa = require('execa');
8
+ const { getOr } = require('lodash/fp');
8
9
 
9
10
  const { createLogger } = require('@strapi/logger');
10
11
  const loadConfiguration = require('../core/app-configuration');
@@ -17,17 +18,18 @@ const strapi = require('../index');
17
18
  module.exports = async function({ build, watchAdmin, polling, browser }) {
18
19
  const dir = process.cwd();
19
20
  const config = loadConfiguration(dir);
20
- const logger = createLogger(config.get('logger', {}));
21
+ const logger = createLogger(config.logger, {});
21
22
 
22
- const adminWatchIgnoreFiles = config.get('server.admin.watchIgnoreFiles', []);
23
- const serveAdminPanel = config.get('server.admin.serveAdminPanel', true);
23
+ const adminWatchIgnoreFiles = getOr([], 'admin.watchIgnoreFiles')(config);
24
+ const serveAdminPanel = getOr(true, 'admin.serveAdminPanel')(config);
24
25
 
25
26
  const buildExists = fs.existsSync(path.join(dir, 'build'));
26
27
  // Don't run the build process if the admin is in watch mode
27
28
  if (build && !watchAdmin && serveAdminPanel && !buildExists) {
28
29
  try {
29
- execa.shellSync('npm run -s build -- --no-optimization', {
30
+ execa.sync('npm run -s build -- --no-optimization', {
30
31
  stdio: 'inherit',
32
+ shell: true,
31
33
  });
32
34
  } catch (err) {
33
35
  process.exit(1);
@@ -50,14 +52,12 @@ module.exports = async function({ build, watchAdmin, polling, browser }) {
50
52
  switch (message) {
51
53
  case 'reload':
52
54
  logger.info('The server is restarting\n');
53
- worker.send('isKilled');
55
+ worker.send('kill');
54
56
  break;
55
- case 'kill':
56
- worker.kill();
57
+ case 'killed':
57
58
  cluster.fork();
58
59
  break;
59
60
  case 'stop':
60
- worker.kill();
61
61
  process.exit(1);
62
62
  default:
63
63
  return;
@@ -81,13 +81,12 @@ module.exports = async function({ build, watchAdmin, polling, browser }) {
81
81
  polling,
82
82
  });
83
83
 
84
- process.on('message', message => {
84
+ process.on('message', async message => {
85
85
  switch (message) {
86
- case 'isKilled':
87
- strapiInstance.server.destroy(() => {
88
- process.send('kill');
89
- });
90
- break;
86
+ case 'kill':
87
+ await strapiInstance.destroy();
88
+ process.send('killed');
89
+ process.exit();
91
90
  default:
92
91
  // Do nothing.
93
92
  }
@@ -122,10 +121,10 @@ function watchFileChanges({ dir, strapiInstance, watchIgnoreFiles, polling }) {
122
121
  ignored: [
123
122
  /(^|[/\\])\../, // dot files
124
123
  /tmp/,
125
- '**/admin',
126
- '**/admin/**',
127
- 'extensions/**/admin',
128
- 'extensions/**/admin/**',
124
+ 'admin',
125
+ 'admin/**',
126
+ 'src/extensions/**/admin',
127
+ 'src/extensions/**/admin/**',
129
128
  '**/documentation',
130
129
  '**/documentation/**',
131
130
  '**/node_modules',