@travetto/di 5.0.14 → 5.0.15
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/__index__.ts +2 -1
- package/package.json +3 -3
- package/src/global.d.ts +27 -0
- package/src/registry.ts +39 -35
- package/support/transformer.injectable.ts +9 -2
package/__index__.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/di",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.15",
|
|
4
4
|
"description": "Dependency registration/management and injection support.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ast-transformations",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"directory": "module/di"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@travetto/registry": "^5.0.
|
|
30
|
+
"@travetto/registry": "^5.0.15"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@travetto/transformer": "^5.0.
|
|
33
|
+
"@travetto/transformer": "^5.0.12"
|
|
34
34
|
},
|
|
35
35
|
"peerDependenciesMeta": {
|
|
36
36
|
"@travetto/transformer": {
|
package/src/global.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import './types';
|
|
2
|
+
|
|
3
|
+
declare global {
|
|
4
|
+
/**
|
|
5
|
+
* @concrete node:buffer#Blob
|
|
6
|
+
*/
|
|
7
|
+
interface Blob { }
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @concrete node:buffer#File
|
|
11
|
+
*/
|
|
12
|
+
interface File { }
|
|
13
|
+
|
|
14
|
+
namespace NodeJS {
|
|
15
|
+
/**
|
|
16
|
+
* @concrete node:stream#Readable
|
|
17
|
+
*/
|
|
18
|
+
interface ReadableStream { }
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare module 'stream' {
|
|
23
|
+
/**
|
|
24
|
+
* @concrete node:stream#Readable
|
|
25
|
+
*/
|
|
26
|
+
interface Readable { }
|
|
27
|
+
}
|
package/src/registry.ts
CHANGED
|
@@ -14,7 +14,7 @@ export type Resolved<T> = { config: InjectableConfig<T>, qualifier: symbol, id:
|
|
|
14
14
|
|
|
15
15
|
export type ResolutionType = 'strict' | 'loose' | 'any';
|
|
16
16
|
|
|
17
|
-
const
|
|
17
|
+
const PrimaryCandidateSymbol = Symbol.for('@travetto/di:primary');
|
|
18
18
|
|
|
19
19
|
const hasPostConstruct = hasFunction<{ postConstruct: () => Promise<unknown> }>('postConstruct');
|
|
20
20
|
const hasPreDestroy = hasFunction<{ preDestroy: () => Promise<unknown> }>('preDestroy');
|
|
@@ -55,8 +55,8 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
|
|
|
55
55
|
const resolved = [...qualifiers.keys()];
|
|
56
56
|
if (!qualifier) {
|
|
57
57
|
// If primary found
|
|
58
|
-
if (qualifiers.has(
|
|
59
|
-
qualifier =
|
|
58
|
+
if (qualifiers.has(PrimaryCandidateSymbol)) {
|
|
59
|
+
qualifier = PrimaryCandidateSymbol;
|
|
60
60
|
} else {
|
|
61
61
|
// If there is only one default symbol
|
|
62
62
|
const filtered = resolved.filter(x => !!x).filter(x => this.defaultSymbols.has(x));
|
|
@@ -219,8 +219,8 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
|
|
|
219
219
|
this.defaultSymbols.delete(qualifier);
|
|
220
220
|
this.instances.get(classId)!.delete(qualifier);
|
|
221
221
|
this.instancePromises.get(classId)!.delete(qualifier);
|
|
222
|
-
this.classToTarget.get(
|
|
223
|
-
console.debug('On uninstall', { id:
|
|
222
|
+
this.classToTarget.get(classId)!.delete(qualifier);
|
|
223
|
+
console.debug('On uninstall', { id: classId, qualifier: qualifier.toString(), classId });
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
override async init(): Promise<void> {
|
|
@@ -286,8 +286,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
|
|
|
286
286
|
* Get all available candidate types for the target
|
|
287
287
|
*/
|
|
288
288
|
getCandidateTypes<T, U = T>(target: Class<U>): InjectableConfig<T>[] {
|
|
289
|
-
const
|
|
290
|
-
const qualifiers = this.targetToClass.get(targetId)!;
|
|
289
|
+
const qualifiers = this.targetToClass.get(target.Ⲑid)!;
|
|
291
290
|
const uniqueQualifiers = qualifiers ? Array.from(new Set(qualifiers.values())) : [];
|
|
292
291
|
return castTo(uniqueQualifiers.map(id => this.get(id)));
|
|
293
292
|
}
|
|
@@ -375,17 +374,19 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
|
|
|
375
374
|
}
|
|
376
375
|
|
|
377
376
|
// Create mock cls for DI purposes
|
|
378
|
-
const
|
|
377
|
+
const fnClass = class { static Ⲑid = config.id; };
|
|
379
378
|
|
|
380
|
-
finalConfig.class =
|
|
379
|
+
finalConfig.class = fnClass;
|
|
381
380
|
|
|
382
|
-
this.registerClass(
|
|
381
|
+
this.registerClass(fnClass, finalConfig);
|
|
383
382
|
|
|
384
|
-
|
|
385
|
-
|
|
383
|
+
const srcClassId = config.src.Ⲑid;
|
|
384
|
+
|
|
385
|
+
if (!this.factories.has(srcClassId)) {
|
|
386
|
+
this.factories.set(srcClassId, new Map());
|
|
386
387
|
}
|
|
387
388
|
|
|
388
|
-
this.factories.get(
|
|
389
|
+
this.factories.get(srcClassId)!.set(fnClass, asFull(finalConfig));
|
|
389
390
|
}
|
|
390
391
|
|
|
391
392
|
/**
|
|
@@ -393,10 +394,11 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
|
|
|
393
394
|
*/
|
|
394
395
|
override onInstall<T>(cls: Class<T>, e: ChangeEvent<Class<T>>): void {
|
|
395
396
|
super.onInstall(cls, e);
|
|
397
|
+
const classId = cls.Ⲑid;
|
|
396
398
|
|
|
397
399
|
// Install factories separate from classes
|
|
398
|
-
if (this.factories.has(
|
|
399
|
-
for (const fact of this.factories.get(
|
|
400
|
+
if (this.factories.has(classId)) {
|
|
401
|
+
for (const fact of this.factories.get(classId)!.keys()) {
|
|
400
402
|
this.onInstall(fact, e);
|
|
401
403
|
}
|
|
402
404
|
}
|
|
@@ -456,34 +458,35 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
|
|
|
456
458
|
this.classToTarget.set(classId, new Map());
|
|
457
459
|
}
|
|
458
460
|
|
|
459
|
-
const
|
|
461
|
+
const targetClassId = config.target.Ⲑid;
|
|
460
462
|
|
|
461
|
-
if (!this.targetToClass.has(
|
|
462
|
-
this.targetToClass.set(
|
|
463
|
+
if (!this.targetToClass.has(targetClassId)) {
|
|
464
|
+
this.targetToClass.set(targetClassId, new Map());
|
|
463
465
|
}
|
|
464
466
|
|
|
465
|
-
if (config.qualifier === Symbol.for(
|
|
467
|
+
if (config.qualifier === Symbol.for(classId)) {
|
|
466
468
|
this.defaultSymbols.add(config.qualifier);
|
|
467
469
|
}
|
|
468
470
|
|
|
469
|
-
this.targetToClass.get(
|
|
470
|
-
this.classToTarget.get(classId)!.set(config.qualifier,
|
|
471
|
+
this.targetToClass.get(targetClassId)!.set(config.qualifier, classId);
|
|
472
|
+
this.classToTarget.get(classId)!.set(config.qualifier, targetClassId);
|
|
471
473
|
|
|
472
474
|
// If aliased
|
|
473
475
|
for (const el of config.interfaces) {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
+
const elClassId = el.Ⲑid;
|
|
477
|
+
if (!this.targetToClass.has(elClassId)) {
|
|
478
|
+
this.targetToClass.set(elClassId, new Map());
|
|
476
479
|
}
|
|
477
|
-
this.targetToClass.get(
|
|
478
|
-
this.classToTarget.get(classId)!.set(Symbol.for(
|
|
480
|
+
this.targetToClass.get(elClassId)!.set(config.qualifier, classId);
|
|
481
|
+
this.classToTarget.get(classId)!.set(Symbol.for(elClassId), elClassId);
|
|
479
482
|
|
|
480
|
-
if (config.primary && (classId ===
|
|
481
|
-
this.targetToClass.get(
|
|
483
|
+
if (config.primary && (classId === targetClassId || config.factory)) {
|
|
484
|
+
this.targetToClass.get(elClassId)!.set(PrimaryCandidateSymbol, classId);
|
|
482
485
|
}
|
|
483
486
|
}
|
|
484
487
|
|
|
485
488
|
// If targeting self (default @Injectable behavior)
|
|
486
|
-
if ((classId ===
|
|
489
|
+
if ((classId === targetClassId || config.factory) && (parentConfig || describeFunction(parentClass)?.abstract)) {
|
|
487
490
|
const parentId = parentClass.Ⲑid;
|
|
488
491
|
|
|
489
492
|
if (!this.targetToClass.has(parentId)) {
|
|
@@ -491,7 +494,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
|
|
|
491
494
|
}
|
|
492
495
|
|
|
493
496
|
if (config.primary) {
|
|
494
|
-
this.targetToClass.get(parentId)!.set(
|
|
497
|
+
this.targetToClass.get(parentId)!.set(PrimaryCandidateSymbol, classId);
|
|
495
498
|
}
|
|
496
499
|
|
|
497
500
|
this.targetToClass.get(parentId)!.set(config.qualifier, classId);
|
|
@@ -502,19 +505,20 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
|
|
|
502
505
|
if (!this.targetToClass.has(classId)) {
|
|
503
506
|
this.targetToClass.set(classId, new Map());
|
|
504
507
|
}
|
|
505
|
-
this.targetToClass.get(classId)!.set(
|
|
508
|
+
this.targetToClass.get(classId)!.set(PrimaryCandidateSymbol, classId);
|
|
506
509
|
|
|
507
510
|
if (config.factory) {
|
|
508
|
-
this.targetToClass.get(
|
|
511
|
+
this.targetToClass.get(targetClassId)!.set(PrimaryCandidateSymbol, classId);
|
|
509
512
|
}
|
|
510
513
|
|
|
511
514
|
// Register primary if only one interface provided and no parent config
|
|
512
515
|
if (config.interfaces.length === 1 && !parentConfig) {
|
|
513
516
|
const [primaryInterface] = config.interfaces;
|
|
514
|
-
|
|
515
|
-
|
|
517
|
+
const primaryClassId = primaryInterface.Ⲑid;
|
|
518
|
+
if (!this.targetToClass.has(primaryClassId)) {
|
|
519
|
+
this.targetToClass.set(primaryClassId, new Map());
|
|
516
520
|
}
|
|
517
|
-
this.targetToClass.get(
|
|
521
|
+
this.targetToClass.get(primaryClassId)!.set(PrimaryCandidateSymbol, classId);
|
|
518
522
|
}
|
|
519
523
|
}
|
|
520
524
|
|
|
@@ -527,7 +531,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
|
|
|
527
531
|
override onUninstallFinalize(cls: Class): void {
|
|
528
532
|
const classId = cls.Ⲑid;
|
|
529
533
|
|
|
530
|
-
if (!this.classToTarget.has(
|
|
534
|
+
if (!this.classToTarget.has(classId)) {
|
|
531
535
|
return;
|
|
532
536
|
}
|
|
533
537
|
|
|
@@ -3,6 +3,7 @@ import ts from 'typescript';
|
|
|
3
3
|
import {
|
|
4
4
|
TransformerState, DecoratorMeta, OnClass, OnProperty, OnStaticMethod, DecoratorUtil, LiteralUtil, OnSetter
|
|
5
5
|
} from '@travetto/transformer';
|
|
6
|
+
import { ForeignType } from '@travetto/transformer/src/resolver/types';
|
|
6
7
|
|
|
7
8
|
const INJECTABLE_MOD = '@travetto/di/src/decorator';
|
|
8
9
|
|
|
@@ -11,6 +12,12 @@ const INJECTABLE_MOD = '@travetto/di/src/decorator';
|
|
|
11
12
|
*/
|
|
12
13
|
export class InjectableTransformer {
|
|
13
14
|
|
|
15
|
+
static getForeignTarget(state: TransformerState, ret: ForeignType): ts.Expression {
|
|
16
|
+
return state.fromLiteral({
|
|
17
|
+
Ⲑid: `${ret.source.split('node_modules/')[1]}+${ret.name}`
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
/**
|
|
15
22
|
* Handle a specific declaration param/property
|
|
16
23
|
*/
|
|
@@ -39,7 +46,7 @@ export class InjectableTransformer {
|
|
|
39
46
|
if (type.key === 'managed') {
|
|
40
47
|
payload.target = state.getOrImport(type);
|
|
41
48
|
} else if (type.key === 'foreign') {
|
|
42
|
-
payload.target =
|
|
49
|
+
payload.target = this.getForeignTarget(state, type);
|
|
43
50
|
} else {
|
|
44
51
|
const file = param.getSourceFile().fileName;
|
|
45
52
|
const src = state.getFileImportName(file);
|
|
@@ -164,7 +171,7 @@ export class InjectableTransformer {
|
|
|
164
171
|
if (ret.key === 'managed') {
|
|
165
172
|
config.target = state.getOrImport(ret);
|
|
166
173
|
} else if (ret.key === 'foreign') {
|
|
167
|
-
config.target =
|
|
174
|
+
config.target = this.getForeignTarget(state, ret);
|
|
168
175
|
}
|
|
169
176
|
|
|
170
177
|
// Build decl
|