刘光辉
12 小时以前 0dfe84494048ce27ba8449831782128412d3eb13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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);
}