@actiondock/core 2.0.11 → 2.0.12

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.
Files changed (119) hide show
  1. package/dist/build/templates.d.ts +19 -0
  2. package/dist/catalog/action-index.d.ts +9 -0
  3. package/dist/catalog/action-resolver.d.ts +20 -0
  4. package/dist/catalog/location-registry.d.ts +15 -0
  5. package/dist/catalog/package-catalog.d.ts +7 -0
  6. package/dist/catalog/types.d.ts +68 -0
  7. package/dist/doctor/doctor.d.ts +6 -0
  8. package/dist/doctor/types.d.ts +23 -0
  9. package/dist/execution/index.d.ts +2 -0
  10. package/dist/execution/service.d.ts +74 -0
  11. package/dist/execution/types.d.ts +74 -0
  12. package/dist/export/templates.d.ts +33 -0
  13. package/dist/filter/intent.d.ts +33 -0
  14. package/{src/index.ts → dist/index.d.ts} +1 -1
  15. package/dist/index.js +8458 -0
  16. package/dist/profile/client.d.ts +116 -0
  17. package/dist/profile/manager.d.ts +47 -0
  18. package/dist/profile/types.d.ts +61 -0
  19. package/dist/project/closure.d.ts +25 -0
  20. package/{src/project/index.ts → dist/project/index.d.ts} +1 -0
  21. package/dist/project/init.d.ts +27 -0
  22. package/dist/project/loader.d.ts +105 -0
  23. package/dist/project/manifest.d.ts +44 -0
  24. package/dist/project/types.d.ts +131 -0
  25. package/dist/registry/registry.d.ts +24 -0
  26. package/dist/registry/types.d.ts +117 -0
  27. package/dist/runtime/clock.d.ts +21 -0
  28. package/dist/runtime/context.d.ts +75 -0
  29. package/dist/runtime/env.d.ts +54 -0
  30. package/dist/runtime/events.d.ts +61 -0
  31. package/dist/runtime/execution-manager.d.ts +48 -0
  32. package/{src/runtime/index.ts → dist/runtime/index.d.ts} +0 -1
  33. package/dist/runtime/module-loader.d.ts +42 -0
  34. package/dist/runtime/process.d.ts +11 -0
  35. package/dist/runtime/runner.d.ts +186 -0
  36. package/dist/runtime/standalone.d.ts +40 -0
  37. package/dist/schema/validator.d.ts +28 -0
  38. package/dist/server/body.d.ts +40 -0
  39. package/{src/server/index.ts → dist/server/index.d.ts} +0 -1
  40. package/dist/server/routes/actions.d.ts +5 -0
  41. package/dist/server/routes/common.d.ts +36 -0
  42. package/dist/server/routes/config.d.ts +5 -0
  43. package/dist/server/routes/doctor.d.ts +5 -0
  44. package/dist/server/routes/health.d.ts +5 -0
  45. package/dist/server/routes/info.d.ts +5 -0
  46. package/dist/server/routes/playbooks.d.ts +5 -0
  47. package/dist/server/routes/runs.d.ts +5 -0
  48. package/dist/server/routes/state.d.ts +5 -0
  49. package/dist/server/runtime-registry.d.ts +78 -0
  50. package/dist/server/security.d.ts +37 -0
  51. package/dist/server/server.d.ts +15 -0
  52. package/dist/server/types.d.ts +59 -0
  53. package/dist/storage/driver.d.ts +15 -0
  54. package/dist/storage/index.d.ts +44 -0
  55. package/{src/storage/mask.ts → dist/storage/mask.d.ts} +5 -20
  56. package/dist/storage/sqlite.d.ts +66 -0
  57. package/dist/storage/types.d.ts +121 -0
  58. package/dist/utils/index.d.ts +29 -0
  59. package/dist/version.d.ts +4 -0
  60. package/package.json +11 -10
  61. package/src/build/templates.ts +0 -59
  62. package/src/catalog/action-index.ts +0 -92
  63. package/src/catalog/action-resolver.ts +0 -120
  64. package/src/catalog/location-registry.ts +0 -134
  65. package/src/catalog/package-catalog.ts +0 -87
  66. package/src/catalog/types.ts +0 -75
  67. package/src/doctor/doctor.ts +0 -419
  68. package/src/doctor/types.ts +0 -25
  69. package/src/execution/index.ts +0 -2
  70. package/src/execution/service.ts +0 -322
  71. package/src/execution/types.ts +0 -73
  72. package/src/export/templates.ts +0 -590
  73. package/src/filter/intent.ts +0 -154
  74. package/src/profile/client.ts +0 -552
  75. package/src/profile/manager.ts +0 -341
  76. package/src/profile/types.ts +0 -71
  77. package/src/project/init.ts +0 -242
  78. package/src/project/loader.ts +0 -479
  79. package/src/project/manifest.ts +0 -299
  80. package/src/project/types.ts +0 -141
  81. package/src/registry/registry.ts +0 -940
  82. package/src/registry/types.ts +0 -127
  83. package/src/runtime/clock.ts +0 -41
  84. package/src/runtime/context.ts +0 -259
  85. package/src/runtime/env.ts +0 -172
  86. package/src/runtime/events.ts +0 -142
  87. package/src/runtime/execution-manager.ts +0 -74
  88. package/src/runtime/module-loader.ts +0 -67
  89. package/src/runtime/process.ts +0 -245
  90. package/src/runtime/runner.ts +0 -527
  91. package/src/runtime/standalone.ts +0 -429
  92. package/src/schema/validator.ts +0 -61
  93. package/src/server/body.ts +0 -112
  94. package/src/server/routes/actions.ts +0 -262
  95. package/src/server/routes/common.ts +0 -126
  96. package/src/server/routes/config.ts +0 -147
  97. package/src/server/routes/doctor.ts +0 -29
  98. package/src/server/routes/health.ts +0 -40
  99. package/src/server/routes/info.ts +0 -221
  100. package/src/server/routes/playbooks.ts +0 -109
  101. package/src/server/routes/runs.ts +0 -301
  102. package/src/server/routes/state.ts +0 -133
  103. package/src/server/runtime-registry.ts +0 -115
  104. package/src/server/security.ts +0 -115
  105. package/src/server/server.ts +0 -251
  106. package/src/server/types.ts +0 -57
  107. package/src/storage/driver.ts +0 -126
  108. package/src/storage/index.ts +0 -81
  109. package/src/storage/sqlite.ts +0 -714
  110. package/src/storage/types.ts +0 -139
  111. package/src/utils/index.ts +0 -62
  112. /package/{src/build/index.ts → dist/build/index.d.ts} +0 -0
  113. /package/{src/catalog/index.ts → dist/catalog/index.d.ts} +0 -0
  114. /package/{src/doctor/index.ts → dist/doctor/index.d.ts} +0 -0
  115. /package/{src/export/index.ts → dist/export/index.d.ts} +0 -0
  116. /package/{src/filter/index.ts → dist/filter/index.d.ts} +0 -0
  117. /package/{src/profile/index.ts → dist/profile/index.d.ts} +0 -0
  118. /package/{src/registry/index.ts → dist/registry/index.d.ts} +0 -0
  119. /package/{src/server/routes/index.ts → dist/server/routes/index.d.ts} +0 -0
