@strapi/strapi 4.0.0-next.9 → 4.0.3

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 (142) hide show
  1. package/README.md +14 -14
  2. package/bin/strapi.js +37 -6
  3. package/lib/Strapi.js +140 -72
  4. package/lib/commands/build.js +21 -11
  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 +24 -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 -19
  18. package/lib/core/bootstrap.js +3 -34
  19. package/lib/core/domain/content-type/index.js +3 -7
  20. package/lib/core/domain/module/index.js +8 -6
  21. package/lib/core/domain/module/validation.js +1 -4
  22. package/lib/core/loaders/admin.js +2 -2
  23. package/lib/core/loaders/apis.js +7 -7
  24. package/lib/core/loaders/components.js +3 -5
  25. package/lib/core/loaders/index.js +1 -0
  26. package/lib/core/loaders/middlewares.js +23 -123
  27. package/lib/core/loaders/plugins/get-enabled-plugins.js +55 -19
  28. package/lib/core/loaders/plugins/get-user-plugins-config.js +37 -0
  29. package/lib/core/loaders/plugins/index.js +30 -16
  30. package/lib/core/loaders/policies.js +1 -1
  31. package/lib/core/loaders/src-index.js +39 -0
  32. package/lib/core/registries/apis.js +2 -16
  33. package/lib/core/registries/content-types.js +50 -6
  34. package/lib/core/registries/controllers.d.ts +7 -0
  35. package/lib/core/registries/controllers.js +74 -3
  36. package/lib/core/registries/hooks.d.ts +20 -0
  37. package/lib/core/registries/hooks.js +87 -0
  38. package/lib/core/registries/middlewares.d.ts +5 -0
  39. package/lib/core/registries/middlewares.js +61 -2
  40. package/lib/core/registries/modules.js +3 -3
  41. package/lib/core/registries/plugins.js +2 -2
  42. package/lib/core/registries/policies.d.ts +9 -0
  43. package/lib/core/registries/policies.js +57 -6
  44. package/lib/core/registries/services.d.ts +7 -0
  45. package/lib/core/registries/services.js +71 -15
  46. package/lib/core-api/controller/collection-type.js +38 -11
  47. package/lib/core-api/controller/index.d.ts +25 -0
  48. package/lib/core-api/controller/index.js +30 -11
  49. package/lib/core-api/controller/single-type.js +26 -7
  50. package/lib/core-api/controller/transform.js +28 -3
  51. package/lib/core-api/routes/index.js +71 -0
  52. package/lib/core-api/service/collection-type.js +22 -27
  53. package/lib/core-api/service/index.d.ts +21 -0
  54. package/lib/core-api/service/index.js +9 -19
  55. package/lib/core-api/service/pagination.js +16 -16
  56. package/lib/core-api/service/single-type.js +17 -20
  57. package/lib/factories.d.ts +48 -0
  58. package/lib/factories.js +84 -0
  59. package/lib/index.d.ts +10 -31
  60. package/lib/index.js +5 -1
  61. package/lib/middlewares/body.js +33 -0
  62. package/lib/middlewares/compression.js +8 -0
  63. package/lib/middlewares/cors.js +58 -0
  64. package/lib/middlewares/errors.js +40 -0
  65. package/lib/middlewares/favicon.js +19 -0
  66. package/lib/middlewares/index.d.ts +5 -0
  67. package/lib/middlewares/index.js +30 -116
  68. package/lib/middlewares/ip.js +8 -0
  69. package/lib/middlewares/logger.js +27 -0
  70. package/lib/middlewares/powered-by.js +20 -0
  71. package/lib/middlewares/public/index.js +72 -77
  72. package/lib/middlewares/query.js +46 -0
  73. package/lib/middlewares/response-time.js +15 -0
  74. package/lib/middlewares/responses.js +19 -0
  75. package/lib/middlewares/security.js +51 -0
  76. package/lib/middlewares/session/index.js +6 -6
  77. package/lib/migrations/draft-publish.js +57 -0
  78. package/lib/services/auth/index.js +87 -0
  79. package/lib/services/core-store.js +64 -49
  80. package/lib/services/cron.js +54 -0
  81. package/lib/services/entity-service/attributes/index.js +31 -0
  82. package/lib/services/entity-service/attributes/transforms.js +20 -0
  83. package/lib/services/entity-service/components.js +39 -15
  84. package/lib/services/entity-service/index.d.ts +91 -0
  85. package/lib/services/entity-service/index.js +118 -60
  86. package/lib/services/entity-service/params.js +48 -81
  87. package/lib/services/entity-validator/index.js +76 -43
  88. package/lib/services/entity-validator/validators.js +131 -43
  89. package/lib/services/errors.js +77 -0
  90. package/lib/services/fs.js +1 -1
  91. package/lib/services/metrics/index.js +38 -36
  92. package/lib/services/server/admin-api.js +14 -0
  93. package/lib/services/server/api.js +36 -0
  94. package/lib/services/server/compose-endpoint.js +141 -0
  95. package/lib/services/server/content-api.js +16 -0
  96. package/lib/{server.js → services/server/http-server.js} +0 -0
  97. package/lib/services/server/index.js +127 -0
  98. package/lib/services/server/koa.js +64 -0
  99. package/lib/services/server/middleware.js +122 -0
  100. package/lib/services/server/policy.js +32 -0
  101. package/lib/services/server/register-middlewares.js +110 -0
  102. package/lib/services/server/register-routes.js +106 -0
  103. package/lib/services/server/routing.js +120 -0
  104. package/lib/services/webhook-runner.js +1 -1
  105. package/lib/utils/ee.js +3 -3
  106. package/lib/utils/get-dirs.js +17 -0
  107. package/lib/utils/index.js +2 -0
  108. package/lib/utils/signals.js +24 -0
  109. package/lib/utils/update-notifier/index.js +2 -1
  110. package/package.json +94 -93
  111. package/lib/core/app-configuration/load-functions.js +0 -28
  112. package/lib/core-api/index.js +0 -39
  113. package/lib/middlewares/boom/defaults.json +0 -5
  114. package/lib/middlewares/boom/index.js +0 -147
  115. package/lib/middlewares/cors/index.js +0 -66
  116. package/lib/middlewares/cron/defaults.json +0 -5
  117. package/lib/middlewares/cron/index.js +0 -43
  118. package/lib/middlewares/favicon/defaults.json +0 -7
  119. package/lib/middlewares/favicon/index.js +0 -32
  120. package/lib/middlewares/gzip/defaults.json +0 -6
  121. package/lib/middlewares/gzip/index.js +0 -19
  122. package/lib/middlewares/helmet/defaults.json +0 -18
  123. package/lib/middlewares/helmet/index.js +0 -9
  124. package/lib/middlewares/ip/defaults.json +0 -7
  125. package/lib/middlewares/ip/index.js +0 -25
  126. package/lib/middlewares/language/defaults.json +0 -9
  127. package/lib/middlewares/language/index.js +0 -40
  128. package/lib/middlewares/logger/defaults.json +0 -5
  129. package/lib/middlewares/logger/index.js +0 -37
  130. package/lib/middlewares/parser/defaults.json +0 -11
  131. package/lib/middlewares/parser/index.js +0 -72
  132. package/lib/middlewares/poweredBy/defaults.json +0 -5
  133. package/lib/middlewares/poweredBy/index.js +0 -16
  134. package/lib/middlewares/public/defaults.json +0 -8
  135. package/lib/middlewares/responseTime/defaults.json +0 -5
  136. package/lib/middlewares/responseTime/index.js +0 -25
  137. package/lib/middlewares/responses/defaults.json +0 -5
  138. package/lib/middlewares/responses/index.js +0 -18
  139. package/lib/middlewares/router/defaults.json +0 -7
  140. package/lib/middlewares/router/index.js +0 -72
  141. package/lib/middlewares/router/utils/compose-endpoint.js +0 -169
  142. package/lib/utils/get-prefixed-dependencies.js +0 -7
