@feathersjs/express 5.0.0-pre.15 → 5.0.0-pre.18
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 +35 -0
- package/LICENSE +1 -1
- package/README.md +2 -2
- package/lib/authentication.d.ts +5 -6
- package/lib/authentication.js +26 -37
- package/lib/authentication.js.map +1 -1
- package/lib/declarations.d.ts +8 -5
- package/lib/index.d.ts +5 -5
- package/lib/index.js +51 -44
- package/lib/index.js.map +1 -1
- package/lib/rest.d.ts +9 -9
- package/lib/rest.js +58 -73
- package/lib/rest.js.map +1 -1
- package/package.json +22 -21
- package/src/authentication.ts +36 -46
- package/src/declarations.ts +17 -14
- package/src/handlers.ts +4 -4
- package/src/index.ts +42 -30
- package/src/rest.ts +78 -87
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,41 @@
|
|
|
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.18](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.17...v5.0.0-pre.18) (2022-04-11)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **core:** Add app.teardown functionality ([#2570](https://github.com/feathersjs/feathers/issues/2570)) ([fcdf524](https://github.com/feathersjs/feathers/commit/fcdf524ae1995bb59265d39f12e98b7794bed023))
|
|
12
|
+
* **core:** Finalize app.teardown() functionality ([#2584](https://github.com/feathersjs/feathers/issues/2584)) ([1a166f3](https://github.com/feathersjs/feathers/commit/1a166f3ded811ecacf0ae8cb67880bc9fa2eeafa))
|
|
13
|
+
* **transport-commons:** add `context.http.response` ([#2524](https://github.com/feathersjs/feathers/issues/2524)) ([5bc9d44](https://github.com/feathersjs/feathers/commit/5bc9d447043c2e2b742c73ed28ecf3b3264dd9e5))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# [5.0.0-pre.17](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.16...v5.0.0-pre.17) (2022-02-15)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
* **express:** Fix application typings to work with typed configuration ([#2539](https://github.com/feathersjs/feathers/issues/2539)) ([b9dfaee](https://github.com/feathersjs/feathers/commit/b9dfaee834b13864c1ed4f2f6a244eb5bb70395b))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# [5.0.0-pre.16](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.15...v5.0.0-pre.16) (2022-01-12)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Features
|
|
34
|
+
|
|
35
|
+
* **express, koa:** make transports similar ([#2486](https://github.com/feathersjs/feathers/issues/2486)) ([26aa937](https://github.com/feathersjs/feathers/commit/26aa937c114fb8596dfefc599b1f53cead69c159))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
6
41
|
# [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
42
|
|
|
8
43
|
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @feathersjs/express
|
|
2
2
|
|
|
3
3
|
[](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI)
|
|
4
|
-
[](https://david-dm.org/feathersjs/feathers?path=packages/express)
|
|
5
4
|
[](https://www.npmjs.com/package/@feathersjs/express)
|
|
5
|
+
[](https://discord.gg/qa8kez8QBx)
|
|
6
6
|
|
|
7
7
|
> Feathers Express framework bindings and REST provider
|
|
8
8
|
|
|
@@ -18,6 +18,6 @@ Refer to the [Feathers Express API documentation](https://docs.feathersjs.com/ap
|
|
|
18
18
|
|
|
19
19
|
## License
|
|
20
20
|
|
|
21
|
-
Copyright (c)
|
|
21
|
+
Copyright (c) 2022 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors)
|
|
22
22
|
|
|
23
23
|
Licensed under the [MIT license](LICENSE).
|
package/lib/authentication.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare type
|
|
1
|
+
import { RequestHandler } from 'express';
|
|
2
|
+
export declare type AuthenticationSettings = {
|
|
3
3
|
service?: string;
|
|
4
|
-
strategies
|
|
4
|
+
strategies?: string[];
|
|
5
5
|
};
|
|
6
|
-
export declare function parseAuthentication(settings?:
|
|
7
|
-
export declare function authenticate(
|
|
8
|
-
export {};
|
|
6
|
+
export declare function parseAuthentication(settings?: AuthenticationSettings): RequestHandler;
|
|
7
|
+
export declare function authenticate(settings: string | AuthenticationSettings, ...strategies: string[]): RequestHandler;
|
package/lib/authentication.js
CHANGED
|
@@ -2,55 +2,44 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.authenticate = exports.parseAuthentication = void 0;
|
|
4
4
|
const commons_1 = require("@feathersjs/commons");
|
|
5
|
-
const
|
|
5
|
+
const authentication_1 = require("@feathersjs/authentication");
|
|
6
6
|
const debug = (0, commons_1.createDebug)('@feathersjs/express/authentication');
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const toHandler = (func) => {
|
|
8
|
+
return (req, res, next) => func(req, res, next).catch(error => next(error));
|
|
9
|
+
};
|
|
10
10
|
function parseAuthentication(settings = {}) {
|
|
11
|
-
return
|
|
11
|
+
return toHandler(async (req, res, next) => {
|
|
12
|
+
var _a;
|
|
12
13
|
const app = req.app;
|
|
13
|
-
const service = app.defaultAuthentication ?
|
|
14
|
-
if (service
|
|
14
|
+
const service = (_a = app.defaultAuthentication) === null || _a === void 0 ? void 0 : _a.call(app, settings.service);
|
|
15
|
+
if (!service) {
|
|
15
16
|
return next();
|
|
16
17
|
}
|
|
17
18
|
const config = service.configuration;
|
|
18
|
-
const authStrategies = config.parseStrategies || config.authStrategies || [];
|
|
19
|
+
const authStrategies = settings.strategies || config.parseStrategies || config.authStrategies || [];
|
|
19
20
|
if (authStrategies.length === 0) {
|
|
20
21
|
debug('No `authStrategies` or `parseStrategies` found in authentication configuration');
|
|
21
22
|
return next();
|
|
22
23
|
}
|
|
23
|
-
service.parse(req, res, ...authStrategies)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
next();
|
|
33
|
-
}).catch(next);
|
|
34
|
-
};
|
|
24
|
+
const authentication = await service.parse(req, res, ...authStrategies);
|
|
25
|
+
if (authentication) {
|
|
26
|
+
debug('Parsed authentication from HTTP header', authentication);
|
|
27
|
+
req.feathers = { ...req.feathers, authentication };
|
|
28
|
+
}
|
|
29
|
+
return next();
|
|
30
|
+
});
|
|
35
31
|
}
|
|
36
32
|
exports.parseAuthentication = parseAuthentication;
|
|
37
|
-
function authenticate(
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
service.authenticate(authentication, req.feathers, ...settings.strategies)
|
|
48
|
-
.then((authResult) => {
|
|
49
|
-
debug('Merging request with', authResult);
|
|
50
|
-
(0, lodash_1.merge)(req, authResult);
|
|
51
|
-
next();
|
|
52
|
-
}).catch(next);
|
|
53
|
-
};
|
|
33
|
+
function authenticate(settings, ...strategies) {
|
|
34
|
+
const hook = (0, authentication_1.authenticate)(settings, ...strategies);
|
|
35
|
+
return toHandler(async (req, _res, next) => {
|
|
36
|
+
const app = req.app;
|
|
37
|
+
const params = req.feathers;
|
|
38
|
+
const context = { app, params };
|
|
39
|
+
await hook(context);
|
|
40
|
+
req.feathers = context.params;
|
|
41
|
+
return next();
|
|
42
|
+
});
|
|
54
43
|
}
|
|
55
44
|
exports.authenticate = authenticate;
|
|
56
45
|
//# sourceMappingURL=authentication.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authentication.js","sourceRoot":"","sources":["../src/authentication.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"authentication.js","sourceRoot":"","sources":["../src/authentication.ts"],"names":[],"mappings":";;;AAEA,iDAAkD;AAClD,+DAA8E;AAI9E,MAAM,KAAK,GAAG,IAAA,qBAAW,EAAC,oCAAoC,CAAC,CAAC;AAEhE,MAAM,SAAS,GAAG,CAAC,IAAsE,EAAkB,EAAE;IAC3G,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9E,CAAC,CAAC;AAOF,SAAgB,mBAAmB,CAAE,WAAmC,EAAE;IACxE,OAAO,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;;QACxC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAyB,CAAC;QAC1C,MAAM,OAAO,GAAG,MAAA,GAAG,CAAC,qBAAqB,oDAAG,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,EAAE,GAAG,EAAE,GAAG,cAAc,CAAC,CAAA;QAEvE,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,CAAC;AACL,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,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QACzC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAyB,CAAC;QAC1C,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC;QAC5B,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,MAAM,EAAwB,CAAC;QAEtD,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpB,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;QAE9B,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAdD,oCAcC"}
|
package/lib/declarations.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import http from 'http';
|
|
3
3
|
import express, { Express } from 'express';
|
|
4
|
-
import { Application as FeathersApplication, Params as FeathersParams, HookContext, ServiceMethods, ServiceInterface } from '@feathersjs/feathers';
|
|
4
|
+
import { Application as FeathersApplication, Params as FeathersParams, HookContext, ServiceMethods, ServiceInterface, RouteLookup } from '@feathersjs/feathers';
|
|
5
5
|
interface ExpressUseHandler<T, Services> {
|
|
6
6
|
<L extends keyof Services & string>(path: L, ...middlewareOrService: (Express | express.RequestHandler | (keyof any extends keyof Services ? ServiceInterface : Services[L]))[]): T;
|
|
7
7
|
(path: string | RegExp, ...expressHandlers: express.RequestHandler[]): T;
|
|
@@ -14,19 +14,22 @@ export interface ExpressOverrides<Services> {
|
|
|
14
14
|
listen(port: number | string | any, callback?: () => void): Promise<http.Server>;
|
|
15
15
|
listen(callback?: () => void): Promise<http.Server>;
|
|
16
16
|
use: ExpressUseHandler<this, Services>;
|
|
17
|
+
server: http.Server;
|
|
17
18
|
}
|
|
18
|
-
export declare type Application<Services = any, Settings = any> = Omit<Express, 'listen' | 'use'> & FeathersApplication<Services, Settings> & ExpressOverrides<Services>;
|
|
19
|
+
export declare type Application<Services = any, Settings = any> = Omit<Express, 'listen' | 'use' | 'get' | 'set'> & FeathersApplication<Services, Settings> & ExpressOverrides<Services>;
|
|
19
20
|
declare module '@feathersjs/feathers/lib/declarations' {
|
|
20
21
|
interface ServiceOptions {
|
|
21
|
-
|
|
22
|
-
before
|
|
23
|
-
after
|
|
22
|
+
express?: {
|
|
23
|
+
before?: express.RequestHandler[];
|
|
24
|
+
after?: express.RequestHandler[];
|
|
25
|
+
composed?: express.RequestHandler;
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
declare module 'express-serve-static-core' {
|
|
28
30
|
interface Request {
|
|
29
31
|
feathers?: Partial<FeathersParams>;
|
|
32
|
+
lookup?: RouteLookup;
|
|
30
33
|
}
|
|
31
34
|
interface Response {
|
|
32
35
|
data?: any;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Express } from 'express';
|
|
2
2
|
import { Application as FeathersApplication } from '@feathersjs/feathers';
|
|
3
3
|
import { Application } from './declarations';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export { _static as serveStatic, _static as static, json, raw, text, urlencoded, query, errorHandler, notFound, express as original, authenticate, parseAuthentication };
|
|
7
|
-
export * from './rest';
|
|
4
|
+
export { default as original, static, static as serveStatic, json, raw, text, urlencoded, query } from 'express';
|
|
5
|
+
export * from './authentication';
|
|
8
6
|
export * from './declarations';
|
|
7
|
+
export * from './handlers';
|
|
8
|
+
export * from './rest';
|
|
9
9
|
export default function feathersExpress<S = any, C = any>(feathersApp?: FeathersApplication<S, C>, expressApp?: Express): Application<S, C>;
|
package/lib/index.js
CHANGED
|
@@ -1,47 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
8
12
|
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
13
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
22
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
23
15
|
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
24
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.
|
|
26
|
-
const express_1 =
|
|
27
|
-
exports.original = express_1.default;
|
|
28
|
-
Object.defineProperty(exports, "serveStatic", { enumerable: true, get: function () { return express_1.static; } });
|
|
29
|
-
Object.defineProperty(exports, "static", { enumerable: true, get: function () { return express_1.static; } });
|
|
30
|
-
Object.defineProperty(exports, "json", { enumerable: true, get: function () { return express_1.json; } });
|
|
31
|
-
Object.defineProperty(exports, "raw", { enumerable: true, get: function () { return express_1.raw; } });
|
|
32
|
-
Object.defineProperty(exports, "text", { enumerable: true, get: function () { return express_1.text; } });
|
|
33
|
-
Object.defineProperty(exports, "urlencoded", { enumerable: true, get: function () { return express_1.urlencoded; } });
|
|
34
|
-
Object.defineProperty(exports, "query", { enumerable: true, get: function () { return express_1.query; } });
|
|
20
|
+
exports.query = exports.urlencoded = exports.text = exports.raw = exports.json = exports.serveStatic = exports.static = exports.original = void 0;
|
|
21
|
+
const express_1 = __importDefault(require("express"));
|
|
35
22
|
const feathers_1 = require("@feathersjs/feathers");
|
|
23
|
+
const transport_commons_1 = require("@feathersjs/transport-commons");
|
|
36
24
|
const commons_1 = require("@feathersjs/commons");
|
|
37
|
-
|
|
38
|
-
Object.defineProperty(exports, "
|
|
39
|
-
Object.defineProperty(exports, "
|
|
40
|
-
|
|
41
|
-
Object.defineProperty(exports, "
|
|
42
|
-
Object.defineProperty(exports, "
|
|
43
|
-
|
|
25
|
+
var express_2 = require("express");
|
|
26
|
+
Object.defineProperty(exports, "original", { enumerable: true, get: function () { return __importDefault(express_2).default; } });
|
|
27
|
+
Object.defineProperty(exports, "static", { enumerable: true, get: function () { return express_2.static; } });
|
|
28
|
+
Object.defineProperty(exports, "serveStatic", { enumerable: true, get: function () { return express_2.static; } });
|
|
29
|
+
Object.defineProperty(exports, "json", { enumerable: true, get: function () { return express_2.json; } });
|
|
30
|
+
Object.defineProperty(exports, "raw", { enumerable: true, get: function () { return express_2.raw; } });
|
|
31
|
+
Object.defineProperty(exports, "text", { enumerable: true, get: function () { return express_2.text; } });
|
|
32
|
+
Object.defineProperty(exports, "urlencoded", { enumerable: true, get: function () { return express_2.urlencoded; } });
|
|
33
|
+
Object.defineProperty(exports, "query", { enumerable: true, get: function () { return express_2.query; } });
|
|
34
|
+
__exportStar(require("./authentication"), exports);
|
|
44
35
|
__exportStar(require("./declarations"), exports);
|
|
36
|
+
__exportStar(require("./handlers"), exports);
|
|
37
|
+
__exportStar(require("./rest"), exports);
|
|
45
38
|
const debug = (0, commons_1.createDebug)('@feathersjs/express');
|
|
46
39
|
function feathersExpress(feathersApp, expressApp = (0, express_1.default)()) {
|
|
47
40
|
if (!feathersApp) {
|
|
@@ -50,9 +43,10 @@ function feathersExpress(feathersApp, expressApp = (0, express_1.default)()) {
|
|
|
50
43
|
if (typeof feathersApp.setup !== 'function') {
|
|
51
44
|
throw new Error('@feathersjs/express requires a valid Feathers application instance');
|
|
52
45
|
}
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
const
|
|
46
|
+
const app = expressApp;
|
|
47
|
+
const { use: expressUse, listen: expressListen } = expressApp;
|
|
48
|
+
const { use: feathersUse, teardown: feathersTeardown } = feathersApp;
|
|
49
|
+
Object.assign(app, {
|
|
56
50
|
use(location, ...rest) {
|
|
57
51
|
let service;
|
|
58
52
|
let options = {};
|
|
@@ -78,37 +72,50 @@ function feathersExpress(feathersApp, expressApp = (0, express_1.default)()) {
|
|
|
78
72
|
// Check for service (any object with at least one service method)
|
|
79
73
|
if (hasMethod(['handle', 'set']) || !hasMethod(feathers_1.defaultServiceMethods)) {
|
|
80
74
|
debug('Passing app.use call to Express app');
|
|
81
|
-
return
|
|
75
|
+
return expressUse.call(this, location, ...rest);
|
|
82
76
|
}
|
|
83
77
|
debug('Registering service with middleware', middleware);
|
|
84
78
|
// Since this is a service, call Feathers `.use`
|
|
85
|
-
|
|
79
|
+
feathersUse.call(this, location, service, {
|
|
86
80
|
...options,
|
|
87
|
-
middleware
|
|
81
|
+
express: middleware
|
|
88
82
|
});
|
|
89
83
|
return this;
|
|
90
84
|
},
|
|
91
85
|
async listen(...args) {
|
|
92
|
-
const server =
|
|
86
|
+
const server = expressListen.call(this, ...args);
|
|
87
|
+
this.server = server;
|
|
93
88
|
await this.setup(server);
|
|
94
89
|
debug('Feathers application listening');
|
|
95
90
|
return server;
|
|
91
|
+
},
|
|
92
|
+
async teardown(server) {
|
|
93
|
+
return feathersTeardown.call(this, server).then(() => new Promise((resolve, reject) => this.server.close(e => e ? reject(e) : resolve(this))));
|
|
96
94
|
}
|
|
95
|
+
});
|
|
96
|
+
const appDescriptors = {
|
|
97
|
+
...Object.getOwnPropertyDescriptors(Object.getPrototypeOf(app)),
|
|
98
|
+
...Object.getOwnPropertyDescriptors(app)
|
|
97
99
|
};
|
|
98
|
-
const
|
|
100
|
+
const newDescriptors = {
|
|
99
101
|
...Object.getOwnPropertyDescriptors(Object.getPrototypeOf(feathersApp)),
|
|
100
102
|
...Object.getOwnPropertyDescriptors(feathersApp)
|
|
101
103
|
};
|
|
102
104
|
// Copy all non-existing properties (including non-enumerables)
|
|
103
105
|
// that don't already exist on the Express app
|
|
104
|
-
Object.keys(
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
if (
|
|
108
|
-
Object.defineProperty(expressApp, prop,
|
|
106
|
+
Object.keys(newDescriptors).forEach(prop => {
|
|
107
|
+
const appProp = appDescriptors[prop];
|
|
108
|
+
const newProp = newDescriptors[prop];
|
|
109
|
+
if (appProp === undefined && newProp !== undefined) {
|
|
110
|
+
Object.defineProperty(expressApp, prop, newProp);
|
|
109
111
|
}
|
|
110
112
|
});
|
|
111
|
-
|
|
113
|
+
app.configure((0, transport_commons_1.routing)());
|
|
114
|
+
app.use((req, _res, next) => {
|
|
115
|
+
req.feathers = { ...req.feathers, provider: 'rest' };
|
|
116
|
+
return next();
|
|
117
|
+
});
|
|
118
|
+
return app;
|
|
112
119
|
}
|
|
113
120
|
exports.default = feathersExpress;
|
|
114
121
|
if (typeof module !== 'undefined') {
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/rest.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
export declare
|
|
5
|
-
export declare
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export declare
|
|
1
|
+
import { RequestHandler } from 'express';
|
|
2
|
+
import { AuthenticationSettings } from './authentication';
|
|
3
|
+
import { Application } from './declarations';
|
|
4
|
+
export declare const formatter: RequestHandler;
|
|
5
|
+
export declare type RestOptions = {
|
|
6
|
+
formatter?: RequestHandler;
|
|
7
|
+
authentication?: AuthenticationSettings;
|
|
8
|
+
};
|
|
9
|
+
export declare const rest: (options?: RestOptions | RequestHandler) => (app: Application) => void;
|
package/lib/rest.js
CHANGED
|
@@ -1,22 +1,56 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.rest = exports.
|
|
3
|
+
exports.rest = exports.formatter = void 0;
|
|
4
|
+
const express_1 = require("express");
|
|
4
5
|
const errors_1 = require("@feathersjs/errors");
|
|
5
6
|
const commons_1 = require("@feathersjs/commons");
|
|
6
7
|
const transport_commons_1 = require("@feathersjs/transport-commons");
|
|
7
8
|
const feathers_1 = require("@feathersjs/feathers");
|
|
8
|
-
const express_1 = require("express");
|
|
9
9
|
const authentication_1 = require("./authentication");
|
|
10
10
|
const debug = (0, commons_1.createDebug)('@feathersjs/express/rest');
|
|
11
|
-
const
|
|
12
|
-
req.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
const toHandler = (func) => {
|
|
12
|
+
return (req, res, next) => func(req, res, next).catch(error => next(error));
|
|
13
|
+
};
|
|
14
|
+
const serviceMiddleware = () => {
|
|
15
|
+
return toHandler(async (req, res, next) => {
|
|
16
|
+
const { query, headers, path, body: data, method: httpMethod } = req;
|
|
17
|
+
const methodOverride = req.headers[transport_commons_1.http.METHOD_HEADER];
|
|
18
|
+
const { service, params: { __id: id = null, ...route } = {} } = req.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
|
+
res.statusCode = error.code;
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
const createArguments = transport_commons_1.http.argumentsFor[method] || transport_commons_1.http.argumentsFor.default;
|
|
28
|
+
const params = { query, headers, route, ...req.feathers };
|
|
29
|
+
const args = createArguments({ id, data, params });
|
|
30
|
+
const contextBase = (0, feathers_1.createContext)(service, method, { http: {} });
|
|
31
|
+
res.hook = contextBase;
|
|
32
|
+
const context = await service[method](...args, contextBase);
|
|
33
|
+
res.hook = context;
|
|
34
|
+
const response = transport_commons_1.http.getResponse(context);
|
|
35
|
+
res.statusCode = response.status;
|
|
36
|
+
res.set(response.headers);
|
|
37
|
+
res.data = response.body;
|
|
38
|
+
return next();
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
const servicesMiddleware = () => {
|
|
42
|
+
return toHandler(async (req, res, next) => {
|
|
43
|
+
const app = req.app;
|
|
44
|
+
const lookup = app.lookup(req.path);
|
|
45
|
+
if (!lookup) {
|
|
46
|
+
return next();
|
|
47
|
+
}
|
|
48
|
+
req.lookup = lookup;
|
|
49
|
+
const options = (0, feathers_1.getServiceOptions)(lookup.service);
|
|
50
|
+
const middleware = options.express.composed;
|
|
51
|
+
return middleware(req, res, next);
|
|
52
|
+
});
|
|
18
53
|
};
|
|
19
|
-
exports.feathersParams = feathersParams;
|
|
20
54
|
const formatter = (_req, res, next) => {
|
|
21
55
|
if (res.data === undefined) {
|
|
22
56
|
return next();
|
|
@@ -28,73 +62,24 @@ const formatter = (_req, res, next) => {
|
|
|
28
62
|
});
|
|
29
63
|
};
|
|
30
64
|
exports.formatter = formatter;
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const params = { query, route, ...req.feathers };
|
|
37
|
-
const context = await callback(req, res, { id, data, params });
|
|
38
|
-
const result = transport_commons_1.http.getData(context);
|
|
39
|
-
res.data = result;
|
|
40
|
-
res.status(transport_commons_1.http.getStatusCode(context, result));
|
|
41
|
-
next();
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
next(error);
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
exports.serviceMiddleware = serviceMiddleware;
|
|
48
|
-
const serviceMethodHandler = (service, methodName, getArgs, headerOverride) => (0, exports.serviceMiddleware)(async (req, res, options) => {
|
|
49
|
-
const methodOverride = typeof headerOverride === 'string' && req.headers[headerOverride];
|
|
50
|
-
const method = methodOverride ? methodOverride : methodName;
|
|
51
|
-
const { methods } = (0, feathers_1.getServiceOptions)(service);
|
|
52
|
-
if (!methods.includes(method) || feathers_1.defaultServiceMethods.includes(methodOverride)) {
|
|
53
|
-
res.status(transport_commons_1.http.statusCodes.methodNotAllowed);
|
|
54
|
-
throw new errors_1.MethodNotAllowed(`Method \`${method}\` is not supported by this endpoint.`);
|
|
55
|
-
}
|
|
56
|
-
const args = getArgs(options);
|
|
57
|
-
const context = (0, feathers_1.createContext)(service, method, { http: {} });
|
|
58
|
-
res.hook = context;
|
|
59
|
-
return service[method](...args, context);
|
|
60
|
-
});
|
|
61
|
-
exports.serviceMethodHandler = serviceMethodHandler;
|
|
62
|
-
function rest(handler = exports.formatter) {
|
|
63
|
-
return function (app) {
|
|
65
|
+
const rest = (options) => {
|
|
66
|
+
options = typeof options === 'function' ? { formatter: options } : options || {};
|
|
67
|
+
const formatterMiddleware = options.formatter || exports.formatter;
|
|
68
|
+
const authenticationOptions = options.authentication;
|
|
69
|
+
return (app) => {
|
|
64
70
|
if (typeof app.route !== 'function') {
|
|
65
71
|
throw new Error('@feathersjs/express/rest needs an Express compatible app.');
|
|
66
72
|
}
|
|
67
|
-
app.use(
|
|
68
|
-
app.use((
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
const baseUri = `/${path}`;
|
|
77
|
-
const find = (0, exports.serviceMethodHandler)(service, 'find', transport_commons_1.http.argumentsFor.find);
|
|
78
|
-
const get = (0, exports.serviceMethodHandler)(service, 'get', transport_commons_1.http.argumentsFor.get);
|
|
79
|
-
const create = (0, exports.serviceMethodHandler)(service, 'create', transport_commons_1.http.argumentsFor.create, transport_commons_1.http.METHOD_HEADER);
|
|
80
|
-
const update = (0, exports.serviceMethodHandler)(service, 'update', transport_commons_1.http.argumentsFor.update);
|
|
81
|
-
const patch = (0, exports.serviceMethodHandler)(service, 'patch', transport_commons_1.http.argumentsFor.patch);
|
|
82
|
-
const remove = (0, exports.serviceMethodHandler)(service, 'remove', transport_commons_1.http.argumentsFor.remove);
|
|
83
|
-
debug(`Adding REST provider for service \`${path}\` at base route \`${baseUri}\``);
|
|
84
|
-
const idRoute = '/:__feathersId';
|
|
85
|
-
const serviceRouter = (0, express_1.Router)({ mergeParams: true })
|
|
86
|
-
.get('/', find)
|
|
87
|
-
.post('/', create)
|
|
88
|
-
.get(idRoute, get)
|
|
89
|
-
.put('/', update)
|
|
90
|
-
.put(idRoute, update)
|
|
91
|
-
.patch('/', patch)
|
|
92
|
-
.patch(idRoute, patch)
|
|
93
|
-
.delete('/', remove)
|
|
94
|
-
.delete(idRoute, remove);
|
|
95
|
-
app.use(baseUri, ...before, serviceRouter, ...after);
|
|
73
|
+
app.use((0, authentication_1.parseAuthentication)(authenticationOptions));
|
|
74
|
+
app.use(servicesMiddleware());
|
|
75
|
+
app.mixins.push((_service, _path, options) => {
|
|
76
|
+
const { express: { before = [], after = [] } = {} } = options;
|
|
77
|
+
const middlewares = [].concat(before, serviceMiddleware(), after, formatterMiddleware);
|
|
78
|
+
const middleware = (0, express_1.Router)().use(middlewares);
|
|
79
|
+
options.express || (options.express = {});
|
|
80
|
+
options.express.composed = middleware;
|
|
96
81
|
});
|
|
97
82
|
};
|
|
98
|
-
}
|
|
83
|
+
};
|
|
99
84
|
exports.rest = rest;
|
|
100
85
|
//# 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":";;;AAAA,+CAAsD;AACtD,iDAAkD;AAClD,qEAAqD;AACrD,
|
|
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/express",
|
|
3
3
|
"description": "Feathers Express framework bindings and REST provider",
|
|
4
|
-
"version": "5.0.0-pre.
|
|
4
|
+
"version": "5.0.0-pre.18",
|
|
5
5
|
"homepage": "https://feathersjs.com",
|
|
6
6
|
"main": "lib/",
|
|
7
|
+
"type": "lib/",
|
|
7
8
|
"keywords": [
|
|
8
9
|
"feathers",
|
|
9
10
|
"feathers-plugin"
|
|
@@ -15,7 +16,8 @@
|
|
|
15
16
|
},
|
|
16
17
|
"repository": {
|
|
17
18
|
"type": "git",
|
|
18
|
-
"url": "git://github.com/feathersjs/feathers.git"
|
|
19
|
+
"url": "git://github.com/feathersjs/feathers.git",
|
|
20
|
+
"directory": "packages/express"
|
|
19
21
|
},
|
|
20
22
|
"author": {
|
|
21
23
|
"name": "Feathers contributors",
|
|
@@ -49,28 +51,27 @@
|
|
|
49
51
|
"access": "public"
|
|
50
52
|
},
|
|
51
53
|
"dependencies": {
|
|
52
|
-
"@feathersjs/
|
|
53
|
-
"@feathersjs/
|
|
54
|
-
"@feathersjs/
|
|
55
|
-
"@feathersjs/
|
|
54
|
+
"@feathersjs/authentication": "^5.0.0-pre.18",
|
|
55
|
+
"@feathersjs/commons": "^5.0.0-pre.18",
|
|
56
|
+
"@feathersjs/errors": "^5.0.0-pre.18",
|
|
57
|
+
"@feathersjs/feathers": "^5.0.0-pre.18",
|
|
58
|
+
"@feathersjs/transport-commons": "^5.0.0-pre.18",
|
|
56
59
|
"@types/express": "^4.17.13",
|
|
57
|
-
"@types/express-serve-static-core": "^4.17.
|
|
58
|
-
"express": "^4.17.
|
|
59
|
-
"lodash": "^4.17.21"
|
|
60
|
+
"@types/express-serve-static-core": "^4.17.28",
|
|
61
|
+
"express": "^4.17.3"
|
|
60
62
|
},
|
|
61
63
|
"devDependencies": {
|
|
62
|
-
"@feathersjs/authentication": "^5.0.0-pre.
|
|
63
|
-
"@feathersjs/
|
|
64
|
-
"@
|
|
65
|
-
"@types/
|
|
66
|
-
"@types/
|
|
67
|
-
"
|
|
68
|
-
"axios": "^0.24.0",
|
|
64
|
+
"@feathersjs/authentication-local": "^5.0.0-pre.18",
|
|
65
|
+
"@feathersjs/tests": "^5.0.0-pre.18",
|
|
66
|
+
"@types/lodash": "^4.14.181",
|
|
67
|
+
"@types/mocha": "^9.1.0",
|
|
68
|
+
"@types/node": "^17.0.23",
|
|
69
|
+
"axios": "^0.26.1",
|
|
69
70
|
"lodash": "^4.17.21",
|
|
70
|
-
"mocha": "^9.
|
|
71
|
-
"shx": "^0.3.
|
|
72
|
-
"ts-node": "^10.
|
|
73
|
-
"typescript": "^4.
|
|
71
|
+
"mocha": "^9.2.2",
|
|
72
|
+
"shx": "^0.3.4",
|
|
73
|
+
"ts-node": "^10.7.0",
|
|
74
|
+
"typescript": "^4.6.3"
|
|
74
75
|
},
|
|
75
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "c0b7b67d872dcd6b6d94e4587f21332c8a519b50"
|
|
76
77
|
}
|
package/src/authentication.ts
CHANGED
|
@@ -1,71 +1,61 @@
|
|
|
1
|
+
import { RequestHandler, Request, Response } from 'express';
|
|
2
|
+
import { HookContext } from '@feathersjs/feathers';
|
|
1
3
|
import { createDebug } from '@feathersjs/commons';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
+
import { authenticate as AuthenticateHook } from '@feathersjs/authentication';
|
|
5
|
+
|
|
6
|
+
import { Application } from './declarations';
|
|
4
7
|
|
|
5
8
|
const debug = createDebug('@feathersjs/express/authentication');
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
strategies: string[]
|
|
10
|
+
const toHandler = (func: (req: Request, res: Response, next: () => void) => Promise<void>): RequestHandler => {
|
|
11
|
+
return (req, res, next) => func(req, res, next).catch(error => next(error));
|
|
10
12
|
};
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
export type AuthenticationSettings = {
|
|
15
|
+
service?: string;
|
|
16
|
+
strategies?: string[];
|
|
17
|
+
};
|
|
16
18
|
|
|
17
|
-
export function parseAuthentication (settings:
|
|
18
|
-
return
|
|
19
|
-
const app = req.app as any;
|
|
20
|
-
const service = app.defaultAuthentication
|
|
19
|
+
export function parseAuthentication (settings: AuthenticationSettings = {}): RequestHandler {
|
|
20
|
+
return toHandler(async (req, res, next) => {
|
|
21
|
+
const app = req.app as any as Application;
|
|
22
|
+
const service = app.defaultAuthentication?.(settings.service);
|
|
21
23
|
|
|
22
|
-
if (service
|
|
24
|
+
if (!service) {
|
|
23
25
|
return next();
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
const config = service.configuration;
|
|
27
|
-
const authStrategies = config.parseStrategies || config.authStrategies || [];
|
|
29
|
+
const authStrategies = settings.strategies || config.parseStrategies || config.authStrategies || [];
|
|
28
30
|
|
|
29
31
|
if (authStrategies.length === 0) {
|
|
30
32
|
debug('No `authStrategies` or `parseStrategies` found in authentication configuration');
|
|
31
33
|
return next();
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
service.parse(req, res, ...authStrategies)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
feathers: { authentication }
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
next();
|
|
45
|
-
}).catch(next);
|
|
46
|
-
};
|
|
47
|
-
}
|
|
36
|
+
const authentication = await service.parse(req, res, ...authStrategies)
|
|
37
|
+
|
|
38
|
+
if (authentication) {
|
|
39
|
+
debug('Parsed authentication from HTTP header', authentication);
|
|
40
|
+
req.feathers = { ...req.feathers, authentication };
|
|
41
|
+
}
|
|
48
42
|
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
return next();
|
|
44
|
+
});
|
|
45
|
+
}
|
|
51
46
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
47
|
+
export function authenticate (settings: string | AuthenticationSettings, ...strategies: string[]): RequestHandler {
|
|
48
|
+
const hook = AuthenticateHook(settings, ...strategies);
|
|
55
49
|
|
|
56
|
-
return (
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
const
|
|
50
|
+
return toHandler(async (req, _res, next) => {
|
|
51
|
+
const app = req.app as any as Application;
|
|
52
|
+
const params = req.feathers;
|
|
53
|
+
const context = { app, params } as any as HookContext;
|
|
60
54
|
|
|
61
|
-
|
|
55
|
+
await hook(context);
|
|
62
56
|
|
|
63
|
-
|
|
64
|
-
.then((authResult: any) => {
|
|
65
|
-
debug('Merging request with', authResult);
|
|
66
|
-
merge(req, authResult);
|
|
57
|
+
req.feathers = context.params;
|
|
67
58
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
};
|
|
59
|
+
return next();
|
|
60
|
+
});
|
|
71
61
|
}
|
package/src/declarations.ts
CHANGED
|
@@ -2,7 +2,7 @@ import http from 'http';
|
|
|
2
2
|
import express, { Express } from 'express';
|
|
3
3
|
import {
|
|
4
4
|
Application as FeathersApplication, Params as FeathersParams,
|
|
5
|
-
HookContext, ServiceMethods, ServiceInterface
|
|
5
|
+
HookContext, ServiceMethods, ServiceInterface, RouteLookup
|
|
6
6
|
} from '@feathersjs/feathers';
|
|
7
7
|
|
|
8
8
|
interface ExpressUseHandler<T, Services> {
|
|
@@ -24,37 +24,40 @@ export interface ExpressOverrides<Services> {
|
|
|
24
24
|
listen(port: number|string|any, callback?: () => void): Promise<http.Server>;
|
|
25
25
|
listen(callback?: () => void): Promise<http.Server>;
|
|
26
26
|
use: ExpressUseHandler<this, Services>;
|
|
27
|
+
server: http.Server;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
export type Application<Services = any, Settings = any> =
|
|
30
|
-
Omit<Express, 'listen'|'use'> &
|
|
31
|
+
Omit<Express, 'listen'|'use'|'get'|'set'> &
|
|
31
32
|
FeathersApplication<Services, Settings> &
|
|
32
33
|
ExpressOverrides<Services>;
|
|
33
34
|
|
|
34
35
|
declare module '@feathersjs/feathers/lib/declarations' {
|
|
35
36
|
interface ServiceOptions {
|
|
36
|
-
|
|
37
|
-
before
|
|
38
|
-
after
|
|
39
|
-
|
|
37
|
+
express?: {
|
|
38
|
+
before?: express.RequestHandler[];
|
|
39
|
+
after?: express.RequestHandler[];
|
|
40
|
+
composed?: express.RequestHandler;
|
|
41
|
+
};
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
declare module 'express-serve-static-core' {
|
|
44
46
|
interface Request {
|
|
45
|
-
|
|
47
|
+
feathers?: Partial<FeathersParams>;
|
|
48
|
+
lookup?: RouteLookup;
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
interface Response {
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
data?: any;
|
|
53
|
+
hook?: HookContext;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
interface IRouterMatcher<T> {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
// eslint-disable-next-line
|
|
58
|
+
<P extends Params = ParamsDictionary, ResBody = any, ReqBody = any>(
|
|
59
|
+
path: PathParams,
|
|
60
|
+
...handlers: (RequestHandler<P, ResBody, ReqBody> | Partial<ServiceMethods> | Application)[]
|
|
61
|
+
): T;
|
|
59
62
|
}
|
|
60
63
|
}
|
package/src/handlers.ts
CHANGED
|
@@ -18,10 +18,10 @@ export function notFound ({ verbose = false } = {}): RequestHandler {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export type ErrorHandlerOptions = {
|
|
21
|
-
public?: string
|
|
22
|
-
logger?: boolean|{ error?: (msg: any) => void, info?: (msg: any) => void }
|
|
23
|
-
html?: any
|
|
24
|
-
json?: any
|
|
21
|
+
public?: string;
|
|
22
|
+
logger?: boolean|{ error?: (msg: any) => void, info?: (msg: any) => void };
|
|
23
|
+
html?: any;
|
|
24
|
+
json?: any;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export function errorHandler (_options: ErrorHandlerOptions = {}): ErrorRequestHandler {
|
package/src/index.ts
CHANGED
|
@@ -1,23 +1,16 @@
|
|
|
1
|
-
import express, {
|
|
2
|
-
|
|
3
|
-
} from '
|
|
4
|
-
import {
|
|
5
|
-
Application as FeathersApplication, defaultServiceMethods
|
|
6
|
-
} from '@feathersjs/feathers';
|
|
1
|
+
import express, { Express } from 'express';
|
|
2
|
+
import { Application as FeathersApplication, defaultServiceMethods } from '@feathersjs/feathers';
|
|
3
|
+
import { routing } from '@feathersjs/transport-commons';
|
|
7
4
|
import { createDebug } from '@feathersjs/commons';
|
|
8
5
|
|
|
9
6
|
import { Application } from './declarations';
|
|
10
|
-
import { errorHandler, notFound } from './handlers';
|
|
11
|
-
import { parseAuthentication, authenticate } from './authentication';
|
|
12
7
|
|
|
13
|
-
export {
|
|
14
|
-
_static as serveStatic, _static as static, json, raw, text,
|
|
15
|
-
urlencoded, query, errorHandler, notFound, express as original,
|
|
16
|
-
authenticate, parseAuthentication
|
|
17
|
-
};
|
|
8
|
+
export { default as original, static, static as serveStatic, json, raw, text, urlencoded, query } from 'express';
|
|
18
9
|
|
|
19
|
-
export * from './
|
|
10
|
+
export * from './authentication';
|
|
20
11
|
export * from './declarations';
|
|
12
|
+
export * from './handlers';
|
|
13
|
+
export * from './rest';
|
|
21
14
|
|
|
22
15
|
const debug = createDebug('@feathersjs/express');
|
|
23
16
|
|
|
@@ -30,10 +23,12 @@ export default function feathersExpress<S = any, C = any> (feathersApp?: Feather
|
|
|
30
23
|
throw new Error('@feathersjs/express requires a valid Feathers application instance');
|
|
31
24
|
}
|
|
32
25
|
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
26
|
+
const app = expressApp as any as Application<S, C>;
|
|
27
|
+
const { use: expressUse, listen: expressListen } = expressApp as any;
|
|
28
|
+
const { use: feathersUse, teardown: feathersTeardown } = feathersApp;
|
|
29
|
+
|
|
30
|
+
Object.assign(app, {
|
|
31
|
+
use (location: string & keyof S, ...rest: any[]) {
|
|
37
32
|
let service: any;
|
|
38
33
|
let options = {};
|
|
39
34
|
|
|
@@ -60,46 +55,63 @@ export default function feathersExpress<S = any, C = any> (feathersApp?: Feather
|
|
|
60
55
|
// Check for service (any object with at least one service method)
|
|
61
56
|
if (hasMethod(['handle', 'set']) || !hasMethod(defaultServiceMethods)) {
|
|
62
57
|
debug('Passing app.use call to Express app');
|
|
63
|
-
return
|
|
58
|
+
return expressUse.call(this, location, ...rest);
|
|
64
59
|
}
|
|
65
60
|
|
|
66
61
|
debug('Registering service with middleware', middleware);
|
|
67
62
|
// Since this is a service, call Feathers `.use`
|
|
68
|
-
|
|
63
|
+
feathersUse.call(this, location, service, {
|
|
69
64
|
...options,
|
|
70
|
-
middleware
|
|
65
|
+
express: middleware
|
|
71
66
|
});
|
|
72
67
|
|
|
73
68
|
return this;
|
|
74
69
|
},
|
|
75
70
|
|
|
76
71
|
async listen (...args: any[]) {
|
|
77
|
-
const server =
|
|
72
|
+
const server = expressListen.call(this, ...args);
|
|
78
73
|
|
|
74
|
+
this.server = server;
|
|
79
75
|
await this.setup(server);
|
|
80
76
|
debug('Feathers application listening');
|
|
81
77
|
|
|
82
78
|
return server;
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
async teardown (server?: any) {
|
|
82
|
+
return feathersTeardown.call(this, server).then(() =>
|
|
83
|
+
new Promise((resolve, reject) => this.server.close(e => e ? reject(e) : resolve(this)))
|
|
84
|
+
);
|
|
83
85
|
}
|
|
84
|
-
};
|
|
86
|
+
} as Application<S, C>);
|
|
85
87
|
|
|
86
|
-
const
|
|
88
|
+
const appDescriptors = {
|
|
89
|
+
...Object.getOwnPropertyDescriptors(Object.getPrototypeOf(app)),
|
|
90
|
+
...Object.getOwnPropertyDescriptors(app)
|
|
91
|
+
};
|
|
92
|
+
const newDescriptors = {
|
|
87
93
|
...Object.getOwnPropertyDescriptors(Object.getPrototypeOf(feathersApp)),
|
|
88
94
|
...Object.getOwnPropertyDescriptors(feathersApp)
|
|
89
95
|
};
|
|
90
96
|
|
|
91
97
|
// Copy all non-existing properties (including non-enumerables)
|
|
92
98
|
// that don't already exist on the Express app
|
|
93
|
-
Object.keys(
|
|
94
|
-
const
|
|
95
|
-
const
|
|
99
|
+
Object.keys(newDescriptors).forEach(prop => {
|
|
100
|
+
const appProp = appDescriptors[prop];
|
|
101
|
+
const newProp = newDescriptors[prop];
|
|
96
102
|
|
|
97
|
-
if (
|
|
98
|
-
Object.defineProperty(expressApp, prop,
|
|
103
|
+
if (appProp === undefined && newProp !== undefined) {
|
|
104
|
+
Object.defineProperty(expressApp, prop, newProp);
|
|
99
105
|
}
|
|
100
106
|
});
|
|
101
107
|
|
|
102
|
-
|
|
108
|
+
app.configure(routing() as any);
|
|
109
|
+
app.use((req, _res, next) => {
|
|
110
|
+
req.feathers = { ...req.feathers, provider: 'rest' };
|
|
111
|
+
return next();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return app;
|
|
103
115
|
}
|
|
104
116
|
|
|
105
117
|
if (typeof module !== 'undefined') {
|
package/src/rest.ts
CHANGED
|
@@ -1,119 +1,110 @@
|
|
|
1
|
+
import { Request, Response, RequestHandler, Router } from 'express';
|
|
1
2
|
import { MethodNotAllowed } from '@feathersjs/errors';
|
|
2
3
|
import { createDebug } from '@feathersjs/commons';
|
|
3
4
|
import { http } from '@feathersjs/transport-commons';
|
|
4
|
-
import {
|
|
5
|
-
import { Request, Response, NextFunction, RequestHandler, Router } from 'express';
|
|
5
|
+
import { createContext, defaultServiceMethods, getServiceOptions } from '@feathersjs/feathers';
|
|
6
6
|
|
|
7
|
-
import { parseAuthentication } from './authentication';
|
|
7
|
+
import { AuthenticationSettings, parseAuthentication } from './authentication';
|
|
8
|
+
import { Application } from './declarations';
|
|
8
9
|
|
|
9
10
|
const debug = createDebug('@feathersjs/express/rest');
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
const toHandler = (func: (req: Request, res: Response, next: () => void) => Promise<void>): RequestHandler => {
|
|
13
|
+
return (req, res, next) => func(req, res, next).catch(error => next(error));
|
|
14
|
+
};
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
req
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
headers: req.headers
|
|
18
|
-
};
|
|
19
|
-
next();
|
|
20
|
-
}
|
|
16
|
+
const serviceMiddleware = (): RequestHandler => {
|
|
17
|
+
return toHandler(async (req, res, next) => {
|
|
18
|
+
const { query, headers, path, body: data, method: httpMethod } = req;
|
|
19
|
+
const methodOverride = req.headers[http.METHOD_HEADER] as string | undefined;
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
21
|
+
const { service, params: { __id: id = null, ...route } = {} } = req.lookup!;
|
|
22
|
+
const method = http.getServiceMethod(httpMethod, id, methodOverride);
|
|
23
|
+
const { methods } = getServiceOptions(service);
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
debug(`Found service for path ${path}, attempting to run '${method}' service method`);
|
|
26
|
+
|
|
27
|
+
if (!methods.includes(method) || defaultServiceMethods.includes(methodOverride)) {
|
|
28
|
+
const error = new MethodNotAllowed(`Method \`${method}\` is not supported by this endpoint.`);
|
|
29
|
+
res.statusCode = error.code;
|
|
30
|
+
throw error;
|
|
30
31
|
}
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
32
|
|
|
33
|
+
const createArguments = http.argumentsFor[method as 'get'] || http.argumentsFor.default;
|
|
34
|
+
const params = { query, headers, route, ...req.feathers };
|
|
35
|
+
const args = createArguments({ id, data, params });
|
|
36
|
+
const contextBase = createContext(service, method, { http: {} });
|
|
37
|
+
res.hook = contextBase;
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
debug(`Running service middleware for '${req.url}'`);
|
|
39
|
+
const context = await (service as any)[method](...args, contextBase);
|
|
40
|
+
res.hook = context;
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
const response = http.getResponse(context);
|
|
43
|
+
res.statusCode = response.status;
|
|
44
|
+
res.set(response.headers);
|
|
45
|
+
res.data = response.body;
|
|
46
|
+
|
|
47
|
+
return next();
|
|
48
|
+
});
|
|
49
|
+
};
|
|
45
50
|
|
|
46
|
-
|
|
47
|
-
|
|
51
|
+
const servicesMiddleware = (): RequestHandler => {
|
|
52
|
+
return toHandler(async (req, res, next) => {
|
|
53
|
+
const app = req.app as any as Application;
|
|
54
|
+
const lookup = app.lookup(req.path);
|
|
48
55
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
next(error);
|
|
56
|
+
if (!lookup) {
|
|
57
|
+
return next();
|
|
52
58
|
}
|
|
53
|
-
}
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const method = methodOverride ? methodOverride : methodName
|
|
60
|
-
const { methods } = getServiceOptions(service);
|
|
60
|
+
req.lookup = lookup;
|
|
61
|
+
|
|
62
|
+
const options = getServiceOptions(lookup.service);
|
|
63
|
+
const middleware = options.express!.composed!;
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
return middleware(req, res, next);
|
|
66
|
+
});
|
|
67
|
+
};
|
|
64
68
|
|
|
65
|
-
|
|
69
|
+
export const formatter: RequestHandler = (_req, res, next) => {
|
|
70
|
+
if (res.data === undefined) {
|
|
71
|
+
return next();
|
|
66
72
|
}
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
res.format({
|
|
75
|
+
'application/json' () {
|
|
76
|
+
res.json(res.data);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export type RestOptions = {
|
|
82
|
+
formatter?: RequestHandler;
|
|
83
|
+
authentication?: AuthenticationSettings;
|
|
84
|
+
};
|
|
70
85
|
|
|
71
|
-
|
|
86
|
+
export const rest = (options?: RestOptions | RequestHandler) => {
|
|
87
|
+
options = typeof options === 'function' ? { formatter: options } : options || {};
|
|
72
88
|
|
|
73
|
-
|
|
74
|
-
|
|
89
|
+
const formatterMiddleware = options.formatter || formatter;
|
|
90
|
+
const authenticationOptions = options.authentication;
|
|
75
91
|
|
|
76
|
-
|
|
77
|
-
return function (this: any, app: any) {
|
|
92
|
+
return (app: Application) => {
|
|
78
93
|
if (typeof app.route !== 'function') {
|
|
79
94
|
throw new Error('@feathersjs/express/rest needs an Express compatible app.');
|
|
80
95
|
}
|
|
81
96
|
|
|
82
|
-
app.use(
|
|
83
|
-
app.use(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const baseUri = `/${path}`;
|
|
95
|
-
const find = serviceMethodHandler(service, 'find', http.argumentsFor.find);
|
|
96
|
-
const get = serviceMethodHandler(service, 'get', http.argumentsFor.get);
|
|
97
|
-
const create = serviceMethodHandler(service, 'create', http.argumentsFor.create, http.METHOD_HEADER);
|
|
98
|
-
const update = serviceMethodHandler(service, 'update', http.argumentsFor.update);
|
|
99
|
-
const patch = serviceMethodHandler(service, 'patch', http.argumentsFor.patch);
|
|
100
|
-
const remove = serviceMethodHandler(service, 'remove', http.argumentsFor.remove);
|
|
101
|
-
|
|
102
|
-
debug(`Adding REST provider for service \`${path}\` at base route \`${baseUri}\``);
|
|
103
|
-
|
|
104
|
-
const idRoute = '/:__feathersId';
|
|
105
|
-
const serviceRouter = Router({ mergeParams: true })
|
|
106
|
-
.get('/', find)
|
|
107
|
-
.post('/', create)
|
|
108
|
-
.get(idRoute, get)
|
|
109
|
-
.put('/', update)
|
|
110
|
-
.put(idRoute, update)
|
|
111
|
-
.patch('/', patch)
|
|
112
|
-
.patch(idRoute, patch)
|
|
113
|
-
.delete('/', remove)
|
|
114
|
-
.delete(idRoute, remove);
|
|
115
|
-
|
|
116
|
-
app.use(baseUri, ...before, serviceRouter, ...after);
|
|
97
|
+
app.use(parseAuthentication(authenticationOptions));
|
|
98
|
+
app.use(servicesMiddleware());
|
|
99
|
+
|
|
100
|
+
app.mixins.push((_service, _path, options) => {
|
|
101
|
+
const { express: { before = [], after = [] } = {} } = options;
|
|
102
|
+
|
|
103
|
+
const middlewares = [].concat(before, serviceMiddleware(), after, formatterMiddleware);
|
|
104
|
+
const middleware = Router().use(middlewares);
|
|
105
|
+
|
|
106
|
+
options.express ||= {};
|
|
107
|
+
options.express.composed = middleware;
|
|
117
108
|
});
|
|
118
109
|
};
|
|
119
110
|
}
|