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