@strapi/strapi 4.0.0-next.9 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/README.md +12 -12
  2. package/bin/strapi.js +32 -5
  3. package/lib/Strapi.js +140 -72
  4. package/lib/commands/build.js +16 -6
  5. package/lib/commands/console.js +1 -1
  6. package/lib/commands/content-types/list.js +22 -0
  7. package/lib/commands/develop.js +14 -15
  8. package/lib/commands/generate-template.js +4 -5
  9. package/lib/commands/hooks/list.js +22 -0
  10. package/lib/commands/middlewares/list.js +22 -0
  11. package/lib/commands/new.js +3 -1
  12. package/lib/commands/policies/list.js +22 -0
  13. package/lib/commands/routes/list.js +28 -0
  14. package/lib/commands/services/list.js +22 -0
  15. package/lib/commands/watchAdmin.js +18 -9
  16. package/lib/core/app-configuration/index.js +3 -19
  17. package/lib/core/bootstrap.js +3 -34
  18. package/lib/core/domain/content-type/index.js +3 -7
  19. package/lib/core/domain/module/index.js +8 -6
  20. package/lib/core/domain/module/validation.js +1 -4
  21. package/lib/core/loaders/admin.js +2 -2
  22. package/lib/core/loaders/apis.js +7 -7
  23. package/lib/core/loaders/components.js +3 -5
  24. package/lib/core/loaders/index.js +1 -0
  25. package/lib/core/loaders/middlewares.js +23 -123
  26. package/lib/core/loaders/plugins/get-enabled-plugins.js +48 -14
  27. package/lib/core/loaders/plugins/index.js +30 -14
  28. package/lib/core/loaders/policies.js +1 -1
  29. package/lib/core/loaders/src-index.js +39 -0
  30. package/lib/core/registries/apis.js +2 -16
  31. package/lib/core/registries/content-types.js +50 -6
  32. package/lib/core/registries/controllers.d.ts +7 -0
  33. package/lib/core/registries/controllers.js +74 -3
  34. package/lib/core/registries/hooks.d.ts +20 -0
  35. package/lib/core/registries/hooks.js +87 -0
  36. package/lib/core/registries/middlewares.d.ts +5 -0
  37. package/lib/core/registries/middlewares.js +61 -2
  38. package/lib/core/registries/modules.js +3 -3
  39. package/lib/core/registries/plugins.js +2 -2
  40. package/lib/core/registries/policies.d.ts +9 -0
  41. package/lib/core/registries/policies.js +57 -6
  42. package/lib/core/registries/services.d.ts +7 -0
  43. package/lib/core/registries/services.js +71 -15
  44. package/lib/core-api/controller/collection-type.js +38 -11
  45. package/lib/core-api/controller/index.d.ts +25 -0
  46. package/lib/core-api/controller/index.js +30 -11
  47. package/lib/core-api/controller/single-type.js +26 -7
  48. package/lib/core-api/controller/transform.js +28 -3
  49. package/lib/core-api/routes/index.js +71 -0
  50. package/lib/core-api/service/collection-type.js +22 -27
  51. package/lib/core-api/service/index.d.ts +21 -0
  52. package/lib/core-api/service/index.js +9 -19
  53. package/lib/core-api/service/pagination.js +7 -2
  54. package/lib/core-api/service/single-type.js +17 -20
  55. package/lib/factories.d.ts +48 -0
  56. package/lib/factories.js +84 -0
  57. package/lib/index.d.ts +10 -31
  58. package/lib/index.js +5 -1
  59. package/lib/middlewares/body.js +33 -0
  60. package/lib/middlewares/compression.js +8 -0
  61. package/lib/middlewares/cors.js +58 -0
  62. package/lib/middlewares/errors.js +40 -0
  63. package/lib/middlewares/favicon.js +19 -0
  64. package/lib/middlewares/index.d.ts +5 -0
  65. package/lib/middlewares/index.js +30 -116
  66. package/lib/middlewares/ip.js +8 -0
  67. package/lib/middlewares/logger.js +27 -0
  68. package/lib/middlewares/powered-by.js +20 -0
  69. package/lib/middlewares/public/index.js +98 -73
  70. package/lib/middlewares/query.js +46 -0
  71. package/lib/middlewares/response-time.js +15 -0
  72. package/lib/middlewares/responses.js +19 -0
  73. package/lib/middlewares/security.js +51 -0
  74. package/lib/middlewares/session/index.js +6 -6
  75. package/lib/migrations/draft-publish.js +57 -0
  76. package/lib/services/auth/index.js +87 -0
  77. package/lib/services/core-store.js +64 -49
  78. package/lib/services/cron.js +54 -0
  79. package/lib/services/entity-service/attributes/index.js +31 -0
  80. package/lib/services/entity-service/attributes/transforms.js +20 -0
  81. package/lib/services/entity-service/components.js +39 -15
  82. package/lib/services/entity-service/index.d.ts +91 -0
  83. package/lib/services/entity-service/index.js +118 -60
  84. package/lib/services/entity-service/params.js +48 -81
  85. package/lib/services/entity-validator/index.js +76 -43
  86. package/lib/services/entity-validator/validators.js +129 -43
  87. package/lib/services/errors.js +77 -0
  88. package/lib/services/fs.js +1 -1
  89. package/lib/services/metrics/index.js +38 -36
  90. package/lib/services/server/admin-api.js +14 -0
  91. package/lib/services/server/api.js +36 -0
  92. package/lib/services/server/compose-endpoint.js +141 -0
  93. package/lib/services/server/content-api.js +16 -0
  94. package/lib/{server.js → services/server/http-server.js} +0 -0
  95. package/lib/services/server/index.js +127 -0
  96. package/lib/services/server/koa.js +64 -0
  97. package/lib/services/server/middleware.js +122 -0
  98. package/lib/services/server/policy.js +32 -0
  99. package/lib/services/server/register-middlewares.js +110 -0
  100. package/lib/services/server/register-routes.js +106 -0
  101. package/lib/services/server/routing.js +120 -0
  102. package/lib/services/webhook-runner.js +1 -1
  103. package/lib/utils/ee.js +3 -3
  104. package/lib/utils/get-dirs.js +17 -0
  105. package/lib/utils/index.js +2 -0
  106. package/lib/utils/signals.js +24 -0
  107. package/lib/utils/update-notifier/index.js +2 -1
  108. package/package.json +93 -93
  109. package/lib/core/app-configuration/load-functions.js +0 -28
  110. package/lib/core-api/index.js +0 -39
  111. package/lib/middlewares/boom/defaults.json +0 -5
  112. package/lib/middlewares/boom/index.js +0 -147
  113. package/lib/middlewares/cors/index.js +0 -66
  114. package/lib/middlewares/cron/defaults.json +0 -5
  115. package/lib/middlewares/cron/index.js +0 -43
  116. package/lib/middlewares/favicon/defaults.json +0 -7
  117. package/lib/middlewares/favicon/index.js +0 -32
  118. package/lib/middlewares/gzip/defaults.json +0 -6
  119. package/lib/middlewares/gzip/index.js +0 -19
  120. package/lib/middlewares/helmet/defaults.json +0 -18
  121. package/lib/middlewares/helmet/index.js +0 -9
  122. package/lib/middlewares/ip/defaults.json +0 -7
  123. package/lib/middlewares/ip/index.js +0 -25
  124. package/lib/middlewares/language/defaults.json +0 -9
  125. package/lib/middlewares/language/index.js +0 -40
  126. package/lib/middlewares/logger/defaults.json +0 -5
  127. package/lib/middlewares/logger/index.js +0 -37
  128. package/lib/middlewares/parser/defaults.json +0 -11
  129. package/lib/middlewares/parser/index.js +0 -72
  130. package/lib/middlewares/poweredBy/defaults.json +0 -5
  131. package/lib/middlewares/poweredBy/index.js +0 -16
  132. package/lib/middlewares/public/defaults.json +0 -8
  133. package/lib/middlewares/responseTime/defaults.json +0 -5
  134. package/lib/middlewares/responseTime/index.js +0 -25
  135. package/lib/middlewares/responses/defaults.json +0 -5
  136. package/lib/middlewares/responses/index.js +0 -18
  137. package/lib/middlewares/router/defaults.json +0 -7
  138. package/lib/middlewares/router/index.js +0 -72
  139. package/lib/middlewares/router/utils/compose-endpoint.js +0 -169
  140. package/lib/utils/get-prefixed-dependencies.js +0 -7
