@apifuse/provider-sdk 2.1.0-beta.1 → 2.1.0-beta.10

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 (212) hide show
  1. package/AUTHORING.md +208 -2
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +114 -10
  4. package/SUBMISSION.md +87 -0
  5. package/bin/apifuse-check.ts +86 -4
  6. package/bin/apifuse-dev.ts +87 -13
  7. package/bin/apifuse-pack-check.ts +80 -0
  8. package/bin/apifuse-pack-smoke.ts +303 -2
  9. package/bin/apifuse-perf.ts +142 -49
  10. package/bin/apifuse-record.ts +182 -104
  11. package/bin/apifuse-submit-check.ts +2538 -0
  12. package/bin/apifuse.ts +1 -1
  13. package/dist/ceremonies/index.d.ts +41 -0
  14. package/dist/ceremonies/index.js +490 -0
  15. package/dist/choice-token.d.ts +24 -0
  16. package/dist/choice-token.js +74 -0
  17. package/dist/cli/commands.d.ts +10 -0
  18. package/dist/cli/commands.js +80 -0
  19. package/dist/cli/create.d.ts +47 -0
  20. package/dist/cli/create.js +762 -0
  21. package/dist/cli/templates/provider/.dockerignore.tpl +22 -0
  22. package/dist/cli/templates/provider/.gitignore.tpl +22 -0
  23. package/dist/cli/templates/provider/Dockerfile.tpl +7 -0
  24. package/dist/cli/templates/provider/README.md.tpl +160 -0
  25. package/dist/cli/templates/provider/dev.ts.tpl +5 -0
  26. package/dist/cli/templates/provider/domain/README.md.tpl +3 -0
  27. package/dist/cli/templates/provider/index.test.ts.tpl +13 -0
  28. package/dist/cli/templates/provider/index.ts.tpl +15 -0
  29. package/dist/cli/templates/provider/mappers/README.md.tpl +3 -0
  30. package/dist/cli/templates/provider/meta.ts.tpl +7 -0
  31. package/dist/cli/templates/provider/operations/index.ts.tpl +5 -0
  32. package/dist/cli/templates/provider/operations/ping.ts.tpl +24 -0
  33. package/dist/cli/templates/provider/schemas/ping.ts.tpl +24 -0
  34. package/dist/cli/templates/provider/start.ts.tpl +5 -0
  35. package/dist/cli/templates/provider/upstream/README.md.tpl +3 -0
  36. package/dist/config/loader.d.ts +107 -0
  37. package/dist/config/loader.js +935 -0
  38. package/dist/contract-json.d.ts +9 -0
  39. package/dist/contract-json.js +51 -0
  40. package/dist/contract-serialization.d.ts +4 -0
  41. package/dist/contract-serialization.js +78 -0
  42. package/dist/contract-types.d.ts +49 -0
  43. package/dist/contract-types.js +1 -0
  44. package/dist/contract.d.ts +6 -0
  45. package/dist/contract.js +155 -0
  46. package/dist/define.d.ts +97 -0
  47. package/dist/define.js +1320 -0
  48. package/dist/dev.d.ts +9 -0
  49. package/dist/dev.js +15 -0
  50. package/dist/errors.d.ts +59 -0
  51. package/dist/errors.js +97 -0
  52. package/dist/i18n/catalog.d.ts +29 -0
  53. package/dist/i18n/catalog.js +159 -0
  54. package/dist/i18n/index.d.ts +2 -0
  55. package/dist/i18n/index.js +2 -0
  56. package/dist/i18n/keys.d.ts +10 -0
  57. package/dist/i18n/keys.js +34 -0
  58. package/dist/index.d.ts +41 -0
  59. package/dist/index.js +37 -0
  60. package/dist/lint.d.ts +73 -0
  61. package/dist/lint.js +702 -0
  62. package/dist/observability.d.ts +5 -0
  63. package/dist/observability.js +39 -0
  64. package/dist/provider.d.ts +9 -0
  65. package/dist/provider.js +8 -0
  66. package/dist/public-schema-field-lint.d.ts +2 -0
  67. package/dist/public-schema-field-lint.js +158 -0
  68. package/dist/recipes/gov-api.d.ts +19 -0
  69. package/dist/recipes/gov-api.js +72 -0
  70. package/dist/recipes/rest-api.d.ts +21 -0
  71. package/dist/recipes/rest-api.js +115 -0
  72. package/dist/runtime/auth-flow.d.ts +14 -0
  73. package/dist/runtime/auth-flow.js +44 -0
  74. package/dist/runtime/browser.d.ts +25 -0
  75. package/dist/runtime/browser.js +1034 -0
  76. package/dist/runtime/cache.d.ts +10 -0
  77. package/dist/runtime/cache.js +372 -0
  78. package/dist/runtime/choice.d.ts +15 -0
  79. package/dist/runtime/choice.js +435 -0
  80. package/dist/runtime/credential.d.ts +8 -0
  81. package/dist/runtime/credential.js +61 -0
  82. package/dist/runtime/env.d.ts +2 -0
  83. package/dist/runtime/env.js +10 -0
  84. package/dist/runtime/executor.d.ts +16 -0
  85. package/dist/runtime/executor.js +51 -0
  86. package/dist/runtime/http.d.ts +8 -0
  87. package/dist/runtime/http.js +706 -0
  88. package/dist/runtime/insights.d.ts +9 -0
  89. package/dist/runtime/insights.js +324 -0
  90. package/dist/runtime/instrumentation.d.ts +8 -0
  91. package/dist/runtime/instrumentation.js +269 -0
  92. package/dist/runtime/key-derivation.d.ts +24 -0
  93. package/dist/runtime/key-derivation.js +73 -0
  94. package/dist/runtime/keyring.d.ts +25 -0
  95. package/dist/runtime/keyring.js +93 -0
  96. package/dist/runtime/namespace.d.ts +9 -0
  97. package/dist/runtime/namespace.js +19 -0
  98. package/dist/runtime/otlp.d.ts +39 -0
  99. package/dist/runtime/otlp.js +103 -0
  100. package/dist/runtime/perf.d.ts +12 -0
  101. package/dist/runtime/perf.js +52 -0
  102. package/dist/runtime/prevalidate.d.ts +12 -0
  103. package/dist/runtime/prevalidate.js +173 -0
  104. package/dist/runtime/provider.d.ts +2 -0
  105. package/dist/runtime/provider.js +11 -0
  106. package/dist/runtime/proxy-errors.d.ts +21 -0
  107. package/dist/runtime/proxy-errors.js +83 -0
  108. package/dist/runtime/proxy-telemetry.d.ts +8 -0
  109. package/dist/runtime/proxy-telemetry.js +174 -0
  110. package/dist/runtime/redis.d.ts +17 -0
  111. package/dist/runtime/redis.js +82 -0
  112. package/dist/runtime/request-options.d.ts +3 -0
  113. package/dist/runtime/request-options.js +42 -0
  114. package/dist/runtime/state.d.ts +17 -0
  115. package/dist/runtime/state.js +344 -0
  116. package/dist/runtime/stealth.d.ts +18 -0
  117. package/dist/runtime/stealth.js +834 -0
  118. package/dist/runtime/stt.d.ts +22 -0
  119. package/dist/runtime/stt.js +480 -0
  120. package/dist/runtime/trace.d.ts +26 -0
  121. package/dist/runtime/trace.js +142 -0
  122. package/dist/runtime/waterfall.d.ts +12 -0
  123. package/dist/runtime/waterfall.js +147 -0
  124. package/dist/schema.d.ts +74 -0
  125. package/dist/schema.js +243 -0
  126. package/dist/serve.d.ts +1 -0
  127. package/dist/serve.js +1 -0
  128. package/dist/server/index.d.ts +3 -0
  129. package/dist/server/index.js +2 -0
  130. package/dist/server/serve.d.ts +64 -0
  131. package/dist/server/serve.js +1110 -0
  132. package/dist/server/types.d.ts +136 -0
  133. package/dist/server/types.js +86 -0
  134. package/dist/stealth/profiles.d.ts +4 -0
  135. package/dist/stealth/profiles.js +259 -0
  136. package/dist/stream.d.ts +44 -0
  137. package/dist/stream.js +151 -0
  138. package/dist/testing/helpers.d.ts +23 -0
  139. package/dist/testing/helpers.js +95 -0
  140. package/dist/testing/index.d.ts +2 -0
  141. package/dist/testing/index.js +2 -0
  142. package/dist/testing/run.d.ts +34 -0
  143. package/dist/testing/run.js +303 -0
  144. package/dist/types.d.ts +1326 -0
  145. package/dist/types.js +61 -0
  146. package/dist/utils/date.d.ts +6 -0
  147. package/dist/utils/date.js +101 -0
  148. package/dist/utils/parse.d.ts +16 -0
  149. package/dist/utils/parse.js +51 -0
  150. package/dist/utils/text.d.ts +4 -0
  151. package/dist/utils/text.js +14 -0
  152. package/dist/utils/transform.d.ts +8 -0
  153. package/dist/utils/transform.js +48 -0
  154. package/package.json +57 -30
  155. package/src/ceremonies/index.ts +8 -2
  156. package/src/choice-token.ts +165 -0
  157. package/src/cli/commands.ts +34 -11
  158. package/src/cli/create.ts +214 -52
  159. package/src/cli/templates/provider/.dockerignore.tpl +22 -0
  160. package/src/cli/templates/provider/.gitignore.tpl +22 -0
  161. package/src/cli/templates/provider/README.md.tpl +120 -1
  162. package/src/cli/templates/provider/dev.ts.tpl +1 -1
  163. package/src/cli/templates/provider/domain/README.md.tpl +3 -0
  164. package/src/cli/templates/provider/index.ts.tpl +5 -48
  165. package/src/cli/templates/provider/mappers/README.md.tpl +3 -0
  166. package/src/cli/templates/provider/meta.ts.tpl +7 -0
  167. package/src/cli/templates/provider/operations/index.ts.tpl +5 -0
  168. package/src/cli/templates/provider/operations/ping.ts.tpl +24 -0
  169. package/src/cli/templates/provider/schemas/ping.ts.tpl +24 -0
  170. package/src/cli/templates/provider/start.ts.tpl +1 -1
  171. package/src/cli/templates/provider/upstream/README.md.tpl +3 -0
  172. package/src/config/loader.ts +1224 -9
  173. package/src/contract-json.ts +75 -0
  174. package/src/contract-serialization.ts +89 -0
  175. package/src/contract-types.ts +52 -0
  176. package/src/contract.ts +215 -0
  177. package/src/define.ts +1688 -48
  178. package/src/errors.ts +27 -0
  179. package/src/i18n/catalog.ts +277 -0
  180. package/src/i18n/index.ts +2 -0
  181. package/src/i18n/keys.ts +64 -0
  182. package/src/index.ts +174 -9
  183. package/src/lint.ts +547 -73
  184. package/src/observability.ts +41 -0
  185. package/src/provider.ts +104 -4
  186. package/src/public-schema-field-lint.ts +237 -0
  187. package/src/runtime/auth-flow.ts +7 -0
  188. package/src/runtime/browser.ts +762 -51
  189. package/src/runtime/cache.ts +528 -0
  190. package/src/runtime/choice.ts +760 -0
  191. package/src/runtime/executor.ts +32 -3
  192. package/src/runtime/http.ts +939 -195
  193. package/src/runtime/insights.ts +11 -11
  194. package/src/runtime/instrumentation.ts +12 -4
  195. package/src/runtime/key-derivation.ts +1 -1
  196. package/src/runtime/keyring.ts +4 -3
  197. package/src/runtime/proxy-errors.ts +132 -0
  198. package/src/runtime/proxy-telemetry.ts +253 -0
  199. package/src/runtime/redis.ts +116 -0
  200. package/src/runtime/request-options.ts +66 -0
  201. package/src/runtime/state.ts +563 -0
  202. package/src/runtime/stealth.ts +1159 -0
  203. package/src/runtime/stt.ts +629 -0
  204. package/src/runtime/trace.ts +1 -1
  205. package/src/schema.ts +363 -1
  206. package/src/server/serve.ts +1157 -75
  207. package/src/server/types.ts +37 -0
  208. package/src/stream.ts +210 -0
  209. package/src/testing/run.ts +31 -5
  210. package/src/types.ts +1107 -59
  211. package/src/runtime/tls.ts +0 -434
  212. package/src/types/playwright-stealth.d.ts +0 -9
