@tailor-platform/sdk 1.76.0 → 1.76.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/application-6zsDLGKv.mjs +3 -0
  3. package/dist/{application-BUfYmf0O.mjs → application-CqjCcZ2n.mjs} +372 -1673
  4. package/dist/application-CqjCcZ2n.mjs.map +1 -0
  5. package/dist/cli/cache/bundle-cache.d.mts +2 -1
  6. package/dist/cli/cache/store.d.mts +1 -1
  7. package/dist/cli/commands/api/index.d.mts +1 -0
  8. package/dist/cli/commands/deploy/aigateway.d.mts +5 -1
  9. package/dist/cli/commands/deploy/application.d.mts +7 -1
  10. package/dist/cli/commands/deploy/apply-phases.d.mts +14 -1
  11. package/dist/cli/commands/deploy/auth.d.mts +5 -1
  12. package/dist/cli/commands/deploy/deploy.d.mts +5 -0
  13. package/dist/cli/commands/deploy/executor.d.mts +7 -1
  14. package/dist/cli/commands/deploy/function-registry.d.mts +5 -0
  15. package/dist/cli/commands/deploy/idp.d.mts +5 -1
  16. package/dist/cli/commands/deploy/resolver.d.mts +5 -1
  17. package/dist/cli/commands/deploy/secret-manager.d.mts +5 -1
  18. package/dist/cli/commands/deploy/staticwebsite.d.mts +5 -1
  19. package/dist/cli/commands/deploy/tailordb/index.d.mts +8 -1
  20. package/dist/cli/commands/deploy/types.d.mts +3 -1
  21. package/dist/cli/commands/deploy/workflow-execution-policy.d.mts +3 -1
  22. package/dist/cli/commands/deploy/workflow.d.mts +4 -1
  23. package/dist/cli/commands/executor/get.d.mts +0 -1
  24. package/dist/cli/commands/executor/jobs.d.mts +0 -1
  25. package/dist/cli/commands/executor/list.d.mts +0 -1
  26. package/dist/cli/commands/executor/transform.d.mts +1 -0
  27. package/dist/cli/commands/executor/trigger.d.mts +0 -1
  28. package/dist/cli/commands/executor/webhook.d.mts +0 -1
  29. package/dist/cli/commands/function/get.d.mts +0 -1
  30. package/dist/cli/commands/function/list.d.mts +0 -1
  31. package/dist/cli/commands/function/transform.d.mts +1 -0
  32. package/dist/cli/commands/generate/service.d.mts +5 -1
  33. package/dist/cli/commands/generate/types.d.mts +3 -1
  34. package/dist/cli/commands/machineuser/list.d.mts +0 -1
  35. package/dist/cli/commands/machineuser/token.d.mts +0 -1
  36. package/dist/cli/commands/oauth2client/get.d.mts +0 -1
  37. package/dist/cli/commands/oauth2client/list.d.mts +0 -1
  38. package/dist/cli/commands/oauth2client/transform.d.mts +1 -0
  39. package/dist/cli/commands/organization/folder/create.d.mts +0 -1
  40. package/dist/cli/commands/organization/folder/delete.d.mts +0 -1
  41. package/dist/cli/commands/organization/folder/get.d.mts +0 -1
  42. package/dist/cli/commands/organization/folder/list.d.mts +0 -1
  43. package/dist/cli/commands/organization/folder/update.d.mts +0 -1
  44. package/dist/cli/commands/organization/get.d.mts +0 -1
  45. package/dist/cli/commands/organization/list.d.mts +0 -1
  46. package/dist/cli/commands/organization/transform.d.mts +2 -0
  47. package/dist/cli/commands/organization/tree.d.mts +0 -1
  48. package/dist/cli/commands/organization/update.d.mts +0 -1
  49. package/dist/cli/commands/remove.d.mts +0 -1
  50. package/dist/cli/commands/show.d.mts +0 -1
  51. package/dist/cli/commands/tailordb/migrate/config.d.mts +0 -1
  52. package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +0 -1
  53. package/dist/cli/commands/tailordb/migrate/generate.d.mts +0 -1
  54. package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +1 -1
  55. package/dist/cli/commands/tailordb/truncate.d.mts +0 -1
  56. package/dist/cli/commands/workflow/executions.d.mts +0 -1
  57. package/dist/cli/commands/workflow/get.d.mts +2 -1
  58. package/dist/cli/commands/workflow/list.d.mts +0 -1
  59. package/dist/cli/commands/workflow/resume.d.mts +0 -1
  60. package/dist/cli/commands/workflow/start.d.mts +0 -1
  61. package/dist/cli/commands/workflow/status.d.mts +1 -0
  62. package/dist/cli/commands/workflow/transform.d.mts +1 -0
  63. package/dist/cli/commands/workflow/wait.d.mts +0 -1
  64. package/dist/cli/commands/workflow/waiter.d.mts +1 -1
  65. package/dist/cli/commands/workspace/app/health.d.mts +0 -1
  66. package/dist/cli/commands/workspace/app/list.d.mts +0 -1
  67. package/dist/cli/commands/workspace/app/transform.d.mts +2 -0
  68. package/dist/cli/commands/workspace/create.d.mts +0 -1
  69. package/dist/cli/commands/workspace/delete.d.mts +0 -1
  70. package/dist/cli/commands/workspace/get.d.mts +0 -1
  71. package/dist/cli/commands/workspace/list.d.mts +0 -1
  72. package/dist/cli/commands/workspace/restore.d.mts +0 -1
  73. package/dist/cli/commands/workspace/transform.d.mts +2 -0
  74. package/dist/cli/commands/workspace/user/invite.d.mts +0 -1
  75. package/dist/cli/commands/workspace/user/list.d.mts +0 -1
  76. package/dist/cli/commands/workspace/user/remove.d.mts +0 -1
  77. package/dist/cli/commands/workspace/user/transform.d.mts +1 -0
  78. package/dist/cli/commands/workspace/user/update.d.mts +0 -1
  79. package/dist/cli/index.d.mts +3 -1
  80. package/dist/cli/index.mjs +599 -42
  81. package/dist/cli/index.mjs.map +1 -1
  82. package/dist/cli/lib.d.mts +2 -0
  83. package/dist/cli/lib.mjs +3 -3
  84. package/dist/cli/query/index.d.mts +0 -1
  85. package/dist/cli/services/application.d.mts +12 -1
  86. package/dist/cli/services/auth/service.d.mts +2 -0
  87. package/dist/cli/services/executor/service.d.mts +1 -1
  88. package/dist/cli/services/http-adapter/bundler.d.mts +3 -1
  89. package/dist/cli/services/http-adapter/service.d.mts +2 -1
  90. package/dist/cli/services/resolver/service.d.mts +1 -1
  91. package/dist/cli/services/tailordb/service.d.mts +3 -1
  92. package/dist/cli/services/workflow/bundler.d.mts +2 -1
  93. package/dist/cli/services/workflow/service.d.mts +1 -1
  94. package/dist/cli/shared/args.d.mts +1 -1
  95. package/dist/cli/shared/client.d.mts +1 -1
  96. package/dist/cli/shared/config-loader.d.mts +0 -1
  97. package/dist/cli/shared/context.d.mts +2 -1
  98. package/dist/cli/shared/script-executor.d.mts +0 -1
  99. package/dist/cli/shared/seed-chunker.d.mts +7 -3
  100. package/dist/cli/shared/type-generator.d.mts +0 -1
  101. package/dist/completion/zsh-worker.zsh +1 -1
  102. package/dist/configure/config/index.d.mts +0 -1
  103. package/dist/configure/config/types.d.mts +2 -2
  104. package/dist/configure/index.d.mts +2 -1
  105. package/dist/configure/index.mjs +54 -4
  106. package/dist/configure/index.mjs.map +1 -1
  107. package/dist/configure/services/aigateway/index.d.mts +0 -1
  108. package/dist/configure/services/aigateway/types.d.mts +0 -1
  109. package/dist/configure/services/auth/index.d.mts +0 -1
  110. package/dist/configure/services/auth/types.d.mts +14 -13
  111. package/dist/configure/services/executor/executor.d.mts +0 -1
  112. package/dist/configure/services/executor/index.d.mts +1 -0
  113. package/dist/configure/services/executor/operation.d.mts +1 -2
  114. package/dist/configure/services/executor/trigger/event.d.mts +0 -1
  115. package/dist/configure/services/executor/trigger/index.d.mts +0 -1
  116. package/dist/configure/services/executor/trigger/schedule.d.mts +0 -1
  117. package/dist/configure/services/executor/trigger/webhook.d.mts +0 -1
  118. package/dist/configure/services/http-adapter/http-adapter.d.mts +1 -2
  119. package/dist/configure/services/idp/index.d.mts +0 -1
  120. package/dist/configure/services/idp/permission.d.mts +4 -5
  121. package/dist/configure/services/idp/types.d.mts +0 -1
  122. package/dist/configure/services/index.d.mts +5 -0
  123. package/dist/configure/services/resolver/resolver.d.mts +0 -1
  124. package/dist/configure/services/resolver/types.d.mts +0 -1
  125. package/dist/configure/services/secrets/index.d.mts +0 -1
  126. package/dist/configure/services/secrets/types.d.mts +0 -1
  127. package/dist/configure/services/staticwebsite/index.d.mts +0 -1
  128. package/dist/configure/services/staticwebsite/types.d.mts +0 -1
  129. package/dist/configure/services/tailordb/permission.d.mts +4 -5
  130. package/dist/configure/services/tailordb/schema.d.mts +24 -14
  131. package/dist/configure/services/tailordb/types.d.mts +4 -5
  132. package/dist/configure/services/workflow/execution-policy.d.mts +0 -1
  133. package/dist/configure/services/workflow/execution-policy.types.d.mts +0 -1
  134. package/dist/configure/services/workflow/index.d.mts +1 -0
  135. package/dist/configure/services/workflow/job.d.mts +0 -1
  136. package/dist/configure/services/workflow/wait-point.d.mts +0 -1
  137. package/dist/configure/services/workflow/workflow.d.mts +0 -1
  138. package/dist/configure/types/field-runtime.d.mts +1 -1
  139. package/dist/configure/types/field.d.mts +1 -2
  140. package/dist/configure/types/field.types.d.mts +1 -2
  141. package/dist/configure/types/type.d.mts +1 -1
  142. package/dist/configure/user.d.mts +0 -1
  143. package/dist/{crashreport-ayWANEZ6.mjs → crashreport-DZDr-TvH.mjs} +3 -2
  144. package/dist/{crashreport-ayWANEZ6.mjs.map → crashreport-DZDr-TvH.mjs.map} +1 -1
  145. package/dist/{crashreport-Dy4ZzSkd.mjs → crashreport-np4-_DX2.mjs} +1 -1
  146. package/dist/{field-runtime-9bfXBAOK.mjs → field-runtime-D4QWRiB1.mjs} +66 -46
  147. package/dist/field-runtime-D4QWRiB1.mjs.map +1 -0
  148. package/dist/{globals-CcU1ONiK.mjs → globals-z6zYMjlr.mjs} +2 -2
  149. package/dist/{globals-CcU1ONiK.mjs.map → globals-z6zYMjlr.mjs.map} +1 -1
  150. package/dist/kysely/index.d.mts +3 -4
  151. package/dist/parser/service/auth/index.d.mts +1 -1
  152. package/dist/parser/service/auth/schema.d.mts +1 -0
  153. package/dist/parser/service/http-adapter/index.d.mts +1 -1
  154. package/dist/parser/service/idp/types.d.mts +1 -0
  155. package/dist/parser/service/tailordb/types.d.mts +0 -1
  156. package/dist/plugin/builtin/enum-constants/index.d.mts +0 -1
  157. package/dist/plugin/builtin/file-utils/index.d.mts +0 -1
  158. package/dist/plugin/builtin/kysely-type/index.d.mts +0 -1
  159. package/dist/plugin/builtin/seed/index.d.mts +0 -1
  160. package/dist/plugin/builtin/seed/index.mjs +1 -1
  161. package/dist/plugin/get-generated-type.d.mts +0 -1
  162. package/dist/plugin/manager.d.mts +3 -1
  163. package/dist/plugin/types.d.mts +0 -1
  164. package/dist/plugin/with-context.d.mts +0 -1
  165. package/dist/{registry-NfSW0BRo.mjs → registry-CTgoVWc_.mjs} +4 -49
  166. package/dist/registry-CTgoVWc_.mjs.map +1 -0
  167. package/dist/runtime/aigateway.d.mts +0 -2
  168. package/dist/runtime/authconnection.d.mts +0 -2
  169. package/dist/runtime/globals.d.mts +0 -1
  170. package/dist/runtime/index.d.mts +0 -1
  171. package/dist/runtime/types.d.mts +16 -7
  172. package/dist/{runtime-_vUgjiqT.mjs → runtime-DlklyuHN.mjs} +1301 -716
  173. package/dist/runtime-DlklyuHN.mjs.map +1 -0
  174. package/dist/{schema-DrVyN-LP.mjs → schema-DbTR1c6M.mjs} +3 -2
  175. package/dist/schema-DbTR1c6M.mjs.map +1 -0
  176. package/dist/{secret-file-VSVGy1V0.mjs → secret-file-DBqZhjFQ.mjs} +2 -27
  177. package/dist/{secret-file-VSVGy1V0.mjs.map → secret-file-DBqZhjFQ.mjs.map} +1 -1
  178. package/dist/seed/index.d.mts +3 -2
  179. package/dist/{seed-fm0LeYP2.mjs → seed-DFFigL8V.mjs} +3 -13
  180. package/dist/seed-DFFigL8V.mjs.map +1 -0
  181. package/dist/service_pb-BoLM0X4K.mjs +167 -0
  182. package/dist/service_pb-BoLM0X4K.mjs.map +1 -0
  183. package/dist/{service_pb-B2FF59sP.mjs → service_pb-r1T7kpJc.mjs} +1 -1
  184. package/dist/tailor-proto/src/tailor/v1/aigateway_pb.d.mts +0 -1
  185. package/dist/tailor-proto/src/tailor/v1/aigateway_resource_pb.d.mts +0 -1
  186. package/dist/tailor-proto/src/tailor/v1/application_pb.d.mts +0 -1
  187. package/dist/tailor-proto/src/tailor/v1/application_resource_pb.d.mts +0 -1
  188. package/dist/tailor-proto/src/tailor/v1/auth_pb.d.mts +0 -1
  189. package/dist/tailor-proto/src/tailor/v1/auth_resource_pb.d.mts +0 -1
  190. package/dist/tailor-proto/src/tailor/v1/events_pb.d.mts +0 -1
  191. package/dist/tailor-proto/src/tailor/v1/events_resource_pb.d.mts +0 -1
  192. package/dist/tailor-proto/src/tailor/v1/executor_pb.d.mts +0 -1
  193. package/dist/tailor-proto/src/tailor/v1/executor_resource_pb.d.mts +0 -1
  194. package/dist/tailor-proto/src/tailor/v1/function_pb.d.mts +0 -1
  195. package/dist/tailor-proto/src/tailor/v1/function_registry_pb.d.mts +0 -1
  196. package/dist/tailor-proto/src/tailor/v1/function_resource_pb.d.mts +0 -1
  197. package/dist/tailor-proto/src/tailor/v1/http_adapter_resource_pb.d.mts +0 -1
  198. package/dist/tailor-proto/src/tailor/v1/idp_pb.d.mts +0 -1
  199. package/dist/tailor-proto/src/tailor/v1/idp_resource_pb.d.mts +0 -1
  200. package/dist/tailor-proto/src/tailor/v1/metadata_pb.d.mts +0 -1
  201. package/dist/tailor-proto/src/tailor/v1/metadata_resource_pb.d.mts +0 -1
  202. package/dist/tailor-proto/src/tailor/v1/meter_pb.d.mts +0 -1
  203. package/dist/tailor-proto/src/tailor/v1/pipeline_pb.d.mts +0 -1
  204. package/dist/tailor-proto/src/tailor/v1/pipeline_resource_pb.d.mts +0 -1
  205. package/dist/tailor-proto/src/tailor/v1/resource_pb.d.mts +0 -1
  206. package/dist/tailor-proto/src/tailor/v1/secret_manager_pb.d.mts +0 -1
  207. package/dist/tailor-proto/src/tailor/v1/secret_manager_resource_pb.d.mts +0 -1
  208. package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +0 -1
  209. package/dist/tailor-proto/src/tailor/v1/stateflow_pb.d.mts +0 -1
  210. package/dist/tailor-proto/src/tailor/v1/stateflow_resource_pb.d.mts +0 -1
  211. package/dist/tailor-proto/src/tailor/v1/staticwebsite_pb.d.mts +0 -1
  212. package/dist/tailor-proto/src/tailor/v1/staticwebsite_resource_pb.d.mts +0 -1
  213. package/dist/tailor-proto/src/tailor/v1/tailordb_pb.d.mts +0 -1
  214. package/dist/tailor-proto/src/tailor/v1/tailordb_resource_pb.d.mts +0 -1
  215. package/dist/tailor-proto/src/tailor/v1/telemetryrouter_pb.d.mts +0 -1
  216. package/dist/tailor-proto/src/tailor/v1/telemetryrouter_resource_pb.d.mts +0 -1
  217. package/dist/tailor-proto/src/tailor/v1/workflow_pb.d.mts +0 -1
  218. package/dist/tailor-proto/src/tailor/v1/workflow_resource_pb.d.mts +0 -1
  219. package/dist/tailor-proto/src/tailor/v1/workspace_pb.d.mts +0 -1
  220. package/dist/tailor-proto/src/tailor/v1/workspace_resource_pb.d.mts +0 -1
  221. package/dist/test-env-key-IPapa1KJ.mjs +49 -0
  222. package/dist/test-env-key-IPapa1KJ.mjs.map +1 -0
  223. package/dist/type-source-DH_LH20p.mjs +13 -0
  224. package/dist/type-source-DH_LH20p.mjs.map +1 -0
  225. package/dist/types/aigateway.generated.d.mts +5 -2
  226. package/dist/types/auth-connection.generated.d.mts +11 -5
  227. package/dist/types/auth.generated.d.mts +111 -51
  228. package/dist/types/executor.generated.d.mts +59 -27
  229. package/dist/types/helpers.d.mts +5 -5
  230. package/dist/types/http-adapter.generated.d.mts +11 -5
  231. package/dist/types/idp.generated.d.mts +20 -9
  232. package/dist/types/resolver.generated.d.mts +19 -9
  233. package/dist/types/staticwebsite.generated.d.mts +7 -3
  234. package/dist/types/tailordb.generated.d.mts +47 -22
  235. package/dist/types/workflow.generated.d.mts +9 -4
  236. package/dist/{types-BwzB2okW.mjs → types-BzJ7A_fn.mjs} +2 -2
  237. package/dist/{types-BwzB2okW.mjs.map → types-BzJ7A_fn.mjs.map} +1 -1
  238. package/dist/types-CG9H7HuE.mjs +4 -0
  239. package/dist/user-agent-DX2Jnw0-.mjs +28 -0
  240. package/dist/user-agent-DX2Jnw0-.mjs.map +1 -0
  241. package/dist/utils/test/index.d.mts +0 -1
  242. package/dist/utils/test/index.mjs +1 -1
  243. package/dist/utils/test/mock.d.mts +0 -1
  244. package/dist/vitest/environment.mjs +1 -1
  245. package/dist/vitest/index.d.mts +1 -1
  246. package/dist/vitest/index.mjs +2 -1
  247. package/dist/vitest/index.mjs.map +1 -1
  248. package/dist/vitest/mock-kysely.d.mts +0 -1
  249. package/dist/vitest/mocks/aigateway.d.mts +2 -2
  250. package/dist/vitest/mocks/authconnection.d.mts +2 -2
  251. package/dist/vitest/mocks/idp.d.mts +2 -2
  252. package/dist/vitest/mocks/secretmanager.d.mts +3 -1
  253. package/dist/vitest/mocks/tailordb.d.mts +6 -3
  254. package/dist/vitest/mocks/workflow.d.mts +11 -6
  255. package/dist/vitest/setup.mjs +1 -1
  256. package/dist/{service_pb-B5w9rjPY.mjs → workspace_resource_pb-Db3fv68L.mjs} +57 -165
  257. package/dist/workspace_resource_pb-Db3fv68L.mjs.map +1 -0
  258. package/docs/services/tailordb.md +10 -1
  259. package/package.json +18 -18
  260. package/dist/application-BUfYmf0O.mjs.map +0 -1
  261. package/dist/application-DbvD5UUz.mjs +0 -3
  262. package/dist/cli/shared/trigger-context.d.mts +0 -1
  263. package/dist/field-runtime-9bfXBAOK.mjs.map +0 -1
  264. package/dist/job-D-PbD1P3.mjs +0 -55
  265. package/dist/job-D-PbD1P3.mjs.map +0 -1
  266. package/dist/registry-NfSW0BRo.mjs.map +0 -1
  267. package/dist/resource_pb-BRv7AMXK.mjs +0 -49
  268. package/dist/resource_pb-BRv7AMXK.mjs.map +0 -1
  269. package/dist/runtime-_vUgjiqT.mjs.map +0 -1
  270. package/dist/schema-DrVyN-LP.mjs.map +0 -1
  271. package/dist/seed-fm0LeYP2.mjs.map +0 -1
  272. package/dist/service_pb-B5w9rjPY.mjs.map +0 -1
  273. package/dist/types-KlawuVKa.mjs +0 -4
