@tailor-platform/sdk 2.30.0 → 2.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/dist/ai/index.d.mts +112 -0
- package/dist/ai/index.mjs +2 -0
- package/dist/ai/index.mjs.map +1 -0
- package/dist/aigateway-DsWDjzk4.mjs.map +1 -1
- package/dist/application-D0xNJbag.mjs.map +1 -1
- package/dist/assert-WeXvmG4j.mjs.map +1 -1
- package/dist/authconnection-CynFBIv8.mjs.map +1 -1
- package/dist/brand-C8nMKhJC.mjs.map +1 -1
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.mjs +6 -6
- package/dist/cli/main.mjs.map +1 -1
- package/dist/completion/zsh-worker.zsh +6 -2
- package/dist/configure/index.mjs.map +1 -1
- package/dist/context-D0QjfxzD.mjs.map +1 -1
- package/dist/crashreport-BCIy33Cz.mjs.map +1 -1
- package/dist/date-CgP7gMG_.mjs.map +1 -1
- package/dist/date-representation-Cr7W7Pn2.mjs.map +1 -1
- package/dist/errors-BOF68LJ5.mjs.map +1 -1
- package/dist/es-builtins-SfvXRVoG.mjs.map +1 -1
- package/dist/field-parse-C41e3UAF.mjs.map +1 -1
- package/dist/file-DKBOj5q4.mjs.map +1 -1
- package/dist/globals-BCmGX05J.mjs.map +1 -1
- package/dist/guards-yDXyKC9F.mjs.map +1 -1
- package/dist/iconv-DlFMt2gW.mjs.map +1 -1
- package/dist/idp-G_ojPBB5.mjs.map +1 -1
- package/dist/interceptor-DQg3cR_9.mjs.map +1 -1
- package/dist/kysely/index.mjs.map +1 -1
- package/dist/{kysely-type-BWMfV301.mjs → kysely-type-CBwsdx16.mjs} +6 -3
- package/dist/kysely-type-CBwsdx16.mjs.map +1 -0
- package/dist/logger-DP2BjQ93.mjs.map +1 -1
- package/dist/logger-RgtbhJ83.mjs.map +1 -1
- package/dist/manager-Bk-7vkwd.mjs.map +1 -1
- package/dist/migration-steps-C6F3zNdQ.mjs.map +1 -1
- package/dist/multiline-EyzjEwn9.mjs.map +1 -1
- package/dist/node-builtins-DYfhPBnz.mjs.map +1 -1
- package/dist/package-json-C690ceex.mjs.map +1 -1
- package/dist/platform-serialize-DkiTdHOt.mjs.map +1 -1
- package/dist/plugin/builtin/enum-constants/index.mjs.map +1 -1
- package/dist/plugin/builtin/file-utils/index.mjs.map +1 -1
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
- package/dist/plugin/index.mjs.map +1 -1
- package/dist/{register-ts-hook-CDnN_Jx2.mjs → register-ts-hook-_dHIREtU.mjs} +127 -89
- package/dist/register-ts-hook-_dHIREtU.mjs.map +1 -0
- package/dist/registry-BijIDRVA.mjs.map +1 -1
- package/dist/repl-editor-DGJBfIt1.mjs.map +1 -1
- package/dist/schema-B6hJQWp6.mjs.map +1 -1
- package/dist/secret-file-C9wp_FCX.mjs.map +1 -1
- package/dist/secretmanager-vHQoXdQz.mjs.map +1 -1
- package/dist/seed/index.mjs.map +1 -1
- package/dist/seed-Cn-3JApy.mjs.map +1 -1
- package/dist/service-9SBPNpK8.mjs.map +1 -1
- package/dist/service-9rwi_I4d.mjs.map +1 -1
- package/dist/service_pb-Bbu2QSIr.mjs.map +1 -1
- package/dist/telemetry-DfT2UfI4.mjs +2 -0
- package/dist/telemetry-DfT2UfI4.mjs.map +1 -0
- package/dist/{telemetry-DpkFGBmu.mjs → telemetry-nqOtDWNO.mjs} +1 -1
- package/dist/type-source--ZNcV8RJ.mjs.map +1 -1
- package/dist/user-agent-vdHYF3QL.mjs.map +1 -1
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/vitest/environment.mjs.map +1 -1
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/setup.mjs.map +1 -1
- package/dist/wait-point-invoker-eiP-IIux.mjs.map +1 -1
- package/dist/wait-point-registry-B-ESkTZX.mjs.map +1 -1
- package/dist/workflow-Cs9ISw6j.mjs.map +1 -1
- package/dist/workspace_resource_pb-CaoM2npP.mjs.map +1 -1
- package/docs/ai.md +92 -0
- package/docs/cli/tailordb.md +17 -15
- package/docs/cli/workspace.md +1 -1
- package/docs/github-actions.md +98 -11
- package/docs/services/tailordb/migration.md +45 -31
- package/docs/testing.md +2 -1
- package/package.json +16 -9
- package/dist/kysely-type-BWMfV301.mjs.map +0 -1
- package/dist/register-ts-hook-CDnN_Jx2.mjs.map +0 -1
- package/dist/telemetry-Xk7J829P.mjs +0 -2
- package/dist/telemetry-Xk7J829P.mjs.map +0 -1
package/docs/ai.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Make choice, boolean, and ordered score decisions from application state through AI Gateway with the System One client from @tailor-platform/sdk/ai."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# System One
|
|
6
|
+
|
|
7
|
+
System One makes semantic decisions from application state, a question, and a fixed answer space. It returns the selected answer and its probability without requiring prompt construction or structured-output parsing.
|
|
8
|
+
|
|
9
|
+
Create a client with the URL the platform assigns to your deployed [AI Gateway](services/aigateway.md). Inside a Tailor Function, `aigateway.get()` returns it as `url`. Omit `token`; the platform authenticates the request:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { createSystemOne } from "@tailor-platform/sdk/ai";
|
|
13
|
+
import { aigateway } from "@tailor-platform/sdk/runtime";
|
|
14
|
+
|
|
15
|
+
const { url } = await aigateway.get("my-aigateway");
|
|
16
|
+
const systemOne = createSystemOne({ baseURL: url });
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
External clients pass the same URL, which `tailor show` lists, directly with an access token issued by the AI Gateway's auth namespace:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { createSystemOne } from "@tailor-platform/sdk/ai";
|
|
23
|
+
|
|
24
|
+
const systemOne = createSystemOne({
|
|
25
|
+
baseURL: "https://my-aigateway-{WORKSPACE_HASH}.ai.erp.dev",
|
|
26
|
+
token: accessToken,
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Choice decisions
|
|
31
|
+
|
|
32
|
+
Use `choice()` to select one value from an answer space. Literal types are inferred without `as const`:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
const result = await systemOne.choice({
|
|
36
|
+
state: { ticket, customer },
|
|
37
|
+
question: "Which department should handle this ticket?",
|
|
38
|
+
choices: ["billing", "sales", "support"],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// result.value: "billing" | "sales" | "support"
|
|
42
|
+
// result.probabilities: Record<"billing" | "sales" | "support", number>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Boolean decisions
|
|
46
|
+
|
|
47
|
+
Use `boolean()` for a binary decision. `value` is `true` when the probability of "yes" is at least `0.5`, and `probability` is the probability of the selected answer:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
const result = await systemOne.boolean({
|
|
51
|
+
state: invoice,
|
|
52
|
+
question: "Is this invoice a duplicate?",
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (result.value && result.probability > 0.95) {
|
|
56
|
+
// Apply the appropriate business rule.
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Ordered scores
|
|
61
|
+
|
|
62
|
+
Use `score()` when the answer space has a meaningful order. Levels are ordered from lowest to highest, and `value` is the level with the highest probability:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const result = await systemOne.score({
|
|
66
|
+
state: transaction,
|
|
67
|
+
question: "Assess the risk of this transaction.",
|
|
68
|
+
levels: ["low", "medium", "high"],
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Models
|
|
73
|
+
|
|
74
|
+
Decisions use `jev-1.13.0` unless a call passes `model`. `jev-latest` always points to the newest model, so its probabilities can shift when a new model is released. Use it only when your logic does not compare probabilities against fixed thresholds:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const result = await systemOne.boolean({
|
|
78
|
+
state: invoice,
|
|
79
|
+
question: "Is this invoice a duplicate?",
|
|
80
|
+
model: "jev-latest",
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Errors
|
|
85
|
+
|
|
86
|
+
Failures throw `SystemOneError` with a provider-independent `code`. Applications can handle stable codes such as `UNAUTHORIZED`, `RATE_LIMITED`, `PROVIDER_TIMEOUT`, and `PROVIDER_UNAVAILABLE` without depending on a model provider.
|
|
87
|
+
|
|
88
|
+
A decision waits until AI Gateway responds. To fail with `PROVIDER_TIMEOUT` instead, pass `timeoutMs`:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const systemOne = createSystemOne({ baseURL: url, timeoutMs: 10_000 });
|
|
92
|
+
```
|
package/docs/cli/tailordb.md
CHANGED
|
@@ -328,26 +328,28 @@ tailor tailordb migration test [options]
|
|
|
328
328
|
|
|
329
329
|
**Options**
|
|
330
330
|
|
|
331
|
-
| Option | Alias | Description
|
|
332
|
-
| --------------------------------------------- | ----- |
|
|
333
|
-
| `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID
|
|
334
|
-
| `--profile <PROFILE>` | `-p` | Workspace profile
|
|
335
|
-
| `--config <CONFIG>` | `-c` | Path to Tailor config file
|
|
336
|
-
| `--yes` | `-y` | Acknowledge that a designated target workspace may be overwritten
|
|
337
|
-
| `--data <DATA>` | - | Data source for the migration test (seed or clone)
|
|
338
|
-
| `--target-workspace-id <TARGET_WORKSPACE_ID>` | - | Existing throwaway workspace to retain after the test (requires --yes)
|
|
339
|
-
| `--keep` | - | Keep the automatically created workspace after the test
|
|
340
|
-
| `--
|
|
341
|
-
| `--
|
|
342
|
-
| `--
|
|
343
|
-
| `--
|
|
344
|
-
| `--
|
|
331
|
+
| Option | Alias | Description | Required | Default | Env |
|
|
332
|
+
| --------------------------------------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------- | --------------------------------- |
|
|
333
|
+
| `--workspace-id <WORKSPACE_ID>` | `-w` | Workspace ID | No | - | `TAILOR_PLATFORM_WORKSPACE_ID` |
|
|
334
|
+
| `--profile <PROFILE>` | `-p` | Workspace profile | No | - | `TAILOR_PLATFORM_PROFILE` |
|
|
335
|
+
| `--config <CONFIG>` | `-c` | Path to Tailor config file | No | `"tailor.config.ts"` | `TAILOR_CONFIG_PATH` |
|
|
336
|
+
| `--yes` | `-y` | Acknowledge that a designated target workspace may be overwritten | No | `false` | - |
|
|
337
|
+
| `--data <DATA>` | - | Data source for the migration test (seed or clone) | No | `"seed"` | - |
|
|
338
|
+
| `--target-workspace-id <TARGET_WORKSPACE_ID>` | - | Existing throwaway workspace to retain after the test (requires --yes) | No | - | - |
|
|
339
|
+
| `--keep` | - | Keep the automatically created workspace after the test | No | `false` | - |
|
|
340
|
+
| `--organization-id <ORGANIZATION_ID>` | - | Organization to create the temporary workspace in, at its root unless --folder-id is given (default: the source workspace's organization and folder). With --target-workspace-id, must match the target's organization | No | - | `TAILOR_PLATFORM_ORGANIZATION_ID` |
|
|
341
|
+
| `--folder-id <FOLDER_ID>` | - | Folder to create the temporary workspace in (default: the source workspace's folder). Requires --organization-id when the source workspace is not in an organization. With --target-workspace-id, must match the target's folder | No | - | `TAILOR_PLATFORM_FOLDER_ID` |
|
|
342
|
+
| `--assert <ASSERT>` | - | Path to a TypeScript assertion script to run after migrations | No | - | - |
|
|
343
|
+
| `--assert-namespace <ASSERT_NAMESPACE>` | - | TailorDB namespace exposed to the assertion script | No | - | - |
|
|
344
|
+
| `--keep-ttl <KEEP_TTL>` | - | Record an expiry on the kept workspace, e.g. 24h or 7d, so workspace prune --expired can delete it (requires --keep) | No | - | - |
|
|
345
|
+
| `--clone-timeout <CLONE_TIMEOUT>` | - | How long to wait for the clone to finish with --data clone, e.g. 30s or 10m (default: 30m) | No | - | - |
|
|
346
|
+
| `--machine-user <MACHINE_USER>` | - | Machine user for seed and assertion script execution | No | - | - |
|
|
345
347
|
|
|
346
348
|
See [Global Options](../cli-reference.md#global-options) for options available to all commands.
|
|
347
349
|
|
|
348
350
|
**Notes**
|
|
349
351
|
|
|
350
|
-
The source workspace is read-only. Without --target-workspace-id, the command creates a workspace in the source workspace's region and deletes it after success or failure; pass --keep to retain it for inspection. A designated target is retained and requires --yes. Clone mode copies TailorDB records only; it does not copy IdP users or file blobs. With --keep-ttl, the kept workspace records an expiry; it is not deleted automatically, but workspace prune --expired removes it once the expiry has passed.
|
|
352
|
+
The source workspace is read-only. Without --target-workspace-id, the command creates a workspace in the source workspace's region and deletes it after success or failure; pass --keep to retain it for inspection. Right after creating the workspace it records a 24h expiry (unless --keep is given without --keep-ttl), so if the run is interrupted before the command can delete the workspace, workspace prune --expired removes it later. A designated target is retained and requires --yes. Clone mode copies TailorDB records only; it does not copy IdP users or file blobs. With --keep-ttl, the kept workspace records an expiry; it is not deleted automatically, but workspace prune --expired removes it once the expiry has passed. Organization and folder IDs loaded by --env-file are used the same way as the options; command-line options take precedence, and empty env-file values are ignored.
|
|
351
353
|
|
|
352
354
|
#### tailordb migration validate
|
|
353
355
|
|
package/docs/cli/workspace.md
CHANGED
|
@@ -107,7 +107,7 @@ tailor workspace create [options]
|
|
|
107
107
|
| Option | Alias | Description | Required | Default | Env |
|
|
108
108
|
| ------------------------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------- | --------------------------------- |
|
|
109
109
|
| `--name <NAME>` | `-n` | Workspace name | Yes | - | - |
|
|
110
|
-
| `--region <REGION>` | `-r` | Workspace region (asia-northeast, us-west)
|
|
110
|
+
| `--region <REGION>` | `-r` | Workspace region (asia-northeast, us-west, europe-west) | Yes | - | - |
|
|
111
111
|
| `--delete-protection` | `-d` | Enable delete protection | No | `false` | - |
|
|
112
112
|
| `--organization-id <ORGANIZATION_ID>` | `-o` | Organization ID to workspace associate with | No | - | `TAILOR_PLATFORM_ORGANIZATION_ID` |
|
|
113
113
|
| `--folder-id <FOLDER_ID>` | `-f` | Folder ID to workspace associate with | No | - | `TAILOR_PLATFORM_FOLDER_ID` |
|
package/docs/github-actions.md
CHANGED
|
@@ -117,6 +117,92 @@ all-added or all-removed viewer artifacts. Re-run `setup ci branch` after adding
|
|
|
117
117
|
removing TailorDB namespaces. `setup check` reports drift when the recorded ERD
|
|
118
118
|
preview namespaces no longer match the current config.
|
|
119
119
|
|
|
120
|
+
#### Migration test on a labeled pull request
|
|
121
|
+
|
|
122
|
+
Pass `--migration-test` on a branch target to add a job that runs
|
|
123
|
+
[`tailor tailordb migration test`](./cli/tailordb.md) against a pull request on
|
|
124
|
+
demand. It is opt-in and requires a config with TailorDB migrations.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
tailor setup ci branch --name my-app-stg --migration-test
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The job runs only when someone adds the `tailor:migration-test` label to a pull
|
|
131
|
+
request from the same repository (change the label with
|
|
132
|
+
`--migration-test-label`). It runs the pending migrations in a temporary
|
|
133
|
+
workspace created next to the source workspace, writes the `--json` result to
|
|
134
|
+
the job summary, and removes the label as its last step, whether the test
|
|
135
|
+
succeeded, failed, or was cancelled while running. To run it again, add the label
|
|
136
|
+
again. If a run is cancelled before the job starts (for example, a reviewer
|
|
137
|
+
rejects the environment's approval), the label stays on the pull request: remove
|
|
138
|
+
it and add it again.
|
|
139
|
+
Anyone who can label pull requests in your repository can start the job, and
|
|
140
|
+
each run creates and deletes a workspace. Runs for one pull request never
|
|
141
|
+
cancel each other.
|
|
142
|
+
|
|
143
|
+
The generated workflow also lists `labeled` in its `pull_request` types. The
|
|
144
|
+
plan and ERD preview jobs skip label events, so adding an unrelated label does
|
|
145
|
+
not re-run them.
|
|
146
|
+
|
|
147
|
+
Runs started by a label report their result job as `tailor-result (<name>) [label]`
|
|
148
|
+
instead of `tailor-result (<name>)`. A label event therefore never replaces the
|
|
149
|
+
result of the check you require for branch protection. The migration test result
|
|
150
|
+
appears only under the `[label]` name, so it does not block merging through the
|
|
151
|
+
check you require.
|
|
152
|
+
|
|
153
|
+
The job clones the source workspace's TailorDB records and passes
|
|
154
|
+
`--clone-timeout 30m`, which bounds only the wait for the data clone. If the clone takes longer, the command
|
|
155
|
+
fails with the clone's operation ID in the error and removes its temporary
|
|
156
|
+
workspace, while the clone itself keeps running on the platform.
|
|
157
|
+
|
|
158
|
+
The migration test step is limited to 50 minutes and the job to 60, so the label
|
|
159
|
+
is still removed when the step times out. A step that is stopped at its limit
|
|
160
|
+
(or a job cancelled at the job limit) gives the command no chance to clean up:
|
|
161
|
+
delete the leftover temporary workspace with `tailor workspace delete`.
|
|
162
|
+
|
|
163
|
+
##### Choosing the source workspace
|
|
164
|
+
|
|
165
|
+
`migration test` reads the source workspace (it is not modified), builds a
|
|
166
|
+
temporary workspace from it in the same organization and folder, and deletes
|
|
167
|
+
that workspace afterwards. Because the machine user creates and deletes that
|
|
168
|
+
workspace, it needs an editor or admin role on the organization or folder that
|
|
169
|
+
holds the source workspace; a viewer role is not enough. The clone also needs the
|
|
170
|
+
same role on the source side. The clone copies TailorDB records only: IdP users
|
|
171
|
+
and file blobs are not copied.
|
|
172
|
+
|
|
173
|
+
Two setups are supported:
|
|
174
|
+
|
|
175
|
+
- **Source is the plan/deploy workspace (default).** The job uses the same GitHub
|
|
176
|
+
Environment as the plan and deploy jobs, so it reads the same
|
|
177
|
+
`TAILOR_PLATFORM_WORKSPACE_ID` variable and machine-user secrets. Nothing
|
|
178
|
+
extra to configure. If that workspace holds too little data to be a useful
|
|
179
|
+
test, point the job at a workspace that does with the next setup.
|
|
180
|
+
- **Source is a different workspace, such as production.** Pass
|
|
181
|
+
`--migration-test-environment <env>`. The job then uses that GitHub
|
|
182
|
+
Environment and reads the source workspace from its
|
|
183
|
+
`TAILOR_PLATFORM_MIGRATION_TEST_SOURCE_WORKSPACE_ID` variable, together with the
|
|
184
|
+
machine-user secrets set on that same environment. Give this environment a
|
|
185
|
+
machine user whose role you are willing to hold on the source workspace's
|
|
186
|
+
organization or folder, since it needs the editor-or-admin role described
|
|
187
|
+
above. Pending migrations run from the source workspace's migration number up
|
|
188
|
+
to the latest, so a source that is behind the deploy target replays more
|
|
189
|
+
migrations, which is closer to what a production deploy will do.
|
|
190
|
+
|
|
191
|
+
A job can declare only one GitHub Environment, and a repository secret or
|
|
192
|
+
variable is read from that environment, which is why a different source needs its
|
|
193
|
+
own environment. `tailor setup ci env` prints what each environment needs,
|
|
194
|
+
including the dedicated one. Keep the dedicated environment separate from your
|
|
195
|
+
production deploy environment: a pull request job runs on the pull request merge
|
|
196
|
+
ref (`refs/pull/<number>/merge`), so if an environment restricts which branches
|
|
197
|
+
may deploy or requires reviewers, check how that affects the pull request job
|
|
198
|
+
before pointing the migration test at it. A required-reviewers rule makes the
|
|
199
|
+
job wait for approval before it can read the environment's secrets. The job runs
|
|
200
|
+
the pull request's own code with that environment's credentials, so add one when
|
|
201
|
+
the source workspace holds production data.
|
|
202
|
+
|
|
203
|
+
Fork pull requests cannot read secrets, so the job is skipped for them.
|
|
204
|
+
`--migration-test` is not available together with several `--dir` values.
|
|
205
|
+
|
|
120
206
|
### Tag target (recommended for production)
|
|
121
207
|
|
|
122
208
|
The tag target fires when a tag matching `--tag-pattern` (default `v*`) is
|
|
@@ -501,17 +587,18 @@ tailor setup ci env --check # check what is registered in GitHu
|
|
|
501
587
|
|
|
502
588
|
The list follows what each generated workflow actually reads:
|
|
503
589
|
|
|
504
|
-
| Name
|
|
505
|
-
|
|
|
506
|
-
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID`
|
|
507
|
-
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET`
|
|
508
|
-
| `TAILOR_PLATFORM_WORKSPACE_ID`
|
|
509
|
-
| `
|
|
510
|
-
| `
|
|
511
|
-
| `
|
|
512
|
-
| `
|
|
513
|
-
| `
|
|
514
|
-
| `
|
|
590
|
+
| Name | Kind | Targets | Required | Where the value comes from |
|
|
591
|
+
| ---------------------------------------------------- | -------- | ----------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
592
|
+
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID` | variable | all | yes | Client ID of the platform machine user CI signs in as (an existing secret of the same name still works as a deprecated fallback); it needs an editor or admin role on the organization or folder that holds the workspace. An organization or folder admin creates one in the Tailor Console and grants it a role; without the required permission you cannot view or create machine users |
|
|
593
|
+
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET` | secret | all | yes | Client secret of the same platform machine user |
|
|
594
|
+
| `TAILOR_PLATFORM_WORKSPACE_ID` | variable | branch, tag | yes | `id` printed by `tailor workspace create`, or listed by `tailor workspace list` |
|
|
595
|
+
| `TAILOR_PLATFORM_MIGRATION_TEST_SOURCE_WORKSPACE_ID` | variable | branch (migration test environment) | yes | ID of the workspace the migration test starts from, set on the environment passed to `--migration-test-environment`; it is only read to build the temporary workspace. Needs the machine user's editor or admin role on that workspace's organization or folder |
|
|
596
|
+
| `TAILOR_PLATFORM_ORGANIZATION_ID` | variable | preview | yes | Organization to create the per-PR workspaces in (a machine user cannot create a workspace without one): `organizationId` listed by `tailor organization list` |
|
|
597
|
+
| `TAILOR_PLATFORM_FOLDER_ID` | variable | preview | no | Folder to create the per-PR workspaces in: `id` listed by `tailor organization folder list -o <organization id>`. When unset they go directly under the organization, which needs the machine user's role on the organization itself |
|
|
598
|
+
| `TAILOR_PLATFORM_FAIL_ON_DRIFT` | variable | all | no | `true` to fail the drift check when it finds drift |
|
|
599
|
+
| `TAILOR_SLACK_BOT_TOKEN` | secret | branch, tag | no | Bot User OAuth Token (`xoxb-...`) of a Slack app with the `chat:write` scope |
|
|
600
|
+
| `TAILOR_SLACK_CHANNEL_ID` | variable | branch, tag | no | Channel ID (`C...`) from the channel details in Slack; invite the bot to the channel |
|
|
601
|
+
| `TAILOR_SLACK_USER_MAPPING` | variable | branch, tag | no | JSON object mapping GitHub usernames to Slack member IDs (for example `{"alice":"U0123456"}`) so notifications mention the actor; read only after you uncomment the `user-mapping` input of the `tailor-notify` step |
|
|
515
602
|
|
|
516
603
|
See [Account management](https://docs.tailor.tech/administration/account-management)
|
|
517
604
|
for how organizations, folders, workspaces, and machine users relate.
|
|
@@ -173,9 +173,17 @@ During deploy, the pre-migration phase keeps the old field and adds the new fiel
|
|
|
173
173
|
|
|
174
174
|
If you decline the prompt (or confirm the removal with `--drop`), the change stays a plain removal + addition with the usual data-loss warning.
|
|
175
175
|
|
|
176
|
+
#### Changing nested member constraints
|
|
177
|
+
|
|
178
|
+
Adding a required member, making an existing member required, or removing enum values inside a nested field requires a migration script, including inside arrays of objects. During Pre-migration, added or newly required members are optional and removed enum values remain allowed. Post-migration enforces the target constraints after your script fills missing values or replaces removed enum values. A newly added optional object may keep required children: those children are required only when the object is present.
|
|
179
|
+
|
|
180
|
+
The generated script includes a `TODO` for each nested constraint change. Replace these with updates to the containing nested field, preserving its other members and handling objects inside arrays. A confirmed member rename generates its copy step alongside these TODOs.
|
|
181
|
+
|
|
182
|
+
Changing a nested member's type, array-ness, decimal scale, or foreign key target is unsupported in a single migration. Use separate migrations to add a member with the target shape, copy or transform values in a custom script, and then remove the old member.
|
|
183
|
+
|
|
176
184
|
#### Renaming a member inside a nested field
|
|
177
185
|
|
|
178
|
-
Members inside a **nested field** (`db.object(...)`) are detected the same way: when `migration generate` finds a member removed from a nested field and a compatible member added under the same parent, it asks whether the member was renamed. Two members qualify only when copying the value preserves it exactly, because
|
|
186
|
+
Members inside a **nested field** (`db.object(...)`) are detected the same way: when `migration generate` finds a member removed from a nested field and a compatible member added under the same parent, it asks whether the member was renamed. Two members qualify only when copying the value preserves it exactly, because a rename copies existing values without transforming them: the type, array-ness, requiredness, foreign key target, decimal scale, hooks, and validations must match (index, unique, and vector may differ, as for a top-level rename), enum values may be added but not removed, an object-typed member must keep the same members recursively, and serial members never qualify.
|
|
179
187
|
|
|
180
188
|
```
|
|
181
189
|
? User.address.zip was removed and zipCode was added with a compatible type. Was it renamed to zipCode? (Y/n)
|
|
@@ -199,7 +207,7 @@ Warning: data loss possible:
|
|
|
199
207
|
- User.address.zip: Nested member removed (existing values will no longer be accessible through the schema). Possibly renamed to zipCode: confirm it with --rename "User.address.zip:<newName>" to scaffold a copy script, or keep the removal and copy the values yourself
|
|
200
208
|
```
|
|
201
209
|
|
|
202
|
-
The pre-migration phase keeps a removed member on the nested field until the script finishes, exactly like a removed top-level field, so a custom script can still read it. Nested fields reach the script as objects. Renaming a nested member cannot be combined in one migration with renaming its table or the nested field itself, and an object-typed member cannot be renamed in the same migration as one of its own members; split such changes into separate migrations (rename the object first, then its member).
|
|
210
|
+
The pre-migration phase keeps a removed member on the nested field until the script finishes, exactly like a removed top-level field, so a custom script can still read it. Nested fields reach the script as objects. Renaming a nested member requires every ancestor, including the top-level nested field, to keep its nested type and array-ness. It cannot be combined in one migration with renaming its table or the nested field itself, and an object-typed member cannot be renamed in the same migration as one of its own members; split such changes into separate migrations (rename the object first, then its member).
|
|
203
211
|
|
|
204
212
|
### Renaming a table
|
|
205
213
|
|
|
@@ -465,33 +473,35 @@ Tables that the failed migration removes are deleted with their data under `--co
|
|
|
465
473
|
|
|
466
474
|
## Supported Schema Changes
|
|
467
475
|
|
|
468
|
-
| Change Type
|
|
469
|
-
|
|
|
470
|
-
| Add optional field
|
|
471
|
-
| Add required field
|
|
472
|
-
| Remove field
|
|
473
|
-
| Rename field
|
|
474
|
-
| Remove nested member
|
|
475
|
-
|
|
|
476
|
-
| Change
|
|
477
|
-
|
|
|
478
|
-
|
|
|
479
|
-
|
|
|
480
|
-
|
|
|
481
|
-
|
|
|
482
|
-
|
|
|
483
|
-
| Remove
|
|
484
|
-
|
|
|
485
|
-
|
|
|
486
|
-
|
|
|
487
|
-
| Add
|
|
488
|
-
| Remove
|
|
489
|
-
|
|
|
490
|
-
|
|
|
491
|
-
|
|
|
492
|
-
| Change
|
|
493
|
-
| Change
|
|
494
|
-
| Change
|
|
476
|
+
| Change Type | Breaking? | Migration Script? | Notes |
|
|
477
|
+
| ----------------------------------------------------------------------------- | --------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
478
|
+
| Add optional field | No | No | Schema change only |
|
|
479
|
+
| Add required field | Yes | Yes | Script populates default values |
|
|
480
|
+
| Remove field | No | Optional | Warning tier — no script is auto-generated, but you can add one with `tailordb migration script` to preserve or clear data before the field leaves the active schema. The field stays readable from `migrate.ts` during Pre-migration. |
|
|
481
|
+
| Rename field | Yes | Yes | Confirmed interactively at generate time or via `--rename "Table.oldField:newField"` — see [Renaming a field](#renaming-a-field). Auto-generated script copies values from the old field to the new one; both fields coexist during Pre-migration. |
|
|
482
|
+
| Remove nested member | No | Optional | Warning tier — see [Renaming a member inside a nested field](#renaming-a-member-inside-a-nested-field). The member stays readable from `migrate.ts` during Pre-migration. |
|
|
483
|
+
| Add required nested member / make member required / remove nested enum values | Yes | Yes | Pre-migration relaxes the member constraints. Complete the generated TODOs to transform the nested values before Post-migration. |
|
|
484
|
+
| Change nested member type / array-ness / decimal scale / foreign key target | Rejected | — | Add a new member, transform and copy values, then remove the old member in separate migrations. |
|
|
485
|
+
| Rename nested member | Yes | Yes | Confirmed interactively at generate time or via `--rename "Table.field.oldMember:newMember"`. Auto-generated script rewrites each row's nested value; the old member stays readable and the new member is optional during Pre-migration. |
|
|
486
|
+
| Change optional → required | Yes | Yes | Script sets defaults for null values |
|
|
487
|
+
| Change required → optional | No | No | Schema change only |
|
|
488
|
+
| Add index (non-unique) | No | No | Schema change only |
|
|
489
|
+
| Add unique index | Yes | Yes | Script must resolve duplicate value combinations across the index fields |
|
|
490
|
+
| Change unique index fields | Yes | Yes | Treated like adding a new unique constraint over the new field set |
|
|
491
|
+
| Remove index | No | No | Schema change only (removing the unique constraint from an index is also non-breaking) |
|
|
492
|
+
| Add unique constraint | Yes | Yes | Script must resolve duplicate values |
|
|
493
|
+
| Remove unique constraint | No | No | Schema change only |
|
|
494
|
+
| Change decimal scale | Yes | Yes | Auto-generated script re-saves existing rows under the new scale. Decreasing scale rounds values half-up and can lose precision. If the same change adds a unique constraint, duplicate handling runs after re-saving. |
|
|
495
|
+
| Add enum value | No | No | Schema change only |
|
|
496
|
+
| Remove enum value | Yes | Yes | Script migrates records with removed values |
|
|
497
|
+
| Add table | No | No | Schema change only |
|
|
498
|
+
| Remove table | No | Optional | Warning tier — no script is auto-generated, but you can add one with `tailordb migration script` to preserve data before the table leaves the active schema. The table stays readable from `migrate.ts` during Pre-migration. |
|
|
499
|
+
| Rename table | Yes | Yes | Confirmed interactively at generate time or via `--rename "OldTable:NewTable"` — see [Renaming a table](#renaming-a-table). Auto-generated script copies all rows preserving ids; both tables coexist until post-migration cleanup. |
|
|
500
|
+
| Change foreign key target table | Yes | Yes | Script updates references to the new target |
|
|
501
|
+
| Change field type (verified pair) | Yes | Yes | In-place for the pairs listed under [Field type changes](#field-type-changes); review the generated normalization scaffold and customize it only when existing values need transformation |
|
|
502
|
+
| Change field type (other pair) | Yes | Yes | Two migrations, generated together after you confirm — see [Converting a field type](#converting-a-field-type). Edit the conversion in the first; the second needs no changes. |
|
|
503
|
+
| Change array → single value | - | - | **Not supported** — see [Converting a field type](#converting-a-field-type) |
|
|
504
|
+
| Change single value → array | Yes | Yes | Two migrations, generated together after you confirm — see [Converting a field type](#converting-a-field-type). Each stored value becomes a one-element array, so the conversion needs no edits. |
|
|
495
505
|
|
|
496
506
|
### Field type changes
|
|
497
507
|
|
|
@@ -611,13 +621,15 @@ Some changes are still rejected and need a temporary field you add yourself —
|
|
|
611
621
|
The command performs the following sequence:
|
|
612
622
|
|
|
613
623
|
1. Reads each migration-enabled namespace's `sdk-migration` checkpoint from the source workspace and reconstructs that exact snapshot from local migration history. A deployed namespace that has no checkpoint is treated as migration 0, as `tailor deploy` does, but only when its schema matches the `0000` snapshot; otherwise the command fails and lists the differences. A namespace that was never deployed also fails.
|
|
614
|
-
2. Creates a temporary workspace in the same region
|
|
624
|
+
2. Creates a temporary workspace in the same region as the source, unless `--target-workspace-id` names an existing throwaway workspace. By default it is created in the source's organization and folder. `--organization-id` places it at the root of that organization, and `--folder-id` places it in that folder (together with `--organization-id` when the folder is in another organization or the source is not in an organization). With `--target-workspace-id`, the given values must match where that workspace already is.
|
|
615
625
|
3. Deploys the checkpoint snapshots and writes their checkpoint labels.
|
|
616
626
|
4. Loads fixture data or clones source records.
|
|
617
627
|
5. Runs the normal deployment pipeline, including every pending pre-migration, `migrate.ts`, and post-migration phase.
|
|
618
628
|
6. Optionally runs an assertion script against the migrated data.
|
|
619
629
|
7. Deletes an automatically-created workspace after success or failure.
|
|
620
630
|
|
|
631
|
+
Right after creating an automatically-created workspace (step 2), the command records a 24-hour expiry on it. If the run is interrupted before step 7 — for example, a CI job is cancelled or reaches its time limit — the command cannot delete the workspace, so it stays. Once the 24 hours have passed, `tailor workspace prune --expired` (with a location option such as `--organization-root`, `--folder-id`, or `--personal`) deletes it. A workspace given with `--target-workspace-id` is not given an expiry. If recording the expiry fails, the command warns and continues the test.
|
|
632
|
+
|
|
621
633
|
Both the pre-migration and final TailorDB schemas come from committed migration snapshots. Ungenerated changes in the current table definitions are not included in the rehearsal.
|
|
622
634
|
|
|
623
635
|
Executors are omitted from the baseline deployment so loading fixture or cloned records cannot trigger current event handlers against the older schema. Auth user profiles are also deferred until the pending migrations finish, while configured machine users remain available to run seed and migration scripts. The final deployment restores the configured executors and user profiles. Static websites are deployed so configuration references to their URLs resolve, but their workspace-bound custom domains are omitted from migration-test deployments.
|
|
@@ -667,6 +679,8 @@ To inspect the result after a run, pass `--keep` so the automatically created wo
|
|
|
667
679
|
tailor tailordb migration test --keep
|
|
668
680
|
```
|
|
669
681
|
|
|
682
|
+
A kept workspace records no expiry unless you also pass `--keep-ttl <age>` (for example `--keep-ttl 7d`), so `tailor workspace prune --expired` does not delete it.
|
|
683
|
+
|
|
670
684
|
Alternatively, provide an empty designated throwaway workspace. This mode never deletes the target and requires explicit acknowledgment:
|
|
671
685
|
|
|
672
686
|
```bash
|
|
@@ -685,7 +699,7 @@ When you run `tailor deploy`, the SDK detects pending migrations (anything past
|
|
|
685
699
|
|
|
686
700
|
For each pending migration:
|
|
687
701
|
|
|
688
|
-
1. **Pre-migration**: Schema changes that would be breaking are applied in a relaxed form first. A verified in-place field type change keeps its complete previous field contract until Post-migration, including field and table-level hooks or validators changed by the same migration. Newly-required fields are added as optional; fields whose `optional → required` transition is breaking are temporarily kept optional. Fields that are being removed in this migration are temporarily kept on the table so that `migrate.ts` can still read them (for example, to `innerJoin` through a foreign key that is about to be dropped); members removed from a nested field are kept the same way, and the new member of a confirmed nested rename is added as optional and non-unique. For a renamed field, the old field is kept and the new field is added with its constraints relaxed, so the script can read the old field and write the new one. For a renamed table, the new table is created with its full constraints while the old table stays on the namespace until post-migration cleanup, so the script can copy rows between them. Breaking table-level index changes are relaxed the same way: a newly-added unique index is withheld, and an index gaining a unique constraint (or a unique index changing its field set) keeps its previous definition, so `migrate.ts` can resolve duplicates first. Non-breaking changes that are part of the same migration are also applied here.
|
|
702
|
+
1. **Pre-migration**: Schema changes that would be breaking are applied in a relaxed form first. A verified in-place field type change keeps its complete previous field contract until Post-migration, including field and table-level hooks or validators changed by the same migration. Newly-required fields are added as optional; fields whose `optional → required` transition is breaking are temporarily kept optional. Fields that are being removed in this migration are temporarily kept on the table so that `migrate.ts` can still read them (for example, to `innerJoin` through a foreign key that is about to be dropped); members removed from a nested field are kept the same way, and the new member of a confirmed nested rename is added as optional and non-unique. Added or newly required nested members are optional and removed nested enum values remain allowed until Post-migration. For a renamed field, the old field is kept and the new field is added with its constraints relaxed, so the script can read the old field and write the new one. For a renamed table, the new table is created with its full constraints while the old table stays on the namespace until post-migration cleanup, so the script can copy rows between them. Breaking table-level index changes are relaxed the same way: a newly-added unique index is withheld, and an index gaining a unique constraint (or a unique index changing its field set) keeps its previous definition, so `migrate.ts` can resolve duplicates first. Non-breaking changes that are part of the same migration are also applied here.
|
|
689
703
|
2. **Script execution**: If `migrate.ts` exists on disk for this migration, it is bundled and runs on the platform as the configured machine user inside a transaction — or, for a script that exports [`steps`](#splitting-a-migration-into-steps), one transaction per step. The script is hard-required for breaking changes (`diff.requiresMigrationScript`) — deploy fails if the file is missing, unless a `--no-script` acknowledgment was recorded (see [Breaking changes without a script](#breaking-changes-without-a-script)). It is also executed when present for warning-tier diffs — see [Warnings and optional migration scripts](#warnings-and-optional-migration-scripts).
|
|
690
704
|
3. **Post-migration schema**: Required constraints and the target field definitions are applied. Do not assume that removing a field clears its underlying stored JSON value.
|
|
691
705
|
4. **Checkpoint and cleanup**: The `sdk-migration` label is bumped to this migration's number, then removed GQL permissions and tables — including the old table left behind by a rename — are deleted. Advancing the checkpoint first prevents a failed checkpoint write from requiring the SDK to recreate irreversibly deleted records.
|
package/docs/testing.md
CHANGED
|
@@ -209,11 +209,12 @@ test("upserts against real rows", async () => {
|
|
|
209
209
|
});
|
|
210
210
|
```
|
|
211
211
|
|
|
212
|
-
The generated columns follow the Kysely types, not TailorDB's storage: `text` for string and enum fields, `timestamptz` for datetime, `date` and `time` for date and time, `numeric` for decimal, rounded to the configured scale and read back with exactly that many fractional digits, `jsonb` for nested objects (and arrays of them), Postgres arrays for other array fields. `id` is a generated `uuid` primary key, `.unique()` fields and unique `.indexes()` are enforced, so `ON CONFLICT` upserts behave, and `.default()` values become column defaults (`"now"` becomes the current time). `.serial()` fields are assigned by the database from the configured `start`, `maxValue`, and format. Relations are not enforced.
|
|
212
|
+
The generated columns follow the Kysely types, not TailorDB's storage: `text` for string and enum fields, `timestamptz` for datetime, `date` and `time` for date and time, `numeric` for decimal, rounded to the configured scale and read back with exactly that many fractional digits, `jsonb` for nested objects (and arrays of them), Postgres arrays for other array fields. `id` is a generated `uuid` primary key, `.unique()` fields and unique `.indexes()` are enforced, so `ON CONFLICT` upserts behave, and `.default()` values become column defaults (`"now"` becomes the current time). `.serial()` fields are assigned by the database from the configured `start`, `maxValue`, and format. Relations are enforced as the platform does: a row that points at a parent that does not exist is rejected with an error containing `violates foreign key constraint`, so create parent rows before their children. This includes relations on array fields. A relation declared on a field inside a nested object is not enforced, as on the platform.
|
|
213
213
|
|
|
214
214
|
What the script cannot reproduce:
|
|
215
215
|
|
|
216
216
|
- Hooks, validations, and permissions do not run. A required field whose value only its own field-level create hook supplies is created nullable, so inserts that omit it succeed; give it a `.default()` if the test reads it back. A field filled by a table-level hook stays `NOT NULL`, as its Kysely type still requires it on insert.
|
|
217
|
+
- Relations on array fields, and relations from a field whose type differs from the field it points at (such as a `string` field related to `id`), are checked only when a row is written. Deleting a parent that such a row still points at is rejected by the platform but not by PGlite, and changing the parent's `id` is not checked either, so a test must not expect PGlite to reject them.
|
|
217
218
|
- 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
219
|
- `gapless` is not reproduced: the numbers come from a sequence, so an insert that fails still uses up its number.
|
|
219
220
|
- 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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-platform/sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.32.0",
|
|
4
4
|
"description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -82,6 +82,11 @@
|
|
|
82
82
|
"import": "./dist/seed/index.mjs",
|
|
83
83
|
"default": "./dist/seed/index.mjs"
|
|
84
84
|
},
|
|
85
|
+
"./ai": {
|
|
86
|
+
"types": "./dist/ai/index.d.mts",
|
|
87
|
+
"import": "./dist/ai/index.mjs",
|
|
88
|
+
"default": "./dist/ai/index.mjs"
|
|
89
|
+
},
|
|
85
90
|
"./vitest": {
|
|
86
91
|
"types": "./dist/vitest/index.d.mts",
|
|
87
92
|
"import": "./dist/vitest/index.mjs",
|
|
@@ -160,9 +165,10 @@
|
|
|
160
165
|
"@jridgewell/trace-mapping": "0.3.31",
|
|
161
166
|
"@napi-rs/keyring": "2.1.1",
|
|
162
167
|
"@opentelemetry/api": "1.9.1",
|
|
168
|
+
"@opentelemetry/context-async-hooks": "2.12.0",
|
|
163
169
|
"@opentelemetry/exporter-trace-otlp-proto": "0.223.0",
|
|
164
170
|
"@opentelemetry/resources": "2.12.0",
|
|
165
|
-
"@opentelemetry/sdk-trace
|
|
171
|
+
"@opentelemetry/sdk-trace": "2.12.0",
|
|
166
172
|
"@opentelemetry/semantic-conventions": "1.43.0",
|
|
167
173
|
"@oxc-project/types": "0.154.0",
|
|
168
174
|
"@politty/zod": "0.5.2",
|
|
@@ -182,7 +188,7 @@
|
|
|
182
188
|
"globals": "17.13.0",
|
|
183
189
|
"graphql": "17.0.2",
|
|
184
190
|
"inflection": "3.0.2",
|
|
185
|
-
"kysely": "0.29.
|
|
191
|
+
"kysely": "0.29.7",
|
|
186
192
|
"lines-db": "0.18.0",
|
|
187
193
|
"mime-types": "3.0.2",
|
|
188
194
|
"open": "11.0.4",
|
|
@@ -191,7 +197,7 @@
|
|
|
191
197
|
"pathe": "2.0.3",
|
|
192
198
|
"pgsql-ast-parser": "12.0.2",
|
|
193
199
|
"pkg-types": "2.3.3",
|
|
194
|
-
"rolldown": "1.2.
|
|
200
|
+
"rolldown": "1.2.14",
|
|
195
201
|
"semver": "7.8.5",
|
|
196
202
|
"sql-highlight": "6.1.0",
|
|
197
203
|
"std-env": "4.3.0",
|
|
@@ -203,21 +209,22 @@
|
|
|
203
209
|
"zod": "4.6.7"
|
|
204
210
|
},
|
|
205
211
|
"devDependencies": {
|
|
212
|
+
"@ark/attest": "0.57.0",
|
|
206
213
|
"@electric-sql/pglite": "0.5.10",
|
|
207
|
-
"@opentelemetry/sdk-trace-base": "2.12.0",
|
|
208
214
|
"@tailor-platform/shared": "^0.0.0",
|
|
209
215
|
"@tailor-platform/tailor-proto": "^0.0.1",
|
|
210
216
|
"@types/mime-types": "3.0.1",
|
|
211
217
|
"@types/node": "24.19.2",
|
|
212
218
|
"@types/semver": "7.8.0",
|
|
213
|
-
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
214
219
|
"@vitest/coverage-v8": "5.0.5",
|
|
215
|
-
"eslint-plugin-zod": "5.
|
|
220
|
+
"eslint-plugin-zod": "5.2.0",
|
|
216
221
|
"oxfmt": "0.73.0",
|
|
217
222
|
"oxlint": "1.88.0",
|
|
218
223
|
"oxlint-tsgolint": "7.0.2004",
|
|
219
224
|
"sonda": "0.14.0",
|
|
220
225
|
"tsdown": "0.23.1",
|
|
226
|
+
"tsrs": "0.16.0-ts7.1.0-dev.20260929",
|
|
227
|
+
"tsx": "4.23.15",
|
|
221
228
|
"typescript": "6.0.3",
|
|
222
229
|
"vitest": "5.0.5",
|
|
223
230
|
"zinfer": "0.4.7"
|
|
@@ -256,8 +263,8 @@
|
|
|
256
263
|
"check:import-cycles": "node --experimental-strip-types scripts/check-import-cycles.ts",
|
|
257
264
|
"lint:fix": "oxlint --type-aware . --fix",
|
|
258
265
|
"typecheck": "tsc --noEmit",
|
|
259
|
-
"typecheck:
|
|
260
|
-
"perf:
|
|
266
|
+
"typecheck:rs": "node scripts/typecheck-native.ts",
|
|
267
|
+
"perf:attest": "tsx scripts/perf/attest/run.ts",
|
|
261
268
|
"perf:runtime": "bash scripts/perf/runtime-perf.sh",
|
|
262
269
|
"postinstall": "node postinstall.mjs",
|
|
263
270
|
"measure:bundle": "node ../../scripts/measure-bundle-size-sonda.js",
|