@navios/di 0.2.1 → 0.3.1

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.
Files changed (62) hide show
  1. package/README.md +299 -38
  2. package/docs/README.md +121 -48
  3. package/docs/api-reference.md +763 -0
  4. package/docs/container.md +274 -0
  5. package/docs/examples/basic-usage.mts +97 -0
  6. package/docs/examples/factory-pattern.mts +318 -0
  7. package/docs/examples/injection-tokens.mts +225 -0
  8. package/docs/examples/request-scope-example.mts +254 -0
  9. package/docs/examples/service-lifecycle.mts +359 -0
  10. package/docs/factory.md +584 -0
  11. package/docs/getting-started.md +308 -0
  12. package/docs/injectable.md +496 -0
  13. package/docs/injection-tokens.md +400 -0
  14. package/docs/lifecycle.md +539 -0
  15. package/docs/scopes.md +749 -0
  16. package/lib/_tsup-dts-rollup.d.mts +494 -145
  17. package/lib/_tsup-dts-rollup.d.ts +494 -145
  18. package/lib/index.d.mts +26 -12
  19. package/lib/index.d.ts +26 -12
  20. package/lib/index.js +1021 -470
  21. package/lib/index.js.map +1 -1
  22. package/lib/index.mjs +1011 -461
  23. package/lib/index.mjs.map +1 -1
  24. package/package.json +2 -2
  25. package/project.json +10 -2
  26. package/src/__tests__/container.spec.mts +1301 -0
  27. package/src/__tests__/factory.spec.mts +137 -0
  28. package/src/__tests__/injectable.spec.mts +32 -88
  29. package/src/__tests__/injection-token.spec.mts +333 -17
  30. package/src/__tests__/request-scope.spec.mts +427 -0
  31. package/src/__type-tests__/factory.spec-d.mts +65 -0
  32. package/src/__type-tests__/inject.spec-d.mts +27 -28
  33. package/src/__type-tests__/injectable.spec-d.mts +42 -206
  34. package/src/container.mts +167 -0
  35. package/src/decorators/factory.decorator.mts +79 -0
  36. package/src/decorators/index.mts +1 -0
  37. package/src/decorators/injectable.decorator.mts +6 -56
  38. package/src/enums/injectable-scope.enum.mts +5 -1
  39. package/src/event-emitter.mts +18 -20
  40. package/src/factory-context.mts +2 -10
  41. package/src/index.mts +3 -2
  42. package/src/injection-token.mts +19 -4
  43. package/src/injector.mts +8 -20
  44. package/src/interfaces/factory.interface.mts +3 -3
  45. package/src/interfaces/index.mts +2 -0
  46. package/src/interfaces/on-service-destroy.interface.mts +3 -0
  47. package/src/interfaces/on-service-init.interface.mts +3 -0
  48. package/src/registry.mts +7 -16
  49. package/src/request-context-holder.mts +174 -0
  50. package/src/service-instantiator.mts +158 -0
  51. package/src/service-locator-event-bus.mts +0 -28
  52. package/src/service-locator-instance-holder.mts +27 -16
  53. package/src/service-locator-manager.mts +84 -0
  54. package/src/service-locator.mts +548 -393
  55. package/src/utils/defer.mts +73 -0
  56. package/src/utils/get-injectors.mts +91 -78
  57. package/src/utils/index.mts +2 -0
  58. package/src/utils/types.mts +52 -0
  59. package/docs/concepts/injectable.md +0 -182
  60. package/docs/concepts/injection-token.md +0 -145
  61. package/src/proxy-service-locator.mts +0 -83
  62. package/src/resolve-service.mts +0 -41
