1 |
|
2 | import { EventEmitter } from 'events';
|
3 | import { BindingAddress } from './binding-key';
|
4 | import { Context } from './context';
|
5 | import { JSONObject } from './json-types';
|
6 | import { Provider } from './provider';
|
7 | import { ResolutionContext, ResolutionOptions, ResolutionSession } from './resolution-session';
|
8 | import { BoundValue, Constructor, MapObject, ValueOrPromise } from './value-promise';
|
9 |
|
10 |
|
11 |
|
12 | export declare enum BindingScope {
|
13 | |
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | TRANSIENT = "Transient",
|
32 | |
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | CONTEXT = "Context",
|
61 | |
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 | SINGLETON = "Singleton",
|
83 | |
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | APPLICATION = "Application",
|
94 | |
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 | SERVER = "Server",
|
116 | |
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 | REQUEST = "Request"
|
129 | }
|
130 |
|
131 |
|
132 |
|
133 | export declare enum BindingType {
|
134 | |
135 |
|
136 |
|
137 | CONSTANT = "Constant",
|
138 | |
139 |
|
140 |
|
141 | DYNAMIC_VALUE = "DynamicValue",
|
142 | |
143 |
|
144 |
|
145 | CLASS = "Class",
|
146 | |
147 |
|
148 |
|
149 | PROVIDER = "Provider",
|
150 | |
151 |
|
152 |
|
153 | ALIAS = "Alias"
|
154 | }
|
155 |
|
156 |
|
157 |
|
158 | export type ConstantBindingSource<T> = {
|
159 | type: BindingType.CONSTANT;
|
160 | value: T;
|
161 | };
|
162 |
|
163 |
|
164 |
|
165 | export type DynamicValueBindingSource<T> = {
|
166 | type: BindingType.DYNAMIC_VALUE;
|
167 | value: ValueFactory<T> | DynamicValueProviderClass<T>;
|
168 | };
|
169 |
|
170 |
|
171 |
|
172 | export type ClassBindingSource<T> = {
|
173 | type: BindingType.CLASS;
|
174 | value: Constructor<T>;
|
175 | };
|
176 |
|
177 |
|
178 |
|
179 | export type ProviderBindingSource<T> = {
|
180 | type: BindingType.PROVIDER;
|
181 | value: Constructor<Provider<T>>;
|
182 | };
|
183 |
|
184 |
|
185 |
|
186 | export type AliasBindingSource<T> = {
|
187 | type: BindingType.ALIAS;
|
188 | value: BindingAddress<T>;
|
189 | };
|
190 |
|
191 |
|
192 |
|
193 | export type BindingSource<T> = ConstantBindingSource<T> | DynamicValueBindingSource<T> | ClassBindingSource<T> | ProviderBindingSource<T> | AliasBindingSource<T>;
|
194 | export type TagMap = MapObject<any>;
|
195 |
|
196 |
|
197 |
|
198 | export type BindingTag = TagMap | string;
|
199 |
|
200 |
|
201 |
|
202 | export type BindingTemplate<T = unknown> = (binding: Binding<T>) => void;
|
203 |
|
204 |
|
205 |
|
206 | export type BindingEvent = {
|
207 | |
208 |
|
209 |
|
210 | type: 'changed' | string;
|
211 | |
212 |
|
213 |
|
214 | binding: Readonly<Binding<unknown>>;
|
215 | |
216 |
|
217 |
|
218 | operation: 'tag' | 'scope' | 'value' | string;
|
219 | };
|
220 |
|
221 |
|
222 |
|
223 | export type BindingEventListener = (
|
224 |
|
225 |
|
226 |
|
227 | event: BindingEvent) => void;
|
228 |
|
229 |
|
230 |
|
231 | export type ValueFactory<T = unknown> = (resolutionCtx: ResolutionContext) => ValueOrPromise<T | undefined>;
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 |
|
247 | export interface DynamicValueProviderClass<T = unknown> extends Constructor<unknown>, Function {
|
248 | value: (...args: BoundValue[]) => ValueOrPromise<T>;
|
249 | }
|
250 |
|
251 |
|
252 |
|
253 |
|
254 | export declare function isDynamicValueProviderClass<T = unknown>(factory: unknown): factory is DynamicValueProviderClass<T>;
|
255 |
|
256 |
|
257 |
|
258 |
|
259 | export declare class Binding<T = BoundValue> extends EventEmitter {
|
260 | isLocked: boolean;
|
261 | |
262 |
|
263 |
|
264 | readonly key: string;
|
265 | |
266 |
|
267 |
|
268 | readonly tagMap: TagMap;
|
269 | private _scope?;
|
270 | |
271 |
|
272 |
|
273 | get scope(): BindingScope;
|
274 | |
275 |
|
276 |
|
277 | get type(): BindingType | undefined;
|
278 | private _cache;
|
279 | private _getValue?;
|
280 | |
281 |
|
282 |
|
283 |
|
284 | private _source?;
|
285 | get source(): BindingSource<T> | undefined;
|
286 | |
287 |
|
288 |
|
289 |
|
290 | get valueConstructor(): Constructor<T> | undefined;
|
291 | |
292 |
|
293 |
|
294 |
|
295 | get providerConstructor(): Constructor<Provider<T>> | undefined;
|
296 | constructor(key: BindingAddress<T>, isLocked?: boolean);
|
297 | /**
|
298 | * Cache the resolved value by the binding scope
|
299 | * @param resolutionCtx - The resolution context
|
300 | * @param result - The calculated value for the binding
|
301 | */
|
302 | private _cacheValue;
|
303 | /**
|
304 | * Clear the cache
|
305 | */
|
306 | private _clearCache;
|
307 | /**
|
308 | * Invalidate the binding cache so that its value will be reloaded next time.
|
309 | * This is useful to force reloading a cached value when its configuration or
|
310 | * dependencies are changed.
|
311 | * **WARNING**: The state held in the cached value will be gone.
|
312 | *
|
313 | * @param ctx - Context object
|
314 | */
|
315 | refresh(ctx: Context): void;
|
316 | /**
|
317 | * This is an internal function optimized for performance.
|
318 | * Users should use `@inject(key)` or `ctx.get(key)` instead.
|
319 | *
|
320 | * Get the value bound to this key. Depending on `isSync`, this
|
321 | * function returns either:
|
322 | * - the bound value
|
323 | * - a promise of the bound value
|
324 | *
|
325 | * Consumers wishing to consume sync values directly should use `isPromiseLike`
|
326 | * to check the type of the returned value to decide how to handle it.
|
327 | *
|
328 | * @example
|
329 | * ```
|
330 | * const result = binding.getValue(ctx);
|
331 | * if (isPromiseLike(result)) {
|
332 | * result.then(doSomething)
|
333 | * } else {
|
334 | * doSomething(result);
|
335 | * }
|
336 | * ```
|
337 | *
|
338 | * @param ctx - Context for the resolution
|
339 | * @param session - Optional session for binding and dependency resolution
|
340 | */
|
341 | getValue(ctx: Context, session?: ResolutionSession): ValueOrPromise<T>;
|
342 | /**
|
343 | * Returns a value or promise for this binding in the given context. The
|
344 | * resolved value can be `undefined` if `optional` is set to `true` in
|
345 | * `options`.
|
346 | * @param ctx - Context for the resolution
|
347 | * @param options - Optional options for binding and dependency resolution
|
348 | */
|
349 | getValue(ctx: Context, options?: ResolutionOptions): ValueOrPromise<T | undefined>;
|
350 | private getValueOrProxy;
|
351 | /**
|
352 | * Locate and validate the resolution context
|
353 | * @param ctx - Current context
|
354 | * @param options - Resolution options
|
355 | */
|
356 | private getResolutionContext;
|
357 | /**
|
358 | * Lock the binding so that it cannot be rebound
|
359 | */
|
360 | lock(): this;
|
361 | /**
|
362 | * Emit a `changed` event
|
363 | * @param operation - Operation that makes changes
|
364 | */
|
365 | private emitChangedEvent;
|
366 | /**
|
367 | * Tag the binding with names or name/value objects. A tag has a name and
|
368 | * an optional value. If not supplied, the tag name is used as the value.
|
369 | *
|
370 | * @param tags - A list of names or name/value objects. Each
|
371 | * parameter can be in one of the following forms:
|
372 | * - string: A tag name without value
|
373 | * - string[]: An array of tag names
|
374 | * - TagMap: A map of tag name/value pairs
|
375 | *
|
376 | * @example
|
377 | * ```ts
|
378 | *
|
379 | * binding.tag('controller');
|
380 | *
|
381 | *
|
382 | * binding.tag('controller', 'rest');
|
383 | *
|
384 | *
|
385 | *
|
386 | *
|
387 | * binding.tag('controller', {name: 'my-controller'});
|
388 | *
|
389 | * ```
|
390 | */
|
391 | tag(...tags: BindingTag[]): this;
|
392 | /**
|
393 | * Get an array of tag names
|
394 | */
|
395 | get tagNames(): string[];
|
396 | /**
|
397 | * Set the binding scope
|
398 | * @param scope - Binding scope
|
399 | */
|
400 | inScope(scope: BindingScope): this;
|
401 | /**
|
402 | * Apply default scope to the binding. It only changes the scope if it's not
|
403 | * set yet
|
404 | * @param scope - Default binding scope
|
405 | */
|
406 | applyDefaultScope(scope: BindingScope): this;
|
407 | /**
|
408 | * Set the `_getValue` function
|
409 | * @param getValue - getValue function
|
410 | */
|
411 | private _setValueGetter;
|
412 | /**
|
413 | * Bind the key to a constant value. The value must be already available
|
414 | * at binding time, it is not allowed to pass a Promise instance.
|
415 | *
|
416 | * @param value - The bound value.
|
417 | *
|
418 | * @example
|
419 | *
|
420 | * ```ts
|
421 | * ctx.bind('appName').to('CodeHub');
|
422 | * ```
|
423 | */
|
424 | to(value: T): this;
|
425 | /**
|
426 | * Bind the key to a computed (dynamic) value.
|
427 | *
|
428 | * @param factoryFn - The factory function creating the value.
|
429 | * Both sync and async functions are supported.
|
430 | *
|
431 | * @example
|
432 | *
|
433 | * ```ts
|
434 | *
|
435 | * ctx.bind('now').toDynamicValue(() => Date.now());
|
436 | *
|
437 | *
|
438 | * ctx.bind('something').toDynamicValue(
|
439 | * async () => Promise.delay(10).then(doSomething)
|
440 | * );
|
441 | * ```
|
442 | */
|
443 | toDynamicValue(factory: ValueFactory<T> | DynamicValueProviderClass<T>): this;
|
444 | private static valueOrProxy;
|
445 | /**
|
446 | * Bind the key to a value computed by a Provider.
|
447 | *
|
448 | * * @example
|
449 | *
|
450 | * ```ts
|
451 | * export class DateProvider implements Provider<Date> {
|
452 | * constructor(@inject('stringDate') private param: String){}
|
453 | * value(): Date {
|
454 | * return new Date(param);
|
455 | * }
|
456 | * }
|
457 | * ```
|
458 | *
|
459 | * @param provider - The value provider to use.
|
460 | */
|
461 | toProvider(providerClass: Constructor<Provider<T>>): this;
|
462 | /**
|
463 | * Bind the key to an instance of the given class.
|
464 | *
|
465 | * @param ctor - The class constructor to call. Any constructor
|
466 | * arguments must be annotated with `@inject` so that
|
467 | * we can resolve them from the context.
|
468 | */
|
469 | toClass<C extends T & object>(ctor: Constructor<C>): this;
|
470 | /**
|
471 | * Bind to a class optionally decorated with `@injectable`. Based on the
|
472 | * introspection of the class, it calls `toClass/toProvider/toDynamicValue`
|
473 | * internally. The current binding key will be preserved (not being overridden
|
474 | * by the key inferred from the class or options).
|
475 | *
|
476 | * This is similar to {@link createBindingFromClass} but applies to an
|
477 | * existing binding.
|
478 | *
|
479 | * @example
|
480 | *
|
481 | * ```ts
|
482 | * @injectable({scope: BindingScope.SINGLETON, tags: {service: 'MyService}})
|
483 | * class MyService {
|
484 | *
|
485 | * }
|
486 | *
|
487 | * const ctx = new Context();
|
488 | * ctx.bind('services.MyService').toInjectable(MyService);
|
489 | * ```
|
490 | *
|
491 | * @param ctor - A class decorated with `@injectable`.
|
492 | */
|
493 | toInjectable(ctor: DynamicValueProviderClass<T> | Constructor<T | Provider<T>>): this;
|
494 | /**
|
495 | * Bind the key to an alias of another binding
|
496 | * @param keyWithPath - Target binding key with optional path,
|
497 | * such as `servers.RestServer.options#apiExplorer`
|
498 | */
|
499 | toAlias(keyWithPath: BindingAddress<T>): this;
|
500 | /**
|
501 | * Unlock the binding
|
502 | */
|
503 | unlock(): this;
|
504 | /**
|
505 | * Apply one or more template functions to set up the binding with scope,
|
506 | * tags, and other attributes as a group.
|
507 | *
|
508 | * @example
|
509 | * ```ts
|
510 | * const serverTemplate = (binding: Binding) =>
|
511 | * binding.inScope(BindingScope.SINGLETON).tag('server');
|
512 | *
|
513 | * const serverBinding = new Binding<RestServer>('servers.RestServer1');
|
514 | * serverBinding.apply(serverTemplate);
|
515 | * ```
|
516 | * @param templateFns - One or more functions to configure the binding
|
517 | */
|
518 | apply(...templateFns: BindingTemplate<T>[]): this;
|
519 | /**
|
520 | * Convert to a plain JSON object
|
521 | */
|
522 | toJSON(): JSONObject;
|
523 | /**
|
524 | * Inspect the binding to return a json representation of the binding information
|
525 | * @param options - Options to control what information should be included
|
526 | */
|
527 | inspect(options?: BindingInspectOptions): JSONObject;
|
528 | /**
|
529 | * A static method to create a binding so that we can do
|
530 | * `Binding.bind('foo').to('bar');` as `new Binding('foo').to('bar')` is not
|
531 | * easy to read.
|
532 | * @param key - Binding key
|
533 | */
|
534 | static bind<V = unknown>(key: BindingAddress<V>): Binding<V>;
|
535 | /**
|
536 | * Create a configuration binding for the given key
|
537 | *
|
538 | * @example
|
539 | * ```ts
|
540 | * const configBinding = Binding.configure('servers.RestServer.server1')
|
541 | * .to({port: 3000});
|
542 | * ```
|
543 | *
|
544 | * @typeParam V Generic type for the configuration value (not the binding to
|
545 | * be configured)
|
546 | *
|
547 | * @param key - Key for the binding to be configured
|
548 | */
|
549 | static configure<V = unknown>(key: BindingAddress): Binding<V>;
|
550 | /**
|
551 | * The "changed" event is emitted by methods such as `tag`, `inScope`, `to`,
|
552 | * and `toClass`.
|
553 | *
|
554 | * @param eventName The name of the event - always `changed`.
|
555 | * @param listener The listener function to call when the event is emitted.
|
556 | */
|
557 | on(eventName: 'changed', listener: BindingEventListener): this;
|
558 | on(event: string | symbol, listener: (...args: any[]) => void): this;
|
559 | /**
|
560 | * The "changed" event is emitted by methods such as `tag`, `inScope`, `to`,
|
561 | * and `toClass`.
|
562 | *
|
563 | * @param eventName The name of the event - always `changed`.
|
564 | * @param listener The listener function to call when the event is emitted.
|
565 | */
|
566 | once(eventName: 'changed', listener: BindingEventListener): this;
|
567 | once(event: string | symbol, listener: (...args: any[]) => void): this;
|
568 | }
|
569 | /**
|
570 | * Options for binding.inspect()
|
571 | */
|
572 | export interface BindingInspectOptions {
|
573 | /**
|
574 | * The flag to control if injections should be inspected
|
575 | */
|
576 | includeInjections?: boolean;
|
577 | }
|
578 |
|
\ | No newline at end of file |