@tailor-platform/sdk 2.0.0-next.0 → 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.
Files changed (208) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/dist/application-Dtqap5jM.mjs +3 -0
  3. package/dist/{client-CobIRHl-.mjs → application-XuMWK4eq.mjs} +5869 -25
  4. package/dist/application-XuMWK4eq.mjs.map +1 -0
  5. package/dist/{assert-CKfwrmCV.mjs → assert-DBxo8jPo.mjs} +1 -2
  6. package/dist/{assert-CKfwrmCV.mjs.map → assert-DBxo8jPo.mjs.map} +1 -1
  7. package/dist/{authconnection-D8SJGMpj.mjs → authconnection-D2MhtTN5.mjs} +2 -3
  8. package/dist/{authconnection-D8SJGMpj.mjs.map → authconnection-D2MhtTN5.mjs.map} +1 -1
  9. package/dist/{authconnection-BIYzEh2p.d.mts → authconnection-DvUQAjQS.d.mts} +1 -1
  10. package/dist/{brand-DlnJ375c.mjs → brand-Eo4pLXPJ.mjs} +1 -2
  11. package/dist/{brand-DlnJ375c.mjs.map → brand-Eo4pLXPJ.mjs.map} +1 -1
  12. package/dist/cli/index.mjs +241 -237
  13. package/dist/cli/index.mjs.map +1 -1
  14. package/dist/cli/lib.d.mts +547 -620
  15. package/dist/cli/lib.mjs +9 -11
  16. package/dist/cli/lib.mjs.map +1 -1
  17. package/dist/completion/zsh-worker.zsh +4108 -0
  18. package/dist/configure/index.d.mts +9 -7
  19. package/dist/configure/index.mjs +76 -40
  20. package/dist/configure/index.mjs.map +1 -1
  21. package/dist/{context-s0lxhu8_.mjs → context-Bd266-ru.mjs} +2 -3
  22. package/dist/context-Bd266-ru.mjs.map +1 -0
  23. package/dist/{context-CUBwSBq4.d.mts → context-C2lEi9uw.d.mts} +7 -28
  24. package/dist/{crashreport-D1wKBJ8N.mjs → crashreport-BMWcxeSE.mjs} +1 -2
  25. package/dist/{crashreport-BhD0y14F.mjs → crashreport-DFq-vsU0.mjs} +21 -14
  26. package/dist/{crashreport-BhD0y14F.mjs.map → crashreport-DFq-vsU0.mjs.map} +1 -1
  27. package/dist/{enum-constants-C7DaWeQo.mjs → enum-constants-j9QBF0cB.mjs} +1 -2
  28. package/dist/enum-constants-j9QBF0cB.mjs.map +1 -0
  29. package/dist/{errors-EsY4XO6O.mjs → errors-Dtf2WPaW.mjs} +1 -2
  30. package/dist/{errors-EsY4XO6O.mjs.map → errors-Dtf2WPaW.mjs.map} +1 -1
  31. package/dist/{field-C4zdJLW5.mjs → field-DOsJCPFa.mjs} +1 -2
  32. package/dist/field-DOsJCPFa.mjs.map +1 -0
  33. package/dist/{file-B58Dm-2P.mjs → file-BbdFGdMV.mjs} +3 -12
  34. package/dist/file-BbdFGdMV.mjs.map +1 -0
  35. package/dist/{file-BzK8z3X-.d.mts → file-Dq3NIt_F.d.mts} +3 -42
  36. package/dist/{file-utils-BHPxPXmn.mjs → file-utils-CYZnO1pX.mjs} +6 -7
  37. package/dist/file-utils-CYZnO1pX.mjs.map +1 -0
  38. package/dist/{globals-ByrCoDip.mjs → globals-Cf0sxIt8.mjs} +53 -5
  39. package/dist/globals-Cf0sxIt8.mjs.map +1 -0
  40. package/dist/http-adapter.generated-DFsXDdm5.d.mts +581 -0
  41. package/dist/{iconv-kwrmd1U_.d.mts → iconv-Co-TOPuH.d.mts} +1 -1
  42. package/dist/{iconv-DreIffeM.mjs → iconv-D2vi8G36.mjs} +2 -3
  43. package/dist/{iconv-DreIffeM.mjs.map → iconv-D2vi8G36.mjs.map} +1 -1
  44. package/dist/{idp-Ch95ag8h.mjs → idp-BDbK5gjm.mjs} +2 -3
  45. package/dist/{idp-Ch95ag8h.mjs.map → idp-BDbK5gjm.mjs.map} +1 -1
  46. package/dist/{idp-BlBPtXJ-.d.mts → idp-DrhVrLmV.d.mts} +1 -1
  47. package/dist/{index-CLxubakC.d.mts → index-BI-_j9Z3.d.mts} +49 -261
  48. package/dist/{index-CPRnOjjt.d.mts → index-C4JirJH8.d.mts} +2 -2
  49. package/dist/{index-CQZVJ5SX.d.mts → index-CZfWhr0a.d.mts} +2 -2
  50. package/dist/{index-DRhMpdnA.d.mts → index-Cg8VKAdN.d.mts} +8 -8
  51. package/dist/{index-CfRFkXIO.d.mts → index-DYRjoLXD.d.mts} +2 -2
  52. package/dist/index-lFpcjHPU.d.mts +201 -0
  53. package/dist/{index-DUupuPhZ.d.mts → index-nW7hE6oE.d.mts} +2 -2
  54. package/dist/{interceptor-DOqRkCya.mjs → interceptor-D-q1rvRl.mjs} +1 -2
  55. package/dist/{interceptor-DOqRkCya.mjs.map → interceptor-D-q1rvRl.mjs.map} +1 -1
  56. package/dist/kysely/index.mjs +0 -1
  57. package/dist/kysely/index.mjs.map +1 -1
  58. package/dist/{kysely-type-D1e0Vwkd.mjs → kysely-type-DR8uzZTA.mjs} +2 -3
  59. package/dist/kysely-type-DR8uzZTA.mjs.map +1 -0
  60. package/dist/{logger-DpJyJvNz.mjs → logger-CxF-Ex5d.mjs} +1 -2
  61. package/dist/{logger-DpJyJvNz.mjs.map → logger-CxF-Ex5d.mjs.map} +1 -1
  62. package/dist/{mock-DMgIygjE.mjs → mock-FPxmnt-y.mjs} +9 -56
  63. package/dist/mock-FPxmnt-y.mjs.map +1 -0
  64. package/dist/{multiline-Cf9ODpr1.mjs → multiline-sfHpTZZK.mjs} +1 -2
  65. package/dist/{multiline-Cf9ODpr1.mjs.map → multiline-sfHpTZZK.mjs.map} +1 -1
  66. package/dist/{package-json-DcQApfPQ.mjs → package-json-8b0O9TlX.mjs} +1 -2
  67. package/dist/{package-json-DcQApfPQ.mjs.map → package-json-8b0O9TlX.mjs.map} +1 -1
  68. package/dist/package-json-Cv2Z-TqQ.mjs +3 -0
  69. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  70. package/dist/plugin/builtin/enum-constants/index.mjs +1 -2
  71. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  72. package/dist/plugin/builtin/file-utils/index.mjs +1 -2
  73. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  74. package/dist/plugin/builtin/kysely-type/index.mjs +1 -2
  75. package/dist/plugin/builtin/seed/index.d.mts +1 -1
  76. package/dist/plugin/builtin/seed/index.mjs +1 -2
  77. package/dist/plugin/index.d.mts +4 -5
  78. package/dist/plugin/index.mjs +0 -1
  79. package/dist/plugin/index.mjs.map +1 -1
  80. package/dist/registry-DH4m7eYo.mjs +53 -0
  81. package/dist/registry-DH4m7eYo.mjs.map +1 -0
  82. package/dist/{repl-editor-CJG3sz7A.mjs → repl-editor-DmGr9zMw.mjs} +2 -3
  83. package/dist/{repl-editor-CJG3sz7A.mjs.map → repl-editor-DmGr9zMw.mjs.map} +1 -1
  84. package/dist/{chunk-BkoGK1jX.mjs → rolldown-runtime-DXywRVcq.mjs} +0 -1
  85. package/dist/runtime/authconnection.d.mts +1 -1
  86. package/dist/runtime/authconnection.mjs +1 -2
  87. package/dist/runtime/context.d.mts +1 -1
  88. package/dist/runtime/context.mjs +1 -2
  89. package/dist/runtime/file.d.mts +2 -2
  90. package/dist/runtime/file.mjs +2 -3
  91. package/dist/runtime/globals.d.mts +8 -41
  92. package/dist/runtime/globals.mjs +0 -1
  93. package/dist/runtime/iconv.d.mts +1 -1
  94. package/dist/runtime/iconv.mjs +1 -2
  95. package/dist/runtime/idp.d.mts +1 -1
  96. package/dist/runtime/idp.mjs +1 -2
  97. package/dist/runtime/index.d.mts +8 -8
  98. package/dist/runtime/index.mjs +7 -8
  99. package/dist/runtime/secretmanager.d.mts +1 -1
  100. package/dist/runtime/secretmanager.mjs +1 -2
  101. package/dist/runtime/workflow.d.mts +2 -2
  102. package/dist/runtime/workflow.mjs +1 -2
  103. package/dist/{runtime-C7qTBDD2.mjs → runtime-CY4JvrDj.mjs} +1069 -542
  104. package/dist/runtime-CY4JvrDj.mjs.map +1 -0
  105. package/dist/{schema-1msIhXwA.mjs → schema-Dtw9Orye.mjs} +18 -16
  106. package/dist/schema-Dtw9Orye.mjs.map +1 -0
  107. package/dist/{secret-file-CWzF8rry.mjs → secret-file-VSVGy1V0.mjs} +27 -3
  108. package/dist/{secret-file-CWzF8rry.mjs.map → secret-file-VSVGy1V0.mjs.map} +1 -1
  109. package/dist/{secretmanager-CKLB3wAQ.d.mts → secretmanager-B3n4KHfm.d.mts} +1 -1
  110. package/dist/{secretmanager-B9h-U_8U.mjs → secretmanager-BVxw3ih_.mjs} +2 -3
  111. package/dist/{secretmanager-B9h-U_8U.mjs.map → secretmanager-BVxw3ih_.mjs.map} +1 -1
  112. package/dist/seed/index.mjs +0 -1
  113. package/dist/seed/index.mjs.map +1 -1
  114. package/dist/{seed-BH2FbrPV.mjs → seed-izIEyP3z.mjs} +7 -19
  115. package/dist/seed-izIEyP3z.mjs.map +1 -0
  116. package/dist/service-DCqIWibD.mjs +3 -0
  117. package/dist/{service-DMohAx8a2.mjs → service-DU1mVzri2.mjs} +3 -4
  118. package/dist/{service-DMohAx8a2.mjs.map → service-DU1mVzri2.mjs.map} +1 -1
  119. package/dist/{service-wI3Hvrgx.mjs → service-DjyqbCaJ.mjs} +9 -10
  120. package/dist/service-DjyqbCaJ.mjs.map +1 -0
  121. package/dist/{telemetry-BQbbVo2t.mjs → telemetry-CdqJEzkj.mjs} +2 -3
  122. package/dist/{telemetry-BQbbVo2t.mjs.map → telemetry-CdqJEzkj.mjs.map} +1 -1
  123. package/dist/telemetry-ClwW5ohF.mjs +3 -0
  124. package/dist/test-env-key-D7UkZp99.mjs +75 -0
  125. package/dist/test-env-key-D7UkZp99.mjs.map +1 -0
  126. package/dist/type-source-DH_LH20p.mjs +13 -0
  127. package/dist/type-source-DH_LH20p.mjs.map +1 -0
  128. package/dist/types-74etvaxy.mjs +4 -0
  129. package/dist/{plugin-C_FyVSdl.d.mts → types-BDRml5C3.d.mts} +128 -188
  130. package/dist/{types-CmzfQP_m.mjs → types-BQijbo4m.mjs} +10 -11
  131. package/dist/types-BQijbo4m.mjs.map +1 -0
  132. package/dist/types-BX4q6Mo6.d.mts +339 -0
  133. package/dist/types-BZ7QKVE8.d.mts +21 -0
  134. package/dist/{tailordb-BlBGmQK-.d.mts → types-CdcQh4Z2.d.mts} +92 -242
  135. package/dist/utils/test/index.d.mts +6 -14
  136. package/dist/utils/test/index.mjs +4 -14
  137. package/dist/utils/test/index.mjs.map +1 -1
  138. package/dist/vitest/environment.mjs +1 -2
  139. package/dist/vitest/environment.mjs.map +1 -1
  140. package/dist/vitest/index.d.mts +42 -5
  141. package/dist/vitest/index.mjs +133 -4
  142. package/dist/vitest/index.mjs.map +1 -1
  143. package/dist/vitest/setup.mjs +2 -3
  144. package/dist/vitest/setup.mjs.map +1 -1
  145. package/dist/{workflow--aPbA8Uq.mjs → workflow-BOmaZwwG.mjs} +9 -5
  146. package/dist/workflow-BOmaZwwG.mjs.map +1 -0
  147. package/dist/{workflow-CMamswkK.d.mts → workflow-BVy4XWjS.d.mts} +15 -10
  148. package/dist/workflow.generated-ClEjBYhm.d.mts +671 -0
  149. package/docs/cli/application.md +0 -2
  150. package/docs/cli/completion.md +3 -0
  151. package/docs/cli/crashreport.md +0 -2
  152. package/docs/cli/executor.md +53 -0
  153. package/docs/cli/function.md +1 -1
  154. package/docs/cli/setup.md +35 -33
  155. package/docs/cli/user.md +3 -3
  156. package/docs/cli/workflow.md +157 -20
  157. package/docs/cli/workspace.md +3 -3
  158. package/docs/cli-reference.md +26 -20
  159. package/docs/configuration.md +0 -2
  160. package/docs/github-actions.md +29 -16
  161. package/docs/migration/v2.md +475 -0
  162. package/docs/plugin/custom.md +2 -2
  163. package/docs/plugin/index.md +1 -1
  164. package/docs/runtime.md +4 -4
  165. package/docs/services/aigateway.md +97 -0
  166. package/docs/services/auth.md +31 -14
  167. package/docs/services/executor.md +3 -5
  168. package/docs/services/resolver.md +8 -10
  169. package/docs/services/tailordb.md +15 -13
  170. package/docs/services/workflow.md +17 -19
  171. package/docs/testing.md +75 -56
  172. package/package.json +18 -17
  173. package/dist/actor-J2gJ0eK5.d.mts +0 -24
  174. package/dist/application-76hhIhnJ.mjs +0 -5594
  175. package/dist/application-76hhIhnJ.mjs.map +0 -1
  176. package/dist/application-av2raLs6.mjs +0 -4
  177. package/dist/cli/skills.d.mts +0 -1
  178. package/dist/cli/skills.mjs +0 -22
  179. package/dist/cli/skills.mjs.map +0 -1
  180. package/dist/client-C68VWo4g.mjs +0 -4
  181. package/dist/client-CobIRHl-.mjs.map +0 -1
  182. package/dist/context-s0lxhu8_.mjs.map +0 -1
  183. package/dist/enum-constants-C7DaWeQo.mjs.map +0 -1
  184. package/dist/env-B-g-qgE4.d.mts +0 -7
  185. package/dist/field-C4zdJLW5.mjs.map +0 -1
  186. package/dist/file-B58Dm-2P.mjs.map +0 -1
  187. package/dist/file-utils-BHPxPXmn.mjs.map +0 -1
  188. package/dist/globals-ByrCoDip.mjs.map +0 -1
  189. package/dist/job-BpsFXPbi.mjs +0 -54
  190. package/dist/job-BpsFXPbi.mjs.map +0 -1
  191. package/dist/kysely-type-D1e0Vwkd.mjs.map +0 -1
  192. package/dist/mock-DMgIygjE.mjs.map +0 -1
  193. package/dist/package-json-wzO6nV9O.mjs +0 -4
  194. package/dist/registry-D0uB0OrK.mjs +0 -178
  195. package/dist/registry-D0uB0OrK.mjs.map +0 -1
  196. package/dist/runtime-C7qTBDD2.mjs.map +0 -1
  197. package/dist/schema-1msIhXwA.mjs.map +0 -1
  198. package/dist/seed-BH2FbrPV.mjs.map +0 -1
  199. package/dist/service-BHQIerYh.mjs +0 -4
  200. package/dist/service-wI3Hvrgx.mjs.map +0 -1
  201. package/dist/telemetry-w92bvGdC.mjs +0 -4
  202. package/dist/types-2Be3wSMc.mjs +0 -5
  203. package/dist/types-CmzfQP_m.mjs.map +0 -1
  204. package/dist/workflow--aPbA8Uq.mjs.map +0 -1
  205. package/dist/workflow.generated-Bf1tWylx.d.mts +0 -1416
  206. package/docs/generator/builtin.md +0 -257
  207. package/docs/generator/custom.md +0 -147
  208. package/docs/generator/index.md +0 -66
