Initial commit: Angular frontend and Expressjs backend

This commit is contained in:
chamikaJ
2024-05-17 09:32:30 +05:30
parent eb0a0d77d6
commit 298ca6beeb
3548 changed files with 193558 additions and 3 deletions

View File

@@ -0,0 +1,16 @@
const fs = require("fs");
const path = require("path");
const wwwFile = fs.readFileSync(path.join(__dirname, "../build/bin/www.js"), "utf8");
const bluebird = /(global\.Promise = require\("bluebird"\);)/g;
const dotenvImport = /(var import_dotenv = __toESM\(require\("dotenv"\)\);)/g;
const dotenvUse = /(import_dotenv\.default\.config\(\);)/g;
const out = wwwFile
.replace(bluebird, "")
.replace(dotenvUse, "")
.replace(dotenvImport, `var import_dotenv = __toESM(require("dotenv"));import_dotenv.default.config();`)
.replace(dotenvUse, `import_dotenv.default.config();global.Promise = require("bluebird");`);
fs.writeFileSync(path.join(__dirname, "../build/bin/www.js"), out, "utf8");

View File

@@ -0,0 +1,106 @@
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const arg = process.argv[2];
function camelize(str) {
return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
return index === 0 ? word.toLowerCase() : word.toUpperCase();
}).replace(/[\W]/g, "");
}
function toPascalCase(string) {
return `${string}`
.toLowerCase()
.replace(new RegExp(/[-_]+/, "g"), "")
.replace(new RegExp(/[^\w\s]/, "g"), "")
.replace(
new RegExp(/\s+(.)(\w*)/, "g"),
($1, $2, $3) => `${$2.toUpperCase() + $3}`
)
.replace(new RegExp(/\w/), s => s.toUpperCase());
}
const name = arg.trim();
const fileName = name.toLowerCase();
const varName = camelize(name);
const Controller = `${toPascalCase(name)}Controller`;
const content = `
import { IWorkLenzRequest } from "../interfaces/worklenz-request";
import { IWorkLenzResponse } from "../interfaces/worklenz-response";
import db from "../config/db";
import { ServerResponse } from "../models/server-response";
import WorklenzControllerBase from "./worklenz-controller-base";
import HandleExceptions from "../decorators/handle-exceptions";
export default class ${Controller} extends WorklenzControllerBase {
@HandleExceptions()
public static async create(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const q = \`\`;
const result = await db.query(q, []);
const [data] = result.rows;
return res.status(200).send(new ServerResponse(true, data));
}
@HandleExceptions()
public static async get(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const q = \`\`;
const result = await db.query(q, []);
return res.status(200).send(new ServerResponse(true, result.rows));
}
@HandleExceptions()
public static async getById(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const q = \`\`;
const result = await db.query(q, []);
const [data] = result.rows;
return res.status(200).send(new ServerResponse(true, data));
}
@HandleExceptions()
public static async update(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const q = \`\`;
const result = await db.query(q, []);
return res.status(200).send(new ServerResponse(true, result.rows));
}
@HandleExceptions()
public static async deleteById(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const q = \`\`;
const result = await db.query(q, []);
return res.status(200).send(new ServerResponse(true, result.rows));
}
}
`;
const fullName = `${name}-controller`;
const apis = `
import express from "express";
import ${Controller} from "../../controllers/${fullName}";
const ${varName}ApiRouter = express.Router();
${varName}ApiRouter.post("/", ${Controller}.create);
${varName}ApiRouter.get("/", ${Controller}.get);
${varName}ApiRouter.get("/:id", ${Controller}.getById);
${varName}ApiRouter.put("/:id", ${Controller}.update);
${varName}ApiRouter.delete("/:id", ${Controller}.deleteById);
export default ${varName}ApiRouter;
`;
fs.writeFileSync(path.join(__dirname, "../src/controllers", `${fullName}.ts`), content.trim(), "utf8");
fs.writeFileSync(path.join(__dirname, "../src/routes/apis/", `${fileName}-api-router.ts`), apis.trim(), "utf8");
let api = fs.readFileSync(path.join(__dirname, "../src/routes/apis", "index.ts"), "utf8");
api = api.replace("\nconst api = express.Router();", `import ${varName}ApiRouter from "./${fileName}-api-router";\n\nconst api = express.Router();`);
api = api.replace("export default api;", `api.use("/${fileName}", ${varName}ApiRouter);\n\nexport default api;`);
fs.writeFileSync(path.join(__dirname, "../src/routes/apis", "index.ts"), api, "utf8");
console.log(`${fullName} generated`);

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const arg = process.argv[2];
const name = arg.trim().toLowerCase();
const content = `
import { NextFunction } from "express";
import { IWorkLenzRequest } from "../../interfaces/worklenz-request";
import { IWorkLenzResponse } from "../../interfaces/worklenz-response";
import { ServerResponse } from "../../models/server-response";
export default function (req: IWorkLenzRequest, res: IWorkLenzResponse, next: NextFunction): IWorkLenzResponse | void {
const { example_name } = req.body;
if (!example_name)
return res.status(200).send(new ServerResponse(false, null, "Name is required"));
return next();
}
`;
const fullName = `${name}-validator`;
fs.writeFileSync(path.join(__dirname, "../src/middlewares/validators", `${fullName}.ts`), content.trim(), "utf8");
console.log(`${fullName} generated`);

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
// Preview
function inline(folder) {
const controllers = fs.readdirSync(path.join(__dirname, folder)).filter(f => f.split(".").pop() === "js");
const replacer = (match, p1, p2, p3, offset, string) => match.split(/\n/g).map(s => s.trim()).join(" ").trim();
for (const item of controllers) {
const controller = fs.readFileSync(path.join(__dirname, folder, item), "utf8");
const q = controller.replace(/(?<=q\s+=(.*?)`)([\s\S]*?)(?=`;)/g, replacer);
fs.writeFileSync(path.join(__dirname, folder, item), q, "utf8");
}
}
// inline("../build/controllers");
// inline("../build/passport");

