Files
SpineParticlesWeb/scripts/verify-announcement.mjs
2026-11-04 10:55:40 +08:00

58 lines
2.8 KiB
JavaScript

import { readFile } from 'node:fs/promises'
import assert from 'node:assert/strict'
import { build } from 'esbuild'
const config = JSON.parse(await readFile('public/announcement.json', 'utf8'))
const locales = ['zh-CN', 'zh-TW', 'en', 'ja', 'ko', 'ru', 'fr', 'de', 'pt-BR', 'es']
if (typeof config.enabled !== 'boolean') throw new Error('announcement.enabled must be boolean')
if (!Number.isFinite(config.scrollDurationSeconds) || config.scrollDurationSeconds < 8 || config.scrollDurationSeconds > 120) {
throw new Error('announcement.scrollDurationSeconds must be between 8 and 120')
}
if (!config.messages || typeof config.messages !== 'object' || Array.isArray(config.messages)) {
throw new Error('announcement.messages must be an object')
}
for (const locale of locales) {
const text = config.messages[locale]
if (typeof text !== 'string' || !text.trim()) throw new Error(`announcement.messages.${locale} is empty`)
if (/[\r\n]/.test(text)) throw new Error(`announcement.messages.${locale} must be a single line`)
}
const bundled = await build({
bundle: true,
entryPoints: ['src/editor/announcement.ts'],
format: 'esm',
platform: 'node',
write: false,
})
const announcement = await import(
`data:text/javascript;base64,${Buffer.from(bundled.outputFiles[0].contents).toString('base64')}`
)
assert.equal(announcement.ANNOUNCEMENT_REFRESH_MS, 30_000, '公告内容应每 30 秒刷新')
const normalized = announcement.normalizeAnnouncementConfig(config)
assert.ok(normalized, '公告配置应通过规范化')
const now = 1_000_000
const first = announcement.prepareAnnouncement(normalized, null, now)
assert.equal(first.shouldShow, true, '没有缓存时应在首次打开显示')
assert.equal(first.cache.lastShownAt, now)
const unchanged = announcement.prepareAnnouncement(normalized, first.cache, now + 60_000)
assert.equal(unchanged.shouldShow, false, '72 小时内内容未变化时不应重复显示')
const changedConfig = {
...normalized,
messages: { ...normalized.messages, en: `${normalized.messages.en} Updated` },
}
const changed = announcement.prepareAnnouncement(changedConfig, unchanged.cache, now + 120_000)
assert.equal(changed.shouldShow, true, '公告内容变化时应立即显示')
assert.equal(changed.cache.lastShownAt, now + 120_000)
const expired = announcement.prepareAnnouncement(normalized, changed.cache, now + announcement.ANNOUNCEMENT_WINDOW_MS + 120_000)
assert.equal(expired.shouldShow, true, '超过 72 小时后首次打开应再次显示')
const disabled = announcement.prepareAnnouncement({ ...normalized, enabled: false }, expired.cache, now + 200_000)
assert.equal(disabled.shouldShow, false, '公告关闭时不应显示')
console.log(`公告栏校验通过:${locales.length} 种语言、三次滚动、72 小时展示窗口、内容变更和 30 秒刷新逻辑`)