@strapi/strapi 4.0.0-next.8 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +14 -14
  2. package/bin/strapi.js +46 -60
  3. package/lib/Strapi.js +152 -74
  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 -19
  18. package/lib/core/bootstrap.js +3 -95
  19. package/lib/core/domain/content-type/index.js +5 -11
  20. package/lib/core/domain/module/index.js +42 -11
  21. package/lib/core/domain/module/validation.js +16 -19
  22. package/lib/core/loaders/admin.js +2 -2
  23. package/lib/core/loaders/apis.js +148 -9
  24. package/lib/core/loaders/components.js +4 -6
  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 +29 -0
  33. package/lib/core/registries/content-types.js +61 -12
  34. package/lib/core/registries/controllers.d.ts +7 -0
  35. package/lib/core/registries/controllers.js +91 -7
  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 +64 -5
  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 +64 -5
  44. package/lib/core/registries/services.d.ts +7 -0
  45. package/lib/core/registries/services.js +86 -17
  46. package/lib/core/utils.js +22 -0
  47. package/lib/core-api/controller/collection-type.js +45 -26
  48. package/lib/core-api/controller/index.d.ts +25 -0
  49. package/lib/core-api/controller/index.js +33 -11
  50. package/lib/core-api/controller/single-type.js +29 -15
  51. package/lib/core-api/controller/transform.js +62 -6
  52. package/lib/core-api/routes/index.js +71 -0
  53. package/lib/core-api/service/collection-type.js +43 -21
  54. package/lib/core-api/service/index.d.ts +21 -0
  55. package/lib/core-api/service/index.js +8 -67
  56. package/lib/core-api/service/pagination.js +125 -0
  57. package/lib/core-api/service/single-type.js +17 -19
  58. package/lib/factories.d.ts +48 -0
  59. package/lib/factories.js +84 -0
  60. package/lib/index.d.ts +10 -31
  61. package/lib/index.js +5 -1
  62. package/lib/middlewares/body.js +33 -0
  63. package/lib/middlewares/compression.js +8 -0
  64. package/lib/middlewares/cors.js +58 -0
  65. package/lib/middlewares/errors.js +40 -0
  66. package/lib/middlewares/favicon.js +19 -0
  67. package/lib/middlewares/index.d.ts +5 -0
  68. package/lib/middlewares/index.js +30 -116
  69. package/lib/middlewares/ip.js +8 -0
  70. package/lib/middlewares/logger.js +27 -0
  71. package/lib/middlewares/powered-by.js +20 -0
  72. package/lib/middlewares/public/index.js +72 -77
  73. package/lib/middlewares/query.js +46 -0
  74. package/lib/middlewares/response-time.js +15 -0
  75. package/lib/middlewares/responses.js +19 -0
  76. package/lib/middlewares/security.js +51 -0
  77. package/lib/middlewares/session/index.js +6 -6
  78. package/lib/migrations/draft-publish.js +57 -0
  79. package/lib/services/auth/index.js +87 -0
  80. package/lib/services/core-store.js +64 -49
  81. package/lib/services/cron.js +54 -0
  82. package/lib/services/entity-service/attributes/index.js +31 -0
  83. package/lib/services/entity-service/attributes/transforms.js +20 -0
  84. package/lib/services/entity-service/components.js +39 -15
  85. package/lib/services/entity-service/index.d.ts +91 -0
  86. package/lib/services/entity-service/index.js +118 -60
  87. package/lib/services/entity-service/params.js +52 -94
  88. package/lib/services/entity-validator/index.js +76 -43
  89. package/lib/services/entity-validator/validators.js +131 -43
  90. package/lib/services/errors.js +77 -0
  91. package/lib/services/fs.js +1 -1
  92. package/lib/services/metrics/index.js +38 -36
  93. package/lib/services/server/admin-api.js +14 -0
  94. package/lib/services/server/api.js +36 -0
  95. package/lib/services/server/compose-endpoint.js +141 -0
  96. package/lib/services/server/content-api.js +16 -0
  97. package/lib/{server.js → services/server/http-server.js} +0 -0
  98. package/lib/services/server/index.js +127 -0
  99. package/lib/services/server/koa.js +64 -0
  100. package/lib/services/server/middleware.js +122 -0
  101. package/lib/services/server/policy.js +32 -0
  102. package/lib/services/server/register-middlewares.js +110 -0
  103. package/lib/services/server/register-routes.js +106 -0
  104. package/lib/services/server/routing.js +120 -0
  105. package/lib/services/webhook-runner.js +1 -1
  106. package/lib/utils/ee.js +3 -3
  107. package/lib/utils/get-dirs.js +17 -0
  108. package/lib/utils/index.js +2 -0
  109. package/lib/utils/signals.js +24 -0
  110. package/lib/utils/update-notifier/index.js +2 -1
  111. package/package.json +94 -97
  112. package/lib/commands/generate.js +0 -76
  113. package/lib/core/app-configuration/load-functions.js +0 -28
  114. package/lib/core-api/index.js +0 -39
  115. package/lib/load/check-reserved-filename.js +0 -10
  116. package/lib/load/load-config-files.js +0 -22
  117. package/lib/load/require-file-parse.js +0 -15
  118. package/lib/middlewares/boom/defaults.json +0 -5
  119. package/lib/middlewares/boom/index.js +0 -147
  120. package/lib/middlewares/cors/index.js +0 -66
  121. package/lib/middlewares/cron/defaults.json +0 -5
  122. package/lib/middlewares/cron/index.js +0 -43
  123. package/lib/middlewares/favicon/defaults.json +0 -7
  124. package/lib/middlewares/favicon/index.js +0 -32
  125. package/lib/middlewares/gzip/defaults.json +0 -6
  126. package/lib/middlewares/gzip/index.js +0 -19
  127. package/lib/middlewares/helmet/defaults.json +0 -18
  128. package/lib/middlewares/helmet/index.js +0 -9
  129. package/lib/middlewares/ip/defaults.json +0 -7
  130. package/lib/middlewares/ip/index.js +0 -25
  131. package/lib/middlewares/language/defaults.json +0 -9
  132. package/lib/middlewares/language/index.js +0 -40
  133. package/lib/middlewares/logger/defaults.json +0 -5
  134. package/lib/middlewares/logger/index.js +0 -37
  135. package/lib/middlewares/parser/defaults.json +0 -11
  136. package/lib/middlewares/parser/index.js +0 -71
  137. package/lib/middlewares/poweredBy/defaults.json +0 -5
  138. package/lib/middlewares/poweredBy/index.js +0 -16
  139. package/lib/middlewares/public/defaults.json +0 -8
  140. package/lib/middlewares/responseTime/defaults.json +0 -5
  141. package/lib/middlewares/responseTime/index.js +0 -25
  142. package/lib/middlewares/responses/defaults.json +0 -5
  143. package/lib/middlewares/responses/index.js +0 -18
  144. package/lib/middlewares/router/defaults.json +0 -7
  145. package/lib/middlewares/router/index.js +0 -58
  146. package/lib/middlewares/router/utils/composeEndpoint.js +0 -177
  147. 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');
