diff --git a/package.json b/package.json index b4aa502..0be09dc 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ }, "dependencies": { "@expressots/boost-ts": "1.1.1", + "@expressots/cli": "file:expressots-cli-1.8.0.tgz", "chalk-animation": "2.0.3", "cli-progress": "3.11.2", "cli-table3": "^0.6.4", @@ -57,6 +58,7 @@ "glob": "10.2.6", "inquirer": "8.0.0", "mustache": "4.2.0", + "semver": "^7.6.2", "ts-node": "10.9.1", "yargs": "17.6.2" }, @@ -70,7 +72,7 @@ "@types/degit": "2.8.3", "@types/inquirer": "9.0.3", "@types/mustache": "4.2.2", - "@types/node": "20.12.7", + "@types/node": "20.14.2", "@types/yargs": "17.0.22", "@typescript-eslint/eslint-plugin": "7.6.0", "@typescript-eslint/parser": "7.6.0", diff --git a/src/new/cli.ts b/src/new/cli.ts index 5599fed..7b02655 100644 --- a/src/new/cli.ts +++ b/src/new/cli.ts @@ -1,5 +1,6 @@ import { Argv, CommandModule } from "yargs"; import { projectForm } from "./form"; +import semver from "semver"; type CommandModuleArgs = object; @@ -37,6 +38,19 @@ const commandOptions = (yargs: Argv): Argv => { .implies("template", "package-manager"); }; +const checkNodeVersion = (): void => { + const minVersion = "18.0.0"; + const maxVersion = "20.7.0"; + const currentVersion = process.version; + + if (!semver.satisfies(currentVersion, `>=${minVersion} <=${maxVersion}`)) { + console.error( + `Node.js version ${currentVersion} is not supported. Please use a version between ${minVersion} and ${maxVersion}.`, + ); + process.exit(1); + } +}; + const createProject = (): CommandModule => { return { command: "new [package-manager] [template] [directory]", @@ -48,6 +62,7 @@ const createProject = (): CommandModule => { template, directory, }) => { + checkNodeVersion(); return await projectForm(projectName, [ packageManager, template, diff --git a/src/new/form.ts b/src/new/form.ts index 54c19a2..83a84cb 100644 --- a/src/new/form.ts +++ b/src/new/form.ts @@ -1,5 +1,5 @@ import chalk from "chalk"; -import { execSync, spawn } from "child_process"; +import { execSync, spawn } from "node:child_process"; import { Presets, SingleBar } from "cli-progress"; import degit from "degit"; import inquirer from "inquirer"; @@ -27,7 +27,11 @@ async function packageManagerInstall({ cwd: directory, }); - installProcess.stdout.on("data", (data: Buffer) => { + installProcess.on("error", (error) => { + reject(new Error(`Failed to start subprocess: ${error.message}`)); + }); + + installProcess.stdout?.on("data", (data: Buffer) => { const output = data.toString().trim(); const npmProgressMatch = output.match(