@tailor-platform/sdk 2.37.0 → 2.38.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.
Files changed (93) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/dist/{application-83WVdH85.mjs → application-Bz80INH4.mjs} +1 -1
  3. package/dist/application-CeqD1OK-.mjs +207 -0
  4. package/dist/application-CeqD1OK-.mjs.map +1 -0
  5. package/dist/cli/commands/deploy/deploy.d.mts +1 -0
  6. package/dist/cli/commands/deploy/tailordb/migration-validation.d.mts +2 -0
  7. package/dist/cli/lib.d.mts +2 -2
  8. package/dist/cli/lib.mjs +1 -1
  9. package/dist/cli/lib.mjs.map +1 -1
  10. package/dist/cli/main.mjs +66 -60
  11. package/dist/cli/main.mjs.map +1 -1
  12. package/dist/cli/shared/args.d.mts +14 -5
  13. package/dist/cli/shared/client.d.mts +14 -3
  14. package/dist/cli/shared/error-json.d.mts +12 -26
  15. package/dist/client-CHXix4LD.mjs +1 -0
  16. package/dist/client-DOQv-BP8.mjs +2 -0
  17. package/dist/client-DOQv-BP8.mjs.map +1 -0
  18. package/dist/completion/zsh-worker.zsh +133 -69
  19. package/dist/configure/services/executor/operation.d.mts +5 -4
  20. package/dist/configure/services/http-adapter/http-adapter.d.mts +1 -1
  21. package/dist/configure/services/index.d.mts +0 -1
  22. package/dist/configure/services/tailordb/types.d.mts +9 -0
  23. package/dist/context-DSi5kfqr.mjs +23 -0
  24. package/dist/context-DSi5kfqr.mjs.map +1 -0
  25. package/dist/context-OOASEQLA.mjs +1 -0
  26. package/dist/{crashreport-D_wf4GZh.mjs → crashreport-CQTAlnbA.mjs} +2 -2
  27. package/dist/{crashreport-D_wf4GZh.mjs.map → crashreport-CQTAlnbA.mjs.map} +1 -1
  28. package/dist/crashreport-GRnWyDnF.mjs +1 -0
  29. package/dist/{errors-Dmdnq0zi.mjs → errors-9OOL3xOM.mjs} +6 -5
  30. package/dist/errors-9OOL3xOM.mjs.map +1 -0
  31. package/dist/field_behavior_pb-B196sUx6.mjs +2 -0
  32. package/dist/field_behavior_pb-B196sUx6.mjs.map +1 -0
  33. package/dist/{kysely-type-DVL90_oX.mjs → kysely-type-DhAZqdQg.mjs} +14 -10
  34. package/dist/kysely-type-DhAZqdQg.mjs.map +1 -0
  35. package/dist/notification_resource_pb-BZ0hCA01.mjs +1 -0
  36. package/dist/notification_resource_pb-Dwzah7gO.mjs +2 -0
  37. package/dist/notification_resource_pb-Dwzah7gO.mjs.map +1 -0
  38. package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
  39. package/dist/register-ts-hook-CXYYYgCl.mjs +1094 -0
  40. package/dist/register-ts-hook-CXYYYgCl.mjs.map +1 -0
  41. package/dist/repl-editor-Bposemei.mjs +2 -0
  42. package/dist/repl-editor-Bposemei.mjs.map +1 -0
  43. package/dist/resource_pb-elY668ZB.mjs +2 -0
  44. package/dist/resource_pb-elY668ZB.mjs.map +1 -0
  45. package/dist/{secret-file-DiuEcLFP.mjs → secret-file-CSXzcg4c.mjs} +2 -2
  46. package/dist/{secret-file-DiuEcLFP.mjs.map → secret-file-CSXzcg4c.mjs.map} +1 -1
  47. package/dist/service-B2vx6CGM.mjs +2 -0
  48. package/dist/{service-DDrbdyd-.mjs.map → service-B2vx6CGM.mjs.map} +1 -1
  49. package/dist/service-DB-RHn25.mjs +9 -0
  50. package/dist/service-DB-RHn25.mjs.map +1 -0
  51. package/dist/service-DsAWXbVX.mjs +1 -0
  52. package/dist/service_pb-Bethc2NW.mjs +1 -0
  53. package/dist/service_pb-CfpSriCy.mjs +2 -0
  54. package/dist/service_pb-CfpSriCy.mjs.map +1 -0
  55. package/dist/validation-errors-DqCeUW4L.mjs +3 -0
  56. package/dist/validation-errors-DqCeUW4L.mjs.map +1 -0
  57. package/{LICENSE → dist/vendor/graphql/LICENSE} +6 -6
  58. package/dist/vendor/graphql/language/KindTypeMap.d.mts +3 -0
  59. package/dist/vendor/graphql/language/ast.d.mts +784 -0
  60. package/dist/vendor/graphql/language/kinds_.d.mts +203 -0
  61. package/dist/vendor/graphql/language/source.d.mts +46 -0
  62. package/dist/vendor/graphql/language/tokenKind.d.mts +35 -0
  63. package/dist/workspace_resource_pb-Cow7mrJY.mjs +2 -0
  64. package/dist/workspace_resource_pb-Cow7mrJY.mjs.map +1 -0
  65. package/docs/cli/application.md +13 -9
  66. package/docs/cli/notification.md +128 -0
  67. package/docs/cli/tailordb.md +26 -57
  68. package/docs/cli/workspace.md +1 -1
  69. package/docs/cli-reference.md +228 -48
  70. package/docs/github-actions.md +162 -26
  71. package/docs/services/tailordb/index.md +6 -2
  72. package/docs/services/tailordb/migration.md +53 -56
  73. package/docs/testing.md +0 -1
  74. package/package.json +14 -10
  75. package/dist/application-Cida-j1g.mjs +0 -207
  76. package/dist/application-Cida-j1g.mjs.map +0 -1
  77. package/dist/configure/services/http-adapter/index.d.mts +0 -2
  78. package/dist/crashreport-C2AcQNTe.mjs +0 -1
  79. package/dist/errors-Dmdnq0zi.mjs.map +0 -1
  80. package/dist/kysely-type-DVL90_oX.mjs.map +0 -1
  81. package/dist/register-ts-hook-Ht4zCseV.mjs +0 -1115
  82. package/dist/register-ts-hook-Ht4zCseV.mjs.map +0 -1
  83. package/dist/repl-editor-DkrCZmmg.mjs +0 -2
  84. package/dist/repl-editor-DkrCZmmg.mjs.map +0 -1
  85. package/dist/service-CZ0EdD2-.mjs +0 -10
  86. package/dist/service-CZ0EdD2-.mjs.map +0 -1
  87. package/dist/service-DDrbdyd-.mjs +0 -2
  88. package/dist/service-WhSyhaho.mjs +0 -1
  89. package/dist/service_pb-BMHhVot2.mjs +0 -1
  90. package/dist/service_pb-BxMSK0gg.mjs +0 -2
  91. package/dist/service_pb-BxMSK0gg.mjs.map +0 -1
  92. package/dist/workspace_resource_pb-7smKERdZ.mjs +0 -2
  93. package/dist/workspace_resource_pb-7smKERdZ.mjs.map +0 -1