@@ -20,15 +20,16 @@ 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
28
28
  if (build && !watchAdmin && serveAdminPanel && !buildExists) {
29
29
  try {
30
- execa.shellSync('npm run -s build -- --no-optimization', {
30
+ execa.sync('npm run -s build -- --no-optimization', {
31
31
  stdio: 'inherit',
32
+ shell: true,
32
33
  });
33
34
  } catch (err) {
34
35
  process.exit(1);
@@ -51,14 +52,12 @@ module.exports = async function({ build, watchAdmin, polling, browser }) {
51
52
  switch (message) {
52
53
  case 'reload':
53
54
  logger.info('The server is restarting\n');
54
- worker.send('isKilled');
55
+ worker.send('kill');
55
56
  break;
56
- case 'kill':
57
- worker.kill();
57
+ case 'killed':
58
58
  cluster.fork();
59
59
  break;
60
60
  case 'stop':
61
- worker.kill();
62
61
  process.exit(1);
63
62
  default:
64
63
  return;
@@ -84,10 +83,10 @@ module.exports = async function({ build, watchAdmin, polling, browser }) {
84
83
 
85
84
  process.on('message', async message => {
86
85
  switch (message) {
87
- case 'isKilled':
88
- await strapiInstance.server.destroy();
89
- process.send('kill');
90
- break;
86
+ case 'kill':
87
+ await strapiInstance.destroy();
88
+ process.send('killed');
89
+ process.exit();
91
90
  default:
92
91
  // Do nothing.
93
92
  }
@@ -122,10 +121,10 @@ function watchFileChanges({ dir, strapiInstance, watchIgnoreFiles, polling }) {
122
121
  ignored: [
123
122
  /(^|[/\\])\../, // dot files
124
123
  /tmp/,
125
- '**/admin',
126
- '**/admin/**',
127
- 'extensions/**/admin',
128
- 'extensions/**/admin/**',
124
+ 'admin',
125
+ 'admin/**',
126
+ 'src/extensions/**/admin',
127
+ 'src/extensions/**/admin/**',
129
128
  '**/documentation',
130
129
  '**/documentation/**',
131
130
  '**/node_modules',
@@ -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) {
@@ -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('hooks').keys();
12
+
13
+ const infoTable = new CLITable({
14
+ head: [chalk.blue('Name')],
15
+ });
16
+
17
+ list.forEach(name => infoTable.push([name]));
18
+
19
+ console.log(infoTable.toString());
20
+
21
+ await app.destroy();
22
+ };
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ const CLITable = require('cli-table3');
4
+ const chalk = require('chalk');
5
+
6
+ const strapi = require('../../index');
7
+
8
+ module.exports = async function() {
9
+ const app = await strapi().register();
10
+
11
+ const list = app.container.get('middlewares').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
+ };
@@ -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
  };
@@ -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('policies').keys();
12
+
13
+ const infoTable = new CLITable({
14
+ head: [chalk.blue('Name')],
15
+ });
16
+
17
+ list.forEach(name => infoTable.push([name]));
18
+
19
+ console.log(infoTable.toString());
20
+
21
+ await app.destroy();
22
+ };
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ const CLITable = require('cli-table3');
4
+ const chalk = require('chalk');
5
+ const { toUpper } = require('lodash/fp');
6
+
7
+ const strapi = require('../../index');
8
+
9
+ module.exports = async function() {
10
+ const app = await strapi().load();
11
+
12
+ const list = app.server.listRoutes();
13
+
14
+ const infoTable = new CLITable({
15
+ head: [chalk.blue('Method'), chalk.blue('Path')],
16
+ colWidths: [20],
17
+ });
18
+
19
+ list
20
+ .filter(route => route.methods.length)
21
+ .forEach(route => {
22
+ infoTable.push([route.methods.map(toUpper).join('|'), route.path]);
23
+ });
24
+
25
+ console.log(infoTable.toString());
26
+
27
+ await app.destroy();
28
+ };
@@ -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
+ };
@@ -1,33 +1,42 @@
1
1
  'use strict';
2
2
 
3
- // eslint-disable-next-line node/no-extraneous-require
4
3
  const strapiAdmin = require('@strapi/admin');
5
- const { getOr } = require('lodash/fp');
6
4
  const { getConfigUrls, getAbsoluteServerUrl } = require('@strapi/utils');
7
- const loadConfiguration = require('../core/app-configuration');
5
+
8
6
  const ee = require('../utils/ee');
9
7
  const addSlash = require('../utils/addSlash');
8
+ const strapi = require('../index');
9
+ const getEnabledPlugins = require('../core/loaders/plugins/get-enabled-plugins');
10
10
 
11
11
  module.exports = async function({ browser }) {
12
12
  const dir = process.cwd();
13
13
 
14
- const config = loadConfiguration(dir);
14
+ const strapiInstance = strapi({
15
+ dir,
16
+ autoReload: true,
17
+ serveAdminPanel: false,
18
+ });
19
+
20
+ const plugins = await getEnabledPlugins(strapiInstance);
21
+
22
+ const { adminPath } = getConfigUrls(strapiInstance.config, true);
15
23
 
16
- const { adminPath } = getConfigUrls(config.server, true);
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', []);
17
27
 
18
- const adminPort = getOr(8000, 'server.admin.port')(config);
19
- const adminHost = getOr('localhost', 'server.admin.host')(config);
20
- const adminWatchIgnoreFiles = getOr([], 'server.admin.watchIgnoreFiles')(config);
28
+ const backendURL = getAbsoluteServerUrl(strapiInstance.config, true);
21
29
 
22
30
  ee({ dir });
23
31
 
24
32
  strapiAdmin.watchAdmin({
25
33
  dir,
34
+ plugins,
26
35
  port: adminPort,
27
36
  host: adminHost,
28
37
  browser,
29
38
  options: {
30
- backend: getAbsoluteServerUrl(config, true),
39
+ backend: backendURL,
31
40
  adminPath: addSlash(adminPath),
32
41
  watchIgnoreFiles: adminWatchIgnoreFiles,
33
42
  features: ee.isEE ? ee.features.getEnabled() : [],
@@ -10,18 +10,10 @@ dotenv.config({ path: process.env.ENV_PATH });
10
10
 
11
11
  process.env.NODE_ENV = process.env.NODE_ENV || 'development';
12
12
 
13
- const getPrefixedDeps = require('../../utils/get-prefixed-dependencies');
14
13
  const loadConfigDir = require('./config-loader');
15
- const loadFunction = require('./load-functions');
16
14
 
17
15
  const { version: strapiVersion } = require(path.join(__dirname, '../../../package.json'));
18
16
 
19
- const CONFIG_PATHS = {
20
- config: 'config',
21
- static: 'public',
22
- views: 'views',
23
- };
24
-
25
17
  const defaultConfig = {
26
18
  server: {
27
19
  host: process.env.HOST || os.hostname() || 'localhost',
@@ -31,14 +23,10 @@ const defaultConfig = {
31
23
  admin: { autoOpen: false },
32
24
  },
33
25
  admin: {},
34
- middleware: {
35
- timeout: 1000,
36
- load: {
37
- before: ['responseTime', 'logger', 'cors', 'responses', 'gzip'],
38
- order: [],
39
- after: ['parser', 'router'],
26
+ api: {
27
+ rest: {
28
+ prefix: '/api',
40
29
  },
41
- settings: {},
42
30
  },
43
31
  };
44
32
 
@@ -51,8 +39,6 @@ module.exports = (dir, initialConfig = {}) => {
51
39
 
52
40
  const rootConfig = {
53
41
  launchedAt: Date.now(),
54
- appPath: dir,
55
- paths: CONFIG_PATHS,
56
42
  serveAdminPanel,
57
43
  autoReload,
58
44
  environment: process.env.NODE_ENV,
@@ -62,8 +48,6 @@ module.exports = (dir, initialConfig = {}) => {
62
48
  ...pkgJSON,
63
49
  strapi: strapiVersion,
64
50
  },
65
- functions: loadFunction(path.join(configDir, 'functions')),
66
- installedMiddlewares: getPrefixedDeps('@strapi/middleware', pkgJSON),
67
51
  };
68
52
 
69
53
  const baseConfig = omit('plugins', loadConfigDir(configDir)); // plugin config will be loaded later
@@ -1,43 +1,12 @@
1
1
  'use strict';
2
2
 
3
- const _ = require('lodash');
4
3
  const { getConfigUrls } = require('@strapi/utils');
5
4
 
6
- module.exports = function(strapi) {
7
- // TODO: delete v3 code
8
- _.forEach(strapi.api, api => {
9
- _.forEach(api.middlewares, (middleware, middlewareName) => {
10
- strapi.middleware[middlewareName] = middleware;
11
- });
12
- });
13
-
14
- _.forEach(strapi.plugins, plugin => {
15
- _.forEach(plugin.middlewares, (middleware, middlewareName) => {
16
- strapi.middleware[middlewareName] = middleware;
17
- });
18
- });
19
-
20
- // Preset config in alphabetical order.
21
- strapi.config.middleware.settings = Object.keys(strapi.middleware).reduce((acc, current) => {
22
- // Try to find the settings in the current environment, then in the main configurations.
23
- const currentSettings = _.merge(
24
- _.cloneDeep(_.get(strapi.middleware[current], ['defaults', current], {})),
25
- strapi.config.get(['middleware', 'settings', current], {})
26
- );
27
-
28
- acc[current] = !_.isObject(currentSettings) ? {} : currentSettings;
29
-
30
- // Ensure that enabled key exist by forcing to false.
31
- _.defaults(acc[current], { enabled: false });
32
-
33
- return acc;
34
- }, {});
35
-
36
- // default settings
5
+ module.exports = function({ strapi }) {
37
6
  strapi.config.port = strapi.config.get('server.port') || strapi.config.port;
38
7
  strapi.config.host = strapi.config.get('server.host') || strapi.config.host;
39
8
 
40
- const { serverUrl, adminUrl, adminPath } = getConfigUrls(strapi.config.get('server'));
9
+ const { serverUrl, adminUrl, adminPath } = getConfigUrls(strapi.config);
41
10
 
42
11
  strapi.config.server = strapi.config.server || {};
43
12
  strapi.config.server.url = serverUrl;
@@ -46,7 +15,7 @@ module.exports = function(strapi) {
46
15
 
47
16
  // check if we should serve admin panel
48
17
  const shouldServeAdmin = strapi.config.get(
49
- 'server.admin.serveAdminPanel',
18
+ 'admin.serveAdminPanel',
50
19
  strapi.config.get('serveAdminPanel')
51
20
  );
52
21
 
@@ -68,12 +68,10 @@ const createContentType = (uid, definition) => {
68
68
  Object.assign(schema.attributes, {
69
69
  [CREATED_AT_ATTRIBUTE]: {
70
70
  type: 'datetime',
71
- default: () => new Date(),
72
71
  },
73
72
  // TODO: handle on edit set to new date
74
73
  [UPDATED_AT_ATTRIBUTE]: {
75
74
  type: 'datetime',
76
- default: () => new Date(),
77
75
  },
78
76
  });
79
77
 
@@ -110,11 +108,9 @@ const createContentType = (uid, definition) => {
110
108
  private: isPrivate,
111
109
  };
112
110
 
113
- return {
114
- ...schema,
115
- actions: actions,
116
- lifecycles: lifecycles,
117
- };
111
+ Object.assign(schema, { actions, lifecycles });
112
+
113
+ return schema;
118
114
  };
119
115
 
120
116
  const getGlobalId = (model, modelName, prefix) => {
@@ -37,21 +37,21 @@ const createModule = (namespace, rawModule, strapi) => {
37
37
  throw new Error(`Bootstrap for ${namespace} has already been called`);
38
38
  }
39
39
  called.bootstrap = true;
40
- await (rawModule.bootstrap && rawModule.bootstrap(strapi));
40
+ await (rawModule.bootstrap && rawModule.bootstrap({ strapi }));
41
41
  },
42
42
  async register() {
43
43
  if (called.register) {
44
44
  throw new Error(`Register for ${namespace} has already been called`);
45
45
  }
46
46
  called.register = true;
47
- await (rawModule.register && rawModule.register(strapi));
47
+ await (rawModule.register && rawModule.register({ strapi }));
48
48
  },
49
49
  async destroy() {
50
50
  if (called.destroy) {
51
51
  throw new Error(`Destroy for ${namespace} has already been called`);
52
52
  }
53
53
  called.destroy = true;
54
- await (rawModule.destroy && rawModule.destroy(strapi));
54
+ await (rawModule.destroy && rawModule.destroy({ strapi }));
55
55
  },
56
56
  load() {
57
57
  strapi.container.get('content-types').add(namespace, rawModule.contentTypes);
@@ -61,9 +61,11 @@ 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,
65
- config(path) {
66
- return strapi.container.get('config').get(`${uidToPath(namespace)}.${path}`);
64
+ get routes() {
65
+ return rawModule.routes;
66
+ },
67
+ config(path, defaultValue) {
68
+ return strapi.container.get('config').get(`${uidToPath(namespace)}.${path}`, defaultValue);
67
69
  },
68
70
  contentType(ctName) {
69
71
  return strapi.container.get('content-types').get(`${namespace}.${ctName}`);
@@ -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: {},
@@ -14,20 +16,18 @@ const DEFAULT_CONTENT_TYPE = {
14
16
  };
15
17
 
16
18
  module.exports = async strapi => {
17
- const apisDir = join(strapi.dir, 'api');
18
-
19
- if (!existsSync(apisDir)) {
20
- throw new Error(`Missing api folder. Please create one in your app root directory`);
19
+ if (!existsSync(strapi.dirs.api)) {
20
+ throw new Error('Missing api folder. Please create one at `./src/api`');
21
21
  }
22
22
 
23
- const apisFDs = await fse.readdir(apisDir, { withFileTypes: true });
23
+ const apisFDs = await fse.readdir(strapi.dirs.api, { withFileTypes: true });
24
24
  const apis = {};
25
25
 
26
26
  // only load folders
27
27
  for (const apiFD of apisFDs) {
28
28
  if (apiFD.isDirectory()) {
29
29
  const apiName = normalizeName(apiFD.name);
30
- const api = await loadAPI(join(apisDir, apiFD.name));
30
+ const api = await loadAPI(join(strapi.dirs.api, apiFD.name));
31
31
 
32
32
  apis[apiName] = api;
33
33
  }
@@ -6,19 +6,17 @@ const { pathExists } = require('fs-extra');
6
6
  const loadFiles = require('../../load/load-files');
7
7
 
8
8
  module.exports = async strapi => {
9
- const componentsDir = join(strapi.dir, 'components');
10
-
11
- if (!(await pathExists(componentsDir))) {
9
+ if (!(await pathExists(strapi.dirs.components))) {
12
10
  return {};
13
11
  }
14
12
 
15
- const map = await loadFiles(componentsDir, '*/*.*(js|json)');
13
+ const map = await loadFiles(strapi.dirs.components, '*/*.*(js|json)');
16
14
 
17
15
  return Object.keys(map).reduce((acc, category) => {
18
16
  Object.keys(map[category]).forEach(key => {
19
17
  const schema = map[category][key];
20
18
 
21
- const filePath = join(componentsDir, category, schema.__filename__);
19
+ const filePath = join(strapi.dirs.components, category, schema.__filename__);
22
20
 
23
21
  if (!schema.collectionName) {
24
22
  return strapi.stopWithError(
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  module.exports = {
4
+ loadSrcIndex: require('./src-index'),
4
5
  loadAPIs: require('./apis'),
5
6
  loadMiddlewares: require('./middlewares'),
6
7
  loadComponents: require('./components'),