@travetto/di 6.0.0 → 7.0.0-rc.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/README.md +14 -14
- package/__index__.ts +2 -1
- package/package.json +3 -3
- package/src/decorator.ts +30 -57
- package/src/error.ts +2 -3
- package/src/registry/registry-adapter.ts +79 -0
- package/src/registry/registry-index.ts +288 -0
- package/src/registry/registry-resolver.ts +175 -0
- package/src/types.ts +47 -54
- package/support/test/suite.ts +14 -13
- package/src/registry.ts +0 -579
- package/support/dynamic.injection.ts +0 -108
- package/support/transformer.injectable.ts +0 -172
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
|
|
3
|
-
import { TransformerState, DecoratorMeta, OnClass, OnProperty, OnStaticMethod, DecoratorUtil, LiteralUtil, OnSetter } from '@travetto/transformer';
|
|
4
|
-
|
|
5
|
-
const INJECTABLE_IMPORT = '@travetto/di/src/decorator.ts';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Injectable/Injection transformer
|
|
9
|
-
*/
|
|
10
|
-
export class InjectableTransformer {
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Handle a specific declaration param/property
|
|
14
|
-
*/
|
|
15
|
-
static processDeclaration(state: TransformerState, param: ts.ParameterDeclaration | ts.SetAccessorDeclaration | ts.PropertyDeclaration): ts.Expression[] {
|
|
16
|
-
const existing = state.findDecorator(this, param, 'Inject', INJECTABLE_IMPORT);
|
|
17
|
-
const args: ts.Expression[] = [];
|
|
18
|
-
|
|
19
|
-
if (existing && ts.isCallExpression(existing.expression)) {
|
|
20
|
-
args.push(...existing.expression.arguments);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const payload: { target?: unknown, qualifier?: unknown, optional?: boolean } = {};
|
|
24
|
-
|
|
25
|
-
if (!!param.questionToken) {
|
|
26
|
-
payload.optional = true;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const keyParam = ts.isSetAccessorDeclaration(param) ? param.parameters[0] : param;
|
|
30
|
-
payload.target = state.getConcreteType(keyParam);
|
|
31
|
-
args.unshift(state.fromLiteral(payload));
|
|
32
|
-
|
|
33
|
-
return args;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Mark class as Injectable
|
|
38
|
-
*/
|
|
39
|
-
@OnClass('Injectable')
|
|
40
|
-
static registerInjectable(state: TransformerState, node: ts.ClassDeclaration): typeof node {
|
|
41
|
-
const cons = node.members.find((x): x is ts.ConstructorDeclaration => ts.isConstructorDeclaration(x));
|
|
42
|
-
const injectArgs = cons &&
|
|
43
|
-
state.fromLiteral(cons.parameters.map(x => this.processDeclaration(state, x)));
|
|
44
|
-
|
|
45
|
-
// Extract all interfaces
|
|
46
|
-
const interfaces: ts.Node[] = [];
|
|
47
|
-
for (const clause of node.heritageClauses ?? []) {
|
|
48
|
-
if (clause.token === ts.SyntaxKind.ImplementsKeyword) {
|
|
49
|
-
for (const typeExpression of clause.types) {
|
|
50
|
-
const resolvedType = state.resolveType(typeExpression);
|
|
51
|
-
if (resolvedType.key === 'managed') {
|
|
52
|
-
const resolved = state.getOrImport(resolvedType);
|
|
53
|
-
interfaces.push(resolved);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Add injectable decorator if not there
|
|
60
|
-
const decl = state.findDecorator(this, node, 'Injectable', INJECTABLE_IMPORT);
|
|
61
|
-
const args = decl && ts.isCallExpression(decl.expression) ? decl.expression.arguments : [undefined];
|
|
62
|
-
|
|
63
|
-
return state.factory.updateClassDeclaration(node,
|
|
64
|
-
DecoratorUtil.spliceDecorators(node, decl, [
|
|
65
|
-
state.createDecorator(INJECTABLE_IMPORT, 'Injectable', ...args, LiteralUtil.extendObjectLiteral(ts.factory, {}, {
|
|
66
|
-
interfaces
|
|
67
|
-
})),
|
|
68
|
-
state.createDecorator(INJECTABLE_IMPORT, 'InjectArgs', injectArgs)
|
|
69
|
-
]),
|
|
70
|
-
node.name,
|
|
71
|
-
node.typeParameters,
|
|
72
|
-
node.heritageClauses,
|
|
73
|
-
node.members
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Handle Inject annotations for fields/args
|
|
79
|
-
*/
|
|
80
|
-
@OnProperty('Inject')
|
|
81
|
-
static registerInjectProperty(state: TransformerState, node: ts.PropertyDeclaration): typeof node {
|
|
82
|
-
const decl = state.findDecorator(this, node, 'Inject', INJECTABLE_IMPORT);
|
|
83
|
-
|
|
84
|
-
// Doing decls
|
|
85
|
-
return state.factory.updatePropertyDeclaration(
|
|
86
|
-
node,
|
|
87
|
-
DecoratorUtil.spliceDecorators(node, decl, [
|
|
88
|
-
state.createDecorator(INJECTABLE_IMPORT, 'Inject', ...this.processDeclaration(state, node)),
|
|
89
|
-
], 0),
|
|
90
|
-
node.name,
|
|
91
|
-
node.questionToken,
|
|
92
|
-
node.type,
|
|
93
|
-
node.initializer
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Handle Inject annotations for fields/args
|
|
99
|
-
*/
|
|
100
|
-
@OnSetter('Inject')
|
|
101
|
-
static registerInjectSetter(state: TransformerState, node: ts.SetAccessorDeclaration): typeof node {
|
|
102
|
-
const decl = state.findDecorator(this, node, 'Inject', INJECTABLE_IMPORT);
|
|
103
|
-
|
|
104
|
-
const modifiers = DecoratorUtil.spliceDecorators(node, decl, [
|
|
105
|
-
state.createDecorator(INJECTABLE_IMPORT, 'Inject', ...this.processDeclaration(state, node)),
|
|
106
|
-
], 0);
|
|
107
|
-
|
|
108
|
-
// Doing decls
|
|
109
|
-
return state.factory.updateSetAccessorDeclaration(
|
|
110
|
-
node,
|
|
111
|
-
modifiers,
|
|
112
|
-
node.name,
|
|
113
|
-
node.parameters,
|
|
114
|
-
node.body
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Handle InjectableFactory creation
|
|
120
|
-
*/
|
|
121
|
-
@OnStaticMethod('InjectableFactory')
|
|
122
|
-
static registerFactory(state: TransformerState, node: ts.MethodDeclaration, dm?: DecoratorMeta): typeof node {
|
|
123
|
-
if (!dm?.dec) {
|
|
124
|
-
return node;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const parent = node.parent;
|
|
128
|
-
if (ts.isObjectLiteralExpression(parent)) {
|
|
129
|
-
return node;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const dec = dm?.dec;
|
|
133
|
-
|
|
134
|
-
// Extract config
|
|
135
|
-
const dependencies = node.parameters.map(x => this.processDeclaration(state, x));
|
|
136
|
-
|
|
137
|
-
// Read target from config or resolve
|
|
138
|
-
const config: { dependencies: unknown[], target?: unknown, qualifier?: unknown, src?: unknown } = {
|
|
139
|
-
dependencies,
|
|
140
|
-
src: parent.name,
|
|
141
|
-
};
|
|
142
|
-
let returnType = state.resolveReturnType(node);
|
|
143
|
-
if (returnType.key === 'literal' && returnType.ctor === Promise && returnType.typeArguments) {
|
|
144
|
-
returnType = returnType.typeArguments![0];
|
|
145
|
-
}
|
|
146
|
-
if (returnType.key === 'managed') {
|
|
147
|
-
config.target = state.getOrImport(returnType);
|
|
148
|
-
} else if (returnType.key === 'foreign') {
|
|
149
|
-
config.target = state.getForeignTarget(returnType);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Build decl
|
|
153
|
-
const args = [...(dec && ts.isCallExpression(dec.expression) ? dec.expression.arguments : [undefined])];
|
|
154
|
-
|
|
155
|
-
args.unshift(state.extendObjectLiteral(config));
|
|
156
|
-
|
|
157
|
-
// Replace decorator
|
|
158
|
-
return state.factory.updateMethodDeclaration(
|
|
159
|
-
node,
|
|
160
|
-
DecoratorUtil.spliceDecorators(node, dec, [
|
|
161
|
-
state.createDecorator(INJECTABLE_IMPORT, 'InjectableFactory', ...args)
|
|
162
|
-
]),
|
|
163
|
-
node.asteriskToken,
|
|
164
|
-
node.name,
|
|
165
|
-
node.questionToken,
|
|
166
|
-
node.typeParameters,
|
|
167
|
-
node.parameters,
|
|
168
|
-
node.type,
|
|
169
|
-
node.body
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
}
|