@travetto/di 5.0.0-rc.0 → 5.0.0-rc.10

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
@@ -100,10 +100,10 @@ Given the `static` method `initService`, the function will be provided as a vali
100
100
 
101
101
  **Code: Example Conditional Dependency**
102
102
  ```typescript
103
- import { Env } from '@travetto/base';
103
+ import { Runtime } from '@travetto/runtime';
104
104
  import { Inject, Injectable } from '@travetto/di';
105
105
 
106
- @Injectable({ enabled: Env.production })
106
+ @Injectable({ enabled: Runtime.production })
107
107
  class ProductionLogger {
108
108
  async log() {
109
109
  console.log('This will only run in production');
@@ -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.0",
3
+ "version": "5.0.0-rc.10",
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.0"
30
+ "@travetto/registry": "^5.0.0-rc.10"
31
31
  },
32
32
  "peerDependencies": {
33
- "@travetto/transformer": "^5.0.0-rc.0"
33
+ "@travetto/transformer": "^5.0.0-rc.7"
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/base';
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/error.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AppError } from '@travetto/base';
1
+ import { AppError } from '@travetto/runtime';
2
2
  import { ClassTarget } from './types';
3
3
 
4
4
  function getName(symbol: symbol): string {
package/src/registry.ts CHANGED
@@ -1,6 +1,5 @@
1
- import { Class, ClassInstance, ConcreteClass, Env } from '@travetto/base';
1
+ import { Class, Runtime, asConstructable, castTo, classConstruct, describeFunction, asFull, castKey, TypedFunction } from '@travetto/runtime';
2
2
  import { MetadataRegistry, RootRegistry, ChangeEvent } from '@travetto/registry';
3
- import { RuntimeIndex } from '@travetto/manifest';
4
3
 
5
4
  import { Dependency, InjectableConfig, ClassTarget, InjectableFactoryConfig } from './types';
6
5
  import { InjectionError } from './error';
@@ -15,13 +14,11 @@ export type ResolutionType = 'strict' | 'loose' | 'any';
15
14
  const PrimaryCandidateⲐ = Symbol.for('@travetto/di:primary');
16
15
 
17
16
  function hasPostConstruct(o: unknown): o is { postConstruct: () => Promise<unknown> } {
18
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
19
- return !!o && !!(o as Record<string, unknown>)['postConstruct'];
17
+ return !!o && typeof o === 'object' && 'postConstruct' in o && typeof o.postConstruct === 'function';
20
18
  }
21
19
 
22
20
  function hasPreDestroy(o: unknown): o is { preDestroy: () => unknown } {
23
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
24
- return !!o && !!(o as Record<string, unknown>)['preDestroy'];
21
+ return !!o && typeof o === 'object' && 'preDestroy' in o && typeof o.preDestroy === 'function';
25
22
  }
26
23
 
27
24
  /**
@@ -70,8 +67,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
70
67
  } else if (filtered.length > 1) {
71
68
  // If dealing with sub types, prioritize exact matches
72
69
  const exact = this
73
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
74
- .getCandidateTypes(target as Class)
70
+ .getCandidateTypes(castTo<Class>(target))
75
71
  .filter(x => x.class === target);
76
72
  if (exact.length === 1) {
77
73
  qualifier = exact[0].qualifier;
@@ -99,8 +95,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
99
95
  }
100
96
  }
101
97
 
102
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
103
- const config = this.get(cls!) as InjectableConfig<T>;
98
+ const config: InjectableConfig<T> = castTo(this.get(cls!));
104
99
  return {
105
100
  qualifier,
106
101
  config,
@@ -139,15 +134,13 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
139
134
  */
140
135
  protected async resolveFieldDependencies<T>(config: InjectableConfig<T>, instance: T): Promise<void> {
141
136
  const keys = Object.keys(config.dependencies.fields ?? {})
142
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
143
- .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
144
138
 
145
139
  // And auto-wire
146
140
  if (keys.length) {
147
141
  const deps = await this.fetchDependencies(config, keys.map(x => config.dependencies.fields[x]));
148
142
  for (let i = 0; i < keys.length; i++) {
149
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
150
- instance[keys[i] as keyof T] = deps[i] as T[keyof T];
143
+ instance[castKey<T>(keys[i])] = castTo(deps[i]);
151
144
  }
152
145
  }
153
146
  }
@@ -164,16 +157,14 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
164
157
  // Create instance
165
158
  const inst = managed.factory ?
166
159
  managed.factory(...consValues) :
167
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
168
- new (managed.class as ConcreteClass<T>)(...consValues);
160
+ classConstruct(managed.class, consValues);
169
161
 
170
162
  // And auto-wire fields
171
163
  await this.resolveFieldDependencies(managed, inst);
172
164
 
173
165
  // If factory with field properties on the sub class
174
166
  if (managed.factory) {
175
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
176
- const resolved = this.get((inst as ClassInstance<T>).constructor);
167
+ const resolved = this.get(asConstructable(inst).constructor);
177
168
 
178
169
  if (resolved) {
179
170
  await this.resolveFieldDependencies(resolved, inst);
@@ -200,8 +191,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
200
191
  }
201
192
 
202
193
  if (this.instancePromises.get(classId)!.has(qualifier)) {
203
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
204
- return this.instancePromises.get(classId)!.get(qualifier) as unknown as T;
194
+ return castTo(this.instancePromises.get(classId)!.get(qualifier));
205
195
  }
206
196
 
207
197
  const instancePromise = this.construct(target, qualifier);
@@ -237,7 +227,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
237
227
 
238
228
  override async init(): Promise<void> {
239
229
  await super.init();
240
- if (Env.dynamic) {
230
+ if (Runtime.dynamic) {
241
231
  const { DependencyRegistration } = await import('../support/dynamic.injection');
242
232
  DependencyRegistration.init(this);
243
233
  }
@@ -291,27 +281,24 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
291
281
  if (!this.instances.has(classId) || !this.instances.get(classId)!.has(qualifier)) {
292
282
  await this.createInstance(target, qualifier); // Wait for proxy
293
283
  }
294
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
295
- return this.instances.get(classId)!.get(qualifier)! as T;
284
+ return castTo(this.instances.get(classId)!.get(qualifier));
296
285
  }
297
286
 
298
287
  /**
299
288
  * Get all available candidate types for the target
300
289
  */
301
- getCandidateTypes<T>(target: Class<T>): InjectableConfig<T>[] {
290
+ getCandidateTypes<T, U = T>(target: Class<U>): InjectableConfig<T>[] {
302
291
  const targetId = target.Ⲑid;
303
292
  const qualifiers = this.targetToClass.get(targetId)!;
304
293
  const uniqueQualifiers = qualifiers ? Array.from(new Set(qualifiers.values())) : [];
305
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
306
- return uniqueQualifiers.map(id => this.get(id)! as InjectableConfig<T>);
294
+ return castTo(uniqueQualifiers.map(id => this.get(id)));
307
295
  }
308
296
 
309
297
  /**
310
298
  * Get candidate instances by target type, with an optional filter
311
299
  */
312
300
  getCandidateInstances<T>(target: Class, predicate?: (cfg: InjectableConfig<T>) => boolean): Promise<T[]> {
313
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
314
- 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));
315
302
  return Promise.all(inputs.map(l => this.getInstance<T>(l.class, l.qualifier)));
316
303
  }
317
304
 
@@ -354,9 +341,10 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
354
341
  }
355
342
  if (pConfig.dependencies) {
356
343
  config.dependencies = {
357
- fields: {},
358
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
359
- ...pConfig.dependencies as Omit<InjectableConfig['dependencies'], 'fields'>
344
+ ...pConfig.dependencies,
345
+ fields: {
346
+ ...pConfig.dependencies.fields
347
+ }
360
348
  };
361
349
  }
362
350
  }
@@ -367,7 +355,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
367
355
  registerFactory(config: Omit<InjectableFactoryConfig, 'qualifier'> & {
368
356
  id: string;
369
357
  qualifier?: undefined | symbol;
370
- fn: (...args: unknown[]) => unknown;
358
+ fn: TypedFunction;
371
359
  }): void {
372
360
  const finalConfig: Partial<InjectableConfig> = {};
373
361
 
@@ -389,8 +377,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
389
377
  }
390
378
 
391
379
  // Create mock cls for DI purposes
392
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
393
- const cls = { Ⲑid: config.id } as Class;
380
+ const cls = asFull<Class>({ Ⲑid: config.id });
394
381
 
395
382
  finalConfig.class = cls;
396
383
 
@@ -400,8 +387,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
400
387
  this.factories.set(config.src.Ⲑid, new Map());
401
388
  }
402
389
 
403
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
404
- this.factories.get(config.src.Ⲑid)!.set(cls, finalConfig as InjectableConfig);
390
+ this.factories.get(config.src.Ⲑid)!.set(cls, asFull(finalConfig));
405
391
  }
406
392
 
407
393
  /**
@@ -424,18 +410,17 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
424
410
  onInstallFinalize<T>(cls: Class<T>): InjectableConfig<T> {
425
411
  const classId = cls.Ⲑid;
426
412
 
427
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
428
- const config = this.getOrCreatePending(cls) as InjectableConfig<T>;
413
+ const config: InjectableConfig<T> = castTo(this.getOrCreatePending(cls));
429
414
 
430
415
  if (!(typeof config.enabled === 'boolean' ? config.enabled : config.enabled())) {
431
416
  return config; // Do not setup if disabled
432
417
  }
433
418
 
434
419
  // Allow for the factory to fulfill the target
435
- let parentClass = config.factory ? config.target : Object.getPrototypeOf(cls);
420
+ let parentClass: Function = config.factory ? config.target : Object.getPrototypeOf(cls);
436
421
 
437
422
  if (config.factory) {
438
- while (RuntimeIndex.getFunctionMetadata(Object.getPrototypeOf(parentClass))?.abstract) {
423
+ while (describeFunction(Object.getPrototypeOf(parentClass))?.abstract) {
439
424
  parentClass = Object.getPrototypeOf(parentClass);
440
425
  }
441
426
  if (!this.targetToClass.has(classId)) {
@@ -465,7 +450,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
465
450
  }
466
451
  }
467
452
 
468
- if (RuntimeIndex.getFunctionMetadata(cls)?.abstract) { // Skip out early, only needed to inherit
453
+ if (describeFunction(cls)?.abstract) { // Skip out early, only needed to inherit
469
454
  return config;
470
455
  }
471
456
 
@@ -500,7 +485,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
500
485
  }
501
486
 
502
487
  // If targeting self (default @Injectable behavior)
503
- if ((classId === targetId || config.factory) && (parentConfig || RuntimeIndex.getFunctionMetadata(parentClass)?.abstract)) {
488
+ if ((classId === targetId || config.factory) && (parentConfig || describeFunction(parentClass)?.abstract)) {
504
489
  const parentId = parentClass.Ⲑid;
505
490
 
506
491
  if (!this.targetToClass.has(parentId)) {
@@ -558,8 +543,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
558
543
  /**
559
544
  * Inject fields into instance
560
545
  */
561
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
562
- 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> {
563
547
  this.verifyInitialized();
564
548
  // Compute fields to be auto-wired
565
549
  return await this.resolveFieldDependencies(this.get(cls), o);
@@ -573,8 +557,7 @@ class $DependencyRegistry extends MetadataRegistry<InjectableConfig> {
573
557
  ): Promise<Awaited<ReturnType<T['run']>>> {
574
558
  await RootRegistry.init();
575
559
  const inst = await this.getInstance<T>(cls);
576
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
577
- return inst.run(...args) as Awaited<ReturnType<T['run']>>;
560
+ return castTo<Awaited<ReturnType<T['run']>>>(inst.run(...args));
578
561
  }
579
562
  }
580
563
 
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Class } from '@travetto/base';
1
+ import { Class } from '@travetto/runtime';
2
2
 
3
3
  export type ClassTarget<T = unknown> = Class<T> | Function;
4
4
 
@@ -1,5 +1,4 @@
1
- import { Class, ClassInstance } from '@travetto/base';
2
- import { RuntimeIndex } from '@travetto/manifest';
1
+ import { Class, describeFunction } from '@travetto/runtime';
3
2
  import { RetargettingProxy } from '@travetto/registry';
4
3
 
5
4
  import type { DependencyRegistry, ResolutionType, Resolved } from '../src/registry';
@@ -21,7 +20,7 @@ class $DynamicDependencyRegistry {
21
20
  */
22
21
  proxyInstance<T>(target: ClassTarget<T>, qual: symbol | undefined, instance: T): T {
23
22
  const { qualifier, id: classId } = this.#registryResolveTarget(target, qual);
24
- let proxy: RetargettingProxy<T>;
23
+ let proxy: RetargettingProxy<unknown>;
25
24
 
26
25
  if (!this.#proxies.has(classId)) {
27
26
  this.#proxies.set(classId, new Map());
@@ -34,18 +33,16 @@ class $DynamicDependencyRegistry {
34
33
  console.debug('Registering proxy', { id: target.Ⲑid, qualifier: qualifier.toString() });
35
34
  }
36
35
  } else {
37
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
38
- proxy = this.#proxies.get(classId)!.get(qualifier) as RetargettingProxy<T>;
36
+ proxy = this.#proxies.get(classId)!.get(qualifier)!;
39
37
  proxy.setTarget(instance);
40
38
  if (this.#registry.trace) {
41
39
  console.debug('Updating target', {
42
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
43
- 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
44
41
  });
45
42
  }
46
43
  }
47
44
 
48
- return proxy.get();
45
+ return proxy.get<T>();
49
46
  }
50
47
 
51
48
  /**
@@ -69,7 +66,7 @@ class $DynamicDependencyRegistry {
69
66
  const classId = cls.Ⲑid;
70
67
 
71
68
  if (
72
- !RuntimeIndex.getFunctionMetadata(cls)?.abstract &&
69
+ !describeFunction(cls)?.abstract &&
73
70
  this.#proxies.has(classId) &&
74
71
  this.#proxies.get(classId)!.has(config.qualifier)
75
72
  ) {
@@ -1,4 +1,4 @@
1
- import { Class, ClassInstance } from '@travetto/base';
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) {