@tailor-platform/sdk 2.4.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/bin/tailor.mjs +3 -2
  3. package/dist/aigateway-DsWDjzk4.mjs +2 -0
  4. package/dist/{aigateway-DR4Kwuik.mjs.map → aigateway-DsWDjzk4.mjs.map} +1 -1
  5. package/dist/application-CNeOcaLc.mjs +1 -0
  6. package/dist/application-CmXOqTaK.mjs +192 -0
  7. package/dist/application-CmXOqTaK.mjs.map +1 -0
  8. package/dist/assert-WeXvmG4j.mjs +2 -0
  9. package/dist/{assert-DBxo8jPo.mjs.map → assert-WeXvmG4j.mjs.map} +1 -1
  10. package/dist/authconnection-CynFBIv8.mjs +2 -0
  11. package/dist/{authconnection-CZvi9ANm.mjs.map → authconnection-CynFBIv8.mjs.map} +1 -1
  12. package/dist/brand-C8nMKhJC.mjs +2 -0
  13. package/dist/{brand-Eo4pLXPJ.mjs.map → brand-C8nMKhJC.mjs.map} +1 -1
  14. package/dist/cli/commands/api/index.d.mts +1 -1
  15. package/dist/cli/commands/deploy/deploy.d.mts +2 -2
  16. package/dist/cli/commands/deploy/deployment-target.d.mts +2 -0
  17. package/dist/cli/commands/deploy/event-subscriptions.d.mts +3 -0
  18. package/dist/cli/commands/deploy/tailordb/apply.d.mts +3 -0
  19. package/dist/cli/commands/deploy/tailordb/index.d.mts +3 -10
  20. package/dist/cli/commands/deploy/tailordb/migration-validation.d.mts +5 -0
  21. package/dist/cli/commands/deploy/tailordb/plan.d.mts +8 -0
  22. package/dist/cli/commands/executor/jobs.d.mts +1 -1
  23. package/dist/cli/commands/executor/trigger.d.mts +1 -1
  24. package/dist/cli/commands/generate/seed/bundler.d.mts +2 -2
  25. package/dist/cli/commands/show.d.mts +1 -1
  26. package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +11 -11
  27. package/dist/cli/commands/tailordb/migrate/generate.d.mts +4 -0
  28. package/dist/cli/commands/tailordb/migrate/rename-detection.d.mts +1 -1
  29. package/dist/cli/commands/tailordb/migrate/snapshot-comparison.d.mts +43 -0
  30. package/dist/cli/commands/tailordb/migrate/snapshot-files.d.mts +62 -0
  31. package/dist/cli/commands/tailordb/migrate/snapshot-local.d.mts +12 -0
  32. package/dist/cli/commands/tailordb/migrate/snapshot-migrations.d.mts +12 -0
  33. package/dist/cli/commands/tailordb/migrate/snapshot-remote.d.mts +1 -0
  34. package/dist/cli/commands/tailordb/migrate/snapshot-types.d.mts +3 -1
  35. package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +5 -117
  36. package/dist/cli/commands/workflow/start.d.mts +1 -1
  37. package/dist/cli/commands/workspace/list.d.mts +1 -1
  38. package/dist/cli/lib.d.mts +12 -4
  39. package/dist/cli/lib.mjs +1 -9
  40. package/dist/cli/lib.mjs.map +1 -1
  41. package/dist/cli/main.d.mts +2 -0
  42. package/dist/cli/main.mjs +1170 -7754
  43. package/dist/cli/main.mjs.map +1 -1
  44. package/dist/cli/shared/args.d.mts +65 -1
  45. package/dist/cli/shared/command.d.mts +11 -0
  46. package/dist/cli/shared/context.d.mts +1 -1
  47. package/dist/cli/shared/logger.d.mts +64 -0
  48. package/dist/cli/shared/script-executor.d.mts +1 -1
  49. package/dist/cli/shared/seed-chunker.d.mts +5 -5
  50. package/dist/completion/zsh-worker.zsh +82 -9
  51. package/dist/configure/config/index.d.mts +1 -1
  52. package/dist/configure/config/types.d.mts +2 -2
  53. package/dist/configure/index.d.mts +48 -12
  54. package/dist/configure/index.mjs +1 -1267
  55. package/dist/configure/index.mjs.map +1 -1
  56. package/dist/configure/services/auth/types.d.mts +1 -1
  57. package/dist/configure/services/idp/types.d.mts +1 -1
  58. package/dist/configure/services/tailordb/schema.d.mts +22 -8
  59. package/dist/configure/services/tailordb/types.d.mts +2 -2
  60. package/dist/configure/services/workflow/execution-policy.d.mts +3 -3
  61. package/dist/configure/services/workflow/job.d.mts +12 -2
  62. package/dist/configure/types/field.types.d.mts +1 -1
  63. package/dist/configure/types/permission-operand.types.d.mts +1 -1
  64. package/dist/context-D0QjfxzD.mjs +2 -0
  65. package/dist/{context-DYQVYWqZ.mjs.map → context-D0QjfxzD.mjs.map} +1 -1
  66. package/dist/crashreport-BN28xp5B.mjs +42 -0
  67. package/dist/{crashreport-Q0pDAlrj.mjs.map → crashreport-BN28xp5B.mjs.map} +1 -1
  68. package/dist/crashreport-By23O2k-.mjs +1 -0
  69. package/dist/errors-DLsQ_-ol.mjs +2 -0
  70. package/dist/errors-DLsQ_-ol.mjs.map +1 -0
  71. package/dist/es-builtins-n3wBv4Sv.mjs +2 -0
  72. package/dist/es-builtins-n3wBv4Sv.mjs.map +1 -0
  73. package/dist/file-COPYfju_.mjs +2 -0
  74. package/dist/file-COPYfju_.mjs.map +1 -0
  75. package/dist/globals-CMHSnj4w.mjs +2 -0
  76. package/dist/{globals-B2nlxBrz.mjs.map → globals-CMHSnj4w.mjs.map} +1 -1
  77. package/dist/iconv-DlFMt2gW.mjs +2 -0
  78. package/dist/{iconv-QWaZh0TT.mjs.map → iconv-DlFMt2gW.mjs.map} +1 -1
  79. package/dist/idp-G_ojPBB5.mjs +2 -0
  80. package/dist/{idp-RA_swu-h.mjs.map → idp-G_ojPBB5.mjs.map} +1 -1
  81. package/dist/interceptor-DQg3cR_9.mjs +2 -0
  82. package/dist/{interceptor-e33JtsC-.mjs.map → interceptor-DQg3cR_9.mjs.map} +1 -1
  83. package/dist/kysely/index.mjs +1 -32
  84. package/dist/kysely/index.mjs.map +1 -1
  85. package/dist/kysely-type-BTi3BMtL.mjs +43 -0
  86. package/dist/kysely-type-BTi3BMtL.mjs.map +1 -0
  87. package/dist/logger-CCjs1DuH.mjs +9 -0
  88. package/dist/logger-CCjs1DuH.mjs.map +1 -0
  89. package/dist/logger-DP2BjQ93.mjs +2 -0
  90. package/dist/{logger-BtX0suGY.mjs.map → logger-DP2BjQ93.mjs.map} +1 -1
  91. package/dist/multiline-EyzjEwn9.mjs +3 -0
  92. package/dist/{multiline-sfHpTZZK.mjs.map → multiline-EyzjEwn9.mjs.map} +1 -1
  93. package/dist/node-builtins-oBl7EbyV.mjs +2 -0
  94. package/dist/{node-builtins-CmaL2Cbq.mjs.map → node-builtins-oBl7EbyV.mjs.map} +1 -1
  95. package/dist/package-json-C690ceex.mjs +2 -0
  96. package/dist/{package-json-8b0O9TlX.mjs.map → package-json-C690ceex.mjs.map} +1 -1
  97. package/dist/package-json-CmqhDJ__.mjs +1 -0
  98. package/dist/parser/service/tailordb/type-source.d.mts +5 -5
  99. package/dist/parser/service/tailordb/types.d.mts +4 -4
  100. package/dist/platform-serialize-DkiTdHOt.mjs +2 -0
  101. package/dist/{platform-serialize-RoRtBS0v.mjs.map → platform-serialize-DkiTdHOt.mjs.map} +1 -1
  102. package/dist/plugin/builtin/enum-constants/index.mjs +5 -114
  103. package/dist/plugin/builtin/enum-constants/index.mjs.map +1 -1
  104. package/dist/plugin/builtin/file-utils/index.mjs +22 -104
  105. package/dist/plugin/builtin/file-utils/index.mjs.map +1 -1
  106. package/dist/plugin/builtin/kysely-type/index.d.mts +8 -1
  107. package/dist/plugin/builtin/kysely-type/index.mjs +1 -275
  108. package/dist/plugin/builtin/seed/index.d.mts +5 -0
  109. package/dist/plugin/builtin/seed/index.mjs +1 -3
  110. package/dist/plugin/builtin/seed/seed-type-processor.d.mts +0 -2
  111. package/dist/plugin/{get-generated-type.d.mts → get-generated-table.d.mts} +5 -5
  112. package/dist/plugin/index.d.mts +3 -2
  113. package/dist/plugin/index.mjs +1 -251
  114. package/dist/plugin/index.mjs.map +1 -1
  115. package/dist/plugin/types.d.mts +30 -23
  116. package/dist/plugin/with-context.d.mts +3 -3
  117. package/dist/register-ts-hook-oDA2JLp2.mjs +640 -0
  118. package/dist/register-ts-hook-oDA2JLp2.mjs.map +1 -0
  119. package/dist/registry-HlEaGvl5.mjs +2 -0
  120. package/dist/{registry-BIGVUrMB.mjs.map → registry-HlEaGvl5.mjs.map} +1 -1
  121. package/dist/repl-editor-BG1aDOfH.mjs +2 -0
  122. package/dist/{repl-editor-F9LotMNx.mjs.map → repl-editor-BG1aDOfH.mjs.map} +1 -1
  123. package/dist/runtime/aigateway.mjs +1 -3
  124. package/dist/runtime/authconnection.mjs +1 -3
  125. package/dist/runtime/context.mjs +1 -3
  126. package/dist/runtime/file.d.mts +21 -21
  127. package/dist/runtime/file.mjs +1 -3
  128. package/dist/runtime/globals.mjs +1 -1
  129. package/dist/runtime/iconv.mjs +1 -3
  130. package/dist/runtime/idp.mjs +1 -3
  131. package/dist/runtime/index.mjs +1 -11
  132. package/dist/runtime/logger.mjs +1 -3
  133. package/dist/runtime/secretmanager.mjs +1 -3
  134. package/dist/runtime/types.d.mts +1 -1
  135. package/dist/runtime/workflow.mjs +1 -3
  136. package/dist/schema-AYG4OhXY.mjs +2 -0
  137. package/dist/schema-AYG4OhXY.mjs.map +1 -0
  138. package/dist/secret-file-C9wp_FCX.mjs +2 -0
  139. package/dist/{secret-file-C3J4Gy8r.mjs.map → secret-file-C9wp_FCX.mjs.map} +1 -1
  140. package/dist/secretmanager-5olfnI1b.mjs +2 -0
  141. package/dist/{secretmanager-IY4UvinW.mjs.map → secretmanager-5olfnI1b.mjs.map} +1 -1
  142. package/dist/secretmanager-vHQoXdQz.mjs +2 -0
  143. package/dist/{secretmanager-CYlpffsz.mjs.map → secretmanager-vHQoXdQz.mjs.map} +1 -1
  144. package/dist/seed/index.mjs +8 -244
  145. package/dist/seed/index.mjs.map +1 -1
  146. package/dist/seed-DwqRFdqP.mjs +207 -0
  147. package/dist/seed-DwqRFdqP.mjs.map +1 -0
  148. package/dist/service-CLPMoj9n.mjs +2 -0
  149. package/dist/{service-LTfp03ZZ.mjs.map → service-CLPMoj9n.mjs.map} +1 -1
  150. package/dist/service-D7iXk0BT.mjs +1 -0
  151. package/dist/service-YqDsHmlK.mjs +7 -0
  152. package/dist/service-YqDsHmlK.mjs.map +1 -0
  153. package/dist/service_pb-DGKCLuAs.mjs +2 -0
  154. package/dist/{service_pb-BEWj1pOV.mjs.map → service_pb-DGKCLuAs.mjs.map} +1 -1
  155. package/dist/service_pb-_aeFE-Nv.mjs +1 -0
  156. package/dist/shared/src/color.d.mts +5 -0
  157. package/dist/tailor-proto/src/tailor/v1/workspace_pb.d.mts +1 -1
  158. package/dist/telemetry-Bklv9kQY.mjs +2 -0
  159. package/dist/{telemetry-BRVdwh14.mjs.map → telemetry-Bklv9kQY.mjs.map} +1 -1
  160. package/dist/telemetry-DXHP3VVi.mjs +1 -0
  161. package/dist/type-source--ZNcV8RJ.mjs +2 -0
  162. package/dist/type-source--ZNcV8RJ.mjs.map +1 -0
  163. package/dist/types/executor.generated.d.mts +1 -1
  164. package/dist/user-agent-vdHYF3QL.mjs +2 -0
  165. package/dist/{user-agent-Bgsszb5I.mjs.map → user-agent-vdHYF3QL.mjs.map} +1 -1
  166. package/dist/utils/test/index.mjs +1 -109
  167. package/dist/utils/test/index.mjs.map +1 -1
  168. package/dist/vitest/environment.mjs +1 -41
  169. package/dist/vitest/environment.mjs.map +1 -1
  170. package/dist/vitest/index.mjs +1 -1986
  171. package/dist/vitest/index.mjs.map +1 -1
  172. package/dist/vitest/mocks/file.d.mts +8 -8
  173. package/dist/vitest/setup.mjs +1 -140
  174. package/dist/vitest/setup.mjs.map +1 -1
  175. package/dist/wait-point-invoker-eiP-IIux.mjs +2 -0
  176. package/dist/wait-point-invoker-eiP-IIux.mjs.map +1 -0
  177. package/dist/wait-point-registry-B-ESkTZX.mjs +2 -0
  178. package/dist/wait-point-registry-B-ESkTZX.mjs.map +1 -0
  179. package/dist/workflow-Cs9ISw6j.mjs +2 -0
  180. package/dist/{workflow-Bamae_Yc.mjs.map → workflow-Cs9ISw6j.mjs.map} +1 -1
  181. package/dist/workspace_resource_pb--GeYQPXu.mjs +2 -0
  182. package/dist/{workspace_resource_pb-HNIL_Vfj.mjs.map → workspace_resource_pb--GeYQPXu.mjs.map} +1 -1
  183. package/docs/cli/function.md +66 -6
  184. package/docs/cli/setup.md +24 -14
  185. package/docs/cli/tailordb.md +2 -0
  186. package/docs/cli-reference.md +9 -8
  187. package/docs/github-actions.md +14 -12
  188. package/docs/migration/v2.md +18 -2
  189. package/docs/migration/v3.md +121 -0
  190. package/docs/plugin/custom.md +130 -85
  191. package/docs/plugin/index.md +3 -3
  192. package/docs/services/tailordb-migration.md +21 -7
  193. package/docs/services/tailordb.md +9 -7
  194. package/docs/services/workflow.md +10 -9
  195. package/package.json +14 -13
  196. package/postinstall.mjs +1 -1
  197. package/dist/aigateway-DR4Kwuik.mjs +0 -9
  198. package/dist/application-C8a0UJ-z.mjs +0 -6071
  199. package/dist/application-C8a0UJ-z.mjs.map +0 -1
  200. package/dist/application-D4zOiLLa.mjs +0 -3
  201. package/dist/assert-DBxo8jPo.mjs +0 -9
  202. package/dist/authconnection-CZvi9ANm.mjs +0 -9
  203. package/dist/brand-Eo4pLXPJ.mjs +0 -36
  204. package/dist/context-DYQVYWqZ.mjs +0 -23
  205. package/dist/crashreport-Cd4TqfZq.mjs +0 -3
  206. package/dist/crashreport-Q0pDAlrj.mjs +0 -427
  207. package/dist/errors-Bxut5_Sy.mjs +0 -89
  208. package/dist/errors-Bxut5_Sy.mjs.map +0 -1
  209. package/dist/file-BUcmVIH2.mjs +0 -58
  210. package/dist/file-BUcmVIH2.mjs.map +0 -1
  211. package/dist/globals-B2nlxBrz.mjs +0 -126
  212. package/dist/iconv-QWaZh0TT.mjs +0 -38
  213. package/dist/idp-RA_swu-h.mjs +0 -82
  214. package/dist/interceptor-e33JtsC-.mjs +0 -33
  215. package/dist/logger-BtX0suGY.mjs +0 -48
  216. package/dist/logger-D0bEznPv.mjs +0 -362
  217. package/dist/logger-D0bEznPv.mjs.map +0 -1
  218. package/dist/multiline-sfHpTZZK.mjs +0 -38
  219. package/dist/node-builtins-CmaL2Cbq.mjs +0 -36
  220. package/dist/package-json-8b0O9TlX.mjs +0 -17
  221. package/dist/package-json-Cv2Z-TqQ.mjs +0 -3
  222. package/dist/platform-serialize-RoRtBS0v.mjs +0 -46
  223. package/dist/plugin/builtin/kysely-type/index.mjs.map +0 -1
  224. package/dist/plugin/builtin/seed/types.d.mts +0 -2
  225. package/dist/register-ts-hook-Vqjza10T.mjs +0 -25679
  226. package/dist/register-ts-hook-Vqjza10T.mjs.map +0 -1
  227. package/dist/registry-BIGVUrMB.mjs +0 -54
  228. package/dist/repl-editor-F9LotMNx.mjs +0 -252
  229. package/dist/schema-D4TC4BC3.mjs +0 -640
  230. package/dist/schema-D4TC4BC3.mjs.map +0 -1
  231. package/dist/secret-file-C3J4Gy8r.mjs +0 -64
  232. package/dist/secretmanager-CYlpffsz.mjs +0 -13
  233. package/dist/secretmanager-IY4UvinW.mjs +0 -131
  234. package/dist/seed-Cibjmtry.mjs +0 -489
  235. package/dist/seed-Cibjmtry.mjs.map +0 -1
  236. package/dist/service-2grcAOCJ.mjs +0 -898
  237. package/dist/service-2grcAOCJ.mjs.map +0 -1
  238. package/dist/service-CaBPNDIZ.mjs +0 -3
  239. package/dist/service-LTfp03ZZ.mjs +0 -133
  240. package/dist/service_pb-BEWj1pOV.mjs +0 -167
  241. package/dist/service_pb-BjlhvK9E.mjs +0 -3
  242. package/dist/telemetry-BRVdwh14.mjs +0 -84
  243. package/dist/telemetry-CkbkeJxl.mjs +0 -3
  244. package/dist/type-source-DH_LH20p.mjs +0 -13
  245. package/dist/type-source-DH_LH20p.mjs.map +0 -1
  246. package/dist/user-agent-Bgsszb5I.mjs +0 -28
  247. package/dist/wait-point-invoker-__oE88_P.mjs +0 -148
  248. package/dist/wait-point-invoker-__oE88_P.mjs.map +0 -1
  249. package/dist/wait-point-registry-TL99zotw.mjs +0 -47
  250. package/dist/wait-point-registry-TL99zotw.mjs.map +0 -1
  251. package/dist/workflow-Bamae_Yc.mjs +0 -34
  252. package/dist/workspace_resource_pb-HNIL_Vfj.mjs +0 -860
