From d7fb38d47cc1af9849b595186c9a4af38514325d Mon Sep 17 00:00:00 2001 From: Nick Oates Date: Sat, 24 Aug 2024 21:03:14 -0700 Subject: [PATCH] Use TypeScript for build script --- build.js | 106 ------------------------------------------------- build.ts | 101 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- pnpm-lock.yaml | 27 +++++++++++++ 4 files changed, 130 insertions(+), 107 deletions(-) delete mode 100644 build.js create mode 100644 build.ts diff --git a/build.js b/build.js deleted file mode 100644 index 5cf542e..0000000 --- a/build.js +++ /dev/null @@ -1,106 +0,0 @@ -import esbuild from "esbuild"; -import fs from "fs"; -import path from "path"; -import crypto from "crypto"; - -const nativeExternals = ["@neptune", "@plugin", "electron"]; - -const minify = true; - -const plugins = fs.readdirSync("./plugins"); -for (const plugin of plugins) { - if (plugin.startsWith("_")) continue; - const pluginPath = path.join("./plugins/", plugin); - const pluginPackage = JSON.parse( - fs.readFileSync(path.join(pluginPath, "package.json"), "utf8") - ); - const outfile = path.join(pluginPath, "dist/index.js"); - - esbuild - .build({ - entryPoints: [ - "./" + path.join(pluginPath, pluginPackage.main ?? "index.js"), - ], - plugins: [ - { - name: "neptuneNativeImports", - setup(build) { - build.onLoad( - { filter: /.*[\/\\].+\.native\.[a-z]+/g }, - async (args) => { - const result = await esbuild.build({ - entryPoints: [args.path], - bundle: true, - minify, - platform: "node", - format: "iife", - globalName: "neptuneExports", - write: false, - external: nativeExternals, - }); - - const outputCode = result.outputFiles[0].text; - - // HATE! WHY WHY WHY WHY WHY (globalName breaks metafile. crying emoji) - const { metafile } = await esbuild.build({ - entryPoints: [args.path], - platform: "node", - write: false, - metafile: true, - bundle: true, - minify, - external: nativeExternals, - }); - - const builtExports = Object.values(metafile.outputs)[0].exports; - - return { - contents: `import {addUnloadable} from "@plugin";const contextId=NeptuneNative.createEvalScope(${JSON.stringify( - outputCode - )});${builtExports - .map( - (e) => - `export ${ - e == "default" ? "default " : `const ${e} =` - } NeptuneNative.getNativeValue(contextId,${JSON.stringify( - e - )})` - ) - .join( - ";" - )};addUnloadable(() => NeptuneNative.deleteEvalScope(contextId))`, - }; - } - ); - }, - }, - ], - bundle: true, - minify, - format: "esm", - external: ["@neptune", "@plugin"], - platform: "browser", - outfile, - logOverride: { - "import-is-undefined": "silent", - }, - }) - .then(() => { - fs.createReadStream(outfile) - // It being md5 does not matter, this is for caching and not security - .pipe(crypto.createHash("md5").setEncoding("hex")) - .on("finish", function () { - fs.writeFileSync( - path.join(pluginPath, "dist/manifest.json"), - JSON.stringify({ - name: pluginPackage.displayName, - description: pluginPackage.description, - author: pluginPackage.author, - hash: this.read(), - }) - ); - - console.log("Built " + pluginPackage.displayName + "!"); - }); - }); -} diff --git a/build.ts b/build.ts new file mode 100644 index 0000000..c40336a --- /dev/null +++ b/build.ts @@ -0,0 +1,101 @@ +import esbuild from "esbuild"; +import fs from "fs"; +import path from "path"; +import crypto from "crypto"; + +const nativeExternals = ["@neptune", "@plugin", "electron"]; + +const minify = true; + +const neptuneNativeImports: esbuild.Plugin = { + name: "neptuneNativeImports", + setup(build) { + build.onLoad({ filter: /.*[\/\\].+\.native\.[a-z]+/g }, async (args) => { + const result = await esbuild.build({ + entryPoints: [args.path], + bundle: true, + minify, + platform: "node", + format: "iife", + globalName: "neptuneExports", + write: false, + external: nativeExternals, + }); + + const outputCode = result.outputFiles[0].text; + + // HATE! WHY WHY WHY WHY WHY (globalName breaks metafile. crying emoji) + const { metafile } = await esbuild.build({ + entryPoints: [args.path], + platform: "node", + write: false, + metafile: true, + bundle: true, + minify, + external: nativeExternals, + }); + + const builtExports = Object.values(metafile.outputs)[0].exports; + + return { + contents: `import {addUnloadable} from "@plugin";const contextId=NeptuneNative.createEvalScope(${JSON.stringify( + outputCode + )});${builtExports + .map( + (e) => + `export ${ + e == "default" ? "default " : `const ${e} =` + } NeptuneNative.getNativeValue(contextId,${JSON.stringify(e)})` + ) + .join( + ";" + )};addUnloadable(() => NeptuneNative.deleteEvalScope(contextId))`, + }; + }); + }, +}; + +const plugins = fs.readdirSync("./plugins"); +for (const plugin of plugins) { + if (plugin.startsWith("_")) continue; + const pluginPath = path.join("./plugins/", plugin); + const pluginPackage = JSON.parse( + fs.readFileSync(path.join(pluginPath, "package.json"), "utf8") + ); + const outfile = path.join(pluginPath, "dist/index.js"); + + esbuild + .build({ + entryPoints: [ + "./" + path.join(pluginPath, pluginPackage.main ?? "index.js"), + ], + plugins: [neptuneNativeImports], + bundle: true, + minify, + format: "esm", + external: ["@neptune", "@plugin"], + platform: "browser", + outfile, + logOverride: { + "import-is-undefined": "silent", + }, + }) + .then(() => { + fs.createReadStream(outfile) + // It being md5 does not matter, this is for caching and not security + .pipe(crypto.createHash("md5").setEncoding("hex")) + .on("finish", function (this: crypto.Hash) { + fs.writeFileSync( + path.join(pluginPath, "dist/manifest.json"), + JSON.stringify({ + name: pluginPackage.displayName, + description: pluginPackage.description, + author: pluginPackage.author, + hash: this.read(), + }) + ); + + console.log("Built " + pluginPackage.displayName + "!"); + }); + }); +} diff --git a/package.json b/package.json index f97b669..3428e9a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "type": "module", "scripts": { "watch": "concurrently nodemon npm:serve", - "build": "node ./build.js", + "build": "tsx build.ts", "serve": "serve -C ./plugins" }, "devDependencies": { @@ -15,6 +15,7 @@ "neptune-types": "^1.0.1", "nodemon": "^3.1.4", "serve": "^14.2.3", + "tsx": "^4.18.0", "typescript": "^5.5.4" }, "dependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76e9e16..b93d492 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,6 +45,9 @@ importers: serve: specifier: ^14.2.3 version: 14.2.3 + tsx: + specifier: ^4.18.0 + version: 4.18.0 typescript: specifier: ^5.5.4 version: 5.5.4 @@ -866,6 +869,9 @@ packages: resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} engines: {node: '>=18'} + get-tsconfig@4.7.6: + resolution: {integrity: sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==} + gifwrap@0.9.4: resolution: {integrity: sha512-MDMwbhASQuVeD4JKd1fKgNgCRL3fGqMM4WaqpNhWO0JiMOAjbQdumbs4BbBZEy9/M00EHEjKN3HieVhCUlwjeQ==} @@ -1326,6 +1332,9 @@ packages: resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} @@ -1519,6 +1528,11 @@ packages: tslib@2.6.3: resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + tsx@4.18.0: + resolution: {integrity: sha512-a1jaKBSVQkd6yEc1/NI7G6yHFfefIcuf3QJST7ZEyn4oQnxLYrZR5uZAM8UrwUa3Ge8suiZHcNS1gNrEvmobqg==} + engines: {node: '>=18.0.0'} + hasBin: true + tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -2421,6 +2435,10 @@ snapshots: '@sec-ant/readable-stream': 0.4.1 is-stream: 4.0.1 + get-tsconfig@4.7.6: + dependencies: + resolve-pkg-maps: 1.0.0 + gifwrap@0.9.4: dependencies: image-q: 4.0.0 @@ -2857,6 +2875,8 @@ snapshots: resolve-alpn@1.2.1: {} + resolve-pkg-maps@1.0.0: {} + responselike@2.0.1: dependencies: lowercase-keys: 2.0.0 @@ -3103,6 +3123,13 @@ snapshots: tslib@2.6.3: {} + tsx@4.18.0: + dependencies: + esbuild: 0.23.1 + get-tsconfig: 4.7.6 + optionalDependencies: + fsevents: 2.3.3 + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1