@loopback/context 3.5.1 → 3.8.1
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/CHANGELOG.md +60 -0
- package/dist/binding-config.js +1 -0
- package/dist/binding-config.js.map +1 -1
- package/dist/binding-decorator.d.ts +1 -2
- package/dist/binding-decorator.js +1 -0
- package/dist/binding-decorator.js.map +1 -1
- package/dist/binding-filter.d.ts +2 -2
- package/dist/binding-filter.js +4 -3
- package/dist/binding-filter.js.map +1 -1
- package/dist/binding-inspector.d.ts +14 -7
- package/dist/binding-inspector.js +14 -6
- package/dist/binding-inspector.js.map +1 -1
- package/dist/binding-key.d.ts +5 -0
- package/dist/binding-key.js +104 -90
- package/dist/binding-key.js.map +1 -1
- package/dist/binding-sorter.js +1 -0
- package/dist/binding-sorter.js.map +1 -1
- package/dist/binding.d.ts +84 -7
- package/dist/binding.js +120 -35
- package/dist/binding.js.map +1 -1
- package/dist/context-subscription.js +1 -0
- package/dist/context-subscription.js.map +1 -1
- package/dist/context-tag-indexer.js +1 -0
- package/dist/context-tag-indexer.js.map +1 -1
- package/dist/context-view.js +1 -0
- package/dist/context-view.js.map +1 -1
- package/dist/context.js +2 -2
- package/dist/context.js.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/inject-config.js +1 -0
- package/dist/inject-config.js.map +1 -1
- package/dist/inject.d.ts +13 -6
- package/dist/inject.js +6 -8
- package/dist/inject.js.map +1 -1
- package/dist/interception-proxy.js +1 -0
- package/dist/interception-proxy.js.map +1 -1
- package/dist/interceptor-chain.d.ts +39 -4
- package/dist/interceptor-chain.js +26 -4
- package/dist/interceptor-chain.js.map +1 -1
- package/dist/interceptor.d.ts +28 -3
- package/dist/interceptor.js +54 -0
- package/dist/interceptor.js.map +1 -1
- package/dist/invocation.js +1 -0
- package/dist/invocation.js.map +1 -1
- package/dist/keys.d.ts +5 -0
- package/dist/keys.js +6 -0
- package/dist/keys.js.map +1 -1
- package/dist/resolution-session.d.ts +26 -6
- package/dist/resolution-session.js +1 -0
- package/dist/resolution-session.js.map +1 -1
- package/dist/resolver.js +1 -0
- package/dist/resolver.js.map +1 -1
- package/dist/value-promise.d.ts +8 -4
- package/dist/value-promise.js +17 -0
- package/dist/value-promise.js.map +1 -1
- package/package.json +13 -13
- package/src/binding-decorator.ts +2 -3
- package/src/binding-filter.ts +8 -7
- package/src/binding-inspector.ts +32 -9
- package/src/binding-key.ts +12 -0
- package/src/binding.ts +210 -44
- package/src/context.ts +2 -2
- package/src/inject.ts +22 -16
- package/src/interceptor-chain.ts +66 -7
- package/src/interceptor.ts +85 -2
- package/src/keys.ts +6 -0
- package/src/resolution-session.ts +30 -2
- package/src/value-promise.ts +13 -0
- package/index.d.ts +0 -6
- package/index.js +0 -6
package/src/interceptor.ts
CHANGED
|
@@ -15,7 +15,13 @@ import assert from 'assert';
|
|
|
15
15
|
import debugFactory from 'debug';
|
|
16
16
|
import {Binding, BindingTemplate} from './binding';
|
|
17
17
|
import {bind} from './binding-decorator';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
BindingFromClassOptions,
|
|
20
|
+
BindingSpec,
|
|
21
|
+
createBindingFromClass,
|
|
22
|
+
isProviderClass,
|
|
23
|
+
} from './binding-inspector';
|
|
24
|
+
import {BindingAddress, BindingKey} from './binding-key';
|
|
19
25
|
import {sortBindingsByPhase} from './binding-sorter';
|
|
20
26
|
import {Context} from './context';
|
|
21
27
|
import {
|
|
@@ -33,8 +39,10 @@ import {
|
|
|
33
39
|
ContextBindings,
|
|
34
40
|
ContextTags,
|
|
35
41
|
GLOBAL_INTERCEPTOR_NAMESPACE,
|
|
42
|
+
LOCAL_INTERCEPTOR_NAMESPACE,
|
|
36
43
|
} from './keys';
|
|
37
|
-
import {
|
|
44
|
+
import {Provider} from './provider';
|
|
45
|
+
import {Constructor, tryWithFinally, ValueOrPromise} from './value-promise';
|
|
38
46
|
const debug = debugFactory('loopback:context:interceptor');
|
|
39
47
|
|
|
40
48
|
/**
|
|
@@ -345,3 +353,78 @@ export function invokeMethodWithInterceptors(
|
|
|
345
353
|
() => invocationCtx.close(),
|
|
346
354
|
);
|
|
347
355
|
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Options for an interceptor binding
|
|
359
|
+
*/
|
|
360
|
+
export interface InterceptorBindingOptions extends BindingFromClassOptions {
|
|
361
|
+
/**
|
|
362
|
+
* Global or local interceptor
|
|
363
|
+
*/
|
|
364
|
+
global?: boolean;
|
|
365
|
+
/**
|
|
366
|
+
* Group name for a global interceptor
|
|
367
|
+
*/
|
|
368
|
+
group?: string;
|
|
369
|
+
/**
|
|
370
|
+
* Source filter for a global interceptor
|
|
371
|
+
*/
|
|
372
|
+
source?: string | string[];
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Register an interceptor function or provider class to the given context
|
|
377
|
+
* @param ctx - Context object
|
|
378
|
+
* @param interceptor - An interceptor function or provider class
|
|
379
|
+
* @param options - Options for the interceptor binding
|
|
380
|
+
*/
|
|
381
|
+
export function registerInterceptor(
|
|
382
|
+
ctx: Context,
|
|
383
|
+
interceptor: Interceptor | Constructor<Provider<Interceptor>>,
|
|
384
|
+
options: InterceptorBindingOptions = {},
|
|
385
|
+
) {
|
|
386
|
+
let {global} = options;
|
|
387
|
+
const {group, source} = options;
|
|
388
|
+
if (group != null || source != null) {
|
|
389
|
+
// If group or source is set, assuming global
|
|
390
|
+
global = global !== false;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const namespace =
|
|
394
|
+
options.namespace ?? options.defaultNamespace ?? global
|
|
395
|
+
? GLOBAL_INTERCEPTOR_NAMESPACE
|
|
396
|
+
: LOCAL_INTERCEPTOR_NAMESPACE;
|
|
397
|
+
|
|
398
|
+
let binding: Binding<Interceptor>;
|
|
399
|
+
if (isProviderClass(interceptor)) {
|
|
400
|
+
binding = createBindingFromClass(interceptor, {
|
|
401
|
+
defaultNamespace: namespace,
|
|
402
|
+
...options,
|
|
403
|
+
});
|
|
404
|
+
if (binding.tagMap[ContextTags.GLOBAL_INTERCEPTOR]) {
|
|
405
|
+
global = true;
|
|
406
|
+
}
|
|
407
|
+
ctx.add(binding);
|
|
408
|
+
} else {
|
|
409
|
+
let key = options.key;
|
|
410
|
+
if (!key) {
|
|
411
|
+
const name = options.name ?? interceptor.name;
|
|
412
|
+
if (!name) {
|
|
413
|
+
key = BindingKey.generate<Interceptor>(namespace).key;
|
|
414
|
+
} else {
|
|
415
|
+
key = `${namespace}.${name}`;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
binding = ctx
|
|
419
|
+
.bind(key as BindingAddress<Interceptor>)
|
|
420
|
+
.to(interceptor as Interceptor);
|
|
421
|
+
}
|
|
422
|
+
if (global) {
|
|
423
|
+
binding.apply(asGlobalInterceptor(group));
|
|
424
|
+
if (source) {
|
|
425
|
+
binding.tag({[ContextTags.GLOBAL_INTERCEPTOR_SOURCE]: source});
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return binding;
|
|
430
|
+
}
|
package/src/keys.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {BindingKey} from './binding-key';
|
|
|
12
12
|
export namespace ContextTags {
|
|
13
13
|
export const CLASS = 'class';
|
|
14
14
|
export const PROVIDER = 'provider';
|
|
15
|
+
export const DYNAMIC_VALUE_PROVIDER = 'dynamicValueProvider';
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Type of the artifact
|
|
@@ -58,6 +59,11 @@ export namespace ContextTags {
|
|
|
58
59
|
*/
|
|
59
60
|
export const GLOBAL_INTERCEPTOR_NAMESPACE = 'globalInterceptors';
|
|
60
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Default namespace for local interceptors
|
|
64
|
+
*/
|
|
65
|
+
export const LOCAL_INTERCEPTOR_NAMESPACE = 'interceptors';
|
|
66
|
+
|
|
61
67
|
/**
|
|
62
68
|
* Namespace for context bindings
|
|
63
69
|
*/
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
import {DecoratorFactory} from '@loopback/metadata';
|
|
7
7
|
import debugModule from 'debug';
|
|
8
8
|
import {Binding} from './binding';
|
|
9
|
-
import {
|
|
9
|
+
import {BindingSelector} from './binding-filter';
|
|
10
|
+
import {Context} from './context';
|
|
11
|
+
import {Injection, InjectionMetadata} from './inject';
|
|
10
12
|
import {BoundValue, tryWithFinally, ValueOrPromise} from './value-promise';
|
|
11
13
|
|
|
12
14
|
const debugSession = debugModule('loopback:context:resolver:session');
|
|
@@ -35,6 +37,12 @@ export interface InjectionElement {
|
|
|
35
37
|
value: Readonly<Injection>;
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
export interface InjectionDescriptor {
|
|
41
|
+
targetName: string;
|
|
42
|
+
bindingSelector: BindingSelector;
|
|
43
|
+
metadata: InjectionMetadata;
|
|
44
|
+
}
|
|
45
|
+
|
|
38
46
|
/**
|
|
39
47
|
* Binding or injection elements tracked by resolution sessions
|
|
40
48
|
*/
|
|
@@ -155,7 +163,9 @@ export class ResolutionSession {
|
|
|
155
163
|
* Describe the injection for debugging purpose
|
|
156
164
|
* @param injection - Injection object
|
|
157
165
|
*/
|
|
158
|
-
static describeInjection(
|
|
166
|
+
static describeInjection(
|
|
167
|
+
injection: Readonly<Injection>,
|
|
168
|
+
): InjectionDescriptor {
|
|
159
169
|
const name = getTargetName(
|
|
160
170
|
injection.target,
|
|
161
171
|
injection.member,
|
|
@@ -366,3 +376,21 @@ export function asResolutionOptions(
|
|
|
366
376
|
}
|
|
367
377
|
return optionsOrSession ?? {};
|
|
368
378
|
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Contextual metadata for resolution
|
|
382
|
+
*/
|
|
383
|
+
export interface ResolutionContext<T = unknown> {
|
|
384
|
+
/**
|
|
385
|
+
* The context for resolution
|
|
386
|
+
*/
|
|
387
|
+
readonly context: Context;
|
|
388
|
+
/**
|
|
389
|
+
* The binding to be resolved
|
|
390
|
+
*/
|
|
391
|
+
readonly binding: Readonly<Binding<T>>;
|
|
392
|
+
/**
|
|
393
|
+
* The options used for resolution
|
|
394
|
+
*/
|
|
395
|
+
readonly options: ResolutionOptions;
|
|
396
|
+
}
|
package/src/value-promise.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* utility methods to handle values and/or promises.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import {v4 as uuidv4} from 'uuid';
|
|
11
12
|
/**
|
|
12
13
|
* A class constructor accepting arbitrary arguments.
|
|
13
14
|
*/
|
|
@@ -270,3 +271,15 @@ export function transformValueOrPromise<T, V>(
|
|
|
270
271
|
return transformer(valueOrPromise);
|
|
271
272
|
}
|
|
272
273
|
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* A utility to generate uuid v4
|
|
277
|
+
*/
|
|
278
|
+
export function uuid() {
|
|
279
|
+
return uuidv4();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* A regular expression for testing uuid v4 PATTERN
|
|
284
|
+
*/
|
|
285
|
+
export const UUID_PATTERN = /[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}/i;
|
package/index.d.ts
DELETED
package/index.js
DELETED