Update builder and migrate to ESM #3

Merged
Sirherobrine23 merged 7 commits from ci_zig into main 2024-02-17 16:41:50 +00:00
20 changed files with 140 additions and 524 deletions

@ -1,100 +0,0 @@
name: Test
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
linux_test:
runs-on: ubuntu-latest
strategy:
matrix:
node_version: [ 16.x, 18.x, 19.x, 20.x, 21.x ]
steps:
- uses: actions/checkout@v4
name: Checkout
- uses: actions/setup-node@v4
name: Setup Node.js
with:
node-version: ${{ matrix.node_version }}
- name: Install dependencies
run: |
echo "Host arch: $(uname -m)"
export DEBIAN_FRONTEND=noninteractive
sudo apt update
packages=(
"binutils-multiarch"
"build-essential"
);
# if [[ $(uname -m) == "x86_64" ]]; then
# packages+=(
# "libc6-arm64-cross"
# "gcc-*aarch64-linux-gnu"
# "gcc-*aarch64-linux-gnu-base"
# "g++-*aarch64-linux-gnu"
# )
# else
# packages+=(
# "libc6-amd64-cross"
# "g++-*x86-64-linux-gnu"
# "gcc-*x86-64-linux-gnu"
# )
# if [[ $(uname -m) != "aarch64" ]]; then
# packages+=(
# "libc6-arm64-cross"
# "gcc-*aarch64-linux-gnu"
# "gcc-*aarch64-linux-gnu-base"
# "g++-*aarch64-linux-gnu"
# )
# fi
# fi
sudo apt install -y ${packages[@]}
npm install --no-save --ignore-scripts
- name: Build addon
run: npm run dev
- name: Upload prebuilds interface
uses: actions/upload-artifact@v3
with:
retention-days: 7
name: prebuilds_${{ runner.os }}_${{ matrix.node_version }}
path: "prebuilds/**"
- name: Test
run: node --require ts-node/register --loader ts-node/esm ./src/index_test.ts
pack_package:
needs: linux_test
runs-on: ubuntu-latest
name: Pack npm package
env:
PACKAGE_VERSION: ${{ github.ref }}
steps:
- uses: actions/checkout@v4
name: Code checkout
- uses: actions/setup-node@v4
name: Setup node.js
with:
node-version: 20.x
registry-url: https://registry.npmjs.org/
- name: Download all artefacts
uses: actions/download-artifact@v3
with:
path: ./prebuilds
- run: npm install --no-save --ignore-scripts
- run: npm pack
- name: Upload npm package
uses: actions/upload-artifact@v3
with:
name: Package_Pack
path: "*.tgz"

