diff --git a/build.ts b/build.ts new file mode 100644 index 0000000..2b43f67 --- /dev/null +++ b/build.ts @@ -0,0 +1,99 @@ +import {promises as fs} from "fs"; +import * as swc from "@swc/core"; +import {fileURLToPath} from "node:url"; +import path from "node:path"; +import child_process from "child_process"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +async function moveFiles(path: string, newPath: string) { + async function processFile(file: string) { + const Prom: Promise[] = []; + if ((await fs.stat(path + "/" + file)).isDirectory()) { + await fs.mkdir(newPath + "/" + file); + Prom.push(moveFiles(path + "/" + file, newPath + "/" + file)); + } else { + if (!file.endsWith(".ts")) { + await fs.copyFile(path + "/" + file, newPath + "/" + file); + } else { + const plainname = file.split(".ts")[0]; + const newfileDir = newPath + "/" + plainname; + const mod = await swc.transformFile(path + "/" + file, { + minify: true, + sourceMaps: true, + isModule: true, + }); + await Promise.all([ + fs.writeFile( + newfileDir + ".js", + mod.code + "\n" + `//# sourceMappingURL= ${plainname}.js.map`, + ), + fs.writeFile(newfileDir + ".js.map", mod.map as string), + ]); + } + } + await Promise.all(Prom); + } + await Promise.all((await fs.readdir(path)).map(processFile)); +} +async function build() { + console.time("build"); + + console.time("Cleaning dir"); + try { + await fs.rm(__dirname + "/dist", {recursive: true}); + } catch {} + await fs.mkdir(__dirname + "/dist"); + console.timeEnd("Cleaning dir"); + + console.time("Moving and compiling files"); + await moveFiles(__dirname + "/src", __dirname + "/dist"); + console.timeEnd("Moving and compiling files"); + + console.time("Moving translations"); + let langs = await fs.readdir(__dirname + "/translations"); + langs = langs.filter((e) => e !== "qqq.json"); + const langobj = {}; + for (const lang of langs) { + const str = await fs.readFile("translations/" + lang); + const json = JSON.parse(str.toString()); + langobj[lang] = json.readableName; + fs.writeFile(__dirname + "/dist/webpage/translations/" + lang, str); + } + await fs.writeFile( + "dist/webpage/translations/langs.js", + `const langs=${JSON.stringify(langobj)};export{langs}`, + ); + console.timeEnd("Moving translations"); + + console.time("Adding git commit hash"); + const revision = child_process.execSync("git rev-parse HEAD").toString().trim(); + await fs.writeFile("dist/webpage/getupdates", revision); + console.timeEnd("Adding git commit hash"); + + console.timeEnd("build"); + console.log(""); +} + +await build(); +if (process.argv.includes("watch")) { + let last = Date.now(); + (async () => { + for await (const thing of fs.watch(__dirname + "/src")) { + if (Date.now() - last < 100) { + continue; + } + last = Date.now(); + await build(); + } + })(); + (async () => { + for await (const thing of fs.watch(__dirname + "/translations")) { + if (Date.now() - last < 100) { + continue; + } + last = Date.now(); + await build(); + } + })(); +} diff --git a/gulpfile.cjs b/gulpfile.cjs deleted file mode 100644 index 60f8067..0000000 --- a/gulpfile.cjs +++ /dev/null @@ -1,127 +0,0 @@ -const gulp = require("gulp"); -const ts = require("gulp-typescript"); -const tsProject = ts.createProject("tsconfig.json"); -const argv = require("yargs").argv; -const rimraf = require("rimraf"); -const plumber = require("gulp-plumber"); -const sourcemaps = require("gulp-sourcemaps"); -const fs = require("fs"); -const {swcDir} = require("@swc/cli"); - -gulp.task( - "watch", - function () { - gulp.watch("./src", gulp.series("default")); - gulp.watch("./translations", gulp.series("default")); - }, - {debounceDelay: 10}, -); - -// Clean task to delete the dist directory -gulp.task("clean", (cb) => { - return rimraf.rimraf("dist").then(cb()); -}); - -// Task to compile TypeScript files using SWC -gulp.task("scripts", async () => { - if (argv.swc || argv.bunswc) { - return await new Promise((ret) => { - swcDir({ - cliOptions: { - outDir: "./dist", - watch: false, - filenames: ["./src"], - extensions: [".ts"], - stripLeadingPaths: true, - }, - callbacks: { - onSuccess: (e) => { - ret(); - console.log(e); - }, - onFail: (e) => { - for ([, reason] of e.reasons) { - console.log(reason); - } - ret(); - }, - onWatchReady: () => {}, - }, - }); - }); - } else { - console.warn("[WARN] Using TSC compiler, will be slower than SWC"); - return gulp - .src("src/**/*.ts") - .pipe(sourcemaps.init()) - .pipe(plumber()) // Prevent pipe breaking caused by errors - .pipe(tsProject()) - .pipe(sourcemaps.write(".")) - .pipe(gulp.dest("dist")); - } -}); -gulp.task("commit", () => { - revision = require("child_process").execSync("git rev-parse HEAD").toString().trim(); - fs.writeFileSync("dist/webpage/getupdates", revision); - return new Promise((_) => _()); -}); -// Task to copy HTML files -gulp.task("copy-html", () => { - return gulp - .src("src/**/*.html") - .pipe(plumber()) // Prevent pipe breaking caused by errors - .pipe(gulp.dest("dist")); -}); -gulp.task("copy-translations", () => { - let langs = fs.readdirSync("translations"); - langs = langs.filter((e) => e !== "qqq.json"); - const langobj = {}; - for (const lang of langs) { - const json = JSON.parse(fs.readFileSync("translations/" + lang).toString()); - langobj[lang] = json.readableName; - } - if (!fs.existsSync("dist/webpage/translations")) fs.mkdirSync("dist/webpage/translations"); - fs.writeFileSync( - "dist/webpage/translations/langs.js", - `const langs=${JSON.stringify(langobj)};export{langs}`, - ); - return gulp - .src("translations/*.json") - .pipe(plumber()) // Prevent pipe breaking caused by errors - .pipe(gulp.dest("dist/webpage/translations")); -}); -// Task to copy other static assets (e.g., CSS, images) -gulp.task("copy-assets", () => { - return gulp - .src( - [ - "src/**/*.css", - "src/**/*.bin", - "src/**/*.ico", - "src/**/*.json", - "src/**/*.js", - "src/**/*.png", - "src/**/*.jpg", - "src/**/*.jpeg", - "src/**/*.webp", - "src/**/*.gif", - "src/**/*.svg", - "src/**/*.jasf", - "src/**/*.txt", - "src/**/*.woff2", - ], - {encoding: false}, - ) - .pipe(plumber()) // Prevent pipe breaking caused by errors - .pipe(gulp.dest("dist")); -}); - -// Default task to run all tasks -gulp.task( - "default", - gulp.series( - "clean", - gulp.parallel("scripts", "copy-html", "copy-assets"), - gulp.parallel("copy-translations", "commit"), - ), -); diff --git a/package.json b/package.json index 75c263d..79d846f 100644 --- a/package.json +++ b/package.json @@ -5,50 +5,28 @@ "main": ".dist/index.js", "type": "module", "scripts": { - "lint": "eslint .", - "build": "npx gulp", + "bunBuild": "bun build.ts", + "build": "node --experimental-strip-types build.ts", "start": "node dist/index.js" }, "author": "MathMan05", "license": "GPL-3.0", "dependencies": { - "compression": "^1.7.4", - "express": "^4.19.2", - "gulp-sourcemaps": "^2.6.5", - "prettier": "^3.4.2", - "rimraf": "^6.0.1" + "compression": "^1.8.0", + "@swc/core": "1.11.24", + "express": "^4.21.2" + }, + "devDependencies": { + "prettier": "^3.5.3", + "@types/compression": "^1.7.5", + "@types/express": "^4.17.21", + "@types/node-fetch": "^2.6.12", + "typescript": "^5.8.3" }, "prettier": { "useTabs": true, "printWidth": 100, "semi": true, "bracketSpacing": false - }, - "devDependencies": { - "@eslint/js": "^9.10.0", - "@html-eslint/eslint-plugin": "^0.25.0", - "@html-eslint/parser": "^0.27.0", - "@rsbuild/core": "^1.1.4", - "@rsbuild/plugin-node-polyfill": "^1.2.0", - "@stylistic/eslint-plugin": "^2.3.0", - "@stylistic/eslint-plugin-js": "^2.8.0", - "@swc/cli": "^0.5.2", - "@swc/core": "^1.10.1", - "@types/compression": "^1.7.5", - "@types/eslint__js": "^8.42.3", - "@types/express": "^4.17.21", - "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^8.14.0", - "@typescript-eslint/parser": "^8.14.0", - "eslint": "^8.57.1", - "eslint-plugin-html": "^8.1.1", - "eslint-plugin-sonarjs": "^1.0.4", - "eslint-plugin-unicorn": "^55.0.0", - "gulp": "^5.0.0", - "gulp-copy": "^5.0.0", - "gulp-plumber": "^1.2.1", - "gulp-typescript": "^6.0.0-alpha.1", - "typescript": "^5.6.2", - "typescript-eslint": "^8.14.0" } } diff --git a/src/index.ts b/src/index.ts index 0bc7ac0..bbdbc20 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,3 @@ -#!/usr/bin/env node - import compression from "compression"; import express, {Request, Response} from "express"; import fs from "node:fs/promises"; @@ -27,6 +25,7 @@ async function getDirectories(path: string): Promise { ), ); } + let dirs: dirtype | undefined = undefined; async function combinePath(path: string, tryAgain = true): Promise { if (!dirs) {