@@ -0,0 +1,427 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest'
2
+
3
+ import { Container } from '../container.mjs'
4
+ import { Injectable } from '../decorators/injectable.decorator.mjs'
5
+ import { InjectableScope } from '../enums/index.mjs'
6
+ import { inject } from '../index.mjs'
7
+ import { InjectionToken } from '../injection-token.mjs'
8
+ import { Registry } from '../registry.mjs'
9
+ import { createRequestContextHolder } from '../request-context-holder.mjs'
10
+
11
+ describe('Request Scope', () => {
12
+ let container: Container
13
+ let registry: Registry
14
+
15
+ beforeEach(() => {
16
+ registry = new Registry()
17
+ container = new Container(registry)
18
+ })
19
+
20
+ describe('Request-scoped services', () => {
21
+ it('should create different instances for different requests', async () => {
22
+ @Injectable({ registry, scope: InjectableScope.Request })
23
+ class RequestService {
24
+ public readonly requestId = Math.random().toString(36)
25
+ public readonly createdAt = new Date()
26
+ }
27
+
28
+ // Start first request
29
+ container.beginRequest('request-1')
30
+ const instance1a = await container.get(RequestService)
31
+ const instance1b = await container.get(RequestService)
32
+
33
+ // Start second request
34
+ container.beginRequest('request-2')
35
+ const instance2a = await container.get(RequestService)
36
+ const instance2b = await container.get(RequestService)
37
+
38
+ // Within same request, instances should be the same
39
+ expect(instance1a).toBe(instance1b)
40
+ expect(instance2a).toBe(instance2b)
41
+
42
+ // Between different requests, instances should be different
43
+ expect(instance1a).not.toBe(instance2a)
44
+ expect(instance1a.requestId).not.toBe(instance2a.requestId)
45
+
46
+ // Clean up
47
+ await container.endRequest('request-1')
48
+ await container.endRequest('request-2')
49
+ })
50
+
51
+ it('should handle request context lifecycle correctly', async () => {
52
+ @Injectable({ registry, scope: InjectableScope.Request })
53
+ class RequestService {
54
+ public readonly requestId = Math.random().toString(36)
55
+ public destroyed = false
56
+
57
+ async onServiceDestroy() {
58
+ this.destroyed = true
59
+ }
60
+ }
61
+
62
+ // Start request
63
+ const requestId = 'test-request'
64
+ container.beginRequest(requestId)
65
+
66
+ const instance = await container.get(RequestService)
67
+ expect(instance.destroyed).toBe(false)
68
+
69
+ // End request should trigger cleanup
70
+ await container.endRequest(requestId)
71
+ expect(instance.destroyed).toBe(true)
72
+ })
73
+
74
+ it('should support request metadata', async () => {
75
+ const requestId = 'test-request'
76
+ const metadata = { userId: 'user123', sessionId: 'session456' }
77
+
78
+ container.beginRequest(requestId, metadata)
79
+
80
+ // Note: In a real implementation, you might want to inject metadata
81
+ // For now, we'll just verify the context exists
82
+ const context = container.getCurrentRequestContext()
83
+ expect(context).not.toBeNull()
84
+ expect(context?.requestId).toBe(requestId)
85
+ expect(context?.getMetadata('userId')).toBe('user123')
86
+ expect(context?.getMetadata('sessionId')).toBe('session456')
87
+
88
+ await container.endRequest(requestId)
89
+ })
90
+
91
+ it('should handle pre-prepared instances', async () => {
92
+ @Injectable({ registry, scope: InjectableScope.Request })
93
+ class RequestService {
94
+ public readonly requestId = Math.random().toString(36)
95
+ public readonly prePrepared = true
96
+ }
97
+
98
+ const requestId = 'test-request'
99
+ container.beginRequest(requestId)
100
+
101
+ // Getting the instance should be fast (pre-prepared)
102
+ const instance = await container.get(RequestService)
103
+ expect(instance.prePrepared).toBe(true)
104
+
105
+ await container.endRequest(requestId)
106
+ })
107
+
108
+ it('should handle mixed scopes correctly', async () => {
109
+ @Injectable({ registry, scope: InjectableScope.Singleton })
110
+ class SingletonService {
111
+ public readonly id = Math.random().toString(36)
112
+ }
113
+
114
+ @Injectable({ registry, scope: InjectableScope.Request })
115
+ class RequestService {
116
+ public readonly id = Math.random().toString(36)
117
+ singleton: SingletonService = inject(SingletonService)
118
+ }
119
+
120
+ @Injectable({ registry, scope: InjectableScope.Transient })
121
+ class TransientService {
122
+ requestService = inject(RequestService)
123
+ public readonly id = Math.random().toString(36)
124
+ }
125
+
126
+ // Start request
127
+ container.beginRequest('test-request')
128
+
129
+ const requestService1 = await container.get(RequestService)
130
+ const requestService2 = await container.get(RequestService)
131
+ const singleton1 = await container.get(SingletonService)
132
+ const singleton2 = await container.get(SingletonService)
133
+ const transient1 = await container.get(TransientService)
134
+ const transient2 = await container.get(TransientService)
135
+
136
+ // Request-scoped: same instance within request
137
+ expect(requestService1).toBe(requestService2)
138
+ expect(requestService1.singleton).toBe(singleton1)
139
+
140
+ // Singleton: same instance always
141
+ expect(singleton1).toBe(singleton2)
142
+
143
+ // Transient: different instances always
144
+ expect(transient1).not.toBe(transient2)
145
+ expect(transient1.requestService).toBe(transient2.requestService)
146
+
147
+ await container.endRequest('test-request')
148
+ })
149
+
150
+ it('should handle nested request contexts', async () => {
151
+ @Injectable({ registry, scope: InjectableScope.Request })
152
+ class RequestService {
153
+ public readonly id = Math.random().toString(36)
154
+ }
155
+
156
+ // Start first request
157
+ container.beginRequest('request-1')
158
+ const instance1 = await container.get(RequestService)
159
+
160
+ // Start second request (nested)
161
+ container.beginRequest('request-2')
162
+ const instance2 = await container.get(RequestService)
163
+
164
+ // Should be different instances
165
+ expect(instance1).not.toBe(instance2)
166
+
167
+ // End second request
168
+ await container.endRequest('request-2')
169
+
170
+ // Get instance from first request again
171
+ const instance1Again = await container.get(RequestService)
172
+ expect(instance1).toBe(instance1Again)
173
+
174
+ // End first request
175
+ await container.endRequest('request-1')
176
+ })
177
+
178
+ it('should handle request context switching', async () => {
179
+ @Injectable({ registry, scope: InjectableScope.Request })
180
+ class RequestService {
181
+ public readonly id = Math.random().toString(36)
182
+ }
183
+
184
+ // Start multiple requests
185
+ container.beginRequest('request-1')
186
+ container.beginRequest('request-2')
187
+ container.beginRequest('request-3')
188
+
189
+ // Switch to request-1
190
+ container.setCurrentRequestContext('request-1')
191
+ const instance1 = await container.get(RequestService)
192
+
193
+ // Switch to request-2
194
+ container.setCurrentRequestContext('request-2')
195
+ const instance2 = await container.get(RequestService)
196
+
197
+ // Switch back to request-1
198
+ container.setCurrentRequestContext('request-1')
199
+ const instance1Again = await container.get(RequestService)
200
+
201
+ // Should get same instance for request-1
202
+ expect(instance1).toBe(instance1Again)
203
+ // Should get different instance for request-2
204
+ expect(instance1).not.toBe(instance2)
205
+
206
+ // Clean up all requests
207
+ await container.endRequest('request-1')
208
+ await container.endRequest('request-2')
209
+ await container.endRequest('request-3')
210
+ })
211
+ })
212
+
213
+ describe('RequestContextHolder', () => {
214
+ it('should manage instances correctly', () => {
215
+ const holder = createRequestContextHolder('test-request', 100, {
216
+ userId: 'user123',
217
+ })
218
+
219
+ expect(holder.requestId).toBe('test-request')
220
+ expect(holder.priority).toBe(100)
221
+ expect(holder.getMetadata('userId')).toBe('user123')
222
+
223
+ // Add instance
224
+ const mockInstance = { id: 'test-instance' }
225
+ const mockHolder = {
226
+ status: 'Created' as any,
227
+ name: 'test-instance',
228
+ instance: mockInstance,
229
+ creationPromise: null,
230
+ destroyPromise: null,
231
+ type: 'Class' as any,
232
+ scope: 'Request' as any,
233
+ deps: new Set<string>(),
234
+ destroyListeners: [],
235
+ createdAt: Date.now(),
236
+ ttl: Infinity,
237
+ }
238
+
239
+ holder.addInstance('test-instance', mockInstance, mockHolder)
240
+
241
+ expect(holder.hasInstance('test-instance')).toBe(true)
242
+ expect(holder.getInstance('test-instance')).toBe(mockInstance)
243
+ expect(holder.getHolder('test-instance')).toBe(mockHolder)
244
+
245
+ // Clear instances
246
+ holder.clear()
247
+ expect(holder.hasInstance('test-instance')).toBe(false)
248
+ })
249
+
250
+ it('should handle metadata correctly', () => {
251
+ const holder = createRequestContextHolder('test-request')
252
+
253
+ holder.setMetadata('key1', 'value1')
254
+ holder.setMetadata('key2', 'value2')
255
+
256
+ expect(holder.getMetadata('key1')).toBe('value1')
257
+ expect(holder.getMetadata('key2')).toBe('value2')
258
+ expect(holder.getMetadata('nonexistent')).toBeUndefined()
259
+
260
+ holder.clear()
261
+ expect(holder.getMetadata('key1')).toBeUndefined()
262
+ })
263
+
264
+ it('should store instances by InjectionToken', () => {
265
+ const holder = createRequestContextHolder('test-request')
266
+ const token = InjectionToken.create<string>('TestService')
267
+ const instance = { id: 'test-instance', data: 'test-data' }
268
+
269
+ // Store instance by InjectionToken
270
+ holder.addInstance(token, instance)
271
+
272
+ // Verify instance is stored and retrievable
273
+ expect(holder.hasInstance(token.toString())).toBe(true)
274
+ expect(holder.getInstance(token.toString())).toBe(instance)
275
+
276
+ // Verify holder is created with correct properties
277
+ const holderInfo = holder.getHolder(token.toString())
278
+ expect(holderInfo).toBeDefined()
279
+ expect(holderInfo?.instance).toBe(instance)
280
+ expect(holderInfo?.name).toBe(token.toString())
281
+ })
282
+
283
+ it('should store multiple instances by different InjectionTokens', () => {
284
+ const holder = createRequestContextHolder('test-request')
285
+
286
+ const token1 = InjectionToken.create<string>('Service1')
287
+ const token2 = InjectionToken.create<number>('Service2')
288
+ const token3 = InjectionToken.create<boolean>('Service3')
289
+
290
+ const instance1 = { id: 'instance1', type: 'string' }
291
+ const instance2 = { id: 'instance2', type: 'number' }
292
+ const instance3 = { id: 'instance3', type: 'boolean' }
293
+
294
+ // Store multiple instances
295
+ holder.addInstance(token1, instance1)
296
+ holder.addInstance(token2, instance2)
297
+ holder.addInstance(token3, instance3)
298
+
299
+ // Verify all instances are stored correctly
300
+ expect(holder.hasInstance(token1.toString())).toBe(true)
301
+ expect(holder.hasInstance(token2.toString())).toBe(true)
302
+ expect(holder.hasInstance(token3.toString())).toBe(true)
303
+
304
+ expect(holder.getInstance(token1.toString())).toBe(instance1)
305
+ expect(holder.getInstance(token2.toString())).toBe(instance2)
306
+ expect(holder.getInstance(token3.toString())).toBe(instance3)
307
+
308
+ // Verify each has its own holder
309
+ const holder1 = holder.getHolder(token1.toString())
310
+ const holder2 = holder.getHolder(token2.toString())
311
+ const holder3 = holder.getHolder(token3.toString())
312
+
313
+ expect(holder1?.instance).toBe(instance1)
314
+ expect(holder2?.instance).toBe(instance2)
315
+ expect(holder3?.instance).toBe(instance3)
316
+ })
317
+
318
+ it('should override instances stored by InjectionToken', () => {
319
+ const holder = createRequestContextHolder('test-request')
320
+ const token = InjectionToken.create<string>('TestService')
321
+
322
+ const originalInstance = { id: 'original', data: 'original-data' }
323
+ const newInstance = { id: 'new', data: 'new-data' }
324
+
325
+ // Store original instance
326
+ holder.addInstance(token, originalInstance)
327
+ expect(holder.getInstance(token.toString())).toBe(originalInstance)
328
+
329
+ // Override with new instance
330
+ holder.addInstance(token, newInstance)
331
+ expect(holder.getInstance(token.toString())).toBe(newInstance)
332
+ expect(holder.getInstance(token.toString())).not.toBe(originalInstance)
333
+
334
+ // Verify holder is updated
335
+ const holderInfo = holder.getHolder(token.toString())
336
+ expect(holderInfo?.instance).toBe(newInstance)
337
+ })
338
+
339
+ it('should handle InjectionToken with different name types', () => {
340
+ const holder = createRequestContextHolder('test-request')
341
+
342
+ // Test with string name
343
+ const stringToken = InjectionToken.create<string>('StringService')
344
+ const stringInstance = { type: 'string' }
345
+
346
+ // Test with symbol name
347
+ const symbolToken = InjectionToken.create<number>(Symbol('SymbolService'))
348
+ const symbolInstance = { type: 'symbol' }
349
+
350
+ // Test with class name
351
+ class TestClass {}
352
+ const classToken = InjectionToken.create(TestClass)
353
+ const classInstance = { type: 'class' }
354
+
355
+ holder.addInstance(stringToken, stringInstance)
356
+ holder.addInstance(symbolToken, symbolInstance)
357
+ holder.addInstance(classToken, classInstance)
358
+
359
+ expect(holder.getInstance(stringToken.toString())).toBe(stringInstance)
360
+ expect(holder.getInstance(symbolToken.toString())).toBe(symbolInstance)
361
+ expect(holder.getInstance(classToken.toString())).toBe(classInstance)
362
+ })
363
+
364
+ it('should clear instances stored by InjectionToken', () => {
365
+ const holder = createRequestContextHolder('test-request')
366
+ const token1 = InjectionToken.create<string>('Service1')
367
+ const token2 = InjectionToken.create<number>('Service2')
368
+
369
+ const instance1 = { id: 'instance1' }
370
+ const instance2 = { id: 'instance2' }
371
+
372
+ holder.addInstance(token1, instance1)
373
+ holder.addInstance(token2, instance2)
374
+
375
+ expect(holder.hasInstance(token1.toString())).toBe(true)
376
+ expect(holder.hasInstance(token2.toString())).toBe(true)
377
+
378
+ // Clear all instances
379
+ holder.clear()
380
+
381
+ expect(holder.hasInstance(token1.toString())).toBe(false)
382
+ expect(holder.hasInstance(token2.toString())).toBe(false)
383
+ expect(holder.getInstance(token1.toString())).toBeUndefined()
384
+ expect(holder.getInstance(token2.toString())).toBeUndefined()
385
+ })
386
+
387
+ it('should handle mixed storage by InjectionToken and string name', () => {
388
+ const holder = createRequestContextHolder('test-request')
389
+
390
+ const token = InjectionToken.create<string>('TokenService')
391
+ const tokenInstance = { id: 'token-instance' }
392
+
393
+ const stringName = 'string-service'
394
+ const stringInstance = { id: 'string-instance' }
395
+
396
+ // Store by InjectionToken
397
+ holder.addInstance(token, tokenInstance)
398
+
399
+ // Store by string name (requires holder)
400
+ const mockHolder = {
401
+ status: 'Created' as any,
402
+ name: stringName,
403
+ instance: stringInstance,
404
+ creationPromise: null,
405
+ destroyPromise: null,
406
+ type: 'Class' as any,
407
+ scope: 'Singleton' as any,
408
+ deps: new Set<string>(),
409
+ destroyListeners: [],
410
+ createdAt: Date.now(),
411
+ ttl: Infinity,
412
+ }
413
+ holder.addInstance(stringName, stringInstance, mockHolder)
414
+
415
+ // Verify both are stored correctly
416
+ expect(holder.hasInstance(token.toString())).toBe(true)
417
+ expect(holder.hasInstance(stringName)).toBe(true)
418
+
419
+ expect(holder.getInstance(token.toString())).toBe(tokenInstance)
420
+ expect(holder.getInstance(stringName)).toBe(stringInstance)
421
+
422
+ // Verify holders
423
+ expect(holder.getHolder(token.toString())?.instance).toBe(tokenInstance)
424
+ expect(holder.getHolder(stringName)?.instance).toBe(stringInstance)
425
+ })
426
+ })
427
+ })
@@ -0,0 +1,65 @@
1
+ import { z } from 'zod/v4'
2
+
3
+ import type { Factorable, FactorableWithArgs } from '../interfaces/index.mjs'
4
+
5
+ import { Factory } from '../decorators/index.mjs'
6
+ import { InjectableScope } from '../enums/index.mjs'
7
+ import { InjectionToken } from '../injection-token.mjs'
8
+ import { Registry } from '../registry.mjs'
9
+
10
+ // Test factory without arguments
11
+ @Factory()
12
+ class TestFactory1 implements Factorable<string> {
13
+ create() {
14
+ return 'test'
15
+ }
16
+ }
17
+
18
+ // Test factory with scope
19
+ @Factory({ scope: InjectableScope.Transient })
20
+ class TestFactory2 implements Factorable<number> {
21
+ create() {
22
+ return 42
23
+ }
24
+ }
25
+
26
+ // Test factory with token
27
+ const token = InjectionToken.create('TestToken')
28
+ @Factory({ token })
29
+ class TestFactory3 implements Factorable<boolean> {
30
+ create() {
31
+ return true
32
+ }
33
+ }
34
+
35
+ // Test factory with token and schema
36
+ const schema = z.object({ name: z.string() })
37
+ const tokenWithSchema = InjectionToken.create('TestTokenWithSchema', schema)
38
+ @Factory({ token: tokenWithSchema })
39
+ class TestFactory4
40
+ implements FactorableWithArgs<{ name: string }, typeof schema>
41
+ {
42
+ create(ctx: any, args: z.output<typeof schema>) {
43
+ return args
44
+ }
45
+ }
46
+
47
+ // Test factory with custom registry
48
+ const registry = new Registry()
49
+ @Factory({ registry })
50
+ class TestFactory5 implements Factorable<object> {
51
+ create() {
52
+ return {}
53
+ }
54
+ }
55
+
56
+ // Type tests
57
+ const test1: string = new TestFactory1().create()
58
+ const test2: number = new TestFactory2().create()
59
+ const test3: boolean = new TestFactory3().create()
60
+ const test4: { name: string } = new TestFactory4().create(undefined, {
61
+ name: 'test',
62
+ })
63
+ const test5: object = new TestFactory5().create()
64
+
65
+ export { test1, test2, test3, test4, test5 }
@@ -2,9 +2,8 @@ import { assertType, describe, test } from 'vitest'
2
2
  import { z } from 'zod/v4'
