@yolk-sdk/emulators 0.1.0-canary.96
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/LICENSE +21 -0
- package/README.md +2135 -0
- package/dist/anthropic.d.mts +269 -0
- package/dist/anthropic.d.mts.map +1 -0
- package/dist/anthropic.mjs +177 -0
- package/dist/anthropic.mjs.map +1 -0
- package/dist/chat-completions.d.mts +288 -0
- package/dist/chat-completions.d.mts.map +1 -0
- package/dist/chat-completions.mjs +451 -0
- package/dist/chat-completions.mjs.map +1 -0
- package/dist/codex.d.mts +265 -0
- package/dist/codex.d.mts.map +1 -0
- package/dist/codex.mjs +199 -0
- package/dist/codex.mjs.map +1 -0
- package/dist/dropbox/api.d.mts +63 -0
- package/dist/dropbox/api.d.mts.map +1 -0
- package/dist/dropbox/api.mjs +565 -0
- package/dist/dropbox/api.mjs.map +1 -0
- package/dist/dropbox/state.d.mts +136 -0
- package/dist/dropbox/state.d.mts.map +1 -0
- package/dist/dropbox/state.mjs +209 -0
- package/dist/dropbox/state.mjs.map +1 -0
- package/dist/dropbox.d.mts +79 -0
- package/dist/dropbox.d.mts.map +1 -0
- package/dist/dropbox.mjs +124 -0
- package/dist/dropbox.mjs.map +1 -0
- package/dist/email-fixtures.d.mts +36 -0
- package/dist/email-fixtures.d.mts.map +1 -0
- package/dist/email-fixtures.mjs +1080 -0
- package/dist/email-fixtures.mjs.map +1 -0
- package/dist/email.d.mts +160 -0
- package/dist/email.d.mts.map +1 -0
- package/dist/email.mjs +608 -0
- package/dist/email.mjs.map +1 -0
- package/dist/emulator-compose.d.mts +40 -0
- package/dist/emulator-compose.d.mts.map +1 -0
- package/dist/emulator-compose.mjs +91 -0
- package/dist/emulator-compose.mjs.map +1 -0
- package/dist/emulator-http.d.mts +53 -0
- package/dist/emulator-http.d.mts.map +1 -0
- package/dist/emulator-http.mjs +117 -0
- package/dist/emulator-http.mjs.map +1 -0
- package/dist/emulator-kernel.d.mts +176 -0
- package/dist/emulator-kernel.d.mts.map +1 -0
- package/dist/emulator-kernel.mjs +413 -0
- package/dist/emulator-kernel.mjs.map +1 -0
- package/dist/fixture-route.d.mts +129 -0
- package/dist/fixture-route.d.mts.map +1 -0
- package/dist/fixture-route.mjs +257 -0
- package/dist/fixture-route.mjs.map +1 -0
- package/dist/fortnox/api.d.mts +92 -0
- package/dist/fortnox/api.d.mts.map +1 -0
- package/dist/fortnox/api.mjs +750 -0
- package/dist/fortnox/api.mjs.map +1 -0
- package/dist/fortnox/state.d.mts +533 -0
- package/dist/fortnox/state.d.mts.map +1 -0
- package/dist/fortnox/state.mjs +612 -0
- package/dist/fortnox/state.mjs.map +1 -0
- package/dist/fortnox.d.mts +128 -0
- package/dist/fortnox.d.mts.map +1 -0
- package/dist/fortnox.mjs +403 -0
- package/dist/fortnox.mjs.map +1 -0
- package/dist/gateway-evaluate-recordings.d.mts +12 -0
- package/dist/gateway-evaluate-recordings.d.mts.map +1 -0
- package/dist/gateway-evaluate-recordings.mjs +128 -0
- package/dist/gateway-evaluate-recordings.mjs.map +1 -0
- package/dist/gateway.d.mts +272 -0
- package/dist/gateway.d.mts.map +1 -0
- package/dist/gateway.mjs +400 -0
- package/dist/gateway.mjs.map +1 -0
- package/dist/github/api.d.mts +63 -0
- package/dist/github/api.d.mts.map +1 -0
- package/dist/github/api.mjs +527 -0
- package/dist/github/api.mjs.map +1 -0
- package/dist/github/state.d.mts +272 -0
- package/dist/github/state.d.mts.map +1 -0
- package/dist/github/state.mjs +303 -0
- package/dist/github/state.mjs.map +1 -0
- package/dist/github.d.mts +77 -0
- package/dist/github.d.mts.map +1 -0
- package/dist/github.mjs +180 -0
- package/dist/github.mjs.map +1 -0
- package/dist/google/calendar.d.mts +10 -0
- package/dist/google/calendar.d.mts.map +1 -0
- package/dist/google/calendar.mjs +252 -0
- package/dist/google/calendar.mjs.map +1 -0
- package/dist/google/drive.d.mts +8 -0
- package/dist/google/drive.d.mts.map +1 -0
- package/dist/google/drive.mjs +252 -0
- package/dist/google/drive.mjs.map +1 -0
- package/dist/google/gmail.d.mts +10 -0
- package/dist/google/gmail.d.mts.map +1 -0
- package/dist/google/gmail.mjs +591 -0
- package/dist/google/gmail.mjs.map +1 -0
- package/dist/google/shared.d.mts +107 -0
- package/dist/google/shared.d.mts.map +1 -0
- package/dist/google/shared.mjs +146 -0
- package/dist/google/shared.mjs.map +1 -0
- package/dist/google/state.d.mts +385 -0
- package/dist/google/state.d.mts.map +1 -0
- package/dist/google/state.mjs +496 -0
- package/dist/google/state.mjs.map +1 -0
- package/dist/google.d.mts +75 -0
- package/dist/google.d.mts.map +1 -0
- package/dist/google.mjs +210 -0
- package/dist/google.mjs.map +1 -0
- package/dist/linkedin-search/api.d.mts +45 -0
- package/dist/linkedin-search/api.d.mts.map +1 -0
- package/dist/linkedin-search/api.mjs +181 -0
- package/dist/linkedin-search/api.mjs.map +1 -0
- package/dist/linkedin-search/state.d.mts +123 -0
- package/dist/linkedin-search/state.d.mts.map +1 -0
- package/dist/linkedin-search/state.mjs +261 -0
- package/dist/linkedin-search/state.mjs.map +1 -0
- package/dist/linkedin-search.d.mts +69 -0
- package/dist/linkedin-search.d.mts.map +1 -0
- package/dist/linkedin-search.mjs +158 -0
- package/dist/linkedin-search.mjs.map +1 -0
- package/dist/mcp/api.d.mts +44 -0
- package/dist/mcp/api.d.mts.map +1 -0
- package/dist/mcp/api.mjs +557 -0
- package/dist/mcp/api.mjs.map +1 -0
- package/dist/mcp/recordings.d.mts +40 -0
- package/dist/mcp/recordings.d.mts.map +1 -0
- package/dist/mcp/recordings.mjs +2390 -0
- package/dist/mcp/recordings.mjs.map +1 -0
- package/dist/mcp/state.d.mts +71 -0
- package/dist/mcp/state.d.mts.map +1 -0
- package/dist/mcp/state.mjs +83 -0
- package/dist/mcp/state.mjs.map +1 -0
- package/dist/mcp.d.mts +84 -0
- package/dist/mcp.d.mts.map +1 -0
- package/dist/mcp.mjs +241 -0
- package/dist/mcp.mjs.map +1 -0
- package/dist/messages.d.mts +183 -0
- package/dist/messages.d.mts.map +1 -0
- package/dist/messages.mjs +532 -0
- package/dist/messages.mjs.map +1 -0
- package/dist/microsoft/api.d.mts +47 -0
- package/dist/microsoft/api.d.mts.map +1 -0
- package/dist/microsoft/api.mjs +178 -0
- package/dist/microsoft/api.mjs.map +1 -0
- package/dist/microsoft/calendar.d.mts +30 -0
- package/dist/microsoft/calendar.d.mts.map +1 -0
- package/dist/microsoft/calendar.mjs +271 -0
- package/dist/microsoft/calendar.mjs.map +1 -0
- package/dist/microsoft/drive.d.mts +36 -0
- package/dist/microsoft/drive.d.mts.map +1 -0
- package/dist/microsoft/drive.mjs +298 -0
- package/dist/microsoft/drive.mjs.map +1 -0
- package/dist/microsoft/graph.d.mts +198 -0
- package/dist/microsoft/graph.d.mts.map +1 -0
- package/dist/microsoft/graph.mjs +264 -0
- package/dist/microsoft/graph.mjs.map +1 -0
- package/dist/microsoft/mail.d.mts +48 -0
- package/dist/microsoft/mail.d.mts.map +1 -0
- package/dist/microsoft/mail.mjs +488 -0
- package/dist/microsoft/mail.mjs.map +1 -0
- package/dist/microsoft/state.d.mts +480 -0
- package/dist/microsoft/state.d.mts.map +1 -0
- package/dist/microsoft/state.mjs +625 -0
- package/dist/microsoft/state.mjs.map +1 -0
- package/dist/microsoft.d.mts +168 -0
- package/dist/microsoft.d.mts.map +1 -0
- package/dist/microsoft.mjs +483 -0
- package/dist/microsoft.mjs.map +1 -0
- package/dist/node.d.mts +47 -0
- package/dist/node.d.mts.map +1 -0
- package/dist/node.mjs +178 -0
- package/dist/node.mjs.map +1 -0
- package/dist/notion/api.d.mts +51 -0
- package/dist/notion/api.d.mts.map +1 -0
- package/dist/notion/api.mjs +507 -0
- package/dist/notion/api.mjs.map +1 -0
- package/dist/notion/state.d.mts +329 -0
- package/dist/notion/state.d.mts.map +1 -0
- package/dist/notion/state.mjs +432 -0
- package/dist/notion/state.mjs.map +1 -0
- package/dist/notion.d.mts +72 -0
- package/dist/notion.d.mts.map +1 -0
- package/dist/notion.mjs +127 -0
- package/dist/notion.mjs.map +1 -0
- package/dist/openai.d.mts +165 -0
- package/dist/openai.d.mts.map +1 -0
- package/dist/openai.mjs +141 -0
- package/dist/openai.mjs.map +1 -0
- package/dist/opencode-recordings.d.mts +7 -0
- package/dist/opencode-recordings.d.mts.map +1 -0
- package/dist/opencode-recordings.mjs +222 -0
- package/dist/opencode-recordings.mjs.map +1 -0
- package/dist/opencode.d.mts +70 -0
- package/dist/opencode.d.mts.map +1 -0
- package/dist/opencode.mjs +217 -0
- package/dist/opencode.mjs.map +1 -0
- package/dist/r2-fixtures.d.mts +36 -0
- package/dist/r2-fixtures.d.mts.map +1 -0
- package/dist/r2-fixtures.mjs +245 -0
- package/dist/r2-fixtures.mjs.map +1 -0
- package/dist/r2-guard.d.mts +43 -0
- package/dist/r2-guard.d.mts.map +1 -0
- package/dist/r2-guard.mjs +215 -0
- package/dist/r2-guard.mjs.map +1 -0
- package/dist/r2.d.mts +166 -0
- package/dist/r2.d.mts.map +1 -0
- package/dist/r2.mjs +517 -0
- package/dist/r2.mjs.map +1 -0
- package/dist/responses.d.mts +231 -0
- package/dist/responses.d.mts.map +1 -0
- package/dist/responses.mjs +556 -0
- package/dist/responses.mjs.map +1 -0
- package/dist/route-evidence.d.mts +45 -0
- package/dist/route-evidence.d.mts.map +1 -0
- package/dist/route-evidence.mjs +56 -0
- package/dist/route-evidence.mjs.map +1 -0
- package/dist/router.d.mts +93 -0
- package/dist/router.d.mts.map +1 -0
- package/dist/router.mjs +259 -0
- package/dist/router.mjs.map +1 -0
- package/dist/stateful-core.d.mts +17 -0
- package/dist/stateful-core.d.mts.map +1 -0
- package/dist/stateful-core.mjs +41 -0
- package/dist/stateful-core.mjs.map +1 -0
- package/dist/stateful-emulator.d.mts +565 -0
- package/dist/stateful-emulator.d.mts.map +1 -0
- package/dist/stateful-emulator.mjs +1228 -0
- package/dist/stateful-emulator.mjs.map +1 -0
- package/dist/stateful-secrets.d.mts +84 -0
- package/dist/stateful-secrets.d.mts.map +1 -0
- package/dist/stateful-secrets.mjs +216 -0
- package/dist/stateful-secrets.mjs.map +1 -0
- package/dist/subscription-usage-recordings.d.mts +9 -0
- package/dist/subscription-usage-recordings.d.mts.map +1 -0
- package/dist/subscription-usage-recordings.mjs +53 -0
- package/dist/subscription-usage-recordings.mjs.map +1 -0
- package/dist/subscription-usage.d.mts +53 -0
- package/dist/subscription-usage.d.mts.map +1 -0
- package/dist/subscription-usage.mjs +21 -0
- package/dist/subscription-usage.mjs.map +1 -0
- package/dist/telegram/api.d.mts +34 -0
- package/dist/telegram/api.d.mts.map +1 -0
- package/dist/telegram/api.mjs +257 -0
- package/dist/telegram/api.mjs.map +1 -0
- package/dist/telegram/state.d.mts +128 -0
- package/dist/telegram/state.d.mts.map +1 -0
- package/dist/telegram/state.mjs +154 -0
- package/dist/telegram/state.mjs.map +1 -0
- package/dist/telegram.d.mts +62 -0
- package/dist/telegram.d.mts.map +1 -0
- package/dist/telegram.mjs +127 -0
- package/dist/telegram.mjs.map +1 -0
- package/dist/todoist/api.d.mts +55 -0
- package/dist/todoist/api.d.mts.map +1 -0
- package/dist/todoist/api.mjs +415 -0
- package/dist/todoist/api.mjs.map +1 -0
- package/dist/todoist/state.d.mts +275 -0
- package/dist/todoist/state.d.mts.map +1 -0
- package/dist/todoist/state.mjs +345 -0
- package/dist/todoist/state.mjs.map +1 -0
- package/dist/todoist.d.mts +68 -0
- package/dist/todoist.d.mts.map +1 -0
- package/dist/todoist.mjs +181 -0
- package/dist/todoist.mjs.map +1 -0
- package/dist/xai.d.mts +267 -0
- package/dist/xai.d.mts.map +1 -0
- package/dist/xai.mjs +252 -0
- package/dist/xai.mjs.map +1 -0
- package/package.json +157 -0
- package/src/anthropic.ts +289 -0
- package/src/chat-completions.ts +924 -0
- package/src/codex.ts +296 -0
- package/src/dropbox/api.ts +1084 -0
- package/src/dropbox/state.ts +364 -0
- package/src/dropbox.ts +203 -0
- package/src/email-fixtures.ts +1297 -0
- package/src/email.ts +1108 -0
- package/src/emulator-compose.ts +147 -0
- package/src/emulator-http.ts +184 -0
- package/src/emulator-kernel.ts +844 -0
- package/src/fixture-route.ts +561 -0
- package/src/fortnox/api.ts +1352 -0
- package/src/fortnox/state.ts +798 -0
- package/src/fortnox.ts +801 -0
- package/src/gateway-evaluate-recordings.ts +153 -0
- package/src/gateway.ts +530 -0
- package/src/github/api.ts +986 -0
- package/src/github/state.ts +439 -0
- package/src/github.ts +271 -0
- package/src/google/calendar.ts +486 -0
- package/src/google/drive.ts +471 -0
- package/src/google/gmail.ts +1011 -0
- package/src/google/shared.ts +321 -0
- package/src/google/state.ts +686 -0
- package/src/google.ts +298 -0
- package/src/linkedin-search/api.ts +363 -0
- package/src/linkedin-search/state.ts +373 -0
- package/src/linkedin-search.ts +241 -0
- package/src/mcp/api.ts +995 -0
- package/src/mcp/recordings.ts +2665 -0
- package/src/mcp/state.ts +125 -0
- package/src/mcp.ts +319 -0
- package/src/messages.ts +844 -0
- package/src/microsoft/api.ts +426 -0
- package/src/microsoft/calendar.ts +491 -0
- package/src/microsoft/drive.ts +541 -0
- package/src/microsoft/graph.ts +550 -0
- package/src/microsoft/mail.ts +833 -0
- package/src/microsoft/state.ts +822 -0
- package/src/microsoft.ts +982 -0
- package/src/node.ts +293 -0
- package/src/notion/api.ts +976 -0
- package/src/notion/state.ts +512 -0
- package/src/notion.ts +210 -0
- package/src/openai.ts +198 -0
- package/src/opencode-recordings.ts +257 -0
- package/src/opencode.ts +271 -0
- package/src/r2-fixtures.ts +295 -0
- package/src/r2-guard.ts +323 -0
- package/src/r2.ts +890 -0
- package/src/responses.ts +901 -0
- package/src/route-evidence.ts +90 -0
- package/src/router.ts +490 -0
- package/src/stateful-core.ts +70 -0
- package/src/stateful-emulator.ts +2571 -0
- package/src/stateful-secrets.ts +299 -0
- package/src/subscription-usage-recordings.ts +77 -0
- package/src/subscription-usage.ts +68 -0
- package/src/telegram/api.ts +437 -0
- package/src/telegram/state.ts +229 -0
- package/src/telegram.ts +227 -0
- package/src/todoist/api.ts +736 -0
- package/src/todoist/state.ts +456 -0
- package/src/todoist.ts +316 -0
- package/src/xai.ts +341 -0
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
import { EmulatorEvidence, EmulatorRouteEvidence } from "./route-evidence.mjs";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
|
|
4
|
+
//#region src/stateful-emulator.d.ts
|
|
5
|
+
declare const NotEmulated_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => Readonly<A> & {
|
|
6
|
+
readonly _tag: "NotEmulated";
|
|
7
|
+
} & import("effect/Pipeable").Pipeable;
|
|
8
|
+
/** A request the emulator does not emulate, with the reason (answered 400 not-emulated). */
|
|
9
|
+
declare class NotEmulated extends NotEmulated_base<{
|
|
10
|
+
readonly reason: string;
|
|
11
|
+
}> {}
|
|
12
|
+
declare const DecodedViewRefusal_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => import("effect/Cause").YieldableError & {
|
|
13
|
+
readonly _tag: "DecodedViewRefusal";
|
|
14
|
+
} & Readonly<A>;
|
|
15
|
+
/**
|
|
16
|
+
* What a route's decoded view throws to refuse a body with a reason of its own (fail-closed mode;
|
|
17
|
+
* see `StatefulRouteBinding.decodedViews`). `reason` must be one of the route's declared
|
|
18
|
+
* `viewRefusalReasons` (a constant the route owns, never derived from the request); `decoded` holds
|
|
19
|
+
* any text the view did decode cleanly, which is still checked for the bearer first.
|
|
20
|
+
*/
|
|
21
|
+
declare class DecodedViewRefusal extends DecodedViewRefusal_base<{
|
|
22
|
+
readonly reason: string;
|
|
23
|
+
readonly decoded: ReadonlyArray<string>;
|
|
24
|
+
}> {}
|
|
25
|
+
declare const notEmulated: (reason: string) => NotEmulated;
|
|
26
|
+
declare const isNotEmulated: (value: unknown) => value is NotEmulated;
|
|
27
|
+
declare const jsonResponse: (status: number, body: unknown, headers?: HeadersInit) => Response;
|
|
28
|
+
/** The one answer for everything no fixture records. */
|
|
29
|
+
declare const notEmulatedResponse: (reason: string) => Response;
|
|
30
|
+
/**
|
|
31
|
+
* Optional fault filter; an omitted field matches every request. `method` is the HTTP method
|
|
32
|
+
* (never a manifest row's `RPC`). `path` is the raw request path (in resolved mode, the
|
|
33
|
+
* resolution's ledger path); ending in `*`, a prefix. `route` is a manifest row path, compared
|
|
34
|
+
* with the request's ledger route: the template of its matched route, or the manifest variant its
|
|
35
|
+
* route admitted it as (see `StatefulRouteBinding.variants`).
|
|
36
|
+
* A `route` that names no manifest row of the emulator could never match, so adding the fault
|
|
37
|
+
* rejects it (a route with variants is matched by its variant rows, never its template).
|
|
38
|
+
*/
|
|
39
|
+
declare const StatefulFaultMatch: Schema.Struct<{
|
|
40
|
+
readonly method: Schema.optionalKey<Schema.String>;
|
|
41
|
+
readonly path: Schema.optionalKey<Schema.String>;
|
|
42
|
+
readonly route: Schema.optionalKey<Schema.String>;
|
|
43
|
+
}>;
|
|
44
|
+
type StatefulFaultMatch = typeof StatefulFaultMatch.Type;
|
|
45
|
+
/**
|
|
46
|
+
* A status fault: answer matching requests with this status (400-599), headers, and body before
|
|
47
|
+
* the route runs, so nothing is written. The body defaults to an emulator-fault body
|
|
48
|
+
* (`{ error: { type: 'emulator_fault', message } }`), never a guessed provider envelope. `count`
|
|
49
|
+
* limits how many requests it answers (omitted: all). `match.path` is the raw request path.
|
|
50
|
+
* Invalid header names or values, `location`, and framing headers are rejected.
|
|
51
|
+
*/
|
|
52
|
+
declare const StatefulFault: Schema.Struct<{
|
|
53
|
+
readonly kind: Schema.Literal<"status">;
|
|
54
|
+
readonly status: Schema.Int;
|
|
55
|
+
readonly headers: Schema.optionalKey<Schema.$Record<Schema.String, Schema.String>>;
|
|
56
|
+
readonly body: Schema.optionalKey<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
57
|
+
readonly match: Schema.optionalKey<Schema.Struct<{
|
|
58
|
+
readonly method: Schema.optionalKey<Schema.String>;
|
|
59
|
+
readonly path: Schema.optionalKey<Schema.String>;
|
|
60
|
+
readonly route: Schema.optionalKey<Schema.String>;
|
|
61
|
+
}>>;
|
|
62
|
+
readonly count: Schema.optionalKey<Schema.Int>;
|
|
63
|
+
}>;
|
|
64
|
+
type StatefulFault = typeof StatefulFault.Type;
|
|
65
|
+
/**
|
|
66
|
+
* Opt-in (`makeChunkedStatefulEmulator`): send the first `chunks` body chunks of the answer a
|
|
67
|
+
* streamed commit prepared (`StreamedCommit`), then close the body cleanly (a truncated answer).
|
|
68
|
+
* It is decided where a status fault is, after the plan, and a truncated request writes nothing:
|
|
69
|
+
* its `commit` never runs (no state, counter, or runtime change). One that cannot take effect (the
|
|
70
|
+
* answer is not streamed, or has no more than `chunks` chunks) answers the 500 emulator error and
|
|
71
|
+
* is not used up, never a silent no-op.
|
|
72
|
+
*/
|
|
73
|
+
declare const StatefulTruncateFault: Schema.Struct<{
|
|
74
|
+
readonly kind: Schema.Literal<"truncate-after-chunks">;
|
|
75
|
+
readonly chunks: Schema.Int;
|
|
76
|
+
readonly match: Schema.optionalKey<Schema.Struct<{
|
|
77
|
+
readonly method: Schema.optionalKey<Schema.String>;
|
|
78
|
+
readonly path: Schema.optionalKey<Schema.String>;
|
|
79
|
+
readonly route: Schema.optionalKey<Schema.String>;
|
|
80
|
+
}>>;
|
|
81
|
+
readonly count: Schema.optionalKey<Schema.Int>;
|
|
82
|
+
}>;
|
|
83
|
+
type StatefulTruncateFault = typeof StatefulTruncateFault.Type;
|
|
84
|
+
/** A status fault, or (`makeChunkedStatefulEmulator`) a truncation fault. */
|
|
85
|
+
declare const StatefulStreamFault: Schema.Union<readonly [Schema.Struct<{
|
|
86
|
+
readonly kind: Schema.Literal<"status">;
|
|
87
|
+
readonly status: Schema.Int;
|
|
88
|
+
readonly headers: Schema.optionalKey<Schema.$Record<Schema.String, Schema.String>>;
|
|
89
|
+
readonly body: Schema.optionalKey<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
90
|
+
readonly match: Schema.optionalKey<Schema.Struct<{
|
|
91
|
+
readonly method: Schema.optionalKey<Schema.String>;
|
|
92
|
+
readonly path: Schema.optionalKey<Schema.String>;
|
|
93
|
+
readonly route: Schema.optionalKey<Schema.String>;
|
|
94
|
+
}>>;
|
|
95
|
+
readonly count: Schema.optionalKey<Schema.Int>;
|
|
96
|
+
}>, Schema.Struct<{
|
|
97
|
+
readonly kind: Schema.Literal<"truncate-after-chunks">;
|
|
98
|
+
readonly chunks: Schema.Int;
|
|
99
|
+
readonly match: Schema.optionalKey<Schema.Struct<{
|
|
100
|
+
readonly method: Schema.optionalKey<Schema.String>;
|
|
101
|
+
readonly path: Schema.optionalKey<Schema.String>;
|
|
102
|
+
readonly route: Schema.optionalKey<Schema.String>;
|
|
103
|
+
}>>;
|
|
104
|
+
readonly count: Schema.optionalKey<Schema.Int>;
|
|
105
|
+
}>]>;
|
|
106
|
+
type StatefulStreamFault = typeof StatefulStreamFault.Type;
|
|
107
|
+
type StatefulFaultState<Fault = StatefulFault> = {
|
|
108
|
+
readonly id: number;
|
|
109
|
+
readonly fault: Fault; /** Remaining matching requests; `undefined` for an unlimited fault. */
|
|
110
|
+
readonly remaining: number | undefined;
|
|
111
|
+
readonly applied: number;
|
|
112
|
+
};
|
|
113
|
+
type StatefulLedgerEntry = {
|
|
114
|
+
/** 1-based arrival order since the last ledger clear or reset. */readonly seq: number;
|
|
115
|
+
readonly method: string;
|
|
116
|
+
/**
|
|
117
|
+
* Raw request path; in fail-closed mode with guarded secrets scrubbed, in resolved mode the
|
|
118
|
+
* resolution's ledger path (scrubbed), and `/<unrecognised>` for an unrecognised request.
|
|
119
|
+
*/
|
|
120
|
+
readonly path: string; /** Path template of the matched route. */
|
|
121
|
+
readonly route?: string; /** Query parameters; the values of credential-named keys are `<redacted>`. */
|
|
122
|
+
readonly query: Readonly<Record<string, string>>; /** Parsed JSON request body, with credential-named keys redacted at any depth. */
|
|
123
|
+
readonly body?: Schema.Json; /** Length of a raw (non-JSON) request body. */
|
|
124
|
+
readonly bodyBytes?: number;
|
|
125
|
+
/**
|
|
126
|
+
* The non-credential request headers the emulator records (lower-case names); a JSON header is
|
|
127
|
+
* recorded with credential-named keys redacted at any depth, or as `<redacted>` when unparseable.
|
|
128
|
+
*/
|
|
129
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
130
|
+
readonly status: number; /** Evidence of the matched route; `unknown-route` for requests on no route. */
|
|
131
|
+
readonly evidence: EmulatorEvidence | 'unknown-route'; /** Why the request was answered 400 not-emulated. */
|
|
132
|
+
readonly notEmulated?: string; /** Set when a fault answered the request (`truncate-after-chunks` cut its streamed body). */
|
|
133
|
+
readonly fault?: 'status' | 'truncate-after-chunks'; /** Set when the emulator could not build the response, or a route threw (answered 500). */
|
|
134
|
+
readonly responseError?: string;
|
|
135
|
+
};
|
|
136
|
+
type StatefulRouteCoverage = EmulatorRouteEvidence & {
|
|
137
|
+
/** Ledger requests on this route since the last ledger clear or reset. */readonly requests: number;
|
|
138
|
+
};
|
|
139
|
+
type StatefulCoverage = {
|
|
140
|
+
readonly routes: ReadonlyArray<StatefulRouteCoverage>; /** Ledger requests on no route. */
|
|
141
|
+
readonly unknownRouteRequests: number; /** Ledger requests answered 400 not-emulated (on a route or not). */
|
|
142
|
+
readonly notEmulatedRequests: number;
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* A ledger entry of an emulator built with `makeHeaderlessStatefulEmulator`, which records no
|
|
146
|
+
* request header and takes status faults only: the entry carries no `headers` field, no
|
|
147
|
+
* `bodyBytes` (it has no `bytes` routes), and only a `status` fault.
|
|
148
|
+
*/
|
|
149
|
+
type StatefulHeaderlessLedgerEntry = Omit<StatefulLedgerEntry, 'headers' | 'bodyBytes' | 'fault'> & {
|
|
150
|
+
/** Set when a fault answered the request. */readonly fault?: 'status';
|
|
151
|
+
};
|
|
152
|
+
/** One routed API request, as a route sees it. */
|
|
153
|
+
type EmulatedRequest = {
|
|
154
|
+
readonly method: string; /** Raw (still percent-encoded) path; in resolved mode, the resolution's ledger path. */
|
|
155
|
+
readonly path: string;
|
|
156
|
+
/**
|
|
157
|
+
* Path parameters, percent-decoded once; in resolved mode (`resolveRequest`), the parameters the
|
|
158
|
+
* resolution supplies (never a credential).
|
|
159
|
+
*/
|
|
160
|
+
readonly params: Readonly<Record<string, string>>;
|
|
161
|
+
readonly query: URLSearchParams;
|
|
162
|
+
/**
|
|
163
|
+
* The raw query (after `?`, before `#`, never decoded; `''` without one), as the wrapper saw it.
|
|
164
|
+
* Absent on a request built elsewhere (then `exactQuery`'s `rawNames` refuses any parameter).
|
|
165
|
+
*/
|
|
166
|
+
readonly rawQuery?: string | undefined;
|
|
167
|
+
/**
|
|
168
|
+
* A non-credential request header (credential headers always read as `undefined`; in resolved
|
|
169
|
+
* mode, every header but `content-type` does).
|
|
170
|
+
*/
|
|
171
|
+
readonly header: (name: string) => string | undefined;
|
|
172
|
+
/**
|
|
173
|
+
* The lower-case names of every request header, credential headers included (names only, never
|
|
174
|
+
* a credential value); none in resolved mode. Absent on a request built elsewhere.
|
|
175
|
+
*/
|
|
176
|
+
readonly headerNames?: ReadonlyArray<string> | undefined; /** Parsed JSON body (`json` routes, and `json-or-empty` routes with a body). */
|
|
177
|
+
readonly json: Schema.Json | undefined; /** Raw body (`bytes` routes). */
|
|
178
|
+
readonly bytes: Uint8Array | undefined;
|
|
179
|
+
/**
|
|
180
|
+
* Fail-closed mode with `bearerDigest` only: the digest of the recognised bearer for the origin
|
|
181
|
+
* the request arrived on (never the bearer itself); `undefined` otherwise.
|
|
182
|
+
*/
|
|
183
|
+
readonly bearerDigest?: string | undefined;
|
|
184
|
+
};
|
|
185
|
+
type RunContext<Env> = {
|
|
186
|
+
readonly env: Env; /** Ledger sequence number of the request (for synthetic request ids). */
|
|
187
|
+
readonly seq: number;
|
|
188
|
+
};
|
|
189
|
+
/** The writing part of an eligible request: applies its change and answers. */
|
|
190
|
+
type Commit = () => Response;
|
|
191
|
+
/** A streamed answer: its status, headers, and body chunks (sent one per pull). */
|
|
192
|
+
type StreamedAnswer = {
|
|
193
|
+
readonly status: number;
|
|
194
|
+
readonly headers: Readonly<Record<string, string>>; /** The body chunks; none answers no body at all. */
|
|
195
|
+
readonly chunks: ReadonlyArray<string>;
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* A commit whose answer the plan prepares: `answer` is sent (one chunk per pull) only after
|
|
199
|
+
* `commit` has written the request's change. Because the answer exists before anything is
|
|
200
|
+
* written, the wrapper decides faults against it: a status fault or a `truncate-after-chunks`
|
|
201
|
+
* fault (`makeChunkedStatefulEmulator`) answers without running `commit`, so a faulted request
|
|
202
|
+
* writes nothing. `persisted` lists the texts `commit` will store (minted ids, for example), which
|
|
203
|
+
* the opt-in output guard (`guardOutput`) checks together with the answer.
|
|
204
|
+
*/
|
|
205
|
+
type StreamedCommit = {
|
|
206
|
+
readonly answer: StreamedAnswer;
|
|
207
|
+
readonly commit: () => void;
|
|
208
|
+
readonly persisted: ReadonlyArray<string>;
|
|
209
|
+
};
|
|
210
|
+
/** A streamed commit: the prepared `answer`, and the write (none by default) it commits. */
|
|
211
|
+
declare const streamedCommit: (answer: StreamedAnswer, commit?: () => void, persisted?: ReadonlyArray<string>) => StreamedCommit;
|
|
212
|
+
/** What a plan returns: a commit, a streamed commit, or not emulated. */
|
|
213
|
+
type Planned = Commit | StreamedCommit | NotEmulated;
|
|
214
|
+
/** An admitted request: its pure, state-reading eligibility check, returning the commit. */
|
|
215
|
+
type Admission<State, Env> = {
|
|
216
|
+
readonly plan: (state: State, context: RunContext<Env>) => Planned;
|
|
217
|
+
/**
|
|
218
|
+
* The path of the manifest variant the request was admitted as (`StatefulRouteBinding.variants`):
|
|
219
|
+
* required when the route has variants, absent otherwise.
|
|
220
|
+
*/
|
|
221
|
+
readonly variant?: string;
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* The body a route takes: none; JSON with an `application/json` media type; JSON of any media type
|
|
225
|
+
* or none (`json-or-empty`: an empty body is no body, any other must be valid JSON, and the route
|
|
226
|
+
* checks the media type itself); or raw bytes.
|
|
227
|
+
*/
|
|
228
|
+
type RouteBody = 'none' | 'json' | 'json-or-empty' | 'bytes';
|
|
229
|
+
/** Route parts that are not evidence: the recorded origin and the raw parameter patterns. */
|
|
230
|
+
type StatefulRouteBinding = {
|
|
231
|
+
/** The origin a fixture records the route on; another origin is not emulated. Omitted: any. */readonly origin?: string;
|
|
232
|
+
/**
|
|
233
|
+
* Raw (still percent-encoded) patterns of the path parameters; a parameter that does not match
|
|
234
|
+
* its pattern makes the path match no route. Fail-closed emulators give every parameter one.
|
|
235
|
+
*/
|
|
236
|
+
readonly params?: Readonly<Record<string, RegExp>>;
|
|
237
|
+
/**
|
|
238
|
+
* Fail-closed mode only: texts the route derives from its raw body that the provider's wire
|
|
239
|
+
* format encodes in a way the percent and JSON closure cannot see through (for example base64url
|
|
240
|
+
* content). Each view is checked for the bearer like the raw body. A body that holds no such
|
|
241
|
+
* content yields no view. A view may throw to refuse a body whose encoded content it cannot
|
|
242
|
+
* check completely (for example content the route would refuse anyway); the request is then
|
|
243
|
+
* ledgered as the constant credential-repeat entry shape, before anything is recorded, a fault is
|
|
244
|
+
* decided, or anything is committed, with this reason:
|
|
245
|
+
*
|
|
246
|
+
* - `the request body repeats the credential` when the throw is a `DecodedViewRefusal` whose
|
|
247
|
+
* cleanly `decoded` texts hold the bearer (a repeat, not a refusal);
|
|
248
|
+
* - otherwise its `reason` when that is one of `viewRefusalReasons` (scrubbed of the bearer,
|
|
249
|
+
* defensively);
|
|
250
|
+
* - otherwise (an undeclared reason, or any other throw)
|
|
251
|
+
* `the request body cannot be checked for the credential`.
|
|
252
|
+
*
|
|
253
|
+
* Omitted: none.
|
|
254
|
+
*/
|
|
255
|
+
readonly decodedViews?: (body: string) => ReadonlyArray<string>;
|
|
256
|
+
/**
|
|
257
|
+
* The constant reasons a decoded view may refuse a body with (`DecodedViewRefusal`); any other
|
|
258
|
+
* reason is replaced by the uncheckable reason. Owned by the route, never derived from a request.
|
|
259
|
+
*/
|
|
260
|
+
readonly viewRefusalReasons?: ReadonlyArray<string>;
|
|
261
|
+
/**
|
|
262
|
+
* Opt-in: the manifest rows this route answers INSTEAD of its own (for example one row per
|
|
263
|
+
* JSON-RPC method on one HTTP endpoint, `{ method: 'RPC', path: '<origin><path>#<method>' }`).
|
|
264
|
+
* Each admission names its row (`Admission.variant`), which becomes the request's ledger route,
|
|
265
|
+
* its coverage row, and what a fault's `match.route` compares; a request refused before it is
|
|
266
|
+
* admitted keeps the route's own template. Every variant carries the route's evidence, and no
|
|
267
|
+
* variant path repeats another manifest row or a route template (checked at build). Omitted:
|
|
268
|
+
* the route is its own manifest row, as before.
|
|
269
|
+
*/
|
|
270
|
+
readonly variants?: ReadonlyArray<EmulatorRouteEvidence>;
|
|
271
|
+
};
|
|
272
|
+
type StatefulRoute<State, Env> = EmulatorRouteEvidence & StatefulRouteBinding & {
|
|
273
|
+
readonly body: RouteBody; /** The request-shape check (reads no state): an admission, or not emulated. */
|
|
274
|
+
readonly admit: (request: EmulatedRequest, env: Env) => Admission<State, Env> | NotEmulated;
|
|
275
|
+
};
|
|
276
|
+
/**
|
|
277
|
+
* A route of the table: its evidence (and recorded origin), the body it takes, its request-shape
|
|
278
|
+
* check `admit` (no state), and `plan`, which only ever sees an admitted input: it reads the state
|
|
279
|
+
* without writing and answers not emulated or the commit that writes.
|
|
280
|
+
*/
|
|
281
|
+
declare const statefulRoute: <State, Env, Input>(evidence: EmulatorRouteEvidence & StatefulRouteBinding, body: RouteBody, admit: (request: EmulatedRequest, env: Env) => Input | NotEmulated, plan: (state: State, input: Input, context: RunContext<Env>) => Planned) => StatefulRoute<State, Env>;
|
|
282
|
+
/** Route evidence without the handler parts. */
|
|
283
|
+
declare const routeEvidence: <State, Env>({
|
|
284
|
+
body: _body,
|
|
285
|
+
admit: _admit,
|
|
286
|
+
origin: _origin,
|
|
287
|
+
params: _params,
|
|
288
|
+
decodedViews: _decodedViews,
|
|
289
|
+
viewRefusalReasons: _viewRefusalReasons,
|
|
290
|
+
variants: _variants,
|
|
291
|
+
...evidence
|
|
292
|
+
}: StatefulRoute<State, Env>) => EmulatorRouteEvidence;
|
|
293
|
+
/** The manifest rows of a route: its variants, or the route itself (`routeEvidence`). */
|
|
294
|
+
declare const routeManifest: <State, Env>(route: StatefulRoute<State, Env>) => ReadonlyArray<EmulatorRouteEvidence>;
|
|
295
|
+
/** A percent-decoded path segment, or `undefined` for invalid percent-encoding. */
|
|
296
|
+
declare const decodeSegment: (segment: string) => string | undefined;
|
|
297
|
+
type MatchedRoute<State, Env> = {
|
|
298
|
+
readonly route: StatefulRoute<State, Env>;
|
|
299
|
+
readonly params: Readonly<Record<string, string>>;
|
|
300
|
+
};
|
|
301
|
+
/**
|
|
302
|
+
* A matcher over a route table: the route answering `method` + raw `path`, with its parameters
|
|
303
|
+
* decoded once, or `undefined` (also for a parameter that is not valid percent-encoding). A raw
|
|
304
|
+
* parameter pattern must match the whole raw parameter; a pattern with the `g` or `y` flag (whose
|
|
305
|
+
* matches depend on earlier ones) is refused when the matcher is built.
|
|
306
|
+
*/
|
|
307
|
+
declare const routeMatcher: <State, Env>(routes: ReadonlyArray<StatefulRoute<State, Env>>) => (method: string, path: string) => MatchedRoute<State, Env> | undefined;
|
|
308
|
+
/** The template parameters of a route that have no raw pattern (fail-closed emulators need one). */
|
|
309
|
+
declare const unpatternedParams: <State, Env>(route: StatefulRoute<State, Env>) => ReadonlyArray<string>;
|
|
310
|
+
/** Parsed JSON, or `undefined` for invalid JSON. */
|
|
311
|
+
declare const parseJsonText: (text: string) => Schema.Json | undefined;
|
|
312
|
+
declare const isJsonObject: (value: Schema.Json | undefined) => value is Schema.JsonObject;
|
|
313
|
+
/**
|
|
314
|
+
* True when any object of a valid JSON text repeats a key, compared after JSON unescaping (so
|
|
315
|
+
* `"id"` and `"\u0069d"` are one key). `JSON.parse` would keep the last value silently.
|
|
316
|
+
*/
|
|
317
|
+
declare const repeatsJsonKey: (text: string) => boolean;
|
|
318
|
+
/** The media type of a `content-type` value (lower-case, without parameters). */
|
|
319
|
+
declare const mediaType: (value: string | undefined) => string;
|
|
320
|
+
/**
|
|
321
|
+
* A JSON object with exactly the `required` keys plus any of the `optional` ones, or not
|
|
322
|
+
* emulated (naming the first missing or unknown key).
|
|
323
|
+
*/
|
|
324
|
+
declare const exactObject: (value: Schema.Json | undefined, label: string, required: ReadonlyArray<string>, optional?: ReadonlyArray<string>) => Schema.JsonObject | NotEmulated;
|
|
325
|
+
/**
|
|
326
|
+
* Constant-text shape check (for fail-closed emulators): a JSON object with exactly the `required`
|
|
327
|
+
* keys plus any of the `optional` ones, or not emulated. Unlike `exactObject`, a reason never
|
|
328
|
+
* echoes a request's own key; it names only `label` and a missing key from the route's own list.
|
|
329
|
+
*/
|
|
330
|
+
declare const exactBodyKeys: (value: Schema.Json | undefined, label: string, required: ReadonlyArray<string>, optional?: ReadonlyArray<string>) => Schema.JsonObject | NotEmulated;
|
|
331
|
+
/** Options of `exactQuery`. */
|
|
332
|
+
type ExactQueryOptions = {
|
|
333
|
+
/**
|
|
334
|
+
* Opt-in: every raw parameter name (before `URLSearchParams` decodes it) must be written exactly
|
|
335
|
+
* as the route names it, so a percent-encoded or `+`-spaced spelling of an accepted name is not
|
|
336
|
+
* emulated. Omitted: names are compared decoded, as before.
|
|
337
|
+
*/
|
|
338
|
+
readonly rawNames?: boolean;
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* Constant-text query check (for fail-closed emulators): exactly the `required` query keys plus
|
|
342
|
+
* any of the `optional` ones, each once, as a record of their values; or not emulated. A reason
|
|
343
|
+
* never echoes a request's own key; it names only a missing key from the route's own list. With
|
|
344
|
+
* `rawNames`, every raw parameter name must also be the plain name it decodes to.
|
|
345
|
+
*/
|
|
346
|
+
declare const exactQuery: (request: EmulatedRequest, required: ReadonlyArray<string>, optional?: ReadonlyArray<string>, options?: ExactQueryOptions) => Readonly<Record<string, string>> | NotEmulated;
|
|
347
|
+
/** An integer in `[minimum, maximum]`, or not emulated. */
|
|
348
|
+
declare const integerIn: (value: Schema.Json | undefined, label: string, minimum: number, maximum: number) => number | NotEmulated;
|
|
349
|
+
/** Error-input kinds of the JS API. */
|
|
350
|
+
type StatefulInputKind = 'seed' | 'fault' | 'option';
|
|
351
|
+
/** The core runtime the Node subpath creates (state, snapshot, restore), as the wrapper uses it. */
|
|
352
|
+
type StatefulCore<State> = {
|
|
353
|
+
readonly fetch: (request: Request) => Promise<Response>;
|
|
354
|
+
readonly baseUrl: string;
|
|
355
|
+
readonly snapshot: () => State;
|
|
356
|
+
readonly restore: (state: State) => Promise<void>;
|
|
357
|
+
readonly close: () => Promise<void>;
|
|
358
|
+
};
|
|
359
|
+
/**
|
|
360
|
+
* What the core runs for a request the wrapper forwarded: `(state, request)` to a response. The
|
|
361
|
+
* Node subpath registers it as the core app's only route.
|
|
362
|
+
*/
|
|
363
|
+
type CoreDispatch<State> = (state: State, request: Request) => Response;
|
|
364
|
+
/** A request header the ledger records. */
|
|
365
|
+
type RecordedHeader = {
|
|
366
|
+
readonly name: string;
|
|
367
|
+
readonly json: boolean;
|
|
368
|
+
};
|
|
369
|
+
/**
|
|
370
|
+
* Fail-closed mode: the constant reasons ledgered and answered for an unrecognised request (no
|
|
371
|
+
* emulated route shape) and for an unrecognisable `Authorization` header. Nothing the request
|
|
372
|
+
* carries is ledgered or answered for either.
|
|
373
|
+
*/
|
|
374
|
+
type StatefulFailClosed = {
|
|
375
|
+
readonly unrecognised: string;
|
|
376
|
+
readonly unrecognisedAuthorization: string;
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Resolved mode: what the emulator's `resolveRequest` decides for one API request, failing closed.
|
|
380
|
+
*
|
|
381
|
+
* - `unrecognised`: the raw request matches no emulated route shape exactly (or its credential
|
|
382
|
+
* cannot be extracted). It is ledgered and answered with constant text only
|
|
383
|
+
* (`/<unrecognised>`, the method as sent when it is a standard one, else `<other>`, an empty
|
|
384
|
+
* query, no headers or body, the constant `reason`).
|
|
385
|
+
* - `refused`: a recognised route refuses the request before its body is read (a missing
|
|
386
|
+
* credential, a query key it does not take); the entry keeps the request's scrubbed fields.
|
|
387
|
+
* - `route`: a recognised request, handed to `route` with the credential-free `params`.
|
|
388
|
+
*
|
|
389
|
+
* For `refused` and `route`, `ledgerPath` is the path the ledger records (and a fault's
|
|
390
|
+
* `match.path` compares), with the credential already replaced by the emulator if the path carries
|
|
391
|
+
* it; `secrets` are the credential values the emulator took from the recognised shape (a path
|
|
392
|
+
* segment, a header), which the wrapper scrubs from everything it ledgers or answers and refuses
|
|
393
|
+
* to see repeated. `guardedPath` is the request text besides the query that must not repeat a
|
|
394
|
+
* secret (the path without the segment that carries the credential, for example).
|
|
395
|
+
*/
|
|
396
|
+
type StatefulResolution<State, Env> = {
|
|
397
|
+
readonly kind: 'unrecognised';
|
|
398
|
+
readonly reason: string;
|
|
399
|
+
} | {
|
|
400
|
+
readonly kind: 'refused';
|
|
401
|
+
readonly route: StatefulRoute<State, Env>;
|
|
402
|
+
readonly ledgerPath: string;
|
|
403
|
+
readonly reason: string;
|
|
404
|
+
readonly secrets: ReadonlyArray<string>;
|
|
405
|
+
} | {
|
|
406
|
+
readonly kind: 'route';
|
|
407
|
+
readonly route: StatefulRoute<State, Env>;
|
|
408
|
+
readonly params: Readonly<Record<string, string>>;
|
|
409
|
+
readonly ledgerPath: string;
|
|
410
|
+
readonly guardedPath: string;
|
|
411
|
+
readonly secrets: ReadonlyArray<string>;
|
|
412
|
+
};
|
|
413
|
+
/**
|
|
414
|
+
* The emulator-owned texts of its recovery answers
|
|
415
|
+
* (`{ error: { type: 'emulator_error', message } }`): `failed` when a response cannot be built or a
|
|
416
|
+
* route throws (500), `closed` after `close` (503), and `unhandled` when handling the request
|
|
417
|
+
* itself fails (500).
|
|
418
|
+
*/
|
|
419
|
+
type StatefulErrorTexts = {
|
|
420
|
+
readonly failed: string;
|
|
421
|
+
readonly closed: string;
|
|
422
|
+
readonly unhandled: string;
|
|
423
|
+
};
|
|
424
|
+
type StatefulEmulatorConfig<State, Env> = {
|
|
425
|
+
readonly routes: ReadonlyArray<StatefulRoute<State, Env>>;
|
|
426
|
+
readonly env: Env;
|
|
427
|
+
readonly initial: State; /** Decode and build a seed; a string is why it is invalid. */
|
|
428
|
+
readonly buildSeed: (input: unknown) => State | string; /** Header rules every request must meet (after the credential); a string is not emulated. */
|
|
429
|
+
readonly requestProblem?: (header: (name: string) => string | undefined) => string | undefined;
|
|
430
|
+
/**
|
|
431
|
+
* Non-credential request headers the ledger records (lower-case names). A `json` header is
|
|
432
|
+
* parsed and its credential-named keys redacted at any depth; an unparseable value is recorded
|
|
433
|
+
* as `<redacted>`. A credential header name is refused when the emulator is built.
|
|
434
|
+
*/
|
|
435
|
+
readonly recordHeaders: ReadonlyArray<RecordedHeader>;
|
|
436
|
+
/**
|
|
437
|
+
* Opt-in fail-closed mode (see the module header): constant-text ledger entries for unrecognised
|
|
438
|
+
* requests and Authorization headers, and the bearer value guarded as a secret. Every route
|
|
439
|
+
* parameter must have a raw pattern (checked when the emulator is built).
|
|
440
|
+
*/
|
|
441
|
+
readonly failClosed?: StatefulFailClosed;
|
|
442
|
+
/**
|
|
443
|
+
* Opt-in resolved mode (not with `failClosed`; checked when the emulator is built), for an
|
|
444
|
+
* emulator whose credential the wrapper cannot find by itself (a token in a path segment) or
|
|
445
|
+
* that has its own credential rules: the emulator resolves every API request itself
|
|
446
|
+
* (`StatefulResolution`) instead of the wrapper's route match and `Authorization` handling, and
|
|
447
|
+
* names the credential values to guard. The wrapper then records the resolution's ledger path
|
|
448
|
+
* and the query as sent (credential-named keys redacted), both scrubbed of the secrets, matches a
|
|
449
|
+
* fault's `match.path` against that ledger path, and refuses, before the request headers are
|
|
450
|
+
* checked or the body is parsed, a recognised request that repeats a secret: the raw query, the
|
|
451
|
+
* `guardedPath`, or the body, each raw or percent-decoded once (`repeatsSecret`), and a JSON body
|
|
452
|
+
* also in any key, string, or number once parsed and as it would be recorded
|
|
453
|
+
* (`jsonRepeatsSecret`). Those refusals keep the request's scrubbed fields and never record the
|
|
454
|
+
* body. Routes see the ledger path and no header names; fault answers and refusals are returned
|
|
455
|
+
* outside the core; `recordHeaders` must be empty (checked at build). See the module header.
|
|
456
|
+
* Omitted: the wrapper matches routes itself, as before.
|
|
457
|
+
*/
|
|
458
|
+
readonly resolveRequest?: (request: Request, url: URL) => StatefulResolution<State, Env>;
|
|
459
|
+
/**
|
|
460
|
+
* Opt-in: the texts of the emulator's recovery answers (`StatefulErrorTexts`). Omitted: the
|
|
461
|
+
* default texts, as before.
|
|
462
|
+
*/
|
|
463
|
+
readonly errorTexts?: StatefulErrorTexts;
|
|
464
|
+
/**
|
|
465
|
+
* Opt-in, fail-closed mode only (checked when the emulator is built): a one-way digest of a
|
|
466
|
+
* recognised bearer for the origin the request arrived on, handed to routes as
|
|
467
|
+
* `EmulatedRequest.bearerDigest`, never the bearer itself. A route compares it with digests its
|
|
468
|
+
* state holds (for example of the keys a seed marks as rejected on one origin), so a credential
|
|
469
|
+
* can change an answer without the bearer reaching the state, the ledger, or `/_emulate/*`.
|
|
470
|
+
* Taking the origin makes the digest per origin: one key gives different digests on two origins.
|
|
471
|
+
* A digest that throws or repeats the bearer (through the closure) answers the 500 emulator
|
|
472
|
+
* error before the route's shape check (no fault used, nothing written). Omitted: routes see no
|
|
473
|
+
* digest, as before.
|
|
474
|
+
*/
|
|
475
|
+
readonly bearerDigest?: (bearer: string, origin: string) => string;
|
|
476
|
+
/**
|
|
477
|
+
* Opt-in, fail-closed mode only (checked at build): every refusal is ledgered with constant text
|
|
478
|
+
* only, like an unrecognised request (`/<unrecognised>`, a standard method or `<other>`, an
|
|
479
|
+
* empty query, no headers or body), keeping only its constant route (template or variant) and
|
|
480
|
+
* reason, so a ledger entry holds request text only once the route admitted the request. Route
|
|
481
|
+
* reasons must then be constants. Omitted: refusals keep the request's recorded fields, as
|
|
482
|
+
* before.
|
|
483
|
+
*/
|
|
484
|
+
readonly constantRefusals?: boolean;
|
|
485
|
+
/**
|
|
486
|
+
* Opt-in, fail-closed mode only (checked at build): every request header other than
|
|
487
|
+
* `Authorization`, its name and its value, is checked for a credential repeat through the
|
|
488
|
+
* closure (not only the recorded headers), independently of what the ledger records; a repeat is
|
|
489
|
+
* refused with the constant credential-repeat entry (`a request header repeats the credential`).
|
|
490
|
+
* Omitted: only the recorded headers are checked, as before.
|
|
491
|
+
*/
|
|
492
|
+
readonly guardAllHeaders?: boolean;
|
|
493
|
+
/**
|
|
494
|
+
* Opt-in, fail-closed mode only (checked at build): a recognised request's prepared output must
|
|
495
|
+
* not repeat its bearer. Every plan answers a `StreamedCommit` (a plain `Commit` answers the 500
|
|
496
|
+
* emulator error), and before any fault is decided or anything is committed, every answer header
|
|
497
|
+
* name and value, every answer chunk, and every `persisted` text are checked for the bearer
|
|
498
|
+
* through the closure; a hit is refused with the constant credential-repeat entry
|
|
499
|
+
* (`the answer would repeat the credential`), no fault used and nothing written. Routes still see
|
|
500
|
+
* only the bearer's digest. Omitted: answers are not checked, as before.
|
|
501
|
+
*/
|
|
502
|
+
readonly guardOutput?: boolean;
|
|
503
|
+
/**
|
|
504
|
+
* Opt-in: a JSON body in which any object repeats a key (after JSON unescaping, so `"id"` and
|
|
505
|
+
* `"\u0069d"` are one key) is not emulated (`a JSON body with a repeated key is not emulated`),
|
|
506
|
+
* instead of `JSON.parse` keeping the last value. Omitted: the last value wins, as before.
|
|
507
|
+
*/
|
|
508
|
+
readonly uniqueJsonKeys?: boolean; /** Clear runtime data (cursors) on reset and seed. */
|
|
509
|
+
readonly clearRuntime: () => void; /** Extra `/_emulate/state` fields (runtime data). */
|
|
510
|
+
readonly runtimeState: () => Schema.JsonObject; /** The `/_emulate/seed` answer for a new state. */
|
|
511
|
+
readonly seedSummary: (state: State) => Schema.JsonObject;
|
|
512
|
+
readonly inputInvalid: (input: StatefulInputKind, reason: string) => Error;
|
|
513
|
+
};
|
|
514
|
+
type StatefulEmulatorApi<State, Seed, Fault = StatefulFault, Entry = StatefulLedgerEntry> = {
|
|
515
|
+
/**
|
|
516
|
+
* The fetch handler (API routes and `/_emulate/*`); a request arrives on the origin of its URL.
|
|
517
|
+
* Never rejects.
|
|
518
|
+
*/
|
|
519
|
+
readonly fetch: (request: Request) => Promise<Response>;
|
|
520
|
+
/**
|
|
521
|
+
* The fetch handler for requests that arrive on `origin` whatever their URL says (serve it on
|
|
522
|
+
* a loopback server behind `EmulatedHttpClient`, which rewrites the origin). Never rejects.
|
|
523
|
+
*/
|
|
524
|
+
readonly fetchOn: (origin: string) => (request: Request) => Promise<Response>;
|
|
525
|
+
readonly ledger: {
|
|
526
|
+
readonly entries: () => ReadonlyArray<Entry>;
|
|
527
|
+
readonly clear: () => void;
|
|
528
|
+
};
|
|
529
|
+
readonly faults: {
|
|
530
|
+
/** Add a fault; throws the emulator's input-invalid error for an invalid fault. */readonly add: (fault: Fault) => StatefulFaultState<Fault>;
|
|
531
|
+
readonly list: () => ReadonlyArray<StatefulFaultState<Fault>>;
|
|
532
|
+
readonly clear: () => void;
|
|
533
|
+
}; /** Restore the current seed and clear the ledger, faults, and runtime data (cursors). */
|
|
534
|
+
readonly reset: () => Promise<void>;
|
|
535
|
+
/**
|
|
536
|
+
* Replace the state with a new seed, which becomes what `reset` restores (runtime data is
|
|
537
|
+
* cleared). Rejects with the emulator's input-invalid error for an invalid seed.
|
|
538
|
+
*/
|
|
539
|
+
readonly seed: (seed: Seed) => Promise<void>; /** A deep copy of the current state. */
|
|
540
|
+
readonly snapshot: () => State;
|
|
541
|
+
readonly coverage: () => StatefulCoverage; /** Close the core runtime. Later requests answer 503. Idempotent. */
|
|
542
|
+
readonly close: () => Promise<void>;
|
|
543
|
+
};
|
|
544
|
+
/**
|
|
545
|
+
* Build the wrapper over a core runtime. `createCore` receives the dispatch the core must run for
|
|
546
|
+
* every request (its only route) and returns the runtime adapter. Faults are status faults only.
|
|
547
|
+
*/
|
|
548
|
+
declare const makeStatefulEmulator: <State, Env, Seed>(config: StatefulEmulatorConfig<State, Env>, createCore: (dispatch: CoreDispatch<State>) => Promise<StatefulCore<State>>) => Promise<StatefulEmulatorApi<State, Seed>>;
|
|
549
|
+
/**
|
|
550
|
+
* `makeStatefulEmulator` for an emulator that records no request header (opt-in): it takes no
|
|
551
|
+
* `recordHeaders`, and its ledger entries carry no `headers` field
|
|
552
|
+
* (`StatefulHeaderlessLedgerEntry`). Faults are status faults only.
|
|
553
|
+
*/
|
|
554
|
+
declare const makeHeaderlessStatefulEmulator: <State, Env, Seed>(config: Omit<StatefulEmulatorConfig<State, Env>, "recordHeaders">, createCore: (dispatch: CoreDispatch<State>) => Promise<StatefulCore<State>>) => Promise<StatefulEmulatorApi<State, Seed, StatefulFault, StatefulHeaderlessLedgerEntry>>;
|
|
555
|
+
/**
|
|
556
|
+
* `makeStatefulEmulator` that also takes `truncate-after-chunks` faults
|
|
557
|
+
* (`StatefulTruncateFault`), which cut a streamed answer (`StreamedCommit`). Opt-in: the other
|
|
558
|
+
* emulators keep status faults only.
|
|
559
|
+
*/
|
|
560
|
+
declare const makeChunkedStatefulEmulator: <State, Env, Seed>(config: StatefulEmulatorConfig<State, Env>, createCore: (dispatch: CoreDispatch<State>) => Promise<StatefulCore<State>>) => Promise<StatefulEmulatorApi<State, Seed, StatefulStreamFault>>;
|
|
561
|
+
/** Throws `inputInvalid('option', ...)` unless every drill knob is a known boolean (or absent). */
|
|
562
|
+
declare const checkBooleanDrills: (drills: object | undefined, knobs: ReadonlyArray<string>, inputInvalid: (input: StatefulInputKind, reason: string) => Error) => void;
|
|
563
|
+
//#endregion
|
|
564
|
+
export { Admission, Commit, CoreDispatch, DecodedViewRefusal, EmulatedRequest, ExactQueryOptions, MatchedRoute, NotEmulated, Planned, RecordedHeader, RouteBody, RunContext, StatefulCore, StatefulCoverage, StatefulEmulatorApi, StatefulEmulatorConfig, StatefulErrorTexts, StatefulFailClosed, StatefulFault, StatefulFaultMatch, StatefulFaultState, StatefulHeaderlessLedgerEntry, StatefulInputKind, StatefulLedgerEntry, StatefulResolution, StatefulRoute, StatefulRouteBinding, StatefulRouteCoverage, StatefulStreamFault, StatefulTruncateFault, StreamedAnswer, StreamedCommit, checkBooleanDrills, decodeSegment, exactBodyKeys, exactObject, exactQuery, integerIn, isJsonObject, isNotEmulated, jsonResponse, makeChunkedStatefulEmulator, makeHeaderlessStatefulEmulator, makeStatefulEmulator, mediaType, notEmulated, notEmulatedResponse, parseJsonText, repeatsJsonKey, routeEvidence, routeManifest, routeMatcher, statefulRoute, streamedCommit, unpatternedParams };
|
|
565
|
+
//# sourceMappingURL=stateful-emulator.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateful-emulator.d.mts","names":[],"sources":["../src/stateful-emulator.ts"],"mappings":";;;;cAmK4B,gBAAA;;;;cAYf,WAAA,SAAoB,gBAAA;EAAA,SAA2C,MAAM;AAAA;AAAA,cAAc,uBAAA;;;;;;;;;cAQnF,kBAAA,SAA2B,uBAAA;EAAA,SAC7B,MAAA;EAAA,SACA,OAAA,EAAS,aAAA;AAAA;AAAA,cAGP,WAAA,GAAe,MAAA,aAAiB,WAA0C;AAAA,cAE1E,aAAA,GAAiB,KAAA,cAAiB,KAAA,IAAS,WAA2C;AAAA,cAEtF,YAAA,GACX,MAAA,UACA,IAAA,WACA,OAAA,GAAS,WAAA,KACR,QAQF;;cAGY,mBAAA,GAAuB,MAAA,aAAiB,QACuC;;;;;AAjC5F;;;;AAAkF;cAwDrE,kBAAA,EAAkB,MAAA,CAAA,MAAA;EAAA;;;;KAMnB,kBAAA,UAA4B,kBAAA,CAAmB,IAAI;;;;;;;;cASlD,aAAA,EAAa,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;KASd,aAAA,UAAuB,aAAA,CAAc,IAAI;;;;AAxErD;;;;;cAkFa,qBAAA,EAAqB,MAAA,CAAA,MAAA;EAAA;;;;;;;;;KAOtB,qBAAA,UAA+B,qBAAA,CAAsB,IAAI;;cAGxD,mBAAA,EAAmB,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;KAEpB,mBAAA,UAA6B,mBAAA,CAAoB,IAAI;AAAA,KAErD,kBAAA,SAA2B,aAAA;EAAA,SAC5B,EAAA;EAAA,SACA,KAAA,EAAO,KAAK;WAEZ,SAAA;EAAA,SACA,OAAA;AAAA;AAAA,KAGC,mBAAA;6EAED,GAAA;EAAA,SACA,MAAA;EA3DoB;;;;EAAA,SAgEpB,IAAA;WAEA,KAAA;WAEA,KAAA,EAAO,QAAA,CAAS,MAAA;WAEhB,IAAA,GAAO,MAAA,CAAO,IAAA;WAEd,SAAA;;;;;WAKA,OAAA,EAAS,QAAA,CAAS,MAAA;EAAA,SAClB,MAAA;WAEA,QAAA,EAAU,gBAAA,oBA1ET;EAAA,SA4ED,WAAA;WAEA,KAAA,uCA9EoD;EAAA,SAgFpD,aAAA;AAAA;AAAA,KAGC,qBAAA,GAAwB,qBAAqB;qFAE9C,QAAQ;AAAA;AAAA,KAGP,gBAAA;EAAA,SACD,MAAA,EAAQ,aAAa,CAAC,qBAAA;WAEtB,oBAAA;WAEA,mBAAA;AAAA;;;;;;KAQC,6BAAA,GAAgC,IAAI,CAC9C,mBAAA;wDAIS,KAAA;AAAA;;KAIC,eAAA;EAAA,SACD,MAAA,UAtGe;EAAA,SAwGf,IAAA;EAxGe;;;;EAAA,SA6Gf,MAAA,EAAQ,QAAA,CAAS,MAAA;EAAA,SACjB,KAAA,EAAO,eAAA;;;;;WAKP,QAAA;;;;;WAKA,MAAA,GAAS,IAAA;;;;;WAKT,WAAA,GAAc,aAAA;WAEd,IAAA,EAAM,MAAA,CAAO,IAAA;WAEb,KAAA,EAAO,UAAA;;;;;WAKP,YAAA;AAAA;AAAA,KAGC,UAAA;EAAA,SACD,GAAA,EAAK,GAAG;WAER,GAAA;AAAA;;KAIC,MAAA,SAAe,QAAQ;;KAGvB,cAAA;EAAA,SACD,MAAA;EAAA,SACA,OAAA,EAAS,QAAA,CAAS,MAAA;WAElB,MAAA,EAAQ,aAAA;AAAA;;;;;;;;AA9InB;KAyJY,cAAA;EAAA,SACD,MAAA,EAAQ,cAAA;EAAA,SACR,MAAA;EAAA,SACA,SAAA,EAAW,aAAa;AAAA;;cAItB,cAAA,GACX,MAAA,EAAQ,cAAA,EACR,MAAA,eACA,SAAA,GAAW,aAAA,aACV,cAAA;;KAGS,OAAA,GAAU,MAAA,GAAS,cAAA,GAAiB,WAAA;;KAGpC,SAAA;EAAA,SACD,IAAA,GAAO,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,UAAA,CAAW,GAAA,MAAS,OAAA;;;;;WAKlD,OAAA;AAAA;;;;;;KAQC,SAAA;;KAGA,oBAAA;0GAED,MAAA;;;;;WAKA,MAAA,GAAS,QAAA,CAAS,MAAA,SAAe,MAAA;;;;;;;;;;;;;;;;;;;WAmBjC,YAAA,IAAgB,IAAA,aAAiB,aAAA;;;;;WAKjC,kBAAA,GAAqB,aAAA;EAzMpB;;;;AAAyD;AAGrE;;;;EAHY,SAmND,QAAA,GAAW,aAAA,CAAc,qBAAA;AAAA;AAAA,KAGxB,aAAA,eAA4B,qBAAA,GACtC,oBAAA;EAAA,SACW,IAAA,EAAM,SAAA;WAEN,KAAA,GAAQ,OAAA,EAAS,eAAA,EAAiB,GAAA,EAAK,GAAA,KAAQ,SAAA,CAAU,KAAA,EAAO,GAAA,IAAO,WAAA;AAAA;;;;;;cAQvE,aAAA,sBACX,QAAA,EAAU,qBAAA,GAAwB,oBAAA,EAClC,IAAA,EAAM,SAAA,EACN,KAAA,GAAQ,OAAA,EAAS,eAAA,EAAiB,GAAA,EAAK,GAAA,KAAQ,KAAA,GAAQ,WAAA,EACvD,IAAA,GAAO,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,UAAA,CAAW,GAAA,MAAS,OAAA,KAC/D,aAAA,CAAc,KAAA,EAAO,GAAA;;cAWX,aAAA;EAA6B,IAAA,EAAA,KAAA;EAAA,KAAA,EAAA,MAAA;EAAA,MAAA,EAAA,OAAA;EAAA,MAAA,EAAA,OAAA;EAAA,YAAA,EAAA,aAAA;EAAA,kBAAA,EAAA,mBAAA;EAAA,QAAA,EAAA,SAAA;EAAA,GAAA;AAAA,GASvC,aAAA,CAAc,KAAA,EAAO,GAAA,MAAO,qBAAA;;cAGlB,aAAA,eACX,KAAA,EAAO,aAAA,CAAc,KAAA,EAAO,GAAA,MAC3B,aAAA,CAAc,qBAAA;;cAGJ,aAAA,GAAiB,OAAe;AAAA,KAwCjC,YAAA;EAAA,SACD,KAAA,EAAO,aAAA,CAAc,KAAA,EAAO,GAAA;EAAA,SAC5B,MAAA,EAAQ,QAAA,CAAS,MAAA;AAAA;;;;;;;cAgBf,YAAA,eAA4B,MAAA,EAAQ,aAAA,CAAc,aAAA,CAAc,KAAA,EAAO,GAAA,QA6B1E,MAAA,UAAgB,IAAA,aAAe,YAAA,CAAa,KAAA,EAAO,GAAA;;cAuChD,iBAAA,eACX,KAAA,EAAO,aAAA,CAAc,KAAA,EAAO,GAAA,MAC3B,aAAA;;cAKU,aAAA,GAAiB,IAAA,aAAe,MAAA,CAAO,IAAI;AAAA,cAM3C,YAAA,GAAgB,KAAA,EAAO,MAAA,CAAO,IAAA,iBAAmB,KAAA,IAAS,MAAA,CAAO,UACe;;;;;cAMhF,cAAA,GAAkB,IAAY;;cA4C9B,SAAA,GAAa,KAAyB;;;;;cAOtC,WAAA,GACX,KAAA,EAAO,MAAA,CAAO,IAAA,cACd,KAAA,UACA,QAAA,EAAU,aAAA,UACV,QAAA,GAAU,aAAA,aACT,MAAA,CAAO,UAAA,GAAa,WAAA;;;;;;cAmBV,aAAA,GACX,KAAA,EAAO,MAAA,CAAO,IAAA,cACd,KAAA,UACA,QAAA,EAAU,aAAA,UACV,QAAA,GAAU,aAAA,aACT,MAAA,CAAO,UAAA,GAAa,WAAA;;KAiBX,iBAAA;;;;;;WAMD,QAAQ;AAAA;;;;;;;cAaN,UAAA,GACX,OAAA,EAAS,eAAA,EACT,QAAA,EAAU,aAAA,UACV,QAAA,GAAU,aAAA,UACV,OAAA,GAAS,iBAAA,KACR,QAAA,CAAS,MAAA,oBAA0B,WAAA;;cA2BzB,SAAA,GACX,KAAA,EAAO,MAAA,CAAO,IAAA,cACd,KAAA,UACA,OAAA,UACA,OAAA,sBACU,WAGkE;;KAGlE,iBAAA;;KAGA,YAAA;EAAA,SACD,KAAA,GAAQ,OAAA,EAAS,OAAA,KAAY,OAAA,CAAQ,QAAA;EAAA,SACrC,OAAA;EAAA,SACA,QAAA,QAAgB,KAAA;EAAA,SAChB,OAAA,GAAU,KAAA,EAAO,KAAA,KAAU,OAAA;EAAA,SAC3B,KAAA,QAAa,OAAA;AAAA;;;;;KAOZ,YAAA,WAAuB,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,OAAA,KAAY,QAAA;;KAG1D,cAAA;EAAA,SAA4B,IAAA;EAAA,SAAuB,IAAI;AAAA;;;;;;KAOvD,kBAAA;EAAA,SACD,YAAA;EAAA,SACA,yBAAyB;AAAA;;;;;;;;;;;;;;;;;;;KAqBxB,kBAAA;EAAA,SACG,IAAA;EAAA,SAA+B,MAAA;AAAA;EAAA,SAE/B,IAAA;EAAA,SACA,KAAA,EAAO,aAAA,CAAc,KAAA,EAAO,GAAA;EAAA,SAC5B,UAAA;EAAA,SACA,MAAA;EAAA,SACA,OAAA,EAAS,aAAA;AAAA;EAAA,SAGT,IAAA;EAAA,SACA,KAAA,EAAO,aAAA,CAAc,KAAA,EAAO,GAAA;EAAA,SAC5B,MAAA,EAAQ,QAAA,CAAS,MAAA;EAAA,SACjB,UAAA;EAAA,SACA,WAAA;EAAA,SACA,OAAA,EAAS,aAAA;AAAA;;;;;;;KASZ,kBAAA;EAAA,SACD,MAAA;EAAA,SACA,MAAA;EAAA,SACA,SAAA;AAAA;AAAA,KASC,sBAAA;EAAA,SACD,MAAA,EAAQ,aAAA,CAAc,aAAA,CAAc,KAAA,EAAO,GAAA;EAAA,SAC3C,GAAA,EAAK,GAAA;EAAA,SACL,OAAA,EAAS,KAAA,EApmBC;EAAA,SAsmBV,SAAA,GAAY,KAAA,cAAmB,KAAA,WAtmBL;EAAA,SAwmB1B,cAAA,IAAkB,MAAA,GAAS,IAAA;EA7nB3B;;;;;EAAA,SAmoBA,aAAA,EAAe,aAAA,CAAc,cAAA;EAxnB7B;;;;;EAAA,SA8nBA,UAAA,GAAa,kBAAA;EAvnBK;;;;;;;;AASL;AAGxB;;;;AAEmB;AAGnB;;EAjB6B,SAwoBlB,cAAA,IAAkB,OAAA,EAAS,OAAA,EAAS,GAAA,EAAK,GAAA,KAAQ,kBAAA,CAAmB,KAAA,EAAO,GAAA;EAtnBtD;;;;EAAA,SA2nBrB,UAAA,GAAa,kBAAA;EAvnBb;;AAAmB;AAQ9B;;;;;;;;EARW,SAmoBA,YAAA,IAAgB,MAAA,UAAgB,MAAA;EAlnB/B;;;;;;;;EAAA,SA2nBD,gBAAA;EA/lBiB;;;;;;;EAAA,SAumBjB,eAAA;EA1nBO;;;;;;;;;EAAA,SAooBP,WAAA;EAjnBO;;;AAKK;AAGvB;EARkB,SAunBP,cAAA,YA/mBW;EAAA,SAinBX,YAAA,cAjnBY;EAAA,SAmnBZ,YAAA,QAAoB,MAAA,CAAO,UAAA,EAlnBtB;EAAA,SAonBL,WAAA,GAAc,KAAA,EAAO,KAAA,KAAU,MAAA,CAAO,UAAA;EAAA,SACtC,YAAA,GAAe,KAAA,EAAO,iBAAA,EAAmB,MAAA,aAAmB,KAAA;AAAA;AAAA,KAG3D,mBAAA,sBAAyC,aAAA,UAAuB,mBAAA;EAlnB1D;;;AAAiB;EAAjB,SAunBP,KAAA,GAAQ,OAAA,EAAS,OAAA,KAAY,OAAA,CAAQ,QAAA;EApnBtB;;;;EAAA,SAynBf,OAAA,GAAU,MAAA,cAAoB,OAAA,EAAS,OAAA,KAAY,OAAA,CAAQ,QAAA;EAAA,SAC3D,MAAA;IAAA,SACE,OAAA,QAAe,aAAA,CAAc,KAAA;IAAA,SAC7B,KAAA;EAAA;EAAA,SAEF,MAAA;IA5nBkB,4FA8nBhB,GAAA,GAAM,KAAA,EAAO,KAAA,KAAU,kBAAA,CAAmB,KAAA;IAAA,SAC1C,IAAA,QAAY,aAAA,CAAc,kBAAA,CAAmB,KAAA;IAAA,SAC7C,KAAA;EAAA,GAnnBD;EAAA,SAsnBD,KAAA,QAAa,OAAA;;;;;WAKb,IAAA,GAAO,IAAA,EAAM,IAAA,KAAS,OAAA,QAxnBtB;EAAA,SA0nBA,QAAA,QAAgB,KAAA;EAAA,SAChB,QAAA,QAAgB,gBAAA,EA3nBQ;EAAA,SA6nBxB,KAAA,QAAa,OAAA;AAAA;;;;;cAk7CX,oBAAA,qBACX,MAAA,EAAQ,sBAAA,CAAuB,KAAA,EAAO,GAAA,GACtC,UAAA,GAAa,QAAA,EAAU,YAAA,CAAa,KAAA,MAAW,OAAA,CAAQ,YAAA,CAAa,KAAA,OACnE,OAAA,CAAQ,mBAAA,CAAoB,KAAA,EAAO,IAAA;;;;;;cAgBzB,8BAAA,qBACX,MAAA,EAAQ,IAAA,CAAK,sBAAA,CAAuB,KAAA,EAAO,GAAA,qBAC3C,UAAA,GAAa,QAAA,EAAU,YAAA,CAAa,KAAA,MAAW,OAAA,CAAQ,YAAA,CAAa,KAAA,OACnE,OAAA,CAAQ,mBAAA,CAAoB,KAAA,EAAO,IAAA,EAAM,aAAA,EAAe,6BAAA;;;AA7jEP;AAGpD;;cA0kEa,2BAAA,qBACX,MAAA,EAAQ,sBAAA,CAAuB,KAAA,EAAO,GAAA,GACtC,UAAA,GAAa,QAAA,EAAU,YAAA,CAAa,KAAA,MAAW,OAAA,CAAQ,YAAA,CAAa,KAAA,OACnE,OAAA,CAAQ,mBAAA,CAAoB,KAAA,EAAO,IAAA,EAAM,mBAAA;;cAS/B,kBAAA,GACX,MAAA,sBACA,KAAA,EAAO,aAAA,UACP,YAAA,GAAe,KAAA,EAAO,iBAAA,EAAmB,MAAA,aAAmB,KAAA"}
|