@stitchem/core 0.0.3

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 (68) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/LICENSE +21 -0
  3. package/README.md +815 -0
  4. package/dist/container/container.d.ts +79 -0
  5. package/dist/container/container.js +156 -0
  6. package/dist/container/module.map.d.ts +22 -0
  7. package/dist/container/module.map.js +40 -0
  8. package/dist/context/context.d.ts +181 -0
  9. package/dist/context/context.js +395 -0
  10. package/dist/context/scope.d.ts +30 -0
  11. package/dist/context/scope.js +42 -0
  12. package/dist/core/core.lifecycle.d.ts +41 -0
  13. package/dist/core/core.lifecycle.js +37 -0
  14. package/dist/core/core.lifetime.d.ts +21 -0
  15. package/dist/core/core.lifetime.js +22 -0
  16. package/dist/core/core.types.d.ts +2 -0
  17. package/dist/core/core.types.js +2 -0
  18. package/dist/core/core.utils.d.ts +8 -0
  19. package/dist/core/core.utils.js +13 -0
  20. package/dist/decorator/inject.decorator.d.ts +50 -0
  21. package/dist/decorator/inject.decorator.js +78 -0
  22. package/dist/decorator/injectable.decorator.d.ts +45 -0
  23. package/dist/decorator/injectable.decorator.js +46 -0
  24. package/dist/errors/core.error.d.ts +24 -0
  25. package/dist/errors/core.error.js +59 -0
  26. package/dist/errors/error.codes.d.ts +17 -0
  27. package/dist/errors/error.codes.js +21 -0
  28. package/dist/index.d.ts +25 -0
  29. package/dist/index.js +23 -0
  30. package/dist/injector/injector.d.ts +78 -0
  31. package/dist/injector/injector.js +295 -0
  32. package/dist/instance-wrapper/instance-wrapper.d.ts +61 -0
  33. package/dist/instance-wrapper/instance-wrapper.js +142 -0
  34. package/dist/instance-wrapper/instance-wrapper.types.d.ts +18 -0
  35. package/dist/instance-wrapper/instance-wrapper.types.js +2 -0
  36. package/dist/logger/console.logger.d.ts +52 -0
  37. package/dist/logger/console.logger.js +90 -0
  38. package/dist/logger/logger.token.d.ts +23 -0
  39. package/dist/logger/logger.token.js +23 -0
  40. package/dist/logger/logger.types.d.ts +38 -0
  41. package/dist/logger/logger.types.js +12 -0
  42. package/dist/module/module.d.ts +104 -0
  43. package/dist/module/module.decorator.d.ts +28 -0
  44. package/dist/module/module.decorator.js +42 -0
  45. package/dist/module/module.graph.d.ts +52 -0
  46. package/dist/module/module.graph.js +263 -0
  47. package/dist/module/module.js +181 -0
  48. package/dist/module/module.ref.d.ts +81 -0
  49. package/dist/module/module.ref.js +123 -0
  50. package/dist/module/module.types.d.ts +80 -0
  51. package/dist/module/module.types.js +10 -0
  52. package/dist/provider/provider.guards.d.ts +46 -0
  53. package/dist/provider/provider.guards.js +62 -0
  54. package/dist/provider/provider.interface.d.ts +39 -0
  55. package/dist/provider/provider.interface.js +2 -0
  56. package/dist/test/test.d.ts +22 -0
  57. package/dist/test/test.js +23 -0
  58. package/dist/test/test.module-builder.d.ts +136 -0
  59. package/dist/test/test.module-builder.js +377 -0
  60. package/dist/test/test.module.d.ts +71 -0
  61. package/dist/test/test.module.js +151 -0
  62. package/dist/token/lazy.token.d.ts +44 -0
  63. package/dist/token/lazy.token.js +42 -0
  64. package/dist/token/token.types.d.ts +8 -0
  65. package/dist/token/token.types.js +2 -0
  66. package/dist/token/token.utils.d.ts +9 -0
  67. package/dist/token/token.utils.js +19 -0
  68. package/package.json +62 -0
