@tailor-platform/sdk 1.50.1 → 1.51.1

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 (150) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +1 -0
  3. package/agent-skills/tailor-sdk/SKILL.md +2 -0
  4. package/dist/{actor-BeIEiPYM.d.mts → actor-Nag62ZDM.d.mts} +2 -3
  5. package/dist/application-Bcx-FbDE.mjs +4 -0
  6. package/dist/{application-CZMzt9jL.mjs → application-Z-fNwyZB.mjs} +50 -14
  7. package/dist/application-Z-fNwyZB.mjs.map +1 -0
  8. package/dist/authconnection-BDFTabLQ.d.mts +39 -0
  9. package/dist/authconnection-BUko4V6H.mjs +16 -0
  10. package/dist/authconnection-BUko4V6H.mjs.map +1 -0
  11. package/dist/{brand-D-d15jx3.mjs → brand-Ll48SMXe.mjs} +1 -1
  12. package/dist/{brand-D-d15jx3.mjs.map → brand-Ll48SMXe.mjs.map} +1 -1
  13. package/dist/chunk-DLeslSnM.mjs +21 -0
  14. package/dist/cli/index.d.mts +0 -1
  15. package/dist/cli/index.mjs +16 -16
  16. package/dist/cli/lib.d.mts +6 -7
  17. package/dist/cli/lib.mjs +8 -8
  18. package/dist/cli/skills.d.mts +0 -1
  19. package/dist/cli/skills.mjs +1 -1
  20. package/dist/{client-_kHh0Pip.mjs → client-BwV17byk.mjs} +4 -4
  21. package/dist/{client-_kHh0Pip.mjs.map → client-BwV17byk.mjs.map} +1 -1
  22. package/dist/{client-CPW1N1Rs.mjs → client-D_a50aIg.mjs} +1 -1
  23. package/dist/configure/index.d.mts +5 -5
  24. package/dist/configure/index.mjs +4 -4
  25. package/dist/configure/index.mjs.map +1 -1
  26. package/dist/context-BP5BUdcq.mjs +25 -0
  27. package/dist/context-BP5BUdcq.mjs.map +1 -0
  28. package/dist/context-BXDgEQK9.d.mts +68 -0
  29. package/dist/{crashreport-DHJuSmUc.mjs → crashreport-C4EbRoku.mjs} +1 -1
  30. package/dist/{crashreport-CvmdFs4i.mjs → crashreport-DauPOrKn.mjs} +5 -5
  31. package/dist/{crashreport-CvmdFs4i.mjs.map → crashreport-DauPOrKn.mjs.map} +1 -1
  32. package/dist/{enum-constants-C3KSpsYj.mjs → enum-constants-DI85-fPE.mjs} +1 -1
  33. package/dist/{enum-constants-C3KSpsYj.mjs.map → enum-constants-DI85-fPE.mjs.map} +1 -1
  34. package/dist/{errors-pMPXghkO.mjs → errors-C4cJ0M2K.mjs} +1 -1
  35. package/dist/{errors-pMPXghkO.mjs.map → errors-C4cJ0M2K.mjs.map} +1 -1
  36. package/dist/{field-DLSIuMTu.mjs → field-BY2vbJ8f.mjs} +1 -1
  37. package/dist/{field-DLSIuMTu.mjs.map → field-BY2vbJ8f.mjs.map} +1 -1
  38. package/dist/file-BE5Sy7lP.mjs +54 -0
  39. package/dist/file-BE5Sy7lP.mjs.map +1 -0
  40. package/dist/file-Dc4_QrlQ.d.mts +206 -0
  41. package/dist/{file-utils-DjNi_3U_.mjs → file-utils-BM8t5jCy.mjs} +20 -10
  42. package/dist/file-utils-BM8t5jCy.mjs.map +1 -0
  43. package/dist/iconv-BFNfdlIS.d.mts +122 -0
  44. package/dist/iconv-D0yL88Il.mjs +64 -0
  45. package/dist/iconv-D0yL88Il.mjs.map +1 -0
  46. package/dist/idp-B1b4O7ia.d.mts +161 -0
  47. package/dist/idp-CM7N7iID.mjs +76 -0
  48. package/dist/idp-CM7N7iID.mjs.map +1 -0
  49. package/dist/{index-C--7W0UO.d.mts → index-BD99GoHO.d.mts} +4 -5
  50. package/dist/{index-nV4ZC_Ve.d.mts → index-BXwAT_oE.d.mts} +2 -3
  51. package/dist/{index-BQ4oi0AI.d.mts → index-CYAZkd4b.d.mts} +2 -3
  52. package/dist/{index-BjXN1SdY.d.mts → index-CfSjuxzK.d.mts} +2 -3
  53. package/dist/index-Dy3ZH5Wm.d.mts +46 -0
  54. package/dist/{index-VJW98BSy.d.mts → index-aiIbrFGw.d.mts} +2 -3
  55. package/dist/{interceptor-DTNS0EtF.mjs → interceptor-Cr3kZWMc.mjs} +1 -1
  56. package/dist/{interceptor-DTNS0EtF.mjs.map → interceptor-Cr3kZWMc.mjs.map} +1 -1
  57. package/dist/{job-M3Avv_SV.mjs → job-4GOnasfT.mjs} +2 -2
  58. package/dist/{job-M3Avv_SV.mjs.map → job-4GOnasfT.mjs.map} +1 -1
  59. package/dist/kysely/index.d.mts +0 -1
  60. package/dist/{kysely-type-B8aRz_oC.mjs → kysely-type-BUoVDC5r.mjs} +2 -2
  61. package/dist/{kysely-type-B8aRz_oC.mjs.map → kysely-type-BUoVDC5r.mjs.map} +1 -1
  62. package/dist/{logger-DTNAMYGy.mjs → logger-B1g4I9wT.mjs} +1 -1
  63. package/dist/{logger-DTNAMYGy.mjs.map → logger-B1g4I9wT.mjs.map} +1 -1
  64. package/dist/{mock-BfL09ULZ.mjs → mock-B2t5gDMl.mjs} +11 -5
  65. package/dist/mock-B2t5gDMl.mjs.map +1 -0
  66. package/dist/{multiline-e3IpANmS.mjs → multiline-G1yF18OH.mjs} +1 -1
  67. package/dist/{multiline-e3IpANmS.mjs.map → multiline-G1yF18OH.mjs.map} +1 -1
  68. package/dist/package-json-CAGKAJff.mjs +4 -0
  69. package/dist/{package-json-6Px8bDpG.mjs → package-json-ZL0MkZOO.mjs} +1 -1
  70. package/dist/{package-json-6Px8bDpG.mjs.map → package-json-ZL0MkZOO.mjs.map} +1 -1
  71. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -2
  72. package/dist/plugin/builtin/enum-constants/index.mjs +1 -1
  73. package/dist/plugin/builtin/file-utils/index.d.mts +1 -2
  74. package/dist/plugin/builtin/file-utils/index.mjs +1 -1
  75. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -2
  76. package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
  77. package/dist/plugin/builtin/seed/index.d.mts +1 -2
  78. package/dist/plugin/builtin/seed/index.mjs +1 -1
  79. package/dist/plugin/index.d.mts +2 -3
  80. package/dist/{repl-editor-jZ493eQI.mjs → repl-editor-yAjwS5_M.mjs} +1 -1
  81. package/dist/{repl-editor-jZ493eQI.mjs.map → repl-editor-yAjwS5_M.mjs.map} +1 -1
  82. package/dist/runtime/authconnection.d.mts +2 -0
  83. package/dist/runtime/authconnection.mjs +4 -0
  84. package/dist/runtime/context.d.mts +2 -0
  85. package/dist/runtime/context.mjs +4 -0
  86. package/dist/runtime/file.d.mts +2 -0
  87. package/dist/runtime/file.mjs +4 -0
  88. package/dist/runtime/globals.d.mts +103 -0
  89. package/dist/runtime/globals.mjs +2 -0
  90. package/dist/runtime/iconv.d.mts +2 -0
  91. package/dist/runtime/iconv.mjs +4 -0
  92. package/dist/runtime/idp.d.mts +2 -0
  93. package/dist/runtime/idp.mjs +4 -0
  94. package/dist/runtime/index.d.mts +9 -0
  95. package/dist/runtime/index.mjs +10 -0
  96. package/dist/runtime/secretmanager.d.mts +2 -0
  97. package/dist/runtime/secretmanager.mjs +4 -0
  98. package/dist/runtime/workflow.d.mts +2 -0
  99. package/dist/runtime/workflow.mjs +4 -0
  100. package/dist/{runtime-DgsMnMrO.mjs → runtime-CyX4zeod.mjs} +55 -32
  101. package/dist/runtime-CyX4zeod.mjs.map +1 -0
  102. package/dist/{schema-C5QjYEc-.mjs → schema-DBq6hr6h.mjs} +3 -3
  103. package/dist/{schema-C5QjYEc-.mjs.map → schema-DBq6hr6h.mjs.map} +1 -1
  104. package/dist/{secret-file-BHpxGyNf.mjs → secret-file-DnbmTWec.mjs} +1 -1
  105. package/dist/{secret-file-BHpxGyNf.mjs.map → secret-file-DnbmTWec.mjs.map} +1 -1
  106. package/dist/secretmanager-CQTTuCmn.mjs +25 -0
  107. package/dist/secretmanager-CQTTuCmn.mjs.map +1 -0
  108. package/dist/secretmanager-Cjq3s2aU.d.mts +55 -0
  109. package/dist/seed/index.d.mts +0 -1
  110. package/dist/{seed-DjfAn0BC.mjs → seed-kNk-xLoB.mjs} +7 -2
  111. package/dist/{seed-DjfAn0BC.mjs.map → seed-kNk-xLoB.mjs.map} +1 -1
  112. package/dist/{service-DCgJxdg1.mjs → service-DHgJ4YEF.mjs} +3 -3
  113. package/dist/{service-DCgJxdg1.mjs.map → service-DHgJ4YEF.mjs.map} +1 -1
  114. package/dist/{tailor-db-field-4bMLe25-.d.mts → tailor-db-field-BhWvOyky.d.mts} +1 -2
  115. package/dist/{telemetry-C1Y56L5E.mjs → telemetry-C8xKz3GM.mjs} +2 -2
  116. package/dist/{telemetry-C1Y56L5E.mjs.map → telemetry-C8xKz3GM.mjs.map} +1 -1
  117. package/dist/telemetry-DQl47E1s.mjs +4 -0
  118. package/dist/types-BnphjkIJ.mjs +5 -0
  119. package/dist/{types-sir9UPht.mjs → types-Duhhsx3R.mjs} +2 -2
  120. package/dist/{types-sir9UPht.mjs.map → types-Duhhsx3R.mjs.map} +1 -1
  121. package/dist/utils/test/index.d.mts +3 -4
  122. package/dist/utils/test/index.mjs +1 -1
  123. package/dist/utils/test/index.mjs.map +1 -1
  124. package/dist/vitest/environment.d.mts +0 -1
  125. package/dist/vitest/environment.mjs +1 -1
  126. package/dist/vitest/index.d.mts +2 -3
  127. package/dist/vitest/index.mjs +3 -3
  128. package/dist/vitest/index.mjs.map +1 -1
  129. package/dist/vitest/setup.d.mts +0 -1
  130. package/dist/vitest/setup.mjs +1 -1
  131. package/dist/workflow-DJRr-0nl.mjs +39 -0
  132. package/dist/workflow-DJRr-0nl.mjs.map +1 -0
  133. package/dist/workflow-DV_88JEf.d.mts +96 -0
  134. package/dist/{workflow.generated-OYAu_6zX.d.mts → workflow.generated-DV87DJfO.d.mts} +2 -3
  135. package/docs/cli/application.md +1 -1
  136. package/docs/cli/tailordb.md +9 -8
  137. package/docs/cli-reference.md +17 -16
  138. package/docs/configuration.md +1 -0
  139. package/docs/generator/builtin.md +2 -0
  140. package/docs/runtime.md +113 -0
  141. package/docs/testing.md +21 -0
  142. package/package.json +53 -9
  143. package/dist/application-CZMzt9jL.mjs.map +0 -1
  144. package/dist/application-v_E2W-Fz.mjs +0 -4
  145. package/dist/file-utils-DjNi_3U_.mjs.map +0 -1
  146. package/dist/mock-BfL09ULZ.mjs.map +0 -1
  147. package/dist/package-json-7sRXVndJ.mjs +0 -4
  148. package/dist/runtime-DgsMnMrO.mjs.map +0 -1
  149. package/dist/telemetry-C13VIFpT.mjs +0 -4
  150. package/dist/types-DoIG6Nij.mjs +0 -5