@ -13,10 +13,20 @@ jobs:
strategy: strategy:
matrix: matrix:
node_version: [ 16.x, 18.x, 19.x, 20.x, 21.x ] node_version: [ 16.x, 18.x, 19.x, 20.x, 21.x ]
target_arch: [ "x86_64", "aarch64" ]
target_os:
- "linux"
# - "windows"
# - "macos"
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
name: Checkout name: Checkout
- name: "Setup zig"
uses: korandoru/setup-zig@v1
with:
zig-version: "master"
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
name: Setup Node.js name: Setup Node.js
with: with:
@ -26,96 +36,24 @@ jobs:
run: | run: |
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
sudo apt update sudo apt update
sudo apt install -y binutils-multiarch gcc-*aarch64-linux-gnu gcc-*aarch64-linux-gnu-base g++-*aarch64-linux-gnu libc6-arm64-cross sudo apt install -y "binutils-multiarch" "build-essential"
npm install --no-save --ignore-scripts npm install --no-save --ignore-scripts
- name: Build addon - name: Build addon
run: npm run prebuildify -- -v run: npm run dev -- --target_zig=${{ matrix.target_arch }}-${{ matrix.target_os }}
- name: Test
run: sudo -E node --require ts-node/register --loader ts-node/esm ./src/index_test.ts
- name: Upload prebuilds interface - name: Upload prebuilds interface
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
retention-days: 7 retention-days: 7
name: prebuilds_${{ runner.os }} name: prebuilds_${{ matrix.target_arch }}-${{ matrix.target_os }}_${{ matrix.node_version }}
path: "prebuilds/**" path: "prebuilds/**"
macos_test:
runs-on: macos-latest
strategy:
matrix:
node_version: [ 16.x, 18.x, 19.x, 20.x, 21.x ]
steps:
- uses: actions/checkout@v4
name: Checkout
- uses: actions/setup-node@v4
name: Setup Node.js
with:
node-version: ${{ matrix.node_version }}
- name: Setup Go environment
uses: actions/setup-go@v5.0.0
- name: Setup wireguard-go
run: |
cd ..
git clone https://git.zx2c4.com/wireguard-go
cd wireguard-go
echo "WG_INETRFACE=utun15" >> $GITHUB_ENV
go build -v -o "wireguard-go"
sudo ./wireguard-go utun15
- name: Install dependencies
run: npm install --no-save --ignore-scripts
- name: Build addon
run: npm run prebuildify -- -v
- name: Test
run: sudo -E node --require ts-node/register --loader ts-node/esm ./src/index_test.ts
- name: Upload prebuilds interface
uses: actions/upload-artifact@v3
with:
retention-days: 7
name: prebuilds_${{ runner.os }}
path: "prebuilds/**"
win_test:
runs-on: windows-latest
strategy:
matrix:
node_version: [ 16.x, 18.x, 19.x, 20.x, 21.x ]
steps:
- uses: actions/checkout@v4
name: Checkout
- uses: actions/setup-node@v4
name: Setup Node.js
with:
node-version: ${{ matrix.node_version }}
- name: Install dependencies
run: npm install --no-save --ignore-scripts
- name: Build addon
run: npm run prebuildify -- -v
- name: Test - name: Test
run: node --require ts-node/register --loader ts-node/esm ./src/index_test.ts run: node --require ts-node/register --loader ts-node/esm ./src/index_test.ts
- name: Upload prebuilds interface
uses: actions/upload-artifact@v3
with:
retention-days: 7
name: prebuilds_${{ runner.os }}
path: "prebuilds/**"
pack_package: pack_package:
needs: [ linux_test, macos_test, win_test ] needs: linux_test
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: Pack npm package name: Pack npm package
env: env:

@ -12,8 +12,7 @@
"source.organizeImports": "explicit" "source.organizeImports": "explicit"
}, },
"files.exclude": { "files.exclude": {
"**/node_modules/": true, "**/node_modules/": true
"**/build/": true
}, },
"terminal.integrated.env.windows": { "terminal.integrated.env.windows": {
"PATH": "${workspaceFolder}/node_modules/.bin;${env:PATH}" "PATH": "${workspaceFolder}/node_modules/.bin;${env:PATH}"

@ -1,9 +1,8 @@
#include <napi.h> #include <napi.h>
#include <wginterface.hh> #include <wginterface.hh>
#include <net/if.h>
unsigned long maxName() { unsigned long maxName() {
return IFNAMSIZ; return 16;
} }
std::string versionDrive() { std::string versionDrive() {

@ -24,7 +24,6 @@
#include <setupapi.h> #include <setupapi.h>
#include <cfgmgr32.h> #include <cfgmgr32.h>
#include <devguid.h> #include <devguid.h>
#include <ndisguid.h>
#include "wginterface.hh" #include "wginterface.hh"
#include <wgkeys.hh> #include <wgkeys.hh>
@ -61,14 +60,14 @@ std::string getErrorString(DWORD errorMessageID) {
return std::string("Error code: ").append(std::to_string(errorMessageID)).append(", Message: ").append(message); return std::string("Error code: ").append(std::to_string(errorMessageID)).append(", Message: ").append(message);
} }
std::string startAddon(const Napi::Env env) { std::string startAddon(const Napi::Env env, Napi::Object exports) {
if (!IsRunAsAdmin()) return "Run nodejs with administrator privilegies"; if (!IsRunAsAdmin()) return "Run nodejs with administrator privilegies";
auto DLLPATH = env.Global().ToObject().Get("WIREGUARD_DLL_PATH"); auto DLLPATH = exports.Get("WIREGUARD_DLL_PATH");
if (!(DLLPATH.IsString())) return "Require WIREGUARD_DLL_PATH in Global process"; if (!(DLLPATH.IsString())) return "Require WIREGUARD_DLL_PATH in addon load!";
LPCWSTR dllPath = toLpcwstr(DLLPATH.ToString()); LPCWSTR dllPath = toLpcwstr(DLLPATH.ToString());
HMODULE WireGuardDll = LoadLibraryExW(dllPath, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32); HMODULE WireGuardDll = LoadLibraryExW(dllPath, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!WireGuardDll) return ((std::string)"Failed to initialize WireGuardNT, ").append(getErrorString(GetLastError()));; if (!WireGuardDll) return std::string("Failed to initialize WireGuardNT, ").append(getErrorString(GetLastError()));;
#define X(Name) ((*(FARPROC *)&Name = GetProcAddress(WireGuardDll, #Name)) == NULL) #define X(Name) ((*(FARPROC *)&Name = GetProcAddress(WireGuardDll, #Name)) == NULL)
if (X(WireGuardCreateAdapter) || X(WireGuardOpenAdapter) || X(WireGuardCloseAdapter) || X(WireGuardGetAdapterLUID) || X(WireGuardGetRunningDriverVersion) || X(WireGuardDeleteDriver) || X(WireGuardSetLogger) || X(WireGuardSetAdapterLogging) || X(WireGuardGetAdapterState) || X(WireGuardSetAdapterState) || X(WireGuardGetConfiguration) || X(WireGuardSetConfiguration)) if (X(WireGuardCreateAdapter) || X(WireGuardOpenAdapter) || X(WireGuardCloseAdapter) || X(WireGuardGetAdapterLUID) || X(WireGuardGetRunningDriverVersion) || X(WireGuardDeleteDriver) || X(WireGuardSetLogger) || X(WireGuardSetAdapterLogging) || X(WireGuardGetAdapterState) || X(WireGuardSetAdapterState) || X(WireGuardGetConfiguration) || X(WireGuardSetConfiguration))
#undef X #undef X
@ -76,7 +75,7 @@ std::string startAddon(const Napi::Env env) {
DWORD LastError = GetLastError(); DWORD LastError = GetLastError();
FreeLibrary(WireGuardDll); FreeLibrary(WireGuardDll);
SetLastError(LastError); SetLastError(LastError);
return ((std::string)"Failed to set Functions from WireGuardNT DLL, ").append(getErrorString(GetLastError()));; return std::string("Failed to set Functions from WireGuardNT DLL, ").append(getErrorString(GetLastError()));;
} }
return ""; return "";
@ -89,10 +88,10 @@ std::string versionDrive() {
auto statusErr = GetLastError(); auto statusErr = GetLastError();
WireGuardCloseAdapter(Adapter); WireGuardCloseAdapter(Adapter);
if (statusErr == ERROR_FILE_NOT_FOUND) return "Driver not loaded"; if (statusErr == ERROR_FILE_NOT_FOUND) return "Driver not loaded";
return ((std::string)"Cannot get version drive, ").append(getErrorString(GetLastError())); return std::string("Cannot get version drive, ").append(getErrorString(GetLastError()));
} }
WireGuardCloseAdapter(Adapter); WireGuardCloseAdapter(Adapter);
return ((std::string)"WireGuardNT v").append(std::to_string((Version >> 16) & 0xff)).append(".").append(std::to_string((Version >> 0) & 0xff)); return std::string("WireGuardNT v").append(std::to_string((Version >> 16) & 0xff)).append(".").append(std::to_string((Version >> 0) & 0xff));
} }
void listDevices::Execute() { void listDevices::Execute() {
@ -197,7 +196,7 @@ void getConfig::Execute() {
free(wg_iface); free(wg_iface);
if (GetLastError() != ERROR_MORE_DATA) return SetError((std::string("Failed get interface config, code: ")).append(std::to_string(GetLastError()))); if (GetLastError() != ERROR_MORE_DATA) return SetError((std::string("Failed get interface config, code: ")).append(std::to_string(GetLastError())));
wg_iface = (WIREGUARD_INTERFACE *)malloc(buf_len); wg_iface = (WIREGUARD_INTERFACE *)malloc(buf_len);
if (!wg_iface) return SetError(((std::string)"Failed get interface config, ").append(std::to_string(-errno))); if (!wg_iface) return SetError(std::string("Failed get interface config, ").append(std::to_string(-errno)));
} }
if (wg_iface->Flags & WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PRIVATE_KEY) privateKey = wgKeys::toString(wg_iface->PrivateKey); if (wg_iface->Flags & WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PRIVATE_KEY) privateKey = wgKeys::toString(wg_iface->PrivateKey);
@ -268,7 +267,8 @@ void setConfig::Execute() {
wgKeys::stringToKey(wg_peer->PublicKey, peerPublicKey); wgKeys::stringToKey(wg_peer->PublicKey, peerPublicKey);
} catch (std::string &err) { } catch (std::string &err) {
SetError(err); SetError(err);
goto outEnd; free(wg_iface);
return;
} }
wg_peer->Flags = WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PUBLIC_KEY; wg_peer->Flags = WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PUBLIC_KEY;
wg_peer->AllowedIPsCount = 0; wg_peer->AllowedIPsCount = 0;
@ -284,7 +284,8 @@ void setConfig::Execute() {
wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PRESHARED_KEY); wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PRESHARED_KEY);
} catch (std::string &err) { } catch (std::string &err) {
SetError(err); SetError(err);
goto outEnd; free(wg_iface);
return;
} }
} }
@ -297,7 +298,8 @@ void setConfig::Execute() {
wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_ENDPOINT); wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_ENDPOINT);
} catch (std::string &err) { } catch (std::string &err) {
SetError(std::string("Cannot parse endpoint, ").append(err)); SetError(std::string("Cannot parse endpoint, ").append(err));
goto outEnd; free(wg_iface);
return;
} }
} }
@ -325,7 +327,7 @@ void setConfig::Execute() {
WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(wgName)); WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(wgName));
if (!Adapter) Adapter = WireGuardCreateAdapter(toLpcwstr(wgName), L"Wireguard-tools.js", NULL); if (!Adapter) Adapter = WireGuardCreateAdapter(toLpcwstr(wgName), L"Wireguard-tools.js", NULL);
if (!Adapter) SetError(((std::string)"Failed to create adapter, ").append(getErrorString(GetLastError()))); if (!Adapter) SetError(std::string("Failed to create adapter, ").append(getErrorString(GetLastError())));
else if (!WireGuardSetConfiguration(Adapter, reinterpret_cast<WIREGUARD_INTERFACE*>(wg_iface), buf_len)) { else if (!WireGuardSetConfiguration(Adapter, reinterpret_cast<WIREGUARD_INTERFACE*>(wg_iface), buf_len)) {
auto status = GetLastError(); auto status = GetLastError();
SetError(std::string("Failed to set interface config, ").append(getErrorString(status))); SetError(std::string("Failed to set interface config, ").append(getErrorString(status)));
@ -357,6 +359,5 @@ void setConfig::Execute() {
} }
} }
} }
outEnd:
free(wg_iface); free(wg_iface);
} }

