@famgia/omnify-atlas 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1389 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +585 -0
- package/dist/index.d.ts +585 -0
- package/dist/index.js +1333 -0
- package/dist/index.js.map +1 -0
- package/package.json +31 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lock/lock-file.ts","../src/hcl/type-mapper.ts","../src/hcl/generator.ts","../src/atlas/runner.ts","../src/diff/parser.ts","../src/preview/preview.ts"],"sourcesContent":["/**\n * @famgia/omnify-atlas - Lock File Management\n *\n * Manages the .omnify.lock file for tracking schema state.\n */\n\nimport { createHash } from 'node:crypto';\nimport { readFile, writeFile, stat } from 'node:fs/promises';\nimport type { SchemaCollection } from '@famgia/omnify-types';\nimport type {\n LockFile,\n SchemaHash,\n SchemaChange,\n LockFileComparison,\n} from './types.js';\n\n/**\n * Default lock file name.\n */\nexport const LOCK_FILE_NAME = '.omnify.lock';\n\n/**\n * Current lock file format version.\n */\nexport const LOCK_FILE_VERSION = 1 as const;\n\n/**\n * Computes SHA-256 hash of content.\n */\nexport function computeHash(content: string): string {\n return createHash('sha256').update(content, 'utf8').digest('hex');\n}\n\n/**\n * Computes hash for a schema.\n */\nexport function computeSchemaHash(schema: {\n name: string;\n relativePath: string;\n properties?: unknown;\n options?: unknown;\n values?: readonly string[];\n kind?: string;\n}): string {\n // Hash only the structural content, not metadata\n const content = JSON.stringify({\n name: schema.name,\n kind: schema.kind ?? 'object',\n properties: schema.properties ?? {},\n options: schema.options ?? {},\n values: schema.values ?? [],\n });\n return computeHash(content);\n}\n\n/**\n * Creates a new empty lock file.\n */\nexport function createEmptyLockFile(driver: string): LockFile {\n return {\n version: LOCK_FILE_VERSION,\n updatedAt: new Date().toISOString(),\n driver,\n schemas: {},\n migrations: [],\n };\n}\n\n/**\n * Reads lock file from disk.\n * Returns null if file doesn't exist.\n */\nexport async function readLockFile(lockFilePath: string): Promise<LockFile | null> {\n try {\n const content = await readFile(lockFilePath, 'utf8');\n const parsed = JSON.parse(content) as LockFile;\n\n // Validate version\n if (parsed.version !== LOCK_FILE_VERSION) {\n throw new Error(\n `Lock file version mismatch: expected ${LOCK_FILE_VERSION}, got ${parsed.version}`\n );\n }\n\n return parsed;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Writes lock file to disk.\n */\nexport async function writeLockFile(\n lockFilePath: string,\n lockFile: LockFile\n): Promise<void> {\n const content = JSON.stringify(lockFile, null, 2) + '\\n';\n await writeFile(lockFilePath, content, 'utf8');\n}\n\n/**\n * Builds schema hashes from a schema collection.\n */\nexport async function buildSchemaHashes(\n schemas: SchemaCollection\n): Promise<Record<string, SchemaHash>> {\n const hashes: Record<string, SchemaHash> = {};\n\n for (const [name, schema] of Object.entries(schemas)) {\n const hash = computeSchemaHash(schema);\n\n // Get file modification time\n let modifiedAt: string;\n try {\n const stats = await stat(schema.filePath);\n modifiedAt = stats.mtime.toISOString();\n } catch {\n modifiedAt = new Date().toISOString();\n }\n\n hashes[name] = {\n name,\n hash,\n relativePath: schema.relativePath,\n modifiedAt,\n };\n }\n\n return hashes;\n}\n\n/**\n * Compares current schemas to lock file and detects changes.\n */\nexport function compareSchemas(\n currentHashes: Record<string, SchemaHash>,\n lockFile: LockFile | null\n): LockFileComparison {\n const changes: SchemaChange[] = [];\n const unchanged: string[] = [];\n\n const previousHashes = lockFile?.schemas ?? {};\n const previousNames = new Set(Object.keys(previousHashes));\n const currentNames = new Set(Object.keys(currentHashes));\n\n // Find added schemas\n for (const name of currentNames) {\n if (!previousNames.has(name)) {\n const current = currentHashes[name];\n if (current) {\n changes.push({\n schemaName: name,\n changeType: 'added',\n currentHash: current.hash,\n });\n }\n }\n }\n\n // Find removed schemas\n for (const name of previousNames) {\n if (!currentNames.has(name)) {\n const previous = previousHashes[name];\n if (previous) {\n changes.push({\n schemaName: name,\n changeType: 'removed',\n previousHash: previous.hash,\n });\n }\n }\n }\n\n // Find modified schemas\n for (const name of currentNames) {\n if (previousNames.has(name)) {\n const current = currentHashes[name];\n const previous = previousHashes[name];\n\n if (current && previous) {\n if (current.hash !== previous.hash) {\n changes.push({\n schemaName: name,\n changeType: 'modified',\n previousHash: previous.hash,\n currentHash: current.hash,\n });\n } else {\n unchanged.push(name);\n }\n }\n }\n }\n\n return {\n hasChanges: changes.length > 0,\n changes,\n unchanged,\n };\n}\n\n/**\n * Updates lock file with current schema state.\n */\nexport function updateLockFile(\n existingLockFile: LockFile | null,\n currentHashes: Record<string, SchemaHash>,\n driver: string\n): LockFile {\n return {\n version: LOCK_FILE_VERSION,\n updatedAt: new Date().toISOString(),\n driver,\n schemas: currentHashes,\n migrations: existingLockFile?.migrations ?? [],\n hclChecksum: existingLockFile?.hclChecksum,\n };\n}\n\n/**\n * Adds a migration record to the lock file.\n */\nexport function addMigrationRecord(\n lockFile: LockFile,\n fileName: string,\n schemas: readonly string[],\n migrationContent: string\n): LockFile {\n const record = {\n fileName,\n generatedAt: new Date().toISOString(),\n schemas,\n checksum: computeHash(migrationContent),\n };\n\n return {\n ...lockFile,\n updatedAt: new Date().toISOString(),\n migrations: [...lockFile.migrations, record],\n };\n}\n","/**\n * @famgia/omnify-atlas - Type Mapper\n *\n * Maps Omnify property types to SQL types for different database drivers.\n */\n\nimport type { PropertyDefinition, DatabaseDriver, BasePropertyDefinition } from '@famgia/omnify-types';\nimport type { SqlColumnType } from './types.js';\n\n/**\n * Extended property with all possible optional fields for type mapping.\n */\ninterface ExtendedProperty {\n readonly type: string;\n readonly displayName?: string;\n readonly nullable?: boolean;\n readonly default?: unknown;\n readonly unique?: boolean;\n readonly length?: number;\n readonly unsigned?: boolean;\n readonly enum?: string | readonly string[];\n}\n\n/**\n * Type mapping for a specific driver.\n */\ntype DriverTypeMap = Record<string, (prop: ExtendedProperty) => SqlColumnType>;\n\n/**\n * MySQL type mappings.\n */\nconst MYSQL_TYPES: DriverTypeMap = {\n String: (prop) => ({\n type: `varchar(${prop.length ?? 255})`,\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? `'${prop.default}'` : undefined,\n }),\n Int: (prop) => ({\n type: 'int',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? String(prop.default) : undefined,\n unsigned: prop.unsigned ?? false,\n }),\n BigInt: (prop) => ({\n type: 'bigint',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? String(prop.default) : undefined,\n unsigned: prop.unsigned ?? false,\n }),\n Float: (prop) => ({\n type: 'double',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? String(prop.default) : undefined,\n }),\n Boolean: (prop) => ({\n type: 'tinyint(1)',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? (prop.default ? '1' : '0') : undefined,\n }),\n Text: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n LongText: (prop) => ({\n type: 'longtext',\n nullable: prop.nullable ?? false,\n }),\n Date: (prop) => ({\n type: 'date',\n nullable: prop.nullable ?? false,\n }),\n Time: (prop) => ({\n type: 'time',\n nullable: prop.nullable ?? false,\n }),\n Timestamp: (prop) => ({\n type: 'timestamp',\n nullable: prop.nullable ?? false,\n }),\n Json: (prop) => ({\n type: 'json',\n nullable: prop.nullable ?? false,\n }),\n Email: (prop) => ({\n type: 'varchar(255)',\n nullable: prop.nullable ?? false,\n }),\n Password: (prop) => ({\n type: 'varchar(255)',\n nullable: prop.nullable ?? false,\n }),\n File: (prop) => ({\n type: 'varchar(500)',\n nullable: prop.nullable ?? false,\n }),\n MultiFile: (prop) => ({\n type: 'json',\n nullable: prop.nullable ?? false,\n }),\n Enum: (prop) => {\n const enumProp = prop as { enum?: readonly string[] };\n const values = enumProp.enum ?? [];\n const enumDef = values.map((v) => `'${v}'`).join(', ');\n return {\n type: `enum(${enumDef})`,\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? `'${prop.default}'` : undefined,\n };\n },\n Select: (prop) => ({\n type: 'varchar(100)',\n nullable: prop.nullable ?? false,\n }),\n Lookup: (prop) => ({\n type: 'bigint',\n nullable: prop.nullable ?? false,\n unsigned: true,\n }),\n};\n\n/**\n * PostgreSQL type mappings.\n */\nconst POSTGRES_TYPES: DriverTypeMap = {\n String: (prop) => ({\n type: `varchar(${prop.length ?? 255})`,\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? `'${prop.default}'` : undefined,\n }),\n Int: (prop) => ({\n type: 'integer',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? String(prop.default) : undefined,\n }),\n BigInt: (prop) => ({\n type: 'bigint',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? String(prop.default) : undefined,\n }),\n Float: (prop) => ({\n type: 'double precision',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? String(prop.default) : undefined,\n }),\n Boolean: (prop) => ({\n type: 'boolean',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? String(prop.default) : undefined,\n }),\n Text: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n LongText: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n Date: (prop) => ({\n type: 'date',\n nullable: prop.nullable ?? false,\n }),\n Time: (prop) => ({\n type: 'time',\n nullable: prop.nullable ?? false,\n }),\n Timestamp: (prop) => ({\n type: 'timestamp',\n nullable: prop.nullable ?? false,\n }),\n Json: (prop) => ({\n type: 'jsonb',\n nullable: prop.nullable ?? false,\n }),\n Email: (prop) => ({\n type: 'varchar(255)',\n nullable: prop.nullable ?? false,\n }),\n Password: (prop) => ({\n type: 'varchar(255)',\n nullable: prop.nullable ?? false,\n }),\n File: (prop) => ({\n type: 'varchar(500)',\n nullable: prop.nullable ?? false,\n }),\n MultiFile: (prop) => ({\n type: 'jsonb',\n nullable: prop.nullable ?? false,\n }),\n // For PostgreSQL, enums are separate types\n Enum: (prop) => ({\n type: 'varchar(100)',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? `'${prop.default}'` : undefined,\n }),\n Select: (prop) => ({\n type: 'varchar(100)',\n nullable: prop.nullable ?? false,\n }),\n Lookup: (prop) => ({\n type: 'bigint',\n nullable: prop.nullable ?? false,\n }),\n};\n\n/**\n * SQLite type mappings.\n */\nconst SQLITE_TYPES: DriverTypeMap = {\n String: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? `'${prop.default}'` : undefined,\n }),\n Int: (prop) => ({\n type: 'integer',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? String(prop.default) : undefined,\n }),\n BigInt: (prop) => ({\n type: 'integer',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? String(prop.default) : undefined,\n }),\n Float: (prop) => ({\n type: 'real',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? String(prop.default) : undefined,\n }),\n Boolean: (prop) => ({\n type: 'integer',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? (prop.default ? '1' : '0') : undefined,\n }),\n Text: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n LongText: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n Date: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n Time: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n Timestamp: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n Json: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n Email: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n Password: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n File: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n MultiFile: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n Enum: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n default: prop.default !== undefined ? `'${prop.default}'` : undefined,\n }),\n Select: (prop) => ({\n type: 'text',\n nullable: prop.nullable ?? false,\n }),\n Lookup: (prop) => ({\n type: 'integer',\n nullable: prop.nullable ?? false,\n }),\n};\n\n/**\n * Driver type maps.\n */\nconst DRIVER_TYPE_MAPS: Record<DatabaseDriver, DriverTypeMap> = {\n mysql: MYSQL_TYPES,\n postgres: POSTGRES_TYPES,\n pgsql: POSTGRES_TYPES, // Alias for postgres\n sqlite: SQLITE_TYPES,\n mariadb: MYSQL_TYPES, // MariaDB uses same types as MySQL\n sqlsrv: MYSQL_TYPES, // SQL Server uses similar types to MySQL for now\n};\n\n/**\n * Maps a property type to SQL column type.\n */\nexport function mapPropertyToSql(\n property: PropertyDefinition,\n driver: DatabaseDriver\n): SqlColumnType {\n const typeMap = DRIVER_TYPE_MAPS[driver];\n const mapper = typeMap[property.type];\n\n // Cast to BasePropertyDefinition since we only handle non-Association types here\n const baseProp = property as BasePropertyDefinition;\n\n if (mapper) {\n return mapper(baseProp);\n }\n\n // Default fallback for unknown types\n return {\n type: 'varchar(255)',\n nullable: baseProp.nullable ?? false,\n };\n}\n\n/**\n * Gets the SQL type for a primary key.\n */\nexport function getPrimaryKeyType(\n pkType: 'Int' | 'BigInt' | 'Uuid' | 'String',\n driver: DatabaseDriver\n): SqlColumnType {\n switch (pkType) {\n case 'Int':\n return {\n type: driver === 'postgres' ? 'serial' : 'int',\n nullable: false,\n autoIncrement: driver !== 'postgres',\n unsigned: driver === 'mysql' || driver === 'mariadb',\n };\n case 'BigInt':\n return {\n type: driver === 'postgres' ? 'bigserial' : 'bigint',\n nullable: false,\n autoIncrement: driver !== 'postgres',\n unsigned: driver === 'mysql' || driver === 'mariadb',\n };\n case 'Uuid':\n return {\n type: driver === 'postgres' ? 'uuid' : 'char(36)',\n nullable: false,\n };\n case 'String':\n return {\n type: 'varchar(255)',\n nullable: false,\n };\n default:\n return {\n type: driver === 'postgres' ? 'bigserial' : 'bigint',\n nullable: false,\n autoIncrement: driver !== 'postgres',\n unsigned: driver === 'mysql' || driver === 'mariadb',\n };\n }\n}\n\n/**\n * Gets the SQL type for timestamp columns.\n */\nexport function getTimestampType(driver: DatabaseDriver): SqlColumnType {\n return {\n type: driver === 'postgres' ? 'timestamp' : 'timestamp',\n nullable: true,\n };\n}\n\n/**\n * Converts table name from PascalCase schema name.\n */\nexport function schemaNameToTableName(schemaName: string): string {\n // Convert PascalCase to snake_case and pluralize\n const snakeCase = schemaName\n .replace(/([A-Z])/g, '_$1')\n .toLowerCase()\n .replace(/^_/, '');\n\n // Simple pluralization\n if (snakeCase.endsWith('y')) {\n return snakeCase.slice(0, -1) + 'ies';\n } else if (\n snakeCase.endsWith('s') ||\n snakeCase.endsWith('x') ||\n snakeCase.endsWith('ch') ||\n snakeCase.endsWith('sh')\n ) {\n return snakeCase + 'es';\n } else {\n return snakeCase + 's';\n }\n}\n\n/**\n * Converts property name to column name.\n */\nexport function propertyNameToColumnName(propertyName: string): string {\n // Convert camelCase to snake_case\n return propertyName.replace(/([A-Z])/g, '_$1').toLowerCase();\n}\n","/**\n * @famgia/omnify-atlas - HCL Generator\n *\n * Generates Atlas HCL schema from Omnify schemas.\n */\n\nimport type { LoadedSchema, SchemaCollection, DatabaseDriver, BasePropertyDefinition } from '@famgia/omnify-types';\nimport type {\n HclSchema,\n HclTable,\n HclColumn,\n HclIndex,\n HclForeignKey,\n HclGenerationOptions,\n} from './types.js';\nimport {\n mapPropertyToSql,\n getPrimaryKeyType,\n getTimestampType,\n schemaNameToTableName,\n propertyNameToColumnName,\n} from './type-mapper.js';\n\n/**\n * Generates HCL table from a schema.\n */\nexport function generateHclTable(\n schema: LoadedSchema,\n allSchemas: SchemaCollection,\n driver: DatabaseDriver\n): HclTable {\n const tableName = schemaNameToTableName(schema.name);\n const columns: HclColumn[] = [];\n const indexes: HclIndex[] = [];\n const foreignKeys: HclForeignKey[] = [];\n\n // Primary key column\n const pkType = schema.options?.primaryKeyType ?? 'BigInt';\n columns.push({\n name: 'id',\n type: getPrimaryKeyType(pkType as 'Int' | 'BigInt' | 'Uuid' | 'String', driver),\n primaryKey: true,\n });\n\n // Process properties\n if (schema.properties) {\n for (const [propName, property] of Object.entries(schema.properties)) {\n // Skip associations - they're handled separately\n if (property.type === 'Association') {\n const assocProp = property as {\n relation?: string;\n target?: string;\n onDelete?: string;\n onUpdate?: string;\n };\n\n // Only create FK column for ManyToOne and OneToOne (owning side)\n if (assocProp.relation === 'ManyToOne' || assocProp.relation === 'OneToOne') {\n const columnName = propertyNameToColumnName(propName) + '_id';\n const targetSchema = assocProp.target ? allSchemas[assocProp.target] : undefined;\n const targetTable = assocProp.target\n ? schemaNameToTableName(assocProp.target)\n : 'unknown';\n\n // Get target PK type\n const targetPkType = targetSchema?.options?.primaryKeyType ?? 'BigInt';\n const fkType = getPrimaryKeyType(\n targetPkType as 'Int' | 'BigInt' | 'Uuid' | 'String',\n driver\n );\n\n // FK columns are nullable when the relation is optional\n const isNullable = assocProp.relation === 'ManyToOne';\n\n columns.push({\n name: columnName,\n type: {\n ...fkType,\n nullable: isNullable,\n autoIncrement: false,\n },\n });\n\n // Create foreign key constraint\n foreignKeys.push({\n name: `fk_${tableName}_${columnName}`,\n columns: [columnName],\n refTable: targetTable,\n refColumns: ['id'],\n onDelete: assocProp.onDelete ?? 'RESTRICT',\n onUpdate: assocProp.onUpdate ?? 'CASCADE',\n });\n\n // Create index for FK\n indexes.push({\n name: `idx_${tableName}_${columnName}`,\n columns: [columnName],\n });\n }\n\n continue;\n }\n\n // Regular column - cast to base property for common props\n const baseProp = property as BasePropertyDefinition;\n const columnName = propertyNameToColumnName(propName);\n const sqlType = mapPropertyToSql(property, driver);\n\n columns.push({\n name: columnName,\n type: sqlType,\n unique: baseProp.unique ?? false,\n });\n\n // Create unique index if needed\n if (baseProp.unique) {\n indexes.push({\n name: `idx_${tableName}_${columnName}_unique`,\n columns: [columnName],\n unique: true,\n });\n }\n }\n }\n\n // Timestamps\n if (schema.options?.timestamps !== false) {\n const timestampType = getTimestampType(driver);\n columns.push(\n { name: 'created_at', type: timestampType },\n { name: 'updated_at', type: timestampType }\n );\n }\n\n // Soft delete\n if (schema.options?.softDelete) {\n columns.push({\n name: 'deleted_at',\n type: getTimestampType(driver),\n });\n }\n\n // Custom indexes from options\n if (schema.options?.indexes) {\n for (const index of schema.options.indexes) {\n const indexColumns = index.columns.map(propertyNameToColumnName);\n indexes.push({\n name: index.name ?? `idx_${tableName}_${indexColumns.join('_')}`,\n columns: indexColumns,\n unique: index.unique ?? false,\n });\n }\n }\n\n // Unique constraints from options\n if (schema.options?.unique) {\n const uniqueConstraints = Array.isArray(schema.options.unique[0])\n ? (schema.options.unique as readonly (readonly string[])[])\n : [schema.options.unique as readonly string[]];\n\n for (const constraint of uniqueConstraints) {\n const constraintColumns = constraint.map(propertyNameToColumnName);\n indexes.push({\n name: `idx_${tableName}_${constraintColumns.join('_')}_unique`,\n columns: constraintColumns,\n unique: true,\n });\n }\n }\n\n return {\n name: tableName,\n columns,\n indexes,\n foreignKeys,\n };\n}\n\n/**\n * Generates complete HCL schema from schema collection.\n */\nexport function generateHclSchema(\n schemas: SchemaCollection,\n options: HclGenerationOptions\n): HclSchema {\n const tables: HclTable[] = [];\n\n for (const schema of Object.values(schemas)) {\n // Skip enum schemas - they don't create tables\n if (schema.kind === 'enum') {\n continue;\n }\n\n const table = generateHclTable(schema, schemas, options.driver);\n tables.push(table);\n }\n\n // Collect enums for PostgreSQL\n const enums = Object.values(schemas)\n .filter((s) => s.kind === 'enum')\n .map((s) => ({\n name: s.name.toLowerCase(),\n values: s.values ?? [],\n }));\n\n return {\n driver: options.driver,\n schemaName: options.schemaName,\n tables,\n enums,\n };\n}\n\n/**\n * Formats HCL column definition.\n */\nfunction formatHclColumn(column: HclColumn, driver: DatabaseDriver): string {\n const parts: string[] = [` column \"${column.name}\" {`];\n\n parts.push(` type = ${formatSqlType(column.type.type, driver)}`);\n\n if (column.type.nullable) {\n parts.push(' null = true');\n }\n\n if (column.type.default !== undefined) {\n parts.push(` default = ${column.type.default}`);\n }\n\n if (column.type.autoIncrement) {\n parts.push(' auto_increment = true');\n }\n\n if (column.type.unsigned && (driver === 'mysql' || driver === 'mariadb')) {\n parts.push(' unsigned = true');\n }\n\n parts.push(' }');\n return parts.join('\\n');\n}\n\n/**\n * Formats SQL type for HCL.\n */\nfunction formatSqlType(type: string, driver: DatabaseDriver): string {\n // Handle enum type\n if (type.startsWith('enum(')) {\n if (driver === 'mysql' || driver === 'mariadb') {\n return type;\n }\n return 'varchar(100)';\n }\n\n // Standard types\n return type;\n}\n\n/**\n * Formats HCL index definition.\n */\nfunction formatHclIndex(index: HclIndex): string {\n const columns = index.columns.map((c) => `\"${c}\"`).join(', ');\n const unique = index.unique ? 'unique = true\\n ' : '';\n\n return ` index \"${index.name}\" {\n columns = [${columns}]\n ${unique}}`;\n}\n\n/**\n * Formats HCL foreign key definition.\n */\nfunction formatHclForeignKey(fk: HclForeignKey): string {\n const columns = fk.columns.map((c) => `\"${c}\"`).join(', ');\n const refColumns = fk.refColumns.map((c) => `\"${c}\"`).join(', ');\n\n return ` foreign_key \"${fk.name}\" {\n columns = [${columns}]\n ref_columns = [${refColumns}]\n on_update = ${fk.onUpdate ?? 'CASCADE'}\n on_delete = ${fk.onDelete ?? 'RESTRICT'}\n }`;\n}\n\n/**\n * Renders HCL schema to string.\n */\nexport function renderHcl(schema: HclSchema): string {\n const lines: string[] = [];\n\n // Add schema block if named\n const schemaPrefix = schema.schemaName ? `schema \"${schema.schemaName}\" {\\n}\\n\\n` : '';\n lines.push(schemaPrefix);\n\n // Add tables\n for (const table of schema.tables) {\n lines.push(`table \"${table.name}\" {`);\n\n // Schema reference\n if (schema.schemaName) {\n lines.push(` schema = schema.${schema.schemaName}`);\n }\n\n // Columns\n for (const column of table.columns) {\n lines.push(formatHclColumn(column, schema.driver));\n }\n\n // Primary key\n const pkColumn = table.columns.find((c) => c.primaryKey);\n if (pkColumn) {\n lines.push(` primary_key {\n columns = [\"${pkColumn.name}\"]\n }`);\n }\n\n // Indexes\n for (const index of table.indexes) {\n lines.push(formatHclIndex(index));\n }\n\n // Foreign keys\n for (const fk of table.foreignKeys) {\n lines.push(formatHclForeignKey(fk));\n }\n\n lines.push('}\\n');\n }\n\n return lines.join('\\n');\n}\n","/**\n * @famgia/omnify-atlas - Atlas Runner\n *\n * Executes Atlas CLI commands via subprocess.\n */\n\nimport { execa } from 'execa';\nimport { mkdir, writeFile, rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { randomUUID } from 'node:crypto';\nimport type { DatabaseDriver } from '@famgia/omnify-types';\nimport { atlasError, atlasNotFoundError } from '@famgia/omnify-core';\nimport type {\n AtlasConfig,\n AtlasDiffOptions,\n AtlasResult,\n AtlasDiffResult,\n AtlasVersion,\n} from './types.js';\n\n/**\n * Default Atlas configuration.\n */\nconst DEFAULT_CONFIG: Partial<AtlasConfig> = {\n binaryPath: 'atlas',\n timeout: 60000, // 60 seconds\n};\n\n/**\n * Gets the Atlas schema URL for a driver.\n */\nfunction getSchemaUrl(_driver: DatabaseDriver, path: string): string {\n // Atlas uses file:// URLs for local HCL files\n return `file://${path}`;\n}\n\n/**\n * Gets the dev database URL format.\n */\nfunction normalizeDevUrl(devUrl: string, driver: DatabaseDriver): string {\n // Atlas uses specific URL formats per driver\n // mysql://user:pass@host:port/dbname\n // postgres://user:pass@host:port/dbname\n // sqlite://path/to/file.db\n\n // If using docker for dev database\n if (devUrl === 'docker') {\n switch (driver) {\n case 'mysql':\n return 'docker://mysql/8/dev';\n case 'mariadb':\n return 'docker://mariadb/latest/dev';\n case 'postgres':\n return 'docker://postgres/15/dev';\n default:\n return devUrl;\n }\n }\n\n return devUrl;\n}\n\n/**\n * Creates a temporary directory for Atlas operations.\n */\nasync function createTempDir(): Promise<string> {\n const tempPath = join(tmpdir(), `omnify-atlas-${randomUUID()}`);\n await mkdir(tempPath, { recursive: true });\n return tempPath;\n}\n\n/**\n * Executes an Atlas command.\n */\nasync function executeAtlas(\n config: AtlasConfig,\n args: string[]\n): Promise<AtlasResult> {\n const binaryPath = config.binaryPath ?? DEFAULT_CONFIG.binaryPath!;\n const timeout = config.timeout ?? DEFAULT_CONFIG.timeout!;\n const startTime = Date.now();\n\n try {\n const result = config.workDir\n ? await execa(binaryPath, args, {\n timeout,\n reject: false,\n cwd: config.workDir,\n })\n : await execa(binaryPath, args, {\n timeout,\n reject: false,\n });\n\n const stdout = typeof result.stdout === 'string' ? result.stdout : '';\n const stderr = typeof result.stderr === 'string' ? result.stderr : '';\n\n return {\n success: result.exitCode === 0,\n stdout,\n stderr,\n exitCode: result.exitCode ?? 0,\n duration: Date.now() - startTime,\n };\n } catch (error) {\n const err = error as Error & { code?: string };\n\n // Check if Atlas is not found\n if (err.code === 'ENOENT') {\n throw atlasNotFoundError();\n }\n\n throw atlasError(`Failed to execute Atlas: ${err.message}`, err);\n }\n}\n\n/**\n * Checks Atlas version and availability.\n */\nexport async function checkAtlasVersion(\n config: Partial<AtlasConfig> = {}\n): Promise<AtlasVersion> {\n const fullConfig: AtlasConfig = {\n ...DEFAULT_CONFIG,\n ...config,\n driver: config.driver ?? 'mysql',\n devUrl: config.devUrl ?? '',\n };\n\n try {\n const result = await executeAtlas(fullConfig, ['version']);\n\n if (result.success) {\n // Parse version from output like \"atlas version v0.14.0-...\"\n const match = result.stdout.match(/v?(\\d+\\.\\d+\\.\\d+)/);\n return {\n version: match?.[1] ?? result.stdout.trim(),\n available: true,\n };\n }\n\n return {\n version: '',\n available: false,\n };\n } catch {\n return {\n version: '',\n available: false,\n };\n }\n}\n\n/**\n * Runs Atlas schema diff.\n */\nexport async function runAtlasDiff(\n config: AtlasConfig,\n options: AtlasDiffOptions\n): Promise<AtlasDiffResult> {\n const devUrl = normalizeDevUrl(config.devUrl, config.driver);\n const toUrl = getSchemaUrl(config.driver, options.toPath);\n\n const args = [\n 'schema',\n 'diff',\n '--dev-url', devUrl,\n '--to', toUrl,\n '--format', '{{ sql . \" \" }}',\n ];\n\n // If we have a \"from\" schema, add it\n if (options.fromPath) {\n const fromUrl = getSchemaUrl(config.driver, options.fromPath);\n args.push('--from', fromUrl);\n }\n\n const result = await executeAtlas(config, args);\n\n // Check if there are changes\n const sql = result.stdout.trim();\n const hasChanges = sql.length > 0 && !sql.includes('-- No changes');\n\n return {\n ...result,\n hasChanges,\n sql: hasChanges ? sql : '',\n };\n}\n\n/**\n * Runs Atlas schema diff comparing two HCL strings.\n */\nexport async function diffHclSchemas(\n config: AtlasConfig,\n fromHcl: string | null,\n toHcl: string\n): Promise<AtlasDiffResult> {\n // Create temp directory for HCL files\n const tempDir = await createTempDir();\n\n try {\n const toPath = join(tempDir, 'to.hcl');\n await writeFile(toPath, toHcl, 'utf8');\n\n let fromPath: string | undefined;\n if (fromHcl) {\n fromPath = join(tempDir, 'from.hcl');\n await writeFile(fromPath, fromHcl, 'utf8');\n }\n\n return await runAtlasDiff(config, {\n fromPath,\n toPath,\n });\n } finally {\n // Clean up temp directory\n await rm(tempDir, { recursive: true, force: true });\n }\n}\n\n/**\n * Validates Atlas HCL schema.\n */\nexport async function validateHcl(\n config: AtlasConfig,\n hclPath: string\n): Promise<AtlasResult> {\n const devUrl = normalizeDevUrl(config.devUrl, config.driver);\n\n return executeAtlas(config, [\n 'schema',\n 'inspect',\n '--dev-url', devUrl,\n '--url', getSchemaUrl(config.driver, hclPath),\n '--format', '{{ sql . }}',\n ]);\n}\n\n/**\n * Applies schema changes to the dev database (for testing).\n */\nexport async function applySchema(\n config: AtlasConfig,\n hclPath: string\n): Promise<AtlasResult> {\n const devUrl = normalizeDevUrl(config.devUrl, config.driver);\n\n return executeAtlas(config, [\n 'schema',\n 'apply',\n '--dev-url', devUrl,\n '--to', getSchemaUrl(config.driver, hclPath),\n '--auto-approve',\n ]);\n}\n","/**\n * @famgia/omnify-atlas - Diff Parser\n *\n * Parses Atlas SQL diff output into structured format.\n */\n\nimport type {\n ParsedStatement,\n TableChange,\n DiffResult,\n DiffSummary,\n} from './types.js';\n\n/**\n * Regex patterns for parsing SQL statements.\n */\nconst PATTERNS = {\n createTable: /^CREATE TABLE\\s+[`\"]?(\\w+)[`\"]?/i,\n dropTable: /^DROP TABLE\\s+(?:IF EXISTS\\s+)?[`\"]?(\\w+)[`\"]?/i,\n alterTable: /^ALTER TABLE\\s+[`\"]?(\\w+)[`\"]?/i,\n addColumn: /ADD\\s+(?:COLUMN\\s+)?[`\"]?(\\w+)[`\"]?/i,\n dropColumn: /DROP\\s+(?:COLUMN\\s+)?[`\"]?(\\w+)[`\"]?/i,\n modifyColumn: /MODIFY\\s+(?:COLUMN\\s+)?[`\"]?(\\w+)[`\"]?/i,\n changeColumn: /CHANGE\\s+(?:COLUMN\\s+)?[`\"]?(\\w+)[`\"]?/i,\n alterColumn: /ALTER\\s+(?:COLUMN\\s+)?[`\"]?(\\w+)[`\"]?/i,\n createIndex: /^CREATE\\s+(?:UNIQUE\\s+)?INDEX\\s+[`\"]?(\\w+)[`\"]?\\s+ON\\s+[`\"]?(\\w+)[`\"]?/i,\n dropIndex: /^DROP\\s+INDEX\\s+[`\"]?(\\w+)[`\"]?(?:\\s+ON\\s+[`\"]?(\\w+)[`\"]?)?/i,\n addConstraint: /ADD\\s+CONSTRAINT\\s+[`\"]?(\\w+)[`\"]?/i,\n dropConstraint: /DROP\\s+CONSTRAINT\\s+[`\"]?(\\w+)[`\"]?/i,\n addForeignKey: /ADD\\s+(?:CONSTRAINT\\s+[`\"]?\\w+[`\"]?\\s+)?FOREIGN KEY/i,\n dropForeignKey: /DROP\\s+FOREIGN KEY\\s+[`\"]?(\\w+)[`\"]?/i,\n};\n\n\n/**\n * Splits SQL into individual statements.\n */\nfunction splitStatements(sql: string): string[] {\n // Split by semicolons, but handle edge cases\n const statements: string[] = [];\n let current = '';\n let inString = false;\n let stringChar = '';\n\n for (let i = 0; i < sql.length; i++) {\n const char = sql[i];\n\n // Track string literals\n if ((char === \"'\" || char === '\"') && sql[i - 1] !== '\\\\') {\n if (!inString) {\n inString = true;\n stringChar = char;\n } else if (char === stringChar) {\n inString = false;\n }\n }\n\n // Split on semicolons outside strings\n if (char === ';' && !inString) {\n const stmt = current.trim();\n if (stmt) {\n statements.push(stmt);\n }\n current = '';\n } else {\n current += char;\n }\n }\n\n // Add final statement\n const final = current.trim();\n if (final) {\n statements.push(final);\n }\n\n return statements;\n}\n\n/**\n * Parses a single SQL statement.\n */\nfunction parseStatement(sql: string): ParsedStatement {\n const trimmedSql = sql.trim();\n\n // CREATE TABLE\n let match = trimmedSql.match(PATTERNS.createTable);\n if (match && match[1]) {\n return {\n sql: trimmedSql,\n type: 'CREATE_TABLE',\n tableName: match[1],\n severity: 'safe',\n };\n }\n\n // DROP TABLE\n match = trimmedSql.match(PATTERNS.dropTable);\n if (match && match[1]) {\n return {\n sql: trimmedSql,\n type: 'DROP_TABLE',\n tableName: match[1],\n severity: 'destructive',\n };\n }\n\n // CREATE INDEX\n match = trimmedSql.match(PATTERNS.createIndex);\n if (match && match[1] && match[2]) {\n return {\n sql: trimmedSql,\n type: 'CREATE_INDEX',\n tableName: match[2],\n indexName: match[1],\n severity: 'safe',\n };\n }\n\n // DROP INDEX\n match = trimmedSql.match(PATTERNS.dropIndex);\n if (match && match[1]) {\n return {\n sql: trimmedSql,\n type: 'DROP_INDEX',\n tableName: match[2] ?? '',\n indexName: match[1],\n severity: 'warning',\n };\n }\n\n // ALTER TABLE\n match = trimmedSql.match(PATTERNS.alterTable);\n if (match && match[1]) {\n const tableName = match[1];\n const alterPart = trimmedSql.slice(match[0].length);\n\n // ADD COLUMN\n const addColMatch = alterPart.match(PATTERNS.addColumn);\n if (addColMatch && addColMatch[1]) {\n return {\n sql: trimmedSql,\n type: 'ADD_COLUMN',\n tableName,\n columnName: addColMatch[1],\n severity: 'safe',\n };\n }\n\n // DROP COLUMN\n const dropColMatch = alterPart.match(PATTERNS.dropColumn);\n if (dropColMatch && dropColMatch[1]) {\n return {\n sql: trimmedSql,\n type: 'DROP_COLUMN',\n tableName,\n columnName: dropColMatch[1],\n severity: 'destructive',\n };\n }\n\n // MODIFY COLUMN\n const modifyColMatch =\n alterPart.match(PATTERNS.modifyColumn) ||\n alterPart.match(PATTERNS.changeColumn) ||\n alterPart.match(PATTERNS.alterColumn);\n if (modifyColMatch && modifyColMatch[1]) {\n return {\n sql: trimmedSql,\n type: 'MODIFY_COLUMN',\n tableName,\n columnName: modifyColMatch[1],\n severity: 'warning',\n };\n }\n\n // ADD FOREIGN KEY\n if (PATTERNS.addForeignKey.test(alterPart)) {\n const constraintMatch = alterPart.match(PATTERNS.addConstraint);\n const fkConstraintName = constraintMatch?.[1];\n if (fkConstraintName) {\n return {\n sql: trimmedSql,\n type: 'ADD_FOREIGN_KEY',\n tableName,\n constraintName: fkConstraintName,\n severity: 'safe',\n };\n }\n // FK without explicit constraint name\n return {\n sql: trimmedSql,\n type: 'ADD_FOREIGN_KEY',\n tableName,\n severity: 'safe',\n };\n }\n\n // DROP FOREIGN KEY\n const dropFkMatch = alterPart.match(PATTERNS.dropForeignKey);\n if (dropFkMatch && dropFkMatch[1]) {\n return {\n sql: trimmedSql,\n type: 'DROP_FOREIGN_KEY',\n tableName,\n constraintName: dropFkMatch[1],\n severity: 'warning',\n };\n }\n\n // ADD CONSTRAINT\n const addConstraintMatch = alterPart.match(PATTERNS.addConstraint);\n if (addConstraintMatch && addConstraintMatch[1]) {\n return {\n sql: trimmedSql,\n type: 'ADD_CONSTRAINT',\n tableName,\n constraintName: addConstraintMatch[1],\n severity: 'safe',\n };\n }\n\n // DROP CONSTRAINT\n const dropConstraintMatch = alterPart.match(PATTERNS.dropConstraint);\n if (dropConstraintMatch && dropConstraintMatch[1]) {\n return {\n sql: trimmedSql,\n type: 'DROP_CONSTRAINT',\n tableName,\n constraintName: dropConstraintMatch[1],\n severity: 'warning',\n };\n }\n\n // Generic ALTER TABLE\n return {\n sql: trimmedSql,\n type: 'ALTER_TABLE',\n tableName,\n severity: 'warning',\n };\n }\n\n // Unknown statement\n return {\n sql: trimmedSql,\n type: 'UNKNOWN',\n tableName: '',\n severity: 'warning',\n };\n}\n\n/**\n * Creates a new empty table change entry.\n */\nfunction createEmptyTableChange(tableName: string): TableChange {\n return {\n tableName,\n isNew: false,\n isDropped: false,\n addedColumns: [],\n droppedColumns: [],\n modifiedColumns: [],\n addedIndexes: [],\n droppedIndexes: [],\n addedForeignKeys: [],\n droppedForeignKeys: [],\n };\n}\n\n/**\n * Gets or creates a table change entry.\n */\nfunction getOrCreateTable(\n tables: Record<string, TableChange>,\n tableName: string\n): TableChange {\n const existing = tables[tableName];\n if (existing) {\n return existing;\n }\n const newTable = createEmptyTableChange(tableName);\n tables[tableName] = newTable;\n return newTable;\n}\n\n/**\n * Groups statements by table.\n */\nfunction groupByTable(statements: ParsedStatement[]): Record<string, TableChange> {\n const tables: Record<string, TableChange> = {};\n\n for (const stmt of statements) {\n if (!stmt.tableName) continue;\n\n const table = getOrCreateTable(tables, stmt.tableName);\n\n switch (stmt.type) {\n case 'CREATE_TABLE':\n tables[stmt.tableName] = { ...table, isNew: true };\n break;\n case 'DROP_TABLE':\n tables[stmt.tableName] = { ...table, isDropped: true };\n break;\n case 'ADD_COLUMN':\n if (stmt.columnName) {\n tables[stmt.tableName] = {\n ...table,\n addedColumns: [...table.addedColumns, stmt.columnName],\n };\n }\n break;\n case 'DROP_COLUMN':\n if (stmt.columnName) {\n tables[stmt.tableName] = {\n ...table,\n droppedColumns: [...table.droppedColumns, stmt.columnName],\n };\n }\n break;\n case 'MODIFY_COLUMN':\n if (stmt.columnName) {\n tables[stmt.tableName] = {\n ...table,\n modifiedColumns: [...table.modifiedColumns, stmt.columnName],\n };\n }\n break;\n case 'CREATE_INDEX':\n if (stmt.indexName) {\n tables[stmt.tableName] = {\n ...table,\n addedIndexes: [...table.addedIndexes, stmt.indexName],\n };\n }\n break;\n case 'DROP_INDEX':\n if (stmt.indexName) {\n tables[stmt.tableName] = {\n ...table,\n droppedIndexes: [...table.droppedIndexes, stmt.indexName],\n };\n }\n break;\n case 'ADD_FOREIGN_KEY':\n tables[stmt.tableName] = {\n ...table,\n addedForeignKeys: [\n ...table.addedForeignKeys,\n stmt.constraintName ?? 'unnamed',\n ],\n };\n break;\n case 'DROP_FOREIGN_KEY':\n if (stmt.constraintName) {\n tables[stmt.tableName] = {\n ...table,\n droppedForeignKeys: [...table.droppedForeignKeys, stmt.constraintName],\n };\n }\n break;\n }\n }\n\n return tables;\n}\n\n/**\n * Calculates summary statistics.\n */\nfunction calculateSummary(statements: ParsedStatement[]): DiffSummary {\n return {\n totalStatements: statements.length,\n tablesCreated: statements.filter((s) => s.type === 'CREATE_TABLE').length,\n tablesDropped: statements.filter((s) => s.type === 'DROP_TABLE').length,\n tablesAltered: statements.filter((s) => s.type === 'ALTER_TABLE').length,\n columnsAdded: statements.filter((s) => s.type === 'ADD_COLUMN').length,\n columnsDropped: statements.filter((s) => s.type === 'DROP_COLUMN').length,\n columnsModified: statements.filter((s) => s.type === 'MODIFY_COLUMN').length,\n indexesAdded: statements.filter((s) => s.type === 'CREATE_INDEX').length,\n indexesDropped: statements.filter((s) => s.type === 'DROP_INDEX').length,\n foreignKeysAdded: statements.filter((s) => s.type === 'ADD_FOREIGN_KEY').length,\n foreignKeysDropped: statements.filter((s) => s.type === 'DROP_FOREIGN_KEY').length,\n };\n}\n\n/**\n * Parses Atlas SQL diff output.\n */\nexport function parseDiffOutput(sql: string): DiffResult {\n const trimmedSql = sql.trim();\n\n // Handle empty or no-change output\n if (!trimmedSql || trimmedSql === '-- No changes') {\n return {\n hasChanges: false,\n hasDestructiveChanges: false,\n statements: [],\n tableChanges: {},\n summary: {\n totalStatements: 0,\n tablesCreated: 0,\n tablesDropped: 0,\n tablesAltered: 0,\n columnsAdded: 0,\n columnsDropped: 0,\n columnsModified: 0,\n indexesAdded: 0,\n indexesDropped: 0,\n foreignKeysAdded: 0,\n foreignKeysDropped: 0,\n },\n rawSql: trimmedSql,\n };\n }\n\n // Filter out comments\n const sqlWithoutComments = trimmedSql\n .split('\\n')\n .filter((line) => !line.trim().startsWith('--'))\n .join('\\n');\n\n // Split and parse statements\n const rawStatements = splitStatements(sqlWithoutComments);\n const statements = rawStatements.map(parseStatement);\n\n // Check for destructive changes\n const hasDestructiveChanges = statements.some(\n (s) => s.severity === 'destructive'\n );\n\n return {\n hasChanges: statements.length > 0,\n hasDestructiveChanges,\n statements,\n tableChanges: groupByTable(statements),\n summary: calculateSummary(statements),\n rawSql: trimmedSql,\n };\n}\n\n/**\n * Formats diff result for display.\n */\nexport function formatDiffSummary(result: DiffResult): string {\n if (!result.hasChanges) {\n return 'No schema changes detected.';\n }\n\n const lines: string[] = ['Schema changes detected:'];\n const { summary } = result;\n\n if (summary.tablesCreated > 0) {\n lines.push(` + ${summary.tablesCreated} table(s) created`);\n }\n if (summary.tablesDropped > 0) {\n lines.push(` - ${summary.tablesDropped} table(s) dropped [DESTRUCTIVE]`);\n }\n if (summary.columnsAdded > 0) {\n lines.push(` + ${summary.columnsAdded} column(s) added`);\n }\n if (summary.columnsDropped > 0) {\n lines.push(` - ${summary.columnsDropped} column(s) dropped [DESTRUCTIVE]`);\n }\n if (summary.columnsModified > 0) {\n lines.push(` ~ ${summary.columnsModified} column(s) modified`);\n }\n if (summary.indexesAdded > 0) {\n lines.push(` + ${summary.indexesAdded} index(es) added`);\n }\n if (summary.indexesDropped > 0) {\n lines.push(` - ${summary.indexesDropped} index(es) dropped`);\n }\n if (summary.foreignKeysAdded > 0) {\n lines.push(` + ${summary.foreignKeysAdded} foreign key(s) added`);\n }\n if (summary.foreignKeysDropped > 0) {\n lines.push(` - ${summary.foreignKeysDropped} foreign key(s) dropped`);\n }\n\n lines.push('');\n lines.push(`Total: ${summary.totalStatements} statement(s)`);\n\n if (result.hasDestructiveChanges) {\n lines.push('');\n lines.push('WARNING: This diff contains destructive changes!');\n }\n\n return lines.join('\\n');\n}\n","/**\n * @famgia/omnify-atlas - Change Preview\n *\n * Generates human-readable change previews.\n */\n\nimport type { SchemaCollection } from '@famgia/omnify-types';\nimport type { AtlasConfig } from '../atlas/types.js';\nimport type { ChangePreview, PreviewOptions, PreviewFormat } from './types.js';\nimport {\n buildSchemaHashes,\n compareSchemas,\n readLockFile,\n LOCK_FILE_NAME,\n} from '../lock/index.js';\nimport { generateHclSchema, renderHcl } from '../hcl/index.js';\nimport { diffHclSchemas, checkAtlasVersion } from '../atlas/index.js';\nimport { parseDiffOutput, formatDiffSummary } from '../diff/index.js';\nimport { join } from 'node:path';\nimport { atlasNotFoundError } from '@famgia/omnify-core';\n\n/**\n * Generates a change preview for schemas.\n */\nexport async function generatePreview(\n schemas: SchemaCollection,\n atlasConfig: AtlasConfig,\n options: PreviewOptions = {}\n): Promise<ChangePreview> {\n // Check Atlas availability\n const atlasVersion = await checkAtlasVersion(atlasConfig);\n if (!atlasVersion.available) {\n throw atlasNotFoundError();\n }\n\n // Build current schema hashes\n const currentHashes = await buildSchemaHashes(schemas);\n\n // Read existing lock file\n const lockFilePath = join(atlasConfig.workDir ?? process.cwd(), LOCK_FILE_NAME);\n const existingLockFile = await readLockFile(lockFilePath);\n\n // Compare schema files\n const schemaChanges = compareSchemas(currentHashes, existingLockFile);\n\n // Generate current HCL\n const currentHcl = renderHcl(\n generateHclSchema(schemas, {\n driver: atlasConfig.driver,\n })\n );\n\n // Get previous HCL from lock file or empty\n let previousHcl: string | null = null;\n if (existingLockFile?.hclChecksum) {\n // For now, we regenerate from scratch each time\n // In production, we might cache the HCL\n previousHcl = null;\n }\n\n // Run Atlas diff\n const atlasDiff = await diffHclSchemas(atlasConfig, previousHcl, currentHcl);\n\n // Parse diff output\n const databaseChanges = parseDiffOutput(atlasDiff.sql);\n\n // Build summary\n const summary = buildSummary(schemaChanges, databaseChanges, options);\n\n return {\n hasChanges: schemaChanges.hasChanges || databaseChanges.hasChanges,\n hasDestructiveChanges: databaseChanges.hasDestructiveChanges,\n schemaChanges,\n databaseChanges,\n summary,\n sql: atlasDiff.sql,\n };\n}\n\n/**\n * Builds a human-readable summary.\n */\nfunction buildSummary(\n schemaChanges: { hasChanges: boolean; changes: readonly { schemaName: string; changeType: string }[] },\n databaseChanges: { hasChanges: boolean; hasDestructiveChanges: boolean; summary: { totalStatements: number } },\n options: PreviewOptions\n): string {\n const lines: string[] = [];\n\n if (!schemaChanges.hasChanges && !databaseChanges.hasChanges) {\n return 'No changes detected. Schema is up to date.';\n }\n\n // Schema file changes\n if (schemaChanges.hasChanges) {\n lines.push('Schema file changes:');\n for (const change of schemaChanges.changes) {\n const icon =\n change.changeType === 'added'\n ? '+'\n : change.changeType === 'removed'\n ? '-'\n : '~';\n lines.push(` ${icon} ${change.schemaName} (${change.changeType})`);\n }\n lines.push('');\n }\n\n // Database changes\n if (databaseChanges.hasChanges) {\n lines.push(formatDiffSummary(databaseChanges as any));\n }\n\n // Destructive warning\n if (options.warnDestructive && databaseChanges.hasDestructiveChanges) {\n lines.push('');\n lines.push('⚠️ WARNING: This preview contains destructive changes!');\n lines.push(' Review carefully before generating migrations.');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Previews changes without running Atlas (schema files only).\n */\nexport async function previewSchemaChanges(\n schemas: SchemaCollection,\n lockFilePath: string\n): Promise<{ hasChanges: boolean; changes: readonly { schemaName: string; changeType: string }[] }> {\n const currentHashes = await buildSchemaHashes(schemas);\n const existingLockFile = await readLockFile(lockFilePath);\n return compareSchemas(currentHashes, existingLockFile);\n}\n\n/**\n * Formats preview for display.\n */\nexport function formatPreview(\n preview: ChangePreview,\n format: PreviewFormat = 'text'\n): string {\n switch (format) {\n case 'json':\n return JSON.stringify(preview, null, 2);\n\n case 'minimal':\n if (!preview.hasChanges) {\n return 'No changes';\n }\n const parts: string[] = [];\n const { summary } = preview.databaseChanges;\n if (summary.tablesCreated > 0) parts.push(`+${summary.tablesCreated} tables`);\n if (summary.tablesDropped > 0) parts.push(`-${summary.tablesDropped} tables`);\n if (summary.columnsAdded > 0) parts.push(`+${summary.columnsAdded} columns`);\n if (summary.columnsDropped > 0) parts.push(`-${summary.columnsDropped} columns`);\n return parts.join(', ') || 'Changes detected';\n\n case 'text':\n default:\n return preview.summary;\n }\n}\n\n/**\n * Checks if preview has blocking issues.\n */\nexport function hasBlockingIssues(_preview: ChangePreview): boolean {\n // Currently, we don't block on any issues\n // This could be extended to check for specific conditions\n return false;\n}\n"],"mappings":"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","names":["columnName","writeFile","join","atlasNotFoundError"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@famgia/omnify-atlas",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Atlas CLI integration for omnify-schema",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"execa": "^9.6.1",
|
|
21
|
+
"@famgia/omnify-core": "0.0.1",
|
|
22
|
+
"@famgia/omnify-types": "0.0.1"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsup",
|
|
26
|
+
"clean": "rm -rf dist",
|
|
27
|
+
"test": "vitest run --passWithNoTests",
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"lint": "eslint src"
|
|
30
|
+
}
|
|
31
|
+
}
|