@autonoma-ai/sdk 0.1.4 → 0.1.7

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.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { H as HandlerConfig, a as HandlerRequest, b as HandlerResponse, S as SchemaInfo, c as SQLExecutor, d as ScenarioDefinition, R as ResolvedEntitySpec, C as CreateContext } from './graph-DY4OdpZ4.js';
2
2
  export { A as AuthCookie, e as AuthResult, D as DiscoverResponse, f as DownResponse, F as FKEdge, g as FieldInfo, M as ModelInfo, h as SchemaRelation, i as SdkInfo, U as UpResponse, j as findDeferrableEdge, t as topoSort } from './graph-DY4OdpZ4.js';
3
3
 
4
- declare const PROTOCOL_VERSION = "1.0";
4
+ declare const PROTOCOL_VERSION: string;
5
5
  declare function handleRequest(config: HandlerConfig, req: HandlerRequest): Promise<HandlerResponse>;
6
6
 
7
7
  declare function signBody(body: string, secret: string): string;
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ function verifySignature(body, signature, secret) {
15
15
  }
16
16
 
17
17
  // src/refs.ts
18
- import { createHmac as createHmac2 } from "crypto";
18
+ import { createHmac as createHmac2, timingSafeEqual as timingSafeEqual2 } from "crypto";
19
19
  function signRefs(payload, secret) {
20
20
  const header = base64url({ alg: "HS256", typ: "REFS" });
21
21
  const body = base64url(payload);
@@ -27,7 +27,11 @@ function verifyRefs(token, secret) {
27
27
  if (parts.length !== 3) throw new Error("malformed token");
28
28
  const [header, body, signature] = parts;
29
29
  const expected = hmac(`${header}.${body}`, secret);
30
- if (expected !== signature) throw new Error("signature mismatch");
30
+ const expectedBuf = Buffer.from(expected);
31
+ const signatureBuf = Buffer.from(signature);
32
+ if (expectedBuf.length !== signatureBuf.length || !timingSafeEqual2(expectedBuf, signatureBuf)) {
33
+ throw new Error("signature mismatch");
34
+ }
31
35
  return JSON.parse(Buffer.from(body, "base64url").toString());
32
36
  }
33
37
  function base64url(obj) {
@@ -553,6 +557,7 @@ function parseMySQLEnum(columnType) {
553
557
  }
554
558
  function mapDataType(dataType, udtName, dialectName) {
555
559
  const dt = dataType.toLowerCase();
560
+ if (dialectName === "mysql" && dt === "tinyint" && udtName.toLowerCase().startsWith("tinyint(1)")) return "Boolean";
556
561
  if (dt === "integer" || dt === "smallint" || dt === "bigint" || dt === "int" || dt === "mediumint" || dt === "tinyint") return "Int";
557
562
  if (dt === "numeric" || dt === "real" || dt === "double precision" || dt === "float" || dt === "double" || dt === "decimal") return "Float";
558
563
  if (dt === "boolean" || dt === "tinyint(1)") return "Boolean";
@@ -694,7 +699,21 @@ async function insertBatch(executor, dialect, dbTable, colMap, enumTypeMap, fiel
694
699
  return fields;
695
700
  });
696
701
  }
697
- const fieldNames = Object.keys(fieldsArr[0]);
702
+ const fieldNameSet = /* @__PURE__ */ new Set();
703
+ for (const fields of fieldsArr) {
704
+ for (const key of Object.keys(fields)) {
705
+ fieldNameSet.add(key);
706
+ }
707
+ }
708
+ const fieldNames = [...fieldNameSet].sort();
709
+ if (fieldNames.length === 0) {
710
+ const allResults2 = [];
711
+ for (const fields of fieldsArr) {
712
+ const [record] = await insertOne(executor, dialect, dbTable, colMap, enumTypeMap, fields);
713
+ if (record) allResults2.push(record);
714
+ }
715
+ return allResults2;
716
+ }
698
717
  const dbCols = fieldNames.map((f) => dialect.quoteId(colMap.get(f) ?? f));
699
718
  const colList = dbCols.join(", ");
700
719
  const MAX_PARAMS = 32e3;
@@ -759,13 +778,14 @@ function castParam(dialect, paramIdx, enumTypeMap, fieldName) {
759
778
  }
760
779
  return placeholder;
761
780
  }
