@tailor-platform/sdk 2.34.0 → 2.35.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 +26 -0
- package/dist/{application-CwpOIOTt.mjs → application-Bj2MtL-d.mjs} +1 -1
- package/dist/{application-Nce5z46R.mjs → application-DIsQSnj3.mjs} +25 -25
- package/dist/application-DIsQSnj3.mjs.map +1 -0
- package/dist/cli/commands/deploy/tailordb/migration-validation.d.mts +1 -2
- package/dist/cli/commands/tailordb/migrate/generate.d.mts +1 -1
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.mjs +37 -37
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/services/application.d.mts +1 -0
- package/dist/cli/services/function-bundle.d.mts +1 -0
- package/dist/cli/shared/sdk-builder-pure-plugin.d.mts +1 -0
- package/dist/completion/zsh-worker.zsh +4 -4
- package/dist/{kysely-type-DxyIWXc6.mjs → kysely-type-B0ri1-Xs.mjs} +9 -7
- package/dist/kysely-type-B0ri1-Xs.mjs.map +1 -0
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
- package/dist/{register-ts-hook-CtWJL3EO.mjs → register-ts-hook-CQ7shKO5.mjs} +59 -58
- package/dist/register-ts-hook-CQ7shKO5.mjs.map +1 -0
- package/docs/cli/tailordb.md +8 -6
- package/docs/cli-reference.md +1 -1
- package/docs/configuration.md +2 -0
- package/docs/services/tailordb/index.md +4 -0
- package/docs/services/tailordb/migration.md +12 -7
- package/docs/testing.md +2 -2
- package/package.json +1 -1
- package/dist/application-Nce5z46R.mjs.map +0 -1
- package/dist/cli/commands/tailordb/migrate/remote-state.d.mts +0 -1
- package/dist/kysely-type-DxyIWXc6.mjs.map +0 -1
- package/dist/register-ts-hook-CtWJL3EO.mjs.map +0 -1
package/docs/cli/tailordb.md
CHANGED
|
@@ -102,7 +102,7 @@ tailor tailordb migration <command>
|
|
|
102
102
|
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
103
103
|
| [`tailordb migration generate`](#tailordb-migration-generate) | Generate migration files by detecting schema differences between current local tables and the previous migration snapshot. |
|
|
104
104
|
| [`tailordb migration rebaseline`](#tailordb-migration-rebaseline) | Collapse the full migration history into a new 0000 baseline. |
|
|
105
|
-
| [`tailordb migration resolve`](#tailordb-migration-resolve) | Settle a migration that a failed deploy left partially applied.
|
|
105
|
+
| [`tailordb migration resolve`](#tailordb-migration-resolve) | Settle a migration that a failed deploy left partially applied, or whose run a deploy could not confirm. |
|
|
106
106
|
| [`tailordb migration script`](#tailordb-migration-script) | Add a migration script (migrate.ts) template to an existing migration directory, or record with --no-script that a migration intentionally has none. |
|
|
107
107
|
| [`tailordb migration set`](#tailordb-migration-set) | Set migration checkpoint to a specific number. |
|
|
108
108
|
| [`tailordb migration status`](#tailordb-migration-status) | Show the current migration status for TailorDB namespaces, including applied and pending migrations. |
|
|
@@ -129,9 +129,9 @@ tailor tailordb migration generate [options]
|
|
|
129
129
|
| `--yes` | `-y` | Skip confirmation prompts | No | `false` | - |
|
|
130
130
|
| `--config <CONFIG>` | `-c` | Path to Tailor config file | No | `"tailor.config.ts"` | `TAILOR_CONFIG_PATH` |
|
|
131
131
|
| `--name <NAME>` | `-n` | Optional description for the migration | No | - | - |
|
|
132
|
-
| `--init` | - | Delete existing migrations and start fresh
|
|
132
|
+
| `--init` | - | Delete existing migrations and start fresh (all namespaces with migrations configured, or only the one given by --namespace) | No | `false` | - |
|
|
133
133
|
| `--data-only` | - | Create a migration with no schema changes whose migration script runs a standalone data transformation | No | `false` | - |
|
|
134
|
-
| `--namespace <NAMESPACE>` | - | Target TailorDB namespace for --data-only (required if multiple namespaces exist)
|
|
134
|
+
| `--namespace <NAMESPACE>` | - | Target TailorDB namespace for --data-only (required if multiple namespaces exist), or the only namespace --init resets | No | - | - |
|
|
135
135
|
| `--rename <RENAME>` | - | Record a field, table, or nested member rename instead of remove + add (format: "Table.oldField:newField", "OldTable:NewTable", or "Table.field.oldMember:newMember"; repeatable). Renames require a migration script that copies the data. | No | - | - |
|
|
136
136
|
| `--drop <DROP>` | - | Confirm that a removed field, table, or nested member is a genuine removal, not a rename (format: "Table.field", "Table", or "Table.field.member"; repeatable). Required in non-interactive runs for a removal with rename candidates. | No | - | - |
|
|
137
137
|
| `--expand-contract <EXPAND_CONTRACT>` | - | Convert a field type, or a single value into an array, through a temporary field (format: "Table.field"; repeatable). Generates two migrations. | No | - | - |
|
|
@@ -166,7 +166,7 @@ Re-baselining removes migrations after 0000 from the working tree, records a new
|
|
|
166
166
|
|
|
167
167
|
#### tailordb migration resolve
|
|
168
168
|
|
|
169
|
-
Settle a migration that a failed deploy left partially applied.
|
|
169
|
+
Settle a migration that a failed deploy left partially applied, or whose run a deploy could not confirm.
|
|
170
170
|
|
|
171
171
|
**Usage**
|
|
172
172
|
|
|
@@ -190,11 +190,13 @@ See [Global Options](../cli-reference.md#global-options) for options available t
|
|
|
190
190
|
|
|
191
191
|
**Notes**
|
|
192
192
|
|
|
193
|
-
Use this after a deploy failed partway through a migration whose `migrate.ts` exports `steps
|
|
193
|
+
Use this after a deploy failed partway through a migration whose `migrate.ts` exports `steps`, or after a deploy could not confirm whether the script of a migration ran (`MIGRATION_OUTCOME_UNKNOWN`). The migration stays in progress: when `maintenanceMode` is on in your config, the tables of its namespace stay in maintenance mode, and `sync` and `rebaseline` are refused, while `set` accepts only the number of the in-progress migration. A deploy stops before changing anything while a run it could not confirm is not settled.
|
|
194
194
|
|
|
195
|
-
- `--rollback` sends the schema of the migration before the failed one. The next deploy runs the failed migration again from its first step
|
|
195
|
+
- `--rollback` sends the schema of the migration before the failed one. The next deploy runs the failed migration again, from its first step for a script that exports `steps`. Data changes the script already made are not undone.
|
|
196
196
|
- `--complete` sends the schema of the failed migration itself and records it as completed, without running its `migrate.ts` again. Fix the data first (for example with `tailor query`), and make sure no record lacks a value for a field that becomes required.
|
|
197
197
|
|
|
198
|
+
For a run that a deploy could not confirm, the command reads how the run ended and shows it before asking for confirmation: use `--complete` when it succeeded, and `--rollback` when it failed, was canceled, or did not start. It refuses while the run is still running, and warns when the option you chose does not fit how the run ended.
|
|
199
|
+
|
|
198
200
|
Both options remove the in-progress record, take the tables out of maintenance mode, and remove the temporary resources of the failed run, so `deploy` and the other migration commands work again. As with `tailordb migration sync`, the local migration history must reproduce the current table definitions. If sending the schema stops partway, run the command again.
|
|
199
201
|
|
|
200
202
|
#### tailordb migration script
|
package/docs/cli-reference.md
CHANGED
|
@@ -332,7 +332,7 @@ Commands for managing TailorDB tables, data, and schema migrations.
|
|
|
332
332
|
| [tailordb migration](./cli/tailordb.md#tailordb-migration) | Manage TailorDB schema migrations. |
|
|
333
333
|
| [tailordb migration generate](./cli/tailordb.md#tailordb-migration-generate) | Generate migration files by detecting schema differences between current local tables and the previous migration snapshot. |
|
|
334
334
|
| [tailordb migration rebaseline](./cli/tailordb.md#tailordb-migration-rebaseline) | Collapse the full migration history into a new 0000 baseline. |
|
|
335
|
-
| [tailordb migration resolve](./cli/tailordb.md#tailordb-migration-resolve) | Settle a migration that a failed deploy left partially applied.
|
|
335
|
+
| [tailordb migration resolve](./cli/tailordb.md#tailordb-migration-resolve) | Settle a migration that a failed deploy left partially applied, or whose run a deploy could not confirm. |
|
|
336
336
|
| [tailordb migration script](./cli/tailordb.md#tailordb-migration-script) | Add a migration script (migrate.ts) template to an existing migration directory, or record with --no-script that a migration intentionally has none. |
|
|
337
337
|
| [tailordb migration set](./cli/tailordb.md#tailordb-migration-set) | Set migration checkpoint to a specific number. |
|
|
338
338
|
| [tailordb migration status](./cli/tailordb.md#tailordb-migration-status) | Show the current migration status for TailorDB namespaces, including applied and pending migrations. |
|
package/docs/configuration.md
CHANGED
|
@@ -211,6 +211,8 @@ export default defineConfig({
|
|
|
211
211
|
|
|
212
212
|
With `false`, a property read whose result is unused is removed, and so is a call that only exists to receive such a read. This also removes a read that exists only for its effect: a getter that initializes something when it is read, or a statement such as `settings.db.url;` that throws when `settings.db` is missing. Keep the default if your code or an installed package relies on a read like that.
|
|
213
213
|
|
|
214
|
+
Field and table definitions written with `db` and `t` count as having no effect, so they do not keep such a call in the bundle: with `propertyReadSideEffects: false`, `createService({ db: { company: shared.db.company }, fields: { note: db.string().index() } })` is removed when nothing uses its result. This applies to `db` and `t` that your own code imports by name from `@tailor-platform/sdk`, not to definitions in installed packages, and not when `treeshake.annotations` is `false`. A function called in a definition's arguments still runs, and keeps the whole definition in the bundle unless it is passed to the last method, as `label()` is in `db.string().description(label())` but not in `db.string().description(label()).index()`. A property read in a definition's arguments can be removed even with the default `propertyReadSideEffects`.
|
|
215
|
+
|
|
214
216
|
`treeshake` has four switches that control how unused code is removed from bundles. The values below are the SDK's defaults, which are tuned for the Tailor Platform runtime and rarely need changing. Most switches ask whether something has side effects, so `true` keeps it, while `annotations` asks whether to honor annotations, so `true` removes more:
|
|
215
217
|
|
|
216
218
|
```typescript
|
|
@@ -175,6 +175,10 @@ db.string().index();
|
|
|
175
175
|
db.string().unique();
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
+
`.unique()` and `.index()` also work on a field inside a `db.object()` that is not an array: with `.unique()` the value must be unique across rows, while `.index()` only indexes it and still allows duplicates. Inside an array of objects (`db.object(..., { array: true })`) the platform does not reject duplicate values, so both are rejected there with an error, as on an array field.
|
|
179
|
+
|
|
180
|
+
A project whose `db.object()` field already uses `.unique()` or `.index()` was deployed with the setting stored as off, so its next `tailor deploy` stops with `MIGRATION_REMOTE_DRIFT`, and `tailor tailordb migration validate` fails the same way. `tailor tailordb migration generate` reports no differences. Run `tailor deploy --no-schema-check` once to apply the setting. If stored rows already hold duplicate values for a field that gains `.unique()`, that deploy fails and the schema stays unchanged until the duplicates are resolved.
|
|
181
|
+
|
|
178
182
|
### Relations
|
|
179
183
|
|
|
180
184
|
Add a relation to field with automatic index and foreign key constraint:
|
|
@@ -64,7 +64,7 @@ If your local tables and remote schema have **diverged**, reconcile them before
|
|
|
64
64
|
|
|
65
65
|
### Resetting
|
|
66
66
|
|
|
67
|
-
`tailor tailordb migration generate --init` deletes the existing `migrations/` directory and creates `0000` from the current local tables. Use it only before the project is deployed. For a deployed migration history, use [`migration rebaseline`](#re-baselining-a-deployed-migration-history), which verifies the history and connected workspace before replacing any files.
|
|
67
|
+
`tailor tailordb migration generate --init` deletes the existing `migrations/` directory of every namespace with migrations configured and creates `0000` from the current local tables. Add `--namespace <name>` to reset only that namespace and leave the others untouched. Use it only before the project is deployed. For a deployed migration history, use [`migration rebaseline`](#re-baselining-a-deployed-migration-history), which verifies the history and connected workspace before replacing any files.
|
|
68
68
|
|
|
69
69
|
## Migration Workflow
|
|
70
70
|
|
|
@@ -426,7 +426,7 @@ export const steps = {
|
|
|
426
426
|
- Each step runs as a separate job, so steps cannot hand data to each other through module-level variables; read what a step needs from the database.
|
|
427
427
|
- `MigrationSteps` is declared by `db.ts` files generated by this SDK version. With an older `db.ts`, annotate each `run` parameter with `Transaction` instead.
|
|
428
428
|
|
|
429
|
-
A script with a single step runs like a `main` script: one job and one transaction, and a failure inside the transaction rolls its data changes back.
|
|
429
|
+
A script with a single step runs like a `main` script: one job and one transaction, and a failure inside the transaction rolls its data changes back. The migration is recorded as in progress from the start of the script until its checkpoint is committed or its failure is rolled back, so that a deploy that loses track of the run leaves it for you to settle rather than running it again (see [Failure Recovery](#failure-recovery)). If the post-migration schema changes fail after the transaction committed, the schema is restored to its state before the migration but the data changes stay, so the next deploy runs the step again and the step must tolerate rows it already migrated. The rules below apply once the script has two or more steps. A migration that an earlier deploy already left in progress keeps running step by step until it completes, even if the script has since been reduced to one step.
|
|
430
430
|
|
|
431
431
|
Because steps commit separately, a failure does not undo the steps that already completed:
|
|
432
432
|
|
|
@@ -437,7 +437,7 @@ Because steps commit separately, a failure does not undo the steps that already
|
|
|
437
437
|
- If the steps changed since the earlier run, or that run is no longer available, every step runs again from the beginning. See [Editing steps of a migration in progress](#editing-steps-of-a-migration-in-progress).
|
|
438
438
|
- If every step completed but the post-migration schema changes fail (for example, a field the migration makes required still has empty values), the migration also stays in progress with its pre-migration schema, and the next deploy retries those schema changes without running the steps again.
|
|
439
439
|
- To run a completed step again (because it had a bug, or to fix rows the post-migration schema changes reject), change the steps: rename that step and update the `dependsOn` lists that name it, or add a step that fixes the rows. Every step then runs again from the beginning, so this relies on every step being safe to run again; to keep the other completed steps from running again, skip them as described below.
|
|
440
|
-
- While a migration is in progress, `migration set`, `migration sync`, and `migration rebaseline` refuse to run, and `migration test` refuses to use that workspace as its source. Finish
|
|
440
|
+
- While a migration is in progress, `migration set`, `migration sync`, and `migration rebaseline` refuse to run, and `migration test` refuses to use that workspace as its source. Finish a multi-step migration left in progress with `tailor deploy` first, or settle it with `migration resolve`. A migration whose script run a deploy could not confirm is not finished by a later deploy, so settle that one with `migration resolve` (see [Settling a migration that stays in progress](#settling-a-migration-that-stays-in-progress)). The one exception to these refusals is `migration set <N>` with the in-progress migration's own number: it marks that migration as completed and clears its in-progress record. Use it only when the migration's schema changes are already applied, for example after the deploy reported that the checkpoint write could not be confirmed.
|
|
441
441
|
|
|
442
442
|
#### Editing steps of a migration in progress
|
|
443
443
|
|
|
@@ -483,13 +483,15 @@ export const steps = {
|
|
|
483
483
|
|
|
484
484
|
### Settling a migration that stays in progress
|
|
485
485
|
|
|
486
|
-
When you do not want to
|
|
486
|
+
A deploy resumes a multi-step migration left in progress. When you do not want it to — you abandoned the migration, or you repaired the data by hand — settle the migration with `tailor tailordb migration resolve`. Pass exactly one of two options:
|
|
487
487
|
|
|
488
488
|
- `--rollback` sends the schema of the migration before the failed one, clears the in-progress record, and leaves the checkpoint where it was. The next `tailor deploy` runs the failed migration again from its first step, so every step must be safe to run again. Data changes made by steps that already completed are not undone, and tables that exist only in the failed migration's schema are deleted with their data.
|
|
489
489
|
- `--complete` sends the schema of the failed migration itself, clears the in-progress record, and moves the checkpoint to that migration, without running its `migrate.ts` again. Repair the data first, for example with `tailor query`, and make sure no record lacks a value for a field the migration makes required: the update is rejected while such a record exists, and the migration stays in progress.
|
|
490
490
|
|
|
491
491
|
Tables that the failed migration removes are deleted with their data under `--complete`. The command refuses to run while an execution of the failed migration is still running; wait for it to finish first. Both options take the namespace's tables out of [maintenance mode](#maintenance-mode) and remove the temporary resources of the failed run. The command shows what it will change and asks for confirmation (`--yes` skips it). As with `migration sync`, the local migration history must reproduce the current table definitions, so settle the migration before you change the tables. If sending the schema stops partway, run the same command again.
|
|
492
492
|
|
|
493
|
+
The same command settles a migration whose script run a deploy could not confirm (see [Failure Recovery](#failure-recovery)). A deploy does not resume such a migration; it stops until this command settles it. The command reads how that run ended and shows it before asking for confirmation. Pass `--complete` when the run succeeded, and `--rollback` when it failed, was canceled, or did not start; `--rollback` deletes the tables and fields the migration introduced together with the data the script wrote to them, and the next deploy runs the script again. The command warns when the option you passed does not fit how the run ended, or when it cannot read the run.
|
|
494
|
+
|
|
493
495
|
## Supported Schema Changes
|
|
494
496
|
|
|
495
497
|
| Change Type | Breaking? | Migration Script? | Notes |
|
|
@@ -754,8 +756,9 @@ Maintenance mode restricts GraphQL writes and record events only. Resolvers, exe
|
|
|
754
756
|
|
|
755
757
|
- If a migration fails, the tables leave maintenance mode before the error is reported: they return to the settings of the last checkpoint that completed. A migration that did not reach its checkpoint returns existing tables to their previous settings and keeps the tables it created in maintenance mode until a later deploy applies it. The settings are not restored if the checkpoint number or migration history changed concurrently, or if checkpoint ownership cannot be verified. A table left behind by a failed post-checkpoint deletion also stays in maintenance mode for manual recovery.
|
|
756
758
|
- A [multi-step migration](#splitting-a-migration-into-steps) left in progress keeps its tables in maintenance mode until a deploy completes it.
|
|
759
|
+
- A migration whose script run a deploy could not confirm keeps its tables in maintenance mode until you settle it with `tailor tailordb migration resolve` (see [Failure Recovery](#failure-recovery)).
|
|
757
760
|
- With `"deploy"`, if a later part of the deploy fails, the tables leave maintenance mode before the error is reported. When the deploy ends maintenance mode, it leaves the tables of a namespace unchanged if that namespace's checkpoint number or migration history changed concurrently, or if checkpoint ownership cannot be verified, and reports it.
|
|
758
|
-
- If the deploy process is interrupted after a namespace's migrations completed but before maintenance mode ended, that namespace's tables stay in maintenance mode until a later `tailor deploy` releases them when it applies its TailorDB changes, before it replaces resolvers and executors. A namespace whose migrations had not all completed is not released this way: the next deploy resumes a multi-step migration left in progress, and otherwise reports remote schema drift (see [Failure Recovery](#failure-recovery)).
|
|
761
|
+
- If the deploy process is interrupted after a namespace's migrations completed but before maintenance mode ended, that namespace's tables stay in maintenance mode until a later `tailor deploy` releases them when it applies its TailorDB changes, before it replaces resolvers and executors. A namespace whose migrations had not all completed is not released this way: the next deploy resumes a multi-step migration left in progress, stops at a migration whose script was running until you settle it, and otherwise reports remote schema drift (see [Failure Recovery](#failure-recovery)).
|
|
759
762
|
|
|
760
763
|
#### Keeping maintenance mode short
|
|
761
764
|
|
|
@@ -932,7 +935,9 @@ A script that exports `steps` follows different rules once one of its steps has
|
|
|
932
935
|
|
|
933
936
|
The rollback is best-effort per table; if reverting a table fails, a warning is logged and the original migration error is still reported. The next deploy then stops with remote schema drift on that table. Run `tailor tailordb migration validate` to see which tables differ, return the namespace to its checkpoint with `tailor tailordb migration sync <N>`, where `<N>` is the checkpoint `tailor tailordb migration status` reports, and deploy again. `sync` deletes the tables and fields that are not in that migration's snapshot, together with any rows the failed migration wrote to them; the next deploy runs the failed migration again.
|
|
934
937
|
|
|
935
|
-
If `tailor deploy` cannot tell whether a `main` script ran, for example because the connection dropped while it started or waited for the script, it does not roll anything back: the pre-migration schema changes stay, the namespace's tables stay in [maintenance mode](#maintenance-mode) if it is on, and the deploy reports that it could not confirm the outcome.
|
|
938
|
+
If `tailor deploy` cannot tell whether a `main` script ran, for example because the connection dropped while it started or waited for the script, it does not roll anything back: the pre-migration schema changes stay, the namespace's tables stay in [maintenance mode](#maintenance-mode) if it is on, the migration stays recorded as in progress, and the deploy reports that it could not confirm the outcome. The same holds when the deploy process stops while the script runs. Until you settle the migration, `tailor deploy` stops before changing anything, including the other namespaces and resources of the application, and reports how the run stands, even with `--no-schema-check`; `migration sync` and `migration rebaseline` refuse to run, and `tailor tailordb migration status` reports the migration as in progress. Run `tailor workflow executions --workflow-name <name>` with the workflow name the error reports until the execution has finished. If it succeeded, run `tailor tailordb migration resolve --complete`, which applies the migration's schema without running the script again; otherwise run `tailor tailordb migration resolve --rollback`, and the next deploy runs the script again. See [Settling a migration that stays in progress](#settling-a-migration-that-stays-in-progress). `migration set <N>` with the migration's own number also marks it as completed, but it does not check the run or apply the schema, so use it only when the run succeeded and the post-migration schema is already in place.
|
|
939
|
+
|
|
940
|
+
If the post-migration schema changes fail after a `main` script succeeded and the deploy cannot clear the in-progress record, it keeps the pre-migration schema instead of rolling it back, so the data the script wrote stays. Settle the migration as above: `--complete` once the data meets the migration's schema, or `--rollback`.
|
|
936
941
|
|
|
937
942
|
`migration sync` refuses to run while a migration is in progress. When a steps migration's post-migration schema changes fail and the deploy cannot return its tables to the pre-migration schema, it logs a warning, and the next deploy stops with remote schema drift on those tables. Run `tailor tailordb migration validate` from a checkout of the deployed migration history. If the only issue it reports is that drift, run `tailor deploy --no-schema-check`: the deploy applies the pre-migration schema again, skips the completed steps unless the steps changed, and retries the post-migration schema changes. `--no-schema-check` skips the schema checks of every namespace, so do not use it while `validate` reports any other issue.
|
|
938
943
|
|
|
@@ -1056,7 +1061,7 @@ npm install -D @electric-sql/pglite
|
|
|
1056
1061
|
|
|
1057
1062
|
The generated `db.pglite.ts` exports the `CREATE TABLE` script for the same schema `db.ts` types — the tables as the pre-migration phase leaves them while `migrate.ts` runs, including relaxed constraints, renamed fields under both names, and retained removed fields. Run it once on the PGlite instance, stage rows, then run the script in a transaction. `tailor tailordb migration script <N> --with-test` scaffolds this test too when `@electric-sql/pglite` is installed. Type the instance with `Unmigrated<Database>` rather than `Database`: `db.ts` types a column the migration makes required as `T | null` on read but `T` on write (and an enum it narrows as the old values on read but the new ones on write), so that `migrate.ts` cannot write what the migration is removing — which would also stop the test from staging the rows the script has to convert. `Unmigrated` lets every column be written with whatever it can still be read as; `main` still receives a `Transaction<Database>`.
|
|
1058
1063
|
|
|
1059
|
-
Relations are enforced as on the platform: a row that points at a parent that does not exist is rejected. Write the records the test starts from inside `prepareFixtures`, which leaves relations unchecked while it runs, so you can stage rows that predate a relation, such as rows whose parent does not exist that the script repairs. Relations are checked again when it returns, so the script itself still cannot write a missing parent. NOT NULL, UNIQUE, and CHECK constraints stay enforced. A relation is left unenforced while the pre-migration schema cannot satisfy it: when a pending type change leaves the field a different type from its target, when the migration retargets the relation to another table, or when the target field's unique constraint is still withheld. How relations on array fields and inside nested objects behave is described under [Real SQL execution with PGlite](../../testing.md#real-sql-execution-with-pglite-mocktailordbwithpglite).
|
|
1064
|
+
Relations are enforced as on the platform: a row that points at a parent that does not exist is rejected. Write the records the test starts from inside `prepareFixtures`, which leaves relations unchecked while it runs, so you can stage rows that predate a relation, such as rows whose parent does not exist that the script repairs. Relations are checked again when it returns, so the script itself still cannot write a missing parent. The same holds in reverse: the script cannot delete a parent that a row still points at, or change the key a row points at, so delete rows in the opposite order of staging them. NOT NULL, UNIQUE, and CHECK constraints stay enforced. A relation is left unenforced while the pre-migration schema cannot satisfy it: when a pending type change leaves the field a different type from its target, when the migration retargets the relation to another table, or when the target field's unique constraint is still withheld. How relations on array fields and inside nested objects behave is described under [Real SQL execution with PGlite](../../testing.md#real-sql-execution-with-pglite-mocktailordbwithpglite).
|
|
1060
1065
|
|
|
1061
1066
|
```typescript
|
|
1062
1067
|
// migrations/0005/migrate.pglite.test.ts
|
package/docs/testing.md
CHANGED
|
@@ -209,15 +209,15 @@ test("upserts against real rows", async () => {
|
|
|
209
209
|
});
|
|
210
210
|
```
|
|
211
211
|
|
|
212
|
-
The generated columns follow the Kysely types, not TailorDB's storage: `text` for string and enum fields, `timestamptz` for datetime, `date` and `time` for date and time, `numeric` for decimal, rounded to the configured scale and read back with exactly that many fractional digits, `jsonb` for nested objects (and arrays of them), Postgres arrays for other array fields. `id` is a generated `uuid` primary key, `.unique()` fields and unique `.indexes()` are enforced, so `ON CONFLICT` upserts behave, and `.default()` values become column defaults (`"now"` becomes the current time). `.serial()` fields are assigned by the database from the configured `start`, `maxValue`, and format. Relations are enforced as the platform does: a row that points at a parent that does not exist is rejected with an error containing `violates foreign key constraint`, so create parent rows before their children. This includes relations on array fields and on fields inside nested objects.
|
|
212
|
+
The generated columns follow the Kysely types, not TailorDB's storage: `text` for string and enum fields, `timestamptz` for datetime, `date` and `time` for date and time, `numeric` for decimal, rounded to the configured scale and read back with exactly that many fractional digits, `jsonb` for nested objects (and arrays of them), Postgres arrays for other array fields. `id` is a generated `uuid` primary key, `.unique()` fields, `.unique()` fields inside `db.object()`, and unique `.indexes()` are enforced, so `ON CONFLICT` upserts behave, and `.default()` values become column defaults (`"now"` becomes the current time). `.serial()` fields are assigned by the database from the configured `start`, `maxValue`, and format. Relations are enforced as the platform does: a row that points at a parent that does not exist is rejected with an error containing `violates foreign key constraint`, so create parent rows before their children. This includes relations on array fields and on fields inside nested objects. The reverse holds too: deleting a parent that a row still points at, or changing the key a row points at, is rejected with an error containing `violates foreign key constraint`, so delete child rows before their parents.
|
|
213
213
|
|
|
214
214
|
What the script cannot reproduce:
|
|
215
215
|
|
|
216
216
|
- Hooks, validations, and permissions do not run. A required field whose value only its own field-level create hook supplies is created nullable, so inserts that omit it succeed; give it a `.default()` if the test reads it back. A field filled by a table-level hook stays `NOT NULL`, as its Kysely type still requires it on insert.
|
|
217
|
-
- Relations on array fields and on fields inside nested objects, and relations from a field whose type differs from the field it points at (such as a `string` field related to `id`), are checked only when a row is written. Deleting a parent that such a row still points at is rejected by the platform but not by PGlite, and changing the parent's `id` is not checked either, so a test must not expect PGlite to reject them.
|
|
218
217
|
- Serial formats are reproduced for a single `%d`, `%x`, or `%X` specifier with an optional zero-padded width; an octal `%o` format fails generation with an error naming the field.
|
|
219
218
|
- `gapless` is not reproduced: the numbers come from a sequence, so an insert that fails still uses up its number.
|
|
220
219
|
- A date or datetime inside a nested object reads back as a string from `jsonb`, not a `Date`, or a `Temporal.PlainDate` or `Temporal.Instant` under `kyselyTypePlugin({ temporal: true })`, although the platform returns those types.
|
|
220
|
+
- A `.unique()` date, datetime, or time inside a nested object compares the stored text, so two spellings of the same instant (`2026-01-01T00:00:00Z` and `2026-01-01T01:00:00+01:00`) are both accepted, although the platform rejects the second. Use one spelling in tests.
|
|
221
221
|
- On a persistent PGlite (`dataDir`), tables created by an earlier run are kept as they were; drop them or start from an empty directory after changing a table definition.
|
|
222
222
|
|
|
223
223
|
To hand-write DDL instead — for a table not in the schema, or to add a constraint — run your own statements after the script, or without it.
|