This commit is contained in:
Aman Varshney
2025-04-14 21:45:28 +05:30
parent 8b03441909
commit 7f441ef670
268 changed files with 3513 additions and 3039 deletions

View File

@@ -3,30 +3,41 @@ import fs from "fs-extra";
import { type AvailableDependencies, dependencyVersionMap } from "../constants";
export const addPackageDependency = (opts: {
export const addPackageDependency = async (opts: {
dependencies?: AvailableDependencies[];
devDependencies?: AvailableDependencies[];
projectDir: string;
}) => {
}): Promise<void> => {
const { dependencies = [], devDependencies = [], projectDir } = opts;
const pkgJsonPath = path.join(projectDir, "package.json");
const pkgJson = fs.readJSONSync(pkgJsonPath);
const pkgJson = await fs.readJson(pkgJsonPath);
if (!pkgJson.dependencies) pkgJson.dependencies = {};
if (!pkgJson.devDependencies) pkgJson.devDependencies = {};
for (const pkgName of dependencies) {
const version = dependencyVersionMap[pkgName];
pkgJson.dependencies[pkgName] = version;
if (version) {
pkgJson.dependencies[pkgName] = version;
} else {
console.warn(`Warning: Dependency ${pkgName} not found in version map.`);
}
}
for (const pkgName of devDependencies) {
const version = dependencyVersionMap[pkgName];
pkgJson.devDependencies[pkgName] = version;
if (version) {
pkgJson.devDependencies[pkgName] = version;
} else {
console.warn(
`Warning: Dev dependency ${pkgName} not found in version map.`,
);
}
}
fs.writeJSONSync(pkgJsonPath, pkgJson, {
await fs.writeJson(pkgJsonPath, pkgJson, {
spaces: 2,
});
};

View File

@@ -2,66 +2,109 @@ import pc from "picocolors";
import type { ProjectConfig } from "../types";
export function displayConfig(config: Partial<ProjectConfig>) {
const configDisplay = [];
const configDisplay: string[] = [];
if (config.projectName) {
configDisplay.push(`${pc.blue("Project Name:")} ${config.projectName}`);
}
if (config.frontend !== undefined) {
const frontend = Array.isArray(config.frontend)
? config.frontend
: [config.frontend];
const frontendText =
config.frontend.length > 0 ? config.frontend.join(", ") : "none";
frontend.length > 0 && frontend[0] !== undefined && frontend[0] !== ""
? frontend.join(", ")
: "none";
configDisplay.push(`${pc.blue("Frontend:")} ${frontendText}`);
}
if (config.backend !== undefined) {
configDisplay.push(`${pc.blue("Backend Framework:")} ${config.backend}`);
configDisplay.push(
`${pc.blue("Backend Framework:")} ${String(config.backend)}`,
);
}
if (config.runtime !== undefined) {
configDisplay.push(`${pc.blue("Runtime:")} ${config.runtime}`);
configDisplay.push(`${pc.blue("Runtime:")} ${String(config.runtime)}`);
}
if (config.api !== undefined) {
configDisplay.push(`${pc.blue("API:")} ${String(config.api)}`);
}
if (config.database !== undefined) {
configDisplay.push(`${pc.blue("Database:")} ${config.database}`);
configDisplay.push(`${pc.blue("Database:")} ${String(config.database)}`);
}
if (config.orm !== undefined) {
configDisplay.push(`${pc.blue("ORM:")} ${config.orm}`);
configDisplay.push(`${pc.blue("ORM:")} ${String(config.orm)}`);
}
if (config.auth !== undefined) {
configDisplay.push(`${pc.blue("Authentication:")} ${config.auth}`);
const authText =
typeof config.auth === "boolean"
? config.auth
? "Yes"
: "No"
: String(config.auth);
configDisplay.push(`${pc.blue("Authentication:")} ${authText}`);
}
if (config.addons !== undefined) {
const addons = Array.isArray(config.addons)
? config.addons
: [config.addons];
const addonsText =
config.addons.length > 0 ? config.addons.join(", ") : "none";
addons.length > 0 && addons[0] !== undefined ? addons.join(", ") : "none";
configDisplay.push(`${pc.blue("Addons:")} ${addonsText}`);
}
if (config.examples !== undefined) {
const examples = Array.isArray(config.examples)
? config.examples
: [config.examples];
const examplesText =
config.examples.length > 0 ? config.examples.join(", ") : "none";
examples.length > 0 && examples[0] !== undefined
? examples.join(", ")
: "none";
configDisplay.push(`${pc.blue("Examples:")} ${examplesText}`);
}
if (config.git !== undefined) {
configDisplay.push(`${pc.blue("Git Init:")} ${config.git}`);
const gitText =
typeof config.git === "boolean"
? config.git
? "Yes"
: "No"
: String(config.git);
configDisplay.push(`${pc.blue("Git Init:")} ${gitText}`);
}
if (config.packageManager !== undefined) {
configDisplay.push(
`${pc.blue("Package Manager:")} ${config.packageManager}`,
`${pc.blue("Package Manager:")} ${String(config.packageManager)}`,
);
}
if (config.noInstall !== undefined) {
configDisplay.push(`${pc.blue("Skip Install:")} ${config.noInstall}`);
if (config.install !== undefined) {
const installText =
typeof config.install === "boolean"
? config.install
? "Yes"
: "No"
: String(config.install);
configDisplay.push(`${pc.blue("Install Dependencies:")} ${installText}`);
}
if (config.dbSetup !== undefined) {
configDisplay.push(`${pc.blue("Database Setup:")} ${config.dbSetup}`);
configDisplay.push(
`${pc.blue("Database Setup:")} ${String(config.dbSetup)}`,
);
}
if (configDisplay.length === 0) {
return pc.yellow("No configuration selected.");
}
return configDisplay.join("\n");

View File

@@ -17,9 +17,13 @@ export function generateReproducibleCommand(config: ProjectConfig): string {
}
}
if (config.api) {
flags.push(`--api ${config.api}`);
}
flags.push(config.auth ? "--auth" : "--no-auth");
flags.push(config.git ? "--git" : "--no-git");
flags.push(config.noInstall ? "--no-install" : "--install");
flags.push(config.install ? "--install" : "--no-install");
if (config.runtime) {
flags.push(`--runtime ${config.runtime}`);

View File

@@ -0,0 +1,23 @@
import type { ProjectPackageManager } from "../types";
/**
* Returns the appropriate command for running a package without installing it globally,
* based on the selected package manager.
*
* @param packageManager - The selected package manager (e.g., 'npm', 'yarn', 'pnpm', 'bun').
* @param commandWithArgs - The command to run, including arguments (e.g., "prisma generate --schema=./prisma/schema.prisma").
* @returns The full command string (e.g., "npx prisma generate --schema=./prisma/schema.prisma").
*/
export function getPackageExecutionCommand(
packageManager: ProjectPackageManager | null | undefined,
commandWithArgs: string,
): string {
switch (packageManager) {
case "pnpm":
return `pnpm dlx ${commandWithArgs}`;
case "bun":
return `bunx ${commandWithArgs}`;
default:
return `npx ${commandWithArgs}`;
}
}

View File

@@ -0,0 +1,37 @@
import path from "node:path";
import fs from "fs-extra";
import handlebars from "handlebars";
import type { ProjectConfig } from "../types";
/**
* Processes a Handlebars template file and writes the output to the destination.
* @param srcPath Path to the source .hbs template file.
* @param destPath Path to write the processed file.
* @param context Data to be passed to the Handlebars template.
*/
export async function processTemplate(
srcPath: string,
destPath: string,
context: ProjectConfig,
): Promise<void> {
try {
const templateContent = await fs.readFile(srcPath, "utf-8");
const template = handlebars.compile(templateContent);
const processedContent = template(context);
await fs.ensureDir(path.dirname(destPath));
await fs.writeFile(destPath, processedContent);
} catch (error) {
console.error(`Error processing template ${srcPath}:`, error);
throw new Error(`Failed to process template ${srcPath}`);
}
}
handlebars.registerHelper("or", (a, b) => a || b);
handlebars.registerHelper("eq", (a, b) => a === b);
handlebars.registerHelper(
"includes",
(array, value) => Array.isArray(array) && array.includes(value),
);