@feathersjs/koa 5.0.0-pre.15 → 5.0.0-pre.16

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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [5.0.0-pre.16](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.15...v5.0.0-pre.16) (2022-01-12)
7
+
8
+
9
+ ### Features
10
+
11
+ * **express, koa:** make transports similar ([#2486](https://github.com/feathersjs/feathers/issues/2486)) ([26aa937](https://github.com/feathersjs/feathers/commit/26aa937c114fb8596dfefc599b1f53cead69c159))
12
+
13
+
14
+
15
+
16
+
6
17
  # [5.0.0-pre.15](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.14...v5.0.0-pre.15) (2021-11-27)
7
18
 
8
19
 
@@ -0,0 +1,7 @@
1
+ import { Middleware } from './declarations';
2
+ export declare type AuthenticationSettings = {
3
+ service?: string;
4
+ strategies?: string[];
5
+ };
6
+ export declare function parseAuthentication(settings?: AuthenticationSettings): Middleware;
7
+ export declare function authenticate(settings: string | AuthenticationSettings, ...strategies: string[]): Middleware;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.authenticate = exports.parseAuthentication = void 0;
4
+ const commons_1 = require("@feathersjs/commons");
5
+ const authentication_1 = require("@feathersjs/authentication");
6
+ const debug = (0, commons_1.createDebug)('@feathersjs/koa/authentication');
7
+ function parseAuthentication(settings = {}) {
8
+ return async (ctx, next) => {
9
+ var _a;
10
+ const app = ctx.app;
11
+ const service = (_a = app.defaultAuthentication) === null || _a === void 0 ? void 0 : _a.call(app, settings.service);
12
+ if (!service) {
13
+ return next();
14
+ }
15
+ const config = service.configuration;
16
+ const authStrategies = settings.strategies || config.parseStrategies || config.authStrategies || [];
17
+ if (authStrategies.length === 0) {
18
+ debug('No `authStrategies` or `parseStrategies` found in authentication configuration');
19
+ return next();
20
+ }
21
+ const authentication = await service.parse(ctx.req, ctx.res, ...authStrategies);
22
+ if (authentication) {
23
+ debug('Parsed authentication from HTTP header', authentication);
24
+ ctx.feathers = { ...ctx.feathers, authentication };
25
+ }
26
+ return next();
27
+ };
28
+ }
29
+ exports.parseAuthentication = parseAuthentication;
30
+ function authenticate(settings, ...strategies) {
31
+ const hook = (0, authentication_1.authenticate)(settings, ...strategies);
32
+ return async (ctx, next) => {
33
+ const app = ctx.app;
34
+ const params = ctx.feathers;
35
+ const context = { app, params };
36
+ await hook(context);
37
+ ctx.feathers = context.params;
38
+ return next();
39
+ };
40
+ }
41
+ exports.authenticate = authenticate;
42
+ //# sourceMappingURL=authentication.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authentication.js","sourceRoot":"","sources":["../src/authentication.ts"],"names":[],"mappings":";;;AACA,iDAAkD;AAClD,+DAA8E;AAI9E,MAAM,KAAK,GAAG,IAAA,qBAAW,EAAC,gCAAgC,CAAC,CAAC;AAO5D,SAAgB,mBAAmB,CAAE,WAAmC,EAAE;IACxE,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;;QACzB,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;QACpB,MAAM,OAAO,GAAG,MAAA,GAAG,CAAC,qBAAqB,+CAAzB,GAAG,EAAyB,QAAQ,CAAC,OAAO,CAAC,CAAC;QAE9D,IAAI,CAAC,OAAO,EAAE;YACZ,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,cAAc,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,CAAC;QAEhF,IAAI,cAAc,EAAE;YAClB,KAAK,CAAC,wCAAwC,EAAE,cAAc,CAAC,CAAC;YAChE,GAAG,CAAC,QAAQ,GAAG,EAAE,GAAG,GAAG,CAAC,QAAQ,EAAE,cAAc,EAAE,CAAC;SACpD;QAED,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AA1BD,kDA0BC;AAED,SAAgB,YAAY,CAAE,QAAyC,EAAE,GAAG,UAAoB;IAC9F,MAAM,IAAI,GAAG,IAAA,6BAAgB,EAAC,QAAQ,EAAE,GAAG,UAAU,CAAC,CAAC;IAEvD,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,MAAM,GAAG,GAAG,GAAG,CAAC,GAAkB,CAAC;QACnC,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC;QAC5B,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,MAAM,EAAiB,CAAC;QAE/C,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpB,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;QAE9B,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AAdD,oCAcC"}
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
- import Koa from 'koa';
2
+ import Koa, { Next } from 'koa';
3
3
  import { Server } from 'http';
4
- import { Application as FeathersApplication, HookContext, Params } from '@feathersjs/feathers';
4
+ import { Application as FeathersApplication, HookContext, Params, RouteLookup } from '@feathersjs/feathers';
5
5
  import '@feathersjs/authentication';
6
6
  export declare type ApplicationAddons = {
7
7
  listen(port?: number, ...args: any[]): Promise<Server>;
@@ -10,9 +10,20 @@ export declare type Application<T = any, C = any> = Omit<Koa, 'listen'> & Feathe
10
10
  export declare type FeathersKoaContext<A = Application> = Koa.Context & {
11
11
  app: A;
12
12
  };
13
+ export declare type Middleware<A = Application> = (context: FeathersKoaContext<A>, next: Next) => any;
14
+ declare module '@feathersjs/feathers/lib/declarations' {
15
+ interface ServiceOptions {
16
+ koa?: {
17
+ before?: Middleware[];
18
+ after?: Middleware[];
19
+ composed?: Middleware;
20
+ };
21
+ }
22
+ }
13
23
  declare module 'koa' {
14
24
  interface ExtendableContext {
15
25
  feathers?: Partial<Params>;
26
+ lookup?: RouteLookup;
16
27
  hook?: HookContext;
17
28
  }
18
29
  }
File without changes
@@ -17,4 +17,4 @@ const errorHandler = () => async (ctx, next) => {
17
17
  }
18
18
  };
19
19
  exports.errorHandler = errorHandler;
20
- //# sourceMappingURL=error-handler.js.map
20
+ //# sourceMappingURL=handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.js","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":";;;AAAA,+CAA8C;AAGvC,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,KAAK,EAAE,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,KAAU,EAAE;QACnB,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,CAAC;AAdW,QAAA,YAAY,gBAcvB"}
package/lib/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import Koa from 'koa';
2
- import bodyParser from 'koa-bodyparser';
3
2
  import { Application as FeathersApplication } from '@feathersjs/feathers';
4
3
  import { Application } from './declarations';
5
- import { errorHandler } from './error-handler';
4
+ export { default as Koa } from 'koa';
5
+ export { default as bodyParser } from 'koa-bodyparser';
6
+ export * from './authentication';
6
7
  export * from './declarations';
7
- export * from './authenticate';
8
- export { rest } from './rest';
9
- export { Koa, bodyParser, errorHandler };
10
- export declare function koa(_app?: FeathersApplication): Application;
8
+ export * from './handlers';
9
+ export * from './rest';
10
+ export declare function koa<S = any, C = any>(feathersApp?: FeathersApplication<S, C>, koaApp?: Koa): Application<S, C>;
package/lib/index.js CHANGED
@@ -13,36 +13,34 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  return (mod && mod.__esModule) ? mod : { "default": mod };
14
14
  };
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.koa = exports.errorHandler = exports.bodyParser = exports.Koa = exports.rest = void 0;
16
+ exports.koa = exports.bodyParser = exports.Koa = void 0;
17
17
  const koa_1 = __importDefault(require("koa"));
18
- exports.Koa = koa_1.default;
19
- const koa_bodyparser_1 = __importDefault(require("koa-bodyparser"));
20
- exports.bodyParser = koa_bodyparser_1.default;
21
18
  const koa_qs_1 = __importDefault(require("koa-qs"));
22
19
  const transport_commons_1 = require("@feathersjs/transport-commons");
23
20
  const commons_1 = require("@feathersjs/commons");
24
- const error_handler_1 = require("./error-handler");
25
- Object.defineProperty(exports, "errorHandler", { enumerable: true, get: function () { return error_handler_1.errorHandler; } });
26
- const debug = (0, commons_1.createDebug)('@feathersjs/koa');
21
+ var koa_2 = require("koa");
22
+ Object.defineProperty(exports, "Koa", { enumerable: true, get: function () { return __importDefault(koa_2).default; } });
23
+ var koa_bodyparser_1 = require("koa-bodyparser");
24
+ Object.defineProperty(exports, "bodyParser", { enumerable: true, get: function () { return __importDefault(koa_bodyparser_1).default; } });
25
+ __exportStar(require("./authentication"), exports);
27
26
  __exportStar(require("./declarations"), exports);
28
- __exportStar(require("./authenticate"), exports);
29
- var rest_1 = require("./rest");
30
- Object.defineProperty(exports, "rest", { enumerable: true, get: function () { return rest_1.rest; } });
31
- function koa(_app) {
32
- const koaApp = new koa_1.default();
33
- if (!_app) {
27
+ __exportStar(require("./handlers"), exports);
28
+ __exportStar(require("./rest"), exports);
29
+ const debug = (0, commons_1.createDebug)('@feathersjs/koa');
30
+ function koa(feathersApp, koaApp = new koa_1.default()) {
31
+ if (!feathersApp) {
34
32
  return koaApp;
35
33
  }
36
- if (typeof _app.setup !== 'function') {
34
+ if (typeof feathersApp.setup !== 'function') {
37
35
  throw new Error('@feathersjs/koa requires a valid Feathers application instance');
38
36
  }
39
- const app = _app;
37
+ const app = feathersApp;
40
38
  const { listen: koaListen, use: koaUse } = koaApp;
41
- const oldUse = app.use;
39
+ const feathersUse = feathersApp.use;
42
40
  Object.assign(app, {
43
41
  use(location, ...args) {
44
42
  if (typeof location === 'string') {
45
- return oldUse.call(this, location, ...args);
43
+ return feathersUse.call(this, location, ...args);
46
44
  }
47
45
  return koaUse.call(this, location);
48
46
  },
@@ -53,27 +51,27 @@ function koa(_app) {
53
51
  return server;
54
52
  }
55
53
  });
56
- const feathersDescriptors = {
54
+ const appDescriptors = {
57
55
  ...Object.getOwnPropertyDescriptors(Object.getPrototypeOf(app)),
58
56
  ...Object.getOwnPropertyDescriptors(app)
59
57
  };
60
- const koaDescriptors = {
58
+ const newDescriptors = {
61
59
  ...Object.getOwnPropertyDescriptors(Object.getPrototypeOf(koaApp)),
62
60
  ...Object.getOwnPropertyDescriptors(koaApp)
63
61
  };
64
62
  // Copy all non-existing properties (including non-enumerables)
65
63
  // that don't already exist on the Express app
66
- Object.keys(koaDescriptors).forEach(prop => {
67
- const feathersProp = feathersDescriptors[prop];
68
- const koaProp = koaDescriptors[prop];
69
- if (koaProp !== undefined && feathersProp === undefined) {
70
- Object.defineProperty(app, prop, koaProp);
64
+ Object.keys(newDescriptors).forEach(prop => {
65
+ const appProp = appDescriptors[prop];
66
+ const newProp = newDescriptors[prop];
67
+ if (appProp === undefined && newProp !== undefined) {
68
+ Object.defineProperty(app, prop, newProp);
71
69
  }
72
70
  });
73
71
  (0, koa_qs_1.default)(app);
74
72
  app.configure((0, transport_commons_1.routing)());
75
73
  app.use((ctx, next) => {
76
- ctx.feathers = { provider: 'rest' };
74
+ ctx.feathers = { ...ctx.feathers, provider: 'rest' };
77
75
  return next();
78
76
  });
79
77
  return app;
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAAsB;AAeb,cAfF,aAAG,CAeE;AAdZ,oEAAwC;AAc1B,qBAdP,wBAAU,CAcO;AAbxB,oDAA2B;AAE3B,qEAAwD;AACxD,iDAAkD;AAGlD,mDAA+C;AAOrB,6FAPjB,4BAAY,OAOiB;AALtC,MAAM,KAAK,GAAG,IAAA,qBAAW,EAAC,iBAAiB,CAAC,CAAC;AAE7C,iDAA+B;AAC/B,iDAA+B;AAC/B,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AAGb,SAAgB,GAAG,CAAE,IAA0B;IAC7C,MAAM,MAAM,GAAG,IAAI,aAAG,EAAE,CAAC;IAEzB,IAAI,CAAC,IAAI,EAAE;QACT,OAAO,MAAgC,CAAC;KACzC;IAED,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,UAAU,EAAE;QACpC,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;KACnF;IAED,MAAM,GAAG,GAAG,IAAmB,CAAC;IAChC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAClD,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC;IAEvB,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;QACjB,GAAG,CAAE,QAA+B,EAAE,GAAG,IAAW;YAClD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;gBAChC,OAAQ,MAAc,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAC;aACtD;YAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC;QAED,KAAK,CAAC,MAAM,CAAE,IAAa,EAAE,GAAG,IAAW;YACzC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;YAEnD,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACzB,KAAK,CAAC,gCAAgC,CAAC,CAAC;YAExC,OAAO,MAAM,CAAC;QAChB,CAAC;KACa,CAAC,CAAC;IAElB,MAAM,mBAAmB,GAAG;QAC1B,GAAG,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAC/D,GAAG,MAAM,CAAC,yBAAyB,CAAC,GAAG,CAAC;KACzC,CAAC;IACF,MAAM,cAAc,GAAG;QACrB,GAAG,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAClE,GAAG,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC;KAC5C,CAAC;IAEF,+DAA+D;IAC/D,8CAA8C;IAC9C,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACzC,MAAM,YAAY,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAErC,IAAI,OAAO,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,EAAE;YACvD,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;SAC3C;IACH,CAAC,CAAC,CAAC;IAEH,IAAA,gBAAK,EAAC,GAAU,CAAC,CAAC;IAClB,GAAG,CAAC,SAAS,CAAC,IAAA,2BAAO,GAAE,CAAC,CAAC;IACzB,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;QACpB,GAAG,CAAC,QAAQ,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAEpC,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC;AA/DD,kBA+DC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/lib/rest.d.ts CHANGED
@@ -1,3 +1,8 @@
1
- import { Next } from 'koa';
2
- import { FeathersKoaContext } from './declarations';
3
- export declare function rest(): (ctx: FeathersKoaContext, next: Next) => Promise<any>;
1
+ import { Application, Middleware } from './declarations';
2
+ import { AuthenticationSettings } from './authentication';
3
+ export declare const formatter: Middleware;
4
+ export declare type RestOptions = {
5
+ formatter?: Middleware;
6
+ authentication?: AuthenticationSettings;
7
+ };
8
+ export declare const rest: (options?: RestOptions | Middleware) => (app: Application) => void;
package/lib/rest.js CHANGED
@@ -1,44 +1,73 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rest = void 0;
6
+ exports.rest = exports.formatter = void 0;
7
+ const koa_compose_1 = __importDefault(require("koa-compose"));
4
8
  const transport_commons_1 = require("@feathersjs/transport-commons");
5
9
  const commons_1 = require("@feathersjs/commons");
6
10
  const feathers_1 = require("@feathersjs/feathers");
7
11
  const errors_1 = require("@feathersjs/errors");
8
- const debug = (0, commons_1.createDebug)('@feathersjs/koa:rest');
9
- function rest() {
12
+ const authentication_1 = require("./authentication");
13
+ const debug = (0, commons_1.createDebug)('@feathersjs/koa/rest');
14
+ const serviceMiddleware = () => {
10
15
  return async (ctx, next) => {
11
- const { app, request } = ctx;
12
- const { query: koaQuery, headers, path, body: data, method: httpMethod } = request;
13
- const query = { ...koaQuery };
14
- const methodOverride = request.headers[transport_commons_1.http.METHOD_HEADER] ?
15
- request.headers[transport_commons_1.http.METHOD_HEADER] : null;
16
- const lookup = app.lookup(path);
17
- if (lookup !== null) {
18
- const { service, params: { __id: id = null, ...route } = {} } = lookup;
19
- const method = transport_commons_1.http.getServiceMethod(httpMethod, id, methodOverride);
20
- const { methods } = (0, feathers_1.getServiceOptions)(service);
21
- debug(`Found service for path ${path}, attempting to run '${method}' service method`);
22
- if (!methods.includes(method) || feathers_1.defaultServiceMethods.includes(methodOverride)) {
23
- ctx.response.status = transport_commons_1.http.statusCodes.methodNotAllowed;
24
- throw new errors_1.MethodNotAllowed(`Method \`${method}\` is not supported by this endpoint.`);
25
- }
26
- const createArguments = transport_commons_1.http.argumentsFor[method] || transport_commons_1.http.argumentsFor.default;
27
- const params = {
28
- ...ctx.feathers,
29
- query,
30
- headers,
31
- route
32
- };
33
- const args = createArguments({ id, data, params });
34
- const hookContext = (0, feathers_1.createContext)(service, method, { http: {} });
35
- ctx.hook = hookContext;
36
- const result = await service[method](...args, hookContext);
37
- ctx.response.status = transport_commons_1.http.getStatusCode(result, {});
38
- ctx.body = transport_commons_1.http.getData(result);
16
+ const { query, headers, path, body: data, method: httpMethod } = ctx.request;
17
+ const methodOverride = ctx.request.headers[transport_commons_1.http.METHOD_HEADER];
18
+ const { service, params: { __id: id = null, ...route } = {} } = ctx.lookup;
19
+ const method = transport_commons_1.http.getServiceMethod(httpMethod, id, methodOverride);
20
+ const { methods } = (0, feathers_1.getServiceOptions)(service);
21
+ debug(`Found service for path ${path}, attempting to run '${method}' service method`);
22
+ if (!methods.includes(method) || feathers_1.defaultServiceMethods.includes(methodOverride)) {
23
+ const error = new errors_1.MethodNotAllowed(`Method \`${method}\` is not supported by this endpoint.`);
24
+ ctx.response.status = error.code;
25
+ throw error;
39
26
  }
27
+ const createArguments = transport_commons_1.http.argumentsFor[method] || transport_commons_1.http.argumentsFor.default;
28
+ const params = { query, headers, route, ...ctx.feathers };
29
+ const args = createArguments({ id, data, params });
30
+ const contextBase = (0, feathers_1.createContext)(service, method, { http: {} });
31
+ ctx.hook = contextBase;
32
+ const context = await service[method](...args, contextBase);
33
+ ctx.hook = context;
34
+ const result = transport_commons_1.http.getData(context);
35
+ const statusCode = transport_commons_1.http.getStatusCode(context, result);
36
+ ctx.body = result;
37
+ ctx.status = statusCode;
40
38
  return next();
41
39
  };
42
- }
40
+ };
41
+ const servicesMiddleware = () => {
42
+ return async (ctx, next) => {
43
+ const app = ctx.app;
44
+ const lookup = app.lookup(ctx.request.path);
45
+ if (!lookup) {
46
+ return next();
47
+ }
48
+ ctx.lookup = lookup;
49
+ const options = (0, feathers_1.getServiceOptions)(lookup.service);
50
+ const middleware = options.koa.composed;
51
+ return middleware(ctx, next);
52
+ };
53
+ };
54
+ const formatter = (_ctx, _next) => { };
55
+ exports.formatter = formatter;
56
+ const rest = (options) => {
57
+ options = typeof options === 'function' ? { formatter: options } : options || {};
58
+ const formatterMiddleware = options.formatter || exports.formatter;
59
+ const authenticationOptions = options.authentication;
60
+ return (app) => {
61
+ app.use((0, authentication_1.parseAuthentication)(authenticationOptions));
62
+ app.use(servicesMiddleware());
63
+ app.mixins.push((_service, _path, options) => {
64
+ const { koa: { before = [], after = [] } = {} } = options;
65
+ const middlewares = [].concat(before, serviceMiddleware(), after, formatterMiddleware);
66
+ const middleware = (0, koa_compose_1.default)(middlewares);
67
+ options.koa || (options.koa = {});
68
+ options.koa.composed = middleware;
69
+ });
70
+ };
71
+ };
43
72
  exports.rest = rest;
44
73
  //# sourceMappingURL=rest.js.map
package/lib/rest.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rest.js","sourceRoot":"","sources":["../src/rest.ts"],"names":[],"mappings":";;;AACA,qEAAqD;AACrD,iDAAkD;AAClD,mDAA+F;AAC/F,+CAAsD;AAGtD,MAAM,KAAK,GAAG,IAAA,qBAAW,EAAC,sBAAsB,CAAC,CAAC;AAElD,SAAgB,IAAI;IAClB,OAAO,KAAK,EAAE,GAAuB,EAAE,IAAU,EAAE,EAAE;QACnD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC;QAC7B,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QACnF,MAAM,KAAK,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC9B,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,wBAAI,CAAC,aAAa,CAAC,CAAC,CAAC;YAC1D,OAAO,CAAC,OAAO,CAAC,wBAAI,CAAC,aAAa,CAAW,CAAC,CAAC,CAAC,IAAI,CAAC;QACvD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEhC,IAAI,MAAM,KAAK,IAAI,EAAE;YACnB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC;YACvE,MAAM,MAAM,GAAG,wBAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,EAAE,EAAE,cAAc,CAAC,CAAC;YACrE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,4BAAiB,EAAC,OAAO,CAAC,CAAC;YAE/C,KAAK,CAAC,0BAA0B,IAAI,wBAAwB,MAAM,kBAAkB,CAAC,CAAC;YAEtF,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,gCAAqB,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE;gBAC/E,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,wBAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC;gBAExD,MAAM,IAAI,yBAAgB,CAAC,YAAY,MAAM,uCAAuC,CAAC,CAAC;aACvF;YAED,MAAM,eAAe,GAAI,wBAAI,CAAC,YAAoB,CAAC,MAAM,CAAC,IAAI,wBAAI,CAAC,YAAY,CAAC,OAAO,CAAC;YACxF,MAAM,MAAM,GAAG;gBACb,GAAG,GAAG,CAAC,QAAQ;gBACf,KAAK;gBACL,OAAO;gBACP,KAAK;aACN,CAAC;YACF,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACnD,MAAM,WAAW,GAAG,IAAA,wBAAa,EAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAEjE,GAAG,CAAC,IAAI,GAAG,WAAkB,CAAC;YAE9B,MAAM,MAAM,GAAG,MAAO,OAAe,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAC;YAEpE,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,wBAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,IAAI,GAAG,wBAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SACjC;QAED,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AA1CD,oBA0CC"}
1
+ {"version":3,"file":"rest.js","sourceRoot":"","sources":["../src/rest.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@feathersjs/koa",
3
3
  "description": "Feathers KoaJS framework bindings and REST provider",
4
- "version": "5.0.0-pre.15",
4
+ "version": "5.0.0-pre.16",
5
5
  "homepage": "https://feathersjs.com",
6
6
  "main": "lib/",
7
7
  "keywords": [
@@ -47,28 +47,31 @@
47
47
  "access": "public"
48
48
  },
49
49
  "dependencies": {
50
- "@feathersjs/authentication": "^5.0.0-pre.15",
51
- "@feathersjs/commons": "^5.0.0-pre.15",
52
- "@feathersjs/errors": "^5.0.0-pre.15",
53
- "@feathersjs/transport-commons": "^5.0.0-pre.15",
50
+ "@feathersjs/authentication": "^5.0.0-pre.16",
51
+ "@feathersjs/commons": "^5.0.0-pre.16",
52
+ "@feathersjs/errors": "^5.0.0-pre.16",
53
+ "@feathersjs/transport-commons": "^5.0.0-pre.16",
54
54
  "@types/koa": "^2.13.4",
55
- "@types/koa-bodyparser": "^4.3.4",
55
+ "@types/koa-bodyparser": "^4.3.5",
56
56
  "@types/koa-qs": "^2.0.0",
57
57
  "koa": "^2.13.4",
58
58
  "koa-bodyparser": "^4.3.0",
59
+ "koa-compose": "^4.1.0",
59
60
  "koa-qs": "^3.0.0"
60
61
  },
61
62
  "devDependencies": {
62
- "@feathersjs/authentication-local": "^5.0.0-pre.15",
63
- "@feathersjs/feathers": "^5.0.0-pre.15",
64
- "@feathersjs/memory": "^5.0.0-pre.15",
65
- "@feathersjs/tests": "^5.0.0-pre.15",
63
+ "@feathersjs/authentication-local": "^5.0.0-pre.16",
64
+ "@feathersjs/feathers": "^5.0.0-pre.16",
65
+ "@feathersjs/memory": "^5.0.0-pre.16",
66
+ "@feathersjs/tests": "^5.0.0-pre.16",
67
+ "@types/koa-compose": "^3.2.5",
66
68
  "@types/mocha": "^9.0.0",
67
- "@types/node": "^16.11.6",
69
+ "@types/node": "^17.0.5",
70
+ "axios": "^0.24.0",
68
71
  "mocha": "^9.1.3",
69
72
  "shx": "^0.3.3",
70
73
  "ts-node": "^10.4.0",
71
- "typescript": "^4.4.4"
74
+ "typescript": "^4.5.4"
72
75
  },
73
- "gitHead": "8008bf4f8529a2a40b6a2f976c1f43ae13675693"
76
+ "gitHead": "f0cd227a82d159b528193bd33747c97684a48773"
74
77
  }
@@ -0,0 +1,56 @@
1
+ import { Application, HookContext } from '@feathersjs/feathers';
2
+ import { createDebug } from '@feathersjs/commons';
3
+ import { authenticate as AuthenticateHook } from '@feathersjs/authentication';
4
+
5
+ import { Middleware } from './declarations';
6
+
7
+ const debug = createDebug('@feathersjs/koa/authentication');
8
+
9
+ export type AuthenticationSettings = {
10
+ service?: string;
11
+ strategies?: string[];
12
+ };
13
+
14
+ export function parseAuthentication (settings: AuthenticationSettings = {}): Middleware {
15
+ return async (ctx, next) => {
16
+ const app = ctx.app;
17
+ const service = app.defaultAuthentication?.(settings.service);
18
+
19
+ if (!service) {
20
+ return next();
21
+ }
22
+
23
+ const config = service.configuration;
24
+ const authStrategies = settings.strategies || config.parseStrategies || config.authStrategies || [];
25
+
26
+ if (authStrategies.length === 0) {
27
+ debug('No `authStrategies` or `parseStrategies` found in authentication configuration');
28
+ return next();
29
+ }
30
+
31
+ const authentication = await service.parse(ctx.req, ctx.res, ...authStrategies);
32
+
33
+ if (authentication) {
34
+ debug('Parsed authentication from HTTP header', authentication);
35
+ ctx.feathers = { ...ctx.feathers, authentication };
36
+ }
37
+
38
+ return next();
39
+ };
40
+ }
41
+
42
+ export function authenticate (settings: string | AuthenticationSettings, ...strategies: string[]): Middleware {
43
+ const hook = AuthenticateHook(settings, ...strategies);
44
+
45
+ return async (ctx, next) => {
46
+ const app = ctx.app as Application;
47
+ const params = ctx.feathers;
48
+ const context = { app, params } as HookContext;
49
+
50
+ await hook(context);
51
+
52
+ ctx.feathers = context.params;
53
+
54
+ return next();
55
+ };
56
+ }
@@ -1,6 +1,6 @@
1
- import Koa from 'koa';
1
+ import Koa, { Next } from 'koa';
2
2
  import { Server } from 'http';
3
- import { Application as FeathersApplication, HookContext, Params } from '@feathersjs/feathers';
3
+ import { Application as FeathersApplication, HookContext, Params, RouteLookup } from '@feathersjs/feathers';
4
4
  import '@feathersjs/authentication';
5
5
 
6
6
  export type ApplicationAddons = {
@@ -14,9 +14,22 @@ export type FeathersKoaContext<A = Application> = Koa.Context & {
14
14
  app: A;
15
15
  };
16
16
 
17
+ export type Middleware<A = Application> = (context: FeathersKoaContext<A>, next: Next) => any;
18
+
19
+ declare module '@feathersjs/feathers/lib/declarations' {
20
+ interface ServiceOptions {
21
+ koa?: {
22
+ before?: Middleware[];
23
+ after?: Middleware[];
24
+ composed?: Middleware;
25
+ };
26
+ }
27
+ }
28
+
17
29
  declare module 'koa' {
18
30
  interface ExtendableContext {
19
31
  feathers?: Partial<Params>;
32
+ lookup?: RouteLookup;
20
33
  hook?: HookContext;
21
34
  }
22
35
  }
@@ -8,7 +8,7 @@ export const errorHandler = () => async (ctx: FeathersKoaContext, next: () => Pr
8
8
  if(ctx.body === undefined) {
9
9
  throw new NotFound('Not Found');
10
10
  }
11
-
11
+
12
12
  } catch (error: any) {
13
13
  ctx.response.status = error.code || 500;
14
14
  ctx.body = typeof error.toJSON === 'function' ? error.toJSON() : {
package/src/index.ts CHANGED
@@ -1,39 +1,38 @@
1
1
  import Koa from 'koa';
2
- import bodyParser from 'koa-bodyparser';
3
2
  import koaQs from 'koa-qs';
4
3
  import { Application as FeathersApplication } from '@feathersjs/feathers';
5
4
  import { routing } from '@feathersjs/transport-commons';
6
5
  import { createDebug } from '@feathersjs/commons';
7
6
 
8
7
  import { Application } from './declarations';
9
- import { errorHandler } from './error-handler';
10
8
 
11
- const debug = createDebug('@feathersjs/koa');
9
+ export { default as Koa } from 'koa';
10
+ export { default as bodyParser } from 'koa-bodyparser';
12
11
 
12
+ export * from './authentication';
13
13
  export * from './declarations';
14
- export * from './authenticate';
15
- export { rest } from './rest';
16
- export { Koa, bodyParser, errorHandler };
14
+ export * from './handlers';
15
+ export * from './rest';
17
16
 
18
- export function koa (_app?: FeathersApplication): Application {
19
- const koaApp = new Koa();
17
+ const debug = createDebug('@feathersjs/koa');
20
18
 
21
- if (!_app) {
22
- return koaApp as unknown as Application;
19
+ export function koa<S = any, C = any> (feathersApp?: FeathersApplication<S, C>, koaApp: Koa = new Koa()): Application<S, C> {
20
+ if (!feathersApp) {
21
+ return koaApp as any;
23
22
  }
24
23
 
25
- if (typeof _app.setup !== 'function') {
24
+ if (typeof feathersApp.setup !== 'function') {
26
25
  throw new Error('@feathersjs/koa requires a valid Feathers application instance');
27
26
  }
28
27
 
29
- const app = _app as Application;
28
+ const app = feathersApp as any as Application<S, C>;
30
29
  const { listen: koaListen, use: koaUse } = koaApp;
31
- const oldUse = app.use;
30
+ const feathersUse = feathersApp.use as any;
32
31
 
33
32
  Object.assign(app, {
34
33
  use (location: string|Koa.Middleware, ...args: any[]) {
35
34
  if (typeof location === 'string') {
36
- return (oldUse as any).call(this, location, ...args);
35
+ return feathersUse.call(this, location, ...args);
37
36
  }
38
37
 
39
38
  return koaUse.call(this, location);
@@ -49,31 +48,31 @@ export function koa (_app?: FeathersApplication): Application {
49
48
  }
50
49
  } as Application);
51
50
 
52
- const feathersDescriptors = {
51
+ const appDescriptors = {
53
52
  ...Object.getOwnPropertyDescriptors(Object.getPrototypeOf(app)),
54
53
  ...Object.getOwnPropertyDescriptors(app)
55
54
  };
56
- const koaDescriptors = {
55
+ const newDescriptors = {
57
56
  ...Object.getOwnPropertyDescriptors(Object.getPrototypeOf(koaApp)),
58
57
  ...Object.getOwnPropertyDescriptors(koaApp)
59
58
  };
60
59
 
61
60
  // Copy all non-existing properties (including non-enumerables)
62
61
  // that don't already exist on the Express app
63
- Object.keys(koaDescriptors).forEach(prop => {
64
- const feathersProp = feathersDescriptors[prop];
65
- const koaProp = koaDescriptors[prop];
62
+ Object.keys(newDescriptors).forEach(prop => {
63
+ const appProp = appDescriptors[prop];
64
+ const newProp = newDescriptors[prop];
66
65
 
67
- if (koaProp !== undefined && feathersProp === undefined) {
68
- Object.defineProperty(app, prop, koaProp);
66
+ if (appProp === undefined && newProp !== undefined) {
67
+ Object.defineProperty(app, prop, newProp);
69
68
  }
70
69
  });
71
70
 
72
71
  koaQs(app as any);
73
- app.configure(routing());
74
- app.use((ctx, next) => {
75
- ctx.feathers = { provider: 'rest' };
76
72
 
73
+ app.configure(routing() as any);
74
+ app.use((ctx, next) => {
75
+ ctx.feathers = { ...ctx.feathers, provider: 'rest' };
77
76
  return next();
78
77
  });
79
78
 
package/src/rest.ts CHANGED
@@ -1,52 +1,93 @@
1
- import { Next } from 'koa';
1
+ import compose from 'koa-compose';
2
2
  import { http } from '@feathersjs/transport-commons';
3
3
  import { createDebug } from '@feathersjs/commons';
4
4
  import { getServiceOptions, defaultServiceMethods, createContext } from '@feathersjs/feathers';
5
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, headers, 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
- headers,
37
- route
38
- };
39
- const args = createArguments({ id, data, params });
40
- const hookContext = createContext(service, method, { http: {} });
41
-
42
- ctx.hook = hookContext as any;
43
-
44
- const result = await (service as any)[method](...args, hookContext);
45
-
46
- ctx.response.status = http.getStatusCode(result, {});
47
- ctx.body = http.getData(result);
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
+ const { service, params: { __id: id = null, ...route } = {} } = ctx.lookup!;
18
+ const method = http.getServiceMethod(httpMethod, id, methodOverride);
19
+ const { methods } = getServiceOptions(service);
20
+
21
+ debug(`Found service for path ${path}, attempting to run '${method}' service method`);
22
+
23
+ if (!methods.includes(method) || defaultServiceMethods.includes(methodOverride)) {
24
+ const error = new MethodNotAllowed(`Method \`${method}\` is not supported by this endpoint.`);
25
+ ctx.response.status = error.code;
26
+ throw error;
48
27
  }
49
28
 
29
+ const createArguments = http.argumentsFor[method as 'get'] || http.argumentsFor.default;
30
+ const params = { query, headers, route, ...ctx.feathers };
31
+ const args = createArguments({ id, data, params });
32
+ const contextBase = createContext(service, method, { http: {} });
33
+ ctx.hook = contextBase;
34
+
35
+ const context = await (service as any)[method](...args, contextBase);
36
+ ctx.hook = context;
37
+
38
+ const result = http.getData(context);
39
+ const statusCode = http.getStatusCode(context, result);
40
+
41
+ ctx.body = result;
42
+ ctx.status = statusCode;
43
+
50
44
  return next();
51
45
  };
52
- }
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();
55
+ }
56
+
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
+ export const formatter: Middleware = (_ctx, _next) => {};
67
+
68
+ export type RestOptions = {
69
+ formatter?: Middleware;
70
+ authentication?: AuthenticationSettings;
71
+ };
72
+
73
+ export const rest = (options?: RestOptions | Middleware) => {
74
+ options = typeof options === 'function' ? { formatter: options } : options || {};
75
+
76
+ const formatterMiddleware = options.formatter || formatter;
77
+ const authenticationOptions = options.authentication;
78
+
79
+ return (app: Application) => {
80
+ app.use(parseAuthentication(authenticationOptions));
81
+ app.use(servicesMiddleware());
82
+
83
+ app.mixins.push((_service, _path, options) => {
84
+ const { koa: { before = [], after = [] } = {} } = options;
85
+
86
+ const middlewares = [].concat(before, serviceMiddleware(), after, formatterMiddleware);
87
+ const middleware = compose(middlewares);
88
+
89
+ options.koa ||= {};
90
+ options.koa.composed = middleware;
91
+ });
92
+ };
93
+ };
@@ -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,29 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.authentication = void 0;
4
- const commons_1 = require("@feathersjs/commons");
5
- const debug = (0, commons_1.createDebug)('@feathersjs/koa:authentication');
6
- function authentication(settings = {}) {
7
- return async (ctx, next) => {
8
- const { app } = ctx;
9
- const service = app.defaultAuthentication ? app.defaultAuthentication(settings.service) : null;
10
- if (service === null) {
11
- return next();
12
- }
13
- const config = service.configuration;
14
- const authStrategies = settings.strategies || config.parseStrategies || config.authStrategies || [];
15
- if (authStrategies.length === 0) {
16
- debug('No `authStrategies` or `parseStrategies` found in authentication configuration');
17
- return next();
18
- }
19
- const { req, res } = ctx;
20
- const authentication = await service.parse(req, res, ...authStrategies);
21
- if (authentication) {
22
- debug('Parsed authentication from HTTP header', authentication);
23
- ctx.feathers.authentication = authentication;
24
- }
25
- return next();
26
- };
27
- }
28
- exports.authentication = authentication;
29
- //# 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,IAAA,qBAAW,EAAC,gCAAgC,CAAC,CAAC;AAO5D,SAAgB,cAAc,CAAE,WAA+B,EAAE;IAC/D,OAAO,KAAK,EAAE,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,CAAC;AACJ,CAAC;AA3BD,wCA2BC"}
@@ -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,KAAK,EAAE,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,KAAU,EAAE;QACnB,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,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
- }