initial commit
This commit is contained in:
commit
18255ce4cd
21 changed files with 1244 additions and 0 deletions
163
scripts/bindgen.js
Normal file
163
scripts/bindgen.js
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
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();
|
||||
59
scripts/download.js
Normal file
59
scripts/download.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { execSync } from "node:child_process";
|
||||
import { createWriteStream, mkdirSync } from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
import { join, resolve } from "node:path";
|
||||
import { Readable } from "node:stream";
|
||||
import { pipeline } from "node:stream/promises";
|
||||
import { t, extract as tarExtract } from "tar";
|
||||
|
||||
const extractDir = resolve("deps");
|
||||
const fileName = "milsko.tar.gz";
|
||||
const source =
|
||||
"https://forgejo.nishi.boats/api/v1/repos/pyrite-dev/milsko/tags";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const { upstream } = require("../package.json");
|
||||
|
||||
export async function download() {
|
||||
console.log("[Mw] Fetching Milsko release tags from", source);
|
||||
|
||||
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 tarUrl = match["tarball_url"];
|
||||
console.log("[Mw] Fetching tarball from " + tarUrl);
|
||||
|
||||
const tarball = await fetch(tarUrl);
|
||||
|
||||
const filePath = join(extractDir, fileName);
|
||||
mkdirSync(extractDir, { recursive: true }); // mkdir -p
|
||||
|
||||
const tarStream = Readable.fromWeb(tarball.body);
|
||||
const fileStream = createWriteStream(filePath);
|
||||
|
||||
await pipeline(tarStream, fileStream);
|
||||
await tarExtract({
|
||||
file: filePath,
|
||||
cwd: extractDir
|
||||
});
|
||||
|
||||
console.log("[Mw] Milsko library successfully installed!");
|
||||
}
|
||||
|
||||
if (import.meta.main)
|
||||
download();
|
||||
31
scripts/install.js
Normal file
31
scripts/install.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { execSync } from "node:child_process"
|
||||
import { createRequire } from "node:module";
|
||||
import { download } from "./download";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const forceBuild = process.env["npm_config_build_from_source"] == "true";
|
||||
|
||||
function hasPrebuilt() {
|
||||
let prebuilt = false;
|
||||
|
||||
try {
|
||||
require("node-gyp-build")("..");
|
||||
prebuilt = true;
|
||||
} catch (error) {
|
||||
prebuilt = false;
|
||||
}
|
||||
|
||||
return prebuilt;
|
||||
}
|
||||
|
||||
async function install() {
|
||||
console.log("[Mw] Downloading Milsko library...");
|
||||
await download();
|
||||
|
||||
console.log("[Mw] Building from source...");
|
||||
execSync("npx node-gyp rebuild", { stdio: "inherit" });
|
||||
}
|
||||
|
||||
if (forceBuild || !hasPrebuilt()) {
|
||||
install();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue