@feathersjs/transport-commons 5.0.0-pre.1 → 5.0.0-pre.15

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/LICENSE +1 -1
  3. package/README.md +1 -1
  4. package/client.d.ts +1 -0
  5. package/client.js +1 -0
  6. package/lib/channels/channel/base.js +1 -1
  7. package/lib/channels/channel/base.js.map +1 -1
  8. package/lib/channels/channel/combined.js +1 -2
  9. package/lib/channels/channel/combined.js.map +1 -1
  10. package/lib/channels/index.d.ts +14 -12
  11. package/lib/channels/index.js +9 -11
  12. package/lib/channels/index.js.map +1 -1
  13. package/lib/channels/mixins.d.ts +2 -2
  14. package/lib/channels/mixins.js +5 -7
  15. package/lib/channels/mixins.js.map +1 -1
  16. package/lib/client.d.ts +11 -9
  17. package/lib/client.js +11 -6
  18. package/lib/client.js.map +1 -1
  19. package/lib/http.d.ts +28 -0
  20. package/lib/http.js +62 -0
  21. package/lib/http.js.map +1 -0
  22. package/lib/index.d.ts +1 -0
  23. package/lib/index.js +21 -1
  24. package/lib/index.js.map +1 -1
  25. package/lib/routing/index.d.ts +21 -0
  26. package/lib/routing/index.js +39 -0
  27. package/lib/routing/index.js.map +1 -0
  28. package/lib/routing/router.d.ts +27 -0
  29. package/lib/routing/router.js +78 -0
  30. package/lib/routing/router.js.map +1 -0
  31. package/lib/socket/index.js +19 -26
  32. package/lib/socket/index.js.map +1 -1
  33. package/lib/socket/utils.d.ts +2 -1
  34. package/lib/socket/utils.js +25 -30
  35. package/lib/socket/utils.js.map +1 -1
  36. package/package.json +13 -15
  37. package/src/channels/channel/base.ts +1 -1
  38. package/src/channels/channel/combined.ts +1 -2
  39. package/src/channels/index.ts +21 -19
  40. package/src/channels/mixins.ts +7 -6
  41. package/src/client.ts +27 -16
  42. package/src/http.ts +76 -0
  43. package/src/index.ts +1 -0
  44. package/src/routing/index.ts +50 -0
  45. package/src/routing/router.ts +98 -0
  46. package/src/socket/index.ts +19 -21
  47. package/src/socket/utils.ts +27 -31
  48. package/lib/routing.d.ts +0 -10
  49. package/lib/routing.js +0 -37
  50. package/lib/routing.js.map +0 -1
  51. package/src/routing.ts +0 -42
package/src/client.ts CHANGED
@@ -1,8 +1,8 @@
1
- import Debug from 'debug';
2
1
  import { convert } from '@feathersjs/errors';
3
- import { Params } from '@feathersjs/feathers';
2
+ import { createDebug } from '@feathersjs/commons';
3
+ import { Id, NullableId, Params, ServiceInterface } from '@feathersjs/feathers';
4
4
 
5
- const debug = Debug('@feathersjs/transport-commons/client');
5
+ const debug = createDebug('@feathersjs/transport-commons/client');
6
6
 