@@ -1,262 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { existsSync } from "node:fs";
3
- import { filterByIntent } from "../../filter";
4
- import { loadActions, loadProjectConfig } from "../../project/loader";
5
- import { listLinkedPackages, resolveActionProject } from "../../registry/registry";
6
- import { ActionRunner } from "../../runtime/runner";
7
- import { InvalidJsonError, readJsonBody, RequestTooLargeError } from "../body";
8
- import { type RouteContext, jsonResponse } from "./common";
9
-
10
- /**
11
- * 处理 Action 列表、详情查询及同步/异步运行接口。
12
- */
13
- export async function handleActionsRoutes(ctx: RouteContext): Promise<Response | null> {
14
- const { req, url, pathname, corsHeaders, projectRoot, customHome, runtimeRegistry, options } = ctx;
15
-
16
- // 1. Actions List: GET /api/v1/actions
17
- if (pathname === "/api/v1/actions" && req.method === "GET") {
18
- try {
19
- const actionList: Array<{
20
- id: string;
21
- description: string;
22
- packageId?: string;
23
- }> = [];
24
-
25
- if (projectRoot) {
26
- const config = loadProjectConfig(projectRoot);
27
- const actions = await loadActions(projectRoot, config.actionsDir);
28
- for (const [id, a] of actions.entries()) {
29
- actionList.push({
30
- id,
31
- description: a.description || "",
32
- packageId: config.id,
33
- });
34
- }
35
- }
36
-
37
- const linked = listLinkedPackages(customHome);
38
- for (const pkg of linked) {
39
- if (projectRoot && pkg.path === projectRoot) continue;
40
- if (!existsSync(pkg.path)) continue;
41
- try {
42
- const config = loadProjectConfig(pkg.path);
43
- const actions = await loadActions(pkg.path, config.actionsDir);
44
- for (const [id, a] of actions.entries()) {
45
- actionList.push({
46
- id,
47
- description: a.description || "",
48
- packageId: pkg.id,
49
- });
50
- }
51
- } catch {
52
- // 忽略故障包
53
- }
54
- }
55
-
56
- const intent = url.searchParams.get("intent");
57
- const targetPkg = url.searchParams.get("package");
58
-
59
- let filtered = targetPkg
60
- ? actionList.filter((a) => a.packageId === targetPkg)
61
- : actionList;
62
-
63
- if (intent) {
64
- filtered = filterByIntent(
65
- filtered,
66
- intent,
67
- [(a) => a.id, (a) => a.description, (a) => a.packageId],
68
- false
69
- );
70
- }
71
-
72
- return jsonResponse(filtered, 200, corsHeaders);
73
- } catch (err: any) {
74
- return jsonResponse(
75
- {
76
- ok: false,
77
- error: { code: "ACTIONS_LIST_ERROR", message: err.message },
78
- },
79
- 500,
80
- corsHeaders
81
- );
82
- }
83
- }
84
-
85
- // 2. Action Show: GET /api/v1/actions/:id
86
- const actionShowMatch = pathname.match(/^\/api\/v1\/actions\/([^/]+)$/);
87
- if (actionShowMatch && req.method === "GET") {
88
- const actionId = decodeURIComponent(actionShowMatch[1]);
89
- try {
90
- const resolved = await resolveActionProject(
91
- actionId,
92
- projectRoot || process.cwd(),
93
- customHome
94
- );
95
- const config = loadProjectConfig(resolved.projectRoot);
96
- const actions = await loadActions(resolved.projectRoot, config.actionsDir);
97
- const action = actions.get(resolved.actionId);
98
- if (!action) {
99
- return jsonResponse(
100
- {
101
- ok: false,
102
- error: {
103
- code: "ACTION_NOT_FOUND",
104
- message: `Action '${resolved.actionId}' not found in package '${resolved.packageId}'`,
105
- },
106
- },
107
- 404,
108
- corsHeaders
109
- );
110
- }
111
-
112
- return jsonResponse(
113
- {
114
- id: action.id,
115
- packageId: resolved.packageId,
116
- description: action.description || "",
117
- inputSchema: action.inputSchema || null,
118
- outputSchema: action.outputSchema || null,
119
- },
120
- 200,
121
- corsHeaders
122
- );
123
- } catch (err: any) {
124
- return jsonResponse(
125
- {
126
- ok: false,
127
- error: { code: "ACTION_NOT_FOUND", message: err.message },
128
- },
129
- 404,
130
- corsHeaders
131
- );
132
- }
133
- }
134
-
135
- // 3. Action Run: POST /api/v1/actions/:id/run
136
- const actionRunMatch = pathname.match(/^\/api\/v1\/actions\/([^/]+)\/run$/);
137
- if (actionRunMatch && req.method === "POST") {
138
- const actionId = decodeURIComponent(actionRunMatch[1]);
139
- let body: any = {};
140
- try {
141
- body = await readJsonBody(req, { maxBytes: options.maxBodyBytes });
142
- } catch (err: any) {
143
- if (err instanceof RequestTooLargeError) {
144
- return jsonResponse(
145
- {
146
- ok: false,
147
- runId: randomUUID(),
148
- error: { code: "REQUEST_TOO_LARGE", message: err.message },
149
- },
150
- 413,
151
- corsHeaders
152
- );
153
- }
154
- if (err instanceof InvalidJsonError) {
155
- return jsonResponse(
156
- {
157
- ok: false,
158
- runId: randomUUID(),
159
- error: { code: "INVALID_JSON", message: err.message },
160
- },
161
- 400,
162
- corsHeaders
163
- );
164
- }
165
- return jsonResponse(
166
- {
167
- ok: false,
168
- runId: randomUUID(),
169
- error: { code: "INVALID_JSON", message: `Failed to parse request body: ${err.message}` },
170
- },
171
- 400,
172
- corsHeaders
173
- );
174
- }
175
-
176
- try {
177
- const resolved = await resolveActionProject(
178
- actionId,
179
- projectRoot || process.cwd(),
180
- customHome
181
- );
182
- const config = loadProjectConfig(resolved.projectRoot);
183
- const actions = await loadActions(resolved.projectRoot, config.actionsDir);
184
- const storage = runtimeRegistry.getStorage(config.id, resolved.projectRoot);
185
-
186
- const runner = new ActionRunner({
187
- packageId: config.id,
188
- storage,
189
- projectConfig: config,
190
- configOverrides: body?.config || {},
191
- actions,
192
- });
193
-
194
- const isAsync = body?.execution?.mode === "async" || body?.async === true;
195
- const timeoutMs =
196
- typeof body?.execution?.timeoutMs === "number" && body.execution.timeoutMs > 0
197
- ? body.execution.timeoutMs
198
- : undefined;
199
-
200
- if (isAsync) {
201
- const handle = runner.start(resolved.actionId, body?.input || {}, {
202
- timeoutMs,
203
- });
204
- runtimeRegistry.executionManager.register(handle);
205
-
206
- // 监听结算以广播 SSE 完成事件
207
- handle.result
208
- .then((res) => {
209
- runtimeRegistry.emit(handle.runId, { type: "finish", data: res });
210
- })
211
- .catch((err) => {
212
- runtimeRegistry.emit(handle.runId, {
213
- type: "finish",
214
- data: {
215
- ok: false,
216
- error: {
217
- code: "ACTION_EXECUTION_ERROR",
218
- message: err?.message || String(err),
219
- },
220
- },
221
- });
222
- });
223
-
224
- return jsonResponse(
225
- {
226
- ok: true,
227
- runId: handle.runId,
228
- status: "running",
229
- streamUrl: `/api/v1/runs/${handle.runId}/stream`,
230
- },
231
- 202,
232
- corsHeaders
233
- );
234
- }
235
-
236
- // 同步执行模式
237
- const handle = runner.start(resolved.actionId, body?.input || {}, {
238
- signal: req.signal,
239
- timeoutMs,
240
- });
241
- runtimeRegistry.executionManager.register(handle);
242
- const result = await handle.result;
243
-
244
- return jsonResponse(result, 200, corsHeaders);
245
- } catch (err: any) {
246
- return jsonResponse(
247
- {
248
- ok: false,
249
- runId: randomUUID(),
250
- error: {
251
- code: "ACTION_EXECUTION_ERROR",
252
- message: err.message || String(err),
253
- },
254
- },
255
- 500,
256
- corsHeaders
257
- );
258
- }
259
- }
260
-
261
- return null;
262
- }
@@ -1,126 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import { loadProjectConfig } from "../../project/loader";
3
- import { listLinkedPackages, resolvePackageRoot } from "../../registry/registry";
4
- import type { RuntimeStorage } from "../../storage/types";
5
- import type { RunRecord } from "@actiondock/sdk";
6
- import type { ServerRuntimeRegistry } from "../runtime-registry";
7
- import type { ServerOptions } from "../types";
8
-
9
- /**
10
- * 路由处理统一上下文对象。
11
- */
12
- export interface RouteContext {
13
- req: Request;
14
- url: URL;
15
- pathname: string;
16
- corsHeaders: Record<string, string>;
17
- projectRoot: string | null;
18
- customHome?: string;
19
- runtimeRegistry: ServerRuntimeRegistry;
20
- options: ServerOptions;
21
- }
22
-
23
- /**
24
- * 辅助函数:构造带 CORS 头的标准 JSON HTTP 响应。
25
- */
26
- export function jsonResponse(
27
- data: unknown,
28
- status = 200,
29
- corsHeaders: Record<string, string> = {}
30
- ): Response {
31
- return new Response(JSON.stringify(data, null, 2), {
32
- status,
33
- headers: {
34
- "Content-Type": "application/json",
35
- ...corsHeaders,
36
- },
37
- });
38
- }
39
-
40
- /**
41
- * 依据 package 参数或项目上下文解析目标 Storage 实例与根目录。
42
- */
43
- export function resolveStorageForPackage(
44
- packageIdOrPath: string | undefined,
45
- runtimeRegistry: ServerRuntimeRegistry,
46
- projectRoot?: string | null,
47
- customHome?: string
48
- ): { packageId: string; storage: RuntimeStorage; projectRoot?: string } {
49
- if (packageIdOrPath) {
50
- const root = resolvePackageRoot(packageIdOrPath, customHome);
51
- if (root) {
52
- const config = loadProjectConfig(root);
53
- return {
54
- packageId: config.id,
55
- storage: runtimeRegistry.getStorage(config.id, root),
56
- projectRoot: root,
57
- };
58
- }
59
- return {
60
- packageId: packageIdOrPath,
61
- storage: runtimeRegistry.getStorage(packageIdOrPath),
62
- };
63
- }
64
-
65
- if (projectRoot) {
66
- const config = loadProjectConfig(projectRoot);
67
- return {
68
- packageId: config.id,
69
- storage: runtimeRegistry.getStorage(config.id, projectRoot),
70
- projectRoot,
71
- };
72
- }
73
-
74
- const linked = listLinkedPackages(customHome);
75
- if (linked.length > 0) {
76
- const first = linked[0];
77
- return {
78
- packageId: first.id,
79
- storage: runtimeRegistry.getStorage(first.id, first.path),
80
- projectRoot: first.path,
81
- };
82
- }
83
-
84
- return {
85
- packageId: "default",
86
- storage: runtimeRegistry.getStorage("default"),
87
- };
88
- }
89
-
90
- /**
91
- * 跨活跃连接与所有已知持久化存储全局检索指定 runId 的运行记录。
92
- */
93
- export function findRunAcrossStorages(
94
- runId: string,
95
- runtimeRegistry: ServerRuntimeRegistry,
96
- projectRoot?: string | null,
97
- customHome?: string
98
- ): { storage: RuntimeStorage; run: RunRecord } | null {
99
- const inMemory = runtimeRegistry.findRun(runId);
100
- if (inMemory) return inMemory as { storage: RuntimeStorage; run: RunRecord };
101
-
102
- if (projectRoot) {
103
- try {
104
- const config = loadProjectConfig(projectRoot);
105
- const storage = runtimeRegistry.getStorage(config.id, projectRoot);
106
- const run = storage.getRun(runId);
107
- if (run) return { storage, run };
108
- } catch {
109
- // 忽略读取错误
110
- }
111
- }
112
-
113
- try {
114
- const linked = listLinkedPackages(customHome);
115
- for (const pkg of linked) {
116
- if (!existsSync(pkg.path)) continue;
117
- const storage = runtimeRegistry.getStorage(pkg.id, pkg.path);
118
- const run = storage.getRun(runId);
119
- if (run) return { storage, run };
120
- }
121
- } catch {
122
- // 忽略读取错误
123
- }
124
-
125
- return null;
126
- }
@@ -1,147 +0,0 @@
1
- import { loadProjectConfig } from "../../project/loader";
2
- import { readJsonBody } from "../body";
3
- import { type RouteContext, jsonResponse, resolveStorageForPackage } from "./common";
4
-
5
- /**
6
- * 处理配置元数据与当前值读取、更新及删除接口。
7
- */
8
- export async function handleConfigRoutes(ctx: RouteContext): Promise<Response | null> {
9
- const { req, url, pathname, corsHeaders, projectRoot, customHome, runtimeRegistry, options } = ctx;
10
-
11
- // 1. Config Env Check: GET /api/v1/config/env
12
- if (pathname === "/api/v1/config/env" && req.method === "GET") {
13
- try {
14
- const pkgParam = url.searchParams.get("package") || undefined;
15
- const { packageId, projectRoot: root } = resolveStorageForPackage(
16
- pkgParam,
17
- runtimeRegistry,
18
- projectRoot,
19
- customHome
20
- );
21
- if (!root) {
22
- return jsonResponse({ ok: true, packageId, envChecks: [] }, 200, corsHeaders);
23
- }
24
- const cfg = loadProjectConfig(root);
25
- const declared = cfg.config || {};
26
- const envChecks: any[] = [];
27
- for (const [k, def] of Object.entries(declared)) {
28
- const envKeys = [
29
- k,
30
- `ACTIONDOCK_${k}`,
31
- `${packageId.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_${k}`,
32
- ];
33
- const foundEnv = envKeys.find((ek) => process.env[ek] !== undefined);
34
- envChecks.push({
35
- key: k,
36
- required: def.default === undefined,
37
- satisfied: Boolean(foundEnv || def.default !== undefined),
38
- matchedEnv: foundEnv || null,
39
- hasDefault: def.default !== undefined,
40
- secret: Boolean(def.secret),
41
- });
42
- }
43
- return jsonResponse({ ok: true, packageId, envChecks }, 200, corsHeaders);
44
- } catch (err: any) {
45
- return jsonResponse(
46
- { ok: false, error: { code: "CONFIG_ENV_ERROR", message: err.message } },
47
- 500,
48
- corsHeaders
49
- );
50
- }
51
- }
52
-
53
- // 2. Config Query: GET /api/v1/config
54
- if (pathname === "/api/v1/config" && req.method === "GET") {
55
- try {
56
- const pkgParam = url.searchParams.get("package") || undefined;
57
- const { packageId, storage, projectRoot: root } = resolveStorageForPackage(
58
- pkgParam,
59
- runtimeRegistry,
60
- projectRoot,
61
- customHome
62
- );
63
- const stored = storage.listConfig();
64
- let declared: Record<string, any> = {};
65
- if (root) {
66
- try {
67
- const cfg = loadProjectConfig(root);
68
- declared = cfg.config || {};
69
- } catch {}
70
- }
71
- const maskedValues: Record<string, any> = {};
72
- for (const [k, v] of Object.entries(stored)) {
73
- if (declared[k]?.secret) {
74
- maskedValues[k] = "******";
75
- } else {
76
- maskedValues[k] = v;
77
- }
78
- }
79
- return jsonResponse(
80
- { ok: true, packageId, declared, values: maskedValues },
81
- 200,
82
- corsHeaders
83
- );
84
- } catch (err: any) {
85
- return jsonResponse(
86
- { ok: false, error: { code: "CONFIG_LIST_ERROR", message: err.message } },
87
- 500,
88
- corsHeaders
89
- );
90
- }
91
- }
92
-
93
- // 3. Config Update: PUT / POST /api/v1/config
94
- if (pathname === "/api/v1/config" && (req.method === "PUT" || req.method === "POST")) {
95
- try {
96
- const body = await readJsonBody(req, { maxBytes: options.maxBodyBytes });
97
- const pkgParam = url.searchParams.get("package") || body.package || undefined;
98
- const { packageId, storage } = resolveStorageForPackage(
99
- pkgParam,
100
- runtimeRegistry,
101
- projectRoot,
102
- customHome
103
- );
104
- const key = body.key;
105
- if (!key) {
106
- return jsonResponse(
107
- { ok: false, error: { code: "INVALID_ARGUMENT", message: "Config 'key' is required" } },
108
- 400,
109
- corsHeaders
110
- );
111
- }
112
- storage.setConfig(key, body.value);
113
- return jsonResponse({ ok: true, packageId, key, message: "updated" }, 200, corsHeaders);
114
- } catch (err: any) {
115
- return jsonResponse(
116
- { ok: false, error: { code: "CONFIG_SET_ERROR", message: err.message } },
117
- 500,
118
- corsHeaders
119
- );
120
- }
121
- }
122
-
123
- // 4. Config Delete: DELETE /api/v1/config/:key
124
- const configKeyMatch = pathname.match(/^\/api\/v1\/config\/([^/]+)$/);
125
- if (configKeyMatch && req.method === "DELETE") {
126
- try {
127
- const key = decodeURIComponent(configKeyMatch[1]);
128
- const pkgParam = url.searchParams.get("package") || undefined;
129
- const { packageId, storage } = resolveStorageForPackage(
130
- pkgParam,
131
- runtimeRegistry,
132
- projectRoot,
133
- customHome
134
- );
135
- const deleted = storage.deleteConfig(key);
136
- return jsonResponse({ ok: true, packageId, key, deleted }, 200, corsHeaders);
137
- } catch (err: any) {
138
- return jsonResponse(
139
- { ok: false, error: { code: "CONFIG_DELETE_ERROR", message: err.message } },
140
- 500,
141
- corsHeaders
142
- );
143
- }
144
- }
145
-
146
- return null;
147
- }
@@ -1,29 +0,0 @@
1
- import { runDoctorChecks } from "../../doctor/doctor";
2
- import { type RouteContext, jsonResponse } from "./common";
3
-
4
- /**
5
- * 处理环境与依赖诊断接口(GET /api/v1/doctor)。
6
- */
7
- export async function handleDoctorRoute(ctx: RouteContext): Promise<Response | null> {
8
- const { req, url, pathname, corsHeaders, projectRoot, customHome } = ctx;
9
-
10
- if (pathname !== "/api/v1/doctor" || req.method !== "GET") {
11
- return null;
12
- }
13
-
14
- try {
15
- const targetPkg = url.searchParams.get("package") || undefined;
16
- const report = await runDoctorChecks({
17
- cwd: projectRoot || process.cwd(),
18
- packageIdOrPath: targetPkg,
19
- customHome,
20
- });
21
- return jsonResponse({ ok: true, report }, 200, corsHeaders);
22
- } catch (err: any) {
23
- return jsonResponse(
24
- { ok: false, error: { code: "DOCTOR_ERROR", message: err.message } },
25
- 500,
26
- corsHeaders
27
- );
28
- }
29
- }
@@ -1,40 +0,0 @@
1
- import { verifyBearerToken } from "../security";
2
- import { type RouteContext, jsonResponse } from "./common";
3
-
4
- /**
5
- * 处理健康检查与就绪状态接口(支持 /api/v1/health 与 /health)。
6
- */
7
- export async function handleHealthRoute(ctx: RouteContext): Promise<Response | null> {
8
- const { req, pathname, corsHeaders, options, projectRoot } = ctx;
9
-
10
- if (pathname !== "/api/v1/health" && pathname !== "/health") {
11
- return null;
12
- }
13
-
14
- if (!verifyBearerToken(req, options.token)) {
15
- return jsonResponse(
16
- {
17
- ok: false,
18
- error: {
19
- code: "UNAUTHORIZED",
20
- message: "Invalid or missing Bearer token",
21
- },
22
- },
23
- 401,
24
- corsHeaders
25
- );
26
- }
27
-
28
- const healthData: Record<string, unknown> = {
29
- status: "ok",
30
- version: "2.0.0",
31
- timestamp: new Date().toISOString(),
32
- uptime: process.uptime(),
33
- };
34
-
35
- if (options.exposeDebugInfo && projectRoot) {
36
- healthData.projectRoot = projectRoot;
37
- }
38
-
39
- return jsonResponse(healthData, 200, corsHeaders);
40
- }