feat: modules file generation using template with specifying host and port asa args

This commit is contained in:
2025-03-12 21:12:48 +04:00
parent 7dcb646b82
commit 1247a80eb6
7 changed files with 106 additions and 131 deletions

1
.gitignore vendored
View File

@@ -11,6 +11,7 @@ node_modules
dist
dist-ssr
*.local
*.cjs
# Editor directories and files
.vscode/*

View File

@@ -1,3 +0,0 @@
sudo npx tsc ./src/modules/modulesFileGen/modulesFileGen.ts
mv -f ./src/modules/modulesFileGen/modulesFileGen.js ./src/modules/modulesFileGen/modulesFileGen.cjs
sudo node ./src/modules/modulesFileGen/modulesFileGen.cjs

View File

@@ -8,7 +8,8 @@
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"generate-client": "openapi --input http://127.0.0.1:8000/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes"
"generate-client": "openapi --input http://127.0.0.1:8000/openapi.json --output ./src/client --client axios --useOptions --useUnionTypes",
"generate-modules": "sudo npx tsc ./src/modules/modulesFileGen/modulesFileGen.ts && mv -f ./src/modules/modulesFileGen/modulesFileGen.js ./src/modules/modulesFileGen/modulesFileGen.cjs && sudo node ./src/modules/modulesFileGen/modulesFileGen.cjs"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.6.0",
@@ -39,6 +40,7 @@
"file-saver": "^2.0.5",
"framer-motion": "^11.3.8",
"globals": "^15.8.0",
"handlebars": "^4.7.8",
"jwt-decode": "^4.0.0",
"lodash": "^4.17.21",
"mantine-contextmenu": "^7.12.2",

View File

@@ -1,21 +1,57 @@
import { IconUser, IconBox, IconCubeSend, IconUsersGroup, IconUserCog } from "@tabler/icons-react"
import {
IconUser,
IconBox,
IconCubeSend,
IconUsersGroup,
IconUserCog,
} from "@tabler/icons-react";
import ModulesType from "./types.tsx";
import connectModules from "./connectModules.tsx";
export enum ModuleNames {
CLIENTS = "clients",
SERVICES_AND_PRODUCTS = "servicesAndProducts",
SHIPMENT = "shipment",
EMPLOYEES = "employees",
MANAGERS = "managers"
CLIENTS = "clients",
SERVICES_AND_PRODUCTS = "servicesAndProducts",
SHIPMENT = "shipment",
EMPLOYEES = "employees",
MANAGERS = "managers",
}
const modules: ModulesType = {
[ModuleNames.CLIENTS]: { info: { label: "Клиенты", key: "clients", icon: <IconUser /> } },
[ModuleNames.SERVICES_AND_PRODUCTS]: { info: { label: "Товары и услуги", key: "servicesAndProducts", icon: <IconBox /> } },
[ModuleNames.SHIPMENT]: { info: { label: "Отгрузка", key: "shipment", icon: <IconCubeSend /> } },
[ModuleNames.EMPLOYEES]: { info: { label: "Сотрудники", key: "employees", icon: <IconUsersGroup /> } },
[ModuleNames.MANAGERS]: { info: { label: "Менеджер", key: "managers", icon: <IconUserCog /> } }
[ModuleNames.CLIENTS]: {
info: {
label: "Клиенты",
key: "clients",
icon: <IconUser />,
}
},
[ModuleNames.SERVICES_AND_PRODUCTS]: {
info: {
label: "Товары и услуги",
key: "servicesAndProducts",
icon: <IconBox />,
}
},
[ModuleNames.SHIPMENT]: {
info: {
label: "Отгрузка",
key: "shipment",
icon: <IconCubeSend />,
}
},
[ModuleNames.EMPLOYEES]: {
info: {
label: "Сотрудники",
key: "employees",
icon: <IconUsersGroup />,
}
},
[ModuleNames.MANAGERS]: {
info: {
label: "Менеджер",
key: "managers",
icon: <IconUserCog />,
}
},
};
export const MODULES = connectModules(modules);
export const MODULES = connectModules(modules);

View File

@@ -1,61 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var axios_1 = require("axios");
var fs = require("fs");
// endregion
var OUTPUT_FILE = "./src/modules/modules.tsx";
function camelToConstCase(camelStr) {
return camelStr
.replace(/([a-z])([A-Z])/g, "$1_$2")
.toUpperCase();
}
var writeToFile = function (data) {
try {
fs.writeFileSync(OUTPUT_FILE, data.trim());
console.log("File successfully generated.");
}
catch (error) {
console.error(error);
}
};
var getImports = function (modules) {
var prefix = "import { ";
var postfix = " } from \"@tabler/icons-react\"\n" +
"import ModulesType from \"./types.tsx\";\n" +
"import connectModules from \"./connectModules.tsx\";";
var filteredModules = modules.filter(function (module) { return module.iconName; });
var icons = filteredModules.map(function (module) { return module.iconName; }).join(", ");
return prefix + icons + postfix;
};
var getModuleNames = function (modules) {
return modules.map(function (module) {
return "".concat(camelToConstCase(module.key), " = \"").concat(module.key, "\"");
}).join(",\n\t");
};
var getModules = function (modules) {
return modules.map(function (module) {
var iconStr = "null";
if (module.iconName) {
iconStr = "<" + module.iconName + " />";
}
return "[ModuleNames.".concat(camelToConstCase(module.key), "]: { info: { label: \"").concat(module.label, "\", key: \"").concat(module.key, "\", icon: ").concat(iconStr, " } }");
}).join(",\n\t");
};
var generateRows = function (modules) {
var imports = getImports(modules);
var moduleNames = "\n\nexport enum ModuleNames {\n\t".concat(getModuleNames(modules), "\n}\n");
var modulesStr = "\nconst modules: ModulesType = {\n\t".concat(getModules(modules), "\n};\n");
var connectModules = "\nexport const MODULES = connectModules(modules);";
var result = imports + moduleNames + modulesStr + connectModules;
writeToFile(result);
};
var modulesFileGen = function () {
console.log("Start file generation...");
axios_1.default
.get("http://127.0.0.1:8000/project/modules")
.then(function (response) {
generateRows(response.data.modules);
})
.catch(function (err) { return console.log(err); });
};
modulesFileGen();

View File

@@ -1,8 +1,23 @@
import * as fs from "fs";
import * as path from "path";
import * as handlebars from "handlebars";
import axios, { AxiosResponse } from "axios";
import * as fs from 'fs';
const HOST_AND_PORT = process.argv.length > 2 ? process.argv[2] : "127.0.0.1:8000";
const ENDPOINT = `http://${HOST_AND_PORT}/project/modules`;
const TEMPLATE_PATH = path.join(__dirname, "templates", "modulesFileTemplate.hbs");
const OUTPUT_PATH = path.join(__dirname, "..", "modules.tsx");
const templateSource = fs.readFileSync(TEMPLATE_PATH, "utf8");
const template = handlebars.compile(templateSource);
handlebars.registerHelper("uppercase", (text) => {
return text
.replace(/([a-z])([A-Z])/g, "$1_$2")
.toUpperCase();
});
// region Types
type Module = {
id: number;
key: string;
@@ -14,73 +29,31 @@ type Module = {
type ModulesResponse = {
modules: Module[];
}
// endregion
const OUTPUT_FILE = "./src/modules/modules.tsx";
function camelToConstCase(camelStr: string): string {
return camelStr
.replace(/([a-z])([A-Z])/g, "$1_$2")
.toUpperCase();
}
const writeToFile = (data: string) => {
const generateRows = (modules: Module[]) => {
try {
fs.writeFileSync(OUTPUT_FILE, data.trim());
const data = {
modules,
};
const tsxContent = template(data);
fs.writeFileSync(OUTPUT_PATH, tsxContent);
console.log("File successfully generated.");
} catch (error) {
console.error(error);
}
};
const getImports = (modules: Module[]): string => {
const prefix = "import { ";
const postfix = " } from \"@tabler/icons-react\"\n" +
"import ModulesType from \"./types.tsx\";\n" +
"import connectModules from \"./connectModules.tsx\";";
const filteredModules = modules.filter(module => module.iconName);
const icons = filteredModules.map((module: Module) => module.iconName).join(", ");
return prefix + icons + postfix;
};
const getModuleNames = (modules: Module[]) => {
return modules.map(module => {
return `${camelToConstCase(module.key)} = "${module.key}"`;
}).join(",\n\t");
};
const getModules = (modules: Module[]) => {
return modules.map(module => {
let iconStr = "null";
if (module.iconName) {
iconStr = "<" + module.iconName + " />";
}
return `[ModuleNames.${camelToConstCase(module.key)}]: { info: { label: "${module.label}", key: "${module.key}", icon: ${iconStr} } }`;
}).join(",\n\t");
};
const generateRows = (modules: Module[]) => {
const imports = getImports(modules);
const moduleNames = `\n\nexport enum ModuleNames {\n\t${getModuleNames(modules)}\n}\n`;
const modulesStr = `\nconst modules: ModulesType = {\n\t${getModules(modules)}\n};\n`;
const connectModules = "\nexport const MODULES = connectModules(modules);";
const result: string = imports + moduleNames + modulesStr + connectModules;
writeToFile(result);
};
const modulesFileGen = () => {
const oldModulesFileGen = () => {
console.log("Start file generation...");
axios
.get("http://127.0.0.1:8000/project/modules")
.get(ENDPOINT)
.then((response: AxiosResponse<ModulesResponse>) => {
generateRows(response.data.modules);
})
.catch(err => console.log(err));
};
modulesFileGen();
oldModulesFileGen();

View File

@@ -0,0 +1,27 @@
import {
{{#each modules}}
{{#if this.iconName}}{{this.iconName}},{{/if}}
{{/each}}
} from "@tabler/icons-react";
import ModulesType from "./types.tsx";
import connectModules from "./connectModules.tsx";
export enum ModuleNames {
{{#each modules}}
{{uppercase this.key}} = "{{this.key}}",
{{/each}}
}
const modules: ModulesType = {
{{#each modules}}
[ModuleNames.{{uppercase this.key}}]: {
info: {
label: "{{this.label}}",
key: "{{this.key}}",
icon: {{#if this.iconName}}<{{this.iconName}} />{{else}}None{{/if}},
}
},
{{/each}}
};
export const MODULES = connectModules(modules);