140 lines
No EOL
3.2 KiB
TypeScript
140 lines
No EOL
3.2 KiB
TypeScript
import { ANSI } from "../../core/src/constants";
|
|
import { name } from "../package.json";
|
|
import { resolve } from "node:path";
|
|
import fs from "node:fs";
|
|
import { isValidElement } from "react";
|
|
|
|
const items = await import("../../core/src/main");
|
|
|
|
const OUTPUT_DIR = "data";
|
|
|
|
const MACRO_CASE = /^[A-Z_]+$/;
|
|
const SNAKE_CASE = /^[a-z]+([A-Z][a-z]*)+$/;
|
|
const PASCAL_CASE = /^([A-Z][a-z]*)+$/;
|
|
|
|
function getItemType(key: string, value: unknown): string | null {
|
|
if (MACRO_CASE.test(key))
|
|
return "Constant";
|
|
|
|
if (typeof value === "function") {
|
|
if (/^use([A-Z][a-z]*)+$/.test(key)) {
|
|
return "Hook";
|
|
} else if (SNAKE_CASE.test(key)) {
|
|
return "Function";
|
|
} else if (PASCAL_CASE.test(key)) {
|
|
if (isValidElement(value)) {
|
|
return "Component";
|
|
} else {
|
|
return "Class";
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function getItemCategory(key: string, value: unknown, type: string): string | null {
|
|
if (type == "Function") {
|
|
if (key.includes("Viewport") || key.endsWith("Url") || key.endsWith("Clipboard")) {
|
|
return "Browser";
|
|
} else if (key.endsWith("Array")) {
|
|
return "Utils";
|
|
} else if (key.endsWith("Time")) {
|
|
return "Time";
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function generateContent(key: string, value: unknown, type: string, category: string | null): string {
|
|
const content: { [key: string]: unknown } = {
|
|
name: key,
|
|
type,
|
|
value
|
|
};
|
|
|
|
if (category != null)
|
|
content.category = category;
|
|
|
|
return JSON.stringify(content, null, 4);
|
|
}
|
|
|
|
function generateFile(key: string, value: unknown) {
|
|
const fileName = `${key}.json`;
|
|
|
|
const type = getItemType(key, value);
|
|
if (type == null) {
|
|
console.log(`${ANSI.fg.yellow}Skipping item with unknown type:${ANSI.reset} ${key}`);
|
|
return;
|
|
}
|
|
|
|
let directory = "/";
|
|
|
|
switch (type) {
|
|
case "Constant":
|
|
directory += "constants/";
|
|
break;
|
|
case "Hook":
|
|
directory += "hooks/";
|
|
break;
|
|
case "Function":
|
|
directory += "functions/";
|
|
break;
|
|
case "Class":
|
|
directory += "classes/";
|
|
break;
|
|
case "Component":
|
|
directory += "components/";
|
|
break;
|
|
}
|
|
|
|
const category = getItemCategory(key, value, type);
|
|
|
|
switch (category) {
|
|
case "Browser":
|
|
directory += "browser/";
|
|
break;
|
|
case "Utils":
|
|
directory += "utils/";
|
|
break;
|
|
case "Time":
|
|
directory += "time/";
|
|
break;
|
|
}
|
|
|
|
try {
|
|
const path = resolve(__dirname, `../${OUTPUT_DIR + directory}`);
|
|
if (!fs.existsSync(path)){
|
|
fs.mkdirSync(path, { recursive: true });
|
|
}
|
|
|
|
const content = generateContent(key, value, type, category);
|
|
|
|
fs.writeFileSync(`${path}/${fileName}`, content, { flag: "w+" });
|
|
console.log(`- ${ANSI.fg.cyan}${OUTPUT_DIR + directory}${fileName}${ANSI.reset}`);
|
|
} catch (error) {
|
|
console.error(error);
|
|
console.log(`${ANSI.fg.red}⚠ Failed to generate: ${fileName}${ANSI.reset}`);
|
|
}
|
|
}
|
|
|
|
function generateData() {
|
|
try {
|
|
console.log(`Context: ${ANSI.decoration.bold}${name}${ANSI.reset}\n`);
|
|
|
|
console.log(`${ANSI.fg.yellow}Generating data...${ANSI.reset}`);
|
|
|
|
for (const [key, value] of Object.entries(items)) {
|
|
generateFile(key, value);
|
|
}
|
|
|
|
console.log(`\n${ANSI.fg.green}✓ Completed generating data${ANSI.reset}`);
|
|
} catch (error) {
|
|
console.error(error);
|
|
console.log(`${ANSI.fg.red}⚠ Data generation failed${ANSI.reset}`);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
void generateData(); |