@attestry/sdk 0.6.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/LICENSE +190 -0
- package/README.md +1269 -0
- package/dist/client.d.ts +58 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +74 -0
- package/dist/client.js.map +1 -0
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +43 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/lines-parser.d.ts +50 -0
- package/dist/lines-parser.d.ts.map +1 -0
- package/dist/lines-parser.js +211 -0
- package/dist/lines-parser.js.map +1 -0
- package/dist/ndjson-parser.d.ts +57 -0
- package/dist/ndjson-parser.d.ts.map +1 -0
- package/dist/ndjson-parser.js +245 -0
- package/dist/ndjson-parser.js.map +1 -0
- package/dist/resources/abac-policies.d.ts +1034 -0
- package/dist/resources/abac-policies.d.ts.map +1 -0
- package/dist/resources/abac-policies.js +1519 -0
- package/dist/resources/abac-policies.js.map +1 -0
- package/dist/resources/audit-log.d.ts +588 -0
- package/dist/resources/audit-log.d.ts.map +1 -0
- package/dist/resources/audit-log.js +629 -0
- package/dist/resources/audit-log.js.map +1 -0
- package/dist/resources/batch.d.ts +845 -0
- package/dist/resources/batch.d.ts.map +1 -0
- package/dist/resources/batch.js +1074 -0
- package/dist/resources/batch.js.map +1 -0
- package/dist/resources/chat.d.ts +151 -0
- package/dist/resources/chat.d.ts.map +1 -0
- package/dist/resources/chat.js +124 -0
- package/dist/resources/chat.js.map +1 -0
- package/dist/resources/check.d.ts +348 -0
- package/dist/resources/check.d.ts.map +1 -0
- package/dist/resources/check.js +543 -0
- package/dist/resources/check.js.map +1 -0
- package/dist/resources/compliance-check.d.ts +330 -0
- package/dist/resources/compliance-check.d.ts.map +1 -0
- package/dist/resources/compliance-check.js +402 -0
- package/dist/resources/compliance-check.js.map +1 -0
- package/dist/resources/decisions.d.ts +1208 -0
- package/dist/resources/decisions.d.ts.map +1 -0
- package/dist/resources/decisions.js +1362 -0
- package/dist/resources/decisions.js.map +1 -0
- package/dist/resources/evidence-pack.d.ts +1080 -0
- package/dist/resources/evidence-pack.d.ts.map +1 -0
- package/dist/resources/evidence-pack.js +1789 -0
- package/dist/resources/evidence-pack.js.map +1 -0
- package/dist/resources/gate.d.ts +613 -0
- package/dist/resources/gate.d.ts.map +1 -0
- package/dist/resources/gate.js +737 -0
- package/dist/resources/gate.js.map +1 -0
- package/dist/resources/incidents.d.ts +136 -0
- package/dist/resources/incidents.d.ts.map +1 -0
- package/dist/resources/incidents.js +229 -0
- package/dist/resources/incidents.js.map +1 -0
- package/dist/resources/regulatory-changes.d.ts +307 -0
- package/dist/resources/regulatory-changes.d.ts.map +1 -0
- package/dist/resources/regulatory-changes.js +365 -0
- package/dist/resources/regulatory-changes.js.map +1 -0
- package/dist/resources/safe-input-read.d.ts +21 -0
- package/dist/resources/safe-input-read.d.ts.map +1 -0
- package/dist/resources/safe-input-read.js +57 -0
- package/dist/resources/safe-input-read.js.map +1 -0
- package/dist/resources/ship-gate.d.ts +475 -0
- package/dist/resources/ship-gate.d.ts.map +1 -0
- package/dist/resources/ship-gate.js +727 -0
- package/dist/resources/ship-gate.js.map +1 -0
- package/dist/resources/vision.d.ts +540 -0
- package/dist/resources/vision.d.ts.map +1 -0
- package/dist/resources/vision.js +1036 -0
- package/dist/resources/vision.js.map +1 -0
- package/dist/retry.d.ts +103 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +224 -0
- package/dist/retry.js.map +1 -0
- package/dist/sse-parser.d.ts +64 -0
- package/dist/sse-parser.d.ts.map +1 -0
- package/dist/sse-parser.js +271 -0
- package/dist/sse-parser.js.map +1 -0
- package/dist/transport.d.ts +142 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +455 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
import type { AttestryClient } from "../client.js";
|
|
2
|
+
import type { RequestOptions } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Input shape for `gate.evaluate`. Source-of-truth at kernel
|
|
5
|
+
* `src/app/api/v1/gate/route.ts:31-36` (Zod schema).
|
|
6
|
+
*
|
|
7
|
+
* **`systemId`** — REQUIRED RFC 4122 hyphenated UUID. The SDK
|
|
8
|
+
* pre-validates the format synchronously (`TypeError` for malformed
|
|
9
|
+
* input — D2). The SDK's runtime check always runs regardless of
|
|
10
|
+
* TypeScript types — `as any` casts do NOT bypass it. The kernel-side
|
|
11
|
+
* Zod validation (422 fallback) only fires for kernel rule changes
|
|
12
|
+
* the SDK hasn't synced to.
|
|
13
|
+
*
|
|
14
|
+
* **`minScore`** — OPTIONAL integer in `[0, 100]`. **Defaults to 70
|
|
15
|
+
* kernel-side** (Zod `.default(70)`) when the SDK omits the field
|
|
16
|
+
* from the body. Consumers who omit this get the implicit threshold
|
|
17
|
+
* of 70 — a non-obvious default (carry-forward #44). Pre-validated
|
|
18
|
+
* by the SDK: `typeof === "number"`, `Number.isInteger`, bounds
|
|
19
|
+
* `[0, 100]` inclusive (`Number.isInteger` already rejects NaN /
|
|
20
|
+
* Infinity, so no separate Number.isFinite check needed).
|
|
21
|
+
*
|
|
22
|
+
* **`frameworks`** — OPTIONAL array of up to 20 framework identifiers;
|
|
23
|
+
* each string of length 1-100. **Substring + case-insensitive
|
|
24
|
+
* matching** (kernel uses `aFrameworks.some((af) =>
|
|
25
|
+
* af.toLowerCase().includes(f.toLowerCase()))` at route.ts:94-96).
|
|
26
|
+
* **Asymmetric with `check.run`'s OR-overlap exact-equality** —
|
|
27
|
+
* gate's looser substring match means `["GDPR"]` matches an
|
|
28
|
+
* assessment with frameworks `["EU_GDPR_2024"]`, `["gdpr_compliance_v2"]`,
|
|
29
|
+
* etc. When omitted (or empty), the kernel considers all completed
|
|
30
|
+
* assessments. Empty array `[]` is accepted (Zod `.max(20)` permits
|
|
31
|
+
* length 0; the kernel's `length > 0` guard at route.ts:90 short-
|
|
32
|
+
* circuits the filter to "no filter").
|
|
33
|
+
*
|
|
34
|
+
* Open-spec field — the kernel does NOT enforce a closed enum of
|
|
35
|
+
* valid framework names; any string within the length bounds is
|
|
36
|
+
* accepted. Consumers should align their filter values with the
|
|
37
|
+
* framework identifiers they used when creating assessments
|
|
38
|
+
* (substring matching is forgiving but not magical).
|
|
39
|
+
*
|
|
40
|
+
* **`failOnMissingAssessment`** — OPTIONAL boolean. **Defaults to
|
|
41
|
+
* `true` kernel-side** (Zod `.default(true)`) when the SDK omits the
|
|
42
|
+
* field from the body. Consumers who omit this get strict behavior
|
|
43
|
+
* (no assessment = fail). Pre-validated by the SDK: `typeof ===
|
|
44
|
+
* "boolean"` (rejects truthy/falsy non-booleans like `1` / `"true"` /
|
|
45
|
+
* `null`). Both defaults documented prominently per carry-forward
|
|
46
|
+
* #44.
|
|
47
|
+
*/
|
|
48
|
+
export interface GateInput {
|
|
49
|
+
/**
|
|
50
|
+
* UUID of the system to evaluate. RFC 4122 hyphenated form
|
|
51
|
+
* (8-4-4-4-12 hex, case-insensitive). Required.
|
|
52
|
+
*/
|
|
53
|
+
systemId: string;
|
|
54
|
+
/**
|
|
55
|
+
* Pass/fail threshold (integer 0-100). **Defaults to 70 kernel-
|
|
56
|
+
* side** when omitted.
|
|
57
|
+
*/
|
|
58
|
+
minScore?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Optional framework filter. Each element must be a non-empty
|
|
61
|
+
* string of length ≤100; the array length must be ≤20.
|
|
62
|
+
*
|
|
63
|
+
* **Substring + case-insensitive matching** (kernel uses
|
|
64
|
+
* `.toLowerCase().includes()` — asymmetric with `check.run`'s exact
|
|
65
|
+
* equality). An assessment matches if any of its frameworks
|
|
66
|
+
* contains any filter string as a substring (after lowercasing).
|
|
67
|
+
*/
|
|
68
|
+
frameworks?: string[];
|
|
69
|
+
/**
|
|
70
|
+
* When `true` (the kernel default), a missing/incomplete
|
|
71
|
+
* assessment causes the gate to return `gate: "fail"`. When
|
|
72
|
+
* `false`, the gate returns `gate: "pass"` with `score: null` and
|
|
73
|
+
* a `reason` indicating the relaxed mode.
|
|
74
|
+
*
|
|
75
|
+
* **Defaults to `true` kernel-side** when omitted (strict mode).
|
|
76
|
+
*/
|
|
77
|
+
failOnMissingAssessment?: boolean;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Structured gap entry returned in the `gaps` array for the normal
|
|
81
|
+
* pass/fail emit path. Source-of-truth at kernel
|
|
82
|
+
* `src/app/api/v1/gate/route.ts:38-43` (`GateGap` interface) +
|
|
83
|
+
* route.ts:156-163 (the emit-site mapping).
|
|
84
|
+
*
|
|
85
|
+
* Built from `schema.remediationTasks` rows for the relevant
|
|
86
|
+
* assessment, filtered to `status !== "resolved" && status !==
|
|
87
|
+
* "wont_fix"` (route.ts:157).
|
|
88
|
+
*
|
|
89
|
+
* **`priority` is OPEN-SPEC** — the kernel does NOT enforce a closed
|
|
90
|
+
* enum on `remediationTasks.priority`; it's a free-text string column.
|
|
91
|
+
* The SDK exposes it as `string` (NOT `"critical" | "high" | "medium"
|
|
92
|
+
* | "low"` enum) to preserve faithful-courier semantics. Consumers
|
|
93
|
+
* needing closed-enum branching should filter post-hoc. **Note**: the
|
|
94
|
+
* kernel uses the literal strings `"critical"` and `"high"` to compute
|
|
95
|
+
* `criticalGaps` / `highGaps` counts (route.ts:193-194), so consumers
|
|
96
|
+
* can safely match those two values; other values (`"medium"`,
|
|
97
|
+
* `"low"`, custom) are not aggregated kernel-side.
|
|
98
|
+
*
|
|
99
|
+
* **`status` is also OPEN-SPEC** — the kernel filters out `"resolved"`
|
|
100
|
+
* and `"wont_fix"` before emitting, so `status` will be neither of
|
|
101
|
+
* those, but the kernel doesn't pin a closed enum on the remaining
|
|
102
|
+
* values (e.g., `"open"`, `"in_progress"`, custom).
|
|
103
|
+
*/
|
|
104
|
+
export interface GateGap {
|
|
105
|
+
/**
|
|
106
|
+
* Stable requirement key the gap addresses (e.g., a framework
|
|
107
|
+
* control identifier). Foreign key to `schema.remediationTasks
|
|
108
|
+
* .requirementKey`.
|
|
109
|
+
*/
|
|
110
|
+
requirementKey: string;
|
|
111
|
+
/**
|
|
112
|
+
* Human-readable title for the gap (the remediation task's title).
|
|
113
|
+
*/
|
|
114
|
+
title: string;
|
|
115
|
+
/**
|
|
116
|
+
* Open-spec priority string. Kernel-aggregated values are
|
|
117
|
+
* `"critical"` and `"high"` (counted into `criticalGaps` /
|
|
118
|
+
* `highGaps` response fields); other values pass through verbatim.
|
|
119
|
+
*/
|
|
120
|
+
priority: string;
|
|
121
|
+
/**
|
|
122
|
+
* Open-spec status string. Filtered kernel-side to NOT include
|
|
123
|
+
* `"resolved"` or `"wont_fix"`; remaining values pass through.
|
|
124
|
+
*/
|
|
125
|
+
status: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Response shape returned by `gate.evaluate`. **UNION of 3 emit
|
|
129
|
+
* paths** keyed by whether a `relevantAssessment` was found
|
|
130
|
+
* (kernel route.ts:88-98) and the value of `failOnMissingAssessment`.
|
|
131
|
+
*
|
|
132
|
+
* Source-of-truth at kernel `src/app/api/v1/gate/route.ts`:
|
|
133
|
+
* - Path 1 — normal pass/fail (route.ts:180-199, 14 fields):
|
|
134
|
+
* `relevantAssessment` found; `score: number`; all 5 emit-only
|
|
135
|
+
* fields (`assessmentId`, `assessmentDate`, `gapCount`,
|
|
136
|
+
* `criticalGaps`, `highGaps`) are present.
|
|
137
|
+
* - Path 2 — fail-on-missing (route.ts:113-123, 9 fields):
|
|
138
|
+
* `failOnMissingAssessment=true` AND `relevantAssessment` is
|
|
139
|
+
* falsy; `gate: "fail"`; `score: null`; `gaps: []`; emit-only
|
|
140
|
+
* fields are ABSENT (not just `undefined` — own-property false).
|
|
141
|
+
* - Path 3 — pass-on-missing (route.ts:126-136, 9 fields):
|
|
142
|
+
* `failOnMissingAssessment=false` AND `relevantAssessment` is
|
|
143
|
+
* falsy; `gate: "pass"`; `score: null`; `gaps: []`; emit-only
|
|
144
|
+
* fields are ABSENT.
|
|
145
|
+
*
|
|
146
|
+
* **`relevantAssessment` is falsy in TWO distinct cases** (kernel
|
|
147
|
+
* route.ts:88-98): (a) NO completed assessment exists within the 10
|
|
148
|
+
* most-recent assessment rows (silent `.limit(10)` truncation), OR
|
|
149
|
+
* (b) — with `frameworks` specified — no completed assessment within
|
|
150
|
+
* those 10 rows matches ANY framework via substring + case-insensitive
|
|
151
|
+
* comparison. A consumer setting `frameworks: ["UNMATCHED_FRAMEWORK"]`
|
|
152
|
+
* on a system with multiple completed assessments would fall into
|
|
153
|
+
* Paths 2/3 and see the literal `reason` string "No completed
|
|
154
|
+
* assessment found for this system." — even though completed
|
|
155
|
+
* assessments DO exist (they just don't match the filter). Consumers
|
|
156
|
+
* should NOT use Paths 2/3 alone to conclude "this system has never
|
|
157
|
+
* had a completed assessment".
|
|
158
|
+
*
|
|
159
|
+
* **Discriminator pattern** (mirrors `check.run`'s `lastAssessedAt ===
|
|
160
|
+
* null`): use `response.score === null` to detect Paths 2 or 3.
|
|
161
|
+
* `Object.hasOwn(response, "assessmentId") === false` is an
|
|
162
|
+
* equivalent own-property-only alternative that is ALSO safe under
|
|
163
|
+
* `Object.prototype.assessmentId` pollution. **Do NOT use
|
|
164
|
+
* `response.assessmentId === undefined`** as the discriminator —
|
|
165
|
+
* a hostile dep polluting `Object.prototype.assessmentId` makes the
|
|
166
|
+
* `=== undefined` check return false (reads the polluted value via
|
|
167
|
+
* prototype walk) even in Paths 2 + 3, silently misclassifying them
|
|
168
|
+
* as Path 1. `score === null` is the canonical safe discriminator
|
|
169
|
+
* (the SDK's P2 validator type-checks `score` as an own property
|
|
170
|
+
* with `objectHasOwn`).
|
|
171
|
+
*/
|
|
172
|
+
export interface GateResponse {
|
|
173
|
+
/**
|
|
174
|
+
* Pass/fail verdict. **String enum, NOT a boolean** — kernel
|
|
175
|
+
* emits the literal strings `"pass"` and `"fail"` (route.ts:114,
|
|
176
|
+
* 127, 181). Consumers should NOT compare against `true`/`false`.
|
|
177
|
+
*
|
|
178
|
+
* **Type contract is closed (`"pass" | "fail"`); runtime is open
|
|
179
|
+
* (faithful courier).** The SDK's P2 validator checks `typeof gate
|
|
180
|
+
* === "string"` only — it does NOT reject unknown string values.
|
|
181
|
+
* If a future kernel emits `gate: "warn"` / `gate: "skip"` / etc.
|
|
182
|
+
* before the SDK is bumped, the value round-trips at runtime
|
|
183
|
+
* (typed as the closed union at compile time, but holding the new
|
|
184
|
+
* string at runtime). Consumers using exhaustive type-narrowing
|
|
185
|
+
* (`if (gate === "pass") ... else /* TS: 'fail' */`) would
|
|
186
|
+
* misclassify an unknown value as the `"fail"` branch. The
|
|
187
|
+
* kernel-side `gate` emit-sites are drift-pinned via the wire-
|
|
188
|
+
* shape build-round pin so a kernel extension surfaces in the
|
|
189
|
+
* drift suite before consumer regressions.
|
|
190
|
+
*/
|
|
191
|
+
gate: "pass" | "fail";
|
|
192
|
+
/**
|
|
193
|
+
* The system's UUID (echoes the input — kernel route.ts:115, 128,
|
|
194
|
+
* 182).
|
|
195
|
+
*/
|
|
196
|
+
systemId: string;
|
|
197
|
+
/**
|
|
198
|
+
* The system's display name (`schema.aiSystems.name`,
|
|
199
|
+
* route.ts:116, 129, 183). Open-spec string.
|
|
200
|
+
*/
|
|
201
|
+
systemName: string;
|
|
202
|
+
/**
|
|
203
|
+
* Overall compliance score from the relevant completed
|
|
204
|
+
* assessment's `scores.overall` jsonb field, IF that field is a
|
|
205
|
+
* `number` (route.ts:141: `typeof scoresObj?.overall === "number"
|
|
206
|
+
* ? scoresObj.overall : 0`).
|
|
207
|
+
*
|
|
208
|
+
* **`null` in the no-assessment paths** (Paths 2 + 3, route.ts:118
|
|
209
|
+
* + 131). **Asymmetric with `check.run` which defaulted to 0**;
|
|
210
|
+
* gate's `null` preserves the distinction at the type level.
|
|
211
|
+
* Consumers should use `score === null` (NOT `score === 0`) to
|
|
212
|
+
* detect the no-assessment branch.
|
|
213
|
+
*
|
|
214
|
+
* **In Path 1, `score: 0` is AMBIGUOUS** between (a) the assessment
|
|
215
|
+
* legitimately scored zero, AND (b) the assessment row had a
|
|
216
|
+
* missing or non-numeric `scores.overall` (e.g., `undefined`, a
|
|
217
|
+
* string, or the literal jsonb string `"NaN"` — anything where
|
|
218
|
+
* `typeof !== "number"`). The kernel collapses (b) to 0 via
|
|
219
|
+
* `typeof === "number" ? value : 0` at `route.ts:141`. Consumers
|
|
220
|
+
* CANNOT distinguish (a) from (b) from the wire response alone —
|
|
221
|
+
* both cases emit `score: 0` with all 14 Path-1 fields present. A
|
|
222
|
+
* CI/CD pipeline treating `gate: "fail" && score === 0` as a
|
|
223
|
+
* "broken assessment data" signal would silently miss case (a).
|
|
224
|
+
* Faithful courier; the SDK does NOT mask the kernel's collapse.
|
|
225
|
+
*
|
|
226
|
+
* **Note on IEEE-754 NaN in jsonb**: an exotic edge case — if the
|
|
227
|
+
* jsonb stores IEEE-754 NaN as a number (NOT the string `"NaN"`),
|
|
228
|
+
* `typeof === "number"` returns true, the kernel passes NaN
|
|
229
|
+
* through, and `JSON.stringify(NaN)` emits `null` on the wire. The
|
|
230
|
+
* SDK's P2 validator accepts `score: null` in Path 1 (`score`
|
|
231
|
+
* typed `number | null`). Consumers would see `gate: "fail" &&
|
|
232
|
+
* score: null` with the OTHER 12 Path-1 fields present (NOT the
|
|
233
|
+
* 9-field Path-2/3 shape). This combination is the disambiguator
|
|
234
|
+
* for NaN-in-jsonb specifically vs the no-assessment branch.
|
|
235
|
+
*
|
|
236
|
+
* In Path 1 the value is a `number` (typically 0..100 but
|
|
237
|
+
* unbounded — the kernel does not clamp the jsonb value).
|
|
238
|
+
*
|
|
239
|
+
* Note: kernel internally uses `scoresObj?.overall` (NOT
|
|
240
|
+
* `overallScore` like `check.run`) but the SDK contract is just
|
|
241
|
+
* `score: number | null`; the jsonb key difference is invisible.
|
|
242
|
+
*/
|
|
243
|
+
score: number | null;
|
|
244
|
+
/**
|
|
245
|
+
* Pass/fail threshold applied (number). Echoes the consumer's
|
|
246
|
+
* input OR the kernel default (70) when omitted. ALWAYS present
|
|
247
|
+
* in all 3 emit paths.
|
|
248
|
+
*/
|
|
249
|
+
minScore: number;
|
|
250
|
+
/**
|
|
251
|
+
* In Paths 2 + 3 (no assessment): echoes the consumer's
|
|
252
|
+
* `frameworks` input (or `[]` if omitted) — route.ts:120 + 133.
|
|
253
|
+
* In Path 1: the **assessment's** frameworks (NOT the consumer's
|
|
254
|
+
* filter) — route.ts:186-188. Type contract is the same
|
|
255
|
+
* (`string[]`) but the SEMANTIC source differs by path.
|
|
256
|
+
* Documented for completeness; consumers should treat this field
|
|
257
|
+
* as "the frameworks relevant to this evaluation" without assuming
|
|
258
|
+
* input echo.
|
|
259
|
+
*/
|
|
260
|
+
frameworks: string[];
|
|
261
|
+
/**
|
|
262
|
+
* Structured gap list (kernel emit-site: route.ts:191 in Path 1;
|
|
263
|
+
* empty array in Paths 2 + 3). Each gap is a `GateGap` row from
|
|
264
|
+
* `schema.remediationTasks` filtered to `status !== "resolved" &&
|
|
265
|
+
* status !== "wont_fix"`.
|
|
266
|
+
*
|
|
267
|
+
* **SILENTLY CAPPED AT 100 ROWS-CONSIDERED** — the kernel reads up
|
|
268
|
+
* to 100 remediation tasks (`.limit(100)` at route.ts:154) and
|
|
269
|
+
* filters within that subset. If the assessment has >100
|
|
270
|
+
* unresolved gaps, the 101st+ are invisible. No `total`, no
|
|
271
|
+
* `hasMore`. Faithful courier; documented in JSDoc + README.
|
|
272
|
+
* Invariant candidate #50.
|
|
273
|
+
*/
|
|
274
|
+
gaps: GateGap[];
|
|
275
|
+
/**
|
|
276
|
+
* Human-readable reason string. Path-specific contents:
|
|
277
|
+
* - Path 1: `"Score N meets minimum threshold of M."` or
|
|
278
|
+
* `"Score N is below minimum threshold of M. K unresolved
|
|
279
|
+
* gaps."` (route.ts:195-197).
|
|
280
|
+
* - Path 2: `"No completed assessment found for this system."`
|
|
281
|
+
* (route.ts:117).
|
|
282
|
+
* - Path 3: `"No assessment found but failOnMissingAssessment is
|
|
283
|
+
* false."` (route.ts:130).
|
|
284
|
+
* Open-spec string; consumers should NOT pattern-match these for
|
|
285
|
+
* branching (kernel may reword). Use `gate` + `score === null` for
|
|
286
|
+
* programmatic decisions.
|
|
287
|
+
*/
|
|
288
|
+
reason: string;
|
|
289
|
+
/**
|
|
290
|
+
* ISO-8601, server-generated at handler end via `new
|
|
291
|
+
* Date().toISOString()` (route.ts:122, 135, 198). Uniquely
|
|
292
|
+
* identifies this evaluation's snapshot — consumers may use it as
|
|
293
|
+
* a freshness marker.
|
|
294
|
+
*/
|
|
295
|
+
timestamp: string;
|
|
296
|
+
/**
|
|
297
|
+
* UUID of the assessment used (`schema.assessments.id`,
|
|
298
|
+
* route.ts:189). **PRESENT ONLY in Path 1** — absent (own-property
|
|
299
|
+
* false) in Paths 2 + 3. **Use `score === null` (or
|
|
300
|
+
* `Object.hasOwn(response, "assessmentId") === false`) to detect
|
|
301
|
+
* the no-assessment branch — NOT `response.assessmentId ===
|
|
302
|
+
* undefined`** which reads via prototype walk and is unsafe under
|
|
303
|
+
* `Object.prototype.assessmentId` pollution. See the top-level
|
|
304
|
+
* GateResponse JSDoc's "Discriminator pattern" section for the full
|
|
305
|
+
* rationale.
|
|
306
|
+
*/
|
|
307
|
+
assessmentId?: string;
|
|
308
|
+
/**
|
|
309
|
+
* ISO-8601 of the assessment's `completedAt`, OR `null` if the
|
|
310
|
+
* assessment row's `completedAt` column is null (rare — completed
|
|
311
|
+
* assessments usually have a non-null timestamp, but the column
|
|
312
|
+
* is nullable). **PRESENT ONLY in Path 1** — absent in Paths 2 + 3.
|
|
313
|
+
*/
|
|
314
|
+
assessmentDate?: string | null;
|
|
315
|
+
/**
|
|
316
|
+
* Count of unresolved gaps after kernel filtering (NOT the raw
|
|
317
|
+
* row count — `blockingGaps.length` at route.ts:192).
|
|
318
|
+
* **PRESENT ONLY in Path 1**. Equivalent to `gaps.length` at the
|
|
319
|
+
* call site; the kernel emits it as a convenience.
|
|
320
|
+
*/
|
|
321
|
+
gapCount?: number;
|
|
322
|
+
/**
|
|
323
|
+
* Count of gaps with `priority === "critical"` (route.ts:193).
|
|
324
|
+
* **PRESENT ONLY in Path 1**. Open-spec priority — the kernel
|
|
325
|
+
* matches the literal string `"critical"`; consumers using custom
|
|
326
|
+
* priority taxonomies won't see those aggregated here.
|
|
327
|
+
*/
|
|
328
|
+
criticalGaps?: number;
|
|
329
|
+
/**
|
|
330
|
+
* Count of gaps with `priority === "high"` (route.ts:194).
|
|
331
|
+
* **PRESENT ONLY in Path 1**. Same priority-string caveat as
|
|
332
|
+
* `criticalGaps`.
|
|
333
|
+
*/
|
|
334
|
+
highGaps?: number;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* `gate` resource — sibling to `IncidentsResource`,
|
|
338
|
+
* `DecisionsResource`, `ChatResource`, `AuditLogResource`,
|
|
339
|
+
* `RegulatoryChangesResource`, `ComplianceCheckResource`,
|
|
340
|
+
* `CheckResource`. Today wraps a single endpoint (`evaluate`); the
|
|
341
|
+
* class is the landing pad for future gate methods if the kernel
|
|
342
|
+
* adds them (resource-class-per-kernel-resource convention, invariant
|
|
343
|
+
* #43).
|
|
344
|
+
*/
|
|
345
|
+
export declare class GateResource {
|
|
346
|
+
private readonly client;
|
|
347
|
+
constructor(client: AttestryClient);
|
|
348
|
+
/**
|
|
349
|
+
* Evaluate a CI/CD compliance gate for a single system. Returns a
|
|
350
|
+
* structured pass/fail verdict (string enum `"pass"`/`"fail"`),
|
|
351
|
+
* the score, the threshold, and a list of unresolved compliance
|
|
352
|
+
* gaps. Designed for pipeline integration (CI build logs / GitHub
|
|
353
|
+
* Actions / GitLab CI).
|
|
354
|
+
*
|
|
355
|
+
* **Three emit paths** — the response shape varies by whether a
|
|
356
|
+
* completed assessment was found and the value of
|
|
357
|
+
* `failOnMissingAssessment`:
|
|
358
|
+
* - **Path 1 (normal pass/fail)**: assessment found; `score: number`;
|
|
359
|
+
* all 14 fields present (including `assessmentId`,
|
|
360
|
+
* `assessmentDate`, `gapCount`, `criticalGaps`, `highGaps`).
|
|
361
|
+
* - **Path 2 (fail-on-missing)**: `failOnMissingAssessment=true`
|
|
362
|
+
* (the default) AND no completed assessment; `gate: "fail"`;
|
|
363
|
+
* `score: null`; `gaps: []`; emit-only fields ABSENT.
|
|
364
|
+
* - **Path 3 (pass-on-missing)**: `failOnMissingAssessment=false`
|
|
365
|
+
* AND no completed assessment; `gate: "pass"`; `score: null`;
|
|
366
|
+
* `gaps: []`; emit-only fields ABSENT.
|
|
367
|
+
*
|
|
368
|
+
* **Multi-permission UNION auth scope**: kernel uses
|
|
369
|
+
* `requireApiKeyWithPermission(req, READ_ASSESSMENTS, READ_SYSTEMS)`
|
|
370
|
+
* which is OR semantics (`Array.some()` at
|
|
371
|
+
* `permissions.ts:53-55`). A key with EITHER permission (or
|
|
372
|
+
* `ADMIN`, or null/empty permissions for backwards-compat)
|
|
373
|
+
* succeeds. **HTTP 401** for no/invalid API key, **HTTP 403** for
|
|
374
|
+
* an authenticated key that has NEITHER required permission. Pin
|
|
375
|
+
* BOTH branches separately. Carry-forward invariant #45 (same
|
|
376
|
+
* shape as `check.run`).
|
|
377
|
+
*
|
|
378
|
+
* **Asymmetric cross-org error code** (carry-forward #47, partial):
|
|
379
|
+
* cross-org `systemId` returns **404** — the kernel's
|
|
380
|
+
* `and(eq id, eq orgId)` at route.ts:62-75 collapses cross-org
|
|
381
|
+
* to "System not found or access denied" (mirror of
|
|
382
|
+
* `check.run`'s 404 surface; note kernel emits a LONGER literal
|
|
383
|
+
* string than `check.run`'s `"System not found"`). Consumers
|
|
384
|
+
* writing defensive error-handling logic must recognize: a 404
|
|
385
|
+
* may be "not your org" OR "genuine missing UUID". No 403-via-
|
|
386
|
+
* orgName twin here (no orgName input mode).
|
|
387
|
+
*
|
|
388
|
+
* **Two silent kernel-side truncations** (faithful courier;
|
|
389
|
+
* documented as kernel surface gaps — JSDoc + README + drift
|
|
390
|
+
* pinned with ANCHORED regex per session-16 second-review
|
|
391
|
+
* MEDIUM #4). Invariant candidate #50:
|
|
392
|
+
* 1. `assessments` row-population — `.limit(10)` at route.ts:85.
|
|
393
|
+
* If the system has >10 assessment rows, the kernel only
|
|
394
|
+
* considers the 10 most recent by `completedAt` DESC. The
|
|
395
|
+
* "relevant" completed assessment is found by `.find()` over
|
|
396
|
+
* those 10 — a system with the most-recent completed
|
|
397
|
+
* assessment in position 11+ would be misclassified as "no
|
|
398
|
+
* assessment found" (falling into Paths 2 or 3). **Tighter
|
|
399
|
+
* cap than `check.run`'s `.limit(100)`** — gate is strictly
|
|
400
|
+
* less defensive against many-assessment systems.
|
|
401
|
+
* 2. `remediationTasks` row-population — `.limit(100)` at
|
|
402
|
+
* route.ts:154. If the assessment has >100 unresolved
|
|
403
|
+
* remediation tasks, the 101st+ are invisible. The cap
|
|
404
|
+
* applies BEFORE the filter-to-unresolved step
|
|
405
|
+
* (`status !== "resolved" && status !== "wont_fix"`), so the
|
|
406
|
+
* final `gaps.length` may be less than 100 even at the cap.
|
|
407
|
+
*
|
|
408
|
+
* **`score` defaults to `null` in the no-assessment paths**
|
|
409
|
+
* (route.ts:118 + 131). **Asymmetric with `check.run` which used
|
|
410
|
+
* `0`** — gate's `null` preserves the distinction at the type
|
|
411
|
+
* level. Consumers should use `score === null` (NOT `score === 0`)
|
|
412
|
+
* to detect Paths 2 or 3.
|
|
413
|
+
*
|
|
414
|
+
* **`gate` is a STRING ENUM, NOT a boolean** — kernel emits the
|
|
415
|
+
* literal strings `"pass"` and `"fail"` (route.ts:114, 127, 181).
|
|
416
|
+
* Type-narrowing via equality check: `if (result.gate === "pass")`.
|
|
417
|
+
*
|
|
418
|
+
* **`frameworks` filter is substring + case-insensitive** — kernel
|
|
419
|
+
* uses `.toLowerCase().includes()` at route.ts:94-96. **Asymmetric
|
|
420
|
+
* with `check.run`'s exact-equality OR-overlap**. Consumer passing
|
|
421
|
+
* `["GDPR"]` matches an assessment with `["EU_GDPR_2024"]`,
|
|
422
|
+
* `["gdpr_compliance_v2"]`, etc. Looser semantics may surprise.
|
|
423
|
+
*
|
|
424
|
+
* **`writeAuditLog` side effect** — every `gate.evaluate(...)`
|
|
425
|
+
* call writes one `gate.checked` entry to the org's audit log
|
|
426
|
+
* (route.ts:104-111 for the no-assessment paths, route.ts:165-178
|
|
427
|
+
* for the normal path). Properties of the write:
|
|
428
|
+
* - Org-scoped, hash-chained (per `writeAuditLog` at
|
|
429
|
+
* `src/lib/api.ts:125-`).
|
|
430
|
+
* - **Time-blocking** but error-tolerant: the kernel uses
|
|
431
|
+
* `await writeAuditLog(...)`, which awaits two DB ops (SELECT
|
|
432
|
+
* previous-hash + INSERT new entry). The gate response latency
|
|
433
|
+
* INCLUDES the audit-log write time — a slow audit-log DB will
|
|
434
|
+
* delay every gate.evaluate() response. Error semantics ARE
|
|
435
|
+
* non-blocking: `writeAuditLog` wraps its body in a try/catch
|
|
436
|
+
* that swallows errors and logs them, so a write FAILURE does
|
|
437
|
+
* NOT fail the gate request.
|
|
438
|
+
* - NOT counted against `decisionsPerMonth` quota (gate is read-
|
|
439
|
+
* shaped from a quota perspective).
|
|
440
|
+
*
|
|
441
|
+
* **Defaults applied by the kernel when fields are omitted**
|
|
442
|
+
* (carry-forward #44, non-obvious-default-filter pattern):
|
|
443
|
+
* - `minScore` defaults to **70** (Zod `.default(70)` at
|
|
444
|
+
* route.ts:33). Consumers who omit this field get the implicit
|
|
445
|
+
* threshold of 70.
|
|
446
|
+
* - `failOnMissingAssessment` defaults to **true** (Zod
|
|
447
|
+
* `.default(true)` at route.ts:35). Consumers who omit this
|
|
448
|
+
* get strict behavior.
|
|
449
|
+
* The SDK omits these fields from the request body when the
|
|
450
|
+
* consumer omits them, so the kernel applies its defaults
|
|
451
|
+
* (invariant candidate #52).
|
|
452
|
+
*
|
|
453
|
+
* Errors — ordered by kernel firing precedence (rate-limit → auth
|
|
454
|
+
* → Zod body validation → DB lookup → internal). A request with
|
|
455
|
+
* multiple problems surfaces ONLY the highest-precedence one. For
|
|
456
|
+
* example: a request with bad auth AND a malformed body surfaces
|
|
457
|
+
* 401, not 422; a request with valid auth + bad body AND a cross-
|
|
458
|
+
* org systemId surfaces 422, not 404.
|
|
459
|
+
* - `AttestryAPIError` (status 429) — rate limit FIRES FIRST
|
|
460
|
+
* (auto-retried by default — invariant #18; per-IP rate-limit
|
|
461
|
+
* key `v1-gate:${ip}`).
|
|
462
|
+
* - `AttestryAPIError` (status 401) — no API key OR invalid key.
|
|
463
|
+
* Fires AFTER rate-limit but BEFORE input validation.
|
|
464
|
+
* - `AttestryAPIError` (status 403) — authenticated key has
|
|
465
|
+
* NEITHER `READ_ASSESSMENTS` nor `READ_SYSTEMS` (the
|
|
466
|
+
* permission-check branch). Single test case — the union-auth
|
|
467
|
+
* pattern collapses three intuition-suggesting cases to one.
|
|
468
|
+
* - `AttestryAPIError` (status 422) — Zod schema rejection
|
|
469
|
+
* (kernel's `BodyParseError` surface — `parseBody(request,
|
|
470
|
+
* gateSchema)` failed). **Fires BEFORE the systemId/cross-
|
|
471
|
+
* org 404 lookup**, so a request with bad UUID format AND
|
|
472
|
+
* cross-org-correct UUID surfaces 422 (the kernel's Zod
|
|
473
|
+
* `.uuid()` reject), not 404. `apiErr.details` carries the
|
|
474
|
+
* full kernel error body verbatim (the transport does NOT
|
|
475
|
+
* strip the `{success:false, ...}` envelope on error responses
|
|
476
|
+
* — only the `{success:true, data}` envelope on success). The
|
|
477
|
+
* wire shape is: `{success: false, error: "Validation failed.",
|
|
478
|
+
* details: Array<{path: string; message: string}>}` — `error`
|
|
479
|
+
* is the literal string
|
|
480
|
+
* "Validation failed." (with trailing period), `details` is
|
|
481
|
+
* an array (NOT a keyed map) of `{path, message}` pairs
|
|
482
|
+
* derived from Zod's `result.error.errors`. Consumers
|
|
483
|
+
* reading field-by-field errors should iterate
|
|
484
|
+
* `apiErr.details.details` (the kernel's `details` array
|
|
485
|
+
* nested under the SDK's parsed-body wrapper). **The SDK
|
|
486
|
+
* pre-validates all closed-spec rules** (UUID format,
|
|
487
|
+
* minScore int + range, failOnMissingAssessment boolean,
|
|
488
|
+
* framework element length 1-100, array length ≤20) AND the
|
|
489
|
+
* runtime checks always run regardless of TypeScript types —
|
|
490
|
+
* `as any` casts do NOT bypass them. So 422 reaches consumers
|
|
491
|
+
* ONLY via kernel rule changes the SDK hasn't synced to.
|
|
492
|
+
* Invariant candidate #51.
|
|
493
|
+
* - `AttestryAPIError` (status 404) — system not found OR
|
|
494
|
+
* cross-org systemId (kernel collapses to "System not found
|
|
495
|
+
* or access denied", route.ts:74). Fires AFTER Zod validation
|
|
496
|
+
* (422).
|
|
497
|
+
* - `AttestryAPIError` (status 500) — internal kernel error
|
|
498
|
+
* (scrubbed message via `internalErrorResponse`).
|
|
499
|
+
* - `AttestryError` ("request aborted by caller") — caller-
|
|
500
|
+
* supplied `options.signal` fired (pre-aborted or mid-flight).
|
|
501
|
+
* - `AttestryError` (P2 hardening) — kernel response failed
|
|
502
|
+
* SDK-side shape validation (not an object, wrong type on any
|
|
503
|
+
* field).
|
|
504
|
+
* - `AttestryAPIError` (P3 hardening) — kernel response had a
|
|
505
|
+
* wrong Content-Type (transport-level guard before body
|
|
506
|
+
* parsing).
|
|
507
|
+
* - `TypeError` (synchronous, no fetch issued) — input failed
|
|
508
|
+
* SDK-side validation (null / array / non-object input,
|
|
509
|
+
* missing systemId, invalid UUID format, non-integer minScore,
|
|
510
|
+
* out-of-range minScore, non-boolean failOnMissingAssessment,
|
|
511
|
+
* frameworks array too long, frameworks element wrong type or
|
|
512
|
+
* length).
|
|
513
|
+
*
|
|
514
|
+
* **Notably ABSENT**:
|
|
515
|
+
* - **No 400** — all input validation is Zod (422).
|
|
516
|
+
* - **No 413** — body size limit not explicit.
|
|
517
|
+
* - **No 402** — read-shaped, doesn't count against
|
|
518
|
+
* decisionsPerMonth quota (despite the audit-log side effect).
|
|
519
|
+
*
|
|
520
|
+
* **SDK-side validation** (synchronous `TypeError`, no fetch
|
|
521
|
+
* issued):
|
|
522
|
+
* - `input` itself: required; must be a non-null, non-array
|
|
523
|
+
* object.
|
|
524
|
+
* - `input.systemId`: required own-property (Object.hasOwn
|
|
525
|
+
* defends against prototype pollution lying about presence —
|
|
526
|
+
* generalization of invariant #48); must be a non-empty
|
|
527
|
+
* string; must match the RFC 4122 hyphenated UUID format
|
|
528
|
+
* (D2 — SDK pre-validates closed-spec rule). No
|
|
529
|
+
* lone-surrogate URIError defense (D6 — POST body uses
|
|
530
|
+
* JSON.stringify).
|
|
531
|
+
* - `input.minScore` (when own-property present, value not
|
|
532
|
+
* undefined): must be a `number`, an integer (`Number.isInteger`,
|
|
533
|
+
* which excludes NaN / ±Infinity automatically), and within
|
|
534
|
+
* `[0, 100]` inclusive. Mirrors Zod's
|
|
535
|
+
* `z.number().int().min(0).max(100)` exactly (D3).
|
|
536
|
+
* - `input.failOnMissingAssessment` (when own-property present,
|
|
537
|
+
* value not undefined): must be a `boolean` (`typeof ===
|
|
538
|
+
* "boolean"`). Mirrors Zod's `z.boolean()` exactly (D4).
|
|
539
|
+
* - `input.frameworks` (when own-property present, value not
|
|
540
|
+
* undefined): must be an array of ≤20 strings, each of length
|
|
541
|
+
* 1-100. SDK pre-validates each rule (D5). Array is
|
|
542
|
+
* snapshotted via `Array.from` for TOCTOU defense.
|
|
543
|
+
*
|
|
544
|
+
* **Response-shape validation** (P2 hardening — D8, symmetric
|
|
545
|
+
* defense on response side per D7):
|
|
546
|
+
* - Rejects with `AttestryError` if the kernel response isn't a
|
|
547
|
+
* non-null, non-array object.
|
|
548
|
+
* - Rejects if `gate` isn't a string.
|
|
549
|
+
* - Rejects if `systemId` / `systemName` / `reason` / `timestamp`
|
|
550
|
+
* aren't strings.
|
|
551
|
+
* - Rejects if `score` isn't a number OR null.
|
|
552
|
+
* - Rejects if `minScore` isn't a number.
|
|
553
|
+
* - Rejects if `frameworks` / `gaps` aren't arrays.
|
|
554
|
+
* - Rejects if `assessmentId` (when own-present) isn't a string.
|
|
555
|
+
* - Rejects if `assessmentDate` (when own-present) isn't a
|
|
556
|
+
* string or null.
|
|
557
|
+
* - Rejects if `gapCount` / `criticalGaps` / `highGaps` (when
|
|
558
|
+
* own-present) aren't numbers.
|
|
559
|
+
* - Each response field read goes through the module-load
|
|
560
|
+
* `objectHasOwn` snapshot (symmetric to the input-side
|
|
561
|
+
* prototype-pollution defense — D7 generalized to the response
|
|
562
|
+
* boundary). A hostile npm dep that pollutes
|
|
563
|
+
* `Object.prototype.<field>` cannot mask a kernel regression
|
|
564
|
+
* where the field is missing — the SDK requires the field to
|
|
565
|
+
* be a kernel-emitted own property.
|
|
566
|
+
* - Per-gap-element shape (open-spec strings) is faithful-
|
|
567
|
+
* courier — NOT validated.
|
|
568
|
+
*
|
|
569
|
+
* **Transport-shape validation** (P3 hardening):
|
|
570
|
+
* - Rejects with `AttestryAPIError` if the kernel responds with
|
|
571
|
+
* a non-`application/json` Content-Type.
|
|
572
|
+
*
|
|
573
|
+
* @example Basic gate evaluation (defaults: minScore=70, failOnMissingAssessment=true)
|
|
574
|
+
* ```ts
|
|
575
|
+
* const result = await client.gate.evaluate({
|
|
576
|
+
* systemId: "11111111-1111-1111-1111-111111111111",
|
|
577
|
+
* });
|
|
578
|
+
* if (result.gate === "pass") {
|
|
579
|
+
* console.log("OK to deploy — score:", result.score);
|
|
580
|
+
* } else if (result.score === null) {
|
|
581
|
+
* console.warn("No completed assessment — failing strict-mode gate");
|
|
582
|
+
* } else {
|
|
583
|
+
* // Path 1 fail: emit-only fields are present at runtime, but
|
|
584
|
+
* // typed as optional. Use `??` (or a Path-1 narrowing check on
|
|
585
|
+
* // `assessmentId`) so the example compiles without `!` or `as`.
|
|
586
|
+
* console.warn(
|
|
587
|
+
* `Score ${result.score} below threshold ${result.minScore};`,
|
|
588
|
+
* `${result.gapCount ?? 0} unresolved gaps (${result.criticalGaps ?? 0} critical)`
|
|
589
|
+
* );
|
|
590
|
+
* }
|
|
591
|
+
* ```
|
|
592
|
+
*
|
|
593
|
+
* @example Strict threshold + framework filter
|
|
594
|
+
* ```ts
|
|
595
|
+
* const euOnly = await client.gate.evaluate({
|
|
596
|
+
* systemId: "11111111-1111-1111-1111-111111111111",
|
|
597
|
+
* minScore: 85,
|
|
598
|
+
* frameworks: ["EU_AI_ACT", "ISO_42001"],
|
|
599
|
+
* });
|
|
600
|
+
* ```
|
|
601
|
+
*
|
|
602
|
+
* @example Pre-launch / staging — allow missing assessments
|
|
603
|
+
* ```ts
|
|
604
|
+
* const lenient = await client.gate.evaluate({
|
|
605
|
+
* systemId: "11111111-1111-1111-1111-111111111111",
|
|
606
|
+
* failOnMissingAssessment: false,
|
|
607
|
+
* });
|
|
608
|
+
* // `lenient.gate === "pass"` even without a completed assessment.
|
|
609
|
+
* ```
|
|
610
|
+
*/
|
|
611
|
+
evaluate(input: GateInput, options?: RequestOptions): Promise<GateResponse>;
|
|
612
|
+
}
|
|
613
|
+
//# sourceMappingURL=gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/resources/gate.ts"],"names":[],"mappings":"AAiJA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAkClD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,OAAO;IACtB;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;;;OASG;IACH,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB;;;;;;;;;;;;OAYG;IACH,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB;;;;;;;;;;;;OAYG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsQG;IACH,QAAQ,CACN,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,YAAY,CAAC;CAsVzB"}
|