@heddleagent/execution-host-client 7.0.0 → 8.0.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 +48 -34
- package/dist/cli/hostctl.d.ts +11 -0
- package/dist/cli/hostctl.d.ts.map +1 -0
- package/dist/cli/hostctl.js +49 -0
- package/dist/cli/hostctl.js.map +1 -0
- package/dist/contracts/index.d.ts +2 -0
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +9 -0
- package/dist/contracts/index.js.map +1 -1
- package/dist/coordinator/contracts.d.ts +148 -5
- package/dist/coordinator/contracts.d.ts.map +1 -1
- package/dist/coordinator/contracts.js +74 -3
- package/dist/coordinator/contracts.js.map +1 -1
- package/dist/coordinator/hosted-heartbeat-execution-client.d.ts +30 -0
- package/dist/coordinator/hosted-heartbeat-execution-client.d.ts.map +1 -0
- package/dist/coordinator/hosted-heartbeat-execution-client.js +240 -0
- package/dist/coordinator/hosted-heartbeat-execution-client.js.map +1 -0
- package/dist/coordinator/hosted-heartbeat-execution-service.d.ts +14 -0
- package/dist/coordinator/hosted-heartbeat-execution-service.d.ts.map +1 -0
- package/dist/coordinator/hosted-heartbeat-execution-service.js +100 -0
- package/dist/coordinator/hosted-heartbeat-execution-service.js.map +1 -0
- package/dist/coordinator/index.d.ts +5 -5
- package/dist/coordinator/index.d.ts.map +1 -1
- package/dist/coordinator/index.js +3 -3
- package/dist/coordinator/index.js.map +1 -1
- package/dist/coordinator/node/execution-http-service.d.ts +11 -0
- package/dist/coordinator/node/execution-http-service.d.ts.map +1 -0
- package/dist/coordinator/node/{delegation-http-service.js → execution-http-service.js} +52 -39
- package/dist/coordinator/node/execution-http-service.js.map +1 -0
- package/dist/coordinator/node/index.d.ts +2 -2
- package/dist/coordinator/node/index.d.ts.map +1 -1
- package/dist/coordinator/node/index.js +1 -1
- package/dist/coordinator/node/index.js.map +1 -1
- package/dist/coordinator/node/types.d.ts +10 -9
- package/dist/coordinator/node/types.d.ts.map +1 -1
- package/dist/coordinator/node/types.js.map +1 -1
- package/dist/coordinator/types.d.ts +51 -13
- package/dist/coordinator/types.d.ts.map +1 -1
- package/dist/coordinator/types.js.map +1 -1
- package/dist/host/schemas.d.ts.map +1 -1
- package/dist/host/schemas.js +2 -7
- package/dist/host/schemas.js.map +1 -1
- package/dist/http-sse/direct-http-execution-host.d.ts.map +1 -1
- package/dist/http-sse/direct-http-execution-host.js +6 -5
- package/dist/http-sse/direct-http-execution-host.js.map +1 -1
- package/dist/http-sse/types.d.ts +2 -0
- package/dist/http-sse/types.d.ts.map +1 -1
- package/dist/http-sse/types.js.map +1 -1
- package/dist/node/authority-key.d.ts.map +1 -1
- package/dist/node/authority-key.js +24 -49
- package/dist/node/authority-key.js.map +1 -1
- package/dist/node/environment-value.d.ts +17 -0
- package/dist/node/environment-value.d.ts.map +1 -0
- package/dist/node/environment-value.js +78 -0
- package/dist/node/environment-value.js.map +1 -0
- package/dist/node/index.d.ts +4 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +2 -0
- package/dist/node/index.js.map +1 -1
- package/dist/node/local-credential-bundle.d.ts +33 -0
- package/dist/node/local-credential-bundle.d.ts.map +1 -0
- package/dist/node/local-credential-bundle.js +196 -0
- package/dist/node/local-credential-bundle.js.map +1 -0
- package/dist/node/owner-only-file.d.ts +17 -0
- package/dist/node/owner-only-file.d.ts.map +1 -0
- package/dist/node/owner-only-file.js +59 -0
- package/dist/node/owner-only-file.js.map +1 -0
- package/package.json +5 -1
- package/dist/coordinator/hosted-heartbeat-delegation-client.d.ts +0 -21
- package/dist/coordinator/hosted-heartbeat-delegation-client.d.ts.map +0 -1
- package/dist/coordinator/hosted-heartbeat-delegation-client.js +0 -117
- package/dist/coordinator/hosted-heartbeat-delegation-client.js.map +0 -1
- package/dist/coordinator/hosted-heartbeat-delegation-service.d.ts +0 -15
- package/dist/coordinator/hosted-heartbeat-delegation-service.d.ts.map +0 -1
- package/dist/coordinator/hosted-heartbeat-delegation-service.js +0 -81
- package/dist/coordinator/hosted-heartbeat-delegation-service.js.map +0 -1
- package/dist/coordinator/node/delegation-http-service.d.ts +0 -11
- package/dist/coordinator/node/delegation-http-service.d.ts.map +0 -1
- package/dist/coordinator/node/delegation-http-service.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { AGENTCORE_RUNTIME_SESSION_HEADER, CONVERSATION_TURN_WORKFLOW, EXECUTION_ASSERTION_HEADER, EXECUTION_CONTRACT_VERSION, EXECUTION_HOST_LOCAL_TOKEN_HEADER, ExecutionHostConversationTurnRequestSchema, ExecutionHostHeartbeatStreamEventSchema, ExecutionHostHeartbeatTaskRequestSchema, ExecutionHostModelCredentialSchema, ExecutionHostStreamEventSchema, HEARTBEAT_TASK_WORKFLOW, MCP_CAPABILITY_HEADER, MODEL_CREDENTIAL_HEADER, OpaqueIdSchema, RuntimeSessionIdSchema, TimestampSchema, isExecutionHostHeartbeatTerminalEvent, isExecutionHostTerminalEvent, isSafeWebUrl, } from '../contracts/index.js';
|
|
2
|
+
import { AGENTCORE_RUNTIME_SESSION_HEADER, CONVERSATION_TURN_WORKFLOW, EXECUTION_ASSERTION_HEADER, EXECUTION_CONTRACT_VERSION, EXECUTION_HOST_LOCAL_TOKEN_HEADER, ExecutionHostConversationTurnRequestSchema, ExecutionHostHeartbeatStreamEventSchema, ExecutionHostHeartbeatTaskRequestSchema, ExecutionHostModelCredentialSchema, ExecutionHostStreamEventSchema, HEARTBEAT_TASK_WORKFLOW, MCP_CAPABILITY_HEADER, MODEL_CREDENTIAL_HEADER, OpaqueIdSchema, RuntimeSessionIdSchema, TimestampSchema, isExecutionHostHeartbeatTerminalEvent, isExecutionHostTerminalEvent, isDockerLocalWebUrl, isSafeWebUrl, } from '../contracts/index.js';
|
|
3
3
|
import { ExecutionHostInvocationCancelledError, ExecutionHostRejectedError, } from './errors.js';
|
|
4
4
|
import { readExecutionHostEventStream, toExecutionHostTransportError, } from '../internal/execution-host-event-stream.js';
|
|
5
5
|
import { readBoundedJsonResponse } from '../internal/http-response.js';
|
|
@@ -36,7 +36,7 @@ export class DirectHttpExecutionHost {
|
|
|
36
36
|
#fetch;
|
|
37
37
|
#localToken;
|
|
38
38
|
constructor(config) {
|
|
39
|
-
assertSafeBaseUrl(config.baseUrl);
|
|
39
|
+
assertSafeBaseUrl(config.baseUrl, config.allowDockerLocalHost === true);
|
|
40
40
|
this.#localToken = SecretSchema.parse(config.localToken);
|
|
41
41
|
this.#endpoint = new URL('invocations', withTrailingSlash(config.baseUrl));
|
|
42
42
|
this.#fetch = config.fetch ?? globalThis.fetch;
|
|
@@ -132,9 +132,10 @@ async function readSafeErrorCode(response) {
|
|
|
132
132
|
return 'unknown';
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
|
-
function assertSafeBaseUrl(url) {
|
|
136
|
-
if (!isSafeWebUrl(url)
|
|
137
|
-
|
|
135
|
+
function assertSafeBaseUrl(url, allowDockerLocalHost) {
|
|
136
|
+
if (!isSafeWebUrl(url)
|
|
137
|
+
&& !(allowDockerLocalHost && isDockerLocalWebUrl(url))) {
|
|
138
|
+
throw new Error('Direct Execution Host URL must use HTTPS or loopback HTTP; Docker local-host HTTP requires an explicit opt-in; URLs must contain no credentials, query, or fragment.');
|
|
138
139
|
}
|
|
139
140
|
}
|
|
140
141
|
function withTrailingSlash(url) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"direct-http-execution-host.js","sourceRoot":"","sources":["../../src/http-sse/direct-http-execution-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n AGENTCORE_RUNTIME_SESSION_HEADER,\n CONVERSATION_TURN_WORKFLOW,\n EXECUTION_ASSERTION_HEADER,\n EXECUTION_CONTRACT_VERSION,\n EXECUTION_HOST_LOCAL_TOKEN_HEADER,\n ExecutionHostConversationTurnRequestSchema,\n ExecutionHostHeartbeatStreamEventSchema,\n ExecutionHostHeartbeatTaskRequestSchema,\n ExecutionHostModelCredentialSchema,\n ExecutionHostStreamEventSchema,\n HEARTBEAT_TASK_WORKFLOW,\n MCP_CAPABILITY_HEADER,\n MODEL_CREDENTIAL_HEADER,\n OpaqueIdSchema,\n RuntimeSessionIdSchema,\n TimestampSchema,\n isExecutionHostHeartbeatTerminalEvent,\n isExecutionHostTerminalEvent,\n isSafeWebUrl,\n type ExecutionHostHeartbeatStreamEvent,\n type ExecutionHostStreamEvent,\n} from '../contracts/index.js';\nimport {\n ExecutionHostInvocationCancelledError,\n ExecutionHostRejectedError,\n} from './errors.js';\nimport type {\n DirectHttpExecutionHostConfig,\n ExecutionHost,\n ExecutionHostConversationTurn,\n ExecutionHostHeartbeatTask,\n HeartbeatExecutionHost,\n} from './types.js';\nimport {\n readExecutionHostEventStream,\n toExecutionHostTransportError,\n} from '../internal/execution-host-event-stream.js';\nimport { readBoundedJsonResponse } from '../internal/http-response.js';\n\nconst MAX_ERROR_BODY_BYTES = 16_384;\nconst SecretSchema = z.string().min(8).max(4_096);\nconst InvocationAuthoritySchema = z.object({\n runtimeSessionId: RuntimeSessionIdSchema,\n executionAssertion: z.string().min(32).max(4_096),\n mcpCapability: z.string().min(32).max(4_096).optional(),\n modelCredential: ExecutionHostModelCredentialSchema,\n signal: z.custom<AbortSignal>(\n (value) => value instanceof AbortSignal,\n 'signal must be an AbortSignal',\n ).optional(),\n}).strict();\nconst ConversationTurnSchema = InvocationAuthoritySchema.extend({\n invocationId: OpaqueIdSchema,\n prompt: z.string().trim().min(1).max(200_000),\n deadlineAt: TimestampSchema.optional(),\n}).strict();\nconst HeartbeatTaskSchema = InvocationAuthoritySchema.extend(\n ExecutionHostHeartbeatTaskRequestSchema.omit({\n schemaVersion: true,\n kind: true,\n }).shape,\n).strict();\nconst ApiErrorSchema = z.object({\n error: z.object({\n code: z.string().min(1).max(128).regex(/^[a-z0-9_]+$/),\n message: z.string(),\n }).strict(),\n}).strict();\n\n/**\n * Strict direct-development HTTP/SSE adapter for the Execution Host v1 wire.\n * It deliberately owns neither AWS SDK nor SigV4 behavior.\n */\nexport class DirectHttpExecutionHost\nimplements ExecutionHost, HeartbeatExecutionHost {\n readonly #endpoint: URL;\n readonly #fetch: typeof fetch;\n readonly #localToken: string;\n\n constructor(config: DirectHttpExecutionHostConfig) {\n assertSafeBaseUrl(config.baseUrl);\n this.#localToken = SecretSchema.parse(config.localToken);\n this.#endpoint = new URL('invocations', withTrailingSlash(config.baseUrl));\n this.#fetch = config.fetch ?? globalThis.fetch;\n }\n\n async *streamConversationTurn(\n rawInput: ExecutionHostConversationTurn,\n ): AsyncIterable<ExecutionHostStreamEvent> {\n const input = ConversationTurnSchema.parse(rawInput);\n if (input.signal?.aborted) {\n throw new ExecutionHostInvocationCancelledError();\n }\n const body = ExecutionHostConversationTurnRequestSchema.parse({\n schemaVersion: EXECUTION_CONTRACT_VERSION,\n kind: CONVERSATION_TURN_WORKFLOW,\n invocationId: input.invocationId,\n prompt: input.prompt,\n ...(input.deadlineAt ? { deadlineAt: input.deadlineAt } : {}),\n });\n yield* this.#streamInvocation(\n input,\n body,\n ExecutionHostStreamEventSchema,\n isExecutionHostTerminalEvent,\n );\n }\n\n async *streamHeartbeatTask(\n rawInput: ExecutionHostHeartbeatTask,\n ): AsyncIterable<ExecutionHostHeartbeatStreamEvent> {\n const input = HeartbeatTaskSchema.parse(rawInput);\n if (input.signal?.aborted) {\n throw new ExecutionHostInvocationCancelledError();\n }\n const body = ExecutionHostHeartbeatTaskRequestSchema.parse({\n schemaVersion: EXECUTION_CONTRACT_VERSION,\n kind: HEARTBEAT_TASK_WORKFLOW,\n invocationId: input.invocationId,\n taskId: input.taskId,\n task: input.task,\n ...(input.checkpoint ? { checkpoint: input.checkpoint } : {}),\n runContext: input.runContext,\n ...(input.model ? { model: input.model } : {}),\n ...(input.reasoningEffort\n ? { reasoningEffort: input.reasoningEffort }\n : {}),\n ...(input.maxSteps !== undefined ? { maxSteps: input.maxSteps } : {}),\n ...(input.searchIgnoreDirs\n ? { searchIgnoreDirs: input.searchIgnoreDirs }\n : {}),\n ...(input.systemContext ? { systemContext: input.systemContext } : {}),\n ...(input.deadlineAt ? { deadlineAt: input.deadlineAt } : {}),\n });\n yield* this.#streamInvocation(\n input,\n body,\n ExecutionHostHeartbeatStreamEventSchema,\n isExecutionHostHeartbeatTerminalEvent,\n );\n }\n\n async *#streamInvocation<TEvent extends ValidatedStreamEvent>(\n input: InvocationInput,\n body: unknown,\n schema: z.ZodType<TEvent>,\n isTerminal: (event: TEvent) => boolean,\n ): AsyncIterable<TEvent> {\n const response = await this.#invoke(input, body);\n if (!response.ok) {\n throw new ExecutionHostRejectedError(\n response.status,\n await readSafeErrorCode(response),\n );\n }\n yield* readExecutionHostEventStream({\n response,\n schema,\n isTerminal,\n invocationId: input.invocationId,\n signal: input.signal,\n });\n }\n\n async #invoke(input: InvocationInput, body: unknown): Promise<Response> {\n try {\n return await this.#fetch(this.#endpoint, {\n method: 'POST',\n redirect: 'error',\n signal: input.signal,\n headers: createSensitiveHeaders(input, this.#localToken),\n body: JSON.stringify(body),\n });\n } catch (error) {\n throw toExecutionHostTransportError(error, input.signal);\n }\n }\n}\n\ntype InvocationInput = {\n invocationId: string;\n runtimeSessionId: string;\n executionAssertion: string;\n mcpCapability?: string;\n modelCredential: z.infer<typeof ExecutionHostModelCredentialSchema>;\n signal?: AbortSignal;\n};\n\ntype ValidatedStreamEvent = {\n kind: string;\n invocationId: string;\n runId: string;\n sequence: number;\n timestamp: string;\n};\n\nfunction createSensitiveHeaders(\n input: InvocationInput,\n localToken: string,\n): Headers {\n const headers = new Headers({\n Accept: 'text/event-stream',\n 'Content-Type': 'application/json',\n [AGENTCORE_RUNTIME_SESSION_HEADER]: input.runtimeSessionId,\n [EXECUTION_HOST_LOCAL_TOKEN_HEADER]: localToken,\n [MODEL_CREDENTIAL_HEADER]: JSON.stringify(input.modelCredential),\n [EXECUTION_ASSERTION_HEADER]: input.executionAssertion,\n });\n if (input.mcpCapability) {\n headers.set(MCP_CAPABILITY_HEADER, input.mcpCapability);\n }\n return headers;\n}\n\nasync function readSafeErrorCode(response: Response): Promise<string> {\n try {\n const parsed = ApiErrorSchema.safeParse(await readBoundedJsonResponse(\n response,\n MAX_ERROR_BODY_BYTES,\n ));\n return parsed.success ? parsed.data.error.code : 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\nfunction assertSafeBaseUrl(url: URL): void {\n if (!isSafeWebUrl(url)) {\n throw new Error(\n 'Direct Execution Host URL must use HTTPS or loopback HTTP and contain no credentials, query, or fragment.',\n );\n }\n}\n\nfunction withTrailingSlash(url: URL): URL {\n const normalized = new URL(url);\n normalized.pathname = normalized.pathname.endsWith('/')\n ? normalized.pathname\n : `${normalized.pathname}/`;\n return normalized;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"direct-http-execution-host.js","sourceRoot":"","sources":["../../src/http-sse/direct-http-execution-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n AGENTCORE_RUNTIME_SESSION_HEADER,\n CONVERSATION_TURN_WORKFLOW,\n EXECUTION_ASSERTION_HEADER,\n EXECUTION_CONTRACT_VERSION,\n EXECUTION_HOST_LOCAL_TOKEN_HEADER,\n ExecutionHostConversationTurnRequestSchema,\n ExecutionHostHeartbeatStreamEventSchema,\n ExecutionHostHeartbeatTaskRequestSchema,\n ExecutionHostModelCredentialSchema,\n ExecutionHostStreamEventSchema,\n HEARTBEAT_TASK_WORKFLOW,\n MCP_CAPABILITY_HEADER,\n MODEL_CREDENTIAL_HEADER,\n OpaqueIdSchema,\n RuntimeSessionIdSchema,\n TimestampSchema,\n isExecutionHostHeartbeatTerminalEvent,\n isExecutionHostTerminalEvent,\n isDockerLocalWebUrl,\n isSafeWebUrl,\n type ExecutionHostHeartbeatStreamEvent,\n type ExecutionHostStreamEvent,\n} from '../contracts/index.js';\nimport {\n ExecutionHostInvocationCancelledError,\n ExecutionHostRejectedError,\n} from './errors.js';\nimport type {\n DirectHttpExecutionHostConfig,\n ExecutionHost,\n ExecutionHostConversationTurn,\n ExecutionHostHeartbeatTask,\n HeartbeatExecutionHost,\n} from './types.js';\nimport {\n readExecutionHostEventStream,\n toExecutionHostTransportError,\n} from '../internal/execution-host-event-stream.js';\nimport { readBoundedJsonResponse } from '../internal/http-response.js';\n\nconst MAX_ERROR_BODY_BYTES = 16_384;\nconst SecretSchema = z.string().min(8).max(4_096);\nconst InvocationAuthoritySchema = z.object({\n runtimeSessionId: RuntimeSessionIdSchema,\n executionAssertion: z.string().min(32).max(4_096),\n mcpCapability: z.string().min(32).max(4_096).optional(),\n modelCredential: ExecutionHostModelCredentialSchema,\n signal: z.custom<AbortSignal>(\n (value) => value instanceof AbortSignal,\n 'signal must be an AbortSignal',\n ).optional(),\n}).strict();\nconst ConversationTurnSchema = InvocationAuthoritySchema.extend({\n invocationId: OpaqueIdSchema,\n prompt: z.string().trim().min(1).max(200_000),\n deadlineAt: TimestampSchema.optional(),\n}).strict();\nconst HeartbeatTaskSchema = InvocationAuthoritySchema.extend(\n ExecutionHostHeartbeatTaskRequestSchema.omit({\n schemaVersion: true,\n kind: true,\n }).shape,\n).strict();\nconst ApiErrorSchema = z.object({\n error: z.object({\n code: z.string().min(1).max(128).regex(/^[a-z0-9_]+$/),\n message: z.string(),\n }).strict(),\n}).strict();\n\n/**\n * Strict direct-development HTTP/SSE adapter for the Execution Host v1 wire.\n * It deliberately owns neither AWS SDK nor SigV4 behavior.\n */\nexport class DirectHttpExecutionHost\nimplements ExecutionHost, HeartbeatExecutionHost {\n readonly #endpoint: URL;\n readonly #fetch: typeof fetch;\n readonly #localToken: string;\n\n constructor(config: DirectHttpExecutionHostConfig) {\n assertSafeBaseUrl(config.baseUrl, config.allowDockerLocalHost === true);\n this.#localToken = SecretSchema.parse(config.localToken);\n this.#endpoint = new URL('invocations', withTrailingSlash(config.baseUrl));\n this.#fetch = config.fetch ?? globalThis.fetch;\n }\n\n async *streamConversationTurn(\n rawInput: ExecutionHostConversationTurn,\n ): AsyncIterable<ExecutionHostStreamEvent> {\n const input = ConversationTurnSchema.parse(rawInput);\n if (input.signal?.aborted) {\n throw new ExecutionHostInvocationCancelledError();\n }\n const body = ExecutionHostConversationTurnRequestSchema.parse({\n schemaVersion: EXECUTION_CONTRACT_VERSION,\n kind: CONVERSATION_TURN_WORKFLOW,\n invocationId: input.invocationId,\n prompt: input.prompt,\n ...(input.deadlineAt ? { deadlineAt: input.deadlineAt } : {}),\n });\n yield* this.#streamInvocation(\n input,\n body,\n ExecutionHostStreamEventSchema,\n isExecutionHostTerminalEvent,\n );\n }\n\n async *streamHeartbeatTask(\n rawInput: ExecutionHostHeartbeatTask,\n ): AsyncIterable<ExecutionHostHeartbeatStreamEvent> {\n const input = HeartbeatTaskSchema.parse(rawInput);\n if (input.signal?.aborted) {\n throw new ExecutionHostInvocationCancelledError();\n }\n const body = ExecutionHostHeartbeatTaskRequestSchema.parse({\n schemaVersion: EXECUTION_CONTRACT_VERSION,\n kind: HEARTBEAT_TASK_WORKFLOW,\n invocationId: input.invocationId,\n taskId: input.taskId,\n task: input.task,\n ...(input.checkpoint ? { checkpoint: input.checkpoint } : {}),\n runContext: input.runContext,\n ...(input.model ? { model: input.model } : {}),\n ...(input.reasoningEffort\n ? { reasoningEffort: input.reasoningEffort }\n : {}),\n ...(input.maxSteps !== undefined ? { maxSteps: input.maxSteps } : {}),\n ...(input.searchIgnoreDirs\n ? { searchIgnoreDirs: input.searchIgnoreDirs }\n : {}),\n ...(input.systemContext ? { systemContext: input.systemContext } : {}),\n ...(input.deadlineAt ? { deadlineAt: input.deadlineAt } : {}),\n });\n yield* this.#streamInvocation(\n input,\n body,\n ExecutionHostHeartbeatStreamEventSchema,\n isExecutionHostHeartbeatTerminalEvent,\n );\n }\n\n async *#streamInvocation<TEvent extends ValidatedStreamEvent>(\n input: InvocationInput,\n body: unknown,\n schema: z.ZodType<TEvent>,\n isTerminal: (event: TEvent) => boolean,\n ): AsyncIterable<TEvent> {\n const response = await this.#invoke(input, body);\n if (!response.ok) {\n throw new ExecutionHostRejectedError(\n response.status,\n await readSafeErrorCode(response),\n );\n }\n yield* readExecutionHostEventStream({\n response,\n schema,\n isTerminal,\n invocationId: input.invocationId,\n signal: input.signal,\n });\n }\n\n async #invoke(input: InvocationInput, body: unknown): Promise<Response> {\n try {\n return await this.#fetch(this.#endpoint, {\n method: 'POST',\n redirect: 'error',\n signal: input.signal,\n headers: createSensitiveHeaders(input, this.#localToken),\n body: JSON.stringify(body),\n });\n } catch (error) {\n throw toExecutionHostTransportError(error, input.signal);\n }\n }\n}\n\ntype InvocationInput = {\n invocationId: string;\n runtimeSessionId: string;\n executionAssertion: string;\n mcpCapability?: string;\n modelCredential: z.infer<typeof ExecutionHostModelCredentialSchema>;\n signal?: AbortSignal;\n};\n\ntype ValidatedStreamEvent = {\n kind: string;\n invocationId: string;\n runId: string;\n sequence: number;\n timestamp: string;\n};\n\nfunction createSensitiveHeaders(\n input: InvocationInput,\n localToken: string,\n): Headers {\n const headers = new Headers({\n Accept: 'text/event-stream',\n 'Content-Type': 'application/json',\n [AGENTCORE_RUNTIME_SESSION_HEADER]: input.runtimeSessionId,\n [EXECUTION_HOST_LOCAL_TOKEN_HEADER]: localToken,\n [MODEL_CREDENTIAL_HEADER]: JSON.stringify(input.modelCredential),\n [EXECUTION_ASSERTION_HEADER]: input.executionAssertion,\n });\n if (input.mcpCapability) {\n headers.set(MCP_CAPABILITY_HEADER, input.mcpCapability);\n }\n return headers;\n}\n\nasync function readSafeErrorCode(response: Response): Promise<string> {\n try {\n const parsed = ApiErrorSchema.safeParse(await readBoundedJsonResponse(\n response,\n MAX_ERROR_BODY_BYTES,\n ));\n return parsed.success ? parsed.data.error.code : 'unknown';\n } catch {\n return 'unknown';\n }\n}\n\nfunction assertSafeBaseUrl(url: URL, allowDockerLocalHost: boolean): void {\n if (\n !isSafeWebUrl(url)\n && !(allowDockerLocalHost && isDockerLocalWebUrl(url))\n ) {\n throw new Error(\n 'Direct Execution Host URL must use HTTPS or loopback HTTP; Docker local-host HTTP requires an explicit opt-in; URLs must contain no credentials, query, or fragment.',\n );\n }\n}\n\nfunction withTrailingSlash(url: URL): URL {\n const normalized = new URL(url);\n normalized.pathname = normalized.pathname.endsWith('/')\n ? normalized.pathname\n : `${normalized.pathname}/`;\n return normalized;\n}\n"]}
|
package/dist/http-sse/types.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ export interface HeartbeatExecutionHost {
|
|
|
25
25
|
export type DirectHttpExecutionHostConfig = {
|
|
26
26
|
baseUrl: URL;
|
|
27
27
|
localToken: string;
|
|
28
|
+
/** Allows only Docker's explicit local-host alias over HTTP. */
|
|
29
|
+
allowDockerLocalHost?: boolean;
|
|
28
30
|
fetch?: typeof fetch;
|
|
29
31
|
};
|
|
30
32
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/http-sse/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,iCAAiC,EACjC,iCAAiC,EACjC,wBAAwB,EACzB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,MAAM,6BAA6B,GAAG;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,4BAA4B,CAAC;IAC9C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,sBAAsB,CACpB,KAAK,EAAE,6BAA6B,GACnC,aAAa,CAAC,wBAAwB,CAAC,CAAC;CAC5C;AAED,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAC3C,iCAAiC,EACjC,eAAe,GAAG,MAAM,CACzB,GAAG;IACF,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,4BAA4B,CAAC;IAC9C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,mBAAmB,CACjB,KAAK,EAAE,0BAA0B,GAChC,aAAa,CAAC,iCAAiC,CAAC,CAAC;CACrD;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,EAAE,GAAG,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/http-sse/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,iCAAiC,EACjC,iCAAiC,EACjC,wBAAwB,EACzB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,MAAM,6BAA6B,GAAG;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,4BAA4B,CAAC;IAC9C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,sBAAsB,CACpB,KAAK,EAAE,6BAA6B,GACnC,aAAa,CAAC,wBAAwB,CAAC,CAAC;CAC5C;AAED,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAC3C,iCAAiC,EACjC,eAAe,GAAG,MAAM,CACzB,GAAG;IACF,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,4BAA4B,CAAC;IAC9C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,mBAAmB,CACjB,KAAK,EAAE,0BAA0B,GAChC,aAAa,CAAC,iCAAiC,CAAC,CAAC;CACrD;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,EAAE,GAAG,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/http-sse/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ExecutionHostModelCredential,\n ExecutionHostHeartbeatStreamEvent,\n ExecutionHostHeartbeatTaskRequest,\n ExecutionHostStreamEvent,\n} from '../contracts/index.js';\n\nexport type ExecutionHostConversationTurn = {\n invocationId: string;\n runtimeSessionId: string;\n prompt: string;\n deadlineAt?: string;\n executionAssertion: string;\n mcpCapability?: string;\n modelCredential: ExecutionHostModelCredential;\n signal?: AbortSignal;\n};\n\nexport interface ExecutionHost {\n streamConversationTurn(\n input: ExecutionHostConversationTurn,\n ): AsyncIterable<ExecutionHostStreamEvent>;\n}\n\nexport type ExecutionHostHeartbeatTask = Omit<\n ExecutionHostHeartbeatTaskRequest,\n 'schemaVersion' | 'kind'\n> & {\n runtimeSessionId: string;\n executionAssertion: string;\n mcpCapability?: string;\n modelCredential: ExecutionHostModelCredential;\n signal?: AbortSignal;\n};\n\nexport interface HeartbeatExecutionHost {\n streamHeartbeatTask(\n input: ExecutionHostHeartbeatTask,\n ): AsyncIterable<ExecutionHostHeartbeatStreamEvent>;\n}\n\nexport type DirectHttpExecutionHostConfig = {\n baseUrl: URL;\n localToken: string;\n fetch?: typeof fetch;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/http-sse/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ExecutionHostModelCredential,\n ExecutionHostHeartbeatStreamEvent,\n ExecutionHostHeartbeatTaskRequest,\n ExecutionHostStreamEvent,\n} from '../contracts/index.js';\n\nexport type ExecutionHostConversationTurn = {\n invocationId: string;\n runtimeSessionId: string;\n prompt: string;\n deadlineAt?: string;\n executionAssertion: string;\n mcpCapability?: string;\n modelCredential: ExecutionHostModelCredential;\n signal?: AbortSignal;\n};\n\nexport interface ExecutionHost {\n streamConversationTurn(\n input: ExecutionHostConversationTurn,\n ): AsyncIterable<ExecutionHostStreamEvent>;\n}\n\nexport type ExecutionHostHeartbeatTask = Omit<\n ExecutionHostHeartbeatTaskRequest,\n 'schemaVersion' | 'kind'\n> & {\n runtimeSessionId: string;\n executionAssertion: string;\n mcpCapability?: string;\n modelCredential: ExecutionHostModelCredential;\n signal?: AbortSignal;\n};\n\nexport interface HeartbeatExecutionHost {\n streamHeartbeatTask(\n input: ExecutionHostHeartbeatTask,\n ): AsyncIterable<ExecutionHostHeartbeatStreamEvent>;\n}\n\nexport type DirectHttpExecutionHostConfig = {\n baseUrl: URL;\n localToken: string;\n /** Allows only Docker's explicit local-host alias over HTTP. */\n allowDockerLocalHost?: boolean;\n fetch?: typeof fetch;\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authority-key.d.ts","sourceRoot":"","sources":["../../src/node/authority-key.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authority-key.d.ts","sourceRoot":"","sources":["../../src/node/authority-key.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAkBvE,iFAAiF;AACjF,wBAAsB,0CAA0C,IAAI,OAAO,CACzE,yBAAyB,CAC1B,CAEA;AAED;;;GAGG;AACH,wBAAsB,iCAAiC,CACrD,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,gFAAgF;AAChF,wBAAsB,qCAAqC,CACzD,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,yBAAyB,CAAC,CA8BpC;AAED,qBAAa,8BAA+B,SAAQ,KAAK;IACvD,QAAQ,CAAC,IAAI,oCAAoC;CAClD"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { open, unlink, } from 'node:fs/promises';
|
|
3
|
-
import { webcrypto } from 'node:crypto';
|
|
1
|
+
import { exportJWK, generateKeyPair, importJWK, } from 'jose';
|
|
4
2
|
import { z } from 'zod';
|
|
3
|
+
import { createOwnerOnlyFile, OwnerOnlyFileError, readOwnerOnlyFile, } from './owner-only-file.js';
|
|
5
4
|
const MAX_PRIVATE_JWK_BYTES = 16 * 1_024;
|
|
6
|
-
const
|
|
5
|
+
const SIGNING_ALGORITHM = 'ES256';
|
|
7
6
|
const Base64UrlSchema = z.string().min(1).regex(/^[A-Za-z0-9_-]+$/);
|
|
8
7
|
const PrivateP256JwkSchema = z.object({
|
|
9
8
|
kty: z.literal('EC'),
|
|
@@ -14,74 +13,50 @@ const PrivateP256JwkSchema = z.object({
|
|
|
14
13
|
}).passthrough();
|
|
15
14
|
/** Generates a non-persisted ES256 pair for tests and disposable local demos. */
|
|
16
15
|
export async function generateEphemeralExecutionAuthorityKeyPair() {
|
|
17
|
-
return
|
|
16
|
+
return generateKeyPair(SIGNING_ALGORITHM);
|
|
18
17
|
}
|
|
19
18
|
/**
|
|
20
19
|
* Creates a new owner-only ES256 private-JWK file for local development.
|
|
21
20
|
* Existing paths are never overwritten.
|
|
22
21
|
*/
|
|
23
22
|
export async function generateExecutionAuthorityKeyFile(filePath) {
|
|
24
|
-
const keyPair = await webcrypto.subtle.generateKey(ECDSA_P256, true, ['sign', 'verify']);
|
|
25
|
-
const jwk = PrivateP256JwkSchema.parse(await webcrypto.subtle.exportKey('jwk', keyPair.privateKey));
|
|
26
|
-
const body = `${JSON.stringify({
|
|
27
|
-
kty: jwk.kty,
|
|
28
|
-
crv: jwk.crv,
|
|
29
|
-
x: jwk.x,
|
|
30
|
-
y: jwk.y,
|
|
31
|
-
d: jwk.d,
|
|
32
|
-
})}\n`;
|
|
33
|
-
let file;
|
|
34
|
-
let created = false;
|
|
35
23
|
try {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
await
|
|
41
|
-
|
|
24
|
+
const { privateKey } = await generateKeyPair(SIGNING_ALGORITHM, {
|
|
25
|
+
extractable: true,
|
|
26
|
+
});
|
|
27
|
+
const jwk = PrivateP256JwkSchema.parse(await exportJWK(privateKey));
|
|
28
|
+
await createOwnerOnlyFile(filePath, `${JSON.stringify({
|
|
29
|
+
kty: jwk.kty,
|
|
30
|
+
crv: jwk.crv,
|
|
31
|
+
x: jwk.x,
|
|
32
|
+
y: jwk.y,
|
|
33
|
+
d: jwk.d,
|
|
34
|
+
})}\n`);
|
|
42
35
|
}
|
|
43
36
|
catch {
|
|
44
|
-
if (created) {
|
|
45
|
-
await file?.close().catch(() => undefined);
|
|
46
|
-
file = undefined;
|
|
47
|
-
await unlink(filePath).catch(() => undefined);
|
|
48
|
-
}
|
|
49
37
|
throw new ExecutionAuthorityKeyFileError('Execution authority signing JWK could not be generated at the requested path.');
|
|
50
38
|
}
|
|
51
|
-
finally {
|
|
52
|
-
await file?.close().catch(() => undefined);
|
|
53
|
-
}
|
|
54
39
|
}
|
|
55
40
|
/** Loads a non-exportable ES256 signing pair from an owner-only private JWK. */
|
|
56
41
|
export async function loadExecutionAuthorityKeyPairFromFile(filePath) {
|
|
57
|
-
let file;
|
|
58
42
|
try {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
if (process.platform !== 'win32' && (metadata.mode & 0o077) !== 0) {
|
|
67
|
-
throw new ExecutionAuthorityKeyFileError('Execution authority signing JWK must not be group- or world-accessible.');
|
|
68
|
-
}
|
|
69
|
-
const jwk = PrivateP256JwkSchema.parse(JSON.parse(await file.readFile('utf8')));
|
|
70
|
-
const privateKey = await webcrypto.subtle.importKey('jwk', { kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y, d: jwk.d }, ECDSA_P256, false, ['sign']);
|
|
71
|
-
const publicKey = await webcrypto.subtle.importKey('jwk', { kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y }, ECDSA_P256, true, ['verify']);
|
|
72
|
-
await file.close();
|
|
73
|
-
file = undefined;
|
|
43
|
+
const jwk = PrivateP256JwkSchema.parse(JSON.parse(await readOwnerOnlyFile(filePath, {
|
|
44
|
+
description: 'Execution authority signing JWK',
|
|
45
|
+
maxBytes: MAX_PRIVATE_JWK_BYTES,
|
|
46
|
+
})));
|
|
47
|
+
const privateKey = await importJWK({ kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y, d: jwk.d }, SIGNING_ALGORITHM, { extractable: false });
|
|
48
|
+
const publicKey = await importJWK({ kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y }, SIGNING_ALGORITHM, { extractable: true });
|
|
74
49
|
return { privateKey, publicKey };
|
|
75
50
|
}
|
|
76
51
|
catch (error) {
|
|
77
52
|
if (error instanceof ExecutionAuthorityKeyFileError) {
|
|
78
53
|
throw error;
|
|
79
54
|
}
|
|
55
|
+
if (error instanceof OwnerOnlyFileError) {
|
|
56
|
+
throw new ExecutionAuthorityKeyFileError(error.message);
|
|
57
|
+
}
|
|
80
58
|
throw new ExecutionAuthorityKeyFileError('Execution authority signing JWK could not be loaded.');
|
|
81
59
|
}
|
|
82
|
-
finally {
|
|
83
|
-
await file?.close().catch(() => undefined);
|
|
84
|
-
}
|
|
85
60
|
}
|
|
86
61
|
export class ExecutionAuthorityKeyFileError extends Error {
|
|
87
62
|
name = 'ExecutionAuthorityKeyFileError';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authority-key.js","sourceRoot":"","sources":["../../src/node/authority-key.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"authority-key.js","sourceRoot":"","sources":["../../src/node/authority-key.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n exportJWK,\n generateKeyPair,\n importJWK,\n} from 'jose';\nimport { z } from 'zod';\nimport type { ExecutionAuthorityKeyPair } from '../authority/index.js';\nimport {\n createOwnerOnlyFile,\n OwnerOnlyFileError,\n readOwnerOnlyFile,\n} from './owner-only-file.js';\n\nconst MAX_PRIVATE_JWK_BYTES = 16 * 1_024;\nconst SIGNING_ALGORITHM = 'ES256';\nconst Base64UrlSchema = z.string().min(1).regex(/^[A-Za-z0-9_-]+$/);\nconst PrivateP256JwkSchema = z.object({\n kty: z.literal('EC'),\n crv: z.literal('P-256'),\n x: Base64UrlSchema,\n y: Base64UrlSchema,\n d: Base64UrlSchema,\n}).passthrough();\n\n/** Generates a non-persisted ES256 pair for tests and disposable local demos. */\nexport async function generateEphemeralExecutionAuthorityKeyPair(): Promise<\n ExecutionAuthorityKeyPair\n> {\n return generateKeyPair(SIGNING_ALGORITHM);\n}\n\n/**\n * Creates a new owner-only ES256 private-JWK file for local development.\n * Existing paths are never overwritten.\n */\nexport async function generateExecutionAuthorityKeyFile(\n filePath: string,\n): Promise<void> {\n try {\n const { privateKey } = await generateKeyPair(SIGNING_ALGORITHM, {\n extractable: true,\n });\n const jwk = PrivateP256JwkSchema.parse(await exportJWK(privateKey));\n await createOwnerOnlyFile(filePath, `${JSON.stringify({\n kty: jwk.kty,\n crv: jwk.crv,\n x: jwk.x,\n y: jwk.y,\n d: jwk.d,\n })}\\n`);\n } catch {\n throw new ExecutionAuthorityKeyFileError(\n 'Execution authority signing JWK could not be generated at the requested path.',\n );\n }\n}\n\n/** Loads a non-exportable ES256 signing pair from an owner-only private JWK. */\nexport async function loadExecutionAuthorityKeyPairFromFile(\n filePath: string,\n): Promise<ExecutionAuthorityKeyPair> {\n try {\n const jwk = PrivateP256JwkSchema.parse(\n JSON.parse(await readOwnerOnlyFile(filePath, {\n description: 'Execution authority signing JWK',\n maxBytes: MAX_PRIVATE_JWK_BYTES,\n })) as unknown,\n );\n const privateKey = await importJWK(\n { kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y, d: jwk.d },\n SIGNING_ALGORITHM,\n { extractable: false },\n );\n const publicKey = await importJWK(\n { kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y },\n SIGNING_ALGORITHM,\n { extractable: true },\n );\n return { privateKey, publicKey };\n } catch (error) {\n if (error instanceof ExecutionAuthorityKeyFileError) {\n throw error;\n }\n if (error instanceof OwnerOnlyFileError) {\n throw new ExecutionAuthorityKeyFileError(error.message);\n }\n throw new ExecutionAuthorityKeyFileError(\n 'Execution authority signing JWK could not be loaded.',\n );\n }\n}\n\nexport class ExecutionAuthorityKeyFileError extends Error {\n readonly name = 'ExecutionAuthorityKeyFileError';\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type EnvironmentFileValueOptions = {
|
|
2
|
+
maxFileBytes?: number;
|
|
3
|
+
};
|
|
4
|
+
/**
|
|
5
|
+
* Takes one deployment value from either `NAME` or the conventional
|
|
6
|
+
* `NAME_FILE` indirection. Both source variables are removed before parsing.
|
|
7
|
+
*/
|
|
8
|
+
export declare function takeEnvironmentValueOrFile(environment: NodeJS.ProcessEnv, name: string, options?: EnvironmentFileValueOptions): string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Atomically takes a set of deployment values from `NAME` / `NAME_FILE`
|
|
11
|
+
* sources. Every source is removed even when one value is invalid.
|
|
12
|
+
*/
|
|
13
|
+
export declare function takeEnvironmentValuesOrFiles(environment: NodeJS.ProcessEnv, rawNames: readonly string[], options?: EnvironmentFileValueOptions): Readonly<Record<string, string | undefined>>;
|
|
14
|
+
export declare class EnvironmentFileValueError extends Error {
|
|
15
|
+
readonly name = "EnvironmentFileValueError";
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=environment-value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment-value.d.ts","sourceRoot":"","sources":["../../src/node/environment-value.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,2BAA2B,GAAG;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAQF;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,CAAC,UAAU,EAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,2BAAgC,GACxC,MAAM,GAAG,SAAS,CAEpB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,MAAM,CAAC,UAAU,EAC9B,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,OAAO,GAAE,2BAAgC,GACxC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAoB9C;AAqDD,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,IAAI,+BAA+B;CAC7C"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { closeSync, fstatSync, openSync, readFileSync, } from 'node:fs';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { removeOneTrailingLineEnding } from './owner-only-file.js';
|
|
4
|
+
const DEFAULT_MAX_FILE_BYTES = 16 * 1_024;
|
|
5
|
+
const EnvironmentNameSchema = z.string().min(1).max(128).regex(/^[A-Za-z_][A-Za-z0-9_]*$/, 'must be an environment variable name');
|
|
6
|
+
const EnvironmentNamesSchema = z.array(EnvironmentNameSchema).min(1)
|
|
7
|
+
.refine((names) => new Set(names).size === names.length, 'must contain unique environment variable names');
|
|
8
|
+
/**
|
|
9
|
+
* Takes one deployment value from either `NAME` or the conventional
|
|
10
|
+
* `NAME_FILE` indirection. Both source variables are removed before parsing.
|
|
11
|
+
*/
|
|
12
|
+
export function takeEnvironmentValueOrFile(environment, name, options = {}) {
|
|
13
|
+
return takeEnvironmentValuesOrFiles(environment, [name], options)[name];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Atomically takes a set of deployment values from `NAME` / `NAME_FILE`
|
|
17
|
+
* sources. Every source is removed even when one value is invalid.
|
|
18
|
+
*/
|
|
19
|
+
export function takeEnvironmentValuesOrFiles(environment, rawNames, options = {}) {
|
|
20
|
+
const names = EnvironmentNamesSchema.parse(rawNames);
|
|
21
|
+
const maxFileBytes = z.number().int().min(1).max(1024 * 1_024)
|
|
22
|
+
.default(DEFAULT_MAX_FILE_BYTES)
|
|
23
|
+
.parse(options.maxFileBytes);
|
|
24
|
+
const sources = names.map((name) => ({
|
|
25
|
+
name,
|
|
26
|
+
directValue: environment[name],
|
|
27
|
+
filePath: environment[`${name}_FILE`],
|
|
28
|
+
}));
|
|
29
|
+
sources.forEach(({ name }) => {
|
|
30
|
+
delete environment[name];
|
|
31
|
+
delete environment[`${name}_FILE`];
|
|
32
|
+
});
|
|
33
|
+
return Object.freeze(Object.fromEntries(sources.map((source) => [
|
|
34
|
+
source.name,
|
|
35
|
+
readEnvironmentValueSource(source, maxFileBytes),
|
|
36
|
+
])));
|
|
37
|
+
}
|
|
38
|
+
function readEnvironmentValueSource(source, maxFileBytes) {
|
|
39
|
+
if (source.directValue !== undefined && source.filePath !== undefined) {
|
|
40
|
+
throw new EnvironmentFileValueError(`${source.name} and ${source.name}_FILE are mutually exclusive.`);
|
|
41
|
+
}
|
|
42
|
+
if (source.directValue !== undefined) {
|
|
43
|
+
return source.directValue;
|
|
44
|
+
}
|
|
45
|
+
if (source.filePath === undefined) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const filePath = source.filePath.trim();
|
|
49
|
+
if (!filePath) {
|
|
50
|
+
throw new EnvironmentFileValueError(`${source.name}_FILE must name a readable regular file.`);
|
|
51
|
+
}
|
|
52
|
+
let descriptor;
|
|
53
|
+
try {
|
|
54
|
+
descriptor = openSync(filePath, 'r');
|
|
55
|
+
const metadata = fstatSync(descriptor);
|
|
56
|
+
if (!metadata.isFile()
|
|
57
|
+
|| metadata.size <= 0
|
|
58
|
+
|| metadata.size > maxFileBytes) {
|
|
59
|
+
throw new EnvironmentFileValueError(`${source.name}_FILE must name a non-empty regular file no larger than ${maxFileBytes} bytes.`);
|
|
60
|
+
}
|
|
61
|
+
return removeOneTrailingLineEnding(readFileSync(descriptor, 'utf8'));
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (error instanceof EnvironmentFileValueError) {
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
throw new EnvironmentFileValueError(`${source.name}_FILE could not be read.`);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
if (descriptor !== undefined) {
|
|
71
|
+
closeSync(descriptor);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export class EnvironmentFileValueError extends Error {
|
|
76
|
+
name = 'EnvironmentFileValueError';
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=environment-value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment-value.js","sourceRoot":"","sources":["../../src/node/environment-value.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n closeSync,\n fstatSync,\n openSync,\n readFileSync,\n} from 'node:fs';\nimport { z } from 'zod';\nimport { removeOneTrailingLineEnding } from './owner-only-file.js';\n\nconst DEFAULT_MAX_FILE_BYTES = 16 * 1_024;\nconst EnvironmentNameSchema = z.string().min(1).max(128).regex(\n /^[A-Za-z_][A-Za-z0-9_]*$/,\n 'must be an environment variable name',\n);\nconst EnvironmentNamesSchema = z.array(EnvironmentNameSchema).min(1)\n .refine(\n (names) => new Set(names).size === names.length,\n 'must contain unique environment variable names',\n );\n\nexport type EnvironmentFileValueOptions = {\n maxFileBytes?: number;\n};\n\ntype EnvironmentValueSource = {\n name: string;\n directValue: string | undefined;\n filePath: string | undefined;\n};\n\n/**\n * Takes one deployment value from either `NAME` or the conventional\n * `NAME_FILE` indirection. Both source variables are removed before parsing.\n */\nexport function takeEnvironmentValueOrFile(\n environment: NodeJS.ProcessEnv,\n name: string,\n options: EnvironmentFileValueOptions = {},\n): string | undefined {\n return takeEnvironmentValuesOrFiles(environment, [name], options)[name];\n}\n\n/**\n * Atomically takes a set of deployment values from `NAME` / `NAME_FILE`\n * sources. Every source is removed even when one value is invalid.\n */\nexport function takeEnvironmentValuesOrFiles(\n environment: NodeJS.ProcessEnv,\n rawNames: readonly string[],\n options: EnvironmentFileValueOptions = {},\n): Readonly<Record<string, string | undefined>> {\n const names = EnvironmentNamesSchema.parse(rawNames);\n const maxFileBytes = z.number().int().min(1).max(1024 * 1_024)\n .default(DEFAULT_MAX_FILE_BYTES)\n .parse(options.maxFileBytes);\n const sources = names.map((name): EnvironmentValueSource => ({\n name,\n directValue: environment[name],\n filePath: environment[`${name}_FILE`],\n }));\n\n sources.forEach(({ name }) => {\n delete environment[name];\n delete environment[`${name}_FILE`];\n });\n\n return Object.freeze(Object.fromEntries(sources.map((source) => [\n source.name,\n readEnvironmentValueSource(source, maxFileBytes),\n ])));\n}\n\nfunction readEnvironmentValueSource(\n source: EnvironmentValueSource,\n maxFileBytes: number,\n): string | undefined {\n if (source.directValue !== undefined && source.filePath !== undefined) {\n throw new EnvironmentFileValueError(\n `${source.name} and ${source.name}_FILE are mutually exclusive.`,\n );\n }\n if (source.directValue !== undefined) {\n return source.directValue;\n }\n if (source.filePath === undefined) {\n return undefined;\n }\n\n const filePath = source.filePath.trim();\n if (!filePath) {\n throw new EnvironmentFileValueError(\n `${source.name}_FILE must name a readable regular file.`,\n );\n }\n\n let descriptor: number | undefined;\n try {\n descriptor = openSync(filePath, 'r');\n const metadata = fstatSync(descriptor);\n if (\n !metadata.isFile()\n || metadata.size <= 0\n || metadata.size > maxFileBytes\n ) {\n throw new EnvironmentFileValueError(\n `${source.name}_FILE must name a non-empty regular file no larger than ${maxFileBytes} bytes.`,\n );\n }\n return removeOneTrailingLineEnding(readFileSync(descriptor, 'utf8'));\n } catch (error) {\n if (error instanceof EnvironmentFileValueError) {\n throw error;\n }\n throw new EnvironmentFileValueError(\n `${source.name}_FILE could not be read.`,\n );\n } finally {\n if (descriptor !== undefined) {\n closeSync(descriptor);\n }\n }\n}\n\nexport class EnvironmentFileValueError extends Error {\n readonly name = 'EnvironmentFileValueError';\n}\n"]}
|
package/dist/node/index.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export { ExecutionAuthorityKeyFileError, generateEphemeralExecutionAuthorityKeyPair, generateExecutionAuthorityKeyFile, loadExecutionAuthorityKeyPairFromFile, } from './authority-key.js';
|
|
2
|
+
export { EnvironmentFileValueError, takeEnvironmentValueOrFile, takeEnvironmentValuesOrFiles, } from './environment-value.js';
|
|
3
|
+
export type { EnvironmentFileValueOptions } from './environment-value.js';
|
|
4
|
+
export { initializeLocalCredentialBundle, LOCAL_CREDENTIAL_BUNDLE_FILES, LocalCredentialBundleError, validateLocalCredentialBundle, } from './local-credential-bundle.js';
|
|
5
|
+
export type { LocalCredentialBundleInitialization, LocalCredentialBundlePaths, } from './local-credential-bundle.js';
|
|
2
6
|
export { DirectExecutionHostCredentials } from './direct-credentials.js';
|
|
3
7
|
export type { DirectExecutionHostCredentialEnvironmentNames, } from './direct-credentials.js';
|
|
4
8
|
export { DEFAULT_ADOPTER_CONVERSATION_TURNS_PATH, DEFAULT_ADOPTER_JWKS_PATH, } from '../adopter/index.js';
|
package/dist/node/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,0CAA0C,EAC1C,iCAAiC,EACjC,qCAAqC,GACtC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AACzE,YAAY,EACV,6CAA6C,GAC9C,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uCAAuC,EACvC,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,+BAA+B,GAChC,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,uCAAuC,EACvC,iCAAiC,EACjC,qCAAqC,EACrC,uCAAuC,EACvC,2BAA2B,EAC3B,+BAA+B,EAC/B,6BAA6B,EAC7B,qCAAqC,EACrC,+BAA+B,GAChC,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,0CAA0C,EAC1C,iCAAiC,EACjC,qCAAqC,GACtC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EACL,+BAA+B,EAC/B,6BAA6B,EAC7B,0BAA0B,EAC1B,6BAA6B,GAC9B,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,mCAAmC,EACnC,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AACzE,YAAY,EACV,6CAA6C,GAC9C,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uCAAuC,EACvC,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,+BAA+B,GAChC,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,uCAAuC,EACvC,iCAAiC,EACjC,qCAAqC,EACrC,uCAAuC,EACvC,2BAA2B,EAC3B,+BAA+B,EAC/B,6BAA6B,EAC7B,qCAAqC,EACrC,+BAA+B,GAChC,MAAM,YAAY,CAAC"}
|
package/dist/node/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { ExecutionAuthorityKeyFileError, generateEphemeralExecutionAuthorityKeyPair, generateExecutionAuthorityKeyFile, loadExecutionAuthorityKeyPairFromFile, } from './authority-key.js';
|
|
2
|
+
export { EnvironmentFileValueError, takeEnvironmentValueOrFile, takeEnvironmentValuesOrFiles, } from './environment-value.js';
|
|
3
|
+
export { initializeLocalCredentialBundle, LOCAL_CREDENTIAL_BUNDLE_FILES, LocalCredentialBundleError, validateLocalCredentialBundle, } from './local-credential-bundle.js';
|
|
2
4
|
export { DirectExecutionHostCredentials } from './direct-credentials.js';
|
|
3
5
|
export { DEFAULT_ADOPTER_CONVERSATION_TURNS_PATH, DEFAULT_ADOPTER_JWKS_PATH, } from '../adopter/index.js';
|
|
4
6
|
export { NodeExecutionAdopterHttpService, } from './http-service.js';
|
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,0CAA0C,EAC1C,iCAAiC,EACjC,qCAAqC,GACtC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAIzE,OAAO,EACL,uCAAuC,EACvC,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,+BAA+B,GAChC,MAAM,mBAAmB,CAAC","sourcesContent":["export {\n ExecutionAuthorityKeyFileError,\n generateEphemeralExecutionAuthorityKeyPair,\n generateExecutionAuthorityKeyFile,\n loadExecutionAuthorityKeyPairFromFile,\n} from './authority-key.js';\nexport { DirectExecutionHostCredentials } from './direct-credentials.js';\nexport type {\n DirectExecutionHostCredentialEnvironmentNames,\n} from './direct-credentials.js';\nexport {\n DEFAULT_ADOPTER_CONVERSATION_TURNS_PATH,\n DEFAULT_ADOPTER_JWKS_PATH,\n} from '../adopter/index.js';\nexport {\n NodeExecutionAdopterHttpService,\n} from './http-service.js';\nexport type {\n NodeExecutionAdopterAuthenticationInput,\n NodeExecutionAdopterAuthenticator,\n NodeExecutionAdopterConversationInput,\n NodeExecutionAdopterConversationService,\n NodeExecutionAdopterFailure,\n NodeExecutionAdopterHttpHandler,\n NodeExecutionAdopterHttpPaths,\n NodeExecutionAdopterHttpServiceConfig,\n NodeExecutionAdopterPublicError,\n} from './types.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,0CAA0C,EAC1C,iCAAiC,EACjC,qCAAqC,GACtC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,+BAA+B,EAC/B,6BAA6B,EAC7B,0BAA0B,EAC1B,6BAA6B,GAC9B,MAAM,8BAA8B,CAAC;AAKtC,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAIzE,OAAO,EACL,uCAAuC,EACvC,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,+BAA+B,GAChC,MAAM,mBAAmB,CAAC","sourcesContent":["export {\n ExecutionAuthorityKeyFileError,\n generateEphemeralExecutionAuthorityKeyPair,\n generateExecutionAuthorityKeyFile,\n loadExecutionAuthorityKeyPairFromFile,\n} from './authority-key.js';\nexport {\n EnvironmentFileValueError,\n takeEnvironmentValueOrFile,\n takeEnvironmentValuesOrFiles,\n} from './environment-value.js';\nexport type { EnvironmentFileValueOptions } from './environment-value.js';\nexport {\n initializeLocalCredentialBundle,\n LOCAL_CREDENTIAL_BUNDLE_FILES,\n LocalCredentialBundleError,\n validateLocalCredentialBundle,\n} from './local-credential-bundle.js';\nexport type {\n LocalCredentialBundleInitialization,\n LocalCredentialBundlePaths,\n} from './local-credential-bundle.js';\nexport { DirectExecutionHostCredentials } from './direct-credentials.js';\nexport type {\n DirectExecutionHostCredentialEnvironmentNames,\n} from './direct-credentials.js';\nexport {\n DEFAULT_ADOPTER_CONVERSATION_TURNS_PATH,\n DEFAULT_ADOPTER_JWKS_PATH,\n} from '../adopter/index.js';\nexport {\n NodeExecutionAdopterHttpService,\n} from './http-service.js';\nexport type {\n NodeExecutionAdopterAuthenticationInput,\n NodeExecutionAdopterAuthenticator,\n NodeExecutionAdopterConversationInput,\n NodeExecutionAdopterConversationService,\n NodeExecutionAdopterFailure,\n NodeExecutionAdopterHttpHandler,\n NodeExecutionAdopterHttpPaths,\n NodeExecutionAdopterHttpServiceConfig,\n NodeExecutionAdopterPublicError,\n} from './types.js';\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const LOCAL_CREDENTIAL_BUNDLE_FILES: Readonly<{
|
|
2
|
+
readonly executionHostLocalToken: "execution-host-local-token";
|
|
3
|
+
readonly executionHostLocalTokenSha256: "execution-host-local-token.sha256";
|
|
4
|
+
readonly coordinatorApiToken: "coordinator-api-token";
|
|
5
|
+
readonly coordinatorProductExecutionToken: "coordinator-product-execution-token";
|
|
6
|
+
readonly executionAuthorityPrivateJwk: "execution-authority-private.jwk";
|
|
7
|
+
readonly manifest: "manifest.json";
|
|
8
|
+
}>;
|
|
9
|
+
export type LocalCredentialBundlePaths = {
|
|
10
|
+
directory: string;
|
|
11
|
+
manifest: string;
|
|
12
|
+
executionHostLocalToken: string;
|
|
13
|
+
executionHostLocalTokenSha256: string;
|
|
14
|
+
coordinatorApiToken: string;
|
|
15
|
+
coordinatorProductExecutionToken: string;
|
|
16
|
+
executionAuthorityPrivateJwk: string;
|
|
17
|
+
};
|
|
18
|
+
export type LocalCredentialBundleInitialization = {
|
|
19
|
+
created: boolean;
|
|
20
|
+
paths: LocalCredentialBundlePaths;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Creates one versioned, owner-only credential bundle for local hosted-service
|
|
24
|
+
* composition. A valid existing bundle is returned unchanged; partial or
|
|
25
|
+
* unmanaged directories fail closed.
|
|
26
|
+
*/
|
|
27
|
+
export declare function initializeLocalCredentialBundle(rawOutputDirectory: string): Promise<LocalCredentialBundleInitialization>;
|
|
28
|
+
/** Validates one generated bundle without returning any credential value. */
|
|
29
|
+
export declare function validateLocalCredentialBundle(rawDirectory: string): Promise<LocalCredentialBundlePaths>;
|
|
30
|
+
export declare class LocalCredentialBundleError extends Error {
|
|
31
|
+
readonly name = "LocalCredentialBundleError";
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=local-credential-bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-credential-bundle.d.ts","sourceRoot":"","sources":["../../src/node/local-credential-bundle.ts"],"names":[],"mappings":"AA4BA,eAAO,MAAM,6BAA6B;;;;;;;EAO/B,CAAC;AA0BZ,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB,EAAE,MAAM,CAAC;IAChC,6BAA6B,EAAE,MAAM,CAAC;IACtC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gCAAgC,EAAE,MAAM,CAAC;IACzC,4BAA4B,EAAE,MAAM,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,mCAAmC,GAAG;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,0BAA0B,CAAC;CACnC,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,+BAA+B,CACnD,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,mCAAmC,CAAC,CA2C9C;AAED,6EAA6E;AAC7E,wBAAsB,6BAA6B,CACjD,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,0BAA0B,CAAC,CA4CrC;AAiID,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,QAAQ,CAAC,IAAI,gCAAgC;CAC9C"}
|