@will-17173/telegram-cli 0.3.0 → 0.4.1
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 +73 -335
- package/README.zh-CN.md +72 -333
- package/dist/account/account-authenticator.js +95 -0
- package/dist/account/account-authenticator.js.map +1 -0
- package/dist/account/account-context.js +7 -0
- package/dist/account/account-context.js.map +1 -1
- package/dist/account/account-name.js +17 -0
- package/dist/account/account-name.js.map +1 -0
- package/dist/account/account-presets.js +20 -3
- package/dist/account/account-presets.js.map +1 -1
- package/dist/account/account-store.js +277 -37
- package/dist/account/account-store.js.map +1 -1
- package/dist/cli/app.js +12 -1
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/output.js +21 -6
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/secure-input.js +408 -0
- package/dist/cli/secure-input.js.map +1 -0
- package/dist/commands/account-options.js +37 -7
- package/dist/commands/account-options.js.map +1 -1
- package/dist/commands/account.js +144 -62
- package/dist/commands/account.js.map +1 -1
- package/dist/commands/archive.js +151 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/config.js +119 -12
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/contact.js +58 -0
- package/dist/commands/contact.js.map +1 -0
- package/dist/commands/data.js +14 -7
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/dialog.js +156 -0
- package/dist/commands/dialog.js.map +1 -0
- package/dist/commands/folder.js +113 -0
- package/dist/commands/folder.js.map +1 -0
- package/dist/commands/group-write.js +45 -5
- package/dist/commands/group-write.js.map +1 -1
- package/dist/commands/group.js +23 -1
- package/dist/commands/group.js.map +1 -1
- package/dist/commands/notification.js +76 -0
- package/dist/commands/notification.js.map +1 -0
- package/dist/commands/query.js +22 -15
- package/dist/commands/query.js.map +1 -1
- package/dist/commands/telegram-runner.js +40 -18
- package/dist/commands/telegram-runner.js.map +1 -1
- package/dist/commands/telegram.js +82 -38
- package/dist/commands/telegram.js.map +1 -1
- package/dist/commands/time-range.js +39 -0
- package/dist/commands/time-range.js.map +1 -0
- package/dist/commands/types.js +3 -2
- package/dist/commands/types.js.map +1 -1
- package/dist/config/credential-store.js +24 -4
- package/dist/config/credential-store.js.map +1 -1
- package/dist/config/env.js +4 -1
- package/dist/config/env.js.map +1 -1
- package/dist/group-commands/catalog.js +10 -0
- package/dist/group-commands/catalog.js.map +1 -1
- package/dist/group-commands/executor.js +13 -4
- package/dist/group-commands/executor.js.map +1 -1
- package/dist/presenters/group.js +16 -0
- package/dist/presenters/group.js.map +1 -1
- package/dist/presenters/human.js +113 -0
- package/dist/presenters/human.js.map +1 -1
- package/dist/presenters/ink/group-command-result.js +2 -0
- package/dist/presenters/ink/group-command-result.js.map +1 -1
- package/dist/presenters/ink/listen-scroll.js +4 -3
- package/dist/presenters/ink/listen-scroll.js.map +1 -1
- package/dist/presenters/ink/listen.js +245 -57
- package/dist/presenters/ink/listen.js.map +1 -1
- package/dist/presenters/ink/mouse-scroll.js +12 -0
- package/dist/presenters/ink/mouse-scroll.js.map +1 -1
- package/dist/presenters/ink/secure-input.js +68 -0
- package/dist/presenters/ink/secure-input.js.map +1 -0
- package/dist/presenters/ink/use-group-command.js +78 -17
- package/dist/presenters/ink/use-group-command.js.map +1 -1
- package/dist/presenters/markdown.js +54 -0
- package/dist/presenters/markdown.js.map +1 -0
- package/dist/presenters/structured.js +8 -3
- package/dist/presenters/structured.js.map +1 -1
- package/dist/services/account-session-service.js +241 -0
- package/dist/services/account-session-service.js.map +1 -0
- package/dist/services/archive-layout.js +61 -0
- package/dist/services/archive-layout.js.map +1 -0
- package/dist/services/archive-manifest.js +187 -0
- package/dist/services/archive-manifest.js.map +1 -0
- package/dist/services/archive-markdown.js +383 -0
- package/dist/services/archive-markdown.js.map +1 -0
- package/dist/services/archive-service.js +718 -0
- package/dist/services/archive-service.js.map +1 -0
- package/dist/services/archive-types.js +2 -0
- package/dist/services/archive-types.js.map +1 -0
- package/dist/services/attachment-download.js +7 -2
- package/dist/services/attachment-download.js.map +1 -1
- package/dist/services/auto-download-coordinator.js +2 -4
- package/dist/services/auto-download-coordinator.js.map +1 -1
- package/dist/services/contact-service.js +78 -0
- package/dist/services/contact-service.js.map +1 -0
- package/dist/services/dialog-service.js +140 -0
- package/dist/services/dialog-service.js.map +1 -0
- package/dist/services/folder-service.js +200 -0
- package/dist/services/folder-service.js.map +1 -0
- package/dist/services/group-write-service.js +78 -18
- package/dist/services/group-write-service.js.map +1 -1
- package/dist/services/message-service.js +17 -1
- package/dist/services/message-service.js.map +1 -1
- package/dist/services/notification-service.js +142 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/write-access-policy.js +19 -0
- package/dist/services/write-access-policy.js.map +1 -0
- package/dist/telegram/archive-types.js +2 -0
- package/dist/telegram/archive-types.js.map +1 -0
- package/dist/telegram/client-factory.js +51 -11
- package/dist/telegram/client-factory.js.map +1 -1
- package/dist/telegram/contact-types.js +10 -0
- package/dist/telegram/contact-types.js.map +1 -0
- package/dist/telegram/dialog-types.js +2 -0
- package/dist/telegram/dialog-types.js.map +1 -0
- package/dist/telegram/errors.js +14 -0
- package/dist/telegram/errors.js.map +1 -0
- package/dist/telegram/fake-group-management.js +5 -0
- package/dist/telegram/fake-group-management.js.map +1 -1
- package/dist/telegram/folder-types.js +13 -0
- package/dist/telegram/folder-types.js.map +1 -0
- package/dist/telegram/group-write-types.js +28 -1
- package/dist/telegram/group-write-types.js.map +1 -1
- package/dist/telegram/mtcute-archive.js +190 -0
- package/dist/telegram/mtcute-archive.js.map +1 -0
- package/dist/telegram/mtcute-client.js +72 -11
- package/dist/telegram/mtcute-client.js.map +1 -1
- package/dist/telegram/mtcute-contacts.js +90 -0
- package/dist/telegram/mtcute-contacts.js.map +1 -0
- package/dist/telegram/mtcute-dialogs.js +186 -0
- package/dist/telegram/mtcute-dialogs.js.map +1 -0
- package/dist/telegram/mtcute-folders.js +318 -0
- package/dist/telegram/mtcute-folders.js.map +1 -0
- package/dist/telegram/mtcute-group-members.js +43 -3
- package/dist/telegram/mtcute-group-members.js.map +1 -1
- package/dist/telegram/mtcute-message-normalizer.js +63 -0
- package/dist/telegram/mtcute-message-normalizer.js.map +1 -0
- package/dist/telegram/mtcute-notifications.js +101 -0
- package/dist/telegram/mtcute-notifications.js.map +1 -0
- package/dist/telegram/notification-types.js +11 -0
- package/dist/telegram/notification-types.js.map +1 -0
- package/dist/telegram/types.js +6 -1
- package/dist/telegram/types.js.map +1 -1
- package/package.json +2 -2
package/README.zh-CN.md
CHANGED
|
@@ -1,422 +1,161 @@
|
|
|
1
1
|
# Telegram CLI
|
|
2
2
|
|
|
3
|
-
[English](README.md)
|
|
3
|
+
[项目网站](https://will-17173.github.io/telegram-cli/zh-CN/) · [Telegram CLI 使用文档](https://will-17173.github.io/telegram-cli/zh-CN/docs/) · [English README](README.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Telegram CLI 是一个 TypeScript 命令行界面(CLI),统一处理 Telegram 在线数据、本地 SQLite 搜索和远端管理。你可以在终端、脚本或编程智能体中调用同一个 `tg` 命令。账号会话与同步消息保留在本机。
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 阅读完整文档
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- 管理多个 Telegram 账号,每个账号使用独立的会话和消息数据库,并支持交互式切换。
|
|
11
|
-
- 将聊天记录提取到本地 SQLite 数据库,以便快速离线搜索。
|
|
12
|
-
- 通过增量同步和批量同步命令更新本地数据。
|
|
13
|
-
- 监听实时消息,并可选显示附件摘要。
|
|
14
|
-
- 从限制下载的频道中下载附件。
|
|
15
|
-
- 搜索、筛选、汇总和导出本地消息,并在最近消息中显示回复上下文和媒体组摘要。
|
|
16
|
-
- 通过命令行发送、编辑和删除消息。
|
|
17
|
-
- 查看并管理群组、成员、管理员、邀请链接、论坛话题和消息。
|
|
18
|
-
- 在支持的场景下使用人类可读输出,或结构化的 JSON/YAML 输出。
|
|
9
|
+
阅读 [Telegram CLI 完整使用文档](https://will-17173.github.io/telegram-cli/zh-CN/docs/),了解安装、工作流、全部命令、自动化、安全边界和故障排查。
|
|
19
10
|
|
|
20
|
-
##
|
|
11
|
+
## 选择 Telegram 工作流
|
|
21
12
|
|
|
22
|
-
|
|
13
|
+
请根据数据新鲜度、结果去向以及命令是否修改 Telegram 来选择工作流。
|
|
23
14
|
|
|
24
|
-
|
|
15
|
+
### 读取 Telegram 当前数据
|
|
25
16
|
|
|
26
|
-
|
|
27
|
-
- 非零退出码和结构化错误码让 Agent 能够检测并处理失败。
|
|
28
|
-
- `--account <name>` 可以明确指定账号,且不会改变 current 账号。
|
|
29
|
-
- 本地搜索和分析命令无需重新连接 Telegram,即可查询已同步消息。
|
|
30
|
-
|
|
31
|
-
例如,Agent 可以搜索指定账号,并将结果作为 JSON 解析:
|
|
17
|
+
需要最新的服务端状态时,请使用在线命令。这些命令不会把返回消息写入 SQLite。
|
|
32
18
|
|
|
33
19
|
```sh
|
|
34
|
-
tg
|
|
20
|
+
tg inbox
|
|
21
|
+
tg read @team --since 2h
|
|
22
|
+
tg search-online "incident" --chat @team --json
|
|
35
23
|
```
|
|
36
24
|
|
|
37
|
-
|
|
25
|
+
你还可以在线查看联系人、通知设置、文件夹和群组详情,且不会导入消息。
|
|
38
26
|
|
|
39
|
-
|
|
27
|
+
### 建立可搜索的本地消息库
|
|
28
|
+
|
|
29
|
+
将一个或多个聊天同步到所选账号的 SQLite 数据库。之后无需连接 Telegram,即可搜索和分析本地副本。
|
|
40
30
|
|
|
41
31
|
```sh
|
|
42
|
-
|
|
43
|
-
|
|
32
|
+
tg sync @team
|
|
33
|
+
tg search "release" --chat @team
|
|
34
|
+
tg recent --chat @team --hours 24
|
|
44
35
|
```
|
|
45
36
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
## 安装
|
|
37
|
+
本地命令还可以筛选、汇总和导出已存储消息。
|
|
49
38
|
|
|
50
|
-
|
|
39
|
+
### 监听新消息并下载文件
|
|
51
40
|
|
|
52
|
-
|
|
41
|
+
`listen` 可以实时接收一个或多个聊天的新消息。它还可以下载收到的附件,并在交互模式中执行回复或群组操作。
|
|
53
42
|
|
|
54
43
|
```sh
|
|
55
|
-
|
|
44
|
+
tg listen @team --auto-download
|
|
56
45
|
```
|
|
57
46
|
|
|
58
|
-
|
|
47
|
+
### 保存增量 Markdown 归档
|
|
59
48
|
|
|
60
|
-
|
|
49
|
+
`archive` 将消息增量写入 Markdown,并可同时下载媒体文件。它单独记录归档进度,不会填充 SQLite。
|
|
61
50
|
|
|
62
51
|
```sh
|
|
63
|
-
tg
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
如果 `TG_API_ID` 和 `TG_API_HASH` 均未设置,且已保存的配置文件不存在,CLI 会使用内置的 Telegram API 凭据。创建 Telegram 客户端时,每个进程只会向 stderr 输出一次以下警告:
|
|
67
|
-
|
|
68
|
-
```text
|
|
69
|
-
warning: using default Telegram API credentials, which have stricter flood limits and may trigger FLOOD_WAIT during frequent or large requests. Run tg config set --api-id <id> --api-hash <hash> to configure your own.
|
|
52
|
+
tg archive @team --download-media
|
|
70
53
|
```
|
|
71
54
|
|
|
72
|
-
|
|
55
|
+
后续运行会追加新消息,并重试仍然缺失的引用媒体。
|
|
73
56
|
|
|
74
|
-
|
|
57
|
+
### 发送消息并管理群组
|
|
75
58
|
|
|
76
|
-
|
|
59
|
+
你可以从终端发送文本、文件或带说明文字的媒体组,也可以查看和管理群成员、管理员、邀请链接、论坛话题和消息。
|
|
77
60
|
|
|
78
61
|
```sh
|
|
79
|
-
tg
|
|
62
|
+
tg send @team "Release is ready" --file ./report.pdf
|
|
63
|
+
tg group members @team --type admins
|
|
64
|
+
tg group member mute @team @alice 2h --yes
|
|
80
65
|
```
|
|
81
66
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
```sh
|
|
85
|
-
TG_PROXY=http://127.0.0.1:8080 tg status
|
|
86
|
-
```
|
|
67
|
+
Telegram CLI 还可以管理联系人、通知设置和聊天文件夹。写操作总开关会控制修改 Telegram 的命令。
|
|
87
68
|
|
|
88
|
-
|
|
69
|
+
### 跨隔离账号运行自动化
|
|
89
70
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
如需以人类可读、JSON 或 YAML 格式查看生效配置,请运行:
|
|
71
|
+
每个已添加账号都有独立的会话和 SQLite 数据库。你可以为单次命令选择账号,且不会改变默认账号。
|
|
93
72
|
|
|
94
73
|
```sh
|
|
95
|
-
tg
|
|
96
|
-
tg config list --json
|
|
97
|
-
tg config list --yaml
|
|
98
|
-
tg config list --show-secrets
|
|
74
|
+
tg stats --account work --json
|
|
99
75
|
```
|
|
100
76
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
输出恰好报告五个字段:生效的 API ID、API hash、凭据来源、代理 URL 以及代理来源。API hash 默认脱敏;使用 `--show-secrets` 可显示完整值。代理 URL 始终完整输出,并可能包含凭据或 MTProxy secret,因此请勿将 `config list` 输出写入日志或与他人分享。`tg config list` 不会创建 Telegram 客户端,也不会发起网络连接。
|
|
77
|
+
有限结果命令支持 JSON、YAML 和 Markdown 输出。失败时会返回非零退出状态和稳定错误码。
|
|
104
78
|
|
|
105
|
-
|
|
79
|
+
## 安装
|
|
106
80
|
|
|
107
|
-
|
|
81
|
+
安装 Node.js 22 或更高版本,再从 npm 安装 Telegram CLI:
|
|
108
82
|
|
|
109
83
|
```sh
|
|
110
|
-
|
|
84
|
+
npm install -g @will-17173/telegram-cli
|
|
111
85
|
```
|
|
112
86
|
|
|
113
|
-
##
|
|
87
|
+
## 开始使用
|
|
88
|
+
|
|
89
|
+
认证一个账号,列出聊天,同步一个聊天,再搜索本地消息:
|
|
114
90
|
|
|
115
91
|
```sh
|
|
116
|
-
# 添加并登录第一个账号
|
|
117
92
|
tg account add
|
|
118
|
-
|
|
119
|
-
# 检查身份验证状态
|
|
120
93
|
tg status
|
|
121
|
-
|
|
122
|
-
# 列出聊天,然后在出现 `<chat>` 的位置使用聊天名称、用户名或 ID
|
|
123
94
|
tg chats
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
tg sync <chat>
|
|
127
|
-
|
|
128
|
-
# 搜索已同步到本地的消息
|
|
129
|
-
tg search "keyword" --chat <chat>
|
|
130
|
-
|
|
131
|
-
# 同步全部聊天
|
|
132
|
-
tg sync-all --max-chats 20 --delay 1
|
|
133
|
-
|
|
134
|
-
# 监听实时消息并自动下载收到的附件
|
|
135
|
-
tg listen <chat-or-id> --auto-download
|
|
136
|
-
|
|
137
|
-
# 使用纯文本输出、下载附件并隐藏消息中的附件摘要
|
|
138
|
-
tg listen <chat-or-id> --no-interactive --auto-download --no-media
|
|
139
|
-
|
|
140
|
-
# 发送消息
|
|
141
|
-
tg send <chat> "Hello from tg"
|
|
95
|
+
tg sync @team
|
|
96
|
+
tg search "release" --chat @team
|
|
142
97
|
```
|
|
143
98
|
|
|
144
|
-
|
|
99
|
+
请将 `@team` 替换为聊天名称、用户名或数字标识符(ID)。运行 `tg --help` 或 `tg sync --help` 等具体命令查看可用选项。
|
|
145
100
|
|
|
146
|
-
|
|
101
|
+
## 了解数据去向
|
|
147
102
|
|
|
148
|
-
|
|
149
|
-
# 仅发送文本
|
|
150
|
-
tg send <chat> "Text only"
|
|
151
|
-
|
|
152
|
-
# 仅发送文件;重复使用 --file,并按指定顺序发送
|
|
153
|
-
tg send <chat> --file ./photo.jpg --file ./clip.mp4
|
|
154
|
-
|
|
155
|
-
# 发送说明文字和文件
|
|
156
|
-
tg send <chat> "Group caption" --file ./photo.jpg --file ./clip.mp4
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
`--file` 可重复使用。多个文件会按指定顺序作为一个 Telegram 媒体组发送。只有提供至少一个文件时,消息文本才可省略。提供文件后,消息文本会成为媒体组的说明文字;CLI 不会另发一条纯文本消息。
|
|
160
|
-
|
|
161
|
-
Telegram 决定可接受的文件组合和媒体组数量限制。如果 Telegram 拒绝所请求的组合或数量,命令会返回错误,不会静默拆分为多条消息或多个媒体组。
|
|
162
|
-
|
|
163
|
-
## 多账号
|
|
164
|
-
|
|
165
|
-
每个 Telegram 账号都有独立持久化的身份验证会话和本地消息数据库。通过以下命令交互式登录并添加账号:
|
|
166
|
-
|
|
167
|
-
```sh
|
|
168
|
-
tg account add
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
添加的第一个账号会自动成为 current 账号。继续添加其他账号时不会自动切换 current 账号,可通过以下命令查看或更改选择:
|
|
103
|
+
运行命令前,先检查它的执行范围:
|
|
172
104
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
105
|
+
| 范围 | 命令 | 结果 |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| 在线读取 | `inbox`、`read`、`search-online` | 查询 Telegram,不保存返回的消息。 |
|
|
108
|
+
| 写入本地 | `history`、`sync`、`sync-all`、`refresh` | 将消息保存到所选账号的 SQLite 数据库。 |
|
|
109
|
+
| 仅本地 | `search`、`recent`、`stats`、`export` | 读取本地 SQLite,不连接 Telegram。 |
|
|
110
|
+
| 文件归档 | `archive` | 读取 Telegram 并写入 Markdown 或媒体文件,不写入 SQLite。 |
|
|
111
|
+
| 远端写入 | `send`、`edit`、`delete`,以及通知、文件夹和群组操作 | 修改 Telegram 消息或设置。 |
|
|
179
112
|
|
|
180
|
-
|
|
181
|
-
tg account switch
|
|
113
|
+
每个账号都有独立的会话和 SQLite 数据库。添加 `--account work` 可以为单次命令选择账号,且不会改变默认账号。
|
|
182
114
|
|
|
183
|
-
|
|
184
|
-
tg account switch <name>
|
|
185
|
-
|
|
186
|
-
# 删除账号及其本地会话和数据
|
|
187
|
-
tg account remove <name> --force
|
|
188
|
-
```
|
|
115
|
+
## 保护远端数据
|
|
189
116
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
各命令默认使用 current 账号。支持 `--account` 的命令可以临时指定另一个已添加的账号,且不会改变 current 账号:
|
|
117
|
+
在只读工作流或自动化任务前关闭远端写入:
|
|
193
118
|
|
|
194
119
|
```sh
|
|
195
|
-
tg
|
|
196
|
-
tg
|
|
197
|
-
tg search "keyword" --account <name>
|
|
120
|
+
tg config write-access off
|
|
121
|
+
tg config write-access status
|
|
198
122
|
```
|
|
199
123
|
|
|
200
|
-
|
|
124
|
+
准备再次修改 Telegram 时,运行 `tg config write-access on`。打开总开关不代表已授权某一项具体写操作。
|
|
201
125
|
|
|
202
|
-
Telegram API
|
|
126
|
+
请妥善保管 Telegram 应用程序接口(API)凭据、代理凭据、会话文件、SQLite 数据库、导出文件和归档。
|
|
203
127
|
|
|
204
|
-
##
|
|
128
|
+
## 配合编程智能体
|
|
205
129
|
|
|
206
|
-
|
|
130
|
+
脚本或编程智能体需要结构化输出时,请使用 JSON 或 YAML:
|
|
207
131
|
|
|
208
132
|
```sh
|
|
209
|
-
|
|
210
|
-
tg group info <chat> --account alice --json
|
|
211
|
-
|
|
212
|
-
# 成员列表:按类型、姓名/用户名查询和结果数量筛选
|
|
213
|
-
tg group members <chat> --type admins --query alice --limit 50 --yaml
|
|
214
|
-
|
|
215
|
-
# 单个成员的角色、管理员权限和限制
|
|
216
|
-
tg group member <chat> <user>
|
|
217
|
-
|
|
218
|
-
# 管理员审计日志;--user 和 --type 均可重复指定
|
|
219
|
-
tg group audit <chat> --query invite --user <user> --type member_invited --type invite_changed --limit 100 --account alice --json
|
|
220
|
-
|
|
221
|
-
# 管理示例(chat 参数位于操作参数之前)
|
|
222
|
-
tg group member ban @team @alice --yes
|
|
223
|
-
tg group chat slowmode @team 30s
|
|
224
|
-
tg group topic --help
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
`group members` 的 `--type` 恰好支持以下七种筛选器:`recent`、`all`、`admins`、`banned`、`restricted`、`bots` 和 `contacts`。默认使用 `recent` 并返回 100 条结果;`--limit` 可设为 1 到 200。Telegram 可能返回少于其报告总数的成员,因此单页结果不保证包含整个群组的全部成员。
|
|
228
|
-
|
|
229
|
-
`group audit` 要求当前账号具有群组管理员权限。`--limit` 的范围是 1 到 500,默认返回 100 条事件。可重复的 `--user` 用于筛选操作发起者。可重复的 `--type` 恰好接受以下 17 种稳定的分组事件类型:`info_changed`、`settings_changed`、`member_joined`、`member_left`、`member_invited`、`member_banned`、`member_unbanned`、`member_restricted`、`member_unrestricted`、`admin_promoted`、`admin_demoted`、`message_deleted`、`message_edited`、`message_pinned`、`invite_changed`、`topic_changed` 和 `other`。
|
|
230
|
-
|
|
231
|
-
查询和管理操作默认输出人类可读内容;暴露 `--json` 或 `--yaml` 的操作会输出结构化成功或错误结果。失败时进程退出状态非零。命令默认使用 current 账号;`--account <name>` 可仅为本次调用选择另一个已添加账号,且不会改变 current 账号。
|
|
232
|
-
|
|
233
|
-
管理操作分为 `member`、`admin`、`chat`、`invite`、`topic` 和 `message` 六个 family。成员目标必须显式使用 `@username` 或 Telegram 数字用户 ID。时长支持 `s`、`m`、`h`、`d` 后缀;支持关闭的设置还可使用 `off`。例如 `tg group member mute @team @alice 2h --yes` 会临时禁言,`tg group chat slowmode @team off` 会关闭慢速模式。
|
|
234
|
-
|
|
235
|
-
有破坏风险的 CLI 操作在缺少 `--yes` 时会直接拒绝,且不会连接 Telegram。永久删除群组还必须用 `--confirm-title` 提供完全一致的当前群名;交互式 listen 模式则通过 Ink 弹窗确认。管理操作需要对应的管理员权限,部分操作还要求超级群组、论坛或 creator 身份。转移所有权时,如果 Telegram 要求密码,本版本只返回 `password_required`,尚不接收密码。
|
|
236
|
-
|
|
237
|
-
查询成员详情请优先使用规范路由 `tg group member info <chat> <user>`。旧形式 `tg group member <chat> <user>` 仍保留,但当群名等于 `ban`、`mute`、`info` 等保留操作名时会产生歧义,必须使用规范路由。
|
|
238
|
-
|
|
239
|
-
## Listen 中的斜杠命令
|
|
240
|
-
|
|
241
|
-
交互式 `tg listen` 会在同一个菜单中展示所有支持的斜杠命令,包括 `/reply` 和完整的群管理命令目录。群管理命令沿用原有语法,无需重复当前群组:
|
|
242
|
-
|
|
243
|
-
```text
|
|
244
|
-
/reply <消息ID> <内容>
|
|
245
|
-
/member mute @alice 2h
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
输入 `/` 会打开统一命令菜单,并优先显示 reply。匹配顺序依次为完整匹配、前缀匹配和有序模糊匹配,因此 `/rep`、`/rpy` 都能找到 `/reply`,`/ban` 能找到 `/member ban`。使用 Up/Down 移动;Tab 补全选中的命令;对于尚未补全的命令,Enter 也会先补全,否则执行完整命令;Esc 关闭菜单、结果或确认框。
|
|
249
|
-
|
|
250
|
-
群管理命令原有的可用性和权限检查保持不变:不可用操作仍会禁用,有风险的操作会打开确认弹窗,删除群组还会要求输入完全一致的群名。监听多个群组时,必须先用 `--send-to <chat>` 明确发送目标,例如 `tg listen @team @ops --send-to @team`,之后才能使用群管理命令。
|
|
251
|
-
|
|
252
|
-
## 在线命令与本地命令
|
|
253
|
-
|
|
254
|
-
在线命令会连接 Telegram,因此需要有效的账号会话。这类命令包括 `status`、`whoami`、`chats`、`history`、`sync`、`sync-all`、`refresh`、`info`、全部 `group` 查询与管理 family、`send`、`edit`、`delete` 和 `listen`。
|
|
255
|
-
|
|
256
|
-
本地命令只读取或修改所选账号的消息数据库,不会连接 Telegram。这类命令包括 `search`、`recent`、`stats`、`top`、`timeline`、`today`、`filter`、`export` 和 `purge`。
|
|
257
|
-
|
|
258
|
-
## 查看最近消息
|
|
259
|
-
|
|
260
|
-
`tg recent` 默认显示最近 24 小时内存储的 50 条消息。你可以按聊天或发送者筛选,也可以调整时间范围和数量:
|
|
261
|
-
|
|
262
|
-
```sh
|
|
263
|
-
tg recent --chat <chat> --sender <sender> --hours 6 --limit 100
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
人类可读输出会将每个 Telegram 媒体组合并为一行,并汇总其中的附件。`ID` 列列出该行包含的所有原始消息 ID。如果回复目标已存储在本地同一聊天中,输出会显示原消息的时间、发送者、ID 和文本。否则会标出本地缺失的消息 ID。
|
|
267
|
-
|
|
268
|
-
JSON 和 YAML 输出保留已存储消息的结构,便于脚本处理。`recent` 只读取本地 SQLite 数据,不会连接 Telegram。
|
|
269
|
-
|
|
270
|
-
## 命令参考
|
|
271
|
-
|
|
272
|
-
运行内置帮助以查看完整且最新的命令列表:
|
|
273
|
-
|
|
274
|
-
```sh
|
|
275
|
-
tg --help
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
常用命令:
|
|
279
|
-
|
|
280
|
-
| 命令 | 用途 |
|
|
281
|
-
| --- | --- |
|
|
282
|
-
| `tg account add` | 登录并添加另一个 Telegram 账号。 |
|
|
283
|
-
| `tg account list` | 列出已添加的账号及 current 状态。 |
|
|
284
|
-
| `tg account current` | 查看 current 账号。 |
|
|
285
|
-
| `tg account switch [name]` | 交互式选择默认账号,或按名称设置账号。 |
|
|
286
|
-
| `tg account remove <name> --force` | 删除账号及其本地会话和数据。 |
|
|
287
|
-
| `tg whoami` | 显示当前登录账号的基本信息。 |
|
|
288
|
-
| `tg config set --api-id <id> --api-hash <hash>` | 持久化保存 Telegram API 凭据。 |
|
|
289
|
-
| `tg config set --proxy <url>` | 为账号登录及所有需要连接 Telegram 的命令保存可选代理。 |
|
|
290
|
-
| `tg config list [--show-secrets]` | 显示生效配置值及其来源;代理 URL 始终可见。 |
|
|
291
|
-
| `tg status` | 检查 Telegram 账户是否已完成身份验证。 |
|
|
292
|
-
| `tg chats` | 列出可用聊天。 |
|
|
293
|
-
| `tg history <chat> -n <limit>` | 获取并保存完整聊天历史(默认最多 1000 条)。 |
|
|
294
|
-
| `tg sync <chat>` | 将聊天消息同步到本地存储。 |
|
|
295
|
-
| `tg sync-all` | 从全部聊天同步消息,按本地已同步进度做增量更新。 |
|
|
296
|
-
| `tg refresh` | 与 `sync-all` 相同用途的批量同步命令。 |
|
|
297
|
-
| `tg listen [chat ...]` | 实时监听指定聊天(或监听全部聊天)。 |
|
|
298
|
-
| `tg listen --no-media` | 监听时隐藏附件摘要。 |
|
|
299
|
-
| `tg listen <chat-or-id> --auto-download` | 监听时自动下载收到的附件。 |
|
|
300
|
-
| `tg search "keyword" --chat <chat>` | 搜索已存储在本地的消息。 |
|
|
301
|
-
| `tg recent`, `tg today`, `tg stats`, `tg top`, `tg timeline` | 浏览本地消息数据。 |
|
|
302
|
-
| `tg filter <keywords>` | 按关键词筛选本地消息(支持按聊天和时间范围过滤)。 |
|
|
303
|
-
| `tg export <chat>` | 导出本地存储的消息。 |
|
|
304
|
-
| `tg send <chat> [message] [--file <path> ...]` | 发送文本、文件或带说明文字的媒体组。 |
|
|
305
|
-
| `tg edit <chat> <msgId> <text>` | 编辑消息。 |
|
|
306
|
-
| `tg delete <chat> <msgIds...>` | 删除一条或多条消息。 |
|
|
307
|
-
| `tg purge <chat> --yes` | 移除某个聊天在本地存储的消息。 |
|
|
308
|
-
| `tg info <chat>` | 查看聊天元信息。 |
|
|
309
|
-
| `tg group info <chat>` | 查看普通群组或超级群组的只读详情。 |
|
|
310
|
-
| `tg group members <chat> [--type <type>] [--query <text>] [--limit <count>]` | 列出并筛选成员(默认 `recent`、100 条;最大 200 条)。 |
|
|
311
|
-
| `tg group member <chat> <user>` | 查看单个成员的角色、权限和限制。 |
|
|
312
|
-
| `tg group audit <chat> [--query <text>] [--user <user>] [--type <type>] [--limit <count>]` | 查询管理员审计日志(默认 100 条;最大 500 条)。 |
|
|
313
|
-
|
|
314
|
-
所有同步类命令都会写入本地 SQLite 数据库。`sync-all` 和 `refresh` 根据本地已保存的消息 ID 增量处理多个聊天。
|
|
315
|
-
|
|
316
|
-
许多命令支持通过 `--json` 或 `--yaml` 输出结构化数据。命令失败时会返回非零退出码,脚本无需解析人类可读文本即可判断执行结果。
|
|
317
|
-
|
|
318
|
-
常用选项:
|
|
319
|
-
|
|
320
|
-
| 选项 | 用途 |
|
|
321
|
-
| --- | --- |
|
|
322
|
-
| `--account <name>` | 临时使用已添加的账号,不改变 current 账号。 |
|
|
323
|
-
| `--json` / `--yaml` | 在命令支持时输出结构化数据。 |
|
|
324
|
-
| `-v`, `--verbose` | 启用调试日志。 |
|
|
325
|
-
| `-V`, `--version` | 输出当前安装版本。 |
|
|
326
|
-
|
|
327
|
-
使用 `tg <command> --help` 查看命令专用选项。例如,`listen` 支持自动重连和纯文本模式,`search` 支持发送者、时间、正则表达式和结果数量筛选。
|
|
328
|
-
|
|
329
|
-
### 同步与监听行为
|
|
330
|
-
|
|
331
|
-
- `sync-all` 和 `refresh` 是写入本地数据库的批量同步流程,不是只读命令。
|
|
332
|
-
- `listen` 会实时打印每条到达消息;可用 `--no-media` 关闭附件摘要显示。
|
|
333
|
-
- Telegram 媒体组会显示为一条收到的消息,并合并附件摘要。
|
|
334
|
-
- 回复输出会在本地原消息可用时显示其上下文,否则标出缺失的消息 ID。
|
|
335
|
-
- 在交互式 `listen` 中,可用 `/reply <消息ID> <内容>` 回复消息;通过可重复的 `--file <路径>` 添加附件,包含空格的路径需要使用引号。
|
|
336
|
-
- 联系人卡片会在附件摘要中显示可用的姓名和手机号。联系人卡片不属于可下载附件,使用 `--no-media` 时不会显示。
|
|
337
|
-
- `listen --auto-download` 同时支持交互式和纯文本模式,附件保存在 `~/Downloads/telegram-cli`,最多同时下载 3 个附件。
|
|
338
|
-
- 下载时保留 Telegram 提供的文件名。无文件名时,依次根据 MIME 类型、媒体类型推断扩展名,最后回退为 `.bin`。
|
|
339
|
-
- 下载失败会被报告,但监听器会继续运行。`--no-media` 只隐藏附件摘要;与 `--auto-download` 组合时仍会下载附件。
|
|
340
|
-
|
|
341
|
-
## 故障排查
|
|
342
|
-
|
|
343
|
-
### 没有可用的当前账号
|
|
344
|
-
|
|
345
|
-
如果命令返回 `account_required`,请添加账号或选择已有账号:
|
|
346
|
-
|
|
347
|
-
```sh
|
|
348
|
-
tg account add
|
|
349
|
-
tg account switch <name>
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
### 账号会话已经失效
|
|
353
|
-
|
|
354
|
-
如果 Telegram 返回 `AUTH_KEY_UNREGISTERED`,请删除失效的本地会话并重新登录:
|
|
355
|
-
|
|
356
|
-
```sh
|
|
357
|
-
tg account remove <name> --force
|
|
358
|
-
tg account add
|
|
133
|
+
tg search "release" --account work --json
|
|
359
134
|
```
|
|
360
135
|
|
|
361
|
-
|
|
136
|
+
命令失败时会返回非零退出状态和稳定错误码。显式传入 `--account` 可以让自动化任务使用预期账号。
|
|
362
137
|
|
|
363
|
-
|
|
138
|
+
在受支持的编程智能体中安装 [`using-telegram-cli` agent skill](https://skills.sh/will-17173/telegram-cli/using-telegram-cli):
|
|
364
139
|
|
|
365
140
|
```sh
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
通过环境变量配置时,必须同时设置 `TG_API_ID` 和 `TG_API_HASH`。只设置其中一个会导致配置错误。
|
|
370
|
-
|
|
371
|
-
## 本地数据与隐私
|
|
372
|
-
|
|
373
|
-
除非你明确复制或导出,否则持久化配置、身份验证会话和已同步消息都会保留在本机。`DATA_DIR` 下的相关文件如下:
|
|
374
|
-
|
|
375
|
-
```text
|
|
376
|
-
config.json
|
|
377
|
-
accounts.json
|
|
378
|
-
accounts/<name>/session
|
|
379
|
-
accounts/<name>/messages.db
|
|
141
|
+
npx skills add https://github.com/will-17173/telegram-cli \
|
|
142
|
+
--skill using-telegram-cli
|
|
380
143
|
```
|
|
381
144
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
除 API 凭据外,`config.json` 文件还可能包含可选的 `proxy` 设置。CLI 的成功和错误输出不会打印已保存的代理 URL,但代理 URL 可能包含凭据或 MTProxy secret,因此仍须保护 `config.json`、环境和 shell 历史记录。
|
|
145
|
+
该技能涵盖认证、同步、查询和写操作安全流程。
|
|
385
146
|
|
|
386
147
|
## 开发
|
|
387
148
|
|
|
388
|
-
|
|
149
|
+
请使用 pnpm 和 Node.js 22 或更高版本:
|
|
389
150
|
|
|
390
151
|
```sh
|
|
391
152
|
pnpm install
|
|
392
153
|
pnpm dev --help
|
|
393
154
|
pnpm test
|
|
394
155
|
pnpm typecheck
|
|
156
|
+
pnpm build
|
|
395
157
|
```
|
|
396
158
|
|
|
397
|
-
开发时,可以将当前源码目录设置为全局 `tg` 命令,并直接运行 TypeScript 源码。在项目根目录执行:
|
|
398
|
-
|
|
399
|
-
```sh
|
|
400
|
-
mkdir -p ~/.local/bin
|
|
401
|
-
cat > ~/.local/bin/tg <<EOF
|
|
402
|
-
#!/bin/sh
|
|
403
|
-
exec "$(pwd)/node_modules/.bin/tsx" "$(pwd)/src/dev.ts" "\$@"
|
|
404
|
-
EOF
|
|
405
|
-
chmod +x ~/.local/bin/tg
|
|
406
|
-
rehash
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
请确保 `~/.local/bin` 已加入 `PATH`。之后执行 `tg` 时会加载最新的源码修改。
|
|
410
|
-
|
|
411
|
-
在本地进行源码开发时,请在项目根目录创建 `.env` 文件:
|
|
412
|
-
|
|
413
|
-
```dotenv
|
|
414
|
-
TG_API_ID=your_telegram_api_id
|
|
415
|
-
TG_API_HASH=your_telegram_api_hash
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
`pnpm dev` 仅在本地源码开发时加载此文件。安装后的 `tg` 不会自动加载 `.env`;如需持久化生产配置,请使用 `tg config set --api-id <id> --api-hash <hash>`。
|
|
419
|
-
|
|
420
159
|
## 许可证
|
|
421
160
|
|
|
422
|
-
|
|
161
|
+
本项目采用 [GPL-3.0-only](LICENSE) 许可证。
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { TelegramClient } from '@mtcute/node';
|
|
2
|
+
import { getTelegramCredentials, getTelegramProxy } from '../config/env.js';
|
|
3
|
+
import { telegramTransportOptions } from '../telegram/proxy.js';
|
|
4
|
+
import { createInterruptScope, isCliInputError, readSecret, readVisibleInput, } from '../cli/secure-input.js';
|
|
5
|
+
export async function authenticateAccountAt(sessionPath, createClient = createAccountAuthClient) {
|
|
6
|
+
const client = createClient(sessionPath);
|
|
7
|
+
const input = createAuthenticationInput();
|
|
8
|
+
try {
|
|
9
|
+
await client.start(input.options);
|
|
10
|
+
const user = await client.getMe();
|
|
11
|
+
return {
|
|
12
|
+
user,
|
|
13
|
+
close: () => client.destroy(),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
await client.destroy().catch(() => undefined);
|
|
18
|
+
throwAccountLoginError(error);
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
input.close();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function createAuthenticationInput() {
|
|
25
|
+
const interrupt = createInterruptScope();
|
|
26
|
+
return {
|
|
27
|
+
options: {
|
|
28
|
+
phone: () => readVisibleInput('Phone number: ', { signal: interrupt.signal }),
|
|
29
|
+
code: () => readVisibleInput('Login code: ', { signal: interrupt.signal }),
|
|
30
|
+
password: () => readSecret('2FA password: ', { signal: interrupt.signal }),
|
|
31
|
+
codeSentCallback: () => {
|
|
32
|
+
process.stderr.write('Login code sent.\n');
|
|
33
|
+
},
|
|
34
|
+
invalidCodeCallback: (type) => {
|
|
35
|
+
process.stderr.write(type === 'code'
|
|
36
|
+
? 'Invalid login code. Please try again.\n'
|
|
37
|
+
: 'Invalid 2FA password. Please try again.\n');
|
|
38
|
+
},
|
|
39
|
+
abortSignal: interrupt.signal,
|
|
40
|
+
},
|
|
41
|
+
close: interrupt.dispose,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function mapAuthUser(user) {
|
|
45
|
+
const displayName = user.displayName?.trim();
|
|
46
|
+
const displayNameFallback = [
|
|
47
|
+
user.firstName,
|
|
48
|
+
user.lastName,
|
|
49
|
+
].filter((value) => value != null && value.trim().length > 0).join(' ');
|
|
50
|
+
const username = user.username?.trim() || `user-${user.id}`;
|
|
51
|
+
const phone = (user.phoneNumber ?? '').replace(/\D/g, '') || String(user.id);
|
|
52
|
+
const preferredName = user.username?.trim().toLowerCase() || '';
|
|
53
|
+
const name = preferredName.length > 0 ? preferredName : phone;
|
|
54
|
+
const resolvedDisplayName = displayName && displayName.length > 0
|
|
55
|
+
? displayName
|
|
56
|
+
: displayNameFallback;
|
|
57
|
+
return {
|
|
58
|
+
user_id: user.id,
|
|
59
|
+
username: username.toLowerCase(),
|
|
60
|
+
phone,
|
|
61
|
+
display_name: resolvedDisplayName.length > 0 ? normalizeDisplayName(resolvedDisplayName) : username,
|
|
62
|
+
name,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function createAccountAuthClient(sessionPath) {
|
|
66
|
+
const credentials = getTelegramCredentials();
|
|
67
|
+
return new TelegramClient({
|
|
68
|
+
apiId: credentials.apiId,
|
|
69
|
+
apiHash: credentials.apiHash,
|
|
70
|
+
storage: sessionPath,
|
|
71
|
+
...telegramTransportOptions(getTelegramProxy()),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function normalizeDisplayName(displayName) {
|
|
75
|
+
const normalized = displayName.trim().replace(/\s+/g, ' ');
|
|
76
|
+
const words = normalized.split(' ');
|
|
77
|
+
for (let len = 1; len * 2 <= words.length; len += 1) {
|
|
78
|
+
if (words.length !== len * 2)
|
|
79
|
+
continue;
|
|
80
|
+
const first = words.slice(0, len).join(' ');
|
|
81
|
+
const second = words.slice(len).join(' ');
|
|
82
|
+
if (first === second)
|
|
83
|
+
return first;
|
|
84
|
+
}
|
|
85
|
+
return normalized;
|
|
86
|
+
}
|
|
87
|
+
function throwAccountLoginError(cause) {
|
|
88
|
+
if (isCliInputError(cause))
|
|
89
|
+
throw cause;
|
|
90
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
91
|
+
const error = new Error(message, { cause });
|
|
92
|
+
error.code = 'account_login_failed';
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=account-authenticator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-authenticator.js","sourceRoot":"","sources":["../../src/account/account-authenticator.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,13 @@ export function resolveAccountContext(input = {}) {
|
|
|
15
15
|
}
|
|
16
16
|
return toAccountContext(dataDir, account);
|
|
17
17
|
}
|
|
18
|
+
export function resolveAuthenticatedAccountContext(input = {}) {
|
|
19
|
+
const context = resolveAccountContext(input);
|
|
20
|
+
if (context.authState === 'logged_out') {
|
|
21
|
+
throw new Error(`account_logged_out: account "${context.name}" is logged out`);
|
|
22
|
+
}
|
|
23
|
+
return context;
|
|
24
|
+
}
|
|
18
25
|
function explicitOrCurrent(explicitName, currentAccount) {
|
|
19
26
|
const explicit = explicitName?.trim();
|
|
20
27
|
return explicit ? explicit : currentAccount ?? undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-context.js","sourceRoot":"","sources":["../../src/account/account-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAOvD,MAAM,UAAU,qBAAqB,CAAC,QAAgC,EAAE;IACtE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAA;IAC3E,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAA;IAC/D,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IAC7B,MAAM,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,YAAY,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAA;IAE5E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAA;IAC9D,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,GAAG,CAAC,CAAA;IACzD,CAAC;IAED,OAAO,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AAC3C,CAAC;AAED,SAAS,iBAAiB,CAAC,YAAgC,EAAE,cAA6B;IACxF,MAAM,QAAQ,GAAG,YAAY,EAAE,IAAI,EAAE,CAAA;IACrC,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,IAAI,SAAS,CAAA;AAC1D,CAAC"}
|
|
1
|
+
{"version":3,"file":"account-context.js","sourceRoot":"","sources":["../../src/account/account-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAOvD,MAAM,UAAU,qBAAqB,CAAC,QAAgC,EAAE;IACtE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAA;IAC3E,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAA;IAC/D,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IAC7B,MAAM,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,YAAY,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAA;IAE5E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAA;IAC9D,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,GAAG,CAAC,CAAA;IACzD,CAAC;IAED,OAAO,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AAC3C,CAAC;AAED,MAAM,UAAU,kCAAkC,CAAC,QAAgC,EAAE;IACnF,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;IAC5C,IAAI,OAAO,CAAC,SAAS,KAAK,YAAY,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,gCAAgC,OAAO,CAAC,IAAI,iBAAiB,CAAC,CAAA;IAChF,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,iBAAiB,CAAC,YAAgC,EAAE,cAA6B;IACxF,MAAM,QAAQ,GAAG,YAAY,EAAE,IAAI,EAAE,CAAA;IACrC,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,IAAI,SAAS,CAAA;AAC1D,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const PATH_SEPARATOR = /[/\\]/u;
|
|
2
|
+
const CONTROL_CHARACTER = /[\u0000-\u001f\u007f-\u009f]/u;
|
|
3
|
+
export function isSafeAccountName(value) {
|
|
4
|
+
return typeof value === 'string'
|
|
5
|
+
&& value.trim().length > 0
|
|
6
|
+
&& value !== '.'
|
|
7
|
+
&& value !== '..'
|
|
8
|
+
&& !PATH_SEPARATOR.test(value)
|
|
9
|
+
&& !CONTROL_CHARACTER.test(value)
|
|
10
|
+
&& value.normalize('NFC') === value;
|
|
11
|
+
}
|
|
12
|
+
export function assertSafeAccountName(value) {
|
|
13
|
+
if (!isSafeAccountName(value)) {
|
|
14
|
+
throw new Error('account_store_error: invalid account name');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=account-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-name.js","sourceRoot":"","sources":["../../src/account/account-name.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG,QAAQ,CAAA;AAC/B,MAAM,iBAAiB,GAAG,+BAA+B,CAAA;AAEzD,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,OAAO,KAAK,KAAK,QAAQ;WAC3B,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;WACvB,KAAK,KAAK,GAAG;WACb,KAAK,KAAK,IAAI;WACd,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;WAC3B,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;WAC9B,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,KAAK,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAA;IAC9D,CAAC;AACH,CAAC"}
|