@strapi/strapi 4.0.0-next.9 → 4.0.3
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 +14 -14
- package/bin/strapi.js +37 -6
- package/lib/Strapi.js +140 -72
- package/lib/commands/build.js +21 -11
- package/lib/commands/console.js +1 -1
- package/lib/commands/content-types/list.js +22 -0
- package/lib/commands/controllers/list.js +22 -0
- package/lib/commands/develop.js +24 -27
- package/lib/commands/generate-template.js +4 -5
- package/lib/commands/hooks/list.js +22 -0
- package/lib/commands/middlewares/list.js +22 -0
- package/lib/commands/new.js +3 -1
- package/lib/commands/policies/list.js +22 -0
- package/lib/commands/routes/list.js +28 -0
- package/lib/commands/services/list.js +22 -0
- package/lib/commands/watchAdmin.js +18 -9
- package/lib/core/app-configuration/index.js +3 -19
- package/lib/core/bootstrap.js +3 -34
- package/lib/core/domain/content-type/index.js +3 -7
- package/lib/core/domain/module/index.js +8 -6
- package/lib/core/domain/module/validation.js +1 -4
- package/lib/core/loaders/admin.js +2 -2
- package/lib/core/loaders/apis.js +7 -7
- package/lib/core/loaders/components.js +3 -5
- package/lib/core/loaders/index.js +1 -0
- package/lib/core/loaders/middlewares.js +23 -123
- package/lib/core/loaders/plugins/get-enabled-plugins.js +55 -19
- package/lib/core/loaders/plugins/get-user-plugins-config.js +37 -0
- package/lib/core/loaders/plugins/index.js +30 -16
- package/lib/core/loaders/policies.js +1 -1
- package/lib/core/loaders/src-index.js +39 -0
- package/lib/core/registries/apis.js +2 -16
- package/lib/core/registries/content-types.js +50 -6
- package/lib/core/registries/controllers.d.ts +7 -0
- package/lib/core/registries/controllers.js +74 -3
- package/lib/core/registries/hooks.d.ts +20 -0
- package/lib/core/registries/hooks.js +87 -0
- package/lib/core/registries/middlewares.d.ts +5 -0
- package/lib/core/registries/middlewares.js +61 -2
- package/lib/core/registries/modules.js +3 -3
- package/lib/core/registries/plugins.js +2 -2
- package/lib/core/registries/policies.d.ts +9 -0
- package/lib/core/registries/policies.js +57 -6
- package/lib/core/registries/services.d.ts +7 -0
- package/lib/core/registries/services.js +71 -15
- package/lib/core-api/controller/collection-type.js +38 -11
- package/lib/core-api/controller/index.d.ts +25 -0
- package/lib/core-api/controller/index.js +30 -11
- package/lib/core-api/controller/single-type.js +26 -7
- package/lib/core-api/controller/transform.js +28 -3
- package/lib/core-api/routes/index.js +71 -0
- package/lib/core-api/service/collection-type.js +22 -27
- package/lib/core-api/service/index.d.ts +21 -0
- package/lib/core-api/service/index.js +9 -19
- package/lib/core-api/service/pagination.js +16 -16
- package/lib/core-api/service/single-type.js +17 -20
- package/lib/factories.d.ts +48 -0
- package/lib/factories.js +84 -0
- package/lib/index.d.ts +10 -31
- package/lib/index.js +5 -1
- package/lib/middlewares/body.js +33 -0
- package/lib/middlewares/compression.js +8 -0
- package/lib/middlewares/cors.js +58 -0
- package/lib/middlewares/errors.js +40 -0
- package/lib/middlewares/favicon.js +19 -0
- package/lib/middlewares/index.d.ts +5 -0
- package/lib/middlewares/index.js +30 -116
- package/lib/middlewares/ip.js +8 -0
- package/lib/middlewares/logger.js +27 -0
- package/lib/middlewares/powered-by.js +20 -0
- package/lib/middlewares/public/index.js +72 -77
- package/lib/middlewares/query.js +46 -0
- package/lib/middlewares/response-time.js +15 -0
- package/lib/middlewares/responses.js +19 -0
- package/lib/middlewares/security.js +51 -0
- package/lib/middlewares/session/index.js +6 -6
- package/lib/migrations/draft-publish.js +57 -0
- package/lib/services/auth/index.js +87 -0
- package/lib/services/core-store.js +64 -49
- package/lib/services/cron.js +54 -0
- package/lib/services/entity-service/attributes/index.js +31 -0
- package/lib/services/entity-service/attributes/transforms.js +20 -0
- package/lib/services/entity-service/components.js +39 -15
- package/lib/services/entity-service/index.d.ts +91 -0
- package/lib/services/entity-service/index.js +118 -60
- package/lib/services/entity-service/params.js +48 -81
- package/lib/services/entity-validator/index.js +76 -43
- package/lib/services/entity-validator/validators.js +131 -43
- package/lib/services/errors.js +77 -0
- package/lib/services/fs.js +1 -1
- package/lib/services/metrics/index.js +38 -36
- package/lib/services/server/admin-api.js +14 -0
- package/lib/services/server/api.js +36 -0
- package/lib/services/server/compose-endpoint.js +141 -0
- package/lib/services/server/content-api.js +16 -0
- package/lib/{server.js → services/server/http-server.js} +0 -0
- package/lib/services/server/index.js +127 -0
- package/lib/services/server/koa.js +64 -0
- package/lib/services/server/middleware.js +122 -0
- package/lib/services/server/policy.js +32 -0
- package/lib/services/server/register-middlewares.js +110 -0
- package/lib/services/server/register-routes.js +106 -0
- package/lib/services/server/routing.js +120 -0
- package/lib/services/webhook-runner.js +1 -1
- package/lib/utils/ee.js +3 -3
- package/lib/utils/get-dirs.js +17 -0
- package/lib/utils/index.js +2 -0
- package/lib/utils/signals.js +24 -0
- package/lib/utils/update-notifier/index.js +2 -1
- package/package.json +94 -93
- package/lib/core/app-configuration/load-functions.js +0 -28
- package/lib/core-api/index.js +0 -39
- package/lib/middlewares/boom/defaults.json +0 -5
- package/lib/middlewares/boom/index.js +0 -147
- package/lib/middlewares/cors/index.js +0 -66
- package/lib/middlewares/cron/defaults.json +0 -5
- package/lib/middlewares/cron/index.js +0 -43
- package/lib/middlewares/favicon/defaults.json +0 -7
- package/lib/middlewares/favicon/index.js +0 -32
- package/lib/middlewares/gzip/defaults.json +0 -6
- package/lib/middlewares/gzip/index.js +0 -19
- package/lib/middlewares/helmet/defaults.json +0 -18
- package/lib/middlewares/helmet/index.js +0 -9
- package/lib/middlewares/ip/defaults.json +0 -7
- package/lib/middlewares/ip/index.js +0 -25
- package/lib/middlewares/language/defaults.json +0 -9
- package/lib/middlewares/language/index.js +0 -40
- package/lib/middlewares/logger/defaults.json +0 -5
- package/lib/middlewares/logger/index.js +0 -37
- package/lib/middlewares/parser/defaults.json +0 -11
- package/lib/middlewares/parser/index.js +0 -72
- package/lib/middlewares/poweredBy/defaults.json +0 -5
- package/lib/middlewares/poweredBy/index.js +0 -16
- package/lib/middlewares/public/defaults.json +0 -8
- package/lib/middlewares/responseTime/defaults.json +0 -5
- package/lib/middlewares/responseTime/index.js +0 -25
- package/lib/middlewares/responses/defaults.json +0 -5
- package/lib/middlewares/responses/index.js +0 -18
- package/lib/middlewares/router/defaults.json +0 -7
- package/lib/middlewares/router/index.js +0 -72
- package/lib/middlewares/router/utils/compose-endpoint.js +0 -169
- package/lib/utils/get-prefixed-dependencies.js +0 -7
|
@@ -3,20 +3,80 @@
|
|
|
3
3
|
const { pickBy, has } = require('lodash/fp');
|
|
4
4
|
const { addNamespace, hasNamespace } = require('../utils');
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('./controllers').Controller} Controller
|
|
8
|
+
* @typedef {import('./controllers').ControllerFactory} ControllerFactory
|
|
9
|
+
*/
|
|
10
|
+
|
|
6
11
|
const controllersRegistry = () => {
|
|
7
12
|
const controllers = {};
|
|
13
|
+
const instances = {};
|
|
8
14
|
|
|
9
15
|
return {
|
|
16
|
+
/**
|
|
17
|
+
* Returns this list of registered controllers uids
|
|
18
|
+
* @returns {string[]}
|
|
19
|
+
*/
|
|
20
|
+
keys() {
|
|
21
|
+
return Object.keys(controllers);
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Returns the instance of a controller. Instantiate the controller if not already done
|
|
26
|
+
* @param {string} uid
|
|
27
|
+
* @returns {Controller}
|
|
28
|
+
*/
|
|
10
29
|
get(uid) {
|
|
11
|
-
|
|
30
|
+
if (instances[uid]) {
|
|
31
|
+
return instances[uid];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const controller = controllers[uid];
|
|
35
|
+
|
|
36
|
+
if (controller) {
|
|
37
|
+
instances[uid] = typeof controller === 'function' ? controller({ strapi }) : controller;
|
|
38
|
+
return instances[uid];
|
|
39
|
+
}
|
|
12
40
|
},
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Returns a map with all the controller in a namespace
|
|
44
|
+
* @param {string} namespace
|
|
45
|
+
* @returns {{ [key: string]: Controller }}
|
|
46
|
+
*/
|
|
13
47
|
getAll(namespace) {
|
|
14
|
-
|
|
48
|
+
const filteredControllers = pickBy((_, uid) => hasNamespace(uid, namespace))(controllers);
|
|
49
|
+
|
|
50
|
+
const map = {};
|
|
51
|
+
for (const uid in filteredControllers) {
|
|
52
|
+
Object.defineProperty(map, uid, {
|
|
53
|
+
enumerable: true,
|
|
54
|
+
get: () => {
|
|
55
|
+
return this.get(uid);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return map;
|
|
15
61
|
},
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Registers a controller
|
|
65
|
+
* @param {string} uid
|
|
66
|
+
* @param {Controller} controller
|
|
67
|
+
*/
|
|
16
68
|
set(uid, value) {
|
|
17
69
|
controllers[uid] = value;
|
|
70
|
+
delete instances[uid];
|
|
18
71
|
return this;
|
|
19
72
|
},
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Registers a map of controllers for a specific namespace
|
|
76
|
+
* @param {string} namespace
|
|
77
|
+
* @param {{ [key: string]: Controller|ControllerFactory }} newControllers
|
|
78
|
+
* @returns
|
|
79
|
+
*/
|
|
20
80
|
add(namespace, newControllers) {
|
|
21
81
|
for (const controllerName in newControllers) {
|
|
22
82
|
const controller = newControllers[controllerName];
|
|
@@ -27,15 +87,26 @@ const controllersRegistry = () => {
|
|
|
27
87
|
}
|
|
28
88
|
controllers[uid] = controller;
|
|
29
89
|
}
|
|
90
|
+
|
|
30
91
|
return this;
|
|
31
92
|
},
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Wraps a controller to extend it
|
|
96
|
+
* @param {string} uid
|
|
97
|
+
* @param {(controller: Controller) => Controller} extendFn
|
|
98
|
+
*/
|
|
32
99
|
extend(controllerUID, extendFn) {
|
|
33
100
|
const currentController = this.get(controllerUID);
|
|
101
|
+
|
|
34
102
|
if (!currentController) {
|
|
35
103
|
throw new Error(`Controller ${controllerUID} doesn't exist`);
|
|
36
104
|
}
|
|
105
|
+
|
|
37
106
|
const newController = extendFn(currentController);
|
|
38
|
-
|
|
107
|
+
instances[controllerUID] = newController;
|
|
108
|
+
|
|
109
|
+
return this;
|
|
39
110
|
},
|
|
40
111
|
};
|
|
41
112
|
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
type Handler = (context: any) => any;
|
|
3
|
+
|
|
4
|
+
type AsyncHook = {
|
|
5
|
+
handlers: Handler[];
|
|
6
|
+
register(handler: Handler): this;
|
|
7
|
+
delete(handler: Handler): this;
|
|
8
|
+
call(): Promise<void>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
type SyncHook = {
|
|
13
|
+
get handlers(): Handler[];
|
|
14
|
+
register(handler: Handler): this;
|
|
15
|
+
delete(handler: Handler): this;
|
|
16
|
+
call(): void;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
export type Hook = AsyncHook|SyncHook
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { pickBy } = require('lodash/fp');
|
|
4
|
+
const { addNamespace, hasNamespace } = require('../utils');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('./hooks').Hook} Hook
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const hooksRegistry = () => {
|
|
11
|
+
const hooks = {};
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
/**
|
|
15
|
+
* Returns this list of registered hooks uids
|
|
16
|
+
* @returns {string[]}
|
|
17
|
+
*/
|
|
18
|
+
keys() {
|
|
19
|
+
return Object.keys(hooks);
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns the instance of a hook.
|
|
24
|
+
* @param {string} uid
|
|
25
|
+
* @returns {Hook}
|
|
26
|
+
*/
|
|
27
|
+
get(uid) {
|
|
28
|
+
return hooks[uid];
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Returns a map with all the hooks in a namespace
|
|
33
|
+
* @param {string} namespace
|
|
34
|
+
* @returns {{ [key: string]: Hook }}
|
|
35
|
+
*/
|
|
36
|
+
getAll(namespace) {
|
|
37
|
+
return pickBy((_, uid) => hasNamespace(uid, namespace))(hooks);
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Registers a hook
|
|
42
|
+
* @param {string} uid
|
|
43
|
+
* @param {Hook} hook
|
|
44
|
+
*/
|
|
45
|
+
set(uid, hook) {
|
|
46
|
+
hooks[uid] = hook;
|
|
47
|
+
return this;
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Registers a map of hooks for a specific namespace
|
|
52
|
+
* @param {string} namespace
|
|
53
|
+
* @param {{ [key: string]: Hook }} newHooks
|
|
54
|
+
* @returns
|
|
55
|
+
*/
|
|
56
|
+
add(namespace, hooks) {
|
|
57
|
+
for (const hookName in hooks) {
|
|
58
|
+
const hook = hooks[hookName];
|
|
59
|
+
const uid = addNamespace(hookName, namespace);
|
|
60
|
+
|
|
61
|
+
this.set(uid, hook);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return this;
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Wraps a hook to extend it
|
|
69
|
+
* @param {string} uid
|
|
70
|
+
* @param {(hook: Hook) => Hook} extendFn
|
|
71
|
+
*/
|
|
72
|
+
extend(uid, extendFn) {
|
|
73
|
+
const currentHook = this.get(uid);
|
|
74
|
+
|
|
75
|
+
if (!currentHook) {
|
|
76
|
+
throw new Error(`Hook ${uid} doesn't exist`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const newHook = extendFn(currentHook);
|
|
80
|
+
hooks[uid] = newHook;
|
|
81
|
+
|
|
82
|
+
return this;
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
module.exports = hooksRegistry;
|
|
@@ -3,16 +3,57 @@
|
|
|
3
3
|
const { pickBy, has } = require('lodash/fp');
|
|
4
4
|
const { addNamespace, hasNamespace } = require('../utils');
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('./middlewares').Middleware} Middleware
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// TODO: move instantiation part here instead of in the server service
|
|
6
11
|
const middlewaresRegistry = () => {
|
|
7
12
|
const middlewares = {};
|
|
8
13
|
|
|
9
14
|
return {
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Returns this list of registered middlewares uids
|
|
17
|
+
* @returns {string[]}
|
|
18
|
+
*/
|
|
19
|
+
keys() {
|
|
20
|
+
return Object.keys(middlewares);
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Returns the instance of a middleware. Instantiate the middleware if not already done
|
|
25
|
+
* @param {string} uid
|
|
26
|
+
* @returns {Middleware}
|
|
27
|
+
*/
|
|
28
|
+
get(uid) {
|
|
29
|
+
return middlewares[uid];
|
|
12
30
|
},
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Returns a map with all the middlewares in a namespace
|
|
34
|
+
* @param {string} namespace
|
|
35
|
+
* @returns {{ [key: string]: Middleware }}
|
|
36
|
+
*/
|
|
13
37
|
getAll(namespace) {
|
|
14
38
|
return pickBy((_, uid) => hasNamespace(uid, namespace))(middlewares);
|
|
15
39
|
},
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Registers a middleware
|
|
43
|
+
* @param {string} uid
|
|
44
|
+
* @param {Middleware} middleware
|
|
45
|
+
*/
|
|
46
|
+
set(uid, middleware) {
|
|
47
|
+
middlewares[uid] = middleware;
|
|
48
|
+
return this;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Registers a map of middlewares for a specific namespace
|
|
53
|
+
* @param {string} namespace
|
|
54
|
+
* @param {{ [key: string]: Middleware }} newMiddlewares
|
|
55
|
+
* @returns
|
|
56
|
+
*/
|
|
16
57
|
add(namespace, rawMiddlewares) {
|
|
17
58
|
for (const middlewareName in rawMiddlewares) {
|
|
18
59
|
const middleware = rawMiddlewares[middlewareName];
|
|
@@ -24,6 +65,24 @@ const middlewaresRegistry = () => {
|
|
|
24
65
|
middlewares[uid] = middleware;
|
|
25
66
|
}
|
|
26
67
|
},
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Wraps a middleware to extend it
|
|
71
|
+
* @param {string} uid
|
|
72
|
+
* @param {(middleware: Middleware) => Middleware} extendFn
|
|
73
|
+
*/
|
|
74
|
+
extend(uid, extendFn) {
|
|
75
|
+
const currentMiddleware = this.get(uid);
|
|
76
|
+
|
|
77
|
+
if (!currentMiddleware) {
|
|
78
|
+
throw new Error(`Middleware ${uid} doesn't exist`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const newMiddleware = extendFn(currentMiddleware);
|
|
82
|
+
middlewares[uid] = newMiddleware;
|
|
83
|
+
|
|
84
|
+
return this;
|
|
85
|
+
},
|
|
27
86
|
};
|
|
28
87
|
};
|
|
29
88
|
|
|
@@ -25,17 +25,17 @@ const modulesRegistry = strapi => {
|
|
|
25
25
|
},
|
|
26
26
|
async bootstrap() {
|
|
27
27
|
for (const mod of Object.values(modules)) {
|
|
28
|
-
await mod.bootstrap(
|
|
28
|
+
await mod.bootstrap();
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
async register() {
|
|
32
32
|
for (const mod of Object.values(modules)) {
|
|
33
|
-
await mod.register(
|
|
33
|
+
await mod.register();
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
async destroy() {
|
|
37
37
|
for (const mod of Object.values(modules)) {
|
|
38
|
-
await mod.destroy(
|
|
38
|
+
await mod.destroy();
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
};
|
|
@@ -17,8 +17,8 @@ const pluginsRegistry = strapi => {
|
|
|
17
17
|
throw new Error(`Plugin ${name} has already been registered.`);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const
|
|
21
|
-
plugins[name] =
|
|
20
|
+
const pluginModule = strapi.container.get('modules').add(`plugin::${name}`, pluginConfig);
|
|
21
|
+
plugins[name] = pluginModule;
|
|
22
22
|
|
|
23
23
|
return plugins[name];
|
|
24
24
|
},
|
|
@@ -3,16 +3,57 @@
|
|
|
3
3
|
const { pickBy, has } = require('lodash/fp');
|
|
4
4
|
const { addNamespace, hasNamespace } = require('../utils');
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('./policies').Policy} Policy
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// TODO: move instantiation part here instead of in the policy utils
|
|
6
11
|
const policiesRegistry = () => {
|
|
7
12
|
const policies = {};
|
|
8
13
|
|
|
9
14
|
return {
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Returns this list of registered policies uids
|
|
17
|
+
* @returns {string[]}
|
|
18
|
+
*/
|
|
19
|
+
keys() {
|
|
20
|
+
return Object.keys(policies);
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Returns the instance of a policy. Instantiate the policy if not already done
|
|
25
|
+
* @param {string} uid
|
|
26
|
+
* @returns {Policy}
|
|
27
|
+
*/
|
|
28
|
+
get(uid) {
|
|
29
|
+
return policies[uid];
|
|
12
30
|
},
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Returns a map with all the policies in a namespace
|
|
34
|
+
* @param {string} namespace
|
|
35
|
+
* @returns {{ [key: string]: Policy }}
|
|
36
|
+
*/
|
|
13
37
|
getAll(namespace) {
|
|
14
38
|
return pickBy((_, uid) => hasNamespace(uid, namespace))(policies);
|
|
15
39
|
},
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Registers a policy
|
|
43
|
+
* @param {string} uid
|
|
44
|
+
* @param {Policy} policy
|
|
45
|
+
*/
|
|
46
|
+
set(uid, policy) {
|
|
47
|
+
policies[uid] = policy;
|
|
48
|
+
return this;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Registers a map of policies for a specific namespace
|
|
53
|
+
* @param {string} namespace
|
|
54
|
+
* @param {{ [key: string]: Policy }} newPolicies
|
|
55
|
+
* @returns
|
|
56
|
+
*/
|
|
16
57
|
add(namespace, newPolicies) {
|
|
17
58
|
for (const policyName in newPolicies) {
|
|
18
59
|
const policy = newPolicies[policyName];
|
|
@@ -24,13 +65,23 @@ const policiesRegistry = () => {
|
|
|
24
65
|
policies[uid] = policy;
|
|
25
66
|
}
|
|
26
67
|
},
|
|
27
|
-
|
|
28
|
-
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Wraps a policy to extend it
|
|
71
|
+
* @param {string} uid
|
|
72
|
+
* @param {(policy: Policy) => Policy} extendFn
|
|
73
|
+
*/
|
|
74
|
+
extend(uid, extendFn) {
|
|
75
|
+
const currentPolicy = this.get(uid);
|
|
76
|
+
|
|
29
77
|
if (!currentPolicy) {
|
|
30
|
-
throw new Error(`Policy ${
|
|
78
|
+
throw new Error(`Policy ${uid} doesn't exist`);
|
|
31
79
|
}
|
|
80
|
+
|
|
32
81
|
const newPolicy = extendFn(currentPolicy);
|
|
33
|
-
policies[
|
|
82
|
+
policies[uid] = newPolicy;
|
|
83
|
+
|
|
84
|
+
return this;
|
|
34
85
|
},
|
|
35
86
|
};
|
|
36
87
|
};
|
|
@@ -1,36 +1,82 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const _ = require('lodash');
|
|
4
3
|
const { pickBy, has } = require('lodash/fp');
|
|
5
4
|
const { addNamespace, hasNamespace } = require('../utils');
|
|
6
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('./services').Service} Service
|
|
8
|
+
* @typedef {import('./services').ServiceFactory} ServiceFactory
|
|
9
|
+
*/
|
|
10
|
+
|
|
7
11
|
const servicesRegistry = strapi => {
|
|
8
12
|
const services = {};
|
|
9
|
-
const
|
|
13
|
+
const instantiatedServices = {};
|
|
10
14
|
|
|
11
15
|
return {
|
|
16
|
+
/**
|
|
17
|
+
* Returns this list of registered services uids
|
|
18
|
+
* @returns {string[]}
|
|
19
|
+
*/
|
|
20
|
+
keys() {
|
|
21
|
+
return Object.keys(services);
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Returns the instance of a service. Instantiate the service if not already done
|
|
26
|
+
* @param {string} uid
|
|
27
|
+
* @returns {Service}
|
|
28
|
+
*/
|
|
12
29
|
get(uid) {
|
|
13
|
-
if (
|
|
14
|
-
return
|
|
30
|
+
if (instantiatedServices[uid]) {
|
|
31
|
+
return instantiatedServices[uid];
|
|
15
32
|
}
|
|
16
33
|
|
|
17
34
|
const service = services[uid];
|
|
18
35
|
if (service) {
|
|
19
|
-
|
|
20
|
-
return
|
|
36
|
+
instantiatedServices[uid] = typeof service === 'function' ? service({ strapi }) : service;
|
|
37
|
+
return instantiatedServices[uid];
|
|
21
38
|
}
|
|
22
|
-
|
|
23
|
-
return undefined;
|
|
24
39
|
},
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns a map with all the services in a namespace
|
|
43
|
+
* @param {string} namespace
|
|
44
|
+
* @returns {{ [key: string]: Service }}
|
|
45
|
+
*/
|
|
25
46
|
getAll(namespace) {
|
|
26
47
|
const filteredServices = pickBy((_, uid) => hasNamespace(uid, namespace))(services);
|
|
27
48
|
|
|
28
|
-
|
|
49
|
+
// create lazy accessor to avoid instantiating the services;
|
|
50
|
+
const map = {};
|
|
51
|
+
for (const uid in filteredServices) {
|
|
52
|
+
Object.defineProperty(map, uid, {
|
|
53
|
+
enumerable: true,
|
|
54
|
+
get: () => {
|
|
55
|
+
return this.get(uid);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return map;
|
|
29
61
|
},
|
|
30
|
-
|
|
31
|
-
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Registers a service
|
|
65
|
+
* @param {string} uid
|
|
66
|
+
* @param {Service} service
|
|
67
|
+
*/
|
|
68
|
+
set(uid, service) {
|
|
69
|
+
services[uid] = service;
|
|
70
|
+
delete instantiatedServices[uid];
|
|
32
71
|
return this;
|
|
33
72
|
},
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Registers a map of services for a specific namespace
|
|
76
|
+
* @param {string} namespace
|
|
77
|
+
* @param {{ [key: string]: Service|ServiceFactory }} newServices
|
|
78
|
+
* @returns
|
|
79
|
+
*/
|
|
34
80
|
add(namespace, newServices) {
|
|
35
81
|
for (const serviceName in newServices) {
|
|
36
82
|
const service = newServices[serviceName];
|
|
@@ -44,13 +90,23 @@ const servicesRegistry = strapi => {
|
|
|
44
90
|
|
|
45
91
|
return this;
|
|
46
92
|
},
|
|
47
|
-
|
|
48
|
-
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Wraps a service to extend it
|
|
96
|
+
* @param {string} uid
|
|
97
|
+
* @param {(service: Service) => Service} extendFn
|
|
98
|
+
*/
|
|
99
|
+
extend(uid, extendFn) {
|
|
100
|
+
const currentService = this.get(uid);
|
|
101
|
+
|
|
49
102
|
if (!currentService) {
|
|
50
|
-
throw new Error(`Service ${
|
|
103
|
+
throw new Error(`Service ${uid} doesn't exist`);
|
|
51
104
|
}
|
|
105
|
+
|
|
52
106
|
const newService = extendFn(currentService);
|
|
53
|
-
|
|
107
|
+
instantiatedServices[uid] = newService;
|
|
108
|
+
|
|
109
|
+
return this;
|
|
54
110
|
},
|
|
55
111
|
};
|
|
56
112
|
};
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { isObject } = require('lodash/fp');
|
|
4
|
+
const { ValidationError } = require('@strapi/utils').errors;
|
|
5
|
+
|
|
3
6
|
const { parseBody } = require('./transform');
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
*
|
|
7
10
|
* Returns a collection type controller to handle default core-api actions
|
|
8
11
|
*/
|
|
9
|
-
const createCollectionTypeController = ({
|
|
12
|
+
const createCollectionTypeController = ({ contentType }) => {
|
|
13
|
+
const { uid } = contentType;
|
|
14
|
+
|
|
10
15
|
return {
|
|
11
16
|
/**
|
|
12
17
|
* Retrieve records.
|
|
@@ -16,9 +21,10 @@ const createCollectionTypeController = ({ service, sanitize, transformResponse }
|
|
|
16
21
|
async find(ctx) {
|
|
17
22
|
const { query } = ctx;
|
|
18
23
|
|
|
19
|
-
const { results, pagination } = await service.find(
|
|
24
|
+
const { results, pagination } = await strapi.service(uid).find(query);
|
|
25
|
+
const sanitizedResults = await this.sanitizeOutput(results, ctx);
|
|
20
26
|
|
|
21
|
-
return transformResponse(
|
|
27
|
+
return this.transformResponse(sanitizedResults, { pagination });
|
|
22
28
|
},
|
|
23
29
|
|
|
24
30
|
/**
|
|
@@ -30,9 +36,10 @@ const createCollectionTypeController = ({ service, sanitize, transformResponse }
|
|
|
30
36
|
const { id } = ctx.params;
|
|
31
37
|
const { query } = ctx;
|
|
32
38
|
|
|
33
|
-
const entity = await service.findOne(id,
|
|
39
|
+
const entity = await strapi.service(uid).findOne(id, query);
|
|
40
|
+
const sanitizedEntity = await this.sanitizeOutput(entity, ctx);
|
|
34
41
|
|
|
35
|
-
return transformResponse(
|
|
42
|
+
return this.transformResponse(sanitizedEntity);
|
|
36
43
|
},
|
|
37
44
|
|
|
38
45
|
/**
|
|
@@ -45,9 +52,18 @@ const createCollectionTypeController = ({ service, sanitize, transformResponse }
|
|
|
45
52
|
|
|
46
53
|
const { data, files } = parseBody(ctx);
|
|
47
54
|
|
|
48
|
-
|
|
55
|
+
if (!isObject(data)) {
|
|
56
|
+
throw new ValidationError('Missing "data" payload in the request body');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const sanitizedInputData = await this.sanitizeInput(data, ctx);
|
|
60
|
+
|
|
61
|
+
const entity = await strapi
|
|
62
|
+
.service(uid)
|
|
63
|
+
.create({ ...query, data: sanitizedInputData, files });
|
|
64
|
+
const sanitizedEntity = await this.sanitizeOutput(entity, ctx);
|
|
49
65
|
|
|
50
|
-
return transformResponse(
|
|
66
|
+
return this.transformResponse(sanitizedEntity);
|
|
51
67
|
},
|
|
52
68
|
|
|
53
69
|
/**
|
|
@@ -61,9 +77,18 @@ const createCollectionTypeController = ({ service, sanitize, transformResponse }
|
|
|
61
77
|
|
|
62
78
|
const { data, files } = parseBody(ctx);
|
|
63
79
|
|
|
64
|
-
|
|
80
|
+
if (!isObject(data)) {
|
|
81
|
+
throw new ValidationError('Missing "data" payload in the request body');
|
|
82
|
+
}
|
|
65
83
|
|
|
66
|
-
|
|
84
|
+
const sanitizedInputData = await this.sanitizeInput(data, ctx);
|
|
85
|
+
|
|
86
|
+
const entity = await strapi
|
|
87
|
+
.service(uid)
|
|
88
|
+
.update(id, { ...query, data: sanitizedInputData, files });
|
|
89
|
+
const sanitizedEntity = await this.sanitizeOutput(entity, ctx);
|
|
90
|
+
|
|
91
|
+
return this.transformResponse(sanitizedEntity);
|
|
67
92
|
},
|
|
68
93
|
|
|
69
94
|
/**
|
|
@@ -75,8 +100,10 @@ const createCollectionTypeController = ({ service, sanitize, transformResponse }
|
|
|
75
100
|
const { id } = ctx.params;
|
|
76
101
|
const { query } = ctx;
|
|
77
102
|
|
|
78
|
-
const entity = await service.delete(id,
|
|
79
|
-
|
|
103
|
+
const entity = await strapi.service(uid).delete(id, query);
|
|
104
|
+
const sanitizedEntity = await this.sanitizeOutput(entity, ctx);
|
|
105
|
+
|
|
106
|
+
return this.transformResponse(sanitizedEntity);
|
|
80
107
|
},
|
|
81
108
|
};
|
|
82
109
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Context } from 'koa';
|
|
2
|
+
|
|
3
|
+
type Response = object;
|
|
4
|
+
|
|
5
|
+
interface BaseController {
|
|
6
|
+
transformResponse(data: object, meta: object): object;
|
|
7
|
+
sanitizeOutput(data: object, ctx: Context): Promise<object>;
|
|
8
|
+
sanitizeInput(data: object, ctx: Context): Promise<object>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface SingleTypeController extends BaseController {
|
|
12
|
+
find(ctx: Context): Promise<Response>;
|
|
13
|
+
update(ctx: Context): Promise<Response>;
|
|
14
|
+
delete(ctx: Context): Promise<Response>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface CollectionTypeController extends BaseController {
|
|
18
|
+
find(ctx: Context): Promise<Response>;
|
|
19
|
+
findOne(ctx: Context): Promise<Response>;
|
|
20
|
+
create(ctx: Context): Promise<Response>;
|
|
21
|
+
update(ctx: Context): Promise<Response>;
|
|
22
|
+
delete(ctx: Context): Promise<Response>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type Controller = SingleTypeController | CollectionTypeController;
|