@travetto/di 5.0.0-rc.8 → 5.0.0-rc.9

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
@@ -16,7 +16,7 @@ yarn add @travetto/di
16
16
  [Dependency injection](https://en.wikipedia.org/wiki/Dependency_injection) is a framework primitive. When used in conjunction with automatic file scanning, it provides for handling of application dependency wiring. Due to the nature of [Typescript](https://typescriptlang.org) and type erasure of interfaces, dependency injection only supports `class`es as a type signifier. The primary goal of dependency injection is to allow for separation of concerns of object creation and it's usage.
17
17
 
18
18
  ## Declaration
19
- The [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L31) and [@InjectableFactory](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L74) decorators provide the registration of dependencies. Dependency declaration revolves around exposing `class`es and subtypes thereof to provide necessary functionality. Additionally, the framework will utilize dependencies to satisfy contracts with various implementation.
19
+ The [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L29) and [@InjectableFactory](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L70) decorators provide the registration of dependencies. Dependency declaration revolves around exposing `class`es and subtypes thereof to provide necessary functionality. Additionally, the framework will utilize dependencies to satisfy contracts with various implementation.
20
20
 
21
21
  **Code: Example Injectable**
22
22
  ```typescript
@@ -77,7 +77,7 @@ class SpecificService extends BaseService {
77
77
  }
78
78
  ```
79
79
 
80
- In this scenario, `SpecificService` is a valid candidate for `BaseService` due to the abstract inheritance. Sometimes, you may want to provide a slight variation to a dependency without extending a class. To this end, the [@InjectableFactory](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L74) decorator denotes a `static` class method that produces an [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L31).
80
+ In this scenario, `SpecificService` is a valid candidate for `BaseService` due to the abstract inheritance. Sometimes, you may want to provide a slight variation to a dependency without extending a class. To this end, the [@InjectableFactory](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L70) decorator denotes a `static` class method that produces an [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L29).
81
81
 
82
82
  **Code: Example InjectableFactory**
83
83
  ```typescript
@@ -125,12 +125,12 @@ 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#L31) 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 [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.
129
129
 
130
130
  ## Injection
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#L31) instances to your code. There are three primary methods for injection:
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:
132
132
 
133
- The [@Inject](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L31) decorator, which denotes a desire to inject a value directly. These will be set post construction.
133
+ The [@Inject](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L29) decorator, which denotes a desire to inject a value directly. These will be set post construction.
134
134
 
135
135
  **Code: Example Injectable with dependencies as Inject fields**
136
136
  ```typescript
@@ -148,7 +148,7 @@ class CustomService {
148
148
  }
149
149
  ```
150
150
 
151
- The [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L31) constructor params, which will be provided as the instance is being constructed.
151
+ The [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L29) constructor params, which will be provided as the instance is being constructed.
152
152
 
153
153
  **Code: Example Injectable with dependencies in constructor**
154
154
  ```typescript
@@ -165,7 +165,7 @@ class CustomService {
165
165
  }
166
166
  ```
167
167
 
168
- Via [@InjectableFactory](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L74) params, which are comparable to constructor params
168
+ Via [@InjectableFactory](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L70) params, which are comparable to constructor params
169
169
 
170
170
  **Code: Example InjectableFactory with parameters as dependencies**
171
171
  ```typescript
@@ -223,9 +223,9 @@ class Config {
223
223
  ```
224
224
 
225
225
  ## Non-Framework Dependencies
226
- The module is built around the framework's management of class registration, and being able to decorate the code with [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L31) decorators. There may also be a desire to leverage external code and pull it into the dependency injection framework. This could easily be achieved using a wrapper class that is owned by the framework.
226
+ The module is built around the framework's management of class registration, and being able to decorate the code with [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L29) decorators. There may also be a desire to leverage external code and pull it into the dependency injection framework. This could easily be achieved using a wrapper class that is owned by the framework.
227
227
 
228
- It is also possible to directly reference external types, and they will be converted into unique symbols. These symbols cannot be used manually, but can be leveraged using [@Inject](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L31) decorators.
228
+ It is also possible to directly reference external types, and they will be converted into unique symbols. These symbols cannot be used manually, but can be leveraged using [@Inject](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L29) decorators.
229
229
 
230
230
  **Code: Example External Dependencies**
231
231
  ```typescript
@@ -233,6 +233,7 @@ import { EventEmitter } from 'node:events';
233
233
  import { Writable } from 'node:stream';
234
234
 
235
235
  import { Inject, Injectable, InjectableFactory } from '@travetto/di';
236
+ import { asFull } from '@travetto/runtime';
236
237
 
237
238
  class Source {
238
239
  @InjectableFactory()
@@ -242,12 +243,12 @@ class Source {
242
243
 
243
244
  @InjectableFactory(Symbol.for('custom-1'))
244
245
  static writable(): Writable {
245
- return {} as Writable;
246
+ return asFull({});
246
247
  }
247
248
 
248
249
  @InjectableFactory(Symbol.for('custom-2'))
249
250
  static writableAlt(): Writable {
250
- return {} as Writable;
251
+ return asFull({});
251
252
  }
252
253
  }
253
254
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/di",
3
- "version": "5.0.0-rc.8",
3
+ "version": "5.0.0-rc.9",
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.0-rc.8"
30
+ "@travetto/registry": "^5.0.0-rc.9"
31
31
  },
32
32
  "peerDependencies": {
33
- "@travetto/transformer": "^5.0.0-rc.5"
33
+ "@travetto/transformer": "^5.0.0-rc.6"
34
34
  },
35
35
  "peerDependenciesMeta": {
36
36
  "@travetto/transformer": {
package/src/decorator.ts CHANGED
@@ -1,11 +1,10 @@
1
- import type { Class, ClassInstance } from '@travetto/runtime';
1
+ import { asConstructable, asFull, TypedFunction, type Class } from '@travetto/runtime';
2
2
 
3
3
  import { InjectableFactoryConfig, InjectableConfig, Dependency } from './types';
4
4
  import { DependencyRegistry, ResolutionType } from './registry';
5
5
 
6
6
  function collapseConfig<T extends { qualifier?: symbol }>(...args: (symbol | Partial<InjectConfig> | undefined)[]): T {
7
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
8
- let out = {} as T;
7
+ let out: Partial<T> = {};
9
8
  if (args) {
10
9
  if (Array.isArray(args)) {
11
10
  for (const arg of args) {
@@ -16,11 +15,10 @@ function collapseConfig<T extends { qualifier?: symbol }>(...args: (symbol | Par
16
15
  }
17
16
  }
18
17
  } else {
19
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
20
- out = args as T;
18
+ out = args;
21
19
  }
22
20
  }
23
- return out;
21
+ return asFull(out);
24
22
  }
25
23
 
26
24
  /**
@@ -30,11 +28,11 @@ function collapseConfig<T extends { qualifier?: symbol }>(...args: (symbol | Par
30
28
  */
31
29
  export function Injectable(first?: Partial<InjectableConfig> | symbol, ...args: (Partial<InjectableConfig> | undefined)[]) {
32
30
  return <T extends Class>(target: T): T => {
33
- const config = collapseConfig<Partial<InjectableConfig>>(first, ...args);
34
-
35
- config.class = target;
36
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
37
- DependencyRegistry.registerClass(target, config as InjectableConfig);
31
+ const config = {
32
+ ...collapseConfig<Partial<InjectableConfig>>(first, ...args),
33
+ class: target
34
+ };
35
+ DependencyRegistry.registerClass(target, config);
38
36
  return target;
39
37
  };
40
38
  }
@@ -43,8 +41,7 @@ export type InjectConfig = { qualifier?: symbol, optional?: boolean, resolution?
43
41
 
44
42
  export function InjectArgs(configs?: InjectConfig[][]) {
45
43
  return <T extends Class>(target: T): void => {
46
- DependencyRegistry.registerConstructor(target,
47
- configs?.map(x => collapseConfig(...x)));
44
+ DependencyRegistry.registerConstructor(target, configs?.map(x => collapseConfig(...x)));
48
45
  };
49
46
  }
50
47
 
@@ -56,11 +53,10 @@ export function InjectArgs(configs?: InjectConfig[][]) {
56
53
  export function Inject(first?: InjectConfig | symbol, ...args: (InjectConfig | undefined)[]) {
57
54
  return (target: unknown, propertyKey?: string, idx?: number | PropertyDescriptor): void => {
58
55
  if (typeof idx !== 'number') { // Only register if on property
59
- const config: InjectConfig = collapseConfig(first, ...args);
56
+ const config = collapseConfig<Dependency>(first, ...args);
60
57
 
61
58
  DependencyRegistry.registerProperty(
62
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
63
- (target as ClassInstance).constructor, propertyKey as string, config as Dependency
59
+ asConstructable(target).constructor, propertyKey!, config
64
60
  );
65
61
  }
66
62
  };
@@ -72,8 +68,7 @@ export function Inject(first?: InjectConfig | symbol, ...args: (InjectConfig | u
72
68
  * @augments `@travetto/di:InjectableFactory`
73
69
  */
74
70
  export function InjectableFactory(first?: Partial<InjectableFactoryConfig> | symbol, ...args: (Partial<InjectableFactoryConfig> | undefined)[]) {
75
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
- return <T extends Class>(target: T, property: string | symbol, descriptor: TypedPropertyDescriptor<((..._: any[]) => any)>): void => {
71
+ return <T extends Class>(target: T, property: string | symbol, descriptor: TypedPropertyDescriptor<TypedFunction>): void => {
77
72
  const config: InjectableFactoryConfig = collapseConfig(first, ...args);
78
73
  DependencyRegistry.registerFactory({
79
74
  ...config,
package/src/registry.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Class, ClassInstance, ConcreteClass, Runtime, describeFunction } from '@travetto/runtime';
1
+ import { Class, Runtime, asConstructable, castTo, classConstruct, describeFunction, asFull, castKey, TypedFunction } from '@travetto/runtime';
2
2
  import { MetadataRegistry, RootRegistry, ChangeEvent } from '@travetto/registry';
3
3
 
4
4
  import { Dependency, InjectableConfig, ClassTarget, InjectableFactoryConfig } from './types';
@@ -14,13 +14,11 @@ export type ResolutionType = 'strict' | 'loose' | 'any';
14
14
  const PrimaryCandidateⲐ = Symbol.for('@travetto/di:primary');
15
15
 
16
16
  function hasPostConstruct(o: unknown): o is { postConstruct: () => Promise<unknown> } {
17
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
18
- return !!o && !!(o as Record<string, unknown>)['postConstruct'];
17
+ return !!o && typeof o === 'object' && 'postConstruct' in o && typeof o.postConstruct === 'function';
19
18
  }
20
19
 
21
20
  function hasPreDestroy(o: unknown): o is { preDestroy: () => unknown } {
22
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
23
- return !!o && !!(o as Record<string, unknown>)['preDestroy'];
21
+ return !!o && typeof o === 'object' && 'preDestroy' in o && typeof o.preDestroy === 'function';
24
22
  }
25
23
 
26
24
  /**
@@ -69,8 +67,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
69
67
  } else if (filtered.length > 1) {
70
68
  // If dealing with sub types, prioritize exact matches
71
69
  const exact = this
72
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
73
- .getCandidateTypes(target as Class)
70
+ .getCandidateTypes(castTo<Class>(target))
74
71
  .filter(x => x.class === target);
75
72
  if (exact.length === 1) {
76
73
  qualifier = exact[0].qualifier;
@@ -98,8 +95,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
98
95
  }
99
96
  }
100
97
 
101
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
102
- const config = this.get(cls!) as InjectableConfig<T>;
98
+ const config: InjectableConfig<T> = castTo(this.get(cls!));
103
99
  return {
104
100
  qualifier,
105
101
  config,
@@ -138,15 +134,13 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
138
134
  */
139
135
  protected async resolveFieldDependencies<T>(config: InjectableConfig<T>, instance: T): Promise<void> {
140
136
  const keys = Object.keys(config.dependencies.fields ?? {})
141
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
142
- .filter(k => instance[k as keyof T] === undefined); // Filter out already set ones
137
+ .filter(k => instance[castKey<T>(k)] === undefined); // Filter out already set ones
143
138
 
144
139
  // And auto-wire
145
140
  if (keys.length) {
146
141
  const deps = await this.fetchDependencies(config, keys.map(x => config.dependencies.fields[x]));
147
142
  for (let i = 0; i < keys.length; i++) {
148
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
149
- instance[keys[i] as keyof T] = deps[i] as T[keyof T];
143
+ instance[castKey<T>(keys[i])] = castTo(deps[i]);
150
144
  }
151
145
  }
152
146
  }
@@ -163,16 +157,14 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
163
157
  // Create instance
164
158
  const inst = managed.factory ?
165
159
  managed.factory(...consValues) :
166
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
167
- new (managed.class as ConcreteClass<T>)(...consValues);
160
+ classConstruct(managed.class, consValues);
168
161
 
169
162
  // And auto-wire fields
170
163
  await this.resolveFieldDependencies(managed, inst);
171
164
 
172
165
  // If factory with field properties on the sub class
173
166
  if (managed.factory) {
174
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
175
- const resolved = this.get((inst as ClassInstance<T>).constructor);
167
+ const resolved = this.get(asConstructable(inst).constructor);
176
168
 
177
169
  if (resolved) {
178
170
  await this.resolveFieldDependencies(resolved, inst);
@@ -199,8 +191,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
199
191
  }
200
192
 
201
193
  if (this.instancePromises.get(classId)!.has(qualifier)) {
202
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
203
- return this.instancePromises.get(classId)!.get(qualifier) as unknown as T;
194
+ return castTo(this.instancePromises.get(classId)!.get(qualifier));
204
195
  }
205
196
 
206
197
  const instancePromise = this.construct(target, qualifier);
@@ -290,27 +281,24 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
290
281
  if (!this.instances.has(classId) || !this.instances.get(classId)!.has(qualifier)) {
291
282
  await this.createInstance(target, qualifier); // Wait for proxy
292
283
  }
293
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
294
- return this.instances.get(classId)!.get(qualifier)! as T;
284
+ return castTo(this.instances.get(classId)!.get(qualifier));
295
285
  }
296
286
 
297
287
  /**
298
288
  * Get all available candidate types for the target
299
289
  */
300
- getCandidateTypes<T>(target: Class<T>): InjectableConfig<T>[] {
290
+ getCandidateTypes<T, U = T>(target: Class<U>): InjectableConfig<T>[] {
301
291
  const targetId = target.Ⲑid;
302
292
  const qualifiers = this.targetToClass.get(targetId)!;
303
293
  const uniqueQualifiers = qualifiers ? Array.from(new Set(qualifiers.values())) : [];
304
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
305
- return uniqueQualifiers.map(id => this.get(id)! as InjectableConfig<T>);
294
+ return castTo(uniqueQualifiers.map(id => this.get(id)));
306
295
  }
307
296
 
308
297
  /**
309
298
  * Get candidate instances by target type, with an optional filter
310
299
  */
311
300
  getCandidateInstances<T>(target: Class, predicate?: (cfg: InjectableConfig<T>) => boolean): Promise<T[]> {
312
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
313
- const inputs = this.getCandidateTypes<T>(target as Class<T>).filter(x => !predicate || predicate(x));
301
+ const inputs = this.getCandidateTypes<T>(target).filter(x => !predicate || predicate(x));
314
302
  return Promise.all(inputs.map(l => this.getInstance<T>(l.class, l.qualifier)));
315
303
  }
316
304
 
@@ -353,9 +341,10 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
353
341
  }
354
342
  if (pConfig.dependencies) {
355
343
  config.dependencies = {
356
- fields: {},
357
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
358
- ...pConfig.dependencies as Omit<InjectableConfig['dependencies'], 'fields'>
344
+ ...pConfig.dependencies,
345
+ fields: {
346
+ ...pConfig.dependencies.fields
347
+ }
359
348
  };
360
349
  }
361
350
  }
@@ -366,7 +355,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
366
355
  registerFactory(config: Omit<InjectableFactoryConfig, 'qualifier'> & {
367
356
  id: string;
368
357
  qualifier?: undefined | symbol;
369
- fn: (...args: unknown[]) => unknown;
358
+ fn: TypedFunction;
370
359
  }): void {
371
360
  const finalConfig: Partial<InjectableConfig> = {};
372
361
 
@@ -388,8 +377,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
388
377
  }
389
378
 
390
379
  // Create mock cls for DI purposes
391
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
392
- const cls = { Ⲑid: config.id } as Class;
380
+ const cls = asFull<Class>({ Ⲑid: config.id });
393
381
 
394
382
  finalConfig.class = cls;
395
383
 
@@ -399,8 +387,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
399
387
  this.factories.set(config.src.Ⲑid, new Map());
400
388
  }
401
389
 
402
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
403
- this.factories.get(config.src.Ⲑid)!.set(cls, finalConfig as InjectableConfig);
390
+ this.factories.get(config.src.Ⲑid)!.set(cls, asFull(finalConfig));
404
391
  }
405
392
 
406
393
  /**
@@ -423,8 +410,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
423
410
  onInstallFinalize<T>(cls: Class<T>): InjectableConfig<T> {
424
411
  const classId = cls.Ⲑid;
425
412
 
426
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
427
- const config = this.getOrCreatePending(cls) as InjectableConfig<T>;
413
+ const config: InjectableConfig<T> = castTo(this.getOrCreatePending(cls));
428
414
 
429
415
  if (!(typeof config.enabled === 'boolean' ? config.enabled : config.enabled())) {
430
416
  return config; // Do not setup if disabled
@@ -557,8 +543,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
557
543
  /**
558
544
  * Inject fields into instance
559
545
  */
560
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
561
- async injectFields<T extends { constructor: Class<T> }>(o: T, cls = o.constructor as Class<T>): Promise<void> {
546
+ async injectFields<T extends { constructor: Class<T> }>(o: T, cls = o.constructor): Promise<void> {
562
547
  this.verifyInitialized();
563
548
  // Compute fields to be auto-wired
564
549
  return await this.resolveFieldDependencies(this.get(cls), o);
@@ -572,8 +557,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
572
557
  ): Promise<Awaited<ReturnType<T['run']>>> {
573
558
  await RootRegistry.init();
574
559
  const inst = await this.getInstance<T>(cls);
575
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
576
- return inst.run(...args) as Awaited<ReturnType<T['run']>>;
560
+ return castTo<Awaited<ReturnType<T['run']>>>(inst.run(...args));
577
561
  }
578
562
  }
579
563
 
@@ -1,4 +1,4 @@
1
- import { Class, ClassInstance, describeFunction } from '@travetto/runtime';
1
+ import { Class, describeFunction } from '@travetto/runtime';
2
2
  import { RetargettingProxy } from '@travetto/registry';
3
3
 
4
4
  import type { DependencyRegistry, ResolutionType, Resolved } from '../src/registry';
@@ -20,7 +20,7 @@ class $DynamicDependencyRegistry {
20
20
  */
21
21
  proxyInstance<T>(target: ClassTarget<T>, qual: symbol | undefined, instance: T): T {
22
22
  const { qualifier, id: classId } = this.#registryResolveTarget(target, qual);
23
- let proxy: RetargettingProxy<T>;
23
+ let proxy: RetargettingProxy<unknown>;
24
24
 
25
25
  if (!this.#proxies.has(classId)) {
26
26
  this.#proxies.set(classId, new Map());
@@ -33,18 +33,16 @@ class $DynamicDependencyRegistry {
33
33
  console.debug('Registering proxy', { id: target.Ⲑid, qualifier: qualifier.toString() });
34
34
  }
35
35
  } else {
36
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
37
- proxy = this.#proxies.get(classId)!.get(qualifier) as RetargettingProxy<T>;
36
+ proxy = this.#proxies.get(classId)!.get(qualifier)!;
38
37
  proxy.setTarget(instance);
39
38
  if (this.#registry.trace) {
40
39
  console.debug('Updating target', {
41
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
42
- id: target.Ⲑid, qualifier: qualifier.toString(), instanceType: (instance as unknown as ClassInstance<T>).constructor.name as string
40
+ id: target.Ⲑid, qualifier: qualifier.toString(), instanceType: target.name
43
41
  });
44
42
  }
45
43
  }
46
44
 
47
- return proxy.get();
45
+ return proxy.get<T>();
48
46
  }
49
47
 
50
48
  /**
@@ -1,4 +1,4 @@
1
- import { Class, ClassInstance } from '@travetto/runtime';
1
+ import { castTo, Class, ClassInstance } from '@travetto/runtime';
2
2
  import { RootRegistry } from '@travetto/registry';
3
3
  import { SuiteRegistry } from '@travetto/test';
4
4
 
@@ -11,9 +11,9 @@ export function InjectableSuite() {
11
11
  return (target: Class) => {
12
12
  SuiteRegistry.registerPendingListener(
13
13
  target,
14
- async function (this: Record<string, Function>) {
14
+ async function (this: unknown) {
15
15
  await RootRegistry.init();
16
- await DependencyRegistry.injectFields(this as ClassInstance, target);
16
+ await DependencyRegistry.injectFields(castTo<ClassInstance>(this), target);
17
17
  },
18
18
  'beforeEach'
19
19
  );
@@ -21,9 +21,11 @@ export class InjectableTransformer {
21
21
  return [];
22
22
  }
23
23
 
24
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
25
- const callExpr = existing?.expression as ts.CallExpression;
26
- const args: ts.Expression[] = [...(callExpr?.arguments ?? [])];
24
+ const args: ts.Expression[] = [];
25
+
26
+ if (existing && ts.isCallExpression(existing.expression)) {
27
+ args.push(...existing.expression.arguments);
28
+ }
27
29
 
28
30
  const payload: { target?: unknown, qualifier?: unknown, optional?: boolean } = {};
29
31
 
@@ -140,6 +142,11 @@ export class InjectableTransformer {
140
142
  return node;
141
143
  }
142
144
 
145
+ const parent = node.parent;
146
+ if (ts.isObjectLiteralExpression(parent)) {
147
+ return node;
148
+ }
149
+
143
150
  const dec = dm?.dec;
144
151
 
145
152
  // Extract config
@@ -148,8 +155,7 @@ export class InjectableTransformer {
148
155
  // Read target from config or resolve
149
156
  const config: { dependencies: unknown[], target?: unknown, qualifier?: unknown, src?: unknown } = {
150
157
  dependencies,
151
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
152
- src: (node.parent as ts.ClassDeclaration).name,
158
+ src: parent.name,
153
159
  };
154
160
  let ret = state.resolveReturnType(node);
155
161
  if (ret.key === 'literal' && ret.ctor === Promise && ret.typeArguments) {