wwwlayermeshusa/fix-migration.mjs
2026-03-10 09:54:58 +01:00

88 lines
4.1 KiB
JavaScript

/**
* fix-migration.mjs (v2)
*
* Run from your project root:
* node fix-migration.mjs
*
* What it does:
* 1. Deletes the broken migration file (the newest one)
* 2. Removes it from migrations/index.ts
* 3. Writes a cleanup-orphaned-types.sql file to your project root
* 4. Tells you exactly what to run next
*/
import { readFileSync, writeFileSync, unlinkSync, readdirSync, statSync } from 'fs'
import { join } from 'path'
const MIGRATIONS_DIR = './src/migrations'
// ── Find the newest migration .ts file ───────────────────────────────────────
const tsFiles = readdirSync(MIGRATIONS_DIR)
.filter(f => f.endsWith('.ts') && f !== 'index.ts')
.map(f => ({ name: f, mtime: statSync(join(MIGRATIONS_DIR, f)).mtime }))
.sort((a, b) => b.mtime - a.mtime)
if (tsFiles.length === 0) {
console.error('❌ No migration files found in', MIGRATIONS_DIR)
process.exit(1)
}
const migrationName = tsFiles[0].name.replace('.ts', '')
const newestTs = join(MIGRATIONS_DIR, tsFiles[0].name)
const newestJson = newestTs.replace('.ts', '.json')
console.log(`\n🗑️ Deleting broken migration: ${tsFiles[0].name}`)
try { unlinkSync(newestTs); console.log(` ✅ deleted .ts`) } catch(e) { console.log(` ⚠️ .ts: ${e.message}`) }
try { unlinkSync(newestJson); console.log(` ✅ deleted .json`) } catch(e) { console.log(` (no .json found)`) }
// ── Remove from migrations/index.ts ──────────────────────────────────────────
const indexPath = join(MIGRATIONS_DIR, 'index.ts')
let indexSrc = readFileSync(indexPath, 'utf8')
// Remove any line that references this migration name
const safeRef = migrationName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
indexSrc = indexSrc.replace(new RegExp(`^.*${safeRef}.*\\n`, 'gm'), '')
writeFileSync(indexPath, indexSrc, 'utf8')
console.log(` ✅ removed from migrations/index.ts`)
// ── Write cleanup SQL ─────────────────────────────────────────────────────────
const cleanupSql = `-- cleanup-orphaned-types.sql
-- Run this against your database BEFORE regenerating the migration.
-- Safe to run — all statements use IF EXISTS.
-- Orphaned enum types from failed migration attempts
DROP TYPE IF EXISTS "public"."enum_pages_blocks_lm_product_detail_section_background" CASCADE;
DROP TYPE IF EXISTS "public"."enum__pages_v_blocks_lm_product_detail_section_background" CASCADE;
DROP TYPE IF EXISTS "public"."enum_pages_blocks_lm_service_cards_cards_icon_slug" CASCADE;
DROP TYPE IF EXISTS "public"."enum__pages_v_blocks_lm_service_cards_cards_icon_slug" CASCADE;
-- Orphaned tables (if partially created)
DROP TABLE IF EXISTS "public"."_pages_v_blocks_lm_product_detail_locales" CASCADE;
DROP TABLE IF EXISTS "public"."_pages_v_blocks_lm_product_detail" CASCADE;
DROP TABLE IF EXISTS "public"."pages_blocks_lm_product_detail_locales" CASCADE;
DROP TABLE IF EXISTS "public"."pages_blocks_lm_product_detail" CASCADE;
-- Orphaned columns added to service_cards (will be re-added by fresh migration)
ALTER TABLE IF EXISTS "public"."pages_blocks_lm_service_cards_cards" DROP COLUMN IF EXISTS "icon_slug";
ALTER TABLE IF EXISTS "public"."pages_blocks_lm_service_cards_cards_locales" DROP COLUMN IF EXISTS "eyebrow";
ALTER TABLE IF EXISTS "public"."_pages_v_blocks_lm_service_cards_cards" DROP COLUMN IF EXISTS "icon_slug";
ALTER TABLE IF EXISTS "public"."_pages_v_blocks_lm_service_cards_cards_locales" DROP COLUMN IF EXISTS "eyebrow";
`
writeFileSync('./cleanup-orphaned-types.sql', cleanupSql, 'utf8')
console.log(`\n📄 Generated: cleanup-orphaned-types.sql`)
console.log(`
${'─'.repeat(60)}
👉 Run these 3 commands in order:
1. psql $DATABASE_URI -f cleanup-orphaned-types.sql
(or open cleanup-orphaned-types.sql in TablePlus /
Postico / any DB GUI and run it as a query)
2. pnpm payload migrate:create
3. pnpm payload migrate
${'─'.repeat(60)}
`)