@numa-tech/numa 1.14.23 → 1.14.24
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 +15 -0
- package/dist/cli.js +30 -10
- package/dist/cli.js.map +1 -1
- package/dist/command-catalog.js +25 -0
- package/dist/command-catalog.js.map +1 -1
- package/dist/mail/client.d.ts +57 -0
- package/dist/mail/client.js +251 -0
- package/dist/mail/client.js.map +1 -0
- package/dist/mail/commands.d.ts +2 -0
- package/dist/mail/commands.js +76 -0
- package/dist/mail/commands.js.map +1 -0
- package/dist/mail/errors.d.ts +6 -0
- package/dist/mail/errors.js +16 -0
- package/dist/mail/errors.js.map +1 -0
- package/dist/mail/schemas.d.ts +65 -0
- package/dist/mail/schemas.js +34 -0
- package/dist/mail/schemas.js.map +1 -0
- package/dist/pipeline/client.d.ts +20 -0
- package/dist/pipeline/client.js +21 -1
- package/dist/pipeline/client.js.map +1 -1
- package/dist/pipeline/commands.js +35 -0
- package/dist/pipeline/commands.js.map +1 -1
- package/dist/pipeline/schemas.d.ts +14 -0
- package/dist/pipeline/schemas.js +13 -0
- package/dist/pipeline/schemas.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { MailArchiveError } from "./errors.js";
|
|
5
|
+
import { CloudflareD1DatabaseListResponseSchema, CloudflareD1QueryResponseSchema } from "./schemas.js";
|
|
6
|
+
const CLOUDFLARE_API_BASE_URL = "https://api.cloudflare.com/client/v4";
|
|
7
|
+
const DEFAULT_D1_DATABASE_NAME = "active-code-inbox-mail-routing-prd";
|
|
8
|
+
const DEFAULT_LIMIT = 50;
|
|
9
|
+
const MAX_LIMIT = 100;
|
|
10
|
+
const MAX_ENV_FILE_BYTES = 64 * 1024;
|
|
11
|
+
export const DEFAULT_CLOUDFLARE_ENV_FILE = join(homedir(), ".config", "active-code-inbox", "cloudflare-microconect_com.env");
|
|
12
|
+
function parseEnvValue(value) {
|
|
13
|
+
const trimmed = value.trim();
|
|
14
|
+
if (trimmed.length >= 2) {
|
|
15
|
+
const first = trimmed[0];
|
|
16
|
+
const last = trimmed.at(-1);
|
|
17
|
+
if ((first === "\"" && last === "\"") || (first === "'" && last === "'")) {
|
|
18
|
+
return trimmed.slice(1, -1);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return trimmed;
|
|
22
|
+
}
|
|
23
|
+
export function parseCloudflareEnv(content) {
|
|
24
|
+
const values = new Map();
|
|
25
|
+
for (const line of content.split(/\r?\n/u)) {
|
|
26
|
+
const trimmed = line.trim();
|
|
27
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
28
|
+
continue;
|
|
29
|
+
const match = /^(?:export\s+)?([A-Z][A-Z0-9_]*)\s*=\s*(.*)$/u.exec(trimmed);
|
|
30
|
+
if (!match)
|
|
31
|
+
continue;
|
|
32
|
+
values.set(match[1], parseEnvValue(match[2]));
|
|
33
|
+
}
|
|
34
|
+
const accountId = values.get("CLOUDFLARE_ACCOUNT_ID") ?? "";
|
|
35
|
+
const apiToken = values.get("CLOUDFLARE_API_TOKEN") ?? "";
|
|
36
|
+
const zoneId = values.get("CLOUDFLARE_ZONE_ID") || undefined;
|
|
37
|
+
const d1DatabaseId = values.get("CLOUDFLARE_D1_DATABASE_ID") || undefined;
|
|
38
|
+
const d1DatabaseName = values.get("CLOUDFLARE_D1_DATABASE_NAME")
|
|
39
|
+
|| DEFAULT_D1_DATABASE_NAME;
|
|
40
|
+
if (!/^[a-f0-9]{32}$/iu.test(accountId)) {
|
|
41
|
+
throw new MailArchiveError("CLOUDFLARE_ACCOUNT_ID 缺失或格式无效。", "mail_archive_credentials_invalid");
|
|
42
|
+
}
|
|
43
|
+
if (apiToken.length < 20 || /[\r\n]/u.test(apiToken)) {
|
|
44
|
+
throw new MailArchiveError("CLOUDFLARE_API_TOKEN 缺失或格式无效。", "mail_archive_credentials_invalid");
|
|
45
|
+
}
|
|
46
|
+
if (zoneId && !/^[a-f0-9]{32}$/iu.test(zoneId)) {
|
|
47
|
+
throw new MailArchiveError("CLOUDFLARE_ZONE_ID 格式无效。", "mail_archive_credentials_invalid");
|
|
48
|
+
}
|
|
49
|
+
if (d1DatabaseId && !/^[a-f0-9-]{36}$/iu.test(d1DatabaseId)) {
|
|
50
|
+
throw new MailArchiveError("CLOUDFLARE_D1_DATABASE_ID 格式无效。", "mail_archive_credentials_invalid");
|
|
51
|
+
}
|
|
52
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(d1DatabaseName)) {
|
|
53
|
+
throw new MailArchiveError("CLOUDFLARE_D1_DATABASE_NAME 格式无效。", "mail_archive_credentials_invalid");
|
|
54
|
+
}
|
|
55
|
+
return { accountId, apiToken, ...(zoneId ? { zoneId } : {}), ...(d1DatabaseId ? { d1DatabaseId } : {}), d1DatabaseName };
|
|
56
|
+
}
|
|
57
|
+
export async function readCloudflareEnv(path = DEFAULT_CLOUDFLARE_ENV_FILE) {
|
|
58
|
+
let content;
|
|
59
|
+
try {
|
|
60
|
+
content = await readFile(path, "utf8");
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
64
|
+
throw new MailArchiveError(`无法读取 Cloudflare 配置文件: ${message}`, "mail_archive_env_file_unreadable");
|
|
65
|
+
}
|
|
66
|
+
if (Buffer.byteLength(content, "utf8") > MAX_ENV_FILE_BYTES) {
|
|
67
|
+
throw new MailArchiveError("Cloudflare 配置文件超过 64 KiB。", "mail_archive_env_file_too_large");
|
|
68
|
+
}
|
|
69
|
+
return parseCloudflareEnv(content);
|
|
70
|
+
}
|
|
71
|
+
function parseDateOption(value, option) {
|
|
72
|
+
if (value == null)
|
|
73
|
+
return {};
|
|
74
|
+
const millis = Date.parse(value);
|
|
75
|
+
if (!Number.isFinite(millis)) {
|
|
76
|
+
throw new MailArchiveError(`${option} 必须是有效的 ISO-8601 时间。`, "mail_archive_input_invalid");
|
|
77
|
+
}
|
|
78
|
+
return { value: new Date(millis).toISOString(), millis };
|
|
79
|
+
}
|
|
80
|
+
function normalizeRecipient(value) {
|
|
81
|
+
const recipient = value.trim().toLowerCase();
|
|
82
|
+
if (recipient.length > 320 || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/u.test(recipient)) {
|
|
83
|
+
throw new MailArchiveError("收件地址格式无效。", "mail_archive_input_invalid");
|
|
84
|
+
}
|
|
85
|
+
return recipient;
|
|
86
|
+
}
|
|
87
|
+
function parseLimit(value) {
|
|
88
|
+
const limit = value ?? DEFAULT_LIMIT;
|
|
89
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > MAX_LIMIT) {
|
|
90
|
+
throw new MailArchiveError(`limit 必须是 1 到 ${MAX_LIMIT} 之间的整数。`, "mail_archive_input_invalid");
|
|
91
|
+
}
|
|
92
|
+
return limit;
|
|
93
|
+
}
|
|
94
|
+
function isoFromMillis(value) {
|
|
95
|
+
if (value == null || !Number.isFinite(value))
|
|
96
|
+
return null;
|
|
97
|
+
return new Date(value).toISOString();
|
|
98
|
+
}
|
|
99
|
+
function deliveryRecord(row) {
|
|
100
|
+
let delivery;
|
|
101
|
+
try {
|
|
102
|
+
delivery = JSON.parse(row.delivery_json);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
throw new MailArchiveError(`Cloudflare D1 返回的 delivery_json 无法解析(${row.delivery_id})。`, "mail_archive_invalid_response");
|
|
106
|
+
}
|
|
107
|
+
if (!delivery || typeof delivery !== "object") {
|
|
108
|
+
throw new MailArchiveError(`Cloudflare D1 返回的 delivery_json 格式无效(${row.delivery_id})。`, "mail_archive_invalid_response");
|
|
109
|
+
}
|
|
110
|
+
const envelope = delivery.envelope;
|
|
111
|
+
const raw = delivery.raw;
|
|
112
|
+
if (!envelope || typeof envelope !== "object" || !raw || typeof raw !== "object") {
|
|
113
|
+
throw new MailArchiveError(`Cloudflare D1 返回的投递记录缺少 envelope/raw(${row.delivery_id})。`, "mail_archive_invalid_response");
|
|
114
|
+
}
|
|
115
|
+
const sender = envelope.from;
|
|
116
|
+
const recipient = envelope.to;
|
|
117
|
+
const receivedAt = delivery.receivedAt;
|
|
118
|
+
const rawSize = raw.size;
|
|
119
|
+
if (typeof sender !== "string" || typeof recipient !== "string"
|
|
120
|
+
|| typeof receivedAt !== "string" || typeof rawSize !== "number") {
|
|
121
|
+
throw new MailArchiveError(`Cloudflare D1 返回的投递记录字段无效(${row.delivery_id})。`, "mail_archive_invalid_response");
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
deliveryId: row.delivery_id,
|
|
125
|
+
receivedAt,
|
|
126
|
+
sender,
|
|
127
|
+
recipient,
|
|
128
|
+
rawSizeBytes: rawSize,
|
|
129
|
+
status: row.status,
|
|
130
|
+
enqueueAttempts: row.enqueue_attempts,
|
|
131
|
+
deliveryAttempts: row.delivery_attempts,
|
|
132
|
+
lastAttemptedAt: isoFromMillis(row.last_attempted_at),
|
|
133
|
+
deliveredAt: isoFromMillis(row.delivered_at),
|
|
134
|
+
errorCode: row.error_code ?? null,
|
|
135
|
+
bodyAvailable: false
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function cloudflareErrorMessage(body, fallback) {
|
|
139
|
+
if (!body || typeof body !== "object")
|
|
140
|
+
return fallback;
|
|
141
|
+
const errors = body.errors;
|
|
142
|
+
if (!Array.isArray(errors))
|
|
143
|
+
return fallback;
|
|
144
|
+
const messages = errors
|
|
145
|
+
.map((item) => item && typeof item === "object" && typeof item.message === "string"
|
|
146
|
+
? item.message : undefined)
|
|
147
|
+
.filter((item) => Boolean(item));
|
|
148
|
+
return messages.join("; ") || fallback;
|
|
149
|
+
}
|
|
150
|
+
export class CloudflareMailArchiveClient {
|
|
151
|
+
credentials;
|
|
152
|
+
fetchImpl;
|
|
153
|
+
constructor(credentials, dependencies = {}) {
|
|
154
|
+
this.credentials = credentials;
|
|
155
|
+
this.fetchImpl = dependencies.fetch ?? fetch;
|
|
156
|
+
}
|
|
157
|
+
apiUrl(path) {
|
|
158
|
+
return `${CLOUDFLARE_API_BASE_URL}/accounts/${encodeURIComponent(this.credentials.accountId)}${path}`;
|
|
159
|
+
}
|
|
160
|
+
async request(path, init = {}) {
|
|
161
|
+
const headers = new Headers(init.headers);
|
|
162
|
+
headers.set("Authorization", `Bearer ${this.credentials.apiToken}`);
|
|
163
|
+
headers.set("Accept", "application/json");
|
|
164
|
+
if (init.body != null && !headers.has("Content-Type"))
|
|
165
|
+
headers.set("Content-Type", "application/json");
|
|
166
|
+
let response;
|
|
167
|
+
try {
|
|
168
|
+
response = await this.fetchImpl(this.apiUrl(path), { ...init, headers });
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
172
|
+
throw new MailArchiveError(`Cloudflare API 请求失败: ${message}`, "mail_archive_network_error");
|
|
173
|
+
}
|
|
174
|
+
const text = await response.text();
|
|
175
|
+
let body = {};
|
|
176
|
+
if (text) {
|
|
177
|
+
try {
|
|
178
|
+
body = JSON.parse(text);
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
body = text;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (!response.ok) {
|
|
185
|
+
throw new MailArchiveError(`Cloudflare API 返回 HTTP ${response.status}: ${cloudflareErrorMessage(body, response.statusText || "请求失败")}`, response.status === 401 || response.status === 403 ? "mail_archive_forbidden" : "mail_archive_api_error", response.status);
|
|
186
|
+
}
|
|
187
|
+
return body;
|
|
188
|
+
}
|
|
189
|
+
async databaseId() {
|
|
190
|
+
if (this.credentials.d1DatabaseId) {
|
|
191
|
+
return { id: this.credentials.d1DatabaseId, name: this.credentials.d1DatabaseName };
|
|
192
|
+
}
|
|
193
|
+
const body = CloudflareD1DatabaseListResponseSchema.safeParse(await this.request("/d1/database?per_page=100"));
|
|
194
|
+
if (!body.success || !body.data.success) {
|
|
195
|
+
throw new MailArchiveError("Cloudflare D1 数据库列表响应格式无效。", "mail_archive_invalid_response");
|
|
196
|
+
}
|
|
197
|
+
const database = (body.data.result ?? []).find((item) => item.name === this.credentials.d1DatabaseName);
|
|
198
|
+
if (!database) {
|
|
199
|
+
throw new MailArchiveError(`找不到 Cloudflare D1 数据库: ${this.credentials.d1DatabaseName}`, "mail_archive_database_not_found");
|
|
200
|
+
}
|
|
201
|
+
return { id: database.uuid, name: database.name };
|
|
202
|
+
}
|
|
203
|
+
async search(input) {
|
|
204
|
+
const recipient = normalizeRecipient(input.recipient);
|
|
205
|
+
const since = parseDateOption(input.since, "--since");
|
|
206
|
+
const until = parseDateOption(input.until, "--until");
|
|
207
|
+
if (since.millis !== undefined && until.millis !== undefined && since.millis >= until.millis) {
|
|
208
|
+
throw new MailArchiveError("--since 必须早于 --until。", "mail_archive_input_invalid");
|
|
209
|
+
}
|
|
210
|
+
const limit = parseLimit(input.limit);
|
|
211
|
+
const database = await this.databaseId();
|
|
212
|
+
const clauses = ["lower(json_extract(delivery_json, '$.envelope.to')) = lower(?)"];
|
|
213
|
+
const params = [recipient];
|
|
214
|
+
if (since.millis !== undefined) {
|
|
215
|
+
clauses.push("created_at >= ?");
|
|
216
|
+
params.push(since.millis);
|
|
217
|
+
}
|
|
218
|
+
if (until.millis !== undefined) {
|
|
219
|
+
clauses.push("created_at < ?");
|
|
220
|
+
params.push(until.millis);
|
|
221
|
+
}
|
|
222
|
+
const sql = `SELECT delivery_id, delivery_json, status, enqueue_attempts, delivery_attempts,
|
|
223
|
+
last_queued_at, last_attempted_at, delivered_at, error_code, created_at, updated_at
|
|
224
|
+
FROM mail_delivery_spool WHERE ${clauses.join(" AND ")}
|
|
225
|
+
ORDER BY created_at DESC LIMIT ?`;
|
|
226
|
+
params.push(limit + 1);
|
|
227
|
+
const body = CloudflareD1QueryResponseSchema.safeParse(await this.request(`/d1/database/${encodeURIComponent(database.id)}/query`, {
|
|
228
|
+
method: "POST",
|
|
229
|
+
body: JSON.stringify({ sql, params })
|
|
230
|
+
}));
|
|
231
|
+
if (!body.success || !body.data.success || body.data.result.length !== 1 || !body.data.result[0].success) {
|
|
232
|
+
throw new MailArchiveError("Cloudflare D1 查询响应格式无效。", "mail_archive_invalid_response");
|
|
233
|
+
}
|
|
234
|
+
const rows = body.data.result[0].results;
|
|
235
|
+
const records = rows.slice(0, limit).map(deliveryRecord);
|
|
236
|
+
return {
|
|
237
|
+
schemaVersion: 1,
|
|
238
|
+
source: "cloudflare-d1-delivery-ledger",
|
|
239
|
+
databaseName: database.name,
|
|
240
|
+
recipient,
|
|
241
|
+
since: since.value ?? null,
|
|
242
|
+
until: until.value ?? null,
|
|
243
|
+
records,
|
|
244
|
+
hasMore: rows.length > limit,
|
|
245
|
+
bodyAvailable: false,
|
|
246
|
+
note: "Cloudflare 成功转交后会删除 R2 原始邮件;本查询只返回投递元数据,正文请到 Code Inbox 归档查看。"
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
export { DEFAULT_D1_DATABASE_NAME, MAX_LIMIT };
|
|
251
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/mail/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { loadAppConfig } from "../app-config.js";
|
|
3
|
+
import { DEFAULT_CLOUDFLARE_ENV_FILE, CloudflareMailArchiveClient, readCloudflareEnv } from "./client.js";
|
|
4
|
+
import { MailArchiveError } from "./errors.js";
|
|
5
|
+
function jsonEnabled(command, configuredOutput) {
|
|
6
|
+
return Boolean(command.optsWithGlobals().json || configuredOutput === "json");
|
|
7
|
+
}
|
|
8
|
+
function printJson(value) {
|
|
9
|
+
process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
|
|
10
|
+
}
|
|
11
|
+
function addExamples(command, examples) {
|
|
12
|
+
return command.addHelpText("after", `\nExamples:\n${examples.map((item) => ` ${item}`).join("\n")}\n`);
|
|
13
|
+
}
|
|
14
|
+
function limit(value) {
|
|
15
|
+
const parsed = Number.parseInt(value, 10);
|
|
16
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 100 || String(parsed) !== value.trim()) {
|
|
17
|
+
throw new MailArchiveError("--limit 必须是 1 到 100 之间的整数。", "mail_archive_input_invalid");
|
|
18
|
+
}
|
|
19
|
+
return parsed;
|
|
20
|
+
}
|
|
21
|
+
function formatDate(value) {
|
|
22
|
+
if (!value)
|
|
23
|
+
return "-";
|
|
24
|
+
return new Date(value).toLocaleString("zh-CN", { hour12: false });
|
|
25
|
+
}
|
|
26
|
+
export function registerMailCommands(program) {
|
|
27
|
+
const mail = program
|
|
28
|
+
.command("mail")
|
|
29
|
+
.description("邮件链路诊断与 Cloudflare 投递账本查询");
|
|
30
|
+
const archive = mail
|
|
31
|
+
.command("archive")
|
|
32
|
+
.description("查询邮件投递元数据(不读取验证码、激活链接或正文)");
|
|
33
|
+
addExamples(archive
|
|
34
|
+
.command("search <recipient>")
|
|
35
|
+
.description("按精确收件地址查询 Cloudflare D1 邮件投递账本")
|
|
36
|
+
.option("--env-file <file>", "Cloudflare env 文件", DEFAULT_CLOUDFLARE_ENV_FILE)
|
|
37
|
+
.option("--since <iso>", "起始时间(ISO-8601,含起始值)")
|
|
38
|
+
.option("--until <iso>", "结束时间(ISO-8601,不含结束值)")
|
|
39
|
+
.option("-l, --limit <number>", "返回条数,1-100", limit, 50)
|
|
40
|
+
.action(async (recipient, options, command) => {
|
|
41
|
+
const credentials = await readCloudflareEnv(options.envFile);
|
|
42
|
+
const result = await new CloudflareMailArchiveClient(credentials).search({
|
|
43
|
+
recipient,
|
|
44
|
+
since: options.since,
|
|
45
|
+
until: options.until,
|
|
46
|
+
limit: options.limit
|
|
47
|
+
});
|
|
48
|
+
const config = await loadAppConfig();
|
|
49
|
+
if (jsonEnabled(command, config.output)) {
|
|
50
|
+
printJson({ ok: true, ...result });
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
process.stdout.write(`Cloudflare 邮件投递账本\n`);
|
|
54
|
+
process.stdout.write(`收件地址: ${result.recipient}\n`);
|
|
55
|
+
process.stdout.write(`数据库: ${result.databaseName}\n`);
|
|
56
|
+
process.stdout.write(`记录数: ${result.records.length}${result.hasMore ? "+" : ""}\n`);
|
|
57
|
+
if (result.records.length === 0) {
|
|
58
|
+
process.stdout.write("没有找到匹配的 Cloudflare 投递记录。\n");
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
for (const record of result.records) {
|
|
62
|
+
process.stdout.write(`- ${formatDate(record.receivedAt)} ${record.status}`
|
|
63
|
+
+ ` from=${record.sender} size=${record.rawSizeBytes}B`
|
|
64
|
+
+ ` attempts=${record.deliveryAttempts}`
|
|
65
|
+
+ ` delivery=${record.deliveryId}\n`);
|
|
66
|
+
if (record.errorCode)
|
|
67
|
+
process.stdout.write(` error=${record.errorCode}\n`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
process.stdout.write(`说明: ${result.note}\n`);
|
|
71
|
+
}), [
|
|
72
|
+
"numa mail archive search kenneth.davis@mail.microconnect.com",
|
|
73
|
+
"numa mail archive search kenneth.davis@mail.microconnect.com --since 2026-09-02T00:00:00Z --json"
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/mail/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function redactMailDiagnosticText(value: string): string;
|
|
2
|
+
export declare class MailArchiveError extends Error {
|
|
3
|
+
readonly code: string;
|
|
4
|
+
readonly status?: number | undefined;
|
|
5
|
+
constructor(message: string, code: string, status?: number | undefined);
|
|
6
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function redactMailDiagnosticText(value) {
|
|
2
|
+
return value
|
|
3
|
+
.replace(/Bearer\s+[A-Za-z0-9._~+/=-]+/giu, "Bearer [REDACTED]")
|
|
4
|
+
.replace(/(CLOUDFLARE_API_TOKEN\s*=\s*)[^\s,]+/giu, "$1[REDACTED]");
|
|
5
|
+
}
|
|
6
|
+
export class MailArchiveError extends Error {
|
|
7
|
+
code;
|
|
8
|
+
status;
|
|
9
|
+
constructor(message, code, status) {
|
|
10
|
+
super(redactMailDiagnosticText(message));
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.name = "MailArchiveError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/mail/errors.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,wBAAwB,CAAC,KAAa;IACpD,OAAO,KAAK;SACT,OAAO,CAAC,iCAAiC,EAAE,mBAAmB,CAAC;SAC/D,OAAO,CAAC,yCAAyC,EAAE,cAAc,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAGvB,IAAI;IACJ,MAAM;IAHxB,YACE,OAAe,EACC,IAAY,EACZ,MAAe;QAE/B,KAAK,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC;oBAHzB,IAAI;sBACJ,MAAM;QAGtB,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const CloudflareD1DatabaseSchema: z.ZodObject<{
|
|
3
|
+
uuid: z.ZodString;
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
}, z.core.$loose>;
|
|
6
|
+
export declare const CloudflareD1DatabaseListResponseSchema: z.ZodObject<{
|
|
7
|
+
success: z.ZodBoolean;
|
|
8
|
+
result: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
9
|
+
uuid: z.ZodString;
|
|
10
|
+
name: z.ZodString;
|
|
11
|
+
}, z.core.$loose>>>;
|
|
12
|
+
errors: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
13
|
+
}, z.core.$loose>;
|
|
14
|
+
export declare const CloudflareD1RowSchema: z.ZodObject<{
|
|
15
|
+
delivery_id: z.ZodString;
|
|
16
|
+
delivery_json: z.ZodString;
|
|
17
|
+
status: z.ZodString;
|
|
18
|
+
enqueue_attempts: z.ZodNumber;
|
|
19
|
+
delivery_attempts: z.ZodNumber;
|
|
20
|
+
last_queued_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
21
|
+
last_attempted_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
22
|
+
delivered_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
23
|
+
error_code: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
24
|
+
created_at: z.ZodNumber;
|
|
25
|
+
updated_at: z.ZodNumber;
|
|
26
|
+
}, z.core.$loose>;
|
|
27
|
+
export declare const CloudflareD1QueryResultSchema: z.ZodObject<{
|
|
28
|
+
success: z.ZodBoolean;
|
|
29
|
+
results: z.ZodArray<z.ZodObject<{
|
|
30
|
+
delivery_id: z.ZodString;
|
|
31
|
+
delivery_json: z.ZodString;
|
|
32
|
+
status: z.ZodString;
|
|
33
|
+
enqueue_attempts: z.ZodNumber;
|
|
34
|
+
delivery_attempts: z.ZodNumber;
|
|
35
|
+
last_queued_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
36
|
+
last_attempted_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
37
|
+
delivered_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
38
|
+
error_code: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
39
|
+
created_at: z.ZodNumber;
|
|
40
|
+
updated_at: z.ZodNumber;
|
|
41
|
+
}, z.core.$loose>>;
|
|
42
|
+
errors: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
43
|
+
}, z.core.$loose>;
|
|
44
|
+
export declare const CloudflareD1QueryResponseSchema: z.ZodObject<{
|
|
45
|
+
success: z.ZodBoolean;
|
|
46
|
+
result: z.ZodArray<z.ZodObject<{
|
|
47
|
+
success: z.ZodBoolean;
|
|
48
|
+
results: z.ZodArray<z.ZodObject<{
|
|
49
|
+
delivery_id: z.ZodString;
|
|
50
|
+
delivery_json: z.ZodString;
|
|
51
|
+
status: z.ZodString;
|
|
52
|
+
enqueue_attempts: z.ZodNumber;
|
|
53
|
+
delivery_attempts: z.ZodNumber;
|
|
54
|
+
last_queued_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
55
|
+
last_attempted_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
56
|
+
delivered_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
57
|
+
error_code: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
58
|
+
created_at: z.ZodNumber;
|
|
59
|
+
updated_at: z.ZodNumber;
|
|
60
|
+
}, z.core.$loose>>;
|
|
61
|
+
errors: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
62
|
+
}, z.core.$loose>>;
|
|
63
|
+
errors: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
64
|
+
}, z.core.$loose>;
|
|
65
|
+
export type CloudflareD1Row = z.infer<typeof CloudflareD1RowSchema>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const CloudflareD1DatabaseSchema = z.object({
|
|
3
|
+
uuid: z.string().min(1),
|
|
4
|
+
name: z.string().min(1)
|
|
5
|
+
}).passthrough();
|
|
6
|
+
export const CloudflareD1DatabaseListResponseSchema = z.object({
|
|
7
|
+
success: z.boolean(),
|
|
8
|
+
result: z.array(CloudflareD1DatabaseSchema).optional(),
|
|
9
|
+
errors: z.array(z.unknown()).optional()
|
|
10
|
+
}).passthrough();
|
|
11
|
+
export const CloudflareD1RowSchema = z.object({
|
|
12
|
+
delivery_id: z.string().min(1),
|
|
13
|
+
delivery_json: z.string().min(1),
|
|
14
|
+
status: z.string().min(1),
|
|
15
|
+
enqueue_attempts: z.number().int().nonnegative(),
|
|
16
|
+
delivery_attempts: z.number().int().nonnegative(),
|
|
17
|
+
last_queued_at: z.number().int().nullable().optional(),
|
|
18
|
+
last_attempted_at: z.number().int().nullable().optional(),
|
|
19
|
+
delivered_at: z.number().int().nullable().optional(),
|
|
20
|
+
error_code: z.string().nullable().optional(),
|
|
21
|
+
created_at: z.number().int(),
|
|
22
|
+
updated_at: z.number().int()
|
|
23
|
+
}).passthrough();
|
|
24
|
+
export const CloudflareD1QueryResultSchema = z.object({
|
|
25
|
+
success: z.boolean(),
|
|
26
|
+
results: z.array(CloudflareD1RowSchema),
|
|
27
|
+
errors: z.array(z.unknown()).optional()
|
|
28
|
+
}).passthrough();
|
|
29
|
+
export const CloudflareD1QueryResponseSchema = z.object({
|
|
30
|
+
success: z.boolean(),
|
|
31
|
+
result: z.array(CloudflareD1QueryResultSchema),
|
|
32
|
+
errors: z.array(z.unknown()).optional()
|
|
33
|
+
}).passthrough();
|
|
34
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/mail/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACxB,CAAC,CAAC,WAAW,EAAE,CAAC;AAEjB,MAAM,CAAC,MAAM,sCAAsC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,QAAQ,EAAE;IACtD,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC,WAAW,EAAE,CAAC;AAEjB,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAChC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAChD,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACjD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACtD,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACzD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACpD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC5C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC5B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;CAC7B,CAAC,CAAC,WAAW,EAAE,CAAC;AAEjB,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC;IACvC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC,WAAW,EAAE,CAAC;AAEjB,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC,MAAM,CAAC;IACtD,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,6BAA6B,CAAC;IAC9C,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC,WAAW,EAAE,CAAC"}
|
|
@@ -26,6 +26,12 @@ export interface TriggerBuildInput extends ProductionApprovalInput {
|
|
|
26
26
|
parameters: Record<string, string>;
|
|
27
27
|
idempotencyKey: string;
|
|
28
28
|
}
|
|
29
|
+
export interface BindingAdjustmentInput {
|
|
30
|
+
bindingId: number;
|
|
31
|
+
jobId: number;
|
|
32
|
+
expectedVersion: number;
|
|
33
|
+
reason: string;
|
|
34
|
+
}
|
|
29
35
|
export declare class PipelineClient {
|
|
30
36
|
private readonly config;
|
|
31
37
|
private readonly fetchImpl;
|
|
@@ -89,6 +95,20 @@ export declare class PipelineClient {
|
|
|
89
95
|
queueId?: number | null | undefined;
|
|
90
96
|
pollUrl?: string | undefined;
|
|
91
97
|
}>;
|
|
98
|
+
adjustBinding(input: BindingAdjustmentInput): Promise<{
|
|
99
|
+
[x: string]: unknown;
|
|
100
|
+
id: number;
|
|
101
|
+
applicationCode: string;
|
|
102
|
+
jobId: number;
|
|
103
|
+
jobFullName?: string | null | undefined;
|
|
104
|
+
instanceId?: number | null | undefined;
|
|
105
|
+
instanceCode?: string | null | undefined;
|
|
106
|
+
tier: string;
|
|
107
|
+
bindingSource: string;
|
|
108
|
+
confirmationStatus: string;
|
|
109
|
+
productionLocked: boolean;
|
|
110
|
+
version: number;
|
|
111
|
+
}>;
|
|
92
112
|
getBuild(identifier: string): Promise<{
|
|
93
113
|
[x: string]: unknown;
|
|
94
114
|
requestId?: string | undefined;
|
package/dist/pipeline/client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolveBackendUrl } from "../backend.js";
|
|
2
2
|
import { ensureAccessToken, fetchWithKeycloakIdentity } from "../oauth.js";
|
|
3
|
-
import { ApiErrorSchema, BuildListSchema, BuildLogSchema, BuildSchema, PipelineDetailSchema, PipelineListSchema } from "./schemas.js";
|
|
3
|
+
import { ApiErrorSchema, BuildListSchema, BuildLogSchema, BuildSchema, JenkinsBindingSchema, PipelineDetailSchema, PipelineListSchema } from "./schemas.js";
|
|
4
4
|
import { PipelineError, redactPipelineText } from "./errors.js";
|
|
5
5
|
function requestIdFrom(response, body) {
|
|
6
6
|
if (body && typeof body === "object" && "requestId" in body && typeof body.requestId === "string")
|
|
@@ -87,6 +87,26 @@ export class PipelineClient {
|
|
|
87
87
|
body: JSON.stringify(input)
|
|
88
88
|
}, [200, 202]);
|
|
89
89
|
}
|
|
90
|
+
adjustBinding(input) {
|
|
91
|
+
if (!Number.isSafeInteger(input.bindingId) || input.bindingId < 1
|
|
92
|
+
|| !Number.isSafeInteger(input.jobId) || input.jobId < 1
|
|
93
|
+
|| !Number.isSafeInteger(input.expectedVersion) || input.expectedVersion < 0
|
|
94
|
+
|| !input.reason.trim() || input.reason.trim().length > 800) {
|
|
95
|
+
throw new PipelineError("Binding adjustment input is invalid.", "JENKINS_CLI_INPUT_INVALID");
|
|
96
|
+
}
|
|
97
|
+
const bindingId = encodeURIComponent(String(input.bindingId));
|
|
98
|
+
return this.json(`/api/v1/admin/jenkins/bindings/${bindingId}/adjust`, JenkinsBindingSchema, {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: {
|
|
101
|
+
"Idempotency-Key": `binding-adjust-${input.bindingId}-${input.jobId}-${input.expectedVersion}`
|
|
102
|
+
},
|
|
103
|
+
body: JSON.stringify({
|
|
104
|
+
jobId: input.jobId,
|
|
105
|
+
expectedVersion: input.expectedVersion,
|
|
106
|
+
reason: input.reason.trim()
|
|
107
|
+
})
|
|
108
|
+
}, [200]);
|
|
109
|
+
}
|
|
90
110
|
getBuild(identifier) {
|
|
91
111
|
return this.json(`/api/v1/jenkins/builds/${encodeURIComponent(identifier)}`, BuildSchema);
|
|
92
112
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/pipeline/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAA8B,MAAM,aAAa,CAAC;AACvG,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAGnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/pipeline/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -70,6 +70,16 @@ function positiveInteger(value, label, fallback, maximum) {
|
|
|
70
70
|
}
|
|
71
71
|
return parsed;
|
|
72
72
|
}
|
|
73
|
+
function nonNegativeInteger(value, label, maximum) {
|
|
74
|
+
if (value == null) {
|
|
75
|
+
throw new PipelineError(`${label} is required.`, "JENKINS_CLI_INPUT_INVALID");
|
|
76
|
+
}
|
|
77
|
+
const parsed = Number(value);
|
|
78
|
+
if (!Number.isInteger(parsed) || parsed < 0 || parsed > maximum) {
|
|
79
|
+
throw new PipelineError(`${label} must be an integer between 0 and ${maximum}.`, "JENKINS_CLI_INPUT_INVALID");
|
|
80
|
+
}
|
|
81
|
+
return parsed;
|
|
82
|
+
}
|
|
73
83
|
function collect(value, previous) {
|
|
74
84
|
return [...previous, value];
|
|
75
85
|
}
|
|
@@ -217,6 +227,31 @@ export function registerPipelineCommands(program, dependencies = {}) {
|
|
|
217
227
|
"用于在未保存 requestId 时按应用、环境、分支或状态找回构建记录。",
|
|
218
228
|
"--cursor 使用上一页响应返回的游标;--limit 控制每页条数,不是页码。"
|
|
219
229
|
]);
|
|
230
|
+
addExamples(pipeline.command("binding-adjust <binding-id>")
|
|
231
|
+
.description("将已确认的 Jenkins binding 切换到另一个当前同步的 Job")
|
|
232
|
+
.requiredOption("--job-id <id>", "目标 Jenkins Job ID")
|
|
233
|
+
.requiredOption("--expected-version <number>", "当前 binding 的乐观锁版本")
|
|
234
|
+
.requiredOption("--reason <text>", "调整原因,最多 800 个字符")
|
|
235
|
+
.option("--yes", "确认停用旧 binding 并建立 successor binding")
|
|
236
|
+
.action(async (bindingId, options, command) => {
|
|
237
|
+
if (!options.yes)
|
|
238
|
+
throw new PipelineError("Adjusting a binding requires --yes.", "JENKINS_CONFIRMATION_REQUIRED");
|
|
239
|
+
const reason = options.reason?.trim() ?? "";
|
|
240
|
+
if (!reason || reason.length > 800) {
|
|
241
|
+
throw new PipelineError("reason must be 1-800 characters.", "JENKINS_CLI_INPUT_INVALID");
|
|
242
|
+
}
|
|
243
|
+
const result = await client().adjustBinding({
|
|
244
|
+
bindingId: positiveInteger(identifier(bindingId, "binding-id"), "binding-id", 1, Number.MAX_SAFE_INTEGER),
|
|
245
|
+
jobId: positiveInteger(options.jobId, "job-id", 1, Number.MAX_SAFE_INTEGER),
|
|
246
|
+
expectedVersion: nonNegativeInteger(options.expectedVersion, "expected-version", Number.MAX_SAFE_INTEGER),
|
|
247
|
+
reason
|
|
248
|
+
});
|
|
249
|
+
await output(command, { ok: true, binding: result }, `${result.id}\t${result.confirmationStatus}\tJob ${result.jobId}\t${result.tier}\tv${result.version}`);
|
|
250
|
+
}), ["numa pipeline binding-adjust 4 --job-id 123 --expected-version 0 --reason 'repair synchronized Jenkins target' --yes --json"], [
|
|
251
|
+
"该命令只修改 DevOps platform binding,不改 Jenkins Job 配置,不改应用仓库,也不触发构建。",
|
|
252
|
+
"旧 binding 会保留为 DISABLED;历史构建仍引用旧 binding,平台返回新的 successor binding。",
|
|
253
|
+
"结果不明时使用完全相同的 binding-id、job-id 和 expected-version 重试;服务端会安全返回已提交的 successor。"
|
|
254
|
+
]);
|
|
220
255
|
addExamples(pipeline.command("build <application>")
|
|
221
256
|
.description("触发流水线构建;生产要求 ops-admin 及审批 ID 或具体说明")
|
|
222
257
|
.requiredOption("--tier <tier>", "develop|staging|production")
|