@voltro/cli 0.35.0 → 0.36.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/CHANGELOG.md +68 -0
- package/dist/{apiBuild-DYD_ONLD.js → apiBuild-DiE9zcj6.js} +1 -1
- package/dist/apiBuild-ZEZnCXn2.js +2 -0
- package/dist/bin.js +1 -1
- package/dist/{build-CD8K4XOr.js → build-DBe6c7qC.js} +6 -6
- package/dist/{checkCommand-DKpDLlqu.js → checkCommand-BTA6P3Yr.js} +1 -1
- package/dist/{checkCommand-Ct9xkTrS.js → checkCommand-BhG0gmUD.js} +2 -2
- package/dist/{codegenCommand-C4YoQIc2.js → codegenCommand-DH-8ZXzR.js} +1 -1
- package/dist/{codemodRunner-BnFq3Fgu.js → codemodRunner-DjQGrdmg.js} +64 -47
- package/dist/{commands-BE8E7zF3.js → commands-Bp7utV-7.js} +18 -18
- package/dist/{dashboardCommand-D7SgZGaN.js → dashboardCommand-D5Jwjmr1.js} +1 -1
- package/dist/{dataCommand-BhYwDgg-.js → dataCommand-DnCm0B2C.js} +1 -1
- package/dist/{dev-D2BikO7a.js → dev-BSFTgCQ5.js} +1 -1
- package/dist/{dev-C7sFZq3m.js → dev-Dc4cpmRl.js} +2000 -2000
- package/dist/doctorCommand-BYffQc0s.js +2 -0
- package/dist/{doctorCommand-DnimF5IM.js → doctorCommand-CNFtt3nR.js} +9 -9
- package/dist/{dormancyCommand-QewYug_s.js → dormancyCommand-6F6NsJKf.js} +1 -1
- package/dist/{embeddingsCommand-BfiLS_QI.js → embeddingsCommand-DRRdneJD.js} +1 -1
- package/dist/{envCommand-CCGPRQY1.js → envCommand-TZzcyqZ-.js} +1 -1
- package/dist/{evolveCommand-CHsLCtDf.js → evolveCommand-iU35TPjT.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{infoCommand-DwOgK1t6.js → infoCommand-unqisJGp.js} +1 -1
- package/dist/{runtimeTrace-CH3eUiMw.js → runtimeTrace-D5LJ_N55.js} +1 -1
- package/dist/{sdkgen-BLkvGRfX.js → sdkgen-82xVuvbt.js} +1 -1
- package/dist/serveCommand-CEBVP36A.js +2 -0
- package/dist/{serveCommand-iwlUBNS1.js → serveCommand-VVGcIMIw.js} +487 -487
- package/dist/serveEntry.js +1 -1
- package/dist/updateCommand-CSBXVsYq.js +2 -0
- package/dist/{updateCommand-x0pI_x-B.js → updateCommand-CwnUK_mf.js} +1 -1
- package/dist/{webhooksCommand-DlAgS2Iw.js → webhooksCommand-di1CJVzu.js} +1 -1
- package/package.json +23 -17
- package/templates/AGENTS.md +1 -1
- package/templates/agent-docs/_index.md +1 -1
- package/templates/agent-docs/cli.md +22 -0
- package/templates/agent-docs/database/misc.md +33 -0
- package/templates/agent-docs/whats-new.md +31 -130
- package/templates/apps/api-ai/package.json +7 -7
- package/templates/apps/api-auth/package.json +8 -8
- package/templates/apps/api-backend/package.json +7 -7
- package/templates/apps/api-backend-deactivation/package.json +7 -7
- package/templates/apps/api-backend-mail/package.json +8 -8
- package/templates/apps/api-backend-mariadb/package.json +9 -9
- package/templates/apps/api-backend-sqlite/package.json +8 -8
- package/templates/apps/api-backend-storage/package.json +8 -8
- package/templates/apps/api-cms/package.json +10 -10
- package/templates/apps/api-collab/package.json +8 -8
- package/templates/apps/api-data-advanced/package.json +8 -8
- package/templates/apps/api-durable/package.json +8 -8
- package/templates/apps/api-feature-flags/package.json +9 -9
- package/templates/apps/api-governance/package.json +8 -8
- package/templates/apps/api-kv/package.json +8 -8
- package/templates/apps/api-moderation/package.json +8 -8
- package/templates/apps/api-observability/package.json +8 -8
- package/templates/apps/api-ratelimit/package.json +8 -8
- package/templates/apps/api-rbac/package.json +8 -8
- package/templates/apps/api-rest/package.json +7 -7
- package/templates/apps/api-saas/package.json +11 -11
- package/templates/apps/api-saas-starter/package.json +10 -10
- package/templates/apps/api-search/package.json +8 -8
- package/templates/apps/api-status/package.json +8 -8
- package/templates/apps/api-versioning/package.json +8 -8
- package/templates/apps/api-webhooks/package.json +9 -9
- package/templates/apps/changelog/package.json +6 -6
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +8 -8
- package/templates/apps/frontend-app/package.json +9 -9
- package/templates/apps/frontend-auth/package.json +8 -8
- package/templates/apps/frontend-blank/package.json +7 -7
- package/templates/apps/frontend-cms/package.json +9 -9
- package/templates/apps/frontend-collab/package.json +10 -10
- package/templates/apps/frontend-contact/package.json +7 -7
- package/templates/apps/frontend-dashboard/package.json +7 -7
- package/templates/apps/frontend-docs/package.json +7 -7
- package/templates/apps/frontend-i18n/package.json +6 -6
- package/templates/apps/frontend-landing/package.json +7 -7
- package/templates/apps/frontend-portal/package.json +8 -8
- package/templates/apps/frontend-saas/package.json +8 -8
- package/templates/apps/frontend-spa/package.json +7 -7
- package/templates/apps/frontend-ssr/package.json +7 -7
- package/templates/apps/frontend-ssr-api/package.json +8 -8
- package/templates/apps/frontend-static-blog/package.json +6 -6
- package/templates/apps/frontend-status/package.json +8 -8
- package/templates/apps/mobile-app/package.json +3 -3
- package/dist/apiBuild-B8aoJvuw.js +0 -2
- package/dist/doctorCommand-CM4Ch9C7.js +0 -2
- package/dist/serveCommand-CbDHU6l-.js +0 -2
- package/dist/updateCommand-BlMZhWgO.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -39,6 +39,74 @@ _Changes staged for the next release accumulate here (rolled up from
|
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
+
## [0.36.0] — 2026-08-13
|
|
43
|
+
|
|
44
|
+
### ⚠ BREAKING
|
|
45
|
+
|
|
46
|
+
- **@voltro/integration-http, @voltro/plugin-atlassian** — A 401 from an upstream now produces `code: 'unauthorized'`, not `code: 'session_expired'`. The connection vault's own failure — where we DO know the credential is unusable — becomes `code: 'credential_unusable'`.
|
|
47
|
+
|
|
48
|
+
`session_expired` asserted a cause the status cannot support. A 401 says the credential was not accepted and says nothing about why: expired, revoked, insufficient scope and MALFORMED all produce it. A consumer's plugin sent ciphertext as a bearer token (a separate defect, fixed in the same release), the upstream answered 401, this name called it an expired session, and their health check acted on the name and deleted a valid session. Login loop, with every symptom pointing at a revoked credential.
|
|
49
|
+
|
|
50
|
+
Names get acted on, which is the whole reason to split them:
|
|
51
|
+
|
|
52
|
+
- `'unauthorized'` — the upstream refused. Non-transient, so still never retried; `status` rides along so a caller that knows more about its own upstream can decide for itself. Deciding for them is what this gives up. - `'credential_unusable'` — the connection vault could not produce a credential (no grant, revoked grant, refresh failed). Here the claim is ours to make, because the failure is ours rather than the far end's.
|
|
53
|
+
|
|
54
|
+
The 401 message stopped saying "session expired" too. It now says the credential was refused and that the reason is not in the response — which is the honest sentence and the one that would have saved the day this cost.
|
|
55
|
+
|
|
56
|
+
Its test asserts the CLAIM rather than banning the word: the first version forbade `/expired/i` and went red against the corrected message, which lists expiry as one of several things a 401 can mean. That distinction is the point of the change, so the assertion had to be about `session expired` specifically.
|
|
57
|
+
|
|
58
|
+
**`voltro update` carries you across this** — codemod `0.35.1/01_unauthorized-replaces-session-expired`.
|
|
59
|
+
|
|
60
|
+
### Added
|
|
61
|
+
|
|
62
|
+
- **@voltro/web** — **`apiSurface: compatible` — why the three altered golden lines cannot break a caller.** `LoaderContext` and `LoaderFn` each gained a type parameter WITH a default, so an unparameterised reference still resolves. The one that needed proving is `query?`, which went from a written-out signature to `LoaderQuery<Procedures>` — and `LoaderQuery` is a conditional whose false branch is character-for-character the previous signature. `unknown` does not extend `ProcedureTypeMap`, so the defaulted instantiation takes that branch.
|
|
63
|
+
|
|
64
|
+
Proved with `tsc` rather than by reading it: a probe asserting mutual assignability between `LoaderQuery<unknown>` and the old signature compiles, and inverting the probe fails — with tsc printing the resolved type as `<T = unknown>(tag: string, input?: Record<string, unknown> | undefined) => Promise<T>`, which is the old signature verbatim.
|
|
65
|
+
|
|
66
|
+
`LoaderContext` takes the app's procedure map, so a loader's `query` infers its input and output from the descriptor instead of returning `unknown`.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import type { AppProcedures } from '<your-api>/rpcGroup'
|
|
70
|
+
|
|
71
|
+
export const loader = async ({ query }: LoaderContext<AppProcedures>) => {
|
|
72
|
+
const rows = await query?.('bookmarks.list', { limit: 100 })
|
|
73
|
+
// ^ inferred; an unknown tag or a wrong input shape is a compile error
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`AppProcedures` is generated already and has been for a while — it was wired to `createHooks` on the CLIENT and to nothing on the server, so every loader call site spelled its own output type by hand and a typo in a tag compiled. A consumer reported it twice.
|
|
78
|
+
|
|
79
|
+
The extraction reuses `ProcedureInput` / `ProcedureOutput` from `@voltro/client` rather than re-deriving them: a second answer to "what does this tag return" drifts the first time a descriptor field is renamed, and both answers look right in isolation.
|
|
80
|
+
|
|
81
|
+
Opt-in, and non-breaking: with no map named, the signature is the previous `<T = unknown>(tag: string, …)`. The framework cannot import an app's generated file, which is the same reason `createHooks<AppProcedures>` takes it explicitly.
|
|
82
|
+
|
|
83
|
+
Covered by a `.test-d.ts`, because the failure mode is "it compiles when it should not" and no runtime assertion can observe that. Two of its cases exist because the first version was vacuous: an `interface` fixture does not satisfy the map constraint (no implicit index signature — the codegen emits an alias for exactly this reason), so the typed branch fell back silently and every `@ts-expect-error` came back unused.
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- **@voltro/cli** — The store a plugin receives through `bindDataStore` now carries the storage codec, so an `.encrypted()` column read through it decrypts.
|
|
88
|
+
|
|
89
|
+
A consumer measured both stores inside one request: `ctx.store` gave a 44-character plaintext PAT, and the store their plugin's `credentialsResolver` received gave 113 characters of `enc:v1:…`. Ciphertext is a syntactically valid bearer token, so nothing threw. Jira answered 401, `@voltro/integration-http` named that `session_expired`, their PAT health check did the reasonable thing with that name and deleted the session, and the user got login → dashboard → login forever. A configuration error in the costume of an authentication refusal, where every symptom pointed at the one explanation that was wrong.
|
|
90
|
+
|
|
91
|
+
The part worth recording is that `bootStoreCodec.ts` was written for exactly this, after it happened at two other seams, and its header predicts this consumer's symptom verbatim: "a route reading an `.encrypted()` column got the literal string `enc:v1:…` back … the failure reads as 'wrong credential'". The fix was applied per-seam. `bindDataStore` was not one of the seams anybody listed, so it happened a third time — and a per-seam test stayed green throughout, because it covered the two seams somebody remembered.
|
|
92
|
+
|
|
93
|
+
`bootStoreHandouts.test.ts` asserts the rule instead: no boot path hands a plugin the raw driver, on either boot path, with the wrapper applied before the handout. The codec needs no Subject — it is how a column is spelled on disk versus in JS — so there was never anything a boot-level store could not carry.
|
|
94
|
+
|
|
95
|
+
Also relevant to anyone who followed the 0.28.0 codemod: that codemod told apps to stop carrying a credential on the Subject and look it up in the resolver instead. Doing exactly that is what put an app on this seam, so the instruction and `.encrypted()` were not simultaneously satisfiable through it.
|
|
96
|
+
- **@voltro/runtime, @voltro/cli** — The rpc/WebSocket query and stream arms now resolve row visibility before the executor sees a context. Fixes a 0.35.0 regression that made every read throw for an app with a registered row filter, and the older leak underneath it.
|
|
97
|
+
|
|
98
|
+
0.35.0 shipped two things for the row filter: the registration moved to `globalThis` (so a duplicate `@voltro/runtime` instance cannot hide it), and a scoped store built without a resolved scope started throwing instead of silently serving unfiltered rows. The first was a real fix for a real hazard. The second was correct in principle and immediately fatal in practice, because the framework itself had a path that did exactly what it now refuses.
|
|
99
|
+
|
|
100
|
+
The consumer who reported the original leak ran the two-line check we asked for and `getRowFilter()` was visible from their request path — so the instance split was NOT their cause, and our hypothesis was wrong. Their measurement is what found the real one: the refusal fired, meaning the registration was FOUND and `ctx.rowFilter` was still undefined at the store. Nothing was missing; a step was.
|
|
101
|
+
|
|
102
|
+
Four arms reach a request context. `makeOneShotQueryRunner` (REST) and `makeQuerySubscriber` (SSE) both `await withRowFilter(...)` and say so in a comment. The rpc query handler and the stream handler — each hand-copied into both boot paths — handed the raw request straight through. So a user's executor received a context whose `ctx.store` applied no row filter, on the two arms that carry the most traffic. It survived because subscriptions are refiltered per DELIVERY, which made a descriptor-returning query look correct end to end while the executor's own reads were not.
|
|
103
|
+
|
|
104
|
+
`withScopedRequest` is the seam that fixes it once: a request that already carries a scope passes through untouched (resolving twice would run the app's `load` twice per request), an app with NO filter stays fully synchronous, and an app with one gets an Effect — which every one of these call sites already accepts. A boot-path parity test pins both stream arms and the shared producer.
|
|
105
|
+
|
|
106
|
+
The refusal also stopped firing for a SYSTEM subject. That is not a softening: `resolveRowFilterScopeFor` returns `NO_ROW_FILTER` for a system subject, so the only correct value was already determined, and several legitimate paths (schedules, resumed workflows, the webhook trigger context) build a context directly with no scope. Demanding a decision there is what took the api down.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
42
110
|
## [0.35.0] — 2026-08-13
|
|
43
111
|
|
|
44
112
|
### ⚠ BREAKING
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as e } from "./dev-
|
|
1
|
+
import { f as e } from "./dev-Dc4cpmRl.js";
|
|
2
2
|
import { ut as t } from "./webDev-Dybxew86.js";
|
|
3
3
|
import { t as n } from "./dialectDriver-CgXnDfec.js";
|
|
4
4
|
import { dirname as r, isAbsolute as i, join as a, relative as o, resolve as s } from "node:path";
|
package/dist/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { r as e } from "./commands-
|
|
2
|
+
import { r as e } from "./commands-Bp7utV-7.js";
|
|
3
3
|
import { a as t } from "./nodeEnvironment-cGFAj1J8.js";
|
|
4
4
|
import { t as n } from "./loadEnv-D9nEOClM.js";
|
|
5
5
|
import { n as r } from "./cliError-BmdYnghb.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { pn as e } from "./dev-
|
|
1
|
+
import { pn as e } from "./dev-Dc4cpmRl.js";
|
|
2
2
|
import { D as t, G as n, K as r, O as i, S as a, W as o, Y as s, a as c, b as l, d as u, f as d, k as f, s as p, st as m, ut as h, v as g, x as _, y as v } from "./webDev-Dybxew86.js";
|
|
3
3
|
import { t as y } from "./cliRuntime-Dh7UDinH.js";
|
|
4
4
|
import { a as b } from "./renderModeScan-D7J1B7Kw.js";
|
|
5
|
-
import { i as x, o as S, s as C } from "./apiBuild-
|
|
5
|
+
import { i as x, o as S, s as C } from "./apiBuild-DiE9zcj6.js";
|
|
6
6
|
import { n as w } from "./renderProfile-1OWWAAtx.js";
|
|
7
7
|
import { dirname as T, join as E, resolve as D } from "node:path";
|
|
8
8
|
import { existsSync as O, promises as k } from "node:fs";
|
|
@@ -467,7 +467,7 @@ var N = A({ scope: "voltro:build" }), P = async (e) => {
|
|
|
467
467
|
file: n.file,
|
|
468
468
|
reason: n.reason
|
|
469
469
|
});
|
|
470
|
-
let { regenerateRpcGroup: r } = await import("./codegenCommand-
|
|
470
|
+
let { regenerateRpcGroup: r } = await import("./codegenCommand-DH-8ZXzR.js"), i = await r(e);
|
|
471
471
|
if (i.kind === "refused") {
|
|
472
472
|
F.warn("could not regenerate the rpc group — building against what is on disk", { reason: i.reason });
|
|
473
473
|
return;
|
|
@@ -479,10 +479,10 @@ var N = A({ scope: "voltro:build" }), P = async (e) => {
|
|
|
479
479
|
}, K = async (e) => {
|
|
480
480
|
let t = await u(e);
|
|
481
481
|
if (!t) {
|
|
482
|
-
let { loadApiConfig: t } = await import("./dev-
|
|
482
|
+
let { loadApiConfig: t } = await import("./dev-BSFTgCQ5.js"), n = await t(e);
|
|
483
483
|
if (n) {
|
|
484
484
|
F.info("building api app", { app: n.name ?? "(unnamed)" }), await G(e);
|
|
485
|
-
let { runApiBuild: t, runServeBundleBuild: r } = await import("./apiBuild-
|
|
485
|
+
let { runApiBuild: t, runServeBundleBuild: r } = await import("./apiBuild-ZEZnCXn2.js");
|
|
486
486
|
await t(e);
|
|
487
487
|
try {
|
|
488
488
|
await r(e);
|
|
@@ -701,7 +701,7 @@ var N = A({ scope: "voltro:build" }), P = async (e) => {
|
|
|
701
701
|
return t.ran ? t.exitCode : (yield* j.logError("no web app found at this path", { hint: "looked for app.config.ts with `type: 'web'`" }), 1);
|
|
702
702
|
}), J = async (t) => {
|
|
703
703
|
if (t.includes("--target")) {
|
|
704
|
-
let { runSdkBuildCommand: e } = await import("./sdkgen-
|
|
704
|
+
let { runSdkBuildCommand: e } = await import("./sdkgen-82xVuvbt.js");
|
|
705
705
|
return e(t);
|
|
706
706
|
}
|
|
707
707
|
let n = t.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await y(q(n), { scope: "voltro:build" }), i = e(n);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, r as t, t as n } from "./checkCommand-
|
|
1
|
+
import { n as e, r as t, t as n } from "./checkCommand-BhG0gmUD.js";
|
|
2
2
|
export { n as offlineManifest, e as runCheckCommand, t as toInput };
|
|
@@ -4,7 +4,7 @@ import { r } from "./appGraph-KGDPTuTy.js";
|
|
|
4
4
|
import { n as i } from "./cliOutput-D1tSBoRM.js";
|
|
5
5
|
import { n as a, o, r as s, t as c } from "./inspectFetch-EMuhTG_9.js";
|
|
6
6
|
import { r as l } from "./fileTaxonomy-CJfgOllU.js";
|
|
7
|
-
import { x as u } from "./doctorCommand-
|
|
7
|
+
import { x as u } from "./doctorCommand-CNFtt3nR.js";
|
|
8
8
|
import { resolve as d } from "node:path";
|
|
9
9
|
import { readdirSync as f, statSync as p } from "node:fs";
|
|
10
10
|
//#region src/observedDiff.ts
|
|
@@ -141,7 +141,7 @@ var m = (e) => e === void 0 ? [] : typeof e == "string" ? [e] : e, h = /* @__PUR
|
|
|
141
141
|
let t = e.severity === "error" ? "✗ error" : "⚠ warn", n = e.file ? ` (${e.file})` : "";
|
|
142
142
|
return `${t} ${e.rule} ${e.node}${n}\n ${e.breaks.join("; ")}\n fix: ${e.fix}`;
|
|
143
143
|
}).join("\n"), C = async (e) => {
|
|
144
|
-
let { walk: t, loadDiscovered: n, loadApiConfig: r } = await import("./dev-
|
|
144
|
+
let { walk: t, loadDiscovered: n, loadApiConfig: r } = await import("./dev-BSFTgCQ5.js"), { buildRpcEntry: i } = await import("./manifestBuild-COkJoyAr.js"), { buildCapabilityManifest: a } = await import("./inspect-P4pxoMaV.js"), { relative: o } = await import("node:path"), s = await n(await t(e)), c = (t, n, r) => i(t, n, o(e, r)), l = [
|
|
145
145
|
...s.queries.map((e) => c(e.descriptor, "query", e.file)),
|
|
146
146
|
...s.mutations.map((e) => c(e.descriptor, "mutation", e.file)),
|
|
147
147
|
...s.actions.map((e) => c(e.descriptor, "action", e.file)),
|
|
@@ -5066,7 +5066,21 @@ var x = (e, t, n) => {
|
|
|
5066
5066
|
"",
|
|
5067
5067
|
"The read is issued at most once per key per process, off the commit path."
|
|
5068
5068
|
].join("\n")
|
|
5069
|
-
}), Gr = (e) => /RunStepStatus/.test(e) || /['"]succeeded['"]/.test(e) && /['"]waiting['"]/.test(e) && /RunStep|runStep|flow/i.test(e),
|
|
5069
|
+
}), Gr = (e) => /RunStepStatus/.test(e) || /['"]succeeded['"]/.test(e) && /['"]waiting['"]/.test(e) && /RunStep|runStep|flow/i.test(e), Kr = C({
|
|
5070
|
+
version: "0.35.0",
|
|
5071
|
+
id: "0.35.0/04_flow-run-step-skipped",
|
|
5072
|
+
title: "A flow run step can now be 'skipped' — handle it where you render a run timeline",
|
|
5073
|
+
kind: "manual",
|
|
5074
|
+
appliesTo: ({ project: e }) => e.getSourceFiles().some((e) => Gr(e.getFullText())),
|
|
5075
|
+
note: (/* @__PURE__ */ "A FLOW RUN STEP CAN NOW BE 'skipped'.((`when:` on a flow step gates it on a prior value, and a step whose condition(is false is SKIPPED rather than run. That is a sixth member of(`RunStepStatus`, so an exhaustive switch over it no longer compiles, and a(lookup keyed by status now has a hole.((WHAT TO DO:((1) FIND IT. Anywhere you render or branch on a run step status — a timeline( component, a status badge map, a progress calculation.((2) DECIDE WHAT A SKIPPED STEP LOOKS LIKE. It is NOT a failure and NOT a( success: it did not run, on purpose, and it produced no output. The( step carries `skipReason` — the rendered condition, e.g.( `{{mode}} equals \"full\"` — so the timeline can say WHY.((3) DO NOT DEFAULT IT TO INVISIBLE. Dropping the row compiles and reads fine( in review, and it reproduces exactly the problem `skipReason` exists to( prevent: a step that vanished is indistinguishable from a step nobody( declared, which is the first thing a user reports as a bug.((A PROGRESS COUNT probably needs a second look too: `succeeded / total` now(under-reports a completed run that skipped a step. Counting(`succeeded + skipped` against the total is usually what was meant.((If your app does not render a flow timeline, there is nothing to do — this(note fires on any file that names the status type or its literals.".split("(")).join("\n")
|
|
5076
|
+
}), qr = C({
|
|
5077
|
+
version: "0.35.0",
|
|
5078
|
+
id: "0.35.0/05_declared-schema-drops-runtime-flags",
|
|
5079
|
+
title: "The declared schema no longer reads `CDC` / `VOLTRO_UNDO` / `VOLTRO_TRACING_PERSIST`",
|
|
5080
|
+
kind: "manual",
|
|
5081
|
+
appliesTo: () => !0,
|
|
5082
|
+
note: (/* @__PURE__ */ "The set of framework tables your app DECLARES is hashed into the schema(fingerprint. A pre-deploy `voltro db apply` records that hash; every serving(container recomputes it and refuses to boot if it differs. Until this release(three RUNTIME flags fed into that set:(( CDC=0 removed `_voltro_cdc_offsets`( VOLTRO_UNDO=on added `_voltro_undo_log`( VOLTRO_TRACING_PERSIST=all added `_voltro_traces`((All three read as pure runtime knobs, so they tend to live on the PODS and(not on the pre-upgrade migrate Job — which is a green migrate followed by(every pod in CrashLoopBackOff. This was reported against a Helm deployment(where `CDC: \"0\"` was in all three overlays' pod blocks and none of their(jobs; it had been latent for months and would have fired on the next deploy.((WHAT YOU MUST DO — only if you set one of these to turn a table ON in(production:(( * `VOLTRO_UNDO=on` in production → add to app.config.ts:( export default { schema: { undo: true }, … }( * `VOLTRO_TRACING_PERSIST` keeping trace history in production → add:( export default { schema: { traces: true }, … }(( Without the declaration, `voltro serve` now REFUSES to boot and names the( field. That refusal is the point: before, the same configuration either( wrote to a table nobody created or produced a fingerprint the migrate job( could not reproduce.(( Turning capture OFF still needs no declaration and never will — a declared( table nobody writes to is harmless. Only turning it ON is a schema claim.((WHAT HAPPENS WITHOUT ANY ACTION:(( * On mariadb or mssql you will see ONE additive `create-table` in your next( plan: `_voltro_cdc_offsets` is now declared by the DIALECT rather than by( `CDC`, so it exists whether or not that process drives CDC. It is an( offsets table — a handful of rows — and the alternative was leaving a( runtime flag able to split your fleet.( * On postgres/sqlite nothing changes: those dialects have no offsets table.((AND ONE THING WORTH DOING ANYWAY: if you are upgrading a deployment that has(a separate migrate job, diff that job's `env:` against your pods' once. The(framework can now guarantee its OWN tables do not depend on a runtime flag;(it cannot make the same guarantee for a plugin's `extendSchema.tables`, which(is app code and may read anything. A `prod-mismatch` refusal now prints which(tables this process decided and from which input, so the comparison is quick.".split("(")).join("\n")
|
|
5083
|
+
}), q = "session_expired", J = [
|
|
5070
5084
|
ge,
|
|
5071
5085
|
_e,
|
|
5072
5086
|
ye,
|
|
@@ -5165,23 +5179,26 @@ var x = (e, t, n) => {
|
|
|
5165
5179
|
Ir,
|
|
5166
5180
|
Hr,
|
|
5167
5181
|
Wr,
|
|
5182
|
+
Kr,
|
|
5183
|
+
qr,
|
|
5168
5184
|
C({
|
|
5169
|
-
version: "0.35.
|
|
5170
|
-
id: "0.35.
|
|
5171
|
-
title: "A
|
|
5172
|
-
kind: "
|
|
5173
|
-
appliesTo: ({ project: e }) => e.getSourceFiles().some((e) =>
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5185
|
+
version: "0.35.1",
|
|
5186
|
+
id: "0.35.1/01_unauthorized-replaces-session-expired",
|
|
5187
|
+
title: "A 401 is `code: 'unauthorized'`; the vault's own failure is `'credential_unusable'`",
|
|
5188
|
+
kind: "transform",
|
|
5189
|
+
appliesTo: ({ project: e }) => e.getSourceFiles().some((e) => e.getFullText().includes(q)),
|
|
5190
|
+
transform: ({ project: e, log: t }) => {
|
|
5191
|
+
let n = [];
|
|
5192
|
+
for (let t of e.getSourceFiles()) {
|
|
5193
|
+
if (!t.getFullText().includes(q)) continue;
|
|
5194
|
+
let e = !1;
|
|
5195
|
+
for (let n of t.getDescendantsOfKind(11)) n.getLiteralValue() === q && (n.setLiteralValue("unauthorized"), e = !0);
|
|
5196
|
+
e && n.push(t.getFilePath());
|
|
5197
|
+
}
|
|
5198
|
+
n.length !== 0 && t(`rewrote '${q}' to 'unauthorized' in ${n.length} file(s).\n A 401 now means only "the credential was refused" — expired, revoked, wrong\n scope and MALFORMED all produce that status, and the old name asserted the\n first one. If a rewritten branch was meant to catch a credential your\n CONNECTION VAULT could not produce (no grant, revoked grant, failed refresh),\n change it to 'credential_unusable' — that is the code the vault raises, and it\n is the one where re-auth is genuinely the right action.\n A health check that logs the user out on this code should read 'unauthorized'\n as "ask again", not as "the session is gone".\n` + n.map((e) => ` ${e}`).join("\n"));
|
|
5199
|
+
}
|
|
5183
5200
|
})
|
|
5184
|
-
],
|
|
5201
|
+
], Y = /* @__PURE__ */ new Set([
|
|
5185
5202
|
"node_modules",
|
|
5186
5203
|
".git",
|
|
5187
5204
|
"dist",
|
|
@@ -5193,12 +5210,12 @@ var x = (e, t, n) => {
|
|
|
5193
5210
|
".turbo",
|
|
5194
5211
|
".cache",
|
|
5195
5212
|
".output"
|
|
5196
|
-
]),
|
|
5213
|
+
]), Jr = () => [...[...Y].map((e) => `**/${e}/**`), "**/.voltro-*/**"], X = /(?:from|import)\s*\(?\s*['"]([^'"]+)['"]|require\s*\(\s*['"]([^'"]+)['"]\s*\)/g, Z = /\.(?:tsx?|jsx?|mjs|cjs)$/, Yr = (e) => m(e).replace(Z, ""), Xr = (e) => {
|
|
5197
5214
|
let t = e.split("/").filter((e) => e.length > 0).pop();
|
|
5198
5215
|
if (t === void 0 || t === "." || t === "..") return;
|
|
5199
|
-
let n = t.replace(
|
|
5216
|
+
let n = t.replace(Z, "");
|
|
5200
5217
|
return n.length > 0 ? n : void 0;
|
|
5201
|
-
},
|
|
5218
|
+
}, Zr = (e) => {
|
|
5202
5219
|
let t = /* @__PURE__ */ new Map();
|
|
5203
5220
|
for (let n of e) {
|
|
5204
5221
|
let e;
|
|
@@ -5207,57 +5224,57 @@ var x = (e, t, n) => {
|
|
|
5207
5224
|
} catch {
|
|
5208
5225
|
continue;
|
|
5209
5226
|
}
|
|
5210
|
-
|
|
5211
|
-
for (let r =
|
|
5212
|
-
let e =
|
|
5227
|
+
X.lastIndex = 0;
|
|
5228
|
+
for (let r = X.exec(e); r !== null; r = X.exec(e)) {
|
|
5229
|
+
let e = Xr(r[1] ?? r[2] ?? "");
|
|
5213
5230
|
if (e === void 0) continue;
|
|
5214
5231
|
let i = t.get(e);
|
|
5215
5232
|
i === void 0 ? t.set(e, /* @__PURE__ */ new Set([n])) : i.add(n);
|
|
5216
5233
|
}
|
|
5217
5234
|
}
|
|
5218
5235
|
return t;
|
|
5219
|
-
},
|
|
5236
|
+
}, Qr = (e, t) => {
|
|
5220
5237
|
let n = new Set(e);
|
|
5221
|
-
for (let r of e) for (let e of [
|
|
5238
|
+
for (let r of e) for (let e of [Yr(r), m(h(r))]) {
|
|
5222
5239
|
let r = t.get(e);
|
|
5223
5240
|
if (r !== void 0) for (let e of r) n.add(e);
|
|
5224
5241
|
}
|
|
5225
5242
|
return n;
|
|
5226
|
-
},
|
|
5243
|
+
}, $r = [
|
|
5227
5244
|
"**/*.ts",
|
|
5228
5245
|
"**/*.tsx",
|
|
5229
5246
|
"!**/node_modules/**",
|
|
5230
5247
|
"!**/dist/**",
|
|
5231
5248
|
"!**/.framework/**",
|
|
5232
5249
|
"!**/*.d.ts"
|
|
5233
|
-
],
|
|
5250
|
+
], Q = (e, t, n = ni) => {
|
|
5234
5251
|
let r = /* @__PURE__ */ new Set();
|
|
5235
|
-
for (let e of t) for (let t of e.scope ??
|
|
5252
|
+
for (let e of t) for (let t of e.scope ?? $r) r.add(t);
|
|
5236
5253
|
let i = n(e);
|
|
5237
5254
|
if (i !== void 0) {
|
|
5238
|
-
let t = [...r].filter((e) => !e.startsWith("!")).map((e) =>
|
|
5255
|
+
let t = [...r].filter((e) => !e.startsWith("!")).map((e) => ti(e)), n = [...r].filter((e) => e.startsWith("!")).map((e) => ti(e.slice(1))), a = [...Y], o = [];
|
|
5239
5256
|
for (let r of i) {
|
|
5240
5257
|
if (a.some((e) => r === e || r.startsWith(`${e}/`) || r.includes(`/${e}/`)) || !t.some((e) => e(r)) || n.some((e) => e(r))) continue;
|
|
5241
5258
|
let i = g(e, r);
|
|
5242
5259
|
v(i) && o.push(i);
|
|
5243
5260
|
}
|
|
5244
|
-
return
|
|
5261
|
+
return ei(o.length, e), o;
|
|
5245
5262
|
}
|
|
5246
5263
|
let a = oe([...r], {
|
|
5247
5264
|
cwd: e,
|
|
5248
5265
|
absolute: !0,
|
|
5249
5266
|
expandDirectories: !1,
|
|
5250
5267
|
followSymbolicLinks: !1,
|
|
5251
|
-
ignore: [...
|
|
5268
|
+
ignore: [...Jr()]
|
|
5252
5269
|
});
|
|
5253
|
-
return
|
|
5254
|
-
},
|
|
5255
|
-
let n =
|
|
5270
|
+
return ei(a.length, e), a;
|
|
5271
|
+
}, ei = (e, t) => {
|
|
5272
|
+
let n = ri();
|
|
5256
5273
|
if (!(e <= n)) throw Error(`voltro update: the codemod scan matched ${e} files under ${t}, past the ${n} ceiling.\n Every matched file is parsed into one ts-morph project, so the heap needed grows with\n this number — past the ceiling it runs out of memory, and V8 aborts without naming a\n limit, which is why this stops here instead. Three ways out, in order:\n • put non-source directories in .gitignore (inside a git repo the scan then never\n sees them at all — a build cache, a data dump, a virtualenv),\n • run \`voltro update\` from the app directory rather than the workspace root, or\n • take one codemod at a time: \`voltro update --dry-run\` lists the ids, then\n \`voltro update --codemods-only --only <id>\` runs a single one.\n If every one of those files really is source this pass must rewrite, raise the ceiling\n with VOLTRO_CODEMOD_MAX_FILES and give node room: NODE_OPTIONS=--max-old-space-size=8192.`);
|
|
5257
|
-
},
|
|
5274
|
+
}, ti = (e) => {
|
|
5258
5275
|
let t = e.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*\//g, "\0").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\u0000/g, "(?:.*/)?").replace(/\\\{([^}]*)\\\}/g, (e, t) => `(?:${t.split(",").join("|")})`);
|
|
5259
5276
|
return (e) => RegExp(`^${t}$`).test(e);
|
|
5260
|
-
},
|
|
5277
|
+
}, ni = (e) => {
|
|
5261
5278
|
try {
|
|
5262
5279
|
let t = re("git", [
|
|
5263
5280
|
"ls-files",
|
|
@@ -5278,17 +5295,17 @@ var x = (e, t, n) => {
|
|
|
5278
5295
|
} catch {
|
|
5279
5296
|
return;
|
|
5280
5297
|
}
|
|
5281
|
-
},
|
|
5298
|
+
}, ri = () => {
|
|
5282
5299
|
let e = Number(process.env.VOLTRO_CODEMOD_MAX_FILES);
|
|
5283
5300
|
return Number.isInteger(e) && e > 0 ? e : 2e4;
|
|
5284
|
-
},
|
|
5301
|
+
}, $ = (e, t) => {
|
|
5285
5302
|
let n = e.split(".").map(Number), r = t.split(".").map(Number);
|
|
5286
5303
|
for (let e = 0; e < 3; e++) {
|
|
5287
5304
|
let t = (n[e] ?? 0) - (r[e] ?? 0);
|
|
5288
5305
|
if (t !== 0) return t;
|
|
5289
5306
|
}
|
|
5290
5307
|
return 0;
|
|
5291
|
-
},
|
|
5308
|
+
}, ii = (e, t, n = J) => n.filter((n) => $(e, n.version) < 0 && $(n.version, t) <= 0).slice().sort(he), ai = (e, t, n = () => {}) => {
|
|
5292
5309
|
let r = [], i = [], a = [];
|
|
5293
5310
|
for (let o of t) {
|
|
5294
5311
|
if (!(!o.appliesTo || o.appliesTo({ project: e }))) {
|
|
@@ -5334,8 +5351,8 @@ var x = (e, t, n) => {
|
|
|
5334
5351
|
manual: i,
|
|
5335
5352
|
skipped: a
|
|
5336
5353
|
};
|
|
5337
|
-
},
|
|
5338
|
-
let t = e.log ?? (() => {}), n =
|
|
5354
|
+
}, oi = async (e) => {
|
|
5355
|
+
let t = e.log ?? (() => {}), n = ii(e.from, e.to, e.codemods ?? J), r = e.only === void 0 || e.only.length === 0 ? n : (() => {
|
|
5339
5356
|
let t = n.filter((t) => e.only.includes(t.id)), r = e.only.filter((e) => !n.some((t) => t.id === e));
|
|
5340
5357
|
if (r.length > 0) throw Error(`voltro update --only: no codemod in ${e.from} → ${e.to} has id ${r.map((e) => `"${e}"`).join(", ")}.\n Available for this jump:\n${n.map((e) => ` ${e.id}`).join("\n")}`);
|
|
5341
5358
|
return t;
|
|
@@ -5354,15 +5371,15 @@ var x = (e, t, n) => {
|
|
|
5354
5371
|
baseUrl: i.baseUrl,
|
|
5355
5372
|
paths: i.paths
|
|
5356
5373
|
} }
|
|
5357
|
-
}), o, s =
|
|
5374
|
+
}), o, s = Q(e.root, r), c = r.filter((e) => e.needsImporters === !0 && e.scope !== void 0), l = [], u = [], d = [], p = c.length > 0 ? Zr(Q(e.root, [{
|
|
5358
5375
|
...c[0],
|
|
5359
|
-
scope:
|
|
5376
|
+
scope: $r
|
|
5360
5377
|
}])) : void 0;
|
|
5361
5378
|
for (let n of r) {
|
|
5362
5379
|
if (c.includes(n)) {
|
|
5363
|
-
let r = a(), i =
|
|
5364
|
-
for (let e of
|
|
5365
|
-
let s =
|
|
5380
|
+
let r = a(), i = Q(e.root, [n]);
|
|
5381
|
+
for (let e of Qr(i, p)) v(e) && r.addSourceFileAtPath(e);
|
|
5382
|
+
let s = ai(r, [n], t);
|
|
5366
5383
|
e.dryRun || await r.save(), l.push(...s.applied), u.push(...s.manual), d.push(...s.skipped), o = void 0;
|
|
5367
5384
|
continue;
|
|
5368
5385
|
}
|
|
@@ -5371,7 +5388,7 @@ var x = (e, t, n) => {
|
|
|
5371
5388
|
for (let t of s) v(t) && e.addSourceFileAtPath(t);
|
|
5372
5389
|
return e;
|
|
5373
5390
|
})();
|
|
5374
|
-
let r =
|
|
5391
|
+
let r = ai(o, [n], t);
|
|
5375
5392
|
e.dryRun || await o.save(), l.push(...r.applied), u.push(...r.manual), d.push(...r.skipped);
|
|
5376
5393
|
}
|
|
5377
5394
|
return {
|
|
@@ -5381,4 +5398,4 @@ var x = (e, t, n) => {
|
|
|
5381
5398
|
};
|
|
5382
5399
|
};
|
|
5383
5400
|
//#endregion
|
|
5384
|
-
export { C as i,
|
|
5401
|
+
export { C as i, oi as n, Y as r, $ as t };
|
|
@@ -90,7 +90,7 @@ var a = () => {
|
|
|
90
90
|
name: "dev",
|
|
91
91
|
summary: "Start the local development server (auto-discovers routes / mutations).",
|
|
92
92
|
status: "wired",
|
|
93
|
-
run: (e) => import("./dev-
|
|
93
|
+
run: (e) => import("./dev-BSFTgCQ5.js").then((t) => t.runDev(e)),
|
|
94
94
|
help: {
|
|
95
95
|
usage: "[app]",
|
|
96
96
|
examples: [["voltro dev", "boot the app in the current directory"], ["voltro dev apps/acme/api", "boot a specific app"]],
|
|
@@ -108,7 +108,7 @@ var a = () => {
|
|
|
108
108
|
name: "dashboard",
|
|
109
109
|
summary: "Serve the DevTools dashboard standalone (from @voltro/dashboard). Targets via VOLTRO_DASHBOARD_APPS; --port to override.",
|
|
110
110
|
status: "wired",
|
|
111
|
-
run: (e) => import("./dashboardCommand-
|
|
111
|
+
run: (e) => import("./dashboardCommand-D5Jwjmr1.js").then((t) => t.runDashboardCommand(e)),
|
|
112
112
|
help: {
|
|
113
113
|
usage: "[--port <n>]",
|
|
114
114
|
flags: [["--port <n>", "port to serve the dashboard on"]],
|
|
@@ -120,7 +120,7 @@ var a = () => {
|
|
|
120
120
|
name: "check",
|
|
121
121
|
summary: "Verify the app graph (blast-radius checks) against a running api; LLM-shaped --json diagnostics. Flags: --json, --process <p>, --diff removeTable:<name>.",
|
|
122
122
|
status: "wired",
|
|
123
|
-
run: (e) => import("./checkCommand-
|
|
123
|
+
run: (e) => import("./checkCommand-BTA6P3Yr.js").then((t) => t.runCheckCommand(e)),
|
|
124
124
|
help: {
|
|
125
125
|
usage: "[--json] [--offline] [--process <name>] [--diff removeTable:<name>]",
|
|
126
126
|
flags: [
|
|
@@ -154,7 +154,7 @@ var a = () => {
|
|
|
154
154
|
name: "webhooks",
|
|
155
155
|
summary: "Outbound-webhook artefacts. `consumer` generates the ZERO-DEPENDENCY Standard-Webhooks verification package a subscriber installs, from this app's own declared events; `events` lists the events a subscriber can register for. Usage: voltro webhooks <consumer|events> [path] [--out <dir>] [--name <pkg>] [--json].",
|
|
156
156
|
status: "wired",
|
|
157
|
-
run: (e) => import("./webhooksCommand-
|
|
157
|
+
run: (e) => import("./webhooksCommand-di1CJVzu.js").then((t) => t.runWebhooksCommand(e)),
|
|
158
158
|
help: {
|
|
159
159
|
usage: "<consumer|events> [path] [--out <dir>] [--name <pkg>] [--json]",
|
|
160
160
|
flags: [
|
|
@@ -170,7 +170,7 @@ var a = () => {
|
|
|
170
170
|
name: "evolve",
|
|
171
171
|
summary: "Schema-evolution copilot: propose an observed-graph-driven codemod + a branch-verified backfill for a schema change (rename/retype/split/drop a column, rename a table). Dry-run by default; --write applies. Usage: voltro evolve rename-column <table>.<col> --to <newName> [--write] [--json].",
|
|
172
172
|
status: "wired",
|
|
173
|
-
run: (e) => import("./evolveCommand-
|
|
173
|
+
run: (e) => import("./evolveCommand-iU35TPjT.js").then((t) => t.runEvolveCommand(e)),
|
|
174
174
|
help: {
|
|
175
175
|
usage: "<rename-column|rename-table|retype-column|split-column|drop-column> <target> [--to <new>] [--write]",
|
|
176
176
|
flags: [
|
|
@@ -187,7 +187,7 @@ var a = () => {
|
|
|
187
187
|
name: "codegen",
|
|
188
188
|
summary: "Emit rpcGroup.generated.ts from discovered route / mutation descriptors.",
|
|
189
189
|
status: "wired",
|
|
190
|
-
run: (e) => import("./codegenCommand-
|
|
190
|
+
run: (e) => import("./codegenCommand-DH-8ZXzR.js").then((t) => t.runCodegenCommand(e)),
|
|
191
191
|
help: {
|
|
192
192
|
usage: "[app]",
|
|
193
193
|
examples: [["voltro codegen", "regenerate rpcGroup.generated.ts for the app in the cwd"]],
|
|
@@ -258,7 +258,7 @@ var a = () => {
|
|
|
258
258
|
name: "info",
|
|
259
259
|
summary: "Report versions (CLI, node, every installed @voltro/* — flags lockstep skew), package manager, and dialect. --json for CI. Exits 1 on version skew.",
|
|
260
260
|
status: "wired",
|
|
261
|
-
run: (e) => import("./infoCommand-
|
|
261
|
+
run: (e) => import("./infoCommand-unqisJGp.js").then((t) => t.runInfoCommand(e)),
|
|
262
262
|
help: {
|
|
263
263
|
usage: "[--json]",
|
|
264
264
|
flags: [["--json", "machine-readable report"]],
|
|
@@ -279,7 +279,7 @@ var a = () => {
|
|
|
279
279
|
name: "env",
|
|
280
280
|
summary: "Inspect/sync the typed-env manifest. Subcommands: check (default), sync (.env.example), types (env.generated.d.ts for CI tsc), turbo.",
|
|
281
281
|
status: "wired",
|
|
282
|
-
run: (e) => import("./envCommand-
|
|
282
|
+
run: (e) => import("./envCommand-TZzcyqZ-.js").then((t) => t.runEnvCommand(e)),
|
|
283
283
|
help: {
|
|
284
284
|
usage: "[check|sync|types|turbo] [--force]",
|
|
285
285
|
flags: [["--force", "overwrite the generated file instead of refusing on a conflict"]],
|
|
@@ -308,12 +308,12 @@ var a = () => {
|
|
|
308
308
|
run: async (e) => {
|
|
309
309
|
let t = e.find((e) => !e.startsWith("-")) ?? process.cwd();
|
|
310
310
|
if (e.includes("--preflight")) {
|
|
311
|
-
let { runServePreflight: e } = await import("./doctorCommand-
|
|
311
|
+
let { runServePreflight: e } = await import("./doctorCommand-BYffQc0s.js");
|
|
312
312
|
return e(n(t), !0);
|
|
313
313
|
}
|
|
314
314
|
let { tryRunWebServe: r } = await import("./webDev-BcykISYQ2.js"), i = await r(n(t));
|
|
315
315
|
if (!i.ran) {
|
|
316
|
-
let { runServeDispatch: t } = await import("./serveCommand-
|
|
316
|
+
let { runServeDispatch: t } = await import("./serveCommand-CEBVP36A.js");
|
|
317
317
|
return t(e);
|
|
318
318
|
}
|
|
319
319
|
return i.exitCode;
|
|
@@ -341,13 +341,13 @@ var a = () => {
|
|
|
341
341
|
handlesHelp: !0,
|
|
342
342
|
summary: "Preflight an app for production: the precompiled serve bundle, hand-rolled primitives (naming the shipped one), @voltro/* version skew, executors with no access check, `.serverOnly()` leaks, and junction-FK gaps.",
|
|
343
343
|
status: "wired",
|
|
344
|
-
run: (e) => import("./doctorCommand-
|
|
344
|
+
run: (e) => import("./doctorCommand-BYffQc0s.js").then((t) => t.runDoctorCommand(e))
|
|
345
345
|
},
|
|
346
346
|
{
|
|
347
347
|
name: "build",
|
|
348
348
|
summary: "Production build for a web app (vite build + per-page SSG pre-render).",
|
|
349
349
|
status: "wired",
|
|
350
|
-
run: (e) => import("./build-
|
|
350
|
+
run: (e) => import("./build-DBe6c7qC.js").then((t) => t.runBuildCommand(e)),
|
|
351
351
|
help: {
|
|
352
352
|
usage: "[app] [--target <t>]",
|
|
353
353
|
flags: [["--target <t>", "build target"]],
|
|
@@ -363,7 +363,7 @@ var a = () => {
|
|
|
363
363
|
name: "prune-runtime",
|
|
364
364
|
summary: "Trim a deployed web tree’s node_modules to the reachable runtime set (standalone image slimming).",
|
|
365
365
|
status: "wired",
|
|
366
|
-
run: (e) => import("./runtimeTrace-
|
|
366
|
+
run: (e) => import("./runtimeTrace-D5LJ_N55.js").then((t) => t.runPruneRuntimeCommand(e)),
|
|
367
367
|
hidden: !0
|
|
368
368
|
},
|
|
369
369
|
{
|
|
@@ -381,7 +381,7 @@ var a = () => {
|
|
|
381
381
|
name: "dormancy",
|
|
382
382
|
summary: "Single-node scale-to-zero: front the API with a wake-orchestrator that stops the app when idle and brings it back on a request or a due wakeup (cron/workflow). Needs a SQL store. Flags: --port, --app-port, --idle-grace-ms, --tick-ms.",
|
|
383
383
|
status: "wired",
|
|
384
|
-
run: (e) => import("./dormancyCommand-
|
|
384
|
+
run: (e) => import("./dormancyCommand-6F6NsJKf.js").then((t) => t.runDormancyCommand(e)),
|
|
385
385
|
help: {
|
|
386
386
|
usage: "[app] [--port <n>] [--app-port <n>] [--idle-grace-ms <n>] [--tick-ms <n>]",
|
|
387
387
|
flags: [
|
|
@@ -468,7 +468,7 @@ var a = () => {
|
|
|
468
468
|
name: "data",
|
|
469
469
|
summary: "Export/import + backup/restore of app data. Logical (rows + optional assets): export <dir> [--tenant <id>|--tables a,b] [--assets] [--compression zstd|gzip|none] [--consistency live|snapshot]; import <dir> [--assets] [--no-verify]. Native (rows ONLY — no blobs): backup <dir> / restore <dir> (pg_dump/mariadb-dump/…). Resumable; typed-NDJSON; content-addressed assets on the logical path.",
|
|
470
470
|
status: "wired",
|
|
471
|
-
run: (e) => import("./dataCommand-
|
|
471
|
+
run: (e) => import("./dataCommand-DnCm0B2C.js").then((t) => t.runDataCommand(e)),
|
|
472
472
|
help: {
|
|
473
473
|
usage: "<export|import|backup|restore> <dir> [options]",
|
|
474
474
|
flags: [
|
|
@@ -523,20 +523,20 @@ var a = () => {
|
|
|
523
523
|
handlesHelp: !0,
|
|
524
524
|
summary: "Upgrade the app to the latest framework: bump every @voltro/* dependency (across ALL workspace members, install once at the workspace root), then run the codemods shipped with the target version. Flags: --to <version>, --from <version>, --codemods-only, --dry-run, --force, --exact, --help. After: run `voltro db apply`.",
|
|
525
525
|
status: "wired",
|
|
526
|
-
run: (e) => import("./updateCommand-
|
|
526
|
+
run: (e) => import("./updateCommand-CSBXVsYq.js").then((t) => t.runUpdateCommand(e))
|
|
527
527
|
},
|
|
528
528
|
{
|
|
529
529
|
name: "_apply-codemods",
|
|
530
530
|
summary: "Internal: apply shipped codemods for a framework version jump (re-exec target of `voltro update`).",
|
|
531
531
|
status: "wired",
|
|
532
532
|
hidden: !0,
|
|
533
|
-
run: (e) => import("./updateCommand-
|
|
533
|
+
run: (e) => import("./updateCommand-CSBXVsYq.js").then((t) => t.runApplyCodemods(e))
|
|
534
534
|
},
|
|
535
535
|
{
|
|
536
536
|
name: "embeddings",
|
|
537
537
|
summary: "Embeddings tooling. Subcommand: backfill <table> --text <field> --vector <field> [--model <m>] [--model-field <f>] [--batch <n>] [--dry-run] — (re)embed rows the vectorEmbedding() mixin missed.",
|
|
538
538
|
status: "wired",
|
|
539
|
-
run: (e) => import("./embeddingsCommand-
|
|
539
|
+
run: (e) => import("./embeddingsCommand-DRRdneJD.js").then((t) => t.runEmbeddingsCommand(e)),
|
|
540
540
|
help: {
|
|
541
541
|
usage: "backfill <table> --text <field> --vector <field> [--model <m>] [--batch <n>] [--dry-run]",
|
|
542
542
|
flags: [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./cliError-BmdYnghb.js";
|
|
2
|
-
import { c as t, i as n, o as r } from "./dev-
|
|
2
|
+
import { c as t, i as n, o as r } from "./dev-Dc4cpmRl.js";
|
|
3
3
|
import { n as i, t as a } from "./cliArgs-D4p8n7EE.js";
|
|
4
4
|
import { r as o } from "./dialectDriver-CgXnDfec.js";
|
|
5
5
|
import { t as s } from "./dataProfile-dW-PsfLB.js";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { c as e, d as t, f as n, i as r, u as i } from "./dev-
|
|
1
|
+
import { c as e, d as t, f as n, i as r, u as i } from "./dev-Dc4cpmRl.js";
|
|
2
2
|
import "./dialectDriver-CgXnDfec.js";
|
|
3
3
|
export { r as buildStore, e as loadApiConfig, i as loadDiscovered, t as runDev, n as walk };
|