@tailor-platform/sdk 2.16.0 → 2.17.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 (66) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/{application-wYQ-ivDg.mjs → application-ChuNPwnl.mjs} +13 -13
  3. package/dist/application-ChuNPwnl.mjs.map +1 -0
  4. package/dist/application-Oh5dMmb5.mjs +1 -0
  5. package/dist/cli/commands/tailordb/migrate/snapshot-files.d.mts +5 -1
  6. package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +2 -2
  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 +40 -40
  11. package/dist/cli/main.mjs.map +1 -1
  12. package/dist/cli/shared/error-json.d.mts +19 -0
  13. package/dist/cli/shared/logger.d.mts +18 -0
  14. package/dist/completion/zsh-worker.zsh +2 -2
  15. package/dist/configure/index.mjs +1 -1
  16. package/dist/configure/index.mjs.map +1 -1
  17. package/dist/crashreport-CgymxQDu.mjs +1 -0
  18. package/dist/crashreport-Cyuz1qiu.mjs +42 -0
  19. package/dist/crashreport-Cyuz1qiu.mjs.map +1 -0
  20. package/dist/{errors-BtTxkzgy.mjs → errors-BjJnpXkK.mjs} +2 -2
  21. package/dist/{errors-BtTxkzgy.mjs.map → errors-BjJnpXkK.mjs.map} +1 -1
  22. package/dist/field-parse-CzlKC4b7.mjs +2 -0
  23. package/dist/field-parse-CzlKC4b7.mjs.map +1 -0
  24. package/dist/kysely-type-B_oA8D1k.mjs +43 -0
  25. package/dist/kysely-type-B_oA8D1k.mjs.map +1 -0
  26. package/dist/{logger-CEAxByN5.mjs → logger-72hM4JWZ.mjs} +4 -4
  27. package/dist/logger-72hM4JWZ.mjs.map +1 -0
  28. package/dist/{manager-E3ffRcCt.mjs → manager-C26Gi1bX.mjs} +2 -2
  29. package/dist/{manager-E3ffRcCt.mjs.map → manager-C26Gi1bX.mjs.map} +1 -1
  30. package/dist/plugin/builtin/kysely-type/index.d.mts +2 -0
  31. package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
  32. package/dist/plugin/index.mjs +1 -1
  33. package/dist/{register-ts-hook-DrHS-J1k.mjs → register-ts-hook-Dn-XlVSD.mjs} +108 -69
  34. package/dist/register-ts-hook-Dn-XlVSD.mjs.map +1 -0
  35. package/dist/schema-DRyQEabV.mjs +2 -0
  36. package/dist/schema-DRyQEabV.mjs.map +1 -0
  37. package/dist/service-B3OiWCYg.mjs +1 -0
  38. package/dist/{service-Cw7hb5HK.mjs → service-B4Gh_bbL.mjs} +2 -2
  39. package/dist/{service-Cw7hb5HK.mjs.map → service-B4Gh_bbL.mjs.map} +1 -1
  40. package/dist/{service-DaoW0kzo.mjs → service-eM7Fd8zS.mjs} +3 -3
  41. package/dist/{service-DaoW0kzo.mjs.map → service-eM7Fd8zS.mjs.map} +1 -1
  42. package/dist/tailordb-ddl-Fgm2cNvT.mjs +7 -0
  43. package/dist/tailordb-ddl-Fgm2cNvT.mjs.map +1 -0
  44. package/dist/utils/test/index.mjs +1 -1
  45. package/dist/utils/test/index.mjs.map +1 -1
  46. package/dist/vitest/index.mjs.map +1 -1
  47. package/dist/vitest/mocks/tailordb-pglite.d.mts +5 -4
  48. package/docs/cli/tailordb.md +8 -8
  49. package/docs/cli-reference.md +7 -3
  50. package/docs/services/tailordb-migration.md +25 -24
  51. package/docs/testing.md +23 -21
  52. package/package.json +8 -7
  53. package/dist/application-Dw3t9p2f.mjs +0 -1
  54. package/dist/application-wYQ-ivDg.mjs.map +0 -1
  55. package/dist/crashreport-DF8YMIE5.mjs +0 -1
  56. package/dist/crashreport-Doz2Kuuq.mjs +0 -42
  57. package/dist/crashreport-Doz2Kuuq.mjs.map +0 -1
  58. package/dist/field-column-type-QMtF6lUp.mjs +0 -2
  59. package/dist/field-column-type-QMtF6lUp.mjs.map +0 -1
  60. package/dist/kysely-type-B-BOlXH7.mjs +0 -43
  61. package/dist/kysely-type-B-BOlXH7.mjs.map +0 -1
  62. package/dist/logger-CEAxByN5.mjs.map +0 -1
  63. package/dist/register-ts-hook-DrHS-J1k.mjs.map +0 -1
  64. package/dist/schema-BTioi2dP.mjs +0 -2
  65. package/dist/schema-BTioi2dP.mjs.map +0 -1
  66. package/dist/service-dn9jxC8c.mjs +0 -1