@@ -1,32 +1,20 @@
1
1
  import { n as isSdkBranded } from "./brand-Eo4pLXPJ.mjs";
2
- import { i as PageDirection } from "./resource_pb-BRv7AMXK.mjs";
3
2
  import { t as assertDefined } from "./assert-DBxo8jPo.mjs";
4
3
  import { a as parseBoolean, n as logger, r as styles } from "./logger-BEiZZ3qT.mjs";
5
4
  import { a as TailorFieldSchema, i as AuthInvokerSchema, n as ExecutorSchema, o as loadFilesWithIgnores, r as AuthConfigSchema, s as functionSchema, t as createExecutorService } from "./service-BCRJ-3NV.mjs";
6
- import { n as enumConstantsPlugin, t as EnumConstantsGeneratorID } from "./enum-constants-j9QBF0cB.mjs";
7
5
  import { t as multiline } from "./multiline-sfHpTZZK.mjs";
8
- import { n as fileUtilsPlugin, t as FileUtilsGeneratorID } from "./file-utils-DcyIPFQh.mjs";
9
- import { n as kyselyTypePlugin, t as KyselyGeneratorID } from "./kysely-type-D-zflMGf.mjs";
10
- import { n as seedPlugin, r as isPluginGeneratedType, t as SeedGeneratorID } from "./seed-fm0LeYP2.mjs";
11
- import { t as readPackageJson } from "./package-json-8b0O9TlX.mjs";
12
- import { i as userAgent, n as tightenSecretFilePermissions, r as writeSecretFile } from "./secret-file-VSVGy1V0.mjs";
13
- import { t as createCLIError } from "./errors-Dtf2WPaW.mjs";
6
+ import { t as isPluginGeneratedType } from "./type-source-DH_LH20p.mjs";
7
+ import { t as userAgent } from "./user-agent-DX2Jnw0-.mjs";
14
8
  import { builtinModules, createRequire } from "node:module";
15
- import { arg } from "politty";
16
9
  import { z } from "zod";
17
10
  import { create } from "@bufbuild/protobuf";
18
11
  import * as fs$1 from "node:fs";
19
12
  import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
20
- import { parseEnv } from "node:util";
21
13
  import { MethodOptions_IdempotencyLevel } from "@bufbuild/protobuf/wkt";
22
14
  import * as path from "pathe";
23
15
  import { join, resolve } from "pathe";
24
16
  import { pathToFileURL } from "node:url";
25
17
  import * as os from "node:os";
26
- import { parseTOML, parseYAML, stringifyYAML } from "confbox";
27
- import { findUpSync } from "find-up-simple";
28
- import { lt } from "semver";
29
- import { xdgConfig } from "xdg-basedir";
30
18
  import { OAuth2Client } from "@badgateway/oauth2-client";
31
19
  import { Code, ConnectError, createClient } from "@connectrpc/connect";
32
20
  import { getGlobalDispatcher } from "undici";
@@ -39,256 +27,6 @@ import { parseSync } from "oxc-parser";
39
27
  import * as inflection from "inflection";
40
28
  import * as globals from "globals";
41
29
 
42
- //#region src/cli/shared/args.ts
43
- const unitToMs = {
44
- ms: 1,
45
- s: 1e3,
46
- m: 60 * 1e3
47
- };
48
- const durationPattern = /^(\d+)(ms|s|m)$/;
49
- /**
50
- * Schema for duration string validation (e.g., "3s", "500ms", "1m")
51
- * Only validates format; use parseDuration() to convert to milliseconds
52
- */
53
- const durationArg = z.string().refine((val) => durationPattern.test(val), { message: "Invalid duration format. Expected format: '3s', '500ms', '1m'" }).refine((val) => {
54
- const match = val.match(durationPattern);
55
- if (!match) return false;
56
- const digits = match[1];
57
- return digits !== void 0 && parseInt(digits, 10) > 0;
58
- }, { message: "Duration must be greater than 0" });
59
- /**
60
- * Parse a validated duration string into milliseconds
61
- * @param duration - Duration string (e.g., "3s", "500ms", "1m")
62
- * @returns Duration in milliseconds
63
- */
64
- function parseDuration(duration) {
65
- const match = assertDefined(duration.match(durationPattern), `invalid duration format: ${duration}`);
66
- const value = parseInt(assertDefined(match[1], "duration digits group missing"), 10);
67
- const unit = assertDefined(match[2], "duration unit group missing");
68
- return value * unitToMs[unit];
69
- }
70
- /**
71
- * Schema for positive integer validation (from string input)
72
- * Transforms the string to a number
73
- */
74
- const positiveIntArg = z.coerce.number().int().positive();
75
- /**
76
- * Schema for non-negative integer validation (from string input).
77
- * Accepts 0 (used for `--limit 0` to disable the limit).
78
- */
79
- const nonNegativeIntArg = z.coerce.number().int().nonnegative();
80
- /**
81
- * Schema for sort order (`asc` or `desc`).
82
- */
83
- const orderArg = z.enum(["asc", "desc"]);
84
- /**
85
- * Translate a CLI `--order` value into the proto `PageDirection` enum.
86
- * Returns `undefined` when the user did not specify an order so that
87
- * callers can omit the field and fall back to the server default.
88
- * @param order - Order string from CLI args (`"asc"` | `"desc"` | undefined)
89
- * @returns PageDirection, or undefined when `order` is undefined
90
- */
91
- function toPageDirection(order) {
92
- if (order === void 0) return void 0;
93
- return order === "asc" ? PageDirection.ASC : PageDirection.DESC;
94
- }
95
- function hasMachineUserFlag(argv) {
96
- return argv.slice(0, argv.indexOf("--") === -1 ? argv.length : argv.indexOf("--")).some((token) => token === "-m" || token.startsWith("-m=") || token === "--machine-user" || token.startsWith("--machine-user=") || token === "--machineUser" || token.startsWith("--machineUser=") || token === "--machineuser" || token.startsWith("--machineuser="));
97
- }
98
- /**
99
- * Resolve whether a parsed machine user value came from an explicit CLI option or env fallback.
100
- * @param machineUser - Parsed machine user value
101
- * @param argv - Raw CLI argv, excluding the executable and script path
102
- * @param options - Source resolution options
103
- * @returns Machine user input source, or undefined when no value was parsed
104
- */
105
- function resolveMachineUserInputSource(machineUser, argv = process.argv.slice(2), options = {}) {
106
- if (machineUser === void 0) return void 0;
107
- if (options.valueIsExplicit) return "option";
108
- if (hasMachineUserFlag(argv)) return "option";
109
- return process.env.TAILOR_PLATFORM_MACHINE_USER_NAME === machineUser ? "env" : "option";
110
- }
111
- /**
112
- * Load env files from parsed arguments.
113
- * Processes --env-file first, then --env-file-if-exists.
114
- *
115
- * Follows Node.js --env-file behavior:
116
- * - Variables already set in the environment are NOT overwritten
117
- * - Variables from later files override those from earlier files
118
- * @param envFiles - Required env file path(s) that must exist
119
- * @param envFilesIfExists - Optional env file path(s) that are loaded if they exist
120
- */
121
- function loadEnvFiles(envFiles, envFilesIfExists) {
122
- const originalEnvKeys = new Set(Object.keys(process.env));
123
- const load = (files, required) => {
124
- for (const file of [files ?? []].flat()) {
125
- const envPath = path.resolve(process.cwd(), file);
126
- if (!fs$1.existsSync(envPath)) {
127
- if (required) throw new Error(`Environment file not found: ${envPath}`);
128
- continue;
129
- }
130
- const parsed = parseEnv(fs$1.readFileSync(envPath, "utf-8"));
131
- for (const [key, value] of Object.entries(parsed)) {
132
- if (originalEnvKeys.has(key)) continue;
133
- process.env[key] = value;
134
- }
135
- }
136
- };
137
- load(envFiles, true);
138
- load(envFilesIfExists, false);
139
- }
140
- /**
141
- * Common arguments for all CLI commands
142
- *
143
- * NOTE: --env-file and --env-file-if-exists collide with Node.js flags due to a bug
144
- * (https://github.com/nodejs/node/issues/54232). Node.js parses these even after the
145
- * script path, causing warnings (twice due to tsx loader).
146
- */
147
- const commonArgs = {
148
- "env-file": arg(z.string().optional(), {
149
- alias: "e",
150
- description: "Path to the environment file (error if not found)",
151
- completion: {
152
- type: "file",
153
- matcher: [".env.*", ".env"]
154
- }
155
- }),
156
- "env-file-if-exists": arg(z.string().optional(), {
157
- description: "Path to the environment file (ignored if not found)",
158
- completion: {
159
- type: "file",
160
- matcher: [".env.*", ".env"]
161
- },
162
- effect: (_value, { args }) => {
163
- loadEnvFiles(args["env-file"], args["env-file-if-exists"]);
164
- }
165
- }),
166
- verbose: arg(z.boolean().default(false), {
167
- description: "Enable verbose logging",
168
- effect: (value) => {
169
- verboseMode = value;
170
- }
171
- }),
172
- json: arg(z.boolean().default(false), {
173
- alias: "j",
174
- description: "Output as JSON",
175
- effect: (value) => {
176
- logger.jsonMode = value;
177
- }
178
- })
179
- };
180
- /**
181
- * Arguments for commands that require workspace context
182
- */
183
- const workspaceArgs = {
184
- "workspace-id": arg(z.string().optional(), {
185
- alias: "w",
186
- description: "Workspace ID",
187
- env: "TAILOR_PLATFORM_WORKSPACE_ID",
188
- completion: { type: "none" }
189
- }),
190
- profile: arg(z.string().optional(), {
191
- alias: "p",
192
- description: "Workspace profile",
193
- env: "TAILOR_PLATFORM_PROFILE",
194
- completion: { type: "none" }
195
- })
196
- };
197
- /**
198
- * Shared config arg for commands that accept a config file path
199
- */
200
- const configArg = { config: arg(z.string().default("tailor.config.ts"), {
201
- alias: "c",
202
- description: "Path to SDK config file",
203
- env: "TAILOR_PLATFORM_SDK_CONFIG_PATH",
204
- completion: {
205
- type: "file",
206
- extensions: ["ts"]
207
- }
208
- }) };
209
- /**
210
- * Shared config arg for commands that accept one or more comma-separated config file paths
211
- */
212
- const multiConfigArg = { config: arg(z.string().default("tailor.config.ts"), {
213
- alias: "c",
214
- description: "Path to SDK config file. Use comma-separated paths to deploy multiple apps together.",
215
- env: "TAILOR_PLATFORM_SDK_CONFIG_PATH",
216
- completion: {
217
- type: "file",
218
- extensions: ["ts"]
219
- }
220
- }) };
221
- /**
222
- * Arguments for commands that interact with deployed resources (includes config)
223
- */
224
- const deploymentArgs = {
225
- ...workspaceArgs,
226
- ...configArg
227
- };
228
- /**
229
- * Arguments for commands that require confirmation
230
- */
231
- const confirmationArgs = { yes: arg(z.boolean().default(false), {
232
- alias: "y",
233
- description: "Skip confirmation prompts"
234
- }) };
235
- /**
236
- * Arguments for commands that require organization context
237
- */
238
- const organizationArgs = { "organization-id": arg(z.string(), {
239
- alias: "o",
240
- description: "Organization ID",
241
- env: "TAILOR_PLATFORM_ORGANIZATION_ID",
242
- completion: { type: "none" }
243
- }) };
244
- /**
245
- * Arguments for list commands that accept `--order` / `--limit`. Sort
246
- * order defaults to `desc` (newest first) because most callers want the
247
- * latest items; pass `--order asc` to opt in to ascending order. The
248
- * limit is unbounded by default so existing invocations keep returning
249
- * every item; pass `--limit N` to cap the result size.
250
- * @param defaultOrder - Default value for `--order` (defaults to `"desc"`)
251
- * @returns Argument shape suitable for spreading into a command schema
252
- */
253
- const paginationArgs = (defaultOrder = "desc") => ({
254
- order: arg(orderArg.default(defaultOrder), { description: "Sort order (asc or desc)" }),
255
- limit: arg(nonNegativeIntArg.optional(), {
256
- alias: "l",
257
- description: "Maximum number of items to return (0 or omit: unlimited)"
258
- })
259
- });
260
- /**
261
- * Arguments for time-series log list commands. Defaults to newest-first
262
- * (`desc`) and a 50-item cap so that listing stays responsive on busy
263
- * workspaces. Pass `--limit 0` to disable the cap and fetch all entries.
264
- */
265
- const pagedLogArgs = {
266
- order: arg(orderArg.default("desc"), { description: "Sort order (asc or desc)" }),
267
- limit: arg(nonNegativeIntArg.default(50), {
268
- alias: "l",
269
- description: "Maximum number of items to return (0: unlimited)"
270
- })
271
- };
272
- /**
273
- * Arguments for commands that require folder context
274
- */
275
- const folderArgs = { "folder-id": arg(z.string(), {
276
- alias: "f",
277
- description: "Folder ID",
278
- env: "TAILOR_PLATFORM_FOLDER_ID",
279
- completion: { type: "none" }
280
- }) };
281
- let verboseMode = false;
282
- /**
283
- * Returns whether verbose mode is enabled.
284
- * Used by the global cleanup handler which doesn't have access to parsed args.
285
- * @returns Whether verbose mode is enabled
286
- */
287
- function isVerbose() {
288
- return verboseMode;
289
- }
290
-
291
- //#endregion
292
30
  //#region src/parser/app-config/log-level.ts
