@tailor-platform/sdk 1.46.0 → 1.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/{actor-BmxQeMFP.d.mts → actor-DhXSqWTW.d.mts} +2 -2
  3. package/dist/application-CN9Htzup.mjs +4 -0
  4. package/dist/{application-B4zVVNRS.mjs → application-TasSqBTD.mjs} +22 -41
  5. package/dist/application-TasSqBTD.mjs.map +1 -0
  6. package/dist/cli/index.mjs +33 -15
  7. package/dist/cli/index.mjs.map +1 -1
  8. package/dist/cli/lib.d.mts +6 -6
  9. package/dist/cli/lib.mjs +3 -3
  10. package/dist/{client-BwXkoiMq.mjs → client-COfsXV69.mjs} +31 -120
  11. package/dist/client-COfsXV69.mjs.map +1 -0
  12. package/dist/{client-DTaArWQr.mjs → client-DYSkSLRr.mjs} +1 -1
  13. package/dist/configure/index.d.mts +4 -4
  14. package/dist/configure/index.mjs +4 -43
  15. package/dist/configure/index.mjs.map +1 -1
  16. package/dist/{crashreport-6mcMyWu4.mjs → crashreport-B8lVOx0U.mjs} +1 -1
  17. package/dist/{crashreport-DGeGj9BF.mjs → crashreport-CKJwnWsX.mjs} +2 -2
  18. package/dist/{crashreport-DGeGj9BF.mjs.map → crashreport-CKJwnWsX.mjs.map} +1 -1
  19. package/dist/{index-DV-5OIEv.d.mts → index-BRvNi5q9.d.mts} +2 -2
  20. package/dist/{index-BBvPd9Uv.d.mts → index-BXyS7xKC.d.mts} +2 -2
  21. package/dist/{index-Dxe6alSZ.d.mts → index-BbOTbZFf.d.mts} +2 -2
  22. package/dist/{index-PB0otrDj.d.mts → index-BoU_52Du.d.mts} +4 -4
  23. package/dist/{index-B5_4Tzm2.d.mts → index-iy-hNfGp.d.mts} +2 -2
  24. package/dist/{interceptor-CrcDfLPq.mjs → interceptor-CBsqEWDK.mjs} +1 -1
  25. package/dist/{interceptor-CrcDfLPq.mjs.map → interceptor-CBsqEWDK.mjs.map} +1 -1
  26. package/dist/mock-BP-9O5On.mjs +796 -0
  27. package/dist/mock-BP-9O5On.mjs.map +1 -0
  28. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  29. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  30. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  31. package/dist/plugin/builtin/seed/index.d.mts +1 -1
  32. package/dist/plugin/index.d.mts +2 -2
  33. package/dist/{repl-editor-BlT2dFtm.mjs → repl-editor-CZpLlOBj.mjs} +1 -1
  34. package/dist/{repl-editor-BlT2dFtm.mjs.map → repl-editor-CZpLlOBj.mjs.map} +1 -1
  35. package/dist/{runtime-B67skpW-.mjs → runtime-DDYL2Zf1.mjs} +86 -8
  36. package/dist/runtime-DDYL2Zf1.mjs.map +1 -0
  37. package/dist/{service-CCgw66c6.mjs → service-obEU5gSM.mjs} +1 -1
  38. package/dist/{service-CCgw66c6.mjs.map → service-obEU5gSM.mjs.map} +1 -1
  39. package/dist/{tailor-db-field-Hx9OqPWY.d.mts → tailor-db-field-Bn8ZC5lK.d.mts} +1 -1
  40. package/dist/{schema-DBq6hr6h.mjs → tailordb-Bg9-TZj1.mjs} +42 -2
  41. package/dist/tailordb-Bg9-TZj1.mjs.map +1 -0
  42. package/dist/utils/test/index.d.mts +13 -4
  43. package/dist/utils/test/index.mjs +12 -3
  44. package/dist/utils/test/index.mjs.map +1 -1
  45. package/dist/vitest/environment.d.mts +12 -0
  46. package/dist/vitest/environment.mjs +44 -0
  47. package/dist/vitest/environment.mjs.map +1 -0
  48. package/dist/vitest/index.d.mts +345 -0
  49. package/dist/vitest/index.mjs +350 -0
  50. package/dist/vitest/index.mjs.map +1 -0
  51. package/dist/vitest/setup.d.mts +64 -0
  52. package/dist/vitest/setup.mjs +141 -0
  53. package/dist/vitest/setup.mjs.map +1 -0
  54. package/dist/{workflow.generated-DFljpJh7.d.mts → workflow.generated-i7PK4fg-.d.mts} +2 -2
  55. package/docs/cli/setup.md +1 -0
  56. package/docs/services/tailordb.md +43 -12
  57. package/docs/services/workflow.md +1 -1
  58. package/docs/testing.md +530 -243
  59. package/package.json +32 -6
  60. package/dist/application-B4zVVNRS.mjs.map +0 -1
  61. package/dist/application-Boa_11Nv.mjs +0 -4
  62. package/dist/client-BwXkoiMq.mjs.map +0 -1
  63. package/dist/runtime-B67skpW-.mjs.map +0 -1
  64. package/dist/schema-DBq6hr6h.mjs.map +0 -1
