Skip to content

Commit bf8dda7

Browse files
committed
chore: 升级工具链并补齐测试、lint 与 CI
构建流程: - 删除 scripts/build.ts 与 cleanup-functions.js。前者在构建期用 writeFileSync 覆写仓库里已提交的 tsconfig.json,导致每次本地构建 都弄脏工作区、不同平台的产物不可复现,而且它把 api/ 排除在类型 检查外。Vercel 与 Netlify 都原生编译 TypeScript,不需要预编译产物 - 新增 tsconfig.check.json 覆盖全部入口。原先的 tsconfig.json 排除了 api/、src/ 和 server.ts,意味着 Vercel 与 Workers 的入口从未被类型 检查过;tsconfig.check.json 一开始也只覆盖了 include 而继承了 exclude,同样在静默跳过 依赖与运行时: - engines 升到 >=22(Node 18 已于 2025-04-30 EOL) - TypeScript 5.9、@types/node 22、Express 5、dotenv 17 - 移除已无引用的 @vercel/node(入口改为 Web 标准签名后不再需要) 测试与质量: - 新增 Vitest,7 个测试文件 222 个用例,全部离线不发真实网络请求 - 新增 ESLint 9 flat config - 新增 GitHub Actions CI,跑 typecheck / lint / test - packageManager 锁定 pnpm 11,CI 从该字段读取版本而非硬编码 实测调优(140 游戏规模的库,真实 Steam 数据): - limit 默认值 100 → 50:并发 8 时 limit=100 冷请求需 14.7 秒, 超过 Vercel Hobby 的 10 秒函数上限,端点实际不可用 - 成就拉取并发上限 8 → 16,可用 STEAM_CONCURRENCY 覆盖。 实测 16 未触发 Steam 速率限制也无超时,limit=100 降至 7.4~9.1 秒 - 每个端点加 Cache-Control: public, s-maxage=..., 由既有 CACHE_TTL_* 推导;错误响应与预检不带缓存头 - clear_cache 新增 ADMIN_TOKEN 鉴权,优先读 Authorization: Bearer 头 (查询参数会进 CDN 缓存键和访问日志);未配置时保持原有行为 - clear_cache 实际执行时响应为 no-store,不会被边缘缓存 部署配置: - netlify.toml 的 functions 路径原指向 dist/netlify/functions, 而 dist 已不再产出,改为 netlify/functions 文档: - 更新 README.md 与 API.md:架构改为「一个核心 + 薄适配层」、 补充 STEAM_CONCURRENCY、limit 默认值、两层缓存说明 - .env.example 补上 STEAM_CONCURRENCY,修正若干与代码不符的描述, 并把 5 个代码根本不读取的变量归入「配了没效果」区
1 parent b5d3deb commit bf8dda7

21 files changed

Lines changed: 3364 additions & 1614 deletions

‎.env.example‎

Lines changed: 72 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
# Steam Profile API - 环境变量配置
2+
#
3+
# 复制本文件为 .env 后按需填写。除 STEAM_API_KEY 和 STEAM_USER_ID 外全部可选,
4+
# 留空即使用代码里的默认值。本地开发由 server.ts 自动加载根目录 .env;
5+
# Vercel / Netlify / Cloudflare 需要在各自控制台配置同名变量。
26

37
# ============================================================================
48
# 必需配置
@@ -7,89 +11,114 @@
711
# [必需] Steam Web API 密钥 - 从 https://steamcommunity.com/dev/apikey 获取
812
STEAM_API_KEY=your_steam_api_key_here
913

10-
# [必需] Steam 用户 ID (64位) - 你自己的 Steam ID
14+
# [必需] Steam 用户 ID - 你自己的 SteamID64,必须是 17 位纯数字
1115
# 查询方式: https://steamid.io/ 或访问你的 Steam 个人资料页面
16+
# 校验位置: lib/handler.ts 的 validateEnvironment(),正则 /^\d{17}$/
17+
# 位数不对会被直接拒绝,接口返回 500 STEAM ID must be a 17-digit number
1218
STEAM_USER_ID=76561198xxxxxxxxx
1319

1420
# ============================================================================
15-
# 缓存配置
21+
# 鉴权配置 (可选)
1622
# ============================================================================
1723

