@voltro/cli 0.43.2 → 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 +50 -0
- package/dist/{apiBuild-BWuw8ZXS.js → apiBuild-DvWreIQP.js} +1 -1
- package/dist/apiBuild-XaW40W8x.js +2 -0
- package/dist/bin.js +1 -1
- package/dist/{build-CGBs4ZOv.js → build-Ckc-FA7d.js} +6 -6
- package/dist/{checkCommand-lTPSN3EQ.js → checkCommand-AlbawIal.js} +1 -1
- package/dist/{checkCommand-BFtFBsqL.js → checkCommand-BNfEs4KG.js} +2 -2
- package/dist/{codegenCommand-BJeyFlip.js → codegenCommand-iClXoRCW.js} +1 -1
- package/dist/{codemodRunner-Cnnz4-I7.js → codemodRunner-BKTnaGOz.js} +22 -0
- package/dist/{commands-pEDOcOo2.js → commands-CYkHTox2.js} +18 -18
- package/dist/{dashboardCommand-Bt2hHMro.js → dashboardCommand-DHDmlo9A.js} +1 -1
- package/dist/{dataCommand-DD2bRHCu.js → dataCommand-WFn8CM11.js} +258 -236
- package/dist/{dev-DMx-MF2s.js → dev-BZO5aLdr.js} +1 -1
- package/dist/{dev-wumUfDm1.js → dev-D-JZ6CGQ.js} +8 -4
- package/dist/doctorCommand-BeLOwq7S.js +2 -0
- package/dist/{doctorCommand-RFKpnLih.js → doctorCommand-BlUyESpD.js} +9 -9
- package/dist/{dormancyCommand-EFDQWiUw.js → dormancyCommand-lQxdrU8C.js} +1 -1
- package/dist/{embeddingsCommand-OeYp3qSq.js → embeddingsCommand-ByBTju6X.js} +1 -1
- package/dist/{envCommand-CKgBZK7x.js → envCommand-CpCbYAgR.js} +1 -1
- package/dist/{evolveCommand-ClQlAH0j.js → evolveCommand-CBV3-TtK.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{infoCommand-Bs_8RU22.js → infoCommand-DJoA9cKD.js} +1 -1
- package/dist/{runtimeTrace-CgpAD9wL.js → runtimeTrace-DJ9tPhrc.js} +1 -1
- package/dist/{sdkgen-Ca2zj4cd.js → sdkgen-7dr8-Onw.js} +1 -1
- package/dist/{serveCommand-CgK7Kj6j.js → serveCommand-BlnAlNQg.js} +632 -621
- package/dist/serveCommand-Dg_E1ev4.js +2 -0
- package/dist/serveEntry.js +1 -1
- package/dist/{updateCommand-CrI9B4d7.js → updateCommand-BvRidHp6.js} +1 -1
- package/dist/updateCommand-DcKVmLVN.js +2 -0
- package/dist/{webhooksCommand-BVNtNsI0.js → webhooksCommand-BfO_JF2b.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 +43 -7
- package/templates/agent-docs/plugins/versioning.md +2 -0
- package/templates/agent-docs/whats-new.md +6 -21
- 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-Cw2-TEXW.js +0 -2
- package/dist/doctorCommand-FOXTTaGp.js +0 -2
- package/dist/serveCommand-DUm2-ikx.js +0 -2
- package/dist/updateCommand-BvkKlV7D.js +0 -2
package/dist/serveEntry.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./loadEnv-D9nEOClM.js";
|
|
2
2
|
import { r as t } from "./appModuleLoader-C9r9mxZt.js";
|
|
3
3
|
import { i as n } from "./dialectDriver-czCHYpeH.js";
|
|
4
|
-
import { t as r } from "./serveCommand-
|
|
4
|
+
import { t as r } from "./serveCommand-BlnAlNQg.js";
|
|
5
5
|
export { e as loadDotEnv, t as registerAppModules, n as registerDriver, r as runServe };
|
|
@@ -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-BKTnaGOz.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";
|
|
@@ -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-BZO5aLdr.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.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",
|
|
@@ -634,6 +634,12 @@
|
|
|
634
634
|
"title": "`DanglingReferenceError` → `RowsRefusedError` (named for the outcome, not a guessed cause)",
|
|
635
635
|
"kind": "transform"
|
|
636
636
|
},
|
|
637
|
+
{
|
|
638
|
+
"version": "0.44.0",
|
|
639
|
+
"id": "0.44.0/01_import-outcome",
|
|
640
|
+
"title": "`runImport` returns an ImportOutcome — read `.manifest` for the bundle",
|
|
641
|
+
"kind": "manual"
|
|
642
|
+
},
|
|
637
643
|
{
|
|
638
644
|
"version": "0.5.0",
|
|
639
645
|
"id": "0.5.0/01_one-terminal-exactly-one",
|
|
@@ -721,22 +727,22 @@
|
|
|
721
727
|
"@effect/platform-node": "^0.108.0",
|
|
722
728
|
"@effect/sql": "^0.52.0",
|
|
723
729
|
"@effect/workflow": "^0.19.0",
|
|
724
|
-
"@voltro/ai": "0.
|
|
725
|
-
"@voltro/cache": "0.
|
|
726
|
-
"@voltro/data-transfer": "0.
|
|
727
|
-
"@voltro/database": "0.
|
|
728
|
-
"@voltro/env": "0.
|
|
729
|
-
"@voltro/kv": "0.
|
|
730
|
-
"@voltro/logger": "0.
|
|
731
|
-
"@voltro/plugin-auth": "0.
|
|
732
|
-
"@voltro/plugin-broadcast": "0.
|
|
733
|
-
"@voltro/plugin-mail": "0.
|
|
734
|
-
"@voltro/plugin-storage": "0.
|
|
735
|
-
"@voltro/plugin-webhooks": "0.
|
|
736
|
-
"@voltro/protocol": "0.
|
|
737
|
-
"@voltro/runtime": "0.
|
|
738
|
-
"@voltro/serverless": "0.
|
|
739
|
-
"@voltro/workflow": "0.
|
|
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",
|
|
740
746
|
"chokidar": "^5.0.0",
|
|
741
747
|
"ioredis": "^5.11.1",
|
|
742
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.
|
|
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.
|
|
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
|
|
|
@@ -2649,7 +2649,8 @@ whole bundle.
|
|
|
2649
2649
|
|---|---|---|
|
|
2650
2650
|
| `--mode upsert\|append\|replace` | `upsert` | How rows are written. See the table below. |
|
|
2651
2651
|
| `--on-conflict skip\|fail` | `skip` | `append` only: what to do when the primary key already exists. |
|
|
2652
|
-
| `--atomic` | off | Wrap the whole table phase in ONE transaction —
|
|
2652
|
+
| `--atomic` | **on for `replace`**, off otherwise | Wrap the whole table phase in ONE transaction — readers see the import all-or-nothing. |
|
|
2653
|
+
| `--no-atomic` | — | Opt out of that. See the trade below. |
|
|
2653
2654
|
| `--tables a,b` | every table | Import only these tables from the bundle. |
|
|
2654
2655
|
| `--dry-run` | off | Run every pre-flight and report what WOULD move; write nothing. |
|
|
2655
2656
|
| `--force` | off | Proceed despite schema drift AND cross-dialect warnings. |
|
|
@@ -2744,7 +2745,27 @@ A row whose write fails on a foreign-key constraint — a forward reference from
|
|
|
2744
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.
|
|
2745
2746
|
3. **Patch pass** — shed rows are re-written with the full bundle row, restoring the FK values.
|
|
2746
2747
|
|
|
2747
|
-
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.
|
|
2748
2769
|
|
|
2749
2770
|
### Write modes (`--mode`)
|
|
2750
2771
|
|
|
@@ -2760,7 +2781,11 @@ Anything still unresolvable — the parent row exists in **neither the bundle no
|
|
|
2760
2781
|
|
|
2761
2782
|
The bundle's tables are emptied **as one unit, in one transaction, with referential integrity suspended for the duration** — not table by table. Both halves matter:
|
|
2762
2783
|
|
|
2763
|
-
- **All or nothing.**
|
|
2784
|
+
- **All or nothing — the emptying AND the load.** `--mode replace` runs the whole table phase in ONE transaction by default, so a run that cannot finish leaves the target exactly as it found it. That default is a correction: the guarantee used to cover only the emptying, and a replace that died partway through the *load* left the target emptied of its old rows and holding part of the new ones. There is no useful state for a replace to stop in, which is why it is the default rather than a flag you have to know about.
|
|
2785
|
+
|
|
2786
|
+
One transaction also closes a window that is easy to miss. Between the delete and the load the target is empty, and if the database is being served, the application writes into that gap — a row it creates on demand is then a primary-key conflict against the same row arriving from the bundle. With one transaction the concurrent writer waits instead of racing.
|
|
2787
|
+
|
|
2788
|
+
`--no-atomic` opts out, and the trade is real: every write to those tables waits for the load, so on a bundle that takes minutes, so does the wait. On postgres it also re-enables the bulk `COPY` loader, which cannot join a transaction it does not own — an atomic run says so once rather than being quietly slower.
|
|
2764
2789
|
- **No ordering can replace the suspension.** MySQL, MariaDB and SQL Server check a foreign key as each *row* is deleted, so a table that references **itself** cannot be emptied at all by ordering tables — the conflict is between two rows of one of them. `createdBy → actors` on the `actors` table is exactly that shape, and it is what an audit mixin on an actor table produces. (Postgres needs no suspension: a multi-table `TRUNCATE` covers the whole set at once.)
|
|
2765
2790
|
|
|
2766
2791
|
What it will **not** do is reach outside the bundle. If a table the bundle does **not** carry holds rows that reference one it does, `replace` refuses **before deleting anything** and names them:
|
|
@@ -2817,10 +2842,10 @@ A plain import connects **straight to the database** (not through the running ap
|
|
|
2817
2842
|
| Target | How | Guarantees | Use for |
|
|
2818
2843
|
|---|---|---|---|
|
|
2819
2844
|
| **direct** (default) | writes straight to the DB | none while live — **guarded**; pass `--allow-live` to override | a stopped target, a replica, a dev/staging DB not serving traffic |
|
|
2820
|
-
| **direct + `--atomic`** | wraps
|
|
2845
|
+
| **direct + `--atomic`** (the default for `replace`) | wraps empty+load in ONE transaction | MVCC readers see the import **all-or-nothing** (old until commit, new after) — the live-safe `replace` | replacing a live target's data with no partial-state window |
|
|
2821
2846
|
| **in-process (`--target api`)** | `voltro data import <dir> --target api --api-url <url> --token <secret>` **uploads** the packed bundle (or, with `--bundle-key`, has the instance **pull it from storage**) to the instance's secret-gated admin endpoint, which imports it **in its own process** through its store | full app pipeline — validation, mixins, **field encryption**, hooks — AND automatic reactivity (in-process writes emit change events, so subscriptions update; no separate resync) | a live merge (incl. PROD) that must honour app invariants |
|
|
2822
2847
|
|
|
2823
|
-
`--atomic` is
|
|
2848
|
+
`--atomic` is what `replace` does by default (see above): one transaction, so live reads never see a half-loaded table. (It holds a write transaction for the load duration — writes to those tables block, readers don't. A shadow-table rename would shorten that lock window, but for a full replace concurrent writes are discarded on swap anyway, so it isn't the default.)
|
|
2824
2849
|
|
|
2825
2850
|
### The `--target api` data-transfer endpoints (prod-safe)
|
|
2826
2851
|
|
|
@@ -2937,6 +2962,17 @@ Net: interrupt an export or import at any point — network drop, `Ctrl-C`, OOM-
|
|
|
2937
2962
|
|
|
2938
2963
|
The `--target api` path is unaffected: the instance unpacks each upload into a fresh temp directory, so it never carries a ledger between runs.
|
|
2939
2964
|
|
|
2965
|
+
### What the summary line counts
|
|
2966
|
+
|
|
2967
|
+
`import complete … rows: N` counts the rows **this run wrote**, not the rows the bundle carries. The two differ more often than you would think, and the case where they differ most used to read as a success:
|
|
2968
|
+
|
|
2969
|
+
```
|
|
2970
|
+
import complete — 0 rows written, every table was already applied by an earlier run
|
|
2971
|
+
of this bundle directory { rows: 0, carried: 242950, skippedTables: 114, skippedRows: 242950 }
|
|
2972
|
+
```
|
|
2973
|
+
|
|
2974
|
+
The resume ledger lives **inside the bundle directory**, so copying a bundle copies its ledger, and the copy then imports nothing — correctly, and with a warning that says so and names the file to delete. But the warning is not the last line, and an operator piping the output through `tail -1` sees only the last line. So the last line now tells the truth on its own: `rows` is what was written, `carried` is what the bundle holds, and `skippedRows` is what an earlier run had already applied.
|
|
2975
|
+
|
|
2940
2976
|
### Progress & observability
|
|
2941
2977
|
|
|
2942
2978
|
A multi-hour job is not a black box. Both pipelines signal per **table** — never per row, so the reporting never slows the hot path:
|
|
@@ -2961,7 +2997,7 @@ yield* runImport({
|
|
|
2961
2997
|
|
|
2962
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):
|
|
2963
2999
|
|
|
2964
|
-
`BundleError`, `CodecError`, `IntegrityError`, `CrossDialectError`, `ImportModeError`, `
|
|
3000
|
+
`BundleError`, `CodecError`, `IntegrityError`, `CrossDialectError`, `ImportModeError`, `RowsRefusedError`, `SchemaDriftError`, `MaskingError`, `ScopeError`.
|
|
2965
3001
|
|
|
2966
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.
|
|
2967
3003
|
|
|
@@ -134,6 +134,8 @@ Version numbers are 1-based in **both** timings, so switching `timing` does not
|
|
|
134
134
|
|
|
135
135
|
**The price is not optional.** That guarantee is only obtainable by being willing to REFUSE. When the history insert fails — disk, lock timeout, constraint, dropped connection — a transaction offers exactly two outcomes: the mutation fails with it, or the error is swallowed and the change commits without its entry, which is post-commit's hole with the cost already paid. There is no third option, so a rare, explained rejection is the shape of the guarantee rather than a defect.
|
|
136
136
|
|
|
137
|
+
**The refusal takes the row with it.** When the trail's insert fails, the write it covers is rolled back — including a write made OUTSIDE any transaction of your own. That has not always been true: the row's statement committed on its own and the trail ran as a second statement afterwards, so a failing trail left a committed row behind a write that reported failure. Anything that retried that write then met its own row and reported a duplicate key for a row nobody wrote twice. A table with recorders is written inside a transaction now, on every SQL dialect, so "the mutation fails with it" means what it says.
|
|
138
|
+
|
|
137
139
|
**Why the default is still `'post-commit'`.** In-transaction makes `_voltro_row_history` a hard dependency of every write path it covers: its availability becomes your write path's availability, and every covered write holds its locks longer. Post-commit loses at worst *one entry*; in-transaction can, at worst, stop writes to the covered tables entirely. For a compliance trail the second trade is the right one — for the undo / time-travel use this plugin also serves, it is not.
|
|
138
140
|
|
|
139
141
|
### Under CDC, and inside a transaction
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# What's new in 0.
|
|
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
|
|
@@ -9,27 +9,12 @@ BREAKING entries name a codemod; run `voltro update` to apply it.
|
|
|
9
9
|
|
|
10
10
|
### Fixed
|
|
11
11
|
|
|
12
|
-
- **@voltro/
|
|
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.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Two defects, and fixing either alone still leaves a reader stuck.
|
|
15
15
|
|
|
16
|
-
|
|
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.
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
- **@voltro/data-transfer, @voltro/database, @voltro/sql-mysql, @voltro/sql-postgres, @voltro/sql-sqlite, @voltro/sql-mssql, @voltro/cli** — `voltro data import --mode replace` no longer leaves a target in neither state, and now works against schemas that have foreign keys.
|
|
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.
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- `DataStore.emptyTables()` (per dialect) empties the whole set as one unit, in one transaction, with referential integrity suspended for the duration — `FOREIGN_KEY_CHECKS` on the mysql family, a multi-table `TRUNCATE` on postgres, `defer_foreign_keys` on sqlite, per-table `NOCHECK`/`WITH CHECK CHECK` on mssql. All-or-nothing on every engine, including under `--atomic`, where it runs on the transaction the import already holds. - A **pre-flight refusal**: if a table OUTSIDE the bundle holds rows referencing one inside it, the import refuses before deleting anything and names the tables, the columns and the row counts. Those rows cannot be restored from the bundle, so forcing it is not an option. An EMPTY outside table blocks nothing. - Table-level failures carry the driver's own reason and code, the way row-level failures already did. `truncate <table> failed: Failed to execute statement` fits every plausible cause equally; the classification that produced `foreign key <name>: … [ER_NO_REFERENCED_ROW_2/1452]` one level down now applies one level up. The word "truncate" is gone from the message too — the step issues DELETE, and naming a statement it does not run sends whoever reads it to reproduce the wrong thing. - A typed refusal reaching the `--target api` transport keeps its text: the admin import endpoint answers `409` with the reason instead of flattening it to `import failed`, on the one transport where the operator has no other way to see it.
|
|
24
|
-
|
|
25
|
-
The bulk empty emits no change events, where the per-table loop emitted one per row. An import through `--target api` now asks every live subscription to re-read once it lands — the coarse refresh the framework already uses after a broadcast gap — so neither the missing deletes nor a table the bundle carries EMPTY leaves a subscriber holding rows that are gone. Wired where the route is mounted, which is the one place both boot paths share.
|
|
26
|
-
|
|
27
|
-
On postgres the emptying is a `DELETE` per table, not a `TRUNCATE`, and the difference is not performance: postgres refuses `TRUNCATE` on a table with ANY incoming foreign key, rows or not, while the mysql family refuses a DELETE only when rows actually reference the doomed ones. A `TRUNCATE` version made an EMPTY table outside the bundle block a replace on postgres and not on mariadb — one import, refused on one engine and accepted on the other, over a table holding nothing.
|
|
28
|
-
|
|
29
|
-
`--target api` also no longer times out on a full bundle. Both api-target calls went through `fetch`, whose undici default gives up after 300 s — a bound on the caller's database size, on a call whose response arrives only when the import does. They wait as long as the instance needs now, stream the body instead of buffering the whole bundle, and take `--timeout <seconds>` when a deadline is wanted. If one is hit, the message says the instance is probably still importing — and gives different advice for `replace` than for the idempotent modes, since re-running the first while it is mid-flight would empty the target under it.
|
|
30
|
-
|
|
31
|
-
Two more, found by measuring rather than by reading:
|
|
32
|
-
|
|
33
|
-
- **`--atomic` on postgres could not import a bundle that needed the deferred-FK repair at all.** A failed statement aborts the transaction there, and that repair depends on a row whose parent has not loaded yet failing, being held, and being retried — so the first such row poisoned every write after it. Every tolerated write now runs inside a savepoint. Per-row savepoints measured 2.40x the time of none on 5 000 rows, so they are amortised: one savepoint per batch of 200, and a batch that fails rolls back whole and replays row by row. The mysql family and sqlite leave a transaction usable after a failed statement and pay nothing for any of this. - **The replace pre-flight asked the caller's snapshot.** Over `--target api` that is the app's DECLARED schema, which cannot show a table the app stopped declaring but the database still has — and rows in a table nobody declares are exactly the rows nobody is watching. `DataStore.incomingForeignKeys()` reads the live catalog per dialect; the snapshot remains the fallback for stores without one.
|
|
34
|
-
|
|
35
|
-
A bundle bigger than one chunk is now uploaded as a series of short requests, so a proxy body cap or an ingress read timeout has nothing large to choke on, and the switch is automatic — the packer's stream is buffered one chunk ahead, so a small bundle is sent exactly as before and nobody has to know in advance which table is the big one. The import still runs ONCE, at the end, over the whole bundle. Resume is byte-exact (`packBundle` is deterministic over a directory, which this package now asserts), guarded by a bundle key so a different bundle under the same upload id is refused rather than spliced into the partial one, and by a contiguity check so a mis-ordered append cannot produce an archive that only fails later during decode. `--chunk-size <mb>` overrides the 16 MiB default.
|
|
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.
|
|
16
|
-
"@voltro/cli": "0.
|
|
17
|
-
"@voltro/database": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/protocol": "0.
|
|
20
|
-
"@voltro/runtime": "0.
|
|
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.
|
|
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.
|
|
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.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.
|
|
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.
|
|
20
|
-
"@voltro/database": "0.
|
|
21
|
-
"@voltro/env": "0.
|
|
22
|
-
"@voltro/plugin-multitenancy": "0.
|
|
23
|
-
"@voltro/protocol": "0.
|
|
24
|
-
"@voltro/runtime": "0.
|
|
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.
|
|
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.
|
|
17
|
-
"@voltro/database": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/plugin-deactivation": "0.
|
|
20
|
-
"@voltro/protocol": "0.
|
|
21
|
-
"@voltro/runtime": "0.
|
|
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.
|
|
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.
|
|
17
|
-
"@voltro/database": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/plugin-mail": "0.
|
|
20
|
-
"@voltro/plugin-multitenancy": "0.
|
|
21
|
-
"@voltro/protocol": "0.
|
|
22
|
-
"@voltro/runtime": "0.
|
|
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.
|
|
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.
|
|
17
|
-
"@voltro/database": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/plugin-multitenancy": "0.
|
|
20
|
-
"@voltro/plugin-storage": "0.
|
|
21
|
-
"@voltro/protocol": "0.
|
|
22
|
-
"@voltro/runtime": "0.
|
|
23
|
-
"@voltro/sql-mysql": "0.
|
|
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.
|
|
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.
|
|
17
|
-
"@voltro/database": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/plugin-multitenancy": "0.
|
|
20
|
-
"@voltro/protocol": "0.
|
|
21
|
-
"@voltro/runtime": "0.
|
|
22
|
-
"@voltro/sql-sqlite": "0.
|
|
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.
|
|
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.
|
|
15
|
-
"@voltro/database": "0.
|
|
16
|
-
"@voltro/env": "0.
|
|
17
|
-
"@voltro/plugin-multitenancy": "0.
|
|
18
|
-
"@voltro/plugin-storage": "0.
|
|
19
|
-
"@voltro/protocol": "0.
|
|
20
|
-
"@voltro/runtime": "0.
|
|
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.
|
|
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.
|
|
17
|
-
"@voltro/cms": "0.
|
|
18
|
-
"@voltro/database": "0.
|
|
19
|
-
"@voltro/env": "0.
|
|
20
|
-
"@voltro/plugin-auth": "0.
|
|
21
|
-
"@voltro/plugin-multitenancy": "0.
|
|
22
|
-
"@voltro/protocol": "0.
|
|
23
|
-
"@voltro/runtime": "0.
|
|
24
|
-
"@voltro/sql-postgres": "0.
|
|
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.
|
|
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.
|
|
17
|
-
"@voltro/database": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/local-first": "0.
|
|
20
|
-
"@voltro/plugin-multitenancy": "0.
|
|
21
|
-
"@voltro/protocol": "0.
|
|
22
|
-
"@voltro/runtime": "0.
|
|
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.
|
|
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.
|
|
16
|
-
"@voltro/database": "0.
|
|
17
|
-
"@voltro/env": "0.
|
|
18
|
-
"@voltro/plugin-governance": "0.
|
|
19
|
-
"@voltro/plugin-multitenancy": "0.
|
|
20
|
-
"@voltro/protocol": "0.
|
|
21
|
-
"@voltro/runtime": "0.
|
|
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.
|
|
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"
|