@strapi/strapi 4.0.0-beta.2 → 4.0.0-beta.20

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 (89) hide show
  1. package/README.md +12 -12
  2. package/bin/strapi.js +6 -1
  3. package/lib/Strapi.js +33 -21
  4. package/lib/commands/build.js +1 -1
  5. package/lib/commands/content-types/list.js +3 -5
  6. package/lib/commands/develop.js +8 -10
  7. package/lib/commands/generate-template.js +4 -5
  8. package/lib/commands/hooks/list.js +3 -5
  9. package/lib/commands/middlewares/list.js +3 -5
  10. package/lib/commands/new.js +3 -1
  11. package/lib/commands/policies/list.js +3 -5
  12. package/lib/commands/services/list.js +22 -0
  13. package/lib/commands/watchAdmin.js +4 -4
  14. package/lib/core/app-configuration/index.js +5 -10
  15. package/lib/core/bootstrap.js +2 -2
  16. package/lib/core/domain/module/index.js +3 -1
  17. package/lib/core/domain/module/validation.js +1 -4
  18. package/lib/core/loaders/admin.js +2 -2
  19. package/lib/core/loaders/apis.js +3 -1
  20. package/lib/core/loaders/plugins/get-enabled-plugins.js +25 -9
  21. package/lib/core/loaders/plugins/index.js +21 -7
  22. package/lib/core/loaders/src-index.js +1 -0
  23. package/lib/core/registries/apis.js +2 -16
  24. package/lib/core/registries/content-types.js +50 -6
  25. package/lib/core/registries/controllers.d.ts +7 -0
  26. package/lib/core/registries/controllers.js +74 -3
  27. package/lib/core/registries/hooks.d.ts +20 -0
  28. package/lib/core/registries/hooks.js +57 -7
  29. package/lib/core/registries/middlewares.d.ts +5 -0
  30. package/lib/core/registries/middlewares.js +61 -2
  31. package/lib/core/registries/policies.d.ts +9 -0
  32. package/lib/core/registries/policies.js +57 -6
  33. package/lib/core/registries/services.d.ts +7 -0
  34. package/lib/core/registries/services.js +67 -11
  35. package/lib/core-api/controller/collection-type.js +38 -11
  36. package/lib/core-api/controller/index.d.ts +25 -0
  37. package/lib/core-api/controller/index.js +30 -11
  38. package/lib/core-api/controller/single-type.js +26 -7
  39. package/lib/core-api/routes/index.js +71 -0
  40. package/lib/core-api/service/collection-type.js +8 -12
  41. package/lib/core-api/service/index.d.ts +21 -0
  42. package/lib/core-api/service/index.js +9 -19
  43. package/lib/core-api/service/pagination.js +7 -2
  44. package/lib/core-api/service/single-type.js +12 -11
  45. package/lib/factories.d.ts +48 -0
  46. package/lib/factories.js +84 -0
  47. package/lib/index.d.ts +1 -0
  48. package/lib/index.js +5 -1
  49. package/lib/middlewares/body.js +33 -0
  50. package/lib/middlewares/compression.js +1 -1
  51. package/lib/middlewares/cors.js +3 -2
  52. package/lib/middlewares/errors.js +24 -119
  53. package/lib/middlewares/favicon.js +3 -3
  54. package/lib/middlewares/index.d.ts +2 -1
  55. package/lib/middlewares/index.js +4 -2
  56. package/lib/middlewares/ip.js +1 -1
  57. package/lib/middlewares/logger.js +1 -1
  58. package/lib/middlewares/powered-by.js +4 -2
  59. package/lib/middlewares/public/index.js +4 -7
  60. package/lib/middlewares/query.js +46 -0
  61. package/lib/middlewares/responses.js +2 -2
  62. package/lib/middlewares/security.js +29 -3
  63. package/lib/middlewares/session/index.js +1 -1
  64. package/lib/services/auth/index.js +1 -6
  65. package/lib/services/entity-service/attributes/index.js +31 -0
  66. package/lib/services/entity-service/attributes/transforms.js +20 -0
  67. package/lib/services/entity-service/components.js +2 -3
  68. package/lib/services/entity-service/index.d.ts +1 -1
  69. package/lib/services/entity-service/index.js +83 -27
  70. package/lib/services/entity-service/params.js +37 -87
  71. package/lib/services/entity-validator/index.js +76 -43
  72. package/lib/services/entity-validator/validators.js +129 -43
  73. package/lib/services/errors.js +77 -0
  74. package/lib/services/metrics/index.js +37 -35
  75. package/lib/services/server/compose-endpoint.js +39 -11
  76. package/lib/services/server/content-api.js +1 -1
  77. package/lib/services/server/index.js +4 -9
  78. package/lib/services/server/koa.js +64 -0
  79. package/lib/services/server/middleware.js +8 -1
  80. package/lib/services/server/policy.js +8 -10
  81. package/lib/services/server/register-middlewares.js +7 -2
  82. package/lib/services/server/register-routes.js +1 -3
  83. package/lib/services/server/routing.js +13 -0
  84. package/lib/utils/get-dirs.js +1 -0
  85. package/lib/utils/signals.js +24 -0
  86. package/package.json +22 -17
  87. package/lib/core/app-configuration/load-functions.js +0 -28
  88. package/lib/core-api/index.js +0 -39
  89. package/lib/middlewares/request.js +0 -74
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,7 +79,7 @@ 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:**
@@ -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
@@ -127,7 +127,7 @@ program
127
127
 