package/README.md CHANGED
@@ -9,11 +9,11 @@
9
9
  <br />
10
10
 
11
11
  <p align="center">
12
- <a href="https://www.npmjs.org/package/strapi">
13
- <img src="https://img.shields.io/npm/v/strapi/latest.svg" alt="NPM Version" />
12
+ <a href="https://www.npmjs.org/package/@strapi/strapi">
13
+ <img src="https://img.shields.io/npm/v/@strapi/strapi/latest.svg" alt="NPM Version" />
14
14
  </a>
15
- <a href="https://www.npmjs.org/package/strapi">
16
- <img src="https://img.shields.io/npm/dm/strapi.svg" alt="Monthly download on NPM" />
15
+ <a href="https://github.com/strapi/strapi/actions/workflows/tests.yml">
16
+ <img src="https://github.com/strapi/strapi/actions/workflows/tests.yml/badge.svg?branch=master" alt="Tests" />
17
17
  </a>
18
18
  <a href="https://discord.strapi.io">
19
19
  <img src="https://img.shields.io/discord/811989166782021633?label=Discord" alt="Strapi on Discord" />
@@ -24,7 +24,7 @@
24
24
 
25
25
  <p align="center">
26
26
  <a href="https://strapi.io">
27
- <img src="https://raw.githubusercontent.com/strapi/strapi/master/public/assets/administration_panel.png" alt="Administration panel" />
27
+ <img src="https://raw.githubusercontent.com/strapi/strapi/0bcebf77b37182fe021cb59cc19be8f5db4a18ac/public/assets/administration_panel.png" alt="Administration panel" />
28
28
  </a>
