@travetto/di 6.0.0-rc.1 → 6.0.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 CHANGED
@@ -43,9 +43,9 @@ class CustomService {
43
43
  }
44
44
  }
45
45
 
46
- const CUSTOM2 = Symbol.for('di-custom2');
46
+ const Custom2Symbol = Symbol.for('di-custom2');
47
47
 
48
- @Injectable({ target: CustomService, qualifier: CUSTOM2 })
48
+ @Injectable({ target: CustomService, qualifier: Custom2Symbol })
49
49
  class CustomService2 extends CustomService {
50
50
  override async coolOperation() {
51
51
  await super.coolOperation();
@@ -54,7 +54,7 @@ class CustomService2 extends CustomService {
54
54
  }
55
55
 
56
56
  class Consumer {
57
- @Inject(CUSTOM2) // Pull in specific service
57
+ @Inject(Custom2Symbol) // Pull in specific service
58
58
  service: CustomService;
59
59
  }
60
60
  ```
@@ -125,7 +125,7 @@ class RuntimeService {
125
125
 
126
126
  In this example, the enabled flag is specified in relationship to the deployment environment. When coupled with optional properties, and optional chaining, allows for seamless inclusion of optional dependencies at runtime.
127
127
 
128
- **Note**: Other modules are able to provide aliases to [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L29) that also provide additional functionality. For example, the [Configuration](https://github.com/travetto/travetto/tree/main/module/config#readme "Configuration support") module @Config or the [RESTful API](https://github.com/travetto/travetto/tree/main/module/rest#readme "Declarative api for RESTful APIs with support for the dependency injection module.") module @Controller decorator registers the associated class as an injectable element.
128
+ **Note**: Other modules are able to provide aliases to [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L29) that also provide additional functionality. For example, the [Configuration](https://github.com/travetto/travetto/tree/main/module/config#readme "Configuration support") module @Config or the [Web API](https://github.com/travetto/travetto/tree/main/module/web#readme "Declarative api for Web Applications with support for the dependency injection.") module @Controller decorator registers the associated class as an injectable element.
129
129
 
130
130
  ## Injection
131
131
  Once all of your necessary dependencies are defined, now is the time to provide those [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L29) instances to your code. There are three primary methods for injection:
@@ -135,7 +135,7 @@ The [@Inject](https://github.com/travetto/travetto/tree/main/module/di/src/decor
135
135
  **Code: Example Injectable with dependencies as Inject fields**
136
136
  ```typescript
137
137
  import { Injectable, Inject } from '@travetto/di';
138
- import { DependentService } from './dep';
138
+ import { DependentService } from './dep.ts';
139
139
 
140
140
  @Injectable()
141
141
  class CustomService {
@@ -153,7 +153,7 @@ The [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/d
153
153
  **Code: Example Injectable with dependencies in constructor**
154
154
  ```typescript
155
155
  import { Injectable } from '@travetto/di';
156
- import { DependentService } from './dep';
156
+ import { DependentService } from './dep.ts';
157
157
 
158
158
  @Injectable()
159
159
  class CustomService {
@@ -176,7 +176,7 @@ Via [@InjectableFactory](https://github.com/travetto/travetto/tree/main/module/d
176
176
  ```typescript
177
177
  import { InjectableFactory } from '@travetto/di';
178
178
 
179
- import { DependentService, CustomService } from './dep';
179
+ import { DependentService, CustomService } from './dep.ts';
180
180
 
181
181
  class Config {
182
182
  @InjectableFactory()
@@ -216,7 +216,7 @@ By default, if there is only one candidate without qualification, then that cand
216
216
  **Code: Example Multiple Candidate Types**
217
217
  ```typescript
218
218
  import { InjectableFactory } from '@travetto/di';
219
- import { Contract, ComplexContract } from './injectable-multiple-default';
219
+ import { Contract, ComplexContract } from './injectable-multiple-default.ts';
220
220
 
221
221
  class Config {
222
222
  // Complex will be marked as the available Contract
@@ -268,7 +268,7 @@ class Service {
268
268
  ```
269
269
 
270
270
  ## Manual Invocation
271
- Some times you will need to lookup a dependency dynamically, or you want to control the injection process at a more granular level. To achieve that you will need to directly access the [DependencyRegistry](https://github.com/travetto/travetto/tree/main/module/di/src/registry.ts#L1). The registry allows for requesting a dependency by class reference:
271
+ Some times you will need to lookup a dependency dynamically, or you want to control the injection process at a more granular level. To achieve that you will need to directly access the [DependencyRegistry](https://github.com/travetto/travetto/tree/main/module/di/src/registry.ts#L25). The registry allows for requesting a dependency by class reference:
272
272
 
273
273
  **Code: Example of Manual Lookup**
274
274
  ```typescript
@@ -290,11 +290,10 @@ Additionally, support for interfaces (over class inheritance) is provided, but r
290
290
  **Code: Example Interface Injection**
291
291
  ```typescript
292
292
  import { DependencyRegistry, Inject, Injectable, InjectableFactory } from '@travetto/di';
293
-
294
- class TargetConcrete { }
293
+ import { toConcrete } from '@travetto/runtime';
295
294
 
296
295
  /**
297
- * @concrete #TargetConcrete
296
+ * @concrete
298
297
  */
299
298
  export interface ServiceContract {
300
299
  deleteUser(userId: string): Promise<void>;
@@ -316,7 +315,7 @@ class SpecificService {
316
315
  class ManualInvocationOfInterface {
317
316
  @InjectableFactory()
318
317
  static getCustomService(): Promise<ServiceContract> {
319
- return DependencyRegistry.getInstance<ServiceContract>(TargetConcrete);
318
+ return DependencyRegistry.getInstance<ServiceContract>(toConcrete<ServiceContract>());
320
319
  }
321
320
  }
322
321
  ```
package/__index__.ts CHANGED
@@ -1,5 +1,4 @@
1
- import type { } from './src/global';
2
- export * from './src/decorator';
3
- export * from './src/error';
4
- export * from './src/registry';
5
- export * from './src/types';
1
+ export * from './src/decorator.ts';
2
+ export * from './src/error.ts';
3
+ export * from './src/registry.ts';
4
+ export * from './src/types.ts';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/di",
3
- "version": "6.0.0-rc.1",
3
+ "version": "6.0.0",
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": "^6.0.0-rc.1"
30
+ "@travetto/registry": "^6.0.0"
31
31
  },
32
32
  "peerDependencies": {
33
- "@travetto/transformer": "^6.0.0-rc.1"
33
+ "@travetto/transformer": "^6.0.0"
34
34
  },
35
35
  "peerDependenciesMeta": {
36
36
  "@travetto/transformer": {
package/src/decorator.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { asConstructable, asFull, TypedFunction, type Class } from '@travetto/runtime';
2
2
 
3
- import { InjectableFactoryConfig, InjectableConfig, Dependency } from './types';
4
- import { DependencyRegistry, ResolutionType } from './registry';
3
+ import { InjectableFactoryConfig, InjectableConfig, Dependency } from './types.ts';
4
+ import { DependencyRegistry, ResolutionType } from './registry.ts';
5
5
 
6
6
  function collapseConfig<T extends { qualifier?: symbol }>(...args: (symbol | Partial<InjectConfig> | undefined)[]): T {
7
7
  let out: Partial<T> = {};
package/src/error.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { AppError } from '@travetto/runtime';
2
- import { ClassTarget } from './types';
2
+ import { ClassTarget } from './types.ts';
3
3
 
4
4
  function getName(symbol: symbol): string {
5
5
  return symbol.toString().split(/[()]/g)[1];
package/src/registry.ts CHANGED
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  Class, Runtime, asConstructable, castTo, classConstruct, describeFunction,
3
- asFull, castKey, TypedFunction, hasFunction
3
+ asFull, castKey, TypedFunction, hasFunction, AppError
4
4
  } from '@travetto/runtime';
5
5
  import { MetadataRegistry, RootRegistry, ChangeEvent } from '@travetto/registry';
6
6
 
7
- import { Dependency, InjectableConfig, ClassTarget, InjectableFactoryConfig } from './types';
8
- import { InjectionError } from './error';
9
- import { AutoCreateTarget } from './internal/types';
7
+ import { Dependency, InjectableConfig, ClassTarget, InjectableFactoryConfig, PostConstructHandler } from './types.ts';
8
+ import { InjectionError } from './error.ts';
10
9
 
10
+ class AutoCreate { }
11
11
  type TargetId = string;
12
12
  type ClassId = string;
13
13
  export type Resolved<T> = { config: InjectableConfig<T>, qualifier: symbol, id: string };
14
14
 
15
15
  export type ResolutionType = 'strict' | 'loose' | 'any';
16
16
 
17
- const PrimaryCandidateSymbol = Symbol.for('@travetto/di:primary');
17
+ const PrimaryCandidateSymbol = Symbol();
18
18
 
19
19
  const hasPostConstruct = hasFunction<{ postConstruct: () => Promise<unknown> }>('postConstruct');
20
20
  const hasPreDestroy = hasFunction<{ preDestroy: () => Promise<unknown> }>('preDestroy');
@@ -104,12 +104,12 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
104
104
  /**
105
105
  * Retrieve all dependencies
106
106
  */
107
- async fetchDependencies(managed: InjectableConfig, deps?: Dependency[]): Promise<unknown[]> {
107
+ async fetchDependencies<T>(managed: InjectableConfig<T>, deps?: Dependency[], keys?: string[]): Promise<unknown[]> {
108
108
  if (!deps || !deps.length) {
109
109
  return [];
110
110
  }
111
111
 
112
- const promises = deps.map(async x => {
112
+ const promises = deps.map(async (x, i) => {
113
113
  try {
114
114
  return await this.getInstance(x.target, x.qualifier, x.resolution);
115
115
  } catch (err) {
@@ -117,7 +117,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
117
117
  return undefined;
118
118
  } else {
119
119
  if (err && err instanceof Error) {
120
- err.message = `${err.message} via=${managed.class.Ⲑid}`;
120
+ err.message = `${err.message} via=${managed.class.Ⲑid}[${keys?.[i] ?? 'constructor'}]`;
121
121
  }
122
122
  throw err;
123
123
  }
@@ -136,7 +136,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
136
136
 
137
137
  // And auto-wire
138
138
  if (keys.length) {
139
- const deps = await this.fetchDependencies(config, keys.map(x => config.dependencies.fields[x]));
139
+ const deps = await this.fetchDependencies(config, keys.map(x => config.dependencies.fields[x]), keys);
140
140
  for (let i = 0; i < keys.length; i++) {
141
141
  instance[castKey<T>(keys[i])] = castTo(deps[i]);
142
142
  }
@@ -174,6 +174,11 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
174
174
  await inst.postConstruct();
175
175
  }
176
176
 
177
+ // Run post constructors
178
+ for (const op of Object.values(managed.postConstruct)) {
179
+ await op(inst);
180
+ }
181
+
177
182
  return inst;
178
183
  }
179
184
 
@@ -226,13 +231,11 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
226
231
  override async init(): Promise<void> {
227
232
  await super.init();
228
233
  if (Runtime.dynamic) {
229
- const { DependencyRegistration } = await import('../support/dynamic.injection');
234
+ const { DependencyRegistration } = await import('../support/dynamic.injection.ts');
230
235
  DependencyRegistration.init(this);
231
236
  }
232
- // Allow for auto-creation
233
- for (const cfg of await this.getCandidateTypes(AutoCreateTarget)) {
234
- await this.getInstance(cfg.class, cfg.qualifier);
235
- }
237
+
238
+ await this.getCandidateInstances(AutoCreate);
236
239
  }
237
240
 
238
241
  /**
@@ -265,7 +268,8 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
265
268
  dependencies: {
266
269
  fields: {},
267
270
  cons: []
268
- }
271
+ },
272
+ postConstruct: {}
269
273
  };
270
274
  }
271
275
 
@@ -275,6 +279,10 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
275
279
  async getInstance<T>(target: ClassTarget<T>, qual?: symbol, resolution?: ResolutionType): Promise<T> {
276
280
  this.verifyInitialized();
277
281
 
282
+ if (!target) {
283
+ throw new AppError('Unable to get instance when target is undefined');
284
+ }
285
+
278
286
  const { id: classId, qualifier } = this.resolveTarget(target, qual, resolution);
279
287
  if (!this.instances.has(classId) || !this.instances.get(classId)!.has(qualifier)) {
280
288
  await this.createInstance(target, qualifier); // Wait for proxy
@@ -285,7 +293,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
285
293
  /**
286
294
  * Get all available candidate types for the target
287
295
  */
288
- getCandidateTypes<T, U = T>(target: Class<U>): InjectableConfig<T>[] {
296
+ getCandidateTypes<T>(target: Class<T>): InjectableConfig<T>[] {
289
297
  const qualifiers = this.targetToClass.get(target.Ⲑid)!;
290
298
  const uniqueQualifiers = qualifiers ? Array.from(new Set(qualifiers.values())) : [];
291
299
  return castTo(uniqueQualifiers.map(id => this.get(id)));
@@ -294,7 +302,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
294
302
  /**
295
303
  * Get candidate instances by target type, with an optional filter
296
304
  */
297
- getCandidateInstances<T>(target: Class, predicate?: (cfg: InjectableConfig<T>) => boolean): Promise<T[]> {
305
+ getCandidateInstances<T>(target: Class<T>, predicate?: (cfg: InjectableConfig<T>) => boolean): Promise<T[]> {
298
306
  const inputs = this.getCandidateTypes<T>(target).filter(x => !predicate || predicate(x));
299
307
  return Promise.all(inputs.map(l => this.getInstance<T>(l.class, l.qualifier)));
300
308
  }
@@ -307,6 +315,14 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
307
315
  conf.dependencies!.cons = dependencies;
308
316
  }
309
317
 
318
+ /**
319
+ * Register a post construct handler
320
+ */
321
+ registerPostConstructHandler<T>(cls: Class<T>, name: string, handler: PostConstructHandler<T>): void {
322
+ const conf = this.getOrCreatePending(cls);
323
+ conf.postConstruct![name] = castTo(handler);
324
+ }
325
+
310
326
  /**
311
327
  * Register a property as a dependency
312
328
  */
@@ -325,7 +341,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
325
341
  config.class = cls;
326
342
  config.qualifier = pConfig.qualifier ?? config.qualifier ?? Symbol.for(cls.Ⲑid);
327
343
  if (pConfig.interfaces) {
328
- config.interfaces?.push(...pConfig.interfaces);
344
+ (config.interfaces ??= []).push(...pConfig.interfaces);
329
345
  }
330
346
  if (pConfig.primary !== undefined) {
331
347
  config.primary = pConfig.primary;
@@ -344,6 +360,9 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
344
360
  }
345
361
  };
346
362
  }
363
+ if (pConfig.autoCreate) {
364
+ (config.interfaces ??= []).push(AutoCreate);
365
+ }
347
366
  }
348
367
 
349
368
  /**
@@ -412,7 +431,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
412
431
 
413
432
  const config: InjectableConfig<T> = castTo(this.getOrCreatePending(cls));
414
433
 
415
- if (!(typeof config.enabled === 'boolean' ? config.enabled : config.enabled())) {
434
+ if (config.enabled !== undefined && !(typeof config.enabled === 'boolean' ? config.enabled : config.enabled())) {
416
435
  return config; // Do not setup if disabled
417
436
  }
418
437
 
@@ -444,6 +463,11 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
444
463
  ...config.interfaces
445
464
  ];
446
465
 
466
+ config.postConstruct = {
467
+ ...parentConfig.postConstruct,
468
+ ...config.postConstruct
469
+ };
470
+
447
471
  // Inherit cons deps if no constructor defined
448
472
  if (config.dependencies.cons === undefined) {
449
473
  config.dependencies.cons = parentConfig.dependencies.cons;
@@ -550,17 +574,6 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
550
574
  // Compute fields to be auto-wired
551
575
  return await this.resolveFieldDependencies(this.get(cls), o);
552
576
  }
553
-
554
- /**
555
- * Execute the run method of a given class
556
- */
557
- async runInstance<T extends { run(..._args: unknown[]): unknown }>(
558
- cls: Class<T>, ...args: Parameters<T['run']>
559
- ): Promise<Awaited<ReturnType<T['run']>>> {
560
- await RootRegistry.init();
561
- const inst = await this.getInstance<T>(cls);
562
- return castTo<Awaited<ReturnType<T['run']>>>(inst.run(...args));
563
- }
564
577
  }
565
578
 
566
579
  export const DependencyRegistry = new $DependencyRegistry();
package/src/types.ts CHANGED
@@ -2,6 +2,8 @@ import { Class } from '@travetto/runtime';
2
2
 
3
3
  export type ClassTarget<T = unknown> = Class<T> | Function;
4
4
 
5
+ export type PostConstructHandler<T> = (value: T) => (void | Promise<void>);
6
+
5
7
  /**
6
8
  * State of a Dependency
7
9
  */
@@ -16,6 +18,24 @@ interface Core<T = unknown> {
16
18
  qualifier: symbol;
17
19
  }
18
20
 
21
+ /**
22
+ * State of a Dependency Target
23
+ */
24
+ interface CoreTarget<T = unknown> extends Core<T> {
25
+ /**
26
+ * Is this injectable enabled
27
+ */
28
+ enabled?: boolean | (() => boolean);
29
+ /**
30
+ * Is this the primary instance
31
+ */
32
+ primary?: boolean;
33
+ /**
34
+ * Should the target be auto-created
35
+ */
36
+ autoCreate?: boolean;
37
+ }
38
+
19
39
  /**
20
40
  * State of a Dependency
21
41
  */
@@ -35,11 +55,7 @@ export interface Dependency<T = unknown> extends Core<T> {
35
55
  /**
36
56
  * Injectable configuration
37
57
  */
38
- export interface InjectableConfig<T = unknown> extends Core<T> {
39
- /**
40
- * Is this injectable enabled
41
- */
42
- enabled: boolean | (() => boolean);
58
+ export interface InjectableConfig<T = unknown> extends CoreTarget<T> {
43
59
  /**
44
60
  * Reference for the class
45
61
  */
@@ -48,10 +64,6 @@ export interface InjectableConfig<T = unknown> extends Core<T> {
48
64
  * Factory function for the injectable
49
65
  */
50
66
  factory?: (...args: unknown[]) => T;
51
- /**
52
- * Is this the primary instance
53
- */
54
- primary: boolean;
55
67
  /**
56
68
  * List of dependencies as fields or as constructor arguments
57
69
  */
@@ -63,31 +75,22 @@ export interface InjectableConfig<T = unknown> extends Core<T> {
63
75
  * List of interface types
64
76
  */
65
77
  interfaces: Class[];
78
+ /**
79
+ * Post construct handlers
80
+ */
81
+ postConstruct: Record<string | symbol, PostConstructHandler<unknown>>;
66
82
  }
67
83
 
68
84
  /**
69
85
  * Factory configuration
70
86
  */
71
- export interface InjectableFactoryConfig<T = unknown> extends Core<T> {
72
- /**
73
- * Is this injectable enabled
74
- */
75
- enabled?: boolean | (() => boolean);
87
+ export interface InjectableFactoryConfig<T = unknown> extends CoreTarget<T> {
76
88
  /**
77
89
  * Src of the factory method
78
90
  */
79
91
  src: Class<T>;
80
- /**
81
- * Is this the primary instance
82
- */
83
- primary?: boolean;
84
92
  /**
85
93
  * List of all dependencies as function arguments
86
94
  */
87
95
  dependencies?: Dependency[];
88
- }
89
-
90
- /**
91
- * @concrete ./internal/types#AutoCreateTarget
92
- */
93
- export interface AutoCreate { }
96
+ }
@@ -1,8 +1,8 @@
1
1
  import { Class, describeFunction } from '@travetto/runtime';
2
2
  import { RetargettingProxy } from '@travetto/registry';
3
3
 
4
- import type { DependencyRegistry, ResolutionType, Resolved } from '../src/registry';
5
- import type { ClassTarget, InjectableConfig } from '../src/types';
4
+ import type { DependencyRegistry, ResolutionType, Resolved } from '../src/registry.ts';
5
+ import type { ClassTarget, InjectableConfig } from '../src/types.ts';
6
6
 
7
7
  /**
8
8
  * Wraps the Dependency Registry to support proxying instances
@@ -89,14 +89,14 @@ class $DynamicDependencyRegistry {
89
89
 
90
90
  register(registry: typeof DependencyRegistry): void {
91
91
  this.#registry = registry;
92
- this.#registryCreateInstance = registry['createInstance'].bind(registry);
93
- this.#registryResolveTarget = registry['resolveTarget'].bind(registry);
94
- this.#registryOnInstallFinalize = registry['onInstallFinalize'].bind(registry);
95
- this.#registryDestroyInstance = registry['destroyInstance'].bind(registry);
92
+ this.#registryCreateInstance = registry.createInstance.bind(registry);
93
+ this.#registryResolveTarget = registry.resolveTarget.bind(registry);
94
+ this.#registryOnInstallFinalize = registry.onInstallFinalize.bind(registry);
95
+ this.#registryDestroyInstance = registry.destroyInstance.bind(registry);
96
96
 
97
- this.#registry['createInstance'] = this.createInstance.bind(this);
98
- this.#registry['destroyInstance'] = this.destroyInstance.bind(this);
99
- this.#registry['onInstallFinalize'] = this.onInstallFinalize.bind(this);
97
+ this.#registry.createInstance = this.createInstance.bind(this);
98
+ this.#registry.destroyInstance = this.destroyInstance.bind(this);
99
+ this.#registry.onInstallFinalize = this.onInstallFinalize.bind(this);
100
100
  }
101
101
  }
102
102
 
@@ -2,7 +2,7 @@ import { castTo, Class, ClassInstance } from '@travetto/runtime';
2
2
  import { RootRegistry } from '@travetto/registry';
3
3
  import { SuiteRegistry } from '@travetto/test';
4
4
 
5
- import { DependencyRegistry } from '../../src/registry';
5
+ import { DependencyRegistry } from '../../src/registry.ts';
6
6
 
7
7
  /**
8
8
  * Registers a suite as injectable
@@ -1,33 +1,19 @@
1
1
  import ts from 'typescript';
2
2
 
3
- import {
4
- TransformerState, DecoratorMeta, OnClass, OnProperty, OnStaticMethod, DecoratorUtil, LiteralUtil, OnSetter
5
- } from '@travetto/transformer';
6
- import { ForeignType } from '@travetto/transformer/src/resolver/types';
3
+ import { TransformerState, DecoratorMeta, OnClass, OnProperty, OnStaticMethod, DecoratorUtil, LiteralUtil, OnSetter } from '@travetto/transformer';
7
4
 
8
- const INJECTABLE_MOD = '@travetto/di/src/decorator';
5
+ const INJECTABLE_IMPORT = '@travetto/di/src/decorator.ts';
9
6
 
10
7
  /**
11
8
  * Injectable/Injection transformer
12
9
  */
13
10
  export class InjectableTransformer {
14
11
 
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
-
21
12
  /**
22
13
  * Handle a specific declaration param/property
23
14
  */
24
15
  static processDeclaration(state: TransformerState, param: ts.ParameterDeclaration | ts.SetAccessorDeclaration | ts.PropertyDeclaration): ts.Expression[] {
25
- const existing = state.findDecorator(this, param, 'Inject', INJECTABLE_MOD);
26
-
27
- if (!(existing || ts.isParameter(param))) {
28
- return [];
29
- }
30
-
16
+ const existing = state.findDecorator(this, param, 'Inject', INJECTABLE_IMPORT);
31
17
  const args: ts.Expression[] = [];
32
18
 
33
19
  if (existing && ts.isCallExpression(existing.expression)) {
@@ -41,18 +27,7 @@ export class InjectableTransformer {
41
27
  }
42
28
 
43
29
  const keyParam = ts.isSetAccessorDeclaration(param) ? param.parameters[0] : param;
44
- const type = state.resolveType(keyParam);
45
-
46
- if (type.key === 'managed') {
47
- payload.target = state.getOrImport(type);
48
- } else if (type.key === 'foreign') {
49
- payload.target = this.getForeignTarget(state, type);
50
- } else {
51
- const file = param.getSourceFile().fileName;
52
- const src = state.getFileImportName(file);
53
- throw new Error(`Unable to import non-external type: ${param.getText()} ${type.key}: ${src}`);
54
- }
55
-
30
+ payload.target = state.getConcreteType(keyParam);
56
31
  args.unshift(state.fromLiteral(payload));
57
32
 
58
33
  return args;
@@ -82,15 +57,15 @@ export class InjectableTransformer {
82
57
  }
83
58
 
84
59
  // Add injectable decorator if not there
85
- const decl = state.findDecorator(this, node, 'Injectable', INJECTABLE_MOD);
60
+ const decl = state.findDecorator(this, node, 'Injectable', INJECTABLE_IMPORT);
86
61
  const args = decl && ts.isCallExpression(decl.expression) ? decl.expression.arguments : [undefined];
87
62
 
88
63
  return state.factory.updateClassDeclaration(node,
89
64
  DecoratorUtil.spliceDecorators(node, decl, [
90
- state.createDecorator(INJECTABLE_MOD, 'Injectable', ...args, LiteralUtil.extendObjectLiteral(ts.factory, {}, {
65
+ state.createDecorator(INJECTABLE_IMPORT, 'Injectable', ...args, LiteralUtil.extendObjectLiteral(ts.factory, {}, {
91
66
  interfaces
92
67
  })),
93
- state.createDecorator(INJECTABLE_MOD, 'InjectArgs', injectArgs)
68
+ state.createDecorator(INJECTABLE_IMPORT, 'InjectArgs', injectArgs)
94
69
  ]),
95
70
  node.name,
96
71
  node.typeParameters,
@@ -103,14 +78,14 @@ export class InjectableTransformer {
103
78
  * Handle Inject annotations for fields/args
104
79
  */
105
80
  @OnProperty('Inject')
106
- static registerInjectProperty(state: TransformerState, node: ts.PropertyDeclaration, dm?: DecoratorMeta): typeof node {
107
- const decl = state.findDecorator(this, node, 'Inject', INJECTABLE_MOD);
81
+ static registerInjectProperty(state: TransformerState, node: ts.PropertyDeclaration): typeof node {
82
+ const decl = state.findDecorator(this, node, 'Inject', INJECTABLE_IMPORT);
108
83
 
109
84
  // Doing decls
110
85
  return state.factory.updatePropertyDeclaration(
111
86
  node,
112
87
  DecoratorUtil.spliceDecorators(node, decl, [
113
- state.createDecorator(INJECTABLE_MOD, 'Inject', ...this.processDeclaration(state, node)),
88
+ state.createDecorator(INJECTABLE_IMPORT, 'Inject', ...this.processDeclaration(state, node)),
114
89
  ], 0),
115
90
  node.name,
116
91
  node.questionToken,
@@ -123,11 +98,11 @@ export class InjectableTransformer {
123
98
  * Handle Inject annotations for fields/args
124
99
  */
125
100
  @OnSetter('Inject')
126
- static registerInjectSetter(state: TransformerState, node: ts.SetAccessorDeclaration, dm?: DecoratorMeta): typeof node {
127
- const decl = state.findDecorator(this, node, 'Inject', INJECTABLE_MOD);
101
+ static registerInjectSetter(state: TransformerState, node: ts.SetAccessorDeclaration): typeof node {
102
+ const decl = state.findDecorator(this, node, 'Inject', INJECTABLE_IMPORT);
128
103
 
129
104
  const modifiers = DecoratorUtil.spliceDecorators(node, decl, [
130
- state.createDecorator(INJECTABLE_MOD, 'Inject', ...this.processDeclaration(state, node)),
105
+ state.createDecorator(INJECTABLE_IMPORT, 'Inject', ...this.processDeclaration(state, node)),
131
106
  ], 0);
132
107
 
133
108
  // Doing decls
@@ -164,14 +139,14 @@ export class InjectableTransformer {
164
139
  dependencies,
165
140
  src: parent.name,
166
141
  };
167
- let ret = state.resolveReturnType(node);
168
- if (ret.key === 'literal' && ret.ctor === Promise && ret.typeArguments) {
169
- ret = ret.typeArguments![0];
142
+ let returnType = state.resolveReturnType(node);
143
+ if (returnType.key === 'literal' && returnType.ctor === Promise && returnType.typeArguments) {
144
+ returnType = returnType.typeArguments![0];
170
145
  }
171
- if (ret.key === 'managed') {
172
- config.target = state.getOrImport(ret);
173
- } else if (ret.key === 'foreign') {
174
- config.target = this.getForeignTarget(state, ret);
146
+ if (returnType.key === 'managed') {
147
+ config.target = state.getOrImport(returnType);
148
+ } else if (returnType.key === 'foreign') {
149
+ config.target = state.getForeignTarget(returnType);
175
150
  }
176
151
 
177
152
  // Build decl
@@ -183,7 +158,7 @@ export class InjectableTransformer {
183
158
  return state.factory.updateMethodDeclaration(
184
159
  node,
185
160
  DecoratorUtil.spliceDecorators(node, dec, [
186
- state.createDecorator(INJECTABLE_MOD, 'InjectableFactory', ...args)
161
+ state.createDecorator(INJECTABLE_IMPORT, 'InjectableFactory', ...args)
187
162
  ]),
188
163
  node.asteriskToken,
189
164
  node.name,
package/src/global.d.ts DELETED
@@ -1,27 +0,0 @@
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
- }
@@ -1 +0,0 @@
1
- export class AutoCreateTarget { }