@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.
Files changed (132) hide show
  1. package/AUTHORING.md +134 -0
  2. package/CHANGELOG.md +56 -0
  3. package/README.md +21 -9
  4. package/SUBMISSION.md +10 -11
  5. package/bin/apifuse-pack-check.ts +22 -0
  6. package/bin/apifuse-submit-check.ts +1747 -388
  7. package/dist/auth-turn/auth-turn.v1.schema.json +89 -0
  8. package/dist/auth-turn/fixtures/invalid/empty-kind.json +4 -0
  9. package/dist/auth-turn/fixtures/invalid/expires-at-not-string.json +5 -0
  10. package/dist/auth-turn/fixtures/invalid/missing-kind.json +3 -0
  11. package/dist/auth-turn/fixtures/invalid/missing-turn-id.json +3 -0
  12. package/dist/auth-turn/fixtures/invalid/timing-unknown-field.json +7 -0
  13. package/dist/auth-turn/fixtures/invalid/turn-id-snake-case.json +4 -0
  14. package/dist/auth-turn/fixtures/invalid/unknown-top-level-field.json +5 -0
  15. package/dist/auth-turn/fixtures/valid/abort.json +8 -0
  16. package/dist/auth-turn/fixtures/valid/challenge.json +17 -0
  17. package/dist/auth-turn/fixtures/valid/complete.json +13 -0
  18. package/dist/auth-turn/fixtures/valid/form.json +14 -0
  19. package/dist/auth-turn/fixtures/valid/message.json +13 -0
  20. package/dist/auth-turn/fixtures/valid/multi_choice.json +15 -0
  21. package/dist/auth-turn/fixtures/valid/pending.json +5 -0
  22. package/dist/auth-turn/fixtures/valid/poll.json +9 -0
  23. package/dist/auth-turn/fixtures/valid/redirect.json +16 -0
  24. package/dist/auth-turn/fixtures/valid/retry.json +8 -0
  25. package/dist/auth-turn/fixtures/valid/unknown-kind.json +7 -0
  26. package/dist/auth-turn/index.d.ts +195 -0
  27. package/dist/auth-turn/index.js +133 -0
  28. package/dist/auth.d.ts +76 -0
  29. package/dist/auth.js +436 -0
  30. package/dist/ceremonies/index.js +7 -31
  31. package/dist/cli/create.js +45 -30
  32. package/dist/cli/templates/provider/.dockerignore.tpl +22 -0
  33. package/dist/cli/templates/provider/.gitignore.tpl +22 -0
  34. package/dist/cli/templates/provider/AGENTS.md.tpl +87 -0
  35. package/dist/cli/templates/provider/CLAUDE.md.tpl +1 -0
  36. package/dist/cli/templates/provider/Dockerfile.tpl +7 -0
  37. package/dist/cli/templates/provider/README.md.tpl +163 -0
  38. package/dist/cli/templates/provider/dev.ts.tpl +5 -0
  39. package/dist/cli/templates/provider/domain/README.md.tpl +3 -0
  40. package/dist/cli/templates/provider/index.test.ts.tpl +13 -0
  41. package/dist/cli/templates/provider/index.ts.tpl +15 -0
  42. package/dist/cli/templates/provider/mappers/README.md.tpl +3 -0
  43. package/dist/cli/templates/provider/meta.ts.tpl +7 -0
  44. package/dist/cli/templates/provider/operations/index.ts.tpl +5 -0
  45. package/dist/cli/templates/provider/operations/ping.ts.tpl +24 -0
  46. package/dist/cli/templates/provider/schemas/ping.ts.tpl +24 -0
  47. package/dist/cli/templates/provider/skills/fixtures-and-recording/SKILL.md.tpl +58 -0
  48. package/dist/cli/templates/provider/skills/health-checks-and-fail-closed/SKILL.md.tpl +65 -0
  49. package/dist/cli/templates/provider/skills/normalization-standards/SKILL.md.tpl +57 -0
  50. package/dist/cli/templates/provider/skills/pagination-and-counts/SKILL.md.tpl +52 -0
  51. package/dist/cli/templates/provider/skills/upstream-contract-verification/SKILL.md.tpl +45 -0
  52. package/dist/cli/templates/provider/skills/upstream-notes/README.md.tpl +13 -0
  53. package/dist/cli/templates/provider/start.ts.tpl +5 -0
  54. package/dist/cli/templates/provider/upstream/README.md.tpl +3 -0
  55. package/dist/contract.js +1 -0
  56. package/dist/define.d.ts +6 -1
  57. package/dist/define.js +140 -70
  58. package/dist/index.d.ts +3 -2
  59. package/dist/index.js +2 -1
  60. package/dist/lint.d.ts +1 -0
  61. package/dist/lint.js +27 -0
  62. package/dist/provider.d.ts +4 -2
  63. package/dist/provider.js +2 -1
  64. package/dist/runtime/auth-flow.js +2 -0
  65. package/dist/runtime/browser.js +203 -0
  66. package/dist/runtime/http.js +28 -8
  67. package/dist/runtime/stealth.d.ts +5 -2
  68. package/dist/runtime/stealth.js +149 -3
  69. package/dist/server/index.d.ts +4 -0
  70. package/dist/server/index.js +4 -0
  71. package/dist/server/self-test-input-tokens.d.ts +1 -0
  72. package/dist/server/self-test-input-tokens.js +37 -0
  73. package/dist/server/self-test-redaction.d.ts +20 -0
  74. package/dist/server/self-test-redaction.js +70 -0
  75. package/dist/server/self-test-token.d.ts +30 -0
  76. package/dist/server/self-test-token.js +50 -0
  77. package/dist/server/self-test.d.ts +98 -0
  78. package/dist/server/self-test.js +555 -0
  79. package/dist/server/serve.d.ts +6 -0
  80. package/dist/server/serve.js +33 -8
  81. package/dist/testing/run.js +5 -1
  82. package/dist/types.d.ts +150 -0
  83. package/package.json +9 -2
  84. package/src/auth-turn/auth-turn.v1.schema.json +89 -0
  85. package/src/auth-turn/fixtures/invalid/empty-kind.json +4 -0
  86. package/src/auth-turn/fixtures/invalid/expires-at-not-string.json +5 -0
  87. package/src/auth-turn/fixtures/invalid/missing-kind.json +3 -0
  88. package/src/auth-turn/fixtures/invalid/missing-turn-id.json +3 -0
  89. package/src/auth-turn/fixtures/invalid/timing-unknown-field.json +7 -0
  90. package/src/auth-turn/fixtures/invalid/turn-id-snake-case.json +4 -0
  91. package/src/auth-turn/fixtures/invalid/unknown-top-level-field.json +5 -0
  92. package/src/auth-turn/fixtures/valid/abort.json +8 -0
  93. package/src/auth-turn/fixtures/valid/challenge.json +17 -0
  94. package/src/auth-turn/fixtures/valid/complete.json +13 -0
  95. package/src/auth-turn/fixtures/valid/form.json +14 -0
  96. package/src/auth-turn/fixtures/valid/message.json +13 -0
  97. package/src/auth-turn/fixtures/valid/multi_choice.json +15 -0
  98. package/src/auth-turn/fixtures/valid/pending.json +5 -0
  99. package/src/auth-turn/fixtures/valid/poll.json +9 -0
  100. package/src/auth-turn/fixtures/valid/redirect.json +16 -0
  101. package/src/auth-turn/fixtures/valid/retry.json +8 -0
  102. package/src/auth-turn/fixtures/valid/unknown-kind.json +7 -0
  103. package/src/auth-turn/index.ts +177 -0
  104. package/src/auth.ts +786 -0
  105. package/src/ceremonies/index.ts +9 -43
  106. package/src/cli/create.ts +60 -97
  107. package/src/cli/templates/provider/AGENTS.md.tpl +87 -0
  108. package/src/cli/templates/provider/CLAUDE.md.tpl +1 -0
  109. package/src/cli/templates/provider/README.md.tpl +7 -4
  110. package/src/cli/templates/provider/skills/fixtures-and-recording/SKILL.md.tpl +58 -0
  111. package/src/cli/templates/provider/skills/health-checks-and-fail-closed/SKILL.md.tpl +65 -0
  112. package/src/cli/templates/provider/skills/normalization-standards/SKILL.md.tpl +57 -0
  113. package/src/cli/templates/provider/skills/pagination-and-counts/SKILL.md.tpl +52 -0
  114. package/src/cli/templates/provider/skills/upstream-contract-verification/SKILL.md.tpl +45 -0
  115. package/src/cli/templates/provider/skills/upstream-notes/README.md.tpl +13 -0
  116. package/src/contract.ts +1 -0
  117. package/src/define.ts +198 -71
  118. package/src/index.ts +16 -0
  119. package/src/lint.ts +33 -0
  120. package/src/provider.ts +27 -0
  121. package/src/runtime/auth-flow.ts +2 -0
  122. package/src/runtime/browser.ts +293 -1
  123. package/src/runtime/http.ts +48 -7
  124. package/src/runtime/stealth.ts +182 -5
  125. package/src/server/index.ts +36 -0
  126. package/src/server/self-test-input-tokens.ts +46 -0
  127. package/src/server/self-test-redaction.ts +97 -0
  128. package/src/server/self-test-token.ts +70 -0
  129. package/src/server/self-test.ts +725 -0
  130. package/src/server/serve.ts +67 -4
  131. package/src/testing/run.ts +9 -1
  132. package/src/types.ts +186 -0
@@ -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(provider, body, "start", options);
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(provider, body, "poll", options);
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(provider, body, "refresh", options);
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(provider, body, "abort", options);
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
  }
@@ -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 () => JSON.stringify(data),
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
  }