@@ -129,4 +129,4 @@ async function upgrade(options) {
129
129
 
130
130
  //#endregion
131
131
  export { upgrade };
132
- //# sourceMappingURL=service-CCgw66c6.mjs.map
132
+ //# sourceMappingURL=service-obEU5gSM.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-CCgw66c6.mjs","names":["CLIError"],"sources":["../src/cli/commands/upgrade/version-detector.ts","../src/cli/commands/upgrade/service.ts"],"sourcesContent":["import * as path from \"pathe\";\nimport { readPackageJSON } from \"pkg-types\";\n\nconst SDK_PACKAGE_NAME = \"@tailor-platform/sdk\";\n\n/**\n * Detect the installed SDK version from the user's project.\n * Walks up from projectRoot to find the SDK package in node_modules,\n * matching Node's module resolution for workspace setups with hoisted deps.\n * @param projectRoot - The project root directory to search from\n * @returns The installed SDK version string, or null if not found\n */\nexport async function detectInstalledVersion(projectRoot: string): Promise<string | null> {\n let dir = path.resolve(projectRoot);\n while (true) {\n try {\n const sdkPath = path.join(dir, \"node_modules\", SDK_PACKAGE_NAME);\n const pkg = await readPackageJSON(sdkPath);\n if (pkg.version) return pkg.version;\n } catch {\n // Not found at this level, try parent\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n","import { spawnSync } from \"node:child_process\";\nimport { CLIError } from \"@/cli/shared/errors\";\nimport { logger, styles } from \"@/cli/shared/logger\";\nimport { detectInstalledVersion } from \"./version-detector\";\nimport type { RunOutput } from \"./types\";\n\ninterface UpgradeOptions {\n from: string;\n dryRun: boolean;\n path: string;\n}\n\n/**\n * Print the upgrade summary to the terminal.\n * @param output - The parsed JSON output from sdk-codemod\n * @param dryRun - Whether this was a dry-run\n */\nfunction printUpgradeSummary(output: RunOutput, dryRun: boolean): void {\n if (dryRun) {\n logger.info(`${styles.bold(\"[Dry Run]\")} No files were modified.`);\n logger.log(\"\");\n }\n\n const total = output.codemodsApplied + output.codemodsSkipped + output.errors.length;\n logger.info(\n `Upgrade complete: ${styles.success(`${output.codemodsApplied} applied`)}, ${styles.dim(`${output.codemodsSkipped} skipped`)} (${total} total codemods)`,\n );\n\n if (output.filesModified.length > 0) {\n logger.log(\"\");\n logger.info(\n `${dryRun ? \"Files that would be modified\" : \"Modified files\"} (${output.filesModified.length}):`,\n );\n for (const file of output.filesModified) {\n logger.log(` ${styles.path(file)}`);\n }\n }\n\n if (output.warnings.length > 0) {\n logger.log(\"\");\n logger.warn(`Manual attention needed (${output.warnings.length}):`);\n for (const warning of output.warnings) {\n logger.log(` ${styles.warning(\"!\")} ${warning}`);\n }\n }\n\n if (output.errors.length > 0) {\n logger.log(\"\");\n logger.error(`Failed codemods (${output.errors.length}):`);\n for (const { codemodId, message } of output.errors) {\n logger.log(` ${styles.error(codemodId)}: ${message}`);\n }\n }\n}\n\n/**\n * Run the upgrade pipeline:\n * 1. Detect target SDK version from node_modules\n * 2. Invoke @tailor-platform/sdk-codemod CLI\n * 3. Parse JSON output and display results\n * @param options - Upgrade options\n */\nexport async function upgrade(options: UpgradeOptions): Promise<void> {\n const projectRoot = options.path;\n\n // Step 1: Detect target SDK version (the newly installed version)\n const targetVersion = await detectInstalledVersion(projectRoot);\n if (!targetVersion) {\n throw CLIError({\n message: `Could not detect installed @tailor-platform/sdk version in ${projectRoot}`,\n suggestion:\n \"Ensure @tailor-platform/sdk is installed. Run 'pnpm install' or 'npm install' first.\",\n command: \"upgrade\",\n });\n }\n\n logger.info(\n `Upgrading from ${styles.highlight(options.from)} → ${styles.highlight(targetVersion)}`,\n );\n\n if (options.dryRun) {\n logger.info(`${styles.bold(\"[Dry Run]\")} Changes will be previewed but not applied.`);\n }\n\n logger.log(\"\");\n\n // Step 2: Invoke sdk-codemod CLI\n // Use \"latest\" because sdk-codemod may not be published at the exact same\n // version as @tailor-platform/sdk. Version filtering is handled internally\n // by sdk-codemod's registry via the --from / --to arguments.\n const npxCommand = process.platform === \"win32\" ? \"npx.cmd\" : \"npx\";\n\n const result = spawnSync(\n npxCommand,\n [\n \"@tailor-platform/sdk-codemod@latest\",\n \"--from\",\n options.from,\n \"--to\",\n targetVersion,\n \"--target\",\n projectRoot,\n ...(options.dryRun ? [\"--dry-run\"] : []),\n ],\n {\n cwd: projectRoot,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n encoding: \"utf-8\",\n timeout: 300_000,\n },\n );\n\n if (result.error) {\n throw CLIError({\n message: `Failed to run @tailor-platform/sdk-codemod: ${result.error.message}`,\n suggestion: \"Ensure npx is available and the network is accessible.\",\n command: \"upgrade\",\n });\n }\n\n // Check for non-zero exit without a launch error (e.g. registry/auth/network failures)\n if (result.status !== 0 && !result.stdout?.trim()) {\n throw CLIError({\n message: `@tailor-platform/sdk-codemod exited with code ${result.status}`,\n details: result.stderr?.trim() || \"(no stderr output)\",\n suggestion:\n \"Review the error above. Common causes: invalid version arguments, network issues, or missing package registry access.\",\n command: \"upgrade\",\n });\n }\n\n // Forward captured stderr so users see dry-run diffs and progress messages\n // written by sdk-codemod. stderr is piped (not inherited) so that the error\n // path above can surface it via CLIError, but on success we still need to\n // replay it verbatim to keep the colorized unified diff output visible.\n if (result.stderr) {\n process.stderr.write(result.stderr);\n }\n\n // Step 3: Parse JSON output\n let output: RunOutput;\n try {\n output = JSON.parse(result.stdout);\n } catch {\n throw CLIError({\n message: \"Failed to parse output from @tailor-platform/sdk-codemod\",\n details: result.stdout || \"(empty stdout)\",\n suggestion: \"This is likely a bug. Please report it.\",\n command: \"upgrade\",\n });\n }\n\n // Step 4: Display results\n // Emit structured data on stdout (honors --json via logger.out) and\n // human-readable summary on stderr (via printUpgradeSummary).\n logger.out(output);\n printUpgradeSummary(output, options.dryRun);\n\n if (output.errors.length > 0) {\n throw CLIError({\n message: `Upgrade completed with ${output.errors.length} error(s)`,\n suggestion: \"Review the errors above and re-run the upgrade after fixing the issues.\",\n command: \"upgrade\",\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"service-obEU5gSM.mjs","names":["CLIError"],"sources":["../src/cli/commands/upgrade/version-detector.ts","../src/cli/commands/upgrade/service.ts"],"sourcesContent":["import * as path from \"pathe\";\nimport { readPackageJSON } from \"pkg-types\";\n\nconst SDK_PACKAGE_NAME = \"@tailor-platform/sdk\";\n\n/**\n * Detect the installed SDK version from the user's project.\n * Walks up from projectRoot to find the SDK package in node_modules,\n * matching Node's module resolution for workspace setups with hoisted deps.\n * @param projectRoot - The project root directory to search from\n * @returns The installed SDK version string, or null if not found\n */\nexport async function detectInstalledVersion(projectRoot: string): Promise<string | null> {\n let dir = path.resolve(projectRoot);\n while (true) {\n try {\n const sdkPath = path.join(dir, \"node_modules\", SDK_PACKAGE_NAME);\n const pkg = await readPackageJSON(sdkPath);\n if (pkg.version) return pkg.version;\n } catch {\n // Not found at this level, try parent\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n","import { spawnSync } from \"node:child_process\";\nimport { CLIError } from \"@/cli/shared/errors\";\nimport { logger, styles } from \"@/cli/shared/logger\";\nimport { detectInstalledVersion } from \"./version-detector\";\nimport type { RunOutput } from \"./types\";\n\ninterface UpgradeOptions {\n from: string;\n dryRun: boolean;\n path: string;\n}\n\n/**\n * Print the upgrade summary to the terminal.\n * @param output - The parsed JSON output from sdk-codemod\n * @param dryRun - Whether this was a dry-run\n */\nfunction printUpgradeSummary(output: RunOutput, dryRun: boolean): void {\n if (dryRun) {\n logger.info(`${styles.bold(\"[Dry Run]\")} No files were modified.`);\n logger.log(\"\");\n }\n\n const total = output.codemodsApplied + output.codemodsSkipped + output.errors.length;\n logger.info(\n `Upgrade complete: ${styles.success(`${output.codemodsApplied} applied`)}, ${styles.dim(`${output.codemodsSkipped} skipped`)} (${total} total codemods)`,\n );\n\n if (output.filesModified.length > 0) {\n logger.log(\"\");\n logger.info(\n `${dryRun ? \"Files that would be modified\" : \"Modified files\"} (${output.filesModified.length}):`,\n );\n for (const file of output.filesModified) {\n logger.log(` ${styles.path(file)}`);\n }\n }\n\n if (output.warnings.length > 0) {\n logger.log(\"\");\n logger.warn(`Manual attention needed (${output.warnings.length}):`);\n for (const warning of output.warnings) {\n logger.log(` ${styles.warning(\"!\")} ${warning}`);\n }\n }\n\n if (output.errors.length > 0) {\n logger.log(\"\");\n logger.error(`Failed codemods (${output.errors.length}):`);\n for (const { codemodId, message } of output.errors) {\n logger.log(` ${styles.error(codemodId)}: ${message}`);\n }\n }\n}\n\n/**\n * Run the upgrade pipeline:\n * 1. Detect target SDK version from node_modules\n * 2. Invoke @tailor-platform/sdk-codemod CLI\n * 3. Parse JSON output and display results\n * @param options - Upgrade options\n */\nexport async function upgrade(options: UpgradeOptions): Promise<void> {\n const projectRoot = options.path;\n\n // Step 1: Detect target SDK version (the newly installed version)\n const targetVersion = await detectInstalledVersion(projectRoot);\n if (!targetVersion) {\n throw CLIError({\n message: `Could not detect installed @tailor-platform/sdk version in ${projectRoot}`,\n suggestion:\n \"Ensure @tailor-platform/sdk is installed. Run 'pnpm install' or 'npm install' first.\",\n command: \"upgrade\",\n });\n }\n\n logger.info(\n `Upgrading from ${styles.highlight(options.from)} → ${styles.highlight(targetVersion)}`,\n );\n\n if (options.dryRun) {\n logger.info(`${styles.bold(\"[Dry Run]\")} Changes will be previewed but not applied.`);\n }\n\n logger.log(\"\");\n\n // Step 2: Invoke sdk-codemod CLI\n // Use \"latest\" because sdk-codemod may not be published at the exact same\n // version as @tailor-platform/sdk. Version filtering is handled internally\n // by sdk-codemod's registry via the --from / --to arguments.\n const npxCommand = process.platform === \"win32\" ? \"npx.cmd\" : \"npx\";\n\n const result = spawnSync(\n npxCommand,\n [\n \"@tailor-platform/sdk-codemod@latest\",\n \"--from\",\n options.from,\n \"--to\",\n targetVersion,\n \"--target\",\n projectRoot,\n ...(options.dryRun ? [\"--dry-run\"] : []),\n ],\n {\n cwd: projectRoot,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n encoding: \"utf-8\",\n timeout: 300_000,\n },\n );\n\n if (result.error) {\n throw CLIError({\n message: `Failed to run @tailor-platform/sdk-codemod: ${result.error.message}`,\n suggestion: \"Ensure npx is available and the network is accessible.\",\n command: \"upgrade\",\n });\n }\n\n // Check for non-zero exit without a launch error (e.g. registry/auth/network failures)\n if (result.status !== 0 && !result.stdout?.trim()) {\n throw CLIError({\n message: `@tailor-platform/sdk-codemod exited with code ${result.status}`,\n details: result.stderr?.trim() || \"(no stderr output)\",\n suggestion:\n \"Review the error above. Common causes: invalid version arguments, network issues, or missing package registry access.\",\n command: \"upgrade\",\n });\n }\n\n // Forward captured stderr so users see dry-run diffs and progress messages\n // written by sdk-codemod. stderr is piped (not inherited) so that the error\n // path above can surface it via CLIError, but on success we still need to\n // replay it verbatim to keep the colorized unified diff output visible.\n if (result.stderr) {\n process.stderr.write(result.stderr);\n }\n\n // Step 3: Parse JSON output\n let output: RunOutput;\n try {\n output = JSON.parse(result.stdout);\n } catch {\n throw CLIError({\n message: \"Failed to parse output from @tailor-platform/sdk-codemod\",\n details: result.stdout || \"(empty stdout)\",\n suggestion: \"This is likely a bug. Please report it.\",\n command: \"upgrade\",\n });\n }\n\n // Step 4: Display results\n // Emit structured data on stdout (honors --json via logger.out) and\n // human-readable summary on stderr (via printUpgradeSummary).\n logger.out(output);\n printUpgradeSummary(output, options.dryRun);\n\n if (output.errors.length > 0) {\n throw CLIError({\n message: `Upgrade completed with ${output.errors.length} error(s)`,\n suggestion: \"Review the errors above and re-run the upgrade after fixing the issues.\",\n command: \"upgrade\",\n });\n }\n}\n"],"mappings":"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"}
@@ -1631,4 +1631,4 @@ type TailorAnyDBType = TailorDBType<any, any>;
1631
1631
  type TailorDBInstance<Fields extends Record<string, TailorAnyDBField> = any, User extends object = InferredAttributeMap> = TailorDBType<Fields, User>;
1632
1632
  //#endregion
1633
1633
  export { ResolverInput as $, RelationType as A, FieldMetadata as At, BeforeLoginHookArgs as B, InferredAttributeMap as Bt, ResolverReadyContext as C, SCIMAuthorization as Ct, DefinedDBFieldMetadata as D, ArrayFieldOutput as Dt, DBFieldMetadata as E, TenantProvider as Et, AuthConfig as F, FieldValidateInput as Ft, UserAttributeListKey as G, JsonCompatible as Gt, OAuth2ClientGrantType as H, TailorUser as Ht, AuthConnectionTokenResult as I, Validators as It, ValueOperand as J, output as Jt, UserAttributeMap as K, JsonValue as Kt, AuthExternalConfig as L, AttributeList as Lt, TailorDBServiceInput as M, FieldOutput$1 as Mt, TailorDBType$1 as N, TailorFieldType as Nt, GqlOperationsConfig as O, DefinedFieldMetadata as Ot, TypeSourceInfoEntry as P, TailorToTs as Pt, Resolver as Q, AuthOwnConfig as R, AttributeMap as Rt, ResolverNamespaceData as S, SCIMAttributeMapping as St, TailorDBReadyContext as T, SCIMResource as Tt, SCIMAttributeType as U, unauthenticatedTailorUser as Ut, DefinedAuth as V, TailorInvoker as Vt, UserAttributeKey as W, InferFieldsOutput as Wt, AuthConnectionConfig as X, TailorField as Y, AuthConnectionOAuth2Config as Z, PluginProcessContext as _, IdProvider as _t, NamespacePluginOutput as a, FunctionOperation as at, ExecutorReadyContext as b, SAML as bt, PluginConfigs as c, IncomingWebhookTrigger as ct, PluginGeneratedExecutor as d, TailorDBTrigger as dt, GeneratorConfig as et, PluginGeneratedExecutorWithFile as f, WebhookOperation as ft, PluginOutput as g, IDToken as gt, PluginNamespaceProcessContext as h, BuiltinIdP as ht, TailorDBType as i, ExecutorInput as it, SerialConfig as j, FieldOptions as jt, IndexDef as k, EnumValue as kt, PluginExecutorContext as l, ResolverExecutedTrigger as lt, PluginGeneratedType as m, AuthInvoker as mt, TailorAnyDBType as n, AuthAccessTokenTrigger as nt, Plugin as o, GqlOperation as ot, PluginGeneratedResolver as p, WorkflowOperation as pt, UsernameFieldKey as q, Prettify as qt, TailorDBField as r, Executor as rt, PluginAttachment as s, IdpUserTrigger as st, TailorAnyDBField as t, BaseGeneratorConfig as tt, PluginExecutorContextBase as u, ScheduleTriggerInput as ut, TailorDBTypeForPlugin as v, OAuth2ClientInput as vt, TailorDBNamespaceData as w, SCIMConfig as wt, GeneratorResult as x, SCIMAttribute as xt, TypePluginOutput as y, OIDC as yt, AuthServiceInput as z, InferredAttributeList as zt };
1634
- //# sourceMappingURL=tailor-db-field-Hx9OqPWY.d.mts.map
1634
+ //# sourceMappingURL=tailor-db-field-Bn8ZC5lK.d.mts.map
@@ -570,5 +570,45 @@ timestamps: () => ({
570
570
  };
571
571
 
572
572
  //#endregion
573
- export { db as t };
574
- //# sourceMappingURL=schema-DBq6hr6h.mjs.map
573
+ //#region src/configure/services/tailordb/permission.ts
574
+ /**
575
+ * Grants full record-level access without any conditions.
576
+ *
577
+ * Unsafe and intended only for local development, prototyping, or tests.
578
+ * Do not use this in production environments, as it effectively disables
579
+ * authorization checks.
580
+ */
581
+ const unsafeAllowAllTypePermission = {
582
+ create: [{
583
+ conditions: [],
584
+ permit: true
585
+ }],
586
+ read: [{
587
+ conditions: [],
588
+ permit: true
589
+ }],
590
+ update: [{
591
+ conditions: [],
592
+ permit: true
593
+ }],
594
+ delete: [{
595
+ conditions: [],
596
+ permit: true
597
+ }]
598
+ };
599
+ /**
600
+ * Grants full GraphQL access (all actions) without any conditions.
601
+ *
602
+ * Unsafe and intended only for local development, prototyping, or tests.
603
+ * Do not use this in production environments, as it effectively disables
604
+ * authorization checks.
605
+ */
606
+ const unsafeAllowAllGqlPermission = [{
607
+ conditions: [],
608
+ actions: "all",
609
+ permit: true
610
+ }];
611
+
612
+ //#endregion
613
+ export { unsafeAllowAllTypePermission as n, db as r, unsafeAllowAllGqlPermission as t };
614
+ //# sourceMappingURL=tailordb-Bg9-TZj1.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailordb-Bg9-TZj1.mjs","names":[],"sources":["../src/configure/services/tailordb/schema.ts","../src/configure/services/tailordb/permission.ts"],"sourcesContent":["import { cloneDeep } from \"es-toolkit\";\nimport {\n type AllowedValues,\n type AllowedValuesOutput,\n mapAllowedValues,\n} from \"@/configure/types/field\";\nimport { brandValue } from \"@/utils/brand\";\nimport type { TailorTypeGqlPermission, TailorTypePermission } from \"./permission\";\nimport type { Hook, Hooks, ExcludeNestedDBFields, TypeFeatures } from \"./types\";\nimport type { FieldOptions, FieldOutput, TailorFieldType, TailorToTs } from \"@/types/field-types\";\nimport type { output, InferFieldsOutput, Prettify } from \"@/types/helpers\";\nimport type { PluginAttachment, PluginConfigs } from \"@/types/plugin\";\nimport type {\n TailorDBField as TailorDBFieldBase,\n TailorDBType as TailorDBTypeBase,\n} from \"@/types/tailor-db-field\";\nimport type { TailorField as TailorFieldMinimal } from \"@/types/tailor-field\";\nimport type {\n DBFieldMetadata,\n DefinedDBFieldMetadata,\n SerialConfig,\n IndexDef,\n TailorDBTypeMetadata,\n RawRelationConfig,\n RelationType,\n} from \"@/types/tailordb\";\nimport type { RawPermissions } from \"@/types/tailordb.generated\";\nimport type { InferredAttributeMap, TailorUser } from \"@/types/user\";\nimport type { FieldValidateInput, ValidateConfig, Validators } from \"@/types/validation\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n// Helper alias: DB fields can be arbitrarily nested, so we intentionally keep this loose.\n// oxlint-disable-next-line no-explicit-any\nexport type TailorAnyDBField = TailorDBField<any, any>;\n\n// Helper alias\n// oxlint-disable-next-line no-explicit-any\nexport type TailorAnyDBType = TailorDBType<any, any>;\n\n/**\n * Full TailorDBField interface with builder methods.\n * Extends the minimal structural interface from types/ with fluent API methods.\n */\nexport interface TailorDBField<\n Defined extends DefinedDBFieldMetadata = DefinedDBFieldMetadata,\n // oxlint-disable-next-line no-explicit-any\n Output = any,\n> extends Omit<TailorDBFieldBase<Defined, Output>, \"fields\"> {\n readonly fields: Record<string, TailorAnyDBField>;\n _metadata: DBFieldMetadata;\n\n /**\n * Parse and validate a value against this field's validation rules\n */\n parse(args: FieldParseArgs): StandardSchemaV1.Result<Output>;\n\n /**\n * Internal parse method that tracks field path for nested validation\n * @private\n */\n _parseInternal(args: FieldParseInternalArgs): StandardSchemaV1.Result<Output>;\n\n /**\n * typeName is not available on TailorDB fields.\n * Use typeName on pipeline fields (t.enum / t.object) instead.\n */\n typeName(this: never, typeName: string): never;\n\n /**\n * Set a description for the field\n */\n description<CurrentDefined extends Defined>(\n this: CurrentDefined extends { description: unknown }\n ? never\n : TailorFieldMinimal<CurrentDefined, Output>,\n description: string,\n ): TailorDBField<Prettify<CurrentDefined & { description: true }>, Output>;\n\n /**\n * Define a relation to another type.\n */\n relation<S extends RelationType, T extends TailorAnyDBType, CurrentDefined extends Defined>(\n this: CurrentDefined extends { relation: unknown }\n ? never\n : TailorDBField<CurrentDefined, Output>,\n config: RelationConfig<S, T>,\n ): TailorDBField<\n S extends \"oneToOne\" | \"1-1\"\n ? Prettify<CurrentDefined & { unique: true; index: true; relation: true }>\n : Prettify<CurrentDefined & { index: true; relation: true }>,\n Output\n >;\n\n /**\n * Define a self-referencing relation\n */\n relation<S extends RelationSelfConfig, CurrentDefined extends Defined>(\n this: CurrentDefined extends { relation: unknown }\n ? never\n : TailorDBField<CurrentDefined, Output>,\n config: S,\n ): TailorDBField<\n S[\"type\"] extends \"oneToOne\" | \"1-1\"\n ? Prettify<CurrentDefined & { unique: true; index: true; relation: true }>\n : Prettify<CurrentDefined & { index: true; relation: true }>,\n Output\n >;\n\n /**\n * Add an index to the field\n */\n index<CurrentDefined extends Defined>(\n this: CurrentDefined extends { index: unknown }\n ? never\n : CurrentDefined extends { array: true }\n ? never\n : TailorDBField<CurrentDefined, Output>,\n ): TailorDBField<Prettify<CurrentDefined & { index: true }>, Output>;\n\n /**\n * Make the field unique (also adds an index)\n */\n unique<CurrentDefined extends Defined>(\n this: CurrentDefined extends { unique: unknown }\n ? never\n : CurrentDefined extends { array: true }\n ? never\n : TailorDBField<CurrentDefined, Output>,\n ): TailorDBField<Prettify<CurrentDefined & { unique: true; index: true }>, Output>;\n\n /**\n * Enable vector search on the field (string type only)\n */\n vector<CurrentDefined extends Defined>(\n this: CurrentDefined extends { vector: unknown }\n ? never\n : CurrentDefined extends { type: \"string\"; array: false }\n ? TailorDBField<CurrentDefined, Output>\n : never,\n ): TailorDBField<Prettify<CurrentDefined & { vector: true }>, Output>;\n\n /**\n * Add hooks for create/update operations on this field.\n */\n hooks<CurrentDefined extends Defined, const H extends Hook<unknown, Output>>(\n this: CurrentDefined extends { hooks: unknown }\n ? never\n : CurrentDefined extends { type: \"nested\" }\n ? never\n : TailorDBField<CurrentDefined, Output>,\n hooks: H,\n ): TailorDBField<\n Prettify<\n CurrentDefined & {\n hooks?: {\n create: H extends { create: unknown } ? true : false;\n update: H extends { update: unknown } ? true : false;\n };\n serial: false;\n }\n >,\n Output\n >;\n\n /**\n * Add validation functions to the field.\n */\n validate<CurrentDefined extends Defined>(\n this: CurrentDefined extends { validate: unknown }\n ? never\n : TailorDBField<CurrentDefined, Output>,\n ...validate: FieldValidateInput<Output>[]\n ): TailorDBField<Prettify<CurrentDefined & { validate: true }>, Output>;\n\n /**\n * Configure serial/auto-increment behavior\n */\n serial<CurrentDefined extends Defined>(\n this: CurrentDefined extends { serial: unknown }\n ? never\n : Output extends null\n ? never\n : CurrentDefined extends { type: \"integer\" | \"string\"; array: false }\n ? TailorDBField<CurrentDefined, Output>\n : never,\n config: SerialConfig<CurrentDefined[\"type\"] & (\"integer\" | \"string\")>,\n ): TailorDBField<\n Prettify<\n CurrentDefined & {\n serial: true;\n hooks: { create: false; update: false };\n }\n >,\n Output\n >;\n\n /**\n * Clone the field with optional overrides for field options\n */\n clone<const NewOpt extends FieldOptions>(\n options?: NewOpt,\n ): TailorDBField<\n Prettify<\n Omit<Defined, \"array\"> & {\n array: NewOpt extends { array: true } ? true : Defined[\"array\"];\n }\n >,\n FieldOutput<TailorToTs[Defined[\"type\"]], NewOpt>\n >;\n}\n\n/**\n * Full TailorDBType interface with builder methods.\n * Extends the minimal structural interface from types/ with fluent API methods.\n */\nexport interface TailorDBType<\n // oxlint-disable-next-line no-explicit-any\n Fields extends Record<string, TailorAnyDBField> = any,\n User extends object = InferredAttributeMap,\n> extends TailorDBTypeBase<Fields, User> {\n _description?: string;\n\n hooks(hooks: Hooks<Fields>): TailorDBType<Fields, User>;\n validate(validators: Validators<Fields>): TailorDBType<Fields, User>;\n features(features: Omit<TypeFeatures, \"pluralForm\">): TailorDBType<Fields, User>;\n indexes(...indexes: IndexDef<TailorDBType<Fields, User>>[]): TailorDBType<Fields, User>;\n files<const F extends string>(\n files: Record<F, string> & Partial<Record<keyof output<TailorDBType<Fields, User>>, never>>,\n ): TailorDBType<Fields, User>;\n permission<\n U extends object = User,\n P extends TailorTypePermission<U, output<TailorDBType<Fields, User>>> = TailorTypePermission<\n U,\n output<TailorDBType<Fields, User>>\n >,\n >(\n permission: P,\n ): TailorDBType<Fields, U>;\n gqlPermission<\n U extends object = User,\n P extends TailorTypeGqlPermission<U> = TailorTypeGqlPermission<U>,\n >(\n permission: P,\n ): TailorDBType<Fields, U>;\n description(description: string): TailorDBType<Fields, User>;\n pickFields<K extends keyof Fields>(keys: K[]): Pick<Fields, K>;\n pickFields<K extends keyof Fields, const Opt extends FieldOptions>(\n keys: K[],\n options: Opt,\n ): {\n [P in K]: Fields[P] extends TailorDBField<infer D, infer _O>\n ? TailorDBField<\n Omit<D, \"array\"> & {\n array: Opt extends { array: true } ? true : D[\"array\"];\n },\n FieldOutput<TailorToTs[D[\"type\"]], Opt>\n >\n : never;\n };\n omitFields<K extends keyof Fields>(keys: K[]): Omit<Fields, K>;\n plugin<P extends keyof PluginConfigs<keyof Fields & string>>(config: {\n [K in P]: PluginConfigs<keyof Fields & string>[K];\n }): TailorDBType<Fields, User>;\n}\n\nexport type TailorDBInstance<\n // oxlint-disable-next-line no-explicit-any\n Fields extends Record<string, TailorAnyDBField> = any,\n User extends object = InferredAttributeMap,\n> = TailorDBType<Fields, User>;\n\ninterface RelationConfig<S extends RelationType, T extends TailorDBType> {\n type: S;\n toward: {\n type: T;\n as?: string;\n key?: keyof T[\"fields\"] & string;\n };\n backward?: string;\n}\n\n// Special config variant for self-referencing relations\ntype RelationSelfConfig = {\n type: RelationType;\n toward: {\n type: \"self\";\n as?: string;\n key?: string;\n };\n backward?: string;\n};\n\nfunction isRelationSelfConfig(\n config: RelationConfig<RelationType, TailorDBType> | RelationSelfConfig,\n): config is RelationSelfConfig {\n return config.toward.type === \"self\";\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 TailorDBField 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 TailorDBField\n */\nfunction createTailorDBField<\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, TailorAnyDBField>,\n values?: AllowedValues,\n): TailorDBField<\n { type: T; array: TOptions extends { array: true } ? true : false },\n FieldOutput<OutputBase, TOptions>\n> {\n type FieldType = TailorDBField<\n { type: T; array: TOptions extends { array: true } ? true : false },\n FieldOutput<OutputBase, TOptions>\n >;\n\n const _metadata: DBFieldMetadata = { required: true };\n let _rawRelation: RawRelationConfig | undefined;\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 function cloneWith(metadataUpdates: Partial<DBFieldMetadata>) {\n const cloned = field.clone();\n Object.assign(cloned._metadata, metadataUpdates);\n return cloned;\n }\n\n const field: FieldType = {\n type,\n fields: (fields ?? {}) as Record<string, TailorAnyDBField>,\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 get rawRelation(): Readonly<RawRelationConfig> | undefined {\n return _rawRelation ? { ..._rawRelation, toward: { ..._rawRelation.toward } } : undefined;\n },\n\n description(description: string) {\n // oxlint-disable-next-line no-explicit-any\n return cloneWith({ description }) as any;\n },\n\n // oxlint-disable-next-line no-explicit-any\n typeName: ((typeName: string) => cloneWith({ typeName })) as any,\n\n validate(...validateInputs: FieldValidateInput<FieldOutput<OutputBase, TOptions>>[]) {\n // oxlint-disable-next-line no-explicit-any\n return cloneWith({ validate: validateInputs }) 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 // TailorDBField specific methods\n relation(config: RelationConfig<RelationType, TailorDBType> | RelationSelfConfig) {\n const cloned = field.clone();\n const targetType = isRelationSelfConfig(config) ? \"self\" : config.toward.type.name;\n // oxlint-disable-next-line no-explicit-any\n (cloned as any)._setRawRelation({\n type: config.type,\n toward: {\n type: targetType,\n as: config.toward.as,\n key: config.toward.key,\n },\n backward: config.backward,\n });\n // oxlint-disable-next-line no-explicit-any\n return cloned as any;\n },\n\n index() {\n // oxlint-disable-next-line no-explicit-any\n return cloneWith({ index: true }) as any;\n },\n\n unique() {\n // oxlint-disable-next-line no-explicit-any\n return cloneWith({ unique: true, index: true }) as any;\n },\n\n vector() {\n // oxlint-disable-next-line no-explicit-any\n return cloneWith({ vector: true }) as any;\n },\n\n hooks(hooks: Hook<unknown, FieldOutput<OutputBase, TOptions>>) {\n // oxlint-disable-next-line no-explicit-any\n return cloneWith({ hooks }) as any;\n },\n\n serial(config: SerialConfig) {\n // oxlint-disable-next-line no-explicit-any\n return cloneWith({ serial: config }) as any;\n },\n\n clone(cloneOptions?: FieldOptions) {\n // Deep clone nested object fields if present\n let clonedFields = fields;\n if (fields) {\n const cloned: Record<string, TailorAnyDBField> = {};\n for (const [key, field] of Object.entries(fields)) {\n cloned[key] = field.clone();\n }\n clonedFields = cloned;\n }\n\n // Create a new field with cloned configuration\n const clonedField = createTailorDBField(type, options, clonedFields, values);\n\n // Deep copy metadata using cloneDeep (preserves function references)\n Object.assign(clonedField._metadata, cloneDeep(this._metadata));\n\n // Apply new options if provided\n if (cloneOptions) {\n if (cloneOptions.optional !== undefined) {\n clonedField._metadata.required = !cloneOptions.optional;\n }\n if (cloneOptions.array !== undefined) {\n clonedField._metadata.array = cloneOptions.array;\n }\n }\n\n // Copy raw relation if exists\n if (_rawRelation) {\n const clonedRawRelation = cloneDeep(_rawRelation);\n // oxlint-disable-next-line no-explicit-any\n (clonedField as any)._setRawRelation(clonedRawRelation);\n }\n\n // oxlint-disable-next-line no-explicit-any\n return clonedField as any;\n },\n\n // Internal method for clone to set rawRelation\n // @ts-ignore - Internal method not in interface\n _setRawRelation(relation: RawRelationConfig) {\n _rawRelation = relation;\n },\n };\n\n return field;\n}\n\nconst createField = createTailorDBField;\n\n/**\n * Create a UUID field.\n * @param options - Field configuration options\n * @returns A UUID field\n * @example db.uuid()\n * @example db.uuid({ optional: true })\n */\nfunction uuid<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"uuid\", options);\n}\n\n/**\n * Create a string field.\n * @param options - Field configuration options\n * @returns A string field\n * @example db.string()\n * @example db.string({ optional: true })\n */\nfunction string<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"string\", options);\n}\n\n/**\n * Create a boolean field.\n * Note: The method name is `bool` but creates a `boolean` type field.\n * @param options - Field configuration options\n * @returns A boolean field\n * @example db.bool()\n * @example db.bool({ optional: true })\n */\nfunction bool<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"boolean\", options);\n}\n\n/**\n * Create an integer field.\n * @param options - Field configuration options\n * @returns An integer field\n * @example db.int()\n * @example db.int({ optional: true })\n */\nfunction int<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"integer\", options);\n}\n\n/**\n * Create a float (decimal number) field.\n * @param options - Field configuration options\n * @returns A float field\n * @example db.float()\n * @example db.float({ optional: true })\n */\nfunction float<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"float\", options);\n}\n\ninterface DecimalFieldOptions extends FieldOptions {\n scale?: number;\n}\n\n/**\n * Create a decimal field (stored as string for precision).\n * @param options - Field configuration options including optional scale (0-12)\n * @returns A decimal field\n * @example db.decimal()\n * @example db.decimal({ scale: 2 })\n * @example db.decimal({ scale: 2, optional: true })\n */\nfunction decimal<const Opt extends DecimalFieldOptions>(options?: Opt) {\n if (options?.scale !== undefined) {\n if (!Number.isInteger(options.scale) || options.scale < 0 || options.scale > 12) {\n throw new Error(\"scale must be an integer between 0 and 12\");\n }\n }\n const field = createField(\"decimal\", options);\n if (options?.scale !== undefined) {\n field._metadata.scale = options.scale;\n }\n return field;\n}\n\n/**\n * Create a date field (date only, no time component).\n * Format: \"yyyy-MM-dd\"\n * @param options - Field configuration options\n * @returns A date field\n * @example db.date()\n */\nfunction date<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"date\", options);\n}\n\n/**\n * Create a datetime field (date and time).\n * Format: ISO 8601 \"yyyy-MM-ddTHH:mm:ssZ\"\n * @param options - Field configuration options\n * @returns A datetime field\n * @example db.datetime()\n */\nfunction datetime<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"datetime\", options);\n}\n\n/**\n * Create a time field (time only, no date component).\n * Format: \"HH:mm\"\n * @param options - Field configuration options\n * @returns A time field\n * @example db.time()\n */\nfunction time<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"time\", options);\n}\n\n/**\n * Create an enum field with a fixed set of allowed string values.\n * @param values - Array of allowed string values, or array of `{ value, description }` objects\n * @param options - Field configuration options\n * @returns An enum field\n * @example db.enum([\"active\", \"inactive\", \"suspended\"])\n * @example db.enum([\"small\", \"medium\", \"large\"], { optional: true })\n */\nfunction _enum<const V extends AllowedValues, const Opt extends FieldOptions>(\n values: V,\n options?: Opt,\n): TailorDBField<\n { type: \"enum\"; array: Opt extends { array: true } ? true : false },\n FieldOutput<AllowedValuesOutput<V>, Opt>\n> {\n return createField<\"enum\", Opt, AllowedValuesOutput<V>>(\"enum\", options, undefined, values);\n}\n\n/**\n * Create a nested object field with sub-fields.\n * @param fields - Record of nested field definitions\n * @param options - Field configuration options\n * @returns A nested object field\n * @example db.object({ street: db.string(), city: db.string(), zip: db.string() })\n * @example db.object({ name: db.string() }, { optional: true })\n */\nfunction object<\n const F extends Record<string, TailorAnyDBField> & ExcludeNestedDBFields<F>,\n const Opt extends FieldOptions,\n>(fields: F, options?: Opt) {\n return createField(\"nested\", options, fields) as unknown as TailorDBField<\n { type: \"nested\"; array: Opt extends { array: true } ? true : false },\n FieldOutput<InferFieldsOutput<F>, Opt>\n >;\n}\n\n/**\n * Creates a new TailorDBType instance.\n * @param name - Type name\n * @param fields - Field definitions\n * @param options - Type options\n * @param options.pluralForm - Optional plural form\n * @param options.description - Optional description\n * @returns A new TailorDBType\n */\nfunction createTailorDBType<\n // oxlint-disable-next-line no-explicit-any\n const Fields extends Record<string, TailorAnyDBField> = any,\n User extends object = InferredAttributeMap,\n>(\n name: string,\n fields: Fields,\n options: { pluralForm?: string; description?: string },\n): TailorDBType<Fields, User> {\n let _description = options.description;\n let _settings: TypeFeatures = {};\n let _indexes: IndexDef<TailorDBType<Fields, User>>[] = [];\n const _permissions: RawPermissions = {};\n let _files: Record<string, string> = {};\n const _plugins: PluginAttachment[] = [];\n\n if (options.pluralForm) {\n if (name === options.pluralForm) {\n throw new Error(`The name and the plural form must be different. name=${name}`);\n }\n _settings.pluralForm = options.pluralForm;\n }\n\n const dbType: TailorDBType<Fields, User> = {\n name,\n fields: { ...fields },\n _output: null as unknown as InferFieldsOutput<Fields>,\n _description,\n\n get metadata(): TailorDBTypeMetadata {\n // Convert indexes to the format expected by the manifest\n const indexes: Record<string, { fields: string[]; unique?: boolean }> = {};\n if (_indexes && _indexes.length > 0) {\n _indexes.forEach((index) => {\n const fieldNames = index.fields.map((field) => String(field));\n const key = index.name || `idx_${fieldNames.join(\"_\")}`;\n indexes[key] = {\n fields: fieldNames,\n unique: index.unique,\n };\n });\n }\n\n return {\n name: this.name,\n description: _description,\n settings: _settings,\n permissions: _permissions,\n files: _files,\n ...(Object.keys(indexes).length > 0 && { indexes }),\n };\n },\n\n hooks(hooks: Hooks<Fields>) {\n // `Hooks<Fields>` is strongly typed, but `Object.entries()` loses that information.\n // oxlint-disable-next-line no-explicit-any\n Object.entries(hooks).forEach(([fieldName, fieldHooks]: [string, any]) => {\n (this.fields as Record<string, TailorAnyDBField>)[fieldName] =\n this.fields[fieldName].hooks(fieldHooks);\n });\n return this;\n },\n\n validate(validators: Validators<Fields>) {\n Object.entries(validators).forEach(([fieldName, fieldValidators]) => {\n const field = this.fields[fieldName] as TailorAnyDBField;\n\n const validators = fieldValidators as\n | FieldValidateInput<unknown>\n | FieldValidateInput<unknown>[];\n\n const isValidateConfig = (v: unknown): v is ValidateConfig<unknown> => {\n return Array.isArray(v) && v.length === 2 && typeof v[1] === \"string\";\n };\n\n let updatedField: TailorAnyDBField;\n if (Array.isArray(validators)) {\n if (isValidateConfig(validators)) {\n updatedField = field.validate(validators);\n } else {\n updatedField = field.validate(...validators);\n }\n } else {\n updatedField = field.validate(validators);\n }\n (this.fields as Record<string, TailorAnyDBField>)[fieldName] = updatedField;\n });\n return this;\n },\n\n features(features: Omit<TypeFeatures, \"pluralForm\">) {\n _settings = {\n ..._settings,\n ...features,\n };\n return this;\n },\n\n indexes(...indexes: IndexDef<TailorDBType<Fields, User>>[]) {\n _indexes = indexes;\n return this;\n },\n\n files<const F extends string>(\n files: Record<F, string> & Partial<Record<keyof output<TailorDBType<Fields, User>>, never>>,\n ) {\n _files = files;\n return this;\n },\n\n permission<\n U extends object = User,\n P extends TailorTypePermission<U, output<TailorDBType<Fields, User>>> = TailorTypePermission<\n U,\n output<TailorDBType<Fields, User>>\n >,\n >(permission: P) {\n const ret = this as TailorDBType<Fields, U>;\n _permissions.record = permission as RawPermissions[\"record\"];\n return ret;\n },\n\n gqlPermission<\n U extends object = User,\n P extends TailorTypeGqlPermission<U> = TailorTypeGqlPermission<U>,\n >(permission: P) {\n const ret = this as TailorDBType<Fields, U>;\n _permissions.gql = permission as RawPermissions[\"gql\"];\n return ret;\n },\n\n description(description: string) {\n _description = description;\n this._description = description;\n return this;\n },\n\n pickFields<K extends keyof Fields, const Opt extends FieldOptions>(keys: K[], options?: Opt) {\n const result = {} as Record<K, TailorAnyDBField>;\n for (const key of keys) {\n if (options) {\n result[key] = this.fields[key].clone(options);\n } else {\n result[key] = this.fields[key];\n }\n }\n // oxlint-disable-next-line no-explicit-any\n return result as any;\n },\n\n omitFields<K extends keyof Fields>(keys: K[]): Omit<Fields, K> {\n const keysSet = new Set(keys);\n const result = {} as Record<string, TailorAnyDBField>;\n for (const key in this.fields) {\n if (Object.hasOwn(this.fields, key) && !keysSet.has(key as unknown as K)) {\n result[key] = this.fields[key];\n }\n }\n return result as Omit<Fields, K>;\n },\n\n get plugins(): PluginAttachment[] {\n return _plugins;\n },\n\n plugin<P extends keyof PluginConfigs<keyof Fields & string>>(config: {\n [K in P]: PluginConfigs<keyof Fields & string>[K];\n }): TailorDBType<Fields, User> {\n for (const [pluginId, pluginConfig] of Object.entries(config)) {\n _plugins.push({ pluginId, config: pluginConfig });\n }\n return this;\n },\n };\n\n return brandValue(dbType, \"tailordb-type\");\n}\n\nconst idField = uuid();\ntype idField = typeof idField;\ntype DBType<F extends { id?: never } & Record<string, TailorAnyDBField>> = TailorDBInstance<\n { id: idField } & F\n>;\n\n/**\n * Creates a new database type with the specified fields.\n * An `id` field (UUID) is automatically added to every type.\n * @param name - The name of the type, or a tuple of [name, pluralForm]\n * @param fields - The field definitions for the type\n * @returns A new TailorDBType instance\n * @example\n * export const user = db.type(\"User\", {\n * name: db.string(),\n * email: db.string(),\n * age: db.int({ optional: true }),\n * role: db.enum([\"admin\", \"member\"]),\n * ...db.fields.timestamps(),\n * });\n * // Always export both the value and type:\n * export type user = typeof user;\n */\nfunction dbType<const F extends { id?: never } & Record<string, TailorAnyDBField>>(\n name: string | [string, string],\n fields: F,\n): DBType<F>;\n/**\n * Creates a new database type with the specified fields and description.\n * An `id` field (UUID) is automatically added to every type.\n * @param name - The name of the type, or a tuple of [name, pluralForm]\n * @param description - A description of the type\n * @param fields - The field definitions for the type\n * @returns A new TailorDBType instance\n */\nfunction dbType<const F extends { id?: never } & Record<string, TailorAnyDBField>>(\n name: string | [string, string],\n description: string,\n fields: F,\n): DBType<F>;\nfunction dbType<const F extends { id?: never } & Record<string, TailorAnyDBField>>(\n name: string | [string, string],\n fieldsOrDescription: string | F,\n fields?: F,\n): DBType<F> {\n const typeName = Array.isArray(name) ? name[0] : name;\n const pluralForm = Array.isArray(name) ? name[1] : undefined;\n\n let description: string | undefined;\n let fieldDef: F;\n if (typeof fieldsOrDescription === \"string\") {\n description = fieldsOrDescription;\n fieldDef = fields as F;\n } else {\n fieldDef = fieldsOrDescription;\n }\n return createTailorDBType<{ id: idField } & F>(\n typeName,\n {\n id: idField,\n ...fieldDef,\n },\n { pluralForm, description },\n ) as DBType<F>;\n}\n\n/** TailorDB schema builder utilities for defining types and fields. */\nexport const db = {\n type: dbType,\n uuid,\n string,\n bool,\n int,\n float,\n decimal,\n date,\n datetime,\n time,\n enum: _enum,\n object,\n fields: {\n /**\n * Creates standard timestamp fields (createdAt, updatedAt) with auto-hooks.\n * createdAt is set on create, updatedAt is set on update.\n * @returns An object with createdAt and updatedAt fields\n * @example\n * const model = db.type(\"Model\", {\n * name: db.string(),\n * ...db.fields.timestamps(),\n * });\n */\n timestamps: () => ({\n createdAt: datetime()\n .hooks({ create: () => new Date() })\n .description(\"Record creation timestamp\"),\n updatedAt: datetime({ optional: true })\n .hooks({ update: () => new Date() })\n .description(\"Record last update timestamp\"),\n }),\n },\n};\n","import type { InferredAttributeMap } from \"@/types/user\";\n\n// --- Permission types (UX-focused, for configure layer) ---\n\n/**\n * Record-level permission configuration for a TailorDB type.\n * Defines create, read, update, and delete permissions.\n *\n * Prefer object format with explicit `conditions` and `permit` for readability.\n * Shorthand array format is supported for compatibility, but less readable.\n *\n * For update operations, use `newRecord`/`oldRecord` operands instead of `record`.\n * @example\n * const permission: TailorTypePermission = {\n * create: [{ conditions: [[{ user: \"_loggedIn\" }, \"=\", true]], permit: true }],\n * read: [{ conditions: [[{ record: \"isPublic\" }, \"=\", true]], permit: true }],\n * update: [{ conditions: [[{ newRecord: \"ownerId\" }, \"=\", { user: \"id\" }]], permit: true }],\n * delete: [{ conditions: [[{ record: \"ownerId\" }, \"=\", { user: \"id\" }]], permit: true }],\n * };\n */\nexport type TailorTypePermission<\n User extends object = InferredAttributeMap,\n Type extends object = object,\n> = {\n create: readonly ActionPermission<\"record\", User, Type, false>[];\n read: readonly ActionPermission<\"record\", User, Type, false>[];\n update: readonly ActionPermission<\"record\", User, Type, true>[];\n delete: readonly ActionPermission<\"record\", User, Type, false>[];\n};\n\ntype ActionPermission<\n Level extends \"record\" | \"gql\" = \"record\" | \"gql\",\n User extends object = InferredAttributeMap,\n Type extends object = object,\n Update extends boolean = boolean,\n> =\n | {\n conditions:\n | PermissionCondition<Level, User, Update, Type>\n | readonly PermissionCondition<Level, User, Update, Type>[];\n description?: string | undefined;\n permit?: boolean;\n }\n | readonly [...PermissionCondition<Level, User, Update, Type>, ...([] | [boolean])] // single array condition\n | readonly [...PermissionCondition<Level, User, Update, Type>[], ...([] | [boolean])]; // multiple array condition\n\nexport type TailorTypeGqlPermission<\n User extends object = InferredAttributeMap,\n Type extends object = object,\n> = readonly GqlPermissionPolicy<User, Type>[];\n\ntype GqlPermissionPolicy<\n User extends object = InferredAttributeMap,\n Type extends object = object,\n> = {\n conditions: readonly PermissionCondition<\"gql\", User, boolean, Type>[];\n actions: \"all\" | readonly GqlPermissionAction[];\n permit?: boolean;\n description?: string;\n};\n\ntype GqlPermissionAction = \"read\" | \"create\" | \"update\" | \"delete\" | \"aggregate\" | \"bulkUpsert\";\n\ntype EqualityOperator = \"=\" | \"!=\";\ntype ContainsOperator = \"in\" | \"not in\";\ntype HasAnyOperator = \"hasAny\" | \"not hasAny\";\n\n// Helper types for User field extraction\ntype StringFieldKeys<User extends object> = {\n [K in keyof User]: User[K] extends string ? K : never;\n}[keyof User];\n\ntype StringArrayFieldKeys<User extends object> = {\n [K in keyof User]: User[K] extends string[] ? K : never;\n}[keyof User];\n\ntype BooleanFieldKeys<User extends object> = {\n [K in keyof User]: User[K] extends boolean ? K : never;\n}[keyof User];\n\ntype BooleanArrayFieldKeys<User extends object> = {\n [K in keyof User]: User[K] extends boolean[] ? K : never;\n}[keyof User];\n\ntype UserStringOperand<User extends object = InferredAttributeMap> = {\n user: StringFieldKeys<User> | \"id\";\n};\n\ntype UserStringArrayOperand<User extends object = InferredAttributeMap> = {\n user: StringArrayFieldKeys<User>;\n};\n\ntype UserBooleanOperand<User extends object = InferredAttributeMap> = {\n user: BooleanFieldKeys<User> | \"_loggedIn\";\n};\n\ntype UserBooleanArrayOperand<User extends object = InferredAttributeMap> = {\n user: BooleanArrayFieldKeys<User>;\n};\n\ntype RecordOperand<Type extends object, Update extends boolean = false> = Update extends true\n ? { oldRecord: (keyof Type & string) | \"id\" } | { newRecord: (keyof Type & string) | \"id\" }\n : { record: (keyof Type & string) | \"id\" };\n\ntype StringEqualityCondition<\n Level extends \"record\" | \"gql\",\n User extends object,\n Update extends boolean,\n Type extends object,\n> =\n | (Level extends \"gql\" ? readonly [string, EqualityOperator, boolean] : never)\n | readonly [string, EqualityOperator, string]\n | readonly [UserStringOperand<User>, EqualityOperator, string]\n | readonly [string, EqualityOperator, UserStringOperand<User>]\n | (Level extends \"record\"\n ?\n | readonly [\n RecordOperand<Type, Update>,\n EqualityOperator,\n string | UserStringOperand<User>,\n ]\n | readonly [\n string | UserStringOperand<User>,\n EqualityOperator,\n RecordOperand<Type, Update>,\n ]\n : never);\n\ntype BooleanEqualityCondition<\n Level extends \"record\" | \"gql\",\n User extends object,\n Update extends boolean,\n Type extends object,\n> =\n | readonly [boolean, EqualityOperator, boolean]\n | readonly [UserBooleanOperand<User>, EqualityOperator, boolean]\n | readonly [boolean, EqualityOperator, UserBooleanOperand<User>]\n | (Level extends \"record\"\n ?\n | readonly [\n RecordOperand<Type, Update>,\n EqualityOperator,\n boolean | UserBooleanOperand<User>,\n ]\n | readonly [\n boolean | UserBooleanOperand<User>,\n EqualityOperator,\n RecordOperand<Type, Update>,\n ]\n : never);\n\ntype EqualityCondition<\n Level extends \"record\" | \"gql\" = \"record\",\n User extends object = InferredAttributeMap,\n Update extends boolean = boolean,\n Type extends object = object,\n> =\n | StringEqualityCondition<Level, User, Update, Type>\n | BooleanEqualityCondition<Level, User, Update, Type>;\n\ntype StringContainsCondition<\n Level extends \"record\" | \"gql\",\n User extends object,\n Update extends boolean,\n Type extends object,\n> =\n | readonly [string, ContainsOperator, string[]]\n | readonly [UserStringOperand<User>, ContainsOperator, string[]]\n | readonly [string, ContainsOperator, UserStringArrayOperand<User>]\n | (Level extends \"record\"\n ?\n | readonly [\n RecordOperand<Type, Update>,\n ContainsOperator,\n string[] | UserStringArrayOperand<User>,\n ]\n | readonly [\n string | UserStringOperand<User>,\n ContainsOperator,\n RecordOperand<Type, Update>,\n ]\n : never);\n\ntype BooleanContainsCondition<\n Level extends \"record\" | \"gql\",\n User extends object,\n Update extends boolean,\n Type extends object,\n> =\n | (Level extends \"gql\" ? readonly [string, ContainsOperator, boolean[]] : never)\n | readonly [boolean, ContainsOperator, boolean[]]\n | readonly [UserBooleanOperand<User>, ContainsOperator, boolean[]]\n | readonly [boolean, ContainsOperator, UserBooleanArrayOperand<User>]\n | (Level extends \"record\"\n ?\n | readonly [\n RecordOperand<Type, Update>,\n ContainsOperator,\n boolean[] | UserBooleanArrayOperand<User>,\n ]\n | readonly [\n boolean | UserBooleanOperand<User>,\n ContainsOperator,\n RecordOperand<Type, Update>,\n ]\n : never);\n\ntype ContainsCondition<\n Level extends \"record\" | \"gql\" = \"record\",\n User extends object = InferredAttributeMap,\n Update extends boolean = boolean,\n Type extends object = object,\n> =\n | StringContainsCondition<Level, User, Update, Type>\n | BooleanContainsCondition<Level, User, Update, Type>;\n\ntype HasAnyCondition<\n Level extends \"record\" | \"gql\",\n User extends object,\n Update extends boolean,\n Type extends object,\n> =\n | readonly [\n string[] | UserStringArrayOperand<User>,\n HasAnyOperator,\n string[] | UserStringArrayOperand<User>,\n ]\n | (Level extends \"record\"\n ?\n | readonly [\n RecordOperand<Type, Update>,\n HasAnyOperator,\n string[] | UserStringArrayOperand<User>,\n ]\n | readonly [\n string[] | UserStringArrayOperand<User>,\n HasAnyOperator,\n RecordOperand<Type, Update>,\n ]\n : never);\n\n/**\n * Type representing a permission condition that combines user attributes, record fields, and literal values using comparison operators.\n *\n * The User type is extended by `tailor.d.ts`, which is automatically generated when running `tailor-sdk generate`.\n * Attributes enabled in the config file's `auth.userProfile.attributes` (or\n * `auth.machineUserAttributes` when userProfile is omitted) become available as types.\n * @example\n * ```ts\n * // tailor.config.ts\n * export const auth = defineAuth(\"my-auth\", {\n * userProfile: {\n * type: user,\n * attributes: {\n * isAdmin: true,\n * roles: true,\n * }\n * }\n * });\n * ```\n */\nexport type PermissionCondition<\n Level extends \"record\" | \"gql\" = \"record\",\n User extends object = InferredAttributeMap,\n Update extends boolean = boolean,\n Type extends object = object,\n> =\n | EqualityCondition<Level, User, Update, Type>\n | ContainsCondition<Level, User, Update, Type>\n | HasAnyCondition<Level, User, Update, Type>;\n\n// --- Runtime constants ---\n\n/**\n * Grants full record-level access without any conditions.\n *\n * Unsafe and intended only for local development, prototyping, or tests.\n * Do not use this in production environments, as it effectively disables\n * authorization checks.\n */\nexport const unsafeAllowAllTypePermission: TailorTypePermission = {\n create: [{ conditions: [], permit: true }],\n read: [{ conditions: [], permit: true }],\n update: [{ conditions: [], permit: true }],\n delete: [{ conditions: [], permit: true }],\n};\n\n/**\n * Grants full GraphQL access (all actions) without any conditions.\n *\n * Unsafe and intended only for local development, prototyping, or tests.\n * Do not use this in production environments, as it effectively disables\n * authorization checks.\n */\nexport const unsafeAllowAllGqlPermission: TailorTypeGqlPermission = [\n { conditions: [], actions: \"all\", permit: true },\n];\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /// <reference types="@tailor-platform/function-types" />
2
- import { Vt as TailorInvoker } from "../../tailor-db-field-Hx9OqPWY.mjs";
3
- import { O as TailorDBType } from "../../workflow.generated-DFljpJh7.mjs";
4
- import { dt as WORKFLOW_TEST_ENV_KEY, n as output, xt as TailorField } from "../../index-PB0otrDj.mjs";
2
+ import { Vt as TailorInvoker } from "../../tailor-db-field-Bn8ZC5lK.mjs";
3
+ import { O as TailorDBType } from "../../workflow.generated-i7PK4fg-.mjs";
4
+ import { dt as WORKFLOW_TEST_ENV_KEY, n as output, xt as TailorField } from "../../index-BoU_52Du.mjs";
5
5
  import { StandardSchemaV1 } from "@standard-schema/spec";
6
6
 
7
7
  //#region src/utils/test/mock.d.ts
@@ -12,6 +12,7 @@ type WaitHandler = (key: string, payload: unknown) => unknown;
12
12
  type ResolveHandler = (executionId: string, key: string, callback: (payload: unknown) => unknown) => Promise<void> | void;
13
13
  /**
14
14
  * Sets up a mock for `globalThis.tailordb.Client` used in bundled resolver/executor tests.
15
+ * @deprecated Use `tailordbMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.
15
16
  * @param resolver - Optional function to resolve query results. Defaults to returning empty arrays.
16
17
  * @returns Object containing arrays of executed queries and created clients for assertions.
17
18
  */
@@ -27,8 +28,9 @@ declare function setupTailordbMock(resolver?: QueryResolver): {
27
28
  };
28
29
  /**
29
30
  * Sets up a mock for `globalThis.tailor.workflow.triggerJobFunction` used in bundled workflow tests.
30
- * `wait`/`resolve` are stubbed to throw a helpful error directing to `setupWaitPointMock()`,
31
+ * `wait`/`resolve` are stubbed to throw a helpful error directing to `workflowMock`,
31
32
  * so mistakenly calling wait without wait-point mocks produces a clear message instead of a TypeError.
33
+ * @deprecated Use `workflowMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.
32
34
  * @param handler - Function that handles triggered job calls and returns results.
33
35
  * @returns Object containing an array of triggered jobs for assertions.
34
36
  */
@@ -41,18 +43,22 @@ declare function setupWorkflowMock(handler: JobHandler): {
41
43
  /**
42
44
  * Sets up a mock for `globalThis.tailor.context.getInvoker` used in bundled
43
45
  * resolver/executor/workflow tests.
46
+ * @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.
44
47
  * @param invoker - The `TailorInvoker` value to return, or `null` for anonymous.
45
48
  */
46
49
  declare function setupInvokerMock(invoker: TailorInvoker): void;
47
50
  /**
48
51
  * Sets up a mock for `globalThis.TailorErrors` used in bundled resolver tests.
49
52
  * Mimics the PF runtime's TailorErrors class that serializes errors with the `TailorErrors: ` prefix.
53
+ * @deprecated Use the `tailor-runtime` environment from `@tailor-platform/sdk/vitest` which auto-injects TailorErrors.
50
54
  */
51
55
  declare function setupTailorErrorsMock(): void;
52
56
  /**
53
57
  * Sets up mocks for `globalThis.tailor.workflow.wait` and `.resolve` used in bundled workflow tests.
54
58
  * `triggerJobFunction` is stubbed to throw a helpful error directing to `setupWorkflowMock()`,
55
59
  * so mistakenly triggering a job without job mocks produces a clear message instead of silently returning undefined.
60
+ * @deprecated Use `workflowMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.
61
+ * `setWaitHandler` / `setResolveHandler` cover wait/resolve, and `waitCalls` / `resolveCalls` give the same assertion shape.
56
62
  * @param config - Optional handlers for wait and resolve calls.
57
63
  * @param config.onWait - Handler called when wait is invoked.
58
64
  * @param config.onResolve - Handler called when resolve is invoked.
@@ -76,6 +82,9 @@ declare function setupWaitPointMock(config?: {
76
82
  * Used to test bundled output from `apply --buildOnly`.
77
83
  * @param baseDir - Base directory where bundled files are located.
78
84
  * @returns An async function that takes a relative path and returns the `main` function.
85
+ * @deprecated This is an SDK-internal testing helper. Bundling integrity is the SDK's responsibility,
86
+ * not the application's — verify your code through unit tests against the TypeScript source and
87
+ * E2E tests against a deployed application instead. This export will be removed in a future release.
79
88
  */
80
89
  declare function createImportMain(baseDir: string): (relativePath: string) => Promise<MainFunction>;
81
90
  //#endregion
@@ -7,6 +7,7 @@ import * as path from "node:path";
7
7
  const GlobalThis = globalThis;
8
8
  /**
9
9
  * Sets up a mock for `globalThis.tailordb.Client` used in bundled resolver/executor tests.
10
+ * @deprecated Use `tailordbMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.
10
11
  * @param resolver - Optional function to resolve query results. Defaults to returning empty arrays.
11
12
  * @returns Object containing arrays of executed queries and created clients for assertions.
12
13
  */
@@ -42,8 +43,9 @@ function setupTailordbMock(resolver = () => []) {
42
43
  }
43
44
  /**
44
45
  * Sets up a mock for `globalThis.tailor.workflow.triggerJobFunction` used in bundled workflow tests.
45
- * `wait`/`resolve` are stubbed to throw a helpful error directing to `setupWaitPointMock()`,
46
+ * `wait`/`resolve` are stubbed to throw a helpful error directing to `workflowMock`,
46
47
  * so mistakenly calling wait without wait-point mocks produces a clear message instead of a TypeError.
48
+ * @deprecated Use `workflowMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.
47
49
  * @param handler - Function that handles triggered job calls and returns results.
48
50
  * @returns Object containing an array of triggered jobs for assertions.
49
51
  */
@@ -53,10 +55,10 @@ function setupWorkflowMock(handler) {
53
55
  ...GlobalThis.tailor,
54
56
  workflow: {
55
57
  wait: () => {
56
- throw new Error("tailor.workflow.wait is not mocked. Use setupWaitPointMock() in tests.");
58
+ throw new Error("tailor.workflow.wait is not mocked. Use workflowMock from @tailor-platform/sdk/vitest in tests.");
57
59
  },
58
60
  resolve: async () => {
59
- throw new Error("tailor.workflow.resolve is not mocked. Use setupWaitPointMock() in tests.");
61
+ throw new Error("tailor.workflow.resolve is not mocked. Use workflowMock from @tailor-platform/sdk/vitest in tests.");
60
62
  },
61
63
  ...GlobalThis.tailor?.workflow,
62
64
  triggerJobFunction: (jobName, args) => {
@@ -73,6 +75,7 @@ function setupWorkflowMock(handler) {
73
75
  /**
74
76
  * Sets up a mock for `globalThis.tailor.context.getInvoker` used in bundled
75
77
  * resolver/executor/workflow tests.
78
+ * @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.
76
79
  * @param invoker - The `TailorInvoker` value to return, or `null` for anonymous.
77
80
  */
78
81
  function setupInvokerMock(invoker) {
@@ -91,6 +94,7 @@ function setupInvokerMock(invoker) {
91
94
  /**
92
95
  * Sets up a mock for `globalThis.TailorErrors` used in bundled resolver tests.
93
96
  * Mimics the PF runtime's TailorErrors class that serializes errors with the `TailorErrors: ` prefix.
97
+ * @deprecated Use the `tailor-runtime` environment from `@tailor-platform/sdk/vitest` which auto-injects TailorErrors.
94
98
  */
95
99
  function setupTailorErrorsMock() {
96
100
  GlobalThis.TailorErrors = class TailorErrors extends Error {
@@ -106,6 +110,8 @@ function setupTailorErrorsMock() {
106
110
  * Sets up mocks for `globalThis.tailor.workflow.wait` and `.resolve` used in bundled workflow tests.
107
111
  * `triggerJobFunction` is stubbed to throw a helpful error directing to `setupWorkflowMock()`,
108
112
  * so mistakenly triggering a job without job mocks produces a clear message instead of silently returning undefined.
113
+ * @deprecated Use `workflowMock` from `@tailor-platform/sdk/vitest` with the `tailor-runtime` environment instead.
114
+ * `setWaitHandler` / `setResolveHandler` cover wait/resolve, and `waitCalls` / `resolveCalls` give the same assertion shape.
109
115
  * @param config - Optional handlers for wait and resolve calls.
110
116
  * @param config.onWait - Handler called when wait is invoked.
111
117
  * @param config.onResolve - Handler called when resolve is invoked.
@@ -147,6 +153,9 @@ function setupWaitPointMock(config) {
147
153
  * Used to test bundled output from `apply --buildOnly`.
148
154
  * @param baseDir - Base directory where bundled files are located.
149
155
  * @returns An async function that takes a relative path and returns the `main` function.
156
+ * @deprecated This is an SDK-internal testing helper. Bundling integrity is the SDK's responsibility,
157
+ * not the application's — verify your code through unit tests against the TypeScript source and
158
+ * E2E tests against a deployed application instead. This export will be removed in a future release.
150
159
  */
151
160
  function createImportMain(baseDir) {
152
161
  return async (relativePath) => {
@@ -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 * @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 `setupWaitPointMock()`,\n * so mistakenly calling wait without wait-point mocks produces a clear message instead of a TypeError.\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(\"tailor.workflow.wait is not mocked. Use setupWaitPointMock() in tests.\");\n },\n resolve: async () => {\n throw new Error(\n \"tailor.workflow.resolve is not mocked. Use setupWaitPointMock() 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 * @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 */\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 * @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 */\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 { 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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"}
@@ -0,0 +1,12 @@
1
+ /// <reference types="@tailor-platform/function-types" />
2
+ //#region src/vitest/environment.d.ts
3
+ declare const _default: {
4
+ name: string;
5
+ viteEnvironment: string;
6
+ setup(global: typeof globalThis): Promise<{
7
+ teardown(global: typeof globalThis): void;
8
+ }>;
9
+ };
10
+ //#endregion
11
+ export { _default as default };
12
+ //# sourceMappingURL=environment.d.mts.map
@@ -0,0 +1,44 @@
1
+
2
+ import { c as injectMocks, i as cleanupMocks, n as STATE_KEY, t as RUNTIME_FLAG_KEY } from "../mock-BP-9O5On.mjs";
3
+ import * as globals from "globals";
4
+
5
+ //#region src/vitest/environment.ts
6
+ const globalsMap = globals.default ?? globals;
7
+ const ALLOWED_GLOBALS = new Set([
8
+ ...Object.keys(globalsMap.builtin ?? {}),
9
+ ...Object.keys(globalsMap["shared-node-browser"] ?? {}),
10
+ STATE_KEY,
11
+ RUNTIME_FLAG_KEY,
12
+ "process",
13
+ "require",
14
+ "module",
15
+ "exports",
16
+ "__vitest_worker__",
17
+ "__vitest_mocker__",
18
+ "VITEST_POOL_ID"
19
+ ]);
20
+ var environment_default = {
21
+ name: "tailor-runtime",
22
+ viteEnvironment: "ssr",
23
+ async setup(global) {
24
+ const g = global;
25
+ const saved = {};
26
+ for (const key of Object.getOwnPropertyNames(g)) if (!ALLOWED_GLOBALS.has(key)) {
27
+ const descriptor = Object.getOwnPropertyDescriptor(g, key);
28
+ if (descriptor?.configurable) {
29
+ saved[key] = descriptor;
30
+ delete g[key];
31
+ }
32
+ }
33
+ injectMocks(global);
34
+ return { teardown(global) {
35
+ cleanupMocks(global);
36
+ const g = global;
37
+ for (const [key, descriptor] of Object.entries(saved)) Object.defineProperty(g, key, descriptor);
38
+ } };
39
+ }
40
+ };
41
+
42
+ //#endregion
43
+ export { environment_default as default };
44
+ //# sourceMappingURL=environment.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.mjs","names":[],"sources":["../../src/vitest/environment.ts"],"sourcesContent":["import * as globals from \"globals\";\nimport { STATE_KEY, RUNTIME_FLAG_KEY, injectMocks, cleanupMocks } from \"./mock\";\n\n// Normalize the `globals` module shape across CJS/ESM interop so the\n// whitelist build doesn't crash if the default export is unavailable or\n// the keyed sets are missing. Mirrors src/cli/services/tailordb/es-builtins.ts.\ntype GlobalsShape = {\n builtin?: Record<string, boolean>;\n \"shared-node-browser\"?: Record<string, boolean>;\n};\nconst globalsMap: GlobalsShape =\n (globals as unknown as { default?: GlobalsShape }).default ??\n (globals as unknown as GlobalsShape);\n\n// Globals allowed in the Tailor Platform runtime.\n// Mirrors ES_BUILTINS in src/cli/services/tailordb/es-builtins.ts so the\n// emulated runtime exposes exactly the same identifiers as the production\n// platform's free-variable allowlist (ECMAScript builtins + shared\n// Node/browser runtime globals like console, fetch, setTimeout).\n// Platform API mocks (tailor, tailordb, etc.) are not listed here — they are\n// injected by injectMocks() after the whitelist cleanup, so they are never removed.\nconst ALLOWED_GLOBALS = new Set([\n ...Object.keys(globalsMap.builtin ?? {}),\n ...Object.keys(globalsMap[\"shared-node-browser\"] ?? {}),\n\n // Mock state key (lazily populated by mock helpers) and the\n // environment-active flag (set in injectMocks, used by setup.ts to detect\n // the tailor-runtime environment).\n STATE_KEY,\n RUNTIME_FLAG_KEY,\n\n // Used by Vitest internally — not in the platform runtime, but removing breaks the test runner\n \"process\",\n \"require\",\n \"module\",\n \"exports\",\n \"__vitest_worker__\",\n \"__vitest_mocker__\",\n \"VITEST_POOL_ID\",\n]);\n\nexport default {\n name: \"tailor-runtime\",\n viteEnvironment: \"ssr\",\n\n async setup(global: typeof globalThis) {\n const g = global as Record<string, unknown>;\n\n // Save and remove all non-whitelisted globals\n const saved: Record<string, PropertyDescriptor> = {};\n for (const key of Object.getOwnPropertyNames(g)) {\n if (!ALLOWED_GLOBALS.has(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(g, key);\n if (descriptor?.configurable) {\n saved[key] = descriptor;\n delete g[key];\n }\n }\n }\n\n // Inject platform API mocks after whitelist cleanup\n injectMocks(global);\n\n return {\n teardown(global: typeof globalThis) {\n cleanupMocks(global);\n\n // Restore removed globals\n const g = global as Record<string, unknown>;\n for (const [key, descriptor] of Object.entries(saved)) {\n Object.defineProperty(g, key, descriptor);\n }\n },\n };\n },\n};\n"],"mappings":";;;;;AAUA,MAAM,aACH,QAAkD,WAClD;AASH,MAAM,kBAAkB,IAAI,IAAI;CAC9B,GAAG,OAAO,KAAK,WAAW,WAAW,EAAE,CAAC;CACxC,GAAG,OAAO,KAAK,WAAW,0BAA0B,EAAE,CAAC;CAKvD;CACA;CAGA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,0BAAe;CACb,MAAM;CACN,iBAAiB;CAEjB,MAAM,MAAM,QAA2B;EACrC,MAAM,IAAI;EAGV,MAAM,QAA4C,EAAE;AACpD,OAAK,MAAM,OAAO,OAAO,oBAAoB,EAAE,CAC7C,KAAI,CAAC,gBAAgB,IAAI,IAAI,EAAE;GAC7B,MAAM,aAAa,OAAO,yBAAyB,GAAG,IAAI;AAC1D,OAAI,YAAY,cAAc;AAC5B,UAAM,OAAO;AACb,WAAO,EAAE;;;AAMf,cAAY,OAAO;AAEnB,SAAO,EACL,SAAS,QAA2B;AAClC,gBAAa,OAAO;GAGpB,MAAM,IAAI;AACV,QAAK,MAAM,CAAC,KAAK,eAAe,OAAO,QAAQ,MAAM,CACnD,QAAO,eAAe,GAAG,KAAK,WAAW;KAG9C;;CAEJ"}