24+
# 管理操作令牌 - 用于 clear_cache=true 这类会改动服务端缓存的请求
25+
# 不设置时保持未鉴权(任何人都能清缓存),生产环境建议务必设置
26+
# 传参方式(lib/app.ts 的 authorizeAdmin):
27+
# Authorization: Bearer <token> 请求头(推荐)
28+
# ?admin_token=<token> 查询参数(回退,仅在没带请求头时才读)
29+
# 优先用请求头的原因: 查询参数会进入 CDN 缓存键和访问日志,请求头不会
30+
ADMIN_TOKEN=
31+
32+
# ============================================================================
33+
# 缓存配置 (可选)
34+
# ============================================================================
35+
36+
# 下列三个值影响服务端内存缓存的过期时间,读取自 lib/handler.ts 的 getCacheTTL()
37+
# 同时也是响应头 Cache-Control 里 s-maxage 的来源
38+
# 留空或填非法值时会回退到注释里标注的默认值
39+
1840
# 用户信息缓存时间 (单位: 分钟)
19-
# 默认: 10分钟
41+
# 默认: 10
2042
CACHE_TTL_USER_MINUTES=10
2143

2244
# 游戏列表缓存时间 (单位: 小时)
23-
# 默认: 24小时
45+
# 默认: 24
2446
CACHE_TTL_GAMES_HOURS=24
2547

2648
# 成就信息缓存时间 (单位: 小时)
27-
# 默认: 1小时
49+
# 默认: 1
2850
CACHE_TTL_ACHIEVEMENTS_HOURS=1
2951

52+
# ============================================================================
53+
# 性能配置 (可选)
54+
# ============================================================================
55+
56+
# 批量拉取成就时同时进行的请求数上限,读取自 lib/pool.ts
57+
# 只影响 steam-games 这类需要逐个游戏拉取成就的端点
58+
# 默认: 16
59+
# 实测 140 游戏规模的库,并发 16 未出现 Steam 429 限流或超时;
60+
# 调高会更快,但超过某个值会开始触发 Steam 速率限制,不建议盲目调高
61+
# 非法值(0 / 负数 / 非数字)会回退到默认值 16
62+
STEAM_CONCURRENCY=16
63+
64+
# ============================================================================
65+
# 语言配置 (可选)
66+
# ============================================================================
67+
68+
# Steam 商店接口返回内容的语言(游戏名、成就名等),读取自 lib/steam-api.ts
69+
# 常用值: english / schinese / tchinese / japanese / koreana / french / german
70+
# 也可以填别名: en / zh / zh-cn / zh-tw / ja / de / fr / es / ru / ko / pt
71+
# 留空时使用代码内置默认值 schinese(简体中文),与 Steam 账号语言无关
72+
# 别名 STEAM_LANG 同样有效,但 STEAM_LANGUAGE 优先
73+
# 填了映射表以外的值会原样传给 Steam,由 Steam 自行决定
74+
STEAM_LANGUAGE=
75+
3076
# ============================================================================
3177
# 游戏配置
3278
# ============================================================================
3379

80+
# 游戏数量由查询参数 ?limit= 控制,不是环境变量:默认 50,最大 100,越界会回退到 50
3481
# 最近游玩游戏列表数量是由 Steam API 决定的(最近两周内玩过的游戏)
3582
# 无法配置,API 会返回 Steam 统计的实际数量
3683

3784
# ============================================================================
3885
# 日志配置
3986
# ============================================================================
4087

41-
# 日志级别 (debug | info | warn | error)
42-
# - debug: 最详细的日志信息
43-
# - info: 常规日志信息(推荐生产环境)
44-
# - warn: 仅显示警告及以上日志
45-
# - error: 仅显示错误日志
88+
# 日志级别 (debug | info | warn | error),读取自 lib/utils.ts 的 Logger
89+
# 注意这不是标准的分级过滤:warn 和 error 无论填什么都照常输出,
90+
# 只有 Logger.log 会被过滤 —— LOG_LEVEL 为 debug 或 info 时输出,填其他值则静默
91+
# - debug: 额外输出 Logger.debug 的调试日志,同时输出常规日志(排查问题时用)
92+
# - info: 输出常规日志(默认,生产环境用这个)
93+
# - warn / error: 两者行为相同,只保留 warn 和 error 级别输出
4694
# 默认: info
4795
LOG_LEVEL=info
4896

