@apifuse/provider-sdk 2.1.0-beta.9 → 2.2.0-beta.2
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 +61 -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 +46 -336
- package/dist/runtime/proxy-retry-policy.d.ts +40 -0
- package/dist/runtime/proxy-retry-policy.js +326 -0
- package/dist/runtime/stealth.d.ts +5 -2
- package/dist/runtime/stealth.js +206 -206
- 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 +38 -10
- package/dist/server/types.d.ts +1 -0
- package/dist/server/types.js +1 -0
- 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 +84 -530
- package/src/runtime/proxy-retry-policy.ts +469 -0
- package/src/runtime/stealth.ts +269 -353
- 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 +75 -6
- package/src/server/types.ts +1 -0
- 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,
|
|
@@ -189,7 +196,7 @@ export function resolveProviderProxyAffinityKey(
|
|
|
189
196
|
operationId: string,
|
|
190
197
|
): string {
|
|
191
198
|
const connectionKey =
|
|
192
|
-
request
|
|
199
|
+
resolveOperationConnectionId(request) ?? request.connection?.externalRef;
|
|
193
200
|
const affinity =
|
|
194
201
|
typeof provider.proxy === "object"
|
|
195
202
|
? provider.proxy.session?.affinity
|
|
@@ -200,6 +207,12 @@ export function resolveProviderProxyAffinityKey(
|
|
|
200
207
|
return connectionKey ?? provider.id;
|
|
201
208
|
}
|
|
202
209
|
|
|
210
|
+
function resolveOperationConnectionId(
|
|
211
|
+
request: OperationRequest,
|
|
212
|
+
): string | undefined {
|
|
213
|
+
return request.connection?.id ?? request.connectionId;
|
|
214
|
+
}
|
|
215
|
+
|
|
203
216
|
function createProviderContext(
|
|
204
217
|
provider: ProviderDefinition,
|
|
205
218
|
request: OperationRequest,
|
|
@@ -238,7 +251,7 @@ function createProviderContext(
|
|
|
238
251
|
values: request.connection?.secrets,
|
|
239
252
|
});
|
|
240
253
|
const requestContext = {
|
|
241
|
-
connectionId: request
|
|
254
|
+
connectionId: resolveOperationConnectionId(request),
|
|
242
255
|
headers: request.headers ?? {},
|
|
243
256
|
};
|
|
244
257
|
const context = wrapWithInstrumentation({
|
|
@@ -329,6 +342,7 @@ function createAuthFlowContext(
|
|
|
329
342
|
provider: ProviderDefinition,
|
|
330
343
|
request: AuthFlowRequest,
|
|
331
344
|
options: ProviderServerOptions = {},
|
|
345
|
+
signal?: AbortSignal,
|
|
332
346
|
): {
|
|
333
347
|
context: FlowContext;
|
|
334
348
|
getPatch: () => Record<string, unknown | null> | undefined;
|
|
@@ -383,6 +397,7 @@ function createAuthFlowContext(
|
|
|
383
397
|
credential,
|
|
384
398
|
context: flowContextStore.context,
|
|
385
399
|
stt: options.stt ?? createSttClientFromEnv(provider.stt),
|
|
400
|
+
auth: createAuthFlowHelpers({ signal }),
|
|
386
401
|
},
|
|
387
402
|
getPatch: flowContextStore.getPatch,
|
|
388
403
|
};
|
|
@@ -1291,6 +1306,7 @@ async function handleAuthFlow(
|
|
|
1291
1306
|
request: AuthFlowRequest,
|
|
1292
1307
|
route: AuthRoute,
|
|
1293
1308
|
options: ProviderServerOptions = {},
|
|
1309
|
+
signal?: AbortSignal,
|
|
1294
1310
|
): Promise<Response | AuthFlowResponse> {
|
|
1295
1311
|
const flow = provider.auth?.flow;
|
|
1296
1312
|
if (!flow) {
|
|
@@ -1303,6 +1319,7 @@ async function handleAuthFlow(
|
|
|
1303
1319
|
provider,
|
|
1304
1320
|
request,
|
|
1305
1321
|
options,
|
|
1322
|
+
signal,
|
|
1306
1323
|
);
|
|
1307
1324
|
try {
|
|
1308
1325
|
const result =
|
|
@@ -1336,6 +1353,11 @@ async function handleAuthFlow(
|
|
|
1336
1353
|
? materializeAuthFlowTurn(provider, request, result)
|
|
1337
1354
|
: result;
|
|
1338
1355
|
return toAuthFlowResponse(materializedResult, getPatch());
|
|
1356
|
+
} catch (error) {
|
|
1357
|
+
if (error instanceof AuthAbortError) {
|
|
1358
|
+
return toAuthFlowResponse(error.turn, getPatch());
|
|
1359
|
+
}
|
|
1360
|
+
throw error;
|
|
1339
1361
|
} finally {
|
|
1340
1362
|
context.stealth.close?.();
|
|
1341
1363
|
}
|
|
@@ -1450,7 +1472,13 @@ export function createServerApp(
|
|
|
1450
1472
|
AuthFlowRequestSchema.parse(rawBody),
|
|
1451
1473
|
c.req.raw.headers,
|
|
1452
1474
|
);
|
|
1453
|
-
const response = await handleAuthFlow(
|
|
1475
|
+
const response = await handleAuthFlow(
|
|
1476
|
+
provider,
|
|
1477
|
+
body,
|
|
1478
|
+
"start",
|
|
1479
|
+
options,
|
|
1480
|
+
c.req.raw.signal,
|
|
1481
|
+
);
|
|
1454
1482
|
logProviderSuccess(
|
|
1455
1483
|
logger,
|
|
1456
1484
|
provider,
|
|
@@ -1495,6 +1523,7 @@ export function createServerApp(
|
|
|
1495
1523
|
body,
|
|
1496
1524
|
"continue",
|
|
1497
1525
|
options,
|
|
1526
|
+
c.req.raw.signal,
|
|
1498
1527
|
);
|
|
1499
1528
|
logProviderSuccess(
|
|
1500
1529
|
logger,
|
|
@@ -1535,7 +1564,13 @@ export function createServerApp(
|
|
|
1535
1564
|
AuthFlowRequestSchema.parse(rawBody),
|
|
1536
1565
|
c.req.raw.headers,
|
|
1537
1566
|
);
|
|
1538
|
-
const response = await handleAuthFlow(
|
|
1567
|
+
const response = await handleAuthFlow(
|
|
1568
|
+
provider,
|
|
1569
|
+
body,
|
|
1570
|
+
"poll",
|
|
1571
|
+
options,
|
|
1572
|
+
c.req.raw.signal,
|
|
1573
|
+
);
|
|
1539
1574
|
logProviderSuccess(
|
|
1540
1575
|
logger,
|
|
1541
1576
|
provider,
|
|
@@ -1575,7 +1610,13 @@ export function createServerApp(
|
|
|
1575
1610
|
AuthFlowRequestSchema.parse(rawBody),
|
|
1576
1611
|
c.req.raw.headers,
|
|
1577
1612
|
);
|
|
1578
|
-
const response = await handleAuthFlow(
|
|
1613
|
+
const response = await handleAuthFlow(
|
|
1614
|
+
provider,
|
|
1615
|
+
body,
|
|
1616
|
+
"refresh",
|
|
1617
|
+
options,
|
|
1618
|
+
c.req.raw.signal,
|
|
1619
|
+
);
|
|
1579
1620
|
logProviderSuccess(
|
|
1580
1621
|
logger,
|
|
1581
1622
|
provider,
|
|
@@ -1615,7 +1656,13 @@ export function createServerApp(
|
|
|
1615
1656
|
AuthFlowRequestSchema.parse(rawBody),
|
|
1616
1657
|
c.req.raw.headers,
|
|
1617
1658
|
);
|
|
1618
|
-
const response = await handleAuthFlow(
|
|
1659
|
+
const response = await handleAuthFlow(
|
|
1660
|
+
provider,
|
|
1661
|
+
body,
|
|
1662
|
+
"abort",
|
|
1663
|
+
options,
|
|
1664
|
+
c.req.raw.signal,
|
|
1665
|
+
);
|
|
1619
1666
|
logProviderSuccess(
|
|
1620
1667
|
logger,
|
|
1621
1668
|
provider,
|
|
@@ -1675,6 +1722,12 @@ function getBunServeRuntime(): BunServeRuntime | undefined {
|
|
|
1675
1722
|
export interface ServeOptions extends ProviderServerOptions {
|
|
1676
1723
|
host?: string;
|
|
1677
1724
|
port?: number;
|
|
1725
|
+
/**
|
|
1726
|
+
* Port for the internal self-test listener (default 3001 or
|
|
1727
|
+
* APIFUSE__PROVIDER_RUNTIME__SELF_TEST_PORT). The listener only starts
|
|
1728
|
+
* when APIFUSE__PROVIDER_RUNTIME__SELF_TEST_MASTER_SECRET is present.
|
|
1729
|
+
*/
|
|
1730
|
+
selfTestPort?: number;
|
|
1678
1731
|
}
|
|
1679
1732
|
|
|
1680
1733
|
export async function serve(
|
|
@@ -1702,5 +1755,21 @@ export async function serve(
|
|
|
1702
1755
|
hostname: options.host ?? DEFAULT_HOST,
|
|
1703
1756
|
fetch: app.fetch,
|
|
1704
1757
|
});
|
|
1758
|
+
|
|
1759
|
+
// Internal self-test listener (health dependency inversion): a SEPARATE
|
|
1760
|
+
// socket the tenant-facing gateway never dials. Off by default — it only
|
|
1761
|
+
// starts when the shared self-test master secret env is present.
|
|
1762
|
+
const selfTestSecrets = resolveSelfTestMasterSecrets();
|
|
1763
|
+
if (selfTestSecrets) {
|
|
1764
|
+
const selfTestApp = createSelfTestApp(provider, {
|
|
1765
|
+
secrets: selfTestSecrets,
|
|
1766
|
+
invoke: createSelfTestInvoke(app),
|
|
1767
|
+
});
|
|
1768
|
+
bunRuntime.serve({
|
|
1769
|
+
port: options.selfTestPort ?? resolveSelfTestPort(),
|
|
1770
|
+
hostname: options.host ?? DEFAULT_HOST,
|
|
1771
|
+
fetch: selfTestApp.fetch,
|
|
1772
|
+
});
|
|
1773
|
+
}
|
|
1705
1774
|
await Promise.resolve();
|
|
1706
1775
|
}
|
package/src/server/types.ts
CHANGED
|
@@ -21,6 +21,7 @@ export const OperationConnectionSchema = z.object({
|
|
|
21
21
|
export const OperationRequestSchema = z.object({
|
|
22
22
|
requestId: z.string(),
|
|
23
23
|
input: z.record(z.string(), z.unknown()),
|
|
24
|
+
connectionId: z.string().optional(),
|
|
24
25
|
connection: OperationConnectionSchema.optional(),
|
|
25
26
|
headers: z.record(z.string(), z.string()).optional(),
|
|
26
27
|
trace: z.record(z.string(), z.string()).optional(),
|
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
|
}
|