Electron forge migration (#2)

Reviewed-on: https://git.internal.vyntehome.com/vynte/vynte-connect/pulls/2
This commit was merged in pull request #2.
This commit is contained in:
2026-05-31 19:28:32 -05:00
parent 980535d682
commit 30bedb9b25
48 changed files with 11388 additions and 4356 deletions
+124
View File
@@ -0,0 +1,124 @@
import { execFile } from 'child_process';
import { MANAGEMENT_URL } from './config';
export interface CommandResult {
ok: boolean;
code?: number;
stdout: string;
stderr: string;
error: Error | null;
}
export class NetBirdClient {
private executablePath: string;
constructor(executablePath: string) {
this.executablePath = executablePath;
}
run(args: string[], options: { timeout?: number } = {}): Promise<CommandResult> {
return new Promise(resolve => {
execFile(this.executablePath, args, { windowsHide: true, timeout: options.timeout ?? 30000, }, (error, stdout, stderr) => {
resolve({
ok: !error,
code: error && typeof (error as NodeJS.ErrnoException).code === 'number' ? (error as NodeJS.ErrnoException).code : 0,
stdout: stdout || '',
stderr: stderr || '',
error
})
});
});
}
runElevated(args: string[]): Promise<Omit<CommandResult, 'code'>> {
const quotedExe = this.executablePath.replace(/'/g, "''");
const quotedArgs = args.map(arg => `'${String(arg).replace(/'/g, "''")}'`).join(',');
const script = `Start-Process -FilePath '${quotedExe}' -ArgumentList @(${quotedArgs}) -Verb RunAs -Wait`;
return new Promise(resolve => {
execFile(
'powershell.exe',
['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', script],
{
windowsHide: true,
timeout: 180000,
},
(error, stdout, stderr) => {
resolve({
ok: !error,
stdout: stdout || '',
stderr: stderr || '',
error
});
}
)
});
}
status(options: { timeout?: number } = {}): Promise<CommandResult> {
return this.run(['status', '--json'], {
timeout: options.timeout ?? 12000
});
}
async ensureService(): Promise<boolean> {
const status = await this.status({ timeout: 10000 });
if (status.ok) return true;
await this.runElevated([
'service',
'install',
'--management-url',
MANAGEMENT_URL,
'--admin-url',
MANAGEMENT_URL,
'--log-level',
'info'
]);
await this.runElevated(['service', 'start']);
for (let index = 0; index < 20; index++) {
const check = await this.status({ timeout: 8000 });
if (check.ok) return true;
await new Promise<void>(resolve => setTimeout(resolve, 500));
}
return false;
}
connect(): Promise<CommandResult> {
return this.run([
'up',
'--management-url',
MANAGEMENT_URL,
'--admin-url',
MANAGEMENT_URL
], { timeout: 180000 });
}
disconnect(): Promise<CommandResult> {
return this.run([
'down',
'--management-url', MANAGEMENT_URL
], { timeout: 45000 });
}
async logout(): Promise<CommandResult> {
await this.run(
['down', '--management-url', MANAGEMENT_URL],
{ timeout: 30000 }
);
return this.run([
'deregister',
'--management-url',
MANAGEMENT_URL,
'--admin-url',
MANAGEMENT_URL
], { timeout: 60000 });
}
}