@@ -1 +1 @@
1
- {"version":3,"file":"types-sir9UPht.mjs","names":[],"sources":["../src/configure/types/type.ts"],"sourcesContent":["import { type AllowedValues, type AllowedValuesOutput, mapAllowedValues } from \"./field\";\nimport type {\n DefinedFieldMetadata,\n TailorFieldType,\n TailorToTs,\n FieldMetadata,\n FieldOptions,\n FieldOutput,\n} from \"@/types/field-types\";\nimport type { InferFieldsOutput, Prettify } from \"@/types/helpers\";\nimport type { TailorField as TailorFieldBase } from \"@/types/tailor-field\";\nimport type { TailorUser } from \"@/types/user\";\nimport type { FieldValidateInput } from \"@/types/validation\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n// This helper type intentionally uses `any` as a placeholder for unknown field output.\n// oxlint-disable-next-line no-explicit-any\nexport type TailorAnyField = TailorField<any>;\n\n/**\n * Full TailorField interface with builder methods.\n * Extends the minimal structural interface from types/ with fluent API methods.\n */\nexport interface TailorField<\n Defined extends DefinedFieldMetadata = DefinedFieldMetadata,\n // Generic default output type (kept loose on purpose for library ergonomics).\n // oxlint-disable-next-line no-explicit-any\n Output = any,\n M extends FieldMetadata = FieldMetadata,\n T extends TailorFieldType = TailorFieldType,\n> extends TailorFieldBase<Defined, Output, M, T> {\n readonly fields: Record<string, TailorAnyField>;\n _metadata: M;\n\n /**\n * Set a description for the field\n * @param description - The description text\n * @returns The field with updated metadata\n */\n description<CurrentDefined extends Defined>(\n this: CurrentDefined extends { description: unknown }\n ? never\n : TailorField<CurrentDefined, Output>,\n description: string,\n ): TailorField<Prettify<CurrentDefined & { description: true }>, Output>;\n\n /**\n * Set a custom type name for enum or nested types\n * @param typeName - The custom type name\n * @returns The field with updated metadata\n */\n typeName<CurrentDefined extends Defined>(\n this: CurrentDefined extends { typeName: unknown }\n ? never\n : CurrentDefined extends { type: \"enum\" | \"nested\" }\n ? TailorField<CurrentDefined, Output>\n : never,\n typeName: string,\n ): TailorField<Prettify<CurrentDefined & { typeName: true }>, Output>;\n\n /**\n * Add validation functions to the field\n * @param validate - One or more validation functions\n * @returns The field with updated metadata\n */\n validate<CurrentDefined extends Defined>(\n this: CurrentDefined extends { validate: unknown }\n ? never\n : TailorField<CurrentDefined, Output>,\n ...validate: FieldValidateInput<Output>[]\n ): TailorField<Prettify<CurrentDefined & { validate: true }>, Output>;\n\n /**\n * Parse and validate a value against this field's validation rules\n * Returns StandardSchema Result type with success or failure\n * @param args - Value, context data, and user\n * @returns Validation result\n */\n parse(args: FieldParseArgs): StandardSchemaV1.Result<Output>;\n\n /**\n * Internal parse method that tracks field path for nested validation\n * @private\n * @param args - Parse arguments\n * @returns Validation result\n */\n _parseInternal(args: FieldParseInternalArgs): StandardSchemaV1.Result<Output>;\n}\n\nconst regex = {\n uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,\n date: /^(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})$/,\n time: /^(?<hour>\\d{2}):(?<minute>\\d{2})$/,\n datetime:\n /^(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})T(?<hour>\\d{2}):(?<minute>\\d{2}):(?<second>\\d{2})(.(?<millisec>\\d{3}))?Z$/,\n decimal: /^-?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?$/,\n} as const;\n\ntype FieldParseArgs = {\n value: unknown;\n data: unknown;\n user: TailorUser;\n};\n\ntype FieldValidateValueArgs<T extends TailorFieldType> = {\n value: TailorToTs[T];\n data: unknown;\n user: TailorUser;\n pathArray: string[];\n};\n\ntype FieldParseInternalArgs = {\n // Runtime input is unknown/untyped; we validate and narrow it inside the parser.\n // oxlint-disable-next-line no-explicit-any\n value: any;\n data: unknown;\n user: TailorUser;\n pathArray: string[];\n};\n\n/**\n * Creates a new TailorField instance.\n * @param type - Field type\n * @param options - Field options\n * @param fields - Nested fields for object-like types\n * @param values - Allowed values for enum-like fields\n * @returns A new TailorField\n */\nfunction createTailorField<\n const T extends TailorFieldType,\n const TOptions extends FieldOptions,\n const OutputBase = TailorToTs[T],\n>(\n type: T,\n options?: TOptions,\n fields?: Record<string, TailorAnyField>,\n values?: AllowedValues,\n): TailorField<\n { type: T; array: TOptions extends { array: true } ? true : false },\n FieldOutput<OutputBase, TOptions>\n> {\n const _metadata: FieldMetadata = { required: true };\n\n if (options) {\n if (options.optional === true) {\n _metadata.required = false;\n }\n if (options.array === true) {\n _metadata.array = true;\n }\n }\n if (values) {\n _metadata.allowedValues = mapAllowedValues(values);\n }\n\n /**\n * Validate a single value (not an array element)\n * Used internally for array element validation\n * @param args - Value, context data, and user\n * @returns Array of validation issues\n */\n function validateValue(args: FieldValidateValueArgs<T>): StandardSchemaV1.Issue[] {\n const { value, data, user, pathArray } = args;\n const issues: StandardSchemaV1.Issue[] = [];\n\n // Type-specific validation\n switch (type) {\n case \"string\":\n if (typeof value !== \"string\") {\n issues.push({\n message: `Expected a string: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n\n case \"integer\":\n if (typeof value !== \"number\" || !Number.isInteger(value)) {\n issues.push({\n message: `Expected an integer: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n\n case \"float\":\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n issues.push({\n message: `Expected a number: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n\n case \"boolean\":\n if (typeof value !== \"boolean\") {\n issues.push({\n message: `Expected a boolean: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n\n case \"uuid\":\n if (typeof value !== \"string\" || !regex.uuid.test(value)) {\n issues.push({\n message: `Expected a valid UUID: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n case \"date\":\n if (typeof value !== \"string\" || !regex.date.test(value)) {\n issues.push({\n message: `Expected to match \"yyyy-MM-dd\" format: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n case \"datetime\":\n if (typeof value !== \"string\" || !regex.datetime.test(value)) {\n issues.push({\n message: `Expected to match ISO format: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n case \"time\":\n if (typeof value !== \"string\" || !regex.time.test(value)) {\n issues.push({\n message: `Expected to match \"HH:mm\" format: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n case \"decimal\":\n if (typeof value !== \"string\" || !regex.decimal.test(value)) {\n issues.push({\n message: `Expected a decimal string: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n\n case \"enum\":\n if (field._metadata.allowedValues) {\n const allowedValues = field._metadata.allowedValues.map((v) => v.value);\n if (typeof value !== \"string\" || !allowedValues.includes(value)) {\n issues.push({\n message: `Must be one of [${allowedValues.join(\", \")}]: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n }\n break;\n\n case \"nested\":\n // Validate nested object fields\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value) ||\n value instanceof Date\n ) {\n issues.push({\n message: `Expected an object: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n } else if (field.fields && Object.keys(field.fields).length > 0) {\n for (const [fieldName, nestedField] of Object.entries(field.fields)) {\n const fieldValue = value?.[fieldName];\n const result = nestedField._parseInternal({\n value: fieldValue,\n data,\n user,\n pathArray: pathArray.concat(fieldName),\n });\n if (result.issues) {\n issues.push(...result.issues);\n }\n }\n }\n break;\n }\n\n // Custom validation functions\n const validateFns = field._metadata.validate;\n if (validateFns && validateFns.length > 0) {\n for (const validateInput of validateFns) {\n const { fn, message } =\n typeof validateInput === \"function\"\n ? { fn: validateInput, message: \"Validation failed\" }\n : { fn: validateInput[0], message: validateInput[1] };\n\n if (!fn({ value, data, user })) {\n issues.push({\n message,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n }\n }\n\n return issues;\n }\n\n /**\n * Internal parse method that tracks field path for nested validation\n * @param args - Parse arguments\n * @returns Parse result with value or issues\n */\n function parseInternal(\n args: FieldParseInternalArgs,\n ): StandardSchemaV1.Result<FieldOutput<OutputBase, TOptions>> {\n const { value, data, user, pathArray } = args;\n const issues: StandardSchemaV1.Issue[] = [];\n\n // 1. Check required/optional\n const isNullOrUndefined = value === null || value === undefined;\n if (field._metadata.required && isNullOrUndefined) {\n issues.push({\n message: \"Required field is missing\",\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n return { issues };\n }\n\n // If optional and null/undefined, skip further validation and normalize to null\n if (!field._metadata.required && isNullOrUndefined) {\n return { value: value ?? null };\n }\n\n // 2. Check array type\n if (field._metadata.array) {\n if (!Array.isArray(value)) {\n issues.push({\n message: \"Expected an array\",\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n return { issues };\n }\n\n // Validate each array element (without array flag)\n for (let i = 0; i < value.length; i++) {\n const elementValue = value[i];\n const elementPath = pathArray.concat(`[${i}]`);\n\n // Validate element with same type but without array flag\n const elementIssues = validateValue({\n value: elementValue,\n data,\n user,\n pathArray: elementPath,\n });\n if (elementIssues.length > 0) {\n issues.push(...elementIssues);\n }\n }\n\n if (issues.length > 0) {\n return { issues };\n }\n return { value: value as FieldOutput<OutputBase, TOptions> };\n }\n\n // 3. Type-specific validation and custom validation\n const valueIssues = validateValue({ value, data, user, pathArray });\n issues.push(...valueIssues);\n\n if (issues.length > 0) {\n return { issues };\n }\n\n return { value };\n }\n\n const field: TailorField<\n { type: T; array: TOptions extends { array: true } ? true : false },\n FieldOutput<OutputBase, TOptions>\n > = {\n type,\n fields: fields ?? {},\n _defined: undefined as unknown as {\n type: T;\n array: TOptions extends { array: true } ? true : false;\n },\n _output: undefined as FieldOutput<OutputBase, TOptions>,\n _metadata,\n\n get metadata() {\n return { ...this._metadata };\n },\n\n description(description: string) {\n this._metadata.description = description;\n // Fluent API returns this with updated type\n // oxlint-disable-next-line no-explicit-any\n return this as any;\n },\n\n typeName(typeName: string) {\n this._metadata.typeName = typeName;\n // Fluent API returns this with updated type\n // oxlint-disable-next-line no-explicit-any\n return this as any;\n },\n\n validate(...validateInputs: FieldValidateInput<FieldOutput<OutputBase, TOptions>>[]) {\n this._metadata.validate = validateInputs;\n // Fluent API returns this with updated type\n // oxlint-disable-next-line no-explicit-any\n return this as any;\n },\n\n parse(args: FieldParseArgs): StandardSchemaV1.Result<FieldOutput<OutputBase, TOptions>> {\n return parseInternal({\n value: args.value,\n data: args.data,\n user: args.user,\n pathArray: [],\n });\n },\n\n _parseInternal: parseInternal,\n };\n\n return field;\n}\n\n/**\n * Create a UUID field for resolver input/output.\n * @param options - Field configuration options\n * @returns A UUID field\n * @example t.uuid()\n */\nfunction uuid<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"uuid\", options);\n}\n\n/**\n * Create a string field for resolver input/output.\n * @param options - Field configuration options\n * @returns A string field\n * @example t.string()\n * @example t.string({ optional: true })\n * @example t.string({ array: true })\n */\nfunction string<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"string\", options);\n}\n\n/**\n * Create a boolean field for resolver input/output.\n * @param options - Field configuration options\n * @returns A boolean field\n * @example t.bool()\n */\nfunction bool<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"boolean\", options);\n}\n\n/**\n * Create an integer field for resolver input/output.\n * @param options - Field configuration options\n * @returns An integer field\n * @example t.int()\n */\nfunction int<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"integer\", options);\n}\n\n/**\n * Create a float field for resolver input/output.\n * @param options - Field configuration options\n * @returns A float field\n * @example t.float()\n */\nfunction float<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"float\", options);\n}\n\n/**\n * Create a decimal field for resolver input/output (stored as string for precision).\n * @param options - Field configuration options\n * @returns A decimal field\n * @example t.decimal()\n * @example t.decimal({ optional: true })\n */\nfunction decimal<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"decimal\", options);\n}\n\n/**\n * Create a date field for resolver input/output.\n * @param options - Field configuration options\n * @returns A date field\n * @example t.date()\n */\nfunction date<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"date\", options);\n}\n\n/**\n * Create a datetime field for resolver input/output.\n * @param options - Field configuration options\n * @returns A datetime field\n * @example t.datetime()\n */\nfunction datetime<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"datetime\", options);\n}\n\n/**\n * Create a time field for resolver input/output.\n * @param options - Field configuration options\n * @returns A time field\n * @example t.time()\n */\nfunction time<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"time\", options);\n}\n\n/**\n * Create an enum field for resolver input/output.\n * @param values - Array of allowed string values\n * @param options - Field configuration options\n * @returns An enum field\n * @example t.enum([\"active\", \"inactive\"])\n */\nfunction _enum<const V extends AllowedValues, const Opt extends FieldOptions>(\n values: V,\n options?: Opt,\n): TailorField<\n { type: \"enum\"; array: Opt extends { array: true } ? true : false },\n FieldOutput<AllowedValuesOutput<V>, Opt>\n> {\n return createTailorField<\"enum\", Opt, AllowedValuesOutput<V>>(\"enum\", options, undefined, values);\n}\n\n/**\n * Create a nested object field for resolver input/output.\n * @param fields - Record of field definitions\n * @param options - Field options (optional, array)\n * @returns A nested object field\n * @example\n * // Single object:\n * output: t.object({ name: t.string(), email: t.string() })\n * @example\n * // Array of objects:\n * items: t.object({ name: t.string() }, { array: true })\n */\nfunction object<const F extends Record<string, TailorAnyField>, const Opt extends FieldOptions>(\n fields: F,\n options?: Opt,\n) {\n const objectField = createTailorField(\"nested\", options, fields) as TailorField<\n { type: \"nested\"; array: Opt extends { array: true } ? true : false },\n FieldOutput<InferFieldsOutput<F>, Opt>\n >;\n return objectField;\n}\n\nexport const t = {\n uuid,\n string,\n bool,\n int,\n float,\n decimal,\n date,\n datetime,\n time,\n enum: _enum,\n object,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"types-Duhhsx3R.mjs","names":[],"sources":["../src/configure/types/type.ts"],"sourcesContent":["import { type AllowedValues, type AllowedValuesOutput, mapAllowedValues } from \"./field\";\nimport type {\n DefinedFieldMetadata,\n TailorFieldType,\n TailorToTs,\n FieldMetadata,\n FieldOptions,\n FieldOutput,\n} from \"@/types/field-types\";\nimport type { InferFieldsOutput, Prettify } from \"@/types/helpers\";\nimport type { TailorField as TailorFieldBase } from \"@/types/tailor-field\";\nimport type { TailorUser } from \"@/types/user\";\nimport type { FieldValidateInput } from \"@/types/validation\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n// This helper type intentionally uses `any` as a placeholder for unknown field output.\n// oxlint-disable-next-line no-explicit-any\nexport type TailorAnyField = TailorField<any>;\n\n/**\n * Full TailorField interface with builder methods.\n * Extends the minimal structural interface from types/ with fluent API methods.\n */\nexport interface TailorField<\n Defined extends DefinedFieldMetadata = DefinedFieldMetadata,\n // Generic default output type (kept loose on purpose for library ergonomics).\n // oxlint-disable-next-line no-explicit-any\n Output = any,\n M extends FieldMetadata = FieldMetadata,\n T extends TailorFieldType = TailorFieldType,\n> extends TailorFieldBase<Defined, Output, M, T> {\n readonly fields: Record<string, TailorAnyField>;\n _metadata: M;\n\n /**\n * Set a description for the field\n * @param description - The description text\n * @returns The field with updated metadata\n */\n description<CurrentDefined extends Defined>(\n this: CurrentDefined extends { description: unknown }\n ? never\n : TailorField<CurrentDefined, Output>,\n description: string,\n ): TailorField<Prettify<CurrentDefined & { description: true }>, Output>;\n\n /**\n * Set a custom type name for enum or nested types\n * @param typeName - The custom type name\n * @returns The field with updated metadata\n */\n typeName<CurrentDefined extends Defined>(\n this: CurrentDefined extends { typeName: unknown }\n ? never\n : CurrentDefined extends { type: \"enum\" | \"nested\" }\n ? TailorField<CurrentDefined, Output>\n : never,\n typeName: string,\n ): TailorField<Prettify<CurrentDefined & { typeName: true }>, Output>;\n\n /**\n * Add validation functions to the field\n * @param validate - One or more validation functions\n * @returns The field with updated metadata\n */\n validate<CurrentDefined extends Defined>(\n this: CurrentDefined extends { validate: unknown }\n ? never\n : TailorField<CurrentDefined, Output>,\n ...validate: FieldValidateInput<Output>[]\n ): TailorField<Prettify<CurrentDefined & { validate: true }>, Output>;\n\n /**\n * Parse and validate a value against this field's validation rules\n * Returns StandardSchema Result type with success or failure\n * @param args - Value, context data, and user\n * @returns Validation result\n */\n parse(args: FieldParseArgs): StandardSchemaV1.Result<Output>;\n\n /**\n * Internal parse method that tracks field path for nested validation\n * @private\n * @param args - Parse arguments\n * @returns Validation result\n */\n _parseInternal(args: FieldParseInternalArgs): StandardSchemaV1.Result<Output>;\n}\n\nconst regex = {\n uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,\n date: /^(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})$/,\n time: /^(?<hour>\\d{2}):(?<minute>\\d{2})$/,\n datetime:\n /^(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})T(?<hour>\\d{2}):(?<minute>\\d{2}):(?<second>\\d{2})(.(?<millisec>\\d{3}))?Z$/,\n decimal: /^-?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?$/,\n} as const;\n\ntype FieldParseArgs = {\n value: unknown;\n data: unknown;\n user: TailorUser;\n};\n\ntype FieldValidateValueArgs<T extends TailorFieldType> = {\n value: TailorToTs[T];\n data: unknown;\n user: TailorUser;\n pathArray: string[];\n};\n\ntype FieldParseInternalArgs = {\n // Runtime input is unknown/untyped; we validate and narrow it inside the parser.\n // oxlint-disable-next-line no-explicit-any\n value: any;\n data: unknown;\n user: TailorUser;\n pathArray: string[];\n};\n\n/**\n * Creates a new TailorField instance.\n * @param type - Field type\n * @param options - Field options\n * @param fields - Nested fields for object-like types\n * @param values - Allowed values for enum-like fields\n * @returns A new TailorField\n */\nfunction createTailorField<\n const T extends TailorFieldType,\n const TOptions extends FieldOptions,\n const OutputBase = TailorToTs[T],\n>(\n type: T,\n options?: TOptions,\n fields?: Record<string, TailorAnyField>,\n values?: AllowedValues,\n): TailorField<\n { type: T; array: TOptions extends { array: true } ? true : false },\n FieldOutput<OutputBase, TOptions>\n> {\n const _metadata: FieldMetadata = { required: true };\n\n if (options) {\n if (options.optional === true) {\n _metadata.required = false;\n }\n if (options.array === true) {\n _metadata.array = true;\n }\n }\n if (values) {\n _metadata.allowedValues = mapAllowedValues(values);\n }\n\n /**\n * Validate a single value (not an array element)\n * Used internally for array element validation\n * @param args - Value, context data, and user\n * @returns Array of validation issues\n */\n function validateValue(args: FieldValidateValueArgs<T>): StandardSchemaV1.Issue[] {\n const { value, data, user, pathArray } = args;\n const issues: StandardSchemaV1.Issue[] = [];\n\n // Type-specific validation\n switch (type) {\n case \"string\":\n if (typeof value !== \"string\") {\n issues.push({\n message: `Expected a string: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n\n case \"integer\":\n if (typeof value !== \"number\" || !Number.isInteger(value)) {\n issues.push({\n message: `Expected an integer: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n\n case \"float\":\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n issues.push({\n message: `Expected a number: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n\n case \"boolean\":\n if (typeof value !== \"boolean\") {\n issues.push({\n message: `Expected a boolean: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n\n case \"uuid\":\n if (typeof value !== \"string\" || !regex.uuid.test(value)) {\n issues.push({\n message: `Expected a valid UUID: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n case \"date\":\n if (typeof value !== \"string\" || !regex.date.test(value)) {\n issues.push({\n message: `Expected to match \"yyyy-MM-dd\" format: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n case \"datetime\":\n if (typeof value !== \"string\" || !regex.datetime.test(value)) {\n issues.push({\n message: `Expected to match ISO format: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n case \"time\":\n if (typeof value !== \"string\" || !regex.time.test(value)) {\n issues.push({\n message: `Expected to match \"HH:mm\" format: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n case \"decimal\":\n if (typeof value !== \"string\" || !regex.decimal.test(value)) {\n issues.push({\n message: `Expected a decimal string: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n break;\n\n case \"enum\":\n if (field._metadata.allowedValues) {\n const allowedValues = field._metadata.allowedValues.map((v) => v.value);\n if (typeof value !== \"string\" || !allowedValues.includes(value)) {\n issues.push({\n message: `Must be one of [${allowedValues.join(\", \")}]: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n }\n break;\n\n case \"nested\":\n // Validate nested object fields\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value) ||\n value instanceof Date\n ) {\n issues.push({\n message: `Expected an object: received ${String(value)}`,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n } else if (field.fields && Object.keys(field.fields).length > 0) {\n for (const [fieldName, nestedField] of Object.entries(field.fields)) {\n const fieldValue = value?.[fieldName];\n const result = nestedField._parseInternal({\n value: fieldValue,\n data,\n user,\n pathArray: pathArray.concat(fieldName),\n });\n if (result.issues) {\n issues.push(...result.issues);\n }\n }\n }\n break;\n }\n\n // Custom validation functions\n const validateFns = field._metadata.validate;\n if (validateFns && validateFns.length > 0) {\n for (const validateInput of validateFns) {\n const { fn, message } =\n typeof validateInput === \"function\"\n ? { fn: validateInput, message: \"Validation failed\" }\n : { fn: validateInput[0], message: validateInput[1] };\n\n if (!fn({ value, data, user })) {\n issues.push({\n message,\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n }\n }\n }\n\n return issues;\n }\n\n /**\n * Internal parse method that tracks field path for nested validation\n * @param args - Parse arguments\n * @returns Parse result with value or issues\n */\n function parseInternal(\n args: FieldParseInternalArgs,\n ): StandardSchemaV1.Result<FieldOutput<OutputBase, TOptions>> {\n const { value, data, user, pathArray } = args;\n const issues: StandardSchemaV1.Issue[] = [];\n\n // 1. Check required/optional\n const isNullOrUndefined = value === null || value === undefined;\n if (field._metadata.required && isNullOrUndefined) {\n issues.push({\n message: \"Required field is missing\",\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n return { issues };\n }\n\n // If optional and null/undefined, skip further validation and normalize to null\n if (!field._metadata.required && isNullOrUndefined) {\n return { value: value ?? null };\n }\n\n // 2. Check array type\n if (field._metadata.array) {\n if (!Array.isArray(value)) {\n issues.push({\n message: \"Expected an array\",\n path: pathArray.length > 0 ? pathArray : undefined,\n });\n return { issues };\n }\n\n // Validate each array element (without array flag)\n for (let i = 0; i < value.length; i++) {\n const elementValue = value[i];\n const elementPath = pathArray.concat(`[${i}]`);\n\n // Validate element with same type but without array flag\n const elementIssues = validateValue({\n value: elementValue,\n data,\n user,\n pathArray: elementPath,\n });\n if (elementIssues.length > 0) {\n issues.push(...elementIssues);\n }\n }\n\n if (issues.length > 0) {\n return { issues };\n }\n return { value: value as FieldOutput<OutputBase, TOptions> };\n }\n\n // 3. Type-specific validation and custom validation\n const valueIssues = validateValue({ value, data, user, pathArray });\n issues.push(...valueIssues);\n\n if (issues.length > 0) {\n return { issues };\n }\n\n return { value };\n }\n\n const field: TailorField<\n { type: T; array: TOptions extends { array: true } ? true : false },\n FieldOutput<OutputBase, TOptions>\n > = {\n type,\n fields: fields ?? {},\n _defined: undefined as unknown as {\n type: T;\n array: TOptions extends { array: true } ? true : false;\n },\n _output: undefined as FieldOutput<OutputBase, TOptions>,\n _metadata,\n\n get metadata() {\n return { ...this._metadata };\n },\n\n description(description: string) {\n this._metadata.description = description;\n // Fluent API returns this with updated type\n // oxlint-disable-next-line no-explicit-any\n return this as any;\n },\n\n typeName(typeName: string) {\n this._metadata.typeName = typeName;\n // Fluent API returns this with updated type\n // oxlint-disable-next-line no-explicit-any\n return this as any;\n },\n\n validate(...validateInputs: FieldValidateInput<FieldOutput<OutputBase, TOptions>>[]) {\n this._metadata.validate = validateInputs;\n // Fluent API returns this with updated type\n // oxlint-disable-next-line no-explicit-any\n return this as any;\n },\n\n parse(args: FieldParseArgs): StandardSchemaV1.Result<FieldOutput<OutputBase, TOptions>> {\n return parseInternal({\n value: args.value,\n data: args.data,\n user: args.user,\n pathArray: [],\n });\n },\n\n _parseInternal: parseInternal,\n };\n\n return field;\n}\n\n/**\n * Create a UUID field for resolver input/output.\n * @param options - Field configuration options\n * @returns A UUID field\n * @example t.uuid()\n */\nfunction uuid<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"uuid\", options);\n}\n\n/**\n * Create a string field for resolver input/output.\n * @param options - Field configuration options\n * @returns A string field\n * @example t.string()\n * @example t.string({ optional: true })\n * @example t.string({ array: true })\n */\nfunction string<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"string\", options);\n}\n\n/**\n * Create a boolean field for resolver input/output.\n * @param options - Field configuration options\n * @returns A boolean field\n * @example t.bool()\n */\nfunction bool<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"boolean\", options);\n}\n\n/**\n * Create an integer field for resolver input/output.\n * @param options - Field configuration options\n * @returns An integer field\n * @example t.int()\n */\nfunction int<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"integer\", options);\n}\n\n/**\n * Create a float field for resolver input/output.\n * @param options - Field configuration options\n * @returns A float field\n * @example t.float()\n */\nfunction float<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"float\", options);\n}\n\n/**\n * Create a decimal field for resolver input/output (stored as string for precision).\n * @param options - Field configuration options\n * @returns A decimal field\n * @example t.decimal()\n * @example t.decimal({ optional: true })\n */\nfunction decimal<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"decimal\", options);\n}\n\n/**\n * Create a date field for resolver input/output.\n * @param options - Field configuration options\n * @returns A date field\n * @example t.date()\n */\nfunction date<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"date\", options);\n}\n\n/**\n * Create a datetime field for resolver input/output.\n * @param options - Field configuration options\n * @returns A datetime field\n * @example t.datetime()\n */\nfunction datetime<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"datetime\", options);\n}\n\n/**\n * Create a time field for resolver input/output.\n * @param options - Field configuration options\n * @returns A time field\n * @example t.time()\n */\nfunction time<const Opt extends FieldOptions>(options?: Opt) {\n return createTailorField(\"time\", options);\n}\n\n/**\n * Create an enum field for resolver input/output.\n * @param values - Array of allowed string values\n * @param options - Field configuration options\n * @returns An enum field\n * @example t.enum([\"active\", \"inactive\"])\n */\nfunction _enum<const V extends AllowedValues, const Opt extends FieldOptions>(\n values: V,\n options?: Opt,\n): TailorField<\n { type: \"enum\"; array: Opt extends { array: true } ? true : false },\n FieldOutput<AllowedValuesOutput<V>, Opt>\n> {\n return createTailorField<\"enum\", Opt, AllowedValuesOutput<V>>(\"enum\", options, undefined, values);\n}\n\n/**\n * Create a nested object field for resolver input/output.\n * @param fields - Record of field definitions\n * @param options - Field options (optional, array)\n * @returns A nested object field\n * @example\n * // Single object:\n * output: t.object({ name: t.string(), email: t.string() })\n * @example\n * // Array of objects:\n * items: t.object({ name: t.string() }, { array: true })\n */\nfunction object<const F extends Record<string, TailorAnyField>, const Opt extends FieldOptions>(\n fields: F,\n options?: Opt,\n) {\n const objectField = createTailorField(\"nested\", options, fields) as TailorField<\n { type: \"nested\"; array: Opt extends { array: true } ? true : false },\n FieldOutput<InferFieldsOutput<F>, Opt>\n >;\n return objectField;\n}\n\nexport const t = {\n uuid,\n string,\n bool,\n int,\n float,\n decimal,\n date,\n datetime,\n time,\n enum: _enum,\n object,\n};\n"],"mappings":"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"}
@@ -1,7 +1,6 @@
1
- /// <reference types="@tailor-platform/function-types" />
2
- import { Vt as TailorInvoker } from "../../tailor-db-field-4bMLe25-.mjs";
3
- import { O as TailorDBType } from "../../workflow.generated-OYAu_6zX.mjs";
4
- import { dt as WORKFLOW_TEST_ENV_KEY, n as output, xt as TailorField } from "../../index-C--7W0UO.mjs";
1
+ import { Vt as TailorInvoker } from "../../tailor-db-field-BhWvOyky.mjs";
2
+ import { O as TailorDBType } from "../../workflow.generated-DV87DJfO.mjs";
3
+ import { dt as WORKFLOW_TEST_ENV_KEY, n as output, xt as TailorField } from "../../index-BD99GoHO.mjs";
5
4
  import { StandardSchemaV1 } from "@standard-schema/spec";
