@strapi/strapi 4.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -84,8 +84,8 @@ Complete installation requirements can be found in the documentation under <a hr
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
 
package/bin/strapi.js CHANGED
@@ -213,4 +213,9 @@ program
213
213
  .description('List all the application services')
214
214
  .action(getLocalScript('services/list'));
215
215
 
216
+ program
217
+ .command('controllers:list')
218
+ .description('List all the application controllers')
219
+ .action(getLocalScript('controllers/list'));
220
+
216
221
  program.parseAsync(process.argv);
@@ -12,7 +12,7 @@ const getEnabledPlugins = require('../core/loaders/plugins/get-enabled-plugins')
12
12
  /**
13
13
  * `$ strapi build`
14
14
  */
15
- module.exports = async ({ clean, optimization }) => {
15
+ module.exports = async ({ clean, optimization, forceBuild = true }) => {
16
16
  const dir = process.cwd();
17
17
 
18
18
  const strapiInstance = strapi({
@@ -36,6 +36,7 @@ module.exports = async ({ clean, optimization }) => {
36
36
 
37
37
  return strapiAdmin
38
38
  .build({
39
+ forceBuild,
39
40
  dir,
40
41
  plugins,
41
42
  // front end build env is always production for now
@@ -47,7 +48,7 @@ module.exports = async ({ clean, optimization }) => {
47
48
  },
48
49
  })
49
50
  .then(() => {
50
- process.exit();
51
+ console.log('Admin UI built successfully');
51
52
  })
52
53
  .catch(err => {
53
54
  console.error(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('controllers').keys();
12
+
13
+ const infoTable = new CLITable({
14
+ head: [chalk.blue('Name')],
15
+ });
16
+
17
+ list.forEach(name => infoTable.push([name]));
18
+
19
+ console.log(infoTable.toString());
20
+
21
+ await app.destroy();
22
+ };
@@ -10,6 +10,7 @@ const { getOr } = require('lodash/fp');
10
10
  const { createLogger } = require('@strapi/logger');
11
11
  const loadConfiguration = require('../core/app-configuration');
12
12
  const strapi = require('../index');
13
+ const buildAdmin = require('./build');
13
14
 
14
15
  /**
15
16
  * `$ strapi develop`
@@ -20,24 +21,20 @@ module.exports = async function({ build, watchAdmin, polling, browser }) {
20
21
  const config = loadConfiguration(dir);
21
22
  const logger = createLogger(config.logger, {});
22
23
 
23
- const adminWatchIgnoreFiles = getOr([], 'admin.watchIgnoreFiles')(config);
24
- const serveAdminPanel = getOr(true, 'admin.serveAdminPanel')(config);
25
-
26
- const buildExists = fs.existsSync(path.join(dir, 'build'));
27
- // Don't run the build process if the admin is in watch mode
28
- if (build && !watchAdmin && serveAdminPanel && !buildExists) {
29
- try {
30
- execa.sync('npm run -s build -- --no-optimization', {
31
- stdio: 'inherit',
32
- shell: true,
33
- });
34
- } catch (err) {
35
- process.exit(1);
36
- }
37
- }
38
-
39
24
  try {
40
25
  if (cluster.isMaster) {
26
+ const serveAdminPanel = getOr(true, 'admin.serveAdminPanel')(config);
27
+
28
+ const buildExists = fs.existsSync(path.join(dir, 'build'));
29
+ // Don't run the build process if the admin is in watch mode
30
+ if (build && !watchAdmin && serveAdminPanel && !buildExists) {
31
+ try {
32
+ await buildAdmin({ clean: false, optimization: false, forceBuild: false });
33
+ } catch (err) {
34
+ process.exit(1);
35
+ }
36
+ }
37
+
41
38
  if (watchAdmin) {
42
39
  try {
43
40
  execa('npm', ['run', '-s', 'strapi', 'watch-admin', '--', '--browser', browser], {
@@ -74,6 +71,7 @@ module.exports = async function({ build, watchAdmin, polling, browser }) {
74
71
  serveAdminPanel: watchAdmin ? false : true,
75
72
  });
76
73
 
74
+ const adminWatchIgnoreFiles = getOr([], 'admin.watchIgnoreFiles')(config);
77
75
  watchFileChanges({
78
76
  dir,
79
77
  strapiInstance,
@@ -121,10 +119,8 @@ function watchFileChanges({ dir, strapiInstance, watchIgnoreFiles, polling }) {
121
119
  ignored: [
122
120
  /(^|[/\\])\../, // dot files
123
121
  /tmp/,
124
- 'admin',
125
- 'admin/**',
126
- 'src/extensions/**/admin',
127
- 'src/extensions/**/admin/**',
122
+ '**/src/admin/**',
123
+ '**/src/plugins/**/admin/',
128
124
  '**/documentation',
129
125
  '**/documentation/**',
130
126
  '**/node_modules',
@@ -5,7 +5,7 @@ const { statSync, existsSync } = require('fs');
5
5
  const _ = require('lodash');
6
6
  const { get, has, pick, pickBy, defaultsDeep, map, prop, pipe } = require('lodash/fp');
7
7
  const { isKebabCase } = require('@strapi/utils');
8
- const loadConfigFile = require('../../app-configuration/load-config-file');
8
+ const getUserPluginsConfig = require('./get-user-plugins-config');
9
9
 
10
10
  const isStrapiPlugin = info => get('strapi.kind', info) === 'plugin';
11
11
  const INTERNAL_PLUGINS = [
@@ -60,7 +60,12 @@ const getEnabledPlugins = async strapi => {
60
60
  const installedPlugins = {};
61
61
  for (const dep in strapi.config.get('info.dependencies', {})) {
62
62
  const packagePath = join(dep, 'package.json');
63
- const packageInfo = require(packagePath);
63
+ let packageInfo;
64
+ try {
65
+ packageInfo = require(packagePath);
66
+ } catch {
67
+ continue;
68
+ }
64
69
 
65
70
  if (isStrapiPlugin(packageInfo)) {
66
71
  validatePluginName(packageInfo.strapi.name);
@@ -72,10 +77,7 @@ const getEnabledPlugins = async strapi => {
72
77
  }
73
78
 
74
79
  const declaredPlugins = {};
75
- const userPluginConfigPath = join(strapi.dirs.config, 'plugins.js');
76
- const userPluginsConfig = existsSync(userPluginConfigPath)
77
- ? loadConfigFile(userPluginConfigPath)
78
- : {};
80
+ const userPluginsConfig = await getUserPluginsConfig();
79
81
 
80
82
  _.forEach(userPluginsConfig, (declaration, pluginName) => {
81
83
  validatePluginName(pluginName);
@@ -0,0 +1,37 @@
1
+ 'use strict';
2
+
3
+ const { join } = require('path');
4
+ const fse = require('fs-extra');
5
+ const { merge } = require('lodash/fp');
6
+ const loadConfigFile = require('../../app-configuration/load-config-file');
7
+
8
+ /**
9
+ * Return user defined plugins' config
10
+ * first load config from `config/plugins.js`
11
+ * and then merge config from `config/env/{env}/plugins.js`
12
+ * @return {Promise<{}>}
13
+ */
14
+ const getUserPluginsConfig = async () => {
15
+ const globalUserConfigPath = join(strapi.dirs.config, 'plugins.js');
16
+ const currentEnvUserConfigPath = join(
17
+ strapi.dirs.config,
18
+ 'env',
19
+ process.env.NODE_ENV,
20
+ 'plugins.js'
21
+ );
22
+ let config = {};
23
+
24
+ // assign global user config if exists
25
+ if (await fse.pathExists(globalUserConfigPath)) {
26
+ config = loadConfigFile(globalUserConfigPath);
27
+ }
28
+
29
+ // and merge user config by environment if exists
30
+ if (await fse.pathExists(currentEnvUserConfigPath)) {
31
+ config = merge(config, loadConfigFile(currentEnvUserConfigPath));
32
+ }
33
+
34
+ return config;
35
+ };
36
+
37
+ module.exports = getUserPluginsConfig;
@@ -7,6 +7,7 @@ const { env } = require('@strapi/utils');
7
7
  const loadConfigFile = require('../../app-configuration/load-config-file');
8
8
  const loadFiles = require('../../../load/load-files');
9
9
  const getEnabledPlugins = require('./get-enabled-plugins');
10
+ const getUserPluginsConfig = require('./get-user-plugins-config');
10
11
 
11
12
  const defaultPlugin = {
12
13
  bootstrap() {},
@@ -66,10 +67,7 @@ const formatContentTypes = plugins => {
66
67
  };
67
68
 
68
69
  const applyUserConfig = async plugins => {
69
- const userPluginConfigPath = join(strapi.dirs.config, 'plugins.js');
70
- const userPluginsConfig = (await fse.pathExists(userPluginConfigPath))
71
- ? loadConfigFile(userPluginConfigPath)
72
- : {};
70
+ const userPluginsConfig = await getUserPluginsConfig();
73
71
 
74
72
  for (const pluginName in plugins) {
75
73
  const plugin = plugins[pluginName];
@@ -13,18 +13,13 @@ const getLimitConfigDefaults = () => ({
13
13
  });
14
14
 
15
15
  /**
16
- * if there is max limit set and limit exceeds this number, return configured max limit
16
+ * Should maxLimit be used as the limit or not
17
17
  * @param {number} limit - limit you want to cap
18
18
  * @param {number?} maxLimit - maxlimit used has capping
19
- * @returns {number}
19
+ * @returns {boolean}
20
20
  */
21
- const applyMaxLimit = (limit, maxLimit) => {
22
- if (maxLimit && (limit === -1 || limit > maxLimit)) {
23
- return maxLimit;
24
- }
25
-
26
- return limit;
27
- };
21
+ const shouldApplyMaxLimit = (limit, maxLimit = null, { isPagedPagination = false } = {}) =>
22
+ (!isPagedPagination && limit === -1) || (maxLimit && limit > maxLimit);
28
23
 
29
24
  const shouldCount = params => {
30
25
  if (has('pagination.withCount', params)) {
@@ -81,17 +76,17 @@ const getPaginationInfo = params => {
81
76
 
82
77
  return {
83
78
  page: Math.max(1, toNumber(pagination.page || 1)),
84
- pageSize: applyMaxLimit(pageSize, maxLimit),
79
+ pageSize: shouldApplyMaxLimit(pageSize, maxLimit, { isPagedPagination: true })
80
+ ? maxLimit
81
+ : Math.max(1, pageSize),
85
82
  };
86
83
  }
87
84
 
88
- const limit = isUndefined(pagination.limit)
89
- ? defaultLimit
90
- : Math.max(1, toNumber(pagination.limit));
85
+ const limit = isUndefined(pagination.limit) ? defaultLimit : toNumber(pagination.limit);
91
86
 
92
87
  return {
93
88
  start: Math.max(0, toNumber(pagination.start || 0)),
94
- limit: applyMaxLimit(limit, maxLimit),
89
+ limit: shouldApplyMaxLimit(limit, maxLimit) ? maxLimit || -1 : Math.max(1, limit),
95
90
  };
96
91
  };
97
92
 
@@ -89,35 +89,5 @@ module.exports = (config, { strapi }) => {
89
89
  ]);
90
90
  }
91
91
 
92
- if (!strapi.config.serveAdminPanel) return async (ctx, next) => next();
93
-
94
- const buildDir = path.resolve(strapi.dirs.root, 'build');
95
- const serveAdmin = async (ctx, next) => {
96
- await next();
97
-
98
- if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {
99
- return;
100
- }
101
-
102
- if (ctx.body != null || ctx.status !== 404) {
103
- return;
104
- }
105
-
106
- ctx.type = 'html';
107
- ctx.body = fs.createReadStream(path.join(buildDir + '/index.html'));
108
- };
109
-
110
- strapi.server.routes([
111
- {
112
- method: 'GET',
113
- path: `${strapi.config.admin.path}/:path*`,
114
- handler: [
115
- serveAdmin,
116
- serveStatic(buildDir, { maxage: maxAge, defer: false, index: 'index.html' }),
117
- ],
118
- config: { auth: false },
119
- },
120
- ]);
121
-
122
92
  return null;
123
93
  };
@@ -104,7 +104,9 @@ const addMaxFloatValidator = (validator, { attr }) =>
104
104
  * @returns {StringSchema}
105
105
  */
106
106
  const addStringRegexValidator = (validator, { attr }) =>
107
- _.isUndefined(attr.regex) ? validator : validator.matches(new RegExp(attr.regex));
107
+ _.isUndefined(attr.regex)
108
+ ? validator
109
+ : validator.matches(new RegExp(attr.regex), { excludeEmptyString: !attr.required });
108
110
 
109
111
  /**
110
112
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/strapi",
3
- "version": "4.0.0",
3
+ "version": "4.0.1",
4
4
  "description": "An open source headless CMS solution to create and manage your own API. It provides a powerful dashboard and features to make your life easier. Databases supported: MySQL, MariaDB, PostgreSQL, SQLite",
5
5
  "keywords": [
6
6
  "strapi",
@@ -74,21 +74,22 @@
74
74
  "bin": "./bin"
75
75
  },
76
76
  "scripts": {
77
- "postinstall": "node lib/utils/success.js"
77
+ "postinstall": "node lib/utils/success.js",
78
+ "test:unit": "jest --verbose"
78
79
  },
79
80
  "dependencies": {
80
81
  "@koa/cors": "3.1.0",
81
82
  "@koa/router": "10.1.1",
82
- "@strapi/admin": "4.0.0",
83
- "@strapi/database": "4.0.0",
84
- "@strapi/generate-new": "4.0.0",
85
- "@strapi/generators": "4.0.0",
86
- "@strapi/logger": "4.0.0",
87
- "@strapi/plugin-content-manager": "4.0.0",
88
- "@strapi/plugin-content-type-builder": "4.0.0",
89
- "@strapi/plugin-email": "4.0.0",
90
- "@strapi/plugin-upload": "4.0.0",
91
- "@strapi/utils": "4.0.0",
83
+ "@strapi/admin": "4.0.1",
84
+ "@strapi/database": "4.0.1",
85
+ "@strapi/generate-new": "4.0.1",
86
+ "@strapi/generators": "4.0.1",
87
+ "@strapi/logger": "4.0.1",
88
+ "@strapi/plugin-content-manager": "4.0.1",
89
+ "@strapi/plugin-content-type-builder": "4.0.1",
90
+ "@strapi/plugin-email": "4.0.1",
91
+ "@strapi/plugin-upload": "4.0.1",
92
+ "@strapi/utils": "4.0.1",
92
93
  "bcryptjs": "2.4.3",
93
94
  "boxen": "5.1.2",
94
95
  "chalk": "4.1.2",
@@ -134,5 +135,5 @@
134
135
  "node": ">=12.x.x <=16.x.x",
135
136
  "npm": ">=6.0.0"
136
137
  },
137
- "gitHead": "b181702f0202b2c6d645d42b195a831f25cd0b03"
138
+ "gitHead": "e2cd01e8c6cbfeba15ad7787e38b6eebcbb92221"
138
139
  }