3
3
 
4
4
  import { Injectable } from '../decorators/index.mjs'
5
- import { InjectableType } from '../enums/index.mjs'
6
5
  import { InjectionToken } from '../injection-token.mjs'
7
- import { inject } from '../injector.mjs'
6
+ import { asyncInject } from '../injector.mjs'
8
7
 
9
8
  interface FooService {
10
9
  makeFoo(): string
@@ -18,8 +17,8 @@ const simpleOptionalObjectSchema = z
18
17
  foo: z.string(),
19
18
  })
20
19
  .optional()
21
- const simpleRecordSchema = z.record(z.string(), z.string())
22
- const simpleOptionalRecordSchema = z.record(z.string(), z.string()).optional()
20
+ // const simpleRecordSchema = z.record(z.string(), z.string())
21
+ // const simpleOptionalRecordSchema = z.record(z.string(), z.string()).optional()
23
22
 
24
23
  const typelessObjectToken = InjectionToken.create(
25
24
  Symbol.for('Typeless object token'),
@@ -29,14 +28,14 @@ const typelessOptionalObjectToken = InjectionToken.create(
29
28
  Symbol.for('Typeless optional object token'),
30
29
  simpleOptionalObjectSchema,
31
30
  )
32
- const typelessRecordToken = InjectionToken.create(
33
- Symbol.for('Typeless record token'),
34
- simpleRecordSchema,
35
- )
36
- const typelessOptionalRecordToken = InjectionToken.create(
37
- Symbol.for('Typeless optional record token'),
38
- simpleOptionalRecordSchema,
39
- )
31
+ // const typelessRecordToken = InjectionToken.create(
32
+ // Symbol.for('Typeless record token'),
33
+ // simpleRecordSchema,
34
+ // )
35
+ // const typelessOptionalRecordToken = InjectionToken.create(
36
+ // Symbol.for('Typeless optional record token'),
37
+ // simpleOptionalRecordSchema,
38
+ // )
40
39
 
41
40
  const typedObjectToken = InjectionToken.create<
42
41
  FooService,
@@ -46,14 +45,14 @@ const typedOptionalObjectToken = InjectionToken.create<
46
45
  FooService,
47
46
  typeof simpleOptionalObjectSchema
48
47
  >(Symbol.for('Typed optional object token'), simpleOptionalObjectSchema)
49
- const typedRecordToken = InjectionToken.create<
50
- FooService,
51
- typeof simpleRecordSchema
52
- >(Symbol.for('Typed record token'), simpleRecordSchema)
53
- const typedOptionalRecordToken = InjectionToken.create<
54
- FooService,
55
- typeof simpleOptionalRecordSchema
56
- >(Symbol.for('Typed optional record token'), simpleOptionalRecordSchema)
48
+ // const typedRecordToken = InjectionToken.create<
49
+ // FooService,
50
+ // typeof simpleRecordSchema
51
+ // >(Symbol.for('Typed record token'), simpleRecordSchema)
52
+ // const typedOptionalRecordToken = InjectionToken.create<
53
+ // FooService,
54
+ // typeof simpleOptionalRecordSchema
55
+ // >(Symbol.for('Typed optional record token'), simpleOptionalRecordSchema)
57
56
 
58
57
  const typedToken = InjectionToken.create<FooService>(Symbol.for('Typed token'))
59
58
 
@@ -66,34 +65,34 @@ describe('inject', () => {
66
65
  }
67
66
  }
68
67
 
69
- assertType<Foo>(await inject(Foo))
68
+ assertType<Foo>(await asyncInject(Foo))
70
69
  })
