alloy-di 1.4.0 → 2.0.0
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 +12 -7
- package/bin/alloy.js +9 -0
- package/dist/cli.d.ts +24 -0
- package/dist/cli.js +168 -0
- package/dist/generate.d.ts +28 -0
- package/dist/generate.js +46 -0
- package/dist/lib/container.d.ts +78 -3
- package/dist/lib/container.js +130 -6
- package/dist/lib/lazy.d.ts +5 -1
- package/dist/lib/providers.d.ts +26 -2
- package/dist/lib/providers.js +23 -1
- package/dist/lib/scope.d.ts +21 -1
- package/dist/lib/types.d.ts +3 -1
- package/dist/plugins/consumer-plugin.d.ts +40 -0
- package/dist/plugins/consumer-plugin.js +101 -0
- package/dist/plugins/core/codegen.js +3 -3
- package/dist/plugins/core/container-loader.js +32 -17
- package/dist/plugins/core/discovery-runtime.js +19 -4
- package/dist/plugins/core/discovery-store.js +20 -6
- package/dist/plugins/core/generation-inputs.js +41 -0
- package/dist/plugins/core/scanner.js +71 -7
- package/dist/plugins/core/utils.js +1 -1
- package/dist/plugins/core/visualization-utils.js +1 -1
- package/dist/plugins/core/visualizer.js +40 -10
- package/dist/plugins/rollup-plugin/index.js +3 -5
- package/dist/plugins/vite-plugin/index.d.ts +2 -29
- package/dist/plugins/vite-plugin/index.js +19 -65
- package/dist/plugins/webpack-like-plugin.d.ts +32 -0
- package/dist/plugins/webpack-like-plugin.js +86 -0
- package/dist/rspack.d.ts +7 -0
- package/dist/rspack.js +10 -0
- package/dist/runtime.d.ts +6 -6
- package/dist/runtime.js +4 -4
- package/dist/scopes.d.ts +9 -1
- package/dist/scopes.js +29 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/vite.d.ts +2 -1
- package/dist/webpack.d.ts +7 -0
- package/dist/webpack.js +10 -0
- package/package.json +28 -12
- package/dist/lib/testing/mocking.d.ts +0 -12
- package/dist/lib/testing/mocking.js +0 -107
- package/dist/lib/testing/registry.js +0 -17
- package/dist/test.d.ts +0 -50
- package/dist/test.js +0 -65
package/dist/scopes.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Constructor, Newable, Token } from "./lib/types.js";
|
|
2
|
-
import { ResolutionContext, ServiceScope } from "./lib/scope.js";
|
|
3
2
|
import { ServiceIdentifier } from "./lib/service-identifiers.js";
|
|
3
|
+
import { FactoryCacheEntry, FactoryPendingEntry, ResolutionContext, ServiceScope } from "./lib/scope.js";
|
|
4
4
|
import { Container } from "./lib/container.js";
|
|
5
5
|
|
|
6
6
|
//#region src/scopes.d.ts
|
|
@@ -14,6 +14,8 @@ declare class Scope implements ResolutionContext {
|
|
|
14
14
|
private readonly cached;
|
|
15
15
|
private readonly pending;
|
|
16
16
|
private readonly valueProviders;
|
|
17
|
+
private readonly factoryValues;
|
|
18
|
+
private readonly factoryPending;
|
|
17
19
|
private readonly activeChildren;
|
|
18
20
|
private readonly instantiatedInstances;
|
|
19
21
|
constructor(parent: ResolutionContext, scopeName: ServiceScope);
|
|
@@ -23,12 +25,18 @@ declare class Scope implements ResolutionContext {
|
|
|
23
25
|
*/
|
|
24
26
|
getContainer(): Container;
|
|
25
27
|
getCached(target: Constructor): unknown;
|
|
28
|
+
hasCached(target: Constructor): boolean;
|
|
26
29
|
setCached(target: Constructor, instance: unknown): void;
|
|
27
30
|
getPending(target: Constructor): Promise<unknown> | undefined;
|
|
28
31
|
setPending(target: Constructor, promise: Promise<unknown>): void;
|
|
29
32
|
deletePending(target: Constructor): void;
|
|
30
33
|
getProvider(tokenId: symbol): unknown;
|
|
31
34
|
hasProvider(tokenId: symbol): boolean;
|
|
35
|
+
getFactoryValue(tokenId: symbol): FactoryCacheEntry | undefined;
|
|
36
|
+
setFactoryValue(tokenId: symbol, generation: number, value: unknown): void;
|
|
37
|
+
getFactoryPending(tokenId: symbol): FactoryPendingEntry | undefined;
|
|
38
|
+
setFactoryPending(tokenId: symbol, generation: number, promise: Promise<unknown>): void;
|
|
39
|
+
deleteFactoryPending(tokenId: symbol, generation: number): void;
|
|
32
40
|
/**
|
|
33
41
|
* Register a value provider for a token scoped to this context.
|
|
34
42
|
*/
|
package/dist/scopes.js
CHANGED
|
@@ -9,6 +9,8 @@ var Scope = class Scope {
|
|
|
9
9
|
cached = /* @__PURE__ */ new Map();
|
|
10
10
|
pending = /* @__PURE__ */ new Map();
|
|
11
11
|
valueProviders = /* @__PURE__ */ new Map();
|
|
12
|
+
factoryValues = /* @__PURE__ */ new Map();
|
|
13
|
+
factoryPending = /* @__PURE__ */ new Map();
|
|
12
14
|
activeChildren = /* @__PURE__ */ new Set();
|
|
13
15
|
instantiatedInstances = [];
|
|
14
16
|
constructor(parent, scopeName) {
|
|
@@ -27,6 +29,9 @@ var Scope = class Scope {
|
|
|
27
29
|
getCached(target) {
|
|
28
30
|
return this.cached.get(target);
|
|
29
31
|
}
|
|
32
|
+
hasCached(target) {
|
|
33
|
+
return this.cached.has(target);
|
|
34
|
+
}
|
|
30
35
|
setCached(target, instance) {
|
|
31
36
|
this.cached.set(target, instance);
|
|
32
37
|
this.instantiatedInstances.push(instance);
|
|
@@ -48,6 +53,28 @@ var Scope = class Scope {
|
|
|
48
53
|
if (this.valueProviders.has(tokenId)) return true;
|
|
49
54
|
return this.parent.hasProvider(tokenId);
|
|
50
55
|
}
|
|
56
|
+
getFactoryValue(tokenId) {
|
|
57
|
+
return this.factoryValues.get(tokenId);
|
|
58
|
+
}
|
|
59
|
+
setFactoryValue(tokenId, generation, value) {
|
|
60
|
+
this.factoryValues.set(tokenId, {
|
|
61
|
+
generation,
|
|
62
|
+
value
|
|
63
|
+
});
|
|
64
|
+
this.instantiatedInstances.push(value);
|
|
65
|
+
}
|
|
66
|
+
getFactoryPending(tokenId) {
|
|
67
|
+
return this.factoryPending.get(tokenId);
|
|
68
|
+
}
|
|
69
|
+
setFactoryPending(tokenId, generation, promise) {
|
|
70
|
+
this.factoryPending.set(tokenId, {
|
|
71
|
+
generation,
|
|
72
|
+
promise
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
deleteFactoryPending(tokenId, generation) {
|
|
76
|
+
if (this.factoryPending.get(tokenId)?.generation === generation) this.factoryPending.delete(tokenId);
|
|
77
|
+
}
|
|
51
78
|
/**
|
|
52
79
|
* Register a value provider for a token scoped to this context.
|
|
53
80
|
*/
|
|
@@ -111,6 +138,8 @@ var Scope = class Scope {
|
|
|
111
138
|
this.cached.clear();
|
|
112
139
|
this.pending.clear();
|
|
113
140
|
this.valueProviders.clear();
|
|
141
|
+
this.factoryValues.clear();
|
|
142
|
+
this.factoryPending.clear();
|
|
114
143
|
if (this.parent instanceof Scope) this.parent.activeChildren.delete(this);
|
|
115
144
|
}
|
|
116
145
|
if (errors.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/entry-points.test.ts","../src/fixture-subpaths.test.ts","../src/rollup.ts","../src/runtime.ts","../src/scopes.ts","../src/test.ts","../src/
|
|
1
|
+
{"root":["../src/cli.test.ts","../src/cli.ts","../src/entry-points.test.ts","../src/fixture-subpaths.test.ts","../src/generate.test.ts","../src/generate.ts","../src/rollup.ts","../src/rspack.ts","../src/runtime.ts","../src/scopes.ts","../src/vite.ts","../src/webpack.ts","../src/lib/container.factories-scoped.test.ts","../src/lib/container.factories.test.ts","../src/lib/container.identifiers.test.ts","../src/lib/container.internals.test.ts","../src/lib/container.test.ts","../src/lib/container.testing-features.test.ts","../src/lib/container.ts","../src/lib/decorators.runtime.test.ts","../src/lib/decorators.test-d.ts","../src/lib/decorators.ts","../src/lib/dependency-error.ts","../src/lib/env-detection.test.ts","../src/lib/env-detection.ts","../src/lib/lazy-retry.test.ts","../src/lib/lazy.ts","../src/lib/providers.test.ts","../src/lib/providers.ts","../src/lib/scope.ts","../src/lib/scopes.test.ts","../src/lib/service-identifiers.test.ts","../src/lib/service-identifiers.ts","../src/lib/tokens.test.ts","../src/lib/types.ts","../src/plugins/consumer-plugin.ts","../src/plugins/webpack-like-plugin.test.ts","../src/plugins/webpack-like-plugin.ts","../src/plugins/core/codegen.test.ts","../src/plugins/core/codegen.ts","../src/plugins/core/container-loader.test.ts","../src/plugins/core/container-loader.ts","../src/plugins/core/decorators.helpers.test.ts","../src/plugins/core/decorators.ts","../src/plugins/core/discovery-runtime.ts","../src/plugins/core/discovery-store.test.ts","../src/plugins/core/discovery-store.ts","../src/plugins/core/generation-inputs.ts","../src/plugins/core/identifier-resolver.test.ts","../src/plugins/core/identifier-resolver.ts","../src/plugins/core/lazy-utils.ts","../src/plugins/core/lazy.helpers.test.ts","../src/plugins/core/lazy.ts","../src/plugins/core/manifest-utils.ts","../src/plugins/core/manifest-utils.validation.test.ts","../src/plugins/core/scanner.test.ts","../src/plugins/core/scanner.ts","../src/plugins/core/scopes-validation.test.ts","../src/plugins/core/scopes-validation.ts","../src/plugins/core/types.ts","../src/plugins/core/utils.ts","../src/plugins/core/utils.walk.test.ts","../src/plugins/core/utils.write.test.ts","../src/plugins/core/visualization-utils.ts","../src/plugins/core/visualizer.test.ts","../src/plugins/core/visualizer.ts","../src/plugins/rollup-plugin/barrel-exports.test.ts","../src/plugins/rollup-plugin/barrel-exports.ts","../src/plugins/rollup-plugin/build-utils.test.ts","../src/plugins/rollup-plugin/build-utils.ts","../src/plugins/rollup-plugin/dependency-resolution.test.ts","../src/plugins/rollup-plugin/dependency-resolution.ts","../src/plugins/rollup-plugin/index.test.ts","../src/plugins/rollup-plugin/index.ts","../src/plugins/rollup-plugin/manifest-deps.test.ts","../src/plugins/rollup-plugin/manifest-deps.ts","../src/plugins/rollup-plugin/package-exports.test.ts","../src/plugins/rollup-plugin/package-exports.ts","../src/plugins/rollup-plugin/types.ts","../src/plugins/vite-plugin/duplicate-registrations.test.ts","../src/plugins/vite-plugin/index.ts","../src/plugins/vite-plugin/lazy-services.test.ts","../src/plugins/vite-plugin/lifecycle-and-hmr.test.ts","../src/plugins/vite-plugin/module-generation.test.ts","../src/plugins/vite-plugin/module-invalidation.ts","../src/plugins/vite-plugin/options-metadata.test.ts","../src/plugins/vite-plugin/test-utils.ts","../src/plugins/vite-plugin/transform-guards.test.ts","../src/plugins/vite-plugin/visualization-option.test.ts"],"version":"6.0.3"}
|
package/dist/vite.d.ts
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AlloyPluginOptions } from "./plugins/consumer-plugin.js";
|
|
2
|
+
import { AlloyWebpackLikePlugin } from "./plugins/webpack-like-plugin.js";
|
|
3
|
+
|
|
4
|
+
//#region src/webpack.d.ts
|
|
5
|
+
declare function alloy(options?: AlloyPluginOptions): AlloyWebpackLikePlugin;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { type AlloyPluginOptions, alloy, alloy as default };
|
package/dist/webpack.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createWebpackLikeAlloyPlugin } from "./plugins/webpack-like-plugin.js";
|
|
2
|
+
//#region src/webpack.ts
|
|
3
|
+
function alloy(options = {}) {
|
|
4
|
+
return createWebpackLikeAlloyPlugin(options, {
|
|
5
|
+
name: "alloy-di-webpack",
|
|
6
|
+
cacheFileName: "webpack-virtual-container.js"
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { alloy, alloy as default };
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alloy-di",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A build-time dependency injection plugin for
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "A build-time dependency injection plugin for TypeScript apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dependency-injection",
|
|
7
7
|
"di",
|
|
8
|
+
"rspack",
|
|
8
9
|
"typescript",
|
|
9
10
|
"vite",
|
|
10
|
-
"vite-plugin"
|
|
11
|
+
"vite-plugin",
|
|
12
|
+
"webpack"
|
|
11
13
|
],
|
|
12
14
|
"homepage": "https://alloy-di.dev",
|
|
13
15
|
"license": "MIT",
|
|
@@ -16,15 +18,21 @@
|
|
|
16
18
|
"type": "git",
|
|
17
19
|
"url": "https://github.com/ciddan/alloy-di/tree/main/packages/alloy"
|
|
18
20
|
},
|
|
21
|
+
"bin": {
|
|
22
|
+
"alloy": "./bin/alloy.js"
|
|
23
|
+
},
|
|
19
24
|
"files": [
|
|
25
|
+
"bin",
|
|
20
26
|
"dist",
|
|
21
27
|
"README.md"
|
|
22
28
|
],
|
|
23
29
|
"type": "module",
|
|
24
30
|
"sideEffects": false,
|
|
25
|
-
"module": "./dist/index.mjs",
|
|
26
|
-
"types": "./dist/index.d.ts",
|
|
27
31
|
"exports": {
|
|
32
|
+
"./generate": {
|
|
33
|
+
"types": "./dist/generate.d.ts",
|
|
34
|
+
"import": "./dist/generate.js"
|
|
35
|
+
},
|
|
28
36
|
"./runtime": {
|
|
29
37
|
"types": "./dist/runtime.d.ts",
|
|
30
38
|
"import": "./dist/runtime.js"
|
|
@@ -37,13 +45,17 @@
|
|
|
37
45
|
"types": "./dist/vite.d.ts",
|
|
38
46
|
"import": "./dist/vite.js"
|
|
39
47
|
},
|
|
48
|
+
"./webpack": {
|
|
49
|
+
"types": "./dist/webpack.d.ts",
|
|
50
|
+
"import": "./dist/webpack.js"
|
|
51
|
+
},
|
|
52
|
+
"./rspack": {
|
|
53
|
+
"types": "./dist/rspack.d.ts",
|
|
54
|
+
"import": "./dist/rspack.js"
|
|
55
|
+
},
|
|
40
56
|
"./rollup": {
|
|
41
57
|
"types": "./dist/rollup.d.ts",
|
|
42
58
|
"import": "./dist/rollup.js"
|
|
43
|
-
},
|
|
44
|
-
"./test": {
|
|
45
|
-
"types": "./dist/test.d.ts",
|
|
46
|
-
"import": "./dist/test.js"
|
|
47
59
|
}
|
|
48
60
|
},
|
|
49
61
|
"publishConfig": {
|
|
@@ -57,19 +69,23 @@
|
|
|
57
69
|
"devDependencies": {
|
|
58
70
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
59
71
|
"rimraf": "^6.1.3",
|
|
60
|
-
"rolldown": "1.1.0",
|
|
72
|
+
"rolldown": "^1.1.0",
|
|
61
73
|
"rolldown-plugin-dts": "^0.25.2"
|
|
62
74
|
},
|
|
63
75
|
"peerDependencies": {
|
|
76
|
+
"@rspack/core": "^1.0.0 || ^2.0.0",
|
|
64
77
|
"typescript": ">=5.0.0",
|
|
65
78
|
"vite": "^7.0.0 || ^8.0.0",
|
|
66
|
-
"
|
|
79
|
+
"webpack": "^5.0.0"
|
|
67
80
|
},
|
|
68
81
|
"peerDependenciesMeta": {
|
|
82
|
+
"@rspack/core": {
|
|
83
|
+
"optional": true
|
|
84
|
+
},
|
|
69
85
|
"vite": {
|
|
70
86
|
"optional": true
|
|
71
87
|
},
|
|
72
|
-
"
|
|
88
|
+
"webpack": {
|
|
73
89
|
"optional": true
|
|
74
90
|
}
|
|
75
91
|
},
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Newable } from "../types.js";
|
|
2
|
-
import { vi } from "vitest";
|
|
3
|
-
|
|
4
|
-
//#region src/lib/testing/mocking.d.ts
|
|
5
|
-
type MethodKeys<T> = { [K in keyof T]: T[K] extends ((...args: any[]) => any) ? K : never }[keyof T];
|
|
6
|
-
/** Typed mock shape returned for class auto-mocking. */
|
|
7
|
-
type MockOf<T> = Partial<T> & {
|
|
8
|
-
/** Map of method name -> vi spy function */spies: Record<Extract<MethodKeys<T>, string>, ReturnType<typeof vi.fn>>; /** Original constructor reference for introspection */
|
|
9
|
-
__target: Newable<T>;
|
|
10
|
-
};
|
|
11
|
-
//#endregion
|
|
12
|
-
export { MockOf };
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { isConstructor } from "../types.js";
|
|
2
|
-
import { isLazy } from "../lazy.js";
|
|
3
|
-
import { getRawDependencies } from "./registry.js";
|
|
4
|
-
import { vi } from "vitest";
|
|
5
|
-
//#region src/lib/testing/mocking.ts
|
|
6
|
-
/** Create a lightweight auto-mock instance for a class constructor. */
|
|
7
|
-
function mockClass(ctor) {
|
|
8
|
-
const proto = ctor.prototype;
|
|
9
|
-
const spies = {};
|
|
10
|
-
const mockObj = {
|
|
11
|
-
spies,
|
|
12
|
-
__target: ctor
|
|
13
|
-
};
|
|
14
|
-
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
15
|
-
if (key === "constructor") continue;
|
|
16
|
-
if (typeof proto[key] === "function") {
|
|
17
|
-
const fn = vi.fn();
|
|
18
|
-
spies[key] = fn;
|
|
19
|
-
mockObj[key] = fn;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return {
|
|
23
|
-
target: ctor,
|
|
24
|
-
mock: mockObj
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
function collectDependencyGraph(target) {
|
|
28
|
-
const constructors = /* @__PURE__ */ new Set();
|
|
29
|
-
const lazyDependencies = [];
|
|
30
|
-
const queue = [target];
|
|
31
|
-
const visited = /* @__PURE__ */ new Set();
|
|
32
|
-
while (queue.length) {
|
|
33
|
-
const current = queue.shift();
|
|
34
|
-
if (!current || visited.has(current)) continue;
|
|
35
|
-
visited.add(current);
|
|
36
|
-
constructors.add(current);
|
|
37
|
-
const deps = getRawDependencies(current);
|
|
38
|
-
for (const dep of deps) {
|
|
39
|
-
if (isLazy(dep)) {
|
|
40
|
-
lazyDependencies.push({ lazy: dep });
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
if (isConstructor(dep)) queue.push(dep);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return {
|
|
47
|
-
constructors,
|
|
48
|
-
lazyDependencies
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
function createMocksForConstructors(constructors, target, overrides) {
|
|
52
|
-
const mocks = /* @__PURE__ */ new Map();
|
|
53
|
-
for (const ctor of constructors) {
|
|
54
|
-
if (ctor === target) continue;
|
|
55
|
-
if (overrides.has(ctor)) continue;
|
|
56
|
-
const classMock = mockClass(ctor);
|
|
57
|
-
mocks.set(ctor, classMock.mock);
|
|
58
|
-
}
|
|
59
|
-
return mocks;
|
|
60
|
-
}
|
|
61
|
-
function applyMocksToContainer(container, mocks) {
|
|
62
|
-
for (const [ctor, mock] of mocks.entries()) container.overrideInstance(ctor, mock);
|
|
63
|
-
}
|
|
64
|
-
function patchLazyDependencies(lazyDeps, mocks, overrides) {
|
|
65
|
-
const patches = [];
|
|
66
|
-
for (const { lazy } of lazyDeps) {
|
|
67
|
-
const originalImporter = lazy.importer;
|
|
68
|
-
lazy.importer = async () => {
|
|
69
|
-
const realCtor = await originalImporter();
|
|
70
|
-
let mockObj = mocks.get(realCtor);
|
|
71
|
-
if (!overrides.has(realCtor) && !mockObj) {
|
|
72
|
-
mockObj = mockClass(realCtor).mock;
|
|
73
|
-
mocks.set(realCtor, mockObj);
|
|
74
|
-
}
|
|
75
|
-
if (!mockObj) return realCtor;
|
|
76
|
-
return buildMockCtorFrom(realCtor, mockObj);
|
|
77
|
-
};
|
|
78
|
-
patches.push({
|
|
79
|
-
lazy,
|
|
80
|
-
originalImporter
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
return patches;
|
|
84
|
-
}
|
|
85
|
-
/** Traverse dependency graph (deep) and create class mocks, including lazy deps. */
|
|
86
|
-
function applyAutoMocks(options) {
|
|
87
|
-
const { target, container, overridesCtors } = options;
|
|
88
|
-
const graph = collectDependencyGraph(target);
|
|
89
|
-
const mocks = createMocksForConstructors(graph.constructors, target, overridesCtors);
|
|
90
|
-
applyMocksToContainer(container, mocks);
|
|
91
|
-
return {
|
|
92
|
-
mocks,
|
|
93
|
-
lazyPatches: patchLazyDependencies(graph.lazyDependencies, mocks, overridesCtors)
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
/** Build a class constructor that exposes spies from a mock object via prototype methods */
|
|
97
|
-
function buildMockCtorFrom(realCtor, mock) {
|
|
98
|
-
function MockCtor() {}
|
|
99
|
-
const proto = realCtor.prototype;
|
|
100
|
-
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
101
|
-
if (key === "constructor") continue;
|
|
102
|
-
if (typeof proto[key] === "function" && key in mock.spies) MockCtor.prototype[key] = mock.spies[key];
|
|
103
|
-
}
|
|
104
|
-
return MockCtor;
|
|
105
|
-
}
|
|
106
|
-
//#endregion
|
|
107
|
-
export { applyAutoMocks };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { dependenciesRegistry } from "../decorators.js";
|
|
2
|
-
//#region src/lib/testing/registry.ts
|
|
3
|
-
/** Take a deep(ish) snapshot of current dependency registry state. */
|
|
4
|
-
function snapshotRegistry() {
|
|
5
|
-
return new Map(dependenciesRegistry);
|
|
6
|
-
}
|
|
7
|
-
/** Restore dependency registry from a prior snapshot. */
|
|
8
|
-
function restoreRegistry(snapshot) {
|
|
9
|
-
dependenciesRegistry.clear();
|
|
10
|
-
for (const [k, v] of snapshot.entries()) dependenciesRegistry.set(k, v);
|
|
11
|
-
}
|
|
12
|
-
/** Get raw declared dependencies including constructors, Lazy and Tokens */
|
|
13
|
-
function getRawDependencies(target) {
|
|
14
|
-
return (dependenciesRegistry.get(target)?.dependencies ?? (() => []))();
|
|
15
|
-
}
|
|
16
|
-
//#endregion
|
|
17
|
-
export { getRawDependencies, restoreRegistry, snapshotRegistry };
|
package/dist/test.d.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Newable, Token, createToken } from "./lib/types.js";
|
|
2
|
-
import { ServiceIdentifier } from "./lib/service-identifiers.js";
|
|
3
|
-
import { Container } from "./lib/container.js";
|
|
4
|
-
import { ProviderDefinitions } from "./lib/providers.js";
|
|
5
|
-
import { MockOf } from "./lib/testing/mocking.js";
|
|
6
|
-
import { vi } from "vitest";
|
|
7
|
-
|
|
8
|
-
//#region src/test.d.ts
|
|
9
|
-
interface OverrideSpec {
|
|
10
|
-
/** Class constructor instance overrides */
|
|
11
|
-
instances?: Array<[Newable<unknown>, unknown]>;
|
|
12
|
-
/** Token value overrides */
|
|
13
|
-
tokens?: Array<[Token<unknown>, unknown]>;
|
|
14
|
-
}
|
|
15
|
-
interface CreateTestContainerOptions {
|
|
16
|
-
overrides?: OverrideSpec;
|
|
17
|
-
autoMock?: boolean;
|
|
18
|
-
target?: Newable<unknown>;
|
|
19
|
-
providers?: ProviderDefinitions | ProviderDefinitions[];
|
|
20
|
-
}
|
|
21
|
-
interface TestContainerHandle {
|
|
22
|
-
container: Container;
|
|
23
|
-
get<T>(target: Newable<T> | ServiceIdentifier<T>): Promise<T>;
|
|
24
|
-
getIdentifier?<T>(ctor: Newable<T>): ServiceIdentifier<T>;
|
|
25
|
-
/** Retrieve a token value via a synthetic classless access */
|
|
26
|
-
getToken<T>(token: Token<T>): T;
|
|
27
|
-
/** Provide a token value into the container */
|
|
28
|
-
provideToken?<T>(token: Token<T>, value: T): void;
|
|
29
|
-
/** Placeholder restore hook (future phases may implement overlay stacks). */
|
|
30
|
-
restore(): void;
|
|
31
|
-
/** Retrieve a single class mock (if autoMock enabled). */
|
|
32
|
-
getMock?<T>(ctor: Newable<T>): MockOf<T> | undefined;
|
|
33
|
-
/** Retrieve multiple class mocks preserving tuple order. */
|
|
34
|
-
getMocks?<T extends readonly Newable<unknown>[]>(ctors: T): { [K in keyof T]: T[K] extends Newable<infer I> ? MockOf<I> | undefined : never };
|
|
35
|
-
/** Convenience: get a specific method spy from a mock. */
|
|
36
|
-
spyOf?<T>(ctor: Newable<T>, method: Extract<keyof T, string>): ReturnType<typeof vi.fn> | undefined;
|
|
37
|
-
/** Convenience: reset all mock spies (calls vi.fn().mockReset()). */
|
|
38
|
-
clearMockSpies?(): void;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Create a test-focused container with manual overrides.
|
|
42
|
-
* - Does not perform auto-mocking (Phase 2 will expand this).
|
|
43
|
-
*/
|
|
44
|
-
declare function createTestContainer(opts?: CreateTestContainerOptions | OverrideSpec): TestContainerHandle & {
|
|
45
|
-
getMock<T>(ctor: Newable<T>): MockOf<T> | undefined;
|
|
46
|
-
getMocks<T extends readonly Newable<unknown>[]>(ctors: T): { [K in keyof T]: T[K] extends Newable<infer I> ? MockOf<I> | undefined : never };
|
|
47
|
-
provideToken<T>(token: Token<T>, value: T): void;
|
|
48
|
-
};
|
|
49
|
-
//#endregion
|
|
50
|
-
export { CreateTestContainerOptions, type MockOf, OverrideSpec, TestContainerHandle, createTestContainer, createToken };
|
package/dist/test.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { createToken } from "./lib/types.js";
|
|
2
|
-
import { Container } from "./lib/container.js";
|
|
3
|
-
import { applyProviders } from "./lib/providers.js";
|
|
4
|
-
import { restoreRegistry, snapshotRegistry } from "./lib/testing/registry.js";
|
|
5
|
-
import { applyAutoMocks } from "./lib/testing/mocking.js";
|
|
6
|
-
//#region src/test.ts
|
|
7
|
-
/**
|
|
8
|
-
* Create a test-focused container with manual overrides.
|
|
9
|
-
* - Does not perform auto-mocking (Phase 2 will expand this).
|
|
10
|
-
*/
|
|
11
|
-
function createTestContainer(opts) {
|
|
12
|
-
const isLegacy = !!opts && !("autoMock" in opts) && !("target" in opts) && !("overrides" in opts);
|
|
13
|
-
const normalizedOpts = isLegacy ? { overrides: opts } : opts ?? {};
|
|
14
|
-
const overrides = normalizedOpts.overrides ?? (isLegacy ? opts : void 0);
|
|
15
|
-
const container = new Container();
|
|
16
|
-
const snapshot = snapshotRegistry();
|
|
17
|
-
if (normalizedOpts.providers) applyProviders(container, normalizedOpts.providers);
|
|
18
|
-
for (const [tok, value] of overrides?.tokens ?? []) container.provideValue(tok, value);
|
|
19
|
-
const overriddenCtors = new Set(overrides?.instances?.map(([c]) => c) ?? []);
|
|
20
|
-
for (const [ctor, instance] of overrides?.instances ?? []) container.overrideInstance(ctor, instance);
|
|
21
|
-
let mocks;
|
|
22
|
-
let lazyPatches;
|
|
23
|
-
if (normalizedOpts.autoMock && normalizedOpts.target) {
|
|
24
|
-
const auto = applyAutoMocks({
|
|
25
|
-
target: normalizedOpts.target,
|
|
26
|
-
container,
|
|
27
|
-
overridesCtors: overriddenCtors
|
|
28
|
-
});
|
|
29
|
-
mocks = auto.mocks;
|
|
30
|
-
lazyPatches = auto.lazyPatches;
|
|
31
|
-
}
|
|
32
|
-
return {
|
|
33
|
-
container,
|
|
34
|
-
get: (target) => typeof target === "symbol" ? container.getByIdentifier(target) : container.get(target),
|
|
35
|
-
getIdentifier: (ctor) => container.getIdentifier(ctor),
|
|
36
|
-
getToken: (token) => {
|
|
37
|
-
return container.getToken(token);
|
|
38
|
-
},
|
|
39
|
-
provideToken: (token, value) => {
|
|
40
|
-
container.provideValue(token, value);
|
|
41
|
-
},
|
|
42
|
-
getMock: (ctor) => {
|
|
43
|
-
return mocks?.get(ctor) ?? void 0;
|
|
44
|
-
},
|
|
45
|
-
getMocks: (ctors) => {
|
|
46
|
-
return ctors.map((c) => mocks?.get(c));
|
|
47
|
-
},
|
|
48
|
-
spyOf: (ctor, method) => {
|
|
49
|
-
return (mocks?.get(ctor))?.spies[method];
|
|
50
|
-
},
|
|
51
|
-
clearMockSpies: () => {
|
|
52
|
-
if (!mocks) return;
|
|
53
|
-
for (const [, m] of mocks) {
|
|
54
|
-
const spies = m.spies;
|
|
55
|
-
for (const key of Object.keys(spies)) spies[key].mockReset();
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
restore: () => {
|
|
59
|
-
for (const patch of lazyPatches ?? []) patch.lazy.importer = patch.originalImporter;
|
|
60
|
-
restoreRegistry(snapshot);
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
//#endregion
|
|
65
|
-
export { createTestContainer, createToken };
|