@strapi/strapi 4.0.0-beta.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 (143) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +144 -0
  3. package/bin/strapi.js +186 -0
  4. package/lib/Strapi.js +470 -0
  5. package/lib/commands/admin-reset.js +51 -0
  6. package/lib/commands/build.js +56 -0
  7. package/lib/commands/configurationDump.js +50 -0
  8. package/lib/commands/configurationRestore.js +169 -0
  9. package/lib/commands/console.js +26 -0
  10. package/lib/commands/develop.js +157 -0
  11. package/lib/commands/generate-template.js +97 -0
  12. package/lib/commands/install.js +48 -0
  13. package/lib/commands/new.js +11 -0
  14. package/lib/commands/start.js +8 -0
  15. package/lib/commands/uninstall.js +68 -0
  16. package/lib/commands/watchAdmin.js +45 -0
  17. package/lib/container.js +45 -0
  18. package/lib/core/app-configuration/config-loader.js +20 -0
  19. package/lib/core/app-configuration/index.js +75 -0
  20. package/lib/core/app-configuration/load-config-file.js +43 -0
  21. package/lib/core/app-configuration/load-functions.js +28 -0
  22. package/lib/core/bootstrap.js +60 -0
  23. package/lib/core/domain/component/index.js +24 -0
  24. package/lib/core/domain/component/validator.js +29 -0
  25. package/lib/core/domain/content-type/index.js +140 -0
  26. package/lib/core/domain/content-type/validator.js +64 -0
  27. package/lib/core/domain/module/index.js +106 -0
  28. package/lib/core/domain/module/validation.js +36 -0
  29. package/lib/core/loaders/admin.js +16 -0
  30. package/lib/core/loaders/apis.js +157 -0
  31. package/lib/core/loaders/components.js +41 -0
  32. package/lib/core/loaders/index.js +11 -0
  33. package/lib/core/loaders/middlewares.js +86 -0
  34. package/lib/core/loaders/plugins/get-enabled-plugins.js +100 -0
  35. package/lib/core/loaders/plugins/index.js +109 -0
  36. package/lib/core/loaders/policies.js +28 -0
  37. package/lib/core/loaders/src-index.js +38 -0
  38. package/lib/core/registries/apis.js +43 -0
  39. package/lib/core/registries/config.js +21 -0
  40. package/lib/core/registries/content-types.js +53 -0
  41. package/lib/core/registries/controllers.js +43 -0
  42. package/lib/core/registries/hooks.js +37 -0
  43. package/lib/core/registries/middlewares.js +30 -0
  44. package/lib/core/registries/modules.js +44 -0
  45. package/lib/core/registries/plugins.js +28 -0
  46. package/lib/core/registries/policies.js +38 -0
  47. package/lib/core/registries/services.js +58 -0
  48. package/lib/core/utils.js +35 -0
  49. package/lib/core-api/controller/collection-type.js +84 -0
  50. package/lib/core-api/controller/index.js +26 -0
  51. package/lib/core-api/controller/single-type.js +44 -0
  52. package/lib/core-api/controller/transform.js +97 -0
  53. package/lib/core-api/index.js +39 -0
  54. package/lib/core-api/service/collection-type.js +84 -0
  55. package/lib/core-api/service/index.js +55 -0
  56. package/lib/core-api/service/pagination.js +125 -0
  57. package/lib/core-api/service/single-type.js +58 -0
  58. package/lib/index.d.ts +26 -0
  59. package/lib/index.js +3 -0
  60. package/lib/load/filepath-to-prop-path.js +22 -0
  61. package/lib/load/glob.js +15 -0
  62. package/lib/load/index.js +9 -0
  63. package/lib/load/load-files.js +56 -0
  64. package/lib/load/package-path.js +9 -0
  65. package/lib/middlewares/cors/index.js +66 -0
  66. package/lib/middlewares/error/defaults.json +5 -0
  67. package/lib/middlewares/error/index.js +147 -0
  68. package/lib/middlewares/favicon/defaults.json +7 -0
  69. package/lib/middlewares/favicon/index.js +31 -0
  70. package/lib/middlewares/gzip/defaults.json +6 -0
  71. package/lib/middlewares/gzip/index.js +19 -0
  72. package/lib/middlewares/helmet/defaults.json +18 -0
  73. package/lib/middlewares/helmet/index.js +9 -0
  74. package/lib/middlewares/index.js +120 -0
  75. package/lib/middlewares/ip/defaults.json +7 -0
  76. package/lib/middlewares/ip/index.js +25 -0
  77. package/lib/middlewares/logger/defaults.json +5 -0
  78. package/lib/middlewares/logger/index.js +37 -0
  79. package/lib/middlewares/parser/defaults.json +11 -0
  80. package/lib/middlewares/parser/index.js +75 -0
  81. package/lib/middlewares/poweredBy/defaults.json +5 -0
  82. package/lib/middlewares/poweredBy/index.js +16 -0
  83. package/lib/middlewares/public/assets/images/group_people_1.png +0 -0
  84. package/lib/middlewares/public/assets/images/group_people_2.png +0 -0
  85. package/lib/middlewares/public/assets/images/group_people_3.png +0 -0
  86. package/lib/middlewares/public/assets/images/logo_login.png +0 -0
  87. package/lib/middlewares/public/defaults.json +8 -0
  88. package/lib/middlewares/public/index.html +66 -0
  89. package/lib/middlewares/public/index.js +130 -0
  90. package/lib/middlewares/public/serve-static.js +23 -0
  91. package/lib/middlewares/responseTime/defaults.json +5 -0
  92. package/lib/middlewares/responseTime/index.js +25 -0
  93. package/lib/middlewares/responses/defaults.json +5 -0
  94. package/lib/middlewares/responses/index.js +19 -0
  95. package/lib/middlewares/router/defaults.json +7 -0
  96. package/lib/middlewares/router/index.js +97 -0
  97. package/lib/middlewares/session/defaults.json +18 -0
  98. package/lib/middlewares/session/index.js +140 -0
  99. package/lib/migrations/draft-publish.js +57 -0
  100. package/lib/services/auth/index.js +92 -0
  101. package/lib/services/core-store.js +145 -0
  102. package/lib/services/cron.js +54 -0
  103. package/lib/services/entity-service/components.js +365 -0
  104. package/lib/services/entity-service/index.d.ts +91 -0
  105. package/lib/services/entity-service/index.js +244 -0
  106. package/lib/services/entity-service/params.js +145 -0
  107. package/lib/services/entity-validator/index.js +187 -0
  108. package/lib/services/entity-validator/validators.js +123 -0
  109. package/lib/services/event-hub.js +15 -0
  110. package/lib/services/fs.js +58 -0
  111. package/lib/services/metrics/index.js +104 -0
  112. package/lib/services/metrics/is-truthy.js +9 -0
  113. package/lib/services/metrics/middleware.js +33 -0
  114. package/lib/services/metrics/rate-limiter.js +27 -0
  115. package/lib/services/metrics/sender.js +76 -0
  116. package/lib/services/metrics/stringify-deep.js +22 -0
  117. package/lib/services/server/admin-api.js +14 -0
  118. package/lib/services/server/api.js +32 -0
  119. package/lib/services/server/compose-endpoint.js +112 -0
  120. package/lib/services/server/content-api.js +16 -0
  121. package/lib/services/server/http-server.js +64 -0
  122. package/lib/services/server/index.js +108 -0
  123. package/lib/services/server/middleware.js +28 -0
  124. package/lib/services/server/policy.js +34 -0
  125. package/lib/services/server/routing.js +107 -0
  126. package/lib/services/utils/upload-files.js +79 -0
  127. package/lib/services/webhook-runner.js +155 -0
  128. package/lib/services/webhook-store.js +91 -0
  129. package/lib/services/worker-queue.js +58 -0
  130. package/lib/utils/addSlash.js +10 -0
  131. package/lib/utils/ee.js +123 -0
  132. package/lib/utils/get-dirs.js +15 -0
  133. package/lib/utils/get-prefixed-dependencies.js +7 -0
  134. package/lib/utils/index.js +11 -0
  135. package/lib/utils/is-initialized.js +23 -0
  136. package/lib/utils/open-browser.js +12 -0
  137. package/lib/utils/resources/key.pub +9 -0
  138. package/lib/utils/run-checks.js +22 -0
  139. package/lib/utils/startup-logger.js +90 -0
  140. package/lib/utils/success.js +31 -0
  141. package/lib/utils/update-notifier/index.js +97 -0
  142. package/lib/utils/url-from-segments.js +12 -0
  143. package/package.json +133 -0
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+
3
+ const { pickBy, has } = require('lodash/fp');
4
+ const { addNamespace, hasNamespace } = require('../utils');
5
+
6
+ const controllersRegistry = () => {
7
+ const controllers = {};
8
+
9
+ return {
10
+ get(uid) {
11
+ return controllers[uid];
12
+ },
13
+ getAll(namespace) {
14
+ return pickBy((_, uid) => hasNamespace(uid, namespace))(controllers);
15
+ },
16
+ set(uid, value) {
17
+ controllers[uid] = value;
18
+ return this;
19
+ },
20
+ add(namespace, newControllers) {
21
+ for (const controllerName in newControllers) {
22
+ const controller = newControllers[controllerName];
23
+ const uid = addNamespace(controllerName, namespace);
24
+
25
+ if (has(uid, controllers)) {
26
+ throw new Error(`Controller ${uid} has already been registered.`);
27
+ }
28
+ controllers[uid] = controller;
29
+ }
30
+ return this;
31
+ },
32
+ extend(controllerUID, extendFn) {
33
+ const currentController = this.get(controllerUID);
34
+ if (!currentController) {
35
+ throw new Error(`Controller ${controllerUID} doesn't exist`);
36
+ }
37
+ const newController = extendFn(currentController);
38
+ controllers[controllerUID] = newController;
39
+ },
40
+ };
41
+ };
42
+
43
+ module.exports = controllersRegistry;
@@ -0,0 +1,37 @@
1
+ 'use strict';
2
+
3
+ const { pickBy, has } = require('lodash/fp');
4
+ const { addNamespace, hasNamespace } = require('../utils');
5
+
6
+ const hooksRegistry = () => {
7
+ const hooks = {};
8
+
9
+ return {
10
+ get(hookUID) {
11
+ return hooks[hookUID];
12
+ },
13
+ getAll(namespace) {
14
+ return pickBy((_, uid) => hasNamespace(uid, namespace))(hooks);
15
+ },
16
+ set(uid, hook) {
17
+ if (has(uid, hooks)) {
18
+ throw new Error(`hook ${uid} has already been registered.`);
19
+ }
20
+
21
+ hooks[uid] = hook;
22
+ return this;
23
+ },
24
+ add(namespace, hooks) {
25
+ for (const hookName in hooks) {
26
+ const hook = hooks[hookName];
27
+ const uid = addNamespace(hookName, namespace);
28
+
29
+ this.set(uid, hook);
30
+ }
31
+
32
+ return this;
33
+ },
34
+ };
35
+ };
36
+
37
+ module.exports = hooksRegistry;
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ const { pickBy, has } = require('lodash/fp');
4
+ const { addNamespace, hasNamespace } = require('../utils');
5
+
6
+ const middlewaresRegistry = () => {
7
+ const middlewares = {};
8
+
9
+ return {
10
+ get(middlewareUID) {
11
+ return middlewares[middlewareUID];
12
+ },
13
+ getAll(namespace) {
14
+ return pickBy((_, uid) => hasNamespace(uid, namespace))(middlewares);
15
+ },
16
+ add(namespace, rawMiddlewares) {
17
+ for (const middlewareName in rawMiddlewares) {
18
+ const middleware = rawMiddlewares[middlewareName];
19
+ const uid = addNamespace(middlewareName, namespace);
20
+
21
+ if (has(uid, middlewares)) {
22
+ throw new Error(`Middleware ${uid} has already been registered.`);
23
+ }
24
+ middlewares[uid] = middleware;
25
+ }
26
+ },
27
+ };
28
+ };
29
+
30
+ module.exports = middlewaresRegistry;
@@ -0,0 +1,44 @@
1
+ 'use strict';
2
+
3
+ const { pickBy, has } = require('lodash/fp');
4
+ const { createModule } = require('../domain/module');
5
+
6
+ const modulesRegistry = strapi => {
7
+ const modules = {};
8
+
9
+ return {
10
+ get(namespace) {
11
+ return modules[namespace];
12
+ },
13
+ getAll(prefix = '') {
14
+ return pickBy((mod, namespace) => namespace.startsWith(prefix))(modules);
15
+ },
16
+ add(namespace, rawModule) {
17
+ if (has(namespace, modules)) {
18
+ throw new Error(`Module ${namespace} has already been registered.`);
19
+ }
20
+
21
+ modules[namespace] = createModule(namespace, rawModule, strapi);
22
+ modules[namespace].load();
23
+
24
+ return modules[namespace];
25
+ },
26
+ async bootstrap() {
27
+ for (const mod of Object.values(modules)) {
28
+ await mod.bootstrap();
29
+ }
30
+ },
31
+ async register() {
32
+ for (const mod of Object.values(modules)) {
33
+ await mod.register();
34
+ }
35
+ },
36
+ async destroy() {
37
+ for (const mod of Object.values(modules)) {
38
+ await mod.destroy();
39
+ }
40
+ },
41
+ };
42
+ };
43
+
44
+ module.exports = modulesRegistry;
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ const { has } = require('lodash/fp');
4
+
5
+ const pluginsRegistry = strapi => {
6
+ const plugins = {};
7
+
8
+ return {
9
+ get(name) {
10
+ return plugins[name];
11
+ },
12
+ getAll() {
13
+ return plugins;
14
+ },
15
+ add(name, pluginConfig) {
16
+ if (has(name, plugins)) {
17
+ throw new Error(`Plugin ${name} has already been registered.`);
18
+ }
19
+
20
+ const pluginModule = strapi.container.get('modules').add(`plugin::${name}`, pluginConfig);
21
+ plugins[name] = pluginModule;
22
+
23
+ return plugins[name];
24
+ },
25
+ };
26
+ };
27
+
28
+ module.exports = pluginsRegistry;
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ const { pickBy, has } = require('lodash/fp');
4
+ const { addNamespace, hasNamespace } = require('../utils');
5
+
6
+ const policiesRegistry = () => {
7
+ const policies = {};
8
+
9
+ return {
10
+ get(policyUID) {
11
+ return policies[policyUID];
12
+ },
13
+ getAll(namespace) {
14
+ return pickBy((_, uid) => hasNamespace(uid, namespace))(policies);
15
+ },
16
+ add(namespace, newPolicies) {
17
+ for (const policyName in newPolicies) {
18
+ const policy = newPolicies[policyName];
19
+ const uid = addNamespace(policyName, namespace);
20
+
21
+ if (has(uid, policies)) {
22
+ throw new Error(`Policy ${uid} has already been registered.`);
23
+ }
24
+ policies[uid] = policy;
25
+ }
26
+ },
27
+ extend(policyUID, extendFn) {
28
+ const currentPolicy = this.get(policyUID);
29
+ if (!currentPolicy) {
30
+ throw new Error(`Policy ${policyUID} doesn't exist`);
31
+ }
32
+ const newPolicy = extendFn(currentPolicy);
33
+ policies[policyUID] = newPolicy;
34
+ },
35
+ };
36
+ };
37
+
38
+ module.exports = policiesRegistry;
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+
3
+ const _ = require('lodash');
4
+ const { pickBy, has } = require('lodash/fp');
5
+ const { addNamespace, hasNamespace } = require('../utils');
6
+
7
+ const servicesRegistry = strapi => {
8
+ const services = {};
9
+ const instantiatedServices = {};
10
+
11
+ return {
12
+ get(uid) {
13
+ if (instantiatedServices[uid]) {
14
+ return instantiatedServices[uid];
15
+ }
16
+
17
+ const service = services[uid];
18
+ if (service) {
19
+ instantiatedServices[uid] = service({ strapi });
20
+ return instantiatedServices[uid];
21
+ }
22
+
23
+ return undefined;
24
+ },
25
+ getAll(namespace) {
26
+ const filteredServices = pickBy((_, uid) => hasNamespace(uid, namespace))(services);
27
+
28
+ return _.mapValues(filteredServices, (service, serviceUID) => this.get(serviceUID));
29
+ },
30
+ set(uid, value) {
31
+ instantiatedServices[uid] = value;
32
+ return this;
33
+ },
34
+ add(namespace, newServices) {
35
+ for (const serviceName in newServices) {
36
+ const service = newServices[serviceName];
37
+ const uid = addNamespace(serviceName, namespace);
38
+
39
+ if (has(uid, services)) {
40
+ throw new Error(`Service ${uid} has already been registered.`);
41
+ }
42
+ services[uid] = service;
43
+ }
44
+
45
+ return this;
46
+ },
47
+ extend(serviceUID, extendFn) {
48
+ const currentService = this.get(serviceUID);
49
+ if (!currentService) {
50
+ throw new Error(`Service ${serviceUID} doesn't exist`);
51
+ }
52
+ const newService = extendFn(currentService);
53
+ instantiatedServices[serviceUID] = newService;
54
+ },
55
+ };
56
+ };
57
+
58
+ module.exports = servicesRegistry;
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ const hasNamespace = (name, namespace) => {
4
+ if (!namespace) {
5
+ return true;
6
+ }
7
+
8
+ if (namespace.endsWith('::')) {
9
+ return name.startsWith(namespace);
10
+ } else {
11
+ return name.startsWith(`${namespace}.`);
12
+ }
13
+ };
14
+
15
+ const addNamespace = (name, namespace) => {
16
+ if (namespace.endsWith('::')) {
17
+ return `${namespace}${name}`;
18
+ } else {
19
+ return `${namespace}.${name}`;
20
+ }
21
+ };
22
+
23
+ const removeNamespace = (name, namespace) => {
24
+ if (namespace.endsWith('::')) {
25
+ return name.replace(namespace, '');
26
+ } else {
27
+ return name.replace(`${namespace}.`, '');
28
+ }
29
+ };
30
+
31
+ module.exports = {
32
+ addNamespace,
33
+ removeNamespace,
34
+ hasNamespace,
35
+ };
@@ -0,0 +1,84 @@
1
+ 'use strict';
2
+
3
+ const { parseBody } = require('./transform');
4
+
5
+ /**
6
+ *
7
+ * Returns a collection type controller to handle default core-api actions
8
+ */
9
+ const createCollectionTypeController = ({ service, sanitize, transformResponse }) => {
10
+ return {
11
+ /**
12
+ * Retrieve records.
13
+ *
14
+ * @return {Object|Array}
15
+ */
16
+ async find(ctx) {
17
+ const { query } = ctx;
18
+
19
+ const { results, pagination } = await service.find(query);
20
+
21
+ return transformResponse(sanitize(results), { pagination });
22
+ },
23
+
24
+ /**
25
+ * Retrieve a record.
26
+ *
27
+ * @return {Object}
28
+ */
29
+ async findOne(ctx) {
30
+ const { id } = ctx.params;
31
+ const { query } = ctx;
32
+
33
+ const entity = await service.findOne(id, query);
34
+
35
+ return transformResponse(sanitize(entity));
36
+ },
37
+
38
+ /**
39
+ * Create a record.
40
+ *
41
+ * @return {Object}
42
+ */
43
+ async create(ctx) {
44
+ const { query } = ctx.request;
45
+
46
+ const { data, files } = parseBody(ctx);
47
+
48
+ const entity = await service.create({ ...query, data, files });
49
+
50
+ return transformResponse(sanitize(entity));
51
+ },
52
+
53
+ /**
54
+ * Update a record.
55
+ *
56
+ * @return {Object}
57
+ */
58
+ async update(ctx) {
59
+ const { id } = ctx.params;
60
+ const { query } = ctx.request;
61
+
62
+ const { data, files } = parseBody(ctx);
63
+
64
+ const entity = await service.update(id, { ...query, data, files });
65
+
66
+ return transformResponse(sanitize(entity));
67
+ },
68
+
69
+ /**
70
+ * Destroy a record.
71
+ *
72
+ * @return {Object}
73
+ */
74
+ async delete(ctx) {
75
+ const { id } = ctx.params;
76
+ const { query } = ctx;
77
+
78
+ const entity = await service.delete(id, query);
79
+ return transformResponse(sanitize(entity));
80
+ },
81
+ };
82
+ };
83
+
84
+ module.exports = createCollectionTypeController;
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ const { sanitizeEntity, contentTypes } = require('@strapi/utils');
4
+
5
+ const { transformResponse } = require('./transform');
6
+ const createSingleTypeController = require('./single-type');
7
+ const createCollectionTypeController = require('./collection-type');
8
+
9
+ module.exports = ({ service, model }) => {
10
+ const ctx = {
11
+ model,
12
+ service,
13
+ transformResponse(data, meta) {
14
+ return transformResponse(data, meta, { contentType: model });
15
+ },
16
+ sanitize(data) {
17
+ return sanitizeEntity(data, { model: strapi.getModel(model.uid) });
18
+ },
19
+ };
20
+
21
+ if (contentTypes.isSingleType(model)) {
22
+ return createSingleTypeController(ctx);
23
+ }
24
+
25
+ return createCollectionTypeController(ctx);
26
+ };
@@ -0,0 +1,44 @@
1
+ 'use strict';
2
+
3
+ const { parseBody } = require('./transform');
4
+
5
+ /**
6
+ * Returns a single type controller to handle default core-api actions
7
+ */
8
+ const createSingleTypeController = ({ service, sanitize, transformResponse }) => {
9
+ return {
10
+ /**
11
+ * Retrieve single type content
12
+ *
13
+ * @return {Object|Array}
14
+ */
15
+ async find(ctx) {
16
+ const { query } = ctx;
17
+ const entity = await service.find(query);
18
+ return transformResponse(sanitize(entity));
19
+ },
20
+
21
+ /**
22
+ * create or update single type content.
23
+ *
24
+ * @return {Object}
25
+ */
26
+ async update(ctx) {
27
+ const { query } = ctx.request;
28
+ const { data, files } = parseBody(ctx);
29
+
30
+ const entity = await service.createOrUpdate({ ...query, data, files });
31
+
32
+ return transformResponse(sanitize(entity));
33
+ },
34
+
35
+ async delete(ctx) {
36
+ const { query } = ctx;
37
+
38
+ const entity = await service.delete(query);
39
+ return transformResponse(sanitize(entity));
40
+ },
41
+ };
42
+ };
43
+
44
+ module.exports = createSingleTypeController;
@@ -0,0 +1,97 @@
1
+ 'use strict';
2
+
3
+ const { isNil, isPlainObject } = require('lodash/fp');
4
+ const { parseMultipartData } = require('@strapi/utils');
5
+
6
+ const parseBody = ctx => {
7
+ if (ctx.is('multipart')) {
8
+ return parseMultipartData(ctx);
9
+ }
10
+
11
+ const { data } = ctx.request.body || {};
12
+
13
+ return { data };
14
+ };
15
+
16
+ const transformResponse = (resource, meta = {}, { contentType } = {}) => {
17
+ if (isNil(resource)) {
18
+ return resource;
19
+ }
20
+
21
+ return {
22
+ data: transformEntry(resource, contentType),
23
+ meta,
24
+ };
25
+ };
26
+
27
+ const transformComponent = (data, component) => {
28
+ if (Array.isArray(data)) {
29
+ return data.map(datum => transformComponent(datum, component));
30
+ }
31
+
32
+ const res = transformEntry(data, component);
33
+
34
+ if (isNil(res)) {
35
+ return res;
36
+ }
37
+
38
+ const { id, attributes } = res;
39
+ return { id, ...attributes };
40
+ };
41
+
42
+ const transformEntry = (entry, type) => {
43
+ if (isNil(entry)) {
44
+ return entry;
45
+ }
46
+
47
+ if (Array.isArray(entry)) {
48
+ return entry.map(singleEntry => transformEntry(singleEntry, type));
49
+ }
50
+
51
+ if (!isPlainObject(entry)) {
52
+ throw new Error('Entry must be an object');
53
+ }
54
+
55
+ const { id, ...properties } = entry;
56
+
57
+ const attributeValues = {};
58
+
59
+ for (const key in properties) {
60
+ const property = properties[key];
61
+ const attribute = type && type.attributes[key];
62
+
63
+ if (attribute && attribute.type === 'relation') {
64
+ const data = transformEntry(property, strapi.contentType(attribute.target));
65
+
66
+ attributeValues[key] = { data };
67
+ } else if (attribute && attribute.type === 'component') {
68
+ attributeValues[key] = transformComponent(property, strapi.components[attribute.component]);
69
+ } else if (attribute && attribute.type === 'dynamiczone') {
70
+ if (isNil(property)) {
71
+ attributeValues[key] = property;
72
+ }
73
+
74
+ attributeValues[key] = property.map(subProperty => {
75
+ return transformComponent(subProperty, strapi.components[subProperty.__component]);
76
+ });
77
+ } else if (attribute && attribute.type === 'media') {
78
+ const data = transformEntry(property, strapi.contentType('plugin::upload.file'));
79
+
80
+ attributeValues[key] = { data };
81
+ } else {
82
+ attributeValues[key] = property;
83
+ }
84
+ }
85
+
86
+ return {
87
+ id,
88
+ attributes: attributeValues,
89
+ // NOTE: not necessary for now
90
+ // meta: {},
91
+ };
92
+ };
93
+
94
+ module.exports = {
95
+ parseBody,
96
+ transformResponse,
97
+ };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Core API
3
+ */
4
+ 'use strict';
5
+
6
+ const _ = require('lodash');
7
+
8
+ const createController = require('./controller');
9
+ const { createService } = require('./service');
10
+
11
+ /**
12
+ * Returns a service and a controller built based on the content type passed
13
+ *
14
+ * @param {object} opts options
15
+ * @param {object} opts.api api
16
+ * @param {object} opts.model model
17
+ * @param {object} opts.strapi strapi
18
+ * @returns {object} controller & service
19
+ */
20
+ function createCoreApi({ api, model, strapi }) {
21
+ const { modelName } = model;
22
+
23
+ // find corresponding service and controller
24
+ const userService = _.get(api, ['services', modelName], {});
25
+ const userController = _.get(api, ['controllers', modelName], {});
26
+
27
+ const service = Object.assign(createService({ model, strapi }), userService);
28
+
29
+ const controller = Object.assign(createController({ service, model }), userController);
30
+
31
+ return {
32
+ service,
33
+ controller,
34
+ };
35
+ }
36
+
37
+ module.exports = {
38
+ createCoreApi,
39
+ };
@@ -0,0 +1,84 @@
1
+ 'use strict';
2
+
3
+ const { propOr } = require('lodash/fp');
4
+
5
+ const {
6
+ hasDraftAndPublish,
7
+ constants: { PUBLISHED_AT_ATTRIBUTE },
8
+ } = require('@strapi/utils').contentTypes;
9
+
10
+ const {
11
+ getPaginationInfo,
12
+ convertPagedToStartLimit,
13
+ shouldCount,
14
+ transformPaginationResponse,
15
+ } = require('./pagination');
16
+
17
+ const setPublishedAt = data => {
18
+ data[PUBLISHED_AT_ATTRIBUTE] = propOr(new Date(), PUBLISHED_AT_ATTRIBUTE, data);
19
+ };
20
+
21
+ /**
22
+ *
23
+ * Returns a collection type service to handle default core-api actions
24
+ */
25
+ const createCollectionTypeService = ({ model, strapi, utils }) => {
26
+ const { uid } = model;
27
+
28
+ const { sanitizeInput, getFetchParams } = utils;
29
+
30
+ return {
31
+ async find(params = {}) {
32
+ const fetchParams = getFetchParams(params);
33
+
34
+ const paginationInfo = getPaginationInfo(fetchParams);
35
+
36
+ const results = await strapi.entityService.findMany(uid, {
37
+ ...fetchParams,
38
+ ...convertPagedToStartLimit(paginationInfo),
39
+ });
40
+
41
+ if (shouldCount(fetchParams)) {
42
+ const count = await strapi.entityService.count(uid, { ...fetchParams, ...paginationInfo });
43
+
44
+ return {
45
+ results,
46
+ pagination: transformPaginationResponse(paginationInfo, count),
47
+ };
48
+ }
49
+
50
+ return {
51
+ results,
52
+ pagination: paginationInfo,
53
+ };
54
+ },
55
+
56
+ findOne(entityId, params = {}) {
57
+ return strapi.entityService.findOne(uid, entityId, getFetchParams(params));
58
+ },
59
+
60
+ create(params = {}) {
61
+ const { data } = params;
62
+ const sanitizedData = sanitizeInput(data);
63
+
64
+ if (hasDraftAndPublish(model)) {
65
+ setPublishedAt(sanitizedData);
66
+ }
67
+
68
+ return strapi.entityService.create(uid, { ...params, data: sanitizedData });
69
+ },
70
+
71
+ update(entityId, params = {}) {
72
+ const { data } = params;
73
+ const sanitizedData = sanitizeInput(data);
74
+
75
+ return strapi.entityService.update(uid, entityId, { ...params, data: sanitizedData });
76
+ },
77
+
78
+ delete(entityId, params = {}) {
79
+ return strapi.entityService.delete(uid, entityId, params);
80
+ },
81
+ };
82
+ };
83
+
84
+ module.exports = createCollectionTypeService;