@voltro/cli 0.48.0 → 0.50.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 +125 -0
- package/dist/apiBuild-BWo8KI6n.js +2 -0
- package/dist/{apiBuild-Dz8TJSxp.js → apiBuild-CFYXo06U.js} +1 -1
- package/dist/bin.js +1 -1
- package/dist/{build-DLme2ppa.js → build-CnSH-zru.js} +6 -6
- package/dist/{checkCommand-Dals7g-I.js → checkCommand-Do3SQbLx.js} +3 -3
- package/dist/{checkCommand-BUBqPBlI.js → checkCommand-OL41BMIb.js} +1 -1
- package/dist/{codegenCommand-L6vacVRW.js → codegenCommand-BJzaRz6q.js} +39 -47
- package/dist/{codemodRunner-DSZjgyCL.js → codemodRunner-De3k0pRd.js} +859 -629
- package/dist/{commands-CAxFLqG4.js → commands-By23Ljny.js} +68 -60
- package/dist/{dashboardCommand-CJC8Kg-s.js → dashboardCommand-DN1rAABE.js} +1 -1
- package/dist/dataCommand-B93TUBIx.js +1306 -0
- package/dist/dataProfile-Du3ztYxv.js +51 -0
- package/dist/{dbCommand-ZGNItjoJ.js → dbCommand-Bf7Cy0mn.js} +2 -2
- package/dist/dbCommand-Bnl7MSGC.js +2 -0
- package/dist/{dev-lvnVq5RD.js → dev-1yu42ubu.js} +2 -2
- package/dist/{dev-cGGsLNn6.js → dev-BWwE0QjK.js} +1 -1
- package/dist/doctorCommand-BmovAwb7.js +2 -0
- package/dist/{doctorCommand-BK0qu7eD.js → doctorCommand-y-EbP8st.js} +12 -12
- package/dist/{dormancyCommand-CyIk-zq4.js → dormancyCommand-Dc7KRNCG.js} +1 -1
- package/dist/{embeddingsCommand-D7TLklps.js → embeddingsCommand-kPs132bB.js} +1 -1
- package/dist/{envCommand-BHxKkGXq.js → envCommand-E12zSt51.js} +1 -1
- package/dist/{evolveCommand-CQh6dw21.js → evolveCommand-B3nagPVc.js} +2 -2
- package/dist/{frameworkTableAssembly-BNod_DKN.js → frameworkTableAssembly-BwJVEKLr.js} +3 -3
- package/dist/frameworkTableAssembly-CVDB2hCq.js +2 -0
- package/dist/index.js +1 -1
- package/dist/{infoCommand-CuNl9cbh.js → infoCommand-Cq0Yz98u.js} +1 -1
- package/dist/{interruptedReplace-C1ZI84xi.js → interruptedReplace-C3O3M1MM.js} +2 -1
- package/dist/interruptedReplace-CvmiAM9K.js +2 -0
- package/dist/{migrate-CL5Ed01M.js → migrate-D3MK9BpK.js} +2 -2
- package/dist/{runtimeTrace-C0SlIoQY.js → runtimeTrace-BpLUcrfy.js} +1 -1
- package/dist/{sdkgen-BXm7zx7F.js → sdkgen-dl4-WKF6.js} +1 -1
- package/dist/serveCommand-8CTzQCY0.js +2362 -0
- package/dist/serveCommand-C_WI4TTG.js +2 -0
- package/dist/serveEntry.js +5 -5
- package/dist/{subcommandNames-CKG5Dz3a.js → subcommandNames-DpYs3DXr.js} +12 -2
- package/dist/updateCommand-D91-TZ7E.js +2 -0
- package/dist/{updateCommand-BlyXavoG.js → updateCommand-i8JbrLAA.js} +2 -1
- package/dist/{webhooksCommand-QlAk_tED.js → webhooksCommand-B0bdyuQ4.js} +1 -1
- package/package.json +47 -17
- package/templates/AGENTS.md +1 -1
- package/templates/agent-docs/_index.md +1 -1
- package/templates/agent-docs/cli.md +124 -16
- package/templates/agent-docs/whats-new.md +30 -52
- 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 +4 -4
- package/dist/apiBuild-DOnvi2zm.js +0 -2
- package/dist/dataCommand-hIaq2iKY.js +0 -1052
- package/dist/dataProfile-Cm0YVKSy.js +0 -18
- package/dist/dbCommand-D1Q33ktl.js +0 -2
- package/dist/doctorCommand-CWgUPye-.js +0 -2
- package/dist/frameworkTableAssembly-Rft-DPUg.js +0 -2
- package/dist/interruptedReplace-DNJ7MKph.js +0 -2
- package/dist/serveCommand-CV3YO9L3.js +0 -2035
- package/dist/serveCommand-ZP_Cb-yz.js +0 -2
- package/dist/updateCommand-CT5AvVg7.js +0 -2
package/dist/serveEntry.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as e } from "./
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
export {
|
|
1
|
+
import { t as e } from "./serveCommand-8CTzQCY0.js";
|
|
2
|
+
import { t } from "./loadEnv-D9nEOClM.js";
|
|
3
|
+
import { r as n } from "./appModuleLoader-C9r9mxZt.js";
|
|
4
|
+
import { i as r } from "./dialectDriver-czCHYpeH.js";
|
|
5
|
+
export { t as loadDotEnv, n as registerAppModules, r as registerDriver, e as runServe };
|
|
@@ -19,9 +19,19 @@ var e = [
|
|
|
19
19
|
"scan-credentials",
|
|
20
20
|
"encrypt-column"
|
|
21
21
|
], t = [
|
|
22
|
+
"export",
|
|
23
|
+
"import",
|
|
24
|
+
"transfers",
|
|
25
|
+
"inspect",
|
|
26
|
+
"unpack",
|
|
27
|
+
"backup",
|
|
28
|
+
"restore",
|
|
29
|
+
"clear-replace-marker",
|
|
30
|
+
"clear-staging"
|
|
31
|
+
], n = [
|
|
22
32
|
"scope",
|
|
23
33
|
"export",
|
|
24
34
|
"erase"
|
|
25
|
-
],
|
|
35
|
+
], r = (e) => `<${e.join("|")}>`;
|
|
26
36
|
//#endregion
|
|
27
|
-
export {
|
|
37
|
+
export { r as i, e as n, n as r, t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as e, r as t, t as n } from "./codemodRunner-
|
|
1
|
+
import { n as e, r as t, t as n } from "./codemodRunner-De3k0pRd.js";
|
|
2
2
|
import { basename as r, dirname as i, join as a, relative as o, resolve as s } from "node:path";
|
|
3
3
|
import { existsSync as c, readFileSync as l, readdirSync as u, statSync as d, writeFileSync as f } from "node:fs";
|
|
4
4
|
import { totalmem as p } from "node:os";
|
|
@@ -579,6 +579,7 @@ with \`--only\` / \`--root\`.`;
|
|
|
579
579
|
for (let e of r.manual) {
|
|
580
580
|
console.log(`\n▸ ${e.id} — ${e.title}`);
|
|
581
581
|
for (let t of e.note.split("\n")) console.log(` ${t}`);
|
|
582
|
+
e.certain || (console.log(""), console.log(" ── nothing in this repository matched. That is NOT a clean bill of health:"), console.log(" `voltro update` reads the files git tracks here, and a CLI call also lives"), console.log(" in places it cannot reach — an inline script in a CI runner, a CronJob"), console.log(" spec in another repo, a runbook, a deploy job. Search those by hand."));
|
|
582
583
|
}
|
|
583
584
|
}
|
|
584
585
|
return n.dryRun && console.log("\n(dry-run — no files written)"), 0;
|
|
@@ -222,7 +222,7 @@ createVerifier({ secret: [process.env.WEBHOOK_SECRET, process.env.WEBHOOK_SECRET
|
|
|
222
222
|
...t === void 0 ? {} : { payload: t }
|
|
223
223
|
};
|
|
224
224
|
}, S = u({ scope: "voltro:webhooks" }), C = ["--out", "--name"], w = async (e) => {
|
|
225
|
-
let { walk: t, loadDiscovered: n } = await import("./dev-
|
|
225
|
+
let { walk: t, loadDiscovered: n } = await import("./dev-BWwE0QjK.js"), { outgoingFromEvents: r } = await import("./webhookDiscovery-il9ti-HE.js");
|
|
226
226
|
return r((await n(await t(e))).events.map((e) => ({
|
|
227
227
|
file: e.file,
|
|
228
228
|
descriptor: e.descriptor
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.50.0",
|
|
4
4
|
"description": "The `voltro` CLI — dev server, codegen, migrations, project scaffolding, agent-docs seeding, and production serve.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -652,6 +652,18 @@
|
|
|
652
652
|
"title": "an aggregate’s `incremental.source` is typechecked against the app’s tables",
|
|
653
653
|
"kind": "manual"
|
|
654
654
|
},
|
|
655
|
+
{
|
|
656
|
+
"version": "0.49.0",
|
|
657
|
+
"id": "0.49.0/01_data-imports-to-transfers",
|
|
658
|
+
"title": "`voltro data imports` → `voltro data transfers`",
|
|
659
|
+
"kind": "manual"
|
|
660
|
+
},
|
|
661
|
+
{
|
|
662
|
+
"version": "0.49.0",
|
|
663
|
+
"id": "0.49.0/02_import-run-symbols",
|
|
664
|
+
"title": "`ImportRun` / `describeImportRun` / `IMPORT_RUNS_TABLE` → their `…TransferRun` names",
|
|
665
|
+
"kind": "transform"
|
|
666
|
+
},
|
|
655
667
|
{
|
|
656
668
|
"version": "0.5.0",
|
|
657
669
|
"id": "0.5.0/01_one-terminal-exactly-one",
|
|
@@ -664,6 +676,24 @@
|
|
|
664
676
|
"title": "store.query() now returns the row type — casts on row fields may stop compiling",
|
|
665
677
|
"kind": "manual"
|
|
666
678
|
},
|
|
679
|
+
{
|
|
680
|
+
"version": "0.50.0",
|
|
681
|
+
"id": "0.50.0/01_transfer-runs-endpoint",
|
|
682
|
+
"title": "`GET /_voltro/admin/imports` → `GET /_voltro/admin/transfers`",
|
|
683
|
+
"kind": "manual"
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
"version": "0.50.0",
|
|
687
|
+
"id": "0.50.0/02_reissue-data-imports-rename",
|
|
688
|
+
"title": "RE-CHECK: `voltro data imports` → `voltro data transfers` (0.49.0's note could not see your scripts)",
|
|
689
|
+
"kind": "manual"
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
"version": "0.50.0",
|
|
693
|
+
"id": "0.50.0/03_interrupted-replace-tables-nullable",
|
|
694
|
+
"title": "`InterruptedReplace.tables` is `number | null`",
|
|
695
|
+
"kind": "manual"
|
|
696
|
+
},
|
|
667
697
|
{
|
|
668
698
|
"version": "0.6.0",
|
|
669
699
|
"id": "0.6.0/01_no-dev-session-secret",
|
|
@@ -739,22 +769,22 @@
|
|
|
739
769
|
"@effect/platform-node": "^0.108.0",
|
|
740
770
|
"@effect/sql": "^0.52.0",
|
|
741
771
|
"@effect/workflow": "^0.19.0",
|
|
742
|
-
"@voltro/ai": "0.
|
|
743
|
-
"@voltro/cache": "0.
|
|
744
|
-
"@voltro/data-transfer": "0.
|
|
745
|
-
"@voltro/database": "0.
|
|
746
|
-
"@voltro/env": "0.
|
|
747
|
-
"@voltro/kv": "0.
|
|
748
|
-
"@voltro/logger": "0.
|
|
749
|
-
"@voltro/plugin-auth": "0.
|
|
750
|
-
"@voltro/plugin-broadcast": "0.
|
|
751
|
-
"@voltro/plugin-mail": "0.
|
|
752
|
-
"@voltro/plugin-storage": "0.
|
|
753
|
-
"@voltro/plugin-webhooks": "0.
|
|
754
|
-
"@voltro/protocol": "0.
|
|
755
|
-
"@voltro/runtime": "0.
|
|
756
|
-
"@voltro/serverless": "0.
|
|
757
|
-
"@voltro/workflow": "0.
|
|
772
|
+
"@voltro/ai": "0.50.0",
|
|
773
|
+
"@voltro/cache": "0.50.0",
|
|
774
|
+
"@voltro/data-transfer": "0.50.0",
|
|
775
|
+
"@voltro/database": "0.50.0",
|
|
776
|
+
"@voltro/env": "0.50.0",
|
|
777
|
+
"@voltro/kv": "0.50.0",
|
|
778
|
+
"@voltro/logger": "0.50.0",
|
|
779
|
+
"@voltro/plugin-auth": "0.50.0",
|
|
780
|
+
"@voltro/plugin-broadcast": "0.50.0",
|
|
781
|
+
"@voltro/plugin-mail": "0.50.0",
|
|
782
|
+
"@voltro/plugin-storage": "0.50.0",
|
|
783
|
+
"@voltro/plugin-webhooks": "0.50.0",
|
|
784
|
+
"@voltro/protocol": "0.50.0",
|
|
785
|
+
"@voltro/runtime": "0.50.0",
|
|
786
|
+
"@voltro/serverless": "0.50.0",
|
|
787
|
+
"@voltro/workflow": "0.50.0",
|
|
758
788
|
"chokidar": "^5.0.0",
|
|
759
789
|
"ioredis": "^5.11.1",
|
|
760
790
|
"tinyglobby": "^0.2.17",
|
package/templates/AGENTS.md
CHANGED
|
@@ -707,7 +707,7 @@ each plugin's own README.
|
|
|
707
707
|
|
|
708
708
|
| Topic | Open | Summary |
|
|
709
709
|
|---|---|---|
|
|
710
|
-
| **What's new in 0.
|
|
710
|
+
| **What's new in 0.50.0** | `node_modules/@voltro/cli/templates/agent-docs/whats-new.md` | Everything that changed in this version. Read it before hand-rolling something the framework may now ship. |
|
|
711
711
|
| AI | `node_modules/@voltro/cli/templates/agent-docs/ai.md` | How Voltro treats AI — agents, tools, streaming, RAG — all primitives over the same WebSocket as the rest of the framework. |
|
|
712
712
|
| Authentication | `node_modules/@voltro/cli/templates/agent-docs/authentication.md` | How @voltro/plugin-auth wires password + session-cookie auth across api + web, plus the pluggable identity-strategy protocol. |
|
|
713
713
|
| Caching | `node_modules/@voltro/cli/templates/agent-docs/caching.md` | Voltro's caching layer (@voltro/cache) — an always-on memory default, swappable Redis-compatible backends, a low-level wrap primitive, and automatic query-result invalidation. |
|
|
@@ -9,7 +9,7 @@ each plugin's own README.
|
|
|
9
9
|
|
|
10
10
|
| Topic | Open | Summary |
|
|
11
11
|
|---|---|---|
|
|
12
|
-
| **What's new in 0.
|
|
12
|
+
| **What's new in 0.50.0** | `node_modules/@voltro/cli/templates/agent-docs/whats-new.md` | Everything that changed in this version. Read it before hand-rolling something the framework may now ship. |
|
|
13
13
|
| AI | `node_modules/@voltro/cli/templates/agent-docs/ai.md` | How Voltro treats AI — agents, tools, streaming, RAG — all primitives over the same WebSocket as the rest of the framework. |
|
|
14
14
|
| Authentication | `node_modules/@voltro/cli/templates/agent-docs/authentication.md` | How @voltro/plugin-auth wires password + session-cookie auth across api + web, plus the pluggable identity-strategy protocol. |
|
|
15
15
|
| Caching | `node_modules/@voltro/cli/templates/agent-docs/caching.md` | Voltro's caching layer (@voltro/cache) — an always-on memory default, swappable Redis-compatible backends, a low-level wrap primitive, and automatic query-result invalidation. |
|
|
@@ -2885,7 +2885,7 @@ recorder is for. Every suspended run says so, and the suspension is scoped to th
|
|
|
2885
2885
|
run rather than the process, so requests served alongside it keep recording.
|
|
2886
2886
|
|
|
2887
2887
|
Instead of per-row history, the operation records **itself**. One row in
|
|
2888
|
-
`
|
|
2888
|
+
`_voltro_data_transfers` per run — in either direction: the mode, the transport, the bundle, the source
|
|
2889
2889
|
deployment's schema fingerprint, the counts — and the failure, for the run you
|
|
2890
2890
|
are usually looking for. A trail that only records successes goes quiet exactly
|
|
2891
2891
|
when it is needed.
|
|
@@ -2895,9 +2895,57 @@ interlock and a run which cannot write it must not proceed, while this is
|
|
|
2895
2895
|
history. A target whose schema is not migrated yet still imports, and says the
|
|
2896
2896
|
trace could not be written.
|
|
2897
2897
|
|
|
2898
|
-
###
|
|
2898
|
+
### Every request fits a budget
|
|
2899
2899
|
|
|
2900
|
-
|
|
2900
|
+
Some environments cap a single request: a job runner that kills a client after
|
|
2901
|
+
ten minutes, an ingress with a 30-second ceiling, a CI step with a deadline. A
|
|
2902
|
+
whole transfer may still take an hour — it just has to do so as a series of short
|
|
2903
|
+
requests, each individually abandonable and individually retryable.
|
|
2904
|
+
|
|
2905
|
+
The rule the endpoints follow:
|
|
2906
|
+
|
|
2907
|
+
> **A request that carries bytes never runs a transfer. A request that starts a
|
|
2908
|
+
> transfer never carries bytes.**
|
|
2909
|
+
|
|
2910
|
+
```bash
|
|
2911
|
+
# Nothing here may take longer than 30 seconds per request.
|
|
2912
|
+
voltro data import ./bundle --target api --api-url https://app.example \
|
|
2913
|
+
--mode replace --max-request-seconds 30
|
|
2914
|
+
|
|
2915
|
+
# Or: start it and walk away. The outcome is NOT known when this returns.
|
|
2916
|
+
voltro data import ./bundle --target api --api-url https://app.example --detach
|
|
2917
|
+
```
|
|
2918
|
+
|
|
2919
|
+
Both staging areas — the uploaded bundle on its way in, the produced one on its
|
|
2920
|
+
way out — sit in the system temp directory by default and move with
|
|
2921
|
+
`VOLTRO_IMPORT_UPLOAD_DIR` / `VOLTRO_EXPORT_ARTIFACT_DIR`. Worth setting on a
|
|
2922
|
+
container: a bundle is the size your database is, and a default `/tmp` is
|
|
2923
|
+
frequently a small tmpfs.
|
|
2924
|
+
|
|
2925
|
+
`--max-request-seconds` is DECLARED rather than probed. The thing that kills a
|
|
2926
|
+
request is a policy on your side, and only you know it — in the one environment
|
|
2927
|
+
this was measured against, the ingress would happily hold a connection for an
|
|
2928
|
+
hour and the caller's own toolchain killed the client at ten minutes.
|
|
2929
|
+
|
|
2930
|
+
**An import is three steps.** The bundle goes up (in 16 MiB chunks when it is
|
|
2931
|
+
big, resumable, one plain request when it is small); `import/start` begins the
|
|
2932
|
+
run and answers as soon as the run is recorded; then the client watches the
|
|
2933
|
+
record. `start` is idempotent — retrying it under a budget returns the run that
|
|
2934
|
+
is already going rather than beginning a second destructive one.
|
|
2935
|
+
|
|
2936
|
+
**An export is three steps too.** Ask, wait for the record, then fetch the bytes
|
|
2937
|
+
in ranges from `GET /_voltro/admin/export/download`. The archive used to arrive
|
|
2938
|
+
in the response body, which made the request last as long as reading your whole
|
|
2939
|
+
database.
|
|
2940
|
+
|
|
2941
|
+
**`--detach` returns once the run has started** and says so plainly: exit `0`
|
|
2942
|
+
there means "it started", not "it worked". Attached, the exit code comes from the
|
|
2943
|
+
run's record — `0` finished, `1` failed, `2` still going when you stopped
|
|
2944
|
+
watching. Ctrl-C loses the watching and never the run.
|
|
2945
|
+
|
|
2946
|
+
### Watching a transfer you cannot see
|
|
2947
|
+
|
|
2948
|
+
Over `--target api` the run happens INSIDE the instance. Everything it decides
|
|
2901
2949
|
— whether it stages, whether recorders are suspended, how far it has got — is
|
|
2902
2950
|
printed in the pod's log, and someone reaching for `--target api` is by
|
|
2903
2951
|
construction someone who cannot reach the database directly and usually cannot
|
|
@@ -2906,9 +2954,12 @@ killing the client does not stop it, which is what keeps a dead client from
|
|
|
2906
2954
|
leaving a half-emptied target. Both properties are right, and together they used
|
|
2907
2955
|
to mean an operator could neither see the run nor learn how it ended.
|
|
2908
2956
|
|
|
2909
|
-
Two things close that, and neither is a streamed response
|
|
2910
|
-
|
|
2911
|
-
|
|
2957
|
+
Two things close that, and neither is a streamed response on the upload
|
|
2958
|
+
connection. That connection is the thing an operator is most likely to lose: a
|
|
2959
|
+
client killed by a job timeout while the import runs on inside the instance is
|
|
2960
|
+
the ordinary case, and a stream would go quiet at exactly the moment somebody
|
|
2961
|
+
needs to know what happened. A poll can be run from a different machine than
|
|
2962
|
+
the one that started the import.
|
|
2912
2963
|
|
|
2913
2964
|
**Ask before you upload.** A `replace` over the api asks the instance what it is
|
|
2914
2965
|
going to do, before a byte of the bundle goes up. The instance answers from the
|
|
@@ -2918,7 +2969,8 @@ same function the run itself calls, so the answer cannot drift from the run:
|
|
|
2918
2969
|
$ voltro data import ./bundle --target api --api-url https://app.example --mode replace
|
|
2919
2970
|
api replace: the instance WILL stage — 104 table(s) load into copies and the
|
|
2920
2971
|
target keeps its rows until one short swap at the end. Interrupting the load leaves the target intact.
|
|
2921
|
-
|
|
2972
|
+
importing — 41200 row(s) across 18 table(s) (staged; the target still holds its own rows)
|
|
2973
|
+
done — 228866 row(s) across 104 table(s)
|
|
2922
2974
|
```
|
|
2923
2975
|
|
|
2924
2976
|
With `--bundle-key` the client never holds the bundle, so it sends the key and
|
|
@@ -2932,22 +2984,28 @@ That is the difference between "interrupting this is safe" and "interrupting
|
|
|
2932
2984
|
this empties the target", which is exactly the decision an operator is making
|
|
2933
2985
|
while they watch.
|
|
2934
2986
|
|
|
2935
|
-
**Read the run from anywhere.** `
|
|
2936
|
-
first table, advanced every couple of
|
|
2937
|
-
outcome — so polling it IS the progress
|
|
2987
|
+
**Read the run from anywhere.** `_voltro_data_transfers` carries one row per run
|
|
2988
|
+
in EITHER direction: opened before the first table, advanced every couple of
|
|
2989
|
+
seconds as tables land, closed with the outcome — so polling it IS the progress
|
|
2990
|
+
feed:
|
|
2938
2991
|
|
|
2939
2992
|
```
|
|
2940
|
-
$ voltro data
|
|
2993
|
+
$ voltro data transfers --target api --api-url https://app.example
|
|
2941
2994
|
1 import(s) IN FLIGHT — re-run this to watch the counters move
|
|
2942
|
-
2026-08-
|
|
2943
|
-
2026-08-
|
|
2995
|
+
2026-08-23T09:04:01.000Z · replace — started and never reported finishing · via api · staged (target untouched until the swap) · from /tmp/b
|
|
2996
|
+
2026-08-23T08:00:00.000Z · export all — 228866 row(s) across 104 table(s) · via api · from backups/nightly.vbundle
|
|
2944
2997
|
```
|
|
2945
2998
|
|
|
2946
|
-
Same data over `GET /_voltro/admin/
|
|
2999
|
+
Same data over `GET /_voltro/admin/transfers?limit=20`, behind the same
|
|
2947
3000
|
data-transfer secret (the row names bundles and schema fingerprints). It works
|
|
2948
3001
|
from a different machine than the one that started the import, and through
|
|
2949
3002
|
anything that forwards a GET.
|
|
2950
3003
|
|
|
3004
|
+
The `staged` part is a separate claim from the preflight's, and both are needed.
|
|
3005
|
+
The preflight says what the instance WILL do; this says what it did. Without it
|
|
3006
|
+
the two could only be closed by reading the pod's log, which is the one place a
|
|
3007
|
+
`--target api` caller cannot reach.
|
|
3008
|
+
|
|
2951
3009
|
### An interrupted `replace` cannot be silent
|
|
2952
3010
|
|
|
2953
3011
|
The capture only helps if somebody knows to reach for it. A half-replaced database is indistinguishable from an empty one **from the inside** — every table exists, every constraint holds, every query returns nothing without erroring — so a run that emptied a target and disappeared can be served over for hours before anyone asks the right question.
|
|
@@ -3272,12 +3330,62 @@ yield* runImport({ store: target, bundleDir: './backup', targetSnapshot }).pipe(
|
|
|
3272
3330
|
## Native backup / restore
|
|
3273
3331
|
|
|
3274
3332
|
```bash
|
|
3275
|
-
voltro data backup ./backups/2026-07-01
|
|
3276
|
-
voltro data
|
|
3333
|
+
voltro data backup ./backups/2026-07-01 # pg_dump --format=custom / mariadb-dump --single-transaction / …
|
|
3334
|
+
voltro data backup ./backups/2026-07-01 --assets # rows AND the stored blobs
|
|
3335
|
+
voltro data restore ./backups/2026-07-01 --assets # pg_restore / mariadb / … + the blobs
|
|
3277
3336
|
```
|
|
3278
3337
|
|
|
3279
3338
|
These shell out to the vendor tools resolved from your `DB_DIALECT` + connection env. They produce a dialect-native artifact (`db.dump`, `db.sql`, `db.sqlite`, `db.bacpac`) that is lossless and point-in-time consistent for **same-dialect** restore — the right tool for disaster recovery. Secrets are passed via the tools' environment variables (`PGPASSWORD`, `MYSQL_PWD`), never on the command line, where the tool supports it. The named tool must be installed and on `PATH`.
|
|
3280
3339
|
|
|
3340
|
+
### `--assets` — the blobs are not in the dump
|
|
3341
|
+
|
|
3342
|
+
A vendor dump contains rows. Your blobs are in object storage, and no `pg_dump` has ever seen them. So a rows-only backup restores a database whose rows reference objects that are not there — and the reference and the object are checked at different times, which is why that state is discovered by a user, months later, rather than by the restore.
|
|
3343
|
+
|
|
3344
|
+
`--assets` captures them alongside the dump, through the same content-addressed pipeline `voltro data export --assets` uses: each blob is streamed (never buffered whole), stored under `assets/<sha256>` so identical content is stored once, and listed in `assets/index.ndjson`. `restore --assets` streams them back and **re-hashes on the way**, so a corrupted artifact can never silently overwrite good bytes.
|
|
3345
|
+
|
|
3346
|
+
```
|
|
3347
|
+
backups/2026-07-01/
|
|
3348
|
+
├─ db.dump # the vendor artifact (rows)
|
|
3349
|
+
├─ voltro-backup-stamp.json # provenance, incl. what --assets captured
|
|
3350
|
+
├─ assets/index.ndjson # key → sha256 → size → contentType
|
|
3351
|
+
└─ assets/<sha256> # the blob bodies, deduped by content
|
|
3352
|
+
```
|
|
3353
|
+
|
|
3354
|
+
Three refusals, each for a belief that is otherwise acted on silently:
|
|
3355
|
+
|
|
3356
|
+
- **`backup --assets` with no storage provider configured → refused.** There is nothing to capture, and a flag that is accepted and ignored lets you build a rollback story on an artifact that does not contain what you asked for.
|
|
3357
|
+
- **`restore --assets` on a rows-only backup → refused.** You believe the blobs are in there. Restoring the rows anyway produces exactly the dangling state this exists to prevent.
|
|
3358
|
+
- **restore *without* `--assets` on a backup that HAS them → warned, not refused.** Restoring rows without blobs is legitimate (a schema drill, a lower environment), and refusing it would push people at `--force`.
|
|
3359
|
+
|
|
3360
|
+
Resume is per blob key, so re-running a `--assets` capture that was interrupted transfers only what is missing. The **dump itself has no resume** — a vendor artifact is one opaque file with no offset to restart from. If you need a resumable, chunkable, observable transfer, that is the logical path (`export` / `import`), and it is why the logical path exists.
|
|
3361
|
+
|
|
3362
|
+
### A restore that is interrupted refuses the next boot
|
|
3363
|
+
|
|
3364
|
+
`restore` writes one row into `_voltro_replace_in_progress` **before** the first destructive statement and removes it **after** the last write — the blobs included. Its presence at boot is a refusal naming the artifact that was going in.
|
|
3365
|
+
|
|
3366
|
+
This is the counterpart to `--allow-live`, and it guards from the other side: `--allow-live` asks you not to restore over a running instance, and this says *this database is mid-restore, do not serve it*. A half-restored database looks exactly like a normal one from the inside — every query answers, nothing errors.
|
|
3367
|
+
|
|
3368
|
+
Whether the marker survives the restore depends on the dialect's restore shape, and that is stated rather than implied:
|
|
3369
|
+
|
|
3370
|
+
| dialect | shape | effect |
|
|
3371
|
+
|---|---|---|
|
|
3372
|
+
| postgres, mysql, mariadb | drops only the objects the dump names | the marker survives, so a killed restore is caught at the next boot |
|
|
3373
|
+
| sqlite, turso | whole-file replacement — made **atomic** (temp file + rename) | there is no half-restored state to catch; a killed restore leaves the live file untouched |
|
|
3374
|
+
| mssql | `sqlpackage /Action:Import` replaces the database | a *failed* import is the one case not covered here — verify with `--drill` |
|
|
3375
|
+
|
|
3376
|
+
Clear a marker deliberately with `voltro data clear-replace-marker --yes` once you have decided the current state is correct.
|
|
3377
|
+
|
|
3378
|
+
### Both directions are in the history
|
|
3379
|
+
|
|
3380
|
+
`backup` and `restore` write a row to the same `_voltro_data_transfers` record `import` and `export` use, so `voltro data transfers` answers "did last night's backup finish" from the instance that ran it:
|
|
3381
|
+
|
|
3382
|
+
```
|
|
3383
|
+
2026-08-23T02:00:00.000Z · backup native postgres + assets — finished (412 blob(s)) · via cli · from ./backups/2026-08-23/db.dump
|
|
3384
|
+
2026-08-22T09:14:02.000Z · FAILED restore native mariadb — mariadb-dump: exited with code 2 · via cli · from ./backups/2026-08-21/db.sql
|
|
3385
|
+
```
|
|
3386
|
+
|
|
3387
|
+
A native run reports **blobs**, not rows: the vendor tool reports no row count we can trust, and printing `0 row(s)` over a `pg_dump` that worked would be a measurement, and a wrong one. A target with no `_voltro_data_transfers` table still gets its backup — the closing line says it was not recorded, rather than implying it was.
|
|
3388
|
+
|
|
3281
3389
|
### The provenance stamp — a restore that refuses the wrong DB
|
|
3282
3390
|
|
|
3283
3391
|
A native dump is opaque: it doesn't say which dialect made it, which schema shape it carries, or when. `backup` writes a sidecar `voltro-backup-stamp.json` next to the artifact recording exactly that — `dialect`, the live schema `fingerprint`, the `@voltro/cli` version, and the timestamp.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# What's new in 0.
|
|
1
|
+
# What's new in 0.50.0
|
|
2
2
|
|
|
3
3
|
Read this FIRST when a task touches an area you have not worked in recently.
|
|
4
4
|
It is the cheapest way to notice that the framework grew the thing you were
|
|
@@ -7,78 +7,56 @@ workaround for something that shipped two versions ago.
|
|
|
7
7
|
|
|
8
8
|
BREAKING entries name a codemod; run `voltro update` to apply it.
|
|
9
9
|
|
|
10
|
-
###
|
|
11
|
-
|
|
12
|
-
- **@voltro/cli, @voltro/data-transfer** — An import over `--target api` can be asked what it will do, and watched while it does it.
|
|
13
|
-
|
|
14
|
-
The transport's two correct properties combined into one blind spot: the run happens INSIDE the instance, so every line it produces goes to a pod log; and it is deliberately decoupled from the caller, so killing the client does not stop it (which is what keeps a dead client from leaving a half-emptied target). Someone reaching for `--target api` cannot reach the database directly and usually cannot read that log either, so "watch for the staging line" was advice they could not follow.
|
|
15
|
-
|
|
16
|
-
**A preflight, before a byte is uploaded.** A `replace` over the api now asks the instance whether it will stage, and prints the answer — including the reason when it will not. It answers from `decideStaging`, the same function the run itself calls, so the two cannot drift; a second copy of that decision would answer confidently and diverge on the next change. With `--bundle-key`, where the client never holds the bundle, it sends the key and the instance reads the table list out of the archive's own manifest — the caller about to have an instance empty its own database is the last one who should be told to check a log they cannot read.
|
|
17
|
-
|
|
18
|
-
**`voltro data imports`** (and `GET /_voltro/admin/imports`, behind the same data-transfer secret) reads the history and the run in flight. `_voltro_data_imports` was write-only; it is now opened before the first table, **advanced every couple of seconds as tables land**, and closed with the outcome — so polling it is the progress feed. Not a streamed response on the upload connection: a chunked body has to survive every proxy in between, and a buffering reverse proxy turns a progress feed into exactly the silence it was meant to replace.
|
|
19
|
-
|
|
20
|
-
**And a `replace` that does not stage now says why.** The staging set was an early `return []` three conditions deep, and the empty array met a `length > 0` further down and read as "do not stage". A bundle table the target does not have — the ordinary case for a development source against a production target — turned the non-destructive path off in silence. Every reason routes through one message now; the cycle case additionally used to be gated on `atomic`, so the mode where an interrupted run leaves the worst outcome was also the one that said the least.
|
|
21
|
-
|
|
22
|
-
### Changed
|
|
23
|
-
|
|
24
|
-
- **@voltro/cli** — The declared framework schema no longer depends on `NODE_ENV`.
|
|
10
|
+
### ⚠ BREAKING
|
|
25
11
|
|
|
26
|
-
|
|
12
|
+
- **@voltro/cli** — The read-only run-history endpoint moved:
|
|
27
13
|
|
|
28
|
-
|
|
14
|
+
GET /_voltro/admin/imports → GET /_voltro/admin/transfers
|
|
29
15
|
|
|
30
|
-
|
|
16
|
+
Same secret, same query parameters, same response shape. Only the path changed.
|
|
31
17
|
|
|
32
|
-
|
|
18
|
+
It answers for four directions now — import, export, native backup, native restore — and it named one of them. The subcommand and the table were renamed for exactly that reason in 0.49.0 and this path was left behind, which is worse than renaming none of them: a reader who follows a rename tries the matching path, gets a 404, and concludes the instance is too old.
|
|
33
19
|
|
|
34
|
-
`voltro
|
|
20
|
+
`voltro data transfers --target api` uses the new path for you. What needs a hand is anything calling it directly — a monitoring check, an uptime probe, a curl in a runbook, a dashboard datasource. The codemod is `manual` and declares `reach: 'beyond-source'`, so it prints whether or not the path is found in your repository.
|
|
21
|
+
- **@voltro/database, @voltro/voltro** — `InterruptedReplace.tables` is `number | null`, and the interface gains `kind?: 'replace' | 'restore'`.
|
|
35
22
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- **@voltro/cli, @voltro/data-transfer** — `voltro data export --exclude a,b` made the bundle BIGGER, and made it unusable for a `replace`.
|
|
39
|
-
|
|
40
|
-
It expanded into `{ kind: 'tables', tables: <everything else> }`, on the reasoning that a manifest should record what was exported rather than claim "everything". Right goal, wrong mechanism, and it cost two things at once. `all` is the only scope that filters out the tables which describe a deployment, so excluding two names silently added nine others back — the migration ledger among them, whose foreign row takes an environment down at the next boot. And `replace` refuses a named scope, so the honest way to leave a table out was also the way to make the bundle unusable for the mode it was being prepared for.
|
|
41
|
-
|
|
42
|
-
The exclusion is a FIELD of the `all` scope now: the filter still runs, the manifest still says "everything except these" (a different and truer claim than "these"), and `replace` accepts it while naming the tables it will therefore not touch. `--exclude` also works over `--target api` now — it no longer expands against a table list only the instance has, so the instance resolves it where that list already is.
|
|
23
|
+
`_voltro_replace_in_progress` records two destructive operations now — an import's `--mode replace` and a native `voltro data restore`. A restore replaces the whole database from an artefact, so "how many tables was this going to empty and refill" has no answer: not known up front, not meaningful after.
|
|
43
24
|
|
|
44
|
-
|
|
45
|
-
- **@voltro/sql-turso** — Opening a second pooled turso connection could fail instantly with `database is locked` — from inside the constructor, before a single query ran.
|
|
25
|
+
Writing `0` would have preserved the type and been worse. That number is rendered into the boot refusal, which is read under pressure, and it would have said `began emptying 0 table(s)` — a measurement that was never taken. The framework's own text says "this database" instead; `Number(null)` is `0`, so coercing it reintroduces exactly the sentence being avoided.
|
|
46
26
|
|
|
47
|
-
`
|
|
27
|
+
`DataTransferRun.direction` also widens to name `'backup'` and `'restore'` explicitly. That one is documentary — the union already ended in `| string`, so no assignability changes.
|
|
48
28
|
|
|
49
|
-
|
|
29
|
+
**`voltro update` carries you across this** — codemod `0.50.0/03_interrupted-replace-tables-nullable`.
|
|
50
30
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
**Why it hid for so long.** The file already carried a long, correct note about `busy_timeout` being mandatory with a pool, and a separate fix had closed the DDL half (`retryFilter` + bounded retries in `applySchema`). Both are about the same lock class, so the constructor read as covered — but a setting cannot protect the two pragmas that run before it.
|
|
54
|
-
|
|
55
|
-
It surfaces as an unrelated flaky test, because the failure lands wherever the second connection happens to be opened: a `CREATE TABLE` in one run, an MVCC pragma in the next. It cost three release gates — twice locally, once on a CI runner — and was twice diagnosed as machine contention and closed. It is contention-DEPENDENT, which is not the same as being the machine's fault.
|
|
31
|
+
### Added
|
|
56
32
|
|
|
57
|
-
|
|
58
|
-
- **@voltro/runtime, @voltro/data-transfer, @voltro/cli** — The `source:` recorder broke every WRITE on the in-memory store, and actions are recorded now.
|
|
33
|
+
- **@voltro/cli, @voltro/data-transfer, @voltro/database** — `voltro data backup --assets` and `voltro data restore --assets` now move the stored blobs alongside the vendor dump, through the same content-addressed phase the logical `export` / `import` path uses — streamed, deduped by sha256, verified on the way back, resumable per key.
|
|
59
34
|
|
|
60
|
-
|
|
35
|
+
`--assets` was accepted by `backup` and silently ignored, with the only signal a field in the closing JSON reading `NOT included`; `restore` did not accept it at all. A rows-only backup restores a database whose rows reference objects nothing puts back, and the reference and the object are checked at different times, so that state is discovered by a user rather than by the restore.
|
|
61
36
|
|
|
62
|
-
|
|
37
|
+
Three refusals, each for a belief that is otherwise acted on silently: `backup --assets` with no storage provider is refused rather than swallowed; `restore --assets` on a rows-only artefact is refused; a restore WITHOUT `--assets` over an artefact that has them warns and proceeds, because restoring rows without blobs is legitimate and refusing it would push people at `--force`.
|
|
63
38
|
|
|
64
|
-
|
|
39
|
+
The dump itself still has no resume — a vendor artefact is one opaque file with no offset to restart from, and the logical path is what exists for that.
|
|
40
|
+
- **@voltro/cli, @voltro/database, @voltro/data-transfer** — A native `backup` / `restore` now writes to the same `_voltro_data_transfers` record `import` and `export` use, so `voltro data transfers` answers "did last night's backup finish" from the instance that ran it. A native run reports blobs rather than rows — a vendor tool reports no row count we can trust, and printing `0 row(s)` over a dump that worked would be a wrong measurement.
|
|
65
41
|
|
|
66
|
-
|
|
42
|
+
`restore` also writes the `_voltro_replace_in_progress` marker before its first destructive statement and clears it after the last write, blobs included, so a killed restore refuses the next boot instead of serving a half-loaded database. `--allow-live` guards from the wrong side — it asks you not to — and this guards from the right one. The marker carries a `kind` so the refusal can say something different for a `replace` (re-import the capture) and a `restore` (finish the restore), and `tables` is nullable because a native restore has no table count to claim.
|
|
67
43
|
|
|
68
|
-
|
|
44
|
+
The sqlite / turso restore is atomic now (temp file + rename): its marker lives in the very file being replaced, so a plain in-place copy would leave a truncated database with nothing left to catch it.
|
|
69
45
|
|
|
70
|
-
|
|
46
|
+
A target with no `_voltro_data_transfers` table still gets its backup; the closing line says it was not recorded rather than implying it was.
|
|
47
|
+
- **@voltro/cli** — A re-issued migration note for the `voltro data imports` → `voltro data transfers` rename that shipped in 0.49.0.
|
|
71
48
|
|
|
72
|
-
|
|
49
|
+
Codemods are selected by `from < version <= to`, so the 0.49.0 note fires once, on the jump that crosses 0.49.0, and cannot be corrected for anyone already past it. Its gate searched `.ts` / `.tsx` while the command it is about lives in shell scripts, CI job definitions and runbooks — so a project whose only occurrence sat in `.gitlab-ci.yml` crossed 0.49.0 and was told there was nothing to apply.
|
|
73
50
|
|
|
74
|
-
|
|
51
|
+
The re-issue is filed under 0.50.0, prints unconditionally, and says what to grep for. Redundant for anyone already fixed; the alternative is firing for nobody.
|
|
75
52
|
|
|
76
|
-
|
|
53
|
+
### Fixed
|
|
77
54
|
|
|
78
|
-
|
|
55
|
+
- **@voltro/cli** — A `manual` codemod's `appliesTo` can now search every text file the project owns — `.sh`, `.yml`, `.json`, `.md`, `Makefile`, the `.js` scripts — through a new `ctx.text` on the predicate context, and a codemod may declare `reach: 'beyond-source'` to print its note even when nothing matched.
|
|
79
56
|
|
|
80
|
-
|
|
57
|
+
Both halves close the same gap, and it was in the codemod most in need of a gate. A manual codemod exists BECAUSE its subject could not be transformed, which usually means it is not source at all — and `appliesTo` was reading the ts-morph project, which holds `.ts` / `.tsx` and nothing else. Measured with one identical CLI invocation in four files: the `.ts` one printed the note, the `.sh`, `.yml` and `.md` ones printed nothing, and the run reported `codemods: nothing to apply for this jump`. That is an acquittal from a check that never looked at the file, and an acquittal gets acted on.
|
|
81
58
|
|
|
82
|
-
|
|
59
|
+
`reach: 'beyond-source'` covers what no scan of one repository can reach — an inline script in a CI runner's own UI, a CronJob spec in another repo, a wiki runbook. The note prints either way; only its framing changes, and an uncertain one says plainly that we could not look there.
|
|
60
|
+
- **@voltro/data-transfer** — When `mariadb-dump` is absent and the mysql-family fallback runs Oracle's `mysqldump` against a MariaDB server, the failure now names the way out.
|
|
83
61
|
|
|
84
|
-
|
|
62
|
+
The stderr it prints is the child's own words and is the right first thing to show — and on its own it is a dead end: `Unknown table 'COLUMN_STATISTICS' in information_schema (1109)` names a table nobody asked for, in a schema nobody wrote, about a feature nobody enabled. Everything needed to act on it was known where the fallback was DECIDED: which binary we wanted, which one we took, and why the difference matters. That travels with the step now and prints under the stderr, including the counter-move a reader reaches for on their own (`--column-statistics=0` does not exist on `mariadb-dump`, so it fixes the wrong client and breaks the right one).
|
|
@@ -12,16 +12,16 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@effect/platform": "^0.97.0",
|
|
14
14
|
"@effect/rpc": "^0.76.0",
|
|
15
|
-
"@voltro/ai": "0.
|
|
16
|
-
"@voltro/cli": "0.
|
|
17
|
-
"@voltro/database": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/protocol": "0.
|
|
20
|
-
"@voltro/runtime": "0.
|
|
15
|
+
"@voltro/ai": "0.50.0",
|
|
16
|
+
"@voltro/cli": "0.50.0",
|
|
17
|
+
"@voltro/database": "0.50.0",
|
|
18
|
+
"@voltro/env": "0.50.0",
|
|
19
|
+
"@voltro/protocol": "0.50.0",
|
|
20
|
+
"@voltro/runtime": "0.50.0",
|
|
21
21
|
"effect": "^3.22.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@voltro/testing": "0.
|
|
24
|
+
"@voltro/testing": "0.50.0",
|
|
25
25
|
"typescript": "^6.0.3",
|
|
26
26
|
"@vitest/coverage-v8": "^4.1.10",
|
|
27
27
|
"vitest": "^4.1.10"
|
|
@@ -13,17 +13,17 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@effect/platform": "^0.97.0",
|
|
15
15
|
"@effect/rpc": "^0.76.0",
|
|
16
|
-
"@voltro/cli": "0.
|
|
17
|
-
"@voltro/database": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/plugin-auth": "0.
|
|
20
|
-
"@voltro/protocol": "0.
|
|
21
|
-
"@voltro/runtime": "0.
|
|
22
|
-
"@voltro/sql-postgres": "0.
|
|
16
|
+
"@voltro/cli": "0.50.0",
|
|
17
|
+
"@voltro/database": "0.50.0",
|
|
18
|
+
"@voltro/env": "0.50.0",
|
|
19
|
+
"@voltro/plugin-auth": "0.50.0",
|
|
20
|
+
"@voltro/protocol": "0.50.0",
|
|
21
|
+
"@voltro/runtime": "0.50.0",
|
|
22
|
+
"@voltro/sql-postgres": "0.50.0",
|
|
23
23
|
"effect": "^3.22.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@voltro/testing": "0.
|
|
26
|
+
"@voltro/testing": "0.50.0",
|
|
27
27
|
"typescript": "^6.0.3",
|
|
28
28
|
"@vitest/coverage-v8": "^4.1.10",
|
|
29
29
|
"vitest": "^4.1.10"
|