@velajs/testing 0.2.0 → 0.2.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
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1 (2026-05-14)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
|
|
7
|
+
- **`compile()` now replicates `bootstrap()`'s global token setup.** Registers `Container`, `ModuleRef`, and `REQUEST_CONTEXT` as global tokens (the last is the canonical seam for the per-request bag that `RouteManager.setRequestInstance` populates). Marks `APP_GUARD/PIPE/INTERCEPTOR/FILTER/MIDDLEWARE` as global so multi-provider pipeline registration via `bindAppProviders` resolves cleanly. Before this fix, guards / services that injected `REQUEST_CONTEXT` (the documented `@CurrentUser` lazy-decorator pattern) crashed at request time with "REQUEST_CONTEXT can only be resolved inside a request". New test pins the behavior end-to-end.
|
|
8
|
+
- **Overrides now win for controller-internal constructor injection.** Pre-registering an override at the root container's `__root__` bucket only beat framework-internal lookups (no `requestingModuleId`). Controller constructor injection passes the controller's module id, which finds the module's own registration before the root override and short-circuits. The builder now post-processes after `loader.load()` and overwrites the registration in every module bucket that already holds the token.
|
|
9
|
+
|
|
10
|
+
### Breaking changes
|
|
11
|
+
|
|
12
|
+
- **`@velajs/vela` peer bumped to `>=1.6.0`.** Needs `REQUEST_CONTEXT` and `createLazyParamDecorator` re-exports (added in vela 1.6.0).
|
|
13
|
+
|
|
3
14
|
## 0.2.0 (2026-04-30)
|
|
4
15
|
|
|
5
16
|
Bugs fixed, rebuilt on `@velajs/vela/internal`, no more `reflect-metadata` dep.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { REQUEST_CONTEXT, Scope } from "@velajs/vela";
|
|
2
|
+
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR, APP_MIDDLEWARE, APP_PIPE, ComponentManager, Container, MetadataRegistry, ModuleLoader, ModuleRef, RouteManager, VelaApplication, bindAppProviders } from "@velajs/vela/internal";
|
|
2
3
|
import { TestingModule } from "./testing-module.js";
|
|
3
4
|
export class OverrideBy {
|
|
4
5
|
builder;
|
|
@@ -78,11 +79,49 @@ export class TestingModuleBuilder {
|
|
|
78
79
|
exports: this.metadata.exports
|
|
79
80
|
});
|
|
80
81
|
const container = new Container();
|
|
82
|
+
// Replicate bootstrap()'s global token setup so request-pipeline tests
|
|
83
|
+
// can resolve REQUEST_CONTEXT, ModuleRef, and the APP_* sentinel tokens
|
|
84
|
+
// from any module scope. Without this, guards / decorators that inject
|
|
85
|
+
// REQUEST_CONTEXT through ExecutionContext fail with "no provider"
|
|
86
|
+
// when the request enters the pipeline. See vela/src/factory/bootstrap.ts.
|
|
81
87
|
container.register({
|
|
82
88
|
provide: Container,
|
|
83
89
|
useValue: container
|
|
84
90
|
});
|
|
85
|
-
|
|
91
|
+
container.markGlobalToken(Container);
|
|
92
|
+
container.register({
|
|
93
|
+
provide: ModuleRef,
|
|
94
|
+
useFactory: (c)=>new ModuleRef(c),
|
|
95
|
+
inject: [
|
|
96
|
+
Container
|
|
97
|
+
]
|
|
98
|
+
});
|
|
99
|
+
container.markGlobalToken(ModuleRef);
|
|
100
|
+
for (const t of [
|
|
101
|
+
APP_GUARD,
|
|
102
|
+
APP_PIPE,
|
|
103
|
+
APP_INTERCEPTOR,
|
|
104
|
+
APP_FILTER,
|
|
105
|
+
APP_MIDDLEWARE
|
|
106
|
+
]){
|
|
107
|
+
container.markGlobalToken(t);
|
|
108
|
+
}
|
|
109
|
+
// REQUEST_CONTEXT is seeded into each per-request child container by
|
|
110
|
+
// RouteManager via setRequestInstance. Registering with a throw-factory
|
|
111
|
+
// here ensures findRegistration succeeds (so the child's cached request
|
|
112
|
+
// instance is returned) while surfacing a clear error if the token is
|
|
113
|
+
// ever resolved outside the request path.
|
|
114
|
+
container.register({
|
|
115
|
+
provide: REQUEST_CONTEXT,
|
|
116
|
+
scope: Scope.REQUEST,
|
|
117
|
+
useFactory: ()=>{
|
|
118
|
+
throw new Error('REQUEST_CONTEXT can only be resolved inside a request — ' + 'it is seeded by RouteManager when the request enters the pipeline.');
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
container.markGlobalToken(REQUEST_CONTEXT);
|
|
122
|
+
// Pre-register at root so `moduleRef.get(token)` and framework-internal
|
|
123
|
+
// resolves (instantiate(guard, container) with no requestingModuleId) see
|
|
124
|
+
// the override immediately.
|
|
86
125
|
for (const override of this.overrides){
|
|
87
126
|
container.register(override.provider);
|
|
88
127
|
}
|
|
@@ -90,6 +129,25 @@ export class TestingModuleBuilder {
|
|
|
90
129
|
ComponentManager.init(container);
|
|
91
130
|
const loader = new ModuleLoader(container, routeManager);
|
|
92
131
|
loader.load(TestRootModule);
|
|
132
|
+
// Force-apply overrides into every module bucket that already holds the
|
|
133
|
+
// token. Without this, controller constructor-injection (which passes
|
|
134
|
+
// requestingModuleId to findRegistration) finds the module's own
|
|
135
|
+
// registration first and never consults the root override. Re-registering
|
|
136
|
+
// with the module's id overwrites the bucket entry.
|
|
137
|
+
//
|
|
138
|
+
// Reaches into Container internals (the `providers` map) until vela
|
|
139
|
+
// exposes a public "force replace across all scopes" API. The shape is
|
|
140
|
+
// stable in vela 1.6.x; if this breaks under a future vela version, raise
|
|
141
|
+
// a vela API request before working around again.
|
|
142
|
+
const providersMap = container.providers;
|
|
143
|
+
for (const override of this.overrides){
|
|
144
|
+
for (const [moduleId, bucket] of providersMap){
|
|
145
|
+
if (moduleId === '__root__') continue;
|
|
146
|
+
if (bucket.has(override.token)) {
|
|
147
|
+
container.register(override.provider, moduleId);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
93
151
|
bindAppProviders(routeManager, container, loader);
|
|
94
152
|
const app = new VelaApplication(container, routeManager);
|
|
95
153
|
const instances = await loader.resolveAllInstances();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velajs/testing",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Testing utilities for Vela framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -47,14 +47,14 @@
|
|
|
47
47
|
"node": ">=20"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@velajs/vela": ">=1.
|
|
50
|
+
"@velajs/vela": ">=1.6.0",
|
|
51
51
|
"hono": ">=4"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@swc/cli": "^0.8.0",
|
|
55
55
|
"@swc/core": "^1.15.11",
|
|
56
56
|
"@types/bun": "latest",
|
|
57
|
-
"@velajs/vela": "^1.
|
|
57
|
+
"@velajs/vela": "^1.6.0",
|
|
58
58
|
"hono": "^4",
|
|
59
59
|
"typescript": "^5",
|
|
60
60
|
"unplugin-swc": "^1.5.9",
|