@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
package/lib/binding.d.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { Context } from './context';
|
|
2
|
-
import { Constructor } from './resolver';
|
|
3
|
-
export declare type BoundValue = any;
|
|
4
|
-
export declare class Binding {
|
|
5
|
-
private readonly _key;
|
|
6
|
-
isLocked: boolean;
|
|
7
|
-
private _tagName;
|
|
8
|
-
valueConstructor: Constructor<BoundValue>;
|
|
9
|
-
constructor(_key: string, isLocked?: boolean);
|
|
10
|
-
readonly key: string;
|
|
11
|
-
readonly tagName: string;
|
|
12
|
-
/**
|
|
13
|
-
* This is an internal function optimized for performance.
|
|
14
|
-
* Users should use `@inject(key)` or `ctx.get(key)` instead.
|
|
15
|
-
*
|
|
16
|
-
* Get the value bound to this key. Depending on `isSync`, this function returns either:
|
|
17
|
-
* - the bound value
|
|
18
|
-
* - a promise of the bound value
|
|
19
|
-
*
|
|
20
|
-
* Consumers wishing to consume sync values directly should use `isPromise`
|
|
21
|
-
* to check the type of the returned value to decide how to handle it.
|
|
22
|
-
*
|
|
23
|
-
* ```
|
|
24
|
-
* const result = binding.getValue(ctx);
|
|
25
|
-
* if (isPromise(result)) {
|
|
26
|
-
* result.then(doSomething)
|
|
27
|
-
* } else {
|
|
28
|
-
* doSomething(result);
|
|
29
|
-
* }
|
|
30
|
-
* ```
|
|
31
|
-
*/
|
|
32
|
-
getValue(ctx: Context): BoundValue | Promise<BoundValue>;
|
|
33
|
-
lock(): this;
|
|
34
|
-
tag(tagName: string): this;
|
|
35
|
-
/**
|
|
36
|
-
* Bind the key to a constant value.
|
|
37
|
-
*
|
|
38
|
-
* @param value The bound value.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
*
|
|
42
|
-
* ```ts
|
|
43
|
-
* ctx.bind('appName').to('CodeHub');
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
to(value: BoundValue): this;
|
|
47
|
-
/**
|
|
48
|
-
* Bind the key to a computed (dynamic) value.
|
|
49
|
-
*
|
|
50
|
-
* @param factoryFn The factory function creating the value.
|
|
51
|
-
* Both sync and async functions are supported.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
*
|
|
55
|
-
* ```ts
|
|
56
|
-
* // synchronous
|
|
57
|
-
* ctx.bind('now').toDynamicValue(() => Date.now());
|
|
58
|
-
*
|
|
59
|
-
* // asynchronous
|
|
60
|
-
* ctx.bind('something').toDynamicValue(
|
|
61
|
-
* async () => Promise.delay(10).then(doSomething)
|
|
62
|
-
* );
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
toDynamicValue(factoryFn: () => BoundValue | Promise<BoundValue>): this;
|
|
66
|
-
/**
|
|
67
|
-
* Bind the key to an instance of the given class.
|
|
68
|
-
*
|
|
69
|
-
* @param ctor The class constructor to call. Any constructor
|
|
70
|
-
* arguments must be annotated with `@inject` so that
|
|
71
|
-
* we can resolve them from the context.
|
|
72
|
-
*/
|
|
73
|
-
toClass<T>(ctor: Constructor<T>): this;
|
|
74
|
-
unlock(): this;
|
|
75
|
-
}
|
package/lib/binding.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright IBM Corp. 2013,2017. All Rights Reserved.
|
|
3
|
-
// Node module: loopback
|
|
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
|
-
const resolver_1 = require("./resolver");
|
|
8
|
-
// FIXME(bajtos) The binding class should be parameterized by the value type stored
|
|
9
|
-
class Binding {
|
|
10
|
-
constructor(_key, isLocked = false) {
|
|
11
|
-
this._key = _key;
|
|
12
|
-
this.isLocked = isLocked;
|
|
13
|
-
}
|
|
14
|
-
get key() { return this._key; }
|
|
15
|
-
get tagName() { return this._tagName; }
|
|
16
|
-
/**
|
|
17
|
-
* This is an internal function optimized for performance.
|
|
18
|
-
* Users should use `@inject(key)` or `ctx.get(key)` instead.
|
|
19
|
-
*
|
|
20
|
-
* Get the value bound to this key. Depending on `isSync`, this function returns either:
|
|
21
|
-
* - the bound value
|
|
22
|
-
* - a promise of the bound value
|
|
23
|
-
*
|
|
24
|
-
* Consumers wishing to consume sync values directly should use `isPromise`
|
|
25
|
-
* to check the type of the returned value to decide how to handle it.
|
|
26
|
-
*
|
|
27
|
-
* ```
|
|
28
|
-
* const result = binding.getValue(ctx);
|
|
29
|
-
* if (isPromise(result)) {
|
|
30
|
-
* result.then(doSomething)
|
|
31
|
-
* } else {
|
|
32
|
-
* doSomething(result);
|
|
33
|
-
* }
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
getValue(ctx) {
|
|
37
|
-
return Promise.reject(new Error(`No value was configured for binding ${this._key}.`));
|
|
38
|
-
}
|
|
39
|
-
lock() {
|
|
40
|
-
this.isLocked = true;
|
|
41
|
-
return this;
|
|
42
|
-
}
|
|
43
|
-
tag(tagName) {
|
|
44
|
-
this._tagName = tagName;
|
|
45
|
-
return this;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Bind the key to a constant value.
|
|
49
|
-
*
|
|
50
|
-
* @param value The bound value.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
*
|
|
54
|
-
* ```ts
|
|
55
|
-
* ctx.bind('appName').to('CodeHub');
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
to(value) {
|
|
59
|
-
this.getValue = () => value;
|
|
60
|
-
return this;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Bind the key to a computed (dynamic) value.
|
|
64
|
-
*
|
|
65
|
-
* @param factoryFn The factory function creating the value.
|
|
66
|
-
* Both sync and async functions are supported.
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
*
|
|
70
|
-
* ```ts
|
|
71
|
-
* // synchronous
|
|
72
|
-
* ctx.bind('now').toDynamicValue(() => Date.now());
|
|
73
|
-
*
|
|
74
|
-
* // asynchronous
|
|
75
|
-
* ctx.bind('something').toDynamicValue(
|
|
76
|
-
* async () => Promise.delay(10).then(doSomething)
|
|
77
|
-
* );
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
toDynamicValue(factoryFn) {
|
|
81
|
-
// TODO(bajtos) allow factoryFn with @inject arguments
|
|
82
|
-
this.getValue = (ctx) => factoryFn();
|
|
83
|
-
return this;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Bind the key to an instance of the given class.
|
|
87
|
-
*
|
|
88
|
-
* @param ctor The class constructor to call. Any constructor
|
|
89
|
-
* arguments must be annotated with `@inject` so that
|
|
90
|
-
* we can resolve them from the context.
|
|
91
|
-
*/
|
|
92
|
-
toClass(ctor) {
|
|
93
|
-
this.getValue = context => resolver_1.instantiateClass(ctor, context);
|
|
94
|
-
this.valueConstructor = ctor;
|
|
95
|
-
return this;
|
|
96
|
-
}
|
|
97
|
-
unlock() {
|
|
98
|
-
this.isLocked = false;
|
|
99
|
-
return this;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
exports.Binding = Binding;
|
package/lib/context.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Binding, BoundValue } from './binding';
|
|
2
|
-
export declare class Context {
|
|
3
|
-
private _parent;
|
|
4
|
-
private registry;
|
|
5
|
-
constructor(_parent?: Context);
|
|
6
|
-
bind(key: string): Binding;
|
|
7
|
-
contains(key: string): boolean;
|
|
8
|
-
find(pattern?: string): Binding[];
|
|
9
|
-
findByTag(pattern: string): Binding[];
|
|
10
|
-
protected _mergeWithParent(childList: Binding[], parentList?: Binding[]): Binding[];
|
|
11
|
-
get(key: string): Promise<BoundValue>;
|
|
12
|
-
getSync(key: string): BoundValue;
|
|
13
|
-
getBinding(key: string): Binding;
|
|
14
|
-
}
|
package/lib/context.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright IBM Corp. 2013,2017. All Rights Reserved.
|
|
3
|
-
// Node module: loopback
|
|
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
|
-
const binding_1 = require("./binding");
|
|
8
|
-
const isPromise_1 = require("./isPromise");
|
|
9
|
-
class Context {
|
|
10
|
-
constructor(_parent) {
|
|
11
|
-
this._parent = _parent;
|
|
12
|
-
this.registry = new Map();
|
|
13
|
-
}
|
|
14
|
-
bind(key) {
|
|
15
|
-
const keyExists = this.registry.has(key);
|
|
16
|
-
if (keyExists) {
|
|
17
|
-
const existingBinding = this.registry.get(key);
|
|
18
|
-
const bindingIsLocked = existingBinding && existingBinding.isLocked;
|
|
19
|
-
if (bindingIsLocked)
|
|
20
|
-
throw new Error(`Cannot rebind key "${key}", associated binding is locked`);
|
|
21
|
-
}
|
|
22
|
-
const binding = new binding_1.Binding(key);
|
|
23
|
-
this.registry.set(key, binding);
|
|
24
|
-
return binding;
|
|
25
|
-
}
|
|
26
|
-
contains(key) {
|
|
27
|
-
return this.registry.has(key);
|
|
28
|
-
}
|
|
29
|
-
find(pattern) {
|
|
30
|
-
let bindings = [];
|
|
31
|
-
if (pattern) {
|
|
32
|
-
// TODO(@superkhau): swap with production grade glob to regex lib
|
|
33
|
-
const glob = new RegExp('^' + pattern.split('*').join('.*') + '$');
|
|
34
|
-
this.registry.forEach(binding => {
|
|
35
|
-
const isMatch = glob.test(binding.key);
|
|
36
|
-
if (isMatch)
|
|
37
|
-
bindings.push(binding);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
bindings = Array.from(this.registry.values());
|
|
42
|
-
}
|
|
43
|
-
const parentBindings = this._parent && this._parent.find(pattern);
|
|
44
|
-
return this._mergeWithParent(bindings, parentBindings);
|
|
45
|
-
}
|
|
46
|
-
findByTag(pattern) {
|
|
47
|
-
const bindings = [];
|
|
48
|
-
// TODO(@superkhau): swap with production grade glob to regex lib
|
|
49
|
-
const glob = new RegExp('^' + pattern.split('*').join('.*') + '$');
|
|
50
|
-
this.registry.forEach(binding => {
|
|
51
|
-
const isMatch = glob.test(binding.tagName);
|
|
52
|
-
if (isMatch)
|
|
53
|
-
bindings.push(binding);
|
|
54
|
-
});
|
|
55
|
-
const parentBindings = this._parent && this._parent.findByTag(pattern);
|
|
56
|
-
return this._mergeWithParent(bindings, parentBindings);
|
|
57
|
-
}
|
|
58
|
-
_mergeWithParent(childList, parentList) {
|
|
59
|
-
if (!parentList)
|
|
60
|
-
return childList;
|
|
61
|
-
const additions = parentList.filter(parentBinding => {
|
|
62
|
-
// children bindings take precedence
|
|
63
|
-
return !childList.some(childBinding => childBinding.key === parentBinding.key);
|
|
64
|
-
});
|
|
65
|
-
return childList.concat(additions);
|
|
66
|
-
}
|
|
67
|
-
get(key) {
|
|
68
|
-
try {
|
|
69
|
-
const binding = this.getBinding(key);
|
|
70
|
-
return Promise.resolve(binding.getValue(this));
|
|
71
|
-
}
|
|
72
|
-
catch (err) {
|
|
73
|
-
return Promise.reject(err);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
getSync(key) {
|
|
77
|
-
const binding = this.getBinding(key);
|
|
78
|
-
const valueOrPromise = binding.getValue(this);
|
|
79
|
-
if (isPromise_1.isPromise(valueOrPromise)) {
|
|
80
|
-
throw new Error(`Cannot get ${key} synchronously: ` +
|
|
81
|
-
`the value requires async computation`);
|
|
82
|
-
}
|
|
83
|
-
return valueOrPromise;
|
|
84
|
-
}
|
|
85
|
-
getBinding(key) {
|
|
86
|
-
const binding = this.registry.get(key);
|
|
87
|
-
if (binding) {
|
|
88
|
-
return binding;
|
|
89
|
-
}
|
|
90
|
-
if (this._parent) {
|
|
91
|
-
return this._parent.getBinding(key);
|
|
92
|
-
}
|
|
93
|
-
throw new Error(`The key ${key} was not bound to any value.`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
exports.Context = Context;
|
package/lib/index.d.ts
DELETED
package/lib/index.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright IBM Corp. 2017. All Rights Reserved.
|
|
3
|
-
// Node module: loopback
|
|
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
|
-
var binding_1 = require("./binding");
|
|
8
|
-
exports.Binding = binding_1.Binding;
|
|
9
|
-
var context_1 = require("./context");
|
|
10
|
-
exports.Context = context_1.Context;
|
|
11
|
-
var inject_1 = require("./inject");
|
|
12
|
-
exports.inject = inject_1.inject;
|
|
13
|
-
exports.isPromise = require('is-promise');
|
package/lib/inject.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import 'reflect-metadata';
|
|
2
|
-
/**
|
|
3
|
-
* A decorator to annotate method arguments for automatic injection
|
|
4
|
-
* by LoopBack IoC container.
|
|
5
|
-
*
|
|
6
|
-
* Usage - Typescript:
|
|
7
|
-
*
|
|
8
|
-
* ```ts
|
|
9
|
-
* class InfoController {
|
|
10
|
-
* constructor(@inject('application.name') public appName: string) {
|
|
11
|
-
* }
|
|
12
|
-
* // ...
|
|
13
|
-
* }
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* Usage - JavaScript:
|
|
17
|
-
*
|
|
18
|
-
* - TODO(bajtos)
|
|
19
|
-
*
|
|
20
|
-
* @param bindingKey What binding to use in order to resolve the value
|
|
21
|
-
* of the annotated argument.
|
|
22
|
-
*/
|
|
23
|
-
export declare function inject(bindingKey: string): (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;
|
|
24
|
-
export declare function describeInjectedArguments(target: Function): string[];
|
package/lib/inject.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright IBM Corp. 2013,2017. All Rights Reserved.
|
|
3
|
-
// Node module: loopback
|
|
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
|
-
const assert = require("assert");
|
|
8
|
-
require("reflect-metadata");
|
|
9
|
-
const REFLECTION_KEY = 'loopback.inject';
|
|
10
|
-
/**
|
|
11
|
-
* A decorator to annotate method arguments for automatic injection
|
|
12
|
-
* by LoopBack IoC container.
|
|
13
|
-
*
|
|
14
|
-
* Usage - Typescript:
|
|
15
|
-
*
|
|
16
|
-
* ```ts
|
|
17
|
-
* class InfoController {
|
|
18
|
-
* constructor(@inject('application.name') public appName: string) {
|
|
19
|
-
* }
|
|
20
|
-
* // ...
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
* Usage - JavaScript:
|
|
25
|
-
*
|
|
26
|
-
* - TODO(bajtos)
|
|
27
|
-
*
|
|
28
|
-
* @param bindingKey What binding to use in order to resolve the value
|
|
29
|
-
* of the annotated argument.
|
|
30
|
-
*/
|
|
31
|
-
function inject(bindingKey) {
|
|
32
|
-
return function markArgumentAsInjected(target, propertyKey, parameterIndex) {
|
|
33
|
-
assert(parameterIndex != undefined, '@inject decorator can be used on function arguments only!');
|
|
34
|
-
const injectedArgs = Reflect.getOwnMetadata(REFLECTION_KEY, target, propertyKey) || [];
|
|
35
|
-
injectedArgs[parameterIndex] = bindingKey;
|
|
36
|
-
Reflect.defineMetadata(REFLECTION_KEY, injectedArgs, target, propertyKey);
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
exports.inject = inject;
|
|
40
|
-
function describeInjectedArguments(target) {
|
|
41
|
-
return Reflect.getOwnMetadata(REFLECTION_KEY, target) || [];
|
|
42
|
-
}
|
|
43
|
-
exports.describeInjectedArguments = describeInjectedArguments;
|
package/lib/isPromise.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function isPromise<T>(value: T | Promise<T>): value is Promise<T>;
|
package/lib/isPromise.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright IBM Corp. 2013,2017. All Rights Reserved.
|
|
3
|
-
// Node module: loopback
|
|
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
|
-
function isPromise(value) {
|
|
8
|
-
if (!value)
|
|
9
|
-
return false;
|
|
10
|
-
if (typeof value !== 'object' && typeof value !== 'function')
|
|
11
|
-
return false;
|
|
12
|
-
return typeof value.then === 'function';
|
|
13
|
-
}
|
|
14
|
-
exports.isPromise = isPromise;
|
package/lib/resolver.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { Context } from './context';
|
|
2
|
-
import { BoundValue } from './binding';
|
|
3
|
-
export declare type Constructor<T> = new (...args: any[]) => T;
|
|
4
|
-
/**
|
|
5
|
-
* Create an instance of a class which constructor has arguments
|
|
6
|
-
* decorated with `@inject`.
|
|
7
|
-
*
|
|
8
|
-
* The function returns a class when all dependencies were
|
|
9
|
-
* resolved synchronously, or a Promise otherwise.
|
|
10
|
-
*
|
|
11
|
-
* @param ctor The class constructor to call.
|
|
12
|
-
* @param ctx The context containing values for `@inject` resolution
|
|
13
|
-
*/
|
|
14
|
-
export declare function instantiateClass<T>(ctor: Constructor<T>, ctx: Context): T | Promise<T>;
|
|
15
|
-
/**
|
|
16
|
-
* Given a function with arguments decorated with `@inject`,
|
|
17
|
-
* return the list of arguments resolved using the values
|
|
18
|
-
* bound in `ctx`.
|
|
19
|
-
|
|
20
|
-
* The function returns an argument array when all dependencies were
|
|
21
|
-
* resolved synchronously, or a Promise otherwise.
|
|
22
|
-
*
|
|
23
|
-
* @param fn The function for which the arguments should be resolved.
|
|
24
|
-
* @param ctx The context containing values for `@inject` resolution
|
|
25
|
-
*/
|
|
26
|
-
export declare function resolveInjectedArguments(fn: Function, ctx: Context): BoundValue[] | Promise<BoundValue[]>;
|
package/lib/resolver.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright IBM Corp. 2013,2017. All Rights Reserved.
|
|
3
|
-
// Node module: loopback
|
|
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
|
-
const isPromise_1 = require("./isPromise");
|
|
8
|
-
const inject_1 = require("./inject");
|
|
9
|
-
/**
|
|
10
|
-
* Create an instance of a class which constructor has arguments
|
|
11
|
-
* decorated with `@inject`.
|
|
12
|
-
*
|
|
13
|
-
* The function returns a class when all dependencies were
|
|
14
|
-
* resolved synchronously, or a Promise otherwise.
|
|
15
|
-
*
|
|
16
|
-
* @param ctor The class constructor to call.
|
|
17
|
-
* @param ctx The context containing values for `@inject` resolution
|
|
18
|
-
*/
|
|
19
|
-
function instantiateClass(ctor, ctx) {
|
|
20
|
-
const argsOrPromise = resolveInjectedArguments(ctor, ctx);
|
|
21
|
-
if (isPromise_1.isPromise(argsOrPromise)) {
|
|
22
|
-
return argsOrPromise.then(args => new ctor(...args));
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
return new ctor(...argsOrPromise);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
exports.instantiateClass = instantiateClass;
|
|
29
|
-
/**
|
|
30
|
-
* Given a function with arguments decorated with `@inject`,
|
|
31
|
-
* return the list of arguments resolved using the values
|
|
32
|
-
* bound in `ctx`.
|
|
33
|
-
|
|
34
|
-
* The function returns an argument array when all dependencies were
|
|
35
|
-
* resolved synchronously, or a Promise otherwise.
|
|
36
|
-
*
|
|
37
|
-
* @param fn The function for which the arguments should be resolved.
|
|
38
|
-
* @param ctx The context containing values for `@inject` resolution
|
|
39
|
-
*/
|
|
40
|
-
function resolveInjectedArguments(fn, ctx) {
|
|
41
|
-
// NOTE: the array may be sparse, i.e.
|
|
42
|
-
// Object.keys(injectedArgs).length !== injectedArgs.length
|
|
43
|
-
// Example value:
|
|
44
|
-
// [ , 'key1', , 'key2']
|
|
45
|
-
const injectedArgs = inject_1.describeInjectedArguments(fn);
|
|
46
|
-
const args = new Array(fn.length);
|
|
47
|
-
let asyncResolvers = undefined;
|
|
48
|
-
for (let ix = 0; ix < fn.length; ix++) {
|
|
49
|
-
const bindingKey = injectedArgs[ix];
|
|
50
|
-
if (!bindingKey) {
|
|
51
|
-
throw new Error(`Cannot resolve injected arguments for function ${fn.name}: ` +
|
|
52
|
-
`The argument ${ix + 1} was not decorated for dependency injection.`);
|
|
53
|
-
}
|
|
54
|
-
const binding = ctx.getBinding(bindingKey);
|
|
55
|
-
const valueOrPromise = binding.getValue(ctx);
|
|
56
|
-
if (isPromise_1.isPromise(valueOrPromise)) {
|
|
57
|
-
if (!asyncResolvers)
|
|
58
|
-
asyncResolvers = [];
|
|
59
|
-
asyncResolvers.push(valueOrPromise.then((v) => args[ix] = v));
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
args[ix] = valueOrPromise;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (asyncResolvers) {
|
|
66
|
-
return Promise.all(asyncResolvers).then(() => args);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
return args;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
exports.resolveInjectedArguments = resolveInjectedArguments;
|
package/lib6/binding.d.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { Context } from './context';
|
|
2
|
-
import { Constructor } from './resolver';
|
|
3
|
-
export declare type BoundValue = any;
|
|
4
|
-
export declare class Binding {
|
|
5
|
-
private readonly _key;
|
|
6
|
-
isLocked: boolean;
|
|
7
|
-
private _tagName;
|
|
8
|
-
valueConstructor: Constructor<BoundValue>;
|
|
9
|
-
constructor(_key: string, isLocked?: boolean);
|
|
10
|
-
readonly key: string;
|
|
11
|
-
readonly tagName: string;
|
|
12
|
-
/**
|
|
13
|
-
* This is an internal function optimized for performance.
|
|
14
|
-
* Users should use `@inject(key)` or `ctx.get(key)` instead.
|
|
15
|
-
*
|
|
16
|
-
* Get the value bound to this key. Depending on `isSync`, this function returns either:
|
|
17
|
-
* - the bound value
|
|
18
|
-
* - a promise of the bound value
|
|
19
|
-
*
|
|
20
|
-
* Consumers wishing to consume sync values directly should use `isPromise`
|
|
21
|
-
* to check the type of the returned value to decide how to handle it.
|
|
22
|
-
*
|
|
23
|
-
* ```
|
|
24
|
-
* const result = binding.getValue(ctx);
|
|
25
|
-
* if (isPromise(result)) {
|
|
26
|
-
* result.then(doSomething)
|
|
27
|
-
* } else {
|
|
28
|
-
* doSomething(result);
|
|
29
|
-
* }
|
|
30
|
-
* ```
|
|
31
|
-
*/
|
|
32
|
-
getValue(ctx: Context): BoundValue | Promise<BoundValue>;
|
|
33
|
-
lock(): this;
|
|
34
|
-
tag(tagName: string): this;
|
|
35
|
-
/**
|
|
36
|
-
* Bind the key to a constant value.
|
|
37
|
-
*
|
|
38
|
-
* @param value The bound value.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
*
|
|
42
|
-
* ```ts
|
|
43
|
-
* ctx.bind('appName').to('CodeHub');
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
to(value: BoundValue): this;
|
|
47
|
-
/**
|
|
48
|
-
* Bind the key to a computed (dynamic) value.
|
|
49
|
-
*
|
|
50
|
-
* @param factoryFn The factory function creating the value.
|
|
51
|
-
* Both sync and async functions are supported.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
*
|
|
55
|
-
* ```ts
|
|
56
|
-
* // synchronous
|
|
57
|
-
* ctx.bind('now').toDynamicValue(() => Date.now());
|
|
58
|
-
*
|
|
59
|
-
* // asynchronous
|
|
60
|
-
* ctx.bind('something').toDynamicValue(
|
|
61
|
-
* async () => Promise.delay(10).then(doSomething)
|
|
62
|
-
* );
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
toDynamicValue(factoryFn: () => BoundValue | Promise<BoundValue>): this;
|
|
66
|
-
/**
|
|
67
|
-
* Bind the key to an instance of the given class.
|
|
68
|
-
*
|
|
69
|
-
* @param ctor The class constructor to call. Any constructor
|
|
70
|
-
* arguments must be annotated with `@inject` so that
|
|
71
|
-
* we can resolve them from the context.
|
|
72
|
-
*/
|
|
73
|
-
toClass<T>(ctor: Constructor<T>): this;
|
|
74
|
-
unlock(): this;
|
|
75
|
-
}
|
package/lib6/binding.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright IBM Corp. 2013,2017. All Rights Reserved.
|
|
3
|
-
// Node module: loopback
|
|
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
|
-
const resolver_1 = require("./resolver");
|
|
8
|
-
// FIXME(bajtos) The binding class should be parameterized by the value type stored
|
|
9
|
-
class Binding {
|
|
10
|
-
constructor(_key, isLocked = false) {
|
|
11
|
-
this._key = _key;
|
|
12
|
-
this.isLocked = isLocked;
|
|
13
|
-
}
|
|
14
|
-
get key() { return this._key; }
|
|
15
|
-
get tagName() { return this._tagName; }
|
|
16
|
-
/**
|
|
17
|
-
* This is an internal function optimized for performance.
|
|
18
|
-
* Users should use `@inject(key)` or `ctx.get(key)` instead.
|
|
19
|
-
*
|
|
20
|
-
* Get the value bound to this key. Depending on `isSync`, this function returns either:
|
|
21
|
-
* - the bound value
|
|
22
|
-
* - a promise of the bound value
|
|
23
|
-
*
|
|
24
|
-
* Consumers wishing to consume sync values directly should use `isPromise`
|
|
25
|
-
* to check the type of the returned value to decide how to handle it.
|
|
26
|
-
*
|
|
27
|
-
* ```
|
|
28
|
-
* const result = binding.getValue(ctx);
|
|
29
|
-
* if (isPromise(result)) {
|
|
30
|
-
* result.then(doSomething)
|
|
31
|
-
* } else {
|
|
32
|
-
* doSomething(result);
|
|
33
|
-
* }
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
getValue(ctx) {
|
|
37
|
-
return Promise.reject(new Error(`No value was configured for binding ${this._key}.`));
|
|
38
|
-
}
|
|
39
|
-
lock() {
|
|
40
|
-
this.isLocked = true;
|
|
41
|
-
return this;
|
|
42
|
-
}
|
|
43
|
-
tag(tagName) {
|
|
44
|
-
this._tagName = tagName;
|
|
45
|
-
return this;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Bind the key to a constant value.
|
|
49
|
-
*
|
|
50
|
-
* @param value The bound value.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
*
|
|
54
|
-
* ```ts
|
|
55
|
-
* ctx.bind('appName').to('CodeHub');
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
to(value) {
|
|
59
|
-
this.getValue = () => value;
|
|
60
|
-
return this;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Bind the key to a computed (dynamic) value.
|
|
64
|
-
*
|
|
65
|
-
* @param factoryFn The factory function creating the value.
|
|
66
|
-
* Both sync and async functions are supported.
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
*
|
|
70
|
-
* ```ts
|
|
71
|
-
* // synchronous
|
|
72
|
-
* ctx.bind('now').toDynamicValue(() => Date.now());
|
|
73
|
-
*
|
|
74
|
-
* // asynchronous
|
|
75
|
-
* ctx.bind('something').toDynamicValue(
|
|
76
|
-
* async () => Promise.delay(10).then(doSomething)
|
|
77
|
-
* );
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
toDynamicValue(factoryFn) {
|
|
81
|
-
// TODO(bajtos) allow factoryFn with @inject arguments
|
|
82
|
-
this.getValue = (ctx) => factoryFn();
|
|
83
|
-
return this;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Bind the key to an instance of the given class.
|
|
87
|
-
*
|
|
88
|
-
* @param ctor The class constructor to call. Any constructor
|
|
89
|
-
* arguments must be annotated with `@inject` so that
|
|
90
|
-
* we can resolve them from the context.
|
|
91
|
-
*/
|
|
92
|
-
toClass(ctor) {
|
|
93
|
-
this.getValue = context => resolver_1.instantiateClass(ctor, context);
|
|
94
|
-
this.valueConstructor = ctor;
|
|
95
|
-
return this;
|
|
96
|
-
}
|
|
97
|
-
unlock() {
|
|
98
|
-
this.isLocked = false;
|
|
99
|
-
return this;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
exports.Binding = Binding;
|
package/lib6/context.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Binding, BoundValue } from './binding';
|
|
2
|
-
export declare class Context {
|
|
3
|
-
private _parent;
|
|
4
|
-
private registry;
|
|
5
|
-
constructor(_parent?: Context);
|
|
6
|
-
bind(key: string): Binding;
|
|
7
|
-
contains(key: string): boolean;
|
|
8
|
-
find(pattern?: string): Binding[];
|
|
9
|
-
findByTag(pattern: string): Binding[];
|
|
10
|
-
protected _mergeWithParent(childList: Binding[], parentList?: Binding[]): Binding[];
|
|
11
|
-
get(key: string): Promise<BoundValue>;
|
|
12
|
-
getSync(key: string): BoundValue;
|
|
13
|
-
getBinding(key: string): Binding;
|
|
14
|
-
}
|