Skip to content

Commit

Permalink
Merge pull request #35 from expressots/feature/project-commands
Browse files Browse the repository at this point in the history
Feature/project commands
  • Loading branch information
rsaz authored Mar 21, 2024
2 parents 51d675f + 53b450f commit ea42780
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 1 deletion.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@
"husky": "^8.0.3",
"prettier": "^2.8.4",
"release-it": "^16.1.5",
"rimraf": "^4.1.2",
"rimraf": "^5.0.5",
"shx": "^0.3.4",
"ts-node-dev": "^2.0.0",
"typescript": "^4.9.5",
"vite": "^4.4.9",
Expand Down
2 changes: 2 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { runCommandModule } from "./commands/project.commands";
import { generateProject } from "./generate";
import { infoProject } from "./info";
import { createProject } from "./new";
Expand All @@ -13,6 +14,7 @@ console.log(`\n[🐎 Expressots]\n`);

yargs(hideBin(process.argv))
.scriptName("expressots")
.command(runCommandModule)
.command(createProject())
.command(generateProviders())
.command(generateProject())
Expand Down
145 changes: 145 additions & 0 deletions src/commands/project.commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { spawn } from "child_process";
import { promises as fs } from "fs";
import path from "path";
import { Argv, CommandModule } from "yargs";
import Compiler from "../utils/compiler";

/**
* Load the configuration from the compiler
* @param compiler The compiler to load the configuration from
* @returns The configuration
*/

const opinionatedConfig: Array<string> = [
"--transpile-only",
"-r",
"dotenv/config",
"-r",
"tsconfig-paths/register",
"./src/main.ts",
];

const nonOpinionatedConfig: Array<string> = [
"--transpile-only",
"-r",
"dotenv/config",
"./src/main.ts",
];

/**
* 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: string,
args: Array<string>,
cwd: string = process.cwd(),
): Promise<void> {
return new Promise((resolve, reject) => {
const proc = 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 to delete the dist directory
const cleanDist = async (): Promise<void> => {
await fs.rm("./dist", { recursive: true, force: true });
};

// Helper to compile TypeScript
const compileTypescript = async () => {
await execCmd("npx", ["tsc", "-p", "tsconfig.build.json"]);
};

// Helper to copy files
const copyFiles = async () => {
const { opinionated } = await Compiler.loadConfig();
let filesToCopy: Array<string> = [];
if (opinionated) {
filesToCopy = [
"./register-path.js",
"tsconfig.build.json",
"package.json",
];
} else {
filesToCopy = ["tsconfig.json", "package.json"];
}
filesToCopy.forEach((file) => {
fs.copyFile(file, path.join("./dist", path.basename(file)));
});
};

// eslint-disable-next-line @typescript-eslint/ban-types
export const runCommandModule: CommandModule<{}, { command: string }> = {
command: "run <command>",
describe: "Runs a specified command (dev, build, prod)",
builder: (yargs: Argv) => {
return yargs.positional("command", {
describe: "The command to run",
type: "string",
choices: ["dev", "build", "prod"],
});
},
handler: async (argv) => {
const { command } = argv;
// Now call your original runCommand function with the command
// Ensure runCommand is properly defined to handle these commands
await runCommand({ command });
},
};

const runCommand = async ({ command }: { command: string }): Promise<void> => {
const { opinionated } = await Compiler.loadConfig();
try {
switch (command) {
case "dev":
// Use execSync or spawn to run ts-node-dev programmatically
execCmd(
"tsnd",
opinionated ? opinionatedConfig : nonOpinionatedConfig,
);
break;
case "build":
await cleanDist();
await compileTypescript();
await copyFiles();
break;
case "prod":
let config: Array<string> = [];
if (opinionated) {
config = [
"-r",
"dotenv/config",
"-r",
"./dist/register-path.js",
"./dist/src/main.js",
];
} else {
config = ["-r", "dotenv/config", "./dist/main.js"];
}
// Ensure environment variables are set
execCmd("node", config);
break;
default:
console.log(`Unknown command: ${command}`);
}
} catch (error) {
console.error("Error executing command:", error);
}
};

export { runCommand };

0 comments on commit ea42780

Please sign in to comment.