@voltro/plugin-auth-auth0 0.22.0 → 0.22.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 +67 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -39,6 +39,73 @@ _Changes staged for the next release accumulate here (rolled up from
|
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
+
## [0.22.1] — 2026-08-01
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- **@voltro/cli** — **Two things a QUERY could not do that a mutation beside it could — and a redirect that answered 500 in dev and 303 in production.**
|
|
47
|
+
|
|
48
|
+
### `useAggregate` in a subscription handler: `Service not found`
|
|
49
|
+
|
|
50
|
+
The documented way to read an aggregate from a handler (`useAggregate(def).read(...)`) failed at runtime with `Service not found: @voltro/AggregateRegistry`, on every delivery.
|
|
51
|
+
|
|
52
|
+
Both boot paths hand the subscription/query executor a `provideEffect` callback, and each had written its own — smaller — layer set:
|
|
53
|
+
|
|
54
|
+
| path | provided to an Effect-returning query | |---|---| | `voltro dev` | store + actionBase (**no** `mergedUserLayer`) | | `voltro serve` | store, and nothing else | | either, handler path | the full set |
|
|
55
|
+
|
|
56
|
+
So a query could not `yield*` the aggregate registry, the cache, the kv store, a plugin's service or the app's own `layers:` — while a mutation in the same app could. `useAggregate` was one symptom of the set being wrong, not a bug of its own.
|
|
57
|
+
|
|
58
|
+
The cost the reporter measured is worth repeating: a subscription whose delivery fails renders NOTHING, so their working-time card showed `00:00` — no error, no empty state. Silence is the worst failure shape a data path has.
|
|
59
|
+
|
|
60
|
+
Both paths now provide the same set, and `serveApi` reaches it through the single helper its handler path already used (it had two, one complete and one not).
|
|
61
|
+
|
|
62
|
+
**Why their tests could not see it**, in their words: `@voltro/testing` supplies `aggregateRegistryLayer(...)` and the existing example uses it, so the suite provided exactly what production lacked — *"wenn der Layer im Test nötig ist und in der Laufzeit fehlt, ist er genau der falsche Default."* That is the sharpest line in the report. A harness that hands the code under test something the runtime does not is a second implementation, not a harness. The runtime supplies it now; the layer stays available for tests that genuinely stand alone.
|
|
63
|
+
|
|
64
|
+
### A loader that throws `RedirectError` answers 303 in dev too
|
|
65
|
+
|
|
66
|
+
`agent-docs/routing.md` promises a 303 with `Location`. `voltro start` did it; `voltro dev` caught the same throw as a render failure and answered **500 with no `Location`**.
|
|
67
|
+
|
|
68
|
+
The divergence was written down as intended — *"each path maps it onto its own convention"* — and recording it is what let it stand. A redirect is CONTROL FLOW. Two renderers that disagree about that disagree about what the app does, and the one they disagreed on is the one every developer and every dev-environment probe hits first. It cost the reporter a rollout: a readiness probe walked a redirecting route, got the 500, and the deployment never became ready.
|
|
69
|
+
|
|
70
|
+
One mapper (`loaderControlResponse`) now answers for both, brand-checked rather than `instanceof` because the error crosses a bundle boundary — and since the CLI cannot import `@voltro/web`, a test reads that package's source so a renamed brand cannot silently put dev back to 500.
|
|
71
|
+
|
|
72
|
+
`NotFoundError` → 404 comes with it, for the same reason.
|
|
73
|
+
- **@voltro/client, @voltro/cli** — **A hot reload no longer takes every page down, and a route that owns the whole origin says so.**
|
|
74
|
+
|
|
75
|
+
### `defineStore` and module re-evaluation
|
|
76
|
+
|
|
77
|
+
The duplicate-name guard keyed on the NAME alone and threw. It is right about the danger — two stores sharing a name silently share state — and wrong about one case: a module RE-EVALUATING, which is exactly what a hot reload does.
|
|
78
|
+
|
|
79
|
+
A consumer measured the cost on one running dev server:
|
|
80
|
+
|
|
81
|
+
| | status | bytes | |---|---|---| | fresh boot | 200 | 43629 | | touch any `*.store.ts` | 500 | 2328 | | three further requests | 500 | — |
|
|
82
|
+
|
|
83
|
+
One edit to a store — or to anything importing one — took all 225 of their pages down for the rest of the session, with no self-recovery. Their workaround memoised registrations by name on `globalThis`, which works and costs the thing HMR is for: editing a store's initial state stopped taking effect until a restart.
|
|
84
|
+
|
|
85
|
+
Registration is keyed by ORIGIN **and evaluation PASS** now — the calling module's stack frame, without `line:column` so that shifting the call down a line is still the same origin. The same module may redefine its own store and gets the LIVE handle back, so state survives the edit. A DIFFERENT module still throws, and the error now names both files, because "rename one" is only actionable if you know which two to look at.
|
|
86
|
+
|
|
87
|
+
Origin alone was not enough, and the existing suite caught it: two `defineStore('x')` calls in ONE file share an origin, so origin-keying merged them — the exact silent state-sharing the guard exists for. A module body runs synchronously, so two registrations in one file land in the same pass; a hot reload re-evaluates in a LATER tick. Same origin AND same pass is a collision; same origin, later pass is a reload.
|
|
88
|
+
|
|
89
|
+
(`line:column` would separate those two as well, and was rejected: stripping the position is what lets an edit ABOVE a `defineStore` call shift it down a line without reading as a new origin — and that edit is the common case this is about.)
|
|
90
|
+
|
|
91
|
+
When the runtime gives no usable stack, it behaves like a collision rather than a redefinition: if the two cannot be told apart, silently sharing state is the worse outcome, and that is what the guard exists for.
|
|
92
|
+
|
|
93
|
+
### A route whose first segment is dynamic
|
|
94
|
+
|
|
95
|
+
`voltro doctor` reports a page route like `[id]/[playerCode]` — its FIRST segment dynamic, so it answers every two-segment URL on that origin, `/api/health` included.
|
|
96
|
+
|
|
97
|
+
The pattern is not a bug; that is what it means. It is invisible until something requests such a URL, and then the page renders, its loader runs, and the failure reads as an application error rather than as a route claiming a path nobody meant it to. Advisory, and scoped so it stays readable: `orders/[id]` is not flagged — a dynamic segment under a literal one is bounded by that literal.
|
|
98
|
+
|
|
99
|
+
The same report described this as REST routes losing to page segments. They do not compete: `restRoutes` are served by the API server and pages by the web server, on different ports. The three-segment probe paths they adopted worked because the pattern is two-segment, not because precedence changed.
|
|
100
|
+
|
|
101
|
+
### Two items from the same report were already shipped
|
|
102
|
+
|
|
103
|
+
Both were measured against 0.20.1 and landed in **0.21.0**, so they need no change — only saying so:
|
|
104
|
+
|
|
105
|
+
- `Could not resolve "@voltro/cli/startEntry"` during the start-bundle build → fixed by `resolve @voltro/cli/{start,serve}Entry from the CLI, not the app root`. It is the same class as the `tsx` bare-specifier bug: a specifier for a package the APP never declared is invisible from the app root under strict pnpm. - `voltro schedule run <name>` exists, with `--process`, `--trigger manual|external` and `--url`. Note it POSTs to a mutating inspect endpoint, so it now needs `VOLTRO_INSPECT_WRITE_TOKEN` outside dev.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
42
109
|
## [0.22.0] — 2026-08-01
|
|
43
110
|
|
|
44
111
|
### ⚠ BREAKING
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/plugin-auth-auth0",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.1",
|
|
4
4
|
"description": "Auth0-backed AuthStrategy for the Voltro framework. Verifies Auth0-issued JWTs via the tenant's JWKS endpoint. Conforms to @voltro/protocol AuthStrategy so it composes with other IdP plugins.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"node": ">=24.0.0"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@voltro/protocol": "0.22.
|
|
35
|
+
"@voltro/protocol": "0.22.1"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"effect": "^3.22.0"
|