@@ -1,1987 +1,2 @@
1
- import { i as getRegisteredJob, t as START_DEFAULT } from "../registry-BIGVUrMB.mjs";
2
- import { a as getWaitPointKey, c as readWorkflowTestEnv, i as getWaitPointInvoker, o as buildJobContext, s as clearWorkflowTestEnv, u as writeWorkflowTestEnv } from "../wait-point-invoker-__oE88_P.mjs";
3
- import { t as assertDefined } from "../assert-DBxo8jPo.mjs";
4
- import { n as isNodeBuiltinImport, t as getNodeBuiltinMessage } from "../node-builtins-CmaL2Cbq.mjs";
5
- import { t as platformSerialize } from "../platform-serialize-RoRtBS0v.mjs";
6
- import { i as withDispose, n as tailorRoot, r as tailordbRoot, t as mockSecretmanager } from "../secretmanager-IY4UvinW.mjs";
7
- import { isEqual } from "es-toolkit";
8
- import { fileURLToPath } from "node:url";
9
- import { ColumnNode, CompiledQuery, InsertQueryNode, Kysely, PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler, PrimitiveValueListNode, ReferenceNode, UpdateQueryNode, ValueListNode, ValueNode, ValuesNode } from "kysely";
10
- import { dirname, isAbsolute, matchesGlob, relative, resolve } from "node:path";
11
- import { vi } from "vitest";
12
-
13
- //#region src/vitest/blocked-modules.ts
14
- /**
15
- * Check if a module specifier is a blocked Node.js built-in.
16
- * @param specifier - Module specifier to check (e.g. "node:crypto", "fs")
17
- * @returns Whether the specifier is blocked
18
- */
19
- function isBlockedModule(specifier) {
20
- return isNodeBuiltinImport(specifier);
21
- }
22
- /**
23
- * Get the error message for a blocked module import.
24
- * @param specifier - Module specifier that was blocked
25
- * @returns Error message with optional suggestion for the Web Standard API alternative
26
- */
27
- function getBlockedMessage(specifier) {
28
- return getNodeBuiltinMessage(specifier);
29
- }
30
-
31
- //#endregion
32
- //#region src/vitest/plugin.ts
33
- const DEFAULT_TEST_INCLUDE = ["**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"];
34
- const IMPORT_LIKE_TYPES = /* @__PURE__ */ new Set([
35
- "ImportDeclaration",
36
- "ExportNamedDeclaration",
37
- "ExportAllDeclaration"
38
- ]);
39
- const UNSAFE_BINDING_NAMES = /* @__PURE__ */ new Set([
40
- "break",
41
- "case",
42
- "catch",
43
- "class",
44
- "const",
45
- "continue",
46
- "debugger",
47
- "default",
48
- "delete",
49
- "do",
50
- "else",
51
- "enum",
52
- "export",
53
- "extends",
54
- "false",
55
- "finally",
56
- "for",
57
- "function",
58
- "if",
59
- "import",
60
- "in",
61
- "instanceof",
62
- "new",
63
- "null",
64
- "return",
65
- "super",
66
- "switch",
67
- "this",
68
- "throw",
69
- "true",
70
- "try",
71
- "typeof",
72
- "var",
73
- "void",
74
- "while",
75
- "with",
76
- "yield",
77
- "let",
78
- "static",
79
- "implements",
80
- "interface",
81
- "package",
82
- "private",
83
- "protected",
84
- "public",
85
- "await",
86
- "arguments",
87
- "eval"
88
- ]);
89
- const ID_START = /^[A-Za-z_$]/;
90
- const ID_CONT = /^[A-Za-z0-9_$]*$/;
91
- function isSafeBindingName(name) {
92
- if (UNSAFE_BINDING_NAMES.has(name)) return false;
93
- if (name.length === 0) return false;
94
- const firstChar = name[0];
95
- if (firstChar === void 0) return false;
96
- return ID_START.test(firstChar) && ID_CONT.test(name.slice(1));
97
- }
98
- function buildBlockedReplacement(node, message) {
99
- const literal = JSON.stringify(message);
100
- const throwStmt = `throw new Error(${literal});`;
101
- const throwExpr = `(() => { throw new Error(${literal}); })()`;
102
- if (node.type === "ExportNamedDeclaration") {
103
- const specs = node.specifiers ?? [];
104
- const stubs = [];
105
- for (const spec of specs) {
106
- const exportedName = spec.exported?.name;
107
- if (typeof exportedName !== "string") continue;
108
- if (exportedName === "default") {
109
- stubs.push(`export default ${throwExpr};`);
110
- continue;
111
- }
112
- if (!isSafeBindingName(exportedName)) return throwStmt;
113
- stubs.push(`export const ${exportedName} = ${throwExpr};`);
114
- }
115
- return stubs.length > 0 ? stubs.join(" ") : throwStmt;
116
- }
117
- if (node.type === "ExportAllDeclaration") {
118
- const exportedName = node.exported?.name;
119
- if (typeof exportedName === "string" && isSafeBindingName(exportedName)) return `export const ${exportedName} = ${throwExpr};`;
120
- return throwStmt;
121
- }
122
- return throwStmt;
123
- }
124
- /**
125
- * Vite plugin that blocks Node.js built-in module imports from production code.
126
- *
127
- * Uses the `transform` hook to walk the Rollup-provided AST of non-test source
128
- * files for static `node:*` imports and re-exports.
129
- * `ImportDeclaration` and bare `export * from "..."` are replaced with a
130
- * `throw new Error(...)` statement so the failure surfaces at evaluation time.
131
- * `ExportNamedDeclaration` (`export { x, y as z } from "..."`) and namespaced
132
- * `export * as ns from "..."` are rewritten to per-binding stub exports
133
- * (`export const x = (() => { throw new Error(...) })();`). The IIFE throws
134
- * eagerly during module evaluation (same timing as a top-level `throw`), but
135
- * preserving the declared export bindings ensures the surfaced error is the
136
- * actual "node:* not available" message rather than an opaque
137
- * "missing export" raised by the loader.
138
- * Vitest treats `node:*` as external SSR modules (skipping `resolveId`), so
139
- * source-level transformation is the only reliable interception point.
140
- * Runs in the default phase (no `enforce: "pre"`) so esbuild's TypeScript
141
- * transform strips `import type` first; only runtime imports reach this hook.
142
- * Node.js globals not in the platform runtime are removed by the environment (whitelist-based).
143
- * Test file patterns are read from the resolved Vitest config (`test.include`).
144
- * Vitest setup files (`test.setupFiles`) and global-setup files
145
- * (`test.globalSetup`) are also exempted: they run in the test runner host,
146
- * not in the emulated platform runtime, so they may freely use `node:*`
147
- * modules (e.g. `node:url` for `pathToFileURL`).
148
- * @returns Vite plugin
149
- */
150
- function createBlockPlugin() {
151
- let isTestFile = () => false;
152
- let isUserSourceFile = () => false;
153
- return {
154
- name: "tailor-runtime-block-node",
155
- configResolved(config) {
156
- const testConfig = config.test;
157
- const root = testConfig?.root ?? config.root;
158
- const toAbsolutePaths = (value, baseRoot) => (Array.isArray(value) ? value : value ? [value] : []).map((f) => resolve(baseRoot, f));
159
- const exemptHostFiles = /* @__PURE__ */ new Set([...toAbsolutePaths(testConfig?.setupFiles, root), ...toAbsolutePaths(testConfig?.globalSetup, root)]);
160
- const includePairs = [{
161
- root,
162
- patterns: testConfig?.include ?? DEFAULT_TEST_INCLUDE
163
- }];
164
- for (const project of testConfig?.projects ?? []) {
165
- const projectTest = project.test;
166
- if (!projectTest) continue;
167
- const projectRoot = projectTest.root ?? root;
168
- for (const f of toAbsolutePaths(projectTest.setupFiles, projectRoot)) exemptHostFiles.add(f);
169
- for (const f of toAbsolutePaths(projectTest.globalSetup, projectRoot)) exemptHostFiles.add(f);
170
- includePairs.push({
171
- root: projectRoot,
172
- patterns: projectTest.include ?? DEFAULT_TEST_INCLUDE
173
- });
174
- }
175
- isTestFile = (id) => {
176
- if (exemptHostFiles.has(id)) return true;
177
- return includePairs.some(({ root: r, patterns }) => {
178
- const candidate = isAbsolute(id) ? relative(r, id) : id;
179
- return patterns.some((pattern) => matchesGlob(candidate, pattern));
180
- });
181
- };
182
- isUserSourceFile = (id) => {
183
- if (!isAbsolute(id)) return false;
184
- const rel = relative(root, id);
185
- return rel !== "" && !rel.startsWith("..") && !isAbsolute(rel);
186
- };
187
- },
188
- transform(code, id) {
189
- const queryIdx = id.search(/[?#]/);
190
- const cleanId = queryIdx === -1 ? id : id.slice(0, queryIdx);
191
- if (isTestFile(cleanId)) return void 0;
192
- if (cleanId.includes("node_modules")) return void 0;
193
- if (!isUserSourceFile(cleanId)) return void 0;
194
- let ast;
195
- try {
196
- ast = this.parse(code);
197
- } catch {
198
- return;
199
- }
200
- const replacements = [];
201
- for (const node of ast.body) {
202
- if (!IMPORT_LIKE_TYPES.has(node.type)) continue;
203
- const specifier = node.source?.value;
204
- if (typeof specifier !== "string") continue;
205
- if (isBlockedModule(specifier)) replacements.push({
206
- start: node.start,
207
- end: node.end,
208
- replacement: buildBlockedReplacement(node, getBlockedMessage(specifier))
209
- });
210
- }
211
- if (replacements.length === 0) return void 0;
212
- let transformed = code;
213
- for (const r of replacements.toSorted((a, b) => b.start - a.start)) transformed = transformed.slice(0, r.start) + r.replacement + transformed.slice(r.end);
214
- return {
215
- code: transformed,
216
- map: null
217
- };
218
- }
219
- };
220
- }
221
- const ENVIRONMENT_NAME = "tailor-runtime";
222
- /**
223
- * Vite plugin that resolves the tailor-runtime environment and injects setup files.
224
- *
225
- * Vitest resolves environments starting with "." or "/" as file paths.
226
- * This plugin rewrites `environment: "tailor-runtime"` to the absolute path
227
- * of the bundled environment module, both at the top-level and per-project.
228
- * It also injects the setup file that removes Vitest-dependent globals
229
- * (like `performance`) per-test via beforeEach/afterEach hooks.
230
- * @param options - Optional configuration
231
- * @param options.config - Path to tailor.config.ts to load SecretManager values into mock
232
- * @returns Vite plugin
233
- */
234
- function createEnvironmentPlugin(options) {
235
- const currentDir = dirname(fileURLToPath(import.meta.url));
236
- const environmentPath = resolve(currentDir, "environment.mjs");
237
- const setupPath = resolve(currentDir, "setup.mjs");
238
- return {
239
- name: "tailor-runtime-environment",
240
- config(config) {
241
- const testConfig = config.test;
242
- let usesTailorRuntime = false;
243
- if (testConfig?.environment === ENVIRONMENT_NAME) {
244
- testConfig.environment = environmentPath;
245
- usesTailorRuntime = true;
246
- }
247
- if (testConfig?.projects) for (const project of testConfig.projects) {
248
- const projectTest = project.test;
249
- if (projectTest?.environment === ENVIRONMENT_NAME) {
250
- projectTest.environment = environmentPath;
251
- usesTailorRuntime = true;
252
- }
253
- }
254
- delete process.env.__TAILOR_RUNTIME_CONFIG;
255
- if (options?.config && usesTailorRuntime) {
256
- const configRoot = config.root ?? process.cwd();
257
- const configAbsPath = resolve(configRoot, options.config);
258
- process.env.__TAILOR_RUNTIME_CONFIG = configAbsPath;
259
- }
260
- if (testConfig && typeof testConfig.setupFiles === "string") testConfig.setupFiles = [testConfig.setupFiles];
261
- return { test: { setupFiles: [setupPath] } };
262
- }
263
- };
264
- }
265
-
266
- //#endregion
267
- //#region src/vitest/mocks/aigateway.ts
268
- /**
269
- * Acquire a disposable mock for `tailor.aigateway`. Restored on dispose.
270
- * @param options - Initial AI Gateway URL fixtures
271
- * @returns Disposable AI Gateway mock control object
272
- * @example
273
- * ```typescript
274
- * import { mockAigateway } from "@tailor-platform/sdk/vitest";
275
- *
276
- * test("resolves an AI Gateway URL", async () => {
277
- * using aigateway = mockAigateway({
278
- * urls: { "my-aigateway": "https://my-aigateway.example.com" },
279
- * });
280
- * aigateway.setUrl("my-aigateway", "https://replacement.example.com");
281
- * // …
282
- * });
283
- * ```
284
- */
285
- function mockAigateway(options = {}) {
286
- const root = tailorRoot();
287
- const prev = root.aigateway;
288
- let urls = { ...options.urls };
289
- async function defaultGet(name) {
290
- const url = urls[name];
291
- if (url === void 0) throw new Error(`No AI Gateway registered for "${name}". Acquire mockAigateway() and call setUrls(...).`);
292
- return { url };
293
- }
294
- const get = vi.fn(defaultGet);
295
- root.aigateway = { get };
296
- return withDispose({
297
- /** The `get` `vi.fn`. */
298
- get,
299
- setUrls(value) {
300
- urls = value;
301
- },
302
- setUrl(name, url) {
303
- urls = {
304
- ...urls,
305
- [name]: url
306
- };
307
- },
308
- get calls() {
309
- return get.mock.calls.map(([name]) => ({ name }));
310
- },
311
- clear() {
312
- get.mockClear();
313
- },
314
- reset() {
315
- urls = {};
316
- get.mockReset();
317
- get.mockImplementation(defaultGet);
318
- }
319
- }, () => {
320
- root.aigateway = prev;
321
- });
322
- }
323
-
324
- //#endregion
325
- //#region src/vitest/mocks/authconnection.ts
326
- /**
327
- * Acquire a disposable mock for `tailor.authconnection`. Restored on dispose.
328
- * @param options - Initial token fixtures and fallback behavior
329
- * @returns Disposable AuthConnection mock control object
330
- * @example
331
- * ```typescript
332
- * import { mockAuthconnection } from "@tailor-platform/sdk/vitest";
333
- *
334
- * test("returns configured token", async () => {
335
- * using ac = mockAuthconnection({ tokens: { google: { access_token: "ya29.xxx" } } });
336
- * ac.setToken("google", { access_token: "replacement" });
337
- * // …
338
- * });
339
- * ```
340
- */
341
- function mockAuthconnection(options = {}) {
342
- const root = tailorRoot();
343
- const prev = root.authconnection;
344
- let tokens = { ...options.tokens };
345
- async function defaultGetConnectionToken(connectionName) {
346
- const token = tokens[connectionName];
347
- if (token) return token;
348
- if (options.onUnhandled === "error") throw new Error(`No AuthConnection token configured for "${connectionName}"`);
349
- return { access_token: "mock-token" };
350
- }
351
- const getConnectionToken = vi.fn(defaultGetConnectionToken);
352
- root.authconnection = { getConnectionToken };
353
- return withDispose({
354
- /** The `getConnectionToken` `vi.fn`. */
355
- getConnectionToken,
356
- setTokens(value) {
357
- tokens = value;
358
- },
359
- setToken(connectionName, token) {
360
- tokens = {
361
- ...tokens,
362
- [connectionName]: token
363
- };
364
- },
365
- get calls() {
366
- return getConnectionToken.mock.calls.map(([connectionName]) => ({ connectionName }));
367
- },
368
- clear() {
369
- getConnectionToken.mockClear();
370
- },
371
- reset() {
372
- tokens = {};
373
- getConnectionToken.mockReset();
374
- getConnectionToken.mockImplementation(defaultGetConnectionToken);
375
- }
376
- }, () => {
377
- root.authconnection = prev;
378
- });
379
- }
380
-
381
- //#endregion
382
- //#region src/vitest/mocks/file.ts
383
- const FILE_METHODS = [
384
- "upload",
385
- "download",
386
- "downloadAsBase64",
387
- "delete",
388
- "getMetadata",
389
- "downloadStream",
390
- "uploadStream"
391
- ];
392
- const FILE_DEFAULTS = {
393
- upload: { metadata: {
394
- fileSize: 0,
395
- sha256sum: ""
396
- } },
397
- download: {
398
- data: /* @__PURE__ */ new Uint8Array(),
399
- metadata: {
400
- contentType: "",
401
- fileSize: 0,
402
- sha256sum: "",
403
- lastUploadedAt: ""
404
- }
405
- },
406
- downloadAsBase64: {
407
- data: "",
408
- metadata: {
409
- contentType: "",
410
- fileSize: 0,
411
- sha256sum: "",
412
- lastUploadedAt: ""
413
- }
414
- },
415
- getMetadata: {
416
- contentType: "",
417
- fileSize: 0,
418
- sha256sum: "",
419
- urlPath: ""
420
- },
421
- downloadStream: null,
422
- uploadStream: { metadata: {
423
- fileSize: 0,
424
- sha256sum: ""
425
- } }
426
- };
427
- /**
428
- * Acquire a disposable mock for `tailordb.file`. Restored on dispose.
429
- * @param options - Controls behavior for calls without a configured result
430
- * @returns Disposable File mock control object
431
- * @example
432
- * ```typescript
433
- * import { mockFile } from "@tailor-platform/sdk/vitest";
434
- *
435
- * test("mock file download", async () => {
436
- * using file = mockFile();
437
- * file.download.mockResolvedValue({ data: new Uint8Array(), metadata: { ... } });
438
- * // …
439
- * });
440
- * ```
441
- */
442
- function mockFile(options = {}) {
443
- const root = tailordbRoot();
444
- const prev = root.file;
445
- const { onUnhandled = "fallback" } = options;
446
- const queue = [];
447
- const calls = [];
448
- let resolver = () => null;
449
- function handle(method, namespace, typeName, fieldName, recordId) {
450
- if (queue.length > 0) return queue.shift();
451
- const resolved = resolver(method, {
452
- method,
453
- namespace,
454
- typeName,
455
- fieldName,
456
- recordId
457
- });
458
- if (resolved != null) return resolved;
459
- if (onUnhandled === "error") throw new Error(`No File mock configured for "${method}"`);
460
- const fallback = FILE_DEFAULTS[method];
461
- return fallback === void 0 ? void 0 : structuredClone(fallback);
462
- }
463
- const upload = vi.fn(async (...args) => {
464
- const [namespace, typeName, fieldName, recordId] = args;
465
- return handle("upload", namespace, typeName, fieldName, recordId);
466
- });
467
- const download = vi.fn(async (...args) => handle("download", ...args));
468
- const downloadAsBase64 = vi.fn(async (...args) => handle("downloadAsBase64", ...args));
469
- const deleteFile = vi.fn(async (...args) => {
470
- handle("delete", ...args);
471
- });
472
- const getMetadata = vi.fn(async (...args) => handle("getMetadata", ...args));
473
- const downloadStream = vi.fn(async (...args) => {
474
- const resolved = handle("downloadStream", ...args);
475
- if (resolved != null) return resolved;
476
- return {
477
- body: new ReadableStream({ start(controller) {
478
- controller.close();
479
- } }),
480
- metadata: {
481
- contentType: "",
482
- fileSize: 0,
483
- sha256sum: "",
484
- lastUploadedAt: ""
485
- }
486
- };
487
- });
488
- const uploadStream = vi.fn(async (...args) => {
489
- const [namespace, typeName, fieldName, recordId] = args;
490
- return handle("uploadStream", namespace, typeName, fieldName, recordId);
491
- });
492
- const mocks = {
493
- upload,
494
- download,
495
- downloadAsBase64,
496
- delete: deleteFile,
497
- getMetadata,
498
- downloadStream,
499
- uploadStream
500
- };
501
- function track(method, operation) {
502
- return function(...args) {
503
- calls.push({
504
- method,
505
- namespace: args[0],
506
- typeName: args[1],
507
- fieldName: args[2],
508
- recordId: args[3]
509
- });
510
- return operation.apply(this, args);
511
- };
512
- }
513
- root.file = {
514
- upload: track("upload", upload),
515
- download: track("download", download),
516
- downloadAsBase64: track("downloadAsBase64", downloadAsBase64),
517
- delete: track("delete", deleteFile),
518
- getMetadata: track("getMetadata", getMetadata),
519
- downloadStream: track("downloadStream", downloadStream),
520
- uploadStream: track("uploadStream", uploadStream)
521
- };
522
- function allMocks() {
523
- return FILE_METHODS.map((method) => mocks[method]);
524
- }
525
- const facade = {
526
- ...mocks,
527
- setResolver(value) {
528
- resolver = value;
529
- },
530
- /**
531
- * Enqueue a single result for the next `tailordb.file` call.
532
- * The queue is shared across all methods and namespaces.
533
- * @param result - Result to return from the next file call
534
- */
535
- enqueueResult(result) {
536
- queue.push(result);
537
- },
538
- /**
539
- * Enqueue results for multiple subsequent `tailordb.file` calls.
540
- * The queue is shared across all methods and namespaces.
541
- * @param results - Results to enqueue, one per upcoming call
542
- */
543
- enqueueResults(...results) {
544
- queue.push(...results);
545
- },
546
- get calls() {
547
- return calls;
548
- },
549
- clear() {
550
- calls.length = 0;
551
- for (const mock of allMocks()) mock.mockClear();
552
- },
553
- reset() {
554
- queue.length = 0;
555
- calls.length = 0;
556
- resolver = () => null;
557
- for (const mock of allMocks()) mock.mockReset();
558
- }
559
- };
560
- return withDispose(facade, () => {
561
- root.file = prev;
562
- });
563
- }
564
-
565
- //#endregion
566
- //#region src/vitest/mocks/iconv.ts
567
- function isUtf8(encoding) {
568
- return encoding === "UTF8" || encoding === "UTF-8";
569
- }
570
- function defaultIconvResult(method, args) {
571
- switch (method) {
572
- case "convert":
573
- case "convertBuffer": return isUtf8(args[2]) ? "" : /* @__PURE__ */ new Uint8Array();
574
- case "decode": return "";
575
- case "encode": return isUtf8(args[1]) ? "" : /* @__PURE__ */ new Uint8Array();
576
- case "encodings": return [];
577
- }
578
- }
579
- /**
580
- * Acquire a disposable mock for `tailor.iconv`. Restored on dispose.
581
- * @param options - Fallback behavior for unconfigured operations
582
- * @returns Disposable Iconv mock control object
583
- * @example
584
- * ```typescript
585
- * import { mockIconv } from "@tailor-platform/sdk/vitest";
586
- *
587
- * test("mock encoding conversion", () => {
588
- * using iconv = mockIconv();
589
- * iconv.decode.mockReturnValue("decoded-text");
590
- * // …
591
- * });
592
- * ```
593
- */
594
- function mockIconv(options = {}) {
595
- const root = tailorRoot();
596
- const prev = root.iconv;
597
- let resolver = null;
598
- const calls = [];
599
- function resolve(method, args) {
600
- if (resolver) {
601
- const result = resolver(method, args);
602
- if (result != null) return result;
603
- }
604
- if (options.onUnhandled === "error") throw new Error(`No Iconv mock behavior configured for "${method}"`);
605
- return defaultIconvResult(method, args);
606
- }
607
- function defaultConvert(input, fromEncoding, toEncoding) {
608
- return resolve("convert", [
609
- input,
610
- fromEncoding,
611
- toEncoding
612
- ]);
613
- }
614
- function defaultConvertBuffer(input, fromEncoding, toEncoding) {
615
- return resolve("convertBuffer", [
616
- input,
617
- fromEncoding,
618
- toEncoding
619
- ]);
620
- }
621
- function defaultDecode(input, encoding) {
622
- return resolve("decode", [input, encoding]);
623
- }
624
- function defaultEncode(input, encoding) {
625
- return resolve("encode", [input, encoding]);
626
- }
627
- function defaultEncodings() {
628
- return resolve("encodings", []);
629
- }
630
- const convert = vi.fn(defaultConvert);
631
- const convertBuffer = vi.fn(defaultConvertBuffer);
632
- const decode = vi.fn(defaultDecode);
633
- const encode = vi.fn(defaultEncode);
634
- const encodings = vi.fn(defaultEncodings);
635
- function track(method, operation) {
636
- return function(...args) {
637
- calls.push({
638
- method,
639
- args: [...args]
640
- });
641
- return operation.apply(this, args);
642
- };
643
- }
644
- const trackedConvert = track("convert", convert);
645
- const trackedConvertBuffer = track("convertBuffer", convertBuffer);
646
- const trackedDecode = track("decode", decode);
647
- const trackedEncode = track("encode", encode);
648
- const trackedEncodings = track("encodings", encodings);
649
- class MockIconv {
650
- #fromEncoding;
651
- #toEncoding;
652
- constructor(fromEncoding, toEncoding) {
653
- this.#fromEncoding = fromEncoding;
654
- this.#toEncoding = toEncoding;
655
- }
656
- convert(input) {
657
- return trackedConvert.call(this, input, this.#fromEncoding, this.#toEncoding);
658
- }
659
- }
660
- root.iconv = {
661
- convert: trackedConvert,
662
- convertBuffer: trackedConvertBuffer,
663
- decode: trackedDecode,
664
- encode: trackedEncode,
665
- encodings: trackedEncodings,
666
- Iconv: MockIconv
667
- };
668
- function clear() {
669
- calls.length = 0;
670
- convert.mockClear();
671
- convertBuffer.mockClear();
672
- decode.mockClear();
673
- encode.mockClear();
674
- encodings.mockClear();
675
- }
676
- return withDispose({
677
- /** The `convert` `vi.fn`. */
678
- convert,
679
- /** The `convertBuffer` `vi.fn`. */
680
- convertBuffer,
681
- /** The `decode` `vi.fn`. */
682
- decode,
683
- /** The `encode` `vi.fn`. */
684
- encode,
685
- /** The `encodings` `vi.fn`. */
686
- encodings,
687
- setResolver(value) {
688
- resolver = value;
689
- },
690
- get calls() {
691
- return calls;
692
- },
693
- clear,
694
- reset() {
695
- resolver = null;
696
- calls.length = 0;
697
- convert.mockReset();
698
- convert.mockImplementation(defaultConvert);
699
- convertBuffer.mockReset();
700
- convertBuffer.mockImplementation(defaultConvertBuffer);
701
- decode.mockReset();
702
- decode.mockImplementation(defaultDecode);
703
- encode.mockReset();
704
- encode.mockImplementation(defaultEncode);
705
- encodings.mockReset();
706
- encodings.mockImplementation(defaultEncodings);
707
- }
708
- }, () => {
709
- root.iconv = prev;
710
- });
711
- }
712
-
713
- //#endregion
714
- //#region src/vitest/mocks/idp.ts
715
- const IDP_METHODS = [
716
- "users",
717
- "user",
718
- "userByName",
719
- "createUser",
720
- "updateUser",
721
- "deleteUser",
722
- "sendPasswordResetEmail",
723
- "unenrollMfa"
724
- ];
725
- const IDP_USER_DEFAULT = {
726
- id: "mock-id",
727
- name: "mock-user",
728
- disabled: false,
729
- mfaEnrolled: false,
730
- mfaFactorIds: []
731
- };
732
- const IDP_DEFAULTS = {
733
- users: {
734
- users: [],
735
- nextPageToken: null,
736
- totalCount: 0
737
- },
738
- user: IDP_USER_DEFAULT,
739
- userByName: IDP_USER_DEFAULT,
740
- createUser: IDP_USER_DEFAULT,
741
- updateUser: IDP_USER_DEFAULT,
742
- deleteUser: true,
743
- sendPasswordResetEmail: true,
744
- unenrollMfa: true
745
- };
746
- /**
747
- * Acquire a disposable mock for `tailor.idp`. Restored on dispose.
748
- * @param options - Controls behavior for calls without a configured result
749
- * @returns Disposable IDP mock control object
750
- * @example
751
- * ```typescript
752
- * import { mockIdp } from "@tailor-platform/sdk/vitest";
753
- *
754
- * test("returns a user", async () => {
755
- * using idp = mockIdp();
756
- * idp.namespace("my-idp").user.mockResolvedValue({
757
- * id: "u-1",
758
- * name: "alice",
759
- * disabled: false,
760
- * mfaEnrolled: false,
761
- * mfaFactorIds: [],
762
- * });
763
- * // …
764
- * });
765
- * ```
766
- */
767
- function mockIdp(options = {}) {
768
- const root = tailorRoot();
769
- const prev = root.idp;
770
- const { onUnhandled = "fallback" } = options;
771
- const queue = [];
772
- const calls = [];
773
- let resolver = () => null;
774
- const namespaces = /* @__PURE__ */ new Map();
775
- function compatibilityArgs(method, args) {
776
- return method === "users" && args.length === 0 ? [void 0] : args;
777
- }
778
- function handle(method, args, namespace) {
779
- if (queue.length > 0) return queue.shift();
780
- const resolved = resolver(method, compatibilityArgs(method, args), namespace);
781
- if (resolved != null) return resolved;
782
- if (onUnhandled === "error") throw new Error(`No IdP mock configured for "${namespace}.${method}"`);
783
- return structuredClone(IDP_DEFAULTS[method]);
784
- }
785
- function createNamespaceMocks(namespace) {
786
- return {
787
- users: vi.fn(async (...args) => handle("users", args, namespace)),
788
- user: vi.fn(async (...args) => handle("user", args, namespace)),
789
- userByName: vi.fn(async (...args) => handle("userByName", args, namespace)),
790
- createUser: vi.fn(async (...args) => handle("createUser", args, namespace)),
791
- updateUser: vi.fn(async (...args) => handle("updateUser", args, namespace)),
792
- deleteUser: vi.fn(async (...args) => handle("deleteUser", args, namespace)),
793
- sendPasswordResetEmail: vi.fn(async (...args) => handle("sendPasswordResetEmail", args, namespace)),
794
- unenrollMfa: vi.fn(async (...args) => handle("unenrollMfa", args, namespace))
795
- };
796
- }
797
- function namespace(name) {
798
- const existing = namespaces.get(name);
799
- if (existing) return existing;
800
- const mocks = createNamespaceMocks(name);
801
- namespaces.set(name, mocks);
802
- return mocks;
803
- }
804
- function track(method, mock, namespaceName) {
805
- return function(...args) {
806
- calls.push({
807
- method,
808
- args: [...compatibilityArgs(method, args)],
809
- namespace: namespaceName
810
- });
811
- return mock.apply(this, args);
812
- };
813
- }
814
- const defaultClient = function(config) {
815
- const mocks = namespace(config.namespace);
816
- this.users = track("users", mocks.users, config.namespace);
817
- this.user = track("user", mocks.user, config.namespace);
818
- this.userByName = track("userByName", mocks.userByName, config.namespace);
819
- this.createUser = track("createUser", mocks.createUser, config.namespace);
820
- this.updateUser = track("updateUser", mocks.updateUser, config.namespace);
821
- this.deleteUser = track("deleteUser", mocks.deleteUser, config.namespace);
822
- this.sendPasswordResetEmail = track("sendPasswordResetEmail", mocks.sendPasswordResetEmail, config.namespace);
823
- this.unenrollMfa = track("unenrollMfa", mocks.unenrollMfa, config.namespace);
824
- };
825
- const Client = vi.fn(defaultClient);
826
- root.idp = { Client };
827
- function allMocks() {
828
- return [...namespaces.values()].flatMap((mocks) => IDP_METHODS.map((method) => mocks[method]));
829
- }
830
- return withDispose({
831
- /** The mock IDP `Client` constructor (`vi.fn`). */
832
- Client,
833
- namespace,
834
- setResolver(value) {
835
- resolver = value;
836
- },
837
- /**
838
- * Enqueue a single result for the next IDP call.
839
- * The queue is shared across all methods and namespaces.
840
- * @param result - Result to return from the next IDP call
841
- */
842
- enqueueResult(result) {
843
- queue.push(result);
844
- },
845
- /**
846
- * Enqueue results for multiple subsequent IDP calls.
847
- * The queue is shared across all methods and namespaces.
848
- * @param results - Results to enqueue, one per upcoming call
849
- */
850
- enqueueResults(...results) {
851
- queue.push(...results);
852
- },
853
- get calls() {
854
- return calls;
855
- },
856
- clear() {
857
- calls.length = 0;
858
- Client.mockClear();
859
- for (const mock of allMocks()) mock.mockClear();
860
- },
861
- reset() {
862
- queue.length = 0;
863
- calls.length = 0;
864
- resolver = () => null;
865
- Client.mockReset();
866
- Client.mockImplementation(defaultClient);
867
- for (const mock of allMocks()) mock.mockReset();
868
- }
869
- }, () => {
870
- root.idp = prev;
871
- });
872
- }
873
-
874
- //#endregion
875
- //#region src/vitest/mocks/logger.ts
876
- /**
877
- * Acquire a disposable mock for `tailor.logger`. Each method is a `vi.fn`, so
878
- * calls can be asserted directly; `calls` returns the `debug`/`info`/`warn`/
879
- * `error` entries in the order they were emitted. Restored on dispose.
880
- * @param _options - Reserved for future initial fixtures
881
- * @returns Disposable logger mock control object
882
- * @example
883
- * ```typescript
884
- * import { mockLogger } from "@tailor-platform/sdk/vitest";
885
- *
886
- * test("logs the processed order", () => {
887
- * using logger = mockLogger();
888
- * // …run code that calls tailor.logger.info…
889
- * expect(logger.info).toHaveBeenCalledWith("order processed", { orderId: "o-1" });
890
- * });
891
- * ```
892
- */
893
- function mockLogger(_options = {}) {
894
- const root = tailorRoot();
895
- const prev = root.logger;
896
- const debug = vi.fn((_message, _attributes) => {});
897
- const info = vi.fn((_message, _attributes) => {});
898
- const warn = vi.fn((_message, _attributes) => {});
899
- const error = vi.fn((_message, _attributes) => {});
900
- const setAttributes = vi.fn((_attributes) => {});
901
- root.logger = {
902
- debug,
903
- info,
904
- warn,
905
- error,
906
- setAttributes
907
- };
908
- const severityFns = {
909
- debug,
910
- info,
911
- warn,
912
- error
913
- };
914
- return withDispose({
915
- /** The `debug` `vi.fn`. */
916
- debug,
917
- /** The `info` `vi.fn`. */
918
- info,
919
- /** The `warn` `vi.fn`. */
920
- warn,
921
- /** The `error` `vi.fn`. */
922
- error,
923
- /** The `setAttributes` `vi.fn`. */
924
- setAttributes,
925
- get calls() {
926
- return Object.entries(severityFns).flatMap(([severity, fn]) => fn.mock.calls.map((args, i) => ({
927
- order: fn.mock.invocationCallOrder[i] ?? 0,
928
- call: {
929
- severity,
930
- message: args[0],
931
- attributes: args[1]
932
- }
933
- }))).toSorted((a, b) => a.order - b.order).map((e) => e.call);
934
- },
935
- clear() {
936
- debug.mockClear();
937
- info.mockClear();
938
- warn.mockClear();
939
- error.mockClear();
940
- setAttributes.mockClear();
941
- },
942
- reset() {
943
- debug.mockReset();
944
- info.mockReset();
945
- warn.mockReset();
946
- error.mockReset();
947
- setAttributes.mockReset();
948
- }
949
- }, () => {
950
- root.logger = prev;
951
- });
952
- }
953
-
954
- //#endregion
955
- //#region src/vitest/mocks/tailordb.ts
956
- function testRegex(regex, value) {
957
- const lastIndex = regex.lastIndex;
958
- regex.lastIndex = 0;
959
- try {
960
- return regex.test(value);
961
- } finally {
962
- regex.lastIndex = lastIndex;
963
- }
964
- }
965
- var MockQueryResult = class {
966
- command;
967
- rowCount;
968
- rows;
969
- constructor(rows) {
970
- this.command = "";
971
- this.rowCount = rows.length;
972
- this.rows = rows;
973
- }
974
- };
975
- /**
976
- * Acquire a disposable mock for TailorDB operations. Installs a mock
977
- * `tailordb.Client` whose `queryObject` is a shared `vi.fn()` (so query
978
- * responses can be staged before the client is constructed). Restored on
979
- * dispose.
980
- * @param options - Query fallback behavior
981
- * @returns Disposable TailorDB mock control object
982
- * @example
983
- * ```typescript
984
- * import { mockTailordb } from "@tailor-platform/sdk/vitest";
985
- *
986
- * test("query-based", async () => {
987
- * using db = mockTailordb();
988
- * db.onQuery({ sql: /FROM users/, params: ["u-1"] }).returnsRows([{ age: 30 }]);
989
- * // …
990
- * expect(db.queryObject).toHaveBeenCalled();
991
- * expect(db.Client).toHaveBeenCalledWith({ namespace: "tailordb" });
992
- * });
993
- * ```
994
- */
995
- function mockTailordb(options = {}) {
996
- const root = tailordbRoot();
997
- const prevClient = root.Client;
998
- const rules = [];
999
- let queryResolver;
1000
- function matchesQuery(matcher, query, params) {
1001
- if (typeof matcher === "function") return matcher(query, params);
1002
- if (typeof matcher === "string") return query === matcher;
1003
- if (matcher instanceof RegExp) return testRegex(matcher, query);
1004
- let sqlMatches;
1005
- if (typeof matcher.sql === "string") sqlMatches = query === matcher.sql;
1006
- else sqlMatches = testRegex(matcher.sql, query);
1007
- if (!sqlMatches || matcher.params === void 0) return sqlMatches;
1008
- if (typeof matcher.params === "function") return matcher.params(params);
1009
- const expectedParams = matcher.params;
1010
- return params.length === expectedParams.length && params.every((value, index) => isEqual(value, expectedParams[index]));
1011
- }
1012
- function queryResponse(response) {
1013
- if (response.type === "error") throw response.error;
1014
- return new MockQueryResult(response.rows);
1015
- }
1016
- async function defaultQuery(query, params = []) {
1017
- for (let i = rules.length - 1; i >= 0; i -= 1) {
1018
- const rule = rules[i];
1019
- if (!rule || !matchesQuery(rule.matcher, query, params)) continue;
1020
- const once = rule.once.shift();
1021
- if (once) return queryResponse(once);
1022
- if (rule.fallback) return queryResponse(rule.fallback);
1023
- }
1024
- if (queryResolver) return new MockQueryResult(queryResolver(query, params) ?? []);
1025
- if (options.onUnhandled === "error") throw new Error(`No TailorDB query behavior matched: ${query}`);
1026
- return new MockQueryResult([]);
1027
- }
1028
- const queryObject = vi.fn(defaultQuery);
1029
- const defaultConnect = async () => {};
1030
- const connect = vi.fn(defaultConnect);
1031
- const createdClients = [];
1032
- function enqueueRowsList(rowsList) {
1033
- for (const rows of rowsList) queryObject.mockImplementationOnce(async () => new MockQueryResult(rows));
1034
- }
1035
- const defaultClient = function(config) {
1036
- const record = {
1037
- namespace: config?.namespace,
1038
- ended: false
1039
- };
1040
- createdClients.push(record);
1041
- this.connect = connect;
1042
- this.end = vi.fn(async () => {
1043
- record.ended = true;
1044
- });
1045
- this.queryObject = queryObject;
1046
- this.createTransaction = (name) => {
1047
- if (!name) throw new Error("Transaction name must be a non-empty string");
1048
- return {
1049
- begin: async () => {},
1050
- commit: async () => {},
1051
- rollback: async () => {},
1052
- queryObject
1053
- };
1054
- };
1055
- };
1056
- const Client = vi.fn(defaultClient);
1057
- root.Client = Client;
1058
- return withDispose({
1059
- /** The mock `tailordb.Client` constructor (`vi.fn`). */
1060
- Client,
1061
- /** The shared `queryObject` `vi.fn` used by every client and transaction. */
1062
- queryObject,
1063
- /**
1064
- * Set a fallback query resolver. Called when the enqueue queue is empty.
1065
- * @param resolver - Function that returns rows for a given query and params
1066
- */
1067
- setQueryResolver(resolver) {
1068
- queryResolver = resolver;
1069
- queryObject.mockImplementation(defaultQuery);
1070
- },
1071
- /**
1072
- * Configure responses for queries matching SQL text, parameters, or a predicate.
1073
- * More recently registered matchers take precedence.
1074
- * Do not combine matchers with a direct `queryObject.mockImplementation()` override.
1075
- * @param matcher - Query matcher
1076
- * @returns Chainable query behavior
1077
- */
1078
- onQuery(matcher) {
1079
- const rule = {
1080
- matcher,
1081
- once: []
1082
- };
1083
- rules.push(rule);
1084
- const behavior = {
1085
- returnsRows(rows) {
1086
- rule.fallback = {
1087
- type: "rows",
1088
- rows
1089
- };
1090
- return behavior;
1091
- },
1092
- returnsRowsOnce(rows) {
1093
- rule.once.push({
1094
- type: "rows",
1095
- rows
1096
- });
1097
- return behavior;
1098
- },
1099
- rejects(error) {
1100
- rule.fallback = {
1101
- type: "error",
1102
- error
1103
- };
1104
- return behavior;
1105
- },
1106
- rejectsOnce(error) {
1107
- rule.once.push({
1108
- type: "error",
1109
- error
1110
- });
1111
- return behavior;
1112
- }
1113
- };
1114
- return behavior;
1115
- },
1116
- /**
1117
- * Enqueue rows for the next `queryObject` call (FIFO; takes priority over
1118
- * `setQueryResolver`). Call with no arguments for an empty result.
1119
- * @param rows - Row objects to return from the next `queryObject` call
1120
- */
1121
- enqueueResult(...rows) {
1122
- enqueueRowsList([rows]);
1123
- },
1124
- /**
1125
- * Enqueue rows for multiple subsequent `queryObject` calls (FIFO).
1126
- * @param rowsList - Rows arrays, one per upcoming query
1127
- */
1128
- enqueueResults(...rowsList) {
1129
- enqueueRowsList(rowsList);
1130
- },
1131
- /**
1132
- * Enqueue row arrays for subsequent queries whose exact order is under test.
1133
- * @param rowsList - Rows arrays, one per upcoming query
1134
- */
1135
- enqueueRows(...rowsList) {
1136
- enqueueRowsList(rowsList);
1137
- },
1138
- /**
1139
- * All queries executed via `queryObject`, in order, derived from the vi.fn
1140
- * call records.
1141
- * @returns Executed queries array
1142
- */
1143
- get executedQueries() {
1144
- return queryObject.mock.calls.map(([query, params]) => ({
1145
- query,
1146
- params: params ?? []
1147
- }));
1148
- },
1149
- /**
1150
- * All TailorDB clients created, with their namespace and end state.
1151
- * @returns Created clients array
1152
- */
1153
- get createdClients() {
1154
- return createdClients;
1155
- },
1156
- /** Clear recorded calls while preserving configured query behavior. */
1157
- clear() {
1158
- queryObject.mockClear();
1159
- connect.mockClear();
1160
- Client.mockClear();
1161
- createdClients.length = 0;
1162
- },
1163
- /** Reset query responses and recorded calls (keeps the mock installed). */
1164
- reset() {
1165
- queryObject.mockReset();
1166
- queryObject.mockImplementation(defaultQuery);
1167
- connect.mockReset();
1168
- connect.mockImplementation(defaultConnect);
1169
- Client.mockReset();
1170
- Client.mockImplementation(defaultClient);
1171
- createdClients.length = 0;
1172
- rules.length = 0;
1173
- queryResolver = void 0;
1174
- }
1175
- }, () => {
1176
- root.Client = prevClient;
1177
- });
1178
- }
1179
-
1180
- //#endregion
1181
- //#region src/vitest/mocks/workflow.ts
1182
- const baseInvokerWait = /* @__PURE__ */ new WeakMap();
1183
- const baseInvokerResolve = /* @__PURE__ */ new WeakMap();
1184
- const originalProcedures = /* @__PURE__ */ new WeakMap();
1185
- function replaceProcedure(target, key, current) {
1186
- const original = originalProcedures.get(current) ?? current;
1187
- const defaultImplementation = function(...args) {
1188
- return Reflect.apply(original, this, args);
1189
- };
1190
- const mock = vi.fn(defaultImplementation);
1191
- originalProcedures.set(mock, original);
1192
- const record = target;
1193
- record[key] = mock;
1194
- return {
1195
- mock,
1196
- scoped: {
1197
- mockClear: () => mock.mockClear(),
1198
- mockReset: () => mock.mockReset(),
1199
- restore: () => {
1200
- if (record[key] === mock) record[key] = current;
1201
- }
1202
- }
1203
- };
1204
- }
1205
- function replaceStart(definition) {
1206
- return replaceProcedure(definition, "start", definition.start);
1207
- }
1208
- /**
1209
- * Acquire a disposable mock for workflow operations (`tailor.workflow`).
1210
- * Restored on dispose.
1211
-
1212
- * @returns Disposable workflow mock control object
1213
- * @example
1214
- * ```typescript
1215
- * import { mockWorkflow } from "@tailor-platform/sdk/vitest";
1216
- *
1217
- * test("job start", async () => {
1218
- * using wf = mockWorkflow();
1219
- * const job = wf.job(validateOrder);
1220
- * job.mockResolvedValue({ valid: true });
1221
- * await runWorkflowUnderTest();
1222
- * expect(job).toHaveBeenCalled();
1223
- * });
1224
- * ```
1225
- */
1226
- function mockWorkflow() {
1227
- const root = tailorRoot();
1228
- const prev = root.workflow;
1229
- const prevEnv = readWorkflowTestEnv();
1230
- const jobSpies = /* @__PURE__ */ new Map();
1231
- const workflowSpies = /* @__PURE__ */ new Map();
1232
- const waitPointMocks = /* @__PURE__ */ new Map();
1233
- const keyDispatchers = /* @__PURE__ */ new Map();
1234
- const scopedMocks = /* @__PURE__ */ new Set();
1235
- const installKeyDispatcher = (definition) => {
1236
- const cached = keyDispatchers.get(definition);
1237
- if (cached) return cached;
1238
- const invoker = getWaitPointInvoker(definition);
1239
- if (!invoker) throw new Error("waitPointWith expects a wait point definition created by createWaitPoint or createWaitPoints.");
1240
- const record = invoker;
1241
- const prevWait = invoker.wait;
1242
- const prevResolve = invoker.resolve;
1243
- const baseWait = baseInvokerWait.get(prevWait) ?? prevWait;
1244
- const baseResolve = baseInvokerResolve.get(prevResolve) ?? prevResolve;
1245
- const slot = {
1246
- perKey: /* @__PURE__ */ new Map(),
1247
- originalWait: (key, payload) => baseWait.call(invoker, key, payload),
1248
- originalResolve: (key, executionId, callback) => baseResolve.call(invoker, key, executionId, callback)
1249
- };
1250
- const dispatchWait = (key, payload) => {
1251
- const mock = slot.perKey.get(key);
1252
- if (!mock) return slot.originalWait(key, payload);
1253
- return payload === void 0 ? mock.wait() : mock.wait(payload);
1254
- };
1255
- const dispatchResolve = async (key, executionId, callback) => {
1256
- const mock = slot.perKey.get(key);
1257
- if (!mock) return slot.originalResolve(key, executionId, callback);
1258
- await mock.resolve(executionId, callback);
1259
- };
1260
- baseInvokerWait.set(dispatchWait, baseWait);
1261
- baseInvokerResolve.set(dispatchResolve, baseResolve);
1262
- record.wait = dispatchWait;
1263
- record.resolve = dispatchResolve;
1264
- const eachSpy = (fn) => {
1265
- for (const mock of slot.perKey.values()) {
1266
- const pair = mock;
1267
- fn(pair.wait);
1268
- fn(pair.resolve);
1269
- }
1270
- };
1271
- scopedMocks.add({
1272
- mockClear: () => eachSpy((spy) => spy.mockClear()),
1273
- mockReset: () => eachSpy((spy) => spy.mockReset()),
1274
- restore: () => {
1275
- record.wait = prevWait;
1276
- record.resolve = prevResolve;
1277
- keyDispatchers.delete(definition);
1278
- }
1279
- });
1280
- keyDispatchers.set(definition, slot);
1281
- return slot;
1282
- };
1283
- const defaultExecJob = (jobName, _args, _options) => {
1284
- throw new Error(`No workflow job mock for "${jobName}". Call mockWorkflow().setJobHandler(...) or enqueueResult(...), or use runWorkflowLocally() for local workflow execution.`);
1285
- };
1286
- const defaultStartWorkflow = async (_workflowName, _args, _options) => {
1287
- return START_DEFAULT;
1288
- };
1289
- const defaultResumeWorkflowExecution = async (executionId) => executionId;
1290
- const execJobFunction = vi.fn(defaultExecJob);
1291
- const startWorkflow = vi.fn(defaultStartWorkflow);
1292
- const resumeWorkflowExecution = vi.fn(defaultResumeWorkflowExecution);
1293
- const wait = vi.fn((_key, _payload) => null);
1294
- const resolve = vi.fn(async (_executionId, _key, _callback) => {});
1295
- const jobFunctionShim = (...call) => {
1296
- const out = call.length >= 3 ? execJobFunction(call[0], platformSerialize(call[1]), call[2]) : execJobFunction(call[0], platformSerialize(call[1]));
1297
- return out instanceof Promise ? out.then((v) => platformSerialize(v)) : platformSerialize(out);
1298
- };
1299
- const workflowShim = (...call) => call.length >= 3 ? startWorkflow(call[0], platformSerialize(call[1]), call[2]) : startWorkflow(call[0], platformSerialize(call[1]));
1300
- const resumeShim = (executionId) => resumeWorkflowExecution(executionId);
1301
- root.workflow = {
1302
- execJobFunction: jobFunctionShim,
1303
- startWorkflow: workflowShim,
1304
- resumeWorkflowExecution: resumeShim,
1305
- wait: (key, payload) => wait(key, platformSerialize(payload)),
1306
- resolve: (executionId, key, callback) => resolve(executionId, key, (payload) => {
1307
- const out = callback(payload);
1308
- return out instanceof Promise ? out.then((v) => platformSerialize(v)) : platformSerialize(out);
1309
- })
1310
- };
1311
- return withDispose({
1312
- /** The `execJobFunction` `vi.fn`. */
1313
- execJobFunction,
1314
- /** The `startWorkflow` `vi.fn`. */
1315
- startWorkflow,
1316
- /** The `resumeWorkflowExecution` `vi.fn`. */
1317
- resumeWorkflowExecution,
1318
- /** The `wait` `vi.fn`. */
1319
- wait,
1320
- /** The `resolve` `vi.fn`. */
1321
- resolve,
1322
- /**
1323
- * Get a stable, typed mock for a workflow job's `start` method.
1324
- * The real start behavior is used until an implementation or result is configured.
1325
- * @param definition - Workflow job definition to mock
1326
- * @returns Typed `start` mock for the definition
1327
- */
1328
- job(definition) {
1329
- const existing = jobSpies.get(definition);
1330
- if (existing) return existing;
1331
- const { mock, scoped } = replaceStart(definition);
1332
- scopedMocks.add(scoped);
1333
- jobSpies.set(definition, mock);
1334
- return mock;
1335
- },
1336
- /**
1337
- * Get a stable, typed mock for a workflow definition's `start` method.
1338
- * The real start behavior is used until an implementation or result is configured.
1339
- * @param definition - Workflow definition to mock
1340
- * @returns Typed `start` mock for the definition
1341
- */
1342
- workflow(definition) {
1343
- const existing = workflowSpies.get(definition);
1344
- if (existing) return existing;
1345
- const { mock, scoped } = replaceStart(definition);
1346
- workflowSpies.set(definition, mock);
1347
- scopedMocks.add(scoped);
1348
- return mock;
1349
- },
1350
- /**
1351
- * Get stable, typed mocks for a wait point's `wait` and `resolve` methods.
1352
- * @param definition - Wait point definition to mock
1353
- * @returns Typed wait point mock control object
1354
- */
1355
- waitPoint(definition) {
1356
- const existing = waitPointMocks.get(definition);
1357
- if (existing) return existing;
1358
- const waitReplacement = replaceProcedure(definition, "wait", definition.wait);
1359
- const resolveReplacement = replaceProcedure(definition, "resolve", definition.resolve);
1360
- const waitSpy = waitReplacement.mock;
1361
- const resolveSpy = resolveReplacement.mock;
1362
- scopedMocks.add(waitReplacement.scoped);
1363
- scopedMocks.add(resolveReplacement.scoped);
1364
- const waitPointMock = {
1365
- wait: waitSpy,
1366
- resolve: resolveSpy,
1367
- /**
1368
- * Invoke the next and subsequent resolve callbacks with a wait payload.
1369
- * @param payload - Payload originally supplied to the wait point
1370
- */
1371
- setResolvePayload(payload) {
1372
- resolveSpy.mockImplementation(async (_executionId, callback) => {
1373
- const result = await callback(platformSerialize(payload));
1374
- platformSerialize(result);
1375
- });
1376
- }
1377
- };
1378
- waitPointMocks.set(definition, waitPointMock);
1379
- return waitPointMock;
1380
- },
1381
- /**
1382
- * Get stable, typed mocks for one param binding of a parameterized wait point.
1383
- * Calls made with other bindings fall through to the platform mock.
1384
- * @param definition - Parameterized wait point definition to mock
1385
- * @param params - Param binding to intercept, as passed to `.with()`
1386
- * @returns Typed wait point mock control object
1387
- */
1388
- waitPointWith(definition, params) {
1389
- const key = getWaitPointKey(definition.with(params));
1390
- if (key === void 0) throw new Error("waitPointWith expects a wait point declared with $params. Use waitPoint() for a wait point with a fixed key.");
1391
- const slot = installKeyDispatcher(definition);
1392
- const existing = slot.perKey.get(key);
1393
- if (existing) return existing;
1394
- const waitSpy = vi.fn((payload) => Promise.resolve(slot.originalWait(key, payload)));
1395
- const resolveSpy = vi.fn((executionId, callback) => slot.originalResolve(key, executionId, callback));
1396
- const waitPointMock = {
1397
- wait: waitSpy,
1398
- resolve: resolveSpy,
1399
- /**
1400
- * Invoke the next and subsequent resolve callbacks with a wait payload.
1401
- * @param payload - Payload originally supplied to the wait point
1402
- */
1403
- setResolvePayload(payload) {
1404
- resolveSpy.mockImplementation(async (_executionId, callback) => {
1405
- const result = await callback(platformSerialize(payload));
1406
- platformSerialize(result);
1407
- });
1408
- }
1409
- };
1410
- slot.perKey.set(key, waitPointMock);
1411
- return waitPointMock;
1412
- },
1413
- /**
1414
- * Set a fallback job handler. Called when the enqueue queue is empty.
1415
- * @param handler - Function returning a result for a job name, args, and options
1416
- */
1417
- setJobHandler(handler) {
1418
- execJobFunction.mockImplementation((name, args, options) => handler(name, args, options));
1419
- },
1420
- /**
1421
- * Enqueue a single result for the next `execJobFunction` call (FIFO;
1422
- * takes priority over `setJobHandler`).
1423
- * @param result - Result to return from the next call
1424
- */
1425
- enqueueResult(result) {
1426
- execJobFunction.mockImplementationOnce(() => result);
1427
- },
1428
- /**
1429
- * Enqueue results for multiple subsequent `execJobFunction` calls (FIFO).
1430
- * @param results - Results to enqueue, one per upcoming call
1431
- */
1432
- enqueueResults(...results) {
1433
- for (const result of results) execJobFunction.mockImplementationOnce(() => result);
1434
- },
1435
- /**
1436
- * All jobs executed via `execJobFunction`, in order.
1437
- * @returns Started jobs array
1438
- */
1439
- get startedJobs() {
1440
- return execJobFunction.mock.calls.map(([jobName, args, options]) => ({
1441
- jobName,
1442
- args,
1443
- ...options !== void 0 && { options }
1444
- }));
1445
- },
1446
- /**
1447
- * Configure what `startWorkflow` returns. Pass a string (same id every
1448
- * call) or `(name, args, options) => string`. Default: a placeholder UUID.
1449
- * @param handler - Static execution ID or a function returning one
1450
- */
1451
- setStartHandler(handler) {
1452
- startWorkflow.mockImplementation(typeof handler === "function" ? async (name, args, options) => handler(name, args, options) : async () => handler);
1453
- },
1454
- /**
1455
- * Configure what `resumeWorkflowExecution` returns. Pass a string (same id
1456
- * every call) or `(executionId) => string`. Default: echoes the input executionId.
1457
- * @param handler - Static execution ID or a function returning one
1458
- */
1459
- setResumeHandler(handler) {
1460
- resumeWorkflowExecution.mockImplementation(typeof handler === "function" ? async (executionId) => handler(executionId) : async () => handler);
1461
- },
1462
- /**
1463
- * Configure what `wait` returns. Pass `(key, payload) => unknown` or any
1464
- * other value to return it for every call. Default: `null`.
1465
- * @param handler - Static value or a function returning one
1466
- */
1467
- setWaitHandler: ((handler) => {
1468
- wait.mockImplementation(typeof handler === "function" ? (key, payload) => handler(key, payload) : () => handler);
1469
- }),
1470
- /**
1471
- * Set the `env` passed to job bodies invoked via `createWorkflowJob().start()`.
1472
- * Cleared on dispose / reset.
1473
- * @param env - Env passed to job bodies.
1474
- */
1475
- setEnv(env) {
1476
- writeWorkflowTestEnv({ ...env });
1477
- },
1478
- /**
1479
- * Configure how `resolve` runs the user-supplied callback. Default: callback
1480
- * is not invoked (records the call only).
1481
- * @param handler - Function invoked per `resolve` call
1482
- */
1483
- setResolveHandler(handler) {
1484
- resolve.mockImplementation(async (executionId, key, callback) => {
1485
- await handler(executionId, key, callback);
1486
- });
1487
- },
1488
- /**
1489
- * `wait` calls reshaped as `{ key, payload }` for assertions.
1490
- * @returns Wait call records
1491
- */
1492
- get waitCalls() {
1493
- return wait.mock.calls.map(([key, payload]) => ({
1494
- key,
1495
- payload
1496
- }));
1497
- },
1498
- /**
1499
- * `resolve` calls reshaped as `{ executionId, key }` for assertions.
1500
- * @returns Resolve call records
1501
- */
1502
- get resolveCalls() {
1503
- return resolve.mock.calls.map(([executionId, key]) => ({
1504
- executionId,
1505
- key
1506
- }));
1507
- },
1508
- /** Clear recorded calls while preserving configured responses. */
1509
- clear() {
1510
- execJobFunction.mockClear();
1511
- startWorkflow.mockClear();
1512
- resumeWorkflowExecution.mockClear();
1513
- wait.mockClear();
1514
- resolve.mockClear();
1515
- for (const mock of scopedMocks) mock.mockClear();
1516
- },
1517
- /** Reset all workflow responses and recorded calls (keeps the mock installed). */
1518
- reset() {
1519
- execJobFunction.mockReset();
1520
- execJobFunction.mockImplementation(defaultExecJob);
1521
- startWorkflow.mockReset();
1522
- startWorkflow.mockImplementation(defaultStartWorkflow);
1523
- resumeWorkflowExecution.mockReset();
1524
- resumeWorkflowExecution.mockImplementation(defaultResumeWorkflowExecution);
1525
- wait.mockReset();
1526
- wait.mockImplementation(() => null);
1527
- resolve.mockReset();
1528
- resolve.mockImplementation(async () => {});
1529
- for (const mock of scopedMocks) mock.mockReset();
1530
- clearWorkflowTestEnv();
1531
- }
1532
- }, () => {
1533
- for (const mock of scopedMocks) mock.restore();
1534
- root.workflow = prev;
1535
- if (prevEnv !== void 0) writeWorkflowTestEnv(prevEnv);
1536
- else clearWorkflowTestEnv();
1537
- });
1538
- }
1539
-
1540
- //#endregion
1541
- //#region src/vitest/workflow-local.ts
1542
- var PendingStart = class {
1543
- jobName;
1544
- args;
1545
- constructor(jobName, args) {
1546
- this.jobName = jobName;
1547
- this.args = args;
1548
- }
1549
- };
1550
- async function runWorkflowLocally(workflow, args, options) {
1551
- const root = globalThis;
1552
- const previousTailor = root.tailor;
1553
- const previousEnv = readWorkflowTestEnv();
1554
- const hasPreviousEnv = previousEnv !== void 0;
1555
- const runner = createLocalJobRunner();
1556
- if (options?.env !== void 0) writeWorkflowTestEnv({ ...options.env });
1557
- root.tailor = {
1558
- ...previousTailor,
1559
- workflow: createLocalWorkflowRuntime(previousTailor?.workflow, runner.execJobFunction)
1560
- };
1561
- try {
1562
- return await runner.runJob(workflow.mainJob.name, args);
1563
- } finally {
1564
- if (previousTailor) root.tailor = previousTailor;
1565
- else delete root.tailor;
1566
- if (options?.env !== void 0) {
1567
- if (hasPreviousEnv) writeWorkflowTestEnv(previousEnv);
1568
- else clearWorkflowTestEnv();
1569
- }
1570
- }
1571
- }
1572
- function createLocalJobRunner() {
1573
- let activeExecution;
1574
- const execJobFunction = (jobName, args) => {
1575
- if (!activeExecution) throw new Error(`Cannot start workflow job "${jobName}" outside runWorkflowLocally() job execution.`);
1576
- if (activeExecution.pending) throw activeExecution.pending;
1577
- const serializedArgs = platformSerialize(args);
1578
- const index = activeExecution.cursor;
1579
- activeExecution.cursor += 1;
1580
- const cached = activeExecution.records[index];
1581
- if (cached) {
1582
- assertSameStart(cached, jobName, serializedArgs);
1583
- if (cached.status === "rejected") throw cached.error;
1584
- return platformSerialize(cached.result);
1585
- }
1586
- const pending = new PendingStart(jobName, serializedArgs);
1587
- activeExecution.pending = pending;
1588
- throw pending;
1589
- };
1590
- const runJob = async (name, args) => {
1591
- const body = getRegisteredJob(name);
1592
- if (!body) return null;
1593
- const records = [];
1594
- for (;;) {
1595
- const execution = {
1596
- records,
1597
- cursor: 0
1598
- };
1599
- const previousExecution = activeExecution;
1600
- activeExecution = execution;
1601
- try {
1602
- const out = await body(platformSerialize(args), buildJobContext());
1603
- if (execution.pending) {
1604
- await settlePendingStart(records, execution.pending, runJob);
1605
- continue;
1606
- }
1607
- if (execution.cursor !== records.length) throw new Error(`Workflow job start sequence changed while replaying "${name}". Expected ${records.length} start(s), but replay reached ${execution.cursor}.`);
1608
- return platformSerialize(out);
1609
- } catch (cause) {
1610
- const pending = cause instanceof PendingStart ? cause : execution.pending;
1611
- if (pending) {
1612
- await settlePendingStart(records, pending, runJob);
1613
- continue;
1614
- }
1615
- throw cause;
1616
- } finally {
1617
- activeExecution = previousExecution;
1618
- }
1619
- }
1620
- };
1621
- return {
1622
- runJob,
1623
- execJobFunction
1624
- };
1625
- }
1626
- async function settlePendingStart(records, pending, runJob) {
1627
- try {
1628
- records.push({
1629
- jobName: pending.jobName,
1630
- args: pending.args,
1631
- status: "fulfilled",
1632
- result: await runJob(pending.jobName, pending.args)
1633
- });
1634
- } catch (error) {
1635
- records.push({
1636
- jobName: pending.jobName,
1637
- args: pending.args,
1638
- status: "rejected",
1639
- error
1640
- });
1641
- }
1642
- }
1643
- function assertSameStart(record, jobName, args) {
1644
- if (record.jobName === jobName && JSON.stringify(record.args) === JSON.stringify(args)) return;
1645
- throw new Error(`Workflow job start sequence changed while replaying. Expected ${record.jobName}(${JSON.stringify(record.args)}), but got ${jobName}(${JSON.stringify(args)}).`);
1646
- }
1647
- function createLocalWorkflowRuntime(previous, execJobFunction) {
1648
- const startWorkflow = async (name, args, options) => {
1649
- if (previous) return await previous.startWorkflow(name, args, options);
1650
- platformSerialize(args);
1651
- return START_DEFAULT;
1652
- };
1653
- const resumeWorkflowExecution = async (executionId) => {
1654
- if (previous) return await previous.resumeWorkflowExecution(executionId);
1655
- return executionId;
1656
- };
1657
- return {
1658
- execJobFunction,
1659
- startWorkflow,
1660
- resumeWorkflowExecution,
1661
- wait: (key, payload) => {
1662
- if (previous) return previous.wait(key, payload);
1663
- throw new Error(`No wait handler for "${key}". Acquire mockWorkflow() and call setWaitHandler(...).`);
1664
- },
1665
- resolve: async (executionId, key, callback) => {
1666
- if (previous) {
1667
- await previous.resolve(executionId, key, callback);
1668
- return;
1669
- }
1670
- throw new Error("No resolve handler. Acquire mockWorkflow() and call setResolveHandler(...).");
1671
- }
1672
- };
1673
- }
1674
-
1675
- //#endregion
1676
- //#region src/vitest/mock-kysely.ts
1677
- /**
1678
- * Kysely-layer mock for unit testing.
1679
- *
1680
- * Builds a real Kysely instance backed by a mock driver: queries compile and
1681
- * type-check normally, but execution returns staged rows and records every
1682
- * query for assertions.
1683
- */
1684
- function unwrapValue(node) {
1685
- return ValueNode.is(node) ? node.value : node;
1686
- }
1687
- function insertRows(node) {
1688
- if (!InsertQueryNode.is(node)) throw new Error(`insertRows: expected InsertQueryNode, got ${node.kind}`);
1689
- const columns = node.columns;
1690
- const valuesNode = node.values;
1691
- if (columns === void 0 || valuesNode === void 0 || !ValuesNode.is(valuesNode)) throw new Error("insertRows: unsupported insert shape; inspect query.node instead");
1692
- return valuesNode.values.map((row) => {
1693
- if (!PrimitiveValueListNode.is(row) && !ValueListNode.is(row)) throw new Error("insertRows: unsupported insert shape; inspect query.node instead");
1694
- const values = PrimitiveValueListNode.is(row) ? row.values : row.values.map(unwrapValue);
1695
- const result = {};
1696
- columns.forEach((col, i) => {
1697
- result[col.column.name] = values[i];
1698
- });
1699
- return result;
1700
- });
1701
- }
1702
- function insertValues(node) {
1703
- const rows = insertRows(node);
1704
- if (rows.length !== 1) throw new Error(`insertValues: query inserts ${rows.length} rows; use insertRows() for multi-row inserts`);
1705
- return assertDefined(rows[0], "insertValues: first row missing");
1706
- }
1707
- function updateValues(node) {
1708
- if (!UpdateQueryNode.is(node)) throw new Error(`updateValues: expected UpdateQueryNode, got ${node.kind}`);
1709
- if (node.updates === void 0) throw new Error("updateValues: unsupported update shape; inspect query.node instead");
1710
- const result = {};
1711
- for (const update of node.updates) {
1712
- const col = update.column;
1713
- const name = ColumnNode.is(col) ? col.column.name : ReferenceNode.is(col) && ColumnNode.is(col.column) ? col.column.column.name : void 0;
1714
- if (name === void 0) throw new Error("updateValues: unsupported update shape; inspect query.node instead");
1715
- result[name] = unwrapValue(update.value);
1716
- }
1717
- return result;
1718
- }
1719
- function toExecutedQuery(compiledQuery) {
1720
- const node = compiledQuery.query;
1721
- return {
1722
- kind: node.kind,
1723
- sql: compiledQuery.sql,
1724
- parameters: compiledQuery.parameters,
1725
- node,
1726
- insertRows: () => insertRows(node),
1727
- insertValues: () => insertValues(node),
1728
- updateValues: () => updateValues(node)
1729
- };
1730
- }
1731
- function toStagedResult(result) {
1732
- if (Array.isArray(result)) return {
1733
- rows: result,
1734
- numAffectedRows: void 0
1735
- };
1736
- return {
1737
- rows: result.rows ?? [],
1738
- numAffectedRows: result.numAffectedRows === void 0 ? void 0 : BigInt(result.numAffectedRows)
1739
- };
1740
- }
1741
- var MockState = class {
1742
- executed = [];
1743
- queue = [];
1744
- resolver;
1745
- enqueue(...results) {
1746
- this.queue.push(...results);
1747
- }
1748
- setResolver(resolver) {
1749
- this.resolver = resolver;
1750
- }
1751
- next(query) {
1752
- const resolved = this.resolver?.(query);
1753
- if (resolved !== void 0) return toStagedResult(resolved);
1754
- const queued = this.queue.shift();
1755
- return queued === void 0 ? {
1756
- rows: [],
1757
- numAffectedRows: void 0
1758
- } : toStagedResult(queued);
1759
- }
1760
- reset() {
1761
- this.executed.length = 0;
1762
- this.queue.length = 0;
1763
- this.resolver = void 0;
1764
- }
1765
- };
1766
- var MockConnection = class {
1767
- state;
1768
- constructor(state) {
1769
- this.state = state;
1770
- }
1771
- async executeQuery(compiledQuery) {
1772
- const query = toExecutedQuery(compiledQuery);
1773
- this.state.executed.push(query);
1774
- const { rows, numAffectedRows } = this.state.next(query);
1775
- return {
1776
- rows,
1777
- numAffectedRows: numAffectedRows ?? BigInt(rows.length)
1778
- };
1779
- }
1780
- streamQuery() {
1781
- throw new Error("createKyselyMock: streaming is not supported");
1782
- }
1783
- };
1784
- var MockDriver = class {
1785
- state;
1786
- constructor(state) {
1787
- this.state = state;
1788
- }
1789
- async init() {}
1790
- async acquireConnection() {
1791
- return new MockConnection(this.state);
1792
- }
1793
- async beginTransaction() {}
1794
- async commitTransaction() {}
1795
- async rollbackTransaction() {}
1796
- async releaseConnection() {}
1797
- async destroy() {}
1798
- };
1799
- function byKind(state, kind) {
1800
- return state.executed.filter((query) => query.kind === kind);
1801
- }
1802
- /**
1803
- * Create a mock Kysely instance for unit-testing code that runs Kysely queries.
1804
- * Pass the namespace schema as the type argument, e.g.
1805
- * `createKyselyMock<Namespace["main-db"]>()`.
1806
- * @returns A {@link KyselyMock} with the mock `db`, recorded queries, and result staging.
1807
- */
1808
- function createKyselyMock() {
1809
- const state = new MockState();
1810
- const kysely = new Kysely({ dialect: {
1811
- createDriver: () => new MockDriver(state),
1812
- createQueryCompiler: () => new PostgresQueryCompiler(),
1813
- createAdapter: () => new PostgresAdapter(),
1814
- createIntrospector: (db) => new PostgresIntrospector(db)
1815
- } });
1816
- return {
1817
- db: kysely,
1818
- get executedQueries() {
1819
- return state.executed;
1820
- },
1821
- get selects() {
1822
- return byKind(state, "SelectQueryNode");
1823
- },
1824
- get inserts() {
1825
- return byKind(state, "InsertQueryNode");
1826
- },
1827
- get updates() {
1828
- return byKind(state, "UpdateQueryNode");
1829
- },
1830
- get deletes() {
1831
- return byKind(state, "DeleteQueryNode");
1832
- },
1833
- enqueueResult: (result) => state.enqueue(result),
1834
- enqueueResults: (...results) => state.enqueue(...results),
1835
- setQueryResolver: (resolver) => state.setResolver(resolver),
1836
- withTx: (fn) => kysely.transaction().execute(fn),
1837
- reset: () => state.reset(),
1838
- [Symbol.dispose]: () => state.reset()
1839
- };
1840
- }
1841
-
1842
- //#endregion
1843
- //#region src/vitest/pglite-kysely.ts
1844
- /**
1845
- * Kysely adapter for running migration scripts against PGlite.
1846
- *
1847
- * Accepts the PGlite client structurally so the SDK does not depend on
1848
- * `@electric-sql/pglite`; users install it themselves as a devDependency.
1849
- */
1850
- var PGliteConnection = class {
1851
- #client;
1852
- constructor(client) {
1853
- this.#client = client;
1854
- }
1855
- async executeQuery(compiledQuery) {
1856
- const result = await this.#client.query(compiledQuery.sql, [...compiledQuery.parameters]);
1857
- return {
1858
- rows: result.rows,
1859
- numAffectedRows: BigInt(result.affectedRows ?? 0)
1860
- };
1861
- }
1862
- streamQuery() {
1863
- throw new Error("createKyselyPGlite: streaming is not supported");
1864
- }
1865
- };
1866
- var PGliteDriver = class {
1867
- #client;
1868
- constructor(client) {
1869
- this.#client = client;
1870
- }
1871
- async init() {}
1872
- async acquireConnection() {
1873
- return new PGliteConnection(this.#client);
1874
- }
1875
- async beginTransaction(connection, settings) {
1876
- const parts = settings.isolationLevel ? ["start transaction", `isolation level ${settings.isolationLevel}`] : ["begin"];
1877
- if (settings.accessMode) parts.push(settings.accessMode);
1878
- await connection.executeQuery(CompiledQuery.raw(parts.join(" ")));
1879
- }
1880
- async commitTransaction(connection) {
1881
- await connection.executeQuery(CompiledQuery.raw("commit"));
1882
- }
1883
- async rollbackTransaction(connection) {
1884
- await connection.executeQuery(CompiledQuery.raw("rollback"));
1885
- }
1886
- async releaseConnection() {}
1887
- async destroy() {
1888
- await this.#client.close();
1889
- }
1890
- };
1891
- /**
1892
- * Create a Kysely instance backed by a PGlite in-memory Postgres, for
1893
- * executing a migration script's queries against real data in tests.
1894
- * Pass the migration's schema as the type argument, e.g.
1895
- * `createKyselyPGlite<Database>(new PGlite())`.
1896
- *
1897
- * PGlite runs full PostgreSQL while TailorDB supports a subset of it, so a
1898
- * statement passing here can still be rejected by the platform; keep a
1899
- * statement-level test (see `createKyselyMock`) alongside.
1900
- * @param client - A `PGlite` instance from `@electric-sql/pglite`
1901
- * @returns A Kysely instance that executes queries on the client and closes it on `destroy()`
1902
- * @example
1903
- * ```typescript
1904
- * // migrations/0005/migrate.test.ts
1905
- * import { PGlite } from "@electric-sql/pglite";
1906
- * import { createKyselyPGlite } from "@tailor-platform/sdk/vitest";
1907
- * import type { Database } from "./db";
1908
- * import { main } from "./migrate";
1909
- *
1910
- * const db = createKyselyPGlite<Database>(new PGlite());
1911
- * // create tables matching db.ts, insert rows, then:
1912
- * await db.transaction().execute((trx) => main(trx));
1913
- * ```
1914
- */
1915
- function createKyselyPGlite(client) {
1916
- return new Kysely({ dialect: {
1917
- createAdapter: () => new PostgresAdapter(),
1918
- createDriver: () => new PGliteDriver(client),
1919
- createIntrospector: (db) => new PostgresIntrospector(db),
1920
- createQueryCompiler: () => new PostgresQueryCompiler()
1921
- } });
1922
- }
1923
-
1924
- //#endregion
1925
- //#region src/vitest/index.ts
1926
- /**
1927
- * Creates Vitest plugins that emulate the Tailor Platform function runtime environment.
1928
- *
1929
- * **Beta:** This API may change in future releases.
1930
- *
1931
- * ## What it does
1932
- *
1933
- * 1. **Node.js module blocking** (transform hook) — Imports of `node:*` modules
1934
- * (and bare builtins like `crypto`, `fs`) in non-test source files are replaced
1935
- * with code that throws an error with a suggestion for the Web Standard API alternative.
1936
- * Test files are exempt and can use `node:*` freely. Test file patterns are read
1937
- * from the resolved Vitest config (`test.include`).
1938
- *
1939
- * 2. **Node.js globals removal** (environment + setup) — Only globals available in the
1940
- * Tailor Platform runtime are kept (whitelist: ECMAScript standard, Web Standard APIs
1941
- * from bootstrap.js, platform mocks). All others (`Buffer`, `global`, `setImmediate`,
1942
- * `__dirname`, `__filename`, etc.) are removed. `performance` is removed per-test
1943
- * via beforeEach/afterEach since Vitest needs it during initialization.
1944
- *
1945
- * 3. **Platform API mocks** (environment) — All platform APIs are auto-injected with
1946
- * control objects: `mockTailordb`, `mockWorkflow`, `mockSecretmanager`,
1947
- * `mockAuthconnection`, `mockIdp`, `mockFile`, `mockIconv`, `mockAigateway`,
1948
- * `mockLogger`. Each
1949
- * provides response configuration, call recording, and reset.
1950
- *
1951
- * 4. **Environment resolution** — Rewrites `environment: "tailor-runtime"` to the
1952
- * absolute path of the bundled environment module via the config hook.
1953
- *
1954
- * ## Known limitations
1955
- *
1956
- * - **`process`** and **`require`** are NOT removed or blocked. Vitest's internal
1957
- * runner depends on them. On the real Tailor Platform runtime, they do not exist.
1958
- * - **Dynamic `import()`** of bundled files bypasses the transform hook since
1959
- * those files are loaded through Node.js native loader.
1960
- * ## Options
1961
- *
1962
- * - **`config`** — Path to `tailor.config.ts`. Loads `defineSecretManager()` values
1963
- * into `mockSecretmanager` so `getSecret()` returns the configured values.
1964
- * @example
1965
- * ```typescript
1966
- * // vitest.config.ts
1967
- * import { defineConfig } from "vitest/config";
1968
- * import { tailorRuntime } from "@tailor-platform/sdk/vitest";
1969
- *
1970
- * export default defineConfig({
1971
- * plugins: [tailorRuntime({ config: "./tailor.config.ts" })],
1972
- * test: {
1973
- * environment: "tailor-runtime",
1974
- * },
1975
- * });
1976
- * ```
1977
- * @param options - Optional configuration
1978
- * @param options.config - Path to tailor.config.ts to load SecretManager values into mock
1979
- * @returns Array of Vite plugins
1980
- */
1981
- function tailorRuntime(options) {
1982
- return [createBlockPlugin(), createEnvironmentPlugin(options)];
1983
- }
1984
-
1985
- //#endregion
1986
- export { createKyselyMock, createKyselyPGlite, mockAigateway, mockAuthconnection, mockFile, mockIconv, mockIdp, mockLogger, mockSecretmanager, mockTailordb, mockWorkflow, runWorkflowLocally, tailorRuntime };
1
+ import{i as e,t}from"../registry-HlEaGvl5.mjs";import{a as n,c as r,i,o as a,s as o,u as s}from"../wait-point-invoker-eiP-IIux.mjs";import{t as c}from"../assert-WeXvmG4j.mjs";import{n as l,t as u}from"../node-builtins-oBl7EbyV.mjs";import{t as d}from"../platform-serialize-DkiTdHOt.mjs";import{i as f,n as p,r as m,t as h}from"../secretmanager-5olfnI1b.mjs";import{isEqual as g}from"es-toolkit";import{fileURLToPath as _}from"node:url";import{ColumnNode as v,CompiledQuery as y,InsertQueryNode as b,Kysely as x,PostgresAdapter as S,PostgresIntrospector as C,PostgresQueryCompiler as w,PrimitiveValueListNode as T,ReferenceNode as E,UpdateQueryNode as D,ValueListNode as O,ValueNode as k,ValuesNode as A}from"kysely";import{dirname as j,isAbsolute as M,matchesGlob as N,relative as P,resolve as F}from"node:path";import{vi as I}from"vitest";function isBlockedModule(e){return l(e)}function getBlockedMessage(e){return u(e)}const L=[`**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}`],R=new Set([`ImportDeclaration`,`ExportNamedDeclaration`,`ExportAllDeclaration`]),z=new Set(`break.case.catch.class.const.continue.debugger.default.delete.do.else.enum.export.extends.false.finally.for.function.if.import.in.instanceof.new.null.return.super.switch.this.throw.true.try.typeof.var.void.while.with.yield.let.static.implements.interface.package.private.protected.public.await.arguments.eval`.split(`.`)),B=/^[A-Za-z_$]/,V=/^[A-Za-z0-9_$]*$/;function isSafeBindingName(e){if(z.has(e)||e.length===0)return!1;let t=e[0];return t!==void 0&&B.test(t)&&V.test(e.slice(1))}function buildBlockedReplacement(e,t){let n=JSON.stringify(t),r=`throw new Error(${n});`,i=`(() => { throw new Error(${n}); })()`;if(e.type===`ExportNamedDeclaration`){let t=e.specifiers??[],n=[];for(let e of t){let t=e.exported?.name;if(typeof t==`string`){if(t==="default"){n.push(`export default ${i};`);continue}if(!isSafeBindingName(t))return r;n.push(`export const ${t} = ${i};`)}}return n.length>0?n.join(` `):r}if(e.type===`ExportAllDeclaration`){let t=e.exported?.name;return typeof t==`string`&&isSafeBindingName(t)?`export const ${t} = ${i};`:r}return r}function createBlockPlugin(){let isTestFile=()=>!1,isUserSourceFile=()=>!1;return{name:`tailor-runtime-block-node`,configResolved(e){let t=e.test,n=t?.root??e.root,toAbsolutePaths=(e,t)=>(Array.isArray(e)?e:e?[e]:[]).map(e=>F(t,e)),r=new Set([...toAbsolutePaths(t?.setupFiles,n),...toAbsolutePaths(t?.globalSetup,n)]),i=[{root:n,patterns:t?.include??L}];for(let e of t?.projects??[]){let t=e.test;if(!t)continue;let a=t.root??n;for(let e of toAbsolutePaths(t.setupFiles,a))r.add(e);for(let e of toAbsolutePaths(t.globalSetup,a))r.add(e);i.push({root:a,patterns:t.include??L})}isTestFile=e=>r.has(e)?!0:i.some(({root:t,patterns:n})=>{let r=M(e)?P(t,e):e;return n.some(e=>N(r,e))}),isUserSourceFile=e=>{if(!M(e))return!1;let t=P(n,e);return t!==``&&!t.startsWith(`..`)&&!M(t)}},transform(e,t){let n=t.search(/[?#]/),r=n===-1?t:t.slice(0,n);if(isTestFile(r)||r.includes(`node_modules`)||!isUserSourceFile(r))return;let i;try{i=this.parse(e)}catch{return}let a=[];for(let e of i.body){if(!R.has(e.type))continue;let t=e.source?.value;typeof t==`string`&&isBlockedModule(t)&&a.push({start:e.start,end:e.end,replacement:buildBlockedReplacement(e,getBlockedMessage(t))})}if(a.length===0)return;let o=e;for(let e of a.toSorted((e,t)=>t.start-e.start))o=o.slice(0,e.start)+e.replacement+o.slice(e.end);return{code:o,map:null}}}}const H=`tailor-runtime`;function createEnvironmentPlugin(e){let t=j(_(import.meta.url)),n=F(t,`environment.mjs`),r=F(t,`setup.mjs`);return{name:`tailor-runtime-environment`,config(t){let i=t.test,a=!1;if(i?.environment===H&&(i.environment=n,a=!0),i?.projects)for(let e of i.projects){let t=e.test;t?.environment===H&&(t.environment=n,a=!0)}if(delete process.env.__TAILOR_RUNTIME_CONFIG,e?.config&&a){let n=t.root??process.cwd(),r=F(n,e.config);process.env.__TAILOR_RUNTIME_CONFIG=r}return i&&typeof i.setupFiles==`string`&&(i.setupFiles=[i.setupFiles]),{test:{setupFiles:[r]}}}}}function mockAigateway(e={}){let t=p(),n=t.aigateway,r={...e.urls};async function defaultGet(e){let t=r[e];if(t===void 0)throw Error(`No AI Gateway registered for "${e}". Acquire mockAigateway() and call setUrls(...).`);return{url:t}}let i=I.fn(defaultGet);return t.aigateway={get:i},f({get:i,setUrls(e){r=e},setUrl(e,t){r={...r,[e]:t}},get calls(){return i.mock.calls.map(([e])=>({name:e}))},clear(){i.mockClear()},reset(){r={},i.mockReset(),i.mockImplementation(defaultGet)}},()=>{t.aigateway=n})}function mockAuthconnection(e={}){let t=p(),n=t.authconnection,r={...e.tokens};async function defaultGetConnectionToken(t){let n=r[t];if(n)return n;if(e.onUnhandled===`error`)throw Error(`No AuthConnection token configured for "${t}"`);return{access_token:`mock-token`}}let i=I.fn(defaultGetConnectionToken);return t.authconnection={getConnectionToken:i},f({getConnectionToken:i,setTokens(e){r=e},setToken(e,t){r={...r,[e]:t}},get calls(){return i.mock.calls.map(([e])=>({connectionName:e}))},clear(){i.mockClear()},reset(){r={},i.mockReset(),i.mockImplementation(defaultGetConnectionToken)}},()=>{t.authconnection=n})}const U=[`upload`,`download`,`downloadAsBase64`,`delete`,`getMetadata`,`downloadStream`,`uploadStream`],W={upload:{metadata:{fileSize:0,sha256sum:``}},download:{data:new Uint8Array,metadata:{contentType:``,fileSize:0,sha256sum:``,lastUploadedAt:``}},downloadAsBase64:{data:``,metadata:{contentType:``,fileSize:0,sha256sum:``,lastUploadedAt:``}},getMetadata:{contentType:``,fileSize:0,sha256sum:``,urlPath:``},downloadStream:null,uploadStream:{metadata:{fileSize:0,sha256sum:``}}};function mockFile(e={}){let t=m(),n=t.file,{onUnhandled:r=`fallback`}=e,i=[],a=[],resolver=()=>null;function handle(e,t,n,a,o){if(i.length>0)return i.shift();let s=resolver(e,{method:e,namespace:t,tableName:n,fieldName:a,recordId:o});if(s!=null)return s;if(r===`error`)throw Error(`No File mock configured for "${e}"`);let c=W[e];return c===void 0?void 0:structuredClone(c)}let o=I.fn(async(...e)=>{let[t,n,r,i]=e;return handle(`upload`,t,n,r,i)}),s=I.fn(async(...e)=>handle(`download`,...e)),c=I.fn(async(...e)=>handle(`downloadAsBase64`,...e)),l=I.fn(async(...e)=>{handle(`delete`,...e)}),u=I.fn(async(...e)=>handle(`getMetadata`,...e)),d=I.fn(async(...e)=>handle(`downloadStream`,...e)??{body:new ReadableStream({start(e){e.close()}}),metadata:{contentType:``,fileSize:0,sha256sum:``,lastUploadedAt:``}}),p=I.fn(async(...e)=>{let[t,n,r,i]=e;return handle(`uploadStream`,t,n,r,i)}),h={upload:o,download:s,downloadAsBase64:c,delete:l,getMetadata:u,downloadStream:d,uploadStream:p};function track(e,t){return function(...n){return a.push({method:e,namespace:n[0],tableName:n[1],fieldName:n[2],recordId:n[3]}),t.apply(this,n)}}t.file={upload:track(`upload`,o),download:track(`download`,s),downloadAsBase64:track(`downloadAsBase64`,c),delete:track(`delete`,l),getMetadata:track(`getMetadata`,u),downloadStream:track(`downloadStream`,d),uploadStream:track(`uploadStream`,p)};function allMocks(){return U.map(e=>h[e])}let g={...h,setResolver(e){resolver=e},enqueueResult(e){i.push(e)},enqueueResults(...e){i.push(...e)},get calls(){return a},clear(){a.length=0;for(let e of allMocks())e.mockClear()},reset(){i.length=0,a.length=0,resolver=()=>null;for(let e of allMocks())e.mockReset()}};return f(g,()=>{t.file=n})}function isUtf8(e){return e===`UTF8`||e===`UTF-8`}function defaultIconvResult(e,t){switch(e){case`convert`:case`convertBuffer`:return isUtf8(t[2])?``:new Uint8Array;case`decode`:return``;case`encode`:return isUtf8(t[1])?``:new Uint8Array;case`encodings`:return[]}}function mockIconv(e={}){let t=p(),n=t.iconv,r=null,i=[];function resolve(t,n){if(r){let e=r(t,n);if(e!=null)return e}if(e.onUnhandled===`error`)throw Error(`No Iconv mock behavior configured for "${t}"`);return defaultIconvResult(t,n)}function defaultConvert(e,t,n){return resolve(`convert`,[e,t,n])}function defaultConvertBuffer(e,t,n){return resolve(`convertBuffer`,[e,t,n])}function defaultDecode(e,t){return resolve(`decode`,[e,t])}function defaultEncode(e,t){return resolve(`encode`,[e,t])}function defaultEncodings(){return resolve(`encodings`,[])}let a=I.fn(defaultConvert),o=I.fn(defaultConvertBuffer),s=I.fn(defaultDecode),c=I.fn(defaultEncode),l=I.fn(defaultEncodings);function track(e,t){return function(...n){return i.push({method:e,args:[...n]}),t.apply(this,n)}}let u=track(`convert`,a),d=track(`convertBuffer`,o),m=track(`decode`,s),h=track(`encode`,c),g=track(`encodings`,l);class MockIconv{#e;#t;constructor(e,t){this.#e=e,this.#t=t}convert(e){return u.call(this,e,this.#e,this.#t)}}t.iconv={convert:u,convertBuffer:d,decode:m,encode:h,encodings:g,Iconv:MockIconv};function clear(){i.length=0,a.mockClear(),o.mockClear(),s.mockClear(),c.mockClear(),l.mockClear()}return f({convert:a,convertBuffer:o,decode:s,encode:c,encodings:l,setResolver(e){r=e},get calls(){return i},clear,reset(){r=null,i.length=0,a.mockReset(),a.mockImplementation(defaultConvert),o.mockReset(),o.mockImplementation(defaultConvertBuffer),s.mockReset(),s.mockImplementation(defaultDecode),c.mockReset(),c.mockImplementation(defaultEncode),l.mockReset(),l.mockImplementation(defaultEncodings)}},()=>{t.iconv=n})}const G=[`users`,`user`,`userByName`,`createUser`,`updateUser`,`deleteUser`,`sendPasswordResetEmail`,`unenrollMfa`],K={id:`mock-id`,name:`mock-user`,disabled:!1,mfaEnrolled:!1,mfaFactorIds:[]},q={users:{users:[],nextPageToken:null,totalCount:0},user:K,userByName:K,createUser:K,updateUser:K,deleteUser:!0,sendPasswordResetEmail:!0,unenrollMfa:!0};function mockIdp(e={}){let t=p(),n=t.idp,{onUnhandled:r=`fallback`}=e,i=[],a=[],resolver=()=>null,o=new Map;function compatibilityArgs(e,t){return e===`users`&&t.length===0?[void 0]:t}function handle(e,t,n){if(i.length>0)return i.shift();let a=resolver(e,compatibilityArgs(e,t),n);if(a!=null)return a;if(r===`error`)throw Error(`No IdP mock configured for "${n}.${e}"`);return structuredClone(q[e])}function createNamespaceMocks(e){return{users:I.fn(async(...t)=>handle(`users`,t,e)),user:I.fn(async(...t)=>handle(`user`,t,e)),userByName:I.fn(async(...t)=>handle(`userByName`,t,e)),createUser:I.fn(async(...t)=>handle(`createUser`,t,e)),updateUser:I.fn(async(...t)=>handle(`updateUser`,t,e)),deleteUser:I.fn(async(...t)=>handle(`deleteUser`,t,e)),sendPasswordResetEmail:I.fn(async(...t)=>handle(`sendPasswordResetEmail`,t,e)),unenrollMfa:I.fn(async(...t)=>handle(`unenrollMfa`,t,e))}}function namespace(e){let t=o.get(e);if(t)return t;let n=createNamespaceMocks(e);return o.set(e,n),n}function track(e,t,n){return function(...r){return a.push({method:e,args:[...compatibilityArgs(e,r)],namespace:n}),t.apply(this,r)}}let defaultClient=function(e){let t=namespace(e.namespace);this.users=track(`users`,t.users,e.namespace),this.user=track(`user`,t.user,e.namespace),this.userByName=track(`userByName`,t.userByName,e.namespace),this.createUser=track(`createUser`,t.createUser,e.namespace),this.updateUser=track(`updateUser`,t.updateUser,e.namespace),this.deleteUser=track(`deleteUser`,t.deleteUser,e.namespace),this.sendPasswordResetEmail=track(`sendPasswordResetEmail`,t.sendPasswordResetEmail,e.namespace),this.unenrollMfa=track(`unenrollMfa`,t.unenrollMfa,e.namespace)},s=I.fn(defaultClient);t.idp={Client:s};function allMocks(){return[...o.values()].flatMap(e=>G.map(t=>e[t]))}return f({Client:s,namespace,setResolver(e){resolver=e},enqueueResult(e){i.push(e)},enqueueResults(...e){i.push(...e)},get calls(){return a},clear(){a.length=0,s.mockClear();for(let e of allMocks())e.mockClear()},reset(){i.length=0,a.length=0,resolver=()=>null,s.mockReset(),s.mockImplementation(defaultClient);for(let e of allMocks())e.mockReset()}},()=>{t.idp=n})}function mockLogger(e={}){let t=p(),n=t.logger,r=I.fn((e,t)=>{}),i=I.fn((e,t)=>{}),a=I.fn((e,t)=>{}),o=I.fn((e,t)=>{}),s=I.fn(e=>{});t.logger={debug:r,info:i,warn:a,error:o,setAttributes:s};let c={debug:r,info:i,warn:a,error:o};return f({debug:r,info:i,warn:a,error:o,setAttributes:s,get calls(){return Object.entries(c).flatMap(([e,t])=>t.mock.calls.map((n,r)=>({order:t.mock.invocationCallOrder[r]??0,call:{severity:e,message:n[0],attributes:n[1]}}))).toSorted((e,t)=>e.order-t.order).map(e=>e.call)},clear(){r.mockClear(),i.mockClear(),a.mockClear(),o.mockClear(),s.mockClear()},reset(){r.mockReset(),i.mockReset(),a.mockReset(),o.mockReset(),s.mockReset()}},()=>{t.logger=n})}function testRegex(e,t){let n=e.lastIndex;e.lastIndex=0;try{return e.test(t)}finally{e.lastIndex=n}}var MockQueryResult=class{command;rowCount;rows;constructor(e){this.command=``,this.rowCount=e.length,this.rows=e}};function mockTailordb(e={}){let t=m(),n=t.Client,r=[],i;function matchesQuery(e,t,n){if(typeof e==`function`)return e(t,n);if(typeof e==`string`)return t===e;if(e instanceof RegExp)return testRegex(e,t);let r;if(r=typeof e.sql==`string`?t===e.sql:testRegex(e.sql,t),!r||e.params===void 0)return r;if(typeof e.params==`function`)return e.params(n);let i=e.params;return n.length===i.length&&n.every((e,t)=>g(e,i[t]))}function queryResponse(e){if(e.type===`error`)throw e.error;return new MockQueryResult(e.rows)}async function defaultQuery(t,n=[]){for(let e=r.length-1;e>=0;--e){let i=r[e];if(!i||!matchesQuery(i.matcher,t,n))continue;let a=i.once.shift();if(a)return queryResponse(a);if(i.fallback)return queryResponse(i.fallback)}if(i)return new MockQueryResult(i(t,n)??[]);if(e.onUnhandled===`error`)throw Error(`No TailorDB query behavior matched: ${t}`);return new MockQueryResult([])}let a=I.fn(defaultQuery),defaultConnect=async()=>{},o=I.fn(defaultConnect),s=[];function enqueueRowsList(e){for(let t of e)a.mockImplementationOnce(async()=>new MockQueryResult(t))}let defaultClient=function(e){let t={namespace:e?.namespace,ended:!1};s.push(t),this.connect=o,this.end=I.fn(async()=>{t.ended=!0}),this.queryObject=a,this.createTransaction=e=>{if(!e)throw Error(`Transaction name must be a non-empty string`);return{begin:async()=>{},commit:async()=>{},rollback:async()=>{},queryObject:a}}},c=I.fn(defaultClient);return t.Client=c,f({Client:c,queryObject:a,setQueryResolver(e){i=e,a.mockImplementation(defaultQuery)},onQuery(e){let t={matcher:e,once:[]};r.push(t);let n={returnsRows(e){return t.fallback={type:`rows`,rows:e},n},returnsRowsOnce(e){return t.once.push({type:`rows`,rows:e}),n},rejects(e){return t.fallback={type:`error`,error:e},n},rejectsOnce(e){return t.once.push({type:`error`,error:e}),n}};return n},enqueueResult(...e){enqueueRowsList([e])},enqueueResults(...e){enqueueRowsList(e)},enqueueRows(...e){enqueueRowsList(e)},get executedQueries(){return a.mock.calls.map(([e,t])=>({query:e,params:t??[]}))},get createdClients(){return s},clear(){a.mockClear(),o.mockClear(),c.mockClear(),s.length=0},reset(){a.mockReset(),a.mockImplementation(defaultQuery),o.mockReset(),o.mockImplementation(defaultConnect),c.mockReset(),c.mockImplementation(defaultClient),s.length=0,r.length=0,i=void 0}},()=>{t.Client=n})}const J=new WeakMap,Y=new WeakMap,X=new WeakMap;function replaceProcedure(e,t,n){let r=X.get(n)??n,i=I.fn(function(...e){return Reflect.apply(r,this,e)});X.set(i,r);let a=e;return a[t]=i,{mock:i,scoped:{mockClear:()=>i.mockClear(),mockReset:()=>i.mockReset(),restore:()=>{a[t]===i&&(a[t]=n)}}}}function replaceStart(e){return replaceProcedure(e,`start`,e.start)}function mockWorkflow(){let e=p(),a=e.workflow,c=r(),l=new Map,u=new Map,m=new Map,h=new Map,g=new Set,installKeyDispatcher=e=>{let t=h.get(e);if(t)return t;let n=i(e);if(!n)throw Error(`waitPointWith expects a wait point definition created by createWaitPoint or createWaitPoints.`);let r=n,a=n.wait,o=n.resolve,s=J.get(a)??a,c=Y.get(o)??o,l={perKey:new Map,originalWait:(e,t)=>s.call(n,e,t),originalResolve:(e,t,r)=>c.call(n,e,t,r)},dispatchWait=(e,t)=>{let n=l.perKey.get(e);return n?t===void 0?n.wait():n.wait(t):l.originalWait(e,t)},dispatchResolve=async(e,t,n)=>{let r=l.perKey.get(e);if(!r)return l.originalResolve(e,t,n);await r.resolve(t,n)};J.set(dispatchWait,s),Y.set(dispatchResolve,c),r.wait=dispatchWait,r.resolve=dispatchResolve;let eachSpy=e=>{for(let t of l.perKey.values()){let n=t;e(n.wait),e(n.resolve)}};return g.add({mockClear:()=>eachSpy(e=>e.mockClear()),mockReset:()=>eachSpy(e=>e.mockReset()),restore:()=>{r.wait=a,r.resolve=o,h.delete(e)}}),h.set(e,l),l},defaultExecJob=(e,t,n)=>{throw Error(`No workflow job mock for "${e}". Call mockWorkflow().setJobHandler(...) or enqueueResult(...), or use runWorkflowLocally() for local workflow execution.`)},defaultStartWorkflow=async(e,n,r)=>t,defaultResumeWorkflowExecution=async e=>e,_=I.fn(defaultExecJob),v=I.fn(defaultStartWorkflow),y=I.fn(defaultResumeWorkflowExecution),b=I.fn((e,t)=>null),x=I.fn(async(e,t,n)=>{});return e.workflow={execJobFunction:(...e)=>{let t=e.length>=3?_(e[0],d(e[1]),e[2]):_(e[0],d(e[1]));return t instanceof Promise?t.then(e=>d(e)):d(t)},startWorkflow:(...e)=>e.length>=3?v(e[0],d(e[1]),e[2]):v(e[0],d(e[1])),resumeWorkflowExecution:e=>y(e),wait:(e,t)=>b(e,d(t)),resolve:(e,t,n)=>x(e,t,e=>{let t=n(e);return t instanceof Promise?t.then(e=>d(e)):d(t)})},f({execJobFunction:_,startWorkflow:v,resumeWorkflowExecution:y,wait:b,resolve:x,job(e){let t=l.get(e);if(t)return t;let{mock:n,scoped:r}=replaceStart(e);return g.add(r),l.set(e,n),n},workflow(e){let t=u.get(e);if(t)return t;let{mock:n,scoped:r}=replaceStart(e);return u.set(e,n),g.add(r),n},waitPoint(e){let t=m.get(e);if(t)return t;let n=replaceProcedure(e,`wait`,e.wait),r=replaceProcedure(e,`resolve`,e.resolve),i=n.mock,a=r.mock;g.add(n.scoped),g.add(r.scoped);let o={wait:i,resolve:a,setResolvePayload(e){a.mockImplementation(async(t,n)=>{let r=await n(d(e));d(r)})}};return m.set(e,o),o},waitPointWith(e,t){let r=n(e.with(t));if(r===void 0)throw Error(`waitPointWith expects a wait point declared with $params. Use waitPoint() for a wait point with a fixed key.`);let i=installKeyDispatcher(e),a=i.perKey.get(r);if(a)return a;let o=I.fn(e=>Promise.resolve(i.originalWait(r,e))),s=I.fn((e,t)=>i.originalResolve(r,e,t)),c={wait:o,resolve:s,setResolvePayload(e){s.mockImplementation(async(t,n)=>{let r=await n(d(e));d(r)})}};return i.perKey.set(r,c),c},setJobHandler(e){_.mockImplementation((t,n,r)=>e(t,n,r))},enqueueResult(e){_.mockImplementationOnce(()=>e)},enqueueResults(...e){for(let t of e)_.mockImplementationOnce(()=>t)},get startedJobs(){return _.mock.calls.map(([e,t,n])=>({jobName:e,args:t,...n!==void 0&&{options:n}}))},setStartHandler(e){v.mockImplementation(typeof e==`function`?async(t,n,r)=>e(t,n,r):async()=>e)},setResumeHandler(e){y.mockImplementation(typeof e==`function`?async t=>e(t):async()=>e)},setWaitHandler:e=>{b.mockImplementation(typeof e==`function`?(t,n)=>e(t,n):()=>e)},setEnv(e){s({...e})},setResolveHandler(e){x.mockImplementation(async(t,n,r)=>{await e(t,n,r)})},get waitCalls(){return b.mock.calls.map(([e,t])=>({key:e,payload:t}))},get resolveCalls(){return x.mock.calls.map(([e,t])=>({executionId:e,key:t}))},clear(){_.mockClear(),v.mockClear(),y.mockClear(),b.mockClear(),x.mockClear();for(let e of g)e.mockClear()},reset(){_.mockReset(),_.mockImplementation(defaultExecJob),v.mockReset(),v.mockImplementation(defaultStartWorkflow),y.mockReset(),y.mockImplementation(defaultResumeWorkflowExecution),b.mockReset(),b.mockImplementation(()=>null),x.mockReset(),x.mockImplementation(async()=>{});for(let e of g)e.mockReset();o()}},()=>{for(let e of g)e.restore();e.workflow=a,c===void 0?o():s(c)})}var PendingStart=class{jobName;args;constructor(e,t){this.jobName=e,this.args=t}};async function runWorkflowLocally(e,t,n){let i=globalThis,a=i.tailor,c=r(),l=c!==void 0,u=createLocalJobRunner();n?.env!==void 0&&s({...n.env}),i.tailor={...a,workflow:createLocalWorkflowRuntime(a?.workflow,u.execJobFunction)};try{return await u.runJob(e.mainJob.name,t)}finally{a?i.tailor=a:delete i.tailor,n?.env!==void 0&&(l?s(c):o())}}function createLocalJobRunner(){let t,execJobFunction=(e,n)=>{if(!t)throw Error(`Cannot start workflow job "${e}" outside runWorkflowLocally() job execution.`);if(t.pending)throw t.pending;let r=d(n),i=t.cursor;t.cursor+=1;let a=t.records[i];if(a){if(assertSameStart(a,e,r),a.status===`rejected`)throw a.error;return d(a.result)}let o=new PendingStart(e,r);throw t.pending=o,o},runJob=async(n,r)=>{let i=e(n);if(!i)return null;let o=[];for(;;){let e={records:o,cursor:0},s=t;t=e;try{let t=await i(d(r),a());if(e.pending){await settlePendingStart(o,e.pending,runJob);continue}if(e.cursor!==o.length)throw Error(`Workflow job start sequence changed while replaying "${n}". Expected ${o.length} start(s), but replay reached ${e.cursor}.`);return d(t)}catch(t){let n=t instanceof PendingStart?t:e.pending;if(n){await settlePendingStart(o,n,runJob);continue}throw t}finally{t=s}}};return{runJob,execJobFunction}}async function settlePendingStart(e,t,n){try{e.push({jobName:t.jobName,args:t.args,status:`fulfilled`,result:await n(t.jobName,t.args)})}catch(n){e.push({jobName:t.jobName,args:t.args,status:`rejected`,error:n})}}function assertSameStart(e,t,n){if(e.jobName!==t||JSON.stringify(e.args)!==JSON.stringify(n))throw Error(`Workflow job start sequence changed while replaying. Expected ${e.jobName}(${JSON.stringify(e.args)}), but got ${t}(${JSON.stringify(n)}).`)}function createLocalWorkflowRuntime(e,n){return{execJobFunction:n,startWorkflow:async(n,r,i)=>e?await e.startWorkflow(n,r,i):(d(r),t),resumeWorkflowExecution:async t=>e?await e.resumeWorkflowExecution(t):t,wait:(t,n)=>{if(e)return e.wait(t,n);throw Error(`No wait handler for "${t}". Acquire mockWorkflow() and call setWaitHandler(...).`)},resolve:async(t,n,r)=>{if(e){await e.resolve(t,n,r);return}throw Error(`No resolve handler. Acquire mockWorkflow() and call setResolveHandler(...).`)}}}function unwrapValue(e){return k.is(e)?e.value:e}function insertRows(e){if(!b.is(e))throw Error(`insertRows: expected InsertQueryNode, got ${e.kind}`);let t=e.columns,n=e.values;if(t===void 0||n===void 0||!A.is(n))throw Error(`insertRows: unsupported insert shape; inspect query.node instead`);return n.values.map(e=>{if(!T.is(e)&&!O.is(e))throw Error(`insertRows: unsupported insert shape; inspect query.node instead`);let n=T.is(e)?e.values:e.values.map(unwrapValue),r={};return t.forEach((e,t)=>{r[e.column.name]=n[t]}),r})}function insertValues(e){let t=insertRows(e);if(t.length!==1)throw Error(`insertValues: query inserts ${t.length} rows; use insertRows() for multi-row inserts`);return c(t[0],`insertValues: first row missing`)}function updateValues(e){if(!D.is(e))throw Error(`updateValues: expected UpdateQueryNode, got ${e.kind}`);if(e.updates===void 0)throw Error(`updateValues: unsupported update shape; inspect query.node instead`);let t={};for(let n of e.updates){let e=n.column,r=v.is(e)?e.column.name:E.is(e)&&v.is(e.column)?e.column.column.name:void 0;if(r===void 0)throw Error(`updateValues: unsupported update shape; inspect query.node instead`);t[r]=unwrapValue(n.value)}return t}function toExecutedQuery(e){let t=e.query;return{kind:t.kind,sql:e.sql,parameters:e.parameters,node:t,insertRows:()=>insertRows(t),insertValues:()=>insertValues(t),updateValues:()=>updateValues(t)}}function toStagedResult(e){return Array.isArray(e)?{rows:e,numAffectedRows:void 0}:{rows:e.rows??[],numAffectedRows:e.numAffectedRows===void 0?void 0:BigInt(e.numAffectedRows)}}var MockState=class{executed=[];queue=[];resolver;enqueue(...e){this.queue.push(...e)}setResolver(e){this.resolver=e}next(e){let t=this.resolver?.(e);if(t!==void 0)return toStagedResult(t);let n=this.queue.shift();return n===void 0?{rows:[],numAffectedRows:void 0}:toStagedResult(n)}reset(){this.executed.length=0,this.queue.length=0,this.resolver=void 0}},MockConnection=class{state;constructor(e){this.state=e}async executeQuery(e){let t=toExecutedQuery(e);this.state.executed.push(t);let{rows:n,numAffectedRows:r}=this.state.next(t);return{rows:n,numAffectedRows:r??BigInt(n.length)}}streamQuery(){throw Error(`createKyselyMock: streaming is not supported`)}},MockDriver=class{state;constructor(e){this.state=e}async init(){}async acquireConnection(){return new MockConnection(this.state)}async beginTransaction(){}async commitTransaction(){}async rollbackTransaction(){}async releaseConnection(){}async destroy(){}};function byKind(e,t){return e.executed.filter(e=>e.kind===t)}function createKyselyMock(){let e=new MockState,t=new x({dialect:{createDriver:()=>new MockDriver(e),createQueryCompiler:()=>new w,createAdapter:()=>new S,createIntrospector:e=>new C(e)}});return{db:t,get executedQueries(){return e.executed},get selects(){return byKind(e,`SelectQueryNode`)},get inserts(){return byKind(e,`InsertQueryNode`)},get updates(){return byKind(e,`UpdateQueryNode`)},get deletes(){return byKind(e,`DeleteQueryNode`)},enqueueResult:t=>e.enqueue(t),enqueueResults:(...t)=>e.enqueue(...t),setQueryResolver:t=>e.setResolver(t),withTx:e=>t.transaction().execute(e),reset:()=>e.reset(),[Symbol.dispose]:()=>e.reset()}}var PGliteConnection=class{#e;constructor(e){this.#e=e}async executeQuery(e){let t=await this.#e.query(e.sql,[...e.parameters]);return{rows:t.rows,numAffectedRows:BigInt(t.affectedRows??0)}}streamQuery(){throw Error(`createKyselyPGlite: streaming is not supported`)}},PGliteDriver=class{#e;constructor(e){this.#e=e}async init(){}async acquireConnection(){return new PGliteConnection(this.#e)}async beginTransaction(e,t){let n=t.isolationLevel?[`start transaction`,`isolation level ${t.isolationLevel}`]:[`begin`];t.accessMode&&n.push(t.accessMode),await e.executeQuery(y.raw(n.join(` `)))}async commitTransaction(e){await e.executeQuery(y.raw(`commit`))}async rollbackTransaction(e){await e.executeQuery(y.raw(`rollback`))}async releaseConnection(){}async destroy(){await this.#e.close()}};function createKyselyPGlite(e){return new x({dialect:{createAdapter:()=>new S,createDriver:()=>new PGliteDriver(e),createIntrospector:e=>new C(e),createQueryCompiler:()=>new w}})}function tailorRuntime(e){return[createBlockPlugin(),createEnvironmentPlugin(e)]}export{createKyselyMock,createKyselyPGlite,mockAigateway,mockAuthconnection,mockFile,mockIconv,mockIdp,mockLogger,h as mockSecretmanager,mockTailordb,mockWorkflow,runWorkflowLocally,tailorRuntime};
1987
2
  //# sourceMappingURL=index.mjs.map