import { spawn } from 'node:child_process';
|
import { readFileSync } from 'node:fs';
|
import { resolve } from 'node:path';
|
|
import { createServer } from 'vite';
|
|
import { createPluginEnvironment } from '../src/gateway.mjs';
|
import { parseRegistry } from '../src/registry.mjs';
|
|
const gatewayRoot = resolve(import.meta.dirname, '..');
|
const repositoryRoot = resolve(gatewayRoot, '../../..');
|
const registry = parseRegistry(readFileSync(resolve(gatewayRoot, '../registry.yaml'), 'utf8'));
|
const gatewayPort = Number(process.env.ONLYOFFICE_GATEWAY_PORT ?? '4173');
|
const publicHost = process.env.ONLYOFFICE_PLUGIN_PUBLIC_HOST ?? 'localhost';
|
/** @type {import('node:child_process').ChildProcess[]} */
|
const children = [];
|
let stopping = false;
|
|
function stop(exitCode = 0) {
|
if (stopping) return;
|
stopping = true;
|
for (const child of children) child.kill('SIGTERM');
|
process.exitCode = exitCode;
|
}
|
|
/** @param {ReturnType<typeof parseRegistry>['plugins'][number]} plugin */
|
async function waitForPlugin(plugin) {
|
const url = `http://127.0.0.1:${plugin.devPort}/onlyoffice-plugins/${registry.release}/${plugin.code}/config.json`;
|
const deadline = Date.now() + 15_000;
|
while (Date.now() < deadline) {
|
try {
|
if ((await fetch(url)).ok) return;
|
} catch {
|
// Vite is still starting.
|
}
|
await new Promise((resolveWait) => setTimeout(resolveWait, 100));
|
}
|
throw new Error(`${plugin.code} 启动超时`);
|
}
|
|
for (const plugin of registry.plugins) {
|
const child = spawn('pnpm', ['--filter', plugin.packageName, 'dev'], {
|
cwd: repositoryRoot,
|
env: { ...process.env, ...createPluginEnvironment(plugin, { gatewayPort, publicHost }) },
|
stdio: 'inherit',
|
});
|
children.push(child);
|
child.once('exit', (code, signal) => {
|
if (!stopping) {
|
console.error(`${plugin.code} 已退出 (${signal ?? code ?? 'unknown'})`);
|
stop(code || 1);
|
}
|
});
|
}
|
|
process.once('SIGINT', () => stop());
|
process.once('SIGTERM', () => stop());
|
|
try {
|
await Promise.all(registry.plugins.map(waitForPlugin));
|
const gateway = await createServer({ configFile: resolve(gatewayRoot, 'vite.config.mjs'), root: gatewayRoot });
|
await gateway.listen();
|
gateway.printUrls();
|
console.log(`ONLYOFFICE plugins: http://${publicHost}:${gatewayPort}/onlyoffice-plugins/${registry.release}/<plugin-code>/config.json`);
|
} catch (error) {
|
console.error(error instanceof Error ? error.message : String(error));
|
stop(1);
|
}
|