29
29
  </p>
30
30
 
@@ -39,7 +39,7 @@ Strapi is a free and open-source headless CMS delivering your content anywhere y
39
39
 
40
40
  ## Getting Started
41
41
 
42
- <a href="https://strapi.io/documentation/developer-docs/latest/getting-started/quick-start.html" target="_blank">Read the Getting Started tutorial</a> or follow the steps below:
42
+ <a href="https://docs.strapi.io/developer-docs/latest/getting-started/quick-start.html" target="_blank">Read the Getting Started tutorial</a> or follow the steps below:
43
43
 
44
44
  ### ⏳ Installation
45
45
 
@@ -65,7 +65,7 @@ Enjoy 🎉
65
65
 
66
66
  ### 🖐 Requirements
67
67
 
68
- Complete installation requirements can be found in the documentation under <a href="https://strapi.io/documentation/developer-docs/latest/setup-deployment-guides/deployment.html#recommended-requirements">Installation Requirements</a>.
68
+ Complete installation requirements can be found in the documentation under <a href="https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/deployment.html">Installation Requirements</a>.
69
69
 
70
70
  **Supported operating systems**:
71
71
 
@@ -79,13 +79,13 @@ Complete installation requirements can be found in the documentation under <a hr
79
79
 
80
80
  **Node:**
81
81
 
82
- - NodeJS >= 10.16 <=14
82
+ - NodeJS >= 12 <= 16
83
83
  - NPM >= 6.x
84
84
 
85
85
  **Database:**
86
86
 
87
- - MySQL >= 5.6
88
- - MariaDB >= 10.1
87
+ - MySQL >= 5.7.8
88
+ - MariaDB >= 10.2.7
89
89
  - PostgreSQL >= 10
90
90
  - SQLite >= 3
91
91
 
@@ -109,7 +109,7 @@ Please read our [Contributing Guide](./CONTRIBUTING.md) before submitting a Pull
109
109
 
110
110
  ## Community support
111
111
 
