163 lines
4.4 KiB
JavaScript
163 lines
4.4 KiB
JavaScript
import { XMLParser } from "fast-xml-parser";
|
|
import { createWriteStream } from "node:fs";
|
|
import { createRequire } from "node:module";
|
|
|
|
const { upstream } = createRequire(import.meta.url)("../package.json");
|
|
const source =
|
|
"https://forgejo.nishi.boats/api/v1/repos/pyrite-dev/milsko/tags";
|
|
|
|
// Out files
|
|
const structsOut = createWriteStream("lib/structs.ts");
|
|
const enumsOut = createWriteStream("lib/enums.ts");
|
|
const constantsOut = createWriteStream("lib/constants.ts");
|
|
|
|
function toCamelCase(input) {
|
|
const split = input.split("_");
|
|
for (let i = 0; i < split.length; i++) {
|
|
const firstChar =
|
|
i <= 0
|
|
? split[i].charAt(0).toLowerCase()
|
|
: split[i].charAt(0).toUpperCase();
|
|
|
|
split[i] = firstChar + split[i].slice(1);
|
|
}
|
|
|
|
return split.join("");
|
|
}
|
|
|
|
function typeToTypescript(type) {
|
|
switch (type) {
|
|
case "integer":
|
|
return "number";
|
|
case "short":
|
|
return "number";
|
|
case "string":
|
|
return "string";
|
|
default:
|
|
"any";
|
|
}
|
|
}
|
|
|
|
function scanStructs(root) {
|
|
const list = root["structs"]["struct"];
|
|
|
|
for (const struct of list) {
|
|
console.log(struct);
|
|
const structName = struct["@_name"];
|
|
structsOut.write("export interface " + structName + " {\n");
|
|
|
|
for (const [type, children] of Object.entries(struct)) {
|
|
// attributes start with @_
|
|
if (!type.startsWith("@_") && Array.isArray(children)) {
|
|
for (const child of children) {
|
|
const attributeName = toCamelCase(child["@_name"]);
|
|
structsOut.write(
|
|
attributeName + ": " + typeToTypescript(type) + ";\n"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
structsOut.write("}\n\n");
|
|
}
|
|
|
|
structsOut.end();
|
|
}
|
|
|
|
function scanEnumerations(root) {
|
|
const list = root["enumerations"]["enumeration"];
|
|
|
|
for (const enumeration of list) {
|
|
const enumName = enumeration["@_name"];
|
|
enumsOut.write("export enum " + enumName + " {\n");
|
|
|
|
for (const [type, children] of Object.entries(enumeration)) {
|
|
// attributes start with @_
|
|
if (!type.startsWith("@_")) {
|
|
for (const child of children) {
|
|
const attributeName = child["@_name"];
|
|
const attributeValue = child["#text"];
|
|
|
|
enumsOut.write(attributeName);
|
|
if (attributeValue) enumsOut.write(" = " + attributeValue);
|
|
|
|
enumsOut.write(",\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
enumsOut.write("}\n\n");
|
|
}
|
|
|
|
enumsOut.end();
|
|
}
|
|
|
|
function scanConstants(root) {
|
|
const list = root["constants"];
|
|
|
|
for (const [type, children] of Object.entries(list)) {
|
|
for (const child of children) {
|
|
const constName = child["@_name"];
|
|
const constValue = child["#text"];
|
|
|
|
constantsOut.write(
|
|
"export const " +
|
|
constName +
|
|
": " +
|
|
typeToTypescript(type) +
|
|
" = " +
|
|
constValue +
|
|
";\n"
|
|
);
|
|
}
|
|
}
|
|
|
|
constantsOut.end();
|
|
}
|
|
|
|
async function bindgen() {
|
|
const parser = new XMLParser({
|
|
attributeNamePrefix: "@_",
|
|
ignoreAttributes: false,
|
|
parseAttributeValue: true
|
|
});
|
|
|
|
const response = await fetch(source);
|
|
if (!response.ok) {
|
|
throw new Error(
|
|
"Failed to fetch the Milsko repository tags, try running npm run install or npm run update again (" +
|
|
response.status +
|
|
")"
|
|
);
|
|
}
|
|
|
|
const tags = await response.json();
|
|
const match = tags.find((k) => k.name == upstream);
|
|
|
|
if (!match) {
|
|
throw new Error(
|
|
"Could not find a tag that matches the upstream version " + upstream
|
|
);
|
|
}
|
|
|
|
const commitHash = match["id"]
|
|
const specURL = "https://forgejo.nishi.boats/pyrite-dev/milsko/raw/commit/" +
|
|
commitHash + "/milsko.xml";
|
|
|
|
const spac = await fetch(specURL);
|
|
if (!spac.ok) {
|
|
throw new Error(
|
|
"Failed to fetch the XML API specification with status code " +
|
|
spac.status
|
|
);
|
|
}
|
|
|
|
const raw = await spac.text();
|
|
const root = parser.parse(raw)["milsko"];
|
|
|
|
scanStructs(root);
|
|
scanEnumerations(root);
|
|
scanConstants(root);
|
|
}
|
|
|
|
bindgen();
|