@apifuse/provider-sdk 2.1.0-beta.0 → 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 (213) hide show
  1. package/AUTHORING.md +218 -21
  2. package/CHANGELOG.md +54 -0
  3. package/README.md +147 -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 +120 -0
  8. package/bin/apifuse-pack-smoke.ts +423 -0
  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 -29
  155. package/src/ceremonies/index.ts +30 -3
  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 +134 -2
  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 -44
  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 +1282 -7
  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 +1726 -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 -15
  183. package/src/lint.ts +547 -73
  184. package/src/observability.ts +41 -0
  185. package/src/provider.ts +104 -5
  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 +945 -185
  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 +1172 -76
  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 +1118 -44
  211. package/src/composite.ts +0 -43
  212. package/src/runtime/tls.ts +0 -425
  213. package/src/types/playwright-stealth.d.ts +0 -9
@@ -7,14 +7,21 @@ import { basename, dirname, relative, resolve } from "node:path";
7
7
  import { pathToFileURL } from "node:url";
8
8
 
9
9
  import {
10
+ createBypassProviderCache,
10
11
  createHttpClient,
11
- createTlsClient,
12
+ createProviderChoiceContext,
13
+ createStealthClient,
14
+ createSttClientFromEnv,
12
15
  executeOperation,
13
16
  type HttpClient,
14
17
  type ProviderContext,
15
18
  type ProviderDefinition,
16
- type TlsClient,
19
+ ProviderError,
20
+ type StealthClient,
21
+ TransportError,
22
+ ValidationError,
17
23
  } from "../src";
24
+ import { createMemoryProviderRuntimeState } from "../src/runtime/state";
18
25
 