@@ -118,68 +115,22 @@ program
118
115
  .description('Start your Strapi application in development mode')
119
116
  .action(getLocalScript('develop'));
120
117
 
121
- // `$ strapi generate:api`
122
- program
123
- .command('generate:api <id> [attributes...]')
124
- .option('-a, --api <api>', 'API name to generate the files in')
125
- .option('-p, --plugin <api>', 'Name of the local plugin')
126
- .option('-e, --extend <api>', 'Name of the plugin to extend')
127
- .option('--draft-and-publish', 'Enable draft/publish', false)
128
- .description('Generate a basic API')
129
- .action((id, attributes, cliArguments) => {
130
- cliArguments.attributes = attributes;
131
- getLocalScript('generate')(id, cliArguments);
132
- });
133
-
134
- // `$ strapi generate:controller`
135
- program
136
- .command('generate:controller <id>')
137
- .option('-a, --api <api>', 'API name to generate the files in')
138
- .option('-p, --plugin <api>', 'Name of the local plugin')
139
- .option('-e, --extend <api>', 'Name of the plugin to extend')
140
- .description('Generate a controller for an API')
141
- .action(getLocalScript('generate'));
142
-
143
- // `$ strapi generate:model`
144
- program
145
- .command('generate:model <id> [attributes...]')
146
- .option('-a, --api <api>', 'API name to generate a sub API')
147
- .option('-p, --plugin <api>', 'plugin name')
148
- .option('--draft-and-publish', 'Enable draft/publish', false)
149
- .description('Generate a model for an API')
150
- .action((id, attributes, cliArguments) => {
151
- cliArguments.attributes = attributes;
152
- getLocalScript('generate')(id, cliArguments);
153
- });
154
-
155
- // `$ strapi generate:policy`
156
- program
157
- .command('generate:policy <id>')
158
- .option('-a, --api <api>', 'API name')
159
- .option('-p, --plugin <api>', 'plugin name')
160
- .description('Generate a policy for an API')
161
- .action(getLocalScript('generate'));
162
-
163
- // `$ strapi generate:service`
118
+ // $ strapi generate
164
119
  program