7
7
  const namespacedEmitterMethods = [
8
8
  'addListener',
@@ -59,7 +59,9 @@ interface ServiceOptions {
59
59
  events?: string[];
60
60
  }
61
61
 
62
- export class Service {
62
+ export type SocketService<T = any, D = Partial<any>> = Service<T, D>;
63
+
64
+ export class Service<T = any, D = Partial<T>> implements ServiceInterface<T, D> {
63
65
  events: string[];
64
66
  path: string;
65
67
  connection: any;
@@ -74,8 +76,8 @@ export class Service {
74
76
  addEmitterMethods(this);
75
77
  }
76
78
 
77
- send (method: string, ...args: any[]) {
78
- return new Promise((resolve, reject) => {
79
+ send<X = any> (method: string, ...args: any[]) {
80
+ return new Promise<X>((resolve, reject) => {
79
81
  args.unshift(method, this.path);
80
82
  args.push(function (error: any, data: any) {
81
83
  return error ? reject(convert(error)) : resolve(data);
@@ -87,28 +89,37 @@ export class Service {
87
89
  });
88
90
  }
89
91
 
92
+ methods (this: any, ...names: string[]) {
93
+ names.forEach(name => {
94
+ this[name] = function (data: any, params: Params = {}) {
95
+ return this.send(name, data, params.query || {});
96
+ }
97
+ });
98
+ return this;
99
+ }
100
+
90
101
  find (params: Params = {}) {
91
- return this.send('find', params.query || {});
102
+ return this.send<T|T[]>('find', params.query || {});
92
103
  }
93
104
 
94
- get (id: number | string, params: Params = {}) {
95
- return this.send('get', id, params.query || {});
105
+ get (id: Id, params: Params = {}) {
106
+ return this.send<T>('get', id, params.query || {});
96
107
  }
97
108
 
98
109
  create (data: any, params: Params = {}) {
99
- return this.send('create', data, params.query || {});
110
+ return this.send<T>('create', data, params.query || {});
100
111
  }
101
112
 
102
- update (id: number | string, data: any, params: Params = {}) {
103
- return this.send('update', id, data, params.query || {});
113
+ update (id: Id, data: any, params: Params = {}) {
114
+ return this.send<T> ('update', id, data, params.query || {});
104
115
  }
105
116
 
106
- patch (id: number | string, data: any, params: Params = {}) {
107
- return this.send('patch', id, data, params.query || {});
117
+ patch (id: NullableId, data: any, params: Params = {}) {
118
+ return this.send<T|T[]> ('patch', id, data, params.query || {});
108
119
  }
109
120
 
110
- remove (id: number | string, params: Params = {}) {
111
- return this.send('remove', id, params.query || {});
121
+ remove (id: NullableId, params: Params = {}) {
122
+ return this.send<T|T[]> ('remove', id, params.query || {});
112
123
  }
113
124
 
114
125
  // `off` is actually not part of the Node event emitter spec
package/src/http.ts ADDED
@@ -0,0 +1,76 @@
1
+ import { MethodNotAllowed } from '@feathersjs/errors/lib';
2
+ import { HookContext, NullableId, Params } from '@feathersjs/feathers';
3
+
4
+ export const METHOD_HEADER = 'x-service-method';
5
+
6
+ export interface ServiceParams {
7
+ id: NullableId,
8
+ data: any,
9
+ params: Params
10
+ }
11
+
12
+ export const statusCodes = {
13
+ created: 201,
14
+ noContent: 204,
15
+ methodNotAllowed: 405,
16
+ success: 200
17
+ };
18
+
19
+ export const knownMethods: { [key: string]: string } = {
20
+ post: 'create',
21
+ patch: 'patch',
22
+ put: 'update',
23
+ delete: 'remove'
24
+ };
25
+
26
+ export function getServiceMethod (_httpMethod: string, id: unknown, headerOverride?: string) {
27
+ const httpMethod = _httpMethod.toLowerCase();
28
+
29
+ if (httpMethod === 'post' && headerOverride) {
30
+ return headerOverride;
31
+ }
32
+
33
+ const mappedMethod = knownMethods[httpMethod];
34
+
35
+ if (mappedMethod) {
36
+ return mappedMethod;
37
+ }
38
+
39
+ if (httpMethod === 'get') {
40
+ return id === null ? 'find' : 'get';
41
+ }
42
+
43
+ throw new MethodNotAllowed(`Method ${_httpMethod} not allowed`);
44
+ }
45
+
46
+ export const argumentsFor = {
47
+ get: ({ id, params }: ServiceParams) => [ id, params ],
48
+ find: ({ params }: ServiceParams) => [ params ],
49
+ create: ({ data, params }: ServiceParams) => [ data, params ],
50
+ update: ({ id, data, params }: ServiceParams) => [ id, data, params ],
51
+ patch: ({ id, data, params }: ServiceParams) => [ id, data, params ],
52
+ remove: ({ id, params }: ServiceParams) => [ id, params ],
53
+ default: ({ data, params }: ServiceParams) => [ data, params ]
54
+ }
55
+
56
+ export function getData (context: HookContext) {
57
+ return context.dispatch !== undefined
58
+ ? context.dispatch
59
+ : context.result;
60
+ }
61
+
62
+ export function getStatusCode (context: HookContext, data?: any) {
63
+ if (context.http?.statusCode) {
64
+ return context.http.statusCode;
65
+ }
66
+
67
+ if (context.method === 'create') {
68
+ return statusCodes.created;
69
+ }
70
+
71
+ if (!data) {
72
+ return statusCodes.noContent;
73
+ }
74
+
75
+ return statusCodes.success;
76
+ }
package/src/index.ts CHANGED
@@ -2,4 +2,5 @@ import { socket } from './socket';
2
2
  import { routing } from './routing';
3
3
  import { channels } from './channels';
4
4
 
5
+ export * as http from './http';
5
6
  export { socket, routing, channels };
@@ -0,0 +1,50 @@
1
+ import { Application, Service, ServiceOptions } from '@feathersjs/feathers';
2
+ import { Router } from './router';
3
+
4
+ declare module '@feathersjs/feathers/lib/declarations' {
5
+ interface RouteLookup {
6
+ service: Service,
7
+ params: { [key: string]: any }
8
+ }
9
+
10
+ interface Application<Services, Settings> { // eslint-disable-line
11
+ routes: Router<{
12
+ service: Service,
13
+ params?: { [key: string]: any }
14
+ }>;
15
+ lookup (path: string): RouteLookup;
16
+ }
17
+ }
18
+
19
+ export * from './router';
20
+
21
+ const lookup = function (this: Application, path: string) {
22
+ const result = this.routes.lookup(path);
23
+
24
+ if (result === null) {
25
+ return null;
26
+ }
27
+
28
+ const { params: colonParams, data: { service, params: dataParams } } = result;
29
+
30
+ const params = dataParams ? { ...dataParams, ...colonParams } : colonParams;
31
+
32
+ return { service, params };
33
+ };
34
+
35
+ export const routing = () => (app: Application) => {
36
+ if (typeof app.lookup === 'function') {
37
+ return;
38
+ }
39
+
40
+ app.routes = new Router();
41
+ app.lookup = lookup;
42
+
43
+ // Add a mixin that registers a service on the router
44
+ app.mixins.push((service: Service, path: string, options: ServiceOptions) => {
45
+ const { routeParams: params = {} } = options;
46
+
47
+ app.routes.insert(path, { service, params });
48
+ app.routes.insert(`${path}/:__id`, { service, params });
49
+ });
50
+ };
@@ -0,0 +1,98 @@
1
+ import { stripSlashes } from '@feathersjs/commons';
2
+
3
+ export interface LookupData {
4
+ params: { [key: string]: string };
5
+ }
6
+
7
+ export interface LookupResult<T> extends LookupData {
8
+ data?: T;
9
+ }
10
+
11
+ export class RouteNode<T = any> {
12
+ data?: T;
13
+ children: { [key: string]: RouteNode } = {};
14
+ placeholders: RouteNode[] = [];
15
+
16
+ constructor (public name: string, public depth: number) {}
17
+
18
+ insert (path: string[], data: T): RouteNode<T> {
19
+ if (this.depth === path.length) {
20
+ if (this.data !== undefined) {
21
+ throw new Error(`Path ${path.join('/')} already exists`);
22
+ }
23
+
24
+ this.data = data;
25
+ return this;
26
+ }
27
+
28
+ const current = path[this.depth];
29
+ const nextDepth = this.depth + 1;
30
+
31
+ if (current.startsWith(':')) {
32
+ // Insert a placeholder node like /messages/:id
33
+ const placeholderName = current.substring(1);
34
+ let placeholder = this.placeholders.find(p => p.name === placeholderName);
35
+
36
+ if (!placeholder) {
37
+ placeholder = new RouteNode(placeholderName, nextDepth);
38
+ this.placeholders.push(placeholder);
39
+ }
40
+
41
+ return placeholder.insert(path, data);
42
+ }
43
+
44
+ const child = this.children[current] || new RouteNode(current, nextDepth);
45
+
46
+ this.children[current] = child;
47
+
48
+ return child.insert(path, data);
49
+ }
50
+
51
+ lookup (path: string[], info: LookupData): LookupResult<T>|null {
52
+ if (path.length === this.depth) {
53
+ return this.data === undefined ? null : {
54
+ ...info,
55
+ data: this.data
56
+ }
57
+ }
58
+
59
+ const current = path[this.depth];
60
+ const child = this.children[current];
61
+
62
+ if (child) {
63
+ return child.lookup(path, info);
64
+ }
65
+
66
+ // This will return the first placeholder that matches early
67
+ for(const placeholder of this.placeholders) {
68
+ const result = placeholder.lookup(path, info);
69
+
70
+ if (result !== null) {
71
+ result.params[placeholder.name] = current;
72
+ return result;
73
+ }
74
+ }
75
+
76
+ return null;
77
+ }
78
+ }
79
+
80
+ export class Router<T = any> {
81
+ constructor (public root: RouteNode<T> = new RouteNode<T>('', 0)) {}
82
+
83
+ getPath (path: string) {
84
+ return stripSlashes(path).split('/');
85
+ }
86
+
87
+ insert (path: string, data: T) {
88
+ return this.root.insert(this.getPath(path), data);
89
+ }
90
+
91
+ lookup (path: string) {
92
+ if (typeof path !== 'string') {
93
+ return null;
94
+ }
95
+
96
+ return this.root.lookup(this.getPath(path), { params: {} });
97
+ }
98
+ }
@@ -1,11 +1,11 @@
1
- import { Application, Params } from '@feathersjs/feathers';
2
- import Debug from 'debug';
1
+ import { Application, getServiceOptions, Params } from '@feathersjs/feathers';
2
+ import { createDebug } from '@feathersjs/commons';
3
3
  import { channels } from '../channels';
4
4
  import { routing } from '../routing';
5
5
  import { getDispatcher, runMethod } from './utils';
6
6
  import { RealTimeConnection } from '../channels/channel/base';
7
7
 
8
- const debug = Debug('@feathersjs/transport-commons');
8
+ const debug = createDebug('@feathersjs/transport-commons');
9
9
 
10
10
  export interface SocketOptions {
11
11
  done: Promise<any>;
@@ -45,28 +45,26 @@ export function socket ({ done, emit, socketMap, socketKey, getParams }: SocketO
45
45
 
46
46
  // `socket.emit('methodName', 'serviceName', ...args)` handlers
47
47
  done.then(provider => provider.on('connection', (connection: any) => {
48
- for (const method of app.methods) {
49
- connection.on(method, (...args: any[]) => {
50
- const path = args.shift();
48
+ const methodHandlers = Object.keys(app.services).reduce((result, name) => {
49
+ const { methods } = getServiceOptions(app.service(name));
51
50
 
52
- debug(`Got '${method}' call for service '${path}'`);
53
- runMethod(app, getParams(connection), path, method, args);
51
+ methods.forEach(method => {
52
+ if (!result[method]) {
53
+ result[method] = (...args: any[]) => {
54
+ const path = args.shift();
55
+
56
+ debug(`Got '${method}' call for service '${path}'`);
57
+ runMethod(app, getParams(connection), path, method, args);
58
+ }
59
+ }
54
60
  });
55
- }
56
61
 
57
- connection.on('authenticate', (...args: any[]) => {
58
- if (app.get('defaultAuthentication')) {
59
- debug('Got legacy authenticate event');
60
- runMethod(app, getParams(connection), app.get('defaultAuthentication'), 'create', args);
61
- }
62
- });
62
+ return result;
63
+ }, {} as any);
63
64
 
64
- connection.on('logout', (callback: any) => {
65
- if (app.get('defaultAuthentication')) {
66
- debug('Got legacy authenticate event');
67
- runMethod(app, getParams(connection), app.get('defaultAuthentication'), 'remove', [ null, {}, callback ]);
68
- }
69
- });
65
+ Object.keys(methodHandlers).forEach(key =>
66
+ connection.on(key, methodHandlers[key])
67
+ );
70
68
  }));
71
69
  };
72
70
  }
@@ -1,17 +1,16 @@
1
- import Debug from 'debug';
1
+ import { HookContext, Application, createContext, getServiceOptions } from '@feathersjs/feathers';
2
+ import { NotFound, MethodNotAllowed, BadRequest } from '@feathersjs/errors';
3
+ import { createDebug } from '@feathersjs/commons';
2
4
  import isEqual from 'lodash/isEqual';
3
- import { NotFound, MethodNotAllowed } from '@feathersjs/errors';
4
- import { HookContext, Application } from '@feathersjs/feathers';
5
5
  import { CombinedChannel } from '../channels/channel/combined';
6
6
  import { RealTimeConnection } from '../channels/channel/base';
7
7
 
8
- const debug = Debug('@feathersjs/transport-commons');
8
+ const debug = createDebug('@feathersjs/transport-commons');
9
+
10
+ export const DEFAULT_PARAMS_POSITION = 1;
9
11
 
10
12
  export const paramsPositions: { [key: string]: number } = {
11
13
  find: 0,
12
- get: 1,
13
- remove: 1,
14
- create: 1,
15
14
  update: 2,
16
15
  patch: 2
17
16
  };
@@ -62,7 +61,7 @@ export function getDispatcher (emit: string, socketMap: WeakMap<RealTimeConnecti
62
61
  };
63
62
  }
64
63
 
65
- export function runMethod (app: Application, connection: RealTimeConnection, path: string, method: string, args: any[]) {
64
+ export async function runMethod (app: Application, connection: RealTimeConnection, path: string, method: string, args: any[]) {
66
65
  const trace = `method '${method}' on service '${path}'`;
67
66
  const methodArgs = args.slice(0);
68
67
  const callback = typeof methodArgs[methodArgs.length - 1] === 'function'
@@ -74,45 +73,42 @@ export function runMethod (app: Application, connection: RealTimeConnection, pat
74
73
  debug(`Error in ${trace}`, error);
75
74
  callback(normalizeError(error));
76
75
  };
77
- // A wrapper function that runs the method and returns a promise
78
- const _run = () => {
76
+
77
+ try {
79
78
  const lookup = app.lookup(path);
80
79
 
81
- // No valid service was found, return a 404
82
- // just like a REST route would
80
+ // No valid service was found throw a NotFound error
83
81
  if (lookup === null) {
84
- return Promise.reject(new NotFound(`Service '${path}' not found`));
82
+ throw new NotFound(`Service '${path}' not found`);
85
83
  }
86
84
 
87
85
  const { service, params: route = {} } = lookup;
86
+ const { methods } = getServiceOptions(service);
88
87
 
89
88
  // Only service methods are allowed
90
- // @ts-ignore
91
- if (paramsPositions[method] === undefined || typeof service[method] !== 'function') {
92
- return Promise.reject(new MethodNotAllowed(`Method '${method}' not allowed on service '${path}'`));
89
+ if (!methods.includes(method)) {
90
+ throw new MethodNotAllowed(`Method '${method}' not allowed on service '${path}'`);
93
91
  }
94
92
 
95
- const position = paramsPositions[method];
93
+ const position = paramsPositions[method] !== undefined ? paramsPositions[method] : DEFAULT_PARAMS_POSITION;
96
94
  const query = methodArgs[position] || {};
97
- // `params` have to be re-mapped to the query
98
- // and added with the route
95
+ // `params` have to be re-mapped to the query and added with the route
99
96
  const params = Object.assign({ query, route, connection }, connection);
100
97
 
98
+ // `params` is always the last parameter. Error if we got more arguments.
99
+ if (methodArgs.length > (position + 1)) {
100
+ throw new BadRequest(`Too many arguments for '${method}' method`);
101
+ }
102
+
101
103
  methodArgs[position] = params;
102
104
 
103
- // @ts-ignore
104
- return service[method](...methodArgs, true);
105
- };
105
+ const ctx = createContext(service, method);
106
+ const returnedCtx: HookContext = await (service as any)[method](...methodArgs, ctx);
107
+ const result = returnedCtx.dispatch || returnedCtx.result;
106
108
 
107
- try {
108
- // Run and map to the callback that is being called for Socket calls
109
- _run().then((hook: HookContext) => {
110
- const result = hook.dispatch || hook.result;
111
-
112
- debug(`Returned successfully ${trace}`, result);
113
- callback(null, result);
114
- }).catch((hook: HookContext) => handleError(hook.type === 'error' ? hook.error : hook));
115
- } catch (error) {
109
+ debug(`Returned successfully ${trace}`, result);
110
+ callback(null, result);
111
+ } catch (error: any) {
116
112
  handleError(error);
117
113
  }
118
114
  }
package/lib/routing.d.ts DELETED
@@ -1,10 +0,0 @@
1
- import { Application } from '@feathersjs/feathers';
2
- export declare const ROUTER: unique symbol;
3
- declare module '@feathersjs/feathers/lib/declarations' {
4
- interface Application<ServiceTypes> {
5
- lookup(path: string): {
6
- [key: string]: string;
7
- };
8
- }
9
- }
10
- export declare const routing: () => (app: Application) => void;
package/lib/routing.js DELETED
@@ -1,37 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.routing = exports.ROUTER = void 0;
7
- // @ts-ignore
8
- const radix_router_1 = __importDefault(require("radix-router"));
9
- const commons_1 = require("@feathersjs/commons");
10
- exports.ROUTER = Symbol('@feathersjs/transport-commons/router');
11
- const routing = () => (app) => {
12
- if (typeof app.lookup === 'function') {
13
- return;
14
- }
15
- const router = new radix_router_1.default();
16
- Object.assign(app, {
17
- [exports.ROUTER]: router,
18
- lookup(path) {
19
- if (!path) {
20
- return null;
21
- }
22
- return this[exports.ROUTER].lookup(commons_1.stripSlashes('' + path) || '/');
23
- }
24
- });
25
- // Add a mixin that registers a service on the router
26
- app.mixins.push((service, path) => {
27
- // @ts-ignore
28
- app[exports.ROUTER].insert({ path, service });
29
- // @ts-ignore
30
- app[exports.ROUTER].insert({
31
- path: `${path}/:__id`,
32
- service
33
- });
34
- });
35
- };
36
- exports.routing = routing;
37
- //# sourceMappingURL=routing.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"routing.js","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":";;;;;;AAAA,aAAa;AACb,gEAAkC;AAClC,iDAAmD;AAGtC,QAAA,MAAM,GAAG,MAAM,CAAC,sCAAsC,CAAC,CAAC;AAQ9D,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC,GAAgB,EAAE,EAAE;IAChD,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,UAAU,EAAE;QACpC,OAAO;KACR;IAED,MAAM,MAAM,GAAG,IAAI,sBAAM,EAAE,CAAC;IAE5B,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;QACjB,CAAC,cAAM,CAAC,EAAE,MAAM;QAChB,MAAM,CAAE,IAAY;YAClB,IAAI,CAAC,IAAI,EAAE;gBACT,OAAO,IAAI,CAAC;aACb;YAED,OAAO,IAAI,CAAC,cAAM,CAAC,CAAC,MAAM,CAAC,sBAAY,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAC7D,CAAC;KACF,CAAC,CAAC;IAEH,qDAAqD;IACrD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;QAChC,aAAa;QACb,GAAG,CAAC,cAAM,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACtC,aAAa;QACb,GAAG,CAAC,cAAM,CAAC,CAAC,MAAM,CAAC;YACjB,IAAI,EAAE,GAAG,IAAI,QAAQ;YACrB,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AA5BW,QAAA,OAAO,WA4BlB"}
package/src/routing.ts DELETED
@@ -1,42 +0,0 @@
1
- // @ts-ignore
2
- import Router from 'radix-router';
3
- import { stripSlashes } from '@feathersjs/commons';
4
- import { Application } from '@feathersjs/feathers';
5
-
6
- export const ROUTER = Symbol('@feathersjs/transport-commons/router');
7
-
8
- declare module '@feathersjs/feathers/lib/declarations' {
9
- interface Application<ServiceTypes> { // eslint-disable-line
10
- lookup (path: string): { [key: string]: string };
11
- }
12
- }
13
-
14
- export const routing = () => (app: Application) => {
15
- if (typeof app.lookup === 'function') {
16
- return;
17
- }
18
-
19
- const router = new Router();
20
-
21
- Object.assign(app, {
22
- [ROUTER]: router,
23
- lookup (path: string): { [key: string]: string } {
24
- if (!path) {
25
- return null;
26
- }
27
-
28
- return this[ROUTER].lookup(stripSlashes('' + path) || '/');
29
- }
30
- });
31
-
32
- // Add a mixin that registers a service on the router
33
- app.mixins.push((service, path) => {
34
- // @ts-ignore
35
- app[ROUTER].insert({ path, service });
36
- // @ts-ignore
37
- app[ROUTER].insert({
38
- path: `${path}/:__id`,
39
- service
40
- });
41
- });
42
- };