@navios/di 0.8.0 → 0.9.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.
- package/CHANGELOG.md +102 -0
- package/README.md +117 -17
- package/lib/browser/container/abstract-container.d.mts +112 -0
- package/lib/browser/container/abstract-container.d.mts.map +1 -0
- package/lib/browser/container/abstract-container.mjs +100 -0
- package/lib/browser/container/abstract-container.mjs.map +1 -0
- package/lib/browser/container/container.d.mts +100 -0
- package/lib/browser/container/container.d.mts.map +1 -0
- package/lib/browser/container/container.mjs +424 -0
- package/lib/browser/container/container.mjs.map +1 -0
- package/lib/browser/container/scoped-container.d.mts +93 -0
- package/lib/browser/container/scoped-container.d.mts.map +1 -0
- package/lib/browser/container/scoped-container.mjs +119 -0
- package/lib/browser/container/scoped-container.mjs.map +1 -0
- package/lib/browser/decorators/factory.decorator.d.mts +26 -0
- package/lib/browser/decorators/factory.decorator.d.mts.map +1 -0
- package/lib/browser/decorators/factory.decorator.mjs +20 -0
- package/lib/browser/decorators/factory.decorator.mjs.map +1 -0
- package/lib/browser/decorators/injectable.decorator.d.mts +38 -0
- package/lib/browser/decorators/injectable.decorator.d.mts.map +1 -0
- package/lib/browser/decorators/injectable.decorator.mjs +21 -0
- package/lib/browser/decorators/injectable.decorator.mjs.map +1 -0
- package/lib/browser/enums/injectable-scope.enum.d.mts +18 -0
- package/lib/browser/enums/injectable-scope.enum.d.mts.map +1 -0
- package/lib/browser/enums/injectable-scope.enum.mjs +20 -0
- package/lib/browser/enums/injectable-scope.enum.mjs.map +1 -0
- package/lib/browser/enums/injectable-type.enum.d.mts +8 -0
- package/lib/browser/enums/injectable-type.enum.d.mts.map +1 -0
- package/lib/browser/enums/injectable-type.enum.mjs +10 -0
- package/lib/browser/enums/injectable-type.enum.mjs.map +1 -0
- package/lib/browser/errors/di-error.d.mts +43 -0
- package/lib/browser/errors/di-error.d.mts.map +1 -0
- package/lib/browser/errors/di-error.mjs +98 -0
- package/lib/browser/errors/di-error.mjs.map +1 -0
- package/lib/browser/event-emitter.d.mts +16 -0
- package/lib/browser/event-emitter.d.mts.map +1 -0
- package/lib/browser/event-emitter.mjs +320 -0
- package/lib/browser/event-emitter.mjs.map +1 -0
- package/lib/browser/index.d.mts +37 -1558
- package/lib/browser/index.mjs +29 -2749
- package/lib/browser/interfaces/container.interface.d.mts +59 -0
- package/lib/browser/interfaces/container.interface.d.mts.map +1 -0
- package/lib/browser/interfaces/factory.interface.d.mts +14 -0
- package/lib/browser/interfaces/factory.interface.d.mts.map +1 -0
- package/lib/browser/interfaces/on-service-destroy.interface.d.mts +7 -0
- package/lib/browser/interfaces/on-service-destroy.interface.d.mts.map +1 -0
- package/lib/browser/interfaces/on-service-init.interface.d.mts +7 -0
- package/lib/browser/interfaces/on-service-init.interface.d.mts.map +1 -0
- package/lib/browser/internal/context/async-local-storage.browser.mjs +20 -0
- package/lib/browser/internal/context/async-local-storage.browser.mjs.map +1 -0
- package/lib/browser/internal/context/async-local-storage.d.mts +9 -0
- package/lib/browser/internal/context/async-local-storage.d.mts.map +1 -0
- package/lib/browser/internal/context/async-local-storage.types.d.mts +11 -0
- package/lib/browser/internal/context/async-local-storage.types.d.mts.map +1 -0
- package/lib/browser/internal/context/factory-context.d.mts +23 -0
- package/lib/browser/internal/context/factory-context.d.mts.map +1 -0
- package/lib/browser/internal/context/resolution-context.d.mts +43 -0
- package/lib/browser/internal/context/resolution-context.d.mts.map +1 -0
- package/lib/browser/internal/context/resolution-context.mjs +56 -0
- package/lib/browser/internal/context/resolution-context.mjs.map +1 -0
- package/lib/browser/internal/context/service-initialization-context.d.mts +48 -0
- package/lib/browser/internal/context/service-initialization-context.d.mts.map +1 -0
- package/lib/browser/internal/context/sync-local-storage.mjs +53 -0
- package/lib/browser/internal/context/sync-local-storage.mjs.map +1 -0
- package/lib/browser/internal/core/instance-resolver.d.mts +119 -0
- package/lib/browser/internal/core/instance-resolver.d.mts.map +1 -0
- package/lib/browser/internal/core/instance-resolver.mjs +306 -0
- package/lib/browser/internal/core/instance-resolver.mjs.map +1 -0
- package/lib/browser/internal/core/name-resolver.d.mts +52 -0
- package/lib/browser/internal/core/name-resolver.d.mts.map +1 -0
- package/lib/browser/internal/core/name-resolver.mjs +118 -0
- package/lib/browser/internal/core/name-resolver.mjs.map +1 -0
- package/lib/browser/internal/core/scope-tracker.d.mts +65 -0
- package/lib/browser/internal/core/scope-tracker.d.mts.map +1 -0
- package/lib/browser/internal/core/scope-tracker.mjs +120 -0
- package/lib/browser/internal/core/scope-tracker.mjs.map +1 -0
- package/lib/browser/internal/core/service-initializer.d.mts +44 -0
- package/lib/browser/internal/core/service-initializer.d.mts.map +1 -0
- package/lib/browser/internal/core/service-initializer.mjs +109 -0
- package/lib/browser/internal/core/service-initializer.mjs.map +1 -0
- package/lib/browser/internal/core/service-invalidator.d.mts +81 -0
- package/lib/browser/internal/core/service-invalidator.d.mts.map +1 -0
- package/lib/browser/internal/core/service-invalidator.mjs +142 -0
- package/lib/browser/internal/core/service-invalidator.mjs.map +1 -0
- package/lib/browser/internal/core/token-resolver.d.mts +54 -0
- package/lib/browser/internal/core/token-resolver.d.mts.map +1 -0
- package/lib/browser/internal/core/token-resolver.mjs +77 -0
- package/lib/browser/internal/core/token-resolver.mjs.map +1 -0
- package/lib/browser/internal/holder/holder-storage.interface.d.mts +99 -0
- package/lib/browser/internal/holder/holder-storage.interface.d.mts.map +1 -0
- package/lib/browser/internal/holder/instance-holder.d.mts +101 -0
- package/lib/browser/internal/holder/instance-holder.d.mts.map +1 -0
- package/lib/browser/internal/holder/instance-holder.mjs +19 -0
- package/lib/browser/internal/holder/instance-holder.mjs.map +1 -0
- package/lib/browser/internal/holder/unified-storage.d.mts +53 -0
- package/lib/browser/internal/holder/unified-storage.d.mts.map +1 -0
- package/lib/browser/internal/holder/unified-storage.mjs +144 -0
- package/lib/browser/internal/holder/unified-storage.mjs.map +1 -0
- package/lib/browser/internal/lifecycle/circular-detector.d.mts +39 -0
- package/lib/browser/internal/lifecycle/circular-detector.d.mts.map +1 -0
- package/lib/browser/internal/lifecycle/circular-detector.mjs +55 -0
- package/lib/browser/internal/lifecycle/circular-detector.mjs.map +1 -0
- package/lib/browser/internal/lifecycle/lifecycle-event-bus.d.mts +18 -0
- package/lib/browser/internal/lifecycle/lifecycle-event-bus.d.mts.map +1 -0
- package/lib/browser/internal/lifecycle/lifecycle-event-bus.mjs +43 -0
- package/lib/browser/internal/lifecycle/lifecycle-event-bus.mjs.map +1 -0
- package/lib/browser/internal/stub-factory-class.d.mts +14 -0
- package/lib/browser/internal/stub-factory-class.d.mts.map +1 -0
- package/lib/browser/internal/stub-factory-class.mjs +18 -0
- package/lib/browser/internal/stub-factory-class.mjs.map +1 -0
- package/lib/browser/symbols/injectable-token.d.mts +5 -0
- package/lib/browser/symbols/injectable-token.d.mts.map +1 -0
- package/lib/browser/symbols/injectable-token.mjs +6 -0
- package/lib/browser/symbols/injectable-token.mjs.map +1 -0
- package/lib/browser/token/injection-token.d.mts +55 -0
- package/lib/browser/token/injection-token.d.mts.map +1 -0
- package/lib/browser/token/injection-token.mjs +100 -0
- package/lib/browser/token/injection-token.mjs.map +1 -0
- package/lib/browser/token/registry.d.mts +37 -0
- package/lib/browser/token/registry.d.mts.map +1 -0
- package/lib/browser/token/registry.mjs +86 -0
- package/lib/browser/token/registry.mjs.map +1 -0
- package/lib/browser/utils/default-injectors.d.mts +12 -0
- package/lib/browser/utils/default-injectors.d.mts.map +1 -0
- package/lib/browser/utils/default-injectors.mjs +13 -0
- package/lib/browser/utils/default-injectors.mjs.map +1 -0
- package/lib/browser/utils/get-injectable-token.d.mts +9 -0
- package/lib/browser/utils/get-injectable-token.d.mts.map +1 -0
- package/lib/browser/utils/get-injectable-token.mjs +13 -0
- package/lib/browser/utils/get-injectable-token.mjs.map +1 -0
- package/lib/browser/utils/get-injectors.d.mts +55 -0
- package/lib/browser/utils/get-injectors.d.mts.map +1 -0
- package/lib/browser/utils/get-injectors.mjs +121 -0
- package/lib/browser/utils/get-injectors.mjs.map +1 -0
- package/lib/browser/utils/types.d.mts +23 -0
- package/lib/browser/utils/types.d.mts.map +1 -0
- package/lib/{container-DAKOvAgr.mjs → container-8-z89TyQ.mjs} +1325 -1462
- package/lib/container-8-z89TyQ.mjs.map +1 -0
- package/lib/{container-Bp1W-pWJ.d.mts → container-CNiqesCL.d.mts} +598 -617
- package/lib/container-CNiqesCL.d.mts.map +1 -0
- package/lib/{container-DENMeJ87.cjs → container-CaY2fDuk.cjs} +1369 -1512
- package/lib/container-CaY2fDuk.cjs.map +1 -0
- package/lib/{container-YPwvmlK2.d.cts → container-D-0Ho3qL.d.cts} +598 -612
- package/lib/container-D-0Ho3qL.d.cts.map +1 -0
- package/lib/index.cjs +13 -15
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +58 -223
- package/lib/index.d.cts.map +1 -1
- package/lib/index.d.mts +62 -222
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +5 -6
- package/lib/index.mjs.map +1 -1
- package/lib/testing/index.cjs +582 -311
- package/lib/testing/index.cjs.map +1 -1
- package/lib/testing/index.d.cts +371 -41
- package/lib/testing/index.d.cts.map +1 -1
- package/lib/testing/index.d.mts +371 -41
- package/lib/testing/index.d.mts.map +1 -1
- package/lib/testing/index.mjs +581 -305
- package/lib/testing/index.mjs.map +1 -1
- package/package.json +2 -1
- package/src/__tests__/circular-detector.spec.mts +193 -0
- package/src/__tests__/concurrent.spec.mts +368 -0
- package/src/__tests__/container.spec.mts +32 -30
- package/src/__tests__/di-error.spec.mts +351 -0
- package/src/__tests__/e2e.browser.spec.mts +0 -4
- package/src/__tests__/e2e.spec.mts +10 -19
- package/src/__tests__/event-emitter.spec.mts +232 -109
- package/src/__tests__/get-injectors.spec.mts +250 -39
- package/src/__tests__/injection-token.spec.mts +293 -349
- package/src/__tests__/library-findings.spec.mts +8 -8
- package/src/__tests__/registry.spec.mts +358 -210
- package/src/__tests__/resolution-context.spec.mts +255 -0
- package/src/__tests__/scope-tracker.spec.mts +598 -0
- package/src/__tests__/scope-upgrade.spec.mts +808 -0
- package/src/__tests__/scoped-container.spec.mts +595 -0
- package/src/__tests__/test-container.spec.mts +293 -0
- package/src/__tests__/token-resolver.spec.mts +207 -0
- package/src/__tests__/unified-storage.spec.mts +535 -0
- package/src/__tests__/unit-test-container.spec.mts +529 -0
- package/src/__type-tests__/container.spec-d.mts +180 -0
- package/src/__type-tests__/factory.spec-d.mts +15 -3
- package/src/__type-tests__/inject.spec-d.mts +115 -20
- package/src/__type-tests__/injectable.spec-d.mts +69 -52
- package/src/__type-tests__/injection-token.spec-d.mts +176 -0
- package/src/__type-tests__/scoped-container.spec-d.mts +212 -0
- package/src/container/abstract-container.mts +327 -0
- package/src/container/container.mts +142 -170
- package/src/container/scoped-container.mts +126 -208
- package/src/decorators/factory.decorator.mts +16 -11
- package/src/decorators/injectable.decorator.mts +20 -16
- package/src/enums/index.mts +2 -2
- package/src/enums/injectable-scope.enum.mts +1 -0
- package/src/enums/injectable-type.enum.mts +1 -0
- package/src/errors/di-error.mts +96 -0
- package/src/event-emitter.mts +3 -27
- package/src/index.mts +6 -153
- package/src/interfaces/container.interface.mts +13 -0
- package/src/interfaces/factory.interface.mts +1 -1
- package/src/interfaces/index.mts +1 -1
- package/src/internal/context/async-local-storage.mts +3 -2
- package/src/internal/context/async-local-storage.types.mts +1 -0
- package/src/internal/context/factory-context.mts +1 -0
- package/src/internal/context/index.mts +3 -1
- package/src/internal/context/resolution-context.mts +1 -0
- package/src/internal/context/service-initialization-context.mts +43 -0
- package/src/internal/core/index.mts +5 -4
- package/src/internal/core/instance-resolver.mts +460 -302
- package/src/internal/core/name-resolver.mts +196 -0
- package/src/internal/core/scope-tracker.mts +242 -0
- package/src/internal/core/{instantiator.mts → service-initializer.mts} +51 -29
- package/src/internal/core/service-invalidator.mts +290 -0
- package/src/internal/core/token-resolver.mts +122 -0
- package/src/internal/holder/holder-storage.interface.mts +11 -5
- package/src/internal/holder/index.mts +2 -5
- package/src/internal/holder/instance-holder.mts +1 -3
- package/src/internal/holder/unified-storage.mts +245 -0
- package/src/internal/index.mts +2 -1
- package/src/internal/lifecycle/circular-detector.mts +1 -0
- package/src/internal/lifecycle/index.mts +1 -1
- package/src/internal/lifecycle/lifecycle-event-bus.mts +1 -0
- package/src/internal/stub-factory-class.mts +16 -0
- package/src/symbols/injectable-token.mts +3 -1
- package/src/testing/index.mts +2 -0
- package/src/testing/test-container.mts +564 -85
- package/src/testing/types.mts +123 -0
- package/src/testing/unit-test-container.mts +601 -0
- package/src/token/injection-token.mts +41 -4
- package/src/token/registry.mts +75 -9
- package/src/utils/default-injectors.mts +16 -0
- package/src/utils/get-injectable-token.mts +2 -3
- package/src/utils/get-injectors.mts +26 -15
- package/src/utils/index.mts +3 -1
- package/src/utils/types.mts +1 -0
- package/tsdown.config.mts +11 -1
- package/lib/browser/index.d.mts.map +0 -1
- package/lib/browser/index.mjs.map +0 -1
- package/lib/container-Bp1W-pWJ.d.mts.map +0 -1
- package/lib/container-DAKOvAgr.mjs.map +0 -1
- package/lib/container-DENMeJ87.cjs.map +0 -1
- package/lib/container-YPwvmlK2.d.cts.map +0 -1
- package/src/__tests__/async-local-storage.browser.spec.mts +0 -166
- package/src/__tests__/async-local-storage.spec.mts +0 -333
- package/src/__tests__/errors.spec.mts +0 -87
- package/src/__tests__/factory.spec.mts +0 -137
- package/src/__tests__/injectable.spec.mts +0 -246
- package/src/__tests__/request-scope.spec.mts +0 -416
- package/src/__tests__/service-instantiator.spec.mts +0 -410
- package/src/__tests__/service-locator-event-bus.spec.mts +0 -242
- package/src/__tests__/service-locator-manager.spec.mts +0 -300
- package/src/__tests__/service-locator.spec.mts +0 -966
- package/src/__tests__/unified-api.spec.mts +0 -130
- package/src/browser.mts +0 -11
- package/src/injectors.mts +0 -18
- package/src/internal/context/request-context.mts +0 -225
- package/src/internal/core/invalidator.mts +0 -437
- package/src/internal/core/service-locator.mts +0 -202
- package/src/internal/core/token-processor.mts +0 -252
- package/src/internal/holder/base-holder-manager.mts +0 -334
- package/src/internal/holder/holder-manager.mts +0 -85
- package/src/internal/holder/request-storage.mts +0 -127
- package/src/internal/holder/singleton-storage.mts +0 -92
- package/src/testing/README.md +0 -80
- package/src/testing/__tests__/test-container.spec.mts +0 -173
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { expectTypeOf, test } from 'vitest'
|
|
2
|
+
import { z } from 'zod/v4'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
BoundInjectionToken,
|
|
6
|
+
FactoryInjectionToken,
|
|
7
|
+
InjectionToken,
|
|
8
|
+
} from '../token/injection-token.mjs'
|
|
9
|
+
|
|
10
|
+
interface FooService {
|
|
11
|
+
makeFoo(): string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const simpleObjectSchema = z.object({
|
|
15
|
+
foo: z.string(),
|
|
16
|
+
})
|
|
17
|
+
const simpleOptionalObjectSchema = z
|
|
18
|
+
.object({
|
|
19
|
+
foo: z.string(),
|
|
20
|
+
})
|
|
21
|
+
.optional()
|
|
22
|
+
|
|
23
|
+
test('InjectionToken.create with class', () => {
|
|
24
|
+
class MyService {
|
|
25
|
+
getValue() {
|
|
26
|
+
return 42
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const token = InjectionToken.create(MyService)
|
|
31
|
+
expectTypeOf(token).toMatchTypeOf<InjectionToken<MyService, undefined>>()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('InjectionToken.create with class and schema', () => {
|
|
35
|
+
class MyService {
|
|
36
|
+
constructor(public config: z.infer<typeof simpleObjectSchema>) {}
|
|
37
|
+
getValue() {
|
|
38
|
+
return 42
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const token = InjectionToken.create(MyService, simpleObjectSchema)
|
|
43
|
+
expectTypeOf(token).toMatchTypeOf<
|
|
44
|
+
InjectionToken<MyService, typeof simpleObjectSchema, true>
|
|
45
|
+
>()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
test('InjectionToken.create with class and optional schema', () => {
|
|
49
|
+
class MyService {
|
|
50
|
+
constructor(public config?: z.infer<typeof simpleOptionalObjectSchema>) {}
|
|
51
|
+
getValue() {
|
|
52
|
+
return 42
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const token = InjectionToken.create(MyService, simpleOptionalObjectSchema)
|
|
57
|
+
expectTypeOf(token).toMatchTypeOf<
|
|
58
|
+
InjectionToken<MyService, typeof simpleOptionalObjectSchema, false>
|
|
59
|
+
>()
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test('InjectionToken.create with string name', () => {
|
|
63
|
+
const token = InjectionToken.create<FooService>('FooService')
|
|
64
|
+
expectTypeOf(token).toMatchTypeOf<InjectionToken<FooService, undefined>>()
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('InjectionToken.create with symbol name', () => {
|
|
68
|
+
const token = InjectionToken.create<FooService>(Symbol.for('FooService'))
|
|
69
|
+
expectTypeOf(token).toMatchTypeOf<InjectionToken<FooService, undefined>>()
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test('InjectionToken.create with string name and schema', () => {
|
|
73
|
+
const token = InjectionToken.create<FooService, typeof simpleObjectSchema>(
|
|
74
|
+
'FooService',
|
|
75
|
+
simpleObjectSchema,
|
|
76
|
+
)
|
|
77
|
+
expectTypeOf(token).toMatchTypeOf<
|
|
78
|
+
InjectionToken<FooService, typeof simpleObjectSchema>
|
|
79
|
+
>()
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
test('InjectionToken.bound creates BoundInjectionToken', () => {
|
|
83
|
+
const token = InjectionToken.create<FooService, typeof simpleObjectSchema>(
|
|
84
|
+
'FooService',
|
|
85
|
+
simpleObjectSchema,
|
|
86
|
+
)
|
|
87
|
+
const boundToken = InjectionToken.bound(token, { foo: 'bar' })
|
|
88
|
+
expectTypeOf(boundToken).toMatchTypeOf<
|
|
89
|
+
BoundInjectionToken<FooService, typeof simpleObjectSchema>
|
|
90
|
+
>()
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
test('InjectionToken.bound requires correct argument type', () => {
|
|
94
|
+
const token = InjectionToken.create<FooService, typeof simpleObjectSchema>(
|
|
95
|
+
'FooService',
|
|
96
|
+
simpleObjectSchema,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
// @ts-expect-error Should fail with wrong argument type
|
|
100
|
+
InjectionToken.bound(token, { wrong: 'key' })
|
|
101
|
+
|
|
102
|
+
// @ts-expect-error Should fail with missing required property
|
|
103
|
+
InjectionToken.bound(token, {})
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test('InjectionToken.factory creates FactoryInjectionToken', () => {
|
|
107
|
+
const token = InjectionToken.create<FooService, typeof simpleObjectSchema>(
|
|
108
|
+
'FooService',
|
|
109
|
+
simpleObjectSchema,
|
|
110
|
+
)
|
|
111
|
+
const factoryToken = InjectionToken.factory(token, async () => ({
|
|
112
|
+
foo: 'bar',
|
|
113
|
+
}))
|
|
114
|
+
expectTypeOf(factoryToken).toMatchTypeOf<
|
|
115
|
+
FactoryInjectionToken<FooService, typeof simpleObjectSchema>
|
|
116
|
+
>()
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
test('InjectionToken.factory requires correct return type', () => {
|
|
120
|
+
const token = InjectionToken.create<FooService, typeof simpleObjectSchema>(
|
|
121
|
+
'FooService',
|
|
122
|
+
simpleObjectSchema,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
// @ts-expect-error Should fail with wrong return type
|
|
126
|
+
InjectionToken.factory(token, async () => ({ wrong: 'key' }))
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
test('InjectionToken.refineType changes BoundInjectionToken type', () => {
|
|
130
|
+
interface RefinedService {
|
|
131
|
+
doSomething(): void
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const token = InjectionToken.create<unknown, typeof simpleObjectSchema>(
|
|
135
|
+
'Service',
|
|
136
|
+
simpleObjectSchema,
|
|
137
|
+
)
|
|
138
|
+
const boundToken = InjectionToken.bound(token, { foo: 'bar' })
|
|
139
|
+
const refinedToken = InjectionToken.refineType<RefinedService>(boundToken)
|
|
140
|
+
expectTypeOf(refinedToken).toMatchTypeOf<
|
|
141
|
+
BoundInjectionToken<RefinedService, any>
|
|
142
|
+
>()
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
test('BoundInjectionToken has value property with correct type', () => {
|
|
146
|
+
const token = InjectionToken.create<FooService, typeof simpleObjectSchema>(
|
|
147
|
+
'FooService',
|
|
148
|
+
simpleObjectSchema,
|
|
149
|
+
)
|
|
150
|
+
const boundToken = InjectionToken.bound(token, { foo: 'bar' })
|
|
151
|
+
|
|
152
|
+
expectTypeOf(boundToken.value).toMatchTypeOf<{ foo: string }>()
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
test('FactoryInjectionToken has factory property', () => {
|
|
156
|
+
const token = InjectionToken.create<FooService, typeof simpleObjectSchema>(
|
|
157
|
+
'FooService',
|
|
158
|
+
simpleObjectSchema,
|
|
159
|
+
)
|
|
160
|
+
const factoryToken = InjectionToken.factory(token, async () => ({
|
|
161
|
+
foo: 'bar',
|
|
162
|
+
}))
|
|
163
|
+
|
|
164
|
+
expectTypeOf(factoryToken.factory).toBeFunction()
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
test('InjectionToken properties', () => {
|
|
168
|
+
const token = InjectionToken.create<FooService, typeof simpleObjectSchema>(
|
|
169
|
+
'FooService',
|
|
170
|
+
simpleObjectSchema,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
expectTypeOf(token.id).toBeString()
|
|
174
|
+
expectTypeOf(token.name).toMatchTypeOf<string | symbol | (new (...args: any[]) => any)>()
|
|
175
|
+
expectTypeOf(token.toString()).toBeString()
|
|
176
|
+
})
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { assertType, describe, test } from 'vitest'
|
|
2
|
+
import { z } from 'zod/v4'
|
|
3
|
+
|
|
4
|
+
import type { Factorable } from '../interfaces/index.mjs'
|
|
5
|
+
|
|
6
|
+
import { Container } from '../container/container.mjs'
|
|
7
|
+
import { Factory, Injectable } from '../decorators/index.mjs'
|
|
8
|
+
import { InjectionToken } from '../token/injection-token.mjs'
|
|
9
|
+
|
|
10
|
+
interface FooService {
|
|
11
|
+
makeFoo(): string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const simpleObjectSchema = z.object({
|
|
15
|
+
foo: z.string(),
|
|
16
|
+
})
|
|
17
|
+
const simpleOptionalObjectSchema = z
|
|
18
|
+
.object({
|
|
19
|
+
foo: z.string(),
|
|
20
|
+
})
|
|
21
|
+
.optional()
|
|
22
|
+
|
|
23
|
+
const typelessObjectToken = InjectionToken.create(
|
|
24
|
+
Symbol.for('Typeless object token'),
|
|
25
|
+
simpleObjectSchema,
|
|
26
|
+
)
|
|
27
|
+
const typelessOptionalObjectToken = InjectionToken.create(
|
|
28
|
+
Symbol.for('Typeless optional object token'),
|
|
29
|
+
simpleOptionalObjectSchema,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const typedObjectToken = InjectionToken.create<
|
|
33
|
+
FooService,
|
|
34
|
+
typeof simpleObjectSchema
|
|
35
|
+
>(Symbol.for('Typed object token'), simpleObjectSchema)
|
|
36
|
+
const typedOptionalObjectToken = InjectionToken.create<
|
|
37
|
+
FooService,
|
|
38
|
+
typeof simpleOptionalObjectSchema
|
|
39
|
+
>(Symbol.for('Typed optional object token'), simpleOptionalObjectSchema)
|
|
40
|
+
|
|
41
|
+
const typedToken = InjectionToken.create<FooService>(Symbol.for('Typed token'))
|
|
42
|
+
|
|
43
|
+
describe('ScopedContainer.get', () => {
|
|
44
|
+
describe('#1 Classes', () => {
|
|
45
|
+
test('simple class', async () => {
|
|
46
|
+
@Injectable()
|
|
47
|
+
class Foo {
|
|
48
|
+
makeFoo() {
|
|
49
|
+
return 'foo'
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const container = new Container()
|
|
54
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
55
|
+
assertType<Foo>(await scopedContainer.get(Foo))
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test('class with required argument', async () => {
|
|
59
|
+
@Injectable({
|
|
60
|
+
schema: simpleObjectSchema,
|
|
61
|
+
})
|
|
62
|
+
class Foo {
|
|
63
|
+
constructor(public arg: z.infer<typeof simpleObjectSchema>) {}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const container = new Container()
|
|
67
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
68
|
+
assertType<Foo>(await scopedContainer.get(Foo, { foo: 'bar' }))
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('should fail if not compatible', async () => {
|
|
72
|
+
@Injectable({
|
|
73
|
+
schema: simpleObjectSchema,
|
|
74
|
+
})
|
|
75
|
+
class Foo {
|
|
76
|
+
constructor(public arg: z.infer<typeof simpleObjectSchema>) {}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const container = new Container()
|
|
80
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
81
|
+
// @ts-expect-error Should fail if not compatible
|
|
82
|
+
await scopedContainer.get(Foo, { test: 'bar' })
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('factory class returns unwrapped type', async () => {
|
|
86
|
+
@Factory()
|
|
87
|
+
class FooFactory implements Factorable<string> {
|
|
88
|
+
create() {
|
|
89
|
+
return 'created'
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const container = new Container()
|
|
94
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
95
|
+
// When getting a Factorable class, we get the created type, not the factory
|
|
96
|
+
assertType<string>(await scopedContainer.get(FooFactory))
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test('#2 Token with required Schema', async () => {
|
|
101
|
+
const container = new Container()
|
|
102
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
103
|
+
|
|
104
|
+
const result = await scopedContainer.get(typelessObjectToken, {
|
|
105
|
+
foo: 'bar',
|
|
106
|
+
})
|
|
107
|
+
assertType<unknown>(result)
|
|
108
|
+
|
|
109
|
+
const result2 = await scopedContainer.get(typedObjectToken, { foo: 'bar' })
|
|
110
|
+
assertType<FooService>(result2)
|
|
111
|
+
|
|
112
|
+
// @ts-expect-error We show error when we pass the wrong type
|
|
113
|
+
await scopedContainer.get(typedObjectToken, undefined)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
test('#3 Token with optional Schema', async () => {
|
|
117
|
+
const container = new Container()
|
|
118
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
119
|
+
|
|
120
|
+
const result = await scopedContainer.get(typelessOptionalObjectToken)
|
|
121
|
+
assertType<unknown>(result)
|
|
122
|
+
|
|
123
|
+
const result2 = await scopedContainer.get(typedOptionalObjectToken)
|
|
124
|
+
assertType<FooService>(result2)
|
|
125
|
+
|
|
126
|
+
const result3 = await scopedContainer.get(typedObjectToken)
|
|
127
|
+
// Special case when we pass the token without args
|
|
128
|
+
// We can only return an error string
|
|
129
|
+
assertType<'Error: Your token requires args: foo'>(result3)
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
test('#4 Token with no Schema', async () => {
|
|
133
|
+
const container = new Container()
|
|
134
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
135
|
+
|
|
136
|
+
const result = await scopedContainer.get(typedToken)
|
|
137
|
+
assertType<FooService>(result)
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
test('#5 BoundInjectionToken', async () => {
|
|
141
|
+
const container = new Container()
|
|
142
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
143
|
+
|
|
144
|
+
const boundToken = InjectionToken.bound(typedObjectToken, { foo: 'bar' })
|
|
145
|
+
const result = await scopedContainer.get(boundToken)
|
|
146
|
+
assertType<FooService>(result)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
test('#6 FactoryInjectionToken', async () => {
|
|
150
|
+
const container = new Container()
|
|
151
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
152
|
+
|
|
153
|
+
const factoryToken = InjectionToken.factory(typedObjectToken, async () => ({
|
|
154
|
+
foo: 'bar',
|
|
155
|
+
}))
|
|
156
|
+
const result = await scopedContainer.get(factoryToken)
|
|
157
|
+
assertType<FooService>(result)
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
describe('ScopedContainer methods', () => {
|
|
162
|
+
test('getRequestId returns string', () => {
|
|
163
|
+
const container = new Container()
|
|
164
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
165
|
+
assertType<string>(scopedContainer.getRequestId())
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
test('getParent returns Container', () => {
|
|
169
|
+
const container = new Container()
|
|
170
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
171
|
+
assertType<Container>(scopedContainer.getParent())
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
test('getMetadata returns any', () => {
|
|
175
|
+
const container = new Container()
|
|
176
|
+
const scopedContainer = container.beginRequest('req-1', { userId: '123' })
|
|
177
|
+
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
178
|
+
assertType<any | undefined>(scopedContainer.getMetadata('userId'))
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
test('setMetadata accepts any value', () => {
|
|
182
|
+
const container = new Container()
|
|
183
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
184
|
+
scopedContainer.setMetadata('userId', '123')
|
|
185
|
+
scopedContainer.setMetadata('count', 42)
|
|
186
|
+
scopedContainer.setMetadata('data', { nested: true })
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
test('dispose returns Promise<void>', async () => {
|
|
190
|
+
const container = new Container()
|
|
191
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
192
|
+
assertType<Promise<void>>(scopedContainer.dispose())
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
test('endRequest returns Promise<void>', async () => {
|
|
196
|
+
const container = new Container()
|
|
197
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
198
|
+
assertType<Promise<void>>(scopedContainer.endRequest())
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
test('invalidate returns Promise<void>', async () => {
|
|
202
|
+
const container = new Container()
|
|
203
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
204
|
+
assertType<Promise<void>>(scopedContainer.invalidate({}))
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
test('requestId property is string', () => {
|
|
208
|
+
const container = new Container()
|
|
209
|
+
const scopedContainer = container.beginRequest('req-1')
|
|
210
|
+
assertType<string>(scopedContainer.requestId)
|
|
211
|
+
})
|
|
212
|
+
})
|