create-node-blueprint
Version:
A cli tool to generate nodejs project
134 lines (133 loc) • 9.59 kB
JavaScript
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());
});
};
import path from "node:path";
import { ensureDirExists, createFileWithContent } from "../utils/utils.js";
import { TemplaterMap } from "../services/templater.js";
import { AuthEnum, FrameworkEnum, OrmEnum } from "../enums/enums.js";
const nodeVersion = process.versions.node.split(".")[0];
// main function to create the project files and folders and populates the files with the correct content
export const createProjectStructure = (config_1, _a) => __awaiter(void 0, [config_1, _a], void 0, function* (config, { root, pkgManager, pkgLock }) {
try {
// ensure folders
yield ensureDirExists(path.resolve(root, "src"));
yield ensureDirExists(path.resolve(root, "scripts"));
yield ensureDirExists(path.resolve(root, "src", "views"));
yield ensureDirExists(path.resolve(root, "src", "utils"));
yield ensureDirExists(path.resolve(root, "src", "routes"));
yield ensureDirExists(path.resolve(root, "src", "config"));
yield ensureDirExists(path.resolve(root, "src", "services"));
yield ensureDirExists(path.resolve(root, "src", "constants"));
yield ensureDirExists(path.resolve(root, "src", "enums"));
yield ensureDirExists(path.resolve(root, "src", "types"));
yield ensureDirExists(path.resolve(root, "src", "types/interfaces"));
yield ensureDirExists(path.resolve(root, "src", "validations"));
yield ensureDirExists(path.resolve(root, "src", "middlewares"));
yield ensureDirExists(path.resolve(root, "src", "controllers"));
// create base files
yield createFileAndInjectContent(root, "", ".env", "base", "env", config);
yield createFileAndInjectContent(root, "", "README.md", "base", "readme", config);
yield createFileAndInjectContent(root, "", ".gitignore", "base", "gitignore", config);
yield createFileAndInjectContent(root, "", "tsconfig.json", "base", "tsconfig", config);
yield createFileAndInjectContent(root, "src/config", "env.ts", "base", "envTs", config);
yield createFileAndInjectContent(root, "src/views", "index.ejs", "base", "indexEjs", config);
if (config.features.includes("docker")) {
yield createFileAndInjectContent(root, "", "Dockerfile", "base", "dockerFile", {
pkgManager,
nodeVersion,
pkgLock
});
yield createFileAndInjectContent(root, "", "docker-compose.yml", "base", "dockerComposeYml", Object.assign(Object.assign({}, config), { nodeVersion, pgVersion: "16", mysqlVersion: "8", mongoVersion: "7" }));
yield createFileAndInjectContent(root, "", ".dockerignore", "base", "dockerIgnore", config);
}
// create files common for all frameworks
yield createFileAndInjectContent(root, "src", "app.ts", "common", "appTs", config);
yield createFileAndInjectContent(root, "src", "server.ts", "common", "serverTs", config);
yield createFileAndInjectContent(root, "src", "router.ts", "common", "routerTs", config);
yield createFileAndInjectContent(root, "src/routes", "user-routes.ts", "common", "userRoutesTs", config);
yield createFileAndInjectContent(root, "src/controllers", "user-controller.ts", "common", "userControllerTs", config);
yield createFileAndInjectContent(root, "src/routes", "health-routes.ts", "common", "healthRoutesTs", config);
yield createFileAndInjectContent(root, "src/controllers", "health-controller.ts", "common", "healthControllerTs", config);
yield createFileAndInjectContent(root, "src/enums", "role-enum.ts", "common", "roleEnumTs", config);
if (config.auth === AuthEnum.jwtAuth) {
yield createFileAndInjectContent(root, "src/routes", "auth-routes.ts", "common", "authRoutesTs", config);
yield createFileAndInjectContent(root, "src/validations", "auth-validations.ts", "common", "authValidationsTs", config);
yield createFileAndInjectContent(root, "src/services", "auth-services.ts", "common", "authServicesTs", config);
}
// express framework specific files
if (config.framework === FrameworkEnum.express) {
yield createFileAndInjectContent(root, "src/config", "cors.ts", "express", "corsTs", config);
yield createFileAndInjectContent(root, "src/middlewares", "cors-middleware.ts", "express", "corsMiddlewareTs", config);
yield createFileAndInjectContent(root, "src/middlewares", "error-middleware.ts", "express", "errorMiddlewareTs", config);
yield createFileAndInjectContent(root, "src/middlewares", "helmet-middleware.ts", "express", "helmetMiddlewareTs", config);
yield createFileAndInjectContent(root, "src/config", "logger.ts", "express", "loggerTs", config);
if (config.auth === AuthEnum.jwtAuth) {
yield createFileAndInjectContent(root, "src/utils", "error-handler.ts", "express", "errorHandlerTs", config);
}
}
// drizzle orm specific files and folders
if (config.orm === OrmEnum.drizzle) {
yield ensureDirExists(path.resolve(root, "src/db/schema"));
yield createFileAndInjectContent(root, "", "drizzle.config.ts", "drizzle", "drizzleConfig", config);
yield createFileAndInjectContent(root, "src/db", "index.ts", "drizzle", "indexTs", config);
yield createFileAndInjectContent(root, "src/db", "seed.ts", "drizzle", "seedTs", config);
yield createFileAndInjectContent(root, "src/db", "schema.ts", "drizzle", "schemaTs", config);
yield createFileAndInjectContent(root, "src/db/schema", "user-schema.ts", "drizzle", "userSchemaTs", config);
yield createFileAndInjectContent(root, "src/db/schema", "token-schema.ts", "drizzle", "tokenSchemaTs", config);
if (config.auth === AuthEnum.jwtAuth) {
yield createFileAndInjectContent(root, "src/controllers", "auth-controller.ts", "drizzle", "authControllerTs", config);
yield createFileAndInjectContent(root, "src/db/schema", "token-schema.ts", "drizzle", "tokenSchemaTs", config);
yield createFileAndInjectContent(root, "src/enums", "token-enum.ts", "common", "tokenEnumTs", config);
}
}
// prisma orm specific files and folders
if (config.orm === OrmEnum.prisma) {
yield ensureDirExists(path.resolve(root, "prisma"));
yield createFileAndInjectContent(root, "prisma", "prisma-client.ts", "prisma", "prismaClientTs", config);
yield createFileAndInjectContent(root, "prisma", "seed.ts", "prisma", "seedTs", config);
yield createFileAndInjectContent(root, "prisma", "schema.prisma", "prisma", "schemaPrisma", config);
if (config.auth === AuthEnum.jwtAuth) {
yield createFileAndInjectContent(root, "src/controllers", "auth-controller.ts", "prisma", "authControllerTs", config);
}
}
// mongoose orm specific files and folders
if (config.orm === OrmEnum.mongoose) {
yield ensureDirExists(path.resolve(root, "src", "models"));
yield createFileAndInjectContent(root, "src/models", "user-model.ts", "mongoose", "userModelTs", config);
yield createFileAndInjectContent(root, "src/config", "db.ts", "mongoose", "dbTs", config);
yield createFileAndInjectContent(root, "src/models", "seed.ts", "mongoose", "seedTs", config);
if (config.auth === AuthEnum.jwtAuth) {
yield createFileAndInjectContent(root, "src/models", "token-model.ts", "mongoose", "tokenModelTs", config);
yield createFileAndInjectContent(root, "src/controllers", "auth-controller.ts", "mongoose", "authControllerTs", config);
yield createFileAndInjectContent(root, "src/enums", "token-enum.ts", "common", "tokenEnumTs", config);
}
}
}
catch (err) {
console.log("\nAn error occurred while creating project files:\n");
process.exit(1);
}
});
// create file with content
const createFileAndInjectContent = (projectPath, pathToCreate, fileToCreate, type, fileMethodKey, config) => __awaiter(void 0, void 0, void 0, function* () {
var _a;
try {
// Retrieve the correct templater function
const templateFunction = (_a = TemplaterMap[type]) === null || _a === void 0 ? void 0 : _a.templater[fileMethodKey];
if (!templateFunction) {
throw new Error(`Template function for ${fileMethodKey} is not found in ${type}`);
}
const fullPath = path.resolve(projectPath, pathToCreate, fileToCreate);
const content = yield templateFunction(config);
yield createFileWithContent(fullPath, content);
}
catch (error) {
console.error(`Error creating ${fileToCreate}:`, error);
}
});