@loopback/context 4.0.0-alpha.6 → 4.0.0
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/LICENSE +25 -0
- package/README.md +116 -0
- package/dist/binding-config.d.ts +40 -0
- package/dist/binding-config.js +33 -0
- package/dist/binding-config.js.map +1 -0
- package/dist/binding-decorator.d.ts +45 -0
- package/dist/binding-decorator.js +118 -0
- package/dist/binding-decorator.js.map +1 -0
- package/dist/binding-filter.d.ts +108 -0
- package/dist/binding-filter.js +162 -0
- package/dist/binding-filter.js.map +1 -0
- package/dist/binding-inspector.d.ts +150 -0
- package/dist/binding-inspector.js +249 -0
- package/dist/binding-inspector.js.map +1 -0
- package/dist/binding-key.d.ts +66 -0
- package/dist/binding-key.js +121 -0
- package/dist/binding-key.js.map +1 -0
- package/dist/binding-sorter.d.ts +71 -0
- package/dist/binding-sorter.js +89 -0
- package/dist/binding-sorter.js.map +1 -0
- package/dist/binding.d.ts +577 -0
- package/dist/binding.js +788 -0
- package/dist/binding.js.map +1 -0
- package/dist/context-event.d.ts +23 -0
- package/dist/context-event.js +7 -0
- package/dist/context-event.js.map +1 -0
- package/dist/context-observer.d.ts +36 -0
- package/dist/context-observer.js +7 -0
- package/dist/context-observer.js.map +1 -0
- package/dist/context-subscription.d.ts +147 -0
- package/dist/context-subscription.js +317 -0
- package/dist/context-subscription.js.map +1 -0
- package/dist/context-tag-indexer.d.ts +42 -0
- package/dist/context-tag-indexer.js +135 -0
- package/dist/context-tag-indexer.js.map +1 -0
- package/dist/context-view.d.ts +209 -0
- package/dist/context-view.js +240 -0
- package/dist/context-view.js.map +1 -0
- package/dist/context.d.ts +513 -0
- package/dist/context.js +717 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/inject-config.d.ts +67 -0
- package/dist/inject-config.js +181 -0
- package/dist/inject-config.js.map +1 -0
- package/dist/inject.d.ts +250 -0
- package/dist/inject.js +535 -0
- package/dist/inject.js.map +1 -0
- package/dist/interception-proxy.d.ts +76 -0
- package/dist/interception-proxy.js +67 -0
- package/dist/interception-proxy.js.map +1 -0
- package/dist/interceptor-chain.d.ts +121 -0
- package/dist/interceptor-chain.js +148 -0
- package/dist/interceptor-chain.js.map +1 -0
- package/dist/interceptor.d.ts +138 -0
- package/dist/interceptor.js +299 -0
- package/dist/interceptor.js.map +1 -0
- package/dist/invocation.d.ts +101 -0
- package/dist/invocation.js +163 -0
- package/dist/invocation.js.map +1 -0
- package/dist/json-types.d.ts +28 -0
- package/dist/json-types.js +7 -0
- package/dist/json-types.js.map +1 -0
- package/dist/keys.d.ts +65 -0
- package/dist/keys.js +74 -0
- package/dist/keys.js.map +1 -0
- package/dist/provider.d.ts +31 -0
- package/dist/provider.js +7 -0
- package/dist/provider.js.map +1 -0
- package/dist/resolution-session.d.ts +180 -0
- package/dist/resolution-session.js +274 -0
- package/dist/resolution-session.js.map +1 -0
- package/dist/resolver.d.ts +46 -0
- package/dist/resolver.js +203 -0
- package/dist/resolver.js.map +1 -0
- package/dist/unique-id.d.ts +14 -0
- package/dist/unique-id.js +26 -0
- package/dist/unique-id.js.map +1 -0
- package/dist/value-promise.d.ts +134 -0
- package/dist/value-promise.js +277 -0
- package/dist/value-promise.js.map +1 -0
- package/package.json +49 -36
- package/src/binding-config.ts +73 -0
- package/src/binding-decorator.ts +136 -0
- package/src/binding-filter.ts +250 -0
- package/src/binding-inspector.ts +371 -0
- package/src/binding-key.ts +136 -0
- package/src/binding-sorter.ts +124 -0
- package/src/binding.ts +1107 -0
- package/src/context-event.ts +30 -0
- package/src/context-observer.ts +50 -0
- package/src/context-subscription.ts +402 -0
- package/src/context-tag-indexer.ts +147 -0
- package/src/context-view.ts +440 -0
- package/src/context.ts +1079 -0
- package/src/index.ts +58 -0
- package/src/inject-config.ts +239 -0
- package/src/inject.ts +796 -0
- package/src/interception-proxy.ts +127 -0
- package/src/interceptor-chain.ts +268 -0
- package/src/interceptor.ts +430 -0
- package/src/invocation.ts +269 -0
- package/src/json-types.ts +35 -0
- package/src/keys.ts +85 -0
- package/src/provider.ts +37 -0
- package/src/resolution-session.ts +414 -0
- package/src/resolver.ts +282 -0
- package/src/unique-id.ts +24 -0
- package/src/value-promise.ts +318 -0
- package/index.d.ts +0 -6
- package/index.js +0 -9
- package/lib/binding.d.ts +0 -75
- package/lib/binding.js +0 -102
- package/lib/context.d.ts +0 -14
- package/lib/context.js +0 -96
- package/lib/index.d.ts +0 -5
- package/lib/index.js +0 -13
- package/lib/inject.d.ts +0 -24
- package/lib/inject.js +0 -43
- package/lib/isPromise.d.ts +0 -1
- package/lib/isPromise.js +0 -14
- package/lib/resolver.d.ts +0 -26
- package/lib/resolver.js +0 -72
- package/lib6/binding.d.ts +0 -75
- package/lib6/binding.js +0 -102
- package/lib6/context.d.ts +0 -14
- package/lib6/context.js +0 -96
- package/lib6/index.d.ts +0 -5
- package/lib6/index.js +0 -13
- package/lib6/inject.d.ts +0 -24
- package/lib6/inject.js +0 -43
- package/lib6/isPromise.d.ts +0 -1
- package/lib6/isPromise.js +0 -14
- package/lib6/resolver.d.ts +0 -26
- package/lib6/resolver.js +0 -72
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright IBM Corp. 2019,2020. All Rights Reserved.
|
|
3
|
+
// Node module: @loopback/context
|
|
4
|
+
// This file is licensed under the MIT License.
|
|
5
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.createProxyWithInterceptors = exports.InterceptionHandler = exports.ProxySource = void 0;
|
|
8
|
+
const context_1 = require("./context");
|
|
9
|
+
const interceptor_1 = require("./interceptor");
|
|
10
|
+
const resolution_session_1 = require("./resolution-session");
|
|
11
|
+
/**
|
|
12
|
+
* Invocation source for injected proxies. It wraps a snapshot of the
|
|
13
|
+
* `ResolutionSession` that tracks the binding/injection stack.
|
|
14
|
+
*/
|
|
15
|
+
class ProxySource {
|
|
16
|
+
constructor(value) {
|
|
17
|
+
this.value = value;
|
|
18
|
+
this.type = 'proxy';
|
|
19
|
+
}
|
|
20
|
+
toString() {
|
|
21
|
+
return this.value.getBindingPath();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ProxySource = ProxySource;
|
|
25
|
+
/**
|
|
26
|
+
* A proxy handler that applies interceptors
|
|
27
|
+
*
|
|
28
|
+
* See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy
|
|
29
|
+
*/
|
|
30
|
+
class InterceptionHandler {
|
|
31
|
+
constructor(context = new context_1.Context(), session, source) {
|
|
32
|
+
this.context = context;
|
|
33
|
+
this.session = session;
|
|
34
|
+
this.source = source;
|
|
35
|
+
}
|
|
36
|
+
get(target, propertyName, receiver) {
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
const targetObj = target;
|
|
39
|
+
if (typeof propertyName !== 'string')
|
|
40
|
+
return targetObj[propertyName];
|
|
41
|
+
const propertyOrMethod = targetObj[propertyName];
|
|
42
|
+
if (typeof propertyOrMethod === 'function') {
|
|
43
|
+
return (...args) => {
|
|
44
|
+
var _a;
|
|
45
|
+
return (0, interceptor_1.invokeMethodWithInterceptors)(this.context, target, propertyName, args, {
|
|
46
|
+
source: (_a = this.source) !== null && _a !== void 0 ? _a : (this.session && new ProxySource(this.session)),
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
return propertyOrMethod;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.InterceptionHandler = InterceptionHandler;
|
|
56
|
+
/**
|
|
57
|
+
* Create a proxy that applies interceptors for method invocations
|
|
58
|
+
* @param target - Target class or object
|
|
59
|
+
* @param context - Context object
|
|
60
|
+
* @param session - Resolution session
|
|
61
|
+
* @param source - Invocation source
|
|
62
|
+
*/
|
|
63
|
+
function createProxyWithInterceptors(target, context, session, source) {
|
|
64
|
+
return new Proxy(target, new InterceptionHandler(context, resolution_session_1.ResolutionSession.fork(session), source));
|
|
65
|
+
}
|
|
66
|
+
exports.createProxyWithInterceptors = createProxyWithInterceptors;
|
|
67
|
+
//# sourceMappingURL=interception-proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interception-proxy.js","sourceRoot":"","sources":["../src/interception-proxy.ts"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,iCAAiC;AACjC,+CAA+C;AAC/C,gEAAgE;;;AAEhE,uCAAkC;AAClC,+CAA2D;AAE3D,6DAAuD;AAoDvD;;;GAGG;AACH,MAAa,WAAW;IAEtB,YAAqB,KAAwB;QAAxB,UAAK,GAAL,KAAK,CAAmB;QAD7C,SAAI,GAAG,OAAO,CAAC;IACiC,CAAC;IAEjD,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;IACrC,CAAC;CACF;AAPD,kCAOC;AAED;;;;GAIG;AACH,MAAa,mBAAmB;IAC9B,YACU,UAAU,IAAI,iBAAO,EAAE,EACvB,OAA2B,EAC3B,MAAyB;QAFzB,YAAO,GAAP,OAAO,CAAgB;QACvB,YAAO,GAAP,OAAO,CAAoB;QAC3B,WAAM,GAAN,MAAM,CAAmB;IAChC,CAAC;IAEJ,GAAG,CAAC,MAAS,EAAE,YAAyB,EAAE,QAAiB;QACzD,8DAA8D;QAC9D,MAAM,SAAS,GAAG,MAAa,CAAC;QAChC,IAAI,OAAO,YAAY,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC,YAAY,CAAC,CAAC;QACrE,MAAM,gBAAgB,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;QACjD,IAAI,OAAO,gBAAgB,KAAK,UAAU,EAAE;YAC1C,OAAO,CAAC,GAAG,IAAoB,EAAE,EAAE;;gBACjC,OAAO,IAAA,0CAA4B,EACjC,IAAI,CAAC,OAAO,EACZ,MAAM,EACN,YAAY,EACZ,IAAI,EACJ;oBACE,MAAM,EACJ,MAAA,IAAI,CAAC,MAAM,mCAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;iBACjE,CACF,CAAC;YACJ,CAAC,CAAC;SACH;aAAM;YACL,OAAO,gBAAgB,CAAC;SACzB;IACH,CAAC;CACF;AA7BD,kDA6BC;AAED;;;;;;GAMG;AACH,SAAgB,2BAA2B,CACzC,MAAS,EACT,OAAiB,EACjB,OAA2B,EAC3B,MAAyB;IAEzB,OAAO,IAAI,KAAK,CACd,MAAM,EACN,IAAI,mBAAmB,CAAC,OAAO,EAAE,sCAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CACzD,CAAC;AACrB,CAAC;AAVD,kEAUC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { BindingFilter } from './binding-filter';
|
|
2
|
+
import { BindingAddress } from './binding-key';
|
|
3
|
+
import { BindingComparator } from './binding-sorter';
|
|
4
|
+
import { Context } from './context';
|
|
5
|
+
import { InvocationResult } from './invocation';
|
|
6
|
+
import { ValueOrPromise } from './value-promise';
|
|
7
|
+
/**
|
|
8
|
+
* Any type except `void`. We use this type to enforce that interceptor functions
|
|
9
|
+
* always return a value (including undefined or null).
|
|
10
|
+
*/
|
|
11
|
+
export declare type NonVoid = string | number | boolean | null | undefined | object;
|
|
12
|
+
/**
|
|
13
|
+
* The `next` function that can be used to invoke next generic interceptor in
|
|
14
|
+
* the chain
|
|
15
|
+
*/
|
|
16
|
+
export declare type Next = () => ValueOrPromise<NonVoid>;
|
|
17
|
+
/**
|
|
18
|
+
* An interceptor function to be invoked in a chain for the given context.
|
|
19
|
+
* It serves as the base interface for various types of interceptors, such
|
|
20
|
+
* as method invocation interceptor or request/response processing interceptor.
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* We choose `NonVoid` as the return type to avoid possible bugs that an
|
|
24
|
+
* interceptor forgets to return the value from `next()`. For example, the code
|
|
25
|
+
* below will fail to compile.
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* const myInterceptor: Interceptor = async (ctx, next) {
|
|
29
|
+
* // preprocessing
|
|
30
|
+
* // ...
|
|
31
|
+
*
|
|
32
|
+
* // There is a subtle bug that the result from `next()` is not further
|
|
33
|
+
* // returned back to the upstream interceptors
|
|
34
|
+
* const result = await next();
|
|
35
|
+
*
|
|
36
|
+
* // postprocessing
|
|
37
|
+
* // ...
|
|
38
|
+
* // We must have `return ...` here
|
|
39
|
+
* // either return `result` or another value if the interceptor decides to
|
|
40
|
+
* // have its own response
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @typeParam C - `Context` class or a subclass of `Context`
|
|
45
|
+
* @param context - Context object
|
|
46
|
+
* @param next - A function to proceed with downstream interceptors or the
|
|
47
|
+
* target operation
|
|
48
|
+
*
|
|
49
|
+
* @returns The invocation result as a value (sync) or promise (async).
|
|
50
|
+
*/
|
|
51
|
+
export declare type GenericInterceptor<C extends Context = Context> = (context: C, next: Next) => ValueOrPromise<NonVoid>;
|
|
52
|
+
/**
|
|
53
|
+
* Interceptor function or a binding key that resolves a generic interceptor
|
|
54
|
+
* function
|
|
55
|
+
* @typeParam C - `Context` class or a subclass of `Context`
|
|
56
|
+
* @typeParam T - Return type of `next()`
|
|
57
|
+
*/
|
|
58
|
+
export declare type GenericInterceptorOrKey<C extends Context = Context> = BindingAddress<GenericInterceptor<C>> | GenericInterceptor<C>;
|
|
59
|
+
/**
|
|
60
|
+
* A chain of generic interceptors to be invoked for the given context
|
|
61
|
+
*
|
|
62
|
+
* @typeParam C - `Context` class or a subclass of `Context`
|
|
63
|
+
*/
|
|
64
|
+
export declare class GenericInterceptorChain<C extends Context = Context> {
|
|
65
|
+
private context;
|
|
66
|
+
/**
|
|
67
|
+
* A getter for an array of interceptor functions or binding keys
|
|
68
|
+
*/
|
|
69
|
+
protected getInterceptors: () => GenericInterceptorOrKey<C>[];
|
|
70
|
+
/**
|
|
71
|
+
* Create an invocation chain with a list of interceptor functions or
|
|
72
|
+
* binding keys
|
|
73
|
+
* @param context - Context object
|
|
74
|
+
* @param interceptors - An array of interceptor functions or binding keys
|
|
75
|
+
*/
|
|
76
|
+
constructor(context: C, interceptors: GenericInterceptorOrKey<C>[]);
|
|
77
|
+
/**
|
|
78
|
+
* Create an invocation interceptor chain with a binding filter and comparator.
|
|
79
|
+
* The interceptors are discovered from the context using the binding filter and
|
|
80
|
+
* sorted by the comparator (if provided).
|
|
81
|
+
*
|
|
82
|
+
* @param context - Context object
|
|
83
|
+
* @param filter - A binding filter function to select interceptors
|
|
84
|
+
* @param comparator - An optional comparator to sort matched interceptor bindings
|
|
85
|
+
*/
|
|
86
|
+
constructor(context: C, filter: BindingFilter, comparator?: BindingComparator);
|
|
87
|
+
/**
|
|
88
|
+
* Invoke the interceptor chain
|
|
89
|
+
*/
|
|
90
|
+
invokeInterceptors(finalHandler?: Next): ValueOrPromise<InvocationResult>;
|
|
91
|
+
/**
|
|
92
|
+
* Use the interceptor chain as an interceptor
|
|
93
|
+
*/
|
|
94
|
+
asInterceptor(): GenericInterceptor<C>;
|
|
95
|
+
/**
|
|
96
|
+
* Invoke downstream interceptors or the target method
|
|
97
|
+
*/
|
|
98
|
+
private next;
|
|
99
|
+
/**
|
|
100
|
+
* Invoke downstream interceptors
|
|
101
|
+
*/
|
|
102
|
+
private invokeNextInterceptor;
|
|
103
|
+
/**
|
|
104
|
+
* Return the interceptor function or resolve the interceptor function as a binding
|
|
105
|
+
* from the context
|
|
106
|
+
*
|
|
107
|
+
* @param interceptor - Interceptor function or binding key
|
|
108
|
+
*/
|
|
109
|
+
private loadInterceptor;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Invoke a chain of interceptors with the context
|
|
113
|
+
* @param context - Context object
|
|
114
|
+
* @param interceptors - An array of interceptor functions or binding keys
|
|
115
|
+
*/
|
|
116
|
+
export declare function invokeInterceptors<C extends Context = Context, T = InvocationResult>(context: C, interceptors: GenericInterceptorOrKey<C>[]): ValueOrPromise<T | undefined>;
|
|
117
|
+
/**
|
|
118
|
+
* Compose a list of interceptors as a single interceptor
|
|
119
|
+
* @param interceptors - A list of interceptor functions or binding keys
|
|
120
|
+
*/
|
|
121
|
+
export declare function composeInterceptors<C extends Context = Context>(...interceptors: GenericInterceptorOrKey<C>[]): GenericInterceptor<C>;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright IBM Corp. 2019,2020. All Rights Reserved.
|
|
3
|
+
// Node module: @loopback/context
|
|
4
|
+
// This file is licensed under the MIT License.
|
|
5
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.composeInterceptors = exports.invokeInterceptors = exports.GenericInterceptorChain = void 0;
|
|
8
|
+
const tslib_1 = require("tslib");
|
|
9
|
+
const debug_1 = (0, tslib_1.__importDefault)(require("debug"));
|
|
10
|
+
const value_promise_1 = require("./value-promise");
|
|
11
|
+
const debug = (0, debug_1.default)('loopback:context:interceptor-chain');
|
|
12
|
+
/**
|
|
13
|
+
* Invocation state of an interceptor chain
|
|
14
|
+
*/
|
|
15
|
+
class InterceptorChainState {
|
|
16
|
+
/**
|
|
17
|
+
* Create a state for the interceptor chain
|
|
18
|
+
* @param interceptors - Interceptor functions or binding keys
|
|
19
|
+
* @param finalHandler - An optional final handler
|
|
20
|
+
*/
|
|
21
|
+
constructor(interceptors, finalHandler = () => undefined) {
|
|
22
|
+
this.interceptors = interceptors;
|
|
23
|
+
this.finalHandler = finalHandler;
|
|
24
|
+
this._index = 0;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get the index for the current interceptor
|
|
28
|
+
*/
|
|
29
|
+
get index() {
|
|
30
|
+
return this._index;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check if the chain is done - all interceptors are invoked
|
|
34
|
+
*/
|
|
35
|
+
done() {
|
|
36
|
+
return this._index === this.interceptors.length;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get the next interceptor to be invoked
|
|
40
|
+
*/
|
|
41
|
+
next() {
|
|
42
|
+
if (this.done()) {
|
|
43
|
+
throw new Error('No more interceptor is in the chain');
|
|
44
|
+
}
|
|
45
|
+
return this.interceptors[this._index++];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A chain of generic interceptors to be invoked for the given context
|
|
50
|
+
*
|
|
51
|
+
* @typeParam C - `Context` class or a subclass of `Context`
|
|
52
|
+
*/
|
|
53
|
+
class GenericInterceptorChain {
|
|
54
|
+
// Implementation
|
|
55
|
+
constructor(context, interceptors, comparator) {
|
|
56
|
+
this.context = context;
|
|
57
|
+
if (typeof interceptors === 'function') {
|
|
58
|
+
const interceptorsView = context.createView(interceptors, comparator);
|
|
59
|
+
this.getInterceptors = () => {
|
|
60
|
+
const bindings = interceptorsView.bindings;
|
|
61
|
+
if (comparator) {
|
|
62
|
+
bindings.sort(comparator);
|
|
63
|
+
}
|
|
64
|
+
return bindings.map(b => b.key);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
else if (Array.isArray(interceptors)) {
|
|
68
|
+
this.getInterceptors = () => interceptors;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Invoke the interceptor chain
|
|
73
|
+
*/
|
|
74
|
+
invokeInterceptors(finalHandler) {
|
|
75
|
+
// Create a state for each invocation to provide isolation
|
|
76
|
+
const state = new InterceptorChainState(this.getInterceptors(), finalHandler);
|
|
77
|
+
return this.next(state);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Use the interceptor chain as an interceptor
|
|
81
|
+
*/
|
|
82
|
+
asInterceptor() {
|
|
83
|
+
return (ctx, next) => {
|
|
84
|
+
return this.invokeInterceptors(next);
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Invoke downstream interceptors or the target method
|
|
89
|
+
*/
|
|
90
|
+
next(state) {
|
|
91
|
+
if (state.done()) {
|
|
92
|
+
// No more interceptors
|
|
93
|
+
return state.finalHandler();
|
|
94
|
+
}
|
|
95
|
+
// Invoke the next interceptor in the chain
|
|
96
|
+
return this.invokeNextInterceptor(state);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Invoke downstream interceptors
|
|
100
|
+
*/
|
|
101
|
+
invokeNextInterceptor(state) {
|
|
102
|
+
const index = state.index;
|
|
103
|
+
const interceptor = state.next();
|
|
104
|
+
const interceptorFn = this.loadInterceptor(interceptor);
|
|
105
|
+
return (0, value_promise_1.transformValueOrPromise)(interceptorFn, fn => {
|
|
106
|
+
/* istanbul ignore if */
|
|
107
|
+
if (debug.enabled) {
|
|
108
|
+
debug('Invoking interceptor %d (%s) on %s', index, fn.name);
|
|
109
|
+
}
|
|
110
|
+
return fn(this.context, () => this.next(state));
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Return the interceptor function or resolve the interceptor function as a binding
|
|
115
|
+
* from the context
|
|
116
|
+
*
|
|
117
|
+
* @param interceptor - Interceptor function or binding key
|
|
118
|
+
*/
|
|
119
|
+
loadInterceptor(interceptor) {
|
|
120
|
+
if (typeof interceptor === 'function')
|
|
121
|
+
return interceptor;
|
|
122
|
+
debug('Resolving interceptor binding %s', interceptor);
|
|
123
|
+
return this.context.getValueOrPromise(interceptor);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.GenericInterceptorChain = GenericInterceptorChain;
|
|
127
|
+
/**
|
|
128
|
+
* Invoke a chain of interceptors with the context
|
|
129
|
+
* @param context - Context object
|
|
130
|
+
* @param interceptors - An array of interceptor functions or binding keys
|
|
131
|
+
*/
|
|
132
|
+
function invokeInterceptors(context, interceptors) {
|
|
133
|
+
const chain = new GenericInterceptorChain(context, interceptors);
|
|
134
|
+
return chain.invokeInterceptors();
|
|
135
|
+
}
|
|
136
|
+
exports.invokeInterceptors = invokeInterceptors;
|
|
137
|
+
/**
|
|
138
|
+
* Compose a list of interceptors as a single interceptor
|
|
139
|
+
* @param interceptors - A list of interceptor functions or binding keys
|
|
140
|
+
*/
|
|
141
|
+
function composeInterceptors(...interceptors) {
|
|
142
|
+
return (ctx, next) => {
|
|
143
|
+
const interceptor = new GenericInterceptorChain(ctx, interceptors).asInterceptor();
|
|
144
|
+
return interceptor(ctx, next);
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
exports.composeInterceptors = composeInterceptors;
|
|
148
|
+
//# sourceMappingURL=interceptor-chain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interceptor-chain.js","sourceRoot":"","sources":["../src/interceptor-chain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { MetadataAccessor } from '@loopback/metadata';
|
|
2
|
+
import { Binding, BindingTemplate } from './binding';
|
|
3
|
+
import { BindingFromClassOptions, BindingSpec } from './binding-inspector';
|
|
4
|
+
import { Context } from './context';
|
|
5
|
+
import { GenericInterceptor, GenericInterceptorOrKey } from './interceptor-chain';
|
|
6
|
+
import { InvocationArgs, InvocationContext, InvocationOptions, InvocationResult } from './invocation';
|
|
7
|
+
import { Provider } from './provider';
|
|
8
|
+
import { Constructor, ValueOrPromise } from './value-promise';
|
|
9
|
+
/**
|
|
10
|
+
* A specialized InvocationContext for interceptors
|
|
11
|
+
*/
|
|
12
|
+
export declare class InterceptedInvocationContext extends InvocationContext {
|
|
13
|
+
/**
|
|
14
|
+
* Discover all binding keys for global interceptors (tagged by
|
|
15
|
+
* ContextTags.GLOBAL_INTERCEPTOR)
|
|
16
|
+
*/
|
|
17
|
+
getGlobalInterceptorBindingKeys(): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Check if the binding for a global interceptor matches the source type
|
|
20
|
+
* of the invocation
|
|
21
|
+
* @param binding - Binding
|
|
22
|
+
*/
|
|
23
|
+
private applicableTo;
|
|
24
|
+
/**
|
|
25
|
+
* Sort global interceptor bindings by `globalInterceptorGroup` tags
|
|
26
|
+
* @param bindings - An array of global interceptor bindings
|
|
27
|
+
*/
|
|
28
|
+
private sortGlobalInterceptorBindings;
|
|
29
|
+
/**
|
|
30
|
+
* Load all interceptors for the given invocation context. It adds
|
|
31
|
+
* interceptors from possibly three sources:
|
|
32
|
+
* 1. method level `@intercept`
|
|
33
|
+
* 2. class level `@intercept`
|
|
34
|
+
* 3. global interceptors discovered in the context
|
|
35
|
+
*/
|
|
36
|
+
loadInterceptors(): InterceptorOrKey[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The `BindingTemplate` function to configure a binding as a global interceptor
|
|
40
|
+
* by tagging it with `ContextTags.INTERCEPTOR`
|
|
41
|
+
* @param group - Group for ordering the interceptor
|
|
42
|
+
*/
|
|
43
|
+
export declare function asGlobalInterceptor(group?: string): BindingTemplate;
|
|
44
|
+
/**
|
|
45
|
+
* `@globalInterceptor` decorator to mark the class as a global interceptor
|
|
46
|
+
* @param group - Group for ordering the interceptor
|
|
47
|
+
* @param specs - Extra binding specs
|
|
48
|
+
*/
|
|
49
|
+
export declare function globalInterceptor(group?: string, ...specs: BindingSpec[]): ClassDecorator;
|
|
50
|
+
/**
|
|
51
|
+
* Interceptor function to intercept method invocations
|
|
52
|
+
*/
|
|
53
|
+
export interface Interceptor extends GenericInterceptor<InvocationContext> {
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Interceptor function or binding key that can be used as parameters for
|
|
57
|
+
* `@intercept()`
|
|
58
|
+
*/
|
|
59
|
+
export declare type InterceptorOrKey = GenericInterceptorOrKey<InvocationContext>;
|
|
60
|
+
/**
|
|
61
|
+
* Metadata key for method-level interceptors
|
|
62
|
+
*/
|
|
63
|
+
export declare const INTERCEPT_METHOD_KEY: MetadataAccessor<InterceptorOrKey[], MethodDecorator>;
|
|
64
|
+
/**
|
|
65
|
+
* Adding interceptors from the spec to the front of existing ones. Duplicate
|
|
66
|
+
* entries are eliminated from the spec side.
|
|
67
|
+
*
|
|
68
|
+
* For example:
|
|
69
|
+
*
|
|
70
|
+
* - [log] + [cache, log] => [cache, log]
|
|
71
|
+
* - [log] + [log, cache] => [log, cache]
|
|
72
|
+
* - [] + [cache, log] => [cache, log]
|
|
73
|
+
* - [cache, log] + [] => [cache, log]
|
|
74
|
+
* - [log] + [cache] => [log, cache]
|
|
75
|
+
*
|
|
76
|
+
* @param interceptorsFromSpec - Interceptors from `@intercept`
|
|
77
|
+
* @param existingInterceptors - Interceptors already applied for the method
|
|
78
|
+
*/
|
|
79
|
+
export declare function mergeInterceptors(interceptorsFromSpec: InterceptorOrKey[], existingInterceptors: InterceptorOrKey[]): InterceptorOrKey[];
|
|
80
|
+
/**
|
|
81
|
+
* Metadata key for method-level interceptors
|
|
82
|
+
*/
|
|
83
|
+
export declare const INTERCEPT_CLASS_KEY: MetadataAccessor<InterceptorOrKey[], ClassDecorator>;
|
|
84
|
+
/**
|
|
85
|
+
* Decorator function `@intercept` for classes/methods to apply interceptors. It
|
|
86
|
+
* can be applied on a class and its public methods. Multiple occurrences of
|
|
87
|
+
* `@intercept` are allowed on the same target class or method. The decorator
|
|
88
|
+
* takes a list of `interceptor` functions or binding keys.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* @intercept(log, metrics)
|
|
93
|
+
* class MyController {
|
|
94
|
+
* @intercept('caching-interceptor')
|
|
95
|
+
* @intercept('name-validation-interceptor')
|
|
96
|
+
* greet(name: string) {
|
|
97
|
+
* return `Hello, ${name}`;
|
|
98
|
+
* }
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* @param interceptorOrKeys - One or more interceptors or binding keys that are
|
|
103
|
+
* resolved to be interceptors
|
|
104
|
+
*/
|
|
105
|
+
export declare function intercept(...interceptorOrKeys: InterceptorOrKey[]): (target: any, method?: string | undefined, methodDescriptor?: TypedPropertyDescriptor<any> | undefined) => any;
|
|
106
|
+
/**
|
|
107
|
+
* Invoke a method with the given context
|
|
108
|
+
* @param context - Context object
|
|
109
|
+
* @param target - Target class (for static methods) or object (for instance methods)
|
|
110
|
+
* @param methodName - Method name
|
|
111
|
+
* @param args - An array of argument values
|
|
112
|
+
* @param options - Options for the invocation
|
|
113
|
+
*/
|
|
114
|
+
export declare function invokeMethodWithInterceptors(context: Context, target: object, methodName: string, args: InvocationArgs, options?: InvocationOptions): ValueOrPromise<InvocationResult>;
|
|
115
|
+
/**
|
|
116
|
+
* Options for an interceptor binding
|
|
117
|
+
*/
|
|
118
|
+
export interface InterceptorBindingOptions extends BindingFromClassOptions {
|
|
119
|
+
/**
|
|
120
|
+
* Global or local interceptor
|
|
121
|
+
*/
|
|
122
|
+
global?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Group name for a global interceptor
|
|
125
|
+
*/
|
|
126
|
+
group?: string;
|
|
127
|
+
/**
|
|
128
|
+
* Source filter for a global interceptor
|
|
129
|
+
*/
|
|
130
|
+
source?: string | string[];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Register an interceptor function or provider class to the given context
|
|
134
|
+
* @param ctx - Context object
|
|
135
|
+
* @param interceptor - An interceptor function or provider class
|
|
136
|
+
* @param options - Options for the interceptor binding
|
|
137
|
+
*/
|
|
138
|
+
export declare function registerInterceptor(ctx: Context, interceptor: Interceptor | Constructor<Provider<Interceptor>>, options?: InterceptorBindingOptions): Binding<Interceptor>;
|