@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
|
@@ -7,7 +7,7 @@ const { get, has, pick, pickBy, defaultsDeep, map, prop, pipe } = require('lodas
|
|
|
7
7
|
const { isKebabCase } = require('@strapi/utils');
|
|
8
8
|
const getUserPluginsConfig = require('./get-user-plugins-config');
|
|
9
9
|
|
|
10
|
-
const isStrapiPlugin = info => get('strapi.kind', info) === 'plugin';
|
|
10
|
+
const isStrapiPlugin = (info) => get('strapi.kind', info) === 'plugin';
|
|
11
11
|
const INTERNAL_PLUGINS = [
|
|
12
12
|
'@strapi/plugin-content-manager',
|
|
13
13
|
'@strapi/plugin-content-type-builder',
|
|
@@ -15,18 +15,18 @@ const INTERNAL_PLUGINS = [
|
|
|
15
15
|
'@strapi/plugin-upload',
|
|
16
16
|
];
|
|
17
17
|
|
|
18
|
-
const validatePluginName = pluginName => {
|
|
18
|
+
const validatePluginName = (pluginName) => {
|
|
19
19
|
if (!isKebabCase(pluginName)) {
|
|
20
20
|
throw new Error(`Plugin name "${pluginName}" is not in kebab (an-example-of-kebab-case)`);
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
const toDetailedDeclaration = declaration => {
|
|
24
|
+
const toDetailedDeclaration = (declaration) => {
|
|
25
25
|
if (typeof declaration === 'boolean') {
|
|
26
26
|
return { enabled: declaration };
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
const detailedDeclaration = pick(['enabled'], declaration);
|
|
30
30
|
if (has('resolve', declaration)) {
|
|
31
31
|
let pathToPlugin = '';
|
|
32
32
|
|
|
@@ -45,7 +45,7 @@ const toDetailedDeclaration = declaration => {
|
|
|
45
45
|
return detailedDeclaration;
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
const getEnabledPlugins = async strapi => {
|
|
48
|
+
const getEnabledPlugins = async (strapi) => {
|
|
49
49
|
const internalPlugins = {};
|
|
50
50
|
for (const dep of INTERNAL_PLUGINS) {
|
|
51
51
|
const packagePath = join(dep, 'package.json');
|
|
@@ -59,7 +59,9 @@ const getEnabledPlugins = async strapi => {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
const installedPlugins = {};
|
|
62
|
-
|
|
62
|
+
const dependencies = strapi.config.get('info.dependencies', {});
|
|
63
|
+
|
|
64
|
+
for (const dep of Object.keys(dependencies)) {
|
|
63
65
|
const packagePath = join(dep, 'package.json');
|
|
64
66
|
let packageInfo;
|
|
65
67
|
try {
|
|
@@ -106,14 +108,14 @@ const getEnabledPlugins = async strapi => {
|
|
|
106
108
|
|
|
107
109
|
const declaredPluginsResolves = map(prop('pathToPlugin'), declaredPlugins);
|
|
108
110
|
const installedPluginsNotAlreadyUsed = pickBy(
|
|
109
|
-
p => !declaredPluginsResolves.includes(p.pathToPlugin),
|
|
111
|
+
(p) => !declaredPluginsResolves.includes(p.pathToPlugin),
|
|
110
112
|
installedPlugins
|
|
111
113
|
);
|
|
112
114
|
|
|
113
115
|
const enabledPlugins = pipe(
|
|
114
116
|
defaultsDeep(declaredPlugins),
|
|
115
117
|
defaultsDeep(installedPluginsNotAlreadyUsed),
|
|
116
|
-
pickBy(p => p.enabled)
|
|
118
|
+
pickBy((p) => p.enabled)
|
|
117
119
|
)(internalPlugins);
|
|
118
120
|
|
|
119
121
|
return enabledPlugins;
|
|
@@ -25,7 +25,7 @@ const defaultPlugin = {
|
|
|
25
25
|
contentTypes: {},
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
const applyUserExtension = async plugins => {
|
|
28
|
+
const applyUserExtension = async (plugins) => {
|
|
29
29
|
const extensionsDir = strapi.dirs.dist.extensions;
|
|
30
30
|
if (!(await fse.pathExists(extensionsDir))) {
|
|
31
31
|
return;
|
|
@@ -34,17 +34,16 @@ const applyUserExtension = async plugins => {
|
|
|
34
34
|
const extendedSchemas = await loadFiles(extensionsDir, '**/content-types/**/schema.json');
|
|
35
35
|
const strapiServers = await loadFiles(extensionsDir, '**/strapi-server.js');
|
|
36
36
|
|
|
37
|
-
for (const pluginName
|
|
37
|
+
for (const pluginName of Object.keys(plugins)) {
|
|
38
38
|
const plugin = plugins[pluginName];
|
|
39
39
|
// first: load json schema
|
|
40
|
-
for (const ctName
|
|
40
|
+
for (const ctName of Object.keys(plugin.contentTypes)) {
|
|
41
41
|
const extendedSchema = get([pluginName, 'content-types', ctName, 'schema'], extendedSchemas);
|
|
42
42
|
if (extendedSchema) {
|
|
43
|
-
plugin.contentTypes[ctName].schema =
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
);
|
|
43
|
+
plugin.contentTypes[ctName].schema = {
|
|
44
|
+
...plugin.contentTypes[ctName].schema,
|
|
45
|
+
...extendedSchema,
|
|
46
|
+
};
|
|
48
47
|
}
|
|
49
48
|
}
|
|
50
49
|
// second: execute strapi-server extension
|
|
@@ -55,10 +54,10 @@ const applyUserExtension = async plugins => {
|
|
|
55
54
|
}
|
|
56
55
|
};
|
|
57
56
|
|
|
58
|
-
const applyUserConfig = async plugins => {
|
|
57
|
+
const applyUserConfig = async (plugins) => {
|
|
59
58
|
const userPluginsConfig = await getUserPluginsConfig();
|
|
60
59
|
|
|
61
|
-
for (const pluginName
|
|
60
|
+
for (const pluginName of Object.keys(plugins)) {
|
|
62
61
|
const plugin = plugins[pluginName];
|
|
63
62
|
const userPluginConfig = getOr({}, `${pluginName}.config`, userPluginsConfig);
|
|
64
63
|
const defaultConfig =
|
|
@@ -76,14 +75,14 @@ const applyUserConfig = async plugins => {
|
|
|
76
75
|
}
|
|
77
76
|
};
|
|
78
77
|
|
|
79
|
-
const loadPlugins = async strapi => {
|
|
78
|
+
const loadPlugins = async (strapi) => {
|
|
80
79
|
const plugins = {};
|
|
81
80
|
|
|
82
81
|
const enabledPlugins = await getEnabledPlugins(strapi);
|
|
83
82
|
|
|
84
83
|
strapi.config.set('enabledPlugins', enabledPlugins);
|
|
85
84
|
|
|
86
|
-
for (const pluginName
|
|
85
|
+
for (const pluginName of Object.keys(enabledPlugins)) {
|
|
87
86
|
const enabledPlugin = enabledPlugins[pluginName];
|
|
88
87
|
|
|
89
88
|
const serverEntrypointPath = join(enabledPlugin.pathToPlugin, 'strapi-server.js');
|
|
@@ -101,7 +100,7 @@ const loadPlugins = async strapi => {
|
|
|
101
100
|
await applyUserConfig(plugins);
|
|
102
101
|
await applyUserExtension(plugins);
|
|
103
102
|
|
|
104
|
-
for (const pluginName
|
|
103
|
+
for (const pluginName of Object.keys(plugins)) {
|
|
105
104
|
strapi.container.get('plugins').add(pluginName, plugins[pluginName]);
|
|
106
105
|
}
|
|
107
106
|
};
|
|
@@ -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 loadPolicies(strapi) {
|
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { resolve } = require('path');
|
|
4
4
|
const { statSync, existsSync } = require('fs');
|
|
5
|
-
const { yup } = require('@strapi/utils');
|
|
6
|
-
|
|
7
|
-
const { importDefault } = require('../../utils');
|
|
5
|
+
const { yup, importDefault } = require('@strapi/utils');
|
|
8
6
|
|
|
9
7
|
const srcSchema = yup
|
|
10
8
|
.object()
|
|
@@ -15,11 +13,11 @@ const srcSchema = yup
|
|
|
15
13
|
})
|
|
16
14
|
.noUnknown();
|
|
17
15
|
|
|
18
|
-
const validateSrcIndex = srcIndex => {
|
|
16
|
+
const validateSrcIndex = (srcIndex) => {
|
|
19
17
|
return srcSchema.validateSync(srcIndex, { strict: true, abortEarly: false });
|
|
20
18
|
};
|
|
21
19
|
|
|
22
|
-
module.exports = strapi => {
|
|
20
|
+
module.exports = (strapi) => {
|
|
23
21
|
if (!existsSync(strapi.dirs.dist.src)) {
|
|
24
22
|
return;
|
|
25
23
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const _ = require('lodash');
|
|
4
4
|
|
|
5
5
|
module.exports = (initialConfig = {}) => {
|
|
6
|
-
const _config =
|
|
6
|
+
const _config = { ...initialConfig }; // not deep clone because it would break some config
|
|
7
7
|
|
|
8
8
|
return {
|
|
9
9
|
..._config, // TODO: to remove
|
|
@@ -4,8 +4,8 @@ const { pickBy, has } = require('lodash/fp');
|
|
|
4
4
|
const { createContentType } = require('../domain/content-type');
|
|
5
5
|
const { addNamespace, hasNamespace } = require('../utils');
|
|
6
6
|
|
|
7
|
-
const validateKeySameToSingularName = contentTypes => {
|
|
8
|
-
for (const ctName
|
|
7
|
+
const validateKeySameToSingularName = (contentTypes) => {
|
|
8
|
+
for (const ctName of Object.keys(contentTypes)) {
|
|
9
9
|
const contentType = contentTypes[ctName];
|
|
10
10
|
|
|
11
11
|
if (ctName !== contentType.schema.info.singularName) {
|
|
@@ -63,7 +63,7 @@ const contentTypesRegistry = () => {
|
|
|
63
63
|
add(namespace, newContentTypes) {
|
|
64
64
|
validateKeySameToSingularName(newContentTypes);
|
|
65
65
|
|
|
66
|
-
for (const rawCtName
|
|
66
|
+
for (const rawCtName of Object.keys(newContentTypes)) {
|
|
67
67
|
const uid = addNamespace(rawCtName, namespace);
|
|
68
68
|
|
|
69
69
|
if (has(uid, contentTypes)) {
|
|
@@ -48,7 +48,7 @@ const controllersRegistry = () => {
|
|
|
48
48
|
const filteredControllers = pickBy((_, uid) => hasNamespace(uid, namespace))(controllers);
|
|
49
49
|
|
|
50
50
|
const map = {};
|
|
51
|
-
for (const uid
|
|
51
|
+
for (const uid of Object.keys(filteredControllers)) {
|
|
52
52
|
Object.defineProperty(map, uid, {
|
|
53
53
|
enumerable: true,
|
|
54
54
|
get: () => {
|
|
@@ -78,7 +78,7 @@ const controllersRegistry = () => {
|
|
|
78
78
|
* @returns
|
|
79
79
|
*/
|
|
80
80
|
add(namespace, newControllers) {
|
|
81
|
-
for (const controllerName
|
|
81
|
+
for (const controllerName of Object.keys(newControllers)) {
|
|
82
82
|
const controller = newControllers[controllerName];
|
|
83
83
|
const uid = addNamespace(controllerName, namespace);
|
|
84
84
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { has } = require('lodash/fp');
|
|
4
|
+
|
|
5
|
+
const ALLOWED_TYPES = [
|
|
6
|
+
'biginteger',
|
|
7
|
+
'boolean',
|
|
8
|
+
'date',
|
|
9
|
+
'datetime',
|
|
10
|
+
'decimal',
|
|
11
|
+
'email',
|
|
12
|
+
'enumeration',
|
|
13
|
+
'float',
|
|
14
|
+
'integer',
|
|
15
|
+
'json',
|
|
16
|
+
'password',
|
|
17
|
+
'richtext',
|
|
18
|
+
'string',
|
|
19
|
+
'text',
|
|
20
|
+
'time',
|
|
21
|
+
'uid',
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const customFieldsRegistry = (strapi) => {
|
|
25
|
+
const customFields = {};
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
getAll() {
|
|
29
|
+
return customFields;
|
|
30
|
+
},
|
|
31
|
+
get(customField) {
|
|
32
|
+
const registeredCustomField = customFields[customField];
|
|
33
|
+
if (!registeredCustomField) {
|
|
34
|
+
throw new Error(`Could not find Custom Field: ${customField}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return registeredCustomField;
|
|
38
|
+
},
|
|
39
|
+
add(customField) {
|
|
40
|
+
const customFieldList = Array.isArray(customField) ? customField : [customField];
|
|
41
|
+
|
|
42
|
+
for (const cf of customFieldList) {
|
|
43
|
+
if (!has('name', cf) || !has('type', cf)) {
|
|
44
|
+
throw new Error(`Custom fields require a 'name' and 'type' key`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const { name, plugin, type } = cf;
|
|
48
|
+
if (!ALLOWED_TYPES.includes(type)) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Custom field type: '${type}' is not a valid Strapi type or it can't be used with a Custom Field`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const isValidObjectKey = /^(?![0-9])[a-zA-Z0-9$_-]+$/g;
|
|
55
|
+
if (!isValidObjectKey.test(name)) {
|
|
56
|
+
throw new Error(`Custom field name: '${name}' is not a valid object key`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// When no plugin is specified, or it isn't found in Strapi, default to global
|
|
60
|
+
const uid = strapi.plugin(plugin) ? `plugin::${plugin}.${name}` : `global::${name}`;
|
|
61
|
+
|
|
62
|
+
if (has(uid, customFields)) {
|
|
63
|
+
throw new Error(`Custom field: '${uid}' has already been registered`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
customFields[uid] = cf;
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
module.exports = customFieldsRegistry;
|
|
@@ -54,8 +54,8 @@ const middlewaresRegistry = () => {
|
|
|
54
54
|
* @param {{ [key: string]: Middleware }} newMiddlewares
|
|
55
55
|
* @returns
|
|
56
56
|
*/
|
|
57
|
-
add(namespace, rawMiddlewares) {
|
|
58
|
-
for (const middlewareName
|
|
57
|
+
add(namespace, rawMiddlewares = {}) {
|
|
58
|
+
for (const middlewareName of Object.keys(rawMiddlewares)) {
|
|
59
59
|
const middleware = rawMiddlewares[middlewareName];
|
|
60
60
|
const uid = addNamespace(middlewareName, namespace);
|
|
61
61
|
|
|
@@ -55,7 +55,7 @@ const policiesRegistry = () => {
|
|
|
55
55
|
* @returns
|
|
56
56
|
*/
|
|
57
57
|
add(namespace, newPolicies) {
|
|
58
|
-
for (const policyName
|
|
58
|
+
for (const policyName of Object.keys(newPolicies)) {
|
|
59
59
|
const policy = newPolicies[policyName];
|
|
60
60
|
const uid = addNamespace(policyName, namespace);
|
|
61
61
|
|
|
@@ -8,7 +8,7 @@ const { addNamespace, hasNamespace } = require('../utils');
|
|
|
8
8
|
* @typedef {import('./services').ServiceFactory} ServiceFactory
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const servicesRegistry = strapi => {
|
|
11
|
+
const servicesRegistry = (strapi) => {
|
|
12
12
|
const services = {};
|
|
13
13
|
const instantiatedServices = {};
|
|
14
14
|
|
|
@@ -48,7 +48,7 @@ const servicesRegistry = strapi => {
|
|
|
48
48
|
|
|
49
49
|
// create lazy accessor to avoid instantiating the services;
|
|
50
50
|
const map = {};
|
|
51
|
-
for (const uid
|
|
51
|
+
for (const uid of Object.keys(filteredServices)) {
|
|
52
52
|
Object.defineProperty(map, uid, {
|
|
53
53
|
enumerable: true,
|
|
54
54
|
get: () => {
|
|
@@ -78,7 +78,7 @@ const servicesRegistry = strapi => {
|
|
|
78
78
|
* @returns
|
|
79
79
|
*/
|
|
80
80
|
add(namespace, newServices) {
|
|
81
|
-
for (const serviceName
|
|
81
|
+
for (const serviceName of Object.keys(newServices)) {
|
|
82
82
|
const service = newServices[serviceName];
|
|
83
83
|
const uid = addNamespace(serviceName, namespace);
|
|
84
84
|
|
package/lib/core/utils.js
CHANGED
|
@@ -7,25 +7,22 @@ const hasNamespace = (name, namespace) => {
|
|
|
7
7
|
|
|
8
8
|
if (namespace.endsWith('::')) {
|
|
9
9
|
return name.startsWith(namespace);
|
|
10
|
-
} else {
|
|
11
|
-
return name.startsWith(`${namespace}.`);
|
|
12
10
|
}
|
|
11
|
+
return name.startsWith(`${namespace}.`);
|
|
13
12
|
};
|
|
14
13
|
|
|
15
14
|
const addNamespace = (name, namespace) => {
|
|
16
15
|
if (namespace.endsWith('::')) {
|
|
17
16
|
return `${namespace}${name}`;
|
|
18
|
-
} else {
|
|
19
|
-
return `${namespace}.${name}`;
|
|
20
17
|
}
|
|
18
|
+
return `${namespace}.${name}`;
|
|
21
19
|
};
|
|
22
20
|
|
|
23
21
|
const removeNamespace = (name, namespace) => {
|
|
24
22
|
if (namespace.endsWith('::')) {
|
|
25
23
|
return name.replace(namespace, '');
|
|
26
|
-
} else {
|
|
27
|
-
return name.replace(`${namespace}.`, '');
|
|
28
24
|
}
|
|
25
|
+
return name.replace(`${namespace}.`, '');
|
|
29
26
|
};
|
|
30
27
|
|
|
31
28
|
module.exports = {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { isNil, isPlainObject } = require('lodash/fp');
|
|
4
4
|
const { parseMultipartData } = require('@strapi/utils');
|
|
5
5
|
|
|
6
|
-
const parseBody = ctx => {
|
|
6
|
+
const parseBody = (ctx) => {
|
|
7
7
|
if (ctx.is('multipart')) {
|
|
8
8
|
return parseMultipartData(ctx);
|
|
9
9
|
}
|
|
@@ -26,7 +26,7 @@ const transformResponse = (resource, meta = {}, { contentType } = {}) => {
|
|
|
26
26
|
|
|
27
27
|
const transformComponent = (data, component) => {
|
|
28
28
|
if (Array.isArray(data)) {
|
|
29
|
-
return data.map(datum => transformComponent(datum, component));
|
|
29
|
+
return data.map((datum) => transformComponent(datum, component));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
const res = transformEntry(data, component);
|
|
@@ -45,7 +45,7 @@ const transformEntry = (entry, type) => {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
if (Array.isArray(entry)) {
|
|
48
|
-
return entry.map(singleEntry => transformEntry(singleEntry, type));
|
|
48
|
+
return entry.map((singleEntry) => transformEntry(singleEntry, type));
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
if (!isPlainObject(entry)) {
|
|
@@ -56,7 +56,7 @@ const transformEntry = (entry, type) => {
|
|
|
56
56
|
|
|
57
57
|
const attributeValues = {};
|
|
58
58
|
|
|
59
|
-
for (const key
|
|
59
|
+
for (const key of Object.keys(properties)) {
|
|
60
60
|
const property = properties[key];
|
|
61
61
|
const attribute = type && type.attributes[key];
|
|
62
62
|
|
|
@@ -71,7 +71,7 @@ const transformEntry = (entry, type) => {
|
|
|
71
71
|
attributeValues[key] = property;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
attributeValues[key] = property.map(subProperty => {
|
|
74
|
+
attributeValues[key] = property.map((subProperty) => {
|
|
75
75
|
return transformComponent(subProperty, strapi.components[subProperty.__component]);
|
|
76
76
|
});
|
|
77
77
|
} else if (attribute && attribute.type === 'media') {
|
|
@@ -12,11 +12,14 @@ export interface SingleTypeService extends BaseService {
|
|
|
12
12
|
|
|
13
13
|
export interface CollectionTypeService extends BaseService {
|
|
14
14
|
find?(params: object): Promise<Entity[]> | Entity;
|
|
15
|
-
findOne?(entityId: string,params: object): Promise<Entity> | Entity;
|
|
15
|
+
findOne?(entityId: string, params: object): Promise<Entity> | Entity;
|
|
16
16
|
create?(params: object): Promise<Entity> | Entity;
|
|
17
|
-
update?(entityId: string,params: object): Promise<Entity> | Entity;
|
|
18
|
-
delete?(entityId: string,params: object): Promise<Entity> | Entity;
|
|
17
|
+
update?(entityId: string, params: object): Promise<Entity> | Entity;
|
|
18
|
+
delete?(entityId: string, params: object): Promise<Entity> | Entity;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export type Service = SingleTypeService | CollectionTypeService;
|
|
22
22
|
|
|
23
|
+
export type GenericService = Partial<Service> & {
|
|
24
|
+
[method: string | number | symbol]: (...args: any) => any;
|
|
25
|
+
};
|
|
@@ -21,7 +21,7 @@ const getLimitConfigDefaults = () => ({
|
|
|
21
21
|
const shouldApplyMaxLimit = (limit, maxLimit = null, { isPagedPagination = false } = {}) =>
|
|
22
22
|
(!isPagedPagination && limit === -1) || (maxLimit && limit > maxLimit);
|
|
23
23
|
|
|
24
|
-
const shouldCount = params => {
|
|
24
|
+
const shouldCount = (params) => {
|
|
25
25
|
if (has('pagination.withCount', params)) {
|
|
26
26
|
const { withCount } = params.pagination;
|
|
27
27
|
|
|
@@ -45,10 +45,10 @@ const shouldCount = params => {
|
|
|
45
45
|
return Boolean(strapi.config.get('api.rest.withCount', true));
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
const isOffsetPagination = pagination => has('start', pagination) || has('limit', pagination);
|
|
49
|
-
const isPagedPagination = pagination => has('page', pagination) || has('pageSize', pagination);
|
|
48
|
+
const isOffsetPagination = (pagination) => has('start', pagination) || has('limit', pagination);
|
|
49
|
+
const isPagedPagination = (pagination) => has('page', pagination) || has('pageSize', pagination);
|
|
50
50
|
|
|
51
|
-
const getPaginationInfo = params => {
|
|
51
|
+
const getPaginationInfo = (params) => {
|
|
52
52
|
const { defaultLimit, maxLimit } = getLimitConfigDefaults();
|
|
53
53
|
|
|
54
54
|
const { pagination } = params;
|
|
@@ -90,7 +90,7 @@ const getPaginationInfo = params => {
|
|
|
90
90
|
};
|
|
91
91
|
};
|
|
92
92
|
|
|
93
|
-
const convertPagedToStartLimit = pagination => {
|
|
93
|
+
const convertPagedToStartLimit = (pagination) => {
|
|
94
94
|
if (isPagedPagination(pagination)) {
|
|
95
95
|
const { page, pageSize } = pagination;
|
|
96
96
|
return {
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { propOr } = require('lodash/fp');
|
|
4
|
+
|
|
3
5
|
const { ValidationError } = require('@strapi/utils').errors;
|
|
6
|
+
const {
|
|
7
|
+
hasDraftAndPublish,
|
|
8
|
+
constants: { PUBLISHED_AT_ATTRIBUTE },
|
|
9
|
+
} = require('@strapi/utils').contentTypes;
|
|
10
|
+
|
|
11
|
+
const setPublishedAt = (data) => {
|
|
12
|
+
data[PUBLISHED_AT_ATTRIBUTE] = propOr(new Date(), PUBLISHED_AT_ATTRIBUTE, data);
|
|
13
|
+
};
|
|
4
14
|
|
|
5
15
|
/**
|
|
6
16
|
* Returns a single type service to handle default core-api actions
|
|
@@ -27,7 +37,7 @@ const createSingleTypeService = ({ contentType }) => {
|
|
|
27
37
|
* @return {Promise}
|
|
28
38
|
*/
|
|
29
39
|
async createOrUpdate({ data, ...params } = {}) {
|
|
30
|
-
const entity = await this.find(params);
|
|
40
|
+
const entity = await this.find({ ...params, publicationState: 'preview' });
|
|
31
41
|
|
|
32
42
|
if (!entity) {
|
|
33
43
|
const count = await strapi.query(uid).count();
|
|
@@ -35,6 +45,9 @@ const createSingleTypeService = ({ contentType }) => {
|
|
|
35
45
|
throw new ValidationError('singleType.alreadyExists');
|
|
36
46
|
}
|
|
37
47
|
|
|
48
|
+
if (hasDraftAndPublish(contentType)) {
|
|
49
|
+
setPublishedAt(data);
|
|
50
|
+
}
|
|
38
51
|
return strapi.entityService.create(uid, { ...params, data });
|
|
39
52
|
}
|
|
40
53
|
|
package/lib/factories.js
CHANGED
|
@@ -12,7 +12,7 @@ const createCoreController = (uid, cfg = {}) => {
|
|
|
12
12
|
contentType: strapi.contentType(uid),
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
const userCtrl = typeof cfg === 'function' ? cfg({ strapi }) : cfg;
|
|
16
16
|
|
|
17
17
|
for (const methodName of Object.keys(baseController)) {
|
|
18
18
|
if (userCtrl[methodName] === undefined) {
|
|
@@ -31,7 +31,7 @@ const createCoreService = (uid, cfg = {}) => {
|
|
|
31
31
|
contentType: strapi.contentType(uid),
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
const userService = typeof cfg === 'function' ? cfg({ strapi }) : cfg;
|
|
35
35
|
|
|
36
36
|
for (const methodName of Object.keys(baseService)) {
|
|
37
37
|
if (userService[methodName] === undefined) {
|
|
@@ -58,15 +58,15 @@ const createCoreRouter = (uid, cfg = {}) => {
|
|
|
58
58
|
|
|
59
59
|
const defaultRoutes = createRoutes({ contentType });
|
|
60
60
|
|
|
61
|
-
Object.keys(defaultRoutes).forEach(routeName => {
|
|
61
|
+
Object.keys(defaultRoutes).forEach((routeName) => {
|
|
62
62
|
const defaultRoute = defaultRoutes[routeName];
|
|
63
63
|
|
|
64
64
|
Object.assign(defaultRoute.config, config[routeName] || {});
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
const selectedRoutes = pipe(
|
|
68
|
-
routes => (except ? omit(except, routes) : routes),
|
|
69
|
-
routes => (only ? pick(only, routes) : routes)
|
|
68
|
+
(routes) => (except ? omit(except, routes) : routes),
|
|
69
|
+
(routes) => (only ? pick(only, routes) : routes)
|
|
70
70
|
)(defaultRoutes);
|
|
71
71
|
|
|
72
72
|
routes = Object.values(selectedRoutes);
|
|
@@ -8,13 +8,13 @@ const _ = require('lodash');
|
|
|
8
8
|
* @param {boolean} useFileNameAsKey - wethear to skip the last path key
|
|
9
9
|
*/
|
|
10
10
|
module.exports = (filePath, useFileNameAsKey = true) => {
|
|
11
|
-
|
|
11
|
+
const cleanPath = filePath.startsWith('./') ? filePath.slice(2) : filePath;
|
|
12
12
|
|
|
13
13
|
const prop = cleanPath
|
|
14
14
|
.replace(/(\.settings|\.json|\.js)/g, '')
|
|
15
15
|
.toLowerCase()
|
|
16
16
|
.split('/')
|
|
17
|
-
.map(p => _.trimStart(p, '.'))
|
|
17
|
+
.map((p) => _.trimStart(p, '.'))
|
|
18
18
|
.join('.')
|
|
19
19
|
.split('.');
|
|
20
20
|
|
package/lib/load/load-files.js
CHANGED
|
@@ -4,7 +4,7 @@ const path = require('path');
|
|
|
4
4
|
const _ = require('lodash');
|
|
5
5
|
const fse = require('fs-extra');
|
|
6
6
|
|
|
7
|
-
const { importDefault } = require('
|
|
7
|
+
const { importDefault } = require('@strapi/utils');
|
|
8
8
|
const glob = require('./glob');
|
|
9
9
|
const filePathToPath = require('./filepath-to-prop-path');
|
|
10
10
|
|
|
@@ -26,7 +26,7 @@ const loadFiles = async (
|
|
|
26
26
|
const root = {};
|
|
27
27
|
const files = await glob(pattern, { cwd: dir, ...globArgs });
|
|
28
28
|
|
|
29
|
-
for (
|
|
29
|
+
for (const file of files) {
|
|
30
30
|
const absolutePath = path.resolve(dir, file);
|
|
31
31
|
|
|
32
32
|
// load module
|
package/lib/load/package-path.js
CHANGED
|
@@ -6,4 +6,4 @@ const path = require('path');
|
|
|
6
6
|
* Returns the path to a node modules root directory (not the main file path)
|
|
7
7
|
* @param {string} moduleName - name of a node module
|
|
8
8
|
*/
|
|
9
|
-
module.exports = moduleName => path.dirname(require.resolve(`${moduleName}/package.json`));
|
|
9
|
+
module.exports = (moduleName) => path.dirname(require.resolve(`${moduleName}/package.json`));
|