View File

@@ -0,0 +1,111 @@
#!/usr/bin/env node
/* eslint-disable no-console */
const fs = require("fs");
const path = require("path");
const { ncp } = require("ncp");
const { exec } = require("child_process");
require("dotenv").config();
const options = {
angular_dist_dir: process.env.ANGULAR_DIST_DIR,
angular_src_dir: process.env.ANGULAR_SRC_DIR,
backend_public_dir: process.env.BACKEND_PUBLIC_DIR,
backend_views_dir: process.env.BACKEND_VIEWS_DIR,
commit_changes: process.env.COMMIT_BUILD_IMMEDIATELY === "true"
};
function run_git_commit(version) {
if (!options.commit_changes) return;
const message = `Frontend build (${version})`;
console.log(message);
exec(`git add . && git commit -m "build: ${message}"`);
}
function copy_build() {
const deleteFolderRecursive = function (p) {
if (fs.existsSync(p)) {
fs.readdirSync(p).forEach((file) => {
const curPath = path.join(p, file);
if (fs.lstatSync(curPath).isDirectory()) { // recurse
deleteFolderRecursive(curPath);
} else { // delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(p);
}
};
if (fs.existsSync(path.join(options.angular_dist_dir, "index.html"))) {
const styles = /styles\.\w+\.css/g;
const runtime = /runtime\.\w+\.js/g;
const polyfills = /polyfills\.\w+\.js/g;
// const scripts = /scripts\.\w+\.js/g;
const main = /main\.\w+\.js/g;
const version = /\?v=\d+/g;
const layoutPath = path.join(options.backend_views_dir, "layout.pug");
const indexHtml = fs.readFileSync(path.join(options.angular_dist_dir, "index.html"), "utf8");
const pugLayout = fs.readFileSync(layoutPath, "utf8");
const v = Date.now();
const newLayout = pugLayout
.replace(styles, indexHtml.match(styles)[0])
.replace(runtime, indexHtml.match(runtime)[0])
.replace(polyfills, indexHtml.match(polyfills)[0])
// .replace(scripts, indexHtml.match(scripts)[0])
.replace(main, indexHtml.match(main)[0])
.replace(version, `?v=${v}`);
fs.writeFileSync(layoutPath, newLayout, "utf8");
if (fs.existsSync(options.backend_public_dir)) deleteFolderRecursive(options.backend_public_dir);
fs.mkdirSync(options.backend_public_dir);
ncp(options.angular_dist_dir, options.backend_public_dir, (err) => {
if (err) {
return console.error(err);
}
fs.unlinkSync(path.join(options.backend_public_dir, "index.html"));
const versionFile = path.join(__dirname, "../", "release");
let $v = null;
if (fs.existsSync(versionFile)) {
const version = fs.readFileSync(versionFile, "utf8");
$v = +version + 1;
fs.writeFileSync(versionFile, $v.toString(), "utf8");
}
console.log(`Release Updated - v${$v}`);
console.log("Running git commit.");
setTimeout(() => run_git_commit(`v${$v}`), 500);
});
} else {
console.log("Build does not exists!");
}
}
function build() {
console.log("Start building the Angular Project");
const cmd = exec(`cd ${options.angular_src_dir} && npm run build`);
cmd.stdout.on("data", (data) => {
console.log(data.toString());
});
cmd.stderr.on("data", (data) => {
console.log(`${data.toString()}`);
});
cmd.on("exit", (code) => {
console.log("Build success.");
console.log("Start Coping");
setTimeout(copy_build, 500);
});
}
build();

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env node
/* eslint-disable @typescript-eslint/no-var-requires */
const swaggerJsdoc = require("swagger-jsdoc");
const fs = require("fs");
const path = require("path");
const options = {
definition: {
openapi: "3.0.0",
info: {
title: "Hello World",
version: "1.0.0",
},
},
apis: ["../build/routes/*.js"], // files containing annotations as above
};
const openapiSpecification = swaggerJsdoc(options);
fs.writeFileSync(path.join(__dirname, "../build/swagger.json"), JSON.stringify(openapiSpecification), "utf8");