| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- import { readFileSync, writeFileSync } from "node:fs"
- import { createRequire } from "node:module"
- import { dirname, resolve } from "node:path"
- import { pathToFileURL, fileURLToPath } from "node:url"
- import ts from "typescript"
- const require = createRequire(import.meta.url)
- const root = resolve(dirname(fileURLToPath(import.meta.url)), "..")
- function optionalIconvLite() {
- try {
- return require("iconv-lite")
- } catch {
- return null
- }
- }
- function repairLikelyMojibake(text) {
- if (!/[锛銆涓绔榛勯噾瀹]/.test(text)) return text
- const iconv = optionalIconvLite()
- if (!iconv) return text
- try {
- const repaired = iconv.decode(iconv.encode(text, "gbk"), "utf8")
- return repaired.includes("�") ? text : repaired
- } catch {
- return text
- }
- }
- async function loadChangelog(rootDir = root) {
- const source = readFileSync(resolve(rootDir, "src/lib/changelog.ts"), "utf8")
- const compiled = ts.transpileModule(source, {
- compilerOptions: {
- module: ts.ModuleKind.ES2022,
- target: ts.ScriptTarget.ES2022,
- },
- }).outputText
- const moduleUrl = `data:text/javascript;base64,${Buffer.from(compiled).toString("base64")}`
- return import(moduleUrl)
- }
- export function formatReleaseNotes(entry) {
- const zhItems = entry?.highlights?.zh ?? []
- if (!entry || zhItems.length === 0) return ""
- return zhItems
- .map((item, index) => `${index + 1}. ${repairLikelyMojibake(item)}`)
- .join("\n")
- }
- export async function buildReleaseNotes(version, rootDir = root) {
- const changelog = await loadChangelog(rootDir)
- const entry = changelog.currentVersionChangelog(version)[0]
- const notes = formatReleaseNotes(entry)
- return notes || `QMAI ${version} 发布版本`
- }
- export async function buildCurrentReleaseNotes(rootDir = root) {
- const pkg = JSON.parse(readFileSync(resolve(rootDir, "package.json"), "utf8"))
- return buildReleaseNotes(pkg.version, rootDir)
- }
- if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
- const args = process.argv.slice(2)
- const outIndex = args.indexOf("--out")
- const outPath = outIndex >= 0 ? args[outIndex + 1] : ""
- const version = args.find((arg, index) => index !== outIndex && index !== outIndex + 1)
- const notes = version ? await buildReleaseNotes(version) : await buildCurrentReleaseNotes()
- if (outPath) {
- writeFileSync(outPath, notes, "utf8")
- } else {
- process.stdout.write(notes)
- }
- }
|