@feathersjs/koa 5.0.0-pre.9 → 5.0.1

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/src/rest.ts CHANGED
@@ -1,51 +1,94 @@
1
- import { Next } from 'koa';
2
- import { http } from '@feathersjs/transport-commons';
3
- import { createDebug } from '@feathersjs/commons';
4
- import { getServiceOptions, defaultServiceMethods, createContext } from '@feathersjs/feathers';
5
- import { MethodNotAllowed } from '@feathersjs/errors';
6
- import { FeathersKoaContext } from './declarations';
7
-
8
- const debug = createDebug('@feathersjs/koa:rest');
9
-
10
- export function rest () {
11
- return async (ctx: FeathersKoaContext, next: Next) => {
12
- const { app, request } = ctx;
13
- const { query: koaQuery, path, body: data, method: httpMethod } = request;
14
- const query = { ...koaQuery };
15
- const methodOverride = request.headers[http.METHOD_HEADER] ?
16
- request.headers[http.METHOD_HEADER] as string : null;
17
- const lookup = app.lookup(path);
18
-
19
- if (lookup !== null) {
20
- const { service, params: { __id: id = null, ...route } = {} } = lookup;
21
- const method = http.getServiceMethod(httpMethod, id, methodOverride);
22
- const { methods } = getServiceOptions(service);
23
-
24
- debug(`Found service for path ${path}, attempting to run '${method}' service method`);
25
-
26
- if (!methods.includes(method) || defaultServiceMethods.includes(methodOverride)) {
27
- ctx.response.status = http.statusCodes.methodNotAllowed;
28
-
29
- throw new MethodNotAllowed(`Method \`${method}\` is not supported by this endpoint.`);
30
- }
31
-
32
- const createArguments = (http.argumentsFor as any)[method] || http.argumentsFor.default;
33
- const params = {
34
- ...ctx.feathers,
35
- query,
36
- route
37
- };
38
- const args = createArguments({ id, data, params });
39
- const hookContext = createContext(service, method);
40
-
41
- ctx.hook = hookContext as any;
42
-
43
- const result = await (service as any)[method](...args, hookContext);
44
-
45
- ctx.response.status = http.getStatusCode(result, {});
46
- ctx.body = http.getData(result);
1
+ import compose from 'koa-compose'
2
+ import { http } from '@feathersjs/transport-commons'
3
+ import { createDebug } from '@feathersjs/commons'
4
+ import { getServiceOptions, defaultServiceMethods, createContext } from '@feathersjs/feathers'
5
+ import { MethodNotAllowed } from '@feathersjs/errors'
6
+
7
+ import { Application, Middleware } from './declarations'
8
+ import { AuthenticationSettings, parseAuthentication } from './authentication'
9
+
10
+ const debug = createDebug('@feathersjs/koa/rest')
11
+
12
+ const serviceMiddleware = (): Middleware => {
13
+ return async (ctx, next) => {
14
+ const { query, headers, path, body: data, method: httpMethod } = ctx.request
15
+ const methodOverride = ctx.request.headers[http.METHOD_HEADER] as string | undefined
16
+
17
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
18
+ const { service, params: { __id: id = null, ...route } = {} } = ctx.lookup!
19
+ const method = http.getServiceMethod(httpMethod, id, methodOverride)
20
+ const { methods } = getServiceOptions(service)
21
+
22
+ debug(`Found service for path ${path}, attempting to run '${method}' service method`)
23
+
24
+ if (!methods.includes(method) || defaultServiceMethods.includes(methodOverride)) {
25
+ const error = new MethodNotAllowed(`Method \`${method}\` is not supported by this endpoint.`)
26
+ ctx.response.status = error.code
27
+ throw error
28
+ }
29
+
30
+ const createArguments = http.argumentsFor[method as 'get'] || http.argumentsFor.default
31
+ const params = { query, headers, route, ...ctx.feathers }
32
+ const args = createArguments({ id, data, params })
33
+ const contextBase = createContext(service, method, { http: {} })
34
+ ctx.hook = contextBase
35
+
36
+ const context = await (service as any)[method](...args, contextBase)
37
+ ctx.hook = context
38
+
39
+ const response = http.getResponse(context)
40
+ ctx.status = response.status
41
+ ctx.set(response.headers)
42
+ ctx.body = response.body
43
+
44
+ return next()
45
+ }
46
+ }
47
+
48
+ const servicesMiddleware = (): Middleware => {
49
+ return async (ctx, next) => {
50
+ const app = ctx.app
51
+ const lookup = app.lookup(ctx.request.path)
52
+
53
+ if (!lookup) {
54
+ return next()
47
55
  }
48
56
 
49
- return next();
50
- };
57
+ ctx.lookup = lookup
58
+
59
+ const options = getServiceOptions(lookup.service)
60
+ const middleware = options.koa.composed
61
+
62
+ return middleware(ctx, next)
63
+ }
64
+ }
65
+
66
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
67
+ export const formatter: Middleware = (_ctx, _next) => {}
68
+
69
+ export type RestOptions = {
70
+ formatter?: Middleware
71
+ authentication?: AuthenticationSettings
72
+ }
73
+
74
+ export const rest = (options?: RestOptions | Middleware) => {
75
+ options = typeof options === 'function' ? { formatter: options } : options || {}
76
+
77
+ const formatterMiddleware = options.formatter || formatter
78
+ const authenticationOptions = options.authentication
79
+
80
+ return (app: Application) => {
81
+ app.use(parseAuthentication(authenticationOptions))
82
+ app.use(servicesMiddleware())
83
+
84
+ app.mixins.push((_service, _path, options) => {
85
+ const { koa: { before = [], after = [] } = {} } = options
86
+
87
+ const middlewares = [].concat(before, serviceMiddleware(), after, formatterMiddleware)
88
+ const middleware = compose(middlewares)
89
+
90
+ options.koa ||= {}
91
+ options.koa.composed = middleware
92
+ })
93
+ }
51
94
  }
@@ -1,8 +0,0 @@
1
- import { Next } from 'koa';
2
- import { FeathersKoaContext } from './declarations';
3
- interface MiddlewareSettings {
4
- service?: string;
5
- strategies?: string[];
6
- }
7
- export declare function authentication(settings?: MiddlewareSettings): (ctx: FeathersKoaContext, next: Next) => Promise<any>;
8
- export {};
@@ -1,38 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.authentication = void 0;
13
- const commons_1 = require("@feathersjs/commons");
14
- const debug = commons_1.createDebug('@feathersjs/koa:authentication');
15
- function authentication(settings = {}) {
16
- return (ctx, next) => __awaiter(this, void 0, void 0, function* () {
17
- const { app } = ctx;
18
- const service = app.defaultAuthentication ? app.defaultAuthentication(settings.service) : null;
19
- if (service === null) {
20
- return next();
21
- }
22
- const config = service.configuration;
23
- const authStrategies = settings.strategies || config.parseStrategies || config.authStrategies || [];
24
- if (authStrategies.length === 0) {
25
- debug('No `authStrategies` or `parseStrategies` found in authentication configuration');
26
- return next();
27
- }
28
- const { req, res } = ctx;
29
- const authentication = yield service.parse(req, res, ...authStrategies);
30
- if (authentication) {
31
- debug('Parsed authentication from HTTP header', authentication);
32
- ctx.feathers.authentication = authentication;
33
- }
34
- return next();
35
- });
36
- }
37
- exports.authentication = authentication;
38
- //# sourceMappingURL=authenticate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../src/authenticate.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,iDAAkD;AAIlD,MAAM,KAAK,GAAG,qBAAW,CAAC,gCAAgC,CAAC,CAAC;AAO5D,SAAgB,cAAc,CAAE,WAA+B,EAAE;IAC/D,OAAO,CAAO,GAAuB,EAAE,IAAU,EAAE,EAAE;QACnD,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;QACpB,MAAM,OAAO,GAAG,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE/F,IAAI,OAAO,KAAK,IAAI,EAAE;YACpB,OAAO,IAAI,EAAE,CAAC;SACf;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;QACrC,MAAM,cAAc,GAAG,QAAQ,CAAC,UAAU,IAAI,MAAM,CAAC,eAAe,IAAI,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC;QAEpG,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;YAC/B,KAAK,CAAC,gFAAgF,CAAC,CAAC;YACxF,OAAO,IAAI,EAAE,CAAC;SACf;QAED,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAU,CAAC;QAChC,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,cAAc,CAAC,CAAC;QAExE,IAAI,cAAc,EAAE;YAClB,KAAK,CAAC,wCAAwC,EAAE,cAAc,CAAC,CAAC;YAChE,GAAG,CAAC,QAAQ,CAAC,cAAc,GAAG,cAAc,CAAC;SAC9C;QAED,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAA,CAAC;AACJ,CAAC;AA3BD,wCA2BC"}
@@ -1,29 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.errorHandler = void 0;
13
- const errors_1 = require("@feathersjs/errors");
14
- const errorHandler = () => (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
15
- try {
16
- yield next();
17
- if (ctx.body === undefined) {
18
- throw new errors_1.NotFound('Not Found');
19
- }
20
- }
21
- catch (error) {
22
- ctx.response.status = error.code || 500;
23
- ctx.body = typeof error.toJSON === 'function' ? error.toJSON() : {
24
- message: error.message
25
- };
26
- }
27
- });
28
- exports.errorHandler = errorHandler;
29
- //# sourceMappingURL=error-handler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../src/error-handler.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+CAA8C;AAGvC,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,CAAO,GAAuB,EAAE,IAAwB,EAAE,EAAE;IAC5F,IAAI;QACF,MAAM,IAAI,EAAE,CAAC;QAEb,IAAG,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE;YACzB,MAAM,IAAI,iBAAQ,CAAC,WAAW,CAAC,CAAC;SACjC;KAEF;IAAC,OAAO,KAAK,EAAE;QACd,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,IAAI,GAAG,CAAC;QACxC,GAAG,CAAC,IAAI,GAAG,OAAO,KAAK,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC/D,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC;KACH;AACH,CAAC,CAAA,CAAC;AAdW,QAAA,YAAY,gBAcvB"}
@@ -1,40 +0,0 @@
1
- import { Next } from 'koa';
2
- import { createDebug } from '@feathersjs/commons';
3
-
4
- import { FeathersKoaContext } from './declarations';
5
-
6
- const debug = createDebug('@feathersjs/koa:authentication');
7
-
8
- interface MiddlewareSettings {
9
- service?: string;
10
- strategies?: string[];
11
- }
12
-
13
- export function authentication (settings: MiddlewareSettings = {}) {
14
- return async (ctx: FeathersKoaContext, next: Next) => {
15
- const { app } = ctx;
16
- const service = app.defaultAuthentication ? app.defaultAuthentication(settings.service) : null;
17
-
18
- if (service === null) {
19
- return next();
20
- }
21
-
22
- const config = service.configuration;
23
- const authStrategies = settings.strategies || config.parseStrategies || config.authStrategies || [];
24
-
25
- if (authStrategies.length === 0) {
26
- debug('No `authStrategies` or `parseStrategies` found in authentication configuration');
27
- return next();
28
- }
29
-
30
- const { req, res } = ctx as any;
31
- const authentication = await service.parse(req, res, ...authStrategies);
32
-
33
- if (authentication) {
34
- debug('Parsed authentication from HTTP header', authentication);
35
- ctx.feathers.authentication = authentication;
36
- }
37
-
38
- return next();
39
- };
40
- }
@@ -1,18 +0,0 @@
1
- import { NotFound } from '@feathersjs/errors';
2
- import { FeathersKoaContext } from './declarations';
3
-
4
- export const errorHandler = () => async (ctx: FeathersKoaContext, next: () => Promise<any>) => {
5
- try {
6
- await next();
7
-
8
- if(ctx.body === undefined) {
9
- throw new NotFound('Not Found');
10
- }
11
-
12
- } catch (error) {
13
- ctx.response.status = error.code || 500;
14
- ctx.body = typeof error.toJSON === 'function' ? error.toJSON() : {
15
- message: error.message
16
- };
17
- }
18
- };
File without changes