ai-fly 0.3.2 → 0.4.0-alpha.10
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/dist/ai-fly.js +23 -6
- package/dist/app/main.js +9047 -0
- package/dist/{common-CqxqIg6D.mjs → common-C51SAE5f.mjs} +17 -6
- package/dist/{common-CgxCXeTt.mjs → common-CanLn0Qt.mjs} +1 -1
- package/dist/{daemon-ZWUSWAgM.mjs → daemon-BWgyJMyB.mjs} +3 -3
- package/dist/{forget-BXL2x4Wv.mjs → forget-B3KRkHho.mjs} +2 -2
- package/dist/{frames-BDqvhB2Y.mjs → frames-BDz8buix.mjs} +1 -0
- package/dist/{group-B96IKEDF.mjs → group-BdnvRD2t.mjs} +1 -1
- package/dist/hook-CvAMGts4.mjs +228 -0
- package/dist/hooks-DUrXA7PL.mjs +142 -0
- package/dist/{import-rpBFh_pa.mjs → import-CTkKGPsa.mjs} +4 -4
- package/dist/{join-u1DqTU3U.mjs → join-BRow9_3-.mjs} +3 -3
- package/dist/{join-CaFx5yoF.mjs → join-d-pqyf8e.mjs} +3 -3
- package/dist/{key-BiEp995L.mjs → key-CTL_AXOh.mjs} +24 -8
- package/dist/{key-KcUU3yhJ.mjs → key-D_66hrWW.mjs} +3 -3
- package/dist/{local-test-C3HGjGY3.mjs → local-test-BZHGo22F.mjs} +1 -1
- package/dist/{models-dev-2UfQoIpQ.mjs → models-dev-CDEyd2k3.mjs} +21 -1
- package/dist/{mux-CS1zhF4W.mjs → mux-BaIDugDq.mjs} +2 -2
- package/dist/{ports-BRXd5UXh.mjs → ports-TQ4tWmiJ.mjs} +2 -2
- package/dist/{presets-C73CAMZ6.mjs → presets-DleOUQiT.mjs} +2 -2
- package/dist/{revoke-CkpvK33Q.mjs → revoke-DTFW_EF1.mjs} +2 -2
- package/dist/{rewrite-xZHWnyJk.mjs → rewrite-CEzfYH9n.mjs} +45 -26
- package/dist/{route-test-Oew0CO1U.mjs → route-test-D2LQyX7c.mjs} +4 -4
- package/dist/{rpc-contract-5qyWzT5t.mjs → rpc-contract-cB5SuyQ_.mjs} +64 -9
- package/dist/{run-3pdPsD8e.mjs → run-D8kgXdId.mjs} +3 -3
- package/dist/{runtime-DNs9GtGp.mjs → runtime-C_pLA5F0.mjs} +3 -3
- package/dist/{secret-COdVHzjH.mjs → secret-P2RgHy2h.mjs} +2 -2
- package/dist/{secrets-BYI6ooTJ.mjs → secrets-1Hmddmwy.mjs} +2 -2
- package/dist/secrets-C9IYp93v.mjs +2 -0
- package/dist/{serve-DSBlodTF.mjs → serve-B51lmr9M.mjs} +2 -2
- package/dist/{serve-Be4zdKVj.mjs → serve-CY7ZFOFM.mjs} +6 -6
- package/dist/{service-B5uORhl3.mjs → service-D6TNolyh.mjs} +36 -9
- package/dist/{settings-DU0YqNDt.mjs → settings-Rq1zLoxY.mjs} +1 -1
- package/dist/{settings-C1Hb4zwd.mjs → settings-XCvAzDK8.mjs} +2 -2
- package/dist/{share-Cug0944N.mjs → share-DdtbAylA.mjs} +28 -13
- package/dist/{status-SkNsxGnk.mjs → status-DSVQ3YHm.mjs} +3 -3
- package/dist/{status-Bttb9aPj.mjs → status-uE2-kOyK.mjs} +3 -3
- package/dist/{store-CQShpYar.mjs → store-DOFDy1rY.mjs} +2 -2
- package/dist/{store-CrTUwskE.mjs → store-EGzVd-dn.mjs} +29 -4
- package/dist/{test-mlaZC1y5.mjs → test-DW4BF7xJ.mjs} +2 -2
- package/hooks/codex.cjs +12 -0
- package/hooks/env.cjs +10 -0
- package/hooks/file.cjs +27 -0
- package/hooks/secret.cjs +11 -0
- package/package.json +6 -2
- package/resources/app-icons/app-icon.icns +0 -0
- package/resources/app-icons/app-icon.ico +0 -0
- package/resources/app-icons/app-icon.json +84 -0
- package/resources/app-icons/app-icon.png +0 -0
- package/resources/app-icons/linux/128x128/app-icon.png +0 -0
- package/resources/app-icons/linux/16x16/app-icon.png +0 -0
- package/resources/app-icons/linux/256x256/app-icon.png +0 -0
- package/resources/app-icons/linux/32x32/app-icon.png +0 -0
- package/resources/app-icons/linux/48x48/app-icon.png +0 -0
- package/resources/app-icons/linux/512x512/app-icon.png +0 -0
- package/resources/app-icons/linux/64x64/app-icon.png +0 -0
- package/resources/app-icons/tray-icon.png +0 -0
- package/webui/dist/assets/index-8MLhHHM0.js +74 -0
- package/webui/dist/assets/index-ihWSPzNq.css +2 -0
- package/webui/dist/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/webui/dist/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/webui/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/webui/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/webui/dist/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/webui/dist/assets/share-tech-mono-latin-400-normal-15MgdvEM.woff +0 -0
- package/webui/dist/assets/share-tech-mono-latin-400-normal-CCqdbj5z.woff2 +0 -0
- package/webui/dist/icons/presets/anthropic.svg +5 -0
- package/webui/dist/icons/presets/codex.svg +5 -0
- package/webui/dist/icons/presets/deepseek.svg +5 -0
- package/webui/dist/icons/presets/openai.svg +5 -0
- package/webui/dist/index.html +13 -0
- package/dist/secrets-u19-8EyW.mjs +0 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as UsageError, r as reportCliError } from "./errors-BGtxPkM7.mjs";
|
|
2
2
|
import { n as parseArgv } from "./args-CSxXW9eD.mjs";
|
|
3
|
-
import { t as loadSettings } from "./settings-
|
|
4
|
-
import { n as loadCuratedPresets, r as modelsDevCachePath, t as fetchModelsDevPresets } from "./models-dev-
|
|
3
|
+
import { t as loadSettings } from "./settings-XCvAzDK8.mjs";
|
|
4
|
+
import { n as loadCuratedPresets, r as modelsDevCachePath, t as fetchModelsDevPresets } from "./models-dev-CDEyd2k3.mjs";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
//#region src/cli/commands/provider/presets.ts
|
|
7
7
|
const SPEC = { json: { type: "boolean" } };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as UsageError, r as reportCliError } from "./errors-BGtxPkM7.mjs";
|
|
2
2
|
import { n as parseArgv } from "./args-CSxXW9eD.mjs";
|
|
3
3
|
import { t as resolveHttpProxy } from "./proxy-D7VMUVEg.mjs";
|
|
4
|
-
import { d as str, l as resolveDataDir, u as resolvedRelayUrls } from "./common-
|
|
5
|
-
import { t as openExistingFabric } from "./serve-
|
|
4
|
+
import { d as str, l as resolveDataDir, u as resolvedRelayUrls } from "./common-C51SAE5f.mjs";
|
|
5
|
+
import { t as openExistingFabric } from "./serve-CY7ZFOFM.mjs";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
7
|
//#region src/cli/commands/provider/revoke.ts
|
|
8
8
|
const SPEC = {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { a as routeLocalPrefix } from "./rpc-contract-
|
|
2
|
-
import { n as FORBIDDEN_REQ_HEADER_NAMES } from "./frames-
|
|
3
|
-
import { a as parseUpstreamUrl, c as matchRequestPath, o as expandUriTemplate, s as compileMatchPattern } from "./store-
|
|
1
|
+
import { a as routeLocalPrefix } from "./rpc-contract-cB5SuyQ_.mjs";
|
|
2
|
+
import { n as FORBIDDEN_REQ_HEADER_NAMES } from "./frames-BDz8buix.mjs";
|
|
3
|
+
import { a as parseUpstreamUrl, c as matchRequestPath, o as expandUriTemplate, s as compileMatchPattern } from "./store-EGzVd-dn.mjs";
|
|
4
|
+
import { o as resolveHookValue } from "./hook-CvAMGts4.mjs";
|
|
5
|
+
import "node:module";
|
|
6
|
+
import "node:fs";
|
|
4
7
|
const ENV_REF_PREFIX = "$env:";
|
|
5
8
|
/** $secret 引用前缀(密钥库名;与 $env 同样按引用整体掩码)。 */
|
|
6
9
|
const SECRET_REF_PREFIX = "$secret:";
|
|
@@ -32,7 +35,7 @@ function buildServiceDetail(service) {
|
|
|
32
35
|
if (prefix !== void 0) rewrite.prefix = prefix;
|
|
33
36
|
if (service.rewrite.headerSet !== void 0) rewrite.headerSet = Object.entries(service.rewrite.headerSet).map(([name, value]) => ({
|
|
34
37
|
name,
|
|
35
|
-
value: isMaskedRef(value) ? "●" : value
|
|
38
|
+
value: typeof value === "string" ? isMaskedRef(value) ? "●" : value : "●"
|
|
36
39
|
}));
|
|
37
40
|
}
|
|
38
41
|
return {
|
|
@@ -121,33 +124,45 @@ var SecretMissingError = class extends Error {
|
|
|
121
124
|
}
|
|
122
125
|
};
|
|
123
126
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
127
|
+
* 头值解析(两协议,Owner 裁决 2026-09-12 最终形态):
|
|
128
|
+
* - string 字面量:原样(空串 = 省略该头)
|
|
129
|
+
* - 对象 = 钩子调用:{ hook: <函数名>, args?, bearer? }——脚本取
|
|
130
|
+
* ctx.script(service.hooks),缺席时按 args 形态推导内建
|
|
131
|
+
* (var→env / name→secret / path→file);经 resolveHookValue 三态取值
|
|
132
|
+
* (string/Promise 每请求拉取;AsyncIterable 订阅 latest);bearer 拼
|
|
133
|
+
* 前缀。未命中抛 SecretMissingError(零上游请求;不泄脚本路径与值)。
|
|
128
134
|
*/
|
|
129
|
-
function
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
async function resolveHeaderEntry(entry, ctx) {
|
|
136
|
+
if (typeof entry === "string") return entry === "" ? void 0 : entry;
|
|
137
|
+
const args = entry.args ?? {};
|
|
138
|
+
let script = ctx.script;
|
|
139
|
+
if (script === void 0 || script === "") {
|
|
140
|
+
if (args.var !== void 0) script = "env";
|
|
141
|
+
else if (args.name !== void 0) script = "secret";
|
|
142
|
+
else if (args.path !== void 0) script = "file";
|
|
143
|
+
else throw new SecretMissingError();
|
|
135
144
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
let raw;
|
|
146
|
+
try {
|
|
147
|
+
raw = await resolveHookValue(entry.hook, {
|
|
148
|
+
script,
|
|
149
|
+
...ctx.home !== void 0 ? { home: ctx.home } : {},
|
|
150
|
+
...Object.keys(args).length > 0 ? { args } : {},
|
|
151
|
+
...ctx.secrets !== void 0 ? { secrets: ctx.secrets } : {},
|
|
152
|
+
...ctx.env !== void 0 ? { env: (n) => ctx.env?.[n] } : {},
|
|
153
|
+
...ctx.loader !== void 0 ? { loader: ctx.loader } : {}
|
|
154
|
+
});
|
|
155
|
+
} catch {
|
|
156
|
+
throw new SecretMissingError();
|
|
157
|
+
}
|
|
158
|
+
return entry.bearer === true ? `Bearer ${raw}` : raw;
|
|
141
159
|
}
|
|
142
|
-
/**
|
|
160
|
+
/** 服务声明的 env 钩子变量名(启动横幅 WARNING 用:声明而未设置)。 */
|
|
143
161
|
function collectEnvVarNames(service) {
|
|
144
162
|
const names = /* @__PURE__ */ new Set();
|
|
145
163
|
const headerSet = service.rewrite?.headerSet;
|
|
146
164
|
if (headerSet === void 0) return [];
|
|
147
|
-
for (const
|
|
148
|
-
const name = value.slice(5);
|
|
149
|
-
if (name !== "") names.add(name);
|
|
150
|
-
}
|
|
165
|
+
for (const entry of Object.values(headerSet)) if (typeof entry === "object" && entry.args?.var !== void 0 && (service.hooks === void 0 || service.hooks === "env")) names.add(entry.args.var);
|
|
151
166
|
return [...names];
|
|
152
167
|
}
|
|
153
168
|
/** HTTP hop-by-hop / 传输层自管头(普通 HTTP 转发路径剥离;WS 路径另行挑选)。 */
|
|
@@ -226,7 +241,7 @@ function isWebSocketUpgradeRequest(headers) {
|
|
|
226
241
|
if (connection === void 0 || upgrade === void 0) return false;
|
|
227
242
|
return connection.split(",").map((t) => t.trim().toLowerCase()).includes("upgrade") && upgrade.trim().toLowerCase() === "websocket";
|
|
228
243
|
}
|
|
229
|
-
function buildUpstreamRequest(service, req, env = process.env, secrets) {
|
|
244
|
+
async function buildUpstreamRequest(service, req, env = process.env, secrets) {
|
|
230
245
|
const upstream = parseUpstreamUrl(service.upstream);
|
|
231
246
|
assertFramePathShape(req.path);
|
|
232
247
|
const split = splitQuery(req.path);
|
|
@@ -290,7 +305,11 @@ function buildUpstreamRequest(service, req, env = process.env, secrets) {
|
|
|
290
305
|
for (const name of service.rewrite?.headerRemove ?? []) delete headers[name];
|
|
291
306
|
const headerSet = service.rewrite?.headerSet;
|
|
292
307
|
if (headerSet !== void 0) for (const [name, value] of Object.entries(headerSet)) {
|
|
293
|
-
const resolved =
|
|
308
|
+
const resolved = await resolveHeaderEntry(value, {
|
|
309
|
+
script: service.hooks,
|
|
310
|
+
env,
|
|
311
|
+
secrets
|
|
312
|
+
});
|
|
294
313
|
if (resolved === void 0) continue;
|
|
295
314
|
headers[name] = resolved;
|
|
296
315
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as ROUTE_LOCAL_PREFIX } from "./rpc-contract-
|
|
2
|
-
import { t as formProbe } from "./local-test-
|
|
3
|
-
import { i as buildUpstreamRequest, t as PathNotOfferedError } from "./rewrite-
|
|
1
|
+
import { n as ROUTE_LOCAL_PREFIX } from "./rpc-contract-cB5SuyQ_.mjs";
|
|
2
|
+
import { t as formProbe } from "./local-test-BZHGo22F.mjs";
|
|
3
|
+
import { i as buildUpstreamRequest, t as PathNotOfferedError } from "./rewrite-CEzfYH9n.mjs";
|
|
4
4
|
//#region src/provider/route-test.ts
|
|
5
5
|
const DEFAULT_TIMEOUT_MS = 2e4;
|
|
6
6
|
const BODY_EXCERPT_MAX = 2e3;
|
|
@@ -25,7 +25,7 @@ async function testServiceRoute(input) {
|
|
|
25
25
|
bodyLen: 0
|
|
26
26
|
};
|
|
27
27
|
try {
|
|
28
|
-
const plan = buildUpstreamRequest(input.service, req, input.env, input.secrets);
|
|
28
|
+
const plan = await buildUpstreamRequest(input.service, req, input.env, input.secrets);
|
|
29
29
|
const response = await fetchImpl(plan.url, {
|
|
30
30
|
method: "POST",
|
|
31
31
|
headers: plan.headers,
|
|
@@ -95,7 +95,11 @@ const SERVICE_REWRITE_SCHEMA = z.strictObject({
|
|
|
95
95
|
hostHeader: z.string().min(1).max(2048).optional(),
|
|
96
96
|
pathPrefixStrip: z.string().min(1).max(2048).optional(),
|
|
97
97
|
pathPrefixAppend: z.string().min(1).max(2048).optional(),
|
|
98
|
-
headerSet: z.record(z.string().min(1).max(1024), z.string().max(8192)
|
|
98
|
+
headerSet: z.record(z.string().min(1).max(1024), z.union([z.string().max(8192), z.strictObject({
|
|
99
|
+
hook: z.string().min(1).max(128),
|
|
100
|
+
args: z.record(z.string().min(1).max(128), z.string().max(2048)).optional(),
|
|
101
|
+
bearer: z.boolean().optional()
|
|
102
|
+
})])).optional(),
|
|
99
103
|
headerRemove: z.array(z.string().min(1).max(1024)).max(32).optional()
|
|
100
104
|
});
|
|
101
105
|
const ROUTE_FORM_SCHEMA = z.enum([
|
|
@@ -143,6 +147,7 @@ const SERVICE_SCHEMA = z.strictObject({
|
|
|
143
147
|
upstream: z.string().min(1).max(2048),
|
|
144
148
|
rewrite: SERVICE_REWRITE_SCHEMA.optional(),
|
|
145
149
|
routes: z.array(SERVICE_ROUTE_SCHEMA).max(3).optional(),
|
|
150
|
+
hooks: z.string().regex(/^[a-z][a-z0-9_-]{0,63}$/).optional(),
|
|
146
151
|
defaultPort: z.number().int().min(1).max(65535)
|
|
147
152
|
});
|
|
148
153
|
/** services.add 输入(defaultPort 缺省规则的校验在 store,同 CLI)。 */
|
|
@@ -152,7 +157,8 @@ const SERVICE_INPUT_SCHEMA = z.strictObject({
|
|
|
152
157
|
match: z.array(SERVICE_MATCH_SCHEMA).min(1).max(64),
|
|
153
158
|
defaultPort: z.number().int().min(1).max(65535).optional(),
|
|
154
159
|
rewrite: SERVICE_REWRITE_SCHEMA.optional(),
|
|
155
|
-
routes: z.array(SERVICE_ROUTE_SCHEMA).max(3).optional()
|
|
160
|
+
routes: z.array(SERVICE_ROUTE_SCHEMA).max(3).optional(),
|
|
161
|
+
hooks: z.string().regex(/^[a-z][a-z0-9_-]{0,63}$/).optional()
|
|
156
162
|
});
|
|
157
163
|
const GROUP_LIMITS_SCHEMA = z.strictObject({
|
|
158
164
|
maxConcurrency: z.number().int().min(1).optional(),
|
|
@@ -163,12 +169,15 @@ const GROUP_SCHEMA = z.strictObject({
|
|
|
163
169
|
serviceIds: z.array(z.string().min(1).max(128)).max(256),
|
|
164
170
|
limits: GROUP_LIMITS_SCHEMA.optional()
|
|
165
171
|
});
|
|
166
|
-
/** 密钥视图:keyId
|
|
172
|
+
/** 密钥视图:keyId/分组/时间/状态 + 名 + 原文(Owner 2026-09-13:随时可
|
|
173
|
+
* 复制——原文随库返回;旧记录只存哈希 → 两字段皆缺省)。 */
|
|
167
174
|
const KEY_VIEW_SCHEMA = z.strictObject({
|
|
168
175
|
keyId: z.string().min(1).max(128),
|
|
169
176
|
group: z.string().min(1).max(256),
|
|
170
177
|
createdAt: z.number().int().min(0),
|
|
171
|
-
revokedAt: z.number().int().min(0).optional()
|
|
178
|
+
revokedAt: z.number().int().min(0).optional(),
|
|
179
|
+
name: z.string().min(1).max(128).optional(),
|
|
180
|
+
key: z.string().min(8).max(256).optional()
|
|
172
181
|
});
|
|
173
182
|
/** 使用方服务目录条目(AUTH_OK / import 视图;detail 为脱敏披露,$env 值显示 ●)。 */
|
|
174
183
|
const SERVICE_ENTRY_SCHEMA = z.object({
|
|
@@ -190,7 +199,11 @@ const SERVICE_ENTRY_SCHEMA = z.object({
|
|
|
190
199
|
prefix: z.string().optional(),
|
|
191
200
|
headerSet: z.array(z.strictObject({
|
|
192
201
|
name: z.string(),
|
|
193
|
-
value: z.string()
|
|
202
|
+
value: z.union([z.string(), z.strictObject({
|
|
203
|
+
hook: z.string(),
|
|
204
|
+
args: z.record(z.string(), z.string()).optional(),
|
|
205
|
+
bearer: z.boolean().optional()
|
|
206
|
+
})])
|
|
194
207
|
})).optional()
|
|
195
208
|
}).optional(),
|
|
196
209
|
/** 按标准路由披露(消费侧呈现各标准本地 base 与可用性判定)。 */
|
|
@@ -228,6 +241,7 @@ const CONSUMER_PROVIDER_STATUS_SCHEMA = z.object({
|
|
|
228
241
|
});
|
|
229
242
|
const API_FORM_SCHEMA = z.enum([
|
|
230
243
|
"openai-completions",
|
|
244
|
+
"openai-responses",
|
|
231
245
|
"anthropic-messages",
|
|
232
246
|
"gemini-native"
|
|
233
247
|
]);
|
|
@@ -240,6 +254,14 @@ const PRESET_SCHEMA = z.strictObject({
|
|
|
240
254
|
iconId: z.string().min(1).max(128).optional(),
|
|
241
255
|
/** 惯用环境变量名(仅用于 $env 注入建议与文档;本地运行时模板无此字段)。 */
|
|
242
256
|
keyEnv: z.string().min(1).max(256).optional(),
|
|
257
|
+
/** 选中的 hooks 脚本名(applyAsService 透传为服务 hooks 字段)。 */
|
|
258
|
+
hooks: z.string().regex(/^[a-z][a-z0-9_-]{0,63}$/).optional(),
|
|
259
|
+
/** 预填 authorization 头的钩子调用对象;优先级:显式 secretName > authHeader > keyEnv。 */
|
|
260
|
+
authHeader: z.strictObject({
|
|
261
|
+
hook: z.string().min(1).max(128),
|
|
262
|
+
args: z.record(z.string().min(1).max(128), z.string().max(2048)).optional(),
|
|
263
|
+
bearer: z.boolean().optional()
|
|
264
|
+
}).optional(),
|
|
243
265
|
/** 使用方本地端口建议(避开 <1024 特权段)。 */
|
|
244
266
|
defaultPort: z.number().int().min(1024).max(65535),
|
|
245
267
|
/** 官方域名集(exact/suffix 建议的生成源)。 */
|
|
@@ -317,7 +339,11 @@ const SETTINGS_SCHEMA = z.strictObject({
|
|
|
317
339
|
const SHARE_CREATE_INPUT_SCHEMA = z.strictObject({
|
|
318
340
|
group: z.string().min(1).max(256),
|
|
319
341
|
/** TTL 毫秒(1s..30d;缺省 60min——范围校验复用 link.ts 常量语义)。 */
|
|
320
|
-
ttlMs: z.number().int().min(1e3).max(2592e6).optional()
|
|
342
|
+
ttlMs: z.number().int().min(1e3).max(2592e6).optional(),
|
|
343
|
+
/** 复用既有 key(现铸 invite 重发链接;缺省签发新钥)。 */
|
|
344
|
+
keyId: z.string().min(1).max(128).optional(),
|
|
345
|
+
/** 新钥名(缺省签发路径下默认 "default")。 */
|
|
346
|
+
keyName: z.string().min(1).max(128).optional()
|
|
321
347
|
});
|
|
322
348
|
const PRESET_APPLY_INPUT_SCHEMA = z.strictObject({
|
|
323
349
|
presetId: z.string().min(1).max(128),
|
|
@@ -393,6 +419,32 @@ oc.errors(RpcErrorDefinitions).router({
|
|
|
393
419
|
localPrefix: z.string().min(1).max(2048).optional()
|
|
394
420
|
})).output(SERVICE_TEST_RESULT_SCHEMA)
|
|
395
421
|
},
|
|
422
|
+
hooks: {
|
|
423
|
+
/** hooks 脚本清单(内建 + 用户库;fns = 命名规范发现的钩子函数)。 */
|
|
424
|
+
list: oc.input(z.object({})).output(z.object({ hooks: z.array(z.strictObject({
|
|
425
|
+
name: z.string(),
|
|
426
|
+
source: z.enum(["user", "builtin"]),
|
|
427
|
+
fns: z.array(z.string())
|
|
428
|
+
})) })),
|
|
429
|
+
/** 脚本内容查看(含 path)。 */
|
|
430
|
+
get: oc.input(z.strictObject({ name: z.string().min(1).max(64) })).output(z.strictObject({
|
|
431
|
+
name: z.string(),
|
|
432
|
+
source: z.enum(["user", "builtin"]),
|
|
433
|
+
path: z.string(),
|
|
434
|
+
content: z.string()
|
|
435
|
+
})),
|
|
436
|
+
/** 安装用户脚本(校验:可加载 + 至少一个导出函数;失败回滚)。 */
|
|
437
|
+
add: oc.input(z.strictObject({
|
|
438
|
+
name: z.string().min(1).max(64),
|
|
439
|
+
content: z.string().min(1).max(65536)
|
|
440
|
+
})).output(z.strictObject({
|
|
441
|
+
name: z.string(),
|
|
442
|
+
path: z.string(),
|
|
443
|
+
fns: z.array(z.string())
|
|
444
|
+
})),
|
|
445
|
+
/** 删除(仅用户库;内建拒绝)。 */
|
|
446
|
+
remove: oc.input(z.strictObject({ name: z.string().min(1).max(64) })).output(z.object({ removed: z.boolean() }))
|
|
447
|
+
},
|
|
396
448
|
secrets: {
|
|
397
449
|
/** 密钥库清单(仅名称与时间戳;值由设计不跨 RPC)。 */
|
|
398
450
|
list: oc.input(z.object({})).output(z.object({ secrets: z.array(SECRET_ENTRY_SCHEMA) })),
|
|
@@ -429,13 +481,16 @@ oc.errors(RpcErrorDefinitions).router({
|
|
|
429
481
|
remove: oc.input(z.strictObject({ name: z.string().min(1).max(256) })).output(z.object({ removed: z.literal(true) }))
|
|
430
482
|
},
|
|
431
483
|
keys: {
|
|
432
|
-
/**
|
|
433
|
-
issue: oc.input(z.strictObject({
|
|
484
|
+
/** 签发(name 缺省 "default";原文随库可再取)。 */
|
|
485
|
+
issue: oc.input(z.strictObject({
|
|
486
|
+
group: z.string().min(1).max(256),
|
|
487
|
+
name: z.string().min(1).max(128).optional()
|
|
488
|
+
})).output(z.object({
|
|
434
489
|
keyId: z.string(),
|
|
435
490
|
key: z.string(),
|
|
436
491
|
createdAt: z.number().int()
|
|
437
492
|
})),
|
|
438
|
-
/**
|
|
493
|
+
/** 密钥清单(含名与原文——本机 GUI 随时复制;无哈希)。 */
|
|
439
494
|
list: oc.input(z.object({})).output(z.object({ keys: z.array(KEY_VIEW_SCHEMA) })),
|
|
440
495
|
/** 撤销(幂等)。 */
|
|
441
496
|
revoke: oc.input(z.strictObject({ keyId: z.string().min(1).max(128) })).output(z.object({ key: KEY_VIEW_SCHEMA }))
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as UsageError, r as reportCliError, t as CliError } from "./errors-BGtxPkM7.mjs";
|
|
2
2
|
import { n as parseArgv } from "./args-CSxXW9eD.mjs";
|
|
3
|
-
import { n as consumersRoot, s as listKeyrings } from "./store-
|
|
4
|
-
import { a as ringsForRun, i as printListeners, n as ctxHomedir, o as waitForSignals, r as ctxOut, t as createSdkFabricFactory } from "./common-
|
|
5
|
-
import { n as createFabricProviderTransport, t as startEngine } from "./runtime-
|
|
3
|
+
import { n as consumersRoot, s as listKeyrings } from "./store-DOFDy1rY.mjs";
|
|
4
|
+
import { a as ringsForRun, i as printListeners, n as ctxHomedir, o as waitForSignals, r as ctxOut, t as createSdkFabricFactory } from "./common-CanLn0Qt.mjs";
|
|
5
|
+
import { n as createFabricProviderTransport, t as startEngine } from "./runtime-C_pLA5F0.mjs";
|
|
6
6
|
import { a as killHard, c as terminateGracefully, i as isAlive, l as writeLastStart, n as daemonDir, o as readLastStart, r as ensureDaemonDir, s as readPid, t as clearPid, u as writePid } from "./daemon-state-CYkiW3SA.mjs";
|
|
7
7
|
import { openSync, readFileSync } from "node:fs";
|
|
8
8
|
import { resolve } from "node:path";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as FRAME_TYPE, o as HTTP_METHODS } from "./frames-
|
|
2
|
-
import { c as loadKeyring, f as saveKeyring, p as setActualPorts, t as applyCatalog, u as reconcileKeyMetadata } from "./store-
|
|
3
|
-
import { i as splitBody, n as FabricWireAdapter, t as WireSession } from "./mux-
|
|
1
|
+
import { i as FRAME_TYPE, o as HTTP_METHODS } from "./frames-BDz8buix.mjs";
|
|
2
|
+
import { c as loadKeyring, f as saveKeyring, p as setActualPorts, t as applyCatalog, u as reconcileKeyMetadata } from "./store-DOFDy1rY.mjs";
|
|
3
|
+
import { i as splitBody, n as FabricWireAdapter, t as WireSession } from "./mux-BaIDugDq.mjs";
|
|
4
4
|
import { n as desiredPortFor, r as listenWithFallback, t as LOOPBACK_HOST } from "./ports-pI59MtmI.mjs";
|
|
5
5
|
import { Hono } from "hono";
|
|
6
6
|
import { createAdaptorServer } from "@hono/node-server";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as UsageError, r as reportCliError } from "./errors-BGtxPkM7.mjs";
|
|
2
2
|
import { n as parseArgv } from "./args-CSxXW9eD.mjs";
|
|
3
|
-
import { d as str, l as resolveDataDir } from "./common-
|
|
4
|
-
import { t as SecretsStore } from "./secrets-
|
|
3
|
+
import { d as str, l as resolveDataDir } from "./common-C51SAE5f.mjs";
|
|
4
|
+
import { t as SecretsStore } from "./secrets-1Hmddmwy.mjs";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
import process from "node:process";
|
|
7
7
|
import { createInterface } from "node:readline";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as SECRET_NAME_SCHEMA } from "./rpc-contract-
|
|
2
|
-
import { i as ensurePrivateDir, n as StoreError, r as atomicWriteFileSync } from "./store-
|
|
1
|
+
import { r as SECRET_NAME_SCHEMA } from "./rpc-contract-cB5SuyQ_.mjs";
|
|
2
|
+
import { i as ensurePrivateDir, n as StoreError, r as atomicWriteFileSync } from "./store-EGzVd-dn.mjs";
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { z } from "zod";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as UsageError, r as reportCliError } from "./errors-BGtxPkM7.mjs";
|
|
2
2
|
import { n as parseArgv } from "./args-CSxXW9eD.mjs";
|
|
3
3
|
import { t as resolveHttpProxy } from "./proxy-D7VMUVEg.mjs";
|
|
4
|
-
import { d as str, l as resolveDataDir, u as resolvedRelayUrls } from "./common-
|
|
5
|
-
import { n as startProviderDaemon } from "./serve-
|
|
4
|
+
import { d as str, l as resolveDataDir, u as resolvedRelayUrls } from "./common-C51SAE5f.mjs";
|
|
5
|
+
import { n as startProviderDaemon } from "./serve-CY7ZFOFM.mjs";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
7
|
//#region src/cli/commands/provider/serve.ts
|
|
8
8
|
const SPEC = {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { c as RESP_META_HEADER_WHITELIST, i as FRAME_TYPE, s as REJECTED_CODE, t as ERROR_CODE } from "./frames-
|
|
1
|
+
import { c as RESP_META_HEADER_WHITELIST, i as FRAME_TYPE, s as REJECTED_CODE, t as ERROR_CODE } from "./frames-BDz8buix.mjs";
|
|
2
2
|
import { n as loadSdk } from "./proxy-D7VMUVEg.mjs";
|
|
3
|
-
import { i as ensurePrivateDir, r as atomicWriteFileSync, t as ProviderStore } from "./store-
|
|
4
|
-
import { n as FabricWireAdapter, r as DEFAULT_BODY_CHUNK_BYTES, t as WireSession } from "./mux-
|
|
5
|
-
import {
|
|
6
|
-
import { t as
|
|
3
|
+
import { i as ensurePrivateDir, r as atomicWriteFileSync, t as ProviderStore } from "./store-EGzVd-dn.mjs";
|
|
4
|
+
import { n as FabricWireAdapter, r as DEFAULT_BODY_CHUNK_BYTES, t as WireSession } from "./mux-BaIDugDq.mjs";
|
|
5
|
+
import { t as SecretsStore } from "./secrets-1Hmddmwy.mjs";
|
|
6
|
+
import { a as collectEnvVarNames, i as buildUpstreamRequest, n as RewriteError, r as SecretMissingError, s as buildServiceEntry, t as PathNotOfferedError } from "./rewrite-CEzfYH9n.mjs";
|
|
7
7
|
import { appendFileSync, existsSync, readFileSync, readdirSync, watch } from "node:fs";
|
|
8
8
|
import "node:os";
|
|
9
9
|
import { dirname, join } from "node:path";
|
|
@@ -533,7 +533,7 @@ function mergeTimeouts(overrides) {
|
|
|
533
533
|
async function forwardRequest(ctx) {
|
|
534
534
|
let plan;
|
|
535
535
|
try {
|
|
536
|
-
plan = buildUpstreamRequest(ctx.service, ctx.req, ctx.env ?? process.env, ctx.secrets);
|
|
536
|
+
plan = await buildUpstreamRequest(ctx.service, ctx.req, ctx.env ?? process.env, ctx.secrets);
|
|
537
537
|
} catch (err) {
|
|
538
538
|
const code = err instanceof SecretMissingError ? ERROR_CODE.secret_missing : err instanceof PathNotOfferedError ? ERROR_CODE.path_not_offered : ERROR_CODE.protocol_error;
|
|
539
539
|
const message = err instanceof RewriteError || err instanceof SecretMissingError || err instanceof PathNotOfferedError ? err.message : "request rewrite failed";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as UsageError, r as reportCliError } from "./errors-BGtxPkM7.mjs";
|
|
2
2
|
import { n as parseArgv } from "./args-CSxXW9eD.mjs";
|
|
3
|
-
import { a as parseMatchSpec, d as str, i as parseHeaderSetSpec, l as resolveDataDir, n as multi, o as parsePortNumber, r as openStore, t as buildRewrite } from "./common-
|
|
4
|
-
import { n as loadCuratedPresets } from "./models-dev-
|
|
3
|
+
import { a as parseMatchSpec, d as str, i as parseHeaderSetSpec, l as resolveDataDir, n as multi, o as parsePortNumber, r as openStore, t as buildRewrite } from "./common-C51SAE5f.mjs";
|
|
4
|
+
import { n as loadCuratedPresets } from "./models-dev-CDEyd2k3.mjs";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
//#region src/cli/commands/provider/service.ts
|
|
7
7
|
const SPEC = {
|
|
@@ -20,6 +20,7 @@ const SPEC = {
|
|
|
20
20
|
route: { type: "multi" },
|
|
21
21
|
"route-pattern": { type: "multi" },
|
|
22
22
|
secret: { type: "string" },
|
|
23
|
+
hooks: { type: "string" },
|
|
23
24
|
preset: { type: "string" },
|
|
24
25
|
form: { type: "string" },
|
|
25
26
|
content: { type: "string" },
|
|
@@ -70,10 +71,18 @@ function add(options, positionals, home) {
|
|
|
70
71
|
...multi(options["route-pattern"]).map(parseRoutePatternSpec),
|
|
71
72
|
...preset !== void 0 && options.route === void 0 && options["route-pattern"] === void 0 ? preset.routes ?? [] : []
|
|
72
73
|
];
|
|
74
|
+
const hooksOverride = options.hooks !== void 0 ? str(options.hooks) : options.secret !== void 0 ? "secret" : preset?.hooks;
|
|
73
75
|
const headerSetSpecs = multi(options["header-set"]).map(parseHeaderSetSpec);
|
|
74
76
|
if (options.secret !== void 0) headerSetSpecs.push({
|
|
75
77
|
name: "authorization",
|
|
76
|
-
value:
|
|
78
|
+
value: {
|
|
79
|
+
hook: "authHeader",
|
|
80
|
+
args: { name: str(options.secret) }
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
else if (preset?.authHeader !== void 0 && !headerSetSpecs.some((h) => h.name.toLowerCase() === "authorization")) headerSetSpecs.push({
|
|
84
|
+
name: "authorization",
|
|
85
|
+
value: preset.authHeader
|
|
77
86
|
});
|
|
78
87
|
const dataDir = resolveDataDir(str(options.data), home);
|
|
79
88
|
const service = openStore(dataDir).addService({
|
|
@@ -82,6 +91,7 @@ function add(options, positionals, home) {
|
|
|
82
91
|
match: matchSpecs,
|
|
83
92
|
...routes.length > 0 ? { routes } : {},
|
|
84
93
|
defaultPort: options.port === void 0 ? preset?.defaultPort : parsePortNumber(str(options.port), "port"),
|
|
94
|
+
...hooksOverride !== void 0 ? { hooks: hooksOverride } : {},
|
|
85
95
|
rewrite: buildRewrite({
|
|
86
96
|
host: str(options.host),
|
|
87
97
|
strip: str(options.strip),
|
|
@@ -192,7 +202,8 @@ function get(options, positionals, home) {
|
|
|
192
202
|
if (service.rewrite.hostHeader !== void 0) rewrite.push(`host: ${service.rewrite.hostHeader}`);
|
|
193
203
|
if (service.rewrite.pathPrefixStrip !== void 0) rewrite.push(`strip: ${service.rewrite.pathPrefixStrip}`);
|
|
194
204
|
if (service.rewrite.pathPrefixAppend !== void 0) rewrite.push(`append: ${service.rewrite.pathPrefixAppend}`);
|
|
195
|
-
for (const [headerName, value] of Object.entries(service.rewrite.headerSet ?? {})) rewrite.push(`header ${headerName}: ${value}`);
|
|
205
|
+
for (const [headerName, value] of Object.entries(service.rewrite.headerSet ?? {})) rewrite.push(`header ${headerName}: ${humanizeHeaderValue(value)}`);
|
|
206
|
+
if (service.hooks !== void 0) rewrite.push(`hooks: ${service.hooks}`);
|
|
196
207
|
for (const headerName of service.rewrite.headerRemove ?? []) rewrite.push(`remove header ${headerName}`);
|
|
197
208
|
if (rewrite.length > 0) lines.push(` rewrite : ${rewrite.join(" | ")}`);
|
|
198
209
|
}
|
|
@@ -203,18 +214,28 @@ function get(options, positionals, home) {
|
|
|
203
214
|
async function test(options, positionals, home) {
|
|
204
215
|
const name = positionals[1];
|
|
205
216
|
if (name === void 0) throw new UsageError("error: service test requires a <name> argument");
|
|
206
|
-
const formRaw = options.form === void 0 ? "openai-chat" : str(options.form);
|
|
207
|
-
if (!ROUTE_FORMS.includes(formRaw)) throw new UsageError(`error: --form must be one of ${ROUTE_FORMS.join(", ")}`);
|
|
208
217
|
const dataDir = resolveDataDir(str(options.data), home);
|
|
209
218
|
const service = openStore(dataDir).getServiceByName(name);
|
|
210
219
|
if (service === void 0) throw new UsageError(`error: service '${name}' not found`);
|
|
211
|
-
|
|
212
|
-
|
|
220
|
+
let formRaw;
|
|
221
|
+
if (options.form !== void 0) formRaw = str(options.form);
|
|
222
|
+
else {
|
|
223
|
+
const localPrefix = options["local-prefix"] !== void 0 ? str(options["local-prefix"]) : void 0;
|
|
224
|
+
const routes = (service.routes ?? []).filter((r) => r.mode !== "pattern");
|
|
225
|
+
formRaw = (localPrefix !== void 0 ? routes.find((r) => r.localPrefix === localPrefix) : routes.length === 1 ? routes[0] : void 0)?.forms[0] ?? "openai-chat";
|
|
226
|
+
}
|
|
227
|
+
if (!ROUTE_FORMS.includes(formRaw)) throw new UsageError(`error: --form must be one of ${ROUTE_FORMS.join(", ")}`);
|
|
228
|
+
const { testServiceRoute } = await import("./route-test-D2LQyX7c.mjs");
|
|
229
|
+
const { SecretsStore } = await import("./secrets-C9IYp93v.mjs");
|
|
213
230
|
const secretsStore = SecretsStore.open(dataDir);
|
|
231
|
+
const hitLocalPrefix = options["local-prefix"] !== void 0 ? str(options["local-prefix"]) : (() => {
|
|
232
|
+
const routes = (service.routes ?? []).filter((r) => r.mode !== "pattern");
|
|
233
|
+
return routes.length === 1 ? routes[0].localPrefix : void 0;
|
|
234
|
+
})();
|
|
214
235
|
const result = await testServiceRoute({
|
|
215
236
|
service,
|
|
216
237
|
form: formRaw,
|
|
217
|
-
...
|
|
238
|
+
...hitLocalPrefix !== void 0 ? { localPrefix: hitLocalPrefix } : {},
|
|
218
239
|
...options.model !== void 0 ? { model: str(options.model) } : {},
|
|
219
240
|
...options.content !== void 0 ? { content: str(options.content) } : {},
|
|
220
241
|
secrets: (secretName) => secretsStore.resolve(secretName)?.headerValue
|
|
@@ -228,5 +249,11 @@ async function test(options, positionals, home) {
|
|
|
228
249
|
if (result.bodyExcerpt !== void 0) out(result.bodyExcerpt.slice(0, 1200));
|
|
229
250
|
return result.ok ? 0 : 1;
|
|
230
251
|
}
|
|
252
|
+
/** 头值 humanize:字面量原样;钩子调用 `hook <fn>(k=v, …)[ bearer]`。 */
|
|
253
|
+
function humanizeHeaderValue(value) {
|
|
254
|
+
if (typeof value === "string") return value;
|
|
255
|
+
const args = Object.entries(value.args ?? {}).map(([k, v]) => `${k}=${v}`).join(", ");
|
|
256
|
+
return `hook ${value.hook}${args !== "" ? ` (${args})` : ""}${value.bearer === true ? " [bearer]" : ""}`;
|
|
257
|
+
}
|
|
231
258
|
//#endregion
|
|
232
259
|
export { run };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as UsageError, r as reportCliError } from "./errors-BGtxPkM7.mjs";
|
|
2
2
|
import { n as parseArgv } from "./args-CSxXW9eD.mjs";
|
|
3
|
-
import { n as saveSettings, r as settingsPath, t as loadSettings } from "./settings-
|
|
3
|
+
import { n as saveSettings, r as settingsPath, t as loadSettings } from "./settings-XCvAzDK8.mjs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
//#region src/cli/commands/settings.ts
|
|
6
6
|
const SPEC = { default: { type: "boolean" } };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as SETTINGS_SCHEMA } from "./rpc-contract-
|
|
2
|
-
import { i as ensurePrivateDir, r as atomicWriteFileSync } from "./store-
|
|
1
|
+
import { i as SETTINGS_SCHEMA } from "./rpc-contract-cB5SuyQ_.mjs";
|
|
2
|
+
import { i as ensurePrivateDir, r as atomicWriteFileSync } from "./store-EGzVd-dn.mjs";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { join } from "node:path";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { r as reportCliError, t as CliError } from "./errors-BGtxPkM7.mjs";
|
|
2
2
|
import { n as parseArgv, r as parseDurationMs, t as assertDurationRange } from "./args-CSxXW9eD.mjs";
|
|
3
|
-
import { l as SERVICE_ENTRY_SCHEMA } from "./frames-
|
|
3
|
+
import { l as SERVICE_ENTRY_SCHEMA } from "./frames-BDz8buix.mjs";
|
|
4
4
|
import { t as resolveHttpProxy } from "./proxy-D7VMUVEg.mjs";
|
|
5
|
-
import { n as StoreError } from "./store-
|
|
6
|
-
import { c as requireString, d as str, l as resolveDataDir, r as openStore, u as resolvedRelayUrls } from "./common-
|
|
7
|
-
import { t as openExistingFabric } from "./serve-
|
|
8
|
-
import { s as buildServiceEntry } from "./rewrite-
|
|
5
|
+
import { n as StoreError } from "./store-EGzVd-dn.mjs";
|
|
6
|
+
import { c as requireString, d as str, l as resolveDataDir, r as openStore, u as resolvedRelayUrls } from "./common-C51SAE5f.mjs";
|
|
7
|
+
import { t as openExistingFabric } from "./serve-CY7ZFOFM.mjs";
|
|
8
|
+
import { s as buildServiceEntry } from "./rewrite-CEzfYH9n.mjs";
|
|
9
9
|
import { homedir } from "node:os";
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
//#region src/provider/link.ts
|
|
@@ -33,21 +33,32 @@ function encodeShareLink(payload) {
|
|
|
33
33
|
return SHARE_LINK_PREFIX + Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* 构造分享链接:前置检查(组存在且非空)->
|
|
37
|
-
*
|
|
36
|
+
* 构造分享链接:前置检查(组存在且非空)-> key(复用 keyId 指定的已存
|
|
37
|
+
* 原文;缺省签发新钥)-> 组内服务脱敏视图 -> payload + link + 警告。
|
|
38
38
|
*/
|
|
39
39
|
function buildShareLink(input) {
|
|
40
40
|
if (input.store.getGroup(input.group) === void 0) throw new StoreError("not-found", `error: group '${input.group}' not found`);
|
|
41
41
|
const services = input.store.groupServices(input.group);
|
|
42
42
|
if (services.length === 0) throw new StoreError("invalid", `error: group '${input.group}' has no services; a share link would be meaningless`);
|
|
43
|
-
|
|
43
|
+
let key;
|
|
44
|
+
let keyId;
|
|
45
|
+
if (input.keyId !== void 0) {
|
|
46
|
+
const material = input.store.getKeyMaterial(input.keyId);
|
|
47
|
+
if (material === void 0) throw new StoreError("invalid", `error: key '${input.keyId}' cannot be shared (missing, revoked, or raw material not stored)`);
|
|
48
|
+
key = material;
|
|
49
|
+
keyId = input.keyId;
|
|
50
|
+
} else {
|
|
51
|
+
const issued = input.store.issueKey(input.group, input.keyName);
|
|
52
|
+
key = issued.key;
|
|
53
|
+
keyId = issued.keyId;
|
|
54
|
+
}
|
|
44
55
|
const serviceEntries = services.map(buildServiceEntry);
|
|
45
56
|
const relayUrls = input.relayUrls === void 0 ? [] : [...input.relayUrls];
|
|
46
57
|
const payload = {
|
|
47
58
|
v: 1,
|
|
48
59
|
invite: input.invite,
|
|
49
|
-
key
|
|
50
|
-
keyId
|
|
60
|
+
key,
|
|
61
|
+
keyId,
|
|
51
62
|
provider: {
|
|
52
63
|
alias: input.alias ?? input.store.alias ?? "provider",
|
|
53
64
|
endpointId: input.endpointId,
|
|
@@ -62,7 +73,7 @@ function buildShareLink(input) {
|
|
|
62
73
|
payload,
|
|
63
74
|
link: encodeShareLink(payload),
|
|
64
75
|
warnings,
|
|
65
|
-
keyId
|
|
76
|
+
keyId
|
|
66
77
|
};
|
|
67
78
|
}
|
|
68
79
|
//#endregion
|
|
@@ -75,7 +86,9 @@ const SPEC = {
|
|
|
75
86
|
group: { type: "string" },
|
|
76
87
|
ttl: { type: "string" },
|
|
77
88
|
relay: { type: "multi" },
|
|
78
|
-
"allow-relayless": { type: "boolean" }
|
|
89
|
+
"allow-relayless": { type: "boolean" },
|
|
90
|
+
"key-id": { type: "string" },
|
|
91
|
+
"key-name": { type: "string" }
|
|
79
92
|
};
|
|
80
93
|
async function run(argv, ctx = {}) {
|
|
81
94
|
let fabric;
|
|
@@ -97,7 +110,9 @@ async function run(argv, ctx = {}) {
|
|
|
97
110
|
group,
|
|
98
111
|
invite,
|
|
99
112
|
endpointId: fabric.endpointId,
|
|
100
|
-
relayUrls: relayStatus.urls
|
|
113
|
+
relayUrls: relayStatus.urls,
|
|
114
|
+
keyId: str(options["key-id"]),
|
|
115
|
+
keyName: str(options["key-name"])
|
|
101
116
|
});
|
|
102
117
|
process.stdout.write([
|
|
103
118
|
`share link for group '${group}' (keyId ${result.keyId}, ttl ${describeTtl(ttlMs)}):`,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { r as reportCliError } from "./errors-BGtxPkM7.mjs";
|
|
2
2
|
import { n as parseArgv } from "./args-CSxXW9eD.mjs";
|
|
3
3
|
import { t as resolveHttpProxy } from "./proxy-D7VMUVEg.mjs";
|
|
4
|
-
import { d as str, l as resolveDataDir, r as openStore, u as resolvedRelayUrls } from "./common-
|
|
5
|
-
import { t as openExistingFabric } from "./serve-
|
|
6
|
-
import { c as detailDisplayLines, o as buildServiceDetail } from "./rewrite-
|
|
4
|
+
import { d as str, l as resolveDataDir, r as openStore, u as resolvedRelayUrls } from "./common-C51SAE5f.mjs";
|
|
5
|
+
import { t as openExistingFabric } from "./serve-CY7ZFOFM.mjs";
|
|
6
|
+
import { c as detailDisplayLines, o as buildServiceDetail } from "./rewrite-CEzfYH9n.mjs";
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
8
|
//#region src/cli/commands/provider/status.ts
|
|
9
9
|
const SPEC = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as parseArgv } from "./args-CSxXW9eD.mjs";
|
|
2
|
-
import { n as consumersRoot, s as listKeyrings } from "./store-
|
|
3
|
-
import { a as ringsForRun, n as ctxHomedir, r as ctxOut, t as createSdkFabricFactory } from "./common-
|
|
4
|
-
import { n as createFabricProviderTransport, t as startEngine } from "./runtime-
|
|
2
|
+
import { n as consumersRoot, s as listKeyrings } from "./store-DOFDy1rY.mjs";
|
|
3
|
+
import { a as ringsForRun, n as ctxHomedir, r as ctxOut, t as createSdkFabricFactory } from "./common-CanLn0Qt.mjs";
|
|
4
|
+
import { n as createFabricProviderTransport, t as startEngine } from "./runtime-C_pLA5F0.mjs";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
//#region src/cli/commands/consumer/status.ts
|
|
7
7
|
/** 状态显示名(spec 六态)。 */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as CliError } from "./errors-BGtxPkM7.mjs";
|
|
2
|
-
import { s as randomZ32 } from "./rpc-contract-
|
|
3
|
-
import { l as SERVICE_ENTRY_SCHEMA } from "./frames-
|
|
2
|
+
import { s as randomZ32 } from "./rpc-contract-cB5SuyQ_.mjs";
|
|
3
|
+
import { l as SERVICE_ENTRY_SCHEMA } from "./frames-BDz8buix.mjs";
|
|
4
4
|
import { chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
import { join } from "node:path";
|