293
31
  const LOG_LEVELS = [
294
32
  "DEBUG",
@@ -301,110 +39,6 @@ function isLogLevel(value) {
301
39
  return LOG_LEVELS.includes(value);
302
40
  }
303
41
 
304
- //#endregion
305
- //#region src/parser/app-config/schema.ts
306
- const envValueSchema = z.union([
307
- z.string(),
308
- z.number(),
309
- z.boolean()
310
- ]);
311
- const LogLevelSchema = z.enum(LOG_LEVELS);
312
- const logLevelSchema = z.string().refine((value) => LogLevelSchema.safeParse(value.trim().toUpperCase()).success, { message: `'logLevel' must be one of: ${LOG_LEVELS.join(", ")}.` });
313
- /**
314
- * Structural validation schema for `defineConfig({...})`. Validates only
315
- * top-level fields with platform-side constraints (notably `id`); fields
316
- * that carry SDK builder objects (`auth`, `idp`, `db`, ...) are accepted
317
- * as opaque values, since their internal shapes are validated by their
318
- * own factory functions and parser-level schemas.
319
- *
320
- * The `id` is auto-managed by `deploy` and stored as a plain UUID. A
321
- * label-compatible prefix is added at the metadata boundary, so user-facing
322
- * configs only need to carry a UUID.
323
- */
324
- const AppConfigSchema = z.object({
325
- id: z.uuid({ message: "'id' must be a UUID." }).optional(),
326
- name: z.string().min(1, { message: "'name' must be a non-empty string." }),
327
- env: z.record(z.string(), envValueSchema).optional(),
328
- cors: z.array(z.string()).optional(),
329
- allowedIpAddresses: z.array(z.string()).optional(),
330
- disableIntrospection: z.boolean().optional(),
331
- inlineSourcemap: z.boolean().optional(),
332
- logLevel: logLevelSchema.optional(),
333
- db: z.unknown().optional(),
334
- resolver: z.unknown().optional(),
335
- idp: z.unknown().optional(),
336
- auth: z.unknown().optional(),
337
- executor: z.unknown().optional(),
338
- workflow: z.unknown().optional(),
339
- httpAdapter: z.unknown().optional(),
340
- staticWebsites: z.unknown().optional(),
341
- aiGateways: z.unknown().optional(),
342
- secrets: z.unknown().optional()
343
- });
344
-
345
- //#endregion
346
- //#region src/parser/generator-config/schema.ts
347
- const DependencyKindSchema = z.enum([
348
- "tailordb",
349
- "resolver",
350
- "executor"
351
- ]);
352
- const KyselyTypeConfigSchema = z.tuple([z.literal("@tailor-platform/kysely-type"), z.object({ distPath: z.string() })]);
353
- const SeedConfigSchema = z.tuple([z.literal("@tailor-platform/seed"), z.object({
354
- distPath: z.string(),
355
- machineUserName: z.string().optional(),
356
- disableIdpUserSync: z.object({
357
- userToIdp: z.boolean().optional(),
358
- idpToUser: z.boolean().optional()
359
- }).optional()
360
- })]);
361
- const EnumConstantsConfigSchema = z.tuple([z.literal("@tailor-platform/enum-constants"), z.object({ distPath: z.string() })]);
362
- const FileUtilsConfigSchema = z.tuple([z.literal("@tailor-platform/file-utils"), z.object({ distPath: z.string() })]);
363
- const CodeGeneratorSchema = z.object({
364
- id: z.string(),
365
- description: z.string(),
366
- dependencies: z.array(DependencyKindSchema),
367
- processType: z.function().optional(),
368
- processResolver: z.function().optional(),
369
- processExecutor: z.function().optional(),
370
- processTailorDBNamespace: z.function().optional(),
371
- processResolverNamespace: z.function().optional(),
372
- aggregate: z.function({ output: z.any() })
373
- });
374
- const BaseGeneratorConfigSchema = z.union([
375
- KyselyTypeConfigSchema,
376
- SeedConfigSchema,
377
- EnumConstantsConfigSchema,
378
- FileUtilsConfigSchema,
379
- CodeGeneratorSchema
380
- ]);
381
-
382
- //#endregion
383
- //#region src/parser/plugin-config/schema.ts
384
- const PluginConfigSchema = z.object({
385
- id: z.string(),
386
- description: z.string(),
387
- importPath: z.string().optional(),
388
- pluginConfig: z.unknown().optional(),
389
- typeConfigRequired: z.union([z.boolean(), functionSchema]).optional(),
390
- onTypeLoaded: functionSchema.optional(),
391
- onNamespaceLoaded: functionSchema.optional(),
392
- onTailorDBReady: functionSchema.optional(),
393
- onResolverReady: functionSchema.optional(),
394
- onExecutorReady: functionSchema.optional()
395
- }).passthrough().refine((p) => {
396
- return !(p.onTypeLoaded || p.onNamespaceLoaded) || !!p.importPath;
397
- }, { message: "importPath is required when plugin has definition-time hooks (onTypeLoaded/onNamespaceLoaded)" }).transform((plugin) => plugin);
398
-
399
- //#endregion
400
- //#region src/plugin/builtin/registry.ts
401
- const builtinPlugins = /* @__PURE__ */ new Map([
402
- [KyselyGeneratorID, (options) => kyselyTypePlugin(options)],
403
- [SeedGeneratorID, (options) => seedPlugin(options)],
404
- [EnumConstantsGeneratorID, (options) => enumConstantsPlugin(options)],
405
- [FileUtilsGeneratorID, (options) => fileUtilsPlugin(options)]
406
- ]);
407
-
408
42
  //#endregion
409
43
  //#region src/cli/shared/apply-concurrency.ts
410
44
  /**
@@ -547,7 +181,7 @@ function initOAuth2Client(config) {
547
181
  */
548
182
  async function initOperatorClient(accessToken, config) {
549
183
  const platformConfig = config ?? getPlatformConfigForToken(accessToken);
550
- const [{ createTracingInterceptor }, { OperatorService }] = await Promise.all([import("./interceptor-D-q1rvRl.mjs"), import("./service_pb-B2FF59sP.mjs")]);
184
+ const [{ createTracingInterceptor }, { OperatorService }] = await Promise.all([import("./interceptor-D-q1rvRl.mjs"), import("./service_pb-r1T7kpJc.mjs")]);
551
185
  const interceptors = [
552
186
  await userAgentInterceptor(),
553
187
  await bearerTokenInterceptor(accessToken),
@@ -627,7 +261,7 @@ function retryInterceptor() {
627
261
  logger.debug(`retry: ${req.method.name} returned AlreadyExists on attempt ${i + 1}; treating as success (prior attempt likely committed)`);
628
262
  return synthesizeEmptyUnaryResponse(req);
629
263
  }
630
- const { reportCrash } = await import("./crashreport-Dy4ZzSkd.mjs");
264
+ const { reportCrash } = await import("./crashreport-np4-_DX2.mjs");
631
265
  await reportCrash(error, "handledError");
632
266
  }
633
267
  if (isRetirable(error, req.method.idempotency)) {
@@ -1032,742 +666,6 @@ async function closeConnectionPool() {
1032
666
  await getGlobalDispatcher().close();
1033
667
  }
1034
668
 
1035
- //#endregion
1036
- //#region src/cli/shared/token-store.ts
1037
- const SERVICE_NAME = "tailor-platform-cli";
1038
- let entryClass;
1039
- async function getEntryClass() {
1040
- if (entryClass !== void 0) return entryClass;
1041
- try {
1042
- const mod = await import("@napi-rs/keyring");
1043
- const probe = new mod.Entry(SERVICE_NAME, "__probe__");
1044
- probe.setPassword("probe");
1045
- probe.deletePassword();
1046
- entryClass = mod.Entry;
1047
- } catch {
1048
- logger.warn("System keyring is not available. Tokens will be stored in the config file. Set TAILOR_PLATFORM_TOKEN environment variable for CI environments.");
1049
- entryClass = false;
1050
- }
1051
- return entryClass;
1052
- }
1053
- /**
1054
- * Check whether the OS keyring is available and functional.
1055
- * @returns true if keyring is available
1056
- */
1057
- async function isKeyringAvailable() {
1058
- return await getEntryClass() !== false;
1059
- }
1060
- /**
1061
- * Load tokens from the OS keyring for a given account.
1062
- * @param account - User identifier (e.g. email or client ID)
1063
- * @returns Token data or undefined if not found or keyring unavailable
1064
- */
1065
- async function loadKeyringTokens(account) {
1066
- const Entry = await getEntryClass();
1067
- if (!Entry) return void 0;
1068
- try {
1069
- const raw = new Entry(SERVICE_NAME, account).getPassword();
1070
- if (raw === null) return void 0;
1071
- return JSON.parse(raw);
1072
- } catch {
1073
- return;
1074
- }
1075
- }
1076
- /**
1077
- * Save tokens to the OS keyring for a given account.
1078
- * @param account - User identifier (e.g. email or client ID)
1079
- * @param tokens - Token data to store
1080
- */
1081
- async function saveKeyringTokens(account, tokens) {
1082
- const Entry = await getEntryClass();
1083
- if (!Entry) return;
1084
- new Entry(SERVICE_NAME, account).setPassword(JSON.stringify(tokens));
1085
- }
1086
- /**
1087
- * Delete tokens from the OS keyring for a given account.
1088
- * @param account - User identifier (e.g. email or client ID)
1089
- */
1090
- async function deleteKeyringTokens(account) {
1091
- const Entry = await getEntryClass();
1092
- if (!Entry) return;
1093
- try {
1094
- new Entry(SERVICE_NAME, account).deletePassword();
1095
- } catch {}
1096
- }
1097
-
1098
- //#endregion
1099
- //#region src/cli/shared/context.ts
1100
- const pfProfileSchema = z.object({
1101
- user: z.string(),
1102
- workspace_id: z.string(),
1103
- readonly: z.boolean().optional(),
1104
- machine_user: z.string().optional(),
1105
- machine_user_override: z.enum(["allow", "deny"]).optional(),
1106
- platform_url: z.url().optional(),
1107
- oauth2_client_id: z.string().optional(),
1108
- console_url: z.url().optional()
1109
- });
1110
- const pfUserSchemaV1 = z.object({
1111
- access_token: z.string(),
1112
- refresh_token: z.string().optional(),
1113
- token_expires_at: z.string()
1114
- });
1115
- const pfUserKeyringSchema = z.object({
1116
- storage: z.literal("keyring"),
1117
- token_expires_at: z.string()
1118
- });
1119
- const pfUserFileSchema = z.object({
1120
- storage: z.literal("file"),
1121
- token_expires_at: z.string(),
1122
- access_token: z.string(),
1123
- refresh_token: z.string().optional()
1124
- });
1125
- const pfUserSchemaV2 = z.discriminatedUnion("storage", [pfUserKeyringSchema, pfUserFileSchema]);
1126
- const pfConfigSchemaV1 = z.object({
1127
- version: z.literal(1),
1128
- users: z.partialRecord(z.string(), pfUserSchemaV1),
1129
- profiles: z.partialRecord(z.string(), pfProfileSchema),
1130
- current_user: z.string().nullable()
1131
- });
1132
- const V2_CONFIG_VERSION = 2;
1133
- const LATEST_CONFIG_VERSION = 3;
1134
- const V2_MIN_SDK_VERSION = "1.29.0";
1135
- const V3_MIN_SDK_VERSION = "1.70.0";
1136
- const semverSchema = z.templateLiteral([
1137
- z.number().int(),
1138
- ".",
1139
- z.number().int(),
1140
- ".",
1141
- z.number().int()
1142
- ]);
1143
- const pfConfigSchema = z.object({
1144
- version: z.union([z.literal(V2_CONFIG_VERSION), z.literal(LATEST_CONFIG_VERSION)]),
1145
- min_sdk_version: semverSchema,
1146
- latest_version: z.number().int().optional(),
1147
- latest_min_sdk_version: semverSchema.optional(),
1148
- users: z.partialRecord(z.string(), pfUserSchemaV2),
1149
- profiles: z.partialRecord(z.string(), pfProfileSchema),
1150
- current_user: z.string().nullable()
1151
- });
1152
- function platformConfigPath() {
1153
- if (!xdgConfig) throw new Error("User home directory not found");
1154
- return path.join(xdgConfig, "tailor-platform", "config.yaml");
1155
- }
1156
- /**
1157
- * Convert stored profile platform fields to platform client settings.
1158
- * @param profile - Profile platform settings
1159
- * @returns Platform client settings
1160
- */
1161
- function platformConfigFromProfile(profile) {
1162
- const config = {
1163
- ...profile?.platform_url ? { platformUrl: profile.platform_url } : {},
1164
- ...profile?.oauth2_client_id ? { oauth2ClientId: profile.oauth2_client_id } : {},
1165
- ...profile?.console_url ? { consoleUrl: profile.console_url } : {}
1166
- };
1167
- return Object.keys(config).length > 0 ? config : void 0;
1168
- }
1169
- function platformUserKey(user, config) {
1170
- const platformUrl = getPlatformBaseUrl(config);
1171
- if (platformUrl === normalizeBaseUrl("https://api.tailor.tech")) return user;
1172
- return `${platformUrl}|${user}`;
1173
- }
1174
- function canUseLegacyUserKey(platformUrl) {
1175
- try {
1176
- return getPlatformBaseUrl() === platformUrl;
1177
- } catch {
1178
- return false;
1179
- }
1180
- }
1181
- function findUserEntry(config, user, platformConfig, opts = {}) {
1182
- const userKey = platformUserKey(user, platformConfig);
1183
- const userEntry = config.users[userKey];
1184
- if (userEntry) return {
1185
- userKey,
1186
- userEntry
1187
- };
1188
- const platformUrl = getPlatformBaseUrl(platformConfig);
1189
- if (userKey !== user && (opts.allowLegacyUserKey === false || !canUseLegacyUserKey(platformUrl))) return {
1190
- userKey,
1191
- userEntry
1192
- };
1193
- const legacyEntry = config.users[user];
1194
- return legacyEntry ? {
1195
- userKey: user,
1196
- userEntry: legacyEntry
1197
- } : {
1198
- userKey,
1199
- userEntry
1200
- };
1201
- }
1202
- /**
1203
- * Resolve the config user key that would be used for a user on the selected platform.
1204
- * @param config - Platform config
1205
- * @param user - User name
1206
- * @param platformConfig - Optional platform connection settings
1207
- * @param opts - Token lookup options
1208
- * @returns Resolved config user key
1209
- */
1210
- function resolveUserTokenKey(config, user, platformConfig, opts) {
1211
- return findUserEntry(config, user, platformConfig, opts).userKey;
1212
- }
1213
- /**
1214
- * Check whether tokens are registered for a user on the selected platform.
1215
- * @param config - Platform config
1216
- * @param user - User name
1217
- * @param platformConfig - Optional platform connection settings
1218
- * @param opts - Token lookup options
1219
- * @returns True when the user has a registered token entry
1220
- */
1221
- function hasUserTokenEntry(config, user, platformConfig, opts) {
1222
- return findUserEntry(config, user, platformConfig, opts).userEntry !== void 0;
1223
- }
1224
- function hasUserKeyForName(users, user) {
1225
- return users[user] !== void 0 || Object.keys(users).some((key) => key.endsWith(`|${user}`));
1226
- }
1227
- /**
1228
- * Check whether any platform has tokens registered for a user.
1229
- * @param config - Platform config
1230
- * @param user - User name
1231
- * @returns True when the user has a token entry for any platform
1232
- */
1233
- function hasAnyUserTokenEntry(config, user) {
1234
- return hasUserKeyForName(config.users, user);
1235
- }
1236
- function hasCurrentUserEntry(users, currentUser) {
1237
- return hasUserKeyForName(users, currentUser);
1238
- }
1239
- /**
1240
- * Migrate a v1 config to v2.
1241
- * Tokens are kept in the config file (storage: "file") during migration.
1242
- * They will be moved to the OS keyring on next login or token refresh.
1243
- * @param v1Config - v1 configuration to migrate
1244
- * @returns Migrated v2 configuration
1245
- */
1246
- function migrateV1ToV2(v1Config) {
1247
- const users = {};
1248
- for (const [name, v1User] of Object.entries(v1Config.users)) {
1249
- if (!v1User) continue;
1250
- users[name] = {
1251
- access_token: v1User.access_token,
1252
- refresh_token: v1User.refresh_token,
1253
- token_expires_at: v1User.token_expires_at,
1254
- storage: "file"
1255
- };
1256
- }
1257
- return {
1258
- version: V2_CONFIG_VERSION,
1259
- min_sdk_version: V2_MIN_SDK_VERSION,
1260
- users,
1261
- profiles: v1Config.profiles,
1262
- current_user: v1Config.current_user
1263
- };
1264
- }
1265
- async function warnIfNewerConfigAvailable(config) {
1266
- if (!config.latest_min_sdk_version) return;
1267
- if (lt((await readPackageJson()).version ?? "0.0.0", config.latest_min_sdk_version)) logger.warn(multiline`
1268
- A newer config version (${String(config.latest_version)}) is available.
1269
- Please update your SDK to >= ${config.latest_min_sdk_version}: pnpm update @tailor-platform/sdk
1270
- `);
1271
- }
1272
- /**
1273
- * Read Tailor Platform CLI configuration, migrating from tailorctl or v1 if necessary.
1274
- * @returns Parsed platform configuration
1275
- */
1276
- async function readPlatformConfig() {
1277
- const configPath = platformConfigPath();
1278
- if (!fs$1.existsSync(configPath)) {
1279
- logger.warn(`Config not found at ${configPath}, migrating from tailorctl config...`);
1280
- const tcConfig = readTailorctlConfig();
1281
- const v1Config = tcConfig ? fromTailorctlConfig(tcConfig) : {
1282
- version: 1,
1283
- users: {},
1284
- profiles: {},
1285
- current_user: null
1286
- };
1287
- writePlatformConfig(v1Config);
1288
- return migrateV1ToV2(v1Config);
1289
- }
1290
- const rawConfig = parseYAML(fs$1.readFileSync(configPath, "utf-8"));
1291
- tightenSecretFilePermissions(configPath);
1292
- const version = rawConfig != null && typeof rawConfig === "object" && "version" in rawConfig ? rawConfig.version : void 0;
1293
- if (typeof version === "number" && version > LATEST_CONFIG_VERSION) {
1294
- const minSdk = "min_sdk_version" in rawConfig ? String(rawConfig.min_sdk_version) : void 0;
1295
- const updateHint = minSdk ? `Please update your SDK to >= ${minSdk}: pnpm update @tailor-platform/sdk` : "Please update your SDK: pnpm update @tailor-platform/sdk";
1296
- throw new Error(multiline`
1297
- Config file uses version ${String(version)}, but this SDK only supports up to version ${String(LATEST_CONFIG_VERSION)}.
1298
- ${updateHint}
1299
- `);
1300
- }
1301
- const configResult = pfConfigSchema.safeParse(rawConfig);
1302
- if (configResult.success) {
1303
- await warnIfNewerConfigAvailable(configResult.data);
1304
- return configResult.data;
1305
- }
1306
- const v1Result = pfConfigSchemaV1.safeParse(rawConfig);
1307
- if (v1Result.success) return migrateV1ToV2(v1Result.data);
1308
- throw new Error(multiline`
1309
- Failed to parse config file at ${configPath}.
1310
- The file may be corrupted or created by an incompatible SDK version.
1311
- `);
1312
- }
1313
- function toV1ForDisk(config) {
1314
- const users = {};
1315
- for (const [name, entry] of Object.entries(config.users)) {
1316
- if (!entry || entry.storage === "keyring") continue;
1317
- users[name] = {
1318
- access_token: entry.access_token,
1319
- refresh_token: entry.refresh_token,
1320
- token_expires_at: entry.token_expires_at
1321
- };
1322
- }
1323
- const currentUser = config.current_user && hasCurrentUserEntry(users, config.current_user) ? config.current_user : null;
1324
- return {
1325
- version: 1,
1326
- users,
1327
- profiles: config.profiles,
1328
- current_user: currentUser
1329
- };
1330
- }
1331
- function hasProfilePlatformSettings(config) {
1332
- return Object.values(config.profiles).some((profile) => profile?.platform_url !== void 0 || profile?.oauth2_client_id !== void 0 || profile?.console_url !== void 0);
1333
- }
1334
- function hasScopedUserKeys(config) {
1335
- return Object.keys(config.users).some((userKey) => userKey.includes("|"));
1336
- }
1337
- function toLatestForDisk(config) {
1338
- return {
1339
- ...config.version === 1 ? migrateV1ToV2(config) : config,
1340
- version: LATEST_CONFIG_VERSION,
1341
- min_sdk_version: V3_MIN_SDK_VERSION
1342
- };
1343
- }
1344
- /**
1345
- * Write Tailor Platform CLI configuration to disk.
1346
- * By default, file-backed configs without newer fields are converted to V1 for
1347
- * backward compatibility, so an older SDK can still read the file. Configs
1348
- * containing a keyring user are kept in V2 or later because the keyring storage
1349
- * variant is not representable in V1. Configs containing profile-level Platform
1350
- * settings or platform-scoped user tokens are written in the latest
1351
- * min-SDK-gated format because older SDKs would silently drop or misread those
1352
- * settings.
1353
- * Set TAILOR_USE_KEYRING to write the current in-memory format unconditionally.
1354
- *
1355
- * The config file may contain access/refresh tokens when the OS keyring is
1356
- * unavailable, so it is written via {@link writeSecretFile} so other users
1357
- * on the host cannot read it.
1358
- * @param config - Platform configuration to write
1359
- */
1360
- function writePlatformConfig(config) {
1361
- const configPath = platformConfigPath();
1362
- const hasKeyringUser = config.version !== 1 && Object.values(config.users).some((u) => u?.storage === "keyring");
1363
- writeSecretFile(configPath, stringifyYAML(hasProfilePlatformSettings(config) || hasScopedUserKeys(config) ? toLatestForDisk(config) : config.version !== 1 && !process.env.TAILOR_USE_KEYRING && !hasKeyringUser ? toV1ForDisk(config) : config));
1364
- }
1365
- const tcContextConfigSchema = z.object({
1366
- username: z.string().optional(),
1367
- controlplaneaccesstoken: z.string().optional(),
1368
- controlplanerefreshtoken: z.string().optional(),
1369
- controlplanetokenexpiresat: z.string().optional(),
1370
- workspaceid: z.string().optional()
1371
- });
1372
- const tcConfigSchema = z.object({ global: z.object({ context: z.string().optional() }).optional() }).catchall(tcContextConfigSchema.optional());
1373
- function readTailorctlConfig() {
1374
- const configPath = path.join(os.homedir(), ".tailorctl", "config");
1375
- if (!fs$1.existsSync(configPath)) return;
1376
- const rawConfig = parseTOML(fs$1.readFileSync(configPath, "utf-8"));
1377
- return tcConfigSchema.parse(rawConfig);
1378
- }
1379
- function fromTailorctlConfig(config) {
1380
- const users = {};
1381
- const profiles = {};
1382
- let currentUser = null;
1383
- const currentContext = config.global?.context || "default";
1384
- for (const [key, val] of Object.entries(config)) {
1385
- if (key === "global") continue;
1386
- const context = val;
1387
- if (!context.username || !context.controlplaneaccesstoken || !context.controlplanerefreshtoken || !context.controlplanetokenexpiresat || !context.workspaceid) continue;
1388
- if (key === currentContext) currentUser = context.username;
1389
- profiles[key] = {
1390
- user: context.username,
1391
- workspace_id: context.workspaceid
1392
- };
1393
- const user = users[context.username];
1394
- if (!user || new Date(user.token_expires_at) < new Date(context.controlplanetokenexpiresat)) users[context.username] = {
1395
- access_token: context.controlplaneaccesstoken,
1396
- refresh_token: context.controlplanerefreshtoken,
1397
- token_expires_at: context.controlplanetokenexpiresat
1398
- };
1399
- }
1400
- return {
1401
- version: 1,
1402
- users,
1403
- profiles,
1404
- current_user: currentUser
1405
- };
1406
- }
1407
- function validateUUID(value, source) {
1408
- const result = z.uuid().safeParse(value);
1409
- if (!result.success) throw new Error(`Invalid value from ${source}: must be a valid UUID`);
1410
- return result.data;
1411
- }
1412
- /**
1413
- * Load workspace ID from command options, environment variables, or platform config.
1414
- * In CLI context, env fallback is also handled by politty's arg env option.
1415
- * Priority: opts/workspaceId > env/workspaceId > opts/profile > error
1416
- * @param opts - Workspace and profile options
1417
- * @returns Resolved workspace ID
1418
- */
1419
- async function loadWorkspaceId(opts) {
1420
- const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
1421
- if (opts?.workspaceId) return validateUUID(opts.workspaceId, "--workspace-id option");
1422
- if (process.env.TAILOR_PLATFORM_WORKSPACE_ID) return validateUUID(process.env.TAILOR_PLATFORM_WORKSPACE_ID, "TAILOR_PLATFORM_WORKSPACE_ID environment variable");
1423
- if (profile) {
1424
- const wsId = (await readPlatformConfig()).profiles[profile]?.workspace_id;
1425
- if (!wsId) throw new Error(`Profile "${profile}" not found`);
1426
- return validateUUID(wsId, `profile "${profile}"`);
1427
- }
1428
- throw new Error(multiline`
1429
- Workspace ID not found.
1430
- Please specify workspace ID via --workspace-id option or TAILOR_PLATFORM_WORKSPACE_ID environment variable.
1431
- `);
1432
- }
1433
- /**
1434
- * Load machine user name from command options, environment variables, or platform config.
1435
- * In CLI context, env fallback is also handled by politty's arg env option.
1436
- * Priority: opts/machineUser > env/TAILOR_PLATFORM_MACHINE_USER_NAME > opts/profile (profile default) > undefined.
1437
- * An explicitly empty `opts.machineUser` is rejected with a CLIError (`MACHINE_USER_NAME_EMPTY`) rather than falling back to the env var or profile default.
1438
- * When the active profile has `machine_user_override: "deny"`, an explicit value that differs from the profile's machine user throws a CLIError with code `PROFILE_MACHINE_USER_OVERRIDE_DENIED`.
1439
- * @param opts - Machine user and profile options
1440
- * @returns Resolved machine user name, or undefined if not set
1441
- */
1442
- async function loadMachineUserName(opts) {
1443
- if (opts?.machineUser === "") throw createCLIError({
1444
- code: "MACHINE_USER_NAME_EMPTY",
1445
- message: "Machine user name cannot be empty.",
1446
- suggestion: "Pass a non-empty machine user name, or omit the option to use the environment variable or profile default."
1447
- });
1448
- const envMachineUser = process.env.TAILOR_PLATFORM_MACHINE_USER_NAME || void 0;
1449
- const explicitMachineUser = opts?.machineUser ? {
1450
- source: opts.machineUserSource ?? "option",
1451
- value: opts.machineUser
1452
- } : envMachineUser ? {
1453
- source: "env",
1454
- value: envMachineUser
1455
- } : void 0;
1456
- const explicit = explicitMachineUser?.value;
1457
- const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
1458
- if (!profile) return explicit;
1459
- const entry = (await readPlatformConfig()).profiles[profile];
1460
- if (!entry) {
1461
- if (explicit) return explicit;
1462
- throw new Error(`Profile "${profile}" not found`);
1463
- }
1464
- if (entry.machine_user && entry.machine_user_override === "deny") {
1465
- if (explicit && explicit !== entry.machine_user) {
1466
- const details = explicitMachineUser.source === "env" ? `The machine user is being set to "${explicit}" via the TAILOR_PLATFORM_MACHINE_USER_NAME environment variable, which conflicts with this profile's pinned machine user "${entry.machine_user}".` : `This profile fixes the machine user to "${entry.machine_user}" for application-data commands.`;
1467
- throw createCLIError({
1468
- code: "PROFILE_MACHINE_USER_OVERRIDE_DENIED",
1469
- message: `Profile "${profile}" denies overriding the machine user.`,
1470
- details,
1471
- suggestion: `Omit the machine user option, unset TAILOR_PLATFORM_MACHINE_USER_NAME, or run 'tailor-sdk profile update ${profile} --machine-user-override allow'.`
1472
- });
1473
- }
1474
- return entry.machine_user;
1475
- }
1476
- return explicit || entry.machine_user;
1477
- }
1478
- /**
1479
- * Load access token from environment variables, command options, or platform config.
1480
- * In CLI context, profile env fallback is also handled by politty's arg env option.
1481
- * Priority: env/TAILOR_PLATFORM_TOKEN > env/TAILOR_TOKEN (deprecated) > opts/profile > env/profile > config/currentUser > error
1482
- * @param opts - Profile options
1483
- * @returns Resolved access token
1484
- */
1485
- async function loadAccessToken(opts) {
1486
- const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
1487
- const envToken = process.env.TAILOR_PLATFORM_TOKEN ?? process.env.TAILOR_TOKEN;
1488
- if (envToken && !process.env.TAILOR_PLATFORM_TOKEN) logger.warn("TAILOR_TOKEN is deprecated. Please use TAILOR_PLATFORM_TOKEN instead.");
1489
- if (envToken) {
1490
- rememberPlatformConfigForToken(envToken, await loadPlatformClientConfig({
1491
- profile,
1492
- allowMissingProfile: true
1493
- }));
1494
- return envToken;
1495
- }
1496
- const pfConfig = await readPlatformConfig();
1497
- const profileEntry = profile ? pfConfig.profiles[profile] : void 0;
1498
- if (profile && !profileEntry) throw new Error(`Profile "${profile}" not found`);
1499
- const user = profileEntry?.user ?? pfConfig.current_user;
1500
- if (!user) throw new Error(multiline`
1501
- Tailor Platform token not found.
1502
- Please specify token via TAILOR_PLATFORM_TOKEN environment variable or login using 'tailor-sdk login' command.
1503
- `);
1504
- return await fetchLatestToken(pfConfig, user, profileEntry ? platformConfigFromProfile(profileEntry) : void 0);
1505
- }
1506
- /**
1507
- * Load platform connection settings from the active profile.
1508
- * @param opts - Profile options
1509
- * @returns Resolved platform connection settings, or undefined for the default environment
1510
- */
1511
- async function loadPlatformClientConfig(opts) {
1512
- const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
1513
- if (!profile) return;
1514
- let pfConfig;
1515
- try {
1516
- pfConfig = await readPlatformConfig();
1517
- } catch (error) {
1518
- if (opts?.allowMissingProfile) return;
1519
- throw error;
1520
- }
1521
- const profileEntry = pfConfig.profiles[profile];
1522
- if (!profileEntry) {
1523
- if (opts?.allowMissingProfile) return;
1524
- throw new Error(`Profile "${profile}" not found`);
1525
- }
1526
- return platformConfigFromProfile(profileEntry);
1527
- }
1528
- /**
1529
- * Load the Tailor Platform Console base URL from environment variables or the active profile.
1530
- * @param opts - Profile options
1531
- * @returns Resolved Console base URL
1532
- */
1533
- async function loadConsoleBaseUrl(opts) {
1534
- return getConsoleBaseUrl(await loadPlatformClientConfig(opts));
1535
- }
1536
- /**
1537
- * Resolve the actual token values for a user, reading from keyring or config as appropriate.
1538
- * @param userEntry - User entry from the config
1539
- * @param user - User identifier
1540
- * @param label - User-facing identifier used in error messages
1541
- * @returns Access token and optional refresh token
1542
- */
1543
- async function resolveTokens(userEntry, user, label = user) {
1544
- if (userEntry.storage === "keyring") {
1545
- const tokens = await loadKeyringTokens(user);
1546
- if (!tokens) throw new Error(multiline`
1547
- Credentials not found in OS keyring for "${label}".
1548
- Please run 'tailor-sdk login' and try again.
1549
- `);
1550
- return tokens;
1551
- }
1552
- return {
1553
- accessToken: userEntry.access_token,
1554
- refreshToken: userEntry.refresh_token
1555
- };
1556
- }
1557
- /**
1558
- * Save tokens for a user, writing to keyring or config as appropriate.
1559
- * @param config - Platform config
1560
- * @param user - User identifier
1561
- * @param tokens - Token data to save
1562
- * @param tokens.accessToken - Access token to persist
1563
- * @param tokens.refreshToken - Refresh token to persist when available
1564
- * @param expiresAt - Token expiration date
1565
- * @param platformConfig - Optional platform connection settings
1566
- */
1567
- async function saveUserTokens(config, user, tokens, expiresAt, platformConfig) {
1568
- const userKey = platformUserKey(user, platformConfig);
1569
- if (process.env.TAILOR_USE_KEYRING && await isKeyringAvailable()) {
1570
- await saveKeyringTokens(userKey, tokens);
1571
- config.users[userKey] = {
1572
- token_expires_at: expiresAt,
1573
- storage: "keyring"
1574
- };
1575
- } else config.users[userKey] = {
1576
- access_token: tokens.accessToken,
1577
- refresh_token: tokens.refreshToken,
1578
- token_expires_at: expiresAt,
1579
- storage: "file"
1580
- };
1581
- }
1582
- /**
1583
- * Delete tokens for a user from keyring if applicable.
1584
- * @param config - Platform config
1585
- * @param user - User identifier
1586
- * @param platformConfig - Optional platform connection settings
1587
- * @param opts - Token lookup options
1588
- */
1589
- async function deleteUserTokens(config, user, platformConfig, opts) {
1590
- const { userKey, userEntry } = findUserEntry(config, user, platformConfig, opts);
1591
- if (userEntry?.storage === "keyring") await deleteKeyringTokens(userKey);
1592
- delete config.users[userKey];
1593
- }
1594
- /**
1595
- * Resolve stored tokens for a user on the selected platform.
1596
- * @param config - Platform config
1597
- * @param user - User name
1598
- * @param platformConfig - Optional platform connection settings
1599
- * @param opts - Token lookup options
1600
- * @returns Stored user entry and token values, or undefined when the user is not logged in
1601
- */
1602
- async function loadStoredUserTokens(config, user, platformConfig, opts) {
1603
- const { userKey, userEntry } = findUserEntry(config, user, platformConfig, opts);
1604
- if (!userEntry) return void 0;
1605
- return {
1606
- userEntry,
1607
- ...await resolveTokens(userEntry, userKey, user)
1608
- };
1609
- }
1610
- /**
1611
- * Fetch the latest access token, refreshing if necessary.
1612
- * @param config - Platform config
1613
- * @param user - User name
1614
- * @param platformConfig - Optional platform connection settings
1615
- * @returns Latest access token
1616
- */
1617
- async function fetchLatestToken(config, user, platformConfig) {
1618
- const { userKey, userEntry } = findUserEntry(config, user, platformConfig);
1619
- if (!userEntry) throw new Error(multiline`
1620
- User "${user}" not found.
1621
- Please verify your user name and login using 'tailor-sdk login' command.
1622
- `);
1623
- const tokens = await resolveTokens(userEntry, userKey, user);
1624
- if (new Date(userEntry.token_expires_at) > /* @__PURE__ */ new Date()) {
1625
- rememberPlatformConfigForToken(tokens.accessToken, platformConfig);
1626
- return tokens.accessToken;
1627
- }
1628
- if (!tokens.refreshToken) throw new Error(multiline`
1629
- Token expired.
1630
- Please run 'tailor-sdk login' and try again.
1631
- `);
1632
- const client = initOAuth2Client(platformConfig);
1633
- let resp;
1634
- try {
1635
- resp = await client.refreshToken({
1636
- accessToken: tokens.accessToken,
1637
- refreshToken: tokens.refreshToken,
1638
- expiresAt: Date.parse(userEntry.token_expires_at)
1639
- });
1640
- } catch {
1641
- throw new Error(multiline`
1642
- Failed to refresh token. Your session may have expired.
1643
- Please run 'tailor-sdk login' and try again.
1644
- `);
1645
- }
1646
- const newExpiresAt = new Date(assertDefined(resp.expiresAt, "token refresh response missing expiresAt")).toISOString();
1647
- await saveUserTokens(config, user, {
1648
- accessToken: resp.accessToken,
1649
- refreshToken: resp.refreshToken ?? void 0
1650
- }, newExpiresAt, platformConfig);
1651
- if (userKey !== platformUserKey(user, platformConfig)) {
1652
- if (userEntry.storage === "keyring") await deleteKeyringTokens(userKey);
1653
- delete config.users[userKey];
1654
- }
1655
- writePlatformConfig(config);
1656
- rememberPlatformConfigForToken(resp.accessToken, platformConfig);
1657
- return resp.accessToken;
1658
- }
1659
- const DEFAULT_CONFIG_FILENAME = "tailor.config.ts";
1660
- /**
1661
- * Load config path from command options, environment variables, or search parent directories.
1662
- * In CLI context, env fallback is also handled by politty's arg env option.
1663
- * Priority: opts/config > env/config > search parent directories
1664
- * @param configPath - Optional explicit config path
1665
- * @returns Resolved config path or undefined
1666
- */
1667
- function loadConfigPath(configPath) {
1668
- if (configPath) return configPath;
1669
- if (process.env.TAILOR_PLATFORM_SDK_CONFIG_PATH) return process.env.TAILOR_PLATFORM_SDK_CONFIG_PATH;
1670
- return findUpSync(DEFAULT_CONFIG_FILENAME);
1671
- }
1672
-
1673
- //#endregion
1674
- //#region src/cli/shared/mock.ts
1675
- /**
1676
- * Install a stub `globalThis.tailordb` so that user code loaded by the CLI
1677
- * (e.g. via `createGetDB` in `@tailor-platform/sdk/kysely`) can reference
1678
- * `tailordb.Client` without hitting a `ReferenceError`. The CLI never
1679
- * actually executes the user code paths that issue queries, so a no-op
1680
- * client suffices.
1681
- *
1682
- * Exposed as a function (rather than a top-level statement) so that
1683
- * `package.json#sideEffects` can keep the file marked side-effect-free
1684
- * without bundlers eliminating the install step.
1685
- */
1686
- function installCliTailordbStub() {
1687
- globalThis.tailordb = { Client: class {
1688
- constructor(_config) {}
1689
- async connect() {}
1690
- async end() {}
1691
- async queryObject() {
1692
- return {};
1693
- }
1694
- } };
1695
- }
1696
-
1697
- //#endregion
1698
- //#region src/cli/shared/config-loader.ts
1699
- const GeneratorConfigSchema = CodeGeneratorSchema.brand("CodeGenerator");
1700
- /**
1701
- * Load Tailor configuration file and associated generators and plugins.
1702
- * @param configPath - Optional explicit config path
1703
- * @param options - Optional module import behavior.
1704
- * @returns Loaded config, generators, plugins, and config path
1705
- */
1706
- async function loadConfig(configPath, options = {}) {
1707
- installCliTailordbStub();
1708
- const foundPath = loadConfigPath(configPath);
1709
- if (!foundPath) throw new Error("Configuration file not found: tailor.config.ts not found in current or parent directories");
1710
- const resolvedPath = path.resolve(process.cwd(), foundPath);
1711
- if (!fs$1.existsSync(resolvedPath)) throw new Error(`Configuration file not found: ${configPath}`);
1712
- const configUrl = pathToFileURL(resolvedPath);
1713
- if (options.importNonce) configUrl.searchParams.set("tailorImportNonce", options.importNonce);
1714
- const configModule = await import(configUrl.href);
1715
- if (!configModule || !configModule.default) throw new Error("Invalid Tailor config module: default export not found");
1716
- const validated = AppConfigSchema.safeParse(configModule.default);
1717
- if (!validated.success) {
1718
- const issues = validated.error.issues.map((i) => ` - ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
1719
- throw new Error(`Invalid Tailor config in ${resolvedPath}:\n${issues}`);
1720
- }
1721
- const allGenerators = [];
1722
- const allPlugins = [];
1723
- for (const value of Object.values(configModule)) if (Array.isArray(value)) {
1724
- const generatorParsed = value.reduce((acc, item) => {
1725
- if (!acc.success) return acc;
1726
- const baseResult = BaseGeneratorConfigSchema.safeParse(item);
1727
- if (baseResult.success && Array.isArray(baseResult.data)) {
1728
- const [id, options] = baseResult.data;
1729
- const pluginFactory = builtinPlugins.get(id);
1730
- if (pluginFactory) {
1731
- acc.convertedPlugins.push(pluginFactory(options));
1732
- return acc;
1733
- }
1734
- }
1735
- const result = GeneratorConfigSchema.safeParse(item);
1736
- if (result.success) acc.items.push(result.data);
1737
- else acc.success = false;
1738
- return acc;
1739
- }, {
1740
- success: true,
1741
- items: [],
1742
- convertedPlugins: []
1743
- });
1744
- if (generatorParsed.success && (generatorParsed.items.length > 0 || generatorParsed.convertedPlugins.length > 0)) {
1745
- allGenerators.push(...generatorParsed.items);
1746
- allPlugins.push(...generatorParsed.convertedPlugins);
1747
- continue;
1748
- }
1749
- const pluginParsed = value.reduce((acc, item) => {
1750
- if (!acc.success) return acc;
1751
- const result = PluginConfigSchema.safeParse(item);
1752
- if (result.success) acc.items.push(result.data);
1753
- else acc.success = false;
1754
- return acc;
1755
- }, {
1756
- success: true,
1757
- items: []
1758
- });
1759
- if (pluginParsed.success && pluginParsed.items.length > 0) allPlugins.push(...pluginParsed.items);
1760
- }
1761
- return {
1762
- config: {
1763
- ...configModule.default,
1764
- path: resolvedPath
1765
- },
1766
- generators: allGenerators,
1767
- plugins: allPlugins
1768
- };
1769
- }
1770
-
1771
669
  //#endregion
1772
670
  //#region src/cli/cache/hasher.ts
1773
671
  /**
@@ -2508,100 +1406,20 @@ async function removeStaleEntryFiles(outputDir) {
2508
1406
  await Promise.all(files.filter((file) => file.endsWith(".entry.js")).map((file) => fs.rm(path.join(outputDir, file), { force: true })));
2509
1407
  }
2510
1408
 
2511
- //#endregion
2512
- //#region src/cli/shared/bundle-log-level.ts
2513
- const INFO_LEVEL_CONSOLE_METHODS = [
2514
- "console.info",
2515
- "console.table",
2516
- "console.dir",
2517
- "console.dirxml",
2518
- "console.count",
2519
- "console.countReset",
2520
- "console.time",
2521
- "console.timeLog",
2522
- "console.timeEnd",
2523
- "console.group",
2524
- "console.groupCollapsed",
2525
- "console.groupEnd",
2526
- "console.clear"
2527
- ];
2528
- const DEBUG_LEVEL_CONSOLE_METHODS = [
2529
- "console.debug",
2530
- "console.log",
2531
- "console.trace"
2532
- ];
2533
- const WARN_LEVEL_CONSOLE_METHODS = ["console.warn"];
2534
- const ERROR_LEVEL_CONSOLE_METHODS = ["console.error"];
2535
- const MANUAL_PURE_FUNCTIONS_BY_LOG_LEVEL = {
2536
- DEBUG: [],
2537
- INFO: DEBUG_LEVEL_CONSOLE_METHODS,
2538
- WARN: [...DEBUG_LEVEL_CONSOLE_METHODS, ...INFO_LEVEL_CONSOLE_METHODS],
2539
- ERROR: [
2540
- ...DEBUG_LEVEL_CONSOLE_METHODS,
2541
- ...INFO_LEVEL_CONSOLE_METHODS,
2542
- ...WARN_LEVEL_CONSOLE_METHODS
2543
- ],
2544
- SILENT: [
2545
- ...DEBUG_LEVEL_CONSOLE_METHODS,
2546
- ...INFO_LEVEL_CONSOLE_METHODS,
2547
- ...WARN_LEVEL_CONSOLE_METHODS,
2548
- ...ERROR_LEVEL_CONSOLE_METHODS
2549
- ]
2550
- };
2551
- function normalizeBundleLogLevel(value) {
2552
- const normalized = value.trim().toUpperCase();
2553
- return isLogLevel(normalized) ? normalized : void 0;
2554
- }
2555
- function resolveBundleLogLevel(configValue) {
2556
- if (configValue === void 0) return "DEBUG";
2557
- const resolved = normalizeBundleLogLevel(configValue);
2558
- if (resolved) return resolved;
2559
- throw new Error(`Invalid logLevel "${configValue}". Expected one of: ${LOG_LEVELS.join(", ")}`);
2560
- }
2561
- function manualPureFunctionsForLogLevel(logLevel) {
2562
- return MANUAL_PURE_FUNCTIONS_BY_LOG_LEVEL[logLevel];
2563
- }
2564
- function createLogLevelTreeshakeOptions(logLevel) {
2565
- const manualPureFunctions = manualPureFunctionsForLogLevel(logLevel);
2566
- return manualPureFunctions.length > 0 ? { manualPureFunctions } : {};
2567
- }
2568
-
2569
- //#endregion
2570
- //#region src/cli/shared/function-treeshake.ts
2571
- const BASE_FUNCTION_TREESHAKE_OPTIONS = {
2572
- moduleSideEffects: false,
2573
- annotations: true,
2574
- unknownGlobalSideEffects: false
2575
- };
2576
- function mergeFunctionTreeshakeOptions(fragments) {
2577
- const merged = {};
2578
- const manualPureFunctions = /* @__PURE__ */ new Set();
2579
- for (const fragment of fragments) {
2580
- Object.assign(merged, fragment);
2581
- for (const name of fragment.manualPureFunctions ?? []) manualPureFunctions.add(name);
2582
- }
2583
- if (manualPureFunctions.size > 0) merged.manualPureFunctions = [...manualPureFunctions];
2584
- else delete merged.manualPureFunctions;
2585
- return merged;
2586
- }
2587
- function composeFunctionTreeshakeOptions(fragments = []) {
2588
- return mergeFunctionTreeshakeOptions([BASE_FUNCTION_TREESHAKE_OPTIONS, ...fragments]);
2589
- }
2590
-
2591
- //#endregion
2592
- //#region src/cli/shared/platform-bundle-plugin.ts
2593
- const GATE = /(?<![\w$.])process\.env\.TAILOR_PLATFORM_BUNDLE\b/g;
2594
- const platformBundleDefinePlugin = {
2595
- name: "tailor-platform-bundle-define",
2596
- transform(code) {
2597
- if (!code.includes("process.env.TAILOR_PLATFORM_BUNDLE")) return null;
2598
- return { code: code.replace(GATE, "true") };
2599
- }
2600
- };
2601
-
2602
1409
  //#endregion
2603
1410
  //#region src/cli/services/workflow/ast-utils.ts
2604
1411
  /**
1412
+ * Read an import or export name from an OXC identifier or string-literal node.
1413
+ * @param node - Import/export name node
1414
+ * @returns Module binding name, or undefined for an unsupported node
1415
+ */
1416
+ function getModuleExportName(node) {
1417
+ if (!node || typeof node !== "object") return void 0;
1418
+ const exportName = node;
1419
+ if (exportName.name) return exportName.name;
1420
+ return typeof exportName.value === "string" ? exportName.value : void 0;
1421
+ }
1422
+ /**
2605
1423
  * Check if a module source is from the Tailor SDK package (including subpaths)
2606
1424
  * @param source - Module source string
2607
1425
  * @returns True if the source is from the Tailor SDK package
@@ -2644,7 +1462,7 @@ function getTriggerCallInfo(node, sourceText) {
2644
1462
  const callee = callExpr.callee;
2645
1463
  if (callee.type !== "MemberExpression") return null;
2646
1464
  const memberExpr = callee;
2647
- if (memberExpr.computed || memberExpr.object.type !== "Identifier" || memberExpr.property.name !== "trigger") return null;
1465
+ if (memberExpr.computed || memberExpr.property.name !== "trigger" || memberExpr.object.type !== "Identifier") return null;
2648
1466
  return {
2649
1467
  identifierName: memberExpr.object.name,
2650
1468
  callRange: {
@@ -2731,20 +1549,6 @@ function findStatementEnd(source, position) {
2731
1549
  if (i < source.length && source[i] === "\n") i++;
2732
1550
  return i;
2733
1551
  }
2734
- /**
2735
- * Resolve a relative path from a base directory
2736
- * Simple implementation that handles ./ and ../ prefixes
2737
- * @param baseDir - Base directory
2738
- * @param relativePath - Relative path to resolve
2739
- * @returns Resolved absolute path
2740
- */
2741
- function resolvePath(baseDir, relativePath) {
2742
- const parts = relativePath.replace(/\\/g, "/").split("/");
2743
- const baseParts = baseDir.replace(/\\/g, "/").split("/");
2744
- for (const part of parts) if (part === ".") {} else if (part === "..") baseParts.pop();
2745
- else baseParts.push(part);
2746
- return baseParts.join("/");
2747
- }
2748
1552
 
2749
1553
  //#endregion
2750
1554
  //#region src/cli/services/workflow/sdk-binding-collector.ts
@@ -2888,43 +1692,6 @@ function findAllJobs(program, _sourceText) {
2888
1692
  walk(program);
2889
1693
  return jobs;
2890
1694
  }
2891
- /**
2892
- * Build a map from export name to job name from detected jobs
2893
- * @param jobs - Detected job locations
2894
- * @returns Map from export name to job name
2895
- */
2896
- function buildJobNameMap(jobs) {
2897
- const map = /* @__PURE__ */ new Map();
2898
- for (const job of jobs) if (job.exportName) map.set(job.exportName, job.name);
2899
- return map;
2900
- }
2901
- /**
2902
- * Detect all .trigger() calls in the source code
2903
- * Returns information about each trigger call for transformation
2904
- * @param program - Parsed TypeScript program
2905
- * @param sourceText - Source code text
2906
- * @returns Detected trigger calls
2907
- */
2908
- function detectTriggerCalls(program, sourceText) {
2909
- const calls = [];
2910
- function walk(node) {
2911
- if (!node || typeof node !== "object") return;
2912
- const triggerCall = getTriggerCallInfo(node, sourceText);
2913
- if (triggerCall) calls.push({
2914
- identifierName: triggerCall.identifierName,
2915
- callRange: triggerCall.callRange,
2916
- argsText: triggerCall.argsText,
2917
- optionsText: triggerCall.optionsText
2918
- });
2919
- for (const key of Object.keys(node)) {
2920
- const child = node[key];
2921
- if (Array.isArray(child)) child.forEach((c) => walk(c));
2922
- else if (child && typeof child === "object") walk(child);
2923
- }
2924
- }
2925
- walk(program);
2926
- return calls;
2927
- }
2928
1695
 
2929
1696
  //#endregion
2930
1697
  //#region src/cli/services/workflow/workflow-detector.ts
@@ -2976,400 +1743,396 @@ function findAllWorkflows(program, _sourceText) {
2976
1743
  walk(program);
2977
1744
  return workflows;
2978
1745
  }
1746
+
1747
+ //#endregion
1748
+ //#region src/cli/shared/trigger-context.ts
2979
1749
  /**
2980
- * Build a map from export name to workflow name from detected workflows
2981
- * @param workflows - Detected workflows
2982
- * @returns Map from export name to workflow name
2983
- */
2984
- function buildWorkflowNameMap(workflows) {
2985
- const map = /* @__PURE__ */ new Map();
2986
- for (const workflow of workflows) if (workflow.exportName) map.set(workflow.exportName, workflow.name);
2987
- return map;
2988
- }
2989
- /**
2990
- * Detect default imports in a source file and return a map from local name to import source
2991
- * @param program - Parsed TypeScript program
2992
- * @returns Map from local name to import source
1750
+ * Normalize a source module path for trigger binding lookup.
1751
+ * @param filePath - Source file path or extensionless relative import path
1752
+ * @returns Absolute path without a JavaScript or TypeScript extension
2993
1753
  */
2994
- function detectDefaultImports(program) {
2995
- const imports = /* @__PURE__ */ new Map();
2996
- function walk(node) {
2997
- if (!node || typeof node !== "object") return;
2998
- if (node.type === "ImportDeclaration") {
2999
- const importDecl = node;
3000
- const source = importDecl.source.value;
3001
- if (typeof source === "string") {
3002
- for (const specifier of importDecl.specifiers) if (specifier.type === "ImportDefaultSpecifier") {
3003
- const spec = specifier;
3004
- if (spec.local.name) imports.set(spec.local.name, source);
3005
- }
1754
+ function normalizeFilePath(filePath) {
1755
+ return path.resolve(filePath.replace(/[?#].*$/, "")).replace(/\.(ts|mts|cts|js|mjs|cjs)$/, "");
1756
+ }
1757
+ function createModuleBindings(program, source) {
1758
+ const localBindings = /* @__PURE__ */ new Map();
1759
+ const exports = /* @__PURE__ */ new Map();
1760
+ for (const workflow of findAllWorkflows(program, source)) {
1761
+ const target = {
1762
+ kind: "workflow",
1763
+ name: workflow.name
1764
+ };
1765
+ if (workflow.exportName) localBindings.set(workflow.exportName, target);
1766
+ if (workflow.isDefaultExport) exports.set("default", target);
1767
+ }
1768
+ for (const job of findAllJobs(program, source)) if (job.exportName) localBindings.set(job.exportName, {
1769
+ kind: "job",
1770
+ name: job.name
1771
+ });
1772
+ for (const statement of program.body) {
1773
+ if (statement.type === "ExportDefaultDeclaration") {
1774
+ const declaration = statement.declaration;
1775
+ if (declaration?.type === "Identifier") {
1776
+ const target = localBindings.get(declaration.name);
1777
+ if (target) exports.set("default", target);
3006
1778
  }
1779
+ continue;
3007
1780
  }
3008
- for (const key of Object.keys(node)) {
3009
- const child = node[key];
3010
- if (Array.isArray(child)) child.forEach((c) => walk(c));
3011
- else if (child && typeof child === "object") walk(child);
1781
+ if (statement.type !== "ExportNamedDeclaration") continue;
1782
+ const declaration = statement.declaration;
1783
+ if (declaration?.type === "VariableDeclaration") for (const declarator of declaration.declarations) {
1784
+ const id = declarator.id;
1785
+ if (id?.type !== "Identifier") continue;
1786
+ const localName = id.name;
1787
+ const target = localBindings.get(localName);
1788
+ if (target) exports.set(localName, target);
1789
+ }
1790
+ if (statement.source) continue;
1791
+ for (const specifier of statement.specifiers ?? []) {
1792
+ const localName = getModuleExportName(specifier.local);
1793
+ const exportedName = getModuleExportName(specifier.exported);
1794
+ if (!localName || !exportedName) continue;
1795
+ const target = localBindings.get(localName);
1796
+ if (target) exports.set(exportedName, target);
3012
1797
  }
3013
1798
  }
3014
- walk(program);
3015
- return imports;
1799
+ return {
1800
+ localBindings,
1801
+ exports
1802
+ };
1803
+ }
1804
+ /**
1805
+ * Build trigger context from configured workflow source files.
1806
+ * @param workflowConfig - Workflow file loading configuration
1807
+ * @param authNamespace - Auth service namespace used by workflow trigger options
1808
+ * @returns Module-local workflow and job binding metadata
1809
+ */
1810
+ async function buildTriggerContext(workflowConfig, authNamespace) {
1811
+ const modules = /* @__PURE__ */ new Map();
1812
+ if (!workflowConfig) return {
1813
+ modules,
1814
+ authNamespace
1815
+ };
1816
+ for (const file of loadFilesWithIgnores(workflowConfig)) try {
1817
+ const source = await fs$1.promises.readFile(file, "utf-8");
1818
+ const { program } = parseSync("input.ts", source);
1819
+ modules.set(normalizeFilePath(file), createModuleBindings(program, source));
1820
+ } catch (error) {
1821
+ const errorMessage = error instanceof Error ? error.message : String(error);
1822
+ logger.warn(`Failed to process workflow file ${file}: ${errorMessage}`, { mode: "stream" });
1823
+ }
1824
+ return {
1825
+ modules,
1826
+ authNamespace
1827
+ };
1828
+ }
1829
+ function sortedTargets(bindings) {
1830
+ return [...bindings].toSorted(([a], [b]) => a.localeCompare(b)).map(([binding, target]) => [
1831
+ binding,
1832
+ target.kind,
1833
+ target.name
1834
+ ]);
1835
+ }
1836
+ /**
1837
+ * Serialize trigger context to a deterministic cache input.
1838
+ * @param context - Trigger context to serialize
1839
+ * @returns Deterministic string, or an empty string when context is absent
1840
+ */
1841
+ function serializeTriggerContext(context) {
1842
+ if (!context) return "";
1843
+ const modules = [...context.modules].toSorted(([a], [b]) => a.localeCompare(b)).map(([file, bindings]) => [
1844
+ file,
1845
+ sortedTargets(bindings.localBindings),
1846
+ sortedTargets(bindings.exports)
1847
+ ]);
1848
+ return JSON.stringify(modules) + (context.authNamespace ?? "");
3016
1849
  }
3017
1850
 
3018
1851
  //#endregion
3019
1852
  //#region src/cli/services/workflow/trigger-transformer.ts
3020
- /**
3021
- * Name of the injected runtime normalizer helper. Chosen to be unique enough
3022
- * to avoid collisions with user code.
3023
- */
3024
1853
  const NORMALIZER_IDENTIFIER = "__tailor_normalizeTriggerOptions";
3025
- /**
3026
- * Build the source text of the injected normalizer helper.
3027
- *
3028
- * Expands a plain-string `authInvoker` (machine user name) in the trigger
3029
- * options to the object form `{ namespace, machineUserName }`; any other
3030
- * options value passes through unchanged. The auth namespace is baked in at
3031
- * bundle time.
3032
- * @param authNamespace - Auth service namespace to embed
3033
- * @returns Source line defining the helper
3034
- */
3035
1854
  function buildNormalizerHelperSource(authNamespace) {
3036
1855
  return `const ${NORMALIZER_IDENTIFIER} = (o) => o && typeof o.authInvoker === "string" ? { ...o, authInvoker: { namespace: ${JSON.stringify(authNamespace)}, machineUserName: o.authInvoker } } : o;\n`;
3037
1856
  }
3038
- /**
3039
- * Check if an AST binding pattern (parameter, catch clause, etc.) contains an Identifier with the given name.
3040
- * @param node - AST node to inspect
3041
- * @param name - Identifier name to look for
3042
- * @returns True if the binding pattern contains the name
3043
- */
3044
- function containsBindingName(node, name) {
3045
- if (!node || typeof node !== "object") return false;
3046
- if (node.type === "Identifier" && node.name === name) return true;
3047
- for (const key of Object.keys(node)) {
3048
- const child = node[key];
3049
- if (Array.isArray(child)) {
3050
- if (child.some((c) => containsBindingName(c, name))) return true;
3051
- } else if (child && typeof child === "object") {
3052
- if (containsBindingName(child, name)) return true;
3053
- }
1857
+ function collectBindingNames(node, names) {
1858
+ if (!node || typeof node !== "object") return;
1859
+ switch (node.type) {
1860
+ case "Identifier":
1861
+ names.add(node.name);
1862
+ return;
1863
+ case "ObjectPattern":
1864
+ for (const property of node.properties) collectBindingNames(property.type === "RestElement" ? property.argument : property.value, names);
1865
+ return;
1866
+ case "ArrayPattern":
1867
+ for (const element of node.elements) collectBindingNames(element, names);
1868
+ return;
1869
+ case "AssignmentPattern":
1870
+ collectBindingNames(node.left, names);
1871
+ return;
1872
+ case "RestElement":
1873
+ collectBindingNames(node.argument, names);
1874
+ return;
1875
+ case "TSParameterProperty": collectBindingNames(node.parameter, names);
3054
1876
  }
3055
- return false;
3056
1877
  }
3057
- /**
3058
- * Build a map of reference counts for multiple identifiers in a single AST pass.
3059
- * Scope-aware: references inside functions or catch clauses that shadow the name
3060
- * via parameters are excluded, so only references to the original import binding
3061
- * are counted.
3062
- * Excludes import declarations and property names in non-computed member expressions.
3063
- * @param program - The parsed AST program
3064
- * @param names - Set of identifier names to count
3065
- * @returns Map from identifier name to reference count
3066
- */
3067
- function buildReferenceCountMap(program, names) {
3068
- if (names.size === 0) return /* @__PURE__ */ new Map();
3069
- const counts = /* @__PURE__ */ new Map();
3070
- const shadowDepth = /* @__PURE__ */ new Map();
3071
- for (const name of names) {
3072
- counts.set(name, 0);
3073
- shadowDepth.set(name, 0);
1878
+ function declarationNode(statement) {
1879
+ return statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration" ? statement.declaration : statement;
1880
+ }
1881
+ function collectBlockBindings(statements, names) {
1882
+ for (const statement of statements) {
1883
+ const declaration = declarationNode(statement);
1884
+ if (!declaration) continue;
1885
+ if (declaration.type === "VariableDeclaration") {
1886
+ if (declaration.kind === "var") continue;
1887
+ for (const declarator of declaration.declarations) collectBindingNames(declarator.id, names);
1888
+ } else if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") collectBindingNames(declaration.id, names);
3074
1889
  }
3075
- function walk(node, parentNode, parentKey) {
1890
+ }
1891
+ function collectFunctionVarBindings(root, names) {
1892
+ function walk(node) {
3076
1893
  if (!node || typeof node !== "object") return;
3077
- const nodeType = node.type;
3078
- if (nodeType === "ImportDeclaration") return;
3079
- const shadowedHere = [];
3080
- if (nodeType === "FunctionDeclaration" || nodeType === "FunctionExpression" || nodeType === "ArrowFunctionExpression") {
3081
- const params = node.params;
3082
- if (params) {
3083
- for (const name of names) if (params.some((p) => containsBindingName(p, name))) {
3084
- shadowDepth.set(name, (shadowDepth.get(name) ?? 0) + 1);
3085
- shadowedHere.push(name);
3086
- }
3087
- }
3088
- }
3089
- if (nodeType === "CatchClause") {
3090
- const param = node.param;
3091
- if (param) {
3092
- for (const name of names) if (containsBindingName(param, name)) {
3093
- shadowDepth.set(name, (shadowDepth.get(name) ?? 0) + 1);
3094
- shadowedHere.push(name);
3095
- }
3096
- }
3097
- }
3098
- if (nodeType === "Identifier") {
3099
- const identName = node.name;
3100
- if (identName && names.has(identName) && (shadowDepth.get(identName) ?? 0) === 0) {
3101
- const isMemberProperty = parentNode && parentNode.type === "MemberExpression" && parentKey === "property" && !parentNode.computed;
3102
- const isObjectPropertyKey = parentNode && parentNode.type === "Property" && parentKey === "key" && !parentNode.shorthand && !parentNode.computed;
3103
- if (!isMemberProperty && !isObjectPropertyKey) counts.set(identName, (counts.get(identName) ?? 0) + 1);
3104
- }
3105
- }
1894
+ if (node !== root && (node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression" || node.type === "StaticBlock")) return;
1895
+ if (node.type === "VariableDeclaration" && node.kind === "var") for (const declarator of node.declarations) collectBindingNames(declarator.id, names);
3106
1896
  for (const key of Object.keys(node)) {
1897
+ if (key === "parent") continue;
3107
1898
  const child = node[key];
3108
- if (Array.isArray(child)) child.forEach((c) => walk(c, node, key));
3109
- else if (child && typeof child === "object") walk(child, node, key);
1899
+ if (Array.isArray(child)) for (const item of child) walk(item);
1900
+ else if (child && typeof child === "object") walk(child);
3110
1901
  }
3111
- for (const name of shadowedHere) shadowDepth.set(name, (shadowDepth.get(name) ?? 0) - 1);
3112
1902
  }
3113
- walk(program);
3114
- return counts;
1903
+ walk(root);
3115
1904
  }
3116
- /**
3117
- * Find the text range to remove for a dead default import.
3118
- *
3119
- * - Default-only import (`import wf from "..."`): returns the full declaration range.
3120
- * - Mixed import (`import wf, { helper } from "..."`): returns the range covering
3121
- * the default specifier and trailing comma/whitespace so the result becomes
3122
- * `import { helper } from "..."`.
3123
- * @param program - The parsed AST program
3124
- * @param localName - The local name of the default import
3125
- * @param source - The source code text (used to locate the `{` in mixed imports)
3126
- * @returns Range to remove, or null if the import was not found
3127
- */
3128
- function findDefaultImportRemovalRange(program, localName, source) {
3129
- for (const statement of program.body) {
3130
- if (statement.type !== "ImportDeclaration") continue;
3131
- const importDecl = statement;
3132
- const specifiers = importDecl.specifiers;
3133
- for (const spec of specifiers) {
3134
- if (spec.type !== "ImportDefaultSpecifier") continue;
3135
- const defaultSpec = spec;
3136
- if (defaultSpec.local.name !== localName) continue;
3137
- if (specifiers.length === 1) return {
3138
- start: importDecl.start,
3139
- end: importDecl.end,
3140
- isFullDeclaration: true
3141
- };
3142
- const braceIndex = source.indexOf("{", defaultSpec.end);
3143
- if (braceIndex !== -1) return {
3144
- start: defaultSpec.start,
3145
- end: braceIndex,
3146
- isFullDeclaration: false
3147
- };
3148
- return null;
3149
- }
1905
+ function collectScopeBindings(node) {
1906
+ const names = /* @__PURE__ */ new Set();
1907
+ if (node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") {
1908
+ collectBindingNames(node.id, names);
1909
+ for (const parameter of node.params) collectBindingNames(parameter, names);
1910
+ collectFunctionVarBindings(node, names);
1911
+ return names;
1912
+ }
1913
+ if (node.type === "BlockStatement") {
1914
+ collectBlockBindings(node.body, names);
1915
+ return names;
1916
+ }
1917
+ if (node.type === "CatchClause") {
1918
+ collectBindingNames(node.param, names);
1919
+ return names;
1920
+ }
1921
+ if (node.type === "ForStatement" || node.type === "ForInStatement" || node.type === "ForOfStatement") {
1922
+ const declaration = node.init ?? node.left;
1923
+ if (declaration?.type === "VariableDeclaration" && declaration.kind !== "var") for (const declarator of declaration.declarations) collectBindingNames(declarator.id, names);
1924
+ return names;
3150
1925
  }
3151
- return null;
3152
1926
  }
3153
- /**
3154
- * Detect .trigger() calls for known workflows and jobs
3155
- * Only detects calls where the identifier is in workflowNames or jobNames
3156
- * @param program - The parsed AST program
3157
- * @param sourceText - The source code text
3158
- * @param workflowNames - Set of known workflow identifier names
3159
- * @param jobNames - Set of known job identifier names
3160
- * @returns Detected trigger call metadata
3161
- */
3162
- function detectExtendedTriggerCalls(program, sourceText, workflowNames, jobNames) {
3163
- const calls = [];
3164
- function walk(node) {
3165
- if (!node || typeof node !== "object") return;
3166
- const triggerCall = getTriggerCallInfo(node, sourceText);
3167
- if (triggerCall) {
3168
- const isWorkflow = workflowNames.has(triggerCall.identifierName);
3169
- const isJob = jobNames.has(triggerCall.identifierName);
3170
- if (isWorkflow) calls.push({
3171
- kind: "workflow",
3172
- identifierName: triggerCall.identifierName,
3173
- callRange: triggerCall.callRange,
3174
- argsText: triggerCall.argsText,
3175
- optionsText: triggerCall.optionsText
3176
- });
3177
- else if (isJob) calls.push({
3178
- kind: "job",
3179
- identifierName: triggerCall.identifierName,
3180
- callRange: triggerCall.callRange,
3181
- argsText: triggerCall.argsText,
3182
- optionsText: triggerCall.optionsText
3183
- });
3184
- }
1927
+ function addShadowedBindings(shadowedNames, bindings, targetNames) {
1928
+ if (!bindings) return shadowedNames;
1929
+ const relevantBindings = [...bindings].filter((name) => targetNames.has(name));
1930
+ return relevantBindings.length === 0 ? shadowedNames : /* @__PURE__ */ new Set([...shadowedNames, ...relevantBindings]);
1931
+ }
1932
+ function walkBindingAware(program, targetNames, visitor) {
1933
+ function walk(node, shadowedNames, parentNode, parentKey) {
1934
+ if (!node || typeof node !== "object" || node.type === "ImportDeclaration") return;
1935
+ const nestedShadowedNames = node.type === "Program" ? shadowedNames : addShadowedBindings(shadowedNames, collectScopeBindings(node), targetNames);
1936
+ visitor(node, nestedShadowedNames, parentNode, parentKey);
3185
1937
  for (const key of Object.keys(node)) {
1938
+ if (key === "parent") continue;
3186
1939
  const child = node[key];
3187
- if (Array.isArray(child)) child.forEach((c) => walk(c));
3188
- else if (child && typeof child === "object") walk(child);
1940
+ if (Array.isArray(child)) for (const item of child) walk(item, nestedShadowedNames, node, key);
1941
+ else if (child && typeof child === "object") walk(child, nestedShadowedNames, node, key);
3189
1942
  }
3190
1943
  }
3191
- walk(program);
1944
+ walk(program, /* @__PURE__ */ new Set());
1945
+ }
1946
+ function resolveRelativeImport(context, currentFilePath, importSource) {
1947
+ if (!importSource.startsWith(".")) return void 0;
1948
+ const currentDirectory = path.dirname(currentFilePath.replace(/[?#].*$/, ""));
1949
+ const modulePath = normalizeFilePath(path.resolve(currentDirectory, importSource));
1950
+ return context.modules.get(modulePath) ?? context.modules.get(path.join(modulePath, "index"));
1951
+ }
1952
+ function collectLocalTargets(program, context, currentFilePath) {
1953
+ const targets = /* @__PURE__ */ new Map();
1954
+ const currentModule = context.modules.get(normalizeFilePath(currentFilePath));
1955
+ if (currentModule) for (const [localName, target] of currentModule.localBindings) targets.set(localName, target);
1956
+ for (const statement of program.body) {
1957
+ if (statement.type !== "ImportDeclaration" || statement.importKind === "type") continue;
1958
+ const importSource = statement.source.value;
1959
+ if (typeof importSource !== "string") continue;
1960
+ const importedModule = resolveRelativeImport(context, currentFilePath, importSource);
1961
+ if (!importedModule) continue;
1962
+ for (const specifier of statement.specifiers) {
1963
+ if (specifier.type === "ImportNamespaceSpecifier") continue;
1964
+ if (specifier.type === "ImportSpecifier" && specifier.importKind === "type") continue;
1965
+ const importedName = specifier.type === "ImportDefaultSpecifier" ? "default" : getModuleExportName(specifier.imported);
1966
+ if (!importedName) continue;
1967
+ const target = importedModule.exports.get(importedName);
1968
+ if (!target) continue;
1969
+ targets.set(specifier.local.name, target);
1970
+ }
1971
+ }
1972
+ return targets;
1973
+ }
1974
+ function detectTriggerCallsWithTargets(program, sourceText, targets) {
1975
+ const calls = [];
1976
+ walkBindingAware(program, new Set(targets.keys()), (node, shadowedNames) => {
1977
+ const triggerCall = getTriggerCallInfo(node, sourceText);
1978
+ if (!triggerCall || shadowedNames.has(triggerCall.identifierName)) return;
1979
+ const target = targets.get(triggerCall.identifierName);
1980
+ if (target) calls.push({
1981
+ ...triggerCall,
1982
+ kind: target.kind,
1983
+ targetName: target.name
1984
+ });
1985
+ });
3192
1986
  return calls;
3193
1987
  }
3194
- /**
3195
- * Transform trigger calls for resolver/executor/workflow functions
3196
- * Handles job.trigger() and workflow.trigger() calls
3197
- * @param source - The source code to transform
3198
- * @param workflowNameMap - Map from variable name to workflow name
3199
- * @param jobNameMap - Map from variable name to job name
3200
- * @param workflowFileMap - Map from file path (without extension) to workflow name for default exports
3201
- * @param currentFilePath - Path of the current file being transformed (for resolving relative imports)
3202
- * @param authNamespace - Auth service namespace used to expand string-literal `authInvoker` to object form
3203
- * @returns Transformed source code with trigger calls rewritten
3204
- */
3205
- function transformFunctionTriggers(source, workflowNameMap, jobNameMap, workflowFileMap, currentFilePath, authNamespace) {
1988
+ function detectResolvedTriggerCalls(program, sourceText, context, currentFilePath) {
1989
+ return detectTriggerCallsWithTargets(program, sourceText, collectLocalTargets(program, context, currentFilePath));
1990
+ }
1991
+ function transformFunctionTriggers(source, triggerContext, currentFilePath) {
3206
1992
  const { program } = parseSync("input.ts", source);
3207
- const localWorkflowNameMap = new Map(workflowNameMap);
3208
- const workflowDefaultImportNames = /* @__PURE__ */ new Set();
3209
- if (workflowFileMap && currentFilePath) {
3210
- const defaultImports = detectDefaultImports(program);
3211
- const currentDir = currentFilePath.replace(/[/\\][^/\\]+$/, "");
3212
- for (const [localName, importSource] of defaultImports) {
3213
- if (!importSource.startsWith(".")) continue;
3214
- const resolvedPath = resolvePath(currentDir, importSource).replace(/\.(ts|mts|cts|js|mjs|cjs)$/, "");
3215
- const workflowName = workflowFileMap.get(resolvedPath);
3216
- if (workflowName) {
3217
- localWorkflowNameMap.set(localName, workflowName);
3218
- workflowDefaultImportNames.add(localName);
3219
- }
3220
- }
3221
- }
3222
- const allTriggerCalls = detectExtendedTriggerCalls(program, source, new Set(localWorkflowNameMap.keys()), new Set(jobNameMap.keys()));
1993
+ const localTargets = collectLocalTargets(program, triggerContext, currentFilePath);
1994
+ const { authNamespace } = triggerContext;
1995
+ const allTriggerCalls = detectTriggerCallsWithTargets(program, source, localTargets);
3223
1996
  const nestedTriggerCalls = [];
3224
1997
  const triggerCalls = allTriggerCalls.filter((call) => {
3225
1998
  const parent = allTriggerCalls.find((other) => other !== call && other.callRange.start <= call.callRange.start && call.callRange.end <= other.callRange.end);
3226
- if (parent) {
3227
- nestedTriggerCalls.push({
3228
- call,
3229
- parent
3230
- });
3231
- return false;
3232
- }
3233
- return true;
1999
+ if (!parent) return true;
2000
+ nestedTriggerCalls.push({
2001
+ call,
2002
+ parent
2003
+ });
2004
+ return false;
3234
2005
  });
3235
2006
  for (const { call, parent } of nestedTriggerCalls) logger.warn(`Nested trigger call "${call.identifierName}.trigger(...)" inside "${parent.identifierName}.trigger(...)" cannot be converted. Move it to a separate statement and pass the result instead.`);
3236
2007
  const replacements = [];
3237
2008
  let needsNormalizerHelper = false;
3238
- const transformedCallsPerIdentifier = /* @__PURE__ */ new Map();
3239
- for (const call of triggerCalls) if (call.kind === "workflow") {
3240
- const workflowName = localWorkflowNameMap.get(call.identifierName);
3241
- if (workflowName) {
2009
+ for (const call of triggerCalls) {
2010
+ let transformedCall;
2011
+ if (call.kind === "workflow") {
3242
2012
  let optionsPart = "";
3243
2013
  if (call.optionsText !== void 0) if (authNamespace) {
3244
2014
  optionsPart = `, ${NORMALIZER_IDENTIFIER}(${call.optionsText})`;
3245
2015
  needsNormalizerHelper = true;
3246
2016
  } else optionsPart = `, ${call.optionsText}`;
3247
- const transformedCall = `tailor.workflow.triggerWorkflow("${workflowName}", ${call.argsText || "undefined"}${optionsPart})`;
3248
- replacements.push({
3249
- start: call.callRange.start,
3250
- end: call.callRange.end,
3251
- text: transformedCall
3252
- });
3253
- transformedCallsPerIdentifier.set(call.identifierName, (transformedCallsPerIdentifier.get(call.identifierName) ?? 0) + 1);
3254
- }
3255
- } else {
3256
- const jobName = jobNameMap.get(call.identifierName);
3257
- if (jobName) {
2017
+ transformedCall = `tailor.workflow.triggerWorkflow(${JSON.stringify(call.targetName)}, ${call.argsText || "undefined"}${optionsPart})`;
2018
+ } else {
3258
2019
  const optionsPart = call.optionsText !== void 0 ? `, ${call.optionsText}` : "";
3259
- const transformedCall = `(async () => tailor.workflow.triggerJobFunction("${jobName}", ${call.argsText || "undefined"}${optionsPart}))()`;
3260
- replacements.push({
3261
- start: call.callRange.start,
3262
- end: call.callRange.end,
3263
- text: transformedCall
3264
- });
3265
- transformedCallsPerIdentifier.set(call.identifierName, (transformedCallsPerIdentifier.get(call.identifierName) ?? 0) + 1);
3266
- }
3267
- }
3268
- const refCounts = buildReferenceCountMap(program, workflowDefaultImportNames);
3269
- for (const localName of workflowDefaultImportNames) {
3270
- const transformedCount = transformedCallsPerIdentifier.get(localName) ?? 0;
3271
- const refCount = refCounts.get(localName) ?? 0;
3272
- if (refCount === 0 || transformedCount >= refCount) {
3273
- const removal = findDefaultImportRemovalRange(program, localName, source);
3274
- if (removal) replacements.push({
3275
- start: removal.start,
3276
- end: removal.isFullDeclaration ? findStatementEnd(source, removal.end) : removal.end,
3277
- text: ""
3278
- });
2020
+ transformedCall = `(async () => tailor.workflow.triggerJobFunction(${JSON.stringify(call.targetName)}, ${call.argsText || "undefined"}${optionsPart}))()`;
3279
2021
  }
2022
+ replacements.push({
2023
+ start: call.callRange.start,
2024
+ end: call.callRange.end,
2025
+ text: transformedCall
2026
+ });
3280
2027
  }
3281
2028
  const transformed = applyReplacements(source, replacements);
3282
- if (needsNormalizerHelper && authNamespace) return buildNormalizerHelperSource(authNamespace) + transformed;
3283
- return transformed;
3284
- }
3285
-
3286
- //#endregion
3287
- //#region src/cli/shared/trigger-context.ts
3288
- /**
3289
- * Normalize a file path by removing extension and resolving to absolute path
3290
- * @param filePath - File path to normalize
3291
- * @returns Normalized absolute path without extension
3292
- */
3293
- function normalizeFilePath(filePath) {
3294
- const absolutePath = path.resolve(filePath);
3295
- const ext = path.extname(absolutePath);
3296
- return absolutePath.slice(0, -ext.length);
3297
- }
3298
- /**
3299
- * Build trigger context from workflow configuration
3300
- * Scans workflow files to collect workflow and job mappings
3301
- * @param workflowConfig - Workflow file loading configuration
3302
- * @param authNamespace - Auth service namespace (optional, used for string-literal authInvoker expansion)
3303
- * @returns Trigger context built from workflow sources
3304
- */
3305
- async function buildTriggerContext(workflowConfig, authNamespace) {
3306
- const workflowNameMap = /* @__PURE__ */ new Map();
3307
- const jobNameMap = /* @__PURE__ */ new Map();
3308
- const workflowFileMap = /* @__PURE__ */ new Map();
3309
- if (!workflowConfig) return {
3310
- workflowNameMap,
3311
- jobNameMap,
3312
- workflowFileMap,
3313
- authNamespace
3314
- };
3315
- const workflowFiles = loadFilesWithIgnores(workflowConfig);
3316
- for (const file of workflowFiles) try {
3317
- const source = await fs$1.promises.readFile(file, "utf-8");
3318
- const { program } = parseSync("input.ts", source);
3319
- const workflows = findAllWorkflows(program, source);
3320
- const workflowMap = buildWorkflowNameMap(workflows);
3321
- for (const [exportName, workflowName] of workflowMap) workflowNameMap.set(exportName, workflowName);
3322
- for (const workflow of workflows) if (workflow.isDefaultExport) {
3323
- const normalizedPath = normalizeFilePath(file);
3324
- workflowFileMap.set(normalizedPath, workflow.name);
3325
- }
3326
- const jobMap = buildJobNameMap(findAllJobs(program, source));
3327
- for (const [exportName, jobName] of jobMap) jobNameMap.set(exportName, jobName);
3328
- } catch (error) {
3329
- const errorMessage = error instanceof Error ? error.message : String(error);
3330
- logger.warn(`Failed to process workflow file ${file}: ${errorMessage}`, { mode: "stream" });
3331
- continue;
3332
- }
3333
- return {
3334
- workflowNameMap,
3335
- jobNameMap,
3336
- workflowFileMap,
3337
- authNamespace
3338
- };
3339
- }
3340
- function sortedMapToJson(m) {
3341
- return JSON.stringify([...m.entries()].toSorted(([a], [b]) => a.localeCompare(b)));
2029
+ return needsNormalizerHelper && authNamespace ? buildNormalizerHelperSource(authNamespace) + transformed : transformed;
3342
2030
  }
3343
- /**
3344
- * Serialize trigger context to a deterministic string for cache hashing.
3345
- * Returns an empty string if no context is provided.
3346
- * @param ctx - Trigger context to serialize
3347
- * @returns Deterministic string representation
3348
- */
3349
- function serializeTriggerContext(ctx) {
3350
- if (!ctx) return "";
3351
- return sortedMapToJson(ctx.workflowNameMap) + sortedMapToJson(ctx.jobNameMap) + sortedMapToJson(ctx.workflowFileMap) + (ctx.authNamespace ?? "");
3352
- }
3353
- /**
3354
- * Create a rolldown plugin for transforming trigger calls
3355
- * Returns undefined if no trigger context is provided
3356
- * @param triggerContext - Trigger context to use for transformations
3357
- * @returns Rolldown plugin or undefined when no context
3358
- */
3359
2031
  function createTriggerTransformPlugin(triggerContext) {
3360
- if (!triggerContext) return;
2032
+ if (!triggerContext) return void 0;
3361
2033
  return {
3362
2034
  name: "trigger-transform",
3363
2035
  transform: {
3364
2036
  filter: { id: { include: [/\.(ts|mts|cts|js|mjs|cjs)$/] } },
3365
2037
  handler(code, id) {
3366
2038
  if (!code.includes(".trigger(")) return null;
3367
- return { code: transformFunctionTriggers(code, triggerContext.workflowNameMap, triggerContext.jobNameMap, triggerContext.workflowFileMap, id, triggerContext.authNamespace) };
2039
+ return { code: transformFunctionTriggers(code, triggerContext, id) };
3368
2040
  }
3369
2041
  }
3370
2042
  };
3371
2043
  }
3372
2044
 
2045
+ //#endregion
2046
+ //#region src/cli/shared/bundle-log-level.ts
2047
+ const INFO_LEVEL_CONSOLE_METHODS = [
2048
+ "console.info",
2049
+ "console.table",
2050
+ "console.dir",
2051
+ "console.dirxml",
2052
+ "console.count",
2053
+ "console.countReset",
2054
+ "console.time",
2055
+ "console.timeLog",
2056
+ "console.timeEnd",
2057
+ "console.group",
2058
+ "console.groupCollapsed",
2059
+ "console.groupEnd",
2060
+ "console.clear"
2061
+ ];
2062
+ const DEBUG_LEVEL_CONSOLE_METHODS = [
2063
+ "console.debug",
2064
+ "console.log",
2065
+ "console.trace"
2066
+ ];
2067
+ const WARN_LEVEL_CONSOLE_METHODS = ["console.warn"];
2068
+ const ERROR_LEVEL_CONSOLE_METHODS = ["console.error"];
2069
+ const MANUAL_PURE_FUNCTIONS_BY_LOG_LEVEL = {
2070
+ DEBUG: [],
2071
+ INFO: DEBUG_LEVEL_CONSOLE_METHODS,
2072
+ WARN: [...DEBUG_LEVEL_CONSOLE_METHODS, ...INFO_LEVEL_CONSOLE_METHODS],
2073
+ ERROR: [
2074
+ ...DEBUG_LEVEL_CONSOLE_METHODS,
2075
+ ...INFO_LEVEL_CONSOLE_METHODS,
2076
+ ...WARN_LEVEL_CONSOLE_METHODS
2077
+ ],
2078
+ SILENT: [
2079
+ ...DEBUG_LEVEL_CONSOLE_METHODS,
2080
+ ...INFO_LEVEL_CONSOLE_METHODS,
2081
+ ...WARN_LEVEL_CONSOLE_METHODS,
2082
+ ...ERROR_LEVEL_CONSOLE_METHODS
2083
+ ]
2084
+ };
2085
+ function normalizeBundleLogLevel(value) {
2086
+ const normalized = value.trim().toUpperCase();
2087
+ return isLogLevel(normalized) ? normalized : void 0;
2088
+ }
2089
+ function resolveBundleLogLevel(configValue) {
2090
+ if (configValue === void 0) return "DEBUG";
2091
+ const resolved = normalizeBundleLogLevel(configValue);
2092
+ if (resolved) return resolved;
2093
+ throw new Error(`Invalid logLevel "${configValue}". Expected one of: ${LOG_LEVELS.join(", ")}`);
2094
+ }
2095
+ function manualPureFunctionsForLogLevel(logLevel) {
2096
+ return MANUAL_PURE_FUNCTIONS_BY_LOG_LEVEL[logLevel];
2097
+ }
2098
+ function createLogLevelTreeshakeOptions(logLevel) {
2099
+ const manualPureFunctions = manualPureFunctionsForLogLevel(logLevel);
2100
+ return manualPureFunctions.length > 0 ? { manualPureFunctions } : {};
2101
+ }
2102
+
2103
+ //#endregion
2104
+ //#region src/cli/shared/function-treeshake.ts
2105
+ const BASE_FUNCTION_TREESHAKE_OPTIONS = {
2106
+ moduleSideEffects: false,
2107
+ annotations: true,
2108
+ unknownGlobalSideEffects: false
2109
+ };
2110
+ function mergeFunctionTreeshakeOptions(fragments) {
2111
+ const merged = {};
2112
+ const manualPureFunctions = /* @__PURE__ */ new Set();
2113
+ for (const fragment of fragments) {
2114
+ Object.assign(merged, fragment);
2115
+ for (const name of fragment.manualPureFunctions ?? []) manualPureFunctions.add(name);
2116
+ }
2117
+ if (manualPureFunctions.size > 0) merged.manualPureFunctions = [...manualPureFunctions];
2118
+ else delete merged.manualPureFunctions;
2119
+ return merged;
2120
+ }
2121
+ function composeFunctionTreeshakeOptions(fragments = []) {
2122
+ return mergeFunctionTreeshakeOptions([BASE_FUNCTION_TREESHAKE_OPTIONS, ...fragments]);
2123
+ }
2124
+
2125
+ //#endregion
2126
+ //#region src/cli/shared/platform-bundle-plugin.ts
2127
+ const GATE = /(?<![\w$.])process\.env\.TAILOR_PLATFORM_BUNDLE\b/g;
2128
+ const platformBundleDefinePlugin = {
2129
+ name: "tailor-platform-bundle-define",
2130
+ transform(code) {
2131
+ if (!code.includes("process.env.TAILOR_PLATFORM_BUNDLE")) return null;
2132
+ return { code: code.replace(GATE, "true") };
2133
+ }
2134
+ };
2135
+
3373
2136
  //#endregion
3374
2137
  //#region src/cli/services/auth/bundler.ts
3375
2138
  /**
@@ -5723,36 +4486,15 @@ function assertUniqueResolverNames(resolvers, namespace) {
5723
4486
  */
5724
4487
  function findVariableDeclarationsByName(program) {
5725
4488
  const declarations = /* @__PURE__ */ new Map();
5726
- function walk(node) {
5727
- if (!node || typeof node !== "object") return;
5728
- const nodeType = node.type;
5729
- if (nodeType === "VariableDeclaration") {
5730
- const varDecl = node;
5731
- for (const decl of varDecl.declarations) if (decl.id.type === "Identifier" && decl.id.name) {
5732
- if (!declarations.has(decl.id.name)) declarations.set(decl.id.name, {
5733
- start: varDecl.start,
5734
- end: varDecl.end
5735
- });
5736
- }
5737
- }
5738
- if (nodeType === "ExportNamedDeclaration") {
5739
- const exportDecl = node;
5740
- const declaration = exportDecl.declaration;
5741
- if (declaration?.type === "VariableDeclaration") {
5742
- const varDecl = declaration;
5743
- for (const decl of varDecl.declarations) if (decl.id.type === "Identifier" && decl.id.name) declarations.set(decl.id.name, {
5744
- start: exportDecl.start,
5745
- end: exportDecl.end
5746
- });
5747
- }
5748
- }
5749
- for (const key of Object.keys(node)) {
5750
- const child = node[key];
5751
- if (Array.isArray(child)) child.forEach((c) => walk(c));
5752
- else if (child && typeof child === "object") walk(child);
5753
- }
4489
+ for (const statement of program.body) {
4490
+ const declaration = statement.type === "ExportNamedDeclaration" ? statement.declaration : statement;
4491
+ if (declaration?.type !== "VariableDeclaration") continue;
4492
+ const variableDeclaration = declaration;
4493
+ for (const declarator of variableDeclaration.declarations) if (declarator.id.type === "Identifier") declarations.set(declarator.id.name, {
4494
+ start: statement.start,
4495
+ end: statement.end
4496
+ });
5754
4497
  }
5755
- walk(program);
5756
4498
  return declarations;
5757
4499
  }
5758
4500
  /**
@@ -5779,48 +4521,32 @@ function findWorkflowDefaultExport(program) {
5779
4521
  }
5780
4522
  /**
5781
4523
  * Transform workflow source code
5782
- * - Transform .trigger() calls to tailor.workflow.triggerJobFunction()
5783
4524
  * - Other jobs: remove entire variable declaration
5784
4525
  * @param source - The source code to transform
5785
4526
  * @param targetJobName - The name of the target job (from job config)
5786
4527
  * @param targetJobExportName - The export name of the target job (optional, for enhanced detection)
5787
4528
  * @param otherJobExportNames - Export names of other jobs to remove (optional, for enhanced detection)
5788
- * @param allJobsMap - Map from export name to job name for trigger transformation (optional)
5789
4529
  * @returns Transformed workflow source code
5790
4530
  */
5791
- function transformWorkflowSource(source, targetJobName, targetJobExportName, otherJobExportNames, allJobsMap) {
4531
+ function transformWorkflowSource(source, targetJobName, targetJobExportName, otherJobExportNames) {
5792
4532
  const { program } = parseSync("input.ts", source);
5793
4533
  const detectedJobs = findAllJobs(program, source);
5794
4534
  if (!detectedJobs.some((j) => j.name === targetJobName)) return source;
5795
- const jobNameMap = allJobsMap ?? buildJobNameMap(detectedJobs);
5796
4535
  const allDeclarations = findVariableDeclarationsByName(program);
5797
- const triggerCalls = detectTriggerCalls(program, source);
5798
4536
  const replacements = [];
5799
- const removedRanges = [];
5800
- const isInsideRemovedRange = (pos) => {
5801
- return removedRanges.some((r) => pos >= r.start && pos < r.end);
5802
- };
5803
- const isAlreadyMarkedForRemoval = (start) => {
5804
- return removedRanges.some((r) => r.start === start);
5805
- };
4537
+ const removedStarts = /* @__PURE__ */ new Set();
5806
4538
  for (const job of detectedJobs) {
5807
4539
  if (job.name === targetJobName) continue;
5808
- if (job.statementRange && !isAlreadyMarkedForRemoval(job.statementRange.start)) {
4540
+ if (job.statementRange && !removedStarts.has(job.statementRange.start)) {
5809
4541
  const endPos = findStatementEnd(source, job.statementRange.end);
5810
- removedRanges.push({
5811
- start: job.statementRange.start,
5812
- end: endPos
5813
- });
4542
+ removedStarts.add(job.statementRange.start);
5814
4543
  replacements.push({
5815
4544
  start: job.statementRange.start,
5816
4545
  end: endPos,
5817
4546
  text: ""
5818
4547
  });
5819
4548
  } else if (!job.statementRange) {
5820
- removedRanges.push({
5821
- start: job.bodyValueRange.start,
5822
- end: job.bodyValueRange.end
5823
- });
4549
+ removedStarts.add(job.bodyValueRange.start);
5824
4550
  replacements.push({
5825
4551
  start: job.bodyValueRange.start,
5826
4552
  end: job.bodyValueRange.end,
@@ -5831,12 +4557,9 @@ function transformWorkflowSource(source, targetJobName, targetJobExportName, oth
5831
4557
  if (otherJobExportNames) for (const exportName of otherJobExportNames) {
5832
4558
  if (exportName === targetJobExportName) continue;
5833
4559
  const declRange = allDeclarations.get(exportName);
5834
- if (declRange && !isAlreadyMarkedForRemoval(declRange.start)) {
4560
+ if (declRange && !removedStarts.has(declRange.start)) {
5835
4561
  const endPos = findStatementEnd(source, declRange.end);
5836
- removedRanges.push({
5837
- start: declRange.start,
5838
- end: endPos
5839
- });
4562
+ removedStarts.add(declRange.start);
5840
4563
  replacements.push({
5841
4564
  start: declRange.start,
5842
4565
  end: endPos,
@@ -5845,31 +4568,15 @@ function transformWorkflowSource(source, targetJobName, targetJobExportName, oth
5845
4568
  }
5846
4569
  }
5847
4570
  const workflowExport = findWorkflowDefaultExport(program);
5848
- if (workflowExport && !isAlreadyMarkedForRemoval(workflowExport.start)) {
4571
+ if (workflowExport && !removedStarts.has(workflowExport.start)) {
5849
4572
  const endPos = findStatementEnd(source, workflowExport.end);
5850
- removedRanges.push({
5851
- start: workflowExport.start,
5852
- end: endPos
5853
- });
4573
+ removedStarts.add(workflowExport.start);
5854
4574
  replacements.push({
5855
4575
  start: workflowExport.start,
5856
4576
  end: endPos,
5857
4577
  text: ""
5858
4578
  });
5859
4579
  }
5860
- for (const call of triggerCalls) {
5861
- if (isInsideRemovedRange(call.callRange.start)) continue;
5862
- const jobName = jobNameMap.get(call.identifierName);
5863
- if (jobName) {
5864
- const optionsPart = call.optionsText !== void 0 ? `, ${call.optionsText}` : "";
5865
- const transformedCall = `(async () => tailor.workflow.triggerJobFunction("${jobName}", ${call.argsText || "undefined"}${optionsPart}))()`;
5866
- replacements.push({
5867
- start: call.callRange.start,
5868
- end: call.callRange.end,
5869
- text: transformedCall
5870
- });
5871
- }
5872
- }
5873
4580
  return applyReplacements(source, replacements);
5874
4581
  }
5875
4582
 
@@ -5911,7 +4618,7 @@ async function bundleWorkflowJobs(allJobs, mainJobNames, env = {}, triggerContex
5911
4618
  bundledCode: /* @__PURE__ */ new Map()
5912
4619
  };
5913
4620
  }
5914
- const { usedJobs, mainJobDeps } = await filterUsedJobs(allJobs, mainJobNames);
4621
+ const { usedJobs, mainJobDeps } = await filterUsedJobs(allJobs, mainJobNames, triggerContext);
5915
4622
  logger.newline();
5916
4623
  logger.log(`Bundling ${styles.highlight(usedJobs.length.toString())} files for ${styles.info("\"workflow-job\"")}`);
5917
4624
  const outputDir = path.resolve(getDistDir(), "workflow-jobs");
@@ -5945,9 +4652,10 @@ async function bundleWorkflowJobs(allJobs, mainJobNames, env = {}, triggerContex
5945
4652
  * Also returns a map of mainJob -> all jobs it depends on (for metadata).
5946
4653
  * @param allJobs - All available job infos
5947
4654
  * @param mainJobNames - Names of main jobs
4655
+ * @param triggerContext - Module binding metadata for resolving trigger targets
5948
4656
  * @returns Used jobs and main job dependency map
5949
4657
  */
5950
- async function filterUsedJobs(allJobs, mainJobNames) {
4658
+ async function filterUsedJobs(allJobs, mainJobNames, triggerContext) {
5951
4659
  if (allJobs.length === 0 || mainJobNames.length === 0) return {
5952
4660
  usedJobs: [],
5953
4661
  mainJobDeps: {}
@@ -5958,26 +4666,19 @@ async function filterUsedJobs(allJobs, mainJobNames) {
5958
4666
  existing.push(job);
5959
4667
  jobsBySourceFile.set(job.sourceFile, existing);
5960
4668
  }
5961
- const exportNameToJobName = /* @__PURE__ */ new Map();
5962
- for (const job of allJobs) exportNameToJobName.set(job.exportName, job.name);
5963
4669
  const dependencies = /* @__PURE__ */ new Map();
5964
4670
  const fileResults = await Promise.all(Array.from(jobsBySourceFile.entries()).map(async ([sourceFile, jobs]) => {
5965
4671
  try {
5966
4672
  const source = await fs$1.promises.readFile(sourceFile, "utf-8");
5967
4673
  const { program } = parseSync("input.ts", source);
5968
4674
  const detectedJobs = findAllJobs(program, source);
5969
- const localExportNameToJobName = /* @__PURE__ */ new Map();
5970
- for (const detected of detectedJobs) if (detected.exportName) localExportNameToJobName.set(detected.exportName, detected.name);
5971
- const triggerCalls = detectTriggerCalls(program, source);
4675
+ const triggerCalls = detectResolvedTriggerCalls(program, source, triggerContext, sourceFile);
5972
4676
  const jobDependencies = [];
5973
4677
  for (const job of jobs) {
5974
4678
  const detectedJob = detectedJobs.find((d) => d.name === job.name);
5975
4679
  if (!detectedJob) continue;
5976
4680
  const jobDeps = /* @__PURE__ */ new Set();
5977
- for (const call of triggerCalls) if (call.callRange.start >= detectedJob.bodyValueRange.start && call.callRange.end <= detectedJob.bodyValueRange.end) {
5978
- const triggeredJobName = localExportNameToJobName.get(call.identifierName) || exportNameToJobName.get(call.identifierName);
5979
- if (triggeredJobName) jobDeps.add(triggeredJobName);
5980
- }
4681
+ for (const call of triggerCalls) if (call.kind === "job" && call.callRange.start >= detectedJob.bodyValueRange.start && call.callRange.end <= detectedJob.bodyValueRange.end) jobDeps.add(call.targetName);
5981
4682
  if (jobDeps.size > 0) jobDependencies.push({
5982
4683
  jobName: job.name,
5983
4684
  deps: jobDeps
@@ -6038,10 +4739,8 @@ async function bundleSingleJob(job, allJobs, outputDir, tsconfig, env, triggerCo
6038
4739
  }
6039
4740
  `;
6040
4741
  fs$1.writeFileSync(entryPath, entryContent);
6041
- const otherJobExportNames = allJobs.filter((j) => j.name !== job.name).map((j) => j.exportName);
6042
- const allJobsMap = /* @__PURE__ */ new Map();
6043
- for (const j of allJobs) allJobsMap.set(j.exportName, j.name);
6044
4742
  const resolvedSourceFile = safeRealpath(job.sourceFile);
4743
+ const otherJobExportNames = allJobs.filter((candidate) => candidate.name !== job.name && safeRealpath(candidate.sourceFile) === resolvedSourceFile).map((j) => j.exportName);
6045
4744
  const plugins = [
6046
4745
  {
6047
4746
  name: "workflow-transform",
@@ -6050,8 +4749,8 @@ async function bundleSingleJob(job, allJobs, outputDir, tsconfig, env, triggerCo
6050
4749
  handler(code, id) {
6051
4750
  if (!code.includes("createWorkflowJob") && !code.includes("createWorkflow") && !code.includes(".trigger(")) return null;
6052
4751
  let transformed = code;
6053
- if (safeRealpath(id) === resolvedSourceFile) transformed = transformWorkflowSource(code, job.name, job.exportName, otherJobExportNames, allJobsMap);
6054
- if (triggerContext && transformed.includes(".trigger(")) transformed = transformFunctionTriggers(transformed, triggerContext.workflowNameMap, triggerContext.jobNameMap, triggerContext.workflowFileMap, id, triggerContext.authNamespace);
4752
+ if (safeRealpath(id) === resolvedSourceFile) transformed = transformWorkflowSource(code, job.name, job.exportName, otherJobExportNames);
4753
+ if (transformed.includes(".trigger(")) transformed = transformFunctionTriggers(transformed, triggerContext, id);
6055
4754
  if (transformed === code) return null;
6056
4755
  return { code: transformed };
6057
4756
  }
@@ -6846,5 +5545,5 @@ async function loadApplication(params) {
6846
5545
  }
6847
5546
 
6848
5547
  //#endregion
6849
- export { getOAuth2ClientId as $, hasAnyUserTokenEntry as A, readPlatformConfig as B, createBundleCache as C, toPageDirection as Ct, loadConfig as D, hashFile as E, loadMachineUserName as F, defaultPlatformBaseUrl as G, saveUserTokens as H, loadPlatformClientConfig as I, fetchMachineUserToken as J, fetchAll as K, loadStoredUserTokens as L, loadAccessToken as M, loadConfigPath as N, deleteUserTokens as O, loadConsoleBaseUrl as P, getConsoleBaseUrl as Q, loadWorkspaceId as R, hasGenerationHooks as S, resolveMachineUserInputSource as St, hashContent as T, writePlatformConfig as U, resolveUserTokenKey as V, closeConnectionPool as W, fetchPlatformMachineUserToken as X, fetchPaged as Y, fetchUserInfo as Z, platformBundleDefinePlugin as _, organizationArgs as _t, resolveInlineSourcemap as a, resolveStaticWebsiteUrls as at, resolveBundleLogLevel as b, parseDuration as bt, ResolverSchema as c, configArg as ct, buildExecutorArgsExpr as d, durationArg as dt, getOrNull as et, buildResolverOperationHookExpr as f, folderArgs as ft, stringifyFunction as g, orderArg as gt, TailorDBTypeSchema as h, nonNegativeIntArg as ht, resolverBundleKey as i, isDefaultPlatform as it, hasUserTokenEntry as j, fetchLatestToken as k, HTTP_METHODS as l, confirmationArgs as lt, assertUniqueTailorDBTypeNamesWithExternal as m, multiConfigArg as mt, generatePluginFilesIfNeeded as n, initOAuth2Client as nt, WorkflowJobFunctionExecutionPolicySchema as o, byName as ot, assertUniqueLocalTailorDBTypeNames as p, isVerbose as pt, fetchAllTolerant as q, loadApplication as r, initOperatorClient as rt, WorkflowJobSchema as s, commonArgs as st, defineApplication as t, getPlatformBaseUrl as tt, INVOKER_EXPR as u, deploymentArgs as ut, composeFunctionTreeshakeOptions as v, pagedLogArgs as vt, getDistDir as w, workspaceArgs as wt, getPluginGenerationDependencies as x, positiveIntArg as xt, createLogLevelTreeshakeOptions as y, paginationArgs as yt, platformConfigFromProfile as z };
6850
- //# sourceMappingURL=application-BUfYmf0O.mjs.map
5548
+ export { fetchAllTolerant as A, initOperatorClient as B, createBundleCache as C, closeConnectionPool as D, hashFile as E, getConsoleBaseUrl as F, byName as G, normalizeBaseUrl as H, getOAuth2ClientId as I, LOG_LEVELS as K, getOrNull as L, fetchPaged as M, fetchPlatformMachineUserToken as N, defaultPlatformBaseUrl as O, fetchUserInfo as P, getPlatformBaseUrl as R, hasGenerationHooks as S, hashContent as T, rememberPlatformConfigForToken as U, isDefaultPlatform as V, resolveStaticWebsiteUrls as W, platformBundleDefinePlugin as _, resolveInlineSourcemap as a, resolveBundleLogLevel as b, ResolverSchema as c, buildExecutorArgsExpr as d, buildResolverOperationHookExpr as f, stringifyFunction as g, TailorDBTypeSchema as h, resolverBundleKey as i, fetchMachineUserToken as j, fetchAll as k, HTTP_METHODS as l, assertUniqueTailorDBTypeNamesWithExternal as m, generatePluginFilesIfNeeded as n, WorkflowJobFunctionExecutionPolicySchema as o, assertUniqueLocalTailorDBTypeNames as p, loadApplication as r, WorkflowJobSchema as s, defineApplication as t, INVOKER_EXPR as u, composeFunctionTreeshakeOptions as v, getDistDir as w, getPluginGenerationDependencies as x, createLogLevelTreeshakeOptions as y, initOAuth2Client as z };
5549
+ //# sourceMappingURL=application-CqjCcZ2n.mjs.map