@strapi/strapi 4.3.4 → 4.4.0-alpha.0

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 (115) hide show
  1. package/README.md +1 -1
  2. package/bin/strapi.js +29 -26
  3. package/lib/Strapi.js +17 -9
  4. package/lib/commands/admin-create.js +2 -5
  5. package/lib/commands/admin-reset.js +1 -1
  6. package/lib/commands/build.js +1 -1
  7. package/lib/commands/builders/admin.js +1 -1
  8. package/lib/commands/builders/typescript.js +2 -2
  9. package/lib/commands/configurationDump.js +3 -3
  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 +12 -13
  20. package/lib/commands/opt-out-telemetry.js +3 -3
  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 +3 -3
  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 +2 -2
  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 +22 -30
  40. package/lib/core/loaders/components.js +2 -2
  41. package/lib/core/loaders/middlewares.js +1 -1
  42. package/lib/core/loaders/plugins/get-enabled-plugins.js +7 -7
  43. package/lib/core/loaders/plugins/index.js +7 -8
  44. package/lib/core/loaders/sanitizers.js +1 -1
  45. package/lib/core/loaders/src-index.js +2 -2
  46. package/lib/core/registries/apis.js +1 -1
  47. package/lib/core/registries/config.js +1 -1
  48. package/lib/core/registries/content-types.js +1 -1
  49. package/lib/core/registries/custom-fields.js +54 -0
  50. package/lib/core/registries/modules.js +1 -1
  51. package/lib/core/registries/plugins.js +1 -1
  52. package/lib/core/registries/services.js +1 -1
  53. package/lib/core/utils.js +3 -6
  54. package/lib/core-api/controller/transform.js +4 -4
  55. package/lib/core-api/service/collection-type.js +1 -1
  56. package/lib/core-api/service/index.d.ts +6 -3
  57. package/lib/core-api/service/pagination.js +5 -5
  58. package/lib/factories.js +5 -5
  59. package/lib/load/filepath-to-prop-path.js +2 -2
  60. package/lib/load/load-files.js +1 -1
  61. package/lib/load/package-path.js +1 -1
  62. package/lib/middlewares/body.js +10 -3
  63. package/lib/middlewares/compression.js +1 -1
  64. package/lib/middlewares/cors.js +3 -10
  65. package/lib/middlewares/ip.js +1 -1
  66. package/lib/middlewares/logger.js +4 -1
  67. package/lib/middlewares/powered-by.js +1 -1
  68. package/lib/middlewares/query.js +8 -2
  69. package/lib/middlewares/response-time.js +1 -1
  70. package/lib/middlewares/responses.js +1 -1
  71. package/lib/middlewares/security.js +22 -16
  72. package/lib/middlewares/session.js +2 -2
  73. package/lib/migrations/draft-publish.js +1 -5
  74. package/lib/services/auth/index.js +1 -3
  75. package/lib/services/core-store.js +4 -4
  76. package/lib/services/custom-fields.js +11 -0
  77. package/lib/services/entity-service/components.js +12 -18
  78. package/lib/services/entity-service/index.js +65 -51
  79. package/lib/services/entity-validator/index.js +134 -127
  80. package/lib/services/entity-validator/validators.js +18 -15
  81. package/lib/services/errors.js +6 -10
  82. package/lib/services/event-hub.js +1 -0
  83. package/lib/services/fs.js +1 -1
  84. package/lib/services/metrics/index.js +6 -9
  85. package/lib/services/metrics/is-truthy.js +1 -1
  86. package/lib/services/metrics/sender.js +4 -4
  87. package/lib/services/metrics/stringify-deep.js +1 -1
  88. package/lib/services/server/admin-api.js +1 -1
  89. package/lib/services/server/compose-endpoint.js +7 -7
  90. package/lib/services/server/content-api.js +1 -1
  91. package/lib/services/server/http-server.js +9 -9
  92. package/lib/services/server/index.js +4 -4
  93. package/lib/services/server/koa.js +9 -12
  94. package/lib/services/server/middleware.js +1 -1
  95. package/lib/services/server/policy.js +1 -1
  96. package/lib/services/server/register-middlewares.js +6 -8
  97. package/lib/services/server/register-routes.js +11 -11
  98. package/lib/services/server/routing.js +11 -26
  99. package/lib/services/utils/upload-files.js +3 -3
  100. package/lib/services/webhook-runner.js +8 -7
  101. package/lib/services/webhook-store.js +3 -2
  102. package/lib/services/worker-queue.js +1 -0
  103. package/lib/types/core/strapi/index.d.ts +4 -3
  104. package/lib/types/factories.d.ts +3 -3
  105. package/lib/utils/addSlash.js +3 -3
  106. package/lib/utils/convert-custom-field-type.js +22 -0
  107. package/lib/utils/ee.js +1 -1
  108. package/lib/utils/import-default.js +1 -1
  109. package/lib/utils/open-browser.js +1 -1
  110. package/lib/utils/run-checks.js +4 -4
  111. package/lib/utils/signals.js +2 -2
  112. package/lib/utils/startup-logger.js +2 -2
  113. package/lib/utils/success.js +1 -1
  114. package/lib/utils/update-notifier/index.js +4 -4
  115. package/package.json +15 -15
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)) {
@@ -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]: <T = any>(...args: any) => T;
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 {
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
 
@@ -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`));
@@ -23,12 +23,19 @@ function getFiles(ctx) {
23
23
  /**
24
24
  * @type {import('./').MiddlewareFactory}
25
25
  */
26
- module.exports = config => {
26
+
27
+ module.exports = (config, { strapi }) => {
27
28
  const bodyConfig = defaultsDeep(defaults, config);
28
29
 
30
+ let gqlEndpoint;
31
+ if (strapi.plugin('graphql')) {
32
+ const { config: gqlConfig } = strapi.plugin('graphql');
33
+ gqlEndpoint = gqlConfig('endpoint');
34
+ }
35
+
29
36
  return async (ctx, next) => {
30
37
  // TODO: find a better way later
31
- if (ctx.url === '/graphql') {
38
+ if (gqlEndpoint && ctx.url === gqlEndpoint) {
32
39
  await next();
33
40
  } else {
34
41
  try {
@@ -64,7 +71,7 @@ module.exports = config => {
64
71
  if (files) {
65
72
  if (Array.isArray(files)) {
66
73
  // not awaiting to not slow the request
67
- Promise.all(files.map(file => fse.remove(file.path)));
74
+ Promise.all(files.map((file) => fse.remove(file.path)));
68
75
  } else if (files && files.path) {
69
76
  // not awaiting to not slow the request
70
77
  fse.remove(files.path);
@@ -5,4 +5,4 @@ const compress = require('koa-compress');
5
5
  /**
6
6
  * @type {import('./').MiddlewareFactory}
7
7
  */
8
- module.exports = config => compress(config);
8
+ module.exports = (config) => compress(config);
@@ -15,16 +15,9 @@ const defaults = {
15
15
  /**
16
16
  * @type {import('./').MiddlewareFactory}
17
17
  */
18
- module.exports = config => {
19
- const {
20
- origin,
21
- expose,
22
- maxAge,
23
- credentials,
24
- methods,
25
- headers,
26
- keepHeadersOnError,
27
- } = defaultsDeep(defaults, config);
18
+ module.exports = (config) => {
19
+ const { origin, expose, maxAge, credentials, methods, headers, keepHeadersOnError } =
20
+ defaultsDeep(defaults, config);
28
21
 
29
22
  return cors({
30
23
  async origin(ctx) {
@@ -5,4 +5,4 @@ const ip = require('koa-ip');
5
5
  /**
6
6
  * @type {import('./').MiddlewareFactory}
7
7
  */
8
- module.exports = config => ip(config);
8
+ module.exports = (config) => ip(config);
@@ -1,7 +1,10 @@
1
1
  'use strict';
2
+
3
+ /* eslint-disable no-nested-ternary */
4
+
2
5
  const chalk = require('chalk');
3
6
 
4
- const codeToColor = code => {
7
+ const codeToColor = (code) => {
5
8
  return code >= 500
6
9
  ? chalk.red(code)
7
10
  : code >= 400
@@ -9,7 +9,7 @@ const defaults = {
9
9
  /**
10
10
  * @type {import('./').MiddlewareFactory}
11
11
  */
12
- module.exports = config => {
12
+ module.exports = (config) => {
13
13
  const { poweredBy } = defaultsDeep(defaults, config);
14
14
 
15
15
  return async (ctx, next) => {
@@ -21,8 +21,14 @@ const addQsParser = (app, settings) => {
21
21
  */
22
22
  get() {
23
23
  const qstr = this.querystring;
24
- const cache = (this._querycache = this._querycache || {});
25
- return cache[qstr] || (cache[qstr] = qs.parse(qstr, settings));
24
+ this._querycache = this._querycache || {};
25
+ const cache = this._querycache;
26
+
27
+ if (!cache[qstr]) {
28
+ cache[qstr] = qs.parse(qstr, settings);
29
+ }
30
+
31
+ return cache[qstr];
26
32
  },
27
33
 
28
34
  /*
@@ -10,6 +10,6 @@ module.exports = () => {
10
10
  await next();
11
11
 
12
12
  const delta = Math.ceil(Date.now() - start);
13
- ctx.set('X-Response-Time', delta + 'ms');
13
+ ctx.set('X-Response-Time', `${delta}ms`);
14
14
  };
15
15
  };
@@ -9,7 +9,7 @@ module.exports = (config = {}) => {
9
9
  return async (ctx, next) => {
10
10
  await next();
11
11
 
12
- const status = ctx.status;
12
+ const { status } = ctx;
13
13
  const handler = prop(`handlers.${status}`, config);
14
14
 
15
15
  if (isFunction(handler)) {
@@ -30,22 +30,28 @@ const defaults = {
30
30
  /**
31
31
  * @type {import('./').MiddlewareFactory}
32
32
  */
33
- module.exports = config => (ctx, next) => {
34
- let helmetConfig = defaultsDeep(defaults, config);
35
33
 
36
- if (
37
- ctx.method === 'GET' &&
38
- ['/graphql', '/documentation'].some(str => ctx.path.startsWith(str))
39
- ) {
40
- helmetConfig = merge(helmetConfig, {
41
- contentSecurityPolicy: {
42
- directives: {
43
- 'script-src': ["'self'", "'unsafe-inline'", 'cdn.jsdelivr.net'],
44
- 'img-src': ["'self'", 'data:', 'cdn.jsdelivr.net', 'strapi.io'],
34
+ module.exports =
35
+ (config, { strapi }) =>
36
+ (ctx, next) => {
37
+ let helmetConfig = defaultsDeep(defaults, config);
38
+ const specialPaths = ['/documentation'];
39
+
40
+ if (strapi.plugin('graphql')) {
41
+ const { config: gqlConfig } = strapi.plugin('graphql');
42
+ specialPaths.push(gqlConfig('endpoint'));
43
+ }
44
+
45
+ if (ctx.method === 'GET' && specialPaths.some((str) => ctx.path.startsWith(str))) {
46
+ helmetConfig = merge(helmetConfig, {
47
+ contentSecurityPolicy: {
48
+ directives: {
49
+ 'script-src': ["'self'", "'unsafe-inline'", 'cdn.jsdelivr.net'],
50
+ 'img-src': ["'self'", 'data:', 'cdn.jsdelivr.net', 'strapi.io'],
51
+ },
45
52
  },
46
- },
47
- });
48
- }
53
+ });
54
+ }
49
55
 
50
- return helmet(helmetConfig)(ctx, next);
51
- };
56
+ return helmet(helmetConfig)(ctx, next);
57
+ };
@@ -12,12 +12,12 @@ const defaultConfig = {
12
12
  signed: true,
13
13
  rolling: false,
14
14
  renew: false,
15
- secure: process.env.NODE_ENV === 'production' ? true : false,
15
+ secure: process.env.NODE_ENV === 'production',
16
16
  sameSite: null,
17
17
  };
18
18
 
19
19
  module.exports = (userConfig, { strapi }) => {
20
- const keys = strapi.server.app.keys;
20
+ const { keys } = strapi.server.app;
21
21
  if (!isArray(keys) || isEmpty(keys) || keys.some(isEmpty)) {
22
22
  throw new Error(
23
23
  `App keys are required. Please set app.keys in config/server.js (ex: keys: ['myKeyA', 'myKeyB'])`
@@ -42,11 +42,7 @@ const disableDraftAndPublish = async ({ oldContentTypes, contentTypes }) => {
42
42
 
43
43
  // if d&p was disabled remove unpublish content before sync
44
44
  if (hasDraftAndPublish(oldContentType) && !hasDraftAndPublish(contentType)) {
45
- await strapi.db
46
- .queryBuilder(uid)
47
- .delete()
48
- .where({ published_at: null })
49
- .execute();
45
+ await strapi.db.queryBuilder(uid).delete().where({ published_at: null }).execute();
50
46
  }
51
47
  }
52
48
  };
@@ -8,7 +8,7 @@ const { UnauthorizedError } = require('@strapi/utils').errors;
8
8
  const INVALID_STRATEGY_MSG =
9
9
  'Invalid auth strategy. Expecting an object with properties {name: string, authenticate: function, verify: function}';
10
10
 
11
- const validStrategy = strategy => {
11
+ const validStrategy = (strategy) => {
12
12
  assert(has('authenticate', strategy), INVALID_STRATEGY_MSG);
13
13
  assert(typeof strategy.authenticate === 'function', INVALID_STRATEGY_MSG);
14
14
 
@@ -78,8 +78,6 @@ const createAuthentication = () => {
78
78
  if (typeof auth.strategy.verify === 'function') {
79
79
  return auth.strategy.verify(auth, config);
80
80
  }
81
-
82
- return;
83
81
  },
84
82
  };
85
83
  };
@@ -30,11 +30,11 @@ const createCoreStore = ({ db }) => {
30
30
  };
31
31
  };
32
32
 
33
- const store = function(defaultParams = {}) {
33
+ const store = function (defaultParams = {}) {
34
34
  return {
35
- get: params => store.get(mergeParams(defaultParams, params)),
36
- set: params => store.set(mergeParams(defaultParams, params)),
37
- delete: params => store.delete(mergeParams(defaultParams, params)),
35
+ get: (params) => store.get(mergeParams(defaultParams, params)),
36
+ set: (params) => store.set(mergeParams(defaultParams, params)),
37
+ delete: (params) => store.delete(mergeParams(defaultParams, params)),
38
38
  };
39
39
  };
40
40
 
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ const createCustomFields = strapi => {
4
+ return {
5
+ register(customField) {
6
+ strapi.container.get('custom-fields').add(customField);
7
+ },
8
+ };
9
+ };
10
+
11
+ module.exports = createCustomFields;
@@ -8,7 +8,7 @@ const { ApplicationError } = require('@strapi/utils').errors;
8
8
 
9
9
  const omitComponentData = (contentType, data) => {
10
10
  const { attributes } = contentType;
11
- const componentAttributes = Object.keys(attributes).filter(attributeName =>
11
+ const componentAttributes = Object.keys(attributes).filter((attributeName) =>
12
12
  contentTypesUtils.isComponentAttribute(attributes[attributeName])
13
13
  );
14
14
 
@@ -43,7 +43,7 @@ const createComponents = async (uid, data) => {
43
43
  }
44
44
 
45
45
  const components = await Promise.all(
46
- componentValue.map(value => createComponent(componentUID, value))
46
+ componentValue.map((value) => createComponent(componentUID, value))
47
47
  );
48
48
 
49
49
  // TODO: add order
@@ -129,7 +129,7 @@ const updateComponents = async (uid, entityToUpdate, data) => {
129
129
  }
130
130
 
131
131
  const components = await Promise.all(
132
- componentValue.map(value => updateOrCreateComponent(componentUID, value))
132
+ componentValue.map((value) => updateOrCreateComponent(componentUID, value))
133
133
  );
134
134
 
135
135
  componentBody[attributeName] = components.filter(_.negate(_.isNil)).map(({ id }, idx) => {
@@ -197,17 +197,11 @@ const deleteOldComponents = async (
197
197
  ) => {
198
198
  const previousValue = await strapi.query(uid).load(entityToUpdate, attributeName);
199
199
 
200
- const idsToKeep = _.castArray(componentValue)
201
- .filter(has('id'))
202
- .map(prop('id'))
203
- .map(toString);
200
+ const idsToKeep = _.castArray(componentValue).filter(has('id')).map(prop('id')).map(toString);
204
201
 
205
- const allIds = _.castArray(previousValue)
206
- .filter(has('id'))
207
- .map(prop('id'))
208
- .map(toString);
202
+ const allIds = _.castArray(previousValue).filter(has('id')).map(prop('id')).map(toString);
209
203
 
210
- idsToKeep.forEach(id => {
204
+ idsToKeep.forEach((id) => {
211
205
  if (!allIds.includes(id)) {
212
206
  throw new ApplicationError(
213
207
  `Some of the provided components in ${attributeName} are not related to the entity`
@@ -242,7 +236,7 @@ const deleteOldDZComponents = async (uid, entityToUpdate, attributeName, dynamic
242
236
  }));
243
237
 
244
238
  idsToKeep.forEach(({ id, __component }) => {
245
- if (!allIds.find(el => el.id === id && el.__component === __component)) {
239
+ if (!allIds.find((el) => el.id === id && el.__component === __component)) {
246
240
  const err = new Error(
247
241
  `Some of the provided components in ${attributeName} are not related to the entity`
248
242
  );
@@ -252,7 +246,7 @@ const deleteOldDZComponents = async (uid, entityToUpdate, attributeName, dynamic
252
246
  });
253
247
 
254
248
  const idsToDelete = allIds.reduce((acc, { id, __component }) => {
255
- if (!idsToKeep.find(el => el.id === id && el.__component === __component)) {
249
+ if (!idsToKeep.find((el) => el.id === id && el.__component === __component)) {
256
250
  acc.push({ id, __component });
257
251
  }
258
252
 
@@ -283,7 +277,7 @@ const deleteComponents = async (uid, entityToDelete) => {
283
277
  }
284
278
 
285
279
  if (Array.isArray(value)) {
286
- await Promise.all(value.map(subValue => deleteComponent(componentUID, subValue)));
280
+ await Promise.all(value.map((subValue) => deleteComponent(componentUID, subValue)));
287
281
  } else {
288
282
  await deleteComponent(componentUID, value);
289
283
  }
@@ -299,7 +293,7 @@ const deleteComponents = async (uid, entityToDelete) => {
299
293
  }
300
294
 
301
295
  if (Array.isArray(value)) {
302
- await Promise.all(value.map(subValue => deleteComponent(subValue.__component, subValue)));
296
+ await Promise.all(value.map((subValue) => deleteComponent(subValue.__component, subValue)));
303
297
  }
304
298
 
305
299
  continue;
@@ -307,9 +301,9 @@ const deleteComponents = async (uid, entityToDelete) => {
307
301
  }
308
302
  };
309
303
 
310
- /***************************
304
+ /** *************************
311
305
  Component queries
312
- ***************************/
306
+ ************************** */
313
307
 
314
308
  // components can have nested compos so this must be recursive
315
309
  const createComponent = async (uid, data) => {