19
26
  type CliArgs = {
20
27
  append: boolean;
@@ -28,55 +35,77 @@ type ProviderRuntime = ProviderDefinition;
28
35
 
29
36
  type MutableRecord = Record<string, unknown>;
30
37
 
31
- export async function main() {
32
- const args = parseArgs(normalizeArgs(process.argv.slice(2)));
33
- const location = resolveProviderLocation(args.providerPath);
34
- const provider = await loadProvider(location.rootDir);
35
- const operationName = resolveOperationName(provider, args.operation);
36
- const operation = provider.operations[operationName];
37
- const parsedParams = parseParams(operation, args.params);
38
-
39
- const capture = createCaptureContext(
40
- resolveOperationBaseUrl(provider, operationName),
41
- );
38
+ const HELP_TEXT = `Usage: apifuse record [path] --operation <operation> --params '<json>'
42
39
 
43
- console.log(`[apifuse record] Calling ${operationName} on ${provider.id}...`);
40
+ Calls a real upstream-backed operation through ctx.http or ctx.stealth and writes __fixtures__/raw.json.
44
41
 
45
- const result = await executeOperation(
46
- provider,
47
- operationName,
48
- capture.ctx,
49
- parsedParams,
50
- );
51
- const captured = capture.getCapturedRaw();
42
+ Options:
43
+ --operation, -o <name> operation to call
44
+ --params, -p <json> JSON input passed to the operation (default: {})
45
+ --append append to an existing array fixture
46
+ --sanitize redact common token/header fields (default)
47
+ --no-sanitize write the captured upstream payload as-is
48
+ --help, -h show this help
52
49
 
53
- if (captured === undefined) {
54
- throw new Error(
55
- `No upstream response was captured for ${provider.id}.${operationName}.`,
50
+ Example:
51
+ apifuse record providers/korea-air-quality --operation realtime --params '{"stationName":"jongno"}'`;
52
+
53
+ export async function main() {
54
+ try {
55
+ const args = parseArgs(normalizeArgs(process.argv.slice(2)));
56
+ const location = resolveProviderLocation(args.providerPath);
57
+ const provider = await loadProvider(location.rootDir);
58
+ const operationName = resolveOperationName(provider, args.operation);
59
+ const operation = provider.operations[operationName];
60
+ const parsedParams = parseParams(operation, args.params);
61
+
62
+ const capture = createCaptureContext(
63
+ provider,
64
+ resolveOperationBaseUrl(provider, operationName),
56
65
  );
57
- }
58
66
 
59
- const rawPayload = args.sanitize ? sanitizeFixture(captured) : captured;
60
- const fixturePath = resolve(location.rootDir, "__fixtures__", "raw.json");
61
- const nextPayload = await prepareFixturePayload(
62
- fixturePath,
63
- rawPayload,
64
- args.append,
65
- );
67
+ console.log(
68
+ `[apifuse record] Calling ${operationName} on ${provider.id}...`,
69
+ );
66
70
 
67
- await mkdir(dirname(fixturePath), { recursive: true });
68
- await writeFile(fixturePath, `${JSON.stringify(nextPayload, null, 2)}\n`);
71
+ const result = await executeOperation(
72
+ provider,
73
+ operationName,
74
+ capture.ctx,
75
+ parsedParams,
76
+ );
77
+ const captured = capture.getCapturedRaw();
69
78
 
70
- console.log(
71
- `[apifuse record] Captured response (${formatBytes(
72
- Buffer.byteLength(JSON.stringify(rawPayload)),
73
- )})`,
74
- );
75
- console.log(
76
- `[apifuse record] Saved to ${relative(process.cwd(), fixturePath)}`,
77
- );
79
+ if (captured === undefined) {
80
+ throw new Error(
81
+ `No upstream response was captured for ${provider.id}.${operationName}.`,
82
+ );
83
+ }
78
84
 
79
- void result;
85
+ const rawPayload = args.sanitize ? sanitizeFixture(captured) : captured;
86
+ const fixturePath = resolve(location.rootDir, "__fixtures__", "raw.json");
87
+ const nextPayload = await prepareFixturePayload(
88
+ fixturePath,
89
+ rawPayload,
90
+ args.append,
91
+ );
92
+
93
+ await mkdir(dirname(fixturePath), { recursive: true });
94
+ await writeFile(fixturePath, `${JSON.stringify(nextPayload, null, 2)}\n`);
95
+
96
+ console.log(
97
+ `[apifuse record] Captured response (${formatBytes(
98
+ Buffer.byteLength(JSON.stringify(rawPayload)),
99
+ )})`,
100
+ );
101
+ console.log(
102
+ `[apifuse record] Saved to ${relative(process.cwd(), fixturePath)}`,
103
+ );
104
+
105
+ void result;
106
+ } catch (error) {
107
+ handleCliError(error);
108
+ }
80
109
  }
81
110
 
82
111
  function normalizeArgs(argv: string[]): string[] {
@@ -104,6 +133,11 @@ function parseArgs(argv: string[]): CliArgs {
104
133
  continue;
105
134
  }
106
135
 
136
+ if (arg === "--help" || arg === "-h") {
137
+ console.log(HELP_TEXT);
138
+ process.exit(0);
139
+ }
140
+
107
141
  if (arg.startsWith("--operation=")) {
108
142
  operation = arg.slice("--operation=".length);
109
143
  continue;
@@ -155,6 +189,43 @@ function parseArgs(argv: string[]): CliArgs {
155
189
  return { append, providerPath, operation, params, sanitize };
156
190
  }
157
191
 
192
+ function handleCliError(error: unknown): never {
193
+ const message = formatCliError(error);
194
+ console.error(`[apifuse record] ${message}`);
195
+ process.exit(1);
196
+ }
197
+
198
+ function formatCliError(error: unknown): string {
199
+ if (error instanceof TransportError) {
200
+ return [
201
+ error.message,
202
+ error.upstreamStatus ? `status=${error.upstreamStatus}` : undefined,
203
+ error.options?.retryable !== undefined
204
+ ? `retryable=${String(error.options.retryable)}`
205
+ : undefined,
206
+ error.fix ? `fix=${error.fix}` : undefined,
207
+ ]
208
+ .filter(Boolean)
209
+ .join(" ");
210
+ }
211
+
212
+ if (error instanceof ProviderError || error instanceof ValidationError) {
213
+ return [
214
+ error.message,
215
+ error.code ? `code=${error.code}` : undefined,
216
+ error.fix,
217
+ ]
218
+ .filter(Boolean)
219
+ .join(" ");
220
+ }
221
+
222
+ if (error instanceof Error) {
223
+ return error.message;
224
+ }
225
+
226
+ return String(error);
227
+ }
228
+
158
229
  function resolveProviderLocation(inputPath?: string) {
159
230
  const originalInput = inputPath ?? process.cwd();
160
231
  const resolvedInput = resolve(process.cwd(), originalInput);
@@ -269,34 +340,53 @@ function resolveOperationBaseUrl(
269
340
  return baseUrl;
270
341
  }
271
342
 
272
- function createCaptureContext(baseUrl: string) {
343
+ function createCaptureContext(provider: ProviderRuntime, baseUrl: string) {
273
344
  let capturedRaw: unknown;
274
345
 
275
346
  const http = proxyHttpClient(createHttpClient(baseUrl), (response) => {
276
347
  capturedRaw = response.data;
277
348
  });
278
- const tls = proxyTlsClient(createTlsClient(baseUrl), (response) => {
279
- capturedRaw = normalizeCapturedTlsResponse(response);
280
- });
349
+ const stealth = proxyStealthClient(
350
+ createStealthClient(baseUrl),
351
+ (response) => {
352
+ capturedRaw = normalizeCapturedStealthResponse(response);
353
+ },
354
+ );
281
355
 
356
+ const env = {
357
+ get: (key: string) => process.env[key],
358
+ };
359
+ const credential = {
360
+ mode: "none" as const,
361
+ get: () => undefined,
362
+ getAll: () => ({}),
363
+ getAccessToken: () => undefined,
364
+ getScopes: () => [],
365
+ };
366
+ const state = createMemoryProviderRuntimeState();
282
367
  const ctx: ProviderContext = {
283
- env: {
284
- get: (key) => process.env[key],
285
- },
286
- credential: {
287
- mode: "none",
288
- get: () => undefined,
289
- getAll: () => ({}),
290
- getAccessToken: () => undefined,
291
- getScopes: () => [],
292
- },
368
+ env,
369
+ credential,
370
+ request: { headers: {} },
293
371
  http,
294
- tls,
372
+ cache: createBypassProviderCache({ providerId: provider.id }),
373
+ state,
374
+ stealth,
295
375
  browser: {
296
376
  engine: "playwright-stealth",
377
+ close: async () => {},
297
378
  newPage: async () => {
298
379
  throw new Error("Browser client is not available in apifuse record.");
299
380
  },
381
+ rawPage: async () => {
382
+ throw new Error("Browser client is not available in apifuse record.");
383
+ },
384
+ withIsolatedContext: async () => {
385
+ throw new Error("Browser client is not available in apifuse record.");
386
+ },
387
+ solveChallenge: async () => {
388
+ throw new Error("Browser client is not available in apifuse record.");
389
+ },
300
390
  },
301
391
  trace: {
302
392
  span: async (_name, fn) => fn(),
@@ -306,6 +396,14 @@ function createCaptureContext(baseUrl: string) {
306
396
  throw new Error("Auth prompts are not available in apifuse record.");
307
397
  },
308
398
  },
399
+ stt: createSttClientFromEnv(provider.stt),
400
+ choice: createProviderChoiceContext({
401
+ providerId: provider.id,
402
+ env,
403
+ request: { headers: {} },
404
+ credential,
405
+ state,
406
+ }),
309
407
  };
310
408
 
311
409
  return {
@@ -335,59 +433,39 @@ function proxyHttpClient(
335
433
  }) as HttpClient;
336
434
  }
337
435
 
338
- function proxyTlsClient(
339
- client: TlsClient,
340
- onResponse: (response: Awaited<ReturnType<TlsClient["fetch"]>>) => void,
341
- ): TlsClient {
342
- return new Proxy(client, {
343
- get(target, prop, receiver) {
344
- const value = Reflect.get(target, prop, receiver);
345
-
346
- if (prop === "fetch" && typeof value === "function") {
347
- return async (...args: unknown[]) => {
348
- const response = await value.apply(target, args);
349
- onResponse(response);
350
- return response;
351
- };
352
- }
436
+ type StealthSession = ReturnType<StealthClient["createSession"]>;
353
437
 
354
- if (prop === "createSession" && typeof value === "function") {
355
- return (...args: unknown[]) => {
356
- const session = value.apply(target, args) as ReturnType<
357
- TlsClient["createSession"]
358
- >;
359
- return proxyTlsSession(session, onResponse);
360
- };
361
- }
362
-
363
- return value;
438
+ function proxyStealthClient(
439
+ client: StealthClient,
440
+ onResponse: (response: Awaited<ReturnType<StealthClient["fetch"]>>) => void,
441
+ ): StealthClient {
442
+ return {
443
+ fetch: async (...args: Parameters<StealthClient["fetch"]>) => {
444
+ const response = await client.fetch(...args);
445
+ onResponse(response);
446
+ return response;
364
447
  },
365
- }) as TlsClient;
448
+ createSession: (...args: Parameters<StealthClient["createSession"]>) =>
449
+ proxyStealthSession(client.createSession(...args), onResponse),
450
+ };
366
451
  }
367
452
 
368
- function proxyTlsSession(
369
- session: ReturnType<TlsClient["createSession"]>,
370
- onResponse: (response: Awaited<ReturnType<TlsClient["fetch"]>>) => void,
371
- ) {
372
- return new Proxy(session, {
373
- get(target, prop, receiver) {
374
- const value = Reflect.get(target, prop, receiver);
375
-
376
- if (prop === "fetch" && typeof value === "function") {
377
- return async (...args: unknown[]) => {
378
- const response = await value.apply(target, args);
379
- onResponse(response);
380
- return response;
381
- };
382
- }
383
-
384
- return value;
453
+ function proxyStealthSession(
454
+ session: StealthSession,
455
+ onResponse: (response: Awaited<ReturnType<StealthClient["fetch"]>>) => void,
456
+ ): StealthSession {
457
+ return {
458
+ fetch: async (...args: Parameters<StealthSession["fetch"]>) => {
459
+ const response = await session.fetch(...args);
460
+ onResponse(response);
461
+ return response;
385
462
  },
386
- }) as ReturnType<TlsClient["createSession"]>;
463
+ close: () => session.close(),
464
+ };
387
465
  }
388
466
 
389
- function normalizeCapturedTlsResponse(
390
- response: Awaited<ReturnType<TlsClient["fetch"]>>,
467
+ function normalizeCapturedStealthResponse(
468
+ response: Awaited<ReturnType<StealthClient["fetch"]>>,
391
469
  ) {
392
470
  try {
393
471
  return JSON.parse(response.body);