1 | import { createSymbol, EventEmitter } from './dependencies';
|
2 | import { ServiceOptions } from './declarations';
|
3 |
|
4 | export const SERVICE = createSymbol('@feathersjs/service');
|
5 |
|
6 | export const defaultServiceArguments = {
|
7 | find: [ 'params' ],
|
8 | get: [ 'id', 'params' ],
|
9 | create: [ 'data', 'params' ],
|
10 | update: [ 'id', 'data', 'params' ],
|
11 | patch: [ 'id', 'data', 'params' ],
|
12 | remove: [ 'id', 'params' ]
|
13 | }
|
14 |
|
15 | export const defaultServiceMethods = Object.keys(defaultServiceArguments);
|
16 |
|
17 | export const defaultEventMap = {
|
18 | create: 'created',
|
19 | update: 'updated',
|
20 | patch: 'patched',
|
21 | remove: 'removed'
|
22 | }
|
23 |
|
24 | export const protectedMethods = Object.keys(Object.prototype)
|
25 | .concat(Object.keys(EventEmitter.prototype))
|
26 | .concat([
|
27 | 'all',
|
28 | 'before',
|
29 | 'after',
|
30 | 'error',
|
31 | 'hooks',
|
32 | 'setup',
|
33 | 'teardown',
|
34 | 'publish'
|
35 | ]);
|
36 |
|
37 | export function getHookMethods (service: any, options: ServiceOptions) {
|
38 | const { methods } = options;
|
39 |
|
40 | return defaultServiceMethods.filter(m =>
|
41 | typeof service[m] === 'function' && !methods.includes(m)
|
42 | ).concat(methods);
|
43 | }
|
44 |
|
45 | export function getServiceOptions (
|
46 | service: any, options: ServiceOptions = {}
|
47 | ): ServiceOptions {
|
48 | const existingOptions = service[SERVICE];
|
49 |
|
50 | if (existingOptions) {
|
51 | return existingOptions;
|
52 | }
|
53 |
|
54 | const {
|
55 | methods = defaultServiceMethods.filter(method =>
|
56 | typeof service[method] === 'function'
|
57 | ),
|
58 | events = service.events || []
|
59 | } = options;
|
60 | const {
|
61 | serviceEvents = Object.values(defaultEventMap).concat(events)
|
62 | } = options;
|
63 |
|
64 | return {
|
65 | ...options,
|
66 | events,
|
67 | methods,
|
68 | serviceEvents
|
69 | };
|
70 | }
|
71 |
|
72 | export function wrapService (
|
73 | location: string, service: any, options: ServiceOptions
|
74 | ) {
|
75 |
|
76 | if (service[SERVICE]) {
|
77 | return service;
|
78 | }
|
79 |
|
80 | const protoService = Object.create(service);
|
81 | const serviceOptions = getServiceOptions(service, options);
|
82 |
|
83 | if (Object.keys(serviceOptions.methods).length === 0 && typeof service.setup !== 'function') {
|
84 | throw new Error(`Invalid service object passed for path \`${location}\``);
|
85 | }
|
86 |
|
87 | Object.defineProperty(protoService, SERVICE, {
|
88 | value: serviceOptions
|
89 | });
|
90 |
|
91 | return protoService;
|
92 | }
|