Files
payload/packages/db-mongodb/src/createMigration.ts

75 lines
2.4 KiB
TypeScript

/* eslint-disable no-restricted-syntax, no-await-in-loop */
import type { CreateMigration } from 'payload/database'
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
const migrationTemplate = (upSQL?: string, downSQL?: string) => `import {
MigrateUpArgs,
MigrateDownArgs,
} from "@payloadcms/db-mongodb";
export async function up({ payload }: MigrateUpArgs): Promise<void> {
${upSQL ?? ` // Migration code`}
};
export async function down({ payload }: MigrateDownArgs): Promise<void> {
${downSQL ?? ` // Migration code`}
};
`
export const createMigration: CreateMigration = async function createMigration({
file,
migrationName,
payload,
}) {
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
const dir = payload.db.migrationDir
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir)
}
let migrationFileContent: string | undefined
// Check for predefined migration.
// Either passed in via --file or prefixed with @payloadcms/db-mongodb/
if (file || migrationName?.startsWith('@payloadcms/db-mongodb/')) {
if (!file) file = migrationName
const predefinedMigrationName = file.replace('@payloadcms/db-mongodb/', '')
migrationName = predefinedMigrationName
const cleanPath = path.join(dirname, `../predefinedMigrations/${predefinedMigrationName}.js`)
// Check if predefined migration exists
if (fs.existsSync(cleanPath)) {
let migration = await eval(`${require ? 'require' : 'import'}(${cleanPath})`)
if ('default' in migration) migration = migration.default
const { down, up } = migration
migrationFileContent = migrationTemplate(up, down)
} else {
payload.logger.error({
msg: `Canned migration ${predefinedMigrationName} not found.`,
})
process.exit(1)
}
} else {
migrationFileContent = migrationTemplate()
}
const [yyymmdd, hhmmss] = new Date().toISOString().split('T')
const formattedDate = yyymmdd.replace(/\D/g, '')
const formattedTime = hhmmss.split('.')[0].replace(/\D/g, '')
const timestamp = `${formattedDate}_${formattedTime}`
const formattedName = migrationName?.replace(/\W/g, '_')
const fileName = migrationName ? `${timestamp}_${formattedName}.ts` : `${timestamp}_migration.ts`
const filePath = `${dir}/${fileName}`
fs.writeFileSync(filePath, migrationFileContent)
payload.logger.info({ msg: `Migration created at ${filePath}` })
}