@palbase/backend 0.5.0 → 0.9.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/schema.ts","../../src/db/columns.ts","../../src/db/generator.ts"],"sourcesContent":["import type { ColumnBuilder } from \"./columns.js\";\n\n/** A table definition with its columns. */\nexport interface TableDef {\n name: string;\n columns: Record<string, ColumnBuilder>;\n}\n\n/** A schema definition containing multiple tables. */\nexport interface SchemaDef<T extends Record<string, TableDef> = Record<string, TableDef>> {\n tables: T;\n}\n\n/** Define a table with a name and columns. */\nexport function table(name: string, columns: Record<string, ColumnBuilder>): TableDef {\n return { name, columns };\n}\n\n/** Define a schema containing multiple tables. */\nexport function defineSchema<T extends Record<string, TableDef>>(tables: T): SchemaDef<T> {\n return { tables };\n}\n","/** On delete action for foreign key references. */\nexport type OnDeleteAction = \"cascade\" | \"set null\" | \"restrict\" | \"no action\";\n\n/** Column type identifiers. */\nexport type ColumnType = \"uuid\" | \"text\" | \"integer\" | \"boolean\" | \"timestamp\" | \"jsonb\" | \"enum\";\n\n/** Base column definition shared by all column types. */\nexport interface ColumnDef {\n type: ColumnType;\n nullable: boolean;\n primaryKey: boolean;\n defaultValue?: unknown;\n defaultRandom?: boolean;\n defaultNow?: boolean;\n references?: { table: string; column: string };\n onDeleteAction?: OnDeleteAction;\n enumName?: string;\n enumValues?: string[];\n}\n\n/** Fluent column builder. Methods return `this` for chaining. */\nclass ColumnBuilder {\n readonly _def: ColumnDef;\n\n constructor(type: ColumnType) {\n this._def = {\n type,\n nullable: false,\n primaryKey: false,\n };\n }\n\n /** Mark this column as the primary key. */\n primaryKey(): this {\n this._def.primaryKey = true;\n return this;\n }\n\n /** Mark this column as NOT NULL (default). */\n notNull(): this {\n this._def.nullable = false;\n return this;\n }\n\n /** Allow NULL values. */\n nullable(): this {\n this._def.nullable = true;\n return this;\n }\n\n /** Set a default value. */\n default(value: unknown): this {\n this._def.defaultValue = value;\n return this;\n }\n\n /** UUID: generate a random default (gen_random_uuid()). */\n defaultRandom(): this {\n this._def.defaultRandom = true;\n return this;\n }\n\n /** Timestamp: default to now(). */\n defaultNow(): this {\n this._def.defaultNow = true;\n return this;\n }\n\n /** Add a foreign key reference. */\n references(table: string, column: string): this {\n this._def.references = { table, column };\n return this;\n }\n\n /** Set the ON DELETE action for a foreign key reference. */\n onDelete(action: OnDeleteAction): this {\n this._def.onDeleteAction = action;\n return this;\n }\n}\n\n/** Create a UUID column. */\nexport function uuid(): ColumnBuilder {\n return new ColumnBuilder(\"uuid\");\n}\n\n/** Create a TEXT column. */\nexport function text(): ColumnBuilder {\n return new ColumnBuilder(\"text\");\n}\n\n/** Create an INTEGER column. */\nexport function integer(): ColumnBuilder {\n return new ColumnBuilder(\"integer\");\n}\n\n/** Create a BOOLEAN column. */\nexport function boolean(): ColumnBuilder {\n return new ColumnBuilder(\"boolean\");\n}\n\n/** Create a TIMESTAMP column. */\nexport function timestamp(): ColumnBuilder {\n return new ColumnBuilder(\"timestamp\");\n}\n\n/** Create a JSONB column. */\nexport function jsonb(): ColumnBuilder {\n return new ColumnBuilder(\"jsonb\");\n}\n\n/** Create an ENUM column. */\nexport function enumType(name: string, values: string[]): ColumnBuilder {\n const builder = new ColumnBuilder(\"enum\");\n builder._def.enumName = name;\n builder._def.enumValues = values;\n return builder;\n}\n\nexport { ColumnBuilder };\n","import type { ColumnDef, OnDeleteAction } from \"./columns.js\";\nimport type { SchemaDef, TableDef } from \"./schema.js\";\n\n/** Maps column types to their PostgreSQL SQL equivalents. */\nfunction columnTypeToSQL(col: ColumnDef): string {\n switch (col.type) {\n case \"uuid\":\n return \"UUID\";\n case \"text\":\n return \"TEXT\";\n case \"integer\":\n return \"INTEGER\";\n case \"boolean\":\n return \"BOOLEAN\";\n case \"timestamp\":\n return \"TIMESTAMPTZ\";\n case \"jsonb\":\n return \"JSONB\";\n case \"enum\":\n return col.enumName ?? \"TEXT\";\n default:\n return \"TEXT\";\n }\n}\n\n/** Generates the DEFAULT clause for a column. */\nfunction defaultClause(col: ColumnDef): string {\n if (col.defaultRandom) {\n return \" DEFAULT gen_random_uuid()\";\n }\n if (col.defaultNow) {\n return \" DEFAULT now()\";\n }\n if (col.defaultValue !== undefined) {\n if (typeof col.defaultValue === \"string\") {\n // Escape single quotes in string defaults\n const escaped = col.defaultValue.replace(/'/g, \"''\");\n return ` DEFAULT '${escaped}'`;\n }\n if (typeof col.defaultValue === \"boolean\") {\n return ` DEFAULT ${col.defaultValue ? \"true\" : \"false\"}`;\n }\n if (typeof col.defaultValue === \"object\" && col.defaultValue !== null) {\n const escaped = JSON.stringify(col.defaultValue).replace(/'/g, \"''\");\n return ` DEFAULT '${escaped}'::jsonb`;\n }\n return ` DEFAULT ${col.defaultValue}`;\n }\n return \"\";\n}\n\n/** Maps OnDeleteAction to SQL. */\nfunction onDeleteSQL(action: OnDeleteAction): string {\n switch (action) {\n case \"cascade\":\n return \"CASCADE\";\n case \"set null\":\n return \"SET NULL\";\n case \"restrict\":\n return \"RESTRICT\";\n case \"no action\":\n return \"NO ACTION\";\n }\n}\n\n/** Generates CREATE TYPE statements for enum columns. */\nfunction generateEnumTypes(tables: Record<string, TableDef>): string[] {\n const enums = new Map<string, string[]>();\n for (const tableDef of Object.values(tables)) {\n for (const col of Object.values(tableDef.columns)) {\n if (col._def.type === \"enum\" && col._def.enumName && col._def.enumValues) {\n enums.set(col._def.enumName, col._def.enumValues);\n }\n }\n }\n\n return Array.from(enums.entries()).map(([name, values]) => {\n const vals = values.map((v) => `'${v.replace(/'/g, \"''\")}'`).join(\", \");\n return `CREATE TYPE ${name} AS ENUM (${vals});`;\n });\n}\n\n/** Generates a CREATE TABLE statement for a single table. */\nfunction generateCreateTable(tableDef: TableDef): string {\n const lines: string[] = [];\n\n for (const [colName, colBuilder] of Object.entries(tableDef.columns)) {\n const col = colBuilder._def;\n let line = ` ${colName} ${columnTypeToSQL(col)}`;\n\n if (col.primaryKey) {\n line += \" PRIMARY KEY\";\n }\n\n if (!col.nullable && !col.primaryKey) {\n line += \" NOT NULL\";\n }\n\n line += defaultClause(col);\n\n if (col.references) {\n line += ` REFERENCES ${col.references.table}(${col.references.column})`;\n if (col.onDeleteAction) {\n line += ` ON DELETE ${onDeleteSQL(col.onDeleteAction)}`;\n }\n }\n\n lines.push(line);\n }\n\n return `CREATE TABLE ${tableDef.name} (\\n${lines.join(\",\\n\")}\\n);`;\n}\n\n/** Generates a DROP TABLE statement (for down migration). */\nfunction generateDropTable(tableDef: TableDef): string {\n return `DROP TABLE IF EXISTS ${tableDef.name};`;\n}\n\n/** Generates DROP TYPE statements for enum columns (for down migration). */\nfunction generateDropEnumTypes(tables: Record<string, TableDef>): string[] {\n const enums = new Set<string>();\n for (const tableDef of Object.values(tables)) {\n for (const col of Object.values(tableDef.columns)) {\n if (col._def.type === \"enum\" && col._def.enumName) {\n enums.add(col._def.enumName);\n }\n }\n }\n return Array.from(enums).map((name) => `DROP TYPE IF EXISTS ${name};`);\n}\n\n/** Result of migration generation. */\nexport interface MigrationResult {\n up: string;\n down: string;\n}\n\n/**\n * Generates a full migration (up + down) from a schema definition.\n * Used for initial schema creation.\n */\nexport function generateMigration(schema: SchemaDef): MigrationResult {\n const upParts: string[] = [];\n const downParts: string[] = [];\n\n // Enum types first (up) / last (down)\n const enumTypes = generateEnumTypes(schema.tables);\n upParts.push(...enumTypes);\n\n // Tables\n for (const tableDef of Object.values(schema.tables)) {\n upParts.push(generateCreateTable(tableDef));\n }\n\n // Down: reverse order — drop tables first, then types\n const tableNames = Object.values(schema.tables);\n for (let i = tableNames.length - 1; i >= 0; i--) {\n downParts.push(generateDropTable(tableNames[i]!));\n }\n downParts.push(...generateDropEnumTypes(schema.tables));\n\n return {\n up: upParts.join(\"\\n\\n\"),\n down: downParts.join(\"\\n\\n\"),\n };\n}\n\n/** Column diff operation. */\ninterface ColumnDiff {\n type: \"add\" | \"drop\" | \"alter\";\n table: string;\n column: string;\n def?: ColumnDef;\n oldDef?: ColumnDef;\n}\n\n/** Computes column-level diffs between two schemas. */\nfunction diffSchemas(\n oldSchema: SchemaDef,\n newSchema: SchemaDef,\n): { addedTables: TableDef[]; droppedTables: TableDef[]; columnDiffs: ColumnDiff[] } {\n const addedTables: TableDef[] = [];\n const droppedTables: TableDef[] = [];\n const columnDiffs: ColumnDiff[] = [];\n\n const oldTableNames = new Set(Object.keys(oldSchema.tables));\n const newTableNames = new Set(Object.keys(newSchema.tables));\n\n // New tables\n for (const name of newTableNames) {\n if (!oldTableNames.has(name)) {\n addedTables.push(newSchema.tables[name]!);\n }\n }\n\n // Dropped tables\n for (const name of oldTableNames) {\n if (!newTableNames.has(name)) {\n droppedTables.push(oldSchema.tables[name]!);\n }\n }\n\n // Column-level diffs for existing tables\n for (const name of newTableNames) {\n if (!oldTableNames.has(name)) continue;\n\n const oldTable = oldSchema.tables[name]!;\n const newTable = newSchema.tables[name]!;\n const oldCols = new Set(Object.keys(oldTable.columns));\n const newCols = new Set(Object.keys(newTable.columns));\n\n for (const col of newCols) {\n if (!oldCols.has(col)) {\n columnDiffs.push({\n type: \"add\",\n table: newTable.name,\n column: col,\n def: newTable.columns[col]!._def,\n });\n }\n }\n\n for (const col of oldCols) {\n if (!newCols.has(col)) {\n columnDiffs.push({\n type: \"drop\",\n table: oldTable.name,\n column: col,\n oldDef: oldTable.columns[col]!._def,\n });\n }\n }\n }\n\n return { addedTables, droppedTables, columnDiffs };\n}\n\n/** Generates an ALTER TABLE ADD COLUMN statement. */\nfunction generateAddColumn(table: string, column: string, col: ColumnDef): string {\n let sql = `ALTER TABLE ${table} ADD COLUMN ${column} ${columnTypeToSQL(col)}`;\n if (!col.nullable) {\n sql += \" NOT NULL\";\n }\n sql += defaultClause(col);\n if (col.references) {\n sql += ` REFERENCES ${col.references.table}(${col.references.column})`;\n if (col.onDeleteAction) {\n sql += ` ON DELETE ${onDeleteSQL(col.onDeleteAction)}`;\n }\n }\n return `${sql};`;\n}\n\n/** Generates an ALTER TABLE DROP COLUMN statement. */\nfunction generateDropColumn(table: string, column: string): string {\n return `ALTER TABLE ${table} DROP COLUMN ${column};`;\n}\n\n/**\n * Generates a diff migration between two schemas.\n * Returns null if there are no changes.\n */\nexport function generateDiffMigration(\n oldSchema: SchemaDef,\n newSchema: SchemaDef,\n): MigrationResult | null {\n const { addedTables, droppedTables, columnDiffs } = diffSchemas(oldSchema, newSchema);\n\n if (addedTables.length === 0 && droppedTables.length === 0 && columnDiffs.length === 0) {\n return null;\n }\n\n const upParts: string[] = [];\n const downParts: string[] = [];\n\n // New enum types from added tables\n const newEnums = generateEnumTypes(\n Object.fromEntries(addedTables.map((t) => [t.name, t])),\n );\n upParts.push(...newEnums);\n\n // New tables\n for (const table of addedTables) {\n upParts.push(generateCreateTable(table));\n downParts.push(generateDropTable(table));\n }\n\n // Dropped tables\n for (const table of droppedTables) {\n upParts.push(generateDropTable(table));\n downParts.push(generateCreateTable(table));\n }\n\n // Column diffs\n for (const diff of columnDiffs) {\n if (diff.type === \"add\" && diff.def) {\n upParts.push(generateAddColumn(diff.table, diff.column, diff.def));\n downParts.push(generateDropColumn(diff.table, diff.column));\n } else if (diff.type === \"drop\") {\n upParts.push(generateDropColumn(diff.table, diff.column));\n if (diff.oldDef) {\n downParts.push(generateAddColumn(diff.table, diff.column, diff.oldDef));\n }\n }\n }\n\n // Drop enum types from dropped tables (down)\n const droppedEnums = generateDropEnumTypes(\n Object.fromEntries(droppedTables.map((t) => [t.name, t])),\n );\n downParts.push(...droppedEnums);\n\n return {\n up: upParts.join(\"\\n\\n\"),\n down: downParts.join(\"\\n\\n\"),\n };\n}\n"],"mappings":"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","names":["table","table"]}
1
+ {"version":3,"sources":["../../src/db/generator.ts"],"sourcesContent":["import type { ColumnDef, OnDeleteAction } from \"./columns.js\";\nimport type { SchemaDef, TableDef } from \"./schema.js\";\n\n/** Maps column types to their PostgreSQL SQL equivalents. */\nfunction columnTypeToSQL(col: ColumnDef): string {\n switch (col.type) {\n case \"uuid\":\n return \"UUID\";\n case \"text\":\n return \"TEXT\";\n case \"integer\":\n return \"INTEGER\";\n case \"boolean\":\n return \"BOOLEAN\";\n case \"timestamp\":\n return \"TIMESTAMPTZ\";\n case \"jsonb\":\n return \"JSONB\";\n case \"enum\":\n return col.enumName ?? \"TEXT\";\n default:\n return \"TEXT\";\n }\n}\n\n/** Generates the DEFAULT clause for a column. */\nfunction defaultClause(col: ColumnDef): string {\n if (col.defaultRandom) {\n return \" DEFAULT gen_random_uuid()\";\n }\n if (col.defaultNow) {\n return \" DEFAULT now()\";\n }\n if (col.defaultValue !== undefined) {\n if (typeof col.defaultValue === \"string\") {\n // Escape single quotes in string defaults\n const escaped = col.defaultValue.replace(/'/g, \"''\");\n return ` DEFAULT '${escaped}'`;\n }\n if (typeof col.defaultValue === \"boolean\") {\n return ` DEFAULT ${col.defaultValue ? \"true\" : \"false\"}`;\n }\n if (typeof col.defaultValue === \"object\" && col.defaultValue !== null) {\n const escaped = JSON.stringify(col.defaultValue).replace(/'/g, \"''\");\n return ` DEFAULT '${escaped}'::jsonb`;\n }\n return ` DEFAULT ${col.defaultValue}`;\n }\n return \"\";\n}\n\n/** Maps OnDeleteAction to SQL. */\nfunction onDeleteSQL(action: OnDeleteAction): string {\n switch (action) {\n case \"cascade\":\n return \"CASCADE\";\n case \"set null\":\n return \"SET NULL\";\n case \"restrict\":\n return \"RESTRICT\";\n case \"no action\":\n return \"NO ACTION\";\n }\n}\n\n/** Generates CREATE TYPE statements for enum columns. */\nfunction generateEnumTypes(tables: Record<string, TableDef>): string[] {\n const enums = new Map<string, string[]>();\n for (const tableDef of Object.values(tables)) {\n for (const col of Object.values(tableDef.columns)) {\n if (col._def.type === \"enum\" && col._def.enumName && col._def.enumValues) {\n enums.set(col._def.enumName, col._def.enumValues);\n }\n }\n }\n\n return Array.from(enums.entries()).map(([name, values]) => {\n const vals = values.map((v) => `'${v.replace(/'/g, \"''\")}'`).join(\", \");\n return `CREATE TYPE ${name} AS ENUM (${vals});`;\n });\n}\n\n/** Generates a CREATE TABLE statement for a single table. */\nfunction generateCreateTable(tableDef: TableDef): string {\n const lines: string[] = [];\n\n for (const [colName, colBuilder] of Object.entries(tableDef.columns)) {\n const col = colBuilder._def;\n let line = ` ${colName} ${columnTypeToSQL(col)}`;\n\n if (col.primaryKey) {\n line += \" PRIMARY KEY\";\n }\n\n if (!col.nullable && !col.primaryKey) {\n line += \" NOT NULL\";\n }\n\n line += defaultClause(col);\n\n if (col.references) {\n line += ` REFERENCES ${col.references.table}(${col.references.column})`;\n if (col.onDeleteAction) {\n line += ` ON DELETE ${onDeleteSQL(col.onDeleteAction)}`;\n }\n }\n\n lines.push(line);\n }\n\n return `CREATE TABLE ${tableDef.name} (\\n${lines.join(\",\\n\")}\\n);`;\n}\n\n/** Generates a DROP TABLE statement (for down migration). */\nfunction generateDropTable(tableDef: TableDef): string {\n return `DROP TABLE IF EXISTS ${tableDef.name};`;\n}\n\n/** Generates DROP TYPE statements for enum columns (for down migration). */\nfunction generateDropEnumTypes(tables: Record<string, TableDef>): string[] {\n const enums = new Set<string>();\n for (const tableDef of Object.values(tables)) {\n for (const col of Object.values(tableDef.columns)) {\n if (col._def.type === \"enum\" && col._def.enumName) {\n enums.add(col._def.enumName);\n }\n }\n }\n return Array.from(enums).map((name) => `DROP TYPE IF EXISTS ${name};`);\n}\n\n/** Result of migration generation. */\nexport interface MigrationResult {\n up: string;\n down: string;\n}\n\n/**\n * Generates a full migration (up + down) from a schema definition.\n * Used for initial schema creation.\n */\nexport function generateMigration(schema: SchemaDef): MigrationResult {\n const upParts: string[] = [];\n const downParts: string[] = [];\n\n // Enum types first (up) / last (down)\n const enumTypes = generateEnumTypes(schema.tables);\n upParts.push(...enumTypes);\n\n // Tables\n for (const tableDef of Object.values(schema.tables)) {\n upParts.push(generateCreateTable(tableDef));\n }\n\n // Down: reverse order — drop tables first, then types\n const tableNames = Object.values(schema.tables);\n for (let i = tableNames.length - 1; i >= 0; i--) {\n downParts.push(generateDropTable(tableNames[i]!));\n }\n downParts.push(...generateDropEnumTypes(schema.tables));\n\n return {\n up: upParts.join(\"\\n\\n\"),\n down: downParts.join(\"\\n\\n\"),\n };\n}\n\n/** Column diff operation. */\ninterface ColumnDiff {\n type: \"add\" | \"drop\" | \"alter\";\n table: string;\n column: string;\n def?: ColumnDef;\n oldDef?: ColumnDef;\n}\n\n/** Computes column-level diffs between two schemas. */\nfunction diffSchemas(\n oldSchema: SchemaDef,\n newSchema: SchemaDef,\n): { addedTables: TableDef[]; droppedTables: TableDef[]; columnDiffs: ColumnDiff[] } {\n const addedTables: TableDef[] = [];\n const droppedTables: TableDef[] = [];\n const columnDiffs: ColumnDiff[] = [];\n\n const oldTableNames = new Set(Object.keys(oldSchema.tables));\n const newTableNames = new Set(Object.keys(newSchema.tables));\n\n // New tables\n for (const name of newTableNames) {\n if (!oldTableNames.has(name)) {\n addedTables.push(newSchema.tables[name]!);\n }\n }\n\n // Dropped tables\n for (const name of oldTableNames) {\n if (!newTableNames.has(name)) {\n droppedTables.push(oldSchema.tables[name]!);\n }\n }\n\n // Column-level diffs for existing tables\n for (const name of newTableNames) {\n if (!oldTableNames.has(name)) continue;\n\n const oldTable = oldSchema.tables[name]!;\n const newTable = newSchema.tables[name]!;\n const oldCols = new Set(Object.keys(oldTable.columns));\n const newCols = new Set(Object.keys(newTable.columns));\n\n for (const col of newCols) {\n if (!oldCols.has(col)) {\n columnDiffs.push({\n type: \"add\",\n table: newTable.name,\n column: col,\n def: newTable.columns[col]!._def,\n });\n }\n }\n\n for (const col of oldCols) {\n if (!newCols.has(col)) {\n columnDiffs.push({\n type: \"drop\",\n table: oldTable.name,\n column: col,\n oldDef: oldTable.columns[col]!._def,\n });\n }\n }\n }\n\n return { addedTables, droppedTables, columnDiffs };\n}\n\n/** Generates an ALTER TABLE ADD COLUMN statement. */\nfunction generateAddColumn(table: string, column: string, col: ColumnDef): string {\n let sql = `ALTER TABLE ${table} ADD COLUMN ${column} ${columnTypeToSQL(col)}`;\n if (!col.nullable) {\n sql += \" NOT NULL\";\n }\n sql += defaultClause(col);\n if (col.references) {\n sql += ` REFERENCES ${col.references.table}(${col.references.column})`;\n if (col.onDeleteAction) {\n sql += ` ON DELETE ${onDeleteSQL(col.onDeleteAction)}`;\n }\n }\n return `${sql};`;\n}\n\n/** Generates an ALTER TABLE DROP COLUMN statement. */\nfunction generateDropColumn(table: string, column: string): string {\n return `ALTER TABLE ${table} DROP COLUMN ${column};`;\n}\n\n/**\n * Generates a diff migration between two schemas.\n * Returns null if there are no changes.\n */\nexport function generateDiffMigration(\n oldSchema: SchemaDef,\n newSchema: SchemaDef,\n): MigrationResult | null {\n const { addedTables, droppedTables, columnDiffs } = diffSchemas(oldSchema, newSchema);\n\n if (addedTables.length === 0 && droppedTables.length === 0 && columnDiffs.length === 0) {\n return null;\n }\n\n const upParts: string[] = [];\n const downParts: string[] = [];\n\n // New enum types from added tables\n const newEnums = generateEnumTypes(\n Object.fromEntries(addedTables.map((t) => [t.name, t])),\n );\n upParts.push(...newEnums);\n\n // New tables\n for (const table of addedTables) {\n upParts.push(generateCreateTable(table));\n downParts.push(generateDropTable(table));\n }\n\n // Dropped tables\n for (const table of droppedTables) {\n upParts.push(generateDropTable(table));\n downParts.push(generateCreateTable(table));\n }\n\n // Column diffs\n for (const diff of columnDiffs) {\n if (diff.type === \"add\" && diff.def) {\n upParts.push(generateAddColumn(diff.table, diff.column, diff.def));\n downParts.push(generateDropColumn(diff.table, diff.column));\n } else if (diff.type === \"drop\") {\n upParts.push(generateDropColumn(diff.table, diff.column));\n if (diff.oldDef) {\n downParts.push(generateAddColumn(diff.table, diff.column, diff.oldDef));\n }\n }\n }\n\n // Drop enum types from dropped tables (down)\n const droppedEnums = generateDropEnumTypes(\n Object.fromEntries(droppedTables.map((t) => [t.name, t])),\n );\n downParts.push(...droppedEnums);\n\n return {\n up: upParts.join(\"\\n\\n\"),\n down: downParts.join(\"\\n\\n\"),\n };\n}\n"],"mappings":"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","names":["table"]}