6
5
 
7
6
  //#region src/utils/test/mock.d.ts
@@ -1,5 +1,5 @@
1
1
 
2
- import { t as WORKFLOW_TEST_ENV_KEY } from "../../job-M3Avv_SV.mjs";
2
+ import { t as WORKFLOW_TEST_ENV_KEY } from "../../job-4GOnasfT.mjs";
3
3
  import { pathToFileURL } from "node:url";
4
4
  import * as path from "node:path";
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/utils/test/mock.ts","../../../src/utils/test/index.ts"],"sourcesContent":["import * as path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { TailorInvoker } from \"@/types/user\";\n\ntype MainFunction = (args: Record<string, unknown>) => unknown | Promise<unknown>;\ntype QueryResolver = (query: string, params: unknown[]) => unknown[];\ntype JobHandler = (jobName: string, args: unknown) => unknown;\ntype WaitHandler = (key: string, payload: unknown) => unknown;\ntype ResolveHandler = (\n executionId: string,\n key: string,\n callback: (payload: unknown) => unknown,\n) => Promise<void> | void;\n\ninterface TailordbGlobal {\n tailordb?: {\n Client: new (config: { namespace?: string }) => {\n connect(): Promise<void> | void;\n end(): Promise<void> | void;\n queryObject(\n query: string,\n params?: unknown[],\n ): Promise<{ rows: unknown[] }> | { rows: unknown[] };\n };\n };\n tailor?: {\n workflow: {\n triggerJobFunction: (jobName: string, args: unknown) => unknown;\n wait?: (key: string, payload?: unknown) => unknown;\n resolve?: (\n executionId: string,\n key: string,\n callback: (payload: unknown) => unknown,\n ) => Promise<void>;\n };\n context: {\n getInvoker: () => tailor.context.Invoker | null;\n };\n };\n}\n\ninterface TailorErrorItem {\n message: string;\n path: (string | number)[];\n}\n\ninterface TailorErrorsGlobal {\n TailorErrors?: new (errors: TailorErrorItem[]) => Error;\n}\n\nconst GlobalThis = globalThis as TailordbGlobal & TailorErrorsGlobal;\n\n/**\n * Sets up a mock for `globalThis.tailordb.Client` used in bundled resolver/executor tests.\n * @deprecated Use `tailordbMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.\n * @param resolver - Optional function to resolve query results. Defaults to returning empty arrays.\n * @returns Object containing arrays of executed queries and created clients for assertions.\n */\nexport function setupTailordbMock(resolver: QueryResolver = () => []): {\n executedQueries: { query: string; params: unknown[] }[];\n createdClients: { namespace?: string; ended: boolean }[];\n} {\n const executedQueries: { query: string; params: unknown[] }[] = [];\n const createdClients: { namespace?: string; ended: boolean }[] = [];\n\n class MockTailordbClient {\n private record: { namespace?: string; ended: boolean };\n\n constructor({ namespace }: { namespace?: string }) {\n this.record = { namespace, ended: false };\n createdClients.push(this.record);\n }\n\n async connect(): Promise<void> {\n /* noop */\n }\n\n async end(): Promise<void> {\n this.record.ended = true;\n }\n\n async queryObject(query: string, params: unknown[] = []): Promise<{ rows: unknown[] }> {\n executedQueries.push({ query, params });\n return { rows: resolver(query, params) ?? [] };\n }\n }\n\n GlobalThis.tailordb = {\n Client: MockTailordbClient,\n } as typeof GlobalThis.tailordb;\n\n return { executedQueries, createdClients };\n}\n\n/**\n * Sets up a mock for `globalThis.tailor.workflow.triggerJobFunction` used in bundled workflow tests.\n * `wait`/`resolve` are stubbed to throw a helpful error directing to `workflowMock`,\n * so mistakenly calling wait without wait-point mocks produces a clear message instead of a TypeError.\n * @deprecated Use `workflowMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.\n * @param handler - Function that handles triggered job calls and returns results.\n * @returns Object containing an array of triggered jobs for assertions.\n */\nexport function setupWorkflowMock(handler: JobHandler): {\n triggeredJobs: { jobName: string; args: unknown }[];\n} {\n const triggeredJobs: { jobName: string; args: unknown }[] = [];\n\n GlobalThis.tailor = {\n ...GlobalThis.tailor,\n workflow: {\n wait: () => {\n throw new Error(\n \"tailor.workflow.wait is not mocked. Use workflowMock from @tailor-platform/sdk/vitest in tests.\",\n );\n },\n resolve: async () => {\n throw new Error(\n \"tailor.workflow.resolve is not mocked. Use workflowMock from @tailor-platform/sdk/vitest in tests.\",\n );\n },\n ...GlobalThis.tailor?.workflow,\n triggerJobFunction: (jobName: string, args: unknown) => {\n triggeredJobs.push({ jobName, args });\n return handler(jobName, args);\n },\n },\n } as typeof GlobalThis.tailor;\n\n return { triggeredJobs };\n}\n\n/**\n * Sets up a mock for `globalThis.tailor.context.getInvoker` used in bundled\n * resolver/executor/workflow tests.\n * @deprecated With the `tailor-runtime` environment from `@tailor-platform/sdk/vitest`, drive the invoker via `vi.spyOn(globalThis.tailor.context, \"getInvoker\").mockReturnValue(...)` for bundled tests, or pass `invoker` directly to `.body()` when unit-testing resolvers/executors/workflow jobs against the TypeScript source.\n * @param invoker - The `TailorInvoker` value to return, or `null` for anonymous.\n */\nexport function setupInvokerMock(invoker: TailorInvoker): void {\n const raw: tailor.context.Invoker | null = invoker\n ? {\n id: invoker.id,\n type: invoker.type,\n workspaceId: invoker.workspaceId,\n attributes: invoker.attributeList as string[],\n attributeMap: invoker.attributes as Record<string, unknown>,\n }\n : null;\n\n GlobalThis.tailor = {\n ...GlobalThis.tailor,\n context: {\n getInvoker: () => raw,\n },\n } as typeof GlobalThis.tailor;\n}\n\n/**\n * Sets up a mock for `globalThis.TailorErrors` used in bundled resolver tests.\n * Mimics the PF runtime's TailorErrors class that serializes errors with the `TailorErrors: ` prefix.\n * @deprecated Use the `tailor-runtime` environment from `@tailor-platform/sdk/vitest` which auto-injects TailorErrors.\n */\nexport function setupTailorErrorsMock(): void {\n GlobalThis.TailorErrors = class TailorErrors extends Error {\n errors: TailorErrorItem[];\n\n constructor(errors: TailorErrorItem[]) {\n super(`TailorErrors: ${JSON.stringify({ errors })}`);\n this.name = \"TailorErrors\";\n this.errors = errors;\n }\n };\n}\n\n/**\n * Sets up mocks for `globalThis.tailor.workflow.wait` and `.resolve` used in bundled workflow tests.\n * `triggerJobFunction` is stubbed to throw a helpful error directing to `setupWorkflowMock()`,\n * so mistakenly triggering a job without job mocks produces a clear message instead of silently returning undefined.\n * @deprecated Use `workflowMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.\n * `setWaitHandler` / `setResolveHandler` cover wait/resolve, and `waitCalls` / `resolveCalls` give the same assertion shape.\n * @param config - Optional handlers for wait and resolve calls.\n * @param config.onWait - Handler called when wait is invoked.\n * @param config.onResolve - Handler called when resolve is invoked.\n * @returns Object containing arrays of wait and resolve calls for assertions.\n */\nexport function setupWaitPointMock(config?: { onWait?: WaitHandler; onResolve?: ResolveHandler }): {\n waitCalls: { key: string; payload: unknown }[];\n resolveCalls: { executionId: string; key: string }[];\n} {\n const waitCalls: { key: string; payload: unknown }[] = [];\n const resolveCalls: { executionId: string; key: string }[] = [];\n\n GlobalThis.tailor = {\n ...GlobalThis.tailor,\n workflow: {\n triggerJobFunction: () => {\n throw new Error(\n \"tailor.workflow.triggerJobFunction is not mocked. Use setupWorkflowMock() in tests.\",\n );\n },\n ...GlobalThis.tailor?.workflow,\n wait: (key: string, payload?: unknown) => {\n waitCalls.push({ key, payload });\n return config?.onWait?.(key, payload);\n },\n resolve: async (\n executionId: string,\n key: string,\n callback: (payload: unknown) => unknown,\n ) => {\n resolveCalls.push({ executionId, key });\n await config?.onResolve?.(executionId, key, callback);\n },\n },\n } as typeof GlobalThis.tailor;\n\n return { waitCalls, resolveCalls };\n}\n\n/**\n * Creates a function that imports a bundled JS file and returns its `main` export.\n * Used to test bundled output from `apply --buildOnly`.\n * @param baseDir - Base directory where bundled files are located.\n * @returns An async function that takes a relative path and returns the `main` function.\n * @deprecated This is an SDK-internal testing helper. Bundling integrity is the SDK's responsibility,\n * not the application's — verify your code through unit tests against the TypeScript source and\n * E2E tests against a deployed application instead. This export will be removed in a future release.\n */\nexport function createImportMain(baseDir: string): (relativePath: string) => Promise<MainFunction> {\n return async (relativePath: string): Promise<MainFunction> => {\n const fileUrl = pathToFileURL(path.join(baseDir, relativePath));\n fileUrl.searchParams.set(\"v\", `${Date.now()}-${Math.random()}`);\n const module = await import(fileUrl.href);\n const main = module.main;\n if (typeof main !== \"function\") {\n throw new Error(`Expected \"main\" to be a function in ${relativePath}, got ${typeof main}`);\n }\n return main;\n };\n}\n","import type { output, TailorUser } from \"@/configure\";\nimport type { TailorDBType } from \"@/configure/services/tailordb/schema\";\nimport type { TailorField } from \"@/configure/types/type\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nexport { WORKFLOW_TEST_ENV_KEY } from \"@/configure/services/workflow/job\";\nexport {\n setupTailordbMock,\n setupTailorErrorsMock,\n setupWorkflowMock,\n setupInvokerMock,\n setupWaitPointMock,\n createImportMain,\n} from \"./mock\";\n\n/** Represents an unauthenticated user in the Tailor platform. */\nexport const unauthenticatedTailorUser = {\n id: \"00000000-0000-0000-0000-000000000000\",\n type: \"\",\n workspaceId: \"00000000-0000-0000-0000-000000000000\",\n attributes: null,\n attributeList: [],\n} as const satisfies TailorUser;\n\n/**\n * Creates a hook function that processes TailorDB type fields\n * - Uses existing id from data if provided, otherwise generates UUID for id fields\n * - Recursively processes nested types\n * - Executes hooks.create for fields with create hooks\n * @template T - The output type of the hook function\n * @param type - TailorDB type definition\n * @returns A function that transforms input data according to field hooks\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createTailorDBHook<T extends TailorDBType<any, any>>(type: T) {\n return (data: unknown) => {\n return Object.entries(type.fields).reduce(\n (hooked, [key, value]) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const field = value as TailorField<any, any, any>;\n if (key === \"id\") {\n // Use existing id from data if provided, otherwise generate new UUID\n const existingId =\n data && typeof data === \"object\" ? (data as Record<string, unknown>)[key] : undefined;\n hooked[key] = existingId ?? crypto.randomUUID();\n } else if (field.type === \"nested\") {\n const nestedValue =\n data && typeof data === \"object\" ? (data as Record<string, unknown>)[key] : undefined;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const nestedHook = createTailorDBHook({ fields: field.fields } as any);\n if (field.metadata.array) {\n // For nested array fields, recurse per element and pass through non-array values\n // (e.g. null/undefined for optional fields) so validation sees the original value.\n hooked[key] = Array.isArray(nestedValue)\n ? nestedValue.map((item) => nestedHook(item))\n : nestedValue;\n } else {\n hooked[key] = nestedHook(nestedValue);\n }\n } else if (field.metadata.hooks?.create) {\n hooked[key] = field.metadata.hooks.create({\n value: (data as Record<string, unknown>)[key],\n data: data,\n user: unauthenticatedTailorUser,\n });\n if (hooked[key] instanceof Date) {\n hooked[key] = hooked[key].toISOString();\n }\n } else if (data && typeof data === \"object\") {\n hooked[key] = (data as Record<string, unknown>)[key];\n }\n return hooked;\n },\n {} as Record<string, unknown>,\n ) as Partial<output<T>>;\n };\n}\n\n/**\n * Creates the standard schema definition for lines-db\n * This returns the first argument for defineSchema with the ~standard section\n * @template T - The output type after validation\n * @param schemaType - TailorDB field schema for validation\n * @param hook - Hook function to transform data before validation\n * @returns Schema object with ~standard section for defineSchema\n */\nexport function createStandardSchema<T = Record<string, unknown>>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schemaType: TailorField<any, T>,\n hook: (data: unknown) => Partial<T>,\n) {\n return {\n \"~standard\": {\n version: 1,\n vendor: \"@tailor-platform/sdk\",\n validate: (value: unknown) => {\n const hooked = hook(value);\n const result = schemaType.parse({\n value: hooked,\n data: hooked,\n user: unauthenticatedTailorUser,\n });\n if (result.issues) {\n return result;\n }\n return { value: hooked as T };\n },\n },\n } as const satisfies StandardSchemaV1<T>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/utils/test/mock.ts","../../../src/utils/test/index.ts"],"sourcesContent":["import * as path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { ContextInvoker } from \"@/runtime/context\";\nimport type { TailorInvoker } from \"@/types/user\";\n\ntype MainFunction = (args: Record<string, unknown>) => unknown | Promise<unknown>;\ntype QueryResolver = (query: string, params: unknown[]) => unknown[];\ntype JobHandler = (jobName: string, args: unknown) => unknown;\ntype WaitHandler = (key: string, payload: unknown) => unknown;\ntype ResolveHandler = (\n executionId: string,\n key: string,\n callback: (payload: unknown) => unknown,\n) => Promise<void> | void;\n\ninterface TailordbGlobal {\n tailordb?: {\n Client: new (config: { namespace?: string }) => {\n connect(): Promise<void> | void;\n end(): Promise<void> | void;\n queryObject(\n query: string,\n params?: unknown[],\n ): Promise<{ rows: unknown[] }> | { rows: unknown[] };\n };\n };\n tailor?: {\n workflow: {\n triggerJobFunction: (jobName: string, args: unknown) => unknown;\n wait?: (key: string, payload?: unknown) => unknown;\n resolve?: (\n executionId: string,\n key: string,\n callback: (payload: unknown) => unknown,\n ) => Promise<void>;\n };\n context: {\n getInvoker: () => ContextInvoker | null;\n };\n };\n}\n\ninterface TailorErrorItem {\n message: string;\n path: (string | number)[];\n}\n\ninterface TailorErrorsGlobal {\n TailorErrors?: new (errors: TailorErrorItem[]) => Error;\n}\n\nconst GlobalThis = globalThis as TailordbGlobal & TailorErrorsGlobal;\n\n/**\n * Sets up a mock for `globalThis.tailordb.Client` used in bundled resolver/executor tests.\n * @deprecated Use `tailordbMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.\n * @param resolver - Optional function to resolve query results. Defaults to returning empty arrays.\n * @returns Object containing arrays of executed queries and created clients for assertions.\n */\nexport function setupTailordbMock(resolver: QueryResolver = () => []): {\n executedQueries: { query: string; params: unknown[] }[];\n createdClients: { namespace?: string; ended: boolean }[];\n} {\n const executedQueries: { query: string; params: unknown[] }[] = [];\n const createdClients: { namespace?: string; ended: boolean }[] = [];\n\n class MockTailordbClient {\n private record: { namespace?: string; ended: boolean };\n\n constructor({ namespace }: { namespace?: string }) {\n this.record = { namespace, ended: false };\n createdClients.push(this.record);\n }\n\n async connect(): Promise<void> {\n /* noop */\n }\n\n async end(): Promise<void> {\n this.record.ended = true;\n }\n\n async queryObject(query: string, params: unknown[] = []): Promise<{ rows: unknown[] }> {\n executedQueries.push({ query, params });\n return { rows: resolver(query, params) ?? [] };\n }\n }\n\n GlobalThis.tailordb = {\n Client: MockTailordbClient,\n } as typeof GlobalThis.tailordb;\n\n return { executedQueries, createdClients };\n}\n\n/**\n * Sets up a mock for `globalThis.tailor.workflow.triggerJobFunction` used in bundled workflow tests.\n * `wait`/`resolve` are stubbed to throw a helpful error directing to `workflowMock`,\n * so mistakenly calling wait without wait-point mocks produces a clear message instead of a TypeError.\n * @deprecated Use `workflowMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.\n * @param handler - Function that handles triggered job calls and returns results.\n * @returns Object containing an array of triggered jobs for assertions.\n */\nexport function setupWorkflowMock(handler: JobHandler): {\n triggeredJobs: { jobName: string; args: unknown }[];\n} {\n const triggeredJobs: { jobName: string; args: unknown }[] = [];\n\n GlobalThis.tailor = {\n ...GlobalThis.tailor,\n workflow: {\n wait: () => {\n throw new Error(\n \"tailor.workflow.wait is not mocked. Use workflowMock from @tailor-platform/sdk/vitest in tests.\",\n );\n },\n resolve: async () => {\n throw new Error(\n \"tailor.workflow.resolve is not mocked. Use workflowMock from @tailor-platform/sdk/vitest in tests.\",\n );\n },\n ...GlobalThis.tailor?.workflow,\n triggerJobFunction: (jobName: string, args: unknown) => {\n triggeredJobs.push({ jobName, args });\n return handler(jobName, args);\n },\n },\n } as typeof GlobalThis.tailor;\n\n return { triggeredJobs };\n}\n\n/**\n * Sets up a mock for `globalThis.tailor.context.getInvoker` used in bundled\n * resolver/executor/workflow tests.\n * @deprecated With the `tailor-runtime` environment from `@tailor-platform/sdk/vitest`, drive the invoker via `vi.spyOn(globalThis.tailor.context, \"getInvoker\").mockReturnValue(...)` for bundled tests, or pass `invoker` directly to `.body()` when unit-testing resolvers/executors/workflow jobs against the TypeScript source.\n * @param invoker - The `TailorInvoker` value to return, or `null` for anonymous.\n */\nexport function setupInvokerMock(invoker: TailorInvoker): void {\n const raw: ContextInvoker | null = invoker\n ? {\n id: invoker.id,\n type: invoker.type,\n workspaceId: invoker.workspaceId,\n attributes: invoker.attributeList as string[],\n attributeMap: invoker.attributes as Record<string, unknown>,\n }\n : null;\n\n GlobalThis.tailor = {\n ...GlobalThis.tailor,\n context: {\n getInvoker: () => raw,\n },\n } as typeof GlobalThis.tailor;\n}\n\n/**\n * Sets up a mock for `globalThis.TailorErrors` used in bundled resolver tests.\n * Mimics the PF runtime's TailorErrors class that serializes errors with the `TailorErrors: ` prefix.\n * @deprecated Use the `tailor-runtime` environment from `@tailor-platform/sdk/vitest` which auto-injects TailorErrors.\n */\nexport function setupTailorErrorsMock(): void {\n GlobalThis.TailorErrors = class TailorErrors extends Error {\n errors: TailorErrorItem[];\n\n constructor(errors: TailorErrorItem[]) {\n super(`TailorErrors: ${JSON.stringify({ errors })}`);\n this.name = \"TailorErrors\";\n this.errors = errors;\n }\n };\n}\n\n/**\n * Sets up mocks for `globalThis.tailor.workflow.wait` and `.resolve` used in bundled workflow tests.\n * `triggerJobFunction` is stubbed to throw a helpful error directing to `setupWorkflowMock()`,\n * so mistakenly triggering a job without job mocks produces a clear message instead of silently returning undefined.\n * @deprecated Use `workflowMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.\n * `setWaitHandler` / `setResolveHandler` cover wait/resolve, and `waitCalls` / `resolveCalls` give the same assertion shape.\n * @param config - Optional handlers for wait and resolve calls.\n * @param config.onWait - Handler called when wait is invoked.\n * @param config.onResolve - Handler called when resolve is invoked.\n * @returns Object containing arrays of wait and resolve calls for assertions.\n */\nexport function setupWaitPointMock(config?: { onWait?: WaitHandler; onResolve?: ResolveHandler }): {\n waitCalls: { key: string; payload: unknown }[];\n resolveCalls: { executionId: string; key: string }[];\n} {\n const waitCalls: { key: string; payload: unknown }[] = [];\n const resolveCalls: { executionId: string; key: string }[] = [];\n\n GlobalThis.tailor = {\n ...GlobalThis.tailor,\n workflow: {\n triggerJobFunction: () => {\n throw new Error(\n \"tailor.workflow.triggerJobFunction is not mocked. Use setupWorkflowMock() in tests.\",\n );\n },\n ...GlobalThis.tailor?.workflow,\n wait: (key: string, payload?: unknown) => {\n waitCalls.push({ key, payload });\n return config?.onWait?.(key, payload);\n },\n resolve: async (\n executionId: string,\n key: string,\n callback: (payload: unknown) => unknown,\n ) => {\n resolveCalls.push({ executionId, key });\n await config?.onResolve?.(executionId, key, callback);\n },\n },\n } as typeof GlobalThis.tailor;\n\n return { waitCalls, resolveCalls };\n}\n\n/**\n * Creates a function that imports a bundled JS file and returns its `main` export.\n * Used to test bundled output from `apply --buildOnly`.\n * @param baseDir - Base directory where bundled files are located.\n * @returns An async function that takes a relative path and returns the `main` function.\n * @deprecated This is an SDK-internal testing helper. Bundling integrity is the SDK's responsibility,\n * not the application's — verify your code through unit tests against the TypeScript source and\n * E2E tests against a deployed application instead. This export will be removed in a future release.\n */\nexport function createImportMain(baseDir: string): (relativePath: string) => Promise<MainFunction> {\n return async (relativePath: string): Promise<MainFunction> => {\n const fileUrl = pathToFileURL(path.join(baseDir, relativePath));\n fileUrl.searchParams.set(\"v\", `${Date.now()}-${Math.random()}`);\n const module = await import(fileUrl.href);\n const main = module.main;\n if (typeof main !== \"function\") {\n throw new Error(`Expected \"main\" to be a function in ${relativePath}, got ${typeof main}`);\n }\n return main;\n };\n}\n","import type { output, TailorUser } from \"@/configure\";\nimport type { TailorDBType } from \"@/configure/services/tailordb/schema\";\nimport type { TailorField } from \"@/configure/types/type\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nexport { WORKFLOW_TEST_ENV_KEY } from \"@/configure/services/workflow/job\";\nexport {\n setupTailordbMock,\n setupTailorErrorsMock,\n setupWorkflowMock,\n setupInvokerMock,\n setupWaitPointMock,\n createImportMain,\n} from \"./mock\";\n\n/** Represents an unauthenticated user in the Tailor platform. */\nexport const unauthenticatedTailorUser = {\n id: \"00000000-0000-0000-0000-000000000000\",\n type: \"\",\n workspaceId: \"00000000-0000-0000-0000-000000000000\",\n attributes: null,\n attributeList: [],\n} as const satisfies TailorUser;\n\n/**\n * Creates a hook function that processes TailorDB type fields\n * - Uses existing id from data if provided, otherwise generates UUID for id fields\n * - Recursively processes nested types\n * - Executes hooks.create for fields with create hooks\n * @template T - The output type of the hook function\n * @param type - TailorDB type definition\n * @returns A function that transforms input data according to field hooks\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createTailorDBHook<T extends TailorDBType<any, any>>(type: T) {\n return (data: unknown) => {\n return Object.entries(type.fields).reduce(\n (hooked, [key, value]) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const field = value as TailorField<any, any, any>;\n if (key === \"id\") {\n // Use existing id from data if provided, otherwise generate new UUID\n const existingId =\n data && typeof data === \"object\" ? (data as Record<string, unknown>)[key] : undefined;\n hooked[key] = existingId ?? crypto.randomUUID();\n } else if (field.type === \"nested\") {\n const nestedValue =\n data && typeof data === \"object\" ? (data as Record<string, unknown>)[key] : undefined;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const nestedHook = createTailorDBHook({ fields: field.fields } as any);\n if (field.metadata.array) {\n // For nested array fields, recurse per element and pass through non-array values\n // (e.g. null/undefined for optional fields) so validation sees the original value.\n hooked[key] = Array.isArray(nestedValue)\n ? nestedValue.map((item) => nestedHook(item))\n : nestedValue;\n } else {\n hooked[key] = nestedHook(nestedValue);\n }\n } else if (field.metadata.hooks?.create) {\n hooked[key] = field.metadata.hooks.create({\n value: (data as Record<string, unknown>)[key],\n data: data,\n user: unauthenticatedTailorUser,\n });\n if (hooked[key] instanceof Date) {\n hooked[key] = hooked[key].toISOString();\n }\n } else if (data && typeof data === \"object\") {\n hooked[key] = (data as Record<string, unknown>)[key];\n }\n return hooked;\n },\n {} as Record<string, unknown>,\n ) as Partial<output<T>>;\n };\n}\n\n/**\n * Creates the standard schema definition for lines-db\n * This returns the first argument for defineSchema with the ~standard section\n * @template T - The output type after validation\n * @param schemaType - TailorDB field schema for validation\n * @param hook - Hook function to transform data before validation\n * @returns Schema object with ~standard section for defineSchema\n */\nexport function createStandardSchema<T = Record<string, unknown>>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schemaType: TailorField<any, T>,\n hook: (data: unknown) => Partial<T>,\n) {\n return {\n \"~standard\": {\n version: 1,\n vendor: \"@tailor-platform/sdk\",\n validate: (value: unknown) => {\n const hooked = hook(value);\n const result = schemaType.parse({\n value: hooked,\n data: hooked,\n user: unauthenticatedTailorUser,\n });\n if (result.issues) {\n return result;\n }\n return { value: hooked as T };\n },\n },\n } as const satisfies StandardSchemaV1<T>;\n}\n"],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- /// <reference types="@tailor-platform/function-types" />
2
1
  //#region src/vitest/environment.d.ts
