#!/usr/bin/env node 'use strict'; /** * Build CSP-safe static protobuf for the RdClient viewer (no runtime codegen / eval). */ const fs = require('fs'); const path = require('path'); const { spawnSync } = require('child_process'); const root = path.join(__dirname, '..'); const pbjs = path.join(root, 'node_modules', 'protobufjs-cli', 'bin', 'pbjs'); const outDir = path.join(root, 'public', 'js', 'rdclient', 'generated'); const rawPath = path.join(outDir, 'protos-static.raw.js'); const outPath = path.join(outDir, 'protos-static.js'); const jsonOut = path.join(root, 'public', 'protos', 'bundle.json'); const protos = [ path.join(root, 'protos', 'rendezvous.proto'), path.join(root, 'protos', 'message.proto'), ]; fs.mkdirSync(outDir, { recursive: true }); fs.mkdirSync(path.dirname(jsonOut), { recursive: true }); function runPbjs(args) { const r = spawnSync(process.execPath, [pbjs, ...args], { cwd: root, encoding: 'utf8' }); if (r.status !== 0) { process.stderr.write(r.stderr || r.stdout || 'pbjs failed\n'); process.exit(r.status || 1); } } runPbjs(['-t', 'json', '-o', jsonOut, ...protos]); runPbjs(['-t', 'static', '-o', rawPath, ...protos]); const body = fs.readFileSync(rawPath, 'utf8'); const wrapped = `/* Generated by scripts/build-rdclient-protos.js - do not edit by hand. */ (function (global) { 'use strict'; var $protobuf = global.protobuf; if (!$protobuf) { throw new Error('BetterDeskProtos requires global protobuf (load vendor/protobuf.min.js first)'); } ${body} global.BetterDeskProtos = $root; })(typeof window !== 'undefined' ? window : globalThis); `; fs.writeFileSync(outPath, wrapped, 'utf8'); fs.unlinkSync(rawPath); console.log('Wrote', path.relative(root, outPath), `(${fs.statSync(outPath).size} bytes)`); console.log('Wrote', path.relative(root, jsonOut), `(${fs.statSync(jsonOut).size} bytes)`);