@apifuse/provider-sdk 2.1.0-beta.5 → 2.1.0-beta.8

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 (163) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +2 -2
  3. package/SUBMISSION.md +2 -1
  4. package/bin/apifuse-check.ts +60 -6
  5. package/bin/apifuse-dev.ts +48 -5
  6. package/bin/apifuse-perf.ts +50 -11
  7. package/bin/apifuse-record.ts +35 -11
  8. package/bin/apifuse-submit-check.ts +1425 -3
  9. package/dist/ceremonies/index.d.ts +41 -0
  10. package/dist/ceremonies/index.js +490 -0
  11. package/dist/choice-token.d.ts +24 -0
  12. package/dist/choice-token.js +74 -0
  13. package/dist/cli/commands.d.ts +10 -0
  14. package/dist/cli/commands.js +80 -0
  15. package/dist/cli/create.d.ts +47 -0
  16. package/dist/cli/create.js +762 -0
  17. package/dist/config/loader.d.ts +107 -0
  18. package/dist/config/loader.js +935 -0
  19. package/dist/contract-json.d.ts +9 -0
  20. package/dist/contract-json.js +51 -0
  21. package/dist/contract-serialization.d.ts +4 -0
  22. package/dist/contract-serialization.js +78 -0
  23. package/dist/contract-types.d.ts +49 -0
  24. package/dist/contract-types.js +1 -0
  25. package/dist/contract.d.ts +6 -0
  26. package/dist/contract.js +155 -0
  27. package/dist/define.d.ts +97 -0
  28. package/dist/define.js +1320 -0
  29. package/dist/dev.d.ts +9 -0
  30. package/dist/dev.js +15 -0
  31. package/dist/errors.d.ts +59 -0
  32. package/dist/errors.js +97 -0
  33. package/dist/i18n/catalog.d.ts +29 -0
  34. package/dist/i18n/catalog.js +159 -0
  35. package/dist/i18n/index.d.ts +2 -0
  36. package/dist/i18n/index.js +2 -0
  37. package/dist/i18n/keys.d.ts +10 -0
  38. package/dist/i18n/keys.js +34 -0
  39. package/dist/index.d.ts +41 -0
  40. package/dist/index.js +37 -0
  41. package/dist/lint.d.ts +73 -0
  42. package/dist/lint.js +702 -0
  43. package/dist/observability.d.ts +5 -0
  44. package/dist/observability.js +39 -0
  45. package/dist/provider.d.ts +9 -0
  46. package/dist/provider.js +8 -0
  47. package/dist/public-schema-field-lint.d.ts +2 -0
  48. package/dist/public-schema-field-lint.js +158 -0
  49. package/dist/recipes/gov-api.d.ts +19 -0
  50. package/dist/recipes/gov-api.js +72 -0
  51. package/dist/recipes/rest-api.d.ts +21 -0
  52. package/dist/recipes/rest-api.js +115 -0
  53. package/dist/runtime/auth-flow.d.ts +14 -0
  54. package/dist/runtime/auth-flow.js +44 -0
  55. package/dist/runtime/browser.d.ts +25 -0
  56. package/dist/runtime/browser.js +1034 -0
  57. package/dist/runtime/cache.d.ts +10 -0
  58. package/dist/runtime/cache.js +372 -0
  59. package/dist/runtime/choice.d.ts +15 -0
  60. package/dist/runtime/choice.js +435 -0
  61. package/dist/runtime/credential.d.ts +8 -0
  62. package/dist/runtime/credential.js +61 -0
  63. package/dist/runtime/env.d.ts +2 -0
  64. package/dist/runtime/env.js +10 -0
  65. package/dist/runtime/executor.d.ts +16 -0
  66. package/dist/runtime/executor.js +51 -0
  67. package/dist/runtime/http.d.ts +8 -0
  68. package/dist/runtime/http.js +706 -0
  69. package/dist/runtime/insights.d.ts +9 -0
  70. package/dist/runtime/insights.js +324 -0
  71. package/dist/runtime/instrumentation.d.ts +8 -0
  72. package/dist/runtime/instrumentation.js +269 -0
  73. package/dist/runtime/key-derivation.d.ts +24 -0
  74. package/dist/runtime/key-derivation.js +73 -0
  75. package/dist/runtime/keyring.d.ts +25 -0
  76. package/dist/runtime/keyring.js +93 -0
  77. package/dist/runtime/namespace.d.ts +9 -0
  78. package/dist/runtime/namespace.js +19 -0
  79. package/dist/runtime/otlp.d.ts +39 -0
  80. package/dist/runtime/otlp.js +103 -0
  81. package/dist/runtime/perf.d.ts +12 -0
  82. package/dist/runtime/perf.js +52 -0
  83. package/dist/runtime/prevalidate.d.ts +12 -0
  84. package/dist/runtime/prevalidate.js +173 -0
  85. package/dist/runtime/provider.d.ts +2 -0
  86. package/dist/runtime/provider.js +11 -0
  87. package/dist/runtime/proxy-errors.d.ts +21 -0
  88. package/dist/runtime/proxy-errors.js +83 -0
  89. package/dist/runtime/proxy-telemetry.d.ts +8 -0
  90. package/dist/runtime/proxy-telemetry.js +174 -0
  91. package/dist/runtime/redis.d.ts +17 -0
  92. package/dist/runtime/redis.js +82 -0
  93. package/dist/runtime/request-options.d.ts +3 -0
  94. package/dist/runtime/request-options.js +42 -0
  95. package/dist/runtime/state.d.ts +17 -0
  96. package/dist/runtime/state.js +344 -0
  97. package/dist/runtime/stealth.d.ts +18 -0
  98. package/dist/runtime/stealth.js +827 -0
  99. package/dist/runtime/stt.d.ts +22 -0
  100. package/dist/runtime/stt.js +480 -0
  101. package/dist/runtime/trace.d.ts +26 -0
  102. package/dist/runtime/trace.js +142 -0
  103. package/dist/runtime/waterfall.d.ts +12 -0
  104. package/dist/runtime/waterfall.js +147 -0
  105. package/dist/schema.d.ts +74 -0
  106. package/dist/schema.js +243 -0
  107. package/dist/serve.d.ts +1 -0
  108. package/dist/serve.js +1 -0
  109. package/dist/server/index.d.ts +3 -0
  110. package/dist/server/index.js +2 -0
  111. package/dist/server/serve.d.ts +64 -0
  112. package/dist/server/serve.js +1110 -0
  113. package/dist/server/types.d.ts +136 -0
  114. package/dist/server/types.js +86 -0
  115. package/dist/stealth/profiles.d.ts +4 -0
  116. package/dist/stealth/profiles.js +259 -0
  117. package/dist/stream.d.ts +44 -0
  118. package/dist/stream.js +151 -0
  119. package/dist/testing/helpers.d.ts +23 -0
  120. package/dist/testing/helpers.js +95 -0
  121. package/dist/testing/index.d.ts +2 -0
  122. package/dist/testing/index.js +2 -0
  123. package/dist/testing/run.d.ts +34 -0
  124. package/dist/testing/run.js +303 -0
  125. package/dist/types.d.ts +1324 -0
  126. package/dist/types.js +61 -0
  127. package/dist/utils/date.d.ts +6 -0
  128. package/dist/utils/date.js +101 -0
  129. package/dist/utils/parse.d.ts +16 -0
  130. package/dist/utils/parse.js +51 -0
  131. package/dist/utils/text.d.ts +4 -0
  132. package/dist/utils/text.js +14 -0
  133. package/dist/utils/transform.d.ts +8 -0
  134. package/dist/utils/transform.js +48 -0
  135. package/package.json +42 -25
  136. package/src/ceremonies/index.ts +8 -2
  137. package/src/choice-token.ts +1 -0
  138. package/src/cli/commands.ts +8 -5
  139. package/src/cli/create.ts +28 -0
  140. package/src/cli/templates/provider/operations/ping.ts.tpl +3 -2
  141. package/src/cli/templates/provider/schemas/ping.ts.tpl +8 -0
  142. package/src/config/loader.ts +19 -1
  143. package/src/contract-json.ts +75 -0
  144. package/src/contract-serialization.ts +89 -0
  145. package/src/contract-types.ts +52 -0
  146. package/src/contract.ts +215 -0
  147. package/src/define.ts +37 -2
  148. package/src/errors.ts +15 -0
  149. package/src/i18n/catalog.ts +156 -0
  150. package/src/index.ts +22 -1
  151. package/src/lint.ts +256 -37
  152. package/src/provider.ts +45 -2
  153. package/src/runtime/browser.ts +685 -30
  154. package/src/runtime/cache.ts +35 -89
  155. package/src/runtime/choice.ts +760 -0
  156. package/src/runtime/executor.ts +19 -2
  157. package/src/runtime/redis.ts +116 -0
  158. package/src/runtime/state.ts +487 -0
  159. package/src/runtime/stealth.ts +8 -1
  160. package/src/server/serve.ts +361 -46
  161. package/src/server/types.ts +2 -0
  162. package/src/testing/run.ts +16 -3
  163. package/src/types.ts +209 -6
