UNPKG

@expressots/cli

Version:

Expressots CLI - modern, fast, lightweight nodejs web framework (@cli)

238 lines (237 loc) 8.11 kB
"use strict"; 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.runCommand = exports.prodCommand = exports.buildCommand = exports.devCommand = void 0; const child_process_1 = require("child_process"); const fs_1 = require("fs"); const os_1 = __importDefault(require("os")); const path_1 = __importStar(require("path")); const cli_ui_1 = require("../utils/cli-ui"); const compiler_1 = __importDefault(require("../utils/compiler")); /** * Helper function to load and extract outDir from tsconfig.build.json */ function getOutDir() { const tsconfigBuildPath = (0, path_1.join)(process.cwd(), "tsconfig.build.json"); if (!(0, fs_1.existsSync)(tsconfigBuildPath)) { (0, cli_ui_1.printError)("Cannot find tsconfig.build.json. Please create one in the root directory", "tsconfig-build-path"); process.exit(1); } const tsconfig = JSON.parse((0, fs_1.readFileSync)(tsconfigBuildPath, "utf-8")); const outDir = tsconfig.compilerOptions.outDir; if (!outDir) { (0, cli_ui_1.printError)("Cannot find outDir in tsconfig.build.json. Please provide an outDir.", "tsconfig-build-path"); process.exit(1); } if (!(0, fs_1.existsSync)(outDir)) { (0, fs_1.mkdirSync)(outDir, { recursive: true }); (0, cli_ui_1.printSuccess)(`Created outDir: ${outDir}`, "outdir-creation"); } return outDir; } /** * Load the configuration from the compiler * @param compiler The compiler to load the configuration from * @returns The configuration */ async function opinionatedConfig() { const { entryPoint } = await compiler_1.default.loadConfig(); const config = [ "--watch", "-r", "tsconfig-paths/register", `./src/${entryPoint}.ts`, ]; return config; } /** * Load the configuration from the compiler * @param compiler The compiler to load the configuration from * @returns The configuration */ async function nonOpinionatedConfig() { const { entryPoint } = await compiler_1.default.loadConfig(); const config = ["--watch", `./src/${entryPoint}.ts`]; return config; } /** * Dev command module * @type {CommandModule<object, object>} * @returns The command module */ exports.devCommand = { command: "dev", describe: "Start development server.", handler: async () => { await (0, exports.runCommand)({ command: "dev" }); }, }; /** * Build command module * @type {CommandModule<object, object>} * @returns The command module */ exports.buildCommand = { command: "build", describe: "Build the project.", handler: async () => { await (0, exports.runCommand)({ command: "build" }); }, }; /** * Prod command module * @type {CommandModule<object, object>} * @returns The command module */ exports.prodCommand = { command: "prod", describe: "Run in production mode.", handler: async () => { await (0, exports.runCommand)({ command: "prod" }); }, }; /** * Helper function to execute a command * @param command The command to execute * @param args The arguments to pass to the command * @param cwd The current working directory to execute the command in * @returns A promise that resolves when the command completes successfully */ function execCmd(command, args, cwd = process.cwd()) { return new Promise((resolve, reject) => { const proc = (0, child_process_1.spawn)(command, args, { stdio: "inherit", shell: true, cwd, }); proc.on("close", (code) => { if (code === 0) { resolve(); } else { reject(new Error(`Command failed with code ${code}`)); } }); }); } /** * Helper function to clean the dist directory */ const cleanDist = async (outDir) => { await fs_1.promises.rm(outDir, { recursive: true, force: true }); (0, cli_ui_1.printSuccess)(`Clean ${outDir} directory`, "clean-dist"); }; /** * Helper function to compile TypeScript */ const compileTypescript = async () => { await execCmd("npx", ["tsc", "-p", "tsconfig.build.json"]); (0, cli_ui_1.printSuccess)("Built successfully", "compile-typescript"); }; /** * Helper function to copy files to the dist directory */ const copyFiles = async (outDir) => { const { opinionated } = await compiler_1.default.loadConfig(); let filesToCopy = []; if (opinionated) { filesToCopy = [ "./register-path.js", "tsconfig.build.json", "package.json", ]; } else { filesToCopy = ["tsconfig.json", "package.json"]; } filesToCopy.forEach((file) => { fs_1.promises.copyFile(file, (0, path_1.join)(outDir, path_1.default.basename(file))); }); }; /** * Helper function to clear the screen */ const clearScreen = () => { const platform = os_1.default.platform(); const command = platform === "win32" ? "cls" : "clear"; (0, child_process_1.spawn)(command, { stdio: "inherit", shell: true }); }; /** * Helper function to run a command * @param command The command to run */ const runCommand = async ({ command, }) => { const { opinionated, entryPoint } = await compiler_1.default.loadConfig(); const outDir = getOutDir(); try { switch (command) { case "dev": execCmd("tsx", opinionated ? await opinionatedConfig() : await nonOpinionatedConfig()); break; case "build": if (!outDir) { (0, cli_ui_1.printError)("Cannot build project. Please provide an outDir in tsconfig.build.json", "build-command"); process.exit(1); } await cleanDist(outDir); await compileTypescript(); await copyFiles(outDir); break; case "prod": { if (!outDir) { (0, cli_ui_1.printError)("Cannot run in prod mode. Please provide an outDir in tsconfig.build.json", "prod-command"); process.exit(1); } let config = []; if (opinionated) { config = [ "-r", `./${outDir}/register-path.js`, `./${outDir}/src/${entryPoint}.js`, ]; } else { config = [`./${outDir}/${entryPoint}.js`]; } clearScreen(); execCmd("node", config); break; } default: (0, cli_ui_1.printError)(`Unknown command: `, command); break; } } catch (error) { (0, cli_ui_1.printError)("Error executing command:", error.message); process.exit(1); } }; exports.runCommand = runCommand;