domains007 1.0.1 → 1.0.5
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/README.md +66 -77
- package/domains.json +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# domains007
|
|
2
2
|
|
|
3
3
|
Base64 编码的 API 域名配置包,用于 Android App 域名容灾。
|
|
4
4
|
|
|
@@ -6,22 +6,22 @@ Base64 编码的 API 域名配置包,用于 Android App 域名容灾。
|
|
|
6
6
|
|
|
7
7
|
> **用 npm + CDN 作为免费、高可用的域名配置分发通道,让 Android App 在域名挂了的时候能自我修复。**
|
|
8
8
|
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
```text
|
|
10
|
+
域名挂了时(你的操作):
|
|
11
|
+
python3 publish.py → 自动拉接口 → 生成 domains.json → npm publish
|
|
12
12
|
│
|
|
13
13
|
▼
|
|
14
14
|
jsdelivr / unpkg CDN 自动更新(1-5分钟)
|
|
15
15
|
│
|
|
16
16
|
▼
|
|
17
17
|
Android App:
|
|
18
|
-
|
|
18
|
+
KeepAlive.init(...) + KeepAlive.failoverInterceptor()
|
|
19
19
|
│
|
|
20
|
-
├─ 1.
|
|
21
|
-
├─ 2.
|
|
22
|
-
├─ 3. base64 解码
|
|
23
|
-
├─ 4.
|
|
24
|
-
└─ 5. SharedPreferences
|
|
20
|
+
├─ 1. 用当前域名发起 okhttp 请求
|
|
21
|
+
├─ 2. 域名实效 → 拦截器同步切换
|
|
22
|
+
├─ 3. CDN 拉取 domains.json → base64 解码 → 获得新域名
|
|
23
|
+
├─ 4. 新域名测速通过 → 切换 → 自动重试
|
|
24
|
+
└─ 5. SharedPreferences 缓存最新域名
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
## 为什么这个方案成立
|
|
@@ -39,14 +39,15 @@ App 同时配 3 个 CDN 地址作为 fallback,几乎不可能全挂。
|
|
|
39
39
|
|
|
40
40
|
## 项目结构
|
|
41
41
|
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
├── package.json # name, version
|
|
45
|
-
├── domains.json # ★ 核心:base64
|
|
42
|
+
```text
|
|
43
|
+
domains/
|
|
44
|
+
├── package.json # name=domains007, version
|
|
45
|
+
├── domains.json # ★ 核心:base64 编码的域名配置(发布到 npm)
|
|
46
46
|
├── index.js # CommonJS 入口,自动解码
|
|
47
47
|
├── index.mjs # ESM 入口
|
|
48
48
|
├── index.d.ts # TypeScript 类型定义
|
|
49
|
-
├──
|
|
49
|
+
├── publish.py # 一键发布脚本(本地工具,不入库)
|
|
50
|
+
├── encode.js # 旧的手动编码脚本(已被 publish.py 取代)
|
|
50
51
|
├── .npmignore
|
|
51
52
|
└── README.md
|
|
52
53
|
```
|
|
@@ -56,105 +57,93 @@ keep-alive-domains/
|
|
|
56
57
|
| 设计点 | 实现 |
|
|
57
58
|
| ------ | ------ |
|
|
58
59
|
| **域名不暴露** | `domains.json` 的 `payload` 是 base64 编码的 JSON,CDN 上浏览看不到明文 |
|
|
60
|
+
| **多渠道** | 按 `channels` 区分不同产品,一个 App 一个 channel |
|
|
59
61
|
| **多 CDN 容灾** | jsdelivr + jsdelivr@latest + unpkg,三个地址依次尝试 |
|
|
60
62
|
| **三级降级** | CDN → 本地 SharedPreferences 缓存 → 编译期内置兜底 |
|
|
61
63
|
| **版本比较** | `domains.json` 的 `version` 递增,App 比较后才更新本地缓存 |
|
|
62
|
-
|
|
|
64
|
+
| **自动发布** | `publish.py` 调接口拉域名,自动 +1 版本并发布 |
|
|
63
65
|
|
|
64
66
|
## domains.json 设计
|
|
65
67
|
|
|
66
68
|
```json
|
|
67
69
|
{
|
|
68
|
-
"version":
|
|
69
|
-
"updatedAt": "2026-
|
|
70
|
-
"payload": "
|
|
70
|
+
"version": 4,
|
|
71
|
+
"updatedAt": "2026-08-16T15:20:28.319Z",
|
|
72
|
+
"payload": "eyJjaGFubmVscyI6eyJ4Y2hhdCI6ey..."
|
|
71
73
|
}
|
|
72
74
|
```
|
|
73
75
|
|
|
74
|
-
`payload` 是 base64 编码的 JSON
|
|
76
|
+
`payload` 是 base64 编码的 JSON,解码后是多渠道结构:
|
|
75
77
|
|
|
76
78
|
```json
|
|
77
79
|
{
|
|
78
|
-
"
|
|
79
|
-
|
|
80
|
-
"https://
|
|
81
|
-
"https://
|
|
82
|
-
|
|
80
|
+
"channels": {
|
|
81
|
+
"xchat": { "primary": "https://xchat-0816-hw-app-api.hbshxnn.cn", "fallbacks": [] },
|
|
82
|
+
"bwcj": { "primary": "https://bwcj-0816-hw-app-api.hbshxnn.cn", "fallbacks": [] },
|
|
83
|
+
"dypj": { "primary": "https://dypj-0816-hw-app-api.hbshxnn.cn", "fallbacks": [] },
|
|
84
|
+
"xsm": { "primary": "https://xsm-0816-hw-app-api.hbshxnn.cn", "fallbacks": [] },
|
|
85
|
+
"91mf": { "primary": "https://91mf-0816-hw-app-api.hbshxnn.cn", "fallbacks": [] }
|
|
86
|
+
}
|
|
83
87
|
}
|
|
84
88
|
```
|
|
85
89
|
|
|
86
90
|
## Usage (Node.js)
|
|
87
91
|
|
|
88
92
|
```js
|
|
89
|
-
const domains = require('
|
|
90
|
-
console.log(domains.
|
|
91
|
-
console.log(domains.
|
|
92
|
-
console.log(domains.
|
|
93
|
-
console.log(domains.getVersion()); // 1
|
|
93
|
+
const domains = require('domains007');
|
|
94
|
+
console.log(domains.getChannel('xchat')); // { primary, fallbacks }
|
|
95
|
+
console.log(domains.getChannelNames()); // ["xchat", "bwcj", ...]
|
|
96
|
+
console.log(domains.getVersion()); // 4
|
|
94
97
|
```
|
|
95
98
|
|
|
96
|
-
##
|
|
99
|
+
## 发布流程(一键脚本)
|
|
100
|
+
|
|
101
|
+
域名更新走接口,**无需手动编辑任何文件**。每次执行 `publish.py` 自动完成整个发布:
|
|
97
102
|
|
|
98
103
|
```bash
|
|
99
|
-
|
|
100
|
-
|
|
104
|
+
cd npm_plan/domains
|
|
105
|
+
python3 publish.py # 交互:打印摘要 → 输入 y 发布
|
|
106
|
+
python3 publish.py --yes # 跳过确认直接发布
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
脚本自动完成 6 件事:
|
|
110
|
+
|
|
111
|
+
1. 遍历 5 个产品调接口拉最新域名(**失败的产品用旧配置兜底**,其余继续)
|
|
112
|
+
2. **所有域名都无变动 → 打印提示并退出**,不发布
|
|
113
|
+
3. `domains.json` 的 `version` +1、`package.json` 的 `version` patch +1
|
|
114
|
+
4. 打印「每个产品新域名 + 新旧版本号」变更摘要
|
|
115
|
+
5. `npm publish`
|
|
116
|
+
6. `git commit` 到**本地**(不 push)
|
|
117
|
+
|
|
118
|
+
### 域名接口
|
|
101
119
|
|
|
102
|
-
|
|
103
|
-
|
|
120
|
+
- 地址:`http://16.163.130.1:8080/api/v1/domains?product={product}&key=DOMAINS_API`
|
|
121
|
+
- 支持的产品:`xchat` / `bwcj` / `dypj` / `xsm` / `91mf`
|
|
122
|
+
- 返回 `data[]`,**第一个 domain 作 primary,其余作 fallbacks**
|
|
104
123
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
124
|
+
### 首次使用(发布前登录一次)
|
|
125
|
+
|
|
126
|
+
当前 token 可能已失效,先登录:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
npm login
|
|
108
130
|
```
|
|
109
131
|
|
|
132
|
+
之后每次只需 `python3 publish.py` 回车 `y` 即可。
|
|
133
|
+
|
|
110
134
|
## Android: Fetch from CDN
|
|
111
135
|
|
|
112
|
-
```
|
|
113
|
-
https://cdn.jsdelivr.net/npm/
|
|
114
|
-
https://cdn.jsdelivr.net/npm/
|
|
115
|
-
https://unpkg.com/
|
|
136
|
+
```text
|
|
137
|
+
https://cdn.jsdelivr.net/npm/domains007/domains.json
|
|
138
|
+
https://cdn.jsdelivr.net/npm/domains007@latest/domains.json
|
|
139
|
+
https://unpkg.com/domains007@latest/domains.json
|
|
116
140
|
```
|
|
117
141
|
|
|
118
142
|
## 进阶方向
|
|
119
143
|
|
|
120
144
|
- **签名校验**:对 payload 加 HMAC 签名,App 内置公钥验签,防止 CDN 被劫持篡改
|
|
121
|
-
- **多渠道**:按 `production` / `staging` 区分不同域名
|
|
122
145
|
- **灰度发布**:利用 npm dist-tag(`npm publish --tag beta`)实现按 tag 拉不同版本
|
|
123
146
|
|
|
124
147
|
## License
|
|
125
148
|
|
|
126
149
|
MIT
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
┌─────────────────────────────────────────────────────────┐
|
|
130
|
-
│ 你的本地(仅你可见) │
|
|
131
|
-
│ │
|
|
132
|
-
│ 1. 编辑 encode.js │
|
|
133
|
-
│ const config = { │
|
|
134
|
-
│ primary: 'https://你的新域名.com', │
|
|
135
|
-
│ fallbacks: [...] │
|
|
136
|
-
│ } │
|
|
137
|
-
│ │
|
|
138
|
-
│ 2. node encode.js │
|
|
139
|
-
│ → 输出新的 base64 payload │
|
|
140
|
-
│ │
|
|
141
|
-
│ 3. 粘贴到 domains.json,version +1 │
|
|
142
|
-
│ │
|
|
143
|
-
│ 4. npm version patch && npm publish │
|
|
144
|
-
│ → 发布到 npmjs.com(domains.json 被打包进去) │
|
|
145
|
-
│ │
|
|
146
|
-
│ 5. git add . && git commit && git push │
|
|
147
|
-
│ → 推送到 Gitee(不含 encode.js / domains.json / README) │
|
|
148
|
-
└─────────────────────────────────────────────────────────┘
|
|
149
|
-
│
|
|
150
|
-
▼
|
|
151
|
-
npmjs.com ──▶ CDN 自动同步 ──▶ Android App 拉取新域名
|
|
152
|
-
|
|
153
|
-
步骤 命令 说明
|
|
154
|
-
① 编辑 encode.js 改 config 里的域名
|
|
155
|
-
② node encode.js 生成 base64 payload
|
|
156
|
-
③ 粘贴到 domains.json 替换 payload,version 递增
|
|
157
|
-
④ npm version patch 包版本号自动 +1(如 1.0.1 → 1.0.2)
|
|
158
|
-
⑤ npm publish 发布,domains.json 随包上传
|
|
159
|
-
⑥ git add . && git commit && git push Gitee 只接收骨架代码变化
|
|
160
|
-
关键点:npm publish 看的是本地文件系统,不是 git。所以 domains.json 即使被 .gitignore 排除,它仍然会被 package.json 的 "files": [...] 打包发布到 npm。Gitee 干净,npm 正常用。
|
package/domains.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
3
|
-
"updatedAt": "2026-08-
|
|
4
|
-
"payload": "
|
|
2
|
+
"version": 5,
|
|
3
|
+
"updatedAt": "2026-08-17T05:11:03.166519Z",
|
|
4
|
+
"payload": "eyJjaGFubmVscyI6IHsieGNoYXQiOiB7InByaW1hcnkiOiAiaHR0cHM6Ly94Y2hhdC0wODE3LWh3LWFwcC1hcGkuaGJzaHhxcS5jbiIsICJmYWxsYmFja3MiOiBbXX0sICJid2NqIjogeyJwcmltYXJ5IjogImh0dHBzOi8vYndjai0wODE3LWh3LWFwcC1hcGkuaGJzaHhxcS5jbiIsICJmYWxsYmFja3MiOiBbXX0sICJkeXBqIjogeyJwcmltYXJ5IjogImh0dHBzOi8vZHlwai0wODE3LWh3LWFwcC1hcGkuaGJzaHhxcS5jbiIsICJmYWxsYmFja3MiOiBbXX0sICJ4c20iOiB7InByaW1hcnkiOiAiaHR0cHM6Ly94c20tMDgxNy1ody1hcHAtYXBpLmhic2h4cXEuY24iLCAiZmFsbGJhY2tzIjogW119LCAiOTFtZiI6IHsicHJpbWFyeSI6ICJodHRwczovLzkxbWYtMDgxNi1ody1hcHAtYXBpLmhic2h4bm4uY24iLCAiZmFsbGJhY2tzIjogW119LCAicHJlIjogeyJwcmltYXJ5IjogImh0dHBzOi8vcHJlLTA4MTctaHctYXBwLWFwaS5oYnNoeHFxLmNuIiwgImZhbGxiYWNrcyI6IFtdfX19"
|
|
5
5
|
}
|