@apifuse/provider-sdk 2.1.0-beta.9 → 2.2.0-beta.1
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/AUTHORING.md +134 -0
- package/CHANGELOG.md +56 -0
- package/README.md +21 -9
- package/SUBMISSION.md +10 -11
- package/bin/apifuse-pack-check.ts +22 -0
- package/bin/apifuse-submit-check.ts +1747 -388
- package/dist/auth-turn/auth-turn.v1.schema.json +89 -0
- package/dist/auth-turn/fixtures/invalid/empty-kind.json +4 -0
- package/dist/auth-turn/fixtures/invalid/expires-at-not-string.json +5 -0
- package/dist/auth-turn/fixtures/invalid/missing-kind.json +3 -0
- package/dist/auth-turn/fixtures/invalid/missing-turn-id.json +3 -0
- package/dist/auth-turn/fixtures/invalid/timing-unknown-field.json +7 -0
- package/dist/auth-turn/fixtures/invalid/turn-id-snake-case.json +4 -0
- package/dist/auth-turn/fixtures/invalid/unknown-top-level-field.json +5 -0
- package/dist/auth-turn/fixtures/valid/abort.json +8 -0
- package/dist/auth-turn/fixtures/valid/challenge.json +17 -0
- package/dist/auth-turn/fixtures/valid/complete.json +13 -0
- package/dist/auth-turn/fixtures/valid/form.json +14 -0
- package/dist/auth-turn/fixtures/valid/message.json +13 -0
- package/dist/auth-turn/fixtures/valid/multi_choice.json +15 -0
- package/dist/auth-turn/fixtures/valid/pending.json +5 -0
- package/dist/auth-turn/fixtures/valid/poll.json +9 -0
- package/dist/auth-turn/fixtures/valid/redirect.json +16 -0
- package/dist/auth-turn/fixtures/valid/retry.json +8 -0
- package/dist/auth-turn/fixtures/valid/unknown-kind.json +7 -0
- package/dist/auth-turn/index.d.ts +195 -0
- package/dist/auth-turn/index.js +133 -0
- package/dist/auth.d.ts +76 -0
- package/dist/auth.js +436 -0
- package/dist/ceremonies/index.js +7 -31
- package/dist/cli/create.js +45 -30
- package/dist/cli/templates/provider/.dockerignore.tpl +22 -0
- package/dist/cli/templates/provider/.gitignore.tpl +22 -0
- package/dist/cli/templates/provider/AGENTS.md.tpl +87 -0
- package/dist/cli/templates/provider/CLAUDE.md.tpl +1 -0
- package/dist/cli/templates/provider/Dockerfile.tpl +7 -0
- package/dist/cli/templates/provider/README.md.tpl +163 -0
- package/dist/cli/templates/provider/dev.ts.tpl +5 -0
- package/dist/cli/templates/provider/domain/README.md.tpl +3 -0
- package/dist/cli/templates/provider/index.test.ts.tpl +13 -0
- package/dist/cli/templates/provider/index.ts.tpl +15 -0
- package/dist/cli/templates/provider/mappers/README.md.tpl +3 -0
- package/dist/cli/templates/provider/meta.ts.tpl +7 -0
- package/dist/cli/templates/provider/operations/index.ts.tpl +5 -0
- package/dist/cli/templates/provider/operations/ping.ts.tpl +24 -0
- package/dist/cli/templates/provider/schemas/ping.ts.tpl +24 -0
- package/dist/cli/templates/provider/skills/fixtures-and-recording/SKILL.md.tpl +58 -0
- package/dist/cli/templates/provider/skills/health-checks-and-fail-closed/SKILL.md.tpl +65 -0
- package/dist/cli/templates/provider/skills/normalization-standards/SKILL.md.tpl +57 -0
- package/dist/cli/templates/provider/skills/pagination-and-counts/SKILL.md.tpl +52 -0
- package/dist/cli/templates/provider/skills/upstream-contract-verification/SKILL.md.tpl +45 -0
- package/dist/cli/templates/provider/skills/upstream-notes/README.md.tpl +13 -0
- package/dist/cli/templates/provider/start.ts.tpl +5 -0
- package/dist/cli/templates/provider/upstream/README.md.tpl +3 -0
- package/dist/contract.js +1 -0
- package/dist/define.d.ts +6 -1
- package/dist/define.js +140 -70
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/lint.d.ts +1 -0
- package/dist/lint.js +27 -0
- package/dist/provider.d.ts +4 -2
- package/dist/provider.js +2 -1
- package/dist/runtime/auth-flow.js +2 -0
- package/dist/runtime/browser.js +203 -0
- package/dist/runtime/http.js +28 -8
- package/dist/runtime/stealth.d.ts +5 -2
- package/dist/runtime/stealth.js +149 -3
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.js +4 -0
- package/dist/server/self-test-input-tokens.d.ts +1 -0
- package/dist/server/self-test-input-tokens.js +37 -0
- package/dist/server/self-test-redaction.d.ts +20 -0
- package/dist/server/self-test-redaction.js +70 -0
- package/dist/server/self-test-token.d.ts +30 -0
- package/dist/server/self-test-token.js +50 -0
- package/dist/server/self-test.d.ts +98 -0
- package/dist/server/self-test.js +555 -0
- package/dist/server/serve.d.ts +6 -0
- package/dist/server/serve.js +33 -8
- package/dist/testing/run.js +5 -1
- package/dist/types.d.ts +150 -0
- package/package.json +9 -2
- package/src/auth-turn/auth-turn.v1.schema.json +89 -0
- package/src/auth-turn/fixtures/invalid/empty-kind.json +4 -0
- package/src/auth-turn/fixtures/invalid/expires-at-not-string.json +5 -0
- package/src/auth-turn/fixtures/invalid/missing-kind.json +3 -0
- package/src/auth-turn/fixtures/invalid/missing-turn-id.json +3 -0
- package/src/auth-turn/fixtures/invalid/timing-unknown-field.json +7 -0
- package/src/auth-turn/fixtures/invalid/turn-id-snake-case.json +4 -0
- package/src/auth-turn/fixtures/invalid/unknown-top-level-field.json +5 -0
- package/src/auth-turn/fixtures/valid/abort.json +8 -0
- package/src/auth-turn/fixtures/valid/challenge.json +17 -0
- package/src/auth-turn/fixtures/valid/complete.json +13 -0
- package/src/auth-turn/fixtures/valid/form.json +14 -0
- package/src/auth-turn/fixtures/valid/message.json +13 -0
- package/src/auth-turn/fixtures/valid/multi_choice.json +15 -0
- package/src/auth-turn/fixtures/valid/pending.json +5 -0
- package/src/auth-turn/fixtures/valid/poll.json +9 -0
- package/src/auth-turn/fixtures/valid/redirect.json +16 -0
- package/src/auth-turn/fixtures/valid/retry.json +8 -0
- package/src/auth-turn/fixtures/valid/unknown-kind.json +7 -0
- package/src/auth-turn/index.ts +177 -0
- package/src/auth.ts +786 -0
- package/src/ceremonies/index.ts +9 -43
- package/src/cli/create.ts +60 -97
- package/src/cli/templates/provider/AGENTS.md.tpl +87 -0
- package/src/cli/templates/provider/CLAUDE.md.tpl +1 -0
- package/src/cli/templates/provider/README.md.tpl +7 -4
- package/src/cli/templates/provider/skills/fixtures-and-recording/SKILL.md.tpl +58 -0
- package/src/cli/templates/provider/skills/health-checks-and-fail-closed/SKILL.md.tpl +65 -0
- package/src/cli/templates/provider/skills/normalization-standards/SKILL.md.tpl +57 -0
- package/src/cli/templates/provider/skills/pagination-and-counts/SKILL.md.tpl +52 -0
- package/src/cli/templates/provider/skills/upstream-contract-verification/SKILL.md.tpl +45 -0
- package/src/cli/templates/provider/skills/upstream-notes/README.md.tpl +13 -0
- package/src/contract.ts +1 -0
- package/src/define.ts +198 -71
- package/src/index.ts +16 -0
- package/src/lint.ts +33 -0
- package/src/provider.ts +27 -0
- package/src/runtime/auth-flow.ts +2 -0
- package/src/runtime/browser.ts +293 -1
- package/src/runtime/http.ts +48 -7
- package/src/runtime/stealth.ts +182 -5
- package/src/server/index.ts +36 -0
- package/src/server/self-test-input-tokens.ts +46 -0
- package/src/server/self-test-redaction.ts +97 -0
- package/src/server/self-test-token.ts +70 -0
- package/src/server/self-test.ts +725 -0
- package/src/server/serve.ts +67 -4
- package/src/testing/run.ts +9 -1
- package/src/types.ts +186 -0
package/src/server/serve.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { join } from "node:path";
|
|
|
3
3
|
|
|
4
4
|
import { Hono } from "hono";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
+
import { AuthAbortError, createAuthFlowHelpers } from "../auth";
|
|
6
7
|
import {
|
|
7
8
|
AuthError,
|
|
8
9
|
ProviderError,
|
|
@@ -75,6 +76,12 @@ import type {
|
|
|
75
76
|
StealthClient,
|
|
76
77
|
SttContext,
|
|
77
78
|
} from "../types";
|
|
79
|
+
import {
|
|
80
|
+
createSelfTestApp,
|
|
81
|
+
createSelfTestInvoke,
|
|
82
|
+
resolveSelfTestPort,
|
|
83
|
+
} from "./self-test";
|
|
84
|
+
import { resolveSelfTestMasterSecrets } from "./self-test-token";
|
|
78
85
|
import {
|
|
79
86
|
type AuthFlowRequest,
|
|
80
87
|
AuthFlowRequestSchema,
|
|
@@ -329,6 +336,7 @@ function createAuthFlowContext(
|
|
|
329
336
|
provider: ProviderDefinition,
|
|
330
337
|
request: AuthFlowRequest,
|
|
331
338
|
options: ProviderServerOptions = {},
|
|
339
|
+
signal?: AbortSignal,
|
|
332
340
|
): {
|
|
333
341
|
context: FlowContext;
|
|
334
342
|
getPatch: () => Record<string, unknown | null> | undefined;
|
|
@@ -383,6 +391,7 @@ function createAuthFlowContext(
|
|
|
383
391
|
credential,
|
|
384
392
|
context: flowContextStore.context,
|
|
385
393
|
stt: options.stt ?? createSttClientFromEnv(provider.stt),
|
|
394
|
+
auth: createAuthFlowHelpers({ signal }),
|
|
386
395
|
},
|
|
387
396
|
getPatch: flowContextStore.getPatch,
|
|
388
397
|
};
|
|
@@ -1291,6 +1300,7 @@ async function handleAuthFlow(
|
|
|
1291
1300
|
request: AuthFlowRequest,
|
|
1292
1301
|
route: AuthRoute,
|
|
1293
1302
|
options: ProviderServerOptions = {},
|
|
1303
|
+
signal?: AbortSignal,
|
|
1294
1304
|
): Promise<Response | AuthFlowResponse> {
|
|
1295
1305
|
const flow = provider.auth?.flow;
|
|
1296
1306
|
if (!flow) {
|
|
@@ -1303,6 +1313,7 @@ async function handleAuthFlow(
|
|
|
1303
1313
|
provider,
|
|
1304
1314
|
request,
|
|
1305
1315
|
options,
|
|
1316
|
+
signal,
|
|
1306
1317
|
);
|
|
1307
1318
|
try {
|
|
1308
1319
|
const result =
|
|
@@ -1336,6 +1347,11 @@ async function handleAuthFlow(
|
|
|
1336
1347
|
? materializeAuthFlowTurn(provider, request, result)
|
|
1337
1348
|
: result;
|
|
1338
1349
|
return toAuthFlowResponse(materializedResult, getPatch());
|
|
1350
|
+
} catch (error) {
|
|
1351
|
+
if (error instanceof AuthAbortError) {
|
|
1352
|
+
return toAuthFlowResponse(error.turn, getPatch());
|
|
1353
|
+
}
|
|
1354
|
+
throw error;
|
|
1339
1355
|
} finally {
|
|
1340
1356
|
context.stealth.close?.();
|
|
1341
1357
|
}
|
|
@@ -1450,7 +1466,13 @@ export function createServerApp(
|
|
|
1450
1466
|
AuthFlowRequestSchema.parse(rawBody),
|
|
1451
1467
|
c.req.raw.headers,
|
|
1452
1468
|
);
|
|
1453
|
-
const response = await handleAuthFlow(
|
|
1469
|
+
const response = await handleAuthFlow(
|
|
1470
|
+
provider,
|
|
1471
|
+
body,
|
|
1472
|
+
"start",
|
|
1473
|
+
options,
|
|
1474
|
+
c.req.raw.signal,
|
|
1475
|
+
);
|
|
1454
1476
|
logProviderSuccess(
|
|
1455
1477
|
logger,
|
|
1456
1478
|
provider,
|
|
@@ -1495,6 +1517,7 @@ export function createServerApp(
|
|
|
1495
1517
|
body,
|
|
1496
1518
|
"continue",
|
|
1497
1519
|
options,
|
|
1520
|
+
c.req.raw.signal,
|
|
1498
1521
|
);
|
|
1499
1522
|
logProviderSuccess(
|
|
1500
1523
|
logger,
|
|
@@ -1535,7 +1558,13 @@ export function createServerApp(
|
|
|
1535
1558
|
AuthFlowRequestSchema.parse(rawBody),
|
|
1536
1559
|
c.req.raw.headers,
|
|
1537
1560
|
);
|
|
1538
|
-
const response = await handleAuthFlow(
|
|
1561
|
+
const response = await handleAuthFlow(
|
|
1562
|
+
provider,
|
|
1563
|
+
body,
|
|
1564
|
+
"poll",
|
|
1565
|
+
options,
|
|
1566
|
+
c.req.raw.signal,
|
|
1567
|
+
);
|
|
1539
1568
|
logProviderSuccess(
|
|
1540
1569
|
logger,
|
|
1541
1570
|
provider,
|
|
@@ -1575,7 +1604,13 @@ export function createServerApp(
|
|
|
1575
1604
|
AuthFlowRequestSchema.parse(rawBody),
|
|
1576
1605
|
c.req.raw.headers,
|
|
1577
1606
|
);
|
|
1578
|
-
const response = await handleAuthFlow(
|
|
1607
|
+
const response = await handleAuthFlow(
|
|
1608
|
+
provider,
|
|
1609
|
+
body,
|
|
1610
|
+
"refresh",
|
|
1611
|
+
options,
|
|
1612
|
+
c.req.raw.signal,
|
|
1613
|
+
);
|
|
1579
1614
|
logProviderSuccess(
|
|
1580
1615
|
logger,
|
|
1581
1616
|
provider,
|
|
@@ -1615,7 +1650,13 @@ export function createServerApp(
|
|
|
1615
1650
|
AuthFlowRequestSchema.parse(rawBody),
|
|
1616
1651
|
c.req.raw.headers,
|
|
1617
1652
|
);
|
|
1618
|
-
const response = await handleAuthFlow(
|
|
1653
|
+
const response = await handleAuthFlow(
|
|
1654
|
+
provider,
|
|
1655
|
+
body,
|
|
1656
|
+
"abort",
|
|
1657
|
+
options,
|
|
1658
|
+
c.req.raw.signal,
|
|
1659
|
+
);
|
|
1619
1660
|
logProviderSuccess(
|
|
1620
1661
|
logger,
|
|
1621
1662
|
provider,
|
|
@@ -1675,6 +1716,12 @@ function getBunServeRuntime(): BunServeRuntime | undefined {
|
|
|
1675
1716
|
export interface ServeOptions extends ProviderServerOptions {
|
|
1676
1717
|
host?: string;
|
|
1677
1718
|
port?: number;
|
|
1719
|
+
/**
|
|
1720
|
+
* Port for the internal self-test listener (default 3001 or
|
|
1721
|
+
* APIFUSE__PROVIDER_RUNTIME__SELF_TEST_PORT). The listener only starts
|
|
1722
|
+
* when APIFUSE__PROVIDER_RUNTIME__SELF_TEST_MASTER_SECRET is present.
|
|
1723
|
+
*/
|
|
1724
|
+
selfTestPort?: number;
|
|
1678
1725
|
}
|
|
1679
1726
|
|
|
1680
1727
|
export async function serve(
|
|
@@ -1702,5 +1749,21 @@ export async function serve(
|
|
|
1702
1749
|
hostname: options.host ?? DEFAULT_HOST,
|
|
1703
1750
|
fetch: app.fetch,
|
|
1704
1751
|
});
|
|
1752
|
+
|
|
1753
|
+
// Internal self-test listener (health dependency inversion): a SEPARATE
|
|
1754
|
+
// socket the tenant-facing gateway never dials. Off by default — it only
|
|
1755
|
+
// starts when the shared self-test master secret env is present.
|
|
1756
|
+
const selfTestSecrets = resolveSelfTestMasterSecrets();
|
|
1757
|
+
if (selfTestSecrets) {
|
|
1758
|
+
const selfTestApp = createSelfTestApp(provider, {
|
|
1759
|
+
secrets: selfTestSecrets,
|
|
1760
|
+
invoke: createSelfTestInvoke(app),
|
|
1761
|
+
});
|
|
1762
|
+
bunRuntime.serve({
|
|
1763
|
+
port: options.selfTestPort ?? resolveSelfTestPort(),
|
|
1764
|
+
hostname: options.host ?? DEFAULT_HOST,
|
|
1765
|
+
fetch: selfTestApp.fetch,
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1705
1768
|
await Promise.resolve();
|
|
1706
1769
|
}
|
package/src/testing/run.ts
CHANGED
|
@@ -128,13 +128,21 @@ function inferFixtureDir(providerId: string): string {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
function jsonResponse(data: unknown): HttpResponse {
|
|
131
|
+
const body = JSON.stringify(data);
|
|
132
|
+
const bodyBytes = new TextEncoder().encode(body);
|
|
131
133
|
return {
|
|
132
134
|
status: 200,
|
|
133
135
|
ok: true,
|
|
134
136
|
headers: {},
|
|
135
137
|
data,
|
|
136
138
|
json: async <_T = unknown>() => JSON.parse(JSON.stringify(data)),
|
|
137
|
-
text: async () =>
|
|
139
|
+
text: async () => body,
|
|
140
|
+
arrayBuffer: async () =>
|
|
141
|
+
bodyBytes.buffer.slice(
|
|
142
|
+
bodyBytes.byteOffset,
|
|
143
|
+
bodyBytes.byteOffset + bodyBytes.byteLength,
|
|
144
|
+
),
|
|
145
|
+
bytes: async () => bodyBytes.slice(0),
|
|
138
146
|
};
|
|
139
147
|
}
|
|
140
148
|
|
package/src/types.ts
CHANGED
|
@@ -331,9 +331,20 @@ export interface HealthJourneySchedule {
|
|
|
331
331
|
kind: "interval";
|
|
332
332
|
/** ISO 8601 duration, for example PT8H. */
|
|
333
333
|
interval: Iso8601Duration;
|
|
334
|
+
randomize?: HealthScheduleRandomization;
|
|
334
335
|
jitter?: Iso8601Duration;
|
|
335
336
|
}
|
|
336
337
|
|
|
338
|
+
export type HealthScheduleRandomization =
|
|
339
|
+
| {
|
|
340
|
+
mode: "centered";
|
|
341
|
+
maxOffset: Iso8601Duration;
|
|
342
|
+
}
|
|
343
|
+
| {
|
|
344
|
+
mode: "delayed";
|
|
345
|
+
maxDelay: Iso8601Duration;
|
|
346
|
+
};
|
|
347
|
+
|
|
337
348
|
export interface HealthJourneyStep {
|
|
338
349
|
id: string;
|
|
339
350
|
description?: string;
|
|
@@ -612,6 +623,9 @@ export interface HealthCheckCase<TInput = unknown, TOutput = unknown> {
|
|
|
612
623
|
export interface HealthCheckSuite<TInput = unknown, TOutput = unknown> {
|
|
613
624
|
/** Polling interval for the suite. All cases share this cadence. */
|
|
614
625
|
interval: ProbeInterval;
|
|
626
|
+
schedule?: {
|
|
627
|
+
randomize?: HealthScheduleRandomization;
|
|
628
|
+
};
|
|
615
629
|
/** Per-case timeout in milliseconds. Default: 30000. */
|
|
616
630
|
timeoutMs?: number;
|
|
617
631
|
/** Default degradation threshold for cases in this suite. Default: runtime threshold. */
|
|
@@ -687,6 +701,14 @@ export interface ProviderHealthMonitorConfig {
|
|
|
687
701
|
serviceAccount?: string;
|
|
688
702
|
}
|
|
689
703
|
|
|
704
|
+
/**
|
|
705
|
+
* New name for `ProviderHealthMonitorConfig` as part of the health dependency
|
|
706
|
+
* inversion (`healthMonitor` → `healthProbe`). Both provider-level fields are
|
|
707
|
+
* accepted transitionally with identical validation; declaring both is a
|
|
708
|
+
* `ValidationError`.
|
|
709
|
+
*/
|
|
710
|
+
export type ProviderHealthProbeConfig = ProviderHealthMonitorConfig;
|
|
711
|
+
|
|
690
712
|
export interface HealthMonitorProbeOverride {
|
|
691
713
|
/** Optional runtime interval override as a positive `ms`-style duration string. */
|
|
692
714
|
interval?: ProbeInterval;
|
|
@@ -979,6 +1001,7 @@ export type HttpMethod =
|
|
|
979
1001
|
export interface StealthFetchOptions extends RequestOptions {
|
|
980
1002
|
method?: HttpMethod;
|
|
981
1003
|
body?: string | Buffer;
|
|
1004
|
+
redirect?: "follow" | "manual" | "error";
|
|
982
1005
|
/**
|
|
983
1006
|
* Offsets policy-managed proxy pool selection for caller-managed retries.
|
|
984
1007
|
* Use when a request receives an upstream challenge page rather than a
|
|
@@ -1005,9 +1028,20 @@ export interface CookieJar {
|
|
|
1005
1028
|
find?(predicate: (cookie: string) => boolean): string | undefined;
|
|
1006
1029
|
}
|
|
1007
1030
|
|
|
1031
|
+
export interface StealthSessionCookies extends CookieJar {
|
|
1032
|
+
has(name: string): boolean;
|
|
1033
|
+
setFromCookieStrings(cookieStrings: readonly string[]): void;
|
|
1034
|
+
toHeader(): string;
|
|
1035
|
+
snapshot(): Record<string, string>;
|
|
1036
|
+
restore(cookies: Record<string, string>): void;
|
|
1037
|
+
clear(): void;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1008
1040
|
export interface DeclarativeStealthResponse {
|
|
1009
1041
|
status: number;
|
|
1010
1042
|
ok: boolean;
|
|
1043
|
+
url?: string;
|
|
1044
|
+
redirected?: boolean;
|
|
1011
1045
|
headers: Record<string, string>;
|
|
1012
1046
|
rawHeaders: [string, string][];
|
|
1013
1047
|
body: string;
|
|
@@ -1026,8 +1060,34 @@ export type RequestWithMethodOptions = RequestOptions & {
|
|
|
1026
1060
|
body?: unknown;
|
|
1027
1061
|
};
|
|
1028
1062
|
|
|
1063
|
+
export interface StealthRedirectHop {
|
|
1064
|
+
url: string;
|
|
1065
|
+
status: number;
|
|
1066
|
+
method: string;
|
|
1067
|
+
location?: string;
|
|
1068
|
+
nextUrl?: string;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
export interface StealthRedirectRunOptions
|
|
1072
|
+
extends Omit<StealthFetchOptions, "redirect"> {
|
|
1073
|
+
url: string;
|
|
1074
|
+
maxHops?: number;
|
|
1075
|
+
stopWhen?: (hop: StealthRedirectHop) => boolean | Promise<boolean>;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
export interface StealthRedirectRunResult {
|
|
1079
|
+
final: StealthResponse;
|
|
1080
|
+
hops: StealthRedirectHop[];
|
|
1081
|
+
reason: "completed" | "stopped" | "max_hops" | "missing_location" | "loop";
|
|
1082
|
+
cookies: Record<string, string>;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1029
1085
|
export interface StealthSession {
|
|
1030
1086
|
fetch(url: string, options?: StealthFetchOptions): Promise<StealthResponse>;
|
|
1087
|
+
cookies: StealthSessionCookies;
|
|
1088
|
+
redirects: {
|
|
1089
|
+
run(options: StealthRedirectRunOptions): Promise<StealthRedirectRunResult>;
|
|
1090
|
+
};
|
|
1031
1091
|
close(): void;
|
|
1032
1092
|
}
|
|
1033
1093
|
|
|
@@ -1050,6 +1110,8 @@ export interface HttpResponse<T = unknown> {
|
|
|
1050
1110
|
data: T;
|
|
1051
1111
|
json<U = T>(): Promise<U>;
|
|
1052
1112
|
text(): Promise<string>;
|
|
1113
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
1114
|
+
bytes(): Promise<Uint8Array>;
|
|
1053
1115
|
}
|
|
1054
1116
|
|
|
1055
1117
|
export interface HttpStreamResponse {
|
|
@@ -1206,6 +1268,45 @@ export interface BrowserFrame {
|
|
|
1206
1268
|
locator(selector: string): BrowserLocator;
|
|
1207
1269
|
}
|
|
1208
1270
|
|
|
1271
|
+
export type BrowserResourceMethod = "GET" | "HEAD";
|
|
1272
|
+
|
|
1273
|
+
export type BrowserResourceRequest = {
|
|
1274
|
+
readonly url: string;
|
|
1275
|
+
readonly method: BrowserResourceMethod;
|
|
1276
|
+
readonly resourceType?: string;
|
|
1277
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
1278
|
+
};
|
|
1279
|
+
|
|
1280
|
+
export type BrowserResourceBody = Buffer | Uint8Array | ArrayBuffer | string;
|
|
1281
|
+
|
|
1282
|
+
export type BrowserResourceDecision =
|
|
1283
|
+
| {
|
|
1284
|
+
readonly action: "fulfill";
|
|
1285
|
+
readonly status?: number;
|
|
1286
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
1287
|
+
readonly body?: BrowserResourceBody;
|
|
1288
|
+
}
|
|
1289
|
+
| {
|
|
1290
|
+
readonly action: "block";
|
|
1291
|
+
readonly reason?: string;
|
|
1292
|
+
};
|
|
1293
|
+
|
|
1294
|
+
export type BrowserResourceRoute = {
|
|
1295
|
+
readonly match:
|
|
1296
|
+
| string
|
|
1297
|
+
| RegExp
|
|
1298
|
+
| ((request: BrowserResourceRequest) => boolean);
|
|
1299
|
+
readonly handle: (
|
|
1300
|
+
request: BrowserResourceRequest,
|
|
1301
|
+
) => Promise<BrowserResourceDecision> | BrowserResourceDecision;
|
|
1302
|
+
};
|
|
1303
|
+
|
|
1304
|
+
export type BrowserResourcePolicy = {
|
|
1305
|
+
readonly defaultAction?: "block";
|
|
1306
|
+
readonly allowedMethods?: readonly BrowserResourceMethod[];
|
|
1307
|
+
readonly routes: readonly BrowserResourceRoute[];
|
|
1308
|
+
};
|
|
1309
|
+
|
|
1209
1310
|
export interface BrowserPage extends BrowserFrame {
|
|
1210
1311
|
close(): Promise<void>;
|
|
1211
1312
|
fill(selector: string, text: string): Promise<void>;
|
|
@@ -1219,6 +1320,10 @@ export interface BrowserPage extends BrowserFrame {
|
|
|
1219
1320
|
options?: { timeout?: number },
|
|
1220
1321
|
): Promise<void>;
|
|
1221
1322
|
frames(): Promise<BrowserFrame[]>;
|
|
1323
|
+
withResourcePolicy<T>(
|
|
1324
|
+
policy: BrowserResourcePolicy,
|
|
1325
|
+
run: () => Promise<T>,
|
|
1326
|
+
): Promise<T>;
|
|
1222
1327
|
}
|
|
1223
1328
|
|
|
1224
1329
|
export type BrowserChallengeRequest = {
|
|
@@ -1397,6 +1502,84 @@ export interface ContextScratchpad {
|
|
|
1397
1502
|
|
|
1398
1503
|
export type FlowContextStore = ContextScratchpad;
|
|
1399
1504
|
|
|
1505
|
+
export type AuthSafeJson =
|
|
1506
|
+
| string
|
|
1507
|
+
| number
|
|
1508
|
+
| boolean
|
|
1509
|
+
| null
|
|
1510
|
+
| readonly AuthSafeJson[]
|
|
1511
|
+
| { readonly [key: string]: AuthSafeJson };
|
|
1512
|
+
|
|
1513
|
+
export type AuthSafeData = { readonly [key: string]: AuthSafeJson };
|
|
1514
|
+
|
|
1515
|
+
export type AuthAbortRetry = "never" | "retry" | "after_user_action";
|
|
1516
|
+
|
|
1517
|
+
export type AuthAbortData = Record<string, unknown> & {
|
|
1518
|
+
readonly code: string;
|
|
1519
|
+
readonly message?: string;
|
|
1520
|
+
readonly retry?: AuthAbortRetry;
|
|
1521
|
+
readonly actionHint?: AuthSafeJson;
|
|
1522
|
+
readonly fieldErrors?: { readonly [field: string]: string };
|
|
1523
|
+
readonly details?: AuthSafeData;
|
|
1524
|
+
};
|
|
1525
|
+
|
|
1526
|
+
export interface AuthFlowTerminalContext {
|
|
1527
|
+
readonly signal?: AbortSignal;
|
|
1528
|
+
readonly deadline?: string;
|
|
1529
|
+
complete<TCredential extends Record<string, string>>(options: {
|
|
1530
|
+
readonly credential: TCredential;
|
|
1531
|
+
readonly metadata?: AuthSafeData;
|
|
1532
|
+
readonly data?: AuthSafeData;
|
|
1533
|
+
readonly turnId?: string;
|
|
1534
|
+
readonly expiresAt?: string;
|
|
1535
|
+
}): AuthTurn;
|
|
1536
|
+
abort(options: {
|
|
1537
|
+
readonly code: string;
|
|
1538
|
+
readonly message?: string;
|
|
1539
|
+
readonly retry?: AuthAbortRetry;
|
|
1540
|
+
readonly actionHint?: AuthSafeJson;
|
|
1541
|
+
readonly fieldErrors?: { readonly [field: string]: string };
|
|
1542
|
+
readonly data?: AuthSafeData;
|
|
1543
|
+
readonly turnId?: string;
|
|
1544
|
+
readonly expiresAt?: string;
|
|
1545
|
+
}): AuthTurn;
|
|
1546
|
+
nextForm(
|
|
1547
|
+
options: {
|
|
1548
|
+
readonly hintKey?: ProviderLocaleKeyInput;
|
|
1549
|
+
readonly data?: AuthSafeData;
|
|
1550
|
+
readonly turnId?: string;
|
|
1551
|
+
readonly expiresAt?: string;
|
|
1552
|
+
readonly timing?: AuthTurn["timing"];
|
|
1553
|
+
} & (
|
|
1554
|
+
| {
|
|
1555
|
+
readonly fields: Record<
|
|
1556
|
+
string,
|
|
1557
|
+
{
|
|
1558
|
+
readonly type?: "string" | "email" | "password" | "otp";
|
|
1559
|
+
readonly labelKey?: ProviderLocaleKeyInput;
|
|
1560
|
+
readonly descriptionKey?: ProviderLocaleKeyInput;
|
|
1561
|
+
readonly placeholderKey?: ProviderLocaleKeyInput;
|
|
1562
|
+
readonly required?: boolean;
|
|
1563
|
+
readonly sensitive?: boolean;
|
|
1564
|
+
}
|
|
1565
|
+
>;
|
|
1566
|
+
readonly expectedInput?: never;
|
|
1567
|
+
}
|
|
1568
|
+
| {
|
|
1569
|
+
readonly expectedInput: Record<string, unknown>;
|
|
1570
|
+
readonly fields?: never;
|
|
1571
|
+
}
|
|
1572
|
+
),
|
|
1573
|
+
): AuthTurn;
|
|
1574
|
+
nextPoll(options?: {
|
|
1575
|
+
readonly hintKey?: ProviderLocaleKeyInput;
|
|
1576
|
+
readonly data?: AuthSafeData;
|
|
1577
|
+
readonly turnId?: string;
|
|
1578
|
+
readonly expiresAt?: string;
|
|
1579
|
+
readonly timing?: AuthTurn["timing"];
|
|
1580
|
+
}): AuthTurn;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1400
1583
|
export interface FlowContext {
|
|
1401
1584
|
connectionId?: string;
|
|
1402
1585
|
externalRef?: string;
|
|
@@ -1408,6 +1591,7 @@ export interface FlowContext {
|
|
|
1408
1591
|
credential?: CredentialContext;
|
|
1409
1592
|
context: ContextScratchpad;
|
|
1410
1593
|
stt: SttContext;
|
|
1594
|
+
auth: AuthFlowTerminalContext;
|
|
1411
1595
|
}
|
|
1412
1596
|
|
|
1413
1597
|
export interface AuthTurn {
|
|
@@ -1636,5 +1820,7 @@ export interface ProviderDefinition {
|
|
|
1636
1820
|
meta: ProviderMeta;
|
|
1637
1821
|
operations: Record<string, OperationDefinition<SchemaLike, SchemaLike>>;
|
|
1638
1822
|
healthMonitor?: ProviderHealthMonitorConfig;
|
|
1823
|
+
/** Transitional alias for `healthMonitor`; `defineProvider` mirrors both. */
|
|
1824
|
+
healthProbe?: ProviderHealthProbeConfig;
|
|
1639
1825
|
healthJourneys?: readonly HealthJourneyDefinition[];
|
|
1640
1826
|
}
|