@@ -450,6 +450,7 @@ Because steps commit separately, a failure does not undo the steps that already
450
450
  - Fix the failing step and run `tailor deploy` again. The deploy resumes the migration: completed steps do not run again, and the failed step and the steps after it run with the updated script. A completed step is treated like an applied migration — editing it afterwards does not run it again.
451
451
  - 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).
452
452
  - 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.
453
+ - If the deploy stops during or after the post-migration schema changes but before it records the migration as applied, for example because the process was killed or recording the checkpoint failed, the migration also stays in progress, with each table in either its pre-migration or its post-migration schema. The next deploy resumes it: it applies the pre-migration schema again, so a field the migration makes required is optional until the post-migration schema changes are applied again. Completed steps do not run again unless you add, remove, or rename a step, change the order the steps run in, or the earlier run is no longer available (see [Editing steps of a migration in progress](#editing-steps-of-a-migration-in-progress)).
453
454
  - 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.
454
455
  - Finish a multi-step migration left in progress with `tailor deploy`, or settle it with `migration resolve`. Until then, the commands listed in [Settling a migration that stays in progress](#settling-a-migration-that-stays-in-progress) refuse to run.
455
456
 
@@ -473,6 +474,7 @@ tailor deploy --migration-skip-steps main-db/backfillUser,main-db/backfillInvoic
473
474
  - A skipped step is reported as completed and is not run. Only steps that succeeded in the migration's earlier run can be skipped, so a step you renamed cannot be.
474
475
  - The option applies to the migration an earlier deploy left in progress. Deploy fails before changing anything when an entry names a step that did not succeed, a step the migration does not define, a namespace without a migration in progress, or a namespace that no deployed config defines. It also fails when the earlier run's step results cannot be read, because then it cannot confirm which steps succeeded; deploy again to retry.
475
476
  - It takes effect for the deploy you pass it to. If that run fails, the next `tailor deploy` resumes it as usual, and the skipped steps stay completed without passing the option again.
477
+ - To check the entries before deploying, pass the same option to `tailor tailordb migration validate`. It reports the entries that deploy would reject for the namespaces of the config it validates.
476
478
 
477
479
  Write every step so that running it again is safe: besides the cases above, a step can run a second time when a deploy is interrupted right after it commits. Use `where` clauses that skip rows a step already migrated, as in the example. Rows written while a migration is in progress are not seen by steps that already completed. [Maintenance mode](#maintenance-mode) blocks GraphQL writes but not the writes your resolvers, executors, or workflows make through Kysely, and without it GraphQL clients can write too, so stop such writers until the migration finishes or write steps that tolerate them.
478
480
 
@@ -493,11 +495,11 @@ export const steps = {
493
495
  - Steps that already completed stay committed. Their changes to existing fields remain in the database, and nothing is recorded as in progress, so the next deploy runs every step again from the beginning. Every step must be safe to run again, or a rolled-back run applies those changes twice. Do not rely on data a step wrote to a field or table that the rollback removed.
494
496
  - If `tailor deploy` cannot tell whether a step ran, or the migration's workflow execution may still be running (for example the connection to it was lost), it does not roll anything back even with `"rollback"`: the migration stays in progress as described for a `main` script below. A migration an earlier deploy left in progress is rolled back only when its earlier run is confirmed to have ended, so a failure before that run is inspected, such as a schema error while applying the Pre-phase, keeps it in progress.
495
497
  - If the in-progress record cannot be cleared, `tailor deploy` does not roll the schema back. It logs a warning and keeps the migration in progress with its tables in maintenance mode, because a record that outlives a rollback would make the next deploy resume against a schema its completed steps no longer match. Deploy again to resume it as described above, or roll it back without deploying with `tailor tailordb migration resolve --rollback`.
496
- - If the schema or GraphQL permission of some tables cannot be rolled back, `tailor deploy` still fails with the step's original error. It also warns `Migration <namespace>/<N> was not rolled back completely` and lists the tables that need manual repair, and separately the tables whose GraphQL permission could not be set back. Check them in the workspace and repair them by hand; deploying again does not release them.
498
+ - If the schema or GraphQL permission of some tables cannot be rolled back, `tailor deploy` still fails with the step's original error. It also warns `Migration <namespace>/<N> was not rolled back completely` and lists the tables that need manual repair, and separately the tables whose GraphQL permission could not be set back. A table that still has the migration's pre-migration schema does not stop the next deploy, which runs every step again (see [Failure Recovery](#failure-recovery)). Otherwise the next deploy stops with remote schema drift, so check the tables in the workspace and repair them by hand.
497
499
 
498
500
  ### Settling a migration that stays in progress
499
501
 
500
- 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. `tailor tailordb migration status` reports the migration as in progress and lists the commands that get it out of that state: `tailor deploy` to resume a multi-step migration, and `tailor tailordb migration resolve` to roll it back or complete it. For a migration whose script run a deploy could not confirm, it lists only `resolve`, because a deploy does not resume that migration.
502
+ While a migration is in progress, `migration sync` and `migration rebaseline` refuse to run, and `migration test` refuses to use that workspace as its source. `tailor tailordb migration status` reports the migration as in progress and lists the commands that get it out of that state: `tailor deploy` to resume a multi-step migration, and `tailor tailordb migration resolve` to roll it back or complete it. For a migration whose script run a deploy could not confirm, it lists only `resolve`, because a deploy does not resume that migration.
501
503
 
502
504
  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:
503
505
 
@@ -506,6 +508,8 @@ A deploy resumes a multi-step migration left in progress. When you do not want i
506
508
 
507
509
  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.
508
510
 
511
+ `--rollback` also accepts a migration that no deploy recorded as in progress, but whose pre-migration schema or maintenance mode a deploy left in place: the deploy stopped before it recorded the migration, or failed to roll it back or to end maintenance mode (see [Maintenance mode](#maintenance-mode)). The command runs only when every table of the namespace has the schema of the checkpoint or the migration's pre-migration schema. With maintenance mode on, a table that has the pre-migration schema must also be in maintenance mode. If only maintenance mode is left, the command runs only when a local migration follows the checkpoint. A deploy that is still running looks the same until it records the migration, so make sure none is running. `--complete` refuses such a migration.
512
+
509
513
  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.
510
514
 
511
515
  ## Supported Schema Changes
@@ -771,11 +775,13 @@ Maintenance mode restricts GraphQL writes and record events only. Resolvers, exe
771
775
 
772
776
  **When a deploy stops early:**
773
777
 
774
- - 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 drops the tables it created (see [Failure Recovery](#failure-recovery)). A created table that the rollback cannot drop stays in maintenance mode, and the deploy names it for manual repair. 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.
778
+ - 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 drops the tables it created (see [Failure Recovery](#failure-recovery)). A created table that the rollback cannot drop stays in maintenance mode, and the deploy names it; deploying again runs the migration again. 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 stays in maintenance mode until the next deploy deletes it (see [Failure Recovery](#failure-recovery)).
779
+ - With `--no-schema-check`, if a local table definition that the migrations do not include cannot be applied after they complete, the existing tables leave maintenance mode with the definitions of the last migration before the error is reported (see [Schema verification](#schema-verification)).
775
780
  - A [multi-step migration](#splitting-a-migration-into-steps) left in progress keeps its tables in maintenance mode until a deploy completes it.
776
781
  - 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)).
777
782
  - 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.
778
- - 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)), except when an earlier checkpoint of the interrupted deploy recorded the maintenance mode. Every migration checkpoint of a namespace records it, so with pending migrations `0001` and `0002`, a deploy interrupted right after the checkpoint of `0001` does not report drift: the next deploy keeps the tables in maintenance mode while it applies `0002` and releases them afterwards (with `"deploy"`, after the whole deploy).
783
+ - 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 stops at a migration whose script was running until you settle it. Every migration checkpoint of a namespace records the maintenance mode, so with pending migrations `0001` and `0002`, a deploy interrupted right after the checkpoint of `0001` leaves the tables in maintenance mode; the next deploy keeps them there while it applies `0002` and releases them afterwards (with `"deploy"`, after the whole deploy).
784
+ - A deploy interrupted before it recorded a migration as in progress (for example, right after the migration's pre-migration schema changes reached some or all of its tables) leaves no record of that migration. The next deploy accepts tables that have the schema of the checkpoint or the migration's pre-migration schema, and runs the migration again from the start. To return the tables to the checkpoint without deploying, run `tailor tailordb migration resolve --rollback` (see [Settling a migration that stays in progress](#settling-a-migration-that-stays-in-progress)).
779
785
 
780
786
  #### Keeping maintenance mode short
781
787
 
@@ -788,17 +794,17 @@ Maintenance mode lasts for the whole migration job, including the time the platf
788
794
 
789
795
  When [maintenance mode](#maintenance-mode) is on, `tailor deploy` reports how long the migrating namespaces' tables were restricted, split into phases. With `"deploy"`, the window also includes the remaining deployment changes and ends when their restrictions are lifted. No maintenance report is emitted with `maintenanceMode: false`.
790
796
 
791
- | Phase | Covers |
792
- | ------------------ | ---------------------------------------------------------------------------------------- |
793
- | `restrict` | Putting the tables into maintenance mode |
794
- | `pre-migration` | Pre-migration schema changes |
795
- | `job setup` | Bundling `migrate.ts` and registering it as a job |
796
- | `waiting to start` | Time when the platform has accepted the job but none of its code runs yet |
797
- | `running` | Time when the script runs |
798
- | `job cleanup` | Collecting the script's logs and removing its job, unless its steps run as separate jobs |
799
- | `post-migration` | Post-migration schema changes, the checkpoint update, and cleanup |
800
- | `remaining deploy` | With `"deploy"`, applying the remaining deployment changes while tables stay restricted |
801
- | `restore` | Taking the tables out of maintenance mode |
797
+ | Phase | Covers |
798
+ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
799
+ | `restrict` | Putting the tables into maintenance mode |
800
+ | `pre-migration` | Pre-migration schema changes |
801
+ | `job setup` | Bundling `migrate.ts` and registering it as a job |
802
+ | `waiting to start` | Time when the platform has accepted the job but none of its code runs yet |
803
+ | `running` | Time when the script runs |
804
+ | `job cleanup` | Collecting the script's logs and removing its job, unless its steps run as separate jobs |
805
+ | `post-migration` | Post-migration schema changes, the checkpoint update, cleanup, and [local definitions](#schema-verification) no migration includes |
806
+ | `remaining deploy` | With `"deploy"`, applying the remaining deployment changes while tables stay restricted |
807
+ | `restore` | Taking the tables out of maintenance mode |
802
808
 
803
809
  Phases that repeat across several migrations are added up. The report is printed only after the migrations succeed and the tables leave maintenance mode; when a migration fails, deploy reports the error instead (see [Failure Recovery](#failure-recovery)). When deploy resumes a migration that an earlier deploy left in progress, the tables were already in maintenance mode before it started, and the report covers only this deploy. A job can be reported as started on the platform well before its code runs, so deploy tells waiting from running by a line every job of a migration logs before your script: `[tailor-sdk] migration script started`. You may see that line in function execution logs; deploy leaves it out of the logs it prints. A script that exports [`steps`](#splitting-a-migration-into-steps) waits for each step's job to start, and that time counts as `waiting to start` too. Time when deploy cannot tell whether the script is running — because the run or a running job's logs could not be read, or because an older SDK version started the run and it never logs the line — is reported as `waiting to start or running` instead.
804
810
 
@@ -809,7 +815,7 @@ Deploy checks the run every few seconds, so a boundary between `waiting to start
809
815
  Before running migrations, `apply` performs two checks:
810
816
 
811
817
  1. **Local schema check** — your current table definitions must match the latest snapshot in `migrations/`. If they don't, you forgot to run `migration generate`.
812
- 2. **Remote schema check** — the deployed schema is reconstructed from migration history; the actual remote schema must match. Drift here means someone applied a different set of migrations or edited the schema out-of-band. A namespace that has tables but no migration label yet must match `0000` (see [Adding migrations to an existing project](#adding-migrations-to-an-existing-project)).
818
+ 2. **Remote schema check** — the deployed schema is reconstructed from migration history; the actual remote schema must match. Drift here means someone applied a different set of migrations or edited the schema out-of-band. A namespace that has tables but no migration label yet must match `0000` (see [Adding migrations to an existing project](#adding-migrations-to-an-existing-project)). When no migration is recorded as in progress, a table may also have the pre-migration schema of the next migration, which an interrupted or failed deploy left; the deploy then runs that migration again from the start (see [Maintenance mode](#maintenance-mode)). With maintenance mode on, such a table must be in maintenance mode.
813
819
 
814
820
  On drift you'll see something like:
815
821
 
@@ -822,7 +828,7 @@ Namespace: tailordb
822
828
  - Field 'email': required: remote=false, expected=true
823
829
  ```
824
830
 
825
- The error also points you at `migration status`, `migration generate`, `migration sync`, and `migration set` — see [Remote schema drift detected](#remote-schema-drift-detected) for which one applies.
831
+ The error also points you at `migration status`, `migration generate`, and `migration sync` — see [Remote schema drift detected](#remote-schema-drift-detected) for which one applies.
826
832
 
827
833
  To run the same checks without deploying — plus migration file integrity (numbering, parseable contents, a `migrate.ts` or a recorded `--no-script` acknowledgment for every migration that requires a script, and no `TODO()` call left in a `migrate.ts`):
828
834
 
@@ -840,6 +846,8 @@ To bypass both checks during deploy (not recommended outside of recovery scenari
840
846
  tailor deploy --no-schema-check
841
847
  ```
842
848
 
849
+ With pending migrations, each migration still applies its own table definitions in its [phases](#per-migration-phases), so `migrate.ts` sees the schema it was written for. Local table definitions that differ from the last pending migration are applied after every pending migration has completed, and the deploy lists those tables. With [maintenance mode](#maintenance-mode) on, existing tables stay in it until their local definitions are applied. If one of them cannot be applied, for example a unique constraint on a field whose records hold duplicate values, the deploy fails with `MIGRATION_LOCAL_DEFINITIONS_FAILED`: the migrations stay applied, tables already created for their local definitions remain, and the existing tables keep the definitions of the last migration and leave maintenance mode.
850
+
843
851
  `--no-schema-check` does not bypass the check that the remote migration checkpoint is in the local migration history. See ["Remote migration checkpoint is not in the local migration history" error](#remote-migration-checkpoint-is-not-in-the-local-migration-history-error).
844
852
 
845
853
  ### Example output
@@ -874,36 +882,15 @@ tailor tailordb migration rebaseline --namespace tailordb
874
882
 
875
883
  The command validates the migration files, verifies that replaying the latest migration exactly reproduces the local table definitions, and checks that the connected workspace is at that latest migration with no schema drift. After confirmation, it replaces the local history with the reconstructed baseline, records a new migration history ID in both `0000/schema.json` and remote metadata, and resets the connected workspace's `sdk-migration` label to `0000`. Use `--yes` only after arranging the same operational preconditions in non-interactive automation.
876
884
 
877
- When the connected workspace records another migration history ID, or one that cannot be read, the command refuses to run. Run it from a checkout of the migration history deployed to that workspace. To replace the workspace's history with the local one on purpose, first run `tailor tailordb migration set <N> --force` with the latest local migration as `<N>` (see [`migration set` Semantics](#migration-set-semantics)). When the workspace's tables differ from the latest migration, the command also refuses to run; see [Remote schema drift detected](#remote-schema-drift-detected), where `tailor tailordb migration sync <N>` rewrites the tables to the latest migration.
885
+ When the connected workspace records another migration history ID, or one that cannot be read, the command refuses to run. Run it from a checkout of the migration history deployed to that workspace. To replace the workspace's history with the local one on purpose, first run `tailor tailordb migration sync <N> --force` with the latest local migration as `<N>`, which rewrites the workspace's tables to that migration, removing the fields it does not have and deleting the tables it does not have together with their data (see [`migration sync` Semantics](#migration-sync-semantics)). When the workspace's tables differ from the latest migration, the command also refuses to run; see [Remote schema drift detected](#remote-schema-drift-detected), where `tailor tailordb migration sync <N>` rewrites the tables to the latest migration.
878
886
 
879
887
  Commit the resulting `migrations/` change before generating any new migrations. For another environment still carrying the exact checkpoint and history ID that the new baseline replaced, the next `tailor deploy` checks whether its remote schema exactly matches the new `0000`. If it does, deploy offers to reset the checkpoint to `0000` and move the environment to the new history ID before applying any later local migrations. A markerless history is eligible only for the first rebaseline, at the exact migration recorded as replaced. Any other checkpoint or history ID is rejected without changing remote metadata, even if its schema happens to match the baseline.
880
888
 
881
889
  Partial squashing is not supported: re-baselining always replaces the full history for one namespace.
882
890
 
883
- ## `migration set` Semantics
884
-
885
- `tailor tailordb migration set <N>` updates the `sdk-migration` label on the deployed namespace's metadata. **It does not modify any data or schema.** It only changes which migrations the next `apply` will consider pending. The command also records the migration history ID of the local baseline on the namespace.
886
-
887
- The command refuses to run when the namespace records a migration history ID other than the local one, or one that cannot be read, unless the namespace has neither a checkpoint nor a history ID yet. Run it from a checkout of the migration history deployed to the workspace. To write the local history over another one on purpose, for example after `migration rebaseline` re-baselined the local history but could not update the workspace, pass `--force`: the command shows the history ID it replaces, records the local history ID or, when the local history has none, removes the namespace's one, and still asks for confirmation unless you pass `--yes`.
888
-
889
- The migration number is validated before anything is sent to the remote: it must be a 4-digit value (e.g. `0001`) or a bare integer (e.g. `1`) within 0–9999, and must exist in the working tree's migration history, which is itself validated (a gapped history is rejected). `0` is always accepted as the baseline (even when no migrations directory exists yet), provided the history passes validation.
890
-
891
- | Movement | Effect on next `apply` | Effect on data |
892
- | -------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------- |
893
- | Forward (e.g., `0001` → `0003`) | Migrations `0002` and `0003` are skipped — they will not run. | None. |
894
- | Backward (e.g., `0003` → `0001`) | Migrations `0002` and `0003` become pending and will re-execute on apply. | None directly — but the re-executed scripts may rewrite data. |
895
-
896
- Use cases:
897
-
898
- - **Recovery from drift** — you investigated, manually fixed the remote, and want the SDK's bookkeeping to reflect reality.
899
- - **Re-running a faulty migration** in a development workspace — set backward, fix `migrate.ts`, apply.
900
- - **Skipping a migration** that you know was already applied out-of-band.
901
-
902
- `migration set` does not perform a true rollback. To undo a schema/data change in production, write a new forward migration that reverses it (see [Rollback Strategy](#rollback-strategy)).
903
-
904
891
  ## `migration sync` Semantics
905
892
 
906
- `tailor tailordb migration sync <N>` reconstructs the schema snapshot at migration `N` from the working tree's migration history and **overwrites the remote schema to match it**, then sets the `sdk-migration` label to `N` and records the migration history ID of the local baseline. Unlike `migration set`, it changes the remote schema as well as the bookkeeping. Like `set`, it never runs `migrate.ts` scripts itself — it only changes what the next `apply` considers pending:
893
+ `tailor tailordb migration sync <N>` reconstructs the schema snapshot at migration `N` from the working tree's migration history and **overwrites the remote schema to match it**, then sets the `sdk-migration` label to `N` and records the migration history ID of the local baseline. It never runs `migrate.ts` scripts itself — it only changes what the next `apply` considers pending:
907
894
 
908
895
  | Movement | Effect on next `apply` | Effect on data |
909
896
  | -------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
@@ -912,7 +899,7 @@ Use cases:
912
899
 
913
900
  Before anything is sent to the remote, `sync` verifies that replaying the full migration history reproduces the current local table definitions. If it does not — because migration files were edited and no longer match, or because a schema change has not been recorded with `migration generate` yet — the command fails without touching the remote. This means a rewritten migration history is validated before it can overwrite the deployed schema.
914
901
 
915
- Like `set`, `sync` refuses to run when the namespace records another migration history ID, or one that cannot be read, before it reads or changes any table. With `--force`, it overwrites both the tables and the history ID with those of the local history, and still asks for confirmation unless you pass `--yes`.
902
+ `sync` refuses to run when the namespace records another migration history ID, or one that cannot be read, before it reads or changes any table, unless the namespace has neither a checkpoint nor a history ID yet. Run it from a checkout of the migration history deployed to the workspace. To write the local history over another one on purpose, for example after `migration rebaseline` re-baselined the local history but could not update the workspace, pass `--force`: it overwrites the tables with those of the local history and replaces the history ID with the local one, or removes it when the local history has none, and still asks for confirmation unless you pass `--yes`.
916
903
 
917
904
  Because syncing backward causes already-applied scripts to re-execute on the next deploy, **write `migrate.ts` scripts to be idempotent** (see [Performance and Large Tables](#performance-and-large-tables) for resumable `where` clauses).
918
905
 
@@ -920,6 +907,8 @@ The main use cases are:
920
907
 
921
908
  - Recovering from drift after a `deploy --no-schema-check`, which deploys the local table definitions without checking them against the migration snapshots: run `migration sync <N>` to restore the remote to a known snapshot, then `tailor deploy` to apply the remaining migrations from the working tree.
922
909
  - Moving a checkpoint that `tailor deploy` reports as not in the local migration history back to that history on purpose (see ["Remote migration checkpoint is not in the local migration history" error](#remote-migration-checkpoint-is-not-in-the-local-migration-history-error)).
910
+ - Recording that the tables already match migration `N`, for example after you fixed them by hand or applied a migration outside the migration history. `sync <N>` sends the same table definitions again, so only the checkpoint changes, although its confirmation still lists the tables as updated.
911
+ - Re-running a faulty migration in a development workspace (see [Rollback Strategy](#rollback-strategy)).
923
912
 
924
913
  ## Team Workflow and CI/CD
925
914
 
@@ -945,7 +934,7 @@ When your branch and main each generated the same number, merging or rebasing st
945
934
  ### CI / CD
946
935
 
947
936
  - For non-interactive environments, pass `--yes` to `migration generate` and `--yes` to `apply`. `apply` runs migrations automatically when the `migrations/` directory is configured.
948
- - Run `tailor tailordb migration validate` in CI to catch uncommitted migrations, broken migration files, unreviewed generated normalization logic, and remote schema drift before deploying. It exits with a non-zero code when validation fails and supports `--json`. Add `--strict` to also require an explicit acknowledgment (a `migrate.ts` or a recorded `--no-script` reason) for every pending migration that can drop data, so destructive changes cannot merge unnoticed.
937
+ - Run `tailor tailordb migration validate` in CI to catch, before deploying, uncommitted migrations, broken migration files, unreviewed generated normalization logic, remote schema drift, and pending migration scripts that `tailor deploy` could not run. It exits with a non-zero code when validation fails and supports `--json`. Add `--strict` to also require an explicit acknowledgment (a `migrate.ts` or a recorded `--no-script` reason) for every pending migration that can drop data, so destructive changes cannot merge unnoticed.
949
938
  - `tailor tailordb migration status` validates the layout and file-format compatibility of the full local history, compares its history ID with the deployed namespace, and shows applied and pending migrations for a human-readable comparison. Its exit code is non-zero on invalid or incompatible files, migration history mismatches, a remote checkpoint ahead of the latest local migration, and remote read errors, so check the output.
950
939
  - Avoid running migrations in parallel against the same workspace — there is no locking. Serialize deploys per environment.
951
940
 
@@ -961,13 +950,13 @@ A script that exports `steps` follows different rules once one of its steps has
961
950
  - **The pre-migration schema changes are rolled back** to the prior checkpoint: tables that already existed are restored to their previous shape and GraphQL permissions, and tables the migration newly introduced are dropped. The workspace is left at its prior checkpoint and prior schema — not half-applied.
962
951
  - The whole `apply` aborts and the checkpoint label is not bumped. Subsequent migrations in the same run do not execute.
963
952
 
964
- 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.
953
+ The rollback is best-effort per table; if reverting a table fails, a warning is logged and the original migration error is still reported. A table left with the migration's pre-migration schema does not stop the next deploy, which runs the failed migration again from the start. This happens, for example, when the script wrote records without a value for a field the migration makes required: the platform refuses to make the field required again while such records exist. `tailor tailordb migration resolve --rollback` returns such tables to the checkpoint without deploying, once those records have a value. A table left in any other shape makes the next deploy stop 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.
965
954
 
966
955
  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`. 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), which also lists the commands that refuse to run until then.
967
956
 
968
957
  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`.
969
958
 
970
- `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.
959
+ 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. The next deploy accepts each table in either the pre-migration or the post-migration schema: it applies the pre-migration schema again, skips the completed steps unless the steps changed, and retries the post-migration schema changes.
971
960
 
972
961
  After a failure:
973
962
 
@@ -977,11 +966,13 @@ After a failure:
977
966
 
978
967
  If a migration **succeeds in script** but its reversible **post-migration schema update** fails (rare; usually a constraint violation the script should have prevented), the SDK makes the same best-effort restoration to the prior-checkpoint schema. The script's committed data changes remain, so write migration scripts to tolerate re-execution.
979
968
 
980
- Before a migration's script starts, `tailor deploy` checks that the namespace's checkpoint and migration history are still the ones it read before applying, or the checkpoint it committed itself. If another deploy or `tailor tailordb migration set` changed them in the meantime, or the deploy cannot read them, the script does not start and the migration is not recorded as in progress: the deploy handles the pre-migration schema as for a script that failed before it ran, and fails with `MIGRATION_CHECKPOINT_CONFLICT` (`MIGRATION_CHECKPOINT_UNVERIFIED` when it cannot read them). Run `tailor tailordb migration status` to see the checkpoint. Wait for the other deploy to finish, or, when no other deploy is running, return the namespace to the checkpoint the error names with `tailor tailordb migration sync <N>`, which also lifts the maintenance mode the deploy left in place, and deploy again. If the error says the checkpoint changed in a different migration history, or with a migration history label that cannot be read, `sync` also needs `--force`, which replaces the workspace's migration history ID with the local one. Pass it only when the local migration history should replace the deployed one; otherwise deploy from a checkout of the migration history deployed to the workspace.
969
+ Before a migration's script starts, `tailor deploy` checks that the namespace's checkpoint and migration history are still the ones it read before applying, or the checkpoint it committed itself. If another deploy or a `tailor tailordb migration` command changed them in the meantime, or the deploy cannot read them, the script does not start and the migration is not recorded as in progress: the deploy handles the pre-migration schema as for a script that failed before it ran, and fails with `MIGRATION_CHECKPOINT_CONFLICT` (`MIGRATION_CHECKPOINT_UNVERIFIED` when it cannot read them). Run `tailor tailordb migration status` to see the checkpoint. Wait for the other deploy to finish, or, when no other deploy is running, return the namespace to the checkpoint the error names with `tailor tailordb migration sync <N>`, which also lifts the maintenance mode the deploy left in place, and deploy again. If the error says the checkpoint changed in a different migration history, or with a migration history label that cannot be read, `sync` also needs `--force`, which replaces the workspace's migration history ID with the local one. Pass it only when the local migration history should replace the deployed one; otherwise deploy from a checkout of the migration history deployed to the workspace.
970
+
971
+ The checkpoint is advanced only after the reversible post-migration schema updates succeed. If the checkpoint write reports an error, the SDK reads it back: a matching value is treated as committed. Any other observed value leaves the post-migration schema unchanged rather than risk rolling back a concurrent deployment; a value beyond the current migration confirms a concurrent deploy, while an older or missing value means the checkpoint must be repaired before retrying, unless the value is the previous checkpoint and the multi-step migration is still recorded as in progress, which the next deploy resumes. If read-back also fails, the SDK likewise leaves the post-migration schema unchanged; verify the remote checkpoint before retrying.
981
972
 
982
- The checkpoint is advanced only after the reversible post-migration schema updates succeed. If the checkpoint write reports an error, the SDK reads it back: a matching value is treated as committed. Any other observed value leaves the post-migration schema unchanged rather than risk rolling back a concurrent deployment; a value beyond the current migration confirms a concurrent deploy, while an older or missing value means the checkpoint must be repaired before retrying. If read-back also fails, the SDK likewise leaves the post-migration schema unchanged; verify the remote checkpoint before retrying.
973
+ Removed tables are deleted only after the checkpoint is committed. The deploy records with the checkpoint that these deletions are still to run, and clears the record once they finish. If that cleanup fails or the deploy is interrupted, the checkpoint remains at the new migration, and the next deploy finishes the cleanup: it lists the tables that migration removed among the tables to delete, and deletes them and their GQL permissions with their data before it runs any pending migration. `tailor tailordb migration validate` reports them as tables the next deploy deletes. To delete them without deploying, run `tailor tailordb migration sync <N>` with the committed migration as `<N>` (when the cleanup fails, the deploy error's suggestion names the command). A same-named remote table is still reported as remote schema drift when no unfinished cleanup is recorded, for example a table created again after the cleanup completed or one left by an SDK version that did not record the cleanup, and when a later migration adds the table back; delete it with `migration sync <N>` or by hand, and then deploy again. A deploy with `--no-schema-check` does not finish the cleanup of a namespace that has pending migrations, and once those migrations commit, the leftover tables are reported as drift as well.
983
974
 
984
- Removed tables are deleted only after the checkpoint is committed. If that cleanup fails, the checkpoint remains at the new migration and the SDK fails closed: the leftover table is reported as remote schema drift on the next deploy. Run `tailor tailordb migration sync <N>` with the committed migration as `<N>` (the warning names the command) to delete the leftover table and its GQL permission, or remove them manually, and then deploy again. The SDK does not automatically ignore or delete a same-named remote table because it cannot distinguish failed cleanup from a table recreated after cleanup completed.
975
+ With `--no-schema-check`, local table definitions that the pending migrations do not include are applied after every migration has committed (see [Schema verification](#schema-verification)). If one of them cannot be applied, the deploy fails with `MIGRATION_LOCAL_DEFINITIONS_FAILED`: the migrations stay committed, the existing tables go back to the definitions of the last migration, and tables already created for their local definitions remain. Fix the cause and deploy again. When existing records refuse the definition, for example a unique constraint on a field whose records hold duplicate values, run `tailor tailordb migration generate` to add the change in a migration whose script updates those records, then deploy again; the error's suggestion names the command.
985
976
 
986
977
  ## Rollback Strategy
987
978
 
@@ -991,7 +982,7 @@ There is no automatic down-migration. To roll back a schema/data change in produ
991
982
  2. `migration generate --name "rollback 0005 email"` produces `0006` with a removal diff.
992
983
  3. Apply.
993
984
 
994
- In **development workspaces**, a quicker option is to fix `0005/migrate.ts` in place, run `migration set <previous>` to re-mark it pending, and apply. Do not do this on production — it confuses migration history across environments.
985
+ In **development workspaces**, a quicker option is to fix `0005/migrate.ts` in place, run `migration sync <previous>` to return the tables to the previous migration and re-mark `0005` pending, and apply. `sync` removes the fields `0005` added and deletes the tables it added together with their data, and stops before moving the checkpoint when existing rows have no value for a field the previous migration requires. Do not do this on production — it confuses migration history across environments.
995
986
 
996
987
  ## Machine User and Permissions
997
988
 
@@ -1002,7 +993,7 @@ Migration scripts execute server-side under a machine user identity. The CLI sel
1002
993
 
1003
994
  The selected user must be defined in `auth.machineUsers`. The CLI logs the selected user before running scripts (`Using machine user: ...`).
1004
995
 
1005
- When a pending migration has a `migrate.ts`, `tailor deploy` checks while planning that auth is configured, that a machine user is selected and defined in `auth.machineUsers`, and that each script can be bundled. A failure stops the deploy before anything is applied, and `tailor deploy --dry-run` reports it too.
996
+ When a pending migration has a `migrate.ts`, `tailor deploy` checks while planning that auth is configured, that a machine user is selected and defined in `auth.machineUsers`, and that each script can be bundled. A failure stops the deploy before anything is applied, and `tailor deploy --dry-run` reports it too. `tailor tailordb migration validate` runs the same checks for the migrations that are pending in the workspace it validates.
1006
997
 
1007
998
  **Permissions required**
1008
999
 
@@ -1017,11 +1008,17 @@ If you see `No machine user available for migration execution`, either:
1017
1008
 
1018
1009
  If your project defines multiple TailorDB namespaces (`db: { ns1: { ... }, ns2: { ... } }`), each has its own `migrations/` directory and its own migration label. During `apply`:
1019
1010
 
1020
- - Migrations are grouped by namespace and executed namespace by namespace.
1021
- - Within a namespace, migrations run sequentially in number order.
1022
- - There is no cross-namespace ordering guarantee. Do not write a migration in `ns1` that depends on data produced by a migration in `ns2` running first.
1011
+ - Pending migrations run one namespace at a time, in alphabetical order of the namespace names, and within a namespace in migration number order. With pending migrations in `inventory` and `billing`, every one of `billing` runs before any of `inventory`.
1012
+ - With [maintenance mode](#maintenance-mode) on, every namespace of the config that has pending migrations enters maintenance mode before the first migration runs, and they leave it together: after the last migration with `"migration"`, and after the whole deploy with `"deploy"`. [Maintenance mode](#maintenance-mode) describes the exceptions when a deploy stops early.
1013
+ - The order follows the namespace names, not dependencies between namespaces. Do not write a migration in `ns1` that depends on data produced by a migration in `ns2` running first.
1023
1014
  - Each namespace can specify its own `migration.machineUser`.
1024
1015
 
1016
+ ### Several configs in one deploy
1017
+
1018
+ When one deploy applies several configs (see [Multiple Config Deploys](../../cli/application.md#deploy)), it applies each kind of resource for every config, in the order the configs are listed, before it moves on to the next kind. For `tailor deploy --config supplier.ts,buyer.ts`, the secrets, static websites, AI gateways, IdPs, auth services and machine users, and function registries of both configs are applied first. Then the TailorDB changes and migrations of `supplier` are applied, then those of `buyer`, then the resolvers of `supplier` and `buyer`, and so on through the applications, executors, and workflows. Each config's `maintenanceMode` covers only its own namespaces, so with `"deploy"` in `supplier`, its tables stay in maintenance mode while the migrations of `buyer` run.
1019
+
1020
+ If a migration of `buyer` fails, the deploy stops there and leaves `supplier` in this state: its migrations have completed and its checkpoint has advanced, its tables are out of maintenance mode even with `"deploy"`, and nothing after TailorDB has been applied, including its resolvers, executors, and workflows. Its tables therefore have the new schema while the resolvers and executors of the previous deploy still use them. When you fix the migration of `buyer` and deploy both configs again, `supplier` has no pending migrations, and the deploy applies the rest of its changes. If the migration of `buyer` must first be settled with `tailor tailordb migration resolve` (see [Failure Recovery](#failure-recovery)), every deploy of the two configs stops before changing anything until then.
1021
+
1025
1022
  ## Performance and Large Tables
1026
1023
 
1027
1024
  The migration script runs in a single transaction. For tables with many rows:
@@ -1209,7 +1206,7 @@ For genuinely different schemas across environments, prefer separate workspaces
1209
1206
 
1210
1207
  1. `tailor tailordb migration status` to see local vs remote.
1211
1208
  2. Compare with teammates — has someone applied different migrations?
1212
- 3. If remote was changed manually, decide whether to update local migrations to match or to use `migration set <N>` to align bookkeeping.
1209
+ 3. If remote was changed manually, decide whether to update the local tables to match and run `migration generate`, or to return the remote to a snapshot as in the next step.
1213
1210
  4. To force the remote schema back to a known snapshot, use `migration sync <N>` (see [`migration sync` Semantics](#migration-sync-semantics)). If the drift follows a failed deploy that warned it could not restore a table's schema, see [Failure Recovery](#failure-recovery) instead.
1214
1211
  5. As a last resort in non-production environments, `--no-schema-check` skips both checks. Do not use this as a routine workaround. It does not skip the checkpoint check described next.
1215
1212
 
@@ -1225,7 +1222,7 @@ One specific cause is a `migration rebaseline` run on a different environment wh
1225
1222
  2. Deploy this environment against that restored history until its checkpoint reaches the migration named in the error, running any `migrate.ts` scripts it still needs.
1226
1223
  3. Switch back to the current (rebaselined) migration files and deploy again. The remote schema now matches the new baseline, so this deploy offers the automatic checkpoint reset to `0000` under the new history ID.
1227
1224
 
1228
- **Resolution (any other cause):** Run `tailor tailordb migration status` to compare local and remote, and pull the latest migration files if your checkout is stale. To move the checkpoint back to the local migration history on purpose, run `tailor tailordb migration sync <N>`, which also rewrites the tables to snapshot `<N>`, or `tailor tailordb migration set <N>`, which moves only the checkpoint, with the latest local migration as `<N>` (the error suggests both commands). When the namespace records another migration history ID, or one that cannot be read, both commands also need `--force`, which replaces that history ID with the local one, or removes it when the local history has none (see [`migration set` Semantics](#migration-set-semantics)). Pass `--force` only when the local migration history should replace the deployed one; otherwise work from a checkout of the migration history deployed to the workspace. Then deploy again.
1225
+ **Resolution (any other cause):** Run `tailor tailordb migration status` to compare local and remote, and pull the latest migration files if your checkout is stale. To move the checkpoint back to the local migration history on purpose, run `tailor tailordb migration sync <N>` with the latest local migration as `<N>` (the error suggests the command). It also rewrites the tables to snapshot `<N>`, removing the fields that snapshot does not have and deleting the tables it does not have together with their data. When the namespace records another migration history ID, or one that cannot be read, the command also needs `--force`, which replaces that history ID with the local one, or removes it when the local history has none (see [`migration sync` Semantics](#migration-sync-semantics)). Pass `--force` only when the local migration history should replace the deployed one; otherwise work from a checkout of the migration history deployed to the workspace. Then deploy again.
1229
1226
 
1230
1227
  ### `MIGRATION_FILES_INVALID` error
1231
1228
 
@@ -1251,13 +1248,13 @@ One specific cause is a `migration rebaseline` run on a different environment wh
1251
1248
 
1252
1249
  ### "No machine user available for migration execution"
1253
1250
 
1254
- **Cause:** Neither `migration.machineUser` is set nor are there any machine users in `auth.machineUsers`. `tailor deploy` reports this while planning, including with `--dry-run`, before anything is applied.
1251
+ **Cause:** Neither `migration.machineUser` is set nor are there any machine users in `auth.machineUsers`. `tailor deploy` reports this while planning, including with `--dry-run`, before anything is applied, and `tailor tailordb migration validate` reports it too.
1255
1252
 
1256
1253
  **Resolution:** Add a machine user to `auth.machineUsers`, then run `tailor deploy` again. The deploy creates the machine user before it runs the migration scripts.
1257
1254
 
1258
1255
  ### "Machine user for migration execution is not defined in auth"
1259
1256
 
1260
- **Cause:** `migration.machineUser`, or `--machine-user` of `tailor tailordb migration test`, names a machine user that is not in `auth.machineUsers`. `tailor deploy` reports this while planning, including with `--dry-run`, before anything is applied.
1257
+ **Cause:** `migration.machineUser`, or `--machine-user` of `tailor tailordb migration test`, names a machine user that is not in `auth.machineUsers`. `tailor deploy` reports this while planning, including with `--dry-run`, before anything is applied, and `tailor tailordb migration validate` reports it too.
1261
1258
 
1262
1259
  **Resolution:** Either add the machine user to `auth.machineUsers`, or name one that is defined there.
1263
1260
 
package/docs/testing.md CHANGED
@@ -214,7 +214,6 @@ The generated columns follow the Kysely types, not TailorDB's storage: `text` fo
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
- - 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.
218
217
  - `gapless` is not reproduced: the numbers come from a sequence, so an insert that fails still uses up its number.
219
218
  - 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
219
  - 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailor-platform/sdk",
3
- "version": "2.37.0",
3
+ "version": "2.38.0",
4
4
  "description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -151,6 +151,9 @@
151
151
  "types": "./dist/runtime/logger.d.mts",
152
152
  "import": "./dist/runtime/logger.mjs",
153
153
  "default": "./dist/runtime/logger.mjs"
154
+ },
155
+ "./vendor/graphql/*": {
156
+ "types": "./dist/vendor/graphql/*.d.mts"
154
157
  }
155
158
  },
156
159
  "dependencies": {
@@ -160,6 +163,9 @@
160
163
  "@bufbuild/protovalidate": "1.3.0",
161
164
  "@connectrpc/connect": "2.2.0",
162
165
  "@connectrpc/connect-node": "2.2.0",
166
+ "@enlumine/graphql": "0.2.0",
167
+ "@enlumine/sql": "0.2.0",
168
+ "@enlumine/terminal": "0.2.0",
163
169
  "@inquirer/core": "12.0.6",
164
170
  "@inquirer/prompts": "8.7.5",
165
171
  "@jridgewell/trace-mapping": "0.3.31",
@@ -177,16 +183,14 @@
177
183
  "@standard-schema/spec": "1.1.0",
178
184
  "@tailor-platform/function-kysely-tailordb": "0.1.3",
179
185
  "@toiroakr/read-multiline": "0.4.3",
180
- "@urql/core": "6.0.3",
181
- "amaro": "1.2.2",
182
- "confbox": "0.3.1",
186
+ "amaro": "1.3.0",
187
+ "confbox": "0.3.2",
183
188
  "date-fns": "4.4.0",
184
- "es-toolkit": "1.53.0",
189
+ "es-toolkit": "1.53.1",
185
190
  "find-up-simple": "1.0.1",
186
191
  "get-east-asian-width": "1.7.0",
187
192
  "get-tsconfig": "4.14.3",
188
193
  "globals": "17.13.0",
189
- "graphql": "17.0.2",
190
194
  "inflection": "3.0.2",
191
195
  "kysely": "0.29.7",
192
196
  "lines-db": "0.18.1",
@@ -199,7 +203,6 @@
199
203
  "pkg-types": "2.4.0",
200
204
  "rolldown": "1.2.15",
201
205
  "semver": "7.8.5",
202
- "sql-highlight": "6.1.0",
203
206
  "std-env": "4.3.0",
204
207
  "temporal-polyfill": "1.0.6",
205
208
  "temporal-spec": "1.0.1",
@@ -210,14 +213,15 @@
210
213
  },
211
214
  "devDependencies": {
212
215
  "@ark/attest": "0.58.0",
213
- "@electric-sql/pglite": "0.5.12",
216
+ "@electric-sql/pglite": "0.5.14",
214
217
  "@tailor-platform/shared": "^0.0.0",
215
218
  "@tailor-platform/tailor-proto": "^0.0.1",
216
219
  "@types/mime-types": "3.0.1",
217
- "@types/node": "26.6.5",
220
+ "@types/node": "26.6.6",
218
221
  "@types/semver": "7.8.0",
219
222
  "@vitest/coverage-v8": "5.0.5",
220
223
  "eslint-plugin-zod": "5.2.2",
224
+ "graphql": "17.0.2",
221
225
  "oxfmt": "0.75.0",
222
226
  "oxlint": "1.90.0",
223
227
  "oxlint-tsgolint": "7.0.2005",
@@ -227,7 +231,7 @@
227
231
  "tsx": "4.23.15",
228
232
  "typescript": "6.0.3",
229
233
  "vitest": "5.0.5",
230
- "zinfer": "0.5.1"
234
+ "zinfer": "0.5.2"
231
235
  },
232
236
  "peerDependencies": {
233
237
  "@electric-sql/pglite": ">=0.2.0",