@astrasyncai/adapter-lambda 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -0
- package/dist/index.d.mts +370 -0
- package/dist/index.d.ts +370 -0
- package/dist/index.js +671 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +615 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lambda/index.js +1 -0
- package/infra/RUNBOOK.md +132 -0
- package/infra/deploy.sh +42 -0
- package/infra/template.yaml +119 -0
- package/package.json +58 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import { CloudFrontRequestEvent, CloudFrontRequestResult, CloudFrontRequest, CloudFrontHeaders, CloudFrontResultResponse } from 'aws-lambda';
|
|
2
|
+
import { EdgeConfig, EdgeMode, EdgeVerificationDepth } from '@astrasyncai/verification-gateway/edge-config';
|
|
3
|
+
import { PlatformFingerprint } from '@astrasyncai/verification-gateway/platform-signatures';
|
|
4
|
+
import { CommerceArtifactsPayload } from '@astrasyncai/verification-gateway';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Commerce Shield edge adapter (spec §7.4 / §33.5 #1) — shared types.
|
|
8
|
+
*
|
|
9
|
+
* The adapter is a thin interception shell: it classifies inbound traffic
|
|
10
|
+
* into three visibility tiers, applies the dashboard-configured EdgeConfig
|
|
11
|
+
* (mode/depth/path rules), forwards raw commerce artifacts to verify-access
|
|
12
|
+
* (which does ALL cryptographic verification server-side, Step 0.5), and —
|
|
13
|
+
* only in enforce mode — turns decisions into responses. In observe mode it
|
|
14
|
+
* NEVER blocks and NEVER mutates responses.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The three visibility tiers of the Commerce Shield live agent feed, plus
|
|
19
|
+
* `human` (which the shell touches as little as possible) and `skipped`
|
|
20
|
+
* (path-filtered — static assets etc.).
|
|
21
|
+
*/
|
|
22
|
+
type TrafficTier = 'verified' | 'identified' | 'anonymous-bot' | 'human' | 'skipped';
|
|
23
|
+
interface Classification {
|
|
24
|
+
tier: TrafficTier;
|
|
25
|
+
/** Detected transport/credential protocol (tier `identified`/`verified`). */
|
|
26
|
+
protocol?: string;
|
|
27
|
+
/** Platform UA fingerprint when one matched. */
|
|
28
|
+
fingerprint?: PlatformFingerprint;
|
|
29
|
+
/** Raw commerce artifacts detected on the wire, ready to forward. */
|
|
30
|
+
artifacts?: CommerceArtifactsPayload;
|
|
31
|
+
/** Light, crypto-free detection detail for the beacon (kid namespace etc). */
|
|
32
|
+
evidence?: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
/** What the shell decided (observe mode records it; enforce mode acts on it). */
|
|
35
|
+
type EdgeDecision = 'allow' | 'deny' | 'manual_review';
|
|
36
|
+
interface TierOutcome {
|
|
37
|
+
tier: TrafficTier;
|
|
38
|
+
decision: EdgeDecision;
|
|
39
|
+
/** Why (deny/step-up reasons, or 'observe-passthrough'). */
|
|
40
|
+
reasons: string[];
|
|
41
|
+
/** ASAT header material when a verify-access call succeeded. */
|
|
42
|
+
asat?: {
|
|
43
|
+
trustScore?: number;
|
|
44
|
+
agentId?: string;
|
|
45
|
+
developerId?: string;
|
|
46
|
+
accessLevel?: string;
|
|
47
|
+
};
|
|
48
|
+
sessionId?: string;
|
|
49
|
+
protocol?: string;
|
|
50
|
+
guidance?: {
|
|
51
|
+
message?: string;
|
|
52
|
+
registrationUrl?: string;
|
|
53
|
+
documentationUrl?: string;
|
|
54
|
+
};
|
|
55
|
+
stepUp?: {
|
|
56
|
+
pollUrl?: string;
|
|
57
|
+
expiresAt?: string;
|
|
58
|
+
};
|
|
59
|
+
correlationId?: string;
|
|
60
|
+
}
|
|
61
|
+
/** Per-request effective policy after path-rule resolution. */
|
|
62
|
+
interface EffectivePolicy {
|
|
63
|
+
mode: EdgeMode;
|
|
64
|
+
depth: EdgeVerificationDepth;
|
|
65
|
+
skip: boolean;
|
|
66
|
+
}
|
|
67
|
+
interface EdgeAdapterOptions {
|
|
68
|
+
/** AstraSync API base, e.g. `https://astrasync.ai/api`. */
|
|
69
|
+
apiBaseUrl: string;
|
|
70
|
+
/** The protected property's ASTRAE endpoint id. */
|
|
71
|
+
counterpartyId: string;
|
|
72
|
+
/** Canonical public URL of the protected property, e.g. `https://astrasync.shop`. */
|
|
73
|
+
counterpartyUrl: string;
|
|
74
|
+
/**
|
|
75
|
+
* Merchant API key (`kya_*`). Provide directly (tests/local) or via
|
|
76
|
+
* `apiKeySecretName` (production — AWS Secrets Manager us-east-1, since
|
|
77
|
+
* Lambda@Edge forbids environment variables).
|
|
78
|
+
*/
|
|
79
|
+
apiKey?: string;
|
|
80
|
+
apiKeySecretName?: string;
|
|
81
|
+
/**
|
|
82
|
+
* Injectable secret fetcher (tests). Defaults to an
|
|
83
|
+
* @aws-sdk/client-secrets-manager GetSecretValue call.
|
|
84
|
+
*/
|
|
85
|
+
fetchSecret?: (secretName: string) => Promise<string | undefined>;
|
|
86
|
+
/** Edge-config cache TTL (ms). Default 60s. */
|
|
87
|
+
configTtlMs?: number;
|
|
88
|
+
/** Time budgets (ms). */
|
|
89
|
+
budgets?: {
|
|
90
|
+
/** Fire-and-forget beacon budget. Default 300. */
|
|
91
|
+
beaconMs?: number;
|
|
92
|
+
/** verify-access budget in observe mode. Default 1500. */
|
|
93
|
+
verifyObserveMs?: number;
|
|
94
|
+
/** verify-access budget in enforce mode. Default 3000. */
|
|
95
|
+
verifyEnforceMs?: number;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Compile-time fallback config used before the first successful
|
|
99
|
+
* edge-config fetch and whenever the backend is unreachable with a cold
|
|
100
|
+
* cache. Defaults to the SDK's DEFAULT_EDGE_CONFIG (observe/classify).
|
|
101
|
+
*/
|
|
102
|
+
fallbackConfig?: EdgeConfig;
|
|
103
|
+
/** Random source for beacon sampling — injectable for tests. */
|
|
104
|
+
random?: () => number;
|
|
105
|
+
/** Structured log sink. Defaults to console. */
|
|
106
|
+
log?: (level: 'info' | 'warn' | 'error', message: string, data?: Record<string, unknown>) => void;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Commerce Shield edge shell — Lambda@Edge origin-request handler factory
|
|
111
|
+
* (§7.4 / §33.5 #1).
|
|
112
|
+
*
|
|
113
|
+
* Composition per request:
|
|
114
|
+
* config (cached) → path policy → classify → tier pipeline → apply outcome
|
|
115
|
+
*
|
|
116
|
+
* THE invariant (tested): outside enforce mode the handler ALWAYS returns
|
|
117
|
+
* the origin-bound request — any error, timeout, or misconfiguration
|
|
118
|
+
* results in pass-through. A top-level catch guarantees it even against
|
|
119
|
+
* bugs in the shell itself.
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
type EdgeHandler = (event: CloudFrontRequestEvent) => Promise<CloudFrontRequestResult>;
|
|
123
|
+
declare function createEdgeHandler(options: EdgeAdapterOptions): EdgeHandler;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Three-tier traffic classification (§33.5 #1: verified /
|
|
127
|
+
* identified-but-unregistered / anonymous) plus the two non-tiers the shell
|
|
128
|
+
* touches as little as possible: `human` (zero network calls, zero logging)
|
|
129
|
+
* and `skipped` (static assets / excluded paths).
|
|
130
|
+
*
|
|
131
|
+
* Cheapest checks first — the human path must add microseconds, not
|
|
132
|
+
* milliseconds. Platform signatures come from the SDK so the edge and the
|
|
133
|
+
* backend's verify-access anonymous handler classify identically.
|
|
134
|
+
*/
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Resolve the effective mode/depth for a path from the EdgeConfig — ordered
|
|
138
|
+
* first-match-wins rules with case-insensitive globs; no match falls through
|
|
139
|
+
* to the config's top-level defaults. Static extensions are always skipped
|
|
140
|
+
* regardless of rules (a rule can only skip MORE, never un-skip an asset).
|
|
141
|
+
*/
|
|
142
|
+
declare function resolvePolicy(config: EdgeConfig, path: string): EffectivePolicy;
|
|
143
|
+
/**
|
|
144
|
+
* Classify one request. Order (cheapest sufficient evidence wins):
|
|
145
|
+
* 1. X-Astra-* credentials → `verified` candidate
|
|
146
|
+
* 2. commerce-protocol credentials on the wire → `identified`
|
|
147
|
+
* 3. platform UA fingerprint (Claude/ChatGPT/Gemini/…) → `identified`
|
|
148
|
+
* 4. bot-shaped UA / headerless non-browser → `anonymous-bot`
|
|
149
|
+
* 5. everything browser-shaped → `human`
|
|
150
|
+
*
|
|
151
|
+
* `depth: 'classify'` skips step 2 (no body decode, no header sniffing
|
|
152
|
+
* beyond UA) — that is the zero-friction setting.
|
|
153
|
+
*/
|
|
154
|
+
declare function classify(request: CloudFrontRequest, host: string, depth: 'classify' | 'authenticate' | 'authorize'): Classification;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* CloudFront origin-request event helpers. The Lambda@Edge event shape puts
|
|
158
|
+
* headers in `{ key, value }[]` arrays keyed by LOWERCASED header name, and
|
|
159
|
+
* (with IncludeBody) the body arrives base64-encoded with an
|
|
160
|
+
* `inputTruncated` flag when it exceeded CloudFront's ~1MB exposure cap.
|
|
161
|
+
*/
|
|
162
|
+
|
|
163
|
+
declare function getRequest(event: CloudFrontRequestEvent): CloudFrontRequest;
|
|
164
|
+
/** First value of a header (lowercase name), or undefined. */
|
|
165
|
+
declare function getHeader(request: CloudFrontRequest, name: string): string | undefined;
|
|
166
|
+
/**
|
|
167
|
+
* Flatten CloudFront headers into the `Record<string, string | string[]>`
|
|
168
|
+
* shape the SDK extractors and verify-access artifacts expect.
|
|
169
|
+
*/
|
|
170
|
+
declare function flattenHeaders(headers: CloudFrontHeaders): Record<string, string | string[]>;
|
|
171
|
+
interface DecodedBody {
|
|
172
|
+
/** UTF-8 body text, undefined when there is no body. */
|
|
173
|
+
text?: string;
|
|
174
|
+
/** True when CloudFront truncated the body before handing it to the trigger. */
|
|
175
|
+
truncated: boolean;
|
|
176
|
+
}
|
|
177
|
+
declare function decodeBody(request: CloudFrontRequest): DecodedBody;
|
|
178
|
+
/** Full request URL as the origin will see it (scheme fixed to https). */
|
|
179
|
+
declare function requestUrl(request: CloudFrontRequest, host: string): string;
|
|
180
|
+
/**
|
|
181
|
+
* Set a header on the origin-bound request (overwrites all prior values).
|
|
182
|
+
*/
|
|
183
|
+
declare function setHeader(request: CloudFrontRequest, name: string, value: string): void;
|
|
184
|
+
/**
|
|
185
|
+
* Strip every inbound header matching a prefix (lowercase compare). Used to
|
|
186
|
+
* drop spoofed `x-astrasync-*` trust headers before the shell injects its
|
|
187
|
+
* own — in BOTH modes, so a caller can never smuggle trust past the origin.
|
|
188
|
+
*/
|
|
189
|
+
declare function stripHeadersByPrefix(request: CloudFrontRequest, prefix: string): void;
|
|
190
|
+
declare function jsonResponse(status: number, body: unknown, extraHeaders?: Record<string, string>): CloudFrontResultResponse;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Crypto-free commerce-protocol detection (§7.4.2 detection order).
|
|
194
|
+
*
|
|
195
|
+
* The edge only SNIFFS — header shapes, compact-JWT patterns, body field
|
|
196
|
+
* names — and packages what it saw as raw `CommerceArtifactsPayload` for
|
|
197
|
+
* verify-access, whose Step 0.5 pipeline does the authoritative parsing and
|
|
198
|
+
* cryptographic verification server-side. Nothing here imports jose/sd-jwt/
|
|
199
|
+
* signature libraries: detection must stay cheap enough to run on every
|
|
200
|
+
* non-human request, and verification must happen exactly once, in the
|
|
201
|
+
* canonical sink, where it is recorded.
|
|
202
|
+
*/
|
|
203
|
+
|
|
204
|
+
interface DetectedCommerce {
|
|
205
|
+
/** Detection-order label: rfc9421-agent-pay | rfc9421-tap | rfc9421-web-bot-auth | vi-sd-jwt | ap2 | acp | ucp | mpp | x402 */
|
|
206
|
+
protocol: string;
|
|
207
|
+
artifacts: CommerceArtifactsPayload;
|
|
208
|
+
/** Light detection detail for beacons/audit — never secrets or full credentials. */
|
|
209
|
+
evidence: Record<string, unknown>;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* §7.4.2 order (after the X-Astra native check, which classify.ts owns):
|
|
213
|
+
* SD-JWT/VI → RFC 9421 (Agent Pay / TAP / Web Bot Auth by kid namespace or
|
|
214
|
+
* Signature-Agent) → ACP HMAC → UCP session → AP2 body triple → MPP → x402.
|
|
215
|
+
* Returns undefined when nothing commerce-shaped is on the wire.
|
|
216
|
+
*
|
|
217
|
+
* When the body was truncated by CloudFront (`inputTruncated`), body-bound
|
|
218
|
+
* artifacts still forward what arrived but carry a `bodyTruncated` evidence
|
|
219
|
+
* flag — the backend downgrades those signatures rather than hard-failing.
|
|
220
|
+
*/
|
|
221
|
+
declare function detectCommerce(request: CloudFrontRequest, host: string, body: DecodedBody): DetectedCommerce | undefined;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Depth-controlled verification per tier. The edge never verifies
|
|
225
|
+
* credentials itself — it forwards what it detected to verify-access, the
|
|
226
|
+
* canonical sole verification sink (backend Step 0.5 runs the commerce
|
|
227
|
+
* pipeline, records events, provisions orphans, persists sessions). What
|
|
228
|
+
* the depth setting controls is how much the edge LOOKS and how much it
|
|
229
|
+
* FORWARDS:
|
|
230
|
+
*
|
|
231
|
+
* classify — what is it? UA tiers only. Zero verify-access calls;
|
|
232
|
+
* beacons only.
|
|
233
|
+
* authenticate — who is it? + protocol detection. X-Astra agents get a
|
|
234
|
+
* verify-access identity check; commerce/platform traffic
|
|
235
|
+
* is beaconed with protocol + evidence (no signature
|
|
236
|
+
* verification anywhere).
|
|
237
|
+
* authorize — are they allowed? + artifact forwarding. X-Astra verify
|
|
238
|
+
* calls carry commerceArtifacts; identified traffic gets an
|
|
239
|
+
* anonymous verify-access call with artifacts +
|
|
240
|
+
* callerMetadata so the backend cryptographically proves
|
|
241
|
+
* and policy-evaluates once.
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Run the tier-appropriate verification/telemetry for one classified
|
|
246
|
+
* request. NEVER throws; on any failure returns an `allow` outcome with the
|
|
247
|
+
* failure recorded in `reasons` (infra failures fail open — a presented
|
|
248
|
+
* credential the BACKEND rejected is a deny, but an unreachable backend is
|
|
249
|
+
* not a rejection).
|
|
250
|
+
*/
|
|
251
|
+
declare function runTier(options: EdgeAdapterOptions, request: CloudFrontRequest, classification: Classification, policy: EffectivePolicy, apiKey: string | undefined, sampling: {
|
|
252
|
+
anonymousBeaconRate: number;
|
|
253
|
+
}): Promise<TierOutcome>;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Decision → CloudFront result wiring (§7.4 enforcement, §7.4.7 ASAT
|
|
257
|
+
* headers). Executed in BOTH modes so observe mode records exactly what
|
|
258
|
+
* enforce mode would have done — but only enforce mode is allowed to return
|
|
259
|
+
* anything other than the origin-bound request.
|
|
260
|
+
*/
|
|
261
|
+
|
|
262
|
+
/** §7.4.7 ASAT trust-attestation headers injected on allowed requests. */
|
|
263
|
+
declare const ASAT_HEADERS: {
|
|
264
|
+
readonly trustScore: "X-AstraSync-Trust-Score";
|
|
265
|
+
readonly agentId: "X-AstraSync-Agent-Id";
|
|
266
|
+
readonly developerId: "X-AstraSync-Developer-Id";
|
|
267
|
+
readonly permissions: "X-AstraSync-Permissions";
|
|
268
|
+
readonly observedDecision: "X-AstraSync-Observed-Decision";
|
|
269
|
+
};
|
|
270
|
+
/**
|
|
271
|
+
* Apply the outcome. Always strips inbound spoofed `x-astrasync-*` headers
|
|
272
|
+
* first (both modes — trust headers must only ever originate here).
|
|
273
|
+
*
|
|
274
|
+
* Observe mode: returns the request untouched apart from header hygiene and
|
|
275
|
+
* an `X-AstraSync-Observed-Decision` stamp for origin-side log correlation.
|
|
276
|
+
*
|
|
277
|
+
* Enforce mode: ALLOW → request + ASAT headers; DENY → 403 machine-readable
|
|
278
|
+
* body; MANUAL_REVIEW → 202 with step-up poll info.
|
|
279
|
+
*/
|
|
280
|
+
declare function applyOutcome(options: EdgeAdapterOptions, request: CloudFrontRequest, outcome: TierOutcome, policy: EffectivePolicy): CloudFrontRequestResult;
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* §7.4.6 — protocol-specific machine-readable messaging for enforce-mode
|
|
284
|
+
* responses. Agents (not humans) consume these bodies: stable error codes,
|
|
285
|
+
* the failure list, and registration guidance with real URLs.
|
|
286
|
+
*/
|
|
287
|
+
|
|
288
|
+
interface DenyBody {
|
|
289
|
+
success: false;
|
|
290
|
+
error: {
|
|
291
|
+
code: 'UNAUTHORIZED' | 'INSUFFICIENT_ACCESS';
|
|
292
|
+
message: string;
|
|
293
|
+
protocol?: string;
|
|
294
|
+
failures: string[];
|
|
295
|
+
correlationId?: string;
|
|
296
|
+
guidance: {
|
|
297
|
+
message?: string;
|
|
298
|
+
registrationUrl?: string;
|
|
299
|
+
documentationUrl?: string;
|
|
300
|
+
};
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
declare function buildDenyBody(outcome: TierOutcome, apiBaseUrl: string): DenyBody;
|
|
304
|
+
interface ManualReviewBody {
|
|
305
|
+
success: false;
|
|
306
|
+
status: 'manual_review';
|
|
307
|
+
message: string;
|
|
308
|
+
stepUpApproval?: {
|
|
309
|
+
pollUrl?: string;
|
|
310
|
+
expiresAt?: string;
|
|
311
|
+
};
|
|
312
|
+
correlationId?: string;
|
|
313
|
+
}
|
|
314
|
+
declare function buildManualReviewBody(outcome: TierOutcome): ManualReviewBody;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Time-budgeted event emission.
|
|
318
|
+
*
|
|
319
|
+
* Lambda@Edge has no `waitUntil` — anything not awaited before the handler
|
|
320
|
+
* returns may never run (the container freezes). So every network call is
|
|
321
|
+
* awaited under an explicit budget and DROPPED on timeout: latency to the
|
|
322
|
+
* customer's traffic is bounded, and a slow AstraSync API costs telemetry,
|
|
323
|
+
* never page loads.
|
|
324
|
+
*/
|
|
325
|
+
|
|
326
|
+
/** Await `promise` for at most `ms`; resolve `undefined` on timeout/error. */
|
|
327
|
+
declare function withBudget<T>(promise: Promise<T>, ms: number): Promise<T | undefined>;
|
|
328
|
+
/**
|
|
329
|
+
* Emit an unregistered-attempt beacon for `identified` (non-crypto depths)
|
|
330
|
+
* and sampled `anonymous-bot` traffic. Unauthenticated by design
|
|
331
|
+
* (CSRF-exempt on the backend); the backend fingerprints the UA and
|
|
332
|
+
* find-or-provisions orphan platform agents server-side.
|
|
333
|
+
*/
|
|
334
|
+
declare function emitBeacon(options: EdgeAdapterOptions, request: CloudFrontRequest, classification: Classification, budgetMs: number): Promise<void>;
|
|
335
|
+
/** Deterministic-in-tests sampling gate. */
|
|
336
|
+
declare function sampled(rate: number, random?: () => number): boolean;
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Runtime configuration for the edge shell.
|
|
340
|
+
*
|
|
341
|
+
* Lambda@Edge forbids environment variables, so configuration is layered:
|
|
342
|
+
* 1. Build-time constants baked into the bundle (apiBaseUrl,
|
|
343
|
+
* counterpartyId, counterpartyUrl, apiKeySecretName) — see
|
|
344
|
+
* `tsup.config.ts` define block and `infra/deploy.sh`.
|
|
345
|
+
* 2. The merchant API key from AWS Secrets Manager (us-east-1), fetched
|
|
346
|
+
* lazily once per container and cached with a 15-minute TTL so
|
|
347
|
+
* rotation needs no redeploy. Observe mode works fully without it —
|
|
348
|
+
* the beacon endpoint is unauthenticated and verify() degrades
|
|
349
|
+
* keyless — so a Secrets Manager outage can never take the shell down.
|
|
350
|
+
* 3. The dashboard EdgeConfig via the SDK's getEdgeConfig (60s TTL,
|
|
351
|
+
* stale-while-revalidate, enforce→observe degradation after 24h
|
|
352
|
+
* staleness, DEFAULT_EDGE_CONFIG fallback — all in the SDK).
|
|
353
|
+
*/
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Resolve the merchant API key. Never throws — a missing/unreachable secret
|
|
357
|
+
* degrades to keyless operation (observe mode is fully functional without
|
|
358
|
+
* it; enforce mode without a key cannot fetch a config that enforces, so it
|
|
359
|
+
* degrades to observe by construction).
|
|
360
|
+
*/
|
|
361
|
+
declare function resolveApiKey(options: EdgeAdapterOptions): Promise<string | undefined>;
|
|
362
|
+
/**
|
|
363
|
+
* Load the effective EdgeConfig. Delegates caching/fallback/degradation to
|
|
364
|
+
* the SDK; adds the compile-time fallback override and never throws.
|
|
365
|
+
*/
|
|
366
|
+
declare function loadEdgeConfig(options: EdgeAdapterOptions, apiKey: string | undefined): Promise<EdgeConfig>;
|
|
367
|
+
/** Reset module caches — tests only. */
|
|
368
|
+
declare function _resetConfigCaches(): void;
|
|
369
|
+
|
|
370
|
+
export { ASAT_HEADERS, type Classification, type DetectedCommerce, type EdgeAdapterOptions, type EdgeDecision, type EdgeHandler, type EffectivePolicy, type TierOutcome, type TrafficTier, _resetConfigCaches, applyOutcome, buildDenyBody, buildManualReviewBody, classify, createEdgeHandler, decodeBody, detectCommerce, emitBeacon, flattenHeaders, getHeader, getRequest, jsonResponse, loadEdgeConfig, requestUrl, resolveApiKey, resolvePolicy, runTier, sampled, setHeader, stripHeadersByPrefix, withBudget };
|