@decaf-ts/injectable-decorators 1.5.15 → 1.6.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.md +0 -0
- package/README.md +32 -107
- package/dist/injectable-decorators.cjs +323 -0
- package/dist/injectable-decorators.esm.cjs +310 -0
- package/lib/Injectables.cjs +1 -0
- package/lib/Injectables.d.ts +0 -0
- package/lib/constants.cjs +1 -0
- package/lib/constants.d.ts +0 -0
- package/lib/decorators.cjs +1 -0
- package/lib/decorators.d.ts +0 -0
- package/lib/esm/Injectables.d.ts +0 -0
- package/lib/esm/Injectables.js +1 -2
- package/lib/esm/constants.d.ts +0 -0
- package/lib/esm/constants.js +1 -2
- package/lib/esm/decorators.d.ts +0 -0
- package/lib/esm/decorators.js +1 -2
- package/lib/esm/index.d.ts +1 -1
- package/lib/esm/index.js +2 -3
- package/lib/esm/registry.d.ts +0 -0
- package/lib/esm/registry.js +1 -2
- package/lib/esm/utils.d.ts +0 -0
- package/lib/esm/utils.js +1 -2
- package/lib/index.cjs +2 -1
- package/lib/index.d.ts +1 -1
- package/lib/registry.cjs +1 -0
- package/lib/registry.d.ts +0 -0
- package/lib/utils.cjs +1 -0
- package/lib/utils.d.ts +0 -0
- package/package.json +36 -41
- package/dist/esm/injectable-decorators.bundle.min.esm.js +0 -2
- package/dist/esm/injectable-decorators.bundle.min.esm.js.LICENSE.txt +0 -14
- package/dist/injectable-decorators.bundle.min.js +0 -2
- package/dist/injectable-decorators.bundle.min.js.LICENSE.txt +0 -14
package/LICENSE.md
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -6,18 +6,21 @@ Simple implementation of injectables
|
|
|
6
6
|

|
|
7
7
|

|
|
8
8
|

