t159 重打包(Arcrun@062757f):補 /portal/daemon/libraries 登記端點(portal 庫目錄空的根因)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"schema": "arcrun-rag-bundles/v1",
|
||||
"built": "2026-07-31",
|
||||
"source": "Arcrun@7e631a8",
|
||||
"source": "Arcrun@062757f",
|
||||
"core": [
|
||||
{
|
||||
"name": "arcrun-array-ops",
|
||||
@@ -503,7 +503,7 @@
|
||||
"tier": 2,
|
||||
"main_file": "tier2/cypher/index.js",
|
||||
"main_module": "index.js",
|
||||
"sha256": "68f723dfe927c8a3dc016189c9f87188f806a443ae96d0632badb2b8541f970d",
|
||||
"sha256": "73c50e8bc75f13f6f0adcf39d08892d78ceb0ccc34067d3c6533a09c3138b1e0",
|
||||
"compat_date": "2025-02-19",
|
||||
"compat_flags": [
|
||||
"nodejs_compat",
|
||||
|
||||
@@ -11628,6 +11628,22 @@ webhooksNamedRouter.post("/webhooks/named/:ns/:name/query", async (c) => {
|
||||
webhooksNamedRouter.get("/q/:ns/:name", async (c) => {
|
||||
return queryNamed(c, c.req.param("ns"), c.req.param("name"), queryStringContext(c));
|
||||
});
|
||||
webhooksNamedRouter.get("/webhooks/named/:name/definition", async (c) => {
|
||||
const apiKey = c.req.header("X-Arcrun-API-Key");
|
||||
if (!apiKey) return c.json({ error: "\u7F3A\u5C11 X-Arcrun-API-Key header" }, 401);
|
||||
const name = c.req.param("name");
|
||||
const raw2 = await c.env.WEBHOOKS.get(kvKey(apiKey, name), "text");
|
||||
if (!raw2) return c.json({ error: `\u627E\u4E0D\u5230 workflow "${name}"` }, 404);
|
||||
const rec = JSON.parse(raw2);
|
||||
return c.json({
|
||||
name: rec.name,
|
||||
description: rec.description ?? "",
|
||||
graph: rec.graph,
|
||||
config: rec.config ?? {},
|
||||
created_at: rec.created_at ?? "",
|
||||
...rec.cron_expr ? { cron_expr: rec.cron_expr } : {}
|
||||
});
|
||||
});
|
||||
webhooksNamedRouter.get("/webhooks/named", async (c) => {
|
||||
const apiKey = c.req.header("X-Arcrun-API-Key");
|
||||
if (!apiKey) {
|
||||
@@ -14024,6 +14040,58 @@ portalRouter.post(
|
||||
return c.json({ success: true, library: created.record ? toPublicLibrary(created.record) : { name } });
|
||||
})
|
||||
);
|
||||
portalRouter.post(
|
||||
"/portal/daemon/libraries",
|
||||
(c) => run(c, async () => {
|
||||
const body = await c.req.json().catch(() => null);
|
||||
const email = String(body?.email ?? "").trim().toLowerCase();
|
||||
const password = String(body?.password ?? "");
|
||||
if (!email || !password) return c.json({ error: "email \u8207 password \u5FC5\u586B" }, 400);
|
||||
const items = Array.isArray(body?.libraries) ? body.libraries : [];
|
||||
if (items.length === 0) return c.json({ success: true, registered: [], skipped: [] });
|
||||
if (await isLocked(c.env, email)) return c.json({ error: "\u767B\u5165\u5931\u6557\u6B21\u6578\u904E\u591A\uFF0C\u8ACB\u7A0D\u5F8C\u518D\u8A66" }, 429);
|
||||
const recordId = await findUserRecordId(c.env, email);
|
||||
const rec = recordId ? await getRecordById(c.env, recordId) : null;
|
||||
if (!rec || (rec.values.status ?? "") !== "active" || !await verifyPassword(password, rec.values.password_hash ?? "")) {
|
||||
await recordLoginFail(c.env, email);
|
||||
return c.json({ error: "email \u6216\u5BC6\u78BC\u932F\u8AA4" }, 401);
|
||||
}
|
||||
await clearLoginFail(c.env, email);
|
||||
const seeded = await ensurePortalTemplates(c.env);
|
||||
if (seeded.errors.length > 0) {
|
||||
return c.json({ error: `portal templates seed \u5931\u6557\uFF1A${seeded.errors.join("; ")}` }, 502);
|
||||
}
|
||||
const existing = await listRecordsByTemplate(c.env, LIBRARY_TEMPLATE);
|
||||
const have = new Set(existing.map((l) => l.values.name ?? ""));
|
||||
const ns = portalNamespace(c.env);
|
||||
const registered = [];
|
||||
const skipped = [];
|
||||
for (const it of items) {
|
||||
const name = String(it?.name ?? "").trim();
|
||||
const displayName = String(it?.display_name ?? "").trim() || name;
|
||||
if (!isValidLibraryName(name) || name === "*") {
|
||||
skipped.push(name || "(\u7A7A)");
|
||||
continue;
|
||||
}
|
||||
if (have.has(name)) {
|
||||
skipped.push(name);
|
||||
continue;
|
||||
}
|
||||
const res = await kbdbFetch(c.env, "/records", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
template: LIBRARY_TEMPLATE,
|
||||
owner_id: ns,
|
||||
values: { name, display_name: displayName, description: "", status: "active" }
|
||||
})
|
||||
});
|
||||
if (!res.ok) throw new KbdbError(`POST /records\uFF08portal_library\uFF0Cdaemon \u767B\u8A18\uFF09\u2192 ${res.status}`);
|
||||
have.add(name);
|
||||
registered.push(name);
|
||||
}
|
||||
return c.json({ success: true, registered, skipped });
|
||||
})
|
||||
);
|
||||
portalRouter.patch(
|
||||
"/portal/admin/libraries/:id",
|
||||
(c) => run(c, async () => {
|
||||
|
||||
Reference in New Issue
Block a user