@tailor-platform/sdk 2.20.0 → 2.21.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 (100) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/application-D4913edS.mjs +199 -0
  3. package/dist/application-D4913edS.mjs.map +1 -0
  4. package/dist/application-DBHaxmJE.mjs +1 -0
  5. package/dist/cli/lib.mjs +1 -1
  6. package/dist/cli/main.d.mts +1 -0
  7. package/dist/cli/main.mjs +35 -35
  8. package/dist/cli/main.mjs.map +1 -1
  9. package/dist/completion/zsh-worker.zsh +654 -131
  10. package/dist/configure/index.d.mts +2 -1
  11. package/dist/configure/index.mjs +12 -1
  12. package/dist/configure/index.mjs.map +1 -1
  13. package/dist/configure/services/secrets/index.d.mts +14 -0
  14. package/dist/configure/services/tailordb/schema.d.mts +3 -2
  15. package/dist/configure/types/secret-vault-name.d.mts +32 -0
  16. package/dist/{crashreport-Cyuz1qiu.mjs → crashreport-BAz-ph5O.mjs} +3 -3
  17. package/dist/{crashreport-Cyuz1qiu.mjs.map → crashreport-BAz-ph5O.mjs.map} +1 -1
  18. package/dist/crashreport-BfOkOFgc.mjs +1 -0
  19. package/dist/{date-B7-oyTGE.mjs → date-Dri6Yas-.mjs} +2 -2
  20. package/dist/date-Dri6Yas-.mjs.map +1 -0
  21. package/dist/{errors-BjJnpXkK.mjs → errors-sNtg2Mv3.mjs} +2 -2
  22. package/dist/{errors-BjJnpXkK.mjs.map → errors-sNtg2Mv3.mjs.map} +1 -1
  23. package/dist/es-builtins-SfvXRVoG.mjs +2 -0
  24. package/dist/{es-builtins-BHCXINQp.mjs.map → es-builtins-SfvXRVoG.mjs.map} +1 -1
  25. package/dist/field-parse-DhnFs9WG.mjs +2 -0
  26. package/dist/field-parse-DhnFs9WG.mjs.map +1 -0
  27. package/dist/{globals-CMHSnj4w.mjs → globals-BCmGX05J.mjs} +2 -2
  28. package/dist/{globals-CMHSnj4w.mjs.map → globals-BCmGX05J.mjs.map} +1 -1
  29. package/dist/guards-DsX7dJCP.mjs +2 -0
  30. package/dist/{guards-ForsrxnH.mjs.map → guards-DsX7dJCP.mjs.map} +1 -1
  31. package/dist/{kysely-type-B_oA8D1k.mjs → kysely-type-C-iyFFH7.mjs} +2 -2
  32. package/dist/{kysely-type-B_oA8D1k.mjs.map → kysely-type-C-iyFFH7.mjs.map} +1 -1
  33. package/dist/{logger-72hM4JWZ.mjs → logger-Cp5U2IDI.mjs} +2 -2
  34. package/dist/{logger-72hM4JWZ.mjs.map → logger-Cp5U2IDI.mjs.map} +1 -1
  35. package/dist/manager-C0dE7pd0.mjs +2 -0
  36. package/dist/{manager-qfbUL7ru.mjs.map → manager-C0dE7pd0.mjs.map} +1 -1
  37. package/dist/plugin/builtin/enum-constants/index.mjs +1 -1
  38. package/dist/plugin/builtin/enum-constants/index.mjs.map +1 -1
  39. package/dist/plugin/builtin/file-utils/index.mjs +1 -1
  40. package/dist/plugin/builtin/file-utils/index.mjs.map +1 -1
  41. package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
  42. package/dist/plugin/index.mjs +1 -1
  43. package/dist/plugin/index.mjs.map +1 -1
  44. package/dist/register-ts-hook-YtsAGTMD.mjs +921 -0
  45. package/dist/{register-ts-hook-FsCX38LQ.mjs.map → register-ts-hook-YtsAGTMD.mjs.map} +1 -1
  46. package/dist/registry-BijIDRVA.mjs +2 -0
  47. package/dist/{registry-HlEaGvl5.mjs.map → registry-BijIDRVA.mjs.map} +1 -1
  48. package/dist/repl-editor-DGJBfIt1.mjs +2 -0
  49. package/dist/{repl-editor-BG1aDOfH.mjs.map → repl-editor-DGJBfIt1.mjs.map} +1 -1
  50. package/dist/runtime/field-parse.d.mts +17 -1
  51. package/dist/runtime/index.d.mts +2 -1
  52. package/dist/runtime/index.mjs +1 -1
  53. package/dist/runtime/secretmanager.d.mts +8 -20
  54. package/dist/schema-CRtAmDcl.mjs +2 -0
  55. package/dist/{schema-BKvcWdVf.mjs.map → schema-CRtAmDcl.mjs.map} +1 -1
  56. package/dist/secretmanager-vHQoXdQz.mjs.map +1 -1
  57. package/dist/seed/index.mjs +2 -2
  58. package/dist/seed/index.mjs.map +1 -1
  59. package/dist/{service-B4Gh_bbL.mjs → service-8xznUrPU.mjs} +2 -2
  60. package/dist/{service-B4Gh_bbL.mjs.map → service-8xznUrPU.mjs.map} +1 -1
  61. package/dist/{service-CuqkHP1r.mjs → service-BrGSi2IQ.mjs} +3 -3
  62. package/dist/{service-CuqkHP1r.mjs.map → service-BrGSi2IQ.mjs.map} +1 -1
  63. package/dist/service-DWMm-4Vm.mjs +1 -0
  64. package/dist/service_pb-DNskuJQC.mjs +1 -0
  65. package/dist/service_pb-y2GYIgfs.mjs +2 -0
  66. package/dist/{service_pb-DprmLNsq.mjs.map → service_pb-y2GYIgfs.mjs.map} +1 -1
  67. package/dist/tailordb-ddl-DqInYupv.mjs +7 -0
  68. package/dist/{tailordb-ddl-Fgm2cNvT.mjs.map → tailordb-ddl-DqInYupv.mjs.map} +1 -1
  69. package/dist/utils/test/index.mjs +1 -1
  70. package/dist/utils/test/index.mjs.map +1 -1
  71. package/dist/vitest/environment.mjs +1 -1
  72. package/dist/vitest/environment.mjs.map +1 -1
  73. package/dist/vitest/index.mjs +1 -1
  74. package/dist/vitest/index.mjs.map +1 -1
  75. package/dist/vitest/setup.mjs +1 -1
  76. package/dist/workspace_resource_pb-D2njwgsE.mjs +2 -0
  77. package/dist/{workspace_resource_pb-BOoRts_z.mjs.map → workspace_resource_pb-D2njwgsE.mjs.map} +1 -1
  78. package/docs/migration/v3.md +64 -0
  79. package/docs/services/resolver.md +21 -0
  80. package/docs/services/secret.md +20 -15
  81. package/package.json +12 -12
  82. package/dist/application-B6NYnrhv.mjs +0 -199
  83. package/dist/application-B6NYnrhv.mjs.map +0 -1
  84. package/dist/application-BlbyGJsd.mjs +0 -1
  85. package/dist/crashreport-CgymxQDu.mjs +0 -1
  86. package/dist/date-B7-oyTGE.mjs.map +0 -1
  87. package/dist/es-builtins-BHCXINQp.mjs +0 -2
  88. package/dist/field-parse-BbNyotv5.mjs +0 -2
  89. package/dist/field-parse-BbNyotv5.mjs.map +0 -1
  90. package/dist/guards-ForsrxnH.mjs +0 -2
  91. package/dist/manager-qfbUL7ru.mjs +0 -2
  92. package/dist/register-ts-hook-FsCX38LQ.mjs +0 -917
  93. package/dist/registry-HlEaGvl5.mjs +0 -2
  94. package/dist/repl-editor-BG1aDOfH.mjs +0 -2
  95. package/dist/schema-BKvcWdVf.mjs +0 -2
  96. package/dist/service-BgrEteZ2.mjs +0 -1
  97. package/dist/service_pb-DKrsO1_u.mjs +0 -1
  98. package/dist/service_pb-DprmLNsq.mjs +0 -2
  99. package/dist/tailordb-ddl-Fgm2cNvT.mjs +0 -7
  100. package/dist/workspace_resource_pb-BOoRts_z.mjs +0 -2
