@strapi/strapi 4.0.0 → 4.0.4
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 +2 -2
- package/bin/strapi.js +5 -1
- package/lib/commands/build.js +5 -5
- package/lib/commands/controllers/list.js +22 -0
- package/lib/commands/develop.js +18 -20
- package/lib/core/loaders/plugins/get-enabled-plugins.js +8 -6
- package/lib/core/loaders/plugins/get-user-plugins-config.js +37 -0
- package/lib/core/loaders/plugins/index.js +2 -4
- package/lib/core-api/service/pagination.js +9 -14
- package/lib/middlewares/public/index.js +0 -30
- package/lib/services/entity-validator/validators.js +3 -1
- package/package.json +16 -15
package/README.md
CHANGED
package/bin/strapi.js
CHANGED
|
@@ -133,7 +133,6 @@ program
|
|
|
133
133
|
|
|
134
134
|
program
|
|
135
135
|
.command('build')
|
|
136
|
-
.option('--clean', 'Remove the build and .cache folders', false)
|
|
137
136
|
.option('--no-optimization', 'Build the Administration without assets optimization')
|
|
138
137
|
.description('Builds the strapi admin app')
|
|
139
138
|
.action(getLocalScript('build'));
|
|
@@ -213,4 +212,9 @@ program
|
|
|
213
212
|
.description('List all the application services')
|
|
214
213
|
.action(getLocalScript('services/list'));
|
|
215
214
|
|
|
215
|
+
program
|
|
216
|
+
.command('controllers:list')
|
|
217
|
+
.description('List all the application controllers')
|
|
218
|
+
.action(getLocalScript('controllers/list'));
|
|
219
|
+
|
|
216
220
|
program.parseAsync(process.argv);
|
package/lib/commands/build.js
CHANGED
|
@@ -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 ({
|
|
15
|
+
module.exports = async ({ optimization, forceBuild = true }) => {
|
|
16
16
|
const dir = process.cwd();
|
|
17
17
|
|
|
18
18
|
const strapiInstance = strapi({
|
|
@@ -28,14 +28,14 @@ module.exports = async ({ clean, optimization }) => {
|
|
|
28
28
|
|
|
29
29
|
console.log(`Building your admin UI with ${green(env)} configuration ...`);
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
31
|
+
// Always remove the .cache and build folders
|
|
32
|
+
await strapiAdmin.clean({ dir });
|
|
34
33
|
|
|
35
34
|
ee({ dir });
|
|
36
35
|
|
|
37
36
|
return strapiAdmin
|
|
38
37
|
.build({
|
|
38
|
+
forceBuild,
|
|
39
39
|
dir,
|
|
40
40
|
plugins,
|
|
41
41
|
// front end build env is always production for now
|
|
@@ -47,7 +47,7 @@ module.exports = async ({ clean, optimization }) => {
|
|
|
47
47
|
},
|
|
48
48
|
})
|
|
49
49
|
.then(() => {
|
|
50
|
-
|
|
50
|
+
console.log('Admin UI built successfully');
|
|
51
51
|
})
|
|
52
52
|
.catch(err => {
|
|
53
53
|
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
|
+
};
|
package/lib/commands/develop.js
CHANGED
|
@@ -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({ 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,15 +119,15 @@ 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',
|
|
131
127
|
'**/node_modules/**',
|
|
132
128
|
'**/plugins.json',
|
|
129
|
+
'**/build',
|
|
130
|
+
'**/build/**',
|
|
133
131
|
'**/index.html',
|
|
134
132
|
'**/public',
|
|
135
133
|
'**/public/**',
|
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
*
|
|
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 {
|
|
19
|
+
* @returns {boolean}
|
|
20
20
|
*/
|
|
21
|
-
const
|
|
22
|
-
|
|
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:
|
|
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:
|
|
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)
|
|
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.
|
|
3
|
+
"version": "4.0.4",
|
|
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,27 +74,28 @@
|
|
|
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.
|
|
83
|
-
"@strapi/database": "4.0.
|
|
84
|
-
"@strapi/generate-new": "4.0.
|
|
85
|
-
"@strapi/generators": "4.0.
|
|
86
|
-
"@strapi/logger": "4.0.
|
|
87
|
-
"@strapi/plugin-content-manager": "4.0.
|
|
88
|
-
"@strapi/plugin-content-type-builder": "4.0.
|
|
89
|
-
"@strapi/plugin-email": "4.0.
|
|
90
|
-
"@strapi/plugin-upload": "4.0.
|
|
91
|
-
"@strapi/utils": "4.0.
|
|
83
|
+
"@strapi/admin": "4.0.4",
|
|
84
|
+
"@strapi/database": "4.0.4",
|
|
85
|
+
"@strapi/generate-new": "4.0.4",
|
|
86
|
+
"@strapi/generators": "4.0.4",
|
|
87
|
+
"@strapi/logger": "4.0.4",
|
|
88
|
+
"@strapi/plugin-content-manager": "4.0.4",
|
|
89
|
+
"@strapi/plugin-content-type-builder": "4.0.4",
|
|
90
|
+
"@strapi/plugin-email": "4.0.4",
|
|
91
|
+
"@strapi/plugin-upload": "4.0.4",
|
|
92
|
+
"@strapi/utils": "4.0.4",
|
|
92
93
|
"bcryptjs": "2.4.3",
|
|
93
94
|
"boxen": "5.1.2",
|
|
94
95
|
"chalk": "4.1.2",
|
|
95
96
|
"chokidar": "3.5.2",
|
|
96
97
|
"ci-info": "3.2.0",
|
|
97
|
-
"cli-table3": "0.6.
|
|
98
|
+
"cli-table3": "0.6.1",
|
|
98
99
|
"commander": "8.2.0",
|
|
99
100
|
"configstore": "5.0.1",
|
|
100
101
|
"debug": "4.3.2",
|
|
@@ -131,8 +132,8 @@
|
|
|
131
132
|
"supertest": "^6.1.6"
|
|
132
133
|
},
|
|
133
134
|
"engines": {
|
|
134
|
-
"node": ">=12.
|
|
135
|
+
"node": ">=12.22.0 <=16.x.x",
|
|
135
136
|
"npm": ">=6.0.0"
|
|
136
137
|
},
|
|
137
|
-
"gitHead": "
|
|
138
|
+
"gitHead": "d81919ac2272948b3f5d3b25a4cf8cc7b6994460"
|
|
138
139
|
}
|