@strapi/strapi 4.0.0-next.6 → 4.0.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.
- package/README.md +12 -12
- package/bin/strapi.js +41 -60
- package/lib/Strapi.js +234 -114
- package/lib/commands/build.js +16 -6
- package/lib/commands/console.js +1 -1
- package/lib/commands/content-types/list.js +22 -0
- package/lib/commands/develop.js +17 -18
- 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 -8
- package/lib/container.js +6 -6
- package/lib/core/app-configuration/config-loader.js +1 -37
- package/lib/core/app-configuration/index.js +6 -46
- package/lib/core/app-configuration/load-config-file.js +43 -0
- package/lib/core/bootstrap.js +5 -117
- package/lib/core/domain/component/index.js +24 -0
- package/lib/core/domain/component/validator.js +29 -0
- package/lib/core/domain/content-type/index.js +140 -0
- package/lib/core/domain/content-type/validator.js +64 -0
- package/lib/core/domain/module/index.js +108 -0
- package/lib/core/domain/module/validation.js +33 -0
- package/lib/core/loaders/admin.js +16 -0
- package/lib/core/loaders/apis.js +159 -0
- package/lib/core/{load-components.js → loaders/components.js} +5 -7
- package/lib/core/loaders/index.js +11 -0
- package/lib/core/loaders/middlewares.js +36 -0
- package/lib/core/loaders/plugins/get-enabled-plugins.js +116 -0
- package/lib/core/loaders/plugins/index.js +123 -0
- package/lib/core/loaders/policies.js +28 -0
- package/lib/core/loaders/src-index.js +39 -0
- package/lib/core/registries/apis.js +29 -0
- package/lib/core/{app-configuration/config-provider.js → registries/config.js} +4 -11
- package/lib/core/registries/content-types.js +97 -0
- package/lib/core/registries/controllers.d.ts +7 -0
- package/lib/core/registries/controllers.js +114 -0
- 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 +89 -0
- package/lib/core/registries/modules.js +44 -0
- package/lib/core/registries/plugins.js +28 -0
- package/lib/core/registries/policies.d.ts +9 -0
- package/lib/core/registries/policies.js +89 -0
- package/lib/core/registries/services.d.ts +7 -0
- package/lib/core/registries/services.js +114 -0
- package/lib/core/utils.js +35 -0
- package/lib/core-api/controller/collection-type.js +45 -26
- package/lib/core-api/controller/index.d.ts +25 -0
- package/lib/core-api/controller/index.js +33 -11
- package/lib/core-api/controller/single-type.js +29 -15
- package/lib/core-api/controller/transform.js +62 -6
- package/lib/core-api/routes/index.js +71 -0
- package/lib/core-api/service/collection-type.js +43 -21
- package/lib/core-api/service/index.d.ts +21 -0
- package/lib/core-api/service/index.js +8 -67
- package/lib/core-api/service/pagination.js +130 -0
- package/lib/core-api/service/single-type.js +17 -19
- 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 -117
- 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 +98 -73
- 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 -51
- 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 +120 -59
- package/lib/services/entity-service/params.js +52 -94
- package/lib/services/entity-validator/index.js +76 -43
- package/lib/services/entity-validator/validators.js +129 -43
- package/lib/services/errors.js +77 -0
- package/lib/{core → services}/fs.js +10 -2
- package/lib/services/metrics/index.js +41 -38
- package/lib/services/metrics/sender.js +2 -2
- 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/utils/upload-files.js +1 -1
- 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/is-initialized.js +1 -1
- package/lib/utils/run-checks.js +0 -15
- package/lib/utils/signals.js +24 -0
- package/lib/utils/startup-logger.js +2 -2
- package/lib/utils/update-notifier/index.js +3 -2
- package/package.json +93 -96
- package/lib/commands/generate.js +0 -76
- package/lib/core/index.js +0 -17
- package/lib/core/load-apis.js +0 -20
- package/lib/core/load-extensions.js +0 -71
- package/lib/core/load-functions.js +0 -21
- package/lib/core/load-middlewares.js +0 -130
- package/lib/core/load-modules.js +0 -55
- package/lib/core/load-plugins.js +0 -68
- package/lib/core/load-policies.js +0 -36
- package/lib/core/walk.js +0 -27
- package/lib/core-api/index.js +0 -39
- package/lib/load/check-reserved-filename.js +0 -10
- package/lib/load/load-config-files.js +0 -22
- package/lib/load/require-file-parse.js +0 -15
- 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 -71
- 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 -64
- package/lib/middlewares/router/utils/composeEndpoint.js +0 -25
- package/lib/middlewares/router/utils/routerChecker.js +0 -92
- package/lib/utils/get-prefixed-dependencies.js +0 -7
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Service } from './core-api/service';
|
|
2
|
+
import { Controller } from './core-api/controller';
|
|
3
|
+
import { Middleware } from './middlewares';
|
|
4
|
+
import { Policy } from './core/registries/policies';
|
|
5
|
+
|
|
6
|
+
type ControllerConfig = Controller;
|
|
7
|
+
|
|
8
|
+
type ServiceConfig = Service;
|
|
9
|
+
|
|
10
|
+
type HandlerConfig = {
|
|
11
|
+
auth: false | { scope: string[] };
|
|
12
|
+
policies: Array<string | Policy>;
|
|
13
|
+
middlewares: Array<string | Middleware>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
type SingleTypeRouterConfig = {
|
|
17
|
+
find: HandlerConfig;
|
|
18
|
+
update: HandlerConfig;
|
|
19
|
+
delete: HandlerConfig;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type CollectionTypeRouterConfig = {
|
|
23
|
+
find: HandlerConfig;
|
|
24
|
+
findOne: HandlerConfig;
|
|
25
|
+
create: HandlerConfig;
|
|
26
|
+
update: HandlerConfig;
|
|
27
|
+
delete: HandlerConfig;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type RouterConfig = {
|
|
31
|
+
prefix: string;
|
|
32
|
+
only: string[];
|
|
33
|
+
except: string[];
|
|
34
|
+
config: SingleTypeRouterConfig | CollectionTypeRouterConfig;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
interface Route {
|
|
38
|
+
method: string;
|
|
39
|
+
path: string;
|
|
40
|
+
}
|
|
41
|
+
interface Router {
|
|
42
|
+
prefix: string;
|
|
43
|
+
routes: Route[];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function createCoreRouter(uid: string, cfg: RouterConfig): () => Router;
|
|
47
|
+
export function createCoreController(uid: string, cfg: ControllerConfig): () => Controller;
|
|
48
|
+
export function createCoreService(uid: string, cfg: ServiceConfig): () => Service;
|
package/lib/factories.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { pipe, omit, pick } = require('lodash/fp');
|
|
4
|
+
|
|
5
|
+
const { createController } = require('./core-api/controller');
|
|
6
|
+
const { createService } = require('./core-api/service');
|
|
7
|
+
const { createRoutes } = require('./core-api/routes');
|
|
8
|
+
|
|
9
|
+
const createCoreController = (uid, cfg = {}) => {
|
|
10
|
+
return ({ strapi }) => {
|
|
11
|
+
const baseController = createController({
|
|
12
|
+
contentType: strapi.contentType(uid),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
let userCtrl = typeof cfg === 'function' ? cfg({ strapi }) : cfg;
|
|
16
|
+
|
|
17
|
+
for (const methodName of Object.keys(baseController)) {
|
|
18
|
+
if (userCtrl[methodName] === undefined) {
|
|
19
|
+
userCtrl[methodName] = baseController[methodName];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Object.setPrototypeOf(userCtrl, baseController);
|
|
24
|
+
return userCtrl;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const createCoreService = (uid, cfg = {}) => {
|
|
29
|
+
return ({ strapi }) => {
|
|
30
|
+
const baseService = createService({
|
|
31
|
+
contentType: strapi.contentType(uid),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
let userService = typeof cfg === 'function' ? cfg({ strapi }) : cfg;
|
|
35
|
+
|
|
36
|
+
for (const methodName of Object.keys(baseService)) {
|
|
37
|
+
if (userService[methodName] === undefined) {
|
|
38
|
+
userService[methodName] = baseService[methodName];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
Object.setPrototypeOf(userService, baseService);
|
|
43
|
+
return userService;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const createCoreRouter = (uid, cfg = {}) => {
|
|
48
|
+
const { prefix, config = {}, only, except } = cfg;
|
|
49
|
+
let routes;
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
get prefix() {
|
|
53
|
+
return prefix;
|
|
54
|
+
},
|
|
55
|
+
get routes() {
|
|
56
|
+
if (!routes) {
|
|
57
|
+
const contentType = strapi.contentType(uid);
|
|
58
|
+
|
|
59
|
+
const defaultRoutes = createRoutes({ contentType });
|
|
60
|
+
|
|
61
|
+
Object.keys(defaultRoutes).forEach(routeName => {
|
|
62
|
+
const defaultRoute = defaultRoutes[routeName];
|
|
63
|
+
|
|
64
|
+
Object.assign(defaultRoute.config, config[routeName] || {});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const selectedRoutes = pipe(
|
|
68
|
+
routes => (except ? omit(except, routes) : routes),
|
|
69
|
+
routes => (only ? pick(only, routes) : routes)
|
|
70
|
+
)(defaultRoutes);
|
|
71
|
+
|
|
72
|
+
routes = Object.values(selectedRoutes);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return routes;
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
module.exports = {
|
|
81
|
+
createCoreController,
|
|
82
|
+
createCoreService,
|
|
83
|
+
createCoreRouter,
|
|
84
|
+
};
|
package/lib/index.d.ts
CHANGED
|
@@ -1,40 +1,15 @@
|
|
|
1
1
|
import { Database } from '@strapi/database';
|
|
2
|
-
import {
|
|
2
|
+
import { EntityService } from './services/entity-service';
|
|
3
|
+
import { Strapi as StrapiClass } from './Strapi';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
interface Options<T> {
|
|
7
|
-
params: Params<T>;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface Params<T> {
|
|
11
|
-
fields: (keyof T)[];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface EntityService {
|
|
15
|
-
uploadFiles<T extends keyof AllTypes>(uid: T);
|
|
16
|
-
wrapOptions<T extends keyof AllTypes>(uid: T);
|
|
17
|
-
|
|
18
|
-
find<T extends keyof AllTypes>(uid: T): Promise<AllTypes[T][]>;
|
|
19
|
-
findPage<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
20
|
-
findWithRelationCounts<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
21
|
-
findOne<T extends keyof AllTypes>(
|
|
22
|
-
uid: T,
|
|
23
|
-
id: ID,
|
|
24
|
-
opts: Options<AllTypes[T]>
|
|
25
|
-
): Promise<AllTypes[T]>;
|
|
26
|
-
|
|
27
|
-
count<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
28
|
-
create<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
29
|
-
update<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
30
|
-
delete<T extends keyof AllTypes>(uid: T): Promise<any>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
interface StrapiInterface extends Strapi {
|
|
5
|
+
export * as factories from './factories';
|
|
6
|
+
interface StrapiInterface extends StrapiClass {
|
|
34
7
|
query: Database['query'];
|
|
35
8
|
entityService: EntityService;
|
|
36
9
|
}
|
|
37
10
|
|
|
11
|
+
export type Strapi = StrapiInterface;
|
|
12
|
+
|
|
38
13
|
declare global {
|
|
39
14
|
interface AllTypes {}
|
|
40
15
|
}
|
|
@@ -44,5 +19,9 @@ declare global {
|
|
|
44
19
|
strapi: StrapiInterface;
|
|
45
20
|
}
|
|
46
21
|
|
|
22
|
+
export type Strapi = StrapiInterface;
|
|
23
|
+
|
|
47
24
|
const strapi: StrapiInterface;
|
|
48
25
|
}
|
|
26
|
+
|
|
27
|
+
export default function(opts): Strapi;
|
package/lib/index.js
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { defaultsDeep } = require('lodash/fp');
|
|
4
|
+
const body = require('koa-body');
|
|
5
|
+
|
|
6
|
+
const defaults = {
|
|
7
|
+
multipart: true,
|
|
8
|
+
patchKoa: true,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @type {import('./').MiddlewareFactory}
|
|
13
|
+
*/
|
|
14
|
+
module.exports = config => {
|
|
15
|
+
const bodyConfig = defaultsDeep(defaults, config);
|
|
16
|
+
|
|
17
|
+
return async (ctx, next) => {
|
|
18
|
+
// TODO: find a better way later
|
|
19
|
+
if (ctx.url === '/graphql') {
|
|
20
|
+
return next();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
await body({ patchKoa: true, ...bodyConfig })(ctx, next);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
if ((e || {}).message && e.message.includes('maxFileSize exceeded')) {
|
|
27
|
+
return ctx.payloadTooLarge('FileTooBig');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
throw e;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { defaultsDeep } = require('lodash/fp');
|
|
4
|
+
const cors = require('@koa/cors');
|
|
5
|
+
|
|
6
|
+
const defaults = {
|
|
7
|
+
origin: '*',
|
|
8
|
+
maxAge: 31536000,
|
|
9
|
+
credentials: true,
|
|
10
|
+
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
|
|
11
|
+
headers: ['Content-Type', 'Authorization', 'Origin', 'Accept'],
|
|
12
|
+
keepHeadersOnError: false,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @type {import('./').MiddlewareFactory}
|
|
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);
|
|
28
|
+
|
|
29
|
+
return cors({
|
|
30
|
+
async origin(ctx) {
|
|
31
|
+
let originList;
|
|
32
|
+
|
|
33
|
+
if (typeof origin === 'function') {
|
|
34
|
+
originList = await origin(ctx);
|
|
35
|
+
} else {
|
|
36
|
+
originList = origin;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const whitelist = Array.isArray(originList) ? originList : originList.split(/\s*,\s*/);
|
|
40
|
+
|
|
41
|
+
const requestOrigin = ctx.accept.headers.origin;
|
|
42
|
+
if (whitelist.includes('*')) {
|
|
43
|
+
return '*';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!whitelist.includes(requestOrigin)) {
|
|
47
|
+
return ctx.throw(`${requestOrigin} is not a valid origin`);
|
|
48
|
+
}
|
|
49
|
+
return requestOrigin;
|
|
50
|
+
},
|
|
51
|
+
exposeHeaders: expose,
|
|
52
|
+
maxAge,
|
|
53
|
+
credentials,
|
|
54
|
+
allowMethods: methods,
|
|
55
|
+
allowHeaders: headers,
|
|
56
|
+
keepHeadersOnError,
|
|
57
|
+
});
|
|
58
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { HttpError, ApplicationError } = require('@strapi/utils').errors;
|
|
4
|
+
const {
|
|
5
|
+
formatApplicationError,
|
|
6
|
+
formatHttpError,
|
|
7
|
+
formatInternalError,
|
|
8
|
+
} = require('../services/errors');
|
|
9
|
+
|
|
10
|
+
module.exports = (/* _, { strapi } */) => {
|
|
11
|
+
return async (ctx, next) => {
|
|
12
|
+
try {
|
|
13
|
+
await next();
|
|
14
|
+
|
|
15
|
+
if (!ctx.response._explicitStatus) {
|
|
16
|
+
return ctx.notFound();
|
|
17
|
+
}
|
|
18
|
+
} catch (error) {
|
|
19
|
+
if (error instanceof ApplicationError) {
|
|
20
|
+
const { status, body } = formatApplicationError(error);
|
|
21
|
+
ctx.status = status;
|
|
22
|
+
ctx.body = body;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (error instanceof HttpError) {
|
|
27
|
+
const { status, body } = formatHttpError(error);
|
|
28
|
+
ctx.status = status;
|
|
29
|
+
ctx.body = body;
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
strapi.log.error(error);
|
|
34
|
+
|
|
35
|
+
const { status, body } = formatInternalError(error);
|
|
36
|
+
ctx.status = status;
|
|
37
|
+
ctx.body = body;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { resolve } = require('path');
|
|
4
|
+
const { defaultsDeep } = require('lodash/fp');
|
|
5
|
+
const favicon = require('koa-favicon');
|
|
6
|
+
|
|
7
|
+
const defaults = {
|
|
8
|
+
path: 'favicon.ico',
|
|
9
|
+
maxAge: 86400000,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @type {import('./').MiddlewareFactory}
|
|
14
|
+
*/
|
|
15
|
+
module.exports = (config, { strapi }) => {
|
|
16
|
+
const { maxAge, path: faviconPath } = defaultsDeep(defaults, config);
|
|
17
|
+
|
|
18
|
+
return favicon(resolve(strapi.dirs.root, faviconPath), { maxAge });
|
|
19
|
+
};
|
package/lib/middlewares/index.js
CHANGED
|
@@ -1,120 +1,33 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
// list of enabled middlewares
|
|
36
|
-
const enabledMiddlewares = Object.keys(this.middleware).filter(middlewareEnabled);
|
|
37
|
-
|
|
38
|
-
// Method to initialize middlewares and emit an event.
|
|
39
|
-
const initialize = middlewareKey => {
|
|
40
|
-
if (this.middleware[middlewareKey].loaded === true) return;
|
|
41
|
-
|
|
42
|
-
const module = this.middleware[middlewareKey].load;
|
|
43
|
-
|
|
44
|
-
return new Promise((resolve, reject) => {
|
|
45
|
-
const timeout = setTimeout(
|
|
46
|
-
() => reject(`(middleware: ${middlewareKey}) is taking too long to load.`),
|
|
47
|
-
middlewareConfig.timeout || 1000
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
this.middleware[middlewareKey] = merge(this.middleware[middlewareKey], module);
|
|
51
|
-
|
|
52
|
-
Promise.resolve()
|
|
53
|
-
.then(() => module.initialize())
|
|
54
|
-
.then(() => {
|
|
55
|
-
clearTimeout(timeout);
|
|
56
|
-
this.middleware[middlewareKey].loaded = true;
|
|
57
|
-
resolve();
|
|
58
|
-
})
|
|
59
|
-
.catch(err => {
|
|
60
|
-
clearTimeout(timeout);
|
|
61
|
-
|
|
62
|
-
if (err) {
|
|
63
|
-
return reject(err);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Run init functions
|
|
71
|
-
*/
|
|
72
|
-
|
|
73
|
-
// Run beforeInitialize of every middleware
|
|
74
|
-
await Promise.all(
|
|
75
|
-
enabledMiddlewares.map(key => {
|
|
76
|
-
const { beforeInitialize } = this.middleware[key].load;
|
|
77
|
-
if (typeof beforeInitialize === 'function') {
|
|
78
|
-
return beforeInitialize();
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
// run the initialization of an array of middlewares sequentially
|
|
84
|
-
const initMiddlewaresSeq = async middlewareArr => {
|
|
85
|
-
for (let key of uniq(middlewareArr)) {
|
|
86
|
-
await initialize(key);
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const middlewaresBefore = get(middlewareConfig, 'load.before', [])
|
|
91
|
-
.filter(middlewareExists)
|
|
92
|
-
.filter(middlewareEnabled);
|
|
93
|
-
|
|
94
|
-
const middlewaresAfter = get(middlewareConfig, 'load.after', [])
|
|
95
|
-
.filter(middlewareExists)
|
|
96
|
-
.filter(middlewareEnabled);
|
|
97
|
-
|
|
98
|
-
const middlewaresOrder = get(middlewareConfig, 'load.order', [])
|
|
99
|
-
.filter(middlewareExists)
|
|
100
|
-
.filter(middlewareEnabled);
|
|
101
|
-
|
|
102
|
-
const unspecifiedMiddlewares = difference(
|
|
103
|
-
enabledMiddlewares,
|
|
104
|
-
middlewaresBefore,
|
|
105
|
-
middlewaresOrder,
|
|
106
|
-
middlewaresAfter
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
// before
|
|
110
|
-
await initMiddlewaresSeq(middlewaresBefore);
|
|
111
|
-
|
|
112
|
-
// ordered // rest of middlewares
|
|
113
|
-
await Promise.all([
|
|
114
|
-
initMiddlewaresSeq(middlewaresOrder),
|
|
115
|
-
Promise.all(unspecifiedMiddlewares.map(initialize)),
|
|
116
|
-
]);
|
|
117
|
-
|
|
118
|
-
// after
|
|
119
|
-
await initMiddlewaresSeq(middlewaresAfter);
|
|
3
|
+
const compression = require('./compression');
|
|
4
|
+
const cors = require('./cors');
|
|
5
|
+
const errors = require('./errors');
|
|
6
|
+
const favicon = require('./favicon');
|
|
7
|
+
const ip = require('./ip');
|
|
8
|
+
const logger = require('./logger');
|
|
9
|
+
const poweredBy = require('./powered-by');
|
|
10
|
+
const body = require('./body');
|
|
11
|
+
const query = require('./query');
|
|
12
|
+
const responseTime = require('./response-time');
|
|
13
|
+
const responses = require('./responses');
|
|
14
|
+
const security = require('./security');
|
|
15
|
+
// TODO: add back ?
|
|
16
|
+
// session: require('./session'),
|
|
17
|
+
const publicStatic = require('./public');
|
|
18
|
+
|
|
19
|
+
module.exports = {
|
|
20
|
+
errors,
|
|
21
|
+
ip,
|
|
22
|
+
security,
|
|
23
|
+
cors,
|
|
24
|
+
responseTime,
|
|
25
|
+
poweredBy,
|
|
26
|
+
logger,
|
|
27
|
+
compression,
|
|
28
|
+
responses,
|
|
29
|
+
body,
|
|
30
|
+
query,
|
|
31
|
+
favicon,
|
|
32
|
+
public: publicStatic,
|
|
120
33
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
|
|
4
|
+
const codeToColor = code => {
|
|
5
|
+
return code >= 500
|
|
6
|
+
? chalk.red(code)
|
|
7
|
+
: code >= 400
|
|
8
|
+
? chalk.yellow(code)
|
|
9
|
+
: code >= 300
|
|
10
|
+
? chalk.cyan(code)
|
|
11
|
+
: code >= 200
|
|
12
|
+
? chalk.green(code)
|
|
13
|
+
: code;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @type {import('./').MiddlewareFactory}
|
|
18
|
+
*/
|
|
19
|
+
module.exports = (_, { strapi }) => {
|
|
20
|
+
return async (ctx, next) => {
|
|
21
|
+
const start = Date.now();
|
|
22
|
+
await next();
|
|
23
|
+
const delta = Math.ceil(Date.now() - start);
|
|
24
|
+
|
|
25
|
+
strapi.log.http(`${ctx.method} ${ctx.url} (${delta} ms) ${codeToColor(ctx.status)}`);
|
|
26
|
+
};
|
|
27
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { defaultsDeep } = require('lodash/fp');
|
|
4
|
+
|
|
5
|
+
const defaults = {
|
|
6
|
+
poweredBy: 'Strapi <strapi.io>',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @type {import('./').MiddlewareFactory}
|
|
11
|
+
*/
|
|
12
|
+
module.exports = config => {
|
|
13
|
+
const { poweredBy } = defaultsDeep(defaults, config);
|
|
14
|
+
|
|
15
|
+
return async (ctx, next) => {
|
|
16
|
+
await next();
|
|
17
|
+
|
|
18
|
+
ctx.set('X-Powered-By', poweredBy);
|
|
19
|
+
};
|
|
20
|
+
};
|