hotshot-mod-manager
Version:
172 lines (150 loc) • 4.96 kB
JavaScript
import fs from "node:fs";
import path from "node:path";
import { configPath, getConfig, nameFixer } from "../main.js";
export async function routerModuleCreator(moduleName) {
const config = await getConfig();
if (
config?.routerModules?.find((m) => m.name === moduleName)
) {
throw new Error(
`Error: Router Module '${moduleName}' already exists in config.`,
);
}
const moduleContent = {
routerContent: routerContents(moduleName),
controllerContent: controllerContents(moduleName),
serviceContent: serviceContents(moduleName),
};
/*
|-----------------------------------------------------------------------
| File System IO
|-----------------------------------------------------------------------
*/
const moduleDirPath = path.join(
process.cwd(),
"src",
`router_modules/${moduleName}_module`,
);
fs.mkdirSync(moduleDirPath, { recursive: true });
fs.writeFileSync(
path.join(moduleDirPath, `${moduleName}_router.ts`),
moduleContent?.routerContent,
);
fs.writeFileSync(
path.join(moduleDirPath, `${moduleName}_controller.ts`),
moduleContent?.controllerContent,
);
fs.writeFileSync(
path.join(moduleDirPath, `${moduleName}_services.ts`),
moduleContent?.serviceContent,
);
/*
|-----------------------------------------------------------------------
| Config Update
|-----------------------------------------------------------------------
*/
config?.routerModules?.push({
name: moduleName,
path: `./src/router_modules/${moduleName}_module`,
includes: ["router", "controller", "services"],
services: [`${moduleName}_service`],
});
const updatedConfigContent = JSON.stringify(config, null, 2);
fs.writeFileSync(configPath, updatedConfigContent);
/*
|-----------------------------------------------------------------------
| Update Routes File
|-----------------------------------------------------------------------
*/
const routesFilePath = path.join(
process.cwd(),
"src",
"router_modules",
"routes.ts",
);
const relativePath =
`"#router_modules/${moduleName}_module/${moduleName}_router"`;
const importStatement = `import(${relativePath}),\n`;
if (!fs.existsSync(routesFilePath)) {
fs.writeFileSync(
routesFilePath,
`export const routerModules = [\n ${importStatement}]\n`,
"utf8",
);
} else {
// Append the new import if it doesn't already exist
const existingContent = fs.readFileSync(routesFilePath, "utf8");
if (!existingContent.includes(relativePath)) {
const updatedContent = existingContent.replace(
/export const routerModules = \[\s*/,
(match) => `${match} ${importStatement}`,
);
fs.writeFileSync(routesFilePath, updatedContent, "utf8");
}
}
}
/*
|-------------------------------------------------------------------------
| Module Contents
|-------------------------------------------------------------------------
*/
function routerContents(moduleName) {
const routerClassName = nameFixer(moduleName, true);
const controllerClassName = `${nameFixer(moduleName, true)}Controller`;
const controllerMethodName = nameFixer(moduleName, false);
return `
import { router } from "@a4arpon/hotshot"
import {${controllerClassName}} from "./${moduleName}_controller";
const ${
nameFixer(controllerClassName, false)
}Instance = new ${controllerClassName}()
export const ${routerClassName} = router({
basePath: "${moduleName.toLowerCase()}",
routes:[{
method: "GET",
path: "/",
handler: ${
nameFixer(controllerClassName, false)
}Instance.${controllerMethodName}.bind(${
nameFixer(controllerClassName, false)
}Instance)
}]
})
`;
}
function controllerContents(moduleName) {
const controllerClassName = `${nameFixer(moduleName, true)}Controller`;
const controllerFileName = nameFixer(moduleName, false);
const serviceName = `${nameFixer(moduleName, true)}Services`;
const serviceMethodName = nameFixer(moduleName, false);
return `
import type {Context} from "hono";
import {${serviceName}} from "./${moduleName}_services";
export class ${controllerClassName} {
private readonly ${nameFixer(moduleName, false)}Services: ${serviceName}
constructor() {
this.${nameFixer(moduleName, false)}Services = new ${serviceName}()
}
public async ${controllerFileName} (ctx: Context) {
return this.${
nameFixer(
moduleName,
false,
)
}Services.${serviceMethodName}()
}
}
`;
}
function serviceContents(moduleName) {
const servicesClassName = `${nameFixer(moduleName, true)}Services`;
const serviceMethodName = nameFixer(moduleName, false);
return `
import {response} from "@a4arpon/hotshot";
export class ${servicesClassName} {
async ${serviceMethodName}() {
return response("Hi from ${moduleName}!");
}
}
`;
}