165
- .command('generate:service <id>')
166
- .option('-a, --api <api>', 'API name')
167
- .option('-p, --plugin <api>', 'plugin name')
168
- .description('Generate a service for an API')
169
- .action(getLocalScript('generate'));
170
-
171
- // `$ strapi generate:plugin`
172
- program
173
- .command('generate:plugin <id>')
174
- .option('-n, --name <name>', 'Plugin name')
175
- .description('Generate a basic plugin')
176
- .action(getLocalScript('generate'));
120
+ .command('generate')
121
+ .description('Launch interactive API generator')
122
+ .action(() => {
123
+ checkCwdIsStrapiApp('generate');
124
+ process.argv.splice(2, 1);
125
+ require('@strapi/generators').runCLI();
126
+ });
177
127
 
178
128
  // `$ strapi generate:template <directory>`
179
129
  program
180
- .command('generate:template <directory>')
130
+ .command('templates:generate <directory>')
181
131
  .description('Generate template from Strapi project')
182
132
  .action(getLocalScript('generate-template'));
133
+
183
134
  program
184
135
  .command('build')
185
136
  .option('--clean', 'Remove the build and .cache folders', false)
@@ -232,4 +183,39 @@ program
232
183
  .option('-p, --password <password>', 'New password for the user')
233
184
  .action(getLocalScript('admin-reset'));
234
185
 
186
+ program
187
+ .command('routes:list')
188
+ .description('List all the application routes')
189
+ .action(getLocalScript('routes/list'));
190
+
191
+ program
192
+ .command('middlewares:list')
193
+ .description('List all the application middlewares')
194
+ .action(getLocalScript('middlewares/list'));
195
+
196
+ program
197
+ .command('policies:list')
198
+ .description('List all the application policies')
199
+ .action(getLocalScript('policies/list'));
200
+
201
+ program
202
+ .command('content-types:list')
203
+ .description('List all the application content-types')
204
+ .action(getLocalScript('content-types/list'));
205
+
206
+ program
207
+ .command('hooks:list')
208
+ .description('List all the application hooks')
209
+ .action(getLocalScript('hooks/list'));
210
+
211
+ program
212
+ .command('services:list')
213
+ .description('List all the application services')
214
+ .action(getLocalScript('services/list'));
215
+
216
+ program
217
+ .command('controllers:list')
218
+ .description('List all the application controllers')
219
+ .action(getLocalScript('controllers/list'));
220
+
235
221
  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,42 +28,53 @@ 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');