71
70
  test('#2 Token with required Schema', async () => {
72
- const result = await inject(typelessObjectToken, { foo: 'bar' })
71
+ const result = await asyncInject(typelessObjectToken, { foo: 'bar' })
73
72
  assertType<unknown>(result)
74
73
 
75
- const result2 = await inject(typedObjectToken, { foo: 'bar' })
74
+ const result2 = await asyncInject(typedObjectToken, { foo: 'bar' })
76
75
  assertType<FooService>(result2)
77
76
 
78
77
  // @ts-expect-error We show error when we pass the wrong type
79
- await inject(typedObjectToken, undefined)
78
+ await asyncInject(typedObjectToken, undefined)
80
79
  })
81
80
 
82
81
  test('#3 Token with optional Schema', async () => {
83
- const result = await inject(typelessOptionalObjectToken)
82
+ const result = await asyncInject(typelessOptionalObjectToken)
84
83
  assertType<unknown>(result)
85
84
 
86
- const result2 = await inject(typedOptionalObjectToken)
85
+ const result2 = await asyncInject(typedOptionalObjectToken)
87
86
  assertType<FooService>(result2)
88
87
 
89
- const result3 = await inject(typedObjectToken)
88
+ const result3 = await asyncInject(typedObjectToken)
90
89
  // Special case when we pass the token without args
91
90
  // We can only return an error string
92
91
  assertType<'Error: Your token requires args: foo'>(result3)
93
92
  })
94
93
 
95
94
  test('#4 Token with no Schema', async () => {
96
- const result = await inject(typedToken)
95
+ const result = await asyncInject(typedToken)
97
96
  assertType<FooService>(result)
98
97
  })
99
98
  })