@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/lib/rest.js CHANGED
@@ -1,60 +1,75 @@
1
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
- var __rest = (this && this.__rest) || function (s, e) {
12
- var t = {};
13
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
- t[p] = s[p];
15
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
- t[p[i]] = s[p[i]];
19
- }
20
- return t;
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
21
4
  };
22
5
  Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.rest = void 0;
6
+ exports.rest = exports.formatter = void 0;
7
+ const koa_compose_1 = __importDefault(require("koa-compose"));
24
8
  const transport_commons_1 = require("@feathersjs/transport-commons");
25
9
  const commons_1 = require("@feathersjs/commons");
26
10
  const feathers_1 = require("@feathersjs/feathers");
27
11
  const errors_1 = require("@feathersjs/errors");
28
- const debug = commons_1.createDebug('@feathersjs/koa:rest');
29
- function rest() {
30
- return (ctx, next) => __awaiter(this, void 0, void 0, function* () {
31
- const { app, request } = ctx;
32
- const { query: koaQuery, path, body: data, method: httpMethod } = request;
33
- const query = Object.assign({}, koaQuery);
34
- const methodOverride = request.headers[transport_commons_1.http.METHOD_HEADER] ?
35
- request.headers[transport_commons_1.http.METHOD_HEADER] : null;
36
- const lookup = app.lookup(path);
37
- if (lookup !== null) {
38
- const { service } = lookup, _a = lookup.params, _b = _a === void 0 ? {} : _a, { __id: id = null } = _b, route = __rest(_b, ["__id"]);
39
- const method = transport_commons_1.http.getServiceMethod(httpMethod, id, methodOverride);
40
- const { methods } = feathers_1.getServiceOptions(service);
41
- debug(`Found service for path ${path}, attempting to run '${method}' service method`);
42
- if (!methods.includes(method) || feathers_1.defaultServiceMethods.includes(methodOverride)) {
43
- ctx.response.status = transport_commons_1.http.statusCodes.methodNotAllowed;
44
- throw new errors_1.MethodNotAllowed(`Method \`${method}\` is not supported by this endpoint.`);
45
- }
46
- const createArguments = transport_commons_1.http.argumentsFor[method] || transport_commons_1.http.argumentsFor.default;
47
- const params = Object.assign(Object.assign({}, ctx.feathers), { query,
48
- route });
49
- const args = createArguments({ id, data, params });
50
- const hookContext = feathers_1.createContext(service, method);
51
- ctx.hook = hookContext;
52
- const result = yield service[method](...args, hookContext);
53
- ctx.response.status = transport_commons_1.http.getStatusCode(result, {});
54
- ctx.body = transport_commons_1.http.getData(result);
12
+ const authentication_1 = require("./authentication");
13
+ const debug = (0, commons_1.createDebug)('@feathersjs/koa/rest');
14
+ const serviceMiddleware = () => {
15
+ return async (ctx, next) => {
16
+ const { query, headers, path, body: data, method: httpMethod } = ctx.request;
17
+ const methodOverride = ctx.request.headers[transport_commons_1.http.METHOD_HEADER];
18
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
19
+ const { service, params: { __id: id = null, ...route } = {} } = ctx.lookup;
20
+ const method = transport_commons_1.http.getServiceMethod(httpMethod, id, methodOverride);
21
+ const { methods } = (0, feathers_1.getServiceOptions)(service);
22
+ debug(`Found service for path ${path}, attempting to run '${method}' service method`);
23
+ if (!methods.includes(method) || feathers_1.defaultServiceMethods.includes(methodOverride)) {
24
+ const error = new errors_1.MethodNotAllowed(`Method \`${method}\` is not supported by this endpoint.`);
25
+ ctx.response.status = error.code;
26
+ throw error;
55
27
  }
28
+ const createArguments = transport_commons_1.http.argumentsFor[method] || transport_commons_1.http.argumentsFor.default;
29
+ const params = { query, headers, route, ...ctx.feathers };
30
+ const args = createArguments({ id, data, params });
31
+ const contextBase = (0, feathers_1.createContext)(service, method, { http: {} });
32
+ ctx.hook = contextBase;
33
+ const context = await service[method](...args, contextBase);
34
+ ctx.hook = context;
35
+ const response = transport_commons_1.http.getResponse(context);
36
+ ctx.status = response.status;
37
+ ctx.set(response.headers);
38
+ ctx.body = response.body;
56
39
  return next();
57
- });
58
- }
40
+ };
41
+ };
42
+ const servicesMiddleware = () => {
43
+ return async (ctx, next) => {
44
+ const app = ctx.app;
45
+ const lookup = app.lookup(ctx.request.path);
46
+ if (!lookup) {
47
+ return next();
48
+ }
49
+ ctx.lookup = lookup;
50
+ const options = (0, feathers_1.getServiceOptions)(lookup.service);
51
+ const middleware = options.koa.composed;
52
+ return middleware(ctx, next);
53
+ };
54
+ };
55
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
56
+ const formatter = (_ctx, _next) => { };
57
+ exports.formatter = formatter;
58
+ const rest = (options) => {
59
+ options = typeof options === 'function' ? { formatter: options } : options || {};
60
+ const formatterMiddleware = options.formatter || exports.formatter;
61
+ const authenticationOptions = options.authentication;
62
+ return (app) => {
63
+ app.use((0, authentication_1.parseAuthentication)(authenticationOptions));
64
+ app.use(servicesMiddleware());
65
+ app.mixins.push((_service, _path, options) => {
66
+ const { koa: { before = [], after = [] } = {} } = options;
67
+ const middlewares = [].concat(before, serviceMiddleware(), after, formatterMiddleware);
68
+ const middleware = (0, koa_compose_1.default)(middlewares);
69
+ options.koa || (options.koa = {});
70
+ options.koa.composed = middleware;
71
+ });
72
+ };
73
+ };
59
74
  exports.rest = rest;
60
75
  //# 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,qBAAW,CAAC,sBAAsB,CAAC,CAAC;AAElD,SAAgB,IAAI;IAClB,OAAO,CAAO,GAAuB,EAAE,IAAU,EAAE,EAAE;QACnD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC;QAC7B,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QAC1E,MAAM,KAAK,qBAAQ,QAAQ,CAAE,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,KAAiD,MAAM,EAArD,KAA+C,MAAM,OAAX,EAA1C,qBAAwC,EAAE,KAAA,EAA1C,EAAU,IAAI,EAAE,EAAE,GAAG,IAAI,OAAiB,EAAZ,KAAK,cAA3B,QAA6B,CAAgB,CAAC;YACvE,MAAM,MAAM,GAAG,wBAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,EAAE,EAAE,cAAc,CAAC,CAAC;YACrE,MAAM,EAAE,OAAO,EAAE,GAAG,4BAAiB,CAAC,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,mCACP,GAAG,CAAC,QAAQ,KACf,KAAK;gBACL,KAAK,GACN,CAAC;YACF,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACnD,MAAM,WAAW,GAAG,wBAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAEnD,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,CAAA,CAAC;AACJ,CAAC;AAzCD,oBAyCC"}
1
+ {"version":3,"file":"rest.js","sourceRoot":"","sources":["../src/rest.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@feathersjs/koa",
3
3
  "description": "Feathers KoaJS framework bindings and REST provider",
4
- "version": "5.0.0-pre.9",
4
+ "version": "5.0.1",
5
5
  "homepage": "https://feathersjs.com",
6
6
  "main": "lib/",
7
+ "types": "lib/",
7
8
  "keywords": [
8
9
  "feathers",
9
10
  "koajs"
@@ -11,7 +12,8 @@
11
12
  "license": "MIT",
12
13
  "repository": {
13
14
  "type": "git",
14
- "url": "git://github.com/feathersjs/feathers.git"
15
+ "url": "git://github.com/feathersjs/feathers.git",
16
+ "directory": "packages/koa"
15
17
  },
16
18
  "author": {
17
19
  "name": "Feathers contributors",
@@ -23,7 +25,7 @@
23
25
  "url": "https://github.com/feathersjs/feathers/issues"
24
26
  },
25
27
  "engines": {
26
- "node": ">= 6"
28
+ "node": ">= 14"
27
29
  },
28
30
  "files": [
29
31
  "CHANGELOG.md",
@@ -36,9 +38,9 @@
36
38
  ],
37
39
  "scripts": {
38
40
  "prepublish": "npm run compile",
39
- "compile": "shx rm -rf lib/ && tsc",
40
- "test": "npm run compile && npm run mocha",
41
- "mocha": "mocha --config ../../.mocharc.json --recursive test/**.test.ts test/**/*.test.ts"
41
+ "pack": "npm pack --pack-destination ../generators/test/build",
42
+ "compile": "shx rm -rf lib/ && tsc && npm run pack",
43
+ "test": "mocha --config ../../.mocharc.json --recursive test/**.test.ts test/**/*.test.ts"
42
44
  },
43
45
  "directories": {
44
46
  "lib": "lib"
@@ -47,28 +49,34 @@
47
49
  "access": "public"
48
50
  },
49
51
  "dependencies": {
50
- "@feathersjs/authentication": "^5.0.0-pre.9",
51
- "@feathersjs/commons": "^5.0.0-pre.9",
52
- "@feathersjs/errors": "^5.0.0-pre.9",
53
- "@feathersjs/transport-commons": "^5.0.0-pre.9",
54
- "@types/koa": "^2.13.4",
55
- "@types/koa-bodyparser": "^4.3.3",
52
+ "@feathersjs/authentication": "^5.0.1",
53
+ "@feathersjs/commons": "^5.0.1",
54
+ "@feathersjs/errors": "^5.0.1",
55
+ "@feathersjs/feathers": "^5.0.1",
56
+ "@feathersjs/transport-commons": "^5.0.1",
57
+ "@koa/cors": "^4.0.0",
58
+ "@types/koa": "^2.13.5",
56
59
  "@types/koa-qs": "^2.0.0",
57
- "koa": "^2.13.1",
58
- "koa-bodyparser": "^4.3.0",
59
- "koa-qs": "^3.0.0"
60
+ "@types/koa-static": "^4.0.2",
61
+ "@types/koa__cors": "^3.3.1",
62
+ "koa": "^2.14.1",
63
+ "koa-body": "^6.0.1",
64
+ "koa-compose": "^4.1.0",
65
+ "koa-qs": "^3.0.0",
66
+ "koa-static": "^5.0.0"
60
67
  },
61
68
  "devDependencies": {
62
- "@feathersjs/authentication-local": "^5.0.0-pre.9",
63
- "@feathersjs/feathers": "^5.0.0-pre.9",
64
- "@feathersjs/memory": "^5.0.0-pre.9",
65
- "@feathersjs/tests": "^5.0.0-pre.9",
66
- "@types/mocha": "^9.0.0",
67
- "@types/node": "^16.4.13",
68
- "mocha": "^9.0.3",
69
- "shx": "^0.3.3",
70
- "ts-node": "^10.1.0",
71
- "typescript": "^4.3.5"
69
+ "@feathersjs/authentication-local": "^5.0.1",
70
+ "@feathersjs/memory": "^5.0.1",
71
+ "@feathersjs/tests": "^5.0.1",
72
+ "@types/koa-compose": "^3.2.5",
73
+ "@types/mocha": "^10.0.1",
74
+ "@types/node": "^18.14.6",
75
+ "axios": "^1.3.4",
76
+ "mocha": "^10.2.0",
77
+ "shx": "^0.3.4",
78
+ "ts-node": "^10.9.1",
79
+ "typescript": "^4.9.5"
72
80
  },
73
- "gitHead": "3d1721a7286e6a7f37bbc38695fe45084023f13b"
81
+ "gitHead": "18b7f4ab0a8075572a81d78956ba1205a9795c91"
74
82
  }
@@ -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,15 +1,37 @@
1
- import Koa from 'koa';
2
- import { Server } from 'http';
3
- import { Application as FeathersApplication } from '@feathersjs/feathers';
4
- import '@feathersjs/authentication';
1
+ import Koa, { Next } from 'koa'
2
+ import { Server } from 'http'
3
+ import { Application as FeathersApplication, HookContext, Params, RouteLookup } from '@feathersjs/feathers'
4
+ import '@feathersjs/authentication'
5
5
 
6
6
  export type ApplicationAddons = {
7
- listen (port?: number, ...args: any[]): Promise<Server>;
7
+ server: Server
8
+ listen(port?: number, ...args: any[]): Promise<Server>
8
9
  }
9
10
 
10
- export type Application<T = any, C = any> =
11
- Omit<Koa, 'listen'> & FeathersApplication<T, C> & ApplicationAddons;
11
+ export type Application<T = any, C = any> = Omit<Koa, 'listen'> &
12
+ FeathersApplication<T, C> &
13
+ ApplicationAddons
12
14
 
13
15
  export type FeathersKoaContext<A = Application> = Koa.Context & {
14
- app: A;
15
- };
16
+ app: A
17
+ }
18
+
19
+ export type Middleware<A = Application> = (context: FeathersKoaContext<A>, next: Next) => any
20
+
21
+ declare module '@feathersjs/feathers/lib/declarations' {
22
+ interface ServiceOptions {
23
+ koa?: {
24
+ before?: Middleware[]
25
+ after?: Middleware[]
26
+ composed?: Middleware
27
+ }
28
+ }
29
+ }
30
+
31
+ declare module 'koa' {
32
+ interface ExtendableContext {
33
+ feathers?: Partial<Params>
34
+ lookup?: RouteLookup
35
+ hook?: HookContext
36
+ }
37
+ }
@@ -0,0 +1,20 @@
1
+ import { FeathersError, 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(`Path ${ctx.path} not found`)
10
+ }
11
+ } catch (error: any) {
12
+ ctx.response.status = error instanceof FeathersError ? error.code : 500
13
+ ctx.body =
14
+ typeof error.toJSON === 'function'
15
+ ? error.toJSON()
16
+ : {
17
+ message: error.message
18
+ }
19
+ }
20
+ }
package/src/index.ts CHANGED
@@ -1,81 +1,104 @@
1
- import Koa from 'koa';
2
- import bodyParser from 'koa-bodyparser';
3
- import koaQs from 'koa-qs';
4
- import { Application as FeathersApplication } from '@feathersjs/feathers';
5
- import { routing } from '@feathersjs/transport-commons';
6
- import { createDebug } from '@feathersjs/commons';
7
-
8
- import { Application } from './declarations';
9
- import { errorHandler } from './error-handler';
10
-
11
- const debug = createDebug('@feathersjs/koa');
12
-
13
- export * from './declarations';
14
- export * from './authenticate';
15
- export { rest } from './rest';
16
- export { Koa, bodyParser, errorHandler };
17
-
18
- export function koa (_app?: FeathersApplication): Application<any> {
19
- const koaApp = new Koa();
20
-
21
- if (!_app) {
22
- return koaApp as unknown as Application<any>;
1
+ import Koa from 'koa'
2
+ import koaQs from 'koa-qs'
3
+ import { Application as FeathersApplication } from '@feathersjs/feathers'
4
+ import { routing } from '@feathersjs/transport-commons'
5
+ import { createDebug } from '@feathersjs/commons'
6
+ import { koaBody as bodyParser } from 'koa-body'
7
+ import cors from '@koa/cors'
8
+ import serveStatic from 'koa-static'
9
+
10
+ import { Application } from './declarations'
11
+
12
+ export { Koa, bodyParser, cors, serveStatic }
13
+ export * from './authentication'
14
+ export * from './declarations'
15
+ export * from './handlers'
16
+ export * from './rest'
17
+
18
+ const debug = createDebug('@feathersjs/koa')
19
+
20
+ export function koa<S = any, C = any>(
21
+ feathersApp?: FeathersApplication<S, C>,
22
+ koaApp: Koa = new Koa()
23
+ ): Application<S, C> {
24
+ if (!feathersApp) {
25
+ return koaApp as any
23
26
  }
24
27
 
25
- if (typeof _app.setup !== 'function') {
26
- throw new Error('@feathersjs/koa requires a valid Feathers application instance');
28
+ if (typeof feathersApp.setup !== 'function') {
29
+ throw new Error('@feathersjs/koa requires a valid Feathers application instance')
27
30
  }
28
31
 
29
- const app = _app as Application;
30
- const { listen: koaListen, use: koaUse } = koaApp;
31
- const oldUse = app.use;
32
+ const app = feathersApp as any as Application<S, C>
33
+ const { listen: koaListen, use: koaUse } = koaApp
34
+ const { use: feathersUse, teardown: feathersTeardown } = feathersApp
32
35
 
33
36
  Object.assign(app, {
34
- use (location: string|Koa.Middleware, ...args: any[]) {
37
+ use(location: string | Koa.Middleware, ...args: any[]) {
35
38
  if (typeof location === 'string') {
36
- return (oldUse as any).call(this, location, ...args);
39
+ return (feathersUse as any).call(this, location, ...args)
37
40
  }
38
41
 
39
- return koaUse.call(this, location);
42
+ return koaUse.call(this, location)
40
43
  },
41
44
 
42
- async listen (port?: number, ...args: any[]) {
43
- const server = koaListen.call(this, port, ...args);
45
+ async listen(port?: number, ...args: any[]) {
46
+ const server = koaListen.call(this, port, ...args)
47
+
48
+ this.server = server
49
+ await this.setup(server)
50
+ debug('Feathers application listening')
44
51
 
45
- await this.setup(server);
46
- debug('Feathers application listening');
52
+ return server
53
+ },
47
54
 
48
- return server;
55
+ async teardown(server?: any) {
56
+ return feathersTeardown
57
+ .call(this, server)
58
+ .then(
59
+ () => new Promise((resolve, reject) => this.server.close((e) => (e ? reject(e) : resolve(this))))
60
+ )
49
61
  }
50
- } as Application);
62
+ } as Application)
51
63
 
52
- const feathersDescriptors = {
64
+ const appDescriptors = {
53
65
  ...Object.getOwnPropertyDescriptors(Object.getPrototypeOf(app)),
54
66
  ...Object.getOwnPropertyDescriptors(app)
55
- };
56
- const koaDescriptors = {
67
+ }
68
+ const newDescriptors = {
57
69
  ...Object.getOwnPropertyDescriptors(Object.getPrototypeOf(koaApp)),
58
70
  ...Object.getOwnPropertyDescriptors(koaApp)
59
- };
71
+ }
60
72
 
61
73
  // Copy all non-existing properties (including non-enumerables)
62
74
  // 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];
75
+ Object.keys(newDescriptors).forEach((prop) => {
76
+ const appProp = appDescriptors[prop]
77
+ const newProp = newDescriptors[prop]
66
78
 
67
- if (koaProp !== undefined && feathersProp === undefined) {
68
- Object.defineProperty(app, prop, koaProp);
79
+ if (appProp === undefined && newProp !== undefined) {
80
+ Object.defineProperty(app, prop, newProp)
69
81
  }
70
- });
82
+ })
71
83
 
72
- koaQs(app as any);
73
- app.configure(routing());
74
- app.use((ctx, next) => {
75
- ctx.feathers = { provider: 'rest' };
84
+ koaQs(app as any)
85
+
86
+ Object.getOwnPropertySymbols(koaApp).forEach((symbol) => {
87
+ const target = app as any
88
+ const source = koaApp as any
76
89
 
77
- return next();
78
- });
90
+ target[symbol] = source[symbol]
91
+ })
92
+
93
+ // This reinitializes hooks
94
+ app.setup = feathersApp.setup as any
95
+ app.teardown = feathersApp.teardown as any
96
+
97
+ app.configure(routing() as any)
98
+ app.use((ctx, next) => {
99
+ ctx.feathers = { ...ctx.feathers, provider: 'rest' }
100
+ return next()
101
+ })
79
102
 
80
- return app;
103
+ return app
81
104
  }