@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.
Files changed (135) hide show
  1. package/README.md +25 -12
  2. package/bin/strapi.js +29 -26
  3. package/lib/Strapi.js +37 -16
  4. package/lib/commands/admin-create.js +3 -6
  5. package/lib/commands/admin-reset.js +1 -1
  6. package/lib/commands/build.js +1 -1
  7. package/lib/commands/builders/admin.js +2 -1
  8. package/lib/commands/builders/typescript.js +2 -2
  9. package/lib/commands/configurationDump.js +4 -4
  10. package/lib/commands/configurationRestore.js +5 -4
  11. package/lib/commands/console.js +1 -1
  12. package/lib/commands/content-types/list.js +2 -2
  13. package/lib/commands/controllers/list.js +2 -2
  14. package/lib/commands/develop.js +16 -10
  15. package/lib/commands/hooks/list.js +2 -2
  16. package/lib/commands/install.js +4 -4
  17. package/lib/commands/middlewares/list.js +2 -2
  18. package/lib/commands/new.js +1 -1
  19. package/lib/commands/opt-in-telemetry.js +14 -15
  20. package/lib/commands/opt-out-telemetry.js +5 -5
  21. package/lib/commands/policies/list.js +2 -2
  22. package/lib/commands/routes/list.js +3 -3
  23. package/lib/commands/services/list.js +2 -2
  24. package/lib/commands/start.js +1 -0
  25. package/lib/commands/ts/generate-types.js +1 -1
  26. package/lib/commands/uninstall.js +4 -4
  27. package/lib/commands/watchAdmin.js +1 -1
  28. package/lib/compile.js +1 -1
  29. package/lib/container.js +1 -1
  30. package/lib/core/app-configuration/config-loader.js +2 -2
  31. package/lib/core/app-configuration/load-config-file.js +4 -6
  32. package/lib/core/bootstrap.js +1 -1
  33. package/lib/core/domain/component/validator.js +3 -9
  34. package/lib/core/domain/content-type/index.js +3 -3
  35. package/lib/core/domain/content-type/validator.js +9 -23
  36. package/lib/core/domain/module/index.js +1 -1
  37. package/lib/core/domain/module/validation.js +3 -4
  38. package/lib/core/loaders/admin.js +1 -1
  39. package/lib/core/loaders/apis.js +26 -34
  40. package/lib/core/loaders/components.js +2 -2
  41. package/lib/core/loaders/middlewares.js +2 -3
  42. package/lib/core/loaders/plugins/get-enabled-plugins.js +10 -8
  43. package/lib/core/loaders/plugins/index.js +12 -13
  44. package/lib/core/loaders/policies.js +1 -2
  45. package/lib/core/loaders/sanitizers.js +1 -1
  46. package/lib/core/loaders/src-index.js +3 -5
  47. package/lib/core/registries/apis.js +1 -1
  48. package/lib/core/registries/config.js +1 -1
  49. package/lib/core/registries/content-types.js +3 -3
  50. package/lib/core/registries/controllers.js +2 -2
  51. package/lib/core/registries/custom-fields.js +72 -0
  52. package/lib/core/registries/hooks.js +1 -1
  53. package/lib/core/registries/middlewares.js +2 -2
  54. package/lib/core/registries/modules.js +1 -1
  55. package/lib/core/registries/plugins.js +1 -1
  56. package/lib/core/registries/policies.js +1 -1
  57. package/lib/core/registries/services.js +3 -3
  58. package/lib/core/utils.js +3 -6
  59. package/lib/core-api/controller/transform.js +5 -5
  60. package/lib/core-api/service/collection-type.js +1 -1
  61. package/lib/core-api/service/index.d.ts +6 -3
  62. package/lib/core-api/service/pagination.js +5 -5
  63. package/lib/core-api/service/single-type.js +14 -1
  64. package/lib/factories.js +5 -5
  65. package/lib/load/filepath-to-prop-path.js +2 -2
  66. package/lib/load/load-files.js +2 -2
  67. package/lib/load/package-path.js +1 -1
  68. package/lib/middlewares/body.js +10 -3
  69. package/lib/middlewares/compression.js +1 -1
  70. package/lib/middlewares/cors.js +3 -10
  71. package/lib/middlewares/favicon.js +16 -3
  72. package/lib/middlewares/ip.js +1 -1
  73. package/lib/middlewares/logger.js +4 -1
  74. package/lib/middlewares/powered-by.js +1 -1
  75. package/lib/middlewares/query.js +8 -2
  76. package/lib/middlewares/response-time.js +1 -1
  77. package/lib/middlewares/responses.js +1 -1
  78. package/lib/middlewares/security.js +22 -16
  79. package/lib/middlewares/session.js +2 -2
  80. package/lib/migrations/draft-publish.js +1 -5
  81. package/lib/services/auth/index.js +5 -4
  82. package/lib/services/content-api/index.js +74 -0
  83. package/lib/services/content-api/permissions/engine.js +5 -0
  84. package/lib/services/content-api/permissions/index.js +148 -0
  85. package/lib/services/content-api/permissions/providers/action.js +19 -0
  86. package/lib/services/content-api/permissions/providers/condition.js +19 -0
  87. package/lib/services/content-api/permissions/providers/index.js +9 -0
  88. package/lib/services/core-store.js +4 -4
  89. package/lib/services/cron.js +1 -1
  90. package/lib/services/custom-fields.js +11 -0
  91. package/lib/services/entity-service/components.js +51 -54
  92. package/lib/services/entity-service/index.js +117 -93
  93. package/lib/services/entity-service/params.js +1 -87
  94. package/lib/services/entity-validator/index.js +284 -122
  95. package/lib/services/entity-validator/validators.js +18 -15
  96. package/lib/services/errors.js +10 -10
  97. package/lib/services/event-hub.js +1 -0
  98. package/lib/services/fs.js +1 -1
  99. package/lib/services/metrics/admin-user-hash.js +15 -0
  100. package/lib/services/metrics/index.js +12 -13
  101. package/lib/services/metrics/is-truthy.js +1 -1
  102. package/lib/services/metrics/middleware.js +2 -2
  103. package/lib/services/metrics/sender.js +22 -12
  104. package/lib/services/metrics/stringify-deep.js +1 -1
  105. package/lib/services/request-context.js +17 -0
  106. package/lib/services/server/admin-api.js +1 -1
  107. package/lib/services/server/compose-endpoint.js +7 -7
  108. package/lib/services/server/content-api.js +1 -1
  109. package/lib/services/server/http-server.js +9 -9
  110. package/lib/services/server/index.js +7 -4
  111. package/lib/services/server/koa.js +9 -12
  112. package/lib/services/server/middleware.js +3 -2
  113. package/lib/services/server/policy.js +1 -1
  114. package/lib/services/server/register-middlewares.js +6 -8
  115. package/lib/services/server/register-routes.js +13 -13
  116. package/lib/services/server/routing.js +11 -26
  117. package/lib/services/utils/upload-files.js +4 -4
  118. package/lib/services/webhook-runner.js +8 -7
  119. package/lib/services/webhook-store.js +3 -2
  120. package/lib/services/worker-queue.js +3 -2
  121. package/lib/types/core/attributes/common.d.ts +3 -0
  122. package/lib/types/core/strapi/index.d.ts +50 -10
  123. package/lib/types/factories.d.ts +4 -4
  124. package/lib/utils/addSlash.js +7 -6
  125. package/lib/utils/convert-custom-field-type.js +22 -0
  126. package/lib/utils/ee.js +1 -1
  127. package/lib/utils/index.js +0 -2
  128. package/lib/utils/open-browser.js +1 -1
  129. package/lib/utils/run-checks.js +4 -4
  130. package/lib/utils/signals.js +2 -2
  131. package/lib/utils/startup-logger.js +2 -2
  132. package/lib/utils/success.js +2 -2
  133. package/lib/utils/update-notifier/index.js +4 -4
  134. package/package.json +21 -20
  135. 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