@@ -82,8 +82,10 @@ export const AuthFlowRequestSchema = z.object({
82
82
  externalRef: z.string().optional(),
83
83
  tenantId: z.string().optional(),
84
84
  providerId: z.string().optional(),
85
+ headers: z.record(z.string(), z.string()).optional(),
85
86
  input: z.record(z.string(), z.unknown()).optional(),
86
87
  context: z.record(z.string(), z.unknown()).optional(),
88
+ connection: OperationConnectionSchema.optional(),
87
89
  });
88
90
 
89
91
  export const AuthFlowSuccessResponseSchema = z.object({
@@ -1,7 +1,8 @@
1
1
  import { describe, expect, it } from "bun:test";
2
2
 
3
3
  import { createProviderCache } from "../runtime/cache";
4
- import { createUnsupportedProviderRuntimeState } from "../runtime/state";
4
+ import { createTestProviderChoiceContext } from "../runtime/choice";
5
+ import { createMemoryProviderRuntimeState } from "../runtime/state";
5
6
  import { createUnsupportedSttClient } from "../runtime/stt";
6
7
  import { safeParseSchemaSync } from "../schema";
7
8
  import type {
@@ -149,11 +150,13 @@ function createSnapshotContext(rawFixture: unknown): ProviderContext {
149
150
  getAccessToken: () => undefined,
150
151
  getScopes: () => [],
151
152
  };
153
+ const request = { headers: {} };
154
+ const state = createMemoryProviderRuntimeState();
152
155
 
153
156
  return {
154
157
  env: { get: () => undefined },
155
158
  credential,
156
- request: { headers: {} },
159
+ request,
157
160
  http: {
158
161
  request: async () => jsonResponse(rawFixture),
159
162
  get: async () => jsonResponse(rawFixture),
@@ -164,7 +167,7 @@ function createSnapshotContext(rawFixture: unknown): ProviderContext {
164
167
  sse: async () => unsupported("ctx.http.sse"),
165
168
  },
166
169
  cache: createProviderCache({ providerId: "standard-test" }),
167
- state: createUnsupportedProviderRuntimeState(),
170
+ state,
168
171
  stealth: {
169
172
  fetch: async () => unsupported("ctx.stealth.fetch"),
170
173
  createSession: () => unsupported("ctx.stealth.createSession"),
@@ -172,6 +175,10 @@ function createSnapshotContext(rawFixture: unknown): ProviderContext {
172
175
  browser: {
173
176
  engine: "playwright-stealth",
174
177
  newPage: async () => unsupported("ctx.browser.newPage"),
178
+ rawPage: async () => unsupported("ctx.browser.rawPage"),
179
+ withIsolatedContext: async () =>
180
+ unsupported("ctx.browser.withIsolatedContext"),
181
+ solveChallenge: async () => unsupported("ctx.browser.solveChallenge"),
175
182
  },
176
183
  trace: {
177
184
  span: async (_name, fn) => fn(),
@@ -183,6 +190,12 @@ function createSnapshotContext(rawFixture: unknown): ProviderContext {
183
190
  stt: createUnsupportedSttClient(
184
191
  "Standard test snapshot context does not support ctx.stt.transcribe",
185
192
  ),
193
+ choice: createTestProviderChoiceContext({
194
+ providerId: "standard-test",
195
+ request,
196
+ credential,
197
+ state,
198
+ }),
186
199
  };
187
200
  }
188
201
 
package/src/types.ts CHANGED
@@ -524,6 +524,26 @@ export interface HealthCheckAssertionContext<TOutput = unknown> {
524
524
  readonly meta?: Record<string, unknown>;
525
525
  }
526
526
 
527
+ export interface HealthCheckInputPreparationContext<TInput = unknown> {
528
+ readonly providerId: string;
529
+ readonly operationId: string;
530
+ readonly input: TInput;
531
+ readonly connectionId?: string;
532
+ readonly gateway: {
533
+ execute: (
534
+ providerId: string,
535
+ operationId: string,
536
+ input: unknown,
537
+ options?: { connectionId?: string },
538
+ ) => Promise<{
539
+ status: number;
540
+ duration: number;
541
+ data: unknown;
542
+ meta?: Record<string, unknown>;
543
+ }>;
544
+ };
545
+ }
546
+
527
547
  /**
528
548
  * Optional return value from an assertions lambda. Allows the case to
529
549
  * downgrade to "degraded" without throwing, and to attach a human-friendly
@@ -550,6 +570,14 @@ export interface HealthCheckCase<TInput = unknown, TOutput = unknown> {
550
570
  description?: string;
551
571
  /** Input passed to the operation handler for this case. */
552
572
  input: TInput;
573
+ /**
574
+ * Optional runtime input preparation hook for volatile probes. Use this when
575
+ * the durable probe input must be derived from a live read-only operation
576
+ * immediately before the checked operation executes.
577
+ */
578
+ prepareInput?: (
579
+ ctx: HealthCheckInputPreparationContext<TInput>,
580
+ ) => TInput | Promise<TInput>;
553
581
  /**
554
582
  * Assertion executed against the operation's response and timing.
555
583
  *
@@ -694,6 +722,7 @@ export interface BrowserOptions {
694
722
  stealth?: boolean;
695
723
  proxy?: string;
696
724
  engine?: BrowserEngine;
725
+ requireCdpPool?: boolean;
697
726
  }
698
727
 
699
728
  export interface StealthProfile {
@@ -950,6 +979,13 @@ export type HttpMethod =
950
979
  export interface StealthFetchOptions extends RequestOptions {
951
980
  method?: HttpMethod;
952
981
  body?: string | Buffer;
982
+ /**
983
+ * Offsets policy-managed proxy pool selection for caller-managed retries.
984
+ * Use when a request receives an upstream challenge page rather than a
985
+ * transport error, so the next logical retry does not restart at the same
986
+ * operation-affinity proxy.
987
+ */
988
+ proxyAttemptOffset?: number;
953
989
  /** Override the configured browser-like stealth profile for this request. */
954
990
  profile?: string;
955
991
  /**
@@ -1139,9 +1175,62 @@ export interface StealthClient {
1139
1175
 
1140
1176
  export interface BrowserClient {
1141
1177
  readonly engine: BrowserEngine;
1142
- newPage(): Promise<unknown>;
1178
+ close?(): Promise<void>;
1179
+ newPage(): Promise<BrowserPage>;
1180
+ rawPage(): Promise<BrowserPage>;
1181
+ withIsolatedContext<T>(
1182
+ handler: (page: BrowserPage) => Promise<T>,
1183
+ ): Promise<T>;
1184
+ solveChallenge(
1185
+ request: BrowserChallengeRequest,
1186
+ ): Promise<BrowserChallengeResult>;
1187
+ }
1188
+
1189
+ export interface BrowserLocator {
1190
+ click(): Promise<void>;
1191
+ fill(text: string): Promise<void>;
1192
+ textContent(): Promise<string | null>;
1193
+ waitFor(options?: { timeout?: number }): Promise<void>;
1194
+ }
1195
+
1196
+ export interface BrowserFrame {
1197
+ id: string;
1198
+ name?: string;
1199
+ parentId?: string;
1200
+ url(): Promise<string>;
1201
+ title(): Promise<string>;
1202
+ content(): Promise<string>;
1203
+ evaluate<T>(fn: string | (() => T)): Promise<T>;
1204
+ locator(selector: string): BrowserLocator;
1205
+ }
1206
+
1207
+ export interface BrowserPage extends BrowserFrame {
1208
+ close(): Promise<void>;
1209
+ fill(selector: string, text: string): Promise<void>;
1210
+ goto(url: string): Promise<void>;
1211
+ pageId?: string;
1212
+ screenshot(options?: { fullPage?: boolean }): Promise<Buffer>;
1213
+ click(selector: string): Promise<void>;
1214
+ type(selector: string, text: string): Promise<void>;
1215
+ waitForSelector(
1216
+ selector: string,
1217
+ options?: { timeout?: number },
1218
+ ): Promise<void>;
1219
+ frames(): Promise<BrowserFrame[]>;
1143
1220
  }
1144
1221
 
1222
+ export type BrowserChallengeRequest = {
1223
+ type: "recaptcha";
1224
+ siteKey?: string;
1225
+ timeout?: number;
1226
+ };
1227
+
1228
+ export type BrowserChallengeResult = {
1229
+ type: BrowserChallengeRequest["type"];
1230
+ solved: boolean;
1231
+ frameUrl?: string;
1232
+ };
1233
+
1145
1234
  export type TraceAttributeValue = string | number | boolean;
1146
1235
 
1147
1236
  export interface TraceSpan {
@@ -1197,6 +1286,107 @@ export interface ProviderRequestContext {
1197
1286
  headers: Record<string, string>;
1198
1287
  }
1199
1288
 
1289
+ export interface ProviderChoiceBindingOptions {
1290
+ connection?: boolean;
1291
+ credentialKeys?: readonly string[];
1292
+ }
1293
+
1294
+ export type ProviderChoiceStorageOptions =
1295
+ | {
1296
+ readonly mode: "inline";
1297
+ }
1298
+ | {
1299
+ readonly mode: "server";
1300
+ readonly namespace: string;
1301
+ readonly state?: ProviderRuntimeState;
1302
+ readonly ttl?: ProviderStateDurationString;
1303
+ readonly maxEntries: number;
1304
+ readonly maxValueBytes: number;
1305
+ readonly unavailable?: "reject";
1306
+ }
1307
+ | {
1308
+ readonly mode: "auto";
1309
+ readonly namespace: string;
1310
+ readonly state?: ProviderRuntimeState;
1311
+ readonly ttl?: ProviderStateDurationString;
1312
+ readonly maxInlineBytes: number;
1313
+ readonly maxEntries: number;
1314
+ readonly maxValueBytes: number;
1315
+ readonly unavailable?: "reject";
1316
+ };
1317
+
1318
+ export interface ProviderChoiceIssueOptions<
1319
+ TPayload extends Record<string, unknown>,
1320
+ > {
1321
+ prefix: string;
1322
+ purpose: string;
1323
+ payload: TPayload;
1324
+ ttlMs: number;
1325
+ nowMs?: number;
1326
+ bind?: ProviderChoiceBindingOptions;
1327
+ storage?: ProviderChoiceStorageOptions;
1328
+ }
1329
+
1330
+ export interface ProviderChoiceParseOptions {
1331
+ token: string;
1332
+ prefix: string;
1333
+ purpose: string;
1334
+ ttlMs?: number;
1335
+ nowMs?: number;
1336
+ futureToleranceMs?: number;
1337
+ bind?: ProviderChoiceBindingOptions;
1338
+ storage?: ProviderChoiceStorageOptions;
1339
+ }
1340
+
1341
+ export interface ProviderChoiceContext {
1342
+ issue<TPayload extends Record<string, unknown>>(
1343
+ options: ProviderChoiceIssueOptions<TPayload> & {
1344
+ readonly storage?: { readonly mode: "inline" };
1345
+ },
1346
+ ): string;
1347
+ issue<TPayload extends Record<string, unknown>>(
1348
+ options: ProviderChoiceIssueOptions<TPayload> & {
1349
+ readonly storage: Extract<
1350
+ ProviderChoiceStorageOptions,
1351
+ { readonly mode: "server" }
1352
+ >;
1353
+ },
1354
+ ): Promise<string>;
1355
+ issue<TPayload extends Record<string, unknown>>(
1356
+ options: ProviderChoiceIssueOptions<TPayload> & {
1357
+ readonly storage: Extract<
1358
+ ProviderChoiceStorageOptions,
1359
+ { readonly mode: "auto" }
1360
+ >;
1361
+ },
1362
+ ): string | Promise<string>;
1363
+ issue<TPayload extends Record<string, unknown>>(
1364
+ options: ProviderChoiceIssueOptions<TPayload>,
1365
+ ): string | Promise<string>;
1366
+ parse(
1367
+ options: ProviderChoiceParseOptions & {
1368
+ readonly storage?: { readonly mode: "inline" };
1369
+ },
1370
+ ): Record<string, unknown>;
1371
+ parse(
1372
+ options: ProviderChoiceParseOptions & {
1373
+ readonly storage: Extract<
1374
+ ProviderChoiceStorageOptions,
1375
+ { readonly mode: "server" }
1376
+ >;
1377
+ },
1378
+ ): Promise<Record<string, unknown>>;
1379
+ parse(
1380
+ options: ProviderChoiceParseOptions & {
1381
+ readonly storage: Extract<
1382
+ ProviderChoiceStorageOptions,
1383
+ { readonly mode: "auto" }
1384
+ >;
1385
+ },
1386
+ ): Record<string, unknown> | Promise<Record<string, unknown>>;
1387
+ parse(options: ProviderChoiceParseOptions): Record<string, unknown>;
1388
+ }
1389
+
1200
1390
  export interface ContextScratchpad {
1201
1391
  get(key: string): unknown;
1202
1392
  set(key: string, value: unknown): void;
@@ -1213,6 +1403,7 @@ export interface FlowContext {
1213
1403
  http: HttpClient;
1214
1404
  stealth: StealthClient;
1215
1405
  env: EnvContext;
1406
+ credential?: CredentialContext;
1216
1407
  context: ContextScratchpad;
1217
1408
  stt: SttContext;
1218
1409
  }
@@ -1223,23 +1414,33 @@ export interface AuthTurn {
1223
1414
  expiresAt?: string;
1224
1415
  data?: Record<string, unknown>;
1225
1416
  expectedInput?: Record<string, unknown>;
1417
+ /**
1418
+ * @deprecated Compatibility-only materialized provider auth hint.
1419
+ * Provider source must emit hintKey; SDK/server boundaries may materialize
1420
+ * this field from provider locale catalogs for legacy clients.
1421
+ */
1226
1422
  hint?: string;
1423
+ /** Provider locale catalog key for the auth turn hint. */
1424
+ hintKey?: ProviderLocaleKeyInput;
1227
1425
  timing?: {
1228
1426
  suggestedPollIntervalMs?: number;
1229
1427
  maxWaitMs?: number;
1230
1428
  };
1231
1429
  }
1232
1430
 
1233
- export type AuthFlowHandler = (
1431
+ export type AuthFlowStartHandler = (ctx: FlowContext) => Promise<AuthTurn>;
1432
+
1433
+ export type AuthFlowInputHandler = (
1234
1434
  ctx: FlowContext,
1235
1435
  input?: Record<string, unknown>,
1236
1436
  ) => Promise<AuthTurn>;
1237
1437
 
1238
1438
  export interface AuthFlowDefinition {
1239
- start: AuthFlowHandler;
1240
- continue: AuthFlowHandler;
1241
- poll?: AuthFlowHandler;
1242
- abort?: AuthFlowHandler;
1439
+ start: AuthFlowStartHandler;
1440
+ continue: AuthFlowInputHandler;
1441
+ poll?: AuthFlowStartHandler;
1442
+ abort?: AuthFlowStartHandler;
1443
+ refresh?: AuthFlowInputHandler;
1243
1444
  }
1244
1445
 
1245
1446
  export type ProviderStateDurationString =
@@ -1325,6 +1526,7 @@ export interface ProviderContext {
1325
1526
  trace: TraceContext;
1326
1527
  auth: AuthContext;
1327
1528
  stt: SttContext;
1529
+ choice: ProviderChoiceContext;
1328
1530
  }
1329
1531
 
1330
1532
  export interface AuthConfig {
@@ -1384,6 +1586,7 @@ export interface OperationDefinition<
1384
1586
  toolRouter?: OperationToolRouterMetadata;
1385
1587
  observability?: OperationObservabilityConfig;
1386
1588
  transport?: OperationTransport;
1589
+ retryOnAuthRefresh?: boolean;
1387
1590
  input: TInput;
1388
1591
  output: TOutput;
1389
1592
  handler(