781
+ var MYSQL_DATETIME_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/;
762
782
  function serializeValue(value, dialect) {
763
- if (value === null || value === void 0) return value;
783
+ if (value === null || value === void 0) return null;
764
784
  if (typeof value === "object" && !(value instanceof Date)) {
765
785
  return JSON.stringify(value);
766
786
  }
767
787
  if (typeof value === "string" && dialect.name === "mysql") {
768
- if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
788
+ if (MYSQL_DATETIME_RE.test(value)) {
769
789
  return value.replace("T", " ").replace("Z", "").replace(/\.\d+$/, "");
770
790
  }
771
791
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hmac.ts","../src/refs.ts","../src/template.ts","../src/tree.ts","../src/errors.ts","../src/generated/sql-queries.ts","../src/dialect.ts","../src/introspect.ts","../src/create.ts","../src/teardown.ts","../src/handler.ts","../src/fingerprint.ts","../src/check.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from 'node:crypto'\n\nexport function signBody(body: string, secret: string): string {\n return createHmac('sha256', secret).update(body).digest('hex')\n}\n\nexport function verifySignature(\n body: string,\n signature: string,\n secret: string,\n): boolean {\n const expected = signBody(body, secret)\n if (expected.length !== signature.length) return false\n return timingSafeEqual(Buffer.from(expected), Buffer.from(signature))\n}\n","import { createHmac } from 'node:crypto'\n\ninterface RefsPayload {\n refs: Record<string, Record<string, unknown>[]>\n testRunId: string\n environment: string\n}\n\n/**\n * Sign refs into a JWT-like token (header.payload.signature).\n * Uses HMAC-SHA256 — not a full JWT library to avoid dependencies.\n */\nexport function signRefs(payload: RefsPayload, secret: string): string {\n const header = base64url({ alg: 'HS256', typ: 'REFS' })\n const body = base64url(payload)\n const signature = hmac(`${header}.${body}`, secret)\n return `${header}.${body}.${signature}`\n}\n\n/**\n * Verify and decode a refs token. Returns the payload or throws.\n */\nexport function verifyRefs(\n token: string,\n secret: string,\n): RefsPayload {\n const parts = token.split('.')\n if (parts.length !== 3) throw new Error('malformed token')\n\n const [header, body, signature] = parts\n const expected = hmac(`${header}.${body}`, secret)\n\n if (expected !== signature) throw new Error('signature mismatch')\n\n return JSON.parse(Buffer.from(body!, 'base64url').toString())\n}\n\nfunction base64url(obj: unknown): string {\n return Buffer.from(JSON.stringify(obj)).toString('base64url')\n}\n\nfunction hmac(data: string, secret: string): string {\n return createHmac('sha256', secret).update(data).digest('base64url')\n}\n","const TEMPLATE_RE = /\\{\\{(.+?)\\}\\}/g\n\nexport interface TemplateContext {\n testRunId: string\n index: number\n}\n\n/**\n * Resolve all {{...}} expressions in a value. Handles strings, objects, and arrays recursively.\n */\nexport function resolveTemplate(value: unknown, ctx: TemplateContext): unknown {\n if (typeof value === 'string') return resolveString(value, ctx)\n if (Array.isArray(value)) return value.map((v) => resolveTemplate(v, ctx))\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n result[k] = resolveTemplate(v, ctx)\n }\n return result\n }\n return value\n}\n\nfunction resolveString(str: string, ctx: TemplateContext): unknown {\n // If the entire string is a single expression, return the raw value (preserving type)\n const fullMatch = str.match(/^\\{\\{(.+?)\\}\\}$/)\n if (fullMatch) {\n return evaluateExpression(fullMatch[1]!, ctx)\n }\n\n // Otherwise, interpolate expressions into the string\n return str.replace(TEMPLATE_RE, (_, expr: string) => {\n const val = evaluateExpression(expr, ctx)\n return String(val)\n })\n}\n\nfunction evaluateExpression(expr: string, ctx: TemplateContext): unknown {\n expr = expr.trim()\n\n // Simple variables\n if (expr === 'testRunId') return ctx.testRunId\n if (expr === 'index') return ctx.index\n if (expr === 'index1') return ctx.index + 1\n\n // cycle([...])\n const cycleMatch = expr.match(/^cycle\\(\\[(.+)\\]\\)$/)\n if (cycleMatch) {\n const items = parseArrayLiteral(cycleMatch[1]!)\n return items[ctx.index % items.length]\n }\n\n // pick([...])\n const pickMatch = expr.match(/^pick\\(\\[(.+)\\]\\)$/)\n if (pickMatch) {\n const items = parseArrayLiteral(pickMatch[1]!)\n return items[Math.floor(Math.random() * items.length)]\n }\n\n // random.int(a,b)\n const randIntMatch = expr.match(/^random\\.int\\((\\d+),\\s*(\\d+)\\)$/)\n if (randIntMatch) {\n const min = parseInt(randIntMatch[1]!, 10)\n const max = parseInt(randIntMatch[2]!, 10)\n return Math.floor(Math.random() * (max - min + 1)) + min\n }\n\n // random.float(a,b)\n const randFloatMatch = expr.match(/^random\\.float\\((\\d+(?:\\.\\d+)?),\\s*(\\d+(?:\\.\\d+)?)\\)$/)\n if (randFloatMatch) {\n const min = parseFloat(randFloatMatch[1]!)\n const max = parseFloat(randFloatMatch[2]!)\n return Math.random() * (max - min) + min\n }\n\n // now()\n if (expr === 'now()') return new Date().toISOString()\n\n // daysAgo(n)\n const daysAgoMatch = expr.match(/^daysAgo\\((\\d+)\\)$/)\n if (daysAgoMatch) {\n const d = new Date()\n d.setDate(d.getDate() - parseInt(daysAgoMatch[1]!, 10))\n return d.toISOString()\n }\n\n throw new Error(`Template error: unknown expression '${expr}'`)\n}\n\nfunction parseArrayLiteral(raw: string): string[] {\n return raw.split(',').map((s) => {\n s = s.trim()\n // Strip surrounding quotes\n if ((s.startsWith(\"'\") && s.endsWith(\"'\")) || (s.startsWith('\"') && s.endsWith('\"'))) {\n return s.slice(1, -1)\n }\n return s\n })\n}\n","import type { SchemaInfo, SchemaRelation } from './types'\nimport { resolveTemplate, type TemplateContext } from './template'\n\nconst RESERVED_KEYS = new Set(['_alias', '_ref', '_count', '_batch'])\n\n/** A create operation produced by the tree resolver */\nexport interface CreateOp {\n model: string\n fields: Record<string, unknown>\n tempId: string\n batch: boolean\n}\n\n/**\n * A deferred FK update — emitted when a _ref points to a node that hasn't\n * been created yet (circular dependency). Resolved after all creates.\n */\nexport interface DeferredUpdate {\n /** Temp ID of the record that needs to be updated */\n targetTempId: string\n /** Model name of the record to update */\n model: string\n /** Field on the record that holds the deferred FK */\n field: string\n /** Alias that will resolve to the FK value once created */\n refAlias: string\n}\n\n/** Result of resolving a tree scenario */\nexport interface ResolvedTree {\n ops: CreateOp[]\n deferredUpdates: DeferredUpdate[]\n aliases: Map<string, string>\n}\n\n/** A resolved reference to another node's id */\nexport interface RefNode {\n _ref: string\n}\n\n/**\n * Resolve a nested scenario tree into an ordered list of create operations.\n *\n * Walks depth-first. Parent-child FKs are wired automatically.\n * Handles both directions:\n * - FK on child (Application.organizationId → Organization): set child FK to parent ID\n * - FK on parent (Member.userId → User): create child first, set parent FK to child ID\n *\n * Circular FK cycles (e.g. Application.mainBranchId ↔ Branch.applicationId) are handled\n * transparently: the nullable FK is omitted on the first create and emitted as a\n * DeferredUpdate to be applied via UPDATE after all records exist.\n */\nexport function resolveTree(\n create: Record<string, Record<string, unknown>[]>,\n schema: SchemaInfo,\n testRunId: string,\n): ResolvedTree {\n const relationByParentField = new Map<string, SchemaRelation>()\n for (const rel of schema.relations) {\n relationByParentField.set(`${rel.parentModel}.${rel.parentField}`, rel)\n }\n\n // Determine FK direction for each relation:\n // Is childField on the parent model or the child model?\n const fkOnParent = new Set<string>() // key: \"parentModel.parentField\"\n for (const rel of schema.relations) {\n const edge = schema.edges.find(\n (e) => e.localField === rel.childField && (e.from === rel.parentModel || e.from === rel.childModel),\n )\n if (edge && edge.from === rel.parentModel) {\n // FK column is on the parent model → create child first, then set parent FK\n fkOnParent.add(`${rel.parentModel}.${rel.parentField}`)\n }\n }\n\n const aliases = new Map<string, string>()\n const ops: CreateOp[] = []\n const deferredUpdates: DeferredUpdate[] = []\n let tempCounter = 0\n\n function makeTempId(model: string): string {\n return `__temp_${model}_${tempCounter++}`\n }\n\n function walkNode(\n modelName: string,\n node: Record<string, unknown>,\n parentTempId: string | null,\n parentRelation: SchemaRelation | null,\n parentFkOnParent: boolean,\n index: number,\n ): string {\n const fields: Record<string, unknown> = {}\n const preChildren: Array<{ relation: SchemaRelation; value: unknown; fkOnParent: boolean }> = []\n const postChildren: Array<{ relation: SchemaRelation; value: unknown; fkOnParent: boolean }> = []\n const alias = node._alias as string | undefined\n const tempId = makeTempId(modelName)\n\n for (const [key, value] of Object.entries(node)) {\n if (RESERVED_KEYS.has(key)) continue\n\n // Look up relation by exact key, then try fallbacks:\n // 1. Model name prefix: Test.steps → Test.testSteps (Prisma abbreviated names)\n // 2. Child model name: Organization.Application → Organization.applications\n // (scenarios using PascalCase model names as relation keys)\n const exactKey = `${modelName}.${key}`\n const prefixedKey = `${modelName}.${modelName.charAt(0).toLowerCase()}${modelName.slice(1)}${key.charAt(0).toUpperCase()}${key.slice(1)}`\n let relation = relationByParentField.get(exactKey) ?? relationByParentField.get(prefixedKey) ?? undefined\n let matchedKey = relationByParentField.has(exactKey) ? exactKey : prefixedKey\n if (!relation) {\n // Fallback: match by child model name (PascalCase keys like Application, Tag)\n for (const [relKey, rel] of relationByParentField) {\n if (relKey.startsWith(`${modelName}.`) && rel.childModel.toLowerCase() === key.toLowerCase()) {\n relation = rel\n matchedKey = relKey\n break\n }\n }\n }\n if (relation) {\n const isOnParent = fkOnParent.has(matchedKey)\n if (isOnParent) {\n // FK is on this model → need to create the child BEFORE this node\n preChildren.push({ relation, value, fkOnParent: true })\n } else {\n // FK is on the child → create child AFTER this node (normal)\n postChildren.push({ relation, value, fkOnParent: false })\n }\n continue\n }\n\n if (value && typeof value === 'object' && '_ref' in value) {\n const refAlias = (value as RefNode)._ref\n const refTempId = aliases.get(refAlias)\n if (!refTempId) {\n // Alias not created yet — defer this FK as an UPDATE after all creates.\n // This handles circular FK cycles (e.g. Application.mainBranchId → Branch\n // where Branch.applicationId → Application).\n deferredUpdates.push({ targetTempId: tempId, model: modelName, field: key, refAlias })\n continue\n }\n fields[key] = refTempId\n continue\n }\n\n const ctx: TemplateContext = { testRunId, index, }\n fields[key] = resolveTemplate(value, ctx)\n }\n\n // Wire FK to parent (if this node is a child and FK is on the child)\n if (parentRelation && parentTempId && !parentFkOnParent) {\n fields[parentRelation.childField] = parentTempId\n }\n\n // Process pre-children: these need to be created BEFORE this node\n // because this node's FK points to them\n for (const { relation, value, fkOnParent: isOnParent } of preChildren) {\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const childTempId = walkNode(relation.childModel, value[i] as Record<string, unknown>, tempId, relation, true, i)\n // Set this node's FK to point to the created child\n fields[relation.childField] = childTempId\n }\n }\n }\n\n // Create this node\n ops.push({ model: modelName, fields, tempId, batch: false })\n if (alias) aliases.set(alias, tempId)\n\n // Process post-children: normal case, FK is on the child\n for (const { relation, value } of postChildren) {\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n walkNode(relation.childModel, value[i] as Record<string, unknown>, tempId, relation, false, i)\n }\n } else if (value && typeof value === 'object' && '_count' in value) {\n const bulk = value as Record<string, unknown>\n const count = bulk._count as number\n const isBatch = (bulk._batch as boolean) ?? false\n\n for (let i = 0; i < count; i++) {\n const bulkFields: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(bulk)) {\n if (k === '_count' || k === '_batch') continue\n const ctx: TemplateContext = { testRunId, index: i, }\n bulkFields[k] = resolveTemplate(v, ctx)\n }\n bulkFields[relation.childField] = tempId\n ops.push({ model: relation.childModel, fields: bulkFields, tempId: makeTempId(relation.childModel), batch: isBatch })\n }\n }\n }\n\n return tempId\n }\n\n for (const [modelName, nodes] of Object.entries(create)) {\n for (let i = 0; i < nodes.length; i++) {\n walkNode(modelName, nodes[i]!, null, null, false, i)\n }\n }\n\n return { ops, deferredUpdates, aliases }\n}\n","export class AutonomaError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly status: number,\n ) {\n super(message)\n this.name = 'AutonomaError'\n }\n}\n\nexport const Errors = {\n unknownAction(action: string) {\n return new AutonomaError(\n `Unknown action: ${action}`,\n 'UNKNOWN_ACTION',\n 400,\n )\n },\n unknownEnvironment(name: string) {\n return new AutonomaError(\n `Unknown environment: ${name}`,\n 'UNKNOWN_ENVIRONMENT',\n 400,\n )\n },\n invalidSignature() {\n return new AutonomaError(\n 'Invalid HMAC signature',\n 'INVALID_SIGNATURE',\n 401,\n )\n },\n invalidRefsToken(reason: string) {\n return new AutonomaError(\n `Invalid refs token: ${reason}`,\n 'INVALID_REFS_TOKEN',\n 403,\n )\n },\n productionBlocked() {\n return new AutonomaError(\n 'Environment factory is disabled in production',\n 'PRODUCTION_BLOCKED',\n 404,\n )\n },\n invalidBody(reason: string) {\n return new AutonomaError(\n `Invalid request body: ${reason}`,\n 'INVALID_BODY',\n 400,\n )\n },\n} as const\n","// AUTO-GENERATED by protocol/sql/codegen.ts — do not edit\n\nexport const POSTGRES_COLUMNS = `SELECT\n table_name,\n column_name,\n data_type,\n udt_name,\n is_nullable,\n column_default\nFROM information_schema.columns\nWHERE table_schema = '{{schema}}'\nORDER BY table_name, ordinal_position`\n\nexport const POSTGRES_ENUMS = `SELECT t.typname AS enum_name, e.enumlabel AS enum_value\nFROM pg_type t\nJOIN pg_enum e ON t.oid = e.enumtypid\nJOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\nORDER BY t.typname, e.enumsortorder`\n\nexport const POSTGRES_FOREIGN_KEYS = `SELECT\n kcu.table_name AS from_table,\n kcu.column_name AS from_column,\n ccu.table_name AS to_table,\n ccu.column_name AS to_column,\n c.is_nullable\nFROM information_schema.table_constraints tc\nJOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\nJOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n AND tc.table_schema = ccu.table_schema\nLEFT JOIN information_schema.columns c\n ON c.table_schema = kcu.table_schema\n AND c.table_name = kcu.table_name\n AND c.column_name = kcu.column_name\nWHERE tc.constraint_type = 'FOREIGN KEY'\n AND tc.table_schema = '{{schema}}'\nORDER BY kcu.table_name, kcu.ordinal_position`\n\nexport const POSTGRES_PRIMARY_KEYS = `SELECT\n tc.table_name,\n kcu.column_name\nFROM information_schema.table_constraints tc\nJOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\nWHERE tc.constraint_type = 'PRIMARY KEY'\n AND tc.table_schema = '{{schema}}'\nORDER BY tc.table_name, kcu.ordinal_position`\n\nexport const POSTGRES_TABLES = `SELECT table_name\nFROM information_schema.tables\nWHERE table_schema = '{{schema}}'\n AND table_type = 'BASE TABLE'\nORDER BY table_name`\n\nexport const MYSQL_COLUMNS = `SELECT\n table_name,\n column_name,\n data_type,\n column_type AS udt_name,\n is_nullable,\n column_default\nFROM information_schema.columns\nWHERE table_schema = '{{schema}}'\nORDER BY table_name, ordinal_position`\n\nexport const MYSQL_ENUMS = `SELECT NULL AS enum_name, NULL AS enum_value FROM DUAL WHERE 1 = 0`\n\nexport const MYSQL_FOREIGN_KEYS = `SELECT\n kcu.table_name AS from_table,\n kcu.column_name AS from_column,\n kcu.referenced_table_name AS to_table,\n kcu.referenced_column_name AS to_column,\n c.is_nullable\nFROM information_schema.key_column_usage kcu\nJOIN information_schema.columns c\n ON c.table_schema = kcu.table_schema\n AND c.table_name = kcu.table_name\n AND c.column_name = kcu.column_name\nWHERE kcu.referenced_table_name IS NOT NULL\n AND kcu.table_schema = '{{schema}}'\nORDER BY kcu.table_name, kcu.ordinal_position`\n\nexport const MYSQL_PRIMARY_KEYS = `SELECT\n tc.table_name,\n kcu.column_name\nFROM information_schema.table_constraints tc\nJOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n AND tc.table_name = kcu.table_name\nWHERE tc.constraint_type = 'PRIMARY KEY'\n AND tc.table_schema = '{{schema}}'\nORDER BY tc.table_name, kcu.ordinal_position`\n\nexport const MYSQL_TABLES = `SELECT table_name\nFROM information_schema.tables\nWHERE table_schema = '{{schema}}'\n AND table_type = 'BASE TABLE'\nORDER BY table_name`\n","/** Database dialect abstraction — generates dialect-specific SQL strings. */\n\nimport {\n POSTGRES_TABLES,\n POSTGRES_COLUMNS,\n POSTGRES_PRIMARY_KEYS,\n POSTGRES_FOREIGN_KEYS,\n POSTGRES_ENUMS,\n MYSQL_TABLES,\n MYSQL_COLUMNS,\n MYSQL_PRIMARY_KEYS,\n MYSQL_FOREIGN_KEYS,\n MYSQL_ENUMS,\n} from './generated/sql-queries'\n\nexport interface Dialect {\n readonly name: 'postgres' | 'mysql' | 'sqlite'\n /** Parameter placeholder for index (1-based). Postgres: $1, MySQL/SQLite: ? */\n param(index: number): string\n /** Quote an identifier. Postgres: \"name\", MySQL: `name` */\n quoteId(name: string): string\n /** Whether INSERT ... RETURNING is supported */\n readonly supportsReturning: boolean\n\n /** SQL to list all base tables in a schema/database */\n tablesSQL(schema: string): string\n /** SQL to list all columns for all tables in a schema/database */\n columnsSQL(schema: string): string\n /** SQL to list primary key columns */\n primaryKeysSQL(schema: string): string\n /** SQL to list foreign key relationships */\n foreignKeysSQL(schema: string): string\n /** SQL to list enum types and their values */\n enumsSQL(schema: string): string\n}\n\nconst replaceSchema = (template: string, schema: string) =>\n template.replace('{{schema}}', schema)\n\nexport const postgres: Dialect = {\n name: 'postgres',\n param: (i) => `$${i}`,\n quoteId: (name) => `\"${name}\"`,\n supportsReturning: true,\n\n tablesSQL: (schema) => replaceSchema(POSTGRES_TABLES, schema),\n columnsSQL: (schema) => replaceSchema(POSTGRES_COLUMNS, schema),\n primaryKeysSQL: (schema) => replaceSchema(POSTGRES_PRIMARY_KEYS, schema),\n foreignKeysSQL: (schema) => replaceSchema(POSTGRES_FOREIGN_KEYS, schema),\n enumsSQL: () => POSTGRES_ENUMS,\n}\n\nexport const mysql: Dialect = {\n name: 'mysql',\n param: () => '?',\n quoteId: (name) => `\\`${name}\\``,\n supportsReturning: false,\n\n tablesSQL: (schema) => replaceSchema(MYSQL_TABLES, schema),\n columnsSQL: (schema) => replaceSchema(MYSQL_COLUMNS, schema),\n primaryKeysSQL: (schema) => replaceSchema(MYSQL_PRIMARY_KEYS, schema),\n foreignKeysSQL: (schema) => replaceSchema(MYSQL_FOREIGN_KEYS, schema),\n enumsSQL: () => MYSQL_ENUMS,\n}\n\nexport function getDialect(name: 'postgres' | 'mysql' | 'sqlite' = 'postgres'): Dialect {\n switch (name) {\n case 'postgres':\n return postgres\n case 'mysql':\n return mysql\n default:\n throw new Error(`Dialect \"${name}\" is not yet supported. Currently only \"postgres\" and \"mysql\" are available.`)\n }\n}\n","import type { SQLExecutor, SchemaInfo, SchemaRelation, ModelInfo, FieldInfo, FKEdge } from './types'\nimport type { Dialect } from './dialect'\n\n/** Internal result including name mapping tables */\nexport interface IntrospectionResult {\n schema: SchemaInfo\n /** model name → DB table name */\n tableMap: Map<string, string>\n /** model name → (field name → DB column name) */\n columnMaps: Map<string, Map<string, string>>\n /** model name → (field name → Postgres enum type name). Only populated for Postgres. */\n enumTypeMaps: Map<string, Map<string, string>>\n}\n\ninterface TableRow { table_name: string }\ninterface ColumnRow {\n table_name: string\n column_name: string\n data_type: string\n udt_name: string\n is_nullable: string\n column_default: string | null\n}\ninterface PKRow { table_name: string; column_name: string }\ninterface FKRow {\n from_table: string\n from_column: string\n to_table: string\n to_column: string\n is_nullable: string\n}\ninterface EnumRow { enum_name: string; enum_value: string }\n\n/**\n * Introspect a database via information_schema to build SchemaInfo.\n *\n * Auto-maps DB names (snake_case) to model names (PascalCase) and\n * field names (camelCase). Override with `tableNameMap`.\n */\nexport async function introspectDatabase(\n executor: SQLExecutor,\n dialect: Dialect,\n config: {\n scopeField: string\n schema?: string\n tableNameMap?: Record<string, string>\n excludeTables?: string[]\n },\n): Promise<IntrospectionResult> {\n const dbSchema = config.schema ?? (dialect.name === 'mysql' ? undefined : 'public')\n if (!dbSchema) {\n throw new Error('MySQL requires a schema (database name). Pass it via config.schema or HandlerConfig.dbSchema.')\n }\n const excludeSet = new Set(config.excludeTables ?? ['_prisma_migrations'])\n\n // Run all introspection queries in parallel.\n // Normalize row keys to lowercase — MySQL's information_schema can return\n // column names in uppercase (TABLE_NAME vs table_name).\n const [tableRows, columnRows, pkRows, fkRows, enumRows] = await Promise.all([\n executor.query<TableRow>(dialect.tablesSQL(dbSchema)).then(normalizeKeys),\n executor.query<ColumnRow>(dialect.columnsSQL(dbSchema)).then(normalizeKeys),\n executor.query<PKRow>(dialect.primaryKeysSQL(dbSchema)).then(normalizeKeys),\n executor.query<FKRow>(dialect.foreignKeysSQL(dbSchema)).then(normalizeKeys),\n executor.query<EnumRow>(dialect.enumsSQL(dbSchema)).then(normalizeKeys),\n ])\n\n // Build enum lookup: name → values[]\n // For Postgres: from pg_type/pg_enum rows\n // For MySQL: extracted from column_type in the column rows below\n const enumValues = new Map<string, string[]>()\n for (const row of enumRows) {\n if (!row.enum_name) continue\n if (!enumValues.has(row.enum_name)) enumValues.set(row.enum_name, [])\n enumValues.get(row.enum_name)!.push(row.enum_value)\n }\n\n // For MySQL, parse inline enums from column_type (udt_name alias)\n // e.g. \"enum('WEB','ANDROID','IOS')\" → ['WEB','ANDROID','IOS']\n if (dialect.name === 'mysql') {\n for (const col of columnRows) {\n const parsed = parseMySQLEnum(col.udt_name)\n if (parsed) {\n const enumKey = `${col.table_name}.${col.column_name}`\n enumValues.set(enumKey, parsed)\n }\n }\n }\n\n // Build PK lookup: table_name → Set<column_name>\n const pksByTable = new Map<string, Set<string>>()\n for (const row of pkRows) {\n if (!pksByTable.has(row.table_name)) pksByTable.set(row.table_name, new Set())\n pksByTable.get(row.table_name)!.add(row.column_name)\n }\n\n // Build table name mapping\n const userMap = config.tableNameMap ?? {}\n const tableMap = new Map<string, string>()\n const reverseTableMap = new Map<string, string>()\n\n // First, register user-provided mappings\n for (const [model, dbTable] of Object.entries(userMap)) {\n tableMap.set(model, dbTable)\n reverseTableMap.set(dbTable, model)\n }\n\n // Then auto-map remaining tables\n const dbTables = tableRows\n .map((r) => r.table_name)\n .filter((t) => !excludeSet.has(t))\n\n for (const dbTable of dbTables) {\n if (reverseTableMap.has(dbTable)) continue\n const modelName = snakeToPascal(dbTable)\n tableMap.set(modelName, dbTable)\n reverseTableMap.set(dbTable, modelName)\n }\n\n // Build column maps and model info\n const models: ModelInfo[] = []\n const columnMaps = new Map<string, Map<string, string>>()\n const enumTypeMaps = new Map<string, Map<string, string>>()\n\n // Group columns by table\n const columnsByTable = new Map<string, ColumnRow[]>()\n for (const row of columnRows) {\n if (!columnsByTable.has(row.table_name)) columnsByTable.set(row.table_name, [])\n columnsByTable.get(row.table_name)!.push(row)\n }\n\n for (const [modelName, dbTable] of tableMap) {\n const cols = columnsByTable.get(dbTable) ?? []\n const pks = pksByTable.get(dbTable) ?? new Set<string>()\n const colMap = new Map<string, string>()\n const fields: FieldInfo[] = []\n\n for (const col of cols) {\n const fieldName = snakeToCamel(col.column_name)\n colMap.set(fieldName, col.column_name)\n\n // Check for enum values\n let enumVals: string[] | undefined\n if (dialect.name === 'mysql') {\n enumVals = enumValues.get(`${col.table_name}.${col.column_name}`)\n } else {\n enumVals = enumValues.get(col.udt_name)\n }\n\n const type = enumVals\n ? `enum(${enumVals.join(',')})`\n : mapDataType(col.data_type, col.udt_name, dialect.name)\n\n // Track Postgres types that need explicit parameter casting.\n // Prisma's $queryRawUnsafe sends string params as explicit text type,\n // preventing Postgres auto-cast for enums, jsonb, and timestamps.\n if (dialect.name === 'postgres') {\n if (enumVals) {\n if (!enumTypeMaps.has(modelName)) enumTypeMaps.set(modelName, new Map())\n enumTypeMaps.get(modelName)!.set(fieldName, col.udt_name)\n } else if (col.data_type === 'jsonb' || col.udt_name === 'jsonb' || col.data_type === 'json' || col.udt_name === 'json') {\n if (!enumTypeMaps.has(modelName)) enumTypeMaps.set(modelName, new Map())\n const jsonType = (col.data_type === 'json' || col.udt_name === 'json') ? 'json' : 'jsonb'\n enumTypeMaps.get(modelName)!.set(fieldName, jsonType)\n } else if (col.data_type.includes('timestamp') || col.udt_name === 'timestamptz' || col.udt_name === 'timestamp') {\n if (!enumTypeMaps.has(modelName)) enumTypeMaps.set(modelName, new Map())\n enumTypeMaps.get(modelName)!.set(fieldName, col.udt_name)\n }\n }\n\n fields.push({\n name: fieldName,\n type,\n isRequired: col.is_nullable === 'NO',\n isId: pks.has(col.column_name),\n hasDefault: col.column_default !== null,\n })\n }\n\n columnMaps.set(modelName, colMap)\n models.push({ name: modelName, tableName: dbTable, fields })\n }\n\n // Build FK edges\n const edges: FKEdge[] = []\n for (const fk of fkRows) {\n const fromModel = reverseTableMap.get(fk.from_table)\n const toModel = reverseTableMap.get(fk.to_table)\n if (!fromModel || !toModel) continue\n\n const fromColMap = columnMaps.get(fromModel)\n const toColMap = columnMaps.get(toModel)\n const localField = fromColMap ? reverseGet(fromColMap, fk.from_column) ?? fk.from_column : fk.from_column\n const foreignField = toColMap ? reverseGet(toColMap, fk.to_column) ?? fk.to_column : fk.to_column\n\n edges.push({\n from: fromModel,\n to: toModel,\n localField,\n foreignField,\n nullable: fk.is_nullable === 'YES',\n })\n }\n\n // Build relations from FK edges.\n // For each edge (from→to), generate two relations:\n // 1. Parent-side: on the \"to\" model, a field pointing to \"from\" model (e.g., Organization.members)\n // 2. Child-side: on the \"from\" model, a field pointing to \"to\" model (e.g., Member.organization)\n const relations: SchemaRelation[] = []\n for (const edge of edges) {\n // Detect one-to-one: if the FK column is the sole PK of the child table,\n // the relationship is one-to-one (e.g., WebApplicationData.applicationId is\n // both PK and FK → Application has singular webApplicationData, not plural).\n const fromDbTable = tableMap.get(edge.from)!\n const fromColMap = columnMaps.get(edge.from) ?? new Map<string, string>()\n const fkDbCol = fromColMap.get(edge.localField) ?? edge.localField\n const fromPks = pksByTable.get(fromDbTable)\n const isOneToOne = fromPks !== undefined && fromPks.size === 1 && fromPks.has(fkDbCol)\n\n // Parent-side: \"to\" model has a collection/reference to \"from\" model\n relations.push({\n parentModel: edge.to,\n childModel: edge.from,\n parentField: isOneToOne ? lowerFirst(edge.from) : pluralCamelCase(edge.from),\n childField: edge.localField,\n })\n\n // Child-side: \"from\" model has a singular reference to \"to\" model (FK is on this side)\n relations.push({\n parentModel: edge.from,\n childModel: edge.to,\n parentField: lowerFirst(edge.to),\n childField: edge.localField,\n })\n }\n\n return {\n schema: { models, edges, relations, scopeField: config.scopeField },\n tableMap,\n columnMaps,\n enumTypeMaps,\n }\n}\n\n// --- Name mapping utilities ---\n\nfunction snakeToPascal(str: string): string {\n return str\n .split('_')\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\n .join('')\n}\n\nfunction snakeToCamel(str: string): string {\n const pascal = snakeToPascal(str)\n return pascal.charAt(0).toLowerCase() + pascal.slice(1)\n}\n\n/**\n * Parse MySQL inline enum definition: \"enum('a','b','c')\" → ['a','b','c']\n */\nfunction parseMySQLEnum(columnType: string): string[] | null {\n if (!columnType) return null\n const match = columnType.match(/^enum\\((.+)\\)$/i)\n if (!match) return null\n return match[1]!\n .split(',')\n .map((v) => v.trim().replace(/^'|'$/g, ''))\n}\n\nfunction mapDataType(dataType: string, udtName: string, dialectName: string): string {\n const dt = dataType.toLowerCase()\n\n // Integer types\n if (dt === 'integer' || dt === 'smallint' || dt === 'bigint' || dt === 'int' || dt === 'mediumint' || dt === 'tinyint') return 'Int'\n\n // Float types\n if (dt === 'numeric' || dt === 'real' || dt === 'double precision' || dt === 'float' || dt === 'double' || dt === 'decimal') return 'Float'\n\n // Boolean\n if (dt === 'boolean' || dt === 'tinyint(1)') return 'Boolean'\n\n // String types\n if (dt === 'text' || dt === 'character varying' || dt === 'character' || dt === 'varchar' || dt === 'char'\n || dt === 'mediumtext' || dt === 'longtext' || dt === 'tinytext') return 'String'\n\n // DateTime types\n if (dt === 'timestamp with time zone' || dt === 'timestamp without time zone'\n || dt === 'date' || dt === 'time' || dt === 'datetime' || dt === 'timestamp') return 'DateTime'\n\n // JSON types\n if (dt === 'json' || dt === 'jsonb') return 'Json'\n\n // UUID / binary\n if (dt === 'uuid') return 'String'\n if (dt === 'bytea' || dt === 'blob' || dt === 'mediumblob' || dt === 'longblob' || dt === 'tinyblob' || dt === 'binary' || dt === 'varbinary') return 'Bytes'\n\n // Postgres user-defined (enums handled by caller)\n if (dt === 'user-defined' && dialectName === 'postgres') return udtName\n\n // MySQL enum is handled before this function is called\n if (dt === 'enum' || dt === 'set') return udtName\n\n return dataType\n}\n\nfunction lowerFirst(str: string): string {\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n\n/**\n * Convert a PascalCase model name to a camelCase plural field name.\n * e.g., \"Member\" → \"members\", \"Application\" → \"applications\", \"ApiKey\" → \"apiKeys\"\n */\nfunction pluralCamelCase(modelName: string): string {\n const camel = lowerFirst(modelName)\n return pluralize(camel)\n}\n\nfunction pluralize(str: string): string {\n if (str.endsWith('s') || str.endsWith('x') || str.endsWith('z') || str.endsWith('ch') || str.endsWith('sh')) {\n return str + 'es'\n }\n if (str.endsWith('y') && str.length > 1 && !isVowel(str.charAt(str.length - 2))) {\n return str.slice(0, -1) + 'ies'\n }\n return str + 's'\n}\n\nfunction isVowel(ch: string): boolean {\n return 'aeiou'.includes(ch.toLowerCase())\n}\n\n/**\n * Lowercase all keys in each row — handles MySQL information_schema returning\n * uppercase column names (TABLE_NAME, COLUMN_NAME, etc.)\n */\nfunction normalizeKeys<T>(rows: T[]): T[] {\n return rows.map((row) => {\n if (!row || typeof row !== 'object') return row\n const normalized: Record<string, unknown> = {}\n for (const [key, val] of Object.entries(row as Record<string, unknown>)) {\n normalized[key.toLowerCase()] = val\n }\n return normalized as T\n })\n}\n\n/** Reverse lookup: find the key whose value matches `dbName` */\nfunction reverseGet(map: Map<string, string>, dbName: string): string | null {\n for (const [key, val] of map) {\n if (val === dbName) return key\n }\n return null\n}\n","import { randomUUID } from 'node:crypto'\nimport type { SQLExecutor, ResolvedEntitySpec, CreateContext } from './types'\nimport type { Dialect } from './dialect'\n\n/**\n * Create entities via raw SQL INSERT.\n *\n * Entities arrive pre-sorted by FK order (handler does topo-sort via tree.ts).\n * Each model in `spec` is inserted sequentially; within a model, batch mode\n * uses a single multi-row INSERT while normal mode inserts one row at a time.\n *\n * For dialects with RETURNING (Postgres): INSERT ... RETURNING *\n * For dialects without (MySQL): INSERT then SELECT via LAST_INSERT_ID()\n */\nexport async function createEntities(\n executor: SQLExecutor,\n dialect: Dialect,\n tableMap: Map<string, string>,\n columnMaps: Map<string, Map<string, string>>,\n spec: Record<string, ResolvedEntitySpec>,\n _context: CreateContext,\n enumTypeMaps: Map<string, Map<string, string>> = new Map(),\n): Promise<Record<string, Record<string, unknown>[]>> {\n const results: Record<string, Record<string, unknown>[]> = {}\n\n for (const [model, entitySpec] of Object.entries(spec)) {\n const dbTable = tableMap.get(model)\n if (!dbTable) throw new Error(`Unknown model \"${model}\". Not found in database tables.`)\n const colMap = columnMaps.get(model) ?? new Map<string, string>()\n const enumTypeMap = enumTypeMaps.get(model) ?? new Map<string, string>()\n\n if (entitySpec.batch && entitySpec.fields.length > 0) {\n results[model] = await insertBatch(executor, dialect, dbTable, colMap, enumTypeMap, entitySpec.fields)\n } else {\n const created: Record<string, unknown>[] = []\n for (const fields of entitySpec.fields) {\n const [record] = await insertOne(executor, dialect, dbTable, colMap, enumTypeMap, fields)\n if (record) created.push(record)\n }\n results[model] = created\n }\n }\n\n return results\n}\n\n/**\n * Update a single record by primary key. Used for circular FK backfill.\n */\nexport async function updateEntity(\n executor: SQLExecutor,\n dialect: Dialect,\n tableMap: Map<string, string>,\n columnMaps: Map<string, Map<string, string>>,\n model: string,\n id: string,\n fields: Record<string, unknown>,\n enumTypeMaps: Map<string, Map<string, string>> = new Map(),\n): Promise<void> {\n const dbTable = tableMap.get(model)\n if (!dbTable) throw new Error(`Unknown model \"${model}\" for update.`)\n const colMap = columnMaps.get(model) ?? new Map<string, string>()\n const enumTypeMap = enumTypeMaps.get(model) ?? new Map<string, string>()\n\n const setClauses: string[] = []\n const params: unknown[] = []\n let paramIdx = 1\n\n for (const [fieldName, value] of Object.entries(fields)) {\n const dbCol = colMap.get(fieldName) ?? fieldName\n setClauses.push(`${dialect.quoteId(dbCol)} = ${castParam(dialect, paramIdx, enumTypeMap, fieldName)}`)\n params.push(serializeValue(value, dialect))\n paramIdx++\n }\n\n const idCol = colMap.get('id') ?? 'id'\n params.push(id)\n\n const sql = `UPDATE ${dialect.quoteId(dbTable)} SET ${setClauses.join(', ')} WHERE ${dialect.quoteId(idCol)} = ${dialect.param(paramIdx)}`\n await executor.query(sql, params)\n}\n\n// --- Internal helpers ---\n\nasync function insertOne(\n executor: SQLExecutor,\n dialect: Dialect,\n dbTable: string,\n colMap: Map<string, string>,\n enumTypeMap: Map<string, string>,\n fields: Record<string, unknown>,\n): Promise<Record<string, unknown>[]> {\n // Generate a client-side ID when none is provided and the table has an 'id' column.\n // Many ORMs (e.g. Prisma's @default(cuid())) generate IDs in the application\n // layer, not as DB-level defaults. Without this, INSERT would send NULL for\n // the PK column and fail with a NOT NULL violation.\n // Tables whose PK is not named 'id' (e.g. WebApplicationData uses applicationId\n // as its PK) already have their PK set via FK wiring, so we skip injection.\n const idFieldName = reverseGet(colMap, findIdCol(colMap))\n if (idFieldName && fields[idFieldName] === undefined) {\n fields = { ...fields, [idFieldName]: randomUUID() }\n }\n\n const entries = Object.entries(fields)\n\n if (entries.length === 0) {\n const sql = `INSERT INTO ${dialect.quoteId(dbTable)} DEFAULT VALUES RETURNING *`\n return mapRowsBack(await executor.query(sql), colMap)\n }\n\n const dbCols: string[] = []\n const params: unknown[] = []\n const placeholders: string[] = []\n let paramIdx = 1\n\n for (const [fieldName, value] of entries) {\n const dbCol = colMap.get(fieldName) ?? fieldName\n dbCols.push(dialect.quoteId(dbCol))\n placeholders.push(castParam(dialect, paramIdx, enumTypeMap, fieldName))\n params.push(serializeValue(value, dialect))\n paramIdx++\n }\n\n const colList = dbCols.join(', ')\n const valList = placeholders.join(', ')\n\n if (dialect.supportsReturning) {\n const sql = `INSERT INTO ${dialect.quoteId(dbTable)} (${colList}) VALUES (${valList}) RETURNING *`\n return mapRowsBack(await executor.query(sql, params), colMap)\n }\n\n // MySQL: INSERT then SELECT back by the ID we set\n await executor.query(\n `INSERT INTO ${dialect.quoteId(dbTable)} (${colList}) VALUES (${valList})`,\n params,\n )\n\n const idCol = findIdCol(colMap)\n const id = fields[idFieldName ?? 'id']\n\n return mapRowsBack(\n await executor.query(\n `SELECT * FROM ${dialect.quoteId(dbTable)} WHERE ${dialect.quoteId(idCol)} = ${dialect.param(1)}`,\n [id],\n ),\n colMap,\n )\n}\n\nasync function insertBatch(\n executor: SQLExecutor,\n dialect: Dialect,\n dbTable: string,\n colMap: Map<string, string>,\n enumTypeMap: Map<string, string>,\n fieldsArr: Record<string, unknown>[],\n): Promise<Record<string, unknown>[]> {\n if (fieldsArr.length === 0) return []\n\n // Generate client-side IDs for batch records, same as insertOne.\n // Only inject if the table actually has an 'id' column.\n const idFieldName = reverseGet(colMap, findIdCol(colMap))\n if (idFieldName) {\n fieldsArr = fieldsArr.map((fields) => {\n if (fields[idFieldName] === undefined) {\n return { ...fields, [idFieldName]: randomUUID() }\n }\n return fields\n })\n }\n\n const fieldNames = Object.keys(fieldsArr[0]!)\n const dbCols = fieldNames.map((f) => dialect.quoteId(colMap.get(f) ?? f))\n const colList = dbCols.join(', ')\n\n // Postgres has a max of 32,767 bind variables per statement.\n // Chunk large batches to stay within this limit.\n const MAX_PARAMS = 32_000\n const chunkSize = Math.max(1, Math.floor(MAX_PARAMS / fieldNames.length))\n const allResults: Record<string, unknown>[] = []\n\n for (let offset = 0; offset < fieldsArr.length; offset += chunkSize) {\n const chunk = fieldsArr.slice(offset, offset + chunkSize)\n const params: unknown[] = []\n const valueTuples: string[] = []\n let paramIdx = 1\n\n for (const fields of chunk) {\n const placeholders: string[] = []\n for (const fieldName of fieldNames) {\n placeholders.push(castParam(dialect, paramIdx, enumTypeMap, fieldName))\n params.push(serializeValue(fields[fieldName], dialect))\n paramIdx++\n }\n valueTuples.push(`(${placeholders.join(', ')})`)\n }\n\n const valList = valueTuples.join(', ')\n\n if (dialect.supportsReturning) {\n const sql = `INSERT INTO ${dialect.quoteId(dbTable)} (${colList}) VALUES ${valList} RETURNING *`\n allResults.push(...mapRowsBack(await executor.query(sql, params), colMap))\n } else {\n await executor.query(\n `INSERT INTO ${dialect.quoteId(dbTable)} (${colList}) VALUES ${valList}`,\n params,\n )\n }\n }\n\n return allResults\n}\n\n/**\n * Map DB column names back to camelCase field names in returned rows.\n */\nfunction mapRowsBack(\n rows: Record<string, unknown>[],\n colMap: Map<string, string>,\n): Record<string, unknown>[] {\n if (colMap.size === 0) return rows\n\n const reverse = new Map<string, string>()\n for (const [fieldName, dbCol] of colMap) {\n reverse.set(dbCol, fieldName)\n }\n\n return rows.map((row) => {\n const mapped: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(row)) {\n const fieldName = reverse.get(key) ?? key\n mapped[fieldName] = value\n }\n return mapped\n })\n}\n\nfunction findIdCol(colMap: Map<string, string>): string {\n return colMap.get('id') ?? 'id'\n}\n\nfunction reverseGet(map: Map<string, string>, dbName: string): string | null {\n for (const [key, val] of map) {\n if (val === dbName) return key\n }\n return null\n}\n\n/**\n * Build a parameter placeholder with an optional Postgres enum cast.\n * e.g. `$1::\"ApplicationArchitecture\"` for enum fields, or just `$1` otherwise.\n */\nfunction castParam(\n dialect: Dialect,\n paramIdx: number,\n enumTypeMap: Map<string, string>,\n fieldName: string,\n): string {\n const placeholder = dialect.param(paramIdx)\n if (dialect.name === 'postgres') {\n const enumType = enumTypeMap.get(fieldName)\n if (enumType) return `${placeholder}::${dialect.quoteId(enumType)}`\n }\n return placeholder\n}\n\n/**\n * Serialize a JS value for SQL insertion.\n * Handles MySQL-specific quirks:\n * - Objects/arrays → JSON.stringify (MySQL requires JSON strings, not objects)\n * - ISO 8601 datetime strings → MySQL DATETIME format\n */\nfunction serializeValue(value: unknown, dialect: Dialect): unknown {\n if (value === null || value === undefined) return value\n\n // JSON: Both MySQL and Postgres need stringified JSON when using parameterized\n // queries with explicit casts (e.g. $1::jsonb). Postgres $queryRawUnsafe cannot\n // pass JS objects directly as parameters.\n if (typeof value === 'object' && !(value instanceof Date)) {\n return JSON.stringify(value)\n }\n\n // DateTime: MySQL doesn't accept ISO 8601 with 'T' and 'Z'\n if (typeof value === 'string' && dialect.name === 'mysql') {\n if (/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/.test(value)) {\n return value.replace('T', ' ').replace('Z', '').replace(/\\.\\d+$/, '')\n }\n }\n\n return value\n}\n","import type { SQLExecutor, SchemaInfo } from './types'\nimport type { Dialect } from './dialect'\nimport { topoSort, findDeferrableEdge } from './graph'\n\n/**\n * Tear down all data scoped to a value, in reverse topological order.\n *\n * Strategy:\n * 1. Find the scope root model (e.g. Organization) from FK edges\n * 2. Any model with a FK pointing to the scope root is \"scoped\"\n * 3. Delete scoped models by their FK = scopeValue\n * 4. Delete non-scoped models by their record IDs from refs\n * 5. Delete the scope root entity last by id = scopeValue\n */\nexport async function teardown(\n executor: SQLExecutor,\n dialect: Dialect,\n tableMap: Map<string, string>,\n columnMaps: Map<string, Map<string, string>>,\n schema: SchemaInfo,\n scopeValue: string,\n refs?: Record<string, Record<string, unknown>[]>,\n): Promise<void> {\n // Find scope root: the model that the scopeField FK points TO\n let scopeRootModel: string | null = null\n for (const edge of schema.edges) {\n if (edge.localField.toLowerCase() === schema.scopeField.toLowerCase() && edge.to !== edge.from) {\n scopeRootModel = edge.to\n break\n }\n }\n\n // Build map: model → FK field name that points to the scope root\n const scopeFieldByModel = new Map<string, string>()\n if (scopeRootModel) {\n for (const edge of schema.edges) {\n if (edge.to === scopeRootModel && edge.from !== scopeRootModel) {\n scopeFieldByModel.set(edge.from, edge.localField)\n }\n }\n }\n\n const modelNames = schema.models.map((m) => m.name)\n const { sorted, cycles } = topoSort(modelNames, schema.edges)\n\n await executor.transaction(async (tx) => {\n // Break cycles by nullifying deferrable FKs\n for (const cycle of cycles) {\n const edge = findDeferrableEdge(cycle, schema.edges)\n if (edge) {\n const scopeFK = scopeFieldByModel.get(edge.from)\n if (scopeFK) {\n const dbTable = tableMap.get(edge.from)\n const colMap = columnMaps.get(edge.from) ?? new Map<string, string>()\n if (dbTable) {\n const dbFKCol = colMap.get(edge.localField) ?? edge.localField\n const dbScopeCol = colMap.get(scopeFK) ?? scopeFK\n await tx.query(\n `UPDATE ${dialect.quoteId(dbTable)} SET ${dialect.quoteId(dbFKCol)} = NULL WHERE ${dialect.quoteId(dbScopeCol)} = ${dialect.param(1)}`,\n [scopeValue],\n )\n }\n }\n }\n }\n\n // Delete cycle nodes\n for (const cycle of cycles) {\n for (const model of cycle) {\n await deleteModel(tx, dialect, tableMap, columnMaps, model, scopeValue, scopeFieldByModel, refs)\n }\n }\n\n // Delete in reverse topo order (dependents first)\n const reversed = [...sorted].reverse()\n for (const model of reversed) {\n if (model === scopeRootModel) continue // deleted last\n await deleteModel(tx, dialect, tableMap, columnMaps, model, scopeValue, scopeFieldByModel, refs)\n }\n\n // Delete the scope root entity last\n if (scopeRootModel) {\n const dbTable = tableMap.get(scopeRootModel)\n const colMap = columnMaps.get(scopeRootModel) ?? new Map<string, string>()\n if (dbTable) {\n const idCol = colMap.get('id') ?? 'id'\n await tx.query(\n `DELETE FROM ${dialect.quoteId(dbTable)} WHERE ${dialect.quoteId(idCol)} = ${dialect.param(1)}`,\n [scopeValue],\n )\n }\n }\n })\n}\n\nasync function deleteModel(\n tx: SQLExecutor,\n dialect: Dialect,\n tableMap: Map<string, string>,\n columnMaps: Map<string, Map<string, string>>,\n model: string,\n scopeValue: string,\n scopeFieldByModel: Map<string, string>,\n refs?: Record<string, Record<string, unknown>[]>,\n): Promise<void> {\n const dbTable = tableMap.get(model)\n if (!dbTable) return\n const colMap = columnMaps.get(model) ?? new Map<string, string>()\n\n const scopeFK = scopeFieldByModel.get(model)\n if (scopeFK) {\n // Has FK to scope root → delete by that FK\n const dbCol = colMap.get(scopeFK) ?? scopeFK\n await tx.query(\n `DELETE FROM ${dialect.quoteId(dbTable)} WHERE ${dialect.quoteId(dbCol)} = ${dialect.param(1)}`,\n [scopeValue],\n )\n } else if (refs?.[model]) {\n // No FK to scope root, but we created records → delete by IDs\n const ids = refs[model]\n .map((r) => r.id)\n .filter((id): id is string => typeof id === 'string')\n if (ids.length > 0) {\n const idCol = colMap.get('id') ?? 'id'\n const placeholders = ids.map((_, i) => dialect.param(i + 1)).join(', ')\n await tx.query(\n `DELETE FROM ${dialect.quoteId(dbTable)} WHERE ${dialect.quoteId(idCol)} IN (${placeholders})`,\n ids,\n )\n }\n }\n}\n","import type {\n HandlerConfig,\n HandlerRequest,\n HandlerResponse,\n ResolvedEntitySpec,\n SdkInfo,\n} from './types'\nimport { verifySignature } from './hmac'\nimport { signRefs, verifyRefs } from './refs'\nimport { resolveTree } from './tree'\nimport { AutonomaError, Errors } from './errors'\nimport { getDialect } from './dialect'\nimport { introspectDatabase, type IntrospectionResult } from './introspect'\nimport { createEntities, updateEntity } from './create'\nimport { teardown } from './teardown'\n\n/** Cache introspection results per config to avoid re-querying on every request */\nconst introspectionCache = new WeakMap<HandlerConfig, IntrospectionResult>()\n\nasync function getIntrospection(config: HandlerConfig): Promise<IntrospectionResult> {\n let cached = introspectionCache.get(config)\n if (cached) return cached\n\n const dialect = getDialect(config.dialect)\n cached = await introspectDatabase(config.executor, dialect, {\n scopeField: config.scopeField,\n schema: config.dbSchema,\n tableNameMap: config.tableNameMap,\n excludeTables: config.excludeTables,\n })\n introspectionCache.set(config, cached)\n return cached\n}\n\nexport const PROTOCOL_VERSION = '1.0'\n\nfunction buildSdkMeta(config: HandlerConfig): { version: string; sdk: SdkInfo } {\n return {\n version: PROTOCOL_VERSION,\n sdk: {\n language: 'typescript',\n orm: config.sdk?.orm ?? 'unknown',\n server: config.sdk?.server ?? 'unknown',\n },\n }\n}\n\nexport async function handleRequest(\n config: HandlerConfig,\n req: HandlerRequest,\n): Promise<HandlerResponse> {\n try {\n if (config.sharedSecret === config.signingSecret) {\n throw new AutonomaError(\n 'sharedSecret and signingSecret must be different. The shared secret is known by Autonoma; the signing secret must be private.',\n 'SAME_SECRETS',\n 500,\n )\n }\n\n if (!config.allowProduction && process.env.NODE_ENV === 'production') {\n throw Errors.productionBlocked()\n }\n\n const signature = req.headers['x-signature'] ?? req.headers['X-Signature'] ?? ''\n if (!verifySignature(req.body, signature, config.sharedSecret)) {\n throw Errors.invalidSignature()\n }\n\n let body: Record<string, unknown>\n try {\n body = JSON.parse(req.body)\n } catch {\n throw Errors.invalidBody('invalid JSON')\n }\n\n const action = body.action as string\n if (!action) throw Errors.invalidBody('missing action')\n\n switch (action) {\n case 'discover':\n return await handleDiscover(config)\n case 'up':\n return await handleUp(config, body)\n case 'down':\n return await handleDown(config, body)\n default:\n throw Errors.unknownAction(action)\n }\n } catch (err) {\n if (err instanceof AutonomaError) {\n return { status: err.status, body: { error: err.message, code: err.code } }\n }\n const message = err instanceof Error ? err.message : 'Internal error'\n return { status: 500, body: { error: message, code: 'INTERNAL_ERROR' } }\n }\n}\n\nasync function handleDiscover(config: HandlerConfig): Promise<HandlerResponse> {\n const { schema } = await getIntrospection(config)\n return { status: 200, body: { ...buildSdkMeta(config), schema } }\n}\n\nasync function handleUp(\n config: HandlerConfig,\n body: Record<string, unknown>,\n): Promise<HandlerResponse> {\n const create = body.create as Record<string, Record<string, unknown>[]> | undefined\n if (!create) throw Errors.invalidBody('missing \"create\" in request body')\n\n const testRunId = (body.testRunId as string) ?? crypto.randomUUID()\n const { schema, tableMap, columnMaps, enumTypeMaps } = await getIntrospection(config)\n const dialect = getDialect(config.dialect)\n\n const tree = resolveTree(create, schema, testRunId)\n const refs: Record<string, Record<string, unknown>[]> = {}\n const idMap = new Map<string, string>()\n\n await config.executor.transaction(async (tx) => {\n let i = 0\n while (i < tree.ops.length) {\n const op = tree.ops[i]!\n const model = op.model\n\n // Collect consecutive ops for the same model with same batch flag\n const batch: typeof tree.ops = [op]\n while (i + 1 < tree.ops.length && tree.ops[i + 1]!.model === model && tree.ops[i + 1]!.batch === op.batch) {\n i++\n batch.push(tree.ops[i]!)\n }\n\n // Replace temp IDs with real IDs in all fields\n const modelInfo = schema.models.find((m) => m.name === model)\n const resolvedFields = batch.map((b) => {\n const fields = { ...b.fields }\n delete fields.id\n for (const [key, value] of Object.entries(fields)) {\n if (typeof value === 'string' && value.startsWith('__temp_')) {\n const realId = idMap.get(value)\n if (realId) fields[key] = realId\n }\n }\n // Inject scope field if applicable\n const scopeEdge = schema.edges.find(\n (e) => e.from === model && e.localField.toLowerCase() === schema.scopeField.toLowerCase() && e.from !== e.to,\n )\n if (scopeEdge && !(scopeEdge.localField in fields)) {\n const scopeVal = detectScopeValue(refs, schema.scopeField)\n if (scopeVal) fields[scopeEdge.localField] = scopeVal\n }\n // Auto-populate required fields without DB defaults (e.g. Prisma's @updatedAt)\n if (modelInfo) {\n for (const field of modelInfo.fields) {\n if (field.isRequired && !field.hasDefault && !field.isId && !(field.name in fields)) {\n if (field.type === 'DateTime') {\n fields[field.name] = new Date()\n }\n }\n }\n }\n return fields\n })\n\n const spec: Record<string, ResolvedEntitySpec> = {\n [model]: { count: resolvedFields.length, fields: resolvedFields, batch: op.batch },\n }\n\n const context = { testRunId, refs }\n const created = await createEntities(tx, dialect, tableMap, columnMaps, spec, context, enumTypeMaps)\n const records = created[model] ?? []\n\n if (!refs[model]) refs[model] = []\n refs[model].push(...records)\n\n for (let j = 0; j < batch.length; j++) {\n const record = records[j]\n if (record && typeof record.id === 'string') {\n idMap.set(batch[j]!.tempId, record.id)\n }\n }\n\n i++\n }\n\n // Resolve deferred FK updates (circular dependency cycles)\n for (const deferred of tree.deferredUpdates) {\n const realTargetId = idMap.get(deferred.targetTempId)\n const refTempId = tree.aliases.get(deferred.refAlias)\n const realRefId = refTempId ? idMap.get(refTempId) : undefined\n\n if (!realTargetId || !realRefId) {\n throw new Error(\n `_ref \"${deferred.refAlias}\" could not be resolved. Ensure the referenced node has _alias defined in the scenario.`,\n )\n }\n\n await updateEntity(tx, dialect, tableMap, columnMaps, deferred.model, realTargetId, { [deferred.field]: realRefId }, enumTypeMaps)\n }\n })\n\n const scopeValue = detectScopeValue(refs, schema.scopeField) ?? testRunId\n\n const firstUser = findFirstUser(refs)\n const auth = await config.auth(firstUser)\n\n const refsToken = signRefs(\n { refs, testRunId: scopeValue, environment: '' },\n config.signingSecret,\n )\n\n return { status: 200, body: { ...buildSdkMeta(config), auth, refs, refsToken } }\n}\n\nasync function handleDown(\n config: HandlerConfig,\n body: Record<string, unknown>,\n): Promise<HandlerResponse> {\n const refsToken = body.refsToken as string\n if (!refsToken) throw Errors.invalidBody('missing refsToken')\n\n let payload: ReturnType<typeof verifyRefs>\n try {\n payload = verifyRefs(refsToken, config.signingSecret)\n } catch (err) {\n const message = err instanceof Error ? err.message : 'invalid token'\n throw Errors.invalidRefsToken(message)\n }\n\n const { schema, tableMap, columnMaps } = await getIntrospection(config)\n const dialect = getDialect(config.dialect)\n\n await teardown(config.executor, dialect, tableMap, columnMaps, schema, payload.testRunId, payload.refs)\n\n return { status: 200, body: { ...buildSdkMeta(config), ok: true } }\n}\n\nfunction findFirstUser(\n refs: Record<string, Record<string, unknown>[]>,\n): Record<string, unknown> | null {\n for (const [model, records] of Object.entries(refs)) {\n if (model.toLowerCase() === 'user' && records.length > 0) {\n return records[0]!\n }\n }\n return null\n}\n\nfunction detectScopeValue(\n refs: Record<string, Record<string, unknown>[]>,\n scopeField: string,\n): string | null {\n const scopeLower = scopeField.toLowerCase()\n for (const records of Object.values(refs)) {\n for (const record of records) {\n for (const [key, value] of Object.entries(record)) {\n if (key.toLowerCase() === scopeLower && typeof value === 'string') {\n return value\n }\n }\n }\n }\n return null\n}\n","import { createHash } from 'node:crypto'\n\n/**\n * Compute a stable 16-char hex fingerprint of a scenario definition.\n * Uses sha256 of the JSON-serialized spec with sorted keys.\n */\nexport function fingerprint(value: unknown): string {\n const json = JSON.stringify(value, sortReplacer)\n return createHash('sha256').update(json).digest('hex').slice(0, 16)\n}\n\n/**\n * JSON replacer that sorts object keys for deterministic serialization.\n */\nfunction sortReplacer(_key: string, value: unknown): unknown {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n return Object.keys(value as Record<string, unknown>)\n .sort()\n .reduce(\n (sorted, k) => {\n sorted[k] = (value as Record<string, unknown>)[k]\n return sorted\n },\n {} as Record<string, unknown>,\n )\n }\n return value\n}\n","import type {\n SQLExecutor,\n ScenarioDefinition,\n HandlerConfig,\n} from './types'\nimport { handleRequest } from './handler'\nimport { signBody } from './hmac'\n\nexport interface CheckResult {\n valid: boolean\n phase: 'up' | 'down' | 'ok'\n errors: CheckError[]\n timing?: { upMs: number; downMs: number }\n}\n\nexport interface CheckError {\n phase: 'up' | 'down'\n message: string\n fix?: string\n}\n\n/**\n * Dry-run a scenario against a real database.\n * Runs the full up → down cycle and returns structured errors.\n */\nexport async function checkScenario(\n executor: SQLExecutor,\n scenario: ScenarioDefinition,\n options?: {\n scopeField: string\n dialect?: HandlerConfig['dialect']\n dbSchema?: string\n tableNameMap?: Record<string, string>\n sharedSecret?: string\n signingSecret?: string\n auth?: HandlerConfig['auth']\n },\n): Promise<CheckResult> {\n const sharedSecret = options?.sharedSecret ?? 'autonoma-check-shared'\n const signingSecret = options?.signingSecret ?? 'autonoma-check-signing'\n\n const config: HandlerConfig = {\n executor,\n scopeField: options?.scopeField ?? 'organizationId',\n dialect: options?.dialect,\n dbSchema: options?.dbSchema,\n tableNameMap: options?.tableNameMap,\n sharedSecret,\n signingSecret,\n auth: options?.auth ?? (async () => ({ headers: { Authorization: 'Bearer check-token' } })),\n }\n\n // Up\n const upBody = JSON.stringify({ action: 'up', create: scenario.create })\n const upReq = {\n body: upBody,\n headers: { 'x-signature': signBody(upBody, sharedSecret) },\n }\n\n const t0 = performance.now()\n const upRes = await handleRequest(config, upReq)\n const upMs = Math.round(performance.now() - t0)\n\n if (upRes.status !== 200) {\n const errorMsg = (upRes.body as Record<string, string>).error ?? 'Unknown error'\n return {\n valid: false,\n phase: 'up',\n errors: [{ phase: 'up', message: errorMsg, fix: suggestFix(errorMsg) }],\n timing: { upMs, downMs: 0 },\n }\n }\n\n // Down\n const refsToken = (upRes.body as Record<string, string>).refsToken\n const downBody = JSON.stringify({ action: 'down', refsToken })\n const downReq = {\n body: downBody,\n headers: { 'x-signature': signBody(downBody, sharedSecret) },\n }\n\n const t1 = performance.now()\n const downRes = await handleRequest(config, downReq)\n const downMs = Math.round(performance.now() - t1)\n\n if (downRes.status !== 200) {\n const errorMsg = (downRes.body as Record<string, string>).error ?? 'Unknown error'\n return {\n valid: false,\n phase: 'down',\n errors: [{ phase: 'down', message: errorMsg }],\n timing: { upMs, downMs },\n }\n }\n\n return { valid: true, phase: 'ok', errors: [], timing: { upMs, downMs } }\n}\n\n/**\n * Check multiple scenarios sequentially.\n */\nexport async function checkAllScenarios(\n executor: SQLExecutor,\n scenarios: ScenarioDefinition[],\n options?: {\n scopeField: string\n dialect?: HandlerConfig['dialect']\n dbSchema?: string\n tableNameMap?: Record<string, string>\n sharedSecret?: string\n signingSecret?: string\n auth?: HandlerConfig['auth']\n },\n): Promise<CheckResult[]> {\n const results: CheckResult[] = []\n for (const scenario of scenarios) {\n results.push(await checkScenario(executor, scenario, options))\n }\n return results\n}\n\nfunction suggestFix(errorMsg: string): string {\n if (errorMsg.includes('Unique constraint failed') || errorMsg.includes('unique constraint')) {\n const match = errorMsg.match(/fields: \\(`(.+?)`\\)/) ?? errorMsg.match(/constraint \"(.+?)\"/)\n if (match) return `Unique constraint on (${match[1]}). Add {{testRunId}} or {{index}} to make values unique.`\n return 'Unique constraint violation. Make field values unique across instances.'\n }\n if (errorMsg.includes('Foreign key constraint') || errorMsg.includes('foreign key')) {\n return 'A referenced record does not exist. Check that parent entities are nested correctly.'\n }\n if (errorMsg.includes('null value in column') || errorMsg.includes('must not be null')) {\n return 'A required field is null. Add it to the node with a value.'\n }\n return ''\n}\n"],"mappings":"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","names":["createHmac","reverseGet"]}
1
+ {"version":3,"sources":["../src/hmac.ts","../src/refs.ts","../src/template.ts","../src/tree.ts","../src/errors.ts","../src/generated/sql-queries.ts","../src/dialect.ts","../src/introspect.ts","../src/create.ts","../src/teardown.ts","../src/handler.ts","../src/fingerprint.ts","../src/check.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from 'node:crypto'\n\nexport function signBody(body: string, secret: string): string {\n return createHmac('sha256', secret).update(body).digest('hex')\n}\n\nexport function verifySignature(\n body: string,\n signature: string,\n secret: string,\n): boolean {\n const expected = signBody(body, secret)\n if (expected.length !== signature.length) return false\n return timingSafeEqual(Buffer.from(expected), Buffer.from(signature))\n}\n","import { createHmac, timingSafeEqual } from 'node:crypto'\n\ninterface RefsPayload {\n refs: Record<string, Record<string, unknown>[]>\n testRunId: string\n environment: string\n}\n\n/**\n * Sign refs into a JWT-like token (header.payload.signature).\n * Uses HMAC-SHA256 — not a full JWT library to avoid dependencies.\n */\nexport function signRefs(payload: RefsPayload, secret: string): string {\n const header = base64url({ alg: 'HS256', typ: 'REFS' })\n const body = base64url(payload)\n const signature = hmac(`${header}.${body}`, secret)\n return `${header}.${body}.${signature}`\n}\n\n/**\n * Verify and decode a refs token. Returns the payload or throws.\n */\nexport function verifyRefs(\n token: string,\n secret: string,\n): RefsPayload {\n const parts = token.split('.')\n if (parts.length !== 3) throw new Error('malformed token')\n\n const [header, body, signature] = parts\n const expected = hmac(`${header}.${body}`, secret)\n\n const expectedBuf = Buffer.from(expected)\n const signatureBuf = Buffer.from(signature!)\n if (expectedBuf.length !== signatureBuf.length || !timingSafeEqual(expectedBuf, signatureBuf)) {\n throw new Error('signature mismatch')\n }\n\n return JSON.parse(Buffer.from(body!, 'base64url').toString())\n}\n\nfunction base64url(obj: unknown): string {\n return Buffer.from(JSON.stringify(obj)).toString('base64url')\n}\n\nfunction hmac(data: string, secret: string): string {\n return createHmac('sha256', secret).update(data).digest('base64url')\n}\n","const TEMPLATE_RE = /\\{\\{(.+?)\\}\\}/g\n\nexport interface TemplateContext {\n testRunId: string\n index: number\n}\n\n/**\n * Resolve all {{...}} expressions in a value. Handles strings, objects, and arrays recursively.\n */\nexport function resolveTemplate(value: unknown, ctx: TemplateContext): unknown {\n if (typeof value === 'string') return resolveString(value, ctx)\n if (Array.isArray(value)) return value.map((v) => resolveTemplate(v, ctx))\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n result[k] = resolveTemplate(v, ctx)\n }\n return result\n }\n return value\n}\n\nfunction resolveString(str: string, ctx: TemplateContext): unknown {\n // If the entire string is a single expression, return the raw value (preserving type)\n const fullMatch = str.match(/^\\{\\{(.+?)\\}\\}$/)\n if (fullMatch) {\n return evaluateExpression(fullMatch[1]!, ctx)\n }\n\n // Otherwise, interpolate expressions into the string\n return str.replace(TEMPLATE_RE, (_, expr: string) => {\n const val = evaluateExpression(expr, ctx)\n return String(val)\n })\n}\n\nfunction evaluateExpression(expr: string, ctx: TemplateContext): unknown {\n expr = expr.trim()\n\n // Simple variables\n if (expr === 'testRunId') return ctx.testRunId\n if (expr === 'index') return ctx.index\n if (expr === 'index1') return ctx.index + 1\n\n // cycle([...])\n const cycleMatch = expr.match(/^cycle\\(\\[(.+)\\]\\)$/)\n if (cycleMatch) {\n const items = parseArrayLiteral(cycleMatch[1]!)\n return items[ctx.index % items.length]\n }\n\n // pick([...])\n const pickMatch = expr.match(/^pick\\(\\[(.+)\\]\\)$/)\n if (pickMatch) {\n const items = parseArrayLiteral(pickMatch[1]!)\n return items[Math.floor(Math.random() * items.length)]\n }\n\n // random.int(a,b)\n const randIntMatch = expr.match(/^random\\.int\\((\\d+),\\s*(\\d+)\\)$/)\n if (randIntMatch) {\n const min = parseInt(randIntMatch[1]!, 10)\n const max = parseInt(randIntMatch[2]!, 10)\n return Math.floor(Math.random() * (max - min + 1)) + min\n }\n\n // random.float(a,b)\n const randFloatMatch = expr.match(/^random\\.float\\((\\d+(?:\\.\\d+)?),\\s*(\\d+(?:\\.\\d+)?)\\)$/)\n if (randFloatMatch) {\n const min = parseFloat(randFloatMatch[1]!)\n const max = parseFloat(randFloatMatch[2]!)\n return Math.random() * (max - min) + min\n }\n\n // now()\n if (expr === 'now()') return new Date().toISOString()\n\n // daysAgo(n)\n const daysAgoMatch = expr.match(/^daysAgo\\((\\d+)\\)$/)\n if (daysAgoMatch) {\n const d = new Date()\n d.setDate(d.getDate() - parseInt(daysAgoMatch[1]!, 10))\n return d.toISOString()\n }\n\n throw new Error(`Template error: unknown expression '${expr}'`)\n}\n\nfunction parseArrayLiteral(raw: string): string[] {\n return raw.split(',').map((s) => {\n s = s.trim()\n // Strip surrounding quotes\n if ((s.startsWith(\"'\") && s.endsWith(\"'\")) || (s.startsWith('\"') && s.endsWith('\"'))) {\n return s.slice(1, -1)\n }\n return s\n })\n}\n","import type { SchemaInfo, SchemaRelation } from './types'\nimport { resolveTemplate, type TemplateContext } from './template'\n\nconst RESERVED_KEYS = new Set(['_alias', '_ref', '_count', '_batch'])\n\n/** A create operation produced by the tree resolver */\nexport interface CreateOp {\n model: string\n fields: Record<string, unknown>\n tempId: string\n batch: boolean\n}\n\n/**\n * A deferred FK update — emitted when a _ref points to a node that hasn't\n * been created yet (circular dependency). Resolved after all creates.\n */\nexport interface DeferredUpdate {\n /** Temp ID of the record that needs to be updated */\n targetTempId: string\n /** Model name of the record to update */\n model: string\n /** Field on the record that holds the deferred FK */\n field: string\n /** Alias that will resolve to the FK value once created */\n refAlias: string\n}\n\n/** Result of resolving a tree scenario */\nexport interface ResolvedTree {\n ops: CreateOp[]\n deferredUpdates: DeferredUpdate[]\n aliases: Map<string, string>\n}\n\n/** A resolved reference to another node's id */\nexport interface RefNode {\n _ref: string\n}\n\n/**\n * Resolve a nested scenario tree into an ordered list of create operations.\n *\n * Walks depth-first. Parent-child FKs are wired automatically.\n * Handles both directions:\n * - FK on child (Application.organizationId → Organization): set child FK to parent ID\n * - FK on parent (Member.userId → User): create child first, set parent FK to child ID\n *\n * Circular FK cycles (e.g. Application.mainBranchId ↔ Branch.applicationId) are handled\n * transparently: the nullable FK is omitted on the first create and emitted as a\n * DeferredUpdate to be applied via UPDATE after all records exist.\n */\nexport function resolveTree(\n create: Record<string, Record<string, unknown>[]>,\n schema: SchemaInfo,\n testRunId: string,\n): ResolvedTree {\n const relationByParentField = new Map<string, SchemaRelation>()\n for (const rel of schema.relations) {\n relationByParentField.set(`${rel.parentModel}.${rel.parentField}`, rel)\n }\n\n // Determine FK direction for each relation:\n // Is childField on the parent model or the child model?\n const fkOnParent = new Set<string>() // key: \"parentModel.parentField\"\n for (const rel of schema.relations) {\n const edge = schema.edges.find(\n (e) => e.localField === rel.childField && (e.from === rel.parentModel || e.from === rel.childModel),\n )\n if (edge && edge.from === rel.parentModel) {\n // FK column is on the parent model → create child first, then set parent FK\n fkOnParent.add(`${rel.parentModel}.${rel.parentField}`)\n }\n }\n\n const aliases = new Map<string, string>()\n const ops: CreateOp[] = []\n const deferredUpdates: DeferredUpdate[] = []\n let tempCounter = 0\n\n function makeTempId(model: string): string {\n return `__temp_${model}_${tempCounter++}`\n }\n\n function walkNode(\n modelName: string,\n node: Record<string, unknown>,\n parentTempId: string | null,\n parentRelation: SchemaRelation | null,\n parentFkOnParent: boolean,\n index: number,\n ): string {\n const fields: Record<string, unknown> = {}\n const preChildren: Array<{ relation: SchemaRelation; value: unknown; fkOnParent: boolean }> = []\n const postChildren: Array<{ relation: SchemaRelation; value: unknown; fkOnParent: boolean }> = []\n const alias = node._alias as string | undefined\n const tempId = makeTempId(modelName)\n\n for (const [key, value] of Object.entries(node)) {\n if (RESERVED_KEYS.has(key)) continue\n\n // Look up relation by exact key, then try fallbacks:\n // 1. Model name prefix: Test.steps → Test.testSteps (Prisma abbreviated names)\n // 2. Child model name: Organization.Application → Organization.applications\n // (scenarios using PascalCase model names as relation keys)\n const exactKey = `${modelName}.${key}`\n const prefixedKey = `${modelName}.${modelName.charAt(0).toLowerCase()}${modelName.slice(1)}${key.charAt(0).toUpperCase()}${key.slice(1)}`\n let relation = relationByParentField.get(exactKey) ?? relationByParentField.get(prefixedKey) ?? undefined\n let matchedKey = relationByParentField.has(exactKey) ? exactKey : prefixedKey\n if (!relation) {\n // Fallback: match by child model name (PascalCase keys like Application, Tag)\n for (const [relKey, rel] of relationByParentField) {\n if (relKey.startsWith(`${modelName}.`) && rel.childModel.toLowerCase() === key.toLowerCase()) {\n relation = rel\n matchedKey = relKey\n break\n }\n }\n }\n if (relation) {\n const isOnParent = fkOnParent.has(matchedKey)\n if (isOnParent) {\n // FK is on this model → need to create the child BEFORE this node\n preChildren.push({ relation, value, fkOnParent: true })\n } else {\n // FK is on the child → create child AFTER this node (normal)\n postChildren.push({ relation, value, fkOnParent: false })\n }\n continue\n }\n\n if (value && typeof value === 'object' && '_ref' in value) {\n const refAlias = (value as RefNode)._ref\n const refTempId = aliases.get(refAlias)\n if (!refTempId) {\n // Alias not created yet — defer this FK as an UPDATE after all creates.\n // This handles circular FK cycles (e.g. Application.mainBranchId → Branch\n // where Branch.applicationId → Application).\n deferredUpdates.push({ targetTempId: tempId, model: modelName, field: key, refAlias })\n continue\n }\n fields[key] = refTempId\n continue\n }\n\n const ctx: TemplateContext = { testRunId, index, }\n fields[key] = resolveTemplate(value, ctx)\n }\n\n // Wire FK to parent (if this node is a child and FK is on the child)\n if (parentRelation && parentTempId && !parentFkOnParent) {\n fields[parentRelation.childField] = parentTempId\n }\n\n // Process pre-children: these need to be created BEFORE this node\n // because this node's FK points to them\n for (const { relation, value, fkOnParent: isOnParent } of preChildren) {\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const childTempId = walkNode(relation.childModel, value[i] as Record<string, unknown>, tempId, relation, true, i)\n // Set this node's FK to point to the created child\n fields[relation.childField] = childTempId\n }\n }\n }\n\n // Create this node\n ops.push({ model: modelName, fields, tempId, batch: false })\n if (alias) aliases.set(alias, tempId)\n\n // Process post-children: normal case, FK is on the child\n for (const { relation, value } of postChildren) {\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n walkNode(relation.childModel, value[i] as Record<string, unknown>, tempId, relation, false, i)\n }\n } else if (value && typeof value === 'object' && '_count' in value) {\n const bulk = value as Record<string, unknown>\n const count = bulk._count as number\n const isBatch = (bulk._batch as boolean) ?? false\n\n for (let i = 0; i < count; i++) {\n const bulkFields: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(bulk)) {\n if (k === '_count' || k === '_batch') continue\n const ctx: TemplateContext = { testRunId, index: i, }\n bulkFields[k] = resolveTemplate(v, ctx)\n }\n bulkFields[relation.childField] = tempId\n ops.push({ model: relation.childModel, fields: bulkFields, tempId: makeTempId(relation.childModel), batch: isBatch })\n }\n }\n }\n\n return tempId\n }\n\n for (const [modelName, nodes] of Object.entries(create)) {\n for (let i = 0; i < nodes.length; i++) {\n walkNode(modelName, nodes[i]!, null, null, false, i)\n }\n }\n\n return { ops, deferredUpdates, aliases }\n}\n","export class AutonomaError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly status: number,\n ) {\n super(message)\n this.name = 'AutonomaError'\n }\n}\n\nexport const Errors = {\n unknownAction(action: string) {\n return new AutonomaError(\n `Unknown action: ${action}`,\n 'UNKNOWN_ACTION',\n 400,\n )\n },\n unknownEnvironment(name: string) {\n return new AutonomaError(\n `Unknown environment: ${name}`,\n 'UNKNOWN_ENVIRONMENT',\n 400,\n )\n },\n invalidSignature() {\n return new AutonomaError(\n 'Invalid HMAC signature',\n 'INVALID_SIGNATURE',\n 401,\n )\n },\n invalidRefsToken(reason: string) {\n return new AutonomaError(\n `Invalid refs token: ${reason}`,\n 'INVALID_REFS_TOKEN',\n 403,\n )\n },\n productionBlocked() {\n return new AutonomaError(\n 'Environment factory is disabled in production',\n 'PRODUCTION_BLOCKED',\n 404,\n )\n },\n invalidBody(reason: string) {\n return new AutonomaError(\n `Invalid request body: ${reason}`,\n 'INVALID_BODY',\n 400,\n )\n },\n} as const\n","// AUTO-GENERATED by protocol/sql/codegen.ts — do not edit\n\nexport const POSTGRES_COLUMNS = `SELECT\n table_name,\n column_name,\n data_type,\n udt_name,\n is_nullable,\n column_default\nFROM information_schema.columns\nWHERE table_schema = '{{schema}}'\nORDER BY table_name, ordinal_position`\n\nexport const POSTGRES_ENUMS = `SELECT t.typname AS enum_name, e.enumlabel AS enum_value\nFROM pg_type t\nJOIN pg_enum e ON t.oid = e.enumtypid\nJOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\nORDER BY t.typname, e.enumsortorder`\n\nexport const POSTGRES_FOREIGN_KEYS = `SELECT\n kcu.table_name AS from_table,\n kcu.column_name AS from_column,\n ccu.table_name AS to_table,\n ccu.column_name AS to_column,\n c.is_nullable\nFROM information_schema.table_constraints tc\nJOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\nJOIN information_schema.constraint_column_usage ccu\n ON tc.constraint_name = ccu.constraint_name\n AND tc.table_schema = ccu.table_schema\nLEFT JOIN information_schema.columns c\n ON c.table_schema = kcu.table_schema\n AND c.table_name = kcu.table_name\n AND c.column_name = kcu.column_name\nWHERE tc.constraint_type = 'FOREIGN KEY'\n AND tc.table_schema = '{{schema}}'\nORDER BY kcu.table_name, kcu.ordinal_position`\n\nexport const POSTGRES_PRIMARY_KEYS = `SELECT\n tc.table_name,\n kcu.column_name\nFROM information_schema.table_constraints tc\nJOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\nWHERE tc.constraint_type = 'PRIMARY KEY'\n AND tc.table_schema = '{{schema}}'\nORDER BY tc.table_name, kcu.ordinal_position`\n\nexport const POSTGRES_TABLES = `SELECT table_name\nFROM information_schema.tables\nWHERE table_schema = '{{schema}}'\n AND table_type = 'BASE TABLE'\nORDER BY table_name`\n\nexport const MYSQL_COLUMNS = `SELECT\n table_name,\n column_name,\n data_type,\n column_type AS udt_name,\n is_nullable,\n column_default\nFROM information_schema.columns\nWHERE table_schema = '{{schema}}'\nORDER BY table_name, ordinal_position`\n\nexport const MYSQL_ENUMS = `SELECT NULL AS enum_name, NULL AS enum_value FROM DUAL WHERE 1 = 0`\n\nexport const MYSQL_FOREIGN_KEYS = `SELECT\n kcu.table_name AS from_table,\n kcu.column_name AS from_column,\n kcu.referenced_table_name AS to_table,\n kcu.referenced_column_name AS to_column,\n c.is_nullable\nFROM information_schema.key_column_usage kcu\nJOIN information_schema.columns c\n ON c.table_schema = kcu.table_schema\n AND c.table_name = kcu.table_name\n AND c.column_name = kcu.column_name\nWHERE kcu.referenced_table_name IS NOT NULL\n AND kcu.table_schema = '{{schema}}'\nORDER BY kcu.table_name, kcu.ordinal_position`\n\nexport const MYSQL_PRIMARY_KEYS = `SELECT\n tc.table_name,\n kcu.column_name\nFROM information_schema.table_constraints tc\nJOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n AND tc.table_name = kcu.table_name\nWHERE tc.constraint_type = 'PRIMARY KEY'\n AND tc.table_schema = '{{schema}}'\nORDER BY tc.table_name, kcu.ordinal_position`\n\nexport const MYSQL_TABLES = `SELECT table_name\nFROM information_schema.tables\nWHERE table_schema = '{{schema}}'\n AND table_type = 'BASE TABLE'\nORDER BY table_name`\n","/** Database dialect abstraction — generates dialect-specific SQL strings. */\n\nimport {\n POSTGRES_TABLES,\n POSTGRES_COLUMNS,\n POSTGRES_PRIMARY_KEYS,\n POSTGRES_FOREIGN_KEYS,\n POSTGRES_ENUMS,\n MYSQL_TABLES,\n MYSQL_COLUMNS,\n MYSQL_PRIMARY_KEYS,\n MYSQL_FOREIGN_KEYS,\n MYSQL_ENUMS,\n} from './generated/sql-queries'\n\nexport interface Dialect {\n readonly name: 'postgres' | 'mysql' | 'sqlite'\n /** Parameter placeholder for index (1-based). Postgres: $1, MySQL/SQLite: ? */\n param(index: number): string\n /** Quote an identifier. Postgres: \"name\", MySQL: `name` */\n quoteId(name: string): string\n /** Whether INSERT ... RETURNING is supported */\n readonly supportsReturning: boolean\n\n /** SQL to list all base tables in a schema/database */\n tablesSQL(schema: string): string\n /** SQL to list all columns for all tables in a schema/database */\n columnsSQL(schema: string): string\n /** SQL to list primary key columns */\n primaryKeysSQL(schema: string): string\n /** SQL to list foreign key relationships */\n foreignKeysSQL(schema: string): string\n /** SQL to list enum types and their values */\n enumsSQL(schema: string): string\n}\n\nconst replaceSchema = (template: string, schema: string) =>\n template.replace('{{schema}}', schema)\n\nexport const postgres: Dialect = {\n name: 'postgres',\n param: (i) => `$${i}`,\n quoteId: (name) => `\"${name}\"`,\n supportsReturning: true,\n\n tablesSQL: (schema) => replaceSchema(POSTGRES_TABLES, schema),\n columnsSQL: (schema) => replaceSchema(POSTGRES_COLUMNS, schema),\n primaryKeysSQL: (schema) => replaceSchema(POSTGRES_PRIMARY_KEYS, schema),\n foreignKeysSQL: (schema) => replaceSchema(POSTGRES_FOREIGN_KEYS, schema),\n enumsSQL: () => POSTGRES_ENUMS,\n}\n\nexport const mysql: Dialect = {\n name: 'mysql',\n param: () => '?',\n quoteId: (name) => `\\`${name}\\``,\n supportsReturning: false,\n\n tablesSQL: (schema) => replaceSchema(MYSQL_TABLES, schema),\n columnsSQL: (schema) => replaceSchema(MYSQL_COLUMNS, schema),\n primaryKeysSQL: (schema) => replaceSchema(MYSQL_PRIMARY_KEYS, schema),\n foreignKeysSQL: (schema) => replaceSchema(MYSQL_FOREIGN_KEYS, schema),\n enumsSQL: () => MYSQL_ENUMS,\n}\n\nexport function getDialect(name: 'postgres' | 'mysql' | 'sqlite' = 'postgres'): Dialect {\n switch (name) {\n case 'postgres':\n return postgres\n case 'mysql':\n return mysql\n default:\n throw new Error(`Dialect \"${name}\" is not yet supported. Currently only \"postgres\" and \"mysql\" are available.`)\n }\n}\n","import type { SQLExecutor, SchemaInfo, SchemaRelation, ModelInfo, FieldInfo, FKEdge } from './types'\nimport type { Dialect } from './dialect'\n\n/** Internal result including name mapping tables */\nexport interface IntrospectionResult {\n schema: SchemaInfo\n /** model name → DB table name */\n tableMap: Map<string, string>\n /** model name → (field name → DB column name) */\n columnMaps: Map<string, Map<string, string>>\n /** model name → (field name → Postgres enum type name). Only populated for Postgres. */\n enumTypeMaps: Map<string, Map<string, string>>\n}\n\ninterface TableRow { table_name: string }\ninterface ColumnRow {\n table_name: string\n column_name: string\n data_type: string\n udt_name: string\n is_nullable: string\n column_default: string | null\n}\ninterface PKRow { table_name: string; column_name: string }\ninterface FKRow {\n from_table: string\n from_column: string\n to_table: string\n to_column: string\n is_nullable: string\n}\ninterface EnumRow { enum_name: string; enum_value: string }\n\n/**\n * Introspect a database via information_schema to build SchemaInfo.\n *\n * Auto-maps DB names (snake_case) to model names (PascalCase) and\n * field names (camelCase). Override with `tableNameMap`.\n */\nexport async function introspectDatabase(\n executor: SQLExecutor,\n dialect: Dialect,\n config: {\n scopeField: string\n schema?: string\n tableNameMap?: Record<string, string>\n excludeTables?: string[]\n },\n): Promise<IntrospectionResult> {\n const dbSchema = config.schema ?? (dialect.name === 'mysql' ? undefined : 'public')\n if (!dbSchema) {\n throw new Error('MySQL requires a schema (database name). Pass it via config.schema or HandlerConfig.dbSchema.')\n }\n const excludeSet = new Set(config.excludeTables ?? ['_prisma_migrations'])\n\n // Run all introspection queries in parallel.\n // Normalize row keys to lowercase — MySQL's information_schema can return\n // column names in uppercase (TABLE_NAME vs table_name).\n const [tableRows, columnRows, pkRows, fkRows, enumRows] = await Promise.all([\n executor.query<TableRow>(dialect.tablesSQL(dbSchema)).then(normalizeKeys),\n executor.query<ColumnRow>(dialect.columnsSQL(dbSchema)).then(normalizeKeys),\n executor.query<PKRow>(dialect.primaryKeysSQL(dbSchema)).then(normalizeKeys),\n executor.query<FKRow>(dialect.foreignKeysSQL(dbSchema)).then(normalizeKeys),\n executor.query<EnumRow>(dialect.enumsSQL(dbSchema)).then(normalizeKeys),\n ])\n\n // Build enum lookup: name → values[]\n // For Postgres: from pg_type/pg_enum rows\n // For MySQL: extracted from column_type in the column rows below\n const enumValues = new Map<string, string[]>()\n for (const row of enumRows) {\n if (!row.enum_name) continue\n if (!enumValues.has(row.enum_name)) enumValues.set(row.enum_name, [])\n enumValues.get(row.enum_name)!.push(row.enum_value)\n }\n\n // For MySQL, parse inline enums from column_type (udt_name alias)\n // e.g. \"enum('WEB','ANDROID','IOS')\" → ['WEB','ANDROID','IOS']\n if (dialect.name === 'mysql') {\n for (const col of columnRows) {\n const parsed = parseMySQLEnum(col.udt_name)\n if (parsed) {\n const enumKey = `${col.table_name}.${col.column_name}`\n enumValues.set(enumKey, parsed)\n }\n }\n }\n\n // Build PK lookup: table_name → Set<column_name>\n const pksByTable = new Map<string, Set<string>>()\n for (const row of pkRows) {\n if (!pksByTable.has(row.table_name)) pksByTable.set(row.table_name, new Set())\n pksByTable.get(row.table_name)!.add(row.column_name)\n }\n\n // Build table name mapping\n const userMap = config.tableNameMap ?? {}\n const tableMap = new Map<string, string>()\n const reverseTableMap = new Map<string, string>()\n\n // First, register user-provided mappings\n for (const [model, dbTable] of Object.entries(userMap)) {\n tableMap.set(model, dbTable)\n reverseTableMap.set(dbTable, model)\n }\n\n // Then auto-map remaining tables\n const dbTables = tableRows\n .map((r) => r.table_name)\n .filter((t) => !excludeSet.has(t))\n\n for (const dbTable of dbTables) {\n if (reverseTableMap.has(dbTable)) continue\n const modelName = snakeToPascal(dbTable)\n tableMap.set(modelName, dbTable)\n reverseTableMap.set(dbTable, modelName)\n }\n\n // Build column maps and model info\n const models: ModelInfo[] = []\n const columnMaps = new Map<string, Map<string, string>>()\n const enumTypeMaps = new Map<string, Map<string, string>>()\n\n // Group columns by table\n const columnsByTable = new Map<string, ColumnRow[]>()\n for (const row of columnRows) {\n if (!columnsByTable.has(row.table_name)) columnsByTable.set(row.table_name, [])\n columnsByTable.get(row.table_name)!.push(row)\n }\n\n for (const [modelName, dbTable] of tableMap) {\n const cols = columnsByTable.get(dbTable) ?? []\n const pks = pksByTable.get(dbTable) ?? new Set<string>()\n const colMap = new Map<string, string>()\n const fields: FieldInfo[] = []\n\n for (const col of cols) {\n const fieldName = snakeToCamel(col.column_name)\n colMap.set(fieldName, col.column_name)\n\n // Check for enum values\n let enumVals: string[] | undefined\n if (dialect.name === 'mysql') {\n enumVals = enumValues.get(`${col.table_name}.${col.column_name}`)\n } else {\n enumVals = enumValues.get(col.udt_name)\n }\n\n const type = enumVals\n ? `enum(${enumVals.join(',')})`\n : mapDataType(col.data_type, col.udt_name, dialect.name)\n\n // Track Postgres types that need explicit parameter casting.\n // Prisma's $queryRawUnsafe sends string params as explicit text type,\n // preventing Postgres auto-cast for enums, jsonb, and timestamps.\n if (dialect.name === 'postgres') {\n if (enumVals) {\n if (!enumTypeMaps.has(modelName)) enumTypeMaps.set(modelName, new Map())\n enumTypeMaps.get(modelName)!.set(fieldName, col.udt_name)\n } else if (col.data_type === 'jsonb' || col.udt_name === 'jsonb' || col.data_type === 'json' || col.udt_name === 'json') {\n if (!enumTypeMaps.has(modelName)) enumTypeMaps.set(modelName, new Map())\n const jsonType = (col.data_type === 'json' || col.udt_name === 'json') ? 'json' : 'jsonb'\n enumTypeMaps.get(modelName)!.set(fieldName, jsonType)\n } else if (col.data_type.includes('timestamp') || col.udt_name === 'timestamptz' || col.udt_name === 'timestamp') {\n if (!enumTypeMaps.has(modelName)) enumTypeMaps.set(modelName, new Map())\n enumTypeMaps.get(modelName)!.set(fieldName, col.udt_name)\n }\n }\n\n fields.push({\n name: fieldName,\n type,\n isRequired: col.is_nullable === 'NO',\n isId: pks.has(col.column_name),\n hasDefault: col.column_default !== null,\n })\n }\n\n columnMaps.set(modelName, colMap)\n models.push({ name: modelName, tableName: dbTable, fields })\n }\n\n // Build FK edges\n const edges: FKEdge[] = []\n for (const fk of fkRows) {\n const fromModel = reverseTableMap.get(fk.from_table)\n const toModel = reverseTableMap.get(fk.to_table)\n if (!fromModel || !toModel) continue\n\n const fromColMap = columnMaps.get(fromModel)\n const toColMap = columnMaps.get(toModel)\n const localField = fromColMap ? reverseGet(fromColMap, fk.from_column) ?? fk.from_column : fk.from_column\n const foreignField = toColMap ? reverseGet(toColMap, fk.to_column) ?? fk.to_column : fk.to_column\n\n edges.push({\n from: fromModel,\n to: toModel,\n localField,\n foreignField,\n nullable: fk.is_nullable === 'YES',\n })\n }\n\n // Build relations from FK edges.\n // For each edge (from→to), generate two relations:\n // 1. Parent-side: on the \"to\" model, a field pointing to \"from\" model (e.g., Organization.members)\n // 2. Child-side: on the \"from\" model, a field pointing to \"to\" model (e.g., Member.organization)\n const relations: SchemaRelation[] = []\n for (const edge of edges) {\n // Detect one-to-one: if the FK column is the sole PK of the child table,\n // the relationship is one-to-one (e.g., WebApplicationData.applicationId is\n // both PK and FK → Application has singular webApplicationData, not plural).\n const fromDbTable = tableMap.get(edge.from)!\n const fromColMap = columnMaps.get(edge.from) ?? new Map<string, string>()\n const fkDbCol = fromColMap.get(edge.localField) ?? edge.localField\n const fromPks = pksByTable.get(fromDbTable)\n const isOneToOne = fromPks !== undefined && fromPks.size === 1 && fromPks.has(fkDbCol)\n\n // Parent-side: \"to\" model has a collection/reference to \"from\" model\n relations.push({\n parentModel: edge.to,\n childModel: edge.from,\n parentField: isOneToOne ? lowerFirst(edge.from) : pluralCamelCase(edge.from),\n childField: edge.localField,\n })\n\n // Child-side: \"from\" model has a singular reference to \"to\" model (FK is on this side)\n relations.push({\n parentModel: edge.from,\n childModel: edge.to,\n parentField: lowerFirst(edge.to),\n childField: edge.localField,\n })\n }\n\n return {\n schema: { models, edges, relations, scopeField: config.scopeField },\n tableMap,\n columnMaps,\n enumTypeMaps,\n }\n}\n\n// --- Name mapping utilities ---\n\nfunction snakeToPascal(str: string): string {\n return str\n .split('_')\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\n .join('')\n}\n\nfunction snakeToCamel(str: string): string {\n const pascal = snakeToPascal(str)\n return pascal.charAt(0).toLowerCase() + pascal.slice(1)\n}\n\n/**\n * Parse MySQL inline enum definition: \"enum('a','b','c')\" → ['a','b','c']\n */\nfunction parseMySQLEnum(columnType: string): string[] | null {\n if (!columnType) return null\n const match = columnType.match(/^enum\\((.+)\\)$/i)\n if (!match) return null\n return match[1]!\n .split(',')\n .map((v) => v.trim().replace(/^'|'$/g, ''))\n}\n\nfunction mapDataType(dataType: string, udtName: string, dialectName: string): string {\n const dt = dataType.toLowerCase()\n\n // MySQL tinyint(1) is conventionally Boolean — check column_type (udtName) before generic tinyint mapping.\n // data_type from information_schema is just \"tinyint\"; the display width lives in udt_name (column_type).\n if (dialectName === 'mysql' && dt === 'tinyint' && udtName.toLowerCase().startsWith('tinyint(1)')) return 'Boolean'\n\n // Integer types\n if (dt === 'integer' || dt === 'smallint' || dt === 'bigint' || dt === 'int' || dt === 'mediumint' || dt === 'tinyint') return 'Int'\n\n // Float types\n if (dt === 'numeric' || dt === 'real' || dt === 'double precision' || dt === 'float' || dt === 'double' || dt === 'decimal') return 'Float'\n\n // Boolean (Postgres native boolean type, or tinyint(1) when data_type includes display width)\n if (dt === 'boolean' || dt === 'tinyint(1)') return 'Boolean'\n\n // String types\n if (dt === 'text' || dt === 'character varying' || dt === 'character' || dt === 'varchar' || dt === 'char'\n || dt === 'mediumtext' || dt === 'longtext' || dt === 'tinytext') return 'String'\n\n // DateTime types\n if (dt === 'timestamp with time zone' || dt === 'timestamp without time zone'\n || dt === 'date' || dt === 'time' || dt === 'datetime' || dt === 'timestamp') return 'DateTime'\n\n // JSON types\n if (dt === 'json' || dt === 'jsonb') return 'Json'\n\n // UUID / binary\n if (dt === 'uuid') return 'String'\n if (dt === 'bytea' || dt === 'blob' || dt === 'mediumblob' || dt === 'longblob' || dt === 'tinyblob' || dt === 'binary' || dt === 'varbinary') return 'Bytes'\n\n // Postgres user-defined (enums handled by caller)\n if (dt === 'user-defined' && dialectName === 'postgres') return udtName\n\n // MySQL enum is handled before this function is called\n if (dt === 'enum' || dt === 'set') return udtName\n\n return dataType\n}\n\nfunction lowerFirst(str: string): string {\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n\n/**\n * Convert a PascalCase model name to a camelCase plural field name.\n * e.g., \"Member\" → \"members\", \"Application\" → \"applications\", \"ApiKey\" → \"apiKeys\"\n */\nfunction pluralCamelCase(modelName: string): string {\n const camel = lowerFirst(modelName)\n return pluralize(camel)\n}\n\nfunction pluralize(str: string): string {\n if (str.endsWith('s') || str.endsWith('x') || str.endsWith('z') || str.endsWith('ch') || str.endsWith('sh')) {\n return str + 'es'\n }\n if (str.endsWith('y') && str.length > 1 && !isVowel(str.charAt(str.length - 2))) {\n return str.slice(0, -1) + 'ies'\n }\n return str + 's'\n}\n\nfunction isVowel(ch: string): boolean {\n return 'aeiou'.includes(ch.toLowerCase())\n}\n\n/**\n * Lowercase all keys in each row — handles MySQL information_schema returning\n * uppercase column names (TABLE_NAME, COLUMN_NAME, etc.)\n */\nfunction normalizeKeys<T>(rows: T[]): T[] {\n return rows.map((row) => {\n if (!row || typeof row !== 'object') return row\n const normalized: Record<string, unknown> = {}\n for (const [key, val] of Object.entries(row as Record<string, unknown>)) {\n normalized[key.toLowerCase()] = val\n }\n return normalized as T\n })\n}\n\n/** Reverse lookup: find the key whose value matches `dbName` */\nfunction reverseGet(map: Map<string, string>, dbName: string): string | null {\n for (const [key, val] of map) {\n if (val === dbName) return key\n }\n return null\n}\n","import { randomUUID } from 'node:crypto'\nimport type { SQLExecutor, ResolvedEntitySpec, CreateContext } from './types'\nimport type { Dialect } from './dialect'\n\n/**\n * Create entities via raw SQL INSERT.\n *\n * Entities arrive pre-sorted by FK order (handler does topo-sort via tree.ts).\n * Each model in `spec` is inserted sequentially; within a model, batch mode\n * uses a single multi-row INSERT while normal mode inserts one row at a time.\n *\n * For dialects with RETURNING (Postgres): INSERT ... RETURNING *\n * For dialects without (MySQL): INSERT then SELECT via LAST_INSERT_ID()\n */\nexport async function createEntities(\n executor: SQLExecutor,\n dialect: Dialect,\n tableMap: Map<string, string>,\n columnMaps: Map<string, Map<string, string>>,\n spec: Record<string, ResolvedEntitySpec>,\n _context: CreateContext,\n enumTypeMaps: Map<string, Map<string, string>> = new Map(),\n): Promise<Record<string, Record<string, unknown>[]>> {\n const results: Record<string, Record<string, unknown>[]> = {}\n\n for (const [model, entitySpec] of Object.entries(spec)) {\n const dbTable = tableMap.get(model)\n if (!dbTable) throw new Error(`Unknown model \"${model}\". Not found in database tables.`)\n const colMap = columnMaps.get(model) ?? new Map<string, string>()\n const enumTypeMap = enumTypeMaps.get(model) ?? new Map<string, string>()\n\n if (entitySpec.batch && entitySpec.fields.length > 0) {\n results[model] = await insertBatch(executor, dialect, dbTable, colMap, enumTypeMap, entitySpec.fields)\n } else {\n const created: Record<string, unknown>[] = []\n for (const fields of entitySpec.fields) {\n const [record] = await insertOne(executor, dialect, dbTable, colMap, enumTypeMap, fields)\n if (record) created.push(record)\n }\n results[model] = created\n }\n }\n\n return results\n}\n\n/**\n * Update a single record by primary key. Used for circular FK backfill.\n */\nexport async function updateEntity(\n executor: SQLExecutor,\n dialect: Dialect,\n tableMap: Map<string, string>,\n columnMaps: Map<string, Map<string, string>>,\n model: string,\n id: string,\n fields: Record<string, unknown>,\n enumTypeMaps: Map<string, Map<string, string>> = new Map(),\n): Promise<void> {\n const dbTable = tableMap.get(model)\n if (!dbTable) throw new Error(`Unknown model \"${model}\" for update.`)\n const colMap = columnMaps.get(model) ?? new Map<string, string>()\n const enumTypeMap = enumTypeMaps.get(model) ?? new Map<string, string>()\n\n const setClauses: string[] = []\n const params: unknown[] = []\n let paramIdx = 1\n\n for (const [fieldName, value] of Object.entries(fields)) {\n const dbCol = colMap.get(fieldName) ?? fieldName\n setClauses.push(`${dialect.quoteId(dbCol)} = ${castParam(dialect, paramIdx, enumTypeMap, fieldName)}`)\n params.push(serializeValue(value, dialect))\n paramIdx++\n }\n\n const idCol = colMap.get('id') ?? 'id'\n params.push(id)\n\n const sql = `UPDATE ${dialect.quoteId(dbTable)} SET ${setClauses.join(', ')} WHERE ${dialect.quoteId(idCol)} = ${dialect.param(paramIdx)}`\n await executor.query(sql, params)\n}\n\n// --- Internal helpers ---\n\nasync function insertOne(\n executor: SQLExecutor,\n dialect: Dialect,\n dbTable: string,\n colMap: Map<string, string>,\n enumTypeMap: Map<string, string>,\n fields: Record<string, unknown>,\n): Promise<Record<string, unknown>[]> {\n // Generate a client-side ID when none is provided and the table has an 'id' column.\n // Many ORMs (e.g. Prisma's @default(cuid())) generate IDs in the application\n // layer, not as DB-level defaults. Without this, INSERT would send NULL for\n // the PK column and fail with a NOT NULL violation.\n // Tables whose PK is not named 'id' (e.g. WebApplicationData uses applicationId\n // as its PK) already have their PK set via FK wiring, so we skip injection.\n const idFieldName = reverseGet(colMap, findIdCol(colMap))\n if (idFieldName && fields[idFieldName] === undefined) {\n fields = { ...fields, [idFieldName]: randomUUID() }\n }\n\n const entries = Object.entries(fields)\n\n if (entries.length === 0) {\n const sql = `INSERT INTO ${dialect.quoteId(dbTable)} DEFAULT VALUES RETURNING *`\n return mapRowsBack(await executor.query(sql), colMap)\n }\n\n const dbCols: string[] = []\n const params: unknown[] = []\n const placeholders: string[] = []\n let paramIdx = 1\n\n for (const [fieldName, value] of entries) {\n const dbCol = colMap.get(fieldName) ?? fieldName\n dbCols.push(dialect.quoteId(dbCol))\n placeholders.push(castParam(dialect, paramIdx, enumTypeMap, fieldName))\n params.push(serializeValue(value, dialect))\n paramIdx++\n }\n\n const colList = dbCols.join(', ')\n const valList = placeholders.join(', ')\n\n if (dialect.supportsReturning) {\n const sql = `INSERT INTO ${dialect.quoteId(dbTable)} (${colList}) VALUES (${valList}) RETURNING *`\n return mapRowsBack(await executor.query(sql, params), colMap)\n }\n\n // MySQL: INSERT then SELECT back by the ID we set\n await executor.query(\n `INSERT INTO ${dialect.quoteId(dbTable)} (${colList}) VALUES (${valList})`,\n params,\n )\n\n const idCol = findIdCol(colMap)\n const id = fields[idFieldName ?? 'id']\n\n return mapRowsBack(\n await executor.query(\n `SELECT * FROM ${dialect.quoteId(dbTable)} WHERE ${dialect.quoteId(idCol)} = ${dialect.param(1)}`,\n [id],\n ),\n colMap,\n )\n}\n\nasync function insertBatch(\n executor: SQLExecutor,\n dialect: Dialect,\n dbTable: string,\n colMap: Map<string, string>,\n enumTypeMap: Map<string, string>,\n fieldsArr: Record<string, unknown>[],\n): Promise<Record<string, unknown>[]> {\n if (fieldsArr.length === 0) return []\n\n // Generate client-side IDs for batch records, same as insertOne.\n // Only inject if the table actually has an 'id' column.\n const idFieldName = reverseGet(colMap, findIdCol(colMap))\n if (idFieldName) {\n fieldsArr = fieldsArr.map((fields) => {\n if (fields[idFieldName] === undefined) {\n return { ...fields, [idFieldName]: randomUUID() }\n }\n return fields\n })\n }\n\n // Compute the union of keys across all rows in deterministic (sorted) order.\n const fieldNameSet = new Set<string>()\n for (const fields of fieldsArr) {\n for (const key of Object.keys(fields)) {\n fieldNameSet.add(key)\n }\n }\n const fieldNames = [...fieldNameSet].sort()\n\n // If no fields at all, fall back to individual DEFAULT VALUES inserts.\n if (fieldNames.length === 0) {\n const allResults: Record<string, unknown>[] = []\n for (const fields of fieldsArr) {\n const [record] = await insertOne(executor, dialect, dbTable, colMap, enumTypeMap, fields)\n if (record) allResults.push(record)\n }\n return allResults\n }\n\n const dbCols = fieldNames.map((f) => dialect.quoteId(colMap.get(f) ?? f))\n const colList = dbCols.join(', ')\n\n // Postgres has a max of 32,767 bind variables per statement.\n // Chunk large batches to stay within this limit.\n const MAX_PARAMS = 32_000\n const chunkSize = Math.max(1, Math.floor(MAX_PARAMS / fieldNames.length))\n const allResults: Record<string, unknown>[] = []\n\n for (let offset = 0; offset < fieldsArr.length; offset += chunkSize) {\n const chunk = fieldsArr.slice(offset, offset + chunkSize)\n const params: unknown[] = []\n const valueTuples: string[] = []\n let paramIdx = 1\n\n for (const fields of chunk) {\n const placeholders: string[] = []\n for (const fieldName of fieldNames) {\n placeholders.push(castParam(dialect, paramIdx, enumTypeMap, fieldName))\n params.push(serializeValue(fields[fieldName], dialect))\n paramIdx++\n }\n valueTuples.push(`(${placeholders.join(', ')})`)\n }\n\n const valList = valueTuples.join(', ')\n\n if (dialect.supportsReturning) {\n const sql = `INSERT INTO ${dialect.quoteId(dbTable)} (${colList}) VALUES ${valList} RETURNING *`\n allResults.push(...mapRowsBack(await executor.query(sql, params), colMap))\n } else {\n await executor.query(\n `INSERT INTO ${dialect.quoteId(dbTable)} (${colList}) VALUES ${valList}`,\n params,\n )\n }\n }\n\n return allResults\n}\n\n/**\n * Map DB column names back to camelCase field names in returned rows.\n */\nfunction mapRowsBack(\n rows: Record<string, unknown>[],\n colMap: Map<string, string>,\n): Record<string, unknown>[] {\n if (colMap.size === 0) return rows\n\n const reverse = new Map<string, string>()\n for (const [fieldName, dbCol] of colMap) {\n reverse.set(dbCol, fieldName)\n }\n\n return rows.map((row) => {\n const mapped: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(row)) {\n const fieldName = reverse.get(key) ?? key\n mapped[fieldName] = value\n }\n return mapped\n })\n}\n\nfunction findIdCol(colMap: Map<string, string>): string {\n return colMap.get('id') ?? 'id'\n}\n\nfunction reverseGet(map: Map<string, string>, dbName: string): string | null {\n for (const [key, val] of map) {\n if (val === dbName) return key\n }\n return null\n}\n\n/**\n * Build a parameter placeholder with an optional Postgres enum cast.\n * e.g. `$1::\"ApplicationArchitecture\"` for enum fields, or just `$1` otherwise.\n */\nfunction castParam(\n dialect: Dialect,\n paramIdx: number,\n enumTypeMap: Map<string, string>,\n fieldName: string,\n): string {\n const placeholder = dialect.param(paramIdx)\n if (dialect.name === 'postgres') {\n const enumType = enumTypeMap.get(fieldName)\n if (enumType) return `${placeholder}::${dialect.quoteId(enumType)}`\n }\n return placeholder\n}\n\n/** Pre-compiled regex for MySQL datetime detection (avoids re-compilation per call). */\nconst MYSQL_DATETIME_RE = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/\n\n/**\n * Serialize a JS value for SQL insertion.\n * Handles MySQL-specific quirks:\n * - Objects/arrays → JSON.stringify (MySQL requires JSON strings, not objects)\n * - ISO 8601 datetime strings → MySQL DATETIME format\n */\nfunction serializeValue(value: unknown, dialect: Dialect): unknown {\n if (value === null || value === undefined) return null\n\n // JSON: Both MySQL and Postgres need stringified JSON when using parameterized\n // queries with explicit casts (e.g. $1::jsonb). Postgres $queryRawUnsafe cannot\n // pass JS objects directly as parameters.\n if (typeof value === 'object' && !(value instanceof Date)) {\n return JSON.stringify(value)\n }\n\n // DateTime: MySQL doesn't accept ISO 8601 with 'T' and 'Z'\n if (typeof value === 'string' && dialect.name === 'mysql') {\n if (MYSQL_DATETIME_RE.test(value)) {\n return value.replace('T', ' ').replace('Z', '').replace(/\\.\\d+$/, '')\n }\n }\n\n return value\n}\n","import type { SQLExecutor, SchemaInfo } from './types'\nimport type { Dialect } from './dialect'\nimport { topoSort, findDeferrableEdge } from './graph'\n\n/**\n * Tear down all data scoped to a value, in reverse topological order.\n *\n * Strategy:\n * 1. Find the scope root model (e.g. Organization) from FK edges\n * 2. Any model with a FK pointing to the scope root is \"scoped\"\n * 3. Delete scoped models by their FK = scopeValue\n * 4. Delete non-scoped models by their record IDs from refs\n * 5. Delete the scope root entity last by id = scopeValue\n */\nexport async function teardown(\n executor: SQLExecutor,\n dialect: Dialect,\n tableMap: Map<string, string>,\n columnMaps: Map<string, Map<string, string>>,\n schema: SchemaInfo,\n scopeValue: string,\n refs?: Record<string, Record<string, unknown>[]>,\n): Promise<void> {\n // Find scope root: the model that the scopeField FK points TO\n let scopeRootModel: string | null = null\n for (const edge of schema.edges) {\n if (edge.localField.toLowerCase() === schema.scopeField.toLowerCase() && edge.to !== edge.from) {\n scopeRootModel = edge.to\n break\n }\n }\n\n // Build map: model → FK field name that points to the scope root\n const scopeFieldByModel = new Map<string, string>()\n if (scopeRootModel) {\n for (const edge of schema.edges) {\n if (edge.to === scopeRootModel && edge.from !== scopeRootModel) {\n scopeFieldByModel.set(edge.from, edge.localField)\n }\n }\n }\n\n const modelNames = schema.models.map((m) => m.name)\n const { sorted, cycles } = topoSort(modelNames, schema.edges)\n\n await executor.transaction(async (tx) => {\n // Break cycles by nullifying deferrable FKs\n for (const cycle of cycles) {\n const edge = findDeferrableEdge(cycle, schema.edges)\n if (edge) {\n const scopeFK = scopeFieldByModel.get(edge.from)\n if (scopeFK) {\n const dbTable = tableMap.get(edge.from)\n const colMap = columnMaps.get(edge.from) ?? new Map<string, string>()\n if (dbTable) {\n const dbFKCol = colMap.get(edge.localField) ?? edge.localField\n const dbScopeCol = colMap.get(scopeFK) ?? scopeFK\n await tx.query(\n `UPDATE ${dialect.quoteId(dbTable)} SET ${dialect.quoteId(dbFKCol)} = NULL WHERE ${dialect.quoteId(dbScopeCol)} = ${dialect.param(1)}`,\n [scopeValue],\n )\n }\n }\n }\n }\n\n // Delete cycle nodes\n for (const cycle of cycles) {\n for (const model of cycle) {\n await deleteModel(tx, dialect, tableMap, columnMaps, model, scopeValue, scopeFieldByModel, refs)\n }\n }\n\n // Delete in reverse topo order (dependents first)\n const reversed = [...sorted].reverse()\n for (const model of reversed) {\n if (model === scopeRootModel) continue // deleted last\n await deleteModel(tx, dialect, tableMap, columnMaps, model, scopeValue, scopeFieldByModel, refs)\n }\n\n // Delete the scope root entity last\n if (scopeRootModel) {\n const dbTable = tableMap.get(scopeRootModel)\n const colMap = columnMaps.get(scopeRootModel) ?? new Map<string, string>()\n if (dbTable) {\n const idCol = colMap.get('id') ?? 'id'\n await tx.query(\n `DELETE FROM ${dialect.quoteId(dbTable)} WHERE ${dialect.quoteId(idCol)} = ${dialect.param(1)}`,\n [scopeValue],\n )\n }\n }\n })\n}\n\nasync function deleteModel(\n tx: SQLExecutor,\n dialect: Dialect,\n tableMap: Map<string, string>,\n columnMaps: Map<string, Map<string, string>>,\n model: string,\n scopeValue: string,\n scopeFieldByModel: Map<string, string>,\n refs?: Record<string, Record<string, unknown>[]>,\n): Promise<void> {\n const dbTable = tableMap.get(model)\n if (!dbTable) return\n const colMap = columnMaps.get(model) ?? new Map<string, string>()\n\n const scopeFK = scopeFieldByModel.get(model)\n if (scopeFK) {\n // Has FK to scope root → delete by that FK\n const dbCol = colMap.get(scopeFK) ?? scopeFK\n await tx.query(\n `DELETE FROM ${dialect.quoteId(dbTable)} WHERE ${dialect.quoteId(dbCol)} = ${dialect.param(1)}`,\n [scopeValue],\n )\n } else if (refs?.[model]) {\n // No FK to scope root, but we created records → delete by IDs\n const ids = refs[model]\n .map((r) => r.id)\n .filter((id): id is string => typeof id === 'string')\n if (ids.length > 0) {\n const idCol = colMap.get('id') ?? 'id'\n const placeholders = ids.map((_, i) => dialect.param(i + 1)).join(', ')\n await tx.query(\n `DELETE FROM ${dialect.quoteId(dbTable)} WHERE ${dialect.quoteId(idCol)} IN (${placeholders})`,\n ids,\n )\n }\n }\n}\n","import type {\n HandlerConfig,\n HandlerRequest,\n HandlerResponse,\n ResolvedEntitySpec,\n SdkInfo,\n} from './types'\nimport { verifySignature } from './hmac'\nimport { signRefs, verifyRefs } from './refs'\nimport { resolveTree } from './tree'\nimport { AutonomaError, Errors } from './errors'\nimport { getDialect } from './dialect'\nimport { introspectDatabase, type IntrospectionResult } from './introspect'\nimport { createEntities, updateEntity } from './create'\nimport { teardown } from './teardown'\n\n/** Cache introspection results per config to avoid re-querying on every request */\nconst introspectionCache = new WeakMap<HandlerConfig, IntrospectionResult>()\n\nasync function getIntrospection(config: HandlerConfig): Promise<IntrospectionResult> {\n let cached = introspectionCache.get(config)\n if (cached) return cached\n\n const dialect = getDialect(config.dialect)\n cached = await introspectDatabase(config.executor, dialect, {\n scopeField: config.scopeField,\n schema: config.dbSchema,\n tableNameMap: config.tableNameMap,\n excludeTables: config.excludeTables,\n })\n introspectionCache.set(config, cached)\n return cached\n}\n\ndeclare const __PROTOCOL_VERSION__: string\nexport const PROTOCOL_VERSION = __PROTOCOL_VERSION__\n\nfunction buildSdkMeta(config: HandlerConfig): { version: string; sdk: SdkInfo } {\n return {\n version: PROTOCOL_VERSION,\n sdk: {\n language: 'typescript',\n orm: config.sdk?.orm ?? 'unknown',\n server: config.sdk?.server ?? 'unknown',\n },\n }\n}\n\nexport async function handleRequest(\n config: HandlerConfig,\n req: HandlerRequest,\n): Promise<HandlerResponse> {\n try {\n if (config.sharedSecret === config.signingSecret) {\n throw new AutonomaError(\n 'sharedSecret and signingSecret must be different. The shared secret is known by Autonoma; the signing secret must be private.',\n 'SAME_SECRETS',\n 500,\n )\n }\n\n if (!config.allowProduction && process.env.NODE_ENV === 'production') {\n throw Errors.productionBlocked()\n }\n\n const signature = req.headers['x-signature'] ?? req.headers['X-Signature'] ?? ''\n if (!verifySignature(req.body, signature, config.sharedSecret)) {\n throw Errors.invalidSignature()\n }\n\n let body: Record<string, unknown>\n try {\n body = JSON.parse(req.body)\n } catch {\n throw Errors.invalidBody('invalid JSON')\n }\n\n const action = body.action as string\n if (!action) throw Errors.invalidBody('missing action')\n\n switch (action) {\n case 'discover':\n return await handleDiscover(config)\n case 'up':\n return await handleUp(config, body)\n case 'down':\n return await handleDown(config, body)\n default:\n throw Errors.unknownAction(action)\n }\n } catch (err) {\n if (err instanceof AutonomaError) {\n return { status: err.status, body: { error: err.message, code: err.code } }\n }\n const message = err instanceof Error ? err.message : 'Internal error'\n return { status: 500, body: { error: message, code: 'INTERNAL_ERROR' } }\n }\n}\n\nasync function handleDiscover(config: HandlerConfig): Promise<HandlerResponse> {\n const { schema } = await getIntrospection(config)\n return { status: 200, body: { ...buildSdkMeta(config), schema } }\n}\n\nasync function handleUp(\n config: HandlerConfig,\n body: Record<string, unknown>,\n): Promise<HandlerResponse> {\n const create = body.create as Record<string, Record<string, unknown>[]> | undefined\n if (!create) throw Errors.invalidBody('missing \"create\" in request body')\n\n const testRunId = (body.testRunId as string) ?? crypto.randomUUID()\n const { schema, tableMap, columnMaps, enumTypeMaps } = await getIntrospection(config)\n const dialect = getDialect(config.dialect)\n\n const tree = resolveTree(create, schema, testRunId)\n const refs: Record<string, Record<string, unknown>[]> = {}\n const idMap = new Map<string, string>()\n\n await config.executor.transaction(async (tx) => {\n let i = 0\n while (i < tree.ops.length) {\n const op = tree.ops[i]!\n const model = op.model\n\n // Collect consecutive ops for the same model with same batch flag\n const batch: typeof tree.ops = [op]\n while (i + 1 < tree.ops.length && tree.ops[i + 1]!.model === model && tree.ops[i + 1]!.batch === op.batch) {\n i++\n batch.push(tree.ops[i]!)\n }\n\n // Replace temp IDs with real IDs in all fields\n const modelInfo = schema.models.find((m) => m.name === model)\n const resolvedFields = batch.map((b) => {\n const fields = { ...b.fields }\n delete fields.id\n for (const [key, value] of Object.entries(fields)) {\n if (typeof value === 'string' && value.startsWith('__temp_')) {\n const realId = idMap.get(value)\n if (realId) fields[key] = realId\n }\n }\n // Inject scope field if applicable\n const scopeEdge = schema.edges.find(\n (e) => e.from === model && e.localField.toLowerCase() === schema.scopeField.toLowerCase() && e.from !== e.to,\n )\n if (scopeEdge && !(scopeEdge.localField in fields)) {\n const scopeVal = detectScopeValue(refs, schema.scopeField)\n if (scopeVal) fields[scopeEdge.localField] = scopeVal\n }\n // Auto-populate required fields without DB defaults (e.g. Prisma's @updatedAt)\n if (modelInfo) {\n for (const field of modelInfo.fields) {\n if (field.isRequired && !field.hasDefault && !field.isId && !(field.name in fields)) {\n if (field.type === 'DateTime') {\n fields[field.name] = new Date()\n }\n }\n }\n }\n return fields\n })\n\n const spec: Record<string, ResolvedEntitySpec> = {\n [model]: { count: resolvedFields.length, fields: resolvedFields, batch: op.batch },\n }\n\n const context = { testRunId, refs }\n const created = await createEntities(tx, dialect, tableMap, columnMaps, spec, context, enumTypeMaps)\n const records = created[model] ?? []\n\n if (!refs[model]) refs[model] = []\n refs[model].push(...records)\n\n for (let j = 0; j < batch.length; j++) {\n const record = records[j]\n if (record && typeof record.id === 'string') {\n idMap.set(batch[j]!.tempId, record.id)\n }\n }\n\n i++\n }\n\n // Resolve deferred FK updates (circular dependency cycles)\n for (const deferred of tree.deferredUpdates) {\n const realTargetId = idMap.get(deferred.targetTempId)\n const refTempId = tree.aliases.get(deferred.refAlias)\n const realRefId = refTempId ? idMap.get(refTempId) : undefined\n\n if (!realTargetId || !realRefId) {\n throw new Error(\n `_ref \"${deferred.refAlias}\" could not be resolved. Ensure the referenced node has _alias defined in the scenario.`,\n )\n }\n\n await updateEntity(tx, dialect, tableMap, columnMaps, deferred.model, realTargetId, { [deferred.field]: realRefId }, enumTypeMaps)\n }\n })\n\n const scopeValue = detectScopeValue(refs, schema.scopeField) ?? testRunId\n\n const firstUser = findFirstUser(refs)\n const auth = await config.auth(firstUser)\n\n const refsToken = signRefs(\n { refs, testRunId: scopeValue, environment: '' },\n config.signingSecret,\n )\n\n return { status: 200, body: { ...buildSdkMeta(config), auth, refs, refsToken } }\n}\n\nasync function handleDown(\n config: HandlerConfig,\n body: Record<string, unknown>,\n): Promise<HandlerResponse> {\n const refsToken = body.refsToken as string\n if (!refsToken) throw Errors.invalidBody('missing refsToken')\n\n let payload: ReturnType<typeof verifyRefs>\n try {\n payload = verifyRefs(refsToken, config.signingSecret)\n } catch (err) {\n const message = err instanceof Error ? err.message : 'invalid token'\n throw Errors.invalidRefsToken(message)\n }\n\n const { schema, tableMap, columnMaps } = await getIntrospection(config)\n const dialect = getDialect(config.dialect)\n\n await teardown(config.executor, dialect, tableMap, columnMaps, schema, payload.testRunId, payload.refs)\n\n return { status: 200, body: { ...buildSdkMeta(config), ok: true } }\n}\n\nfunction findFirstUser(\n refs: Record<string, Record<string, unknown>[]>,\n): Record<string, unknown> | null {\n for (const [model, records] of Object.entries(refs)) {\n if (model.toLowerCase() === 'user' && records.length > 0) {\n return records[0]!\n }\n }\n return null\n}\n\nfunction detectScopeValue(\n refs: Record<string, Record<string, unknown>[]>,\n scopeField: string,\n): string | null {\n const scopeLower = scopeField.toLowerCase()\n for (const records of Object.values(refs)) {\n for (const record of records) {\n for (const [key, value] of Object.entries(record)) {\n if (key.toLowerCase() === scopeLower && typeof value === 'string') {\n return value\n }\n }\n }\n }\n return null\n}\n","import { createHash } from 'node:crypto'\n\n/**\n * Compute a stable 16-char hex fingerprint of a scenario definition.\n * Uses sha256 of the JSON-serialized spec with sorted keys.\n */\nexport function fingerprint(value: unknown): string {\n const json = JSON.stringify(value, sortReplacer)\n return createHash('sha256').update(json).digest('hex').slice(0, 16)\n}\n\n/**\n * JSON replacer that sorts object keys for deterministic serialization.\n */\nfunction sortReplacer(_key: string, value: unknown): unknown {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n return Object.keys(value as Record<string, unknown>)\n .sort()\n .reduce(\n (sorted, k) => {\n sorted[k] = (value as Record<string, unknown>)[k]\n return sorted\n },\n {} as Record<string, unknown>,\n )\n }\n return value\n}\n","import type {\n SQLExecutor,\n ScenarioDefinition,\n HandlerConfig,\n} from './types'\nimport { handleRequest } from './handler'\nimport { signBody } from './hmac'\n\nexport interface CheckResult {\n valid: boolean\n phase: 'up' | 'down' | 'ok'\n errors: CheckError[]\n timing?: { upMs: number; downMs: number }\n}\n\nexport interface CheckError {\n phase: 'up' | 'down'\n message: string\n fix?: string\n}\n\n/**\n * Dry-run a scenario against a real database.\n * Runs the full up → down cycle and returns structured errors.\n */\nexport async function checkScenario(\n executor: SQLExecutor,\n scenario: ScenarioDefinition,\n options?: {\n scopeField: string\n dialect?: HandlerConfig['dialect']\n dbSchema?: string\n tableNameMap?: Record<string, string>\n sharedSecret?: string\n signingSecret?: string\n auth?: HandlerConfig['auth']\n },\n): Promise<CheckResult> {\n const sharedSecret = options?.sharedSecret ?? 'autonoma-check-shared'\n const signingSecret = options?.signingSecret ?? 'autonoma-check-signing'\n\n const config: HandlerConfig = {\n executor,\n scopeField: options?.scopeField ?? 'organizationId',\n dialect: options?.dialect,\n dbSchema: options?.dbSchema,\n tableNameMap: options?.tableNameMap,\n sharedSecret,\n signingSecret,\n auth: options?.auth ?? (async () => ({ headers: { Authorization: 'Bearer check-token' } })),\n }\n\n // Up\n const upBody = JSON.stringify({ action: 'up', create: scenario.create })\n const upReq = {\n body: upBody,\n headers: { 'x-signature': signBody(upBody, sharedSecret) },\n }\n\n const t0 = performance.now()\n const upRes = await handleRequest(config, upReq)\n const upMs = Math.round(performance.now() - t0)\n\n if (upRes.status !== 200) {\n const errorMsg = (upRes.body as Record<string, string>).error ?? 'Unknown error'\n return {\n valid: false,\n phase: 'up',\n errors: [{ phase: 'up', message: errorMsg, fix: suggestFix(errorMsg) }],\n timing: { upMs, downMs: 0 },\n }\n }\n\n // Down\n const refsToken = (upRes.body as Record<string, string>).refsToken\n const downBody = JSON.stringify({ action: 'down', refsToken })\n const downReq = {\n body: downBody,\n headers: { 'x-signature': signBody(downBody, sharedSecret) },\n }\n\n const t1 = performance.now()\n const downRes = await handleRequest(config, downReq)\n const downMs = Math.round(performance.now() - t1)\n\n if (downRes.status !== 200) {\n const errorMsg = (downRes.body as Record<string, string>).error ?? 'Unknown error'\n return {\n valid: false,\n phase: 'down',\n errors: [{ phase: 'down', message: errorMsg }],\n timing: { upMs, downMs },\n }\n }\n\n return { valid: true, phase: 'ok', errors: [], timing: { upMs, downMs } }\n}\n\n/**\n * Check multiple scenarios sequentially.\n */\nexport async function checkAllScenarios(\n executor: SQLExecutor,\n scenarios: ScenarioDefinition[],\n options?: {\n scopeField: string\n dialect?: HandlerConfig['dialect']\n dbSchema?: string\n tableNameMap?: Record<string, string>\n sharedSecret?: string\n signingSecret?: string\n auth?: HandlerConfig['auth']\n },\n): Promise<CheckResult[]> {\n const results: CheckResult[] = []\n for (const scenario of scenarios) {\n results.push(await checkScenario(executor, scenario, options))\n }\n return results\n}\n\nfunction suggestFix(errorMsg: string): string {\n if (errorMsg.includes('Unique constraint failed') || errorMsg.includes('unique constraint')) {\n const match = errorMsg.match(/fields: \\(`(.+?)`\\)/) ?? errorMsg.match(/constraint \"(.+?)\"/)\n if (match) return `Unique constraint on (${match[1]}). Add {{testRunId}} or {{index}} to make values unique.`\n return 'Unique constraint violation. Make field values unique across instances.'\n }\n if (errorMsg.includes('Foreign key constraint') || errorMsg.includes('foreign key')) {\n return 'A referenced record does not exist. Check that parent entities are nested correctly.'\n }\n if (errorMsg.includes('null value in column') || errorMsg.includes('must not be null')) {\n return 'A required field is null. Add it to the node with a value.'\n }\n return ''\n}\n"],"mappings":"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","names":["createHmac","timingSafeEqual","reverseGet","allResults"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autonoma-ai/sdk",
3
- "version": "0.1.4",
3
+ "version": "0.1.7",
4
4
  "description": "Autonoma Environment Factory SDK — protocol layer",
5
5
  "type": "module",
6
6
  "exports": {