- let detailedDeclaration = pick(['enabled'], declaration);
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
- for (const dep in strapi.config.get('info.dependencies', {})) {
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 in plugins) {
37
+ for (const pluginName of Object.keys(plugins)) {
38
38
  const plugin = plugins[pluginName];
39
39
  // first: load json schema
40
- for (const ctName in plugin.contentTypes) {
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 = Object.assign(
44
- {},
45
- plugin.contentTypes[ctName].schema,
46
- extendedSchema
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 in plugins) {
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 in enabledPlugins) {
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 in plugins) {
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) {
@@ -1,5 +1,5 @@
1
1
  'use strict';
2
2
 
3
- module.exports = strapi => {
3
+ module.exports = (strapi) => {
4
4
  strapi.container.get('sanitizers').set('content-api', { input: [], output: [] });
5
5
  };
@@ -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
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  const { has } = require('lodash/fp');
4
4
 
5
- const apisRegistry = strapi => {
5
+ const apisRegistry = (strapi) => {
6
6
  const apis = {};
7
7
 
8
8
  return {
@@ -3,7 +3,7 @@
3
3
  const _ = require('lodash');
4
4
 
5
5
  module.exports = (initialConfig = {}) => {
6
- const _config = Object.assign({}, initialConfig); // not deep clone because it would break some 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 in contentTypes) {
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 in newContentTypes) {
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 in filteredControllers) {
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 in newControllers) {
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,7 +54,7 @@ const hooksRegistry = () => {
54
54
  * @returns
55
55
  */
56
56
  add(namespace, hooks) {
57
- for (const hookName in hooks) {
57
+ for (const hookName of Object.keys(hooks)) {
58
58
  const hook = hooks[hookName];
59
59
  const uid = addNamespace(hookName, namespace);
60
60
 
@@ -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 in rawMiddlewares) {
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
 
@@ -3,7 +3,7 @@
3
3
  const { pickBy, has } = require('lodash/fp');
4
4
  const { createModule } = require('../domain/module');
5
5
 
6
- const modulesRegistry = strapi => {
6
+ const modulesRegistry = (strapi) => {
7
7
  const modules = {};
8
8
 
9
9
  return {
@@ -2,7 +2,7 @@
2
2
 
3
3
  const { has } = require('lodash/fp');
4
4
 
5
- const pluginsRegistry = strapi => {
5
+ const pluginsRegistry = (strapi) => {
6
6
  const plugins = {};
7
7
 
8
8
  return {
@@ -55,7 +55,7 @@ const policiesRegistry = () => {
55
55
  * @returns
56
56
  */
57
57
  add(namespace, newPolicies) {
58
- for (const policyName in newPolicies) {
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 in filteredServices) {
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 in newServices) {
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 in properties) {
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') {
@@ -14,7 +14,7 @@ const {
14
14
  transformPaginationResponse,
15
15
  } = require('./pagination');
16
16
 
17
- const setPublishedAt = data => {
17
+ const setPublishedAt = (data) => {
18
18
  data[PUBLISHED_AT_ATTRIBUTE] = propOr(new Date(), PUBLISHED_AT_ATTRIBUTE, data);
19
19
  };
20
20
 
@@ -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
- let userCtrl = typeof cfg === 'function' ? cfg({ strapi }) : cfg;
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
- let userService = typeof cfg === 'function' ? cfg({ strapi }) : cfg;
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
- let cleanPath = filePath.startsWith('./') ? filePath.slice(2) : filePath;
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
 
@@ -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('../utils');
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 (let file of files) {
29
+ for (const file of files) {
30
30
  const absolutePath = path.resolve(dir, file);
31
31
 
32
32
  // load module
@@ -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`));