| @@ -9,7 +9,7 export class ActivationError { | |||||
| 9 |
|
9 | |||
| 10 | message: string; |
|
10 | message: string; | |
| 11 |
|
11 | |||
| 12 | constructor(service: string, activationStack: ActivationContextInfo[], innerException) { |
|
12 | constructor(service: string, activationStack: ActivationContextInfo[], innerException: any) { | |
| 13 | this.message = "Failed to activate the service"; |
|
13 | this.message = "Failed to activate the service"; | |
| 14 | this.activationStack = activationStack; |
|
14 | this.activationStack = activationStack; | |
| 15 | this.service = service; |
|
15 | this.service = service; | |
| @@ -2,10 +2,10 import { Descriptor, isDescriptor } from | |||||
| 2 | import { ActivationContext } from "./ActivationContext"; |
|
2 | import { ActivationContext } from "./ActivationContext"; | |
| 3 | import { isPrimitive } from "../safe"; |
|
3 | import { isPrimitive } from "../safe"; | |
| 4 |
|
4 | |||
| 5 | export class AggregateDescriptor implements Descriptor { |
|
5 | export class AggregateDescriptor<T> implements Descriptor<T> { | |
| 6 |
_value: |
|
6 | _value: T; | |
| 7 |
|
7 | |||
| 8 |
constructor(value: |
|
8 | constructor(value: T) { | |
| 9 | this._value = value; |
|
9 | this._value = value; | |
| 10 | } |
|
10 | } | |
| 11 |
|
11 | |||
| @@ -14,7 +14,7 export class AggregateDescriptor impleme | |||||
| 14 | } |
|
14 | } | |
| 15 |
|
15 | |||
| 16 | // TODO: make async |
|
16 | // TODO: make async | |
| 17 | _parse(value, context: ActivationContext, path: string) { |
|
17 | _parse(value: T, context: ActivationContext, path: string) { | |
| 18 | if (isPrimitive(value)) |
|
18 | if (isPrimitive(value)) | |
| 19 | return value; |
|
19 | return value; | |
| 20 |
|
20 | |||
| @@ -28,7 +28,7 import { ICancellation } from "../interf | |||||
| 28 |
|
28 | |||
| 29 | const trace = TraceSource.get("@implab/core/di/Configuration"); |
|
29 | const trace = TraceSource.get("@implab/core/di/Configuration"); | |
| 30 |
|
30 | |||
| 31 |
async function mapAll(data: |
|
31 | async function mapAll(data: any | any[], map?: (v: any, k: keyof any) => any): Promise<any> { | |
| 32 | if (data instanceof Array) { |
|
32 | if (data instanceof Array) { | |
| 33 | return Promise.all(map ? data.map(map) : data); |
|
33 | return Promise.all(map ? data.map(map) : data); | |
| 34 | } else { |
|
34 | } else { | |
| @@ -57,9 +57,9 export class Configuration { | |||||
| 57 |
|
57 | |||
| 58 | _path: Array<_key>; |
|
58 | _path: Array<_key>; | |
| 59 |
|
59 | |||
| 60 | _configName: string; |
|
60 | _configName: string | undefined; | |
| 61 |
|
61 | |||
| 62 | _require: ModuleResolver; |
|
62 | _require: ModuleResolver | undefined; | |
| 63 |
|
63 | |||
| 64 | constructor(container: Container) { |
|
64 | constructor(container: Container) { | |
| 65 | argumentNotNull(container, "container"); |
|
65 | argumentNotNull(container, "container"); | |
| @@ -78,7 +78,7 export class Configuration { | |||||
| 78 |
|
78 | |||
| 79 | this._configName = moduleName; |
|
79 | this._configName = moduleName; | |
| 80 |
|
80 | |||
| 81 |
const r = await makeResolver( |
|
81 | const r = await makeResolver(undefined, contextRequire); | |
| 82 |
|
82 | |||
| 83 | const config = await r(moduleName, ct); |
|
83 | const config = await r(moduleName, ct); | |
| 84 |
|
84 | |||
| @@ -114,9 +114,9 export class Configuration { | |||||
| 114 | this._container.register(services); |
|
114 | this._container.register(services); | |
| 115 | } |
|
115 | } | |
| 116 |
|
116 | |||
| 117 | _makeError(inner) { |
|
117 | _makeError(inner: any) { | |
| 118 | const e = new ConfigError("Failed to load configuration", inner); |
|
118 | const e = new ConfigError("Failed to load configuration", inner); | |
| 119 | e.configName = this._configName; |
|
119 | e.configName = this._configName || "<inline>"; | |
| 120 | e.path = this._makePath(); |
|
120 | e.path = this._makePath(); | |
| 121 | return e; |
|
121 | return e; | |
| 122 | } |
|
122 | } | |
| @@ -144,11 +144,13 export class Configuration { | |||||
| 144 |
|
144 | |||
| 145 | _loadModule(moduleName: string) { |
|
145 | _loadModule(moduleName: string) { | |
| 146 | trace.debug("loadModule {0}", moduleName); |
|
146 | trace.debug("loadModule {0}", moduleName); | |
|
|
147 | if (!this._require) | |||
|
|
148 | throw new Error("Module loader isn't specified"); | |||
| 147 |
|
149 | |||
| 148 | return this._require(moduleName); |
|
150 | return this._require(moduleName); | |
| 149 | } |
|
151 | } | |
| 150 |
|
152 | |||
| 151 | async _visitRegistrations(data, name: _key) { |
|
153 | async _visitRegistrations(data: any, name: _key) { | |
| 152 | this._enter(name); |
|
154 | this._enter(name); | |
| 153 |
|
155 | |||
| 154 | if (data.constructor && |
|
156 | if (data.constructor && | |
| @@ -168,8 +170,8 export class Configuration { | |||||
| 168 | return services; |
|
170 | return services; | |
| 169 | } |
|
171 | } | |
| 170 |
|
172 | |||
| 171 |
_enter(name: |
|
173 | _enter(name: keyof any) { | |
| 172 | this._path.push(name); |
|
174 | this._path.push(name.toString()); | |
| 173 | trace.debug(">{0}", name); |
|
175 | trace.debug(">{0}", name); | |
| 174 | } |
|
176 | } | |
| 175 |
|
177 | |||
| @@ -178,7 +180,7 export class Configuration { | |||||
| 178 | trace.debug("<{0}", name); |
|
180 | trace.debug("<{0}", name); | |
| 179 | } |
|
181 | } | |
| 180 |
|
182 | |||
| 181 |
async _visit(data, name: |
|
183 | async _visit<T extends object>(data: T, name: keyof T) { | |
| 182 | if (isPrimitive(data) || isDescriptor(data)) |
|
184 | if (isPrimitive(data) || isDescriptor(data)) | |
| 183 | return data; |
|
185 | return data; | |
| 184 |
|
186 | |||
| @@ -233,7 +235,7 export class Configuration { | |||||
| 233 | return v; |
|
235 | return v; | |
| 234 | } |
|
236 | } | |
| 235 |
|
237 | |||
| 236 | _makeServiceParams(data: ServiceRegistration) { |
|
238 | _makeServiceParams<T, P, S>(data: ServiceRegistration<T, P, S>) { | |
| 237 | const opts: any = { |
|
239 | const opts: any = { | |
| 238 | owner: this._container |
|
240 | owner: this._container | |
| 239 | }; |
|
241 | }; | |
| @@ -289,17 +291,17 export class Configuration { | |||||
| 289 | return opts; |
|
291 | return opts; | |
| 290 | } |
|
292 | } | |
| 291 |
|
293 | |||
| 292 | async _visitValueRegistration(data: ValueRegistration, name: _key) { |
|
294 | async _visitValueRegistration<T>(data: ValueRegistration<T>, name: _key) { | |
| 293 | this._enter(name); |
|
295 | this._enter(name); | |
| 294 | const d = data.parse ? new AggregateDescriptor(data.$value) : new ValueDescriptor(data.$value); |
|
296 | const d = data.parse ? new AggregateDescriptor(data.$value) : new ValueDescriptor(data.$value); | |
| 295 | this._leave(); |
|
297 | this._leave(); | |
| 296 | return d; |
|
298 | return d; | |
| 297 | } |
|
299 | } | |
| 298 |
|
300 | |||
| 299 |
async _visitDependencyRegistration(data: DependencyRegistration, name: |
|
301 | async _visitDependencyRegistration<S, K extends keyof S>(data: DependencyRegistration<S, K>, name: keyof S) { | |
| 300 | argumentNotEmptyString(data && data.$dependency, "data.$dependency"); |
|
302 | argumentNotEmptyString(data && data.$dependency, "data.$dependency"); | |
| 301 | this._enter(name); |
|
303 | this._enter(name); | |
| 302 | const d = new ReferenceDescriptor({ |
|
304 | const d = new ReferenceDescriptor<S, K>({ | |
| 303 | name: data.$dependency, |
|
305 | name: data.$dependency, | |
| 304 | lazy: data.lazy, |
|
306 | lazy: data.lazy, | |
| 305 | optional: data.optional, |
|
307 | optional: data.optional, | |
| @@ -310,7 +312,7 export class Configuration { | |||||
| 310 | return d; |
|
312 | return d; | |
| 311 | } |
|
313 | } | |
| 312 |
|
314 | |||
| 313 | async _visitTypeRegistration(data: TypeRegistration, name: _key) { |
|
315 | async _visitTypeRegistration<T, P, S>(data: TypeRegistration<T, P, S>, name: _key) { | |
| 314 | argumentNotNull(data.$type, "data.$type"); |
|
316 | argumentNotNull(data.$type, "data.$type"); | |
| 315 | this._enter(name); |
|
317 | this._enter(name); | |
| 316 |
|
318 | |||
| @@ -331,7 +333,7 export class Configuration { | |||||
| 331 | return d; |
|
333 | return d; | |
| 332 | } |
|
334 | } | |
| 333 |
|
335 | |||
| 334 | async _visitFactoryRegistration(data: FactoryRegistration, name: _key) { |
|
336 | async _visitFactoryRegistration<T, P, S>(data: FactoryRegistration<T, P, S>, name: _key) { | |
| 335 | argumentOfType(data.$factory, Function, "data.$factory"); |
|
337 | argumentOfType(data.$factory, Function, "data.$factory"); | |
| 336 | this._enter(name); |
|
338 | this._enter(name); | |
| 337 |
|
339 | |||
| @@ -3,16 +3,16 import { ActivationContext } from "./Act | |||||
| 3 | import { ServiceMap, Descriptor } from "./interfaces"; |
|
3 | import { ServiceMap, Descriptor } from "./interfaces"; | |
| 4 | import { ActivationError } from "./ActivationError"; |
|
4 | import { ActivationError } from "./ActivationError"; | |
| 5 |
|
5 | |||
| 6 | export interface ReferenceDescriptorParams { |
|
6 | export interface ReferenceDescriptorParams<S, K extends keyof S> { | |
| 7 |
name: |
|
7 | name: K; | |
| 8 | lazy?: boolean; |
|
8 | lazy?: boolean; | |
| 9 | optional?: boolean; |
|
9 | optional?: boolean; | |
| 10 | default?; |
|
10 | default?: S[K]; | |
| 11 | services?: ServiceMap; |
|
11 | services?: ServiceMap; | |
| 12 | } |
|
12 | } | |
| 13 |
|
13 | |||
| 14 | export class ReferenceDescriptor implements Descriptor { |
|
14 | export class ReferenceDescriptor<S, K extends keyof S> implements Descriptor<S[K]> { | |
| 15 |
_name: |
|
15 | _name: K; | |
| 16 |
|
16 | |||
| 17 | _lazy = false; |
|
17 | _lazy = false; | |
| 18 |
|
18 | |||
| @@ -22,13 +22,14 export class ReferenceDescriptor impleme | |||||
| 22 |
|
22 | |||
| 23 | _services: ServiceMap; |
|
23 | _services: ServiceMap; | |
| 24 |
|
24 | |||
| 25 | constructor(opts: ReferenceDescriptorParams) { |
|
25 | constructor(opts: ReferenceDescriptorParams<S, K>) { | |
| 26 | argumentNotEmptyString(opts && opts.name, "opts.name"); |
|
26 | argumentNotEmptyString(opts && opts.name, "opts.name"); | |
| 27 | this._name = opts.name; |
|
27 | this._name = opts.name; | |
| 28 | this._lazy = !!opts.lazy; |
|
28 | this._lazy = !!opts.lazy; | |
| 29 | this._optional = !!opts.optional; |
|
29 | this._optional = !!opts.optional; | |
| 30 | this._default = opts.default; |
|
30 | this._default = opts.default; | |
| 31 | this._services = opts.services; |
|
31 | ||
|
|
32 | this._services = opts.services || {}; | |||
| 32 | } |
|
33 | } | |
| 33 |
|
34 | |||
| 34 | activate(context: ActivationContext, name: string) { |
|
35 | activate(context: ActivationContext, name: string) { | |
| @@ -54,7 +55,7 export class ReferenceDescriptor impleme | |||||
| 54 | return this._optional ? ct.resolve(this._name, this._default) : ct |
|
55 | return this._optional ? ct.resolve(this._name, this._default) : ct | |
| 55 | .resolve(this._name); |
|
56 | .resolve(this._name); | |
| 56 | } catch (error) { |
|
57 | } catch (error) { | |
| 57 | throw new ActivationError(this._name, ct.getStack(), error); |
|
58 | throw new ActivationError(this._name.toString(), ct.getStack(), error); | |
| 58 | } |
|
59 | } | |
| 59 | }; |
|
60 | }; | |
| 60 | } else { |
|
61 | } else { | |
| @@ -88,7 +89,7 export class ReferenceDescriptor impleme | |||||
| 88 | parts.push("} "); |
|
89 | parts.push("} "); | |
| 89 | } |
|
90 | } | |
| 90 |
|
91 | |||
| 91 | parts.push(this._name); |
|
92 | parts.push(this._name.toString()); | |
| 92 |
|
93 | |||
| 93 | if (!isNull(this._default)) { |
|
94 | if (!isNull(this._default)) { | |
| 94 | parts.push(" = "); |
|
95 | parts.push(" = "); | |
| @@ -1,9 +1,9 | |||||
| 1 | import { Descriptor } from "./interfaces"; |
|
1 | import { Descriptor } from "./interfaces"; | |
| 2 |
|
2 | |||
| 3 | export class ValueDescriptor implements Descriptor { |
|
3 | export class ValueDescriptor<T> implements Descriptor<T> { | |
| 4 | _value; |
|
4 | _value: T; | |
| 5 |
|
5 | |||
| 6 | constructor(value) { |
|
6 | constructor(value: T) { | |
| 7 | this._value = value; |
|
7 | this._value = value; | |
| 8 | } |
|
8 | } | |
| 9 |
|
9 | |||
| @@ -1,18 +1,18 | |||||
| 1 |
import { |
|
1 | import { isPrimitive } from "../safe"; | |
| 2 | import { ActivationContext } from "./ActivationContext"; |
|
2 | import { ActivationContext } from "./ActivationContext"; | |
| 3 | import { Constructor, Factory } from "../interfaces"; |
|
3 | import { Constructor, Factory } from "../interfaces"; | |
| 4 |
|
4 | |||
| 5 | export interface Descriptor { |
|
5 | export interface Descriptor<T = any> { | |
| 6 | activate(context: ActivationContext, name?: string); |
|
6 | activate(context: ActivationContext, name?: string): T; | |
| 7 | } |
|
7 | } | |
| 8 |
|
8 | |||
| 9 | export function isDescriptor(x): x is Descriptor { |
|
9 | export function isDescriptor(x: any): x is Descriptor { | |
| 10 | return (!isPrimitive(x)) && |
|
10 | return (!isPrimitive(x)) && | |
| 11 | (x.activate instanceof Function); |
|
11 | (x.activate instanceof Function); | |
| 12 | } |
|
12 | } | |
| 13 |
|
13 | |||
| 14 |
export |
|
14 | export type ServiceMap<S = any> = { | |
| 15 |
[ |
|
15 | [k in keyof S]: Descriptor<S[k]>; | |
| 16 | } |
|
16 | } | |
| 17 |
|
17 | |||
| 18 | export enum ActivationType { |
|
18 | export enum ActivationType { | |
| @@ -23,53 +23,53 export enum ActivationType { | |||||
| 23 | Call |
|
23 | Call | |
| 24 | } |
|
24 | } | |
| 25 |
|
25 | |||
| 26 | export interface RegistrationWithServices { |
|
26 | export interface RegistrationWithServices<S> { | |
| 27 |
services?: |
|
27 | services?: ServiceMap<S>; | |
| 28 | } |
|
28 | } | |
| 29 |
|
29 | |||
| 30 | export interface ServiceRegistration extends RegistrationWithServices { |
|
30 | export interface ServiceRegistration<T, P, S> extends RegistrationWithServices<S> { | |
| 31 |
|
31 | |||
| 32 | activation?: "singleton" | "container" | "hierarchy" | "context" | "call"; |
|
32 | activation?: "singleton" | "container" | "hierarchy" | "context" | "call"; | |
| 33 |
|
33 | |||
| 34 | params?; |
|
34 | params?: P; | |
| 35 |
|
35 | |||
| 36 | inject?: object | object[]; |
|
36 | inject?: object | object[]; | |
| 37 |
|
37 | |||
| 38 | cleanup?: (instance) => void | string; |
|
38 | cleanup?: ((instance: T) => void) | string; | |
| 39 | } |
|
39 | } | |
| 40 |
|
40 | |||
| 41 | export interface TypeRegistration extends ServiceRegistration { |
|
41 | export interface TypeRegistration<T, P, S> extends ServiceRegistration<T, P, S> { | |
| 42 | $type: string | Constructor; |
|
42 | $type: string | Constructor<T>; | |
| 43 | } |
|
43 | } | |
| 44 |
|
44 | |||
| 45 | export interface FactoryRegistration extends ServiceRegistration { |
|
45 | export interface FactoryRegistration<T, P, S> extends ServiceRegistration<T, P, S> { | |
| 46 | $factory: string | Factory; |
|
46 | $factory: string | Factory<T>; | |
| 47 | } |
|
47 | } | |
| 48 |
|
48 | |||
| 49 | export interface ValueRegistration { |
|
49 | export interface ValueRegistration<T> { | |
| 50 | $value; |
|
50 | $value: T; | |
| 51 | parse?: boolean; |
|
51 | parse?: boolean; | |
| 52 | } |
|
52 | } | |
| 53 |
|
53 | |||
| 54 | export interface DependencyRegistration extends RegistrationWithServices { |
|
54 | export interface DependencyRegistration<S, K extends keyof S> extends RegistrationWithServices<S> { | |
| 55 |
$dependency: |
|
55 | $dependency: K; | |
| 56 | lazy?: boolean; |
|
56 | lazy?: boolean; | |
| 57 | optional?: boolean; |
|
57 | optional?: boolean; | |
| 58 | default?; |
|
58 | default?: S[K]; | |
| 59 | } |
|
59 | } | |
| 60 |
|
60 | |||
| 61 | export function isTypeRegistration(x): x is TypeRegistration { |
|
61 | export function isTypeRegistration(x: any): x is TypeRegistration<any, any, any> { | |
| 62 | return (!isPrimitive(x)) && ("$type" in x); |
|
62 | return (!isPrimitive(x)) && ("$type" in x); | |
| 63 | } |
|
63 | } | |
| 64 |
|
64 | |||
| 65 | export function isFactoryRegistration(x): x is FactoryRegistration { |
|
65 | export function isFactoryRegistration(x: any): x is FactoryRegistration<any, any, any> { | |
| 66 | return (!isPrimitive(x)) && ("$factory" in x); |
|
66 | return (!isPrimitive(x)) && ("$factory" in x); | |
| 67 | } |
|
67 | } | |
| 68 |
|
68 | |||
| 69 | export function isValueRegistration(x): x is ValueRegistration { |
|
69 | export function isValueRegistration(x: any): x is ValueRegistration<any> { | |
| 70 | return (!isPrimitive(x)) && ("$value" in x); |
|
70 | return (!isPrimitive(x)) && ("$value" in x); | |
| 71 | } |
|
71 | } | |
| 72 |
|
72 | |||
| 73 | export function isDependencyRegistration(x): x is DependencyRegistration { |
|
73 | export function isDependencyRegistration(x: any): x is DependencyRegistration<any, string | number | symbol> { | |
| 74 | return (!isPrimitive(x)) && ("$dependency" in x); |
|
74 | return (!isPrimitive(x)) && ("$dependency" in x); | |
| 75 | } |
|
75 | } | |
General Comments 0
You need to be logged in to leave comments.
Login now