112
- For general help using Strapi, please refer to [the official Strapi documentation](https://strapi.io/documentation/). For additional help, you can use one of these channels to ask a question:
112
+ For general help using Strapi, please refer to [the official Strapi documentation](https://docs.strapi.io). For additional help, you can use one of these channels to ask a question:
113
113
 
114
114
  - [Discord](https://discord.strapi.io) (For live discussion with the Community and Strapi team)
115
115
  - [GitHub](https://github.com/strapi/strapi) (Bug reports, Contributions)
@@ -122,7 +122,7 @@ For general help using Strapi, please refer to [the official Strapi documentatio
122
122
 
123
123
  ## Migration
124
124
 
125
- Follow our [migration guides](https://strapi.io/documentation/developer-docs/latest/update-migration-guides/migration-guides.html) on the documentation to keep your projects up-to-date.
125
+ Follow our [migration guides](https://docs.strapi.io/developer-docs/latest/update-migration-guides/migration-guides.html) on the documentation to keep your projects up-to-date.
126
126
 
127
127
  ## Roadmap
128
128
 
@@ -132,8 +132,8 @@ Check out our [roadmap](https://portal.productboard.com/strapi) to get informed
132
132
 
133
133
  See our dedicated [repository](https://github.com/strapi/documentation) for the Strapi documentation, or view our documentation live:
134
134
 
135
- - [Developer docs](https://strapi.io/documentation/developer-docs/latest/getting-started/introduction.html)
136
- - [User docs](https://strapi.io/documentation/user-docs/latest/getting-started/introduction.html)
135
+ - [Developer docs](https://docs.strapi.io/developer-docs/latest/getting-started/introduction.html)
136
+ - [User guide](https://docs.strapi.io/user-docs/latest/getting-started/introduction.html)
137
137
 
138
138
  ## Try live demo
139
139
 
package/bin/strapi.js CHANGED
@@ -58,10 +58,7 @@ const getLocalScript = name => (...args) => {
58
58
  };
59
59
 
60
60
  // Initial program setup
61
- program
62
- .storeOptionsAsProperties(false)
63
- .passCommandToAction(false)
64
- .allowUnknownOption(true);
61
+ program.storeOptionsAsProperties(false).allowUnknownOption(true);
65
62
 
66
63
  program.helpOption('-h, --help', 'Display help for command');
67
64
  program.addHelpCommand('help [command]', 'Display help for command');
@@ -130,13 +127,12 @@ program
130
127
 
131
128
  // `$ strapi generate:template <directory>`
132
129
  program
133
- .command('generate:template <directory>')
130
+ .command('templates:generate <directory>')
134
131
  .description('Generate template from Strapi project')
135
132
  .action(getLocalScript('generate-template'));
136
133
 
137
134
  program
138
135
  .command('build')
139
- .option('--clean', 'Remove the build and .cache folders', false)
140
136
  .option('--no-optimization', 'Build the Administration without assets optimization')
141
137
  .description('Builds the strapi admin app')
142
138
  .action(getLocalScript('build'));
@@ -186,4 +182,39 @@ program
186
182
  .option('-p, --password <password>', 'New password for the user')
187
183
  .action(getLocalScript('admin-reset'));
188
184
 
185
+ program
186
+ .command('routes:list')
187
+ .description('List all the application routes')
188
+ .action(getLocalScript('routes/list'));
189
+
190
+ program
191
+ .command('middlewares:list')
192
+ .description('List all the application middlewares')
193
+ .action(getLocalScript('middlewares/list'));
194
+
195
+ program
196
+ .command('policies:list')
197
+ .description('List all the application policies')
198
+ .action(getLocalScript('policies/list'));
199
+
200
+ program
201
+ .command('content-types:list')
202
+ .description('List all the application content-types')
203
+ .action(getLocalScript('content-types/list'));
204
+
205
+ program
206
+ .command('hooks:list')
207
+ .description('List all the application hooks')
208
+ .action(getLocalScript('hooks/list'));
209
+
210
+ program
211
+ .command('services:list')
212
+ .description('List all the application services')
213
+ .action(getLocalScript('services/list'));
214
+
215
+ program
216
+ .command('controllers:list')
217
+ .description('List all the application controllers')
218
+ .action(getLocalScript('controllers/list'));
219
+
189
220
  program.parseAsync(process.argv);
package/lib/Strapi.js CHANGED
@@ -1,25 +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
12
  const utils = require('./utils');
14
- const initializeMiddlewares = require('./middlewares');
15
13
  const createStrapiFs = require('./services/fs');
16
14
  const createEventHub = require('./services/event-hub');
15
+ const { createServer } = require('./services/server');
17
16
  const createWebhookRunner = require('./services/webhook-runner');
18
17
  const { webhookModel, createWebhookStore } = require('./services/webhook-store');
19
18
  const { createCoreStore, coreStoreModel } = require('./services/core-store');
20
19
  const createEntityService = require('./services/entity-service');
20
+ const createCronService = require('./services/cron');
21
21
  const entityValidator = require('./services/entity-validator');
22
22
  const createTelemetry = require('./services/metrics');
23
+ const createAuth = require('./services/auth');
23
24
  const createUpdateNotifier = require('./utils/update-notifier');
24
25
  const createStartupLogger = require('./utils/startup-logger');
25
26
  const ee = require('./utils/ee');
@@ -27,6 +28,7 @@ const contentTypesRegistry = require('./core/registries/content-types');
27
28
  const servicesRegistry = require('./core/registries/services');
28
29
  const policiesRegistry = require('./core/registries/policies');
29
30
  const middlewaresRegistry = require('./core/registries/middlewares');
31
+ const hooksRegistry = require('./core/registries/hooks');
30
32
  const controllersRegistry = require('./core/registries/controllers');
31
33
  const modulesRegistry = require('./core/registries/modules');
32
34
  const pluginsRegistry = require('./core/registries/plugins');
@@ -34,37 +36,45 @@ const createConfigProvider = require('./core/registries/config');
34
36
  const apisRegistry = require('./core/registries/apis');
35
37
  const bootstrap = require('./core/bootstrap');
36
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');
37
43
 
38
44
  const LIFECYCLES = {
39
45
  REGISTER: 'register',
40
46
  BOOTSTRAP: 'bootstrap',
47
+ DESTROY: 'destroy',
41
48
  };
42
49
 
43
50
  class Strapi {
44
51
  constructor(opts = {}) {
45
- this.dir = opts.dir || process.cwd();
46
- 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);
47
55
  this.container = createContainer(this);
48
56
  this.container.register('config', createConfigProvider(appConfig));
49
57
  this.container.register('content-types', contentTypesRegistry(this));
50
58
  this.container.register('services', servicesRegistry(this));
51
59
  this.container.register('policies', policiesRegistry(this));
52
60
  this.container.register('middlewares', middlewaresRegistry(this));
61
+ this.container.register('hooks', hooksRegistry(this));
53
62
  this.container.register('controllers', controllersRegistry(this));
54
63
  this.container.register('modules', modulesRegistry(this));
55
64
  this.container.register('plugins', pluginsRegistry(this));
56
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);
70
+ this.server = createServer(this);
71
+
63
72
  this.fs = createStrapiFs(this);
64
73
  this.eventHub = createEventHub();
65
74
  this.startupLogger = createStartupLogger(this);
66
- this.app.proxy = this.config.get('server.proxy');
67
75
  this.log = createLogger(this.config.get('logger', {}));
76
+ this.cron = createCronService();
77
+ this.telemetry = createTelemetry(this);
68
78
 
69
79
  createUpdateNotifier(this).notify();
70
80
  }
@@ -74,39 +84,63 @@ class Strapi {
74
84
  }
75
85
 
76
86
  get EE() {
77
- 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();
78
92
  }
79
93
 
80
94
  service(uid) {
81
95
  return this.container.get('services').get(uid);
82
96
  }
83
97
 
98
+ get controllers() {
99
+ return this.container.get('controllers').getAll();
100
+ }
101
+
84
102
  controller(uid) {
85
103
  return this.container.get('controllers').get(uid);
86
104
  }
87
105
 
106
+ get contentTypes() {
107
+ return this.container.get('content-types').getAll();
108
+ }
109
+
88
110
  contentType(name) {
89
111
  return this.container.get('content-types').get(name);
90
112
  }
91
113
 
92
- get contentTypes() {
93
- return this.container.get('content-types').getAll();
114
+ get policies() {
115
+ return this.container.get('policies').getAll();
94
116
  }
95
117
 
96
118
  policy(name) {
97
119
  return this.container.get('policies').get(name);
98
120
  }
99
121
 
122
+ get middlewares() {
123
+ return this.container.get('middlewares').getAll();
124
+ }
125
+
100
126
  middleware(name) {
101
127
  return this.container.get('middlewares').get(name);
102
128
  }
103
129
 
130
+ get plugins() {
131
+ return this.container.get('plugins').getAll();
132
+ }
133
+
104
134
  plugin(name) {
105
135
  return this.container.get('plugins').get(name);
106
136
  }
107
137
 
108
- get plugins() {
109
- return this.container.get('plugins').getAll();
138
+ get hooks() {
139
+ return this.container.get('hooks').getAll();
140
+ }
141
+
142
+ hook(name) {
143
+ return this.container.get('hooks').get(name);
110
144
  }
111
145
 
112
146
  // api(name) {
@@ -117,15 +151,16 @@ class Strapi {
117
151
  return this.container.get('apis').getAll();
118
152
  }
119
153
 
154
+ get auth() {
155
+ return this.container.get('auth');
156
+ }
157
+
120
158
  async start() {
121
159
  try {
122
160
  if (!this.isLoaded) {
123
161
  await this.load();
124
162
  }
125
163
 
126
- this.app.use(this.router.routes()).use(this.router.allowedMethods());
127
-
128
- // Launch server.
129
164
  await this.listen();
130
165
 
131
166
  return this;
@@ -137,17 +172,7 @@ class Strapi {
137
172
  async destroy() {
138
173
  await this.server.destroy();
139
174
 
140
- await Promise.all(
141
- Object.values(this.plugins).map(plugin => {
142
- if (_.has(plugin, 'destroy') && typeof plugin.destroy === 'function') {
143
- return plugin.destroy();
144
- }
145
- })
146
- );
147
-
148
- if (_.has(this, 'admin')) {
149
- await this.admin.destroy();
150
- }
175
+ await this.runLifecyclesFunctions(LIFECYCLES.DESTROY);
151
176
 
152
177
  this.eventHub.removeAllListeners();
153
178
 
@@ -156,6 +181,9 @@ class Strapi {
156
181
  }
157
182
 
158
183
  this.telemetry.destroy();
184
+ this.cron.destroy();
185
+
186
+ process.removeAllListeners();
159
187
 
160
188
  delete global.strapi;
161
189
  }
@@ -176,9 +204,9 @@ class Strapi {
176
204
  async openAdmin({ isInitialized }) {
177
205
  const shouldOpenAdmin =
178
206
  this.config.get('environment') === 'development' &&
179
- this.config.get('server.admin.autoOpen', true) !== false;
207
+ this.config.get('admin.autoOpen', true) !== false;
180
208
 
181
- if (shouldOpenAdmin || !isInitialized) {
209
+ if (shouldOpenAdmin && !isInitialized) {
182
210
  await utils.openBrowser(this.config);
183
211
  }
184
212
  }
@@ -233,7 +261,7 @@ class Strapi {
233
261
  }
234
262
 
235
263
  stop(exitCode = 1) {
236
- this.server.destroy();
264
+ this.destroy();
237
265
 
238
266
  if (this.config.get('autoReload')) {
239
267
  process.send('stop');
@@ -264,20 +292,24 @@ class Strapi {
264
292
  }
265
293
 
266
294
  async loadMiddlewares() {
267
- this.middleware = await loaders.loadMiddlewares(this);
295
+ await loaders.loadMiddlewares(this);
268
296
  }
269
297
 
270
- async load() {
271
- this.app.use(async (ctx, next) => {
272
- if (ctx.request.url === '/_health' && ['HEAD', 'GET'].includes(ctx.request.method)) {
273
- ctx.set('strapi', 'You are so French!');
274
- ctx.status = 204;
275
- } else {
276
- await next();
277
- }
278
- });
298
+ async loadApp() {
299
+ this.app = await loaders.loadSrcIndex(this);
300
+ }
301
+
302
+ registerInternalHooks() {
303
+ this.container.get('hooks').set('strapi::content-types.beforeSync', createAsyncParallelHook());
304
+ this.container.get('hooks').set('strapi::content-types.afterSync', createAsyncParallelHook());
279
305
 
306
+ this.hook('strapi::content-types.beforeSync').register(draftAndPublishSync.disable);
307
+ this.hook('strapi::content-types.afterSync').register(draftAndPublishSync.enable);
308
+ }
309
+
310
+ async register() {
280
311
  await Promise.all([
312
+ this.loadApp(),
281
313
  this.loadPlugins(),
282
314
  this.loadAdmin(),
283
315
  this.loadAPIs(),
@@ -286,7 +318,7 @@ class Strapi {
286
318
  this.loadPolicies(),
287
319
  ]);
288
320
 
289
- await bootstrap(this);
321
+ await bootstrap({ strapi: this });
290
322
 
291
323
  // init webhook runner
292
324
  this.webhookRunner = createWebhookRunner({
@@ -295,8 +327,16 @@ class Strapi {
295
327
  configuration: this.config.get('server.webhooks', {}),
296
328
  });
297
329
 
330
+ this.registerInternalHooks();
331
+
332
+ this.telemetry.register();
333
+
298
334
  await this.runLifecyclesFunctions(LIFECYCLES.REGISTER);
299
335
 
336
+ return this;
337
+ }
338
+
339
+ async bootstrap() {
300
340
  const contentTypes = [
301
341
  coreStoreModel,
302
342
  webhookModel,
@@ -309,19 +349,10 @@ class Strapi {
309
349
  models: Database.transformContentTypes(contentTypes),
310
350
  });
311
351
 
312
- await this.db.schema.sync();
313
-
314
- this.store = createCoreStore({
315
- environment: this.config.get('environment'),
316
- db: this.db,
317
- });
318
-
352
+ this.store = createCoreStore({ db: this.db });
319
353
  this.webhookStore = createWebhookStore({ db: this.db });
320
354
 
321
- await this.startWebhooks();
322
-
323
355
  this.entityValidator = entityValidator;
324
-
325
356
  this.entityService = createEntityService({
326
357
  strapi: this,
327
358
  db: this.db,
@@ -329,14 +360,57 @@ class Strapi {
329
360
  entityValidator: this.entityValidator,
330
361
  });
331
362
 
332
- this.telemetry = createTelemetry(this);
363
+ const cronTasks = this.config.get('server.cron.tasks', {});
364
+ this.cron.add(cronTasks);
365
+
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
+ });
333
381
 
334
- // Initialize middlewares.
335
- await initializeMiddlewares.call(this);
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();
336
400
 
337
401
  await this.runLifecyclesFunctions(LIFECYCLES.BOOTSTRAP);
338
402
 
403
+ this.cron.start();
404
+
405
+ return this;
406
+ }
407
+
408
+ async load() {
409
+ await this.register();
410
+ await this.bootstrap();
411
+
339
412
  this.isLoaded = true;
413
+
340
414
  return this;
341
415
  }
342
416
 
@@ -359,7 +433,6 @@ class Strapi {
359
433
  }
360
434
 
361
435
  if (this.config.get('autoReload')) {
362
- this.server.destroy();
363
436
  process.send('reload');
364
437
  }
365
438
  };
@@ -367,14 +440,14 @@ class Strapi {
367
440
  Object.defineProperty(reload, 'isWatching', {
368
441
  configurable: true,
369
442
  enumerable: true,
370
- set: value => {
443
+ set(value) {
371
444
  // Special state when the reloader is disabled temporarly (see GraphQL plugin example).
372
445
  if (state.isWatching === false && value === true) {
373
446
  state.shouldReload += 1;
374
447
  }
375
448
  state.isWatching = value;
376
449
  },
377
- get: () => {
450
+ get() {
378
451
  return state.isWatching;
379
452
  },
380
453
  });
@@ -386,24 +459,20 @@ class Strapi {
386
459
  }
387
460
 
388
461
  async runLifecyclesFunctions(lifecycleName) {
389
- const execLifecycle = async fn => {
390
- if (!fn) {
391
- return;
392
- }
393
-
394
- return fn({ strapi: this });
395
- };
396
-
397
- const configPath = `functions.${lifecycleName}`;
398
-
399
462
  // plugins
400
463
  await this.container.get('modules')[lifecycleName]();
401
464
 
402
465
  // user
403
- await execLifecycle(this.config.get(configPath));
466
+ const userLifecycleFunction = this.app && this.app[lifecycleName];
467
+ if (isFunction(userLifecycleFunction)) {
468
+ await userLifecycleFunction({ strapi: this });
469
+ }
404
470
 
405
471
  // admin
406
- await this.admin[lifecycleName]();
472
+ const adminLifecycleFunction = this.admin && this.admin[lifecycleName];
473
+ if (isFunction(adminLifecycleFunction)) {
474
+ await adminLifecycleFunction({ strapi: this });
475
+ }
407
476
  }
408
477
 
409
478
  getModel(uid) {
@@ -413,7 +482,6 @@ class Strapi {
413
482
  /**
414
483
  * Binds queries with a specific model
415
484
  * @param {string} uid
416
- * @returns {}
417
485
  */
418
486
  query(uid) {
419
487
  return this.db.query(uid);
@@ -1,33 +1,43 @@
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 ({ 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
- if (clean) {
23
- await strapiAdmin.clean({ dir });
24
- }
31
+ // Always remove the .cache and build folders
32
+ await strapiAdmin.clean({ dir });
25
33
 
26
34
  ee({ dir });
27
35
 
28
36
  return strapiAdmin
29
37
  .build({
38
+ forceBuild,
30
39
  dir,
40
+ plugins,
31
41
  // front end build env is always production for now
32
42
  env: 'production',
33
43
  optimize: optimization,
@@ -37,7 +47,7 @@ module.exports = async ({ clean, optimization }) => {
37
47
  },
38
48
  })
39
49
  .then(() => {
40
- process.exit();
50
+ console.log('Admin UI built successfully');
41
51
  })
42
52
  .catch(err => {
43
53
  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
+ };