{"version":3,"file":"index.mjs","names":[],"sources":["../src/typeorm-adapter.ts"],"sourcesContent":["import { BetterAuthError } from \"better-auth\";\nimport { type CleanedWhere, createAdapterFactory } from \"better-auth/adapters\";\nimport type { Where } from \"better-auth/types\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport {\n  DataSource,\n  type DeleteResult,\n  type FindOptionsWhere,\n  In,\n  LessThan,\n  LessThanOrEqual,\n  Like,\n  MoreThan,\n  MoreThanOrEqual,\n  Not,\n  type ObjectLiteral,\n  type QueryResult,\n  type Repository,\n  type UpdateResult,\n} from \"typeorm\";\n\nfunction tryGetRepository(\n  dataSource: DataSource,\n  tableName: string,\n  requiredFields?: string[],\n): Repository<ObjectLiteral> | null {\n  try {\n    const metadata = dataSource.entityMetadatas.find(\n      (meta) =>\n        meta.tableName === tableName || meta.name === tableName || meta.targetName === tableName,\n    );\n    if (!metadata) {\n      return null;\n    }\n    if (requiredFields) {\n      for (const field of requiredFields) {\n        const hasColumn = metadata.columns.some(\n          (col) => col.propertyName === field || col.databaseName === field,\n        );\n        if (!hasColumn) {\n          return null;\n        }\n      }\n    }\n    return dataSource.getRepository(tableName);\n  } catch {\n    return null;\n  }\n}\n\nfunction escapeId(dataSource: DataSource, name: string): string {\n  return dataSource.driver.escape(name);\n}\n\nfunction createParameterToken(dataSource: DataSource, index: number): string {\n  return dataSource.driver.createParameter(`orm_param_${index}`, index);\n}\n\nfunction pushParameter(\n  dataSource: DataSource,\n  params: unknown[],\n  value: unknown,\n  startIndex = 0,\n): string {\n  params.push(value);\n  return createParameterToken(dataSource, startIndex + params.length - 1);\n}\n\nfunction normalizeQueryValue(value: unknown, dataSource: DataSource): unknown {\n  if (value instanceof Date) {\n    if (dataSource.options.type === \"mysql\" || dataSource.options.type === \"mariadb\") {\n      return value;\n    }\n    return value.toISOString();\n  }\n  if (typeof value === \"object\" && value !== null) {\n    return JSON.stringify(value);\n  }\n  return value;\n}\n\nasync function ensureTableExists(\n  dataSource: DataSource,\n  tableName: string,\n  data: Record<string, unknown>,\n): Promise<void> {\n  const queryRunner = dataSource.createQueryRunner();\n  await queryRunner.connect();\n  try {\n    const tableExists = await queryRunner.hasTable(tableName);\n    if (!tableExists) {\n      const columns = Object.entries(data)\n        .map(([key, value]) => {\n          const escaped = escapeId(dataSource, key);\n          if (key === \"id\") {\n            return `${escaped} text PRIMARY KEY`;\n          }\n          const type =\n            typeof value === \"boolean\"\n              ? \"boolean\"\n              : typeof value === \"number\"\n                ? \"integer\"\n                : value instanceof Date\n                  ? getDateColumnType(dataSource)\n                  : \"text\";\n          return `${escaped} ${type}`;\n        })\n        .join(\", \");\n      await queryRunner.query(\n        `CREATE TABLE IF NOT EXISTS ${escapeId(dataSource, tableName)} (${columns})`,\n      );\n    } else {\n      const table = await queryRunner.getTable(tableName);\n      if (table) {\n        const existingColumns = new Set(table.columns.map((col) => col.name));\n        for (const [key, value] of Object.entries(data)) {\n          if (!existingColumns.has(key)) {\n            const type =\n              typeof value === \"boolean\"\n                ? \"boolean\"\n                : typeof value === \"number\"\n                  ? \"integer\"\n                  : value instanceof Date\n                    ? getDateColumnType(dataSource)\n                    : \"text\";\n            await queryRunner.query(\n              `ALTER TABLE ${escapeId(dataSource, tableName)} ADD COLUMN ${escapeId(dataSource, key)} ${type}`,\n            );\n          }\n        }\n      }\n    }\n  } finally {\n    await queryRunner.release();\n  }\n}\n\ntype FieldAttribute = {\n  type: string | string[];\n  required?: boolean;\n  unique?: boolean;\n  index?: boolean;\n  bigint?: boolean;\n  fieldName?: string;\n  defaultValue?: unknown | (() => unknown);\n  onUpdate?: () => unknown;\n  references?: {\n    model: string;\n    field: string;\n    onDelete?: \"no action\" | \"restrict\" | \"cascade\" | \"set null\" | \"set default\";\n  };\n};\n\nfunction toPascalCase(value: string): string {\n  return value\n    .split(/[^a-zA-Z0-9]+/)\n    .filter(Boolean)\n    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n    .join(\"\");\n}\n\nfunction toRelationPropertyName(fieldName: string): string {\n  if (fieldName.endsWith(\"Id\") && fieldName.length > 2) {\n    return fieldName.slice(0, -2);\n  }\n  return `${fieldName}Relation`;\n}\n\nfunction getDateColumnType(dataSource: DataSource): string {\n  switch (dataSource.options.type) {\n    case \"postgres\":\n    case \"cockroachdb\":\n      return \"timestamptz\";\n    case \"mssql\":\n      return \"datetime2\";\n    case \"mysql\":\n    case \"mariadb\":\n    case \"better-sqlite3\":\n    case \"sqljs\":\n    case \"capacitor\":\n    case \"cordova\":\n    case \"expo\":\n    case \"react-native\":\n      return \"datetime\";\n    default:\n      return \"timestamp\";\n  }\n}\n\nfunction mapFieldTypeToTypeORM(\n  fieldType: string | string[],\n  field: FieldAttribute,\n  dataSource: DataSource,\n): { type: string; length?: string } {\n  const typeStr = Array.isArray(fieldType) ? fieldType[0] || \"string\" : fieldType;\n\n  switch (typeStr) {\n    case \"string\":\n      return { type: \"text\" };\n    case \"number\":\n      return { type: field.bigint ? \"bigint\" : \"integer\" };\n    case \"boolean\":\n      return { type: \"boolean\" };\n    case \"date\":\n      return { type: getDateColumnType(dataSource) };\n    default:\n      return { type: \"text\" };\n  }\n}\n\nfunction formatDefaultValueForEntity(field: FieldAttribute): string | null {\n  if (field.defaultValue === undefined) {\n    return null;\n  }\n\n  if (typeof field.defaultValue === \"function\") {\n    if ((Array.isArray(field.type) ? field.type[0] : field.type) === \"date\") {\n      return \"default: () => 'CURRENT_TIMESTAMP'\";\n    }\n    return null;\n  }\n\n  if (typeof field.defaultValue === \"string\") {\n    return `default: ${JSON.stringify(field.defaultValue)}`;\n  }\n\n  if (typeof field.defaultValue === \"number\" || typeof field.defaultValue === \"boolean\") {\n    return `default: ${String(field.defaultValue)}`;\n  }\n\n  return null;\n}\n\nfunction formatDefaultValueForMigration(field: FieldAttribute): string | null {\n  if (field.defaultValue === undefined) {\n    return null;\n  }\n\n  if (typeof field.defaultValue === \"function\") {\n    if ((Array.isArray(field.type) ? field.type[0] : field.type) === \"date\") {\n      return JSON.stringify(\"CURRENT_TIMESTAMP\");\n    }\n    return null;\n  }\n\n  if (typeof field.defaultValue === \"string\") {\n    return JSON.stringify(`'${field.defaultValue}'`);\n  }\n\n  if (typeof field.defaultValue === \"number\" || typeof field.defaultValue === \"boolean\") {\n    return JSON.stringify(field.defaultValue);\n  }\n\n  return null;\n}\n\nfunction convertOperatorToTypeORM(operator: Where[\"operator\"], value: unknown) {\n  switch (operator) {\n    case \"ne\":\n      return Not(value);\n    case \"lt\":\n      return LessThan(value);\n    case \"lte\":\n      return LessThanOrEqual(value);\n    case \"gt\":\n      return MoreThan(value);\n    case \"gte\":\n      return MoreThanOrEqual(value);\n    case \"in\":\n      return In(value as unknown[]);\n    case \"not_in\":\n      return Not(In(value as unknown[]));\n    case \"contains\":\n      return Like(`%${value}%`);\n    case \"starts_with\":\n      return Like(`${value}%`);\n    case \"ends_with\":\n      return Like(`%${value}`);\n    default:\n      return value;\n  }\n}\n\nfunction generateEntity(\n  dataSource: DataSource,\n  modelName: string,\n  modelSchema: {\n    modelName: string;\n    fields: Record<string, FieldAttribute>;\n    disableMigrations?: boolean;\n    order?: number;\n  },\n): string {\n  const className = toPascalCase(modelName);\n  const tableName = modelSchema.modelName;\n  const referencedModels = new Set<string>();\n  const typeormImports = new Set([\"Column\", \"Entity\", \"Index\", \"PrimaryColumn\"]);\n\n  for (const field of Object.values(modelSchema.fields)) {\n    if (field.references) {\n      referencedModels.add(field.references.model);\n      typeormImports.add(\"JoinColumn\");\n      typeormImports.add(\"ManyToOne\");\n    }\n  }\n\n  const imports = [`import { ${Array.from(typeormImports).sort().join(\", \")} } from 'typeorm';`];\n  for (const referencedModel of Array.from(referencedModels).sort()) {\n    imports.push(\n      `import { ${toPascalCase(referencedModel)} } from './${toPascalCase(referencedModel)}';`,\n    );\n  }\n  imports.push(\"\");\n  let entityCode = `@Entity('${tableName}')\\nexport class ${className} {\\n`;\n\n  entityCode += \"  @PrimaryColumn('text')\\n\";\n  entityCode += \"  id!: string;\\n\\n\";\n\n  for (const [fieldName, field] of Object.entries(modelSchema.fields)) {\n    const fieldAttr = field as FieldAttribute;\n    const dbField = fieldAttr.fieldName || fieldName;\n    const typeInfo = mapFieldTypeToTypeORM(fieldAttr.type, fieldAttr, dataSource);\n\n    const columnOptions: string[] = [];\n\n    columnOptions.push(`name: '${dbField}'`);\n\n    if (!fieldAttr.required) {\n      columnOptions.push(\"nullable: true\");\n    }\n\n    if (fieldAttr.unique || dbField === \"email\" || dbField === \"token\") {\n      columnOptions.push(\"unique: true\");\n    }\n\n    const defaultValue = formatDefaultValueForEntity(fieldAttr);\n    if (defaultValue) {\n      columnOptions.push(defaultValue);\n    }\n\n    const columnOptionsStr = columnOptions.length > 0 ? `, { ${columnOptions.join(\", \")} }` : \"\";\n\n    if (fieldAttr.index) {\n      entityCode += `  @Index('${tableName}_${dbField}_idx')\\n`;\n    }\n\n    entityCode += `  @Column('${typeInfo.type}'${columnOptionsStr})\\n`;\n    const tsType =\n      fieldAttr.type === \"date\"\n        ? \"Date\"\n        : fieldAttr.type === \"boolean\"\n          ? \"boolean\"\n          : fieldAttr.type === \"number\"\n            ? \"number\"\n            : \"string\";\n    const nullableModifier = fieldAttr.required ? \"!\" : \"\";\n    const nullableType = fieldAttr.required ? \"\" : \" | null\";\n    entityCode += `  ${fieldName}${nullableModifier}: ${tsType}${nullableType};\\n\\n`;\n\n    if (fieldAttr.references) {\n      const relationClass = toPascalCase(fieldAttr.references.model);\n      const relationPropertyName = toRelationPropertyName(fieldName);\n      entityCode += `  @ManyToOne(() => ${relationClass}, { onDelete: '${(fieldAttr.references.onDelete || \"cascade\").toUpperCase()}', nullable: ${fieldAttr.required ? \"false\" : \"true\"} })\\n`;\n      entityCode += `  @JoinColumn({ name: '${dbField}', referencedColumnName: '${fieldAttr.references.field}' })\\n`;\n      entityCode += `  ${relationPropertyName}${fieldAttr.required ? \"!\" : \"?\"}: ${relationClass};\\n\\n`;\n    }\n  }\n\n  entityCode += \"}\";\n\n  return `${imports.join(\"\\n\")}\\n${entityCode}`;\n}\n\nfunction generateMigration(\n  dataSource: DataSource,\n  modelName: string,\n  modelSchema: {\n    modelName: string;\n    fields: Record<string, FieldAttribute>;\n    disableMigrations?: boolean;\n    order?: number;\n  },\n  timestamp: number,\n  action: \"create\" | \"alter\",\n  changes?: {\n    addColumns?: { name: string; field: FieldAttribute }[];\n    dropColumns?: string[];\n    modifyColumns?: { name: string; field: FieldAttribute }[];\n  },\n): string {\n  const className = `${action.charAt(0).toUpperCase() + action.slice(1)}${toPascalCase(modelName)}${timestamp}`;\n  const tableName = modelSchema.modelName;\n\n  let migrationCode =\n    \"import { type MigrationInterface, type QueryRunner, Table, TableColumn, TableForeignKey, TableIndex } from 'typeorm';\\n\\n\";\n  migrationCode += `export class ${className} implements MigrationInterface {\\n`;\n  migrationCode += \"  public async up(queryRunner: QueryRunner): Promise<void> {\\n\";\n\n  if (action === \"create\") {\n    migrationCode += \"    await queryRunner.createTable(\\n\";\n    migrationCode += \"      new Table({\\n\";\n    migrationCode += `        name: '${tableName}',\\n`;\n    migrationCode += \"        columns: [\\n\";\n\n    const columns: string[] = [];\n    const postCreateStatements: string[] = [];\n\n    columns.push(`          {\n            name: 'id',\n            type: 'text',\n            isPrimary: true,\n          }`);\n\n    for (const [fieldName, field] of Object.entries(modelSchema.fields)) {\n      const fieldAttr = field as FieldAttribute;\n      const dbField = fieldAttr.fieldName || fieldName;\n      const typeInfo = mapFieldTypeToTypeORM(fieldAttr.type, fieldAttr, dataSource);\n\n      if (fieldName === \"id\" || dbField === \"id\") {\n        continue;\n      }\n\n      let columnDef = \"          {\\n\";\n      columnDef += `            name: '${dbField}',\\n`;\n      columnDef += `            type: '${typeInfo.type}',\\n`;\n\n      if (typeInfo.length) {\n        columnDef += `            length: '${typeInfo.length}',\\n`;\n      }\n\n      if (!fieldAttr.required) {\n        columnDef += \"            isNullable: true,\\n\";\n      }\n\n      if (fieldAttr.unique || dbField === \"email\" || dbField === \"token\") {\n        columnDef += \"            isUnique: true,\\n\";\n      }\n\n      const defaultValue = formatDefaultValueForMigration(fieldAttr);\n      if (defaultValue) {\n        columnDef += `            default: ${defaultValue},\\n`;\n      }\n\n      columnDef += \"          }\";\n      columns.push(columnDef);\n\n      if (fieldAttr.index) {\n        postCreateStatements.push(`    await queryRunner.createIndex(\n      '${tableName}',\n      new TableIndex({\n        name: '${tableName}_${dbField}_idx',\n        columnNames: ['${dbField}'],\n      }),\n    );`);\n      }\n\n      if (fieldAttr.references) {\n        postCreateStatements.push(`    await queryRunner.createForeignKey(\n      '${tableName}',\n      new TableForeignKey({\n        columnNames: ['${dbField}'],\n        referencedTableName: '${fieldAttr.references.model}',\n        referencedColumnNames: ['${fieldAttr.references.field}'],\n        onDelete: '${(fieldAttr.references.onDelete || \"cascade\").toUpperCase()}',\n      }),\n    );`);\n      }\n    }\n\n    migrationCode += `${columns.join(\",\\n\")}\\n`;\n    migrationCode += \"        ],\\n\";\n    migrationCode += \"      }),\\n\";\n    migrationCode += \"    );\\n\\n\";\n\n    if (postCreateStatements.length > 0) {\n      migrationCode += `${postCreateStatements.join(\"\\n\\n\")}\\n`;\n    }\n  } else if (action === \"alter\" && changes) {\n    if (changes.addColumns && changes.addColumns.length > 0) {\n      for (const { name, field } of changes.addColumns) {\n        const typeInfo = mapFieldTypeToTypeORM(field.type, field, dataSource);\n        migrationCode += `    await queryRunner.addColumn('${tableName}', new TableColumn({\\n`;\n        migrationCode += `      name: '${field.fieldName || name}',\\n`;\n        migrationCode += `      type: '${typeInfo.type}',\\n`;\n        migrationCode += `      isNullable: ${!field.required},\\n`;\n        if (\n          field.unique ||\n          (field.fieldName || name) === \"email\" ||\n          (field.fieldName || name) === \"token\"\n        ) {\n          migrationCode += \"      isUnique: true,\\n\";\n        }\n        const defaultValue = formatDefaultValueForMigration(field);\n        if (defaultValue) {\n          migrationCode += `      default: ${defaultValue},\\n`;\n        }\n        migrationCode += \"    }));\\n\\n\";\n        if (field.index) {\n          const dbField = field.fieldName || name;\n          migrationCode += `    await queryRunner.createIndex('${tableName}', new TableIndex({ name: '${tableName}_${dbField}_idx', columnNames: ['${dbField}'] }));\\n\\n`;\n        }\n        if (field.references) {\n          const dbField = field.fieldName || name;\n          migrationCode += `    await queryRunner.createForeignKey('${tableName}', new TableForeignKey({ columnNames: ['${dbField}'], referencedTableName: '${field.references.model}', referencedColumnNames: ['${field.references.field}'], onDelete: '${(field.references.onDelete || \"cascade\").toUpperCase()}' }));\\n\\n`;\n        }\n      }\n    }\n\n    if (changes.dropColumns && changes.dropColumns.length > 0) {\n      for (const columnName of changes.dropColumns) {\n        migrationCode += `    await queryRunner.dropColumn('${tableName}', '${columnName}');\\n\\n`;\n      }\n    }\n\n    if (changes.modifyColumns && changes.modifyColumns.length > 0) {\n      for (const { name, field } of changes.modifyColumns) {\n        const typeInfo = mapFieldTypeToTypeORM(field.type, field, dataSource);\n        migrationCode += `    await queryRunner.changeColumn('${tableName}', '${name}', new TableColumn({\\n`;\n        migrationCode += `      name: '${field.fieldName || name}',\\n`;\n        migrationCode += `      type: '${typeInfo.type}',\\n`;\n        migrationCode += `      isNullable: ${!field.required},\\n`;\n        if (\n          field.unique ||\n          (field.fieldName || name) === \"email\" ||\n          (field.fieldName || name) === \"token\"\n        ) {\n          migrationCode += \"      isUnique: true,\\n\";\n        }\n        const defaultValue = formatDefaultValueForMigration(field);\n        if (defaultValue) {\n          migrationCode += `      default: ${defaultValue},\\n`;\n        }\n        migrationCode += \"    }));\\n\\n\";\n      }\n    }\n  }\n\n  migrationCode += \"  }\\n\\n\";\n  migrationCode += \"  public async down(queryRunner: QueryRunner): Promise<void> {\\n\";\n\n  if (action === \"create\") {\n    migrationCode += `    await queryRunner.dropTable('${tableName}');\\n`;\n  } else if (action === \"alter\" && changes) {\n    if (changes.addColumns && changes.addColumns.length > 0) {\n      for (const { name, field } of changes.addColumns) {\n        migrationCode += `    await queryRunner.dropColumn('${tableName}', '${field.fieldName || name}');\\n`;\n      }\n    }\n    if (changes.dropColumns && changes.dropColumns.length > 0) {\n      for (const columnName of changes.dropColumns) {\n        migrationCode += `    await queryRunner.addColumn('${tableName}', new TableColumn({ name: '${columnName}', type: 'text', isNullable: true }));\\n`;\n      }\n    }\n  }\n\n  migrationCode += \"  }\\n\";\n  migrationCode += \"}\";\n\n  return migrationCode;\n}\n\nexport interface TypeormAdapterOptions {\n  outputDir?: string;\n  migrationsDir?: string;\n  entitiesDir?: string;\n  usePlural?: boolean;\n  debugLogs?: boolean;\n  softDeleteEnabledEntities?: string[];\n  enableSchemaSync?: boolean;\n}\n\nfunction createSchemaGenerationDataSource(dataSource: DataSource): DataSource {\n  return new DataSource({\n    ...dataSource.options,\n    entities: [],\n    migrations: [],\n    subscribers: [],\n    migrationsRun: false,\n    synchronize: false,\n    dropSchema: false,\n  });\n}\n\nexport const typeormAdapter = (dataSource: DataSource, options?: TypeormAdapterOptions) =>\n  createAdapterFactory({\n    config: {\n      adapterId: \"typeorm\",\n      adapterName: \"TypeORM\",\n      usePlural: options?.usePlural ?? false,\n      debugLogs: options?.debugLogs ?? false,\n      supportsJSON: true,\n      supportsDates: true,\n      supportsBooleans: true,\n      supportsNumericIds: false,\n    },\n    adapter: ({\n      schema,\n      getModelName,\n      getDefaultModelName,\n      getFieldName,\n      transformInput,\n      transformOutput,\n      transformWhereClause,\n    }) => {\n      const fieldMapCache: Record<string, Record<string, string>> = {};\n\n      function isJsonTypedField(defaultModelName: string, fieldKey: string): boolean {\n        const fieldType = schema?.[defaultModelName]?.fields?.[fieldKey]?.type;\n        if (!fieldType) {\n          return false;\n        }\n        if (Array.isArray(fieldType)) {\n          return false;\n        }\n        return fieldType === \"json\" || fieldType === \"string[]\" || fieldType === \"number[]\";\n      }\n\n      function isDateTypedField(defaultModelName: string, fieldKey: string): boolean {\n        const fieldType = schema?.[defaultModelName]?.fields?.[fieldKey]?.type;\n        return fieldType === \"date\";\n      }\n\n      function isBooleanTypedField(defaultModelName: string, fieldKey: string): boolean {\n        const fieldType = schema?.[defaultModelName]?.fields?.[fieldKey]?.type;\n        return fieldType === \"boolean\";\n      }\n\n      function deserializeRow(\n        defaultModelName: string,\n        row: Record<string, unknown>,\n        reverseFieldMap: Record<string, string>,\n      ): Record<string, unknown> {\n        const denormalized: Record<string, unknown> = {};\n        for (const [key, value] of Object.entries(row)) {\n          const originalKey = reverseFieldMap[key] || key;\n          if (typeof value === \"string\" && isJsonTypedField(defaultModelName, originalKey)) {\n            try {\n              denormalized[originalKey] = JSON.parse(value);\n              continue;\n            } catch {}\n          }\n          if (value !== null && isDateTypedField(defaultModelName, originalKey)) {\n            denormalized[originalKey] = new Date(value as string | number);\n            continue;\n          }\n          if (value !== null && isBooleanTypedField(defaultModelName, originalKey)) {\n            denormalized[originalKey] =\n              value === 1 || value === \"1\" || value === \"true\" || value === true;\n            continue;\n          }\n          denormalized[originalKey] = value;\n        }\n        return denormalized;\n      }\n\n      function buildReverseFieldMap(model: string): Record<string, string> {\n        const reverseFieldMap: Record<string, string> = {};\n        const cached = fieldMapCache[model];\n        if (cached) {\n          for (const [originalKey, mappedKey] of Object.entries(cached)) {\n            reverseFieldMap[mappedKey] = originalKey;\n          }\n        }\n        return reverseFieldMap;\n      }\n\n      function convertWhereToFindOptions(\n        model: string,\n        action:\n          | \"create\"\n          | \"update\"\n          | \"updateMany\"\n          | \"findOne\"\n          | \"findMany\"\n          | \"delete\"\n          | \"deleteMany\"\n          | \"count\",\n        where?: Where[],\n      ): FindOptionsWhere<ObjectLiteral>[] {\n        if (!where || where.length === 0) {\n          return [{}];\n        }\n\n        const cleanedWhere = transformWhereClause({ model, where, action });\n        const findOptions: FindOptionsWhere<ObjectLiteral>[] = [];\n        let currentGroup: FindOptionsWhere<ObjectLiteral> = {};\n        findOptions.push(currentGroup);\n\n        for (const w of cleanedWhere) {\n          if (w.connector === \"OR\") {\n            currentGroup = {};\n            findOptions.push(currentGroup);\n          }\n          const field = w.field;\n          const value =\n            !w.operator || w.operator === \"eq\"\n              ? w.value\n              : convertOperatorToTypeORM(w.operator, w.value);\n\n          currentGroup[field] = value;\n        }\n\n        return findOptions;\n      }\n      async function deleteOrSoftDeleteHandler(\n        repository: Repository<ObjectLiteral>,\n        findOptions: FindOptionsWhere<ObjectLiteral>,\n        repositoryName: string,\n      ) {\n        let result: UpdateResult | DeleteResult;\n        if (options?.softDeleteEnabledEntities?.includes(repositoryName)) {\n          const hasDeletedAtColumn = repository.metadata.columns.some(\n            (column) => column.propertyName === \"deletedAt\",\n          );\n\n          if (!hasDeletedAtColumn) {\n            throw new BetterAuthError(`Failed to soft delete. Couldn't locate deletedAt column.`);\n          }\n          result = await repository.softDelete(findOptions);\n        } else {\n          result = await repository.delete(findOptions);\n        }\n        return result;\n      }\n      function buildWhereSql(\n        model: string,\n        action:\n          | \"update\"\n          | \"updateMany\"\n          | \"findOne\"\n          | \"findMany\"\n          | \"delete\"\n          | \"deleteMany\"\n          | \"count\",\n        where?: Where[],\n        startIndex = 0,\n      ) {\n        const cleaned = where?.length ? transformWhereClause({ model, where, action }) : [];\n\n        if (!cleaned.length) {\n          return { sql: \"\", params: [] as unknown[] };\n        }\n\n        const params: unknown[] = [];\n        const parts: string[] = [];\n\n        for (let i = 0; i < cleaned.length; i++) {\n          const w = cleaned[i];\n          const prefix = i === 0 ? \"\" : ` ${w.connector ?? \"AND\"} `;\n          let mappedFieldName = getFieldName({ model, field: w.field });\n\n          if (fieldMapCache[model]?.[w.field]) {\n            mappedFieldName = fieldMapCache[model][w.field];\n          }\n          const col = escapeId(dataSource, mappedFieldName);\n          const isInsensitive = w.mode === \"insensitive\";\n          const colSql = isInsensitive ? `LOWER(${col})` : col;\n\n          const push = (value: unknown) => {\n            let normalized = normalizeQueryValue(value, dataSource);\n            if (isInsensitive && typeof normalized === \"string\") {\n              normalized = normalized.toLowerCase();\n            }\n            return pushParameter(dataSource, params, normalized, startIndex);\n          };\n\n          switch (w.operator ?? \"eq\") {\n            case \"eq\":\n              if (w.value === null) {\n                parts.push(`${prefix}${col} IS NULL`);\n              } else {\n                parts.push(`${prefix}${colSql} = ${push(w.value)}`);\n              }\n              break;\n            case \"ne\":\n              if (w.value === null) {\n                parts.push(`${prefix}${col} IS NOT NULL`);\n              } else {\n                parts.push(`${prefix}${colSql} <> ${push(w.value)}`);\n              }\n              break;\n            case \"lt\":\n              parts.push(`${prefix}${colSql} < ${push(w.value)}`);\n              break;\n            case \"lte\":\n              parts.push(`${prefix}${colSql} <= ${push(w.value)}`);\n              break;\n            case \"gt\":\n              parts.push(`${prefix}${colSql} > ${push(w.value)}`);\n              break;\n            case \"gte\":\n              parts.push(`${prefix}${colSql} >= ${push(w.value)}`);\n              break;\n            case \"contains\":\n              parts.push(`${prefix}${colSql} LIKE ${push(`%${String(w.value)}%`)}`);\n              break;\n            case \"starts_with\":\n              parts.push(`${prefix}${colSql} LIKE ${push(`${String(w.value)}%`)}`);\n              break;\n            case \"ends_with\":\n              parts.push(`${prefix}${colSql} LIKE ${push(`%${String(w.value)}`)}`);\n              break;\n            case \"in\": {\n              const values = Array.isArray(w.value) ? w.value : [];\n              if (!values.length) {\n                parts.push(`${prefix}1 = 0`);\n              } else {\n                const placeholders = values.map((v) => push(v)).join(\", \");\n                parts.push(`${prefix}${colSql} IN (${placeholders})`);\n              }\n              break;\n            }\n            case \"not_in\": {\n              const values = Array.isArray(w.value) ? w.value : [];\n              if (!values.length) {\n                parts.push(`${prefix}1 = 1`);\n              } else {\n                const placeholders = values.map((v) => push(v)).join(\", \");\n                parts.push(`${prefix}${colSql} NOT IN (${placeholders})`);\n              }\n              break;\n            }\n            default:\n              parts.push(`${prefix}${colSql} = ${push(w.value)}`);\n              break;\n          }\n        }\n\n        return {\n          sql: ` WHERE ${parts.join(\"\")}`,\n          params,\n        };\n      }\n\n      async function rawCreate(model: string, data: Record<string, unknown>, select?: string[]) {\n        const defaultModelName = getDefaultModelName(model);\n        const tableName = getModelName(model);\n        const transformedData = await transformInput(data, defaultModelName, \"create\");\n\n        const queryRunner = dataSource.createQueryRunner();\n        await queryRunner.connect();\n\n        let existingColumns: Set<string> | null = null;\n        try {\n          const table = await queryRunner.getTable(tableName);\n          if (table) {\n            existingColumns = new Set(table.columns.map((col) => col.name));\n          }\n        } catch {}\n\n        const createFieldMap: Record<string, string> = {};\n        for (const [key] of Object.entries(data)) {\n          if (existingColumns?.has(key)) {\n            createFieldMap[key] = key;\n          } else {\n            let found = false;\n            const variants = [\n              key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()),\n              key.replace(/([A-Z])/g, \"_$1\").toLowerCase(),\n            ];\n            for (const variant of variants) {\n              if (existingColumns?.has(variant)) {\n                createFieldMap[key] = variant;\n                found = true;\n                break;\n              }\n            }\n            if (!found && existingColumns) {\n              for (const col of Array.from(existingColumns)) {\n                if (\n                  key.toLowerCase().includes(col.toLowerCase()) ||\n                  col.toLowerCase().includes(key.toLowerCase())\n                ) {\n                  const keyLower = key.toLowerCase().replace(/_/g, \"\");\n                  const colLower = col.toLowerCase().replace(/_/g, \"\");\n                  if (col.length < key.length && keyLower.startsWith(colLower)) {\n                    createFieldMap[key] = col;\n                    found = true;\n                    break;\n                  }\n                }\n              }\n            }\n            if (!found) {\n              const dbFieldName = getFieldName({ model, field: key });\n              if (existingColumns?.has(dbFieldName)) {\n                createFieldMap[key] = dbFieldName;\n              } else if (!existingColumns) {\n                createFieldMap[key] = dbFieldName || key;\n              }\n            }\n          }\n        }\n\n        const mappedData: Record<string, unknown> = {};\n        for (const [key, value] of Object.entries(transformedData)) {\n          if (value === undefined) {\n            continue;\n          }\n          const targetKey = createFieldMap[key] || key;\n          mappedData[targetKey] = value;\n        }\n\n        if (!fieldMapCache[model]) {\n          fieldMapCache[model] = createFieldMap;\n        }\n\n        let updatedExistingColumns: Set<string> | null = existingColumns;\n        if (options?.enableSchemaSync) {\n          await ensureTableExists(dataSource, tableName, mappedData);\n          updatedExistingColumns = null;\n          try {\n            const table = await queryRunner.getTable(tableName);\n            if (table) {\n              updatedExistingColumns = new Set(table.columns.map((col) => col.name));\n            }\n          } catch {}\n        }\n\n        const insertData: Record<string, unknown> = {};\n        if (updatedExistingColumns) {\n          for (const [key, value] of Object.entries(mappedData)) {\n            if (value === undefined) {\n              continue;\n            }\n            if (updatedExistingColumns.has(key)) {\n              insertData[key] = value;\n            }\n          }\n        } else {\n          Object.assign(insertData, mappedData);\n        }\n        const entries = Object.entries(insertData).filter(([, value]) => value !== undefined);\n        const columns = entries.map(([key]) => escapeId(dataSource, key)).join(\", \");\n        const placeholders = entries\n          .map((_, index) => createParameterToken(dataSource, index))\n          .join(\", \");\n        const values = entries.map(([, value]) => normalizeQueryValue(value, dataSource));\n\n        try {\n          const isSqlite = dataSource.options.type === \"better-sqlite3\";\n          if (isSqlite) {\n            await queryRunner.query(\"PRAGMA foreign_keys = OFF\");\n          }\n          try {\n            const sql = `INSERT INTO ${escapeId(dataSource, tableName)} (${columns}) VALUES (${placeholders})`;\n            await queryRunner.query(sql, values);\n          } finally {\n            if (isSqlite) {\n              await queryRunner.query(\"PRAGMA foreign_keys = ON\");\n            }\n          }\n\n          const rows = await queryRunner.query(\n            `SELECT * FROM ${escapeId(dataSource, tableName)} WHERE ${escapeId(dataSource, \"id\")} = ${createParameterToken(dataSource, 0)}`,\n            [mappedData.id],\n          );\n\n          if (rows[0]) {\n            const reverseFieldMap: Record<string, string> = {};\n            for (const [originalKey, mappedKey] of Object.entries(createFieldMap)) {\n              reverseFieldMap[mappedKey] = originalKey;\n            }\n            const denormalizedRow = deserializeRow(defaultModelName, rows[0], reverseFieldMap);\n            return await transformOutput(denormalizedRow, defaultModelName, select);\n          }\n          return await transformOutput(mappedData, defaultModelName, select);\n        } finally {\n          await queryRunner.release();\n        }\n      }\n\n      async function rawFindOne<T>(\n        model: string,\n        where: CleanedWhere[],\n        select?: string[],\n      ): Promise<T | null> {\n        const defaultModelName = getDefaultModelName(model);\n        const tableName = getModelName(model);\n        const { sql, params } = buildWhereSql(model, \"findOne\", where);\n\n        const queryRunner = dataSource.createQueryRunner();\n        await queryRunner.connect();\n        try {\n          const rows = await queryRunner.query(\n            `SELECT * FROM ${escapeId(dataSource, tableName)}${sql} LIMIT 1`,\n            params,\n          );\n          if (!rows[0]) {\n            return null;\n          }\n          const reverseFieldMap = buildReverseFieldMap(model);\n          const denormalizedRow = deserializeRow(defaultModelName, rows[0], reverseFieldMap);\n          return (await transformOutput(denormalizedRow, defaultModelName, select)) as T;\n        } finally {\n          await queryRunner.release();\n        }\n      }\n\n      async function rawFindMany<T>(\n        model: string,\n        where?: CleanedWhere[],\n        limit?: number,\n        sortBy?: { field: string; direction: \"asc\" | \"desc\" },\n        offset?: number,\n      ): Promise<T[]> {\n        const defaultModelName = getDefaultModelName(model);\n        const tableName = getModelName(model);\n        const { sql, params } = buildWhereSql(model, \"findMany\", where);\n\n        let query = `SELECT * FROM ${escapeId(dataSource, tableName)}${sql}`;\n\n        if (sortBy?.field) {\n          let mappedSortField = getFieldName({ model, field: sortBy.field });\n          if (fieldMapCache[model]?.[sortBy.field]) {\n            mappedSortField = fieldMapCache[model][sortBy.field];\n          }\n          query += ` ORDER BY ${escapeId(dataSource, mappedSortField)} ${sortBy.direction === \"desc\" ? \"DESC\" : \"ASC\"}`;\n        }\n        query += ` LIMIT ${limit || 100}`;\n        if (offset) {\n          query += ` OFFSET ${offset}`;\n        }\n\n        const queryRunner = dataSource.createQueryRunner();\n        await queryRunner.connect();\n        try {\n          const rows = await queryRunner.query(query, params);\n          const reverseFieldMap = buildReverseFieldMap(model);\n          const transformed = await Promise.all(\n            rows.map((r: Record<string, unknown>) => {\n              const denormalizedRow = deserializeRow(defaultModelName, r, reverseFieldMap);\n              return transformOutput(denormalizedRow, defaultModelName);\n            }),\n          );\n          return transformed as T[];\n        } finally {\n          await queryRunner.release();\n        }\n      }\n\n      async function rawUpdate(model: string, where: Where[], update: Record<string, unknown>) {\n        const defaultModelName = getDefaultModelName(model);\n        const tableName = getModelName(model);\n        const transformed = await transformInput(update, defaultModelName, \"update\");\n\n        const { sql: whereSql, params: whereParams } = buildWhereSql(model, \"findOne\", where);\n\n        const queryRunner = dataSource.createQueryRunner();\n        await queryRunner.connect();\n        try {\n          const existing = await queryRunner.query(\n            `SELECT * FROM ${escapeId(dataSource, tableName)}${whereSql} LIMIT 1`,\n            whereParams,\n          );\n\n          if (!existing[0]) {\n            return null;\n          }\n\n          const setClauses: string[] = [];\n          const setValues: unknown[] = [];\n          for (const [key, value] of Object.entries(transformed)) {\n            if (value !== undefined) {\n              setClauses.push(\n                `${escapeId(dataSource, key)} = ${createParameterToken(dataSource, setValues.length)}`,\n              );\n              setValues.push(normalizeQueryValue(value, dataSource));\n            }\n          }\n\n          if (setClauses.length > 0) {\n            await queryRunner.query(\n              `UPDATE ${escapeId(dataSource, tableName)} SET ${setClauses.join(\", \")} WHERE ${escapeId(dataSource, \"id\")} = ${createParameterToken(dataSource, setValues.length)}`,\n              [...setValues, existing[0].id],\n            );\n          }\n\n          const result = await queryRunner.query(\n            `SELECT * FROM ${escapeId(dataSource, tableName)} WHERE ${escapeId(dataSource, \"id\")} = ${createParameterToken(dataSource, 0)}`,\n            [existing[0].id],\n          );\n\n          if (result[0]) {\n            const reverseFieldMap = buildReverseFieldMap(model);\n            const denormalizedRow = deserializeRow(defaultModelName, result[0], reverseFieldMap);\n            return await transformOutput(denormalizedRow, defaultModelName);\n          }\n          return null;\n        } finally {\n          await queryRunner.release();\n        }\n      }\n\n      async function rawDelete(model: string, where: Where[]) {\n        const tableName = getModelName(model);\n        const { sql, params } = buildWhereSql(model, \"delete\", where);\n\n        const queryRunner = dataSource.createQueryRunner();\n        await queryRunner.connect();\n        try {\n          await queryRunner.query(`DELETE FROM ${escapeId(dataSource, tableName)}${sql}`, params);\n        } finally {\n          await queryRunner.release();\n        }\n      }\n\n      async function rawCount(model: string, where?: Where[]) {\n        const tableName = getModelName(model);\n        const { sql, params } = buildWhereSql(model, \"count\", where);\n\n        const queryRunner = dataSource.createQueryRunner();\n        await queryRunner.connect();\n        try {\n          const result = await queryRunner.query(\n            `SELECT COUNT(*) as cnt FROM ${escapeId(dataSource, tableName)}${sql}`,\n            params,\n          );\n          return Number(result[0]?.cnt ?? 0);\n        } finally {\n          await queryRunner.release();\n        }\n      }\n\n      async function rawUpdateMany(\n        model: string,\n        where: Where[] | undefined,\n        update: Record<string, unknown>,\n      ) {\n        const defaultModelName = getDefaultModelName(model);\n        const tableName = getModelName(model);\n        const transformed = await transformInput(update, defaultModelName, \"update\");\n\n        const setClauses: string[] = [];\n        const setValues: unknown[] = [];\n        for (const [key, value] of Object.entries(transformed)) {\n          if (value !== undefined) {\n            setClauses.push(\n              `${escapeId(dataSource, key)} = ${createParameterToken(dataSource, setValues.length)}`,\n            );\n            setValues.push(normalizeQueryValue(value, dataSource));\n          }\n        }\n\n        if (setClauses.length === 0) {\n          return 0;\n        }\n\n        const { sql: whereSql, params: whereParams } = buildWhereSql(\n          model,\n          \"updateMany\",\n          where,\n          setValues.length,\n        );\n\n        const queryRunner = dataSource.createQueryRunner();\n        await queryRunner.connect();\n        try {\n          const result = await queryRunner.query(\n            `UPDATE ${escapeId(dataSource, tableName)} SET ${setClauses.join(\", \")}${whereSql}`,\n            [...setValues, ...whereParams],\n            true,\n          );\n          return getAffectedRowCount(result);\n        } finally {\n          await queryRunner.release();\n        }\n      }\n\n      async function rawDeleteMany(model: string, where?: Where[]) {\n        const tableName = getModelName(model);\n        const { sql, params } = buildWhereSql(model, \"deleteMany\", where);\n\n        const queryRunner = dataSource.createQueryRunner();\n        await queryRunner.connect();\n        try {\n          const result = await queryRunner.query(\n            `DELETE FROM ${escapeId(dataSource, tableName)}${sql}`,\n            params,\n            true,\n          );\n          return getAffectedRowCount(result);\n        } finally {\n          await queryRunner.release();\n        }\n      }\n\n      function getAffectedRowCount(result: QueryResult): number {\n        if (typeof result.affected === \"number\") {\n          return result.affected;\n        }\n\n        return 0;\n      }\n\n      return {\n        async create({ data, model, select }) {\n          if (!dataSource.isInitialized) {\n            await dataSource.initialize();\n          }\n          try {\n            return (await rawCreate(model, data as Record<string, unknown>, select)) as typeof data;\n          } catch (error: unknown) {\n            throw new BetterAuthError(\n              `Failed to create ${model}: ${error instanceof Error ? error.message : String(error)}`,\n            );\n          }\n        },\n\n        async update({ model, where, update }) {\n          if (!dataSource.isInitialized) {\n            await dataSource.initialize();\n          }\n          try {\n            return (await rawUpdate(\n              model,\n              where,\n              update as Record<string, unknown>,\n            )) as typeof update;\n          } catch (error: unknown) {\n            throw new BetterAuthError(\n              `Failed to update ${model}: ${error instanceof Error ? error.message : String(error)}`,\n            );\n          }\n        },\n\n        async delete({ model, where }) {\n          if (!dataSource.isInitialized) {\n            await dataSource.initialize();\n          }\n\n          const repositoryName = getModelName(model);\n          const repository = tryGetRepository(dataSource, repositoryName);\n\n          if (repository && options?.softDeleteEnabledEntities?.includes(repositoryName)) {\n            try {\n              const findOptionsArr = convertWhereToFindOptions(model, \"delete\", where);\n              const findOptions = findOptionsArr.length === 1 ? findOptionsArr[0] : findOptionsArr;\n              await deleteOrSoftDeleteHandler(repository, findOptions, repositoryName);\n              return;\n            } catch (error: unknown) {\n              throw new BetterAuthError(\n                `Failed to delete ${model}: ${error instanceof Error ? error.message : String(error)}`,\n              );\n            }\n          }\n\n          try {\n            await rawDelete(model, where);\n          } catch (error: unknown) {\n            throw new BetterAuthError(\n              `Failed to delete ${model}: ${error instanceof Error ? error.message : String(error)}`,\n            );\n          }\n        },\n\n        async findOne<T>({\n          model,\n          where,\n          select,\n        }: {\n          model: string;\n          where: CleanedWhere[];\n          select?: string[] | undefined;\n        }): Promise<T | null> {\n          if (!dataSource.isInitialized) {\n            await dataSource.initialize();\n          }\n          try {\n            return await rawFindOne<T>(model, where, select);\n          } catch (error: unknown) {\n            throw new BetterAuthError(\n              `Failed to find ${model}: ${error instanceof Error ? error.message : String(error)}`,\n            );\n          }\n        },\n\n        async findMany<T>({\n          model,\n          where,\n          limit,\n          sortBy,\n          offset,\n        }: {\n          model: string;\n          where?: CleanedWhere[] | undefined;\n          limit: number;\n          sortBy?:\n            | {\n                field: string;\n                direction: \"asc\" | \"desc\";\n              }\n            | undefined;\n          offset?: number | undefined;\n        }): Promise<T[]> {\n          if (!dataSource.isInitialized) {\n            await dataSource.initialize();\n          }\n          try {\n            return await rawFindMany<T>(model, where, limit, sortBy, offset);\n          } catch (error: unknown) {\n            throw new BetterAuthError(\n              `Failed to find many ${model}: ${error instanceof Error ? error.message : String(error)}`,\n            );\n          }\n        },\n\n        async count({ model, where }) {\n          if (!dataSource.isInitialized) {\n            await dataSource.initialize();\n          }\n          try {\n            return await rawCount(model, where);\n          } catch (error: unknown) {\n            throw new BetterAuthError(\n              `Failed to count ${model}: ${error instanceof Error ? error.message : String(error)}`,\n            );\n          }\n        },\n\n        async updateMany({ model, where, update }) {\n          if (!dataSource.isInitialized) {\n            await dataSource.initialize();\n          }\n          try {\n            return await rawUpdateMany(model, where, update as Record<string, unknown>);\n          } catch (error: unknown) {\n            throw new BetterAuthError(\n              `Failed to update many ${model}: ${error instanceof Error ? error.message : String(error)}`,\n            );\n          }\n        },\n\n        async deleteMany({ model, where }) {\n          if (!dataSource.isInitialized) {\n            await dataSource.initialize();\n          }\n\n          const repositoryName = getModelName(model);\n          const repository = tryGetRepository(dataSource, repositoryName);\n\n          if (repository && options?.softDeleteEnabledEntities?.includes(repositoryName)) {\n            try {\n              if (!where || where.length === 0) {\n                const result = await repository\n                  .createQueryBuilder()\n                  .softDelete()\n                  .from(repository.target)\n                  .where(\"1=1\")\n                  .execute();\n                return result.affected || 0;\n              }\n              const findOptionsArr = convertWhereToFindOptions(model, \"deleteMany\", where);\n              const findOptions = findOptionsArr.length === 1 ? findOptionsArr[0] : findOptionsArr;\n              const result = await deleteOrSoftDeleteHandler(\n                repository,\n                findOptions,\n                repositoryName,\n              );\n              return result.affected || 0;\n            } catch (error: unknown) {\n              throw new BetterAuthError(\n                `Failed to delete many ${model}: ${error instanceof Error ? error.message : String(error)}`,\n              );\n            }\n          }\n\n          try {\n            return await rawDeleteMany(model, where);\n          } catch (error: unknown) {\n            throw new BetterAuthError(\n              `Failed to delete many ${model}: ${error instanceof Error ? error.message : String(error)}`,\n            );\n          }\n        },\n\n        async createSchema({ tables, file }) {\n          let schemaDataSource = dataSource;\n          let destroySchemaDataSource = false;\n\n          if (!schemaDataSource.isInitialized) {\n            schemaDataSource = createSchemaGenerationDataSource(dataSource);\n            destroySchemaDataSource = true;\n            await schemaDataSource.initialize();\n          }\n          try {\n            const timestamp = Date.now();\n            const typeormDir = path.resolve(options?.outputDir ?? \"./typeorm\");\n            const migrationsDir = path.resolve(\n              options?.migrationsDir ?? `${options?.outputDir ?? \"./typeorm\"}/migrations`,\n            );\n            const entitiesDir = path.resolve(\n              options?.entitiesDir ?? `${options?.outputDir ?? \"./typeorm\"}/entities`,\n            );\n\n            if (!fs.existsSync(typeormDir)) {\n              fs.mkdirSync(typeormDir, { recursive: true });\n            }\n            if (!fs.existsSync(migrationsDir)) {\n              fs.mkdirSync(migrationsDir, { recursive: true });\n            }\n            if (!fs.existsSync(entitiesDir)) {\n              fs.mkdirSync(entitiesDir, { recursive: true });\n            }\n\n            const queryRunner = schemaDataSource.createQueryRunner();\n            await queryRunner.connect();\n\n            let changelogContent = `# TypeORM Schema Changes - ${new Date().toISOString()}\\n\\n`;\n            let hasChanges = false;\n\n            const expectedTables = Object.keys(tables);\n\n            for (const modelName of expectedTables) {\n              const modelSchema = tables[modelName];\n              const tableName = modelSchema.modelName;\n\n              const tableExists = await queryRunner.hasTable(tableName);\n\n              const entityCode = generateEntity(dataSource, modelName, modelSchema);\n              const entityPath = path.join(\n                entitiesDir,\n                `${modelName.charAt(0).toUpperCase() + modelName.slice(1)}.ts`,\n              );\n\n              if (!tableExists) {\n                const migrationFileName = `${timestamp}-create-${modelName}.ts`;\n                const migrationCode = generateMigration(\n                  dataSource,\n                  modelName,\n                  modelSchema,\n                  timestamp,\n                  \"create\",\n                );\n                const migrationPath = path.join(migrationsDir, migrationFileName);\n                fs.writeFileSync(migrationPath, migrationCode);\n                fs.writeFileSync(entityPath, entityCode);\n\n                changelogContent += `- CREATE Migration: migrations/${migrationFileName}\\n`;\n                changelogContent += `- Entity: entities/${modelName.charAt(0).toUpperCase() + modelName.slice(1)}.ts\\n\\n`;\n                hasChanges = true;\n              } else {\n                const table = await queryRunner.getTable(tableName);\n                if (!table) {\n                  continue;\n                }\n\n                const existingColumns = table.columns.map((col) => col.name);\n                const expectedFields = modelSchema.fields;\n\n                const addColumns = [];\n                const dropColumns = [];\n\n                for (const [fieldName, field] of Object.entries(expectedFields)) {\n                  const dbField = field.fieldName || fieldName;\n                  if (!existingColumns.includes(dbField)) {\n                    addColumns.push({ name: fieldName, field });\n                  }\n                }\n\n                for (const existingCol of existingColumns) {\n                  if (existingCol === \"id\") {\n                    continue;\n                  }\n                  const fieldExists = Object.entries(expectedFields).some(\n                    ([fieldName, field]) => (field.fieldName || fieldName) === existingCol,\n                  );\n                  if (!fieldExists) {\n                    dropColumns.push(existingCol);\n                  }\n                }\n\n                if (addColumns.length > 0 || dropColumns.length > 0) {\n                  const migrationFileName = `${timestamp}-alter-${modelName}.ts`;\n                  const changes = { addColumns, dropColumns, modifyColumns: [] };\n                  const migrationCode = generateMigration(\n                    dataSource,\n                    modelName,\n                    modelSchema,\n                    timestamp,\n                    \"alter\",\n                    changes,\n                  );\n                  const migrationPath = path.join(migrationsDir, migrationFileName);\n                  fs.writeFileSync(migrationPath, migrationCode);\n                  fs.writeFileSync(entityPath, entityCode);\n\n                  changelogContent += `- ALTER Migration: migrations/${migrationFileName}\\n`;\n                  changelogContent += `- Updated Entity: entities/${modelName.charAt(0).toUpperCase() + modelName.slice(1)}.ts\\n`;\n\n                  if (addColumns.length > 0) {\n                    changelogContent += `  - Added columns: ${addColumns.map((col) => col.field.fieldName || col.name).join(\", \")}\\n`;\n                  }\n                  if (dropColumns.length > 0) {\n                    changelogContent += `  - Removed columns: ${dropColumns.join(\", \")}\\n`;\n                  }\n                  changelogContent += \"\\n\";\n                  hasChanges = true;\n                } else {\n                  if (fs.existsSync(entityPath)) {\n                    const existingContent = fs.readFileSync(entityPath, \"utf-8\");\n                    if (existingContent !== entityCode) {\n                      fs.writeFileSync(entityPath, entityCode);\n                      changelogContent += `- Updated entity: entities/${modelName.charAt(0).toUpperCase() + modelName.slice(1)}.ts\\n\\n`;\n                      hasChanges = true;\n                    }\n                  } else {\n                    fs.writeFileSync(entityPath, entityCode);\n                    changelogContent += `- Generated missing entity: entities/${modelName.charAt(0).toUpperCase() + modelName.slice(1)}.ts\\n\\n`;\n                    hasChanges = true;\n                  }\n                }\n              }\n            }\n\n            await queryRunner.release();\n            if (destroySchemaDataSource) {\n              await schemaDataSource.destroy();\n            }\n\n            if (!hasChanges) {\n              changelogContent += \"Schema is up to date. No changes detected.\\n\";\n            }\n\n            return {\n              code: changelogContent,\n              path: file ?? \"typeorm/changelog.txt\",\n            };\n          } catch (error) {\n            if (destroySchemaDataSource && schemaDataSource.isInitialized) {\n              await schemaDataSource.destroy();\n            }\n            throw new BetterAuthError(\n              `Failed to create schema: ${error instanceof Error ? error.message : String(error)}`,\n            );\n          }\n        },\n      };\n    },\n  });\n"],"mappings":"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"}