UNPKG

@limlabs/limo

Version:

Infrastructure as Code generator

138 lines (137 loc) 6.49 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateMigrationHistory = exports.getUnappliedMigrations = exports.getMigrationFiles = exports.getMigrationHistory = exports.ensureMigrations = exports.exportMigration = exports.parseMigration = exports.migrationSchema = exports.extraOptionTypes = exports.codeModTypes = exports.operationTypes = void 0; const js_yaml_1 = __importDefault(require("js-yaml")); const zod_1 = __importDefault(require("zod")); const path_1 = __importDefault(require("path")); const fs_1 = require("fs"); const promises_1 = require("fs/promises"); const yaml_1 = require("../yaml"); const process_1 = require("process"); exports.operationTypes = [ "addComponents", "removeComponents", "installComponents", "addInstance", "removeInstance", "initResourceGroup", "removeResourceGroup", "applyResourceGroupChanges", "undoResourceGroupChanges", "configureFramework", "runCodeMod" ]; exports.codeModTypes = ["configureNext"]; exports.extraOptionTypes = [...exports.codeModTypes]; exports.migrationSchema = zod_1.default.object({ id: zod_1.default.string(), up: zod_1.default.array(zod_1.default.object({ type: zod_1.default.enum(exports.operationTypes), options: zod_1.default .object({ type: zod_1.default.enum(exports.extraOptionTypes).optional(), args: zod_1.default.record(zod_1.default.string(), zod_1.default.string().or(zod_1.default.record(zod_1.default.string(), zod_1.default.any()))) }) .optional() })), down: zod_1.default .array(zod_1.default.object({ type: zod_1.default.enum(exports.operationTypes), options: zod_1.default .object({ type: zod_1.default.enum(exports.extraOptionTypes).optional(), args: zod_1.default.record(zod_1.default.string(), zod_1.default.string().or(zod_1.default.record(zod_1.default.string(), zod_1.default.any()))) }) .optional() })) .optional() }); const parseMigration = (yamlString) => { const base = js_yaml_1.default.load(yamlString); const parsed = exports.migrationSchema.safeParse(base); if (!parsed.success) { throw new Error(parsed.error.errors.join(", ")); } return parsed.data; }; exports.parseMigration = parseMigration; const exportMigration = (migration, path) => __awaiter(void 0, void 0, void 0, function* () { const migrationHistory = yield getMigrationHistory(); if (migrationHistory.migrations.includes(migration.id)) { throw new Error(`Migration ${migration.id} already exists`); } const newMigration = (0, yaml_1.jsonToYaml)(migration); yield (0, promises_1.writeFile)(path, newMigration); }); exports.exportMigration = exportMigration; function ensureMigrations() { return __awaiter(this, void 0, void 0, function* () { yield (0, promises_1.mkdir)(path_1.default.join("infrastructure", "migrations"), { recursive: true }); const historyPath = path_1.default.join("infrastructure", "migrations", "history.yaml"); if (!(0, fs_1.existsSync)(historyPath)) { yield (0, promises_1.writeFile)(historyPath, (0, yaml_1.jsonToYaml)({ migrations: [] })); } }); } exports.ensureMigrations = ensureMigrations; function getMigrationHistory() { return __awaiter(this, void 0, void 0, function* () { const historyPath = path_1.default.join("infrastructure", "migrations", "history.yaml"); const history = yield (0, promises_1.readFile)(historyPath, "utf8"); const yamlHistory = (0, yaml_1.parseYaml)(history); return yamlHistory; }); } exports.getMigrationHistory = getMigrationHistory; function getMigrationFiles() { return __awaiter(this, void 0, void 0, function* () { const migrationsPath = path_1.default.join("infrastructure", "migrations"); const files = yield (0, promises_1.readdir)(migrationsPath); return files.filter((file) => file.endsWith(".yaml") && !file.endsWith("history.yaml")); }); } exports.getMigrationFiles = getMigrationFiles; function getUnappliedMigrations() { return __awaiter(this, void 0, void 0, function* () { const history = yield getMigrationHistory(); const migrationFiles = (yield getMigrationFiles()).sort(); const migrationPath = path_1.default.join((0, process_1.cwd)(), "infrastructure", "migrations"); const migrations = migrationFiles.map((file) => { const migrationYaml = (0, fs_1.readFileSync)(path_1.default.join(migrationPath, file), "utf-8"); return (0, exports.parseMigration)(migrationYaml); }); return migrations.filter((migration) => !history.migrations.includes(migration.id)); }); } exports.getUnappliedMigrations = getUnappliedMigrations; function updateMigrationHistory(migrationId, apply = true) { return __awaiter(this, void 0, void 0, function* () { const historyPath = path_1.default.join("infrastructure", "migrations", "history.yaml"); const history = yield getMigrationHistory(); if (history.migrations.includes(migrationId)) { if (apply) { throw new Error(`Migration ${migrationId} already applied`); } history.migrations = history.migrations.filter((id) => id !== migrationId); } else { history.migrations.push(migrationId); } yield (0, promises_1.writeFile)(historyPath, (0, yaml_1.jsonToYaml)(history)); }); } exports.updateMigrationHistory = updateMigrationHistory;