UNPKG

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