33
35
  const createConfigProvider = require('./core/registries/config');
36
+ const apisRegistry = require('./core/registries/apis');
34
37
  const bootstrap = require('./core/bootstrap');
35
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');
36
43
 
37
44
  const LIFECYCLES = {
38
45
  REGISTER: 'register',
39
46
  BOOTSTRAP: 'bootstrap',
47
+ DESTROY: 'destroy',
40
48
  };
41
49
 
42
50
  class Strapi {
43
51
  constructor(opts = {}) {
44
- this.dir = opts.dir || process.cwd();
45
- 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);
46
55
  this.container = createContainer(this);
47
56
  this.container.register('config', createConfigProvider(appConfig));
48
57
  this.container.register('content-types', contentTypesRegistry(this));
49
58
  this.container.register('services', servicesRegistry(this));
50
59
  this.container.register('policies', policiesRegistry(this));
51
60
  this.container.register('middlewares', middlewaresRegistry(this));
61
+ this.container.register('hooks', hooksRegistry(this));
52
62
  this.container.register('controllers', controllersRegistry(this));
53
63
  this.container.register('modules', modulesRegistry(this));
54
64
  this.container.register('plugins', pluginsRegistry(this));
65
+ this.container.register('apis', apisRegistry(this));
66
+ this.container.register('auth', createAuth(this));
55
67
 
56
68
  this.isLoaded = false;
57
69
  this.reload = this.reload();
58
- this.app = new Koa();
59
- this.router = new Router();
60
- this.server = createHTTPServer(this, this.app);
70
+ this.server = createServer(this);
71
+
61
72
  this.fs = createStrapiFs(this);
62
73
  this.eventHub = createEventHub();
63
74
  this.startupLogger = createStartupLogger(this);
64
- this.app.proxy = this.config.get('server.proxy');
65
75
  this.log = createLogger(this.config.get('logger', {}));
76
+ this.cron = createCronService();
77
+ this.telemetry = createTelemetry(this);
66
78
 
67
79
  createUpdateNotifier(this).notify();
68
80
  }
@@ -72,39 +84,75 @@ class Strapi {
72
84
  }
73
85
 
74
86
  get EE() {
75
- 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();
76
92
  }
77
93
 
78
94
  service(uid) {
79
95
  return this.container.get('services').get(uid);
80
96
  }
81
97
 
98
+ get controllers() {
99
+ return this.container.get('controllers').getAll();
100
+ }
101
+
82
102
  controller(uid) {
83
103
  return this.container.get('controllers').get(uid);
84
104
  }
85
105
 
106
+ get contentTypes() {
107
+ return this.container.get('content-types').getAll();
108
+ }
109
+
86
110
  contentType(name) {
87
111
  return this.container.get('content-types').get(name);
88
112
  }
89
113
 
90
- get contentTypes() {
91
- return this.container.get('content-types').getAll();
114
+ get policies() {
115
+ return this.container.get('policies').getAll();
92
116
  }
93
117
 
94
118
  policy(name) {
95
119
  return this.container.get('policies').get(name);
96
120
  }
97
121
 
122
+ get middlewares() {
123
+ return this.container.get('middlewares').getAll();
124
+ }
125
+
98
126
  middleware(name) {
99
127
  return this.container.get('middlewares').get(name);
100
128
  }
101
129
 
130
+ get plugins() {
131
+ return this.container.get('plugins').getAll();
132
+ }
133
+
102
134
  plugin(name) {
103
135
  return this.container.get('plugins').get(name);
104
136
  }
105
137
 
106
- get plugins() {
107
- 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);
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');
108
156
  }
109
157
 