@@ -29,10 +29,11 @@ interface CreatedClient {
29
29
  * PGlite instances are borrowed, never closed — close them yourself (e.g. in
30
30
  * `afterAll`).
31
31
  *
32
- * Create the tables a test needs up front with `CREATE TABLE` statements
33
- * matching the generated Kysely types. PGlite runs full PostgreSQL while
34
- * TailorDB supports a subset of it, so a statement passing here can still be
35
- * rejected by the platform.
32
+ * Create the tables a test needs up front: run the script `kyselyTypePlugin`
33
+ * writes when `pgliteSchemaPath` is set, or your own `CREATE TABLE`
34
+ * statements matching the generated Kysely types. PGlite runs full PostgreSQL
35
+ * while TailorDB supports a subset of it, so a statement passing here can
36
+ * still be rejected by the platform.
36
37
  *
37
38
  * Transactions on a shared instance are serialized: while one is open,
38
39
  * queries from other `getDB` instances on the same PGlite instance wait for
@@ -177,19 +177,19 @@ tailor tailordb migration script [options] <number>
177
177
 
178
178
  **Options**
179
179
 
180
- | Option | Alias | Description | Required | Default | Env |
181
- | ------------------------- | ----- | ----------------------------------------------------------------------------------------------------- | -------- | -------------------- | -------------------- |
182
- | `--config <CONFIG>` | `-c` | Path to Tailor config file | No | `"tailor.config.ts"` | `TAILOR_CONFIG_PATH` |
183
- | `--namespace <NAMESPACE>` | `-n` | Target TailorDB namespace (required if multiple namespaces exist) | No | - | - |
184
- | `--no-script` | - | Record that this migration intentionally runs without a migration script (requires --reason) | No | - | - |
185
- | `--reason <REASON>` | - | Reason why no migration script is needed (used with --no-script) | No | - | - |
186
- | `--with-test` | - | Also add a migrate.test.ts unit-test scaffold; when migrate.ts already exists, only the test is added | No | - | - |
180
+ | Option | Alias | Description | Required | Default | Env |
181
+ | ------------------------- | ----- | -------------------------------------------------------------------------------------------- | -------- | -------------------- | -------------------- |
182
+ | `--config <CONFIG>` | `-c` | Path to Tailor config file | No | `"tailor.config.ts"` | `TAILOR_CONFIG_PATH` |
183
+ | `--namespace <NAMESPACE>` | `-n` | Target TailorDB namespace (required if multiple namespaces exist) | No | - | - |
184
+ | `--no-script` | - | Record that this migration intentionally runs without a migration script (requires --reason) | No | - | - |
185
+ | `--reason <REASON>` | - | Reason why no migration script is needed (used with --no-script) | No | - | - |
186
+ | `--with-test` | - | Also add the migrate.test.ts and migrate.pglite.test.ts scaffolds | No | - | - |
187
187
 
188
188
  See [Global Options](../cli-reference.md#global-options) for options available to all commands.
189
189
 
190
190
  **Notes**
191
191
 
192
- When `migrate.ts` already exists, running the command clears a previously recorded `--no-script` acknowledgment.
192
+ When `migrate.ts` already exists, running the command clears a previously recorded `--no-script` acknowledgment, and `--with-test` adds only the tests that do not exist yet (writing `db.pglite.ts` if it is missing). `migrate.pglite.test.ts` is scaffolded only when `@electric-sql/pglite` is installed in the project.
193
193
 
194
194
  #### tailordb migration set
195
195
 
@@ -210,9 +210,13 @@ Resolution rules:
210
210
  - **Lookup order:** the project's `node_modules/.bin` (nearest first, walking up from the current
211
211
  directory), then your `PATH`. So a plugin installed as a project dev-dependency takes precedence over a
212
212
  globally installed one.
213
- - **Place global flags after the plugin command.** Only the arguments following the plugin name are
214
- forwarded; a global flag placed before it (e.g. `tailor --json tailordb erd export`) is consumed by
215
- the host CLI and does not reach the plugin. Write `tailor tailordb erd export --json` instead.
213
+ - **Global flags reach the plugin from either side.** `tailor --json tailordb erd export` and
214
+ `tailor tailordb erd export --json` both forward `--json`, and likewise `--verbose` and the
215
+ `--env-file` options. A flag typed before the plugin name is consumed by the host CLI first and
216
+ then forwarded, so when the same flag appears on both sides the later one wins. A flag the host
217
+ does not define — including one only some commands declare, such as `--profile` — still has to be
218
+ typed after the plugin's own subcommand. `--help` and `--version` are answered by the host CLI and
219
+ never dispatch a plugin.
216
220
 
217
221
  Because resolution is based on `node_modules/.bin` and `PATH`, any package manager that populates
218
222
  `node_modules/.bin` works for project-local plugins — npm, pnpm (its content-addressable store is
@@ -24,7 +24,8 @@ migrations/
24
24
  ├── 0001/ # First change
25
25
  │ ├── diff.json # Field-level diff from 0000
26
26
  │ ├── migrate.ts # Data migration script (auto-generated for breaking changes; can be added manually via `migration script`)
27
- │ └── db.ts # Kysely types for the script (pre-migration shape)
27
+ │ ├── db.ts # Kysely types for the script (pre-migration shape)
28
+ │ └── db.pglite.ts # CREATE TABLE script of that shape, for PGlite tests
28
29
  ├── 0002/
29
30
  │ └── diff.json # No script — non-breaking changes only
30
31
  └── ...
@@ -129,7 +130,7 @@ No `migrate.ts` is generated automatically because the schema change itself is n
129
130
  tailor tailordb migration script 0002
130
131
  ```
131
132
 
132
- This writes `migrations/0002/migrate.ts` and `migrations/0002/db.ts` next to the existing `diff.json` (add `--with-test` to also scaffold a `migrate.test.ts` — see [Testing Migrations Locally](#testing-migrations-locally)). The removed field stays readable inside `migrate.ts` because the pre-migration phase keeps it on the table until the script finishes (see [Per-migration phases](#per-migration-phases)). The next `tailor deploy` runs the script automatically — `migrate.ts` is executed whenever the file exists on disk, regardless of whether the diff itself required it.
133
+ This writes `migrations/0002/migrate.ts`, `migrations/0002/db.ts`, and `migrations/0002/db.pglite.ts` next to the existing `diff.json` (add `--with-test` to also scaffold the tests — see [Testing Migrations Locally](#testing-migrations-locally)). The removed field stays readable inside `migrate.ts` because the pre-migration phase keeps it on the table until the script finishes (see [Per-migration phases](#per-migration-phases)). The next `tailor deploy` runs the script automatically — `migrate.ts` is executed whenever the file exists on disk, regardless of whether the diff itself required it.
133
134
 
134
135
  If the data loss is intentional and no script is needed, record that decision the same way as for breaking changes (see [Breaking changes without a script](#breaking-changes-without-a-script)):
135
136
 
@@ -267,13 +268,15 @@ export default defineConfig({
267
268
 
268
269
  ## Generated Files
269
270
 
270
- | File | When generated | Description |
271
- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
272
- | `0000/schema.json` | First `migration generate` | Full snapshot of all tables in the namespace. |
273
- | `XXXX/diff.json` | Every subsequent migration | Field-level diff against the previous snapshot. |
274
- | `XXXX/migrate.ts` | Auto-generated for breaking changes and `--data-only` migrations; added manually via `tailordb migration script` for warning-tier changes | Data transformation script. The `main` export receives a Kysely `Transaction`. |
275
- | `XXXX/db.ts` | Generated once when `migrate.ts` is created | Kysely types reflecting the schema **before** this migration. Exports `Database`, `Transaction`, and `MigrationContext`. |
276
- | `XXXX/migrate.test.ts` | Added via `tailordb migration script --with-test` | Unit-test scaffold for `migrate.ts` (see [Testing Migrations Locally](#testing-migrations-locally)). Never deployed. |
271
+ | File | When generated | Description |
272
+ | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
273
+ | `0000/schema.json` | First `migration generate` | Full snapshot of all tables in the namespace. |
274
+ | `XXXX/diff.json` | Every subsequent migration | Field-level diff against the previous snapshot. |
275
+ | `XXXX/migrate.ts` | Auto-generated for breaking changes and `--data-only` migrations; added manually via `tailordb migration script` for warning-tier changes | Data transformation script. The `main` export receives a Kysely `Transaction`. |
276
+ | `XXXX/db.ts` | Generated once when `migrate.ts` is created | Kysely types reflecting the schema **before** this migration. Exports `Database`, `Transaction`, and `MigrationContext`. |
277
+ | `XXXX/db.pglite.ts` | Generated with `db.ts` | `CREATE TABLE` script of the same schema, for running `migrate.ts` on PGlite. Never deployed. |
278
+ | `XXXX/migrate.test.ts` | Added via `tailordb migration script --with-test` | Unit-test scaffold for `migrate.ts` (see [Testing Migrations Locally](#testing-migrations-locally)). Never deployed. |
279
+ | `XXXX/migrate.pglite.test.ts` | Added via `tailordb migration script --with-test` when `@electric-sql/pglite` is installed | PGlite test scaffold for `migrate.ts`. Never deployed. |
277
280
 
278
281
  `db.ts` reflects the pre-migration schema because the script runs after the pre-migration phase has temporarily relaxed breaking constraints (e.g., a new `required` field is added as `optional` first), so the data being read still matches the previous shape.
279
282
 
@@ -811,7 +814,7 @@ Scaffold a ready-to-fill test next to the script with:
811
814
  tailor tailordb migration script 0005 --with-test
812
815
  ```
813
816
 
814
- When `migrate.ts` already exists (the usual case for breaking changes, where `migration generate` creates it), the command adds only `migrate.test.ts`. Or write the test by hand:
817
+ When `migrate.ts` already exists (the usual case for breaking changes, where `migration generate` creates it), the command adds only the tests that do not exist yet, plus a missing `db.pglite.ts`. Or write the test by hand:
815
818
 
816
819
  ```typescript
817
820
  // migrations/0005/migrate.test.ts
@@ -845,30 +848,24 @@ A statement-level test verifies what the script issues, not what it does to data
845
848
  npm install -D @electric-sql/pglite
846
849
  ```
847
850
 
848
- Create the tables the script touches (matching the shape in the generated `db.ts`), stage rows, then run the script in a transaction. 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>`.
851
+ 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>`.
849
852
 
850
853
  ```typescript
851
854
  // migrations/0005/migrate.pglite.test.ts
852
855
  import { PGlite } from "@electric-sql/pglite";
853
- import { sql } from "@tailor-platform/sdk/kysely";
854
856
  import { createKyselyPGlite, type Unmigrated } from "@tailor-platform/sdk/vitest";
855
857
  import { afterAll, beforeAll, describe, expect, test } from "vitest";
856
858
  import type { Database } from "./db";
859
+ import { pgliteSchema } from "./db.pglite";
857
860
  import { main } from "./migrate";
858
861
 
859
- const db = createKyselyPGlite<Unmigrated<Database>>(new PGlite());
862
+ const pglite = new PGlite();
863
+ const db = createKyselyPGlite<Unmigrated<Database>>(pglite);
860
864
 
865
+ // PGlite loads Postgres on first use, which can take longer than the default hook timeout.
861
866
  beforeAll(async () => {
862
- await sql`
863
- CREATE TABLE "User" (
864
- "id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
865
- "name" text NOT NULL,
866
- "email" text,
867
- "createdAt" timestamptz NOT NULL,
868
- "updatedAt" timestamptz NOT NULL
869
- )
870
- `.execute(db);
871
- });
867
+ await pglite.exec(pgliteSchema.tailordb);
868
+ }, 60_000);
872
869
 
873
870
  afterAll(async () => {
874
871
  await db.destroy();
@@ -896,10 +893,14 @@ describe("0005 add required email", () => {
896
893
  });
897
894
  ```
898
895
 
896
+ Pass nested field values as JavaScript objects or arrays of objects, without `JSON.stringify`.
897
+ Generated migration types use `Record<string, unknown>` for each nested object so scripts can
898
+ work with both old and new members during a migration; narrow member values before using them.
899
+
899
900
  Two caveats keep this from replacing a scratch workspace:
900
901
 
901
902
  - PGlite runs full PostgreSQL, while TailorDB supports [a subset of it](https://docs.tailor.tech/guides/function/accessing-tailordb#supported-sql-queries) — a statement that passes here can still be rejected on deploy.
902
- - The `CREATE TABLE` statements are yours, so they can drift from the schema the platform actually has.
903
+ - `db.pglite.ts` mirrors the column shape, not the platform: hooks, validations, and permissions do not run, and the limits listed under [Real SQL execution with PGlite](../testing.md#real-sql-execution-with-pglite-mocktailordbwithpglite) apply.
903
904
 
904
905
  ### Beyond unit tests
905
906
 
package/docs/testing.md CHANGED
@@ -149,26 +149,30 @@ Pass `{ onUnhandled: "error" }` to make an unmatched query fail instead of retur
149
149
 
150
150
  Instead of staging responses, back TailorDB with [`@electric-sql/pglite`](https://pglite.dev/) — an in-memory PostgreSQL (install it as a devDependency) — so the queries a resolver, executor, or workflow job issues through `getDB()` execute against real data. `getDB(namespace)` needs no test-side swap: acquire the mock, and each namespace you list resolves to its PGlite instance.
151
151
 
152
- Create the tables the test touches with `CREATE TABLE` statements matching the generated Kysely types — `text` for string and enum fields, `timestamptz` for date/datetime, `jsonb` for nested objects. The schema only has to match what your code reads and writes, not TailorDB's storage; relations are not enforced.
152
+ Let `kyselyTypePlugin` generate the `CREATE TABLE` script for you: set `pgliteSchemaPath` next to `distPath`, and `tailor generate` writes a module exporting one script per namespace, derived from the same table definitions as the Kysely types.
153
+
154
+ ```typescript
155
+ // tailor.config.ts
156
+ kyselyTypePlugin({
157
+ distPath: "./generated/db.ts",
158
+ pgliteSchemaPath: "./generated/db.pglite.ts",
159
+ });
160
+ ```
161
+
162
+ Run the namespace's script once per PGlite instance. Every statement is `IF NOT EXISTS`, so applying it again to an instance that already has the tables is harmless.
153
163
 
154
164
  ```typescript
155
165
  import { PGlite } from "@electric-sql/pglite";
156
166
  import { mockTailordbWithPGlite } from "@tailor-platform/sdk/vitest";
157
167
  import { afterAll, beforeAll, expect, test } from "vitest";
158
168
  import { getDB } from "../generated/db";
169
+ import { pgliteSchema } from "../generated/db.pglite";
159
170
  import resolver from "./upsertUsers";
160
171
 
161
172
  const pglite = new PGlite();
162
173
 
163
174
  beforeAll(async () => {
164
- await pglite.exec(`
165
- CREATE TABLE "User" (
166
- "id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
167
- "name" text NOT NULL,
168
- "email" text NOT NULL,
169
- "age" integer NOT NULL
170
- );
171
- `);
175
+ await pglite.exec(pgliteSchema["main-db"]);
172
176
  });
173
177
 
174
178
  afterAll(async () => {
@@ -201,21 +205,19 @@ test("upserts against real rows", async () => {
201
205
  });
202
206
  ```
203
207
 
204
- A `.serial()` field is omitted from generated `getDB()` inserts, so its PGlite column must generate a value. Use an identity for an integer serial. For a formatted string serial, create a sequence and reproduce the format in its `DEFAULT` expression:
208
+ 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 not enforced.
205
209
 
206
- ```sql
207
- CREATE SEQUENCE "invoiceNumberSequence" START WITH 1000;
208
- CREATE TABLE "Invoice" (
209
- "sequentialId" integer GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
210
- "invoiceNumber" text NOT NULL
211
- DEFAULT ('INV-' || lpad(nextval('"invoiceNumberSequence"')::text, 5, '0'))
212
- );
213
- ```
210
+ What the script cannot reproduce:
211
+
212
+ - 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.
213
+ - 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.
214
+ - A datetime inside a nested object reads back as a string from `jsonb`, not a `Date`.
215
+ - 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.
214
216
 
215
- PGlite does not apply the TailorDB `.serial()` configuration itself. Match the `start`, `format`, and any limit that the behavior under test relies on.
217
+ 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.
216
218
 
217
219
  - The PGlite instance is yours: the mock never closes it, so close it in `afterAll`. Reuse one instance across a suite — creating one per test is slow.
218
- - Pass the same instance under several namespaces to drive them against one shared database.
220
+ - Pass the same instance under several namespaces to drive them against one shared database. Two namespaces with a same-named table cannot share one instance, because the second script leaves the first table as it is.
219
221
  - Seed through `getDB` itself. When a column type rejects a value that only the test must stage, use `createKyselyPGlite<Unmigrated<...>>(pglite)` instead — see [Testing Migrations Locally](./services/tailordb-migration.md#testing-migrations-locally). This only affects test setup; it cannot supply a `.serial()` value for an insert issued by the code under test.
220
222
  - Transactions on a shared instance are serialized: while one is open, queries from other `getDB` instances wait. Do not use `test.concurrent` with a shared instance, and do not query the same instance through a second `getDB` from inside a transaction — that waits on itself.
221
223
  - PGlite runs full PostgreSQL while TailorDB supports a subset of it, and TailorDB hooks, validations, and permissions do not run here — a test passing on PGlite can still behave differently on the platform. Keep [`mockTailordb`](#tailordb-mock) or [`createKyselyMock`](#kysely-layer-mock-createkyselymock) tests for query shape and error paths, and E2E tests for platform behavior.
@@ -666,7 +668,7 @@ describe("upsertUsers resolver", () => {
666
668
 
667
669
  Reach for [`mockTailordb`](#mocking-the-tailordb-client) instead when you want to drive the raw query sequence at the `tailordb.Client` level rather than at the Kysely layer, or [`mockTailordbWithPGlite`](#real-sql-execution-with-pglite-mocktailordbwithpglite) to execute the queries against a real in-memory Postgres.
668
670
 
669
- TailorDB migration scripts (`migrate.ts`) are unit-tested the same way: the generated `db.ts` exports the `Database` interface to type the mock, and `tailor tailordb migration script <N> --with-test` scaffolds a ready-to-fill test. To execute a migration script against real rows in an in-memory Postgres, use `createKyselyPGlite` with `@electric-sql/pglite`. See [Testing Migrations Locally](./services/tailordb-migration.md#testing-migrations-locally).
671
+ TailorDB migration scripts (`migrate.ts`) are unit-tested the same way: the generated `db.ts` exports the `Database` interface to type the mock, and `tailor tailordb migration script <N> --with-test` scaffolds a ready-to-fill test. To execute a migration script against real rows in an in-memory Postgres, use `createKyselyPGlite` with `@electric-sql/pglite` and the generated `db.pglite.ts` schema. See [Testing Migrations Locally](./services/tailordb-migration.md#testing-migrations-locally).
670
672
 
671
673
  #### Resolvers that resume a workflow
672
674
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailor-platform/sdk",
3
- "version": "2.16.0",
3
+ "version": "2.17.0",
4
4
  "description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -155,8 +155,8 @@
155
155
  "@bufbuild/protovalidate": "1.2.0",
156
156
  "@connectrpc/connect": "2.2.0",
157
157
  "@connectrpc/connect-node": "2.2.0",
158
- "@inquirer/core": "12.0.2",
159
- "@inquirer/prompts": "8.7.1",
158
+ "@inquirer/core": "12.0.3",
159
+ "@inquirer/prompts": "8.7.2",
160
160
  "@jridgewell/trace-mapping": "0.3.31",
161
161
  "@napi-rs/keyring": "2.0.0",
162
162
  "@opentelemetry/api": "1.9.1",
@@ -190,7 +190,7 @@
190
190
  "p-limit": "7.3.2",
191
191
  "pathe": "2.0.3",
192
192
  "pgsql-ast-parser": "12.0.2",
193
- "pkg-types": "2.3.2",
193
+ "pkg-types": "2.3.3",
194
194
  "rolldown": "1.2.7",
195
195
  "semver": "7.8.5",
196
196
  "sql-highlight": "6.1.0",
@@ -201,15 +201,16 @@
201
201
  "zod": "4.5.4"
202
202
  },
203
203
  "devDependencies": {
204
+ "@electric-sql/pglite": "0.5.8",
204
205
  "@opentelemetry/sdk-trace-base": "2.11.0",
205
206
  "@tailor-platform/shared": "^0.0.0",
206
207
  "@tailor-platform/tailor-proto": "^0.0.1",
207
208
  "@types/mime-types": "3.0.1",
208
- "@types/node": "24.13.3",
209
+ "@types/node": "24.13.4",
209
210
  "@types/semver": "7.8.0",
210
211
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
211
212
  "@vitest/coverage-v8": "5.0.0",
212
- "eslint-plugin-zod": "4.12.0",
213
+ "eslint-plugin-zod": "4.12.1",
213
214
  "oxfmt": "0.66.0",
214
215
  "oxlint": "1.81.0",
215
216
  "oxlint-tsgolint": "7.0.2001",
@@ -217,7 +218,7 @@
217
218
  "tsdown": "0.23.0",
218
219
  "typescript": "6.0.3",
219
220
  "vitest": "5.0.0",
220
- "zinfer": "0.4.5"
221
+ "zinfer": "0.4.6"
221
222
  },
222
223
  "peerDependencies": {
223
224
  "@electric-sql/pglite": ">=0.2.0",
@@ -1 +0,0 @@
1
- import{n as e,t}from"./application-wYQ-ivDg.mjs";export{t as defineApplication,e as generatePluginFilesIfNeeded};