@ -5,7 +5,7 @@
Napi::Object Init(Napi::Env initEnv, Napi::Object exports) { Napi::Object Init(Napi::Env initEnv, Napi::Object exports) {
/// Call Addon /// Call Addon
#ifdef ONSTARTADDON #ifdef ONSTARTADDON
auto status = startAddon(initEnv); auto status = startAddon(initEnv, exports);
if (status.length() >= 1) { if (status.length() >= 1) {
Napi::Error::New(initEnv, status).ThrowAsJavaScriptException(); Napi::Error::New(initEnv, status).ThrowAsJavaScriptException();
return exports; return exports;

@ -12,7 +12,7 @@ unsigned long maxName();
std::string versionDrive(); std::string versionDrive();
// On start module call this function // On start module call this function
std::string startAddon(const Napi::Env env); std::string startAddon(const Napi::Env env, Napi::Object exports);
class deleteInterface : public Napi::AsyncWorker { class deleteInterface : public Napi::AsyncWorker {
private: private:

@ -1,110 +0,0 @@
{
"target_defaults": {
"cflags!": [ "-fno-exceptions" ],
"cflags_cc!": [ "-fno-exceptions" ],
"defines": [
"NAPI_DISABLE_CPP_EXCEPTIONS"
],
"conditions": [
["OS=='win'", {
"defines": [
"_HAS_EXCEPTIONS=1"
],
"msvs_settings": {
"VCCLCompilerTool": {
"ExceptionHandling": 1
},
},
}],
["OS=='mac'", {
"xcode_settings": {
"GCC_ENABLE_CPP_EXCEPTIONS": "YES"
},
}],
],
"include_dirs": [
"<!(node -p \"require('node-addon-api').include_dir\")"
],
"cflags": [
"-fpermissive",
"-fexceptions",
"-w",
"-fpermissive",
"-fPIC",
"-static"
],
"cflags_cc": [
"-fpermissive",
"-fexceptions",
"-w",
"-fpermissive",
"-fPIC",
"-static"
]
},
"targets": [
{
"target_name": "wginterface",
"include_dirs": [
"addons/genKey",
"addons/tools"
],
"sources": [
"addons/genKey/wgkeys.cpp",
"addons/tools/wginterface.cpp"
],
"conditions": [
["OS=='linux'", {
"defines": [
"LISTDEV",
"GETCONFIG",
"SETCONFIG",
"DELIFACE"
],
"sources": [
"addons/tools/linux/wireguard.c",
"addons/tools/wginterface-linux.cpp"
]
}],
["OS=='mac'", {
"cflags!": [ "-fno-exceptions" ],
"cflags_cc!": [ "-fno-exceptions" ],
"cflags_cc": [ "-fexceptions" ],
"cflags": [ "-fexceptions" ],
"xcode_settings": {
"GCC_ENABLE_CPP_EXCEPTIONS": "YES"
}
}],
["OS=='win'", {
"include_dirs": [
"addons/tools/win"
],
"defines": [
"ONSTARTADDON",
"LISTDEV",
"GETCONFIG",
"SETCONFIG",
"DELIFACE"
],
"libraries": [
"bcrypt.lib",
"crypt32.lib",
"iphlpapi.lib",
"kernel32.lib",
"ntdll.lib",
"ws2_32.lib",
"setupapi.lib"
],
"sources": [
"addons/tools/wginterface-win.cpp"
]
}],
["OS not in 'linux win'", {
"sources": [
"addons/tools/wginterface-dummy.cpp"
]
}]
]
}
]
}

67
binding.yaml Normal file

@ -0,0 +1,67 @@
- name: wginterface
ncflags:
- "-fno-exceptions"
nflags_cc:
- "-fno-exceptions"
defines:
- "NAPI_DISABLE_CPP_EXCEPTIONS"
- "NODE_VERSION=4"
cflags:
- "-fpermissive"
- "-fexceptions"
- "-w"
- "-fpermissive"
flags_cc:
- "-fpermissive"
- "-fexceptions"
- "-w"
- "-fpermissive"
includes:
- addons/genKey
- addons/tools
- node_modules/node-addon-api
sources:
- "addons/genKey/wgkeys.cpp"
- "addons/tools/wginterface.cpp"
- "addons/tools/wginterface-dummy.cpp"
target:
linux:
sources:
- "addons/tools/linux/wireguard.c"
- "addons/tools/wginterface-linux.cpp"
- "!addons/tools/wginterface-dummy.cpp"
defines:
- "LISTDEV"
- "GETCONFIG"
- "SETCONFIG"
- "DELIFACE"
cflags:
- "-fPIC"
flags_cc:
- "-fPIC"
macos:
cflags_cc:
- "-fexceptions"
cflags:
- "-fexceptions"
windows:
sources:
- "addons/tools/wginterface-win.cpp"
- "!addons/tools/wginterface-dummy.cpp"
includes:
- "addons/tools/win"
defines:
- "ONSTARTADDON"
- "LISTDEV"
- "GETCONFIG"
- "SETCONFIG"
- "DELIFACE"
- "_HAS_EXCEPTIONS=1"
libraries:
- "bcrypt.lib"
- "crypt32.lib"
- "iphlpapi.lib"
- "kernel32.lib"
- "ntdll.lib"
- "ws2_32.lib"
- "setupapi.lib"

@ -1,14 +0,0 @@
import * as __wg from "./src/index.js";
export const {
constants,
key,
key_experimental,
wgQuick,
wginterface,
getConfig,
setConfig,
listDevices,
deleteInterface,
} = __wg;
export default __wg.default;

@ -1,138 +0,0 @@
// @ts-check
import child_process from "node:child_process";
import { promises as fs } from "node:fs";
import { createRequire } from "node:module";
import path from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Fix ESM __dirname
const nodeGyp = path.resolve(createRequire(import.meta.url).resolve("node-gyp"), "../../bin/node-gyp.js"); // Node gyp script
const env = Object.assign({}, process.env);
const prebuilds = path.resolve(__dirname, "../prebuilds");
const buildDir = path.resolve(__dirname, "../build") /* Build Directory */, buildRelease = path.join(buildDir, "Release"), buildDebug = path.join(buildDir, "Debug");
async function exist(path) {
return fs.open(path).then(e => e.close().then(() => true, () => true), () => false);
}
/**
*
* @param {string} command
* @param {string[]} args
* @param {Omit<import("child_process").ForkOptions, "stdio">} options
*/
async function fork(command, args, options) {
if (options) options["stdio"] = undefined;
console.log("%s", command, ...args);
return new Promise((done, reject) => {
const child = child_process.fork(command, args, options);
child.on("error", reject);
if (child.stdout) child.stdout.once("data", function log(data) { process.stdout.write(data); if (child.stdout) child.stdout.once("data", log); });
if (child.stderr) child.stderr.once("data", function log(data) { process.stderr.write(data); if (child.stderr) child.stderr.once("data", log); });
child.once("exit", (code, sig) => {
if (code === 0) return done(0);
return reject(new Error(("Process exit with ").concat(String(code), " and signal ", String(sig))));
});
});
}
// Fix CI prebuild download
if (await exist(prebuilds)) {
for (const folderLayer1 of await fs.readdir(prebuilds)) {
let toRm = false;
for (const folderLayer2 of await fs.readdir(path.join(prebuilds, folderLayer1))) {
const currentFolder = path.join(prebuilds, folderLayer1, folderLayer2);
if ((await fs.lstat(currentFolder)).isDirectory()) {
toRm = true;
const newFolder = path.join(prebuilds, folderLayer2);
console.log("\nMigrate from %O to %O", currentFolder, newFolder);
if (await exist(newFolder)) await fs.rm(newFolder, { recursive: true, force: true });
await fs.mkdir(newFolder, { recursive: true });
await Promise.all((await fs.readdir(currentFolder)).map(async p => {
console.log("Copy %O", path.join(currentFolder, p));
return fs.copyFile(path.join(currentFolder, p), path.join(newFolder, p))
}));
await fs.rm(currentFolder, { recursive: true, force: true });
}
}
if (toRm) await fs.rm(path.join(prebuilds, folderLayer1), { recursive: true, force: true });
}
}
/**
*
* @param {string} platform
* @param {string} arch
*/
async function migrateBuildAddon(platform, arch) {
const files = (await fs.readdir(buildRelease)).filter(f => f.endsWith(".node"));
const targetPath = path.join(prebuilds, `${platform}_${arch}`);
if (await exist(targetPath)) await fs.rm(targetPath, {recursive: true, force: true});
await fs.mkdir(targetPath, {recursive: true});
for (const file of files) {
console.log("Move %O to %O", path.join(buildRelease, file), path.join(targetPath, file));
await fs.rename(path.join(buildRelease, file), path.join(targetPath, file));
}
await fs.rm(buildDir, { recursive: true, force: true });
}
if (process.argv.slice(2).at(0) === "build") {
let archs = [];
if (process.argv.includes("--clean")) {
if (await exist(buildDir)) await fs.rm(buildDir, { recursive: true, force: true });
if (await exist(prebuilds)) await fs.rm(prebuilds, { recursive: true, force: true });
}
if (process.argv.includes("--auto")) {
if (process.platform === "linux") archs.push("x64", "arm64");
else if (process.platform === "win32") archs.push("x64", "arm64");
else if (process.platform === "darwin") archs.push("x64", "arm64");
else archs.push(process.arch);
} else {
process.argv.slice(2).filter(f => f.startsWith("--arch=")).map(arch => arch.slice(7));
if (archs.length <= 0) archs.push(process.arch);
}
for (const arch of Array.from(new Set(archs))) {
if (process.platform === "linux" && arch !== process.arch) {
if (arch === "x64") {
// x86_64-linux-gnu-gcc
env.CC = "x86_64-linux-gnu-gcc";
env.CXX = "x86_64-linux-gnu-g++";
} else if (arch === "arm64") {
// aarch64-linux-gnu-gcc
env.CC = "aarch64-linux-gnu-gcc";
env.CXX = "aarch64-linux-gnu-g++";
}
} else if (process.platform === "win32" && arch !== process.arch) {
let skip = true;
for (const vsPath of [ "C:\\Program Files (x86)\\Microsoft Visual Studio", "C:\\Program Files\\Microsoft Visual Studio" ]) {
if (!(await exist(vsPath))) continue;
const year = ((await fs.readdir(vsPath)).filter(s => !(isNaN(Number(s)))).sort((a, b) => (Number(a) < Number(b)) ? -1 : 0).at(-1));
if (!year) continue;
for (const vsEdition of await fs.readdir(path.join(vsPath, year))) {
if (await exist(path.join(vsPath, year, vsEdition, "MSBuild\\Current\\Bin", arch))) {
if (skip) skip = false;
break;
}
}
if (!skip) break;
}
if (skip) {
console.info("Arch not avaible to copiler!");
continue;
}
}
try {
console.log("Bulding to %O\n", arch);
await fork(nodeGyp, ["rebuild", ...(process.platform !== "android"?["-j", "max"]:[]), ("--arch=").concat(arch)], {env});
console.log("Migrating addons!");
await migrateBuildAddon(process.platform, arch);
} catch (err) {
if (process.platform === "win32" && arch !== process.arch) continue;
throw err;
}
}
} else if (!(await exist(path.join(prebuilds, `${process.platform}_${process.arch}`)) || await exist(buildRelease))) {
await fork(nodeGyp, ["rebuild", ...(process.platform !== "android"?["-j", "max"]:[])], {env});
await migrateBuildAddon(process.platform, process.arch);
}

@ -1,33 +0,0 @@
const fs = require("fs");
const path = require("path");
module.exports = main;
/**
* Load node addon
* @param {string|number|undefined} name
* @param {string|undefined} path
* @returns {any}
*/
function main(name, pathLocation) {
if (!pathLocation) pathLocation = path.resolve(__dirname, "..");
else pathLocation = path.resolve(process.cwd(), pathLocation);
const folders = [
path.join(pathLocation, "build", "Release"),
path.join(pathLocation, "build", "Debug"),
path.join(pathLocation, "prebuilds", `${process.platform}_${process.arch}`),
path.join(pathLocation, "prebuilds", `${process.platform}-${process.arch}`),
];
for (const folder of folders) {
if (fs.existsSync(folder)) {
const files = (fs.readdirSync(folder)).filter(file => file.endsWith(".node"));
if (typeof name === "number") return require(path.join(folder, files.at(name)));
else if (!name) name = files.at(0);
if (typeof name === "string") {
const bname = name.concat("");
if ((name = files.find(s => s.startsWith(name)))) return require(path.join(folder, name));
name = bname;
}
}
}
throw new Error("Cannot get node addon");
}

@ -3,17 +3,9 @@
"version": "1.8.3", "version": "1.8.3",
"description": "Control your wireguard interface from node.js, not a wireguard-tools/wg wrapper!", "description": "Control your wireguard interface from node.js, not a wireguard-tools/wg wrapper!",
"private": false, "private": false,
"type": "commonjs", "type": "module",
"main": "./src/index.js", "main": "./src/index.js",
"types": "./src/index.d.ts", "types": "./src/index.d.ts",
"default": "./index.mjs",
"exports": {
".": {
"require": "./src/index.js",
"default": "./index.mjs",
"types": "./src/index.d.ts"
}
},
"homepage": "https://sirherobrine23.org/Wireguard/Wireguard-tools.js#readme", "homepage": "https://sirherobrine23.org/Wireguard/Wireguard-tools.js#readme",
"author": "Matheus Sampaio Queiroga <srherobrine20@gmail.com> (https://sirherobrine23.org/)", "author": "Matheus Sampaio Queiroga <srherobrine20@gmail.com> (https://sirherobrine23.org/)",
"license": "GPL-3.0-or-later", "license": "GPL-3.0-or-later",
@ -41,20 +33,18 @@
"node": ">=16.0.0" "node": ">=16.0.0"
}, },
"scripts": { "scripts": {
"install": "node libs/build.mjs", "install": "rebory prebuild",
"test": "node libs/build.mjs build --clean && node --require ts-node/register --loader ts-node/esm --test src/**/*_test.ts", "dev": "rebory build -DP",
"dev": "node libs/build.mjs build", "prepack": "tsc --build --clean && tsc --build",
"prebuildify": "node libs/build.mjs build --auto",
"prepack": "tsc --build --clean && tsc --build && node libs/build.mjs",
"postpack": "tsc --build --clean" "postpack": "tsc --build --clean"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.11.0", "@types/node": "^20.11.19",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },
"dependencies": { "dependencies": {
"node-addon-api": "^7.0.0", "node-addon-api": "^7.1.0",
"node-gyp": "^10.0.1" "rebory": "^0.1.10"
} }
} }

@ -1,5 +1,5 @@
export * as key from "./key"; export * as key from "./key.js";
export * as wgQuick from "./quick"; export * as wgQuick from "./quick.js";
export * from "./wginterface"; export * from "./wginterface.js";
export * as wginterface from "./wginterface"; export * as wginterface from "./wginterface.js";
export * as default from "./wginterface"; export * as default from "./wginterface.js";

@ -1,2 +1,2 @@
import "./quick_test"; import "./quick_test.js";
import "./key_test"; import "./key_test.js";

@ -1,6 +1,6 @@
import assert from "node:assert"; import assert from "node:assert";
import test from "node:test"; import test from "node:test";
import { presharedKey, privateKey, publicKey } from "./key"; import { presharedKey, privateKey, publicKey } from "./key.js";
const max = 100, keysArray = Array(max).fill(null); const max = 100, keysArray = Array(max).fill(null);
test("Generate key in javascript", async (t) => { test("Generate key in javascript", async (t) => {

@ -1,6 +1,6 @@
import { isIP } from "net"; import { isIP } from "net";
import { format } from "util"; import { format } from "util";
import { Peer, WgConfigBase } from "./wginterface"; import { Peer, WgConfigBase } from "./wginterface.js";
export interface QuickConfig extends WgConfigBase<Peer>, Partial<Record<`${"Post" | "Pre"}${"Up" | "Down"}`, string[]>> { export interface QuickConfig extends WgConfigBase<Peer>, Partial<Record<`${"Post" | "Pre"}${"Up" | "Down"}`, string[]>> {
DNS?: string[]; DNS?: string[];

@ -1,6 +1,6 @@
import test from "node:test"; import test from "node:test";
import assert from "node:assert"; import assert from "node:assert";
import { QuickConfig, parse, stringify } from "./quick"; import { QuickConfig, parse, stringify } from "./quick.js";
const StaticConfig = `[Interface] const StaticConfig = `[Interface]
ListenPort = 38451 ListenPort = 38451

@ -3,10 +3,27 @@ import { isIPv4, createConnection as netConnection } from "net";
import path from "path"; import path from "path";
import readline from "readline"; import readline from "readline";
import { finished } from "stream/promises"; import { finished } from "stream/promises";
if (process.platform === "win32") global.WIREGUARD_DLL_PATH = path.join(__dirname, "../addons/tools/win/wireguard-nt/bin", process.arch === "x64" ? "amd64" : process.arch, "wireguard.dll"); import rebory from "rebory";
const addon = require("../libs/prebuildifyLoad.cjs")("wginterface"); import { fileURLToPath } from "url";
export const { constants } = addon as { constants: { WG_B64_LENGTH: number, WG_LENGTH: number, MAX_NAME_LENGTH: number, driveVersion: string } }; const __dirname = path.dirname(fileURLToPath(import.meta.url));
const addon = rebory.loadAddon(path.join(__dirname, "../binding.yaml")).wginterface.loadRelease<{
listDevices?: () => Promise<{from: "userspace"|"kernel", name: string, path?: string}[]>;
deleteInterface?: (wgName: string) => Promise<void>;
setConfig?: (wgName: string, config: WgConfigSet) => Promise<void>;
getConfig?: (wgName: string) => Promise<WgConfigGet>;
constants: {
WG_B64_LENGTH: number;
WG_LENGTH: number;
MAX_NAME_LENGTH: number;
driveVersion: string;
};
}>({
WIREGUARD_DLL_PATH: path.resolve(__dirname, "../addons/tools/win/wireguard-nt/bin", ((process.arch === "x64" && "amd64") || (process.arch === "ia32" && "i386"))||process.arch, "wireguard.dll")
});
export const { constants } = addon;
console.log(addon);
/** default location to run socket's */ /** default location to run socket's */
const defaultPath = (process.env.WIRWGUARD_GO_RUN||"").length > 0 ? path.resolve(process.cwd(), process.env.WIRWGUARD_GO_RUN) : process.platform === "win32" ? "\\\\.\\pipe\\WireGuard" : "/var/run/wireguard"; const defaultPath = (process.env.WIRWGUARD_GO_RUN||"").length > 0 ? path.resolve(process.cwd(), process.env.WIRWGUARD_GO_RUN) : process.platform === "win32" ? "\\\\.\\pipe\\WireGuard" : "/var/run/wireguard";

@ -1,8 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
"esModuleInterop": true, "esModuleInterop": true,
"module": "CommonJS", "module": "NodeNext",
"moduleResolution": "Node", "moduleResolution": "NodeNext",
"target": "ESNext", "target": "ESNext",
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"declaration": true, "declaration": true,