@feathersjs/feathers 5.0.0-pre.2 → 5.0.0-pre.20

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.
@@ -0,0 +1,207 @@
1
+ import { HookFunction, RegularHookFunction, RegularHookMap } from '../declarations';
2
+ import { defaultServiceMethods } from '../service';
3
+
4
+ const runHook = <A, S> (hook: RegularHookFunction<A, S>, context: any, type?: string) => {
5
+ if (type) context.type = type;
6
+ return Promise.resolve(hook.call(context.self, context))
7
+ .then((res: any) => {
8
+ if (type) context.type = null;
9
+ if (res && res !== context) {
10
+ Object.assign(context, res);
11
+ }
12
+ });
13
+ };
14
+
15
+ export function fromBeforeHook<A, S> (hook: RegularHookFunction<A, S>): HookFunction<A, S> {
16
+ return (context, next) => {
17
+ return runHook(hook, context, 'before').then(next);
18
+ };
19
+ }
20
+
21
+ export function fromAfterHook<A, S> (hook: RegularHookFunction<A, S>): HookFunction<A, S> {
22
+ return (context, next) => {
23
+ return next().then(() => runHook(hook, context, 'after'));
24
+ }
25
+ }
26
+
27
+ export function fromErrorHook<A, S> (hook: RegularHookFunction<A, S>): HookFunction<A, S> {
28
+ return (context, next) => {
29
+ return next().catch((error: any) => {
30
+ if (context.error !== error || context.result !== undefined) {
31
+ (context as any).original = { ...context };
32
+ context.error = error;
33
+ delete context.result;
34
+ }
35
+
36
+ return runHook(hook, context, 'error').then(() => {
37
+ if (context.result === undefined && context.error !== undefined) {
38
+ throw context.error;
39
+ }
40
+ });
41
+ });
42
+ }
43
+ }
44
+
45
+ const RunHooks = <A, S> (hooks: RegularHookFunction<A, S>[]) => (context: any) => {
46
+ return hooks.reduce((promise, hook) => {
47
+ return promise.then(() => runHook(hook, context))
48
+ }, Promise.resolve(undefined));
49
+ };
50
+
51
+ export function fromBeforeHooks<A, S> (hooks: RegularHookFunction<A, S>[]) {
52
+ return fromBeforeHook(RunHooks(hooks));
53
+ }
54
+
55
+ export function fromAfterHooks<A, S> (hooks: RegularHookFunction<A, S>[]) {
56
+ return fromAfterHook(RunHooks(hooks));
57
+ }
58
+
59
+ export function fromErrorHooks<A, S> (hooks: RegularHookFunction<A, S>[]) {
60
+ return fromErrorHook(RunHooks(hooks));
61
+ }
62
+
63
+ export function collectRegularHooks (target: any, method: string) {
64
+ return target.__hooks.hooks[method] || [];
65
+ }
66
+
67
+ // Converts different hook registration formats into the
68
+ // same internal format
69
+ export function convertHookData (input: any) {
70
+ const result: { [ method: string ]: RegularHookFunction[] } = {};
71
+
72
+ if (Array.isArray(input)) {
73
+ result.all = input;
74
+ } else if (typeof input !== 'object') {
75
+ result.all = [ input ];
76
+ } else {
77
+ for (const key of Object.keys(input)) {
78
+ const value = input[key];
79
+ result[key] = Array.isArray(value) ? value : [ value ];
80
+ }
81
+ }
82
+
83
+ return result;
84
+ }
85
+
86
+ type RegularType = 'before' | 'after' | 'error';
87
+
88
+ type RegularMap = { [ type in RegularType ]: ReturnType< typeof convertHookData > };
89
+
90
+ type RegularAdapter = HookFunction & { hooks: RegularHookFunction[] };
91
+
92
+ type RegularStore = {
93
+ before: { [ method: string ]: RegularAdapter },
94
+ after: { [ method: string ]: RegularAdapter },
95
+ error: { [ method: string ]: RegularAdapter },
96
+ hooks: { [ method: string ]: HookFunction[] }
97
+ };
98
+
99
+ const types: RegularType[] = ['before', 'after', 'error'];
100
+
101
+ const isType = (value: any): value is RegularType => types.includes(value);
102
+
103
+ const wrappers = {
104
+ before: fromBeforeHooks,
105
+ after: fromAfterHooks,
106
+ error: fromErrorHooks
107
+ };
108
+
109
+ const createStore = (methods: string[]) => {
110
+ const store: RegularStore = {
111
+ before: {},
112
+ after: {},
113
+ error: {},
114
+ hooks: {}
115
+ };
116
+
117
+ for (const method of methods) {
118
+ store.hooks[method] = [];
119
+ }
120
+
121
+ return store;
122
+ };
123
+
124
+ const setStore = (object: any, store: RegularStore) => {
125
+ Object.defineProperty(object, '__hooks', {
126
+ configurable: true,
127
+ value: store,
128
+ writable: true
129
+ });
130
+ };
131
+
132
+ const getStore = (object: any): RegularStore => object.__hooks;
133
+
134
+ const createMap = (input: RegularHookMap<any, any>, methods: string[]) => {
135
+ const map = {} as RegularMap;
136
+
137
+ Object.keys(input).forEach((type) => {
138
+ if (!isType(type)) {
139
+ throw new Error(`'${type}' is not a valid hook type`);
140
+ }
141
+
142
+ const data = convertHookData(input[type]);
143
+
144
+ Object.keys(data).forEach((method) => {
145
+ if (method !== 'all' && !methods.includes(method)) {
146
+ throw new Error(`'${method}' is not a valid hook method`);
147
+ }
148
+ });
149
+
150
+ map[type] = data;
151
+ });
152
+
153
+ return map;
154
+ };
155
+
156
+ const createAdapter = (type: RegularType) => {
157
+ const hooks: RegularHookFunction[] = [];
158
+ const hook = wrappers[type](hooks);
159
+ const adapter = Object.assign(hook, { hooks });
160
+
161
+ return adapter;
162
+ };
163
+
164
+ const updateStore = (store: RegularStore, map: RegularMap) => {
165
+ Object.keys(store.hooks).forEach((method) => {
166
+ let adapted = false;
167
+
168
+ Object.keys(map).forEach((key) => {
169
+ const type = key as RegularType;
170
+ const allHooks = map[type].all || [];
171
+ const methodHooks = map[type][method] || [];
172
+
173
+ if (allHooks.length || methodHooks.length) {
174
+ const adapter = store[type][method] ||= (adapted = true, createAdapter(type));
175
+
176
+ adapter.hooks.push(...allHooks, ...methodHooks);
177
+ }
178
+ });
179
+
180
+ if (adapted) {
181
+ store.hooks[method] = [
182
+ store.error[method],
183
+ store.before[method],
184
+ store.after[method]
185
+ ].filter(hook => hook);
186
+ }
187
+ });
188
+ };
189
+
190
+ // Add `.hooks` functionality to an object
191
+ export function enableRegularHooks (
192
+ object: any,
193
+ methods: string[] = defaultServiceMethods
194
+ ) {
195
+ const store = createStore(methods);
196
+
197
+ setStore(object, store);
198
+
199
+ return function regularHooks (this: any, input: RegularHookMap<any, any>) {
200
+ const store = getStore(this);
201
+ const map = createMap(input, methods);
202
+
203
+ updateStore(store, map);
204
+
205
+ return this;
206
+ }
207
+ }
package/src/index.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { _ } from '@feathersjs/commons';
2
-
1
+ import { setDebug } from './dependencies';
3
2
  import version from './version';
