@dezhouzhang/archery-query-mcp 0.1.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.
Files changed (66) hide show
  1. package/README.md +48 -0
  2. package/dist/archeryClient.d.ts +16 -0
  3. package/dist/archeryClient.d.ts.map +1 -0
  4. package/dist/archeryClient.js +207 -0
  5. package/dist/archeryClient.js.map +1 -0
  6. package/dist/archeryHttpSupport.d.ts +8 -0
  7. package/dist/archeryHttpSupport.d.ts.map +1 -0
  8. package/dist/archeryHttpSupport.js +47 -0
  9. package/dist/archeryHttpSupport.js.map +1 -0
  10. package/dist/archeryMappers.d.ts +10 -0
  11. package/dist/archeryMappers.d.ts.map +1 -0
  12. package/dist/archeryMappers.js +205 -0
  13. package/dist/archeryMappers.js.map +1 -0
  14. package/dist/archeryShared.d.ts +32 -0
  15. package/dist/archeryShared.d.ts.map +1 -0
  16. package/dist/archeryShared.js +9 -0
  17. package/dist/archeryShared.js.map +1 -0
  18. package/dist/cli.d.ts +3 -0
  19. package/dist/cli.d.ts.map +1 -0
  20. package/dist/cli.js +38 -0
  21. package/dist/cli.js.map +1 -0
  22. package/dist/clouds.d.ts +9 -0
  23. package/dist/clouds.d.ts.map +1 -0
  24. package/dist/clouds.js +23 -0
  25. package/dist/clouds.js.map +1 -0
  26. package/dist/config.d.ts +30 -0
  27. package/dist/config.d.ts.map +1 -0
  28. package/dist/config.js +75 -0
  29. package/dist/config.js.map +1 -0
  30. package/dist/httpServer.d.ts +9 -0
  31. package/dist/httpServer.d.ts.map +1 -0
  32. package/dist/httpServer.js +87 -0
  33. package/dist/httpServer.js.map +1 -0
  34. package/dist/mcpServer.d.ts +5 -0
  35. package/dist/mcpServer.d.ts.map +1 -0
  36. package/dist/mcpServer.js +22 -0
  37. package/dist/mcpServer.js.map +1 -0
  38. package/dist/policy.d.ts +4 -0
  39. package/dist/policy.d.ts.map +1 -0
  40. package/dist/policy.js +91 -0
  41. package/dist/policy.js.map +1 -0
  42. package/dist/responses.d.ts +31 -0
  43. package/dist/responses.d.ts.map +1 -0
  44. package/dist/responses.js +2 -0
  45. package/dist/responses.js.map +1 -0
  46. package/dist/scope.d.ts +21 -0
  47. package/dist/scope.d.ts.map +1 -0
  48. package/dist/scope.js +44 -0
  49. package/dist/scope.js.map +1 -0
  50. package/dist/services.d.ts +39 -0
  51. package/dist/services.d.ts.map +1 -0
  52. package/dist/services.js +171 -0
  53. package/dist/services.js.map +1 -0
  54. package/dist/store.d.ts +8 -0
  55. package/dist/store.d.ts.map +1 -0
  56. package/dist/store.js +17 -0
  57. package/dist/store.js.map +1 -0
  58. package/dist/tools.d.ts +65 -0
  59. package/dist/tools.d.ts.map +1 -0
  60. package/dist/tools.js +98 -0
  61. package/dist/tools.js.map +1 -0
  62. package/dist/types.d.ts +78 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +2 -0
  65. package/dist/types.js.map +1 -0
  66. package/package.json +37 -0
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { HttpArcheryClient, StubArcheryClient } from "./archeryClient.js";
4
+ import { loadConfig } from "./config.js";
5
+ import { runHttpServer } from "./httpServer.js";
6
+ import { runStdioServer } from "./mcpServer.js";
7
+ import { createServiceContext } from "./services.js";
8
+ const program = new Command()
9
+ .name("archery-query-mcp")
10
+ .description("MCP server for querying Archery safely via stdio or HTTP")
11
+ .option("--transport <transport>", "stdio or http", "stdio")
12
+ .option("--port <port>", "HTTP port", "8080")
13
+ .option("--archery-auth-mode <mode>", "simulated-login or personal-session", "simulated-login")
14
+ .option("--archery-client-mode <mode>", "http-query or stub", "http-query")
15
+ .option("--query-path <path>", "Archery query endpoint path", "/query/")
16
+ .option("--user <subject>", "Authenticated MCP user subject");
17
+ program.parse(process.argv);
18
+ const config = loadConfig(process.env, program.opts());
19
+ const archeryClient = config.clientMode === "stub" ? new StubArcheryClient() : new HttpArcheryClient(config);
20
+ const context = createServiceContext({
21
+ userSubject: config.userSubject,
22
+ policy: config.policy,
23
+ archeryClient,
24
+ });
25
+ // no-excuse-ok: catch
26
+ try {
27
+ if (config.transport === "stdio") {
28
+ await runStdioServer(context);
29
+ }
30
+ else {
31
+ runHttpServer(context, config.port);
32
+ }
33
+ }
34
+ catch (error) {
35
+ console.error(error);
36
+ process.exit(1);
37
+ }
38
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAEpD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE;KAC1B,IAAI,CAAC,mBAAmB,CAAC;KACzB,WAAW,CAAC,0DAA0D,CAAC;KACvE,MAAM,CAAC,yBAAyB,EAAE,eAAe,EAAE,OAAO,CAAC;KAC3D,MAAM,CAAC,eAAe,EAAE,WAAW,EAAE,MAAM,CAAC;KAC5C,MAAM,CAAC,4BAA4B,EAAE,qCAAqC,EAAE,iBAAiB,CAAC;KAC9F,MAAM,CAAC,8BAA8B,EAAE,oBAAoB,EAAE,YAAY,CAAC;KAC1E,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,EAAE,SAAS,CAAC;KACvE,MAAM,CAAC,kBAAkB,EAAE,gCAAgC,CAAC,CAAA;AAE/D,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAE3B,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;AACtD,MAAM,aAAa,GACjB,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAA;AACxF,MAAM,OAAO,GAAG,oBAAoB,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC,WAAW;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,aAAa;CACd,CAAC,CAAA;AAEF,sBAAsB;AACtB,IAAI,CAAC;IACH,IAAI,MAAM,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;IAC/B,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;IACrC,CAAC;AACH,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { CloudName } from "./types.js";
2
+ export declare const CLOUD_BASE_URLS: {
3
+ readonly hangzhou: "https://archery-hangzhou.ihr360.com/";
4
+ readonly beijing: "https://archery-beijing.ihr360.com/";
5
+ readonly huawei: "http://archery-hw.irenshi.net/";
6
+ };
7
+ export declare function parseCloudName(value: string): CloudName | null;
8
+ export declare function supportedCloudNames(): string;
9
+ //# sourceMappingURL=clouds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clouds.d.ts","sourceRoot":"","sources":["../src/clouds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C,eAAO,MAAM,eAAe;;;;CAIkB,CAAA;AAc9C,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAE9D;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
package/dist/clouds.js ADDED
@@ -0,0 +1,23 @@
1
+ export const CLOUD_BASE_URLS = {
2
+ hangzhou: "https://archery-hangzhou.ihr360.com/",
3
+ beijing: "https://archery-beijing.ihr360.com/",
4
+ huawei: "http://archery-hw.irenshi.net/",
5
+ };
6
+ const CLOUD_ALIASES = new Map([
7
+ ["hangzhou", "hangzhou"],
8
+ ["hz", "hangzhou"],
9
+ ["杭州云", "hangzhou"],
10
+ ["beijing", "beijing"],
11
+ ["bj", "beijing"],
12
+ ["北京云", "beijing"],
13
+ ["huawei", "huawei"],
14
+ ["hw", "huawei"],
15
+ ["华为云", "huawei"],
16
+ ]);
17
+ export function parseCloudName(value) {
18
+ return CLOUD_ALIASES.get(value.trim().toLowerCase()) ?? null;
19
+ }
20
+ export function supportedCloudNames() {
21
+ return "hangzhou, beijing, huawei";
22
+ }
23
+ //# sourceMappingURL=clouds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clouds.js","sourceRoot":"","sources":["../src/clouds.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,sCAAsC;IAChD,OAAO,EAAE,qCAAqC;IAC9C,MAAM,EAAE,gCAAgC;CACI,CAAA;AAE9C,MAAM,aAAa,GAAG,IAAI,GAAG,CAAoB;IAC/C,CAAC,UAAU,EAAE,UAAU,CAAC;IACxB,CAAC,IAAI,EAAE,UAAU,CAAC;IAClB,CAAC,KAAK,EAAE,UAAU,CAAC;IACnB,CAAC,SAAS,EAAE,SAAS,CAAC;IACtB,CAAC,IAAI,EAAE,SAAS,CAAC;IACjB,CAAC,KAAK,EAAE,SAAS,CAAC;IAClB,CAAC,QAAQ,EAAE,QAAQ,CAAC;IACpB,CAAC,IAAI,EAAE,QAAQ,CAAC;IAChB,CAAC,KAAK,EAAE,QAAQ,CAAC;CAClB,CAAC,CAAA;AAEF,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,IAAI,IAAI,CAAA;AAC9D,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,2BAA2B,CAAA;AACpC,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+ import type { PolicyConfig } from "./types.js";
3
+ declare const AuthModeSchema: z.ZodUnion<readonly [z.ZodLiteral<"personal-session">, z.ZodLiteral<"simulated-login">]>;
4
+ declare const ClientModeSchema: z.ZodUnion<readonly [z.ZodLiteral<"http-query">, z.ZodLiteral<"stub">]>;
5
+ declare const TransportSchema: z.ZodUnion<readonly [z.ZodLiteral<"stdio">, z.ZodLiteral<"http">]>;
6
+ export type AuthMode = z.infer<typeof AuthModeSchema>;
7
+ export type ClientMode = z.infer<typeof ClientModeSchema>;
8
+ export type TransportMode = z.infer<typeof TransportSchema>;
9
+ export type RuntimeConfig = {
10
+ readonly transport: TransportMode;
11
+ readonly port: number;
12
+ readonly authMode: AuthMode;
13
+ readonly clientMode: ClientMode;
14
+ readonly queryPath: string;
15
+ readonly username: string | null;
16
+ readonly password: string | null;
17
+ readonly userSubject: string;
18
+ readonly policy: PolicyConfig;
19
+ };
20
+ export type CliOptions = {
21
+ readonly transport?: string;
22
+ readonly port?: string | number;
23
+ readonly archeryAuthMode?: string;
24
+ readonly archeryClientMode?: string;
25
+ readonly queryPath?: string;
26
+ readonly user?: string;
27
+ };
28
+ export declare function loadConfig(env: NodeJS.ProcessEnv, options: CliOptions): RuntimeConfig;
29
+ export {};
30
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,QAAA,MAAM,cAAc,0FAAyE,CAAA;AAC7F,QAAA,MAAM,gBAAgB,yEAAwD,CAAA;AAC9E,QAAA,MAAM,eAAe,oEAAmD,CAAA;AAiBxE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AACrD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACzD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAE3D,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAA;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAA;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAC9B,CAAA;AAmBD,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC/B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,aAAa,CAiCrF"}
package/dist/config.js ADDED
@@ -0,0 +1,75 @@
1
+ import { z } from "zod";
2
+ const AuthModeSchema = z.union([z.literal("personal-session"), z.literal("simulated-login")]);
3
+ const ClientModeSchema = z.union([z.literal("http-query"), z.literal("stub")]);
4
+ const TransportSchema = z.union([z.literal("stdio"), z.literal("http")]);
5
+ const EnvBooleanSchema = z
6
+ .preprocess((value) => {
7
+ if (typeof value !== "string") {
8
+ return value;
9
+ }
10
+ const normalized = value.trim().toLowerCase();
11
+ if (["true", "1", "yes", "y", "on"].includes(normalized)) {
12
+ return true;
13
+ }
14
+ if (["false", "0", "no", "n", "off"].includes(normalized)) {
15
+ return false;
16
+ }
17
+ return value;
18
+ }, z.boolean())
19
+ .default(true);
20
+ const CsvSchema = z
21
+ .string()
22
+ .optional()
23
+ .transform((value) => new Set(splitCsv(value)));
24
+ const EnvSchema = z.object({
25
+ MCP_ARCHERY_LOGIN_USERNAME: z.string().optional(),
26
+ MCP_ARCHERY_LOGIN_PASSWORD: z.string().optional(),
27
+ MCP_AUTHENTICATED_USER: z.string().optional(),
28
+ ARCHERY_QUERY_DEFAULT_LIMIT: z.coerce.number().int().min(1).default(100),
29
+ ARCHERY_QUERY_MAX_LIMIT: z.coerce.number().int().min(1).default(500),
30
+ ARCHERY_QUERY_REQUIRE_CONFIRMATION: EnvBooleanSchema,
31
+ ARCHERY_QUERY_ALLOWED_INSTANCES: CsvSchema,
32
+ ARCHERY_QUERY_ALLOWED_DATABASES: CsvSchema,
33
+ ARCHERY_QUERY_BLOCKED_TABLES: CsvSchema,
34
+ });
35
+ export function loadConfig(env, options) {
36
+ const parsedEnv = EnvSchema.parse(env);
37
+ const transport = TransportSchema.parse(options.transport ?? "stdio");
38
+ const authMode = AuthModeSchema.parse(options.archeryAuthMode ?? "simulated-login");
39
+ const clientMode = ClientModeSchema.parse(options.archeryClientMode ?? "http-query");
40
+ const port = z.coerce
41
+ .number()
42
+ .int()
43
+ .min(1)
44
+ .max(65535)
45
+ .parse(options.port ?? 8080);
46
+ const maxLimit = Math.max(parsedEnv.ARCHERY_QUERY_MAX_LIMIT, parsedEnv.ARCHERY_QUERY_DEFAULT_LIMIT);
47
+ return {
48
+ transport,
49
+ port,
50
+ authMode,
51
+ clientMode,
52
+ queryPath: options.queryPath ?? "/query/",
53
+ username: parsedEnv.MCP_ARCHERY_LOGIN_USERNAME ?? null,
54
+ password: parsedEnv.MCP_ARCHERY_LOGIN_PASSWORD ?? null,
55
+ userSubject: options.user ?? parsedEnv.MCP_AUTHENTICATED_USER ?? "local-user",
56
+ policy: {
57
+ defaultLimit: parsedEnv.ARCHERY_QUERY_DEFAULT_LIMIT,
58
+ maxLimit,
59
+ requireConfirmation: parsedEnv.ARCHERY_QUERY_REQUIRE_CONFIRMATION,
60
+ allowedInstances: parsedEnv.ARCHERY_QUERY_ALLOWED_INSTANCES,
61
+ allowedDatabases: parsedEnv.ARCHERY_QUERY_ALLOWED_DATABASES,
62
+ blockedTables: parsedEnv.ARCHERY_QUERY_BLOCKED_TABLES,
63
+ },
64
+ };
65
+ }
66
+ function splitCsv(value) {
67
+ if (value === undefined || value.trim() === "") {
68
+ return [];
69
+ }
70
+ return value
71
+ .split(",")
72
+ .map((item) => item.trim())
73
+ .filter((item) => item.length > 0);
74
+ }
75
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { Hono } from "hono";
2
+ import type { ServiceContext } from "./services.js";
3
+ import type { JsonObject } from "./types.js";
4
+ type JsonRpcId = string | number | null;
5
+ export declare function createHttpApp(context: ServiceContext): Hono;
6
+ export declare function runHttpServer(context: ServiceContext, port: number): void;
7
+ export declare function handleJsonRpc(context: ServiceContext, id: JsonRpcId, method: string, params: unknown): Promise<JsonObject>;
8
+ export {};
9
+ //# sourceMappingURL=httpServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpServer.d.ts","sourceRoot":"","sources":["../src/httpServer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAA;AASvD,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAEvC,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAwB3D;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAEzE;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,cAAc,EACvB,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,UAAU,CAAC,CAkBrB"}
@@ -0,0 +1,87 @@
1
+ import { serve } from "@hono/node-server";
2
+ import { Hono } from "hono";
3
+ import { z } from "zod";
4
+ import { callTool, toolDefinitions, UnknownToolError } from "./tools.js";
5
+ const JsonRpcRequestSchema = z.object({
6
+ jsonrpc: z.string().optional(),
7
+ id: z.union([z.string(), z.number(), z.null()]).optional().default(null),
8
+ method: z.string(),
9
+ params: z.unknown().optional(),
10
+ });
11
+ export function createHttpApp(context) {
12
+ const app = new Hono();
13
+ app.post("/mcp", async (c) => {
14
+ let body;
15
+ try {
16
+ body = await c.req.json();
17
+ }
18
+ catch (errorValue) {
19
+ if (errorValue instanceof SyntaxError) {
20
+ return jsonResponse(error(null, -32700, "Parse error"));
21
+ }
22
+ throw errorValue;
23
+ }
24
+ const request = JsonRpcRequestSchema.safeParse(body);
25
+ if (!request.success) {
26
+ return jsonResponse(error(null, -32600, "Invalid Request"));
27
+ }
28
+ if (request.data.method.startsWith("notifications/")) {
29
+ return new Response(null, { status: 204 });
30
+ }
31
+ return jsonResponse(await handleJsonRpc(context, request.data.id, request.data.method, request.data.params));
32
+ });
33
+ return app;
34
+ }
35
+ export function runHttpServer(context, port) {
36
+ serve({ fetch: createHttpApp(context).fetch, port });
37
+ }
38
+ export async function handleJsonRpc(context, id, method, params) {
39
+ if (method === "initialize") {
40
+ return result(id, {
41
+ protocolVersion: "2025-03-26",
42
+ capabilities: { tools: {} },
43
+ serverInfo: { name: "archery-query-mcp", version: "0.1.0" },
44
+ });
45
+ }
46
+ if (method === "tools/list") {
47
+ return result(id, { tools: toolDefinitions() });
48
+ }
49
+ if (method === "tools/call") {
50
+ return callToolRpc(context, id, params);
51
+ }
52
+ if (method.startsWith("notifications/")) {
53
+ return result(id, {});
54
+ }
55
+ return error(id, -32601, `Unknown MCP method: ${method}`);
56
+ }
57
+ async function callToolRpc(context, id, params) {
58
+ try {
59
+ const parsed = z
60
+ .object({ name: z.string(), arguments: z.unknown().optional().default({}) })
61
+ .parse(params);
62
+ const payload = await callTool(context, parsed.name, parsed.arguments);
63
+ return result(id, { content: [{ type: "text", text: JSON.stringify(payload) }] });
64
+ }
65
+ catch (errorValue) {
66
+ if (errorValue instanceof UnknownToolError) {
67
+ return error(id, -32602, errorValue.message);
68
+ }
69
+ if (errorValue instanceof z.ZodError) {
70
+ return error(id, -32602, "Invalid tool arguments");
71
+ }
72
+ throw errorValue;
73
+ }
74
+ }
75
+ function result(id, payload) {
76
+ return { jsonrpc: "2.0", id, result: payload };
77
+ }
78
+ function error(id, code, message) {
79
+ return { jsonrpc: "2.0", id, error: { code, message } };
80
+ }
81
+ function jsonResponse(payload) {
82
+ return new Response(JSON.stringify(payload), {
83
+ status: 200,
84
+ headers: { "Content-Type": "application/json" },
85
+ });
86
+ }
87
+ //# sourceMappingURL=httpServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpServer.js","sourceRoot":"","sources":["../src/httpServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ServiceContext } from "./services.js";
3
+ export declare function createMcpServer(context: ServiceContext): McpServer;
4
+ export declare function runStdioServer(context: ServiceContext): Promise<void>;
5
+ //# sourceMappingURL=mcpServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpServer.d.ts","sourceRoot":"","sources":["../src/mcpServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAGnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AASnD,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,CA+BlE;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E"}
@@ -0,0 +1,22 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { callTool, DescribeTableShape, ExecuteQueryShape, PrepareQueryShape, QueryHistoryShape, } from "./tools.js";
4
+ export function createMcpServer(context) {
5
+ const server = new McpServer({ name: "archery-query-mcp", version: "0.1.0" });
6
+ registerJsonTool(server, context, "archery_prepare_query", "Validate and prepare a read-only SQL query for Archery execution", PrepareQueryShape);
7
+ registerJsonTool(server, context, "archery_execute_query", "Execute a prepared query through Archery", ExecuteQueryShape);
8
+ registerJsonTool(server, context, "archery_describe_table", "Read table metadata through Archery", DescribeTableShape);
9
+ registerJsonTool(server, context, "archery_query_history", "Search prior query history summaries", QueryHistoryShape);
10
+ return server;
11
+ }
12
+ export async function runStdioServer(context) {
13
+ const server = createMcpServer(context);
14
+ await server.connect(new StdioServerTransport());
15
+ }
16
+ function registerJsonTool(server, context, name, description, inputSchema) {
17
+ server.registerTool(name, { description, inputSchema }, async (args) => {
18
+ const payload = await callTool(context, name, args);
19
+ return { content: [{ type: "text", text: JSON.stringify(payload) }] };
20
+ });
21
+ }
22
+ //# sourceMappingURL=mcpServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpServer.js","sourceRoot":"","sources":["../src/mcpServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAGhF,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,YAAY,CAAA;AAEnB,MAAM,UAAU,eAAe,CAAC,OAAuB;IACrD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;IAC7E,gBAAgB,CACd,MAAM,EACN,OAAO,EACP,uBAAuB,EACvB,kEAAkE,EAClE,iBAAiB,CAClB,CAAA;IACD,gBAAgB,CACd,MAAM,EACN,OAAO,EACP,uBAAuB,EACvB,0CAA0C,EAC1C,iBAAiB,CAClB,CAAA;IACD,gBAAgB,CACd,MAAM,EACN,OAAO,EACP,wBAAwB,EACxB,qCAAqC,EACrC,kBAAkB,CACnB,CAAA;IACD,gBAAgB,CACd,MAAM,EACN,OAAO,EACP,uBAAuB,EACvB,sCAAsC,EACtC,iBAAiB,CAClB,CAAA;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB;IAC1D,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAA;AAClD,CAAC;AAED,SAAS,gBAAgB,CACvB,MAAiB,EACjB,OAAuB,EACvB,IAAY,EACZ,WAAmB,EACnB,WAA0B;IAE1B,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACrE,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QACnD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAA;IAChF,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { PolicyConfig, PolicyDecision } from "./types.js";
2
+ export declare function validateSql(config: PolicyConfig, instanceName: string, dbName: string, sql: string, requestedLimit: number): PolicyDecision;
3
+ export declare function sqlHash(sql: string): string;
4
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAiB,MAAM,YAAY,CAAA;AAU7E,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,MAAM,GACrB,cAAc,CAoDhB;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C"}
package/dist/policy.js ADDED
@@ -0,0 +1,91 @@
1
+ import { createHash } from "node:crypto";
2
+ const WRITE_OR_DDL = /\b(insert|update|delete|merge|replace|create|alter|drop|truncate|grant|revoke)\b/i;
3
+ const SESSION_OR_EXPORT = /\b(set|reset|use|into\s+outfile|into\s+dumpfile|load_file|xp_cmdshell)\b/i;
4
+ const LIMIT_PATTERN = /\blimit\s+(\d+)\b/i;
5
+ const CONSERVATIVE_SELECT = /^select\s+[a-z0-9_.,\s`]+\s+from\s+[a-z0-9_`]+(?:\s+where\s+[a-z0-9_`]+\s*=\s*(?:\?|[-]?[0-9]+|'[^']*'))?(?:\s+limit\s+\d+)?$/i;
6
+ export function validateSql(config, instanceName, dbName, sql, requestedLimit) {
7
+ const findings = [];
8
+ let normalizedSql = normalizeSql(sql);
9
+ const lower = normalizedSql.toLowerCase();
10
+ if (normalizedSql.length === 0) {
11
+ findings.push({ code: "EMPTY_SQL", message: "SQL must not be empty" });
12
+ }
13
+ if (containsMultipleStatements(normalizedSql)) {
14
+ findings.push({ code: "MULTI_STATEMENT", message: "Multiple SQL statements are not allowed" });
15
+ }
16
+ if (!lower.startsWith("select") && !lower.startsWith("show") && !lower.startsWith("explain")) {
17
+ findings.push({ code: "NON_READ", message: "Only read-oriented SQL is allowed" });
18
+ }
19
+ if (WRITE_OR_DDL.test(normalizedSql)) {
20
+ findings.push({ code: "WRITE_OR_DDL", message: "Write and DDL statements are blocked" });
21
+ }
22
+ if (SESSION_OR_EXPORT.test(normalizedSql)) {
23
+ findings.push({
24
+ code: "SESSION_OR_EXPORT",
25
+ message: "Session changes and file export operations are blocked",
26
+ });
27
+ }
28
+ if (config.allowedInstances.size > 0 && !config.allowedInstances.has(instanceName)) {
29
+ findings.push({
30
+ code: "INSTANCE_NOT_ALLOWED",
31
+ message: "Instance is outside the configured allowlist",
32
+ });
33
+ }
34
+ if (config.allowedDatabases.size > 0 && !config.allowedDatabases.has(dbName)) {
35
+ findings.push({
36
+ code: "DATABASE_NOT_ALLOWED",
37
+ message: "Database is outside the configured allowlist",
38
+ });
39
+ }
40
+ for (const blockedTable of config.blockedTables) {
41
+ if (blockedTable.trim().length > 0 && lower.includes(blockedTable.toLowerCase())) {
42
+ findings.push({ code: "BLOCKED_TABLE", message: "SQL references a blocked table" });
43
+ }
44
+ }
45
+ const effectiveLimit = requestedLimit <= 0 ? config.defaultLimit : Math.min(requestedLimit, config.maxLimit);
46
+ if (!LIMIT_PATTERN.test(normalizedSql) && lower.startsWith("select")) {
47
+ normalizedSql = `${normalizedSql} LIMIT ${effectiveLimit}`;
48
+ }
49
+ const allowed = findings.length === 0;
50
+ return {
51
+ allowed,
52
+ normalizedSql,
53
+ effectiveLimit,
54
+ riskLevel: allowed ? riskLevel(normalizedSql) : "blocked",
55
+ findings,
56
+ };
57
+ }
58
+ export function sqlHash(sql) {
59
+ return `sha256:${createHash("sha256").update(sql, "utf8").digest("hex")}`;
60
+ }
61
+ function normalizeSql(sql) {
62
+ return sql.trim().replace(/\s+/g, " ").replace(/;+$/g, "");
63
+ }
64
+ function containsMultipleStatements(sql) {
65
+ return sql.trim().replace(/;+$/g, "").includes(";");
66
+ }
67
+ function riskLevel(normalizedSql) {
68
+ const lower = normalizedSql.toLowerCase();
69
+ if (lower.startsWith("show") || lower.startsWith("explain")) {
70
+ return "low";
71
+ }
72
+ if (!lower.startsWith("select")) {
73
+ return "medium";
74
+ }
75
+ if (containsBroaderReadPattern(lower)) {
76
+ return "medium";
77
+ }
78
+ return CONSERVATIVE_SELECT.test(normalizedSql) ? "low" : "medium";
79
+ }
80
+ function containsBroaderReadPattern(lower) {
81
+ return (lower.includes(" join ") ||
82
+ lower.includes(" union ") ||
83
+ lower.includes(" group by ") ||
84
+ lower.includes(" order by ") ||
85
+ lower.includes(" having ") ||
86
+ lower.includes(" distinct ") ||
87
+ lower.includes("(") ||
88
+ lower.includes(")") ||
89
+ !lower.includes(" where "));
90
+ }
91
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { HistoryMatch, JsonObject, PolicyFinding, TableColumn } from "./types.js";
2
+ export type PrepareQueryResponse = {
3
+ readonly prepareId: string | null;
4
+ readonly normalizedSql: string;
5
+ readonly riskLevel: string;
6
+ readonly requiresConfirmation: boolean;
7
+ readonly policyFindings: readonly PolicyFinding[];
8
+ readonly confirmationSummary: string;
9
+ };
10
+ export type ExecuteQueryResponse = {
11
+ readonly executionId: string;
12
+ readonly status: string;
13
+ readonly columns: readonly string[];
14
+ readonly rows: readonly JsonObject[];
15
+ readonly rowCount: number;
16
+ readonly durationMs: number;
17
+ readonly masked: boolean;
18
+ readonly archeryMessage: string;
19
+ readonly archeryQueryLogId: string | null;
20
+ };
21
+ export type DescribeTableResponse = {
22
+ readonly columns: readonly TableColumn[];
23
+ readonly source: string;
24
+ };
25
+ export type QueryHistoryResponse = {
26
+ readonly matches: readonly HistoryMatch[];
27
+ readonly total: number;
28
+ readonly truncated: boolean;
29
+ readonly status: string;
30
+ };
31
+ //# sourceMappingURL=responses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../src/responses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAEtF,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAA;IACtC,QAAQ,CAAC,cAAc,EAAE,SAAS,aAAa,EAAE,CAAA;IACjD,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,QAAQ,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,CAAA;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1C,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAA;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=responses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.js","sourceRoot":"","sources":["../src/responses.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import type { QueryScope } from "./types.js";
2
+ export type QueryScopeInput = {
3
+ readonly cloudName?: string;
4
+ readonly instanceName?: string;
5
+ readonly dbName?: string;
6
+ };
7
+ export type ScopeResolutionResult = {
8
+ readonly ok: true;
9
+ readonly scope: QueryScope;
10
+ } | {
11
+ readonly ok: false;
12
+ readonly code: "missing_scope";
13
+ readonly message: string;
14
+ };
15
+ export declare class QueryScopeStore {
16
+ #private;
17
+ bind(user: string, scope: QueryScope): void;
18
+ find(user: string): QueryScope | null;
19
+ }
20
+ export declare function resolveScope(store: QueryScopeStore, user: string, input: QueryScopeInput): ScopeResolutionResult;
21
+ //# sourceMappingURL=scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpF,qBAAa,eAAe;;IAG1B,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAI3C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;CAGtC;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,eAAe,GACrB,qBAAqB,CAmCvB"}
package/dist/scope.js ADDED
@@ -0,0 +1,44 @@
1
+ import { parseCloudName, supportedCloudNames } from "./clouds.js";
2
+ export class QueryScopeStore {
3
+ #scopes = new Map();
4
+ bind(user, scope) {
5
+ this.#scopes.set(user, scope);
6
+ }
7
+ find(user) {
8
+ return this.#scopes.get(user) ?? null;
9
+ }
10
+ }
11
+ export function resolveScope(store, user, input) {
12
+ const cloudName = input.cloudName?.trim() ?? "";
13
+ const instanceName = input.instanceName?.trim() ?? "";
14
+ const dbName = input.dbName?.trim() ?? "";
15
+ const explicitFieldCount = [cloudName, instanceName, dbName].filter((value) => value.length > 0).length;
16
+ if (explicitFieldCount === 3) {
17
+ const canonicalCloudName = parseCloudName(cloudName);
18
+ if (canonicalCloudName === null) {
19
+ return {
20
+ ok: false,
21
+ code: "missing_scope",
22
+ message: `Unsupported cloudName; provide one of ${supportedCloudNames()} with instanceName and dbName`,
23
+ };
24
+ }
25
+ return { ok: true, scope: { cloudName: canonicalCloudName, instanceName, dbName } };
26
+ }
27
+ if (explicitFieldCount > 0) {
28
+ return {
29
+ ok: false,
30
+ code: "missing_scope",
31
+ message: "Provide cloudName, instanceName, and dbName together, or omit all three to reuse the current session scope",
32
+ };
33
+ }
34
+ const boundScope = store.find(user);
35
+ if (boundScope === null) {
36
+ return {
37
+ ok: false,
38
+ code: "missing_scope",
39
+ message: "No active session scope is bound; provide cloudName, instanceName, and dbName",
40
+ };
41
+ }
42
+ return { ok: true, scope: boundScope };
43
+ }
44
+ //# sourceMappingURL=scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAajE,MAAM,OAAO,eAAe;IACjB,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAA;IAEhD,IAAI,CAAC,IAAY,EAAE,KAAiB;QAClC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI,CAAC,IAAY;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAA;IACvC,CAAC;CACF;AAED,MAAM,UAAU,YAAY,CAC1B,KAAsB,EACtB,IAAY,EACZ,KAAsB;IAEtB,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;IAC/C,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;IACrD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;IACzC,MAAM,kBAAkB,GAAG,CAAC,SAAS,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC,MAAM,CACjE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAC5B,CAAC,MAAM,CAAA;IACR,IAAI,kBAAkB,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,kBAAkB,GAAG,cAAc,CAAC,SAAS,CAAC,CAAA;QACpD,IAAI,kBAAkB,KAAK,IAAI,EAAE,CAAC;YAChC,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,yCAAyC,mBAAmB,EAAE,+BAA+B;aACvG,CAAA;QACH,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,CAAA;IACrF,CAAC;IACD,IAAI,kBAAkB,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,eAAe;YACrB,OAAO,EACL,4GAA4G;SAC/G,CAAA;IACH,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,+EAA+E;SACzF,CAAA;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;AACxC,CAAC"}