@rebasepro/server-postgres 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/BranchService-ByLfM_Tt.js +360 -0
  2. package/dist/BranchService-ByLfM_Tt.js.map +1 -0
  3. package/dist/__vite-browser-external-BnuHet1e.js +46 -0
  4. package/dist/__vite-browser-external-BnuHet1e.js.map +1 -0
  5. package/dist/arg-Dni7MzLB.js +87 -0
  6. package/dist/arg-Dni7MzLB.js.map +1 -0
  7. package/dist/auth-users-columns-D2LBFrMH.js +116 -0
  8. package/dist/auth-users-columns-D2LBFrMH.js.map +1 -0
  9. package/dist/backup-cli-oM9WQVlV.js +408 -0
  10. package/dist/backup-cli-oM9WQVlV.js.map +1 -0
  11. package/dist/backup-service-Br3tqwsy.js +715 -0
  12. package/dist/backup-service-Br3tqwsy.js.map +1 -0
  13. package/dist/cli-errors-DxN4yzdH.js +657 -0
  14. package/dist/cli-errors-DxN4yzdH.js.map +1 -0
  15. package/dist/cli-output-CNdMql-L.js +47 -0
  16. package/dist/cli-output-CNdMql-L.js.map +1 -0
  17. package/dist/cli.js +2020 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/{collection-index-C7LopMyX.js → collection-index-BHgT_TKd.js} +32 -3
  20. package/dist/{collection-index-C7LopMyX.js.map → collection-index-BHgT_TKd.js.map} +1 -1
  21. package/dist/{collections-schema-version-BMeu3cgv.js → collections-schema-version-T6cGvrDi.js} +1 -2
  22. package/dist/{collections-schema-version-BMeu3cgv.js.map → collections-schema-version-T6cGvrDi.js.map} +1 -1
  23. package/dist/databasePoolManager-Bj5FbeAs.js +349 -0
  24. package/dist/databasePoolManager-Bj5FbeAs.js.map +1 -0
  25. package/dist/doctor-D7HWmGzs.js +974 -0
  26. package/dist/doctor-D7HWmGzs.js.map +1 -0
  27. package/dist/{ensure-collection-policies-CagOzEPS.js → ensure-collection-policies-2c2NV8zX.js} +5 -25
  28. package/dist/ensure-collection-policies-2c2NV8zX.js.map +1 -0
  29. package/dist/ensure-collection-tables-D4wJzM4y.js +820 -0
  30. package/dist/ensure-collection-tables-D4wJzM4y.js.map +1 -0
  31. package/dist/ensure-tables-CIojK-Rx.js +650 -0
  32. package/dist/ensure-tables-CIojK-Rx.js.map +1 -0
  33. package/dist/generate-drizzle-schema-CwEgVyjO.js +123 -0
  34. package/dist/generate-drizzle-schema-CwEgVyjO.js.map +1 -0
  35. package/dist/generate-drizzle-schema-logic-so2Z_lyC.js +528 -0
  36. package/dist/generate-drizzle-schema-logic-so2Z_lyC.js.map +1 -0
  37. package/dist/generate-postgres-ddl-logic-CtnpIBVv.js +1312 -0
  38. package/dist/generate-postgres-ddl-logic-CtnpIBVv.js.map +1 -0
  39. package/dist/generated-schema-staleness-DQdfJl2A.js +157 -0
  40. package/dist/generated-schema-staleness-DQdfJl2A.js.map +1 -0
  41. package/dist/index.es.js +849 -10807
  42. package/dist/index.es.js.map +1 -1
  43. package/dist/introspect-db-logic-C6LQdTxj.js +1378 -0
  44. package/dist/introspect-db-logic-C6LQdTxj.js.map +1 -0
  45. package/dist/policy-drift-kNJ6X2Uj.js +313 -0
  46. package/dist/policy-drift-kNJ6X2Uj.js.map +1 -0
  47. package/dist/rls-bootstrap-sql-DLDnUjtx.js +7092 -0
  48. package/dist/rls-bootstrap-sql-DLDnUjtx.js.map +1 -0
  49. package/dist/{rls-enforcement-ClJoTboT.js → rls-enforcement-DeYEjYLt.js} +14 -3
  50. package/dist/{rls-enforcement-ClJoTboT.js.map → rls-enforcement-DeYEjYLt.js.map} +1 -1
  51. package/dist/schema/bin/generate-drizzle-schema.d.ts +1 -0
  52. package/dist/schema/bin/generate-postgres-ddl.d.ts +1 -0
  53. package/dist/schema/doctor-cli.js +129 -0
  54. package/dist/schema/doctor-cli.js.map +1 -0
  55. package/dist/schema/generate-drizzle-schema.d.ts +1 -1
  56. package/dist/schema/generate-drizzle-schema.js +24 -0
  57. package/dist/schema/generate-drizzle-schema.js.map +1 -0
  58. package/dist/schema/generate-postgres-ddl.d.ts +1 -1
  59. package/dist/schema/generate-postgres-ddl.js +138 -0
  60. package/dist/schema/generate-postgres-ddl.js.map +1 -0
  61. package/dist/schema/introspect-db.js +866 -0
  62. package/dist/schema/introspect-db.js.map +1 -0
  63. package/dist/source-Br7L7GOI.js +410 -0
  64. package/dist/source-Br7L7GOI.js.map +1 -0
  65. package/dist/vector-index-DkWxm2de.js +309 -0
  66. package/dist/vector-index-DkWxm2de.js.map +1 -0
  67. package/package.json +7 -7
  68. package/dist/ensure-collection-policies-CagOzEPS.js.map +0 -1
  69. package/dist/ensure-collection-tables-DbAhrjnG.js +0 -2732
  70. package/dist/ensure-collection-tables-DbAhrjnG.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-drizzle-schema-logic-so2Z_lyC.js","names":[],"sources":["../src/schema/generate-drizzle-schema-logic.ts"],"sourcesContent":["import { CollectionConfig, NumberProperty, Property, ResolvedRelation, RelationProperty, SecurityOperation, SecurityRule, StringProperty, isPostgresCollectionConfig, DateProperty, ArrayProperty, MapProperty, ReferenceProperty, VectorProperty, BinaryProperty, isManyToMany, type ResolvedManyToMany, type ResolvedBelongsTo, type ResolvedForeignKeyOnTarget, hasForeignKeyOnTarget } from \"@rebasepro/types\";\nimport { getPrimaryKeys } from \"../services/collection-helpers\";\nimport { buildSearchColumnSpec } from \"./search-column\";\nimport { defaultBelongsToOnDelete } from \"./generate-postgres-ddl-logic\";\nimport { getEnumVarName, getTableName, getTableVarName, resolveCollectionRelations, findRelation, fieldKeyForColumn, securityRuleToConditions, policyToPostgres, getEffectiveSecurityRules, resolveJunctionSpecs, getJunctionSecurityRules, getJunctionCollectionConfig, resolveStringColumnLength, relationalCollections, sortCollectionsBySlug } from \"@rebasepro/common\";\nimport { toSnakeCase, getPolicyNamesForRule } from \"@rebasepro/utils\";\nimport { logger } from \"@rebasepro/server\";\n// --- Helper Functions ---\n\n/**\n * Resolve the SQL column name for a property.\n * Uses the explicit `columnName` when set (e.g. from introspection),\n * falling back to `toSnakeCase(propName)` for manually-authored collections.\n */\nconst JS_IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/**\n * A string literal for the generated schema file.\n *\n * Column names, table names and enum values are all written into this file as\n * literals, and none of them is constrained to be quote-free: a Postgres\n * identifier only has to be quoted, and `O'Brien` is an ordinary enum value.\n * Interpolating them raw ended the literal early — for enum values, inside\n * single quotes, where an apostrophe is not an edge case.\n */\nconst quote = (value: string): string => JSON.stringify(value);\n\n/** An object key: verbatim when it is an identifier, quoted otherwise. */\nconst propKey = (name: string): string => (JS_IDENTIFIER.test(name) ? name : quote(name));\n\n/**\n * A property access on a generated table variable.\n *\n * `users.full name` is not an expression; `users[\"full name\"]` is, and Drizzle\n * treats the two identically.\n */\nconst member = (object: string, key: string): string =>\n (JS_IDENTIFIER.test(key) ? `${object}.${key}` : `${object}[${quote(key)}]`);\n\nconst resolveColumnName = (propName: string, prop?: Property | null): string => {\n if (prop && \"columnName\" in prop && typeof prop.columnName === \"string\") {\n return prop.columnName;\n }\n return toSnakeCase(propName);\n};\n\nconst getPrimaryKeyProp = (collection: CollectionConfig): { name: string, type: \"string\" | \"number\", isUuid: boolean } => {\n if (collection.properties) {\n const idPropEntry = Object.entries(collection.properties).find(([_, prop]) => \"isId\" in (prop as unknown as object) && Boolean((prop as unknown as Record<string, unknown>).isId));\n if (idPropEntry) {\n const prop = idPropEntry[1] as unknown as Property;\n const isUuid = prop.type === \"string\" && \"isId\" in prop && (prop as unknown as StringProperty).isId === \"uuid\";\n return { name: idPropEntry[0],\ntype: prop.type === \"number\" ? \"number\" : \"string\",\nisUuid };\n }\n }\n // Fallback\n const idProp = collection.properties?.[\"id\"] as unknown as Property | undefined;\n if (idProp?.type === \"number\") {\n return { name: \"id\",\ntype: \"number\",\nisUuid: false };\n }\n const isUuid = idProp?.type === \"string\" && \"isId\" in idProp && (idProp as unknown as StringProperty).isId === \"uuid\";\n return { name: \"id\",\ntype: \"string\",\nisUuid: isUuid ?? false };\n};\n\n/**\n * Given a raw DB column name (e.g. \"client_id\"), the Drizzle property key that\n * maps to it.\n *\n * One line, because the rule is shared: the Drizzle object key is the wire\n * name, and {@link fieldKeyForColumn} is the one definition of what a column is\n * named on the wire. This used to be a private copy that fell back to the\n * column verbatim, which is how a derived foreign key ended up served as\n * `author_id` beside a hand-authored `displayName`.\n */\nconst resolvePropertyKeyForColumn = (collection: CollectionConfig, column: string): string =>\n fieldKeyForColumn(collection, column);\n\nconst isNumericId = (collection: CollectionConfig): boolean => {\n return getPrimaryKeyProp(collection).type === \"number\";\n};\n\nconst getPrimaryKeyName = (collection: CollectionConfig): string => {\n return getPrimaryKeyProp(collection).name;\n};\n\nconst isIdProperty = (propName: string, prop: Property, collection: CollectionConfig): boolean => {\n if (\"isId\" in prop && Boolean(prop.isId)) return true;\n\n // We only fallback to \"id\" if NO property is explicitly marked with `isId: true` or a generator string\n const hasExplicitId = Object.values(collection.properties ?? {}).some(p => \"isId\" in (p as unknown as object) && Boolean((p as unknown as Record<string, unknown>).isId));\n return !hasExplicitId && propName === \"id\";\n};\n\n/**\n * The Drizzle column declaration a property compiles to, or `null` when the\n * property puts no column on *this* table (an inverse relation, whose column\n * lives on the target). Exported so it can be checked against its DDL twin\n * `getSqlColumnType` directly — the two disagreeing is what left `geopoint`\n * with a database column and no Drizzle key.\n */\nexport const getDrizzleColumn = (propName: string, prop: Property, collection: CollectionConfig, collections: CollectionConfig[]): string | null => {\n\n const colName = resolveColumnName(propName, prop);\n let columnDefinition: string;\n\n switch (prop.type) {\n case \"string\": {\n const stringProp = prop as unknown as StringProperty;\n if (stringProp.enum) {\n const enumName = getEnumVarName(getTableName(collection), propName);\n columnDefinition = `${enumName}(${quote(colName)})`;\n } else if (\"isId\" in stringProp && stringProp.isId === \"uuid\") {\n columnDefinition = `uuid(${quote(colName)})`;\n } else if (stringProp.columnType === \"uuid\") {\n columnDefinition = `uuid(${quote(colName)})`;\n } else if (stringProp.columnType === \"char\") {\n columnDefinition = `char(${quote(colName)}, { length: ${resolveStringColumnLength(stringProp)} })`;\n } else if (stringProp.columnType === \"varchar\") {\n // The length is not optional decoration: `varchar(\"col\")` with\n // no length is an UNBOUNDED varchar in Postgres, which is what\n // this emitted while the DDL generator emitted VARCHAR(255) for\n // the very same property.\n columnDefinition = `varchar(${quote(colName)}, { length: ${resolveStringColumnLength(stringProp)} })`;\n } else {\n // `text` is the default, and the only length-unbounded choice.\n // Ask for `varchar` explicitly if you want the length constraint.\n columnDefinition = `text(${quote(colName)})`;\n }\n if (isIdProperty(propName, prop, collection)) {\n columnDefinition += \".primaryKey()\";\n }\n if (\"isId\" in stringProp && stringProp.isId !== \"manual\" && stringProp.isId !== true) {\n if (stringProp.isId === \"uuid\") {\n columnDefinition += \".defaultRandom()\";\n } else if (stringProp.isId === \"cuid\") {\n columnDefinition += \".default(sql`cuid()`)\";\n } else if (typeof stringProp.isId === \"string\") {\n const sqlContent = stringProp.isId.startsWith(\"sql`\") && stringProp.isId.endsWith(\"`\")\n ? stringProp.isId.substring(4, stringProp.isId.length - 1)\n : stringProp.isId;\n columnDefinition += `.default(sql\\`${sqlContent}\\`)`;\n }\n }\n if (stringProp.validation?.unique) {\n columnDefinition += \".unique()\";\n }\n break;\n }\n case \"number\": {\n const numProp = prop as unknown as NumberProperty;\n const isId = isIdProperty(propName, prop, collection);\n\n let baseType = (numProp.validation?.integer || isId) ? `integer(${quote(colName)})` : `numeric(${quote(colName)})`;\n if (numProp.columnType) {\n if (numProp.columnType === \"double precision\") baseType = `doublePrecision(${quote(colName)})`;\n // `bigint` and `bigserial` are the only pg-core builders that\n // *require* a config argument: without `mode`, drizzle cannot\n // know whether to hand back a `number` or a `bigint`, and the\n // emitted call does not typecheck.\n //\n // This is why `schema.generated.ts` drifted. Regenerating it\n // produced a file that would not compile, so the bigint lines\n // were hand-patched — and every regeneration after that looked\n // like a large, alarming diff nobody wanted to ship. The file\n // then sat stale for long enough that a security fix to two RLS\n // policies never reached production.\n //\n // `number` rather than `bigint`: these are counters and byte\n // totals that every caller already treats as numbers, and\n // switching the runtime type would be a breaking change to\n // every consumer of the generated schema.\n else if (numProp.columnType === \"bigint\" || numProp.columnType === \"bigserial\") {\n baseType = `${numProp.columnType}(${quote(colName)}, { mode: \"number\" })`;\n }\n else baseType = `${numProp.columnType}(${quote(colName)})`;\n }\n\n if (\"isId\" in numProp && numProp.isId === \"increment\") {\n columnDefinition = `${baseType}.generatedByDefaultAsIdentity()`;\n } else if (\"isId\" in numProp && typeof numProp.isId === \"string\" && numProp.isId !== \"manual\") {\n columnDefinition = baseType;\n const sqlContent = numProp.isId.startsWith(\"sql`\") && numProp.isId.endsWith(\"`\")\n ? numProp.isId.substring(4, numProp.isId.length - 1)\n : numProp.isId;\n columnDefinition += `.default(sql\\`${sqlContent}\\`)`;\n } else {\n columnDefinition = baseType;\n }\n\n if (isId) {\n columnDefinition += \".primaryKey()\";\n }\n if (numProp.validation?.unique) {\n columnDefinition += \".unique()\";\n }\n break;\n }\n case \"boolean\":\n columnDefinition = `boolean(${quote(colName)})`;\n break;\n case \"date\": {\n const dateProp = prop as DateProperty;\n if (dateProp.columnType === \"date\") {\n columnDefinition = `date(${quote(colName)}, { mode: 'string' })`;\n } else if (dateProp.columnType === \"time\") {\n columnDefinition = `time(${quote(colName)})`;\n } else {\n columnDefinition = `timestamp(${quote(colName)}, { withTimezone: true, mode: 'string' })`;\n }\n // autoValue: database-level default for initial value on INSERT\n if (dateProp.autoValue === \"on_create\" || dateProp.autoValue === \"on_update\") {\n columnDefinition += \".default(sql`now()`)\";\n }\n break;\n }\n case \"map\": {\n const mapProp = prop as MapProperty;\n if (mapProp.columnType === \"json\") {\n columnDefinition = `json(${quote(colName)})`;\n } else {\n columnDefinition = `jsonb(${quote(colName)})`;\n }\n break;\n }\n case \"geopoint\": {\n // `{ latitude, longitude }`, which is what the OpenAPI schema, the\n // generated TS type and the admin's field binding all describe.\n // This arm did not exist: `geopoint` fell to `default: return null`\n // and the caller dropped the column, so the DDL generator created a\n // column the Drizzle table had no key for — and every write to it\n // was silently discarded with a 201.\n columnDefinition = `jsonb(${quote(colName)})`;\n break;\n }\n case \"array\": {\n const arrayProp = prop as ArrayProperty;\n let colType = arrayProp.columnType;\n if (!colType && arrayProp.of && !Array.isArray(arrayProp.of)) {\n const ofProp = arrayProp.of as Property;\n if (ofProp.type === \"string\") {\n colType = \"text[]\";\n } else if (ofProp.type === \"number\") {\n colType = ofProp.validation?.integer ? \"integer[]\" : \"numeric[]\";\n } else if (ofProp.type === \"boolean\") {\n colType = \"boolean[]\";\n }\n }\n\n if (colType === \"json\") {\n columnDefinition = `json(${quote(colName)})`;\n } else if (colType === \"text[]\") {\n columnDefinition = `text(${quote(colName)}).array()`;\n } else if (colType === \"integer[]\") {\n columnDefinition = `integer(${quote(colName)}).array()`;\n } else if (colType === \"boolean[]\") {\n columnDefinition = `boolean(${quote(colName)}).array()`;\n } else if (colType === \"numeric[]\") {\n columnDefinition = `numeric(${quote(colName)}).array()`;\n } else {\n columnDefinition = `jsonb(${quote(colName)})`;\n }\n break;\n }\n case \"vector\": {\n const vp = prop as VectorProperty;\n columnDefinition = `vector(${quote(colName)}, { dimensions: ${vp.dimensions} })`;\n break;\n }\n case \"binary\": {\n columnDefinition = `customType({ dataType() { return 'bytea'; } })(${quote(colName)})`;\n break;\n }\n case \"relation\": {\n const refProp = prop as RelationProperty;\n const resolvedRelations = resolveCollectionRelations(collection);\n const relation = findRelation(resolvedRelations, refProp.relation?.relationName ?? propName);\n\n // Only `belongsTo` puts a column on this table; every other kind\n // is a column on the target, a junction row, or a join chain.\n if (!relation || relation.kind !== \"belongsTo\") {\n return null;\n }\n\n // If a property of its own already declares this foreign key, that\n // property emits the column and this relation must not emit a second\n // key for it. Asked of the *field key*, not the column: a property\n // declared `authorId` with `columnName: \"author_id\"` did not answer\n // to `properties[\"author_id\"]`, so both sides emitted and the table\n // carried two Drizzle keys pointing at one column.\n const fkFieldKey = fieldKeyForColumn(collection, relation.localKey);\n if (collection.properties[fkFieldKey] && propName !== fkFieldKey) {\n return null;\n }\n\n let targetCollection: CollectionConfig;\n try {\n targetCollection = relation.target();\n } catch {\n return null; // Cannot resolve target\n }\n\n const fkColumnName = relation.localKey;\n const targetTableVar = getTableVarName(getTableName(targetCollection));\n const pkProp = getPrimaryKeyProp(targetCollection);\n const targetIdField = pkProp.name;\n // `quote`, like every other column literal in this file: a column\n // name only has to be quotable in Postgres, and this one is derived\n // from a relation the author wrote.\n const baseColumn = pkProp.type === \"number\"\n ? `integer(${quote(fkColumnName)})`\n : (pkProp.isUuid ? `uuid(${quote(fkColumnName)})` : `text(${quote(fkColumnName)})`);\n\n const onUpdate = relation.onUpdate ? `onUpdate: \"${relation.onUpdate}\"` : \"\";\n const required = prop.validation?.required;\n // Same default as the DDL generator, lowercased for Drizzle's\n // option literal. The two files describe the same constraint; a\n // default that differs between them makes `db push` plan a rewrite\n // of every required foreign key on every run.\n const onDeleteVal = relation.onDelete ?? defaultBelongsToOnDelete(required).toLowerCase();\n const onDelete = `onDelete: \\\"${onDeleteVal}\\\"`;\n\n const refOptionsParts = [onUpdate, onDelete].filter(Boolean);\n const refOptions = refOptionsParts.length > 0 ? `{ ${refOptionsParts.join(\", \")} }` : \"\";\n\n let columnDef = `${baseColumn}.references(() => ${member(targetTableVar, targetIdField)}${refOptions ? `, ${refOptions}` : \"\"})`;\n\n if (required) {\n columnDef += \".notNull()\";\n }\n\n // Key by the wire name, column by `localKey`. They are two different\n // names for one thing and the generated line is where they meet:\n // `authorId: integer(\"author_id\")`.\n return ` ${propKey(fkFieldKey)}: ${columnDef}`;\n }\n case \"reference\": {\n const refProp = prop as ReferenceProperty;\n const targetCollection = collections.find(c => c.slug === refProp.path || getTableName(c) === refProp.path);\n if (!targetCollection) {\n columnDefinition = `text(${quote(colName)})`;\n break;\n }\n\n const pkProp = getPrimaryKeyProp(targetCollection);\n const targetTableVar = getTableVarName(getTableName(targetCollection));\n const targetIdField = pkProp.name;\n const baseColumn = pkProp.type === \"number\" ? `integer(${quote(colName)})` : (pkProp.isUuid ? `uuid(${quote(colName)})` : `text(${quote(colName)})`);\n\n const required = prop.validation?.required;\n const onDelete = required ? \"cascade\" : \"set null\";\n const refOptions = `{ onDelete: \"${onDelete}\" }`;\n\n columnDefinition = `${baseColumn}.references(() => ${member(targetTableVar, targetIdField)}, ${refOptions})`;\n if (required) {\n columnDefinition += \".notNull()\";\n }\n // Skip the standard notNull() handling below because we did it here with references\n return ` ${propKey(propName)}: ${columnDefinition}`;\n }\n default:\n // Not `return null`. A `null` here means \"this property puts no\n // column on this table\", which is true of an inverse relation and\n // false of everything else — and the caller cannot tell the two\n // apart, so a type this switch simply forgot produced a table\n // missing a column while the DDL generator happily created one.\n // That is how `geopoint` stayed unpersistable: writes to it were\n // dropped before the SQL was built, forever, with a 201. A property\n // type nobody mapped is a generator bug, and it says so here rather\n // than at some caller's next INSERT.\n throw new Error(\n `No Postgres column mapping for property '${propName}' of type ` +\n `'${(prop as Property).type}' in collection '${collection.slug}'. ` +\n \"Add a case to `getDrizzleColumn` (and to `getSqlColumnType`, which must agree).\"\n );\n }\n\n if (prop.validation?.required) {\n columnDefinition += \".notNull()\";\n }\n\n return ` ${propKey(propName)}: ${columnDefinition}`;\n};\n\n/**\n * Wraps a compiled SQL clause in a Drizzle `sql\\`...\\`` template literal.\n *\n * The clause is SQL being written into a TypeScript file, so it has to survive\n * being read back as a template literal. Three characters do not:\n *\n * - `` ` `` closes the template early, and the rest of the clause becomes code.\n * - `${` opens an interpolation — the file stops compiling, or worse, compiles\n * against whatever identifier happens to be in scope.\n * - `\\` is an escape, and Drizzle's `sql` tag reads the *cooked* strings, not\n * `.raw`. So a policy written as `email ~ '^admin\\.user@corp\\.com$'` reaches\n * the database as `^admin.user@corp.com$`, where every `\\.` now matches any\n * character. A `USING` clause is a security boundary and that one silently\n * widened it — the SQL file emitted by the DDL generator kept the backslashes\n * while this path dropped them, so the two disagreed about who could read the\n * table.\n *\n * Escaping here rather than in the compiler: the clause is correct SQL, and it\n * is only this destination that has an opinion about backslashes.\n */\nconst wrapSql = (clause: string): string =>\n `sql\\`${clause.replace(/\\\\/g, \"\\\\\\\\\").replace(/`/g, \"\\\\`\").replace(/\\$\\{/g, \"\\\\${\")}\\``;\n\n/**\n * Generates a deterministic hash based on the rule configuration.\n */\n\n/**\n * Generates Drizzle pgPolicy() calls from a declarative SecurityRule definition.\n *\n * Supports the full spectrum:\n * - Convenience shortcuts: ownerField, access, roles\n * - Raw SQL: using, withCheck\n * - Mode: permissive (default) or restrictive\n * - operations[] array: generates one policy per operation\n * - Combinations: roles + ownerField, roles + raw SQL, etc.\n */\ntype ResolveCollection = (slug: string) => CollectionConfig | undefined;\n\nconst generatePolicyCode = (collection: CollectionConfig, rule: SecurityRule, index: number, resolveCollection: ResolveCollection): string => {\n const tableName = getTableName(collection);\n // Resolve operations: operations[] takes precedence over operation (singular)\n const ops: readonly SecurityOperation[] = rule.operations && rule.operations.length > 0\n ? rule.operations\n : [rule.operation ?? \"all\"];\n\n const policyNames = getPolicyNamesForRule(rule, tableName);\n\n // Generate one pgPolicy per operation\n return ops.map((op, opIdx) => {\n return generateSinglePolicyCode(collection, rule, op, policyNames[opIdx], resolveCollection);\n }).join(\"\");\n};\n\n/**\n * Generates a single pgPolicy() call for one specific operation.\n */\nconst generateSinglePolicyCode = (collection: CollectionConfig, rule: SecurityRule, operation: SecurityOperation, policyName: string, resolveCollection: ResolveCollection): string => {\n const mode = rule.mode ?? \"permissive\";\n\n // Determine which clauses this operation needs:\n // SELECT, DELETE → USING only\n // INSERT → WITH CHECK only\n // UPDATE, ALL → both USING and WITH CHECK\n const needsUsing = operation !== \"insert\";\n const needsWithCheck = operation !== \"select\" && operation !== \"delete\";\n\n // Desugar the rule (access / ownerField / roles / structured condition / raw\n // SQL) into the shared PolicyExpression model, then compile to SQL — the same\n // normalization the DDL generator and the client-side evaluator use.\n const { usingExpr, withCheckExpr } = securityRuleToConditions(rule);\n\n let usingClause = needsUsing && usingExpr ? wrapSql(policyToPostgres(usingExpr, collection, { resolveCollection })) : null;\n let withCheckClause = needsWithCheck && withCheckExpr ? wrapSql(policyToPostgres(withCheckExpr, collection, { resolveCollection })) : null;\n\n // Fallback: if we still have no clauses, deny all (safety net)\n if (!usingClause && needsUsing) {\n usingClause = \"sql`false`\";\n }\n if (!withCheckClause && needsWithCheck) {\n withCheckClause = \"sql`false`\";\n }\n\n // Build the policy options object\n const parts: string[] = [];\n parts.push(`as: \"${mode}\"`);\n parts.push(`for: \"${operation}\"`);\n const toRoles = rule.pgRoles ? [...rule.pgRoles].sort() : [\"public\"];\n parts.push(`to: [${toRoles.map(r => `\"${r}\"`).join(\", \")}]`);\n if (usingClause) parts.push(`using: ${usingClause}`);\n if (withCheckClause) parts.push(`withCheck: ${withCheckClause}`);\n\n return ` pgPolicy(${quote(policyName)}, { ${parts.join(\", \")} }),\\n`;\n};\n\n/**\n * Computes a deterministic shared relation name for Drizzle.\n *\n * Drizzle requires both sides of a relation (owning + inverse) to use the\n * exact same `relationName` string so it can pair them. Each collection\n * definition may use a different local `relationName`, so we need a canonical\n * form that both sides can independently compute.\n *\n * Strategy: `{owningTable}_{foreignKey}`\n * - owning side → `{thisTable}_{localKey}` e.g. \"jobs_company_id\"\n * - inverse side → `{targetTable}_{foreignKeyOnTarget}` e.g. \"jobs_company_id\"\n *\n * For M2M with junction tables the owning relation name is already shared via\n * the junction table wiring, so we keep it as-is.\n *\n * Falls back to the local relation name when the counterpart can't be resolved.\n */\nconst computeSharedRelationName = (\n rel: ResolvedRelation,\n sourceCollection: CollectionConfig,\n _collections: CollectionConfig[]\n): string => {\n const fallback = rel.relationName ?? toSnakeCase(rel.target().slug);\n\n // Both sides of a link must derive the same name, so each resolves the\n // column to its Drizzle property key and builds the name from the table\n // that actually owns it.\n if (rel.kind === \"belongsTo\") {\n const normalisedKey = resolvePropertyKeyForColumn(sourceCollection, rel.localKey);\n return `${getTableName(sourceCollection)}_${normalisedKey}`;\n }\n\n if (rel.kind === \"hasMany\" || rel.kind === \"hasOne\") {\n // The owning table is the *target*; the column is foreignKeyOnTarget.\n try {\n const targetCollection = rel.target();\n const normalisedFK = resolvePropertyKeyForColumn(targetCollection, rel.foreignKeyOnTarget);\n return `${getTableName(targetCollection)}_${normalisedFK}`;\n } catch {\n return fallback;\n }\n }\n\n // manyToMany is named through its junction wiring; `via` is not emitted as\n // a Drizzle relation at all. Both keep the local name.\n return fallback;\n};\n\n// --- Main Schema Generation Logic ---\nexport const generateSchema = async (allCollections: CollectionConfig[], stripPolicies = false): Promise<string> => {\n // A Firestore or MongoDB collection has no table to generate, and generating\n // one for it is not merely wasted output: `db push` would create it, and\n // `rebase doctor` would then report the store the collection actually reads\n // from as drift. Non-SQL collections leave the toolchain here, once, rather\n // than being filtered again in each stage below.\n //\n // Sorted here rather than in the writer: the output is order-dependent and\n // `rebase doctor` regenerates it in memory to diff against the file on\n // disk. With the sort in the writer only, a project whose file order\n // differed from its slug order was reported stale forever.\n const collections = sortCollectionsBySlug(relationalCollections(allCollections));\n let schemaContent = \"// This file is auto-generated by the Rebase Drizzle generator. Do not edit manually.\\n\\n\";\n\n\n const hasUuid = collections.some(c =>\n c.properties && Object.values(c.properties).some(\n (p: Property) => p.type === \"string\" && ((p as unknown as Record<string, unknown>).autoValue === \"uuid\" || (p as unknown as Record<string, unknown>).isId === \"uuid\")\n )\n );\n\n const hasVector = collections.some(c =>\n c.properties && Object.values(c.properties).some(\n (p: Property) => p.type === \"vector\"\n )\n );\n\n const hasBinary = collections.some(c =>\n c.properties && Object.values(c.properties).some(\n (p: Property) => p.type === \"binary\"\n )\n );\n\n // drizzle ships no `tsvector` builder, so an opted-in search column reaches\n // the schema the same way `bytea` does — through `customType`.\n const hasSearch = collections.some(c => buildSearchColumnSpec(c) !== undefined);\n\n // Always import pgPolicy and sql — RLS is enabled on every table (secure by default)\n const pgCoreImports = [\"primaryKey\", \"pgTable\", \"integer\", \"varchar\", \"text\", \"char\", \"boolean\", \"timestamp\", \"date\", \"time\", \"jsonb\", \"json\", \"pgEnum\", \"numeric\", \"real\", \"doublePrecision\", \"bigint\", \"serial\", \"bigserial\", \"pgPolicy\"];\n if (hasUuid) pgCoreImports.push(\"uuid\");\n if (hasVector) pgCoreImports.push(\"vector\");\n if (hasBinary || hasSearch) pgCoreImports.push(\"customType\");\n\n const uniqueSchemas = Array.from(new Set(\n collections.map(c => isPostgresCollectionConfig(c) ? c.schema : undefined).filter(Boolean)\n ));\n if (uniqueSchemas.length > 0) {\n pgCoreImports.push(\"pgSchema\");\n }\n\n schemaContent += `import { ${pgCoreImports.join(\", \")} } from 'drizzle-orm/pg-core';\\n`;\n schemaContent += \"import { relations as drizzleRelations, sql } from 'drizzle-orm';\\n\\n\";\n\n uniqueSchemas.forEach(schema => {\n schemaContent += `export const ${schema}Schema = pgSchema(\"${schema}\");\\n`;\n });\n if (uniqueSchemas.length > 0) {\n schemaContent += \"\\n\";\n }\n\n const exportedTableVars: string[] = [];\n const exportedEnumVars: string[] = [];\n const exportedRelationVars: string[] = [];\n\n const allTablesToGenerate = new Map<string, {\n collection: CollectionConfig,\n isJunction?: boolean,\n relation?: ResolvedRelation,\n sourceCollection?: CollectionConfig\n }>();\n\n // 1. Generate Enums\n collections.forEach(collection => {\n const collectionPath = getTableName(collection);\n Object.entries(collection.properties ?? {}).forEach(([propName, prop]) => {\n\n if ((\"enum\" in prop) && (prop.type === \"string\" || prop.type === \"number\") && prop.enum) {\n const enumVarName = getEnumVarName(collectionPath, propName);\n const enumDbName = `${collectionPath}_${resolveColumnName(propName, prop)}`;\n const values = Array.isArray(prop.enum)\n ? (prop.enum as (string | number | { id: string | number })[]).map((v: string | number | { id: string | number }) =>\n String(typeof v === \"object\" && v !== null && \"id\" in v ? v.id : v)\n )\n : Object.keys(prop.enum);\n if (values.length > 0) {\n schemaContent += `export const ${enumVarName} = pgEnum(${quote(enumDbName)}, [${values.map(v => quote(v)).join(\", \")}]);\\n`;\n if (!exportedEnumVars.includes(enumVarName)) exportedEnumVars.push(enumVarName);\n }\n }\n });\n });\n schemaContent += \"\\n\";\n\n // Junction policy derivation needs every declaring side of each junction,\n // not just the first relation that reached it in the walk below.\n const junctionSpecs = resolveJunctionSpecs(collections);\n\n // 2. Identify all tables (collections and junction tables only)\n for (const collection of collections) {\n const tableName = getTableName(collection);\n if (tableName) {\n allTablesToGenerate.set(tableName, { collection });\n }\n\n const resolvedRelations = resolveCollectionRelations(collection);\n for (const relation of Object.values(resolvedRelations)) {\n if (isManyToMany(relation)) { // Standard M2M junction table\n const junctionTableName = relation.through.table;\n if (!allTablesToGenerate.has(junctionTableName)) {\n allTablesToGenerate.set(junctionTableName, {\n collection: {\n table: junctionTableName,\n properties: {}\n } as CollectionConfig,\n isJunction: true,\n relation: relation,\n sourceCollection: collection\n });\n }\n }\n // joinPath relations use existing user-controlled tables - no generation needed\n }\n }\n\n // 3. Generate pgTable definitions for all unique tables\n for (const [tableName, {\n collection,\n isJunction,\n relation,\n sourceCollection\n }] of allTablesToGenerate.entries()) {\n const tableVarName = getTableVarName(tableName);\n if (isJunction && relation && sourceCollection && isManyToMany(relation)) {\n const targetCollection = relation.target();\n // Junctions live in `public`, full stop — `resolveJunctionSpecs`\n // hardcodes that, so it is where `planJunctionTables` CREATEs them\n // and where the derived RLS policies are applied. Inheriting the\n // endpoint's schema here (as this used to) put the junction of any\n // m2m onto `users` in `rebase`, while its policies were still\n // created against `public.<junction>` — RLS enabled on one table,\n // rows written to another. The three generators have to agree, and\n // the other two already did.\n const tableCreator = \"pgTable\";\n const baseTableName = tableName.includes(\".\") ? tableName.split(\".\").pop()! : tableName;\n const {\n sourceColumn,\n targetColumn\n } = relation.through;\n\n const onDelete = relation.onDelete ?? \"cascade\";\n const refOptions = `{ onDelete: \\\"${onDelete}\\\" }`;\n\n // `text`, matching the string default: a junction column must have the\n // same type as the primary key it references.\n const sourceColType = isNumericId(sourceCollection) ? \"integer\" : (getPrimaryKeyProp(sourceCollection).isUuid ? \"uuid\" : \"text\");\n const targetColType = isNumericId(targetCollection) ? \"integer\" : (getPrimaryKeyProp(targetCollection).isUuid ? \"uuid\" : \"text\");\n const sourceId = getPrimaryKeyName(sourceCollection);\n const targetId = getPrimaryKeyName(targetCollection);\n\n schemaContent += `export const ${tableVarName} = ${tableCreator}(\\\"${baseTableName}\\\", {\\n`;\n // The junction block was the one place these three helpers were not\n // applied, so a junction column containing a space or a hyphen —\n // both legal in Postgres — produced a file that does not parse.\n schemaContent += ` ${propKey(sourceColumn)}: ${sourceColType}(${quote(sourceColumn)}).notNull().references(() => ${member(getTableVarName(getTableName(sourceCollection)), sourceId)}, ${refOptions}),\\n`;\n schemaContent += ` ${propKey(targetColumn)}: ${targetColType}(${quote(targetColumn)}).notNull().references(() => ${member(getTableVarName(getTableName(targetCollection)), targetId)}, ${refOptions}),\\n`;\n schemaContent += \"}, (table) => ([\\n\";\n schemaContent += ` primaryKey({ columns: [${member(\"table\", sourceColumn)}, ${member(\"table\", targetColumn)}] }),\\n`;\n\n // Junctions are generated tables like any other: locked by default,\n // with derived policies (reads follow the endpoints, writes follow\n // the declaring side's update rules). RLS is enabled regardless of\n // policy stripping — a bare junction must default-deny, not fail open.\n const junctionSpec = junctionSpecs.get(baseTableName);\n if (!stripPolicies && junctionSpec) {\n const junctionCollection = getJunctionCollectionConfig(junctionSpec);\n const resolveCollection: ResolveCollection = (slug) => collections.find(c => c.slug === slug || getTableName(c) === slug);\n getJunctionSecurityRules(junctionSpec).forEach((rule: SecurityRule, idx: number) => {\n schemaContent += generatePolicyCode(junctionCollection, rule, idx, resolveCollection);\n });\n }\n schemaContent += \"])).enableRLS();\\n\\n\";\n } else if (!isJunction) {\n const schema = isPostgresCollectionConfig(collection) ? collection.schema : undefined;\n const tableCreator = schema ? `${schema}Schema.table` : \"pgTable\";\n const baseTableName = tableName.includes(\".\") ? tableName.split(\".\").pop()! : tableName;\n schemaContent += `export const ${tableVarName} = ${tableCreator}(\\\"${baseTableName}\\\", {\\n`;\n const columns = new Set<string>();\n Object.entries(collection.properties ?? {}).forEach(([propName, prop]) => {\n const columnString = getDrizzleColumn(propName, prop as Property, collection, collections);\n if (columnString) columns.add(columnString);\n\n });\n\n // The opt-in search column. Declared with its real generation\n // expression rather than as a bare custom type: `schema.generated.ts`\n // is what a developer running drizzle-kit themselves diffs against,\n // and a column declared without its expression reads to drizzle-kit\n // as one it should alter.\n const searchSpec = buildSearchColumnSpec(collection);\n if (searchSpec) {\n columns.add(\n ` ${propKey(searchSpec.column)}: customType({ dataType() { return 'tsvector'; } })(${quote(searchSpec.column)})` +\n `.generatedAlwaysAs(sql\\`${searchSpec.expression}\\`)`\n );\n if (searchSpec.fuzzy) {\n columns.add(\n ` ${propKey(searchSpec.fuzzy.column)}: text(${quote(searchSpec.fuzzy.column)})` +\n `.generatedAlwaysAs(sql\\`${searchSpec.fuzzy.expression}\\`)`\n );\n }\n }\n\n // A collection that declares no primary key gets an implicit one:\n // `id TEXT PRIMARY KEY`. The DDL generator emits the same column,\n // and `derivePrimaryKeys` reads it back.\n const hasIdColumn = Array.from(columns).some(col => col.includes(\".primaryKey()\"));\n if (!hasIdColumn) {\n columns.add(\" id: text(\\\"id\\\").primaryKey()\");\n }\n\n schemaContent += `${Array.from(columns).join(\",\\n\")}`;\n\n const securityRules = getEffectiveSecurityRules(collection);\n if (!stripPolicies && securityRules.length > 0) {\n schemaContent += \"\\n}, (table) => ([\\n\";\n const resolveCollection: ResolveCollection = (slug) => collections.find(c => c.slug === slug || getTableName(c) === slug);\n securityRules.forEach((rule: SecurityRule, idx: number) => {\n schemaContent += generatePolicyCode(collection, rule, idx, resolveCollection);\n });\n schemaContent += \"])).enableRLS();\\n\\n\";\n } else {\n // No explicit policies — RLS enabled with deny-all default (Postgres denies\n // everything when RLS is on and no permissive policies exist).\n schemaContent += \"\\n}).enableRLS();\\n\\n\";\n }\n }\n if (!exportedTableVars.includes(tableVarName)) exportedTableVars.push(tableVarName);\n }\n\n // 4. Generate Drizzle Relations\n for (const [tableName, {\n collection,\n isJunction\n }] of allTablesToGenerate.entries()) {\n const tableVarName = getTableVarName(tableName);\n const tableRelations: string[] = [];\n\n if (isJunction) {\n const relationInfo = Array.from(allTablesToGenerate.values()).find(v => v.isJunction && getTableName(v.collection) === tableName);\n if (relationInfo && relationInfo.relation && relationInfo.sourceCollection && isManyToMany(relationInfo.relation)) {\n const {\n relation,\n sourceCollection\n } = relationInfo;\n const targetCollection = relation.target();\n const sourceTableVar = getTableVarName(getTableName(sourceCollection));\n const targetTableVar = getTableVarName(getTableName(targetCollection));\n const sourceId = getPrimaryKeyName(sourceCollection);\n const targetId = getPrimaryKeyName(targetCollection);\n\n if (!relation?.through)\n throw new Error(\"Internal, the relation should have a through property. Relations passed to this script should sanitized first with sanitizeRelation().\");\n\n // The owning relation's name — used on the source side of the junction\n const owningRelationName = relation.relationName ?? toSnakeCase(getTableName(targetCollection));\n\n // Find the inverse relation name on the target collection (if any)\n // This is needed so the junction's target-side one() can pair with the\n // inverse many() on the target table.\n let inverseRelationName: string | null = null;\n try {\n const targetRelations = resolveCollectionRelations(targetCollection);\n for (const [, targetRel] of Object.entries(targetRelations)) {\n if (targetRel.kind !== \"belongsTo\" &&\n targetRel.cardinality === \"many\" &&\n targetRel.relationName === owningRelationName) {\n inverseRelationName = targetRel.relationName ?? null;\n break;\n }\n }\n } catch {\n // ignore — inverse side may not exist\n }\n\n // Source side one(): pairs with owning table's many(junctionTable, { relationName })\n tableRelations.push(` ${quote(relation.through.sourceColumn)}: one(${sourceTableVar}, {\\n fields: [${member(tableVarName, relation.through.sourceColumn)}],\\n references: [${member(sourceTableVar, sourceId)}],\\n relationName: ${quote(owningRelationName)}\\n })`);\n\n // Target side one(): pairs with inverse table's many(junctionTable, { relationName })\n // Always emit a relationName to avoid collisions with the source-side's owningRelationName.\n // When no inverse relation exists on the target collection, synthesize a unique name.\n const targetRelationName = inverseRelationName\n ? inverseRelationName\n : `${tableName}_${relation.through.targetColumn}`;\n tableRelations.push(` ${quote(relation.through.targetColumn)}: one(${targetTableVar}, {\\n fields: [${member(tableVarName, relation.through.targetColumn)}],\\n references: [${member(targetTableVar, targetId)}],\\n relationName: ${quote(targetRelationName)}\\n })`);\n }\n } else {\n const resolvedRelations = resolveCollectionRelations(collection);\n // Defensive safety net: track emitted `drizzleRelationName` values\n // to prevent duplicate one()/many() entries in the generated schema.\n // The root deduplication happens inside resolveCollectionRelations,\n // but this guards against any future regressions in that utility.\n const emittedRelationNames = new Set<string>();\n for (const [relationKey, rel] of Object.entries(resolvedRelations)) {\n try {\n const target = rel.target();\n const targetTableVar = getTableVarName(getTableName(target));\n\n // Compute a deterministic shared relationName for Drizzle.\n // Both sides of an owning/inverse pair MUST share the same\n // relationName, otherwise Drizzle cannot pair them.\n //\n // Strategy: use \"{ownerTable}_{foreignKey}\" which is\n // computable from either side:\n // - owning side: {thisTable}_{localKey}\n // - inverse side: {targetTable}_{foreignKeyOnTarget}\n const drizzleRelationName = computeSharedRelationName(rel, collection, collections);\n\n // Skip if we've already emitted a relation with this drizzleRelationName\n // for this table — prevents duplicate definitions when\n // resolveCollectionRelations returns alias entries for the same FK.\n const deduplicationKey = `${drizzleRelationName}::${rel.kind}`;\n if (emittedRelationNames.has(deduplicationKey)) continue;\n emittedRelationNames.add(deduplicationKey);\n\n switch (rel.kind) {\n case \"belongsTo\": {\n // `localKey` is a COLUMN name; the generated Drizzle\n // object is keyed by PROPERTY. They differ whenever\n // the property is camelCase — `user_id` is exposed\n // as `userId` — and emitting the column produces a\n // schema that does not compile. The three other\n // emission sites normalise; this one did not.\n const localFieldKey = resolvePropertyKeyForColumn(collection, rel.localKey);\n tableRelations.push(` ${quote(relationKey)}: one(${targetTableVar}, {\\n fields: [${member(tableVarName, localFieldKey)}],\\n references: [${member(targetTableVar, getPrimaryKeyName(target))}],\\n relationName: ${quote(drizzleRelationName)}\\n })`);\n break;\n }\n\n case \"hasOne\":\n // The foreign key lives on the TARGET table. Drizzle pairs\n // the two sides by `relationName` alone — giving\n // `fields`/`references` here is invalid and crashes\n // `normalizeRelation` with \"Cannot read properties of\n // undefined (reading 'referencedTable')\".\n // A `relationName` is authored, and a `\"` in one\n // closed this string literal early — in a file that\n // is compiled and imported by the server.\n tableRelations.push(` ${quote(relationKey)}: one(${targetTableVar}, {\\n relationName: ${quote(drizzleRelationName)}\\n })`);\n break;\n\n case \"hasMany\":\n tableRelations.push(` ${quote(relationKey)}: many(${targetTableVar}, { relationName: ${quote(drizzleRelationName)} })`);\n break;\n\n case \"manyToMany\": {\n // Both sides point at the junction. This used to have a\n // second arm that searched the *target's* relations for an\n // owning many-to-many whose name matched, to borrow its\n // junction table — unnecessary now that each side names\n // its own.\n const junctionTableVar = getTableVarName(rel.through.table);\n tableRelations.push(` ${quote(relationKey)}: many(${junctionTableVar}, { relationName: ${quote(drizzleRelationName)} })`);\n break;\n }\n\n case \"via\":\n // A join chain is resolved at query time, not modelled\n // as a Drizzle relation.\n break;\n }\n } catch (e) {\n logger.warn(`Could not generate relation ${relationKey} for ${collection.name}`, { error: e });\n }\n }\n\n // Synthesize missing reciprocal relations\n for (const otherCollection of collections) {\n if (otherCollection.slug === collection.slug) continue;\n\n const otherRelations = resolveCollectionRelations(otherCollection);\n for (const [otherKey, otherRel] of Object.entries(otherRelations)) {\n if (hasForeignKeyOnTarget(otherRel)) {\n try {\n const otherTarget = otherRel.target();\n if (otherTarget.slug === collection.slug) {\n const drizzleRelationName = computeSharedRelationName(otherRel, otherCollection, collections);\n const deduplicationKey = `${drizzleRelationName}::belongsTo`;\n\n if (!emittedRelationNames.has(deduplicationKey)) {\n const otherTableVar = getTableVarName(getTableName(otherCollection));\n // Resolve foreignKeyOnTarget to the Drizzle property key\n // on THIS collection (the owning table). The raw FK column\n // name (e.g. \"client_id\") may differ from the property key\n // (e.g. \"clientId\") when `columnName` is set.\n const drizzleFieldKey = resolvePropertyKeyForColumn(collection, otherRel.foreignKeyOnTarget);\n // The column the far side points at: its\n // primary key, unless the link names another\n // one with `sourceKey`.\n const referencedKey = otherRel.sourceKey\n ? resolvePropertyKeyForColumn(otherCollection, otherRel.sourceKey)\n : getPrimaryKeyName(otherCollection);\n const synthKey = `_synth_${otherTableVar}_${drizzleFieldKey}`;\n tableRelations.push(` ${quote(synthKey)}: one(${otherTableVar}, {\\n fields: [${member(tableVarName, drizzleFieldKey)}],\\n references: [${member(otherTableVar, referencedKey)}],\\n relationName: ${quote(drizzleRelationName)}\\n })`);\n emittedRelationNames.add(deduplicationKey);\n }\n }\n } catch (e) {\n // ignore\n }\n }\n }\n }\n }\n\n if (tableRelations.length > 0) {\n const relVarName = `${tableVarName}Relations`;\n schemaContent += `export const ${relVarName} = drizzleRelations(${tableVarName}, ({ one, many }) => ({\\n${tableRelations.join(\",\\n\")}\\n}));\\n\\n`;\n if (!exportedRelationVars.includes(relVarName)) exportedRelationVars.push(relVarName);\n }\n }\n\n // <<< ADDED: Final aggregated exports block\n const tablesExport = `export const tables = { ${exportedTableVars.join(\", \")} };\\n`;\n const enumsExport = `export const enums = { ${exportedEnumVars.join(\", \")} };\\n`;\n const relationsExport = `export const relations = { ${exportedRelationVars.join(\", \")} };\\n\\n`;\n schemaContent += tablesExport + enumsExport + relationsExport;\n\n return schemaContent;\n};\n\n"],"mappings":";;;;;;;;;;;;;AAcA,IAAM,gBAAgB;;;;;;;;;;AAWtB,IAAM,SAAS,UAA0B,KAAK,UAAU,KAAK;;AAG7D,IAAM,WAAW,SAA0B,cAAc,KAAK,IAAI,IAAI,OAAO,MAAM,IAAI;;;;;;;AAQvF,IAAM,UAAU,QAAgB,QAC3B,cAAc,KAAK,GAAG,IAAI,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,EAAE;AAE5E,IAAM,qBAAqB,UAAkB,SAAmC;CAC5E,IAAI,QAAQ,gBAAgB,QAAQ,OAAO,KAAK,eAAe,UAC3D,OAAO,KAAK;CAEhB,OAAO,YAAY,QAAQ;AAC/B;AAEA,IAAM,qBAAqB,eAA+F;CACtH,IAAI,WAAW,YAAY;EACvB,MAAM,cAAc,OAAO,QAAQ,WAAW,UAAU,CAAC,CAAC,MAAM,CAAC,GAAG,UAAU,UAAW,QAA8B,QAAS,KAA4C,IAAI,CAAC;EACjL,IAAI,aAAa;GACb,MAAM,OAAO,YAAY;GACzB,MAAM,SAAS,KAAK,SAAS,YAAY,UAAU,QAAS,KAAmC,SAAS;GACxG,OAAO;IAAE,MAAM,YAAY;IACvC,MAAM,KAAK,SAAS,WAAW,WAAW;IAC1C;GAAO;EACC;CACJ;CAEA,MAAM,SAAS,WAAW,aAAa;CACvC,IAAI,QAAQ,SAAS,UACjB,OAAO;EAAE,MAAM;EACvB,MAAM;EACN,QAAQ;CAAM;CAGV,OAAO;EAAE,MAAM;EACnB,MAAM;EACN,QAHmB,QAAQ,SAAS,YAAY,UAAU,UAAW,OAAqC,SAAS;CAG3F;AACxB;;;;;;;;;;;AAYA,IAAM,+BAA+B,YAA8B,WAC/D,kBAAkB,YAAY,MAAM;AAExC,IAAM,eAAe,eAA0C;CAC3D,OAAO,kBAAkB,UAAU,CAAC,CAAC,SAAS;AAClD;AAEA,IAAM,qBAAqB,eAAyC;CAChE,OAAO,kBAAkB,UAAU,CAAC,CAAC;AACzC;AAEA,IAAM,gBAAgB,UAAkB,MAAgB,eAA0C;CAC9F,IAAI,UAAU,QAAQ,QAAQ,KAAK,IAAI,GAAG,OAAO;CAIjD,OAAO,CADe,OAAO,OAAO,WAAW,cAAc,CAAC,CAAC,CAAC,CAAC,MAAK,MAAK,UAAW,KAA2B,QAAS,EAAyC,IAAI,CAC/J,KAAiB,aAAa;AAC1C;;;;;;;;AASA,IAAa,oBAAoB,UAAkB,MAAgB,YAA8B,gBAAmD;CAEhJ,MAAM,UAAU,kBAAkB,UAAU,IAAI;CAChD,IAAI;CAEJ,QAAQ,KAAK,MAAb;EACI,KAAK,UAAU;GACX,MAAM,aAAa;GACnB,IAAI,WAAW,MAEX,mBAAmB,GADF,eAAe,aAAa,UAAU,GAAG,QACpC,EAAS,GAAG,MAAM,OAAO,EAAE;QAC9C,IAAI,UAAU,cAAc,WAAW,SAAS,QACnD,mBAAmB,QAAQ,MAAM,OAAO,EAAE;QACvC,IAAI,WAAW,eAAe,QACjC,mBAAmB,QAAQ,MAAM,OAAO,EAAE;QACvC,IAAI,WAAW,eAAe,QACjC,mBAAmB,QAAQ,MAAM,OAAO,EAAE,cAAc,0BAA0B,UAAU,EAAE;QAC3F,IAAI,WAAW,eAAe,WAKjC,mBAAmB,WAAW,MAAM,OAAO,EAAE,cAAc,0BAA0B,UAAU,EAAE;QAIjG,mBAAmB,QAAQ,MAAM,OAAO,EAAE;GAE9C,IAAI,aAAa,UAAU,MAAM,UAAU,GACvC,oBAAoB;GAExB,IAAI,UAAU,cAAc,WAAW,SAAS,YAAY,WAAW,SAAS;QACxE,WAAW,SAAS,QACpB,oBAAoB;SACjB,IAAI,WAAW,SAAS,QAC3B,oBAAoB;SACjB,IAAI,OAAO,WAAW,SAAS,UAAU;KAC5C,MAAM,aAAa,WAAW,KAAK,WAAW,MAAM,KAAK,WAAW,KAAK,SAAS,GAAG,IAC/E,WAAW,KAAK,UAAU,GAAG,WAAW,KAAK,SAAS,CAAC,IACvD,WAAW;KACjB,oBAAoB,iBAAiB,WAAW;IACpD;;GAEJ,IAAI,WAAW,YAAY,QACvB,oBAAoB;GAExB;EACJ;EACA,KAAK,UAAU;GACX,MAAM,UAAU;GAChB,MAAM,OAAO,aAAa,UAAU,MAAM,UAAU;GAEpD,IAAI,WAAY,QAAQ,YAAY,WAAW,OAAQ,WAAW,MAAM,OAAO,EAAE,KAAK,WAAW,MAAM,OAAO,EAAE;GAChH,IAAI,QAAQ,YACR,IAAI,QAAQ,eAAe,oBAAoB,WAAW,mBAAmB,MAAM,OAAO,EAAE;QAiBvF,IAAI,QAAQ,eAAe,YAAY,QAAQ,eAAe,aAC/D,WAAW,GAAG,QAAQ,WAAW,GAAG,MAAM,OAAO,EAAE;QAElD,WAAW,GAAG,QAAQ,WAAW,GAAG,MAAM,OAAO,EAAE;GAG5D,IAAI,UAAU,WAAW,QAAQ,SAAS,aACtC,mBAAmB,GAAG,SAAS;QAC5B,IAAI,UAAU,WAAW,OAAO,QAAQ,SAAS,YAAY,QAAQ,SAAS,UAAU;IAC3F,mBAAmB;IACnB,MAAM,aAAa,QAAQ,KAAK,WAAW,MAAM,KAAK,QAAQ,KAAK,SAAS,GAAG,IACzE,QAAQ,KAAK,UAAU,GAAG,QAAQ,KAAK,SAAS,CAAC,IACjD,QAAQ;IACd,oBAAoB,iBAAiB,WAAW;GACpD,OACI,mBAAmB;GAGvB,IAAI,MACA,oBAAoB;GAExB,IAAI,QAAQ,YAAY,QACpB,oBAAoB;GAExB;EACJ;EACA,KAAK;GACD,mBAAmB,WAAW,MAAM,OAAO,EAAE;GAC7C;EACJ,KAAK,QAAQ;GACT,MAAM,WAAW;GACjB,IAAI,SAAS,eAAe,QACxB,mBAAmB,QAAQ,MAAM,OAAO,EAAE;QACvC,IAAI,SAAS,eAAe,QAC/B,mBAAmB,QAAQ,MAAM,OAAO,EAAE;QAE1C,mBAAmB,aAAa,MAAM,OAAO,EAAE;GAGnD,IAAI,SAAS,cAAc,eAAe,SAAS,cAAc,aAC7D,oBAAoB;GAExB;EACJ;EACA,KAAK;GAED,IAAI,KAAQ,eAAe,QACvB,mBAAmB,QAAQ,MAAM,OAAO,EAAE;QAE1C,mBAAmB,SAAS,MAAM,OAAO,EAAE;GAE/C;EAEJ,KAAK;GAOD,mBAAmB,SAAS,MAAM,OAAO,EAAE;GAC3C;EAEJ,KAAK,SAAS;GACV,MAAM,YAAY;GAClB,IAAI,UAAU,UAAU;GACxB,IAAI,CAAC,WAAW,UAAU,MAAM,CAAC,MAAM,QAAQ,UAAU,EAAE,GAAG;IAC1D,MAAM,SAAS,UAAU;IACzB,IAAI,OAAO,SAAS,UAChB,UAAU;SACP,IAAI,OAAO,SAAS,UACvB,UAAU,OAAO,YAAY,UAAU,cAAc;SAClD,IAAI,OAAO,SAAS,WACvB,UAAU;GAElB;GAEA,IAAI,YAAY,QACZ,mBAAmB,QAAQ,MAAM,OAAO,EAAE;QACvC,IAAI,YAAY,UACnB,mBAAmB,QAAQ,MAAM,OAAO,EAAE;QACvC,IAAI,YAAY,aACnB,mBAAmB,WAAW,MAAM,OAAO,EAAE;QAC1C,IAAI,YAAY,aACnB,mBAAmB,WAAW,MAAM,OAAO,EAAE;QAC1C,IAAI,YAAY,aACnB,mBAAmB,WAAW,MAAM,OAAO,EAAE;QAE7C,mBAAmB,SAAS,MAAM,OAAO,EAAE;GAE/C;EACJ;EACA,KAAK,UAAU;GACX,MAAM,KAAK;GACX,mBAAmB,UAAU,MAAM,OAAO,EAAE,kBAAkB,GAAG,WAAW;GAC5E;EACJ;EACA,KAAK;GACD,mBAAmB,kDAAkD,MAAM,OAAO,EAAE;GACpF;EAEJ,KAAK,YAAY;GACb,MAAM,UAAU;GAEhB,MAAM,WAAW,aADS,2BAA2B,UACvB,GAAmB,QAAQ,UAAU,gBAAgB,QAAQ;GAI3F,IAAI,CAAC,YAAY,SAAS,SAAS,aAC/B,OAAO;GASX,MAAM,aAAa,kBAAkB,YAAY,SAAS,QAAQ;GAClE,IAAI,WAAW,WAAW,eAAe,aAAa,YAClD,OAAO;GAGX,IAAI;GACJ,IAAI;IACA,mBAAmB,SAAS,OAAO;GACvC,QAAQ;IACJ,OAAO;GACX;GAEA,MAAM,eAAe,SAAS;GAC9B,MAAM,iBAAiB,gBAAgB,aAAa,gBAAgB,CAAC;GACrE,MAAM,SAAS,kBAAkB,gBAAgB;GACjD,MAAM,gBAAgB,OAAO;GAI7B,MAAM,aAAa,OAAO,SAAS,WAC7B,WAAW,MAAM,YAAY,EAAE,KAC9B,OAAO,SAAS,QAAQ,MAAM,YAAY,EAAE,KAAK,QAAQ,MAAM,YAAY,EAAE;GAEpF,MAAM,WAAW,SAAS,WAAW,cAAc,SAAS,SAAS,KAAK;GAC1E,MAAM,WAAW,KAAK,YAAY;GAQlC,MAAM,kBAAkB,CAAC,UAAU,eAHf,SAAS,YAAY,yBAAyB,QAAQ,CAAC,CAAC,YAAY,EAC5C,GAED,CAAC,CAAC,OAAO,OAAO;GAC3D,MAAM,aAAa,gBAAgB,SAAS,IAAI,KAAK,gBAAgB,KAAK,IAAI,EAAE,MAAM;GAEtF,IAAI,YAAY,GAAG,WAAW,oBAAoB,OAAO,gBAAgB,aAAa,IAAI,aAAa,KAAK,eAAe,GAAG;GAE9H,IAAI,UACA,aAAa;GAMjB,OAAO,OAAO,QAAQ,UAAU,EAAE,IAAI;EAC1C;EACA,KAAK,aAAa;GACd,MAAM,UAAU;GAChB,MAAM,mBAAmB,YAAY,MAAK,MAAK,EAAE,SAAS,QAAQ,QAAQ,aAAa,CAAC,MAAM,QAAQ,IAAI;GAC1G,IAAI,CAAC,kBAAkB;IACnB,mBAAmB,QAAQ,MAAM,OAAO,EAAE;IAC1C;GACJ;GAEA,MAAM,SAAS,kBAAkB,gBAAgB;GACjD,MAAM,iBAAiB,gBAAgB,aAAa,gBAAgB,CAAC;GACrE,MAAM,gBAAgB,OAAO;GAC7B,MAAM,aAAa,OAAO,SAAS,WAAW,WAAW,MAAM,OAAO,EAAE,KAAM,OAAO,SAAS,QAAQ,MAAM,OAAO,EAAE,KAAK,QAAQ,MAAM,OAAO,EAAE;GAEjJ,MAAM,WAAW,KAAK,YAAY;GAElC,MAAM,aAAa,gBADF,WAAW,YAAY,WACI;GAE5C,mBAAmB,GAAG,WAAW,oBAAoB,OAAO,gBAAgB,aAAa,EAAE,IAAI,WAAW;GAC1G,IAAI,UACA,oBAAoB;GAGxB,OAAO,OAAO,QAAQ,QAAQ,EAAE,IAAI;EACxC;EACA,SAUI,MAAM,IAAI,MACN,4CAA4C,SAAS,aAChD,KAAkB,KAAK,mBAAmB,WAAW,KAAK,uFAEnE;CACR;CAEA,IAAI,KAAK,YAAY,UACjB,oBAAoB;CAGxB,OAAO,OAAO,QAAQ,QAAQ,EAAE,IAAI;AACxC;;;;;;;;;;;;;;;;;;;;;AAsBA,IAAM,WAAW,WACb,QAAQ,OAAO,QAAQ,OAAO,MAAM,CAAC,CAAC,QAAQ,MAAM,KAAK,CAAC,CAAC,QAAQ,SAAS,MAAM,EAAE;AAkBxF,IAAM,sBAAsB,YAA8B,MAAoB,OAAe,sBAAiD;CAC1I,MAAM,YAAY,aAAa,UAAU;CAEzC,MAAM,MAAoC,KAAK,cAAc,KAAK,WAAW,SAAS,IAChF,KAAK,aACL,CAAC,KAAK,aAAa,KAAK;CAE9B,MAAM,cAAc,sBAAsB,MAAM,SAAS;CAGzD,OAAO,IAAI,KAAK,IAAI,UAAU;EAC1B,OAAO,yBAAyB,YAAY,MAAM,IAAI,YAAY,QAAQ,iBAAiB;CAC/F,CAAC,CAAC,CAAC,KAAK,EAAE;AACd;;;;AAKA,IAAM,4BAA4B,YAA8B,MAAoB,WAA8B,YAAoB,sBAAiD;CACnL,MAAM,OAAO,KAAK,QAAQ;CAM1B,MAAM,aAAa,cAAc;CACjC,MAAM,iBAAiB,cAAc,YAAY,cAAc;CAK/D,MAAM,EAAE,WAAW,kBAAkB,yBAAyB,IAAI;CAElE,IAAI,cAAc,cAAc,YAAY,QAAQ,iBAAiB,WAAW,YAAY,EAAE,kBAAkB,CAAC,CAAC,IAAI;CACtH,IAAI,kBAAkB,kBAAkB,gBAAgB,QAAQ,iBAAiB,eAAe,YAAY,EAAE,kBAAkB,CAAC,CAAC,IAAI;CAGtI,IAAI,CAAC,eAAe,YAChB,cAAc;CAElB,IAAI,CAAC,mBAAmB,gBACpB,kBAAkB;CAItB,MAAM,QAAkB,CAAC;CACzB,MAAM,KAAK,QAAQ,KAAK,EAAE;CAC1B,MAAM,KAAK,SAAS,UAAU,EAAE;CAChC,MAAM,UAAU,KAAK,UAAU,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC,QAAQ;CACnE,MAAM,KAAK,QAAQ,QAAQ,KAAI,MAAK,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE;CAC3D,IAAI,aAAa,MAAM,KAAK,UAAU,aAAa;CACnD,IAAI,iBAAiB,MAAM,KAAK,cAAc,iBAAiB;CAE/D,OAAO,gBAAgB,MAAM,UAAU,EAAE,MAAM,MAAM,KAAK,IAAI,EAAE;AACpE;;;;;;;;;;;;;;;;;;AAmBA,IAAM,6BACF,KACA,kBACA,iBACS;CACT,MAAM,WAAW,IAAI,gBAAgB,YAAY,IAAI,OAAO,CAAC,CAAC,IAAI;CAKlE,IAAI,IAAI,SAAS,aAAa;EAC1B,MAAM,gBAAgB,4BAA4B,kBAAkB,IAAI,QAAQ;EAChF,OAAO,GAAG,aAAa,gBAAgB,EAAE,GAAG;CAChD;CAEA,IAAI,IAAI,SAAS,aAAa,IAAI,SAAS,UAEvC,IAAI;EACA,MAAM,mBAAmB,IAAI,OAAO;EACpC,MAAM,eAAe,4BAA4B,kBAAkB,IAAI,kBAAkB;EACzF,OAAO,GAAG,aAAa,gBAAgB,EAAE,GAAG;CAChD,QAAQ;EACJ,OAAO;CACX;CAKJ,OAAO;AACX;AAGA,IAAa,iBAAiB,OAAO,gBAAoC,gBAAgB,UAA2B;CAWhH,MAAM,cAAc,sBAAsB,sBAAsB,cAAc,CAAC;CAC/E,IAAI,gBAAgB;CAGpB,MAAM,UAAU,YAAY,MAAK,MAC7B,EAAE,cAAc,OAAO,OAAO,EAAE,UAAU,CAAC,CAAC,MACvC,MAAgB,EAAE,SAAS,aAAc,EAAyC,cAAc,UAAW,EAAyC,SAAS,OAClK,CACJ;CAEA,MAAM,YAAY,YAAY,MAAK,MAC/B,EAAE,cAAc,OAAO,OAAO,EAAE,UAAU,CAAC,CAAC,MACvC,MAAgB,EAAE,SAAS,QAChC,CACJ;CAEA,MAAM,YAAY,YAAY,MAAK,MAC/B,EAAE,cAAc,OAAO,OAAO,EAAE,UAAU,CAAC,CAAC,MACvC,MAAgB,EAAE,SAAS,QAChC,CACJ;CAIA,MAAM,YAAY,YAAY,MAAK,MAAK,sBAAsB,CAAC,MAAM,KAAA,CAAS;CAG9E,MAAM,gBAAgB;EAAC;EAAc;EAAW;EAAW;EAAW;EAAQ;EAAQ;EAAW;EAAa;EAAQ;EAAQ;EAAS;EAAQ;EAAU;EAAW;EAAQ;EAAmB;EAAU;EAAU;EAAa;CAAU;CAC1O,IAAI,SAAS,cAAc,KAAK,MAAM;CACtC,IAAI,WAAW,cAAc,KAAK,QAAQ;CAC1C,IAAI,aAAa,WAAW,cAAc,KAAK,YAAY;CAE3D,MAAM,gBAAgB,MAAM,KAAK,IAAI,IACjC,YAAY,KAAI,MAAK,2BAA2B,CAAC,IAAI,EAAE,SAAS,KAAA,CAAS,CAAC,CAAC,OAAO,OAAO,CAC7F,CAAC;CACD,IAAI,cAAc,SAAS,GACvB,cAAc,KAAK,UAAU;CAGjC,iBAAiB,YAAY,cAAc,KAAK,IAAI,EAAE;CACtD,iBAAiB;CAEjB,cAAc,SAAQ,WAAU;EAC5B,iBAAiB,gBAAgB,OAAO,qBAAqB,OAAO;CACxE,CAAC;CACD,IAAI,cAAc,SAAS,GACvB,iBAAiB;CAGrB,MAAM,oBAA8B,CAAC;CACrC,MAAM,mBAA6B,CAAC;CACpC,MAAM,uBAAiC,CAAC;CAExC,MAAM,sCAAsB,IAAI,IAK7B;CAGH,YAAY,SAAQ,eAAc;EAC9B,MAAM,iBAAiB,aAAa,UAAU;EAC9C,OAAO,QAAQ,WAAW,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,UAAU;GAEtE,IAAK,UAAU,SAAU,KAAK,SAAS,YAAY,KAAK,SAAS,aAAa,KAAK,MAAM;IACrF,MAAM,cAAc,eAAe,gBAAgB,QAAQ;IAC3D,MAAM,aAAa,GAAG,eAAe,GAAG,kBAAkB,UAAU,IAAI;IACxE,MAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,IAC/B,KAAK,KAAuD,KAAK,MAChE,OAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,QAAQ,IAAI,EAAE,KAAK,CAAC,CACtE,IACE,OAAO,KAAK,KAAK,IAAI;IAC3B,IAAI,OAAO,SAAS,GAAG;KACnB,iBAAiB,gBAAgB,YAAY,YAAY,MAAM,UAAU,EAAE,KAAK,OAAO,KAAI,MAAK,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;KACrH,IAAI,CAAC,iBAAiB,SAAS,WAAW,GAAG,iBAAiB,KAAK,WAAW;IAClF;GACJ;EACJ,CAAC;CACL,CAAC;CACD,iBAAiB;CAIjB,MAAM,gBAAgB,qBAAqB,WAAW;CAGtD,KAAK,MAAM,cAAc,aAAa;EAClC,MAAM,YAAY,aAAa,UAAU;EACzC,IAAI,WACA,oBAAoB,IAAI,WAAW,EAAE,WAAW,CAAC;EAGrD,MAAM,oBAAoB,2BAA2B,UAAU;EAC/D,KAAK,MAAM,YAAY,OAAO,OAAO,iBAAiB,GAClD,IAAI,aAAa,QAAQ,GAAG;GACxB,MAAM,oBAAoB,SAAS,QAAQ;GAC3C,IAAI,CAAC,oBAAoB,IAAI,iBAAiB,GAC1C,oBAAoB,IAAI,mBAAmB;IACvC,YAAY;KACR,OAAO;KACP,YAAY,CAAC;IACjB;IACA,YAAY;IACF;IACV,kBAAkB;GACtB,CAAC;EAET;CAGR;CAGA,KAAK,MAAM,CAAC,WAAW,EACnB,YACA,YACA,UACA,uBACE,oBAAoB,QAAQ,GAAG;EACjC,MAAM,eAAe,gBAAgB,SAAS;EAC9C,IAAI,cAAc,YAAY,oBAAoB,aAAa,QAAQ,GAAG;GACtE,MAAM,mBAAmB,SAAS,OAAO;GASzC,MAAM,eAAe;GACrB,MAAM,gBAAgB,UAAU,SAAS,GAAG,IAAI,UAAU,MAAM,GAAG,CAAC,CAAC,IAAI,IAAK;GAC9E,MAAM,EACF,cACA,iBACA,SAAS;GAGb,MAAM,aAAa,iBADF,SAAS,YAAY,UACO;GAI7C,MAAM,gBAAgB,YAAY,gBAAgB,IAAI,YAAa,kBAAkB,gBAAgB,CAAC,CAAC,SAAS,SAAS;GACzH,MAAM,gBAAgB,YAAY,gBAAgB,IAAI,YAAa,kBAAkB,gBAAgB,CAAC,CAAC,SAAS,SAAS;GACzH,MAAM,WAAW,kBAAkB,gBAAgB;GACnD,MAAM,WAAW,kBAAkB,gBAAgB;GAEnD,iBAAiB,gBAAgB,aAAa,KAAK,aAAa,KAAK,cAAc;GAInF,iBAAiB,OAAO,QAAQ,YAAY,EAAE,IAAI,cAAc,GAAG,MAAM,YAAY,EAAE,+BAA+B,OAAO,gBAAgB,aAAa,gBAAgB,CAAC,GAAG,QAAQ,EAAE,IAAI,WAAW;GACvM,iBAAiB,OAAO,QAAQ,YAAY,EAAE,IAAI,cAAc,GAAG,MAAM,YAAY,EAAE,+BAA+B,OAAO,gBAAgB,aAAa,gBAAgB,CAAC,GAAG,QAAQ,EAAE,IAAI,WAAW;GACvM,iBAAiB;GACjB,iBAAiB,8BAA8B,OAAO,SAAS,YAAY,EAAE,IAAI,OAAO,SAAS,YAAY,EAAE;GAM/G,MAAM,eAAe,cAAc,IAAI,aAAa;GACpD,IAAI,CAAC,iBAAiB,cAAc;IAChC,MAAM,qBAAqB,4BAA4B,YAAY;IACnE,MAAM,qBAAwC,SAAS,YAAY,MAAK,MAAK,EAAE,SAAS,QAAQ,aAAa,CAAC,MAAM,IAAI;IACxH,yBAAyB,YAAY,CAAC,CAAC,SAAS,MAAoB,QAAgB;KAChF,iBAAiB,mBAAmB,oBAAoB,MAAM,KAAK,iBAAiB;IACxF,CAAC;GACL;GACA,iBAAiB;EACrB,OAAO,IAAI,CAAC,YAAY;GACpB,MAAM,SAAS,2BAA2B,UAAU,IAAI,WAAW,SAAS,KAAA;GAC5E,MAAM,eAAe,SAAS,GAAG,OAAO,gBAAgB;GACxD,MAAM,gBAAgB,UAAU,SAAS,GAAG,IAAI,UAAU,MAAM,GAAG,CAAC,CAAC,IAAI,IAAK;GAC9E,iBAAiB,gBAAgB,aAAa,KAAK,aAAa,KAAK,cAAc;GACnF,MAAM,0BAAU,IAAI,IAAY;GAChC,OAAO,QAAQ,WAAW,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,UAAU;IACtE,MAAM,eAAe,iBAAiB,UAAU,MAAkB,YAAY,WAAW;IACzF,IAAI,cAAc,QAAQ,IAAI,YAAY;GAE9C,CAAC;GAOD,MAAM,aAAa,sBAAsB,UAAU;GACnD,IAAI,YAAY;IACZ,QAAQ,IACJ,OAAO,QAAQ,WAAW,MAAM,EAAE,sDAAsD,MAAM,WAAW,MAAM,EAAE,2BACtF,WAAW,WAAW,IACrD;IACA,IAAI,WAAW,OACX,QAAQ,IACJ,OAAO,QAAQ,WAAW,MAAM,MAAM,EAAE,SAAS,MAAM,WAAW,MAAM,MAAM,EAAE,2BACrD,WAAW,MAAM,WAAW,IAC3D;GAER;GAMA,IAAI,CADgB,MAAM,KAAK,OAAO,CAAC,CAAC,MAAK,QAAO,IAAI,SAAS,eAAe,CAC3E,GACD,QAAQ,IAAI,mCAAmC;GAGnD,iBAAiB,GAAG,MAAM,KAAK,OAAO,CAAC,CAAC,KAAK,KAAK;GAElD,MAAM,gBAAgB,0BAA0B,UAAU;GAC1D,IAAI,CAAC,iBAAiB,cAAc,SAAS,GAAG;IAC5C,iBAAiB;IACjB,MAAM,qBAAwC,SAAS,YAAY,MAAK,MAAK,EAAE,SAAS,QAAQ,aAAa,CAAC,MAAM,IAAI;IACxH,cAAc,SAAS,MAAoB,QAAgB;KACvD,iBAAiB,mBAAmB,YAAY,MAAM,KAAK,iBAAiB;IAChF,CAAC;IACD,iBAAiB;GACrB,OAGI,iBAAiB;EAEzB;EACA,IAAI,CAAC,kBAAkB,SAAS,YAAY,GAAG,kBAAkB,KAAK,YAAY;CACtF;CAGA,KAAK,MAAM,CAAC,WAAW,EACnB,YACA,iBACE,oBAAoB,QAAQ,GAAG;EACjC,MAAM,eAAe,gBAAgB,SAAS;EAC9C,MAAM,iBAA2B,CAAC;EAElC,IAAI,YAAY;GACZ,MAAM,eAAe,MAAM,KAAK,oBAAoB,OAAO,CAAC,CAAC,CAAC,MAAK,MAAK,EAAE,cAAc,aAAa,EAAE,UAAU,MAAM,SAAS;GAChI,IAAI,gBAAgB,aAAa,YAAY,aAAa,oBAAoB,aAAa,aAAa,QAAQ,GAAG;IAC/G,MAAM,EACF,UACA,qBACA;IACJ,MAAM,mBAAmB,SAAS,OAAO;IACzC,MAAM,iBAAiB,gBAAgB,aAAa,gBAAgB,CAAC;IACrE,MAAM,iBAAiB,gBAAgB,aAAa,gBAAgB,CAAC;IACrE,MAAM,WAAW,kBAAkB,gBAAgB;IACnD,MAAM,WAAW,kBAAkB,gBAAgB;IAEnD,IAAI,CAAC,UAAU,SACX,MAAM,IAAI,MAAM,wIAAwI;IAG5J,MAAM,qBAAqB,SAAS,gBAAgB,YAAY,aAAa,gBAAgB,CAAC;IAK9F,IAAI,sBAAqC;IACzC,IAAI;KACA,MAAM,kBAAkB,2BAA2B,gBAAgB;KACnE,KAAK,MAAM,GAAG,cAAc,OAAO,QAAQ,eAAe,GACtD,IAAI,UAAU,SAAS,eACnB,UAAU,gBAAgB,UAC1B,UAAU,iBAAiB,oBAAoB;MAC/C,sBAAsB,UAAU,gBAAgB;MAChD;KACJ;IAER,QAAQ,CAER;IAGA,eAAe,KAAK,OAAO,MAAM,SAAS,QAAQ,YAAY,EAAE,QAAQ,eAAe,wBAAwB,OAAO,cAAc,SAAS,QAAQ,YAAY,EAAE,2BAA2B,OAAO,gBAAgB,QAAQ,EAAE,4BAA4B,MAAM,kBAAkB,EAAE,SAAS;IAK9R,MAAM,qBAAqB,sBACrB,sBACA,GAAG,UAAU,GAAG,SAAS,QAAQ;IACvC,eAAe,KAAK,OAAO,MAAM,SAAS,QAAQ,YAAY,EAAE,QAAQ,eAAe,wBAAwB,OAAO,cAAc,SAAS,QAAQ,YAAY,EAAE,2BAA2B,OAAO,gBAAgB,QAAQ,EAAE,4BAA4B,MAAM,kBAAkB,EAAE,SAAS;GAClS;EACJ,OAAO;GACH,MAAM,oBAAoB,2BAA2B,UAAU;GAK/D,MAAM,uCAAuB,IAAI,IAAY;GAC7C,KAAK,MAAM,CAAC,aAAa,QAAQ,OAAO,QAAQ,iBAAiB,GAC7D,IAAI;IACA,MAAM,SAAS,IAAI,OAAO;IAC1B,MAAM,iBAAiB,gBAAgB,aAAa,MAAM,CAAC;IAU3D,MAAM,sBAAsB,0BAA0B,KAAK,YAAY,WAAW;IAKlF,MAAM,mBAAmB,GAAG,oBAAoB,IAAI,IAAI;IACxD,IAAI,qBAAqB,IAAI,gBAAgB,GAAG;IAChD,qBAAqB,IAAI,gBAAgB;IAEzC,QAAQ,IAAI,MAAZ;KACI,KAAK,aAAa;MAOd,MAAM,gBAAgB,4BAA4B,YAAY,IAAI,QAAQ;MAC1E,eAAe,KAAK,OAAO,MAAM,WAAW,EAAE,QAAQ,eAAe,wBAAwB,OAAO,cAAc,aAAa,EAAE,2BAA2B,OAAO,gBAAgB,kBAAkB,MAAM,CAAC,EAAE,4BAA4B,MAAM,mBAAmB,EAAE,SAAS;MAC9Q;KACJ;KAEA,KAAK;MASD,eAAe,KAAK,OAAO,MAAM,WAAW,EAAE,QAAQ,eAAe,6BAA6B,MAAM,mBAAmB,EAAE,SAAS;MACtI;KAEJ,KAAK;MACD,eAAe,KAAK,OAAO,MAAM,WAAW,EAAE,SAAS,eAAe,oBAAoB,MAAM,mBAAmB,EAAE,IAAI;MACzH;KAEJ,KAAK,cAAc;MAMf,MAAM,mBAAmB,gBAAgB,IAAI,QAAQ,KAAK;MAC1D,eAAe,KAAK,OAAO,MAAM,WAAW,EAAE,SAAS,iBAAiB,oBAAoB,MAAM,mBAAmB,EAAE,IAAI;MAC3H;KACJ;KAEA,KAAK,OAGD;IACR;GACJ,SAAS,GAAG;IACR,OAAO,KAAK,+BAA+B,YAAY,OAAO,WAAW,QAAQ,EAAE,OAAO,EAAE,CAAC;GACjG;GAIJ,KAAK,MAAM,mBAAmB,aAAa;IACvC,IAAI,gBAAgB,SAAS,WAAW,MAAM;IAE9C,MAAM,iBAAiB,2BAA2B,eAAe;IACjE,KAAK,MAAM,CAAC,UAAU,aAAa,OAAO,QAAQ,cAAc,GAC5D,IAAI,sBAAsB,QAAQ,GAC9B,IAAI;KAEA,IADoB,SAAS,OACzB,CAAA,CAAY,SAAS,WAAW,MAAM;MACtC,MAAM,sBAAsB,0BAA0B,UAAU,iBAAiB,WAAW;MAC5F,MAAM,mBAAmB,GAAG,oBAAoB;MAEhD,IAAI,CAAC,qBAAqB,IAAI,gBAAgB,GAAG;OAC7C,MAAM,gBAAgB,gBAAgB,aAAa,eAAe,CAAC;OAKnE,MAAM,kBAAkB,4BAA4B,YAAY,SAAS,kBAAkB;OAI3F,MAAM,gBAAgB,SAAS,YACzB,4BAA4B,iBAAiB,SAAS,SAAS,IAC/D,kBAAkB,eAAe;OACvC,MAAM,WAAW,UAAU,cAAc,GAAG;OAC5C,eAAe,KAAK,OAAO,MAAM,QAAQ,EAAE,QAAQ,cAAc,wBAAwB,OAAO,cAAc,eAAe,EAAE,2BAA2B,OAAO,eAAe,aAAa,EAAE,4BAA4B,MAAM,mBAAmB,EAAE,SAAS;OAC/P,qBAAqB,IAAI,gBAAgB;MAC7C;KACJ;IACJ,SAAS,GAAG,CAEZ;GAGZ;EACJ;EAEA,IAAI,eAAe,SAAS,GAAG;GAC3B,MAAM,aAAa,GAAG,aAAa;GACnC,iBAAiB,gBAAgB,WAAW,sBAAsB,aAAa,2BAA2B,eAAe,KAAK,KAAK,EAAE;GACrI,IAAI,CAAC,qBAAqB,SAAS,UAAU,GAAG,qBAAqB,KAAK,UAAU;EACxF;CACJ;CAGA,MAAM,eAAe,2BAA2B,kBAAkB,KAAK,IAAI,EAAE;CAC7E,MAAM,cAAc,0BAA0B,iBAAiB,KAAK,IAAI,EAAE;CAC1E,MAAM,kBAAkB,8BAA8B,qBAAqB,KAAK,IAAI,EAAE;CACtF,iBAAiB,eAAe,cAAc;CAE9C,OAAO;AACX"}