4
3
  import { Feathers } from './application';
5
4
  import { Application } from './declarations';
@@ -8,10 +7,12 @@ export function feathers<T = any, S = any> () {
8
7
  return new Feathers<T, S>() as Application<T, S>;
9
8
  }
10
9
 
10
+ feathers.setDebug = setDebug;
11
+
11
12
  export { version, Feathers };
13
+ export * from './hooks/index';
12
14
  export * from './declarations';
13
15
  export * from './service';
14
- export * from './hooks';
15
16
 
16
17
  if (typeof module !== 'undefined') {
17
18
  module.exports = Object.assign(feathers, module.exports);
package/src/service.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { createSymbol } from '@feathersjs/commons';
2
-
1
+ import { createSymbol, EventEmitter } from './dependencies';
3
2
  import { ServiceOptions } from './declarations';
4
3
 
5
4
  export const SERVICE = createSymbol('@feathersjs/service');
@@ -22,9 +21,22 @@ export const defaultEventMap = {
22
21
  remove: 'removed'
23
22
  }
24
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
+
25
37
  export function getHookMethods (service: any, options: ServiceOptions) {
26
38
  const { methods } = options;
27
-
39
+
28
40
  return defaultServiceMethods.filter(m =>
29
41
  typeof service[m] === 'function' && !methods.includes(m)
30
42
  ).concat(methods);
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export default '5.0.0-pre.2';
1
+ export default '5.0.0-pre.20';
@@ -1,7 +0,0 @@
1
- import { LegacyHookFunction } from '../declarations';
2
- export declare function fromBeforeHook(hook: LegacyHookFunction): (context: any, next: any) => Promise<any>;
3
- export declare function fromAfterHook(hook: LegacyHookFunction): (context: any, next: any) => any;
4
- export declare function fromErrorHooks(hooks: LegacyHookFunction[]): (context: any, next: any) => any;
5
- export declare function collectLegacyHooks(target: any, method: string): any[];
6
- export declare function convertHookData(obj: any): any;
7
- export declare function enableLegacyHooks(obj: any, methods?: string[], types?: string[]): (this: any, allHooks: any) => any;
@@ -1,114 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.enableLegacyHooks = exports.convertHookData = exports.collectLegacyHooks = exports.fromErrorHooks = exports.fromAfterHook = exports.fromBeforeHook = void 0;
4
- const commons_1 = require("@feathersjs/commons");
5
- const { each } = commons_1._;
6
- function fromBeforeHook(hook) {
7
- return (context, next) => {
8
- context.type = 'before';
9
- return Promise.resolve(hook.call(context.self, context)).then(() => {
10
- context.type = null;
11
- return next();
12
- });
13
- };
14
- }
15
- exports.fromBeforeHook = fromBeforeHook;
16
- function fromAfterHook(hook) {
17
- return (context, next) => {
18
- return next().then(() => {
19
- context.type = 'after';
20
- return hook.call(context.self, context);
21
- }).then(() => {
22
- context.type = null;
23
- });
24
- };
25
- }
26
- exports.fromAfterHook = fromAfterHook;
27
- function fromErrorHooks(hooks) {
28
- return (context, next) => {
29
- return next().catch((error) => {
30
- let promise = Promise.resolve();
31
- context.original = Object.assign({}, context);
32
- context.error = error;
33
- context.type = 'error';
34
- delete context.result;
35
- for (const hook of hooks) {
36
- promise = promise.then(() => hook.call(context.self, context));
37
- }
38
- return promise.then(() => {
39
- context.type = null;
40
- if (context.result === undefined) {
41
- throw context.error;
42
- }
43
- });
44
- });
45
- };
46
- }
47
- exports.fromErrorHooks = fromErrorHooks;
48
- function collectLegacyHooks(target, method) {
49
- const { before: { [method]: before = [] }, after: { [method]: after = [] }, error: { [method]: error = [] } } = target.__hooks;
50
- const beforeHooks = before;
51
- const afterHooks = [...after].reverse();
52
- const errorHook = fromErrorHooks(error);
53
- return [errorHook, ...beforeHooks, ...afterHooks];
54
- }
55
- exports.collectLegacyHooks = collectLegacyHooks;
56
- // Converts different hook registration formats into the
57
- // same internal format
58
- function convertHookData(obj) {
59
- let hook = {};
60
- if (Array.isArray(obj)) {
61
- hook = { all: obj };
62
- }
63
- else if (typeof obj !== 'object') {
64
- hook = { all: [obj] };
65
- }
66
- else {
67
- each(obj, function (value, key) {
68
- hook[key] = !Array.isArray(value) ? [value] : value;
69
- });
70
- }
71
- return hook;
72
- }
73
- exports.convertHookData = convertHookData;
74
- // Add `.hooks` functionality to an object
75
- function enableLegacyHooks(obj, methods = ['find', 'get', 'create', 'update', 'patch', 'remove'], types = ['before', 'after', 'error']) {
76
- const hookData = {};
77
- types.forEach(type => {
78
- // Initialize properties where hook functions are stored
79
- hookData[type] = {};
80
- });
81
- // Add non-enumerable `__hooks` property to the object
82
- Object.defineProperty(obj, '__hooks', {
83
- configurable: true,
84
- value: hookData,
85
- writable: true
86
- });
87
- return function legacyHooks(allHooks) {
88
- each(allHooks, (current, type) => {
89
- if (!this.__hooks[type]) {
90
- throw new Error(`'${type}' is not a valid hook type`);
91
- }
92
- const hooks = convertHookData(current);
93
- each(hooks, (_value, method) => {
94
- if (method !== 'all' && methods.indexOf(method) === -1) {
95
- throw new Error(`'${method}' is not a valid hook method`);
96
- }
97
- });
98
- methods.forEach(method => {
99
- let currentHooks = [...(hooks.all || []), ...(hooks[method] || [])];
100
- this.__hooks[type][method] = this.__hooks[type][method] || [];
101
- if (type === 'before') {
102
- currentHooks = currentHooks.map(fromBeforeHook);
103
- }
104
- if (type === 'after') {
105
- currentHooks = currentHooks.map(fromAfterHook);
106
- }
107
- this.__hooks[type][method].push(...currentHooks);
108
- });
109
- });
110
- return this;
111
- };
112
- }
113
- exports.enableLegacyHooks = enableLegacyHooks;
114
- //# sourceMappingURL=legacy.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"legacy.js","sourceRoot":"","sources":["../../src/hooks/legacy.ts"],"names":[],"mappings":"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"}
@@ -1,138 +0,0 @@
1
- import { _ } from '@feathersjs/commons';
2
- import { LegacyHookFunction } from '../declarations';
3
-
4
- const { each } = _;
5
-
6
- export function fromBeforeHook (hook: LegacyHookFunction) {
7
- return (context: any, next: any) => {
8
- context.type = 'before';
9
-
10
- return Promise.resolve(hook.call(context.self, context)).then(() => {
11
- context.type = null;
12
- return next();
13
- });
14
- };
15
- }
16
-
17
- export function fromAfterHook (hook: LegacyHookFunction) {
18
- return (context: any, next: any) => {
19
- return next().then(() => {
20
- context.type = 'after';
21
- return hook.call(context.self, context)
22
- }).then(() => {
23
- context.type = null;
24
- });
25
- }
26
- }
27
-
28
- export function fromErrorHooks (hooks: LegacyHookFunction[]) {
29
- return (context: any, next: any) => {
30
- return next().catch((error: any) => {
31
- let promise: Promise<any> = Promise.resolve();
32
-
33
- context.original = { ...context };
34
- context.error = error;
35
- context.type = 'error';
36
-
37
- delete context.result;
38
-
39
- for (const hook of hooks) {
40
- promise = promise.then(() => hook.call(context.self, context))
41
- }
42
-
43
- return promise.then(() => {
44
- context.type = null;
45
-
46
- if (context.result === undefined) {
47
- throw context.error;
48
- }
49
- });
50
- });
51
- }
52
- }
53
-
54
- export function collectLegacyHooks (target: any, method: string) {
55
- const {
56
- before: { [method]: before = [] },
57
- after: { [method]: after = [] },
58
- error: { [method]: error = [] }
59
- } = target.__hooks;
60
- const beforeHooks = before;
61
- const afterHooks = [...after].reverse();
62
- const errorHook = fromErrorHooks(error);
63
-
64
- return [errorHook, ...beforeHooks, ...afterHooks];
65
- }
66
-
67
- // Converts different hook registration formats into the
68
- // same internal format
69
- export function convertHookData (obj: any) {
70
- let hook: any = {};
71
-
72
- if (Array.isArray(obj)) {
73
- hook = { all: obj };
74
- } else if (typeof obj !== 'object') {
75
- hook = { all: [ obj ] };
76
- } else {
77
- each(obj, function (value, key) {
78
- hook[key] = !Array.isArray(value) ? [ value ] : value;
79
- });
80
- }
81
-
82
- return hook;
83
- }
84
-
85
- // Add `.hooks` functionality to an object
86
- export function enableLegacyHooks (
87
- obj: any,
88
- methods: string[] = ['find', 'get', 'create', 'update', 'patch', 'remove'],
89
- types: string[] = ['before', 'after', 'error']
90
- ) {
91
- const hookData: any = {};
92
-
93
- types.forEach(type => {
94
- // Initialize properties where hook functions are stored
95
- hookData[type] = {};
96
- });
97
-
98
- // Add non-enumerable `__hooks` property to the object
99
- Object.defineProperty(obj, '__hooks', {
100
- configurable: true,
101
- value: hookData,
102
- writable: true
103
- });
104
-
105
- return function legacyHooks (this: any, allHooks: any) {
106
- each(allHooks, (current: any, type) => {
107
- if (!this.__hooks[type]) {
108
- throw new Error(`'${type}' is not a valid hook type`);
109
- }
110
-
111
- const hooks = convertHookData(current);
112
-
113
- each(hooks, (_value, method) => {
114
- if (method !== 'all' && methods.indexOf(method) === -1) {
115
- throw new Error(`'${method}' is not a valid hook method`);
116
- }
117
- });
118
-
119
- methods.forEach(method => {
120
- let currentHooks = [...(hooks.all || []), ...(hooks[method] || [])];
121
-
122
- this.__hooks[type][method] = this.__hooks[type][method] || [];
123
-
124
- if (type === 'before') {
125
- currentHooks = currentHooks.map(fromBeforeHook);
126
- }
127
-
128
- if (type === 'after') {
129
- currentHooks = currentHooks.map(fromAfterHook);
130
- }
131
-
132
- this.__hooks[type][method].push(...currentHooks);
133
- });
134
- });
135
-
136
- return this;
137
- }
138
- }