@@ -0,0 +1,7 @@
1
+ function mapFieldTypeToColumnType(e){switch(e){case`uuid`:case`string`:case`decimal`:return`string`;case`integer`:case`float`:return`number`;case`date`:case`datetime`:return`Timestamp`;case`bool`:case`boolean`:return`boolean`;case`enum`:case`nested`:throw Error(`Field type "${e}" has no scalar column type; resolve it before mapping.`);default:return`string`}}const e=/* @__PURE__ */ new Map([[`Timestamp`,{select:`Date`,write:`Date | string`}]]),t=new TextEncoder;function mapFieldTypeToPostgresType(e){switch(e){case`uuid`:return`uuid`;case`string`:case`enum`:return`text`;case`boolean`:case`bool`:return`boolean`;case`integer`:return`integer`;case`float`:return`double precision`;case`decimal`:return`numeric`;case`date`:return`date`;case`datetime`:return`timestamptz`;case`time`:return`time`;case`nested`:return`jsonb`;default:throw Error(`Field type "${e}" has no PostgreSQL column type.`)}}function identifier(e){return`"${e.replaceAll(`"`,`""`)}"`}function fnv1aHex(e){let n=2166136261;for(let r of t.encode(e))n=Math.imul(n^r,16777619)>>>0;return n.toString(16).padStart(8,`0`)}function derivedIdentifier(e,n,r){let i=`_${fnv1aHex(JSON.stringify([e,n,r]))}_${r}`,a=`${e}_${n}`;for(;t.encode(a+i).length>63;)a=a.slice(0,-1);return identifier(a+i)}function stringLiteral(e){return`'${e.replaceAll(`'`,`''`)}'`}function columnType(e){let t=e.type===`decimal`?`numeric(1000, ${e.scale??6})`:mapFieldTypeToPostgresType(e.type);return e.array&&e.type!==`nested`?`${t}[]`:t}function scalarLiteral(e,t,n){let r=mapFieldTypeToPostgresType(t.type);if(e instanceof Date){if(Number.isNaN(e.getTime()))throw Error(`Default of field ${n} is an invalid Date.`);return`${stringLiteral(e.toISOString())}::${r}`}switch(typeof e){case`string`:return r===`text`?stringLiteral(e):`${stringLiteral(e)}::${r}`;case`number`:if(!Number.isFinite(e))throw Error(`Default of field ${n} is not a finite number.`);return String(e);case`boolean`:return e?`TRUE`:`FALSE`;default:throw Error(`Default of field ${n} cannot be rendered as a SQL literal.`)}}const n=/* @__PURE__ */ new Map([[`datetime`,`now()`],[`date`,`CURRENT_DATE`],[`time`,`LOCALTIME`]]);function defaultExpression(e,t){let r=e.default,i=n.get(e.type);if(r===`now`&&i!==void 0)return i;if(e.array){if(!Array.isArray(r))throw Error(`Default of array field ${t} must be an array.`);let n=columnType(e);return r.length===0?`'{}'::${n}`:`ARRAY[${r.map(n=>scalarLiteral(n,e,t)).join(`, `)}]::${n}`}return scalarLiteral(r,e,t)}function parseSerialFormat(e,t){let n=/^(?<prefix>[^%]*)%(?<zero>0?)(?<width>\d*)(?<conversion>[a-zA-Z])(?<suffix>[^%]*)$/.exec(e)?.groups,r=n?.conversion;if(!n||r!==`d`&&r!==`x`&&r!==`X`)throw Error(`Serial format "${e}" of field ${t} is not supported; use a single %d, %x, or %X specifier with an optional width (e.g. "INV-%05d").`);return{prefix:n.prefix??``,zeroPad:n.zero===`0`,width:n.width?Number(n.width):0,conversion:r,suffix:n.suffix??``}}function sequenceName(e,t){return derivedIdentifier(e,t,`seq`)}function sequenceRange(e){let t=[`START WITH ${e.start}`,`MINVALUE ${e.start}`];return e.maxValue!==void 0&&t.push(`MAXVALUE ${e.maxValue}`),t.join(` `)}const r={d:e=>e,x:e=>`to_hex(${e})`,X:e=>`upper(to_hex(${e}))`};function serialStringDefault(e,t,n){let i=`nextval(${stringLiteral(e)})`;if(t===void 0)return`(${i}::text)`;let{prefix:a,width:o,zeroPad:s,conversion:c,suffix:l}=parseSerialFormat(t,n),u=r[c](i),d=c===`d`?`${u}::text`:u;return o>0&&(d=`format('%${o}s', ${u})`,s&&(d=`translate(${d}, ' ', '0')`)),`(${[...a?[stringLiteral(a)]:[],d,...l?[stringLiteral(l)]:[]].join(` || `)})`}function columnDefinition(e,t,n){let r=identifier(t),i=`${identifier(e)}.${r}`,a=[r,columnType(n)];if(n.serial)return n.type===`integer`?(a.push(`GENERATED BY DEFAULT AS IDENTITY (${sequenceRange(n.serial)})`),n.unique&&a.push(`UNIQUE`),a.join(` `)):(n.required&&a.push(`NOT NULL`),n.unique&&a.push(`UNIQUE`),a.push(`DEFAULT ${serialStringDefault(sequenceName(e,t),n.serial.format,i)}`),a.join(` `));let o=n.default!==void 0,s=n.hooks?.create!==void 0||n.optionalOnCreate===!0;return n.required&&(o||!s)&&a.push(`NOT NULL`),n.unique&&a.push(`UNIQUE`),o&&a.push(`DEFAULT ${defaultExpression(n,i)}`),a.join(` `)}function generateTableDDL(e){let t=identifier(e.name),n=[],r=[],i=[` "id" uuid PRIMARY KEY DEFAULT gen_random_uuid()`];for(let[a,o]of Object.entries(e.fields))if(a!==`id`){if(o.serial&&o.type!==`integer`){let i=sequenceName(e.name,a);n.push(`CREATE SEQUENCE IF NOT EXISTS ${i} ${sequenceRange(o.serial)}`),r.push(`ALTER SEQUENCE ${i} OWNED BY ${t}.${identifier(a)}`)}i.push(` ${columnDefinition(e.name,a,o)}`)}let a=Object.entries(e.indexes??{}).filter(([,e])=>e.unique).map(([n,r])=>`CREATE UNIQUE INDEX IF NOT EXISTS ${derivedIdentifier(e.name,n,`idx`)} ON ${t} (${r.fields.map(identifier).join(`, `)})`);return[...n,`CREATE TABLE IF NOT EXISTS ${t} (\n${i.join(`,
2
+ `)}\n)`,...r,...a]}function generateSchemaDDL(e){return e.map(e=>generateTableDDL(e).map(e=>`${e};`).join(`
3
+ `)).join(`
4
+
5
+ `)}function templateLiteral(e){return`\`${e.replaceAll(`\\`,`\\\\`).replaceAll("`","\\`").replaceAll("${","\\${").replaceAll(`\r`,`\\r`)}\``}function generatePgliteSchemaModule(e,t){let n=e.map(({namespace:e,tables:t})=>` ${JSON.stringify(e)}: ${templateLiteral(generateSchemaDDL(t))},`);return[`/**`,` * Auto-generated PGlite schema for TailorDB tables.`," * Create a namespace's tables in a test with `pglite.exec(pgliteSchema[namespace])`.",` *`,` * DO NOT EDIT - This file is auto-generated by ${t.generatedBy}.`,` */`,``,`export const pgliteSchema = {`,...n,`} as const;`,``].join(`
6
+ `)}export{e as n,mapFieldTypeToColumnType as r,generatePgliteSchemaModule as t};
7
+ //# sourceMappingURL=tailordb-ddl-DqInYupv.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"tailordb-ddl-Fgm2cNvT.mjs","names":[],"sources":["../src/utils/field-column-type.ts","../src/utils/tailordb-ddl.ts"],"sourcesContent":["/** The Kysely column type a TailorDB field maps to, before array/null modifiers. */\nexport type FieldColumnType = \"string\" | \"number\" | \"boolean\" | \"Timestamp\";\n\n/**\n * Map a scalar TailorDB field type to the column type generated code uses for it.\n *\n * `date` resolves to `Timestamp` because the function runtime hands back a\n * `Date` for a date column, same as for datetime.\n *\n * `enum` and `nested` carry their own shape, so each generator resolves them\n * before reaching here; passing either is a caller bug rather than a `string`\n * column.\n * @param fieldType - TailorDB scalar field type name\n * @returns The column type for the field, defaulting to `string`\n * @throws If given `enum` or `nested`\n */\nexport function mapFieldTypeToColumnType(fieldType: string): FieldColumnType {\n switch (fieldType) {\n case \"uuid\":\n case \"string\":\n case \"decimal\":\n return \"string\";\n case \"integer\":\n case \"float\":\n return \"number\";\n case \"date\":\n case \"datetime\":\n return \"Timestamp\";\n case \"bool\":\n case \"boolean\":\n return \"boolean\";\n case \"enum\":\n case \"nested\":\n throw new Error(\n `Field type \"${fieldType}\" has no scalar column type; resolve it before mapping.`,\n );\n default:\n return \"string\";\n }\n}\n\n/** The select and write types a `ColumnType`-shaped alias expands to. */\nexport type ColumnTypeAliasExpansion = {\n /** Type the alias reads back as. */\n readonly select: string;\n /** Type the alias accepts on insert and update. */\n readonly write: string;\n};\n\n/**\n * Column types whose alias expands to a `ColumnType`, mapped to that expansion.\n *\n * Kysely only unwraps a `ColumnType` at the top level of a table property, so an\n * array of one of these stays wrapped in `ArrayColumnType<...>` rather than taking\n * a `[]` suffix, which would nest the `ColumnType` out of Kysely's reach. Where a\n * generator has to spell out the slots itself, it reads the expansion from here\n * rather than inlining the alias, which would nest just the same.\n *\n * Both type generators track alias usage per alias to decide which declarations to\n * emit, so adding an entry here also means teaching them to report the new alias.\n */\nexport const COLUMN_TYPE_ALIASES: ReadonlyMap<string, ColumnTypeAliasExpansion> = new Map<\n FieldColumnType,\n ColumnTypeAliasExpansion\n>([[\"Timestamp\", { select: \"Date\", write: \"Date | string\" }]]);\n","/**\n * PostgreSQL DDL derived from TailorDB table definitions, for creating the\n * tables a PGlite-backed test needs. The columns match the flat shape the\n * Kysely type generators emit, not TailorDB's storage layout.\n */\n\n/** The field shape the DDL generator reads; parsed and snapshot field configs are both assignable. */\nexport interface DDLFieldConfig {\n type: string;\n required?: boolean;\n array?: boolean;\n unique?: boolean;\n serial?: { start: number; maxValue?: number; format?: string };\n scale?: number;\n default?: unknown;\n optionalOnCreate?: boolean;\n hooks?: { create?: unknown; update?: unknown };\n fields?: Record<string, DDLFieldConfig>;\n}\n\n/** A table to emit DDL for. */\nexport interface DDLTableConfig {\n name: string;\n fields: Record<string, DDLFieldConfig>;\n indexes?: Record<string, { fields: string[]; unique?: boolean }>;\n}\n\nconst MAX_IDENTIFIER_BYTES = 63;\n// The platform rounds decimals to their scale (6 unless configured); numeric\n// needs a precision to carry a scale, and the maximum leaves it unconstrained.\nconst DECIMAL_PRECISION = 1000;\nconst DEFAULT_DECIMAL_SCALE = 6;\nconst utf8 = new TextEncoder();\n\n/**\n * Map a TailorDB field type to the PostgreSQL column type PGlite tests use for it.\n * @param fieldType - TailorDB field type name\n * @returns The PostgreSQL type name\n * @throws If the type is not a TailorDB field type\n */\nexport function mapFieldTypeToPostgresType(fieldType: string): string {\n switch (fieldType) {\n case \"uuid\":\n return \"uuid\";\n case \"string\":\n case \"enum\":\n return \"text\";\n case \"boolean\":\n case \"bool\":\n return \"boolean\";\n case \"integer\":\n return \"integer\";\n case \"float\":\n return \"double precision\";\n case \"decimal\":\n return \"numeric\";\n case \"date\":\n return \"date\";\n case \"datetime\":\n return \"timestamptz\";\n case \"time\":\n return \"time\";\n case \"nested\":\n return \"jsonb\";\n default:\n throw new Error(`Field type \"${fieldType}\" has no PostgreSQL column type.`);\n }\n}\n\nfunction identifier(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction fnv1aHex(value: string): string {\n let hash = 0x811c9dc5;\n for (const byte of utf8.encode(value)) {\n hash = Math.imul(hash ^ byte, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n\nfunction derivedIdentifier(tableName: string, memberName: string, kind: \"seq\" | \"idx\"): string {\n const suffix = `_${fnv1aHex(JSON.stringify([tableName, memberName, kind]))}_${kind}`;\n let head = `${tableName}_${memberName}`;\n while (utf8.encode(head + suffix).length > MAX_IDENTIFIER_BYTES) head = head.slice(0, -1);\n return identifier(head + suffix);\n}\n\nfunction stringLiteral(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction columnType(field: DDLFieldConfig): string {\n const base =\n field.type === \"decimal\"\n ? `numeric(${DECIMAL_PRECISION}, ${field.scale ?? DEFAULT_DECIMAL_SCALE})`\n : mapFieldTypeToPostgresType(field.type);\n return field.array && field.type !== \"nested\" ? `${base}[]` : base;\n}\n\nfunction scalarLiteral(value: unknown, field: DDLFieldConfig, label: string): string {\n const pgType = mapFieldTypeToPostgresType(field.type);\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) {\n throw new Error(`Default of field ${label} is an invalid Date.`);\n }\n return `${stringLiteral(value.toISOString())}::${pgType}`;\n }\n switch (typeof value) {\n case \"string\":\n return pgType === \"text\" ? stringLiteral(value) : `${stringLiteral(value)}::${pgType}`;\n case \"number\":\n if (!Number.isFinite(value)) {\n throw new Error(`Default of field ${label} is not a finite number.`);\n }\n return String(value);\n case \"boolean\":\n return value ? \"TRUE\" : \"FALSE\";\n default:\n throw new Error(`Default of field ${label} cannot be rendered as a SQL literal.`);\n }\n}\n\nconst CURRENT_TIME_EXPRESSIONS = new Map([\n [\"datetime\", \"now()\"],\n [\"date\", \"CURRENT_DATE\"],\n [\"time\", \"LOCALTIME\"],\n]);\n\nfunction defaultExpression(field: DDLFieldConfig, label: string): string {\n const value = field.default;\n const currentTime = CURRENT_TIME_EXPRESSIONS.get(field.type);\n if (value === \"now\" && currentTime !== undefined) {\n return currentTime;\n }\n if (field.array) {\n if (!Array.isArray(value)) {\n throw new Error(`Default of array field ${label} must be an array.`);\n }\n const pgType = columnType(field);\n if (value.length === 0) return `'{}'::${pgType}`;\n return `ARRAY[${value.map((v) => scalarLiteral(v, field, label)).join(\", \")}]::${pgType}`;\n }\n return scalarLiteral(value, field, label);\n}\n\ninterface SerialFormat {\n prefix: string;\n width: number;\n zeroPad: boolean;\n conversion: \"d\" | \"x\" | \"X\";\n suffix: string;\n}\n\n// printf-style with exactly one conversion specifier; octal has no Postgres\n// formatting function to stand in for it.\nfunction parseSerialFormat(format: string, label: string): SerialFormat {\n const match =\n /^(?<prefix>[^%]*)%(?<zero>0?)(?<width>\\d*)(?<conversion>[a-zA-Z])(?<suffix>[^%]*)$/.exec(\n format,\n );\n const groups = match?.groups;\n const conversion = groups?.conversion;\n if (!groups || (conversion !== \"d\" && conversion !== \"x\" && conversion !== \"X\")) {\n throw new Error(\n `Serial format \"${format}\" of field ${label} is not supported; use a single %d, %x, or %X specifier with an optional width (e.g. \"INV-%05d\").`,\n );\n }\n return {\n prefix: groups.prefix ?? \"\",\n zeroPad: groups.zero === \"0\",\n width: groups.width ? Number(groups.width) : 0,\n conversion,\n suffix: groups.suffix ?? \"\",\n };\n}\n\nfunction sequenceName(tableName: string, fieldName: string): string {\n return derivedIdentifier(tableName, fieldName, \"seq\");\n}\n\n// A sequence's minimum defaults to 1, which rejects a start of 0.\nfunction sequenceRange(serial: NonNullable<DDLFieldConfig[\"serial\"]>): string {\n const range = [`START WITH ${serial.start}`, `MINVALUE ${serial.start}`];\n if (serial.maxValue !== undefined) range.push(`MAXVALUE ${serial.maxValue}`);\n return range.join(\" \");\n}\n\nconst SERIAL_CONVERSIONS: Record<SerialFormat[\"conversion\"], (nextval: string) => string> = {\n d: (nextval) => nextval,\n x: (nextval) => `to_hex(${nextval})`,\n X: (nextval) => `upper(to_hex(${nextval}))`,\n};\n\nfunction serialStringDefault(sequence: string, format: string | undefined, label: string): string {\n const nextval = `nextval(${stringLiteral(sequence)})`;\n if (format === undefined) return `(${nextval}::text)`;\n const { prefix, width, zeroPad, conversion, suffix } = parseSerialFormat(format, label);\n const number = SERIAL_CONVERSIONS[conversion](nextval);\n let value = conversion === \"d\" ? `${number}::text` : number;\n if (width > 0) {\n value = `format('%${width}s', ${number})`;\n if (zeroPad) value = `translate(${value}, ' ', '0')`;\n }\n const parts = [\n ...(prefix ? [stringLiteral(prefix)] : []),\n value,\n ...(suffix ? [stringLiteral(suffix)] : []),\n ];\n return `(${parts.join(\" || \")})`;\n}\n\nfunction columnDefinition(tableName: string, fieldName: string, field: DDLFieldConfig): string {\n const column = identifier(fieldName);\n const label = `${identifier(tableName)}.${column}`;\n const parts = [column, columnType(field)];\n\n if (field.serial) {\n if (field.type === \"integer\") {\n parts.push(`GENERATED BY DEFAULT AS IDENTITY (${sequenceRange(field.serial)})`);\n if (field.unique) parts.push(\"UNIQUE\");\n return parts.join(\" \");\n }\n if (field.required) parts.push(\"NOT NULL\");\n if (field.unique) parts.push(\"UNIQUE\");\n parts.push(\n `DEFAULT ${serialStringDefault(sequenceName(tableName, fieldName), field.serial.format, label)}`,\n );\n return parts.join(\" \");\n }\n\n const hasDefault = field.default !== undefined;\n const filledOnCreate = field.hooks?.create !== undefined || field.optionalOnCreate === true;\n if (field.required && (hasDefault || !filledOnCreate)) parts.push(\"NOT NULL\");\n if (field.unique) parts.push(\"UNIQUE\");\n if (hasDefault) parts.push(`DEFAULT ${defaultExpression(field, label)}`);\n return parts.join(\" \");\n}\n\n/**\n * DDL statements that create one table: any sequences its string serial\n * fields draw from, the table, the sequences' ownership of their columns,\n * then its unique indexes. Every statement is `IF NOT EXISTS` or otherwise\n * idempotent, so re-applying the script on a database that already has the\n * table is a no-op. Owning a sequence makes `DROP TABLE` drop it and\n * `TRUNCATE ... RESTART IDENTITY` reset it to the configured start. Index\n * names end in `_idx` so they cannot take the `<table>_<column>_key` name\n * Postgres gives a UNIQUE column, which `IF NOT EXISTS` would otherwise\n * silently skip.\n * @param table - Table name, fields, and indexes\n * @returns Statements in execution order, without trailing semicolons\n * @throws If a field type, default, or serial format cannot be expressed\n */\nexport function generateTableDDL(table: DDLTableConfig): string[] {\n const tableIdentifier = identifier(table.name);\n const sequences: string[] = [];\n const ownerships: string[] = [];\n const columns = [` \"id\" uuid PRIMARY KEY DEFAULT gen_random_uuid()`];\n\n for (const [fieldName, field] of Object.entries(table.fields)) {\n if (fieldName === \"id\") continue;\n if (field.serial && field.type !== \"integer\") {\n const sequence = sequenceName(table.name, fieldName);\n sequences.push(`CREATE SEQUENCE IF NOT EXISTS ${sequence} ${sequenceRange(field.serial)}`);\n ownerships.push(\n `ALTER SEQUENCE ${sequence} OWNED BY ${tableIdentifier}.${identifier(fieldName)}`,\n );\n }\n columns.push(` ${columnDefinition(table.name, fieldName, field)}`);\n }\n\n const indexes = Object.entries(table.indexes ?? {})\n .filter(([, index]) => index.unique)\n .map(\n ([name, index]) =>\n `CREATE UNIQUE INDEX IF NOT EXISTS ${derivedIdentifier(table.name, name, \"idx\")} ON ${tableIdentifier} (${index.fields.map(identifier).join(\", \")})`,\n );\n\n return [\n ...sequences,\n `CREATE TABLE IF NOT EXISTS ${tableIdentifier} (\\n${columns.join(\",\\n\")}\\n)`,\n ...ownerships,\n ...indexes,\n ];\n}\n\n/**\n * A single SQL script creating every given table, for `pglite.exec()`.\n * @param tables - Tables in the order to create them\n * @returns The script, empty when there are no tables\n */\nexport function generateSchemaDDL(tables: readonly DDLTableConfig[]): string {\n return tables\n .map((table) =>\n generateTableDDL(table)\n .map((statement) => `${statement};`)\n .join(\"\\n\"),\n )\n .join(\"\\n\\n\");\n}\n\n/** One namespace's tables, as the schema module groups them. */\nexport interface PgliteSchemaNamespace {\n namespace: string;\n tables: readonly DDLTableConfig[];\n}\n\n/** Options for {@link generatePgliteSchemaModule}. */\nexport interface PgliteSchemaModuleOptions {\n /** Named in the generated header as the producer users must not edit around. */\n generatedBy: string;\n}\n\n// A template literal keeps line feeds but folds a carriage return into one.\nfunction templateLiteral(value: string): string {\n const escaped = value\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll(\"`\", \"\\\\`\")\n .replaceAll(\"${\", \"\\\\${\")\n .replaceAll(\"\\r\", \"\\\\r\");\n return `\\`${escaped}\\``;\n}\n\n/**\n * Render the module that exports each namespace's `CREATE TABLE` script for\n * `pglite.exec()`.\n * @param namespaces - Namespaces with the tables to create\n * @param options - Header wording\n * @returns TypeScript source of the schema module\n */\nexport function generatePgliteSchemaModule(\n namespaces: readonly PgliteSchemaNamespace[],\n options: PgliteSchemaModuleOptions,\n): string {\n const entries = namespaces.map(\n ({ namespace, tables }) =>\n ` ${JSON.stringify(namespace)}: ${templateLiteral(generateSchemaDDL(tables))},`,\n );\n return [\n \"/**\",\n \" * Auto-generated PGlite schema for TailorDB tables.\",\n \" * Create a namespace's tables in a test with `pglite.exec(pgliteSchema[namespace])`.\",\n \" *\",\n ` * DO NOT EDIT - This file is auto-generated by ${options.generatedBy}.`,\n \" */\",\n \"\",\n \"export const pgliteSchema = {\",\n ...entries,\n \"} as const;\",\n \"\",\n ].join(\"\\n\");\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tailordb-ddl-DqInYupv.mjs","names":[],"sources":["../src/utils/field-column-type.ts","../src/utils/tailordb-ddl.ts"],"sourcesContent":["/** The Kysely column type a TailorDB field maps to, before array/null modifiers. */\nexport type FieldColumnType = \"string\" | \"number\" | \"boolean\" | \"Timestamp\";\n\n/**\n * Map a scalar TailorDB field type to the column type generated code uses for it.\n *\n * `date` resolves to `Timestamp` because the function runtime hands back a\n * `Date` for a date column, same as for datetime.\n *\n * `enum` and `nested` carry their own shape, so each generator resolves them\n * before reaching here; passing either is a caller bug rather than a `string`\n * column.\n * @param fieldType - TailorDB scalar field type name\n * @returns The column type for the field, defaulting to `string`\n * @throws If given `enum` or `nested`\n */\nexport function mapFieldTypeToColumnType(fieldType: string): FieldColumnType {\n switch (fieldType) {\n case \"uuid\":\n case \"string\":\n case \"decimal\":\n return \"string\";\n case \"integer\":\n case \"float\":\n return \"number\";\n case \"date\":\n case \"datetime\":\n return \"Timestamp\";\n case \"bool\":\n case \"boolean\":\n return \"boolean\";\n case \"enum\":\n case \"nested\":\n throw new Error(\n `Field type \"${fieldType}\" has no scalar column type; resolve it before mapping.`,\n );\n default:\n return \"string\";\n }\n}\n\n/** The select and write types a `ColumnType`-shaped alias expands to. */\nexport type ColumnTypeAliasExpansion = {\n /** Type the alias reads back as. */\n readonly select: string;\n /** Type the alias accepts on insert and update. */\n readonly write: string;\n};\n\n/**\n * Column types whose alias expands to a `ColumnType`, mapped to that expansion.\n *\n * Kysely only unwraps a `ColumnType` at the top level of a table property, so an\n * array of one of these stays wrapped in `ArrayColumnType<...>` rather than taking\n * a `[]` suffix, which would nest the `ColumnType` out of Kysely's reach. Where a\n * generator has to spell out the slots itself, it reads the expansion from here\n * rather than inlining the alias, which would nest just the same.\n *\n * Both type generators track alias usage per alias to decide which declarations to\n * emit, so adding an entry here also means teaching them to report the new alias.\n */\nexport const COLUMN_TYPE_ALIASES: ReadonlyMap<string, ColumnTypeAliasExpansion> = new Map<\n FieldColumnType,\n ColumnTypeAliasExpansion\n>([[\"Timestamp\", { select: \"Date\", write: \"Date | string\" }]]);\n","/**\n * PostgreSQL DDL derived from TailorDB table definitions, for creating the\n * tables a PGlite-backed test needs. The columns match the flat shape the\n * Kysely type generators emit, not TailorDB's storage layout.\n */\n\n/** The field shape the DDL generator reads; parsed and snapshot field configs are both assignable. */\nexport interface DDLFieldConfig {\n type: string;\n required?: boolean;\n array?: boolean;\n unique?: boolean;\n serial?: { start: number; maxValue?: number; format?: string };\n scale?: number;\n default?: unknown;\n optionalOnCreate?: boolean;\n hooks?: { create?: unknown; update?: unknown };\n fields?: Record<string, DDLFieldConfig>;\n}\n\n/** A table to emit DDL for. */\nexport interface DDLTableConfig {\n name: string;\n fields: Record<string, DDLFieldConfig>;\n indexes?: Record<string, { fields: string[]; unique?: boolean }>;\n}\n\nconst MAX_IDENTIFIER_BYTES = 63;\n// The platform rounds decimals to their scale (6 unless configured); numeric\n// needs a precision to carry a scale, and the maximum leaves it unconstrained.\nconst DECIMAL_PRECISION = 1000;\nconst DEFAULT_DECIMAL_SCALE = 6;\nconst utf8 = new TextEncoder();\n\n/**\n * Map a TailorDB field type to the PostgreSQL column type PGlite tests use for it.\n * @param fieldType - TailorDB field type name\n * @returns The PostgreSQL type name\n * @throws If the type is not a TailorDB field type\n */\nexport function mapFieldTypeToPostgresType(fieldType: string): string {\n switch (fieldType) {\n case \"uuid\":\n return \"uuid\";\n case \"string\":\n case \"enum\":\n return \"text\";\n case \"boolean\":\n case \"bool\":\n return \"boolean\";\n case \"integer\":\n return \"integer\";\n case \"float\":\n return \"double precision\";\n case \"decimal\":\n return \"numeric\";\n case \"date\":\n return \"date\";\n case \"datetime\":\n return \"timestamptz\";\n case \"time\":\n return \"time\";\n case \"nested\":\n return \"jsonb\";\n default:\n throw new Error(`Field type \"${fieldType}\" has no PostgreSQL column type.`);\n }\n}\n\nfunction identifier(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction fnv1aHex(value: string): string {\n let hash = 0x811c9dc5;\n for (const byte of utf8.encode(value)) {\n hash = Math.imul(hash ^ byte, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n\nfunction derivedIdentifier(tableName: string, memberName: string, kind: \"seq\" | \"idx\"): string {\n const suffix = `_${fnv1aHex(JSON.stringify([tableName, memberName, kind]))}_${kind}`;\n let head = `${tableName}_${memberName}`;\n while (utf8.encode(head + suffix).length > MAX_IDENTIFIER_BYTES) head = head.slice(0, -1);\n return identifier(head + suffix);\n}\n\nfunction stringLiteral(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction columnType(field: DDLFieldConfig): string {\n const base =\n field.type === \"decimal\"\n ? `numeric(${DECIMAL_PRECISION}, ${field.scale ?? DEFAULT_DECIMAL_SCALE})`\n : mapFieldTypeToPostgresType(field.type);\n return field.array && field.type !== \"nested\" ? `${base}[]` : base;\n}\n\nfunction scalarLiteral(value: unknown, field: DDLFieldConfig, label: string): string {\n const pgType = mapFieldTypeToPostgresType(field.type);\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) {\n throw new Error(`Default of field ${label} is an invalid Date.`);\n }\n return `${stringLiteral(value.toISOString())}::${pgType}`;\n }\n switch (typeof value) {\n case \"string\":\n return pgType === \"text\" ? stringLiteral(value) : `${stringLiteral(value)}::${pgType}`;\n case \"number\":\n if (!Number.isFinite(value)) {\n throw new Error(`Default of field ${label} is not a finite number.`);\n }\n return String(value);\n case \"boolean\":\n return value ? \"TRUE\" : \"FALSE\";\n default:\n throw new Error(`Default of field ${label} cannot be rendered as a SQL literal.`);\n }\n}\n\nconst CURRENT_TIME_EXPRESSIONS = new Map([\n [\"datetime\", \"now()\"],\n [\"date\", \"CURRENT_DATE\"],\n [\"time\", \"LOCALTIME\"],\n]);\n\nfunction defaultExpression(field: DDLFieldConfig, label: string): string {\n const value = field.default;\n const currentTime = CURRENT_TIME_EXPRESSIONS.get(field.type);\n if (value === \"now\" && currentTime !== undefined) {\n return currentTime;\n }\n if (field.array) {\n if (!Array.isArray(value)) {\n throw new Error(`Default of array field ${label} must be an array.`);\n }\n const pgType = columnType(field);\n if (value.length === 0) return `'{}'::${pgType}`;\n return `ARRAY[${value.map((v) => scalarLiteral(v, field, label)).join(\", \")}]::${pgType}`;\n }\n return scalarLiteral(value, field, label);\n}\n\ninterface SerialFormat {\n prefix: string;\n width: number;\n zeroPad: boolean;\n conversion: \"d\" | \"x\" | \"X\";\n suffix: string;\n}\n\n// printf-style with exactly one conversion specifier; octal has no Postgres\n// formatting function to stand in for it.\nfunction parseSerialFormat(format: string, label: string): SerialFormat {\n const match =\n /^(?<prefix>[^%]*)%(?<zero>0?)(?<width>\\d*)(?<conversion>[a-zA-Z])(?<suffix>[^%]*)$/.exec(\n format,\n );\n const groups = match?.groups;\n const conversion = groups?.conversion;\n if (!groups || (conversion !== \"d\" && conversion !== \"x\" && conversion !== \"X\")) {\n throw new Error(\n `Serial format \"${format}\" of field ${label} is not supported; use a single %d, %x, or %X specifier with an optional width (e.g. \"INV-%05d\").`,\n );\n }\n return {\n prefix: groups.prefix ?? \"\",\n zeroPad: groups.zero === \"0\",\n width: groups.width ? Number(groups.width) : 0,\n conversion,\n suffix: groups.suffix ?? \"\",\n };\n}\n\nfunction sequenceName(tableName: string, fieldName: string): string {\n return derivedIdentifier(tableName, fieldName, \"seq\");\n}\n\n// A sequence's minimum defaults to 1, which rejects a start of 0.\nfunction sequenceRange(serial: NonNullable<DDLFieldConfig[\"serial\"]>): string {\n const range = [`START WITH ${serial.start}`, `MINVALUE ${serial.start}`];\n if (serial.maxValue !== undefined) range.push(`MAXVALUE ${serial.maxValue}`);\n return range.join(\" \");\n}\n\nconst SERIAL_CONVERSIONS: Record<SerialFormat[\"conversion\"], (nextval: string) => string> = {\n d: (nextval) => nextval,\n x: (nextval) => `to_hex(${nextval})`,\n X: (nextval) => `upper(to_hex(${nextval}))`,\n};\n\nfunction serialStringDefault(sequence: string, format: string | undefined, label: string): string {\n const nextval = `nextval(${stringLiteral(sequence)})`;\n if (format === undefined) return `(${nextval}::text)`;\n const { prefix, width, zeroPad, conversion, suffix } = parseSerialFormat(format, label);\n const number = SERIAL_CONVERSIONS[conversion](nextval);\n let value = conversion === \"d\" ? `${number}::text` : number;\n if (width > 0) {\n value = `format('%${width}s', ${number})`;\n if (zeroPad) value = `translate(${value}, ' ', '0')`;\n }\n const parts = [\n ...(prefix ? [stringLiteral(prefix)] : []),\n value,\n ...(suffix ? [stringLiteral(suffix)] : []),\n ];\n return `(${parts.join(\" || \")})`;\n}\n\nfunction columnDefinition(tableName: string, fieldName: string, field: DDLFieldConfig): string {\n const column = identifier(fieldName);\n const label = `${identifier(tableName)}.${column}`;\n const parts = [column, columnType(field)];\n\n if (field.serial) {\n if (field.type === \"integer\") {\n parts.push(`GENERATED BY DEFAULT AS IDENTITY (${sequenceRange(field.serial)})`);\n if (field.unique) parts.push(\"UNIQUE\");\n return parts.join(\" \");\n }\n if (field.required) parts.push(\"NOT NULL\");\n if (field.unique) parts.push(\"UNIQUE\");\n parts.push(\n `DEFAULT ${serialStringDefault(sequenceName(tableName, fieldName), field.serial.format, label)}`,\n );\n return parts.join(\" \");\n }\n\n const hasDefault = field.default !== undefined;\n const filledOnCreate = field.hooks?.create !== undefined || field.optionalOnCreate === true;\n if (field.required && (hasDefault || !filledOnCreate)) parts.push(\"NOT NULL\");\n if (field.unique) parts.push(\"UNIQUE\");\n if (hasDefault) parts.push(`DEFAULT ${defaultExpression(field, label)}`);\n return parts.join(\" \");\n}\n\n/**\n * DDL statements that create one table: any sequences its string serial\n * fields draw from, the table, the sequences' ownership of their columns,\n * then its unique indexes. Every statement is `IF NOT EXISTS` or otherwise\n * idempotent, so re-applying the script on a database that already has the\n * table is a no-op. Owning a sequence makes `DROP TABLE` drop it and\n * `TRUNCATE ... RESTART IDENTITY` reset it to the configured start. Index\n * names end in `_idx` so they cannot take the `<table>_<column>_key` name\n * Postgres gives a UNIQUE column, which `IF NOT EXISTS` would otherwise\n * silently skip.\n * @param table - Table name, fields, and indexes\n * @returns Statements in execution order, without trailing semicolons\n * @throws If a field type, default, or serial format cannot be expressed\n */\nexport function generateTableDDL(table: DDLTableConfig): string[] {\n const tableIdentifier = identifier(table.name);\n const sequences: string[] = [];\n const ownerships: string[] = [];\n const columns = [` \"id\" uuid PRIMARY KEY DEFAULT gen_random_uuid()`];\n\n for (const [fieldName, field] of Object.entries(table.fields)) {\n if (fieldName === \"id\") continue;\n if (field.serial && field.type !== \"integer\") {\n const sequence = sequenceName(table.name, fieldName);\n sequences.push(`CREATE SEQUENCE IF NOT EXISTS ${sequence} ${sequenceRange(field.serial)}`);\n ownerships.push(\n `ALTER SEQUENCE ${sequence} OWNED BY ${tableIdentifier}.${identifier(fieldName)}`,\n );\n }\n columns.push(` ${columnDefinition(table.name, fieldName, field)}`);\n }\n\n const indexes = Object.entries(table.indexes ?? {})\n .filter(([, index]) => index.unique)\n .map(\n ([name, index]) =>\n `CREATE UNIQUE INDEX IF NOT EXISTS ${derivedIdentifier(table.name, name, \"idx\")} ON ${tableIdentifier} (${index.fields.map(identifier).join(\", \")})`,\n );\n\n return [\n ...sequences,\n `CREATE TABLE IF NOT EXISTS ${tableIdentifier} (\\n${columns.join(\",\\n\")}\\n)`,\n ...ownerships,\n ...indexes,\n ];\n}\n\n/**\n * A single SQL script creating every given table, for `pglite.exec()`.\n * @param tables - Tables in the order to create them\n * @returns The script, empty when there are no tables\n */\nexport function generateSchemaDDL(tables: readonly DDLTableConfig[]): string {\n return tables\n .map((table) =>\n generateTableDDL(table)\n .map((statement) => `${statement};`)\n .join(\"\\n\"),\n )\n .join(\"\\n\\n\");\n}\n\n/** One namespace's tables, as the schema module groups them. */\nexport interface PgliteSchemaNamespace {\n namespace: string;\n tables: readonly DDLTableConfig[];\n}\n\n/** Options for {@link generatePgliteSchemaModule}. */\nexport interface PgliteSchemaModuleOptions {\n /** Named in the generated header as the producer users must not edit around. */\n generatedBy: string;\n}\n\n// A template literal keeps line feeds but folds a carriage return into one.\nfunction templateLiteral(value: string): string {\n const escaped = value\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll(\"`\", \"\\\\`\")\n .replaceAll(\"${\", \"\\\\${\")\n .replaceAll(\"\\r\", \"\\\\r\");\n return `\\`${escaped}\\``;\n}\n\n/**\n * Render the module that exports each namespace's `CREATE TABLE` script for\n * `pglite.exec()`.\n * @param namespaces - Namespaces with the tables to create\n * @param options - Header wording\n * @returns TypeScript source of the schema module\n */\nexport function generatePgliteSchemaModule(\n namespaces: readonly PgliteSchemaNamespace[],\n options: PgliteSchemaModuleOptions,\n): string {\n const entries = namespaces.map(\n ({ namespace, tables }) =>\n ` ${JSON.stringify(namespace)}: ${templateLiteral(generateSchemaDDL(tables))},`,\n );\n return [\n \"/**\",\n \" * Auto-generated PGlite schema for TailorDB tables.\",\n \" * Create a namespace's tables in a test with `pglite.exec(pgliteSchema[namespace])`.\",\n \" *\",\n ` * DO NOT EDIT - This file is auto-generated by ${options.generatedBy}.`,\n \" */\",\n \"\",\n \"export const pgliteSchema = {\",\n ...entries,\n \"} as const;\",\n \"\",\n ].join(\"\\n\");\n}\n"],"mappings":"AAgBA,SAAgB,yBAAyB,EAAoC,CAC3E,OAAQ,EAAR,CACE,IAAK,OACL,IAAK,SACL,IAAK,UACH,MAAO,SACT,IAAK,UACL,IAAK,QACH,MAAO,SACT,IAAK,OACL,IAAK,WACH,MAAO,YACT,IAAK,OACL,IAAK,UACH,MAAO,UACT,IAAK,OACL,IAAK,SACH,MAAU,MACR,eAAe,EAAU,wDAC3B,EACF,QACE,MAAO,QACX,CACF,CAsBA,MAAa,kBAAqE,IAAI,IAGpF,CAAC,CAAC,YAAa,CAAE,OAAQ,OAAQ,MAAO,eAAgB,CAAC,CAAC,CAAC,EChCvD,EAAO,IAAI,YAQjB,SAAgB,2BAA2B,EAA2B,CACpE,OAAQ,EAAR,CACE,IAAK,OACH,MAAO,OACT,IAAK,SACL,IAAK,OACH,MAAO,OACT,IAAK,UACL,IAAK,OACH,MAAO,UACT,IAAK,UACH,MAAO,UACT,IAAK,QACH,MAAO,mBACT,IAAK,UACH,MAAO,UACT,IAAK,OACH,MAAO,OACT,IAAK,WACH,MAAO,cACT,IAAK,OACH,MAAO,OACT,IAAK,SACH,MAAO,QACT,QACE,MAAU,MAAM,eAAe,EAAU,iCAAiC,CAC9E,CACF,CAEA,SAAS,WAAW,EAAsB,CACxC,MAAO,IAAI,EAAK,WAAW,IAAK,IAAI,EAAE,EACxC,CAEA,SAAS,SAAS,EAAuB,CACvC,IAAI,EAAO,WACX,IAAK,IAAM,KAAQ,EAAK,OAAO,CAAK,EAClC,EAAO,KAAK,KAAK,EAAO,EAAM,QAAU,IAAM,EAEhD,OAAO,EAAK,SAAS,EAAE,CAAC,CAAC,SAAS,EAAG,GAAG,CAC1C,CAEA,SAAS,kBAAkB,EAAmB,EAAoB,EAA6B,CAC7F,IAAM,EAAS,IAAI,SAAS,KAAK,UAAU,CAAC,EAAW,EAAY,CAAI,CAAC,CAAC,EAAE,GAAG,IAC1E,EAAO,GAAG,EAAU,GAAG,IAC3B,KAAO,EAAK,OAAO,EAAO,CAAM,CAAC,CAAC,OAAS,IAAsB,EAAO,EAAK,MAAM,EAAG,EAAE,EACxF,OAAO,WAAW,EAAO,CAAM,CACjC,CAEA,SAAS,cAAc,EAAuB,CAC5C,MAAO,IAAI,EAAM,WAAW,IAAK,IAAI,EAAE,EACzC,CAEA,SAAS,WAAW,EAA+B,CACjD,IAAM,EACJ,EAAM,OAAS,UACX,iBAAiC,EAAM,OAAS,EAAsB,GACtE,2BAA2B,EAAM,IAAI,EAC3C,OAAO,EAAM,OAAS,EAAM,OAAS,SAAW,GAAG,EAAK,IAAM,CAChE,CAEA,SAAS,cAAc,EAAgB,EAAuB,EAAuB,CACnF,IAAM,EAAS,2BAA2B,EAAM,IAAI,EACpD,GAAI,aAAiB,KAAM,CACzB,GAAI,OAAO,MAAM,EAAM,QAAQ,CAAC,EAC9B,MAAU,MAAM,oBAAoB,EAAM,qBAAqB,EAEjE,MAAO,GAAG,cAAc,EAAM,YAAY,CAAC,EAAE,IAAI,GACnD,CACA,OAAQ,OAAO,EAAf,CACE,IAAK,SACH,OAAO,IAAW,OAAS,cAAc,CAAK,EAAI,GAAG,cAAc,CAAK,EAAE,IAAI,IAChF,IAAK,SACH,GAAI,CAAC,OAAO,SAAS,CAAK,EACxB,MAAU,MAAM,oBAAoB,EAAM,yBAAyB,EAErE,OAAO,OAAO,CAAK,EACrB,IAAK,UACH,OAAO,EAAQ,OAAS,QAC1B,QACE,MAAU,MAAM,oBAAoB,EAAM,sCAAsC,CACpF,CACF,CAEA,MAAM,kBAA2B,IAAI,IAAI,CACvC,CAAC,WAAY,OAAO,EACpB,CAAC,OAAQ,cAAc,EACvB,CAAC,OAAQ,WAAW,CACtB,CAAC,EAED,SAAS,kBAAkB,EAAuB,EAAuB,CACvE,IAAM,EAAQ,EAAM,QACd,EAAc,EAAyB,IAAI,EAAM,IAAI,EAC3D,GAAI,IAAU,OAAS,IAAgB,IAAA,GACrC,OAAO,EAET,GAAI,EAAM,MAAO,CACf,GAAI,CAAC,MAAM,QAAQ,CAAK,EACtB,MAAU,MAAM,0BAA0B,EAAM,mBAAmB,EAErE,IAAM,EAAS,WAAW,CAAK,EAE/B,OADI,EAAM,SAAW,EAAU,SAAS,IACjC,SAAS,EAAM,IAAK,GAAM,cAAc,EAAG,EAAO,CAAK,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,KAAK,GACnF,CACA,OAAO,cAAc,EAAO,EAAO,CAAK,CAC1C,CAYA,SAAS,kBAAkB,EAAgB,EAA6B,CAKtE,IAAM,EAHJ,qFAAqF,KACnF,CAEe,CAAC,EAAE,OAChB,EAAa,GAAQ,WAC3B,GAAI,CAAC,GAAW,IAAe,KAAO,IAAe,KAAO,IAAe,IACzE,MAAU,MACR,kBAAkB,EAAO,aAAa,EAAM,kGAC9C,EAEF,MAAO,CACL,OAAQ,EAAO,QAAU,GACzB,QAAS,EAAO,OAAS,IACzB,MAAO,EAAO,MAAQ,OAAO,EAAO,KAAK,EAAI,EAC7C,aACA,OAAQ,EAAO,QAAU,EAC3B,CACF,CAEA,SAAS,aAAa,EAAmB,EAA2B,CAClE,OAAO,kBAAkB,EAAW,EAAW,KAAK,CACtD,CAGA,SAAS,cAAc,EAAuD,CAC5E,IAAM,EAAQ,CAAC,cAAc,EAAO,QAAS,YAAY,EAAO,OAAO,EAEvE,OADI,EAAO,WAAa,IAAA,IAAW,EAAM,KAAK,YAAY,EAAO,UAAU,EACpE,EAAM,KAAK,GAAG,CACvB,CAEA,MAAM,EAAsF,CAC1F,EAAI,GAAY,EAChB,EAAI,GAAY,UAAU,EAAQ,GAClC,EAAI,GAAY,gBAAgB,EAAQ,GAC1C,EAEA,SAAS,oBAAoB,EAAkB,EAA4B,EAAuB,CAChG,IAAM,EAAU,WAAW,cAAc,CAAQ,EAAE,GACnD,GAAI,IAAW,IAAA,GAAW,MAAO,IAAI,EAAQ,SAC7C,GAAM,CAAE,SAAQ,QAAO,UAAS,aAAY,UAAW,kBAAkB,EAAQ,CAAK,EAChF,EAAS,EAAmB,EAAW,CAAC,CAAO,EACjD,EAAQ,IAAe,IAAM,GAAG,EAAO,QAAU,EAUrD,OATI,EAAQ,IACV,EAAQ,YAAY,EAAM,MAAM,EAAO,GACnC,IAAS,EAAQ,aAAa,EAAM,eAOnC,IAAI,CAJT,GAAI,EAAS,CAAC,cAAc,CAAM,CAAC,EAAI,CAAC,EACxC,EACA,GAAI,EAAS,CAAC,cAAc,CAAM,CAAC,EAAI,CAAC,CAE3B,CAAC,CAAC,KAAK,MAAM,EAAE,EAChC,CAEA,SAAS,iBAAiB,EAAmB,EAAmB,EAA+B,CAC7F,IAAM,EAAS,WAAW,CAAS,EAC7B,EAAQ,GAAG,WAAW,CAAS,EAAE,GAAG,IACpC,EAAQ,CAAC,EAAQ,WAAW,CAAK,CAAC,EAExC,GAAI,EAAM,OAWR,OAVI,EAAM,OAAS,WACjB,EAAM,KAAK,qCAAqC,cAAc,EAAM,MAAM,EAAE,EAAE,EAC1E,EAAM,QAAQ,EAAM,KAAK,QAAQ,EAC9B,EAAM,KAAK,GAAG,IAEnB,EAAM,UAAU,EAAM,KAAK,UAAU,EACrC,EAAM,QAAQ,EAAM,KAAK,QAAQ,EACrC,EAAM,KACJ,WAAW,oBAAoB,aAAa,EAAW,CAAS,EAAG,EAAM,OAAO,OAAQ,CAAK,GAC/F,EACO,EAAM,KAAK,GAAG,GAGvB,IAAM,EAAa,EAAM,UAAY,IAAA,GAC/B,EAAiB,EAAM,OAAO,SAAW,IAAA,IAAa,EAAM,mBAAqB,GAIvF,OAHI,EAAM,WAAa,GAAc,CAAC,IAAiB,EAAM,KAAK,UAAU,EACxE,EAAM,QAAQ,EAAM,KAAK,QAAQ,EACjC,GAAY,EAAM,KAAK,WAAW,kBAAkB,EAAO,CAAK,GAAG,EAChE,EAAM,KAAK,GAAG,CACvB,CAgBA,SAAgB,iBAAiB,EAAiC,CAChE,IAAM,EAAkB,WAAW,EAAM,IAAI,EACvC,EAAsB,CAAC,EACvB,EAAuB,CAAC,EACxB,EAAU,CAAC,mDAAmD,EAEpE,IAAK,GAAM,CAAC,EAAW,KAAU,OAAO,QAAQ,EAAM,MAAM,EACtD,OAAc,KAClB,IAAI,EAAM,QAAU,EAAM,OAAS,UAAW,CAC5C,IAAM,EAAW,aAAa,EAAM,KAAM,CAAS,EACnD,EAAU,KAAK,iCAAiC,EAAS,GAAG,cAAc,EAAM,MAAM,GAAG,EACzF,EAAW,KACT,kBAAkB,EAAS,YAAY,EAAgB,GAAG,WAAW,CAAS,GAChF,CACF,CACA,EAAQ,KAAK,KAAK,iBAAiB,EAAM,KAAM,EAAW,CAAK,GAAG,CADlE,CAIF,IAAM,EAAU,OAAO,QAAQ,EAAM,SAAW,CAAC,CAAC,CAAC,CAChD,QAAQ,EAAG,KAAW,EAAM,MAAM,CAAC,CACnC,KACE,CAAC,EAAM,KACN,qCAAqC,kBAAkB,EAAM,KAAM,EAAM,KAAK,EAAE,MAAM,EAAgB,IAAI,EAAM,OAAO,IAAI,UAAU,CAAC,CAAC,KAAK,IAAI,EAAE,EACtJ,EAEF,MAAO,CACL,GAAG,EACH,8BAA8B,EAAgB,MAAM,EAAQ,KAAK;CAAK,EAAE,KACxE,GAAG,EACH,GAAG,CACL,CACF,CAOA,SAAgB,kBAAkB,EAA2C,CAC3E,OAAO,EACJ,IAAK,GACJ,iBAAiB,CAAK,CAAC,CACpB,IAAK,GAAc,GAAG,EAAU,EAAE,CAAC,CACnC,KAAK;CAAI,CACd,CAAC,CACA,KAAK;;CAAM,CAChB,CAeA,SAAS,gBAAgB,EAAuB,CAM9C,MAAO,KALS,EACb,WAAW,KAAM,MAAM,CAAC,CACxB,WAAW,IAAK,KAAK,CAAC,CACtB,WAAW,KAAM,MAAM,CAAC,CACxB,WAAW,KAAM,KACF,EAAE,GACtB,CASA,SAAgB,2BACd,EACA,EACQ,CACR,IAAM,EAAU,EAAW,KACxB,CAAE,YAAW,YACZ,KAAK,KAAK,UAAU,CAAS,EAAE,IAAI,gBAAgB,kBAAkB,CAAM,CAAC,EAAE,EAClF,EACA,MAAO,CACL,MACA,uDACA,wFACA,KACA,mDAAmD,EAAQ,YAAY,GACvE,MACA,GACA,gCACA,GAAG,EACH,cACA,EACF,CAAC,CAAC,KAAK;CAAI,CACb"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"../../field-parse-BbNyotv5.mjs";function setField(e,t,n){Object.defineProperty(e,t,{value:n,enumerable:!0,writable:!0,configurable:!0})}function createTailorDBHook(t){return(n,r=new Date)=>{let i=n&&typeof n==`object`?n:void 0,a=Object.entries(t.fields).reduce((t,[n,a])=>{let o=a,s=i&&Object.hasOwn(i,n)?i[n]:void 0,c;if(n===`id`)c=s??crypto.randomUUID();else if(o.type===`nested`){let t=createTailorDBHook({fields:o.fields});c=o.metadata.array?Array.isArray(s)?s.map(n=>e(n)?t(n,r):n):s:e(s)?t(s,r):s}else o.metadata.hooks?.create?(c=o.metadata.hooks.create({input:s,invoker:null,now:r}),c instanceof Date&&(c=c.toISOString())):c=s;if(c==null&&o.metadata.default!==void 0){let e=o.type===`datetime`||o.type===`date`||o.type===`time`;c=o.metadata.default===`now`&&e?r.toISOString():o.metadata.default}return setField(t,n,c),t},{});if(t.metadata?.typeHook?.create){let{id:e,...n}=a,i=t.metadata.typeHook.create({input:n,invoker:null,now:r});if(i&&typeof i==`object`)for(let[e,t]of Object.entries(i))setField(a,e,t instanceof Date?t.toISOString():t)}return a}}function typeLevelIssues(e,t){let n=e?.metadata?.typeValidate;if(!n)return[];let{id:r,...i}=t,a=[];return n({newRecord:i,oldRecord:null,invoker:null},(e,t)=>{a.push({message:t,path:[e]})}),a}function undeclaredFieldMessage(e){return`Field "${e}" is not declared by the table. Remove it from the row, or add it to the table definition and run \`tailor generate\`.`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function collectUndeclaredFieldIssues(e,t,n,r){if(isRecord(e))for(let i of Object.keys(e)){if(!Object.hasOwn(t,i)){r.push({message:undeclaredFieldMessage(i),path:n.concat(i)});continue}let a=t[i];if(a?.type!==`nested`)continue;let o=e[i],s=a.fields;a.metadata.array?Array.isArray(o)&&o.forEach((e,t)=>{collectUndeclaredFieldIssues(e,s,n.concat(i,`[${t}]`),r)}):collectUndeclaredFieldIssues(o,s,n.concat(i),r)}}function createStandardSchema(e,t,n){let validateHooked=t=>{let r=typeLevelIssues(n,t);if(r.length>0)return{issues:r};let i=e.parse({value:t,data:t,invoker:null});return i.issues?i:{value:t}};return{"~standard":{version:1,vendor:`@tailor-platform/sdk`,validate:e=>{let r=t(e),i=[];n&&collectUndeclaredFieldIssues(e,n.fields,[],i);let a=validateHooked(r),o=[...i,...a.issues??[]];return o.length>0?{issues:o}:a}}}}export{createStandardSchema,createTailorDBHook};
1
+ import{t as e}from"../../field-parse-DhnFs9WG.mjs";function setField(e,t,n){Object.defineProperty(e,t,{value:n,enumerable:!0,writable:!0,configurable:!0})}function createTailorDBHook(t){return(n,r=/* @__PURE__ */ new Date)=>{let i=n&&typeof n==`object`?n:void 0,a=Object.entries(t.fields).reduce((t,[n,a])=>{let o=a,s=i&&Object.hasOwn(i,n)?i[n]:void 0,c;if(n===`id`)c=s??crypto.randomUUID();else if(o.type===`nested`){let t=createTailorDBHook({fields:o.fields});c=o.metadata.array?Array.isArray(s)?s.map(n=>e(n)?t(n,r):n):s:e(s)?t(s,r):s}else o.metadata.hooks?.create?(c=o.metadata.hooks.create({input:s,invoker:null,now:r}),c instanceof Date&&(c=c.toISOString())):c=s;if(c==null&&o.metadata.default!==void 0){let e=o.type===`datetime`||o.type===`date`||o.type===`time`;c=o.metadata.default===`now`&&e?r.toISOString():o.metadata.default}return setField(t,n,c),t},{});if(t.metadata?.typeHook?.create){let{id:e,...n}=a,i=t.metadata.typeHook.create({input:n,invoker:null,now:r});if(i&&typeof i==`object`)for(let[e,t]of Object.entries(i))setField(a,e,t instanceof Date?t.toISOString():t)}return a}}function typeLevelIssues(e,t){let n=e?.metadata?.typeValidate;if(!n)return[];let{id:r,...i}=t,a=[];return n({newRecord:i,oldRecord:null,invoker:null},(e,t)=>{a.push({message:t,path:[e]})}),a}function undeclaredFieldMessage(e){return`Field "${e}" is not declared by the table. Remove it from the row, or add it to the table definition and run \`tailor generate\`.`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function collectUndeclaredFieldIssues(e,t,n,r){if(isRecord(e))for(let i of Object.keys(e)){if(!Object.hasOwn(t,i)){r.push({message:undeclaredFieldMessage(i),path:n.concat(i)});continue}let a=t[i];if(a?.type!==`nested`)continue;let o=e[i],s=a.fields;a.metadata.array?Array.isArray(o)&&o.forEach((e,t)=>{collectUndeclaredFieldIssues(e,s,n.concat(i,`[${t}]`),r)}):collectUndeclaredFieldIssues(o,s,n.concat(i),r)}}function createStandardSchema(e,t,n){let validateHooked=t=>{let r=typeLevelIssues(n,t);if(r.length>0)return{issues:r};let i=e.parse({value:t,data:t,invoker:null});return i.issues?i:{value:t}};return{"~standard":{version:1,vendor:`@tailor-platform/sdk`,validate:e=>{let r=t(e),i=[];n&&collectUndeclaredFieldIssues(e,n.fields,[],i);let a=validateHooked(r),o=[...i,...a.issues??[]];return o.length>0?{issues:o}:a}}}}export{createStandardSchema,createTailorDBHook};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/utils/test/index.ts"],"sourcesContent":["import { isNestedObject } from \"#/runtime/field-parse\";\nimport type { output } from \"#/configure/index\";\nimport type { TailorDBType } from \"#/configure/services/tailordb/schema\";\nimport type { TailorField } from \"#/configure/types/type\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n// Not `record[key] = value`: assigning to `__proto__` goes through the inherited\n// setter, which mutates the prototype instead of recording the field and leaves\n// no own property behind for the value to be read from.\nfunction setField(record: Record<string, unknown>, key: string, value: unknown): void {\n Object.defineProperty(record, key, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n}\n\n/**\n * Creates a hook function that processes TailorDB table 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 * - Takes each field from the data's own properties, so a field named after a\n * member of `Object` such as `toString` is read from the record rather than\n * from the prototype\n * @template T - The output type of the hook function\n * @param type - TailorDB table 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, now: Date = new Date()) => {\n const obj = data && typeof data === \"object\" ? (data as Record<string, unknown>) : undefined;\n const hooked = 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 // `Object.hasOwn`, not `obj?.[key]`: a field named after an Object member\n // such as `toString` would otherwise read the inherited value.\n const input = obj && Object.hasOwn(obj, key) ? obj[key] : undefined;\n let hookedValue: unknown;\n if (key === \"id\") {\n hookedValue = input ?? crypto.randomUUID();\n } else if (field.type === \"nested\") {\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 hookedValue = Array.isArray(input)\n ? input.map((item) => (isNestedObject(item) ? nestedHook(item, now) : item))\n : input;\n } else {\n hookedValue = isNestedObject(input) ? nestedHook(input, now) : input;\n }\n } else if (field.metadata.hooks?.create) {\n hookedValue = field.metadata.hooks.create({ input, invoker: null, now });\n if (hookedValue instanceof Date) {\n hookedValue = hookedValue.toISOString();\n }\n } else {\n hookedValue = input;\n }\n if (hookedValue == null && field.metadata.default !== undefined) {\n const isTimeType =\n field.type === \"datetime\" || field.type === \"date\" || field.type === \"time\";\n hookedValue =\n field.metadata.default === \"now\" && isTimeType\n ? now.toISOString()\n : field.metadata.default;\n }\n // Set even when there is no value: the key carrying `undefined` is what\n // tells a schema inferred from the record that the column is nullable,\n // and it shadows a same-named member of `Object.prototype`.\n setField(hooked, key, hookedValue);\n return hooked;\n },\n {} as Record<string, unknown>,\n );\n\n // oxlint-disable-next-line typescript/no-unnecessary-condition -- metadata absent in recursive nested calls\n if (type.metadata?.typeHook?.create) {\n const { id: _id, ...typeHookInput } = hooked;\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n const overrides = type.metadata.typeHook.create({\n input: typeHookInput,\n invoker: null,\n now,\n });\n if (overrides && typeof overrides === \"object\") {\n for (const [key, value] of Object.entries(overrides as Record<string, unknown>)) {\n setField(hooked, key, value instanceof Date ? value.toISOString() : value);\n }\n }\n }\n\n return hooked as Partial<output<T>>;\n };\n}\n\n// Collect the issues the table's own `validate` reports for a record, so they\n// surface the same way a field's do instead of ending the run.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction typeLevelIssues(type: TailorDBType<any, any> | undefined, hooked: unknown) {\n // oxlint-disable-next-line typescript/no-unnecessary-condition -- absent on a nested type\n const typeValidate = type?.metadata?.typeValidate;\n if (!typeValidate) {\n return [];\n }\n const { id: _id, ...newRecord } = hooked as Record<string, unknown>;\n const issues: StandardSchemaV1.Issue[] = [];\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n typeValidate({ newRecord, oldRecord: null, invoker: null }, (field: string, message: string) => {\n issues.push({ message, path: [field] });\n });\n return issues;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype DeclaredFields = Record<string, TailorField<any, any, any>>;\n\nfunction undeclaredFieldMessage(key: string): string {\n return `Field \"${key}\" is not declared by the table. Remove it from the row, or add it to the table definition and run \\`tailor generate\\`.`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n// Reads the raw row, not the hooked one: the hook only copies the declared fields,\n// so an undeclared key is gone by the time the field schema runs.\nfunction collectUndeclaredFieldIssues(\n value: unknown,\n fields: DeclaredFields,\n path: string[],\n issues: StandardSchemaV1.Issue[],\n): void {\n if (!isRecord(value)) {\n return;\n }\n for (const key of Object.keys(value)) {\n // `Object.hasOwn`, not `key in fields`: a key such as `constructor` would\n // otherwise resolve to a member of `Object.prototype`.\n if (!Object.hasOwn(fields, key)) {\n issues.push({ message: undeclaredFieldMessage(key), path: path.concat(key) });\n continue;\n }\n const field = fields[key];\n if (field?.type !== \"nested\") {\n continue;\n }\n const nested = value[key];\n const nestedFields = field.fields as DeclaredFields;\n if (field.metadata.array) {\n if (Array.isArray(nested)) {\n nested.forEach((item, index) => {\n collectUndeclaredFieldIssues(item, nestedFields, path.concat(key, `[${index}]`), issues);\n });\n }\n } else {\n collectUndeclaredFieldIssues(nested, nestedFields, path.concat(key), issues);\n }\n }\n}\n\n/**\n * Creates the standard schema definition used to validate seed rows.\n * Runs the hook, then the table's own `validate`, and the field schema only when\n * that reported nothing, so both levels of validation report as issues rather\n * than by throwing. When the table is given, a key the row carries that the table\n * does not declare is reported as an issue as well, including keys inside nested\n * objects, so a row that no longer matches the table fails here instead of when\n * it is applied.\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 * @param type - TailorDB table definition; runs its table-level `validate` and\n * rejects fields it does not declare\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n type?: TailorDBType<any, any>,\n) {\n const validateHooked = (hooked: Partial<T>): StandardSchemaV1.Result<T> => {\n const issues = typeLevelIssues(type, hooked);\n if (issues.length > 0) {\n return { issues };\n }\n const result = schemaType.parse({\n value: hooked,\n data: hooked,\n invoker: null,\n });\n if (result.issues) {\n return result;\n }\n return { value: hooked as T };\n };\n\n return {\n \"~standard\": {\n version: 1,\n vendor: \"@tailor-platform/sdk\",\n validate: (value: unknown) => {\n const hooked = hook(value);\n const undeclared: StandardSchemaV1.Issue[] = [];\n if (type) {\n collectUndeclaredFieldIssues(value, type.fields as DeclaredFields, [], undeclared);\n }\n const result = validateHooked(hooked);\n const issues = [...undeclared, ...(result.issues ?? [])];\n return issues.length > 0 ? { issues } : result;\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/index.ts"],"sourcesContent":["import { isNestedObject } from \"#/runtime/field-parse\";\nimport type { output } from \"#/configure/index\";\nimport type { TailorDBType } from \"#/configure/services/tailordb/schema\";\nimport type { TailorField } from \"#/configure/types/type\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n// Not `record[key] = value`: assigning to `__proto__` goes through the inherited\n// setter, which mutates the prototype instead of recording the field and leaves\n// no own property behind for the value to be read from.\nfunction setField(record: Record<string, unknown>, key: string, value: unknown): void {\n Object.defineProperty(record, key, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n}\n\n/**\n * Creates a hook function that processes TailorDB table 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 * - Takes each field from the data's own properties, so a field named after a\n * member of `Object` such as `toString` is read from the record rather than\n * from the prototype\n * @template T - The output type of the hook function\n * @param type - TailorDB table 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, now: Date = new Date()) => {\n const obj = data && typeof data === \"object\" ? (data as Record<string, unknown>) : undefined;\n const hooked = 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 // `Object.hasOwn`, not `obj?.[key]`: a field named after an Object member\n // such as `toString` would otherwise read the inherited value.\n const input = obj && Object.hasOwn(obj, key) ? obj[key] : undefined;\n let hookedValue: unknown;\n if (key === \"id\") {\n hookedValue = input ?? crypto.randomUUID();\n } else if (field.type === \"nested\") {\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 hookedValue = Array.isArray(input)\n ? input.map((item) => (isNestedObject(item) ? nestedHook(item, now) : item))\n : input;\n } else {\n hookedValue = isNestedObject(input) ? nestedHook(input, now) : input;\n }\n } else if (field.metadata.hooks?.create) {\n hookedValue = field.metadata.hooks.create({ input, invoker: null, now });\n if (hookedValue instanceof Date) {\n hookedValue = hookedValue.toISOString();\n }\n } else {\n hookedValue = input;\n }\n if (hookedValue == null && field.metadata.default !== undefined) {\n const isTimeType =\n field.type === \"datetime\" || field.type === \"date\" || field.type === \"time\";\n hookedValue =\n field.metadata.default === \"now\" && isTimeType\n ? now.toISOString()\n : field.metadata.default;\n }\n // Set even when there is no value: the key carrying `undefined` is what\n // tells a schema inferred from the record that the column is nullable,\n // and it shadows a same-named member of `Object.prototype`.\n setField(hooked, key, hookedValue);\n return hooked;\n },\n {} as Record<string, unknown>,\n );\n\n // oxlint-disable-next-line typescript/no-unnecessary-condition -- metadata absent in recursive nested calls\n if (type.metadata?.typeHook?.create) {\n const { id: _id, ...typeHookInput } = hooked;\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n const overrides = type.metadata.typeHook.create({\n input: typeHookInput,\n invoker: null,\n now,\n });\n if (overrides && typeof overrides === \"object\") {\n for (const [key, value] of Object.entries(overrides as Record<string, unknown>)) {\n setField(hooked, key, value instanceof Date ? value.toISOString() : value);\n }\n }\n }\n\n return hooked as Partial<output<T>>;\n };\n}\n\n// Collect the issues the table's own `validate` reports for a record, so they\n// surface the same way a field's do instead of ending the run.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction typeLevelIssues(type: TailorDBType<any, any> | undefined, hooked: unknown) {\n // oxlint-disable-next-line typescript/no-unnecessary-condition -- absent on a nested type\n const typeValidate = type?.metadata?.typeValidate;\n if (!typeValidate) {\n return [];\n }\n const { id: _id, ...newRecord } = hooked as Record<string, unknown>;\n const issues: StandardSchemaV1.Issue[] = [];\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n typeValidate({ newRecord, oldRecord: null, invoker: null }, (field: string, message: string) => {\n issues.push({ message, path: [field] });\n });\n return issues;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype DeclaredFields = Record<string, TailorField<any, any, any>>;\n\nfunction undeclaredFieldMessage(key: string): string {\n return `Field \"${key}\" is not declared by the table. Remove it from the row, or add it to the table definition and run \\`tailor generate\\`.`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n// Reads the raw row, not the hooked one: the hook only copies the declared fields,\n// so an undeclared key is gone by the time the field schema runs.\nfunction collectUndeclaredFieldIssues(\n value: unknown,\n fields: DeclaredFields,\n path: string[],\n issues: StandardSchemaV1.Issue[],\n): void {\n if (!isRecord(value)) {\n return;\n }\n for (const key of Object.keys(value)) {\n // `Object.hasOwn`, not `key in fields`: a key such as `constructor` would\n // otherwise resolve to a member of `Object.prototype`.\n if (!Object.hasOwn(fields, key)) {\n issues.push({ message: undeclaredFieldMessage(key), path: path.concat(key) });\n continue;\n }\n const field = fields[key];\n if (field?.type !== \"nested\") {\n continue;\n }\n const nested = value[key];\n const nestedFields = field.fields as DeclaredFields;\n if (field.metadata.array) {\n if (Array.isArray(nested)) {\n nested.forEach((item, index) => {\n collectUndeclaredFieldIssues(item, nestedFields, path.concat(key, `[${index}]`), issues);\n });\n }\n } else {\n collectUndeclaredFieldIssues(nested, nestedFields, path.concat(key), issues);\n }\n }\n}\n\n/**\n * Creates the standard schema definition used to validate seed rows.\n * Runs the hook, then the table's own `validate`, and the field schema only when\n * that reported nothing, so both levels of validation report as issues rather\n * than by throwing. When the table is given, a key the row carries that the table\n * does not declare is reported as an issue as well, including keys inside nested\n * objects, so a row that no longer matches the table fails here instead of when\n * it is applied.\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 * @param type - TailorDB table definition; runs its table-level `validate` and\n * rejects fields it does not declare\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n type?: TailorDBType<any, any>,\n) {\n const validateHooked = (hooked: Partial<T>): StandardSchemaV1.Result<T> => {\n const issues = typeLevelIssues(type, hooked);\n if (issues.length > 0) {\n return { issues };\n }\n const result = schemaType.parse({\n value: hooked,\n data: hooked,\n invoker: null,\n });\n if (result.issues) {\n return result;\n }\n return { value: hooked as T };\n };\n\n return {\n \"~standard\": {\n version: 1,\n vendor: \"@tailor-platform/sdk\",\n validate: (value: unknown) => {\n const hooked = hook(value);\n const undeclared: StandardSchemaV1.Issue[] = [];\n if (type) {\n collectUndeclaredFieldIssues(value, type.fields as DeclaredFields, [], undeclared);\n }\n const result = validateHooked(hooked);\n const issues = [...undeclared, ...(result.issues ?? [])];\n return issues.length > 0 ? { issues } : result;\n },\n },\n } as const satisfies StandardSchemaV1<T>;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"../es-builtins-BHCXINQp.mjs";import{n as t,r as n,t as r}from"../globals-CMHSnj4w.mjs";const i=new Set([...e,r,`process`,`require`,`module`,`exports`,`__vitest_worker__`,`__vitest_mocker__`,`VITEST_POOL_ID`]);var a={name:`tailor-runtime`,viteEnvironment:`ssr`,async setup(e){let r=e,a=Object.getOwnPropertyDescriptor(r,`Temporal`),o=r.Temporal===void 0,s=o?(await import(`temporal-polyfill/full/implementation`)).Temporal:void 0,c={};for(let e of Object.getOwnPropertyNames(r))if(!i.has(e)){let t=Object.getOwnPropertyDescriptor(r,e);t?.configurable&&(c[e]=t,delete r[e])}return n(e),o&&Object.defineProperty(r,"Temporal",{value:s,writable:!0,configurable:!0}),{teardown(e){t(e),o&&(a?Object.defineProperty(e,"Temporal",a):Reflect.deleteProperty(e,`Temporal`));let n=e;for(let[e,t]of Object.entries(c))Object.defineProperty(n,e,t)}}}};export{a as default};
1
+ import{t as e}from"../es-builtins-SfvXRVoG.mjs";import{n as t,r as n,t as r}from"../globals-BCmGX05J.mjs";const i=/* @__PURE__ */ new Set([...e,r,`process`,`require`,`module`,`exports`,`__vitest_worker__`,`__vitest_mocker__`,`VITEST_POOL_ID`]);var a={name:`tailor-runtime`,viteEnvironment:`ssr`,async setup(e){let r=e,a=Object.getOwnPropertyDescriptor(r,`Temporal`),o=r.Temporal===void 0,s=o?(await import(`temporal-polyfill/full/implementation`)).Temporal:void 0,c={};for(let e of Object.getOwnPropertyNames(r))if(!i.has(e)){let t=Object.getOwnPropertyDescriptor(r,e);t?.configurable&&(c[e]=t,delete r[e])}return n(e),o&&Object.defineProperty(r,"Temporal",{value:s,writable:!0,configurable:!0}),{teardown(e){t(e),o&&(a?Object.defineProperty(e,"Temporal",a):Reflect.deleteProperty(e,`Temporal`));let n=e;for(let[e,t]of Object.entries(c))Object.defineProperty(n,e,t)}}}};export{a as default};
2
2
  //# sourceMappingURL=environment.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"environment.mjs","names":[],"sources":["../../src/vitest/environment.ts"],"sourcesContent":["import { ES_BUILTINS } from \"#/utils/es-builtins\";\n// Import from ./globals (NOT ./mock): this module runs in the Vitest environment\n// realm where `vi` is unavailable, and ./mock imports `vi`. ./globals is\n// dependency-free of vitest.\nimport { RUNTIME_FLAG_KEY, cleanupPlatformGlobals, installPlatformGlobals } from \"./globals\";\n\n// Globals allowed in the Tailor Platform runtime.\n// ES_BUILTINS is the free-variable allowlist the deploy-time check uses, so\n// the emulated runtime exposes exactly the same identifiers as the production\n// platform (ECMAScript builtins + shared Node/browser runtime globals like\n// console, fetch, setTimeout).\n// Platform API mocks (tailor, tailordb, etc.) are not listed here — the base\n// surface is injected by installPlatformGlobals() after the whitelist cleanup,\n// and per-namespace mocks are layered on at `using xMock()` acquisition time.\nconst ALLOWED_GLOBALS = new Set([\n ...ES_BUILTINS,\n\n // The environment-active flag (set in installPlatformGlobals, used by\n // setup.ts to detect the tailor-runtime environment).\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 const temporalDescriptor = Object.getOwnPropertyDescriptor(g, \"Temporal\");\n const needsTemporal = g.Temporal === undefined;\n const temporal = needsTemporal\n ? (await import(\"temporal-polyfill/full/implementation\")).Temporal\n : undefined;\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 // Install the base platform surface after whitelist cleanup. Per-namespace\n // mocks (workflow, tailordb, …) are installed on demand by `using xMock()`.\n installPlatformGlobals(global);\n if (needsTemporal) {\n Object.defineProperty(g, \"Temporal\", {\n value: temporal,\n writable: true,\n configurable: true,\n });\n }\n\n return {\n teardown(global: typeof globalThis) {\n cleanupPlatformGlobals(global);\n\n if (needsTemporal) {\n if (temporalDescriptor) {\n Object.defineProperty(global, \"Temporal\", temporalDescriptor);\n } else {\n Reflect.deleteProperty(global, \"Temporal\");\n }\n }\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":"0GAcA,MAAM,EAAkB,IAAI,IAAI,CAC9B,GAAG,EAIH,EAGA,UACA,UACA,SACA,UACA,oBACA,oBACA,gBACF,CAAC,EAED,IAAA,EAAe,CACb,KAAM,iBACN,gBAAiB,MAEjB,MAAM,MAAM,EAA2B,CACrC,IAAM,EAAI,EAEJ,EAAqB,OAAO,yBAAyB,EAAG,UAAU,EAClE,EAAgB,EAAE,WAAa,IAAA,GAC/B,EAAW,GACZ,MAAM,OAAO,yCAAA,CAA0C,SACxD,IAAA,GAGE,EAA4C,CAAC,EACnD,IAAK,IAAM,KAAO,OAAO,oBAAoB,CAAC,EAC5C,GAAI,CAAC,EAAgB,IAAI,CAAG,EAAG,CAC7B,IAAM,EAAa,OAAO,yBAAyB,EAAG,CAAG,EACrD,GAAY,eACd,EAAM,GAAO,EACb,OAAO,EAAE,GAEb,CAcF,OATA,EAAuB,CAAM,EACzB,GACF,OAAO,eAAe,EAAG,WAAY,CACnC,MAAO,EACP,SAAU,GACV,aAAc,EAChB,CAAC,EAGI,CACL,SAAS,EAA2B,CAClC,EAAuB,CAAM,EAEzB,IACE,EACF,OAAO,eAAe,EAAQ,WAAY,CAAkB,EAE5D,QAAQ,eAAe,EAAQ,UAAU,GAK7C,IAAM,EAAI,EACV,IAAK,GAAM,CAAC,EAAK,KAAe,OAAO,QAAQ,CAAK,EAClD,OAAO,eAAe,EAAG,EAAK,CAAU,CAE5C,CACF,CACF,CACF"}
1
+ {"version":3,"file":"environment.mjs","names":[],"sources":["../../src/vitest/environment.ts"],"sourcesContent":["import { ES_BUILTINS } from \"#/utils/es-builtins\";\n// Import from ./globals (NOT ./mock): this module runs in the Vitest environment\n// realm where `vi` is unavailable, and ./mock imports `vi`. ./globals is\n// dependency-free of vitest.\nimport { RUNTIME_FLAG_KEY, cleanupPlatformGlobals, installPlatformGlobals } from \"./globals\";\n\n// Globals allowed in the Tailor Platform runtime.\n// ES_BUILTINS is the free-variable allowlist the deploy-time check uses, so\n// the emulated runtime exposes exactly the same identifiers as the production\n// platform (ECMAScript builtins + shared Node/browser runtime globals like\n// console, fetch, setTimeout).\n// Platform API mocks (tailor, tailordb, etc.) are not listed here — the base\n// surface is injected by installPlatformGlobals() after the whitelist cleanup,\n// and per-namespace mocks are layered on at `using xMock()` acquisition time.\nconst ALLOWED_GLOBALS = new Set([\n ...ES_BUILTINS,\n\n // The environment-active flag (set in installPlatformGlobals, used by\n // setup.ts to detect the tailor-runtime environment).\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 const temporalDescriptor = Object.getOwnPropertyDescriptor(g, \"Temporal\");\n const needsTemporal = g.Temporal === undefined;\n const temporal = needsTemporal\n ? (await import(\"temporal-polyfill/full/implementation\")).Temporal\n : undefined;\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 // Install the base platform surface after whitelist cleanup. Per-namespace\n // mocks (workflow, tailordb, …) are installed on demand by `using xMock()`.\n installPlatformGlobals(global);\n if (needsTemporal) {\n Object.defineProperty(g, \"Temporal\", {\n value: temporal,\n writable: true,\n configurable: true,\n });\n }\n\n return {\n teardown(global: typeof globalThis) {\n cleanupPlatformGlobals(global);\n\n if (needsTemporal) {\n if (temporalDescriptor) {\n Object.defineProperty(global, \"Temporal\", temporalDescriptor);\n } else {\n Reflect.deleteProperty(global, \"Temporal\");\n }\n }\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":"0GAcA,MAAM,kBAAkB,IAAI,IAAI,CAC9B,GAAG,EAIH,EAGA,UACA,UACA,SACA,UACA,oBACA,oBACA,gBACF,CAAC,EAED,IAAA,EAAe,CACb,KAAM,iBACN,gBAAiB,MAEjB,MAAM,MAAM,EAA2B,CACrC,IAAM,EAAI,EAEJ,EAAqB,OAAO,yBAAyB,EAAG,UAAU,EAClE,EAAgB,EAAE,WAAa,IAAA,GAC/B,EAAW,GACZ,MAAM,OAAO,yCAAA,CAA0C,SACxD,IAAA,GAGE,EAA4C,CAAC,EACnD,IAAK,IAAM,KAAO,OAAO,oBAAoB,CAAC,EAC5C,GAAI,CAAC,EAAgB,IAAI,CAAG,EAAG,CAC7B,IAAM,EAAa,OAAO,yBAAyB,EAAG,CAAG,EACrD,GAAY,eACd,EAAM,GAAO,EACb,OAAO,EAAE,GAEb,CAcF,OATA,EAAuB,CAAM,EACzB,GACF,OAAO,eAAe,EAAG,WAAY,CACnC,MAAO,EACP,SAAU,GACV,aAAc,EAChB,CAAC,EAGI,CACL,SAAS,EAA2B,CAClC,EAAuB,CAAM,EAEzB,IACE,EACF,OAAO,eAAe,EAAQ,WAAY,CAAkB,EAE5D,QAAQ,eAAe,EAAQ,UAAU,GAK7C,IAAM,EAAI,EACV,IAAK,GAAM,CAAC,EAAK,KAAe,OAAO,QAAQ,CAAK,EAClD,OAAO,eAAe,EAAG,EAAK,CAAU,CAE5C,CACF,CACF,CACF"}
@@ -1,2 +1,2 @@
1
- import{i as e,t}from"../registry-HlEaGvl5.mjs";import{a as n,c as r,i,o as a,s as o,u as s}from"../wait-point-invoker-eiP-IIux.mjs";import{t as c}from"../assert-WeXvmG4j.mjs";import{n as l,r as u}from"../node-builtins-DYfhPBnz.mjs";import{t as d}from"../platform-serialize-DkiTdHOt.mjs";import{i as f,n as p,r as m,t as h}from"../secretmanager-5olfnI1b.mjs";import{createRequire as g}from"node:module";import{isEqual as _}from"es-toolkit";import{fileURLToPath as v}from"node:url";import{ColumnNode as y,CompiledQuery as b,InsertQueryNode as x,Kysely as S,PostgresAdapter as C,PostgresIntrospector as w,PostgresQueryCompiler as T,PrimitiveValueListNode as E,ReferenceNode as D,UpdateQueryNode as O,ValueListNode as k,ValueNode as A,ValuesNode as j}from"kysely";import{dirname as M,isAbsolute as N,matchesGlob as P,relative as F,resolve as I}from"node:path";import{vi as L}from"vitest";function isBlockedModule(e){return u(e)}function getBlockedMessage(e){return l(e)}const R=[`**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}`],z=new Set([`ImportDeclaration`,`ExportNamedDeclaration`,`ExportAllDeclaration`]),B=new Set(`break.case.catch.class.const.continue.debugger.default.delete.do.else.enum.export.extends.false.finally.for.function.if.import.in.instanceof.new.null.return.super.switch.this.throw.true.try.typeof.var.void.while.with.yield.let.static.implements.interface.package.private.protected.public.await.arguments.eval`.split(`.`)),V=/^[A-Za-z_$]/,H=/^[A-Za-z0-9_$]*$/;function isSafeBindingName(e){if(B.has(e)||e.length===0)return!1;let t=e[0];return t!==void 0&&V.test(t)&&H.test(e.slice(1))}function buildBlockedReplacement(e,t){let n=JSON.stringify(t),r=`throw new Error(${n});`,i=`(() => { throw new Error(${n}); })()`;if(e.type===`ExportNamedDeclaration`){let t=e.specifiers??[],n=[];for(let e of t){let t=e.exported?.name;if(typeof t==`string`){if(t==="default"){n.push(`export default ${i};`);continue}if(!isSafeBindingName(t))return r;n.push(`export const ${t} = ${i};`)}}return n.length>0?n.join(` `):r}if(e.type===`ExportAllDeclaration`){let t=e.exported?.name;return typeof t==`string`&&isSafeBindingName(t)?`export const ${t} = ${i};`:r}return r}const toFileList=e=>Array.isArray(e)?e:e?[e]:[];let U;function supportsDefaultProjectInheritance(){if(U===void 0)try{let{version:e}=g(import.meta.url)(`vitest/package.json`);U=Number.parseInt(e,10)>=5}catch{U=!1}return U}function createBlockPlugin(){let isTestFile=()=>!1,isUserSourceFile=()=>!1;return{name:`tailor-runtime-block-node`,configResolved(e){let t=e.test,n=t?.root??e.root,toAbsolutePaths=(e,t)=>toFileList(e).map(e=>I(t,e)),r=new Set([...toAbsolutePaths(t?.setupFiles,n),...toAbsolutePaths(t?.globalSetup,n)]),i=[{root:n,patterns:t?.include??R}];for(let e of t?.projects??[]){let t=e.test;if(!t)continue;let a=t.root??n;for(let e of toAbsolutePaths(t.setupFiles,a))r.add(e);for(let e of toAbsolutePaths(t.globalSetup,a))r.add(e);i.push({root:a,patterns:t.include??R})}isTestFile=e=>r.has(e)?!0:i.some(({root:t,patterns:n})=>{let r=N(e)?F(t,e):e;return n.some(e=>P(r,e))}),isUserSourceFile=e=>{if(!N(e))return!1;let t=F(n,e);return t!==``&&!t.startsWith(`..`)&&!N(t)}},transform(e,t){let n=t.search(/[?#]/),r=n===-1?t:t.slice(0,n);if(isTestFile(r)||r.includes(`node_modules`)||!isUserSourceFile(r))return;let i;try{i=this.parse(e)}catch{return}let a=[];for(let e of i.body){if(!z.has(e.type))continue;let t=e.source?.value;typeof t==`string`&&isBlockedModule(t)&&a.push({start:e.start,end:e.end,replacement:buildBlockedReplacement(e,getBlockedMessage(t))})}if(a.length===0)return;let o=e;for(let e of a.toSorted((e,t)=>t.start-e.start))o=o.slice(0,e.start)+e.replacement+o.slice(e.end);return{code:o,map:null}}}}function setConfigEnv(e,t){e.env={...e.env,__TAILOR_RUNTIME_CONFIG:t}}function createEnvironmentPlugin(e){let t=M(v(import.meta.url)),n=I(t,`environment.mjs`),r=I(t,`setup.mjs`),selectsTailorRuntime=e=>e===`tailor-runtime`||e===n;return{name:`tailor-runtime-environment`,config(t){let i=t.test,a=!!i&&selectsTailorRuntime(i.environment);if(i&&a&&(i.environment=n),i?.projects)for(let o of i.projects){if(typeof o==`string`)continue;let i=o.test??={};if(!(i.environment===void 0&&a&&(o.extends===!0||o.extends===void 0&&supportsDefaultProjectInheritance()))&&!selectsTailorRuntime(i.environment)){e?.config&&setConfigEnv(i,``);continue}i.environment=n;let s=toFileList(i.setupFiles);if(s.includes(r)||(i.setupFiles=[...s,r]),e?.config){let n=o.root??i.root??t.root??process.cwd();setConfigEnv(i,I(n,e.config))}}if(e?.config&&i){let n=i.root??t.root??process.cwd();setConfigEnv(i,a?I(n,e.config):``)}let o=toFileList(i?.setupFiles);return i&&typeof i.setupFiles==`string`&&(i.setupFiles=o),!a||o.includes(r)?{}:{test:{setupFiles:[r]}}}}}function mockAigateway(e={}){let t=p(),n=t.aigateway,r={...e.urls};async function defaultGet(e){let t=r[e];if(t===void 0)throw Error(`No AI Gateway registered for "${e}". Acquire mockAigateway() and call setUrls(...).`);return{url:t}}let i=L.fn(defaultGet);return t.aigateway={get:i},f({get:i,setUrls(e){r=e},setUrl(e,t){r={...r,[e]:t}},get calls(){return i.mock.calls.map(([e])=>({name:e}))},clear(){i.mockClear()},reset(){r={},i.mockReset(),i.mockImplementation(defaultGet)}},()=>{t.aigateway=n})}function mockAuthconnection(e={}){let t=p(),n=t.authconnection,r={...e.tokens};async function defaultGetConnectionToken(t){let n=r[t];if(n)return n;if(e.onUnhandled===`error`)throw Error(`No AuthConnection token configured for "${t}"`);return{access_token:`mock-token`}}let i=L.fn(defaultGetConnectionToken);return t.authconnection={getConnectionToken:i},f({getConnectionToken:i,setTokens(e){r=e},setToken(e,t){r={...r,[e]:t}},get calls(){return i.mock.calls.map(([e])=>({connectionName:e}))},clear(){i.mockClear()},reset(){r={},i.mockReset(),i.mockImplementation(defaultGetConnectionToken)}},()=>{t.authconnection=n})}const W=[`upload`,`download`,`downloadAsBase64`,`delete`,`getMetadata`,`downloadStream`,`uploadStream`],G={upload:{metadata:{fileSize:0,sha256sum:``}},download:{data:new Uint8Array,metadata:{contentType:``,fileSize:0,sha256sum:``,lastUploadedAt:``}},downloadAsBase64:{data:``,metadata:{contentType:``,fileSize:0,sha256sum:``,lastUploadedAt:``}},getMetadata:{contentType:``,fileSize:0,sha256sum:``,urlPath:``},downloadStream:null,uploadStream:{metadata:{fileSize:0,sha256sum:``}}};function mockFile(e={}){let t=m(),n=t.file,{onUnhandled:r=`fallback`}=e,i=[],a=[],resolver=()=>null;function handle(e,t,n,a,o){if(i.length>0)return i.shift();let s=resolver(e,{method:e,namespace:t,tableName:n,fieldName:a,recordId:o});if(s!=null)return s;if(r===`error`)throw Error(`No File mock configured for "${e}"`);let c=G[e];return c===void 0?void 0:structuredClone(c)}let o=L.fn(async(...e)=>{let[t,n,r,i]=e;return handle(`upload`,t,n,r,i)}),s=L.fn(async(...e)=>handle(`download`,...e)),c=L.fn(async(...e)=>handle(`downloadAsBase64`,...e)),l=L.fn(async(...e)=>{handle(`delete`,...e)}),u=L.fn(async(...e)=>handle(`getMetadata`,...e)),d=L.fn(async(...e)=>handle(`downloadStream`,...e)??{body:new ReadableStream({start(e){e.close()}}),metadata:{contentType:``,fileSize:0,sha256sum:``,lastUploadedAt:``}}),p=L.fn(async(...e)=>{let[t,n,r,i]=e;return handle(`uploadStream`,t,n,r,i)}),h={upload:o,download:s,downloadAsBase64:c,delete:l,getMetadata:u,downloadStream:d,uploadStream:p};function track(e,t){return function(...n){return a.push({method:e,namespace:n[0],tableName:n[1],fieldName:n[2],recordId:n[3]}),t.apply(this,n)}}t.file={upload:track(`upload`,o),download:track(`download`,s),downloadAsBase64:track(`downloadAsBase64`,c),delete:track(`delete`,l),getMetadata:track(`getMetadata`,u),downloadStream:track(`downloadStream`,d),uploadStream:track(`uploadStream`,p)};function allMocks(){return W.map(e=>h[e])}let g={...h,setResolver(e){resolver=e},enqueueResult(e){i.push(e)},enqueueResults(...e){i.push(...e)},get calls(){return a},clear(){a.length=0;for(let e of allMocks())e.mockClear()},reset(){i.length=0,a.length=0,resolver=()=>null;for(let e of allMocks())e.mockReset()}};return f(g,()=>{t.file=n})}function isUtf8(e){return e===`UTF8`||e===`UTF-8`}function defaultIconvResult(e,t){switch(e){case`convert`:case`convertBuffer`:return isUtf8(t[2])?``:new Uint8Array;case`decode`:return``;case`encode`:return isUtf8(t[1])?``:new Uint8Array;case`encodings`:return[]}}function mockIconv(e={}){let t=p(),n=t.iconv,r=null,i=[];function resolve(t,n){if(r){let e=r(t,n);if(e!=null)return e}if(e.onUnhandled===`error`)throw Error(`No Iconv mock behavior configured for "${t}"`);return defaultIconvResult(t,n)}function defaultConvert(e,t,n){return resolve(`convert`,[e,t,n])}function defaultConvertBuffer(e,t,n){return resolve(`convertBuffer`,[e,t,n])}function defaultDecode(e,t){return resolve(`decode`,[e,t])}function defaultEncode(e,t){return resolve(`encode`,[e,t])}function defaultEncodings(){return resolve(`encodings`,[])}let a=L.fn(defaultConvert),o=L.fn(defaultConvertBuffer),s=L.fn(defaultDecode),c=L.fn(defaultEncode),l=L.fn(defaultEncodings);function track(e,t){return function(...n){return i.push({method:e,args:[...n]}),t.apply(this,n)}}let u=track(`convert`,a),d=track(`convertBuffer`,o),m=track(`decode`,s),h=track(`encode`,c),g=track(`encodings`,l);class MockIconv{#e;#t;constructor(e,t){this.#e=e,this.#t=t}convert(e){return u.call(this,e,this.#e,this.#t)}}t.iconv={convert:u,convertBuffer:d,decode:m,encode:h,encodings:g,Iconv:MockIconv};function clear(){i.length=0,a.mockClear(),o.mockClear(),s.mockClear(),c.mockClear(),l.mockClear()}return f({convert:a,convertBuffer:o,decode:s,encode:c,encodings:l,setResolver(e){r=e},get calls(){return i},clear,reset(){r=null,i.length=0,a.mockReset(),a.mockImplementation(defaultConvert),o.mockReset(),o.mockImplementation(defaultConvertBuffer),s.mockReset(),s.mockImplementation(defaultDecode),c.mockReset(),c.mockImplementation(defaultEncode),l.mockReset(),l.mockImplementation(defaultEncodings)}},()=>{t.iconv=n})}const K=[`users`,`user`,`userByName`,`createUser`,`updateUser`,`deleteUser`,`sendPasswordResetEmail`,`unenrollMfa`],q={id:`mock-id`,name:`mock-user`,disabled:!1,mfaEnrolled:!1,mfaFactorIds:[]},J={users:{users:[],nextPageToken:null,totalCount:0},user:q,userByName:q,createUser:q,updateUser:q,deleteUser:!0,sendPasswordResetEmail:!0,unenrollMfa:!0};function mockIdp(e={}){let t=p(),n=t.idp,{onUnhandled:r=`fallback`}=e,i=[],a=[],resolver=()=>null,o=new Map;function compatibilityArgs(e,t){return e===`users`&&t.length===0?[void 0]:t}function handle(e,t,n){if(i.length>0)return i.shift();let a=resolver(e,compatibilityArgs(e,t),n);if(a!=null)return a;if(r===`error`)throw Error(`No IdP mock configured for "${n}.${e}"`);return structuredClone(J[e])}function createNamespaceMocks(e){return{users:L.fn(async(...t)=>handle(`users`,t,e)),user:L.fn(async(...t)=>handle(`user`,t,e)),userByName:L.fn(async(...t)=>handle(`userByName`,t,e)),createUser:L.fn(async(...t)=>handle(`createUser`,t,e)),updateUser:L.fn(async(...t)=>handle(`updateUser`,t,e)),deleteUser:L.fn(async(...t)=>handle(`deleteUser`,t,e)),sendPasswordResetEmail:L.fn(async(...t)=>handle(`sendPasswordResetEmail`,t,e)),unenrollMfa:L.fn(async(...t)=>handle(`unenrollMfa`,t,e))}}function namespace(e){let t=o.get(e);if(t)return t;let n=createNamespaceMocks(e);return o.set(e,n),n}function track(e,t,n){return function(...r){return a.push({method:e,args:[...compatibilityArgs(e,r)],namespace:n}),t.apply(this,r)}}let defaultClient=function(e){let t=namespace(e.namespace);this.users=track(`users`,t.users,e.namespace),this.user=track(`user`,t.user,e.namespace),this.userByName=track(`userByName`,t.userByName,e.namespace),this.createUser=track(`createUser`,t.createUser,e.namespace),this.updateUser=track(`updateUser`,t.updateUser,e.namespace),this.deleteUser=track(`deleteUser`,t.deleteUser,e.namespace),this.sendPasswordResetEmail=track(`sendPasswordResetEmail`,t.sendPasswordResetEmail,e.namespace),this.unenrollMfa=track(`unenrollMfa`,t.unenrollMfa,e.namespace)},s=L.fn(defaultClient);t.idp={Client:s};function allMocks(){return[...o.values()].flatMap(e=>K.map(t=>e[t]))}return f({Client:s,namespace,setResolver(e){resolver=e},enqueueResult(e){i.push(e)},enqueueResults(...e){i.push(...e)},get calls(){return a},clear(){a.length=0,s.mockClear();for(let e of allMocks())e.mockClear()},reset(){i.length=0,a.length=0,resolver=()=>null,s.mockReset(),s.mockImplementation(defaultClient);for(let e of allMocks())e.mockReset()}},()=>{t.idp=n})}function mockLogger(e={}){let t=p(),n=t.logger,r=L.fn((e,t)=>{}),i=L.fn((e,t)=>{}),a=L.fn((e,t)=>{}),o=L.fn((e,t)=>{}),s=L.fn(e=>{});t.logger={debug:r,info:i,warn:a,error:o,setAttributes:s};let c={debug:r,info:i,warn:a,error:o};return f({debug:r,info:i,warn:a,error:o,setAttributes:s,get calls(){return Object.entries(c).flatMap(([e,t])=>t.mock.calls.map((n,r)=>({order:t.mock.invocationCallOrder[r]??0,call:{severity:e,message:n[0],attributes:n[1]}}))).toSorted((e,t)=>e.order-t.order).map(e=>e.call)},clear(){r.mockClear(),i.mockClear(),a.mockClear(),o.mockClear(),s.mockClear()},reset(){r.mockReset(),i.mockReset(),a.mockReset(),o.mockReset(),s.mockReset()}},()=>{t.logger=n})}function testRegex(e,t){let n=e.lastIndex;e.lastIndex=0;try{return e.test(t)}finally{e.lastIndex=n}}var MockQueryResult=class{command;rowCount;rows;constructor(e){this.command=``,this.rowCount=e.length,this.rows=e}};function mockTailordb(e={}){let t=m(),n=t.Client,r=[],i;function matchesQuery(e,t,n){if(typeof e==`function`)return e(t,n);if(typeof e==`string`)return t===e;if(e instanceof RegExp)return testRegex(e,t);let r;if(r=typeof e.sql==`string`?t===e.sql:testRegex(e.sql,t),!r||e.params===void 0)return r;if(typeof e.params==`function`)return e.params(n);let i=e.params;return n.length===i.length&&n.every((e,t)=>_(e,i[t]))}function queryResponse(e){if(e.type===`error`)throw e.error;return new MockQueryResult(e.rows)}async function defaultQuery(t,n=[]){for(let e=r.length-1;e>=0;--e){let i=r[e];if(!i||!matchesQuery(i.matcher,t,n))continue;let a=i.once.shift();if(a)return queryResponse(a);if(i.fallback)return queryResponse(i.fallback)}if(i)return new MockQueryResult(i(t,n)??[]);if(e.onUnhandled===`error`)throw Error(`No TailorDB query behavior matched: ${t}`);return new MockQueryResult([])}let a=L.fn(defaultQuery),defaultConnect=async()=>{},o=L.fn(defaultConnect),s=[];function enqueueRowsList(e){for(let t of e)a.mockImplementationOnce(async()=>new MockQueryResult(t))}let defaultClient=function(e){let t={namespace:e?.namespace,ended:!1};s.push(t),this.connect=o,this.end=L.fn(async()=>{t.ended=!0}),this.queryObject=a,this.createTransaction=e=>{if(!e)throw Error(`Transaction name must be a non-empty string`);return{begin:async()=>{},commit:async()=>{},rollback:async()=>{},queryObject:a}}},c=L.fn(defaultClient);return t.Client=c,f({Client:c,queryObject:a,setQueryResolver(e){i=e,a.mockImplementation(defaultQuery)},onQuery(e){let t={matcher:e,once:[]};r.push(t);let n={returnsRows(e){return t.fallback={type:`rows`,rows:e},n},returnsRowsOnce(e){return t.once.push({type:`rows`,rows:e}),n},rejects(e){return t.fallback={type:`error`,error:e},n},rejectsOnce(e){return t.once.push({type:`error`,error:e}),n}};return n},enqueueResult(...e){enqueueRowsList([e])},enqueueResults(...e){enqueueRowsList(e)},enqueueRows(...e){enqueueRowsList(e)},get executedQueries(){return a.mock.calls.map(([e,t])=>({query:e,params:t??[]}))},get createdClients(){return s},clear(){a.mockClear(),o.mockClear(),c.mockClear(),s.length=0},reset(){a.mockReset(),a.mockImplementation(defaultQuery),o.mockReset(),o.mockImplementation(defaultConnect),c.mockReset(),c.mockImplementation(defaultClient),s.length=0,r.length=0,i=void 0}},()=>{t.Client=n})}const Y=new WeakMap,X=new WeakMap,Z=new WeakMap;function replaceProcedure(e,t,n){let r=Z.get(n)??n,i=L.fn(function(...e){return Reflect.apply(r,this,e)});Z.set(i,r);let a=e;return a[t]=i,{mock:i,scoped:{mockClear:()=>i.mockClear(),mockReset:()=>i.mockReset(),restore:()=>{a[t]===i&&(a[t]=n)}}}}function replaceStart(e){return replaceProcedure(e,`start`,e.start)}function mockWorkflow(){let e=p(),a=e.workflow,c=r(),l=new Map,u=new Map,m=new Map,h=new Map,g=new Set,installKeyDispatcher=e=>{let t=h.get(e);if(t)return t;let n=i(e);if(!n)throw Error(`waitPointWith expects a wait point definition created by createWaitPoint or createWaitPoints.`);let r=n,a=n.wait,o=n.resolve,s=Y.get(a)??a,c=X.get(o)??o,l={perKey:new Map,originalWait:(e,t)=>s.call(n,e,t),originalResolve:(e,t,r)=>c.call(n,e,t,r)},dispatchWait=(e,t)=>{let n=l.perKey.get(e);return n?t===void 0?n.wait():n.wait(t):l.originalWait(e,t)},dispatchResolve=async(e,t,n)=>{let r=l.perKey.get(e);if(!r)return l.originalResolve(e,t,n);await r.resolve(t,n)};Y.set(dispatchWait,s),X.set(dispatchResolve,c),r.wait=dispatchWait,r.resolve=dispatchResolve;let eachSpy=e=>{for(let t of l.perKey.values()){let n=t;e(n.wait),e(n.resolve)}};return g.add({mockClear:()=>eachSpy(e=>e.mockClear()),mockReset:()=>eachSpy(e=>e.mockReset()),restore:()=>{r.wait=a,r.resolve=o,h.delete(e)}}),h.set(e,l),l},defaultExecJob=(e,t,n)=>{throw Error(`No workflow job mock for "${e}". Call mockWorkflow().setJobHandler(...) or enqueueResult(...), or use runWorkflowLocally() for local workflow execution.`)},defaultStartWorkflow=async(e,n,r)=>t,defaultResumeWorkflowExecution=async e=>e,_=L.fn(defaultExecJob),v=L.fn(defaultStartWorkflow),y=L.fn(defaultResumeWorkflowExecution),b=L.fn((e,t)=>null),x=L.fn(async(e,t,n)=>{});return e.workflow={execJobFunction:(...e)=>{let t=e.length>=3?_(e[0],d(e[1]),e[2]):_(e[0],d(e[1]));return t instanceof Promise?t.then(e=>d(e)):d(t)},startWorkflow:(...e)=>e.length>=3?v(e[0],d(e[1]),e[2]):v(e[0],d(e[1])),resumeWorkflowExecution:e=>y(e),wait:(e,t)=>b(e,d(t)),resolve:(e,t,n)=>x(e,t,e=>{let t=n(e);return t instanceof Promise?t.then(e=>d(e)):d(t)})},f({execJobFunction:_,startWorkflow:v,resumeWorkflowExecution:y,wait:b,resolve:x,job(e){let t=l.get(e);if(t)return t;let{mock:n,scoped:r}=replaceStart(e);return g.add(r),l.set(e,n),n},workflow(e){let t=u.get(e);if(t)return t;let{mock:n,scoped:r}=replaceStart(e);return u.set(e,n),g.add(r),n},waitPoint(e){let t=m.get(e);if(t)return t;let n=replaceProcedure(e,`wait`,e.wait),r=replaceProcedure(e,`resolve`,e.resolve),i=n.mock,a=r.mock;g.add(n.scoped),g.add(r.scoped);let o={wait:i,resolve:a,setResolvePayload(e){a.mockImplementation(async(t,n)=>{let r=await n(d(e));d(r)})}};return m.set(e,o),o},waitPointWith(e,t){let r=n(e.with(t));if(r===void 0)throw Error(`waitPointWith expects a wait point declared with $params. Use waitPoint() for a wait point with a fixed key.`);let i=installKeyDispatcher(e),a=i.perKey.get(r);if(a)return a;let o=L.fn(e=>Promise.resolve(i.originalWait(r,e))),s=L.fn((e,t)=>i.originalResolve(r,e,t)),c={wait:o,resolve:s,setResolvePayload(e){s.mockImplementation(async(t,n)=>{let r=await n(d(e));d(r)})}};return i.perKey.set(r,c),c},setJobHandler(e){_.mockImplementation((t,n,r)=>e(t,n,r))},enqueueResult(e){_.mockImplementationOnce(()=>e)},enqueueResults(...e){for(let t of e)_.mockImplementationOnce(()=>t)},get startedJobs(){return _.mock.calls.map(([e,t,n])=>({jobName:e,args:t,...n!==void 0&&{options:n}}))},setStartHandler(e){v.mockImplementation(typeof e==`function`?async(t,n,r)=>e(t,n,r):async()=>e)},setResumeHandler(e){y.mockImplementation(typeof e==`function`?async t=>e(t):async()=>e)},setWaitHandler:e=>{b.mockImplementation(typeof e==`function`?(t,n)=>e(t,n):()=>e)},setEnv(e){s({...e})},setResolveHandler(e){x.mockImplementation(async(t,n,r)=>{await e(t,n,r)})},get waitCalls(){return b.mock.calls.map(([e,t])=>({key:e,payload:t}))},get resolveCalls(){return x.mock.calls.map(([e,t])=>({executionId:e,key:t}))},clear(){_.mockClear(),v.mockClear(),y.mockClear(),b.mockClear(),x.mockClear();for(let e of g)e.mockClear()},reset(){_.mockReset(),_.mockImplementation(defaultExecJob),v.mockReset(),v.mockImplementation(defaultStartWorkflow),y.mockReset(),y.mockImplementation(defaultResumeWorkflowExecution),b.mockReset(),b.mockImplementation(()=>null),x.mockReset(),x.mockImplementation(async()=>{});for(let e of g)e.mockReset();o()}},()=>{for(let e of g)e.restore();e.workflow=a,c===void 0?o():s(c)})}var TransactionLock=class{#e=null;#t=[];holds(e){return this.#e===e}async acquire(e){for(;this.#e!==null;)await new Promise(e=>this.#t.push(e));this.#e=e}release(e){this.#e===e&&(this.#e=null,this.#t.shift()?.())}};const Q=/^\s*(?:begin|start\s+transaction)\b/i,$=/^\s*(?:commit\b|rollback\b(?!(?:\s+(?:work|transaction))?\s+to\b))/i;function toQueryObjectResult(e){return{command:e.command??(e.affectedRows?`UPDATE`:`SELECT`),rowCount:e.rowCount??(e.affectedRows||e.rows.length),rows:e.rows}}function mockTailordbWithPGlite(e){let t=m(),n=t.Client,r=[],i=[],a=new Map,o=new Set,assertNoOpenTransaction=e=>{if(o.size>0)throw Error(`mockTailordbWithPGlite: ${e}() cannot run while a transaction is open; commit, roll back, or end() its client first`)},defaultClient=function(t){let n=t?.namespace,s=n!==void 0&&Object.hasOwn(e.namespaces,n)?e.namespaces[n]:void 0;if(n===void 0||!s)throw Error(`mockTailordbWithPGlite: no PGlite instance registered for namespace "${n}"`);let c=a.get(s)??new TransactionLock;a.set(s,c);let l={namespace:n,ended:!1};i.push(l);let u=this,run=async(e,t)=>(r.push({namespace:n,query:e,params:t??[]}),toQueryObjectResult(await s.query(e,t??[]))),throwEnded=()=>{throw Error(`mockTailordbWithPGlite: query after end() on this client`)},acquire=async()=>{await c.acquire(u),l.ended&&(c.release(u),throwEnded())},queryObject=async(e,t)=>{if(l.ended&&throwEnded(),Q.test(e)){if(c.holds(u))throw Error(`mockTailordbWithPGlite: transaction already open on this client — run nested statements on the transaction callback's trx`);await acquire();try{let n=await run(e,t);return o.add(l),n}catch(e){throw c.release(u),e}}if($.test(e)){if(c.holds(u))try{return await run(e,t)}finally{o.delete(l),c.release(u)}await acquire();try{return await run(e,t)}finally{c.release(u)}}if(c.holds(u))return await run(e,t);await acquire();try{return await run(e,t)}finally{c.release(u)}};this.connect=async()=>{},this.end=async()=>{if(l.ended=!0,c.holds(u))try{await run(`rollback`)}finally{o.delete(l),c.release(u)}},this.queryObject=queryObject,this.createTransaction=e=>{if(!e)throw Error(`Transaction name must be a non-empty string`);return{begin:()=>queryObject(`begin`),commit:()=>queryObject(`commit`),rollback:()=>queryObject(`rollback`),queryObject}}},s=L.fn(defaultClient);return t.Client=s,f({Client:s,get executedQueries(){return r},get createdClients(){return i},clear(){assertNoOpenTransaction(`clear`),s.mockClear(),r.length=0,i.length=0},reset(){assertNoOpenTransaction(`reset`),s.mockReset(),s.mockImplementation(defaultClient),r.length=0,i.length=0}},()=>{t.Client=n})}var PendingStart=class{jobName;args;constructor(e,t){this.jobName=e,this.args=t}};async function runWorkflowLocally(e,t,n){let i=globalThis,a=i.tailor,c=r(),l=c!==void 0,u=createLocalJobRunner();n?.env!==void 0&&s({...n.env}),i.tailor={...a,workflow:createLocalWorkflowRuntime(a?.workflow,u.execJobFunction)};try{return await u.runJob(e.mainJob.name,t)}finally{a?i.tailor=a:delete i.tailor,n?.env!==void 0&&(l?s(c):o())}}function createLocalJobRunner(){let t,execJobFunction=(e,n)=>{if(!t)throw Error(`Cannot start workflow job "${e}" outside runWorkflowLocally() job execution.`);if(t.pending)throw t.pending;let r=d(n),i=t.cursor;t.cursor+=1;let a=t.records[i];if(a){if(assertSameStart(a,e,r),a.status===`rejected`)throw a.error;return d(a.result)}let o=new PendingStart(e,r);throw t.pending=o,o},runJob=async(n,r)=>{let i=e(n);if(!i)return null;let o=[];for(;;){let e={records:o,cursor:0},s=t;t=e;try{let t=await i(d(r),a());if(e.pending){await settlePendingStart(o,e.pending,runJob);continue}if(e.cursor!==o.length)throw Error(`Workflow job start sequence changed while replaying "${n}". Expected ${o.length} start(s), but replay reached ${e.cursor}.`);return d(t)}catch(t){let n=t instanceof PendingStart?t:e.pending;if(n){await settlePendingStart(o,n,runJob);continue}throw t}finally{t=s}}};return{runJob,execJobFunction}}async function settlePendingStart(e,t,n){try{e.push({jobName:t.jobName,args:t.args,status:`fulfilled`,result:await n(t.jobName,t.args)})}catch(n){e.push({jobName:t.jobName,args:t.args,status:`rejected`,error:n})}}function assertSameStart(e,t,n){if(e.jobName!==t||JSON.stringify(e.args)!==JSON.stringify(n))throw Error(`Workflow job start sequence changed while replaying. Expected ${e.jobName}(${JSON.stringify(e.args)}), but got ${t}(${JSON.stringify(n)}).`)}function createLocalWorkflowRuntime(e,n){return{execJobFunction:n,startWorkflow:async(n,r,i)=>e?await e.startWorkflow(n,r,i):(d(r),t),resumeWorkflowExecution:async t=>e?await e.resumeWorkflowExecution(t):t,wait:(t,n)=>{if(e)return e.wait(t,n);throw Error(`No wait handler for "${t}". Acquire mockWorkflow() and call setWaitHandler(...).`)},resolve:async(t,n,r)=>{if(e){await e.resolve(t,n,r);return}throw Error(`No resolve handler. Acquire mockWorkflow() and call setResolveHandler(...).`)}}}function unwrapValue(e){return A.is(e)?e.value:e}function insertRows(e){if(!x.is(e))throw Error(`insertRows: expected InsertQueryNode, got ${e.kind}`);let t=e.columns,n=e.values;if(t===void 0||n===void 0||!j.is(n))throw Error(`insertRows: unsupported insert shape; inspect query.node instead`);return n.values.map(e=>{if(!E.is(e)&&!k.is(e))throw Error(`insertRows: unsupported insert shape; inspect query.node instead`);let n=E.is(e)?e.values:e.values.map(unwrapValue),r={};return t.forEach((e,t)=>{r[e.column.name]=n[t]}),r})}function insertValues(e){let t=insertRows(e);if(t.length!==1)throw Error(`insertValues: query inserts ${t.length} rows; use insertRows() for multi-row inserts`);return c(t[0],`insertValues: first row missing`)}function updateValues(e){if(!O.is(e))throw Error(`updateValues: expected UpdateQueryNode, got ${e.kind}`);if(e.updates===void 0)throw Error(`updateValues: unsupported update shape; inspect query.node instead`);let t={};for(let n of e.updates){let e=n.column,r=y.is(e)?e.column.name:D.is(e)&&y.is(e.column)?e.column.column.name:void 0;if(r===void 0)throw Error(`updateValues: unsupported update shape; inspect query.node instead`);t[r]=unwrapValue(n.value)}return t}function toExecutedQuery(e){let t=e.query;return{kind:t.kind,sql:e.sql,parameters:e.parameters,node:t,insertRows:()=>insertRows(t),insertValues:()=>insertValues(t),updateValues:()=>updateValues(t)}}function toStagedResult(e){return Array.isArray(e)?{rows:e,numAffectedRows:void 0}:{rows:e.rows??[],numAffectedRows:e.numAffectedRows===void 0?void 0:BigInt(e.numAffectedRows)}}var MockState=class{executed=[];queue=[];resolver;enqueue(...e){this.queue.push(...e)}setResolver(e){this.resolver=e}next(e){let t=this.resolver?.(e);if(t!==void 0)return toStagedResult(t);let n=this.queue.shift();return n===void 0?{rows:[],numAffectedRows:void 0}:toStagedResult(n)}reset(){this.executed.length=0,this.queue.length=0,this.resolver=void 0}},MockConnection=class{state;constructor(e){this.state=e}async executeQuery(e){let t=toExecutedQuery(e);this.state.executed.push(t);let{rows:n,numAffectedRows:r}=this.state.next(t);return{rows:n,numAffectedRows:r??BigInt(n.length)}}streamQuery(){throw Error(`createKyselyMock: streaming is not supported`)}},MockDriver=class{state;constructor(e){this.state=e}async init(){}async acquireConnection(){return new MockConnection(this.state)}async beginTransaction(){}async commitTransaction(){}async rollbackTransaction(){}async releaseConnection(){}async destroy(){}};function byKind(e,t){return e.executed.filter(e=>e.kind===t)}function createKyselyMock(){let e=new MockState,t=new S({dialect:{createDriver:()=>new MockDriver(e),createQueryCompiler:()=>new T,createAdapter:()=>new C,createIntrospector:e=>new w(e)}});return{db:t,get executedQueries(){return e.executed},get selects(){return byKind(e,`SelectQueryNode`)},get inserts(){return byKind(e,`InsertQueryNode`)},get updates(){return byKind(e,`UpdateQueryNode`)},get deletes(){return byKind(e,`DeleteQueryNode`)},enqueueResult:t=>e.enqueue(t),enqueueResults:(...t)=>e.enqueue(...t),setQueryResolver:t=>e.setResolver(t),withTx:e=>t.transaction().execute(e),reset:()=>e.reset(),[Symbol.dispose]:()=>e.reset()}}var PGliteConnection=class{#e;constructor(e){this.#e=e}async executeQuery(e){let t=await this.#e.query(e.sql,[...e.parameters]);return{rows:t.rows,numAffectedRows:BigInt(t.affectedRows??0)}}streamQuery(){throw Error(`createKyselyPGlite: streaming is not supported`)}},PGliteDriver=class{#e;constructor(e){this.#e=e}async init(){}async acquireConnection(){return new PGliteConnection(this.#e)}async beginTransaction(e,t){let n=t.isolationLevel?[`start transaction`,`isolation level ${t.isolationLevel}`]:[`begin`];t.accessMode&&n.push(t.accessMode),await e.executeQuery(b.raw(n.join(` `)))}async commitTransaction(e){await e.executeQuery(b.raw(`commit`))}async rollbackTransaction(e){await e.executeQuery(b.raw(`rollback`))}async releaseConnection(){}async destroy(){await this.#e.close()}};function createKyselyPGlite(e){return new S({dialect:{createAdapter:()=>new C,createDriver:()=>new PGliteDriver(e),createIntrospector:e=>new w(e),createQueryCompiler:()=>new T}})}function tailorRuntime(e){return[createBlockPlugin(),createEnvironmentPlugin(e)]}export{createKyselyMock,createKyselyPGlite,mockAigateway,mockAuthconnection,mockFile,mockIconv,mockIdp,mockLogger,h as mockSecretmanager,mockTailordb,mockTailordbWithPGlite,mockWorkflow,runWorkflowLocally,tailorRuntime};
1
+ import{i as e,t}from"../registry-BijIDRVA.mjs";import{a as n,c as r,i,o as a,s as o,u as s}from"../wait-point-invoker-eiP-IIux.mjs";import{t as c}from"../assert-WeXvmG4j.mjs";import{n as l,r as u}from"../node-builtins-DYfhPBnz.mjs";import{t as d}from"../platform-serialize-DkiTdHOt.mjs";import{i as f,n as p,r as m,t as h}from"../secretmanager-5olfnI1b.mjs";import{createRequire as g}from"node:module";import{isEqual as _}from"es-toolkit";import{fileURLToPath as v}from"node:url";import{ColumnNode as y,CompiledQuery as b,InsertQueryNode as x,Kysely as S,PostgresAdapter as C,PostgresIntrospector as w,PostgresQueryCompiler as T,PrimitiveValueListNode as E,ReferenceNode as D,UpdateQueryNode as O,ValueListNode as k,ValueNode as A,ValuesNode as j}from"kysely";import{dirname as M,isAbsolute as N,matchesGlob as P,relative as F,resolve as I}from"node:path";import{vi as L}from"vitest";function isBlockedModule(e){return u(e)}function getBlockedMessage(e){return l(e)}const R=[`**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}`],z=/* @__PURE__ */ new Set([`ImportDeclaration`,`ExportNamedDeclaration`,`ExportAllDeclaration`]),B=/* @__PURE__ */ new Set(/* @__PURE__ */ `break.case.catch.class.const.continue.debugger.default.delete.do.else.enum.export.extends.false.finally.for.function.if.import.in.instanceof.new.null.return.super.switch.this.throw.true.try.typeof.var.void.while.with.yield.let.static.implements.interface.package.private.protected.public.await.arguments.eval`.split(`.`)),V=/^[A-Za-z_$]/,H=/^[A-Za-z0-9_$]*$/;function isSafeBindingName(e){if(B.has(e)||e.length===0)return!1;let t=e[0];return t!==void 0&&V.test(t)&&H.test(e.slice(1))}function buildBlockedReplacement(e,t){let n=JSON.stringify(t),r=`throw new Error(${n});`,i=`(() => { throw new Error(${n}); })()`;if(e.type===`ExportNamedDeclaration`){let t=e.specifiers??[],n=[];for(let e of t){let t=e.exported?.name;if(typeof t==`string`){if(t==="default"){n.push(`export default ${i};`);continue}if(!isSafeBindingName(t))return r;n.push(`export const ${t} = ${i};`)}}return n.length>0?n.join(` `):r}if(e.type===`ExportAllDeclaration`){let t=e.exported?.name;return typeof t==`string`&&isSafeBindingName(t)?`export const ${t} = ${i};`:r}return r}const toFileList=e=>Array.isArray(e)?e:e?[e]:[];let U;function supportsDefaultProjectInheritance(){if(U===void 0)try{let{version:e}=g(import.meta.url)(`vitest/package.json`);U=Number.parseInt(e,10)>=5}catch{U=!1}return U}function createBlockPlugin(){let isTestFile=()=>!1,isUserSourceFile=()=>!1;return{name:`tailor-runtime-block-node`,configResolved(e){let t=e.test,n=t?.root??e.root,toAbsolutePaths=(e,t)=>toFileList(e).map(e=>I(t,e)),r=/* @__PURE__ */ new Set([...toAbsolutePaths(t?.setupFiles,n),...toAbsolutePaths(t?.globalSetup,n)]),i=[{root:n,patterns:t?.include??R}];for(let e of t?.projects??[]){let t=e.test;if(!t)continue;let a=t.root??n;for(let e of toAbsolutePaths(t.setupFiles,a))r.add(e);for(let e of toAbsolutePaths(t.globalSetup,a))r.add(e);i.push({root:a,patterns:t.include??R})}isTestFile=e=>r.has(e)?!0:i.some(({root:t,patterns:n})=>{let r=N(e)?F(t,e):e;return n.some(e=>P(r,e))}),isUserSourceFile=e=>{if(!N(e))return!1;let t=F(n,e);return t!==``&&!t.startsWith(`..`)&&!N(t)}},transform(e,t){let n=t.search(/[?#]/),r=n===-1?t:t.slice(0,n);if(isTestFile(r)||r.includes(`node_modules`)||!isUserSourceFile(r))return;let i;try{i=this.parse(e)}catch{return}let a=[];for(let e of i.body){if(!z.has(e.type))continue;let t=e.source?.value;typeof t==`string`&&isBlockedModule(t)&&a.push({start:e.start,end:e.end,replacement:buildBlockedReplacement(e,getBlockedMessage(t))})}if(a.length===0)return;let o=e;for(let e of a.toSorted((e,t)=>t.start-e.start))o=o.slice(0,e.start)+e.replacement+o.slice(e.end);return{code:o,map:null}}}}function setConfigEnv(e,t){e.env={...e.env,__TAILOR_RUNTIME_CONFIG:t}}function createEnvironmentPlugin(e){let t=M(v(import.meta.url)),n=I(t,`environment.mjs`),r=I(t,`setup.mjs`),selectsTailorRuntime=e=>e===`tailor-runtime`||e===n;return{name:`tailor-runtime-environment`,config(t){let i=t.test,a=!!i&&selectsTailorRuntime(i.environment);if(i&&a&&(i.environment=n),i?.projects)for(let o of i.projects){if(typeof o==`string`)continue;let i=o.test??={};if(!(i.environment===void 0&&a&&(o.extends===!0||o.extends===void 0&&supportsDefaultProjectInheritance()))&&!selectsTailorRuntime(i.environment)){e?.config&&setConfigEnv(i,``);continue}i.environment=n;let s=toFileList(i.setupFiles);if(s.includes(r)||(i.setupFiles=[...s,r]),e?.config){let n=o.root??i.root??t.root??process.cwd();setConfigEnv(i,I(n,e.config))}}if(e?.config&&i){let n=i.root??t.root??process.cwd();setConfigEnv(i,a?I(n,e.config):``)}let o=toFileList(i?.setupFiles);return i&&typeof i.setupFiles==`string`&&(i.setupFiles=o),!a||o.includes(r)?{}:{test:{setupFiles:[r]}}}}}function mockAigateway(e={}){let t=p(),n=t.aigateway,r={...e.urls};async function defaultGet(e){let t=r[e];if(t===void 0)throw Error(`No AI Gateway registered for "${e}". Acquire mockAigateway() and call setUrls(...).`);return{url:t}}let i=L.fn(defaultGet);return t.aigateway={get:i},f({get:i,setUrls(e){r=e},setUrl(e,t){r={...r,[e]:t}},get calls(){return i.mock.calls.map(([e])=>({name:e}))},clear(){i.mockClear()},reset(){r={},i.mockReset(),i.mockImplementation(defaultGet)}},()=>{t.aigateway=n})}function mockAuthconnection(e={}){let t=p(),n=t.authconnection,r={...e.tokens};async function defaultGetConnectionToken(t){let n=r[t];if(n)return n;if(e.onUnhandled===`error`)throw Error(`No AuthConnection token configured for "${t}"`);return{access_token:`mock-token`}}let i=L.fn(defaultGetConnectionToken);return t.authconnection={getConnectionToken:i},f({getConnectionToken:i,setTokens(e){r=e},setToken(e,t){r={...r,[e]:t}},get calls(){return i.mock.calls.map(([e])=>({connectionName:e}))},clear(){i.mockClear()},reset(){r={},i.mockReset(),i.mockImplementation(defaultGetConnectionToken)}},()=>{t.authconnection=n})}const W=[`upload`,`download`,`downloadAsBase64`,`delete`,`getMetadata`,`downloadStream`,`uploadStream`],G={upload:{metadata:{fileSize:0,sha256sum:``}},download:{data:/* @__PURE__ */ new Uint8Array,metadata:{contentType:``,fileSize:0,sha256sum:``,lastUploadedAt:``}},downloadAsBase64:{data:``,metadata:{contentType:``,fileSize:0,sha256sum:``,lastUploadedAt:``}},getMetadata:{contentType:``,fileSize:0,sha256sum:``,urlPath:``},downloadStream:null,uploadStream:{metadata:{fileSize:0,sha256sum:``}}};function mockFile(e={}){let t=m(),n=t.file,{onUnhandled:r=`fallback`}=e,i=[],a=[],resolver=()=>null;function handle(e,t,n,a,o){if(i.length>0)return i.shift();let s=resolver(e,{method:e,namespace:t,tableName:n,fieldName:a,recordId:o});if(s!=null)return s;if(r===`error`)throw Error(`No File mock configured for "${e}"`);let c=G[e];return c===void 0?void 0:structuredClone(c)}let o=L.fn(async(...e)=>{let[t,n,r,i]=e;return handle(`upload`,t,n,r,i)}),s=L.fn(async(...e)=>handle(`download`,...e)),c=L.fn(async(...e)=>handle(`downloadAsBase64`,...e)),l=L.fn(async(...e)=>{handle(`delete`,...e)}),u=L.fn(async(...e)=>handle(`getMetadata`,...e)),d=L.fn(async(...e)=>handle(`downloadStream`,...e)??{body:new ReadableStream({start(e){e.close()}}),metadata:{contentType:``,fileSize:0,sha256sum:``,lastUploadedAt:``}}),p=L.fn(async(...e)=>{let[t,n,r,i]=e;return handle(`uploadStream`,t,n,r,i)}),h={upload:o,download:s,downloadAsBase64:c,delete:l,getMetadata:u,downloadStream:d,uploadStream:p};function track(e,t){return function(...n){return a.push({method:e,namespace:n[0],tableName:n[1],fieldName:n[2],recordId:n[3]}),t.apply(this,n)}}t.file={upload:track(`upload`,o),download:track(`download`,s),downloadAsBase64:track(`downloadAsBase64`,c),delete:track(`delete`,l),getMetadata:track(`getMetadata`,u),downloadStream:track(`downloadStream`,d),uploadStream:track(`uploadStream`,p)};function allMocks(){return W.map(e=>h[e])}let g={...h,setResolver(e){resolver=e},enqueueResult(e){i.push(e)},enqueueResults(...e){i.push(...e)},get calls(){return a},clear(){a.length=0;for(let e of allMocks())e.mockClear()},reset(){i.length=0,a.length=0,resolver=()=>null;for(let e of allMocks())e.mockReset()}};return f(g,()=>{t.file=n})}function isUtf8(e){return e===`UTF8`||e===`UTF-8`}function defaultIconvResult(e,t){switch(e){case`convert`:case`convertBuffer`:return isUtf8(t[2])?``:/* @__PURE__ */ new Uint8Array;case`decode`:return``;case`encode`:return isUtf8(t[1])?``:/* @__PURE__ */ new Uint8Array;case`encodings`:return[]}}function mockIconv(e={}){let t=p(),n=t.iconv,r=null,i=[];function resolve(t,n){if(r){let e=r(t,n);if(e!=null)return e}if(e.onUnhandled===`error`)throw Error(`No Iconv mock behavior configured for "${t}"`);return defaultIconvResult(t,n)}function defaultConvert(e,t,n){return resolve(`convert`,[e,t,n])}function defaultConvertBuffer(e,t,n){return resolve(`convertBuffer`,[e,t,n])}function defaultDecode(e,t){return resolve(`decode`,[e,t])}function defaultEncode(e,t){return resolve(`encode`,[e,t])}function defaultEncodings(){return resolve(`encodings`,[])}let a=L.fn(defaultConvert),o=L.fn(defaultConvertBuffer),s=L.fn(defaultDecode),c=L.fn(defaultEncode),l=L.fn(defaultEncodings);function track(e,t){return function(...n){return i.push({method:e,args:[...n]}),t.apply(this,n)}}let u=track(`convert`,a),d=track(`convertBuffer`,o),m=track(`decode`,s),h=track(`encode`,c),g=track(`encodings`,l);class MockIconv{#e;#t;constructor(e,t){this.#e=e,this.#t=t}convert(e){return u.call(this,e,this.#e,this.#t)}}t.iconv={convert:u,convertBuffer:d,decode:m,encode:h,encodings:g,Iconv:MockIconv};function clear(){i.length=0,a.mockClear(),o.mockClear(),s.mockClear(),c.mockClear(),l.mockClear()}return f({convert:a,convertBuffer:o,decode:s,encode:c,encodings:l,setResolver(e){r=e},get calls(){return i},clear,reset(){r=null,i.length=0,a.mockReset(),a.mockImplementation(defaultConvert),o.mockReset(),o.mockImplementation(defaultConvertBuffer),s.mockReset(),s.mockImplementation(defaultDecode),c.mockReset(),c.mockImplementation(defaultEncode),l.mockReset(),l.mockImplementation(defaultEncodings)}},()=>{t.iconv=n})}const K=[`users`,`user`,`userByName`,`createUser`,`updateUser`,`deleteUser`,`sendPasswordResetEmail`,`unenrollMfa`],q={id:`mock-id`,name:`mock-user`,disabled:!1,mfaEnrolled:!1,mfaFactorIds:[]},J={users:{users:[],nextPageToken:null,totalCount:0},user:q,userByName:q,createUser:q,updateUser:q,deleteUser:!0,sendPasswordResetEmail:!0,unenrollMfa:!0};function mockIdp(e={}){let t=p(),n=t.idp,{onUnhandled:r=`fallback`}=e,i=[],a=[],resolver=()=>null,o=/* @__PURE__ */ new Map;function compatibilityArgs(e,t){return e===`users`&&t.length===0?[void 0]:t}function handle(e,t,n){if(i.length>0)return i.shift();let a=resolver(e,compatibilityArgs(e,t),n);if(a!=null)return a;if(r===`error`)throw Error(`No IdP mock configured for "${n}.${e}"`);return structuredClone(J[e])}function createNamespaceMocks(e){return{users:L.fn(async(...t)=>handle(`users`,t,e)),user:L.fn(async(...t)=>handle(`user`,t,e)),userByName:L.fn(async(...t)=>handle(`userByName`,t,e)),createUser:L.fn(async(...t)=>handle(`createUser`,t,e)),updateUser:L.fn(async(...t)=>handle(`updateUser`,t,e)),deleteUser:L.fn(async(...t)=>handle(`deleteUser`,t,e)),sendPasswordResetEmail:L.fn(async(...t)=>handle(`sendPasswordResetEmail`,t,e)),unenrollMfa:L.fn(async(...t)=>handle(`unenrollMfa`,t,e))}}function namespace(e){let t=o.get(e);if(t)return t;let n=createNamespaceMocks(e);return o.set(e,n),n}function track(e,t,n){return function(...r){return a.push({method:e,args:[...compatibilityArgs(e,r)],namespace:n}),t.apply(this,r)}}let defaultClient=function(e){let t=namespace(e.namespace);this.users=track(`users`,t.users,e.namespace),this.user=track(`user`,t.user,e.namespace),this.userByName=track(`userByName`,t.userByName,e.namespace),this.createUser=track(`createUser`,t.createUser,e.namespace),this.updateUser=track(`updateUser`,t.updateUser,e.namespace),this.deleteUser=track(`deleteUser`,t.deleteUser,e.namespace),this.sendPasswordResetEmail=track(`sendPasswordResetEmail`,t.sendPasswordResetEmail,e.namespace),this.unenrollMfa=track(`unenrollMfa`,t.unenrollMfa,e.namespace)},s=L.fn(defaultClient);t.idp={Client:s};function allMocks(){return[...o.values()].flatMap(e=>K.map(t=>e[t]))}return f({Client:s,namespace,setResolver(e){resolver=e},enqueueResult(e){i.push(e)},enqueueResults(...e){i.push(...e)},get calls(){return a},clear(){a.length=0,s.mockClear();for(let e of allMocks())e.mockClear()},reset(){i.length=0,a.length=0,resolver=()=>null,s.mockReset(),s.mockImplementation(defaultClient);for(let e of allMocks())e.mockReset()}},()=>{t.idp=n})}function mockLogger(e={}){let t=p(),n=t.logger,r=L.fn((e,t)=>{}),i=L.fn((e,t)=>{}),a=L.fn((e,t)=>{}),o=L.fn((e,t)=>{}),s=L.fn(e=>{});t.logger={debug:r,info:i,warn:a,error:o,setAttributes:s};let c={debug:r,info:i,warn:a,error:o};return f({debug:r,info:i,warn:a,error:o,setAttributes:s,get calls(){return Object.entries(c).flatMap(([e,t])=>t.mock.calls.map((n,r)=>({order:t.mock.invocationCallOrder[r]??0,call:{severity:e,message:n[0],attributes:n[1]}}))).toSorted((e,t)=>e.order-t.order).map(e=>e.call)},clear(){r.mockClear(),i.mockClear(),a.mockClear(),o.mockClear(),s.mockClear()},reset(){r.mockReset(),i.mockReset(),a.mockReset(),o.mockReset(),s.mockReset()}},()=>{t.logger=n})}function testRegex(e,t){let n=e.lastIndex;e.lastIndex=0;try{return e.test(t)}finally{e.lastIndex=n}}var MockQueryResult=class{command;rowCount;rows;constructor(e){this.command=``,this.rowCount=e.length,this.rows=e}};function mockTailordb(e={}){let t=m(),n=t.Client,r=[],i;function matchesQuery(e,t,n){if(typeof e==`function`)return e(t,n);if(typeof e==`string`)return t===e;if(e instanceof RegExp)return testRegex(e,t);let r;if(r=typeof e.sql==`string`?t===e.sql:testRegex(e.sql,t),!r||e.params===void 0)return r;if(typeof e.params==`function`)return e.params(n);let i=e.params;return n.length===i.length&&n.every((e,t)=>_(e,i[t]))}function queryResponse(e){if(e.type===`error`)throw e.error;return new MockQueryResult(e.rows)}async function defaultQuery(t,n=[]){for(let e=r.length-1;e>=0;--e){let i=r[e];if(!i||!matchesQuery(i.matcher,t,n))continue;let a=i.once.shift();if(a)return queryResponse(a);if(i.fallback)return queryResponse(i.fallback)}if(i)return new MockQueryResult(i(t,n)??[]);if(e.onUnhandled===`error`)throw Error(`No TailorDB query behavior matched: ${t}`);return new MockQueryResult([])}let a=L.fn(defaultQuery),defaultConnect=async()=>{},o=L.fn(defaultConnect),s=[];function enqueueRowsList(e){for(let t of e)a.mockImplementationOnce(async()=>new MockQueryResult(t))}let defaultClient=function(e){let t={namespace:e?.namespace,ended:!1};s.push(t),this.connect=o,this.end=L.fn(async()=>{t.ended=!0}),this.queryObject=a,this.createTransaction=e=>{if(!e)throw Error(`Transaction name must be a non-empty string`);return{begin:async()=>{},commit:async()=>{},rollback:async()=>{},queryObject:a}}},c=L.fn(defaultClient);return t.Client=c,f({Client:c,queryObject:a,setQueryResolver(e){i=e,a.mockImplementation(defaultQuery)},onQuery(e){let t={matcher:e,once:[]};r.push(t);let n={returnsRows(e){return t.fallback={type:`rows`,rows:e},n},returnsRowsOnce(e){return t.once.push({type:`rows`,rows:e}),n},rejects(e){return t.fallback={type:`error`,error:e},n},rejectsOnce(e){return t.once.push({type:`error`,error:e}),n}};return n},enqueueResult(...e){enqueueRowsList([e])},enqueueResults(...e){enqueueRowsList(e)},enqueueRows(...e){enqueueRowsList(e)},get executedQueries(){return a.mock.calls.map(([e,t])=>({query:e,params:t??[]}))},get createdClients(){return s},clear(){a.mockClear(),o.mockClear(),c.mockClear(),s.length=0},reset(){a.mockReset(),a.mockImplementation(defaultQuery),o.mockReset(),o.mockImplementation(defaultConnect),c.mockReset(),c.mockImplementation(defaultClient),s.length=0,r.length=0,i=void 0}},()=>{t.Client=n})}const Y=/* @__PURE__ */ new WeakMap,X=/* @__PURE__ */ new WeakMap,Z=/* @__PURE__ */ new WeakMap;function replaceProcedure(e,t,n){let r=Z.get(n)??n,i=L.fn(function(...e){return Reflect.apply(r,this,e)});Z.set(i,r);let a=e;return a[t]=i,{mock:i,scoped:{mockClear:()=>i.mockClear(),mockReset:()=>i.mockReset(),restore:()=>{a[t]===i&&(a[t]=n)}}}}function replaceStart(e){return replaceProcedure(e,`start`,e.start)}function mockWorkflow(){let e=p(),a=e.workflow,c=r(),l=/* @__PURE__ */ new Map,u=/* @__PURE__ */ new Map,m=/* @__PURE__ */ new Map,h=/* @__PURE__ */ new Map,g=/* @__PURE__ */ new Set,installKeyDispatcher=e=>{let t=h.get(e);if(t)return t;let n=i(e);if(!n)throw Error(`waitPointWith expects a wait point definition created by createWaitPoint or createWaitPoints.`);let r=n,a=n.wait,o=n.resolve,s=Y.get(a)??a,c=X.get(o)??o,l={perKey:/* @__PURE__ */ new Map,originalWait:(e,t)=>s.call(n,e,t),originalResolve:(e,t,r)=>c.call(n,e,t,r)},dispatchWait=(e,t)=>{let n=l.perKey.get(e);return n?t===void 0?n.wait():n.wait(t):l.originalWait(e,t)},dispatchResolve=async(e,t,n)=>{let r=l.perKey.get(e);if(!r)return l.originalResolve(e,t,n);await r.resolve(t,n)};Y.set(dispatchWait,s),X.set(dispatchResolve,c),r.wait=dispatchWait,r.resolve=dispatchResolve;let eachSpy=e=>{for(let t of l.perKey.values()){let n=t;e(n.wait),e(n.resolve)}};return g.add({mockClear:()=>eachSpy(e=>e.mockClear()),mockReset:()=>eachSpy(e=>e.mockReset()),restore:()=>{r.wait=a,r.resolve=o,h.delete(e)}}),h.set(e,l),l},defaultExecJob=(e,t,n)=>{throw Error(`No workflow job mock for "${e}". Call mockWorkflow().setJobHandler(...) or enqueueResult(...), or use runWorkflowLocally() for local workflow execution.`)},defaultStartWorkflow=async(e,n,r)=>t,defaultResumeWorkflowExecution=async e=>e,_=L.fn(defaultExecJob),v=L.fn(defaultStartWorkflow),y=L.fn(defaultResumeWorkflowExecution),b=L.fn((e,t)=>null),x=L.fn(async(e,t,n)=>{});return e.workflow={execJobFunction:(...e)=>{let t=e.length>=3?_(e[0],d(e[1]),e[2]):_(e[0],d(e[1]));return t instanceof Promise?t.then(e=>d(e)):d(t)},startWorkflow:(...e)=>e.length>=3?v(e[0],d(e[1]),e[2]):v(e[0],d(e[1])),resumeWorkflowExecution:e=>y(e),wait:(e,t)=>b(e,d(t)),resolve:(e,t,n)=>x(e,t,e=>{let t=n(e);return t instanceof Promise?t.then(e=>d(e)):d(t)})},f({execJobFunction:_,startWorkflow:v,resumeWorkflowExecution:y,wait:b,resolve:x,job(e){let t=l.get(e);if(t)return t;let{mock:n,scoped:r}=replaceStart(e);return g.add(r),l.set(e,n),n},workflow(e){let t=u.get(e);if(t)return t;let{mock:n,scoped:r}=replaceStart(e);return u.set(e,n),g.add(r),n},waitPoint(e){let t=m.get(e);if(t)return t;let n=replaceProcedure(e,`wait`,e.wait),r=replaceProcedure(e,`resolve`,e.resolve),i=n.mock,a=r.mock;g.add(n.scoped),g.add(r.scoped);let o={wait:i,resolve:a,setResolvePayload(e){a.mockImplementation(async(t,n)=>{let r=await n(d(e));d(r)})}};return m.set(e,o),o},waitPointWith(e,t){let r=n(e.with(t));if(r===void 0)throw Error(`waitPointWith expects a wait point declared with $params. Use waitPoint() for a wait point with a fixed key.`);let i=installKeyDispatcher(e),a=i.perKey.get(r);if(a)return a;let o=L.fn(e=>Promise.resolve(i.originalWait(r,e))),s=L.fn((e,t)=>i.originalResolve(r,e,t)),c={wait:o,resolve:s,setResolvePayload(e){s.mockImplementation(async(t,n)=>{let r=await n(d(e));d(r)})}};return i.perKey.set(r,c),c},setJobHandler(e){_.mockImplementation((t,n,r)=>e(t,n,r))},enqueueResult(e){_.mockImplementationOnce(()=>e)},enqueueResults(...e){for(let t of e)_.mockImplementationOnce(()=>t)},get startedJobs(){return _.mock.calls.map(([e,t,n])=>({jobName:e,args:t,...n!==void 0&&{options:n}}))},setStartHandler(e){v.mockImplementation(typeof e==`function`?async(t,n,r)=>e(t,n,r):async()=>e)},setResumeHandler(e){y.mockImplementation(typeof e==`function`?async t=>e(t):async()=>e)},setWaitHandler:e=>{b.mockImplementation(typeof e==`function`?(t,n)=>e(t,n):()=>e)},setEnv(e){s({...e})},setResolveHandler(e){x.mockImplementation(async(t,n,r)=>{await e(t,n,r)})},get waitCalls(){return b.mock.calls.map(([e,t])=>({key:e,payload:t}))},get resolveCalls(){return x.mock.calls.map(([e,t])=>({executionId:e,key:t}))},clear(){_.mockClear(),v.mockClear(),y.mockClear(),b.mockClear(),x.mockClear();for(let e of g)e.mockClear()},reset(){_.mockReset(),_.mockImplementation(defaultExecJob),v.mockReset(),v.mockImplementation(defaultStartWorkflow),y.mockReset(),y.mockImplementation(defaultResumeWorkflowExecution),b.mockReset(),b.mockImplementation(()=>null),x.mockReset(),x.mockImplementation(async()=>{});for(let e of g)e.mockReset();o()}},()=>{for(let e of g)e.restore();e.workflow=a,c===void 0?o():s(c)})}var TransactionLock=class{#e=null;#t=[];holds(e){return this.#e===e}async acquire(e){for(;this.#e!==null;)await new Promise(e=>this.#t.push(e));this.#e=e}release(e){this.#e===e&&(this.#e=null,this.#t.shift()?.())}};const Q=/^\s*(?:begin|start\s+transaction)\b/i,$=/^\s*(?:commit\b|rollback\b(?!(?:\s+(?:work|transaction))?\s+to\b))/i;function toQueryObjectResult(e){return{command:e.command??(e.affectedRows?`UPDATE`:`SELECT`),rowCount:e.rowCount??(e.affectedRows||e.rows.length),rows:e.rows}}function mockTailordbWithPGlite(e){let t=m(),n=t.Client,r=[],i=[],a=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Set,assertNoOpenTransaction=e=>{if(o.size>0)throw Error(`mockTailordbWithPGlite: ${e}() cannot run while a transaction is open; commit, roll back, or end() its client first`)},defaultClient=function(t){let n=t?.namespace,s=n!==void 0&&Object.hasOwn(e.namespaces,n)?e.namespaces[n]:void 0;if(n===void 0||!s)throw Error(`mockTailordbWithPGlite: no PGlite instance registered for namespace "${n}"`);let c=a.get(s)??new TransactionLock;a.set(s,c);let l={namespace:n,ended:!1};i.push(l);let u=this,run=async(e,t)=>(r.push({namespace:n,query:e,params:t??[]}),toQueryObjectResult(await s.query(e,t??[]))),throwEnded=()=>{throw Error(`mockTailordbWithPGlite: query after end() on this client`)},acquire=async()=>{await c.acquire(u),l.ended&&(c.release(u),throwEnded())},queryObject=async(e,t)=>{if(l.ended&&throwEnded(),Q.test(e)){if(c.holds(u))throw Error(`mockTailordbWithPGlite: transaction already open on this client — run nested statements on the transaction callback's trx`);await acquire();try{let n=await run(e,t);return o.add(l),n}catch(e){throw c.release(u),e}}if($.test(e)){if(c.holds(u))try{return await run(e,t)}finally{o.delete(l),c.release(u)}await acquire();try{return await run(e,t)}finally{c.release(u)}}if(c.holds(u))return await run(e,t);await acquire();try{return await run(e,t)}finally{c.release(u)}};this.connect=async()=>{},this.end=async()=>{if(l.ended=!0,c.holds(u))try{await run(`rollback`)}finally{o.delete(l),c.release(u)}},this.queryObject=queryObject,this.createTransaction=e=>{if(!e)throw Error(`Transaction name must be a non-empty string`);return{begin:()=>queryObject(`begin`),commit:()=>queryObject(`commit`),rollback:()=>queryObject(`rollback`),queryObject}}},s=L.fn(defaultClient);return t.Client=s,f({Client:s,get executedQueries(){return r},get createdClients(){return i},clear(){assertNoOpenTransaction(`clear`),s.mockClear(),r.length=0,i.length=0},reset(){assertNoOpenTransaction(`reset`),s.mockReset(),s.mockImplementation(defaultClient),r.length=0,i.length=0}},()=>{t.Client=n})}var PendingStart=class{jobName;args;constructor(e,t){this.jobName=e,this.args=t}};async function runWorkflowLocally(e,t,n){let i=globalThis,a=i.tailor,c=r(),l=c!==void 0,u=createLocalJobRunner();n?.env!==void 0&&s({...n.env}),i.tailor={...a,workflow:createLocalWorkflowRuntime(a?.workflow,u.execJobFunction)};try{return await u.runJob(e.mainJob.name,t)}finally{a?i.tailor=a:delete i.tailor,n?.env!==void 0&&(l?s(c):o())}}function createLocalJobRunner(){let t,execJobFunction=(e,n)=>{if(!t)throw Error(`Cannot start workflow job "${e}" outside runWorkflowLocally() job execution.`);if(t.pending)throw t.pending;let r=d(n),i=t.cursor;t.cursor+=1;let a=t.records[i];if(a){if(assertSameStart(a,e,r),a.status===`rejected`)throw a.error;return d(a.result)}let o=new PendingStart(e,r);throw t.pending=o,o},runJob=async(n,r)=>{let i=e(n);if(!i)return null;let o=[];for(;;){let e={records:o,cursor:0},s=t;t=e;try{let t=await i(d(r),a());if(e.pending){await settlePendingStart(o,e.pending,runJob);continue}if(e.cursor!==o.length)throw Error(`Workflow job start sequence changed while replaying "${n}". Expected ${o.length} start(s), but replay reached ${e.cursor}.`);return d(t)}catch(t){let n=t instanceof PendingStart?t:e.pending;if(n){await settlePendingStart(o,n,runJob);continue}throw t}finally{t=s}}};return{runJob,execJobFunction}}async function settlePendingStart(e,t,n){try{e.push({jobName:t.jobName,args:t.args,status:`fulfilled`,result:await n(t.jobName,t.args)})}catch(n){e.push({jobName:t.jobName,args:t.args,status:`rejected`,error:n})}}function assertSameStart(e,t,n){if(e.jobName!==t||JSON.stringify(e.args)!==JSON.stringify(n))throw Error(`Workflow job start sequence changed while replaying. Expected ${e.jobName}(${JSON.stringify(e.args)}), but got ${t}(${JSON.stringify(n)}).`)}function createLocalWorkflowRuntime(e,n){return{execJobFunction:n,startWorkflow:async(n,r,i)=>e?await e.startWorkflow(n,r,i):(d(r),t),resumeWorkflowExecution:async t=>e?await e.resumeWorkflowExecution(t):t,wait:(t,n)=>{if(e)return e.wait(t,n);throw Error(`No wait handler for "${t}". Acquire mockWorkflow() and call setWaitHandler(...).`)},resolve:async(t,n,r)=>{if(e){await e.resolve(t,n,r);return}throw Error(`No resolve handler. Acquire mockWorkflow() and call setResolveHandler(...).`)}}}function unwrapValue(e){return A.is(e)?e.value:e}function insertRows(e){if(!x.is(e))throw Error(`insertRows: expected InsertQueryNode, got ${e.kind}`);let t=e.columns,n=e.values;if(t===void 0||n===void 0||!j.is(n))throw Error(`insertRows: unsupported insert shape; inspect query.node instead`);return n.values.map(e=>{if(!E.is(e)&&!k.is(e))throw Error(`insertRows: unsupported insert shape; inspect query.node instead`);let n=E.is(e)?e.values:e.values.map(unwrapValue),r={};return t.forEach((e,t)=>{r[e.column.name]=n[t]}),r})}function insertValues(e){let t=insertRows(e);if(t.length!==1)throw Error(`insertValues: query inserts ${t.length} rows; use insertRows() for multi-row inserts`);return c(t[0],`insertValues: first row missing`)}function updateValues(e){if(!O.is(e))throw Error(`updateValues: expected UpdateQueryNode, got ${e.kind}`);if(e.updates===void 0)throw Error(`updateValues: unsupported update shape; inspect query.node instead`);let t={};for(let n of e.updates){let e=n.column,r=y.is(e)?e.column.name:D.is(e)&&y.is(e.column)?e.column.column.name:void 0;if(r===void 0)throw Error(`updateValues: unsupported update shape; inspect query.node instead`);t[r]=unwrapValue(n.value)}return t}function toExecutedQuery(e){let t=e.query;return{kind:t.kind,sql:e.sql,parameters:e.parameters,node:t,insertRows:()=>insertRows(t),insertValues:()=>insertValues(t),updateValues:()=>updateValues(t)}}function toStagedResult(e){return Array.isArray(e)?{rows:e,numAffectedRows:void 0}:{rows:e.rows??[],numAffectedRows:e.numAffectedRows===void 0?void 0:BigInt(e.numAffectedRows)}}var MockState=class{executed=[];queue=[];resolver;enqueue(...e){this.queue.push(...e)}setResolver(e){this.resolver=e}next(e){let t=this.resolver?.(e);if(t!==void 0)return toStagedResult(t);let n=this.queue.shift();return n===void 0?{rows:[],numAffectedRows:void 0}:toStagedResult(n)}reset(){this.executed.length=0,this.queue.length=0,this.resolver=void 0}},MockConnection=class{state;constructor(e){this.state=e}async executeQuery(e){let t=toExecutedQuery(e);this.state.executed.push(t);let{rows:n,numAffectedRows:r}=this.state.next(t);return{rows:n,numAffectedRows:r??BigInt(n.length)}}streamQuery(){throw Error(`createKyselyMock: streaming is not supported`)}},MockDriver=class{state;constructor(e){this.state=e}async init(){}async acquireConnection(){return new MockConnection(this.state)}async beginTransaction(){}async commitTransaction(){}async rollbackTransaction(){}async releaseConnection(){}async destroy(){}};function byKind(e,t){return e.executed.filter(e=>e.kind===t)}function createKyselyMock(){let e=new MockState,t=new S({dialect:{createDriver:()=>new MockDriver(e),createQueryCompiler:()=>new T,createAdapter:()=>new C,createIntrospector:e=>new w(e)}});return{db:t,get executedQueries(){return e.executed},get selects(){return byKind(e,`SelectQueryNode`)},get inserts(){return byKind(e,`InsertQueryNode`)},get updates(){return byKind(e,`UpdateQueryNode`)},get deletes(){return byKind(e,`DeleteQueryNode`)},enqueueResult:t=>e.enqueue(t),enqueueResults:(...t)=>e.enqueue(...t),setQueryResolver:t=>e.setResolver(t),withTx:e=>t.transaction().execute(e),reset:()=>e.reset(),[Symbol.dispose]:()=>e.reset()}}var PGliteConnection=class{#e;constructor(e){this.#e=e}async executeQuery(e){let t=await this.#e.query(e.sql,[...e.parameters]);return{rows:t.rows,numAffectedRows:BigInt(t.affectedRows??0)}}streamQuery(){throw Error(`createKyselyPGlite: streaming is not supported`)}},PGliteDriver=class{#e;constructor(e){this.#e=e}async init(){}async acquireConnection(){return new PGliteConnection(this.#e)}async beginTransaction(e,t){let n=t.isolationLevel?[`start transaction`,`isolation level ${t.isolationLevel}`]:[`begin`];t.accessMode&&n.push(t.accessMode),await e.executeQuery(b.raw(n.join(` `)))}async commitTransaction(e){await e.executeQuery(b.raw(`commit`))}async rollbackTransaction(e){await e.executeQuery(b.raw(`rollback`))}async releaseConnection(){}async destroy(){await this.#e.close()}};function createKyselyPGlite(e){return new S({dialect:{createAdapter:()=>new C,createDriver:()=>new PGliteDriver(e),createIntrospector:e=>new w(e),createQueryCompiler:()=>new T}})}function tailorRuntime(e){return[createBlockPlugin(),createEnvironmentPlugin(e)]}export{createKyselyMock,createKyselyPGlite,mockAigateway,mockAuthconnection,mockFile,mockIconv,mockIdp,mockLogger,h as mockSecretmanager,mockTailordb,mockTailordbWithPGlite,mockWorkflow,runWorkflowLocally,tailorRuntime};
2
2
  //# sourceMappingURL=index.mjs.map