4997
# ============================================================================
5098
# 服务配置
5199
# ============================================================================
52100

53-
# 服务端口 (Vercel/Netlify 会自动使用 PORT 环境变量)
101+
# 服务端口(仅本地 Express 服务器 server.ts 使用;Vercel/Netlify 会注入自己的 PORT)
102+
# 端口被占用时 server.ts 会自动改用随机端口
54103
# 默认: 4000
55104
PORT=4000
56105

57106
# 运行环境 (development | production)
58-
# 默认: production
59-
NODE_ENV=production
60-
61-
# ============================================================================
62-
# API 速率限制配置 (可选)
63-
# ============================================================================
64-
65-
# 启用速率限制 (true | false)
66-
# 默认: false
67-
ENABLE_RATE_LIMIT=false
68-
69-
# 速率限制窗口大小 (单位: 秒)
70-
# 默认: 60
71-
RATE_LIMIT_WINDOW=60
72-
73-
# 速率限制请求数 (每个窗口内的最大请求数)
74-
# 默认: 100
75-
RATE_LIMIT_MAX_REQUESTS=100
76-
77-
# ============================================================================
78-
# CORS 配置 (可选)
79-
# ============================================================================
80-
81-
# CORS 允许的源 (逗号分隔)
82-
# 默认: * (允许所有源)
83-
# 例如: https://example.com,https://another.com
84-
CORS_ORIGIN=*
107+
# 项目代码不读取这个变量,保留仅为兼容 Node / 平台的通用约定;
108+
# 部署平台上建议直接用平台的环境设置控制,不要指望它影响本项目行为
109+
# NODE_ENV=production
85110

86111
# ============================================================================
87-
# 缓存存储配置 (可选)
112+
# 以下配置当前实现未读取,仅作为预留项保留,配了不会有任何效果
88113
# ============================================================================
89114

90-
# 缓存过期检查间隔 (单位: 分钟)
91-
# 默认: 5
92-
CACHE_CLEANUP_INTERVAL=5
115+
# CORS 允许的源。响应头在 lib/app.ts 的 CORS_HEADERS 里静态写死为 *
116+
# CORS_ORIGIN=*
93117

94-
# ============================================================================
118+
# 速率限制。代码里没有任何限流逻辑
119+
# ENABLE_RATE_LIMIT=false
120+
# RATE_LIMIT_WINDOW=60
121+
# RATE_LIMIT_MAX_REQUESTS=100
95122

123+
# 缓存过期检查间隔 (单位: 分钟)。没有后台清理定时器,缓存靠读取时惰性过期
124+
# CACHE_CLEANUP_INTERVAL=5

‎.github/workflows/ci.yml‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
# 同一分支的新 push 会取消仍在跑的旧 run,避免浪费额度
10+
concurrency:
11+
group: ci-${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
permissions:
15+
contents: read
16+
17+
jobs:
18+
verify:
19+
name: Typecheck / Lint / Test
20+
runs-on: ubuntu-latest
21+
timeout-minutes: 10
22+
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
27+
# pnpm 必须先于 setup-node 安装:setup-node 的 pnpm 缓存依赖 pnpm store
28+
# 不写 version:action 会自动读取 package.json 的 packageManager 字段,
29+
# 本地与 CI 保持同一版本(pnpm-workspace.yaml 的 allowBuilds 依赖 pnpm 11 语法)
30+
- name: Setup pnpm
31+
uses: pnpm/action-setup@v4
32+
with:
33+
run_install: false
34+
35+
- name: Setup Node.js
36+
uses: actions/setup-node@v4
37+
with:
38+
node-version: 22
39+
cache: pnpm
40+
cache-dependency-path: pnpm-lock.yaml
41+
42+
- name: Install dependencies
43+
run: pnpm install --frozen-lockfile
44+
45+
- name: Typecheck
46+
run: pnpm run typecheck
47+
48+
- name: Lint
49+
run: pnpm run lint
50+
51+
- name: Test
52+
run: pnpm run test

0 commit comments

Comments
 (0)