128
128
  // `$ strapi generate:template <directory>`
129
129
  program
130
- .command('generate:template <directory>')
130
+ .command('templates:generate <directory>')
131
131
  .description('Generate template from Strapi project')
132
132
  .action(getLocalScript('generate-template'));
133
133
 
@@ -208,4 +208,9 @@ program
208
208
  .description('List all the application hooks')
209
209
  .action(getLocalScript('hooks/list'));
210
210
 
211
+ program
212
+ .command('services:list')
213
+ .description('List all the application services')
214
+ .action(getLocalScript('services/list'));
215
+
211
216
  program.parseAsync(process.argv);
package/lib/Strapi.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const _ = require('lodash');
4
+ const { isFunction } = require('lodash/fp');
4
5
  const { createLogger } = require('@strapi/logger');
5
6
  const { Database } = require('@strapi/database');
6
7
  const { createAsyncParallelHook } = require('@strapi/utils').hooks;
@@ -35,6 +36,7 @@ const createConfigProvider = require('./core/registries/config');
35
36
  const apisRegistry = require('./core/registries/apis');
36
37
  const bootstrap = require('./core/bootstrap');
37
38
  const loaders = require('./core/loaders');
39
+ const { destroyOnSignal } = require('./utils/signals');
38
40
 
39
41
  // TODO: move somewhere else
40
42
  const draftAndPublishSync = require('./migrations/draft-publish');
@@ -42,10 +44,12 @@ const draftAndPublishSync = require('./migrations/draft-publish');
42
44
  const LIFECYCLES = {
43
45
  REGISTER: 'register',
44
46
  BOOTSTRAP: 'bootstrap',
47
+ DESTROY: 'destroy',
45
48
  };
46
49
 
