@actiondock/core 2.6.0 → 2.8.0
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 +61 -68
- package/dist/catalog/action-catalog.d.ts +56 -0
- package/dist/catalog/action-catalog.js +202 -0
- package/dist/catalog/discovery.d.ts +60 -0
- package/dist/catalog/discovery.js +119 -0
- package/dist/catalog/graph.d.ts +190 -0
- package/dist/catalog/graph.js +589 -0
- package/dist/catalog/index.d.ts +5 -5
- package/dist/catalog/index.js +5 -5
- package/dist/catalog/resolve-action.d.ts +43 -0
- package/dist/catalog/resolve-action.js +119 -0
- package/dist/catalog/resolve-playbook.d.ts +26 -0
- package/dist/catalog/resolve-playbook.js +114 -0
- package/dist/doctor/checks/project.js +27 -8
- package/dist/doctor/checks/registry.js +2 -2
- package/dist/doctor/checks/runtime.js +34 -1
- package/dist/errors.d.ts +122 -10
- package/dist/errors.js +123 -10
- package/dist/execution/service.d.ts +18 -16
- package/dist/execution/service.js +183 -252
- package/dist/execution/types.d.ts +25 -69
- package/dist/execution/types.js +2 -1
- package/dist/filter/intent.d.ts +8 -9
- package/dist/filter/intent.js +49 -10
- package/dist/graph/index.d.ts +4 -0
- package/dist/graph/index.js +4 -0
- package/dist/host/host.d.ts +74 -32
- package/dist/host/host.js +585 -336
- package/dist/host/routing.d.ts +15 -48
- package/dist/host/routing.js +90 -153
- package/dist/host/types.d.ts +50 -17
- package/dist/index.d.ts +21 -22
- package/dist/index.js +19 -21
- package/dist/input/advice.d.ts +104 -0
- package/dist/input/advice.js +716 -0
- package/dist/input/describe.d.ts +106 -0
- package/dist/input/describe.js +176 -0
- package/dist/input/file-input.d.ts +54 -0
- package/dist/input/file-input.js +124 -0
- package/dist/input/flat-decode.d.ts +11 -0
- package/dist/input/flat-decode.js +13 -0
- package/dist/input/flat-errors.d.ts +71 -0
- package/dist/input/flat-errors.js +87 -0
- package/dist/input/flat-materializer.d.ts +29 -0
- package/dist/input/flat-materializer.js +177 -0
- package/dist/input/flat-parser.d.ts +50 -0
- package/dist/input/flat-parser.js +169 -0
- package/dist/input/flat-predicates.d.ts +34 -0
- package/dist/input/flat-predicates.js +50 -0
- package/dist/input/index.d.ts +14 -0
- package/dist/input/index.js +14 -0
- package/dist/input/input-resolver.d.ts +63 -0
- package/dist/input/input-resolver.js +254 -0
- package/dist/input/json-depth-scanner.d.ts +17 -0
- package/dist/input/json-depth-scanner.js +49 -0
- package/dist/input/metadata.d.ts +99 -0
- package/dist/input/metadata.js +99 -0
- package/dist/input/stdin-input.d.ts +26 -0
- package/dist/input/stdin-input.js +125 -0
- package/dist/input/utf8.d.ts +19 -0
- package/dist/input/utf8.js +36 -0
- package/dist/input/validation-mapper.d.ts +27 -0
- package/dist/input/validation-mapper.js +144 -0
- package/dist/invocation/index.d.ts +2 -0
- package/dist/invocation/index.js +2 -0
- package/dist/invocation/policy.d.ts +157 -0
- package/dist/invocation/policy.js +231 -0
- package/dist/invocation/types.d.ts +172 -0
- package/dist/invocation/types.js +97 -0
- package/dist/ipc/diagnostic.d.ts +0 -12
- package/dist/ipc/diagnostic.js +0 -21
- package/dist/ipc/host.d.ts +4 -4
- package/dist/ipc/host.js +44 -47
- package/dist/ipc/index.d.ts +1 -1
- package/dist/ipc/index.js +1 -1
- package/dist/ipc/service.d.ts +40 -0
- package/dist/ipc/service.js +349 -0
- package/dist/ipc/types.d.ts +21 -15
- package/dist/json/index.d.ts +1 -0
- package/dist/json/index.js +1 -0
- package/dist/json/value-validator.d.ts +88 -0
- package/dist/json/value-validator.js +330 -0
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.js +1 -0
- package/dist/node/module-loader.d.ts +63 -0
- package/dist/node/module-loader.js +112 -0
- package/dist/package/index.d.ts +23 -0
- package/dist/package/index.js +18 -0
- package/dist/{app/app.d.ts → package/runtime.d.ts} +41 -20
- package/dist/{app/app.js → package/runtime.js} +140 -95
- package/dist/{app → package}/static-index.js +58 -41
- package/dist/package/storage-view.d.ts +13 -0
- package/dist/package/storage-view.js +22 -0
- package/dist/{app → package}/types.d.ts +76 -57
- package/dist/package/types.js +22 -0
- package/dist/platform/index.d.ts +1 -1
- package/dist/platform/index.js +1 -1
- package/dist/platform/node.d.ts +48 -0
- package/dist/platform/node.js +96 -0
- package/dist/platform/types.d.ts +0 -9
- package/dist/process/control-arbiter.d.ts +2 -1
- package/dist/process/control-arbiter.js +1 -2
- package/dist/process/driver.d.ts +9 -8
- package/dist/process/driver.js +11 -22
- package/dist/process/index.d.ts +2 -0
- package/dist/process/index.js +2 -0
- package/dist/process/managed-record.d.ts +2 -2
- package/dist/process/process-driver.d.ts +109 -0
- package/dist/process/process-driver.js +650 -0
- package/dist/process/process-executor.d.ts +47 -0
- package/dist/process/process-executor.js +296 -0
- package/dist/process/process-manager.js +48 -26
- package/dist/process/run-executor.js +12 -12
- package/dist/profile/client-actions.js +2 -2
- package/dist/profile/client-health.js +3 -2
- package/dist/profile/client-query.js +5 -6
- package/dist/profile/client-transport.d.ts +19 -17
- package/dist/profile/client-transport.js +48 -80
- package/dist/profile/client.d.ts +2 -2
- package/dist/profile/client.js +1 -1
- package/dist/profile/index.d.ts +1 -0
- package/dist/profile/index.js +1 -0
- package/dist/profile/manager.d.ts +5 -0
- package/dist/profile/manager.js +41 -6
- package/dist/project/closure.js +2 -2
- package/dist/project/index.d.ts +8 -1
- package/dist/project/index.js +10 -1
- package/dist/project/init.js +2 -2
- package/dist/project/loader.d.ts +1 -1
- package/dist/project/loader.js +26 -29
- package/dist/project/transactions.js +5 -10
- package/dist/registry/index.d.ts +3 -1
- package/dist/registry/index.js +2 -1
- package/dist/registry/lock.d.ts +28 -7
- package/dist/registry/lock.js +136 -16
- package/dist/registry/registry.d.ts +1 -5
- package/dist/registry/registry.js +1 -53
- package/dist/registry/scan.d.ts +0 -15
- package/dist/registry/scan.js +0 -59
- package/dist/registry/store.d.ts +42 -0
- package/dist/registry/store.js +43 -0
- package/dist/registry/types.d.ts +0 -24
- package/dist/runtime/action-collection.d.ts +1 -1
- package/dist/runtime/action-registry.d.ts +0 -4
- package/dist/runtime/action-registry.js +0 -7
- package/dist/runtime/context.js +5 -11
- package/dist/runtime/events.js +3 -6
- package/dist/runtime/identity.d.ts +22 -0
- package/dist/runtime/identity.js +10 -0
- package/dist/runtime/index.d.ts +1 -2
- package/dist/runtime/index.js +1 -2
- package/dist/runtime/module-loader.d.ts +2 -34
- package/dist/runtime/module-loader.js +1 -16
- package/dist/runtime/process.d.ts +6 -24
- package/dist/runtime/process.js +1 -118
- package/dist/runtime/run-persistence.js +2 -5
- package/dist/runtime/runner.d.ts +33 -103
- package/dist/runtime/runner.js +142 -404
- package/dist/runtime/standalone.d.ts +37 -9
- package/dist/runtime/standalone.js +195 -136
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +1 -0
- package/dist/schema/validator.d.ts +10 -0
- package/dist/schema/validator.js +48 -54
- package/dist/server/body.d.ts +16 -8
- package/dist/server/body.js +33 -16
- package/dist/server/dispatcher.d.ts +6 -10
- package/dist/server/dispatcher.js +24 -32
- package/dist/server/http-server.d.ts +87 -0
- package/dist/server/http-server.js +304 -0
- package/dist/server/index.d.ts +11 -0
- package/dist/server/index.js +10 -0
- package/dist/server/mcp-endpoint.d.ts +61 -0
- package/dist/server/mcp-endpoint.js +118 -0
- package/dist/server/routes/actions.js +34 -28
- package/dist/server/routes/common.d.ts +10 -14
- package/dist/server/routes/common.js +32 -56
- package/dist/server/routes/config.js +54 -64
- package/dist/server/routes/doctor.d.ts +1 -1
- package/dist/server/routes/doctor.js +10 -18
- package/dist/server/routes/health.d.ts +1 -1
- package/dist/server/routes/health.js +2 -3
- package/dist/server/routes/info.d.ts +2 -2
- package/dist/server/routes/info.js +12 -13
- package/dist/server/routes/playbooks.js +16 -29
- package/dist/server/routes/runs.js +95 -117
- package/dist/server/routes/state.js +63 -62
- package/dist/server/server.d.ts +2 -2
- package/dist/server/server.js +43 -227
- package/dist/server/types.d.ts +8 -19
- package/dist/service/factory.d.ts +12 -0
- package/dist/service/factory.js +85 -0
- package/dist/{target → service}/index.d.ts +1 -1
- package/dist/{target → service}/index.js +1 -1
- package/dist/service/local.d.ts +27 -0
- package/dist/service/local.js +138 -0
- package/dist/{target → service}/remote-errors.d.ts +3 -6
- package/dist/service/remote-errors.js +38 -0
- package/dist/{target → service}/remote-polling.d.ts +2 -2
- package/dist/{target → service}/remote-polling.js +8 -8
- package/dist/service/remote.d.ts +34 -0
- package/dist/service/remote.js +634 -0
- package/dist/service/sse-stream.d.ts +24 -0
- package/dist/service/sse-stream.js +139 -0
- package/dist/service/types.d.ts +272 -0
- package/dist/service/types.js +32 -0
- package/dist/storage/data-dir-lock.js +10 -5
- package/dist/storage/driver.d.ts +2 -1
- package/dist/storage/driver.js +3 -52
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +1 -0
- package/dist/storage/lock-core.d.ts +2 -6
- package/dist/storage/lock-core.js +4 -17
- package/dist/storage/params.d.ts +2 -8
- package/dist/storage/params.js +2 -8
- package/dist/storage/sqlite-driver.d.ts +40 -0
- package/dist/storage/sqlite-driver.js +116 -0
- package/dist/storage/sqlite.js +21 -6
- package/dist/storage/types.d.ts +4 -4
- package/dist/storage/types.js +2 -2
- package/dist/utils/index.d.ts +53 -0
- package/dist/utils/index.js +99 -4
- package/dist/utils/process.d.ts +10 -0
- package/dist/utils/process.js +21 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +41 -3
- package/dist/app/index.d.ts +0 -2
- package/dist/app/index.js +0 -2
- package/dist/app/types.js +0 -1
- package/dist/catalog/action-index.d.ts +0 -9
- package/dist/catalog/action-index.js +0 -95
- package/dist/catalog/action-resolver.d.ts +0 -20
- package/dist/catalog/action-resolver.js +0 -95
- package/dist/catalog/location-registry.d.ts +0 -15
- package/dist/catalog/location-registry.js +0 -138
- package/dist/catalog/package-catalog.d.ts +0 -7
- package/dist/catalog/package-catalog.js +0 -77
- package/dist/catalog/types.d.ts +0 -68
- package/dist/catalog/types.js +0 -1
- package/dist/export/index.d.ts +0 -1
- package/dist/export/index.js +0 -1
- package/dist/export/templates.d.ts +0 -71
- package/dist/export/templates.js +0 -623
- package/dist/ipc/target.d.ts +0 -74
- package/dist/ipc/target.js +0 -365
- package/dist/platform/default.d.ts +0 -38
- package/dist/platform/default.js +0 -78
- package/dist/project/resolver.d.ts +0 -116
- package/dist/project/resolver.js +0 -376
- package/dist/registry/resolve.d.ts +0 -62
- package/dist/registry/resolve.js +0 -195
- package/dist/runtime/execution-manager.d.ts +0 -48
- package/dist/runtime/execution-manager.js +0 -66
- package/dist/runtime/package-runner-factory.d.ts +0 -82
- package/dist/runtime/package-runner-factory.js +0 -186
- package/dist/target/local.d.ts +0 -53
- package/dist/target/local.js +0 -349
- package/dist/target/remote-errors.js +0 -51
- package/dist/target/remote.d.ts +0 -86
- package/dist/target/remote.js +0 -818
- package/dist/target/target.d.ts +0 -6
- package/dist/target/target.js +0 -37
- package/dist/target/types.d.ts +0 -261
- package/dist/target/types.js +0 -35
- /package/dist/{app → package}/static-index.d.ts +0 -0
- /package/dist/{target → service}/sse-parser.d.ts +0 -0
- /package/dist/{target → service}/sse-parser.js +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { EXECUTION_FAILED } from "../../errors.js";
|
|
1
|
+
import { CAPABILITY_UNAVAILABLE, EVENT_BACKPRESSURE_LIMIT, EVENT_CURSOR_EXPIRED, EXECUTION_FAILED, PACKAGE_FORBIDDEN, RUN_ALREADY_FINISHED, RUN_INTERRUPTED, RUN_NOT_FOUND, RUNS_CLEAR_ERROR, RUNS_LIST_ERROR, } from "../../errors.js";
|
|
3
2
|
import { isTerminalRunStatus } from "../../storage/types.js";
|
|
4
3
|
import { readJsonBody } from "../body.js";
|
|
5
4
|
import { getSubPath, jsonResponse } from "./common.js";
|
|
@@ -7,7 +6,7 @@ import { getSubPath, jsonResponse } from "./common.js";
|
|
|
7
6
|
* 处理历史运行记录查询、清理、详情及 SSE 流式日志接口。
|
|
8
7
|
*/
|
|
9
8
|
export async function handleRunsRoutes(ctx) {
|
|
10
|
-
const { req, url, pathname, corsHeaders, options,
|
|
9
|
+
const { req, url, pathname, corsHeaders, options, service } = ctx;
|
|
11
10
|
const subpath = getSubPath(pathname);
|
|
12
11
|
// 1. Runs List: GET /api/v2/runs, GET /runs
|
|
13
12
|
if (subpath === "/runs" && req.method === "GET") {
|
|
@@ -16,7 +15,11 @@ export async function handleRunsRoutes(ctx) {
|
|
|
16
15
|
const actionId = url.searchParams.get("actionId") || undefined;
|
|
17
16
|
const packageId = url.searchParams.get("packageId") || undefined;
|
|
18
17
|
const intent = url.searchParams.get("intent") || undefined;
|
|
19
|
-
|
|
18
|
+
// limit 边界防护:非法或超界值回退默认 50,并夹紧到 1 至 500 区间
|
|
19
|
+
const parsedLimit = parseInt(url.searchParams.get("limit") || "50", 10);
|
|
20
|
+
const limit = Number.isFinite(parsedLimit) && parsedLimit > 0
|
|
21
|
+
? Math.min(parsedLimit, 500)
|
|
22
|
+
: 50;
|
|
20
23
|
if (packageId &&
|
|
21
24
|
options.packageAllowlist &&
|
|
22
25
|
options.packageAllowlist.length > 0 &&
|
|
@@ -24,61 +27,26 @@ export async function handleRunsRoutes(ctx) {
|
|
|
24
27
|
return jsonResponse({
|
|
25
28
|
ok: false,
|
|
26
29
|
error: {
|
|
27
|
-
code:
|
|
30
|
+
code: PACKAGE_FORBIDDEN,
|
|
28
31
|
message: `Package '${packageId}' is not in the allowed package list`,
|
|
29
32
|
},
|
|
30
33
|
}, 403, corsHeaders);
|
|
31
34
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (!app)
|
|
42
|
-
continue;
|
|
43
|
-
if (packageId && app.packageId !== packageId)
|
|
44
|
-
continue;
|
|
45
|
-
if (options.packageAllowlist && options.packageAllowlist.length > 0) {
|
|
46
|
-
if (!options.packageAllowlist.includes(app.packageId)) {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (app.storage && typeof app.storage.listRuns === "function") {
|
|
51
|
-
try {
|
|
52
|
-
// 状态过滤下推到存储层 SQL,避免先分页后过滤导致某包前 N 条非目标状态时贡献 0 条
|
|
53
|
-
const records = app.storage.listRuns({ actionId, status, limit });
|
|
54
|
-
for (const r of records) {
|
|
55
|
-
if (!seenRunIds.has(r.id)) {
|
|
56
|
-
seenRunIds.add(r.id);
|
|
57
|
-
if (options.packageAllowlist &&
|
|
58
|
-
options.packageAllowlist.length > 0 &&
|
|
59
|
-
r.packageId &&
|
|
60
|
-
!options.packageAllowlist.includes(r.packageId)) {
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
allRuns.push(r);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
// 单包查询失败不阻断整体列表响应,但必须可观测
|
|
69
|
-
console.warn(`[actiondock] listRuns failed for package '${app.packageId}': ${err instanceof Error ? err.message : String(err)}`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
35
|
+
let allRuns = await service.runs.list({
|
|
36
|
+
actionId,
|
|
37
|
+
status,
|
|
38
|
+
packageId,
|
|
39
|
+
intent,
|
|
40
|
+
limit,
|
|
41
|
+
});
|
|
42
|
+
if (options.packageAllowlist && options.packageAllowlist.length > 0) {
|
|
43
|
+
allRuns = allRuns.filter((r) => !r.packageId || options.packageAllowlist.includes(r.packageId));
|
|
72
44
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
? filterByIntent(allRuns, intent, [(r) => r.id, (r) => r.actionId, (r) => r.status, (r) => r.packageId], false)
|
|
76
|
-
: allRuns;
|
|
77
|
-
const sliced = filtered.slice(0, limit);
|
|
78
|
-
return jsonResponse({ ok: true, total: filtered.length, items: sliced }, 200, corsHeaders);
|
|
45
|
+
const sliced = allRuns.slice(0, limit);
|
|
46
|
+
return jsonResponse({ ok: true, total: allRuns.length, items: sliced }, 200, corsHeaders);
|
|
79
47
|
}
|
|
80
48
|
catch (err) {
|
|
81
|
-
return jsonResponse({ ok: false, error: { code:
|
|
49
|
+
return jsonResponse({ ok: false, error: { code: RUNS_LIST_ERROR, message: err.message } }, 500, corsHeaders);
|
|
82
50
|
}
|
|
83
51
|
}
|
|
84
52
|
// 2. Runs Clear: POST /api/v2/runs/clear, DELETE /api/v2/runs, etc.
|
|
@@ -99,45 +67,28 @@ export async function handleRunsRoutes(ctx) {
|
|
|
99
67
|
return jsonResponse({
|
|
100
68
|
ok: false,
|
|
101
69
|
error: {
|
|
102
|
-
code:
|
|
70
|
+
code: PACKAGE_FORBIDDEN,
|
|
103
71
|
message: `Package '${packageId}' is not in the allowed package list`,
|
|
104
72
|
},
|
|
105
73
|
}, 403, corsHeaders);
|
|
106
74
|
}
|
|
107
75
|
let clearedCount = 0;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
: (() => {
|
|
111
|
-
const inner = target?.unwrap?.();
|
|
112
|
-
return inner && "listApps" in inner ? inner.listApps() : [inner].filter(Boolean);
|
|
113
|
-
})();
|
|
114
|
-
for (const app of apps) {
|
|
115
|
-
if (!app)
|
|
116
|
-
continue;
|
|
117
|
-
if (packageId && app.packageId !== packageId)
|
|
118
|
-
continue;
|
|
119
|
-
if (options.packageAllowlist && options.packageAllowlist.length > 0) {
|
|
120
|
-
if (!options.packageAllowlist.includes(app.packageId)) {
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (app.storage && typeof app.storage.clearRuns === "function") {
|
|
125
|
-
clearedCount += app.storage.clearRuns({ actionId, status });
|
|
126
|
-
}
|
|
76
|
+
if (service.runs.clear) {
|
|
77
|
+
clearedCount = await service.runs.clear({ packageId, actionId, status });
|
|
127
78
|
}
|
|
128
79
|
return jsonResponse({ ok: true, clearedCount }, 200, corsHeaders);
|
|
129
80
|
}
|
|
130
81
|
catch (err) {
|
|
131
|
-
return jsonResponse({ ok: false, error: { code:
|
|
82
|
+
return jsonResponse({ ok: false, error: { code: RUNS_CLEAR_ERROR, message: err.message } }, 500, corsHeaders);
|
|
132
83
|
}
|
|
133
84
|
}
|
|
134
85
|
// 3. Run Events SSE: GET /api/v2/runs/:runId/events (and stream alias)
|
|
135
86
|
const runEventsMatch = subpath.match(/^\/runs\/([^/]+)\/(events|stream)$/);
|
|
136
87
|
if (runEventsMatch && req.method === "GET") {
|
|
137
88
|
const runId = decodeURIComponent(runEventsMatch[1]);
|
|
138
|
-
const run = await
|
|
89
|
+
const run = await service.runs.get(runId);
|
|
139
90
|
if (!run) {
|
|
140
|
-
return jsonResponse({ ok: false, error: { code:
|
|
91
|
+
return jsonResponse({ ok: false, error: { code: RUN_NOT_FOUND, message: `Run '${runId}' not found` } }, 404, corsHeaders);
|
|
141
92
|
}
|
|
142
93
|
if (options.packageAllowlist &&
|
|
143
94
|
options.packageAllowlist.length > 0 &&
|
|
@@ -145,7 +96,7 @@ export async function handleRunsRoutes(ctx) {
|
|
|
145
96
|
return jsonResponse({
|
|
146
97
|
ok: false,
|
|
147
98
|
error: {
|
|
148
|
-
code:
|
|
99
|
+
code: PACKAGE_FORBIDDEN,
|
|
149
100
|
message: `Package '${run.packageId}' is not in the allowed package list`,
|
|
150
101
|
},
|
|
151
102
|
}, 403, corsHeaders);
|
|
@@ -165,44 +116,62 @@ export async function handleRunsRoutes(ctx) {
|
|
|
165
116
|
afterCursor = trimmed;
|
|
166
117
|
}
|
|
167
118
|
}
|
|
168
|
-
|
|
119
|
+
if (!service.events) {
|
|
120
|
+
return jsonResponse({
|
|
121
|
+
ok: false,
|
|
122
|
+
error: {
|
|
123
|
+
code: CAPABILITY_UNAVAILABLE,
|
|
124
|
+
message: "EventsPort is not supported by this ActionDock service",
|
|
125
|
+
},
|
|
126
|
+
}, 501);
|
|
127
|
+
}
|
|
128
|
+
const eventStream = service.events.events(runId, { after: afterCursor, signal: req.signal });
|
|
169
129
|
const iterator = eventStream[Symbol.asyncIterator]();
|
|
170
|
-
|
|
130
|
+
const encoder = new TextEncoder();
|
|
131
|
+
const encodeEvent = (evt) => {
|
|
132
|
+
const eventType = evt.type || "message";
|
|
133
|
+
const idField = evt.eventId ? `id: ${evt.eventId}\n` : `id: ${evt.sequence}\n`;
|
|
134
|
+
return encoder.encode(`${idField}event: ${eventType}\ndata: ${JSON.stringify(evt)}\n\n`);
|
|
135
|
+
};
|
|
136
|
+
// 游标过期检测:仅等待首事件一小段时间(过期错误通常在拉取瞬间抛出);
|
|
137
|
+
// 超时后立即开流,保证响应头及时下发,不再等首事件到达
|
|
138
|
+
const CURSOR_PROBE_MS = 250;
|
|
171
139
|
let firstResult;
|
|
140
|
+
let cursorExpired = null;
|
|
141
|
+
const firstPull = iterator.next();
|
|
172
142
|
try {
|
|
173
|
-
firstResult = await
|
|
143
|
+
firstResult = await Promise.race([
|
|
144
|
+
firstPull,
|
|
145
|
+
new Promise((resolve) => setTimeout(() => resolve(undefined), CURSOR_PROBE_MS)),
|
|
146
|
+
]);
|
|
174
147
|
}
|
|
175
148
|
catch (err) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
149
|
+
cursorExpired = err;
|
|
150
|
+
}
|
|
151
|
+
if (cursorExpired?.code === EVENT_CURSOR_EXPIRED) {
|
|
152
|
+
return jsonResponse({
|
|
153
|
+
ok: false,
|
|
154
|
+
error: {
|
|
155
|
+
code: EVENT_CURSOR_EXPIRED,
|
|
156
|
+
message: cursorExpired.message || "Event cursor has expired",
|
|
157
|
+
details: cursorExpired.details,
|
|
158
|
+
},
|
|
159
|
+
}, 410, corsHeaders);
|
|
187
160
|
}
|
|
188
161
|
const stream = new ReadableStream({
|
|
189
162
|
async start(controller) {
|
|
190
|
-
const encoder = new TextEncoder();
|
|
191
163
|
let sawFinish = false;
|
|
192
|
-
let eventsCount = 0;
|
|
193
164
|
try {
|
|
194
|
-
//
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const evt =
|
|
165
|
+
// 先消费首个事件结果(探测期内未完成则继续等待)
|
|
166
|
+
const first = firstResult ?? (await firstPull);
|
|
167
|
+
if (!first.done) {
|
|
168
|
+
const evt = first.value;
|
|
198
169
|
if (evt.type === "finish") {
|
|
199
170
|
sawFinish = true;
|
|
200
171
|
}
|
|
201
|
-
|
|
202
|
-
const idField = evt.eventId ? `id: ${evt.eventId}\n` : `id: ${evt.sequence}\n`;
|
|
203
|
-
controller.enqueue(encoder.encode(`${idField}event: ${eventType}\ndata: ${JSON.stringify(evt)}\n\n`));
|
|
172
|
+
controller.enqueue(encodeEvent(evt));
|
|
204
173
|
// 若首条事件为背压终止事件,立即关闭通道
|
|
205
|
-
if (evt.type === "error" && evt.error?.code ===
|
|
174
|
+
if (evt.type === "error" && evt.error?.code === EVENT_BACKPRESSURE_LIMIT) {
|
|
206
175
|
controller.close();
|
|
207
176
|
return;
|
|
208
177
|
}
|
|
@@ -212,16 +181,13 @@ export async function handleRunsRoutes(ctx) {
|
|
|
212
181
|
const nextResult = await iterator.next();
|
|
213
182
|
if (nextResult.done)
|
|
214
183
|
break;
|
|
215
|
-
eventsCount++;
|
|
216
184
|
const evt = nextResult.value;
|
|
217
185
|
if (evt.type === "finish") {
|
|
218
186
|
sawFinish = true;
|
|
219
187
|
}
|
|
220
|
-
|
|
221
|
-
const idField = evt.eventId ? `id: ${evt.eventId}\n` : `id: ${evt.sequence}\n`;
|
|
222
|
-
controller.enqueue(encoder.encode(`${idField}event: ${eventType}\ndata: ${JSON.stringify(evt)}\n\n`));
|
|
188
|
+
controller.enqueue(encodeEvent(evt));
|
|
223
189
|
// 若收到背压截断终止事件,正常关闭流通道
|
|
224
|
-
if (evt.type === "error" && evt.error?.code ===
|
|
190
|
+
if (evt.type === "error" && evt.error?.code === EVENT_BACKPRESSURE_LIMIT) {
|
|
225
191
|
break;
|
|
226
192
|
}
|
|
227
193
|
}
|
|
@@ -236,7 +202,7 @@ export async function handleRunsRoutes(ctx) {
|
|
|
236
202
|
ok: false,
|
|
237
203
|
runId,
|
|
238
204
|
error: run.error || {
|
|
239
|
-
code: run.status === "interrupted" ?
|
|
205
|
+
code: run.status === "interrupted" ? RUN_INTERRUPTED : EXECUTION_FAILED,
|
|
240
206
|
message: `Run finished with status ${run.status}`,
|
|
241
207
|
},
|
|
242
208
|
},
|
|
@@ -244,8 +210,11 @@ export async function handleRunsRoutes(ctx) {
|
|
|
244
210
|
controller.enqueue(encoder.encode(`event: finish\ndata: ${JSON.stringify(finishEvt)}\n\n`));
|
|
245
211
|
}
|
|
246
212
|
}
|
|
247
|
-
catch {
|
|
248
|
-
//
|
|
213
|
+
catch (err) {
|
|
214
|
+
// 流中断不静默:保留诊断线索(客户端断连属正常路径,仅记录非预期异常)
|
|
215
|
+
if (!(err instanceof Error) || err.name !== "AbortError") {
|
|
216
|
+
console.warn(`[RunsRoute] SSE stream for run '${runId}' interrupted: ${err instanceof Error ? err.message : String(err)}`);
|
|
217
|
+
}
|
|
249
218
|
}
|
|
250
219
|
finally {
|
|
251
220
|
try {
|
|
@@ -254,7 +223,16 @@ export async function handleRunsRoutes(ctx) {
|
|
|
254
223
|
catch { }
|
|
255
224
|
}
|
|
256
225
|
},
|
|
257
|
-
cancel() {
|
|
226
|
+
cancel() {
|
|
227
|
+
// 客户端断开时释放底层事件迭代器,避免资源悬挂
|
|
228
|
+
try {
|
|
229
|
+
const ret = iterator.return?.();
|
|
230
|
+
if (ret && typeof ret.catch === "function") {
|
|
231
|
+
ret.catch(() => { });
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch { }
|
|
235
|
+
},
|
|
258
236
|
});
|
|
259
237
|
return new Response(stream, {
|
|
260
238
|
status: 200,
|
|
@@ -270,12 +248,12 @@ export async function handleRunsRoutes(ctx) {
|
|
|
270
248
|
const runShowMatch = subpath.match(/^\/runs\/([^/]+)$/);
|
|
271
249
|
if (runShowMatch && req.method === "GET") {
|
|
272
250
|
const runId = decodeURIComponent(runShowMatch[1]);
|
|
273
|
-
const run = await
|
|
251
|
+
const run = await service.runs.get(runId);
|
|
274
252
|
if (!run) {
|
|
275
253
|
return jsonResponse({
|
|
276
254
|
ok: false,
|
|
277
255
|
error: {
|
|
278
|
-
code:
|
|
256
|
+
code: RUN_NOT_FOUND,
|
|
279
257
|
message: `Run '${runId}' not found`,
|
|
280
258
|
},
|
|
281
259
|
}, 404, corsHeaders);
|
|
@@ -286,7 +264,7 @@ export async function handleRunsRoutes(ctx) {
|
|
|
286
264
|
return jsonResponse({
|
|
287
265
|
ok: false,
|
|
288
266
|
error: {
|
|
289
|
-
code:
|
|
267
|
+
code: PACKAGE_FORBIDDEN,
|
|
290
268
|
message: `Package '${run.packageId || "unknown"}' is not in the allowed package list`,
|
|
291
269
|
},
|
|
292
270
|
}, 403, corsHeaders);
|
|
@@ -298,12 +276,12 @@ export async function handleRunsRoutes(ctx) {
|
|
|
298
276
|
if (runCancelMatch && req.method === "POST") {
|
|
299
277
|
const runId = decodeURIComponent(runCancelMatch[1]);
|
|
300
278
|
if (options.packageAllowlist && options.packageAllowlist.length > 0) {
|
|
301
|
-
const run = await
|
|
279
|
+
const run = await service.runs.get(runId);
|
|
302
280
|
if (run && (!run.packageId || !options.packageAllowlist.includes(run.packageId))) {
|
|
303
281
|
return jsonResponse({
|
|
304
282
|
ok: false,
|
|
305
283
|
error: {
|
|
306
|
-
code:
|
|
284
|
+
code: PACKAGE_FORBIDDEN,
|
|
307
285
|
message: `Package '${run.packageId}' is not in the allowed package list`,
|
|
308
286
|
},
|
|
309
287
|
}, 403, corsHeaders);
|
|
@@ -315,12 +293,12 @@ export async function handleRunsRoutes(ctx) {
|
|
|
315
293
|
}
|
|
316
294
|
catch { }
|
|
317
295
|
const reason = body?.reason || "Cancelled by client request";
|
|
318
|
-
const cancelResult = await
|
|
296
|
+
const cancelResult = await service.runs.cancel(runId, reason);
|
|
319
297
|
if (cancelResult.outcome === "not_found") {
|
|
320
298
|
return jsonResponse({
|
|
321
299
|
ok: false,
|
|
322
300
|
error: {
|
|
323
|
-
code:
|
|
301
|
+
code: RUN_NOT_FOUND,
|
|
324
302
|
message: `Run '${runId}' not found`,
|
|
325
303
|
},
|
|
326
304
|
}, 404, corsHeaders);
|
|
@@ -329,7 +307,7 @@ export async function handleRunsRoutes(ctx) {
|
|
|
329
307
|
return jsonResponse({
|
|
330
308
|
ok: false,
|
|
331
309
|
error: {
|
|
332
|
-
code:
|
|
310
|
+
code: RUN_ALREADY_FINISHED,
|
|
333
311
|
message: `Run '${runId}' has already finished with status '${cancelResult.status}'`,
|
|
334
312
|
status: cancelResult.status,
|
|
335
313
|
},
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import { decodeStateKey } from "../../storage/index.js";
|
|
2
|
-
import { CAPABILITY_UNAVAILABLE, STATE_KEY_NOT_FOUND } from "../../errors.js";
|
|
2
|
+
import { AMBIGUOUS_STATE_KEY, CAPABILITY_UNAVAILABLE, INVALID_ARGUMENT, INVALID_PACKAGE_ID, PACKAGE_NOT_ALLOWED, PACKAGE_NOT_FOUND, PATH_TRAVERSAL, STATE_CLEAR_ERROR, STATE_KEY_ERROR, STATE_KEY_NOT_FOUND, STATE_LIST_ERROR, } from "../../errors.js";
|
|
3
3
|
import { readJsonBody } from "../body.js";
|
|
4
|
-
import {
|
|
4
|
+
import { getSubPath, jsonResponse, resolveTargetPackageId } from "./common.js";
|
|
5
|
+
function isClientStateError(err) {
|
|
6
|
+
return (err?.code === PACKAGE_NOT_FOUND ||
|
|
7
|
+
err?.code === INVALID_PACKAGE_ID ||
|
|
8
|
+
err?.code === PATH_TRAVERSAL ||
|
|
9
|
+
err?.code === AMBIGUOUS_STATE_KEY ||
|
|
10
|
+
err?.code === INVALID_ARGUMENT ||
|
|
11
|
+
err?.status === 400 ||
|
|
12
|
+
err?.status === 404);
|
|
13
|
+
}
|
|
5
14
|
/**
|
|
6
15
|
* 处理状态键名列表、读取、写入、删除及清空接口。
|
|
7
16
|
* 在未显式开启管理功能 (options.enableManagement !== true) 时返回 403 拒绝。
|
|
8
17
|
*/
|
|
9
18
|
export async function handleStateRoutes(ctx) {
|
|
10
|
-
const { req, url, pathname, corsHeaders, options,
|
|
19
|
+
const { req, url, pathname, corsHeaders, options, service } = ctx;
|
|
11
20
|
const subpath = getSubPath(pathname);
|
|
12
21
|
const isStateRoute = subpath === "/state" ||
|
|
13
22
|
subpath.startsWith("/state/") ||
|
|
@@ -16,7 +25,7 @@ export async function handleStateRoutes(ctx) {
|
|
|
16
25
|
return null;
|
|
17
26
|
}
|
|
18
27
|
// 校验管理能力开关
|
|
19
|
-
if (options.enableManagement !== true) {
|
|
28
|
+
if (options.enableManagement !== true || !service.management?.state) {
|
|
20
29
|
return jsonResponse({
|
|
21
30
|
ok: false,
|
|
22
31
|
error: {
|
|
@@ -32,31 +41,26 @@ export async function handleStateRoutes(ctx) {
|
|
|
32
41
|
const actionParam = url.searchParams.get("action") || url.searchParams.get("actionId") || "";
|
|
33
42
|
const nsParam = url.searchParams.get("namespace") ?? undefined;
|
|
34
43
|
const prefix = url.searchParams.get("prefix") || "";
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
: (nsParam !== undefined ? nsParam : null);
|
|
43
|
-
const keys = await app.storage.listStateKeys(effectiveNs, prefix);
|
|
44
|
-
return jsonResponse({ ok: true, packageId: app.packageId, keys }, 200, corsHeaders);
|
|
44
|
+
const pkgs = await service.discovery.listPackages();
|
|
45
|
+
const targetPackageId = resolveTargetPackageId(pkgs, pkgParam, options);
|
|
46
|
+
const keys = await service.management.state.list(targetPackageId, actionParam, {
|
|
47
|
+
namespace: nsParam,
|
|
48
|
+
prefix,
|
|
49
|
+
});
|
|
50
|
+
return jsonResponse({ ok: true, packageId: targetPackageId, keys }, 200, corsHeaders);
|
|
45
51
|
}
|
|
46
52
|
catch (err) {
|
|
47
|
-
if (err.code ===
|
|
53
|
+
if (err.code === PACKAGE_NOT_ALLOWED || err.status === 403) {
|
|
48
54
|
return jsonResponse({
|
|
49
55
|
ok: false,
|
|
50
56
|
error: {
|
|
51
|
-
code:
|
|
57
|
+
code: PACKAGE_NOT_ALLOWED,
|
|
52
58
|
message: err.message || "Package is not in the allowed package list",
|
|
53
59
|
},
|
|
54
60
|
}, 403, corsHeaders);
|
|
55
61
|
}
|
|
56
|
-
const isClient = err
|
|
57
|
-
|
|
58
|
-
err.message?.includes("escapes boundary");
|
|
59
|
-
return jsonResponse({ ok: false, error: { code: isClient ? "INVALID_ARGUMENT" : "STATE_LIST_ERROR", message: err.message } }, isClient ? 400 : 500, corsHeaders);
|
|
62
|
+
const isClient = isClientStateError(err);
|
|
63
|
+
return jsonResponse({ ok: false, error: { code: isClient ? INVALID_ARGUMENT : STATE_LIST_ERROR, message: err.message } }, isClient ? 400 : 500, corsHeaders);
|
|
60
64
|
}
|
|
61
65
|
}
|
|
62
66
|
// 2. State Clear: POST /state/clear
|
|
@@ -66,33 +70,27 @@ export async function handleStateRoutes(ctx) {
|
|
|
66
70
|
const pkgParam = url.searchParams.get("package") || url.searchParams.get("packageId") || body.package || undefined;
|
|
67
71
|
const actionParam = url.searchParams.get("action") || url.searchParams.get("actionId") || body.action || body.actionId || "";
|
|
68
72
|
const baseNs = body.namespace ?? (url.searchParams.get("namespace") || undefined);
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const app = resolveAppForPackage(pkgParam, host, target, options);
|
|
74
|
-
assertPackageAllowed(app.packageId, options);
|
|
75
|
-
const clearedCount = await app.storage.clearState({
|
|
76
|
-
namespace: effectiveNs,
|
|
73
|
+
const pkgs = await service.discovery.listPackages();
|
|
74
|
+
const targetPackageId = resolveTargetPackageId(pkgs, pkgParam, options);
|
|
75
|
+
const clearedCount = await service.management.state.clear(targetPackageId, actionParam, {
|
|
76
|
+
namespace: baseNs,
|
|
77
77
|
all: Boolean(body.all ?? url.searchParams.get("all") === "true"),
|
|
78
78
|
prefix: body.prefix ?? (url.searchParams.get("prefix") || undefined),
|
|
79
79
|
});
|
|
80
|
-
return jsonResponse({ ok: true, packageId:
|
|
80
|
+
return jsonResponse({ ok: true, packageId: targetPackageId, clearedCount }, 200, corsHeaders);
|
|
81
81
|
}
|
|
82
82
|
catch (err) {
|
|
83
|
-
if (err.code ===
|
|
83
|
+
if (err.code === PACKAGE_NOT_ALLOWED || err.status === 403) {
|
|
84
84
|
return jsonResponse({
|
|
85
85
|
ok: false,
|
|
86
86
|
error: {
|
|
87
|
-
code:
|
|
87
|
+
code: PACKAGE_NOT_ALLOWED,
|
|
88
88
|
message: err.message || "Package is not in the allowed package list",
|
|
89
89
|
},
|
|
90
90
|
}, 403, corsHeaders);
|
|
91
91
|
}
|
|
92
|
-
const isClient = err
|
|
93
|
-
|
|
94
|
-
err.message?.includes("escapes boundary");
|
|
95
|
-
return jsonResponse({ ok: false, error: { code: isClient ? "INVALID_ARGUMENT" : "STATE_CLEAR_ERROR", message: err.message } }, isClient ? 400 : 500, corsHeaders);
|
|
92
|
+
const isClient = isClientStateError(err);
|
|
93
|
+
return jsonResponse({ ok: false, error: { code: isClient ? INVALID_ARGUMENT : STATE_CLEAR_ERROR, message: err.message } }, isClient ? 400 : 500, corsHeaders);
|
|
96
94
|
}
|
|
97
95
|
}
|
|
98
96
|
// 3. State Key CRUD: GET / PUT / POST / DELETE /state/:key
|
|
@@ -103,24 +101,26 @@ export async function handleStateRoutes(ctx) {
|
|
|
103
101
|
const pkgParam = url.searchParams.get("package") || url.searchParams.get("packageId") || undefined;
|
|
104
102
|
const actionParam = url.searchParams.get("action") || url.searchParams.get("actionId") || "";
|
|
105
103
|
const nsParam = url.searchParams.get("namespace") || undefined;
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
assertPackageAllowed(pkgParam, options);
|
|
109
|
-
}
|
|
110
|
-
const app = resolveAppForPackage(pkgParam, host, target, options);
|
|
111
|
-
assertPackageAllowed(app.packageId, options);
|
|
104
|
+
const pkgs = await service.discovery.listPackages();
|
|
105
|
+
const targetPackageId = resolveTargetPackageId(pkgs, pkgParam, options);
|
|
112
106
|
if (req.method === "GET") {
|
|
113
|
-
const entry = await
|
|
114
|
-
|
|
107
|
+
const entry = await service.management.state.get(targetPackageId, actionParam, key, {
|
|
108
|
+
namespace: nsParam,
|
|
109
|
+
detail: true,
|
|
110
|
+
});
|
|
111
|
+
if (!entry || (typeof entry === "object" && entry.value === undefined)) {
|
|
115
112
|
return jsonResponse({ ok: false, error: { code: STATE_KEY_NOT_FOUND, message: `State key '${key}' not found` } }, 404, corsHeaders);
|
|
116
113
|
}
|
|
114
|
+
const data = typeof entry === "object" && "value" in entry
|
|
115
|
+
? entry
|
|
116
|
+
: { key, namespace: nsParam || "", value: entry, expiresAt: undefined };
|
|
117
117
|
return jsonResponse({
|
|
118
118
|
ok: true,
|
|
119
|
-
packageId:
|
|
120
|
-
key:
|
|
121
|
-
namespace:
|
|
122
|
-
value:
|
|
123
|
-
expiresAt:
|
|
119
|
+
packageId: targetPackageId,
|
|
120
|
+
key: data.key || key,
|
|
121
|
+
namespace: data.namespace ?? nsParam ?? "",
|
|
122
|
+
value: data.value,
|
|
123
|
+
expiresAt: data.expiresAt,
|
|
124
124
|
}, 200, corsHeaders);
|
|
125
125
|
}
|
|
126
126
|
if (req.method === "PUT" || req.method === "POST") {
|
|
@@ -129,40 +129,41 @@ export async function handleStateRoutes(ctx) {
|
|
|
129
129
|
const ttl = typeof body.ttl === "number" ? body.ttl : undefined;
|
|
130
130
|
const bodyAction = body.action || body.actionId || actionParam;
|
|
131
131
|
const explicitNs = body.namespace || nsParam;
|
|
132
|
-
const combinedNs = bodyAction ? (explicitNs ? `${bodyAction}:${explicitNs}` : bodyAction) : explicitNs;
|
|
133
132
|
let actualKey = key;
|
|
134
|
-
let ns =
|
|
135
|
-
if (!
|
|
133
|
+
let ns = explicitNs;
|
|
134
|
+
if (!bodyAction && !explicitNs) {
|
|
136
135
|
const decoded = decodeStateKey(key);
|
|
137
136
|
ns = decoded.namespace;
|
|
138
137
|
actualKey = decoded.key;
|
|
139
138
|
}
|
|
140
|
-
await
|
|
141
|
-
|
|
139
|
+
await service.management.state.set(targetPackageId, bodyAction, actualKey, val, {
|
|
140
|
+
namespace: ns,
|
|
141
|
+
ttl,
|
|
142
|
+
});
|
|
143
|
+
return jsonResponse({ ok: true, packageId: targetPackageId, key: actualKey, namespace: ns || bodyAction || "", message: "updated" }, 200, corsHeaders);
|
|
142
144
|
}
|
|
143
145
|
if (req.method === "DELETE") {
|
|
144
|
-
const deleted = await
|
|
146
|
+
const deleted = await service.management.state.delete(targetPackageId, actionParam, key, {
|
|
147
|
+
namespace: nsParam,
|
|
148
|
+
});
|
|
145
149
|
if (!deleted) {
|
|
146
150
|
return jsonResponse({ ok: false, error: { code: STATE_KEY_NOT_FOUND, message: `State key '${key}' not found` } }, 404, corsHeaders);
|
|
147
151
|
}
|
|
148
|
-
return jsonResponse({ ok: true, packageId:
|
|
152
|
+
return jsonResponse({ ok: true, packageId: targetPackageId, key, deleted: true }, 200, corsHeaders);
|
|
149
153
|
}
|
|
150
154
|
}
|
|
151
155
|
catch (err) {
|
|
152
|
-
if (err.code ===
|
|
156
|
+
if (err.code === PACKAGE_NOT_ALLOWED || err.status === 403) {
|
|
153
157
|
return jsonResponse({
|
|
154
158
|
ok: false,
|
|
155
159
|
error: {
|
|
156
|
-
code:
|
|
160
|
+
code: PACKAGE_NOT_ALLOWED,
|
|
157
161
|
message: err.message || "Package is not in the allowed package list",
|
|
158
162
|
},
|
|
159
163
|
}, 403, corsHeaders);
|
|
160
164
|
}
|
|
161
|
-
const isClient = err
|
|
162
|
-
|
|
163
|
-
err.message?.includes("escapes boundary") ||
|
|
164
|
-
err.message?.includes("Ambiguous state key");
|
|
165
|
-
return jsonResponse({ ok: false, error: { code: isClient ? "INVALID_ARGUMENT" : "STATE_KEY_ERROR", message: err.message } }, isClient ? 400 : 500, corsHeaders);
|
|
165
|
+
const isClient = isClientStateError(err);
|
|
166
|
+
return jsonResponse({ ok: false, error: { code: isClient ? INVALID_ARGUMENT : STATE_KEY_ERROR, message: err.message } }, isClient ? 400 : 500, corsHeaders);
|
|
166
167
|
}
|
|
167
168
|
}
|
|
168
169
|
return null;
|
package/dist/server/server.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare function formatHostForUrl(host: string): string;
|
|
|
9
9
|
*/
|
|
10
10
|
export declare function launchHttpServer(port: number, host: string, fetchHandler: (req: Request) => Promise<Response>, tls?: ServerTlsOptions): Promise<CoreHttpServerInstance>;
|
|
11
11
|
/**
|
|
12
|
-
* 启动 ActionDock
|
|
13
|
-
*
|
|
12
|
+
* 启动 ActionDock 原生轻量级 HTTP 服务端。
|
|
13
|
+
* 面向 ActionDockService 服务端口,负责中间件流转、认证拦截与路由分发。
|
|
14
14
|
*/
|
|
15
15
|
export declare function startActionDockServer(options?: ServerOptions): Promise<ActionDockServerInstance>;
|