@@ -1,5 +1,7 @@
1
1
  import { z } from "zod";
2
2
 
3
+ import { HttpRetryPreset } from "../types";
4
+
3
5
  export const ConnectionModeSchema = z.enum([
4
6
  "oauth2",
5
7
  "credentials",
@@ -34,6 +36,39 @@ export const ErrorEnvelopeSchema = z.object({
34
36
 
35
37
  export const OperationSuccessResponseSchema = z.object({
36
38
  data: z.unknown(),
39
+ meta: z
40
+ .object({
41
+ cached: z.boolean().optional(),
42
+ stale: z.boolean().optional(),
43
+ cache: z
44
+ .object({
45
+ hit: z.boolean(),
46
+ stale: z.boolean(),
47
+ keys: z.array(z.string()),
48
+ source: z.enum(["redis", "memory", "loader", "mixed"]).optional(),
49
+ })
50
+ .optional(),
51
+ retry: z
52
+ .object({
53
+ attempts: z.number().int().min(1),
54
+ retries: z.number().int().min(0),
55
+ preset: z
56
+ .enum([
57
+ HttpRetryPreset.Off,
58
+ HttpRetryPreset.TransportTransient,
59
+ HttpRetryPreset.SafeRead,
60
+ HttpRetryPreset.AggressiveRead,
61
+ HttpRetryPreset.RateLimitAware,
62
+ ])
63
+ .optional(),
64
+ transport: z.enum(["native"]),
65
+ lastErrorCode: z.string().optional(),
66
+ lastStatus: z.number().int().optional(),
67
+ })
68
+ .optional(),
69
+ })
70
+ .passthrough()
71
+ .optional(),
37
72
  });
38
73
 
39
74
  export const OperationErrorResponseSchema = z.object({
@@ -47,8 +82,10 @@ export const AuthFlowRequestSchema = z.object({
47
82
  externalRef: z.string().optional(),
48
83
  tenantId: z.string().optional(),
49
84
  providerId: z.string().optional(),
85
+ headers: z.record(z.string(), z.string()).optional(),
50
86
  input: z.record(z.string(), z.unknown()).optional(),
51
87
  context: z.record(z.string(), z.unknown()).optional(),
88
+ connection: OperationConnectionSchema.optional(),
52
89
  });
53
90
 
54
91
  export const AuthFlowSuccessResponseSchema = z.object({
package/src/stream.ts ADDED
@@ -0,0 +1,210 @@
1
+ import type { SseMessage } from "./types";
2
+
3
+ export interface SseEvent<TData = unknown> {
4
+ event: string;
5
+ data: TData;
6
+ id?: string;
7
+ retry?: number;
8
+ }
9
+
10
+ export interface SseErrorData {
11
+ code: string;
12
+ message: string;
13
+ requestId?: string;
14
+ retryable?: boolean;
15
+ details?: unknown;
16
+ }
17
+
18
+ export const APIFUSE_STREAM_ERROR_EVENT = "apifuse.error";
19
+ export const APIFUSE_STREAM_DONE_EVENT = "apifuse.done";
20
+
21
+ export function event<TData>(
22
+ eventName: string,
23
+ data: TData,
24
+ options: { id?: string; retry?: number } = {},
25
+ ): SseEvent<TData> {
26
+ return {
27
+ event: eventName,
28
+ data,
29
+ ...(options.id ? { id: options.id } : {}),
30
+ ...(options.retry !== undefined ? { retry: options.retry } : {}),
31
+ };
32
+ }
33
+
34
+ export function error(
35
+ code: string,
36
+ message: string,
37
+ options: Omit<SseErrorData, "code" | "message"> & {
38
+ id?: string;
39
+ retry?: number;
40
+ } = {},
41
+ ): SseEvent<SseErrorData> {
42
+ const { id, retry, ...dataOptions } = options;
43
+ return event(
44
+ APIFUSE_STREAM_ERROR_EVENT,
45
+ { code, message, ...dataOptions },
46
+ { ...(id ? { id } : {}), ...(retry !== undefined ? { retry } : {}) },
47
+ );
48
+ }
49
+
50
+ export function done(): SseEvent<Record<string, never>>;
51
+ export function done<TData>(
52
+ data: TData,
53
+ options?: { id?: string; retry?: number },
54
+ ): SseEvent<TData>;
55
+ export function done<TData>(
56
+ data?: TData,
57
+ options: { id?: string; retry?: number } = {},
58
+ ): SseEvent<TData | Record<string, never>> {
59
+ return event(APIFUSE_STREAM_DONE_EVENT, data ?? {}, options);
60
+ }
61
+
62
+ export function encodeSseEvent(input: SseEvent): string {
63
+ const lines: string[] = [];
64
+ if (input.id !== undefined)
65
+ lines.push(`id: ${sseFieldValue(input.id, "id")}`);
66
+ if (input.event) lines.push(`event: ${sseFieldValue(input.event, "event")}`);
67
+ if (input.retry !== undefined) {
68
+ if (!Number.isInteger(input.retry) || input.retry < 0) {
69
+ throw new TypeError("SSE retry must be a non-negative integer.");
70
+ }
71
+ lines.push(`retry: ${input.retry}`);
72
+ }
73
+ const data =
74
+ typeof input.data === "string" ? input.data : JSON.stringify(input.data);
75
+ for (const line of data.split(/\r?\n/)) {
76
+ lines.push(`data: ${line}`);
77
+ }
78
+ return `${lines.join("\n")}\n\n`;
79
+ }
80
+
81
+ function sseFieldValue(value: string, field: "event" | "id"): string {
82
+ if (/[\r\n]/.test(value)) {
83
+ throw new TypeError(`SSE ${field} must not contain CR or LF.`);
84
+ }
85
+ return value;
86
+ }
87
+
88
+ export async function* readableBytes(
89
+ body: ReadableStream<Uint8Array>,
90
+ ): AsyncIterable<Uint8Array> {
91
+ const reader = body.getReader();
92
+ try {
93
+ for (;;) {
94
+ const { value, done } = await reader.read();
95
+ if (done) return;
96
+ if (value) yield value;
97
+ }
98
+ } finally {
99
+ reader.releaseLock();
100
+ }
101
+ }
102
+
103
+ export async function* readableTextChunks(
104
+ body: ReadableStream<Uint8Array>,
105
+ ): AsyncIterable<string> {
106
+ const decoder = new TextDecoder();
107
+ for await (const chunk of readableBytes(body)) {
108
+ yield decoder.decode(chunk, { stream: true });
109
+ }
110
+ const tail = decoder.decode();
111
+ if (tail) yield tail;
112
+ }
113
+
114
+ export async function* readableLines(
115
+ body: ReadableStream<Uint8Array>,
116
+ ): AsyncIterable<string> {
117
+ let buffer = "";
118
+ for await (const chunk of readableTextChunks(body)) {
119
+ buffer += chunk;
120
+ for (;;) {
121
+ const index = buffer.search(/\r?\n/);
122
+ if (index < 0) break;
123
+ const line = buffer.slice(0, index);
124
+ const newlineLength =
125
+ buffer[index] === "\r" && buffer[index + 1] === "\n" ? 2 : 1;
126
+ buffer = buffer.slice(index + newlineLength);
127
+ yield line;
128
+ }
129
+ }
130
+ if (buffer) yield buffer;
131
+ }
132
+
133
+ function createSseMessage(
134
+ eventName: string,
135
+ data: string,
136
+ options: { id?: string; retry?: number },
137
+ ): SseMessage {
138
+ return {
139
+ event: eventName || "message",
140
+ data,
141
+ ...(options.id !== undefined ? { id: options.id } : {}),
142
+ ...(options.retry !== undefined ? { retry: options.retry } : {}),
143
+ json<T = unknown>() {
144
+ return parseJson<T>(data);
145
+ },
146
+ };
147
+ }
148
+
149
+ function parseJson<T>(data: string): T {
150
+ return JSON.parse(data);
151
+ }
152
+
153
+ export async function* parseSseStream(
154
+ body: ReadableStream<Uint8Array>,
155
+ ): AsyncIterable<SseMessage> {
156
+ let eventName = "message";
157
+ let dataLines: string[] = [];
158
+ let id: string | undefined;
159
+ let retry: number | undefined;
160
+
161
+ const dispatch = function* () {
162
+ if (dataLines.length === 0 && id === undefined && retry === undefined) {
163
+ return;
164
+ }
165
+ yield createSseMessage(eventName, dataLines.join("\n"), { id, retry });
166
+ eventName = "message";
167
+ dataLines = [];
168
+ retry = undefined;
169
+ };
170
+
171
+ for await (const line of readableLines(body)) {
172
+ if (line === "") {
173
+ yield* dispatch();
174
+ continue;
175
+ }
176
+ if (line.startsWith(":")) continue;
177
+ const separator = line.indexOf(":");
178
+ const field = separator < 0 ? line : line.slice(0, separator);
179
+ const rawValue = separator < 0 ? "" : line.slice(separator + 1);
180
+ const value = rawValue.startsWith(" ") ? rawValue.slice(1) : rawValue;
181
+ switch (field) {
182
+ case "event":
183
+ eventName = value;
184
+ break;
185
+ case "data":
186
+ dataLines.push(value);
187
+ break;
188
+ case "id":
189
+ id = value;
190
+ break;
191
+ case "retry": {
192
+ const parsed = Number(value);
193
+ if (Number.isInteger(parsed) && parsed >= 0) retry = parsed;
194
+ break;
195
+ }
196
+ }
197
+ }
198
+ yield* dispatch();
199
+ }
200
+
201
+ export const stream = {
202
+ event,
203
+ error,
204
+ done,
205
+ encodeSseEvent,
206
+ parseSseStream,
207
+ readableBytes,
208
+ readableTextChunks,
209
+ readableLines,
210
+ };
@@ -1,5 +1,9 @@
1
1
  import { describe, expect, it } from "bun:test";
2
2
 
3
+ import { createProviderCache } from "../runtime/cache";
4
+ import { createTestProviderChoiceContext } from "../runtime/choice";
5
+ import { createMemoryProviderRuntimeState } from "../runtime/state";
6
+ import { createUnsupportedSttClient } from "../runtime/stt";
3
7
  import { safeParseSchemaSync } from "../schema";
4
8
  import type {
5
9
  AuthMode,
@@ -9,7 +13,10 @@ import type {
9
13
  ProviderDefinition,
10
14
  } from "../types";
11
15
 
12
- const CONNECTOR_ID_REGEX = /^[a-z][a-z0-9]*(-[a-z][a-z0-9]*)+$/;
16
+ // Mirrors CONNECTOR_ID_REGEX in ../define.ts, which defineProvider() enforces.
17
+ // A single lowercase segment (no hyphen) is a valid id, so the trailing group
18
+ // is optional (`*`), matching providers like `kakaomap`, `kstartup`, `triple`.
19
+ const CONNECTOR_ID_REGEX = /^[a-z][a-z0-9]*(-[a-z][a-z0-9]*)*$/;
13
20
  const VALID_AUTH_MODES = [
14
21
  "none",
15
22
  "platform-managed",
@@ -143,25 +150,35 @@ function createSnapshotContext(rawFixture: unknown): ProviderContext {
143
150
  getAccessToken: () => undefined,
144
151
  getScopes: () => [],
145
152
  };
153
+ const request = { headers: {} };
154
+ const state = createMemoryProviderRuntimeState();
146
155
 
147
156
  return {
148
157
  env: { get: () => undefined },
149
158
  credential,
150
- request: { headers: {} },
159
+ request,
151
160
  http: {
152
161
  request: async () => jsonResponse(rawFixture),
153
162
  get: async () => jsonResponse(rawFixture),
154
163
  post: async () => jsonResponse(rawFixture),
155
164
  put: async () => jsonResponse(rawFixture),
156
165
  delete: async () => jsonResponse(rawFixture),
166
+ stream: async () => unsupported("ctx.http.stream"),
167
+ sse: async () => unsupported("ctx.http.sse"),
157
168
  },
158
- tls: {
159
- fetch: async () => unsupported("ctx.tls.fetch"),
160
- createSession: () => unsupported("ctx.tls.createSession"),
169
+ cache: createProviderCache({ providerId: "standard-test" }),
170
+ state,
171
+ stealth: {
172
+ fetch: async () => unsupported("ctx.stealth.fetch"),
173
+ createSession: () => unsupported("ctx.stealth.createSession"),
161
174
  },
162
175
  browser: {
163
176
  engine: "playwright-stealth",
164
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"),
165
182
  },
166
183
  trace: {
167
184
  span: async (_name, fn) => fn(),
@@ -170,6 +187,15 @@ function createSnapshotContext(rawFixture: unknown): ProviderContext {
170
187
  requestField: async (name) =>
171
188
  unsupported(`ctx.auth.requestField(${name})`),
172
189
  },
190
+ stt: createUnsupportedSttClient(
191
+ "Standard test snapshot context does not support ctx.stt.transcribe",
192
+ ),
193
+ choice: createTestProviderChoiceContext({
194
+ providerId: "standard-test",
195
+ request,
196
+ credential,
197
+ state,
198
+ }),
173
199
  };
174
200
  }
175
201