3
2
  declare const _default: {
4
3
  name: string;
@@ -1,5 +1,5 @@
1
1
 
2
- import { c as injectMocks, i as cleanupMocks, n as STATE_KEY, t as RUNTIME_FLAG_KEY } from "../mock-BfL09ULZ.mjs";
2
+ import { c as injectMocks, i as cleanupMocks, n as STATE_KEY, t as RUNTIME_FLAG_KEY } from "../mock-B2t5gDMl.mjs";
3
3
  import * as globals from "globals";
4
4
 
5
5
  //#region src/vitest/environment.ts
@@ -1,4 +1,3 @@
1
- /// <reference types="@tailor-platform/function-types" />
2
1
  import { Plugin } from "vitest/config";
3
2
 
4
3
  //#region src/vitest/mock.d.ts
@@ -304,8 +303,8 @@ declare const iconvMock: {
304
303
  *
305
304
  * 3. **Platform API mocks** (environment) — All platform APIs are auto-injected with
306
305
  * control objects: `tailordbMock`, `workflowMock`, `secretmanagerMock`,
307
- * `authconnectionMock`, `idpMock`, `fileMock`, `iconvMock`. Each provides response
308
- * configuration, call recording, and reset.
306
+ * `authconnectionMock`, `idpMock`, `fileMock`, `iconvMock`. Each
307
+ * provides response configuration, call recording, and reset.
309
308
  *
310
309
  * 4. **Environment resolution** — Rewrites `environment: "tailor-runtime"` to the
311
310
  * absolute path of the bundled environment module via the config hook.
@@ -1,5 +1,5 @@
1
1
 
2
- import { a as fileMock, d as workflowMock, l as secretmanagerMock, o as iconvMock, r as authconnectionMock, s as idpMock, u as tailordbMock } from "../mock-BfL09ULZ.mjs";
2
+ import { a as fileMock, d as workflowMock, l as secretmanagerMock, o as iconvMock, r as authconnectionMock, s as idpMock, u as tailordbMock } from "../mock-B2t5gDMl.mjs";
3
3
  import { builtinModules } from "node:module";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { dirname, isAbsolute, matchesGlob, relative, resolve } from "node:path";
@@ -308,8 +308,8 @@ function createEnvironmentPlugin(options) {
308
308
  *
309
309
  * 3. **Platform API mocks** (environment) — All platform APIs are auto-injected with
310
310
  * control objects: `tailordbMock`, `workflowMock`, `secretmanagerMock`,
311
- * `authconnectionMock`, `idpMock`, `fileMock`, `iconvMock`. Each provides response
312
- * configuration, call recording, and reset.
311
+ * `authconnectionMock`, `idpMock`, `fileMock`, `iconvMock`. Each
312
+ * provides response configuration, call recording, and reset.
313
313
  *
314
314
  * 4. **Environment resolution** — Rewrites `environment: "tailor-runtime"` to the
315
315
  * absolute path of the bundled environment module via the config hook.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/vitest/blocked-modules.ts","../../src/vitest/plugin.ts","../../src/vitest/index.ts"],"sourcesContent":["/**\n * Blocked Node.js built-in modules and their Web Standard API alternatives.\n *\n * The Tailor Platform runtime only provides Web Standard APIs.\n * These Node.js modules are not available and should be replaced with\n * the suggested alternatives.\n */\nimport { builtinModules } from \"node:module\";\n\n// Suggestions keyed by bare specifier. Lookup also checks with \"node:\" prefix stripped.\nconst SUGGESTIONS: Record<string, string> = {\n crypto: \"Use the Web Crypto API (globalThis.crypto) instead.\",\n buffer: \"Use Uint8Array or ArrayBuffer instead.\",\n fs: \"File system access is not available in the Tailor Platform runtime.\",\n \"fs/promises\": \"File system access is not available in the Tailor Platform runtime.\",\n path: \"Use URL or URLPattern for path manipulation.\",\n http: \"Use the Fetch API (globalThis.fetch) for HTTP requests instead.\",\n https: \"Use the Fetch API (globalThis.fetch) for HTTPS requests instead.\",\n url: \"Use the URL and URLSearchParams Web APIs instead.\",\n util: \"Use Web Standard APIs instead.\",\n stream: \"Use Web Streams API (ReadableStream, WritableStream, TransformStream) instead.\",\n \"stream/web\": \"Use Web Streams API (ReadableStream, WritableStream, TransformStream) instead.\",\n events: \"Use EventTarget instead.\",\n zlib: \"Use CompressionStream and DecompressionStream Web APIs instead.\",\n querystring: \"Use URLSearchParams instead.\",\n string_decoder: \"Use TextDecoder instead.\",\n};\n\nconst BLOCKED_MODULES = new Set<string>();\nfor (const mod of builtinModules) {\n BLOCKED_MODULES.add(mod);\n BLOCKED_MODULES.add(`node:${mod}`);\n}\n\n/**\n * Check if a module specifier is a blocked Node.js built-in.\n * @param specifier - Module specifier to check (e.g. \"node:crypto\", \"fs\")\n * @returns Whether the specifier is blocked\n */\nexport function isBlockedModule(specifier: string): boolean {\n return BLOCKED_MODULES.has(specifier);\n}\n\n/**\n * Get the error message for a blocked module import.\n * @param specifier - Module specifier that was blocked\n * @returns Error message with optional suggestion for the Web Standard API alternative\n */\nexport function getBlockedMessage(specifier: string): string {\n const bare = specifier.startsWith(\"node:\") ? specifier.slice(5) : specifier;\n const suggestion = SUGGESTIONS[bare];\n const base = `\"${specifier}\" is not available in the Tailor Platform runtime.`;\n return suggestion ? `${base} ${suggestion}` : base;\n}\n","import { dirname, isAbsolute, matchesGlob, relative, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { isBlockedModule, getBlockedMessage } from \"./blocked-modules\";\nimport type { Plugin } from \"vitest/config\";\n\nconst DEFAULT_TEST_INCLUDE = [\"**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}\"];\n\ninterface ExportSpecifierNode {\n type?: string;\n exported?: { name?: unknown } | null;\n}\n\ninterface ImportLikeNode {\n type: string;\n start: number;\n end: number;\n source?: { value?: unknown } | null;\n specifiers?: ExportSpecifierNode[] | null;\n exported?: { name?: unknown } | null;\n}\n\nconst IMPORT_LIKE_TYPES = new Set([\n \"ImportDeclaration\",\n \"ExportNamedDeclaration\",\n \"ExportAllDeclaration\",\n]);\n\n// Re-export specifiers (`export { x as Y } from \"...\"`) accept any\n// `IdentifierName` for `Y` — including reserved words like `delete`. But\n// `export const Y = ...` requires a `BindingIdentifier`, which forbids\n// reserved words and the strict-mode-banned `arguments` / `eval`. Synthesizing\n// `export const delete = ...` would yield a syntax error, so we fall back to\n// plain `throw` for unsafe names.\nconst UNSAFE_BINDING_NAMES = new Set([\n // ReservedWord (ES2022+)\n \"break\",\n \"case\",\n \"catch\",\n \"class\",\n \"const\",\n \"continue\",\n \"debugger\",\n \"default\",\n \"delete\",\n \"do\",\n \"else\",\n \"enum\",\n \"export\",\n \"extends\",\n \"false\",\n \"finally\",\n \"for\",\n \"function\",\n \"if\",\n \"import\",\n \"in\",\n \"instanceof\",\n \"new\",\n \"null\",\n \"return\",\n \"super\",\n \"switch\",\n \"this\",\n \"throw\",\n \"true\",\n \"try\",\n \"typeof\",\n \"var\",\n \"void\",\n \"while\",\n \"with\",\n \"yield\",\n // Strict-mode reserved (ESM is always strict)\n \"let\",\n \"static\",\n \"implements\",\n \"interface\",\n \"package\",\n \"private\",\n \"protected\",\n \"public\",\n // Module-specific reserved\n \"await\",\n // Banned as binding names in strict mode\n \"arguments\",\n \"eval\",\n]);\n\nconst ID_START = /^[A-Za-z_$]/;\nconst ID_CONT = /^[A-Za-z0-9_$]*$/;\n\nfunction isSafeBindingName(name: string): boolean {\n if (UNSAFE_BINDING_NAMES.has(name)) return false;\n if (name.length === 0) return false;\n // Restrict to ASCII identifiers — Unicode bindings are valid JS but rare\n // for re-exports of node:* modules, and a regex over the full\n // ID_Start/ID_Continue sets adds substantial weight for marginal gain.\n return ID_START.test(name[0] ?? \"\") && ID_CONT.test(name.slice(1));\n}\n\nfunction buildBlockedReplacement(node: ImportLikeNode, message: string): string {\n // JSON.stringify yields a fully-escaped string literal (including the\n // surrounding quotes), so we don't need to manually handle backslashes,\n // newlines, or other control characters that may appear in the message.\n const literal = JSON.stringify(message);\n const throwStmt = `throw new Error(${literal});`;\n const throwExpr = `(() => { throw new Error(${literal}); })()`;\n\n if (node.type === \"ExportNamedDeclaration\") {\n const specs = node.specifiers ?? [];\n const stubs: string[] = [];\n for (const spec of specs) {\n const exportedName = spec.exported?.name;\n if (typeof exportedName !== \"string\") continue;\n if (exportedName === \"default\") {\n stubs.push(`export default ${throwExpr};`);\n continue;\n }\n // Reserved words can be re-export names but not binding names.\n // Bail to a plain throw rather than emit invalid syntax.\n if (!isSafeBindingName(exportedName)) return throwStmt;\n stubs.push(`export const ${exportedName} = ${throwExpr};`);\n }\n return stubs.length > 0 ? stubs.join(\" \") : throwStmt;\n }\n\n if (node.type === \"ExportAllDeclaration\") {\n const exportedName = node.exported?.name;\n if (typeof exportedName === \"string\" && isSafeBindingName(exportedName)) {\n return `export const ${exportedName} = ${throwExpr};`;\n }\n return throwStmt;\n }\n\n return throwStmt;\n}\n\n/**\n * Vite plugin that blocks Node.js built-in module imports from production code.\n *\n * Uses the `transform` hook to walk the Rollup-provided AST of non-test source\n * files for static `node:*` imports and re-exports.\n * `ImportDeclaration` and bare `export * from \"...\"` are replaced with a\n * `throw new Error(...)` statement so the failure surfaces at evaluation time.\n * `ExportNamedDeclaration` (`export { x, y as z } from \"...\"`) and namespaced\n * `export * as ns from \"...\"` are rewritten to per-binding stub exports\n * (`export const x = (() => { throw new Error(...) })();`). The IIFE throws\n * eagerly during module evaluation (same timing as a top-level `throw`), but\n * preserving the declared export bindings ensures the surfaced error is the\n * actual \"node:* not available\" message rather than an opaque\n * \"missing export\" raised by the loader.\n * Vitest treats `node:*` as external SSR modules (skipping `resolveId`), so\n * source-level transformation is the only reliable interception point.\n * Runs in the default phase (no `enforce: \"pre\"`) so esbuild's TypeScript\n * transform strips `import type` first; only runtime imports reach this hook.\n * Node.js globals not in the platform runtime are removed by the environment (whitelist-based).\n * Test file patterns are read from the resolved Vitest config (`test.include`).\n * Vitest setup files (`test.setupFiles`) and global-setup files\n * (`test.globalSetup`) are also exempted: they run in the test runner host,\n * not in the emulated platform runtime, so they may freely use `node:*`\n * modules (e.g. `node:url` for `pathToFileURL`).\n * @returns Vite plugin\n */\nexport function createBlockPlugin(): Plugin {\n let isTestFile: (id: string) => boolean = () => false;\n let isUserSourceFile: (id: string) => boolean = () => false;\n\n return {\n name: \"tailor-runtime-block-node\",\n\n configResolved(config) {\n type HostFileTestConfig = {\n include?: string[];\n setupFiles?: string | string[];\n globalSetup?: string | string[];\n root?: string;\n };\n const testConfig = (\n config as typeof config & {\n test?: HostFileTestConfig & {\n projects?: { test?: HostFileTestConfig }[];\n };\n }\n ).test;\n const root = testConfig?.root ?? config.root;\n // Setup files and global-setup files run in the Vitest host (not the\n // emulated runtime), so they may freely import node:* modules. Collect\n // them from the top-level config AND from each `test.projects[i]` —\n // per-project setup files run in the host too and would otherwise be\n // transformed as production code, breaking node:* imports inside them.\n const toAbsolutePaths = (value: string | string[] | undefined, baseRoot: string) =>\n (Array.isArray(value) ? value : value ? [value] : []).map((f) => resolve(baseRoot, f));\n const exemptHostFiles = new Set<string>([\n ...toAbsolutePaths(testConfig?.setupFiles, root),\n ...toAbsolutePaths(testConfig?.globalSetup, root),\n ]);\n // Vitest projects can each define their own `test.include` (and root).\n // A project that uses non-default patterns (e.g. `tests/**/*.spec.ts`)\n // must also be considered when classifying test files — otherwise its\n // tests would be treated as production code and have node:* imports\n // rewritten. Build a list of (root, patterns) pairs covering top-level\n // + every project, and accept a file if any pair matches.\n const includePairs: { root: string; patterns: string[] }[] = [\n { root, patterns: testConfig?.include ?? DEFAULT_TEST_INCLUDE },\n ];\n for (const project of testConfig?.projects ?? []) {\n const projectTest = project?.test;\n if (!projectTest) continue;\n const projectRoot = projectTest.root ?? root;\n for (const f of toAbsolutePaths(projectTest.setupFiles, projectRoot)) {\n exemptHostFiles.add(f);\n }\n for (const f of toAbsolutePaths(projectTest.globalSetup, projectRoot)) {\n exemptHostFiles.add(f);\n }\n includePairs.push({\n root: projectRoot,\n patterns: projectTest.include ?? DEFAULT_TEST_INCLUDE,\n });\n }\n isTestFile = (id: string) => {\n if (exemptHostFiles.has(id)) return true;\n return includePairs.some(({ root: r, patterns }) => {\n const candidate = isAbsolute(id) ? relative(r, id) : id;\n return patterns.some((pattern) => matchesGlob(candidate, pattern));\n });\n };\n // Only transform files inside the project root. With pnpm workspaces,\n // dependencies are symlinked and Vite resolves them to absolute paths\n // outside `node_modules`, so the substring check alone is insufficient.\n // Non-absolute ids are Vite-internal: virtual modules (`\\0...`,\n // `virtual:...`), bare specifiers, etc. Those are never user source\n // files and must not be parsed/transformed.\n isUserSourceFile = (id: string) => {\n if (!isAbsolute(id)) return false;\n const rel = relative(root, id);\n return rel !== \"\" && !rel.startsWith(\"..\") && !isAbsolute(rel);\n };\n },\n\n transform(code, id) {\n // Vite can pass ids with query/hash suffixes (e.g. `file.ts?import`,\n // `file.ts?v=hash`). Strip them so exact-path lookups (Set membership,\n // glob matching, absolute-path checks) match what callers configured.\n const queryIdx = id.search(/[?#]/);\n const cleanId = queryIdx === -1 ? id : id.slice(0, queryIdx);\n\n if (isTestFile(cleanId)) return undefined;\n if (cleanId.includes(\"node_modules\")) return undefined;\n if (!isUserSourceFile(cleanId)) return undefined;\n\n let ast: { body: ImportLikeNode[] };\n try {\n ast = this.parse(code) as unknown as { body: ImportLikeNode[] };\n } catch {\n // Not parseable as ESM (e.g. JSON, asset). Let other plugins handle it.\n return undefined;\n }\n\n const replacements: { start: number; end: number; replacement: string }[] = [];\n for (const node of ast.body) {\n if (!IMPORT_LIKE_TYPES.has(node.type)) continue;\n const specifier = node.source?.value;\n if (typeof specifier !== \"string\") continue;\n if (isBlockedModule(specifier)) {\n replacements.push({\n start: node.start,\n end: node.end,\n replacement: buildBlockedReplacement(node, getBlockedMessage(specifier)),\n });\n }\n }\n\n if (replacements.length === 0) return undefined;\n\n let transformed = code;\n for (const r of replacements.sort((a, b) => b.start - a.start)) {\n transformed = transformed.slice(0, r.start) + r.replacement + transformed.slice(r.end);\n }\n\n return { code: transformed, map: null };\n },\n };\n}\n\nconst ENVIRONMENT_NAME = \"tailor-runtime\";\n\n/**\n * Vite plugin that resolves the tailor-runtime environment and injects setup files.\n *\n * Vitest resolves environments starting with \".\" or \"/\" as file paths.\n * This plugin rewrites `environment: \"tailor-runtime\"` to the absolute path\n * of the bundled environment module, both at the top-level and per-project.\n * It also injects the setup file that removes Vitest-dependent globals\n * (like `performance`) per-test via beforeEach/afterEach hooks.\n * @param options - Optional configuration\n * @param options.config - Path to tailor.config.ts to load SecretManager values into mock\n * @returns Vite plugin\n */\nexport function createEnvironmentPlugin(options?: { config?: string }): Plugin {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const environmentPath = resolve(currentDir, \"environment.mjs\");\n const setupPath = resolve(currentDir, \"setup.mjs\");\n\n return {\n name: \"tailor-runtime-environment\",\n\n config(config) {\n const testConfig = config.test as\n | (Record<string, unknown> & {\n projects?: Record<string, unknown>[];\n setupFiles?: string | string[];\n })\n | undefined;\n\n // Rewrite environment name to absolute path at top-level\n let usesTailorRuntime = false;\n if (testConfig?.environment === ENVIRONMENT_NAME) {\n testConfig.environment = environmentPath;\n usesTailorRuntime = true;\n }\n\n // Rewrite in each project config\n if (testConfig?.projects) {\n for (const project of testConfig.projects) {\n const projectTest = project.test as Record<string, unknown> | undefined;\n if (projectTest?.environment === ENVIRONMENT_NAME) {\n projectTest.environment = environmentPath;\n usesTailorRuntime = true;\n }\n }\n }\n\n // Pass config path to setup.ts via env var (cross-process compatible).\n // Always clear first, then set only when tailor-runtime is actually\n // selected. This makes the env var deterministic across Vite config\n // reloads (watch mode, programmatic re-init): a stale value from a\n // prior iteration cannot make setup.ts load secrets from an old config.\n // The leading `__` marks this as plugin-private, so deleting any\n // pre-existing value is safe.\n delete process.env.__TAILOR_RUNTIME_CONFIG;\n if (options?.config && usesTailorRuntime) {\n // Resolve against the user-provided Vite root when present (falling\n // back to cwd). Vitest projects with a non-cwd `root` would otherwise\n // resolve a relative options.config against the wrong directory.\n const configRoot = (config.root as string | undefined) ?? process.cwd();\n const configAbsPath = resolve(configRoot, options.config);\n process.env.__TAILOR_RUNTIME_CONFIG = configAbsPath;\n }\n\n // Normalize a user-provided string `setupFiles` into an array so Vite's\n // array-concat merge sees both sides as arrays (the string form would\n // otherwise be replaced rather than concatenated by some merge paths).\n // Vite then concatenates the user's array with our [setupPath].\n if (testConfig && typeof testConfig.setupFiles === \"string\") {\n testConfig.setupFiles = [testConfig.setupFiles];\n }\n\n return {\n test: {\n setupFiles: [setupPath],\n },\n };\n },\n };\n}\n","import { createBlockPlugin, createEnvironmentPlugin } from \"./plugin\";\nimport type { Plugin } from \"vitest/config\";\n\n/**\n * Creates Vitest plugins that emulate the Tailor Platform function runtime environment.\n *\n * **Beta:** This API may change in future releases.\n *\n * ## What it does\n *\n * 1. **Node.js module blocking** (transform hook) — Imports of `node:*` modules\n * (and bare builtins like `crypto`, `fs`) in non-test source files are replaced\n * with code that throws an error with a suggestion for the Web Standard API alternative.\n * Test files are exempt and can use `node:*` freely. Test file patterns are read\n * from the resolved Vitest config (`test.include`).\n *\n * 2. **Node.js globals removal** (environment + setup) — Only globals available in the\n * Tailor Platform runtime are kept (whitelist: ECMAScript standard, Web Standard APIs\n * from bootstrap.js, platform mocks). All others (`Buffer`, `global`, `setImmediate`,\n * `__dirname`, `__filename`, etc.) are removed. `performance` is removed per-test\n * via beforeEach/afterEach since Vitest needs it during initialization.\n *\n * 3. **Platform API mocks** (environment) — All platform APIs are auto-injected with\n * control objects: `tailordbMock`, `workflowMock`, `secretmanagerMock`,\n * `authconnectionMock`, `idpMock`, `fileMock`, `iconvMock`. Each provides response\n * configuration, call recording, and reset.\n *\n * 4. **Environment resolution** — Rewrites `environment: \"tailor-runtime\"` to the\n * absolute path of the bundled environment module via the config hook.\n *\n * ## Known limitations\n *\n * - **`process`** and **`require`** are NOT removed or blocked. Vitest's internal\n * runner depends on them. On the real Tailor Platform runtime, they do not exist.\n * - **Dynamic `import()`** of bundled files (via `createImportMain()`) bypasses\n * the transform hook since those files are loaded through Node.js native loader.\n * ## Options\n *\n * - **`config`** — Path to `tailor.config.ts`. Loads `defineSecretManager()` values\n * into `secretmanagerMock` so `getSecret()` returns the configured values.\n * @example\n * ```typescript\n * // vitest.config.ts\n * import { defineConfig } from \"vitest/config\";\n * import { tailorRuntime } from \"@tailor-platform/sdk/vitest\";\n *\n * export default defineConfig({\n * plugins: [tailorRuntime({ config: \"./tailor.config.ts\" })],\n * test: {\n * environment: \"tailor-runtime\",\n * },\n * });\n * ```\n * @param options - Optional configuration\n * @param options.config - Path to tailor.config.ts to load SecretManager values into mock\n * @returns Array of Vite plugins\n */\nexport function tailorRuntime(options?: { config?: string }): Plugin[] {\n return [createBlockPlugin(), createEnvironmentPlugin(options)];\n}\n\nexport {\n tailordbMock,\n workflowMock,\n secretmanagerMock,\n authconnectionMock,\n idpMock,\n fileMock,\n iconvMock,\n} from \"./mock\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/vitest/blocked-modules.ts","../../src/vitest/plugin.ts","../../src/vitest/index.ts"],"sourcesContent":["/**\n * Blocked Node.js built-in modules and their Web Standard API alternatives.\n *\n * The Tailor Platform runtime only provides Web Standard APIs.\n * These Node.js modules are not available and should be replaced with\n * the suggested alternatives.\n */\nimport { builtinModules } from \"node:module\";\n\n// Suggestions keyed by bare specifier. Lookup also checks with \"node:\" prefix stripped.\nconst SUGGESTIONS: Record<string, string> = {\n crypto: \"Use the Web Crypto API (globalThis.crypto) instead.\",\n buffer: \"Use Uint8Array or ArrayBuffer instead.\",\n fs: \"File system access is not available in the Tailor Platform runtime.\",\n \"fs/promises\": \"File system access is not available in the Tailor Platform runtime.\",\n path: \"Use URL or URLPattern for path manipulation.\",\n http: \"Use the Fetch API (globalThis.fetch) for HTTP requests instead.\",\n https: \"Use the Fetch API (globalThis.fetch) for HTTPS requests instead.\",\n url: \"Use the URL and URLSearchParams Web APIs instead.\",\n util: \"Use Web Standard APIs instead.\",\n stream: \"Use Web Streams API (ReadableStream, WritableStream, TransformStream) instead.\",\n \"stream/web\": \"Use Web Streams API (ReadableStream, WritableStream, TransformStream) instead.\",\n events: \"Use EventTarget instead.\",\n zlib: \"Use CompressionStream and DecompressionStream Web APIs instead.\",\n querystring: \"Use URLSearchParams instead.\",\n string_decoder: \"Use TextDecoder instead.\",\n};\n\nconst BLOCKED_MODULES = new Set<string>();\nfor (const mod of builtinModules) {\n BLOCKED_MODULES.add(mod);\n BLOCKED_MODULES.add(`node:${mod}`);\n}\n\n/**\n * Check if a module specifier is a blocked Node.js built-in.\n * @param specifier - Module specifier to check (e.g. \"node:crypto\", \"fs\")\n * @returns Whether the specifier is blocked\n */\nexport function isBlockedModule(specifier: string): boolean {\n return BLOCKED_MODULES.has(specifier);\n}\n\n/**\n * Get the error message for a blocked module import.\n * @param specifier - Module specifier that was blocked\n * @returns Error message with optional suggestion for the Web Standard API alternative\n */\nexport function getBlockedMessage(specifier: string): string {\n const bare = specifier.startsWith(\"node:\") ? specifier.slice(5) : specifier;\n const suggestion = SUGGESTIONS[bare];\n const base = `\"${specifier}\" is not available in the Tailor Platform runtime.`;\n return suggestion ? `${base} ${suggestion}` : base;\n}\n","import { dirname, isAbsolute, matchesGlob, relative, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { isBlockedModule, getBlockedMessage } from \"./blocked-modules\";\nimport type { Plugin } from \"vitest/config\";\n\nconst DEFAULT_TEST_INCLUDE = [\"**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}\"];\n\ninterface ExportSpecifierNode {\n type?: string;\n exported?: { name?: unknown } | null;\n}\n\ninterface ImportLikeNode {\n type: string;\n start: number;\n end: number;\n source?: { value?: unknown } | null;\n specifiers?: ExportSpecifierNode[] | null;\n exported?: { name?: unknown } | null;\n}\n\nconst IMPORT_LIKE_TYPES = new Set([\n \"ImportDeclaration\",\n \"ExportNamedDeclaration\",\n \"ExportAllDeclaration\",\n]);\n\n// Re-export specifiers (`export { x as Y } from \"...\"`) accept any\n// `IdentifierName` for `Y` — including reserved words like `delete`. But\n// `export const Y = ...` requires a `BindingIdentifier`, which forbids\n// reserved words and the strict-mode-banned `arguments` / `eval`. Synthesizing\n// `export const delete = ...` would yield a syntax error, so we fall back to\n// plain `throw` for unsafe names.\nconst UNSAFE_BINDING_NAMES = new Set([\n // ReservedWord (ES2022+)\n \"break\",\n \"case\",\n \"catch\",\n \"class\",\n \"const\",\n \"continue\",\n \"debugger\",\n \"default\",\n \"delete\",\n \"do\",\n \"else\",\n \"enum\",\n \"export\",\n \"extends\",\n \"false\",\n \"finally\",\n \"for\",\n \"function\",\n \"if\",\n \"import\",\n \"in\",\n \"instanceof\",\n \"new\",\n \"null\",\n \"return\",\n \"super\",\n \"switch\",\n \"this\",\n \"throw\",\n \"true\",\n \"try\",\n \"typeof\",\n \"var\",\n \"void\",\n \"while\",\n \"with\",\n \"yield\",\n // Strict-mode reserved (ESM is always strict)\n \"let\",\n \"static\",\n \"implements\",\n \"interface\",\n \"package\",\n \"private\",\n \"protected\",\n \"public\",\n // Module-specific reserved\n \"await\",\n // Banned as binding names in strict mode\n \"arguments\",\n \"eval\",\n]);\n\nconst ID_START = /^[A-Za-z_$]/;\nconst ID_CONT = /^[A-Za-z0-9_$]*$/;\n\nfunction isSafeBindingName(name: string): boolean {\n if (UNSAFE_BINDING_NAMES.has(name)) return false;\n if (name.length === 0) return false;\n // Restrict to ASCII identifiers — Unicode bindings are valid JS but rare\n // for re-exports of node:* modules, and a regex over the full\n // ID_Start/ID_Continue sets adds substantial weight for marginal gain.\n return ID_START.test(name[0] ?? \"\") && ID_CONT.test(name.slice(1));\n}\n\nfunction buildBlockedReplacement(node: ImportLikeNode, message: string): string {\n // JSON.stringify yields a fully-escaped string literal (including the\n // surrounding quotes), so we don't need to manually handle backslashes,\n // newlines, or other control characters that may appear in the message.\n const literal = JSON.stringify(message);\n const throwStmt = `throw new Error(${literal});`;\n const throwExpr = `(() => { throw new Error(${literal}); })()`;\n\n if (node.type === \"ExportNamedDeclaration\") {\n const specs = node.specifiers ?? [];\n const stubs: string[] = [];\n for (const spec of specs) {\n const exportedName = spec.exported?.name;\n if (typeof exportedName !== \"string\") continue;\n if (exportedName === \"default\") {\n stubs.push(`export default ${throwExpr};`);\n continue;\n }\n // Reserved words can be re-export names but not binding names.\n // Bail to a plain throw rather than emit invalid syntax.\n if (!isSafeBindingName(exportedName)) return throwStmt;\n stubs.push(`export const ${exportedName} = ${throwExpr};`);\n }\n return stubs.length > 0 ? stubs.join(\" \") : throwStmt;\n }\n\n if (node.type === \"ExportAllDeclaration\") {\n const exportedName = node.exported?.name;\n if (typeof exportedName === \"string\" && isSafeBindingName(exportedName)) {\n return `export const ${exportedName} = ${throwExpr};`;\n }\n return throwStmt;\n }\n\n return throwStmt;\n}\n\n/**\n * Vite plugin that blocks Node.js built-in module imports from production code.\n *\n * Uses the `transform` hook to walk the Rollup-provided AST of non-test source\n * files for static `node:*` imports and re-exports.\n * `ImportDeclaration` and bare `export * from \"...\"` are replaced with a\n * `throw new Error(...)` statement so the failure surfaces at evaluation time.\n * `ExportNamedDeclaration` (`export { x, y as z } from \"...\"`) and namespaced\n * `export * as ns from \"...\"` are rewritten to per-binding stub exports\n * (`export const x = (() => { throw new Error(...) })();`). The IIFE throws\n * eagerly during module evaluation (same timing as a top-level `throw`), but\n * preserving the declared export bindings ensures the surfaced error is the\n * actual \"node:* not available\" message rather than an opaque\n * \"missing export\" raised by the loader.\n * Vitest treats `node:*` as external SSR modules (skipping `resolveId`), so\n * source-level transformation is the only reliable interception point.\n * Runs in the default phase (no `enforce: \"pre\"`) so esbuild's TypeScript\n * transform strips `import type` first; only runtime imports reach this hook.\n * Node.js globals not in the platform runtime are removed by the environment (whitelist-based).\n * Test file patterns are read from the resolved Vitest config (`test.include`).\n * Vitest setup files (`test.setupFiles`) and global-setup files\n * (`test.globalSetup`) are also exempted: they run in the test runner host,\n * not in the emulated platform runtime, so they may freely use `node:*`\n * modules (e.g. `node:url` for `pathToFileURL`).\n * @returns Vite plugin\n */\nexport function createBlockPlugin(): Plugin {\n let isTestFile: (id: string) => boolean = () => false;\n let isUserSourceFile: (id: string) => boolean = () => false;\n\n return {\n name: \"tailor-runtime-block-node\",\n\n configResolved(config) {\n type HostFileTestConfig = {\n include?: string[];\n setupFiles?: string | string[];\n globalSetup?: string | string[];\n root?: string;\n };\n const testConfig = (\n config as typeof config & {\n test?: HostFileTestConfig & {\n projects?: { test?: HostFileTestConfig }[];\n };\n }\n ).test;\n const root = testConfig?.root ?? config.root;\n // Setup files and global-setup files run in the Vitest host (not the\n // emulated runtime), so they may freely import node:* modules. Collect\n // them from the top-level config AND from each `test.projects[i]` —\n // per-project setup files run in the host too and would otherwise be\n // transformed as production code, breaking node:* imports inside them.\n const toAbsolutePaths = (value: string | string[] | undefined, baseRoot: string) =>\n (Array.isArray(value) ? value : value ? [value] : []).map((f) => resolve(baseRoot, f));\n const exemptHostFiles = new Set<string>([\n ...toAbsolutePaths(testConfig?.setupFiles, root),\n ...toAbsolutePaths(testConfig?.globalSetup, root),\n ]);\n // Vitest projects can each define their own `test.include` (and root).\n // A project that uses non-default patterns (e.g. `tests/**/*.spec.ts`)\n // must also be considered when classifying test files — otherwise its\n // tests would be treated as production code and have node:* imports\n // rewritten. Build a list of (root, patterns) pairs covering top-level\n // + every project, and accept a file if any pair matches.\n const includePairs: { root: string; patterns: string[] }[] = [\n { root, patterns: testConfig?.include ?? DEFAULT_TEST_INCLUDE },\n ];\n for (const project of testConfig?.projects ?? []) {\n const projectTest = project?.test;\n if (!projectTest) continue;\n const projectRoot = projectTest.root ?? root;\n for (const f of toAbsolutePaths(projectTest.setupFiles, projectRoot)) {\n exemptHostFiles.add(f);\n }\n for (const f of toAbsolutePaths(projectTest.globalSetup, projectRoot)) {\n exemptHostFiles.add(f);\n }\n includePairs.push({\n root: projectRoot,\n patterns: projectTest.include ?? DEFAULT_TEST_INCLUDE,\n });\n }\n isTestFile = (id: string) => {\n if (exemptHostFiles.has(id)) return true;\n return includePairs.some(({ root: r, patterns }) => {\n const candidate = isAbsolute(id) ? relative(r, id) : id;\n return patterns.some((pattern) => matchesGlob(candidate, pattern));\n });\n };\n // Only transform files inside the project root. With pnpm workspaces,\n // dependencies are symlinked and Vite resolves them to absolute paths\n // outside `node_modules`, so the substring check alone is insufficient.\n // Non-absolute ids are Vite-internal: virtual modules (`\\0...`,\n // `virtual:...`), bare specifiers, etc. Those are never user source\n // files and must not be parsed/transformed.\n isUserSourceFile = (id: string) => {\n if (!isAbsolute(id)) return false;\n const rel = relative(root, id);\n return rel !== \"\" && !rel.startsWith(\"..\") && !isAbsolute(rel);\n };\n },\n\n transform(code, id) {\n // Vite can pass ids with query/hash suffixes (e.g. `file.ts?import`,\n // `file.ts?v=hash`). Strip them so exact-path lookups (Set membership,\n // glob matching, absolute-path checks) match what callers configured.\n const queryIdx = id.search(/[?#]/);\n const cleanId = queryIdx === -1 ? id : id.slice(0, queryIdx);\n\n if (isTestFile(cleanId)) return undefined;\n if (cleanId.includes(\"node_modules\")) return undefined;\n if (!isUserSourceFile(cleanId)) return undefined;\n\n let ast: { body: ImportLikeNode[] };\n try {\n ast = this.parse(code) as unknown as { body: ImportLikeNode[] };\n } catch {\n // Not parseable as ESM (e.g. JSON, asset). Let other plugins handle it.\n return undefined;\n }\n\n const replacements: { start: number; end: number; replacement: string }[] = [];\n for (const node of ast.body) {\n if (!IMPORT_LIKE_TYPES.has(node.type)) continue;\n const specifier = node.source?.value;\n if (typeof specifier !== \"string\") continue;\n if (isBlockedModule(specifier)) {\n replacements.push({\n start: node.start,\n end: node.end,\n replacement: buildBlockedReplacement(node, getBlockedMessage(specifier)),\n });\n }\n }\n\n if (replacements.length === 0) return undefined;\n\n let transformed = code;\n for (const r of replacements.sort((a, b) => b.start - a.start)) {\n transformed = transformed.slice(0, r.start) + r.replacement + transformed.slice(r.end);\n }\n\n return { code: transformed, map: null };\n },\n };\n}\n\nconst ENVIRONMENT_NAME = \"tailor-runtime\";\n\n/**\n * Vite plugin that resolves the tailor-runtime environment and injects setup files.\n *\n * Vitest resolves environments starting with \".\" or \"/\" as file paths.\n * This plugin rewrites `environment: \"tailor-runtime\"` to the absolute path\n * of the bundled environment module, both at the top-level and per-project.\n * It also injects the setup file that removes Vitest-dependent globals\n * (like `performance`) per-test via beforeEach/afterEach hooks.\n * @param options - Optional configuration\n * @param options.config - Path to tailor.config.ts to load SecretManager values into mock\n * @returns Vite plugin\n */\nexport function createEnvironmentPlugin(options?: { config?: string }): Plugin {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const environmentPath = resolve(currentDir, \"environment.mjs\");\n const setupPath = resolve(currentDir, \"setup.mjs\");\n\n return {\n name: \"tailor-runtime-environment\",\n\n config(config) {\n const testConfig = config.test as\n | (Record<string, unknown> & {\n projects?: Record<string, unknown>[];\n setupFiles?: string | string[];\n })\n | undefined;\n\n // Rewrite environment name to absolute path at top-level\n let usesTailorRuntime = false;\n if (testConfig?.environment === ENVIRONMENT_NAME) {\n testConfig.environment = environmentPath;\n usesTailorRuntime = true;\n }\n\n // Rewrite in each project config\n if (testConfig?.projects) {\n for (const project of testConfig.projects) {\n const projectTest = project.test as Record<string, unknown> | undefined;\n if (projectTest?.environment === ENVIRONMENT_NAME) {\n projectTest.environment = environmentPath;\n usesTailorRuntime = true;\n }\n }\n }\n\n // Pass config path to setup.ts via env var (cross-process compatible).\n // Always clear first, then set only when tailor-runtime is actually\n // selected. This makes the env var deterministic across Vite config\n // reloads (watch mode, programmatic re-init): a stale value from a\n // prior iteration cannot make setup.ts load secrets from an old config.\n // The leading `__` marks this as plugin-private, so deleting any\n // pre-existing value is safe.\n delete process.env.__TAILOR_RUNTIME_CONFIG;\n if (options?.config && usesTailorRuntime) {\n // Resolve against the user-provided Vite root when present (falling\n // back to cwd). Vitest projects with a non-cwd `root` would otherwise\n // resolve a relative options.config against the wrong directory.\n const configRoot = (config.root as string | undefined) ?? process.cwd();\n const configAbsPath = resolve(configRoot, options.config);\n process.env.__TAILOR_RUNTIME_CONFIG = configAbsPath;\n }\n\n // Normalize a user-provided string `setupFiles` into an array so Vite's\n // array-concat merge sees both sides as arrays (the string form would\n // otherwise be replaced rather than concatenated by some merge paths).\n // Vite then concatenates the user's array with our [setupPath].\n if (testConfig && typeof testConfig.setupFiles === \"string\") {\n testConfig.setupFiles = [testConfig.setupFiles];\n }\n\n return {\n test: {\n setupFiles: [setupPath],\n },\n };\n },\n };\n}\n","import { createBlockPlugin, createEnvironmentPlugin } from \"./plugin\";\nimport type { Plugin } from \"vitest/config\";\n\n/**\n * Creates Vitest plugins that emulate the Tailor Platform function runtime environment.\n *\n * **Beta:** This API may change in future releases.\n *\n * ## What it does\n *\n * 1. **Node.js module blocking** (transform hook) — Imports of `node:*` modules\n * (and bare builtins like `crypto`, `fs`) in non-test source files are replaced\n * with code that throws an error with a suggestion for the Web Standard API alternative.\n * Test files are exempt and can use `node:*` freely. Test file patterns are read\n * from the resolved Vitest config (`test.include`).\n *\n * 2. **Node.js globals removal** (environment + setup) — Only globals available in the\n * Tailor Platform runtime are kept (whitelist: ECMAScript standard, Web Standard APIs\n * from bootstrap.js, platform mocks). All others (`Buffer`, `global`, `setImmediate`,\n * `__dirname`, `__filename`, etc.) are removed. `performance` is removed per-test\n * via beforeEach/afterEach since Vitest needs it during initialization.\n *\n * 3. **Platform API mocks** (environment) — All platform APIs are auto-injected with\n * control objects: `tailordbMock`, `workflowMock`, `secretmanagerMock`,\n * `authconnectionMock`, `idpMock`, `fileMock`, `iconvMock`. Each\n * provides response configuration, call recording, and reset.\n *\n * 4. **Environment resolution** — Rewrites `environment: \"tailor-runtime\"` to the\n * absolute path of the bundled environment module via the config hook.\n *\n * ## Known limitations\n *\n * - **`process`** and **`require`** are NOT removed or blocked. Vitest's internal\n * runner depends on them. On the real Tailor Platform runtime, they do not exist.\n * - **Dynamic `import()`** of bundled files (via `createImportMain()`) bypasses\n * the transform hook since those files are loaded through Node.js native loader.\n * ## Options\n *\n * - **`config`** — Path to `tailor.config.ts`. Loads `defineSecretManager()` values\n * into `secretmanagerMock` so `getSecret()` returns the configured values.\n * @example\n * ```typescript\n * // vitest.config.ts\n * import { defineConfig } from \"vitest/config\";\n * import { tailorRuntime } from \"@tailor-platform/sdk/vitest\";\n *\n * export default defineConfig({\n * plugins: [tailorRuntime({ config: \"./tailor.config.ts\" })],\n * test: {\n * environment: \"tailor-runtime\",\n * },\n * });\n * ```\n * @param options - Optional configuration\n * @param options.config - Path to tailor.config.ts to load SecretManager values into mock\n * @returns Array of Vite plugins\n */\nexport function tailorRuntime(options?: { config?: string }): Plugin[] {\n return [createBlockPlugin(), createEnvironmentPlugin(options)];\n}\n\nexport {\n tailordbMock,\n workflowMock,\n secretmanagerMock,\n authconnectionMock,\n idpMock,\n fileMock,\n iconvMock,\n} from \"./mock\";\n"],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- /// <reference types="@tailor-platform/function-types" />
2
1
  //#region src/vitest/setup.d.ts
3
2
  type SavedGlobals = Record<string, PropertyDescriptor | undefined>;
4
3
  /**
@@ -1,5 +1,5 @@
1
1
 
2
- import { l as secretmanagerMock, t as RUNTIME_FLAG_KEY } from "../mock-BfL09ULZ.mjs";
2
+ import { l as secretmanagerMock, t as RUNTIME_FLAG_KEY } from "../mock-B2t5gDMl.mjs";
3
3
  import { pathToFileURL } from "node:url";
4
4
  import { afterEach, beforeAll, beforeEach } from "vitest";
5
5
 
@@ -0,0 +1,39 @@
1
+
2
+ import { t as __exportAll } from "./chunk-DLeslSnM.mjs";
3
+
4
+ //#region src/runtime/workflow.ts
5
+ var workflow_exports = /* @__PURE__ */ __exportAll({
6
+ resolve: () => resolve,
7
+ triggerJobFunction: () => triggerJobFunction,
8
+ triggerWorkflow: () => triggerWorkflow,
9
+ wait: () => wait
10
+ });
11
+ const api = () => globalThis.tailor.workflow;
12
+ /**
13
+ * See {@link TailorWorkflowAPI.triggerWorkflow}.
14
+ * @param args - Forwarded to {@link TailorWorkflowAPI.triggerWorkflow}
15
+ * @returns The execution ID of the triggered workflow
16
+ */
17
+ const triggerWorkflow = (...args) => api().triggerWorkflow(...args);
18
+ /**
19
+ * See {@link TailorWorkflowAPI.triggerJobFunction}.
20
+ * @param args - Forwarded to {@link TailorWorkflowAPI.triggerJobFunction}
21
+ * @returns The job's return value
22
+ */
23
+ const triggerJobFunction = (...args) => api().triggerJobFunction(...args);
24
+ /**
25
+ * See {@link TailorWorkflowAPI.wait}.
26
+ * @param args - Forwarded to {@link TailorWorkflowAPI.wait}
27
+ * @returns The payload supplied by the corresponding `resolve` call
28
+ */
29
+ const wait = (...args) => api().wait(...args);
30
+ /**
31
+ * See {@link TailorWorkflowAPI.resolve}.
32
+ * @param args - Forwarded to {@link TailorWorkflowAPI.resolve}
33
+ * @returns A promise that resolves once the resolve has been recorded
34
+ */
35
+ const resolve = (...args) => api().resolve(...args);
36
+
37
+ //#endregion
38
+ export { workflow_exports as a, wait as i, triggerJobFunction as n, triggerWorkflow as r, resolve as t };
39
+ //# sourceMappingURL=workflow-DJRr-0nl.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-DJRr-0nl.mjs","names":[],"sources":["../src/runtime/workflow.ts"],"sourcesContent":["/**\n * Workflow utilities.\n *\n * Thin typed wrapper around the platform-provided `tailor.workflow` runtime API.\n * At runtime this delegates to `globalThis.tailor.workflow`. Use `workflowMock`\n * from `@tailor-platform/sdk/vitest` to mock these calls in unit tests.\n * @example\n * import { workflow } from \"@tailor-platform/sdk/runtime\";\n *\n * const executionId = await workflow.triggerWorkflow(\"myWorkflow\", { data: \"value\" });\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Specifies the machine user that should be used to execute the workflow.\n * This allows workflows to run with specific authentication context.\n */\nexport interface AuthInvoker {\n /** The namespace where the machine user is defined */\n namespace: string;\n /** The name of the machine user to use for workflow execution */\n machineUserName: string;\n}\n\n/** Options for {@link triggerWorkflow}. */\nexport interface TriggerWorkflowOptions {\n /** Optional authentication invoker to specify which machine user should execute the workflow */\n authInvoker?: AuthInvoker;\n}\n\n/**\n * Platform API surface for `tailor.workflow`. Describes the shape the platform\n * runtime injects on `globalThis.tailor.workflow`.\n *\n * Each method below is also re-exported as a top-level named export from this\n * module so callers can either `import * as workflow from\n * \"@tailor-platform/sdk/runtime/workflow\"` or pick individual methods.\n */\nexport interface TailorWorkflowAPI {\n /**\n * Triggers a workflow and returns its execution ID.\n * @param workflowName - Workflow name as defined in tailor.config\n * @param args - Arguments forwarded to the workflow's main job\n * @param options - Optional trigger options (e.g. `authInvoker`)\n * @returns The execution ID of the triggered workflow\n */\n triggerWorkflow(\n workflowName: string,\n args?: any,\n options?: TriggerWorkflowOptions,\n ): Promise<string>;\n\n /**\n * Triggers a job function and returns its result.\n * @param jobName - Job name as defined in the workflow\n * @param args - Arguments forwarded to the job\n * @returns The job's return value\n */\n triggerJobFunction(jobName: string, args?: any): any;\n\n /**\n * Suspends the current workflow execution and waits for an external signal to resume.\n * @param key - Wait point key\n * @param payload - Optional payload to record with the wait point\n * @returns The payload supplied by the corresponding `resolve` call\n */\n wait(key: string, payload?: any): any;\n\n /**\n * Resolves a waiting workflow execution, causing it to resume.\n * @param executionId - The execution to resume\n * @param key - Wait point key to resolve\n * @param callback - Callback receiving the wait payload; its return value is forwarded to `wait`\n * @returns A promise that resolves once the resolve has been recorded\n */\n resolve(executionId: string, key: string, callback: (waitPayload: any) => any): Promise<void>;\n}\n\nconst api = (): TailorWorkflowAPI =>\n (globalThis as { tailor: { workflow: TailorWorkflowAPI } }).tailor.workflow;\n\n/**\n * See {@link TailorWorkflowAPI.triggerWorkflow}.\n * @param args - Forwarded to {@link TailorWorkflowAPI.triggerWorkflow}\n * @returns The execution ID of the triggered workflow\n */\nexport const triggerWorkflow: TailorWorkflowAPI[\"triggerWorkflow\"] = (...args) =>\n api().triggerWorkflow(...args);\n\n/**\n * See {@link TailorWorkflowAPI.triggerJobFunction}.\n * @param args - Forwarded to {@link TailorWorkflowAPI.triggerJobFunction}\n * @returns The job's return value\n */\nexport const triggerJobFunction: TailorWorkflowAPI[\"triggerJobFunction\"] = (...args) =>\n api().triggerJobFunction(...args);\n\n/**\n * See {@link TailorWorkflowAPI.wait}.\n * @param args - Forwarded to {@link TailorWorkflowAPI.wait}\n * @returns The payload supplied by the corresponding `resolve` call\n */\nexport const wait: TailorWorkflowAPI[\"wait\"] = (...args) => api().wait(...args);\n\n/**\n * See {@link TailorWorkflowAPI.resolve}.\n * @param args - Forwarded to {@link TailorWorkflowAPI.resolve}\n * @returns A promise that resolves once the resolve has been recorded\n */\nexport const resolve: TailorWorkflowAPI[\"resolve\"] = (...args) => api().resolve(...args);\n"],"mappings":";;;;;;;;;;AA+EA,MAAM,YACH,WAA2D,OAAO;;;;;;AAOrE,MAAa,mBAAyD,GAAG,SACvE,IAAI,EAAE,gBAAgB,GAAG,IAAI;;;;;;AAO/B,MAAa,sBAA+D,GAAG,SAC7E,IAAI,EAAE,mBAAmB,GAAG,IAAI;;;;;;AAOlC,MAAa,QAAmC,GAAG,SAAS,IAAI,EAAE,KAAK,GAAG,IAAI;;;;;;AAO9E,MAAa,WAAyC,GAAG,SAAS,IAAI,EAAE,QAAQ,GAAG,IAAI"}
@@ -0,0 +1,96 @@
1
+ declare namespace workflow_d_exports {
2
+ export { AuthInvoker, TailorWorkflowAPI, TriggerWorkflowOptions, resolve, triggerJobFunction, triggerWorkflow, wait };
3
+ }
4
+ /**
5
+ * Workflow utilities.
6
+ *
7
+ * Thin typed wrapper around the platform-provided `tailor.workflow` runtime API.
8
+ * At runtime this delegates to `globalThis.tailor.workflow`. Use `workflowMock`
9
+ * from `@tailor-platform/sdk/vitest` to mock these calls in unit tests.
10
+ * @example
11
+ * import { workflow } from "@tailor-platform/sdk/runtime";
12
+ *
13
+ * const executionId = await workflow.triggerWorkflow("myWorkflow", { data: "value" });
14
+ */
15
+ /**
16
+ * Specifies the machine user that should be used to execute the workflow.
17
+ * This allows workflows to run with specific authentication context.
18
+ */
19
+ interface AuthInvoker {
20
+ /** The namespace where the machine user is defined */
21
+ namespace: string;
22
+ /** The name of the machine user to use for workflow execution */
23
+ machineUserName: string;
24
+ }
25
+ /** Options for {@link triggerWorkflow}. */
26
+ interface TriggerWorkflowOptions {
27
+ /** Optional authentication invoker to specify which machine user should execute the workflow */
28
+ authInvoker?: AuthInvoker;
29
+ }
30
+ /**
31
+ * Platform API surface for `tailor.workflow`. Describes the shape the platform
32
+ * runtime injects on `globalThis.tailor.workflow`.
33
+ *
34
+ * Each method below is also re-exported as a top-level named export from this
35
+ * module so callers can either `import * as workflow from
36
+ * "@tailor-platform/sdk/runtime/workflow"` or pick individual methods.
37
+ */
38
+ interface TailorWorkflowAPI {
39
+ /**
40
+ * Triggers a workflow and returns its execution ID.
41
+ * @param workflowName - Workflow name as defined in tailor.config
42
+ * @param args - Arguments forwarded to the workflow's main job
43
+ * @param options - Optional trigger options (e.g. `authInvoker`)
44
+ * @returns The execution ID of the triggered workflow
45
+ */
46
+ triggerWorkflow(workflowName: string, args?: any, options?: TriggerWorkflowOptions): Promise<string>;
47
+ /**
48
+ * Triggers a job function and returns its result.
49
+ * @param jobName - Job name as defined in the workflow
50
+ * @param args - Arguments forwarded to the job
51
+ * @returns The job's return value
52
+ */
53
+ triggerJobFunction(jobName: string, args?: any): any;
54
+ /**
55
+ * Suspends the current workflow execution and waits for an external signal to resume.
56
+ * @param key - Wait point key
57
+ * @param payload - Optional payload to record with the wait point
58
+ * @returns The payload supplied by the corresponding `resolve` call
59
+ */
60
+ wait(key: string, payload?: any): any;
61
+ /**
62
+ * Resolves a waiting workflow execution, causing it to resume.
63
+ * @param executionId - The execution to resume
64
+ * @param key - Wait point key to resolve
65
+ * @param callback - Callback receiving the wait payload; its return value is forwarded to `wait`
66
+ * @returns A promise that resolves once the resolve has been recorded
67
+ */
68
+ resolve(executionId: string, key: string, callback: (waitPayload: any) => any): Promise<void>;
69
+ }
70
+ /**
71
+ * See {@link TailorWorkflowAPI.triggerWorkflow}.
72
+ * @param args - Forwarded to {@link TailorWorkflowAPI.triggerWorkflow}
73
+ * @returns The execution ID of the triggered workflow
74
+ */
75
+ declare const triggerWorkflow: TailorWorkflowAPI["triggerWorkflow"];
76
+ /**
77
+ * See {@link TailorWorkflowAPI.triggerJobFunction}.
78
+ * @param args - Forwarded to {@link TailorWorkflowAPI.triggerJobFunction}
79
+ * @returns The job's return value
80
+ */
81
+ declare const triggerJobFunction: TailorWorkflowAPI["triggerJobFunction"];
82
+ /**
83
+ * See {@link TailorWorkflowAPI.wait}.
84
+ * @param args - Forwarded to {@link TailorWorkflowAPI.wait}
85
+ * @returns The payload supplied by the corresponding `resolve` call
86
+ */
87
+ declare const wait: TailorWorkflowAPI["wait"];
88
+ /**
89
+ * See {@link TailorWorkflowAPI.resolve}.
90
+ * @param args - Forwarded to {@link TailorWorkflowAPI.resolve}
91
+ * @returns A promise that resolves once the resolve has been recorded
92
+ */
93
+ declare const resolve: TailorWorkflowAPI["resolve"];
94
+ //#endregion
95
+ export { triggerJobFunction as a, workflow_d_exports as c, resolve as i, TailorWorkflowAPI as n, triggerWorkflow as o, TriggerWorkflowOptions as r, wait as s, AuthInvoker as t };
96
+ //# sourceMappingURL=workflow-DV_88JEf.d.mts.map
@@ -1,5 +1,4 @@
1
- /// <reference types="@tailor-platform/function-types" />
2
- import { A as RelationType, Bt as InferredAttributeMap, D as DefinedDBFieldMetadata, Dt as ArrayFieldOutput, E as DBFieldMetadata, F as AuthConfig, Ft as FieldValidateInput, Ht as TailorUser, It as Validators, Jt as output, M as TailorDBServiceInput, Mt as FieldOutput, O as GqlOperationsConfig, Pt as TailorToTs, Wt as InferFieldsOutput, Y as TailorField, c as PluginConfigs, ht as BuiltinIdP, i as TailorDBType$1, j as SerialConfig, jt as FieldOptions, k as IndexDef, kt as EnumValue, qt as Prettify, r as TailorDBField$1, t as TailorAnyDBField$1 } from "./tailor-db-field-4bMLe25-.mjs";
1
+ import { A as RelationType, Bt as InferredAttributeMap, D as DefinedDBFieldMetadata, Dt as ArrayFieldOutput, E as DBFieldMetadata, F as AuthConfig, Ft as FieldValidateInput, Ht as TailorUser, It as Validators, Jt as output, M as TailorDBServiceInput, Mt as FieldOutput, O as GqlOperationsConfig, Pt as TailorToTs, Wt as InferFieldsOutput, Y as TailorField, c as PluginConfigs, ht as BuiltinIdP, i as TailorDBType$1, j as SerialConfig, jt as FieldOptions, k as IndexDef, kt as EnumValue, qt as Prettify, r as TailorDBField$1, t as TailorAnyDBField$1 } from "./tailor-db-field-BhWvOyky.mjs";
3
2
  import { NonEmptyObject } from "type-fest";
4
3
  import { StandardSchemaV1 } from "@standard-schema/spec";
5
4
 
@@ -1217,4 +1216,4 @@ type ConcurrencyPolicy = {
1217
1216
  };
1218
1217
  //#endregion
1219
1218
  export { PermissionCondition as A, IdPInput as C, TailorDBInstance as D, TailorDBField as E, AllowedValues as F, AllowedValuesOutput as I, TailorTypePermission as M, unsafeAllowAllGqlPermission as N, TailorDBType as O, unsafeAllowAllTypePermission as P, IdPGqlOperationsInput as S, TailorAnyDBType as T, IdPExternalConfig as _, ExecutorServiceInput as a, IdPEmailConfig as b, ResolverServiceInput as c, StaticWebsiteConfig as d, StaticWebsiteDefinitionBrand as f, IdPConfig as g, SecretsDefinitionBrand as h, ExecutorServiceConfig as i, TailorTypeGqlPermission as j, db as k, WorkflowServiceConfig as l, SecretsConfig as m, RetryPolicy as n, ResolverExternalConfig as o, StaticWebsiteInput as p, AppConfig as r, ResolverServiceConfig as s, ConcurrencyPolicy as t, WorkflowServiceInput as u, IdPUserField as v, TailorAnyDBField as w, IdPGqlOperations as x, IdpDefinitionBrand as y };
1220
- //# sourceMappingURL=workflow.generated-OYAu_6zX.d.mts.map
1219
+ //# sourceMappingURL=workflow.generated-DV87DJfO.d.mts.map
@@ -149,7 +149,7 @@ When migrations are configured (`db.tailordb.migration` in config), the `deploy`
149
149
  3. Executes migration scripts via TestExecScript API
150
150
  4. Updates migration state labels in TailorDB metadata
151
151
 
152
- See [TailorDB Commands](./tailordb.md#automatic-migration-execution) for details on automatic migration execution.
152
+ See [Automatic Migration Execution](../services/tailordb-migration.md#automatic-migration-execution) for details on automatic migration execution.
153
153
 
154
154
  **Schema Check:**
155
155