| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- #!/usr/bin/env node
- // 为 Bun ZIP 交付生成 CDN 使用的 latest.json。该脚本不发布 npm,也不读取任何凭据。
- import fs from 'node:fs';
- import path from 'node:path';
- import crypto from 'node:crypto';
- import { fileURLToPath } from 'node:url';
- const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
- const DIST = path.resolve(process.env.QIWEI_DIST_DIR || path.join(ROOT, 'dist'));
- const OUT = path.resolve(process.env.QIWEI_UPDATE_MANIFEST_OUT || path.join(DIST, 'latest.json'));
- const BASE_URL = String(process.env.QIWEI_UPDATE_BASE_URL || 'https://repos.fmode.cn/x/openclaw-skills/packages').replace(/\/$/, '');
- function readJson(filePath) { return JSON.parse(fs.readFileSync(filePath, 'utf8').replace(/^\uFEFF/, '')); }
- function sha256(filePath) { return crypto.createHash('sha256').update(fs.readFileSync(filePath)).digest('hex'); }
- function findArchive(platform, version) {
- const candidates = [
- path.join(DIST, `qiwei-training-${platform}-${version}.zip`),
- path.join(DIST, `qiwei-training-${platform}.zip`),
- path.join(DIST, `qiwei-training-${platform}-latest.zip`),
- ];
- return candidates.find(filePath => fs.existsSync(filePath)) || '';
- }
- const platformDirs = {
- 'win-x64': ['qiwei-training-win-x64', 'qiwei-training-win-x64-v'],
- 'mac-arm64': ['qiwei-training-mac-arm64'],
- 'mac-x64': ['qiwei-training-mac-x64'],
- };
- const firstDir = [DIST, ...Object.values(platformDirs).flat().map(name => path.join(DIST, name))]
- .find(dir => fs.existsSync(path.join(dir, 'version.json')));
- if (!firstDir) throw new Error(`dist 中没有带 version.json 的 Bun 交付目录:${DIST}`);
- const baseVersion = readJson(path.join(firstDir, 'version.json'));
- const platforms = {};
- for (const [platform, dirs] of Object.entries(platformDirs)) {
- const directory = [DIST, ...dirs.map(name => path.join(DIST, name))]
- .find(dir => fs.existsSync(path.join(dir, 'version.json')) && readJson(path.join(dir, 'version.json')).platform === platform);
- const version = directory ? readJson(path.join(directory, 'version.json')).version : baseVersion.version;
- const archive = findArchive(platform, version);
- if (!archive) continue;
- const stat = fs.statSync(archive);
- platforms[platform] = {
- url: `${BASE_URL}/${path.basename(archive)}`,
- sha256: sha256(archive),
- size: stat.size,
- };
- }
- const manifest = {
- product: 'fmode-qiwei-training',
- version: baseVersion.version,
- publishedAt: new Date().toISOString(),
- notes: String(process.env.QIWEI_UPDATE_NOTES || '').trim(),
- platforms,
- };
- fs.mkdirSync(path.dirname(OUT), { recursive: true });
- fs.writeFileSync(OUT, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
- process.stdout.write(`${JSON.stringify({ status: 'ok', output: OUT, version: manifest.version, platforms: Object.keys(platforms) }, null, 2)}\n`);
|