china-nbs 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +93 -0
- package/CONTRIBUTING.md +59 -0
- package/LICENSE +31 -0
- package/README.md +298 -2
- package/dist/cli.cjs +4473 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +5 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +4470 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +4231 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +413 -0
- package/dist/index.d.ts +413 -0
- package/dist/index.js +4216 -0
- package/dist/index.js.map +1 -0
- package/docs/contracts.md +361 -0
- package/docs/data-semantics.md +123 -0
- package/docs/evaluation.md +117 -0
- package/docs/rate-limit.md +77 -0
- package/package.json +83 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.0 (2026-11-04)
|
|
4
|
+
|
|
5
|
+
首个公开发布版本,补齐 M2-C 工程项。
|
|
6
|
+
|
|
7
|
+
- 通用分片发现:分类树叶子名称带 `(2021-)`、`(2016-2020)`、`(-2015)` 等年份范围时,自动查找同父节点兄弟叶子并按指标名匹配,合并为 `shards`
|
|
8
|
+
- `compare` 明确为**单指标多地区**;多指标请分多次调用
|
|
9
|
+
- NOT_FOUND 负缓存:5 分钟 TTL,避免重复解析不存在的指标
|
|
10
|
+
- 熔断器:连续 5 次可重试失败后打开,冷却 30 秒;支持 `circuitBreaker: false` 关闭
|
|
11
|
+
- 代理注入:库层支持 `fetchImpl` / `dispatcher`;CLI 新增 `--proxy`(需可选安装 `undici`)
|
|
12
|
+
- 新增 `CIRCUIT_OPEN` 错误码
|
|
13
|
+
- 测试从 53 个增加到 **58 个**
|
|
14
|
+
- 文档更新:分片发现、负缓存、熔断、代理、compare 边界
|
|
15
|
+
- curated **130 个**,评测 **168 条**(159 curated + 9 fallback)
|
|
16
|
+
|
|
17
|
+
## 0.2.2 (2026-11-03)
|
|
18
|
+
|
|
19
|
+
覆盖率继续扩展,并修正城市范围。
|
|
20
|
+
|
|
21
|
+
- 通过官网 `getDasByDaCatalogId` 确认:主要城市年度(code=8)官方只覆盖 **36 个城市**(4 个直辖市 + 32 个地级市)
|
|
22
|
+
- 移除误导性的 334 个地级市列表,改为官方 36 城;其他地级市没有城市年度数据
|
|
23
|
+
- 新增 58 个 curated:
|
|
24
|
+
- 能源消费总量、发电量、原煤产量、原油产量
|
|
25
|
+
- 全国年度商品房销售面积/销售额
|
|
26
|
+
- 分省年度建筑业总产值
|
|
27
|
+
- 分省年度/季度农村居民人均可支配收入
|
|
28
|
+
- 全国月度房地产投资
|
|
29
|
+
- 实物商品网上零售额
|
|
30
|
+
- 分省规模以上工业企业营业利润
|
|
31
|
+
- 分省经营单位所在地出口总额
|
|
32
|
+
- 分省新建商品房销售面积累计增长
|
|
33
|
+
- 人口出生率、死亡率、自然增长率、总抚养比
|
|
34
|
+
- 水泥、粗钢、钢材、汽车、手机、集成电路产量
|
|
35
|
+
- 旅客/货物运输量、旅客/货物周转量、快递量/收入、移动电话用户、宽带接入用户
|
|
36
|
+
- M2、金融机构各项存款、各项贷款
|
|
37
|
+
- 普通高等学校数、本专科在校生、高校专任教师
|
|
38
|
+
- 医疗卫生机构数、卫生技术人员、床位、卫生总费用
|
|
39
|
+
- 供水总量、生活垃圾清运量/无害化处理率、造林总面积
|
|
40
|
+
- 煤炭、油气、黑色金属矿、汽车、计算机通信电子制造业 PPI
|
|
41
|
+
- 月度 M2/M1 期末值、M2 同比
|
|
42
|
+
- 国有单位平均工资、原煤占能源生产总量比重、25–29 岁失业率、制造业产能利用率
|
|
43
|
+
- curated 从 72 个扩到 **130 个**
|
|
44
|
+
- 评测集从 101 条扩到 **168 条**:159 条 curated + 9 条 fallback
|
|
45
|
+
- curated 离线 **159/159 top-1**;在线整体 **168/168(100.0%)**,fallback **9/9**
|
|
46
|
+
- 文档更新城市范围、新增指标与覆盖率评估
|
|
47
|
+
|
|
48
|
+
## 0.2.1 (2026-11-03)
|
|
49
|
+
|
|
50
|
+
M2-B:覆盖率扩展。
|
|
51
|
+
|
|
52
|
+
- curated 从 10 个扩到 **72 个**,覆盖社零、固投、收入、消费、财政、粮食、进出口、工业、失业率、房地产、建筑业、能源、网上零售等
|
|
53
|
+
- 新增 36 个主要城市年度(`code=8`)和城市 GDP curated;城市季度/月度单城市数据明确不支持
|
|
54
|
+
- 通用解析改进:
|
|
55
|
+
- 查询先清洗日期/地区/停用词
|
|
56
|
+
- 完整名称匹配,避免短别名抢走限定词查询
|
|
57
|
+
- 限定词评分(城镇/农村、税收/支出、利润/营业收入、夏收/秋收等)
|
|
58
|
+
- 分类树提示词扩展 + 叶子 n-gram 排序
|
|
59
|
+
- 搜索结果不确定时继续走分类树
|
|
60
|
+
- 新增 `npm run eval`(离线)和 `npm run eval:live`
|
|
61
|
+
- 评测集 **101 条**,离线/在线 top-1 100%、top-3 100%
|
|
62
|
+
- 测试从 46 个增加到 53 个
|
|
63
|
+
- 新增 `docs/evaluation.md`,更新 README/PROJECT/契约/口径/限流文档
|
|
64
|
+
|
|
65
|
+
## 0.2.0 (2026-11-03)
|
|
66
|
+
|
|
67
|
+
M2-A:分省月度/季度接入。
|
|
68
|
+
|
|
69
|
+
- 新增 `scope × period → code` 映射:全国 `1/2/3`,分省 `4/5/6`
|
|
70
|
+
- 分省季度 GDP(累计值)curated:`44ecf9ea21884caea5451c35e9c08fff`
|
|
71
|
+
- 分省月度 CPI(4 个分片)curated,分片 id 与全国不同
|
|
72
|
+
- 解除 `resolver` / `compare` 对分省月度、季度的拦截
|
|
73
|
+
- `catalog` 支持 `code=4/5/7/8/9`(分省月/季、主要城市、港澳台)
|
|
74
|
+
- CLI 新增分省季度/月度示例,`--code` 说明更新为 `1-9`
|
|
75
|
+
- `fetchSeries` 合并分片时按分片 `indicId` 取值,避免多指标时取错列
|
|
76
|
+
- 新增 10 个测试(共 46 个)
|
|
77
|
+
- 文档补充 `code` 矩阵、分省实测样例与请求预算
|
|
78
|
+
|
|
79
|
+
## 0.1.0 (2026-11-03)
|
|
80
|
+
|
|
81
|
+
首个 M1 版本。
|
|
82
|
+
|
|
83
|
+
- 统一 `query()` 入口,支持 `search`、`series`、`compare`、`catalog`
|
|
84
|
+
- 全国年度/季度/月度查询;分省年度查询
|
|
85
|
+
- 关键词搜索 + 频率/地区/口径排序
|
|
86
|
+
- `AMBIGUOUS` 候选 + `indicatorId` 消歧
|
|
87
|
+
- 月度 CPI 分片自动合并(2026- / 2021–2025 / 2016–2020 / –2015)
|
|
88
|
+
- 34 个地区映射(含台湾、香港、澳门)
|
|
89
|
+
- CLI:`search`、`series`、`compare`、`catalog`
|
|
90
|
+
- 文本/表格/JSON 渲染
|
|
91
|
+
- TTL+LRU 缓存、串行限流、超时、一次重试
|
|
92
|
+
- 真实接口契约文档与固定 fixtures
|
|
93
|
+
- 36 个单元/集成测试
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
欢迎补充指标别名、fixtures 和文档。这个项目最容易出错的地方不是代码,而是**口径**和**上游契约**。
|
|
4
|
+
|
|
5
|
+
## 开发
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
npm run typecheck
|
|
10
|
+
npm test
|
|
11
|
+
npm run lint
|
|
12
|
+
npm run build
|
|
13
|
+
npm run eval # 离线评测 curated
|
|
14
|
+
npm run smoke # 手动跑真实接口
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 添加一个常用指标
|
|
18
|
+
|
|
19
|
+
1. 用真实接口确认 `cid` 和 `indicatorId`(见 `docs/contracts.md`)。
|
|
20
|
+
2. 在 `src/curated.ts` 增加一个 `CuratedEntry`:
|
|
21
|
+
- `aliases` 只放**完整等价**的说法;不要把 `GDP指数` 这样的限定词放进去。
|
|
22
|
+
- `frequency`、`regionScope`、`measure` 要和指标实际口径一致。
|
|
23
|
+
- 分片指标在 `shards` 中写清每个分片的 `cid`、`indicId`、起止年份。
|
|
24
|
+
3. 在 `test/fixtures/` 放固定响应;测试不要依赖线上接口。
|
|
25
|
+
4. 在 `test/resolver.test.ts` 或 `test/series.test.ts` 增加断言。
|
|
26
|
+
5. 在 `scripts/eval-cases.ts` 增加至少一条查询用例(`expectedKey`)。
|
|
27
|
+
6. 更新 `docs/data-semantics.md`(如果涉及口径)和 `CHANGELOG.md`。
|
|
28
|
+
|
|
29
|
+
## 添加一个别名
|
|
30
|
+
|
|
31
|
+
- 别名表在 `src/aliases.ts`。
|
|
32
|
+
- 只加真正等价的缩写,例如 `社零` → `社会消费品零售总额`。
|
|
33
|
+
- 有口径差异的词(同比/累计/当季/不变价/人均/贡献率)不要互相映射。
|
|
34
|
+
|
|
35
|
+
## 修改解析/排序
|
|
36
|
+
|
|
37
|
+
- 先加 fixture,再改 `scoreRecord`。
|
|
38
|
+
- 任何新的“默认偏好”都要有测试,尤其是:
|
|
39
|
+
- GDP 总量 vs 贡献率/指数/人均/不变价
|
|
40
|
+
- CPI 年度 vs 月度
|
|
41
|
+
- 人口总数 vs 男性/女性/城镇/乡村
|
|
42
|
+
- 不确定时返回 `AMBIGUOUS`,不要猜。
|
|
43
|
+
|
|
44
|
+
## 上游礼貌
|
|
45
|
+
|
|
46
|
+
- 不要提高默认并发;不要移除 2 秒间隔。
|
|
47
|
+
- 不要加“绕过 WAF/换 IP/伪造 Cookie”的逻辑。
|
|
48
|
+
- 403 不重试;429/5xx 最多重试一次。
|
|
49
|
+
- 新增请求前先考虑缓存和请求预算。
|
|
50
|
+
|
|
51
|
+
## PR 检查
|
|
52
|
+
|
|
53
|
+
- [ ] `npm run typecheck`
|
|
54
|
+
- [ ] `npm test`
|
|
55
|
+
- [ ] `npm run lint`
|
|
56
|
+
- [ ] `npm run build`
|
|
57
|
+
- [ ] `npm run eval`
|
|
58
|
+
- [ ] 如涉及真实接口,手动跑过 `npm run smoke`
|
|
59
|
+
- [ ] 文档/CHANGELOG 已更新
|
package/LICENSE
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 china-nbs contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Data notice:
|
|
26
|
+
|
|
27
|
+
The data accessed by this software is published by China's National Bureau of
|
|
28
|
+
Statistics (国家统计局). The MIT License above covers the software code only,
|
|
29
|
+
not the data. Data remains subject to the National Bureau of Statistics' terms
|
|
30
|
+
of use. This project is not affiliated with or endorsed by the National Bureau
|
|
31
|
+
of Statistics.
|
package/README.md
CHANGED
|
@@ -1,3 +1,299 @@
|
|
|
1
|
-
#
|
|
1
|
+
# china-nbs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/china-nbs)
|
|
4
|
+
[](https://github.com/salt-fishes/china-nbs/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
用**一个 `query()` 入口**查询中国国家统计局数据发布库的 Node.js 库 + CLI。
|
|
7
|
+
|
|
8
|
+
> **非国家统计局官方项目。** 数据来源:国家统计局([data.stats.gov.cn](https://data.stats.gov.cn/))。
|
|
9
|
+
> 代码使用 MIT License,但 MIT 不覆盖国家统计局数据;请依法、准确使用并注明来源。
|
|
10
|
+
> 新版数据发布库仍处于试运行期,接口可能变化。本项目不绕过 WAF,也不批量镜像或转售数据。
|
|
11
|
+
|
|
12
|
+
## 特性
|
|
13
|
+
|
|
14
|
+
- **一个入口**:`query()` 自动完成关键词搜索、分类树导航、指标解析、时间序列查询、分片合并。
|
|
15
|
+
- **四个动作**:`search`(最新数据)、`series`(时间序列)、`compare`(分省对比)、`catalog`(分类树)。
|
|
16
|
+
- **覆盖广**:全国、分省、主要城市;年度、季度、月度;130 个常用指标 curated,其他走分类树兜底。
|
|
17
|
+
- **歧义可控**:候选分数接近时返回 `AMBIGUOUS` + 候选列表,可用 `indicatorId` 精确回查,不猜错误指标。
|
|
18
|
+
- **口径优先**:默认优先总量/亿元;识别“增速、指数、人均、贡献率、累计、当季、不变价”等口径。
|
|
19
|
+
- **分片合并**:自动识别分类树里的跨年份分片(不只 CPI),按时间范围拆分请求、合并、去重、排序。
|
|
20
|
+
- **可评测**:168 条评测用例(159 curated + 9 fallback),`npm run eval` 离线测 curated,`npm run eval:live` 测真实解析。
|
|
21
|
+
- **零运行时依赖**:Node 22+ 原生 `fetch`;TypeScript 编写,ESM + CJS。
|
|
22
|
+
- **对上游友好**:默认串行限流(2 秒间隔)、TTL+LRU 缓存、in-flight 去重、超时、一次重试、NOT_FOUND 负缓存和熔断器。
|
|
23
|
+
- **可接代理**:库支持 `fetchImpl` / `dispatcher` 注入;CLI 支持 `--proxy`(可选安装 `undici`)。
|
|
24
|
+
|
|
25
|
+
## 环境
|
|
26
|
+
|
|
27
|
+
- Node.js **>= 22**
|
|
28
|
+
- 无需 API Key,无需 Cookie
|
|
29
|
+
- 数据接口:`https://data.stats.gov.cn/dg/website/publicrelease/web/external`
|
|
30
|
+
|
|
31
|
+
## 安装
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install china-nbs
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
CLI 可直接运行:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx china-nbs search GDP
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
本地开发:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install
|
|
47
|
+
npm run build
|
|
48
|
+
node dist/cli.js search GDP
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 快速开始
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { query, render } from 'china-nbs';
|
|
55
|
+
|
|
56
|
+
const result = await query({
|
|
57
|
+
action: 'series',
|
|
58
|
+
query: 'GDP',
|
|
59
|
+
region: '全国',
|
|
60
|
+
period: 'year',
|
|
61
|
+
start: 2015,
|
|
62
|
+
end: 2025,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
console.log(render(result, 'text'));
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
输出:
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
国家统计局 · 国内生产总值 (亿元)
|
|
72
|
+
2015年 全国:702,511.5 亿元
|
|
73
|
+
...
|
|
74
|
+
2025年 全国:1,401,879.2 亿元
|
|
75
|
+
来源:国家统计局(data.stats.gov.cn)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`query()` **永远返回结构化 `QueryResult`**;`format` 不改变返回类型。展示用 `render(result, 'text' | 'table' | 'json')`。
|
|
79
|
+
|
|
80
|
+
## CLI
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# 最新数据
|
|
84
|
+
npx china-nbs search GDP --period year --region 全国
|
|
85
|
+
|
|
86
|
+
# 时间序列
|
|
87
|
+
npx china-nbs series GDP --start 2015 --end 2025
|
|
88
|
+
|
|
89
|
+
# 月度 CPI
|
|
90
|
+
npx china-nbs series CPI --start 2025-01 --end 2025-10
|
|
91
|
+
|
|
92
|
+
# 分省季度 GDP(累计值)
|
|
93
|
+
npx china-nbs series GDP --period quarter --region 广东 --start 2025Q1 --end 2026Q3
|
|
94
|
+
|
|
95
|
+
# 分省月度 CPI
|
|
96
|
+
npx china-nbs series CPI --period month --region 广东 --start 2025-01 --end 2025-10
|
|
97
|
+
|
|
98
|
+
# 主要城市年度数据
|
|
99
|
+
npx china-nbs series 广州GDP --start 2020 --end 2024
|
|
100
|
+
npx china-nbs compare GDP --regions 广州,深圳 --year 2024
|
|
101
|
+
|
|
102
|
+
# 常用宏观指标
|
|
103
|
+
npx china-nbs series 居民人均消费支出 --start 2020 --end 2025
|
|
104
|
+
npx china-nbs series PPI --period month --start 2025-01 --end 2025-10
|
|
105
|
+
npx china-nbs series 31个大城市城镇调查失业率 --period month --start 2025-01 --end 2025-10
|
|
106
|
+
|
|
107
|
+
# 分省对比
|
|
108
|
+
npx china-nbs compare GDP --regions 广东,江苏,浙江 --year 2025
|
|
109
|
+
npx china-nbs compare GDP --regions 广东,江苏,浙江 --period quarter --start 2025Q1 --end 2025Q4
|
|
110
|
+
|
|
111
|
+
# 分类树
|
|
112
|
+
npx china-nbs catalog --code 3 --depth 2
|
|
113
|
+
npx china-nbs catalog --code 4 --depth 2
|
|
114
|
+
|
|
115
|
+
# JSON 输出
|
|
116
|
+
npx china-nbs search CPI --json
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
退出码:
|
|
120
|
+
|
|
121
|
+
| 码 | 含义 |
|
|
122
|
+
| --- | ----------------------- |
|
|
123
|
+
| 0 | 成功 |
|
|
124
|
+
| 1 | 参数错误 / 不支持的动作 |
|
|
125
|
+
| 2 | 未找到指标 |
|
|
126
|
+
| 3 | 上游错误 / 超时 |
|
|
127
|
+
| 4 | 歧义,需要选择候选 |
|
|
128
|
+
|
|
129
|
+
### 消歧
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npx china-nbs search 人口 --period year --json
|
|
133
|
+
# 看 candidates[].id,或直接用序号:
|
|
134
|
+
npx china-nbs search 人口 --period year --select 1
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## API
|
|
138
|
+
|
|
139
|
+
### `query(options): Promise<QueryResult>`
|
|
140
|
+
|
|
141
|
+
| 参数 | 类型 | 说明 |
|
|
142
|
+
| ------------------------ | ------------------------------------------------ | ----------------------------------------------- |
|
|
143
|
+
| `action` | `'search' \| 'series' \| 'compare' \| 'catalog'` | 默认 `search` |
|
|
144
|
+
| `query` | `string` | 指标关键词,如 `GDP`、`CPI`、`广东 GDP` |
|
|
145
|
+
| `region` | `string` | 单个地区,默认 `全国`;支持分省和 36 个主要城市 |
|
|
146
|
+
| `regions` | `string[]` | `compare` 用 |
|
|
147
|
+
| `period` | `'year' \| 'quarter' \| 'month'` | 不填则按 start/end/关键词推断 |
|
|
148
|
+
| `start` / `end` | `string \| number` | 闭区间;`2015`、`2025Q1`、`2025-01` |
|
|
149
|
+
| `limit` | `number` | `search` 最新数据点数量,默认 5 |
|
|
150
|
+
| `maxPoints` | `number` | `series` 最大数据点,默认 240 |
|
|
151
|
+
| `indicatorId` | `string` | 候选的 `id`,用于消歧 |
|
|
152
|
+
| `code` / `pid` / `depth` | `string` / `string` / `number` | `catalog` 用;`code` 1-9,默认 3 |
|
|
153
|
+
| `timeoutMs` | `number` | 单请求超时,默认 20000 |
|
|
154
|
+
| `totalTimeoutMs` | `number` | 整次查询超时,默认 45000 |
|
|
155
|
+
| `signal` | `AbortSignal` | 调用方取消 |
|
|
156
|
+
| `noCache` | `boolean` | 跳过本次缓存 |
|
|
157
|
+
| `fetchImpl` | `typeof fetch` | 自定义 fetch,用于代理/网关/测试 |
|
|
158
|
+
| `dispatcher` | `unknown` | undici dispatcher,如 `new ProxyAgent(url)` |
|
|
159
|
+
| `debug` / `logger` | `boolean` / function | 调试日志 |
|
|
160
|
+
|
|
161
|
+
`compare` 只比较**一个指标**在多个地区的序列;需要比较多个指标时请分多次调用,不要在一次 `compare` 里混指标。
|
|
162
|
+
|
|
163
|
+
### `QueryResult`
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
interface QueryResult {
|
|
167
|
+
ok: boolean;
|
|
168
|
+
action: Action;
|
|
169
|
+
indicator?: IndicatorMeta;
|
|
170
|
+
points?: DataPoint[];
|
|
171
|
+
series?: CompareSeries[];
|
|
172
|
+
candidates?: IndicatorCandidate[];
|
|
173
|
+
nodes?: CatalogNode[];
|
|
174
|
+
source: { name: '国家统计局'; url: string; retrievedAt: string };
|
|
175
|
+
notes?: string[];
|
|
176
|
+
partial?: boolean;
|
|
177
|
+
error?: { code: ErrorCode; message: string; retryable: boolean; hint?: string };
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
示例:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
const latest = await query({ action: 'search', query: 'GDP', period: 'year' });
|
|
185
|
+
|
|
186
|
+
const ambiguous = await query({ action: 'search', query: '人口', period: 'year' });
|
|
187
|
+
if (ambiguous.error?.code === 'AMBIGUOUS') {
|
|
188
|
+
const choice = ambiguous.candidates?.[0];
|
|
189
|
+
if (choice) {
|
|
190
|
+
const precise = await query({
|
|
191
|
+
action: 'series',
|
|
192
|
+
query: '人口',
|
|
193
|
+
period: 'year',
|
|
194
|
+
indicatorId: choice.id,
|
|
195
|
+
start: 2020,
|
|
196
|
+
end: 2025,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 支持范围(v0.2)
|
|
203
|
+
|
|
204
|
+
| 数据 | 状态 |
|
|
205
|
+
| --------------------------- | --------------------------------------------------- |
|
|
206
|
+
| 全国年度 | ✅ |
|
|
207
|
+
| 全国季度 | ✅(GDP 等常用指标;季度 GDP 默认累计值) |
|
|
208
|
+
| 全国月度 | ✅(CPI/PPI/社零/固投/失业率/财政/M2/M1 等) |
|
|
209
|
+
| 分省年度(code=6) | ✅(GDP、社零、固投、收入、财政、粮食等) |
|
|
210
|
+
| 分省季度(code=5) | ✅(GDP、收入、消费、社零增速、建筑业、农林牧渔等) |
|
|
211
|
+
| 分省月度(code=4) | ✅(CPI、PPI、工业、固投、房地产等) |
|
|
212
|
+
| 主要城市年度(code=8) | ✅(内置 36 个主要城市;GDP curated,其他走分类树) |
|
|
213
|
+
| 主要城市月度价格(code=7) | ⏳ 36/70 城市汇总价格指数,不是单城市数据 |
|
|
214
|
+
| 港澳台 / 部门 / 国际 / 普查 | ⏳ 后续 |
|
|
215
|
+
| MCP server | ⏳ 计划 v0.4 |
|
|
216
|
+
|
|
217
|
+
常用指标 curated 共 **130 个**,覆盖 GDP、CPI、PPI、人口与人口结构、社零、固投、收入、消费、财政、粮食、进出口、工业与工业产品产量、失业率、房地产、建筑业、能源、交通邮电、金融(含月度 M2/M1)、教育、卫生、环境、分行业 PPI、网上零售等。
|
|
218
|
+
|
|
219
|
+
## 评测
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
npm run eval # 离线:只测 curated 快速路径,不请求上游
|
|
223
|
+
npm run eval:live # 在线:curated + search/tree 的真实解析
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
当前评测集 **168 条**:159 条 curated 用例 + 9 条 fallback 用例,覆盖全国/分省/主要城市、年/季/月、总量/累计/增速等口径。离线 curated 为 **159/159 top-1**;在线整体 **168/168 top-1(100.0%)**,其中 fallback 为 **9/9**。评测集在 `scripts/eval-cases.ts`,新增指标时请同时补用例。
|
|
227
|
+
|
|
228
|
+
## 数据口径
|
|
229
|
+
|
|
230
|
+
一定要区分:
|
|
231
|
+
|
|
232
|
+
- **同比**:月度 CPI 常见 `上年同月=100`;年度 `上年=100`。
|
|
233
|
+
- **累计 / 当季**:全国季度 GDP 同时存在累计值和当季值;默认 `GDP` 取累计值,`GDP当季` 取当季值。分省季度目前只有累计值和指数,没有当季值。
|
|
234
|
+
- **分省 code**:分省年度/季度/月度分别用 `code=6/5/4`;不要把所有分省查询都当成年度。
|
|
235
|
+
- **社零**:月度默认取**当期值**;`社零累计` 取累计值,`社零同比/社零增速` 取同比增长。分省季度只有累计增速。
|
|
236
|
+
- **固投**:全国年度取亿元总量;全国月度、分省年度/月度只有增速,没有亿元总量。
|
|
237
|
+
- **PPI**:月度/年度都是 `上年(同月)=100` 的指数,不是百分比涨跌幅。
|
|
238
|
+
- **失业率**:默认月度**城镇调查失业率**;年度**城镇登记失业率**数据截至 2021,且口径不同。
|
|
239
|
+
- **城市**:主要城市年度 `code=8`,内置 36 个城市;`code=7` 是 36/70 城市汇总价格指数,不是单城市数据。
|
|
240
|
+
- **现价 / 不变价**:默认取现价总量;问“实际增速/不变价”时会降权现价指标。
|
|
241
|
+
- **贡献率 / 拉动 / 构成**:只有明确问到时才优先。
|
|
242
|
+
- **人均**:只有明确问“人均”时才优先。
|
|
243
|
+
- **修订**:GDP 等数据会初步核算、最终核实和修订;结果带 `retrievedAt`,请注明查询时间。
|
|
244
|
+
|
|
245
|
+
详见 [docs/data-semantics.md](docs/data-semantics.md)。
|
|
246
|
+
|
|
247
|
+
## 限流与缓存
|
|
248
|
+
|
|
249
|
+
| 内容 | TTL |
|
|
250
|
+
| -------- | ------- |
|
|
251
|
+
| 搜索 | 10 分钟 |
|
|
252
|
+
| 时间序列 | 30 分钟 |
|
|
253
|
+
| 分类树 | 24 小时 |
|
|
254
|
+
| 指标列表 | 24 小时 |
|
|
255
|
+
| 省份列表 | 7 天 |
|
|
256
|
+
|
|
257
|
+
默认串行请求,请求间隔 ≥ 2 秒(加 0–250ms jitter),5xx/429 重试 1 次。连续 5 次可重试失败后熔断 30 秒(可配置),`NOT_FOUND` 结果会做 5 分钟负缓存。详见 [docs/rate-limit.md](docs/rate-limit.md)。
|
|
258
|
+
|
|
259
|
+
## 代理
|
|
260
|
+
|
|
261
|
+
库层可以直接注入 `dispatcher`(需要安装 `undici`):
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
import { query } from 'china-nbs';
|
|
265
|
+
import { ProxyAgent } from 'undici';
|
|
266
|
+
|
|
267
|
+
const result = await query({
|
|
268
|
+
query: 'GDP',
|
|
269
|
+
dispatcher: new ProxyAgent('http://127.0.0.1:7890'),
|
|
270
|
+
});
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
CLI:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
npm install -g undici
|
|
277
|
+
china-nbs search GDP --proxy http://127.0.0.1:7890
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
也可以传自定义 `fetchImpl`,接入公司网关或测试桩。
|
|
281
|
+
|
|
282
|
+
## 开发
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
npm install
|
|
286
|
+
npm run typecheck
|
|
287
|
+
npm test
|
|
288
|
+
npm run lint
|
|
289
|
+
npm run build
|
|
290
|
+
npm run smoke # 手动跑真实接口,不在 CI 中执行
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
真实接口契约和字段说明见 [docs/contracts.md](docs/contracts.md)。
|
|
294
|
+
|
|
295
|
+
## License
|
|
296
|
+
|
|
297
|
+
代码:MIT。
|
|
298
|
+
数据:国家统计局,版权归国家统计局所有;本项目不主张数据版权。
|
|
299
|
+
请勿用本项目批量镜像、转售或商业分发国家统计局数据。
|