47
50
  class Strapi {
48
51
  constructor(opts = {}) {
52
+ destroyOnSignal(this);
49
53
  this.dirs = utils.getDirs(opts.dir || process.cwd());
50
54
  const appConfig = loadConfiguration(this.dirs.root, opts);
51
55
  this.container = createContainer(this);
@@ -70,6 +74,7 @@ class Strapi {
70
74
  this.startupLogger = createStartupLogger(this);
71
75
  this.log = createLogger(this.config.get('logger', {}));
72
76
  this.cron = createCronService();
77
+ this.telemetry = createTelemetry(this);
73
78
 
74
79
  createUpdateNotifier(this).notify();
75
80
  }
@@ -167,17 +172,7 @@ class Strapi {
167
172
  async destroy() {
168
173
  await this.server.destroy();
169
174
 
170
- await Promise.all(
171
- Object.values(this.plugins).map(plugin => {
172
- if (_.has(plugin, 'destroy') && typeof plugin.destroy === 'function') {
173
- return plugin.destroy();
174
- }
175
- })
176
- );
177
-
178
- if (_.has(this, 'admin')) {
179
- await this.admin.destroy();
180
- }
175
+ await this.runLifecyclesFunctions(LIFECYCLES.DESTROY);
181
176
 
182
177
  this.eventHub.removeAllListeners();
183
178
 
@@ -188,6 +183,8 @@ class Strapi {
188
183
  this.telemetry.destroy();
189
184
  this.cron.destroy();
190
185
 
186
+ process.removeAllListeners();
187
+
191
188
  delete global.strapi;
192
189
  }
193
190
 
@@ -207,7 +204,7 @@ class Strapi {
207
204
  async openAdmin({ isInitialized }) {
208
205
  const shouldOpenAdmin =
209
206
  this.config.get('environment') === 'development' &&
210
- this.config.get('server.admin.autoOpen', true) !== false;
207
+ this.config.get('admin.autoOpen', true) !== false;
211
208
 
212
209
  if (shouldOpenAdmin && !isInitialized) {
213
210
  await utils.openBrowser(this.config);
@@ -264,7 +261,7 @@ class Strapi {
264
261
  }
265
262
 
266
263
  stop(exitCode = 1) {
267
- this.server.destroy();
264
+ this.destroy();
268
265
 
269
266
  if (this.config.get('autoReload')) {
270
267
  process.send('stop');
@@ -310,7 +307,7 @@ class Strapi {
310
307
  this.hook('strapi::content-types.afterSync').register(draftAndPublishSync.enable);
311
308
  }
312
309
 
313
- async load() {
310
+ async register() {
314
311
  await Promise.all([
315
312
  this.loadApp(),
316
313
  this.loadPlugins(),
@@ -332,8 +329,14 @@ class Strapi {
332
329
 
333
330
  this.registerInternalHooks();
334
331
 
332
+ this.telemetry.register();
333
+
335
334
  await this.runLifecyclesFunctions(LIFECYCLES.REGISTER);
336
335
 
336
+ return this;
337
+ }
338
+
339
+ async bootstrap() {
337
340
  const contentTypes = [
338
341
  coreStoreModel,
339
342
  webhookModel,
@@ -360,10 +363,10 @@ class Strapi {
360
363
  const cronTasks = this.config.get('server.cron.tasks', {});
361
364
  this.cron.add(cronTasks);
362
365
 
363
- this.telemetry = createTelemetry(this);
366
+ this.telemetry.bootstrap();
364
367
 
365
368
  let oldContentTypes;
366
- if (await this.db.connection.schema.hasTable(coreStoreModel.collectionName)) {
369
+ if (await this.db.getSchemaConnection().hasTable(coreStoreModel.collectionName)) {
367
370
  oldContentTypes = await this.store.get({
368
371
  type: 'strapi',
369
372
  name: 'content_types',
@@ -399,6 +402,13 @@ class Strapi {
399
402
 
400
403
  this.cron.start();
401
404
 
405
+ return this;
406
+ }
407
+
408
+ async load() {
409
+ await this.register();
410
+ await this.bootstrap();
411
+
402
412
  this.isLoaded = true;
403
413
 
404
414
  return this;
@@ -423,7 +433,6 @@ class Strapi {
423
433
  }
424
434
 
425
435
  if (this.config.get('autoReload')) {
426
- this.server.destroy();
427
436
  process.send('reload');
428
437
  }
429
438
  };
@@ -454,13 +463,16 @@ class Strapi {
454
463
  await this.container.get('modules')[lifecycleName]();
455
464
 
456
465
  // user
457
- const lifecycleFunction = this.app[lifecycleName];
458
- if (lifecycleFunction) {
459
- await lifecycleFunction({ strapi: this });
466
+ const userLifecycleFunction = this.app && this.app[lifecycleName];
467
+ if (isFunction(userLifecycleFunction)) {
468
+ await userLifecycleFunction({ strapi: this });
460
469
  }
461
470
 
462
471
  // admin
463
- await this.admin[lifecycleName]({ strapi: this });
472
+ const adminLifecycleFunction = this.admin && this.admin[lifecycleName];
473
+ if (isFunction(adminLifecycleFunction)) {
474
+ await adminLifecycleFunction({ strapi: this });
475
+ }
464
476
  }
465
477
 
466
478
  getModel(uid) {
@@ -24,7 +24,7 @@ module.exports = async ({ clean, optimization }) => {
24
24
  const plugins = await getEnabledPlugins(strapiInstance);
25
25
 
26
26
  const env = strapiInstance.config.get('environment');
27
- const { serverUrl, adminPath } = getConfigUrls(strapiInstance.config.get('server'), true);
27
+ const { serverUrl, adminPath } = getConfigUrls(strapiInstance.config, true);
28
28
 
29
29
  console.log(`Building your admin UI with ${green(env)} configuration ...`);
30
30
 
@@ -6,17 +6,15 @@ const chalk = require('chalk');
6
6
  const strapi = require('../../index');
7
7
 
8
8
  module.exports = async function() {
9
- const app = await strapi().load();
9
+ const app = await strapi().register();
10
10
 
11
- const list = app.contentTypes;
11
+ const list = app.container.get('content-types').keys();
12
12
 
13
13
  const infoTable = new CLITable({
14
14
  head: [chalk.blue('Name')],
15
15
  });
16
16
 
17
- Object.keys(list).forEach(name => {
18
- infoTable.push([name]);
19
- });
17
+ list.forEach(name => infoTable.push([name]));
20
18
 
21
19
  console.log(infoTable.toString());
22
20
 
@@ -20,8 +20,8 @@ module.exports = async function({ build, watchAdmin, polling, browser }) {
20
20
  const config = loadConfiguration(dir);
21
21
  const logger = createLogger(config.logger, {});
22
22
 
23
- const adminWatchIgnoreFiles = getOr([], 'server.admin.watchIgnoreFiles')(config);
24
- const serveAdminPanel = getOr(true, 'server.admin.serveAdminPanel')(config);
23
+ const adminWatchIgnoreFiles = getOr([], 'admin.watchIgnoreFiles')(config);
24
+ const serveAdminPanel = getOr(true, 'admin.serveAdminPanel')(config);
25
25
 
26
26
  const buildExists = fs.existsSync(path.join(dir, 'build'));
27
27
  // Don't run the build process if the admin is in watch mode
@@ -52,14 +52,12 @@ module.exports = async function({ build, watchAdmin, polling, browser }) {
52
52
  switch (message) {
53
53
  case 'reload':
54
54
  logger.info('The server is restarting\n');
55
- worker.send('isKilled');
55
+ worker.send('kill');
56
56
  break;
57
- case 'kill':
58
- worker.kill();
57
+ case 'killed':
59
58
  cluster.fork();
60
59
  break;
61
60
  case 'stop':
62
- worker.kill();
63
61
  process.exit(1);
64
62
  default:
65
63
  return;
@@ -85,10 +83,10 @@ module.exports = async function({ build, watchAdmin, polling, browser }) {
85
83
 
86
84
  process.on('message', async message => {
87
85
  switch (message) {
88
- case 'isKilled':
89
- await strapiInstance.server.destroy();
90
- process.send('kill');
91
- break;
86
+ case 'kill':
87
+ await strapiInstance.destroy();
88
+ process.send('killed');
89
+ process.exit();
92
90
  default:
93
91
  // Do nothing.
94
92
  }
@@ -6,7 +6,7 @@ const chalk = require('chalk');
6
6
  const inquirer = require('inquirer');
7
7
 
8
8
  // All directories that a template could need
9
- const TEMPLATE_CONTENT = ['api', 'components', 'config/functions/bootstrap.js', 'data'];
9
+ const TEMPLATE_CONTENT = ['src', 'data'];
10
10
 
11
11
  /**
12
12
  *
@@ -54,10 +54,9 @@ async function writeTemplateJson(rootPath) {
54
54
  * @returns boolean
55
55
  */
56
56
  async function templateConfigExists(rootPath) {
57
- const jsonConfig = await fse.pathExists(join(rootPath, 'template.json'));
58
- const functionConfig = await fse.pathExists(join(rootPath, 'template.js'));
59
-
60
- return jsonConfig || functionConfig;
57
+ const configExists = await fse.pathExists(join(rootPath, 'template.json'));
58
+ console.log(`checking: ${join(rootPath, 'template.json')}. result ${configExists}`);
59
+ return configExists;
61
60
  }
62
61
 
63
62
  module.exports = async function generateTemplate(directory) {
@@ -6,17 +6,15 @@ const chalk = require('chalk');
6
6
  const strapi = require('../../index');
7
7
 
8
8
  module.exports = async function() {
9
- const app = await strapi().load();
9
+ const app = await strapi().register();
10
10
 
11
- const list = app.hooks;
11
+ const list = app.container.get('hooks').keys();
12
12
 
13
13
  const infoTable = new CLITable({
14
14
  head: [chalk.blue('Name')],
15
15
  });
16
16
 
17
- Object.keys(list).forEach(name => {
18
- infoTable.push([name]);
19
- });
17
+ list.forEach(name => infoTable.push([name]));
20
18
 
21
19
  console.log(infoTable.toString());
22
20
 
@@ -6,17 +6,15 @@ const chalk = require('chalk');
6
6
  const strapi = require('../../index');
7
7
 
8
8
  module.exports = async function() {
9
- const app = await strapi().load();
9
+ const app = await strapi().register();
10
10
 
11
- const list = app.middlewares;
11
+ const list = app.container.get('middlewares').keys();
12
12
 
13
13
  const infoTable = new CLITable({
14
14
  head: [chalk.blue('Name')],
15
15
  });
16
16
 
17
- Object.keys(list).forEach(name => {
18
- infoTable.push([name]);
19
- });
17
+ list.forEach(name => infoTable.push([name]));
20
18
 
21
19
  console.log(infoTable.toString());
22
20
 
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ const { generateNewApp } = require('@strapi/generate-new');
4
+
3
5
  /**
4
6
  * `$ strapi new`
5
7
  *
@@ -7,5 +9,5 @@
7
9
  */
8
10
 
9
11
  module.exports = function(...args) {
10
- return require('@strapi/generate-new')(...args);
12
+ return generateNewApp(...args);
11
13
  };
@@ -6,17 +6,15 @@ const chalk = require('chalk');
6
6
  const strapi = require('../../index');
7
7
 
8
8
  module.exports = async function() {
9
- const app = await strapi().load();
9
+ const app = await strapi().register();
10
10
 
11
- const list = app.policies;
11
+ const list = app.container.get('policies').keys();
12
12
 
13
13
  const infoTable = new CLITable({
14
14
  head: [chalk.blue('Name')],
15
15
  });
16
16
 
17
- Object.keys(list).forEach(name => {
18
- infoTable.push([name]);
19
- });
17
+ list.forEach(name => infoTable.push([name]));
20
18
 
21
19
  console.log(infoTable.toString());
22
20
 
@@ -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('services').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
+ };
@@ -19,11 +19,11 @@ module.exports = async function({ browser }) {
19
19
 
20
20
  const plugins = await getEnabledPlugins(strapiInstance);
21
21
 
22
- const { adminPath } = getConfigUrls(strapiInstance.config.get('server'), true);
22
+ const { adminPath } = getConfigUrls(strapiInstance.config, true);
23
23
 
24
- const adminPort = strapiInstance.config.get('server.admin.port', 8000);
25
- const adminHost = strapiInstance.config.get('server.admin.host', 'localhost');
26
- const adminWatchIgnoreFiles = strapiInstance.config.get('server.admin.watchIgnoreFiles', []);
24
+ const adminPort = strapiInstance.config.get('admin.port', 8000);
25
+ const adminHost = strapiInstance.config.get('admin.host', 'localhost');
26
+ const adminWatchIgnoreFiles = strapiInstance.config.get('admin.watchIgnoreFiles', []);
27
27
 
28
28
  const backendURL = getAbsoluteServerUrl(strapiInstance.config, true);
29
29
 
@@ -11,16 +11,9 @@ dotenv.config({ path: process.env.ENV_PATH });
11
11
  process.env.NODE_ENV = process.env.NODE_ENV || 'development';
12
12
 
13
13
  const loadConfigDir = require('./config-loader');
14
- const loadFunction = require('./load-functions');
15
14
 
16
15
  const { version: strapiVersion } = require(path.join(__dirname, '../../../package.json'));
17
16
 
18
- const CONFIG_PATHS = {
19
- config: 'config',
20
- static: 'public',
21
- views: 'views',
22
- };
23
-
24
17
  const defaultConfig = {
25
18
  server: {
26
19
  host: process.env.HOST || os.hostname() || 'localhost',
@@ -30,6 +23,11 @@ const defaultConfig = {
30
23
  admin: { autoOpen: false },
31
24
  },
32
25
  admin: {},
26
+ api: {
27
+ rest: {
28
+ prefix: '/api',
29
+ },
30
+ },
33
31
  };
34
32
 
35
33
  module.exports = (dir, initialConfig = {}) => {
@@ -41,8 +39,6 @@ module.exports = (dir, initialConfig = {}) => {
41
39
 
42
40
  const rootConfig = {
43
41
  launchedAt: Date.now(),
44
- appPath: dir,
45
- paths: CONFIG_PATHS,
46
42
  serveAdminPanel,
47
43
  autoReload,
48
44
  environment: process.env.NODE_ENV,
@@ -52,7 +48,6 @@ module.exports = (dir, initialConfig = {}) => {
52
48
  ...pkgJSON,
53
49
  strapi: strapiVersion,
54
50
  },
55
- functions: loadFunction(path.join(configDir, 'functions')),
56
51
  };
57
52
 
58
53
  const baseConfig = omit('plugins', loadConfigDir(configDir)); // plugin config will be loaded later
@@ -6,7 +6,7 @@ module.exports = function({ strapi }) {
6
6
  strapi.config.port = strapi.config.get('server.port') || strapi.config.port;
7
7
  strapi.config.host = strapi.config.get('server.host') || strapi.config.host;
8
8
 
9
- const { serverUrl, adminUrl, adminPath } = getConfigUrls(strapi.config.get('server'));
9
+ const { serverUrl, adminUrl, adminPath } = getConfigUrls(strapi.config);
10
10
 
11
11
  strapi.config.server = strapi.config.server || {};
12
12
  strapi.config.server.url = serverUrl;
@@ -15,7 +15,7 @@ module.exports = function({ strapi }) {
15
15
 
16
16
  // check if we should serve admin panel
17
17
  const shouldServeAdmin = strapi.config.get(
18
- 'server.admin.serveAdminPanel',
18
+ 'admin.serveAdminPanel',
19
19
  strapi.config.get('serveAdminPanel')
20
20
  );
21
21
 
@@ -61,7 +61,9 @@ const createModule = (namespace, rawModule, strapi) => {
61
61
  strapi.container.get('controllers').add(namespace, rawModule.controllers);
62
62
  strapi.container.get('config').set(uidToPath(namespace), rawModule.config);
63
63
  },
64
- routes: rawModule.routes,
64
+ get routes() {
65
+ return rawModule.routes;
66
+ },
65
67
  config(path, defaultValue) {
66
68
  return strapi.container.get('config').get(`${uidToPath(namespace)}.${path}`, defaultValue);
67
69
  },
@@ -1,6 +1,5 @@
1
1
  'use strict';
2
2
 
3
- const _ = require('lodash');
4
3
  const { yup } = require('@strapi/utils');
5
4
 
6
5
  const strapiServerSchema = yup
@@ -14,9 +13,7 @@ const strapiServerSchema = yup
14
13
  if (Array.isArray(value)) {
15
14
  return yup.array();
16
15
  } else {
17
- const shape = _.mapValues(value, () => yup.object({ routes: yup.array().required() }));
18
-
19
- return yup.object(shape);
16
+ return yup.object();
20
17
  }
21
18
  }),
22
19
  controllers: yup.object(),
@@ -11,6 +11,6 @@ module.exports = strapi => {
11
11
  strapi.container.get('policies').add(`admin::`, strapi.admin.policies);
12
12
  strapi.container.get('middlewares').add(`admin::`, strapi.admin.middlewares);
13
13
 
14
- const userAdminConfig = strapi.config.get('server.admin');
15
- strapi.container.get('config').set('server.admin', _.merge(strapi.admin.config, userAdminConfig));
14
+ const userAdminConfig = strapi.config.get('admin');
15
+ strapi.container.get('config').set('admin', _.merge(strapi.admin.config, userAdminConfig));
16
16
  };
@@ -4,8 +4,10 @@ const { join, extname, basename } = require('path');
4
4
  const { existsSync } = require('fs-extra');
5
5
  const _ = require('lodash');
6
6
  const fse = require('fs-extra');
7
+ const { isKebabCase } = require('@strapi/utils');
7
8
 
8
- const normalizeName = _.kebabCase;
9
+ // to handle names with numbers in it we first check if it is already in kebabCase
10
+ const normalizeName = name => (isKebabCase(name) ? name : _.kebabCase(name));
9
11
 
10
12
  const DEFAULT_CONTENT_TYPE = {
11
13
  schema: {},
@@ -51,10 +51,10 @@ const getEnabledPlugins = async strapi => {
51
51
  const packageInfo = require(packagePath);
52
52
 
53
53
  validatePluginName(packageInfo.strapi.name);
54
- internalPlugins[packageInfo.strapi.name] = toDetailedDeclaration({
55
- enabled: true,
56
- resolve: packagePath,
57
- });
54
+ internalPlugins[packageInfo.strapi.name] = {
55
+ ...toDetailedDeclaration({ enabled: true, resolve: packagePath }),
56
+ info: packageInfo.strapi,
57
+ };
58
58
  }
59
59
 
60
60
  const installedPlugins = {};
@@ -64,10 +64,10 @@ const getEnabledPlugins = async strapi => {
64
64
 
65
65
  if (isStrapiPlugin(packageInfo)) {
66
66
  validatePluginName(packageInfo.strapi.name);
67
- installedPlugins[packageInfo.strapi.name] = toDetailedDeclaration({
68
- enabled: true,
69
- resolve: packagePath,
70
- });
67
+ installedPlugins[packageInfo.strapi.name] = {
68
+ ...toDetailedDeclaration({ enabled: true, resolve: packagePath }),
69
+ info: packageInfo.strapi,
70
+ };
71
71
  }
72
72
  }
73
73
 
@@ -79,7 +79,23 @@ const getEnabledPlugins = async strapi => {
79
79
 
80
80
  _.forEach(userPluginsConfig, (declaration, pluginName) => {
81
81
  validatePluginName(pluginName);
82
- declaredPlugins[pluginName] = toDetailedDeclaration(declaration);
82
+
83
+ declaredPlugins[pluginName] = {
84
+ ...toDetailedDeclaration(declaration),
85
+ info: {},
86
+ };
87
+
88
+ const { pathToPlugin } = declaredPlugins[pluginName];
89
+
90
+ // for manually resolved plugins
91
+ if (pathToPlugin) {
92
+ const packagePath = join(pathToPlugin, 'package.json');
93
+ const packageInfo = require(packagePath);
94
+
95
+ if (isStrapiPlugin(packageInfo)) {
96
+ declaredPlugins[pluginName].info = packageInfo.strapi || {};
97
+ }
98
+ }
83
99
  });
84
100
 
85
101
  const declaredPluginsResolves = map(prop('pathToPlugin'), declaredPlugins);