@tailor-platform/sdk 2.0.0-next.1 → 2.0.0-next.2
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 +56 -0
- package/dist/application-Dtqap5jM.mjs +3 -0
- package/dist/{client-z_oHGVNy.mjs → application-XuMWK4eq.mjs} +5861 -20
- package/dist/application-XuMWK4eq.mjs.map +1 -0
- package/dist/cli/index.mjs +179 -122
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.d.mts +75 -16
- package/dist/cli/lib.mjs +5 -6
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/completion/zsh-worker.zsh +105 -26
- package/dist/configure/index.d.mts +9 -8
- package/dist/configure/index.mjs +56 -19
- package/dist/configure/index.mjs.map +1 -1
- package/dist/context-Bd266-ru.mjs.map +1 -1
- package/dist/{context-BuuIb8CC.d.mts → context-C2lEi9uw.d.mts} +7 -28
- package/dist/{crashreport-pr6Rhvza.mjs → crashreport-BMWcxeSE.mjs} +1 -1
- package/dist/{crashreport-BsjAkFWw.mjs → crashreport-DFq-vsU0.mjs} +5 -7
- package/dist/{crashreport-BsjAkFWw.mjs.map → crashreport-DFq-vsU0.mjs.map} +1 -1
- package/dist/{file-_oUZo76X.mjs → file-BbdFGdMV.mjs} +2 -10
- package/dist/file-BbdFGdMV.mjs.map +1 -0
- package/dist/{file-BB8Vs9O_.d.mts → file-Dq3NIt_F.d.mts} +3 -42
- package/dist/{file-utils-DcyIPFQh.mjs → file-utils-CYZnO1pX.mjs} +5 -5
- package/dist/file-utils-CYZnO1pX.mjs.map +1 -0
- package/dist/{globals-Crz8o65k.mjs → globals-Cf0sxIt8.mjs} +2 -2
- package/dist/{globals-Crz8o65k.mjs.map → globals-Cf0sxIt8.mjs.map} +1 -1
- package/dist/{http-adapter.generated-WgMnb7Sb.d.mts → http-adapter.generated-DFsXDdm5.d.mts} +11 -10
- package/dist/{index-BlpzXncY.d.mts → index-BI-_j9Z3.d.mts} +29 -32
- package/dist/{index-DjUdWlzf.d.mts → index-C4JirJH8.d.mts} +2 -2
- package/dist/{index-5vPyRu1y.d.mts → index-CZfWhr0a.d.mts} +2 -2
- package/dist/{index-CK7u9isy.d.mts → index-Cg8VKAdN.d.mts} +4 -4
- package/dist/{index-B7AKc18V.d.mts → index-DYRjoLXD.d.mts} +2 -2
- package/dist/{index-ZePLwxw7.d.mts → index-lFpcjHPU.d.mts} +8 -15
- package/dist/{index-CNYe5lnW.d.mts → index-nW7hE6oE.d.mts} +2 -2
- package/dist/{mock-BjFj5o1I.mjs → mock-FPxmnt-y.mjs} +4 -49
- package/dist/{mock-BjFj5o1I.mjs.map → mock-FPxmnt-y.mjs.map} +1 -1
- package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
- package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
- package/dist/plugin/builtin/file-utils/index.mjs +1 -1
- package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
- package/dist/plugin/builtin/seed/index.d.mts +1 -1
- package/dist/plugin/builtin/seed/index.mjs +1 -1
- package/dist/plugin/index.d.mts +4 -3
- package/dist/plugin/index.mjs.map +1 -1
- package/dist/{registry-DdsYlL_P.mjs → registry-DH4m7eYo.mjs} +4 -2
- package/dist/registry-DH4m7eYo.mjs.map +1 -0
- package/dist/runtime/context.d.mts +1 -1
- package/dist/runtime/file.d.mts +2 -2
- package/dist/runtime/file.mjs +2 -2
- package/dist/runtime/globals.d.mts +6 -6
- package/dist/runtime/index.d.mts +4 -4
- package/dist/runtime/index.mjs +2 -2
- package/dist/runtime/workflow.d.mts +2 -2
- package/dist/runtime/workflow.mjs +1 -1
- package/dist/{runtime-n9NCkjee.mjs → runtime-CY4JvrDj.mjs} +777 -234
- package/dist/runtime-CY4JvrDj.mjs.map +1 -0
- package/dist/{schema-BhkpP5Hw.mjs → schema-Dtw9Orye.mjs} +16 -13
- package/dist/schema-Dtw9Orye.mjs.map +1 -0
- package/dist/{secret-file-DBqZhjFQ.mjs → secret-file-VSVGy1V0.mjs} +27 -2
- package/dist/{secret-file-DBqZhjFQ.mjs.map → secret-file-VSVGy1V0.mjs.map} +1 -1
- package/dist/{seed-jf3008-h.mjs → seed-izIEyP3z.mjs} +3 -4
- package/dist/seed-izIEyP3z.mjs.map +1 -0
- package/dist/service-DCqIWibD.mjs +3 -0
- package/dist/{service-DU1mVzri.mjs → service-DU1mVzri2.mjs} +1 -1
- package/dist/service-DU1mVzri2.mjs.map +1 -0
- package/dist/{service-CCL8ruDf.mjs → service-DjyqbCaJ.mjs} +7 -7
- package/dist/{service-CCL8ruDf.mjs.map → service-DjyqbCaJ.mjs.map} +1 -1
- package/dist/test-env-key-D7UkZp99.mjs +75 -0
- package/dist/test-env-key-D7UkZp99.mjs.map +1 -0
- package/dist/{types-ClhIrW_C.mjs → types-74etvaxy.mjs} +1 -1
- package/dist/{types-DhO_VEZd.d.mts → types-BDRml5C3.d.mts} +12 -12
- package/dist/{types-B2RpYyA_.mjs → types-BQijbo4m.mjs} +9 -9
- package/dist/types-BQijbo4m.mjs.map +1 -0
- package/dist/{types-DwDgacni.d.mts → types-BX4q6Mo6.d.mts} +3 -2
- package/dist/types-BZ7QKVE8.d.mts +21 -0
- package/dist/{types-DCUhgpyI.d.mts → types-CdcQh4Z2.d.mts} +5 -76
- package/dist/utils/test/index.d.mts +6 -15
- package/dist/utils/test/index.mjs +4 -13
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/vitest/environment.mjs +1 -1
- package/dist/vitest/index.d.mts +2 -2
- package/dist/vitest/index.mjs +4 -4
- package/dist/vitest/setup.mjs +2 -2
- package/dist/{workflow-DgemCAz3.mjs → workflow-BOmaZwwG.mjs} +8 -3
- package/dist/workflow-BOmaZwwG.mjs.map +1 -0
- package/dist/{workflow-BbKvGLQg.d.mts → workflow-BVy4XWjS.d.mts} +15 -10
- package/dist/{workflow.generated-DtQwEo-x.d.mts → workflow.generated-ClEjBYhm.d.mts} +3 -3
- package/docs/cli/executor.md +53 -0
- package/docs/cli/setup.md +35 -33
- package/docs/cli/workflow.md +157 -20
- package/docs/cli-reference.md +26 -20
- package/docs/github-actions.md +29 -16
- package/docs/migration/v2.md +475 -0
- package/docs/runtime.md +1 -1
- package/docs/services/auth.md +12 -12
- package/docs/services/executor.md +3 -3
- package/docs/services/resolver.md +6 -6
- package/docs/services/tailordb.md +14 -12
- package/docs/services/workflow.md +4 -4
- package/docs/testing.md +59 -47
- package/package.json +7 -7
- package/dist/application-DB2r36Et.mjs +0 -3
- package/dist/application-DqS1yBg3.mjs +0 -5680
- package/dist/application-DqS1yBg3.mjs.map +0 -1
- package/dist/client-Dbohmtkv.mjs +0 -3
- package/dist/client-z_oHGVNy.mjs.map +0 -1
- package/dist/file-_oUZo76X.mjs.map +0 -1
- package/dist/file-utils-DcyIPFQh.mjs.map +0 -1
- package/dist/job-fuc3j1Ma.mjs +0 -53
- package/dist/job-fuc3j1Ma.mjs.map +0 -1
- package/dist/registry-DdsYlL_P.mjs.map +0 -1
- package/dist/runtime-n9NCkjee.mjs.map +0 -1
- package/dist/schema-BhkpP5Hw.mjs.map +0 -1
- package/dist/seed-jf3008-h.mjs.map +0 -1
- package/dist/service-D6yonf2I.mjs +0 -3
- package/dist/service-DU1mVzri.mjs.map +0 -1
- package/dist/test-env-key-D9kM6ETE.mjs +0 -49
- package/dist/test-env-key-D9kM6ETE.mjs.map +0 -1
- package/dist/types-B2RpYyA_.mjs.map +0 -1
- package/dist/workflow-DgemCAz3.mjs.map +0 -1
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
# Migrating to v2
|
|
2
|
+
|
|
3
|
+
<!-- Generated from the sdk-codemod registry. Run `pnpm codemod:docs:update` and edit `packages/sdk-codemod/src/registry.ts` instead of this file. -->
|
|
4
|
+
|
|
5
|
+
Run the codemods, then finish anything reported as not migrated automatically:
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npx @tailor-platform/sdk-codemod --from <current-version> --to <target-version>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## defineGenerators → definePlugins
|
|
12
|
+
|
|
13
|
+
**Migration:** Partially automatic
|
|
14
|
+
|
|
15
|
+
Migrate defineGenerators() tuple syntax to definePlugins() with explicit plugin imports
|
|
16
|
+
|
|
17
|
+
Before:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { defineGenerators } from "@tailor-platform/sdk";
|
|
21
|
+
|
|
22
|
+
export const generators = defineGenerators(
|
|
23
|
+
["@tailor-platform/kysely-type", { distPath: "db.ts" }],
|
|
24
|
+
);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
After:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { definePlugins } from "@tailor-platform/sdk";
|
|
31
|
+
import { kyselyTypePlugin } from "@tailor-platform/sdk/plugin/kysely-type";
|
|
32
|
+
|
|
33
|
+
export const generators = definePlugins(kyselyTypePlugin({ distPath: "db.ts" }));
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
<details>
|
|
37
|
+
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
defineGenerators() is replaced by definePlugins() in v2. The codemod rewrites the
|
|
41
|
+
known plugin tuples (kysely-type, enum-constants, file-utils, seed). For any
|
|
42
|
+
remaining defineGenerators([...]) the codemod left in place — a plugin it does not
|
|
43
|
+
know, or a non-tuple/spread form — convert it to definePlugins(pluginFn(config)),
|
|
44
|
+
importing the matching plugin from its @tailor-platform/sdk/plugin/<name> subpath.
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
## @tailor-platform/sdk/cli plugin imports → dedicated subpaths
|
|
50
|
+
|
|
51
|
+
**Migration:** Automatic
|
|
52
|
+
|
|
53
|
+
Rewrite deprecated plugin re-export imports (kyselyTypePlugin, enumConstantsPlugin, fileUtilsPlugin, seedPlugin) from `@tailor-platform/sdk/cli` to their dedicated plugin subpaths
|
|
54
|
+
|
|
55
|
+
Before:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { kyselyTypePlugin } from "@tailor-platform/sdk/cli";
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
After:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { kyselyTypePlugin } from "@tailor-platform/sdk/plugin/kysely-type";
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## function test-run --arg input unwrap
|
|
68
|
+
|
|
69
|
+
**Migration:** Automatic
|
|
70
|
+
|
|
71
|
+
Strip the deprecated {input: ...} wrapper from `tailor-sdk function test-run --arg` JSON in scripts and docs
|
|
72
|
+
|
|
73
|
+
Before:
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
tailor-sdk function test-run resolvers/add.ts --arg '{"input":{"a":1}}'
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
After:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
tailor-sdk function test-run resolvers/add.ts --arg '{"a":1}'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## tailor-sdk-skills → tailor-sdk skills install
|
|
86
|
+
|
|
87
|
+
**Migration:** Partially automatic
|
|
88
|
+
|
|
89
|
+
Replace deprecated `tailor-sdk-skills` invocations with `tailor-sdk skills install`
|
|
90
|
+
|
|
91
|
+
Before:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
npx tailor-sdk-skills
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
After:
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
tailor-sdk skills install
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
<details>
|
|
104
|
+
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
The standalone tailor-sdk-skills binary is removed in v2; call the skills install
|
|
108
|
+
subcommand on the main tailor-sdk CLI instead. Replace any remaining
|
|
109
|
+
tailor-sdk-skills invocations the codemod did not rewrite with
|
|
110
|
+
`tailor-sdk skills install`.
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
</details>
|
|
114
|
+
|
|
115
|
+
## Unify TailorUser/TailorActor/TailorActorType/TailorInvoker → TailorPrincipal
|
|
116
|
+
|
|
117
|
+
**Migration:** Partially automatic
|
|
118
|
+
|
|
119
|
+
Rename TailorUser/TailorActor/TailorActorType/TailorInvoker to TailorPrincipal, drop unauthenticatedTailorUser, rename resolver body `user` to `caller`, and rename TailorDB callback `user` to `invoker`
|
|
120
|
+
|
|
121
|
+
Type references unify under `TailorPrincipal`:
|
|
122
|
+
|
|
123
|
+
Before:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import type { TailorUser } from "@tailor-platform/sdk";
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
After:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
import type { TailorPrincipal } from "@tailor-platform/sdk";
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The resolver body `user` becomes `caller`:
|
|
136
|
+
|
|
137
|
+
Before:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
body: ({ input, user }) => user.id,
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
After:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
body: ({ input, caller }) => caller.id,
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
<details>
|
|
150
|
+
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
151
|
+
|
|
152
|
+
```text
|
|
153
|
+
Finish the cases the codemod left for manual migration:
|
|
154
|
+
- Rename user -> caller in resolver bodies the codemod skipped because a `caller`
|
|
155
|
+
binding already exists or renaming would shadow/collide with another value.
|
|
156
|
+
- Replace member-access on the removed unauthenticatedTailorUser (e.g.
|
|
157
|
+
unauthenticatedTailorUser.id); the codemod only replaced standalone references
|
|
158
|
+
with null and left member access to surface a type error.
|
|
159
|
+
- Review helper adapters that still accept or read `context.user`; v2 resolver
|
|
160
|
+
context uses nullable `caller` and `invoker`, so project-specific helper
|
|
161
|
+
semantics for anonymous callers and command invokers must be chosen explicitly.
|
|
162
|
+
- Review `caller?.` values passed to APIs that require non-null values. If the
|
|
163
|
+
resolver requires authentication, throw or otherwise narrow before the call;
|
|
164
|
+
if anonymous callers are allowed, keep the nullable flow explicit.
|
|
165
|
+
Use TailorPrincipal for the unified user/actor/invoker type.
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
</details>
|
|
169
|
+
|
|
170
|
+
## tailor-sdk apply → tailor-sdk deploy
|
|
171
|
+
|
|
172
|
+
**Migration:** Automatic
|
|
173
|
+
|
|
174
|
+
Rewrite `tailor-sdk apply` invocations in package.json scripts, shell scripts, CI configs, and docs to the canonical v2 `tailor-sdk deploy` command
|
|
175
|
+
|
|
176
|
+
Before:
|
|
177
|
+
|
|
178
|
+
```sh
|
|
179
|
+
tailor-sdk apply --profile prod
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
After:
|
|
183
|
+
|
|
184
|
+
```sh
|
|
185
|
+
tailor-sdk deploy --profile prod
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## v2 CLI rename
|
|
189
|
+
|
|
190
|
+
**Migration:** Partially automatic
|
|
191
|
+
|
|
192
|
+
Rewrite `tailor-sdk crash-report` to `tailor-sdk crashreport` and `--machineuser` to `--machine-user` across package.json scripts, shell scripts, CI configs, and docs
|
|
193
|
+
|
|
194
|
+
Before:
|
|
195
|
+
|
|
196
|
+
```sh
|
|
197
|
+
tailor-sdk crash-report list
|
|
198
|
+
tailor-sdk login --machineuser
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
After:
|
|
202
|
+
|
|
203
|
+
```sh
|
|
204
|
+
tailor-sdk crashreport list
|
|
205
|
+
tailor-sdk login --machine-user
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
<details>
|
|
209
|
+
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
210
|
+
|
|
211
|
+
```text
|
|
212
|
+
Apply the v2 CLI renames the codemod did not reach (only `tailor-sdk`-prefixed
|
|
213
|
+
invocations are rewritten): `tailor-sdk crash-report` -> `tailor-sdk crashreport`
|
|
214
|
+
and the `--machineuser` option -> `--machine-user`. Leave unrelated commands that
|
|
215
|
+
happen to use `--machineuser` alone.
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
</details>
|
|
219
|
+
|
|
220
|
+
## auth.invoker("name") → "name"
|
|
221
|
+
|
|
222
|
+
**Migration:** Partially automatic
|
|
223
|
+
|
|
224
|
+
Replace `auth.invoker("name")` calls with the bare `"name"` string and drop the `auth` import when no other reference remains. The `auth.invoker()` helper is deprecated in v2 because importing `auth` from `tailor.config.ts` into runtime files pulls Node-only modules into the bundle.
|
|
225
|
+
|
|
226
|
+
Before:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
createResolver({ invoker: auth.invoker("manager") });
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
After:
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
createResolver({ invoker: "manager" });
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
<details>
|
|
239
|
+
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
240
|
+
|
|
241
|
+
```text
|
|
242
|
+
In Tailor SDK v2 the auth.invoker() helper is removed; an invoker is now the
|
|
243
|
+
machine user name passed directly as a string. The codemod already rewrote the
|
|
244
|
+
string-literal form auth.invoker("name") to "name". These files still contain
|
|
245
|
+
auth.invoker(...) because the argument is not a plain string literal (a variable,
|
|
246
|
+
template literal, function call, or property access).
|
|
247
|
+
|
|
248
|
+
For each remaining auth.invoker(<expr>) call:
|
|
249
|
+
1. Replace the whole call with <expr> as-is (e.g. auth.invoker(name) becomes name).
|
|
250
|
+
2. Make sure <expr> evaluates to the machine user name (a string); adjust it if it
|
|
251
|
+
resolves to an object or an auth config value instead.
|
|
252
|
+
3. After removing every auth.invoker usage in a file, delete the now-unused auth
|
|
253
|
+
import (keeping it pulls Node-only config modules into runtime bundles); leave
|
|
254
|
+
the import if auth is still referenced elsewhere.
|
|
255
|
+
|
|
256
|
+
Do not change behavior beyond removing the auth.invoker() indirection.
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
</details>
|
|
260
|
+
|
|
261
|
+
## Tailordb → tailordb (lowercase ambient namespace)
|
|
262
|
+
|
|
263
|
+
**Migration:** Partially automatic
|
|
264
|
+
|
|
265
|
+
Rewrite references to the removed capital-cased `Tailordb` ambient namespace (`Tailordb.QueryResult`, `Tailordb.CommandType`, `Tailordb.Client`, `typeof Tailordb.Client`) to the lowercase `tailordb.*` namespace exposed by `@tailor-platform/sdk/runtime/globals`. Because v2 no longer activates ambient declarations automatically, each file that contains `tailordb.*` references after the rewrite must also add `import "@tailor-platform/sdk/runtime/globals"`.
|
|
266
|
+
|
|
267
|
+
Before:
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
const command: Tailordb.CommandType = "SELECT";
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
After:
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
import "@tailor-platform/sdk/runtime/globals";
|
|
277
|
+
const command: tailordb.CommandType = "SELECT";
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
<details>
|
|
281
|
+
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
282
|
+
|
|
283
|
+
```text
|
|
284
|
+
The capital-cased Tailordb ambient namespace is removed in v2; use the lowercase
|
|
285
|
+
tailordb.* namespace from @tailor-platform/sdk/runtime/globals. The codemod rewrites
|
|
286
|
+
the known members (QueryResult, CommandType, Client). Rewrite any other remaining
|
|
287
|
+
Tailordb.* reference to its tailordb.* equivalent (and confirm the member still
|
|
288
|
+
exists on the lowercase namespace).
|
|
289
|
+
Also add `import "@tailor-platform/sdk/runtime/globals"` at the top of each file
|
|
290
|
+
that contains any tailordb.* type reference — v2 no longer activates ambient
|
|
291
|
+
declarations automatically on SDK import.
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
</details>
|
|
295
|
+
|
|
296
|
+
## executeScript arg JSON.stringify → value
|
|
297
|
+
|
|
298
|
+
**Migration:** Partially automatic
|
|
299
|
+
|
|
300
|
+
Unwrap `JSON.stringify(...)` passed as the `executeScript` `arg` option. In v2 `arg` takes a JSON-serializable value and is serialized internally, so a pre-stringified argument double-encodes.
|
|
301
|
+
|
|
302
|
+
Before:
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
await executeScript({ ...opts, arg: JSON.stringify({ a: 1 }) });
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
After:
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
await executeScript({ ...opts, arg: { a: 1 } });
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
<details>
|
|
315
|
+
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
316
|
+
|
|
317
|
+
```text
|
|
318
|
+
In Tailor SDK v2 the executeScript() arg option takes a JSON-serializable value
|
|
319
|
+
and is serialized internally, so a pre-stringified argument double-encodes. The
|
|
320
|
+
codemod already rewrote the direct form arg: JSON.stringify(X) to arg: X. Review
|
|
321
|
+
the executeScript calls in these files for cases it could not rewrite — where the
|
|
322
|
+
arg value is reached indirectly, for example:
|
|
323
|
+
- a variable holding a JSON.stringify(...) result (const s = JSON.stringify(x); ... arg: s)
|
|
324
|
+
- JSON.stringify(x, null, 2) or another multi-argument form
|
|
325
|
+
- an options object built or spread dynamically
|
|
326
|
+
|
|
327
|
+
For each such call, pass the underlying value directly as arg (drop the
|
|
328
|
+
JSON.stringify wrapper) so executeScript serializes it once. Leave calls that
|
|
329
|
+
already pass a plain value unchanged.
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
</details>
|
|
333
|
+
|
|
334
|
+
## openDownloadStream → downloadStream
|
|
335
|
+
|
|
336
|
+
**Migration:** Manual
|
|
337
|
+
|
|
338
|
+
The deprecated `openDownloadStream` file-streaming API is removed in v2. Use `downloadStream` for streamed file downloads. The generated file utilities now emit `downloadFileStream` (which calls `downloadStream` and returns `FileDownloadStreamResponse`) instead of the removed `openFileDownloadStream` helper.
|
|
339
|
+
|
|
340
|
+
Before:
|
|
341
|
+
|
|
342
|
+
```ts
|
|
343
|
+
const res = await openDownloadStream(namespace, typeName, fieldName, recordId);
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
After:
|
|
347
|
+
|
|
348
|
+
```ts
|
|
349
|
+
const res = await downloadStream(namespace, typeName, fieldName, recordId);
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
<details>
|
|
353
|
+
<summary>Prompt for an AI agent (to perform this migration)</summary>
|
|
354
|
+
|
|
355
|
+
```text
|
|
356
|
+
The openDownloadStream file-streaming API is removed in v2. Replace every call to
|
|
357
|
+
openDownloadStream with downloadStream (same arguments). If you used the generated
|
|
358
|
+
openFileDownloadStream helper, switch to downloadFileStream, which calls
|
|
359
|
+
downloadStream and returns FileDownloadStreamResponse.
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
</details>
|
|
363
|
+
|
|
364
|
+
## Ambient runtime globals are opt-in
|
|
365
|
+
|
|
366
|
+
**Migration:** Manual
|
|
367
|
+
|
|
368
|
+
Importing `@tailor-platform/sdk` no longer activates the ambient `tailor.*` / `tailordb.*` global declarations. Normal SDK development does not need them — use the SDK APIs and the typed wrappers from `@tailor-platform/sdk/runtime`. Only if you relied on the ambient globals directly, add `import "@tailor-platform/sdk/runtime/globals"`. (The capital-cased `Tailordb.*` namespace is removed separately — see the `Tailordb → tailordb` codemod.)
|
|
369
|
+
|
|
370
|
+
Preferred: switch to the typed wrappers from `@tailor-platform/sdk/runtime` and drop the ambient globals:
|
|
371
|
+
|
|
372
|
+
Before:
|
|
373
|
+
|
|
374
|
+
```ts
|
|
375
|
+
const client = new tailor.idp.Client();
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
After:
|
|
379
|
+
|
|
380
|
+
```ts
|
|
381
|
+
import { idp } from "@tailor-platform/sdk/runtime";
|
|
382
|
+
const client = new idp.Client({ namespace: "my-namespace" });
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
Fallback: only if you must keep referencing the bare `tailor.*` names, opt into the global declarations:
|
|
386
|
+
|
|
387
|
+
Before:
|
|
388
|
+
|
|
389
|
+
```ts
|
|
390
|
+
const client = new tailor.idp.Client();
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
After:
|
|
394
|
+
|
|
395
|
+
```ts
|
|
396
|
+
import "@tailor-platform/sdk/runtime/globals";
|
|
397
|
+
const client = new tailor.idp.Client();
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
<details>
|
|
401
|
+
<summary>Prompt for an AI agent (to perform this migration)</summary>
|
|
402
|
+
|
|
403
|
+
```text
|
|
404
|
+
The v2 SDK no longer enables ambient Tailor runtime globals from
|
|
405
|
+
`@tailor-platform/sdk`. For each flagged file that uses `tailor.*`,
|
|
406
|
+
`tailordb.*`, or Tailor runtime error globals, prefer migrating to the
|
|
407
|
+
typed wrappers from `@tailor-platform/sdk/runtime` (e.g. replace
|
|
408
|
+
`new tailor.idp.Client()` with `import { idp } from "@tailor-platform/sdk/runtime"`
|
|
409
|
+
and `new idp.Client({ namespace })`). The wrappers are self-contained, so the
|
|
410
|
+
ambient globals are no longer needed.
|
|
411
|
+
|
|
412
|
+
Only when the file must keep referencing the bare `tailor.*` names directly,
|
|
413
|
+
opt into the global declarations instead by adding one of these:
|
|
414
|
+
- per-file: `import "@tailor-platform/sdk/runtime/globals";`
|
|
415
|
+
- project-wide: `"types": ["@tailor-platform/sdk/runtime/globals"]` in
|
|
416
|
+
the relevant tsconfig compilerOptions
|
|
417
|
+
|
|
418
|
+
Leave files unchanged when the matching name is local, imported from another
|
|
419
|
+
module, or appears only in comments or strings.
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
</details>
|
|
423
|
+
|
|
424
|
+
## Workflow .trigger() and trigger tests
|
|
425
|
+
|
|
426
|
+
**Migration:** Manual
|
|
427
|
+
|
|
428
|
+
Workflow job `.trigger()` now aligns with the platform runtime: it returns the job result directly instead of a Promise wrapper, and tests no longer run job bodies locally. Mock trigger responses with `mockWorkflow()` (`setJobHandler` / `enqueueResult`, assert via `triggeredJobs`), or use `runWorkflowLocally()` for a full-chain local run.
|
|
429
|
+
|
|
430
|
+
Tests must mock the workflow runtime instead of running bodies locally:
|
|
431
|
+
|
|
432
|
+
Before:
|
|
433
|
+
|
|
434
|
+
```ts
|
|
435
|
+
const result = await orderJob.trigger({ id });
|
|
436
|
+
expect(result.status).toBe("done");
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
After:
|
|
440
|
+
|
|
441
|
+
```ts
|
|
442
|
+
using wf = mockWorkflow();
|
|
443
|
+
wf.setJobHandler((jobName) => (jobName === "order-job" ? { status: "done" } : null));
|
|
444
|
+
const result = await orderJob.trigger({ id });
|
|
445
|
+
expect(result.status).toBe("done");
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
<details>
|
|
449
|
+
<summary>Prompt for an AI agent (to perform this migration)</summary>
|
|
450
|
+
|
|
451
|
+
```text
|
|
452
|
+
Workflow job .trigger() now uses the platform workflow runtime instead of running
|
|
453
|
+
the job body locally. In tests, acquire `using wf = mockWorkflow()` and provide
|
|
454
|
+
trigger responses (setJobHandler / enqueueResult), or use runWorkflowLocally() for a
|
|
455
|
+
full-chain local run; an unmocked trigger now throws. Outside tests, treat the
|
|
456
|
+
trigger result as the job output directly (no Promise wrapper to unwrap).
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
</details>
|
|
460
|
+
|
|
461
|
+
## Behavioral changes (no migration required)
|
|
462
|
+
|
|
463
|
+
These v2 changes alter runtime or CLI behavior; no source change is needed.
|
|
464
|
+
|
|
465
|
+
### CLI tokens stored in the OS keyring
|
|
466
|
+
|
|
467
|
+
CLI login tokens are stored in the OS keyring by default when available, falling back to the platform config file when it is not. No source change is required; re-login if you need tokens moved into the keyring.
|
|
468
|
+
|
|
469
|
+
### CLI users keyed by subject ID
|
|
470
|
+
|
|
471
|
+
The CLI stores human users by their stable subject ID instead of email (email is kept for display). Legacy email-keyed entries are migrated automatically on the next login or token refresh. No source change is required.
|
|
472
|
+
|
|
473
|
+
### function logs require a content hash for source mapping
|
|
474
|
+
|
|
475
|
+
`tailor-sdk function logs` maps stack traces against the function bundle only when the execution recorded a `contentHash`. Executions without one now show raw stack traces instead of mapped frames. No source change is required.
|
package/docs/runtime.md
CHANGED
|
@@ -78,7 +78,7 @@ The runtime entry re-exports the following namespaces. Detailed signatures, para
|
|
|
78
78
|
- `idp` — IdP user management (`new Client({ namespace })`)
|
|
79
79
|
- `workflow` — workflow & job control (`triggerWorkflow`, `triggerJobFunction`, `wait`, `resolve`)
|
|
80
80
|
- `context` — execution context (`getInvoker`)
|
|
81
|
-
- `file` — `tailordb.file` BLOB API (`upload`, `download`, `downloadAsBase64`, `delete`, `getMetadata`, `downloadStream`, `uploadStream
|
|
81
|
+
- `file` — `tailordb.file` BLOB API (`upload`, `download`, `downloadAsBase64`, `delete`, `getMetadata`, `downloadStream`, `uploadStream`)
|
|
82
82
|
|
|
83
83
|
## Testing
|
|
84
84
|
|
package/docs/services/auth.md
CHANGED
|
@@ -139,18 +139,18 @@ export const user = db.type("User", {
|
|
|
139
139
|
});
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
-
The `attributeList` values are accessible via `
|
|
142
|
+
The `attributeList` values are accessible via the runtime principal's `attributeList` as a tuple:
|
|
143
143
|
|
|
144
144
|
```typescript
|
|
145
145
|
// In a resolver
|
|
146
146
|
body: (context) => {
|
|
147
|
-
const [organizationId, teamId] = context.
|
|
147
|
+
const [organizationId, teamId] = context.caller?.attributeList ?? [];
|
|
148
148
|
},
|
|
149
149
|
|
|
150
150
|
// In TailorDB hooks
|
|
151
151
|
.hooks({
|
|
152
152
|
field: {
|
|
153
|
-
create: ({
|
|
153
|
+
create: ({ invoker }) => invoker?.attributeList[0] ?? null, // First UUID from list
|
|
154
154
|
},
|
|
155
155
|
})
|
|
156
156
|
```
|
|
@@ -160,7 +160,7 @@ body: (context) => {
|
|
|
160
160
|
When you want to use machine users without defining a `userProfile`, define `machineUserAttributes` instead. These attributes are used for:
|
|
161
161
|
|
|
162
162
|
- type-safe `machineUsers[*].attributes`
|
|
163
|
-
- `
|
|
163
|
+
- runtime principal `attributes` typing (via `tailor.d.ts`)
|
|
164
164
|
|
|
165
165
|
```typescript
|
|
166
166
|
import { defineAuth, t } from "@tailor-platform/sdk";
|
|
@@ -200,12 +200,12 @@ machineUsers: {
|
|
|
200
200
|
},
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
-
**attributes**: Values for attributes enabled in `userProfile.attributes` (or all fields defined in `machineUserAttributes` when `userProfile` is omitted). All enabled fields must be set here. These values are accessible via `
|
|
203
|
+
**attributes**: Values for attributes enabled in `userProfile.attributes` (or all fields defined in `machineUserAttributes` when `userProfile` is omitted). All enabled fields must be set here. These values are accessible via the runtime principal's `attributes`:
|
|
204
204
|
|
|
205
205
|
```typescript
|
|
206
206
|
// In a resolver
|
|
207
207
|
body: (context) => {
|
|
208
|
-
const role = context.
|
|
208
|
+
const role = context.caller?.attributes.role;
|
|
209
209
|
},
|
|
210
210
|
```
|
|
211
211
|
|
|
@@ -230,25 +230,25 @@ machineUsers: {
|
|
|
230
230
|
},
|
|
231
231
|
```
|
|
232
232
|
|
|
233
|
-
These values are accessible via `
|
|
233
|
+
These values are accessible via the runtime principal's `attributeList`:
|
|
234
234
|
|
|
235
235
|
```typescript
|
|
236
236
|
// In a resolver
|
|
237
237
|
body: (context) => {
|
|
238
|
-
const [organizationId, teamId] = context.
|
|
238
|
+
const [organizationId, teamId] = context.caller?.attributeList ?? [];
|
|
239
239
|
},
|
|
240
240
|
|
|
241
241
|
// In TailorDB hooks
|
|
242
242
|
.hooks({
|
|
243
243
|
field: {
|
|
244
|
-
create: ({
|
|
244
|
+
create: ({ invoker }) => invoker?.attributes.role === "ADMIN" ? "default" : null,
|
|
245
245
|
},
|
|
246
246
|
})
|
|
247
247
|
|
|
248
248
|
// In TailorDB validate
|
|
249
249
|
.validate({
|
|
250
250
|
field: [
|
|
251
|
-
({
|
|
251
|
+
({ invoker }) => invoker?.attributes.role === "ADMIN",
|
|
252
252
|
"Only admins can set this field",
|
|
253
253
|
],
|
|
254
254
|
})
|
|
@@ -269,7 +269,7 @@ tailor-sdk machineuser token <name>
|
|
|
269
269
|
|
|
270
270
|
### Specifying a machine user invoker
|
|
271
271
|
|
|
272
|
-
Resolvers, executors, and `workflow.trigger()` accept an `
|
|
272
|
+
Resolvers, executors, and `workflow.trigger()` accept an `invoker` option that chooses which machine user runs the operation. Pass the machine user name as a plain string — it is type-narrowed to the names you registered in `machineUsers`.
|
|
273
273
|
|
|
274
274
|
```typescript
|
|
275
275
|
// tailor.config.ts
|
|
@@ -298,7 +298,7 @@ export default createResolver({
|
|
|
298
298
|
// Trigger workflow with machine user permissions
|
|
299
299
|
const workflowRunId = await myWorkflow.trigger(
|
|
300
300
|
{ id: input.id },
|
|
301
|
-
{
|
|
301
|
+
{ invoker: "admin-machine-user" },
|
|
302
302
|
);
|
|
303
303
|
return { workflowRunId };
|
|
304
304
|
},
|
|
@@ -219,7 +219,7 @@ createExecutor({
|
|
|
219
219
|
});
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
-
Executor callbacks receive the trigger args, including `env` from `defineConfig({ env })`. `function` and `jobFunction` `body` args also include an `invoker` field: the principal running this function,
|
|
222
|
+
Executor callbacks receive the trigger args, including `env` from `defineConfig({ env })`. `function` and `jobFunction` `body` args also include an `invoker` field: the principal running this function, or the machine user configured through the operation `invoker` option; `null` for anonymous calls. Other operation kinds (`graphql`, `webhook`, `workflow`) receive `env` through their callback args but do not pass `invoker` into those callbacks.
|
|
223
223
|
|
|
224
224
|
### Job Function Operation
|
|
225
225
|
|
|
@@ -331,7 +331,7 @@ createExecutor({
|
|
|
331
331
|
|
|
332
332
|
### Authentication for Operations
|
|
333
333
|
|
|
334
|
-
GraphQL and Workflow operations can specify an `
|
|
334
|
+
GraphQL and Workflow operations can specify an `invoker` to execute with machine user credentials. Pass the machine user name as a plain string — it is type-narrowed to the names defined in your auth config:
|
|
335
335
|
|
|
336
336
|
```typescript
|
|
337
337
|
import { createExecutor, scheduleTrigger } from "@tailor-platform/sdk";
|
|
@@ -342,7 +342,7 @@ export default createExecutor({
|
|
|
342
342
|
operation: {
|
|
343
343
|
kind: "graphql",
|
|
344
344
|
query: `mutation { cleanupOldRecords { count } }`,
|
|
345
|
-
|
|
345
|
+
invoker: "batch-processor",
|
|
346
346
|
},
|
|
347
347
|
});
|
|
348
348
|
```
|
|
@@ -208,7 +208,7 @@ Validation functions receive:
|
|
|
208
208
|
|
|
209
209
|
- `value` - The field value being validated
|
|
210
210
|
- `data` - The entire input object
|
|
211
|
-
- `
|
|
211
|
+
- `invoker` - The principal performing the operation
|
|
212
212
|
|
|
213
213
|
You can specify validation as:
|
|
214
214
|
|
|
@@ -234,8 +234,8 @@ Validation runs automatically before the `body` function executes. When validati
|
|
|
234
234
|
Define actual resolver logic in the `body` function. Function arguments include:
|
|
235
235
|
|
|
236
236
|
- `input` - Input data from GraphQL request
|
|
237
|
-
- `
|
|
238
|
-
- `invoker` - The principal running this function; equals `
|
|
237
|
+
- `caller` - The user or machine user who called this resolver; unaffected by `invoker`. `null` for anonymous calls.
|
|
238
|
+
- `invoker` - The principal running this function; equals `caller` by default, or the machine user configured through the resolver `invoker` option. `null` for anonymous calls.
|
|
239
239
|
- `env` - Environment variables declared in `tailor.config.ts`
|
|
240
240
|
|
|
241
241
|
### Using Kysely for Database Access
|
|
@@ -352,7 +352,7 @@ createResolver({
|
|
|
352
352
|
|
|
353
353
|
## Authentication
|
|
354
354
|
|
|
355
|
-
Specify an `
|
|
355
|
+
Specify an `invoker` to execute the resolver with machine user credentials. Pass the machine user name as a plain string — it is type-narrowed to the names you defined in your auth config:
|
|
356
356
|
|
|
357
357
|
```typescript
|
|
358
358
|
import { createResolver, t } from "@tailor-platform/sdk";
|
|
@@ -365,10 +365,10 @@ export default createResolver({
|
|
|
365
365
|
// Executes as "batch-processor" machine user
|
|
366
366
|
return { result: "ok" };
|
|
367
367
|
},
|
|
368
|
-
|
|
368
|
+
invoker: "batch-processor",
|
|
369
369
|
});
|
|
370
370
|
```
|
|
371
371
|
|
|
372
372
|
The machine user name is looked up in the auth service configured on your app (`machineUsers` in `defineAuth`). The namespace is resolved automatically — no need to import `auth` from `tailor.config.ts` in resolver files.
|
|
373
373
|
|
|
374
|
-
**Note:** `
|
|
374
|
+
**Note:** The `invoker` option controls the permissions for database operations and other platform actions. The `caller` object passed to `body` still reflects the original caller, while the `invoker` body field reflects the principal actually running the body.
|