@strapi/strapi 0.0.0-d0fee44d6f → 0.0.0-d36609ff26fb4e00a41a7e2b657f16c7466203fe
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 +25 -12
- package/bin/strapi.js +29 -26
- package/lib/Strapi.js +37 -16
- package/lib/commands/admin-create.js +3 -6
- package/lib/commands/admin-reset.js +1 -1
- package/lib/commands/build.js +1 -1
- package/lib/commands/builders/admin.js +2 -1
- package/lib/commands/builders/typescript.js +2 -2
- package/lib/commands/configurationDump.js +4 -4
- package/lib/commands/configurationRestore.js +5 -4
- package/lib/commands/console.js +1 -1
- package/lib/commands/content-types/list.js +2 -2
- package/lib/commands/controllers/list.js +2 -2
- package/lib/commands/develop.js +16 -10
- package/lib/commands/hooks/list.js +2 -2
- package/lib/commands/install.js +4 -4
- package/lib/commands/middlewares/list.js +2 -2
- package/lib/commands/new.js +1 -1
- package/lib/commands/opt-in-telemetry.js +14 -15
- package/lib/commands/opt-out-telemetry.js +5 -5
- package/lib/commands/policies/list.js +2 -2
- package/lib/commands/routes/list.js +3 -3
- package/lib/commands/services/list.js +2 -2
- package/lib/commands/start.js +1 -0
- package/lib/commands/ts/generate-types.js +1 -1
- package/lib/commands/uninstall.js +4 -4
- package/lib/commands/watchAdmin.js +1 -1
- package/lib/compile.js +1 -1
- package/lib/container.js +1 -1
- package/lib/core/app-configuration/config-loader.js +2 -2
- package/lib/core/app-configuration/load-config-file.js +4 -6
- package/lib/core/bootstrap.js +1 -1
- package/lib/core/domain/component/validator.js +3 -9
- package/lib/core/domain/content-type/index.js +3 -3
- package/lib/core/domain/content-type/validator.js +9 -23
- package/lib/core/domain/module/index.js +1 -1
- package/lib/core/domain/module/validation.js +3 -4
- package/lib/core/loaders/admin.js +1 -1
- package/lib/core/loaders/apis.js +26 -34
- package/lib/core/loaders/components.js +2 -2
- package/lib/core/loaders/middlewares.js +2 -3
- package/lib/core/loaders/plugins/get-enabled-plugins.js +10 -8
- package/lib/core/loaders/plugins/index.js +12 -13
- package/lib/core/loaders/policies.js +1 -2
- package/lib/core/loaders/sanitizers.js +1 -1
- package/lib/core/loaders/src-index.js +3 -5
- package/lib/core/registries/apis.js +1 -1
- package/lib/core/registries/config.js +1 -1
- package/lib/core/registries/content-types.js +3 -3
- package/lib/core/registries/controllers.js +2 -2
- package/lib/core/registries/custom-fields.js +72 -0
- package/lib/core/registries/hooks.js +1 -1
- package/lib/core/registries/middlewares.js +2 -2
- package/lib/core/registries/modules.js +1 -1
- package/lib/core/registries/plugins.js +1 -1
- package/lib/core/registries/policies.js +1 -1
- package/lib/core/registries/services.js +3 -3
- package/lib/core/utils.js +3 -6
- package/lib/core-api/controller/transform.js +5 -5
- package/lib/core-api/service/collection-type.js +1 -1
- package/lib/core-api/service/index.d.ts +6 -3
- package/lib/core-api/service/pagination.js +5 -5
- package/lib/core-api/service/single-type.js +14 -1
- package/lib/factories.js +5 -5
- package/lib/load/filepath-to-prop-path.js +2 -2
- package/lib/load/load-files.js +2 -2
- package/lib/load/package-path.js +1 -1
- package/lib/middlewares/body.js +10 -3
- package/lib/middlewares/compression.js +1 -1
- package/lib/middlewares/cors.js +3 -10
- package/lib/middlewares/favicon.js +16 -3
- package/lib/middlewares/ip.js +1 -1
- package/lib/middlewares/logger.js +4 -1
- package/lib/middlewares/powered-by.js +1 -1
- package/lib/middlewares/query.js +8 -2
- package/lib/middlewares/response-time.js +1 -1
- package/lib/middlewares/responses.js +1 -1
- package/lib/middlewares/security.js +22 -16
- package/lib/middlewares/session.js +2 -2
- package/lib/migrations/draft-publish.js +1 -5
- package/lib/services/auth/index.js +5 -4
- package/lib/services/content-api/index.js +74 -0
- package/lib/services/content-api/permissions/engine.js +5 -0
- package/lib/services/content-api/permissions/index.js +148 -0
- package/lib/services/content-api/permissions/providers/action.js +19 -0
- package/lib/services/content-api/permissions/providers/condition.js +19 -0
- package/lib/services/content-api/permissions/providers/index.js +9 -0
- package/lib/services/core-store.js +4 -4
- package/lib/services/cron.js +1 -1
- package/lib/services/custom-fields.js +11 -0
- package/lib/services/entity-service/components.js +51 -54
- package/lib/services/entity-service/index.js +117 -93
- package/lib/services/entity-service/params.js +1 -87
- package/lib/services/entity-validator/index.js +284 -122
- package/lib/services/entity-validator/validators.js +18 -15
- package/lib/services/errors.js +10 -10
- package/lib/services/event-hub.js +1 -0
- package/lib/services/fs.js +1 -1
- package/lib/services/metrics/admin-user-hash.js +15 -0
- package/lib/services/metrics/index.js +12 -13
- package/lib/services/metrics/is-truthy.js +1 -1
- package/lib/services/metrics/middleware.js +2 -2
- package/lib/services/metrics/sender.js +22 -12
- package/lib/services/metrics/stringify-deep.js +1 -1
- package/lib/services/request-context.js +17 -0
- package/lib/services/server/admin-api.js +1 -1
- package/lib/services/server/compose-endpoint.js +7 -7
- package/lib/services/server/content-api.js +1 -1
- package/lib/services/server/http-server.js +9 -9
- package/lib/services/server/index.js +7 -4
- package/lib/services/server/koa.js +9 -12
- package/lib/services/server/middleware.js +3 -2
- package/lib/services/server/policy.js +1 -1
- package/lib/services/server/register-middlewares.js +6 -8
- package/lib/services/server/register-routes.js +13 -13
- package/lib/services/server/routing.js +11 -26
- package/lib/services/utils/upload-files.js +4 -4
- package/lib/services/webhook-runner.js +8 -7
- package/lib/services/webhook-store.js +3 -2
- package/lib/services/worker-queue.js +3 -2
- package/lib/types/core/attributes/common.d.ts +3 -0
- package/lib/types/core/strapi/index.d.ts +50 -10
- package/lib/types/factories.d.ts +4 -4
- package/lib/utils/addSlash.js +7 -6
- package/lib/utils/convert-custom-field-type.js +22 -0
- package/lib/utils/ee.js +1 -1
- package/lib/utils/index.js +0 -2
- package/lib/utils/open-browser.js +1 -1
- package/lib/utils/run-checks.js +4 -4
- package/lib/utils/signals.js +2 -2
- package/lib/utils/startup-logger.js +2 -2
- package/lib/utils/success.js +2 -2
- package/lib/utils/update-notifier/index.js +4 -4
- package/package.json +21 -20
- package/lib/utils/import-default.js +0 -10
|
@@ -5,7 +5,7 @@ const chalk = require('chalk');
|
|
|
5
5
|
|
|
6
6
|
const strapi = require('../../index');
|
|
7
7
|
|
|
8
|
-
module.exports = async function() {
|
|
8
|
+
module.exports = async function () {
|
|
9
9
|
const appContext = await strapi.compile();
|
|
10
10
|
const app = await strapi(appContext).register();
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ module.exports = async function() {
|
|
|
15
15
|
head: [chalk.blue('Name')],
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
list.forEach(name => infoTable.push([name]));
|
|
18
|
+
list.forEach((name) => infoTable.push([name]));
|
|
19
19
|
|
|
20
20
|
console.log(infoTable.toString());
|
|
21
21
|
|
package/lib/commands/new.js
CHANGED
|
@@ -7,7 +7,7 @@ const fetch = require('node-fetch');
|
|
|
7
7
|
const { v4: uuidv4 } = require('uuid');
|
|
8
8
|
const machineID = require('../utils/machine-id');
|
|
9
9
|
|
|
10
|
-
const readPackageJSON = async path => {
|
|
10
|
+
const readPackageJSON = async (path) => {
|
|
11
11
|
try {
|
|
12
12
|
const packageObj = await fse.readJson(path);
|
|
13
13
|
return packageObj;
|
|
@@ -31,7 +31,7 @@ const writePackageJSON = async (path, file, spacing) => {
|
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
const generateNewPackageJSON = packageObj => {
|
|
34
|
+
const generateNewPackageJSON = (packageObj) => {
|
|
35
35
|
if (!packageObj.strapi) {
|
|
36
36
|
return {
|
|
37
37
|
...packageObj,
|
|
@@ -40,31 +40,30 @@ const generateNewPackageJSON = packageObj => {
|
|
|
40
40
|
telemetryDisabled: false,
|
|
41
41
|
},
|
|
42
42
|
};
|
|
43
|
-
} else {
|
|
44
|
-
return {
|
|
45
|
-
...packageObj,
|
|
46
|
-
strapi: {
|
|
47
|
-
...packageObj.strapi,
|
|
48
|
-
uuid: packageObj.strapi.uuid ? packageObj.strapi.uuid : uuidv4(),
|
|
49
|
-
telemetryDisabled: false,
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
43
|
}
|
|
44
|
+
return {
|
|
45
|
+
...packageObj,
|
|
46
|
+
strapi: {
|
|
47
|
+
...packageObj.strapi,
|
|
48
|
+
uuid: packageObj.strapi.uuid ? packageObj.strapi.uuid : uuidv4(),
|
|
49
|
+
telemetryDisabled: false,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
53
52
|
};
|
|
54
53
|
|
|
55
|
-
const sendEvent = async uuid => {
|
|
54
|
+
const sendEvent = async (uuid) => {
|
|
56
55
|
try {
|
|
57
|
-
await fetch('https://analytics.strapi.io/track', {
|
|
56
|
+
await fetch('https://analytics.strapi.io/api/v2/track', {
|
|
58
57
|
method: 'POST',
|
|
59
58
|
body: JSON.stringify({
|
|
60
59
|
event: 'didOptInTelemetry',
|
|
61
|
-
uuid,
|
|
62
60
|
deviceId: machineID(),
|
|
61
|
+
groupProperties: { projectId: uuid },
|
|
63
62
|
}),
|
|
64
63
|
headers: { 'Content-Type': 'application/json' },
|
|
65
64
|
});
|
|
66
65
|
} catch (e) {
|
|
67
|
-
|
|
66
|
+
// ...
|
|
68
67
|
}
|
|
69
68
|
};
|
|
70
69
|
|
|
@@ -6,7 +6,7 @@ const chalk = require('chalk');
|
|
|
6
6
|
const fetch = require('node-fetch');
|
|
7
7
|
const machineID = require('../utils/machine-id');
|
|
8
8
|
|
|
9
|
-
const readPackageJSON = async path => {
|
|
9
|
+
const readPackageJSON = async (path) => {
|
|
10
10
|
try {
|
|
11
11
|
const packageObj = await fse.readJson(path);
|
|
12
12
|
const uuid = packageObj.strapi ? packageObj.strapi.uuid : null;
|
|
@@ -26,19 +26,19 @@ const writePackageJSON = async (path, file, spacing) => {
|
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
const sendEvent = async uuid => {
|
|
29
|
+
const sendEvent = async (uuid) => {
|
|
30
30
|
try {
|
|
31
|
-
await fetch('https://analytics.strapi.io/track', {
|
|
31
|
+
await fetch('https://analytics.strapi.io/api/v2/track', {
|
|
32
32
|
method: 'POST',
|
|
33
33
|
body: JSON.stringify({
|
|
34
34
|
event: 'didOptOutTelemetry',
|
|
35
|
-
uuid,
|
|
36
35
|
deviceId: machineID(),
|
|
36
|
+
groupProperties: { projectId: uuid },
|
|
37
37
|
}),
|
|
38
38
|
headers: { 'Content-Type': 'application/json' },
|
|
39
39
|
});
|
|
40
40
|
} catch (e) {
|
|
41
|
-
|
|
41
|
+
// ...
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
44
|
|
|
@@ -5,7 +5,7 @@ const chalk = require('chalk');
|
|
|
5
5
|
|
|
6
6
|
const strapi = require('../../index');
|
|
7
7
|
|
|
8
|
-
module.exports = async function() {
|
|
8
|
+
module.exports = async function () {
|
|
9
9
|
const appContext = await strapi.compile();
|
|
10
10
|
const app = await strapi(appContext).register();
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ module.exports = async function() {
|
|
|
15
15
|
head: [chalk.blue('Name')],
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
list.forEach(name => infoTable.push([name]));
|
|
18
|
+
list.forEach((name) => infoTable.push([name]));
|
|
19
19
|
|
|
20
20
|
console.log(infoTable.toString());
|
|
21
21
|
|
|
@@ -6,7 +6,7 @@ const { toUpper } = require('lodash/fp');
|
|
|
6
6
|
|
|
7
7
|
const strapi = require('../../index');
|
|
8
8
|
|
|
9
|
-
module.exports = async function() {
|
|
9
|
+
module.exports = async function () {
|
|
10
10
|
const appContext = await strapi.compile();
|
|
11
11
|
const app = await strapi(appContext).load();
|
|
12
12
|
|
|
@@ -18,8 +18,8 @@ module.exports = async function() {
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
list
|
|
21
|
-
.filter(route => route.methods.length)
|
|
22
|
-
.forEach(route => {
|
|
21
|
+
.filter((route) => route.methods.length)
|
|
22
|
+
.forEach((route) => {
|
|
23
23
|
infoTable.push([route.methods.map(toUpper).join('|'), route.path]);
|
|
24
24
|
});
|
|
25
25
|
|
|
@@ -5,7 +5,7 @@ const chalk = require('chalk');
|
|
|
5
5
|
|
|
6
6
|
const strapi = require('../../index');
|
|
7
7
|
|
|
8
|
-
module.exports = async function() {
|
|
8
|
+
module.exports = async function () {
|
|
9
9
|
const appContext = await strapi.compile();
|
|
10
10
|
const app = await strapi(appContext).register();
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ module.exports = async function() {
|
|
|
15
15
|
head: [chalk.blue('Name')],
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
list.forEach(name => infoTable.push([name]));
|
|
18
|
+
list.forEach((name) => infoTable.push([name]));
|
|
19
19
|
|
|
20
20
|
console.log(infoTable.toString());
|
|
21
21
|
|
package/lib/commands/start.js
CHANGED
|
@@ -4,7 +4,7 @@ const tsUtils = require('@strapi/typescript-utils');
|
|
|
4
4
|
|
|
5
5
|
const strapi = require('../../index');
|
|
6
6
|
|
|
7
|
-
module.exports = async function({ outDir, file, verbose, silent }) {
|
|
7
|
+
module.exports = async function ({ outDir, file, verbose, silent }) {
|
|
8
8
|
if (verbose && silent) {
|
|
9
9
|
console.error('You cannot enable verbose and silent flags at the same time, exiting...');
|
|
10
10
|
process.exit(1);
|
|
@@ -21,13 +21,13 @@ module.exports = async (plugins, { deleteFiles }) => {
|
|
|
21
21
|
const loader = ora();
|
|
22
22
|
const dir = process.cwd();
|
|
23
23
|
|
|
24
|
-
const pluginArgs = plugins.map(name => `@strapi/plugin-${name}`);
|
|
24
|
+
const pluginArgs = plugins.map((name) => `@strapi/plugin-${name}`);
|
|
25
25
|
|
|
26
26
|
try {
|
|
27
27
|
// verify should rebuild before removing the pacakge
|
|
28
28
|
let shouldRebuild = false;
|
|
29
|
-
for (
|
|
30
|
-
|
|
29
|
+
for (const name of plugins) {
|
|
30
|
+
const pkgPath = findPackagePath(`@strapi/plugin-${name}`);
|
|
31
31
|
if (existsSync(join(pkgPath, 'admin', 'src', 'index.js'))) {
|
|
32
32
|
shouldRebuild = true;
|
|
33
33
|
}
|
|
@@ -46,7 +46,7 @@ module.exports = async (plugins, { deleteFiles }) => {
|
|
|
46
46
|
|
|
47
47
|
if (deleteFiles === true || answers.deleteFiles === true) {
|
|
48
48
|
loader.start('Deleting old files');
|
|
49
|
-
for (
|
|
49
|
+
for (const name of plugins) {
|
|
50
50
|
const pluginDir = join(dir, 'extensions', name);
|
|
51
51
|
if (existsSync(pluginDir)) {
|
|
52
52
|
removeSync(pluginDir);
|
|
@@ -7,7 +7,7 @@ const getEnabledPlugins = require('../core/loaders/plugins/get-enabled-plugins')
|
|
|
7
7
|
const addSlash = require('../utils/addSlash');
|
|
8
8
|
const strapi = require('../index');
|
|
9
9
|
|
|
10
|
-
module.exports = async function({ browser }) {
|
|
10
|
+
module.exports = async function ({ browser }) {
|
|
11
11
|
const appContext = await strapi.compile();
|
|
12
12
|
|
|
13
13
|
const strapiInstance = strapi({
|
package/lib/compile.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const tsUtils = require('@strapi/typescript-utils');
|
|
4
4
|
|
|
5
|
-
module.exports = async dir => {
|
|
5
|
+
module.exports = async (dir) => {
|
|
6
6
|
const appDir = dir || process.cwd();
|
|
7
7
|
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
|
|
8
8
|
const outDir = await tsUtils.resolveOutDir(appDir);
|
package/lib/container.js
CHANGED
|
@@ -6,12 +6,12 @@ const loadFile = require('./load-config-file');
|
|
|
6
6
|
|
|
7
7
|
const VALID_EXTENSIONS = ['.js', '.json'];
|
|
8
8
|
|
|
9
|
-
module.exports = dir => {
|
|
9
|
+
module.exports = (dir) => {
|
|
10
10
|
if (!fs.existsSync(dir)) return {};
|
|
11
11
|
|
|
12
12
|
return fs
|
|
13
13
|
.readdirSync(dir, { withFileTypes: true })
|
|
14
|
-
.filter(file => file.isFile() && VALID_EXTENSIONS.includes(path.extname(file.name)))
|
|
14
|
+
.filter((file) => file.isFile() && VALID_EXTENSIONS.includes(path.extname(file.name)))
|
|
15
15
|
.reduce((acc, file) => {
|
|
16
16
|
const key = path.basename(file.name, path.extname(file.name));
|
|
17
17
|
|
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const fs = require('fs');
|
|
5
|
-
const { templateConfiguration, env } = require('@strapi/utils');
|
|
5
|
+
const { templateConfiguration, env, importDefault } = require('@strapi/utils');
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const loadJsFile = file => {
|
|
7
|
+
const loadJsFile = (file) => {
|
|
10
8
|
try {
|
|
11
9
|
const jsModule = importDefault(file);
|
|
12
10
|
|
|
@@ -21,7 +19,7 @@ const loadJsFile = file => {
|
|
|
21
19
|
}
|
|
22
20
|
};
|
|
23
21
|
|
|
24
|
-
const loadJSONFile = file => {
|
|
22
|
+
const loadJSONFile = (file) => {
|
|
25
23
|
try {
|
|
26
24
|
return templateConfiguration(JSON.parse(fs.readFileSync(file)));
|
|
27
25
|
} catch (error) {
|
|
@@ -29,7 +27,7 @@ const loadJSONFile = file => {
|
|
|
29
27
|
}
|
|
30
28
|
};
|
|
31
29
|
|
|
32
|
-
const loadFile = file => {
|
|
30
|
+
const loadFile = (file) => {
|
|
33
31
|
const ext = path.extname(file);
|
|
34
32
|
|
|
35
33
|
switch (ext) {
|
package/lib/core/bootstrap.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { getConfigUrls } = require('@strapi/utils');
|
|
4
4
|
const fse = require('fs-extra');
|
|
5
5
|
|
|
6
|
-
module.exports = async function({ strapi }) {
|
|
6
|
+
module.exports = async function ({ strapi }) {
|
|
7
7
|
strapi.config.port = strapi.config.get('server.port') || strapi.config.port;
|
|
8
8
|
strapi.config.host = strapi.config.get('server.host') || strapi.config.host;
|
|
9
9
|
|
|
@@ -7,20 +7,14 @@ const componentSchemaValidator = () =>
|
|
|
7
7
|
info: yup
|
|
8
8
|
.object()
|
|
9
9
|
.shape({
|
|
10
|
-
singularName: yup
|
|
11
|
-
|
|
12
|
-
.isCamelCase()
|
|
13
|
-
.required(),
|
|
14
|
-
pluralName: yup
|
|
15
|
-
.string()
|
|
16
|
-
.isCamelCase()
|
|
17
|
-
.required(),
|
|
10
|
+
singularName: yup.string().isCamelCase().required(),
|
|
11
|
+
pluralName: yup.string().isCamelCase().required(),
|
|
18
12
|
displayName: yup.string().required(),
|
|
19
13
|
})
|
|
20
14
|
.required(),
|
|
21
15
|
});
|
|
22
16
|
|
|
23
|
-
const validateComponentDefinition = data => {
|
|
17
|
+
const validateComponentDefinition = (data) => {
|
|
24
18
|
return componentSchemaValidator.validateSync(data, { strict: true, abortEarly: false });
|
|
25
19
|
};
|
|
26
20
|
|
|
@@ -54,7 +54,7 @@ const createContentType = (uid, definition) => {
|
|
|
54
54
|
});
|
|
55
55
|
} else {
|
|
56
56
|
throw new Error(
|
|
57
|
-
`Incorrect Content Type UID "${uid}". The UID should start with api::, plugin:: or
|
|
57
|
+
`Incorrect Content Type UID "${uid}". The UID should start with api::, plugin:: or admin::.`
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -114,12 +114,12 @@ const createContentType = (uid, definition) => {
|
|
|
114
114
|
};
|
|
115
115
|
|
|
116
116
|
const getGlobalId = (model, modelName, prefix) => {
|
|
117
|
-
|
|
117
|
+
const globalId = prefix ? `${prefix}-${modelName}` : modelName;
|
|
118
118
|
|
|
119
119
|
return model.globalId || _.upperFirst(_.camelCase(globalId));
|
|
120
120
|
};
|
|
121
121
|
|
|
122
|
-
const pickSchema = model => {
|
|
122
|
+
const pickSchema = (model) => {
|
|
123
123
|
const schema = _.cloneDeep(
|
|
124
124
|
_.pick(model, [
|
|
125
125
|
'connection',
|
|
@@ -36,14 +36,9 @@ const LIFECYCLES = [
|
|
|
36
36
|
* TODO V5: check if we can avoid this coupling by moving this logic
|
|
37
37
|
* into the GraphQL plugin.
|
|
38
38
|
*/
|
|
39
|
-
const GRAPHQL_ENUM_REGEX =
|
|
39
|
+
const GRAPHQL_ENUM_REGEX = /^[_A-Za-z][_0-9A-Za-z]*$/;
|
|
40
40
|
|
|
41
|
-
const lifecyclesShape = _.mapValues(_.keyBy(LIFECYCLES), () =>
|
|
42
|
-
yup
|
|
43
|
-
.mixed()
|
|
44
|
-
.nullable()
|
|
45
|
-
.isFunction()
|
|
46
|
-
);
|
|
41
|
+
const lifecyclesShape = _.mapValues(_.keyBy(LIFECYCLES), () => yup.mixed().nullable().isFunction());
|
|
47
42
|
|
|
48
43
|
const contentTypeSchemaValidator = yup.object().shape({
|
|
49
44
|
schema: yup.object().shape({
|
|
@@ -51,34 +46,28 @@ const contentTypeSchemaValidator = yup.object().shape({
|
|
|
51
46
|
.object()
|
|
52
47
|
.shape({
|
|
53
48
|
displayName: yup.string().required(),
|
|
54
|
-
singularName: yup
|
|
55
|
-
|
|
56
|
-
.isKebabCase()
|
|
57
|
-
.required(),
|
|
58
|
-
pluralName: yup
|
|
59
|
-
.string()
|
|
60
|
-
.isKebabCase()
|
|
61
|
-
.required(),
|
|
49
|
+
singularName: yup.string().isKebabCase().required(),
|
|
50
|
+
pluralName: yup.string().isKebabCase().required(),
|
|
62
51
|
})
|
|
63
52
|
.required(),
|
|
64
53
|
attributes: yup.object().test({
|
|
65
54
|
name: 'valuesCollide',
|
|
66
55
|
message: 'Some values collide when normalized',
|
|
67
56
|
test(attributes) {
|
|
68
|
-
for (const attrName
|
|
57
|
+
for (const attrName of Object.keys(attributes)) {
|
|
69
58
|
const attr = attributes[attrName];
|
|
70
59
|
if (attr.type === 'enumeration') {
|
|
71
60
|
const regressedValues = attr.enum.map(toRegressedEnumValue);
|
|
72
61
|
|
|
73
62
|
// should match the GraphQL regex
|
|
74
|
-
if (!regressedValues.every(value => GRAPHQL_ENUM_REGEX.test(value))) {
|
|
63
|
+
if (!regressedValues.every((value) => GRAPHQL_ENUM_REGEX.test(value))) {
|
|
75
64
|
const message = `Invalid enumeration value. Values should have at least one alphabetical character preceeding the first occurence of a number. Update your enumeration '${attrName}'.`;
|
|
76
65
|
|
|
77
66
|
return this.createError({ message });
|
|
78
67
|
}
|
|
79
68
|
|
|
80
69
|
// should not contain empty values
|
|
81
|
-
if (regressedValues.some(value => value === '')) {
|
|
70
|
+
if (regressedValues.some((value) => value === '')) {
|
|
82
71
|
return this.createError({
|
|
83
72
|
message: `At least one value of the enumeration '${attrName}' appears to be empty. Only alphanumerical characters are taken into account.`,
|
|
84
73
|
});
|
|
@@ -104,13 +93,10 @@ const contentTypeSchemaValidator = yup.object().shape({
|
|
|
104
93
|
}),
|
|
105
94
|
}),
|
|
106
95
|
actions: yup.object().onlyContainsFunctions(),
|
|
107
|
-
lifecycles: yup
|
|
108
|
-
.object()
|
|
109
|
-
.shape(lifecyclesShape)
|
|
110
|
-
.noUnknown(),
|
|
96
|
+
lifecycles: yup.object().shape(lifecyclesShape).noUnknown(),
|
|
111
97
|
});
|
|
112
98
|
|
|
113
|
-
const validateContentTypeDefinition = data => {
|
|
99
|
+
const validateContentTypeDefinition = (data) => {
|
|
114
100
|
return contentTypeSchemaValidator.validateSync(data, { strict: true, abortEarly: false });
|
|
115
101
|
};
|
|
116
102
|
|
|
@@ -4,7 +4,7 @@ const _ = require('lodash');
|
|
|
4
4
|
const { removeNamespace } = require('../../utils');
|
|
5
5
|
const { validateModule } = require('./validation');
|
|
6
6
|
|
|
7
|
-
const uidToPath = uid => uid.replace('::', '.');
|
|
7
|
+
const uidToPath = (uid) => uid.replace('::', '.');
|
|
8
8
|
|
|
9
9
|
// Removes the namespace from a map with keys prefixed with a namespace
|
|
10
10
|
const removeNamespacedKeys = (map, namespace) => {
|
|
@@ -9,12 +9,11 @@ const strapiServerSchema = yup
|
|
|
9
9
|
destroy: yup.mixed().isFunction(),
|
|
10
10
|
register: yup.mixed().isFunction(),
|
|
11
11
|
config: yup.object(),
|
|
12
|
-
routes: yup.lazy(value => {
|
|
12
|
+
routes: yup.lazy((value) => {
|
|
13
13
|
if (Array.isArray(value)) {
|
|
14
14
|
return yup.array();
|
|
15
|
-
} else {
|
|
16
|
-
return yup.object();
|
|
17
15
|
}
|
|
16
|
+
return yup.object();
|
|
18
17
|
}),
|
|
19
18
|
controllers: yup.object(),
|
|
20
19
|
services: yup.object(),
|
|
@@ -24,7 +23,7 @@ const strapiServerSchema = yup
|
|
|
24
23
|
})
|
|
25
24
|
.noUnknown();
|
|
26
25
|
|
|
27
|
-
const validateModule = data => {
|
|
26
|
+
const validateModule = (data) => {
|
|
28
27
|
return strapiServerSchema.validateSync(data, { strict: true, abortEarly: false });
|
|
29
28
|
};
|
|
30
29
|
|
package/lib/core/loaders/apis.js
CHANGED
|
@@ -4,8 +4,7 @@ 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');
|
|
8
|
-
const { importDefault } = require('../../utils');
|
|
7
|
+
const { isKebabCase, importDefault } = require('@strapi/utils');
|
|
9
8
|
|
|
10
9
|
const DEFAULT_CONTENT_TYPE = {
|
|
11
10
|
schema: {},
|
|
@@ -14,12 +13,12 @@ const DEFAULT_CONTENT_TYPE = {
|
|
|
14
13
|
};
|
|
15
14
|
|
|
16
15
|
// to handle names with numbers in it we first check if it is already in kebabCase
|
|
17
|
-
const normalizeName = name => (isKebabCase(name) ? name : _.kebabCase(name));
|
|
16
|
+
const normalizeName = (name) => (isKebabCase(name) ? name : _.kebabCase(name));
|
|
18
17
|
|
|
19
|
-
const isDirectory = fd => fd.isDirectory();
|
|
20
|
-
const isDotFile = fd => fd.name.startsWith('.');
|
|
18
|
+
const isDirectory = (fd) => fd.isDirectory();
|
|
19
|
+
const isDotFile = (fd) => fd.name.startsWith('.');
|
|
21
20
|
|
|
22
|
-
module.exports = async strapi => {
|
|
21
|
+
module.exports = async (strapi) => {
|
|
23
22
|
if (!existsSync(strapi.dirs.dist.api)) {
|
|
24
23
|
return;
|
|
25
24
|
}
|
|
@@ -40,13 +39,13 @@ module.exports = async strapi => {
|
|
|
40
39
|
|
|
41
40
|
validateContentTypesUnicity(apis);
|
|
42
41
|
|
|
43
|
-
for (const apiName
|
|
42
|
+
for (const apiName of Object.keys(apis)) {
|
|
44
43
|
strapi.container.get('apis').add(apiName, apis[apiName]);
|
|
45
44
|
}
|
|
46
45
|
};
|
|
47
46
|
|
|
48
|
-
const validateContentTypesUnicity = apis => {
|
|
49
|
-
const allApisSchemas = Object.values(apis).flatMap(api => Object.values(api.contentTypes));
|
|
47
|
+
const validateContentTypesUnicity = (apis) => {
|
|
48
|
+
const allApisSchemas = Object.values(apis).flatMap((api) => Object.values(api.contentTypes));
|
|
50
49
|
|
|
51
50
|
const names = [];
|
|
52
51
|
allApisSchemas.forEach(({ schema }) => {
|
|
@@ -68,26 +67,18 @@ const validateContentTypesUnicity = apis => {
|
|
|
68
67
|
});
|
|
69
68
|
};
|
|
70
69
|
|
|
71
|
-
const loadAPI = async dir => {
|
|
72
|
-
const [
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
loadDir(join(dir, 'config')),
|
|
84
|
-
loadDir(join(dir, 'routes')),
|
|
85
|
-
loadDir(join(dir, 'controllers')),
|
|
86
|
-
loadDir(join(dir, 'services')),
|
|
87
|
-
loadDir(join(dir, 'policies')),
|
|
88
|
-
loadDir(join(dir, 'middlewares')),
|
|
89
|
-
loadContentTypes(join(dir, 'content-types')),
|
|
90
|
-
]);
|
|
70
|
+
const loadAPI = async (dir) => {
|
|
71
|
+
const [index, config, routes, controllers, services, policies, middlewares, contentTypes] =
|
|
72
|
+
await Promise.all([
|
|
73
|
+
loadIndex(dir),
|
|
74
|
+
loadDir(join(dir, 'config')),
|
|
75
|
+
loadDir(join(dir, 'routes')),
|
|
76
|
+
loadDir(join(dir, 'controllers')),
|
|
77
|
+
loadDir(join(dir, 'services')),
|
|
78
|
+
loadDir(join(dir, 'policies')),
|
|
79
|
+
loadDir(join(dir, 'middlewares')),
|
|
80
|
+
loadContentTypes(join(dir, 'content-types')),
|
|
81
|
+
]);
|
|
91
82
|
|
|
92
83
|
return {
|
|
93
84
|
...(index || {}),
|
|
@@ -101,13 +92,13 @@ const loadAPI = async dir => {
|
|
|
101
92
|
};
|
|
102
93
|
};
|
|
103
94
|
|
|
104
|
-
const loadIndex = async dir => {
|
|
95
|
+
const loadIndex = async (dir) => {
|
|
105
96
|
if (await fse.pathExists(join(dir, 'index.js'))) {
|
|
106
97
|
return loadFile(join(dir, 'index.js'));
|
|
107
98
|
}
|
|
108
99
|
};
|
|
109
100
|
|
|
110
|
-
const loadContentTypes = async dir => {
|
|
101
|
+
const loadContentTypes = async (dir) => {
|
|
111
102
|
if (!(await fse.pathExists(dir))) {
|
|
112
103
|
return;
|
|
113
104
|
}
|
|
@@ -130,7 +121,7 @@ const loadContentTypes = async dir => {
|
|
|
130
121
|
return contentTypes;
|
|
131
122
|
};
|
|
132
123
|
|
|
133
|
-
const loadDir = async dir => {
|
|
124
|
+
const loadDir = async (dir) => {
|
|
134
125
|
if (!(await fse.pathExists(dir))) {
|
|
135
126
|
return;
|
|
136
127
|
}
|
|
@@ -139,18 +130,19 @@ const loadDir = async dir => {
|
|
|
139
130
|
|
|
140
131
|
const root = {};
|
|
141
132
|
for (const fd of fds) {
|
|
142
|
-
if (!fd.isFile()) {
|
|
133
|
+
if (!fd.isFile() || extname(fd.name) === '.map') {
|
|
143
134
|
continue;
|
|
144
135
|
}
|
|
145
136
|
|
|
146
137
|
const key = basename(fd.name, extname(fd.name));
|
|
138
|
+
|
|
147
139
|
root[normalizeName(key)] = await loadFile(join(dir, fd.name));
|
|
148
140
|
}
|
|
149
141
|
|
|
150
142
|
return root;
|
|
151
143
|
};
|
|
152
144
|
|
|
153
|
-
const loadFile = file => {
|
|
145
|
+
const loadFile = (file) => {
|
|
154
146
|
const ext = extname(file);
|
|
155
147
|
|
|
156
148
|
switch (ext) {
|
|
@@ -5,7 +5,7 @@ const _ = require('lodash');
|
|
|
5
5
|
const { pathExists } = require('fs-extra');
|
|
6
6
|
const loadFiles = require('../../load/load-files');
|
|
7
7
|
|
|
8
|
-
module.exports = async strapi => {
|
|
8
|
+
module.exports = async (strapi) => {
|
|
9
9
|
if (!(await pathExists(strapi.dirs.dist.components))) {
|
|
10
10
|
return {};
|
|
11
11
|
}
|
|
@@ -13,7 +13,7 @@ module.exports = async strapi => {
|
|
|
13
13
|
const map = await loadFiles(strapi.dirs.dist.components, '*/*.*(js|json)');
|
|
14
14
|
|
|
15
15
|
return Object.keys(map).reduce((acc, category) => {
|
|
16
|
-
Object.keys(map[category]).forEach(key => {
|
|
16
|
+
Object.keys(map[category]).forEach((key) => {
|
|
17
17
|
const schema = map[category][key];
|
|
18
18
|
|
|
19
19
|
if (!schema.collectionName) {
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { join, extname, basename } = require('path');
|
|
4
4
|
const fse = require('fs-extra');
|
|
5
|
-
|
|
6
|
-
const { importDefault } = require('../../utils');
|
|
5
|
+
const { importDefault } = require('@strapi/utils');
|
|
7
6
|
|
|
8
7
|
// TODO:: allow folders with index.js inside for bigger policies
|
|
9
8
|
module.exports = async function loadMiddlewares(strapi) {
|
|
@@ -14,7 +13,7 @@ module.exports = async function loadMiddlewares(strapi) {
|
|
|
14
13
|
strapi.container.get('middlewares').add(`strapi::`, internalMiddlewares);
|
|
15
14
|
};
|
|
16
15
|
|
|
17
|
-
const loadLocalMiddlewares = async strapi => {
|
|
16
|
+
const loadLocalMiddlewares = async (strapi) => {
|
|
18
17
|
const dir = strapi.dirs.dist.middlewares;
|
|
19
18
|
|
|
20
19
|
if (!(await fse.pathExists(dir))) {
|