@@ -0,0 +1,136 @@
1
+ import type { Token } from '../token/token.types.js';
2
+ import type { constructor } from '../core/core.types.js';
3
+ import type { ModuleMetadata } from '../module/module.types.js';
4
+ import type { ContextOptions } from '../context/context.js';
5
+ import type { Provider } from '../provider/provider.interface.js';
6
+ import type { Lifetime } from '../core/core.lifetime.js';
7
+ import { TestModule } from './test.module.js';
8
+ interface InjectableValueOverride {
9
+ kind: 'value';
10
+ ctor: constructor;
11
+ value: unknown;
12
+ }
13
+ interface InjectableClassOverride {
14
+ kind: 'class';
15
+ ctor: constructor;
16
+ useClass: constructor;
17
+ }
18
+ interface InjectableFactoryOverride {
19
+ kind: 'factory';
20
+ ctor: constructor;
21
+ factory: (...args: unknown[]) => unknown;
22
+ inject?: Token[];
23
+ }
24
+ type InjectableOverride = InjectableValueOverride | InjectableClassOverride | InjectableFactoryOverride;
25
+ interface ComponentValueOverride {
26
+ kind: 'value';
27
+ classRef: constructor;
28
+ value: unknown;
29
+ }
30
+ interface ComponentClassOverride {
31
+ kind: 'class';
32
+ classRef: constructor;
33
+ useClass: constructor;
34
+ }
35
+ type ComponentOverride = ComponentValueOverride | ComponentClassOverride;
36
+ /**
37
+ * Builder for creating a test module with provider overrides.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const module = await Test.createModule({
42
+ * imports: [UserModule, DbModule],
43
+ * providers: [UserService],
44
+ * })
45
+ * .overrideProvider(DbService).useValue({ query: vi.fn() })
46
+ * .compile();
47
+ * ```
48
+ */
49
+ export declare class TestModuleBuilder {
50
+ private readonly metadata;
51
+ private readonly overrides;
52
+ private readonly injectableOverrides;
53
+ private readonly componentOverrides;
54
+ constructor(metadata: ModuleMetadata);
55
+ /**
56
+ * Starts overriding a provider identified by its token.
57
+ * Returns an {@link OverrideBy} helper with `.useValue()`, `.useClass()`, etc.
58
+ */
59
+ overrideProvider(token: Token): OverrideBy;
60
+ /**
61
+ * Starts overriding an injectable (guard, filter, middleware, etc.) by class.
62
+ * Returns an {@link InjectableOverrideBy} helper with `.useValue()`,
63
+ * `.useClass()`, or `.useFactory()`.
64
+ */
65
+ overrideInjectable(ctor: constructor): InjectableOverrideBy;
66
+ /**
67
+ * Starts overriding a component (router, etc.) by class reference.
68
+ * Returns a {@link ComponentOverrideBy} helper with `.useValue()` or `.useClass()`.
69
+ */
70
+ overrideComponent(classRef: constructor): ComponentOverrideBy;
71
+ /**
72
+ * Compiles the test module.
73
+ * Builds the module graph, applies overrides, and resolves singletons.
74
+ */
75
+ compile(options?: ContextOptions): Promise<TestModule>;
76
+ /** @internal */
77
+ addOverride(provider: Provider): this;
78
+ /** @internal */
79
+ addInjectableOverride(override: InjectableOverride): this;
80
+ /** @internal */
81
+ addComponentOverride(override: ComponentOverride): this;
82
+ }
83
+ /**
84
+ * Fluent helper for specifying how to override a provider.
85
+ * Returned by {@link TestModuleBuilder.overrideProvider}.
86
+ */
87
+ export declare class OverrideBy {
88
+ private readonly builder;
89
+ private readonly token;
90
+ constructor(builder: TestModuleBuilder, token: Token);
91
+ /** Override with a static value. */
92
+ useValue(value: unknown): TestModuleBuilder;
93
+ /** Override with a class. */
94
+ useClass(cls: constructor, lifetime?: Lifetime): TestModuleBuilder;
95
+ /** Override with a factory function. */
96
+ useFactory(options: {
97
+ factory: (...args: unknown[]) => unknown;
98
+ inject?: Token[];
99
+ lifetime?: Lifetime;
100
+ }): TestModuleBuilder;
101
+ /** Override with an alias to another token. */
102
+ useExisting(existingToken: Token): TestModuleBuilder;
103
+ }
104
+ /**
105
+ * Fluent helper for specifying how to override an injectable.
106
+ * Returned by {@link TestModuleBuilder.overrideInjectable}.
107
+ */
108
+ export declare class InjectableOverrideBy {
109
+ private readonly builder;
110
+ private readonly ctor;
111
+ constructor(builder: TestModuleBuilder, ctor: constructor);
112
+ /** Override with a static value (mock instance). */
113
+ useValue(value: unknown): TestModuleBuilder;
114
+ /** Override with a replacement class (resolved via DI). */
115
+ useClass(cls: constructor): TestModuleBuilder;
116
+ /** Override with a factory function. */
117
+ useFactory(options: {
118
+ factory: (...args: unknown[]) => unknown;
119
+ inject?: Token[];
120
+ }): TestModuleBuilder;
121
+ }
122
+ /**
123
+ * Fluent helper for specifying how to override a component.
124
+ * Returned by {@link TestModuleBuilder.overrideComponent}.
125
+ */
126
+ export declare class ComponentOverrideBy {
127
+ private readonly builder;
128
+ private readonly classRef;
129
+ constructor(builder: TestModuleBuilder, classRef: constructor);
130
+ /** Override with a static value (skip DI instantiation entirely). */
131
+ useValue(value: unknown): TestModuleBuilder;
132
+ /** Override with a different class (instantiated via DI). */
133
+ useClass(cls: constructor): TestModuleBuilder;
134
+ }
135
+ export {};
136
+ //# sourceMappingURL=test.module-builder.d.ts.map
@@ -0,0 +1,377 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { module as moduleDecorator } from '../module/module.decorator.js';
36
+ import { Container } from '../container/container.js';
37
+ import { ModuleGraph } from '../module/module.graph.js';
38
+ import { ModuleRef } from '../module/module.ref.js';
39
+ import { Injector } from '../injector/injector.js';
40
+ import { Scope } from '../context/scope.js';
41
+ import { hasOnReady } from '../core/core.lifecycle.js';
42
+ import { getProviderToken } from '../provider/provider.guards.js';
43
+ import { TestModule } from './test.module.js';
44
+ // ---------------------------------------------------------------------------
45
+ // TestModuleBuilder
46
+ // ---------------------------------------------------------------------------
47
+ /**
48
+ * Builder for creating a test module with provider overrides.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * const module = await Test.createModule({
53
+ * imports: [UserModule, DbModule],
54
+ * providers: [UserService],
55
+ * })
56
+ * .overrideProvider(DbService).useValue({ query: vi.fn() })
57
+ * .compile();
58
+ * ```
59
+ */
60
+ export class TestModuleBuilder {
61
+ metadata;
62
+ overrides = [];
63
+ injectableOverrides = [];
64
+ componentOverrides = [];
65
+ constructor(metadata) {
66
+ this.metadata = metadata;
67
+ }
68
+ /**
69
+ * Starts overriding a provider identified by its token.
70
+ * Returns an {@link OverrideBy} helper with `.useValue()`, `.useClass()`, etc.
71
+ */
72
+ overrideProvider(token) {
73
+ return new OverrideBy(this, token);
74
+ }
75
+ /**
76
+ * Starts overriding an injectable (guard, filter, middleware, etc.) by class.
77
+ * Returns an {@link InjectableOverrideBy} helper with `.useValue()`,
78
+ * `.useClass()`, or `.useFactory()`.
79
+ */
80
+ overrideInjectable(ctor) {
81
+ return new InjectableOverrideBy(this, ctor);
82
+ }
83
+ /**
84
+ * Starts overriding a component (router, etc.) by class reference.
85
+ * Returns a {@link ComponentOverrideBy} helper with `.useValue()` or `.useClass()`.
86
+ */
87
+ overrideComponent(classRef) {
88
+ return new ComponentOverrideBy(this, classRef);
89
+ }
90
+ /**
91
+ * Compiles the test module.
92
+ * Builds the module graph, applies overrides, and resolves singletons.
93
+ */
94
+ async compile(options) {
95
+ let TestRootModule = (() => {
96
+ let _classDecorators = [moduleDecorator(this.metadata)];
97
+ let _classDescriptor;
98
+ let _classExtraInitializers = [];
99
+ let _classThis;
100
+ var TestRootModule = class {
101
+ static { _classThis = this; }
102
+ static {
103
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
104
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
105
+ TestRootModule = _classThis = _classDescriptor.value;
106
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
107
+ __runInitializers(_classThis, _classExtraInitializers);
108
+ }
109
+ };
110
+ return TestRootModule = _classThis;
111
+ })();
112
+ const container = new Container();
113
+ const moduleGraph = new ModuleGraph(TestRootModule, container);
114
+ const injector = new Injector(container);
115
+ const componentKeys = options?.componentKeys ?? [];
116
+ // Register ModuleRef factory per module.
117
+ for (const id of moduleGraph.sortedIds) {
118
+ const mod = container.getModule(id);
119
+ mod.addProvider({
120
+ provide: ModuleRef,
121
+ useFactory: () => new ModuleRef(container, injector, mod),
122
+ });
123
+ }
124
+ // Apply provider overrides across all modules.
125
+ for (const override of this.overrides) {
126
+ const token = getProviderToken(override);
127
+ for (const id of moduleGraph.sortedIds) {
128
+ const mod = container.getModule(id);
129
+ if (mod.hasProvider(token)) {
130
+ mod.addProvider(override);
131
+ }
132
+ }
133
+ }
134
+ // Apply value-based injectable overrides immediately (pre-populate cache).
135
+ for (const override of this.injectableOverrides) {
136
+ if (override.kind !== 'value')
137
+ continue;
138
+ for (const id of moduleGraph.sortedIds) {
139
+ const mod = container.getModule(id);
140
+ mod.setInjectable(override.ctor, override.value);
141
+ }
142
+ }
143
+ // Rebuild global exports after overrides.
144
+ container.buildGlobalExports();
145
+ const rootModule = container.getModule(moduleGraph.rootModuleId);
146
+ // Eagerly resolve singletons and instantiate module classes.
147
+ const instantiatedModules = new Map();
148
+ for (const id of moduleGraph.sortedIds) {
149
+ const mod = container.getModule(id);
150
+ for (const [, wrapper] of mod.providers) {
151
+ if (!wrapper.isSingleton || wrapper.isResolved())
152
+ continue;
153
+ await injector.loadInstance(wrapper, mod, Scope.STATIC);
154
+ }
155
+ const existing = instantiatedModules.get(mod.classRef);
156
+ if (existing !== undefined) {
157
+ mod.instance = existing;
158
+ continue;
159
+ }
160
+ const instance = await injector.instantiateClass(mod.classRef, mod);
161
+ mod.instance = instance;
162
+ instantiatedModules.set(mod.classRef, instance);
163
+ }
164
+ // Apply class/factory injectable overrides (may depend on resolved providers).
165
+ for (const override of this.injectableOverrides) {
166
+ if (override.kind === 'value')
167
+ continue;
168
+ let instance;
169
+ if (override.kind === 'class') {
170
+ instance = await injector.instantiateClassGlobal(override.useClass, Scope.STATIC);
171
+ }
172
+ else {
173
+ const deps = [];
174
+ for (const token of override.inject ?? []) {
175
+ const { wrapper, module: depMod } = container.getProviderByTokenGlobal(token);
176
+ deps.push(await injector.loadInstance(wrapper, depMod, Scope.STATIC));
177
+ }
178
+ const result = override.factory(...deps);
179
+ instance = result instanceof Promise ? await result : result;
180
+ }
181
+ if (hasOnReady(instance)) {
182
+ await instance.onReady();
183
+ }
184
+ for (const id of moduleGraph.sortedIds) {
185
+ const mod = container.getModule(id);
186
+ mod.setInjectable(override.ctor, instance);
187
+ }
188
+ }
189
+ // Build component override lookup (last override wins).
190
+ const componentOverrideMap = new Map();
191
+ for (const override of this.componentOverrides) {
192
+ componentOverrideMap.set(override.classRef, override);
193
+ }
194
+ // Resolve components.
195
+ for (const id of moduleGraph.sortedIds) {
196
+ const mod = container.getModule(id);
197
+ const meta = mod.metadata;
198
+ for (const key of componentKeys) {
199
+ const classes = meta[key];
200
+ if (!Array.isArray(classes))
201
+ continue;
202
+ for (const cls of classes) {
203
+ const override = componentOverrideMap.get(cls);
204
+ if (override?.kind === 'value') {
205
+ mod.addComponent(key, override.value, cls);
206
+ }
207
+ else if (override?.kind === 'class') {
208
+ const instance = await injector.instantiateClass(override.useClass, mod);
209
+ mod.addComponent(key, instance, cls);
210
+ }
211
+ else {
212
+ const instance = await injector.instantiateClass(cls, mod);
213
+ mod.addComponent(key, instance, cls);
214
+ }
215
+ }
216
+ }
217
+ }
218
+ // Fire onReady lifecycle.
219
+ for (const id of moduleGraph.sortedIds) {
220
+ const mod = container.getModule(id);
221
+ for (const [, wrapper] of mod.providers) {
222
+ if (!wrapper.isSingleton)
223
+ continue;
224
+ const instance = wrapper.getInstance(Scope.STATIC);
225
+ if (instance !== undefined && hasOnReady(instance)) {
226
+ await instance.onReady();
227
+ }
228
+ }
229
+ if (mod.instance !== undefined && hasOnReady(mod.instance)) {
230
+ await mod.instance.onReady();
231
+ }
232
+ for (const key of componentKeys) {
233
+ for (const entry of mod.getComponents(key)) {
234
+ if (hasOnReady(entry.instance)) {
235
+ await entry.instance.onReady();
236
+ }
237
+ }
238
+ }
239
+ }
240
+ return new TestModule(container, injector, rootModule, moduleGraph.sortedIds);
241
+ }
242
+ /** @internal */
243
+ addOverride(provider) {
244
+ this.overrides.push(provider);
245
+ return this;
246
+ }
247
+ /** @internal */
248
+ addInjectableOverride(override) {
249
+ this.injectableOverrides.push(override);
250
+ return this;
251
+ }
252
+ /** @internal */
253
+ addComponentOverride(override) {
254
+ this.componentOverrides.push(override);
255
+ return this;
256
+ }
257
+ }
258
+ // ---------------------------------------------------------------------------
259
+ // OverrideBy (providers)
260
+ // ---------------------------------------------------------------------------
261
+ /**
262
+ * Fluent helper for specifying how to override a provider.
263
+ * Returned by {@link TestModuleBuilder.overrideProvider}.
264
+ */
265
+ export class OverrideBy {
266
+ builder;
267
+ token;
268
+ constructor(builder, token) {
269
+ this.builder = builder;
270
+ this.token = token;
271
+ }
272
+ /** Override with a static value. */
273
+ useValue(value) {
274
+ return this.builder.addOverride({
275
+ provide: this.token,
276
+ useValue: value,
277
+ });
278
+ }
279
+ /** Override with a class. */
280
+ useClass(cls, lifetime) {
281
+ const provider = {
282
+ provide: this.token,
283
+ useClass: cls,
284
+ lifetime,
285
+ };
286
+ return this.builder.addOverride(provider);
287
+ }
288
+ /** Override with a factory function. */
289
+ useFactory(options) {
290
+ const provider = {
291
+ provide: this.token,
292
+ useFactory: options.factory,
293
+ inject: options.inject,
294
+ lifetime: options.lifetime,
295
+ };
296
+ return this.builder.addOverride(provider);
297
+ }
298
+ /** Override with an alias to another token. */
299
+ useExisting(existingToken) {
300
+ return this.builder.addOverride({
301
+ provide: this.token,
302
+ useExisting: existingToken,
303
+ });
304
+ }
305
+ }
306
+ // ---------------------------------------------------------------------------
307
+ // InjectableOverrideBy
308
+ // ---------------------------------------------------------------------------
309
+ /**
310
+ * Fluent helper for specifying how to override an injectable.
311
+ * Returned by {@link TestModuleBuilder.overrideInjectable}.
312
+ */
313
+ export class InjectableOverrideBy {
314
+ builder;
315
+ ctor;
316
+ constructor(builder, ctor) {
317
+ this.builder = builder;
318
+ this.ctor = ctor;
319
+ }
320
+ /** Override with a static value (mock instance). */
321
+ useValue(value) {
322
+ return this.builder.addInjectableOverride({
323
+ kind: 'value',
324
+ ctor: this.ctor,
325
+ value,
326
+ });
327
+ }
328
+ /** Override with a replacement class (resolved via DI). */
329
+ useClass(cls) {
330
+ return this.builder.addInjectableOverride({
331
+ kind: 'class',
332
+ ctor: this.ctor,
333
+ useClass: cls,
334
+ });
335
+ }
336
+ /** Override with a factory function. */
337
+ useFactory(options) {
338
+ return this.builder.addInjectableOverride({
339
+ kind: 'factory',
340
+ ctor: this.ctor,
341
+ factory: options.factory,
342
+ inject: options.inject,
343
+ });
344
+ }
345
+ }
346
+ // ---------------------------------------------------------------------------
347
+ // ComponentOverrideBy
348
+ // ---------------------------------------------------------------------------
349
+ /**
350
+ * Fluent helper for specifying how to override a component.
351
+ * Returned by {@link TestModuleBuilder.overrideComponent}.
352
+ */
353
+ export class ComponentOverrideBy {
354
+ builder;
355
+ classRef;
356
+ constructor(builder, classRef) {
357
+ this.builder = builder;
358
+ this.classRef = classRef;
359
+ }
360
+ /** Override with a static value (skip DI instantiation entirely). */
361
+ useValue(value) {
362
+ return this.builder.addComponentOverride({
363
+ kind: 'value',
364
+ classRef: this.classRef,
365
+ value,
366
+ });
367
+ }
368
+ /** Override with a different class (instantiated via DI). */
369
+ useClass(cls) {
370
+ return this.builder.addComponentOverride({
371
+ kind: 'class',
372
+ classRef: this.classRef,
373
+ useClass: cls,
374
+ });
375
+ }
376
+ }
377
+ //# sourceMappingURL=test.module-builder.js.map
@@ -0,0 +1,71 @@
1
+ import type { Token } from '../token/token.types.js';
2
+ import type { constructor } from '../core/core.types.js';
3
+ import type { ComponentRef } from '../context/context.js';
4
+ import type { Container } from '../container/container.js';
5
+ import type { Injector } from '../injector/injector.js';
6
+ import type { Module } from '../module/module.js';
7
+ import { Scope } from '../context/scope.js';
8
+ import { ModuleRef } from '../module/module.ref.js';
9
+ /**
10
+ * A compiled test module.
11
+ * Provides resolution and lifecycle management for test scenarios.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * await using module = await Test.createModule({
16
+ * imports: [UserModule],
17
+ * providers: [UserService],
18
+ * }).compile();
19
+ *
20
+ * const userService = await module.resolve(UserService);
21
+ * ```
22
+ */
23
+ export declare class TestModule implements AsyncDisposable {
24
+ private readonly container;
25
+ private readonly injector;
26
+ private readonly rootModule;
27
+ private readonly sortedIds;
28
+ private disposed;
29
+ /** @internal */
30
+ constructor(container: Container, injector: Injector, rootModule: Module, sortedIds: readonly string[]);
31
+ /** Resolves a provider by token from the root module. */
32
+ resolve<T>(token: Token<T>, scope?: Scope): Promise<T>;
33
+ /** Synchronously resolves a provider by token. */
34
+ resolveSync<T>(token: Token<T>, scope?: Scope): T;
35
+ /** Navigates to a specific module for resolution. */
36
+ select<T extends constructor>(moduleClass: T): ModuleRef;
37
+ /** Returns all component instances for a given metadata key. */
38
+ getComponents<T = unknown>(key: string): ComponentRef<T>[];
39
+ /**
40
+ * Resolves an injectable class with global dependency resolution.
41
+ *
42
+ * Dependencies are always resolved globally and the instance is cached
43
+ * on the root module. This makes TestModule satisfy the InjectableHost
44
+ * structural interface used by extension resolvers.
45
+ *
46
+ * @param ctor - The injectable class to resolve.
47
+ * @param _options - Accepted for InjectableHost compatibility; ignored
48
+ * (TestModule always resolves globally, like Context).
49
+ */
50
+ resolveInjectable<T>(ctor: constructor<T>, _options?: {
51
+ strict?: boolean;
52
+ }): Promise<T>;
53
+ /** The DI container. For extension authors only. */
54
+ get $container(): Container;
55
+ /** The dependency injector. For extension authors only. */
56
+ get $injector(): Injector;
57
+ /** The root module of the test module graph. For extension authors only. */
58
+ get $rootModule(): Module;
59
+ /** Module IDs in topological order. For extension authors only. */
60
+ get $sortedIds(): readonly string[];
61
+ /** Creates a new disposable scope for scoped resolution. */
62
+ createScope(): Scope;
63
+ [Symbol.asyncDispose](): Promise<void>;
64
+ /**
65
+ * Disposes the test module.
66
+ * Call in afterEach/afterAll to clean up.
67
+ */
68
+ close(scope?: Scope): Promise<void>;
69
+ private ensureNotDisposed;
70
+ }
71
+ //# sourceMappingURL=test.module.d.ts.map