UNPKG

@limlabs/limo

Version:

Infrastructure as Code generator

178 lines (177 loc) 7.26 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.getInputPrompts = exports.parseInputSchema = exports.BaseTemplate = void 0; const zod_1 = __importDefault(require("zod")); const yaml_1 = require("./yaml"); const node_fs_1 = require("node:fs"); class BaseTemplate { constructor(name, directory, resourceGroupType, dirname = __dirname) { this.scripts = {}; this.name = name; this.directory = directory; this.resourceGroupType = resourceGroupType; this.data = {}; const templatePath = `${dirname}/template.yaml`; if ((0, node_fs_1.existsSync)(templatePath)) { this.inputSchema = parseInputSchema((0, node_fs_1.readFileSync)(templatePath, "utf-8")); } } collectInputs(inputs) { return __awaiter(this, void 0, void 0, function* () { if (typeof this.inputSchema === "undefined") { throw new Error("Error parsing input schema"); } this.data = this.inputSchema.parse(inputs); }); } dependsOn() { return __awaiter(this, void 0, void 0, function* () { return { files: [], packages: [] }; }); } generate() { return __awaiter(this, void 0, void 0, function* () { throw new Error("Method not implemented."); }); } destroy() { return __awaiter(this, void 0, void 0, function* () { throw new Error("Method not implemented."); }); } envPull(options) { return __awaiter(this, void 0, void 0, function* () { throw new Error("Method not implemented."); }); } } exports.BaseTemplate = BaseTemplate; BaseTemplate.resourceGroupsSupported = []; function parseInputSchema(template) { const data = (0, yaml_1.parseYaml)(template); if (!data || typeof data !== "object") { return; } if (!data["inputs"] || !Array.isArray(data["inputs"])) { return; } const inputSchema = zod_1.default.object({ name: zod_1.default.string(), description: zod_1.default.string(), required: zod_1.default.boolean().optional().default(false), default: zod_1.default.any().optional(), type: zod_1.default.enum(["text", "number", "bool", "choice"]), choices: zod_1.default .array(zod_1.default.object({ name: zod_1.default.string(), value: zod_1.default.string() })) .optional() }); const inputs = data.inputs.map((input) => { return inputSchema.parse(input); }); let resultSchema = zod_1.default.object({}); inputs.forEach((input) => { var _a; let type; switch (input.type) { case "text": type = input.required ? zod_1.default.string() : zod_1.default.string().optional(); if (input.default) { type = type.default(input.default); } break; case "number": type = input.required ? zod_1.default.number() : zod_1.default.number().optional(); if (input.default) { type = type.default(input.default); } break; case "bool": type = input.required ? zod_1.default.boolean() : zod_1.default.boolean().optional(); if (input.default) { type = type.default(input.default); } break; case "choice": if (!input.choices) { throw new Error("Choice input must have choices"); } const choices = input.choices.map((choice) => choice.value); // @ts-ignore - allow enums from dynamic string array type = zod_1.default.enum(choices); if (!input.required) { type = type.optional(); } if (input.default) { type = type.default(input.default); } break; } type = type.describe((_a = input.description) !== null && _a !== void 0 ? _a : "unknown"); const newSchema = { [input.name]: type }; resultSchema = resultSchema.merge(zod_1.default.object(newSchema)); }); return resultSchema; } exports.parseInputSchema = parseInputSchema; function getInputPrompts(schema) { return __awaiter(this, void 0, void 0, function* () { // loop over properties in schema and prompt user for input const allPrompts = Object.keys(schema.shape).map((key) => { const shape = schema.shape; const prop = shape[key]; let type = prop._def.typeName; let propChoices = []; let defaultValue = type === "ZodString" ? "" : type === "ZodNumber" ? -1 : false; if (type === "ZodEnum") { propChoices = prop._def.values; } if (type === "ZodOptional" || type === "ZodDefault") { if (type === "ZodDefault") { defaultValue = prop._def.defaultValue(); } type = prop._def.innerType._def.typeName; if (type === "ZodEnum") { propChoices = prop._def.innerType._def.values; } } if (type === "ZodEnum" && propChoices.length > 0 && defaultValue) { defaultValue = propChoices.indexOf(defaultValue); } let promptType = type === "ZodString" ? "text" : type === "ZodNumber" ? "number" : "confirm"; if (type === "ZodEnum") { promptType = "select"; } const choices = promptType === "select" ? { choices: propChoices.map((value) => { return { title: value, value: value }; }) } : {}; const initialValue = !defaultValue ? {} : { initial: defaultValue }; const result = Object.assign(Object.assign({ type: promptType, name: key, message: prop._def.description }, initialValue), choices); return result; }); return allPrompts; }); } exports.getInputPrompts = getInputPrompts;