package/docs/testing.md CHANGED
@@ -11,18 +11,21 @@ Lean on unit tests for the day-to-day feedback loop — they run fast and exerci
11
11
 
12
12
  Unit-test entrypoints exposed by the SDK:
13
13
 
14
- - `resolver.body({ input, user, env })` — invoke a resolver
15
- - `workflowJob.body(input, { env })` / `workflowJob.trigger(input)` — invoke or chain a workflow job
16
- - `executor.operation.body(args)` — invoke a function-kind executor
14
+ - `resolver.body({ input, caller, invoker, env })` — invoke a resolver
15
+ - `workflowJob.body(input, { env, invoker })` — invoke a workflow job body directly
16
+ - `workflowJob.trigger(input)` — chain a workflow job through the workflow runtime
17
+ - `runWorkflowLocally(workflow, args)` — run a workflow chain locally with real job bodies
18
+ - `executor.operation.body({ ...args, invoker })` — invoke a function-kind executor
17
19
 
18
- Helpers under `@tailor-platform/sdk/test`:
20
+ For anonymous direct calls:
19
21
 
20
- - `unauthenticatedTailorUser` default `user` value for resolver contexts
22
+ - Pass `null` for anonymous `caller` / `invoker` context in direct unit tests.
21
23
 
22
24
  Platform API mocks under `@tailor-platform/sdk/vitest` (for use with the [`tailor-runtime` Vitest environment](#runtime-environment-emulation-beta) below):
23
25
 
24
26
  - `mockTailordb` — TailorDB query stubs and call recording
25
27
  - `mockWorkflow` — `tailor.workflow` job / wait / resolve mocks
28
+ - `runWorkflowLocally` — local full-chain workflow runner
26
29
  - `mockSecretmanager`, `mockAuthconnection`, `mockIdp`, `mockFile`, `mockIconv` — corresponding platform API mocks
27
30
 
28
31
  For tighter alignment with the production runtime — Node.js module blocking, Web-only globals, and platform API mocks — pair the resolver helpers with the [`tailor-runtime` Vitest environment](#runtime-environment-emulation-beta) below.
@@ -96,7 +99,12 @@ test("resolver queries the database", async () => {
96
99
  [], // COMMIT
97
100
  );
98
101
 
99
- const result = await resolver.body({ input: { email: "test@example.com" } });
102
+ const result = await resolver.body({
103
+ input: { email: "test@example.com" },
104
+ caller: null,
105
+ invoker: null,
106
+ env: {},
107
+ });
100
108
 
101
109
  expect(result).toEqual({ oldAge: 30, newAge: 31 });
102
110
  expect(db.executedQueries).toHaveLength(3);
@@ -118,7 +126,12 @@ test("content-based mock", async () => {
118
126
  return [];
119
127
  });
120
128
 
121
- const result = await resolver.body({ input: { userId: "1" } });
129
+ const result = await resolver.body({
130
+ input: { userId: "1" },
131
+ caller: null,
132
+ invoker: null,
133
+ env: {},
134
+ });
122
135
 
123
136
  expect(db.executedQueries[0].query).toContain("SELECT");
124
137
  });
@@ -126,7 +139,7 @@ test("content-based mock", async () => {
126
139
 
127
140
  ### Workflow Mock
128
141
 
129
- `.trigger()` runs the real job bodies locally out of the box (see [Running a full workflow locally](#running-a-full-workflow-locally)). Acquire `mockWorkflow()` when you want to override responses with `setJobHandler` / `enqueueResult` or assert on `triggeredJobs`:
142
+ Workflow job `.trigger()` calls use the platform workflow runtime. Acquire `mockWorkflow()` when you want to provide trigger responses with `setJobHandler` / `enqueueResult` or assert on `triggeredJobs`. If no response is configured, the mock throws so missing job mocks fail loudly:
130
143
 
131
144
  ```typescript
132
145
  import { mockWorkflow } from "@tailor-platform/sdk/vitest";
@@ -160,6 +173,8 @@ wf.enqueueResult({ valid: true });
160
173
  wf.enqueueResults({ valid: true }, { txnId: "txn-1" });
161
174
  ```
162
175
 
176
+ Use `wf.setEnv(...)` when locally-run workflow job bodies need configuration values. Per-run `runWorkflowLocally(..., { env })` options take precedence over the mock's env.
177
+
163
178
  ### SecretManager Mock
164
179
 
165
180
  ```typescript
@@ -262,28 +277,6 @@ test("mock file download stream", async () => {
262
277
  });
263
278
  ```
264
279
 
265
- For the deprecated `openDownloadStream`, enqueue an iterable of `StreamValue` items — `metadata`, one or more `chunk` items, and a terminal `complete`. Raw `Uint8Array` / `ArrayBuffer` chunks are rejected so tests stay aligned with the platform's structured stream contract.
266
-
267
- ```typescript
268
- test("mock file download stream (deprecated openDownloadStream)", async () => {
269
- using file = mockFile();
270
- file.enqueueResult([
271
- {
272
- type: "metadata",
273
- metadata: { contentType: "image/png", fileSize: 3, sha256sum: "abc" },
274
- },
275
- { type: "chunk", data: new Uint8Array([1, 2]), position: 0 },
276
- { type: "chunk", data: new Uint8Array([3]), position: 2 },
277
- { type: "complete" },
278
- ]);
279
-
280
- const stream = await tailordb.file.openDownloadStream("ns", "Doc", "attachment", "r-1");
281
- const items = [];
282
- for await (const item of stream) items.push(item);
283
- expect(items).toHaveLength(4);
284
- });
285
- ```
286
-
287
280
  ### Iconv Mock
288
281
 
289
282
  ```typescript
@@ -364,7 +357,6 @@ Unit tests call `.body()` (or `.trigger()`) directly on a resolver, workflow job
364
357
  For pure logic with no external dependencies, invoke `.body()` directly:
365
358
 
366
359
  ```typescript
367
- import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
368
360
  import { describe, expect, test } from "vitest";
369
361
  import resolver from "../src/resolver/add";
370
362
 
@@ -372,7 +364,8 @@ describe("add resolver", () => {
372
364
  test("adds two numbers", async () => {
373
365
  const result = await resolver.body({
374
366
  input: { left: 1, right: 2 },
375
- user: unauthenticatedTailorUser,
367
+ caller: null,
368
+ invoker: null,
376
369
  env: {},
377
370
  });
378
371
  expect(result).toBe(3);
@@ -389,7 +382,6 @@ Stub the global `tailordb.Client` and queue raw query results in order. Best for
389
382
  > If you are running with the [`tailor-runtime` Vitest environment](#runtime-environment-emulation-beta), acquire `using db = mockTailordb()` to install and drive the mock `tailordb.Client` instead of `vi.stubGlobal()`.
390
383
 
391
384
  ```typescript
392
- import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
393
385
  import { afterAll, afterEach, beforeAll, describe, expect, test, vi } from "vitest";
394
386
  import resolver from "../src/resolver/incrementUserAge";
395
387
 
@@ -419,7 +411,8 @@ describe("incrementUserAge resolver", () => {
419
411
 
420
412
  const result = await resolver.body({
421
413
  input: { email: "test@example.com" },
422
- user: unauthenticatedTailorUser,
414
+ caller: null,
415
+ invoker: null,
423
416
  env: {},
424
417
  });
425
418
 
@@ -490,7 +483,6 @@ describe("decrementUserAge", () => {
490
483
  Pass `mock.db` to functions that take a Kysely instance. When a resolver or executor calls `getDB()` internally there is no such seam, so spy the generated `getDB` and point it at the mock:
491
484
 
492
485
  ```typescript
493
- import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
494
486
  import { createKyselyMock } from "@tailor-platform/sdk/vitest";
495
487
  import { describe, expect, test, vi } from "vitest";
496
488
  import { getDB, type Namespace } from "../generated/db";
@@ -522,7 +514,8 @@ describe("upsertUsers resolver", () => {
522
514
  { name: "Existing", email: "exists@example.com", age: 41 },
523
515
  ],
524
516
  },
525
- user: unauthenticatedTailorUser,
517
+ caller: null,
518
+ invoker: null,
526
519
  env: { appName: "Resolver Template", version: 1 },
527
520
  });
528
521
 
@@ -541,7 +534,6 @@ Reach for [`mockTailordb`](#mocking-the-tailordb-client) instead when you want t
541
534
  Resolvers that call `waitPoint.resolve(...)` delegate to `tailor.workflow.resolve` at runtime. With the `tailor-runtime` environment active, use `mockWorkflow().setResolveHandler` to drive the user-supplied callback and inspect `resolveCalls`:
542
535
 
543
536
  ```typescript
544
- import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
545
537
  import { mockWorkflow } from "@tailor-platform/sdk/vitest";
546
538
  import { describe, expect, test } from "vitest";
547
539
  import resolver from "./resolveApproval";
@@ -556,7 +548,8 @@ describe("resolveApproval resolver", () => {
556
548
 
557
549
  const result = await resolver.body({
558
550
  input: { executionId: "exec-1", approved: true },
559
- user: unauthenticatedTailorUser,
551
+ caller: null,
552
+ invoker: null,
560
553
  env: {},
561
554
  });
562
555
 
@@ -570,7 +563,7 @@ describe("resolveApproval resolver", () => {
570
563
 
571
564
  ### Testing Executors
572
565
 
573
- Function-kind executors expose their handler as `executor.operation.body(args)`. The shape of `args` is determined by the trigger — for example, `recordCreatedTrigger({ type: user })` produces `{ newRecord }` typed against the type's output. GraphQL, webhook, and workflow operation kinds are declarative and don't expose a user-authored body to test.
566
+ Function-kind executors expose their handler as `executor.operation.body(args)`. The shape of `args` is determined by the trigger — for example, `recordCreatedTrigger({ type: user })` produces `{ newRecord }` typed against the type's output, plus runtime fields such as `env`, `actor`, and `invoker`. GraphQL, webhook, and workflow operation kinds are declarative and don't expose a user-authored body to test.
574
567
 
575
568
  The `executor` template extracts shared DB access into a helper (`shared.ts`) and tests the helper directly against a mocked `tailordb.Client` (same TailorDB-mocking pattern as the resolver section). Executor handlers themselves stay thin and can be tested by spying on the helper:
576
569
 
@@ -587,6 +580,14 @@ describe("onUserCreated executor", () => {
587
580
  throw new Error("expected function operation");
588
581
  }
589
582
  await onUserCreated.operation.body({
583
+ workspaceId: "workspace-1",
584
+ appNamespace: "app",
585
+ env: {},
586
+ actor: null,
587
+ invoker: null,
588
+ event: "created",
589
+ rawEvent: "tailordb.type_record.created",
590
+ typeName: "User",
590
591
  newRecord: {
591
592
  id: "user-1",
592
593
  name: "Alice",
@@ -615,7 +616,7 @@ Workflow jobs expose the same `.body()` entrypoint as resolvers, plus `.trigger(
615
616
 
616
617
  #### Simple job
617
618
 
618
- Call `.body()` with the input and a stub `{ env: {} }`:
619
+ Call `.body()` with the input and a stub `{ env: {}, invoker: null }`:
619
620
 
620
621
  ```typescript
621
622
  import { describe, expect, test } from "vitest";
@@ -623,14 +624,17 @@ import { validateOrder } from "./order-fulfillment";
623
624
 
624
625
  describe("validateOrder", () => {
625
626
  test("accepts a valid order", () => {
626
- const result = validateOrder.body({ orderId: "order-1", amount: 100 }, { env: {} });
627
+ const result = validateOrder.body(
628
+ { orderId: "order-1", amount: 100 },
629
+ { env: {}, invoker: null },
630
+ );
627
631
  expect(result).toEqual({ valid: true, orderId: "order-1" });
628
632
  });
629
633
 
630
634
  test("rejects a non-positive amount", () => {
631
- expect(() => validateOrder.body({ orderId: "order-1", amount: 0 }, { env: {} })).toThrow(
632
- "Order amount must be positive",
633
- );
635
+ expect(() =>
636
+ validateOrder.body({ orderId: "order-1", amount: 0 }, { env: {}, invoker: null }),
637
+ ).toThrow("Order amount must be positive");
634
638
  });
635
639
  });
636
640
  ```
@@ -645,22 +649,25 @@ import { fulfillOrder, processPayment, sendConfirmation, validateOrder } from ".
645
649
 
646
650
  describe("fulfillOrder", () => {
647
651
  test("chains validate → pay → confirm", async () => {
648
- using _validateSpy = vi.spyOn(validateOrder, "trigger").mockResolvedValue({
652
+ using _validateSpy = vi.spyOn(validateOrder, "trigger").mockReturnValue({
649
653
  valid: true,
650
654
  orderId: "order-1",
651
655
  });
652
- using _paymentSpy = vi.spyOn(processPayment, "trigger").mockResolvedValue({
656
+ using _paymentSpy = vi.spyOn(processPayment, "trigger").mockReturnValue({
653
657
  transactionId: "txn-order-1",
654
658
  amount: 100,
655
659
  status: "completed",
656
660
  });
657
- using _confirmSpy = vi.spyOn(sendConfirmation, "trigger").mockResolvedValue({
661
+ using _confirmSpy = vi.spyOn(sendConfirmation, "trigger").mockReturnValue({
658
662
  orderId: "order-1",
659
663
  transactionId: "txn-order-1",
660
664
  confirmed: true,
661
665
  });
662
666
 
663
- const result = await fulfillOrder.body({ orderId: "order-1", amount: 100 }, { env: {} });
667
+ const result = await fulfillOrder.body(
668
+ { orderId: "order-1", amount: 100 },
669
+ { env: {}, invoker: null },
670
+ );
664
671
 
665
672
  expect(validateOrder.trigger).toHaveBeenCalledWith({ orderId: "order-1", amount: 100 });
666
673
  expect(result).toMatchObject({ confirmed: true, paymentStatus: "completed" });
@@ -684,7 +691,10 @@ describe("processWithApproval", () => {
684
691
  using wf = mockWorkflow();
685
692
  wf.setWaitHandler({ approved: true });
686
693
 
687
- const result = await processWithApproval.body({ orderId: "order-1" }, { env: {} });
694
+ const result = await processWithApproval.body(
695
+ { orderId: "order-1" },
696
+ { env: {}, invoker: null },
697
+ );
688
698
 
689
699
  expect(result).toEqual({ orderId: "order-1", status: "approved" });
690
700
  expect(wf.waitCalls[0]).toEqual({
@@ -697,7 +707,10 @@ describe("processWithApproval", () => {
697
707
  using wf = mockWorkflow();
698
708
  wf.setWaitHandler({ approved: false });
699
709
 
700
- const result = await processWithApproval.body({ orderId: "order-2" }, { env: {} });
710
+ const result = await processWithApproval.body(
711
+ { orderId: "order-2" },
712
+ { env: {}, invoker: null },
713
+ );
701
714
 
702
715
  expect(result.status).toBe("rejected");
703
716
  });
@@ -708,22 +721,29 @@ describe("processWithApproval", () => {
708
721
 
709
722
  #### Running a full workflow locally
710
723
 
711
- To exercise the full chain with real job bodies, just call `workflow.mainJob.trigger()` — no `mockWorkflow()` needed. Dependent jobs run their real `.body()` functions, and trigger args/results cross the same JSON boundary as the platform, so a non-serializable payload fails the test exactly as it would in production:
724
+ To exercise the full chain with real job bodies, call `runWorkflowLocally(workflow, args)`. Dependent jobs run their real `.body()` functions, and trigger args/results cross the same JSON boundary as the platform, so a non-serializable payload fails the test exactly as it would in production:
712
725
 
713
726
  ```typescript
727
+ import { runWorkflowLocally } from "@tailor-platform/sdk/vitest";
714
728
  import { describe, expect, test } from "vitest";
715
729
  import workflow from "./order-fulfillment";
716
730
 
717
731
  describe("order-fulfillment workflow", () => {
718
- test("mainJob.trigger() executes all jobs", async () => {
719
- const result = await workflow.mainJob.trigger({ orderId: "order-3", amount: 300 });
732
+ test("runWorkflowLocally() executes all jobs", async () => {
733
+ const result = await runWorkflowLocally(workflow, { orderId: "order-3", amount: 300 });
720
734
 
721
735
  expect(result).toMatchObject({ confirmed: true, paymentStatus: "completed" });
722
736
  });
723
737
  });
724
738
  ```
725
739
 
726
- Acquire `mockWorkflow()` only when you need to override a dependent job with `wf.setJobHandler(...)` / `wf.enqueueResult(...)` (the rest still run their real bodies), control the env via `wf.setEnv(...)`, or assert on `wf.triggeredJobs`.
740
+ Pass `{ env }` as the third argument when job bodies need configuration values during the local run.
741
+
742
+ If you already acquired `mockWorkflow()`, you can also call `wf.setEnv(...)` to reuse the same env across local workflow runs.
743
+
744
+ Like the platform runtime, the local runner re-runs the orchestrator body once per `.trigger()` call (N triggers means N+1 passes), so any side effects outside the trigger results fire on every pass. Keep the body deterministic and move repeatable side effects into the triggered jobs.
745
+
746
+ This helper is still a local runner. Use E2E tests when you need to verify deployed workflow scheduling, suspension, or replay behavior.
727
747
 
728
748
  **Use when:** you want to verify orchestration end to end without the cost of a real deployment.
729
749
 
@@ -823,14 +843,13 @@ Use `startWorkflow` from the CLI helpers. It starts the workflow on the deployed
823
843
  import { randomUUID } from "node:crypto";
824
844
  import { startWorkflow } from "@tailor-platform/sdk/cli";
825
845
  import { describe, expect, test } from "vitest";
826
- import config from "../tailor.config";
827
846
  import userProfileSync from "../src/workflow/sync-profile";
828
847
 
829
848
  describe("user-profile-sync workflow", () => {
830
849
  test("executes end to end", { timeout: 180_000 }, async () => {
831
850
  const { executionId, wait } = await startWorkflow({
832
851
  workflow: userProfileSync,
833
- authInvoker: config.auth.invoker("admin"),
852
+ invoker: "admin",
834
853
  arg: {
835
854
  name: "workflow-test",
836
855
  email: `wf-${randomUUID()}@example.com`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailor-platform/sdk",
3
- "version": "2.0.0-next.0",
3
+ "version": "2.0.0-next.2",
4
4
  "description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -9,8 +9,7 @@
9
9
  "directory": "packages/sdk"
10
10
  },
11
11
  "bin": {
12
- "tailor-sdk": "./dist/cli/index.mjs",
13
- "tailor-sdk-skills": "./dist/cli/skills.mjs"
12
+ "tailor-sdk": "./dist/cli/index.mjs"
14
13
  },
15
14
  "files": [
16
15
  "CHANGELOG.md",
@@ -135,12 +134,12 @@
135
134
  }
136
135
  },
137
136
  "dependencies": {
138
- "@0no-co/graphql.web": "1.2.0",
137
+ "@0no-co/graphql.web": "1.3.2",
139
138
  "@badgateway/oauth2-client": "3.3.1",
140
139
  "@bufbuild/protobuf": "2.12.0",
141
140
  "@bufbuild/protovalidate": "1.2.0",
142
- "@connectrpc/connect": "2.1.1",
143
- "@connectrpc/connect-node": "2.1.1",
141
+ "@connectrpc/connect": "2.1.2",
142
+ "@connectrpc/connect-node": "2.1.2",
144
143
  "@inquirer/core": "11.2.1",
145
144
  "@inquirer/prompts": "8.5.2",
146
145
  "@jridgewell/trace-mapping": "0.3.31",
@@ -160,10 +159,10 @@
160
159
  "chokidar": "5.0.0",
161
160
  "confbox": "0.2.4",
162
161
  "date-fns": "4.4.0",
163
- "es-toolkit": "1.47.0",
162
+ "es-toolkit": "1.47.1",
164
163
  "find-up-simple": "1.0.1",
165
164
  "globals": "17.6.0",
166
- "graphql": "16.14.1",
165
+ "graphql": "16.14.2",
167
166
  "inflection": "3.0.2",
168
167
  "kysely": "0.29.2",
169
168
  "madge": "8.0.0",
@@ -174,16 +173,16 @@
174
173
  "pathe": "2.0.3",
175
174
  "pgsql-ast-parser": "12.0.2",
176
175
  "pkg-types": "2.3.1",
177
- "politty": "0.5.1",
178
- "rolldown": "1.1.0",
179
- "semver": "7.8.3",
176
+ "politty": "0.6.0",
177
+ "rolldown": "1.1.1",
178
+ "semver": "7.8.5",
180
179
  "sql-highlight": "6.1.0",
181
180
  "std-env": "4.1.0",
182
181
  "table": "6.9.0",
183
182
  "ts-cron-validator": "1.1.5",
184
183
  "tsx": "4.22.4",
185
184
  "type-fest": "5.7.0",
186
- "undici": "8.4.1",
185
+ "undici": "8.5.0",
187
186
  "xdg-basedir": "5.1.0",
188
187
  "zod": "4.4.3"
189
188
  },
@@ -191,16 +190,16 @@
191
190
  "@opentelemetry/sdk-trace-base": "2.8.0",
192
191
  "@types/madge": "5.0.3",
193
192
  "@types/mime-types": "3.0.1",
194
- "@types/node": "24.13.1",
193
+ "@types/node": "24.13.2",
195
194
  "@types/semver": "7.7.1",
196
- "@typescript/native-preview": "7.0.0-dev.20260612.1",
195
+ "@typescript/native-preview": "7.0.0-dev.20260614.1",
197
196
  "@vitest/coverage-v8": "4.1.8",
198
197
  "oxfmt": "0.54.0",
199
198
  "oxlint": "1.69.0",
200
199
  "oxlint-tsgolint": "0.23.0",
201
- "sonda": "0.11.1",
200
+ "sonda": "0.13.1",
202
201
  "tsdown": "0.22.2",
203
- "typescript": "5.9.3",
202
+ "typescript": "6.0.3",
204
203
  "vitest": "4.1.8",
205
204
  "zinfer": "0.1.8"
206
205
  },
@@ -227,9 +226,11 @@
227
226
  "test:coverage": "vitest --coverage",
228
227
  "docs:check": "vitest run --project=unit* src/cli/docs.test.ts",
229
228
  "docs:update": "POLITTY_DOCS_UPDATE=true vitest run --project=unit* src/cli/docs.test.ts",
230
- "build": "tsdown",
229
+ "build": "tsdown && politty generate-worker --bin dist/cli/index.mjs --program tailor-sdk --shell zsh --verify",
231
230
  "lint": "oxlint --type-aware .",
232
231
  "check:public-api-jsdoc": "tsx scripts/check-public-api-jsdoc.ts",
232
+ "check:zod-isolation": "tsx scripts/check-zod-isolation.ts",
233
+ "check:import-cycles": "tsx scripts/check-import-cycles.ts",
233
234
  "lint:fix": "oxlint --type-aware . --fix",
234
235
  "typecheck": "tsc --noEmit",
235
236
  "typecheck:go": "tsgo",
@@ -1,24 +0,0 @@
1
- import { A as InferredAttributeList, j as InferredAttributeMap } from "./tailordb-BlBGmQK-.mjs";
2
-
3
- //#region src/types/actor.d.ts
4
- /** User type enum values from the Tailor Platform server. */
5
- type TailorActorType = "USER_TYPE_USER" | "USER_TYPE_MACHINE_USER" | "USER_TYPE_UNSPECIFIED";
6
- /** Represents an actor in event triggers. */
7
- type TailorActor = {
8
- /** The ID of the workspace the user belongs to. */workspaceId: string; /** The ID of the user. */
9
- userId: string;
10
- /**
11
- * A map of the user's attributes.
12
- * Maps from server's `attributeMap` field.
13
- */
14
- attributes: InferredAttributeMap | null;
15
- /**
16
- * A list of the user's attributes.
17
- * Maps from server's `attributes` field.
18
- */
19
- attributeList: InferredAttributeList; /** The type of the user. */
20
- userType: TailorActorType;
21
- };
22
- //#endregion
23
- export { TailorActor as t };
24
- //# sourceMappingURL=actor-J2gJ0eK5.d.mts.map