110
158
  async start() {
@@ -113,9 +161,6 @@ class Strapi {
113
161
  await this.load();
114
162
  }
115
163
 
116
- this.app.use(this.router.routes()).use(this.router.allowedMethods());
117
-
118
- // Launch server.
119
164
  await this.listen();
120
165
 
121
166
  return this;
@@ -127,17 +172,7 @@ class Strapi {
127
172
  async destroy() {
128
173
  await this.server.destroy();
129
174
 
130
- await Promise.all(
131
- Object.values(this.plugins).map(plugin => {
132
- if (_.has(plugin, 'destroy') && typeof plugin.destroy === 'function') {
133
- return plugin.destroy();
134
- }
135
- })
136
- );
137
-
138
- if (_.has(this, 'admin')) {
139
- await this.admin.destroy();
140
- }
175
+ await this.runLifecyclesFunctions(LIFECYCLES.DESTROY);
141
176
 
142
177
  this.eventHub.removeAllListeners();
143
178
 
@@ -146,6 +181,9 @@ class Strapi {
146
181
  }
147
182
 
148
183
  this.telemetry.destroy();
184
+ this.cron.destroy();
185
+
186
+ process.removeAllListeners();
149
187
 
150
188
  delete global.strapi;
151
189
  }
@@ -165,10 +203,10 @@ class Strapi {
165
203
 
166
204
  async openAdmin({ isInitialized }) {
167
205
  const shouldOpenAdmin =
168
- this.config.environment === 'development' &&
169
- this.config.get('server.admin.autoOpen', true) !== false;
206
+ this.config.get('environment') === 'development' &&
207
+ this.config.get('admin.autoOpen', true) !== false;
170
208
 
171
- if (shouldOpenAdmin || !isInitialized) {
209
+ if (shouldOpenAdmin && !isInitialized) {
172
210
  await utils.openBrowser(this.config);
173
211
  }
174
212
  }
@@ -223,7 +261,7 @@ class Strapi {
223
261
  }
224
262
 
225
263
  stop(exitCode = 1) {
226
- this.server.destroy();
264
+ this.destroy();
227
265
 
228
266
  if (this.config.get('autoReload')) {
229
267
  process.send('stop');
@@ -246,7 +284,7 @@ class Strapi {
246
284
  }
247
285
 
248
286
  async loadAPIs() {
249
- this.api = await loaders.loadAPIs(this);
287
+ await loaders.loadAPIs(this);
250
288
  }
251
289
 
252
290
  async loadComponents() {
@@ -254,20 +292,24 @@ class Strapi {
254
292
  }
255
293
 
256
294
  async loadMiddlewares() {
257
- this.middleware = await loaders.loadMiddlewares(this);
295
+ await loaders.loadMiddlewares(this);
258
296
  }
259
297
 
260
- async load() {
261
- this.app.use(async (ctx, next) => {
262
- if (ctx.request.url === '/_health' && ['HEAD', 'GET'].includes(ctx.request.method)) {
263
- ctx.set('strapi', 'You are so French!');
264
- ctx.status = 204;
265
- } else {
266
- await next();
267
- }
268
- });
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());
269
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() {
270
311
  await Promise.all([
312
+ this.loadApp(),
271
313
  this.loadPlugins(),
272
314
  this.loadAdmin(),
273
315
  this.loadAPIs(),
@@ -276,7 +318,7 @@ class Strapi {
276
318
  this.loadPolicies(),
277
319
  ]);
278
320
 
279
- await bootstrap(this);
321
+ await bootstrap({ strapi: this });
280
322
 
281
323
  // init webhook runner
282
324
  this.webhookRunner = createWebhookRunner({
@@ -285,8 +327,16 @@ class Strapi {
285
327
  configuration: this.config.get('server.webhooks', {}),
286
328
  });
287
329
 
330
+ this.registerInternalHooks();
331
+
332
+ this.telemetry.register();
333
+
288
334
  await this.runLifecyclesFunctions(LIFECYCLES.REGISTER);
289
335
 
336
+ return this;
337
+ }
338
+
339
+ async bootstrap() {
290
340
  const contentTypes = [
291
341
  coreStoreModel,
292
342
  webhookModel,
@@ -299,19 +349,10 @@ class Strapi {
299
349
  models: Database.transformContentTypes(contentTypes),
300
350
  });
301
351
 
302
- await this.db.schema.sync();
303
-
304
- this.store = createCoreStore({
305
- environment: this.config.environment,
306
- db: this.db,
307
- });
308
-
352
+ this.store = createCoreStore({ db: this.db });
309
353
  this.webhookStore = createWebhookStore({ db: this.db });
310
354
 
311
- await this.startWebhooks();
312
-
313
355
  this.entityValidator = entityValidator;
314
-
315
356
  this.entityService = createEntityService({
316
357
  strapi: this,
317
358
  db: this.db,
@@ -319,14 +360,57 @@ class Strapi {
319
360
  entityValidator: this.entityValidator,
320
361
  });
321
362
 
322
- 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
+ }
323
376
 
324
- // Initialize middlewares.
325
- await initializeMiddlewares.call(this);
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();
326
400
 
327
401
  await this.runLifecyclesFunctions(LIFECYCLES.BOOTSTRAP);
328
402
 
403
+ this.cron.start();
404
+
405
+ return this;
406
+ }
407
+
408
+ async load() {
409
+ await this.register();
410
+ await this.bootstrap();
411
+
329
412
  this.isLoaded = true;
413
+
330
414
  return this;
331
415
  }
332
416
 
@@ -349,7 +433,6 @@ class Strapi {
349
433
  }
350
434
 
351
435
  if (this.config.get('autoReload')) {
352
- this.server.destroy();
353
436
  process.send('reload');
354
437
  }
355
438
  };
@@ -357,14 +440,14 @@ class Strapi {
357
440
  Object.defineProperty(reload, 'isWatching', {
358
441
  configurable: true,
359
442
  enumerable: true,
360
- set: value => {
443
+ set(value) {
361
444
  // Special state when the reloader is disabled temporarly (see GraphQL plugin example).
362
445
  if (state.isWatching === false && value === true) {
363
446
  state.shouldReload += 1;
364
447
  }
365
448
  state.isWatching = value;
366
449
  },
367
- get: () => {
450
+ get() {
368
451
  return state.isWatching;
369
452
  },
370
453
  });
@@ -376,24 +459,20 @@ class Strapi {
376
459
  }
377
460
 
378
461
  async runLifecyclesFunctions(lifecycleName) {
379
- const execLifecycle = async fn => {
380
- if (!fn) {
381
- return;
382
- }
383
-
384
- return fn();
385
- };
386
-
387
- const configPath = `functions.${lifecycleName}`;
388
-
389
462
  // plugins
390
463
  await this.container.get('modules')[lifecycleName]();
391
464
 
392
465
  // user
393
- await execLifecycle(this.config.get(configPath));
466
+ const userLifecycleFunction = this.app && this.app[lifecycleName];
467
+ if (isFunction(userLifecycleFunction)) {
468
+ await userLifecycleFunction({ strapi: this });
469
+ }
394
470
 
395
471
  // admin
396
- await this.admin[lifecycleName]();
472
+ const adminLifecycleFunction = this.admin && this.admin[lifecycleName];
473
+ if (isFunction(adminLifecycleFunction)) {
474
+ await adminLifecycleFunction({ strapi: this });
475
+ }
397
476
  }
398
477
 
399
478
  getModel(uid) {
@@ -403,7 +482,6 @@ class Strapi {
403
482
  /**
404
483
  * Binds queries with a specific model
405
484
  * @param {string} uid
406
- * @returns {}
407
485
  */
408
486
  query(uid) {
409
487
  return this.db.query(uid);