@spinajs/di 1.0.18 → 1.2.7

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/lib/array.d.ts CHANGED
@@ -1,5 +1,9 @@
1
- /// <reference path="../typings/array.d.ts" />
2
1
  import { Class } from './types';
2
+ declare global {
3
+ interface ArrayConstructor {
4
+ ofType<T>(type: Class<T>): TypedArray<T>;
5
+ }
6
+ }
3
7
  export declare class TypedArray<R> extends Array<R> {
4
8
  Type: Class<R>;
5
9
  constructor(Type: Class<R>);
package/lib/array.js CHANGED
@@ -1,6 +1,4 @@
1
1
  "use strict";
2
- // tslint:disable-next-line: no-reference
3
- /// <reference path="./../typings/array.d.ts" />
4
2
  Object.defineProperty(exports, "__esModule", { value: true });
5
3
  exports.TypedArray = void 0;
6
4
  class TypedArray extends Array {
@@ -10,7 +8,6 @@ class TypedArray extends Array {
10
8
  }
11
9
  }
12
10
  exports.TypedArray = TypedArray;
13
- // tslint:disable-next-line: only-arrow-functions
14
11
  Array.ofType = function (type) {
15
12
  return new TypedArray(type);
16
13
  };
package/lib/array.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"array.js","sourceRoot":"","sources":["../src/array.ts"],"names":[],"mappings":";AAAA,yCAAyC;AACzC,gDAAgD;;;AAIhD,MAAa,UAAc,SAAQ,KAAQ;IACzC,YAAmB,IAAc;QAC/B,KAAK,EAAE,CAAC;QADS,SAAI,GAAJ,IAAI,CAAU;IAEjC,CAAC;CACF;AAJD,gCAIC;AAED,iDAAiD;AACjD,KAAK,CAAC,MAAM,GAAG,UAAY,IAAc;IACvC,OAAO,IAAI,UAAU,CAAI,IAAI,CAAC,CAAC;AACjC,CAAC,CAAC"}
1
+ {"version":3,"file":"array.js","sourceRoot":"","sources":["../src/array.ts"],"names":[],"mappings":";;;AAOA,MAAa,UAAc,SAAQ,KAAQ;IACzC,YAAmB,IAAc;QAC/B,KAAK,EAAE,CAAC;QADS,SAAI,GAAJ,IAAI,CAAU;IAEjC,CAAC;CACF;AAJD,gCAIC;AAED,KAAK,CAAC,MAAM,GAAG,UAAa,IAAc;IACxC,OAAO,IAAI,UAAU,CAAI,IAAI,CAAC,CAAC;AACjC,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { IBind, IContainer, ResolvableObject } from './interfaces';
2
+ import { Class, Factory } from './types';
3
+ export declare class Binder<T> implements IBind {
4
+ private implementation;
5
+ private container;
6
+ private isFactory;
7
+ private isConstructor;
8
+ constructor(implementation: Class<T> | Factory<T> | ResolvableObject, container: IContainer);
9
+ as<T>(type: string | Class<T>): this;
10
+ /**
11
+ * Add plain value to container. If value exists, it overrides content in container cache
12
+ *
13
+ * @param type - name of added value
14
+ * @returns
15
+ */
16
+ asValue(type: string): this;
17
+ /**
18
+ * Add value as array entry, and push to array if already value exists.
19
+ * Usefull if for eg. user wants to add multiple values and not override its contents.
20
+ *
21
+ * @param type - name / or type to add
22
+ */
23
+ asArrayValue(type: string): this;
24
+ asSelf(): this;
25
+ singleInstance(): this;
26
+ }
package/lib/binder.js ADDED
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Binder = void 0;
4
+ const exceptions_1 = require("./exceptions");
5
+ const decorators_1 = require("./decorators");
6
+ const enums_1 = require("./enums");
7
+ const helpers_1 = require("./helpers");
8
+ const _1 = require(".");
9
+ class Binder {
10
+ constructor(implementation, container) {
11
+ this.implementation = implementation;
12
+ this.container = container;
13
+ this.isFactory = (0, helpers_1.isFactory)(implementation);
14
+ this.isConstructor = (0, _1.isConstructor)(implementation);
15
+ }
16
+ as(type) {
17
+ this.container.Registry.register(type, this.implementation);
18
+ return this;
19
+ }
20
+ /**
21
+ * Add plain value to container. If value exists, it overrides content in container cache
22
+ *
23
+ * @param type - name of added value
24
+ * @returns
25
+ */
26
+ asValue(type) {
27
+ this.container.Cache.add(type, this.implementation);
28
+ return this;
29
+ }
30
+ /**
31
+ * Add value as array entry, and push to array if already value exists.
32
+ * Usefull if for eg. user wants to add multiple values and not override its contents.
33
+ *
34
+ * @param type - name / or type to add
35
+ */
36
+ asArrayValue(type) {
37
+ if (this.container.Cache.has(type)) {
38
+ this.container.Cache.get(type).push(this.implementation);
39
+ }
40
+ else {
41
+ this.container.Cache.add(type, [this.implementation]);
42
+ }
43
+ return this;
44
+ }
45
+ asSelf() {
46
+ if (!this.isConstructor || this.isFactory) {
47
+ throw new exceptions_1.BindException('cannot register as self non class');
48
+ }
49
+ // we can safly cast to any, we checked params earlier
50
+ this.container.Registry.register(this.implementation, this.implementation);
51
+ return this;
52
+ }
53
+ singleInstance() {
54
+ const descriptor = {
55
+ inject: [],
56
+ resolver: enums_1.ResolveType.Singleton,
57
+ };
58
+ if (this.isFactory || !this.isConstructor) {
59
+ throw new exceptions_1.BindException('Cannot bind factory function as singleton.');
60
+ }
61
+ else {
62
+ this.implementation[`${decorators_1.DI_DESCRIPTION_SYMBOL}`] = descriptor;
63
+ }
64
+ return this;
65
+ }
66
+ }
67
+ exports.Binder = Binder;
68
+ //# sourceMappingURL=binder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binder.js","sourceRoot":"","sources":["../src/binder.ts"],"names":[],"mappings":";;;AAAA,6CAA6C;AAC7C,6CAAqD;AACrD,mCAAsC;AACtC,uCAAsC;AAGtC,wBAAkC;AAElC,MAAa,MAAM;IAIjB,YAAoB,cAAwD,EAAU,SAAqB;QAAvF,mBAAc,GAAd,cAAc,CAA0C;QAAU,cAAS,GAAT,SAAS,CAAY;QACzG,IAAI,CAAC,SAAS,GAAG,IAAA,mBAAS,EAAC,cAAc,CAAC,CAAC;QAC3C,IAAI,CAAC,aAAa,GAAG,IAAA,gBAAa,EAAC,cAAc,CAAC,CAAC;IACrD,CAAC;IAED,EAAE,CAAI,IAAuB;QAC3B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,IAAY;QAClB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,IAAY;QACvB,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YACjC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAW,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;SACrE;aAAM;YACL,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;SACvD;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,SAAS,EAAE;YACzC,MAAM,IAAI,0BAAa,CAAC,mCAAmC,CAAC,CAAC;SAC9D;QAED,sDAAsD;QACtD,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAqB,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,cAAc;QACZ,MAAM,UAAU,GAA+B;YAC7C,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,mBAAW,CAAC,SAAS;SAChC,CAAC;QAEF,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;YACzC,MAAM,IAAI,0BAAa,CAAC,4CAA4C,CAAC,CAAC;SACvE;aAAM;YACJ,IAAI,CAAC,cAAsB,CAAC,GAAG,kCAAqB,EAAE,CAAC,GAAG,UAAU,CAAC;SACvE;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA9DD,wBA8DC"}
@@ -0,0 +1,12 @@
1
+ import { TypedArray } from './array';
2
+ import { IContainer } from './interfaces';
3
+ import { Class } from './types';
4
+ export declare class ContainerCache {
5
+ private container;
6
+ private cache;
7
+ constructor(container: IContainer);
8
+ add(key: string | Class<any> | object, instance: any): void;
9
+ has(key: string | Class<any> | object | TypedArray<any>, parent?: boolean): boolean;
10
+ get(key: string | Class<any> | TypedArray<any>, parent?: boolean): any;
11
+ clear(): void;
12
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContainerCache = void 0;
4
+ const helpers_1 = require("./helpers");
5
+ class ContainerCache {
6
+ constructor(container) {
7
+ this.container = container;
8
+ this.cache = new Map();
9
+ // add to cache container
10
+ // so we can inject container if needed
11
+ this.add(container, container);
12
+ }
13
+ add(key, instance) {
14
+ const tName = (0, helpers_1.getTypeName)(key);
15
+ if (this.has(key)) {
16
+ if (this.cache.get(tName).indexOf(instance) === -1) {
17
+ this.cache.get(tName).push(instance);
18
+ }
19
+ }
20
+ else {
21
+ this.cache.set(tName, [instance]);
22
+ }
23
+ }
24
+ has(key, parent) {
25
+ if (this.cache.has((0, helpers_1.getTypeName)(key))) {
26
+ return true;
27
+ }
28
+ if (parent && this.container.Parent) {
29
+ return this.container.Parent.Cache.has(key, parent);
30
+ }
31
+ return false;
32
+ }
33
+ get(key, parent) {
34
+ const tName = (0, helpers_1.getTypeName)(key);
35
+ if (this.cache.has(tName)) {
36
+ return this.cache.get(tName);
37
+ }
38
+ if (parent && this.container.Parent) {
39
+ return this.container.Parent.Cache.get(key, parent);
40
+ }
41
+ return [];
42
+ }
43
+ clear() {
44
+ this.cache.clear();
45
+ this.add(this.container, this.container);
46
+ }
47
+ }
48
+ exports.ContainerCache = ContainerCache;
49
+ //# sourceMappingURL=container-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container-cache.js","sourceRoot":"","sources":["../src/container-cache.ts"],"names":[],"mappings":";;;AACA,uCAAwC;AAIxC,MAAa,cAAc;IAGzB,YAAoB,SAAqB;QAArB,cAAS,GAAT,SAAS,CAAY;QACvC,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,EAAiB,CAAC;QAEtC,yBAAyB;QACzB,uCAAuC;QACvC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACjC,CAAC;IAEM,GAAG,CAAC,GAAiC,EAAE,QAAa;QACzD,MAAM,KAAK,GAAG,IAAA,qBAAW,EAAC,GAAG,CAAC,CAAC;QAE/B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YACjB,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE;gBAClD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;aACtC;SACF;aAAM;YACL,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;SACnC;IACH,CAAC;IAEM,GAAG,CAAC,GAAmD,EAAE,MAAgB;QAC9E,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAA,qBAAW,EAAC,GAAG,CAAC,CAAC,EAAE;YACpC,OAAO,IAAI,CAAC;SACb;QAED,IAAI,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;YACnC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;SACrD;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEM,GAAG,CAAC,GAA0C,EAAE,MAAgB;QACrE,MAAM,KAAK,GAAG,IAAA,qBAAW,EAAC,GAAG,CAAC,CAAC;QAE/B,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACzB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;SAC9B;QAED,IAAI,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;YACnC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;SACrD;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAEM,KAAK;QACV,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC;CACF;AArDD,wCAqDC"}
@@ -1,20 +1,22 @@
1
+ /// <reference types="node" />
1
2
  import 'reflect-metadata';
2
3
  import { TypedArray } from './array';
3
- import { IBind, IContainer, AsyncModule } from './interfaces';
4
+ import { IBind, IContainer, IInjectDescriptor, IResolvedInjection, IToInject, AsyncModule, ResolvableObject } from './interfaces';
4
5
  import { Class, Factory } from './types';
6
+ import { EventEmitter } from 'events';
7
+ import { Registry } from './registry';
8
+ import { ContainerCache } from './container-cache';
5
9
  /**
6
10
  * Dependency injection container implementation
7
11
  */
8
- export declare class Container implements IContainer {
12
+ export declare class Container extends EventEmitter implements IContainer {
9
13
  /**
10
14
  * Handles information about what is registered as what
11
15
  * eg. that class IConfiguration should be resolved as DatabaseConfiguration etc.
12
- * @access private
13
16
  */
14
17
  private registry;
15
18
  /**
16
19
  * Singletons cache, objects that should be created only once are stored here.
17
- * @access private
18
20
  */
19
21
  private cache;
20
22
  /**
@@ -24,19 +26,28 @@ export declare class Container implements IContainer {
24
26
  /**
25
27
  * Returns container cache - map object with resolved classes as singletons
26
28
  */
27
- get Cache(): Map<string, any>;
28
- get Registry(): Map<string, Array<Class<any>>>;
29
+ get Cache(): ContainerCache;
30
+ get Registry(): Registry;
31
+ get Parent(): IContainer;
29
32
  constructor(parent?: IContainer);
30
33
  /**
31
- * Clears container registry and cache.
34
+ * Clears container registry and cache. shorthand for container.clearCache() && container.clearRegistry()
32
35
  */
33
36
  clear(): void;
37
+ /**
38
+ * clears container registered types information
39
+ */
40
+ clearCache(): void;
41
+ /**
42
+ * Clears container resolved types
43
+ */
44
+ clearRegistry(): void;
34
45
  /**
35
46
  * Register class/interface to DI.
36
47
  * @param type - interface object to register
37
- * @throws { InvalidArgument } if type is null or undefined
48
+ * @throws {@link InvalidArgument} if type is null or undefined
38
49
  */
39
- register<T>(implementation: Class<T> | Factory<T>): IBind;
50
+ register<T>(implementation: Class<T> | Factory<T> | ResolvableObject): IBind;
40
51
  /**
41
52
  * Creates child DI container.
42
53
  *
@@ -45,52 +56,75 @@ export declare class Container implements IContainer {
45
56
  /**
46
57
  * Gets already resolved services. Works only for singleton classes.
47
58
  *
59
+ * Do not try to get service by factory func, it will always return null.
60
+ * If you somehowe want to cache instances created by factory functions,
61
+ * factory itself should do that somehow and end user should always resolve by
62
+ * assigned type
63
+ *
48
64
  * @param serviceName - name of service to get
49
- * @returns { null | T} - null if no service has been resolved at given name
65
+ * @returns null if no service has been resolved at given name
50
66
  */
51
67
  get<T>(service: TypedArray<T>, parent?: boolean): T[];
52
68
  get<T>(service: string | Class<T>, parent?: boolean): T;
53
- getRegistered<T>(service: string | Class<T>, parent?: boolean): Array<Class<any>>;
54
69
  hasRegistered<T>(service: Class<T> | string, parent?: boolean): boolean;
55
70
  /**
56
71
  * Checks if service is already resolved and exists in container cache.
57
72
  * NOTE: check is only valid for classes that are singletons.
58
73
  *
59
74
  * @param service - service name or class to check
60
- * @returns { boolean } - true if service instance already exists, otherwise false.
61
- * @throws { InvalidArgument } when service is null or empty
75
+ * @returns true if service instance already exists, otherwise false.
76
+ * @throws {@link InvalidArgument} when service is null or empty
62
77
  */
63
- has<T>(service: string | Class<T>, parent?: boolean): boolean;
78
+ isResolved<T>(service: string | Class<T> | TypedArray<T>, parent?: boolean): boolean;
64
79
  /**
65
80
  *
66
81
  * Resolves single instance of class
67
82
  *
68
- * @param type what to resolve, can be class definition or factory function
69
- * @param options options passed to constructor / factory
83
+ * @param type - what to resolve, can be class definition or factory function
84
+ * @param options - options passed to constructor / factory
70
85
  */
71
- resolve<T>(type: string, options?: any[], check?: boolean): T;
86
+ resolve<T>(type: string, options?: unknown[], check?: boolean): T;
72
87
  resolve<T>(type: string, check?: boolean): T;
73
88
  /**
74
89
  *
75
90
  * Resolves single instance of class
76
91
  *
77
- * @param type what to resolve, can be class definition or factory function
78
- * @param options options passed to constructor / factory
92
+ * @param type - what to resolve, can be class definition or factory function
93
+ * @param options - options passed to constructor / factory
79
94
  */
80
- resolve<T>(type: Class<T>, options?: any[], check?: boolean): T extends AsyncModule ? Promise<T> : T;
95
+ resolve<T>(type: Class<T>, options?: unknown[], check?: boolean): T extends AsyncModule ? Promise<T> : T;
81
96
  resolve<T>(type: Class<T>, check?: boolean): T extends AsyncModule ? Promise<T> : T;
82
97
  /**
83
98
  *
84
99
  * Resolves all instances of given class. Under single definition can be registered multiple implementations.
85
100
  *
86
- * @param type typed array of specified type. since TS does not expose array metadata and type its uses TypedArray<T> consctruct
87
- * @param options options passed to constructor / factory
101
+ * @param type - typed array of specified type. since TS does not expose array metadata and type its uses TypedArray<T> consctruct
102
+ * @param options - options passed to constructor / factory
88
103
  * @param check - strict check if serivice is registered in container before resolving. Default behavior is to not check and resolve
89
104
  *
90
105
  */
91
- resolve<T>(type: TypedArray<T>, options?: any[], check?: boolean): T extends AsyncModule ? Promise<T[]> : T[];
106
+ resolve<T>(type: TypedArray<T>, options?: unknown[], check?: boolean): T extends AsyncModule ? Promise<T[]> : T[];
92
107
  resolve<T>(type: TypedArray<T>, check?: boolean): T extends AsyncModule ? Promise<T[]> : T[];
108
+ getRegisteredTypes<T>(service: string | Class<T> | TypedArray<T>, parent?: boolean): (Class<unknown> | Factory<unknown>)[];
93
109
  private resolveType;
94
- private _hasRegisteredType;
95
- private registerSelf;
110
+ protected getNewInstance(typeToCreate: Class<unknown> | Factory<unknown>, a?: IResolvedInjection[], options?: unknown[]): Promise<unknown> | unknown;
111
+ hasRegisteredType<T>(source: Class<T> | string, type: Class<T> | string | TypedArray<T>, parent?: boolean): boolean;
112
+ protected resolveDependencies(toInject: IToInject<unknown>[]): (Promise<{
113
+ autoinject: boolean;
114
+ autoinjectKey: string;
115
+ instance: any;
116
+ }> | {
117
+ autoinject: boolean;
118
+ autoinjectKey: string;
119
+ instance: unknown;
120
+ })[] | Promise<({
121
+ autoinject: boolean;
122
+ autoinjectKey: string;
123
+ instance: any;
124
+ } | {
125
+ autoinject: boolean;
126
+ autoinjectKey: string;
127
+ instance: unknown;
128
+ })[]>;
129
+ protected extractDescriptor(type: Class<unknown>): IInjectDescriptor<unknown>;
96
130
  }