|
|
9
|
-
|
|
10
|
-
[](https://github.com/decaf-ts/injectable-decorators/actions/workflows/nodejs-build-prod.yaml)
|
|
11
|
+
[](https://github.com/decaf-ts/injectable-decorators/actions/workflows/codeql-analysis.yml)[](https://github.com/decaf-ts/injectable-decorators/actions/workflows/snyk-analysis.yaml)
|
|
12
|
+
[](https://github.com/decaf-ts/injectable-decorators/actions/workflows/pages.yaml)
|
|
13
|
+
[](https://github.com/decaf-ts/injectable-decorators/actions/workflows/release-on-tag.yaml)
|
|
11
14
|
|
|
12
15
|

|
|
13
16
|

|
|
14
17
|

|
|
15
18
|

|
|
16
19
|
|
|
17
|
-

|
|
18
|
-

|
|
19
|
-

|
|
20
|
-

|
|
20
|
+

|
|
21
|
+

|
|
22
|
+

|
|
23
|
+

|
|
21
24
|
|
|
22
25
|
|
|
23
26
|

|
|
@@ -27,108 +30,32 @@ Simple implementation of injectables
|
|
|
27
30
|

|
|
28
31
|

|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
Documentation available [here](https://decaf-ts.github.io/injectable-decorators/)
|
|
34
|
+
|
|
35
|
+
### Description
|
|
31
36
|
|
|
32
37
|
Simple implementation of a Typescript decorator based injectable system.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"experimentalDecorators": true,
|
|
43
|
-
"emitDecoratorMetadata": true,
|
|
44
|
-
"useDefineForClassFields": false
|
|
45
|
-
}
|
|
46
|
-
```
|
|
38
|
+
|
|
39
|
+
### How to Use
|
|
40
|
+
|
|
41
|
+
- [Initial Setup](./tutorials/For%20Developers.md#_initial-setup_)
|
|
42
|
+
- [Installation](./tutorials/For%20Developers.md#installation)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
47
|
### Related
|
|
48
48
|
|
|
49
|
-
[](https://github.com/decaf-ts/ts-workspace)
|
|
50
|
+
|
|
51
51
|
### Social
|
|
52
52
|
|
|
53
53
|
[](https://www.linkedin.com/in/decaf-ts/)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
- `do-install` - sets a `TOKEN` environment variable to the contents of `.token` and runs npm install (useful when you
|
|
60
|
-
have private dependencies);
|
|
61
|
-
- `flash-forward` - updates all dependencies. Take care, This may not be desirable is some cases;
|
|
62
|
-
- `reset` - updates all dependencies. Take care, This may not be desirable is some cases;
|
|
63
|
-
- `build` - builds the code (via gulp `gulpfile.js`) in development mode (generates `lib` and `dist` folder);
|
|
64
|
-
- `build:prod` - builds the code (via gulp `gulpfile.js`) in production mode (generates `lib` and `dist` folder);
|
|
65
|
-
- `test` - runs unit tests;
|
|
66
|
-
- `test:integration` - runs it tests;
|
|
67
|
-
- `test:all` - runs all tests;
|
|
68
|
-
- `lint` - runs es lint on the code folder;
|
|
69
|
-
- `lint-fix` - tries to auto-fix the code folder;
|
|
70
|
-
- `prepare-release` - defines the commands to run prior to a new tag (defaults to linting, building production code,
|
|
71
|
-
running tests and documentation generation);
|
|
72
|
-
- `release` - triggers a new tag being pushed to master (via `./bin/tag_release.sh`);
|
|
73
|
-
- `clean-publish` - cleans the package.json for publishing;
|
|
74
|
-
- `coverage` - runs all test, calculates coverage and generates badges for readme;
|
|
75
|
-
- `drawings` - compiles all DrawIO `*.drawio` files in the `workdocs/drawings` folder to png and moves them to
|
|
76
|
-
the `workdocs/resources` folder;
|
|
77
|
-
- `uml` - compiles all PlantUML `*.puml` files in the `workdocs/uml` folder to png and moves them to
|
|
78
|
-
the `workdocs/resources` folder;
|
|
79
|
-
- `docs` - compiles all the coverage, drawings, uml, jsdocs and md docs into a readable web page under `./docs`;
|
|
80
|
-
|
|
81
|
-
### Repository Structure
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
injectable-decorators
|
|
85
|
-
│
|
|
86
|
-
│ .gitignore <-- Defines files ignored to git
|
|
87
|
-
│ .npmignore <-- Defines files ignored by npm
|
|
88
|
-
│ .nmprc <-- Defines the Npm registry for this package
|
|
89
|
-
│ .eslintrc.cjs <-- linting for the project
|
|
90
|
-
│ .prettier.config.cjs <-- Code style for the project
|
|
91
|
-
│ .gitlab-ci.yml <-- Gillab CI/CD file
|
|
92
|
-
│ gulpfile.js <-- Gulp build scripts. used for building na other features (eg docs)
|
|
93
|
-
│ jest.config.ts <-- Tests Configuration file
|
|
94
|
-
│ mdCompile.json <-- md Documentation generation configuration file
|
|
95
|
-
│ jsdocs.json <-- jsdoc Documentation generation configuration file
|
|
96
|
-
│ Dockerfile <-- minimal example of a node service Dockerfile
|
|
97
|
-
│ LICENCE.md <-- Licence disclamer
|
|
98
|
-
│ package.json
|
|
99
|
-
│ package-lock.json
|
|
100
|
-
│ README.md <-- Readme File dynamically compiled from 'workdocs' via the 'docs' npm script
|
|
101
|
-
│ tsconfig.json <-- Typescript config file. Is overriden in 'gulpfile.js'
|
|
102
|
-
│
|
|
103
|
-
└───bin
|
|
104
|
-
│ │ tag_release.sh <-- Script to help with releases
|
|
105
|
-
│
|
|
106
|
-
└───docs
|
|
107
|
-
│ │ ... <-- Dinamically generated folder, containing the compiled documentation for this repository. generated via the 'docs' npm script
|
|
108
|
-
│
|
|
109
|
-
└───src
|
|
110
|
-
│ │ ... <-- Source code for this repository
|
|
111
|
-
│
|
|
112
|
-
└───tests
|
|
113
|
-
│ │───unit <-- Unit tests
|
|
114
|
-
│ └───integration <-- Integration tests
|
|
115
|
-
│
|
|
116
|
-
└───workdocs <-- Folder with all pre-compiled documentation
|
|
117
|
-
│ │───assets <-- Documentation asset folder
|
|
118
|
-
│ │───badges <-- Auto generated coverage badges folder
|
|
119
|
-
│ │───coverage <-- Auto generated coverage results
|
|
120
|
-
│ │───drawings <-- DrawIO folder. Drawings (*.drawio) here will be processed to generate documentation (requires docker)
|
|
121
|
-
│ │───uml <-- PlantUML folder. Diagrams (*.puml) here will be processed to generate documentation (requires docker)
|
|
122
|
-
│ │───tutorials <-- Tutorial folder
|
|
123
|
-
│ │ ... <-- Categorized *.md files that are merged to generate the final readme (via md compile)
|
|
124
|
-
│ │ Readme.md <-- Entry point to the README.md
|
|
125
|
-
│
|
|
126
|
-
└───dist
|
|
127
|
-
│ │ ... <-- Dinamically generated folder containing the bundles for distribution
|
|
128
|
-
│
|
|
129
|
-
└───lib
|
|
130
|
-
| ... <-- Dinamically generated folder containing the compiled code
|
|
131
|
-
```
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
#### Languages
|
|
132
59
|
|
|
133
60
|

|
|
134
61
|

|
|
@@ -137,7 +64,7 @@ injectable-decorators
|
|
|
137
64
|
|
|
138
65
|
## Getting help
|
|
139
66
|
|
|
140
|
-
If you have bug reports, questions or suggestions please [create a new issue](https://github.com/decaf-ts/
|
|
67
|
+
If you have bug reports, questions or suggestions please [create a new issue](https://github.com/decaf-ts/ts-workspace/issues/new/choose).
|
|
141
68
|
|
|
142
69
|
## Contributing
|
|
143
70
|
|
|
@@ -147,14 +74,12 @@ I am grateful for any contributions made to this project. Please read [this](./w
|
|
|
147
74
|
|
|
148
75
|
The first and easiest way you can support it is by [Contributing](./workdocs/98-Contributing.md). Even just finding a typo in the documentation is important.
|
|
149
76
|
|
|
150
|
-
Financial support is always welcome and helps keep
|
|
77
|
+
Financial support is always welcome and helps keep both me and the project alive and healthy.
|
|
151
78
|
|
|
152
79
|
So if you can, if this project in any way. either by learning something or simply by helping you save precious time, please consider donating.
|
|
153
80
|
|
|
154
81
|
## License
|
|
155
82
|
|
|
156
|
-
This project is released under the [MIT License](LICENSE.md).
|
|
157
|
-
|
|
158
|
-
#### Disclaimer:
|
|
83
|
+
This project is released under the [MIT License](./LICENSE.md).
|
|
159
84
|
|
|
160
|
-
|
|
85
|
+
By developers, for developers...
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('reflect-metadata')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'reflect-metadata'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["injectable-decorators"] = {}));
|
|
5
|
+
})(this, (function (exports) { 'use strict';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @summary Injectables Reflection keys
|
|
9
|
+
* @const InjectablesKeys
|
|
10
|
+
*
|
|
11
|
+
* @property {string} REFLECT Reflection injectables base key
|
|
12
|
+
* @property {string} INJECTABLE Reflection injectable key
|
|
13
|
+
* @property {string} INJECT Reflection inject key
|
|
14
|
+
*
|
|
15
|
+
* @memberOf injectable-decorators
|
|
16
|
+
*/
|
|
17
|
+
const InjectablesKeys = {
|
|
18
|
+
REFLECT: "inject.db.",
|
|
19
|
+
INJECTABLE: "injectable",
|
|
20
|
+
INJECT: "inject",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @summary Holds the vairous {@link Injectable}s
|
|
25
|
+
* @class InjectableRegistryImp
|
|
26
|
+
* @implements InjectablesRegistry
|
|
27
|
+
*/
|
|
28
|
+
class InjectableRegistryImp {
|
|
29
|
+
constructor() {
|
|
30
|
+
this.cache = {};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @inheritDoc
|
|
34
|
+
*/
|
|
35
|
+
get(name, ...args) {
|
|
36
|
+
try {
|
|
37
|
+
const innerCache = this.cache[name];
|
|
38
|
+
const buildDef = { name: name };
|
|
39
|
+
if (!innerCache.singleton && !innerCache.instance)
|
|
40
|
+
return this.build(buildDef, ...args);
|
|
41
|
+
return innerCache.instance || this.build(buildDef, ...args);
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @inheritDoc
|
|
50
|
+
*/
|
|
51
|
+
register(obj, category = undefined, isSingleton = true, force = false) {
|
|
52
|
+
const castObj = obj;
|
|
53
|
+
const constructor = !castObj.name && castObj.constructor;
|
|
54
|
+
if (typeof castObj !== "function" && !constructor)
|
|
55
|
+
throw new Error(`Injectable registering failed. Missing Class name or constructor`);
|
|
56
|
+
const name = category ||
|
|
57
|
+
(constructor && constructor.name && constructor.name !== "Function"
|
|
58
|
+
? constructor.name
|
|
59
|
+
: castObj.name);
|
|
60
|
+
if (!this.cache[name] || force)
|
|
61
|
+
this.cache[name] = {
|
|
62
|
+
instance: constructor ? obj : undefined,
|
|
63
|
+
constructor: !constructor ? obj : undefined,
|
|
64
|
+
singleton: isSingleton,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* @inheritDoc
|
|
69
|
+
*/
|
|
70
|
+
build(defs, ...args) {
|
|
71
|
+
const { constructor, singleton } = this.cache[defs.name];
|
|
72
|
+
const instance = new constructor(...args);
|
|
73
|
+
this.cache[defs.name] = {
|
|
74
|
+
instance: instance,
|
|
75
|
+
constructor: constructor,
|
|
76
|
+
singleton: singleton,
|
|
77
|
+
};
|
|
78
|
+
return instance;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @summary Static class Holding the access to the injectables functions
|
|
84
|
+
*
|
|
85
|
+
* @class Injectables
|
|
86
|
+
* @static
|
|
87
|
+
*/
|
|
88
|
+
class Injectables {
|
|
89
|
+
static { this.actingInjectablesRegistry = undefined; }
|
|
90
|
+
constructor() { }
|
|
91
|
+
/**
|
|
92
|
+
* @summary Retrieves the named {@link Injectable} from the registry
|
|
93
|
+
* @param {string} name
|
|
94
|
+
* @param {any[]} args
|
|
95
|
+
*/
|
|
96
|
+
static get(name, ...args) {
|
|
97
|
+
return Injectables.getRegistry().get(name, ...args);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* @summary registers an injectable constructor
|
|
101
|
+
* @param {Injectable} constructor
|
|
102
|
+
* @param {any[]} args
|
|
103
|
+
*
|
|
104
|
+
*/
|
|
105
|
+
static register(constructor, ...args) {
|
|
106
|
+
return Injectables.getRegistry().register(constructor, ...args);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* @summary Instantiates an Injectable
|
|
110
|
+
* @param {Record<string, any>} obj
|
|
111
|
+
* @param {any[]} args
|
|
112
|
+
* @return T
|
|
113
|
+
*
|
|
114
|
+
*/
|
|
115
|
+
static build(obj, ...args) {
|
|
116
|
+
return Injectables.getRegistry().build(obj, ...args);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* @summary Sets a new {@link InjectablesRegistry}
|
|
120
|
+
* @param {InjectablesRegistry} operationsRegistry the new implementation of Registry
|
|
121
|
+
*/
|
|
122
|
+
static setRegistry(operationsRegistry) {
|
|
123
|
+
Injectables.actingInjectablesRegistry = operationsRegistry;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* @summary Returns the current {@link InjectablesRegistry}
|
|
127
|
+
*/
|
|
128
|
+
static getRegistry() {
|
|
129
|
+
if (!Injectables.actingInjectablesRegistry)
|
|
130
|
+
Injectables.actingInjectablesRegistry = new InjectableRegistryImp();
|
|
131
|
+
return Injectables.actingInjectablesRegistry;
|
|
132
|
+
}
|
|
133
|
+
static reset() {
|
|
134
|
+
Injectables.setRegistry(new InjectableRegistryImp());
|
|
135
|
+
}
|
|
136
|
+
static selectiveReset(match) {
|
|
137
|
+
const regexp = typeof match === "string" ? new RegExp(match) : match;
|
|
138
|
+
Injectables.actingInjectablesRegistry["cache"] = Object.entries(Injectables.actingInjectablesRegistry["cache"]).reduce((accum, [key, val]) => {
|
|
139
|
+
if (!key.match(regexp))
|
|
140
|
+
accum[key] = val;
|
|
141
|
+
return accum;
|
|
142
|
+
}, {});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @summary holds the key for the design type
|
|
148
|
+
* @const TypeKey
|
|
149
|
+
* @memberOf module:injectable-decorators
|
|
150
|
+
*/
|
|
151
|
+
const TypeKey = "design:type";
|
|
152
|
+
/**
|
|
153
|
+
* @summary Retrieves the type from the decorators
|
|
154
|
+
* @param {any} model
|
|
155
|
+
* @param {string | symbol} propKey
|
|
156
|
+
* @return {string | undefined}
|
|
157
|
+
*
|
|
158
|
+
* @function geTypeFromDecorators
|
|
159
|
+
*
|
|
160
|
+
* @memberOf module:injectable-decorators
|
|
161
|
+
*/
|
|
162
|
+
function getTypeFromDecorator(model, propKey) {
|
|
163
|
+
const typeDef = Reflect.getMetadata(TypeKey, model, propKey);
|
|
164
|
+
return typeDef.name !== "Function" ? typeDef.name : undefined;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @summary Return the reflection key for injectables
|
|
169
|
+
*
|
|
170
|
+
* @param {string} key
|
|
171
|
+
* @function getInjectKey
|
|
172
|
+
*
|
|
173
|
+
* @memberOf module:injectable-decorators
|
|
174
|
+
*/
|
|
175
|
+
const getInjectKey = (key) => InjectablesKeys.REFLECT + key;
|
|
176
|
+
/**
|
|
177
|
+
* @summary Defines a class as an injectable
|
|
178
|
+
*
|
|
179
|
+
* @param {string} [category] defaults to the class Name. (Useful when minification occours and names are changed so we can no longer rely on the class name, or when we want to upcast the Object)
|
|
180
|
+
* @param {boolean} [force] defines if the injectable should override the already existing instance (if any). (only meant for extending decorators
|
|
181
|
+
* @param instanceCallback
|
|
182
|
+
*
|
|
183
|
+
* @function injectable
|
|
184
|
+
*
|
|
185
|
+
* @memberOf module:injectable-decorators.Decorators
|
|
186
|
+
*/
|
|
187
|
+
const injectable = (category = undefined, force = false, instanceCallback) =>
|
|
188
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
189
|
+
(original, propertyKey) => {
|
|
190
|
+
const name = category || original.name;
|
|
191
|
+
// the new constructor behaviour
|
|
192
|
+
const newConstructor = function (...args) {
|
|
193
|
+
let inj = Injectables.get(name, ...args);
|
|
194
|
+
if (!inj) {
|
|
195
|
+
Injectables.register(original, name, true, force);
|
|
196
|
+
inj = Injectables.get(name, ...args);
|
|
197
|
+
if (!inj)
|
|
198
|
+
return undefined;
|
|
199
|
+
if (instanceCallback)
|
|
200
|
+
try {
|
|
201
|
+
instanceCallback(inj);
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
console.error(`Failed to call injectable callback for ${name}: ${e}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const metadata = Object.assign({}, {
|
|
208
|
+
class: name,
|
|
209
|
+
});
|
|
210
|
+
Reflect.defineMetadata(getInjectKey(InjectablesKeys.INJECTABLE), metadata, inj.constructor);
|
|
211
|
+
return inj;
|
|
212
|
+
};
|
|
213
|
+
// copy prototype so instanceof operator still works
|
|
214
|
+
newConstructor.prototype = original.prototype;
|
|
215
|
+
// newConstructor.__proto__ = original.__proto__;
|
|
216
|
+
// Sets the proper constructor name for type verification
|
|
217
|
+
Object.defineProperty(newConstructor, "name", {
|
|
218
|
+
writable: false,
|
|
219
|
+
enumerable: true,
|
|
220
|
+
configurable: false,
|
|
221
|
+
value: original.prototype.constructor.name,
|
|
222
|
+
});
|
|
223
|
+
// return new constructor (will override original)
|
|
224
|
+
return newConstructor;
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* @summary Allows for the injection of an {@link injectable} decorated dependency
|
|
228
|
+
* @description the property must be typed for the requested dependency.
|
|
229
|
+
*
|
|
230
|
+
* Only concrete classes. No generics are supported
|
|
231
|
+
*
|
|
232
|
+
* Injected properties should be described like so:
|
|
233
|
+
* <pre>
|
|
234
|
+
* class ClassName {
|
|
235
|
+
* ...
|
|
236
|
+
*
|
|
237
|
+
* @inject()
|
|
238
|
+
* propertyName!: InjectableClass;
|
|
239
|
+
*
|
|
240
|
+
* ...
|
|
241
|
+
* }
|
|
242
|
+
* </pre>
|
|
243
|
+
*
|
|
244
|
+
* where InjectableClass is the class you want to inject.
|
|
245
|
+
* Notice the use of '!:' to ensure the transpiler the property will be set outside the constructor but will always be defined
|
|
246
|
+
* For project where minification occours, you should use the category param to ensure the name is the same throughout
|
|
247
|
+
*
|
|
248
|
+
* @param {string} [category] defaults to the class Name. (Useful when minification occours and names are changed so we can no longer rely on the class name, or when we want to upcast the Object)
|
|
249
|
+
* @param {InstanceTransformer} [transformer]
|
|
250
|
+
*
|
|
251
|
+
* @function inject
|
|
252
|
+
*
|
|
253
|
+
* @memberOf module:injectable-decorators.Decorators
|
|
254
|
+
*/
|
|
255
|
+
const inject = (category, transformer) => (target, propertyKey) => {
|
|
256
|
+
const values = new WeakMap();
|
|
257
|
+
const name = category || getTypeFromDecorator(target, propertyKey);
|
|
258
|
+
if (!name)
|
|
259
|
+
throw new Error(`Could not get Type from decorator`);
|
|
260
|
+
Reflect.defineMetadata(getInjectKey(InjectablesKeys.INJECT), {
|
|
261
|
+
injectable: name,
|
|
262
|
+
}, target, propertyKey);
|
|
263
|
+
Object.defineProperty(target, propertyKey, {
|
|
264
|
+
configurable: true,
|
|
265
|
+
get() {
|
|
266
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
|
|
267
|
+
if (descriptor.configurable) {
|
|
268
|
+
Object.defineProperty(this, propertyKey, {
|
|
269
|
+
enumerable: true,
|
|
270
|
+
configurable: false,
|
|
271
|
+
get() {
|
|
272
|
+
let obj = values.get(this);
|
|
273
|
+
if (!obj) {
|
|
274
|
+
obj = Injectables.get(name);
|
|
275
|
+
if (!obj)
|
|
276
|
+
throw new Error(`Could not get Injectable ${name} to inject in ${target.constructor ? target.constructor.name : target.name}'s ${propertyKey}`);
|
|
277
|
+
if (transformer)
|
|
278
|
+
try {
|
|
279
|
+
obj = transformer(obj, target);
|
|
280
|
+
}
|
|
281
|
+
catch (e) {
|
|
282
|
+
console.error(e);
|
|
283
|
+
}
|
|
284
|
+
values.set(this, obj);
|
|
285
|
+
}
|
|
286
|
+
return obj;
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
return this[propertyKey];
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* @summary Adds a simple Injectables implementation to create singleton instances of an object
|
|
297
|
+
* and easily inject it into other objects
|
|
298
|
+
*
|
|
299
|
+
* @module injectable-decorators
|
|
300
|
+
*/
|
|
301
|
+
/**
|
|
302
|
+
* @summary functions that decorate classes or class properties
|
|
303
|
+
* @namespace Decorators
|
|
304
|
+
* @memberOf module:injectable-decorators
|
|
305
|
+
*/
|
|
306
|
+
/**
|
|
307
|
+
* @summary Defined on library build. holds the library current version
|
|
308
|
+
* @const VERSION
|
|
309
|
+
* @memberOf module:injectable-decorators
|
|
310
|
+
*/
|
|
311
|
+
const VERSION = "1.6.0";
|
|
312
|
+
|
|
313
|
+
exports.InjectableRegistryImp = InjectableRegistryImp;
|
|
314
|
+
exports.Injectables = Injectables;
|
|
315
|
+
exports.InjectablesKeys = InjectablesKeys;
|
|
316
|
+
exports.TypeKey = TypeKey;
|
|
317
|
+
exports.VERSION = VERSION;
|
|
318
|
+
exports.getTypeFromDecorator = getTypeFromDecorator;
|
|
319
|
+
exports.inject = inject;
|
|
320
|
+
exports.injectable = injectable;
|
|
321
|
+
|
|
322
|
+
}));
|
|
323
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5qZWN0YWJsZS1kZWNvcmF0b3JzLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbnN0YW50cy50cyIsIi4uL3NyYy9yZWdpc3RyeS50cyIsIi4uL3NyYy9JbmplY3RhYmxlcy50cyIsIi4uL3NyYy91dGlscy50cyIsIi4uL3NyYy9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHN1bW1hcnkgSW5qZWN0YWJsZXMgUmVmbGVjdGlvbiBrZXlzXG4gKiBAY29uc3QgSW5qZWN0YWJsZXNLZXlzXG4gKlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFRkxFQ1QgUmVmbGVjdGlvbiBpbmplY3RhYmxlcyBiYXNlIGtleVxuICogQHByb3BlcnR5IHtzdHJpbmd9IElOSkVDVEFCTEUgUmVmbGVjdGlvbiBpbmplY3RhYmxlIGtleVxuICogQHByb3BlcnR5IHtzdHJpbmd9IElOSkVDVCBSZWZsZWN0aW9uIGluamVjdCBrZXlcbiAqXG4gKiBAbWVtYmVyT2YgaW5qZWN0YWJsZS1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBjb25zdCBJbmplY3RhYmxlc0tleXMgPSB7XG4gIFJFRkxFQ1Q6IFwiaW5qZWN0LmRiLlwiLFxuICBJTkpFQ1RBQkxFOiBcImluamVjdGFibGVcIixcbiAgSU5KRUNUOiBcImluamVjdFwiLFxufTtcbiIsIi8qKlxuICogQHN1bW1hcnkgZGVmaW5lcyBhbiBJbmplY3RhYmxlIHR5cGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6aW5qZWN0YWJsZS1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCB0eXBlIEluamVjdGFibGU8VD4gPSB7IG5ldyAoLi4uYXJnczogYW55W10pOiBUIH0gfCBUO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEludGVyZmFjZSBmb3IgYW4gaW5qZWN0YWJsZSByZWdpc3RyeVxuICogQGludGVyZmFjZSBJbmplY3RhYmxlUmVnaXN0cnlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmplY3RhYmxlc1JlZ2lzdHJ5IHtcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJldHJpZXZlcyBhbiB7QGxpbmsgSW5qZWN0YWJsZX1cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHthbnlbXX0gYXJnc1xuICAgKiBAcmV0dXJuIHtJbmplY3RhYmxlIHwgdW5kZWZpbmVkfVxuICAgKlxuICAgKiBAbWV0aG9kXG4gICAqL1xuICBnZXQ8VD4obmFtZTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IEluamVjdGFibGU8VD4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJlZ2lzdGVycyBhbiBpbmplY3RhYmxlIGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7SW5qZWN0YWJsZX0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHthbnlbXX0gYXJnc1xuICAgKlxuICAgKiBAbWV0aG9kXG4gICAqL1xuICByZWdpc3RlcjxUPihjb25zdHJ1Y3RvcjogSW5qZWN0YWJsZTxUPiwgLi4uYXJnczogYW55W10pOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBJbnN0YW50aWF0ZXMgYW4gSW5qZWN0YWJsZVxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG9ialxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzXG4gICAqIEByZXR1cm4gVFxuICAgKlxuICAgKiBAbWV0aG9kXG4gICAqL1xuICBidWlsZDxUPihvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4sIC4uLmFyZ3M6IGFueVtdKTogVDtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBIb2xkcyB0aGUgdmFpcm91cyB7QGxpbmsgSW5qZWN0YWJsZX1zXG4gKiBAY2xhc3MgSW5qZWN0YWJsZVJlZ2lzdHJ5SW1wXG4gKiBAaW1wbGVtZW50cyBJbmplY3RhYmxlc1JlZ2lzdHJ5XG4gKi9cbmV4cG9ydCBjbGFzcyBJbmplY3RhYmxlUmVnaXN0cnlJbXAgaW1wbGVtZW50cyBJbmplY3RhYmxlc1JlZ2lzdHJ5IHtcbiAgcHJpdmF0ZSBjYWNoZTogeyBbaW5kZXhlcjogc3RyaW5nXTogYW55IH0gPSB7fTtcblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGdldDxUPihuYW1lOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogVCB8IHVuZGVmaW5lZCB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGlubmVyQ2FjaGUgPSB0aGlzLmNhY2hlW25hbWVdO1xuICAgICAgY29uc3QgYnVpbGREZWYgPSB7IG5hbWU6IG5hbWUgfTtcbiAgICAgIGlmICghaW5uZXJDYWNoZS5zaW5nbGV0b24gJiYgIWlubmVyQ2FjaGUuaW5zdGFuY2UpXG4gICAgICAgIHJldHVybiB0aGlzLmJ1aWxkPFQ+KGJ1aWxkRGVmLCAuLi5hcmdzKTtcbiAgICAgIHJldHVybiBpbm5lckNhY2hlLmluc3RhbmNlIHx8IHRoaXMuYnVpbGQ8VD4oYnVpbGREZWYsIC4uLmFyZ3MpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgcmVnaXN0ZXI8VD4oXG4gICAgb2JqOiBJbmplY3RhYmxlPFQ+LFxuICAgIGNhdGVnb3J5OiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4gICAgaXNTaW5nbGV0b246IGJvb2xlYW4gPSB0cnVlLFxuICAgIGZvcmNlOiBib29sZWFuID0gZmFsc2VcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgY2FzdE9iajogUmVjb3JkPHN0cmluZywgYW55PiA9IG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXG4gICAgY29uc3QgY29uc3RydWN0b3IgPSAhY2FzdE9iai5uYW1lICYmIGNhc3RPYmouY29uc3RydWN0b3I7XG4gICAgaWYgKHR5cGVvZiBjYXN0T2JqICE9PSBcImZ1bmN0aW9uXCIgJiYgIWNvbnN0cnVjdG9yKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgSW5qZWN0YWJsZSByZWdpc3RlcmluZyBmYWlsZWQuIE1pc3NpbmcgQ2xhc3MgbmFtZSBvciBjb25zdHJ1Y3RvcmBcbiAgICAgICk7XG5cbiAgICBjb25zdCBuYW1lID1cbiAgICAgIGNhdGVnb3J5IHx8XG4gICAgICAoY29uc3RydWN0b3IgJiYgY29uc3RydWN0b3IubmFtZSAmJiBjb25zdHJ1Y3Rvci5uYW1lICE9PSBcIkZ1bmN0aW9uXCJcbiAgICAgICAgPyAoY29uc3RydWN0b3IgYXMgeyBbaW5kZXhlcjogc3RyaW5nXTogYW55IH0pLm5hbWVcbiAgICAgICAgOiBjYXN0T2JqLm5hbWUpO1xuXG4gICAgaWYgKCF0aGlzLmNhY2hlW25hbWVdIHx8IGZvcmNlKVxuICAgICAgdGhpcy5jYWNoZVtuYW1lXSA9IHtcbiAgICAgICAgaW5zdGFuY2U6IGNvbnN0cnVjdG9yID8gb2JqIDogdW5kZWZpbmVkLFxuICAgICAgICBjb25zdHJ1Y3RvcjogIWNvbnN0cnVjdG9yID8gb2JqIDogdW5kZWZpbmVkLFxuICAgICAgICBzaW5nbGV0b246IGlzU2luZ2xldG9uLFxuICAgICAgfTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGJ1aWxkPFQ+KGRlZnM6IHsgbmFtZTogc3RyaW5nIH0sIC4uLmFyZ3M6IGFueVtdKTogVCB7XG4gICAgY29uc3QgeyBjb25zdHJ1Y3Rvciwgc2luZ2xldG9uIH0gPSB0aGlzLmNhY2hlW2RlZnMubmFtZV07XG4gICAgY29uc3QgaW5zdGFuY2UgPSBuZXcgY29uc3RydWN0b3IoLi4uYXJncyk7XG4gICAgdGhpcy5jYWNoZVtkZWZzLm5hbWVdID0ge1xuICAgICAgaW5zdGFuY2U6IGluc3RhbmNlLFxuICAgICAgY29uc3RydWN0b3I6IGNvbnN0cnVjdG9yLFxuICAgICAgc2luZ2xldG9uOiBzaW5nbGV0b24sXG4gICAgfTtcbiAgICByZXR1cm4gaW5zdGFuY2U7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIEluamVjdGFibGUsXG4gIEluamVjdGFibGVSZWdpc3RyeUltcCxcbiAgSW5qZWN0YWJsZXNSZWdpc3RyeSxcbn0gZnJvbSBcIi4vcmVnaXN0cnlcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBTdGF0aWMgY2xhc3MgSG9sZGluZyB0aGUgYWNjZXNzIHRvIHRoZSBpbmplY3RhYmxlcyBmdW5jdGlvbnNcbiAqXG4gKiBAY2xhc3MgSW5qZWN0YWJsZXNcbiAqIEBzdGF0aWNcbiAqL1xuZXhwb3J0IGNsYXNzIEluamVjdGFibGVzIHtcbiAgcHJpdmF0ZSBzdGF0aWMgYWN0aW5nSW5qZWN0YWJsZXNSZWdpc3RyeT86IEluamVjdGFibGVzUmVnaXN0cnkgPSB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgbmFtZWQge0BsaW5rIEluamVjdGFibGV9IGZyb20gdGhlIHJlZ2lzdHJ5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3NcbiAgICovXG4gIHN0YXRpYyBnZXQ8VD4obmFtZTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IEluamVjdGFibGU8VD4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBJbmplY3RhYmxlcy5nZXRSZWdpc3RyeSgpLmdldChuYW1lLCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSByZWdpc3RlcnMgYW4gaW5qZWN0YWJsZSBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge0luamVjdGFibGV9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3NcbiAgICpcbiAgICovXG4gIHN0YXRpYyByZWdpc3RlcjxUPihjb25zdHJ1Y3RvcjogSW5qZWN0YWJsZTxUPiwgLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICByZXR1cm4gSW5qZWN0YWJsZXMuZ2V0UmVnaXN0cnkoKS5yZWdpc3Rlcihjb25zdHJ1Y3RvciwgLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgSW5zdGFudGlhdGVzIGFuIEluamVjdGFibGVcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBvYmpcbiAgICogQHBhcmFtIHthbnlbXX0gYXJnc1xuICAgKiBAcmV0dXJuIFRcbiAgICpcbiAgICovXG4gIHN0YXRpYyBidWlsZDxUPihvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4sIC4uLmFyZ3M6IGFueVtdKTogVCB7XG4gICAgcmV0dXJuIEluamVjdGFibGVzLmdldFJlZ2lzdHJ5KCkuYnVpbGQob2JqLCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBTZXRzIGEgbmV3IHtAbGluayBJbmplY3RhYmxlc1JlZ2lzdHJ5fVxuICAgKiBAcGFyYW0ge0luamVjdGFibGVzUmVnaXN0cnl9IG9wZXJhdGlvbnNSZWdpc3RyeSB0aGUgbmV3IGltcGxlbWVudGF0aW9uIG9mIFJlZ2lzdHJ5XG4gICAqL1xuICBzdGF0aWMgc2V0UmVnaXN0cnkob3BlcmF0aW9uc1JlZ2lzdHJ5OiBJbmplY3RhYmxlc1JlZ2lzdHJ5KSB7XG4gICAgSW5qZWN0YWJsZXMuYWN0aW5nSW5qZWN0YWJsZXNSZWdpc3RyeSA9IG9wZXJhdGlvbnNSZWdpc3RyeTtcbiAgfVxuICAvKipcbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgY3VycmVudCB7QGxpbmsgSW5qZWN0YWJsZXNSZWdpc3RyeX1cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdldFJlZ2lzdHJ5KCkge1xuICAgIGlmICghSW5qZWN0YWJsZXMuYWN0aW5nSW5qZWN0YWJsZXNSZWdpc3RyeSlcbiAgICAgIEluamVjdGFibGVzLmFjdGluZ0luamVjdGFibGVzUmVnaXN0cnkgPSBuZXcgSW5qZWN0YWJsZVJlZ2lzdHJ5SW1wKCk7XG4gICAgcmV0dXJuIEluamVjdGFibGVzLmFjdGluZ0luamVjdGFibGVzUmVnaXN0cnk7XG4gIH1cblxuICBzdGF0aWMgcmVzZXQoKSB7XG4gICAgSW5qZWN0YWJsZXMuc2V0UmVnaXN0cnkobmV3IEluamVjdGFibGVSZWdpc3RyeUltcCgpKTtcbiAgfVxuXG4gIHN0YXRpYyBzZWxlY3RpdmVSZXNldChtYXRjaDogc3RyaW5nIHwgUmVnRXhwKSB7XG4gICAgY29uc3QgcmVnZXhwID0gdHlwZW9mIG1hdGNoID09PSBcInN0cmluZ1wiID8gbmV3IFJlZ0V4cChtYXRjaCkgOiBtYXRjaDtcbiAgICAoSW5qZWN0YWJsZXMuYWN0aW5nSW5qZWN0YWJsZXNSZWdpc3RyeSBhcyBhbnkpW1wiY2FjaGVcIl0gPSBPYmplY3QuZW50cmllcyhcbiAgICAgIChJbmplY3RhYmxlcy5hY3RpbmdJbmplY3RhYmxlc1JlZ2lzdHJ5IGFzIGFueSlbXCJjYWNoZVwiXVxuICAgICkucmVkdWNlKChhY2N1bTogUmVjb3JkPHN0cmluZywgYW55PiwgW2tleSwgdmFsXSkgPT4ge1xuICAgICAgaWYgKCFrZXkubWF0Y2gocmVnZXhwKSkgYWNjdW1ba2V5XSA9IHZhbDtcbiAgICAgIHJldHVybiBhY2N1bTtcbiAgICB9LCB7fSk7XG4gIH1cbn1cbiIsImltcG9ydCBcInJlZmxlY3QtbWV0YWRhdGFcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBob2xkcyB0aGUga2V5IGZvciB0aGUgZGVzaWduIHR5cGVcbiAqIEBjb25zdCBUeXBlS2V5XG4gKiBAbWVtYmVyT2YgIG1vZHVsZTppbmplY3RhYmxlLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGNvbnN0IFR5cGVLZXkgPSBcImRlc2lnbjp0eXBlXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSB0eXBlIGZyb20gdGhlIGRlY29yYXRvcnNcbiAqIEBwYXJhbSB7YW55fSBtb2RlbFxuICogQHBhcmFtIHtzdHJpbmcgfCBzeW1ib2x9IHByb3BLZXlcbiAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAqXG4gKiBAZnVuY3Rpb24gZ2VUeXBlRnJvbURlY29yYXRvcnNcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHlwZUZyb21EZWNvcmF0b3IoXG4gIG1vZGVsOiBhbnksXG4gIHByb3BLZXk6IHN0cmluZyB8IHN5bWJvbCxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHR5cGVEZWYgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFR5cGVLZXksIG1vZGVsLCBwcm9wS2V5KTtcbiAgcmV0dXJuIHR5cGVEZWYubmFtZSAhPT0gXCJGdW5jdGlvblwiID8gdHlwZURlZi5uYW1lIDogdW5kZWZpbmVkO1xufVxuIiwiaW1wb3J0IHsgSW5qZWN0YWJsZXNLZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBJbmplY3RhYmxlcyB9IGZyb20gXCIuL0luamVjdGFibGVzXCI7XG5pbXBvcnQgeyBnZXRUeXBlRnJvbURlY29yYXRvciB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgUmV0dXJuIHRoZSByZWZsZWN0aW9uIGtleSBmb3IgaW5qZWN0YWJsZXNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAZnVuY3Rpb24gZ2V0SW5qZWN0S2V5XG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTppbmplY3RhYmxlLWRlY29yYXRvcnNcbiAqL1xuY29uc3QgZ2V0SW5qZWN0S2V5ID0gKGtleTogc3RyaW5nKSA9PiBJbmplY3RhYmxlc0tleXMuUkVGTEVDVCArIGtleTtcblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgY2xhc3MgYXMgYW4gaW5qZWN0YWJsZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbY2F0ZWdvcnldIGRlZmF1bHRzIHRvIHRoZSBjbGFzcyBOYW1lLiAoVXNlZnVsIHdoZW4gbWluaWZpY2F0aW9uIG9jY291cnMgYW5kIG5hbWVzIGFyZSBjaGFuZ2VkIHNvIHdlIGNhbiBubyBsb25nZXIgcmVseSBvbiB0aGUgY2xhc3MgbmFtZSwgb3Igd2hlbiB3ZSB3YW50IHRvIHVwY2FzdCB0aGUgT2JqZWN0KVxuICogQHBhcmFtIHtib29sZWFufSBbZm9yY2VdIGRlZmluZXMgaWYgdGhlIGluamVjdGFibGUgc2hvdWxkIG92ZXJyaWRlIHRoZSBhbHJlYWR5IGV4aXN0aW5nIGluc3RhbmNlIChpZiBhbnkpLiAob25seSBtZWFudCBmb3IgZXh0ZW5kaW5nIGRlY29yYXRvcnNcbiAqIEBwYXJhbSBpbnN0YW5jZUNhbGxiYWNrXG4gKlxuICogQGZ1bmN0aW9uIGluamVjdGFibGVcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9ycy5EZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBjb25zdCBpbmplY3RhYmxlID1cbiAgKFxuICAgIGNhdGVnb3J5OiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4gICAgZm9yY2U6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICBpbnN0YW5jZUNhbGxiYWNrPzogKGluc3RhbmNlOiBhbnksIC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkXG4gICkgPT5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAob3JpZ2luYWw6IGFueSwgcHJvcGVydHlLZXk/OiBhbnkpID0+IHtcbiAgICBjb25zdCBuYW1lID0gY2F0ZWdvcnkgfHwgb3JpZ2luYWwubmFtZTtcbiAgICAvLyB0aGUgbmV3IGNvbnN0cnVjdG9yIGJlaGF2aW91clxuICAgIGNvbnN0IG5ld0NvbnN0cnVjdG9yOiBhbnkgPSBmdW5jdGlvbiAoLi4uYXJnczogYW55W10pIHtcbiAgICAgIGxldCBpbmo6IGFueSA9IEluamVjdGFibGVzLmdldDxhbnk+KG5hbWUsIC4uLmFyZ3MpO1xuICAgICAgaWYgKCFpbmopIHtcbiAgICAgICAgSW5qZWN0YWJsZXMucmVnaXN0ZXIob3JpZ2luYWwsIG5hbWUsIHRydWUsIGZvcmNlKTtcbiAgICAgICAgaW5qID0gSW5qZWN0YWJsZXMuZ2V0PGFueT4obmFtZSwgLi4uYXJncyk7XG4gICAgICAgIGlmICghaW5qKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmIChpbnN0YW5jZUNhbGxiYWNrKVxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpbnN0YW5jZUNhbGxiYWNrKGluaik7XG4gICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgICBgRmFpbGVkIHRvIGNhbGwgaW5qZWN0YWJsZSBjYWxsYmFjayBmb3IgJHtuYW1lfTogJHtlfWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBtZXRhZGF0YSA9IE9iamVjdC5hc3NpZ24oXG4gICAgICAgIHt9LFxuICAgICAgICB7XG4gICAgICAgICAgY2xhc3M6IG5hbWUsXG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXG4gICAgICAgIGdldEluamVjdEtleShJbmplY3RhYmxlc0tleXMuSU5KRUNUQUJMRSksXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICBpbmouY29uc3RydWN0b3JcbiAgICAgICk7XG5cbiAgICAgIHJldHVybiBpbmo7XG4gICAgfTtcblxuICAgIC8vIGNvcHkgcHJvdG90eXBlIHNvIGluc3RhbmNlb2Ygb3BlcmF0b3Igc3RpbGwgd29ya3NcbiAgICBuZXdDb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBvcmlnaW5hbC5wcm90b3R5cGU7XG4gICAgLy8gbmV3Q29uc3RydWN0b3IuX19wcm90b19fID0gb3JpZ2luYWwuX19wcm90b19fO1xuICAgIC8vIFNldHMgdGhlIHByb3BlciBjb25zdHJ1Y3RvciBuYW1lIGZvciB0eXBlIHZlcmlmaWNhdGlvblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuZXdDb25zdHJ1Y3RvciwgXCJuYW1lXCIsIHtcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgdmFsdWU6IG9yaWdpbmFsLnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgIH0pO1xuICAgIC8vIHJldHVybiBuZXcgY29uc3RydWN0b3IgKHdpbGwgb3ZlcnJpZGUgb3JpZ2luYWwpXG4gICAgcmV0dXJuIG5ld0NvbnN0cnVjdG9yO1xuICB9O1xuXG4vKipcbiAqIEBzdW1tYXJ5IGZ1bmN0aW9uIHdpdGNoIHRyYW5zZm9ybXMgYSBjYWNoZWQge0BsaW5rIGluamVjdGFibGV9XG4gKlxuICogQHBhcmFtIHthbnl9IGluamVjdGFibGVcbiAqIEBwYXJhbSB7YW55fSBvYmogdGhlIG9iaiB0aGUgaW5qZWN0YWJsZSB3aWxsIGJlIGluamVjdGVkIG9uXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTppbmplY3RhYmxlLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IHR5cGUgSW5zdGFuY2VUcmFuc2Zvcm1lciA9IChpbmplY3RhYmxlOiBhbnksIG9iajogYW55KSA9PiBhbnk7XG5cbi8qKlxuICogQHN1bW1hcnkgQWxsb3dzIGZvciB0aGUgaW5qZWN0aW9uIG9mIGFuIHtAbGluayBpbmplY3RhYmxlfSBkZWNvcmF0ZWQgZGVwZW5kZW5jeVxuICogQGRlc2NyaXB0aW9uIHRoZSBwcm9wZXJ0eSBtdXN0IGJlIHR5cGVkIGZvciB0aGUgcmVxdWVzdGVkIGRlcGVuZGVuY3kuXG4gKlxuICogT25seSBjb25jcmV0ZSBjbGFzc2VzLiBObyBnZW5lcmljcyBhcmUgc3VwcG9ydGVkXG4gKlxuICogSW5qZWN0ZWQgcHJvcGVydGllcyBzaG91bGQgYmUgZGVzY3JpYmVkIGxpa2Ugc286XG4gKiA8cHJlPlxuICogICAgIGNsYXNzIENsYXNzTmFtZSB7XG4gKiAgICAgICAgIC4uLlxuICpcbiAqICAgICAgICAgQGluamVjdCgpXG4gKiAgICAgICAgIHByb3BlcnR5TmFtZSE6IEluamVjdGFibGVDbGFzcztcbiAqXG4gKiAgICAgICAgIC4uLlxuICogICAgIH1cbiAqIDwvcHJlPlxuICpcbiAqIHdoZXJlIEluamVjdGFibGVDbGFzcyBpcyB0aGUgY2xhc3MgeW91IHdhbnQgdG8gaW5qZWN0LlxuICogTm90aWNlIHRoZSB1c2Ugb2YgJyE6JyB0byBlbnN1cmUgdGhlIHRyYW5zcGlsZXIgdGhlIHByb3BlcnR5IHdpbGwgYmUgc2V0IG91dHNpZGUgdGhlIGNvbnN0cnVjdG9yIGJ1dCB3aWxsIGFsd2F5cyBiZSBkZWZpbmVkXG4gKiBGb3IgcHJvamVjdCB3aGVyZSBtaW5pZmljYXRpb24gb2Njb3VycywgeW91IHNob3VsZCB1c2UgdGhlIGNhdGVnb3J5IHBhcmFtIHRvIGVuc3VyZSB0aGUgbmFtZSBpcyB0aGUgc2FtZSB0aHJvdWdob3V0XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtjYXRlZ29yeV0gZGVmYXVsdHMgdG8gdGhlIGNsYXNzIE5hbWUuIChVc2VmdWwgd2hlbiBtaW5pZmljYXRpb24gb2Njb3VycyBhbmQgbmFtZXMgYXJlIGNoYW5nZWQgc28gd2UgY2FuIG5vIGxvbmdlciByZWx5IG9uIHRoZSBjbGFzcyBuYW1lLCBvciB3aGVuIHdlIHdhbnQgdG8gdXBjYXN0IHRoZSBPYmplY3QpXG4gKiBAcGFyYW0ge0luc3RhbmNlVHJhbnNmb3JtZXJ9IFt0cmFuc2Zvcm1lcl1cbiAqXG4gKiBAZnVuY3Rpb24gaW5qZWN0XG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTppbmplY3RhYmxlLWRlY29yYXRvcnMuRGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgaW5qZWN0ID1cbiAgKGNhdGVnb3J5Pzogc3RyaW5nLCB0cmFuc2Zvcm1lcj86IEluc3RhbmNlVHJhbnNmb3JtZXIpID0+XG4gICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk/OiBhbnkpID0+IHtcbiAgICBjb25zdCB2YWx1ZXMgPSBuZXcgV2Vha01hcCgpO1xuXG4gICAgY29uc3QgbmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkID1cbiAgICAgIGNhdGVnb3J5IHx8IGdldFR5cGVGcm9tRGVjb3JhdG9yKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgIGlmICghbmFtZSkgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgZ2V0IFR5cGUgZnJvbSBkZWNvcmF0b3JgKTtcblxuICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXG4gICAgICBnZXRJbmplY3RLZXkoSW5qZWN0YWJsZXNLZXlzLklOSkVDVCksXG4gICAgICB7XG4gICAgICAgIGluamVjdGFibGU6IG5hbWUsXG4gICAgICB9LFxuICAgICAgdGFyZ2V0LFxuICAgICAgcHJvcGVydHlLZXlcbiAgICApO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGdldCh0aGlzOiBhbnkpIHtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvcjogUHJvcGVydHlEZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihcbiAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgcHJvcGVydHlLZXlcbiAgICAgICAgKSBhcyBQcm9wZXJ0eURlc2NyaXB0b3I7XG4gICAgICAgIGlmIChkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSkge1xuICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBwcm9wZXJ0eUtleSwge1xuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICBnZXQodGhpczogYW55KSB7XG4gICAgICAgICAgICAgIGxldCBvYmogPSB2YWx1ZXMuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgICBpZiAoIW9iaikge1xuICAgICAgICAgICAgICAgIG9iaiA9IEluamVjdGFibGVzLmdldChuYW1lKTtcbiAgICAgICAgICAgICAgICBpZiAoIW9iailcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYENvdWxkIG5vdCBnZXQgSW5qZWN0YWJsZSAke25hbWV9IHRvIGluamVjdCBpbiAke3RhcmdldC5jb25zdHJ1Y3RvciA/IHRhcmdldC5jb25zdHJ1Y3Rvci5uYW1lIDogdGFyZ2V0Lm5hbWV9J3MgJHtwcm9wZXJ0eUtleX1gXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGlmICh0cmFuc2Zvcm1lcilcbiAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIG9iaiA9IHRyYW5zZm9ybWVyKG9iaiwgdGFyZ2V0KTtcbiAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YWx1ZXMuc2V0KHRoaXMsIG9iaik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHRoaXNbcHJvcGVydHlLZXldO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9O1xuIiwiLyoqXG4gKiBAc3VtbWFyeSBBZGRzIGEgc2ltcGxlIEluamVjdGFibGVzIGltcGxlbWVudGF0aW9uIHRvIGNyZWF0ZSBzaW5nbGV0b24gaW5zdGFuY2VzIG9mIGFuIG9iamVjdFxuICogYW5kIGVhc2lseSBpbmplY3QgaXQgaW50byBvdGhlciBvYmplY3RzXG4gKlxuICogQG1vZHVsZSBpbmplY3RhYmxlLWRlY29yYXRvcnNcbiAqL1xuXG4vKipcbiAqIEBzdW1tYXJ5IGZ1bmN0aW9ucyB0aGF0IGRlY29yYXRlIGNsYXNzZXMgb3IgY2xhc3MgcHJvcGVydGllc1xuICogQG5hbWVzcGFjZSBEZWNvcmF0b3JzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmluamVjdGFibGUtZGVjb3JhdG9yc1xuICovXG5cbmV4cG9ydCAqIGZyb20gXCIuL2NvbnN0YW50c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vSW5qZWN0YWJsZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3JlZ2lzdHJ5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi91dGlsc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZWQgb24gbGlicmFyeSBidWlsZC4gaG9sZHMgdGhlIGxpYnJhcnkgY3VycmVudCB2ZXJzaW9uXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG1lbWJlck9mIG1vZHVsZTppbmplY3RhYmxlLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBQUE7Ozs7Ozs7OztJQVNHO0FBQ1UsVUFBQSxlQUFlLEdBQUc7SUFDN0IsSUFBQSxPQUFPLEVBQUUsWUFBWTtJQUNyQixJQUFBLFVBQVUsRUFBRSxZQUFZO0lBQ3hCLElBQUEsTUFBTSxFQUFFLFFBQVE7OztJQzRCbEI7Ozs7SUFJRztVQUNVLHFCQUFxQixDQUFBO0lBQWxDLElBQUEsV0FBQSxHQUFBO1lBQ1UsSUFBSyxDQUFBLEtBQUEsR0FBK0IsRUFBRTs7SUFFOUM7O0lBRUc7SUFDSCxJQUFBLEdBQUcsQ0FBSSxJQUFZLEVBQUUsR0FBRyxJQUFXLEVBQUE7SUFDakMsUUFBQSxJQUFJO2dCQUNGLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO0lBQ25DLFlBQUEsTUFBTSxRQUFRLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFO2dCQUMvQixJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRO29CQUMvQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUksUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDO0lBQ3pDLFlB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
|