@voltro/cli 0.44.0 → 0.44.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 +16 -0
- package/dist/bin.js +1 -1
- package/dist/{commands-fsnezHLH.js → commands-CYkHTox2.js} +1 -1
- package/dist/{dataCommand-sfpGV694.js → dataCommand-WFn8CM11.js} +5 -2
- package/dist/index.js +1 -1
- package/package.json +17 -17
- package/templates/AGENTS.md +1 -1
- package/templates/agent-docs/_index.md +1 -1
- package/templates/agent-docs/cli.md +23 -3
- package/templates/agent-docs/whats-new.md +6 -24
- 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/CHANGELOG.md
CHANGED
|
@@ -39,6 +39,22 @@ _Changes staged for the next release accumulate here (rolled up from
|
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
+
## [0.44.1] — 2026-08-19
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- **@voltro/database, @voltro/data-transfer, @voltro/cli** — A refused import row reported `(FiberFailure) SqlError: Failed to execute statement` — our runtime's rendering of a rejection, marker and stack frames and all — instead of the constraint that fired. It names neither a rule, nor a code, nor even which layer refused, and every row refused for the same cause carries it identically.
|
|
47
|
+
|
|
48
|
+
Two defects, and fixing either alone still leaves a reader stuck.
|
|
49
|
+
|
|
50
|
+
**`Cause.squash` elects a branch, and first is a position, not a ranking.** A `Cause` is a tree, and a transaction routinely produces one with more than one leaf: the statement that failed, and whatever the rollback or a finalizer did on the way out. When the first leaf was the bare wrapper, the driver error sitting in the sibling branch was never looked at. Measured: `sequential(bareSqlError, sqlErrorWithDriver)` classified as nothing while the same two branches in the opposite order classified as `unique constraint PRIMARY … [ER_DUP_ENTRY/1062]`. `extractDbCause` flattens failures AND defects now, in Cause order, expanding a nested `FiberFailure` leaf, and elects the branch that names a driver — the others' chains are appended rather than dropped.
|
|
51
|
+
|
|
52
|
+
**A row's reason may never read like a stack trace.** The runtime rendering is stripped before any tier looks at the text, so the failure mode cannot return invisibly. And when no driver detail is reachable at all, the reason now names the CHAIN of wrappers the failure passed through — the difference between "the database refused this row" and "the connection died mid-import" — while the run logs the full rendering of the first few such failures. Never returned over the wire: it carries frames, and on some engines a driver's sentence carries row data.
|
|
53
|
+
|
|
54
|
+
`RowsRefusedError` also gained `byTable`: **complete** per-table counts. `rows` is capped at 20, so per-table counts tallied off the printed list sum to the cap rather than to the failure — and nothing else in the payload offered any.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
42
58
|
## [0.44.0] — 2026-08-19
|
|
43
59
|
|
|
44
60
|
### ⚠ BREAKING
|
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-CYkHTox2.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";
|
|
@@ -469,7 +469,7 @@ var c = () => {
|
|
|
469
469
|
name: "data",
|
|
470
470
|
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.",
|
|
471
471
|
status: "wired",
|
|
472
|
-
run: (e) => import("./dataCommand-
|
|
472
|
+
run: (e) => import("./dataCommand-WFn8CM11.js").then((t) => t.runDataCommand(e)),
|
|
473
473
|
help: {
|
|
474
474
|
usage: "<export|import|backup|restore> <dir> [options]",
|
|
475
475
|
flags: [
|
|
@@ -553,9 +553,12 @@ var A = class extends Error {
|
|
|
553
553
|
if (t?._tag !== "RowsRefusedError" || !Array.isArray(t.rows)) return;
|
|
554
554
|
let n = t.rows, r = n.filter((e) => !e.derived), i = Number(t.totalCount ?? n.length), a = Number(t.primaryCount ?? r.length);
|
|
555
555
|
F.error(`import refused ${i} row(s), of which ${a} are the actual failures — the rest could not land because a row they reference did not.`);
|
|
556
|
+
let o = Array.isArray(t.byTable) ? t.byTable : [];
|
|
557
|
+
o.length > 1 && F.error(` by table: ${o.map((e) => `${e.table} ${e.refused}`).join(", ")}`);
|
|
556
558
|
for (let e of r) F.error(` ${e.table} ${e.id} ${e.reason}`);
|
|
557
|
-
|
|
558
|
-
|
|
559
|
+
n.length < i && F.error(` (the list above is capped at ${n.length} of ${i} — the counts by table are complete)`);
|
|
560
|
+
let s = i - a;
|
|
561
|
+
s > 0 && F.error(` … and ${s} row(s) behind them. Fix the ${a} above and re-run; they resolve with their parents.`);
|
|
559
562
|
}, Ue = async (e) => {
|
|
560
563
|
let t = z(e, "--target") === "api", n = z(e, "--bundle-key"), i = B(e);
|
|
561
564
|
if (!i && !(t && n)) return F.error("usage: voltro data import <bundleDir> [--target direct|api] [--api-url <url>] [--token <secret>] [--timeout <seconds>] [--bundle-key <storage-key>] [--tables a,b] [--mode upsert|append|replace] [--on-conflict skip|fail] [--atomic] [--assets] [--no-verify] [--force] [--allow-live] [--dry-run] (--force: import despite schema drift AND cross-dialect warnings; --dry-run: report what would move, write nothing)"), 1;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/cli",
|
|
3
|
-
"version": "0.44.
|
|
3
|
+
"version": "0.44.1",
|
|
4
4
|
"description": "The `voltro` CLI — dev server, codegen, migrations, project scaffolding, agent-docs seeding, and production serve.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -727,22 +727,22 @@
|
|
|
727
727
|
"@effect/platform-node": "^0.108.0",
|
|
728
728
|
"@effect/sql": "^0.52.0",
|
|
729
729
|
"@effect/workflow": "^0.19.0",
|
|
730
|
-
"@voltro/ai": "0.44.
|
|
731
|
-
"@voltro/cache": "0.44.
|
|
732
|
-
"@voltro/data-transfer": "0.44.
|
|
733
|
-
"@voltro/database": "0.44.
|
|
734
|
-
"@voltro/env": "0.44.
|
|
735
|
-
"@voltro/kv": "0.44.
|
|
736
|
-
"@voltro/logger": "0.44.
|
|
737
|
-
"@voltro/plugin-auth": "0.44.
|
|
738
|
-
"@voltro/plugin-broadcast": "0.44.
|
|
739
|
-
"@voltro/plugin-mail": "0.44.
|
|
740
|
-
"@voltro/plugin-storage": "0.44.
|
|
741
|
-
"@voltro/plugin-webhooks": "0.44.
|
|
742
|
-
"@voltro/protocol": "0.44.
|
|
743
|
-
"@voltro/runtime": "0.44.
|
|
744
|
-
"@voltro/serverless": "0.44.
|
|
745
|
-
"@voltro/workflow": "0.44.
|
|
730
|
+
"@voltro/ai": "0.44.1",
|
|
731
|
+
"@voltro/cache": "0.44.1",
|
|
732
|
+
"@voltro/data-transfer": "0.44.1",
|
|
733
|
+
"@voltro/database": "0.44.1",
|
|
734
|
+
"@voltro/env": "0.44.1",
|
|
735
|
+
"@voltro/kv": "0.44.1",
|
|
736
|
+
"@voltro/logger": "0.44.1",
|
|
737
|
+
"@voltro/plugin-auth": "0.44.1",
|
|
738
|
+
"@voltro/plugin-broadcast": "0.44.1",
|
|
739
|
+
"@voltro/plugin-mail": "0.44.1",
|
|
740
|
+
"@voltro/plugin-storage": "0.44.1",
|
|
741
|
+
"@voltro/plugin-webhooks": "0.44.1",
|
|
742
|
+
"@voltro/protocol": "0.44.1",
|
|
743
|
+
"@voltro/runtime": "0.44.1",
|
|
744
|
+
"@voltro/serverless": "0.44.1",
|
|
745
|
+
"@voltro/workflow": "0.44.1",
|
|
746
746
|
"chokidar": "^5.0.0",
|
|
747
747
|
"ioredis": "^5.11.1",
|
|
748
748
|
"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.44.
|
|
710
|
+
| **What's new in 0.44.1** | `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.44.
|
|
12
|
+
| **What's new in 0.44.1** | `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. |
|
|
@@ -2607,7 +2607,7 @@ Tenant-scope details:
|
|
|
2607
2607
|
|
|
2608
2608
|
- **A tenant scope without a tenant id refuses loudly** (`ScopeError`): pass `--tenant <id>` (CLI) or `scope.tenantId` (API/profile). It never falls back to an unfiltered export.
|
|
2609
2609
|
- **Which tables count as tenant-scoped** comes from the `tenant()` mixin metadata when the CLI / admin endpoint can read the declared schema (authoritative — a table can carry a `tenantId` column *without* being tenant-scoped, e.g. a global `users` table's active-org pointer). Without that metadata the exporter falls back to a documented heuristic: any table with a `tenantId` column.
|
|
2610
|
-
- A **cross-tenant reference** (a tenant-A row pointing at a tenant-B row) is never followed — the bundle stays tenant-clean and the reference dangles; importing such a bundle reports it loudly (`
|
|
2610
|
+
- A **cross-tenant reference** (a tenant-A row pointing at a tenant-B row) is never followed — the bundle stays tenant-clean and the reference dangles; importing such a bundle reports it loudly (`RowsRefusedError`) unless the target already has the row.
|
|
2611
2611
|
|
|
2612
2612
|
### Consistency: `live` vs `snapshot`
|
|
2613
2613
|
|
|
@@ -2745,7 +2745,27 @@ A row whose write fails on a foreign-key constraint — a forward reference from
|
|
|
2745
2745
|
2. **FK-shedding** — rows still stuck are written with their FK-bearing columns set to `NULL` (possible wherever those columns are nullable), which breaks row cycles on every dialect without session-level constraint toggles.
|
|
2746
2746
|
3. **Patch pass** — shed rows are re-written with the full bundle row, restoring the FK values.
|
|
2747
2747
|
|
|
2748
|
-
Anything still unresolvable — the parent row exists in **neither the bundle nor the target**,
|
|
2748
|
+
Anything still unresolvable — the parent row exists in **neither the bundle nor the target**, a `NOT NULL` FK cycle, or a row the target refuses for a reason of its own — fails with a typed `RowsRefusedError`. Held rows are the exception set, not the data set: memory is bounded by how many rows dangle at load time.
|
|
2749
|
+
|
|
2750
|
+
#### Reading a refusal
|
|
2751
|
+
|
|
2752
|
+
The error carries three things, and they answer different questions:
|
|
2753
|
+
|
|
2754
|
+
| Field | What it is |
|
|
2755
|
+
|---|---|
|
|
2756
|
+
| `totalCount` / `primaryCount` | how many rows were refused, and how many of those are the actual failures. A row is **derived** when one of its reference columns points at another row that also failed — it could not have landed whatever it contained, so it says nothing about itself. In an FK-dense bundle these dominate. |
|
|
2757
|
+
| `byTable` | **complete** per-table counts (`refused`, `primary`), worst first. |
|
|
2758
|
+
| `rows` | up to 20 refused rows — primary ones first — each with `table`, `id`, `reason`. |
|
|
2759
|
+
|
|
2760
|
+
`rows` is **capped and `byTable` is not**, and that distinction is worth one sentence: tallying the tables in the printed list answers "how big is the cap", not "which tables failed". The CLI prints the `byTable` line above the list and says so when the list is truncated.
|
|
2761
|
+
|
|
2762
|
+
A row's `reason` is stated as precisely as the driver allows, in three tiers:
|
|
2763
|
+
|
|
2764
|
+
1. **the rule, in your schema's vocabulary** — `unique constraint PRIMARY: a row with this value already exists [ER_DUP_ENTRY/1062]`, `foreign key teams_ibfk_1: the referenced row does not exist (import it first, or check the bundle's table order) [ER_NO_REFERENCED_ROW_2/1452]`. The driver's own code is appended, because that is what you grep a log for;
|
|
2765
|
+
2. **the driver's own message + code**, for anything it refused that is not one of the five integrity rules — `Data too long for column 'v' at row 1 [ER_DATA_TOO_LONG/1406]`;
|
|
2766
|
+
3. **that there was nothing**, when no driver detail is reachable at all: `the database refused the write and the driver gave no detail` — plus `(via …)`, the chain of wrappers, whenever that chain has more than one layer to name. Read this tier as "not a constraint": a guard, a row filter, or a failure whose words did not survive. When it fires, the run also **logs the full rendering** of the first three such rows (table, primary key, and the whole error as it rendered) and counts the rest. That log line is never returned over the wire — it carries our stack frames, and on some engines a driver's sentence carries row data — so on `--target api` you read it in the instance's log.
|
|
2767
|
+
|
|
2768
|
+
Unlike the rpc wire, this string DOES include the driver's own words. The audience is the difference: it is read only by whoever ran `voltro data import` — the holder of the data-transfer secret, who supplied the rows and can export the whole target anyway.
|
|
2749
2769
|
|
|
2750
2770
|
### Write modes (`--mode`)
|
|
2751
2771
|
|
|
@@ -2977,7 +2997,7 @@ yield* runImport({
|
|
|
2977
2997
|
|
|
2978
2998
|
Every pipeline failure is a **tagged error**, caught by tag with `Effect.catchTag(...)`. The errors that appear on the `runExport` / `runImport` error channels — the **wire errors**, and therefore exactly what the `--target api` admin endpoints surface — are `Schema.TaggedError`, so a handler can declare them on an rpc procedure's `error:` schema and the rpc encoder marshals them across the wire round-trip-safely (no hand-rolled JSON per tag):
|
|
2979
2999
|
|
|
2980
|
-
`BundleError`, `CodecError`, `IntegrityError`, `CrossDialectError`, `ImportModeError`, `
|
|
3000
|
+
`BundleError`, `CodecError`, `IntegrityError`, `CrossDialectError`, `ImportModeError`, `RowsRefusedError`, `SchemaDriftError`, `MaskingError`, `ScopeError`.
|
|
2981
3001
|
|
|
2982
3002
|
The two internal errors — `NativeToolError` (native `backup`/`restore`) and `CompressionError` (folded into `BundleError` by the pipelines) — never cross the wire, so they stay plain `Data.TaggedError`: still catchable by tag, just no Schema surface.
|
|
2983
3003
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# What's new in 0.44.
|
|
1
|
+
# What's new in 0.44.1
|
|
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,32 +7,14 @@ 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
|
-
### ⚠ BREAKING
|
|
11
|
-
|
|
12
|
-
- **@voltro/data-transfer, @voltro/cli** — `runImport` returns an `ImportOutcome` instead of the bundle's `Manifest`, and `--mode replace` runs as ONE transaction by default.
|
|
13
|
-
|
|
14
|
-
**Why the return type changed.** The summary line counted the rows the BUNDLE carries, not the rows the run wrote. Those differ most exactly where it matters: a bundle directory carries its own resume ledger, so a copied directory imports nothing — correctly, with a warning naming the file to delete — and the run then printed `import complete … rows: 242950` over a target it had not touched. The warning was one line above, which is one line too far for anyone piping the output through `tail -1`. The outcome carries `rowsWritten`, `rowsSkipped` and `fullyResumed`, the CLI reports written-vs-carried, and a fully-skipped run says so on its LAST line.
|
|
15
|
-
|
|
16
|
-
Migration: `runImport(...)` now resolves to `{ manifest, tablesWritten, rowsWritten, tablesSkipped, rowsSkipped, fullyResumed }`. Read `.manifest` where you read the manifest before.
|
|
17
|
-
|
|
18
|
-
**Why replace is atomic now.** The all-or-nothing guarantee was written for the emptying step, and read — reasonably — as covering the run. A replace that died partway through the LOAD left the target emptied of its old rows and holding part of the new ones, measured on a live instance over sixteen minutes. There is no useful state for a replace to stop in, so it is a default rather than a flag you have to know about. It also closes the window that produced that failure: with the tables emptied and the load uncommitted, a concurrent writer in the application waits instead of inserting a row the bundle is about to insert too.
|
|
19
|
-
|
|
20
|
-
`--no-atomic` (CLI) / `atomic: false` (API) opts out. The trade is stated where it bites: every write to those tables waits for the load, and on postgres the bulk `COPY` loader cannot join a transaction it does not own — an atomic run now says that once rather than being quietly slower.
|
|
21
|
-
|
|
22
|
-
Two smaller things from the same report: `--mode replace` against a running instance warns about the empty-target window when it is NOT atomic, and the `--target api` upload reports progress per chunk plus a line explaining that the final request stays open for the whole import — sixteen minutes of silence is indistinguishable from a hang, and one operator killed a run that had finished.
|
|
23
|
-
|
|
24
|
-
**`voltro update` carries you across this** — codemod `0.44.0/01_import-outcome`.
|
|
25
|
-
|
|
26
10
|
### Fixed
|
|
27
11
|
|
|
28
|
-
- **@voltro/
|
|
29
|
-
|
|
30
|
-
A recorder (a versioning trail, an audit log) runs on the caller's connection and is ALLOWED to fail — a recorder that throws must take the write down with it, that is its contract. Outside a caller transaction the two were not one unit: the row's statement committed on its own, and the recorder's INSERT ran afterwards as a second autocommit statement. So a recorder that threw left a COMMITTED row behind a write that reported failure. Measured directly: `insert` throws, the row is in the table, and a second attempt at the same row is `ER_DUP_ENTRY` on PRIMARY.
|
|
12
|
+
- **@voltro/database, @voltro/data-transfer, @voltro/cli** — A refused import row reported `(FiberFailure) SqlError: Failed to execute statement` — our runtime's rendering of a rejection, marker and stack frames and all — instead of the constraint that fired. It names neither a rule, nor a code, nor even which layer refused, and every row refused for the same cause carries it identically.
|
|
31
13
|
|
|
32
|
-
|
|
14
|
+
Two defects, and fixing either alone still leaves a reader stuck.
|
|
33
15
|
|
|
34
|
-
|
|
16
|
+
**`Cause.squash` elects a branch, and first is a position, not a ranking.** A `Cause` is a tree, and a transaction routinely produces one with more than one leaf: the statement that failed, and whatever the rollback or a finalizer did on the way out. When the first leaf was the bare wrapper, the driver error sitting in the sibling branch was never looked at. Measured: `sequential(bareSqlError, sqlErrorWithDriver)` classified as nothing while the same two branches in the opposite order classified as `unique constraint PRIMARY … [ER_DUP_ENTRY/1062]`. `extractDbCause` flattens failures AND defects now, in Cause order, expanding a nested `FiberFailure` leaf, and elects the branch that names a driver — the others' chains are appended rather than dropped.
|
|
35
17
|
|
|
36
|
-
|
|
18
|
+
**A row's reason may never read like a stack trace.** The runtime rendering is stripped before any tier looks at the text, so the failure mode cannot return invisibly. And when no driver detail is reachable at all, the reason now names the CHAIN of wrappers the failure passed through — the difference between "the database refused this row" and "the connection died mid-import" — while the run logs the full rendering of the first few such failures. Never returned over the wire: it carries frames, and on some engines a driver's sentence carries row data.
|
|
37
19
|
|
|
38
|
-
|
|
20
|
+
`RowsRefusedError` also gained `byTable`: **complete** per-table counts. `rows` is capped at 20, so per-table counts tallied off the printed list sum to the cap rather than to the failure — and nothing else in the payload offered any.
|
|
@@ -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.44.
|
|
16
|
-
"@voltro/cli": "0.44.
|
|
17
|
-
"@voltro/database": "0.44.
|
|
18
|
-
"@voltro/env": "0.44.
|
|
19
|
-
"@voltro/protocol": "0.44.
|
|
20
|
-
"@voltro/runtime": "0.44.
|
|
15
|
+
"@voltro/ai": "0.44.1",
|
|
16
|
+
"@voltro/cli": "0.44.1",
|
|
17
|
+
"@voltro/database": "0.44.1",
|
|
18
|
+
"@voltro/env": "0.44.1",
|
|
19
|
+
"@voltro/protocol": "0.44.1",
|
|
20
|
+
"@voltro/runtime": "0.44.1",
|
|
21
21
|
"effect": "^3.22.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@voltro/testing": "0.44.
|
|
24
|
+
"@voltro/testing": "0.44.1",
|
|
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.44.
|
|
17
|
-
"@voltro/database": "0.44.
|
|
18
|
-
"@voltro/env": "0.44.
|
|
19
|
-
"@voltro/plugin-auth": "0.44.
|
|
20
|
-
"@voltro/protocol": "0.44.
|
|
21
|
-
"@voltro/runtime": "0.44.
|
|
22
|
-
"@voltro/sql-postgres": "0.44.
|
|
16
|
+
"@voltro/cli": "0.44.1",
|
|
17
|
+
"@voltro/database": "0.44.1",
|
|
18
|
+
"@voltro/env": "0.44.1",
|
|
19
|
+
"@voltro/plugin-auth": "0.44.1",
|
|
20
|
+
"@voltro/protocol": "0.44.1",
|
|
21
|
+
"@voltro/runtime": "0.44.1",
|
|
22
|
+
"@voltro/sql-postgres": "0.44.1",
|
|
23
23
|
"effect": "^3.22.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@voltro/testing": "0.44.
|
|
26
|
+
"@voltro/testing": "0.44.1",
|
|
27
27
|
"typescript": "^6.0.3",
|
|
28
28
|
"@vitest/coverage-v8": "^4.1.10",
|
|
29
29
|
"vitest": "^4.1.10"
|
|
@@ -16,16 +16,16 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@effect/platform": "^0.97.0",
|
|
18
18
|
"@effect/rpc": "^0.76.0",
|
|
19
|
-
"@voltro/cli": "0.44.
|
|
20
|
-
"@voltro/database": "0.44.
|
|
21
|
-
"@voltro/env": "0.44.
|
|
22
|
-
"@voltro/plugin-multitenancy": "0.44.
|
|
23
|
-
"@voltro/protocol": "0.44.
|
|
24
|
-
"@voltro/runtime": "0.44.
|
|
19
|
+
"@voltro/cli": "0.44.1",
|
|
20
|
+
"@voltro/database": "0.44.1",
|
|
21
|
+
"@voltro/env": "0.44.1",
|
|
22
|
+
"@voltro/plugin-multitenancy": "0.44.1",
|
|
23
|
+
"@voltro/protocol": "0.44.1",
|
|
24
|
+
"@voltro/runtime": "0.44.1",
|
|
25
25
|
"effect": "^3.22.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@voltro/testing": "0.44.
|
|
28
|
+
"@voltro/testing": "0.44.1",
|
|
29
29
|
"typescript": "^6.0.3",
|
|
30
30
|
"@vitest/coverage-v8": "^4.1.10",
|
|
31
31
|
"vitest": "^4.1.10"
|
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@effect/platform": "^0.97.0",
|
|
15
15
|
"@effect/rpc": "^0.76.0",
|
|
16
|
-
"@voltro/cli": "0.44.
|
|
17
|
-
"@voltro/database": "0.44.
|
|
18
|
-
"@voltro/env": "0.44.
|
|
19
|
-
"@voltro/plugin-deactivation": "0.44.
|
|
20
|
-
"@voltro/protocol": "0.44.
|
|
21
|
-
"@voltro/runtime": "0.44.
|
|
16
|
+
"@voltro/cli": "0.44.1",
|
|
17
|
+
"@voltro/database": "0.44.1",
|
|
18
|
+
"@voltro/env": "0.44.1",
|
|
19
|
+
"@voltro/plugin-deactivation": "0.44.1",
|
|
20
|
+
"@voltro/protocol": "0.44.1",
|
|
21
|
+
"@voltro/runtime": "0.44.1",
|
|
22
22
|
"effect": "^3.22.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@voltro/testing": "0.44.
|
|
25
|
+
"@voltro/testing": "0.44.1",
|
|
26
26
|
"typescript": "^6.0.3",
|
|
27
27
|
"@vitest/coverage-v8": "^4.1.10",
|
|
28
28
|
"vitest": "^4.1.10"
|
|
@@ -13,18 +13,18 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@react-email/components": "^1.0.12",
|
|
15
15
|
"@react-email/render": "^1.4.0",
|
|
16
|
-
"@voltro/cli": "0.44.
|
|
17
|
-
"@voltro/database": "0.44.
|
|
18
|
-
"@voltro/env": "0.44.
|
|
19
|
-
"@voltro/plugin-mail": "0.44.
|
|
20
|
-
"@voltro/plugin-multitenancy": "0.44.
|
|
21
|
-
"@voltro/protocol": "0.44.
|
|
22
|
-
"@voltro/runtime": "0.44.
|
|
16
|
+
"@voltro/cli": "0.44.1",
|
|
17
|
+
"@voltro/database": "0.44.1",
|
|
18
|
+
"@voltro/env": "0.44.1",
|
|
19
|
+
"@voltro/plugin-mail": "0.44.1",
|
|
20
|
+
"@voltro/plugin-multitenancy": "0.44.1",
|
|
21
|
+
"@voltro/protocol": "0.44.1",
|
|
22
|
+
"@voltro/runtime": "0.44.1",
|
|
23
23
|
"effect": "^3.22.0",
|
|
24
24
|
"react": "^19.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@voltro/testing": "0.44.
|
|
27
|
+
"@voltro/testing": "0.44.1",
|
|
28
28
|
"typescript": "^6.0.3",
|
|
29
29
|
"@vitest/coverage-v8": "^4.1.10",
|
|
30
30
|
"vitest": "^4.1.10"
|
|
@@ -13,18 +13,18 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@effect/platform": "^0.97.0",
|
|
15
15
|
"@effect/rpc": "^0.76.0",
|
|
16
|
-
"@voltro/cli": "0.44.
|
|
17
|
-
"@voltro/database": "0.44.
|
|
18
|
-
"@voltro/env": "0.44.
|
|
19
|
-
"@voltro/plugin-multitenancy": "0.44.
|
|
20
|
-
"@voltro/plugin-storage": "0.44.
|
|
21
|
-
"@voltro/protocol": "0.44.
|
|
22
|
-
"@voltro/runtime": "0.44.
|
|
23
|
-
"@voltro/sql-mysql": "0.44.
|
|
16
|
+
"@voltro/cli": "0.44.1",
|
|
17
|
+
"@voltro/database": "0.44.1",
|
|
18
|
+
"@voltro/env": "0.44.1",
|
|
19
|
+
"@voltro/plugin-multitenancy": "0.44.1",
|
|
20
|
+
"@voltro/plugin-storage": "0.44.1",
|
|
21
|
+
"@voltro/protocol": "0.44.1",
|
|
22
|
+
"@voltro/runtime": "0.44.1",
|
|
23
|
+
"@voltro/sql-mysql": "0.44.1",
|
|
24
24
|
"effect": "^3.22.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@voltro/testing": "0.44.
|
|
27
|
+
"@voltro/testing": "0.44.1",
|
|
28
28
|
"typescript": "^6.0.3",
|
|
29
29
|
"@vitest/coverage-v8": "^4.1.10",
|
|
30
30
|
"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.44.
|
|
17
|
-
"@voltro/database": "0.44.
|
|
18
|
-
"@voltro/env": "0.44.
|
|
19
|
-
"@voltro/plugin-multitenancy": "0.44.
|
|
20
|
-
"@voltro/protocol": "0.44.
|
|
21
|
-
"@voltro/runtime": "0.44.
|
|
22
|
-
"@voltro/sql-sqlite": "0.44.
|
|
16
|
+
"@voltro/cli": "0.44.1",
|
|
17
|
+
"@voltro/database": "0.44.1",
|
|
18
|
+
"@voltro/env": "0.44.1",
|
|
19
|
+
"@voltro/plugin-multitenancy": "0.44.1",
|
|
20
|
+
"@voltro/protocol": "0.44.1",
|
|
21
|
+
"@voltro/runtime": "0.44.1",
|
|
22
|
+
"@voltro/sql-sqlite": "0.44.1",
|
|
23
23
|
"effect": "^3.22.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@voltro/testing": "0.44.
|
|
26
|
+
"@voltro/testing": "0.44.1",
|
|
27
27
|
"typescript": "^6.0.3",
|
|
28
28
|
"@vitest/coverage-v8": "^4.1.10",
|
|
29
29
|
"vitest": "^4.1.10"
|
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
"test": "voltro test"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@voltro/cli": "0.44.
|
|
15
|
-
"@voltro/database": "0.44.
|
|
16
|
-
"@voltro/env": "0.44.
|
|
17
|
-
"@voltro/plugin-multitenancy": "0.44.
|
|
18
|
-
"@voltro/plugin-storage": "0.44.
|
|
19
|
-
"@voltro/protocol": "0.44.
|
|
20
|
-
"@voltro/runtime": "0.44.
|
|
14
|
+
"@voltro/cli": "0.44.1",
|
|
15
|
+
"@voltro/database": "0.44.1",
|
|
16
|
+
"@voltro/env": "0.44.1",
|
|
17
|
+
"@voltro/plugin-multitenancy": "0.44.1",
|
|
18
|
+
"@voltro/plugin-storage": "0.44.1",
|
|
19
|
+
"@voltro/protocol": "0.44.1",
|
|
20
|
+
"@voltro/runtime": "0.44.1",
|
|
21
21
|
"effect": "^3.22.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@voltro/testing": "0.44.
|
|
24
|
+
"@voltro/testing": "0.44.1",
|
|
25
25
|
"typescript": "^6.0.3",
|
|
26
26
|
"@vitest/coverage-v8": "^4.1.10",
|
|
27
27
|
"vitest": "^4.1.10"
|
|
@@ -13,19 +13,19 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@effect/platform": "^0.97.0",
|
|
15
15
|
"@effect/rpc": "^0.76.0",
|
|
16
|
-
"@voltro/cli": "0.44.
|
|
17
|
-
"@voltro/cms": "0.44.
|
|
18
|
-
"@voltro/database": "0.44.
|
|
19
|
-
"@voltro/env": "0.44.
|
|
20
|
-
"@voltro/plugin-auth": "0.44.
|
|
21
|
-
"@voltro/plugin-multitenancy": "0.44.
|
|
22
|
-
"@voltro/protocol": "0.44.
|
|
23
|
-
"@voltro/runtime": "0.44.
|
|
24
|
-
"@voltro/sql-postgres": "0.44.
|
|
16
|
+
"@voltro/cli": "0.44.1",
|
|
17
|
+
"@voltro/cms": "0.44.1",
|
|
18
|
+
"@voltro/database": "0.44.1",
|
|
19
|
+
"@voltro/env": "0.44.1",
|
|
20
|
+
"@voltro/plugin-auth": "0.44.1",
|
|
21
|
+
"@voltro/plugin-multitenancy": "0.44.1",
|
|
22
|
+
"@voltro/protocol": "0.44.1",
|
|
23
|
+
"@voltro/runtime": "0.44.1",
|
|
24
|
+
"@voltro/sql-postgres": "0.44.1",
|
|
25
25
|
"effect": "^3.22.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@voltro/testing": "0.44.
|
|
28
|
+
"@voltro/testing": "0.44.1",
|
|
29
29
|
"typescript": "^6.0.3",
|
|
30
30
|
"@vitest/coverage-v8": "^4.1.10",
|
|
31
31
|
"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.44.
|
|
17
|
-
"@voltro/database": "0.44.
|
|
18
|
-
"@voltro/env": "0.44.
|
|
19
|
-
"@voltro/local-first": "0.44.
|
|
20
|
-
"@voltro/plugin-multitenancy": "0.44.
|
|
21
|
-
"@voltro/protocol": "0.44.
|
|
22
|
-
"@voltro/runtime": "0.44.
|
|
16
|
+
"@voltro/cli": "0.44.1",
|
|
17
|
+
"@voltro/database": "0.44.1",
|
|
18
|
+
"@voltro/env": "0.44.1",
|
|
19
|
+
"@voltro/local-first": "0.44.1",
|
|
20
|
+
"@voltro/plugin-multitenancy": "0.44.1",
|
|
21
|
+
"@voltro/protocol": "0.44.1",
|
|
22
|
+
"@voltro/runtime": "0.44.1",
|
|
23
23
|
"effect": "^3.22.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@voltro/testing": "0.44.
|
|
26
|
+
"@voltro/testing": "0.44.1",
|
|
27
27
|
"typescript": "^6.0.3",
|
|
28
28
|
"@vitest/coverage-v8": "^4.1.10",
|
|
29
29
|
"vitest": "^4.1.10"
|
|
@@ -12,17 +12,17 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@effect/platform": "^0.97.0",
|
|
14
14
|
"@effect/rpc": "^0.76.0",
|
|
15
|
-
"@voltro/cli": "0.44.
|
|
16
|
-
"@voltro/database": "0.44.
|
|
17
|
-
"@voltro/env": "0.44.
|
|
18
|
-
"@voltro/plugin-governance": "0.44.
|
|
19
|
-
"@voltro/plugin-multitenancy": "0.44.
|
|
20
|
-
"@voltro/protocol": "0.44.
|
|
21
|
-
"@voltro/runtime": "0.44.
|
|
15
|
+
"@voltro/cli": "0.44.1",
|
|
16
|
+
"@voltro/database": "0.44.1",
|
|
17
|
+
"@voltro/env": "0.44.1",
|
|
18
|
+
"@voltro/plugin-governance": "0.44.1",
|
|
19
|
+
"@voltro/plugin-multitenancy": "0.44.1",
|
|
20
|
+
"@voltro/protocol": "0.44.1",
|
|
21
|
+
"@voltro/runtime": "0.44.1",
|
|
22
22
|
"effect": "^3.22.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@voltro/testing": "0.44.
|
|
25
|
+
"@voltro/testing": "0.44.1",
|
|
26
26
|
"typescript": "^6.0.3",
|
|
27
27
|
"@vitest/coverage-v8": "^4.1.10",
|
|
28
28
|
"vitest": "^4.1.10"
|
|
@@ -12,17 +12,17 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@effect/platform": "^0.97.0",
|
|
14
14
|
"@effect/rpc": "^0.76.0",
|
|
15
|
-
"@voltro/cli": "0.44.
|
|
16
|
-
"@voltro/database": "0.44.
|
|
17
|
-
"@voltro/env": "0.44.
|
|
18
|
-
"@voltro/plugin-multitenancy": "0.44.
|
|
19
|
-
"@voltro/protocol": "0.44.
|
|
20
|
-
"@voltro/runtime": "0.44.
|
|
21
|
-
"@voltro/workflow": "0.44.
|
|
15
|
+
"@voltro/cli": "0.44.1",
|
|
16
|
+
"@voltro/database": "0.44.1",
|
|
17
|
+
"@voltro/env": "0.44.1",
|
|
18
|
+
"@voltro/plugin-multitenancy": "0.44.1",
|
|
19
|
+
"@voltro/protocol": "0.44.1",
|
|
20
|
+
"@voltro/runtime": "0.44.1",
|
|
21
|
+
"@voltro/workflow": "0.44.1",
|
|
22
22
|
"effect": "^3.22.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@voltro/testing": "0.44.
|
|
25
|
+
"@voltro/testing": "0.44.1",
|
|
26
26
|
"typescript": "^6.0.3",
|
|
27
27
|
"@vitest/coverage-v8": "^4.1.10",
|
|
28
28
|
"vitest": "^4.1.10"
|
|
@@ -13,18 +13,18 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@effect/platform": "^0.97.0",
|
|
15
15
|
"@effect/rpc": "^0.76.0",
|
|
16
|
-
"@voltro/cli": "0.44.
|
|
17
|
-
"@voltro/database": "0.44.
|
|
18
|
-
"@voltro/env": "0.44.
|
|
19
|
-
"@voltro/plugin-flags": "0.44.
|
|
20
|
-
"@voltro/plugin-multitenancy": "0.44.
|
|
21
|
-
"@voltro/protocol": "0.44.
|
|
22
|
-
"@voltro/runtime": "0.44.
|
|
23
|
-
"@voltro/sql-postgres": "0.44.
|
|
16
|
+
"@voltro/cli": "0.44.1",
|
|
17
|
+
"@voltro/database": "0.44.1",
|
|
18
|
+
"@voltro/env": "0.44.1",
|
|
19
|
+
"@voltro/plugin-flags": "0.44.1",
|
|
20
|
+
"@voltro/plugin-multitenancy": "0.44.1",
|
|
21
|
+
"@voltro/protocol": "0.44.1",
|
|
22
|
+
"@voltro/runtime": "0.44.1",
|
|
23
|
+
"@voltro/sql-postgres": "0.44.1",
|
|
24
24
|
"effect": "^3.22.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@voltro/testing": "0.44.
|
|
27
|
+
"@voltro/testing": "0.44.1",
|
|
28
28
|
"typescript": "^6.0.3",
|
|
29
29
|
"@vitest/coverage-v8": "^4.1.10",
|
|
30
30
|
"vitest": "^4.1.10"
|