limgen
Version:
Infrastructure as Code generator
173 lines (172 loc) • 8.67 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
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.delay = exports.collectFrameworkInputs = exports.collectProjectInputs = exports.getProjectType = exports.init = exports.initOptionsSchema = void 0;
const zod_1 = __importDefault(require("zod"));
const commander_1 = require("commander");
const prompts_1 = __importDefault(require("prompts"));
const path_1 = __importStar(require("path"));
const framework_1 = require("../framework");
const project_1 = require("../project");
const workspace_1 = require("../workspace");
const cli_helpers_1 = require("../cli-helpers");
exports.initOptionsSchema = zod_1.default.object({
directory: zod_1.default.string().optional().default(process.cwd()),
name: zod_1.default.string().optional(),
framework: zod_1.default.string().optional(),
projectType: zod_1.default.enum(project_1.AllProjectTypes).optional(),
});
exports.init = new commander_1.Command()
.name('init')
.allowUnknownOption(true)
.description('Initialize a new infrastructure project')
.option('-d, --directory <directory>', 'Directory where the infrastructure folder should be added', process.cwd())
.option('-n, --name <name>', 'Name of the project')
.option('-t, --projectType <type>', 'Type of project to create')
.option('-f, --framework <framework>', 'Framework to use')
.action((options) => __awaiter(void 0, void 0, void 0, function* () {
const cmdArgs = exports.initOptionsSchema.parse(options);
if (cmdArgs.directory) {
process.chdir(cmdArgs.directory);
}
let frameworkType = cmdArgs.framework;
if (!frameworkType) {
frameworkType = yield (0, framework_1.detectFramework)();
}
yield (0, workspace_1.renderWorkspace)();
const projectType = yield getProjectType(cmdArgs);
const project = yield (0, project_1.importProjectType)(projectType);
const projectInputs = yield collectProjectInputs(project, cmdArgs, projectType, frameworkType);
const projectSpinner = (0, cli_helpers_1.spinner)(`${(0, cli_helpers_1.bold)('Initializing project')} …`).start();
yield (0, project_1.renderProject)(cmdArgs, project, projectInputs);
projectSpinner.succeed();
if (framework_1.AllFrameworkTypes.includes(frameworkType) && frameworkType !== 'unknown') {
const frameworkSpinner = (0, cli_helpers_1.spinner)(`${(0, cli_helpers_1.bold)('Intializing framework')} ${(0, cli_helpers_1.colorize)('yellow', frameworkType)} …`).start();
const framework = yield (0, framework_1.importFramework)(frameworkType);
const frameworkInputs = yield collectFrameworkInputs(framework, cmdArgs, projectInputs);
yield (0, framework_1.renderFramework)(cmdArgs, framework, frameworkInputs);
frameworkSpinner.succeed();
}
const cmdToRun = `(cd ${path_1.default.join('infrastructure', 'projects', projectInputs.projectName)} && pulumi up)`;
yield animateTyping(`Project ${(0, cli_helpers_1.colorize)('cyan', projectInputs.projectName)} initialized successfully!`);
yield (0, exports.delay)(500);
yield animateTyping(`To deploy your resources, run ${(0, cli_helpers_1.bold)(cmdToRun)}\n`);
}));
function getProjectType(cmdArgs) {
return __awaiter(this, void 0, void 0, function* () {
if (cmdArgs.projectType) {
return cmdArgs.projectType;
}
const answer = yield (0, prompts_1.default)({
type: 'select',
name: 'projectType',
message: 'Select a project type',
choices: project_1.AllProjectTypes.map((type) => ({ title: type, value: type })),
});
return answer.projectType;
});
}
exports.getProjectType = getProjectType;
function collectProjectInputs(project, cmdArgs, projectType, framework) {
return __awaiter(this, void 0, void 0, function* () {
const projectInput = yield project.inputs(cmdArgs);
const schema = projectInput.reduce((acc, opt) => {
acc[opt.name] = opt.schema;
return acc;
}, {});
const processArgs = (0, cli_helpers_1.parseProcessArgs)();
for (const opt of projectInput) {
if (processArgs[opt.name] === undefined) {
processArgs[opt.name] = 'unknown';
}
}
let projectName = cmdArgs.name;
if (!projectName) {
const result = yield (0, prompts_1.default)({
type: 'text',
name: 'projectName',
message: 'Enter a project name',
initial: `${(0, path_1.basename)(cmdArgs.directory)}-${projectType}${framework !== 'unknown' ? '-' + framework : ''}`,
});
projectName = result.projectName;
}
const projectArgs = zod_1.default.object(schema).parse(processArgs);
const inputs = yield project.collectInput(cmdArgs, projectArgs);
return Object.assign({ projectName,
projectType }, inputs);
});
}
exports.collectProjectInputs = collectProjectInputs;
function collectFrameworkInputs(framework, cmdArgs, projectInput) {
return __awaiter(this, void 0, void 0, function* () {
const frameworkInput = yield framework.inputs(cmdArgs, projectInput);
const schema = frameworkInput.reduce((acc, opt) => {
acc[opt.name] = opt.schema;
return acc;
}, {});
const processArgs = (0, cli_helpers_1.parseProcessArgs)();
for (const opt of frameworkInput) {
if (processArgs[opt.name] === undefined) {
processArgs[opt.name] = 'unknown';
}
}
const frameworkArgs = zod_1.default.object(schema).parse(processArgs);
const inputs = yield framework.collectInput(cmdArgs, projectInput, frameworkArgs);
return inputs;
});
}
exports.collectFrameworkInputs = collectFrameworkInputs;
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
exports.delay = delay;
const animateTyping = (message) => __awaiter(void 0, void 0, void 0, function* () {
// only log if we are in a TTY
if (!process.stdout.isTTY) {
process.stdout.write(`${message}\n`);
return;
}
const minDelay = 10; // Minimum delay between "keypresses" in milliseconds
const maxDelay = 45; // Maximum delay between "keypresses" in milliseconds
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
process.stdout.write("\n");
for (let i = 0; i < message.length; i++) {
const char = message[i];
process.stdout.write(char); // Print one character at a time
const randomDelay = Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
yield delay(randomDelay);
}
process.stdout.write("\n"); // Move to the next line after completing the animation
});