@apifuse/provider-sdk 2.2.0-beta.3 → 2.2.0-beta.5

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 (165) hide show
  1. package/AUTHORING.md +53 -0
  2. package/CHANGELOG.md +8 -0
  3. package/bin/apifuse-check.ts +18 -58
  4. package/bin/apifuse-create.ts +1 -1
  5. package/bin/apifuse-dev.ts +27 -52
  6. package/bin/apifuse-pack-smoke.ts +22 -81
  7. package/bin/apifuse-pack-types.ts +266 -0
  8. package/bin/apifuse-perf.ts +45 -127
  9. package/bin/apifuse-record.ts +23 -61
  10. package/bin/apifuse-submit-check.ts +266 -34
  11. package/bin/apifuse.ts +1 -1
  12. package/bin/submit-check-xml.ts +1 -1
  13. package/dist/auth-turn/index.d.ts +1 -1
  14. package/dist/auth.d.ts +2 -2
  15. package/dist/auth.js +9 -18
  16. package/dist/ceremonies/index.d.ts +1 -1
  17. package/dist/ceremonies/index.js +8 -18
  18. package/dist/config/loader.d.ts +2 -2
  19. package/dist/config/loader.js +19 -42
  20. package/dist/contract-serialization.d.ts +2 -2
  21. package/dist/contract-serialization.js +3 -6
  22. package/dist/contract-types.d.ts +2 -2
  23. package/dist/contract.d.ts +3 -3
  24. package/dist/contract.js +4 -6
  25. package/dist/define.d.ts +8 -1
  26. package/dist/define.js +57 -115
  27. package/dist/dev.d.ts +1 -1
  28. package/dist/dev.js +1 -1
  29. package/dist/errors.d.ts +1 -1
  30. package/dist/errors.js +1 -3
  31. package/dist/i18n/catalog.d.ts +2 -2
  32. package/dist/i18n/catalog.js +4 -10
  33. package/dist/i18n/index.d.ts +2 -2
  34. package/dist/i18n/index.js +2 -2
  35. package/dist/i18n/keys.d.ts +2 -2
  36. package/dist/index.d.ts +43 -42
  37. package/dist/index.js +38 -37
  38. package/dist/lint.js +8 -15
  39. package/dist/provider.d.ts +11 -11
  40. package/dist/provider.js +9 -9
  41. package/dist/public-schema-field-lint.d.ts +1 -1
  42. package/dist/recipes/gov-api.js +1 -1
  43. package/dist/runtime/auth-flow.d.ts +1 -1
  44. package/dist/runtime/auth-flow.js +3 -3
  45. package/dist/runtime/browser.d.ts +1 -1
  46. package/dist/runtime/browser.js +15 -29
  47. package/dist/runtime/cache.d.ts +1 -1
  48. package/dist/runtime/cache.js +4 -8
  49. package/dist/runtime/choice.d.ts +1 -1
  50. package/dist/runtime/choice.js +12 -34
  51. package/dist/runtime/credential.d.ts +1 -1
  52. package/dist/runtime/credential.js +1 -1
  53. package/dist/runtime/env.d.ts +1 -1
  54. package/dist/runtime/executor.d.ts +1 -1
  55. package/dist/runtime/executor.js +2 -2
  56. package/dist/runtime/http.d.ts +2 -2
  57. package/dist/runtime/http.js +5 -5
  58. package/dist/runtime/insights.d.ts +1 -1
  59. package/dist/runtime/insights.js +6 -13
  60. package/dist/runtime/instrumentation.d.ts +2 -2
  61. package/dist/runtime/instrumentation.js +5 -15
  62. package/dist/runtime/keyring.js +1 -1
  63. package/dist/runtime/namespace.js +1 -1
  64. package/dist/runtime/otlp.d.ts +1 -1
  65. package/dist/runtime/perf.d.ts +1 -1
  66. package/dist/runtime/provider.d.ts +1 -1
  67. package/dist/runtime/provider.js +1 -2
  68. package/dist/runtime/proxy-errors.d.ts +1 -1
  69. package/dist/runtime/proxy-errors.js +3 -5
  70. package/dist/runtime/proxy-retry-policy.d.ts +2 -2
  71. package/dist/runtime/proxy-retry-policy.js +2 -2
  72. package/dist/runtime/proxy-telemetry.d.ts +1 -1
  73. package/dist/runtime/proxy-telemetry.js +16 -48
  74. package/dist/runtime/redis.d.ts +1 -1
  75. package/dist/runtime/redis.js +2 -4
  76. package/dist/runtime/request-options.d.ts +1 -1
  77. package/dist/runtime/state.d.ts +2 -2
  78. package/dist/runtime/state.js +3 -3
  79. package/dist/runtime/stealth.d.ts +2 -2
  80. package/dist/runtime/stealth.js +6 -6
  81. package/dist/runtime/stt.d.ts +1 -1
  82. package/dist/runtime/stt.js +11 -15
  83. package/dist/runtime/trace.d.ts +2 -2
  84. package/dist/runtime/trace.js +2 -4
  85. package/dist/runtime/waterfall.d.ts +1 -1
  86. package/dist/schema.d.ts +1 -1
  87. package/dist/schema.js +7 -15
  88. package/dist/serve.d.ts +1 -1
  89. package/dist/serve.js +1 -1
  90. package/dist/server/index.d.ts +7 -7
  91. package/dist/server/index.js +6 -6
  92. package/dist/server/self-test-redaction.d.ts +1 -1
  93. package/dist/server/self-test-redaction.js +1 -1
  94. package/dist/server/self-test.d.ts +104 -3
  95. package/dist/server/self-test.js +673 -115
  96. package/dist/server/serve.d.ts +3 -3
  97. package/dist/server/serve.js +37 -49
  98. package/dist/server/types.js +2 -7
  99. package/dist/stealth/profiles.d.ts +1 -1
  100. package/dist/stealth/profiles.js +5 -14
  101. package/dist/stream.d.ts +1 -1
  102. package/dist/testing/index.d.ts +2 -2
  103. package/dist/testing/index.js +2 -2
  104. package/dist/testing/run.d.ts +1 -1
  105. package/dist/testing/run.js +7 -14
  106. package/dist/types.d.ts +57 -0
  107. package/dist/user-input.d.ts +30 -0
  108. package/dist/user-input.js +66 -0
  109. package/package.json +6 -4
  110. package/src/auth-turn/index.ts +1 -1
  111. package/src/auth.ts +28 -86
  112. package/src/ceremonies/index.ts +24 -78
  113. package/src/config/loader.ts +58 -176
  114. package/src/contract-serialization.ts +5 -11
  115. package/src/contract-types.ts +2 -2
  116. package/src/contract.ts +12 -28
  117. package/src/define.ts +174 -495
  118. package/src/dev.ts +4 -9
  119. package/src/errors.ts +4 -11
  120. package/src/i18n/catalog.ts +10 -32
  121. package/src/i18n/index.ts +2 -2
  122. package/src/i18n/keys.ts +5 -11
  123. package/src/index.ts +44 -42
  124. package/src/lint.ts +89 -159
  125. package/src/provider.ts +12 -11
  126. package/src/public-schema-field-lint.ts +7 -33
  127. package/src/recipes/gov-api.ts +2 -5
  128. package/src/runtime/auth-flow.ts +5 -7
  129. package/src/runtime/browser.ts +64 -187
  130. package/src/runtime/cache.ts +20 -67
  131. package/src/runtime/choice.ts +55 -129
  132. package/src/runtime/credential.ts +2 -2
  133. package/src/runtime/env.ts +1 -1
  134. package/src/runtime/executor.ts +9 -19
  135. package/src/runtime/http.ts +7 -7
  136. package/src/runtime/insights.ts +15 -53
  137. package/src/runtime/instrumentation.ts +19 -58
  138. package/src/runtime/keyring.ts +7 -19
  139. package/src/runtime/namespace.ts +2 -7
  140. package/src/runtime/otlp.ts +12 -23
  141. package/src/runtime/perf.ts +1 -1
  142. package/src/runtime/provider.ts +4 -9
  143. package/src/runtime/proxy-errors.ts +17 -38
  144. package/src/runtime/proxy-retry-policy.ts +3 -3
  145. package/src/runtime/proxy-telemetry.ts +23 -72
  146. package/src/runtime/redis.ts +4 -12
  147. package/src/runtime/request-options.ts +4 -13
  148. package/src/runtime/state.ts +30 -109
  149. package/src/runtime/stealth.ts +8 -8
  150. package/src/runtime/stt.ts +38 -94
  151. package/src/runtime/trace.ts +14 -44
  152. package/src/runtime/waterfall.ts +5 -18
  153. package/src/schema.ts +23 -84
  154. package/src/serve.ts +1 -1
  155. package/src/server/index.ts +12 -7
  156. package/src/server/self-test-redaction.ts +2 -2
  157. package/src/server/self-test.ts +857 -132
  158. package/src/server/serve.ts +89 -238
  159. package/src/server/types.ts +6 -19
  160. package/src/stealth/profiles.ts +10 -26
  161. package/src/stream.ts +8 -19
  162. package/src/testing/index.ts +2 -2
  163. package/src/testing/run.ts +19 -67
  164. package/src/types.ts +58 -0
  165. package/src/user-input.ts +118 -0
@@ -3,63 +3,60 @@ 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
+ import { AuthAbortError, createAuthFlowHelpers } from "../auth.js";
7
7
  import {
8
8
  AuthError,
9
9
  isProviderError,
10
10
  isSessionExpiredError,
11
11
  isTransportError,
12
12
  ProviderError,
13
- } from "../errors";
13
+ } from "../errors.js";
14
14
  import {
15
15
  loadProviderLocaleCatalogs,
16
16
  localizeAuthTurn,
17
17
  type ProviderLocaleCatalogMap,
18
- } from "../i18n/catalog";
19
- import type { ProviderLocale } from "../i18n/keys";
18
+ } from "../i18n/catalog.js";
19
+ import type { ProviderLocale } from "../i18n/keys.js";
20
20
  import {
21
21
  categoryForStatus,
22
22
  isRetryableCategory,
23
23
  PROVIDER_OBSERVABILITY_TAXONOMY_VERSION,
24
24
  type ProviderErrorCategory,
25
- } from "../observability";
26
- import { createScratchpad } from "../runtime/auth-flow";
27
- import { createBrowserClient } from "../runtime/browser";
28
- import { createProviderCache } from "../runtime/cache";
25
+ } from "../observability.js";
26
+ import { createScratchpad } from "../runtime/auth-flow.js";
27
+ import { createBrowserClient } from "../runtime/browser.js";
28
+ import { createProviderCache } from "../runtime/cache.js";
29
29
  import {
30
30
  createProviderChoiceContext,
31
31
  PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
32
- } from "../runtime/choice";
33
- import { createCredentialContext } from "../runtime/credential";
34
- import { createEnvContext } from "../runtime/env";
35
- import { executeOperation } from "../runtime/executor";
36
- import { createHttpClient } from "../runtime/http";
37
- import { wrapWithInstrumentation } from "../runtime/instrumentation";
38
- import { getProviderBaseUrl } from "../runtime/provider";
32
+ } from "../runtime/choice.js";
33
+ import { createCredentialContext } from "../runtime/credential.js";
34
+ import { createEnvContext } from "../runtime/env.js";
35
+ import { executeOperation } from "../runtime/executor.js";
36
+ import { createHttpClient } from "../runtime/http.js";
37
+ import { wrapWithInstrumentation } from "../runtime/instrumentation.js";
38
+ import { getProviderBaseUrl } from "../runtime/provider.js";
39
39
  import {
40
40
  PROXY_AUTH_IP_DENIED_CODE,
41
41
  PROXY_EDGE_AUTH_REJECTED_CODE,
42
42
  PROXY_POOL_EXHAUSTED_CODE,
43
- } from "../runtime/proxy-errors";
44
- import {
45
- PROVIDER_TELEMETRY_HEADER,
46
- ProxyTelemetryCollector,
47
- } from "../runtime/proxy-telemetry";
43
+ } from "../runtime/proxy-errors.js";
44
+ import { PROVIDER_TELEMETRY_HEADER, ProxyTelemetryCollector } from "../runtime/proxy-telemetry.js";
48
45
  import {
49
46
  createProviderRuntimeStateFromEnv,
50
47
  createUnsupportedProviderRuntimeState,
51
- } from "../runtime/state";
52
- import { createStealthClient } from "../runtime/stealth";
53
- import { createSttClientFromEnv } from "../runtime/stt";
54
- import { createTraceContext } from "../runtime/trace";
55
- import { parseSchema } from "../schema";
56
- import { getStealthProfile } from "../stealth/profiles";
48
+ } from "../runtime/state.js";
49
+ import { createStealthClient } from "../runtime/stealth.js";
50
+ import { createSttClientFromEnv } from "../runtime/stt.js";
51
+ import { createTraceContext } from "../runtime/trace.js";
52
+ import { parseSchema } from "../schema.js";
53
+ import { getStealthProfile } from "../stealth/profiles.js";
57
54
  import {
58
55
  APIFUSE_STREAM_DONE_EVENT,
59
56
  APIFUSE_STREAM_ERROR_EVENT,
60
57
  encodeSseEvent,
61
58
  error as streamError,
62
- } from "../stream";
59
+ } from "../stream.js";
63
60
  import type {
64
61
  AuthContext,
65
62
  AuthTurn,
@@ -76,13 +73,14 @@ import type {
76
73
  ProviderStreamEvent,
77
74
  StealthClient,
78
75
  SttContext,
79
- } from "../types";
76
+ } from "../types.js";
80
77
  import {
81
78
  createSelfTestApp,
79
+ createSelfTestAuthFlowInvoke,
82
80
  createSelfTestInvoke,
83
81
  resolveSelfTestPort,
84
- } from "./self-test";
85
- import { resolveSelfTestMasterSecrets } from "./self-test-token";
82
+ } from "./self-test.js";
83
+ import { resolveSelfTestMasterSecrets } from "./self-test-token.js";
86
84
  import {
87
85
  type AuthFlowRequest,
88
86
  AuthFlowRequestSchema,
@@ -93,7 +91,7 @@ import {
93
91
  OperationRequestSchema,
94
92
  type OperationResponse,
95
93
  type OperationSuccessResponse,
96
- } from "./types";
94
+ } from "./types.js";
97
95
 
98
96
  const DEFAULT_HOST = "0.0.0.0";
99
97
  const DEFAULT_PORT = 3000;
@@ -157,9 +155,7 @@ function createStealthStub(): StealthClient {
157
155
  };
158
156
  }
159
157
 
160
- function getProviderStealthBaseUrl(
161
- provider: ProviderDefinition,
162
- ): string | undefined {
158
+ function getProviderStealthBaseUrl(provider: ProviderDefinition): string | undefined {
163
159
  const baseUrl = getProviderBaseUrl(provider);
164
160
  if (baseUrl) {
165
161
  return baseUrl;
@@ -169,15 +165,10 @@ function getProviderStealthBaseUrl(
169
165
  }
170
166
 
171
167
  function getProviderStealthProfile(provider: ProviderDefinition) {
172
- return provider.stealth?.profile
173
- ? getStealthProfile(provider.stealth.profile)
174
- : undefined;
168
+ return provider.stealth?.profile ? getStealthProfile(provider.stealth.profile) : undefined;
175
169
  }
176
170
 
177
- function isProductionProviderBrowserMode(
178
- provider: ProviderDefinition,
179
- env = process.env,
180
- ): boolean {
171
+ function isProductionProviderBrowserMode(provider: ProviderDefinition, env = process.env): boolean {
181
172
  if (provider.runtime !== "browser") {
182
173
  return false;
183
174
  }
@@ -186,9 +177,7 @@ function isProductionProviderBrowserMode(
186
177
  return true;
187
178
  }
188
179
 
189
- return (
190
- env.NODE_ENV === "production" && env.APIFUSE__PROVIDER__ID === provider.id
191
- );
180
+ return env.NODE_ENV === "production" && env.APIFUSE__PROVIDER__ID === provider.id;
192
181
  }
193
182
 
194
183
  export function resolveProviderProxyAffinityKey(
@@ -196,21 +185,16 @@ export function resolveProviderProxyAffinityKey(
196
185
  request: OperationRequest,
197
186
  operationId: string,
198
187
  ): string {
199
- const connectionKey =
200
- resolveOperationConnectionId(request) ?? request.connection?.externalRef;
188
+ const connectionKey = resolveOperationConnectionId(request) ?? request.connection?.externalRef;
201
189
  const affinity =
202
- typeof provider.proxy === "object"
203
- ? provider.proxy.session?.affinity
204
- : undefined;
190
+ typeof provider.proxy === "object" ? provider.proxy.session?.affinity : undefined;
205
191
  if (affinity === "operation") {
206
192
  return `${provider.id}/${operationId}`;
207
193
  }
208
194
  return connectionKey ?? provider.id;
209
195
  }
210
196
 
211
- function resolveOperationConnectionId(
212
- request: OperationRequest,
213
- ): string | undefined {
197
+ function resolveOperationConnectionId(request: OperationRequest): string | undefined {
214
198
  return request.connection?.id ?? request.connectionId;
215
199
  }
216
200
 
@@ -227,11 +211,7 @@ function createProviderContext(
227
211
  const stealthProfile = getProviderStealthProfile(provider);
228
212
  const proxyClientOptions = {
229
213
  upstream: { proxy: provider.proxy },
230
- affinityKey: resolveProviderProxyAffinityKey(
231
- provider,
232
- request,
233
- operationId,
234
- ),
214
+ affinityKey: resolveProviderProxyAffinityKey(provider, request, operationId),
235
215
  telemetry: proxyTelemetry,
236
216
  };
237
217
  let wrappedContext: ProviderContext | undefined;
@@ -270,11 +250,7 @@ function createProviderContext(
270
250
  state,
271
251
  stealth: stealthBaseUrl
272
252
  ? stealthProfile
273
- ? createStealthClient(
274
- stealthBaseUrl,
275
- stealthProfile.name,
276
- stealthClientOptions,
277
- )
253
+ ? createStealthClient(stealthBaseUrl, stealthProfile.name, stealthClientOptions)
278
254
  : createStealthClient(stealthBaseUrl, stealthClientOptions)
279
255
  : createStealthStub(),
280
256
  browser:
@@ -387,11 +363,7 @@ function createAuthFlowContext(
387
363
  http: createHttpClient(baseUrl, proxyClientOptions),
388
364
  stealth: stealthBaseUrl
389
365
  ? stealthProfile
390
- ? createStealthClient(
391
- stealthBaseUrl,
392
- stealthProfile.name,
393
- stealthClientOptions,
394
- )
366
+ ? createStealthClient(stealthBaseUrl, stealthProfile.name, stealthClientOptions)
395
367
  : createStealthClient(stealthBaseUrl, stealthClientOptions)
396
368
  : createStealthStub(),
397
369
  env: createEnvContext(provider.secrets?.map((secret) => secret.name)),
@@ -504,10 +476,7 @@ function zodDetails(error: z.ZodError): Array<{
504
476
  }));
505
477
  }
506
478
 
507
- function toErrorResponse(
508
- error: unknown,
509
- requestId?: string,
510
- ): OperationErrorResponse {
479
+ function toErrorResponse(error: unknown, requestId?: string): OperationErrorResponse {
511
480
  if (isProviderError(error)) {
512
481
  const details = publicProviderErrorDetails(error);
513
482
  return {
@@ -645,9 +614,7 @@ function publicProviderErrorMessage(error: ProviderError): string {
645
614
  return error.message;
646
615
  }
647
616
 
648
- function toStatusCode(
649
- error: unknown,
650
- ): 400 | 401 | 404 | 429 | 500 | 502 | 503 | 504 {
617
+ function toStatusCode(error: unknown): 400 | 401 | 404 | 429 | 500 | 502 | 503 | 504 {
651
618
  if (error instanceof z.ZodError) {
652
619
  return 400;
653
620
  }
@@ -702,20 +669,15 @@ function logProviderError(
702
669
  status: number,
703
670
  cost: ProviderRequestCost,
704
671
  ): void {
705
- const code =
706
- isProviderError(error)
707
- ? (error.code ?? "provider_error")
708
- : error instanceof z.ZodError
709
- ? "invalid_request"
710
- : "internal_error";
672
+ const code = isProviderError(error)
673
+ ? (error.code ?? "provider_error")
674
+ : error instanceof z.ZodError
675
+ ? "invalid_request"
676
+ : "internal_error";
711
677
  const errorClass = error instanceof Error ? error.name : typeof error;
712
678
  const message = error instanceof Error ? error.message : String(error);
713
- const details =
714
- isProviderError(error)
715
- ? providerObservabilityDetails(error)
716
- : undefined;
717
- const emit =
718
- typeof logger === "function" ? logger : defaultProviderServerLogger;
679
+ const details = isProviderError(error) ? providerObservabilityDetails(error) : undefined;
680
+ const emit = typeof logger === "function" ? logger : defaultProviderServerLogger;
719
681
  emit({
720
682
  level: status >= 500 ? "error" : "warn",
721
683
  event: "provider_request_failed",
@@ -750,8 +712,7 @@ function logProviderCleanupError(
750
712
  resource: "browser" | "stealth",
751
713
  error: unknown,
752
714
  ): void {
753
- const emit =
754
- typeof logger === "function" ? logger : defaultProviderServerLogger;
715
+ const emit = typeof logger === "function" ? logger : defaultProviderServerLogger;
755
716
  const errorClass = error instanceof Error ? error.name : typeof error;
756
717
  const message = error instanceof Error ? error.message : String(error);
757
718
  emit({
@@ -776,8 +737,7 @@ function logProviderSuccess(
776
737
  status: number,
777
738
  cost: ProviderRequestCost,
778
739
  ): void {
779
- const emit =
780
- typeof logger === "function" ? logger : defaultProviderServerLogger;
740
+ const emit = typeof logger === "function" ? logger : defaultProviderServerLogger;
781
741
  emit({
782
742
  level: "info",
783
743
  event: "provider_request_completed",
@@ -823,18 +783,13 @@ function toJsonSuccessResponse(
823
783
  };
824
784
  }
825
785
 
826
- function isAsyncIterable<T = unknown>(
827
- value: unknown,
828
- ): value is AsyncIterable<T> {
786
+ function isAsyncIterable<T = unknown>(value: unknown): value is AsyncIterable<T> {
829
787
  if (!value || typeof value !== "object") return false;
830
788
  const iterator = Reflect.get(value, Symbol.asyncIterator);
831
789
  return typeof iterator === "function";
832
790
  }
833
791
 
834
- function responseWithCleanup(
835
- response: Response,
836
- cleanup: RequestCleanup,
837
- ): Response {
792
+ function responseWithCleanup(response: Response, cleanup: RequestCleanup): Response {
838
793
  if (!response.body) {
839
794
  void cleanup();
840
795
  return response;
@@ -883,10 +838,7 @@ async function validateSseEvent(
883
838
  const transport = getSseTransport(operation);
884
839
  const schema = transport?.events?.[event.event];
885
840
  if (!schema) {
886
- if (
887
- event.event === APIFUSE_STREAM_ERROR_EVENT ||
888
- event.event === APIFUSE_STREAM_DONE_EVENT
889
- ) {
841
+ if (event.event === APIFUSE_STREAM_ERROR_EVENT || event.event === APIFUSE_STREAM_DONE_EVENT) {
890
842
  return event;
891
843
  }
892
844
  throw new ProviderError(
@@ -899,11 +851,7 @@ async function validateSseEvent(
899
851
  },
900
852
  );
901
853
  }
902
- const data = await parseSchema(
903
- schema,
904
- event.data,
905
- `transport.events.${event.event}`,
906
- );
854
+ const data = await parseSchema(schema, event.data, `transport.events.${event.event}`);
907
855
  return { ...event, data };
908
856
  }
909
857
 
@@ -923,8 +871,7 @@ function assertStreamPayloadWithinLimit(
923
871
  throw new ProviderError(
924
872
  `Stream ${kind} exceeded declared byte limit (${actualBytes} > ${maxBytes}).`,
925
873
  {
926
- code:
927
- kind === "event" ? "STREAM_EVENT_TOO_LARGE" : "STREAM_CHUNK_TOO_LARGE",
874
+ code: kind === "event" ? "STREAM_EVENT_TOO_LARGE" : "STREAM_CHUNK_TOO_LARGE",
928
875
  retryable: false,
929
876
  category: "input_validation",
930
877
  fix:
@@ -969,15 +916,10 @@ function toSseResponse(
969
916
  const validated = await validateSseEvent(operation, next.value);
970
917
  const encodedEvent = encodeSseEvent(validated);
971
918
  const encodedBytes = encoder.encode(encodedEvent);
972
- assertStreamPayloadWithinLimit(
973
- encodedBytes.byteLength,
974
- transport?.maxEventBytes,
975
- "event",
976
- );
919
+ assertStreamPayloadWithinLimit(encodedBytes.byteLength, transport?.maxEventBytes, "event");
977
920
  controller.enqueue(encodedBytes);
978
921
  } catch (error) {
979
- const message =
980
- error instanceof Error ? error.message : "Stream failed";
922
+ const message = error instanceof Error ? error.message : "Stream failed";
981
923
  controller.enqueue(
982
924
  encoder.encode(
983
925
  encodeSseEvent(
@@ -1024,11 +966,7 @@ function enforceStreamChunkLimit(
1024
966
  return;
1025
967
  }
1026
968
  if (value) {
1027
- assertStreamPayloadWithinLimit(
1028
- byteLength(value),
1029
- maxChunkBytes,
1030
- "chunk",
1031
- );
969
+ assertStreamPayloadWithinLimit(byteLength(value), maxChunkBytes, "chunk");
1032
970
  controller.enqueue(value);
1033
971
  }
1034
972
  } catch (error) {
@@ -1048,10 +986,7 @@ function toStreamingResponse(
1048
986
  requestId?: string,
1049
987
  ): Response {
1050
988
  const transport = operation.transport?.kind ?? "json";
1051
- if (
1052
- transport === "sse" &&
1053
- (result instanceof Response || result instanceof ReadableStream)
1054
- ) {
989
+ if (transport === "sse" && (result instanceof Response || result instanceof ReadableStream)) {
1055
990
  void cleanup();
1056
991
  throw new ProviderError(
1057
992
  "SSE operations must return an AsyncIterable of typed stream.event(...) values.",
@@ -1065,20 +1000,13 @@ function toStreamingResponse(
1065
1000
  }
1066
1001
  if (result instanceof Response) {
1067
1002
  const httpTransport = getHttpStreamTransport(operation);
1068
- if (
1069
- httpTransport &&
1070
- result.body &&
1071
- httpTransport?.maxChunkBytes !== undefined
1072
- ) {
1003
+ if (httpTransport && result.body && httpTransport?.maxChunkBytes !== undefined) {
1073
1004
  return responseWithCleanup(
1074
- new Response(
1075
- enforceStreamChunkLimit(result.body, httpTransport.maxChunkBytes),
1076
- {
1077
- headers: result.headers,
1078
- status: result.status,
1079
- statusText: result.statusText,
1080
- },
1081
- ),
1005
+ new Response(enforceStreamChunkLimit(result.body, httpTransport.maxChunkBytes), {
1006
+ headers: result.headers,
1007
+ status: result.status,
1008
+ statusText: result.statusText,
1009
+ }),
1082
1010
  cleanup,
1083
1011
  );
1084
1012
  }
@@ -1098,8 +1026,7 @@ function toStreamingResponse(
1098
1026
  : {
1099
1027
  "Content-Type":
1100
1028
  operation.transport?.kind === "http-stream"
1101
- ? (operation.transport.contentType ??
1102
- "application/octet-stream")
1029
+ ? (operation.transport.contentType ?? "application/octet-stream")
1103
1030
  : "application/octet-stream",
1104
1031
  },
1105
1032
  }),
@@ -1119,18 +1046,14 @@ function toStreamingResponse(
1119
1046
  );
1120
1047
  }
1121
1048
 
1122
- function getSseTransport(
1123
- operation: OperationDefinition,
1124
- ): OperationSseTransport | undefined {
1049
+ function getSseTransport(operation: OperationDefinition): OperationSseTransport | undefined {
1125
1050
  return operation.transport?.kind === "sse" ? operation.transport : undefined;
1126
1051
  }
1127
1052
 
1128
1053
  function getHttpStreamTransport(
1129
1054
  operation: OperationDefinition,
1130
1055
  ): OperationHttpStreamTransport | undefined {
1131
- return operation.transport?.kind === "http-stream"
1132
- ? operation.transport
1133
- : undefined;
1056
+ return operation.transport?.kind === "http-stream" ? operation.transport : undefined;
1134
1057
  }
1135
1058
 
1136
1059
  function toAuthFlowResponse(
@@ -1151,9 +1074,7 @@ function toAuthFlowResponse(
1151
1074
  };
1152
1075
  }
1153
1076
 
1154
- function authFlowLocaleFromHeaders(
1155
- headers?: Record<string, string>,
1156
- ): ProviderLocale {
1077
+ function authFlowLocaleFromHeaders(headers?: Record<string, string>): ProviderLocale {
1157
1078
  const header = Object.entries(headers ?? {}).find(
1158
1079
  ([key]) => key.toLowerCase() === "accept-language",
1159
1080
  )?.[1];
@@ -1171,9 +1092,7 @@ function isAuthFlowLocale(value: string | undefined): value is ProviderLocale {
1171
1092
  }
1172
1093
 
1173
1094
  function isAuthTurn(value: unknown): value is AuthTurn {
1174
- return (
1175
- !!value && typeof value === "object" && "kind" in value && "turnId" in value
1176
- );
1095
+ return !!value && typeof value === "object" && "kind" in value && "turnId" in value;
1177
1096
  }
1178
1097
 
1179
1098
  function loadAuthFlowLocaleCatalogs(
@@ -1210,10 +1129,7 @@ function materializeAuthFlowTurn(
1210
1129
  });
1211
1130
  }
1212
1131
 
1213
- function withAuthRequestHeaders(
1214
- request: AuthFlowRequest,
1215
- headers: Headers,
1216
- ): AuthFlowRequest {
1132
+ function withAuthRequestHeaders(request: AuthFlowRequest, headers: Headers): AuthFlowRequest {
1217
1133
  return {
1218
1134
  ...request,
1219
1135
  headers: {
@@ -1231,17 +1147,9 @@ async function handleOperation(
1231
1147
  state: ProviderRuntimeState = createUnsupportedProviderRuntimeState(),
1232
1148
  proxyTelemetry?: ProxyTelemetryCollector,
1233
1149
  ): Promise<Response | OperationResponse> {
1234
- const ctx = createProviderContext(
1235
- provider,
1236
- request,
1237
- operationId,
1238
- options,
1239
- state,
1240
- proxyTelemetry,
1241
- );
1150
+ const ctx = createProviderContext(provider, request, operationId, options, state, proxyTelemetry);
1242
1151
  const operation = provider.operations[operationId];
1243
- const streaming =
1244
- operation?.transport?.kind && operation.transport.kind !== "json";
1152
+ const streaming = operation?.transport?.kind && operation.transport.kind !== "json";
1245
1153
  let cleanupCalled = false;
1246
1154
  const cleanup = async () => {
1247
1155
  if (cleanupCalled) return;
@@ -1272,12 +1180,7 @@ async function handleOperation(
1272
1180
  }
1273
1181
  };
1274
1182
  try {
1275
- const result = await executeOperation(
1276
- provider,
1277
- operationId,
1278
- ctx,
1279
- request.input,
1280
- );
1183
+ const result = await executeOperation(provider, operationId, ctx, request.input);
1281
1184
  if (streaming && operation) {
1282
1185
  return toStreamingResponse(operation, result, cleanup, request.requestId);
1283
1186
  }
@@ -1321,12 +1224,7 @@ async function handleAuthFlow(
1321
1224
  });
1322
1225
  }
1323
1226
 
1324
- const { context, getPatch } = createAuthFlowContext(
1325
- provider,
1326
- request,
1327
- options,
1328
- signal,
1329
- );
1227
+ const { context, getPatch } = createAuthFlowContext(provider, request, options, signal);
1330
1228
  try {
1331
1229
  const result =
1332
1230
  route === "start"
@@ -1474,17 +1372,8 @@ export function createServerApp(
1474
1372
  .clone()
1475
1373
  .json()
1476
1374
  .catch(() => undefined);
1477
- const body = withAuthRequestHeaders(
1478
- AuthFlowRequestSchema.parse(rawBody),
1479
- c.req.raw.headers,
1480
- );
1481
- const response = await handleAuthFlow(
1482
- provider,
1483
- body,
1484
- "start",
1485
- options,
1486
- c.req.raw.signal,
1487
- );
1375
+ const body = withAuthRequestHeaders(AuthFlowRequestSchema.parse(rawBody), c.req.raw.headers);
1376
+ const response = await handleAuthFlow(provider, body, "start", options, c.req.raw.signal);
1488
1377
  logProviderSuccess(
1489
1378
  logger,
1490
1379
  provider,
@@ -1520,17 +1409,8 @@ export function createServerApp(
1520
1409
  .clone()
1521
1410
  .json()
1522
1411
  .catch(() => undefined);
1523
- const body = withAuthRequestHeaders(
1524
- AuthFlowRequestSchema.parse(rawBody),
1525
- c.req.raw.headers,
1526
- );
1527
- const response = await handleAuthFlow(
1528
- provider,
1529
- body,
1530
- "continue",
1531
- options,
1532
- c.req.raw.signal,
1533
- );
1412
+ const body = withAuthRequestHeaders(AuthFlowRequestSchema.parse(rawBody), c.req.raw.headers);
1413
+ const response = await handleAuthFlow(provider, body, "continue", options, c.req.raw.signal);
1534
1414
  logProviderSuccess(
1535
1415
  logger,
1536
1416
  provider,
@@ -1566,17 +1446,8 @@ export function createServerApp(
1566
1446
  .clone()
1567
1447
  .json()
1568
1448
  .catch(() => undefined);
1569
- const body = withAuthRequestHeaders(
1570
- AuthFlowRequestSchema.parse(rawBody),
1571
- c.req.raw.headers,
1572
- );
1573
- const response = await handleAuthFlow(
1574
- provider,
1575
- body,
1576
- "poll",
1577
- options,
1578
- c.req.raw.signal,
1579
- );
1449
+ const body = withAuthRequestHeaders(AuthFlowRequestSchema.parse(rawBody), c.req.raw.headers);
1450
+ const response = await handleAuthFlow(provider, body, "poll", options, c.req.raw.signal);
1580
1451
  logProviderSuccess(
1581
1452
  logger,
1582
1453
  provider,
@@ -1612,17 +1483,8 @@ export function createServerApp(
1612
1483
  .clone()
1613
1484
  .json()
1614
1485
  .catch(() => undefined);
1615
- const body = withAuthRequestHeaders(
1616
- AuthFlowRequestSchema.parse(rawBody),
1617
- c.req.raw.headers,
1618
- );
1619
- const response = await handleAuthFlow(
1620
- provider,
1621
- body,
1622
- "refresh",
1623
- options,
1624
- c.req.raw.signal,
1625
- );
1486
+ const body = withAuthRequestHeaders(AuthFlowRequestSchema.parse(rawBody), c.req.raw.headers);
1487
+ const response = await handleAuthFlow(provider, body, "refresh", options, c.req.raw.signal);
1626
1488
  logProviderSuccess(
1627
1489
  logger,
1628
1490
  provider,
@@ -1658,17 +1520,8 @@ export function createServerApp(
1658
1520
  .clone()
1659
1521
  .json()
1660
1522
  .catch(() => undefined);
1661
- const body = withAuthRequestHeaders(
1662
- AuthFlowRequestSchema.parse(rawBody),
1663
- c.req.raw.headers,
1664
- );
1665
- const response = await handleAuthFlow(
1666
- provider,
1667
- body,
1668
- "abort",
1669
- options,
1670
- c.req.raw.signal,
1671
- );
1523
+ const body = withAuthRequestHeaders(AuthFlowRequestSchema.parse(rawBody), c.req.raw.headers);
1524
+ const response = await handleAuthFlow(provider, body, "abort", options, c.req.raw.signal);
1672
1525
  logProviderSuccess(
1673
1526
  logger,
1674
1527
  provider,
@@ -1743,12 +1596,9 @@ export async function serve(
1743
1596
  const bunRuntime = getBunServeRuntime();
1744
1597
 
1745
1598
  if (bunRuntime === undefined) {
1746
- throw new ProviderError(
1747
- "Bun runtime is required to start the provider server",
1748
- {
1749
- code: "RUNTIME_UNSUPPORTED",
1750
- },
1751
- );
1599
+ throw new ProviderError("Bun runtime is required to start the provider server", {
1600
+ code: "RUNTIME_UNSUPPORTED",
1601
+ });
1752
1602
  }
1753
1603
 
1754
1604
  const app = createServerApp(provider, {
@@ -1770,6 +1620,7 @@ export async function serve(
1770
1620
  const selfTestApp = createSelfTestApp(provider, {
1771
1621
  secrets: selfTestSecrets,
1772
1622
  invoke: createSelfTestInvoke(app),
1623
+ authFlow: createSelfTestAuthFlowInvoke(app),
1773
1624
  });
1774
1625
  bunRuntime.serve({
1775
1626
  port: options.selfTestPort ?? resolveSelfTestPort(),
@@ -1,13 +1,8 @@
1
1
  import { z } from "zod";
2
2
 
3
- import { HttpRetryPreset } from "../types";
3
+ import { HttpRetryPreset } from "../types.js";
4
4
 
5
- export const ConnectionModeSchema = z.enum([
6
- "oauth2",
7
- "credentials",
8
- "platform-managed",
9
- "none",
10
- ]);
5
+ export const ConnectionModeSchema = z.enum(["oauth2", "credentials", "platform-managed", "none"]);
11
6
 
12
7
  export const OperationConnectionSchema = z.object({
13
8
  id: z.string(),
@@ -99,18 +94,10 @@ export const AuthFlowErrorResponseSchema = OperationErrorResponseSchema;
99
94
  export type ConnectionMode = z.infer<typeof ConnectionModeSchema>;
100
95
  export type OperationConnection = z.infer<typeof OperationConnectionSchema>;
101
96
  export type OperationRequest = z.infer<typeof OperationRequestSchema>;
102
- export type OperationSuccessResponse = z.infer<
103
- typeof OperationSuccessResponseSchema
104
- >;
105
- export type OperationErrorResponse = z.infer<
106
- typeof OperationErrorResponseSchema
107
- >;
108
- export type OperationResponse =
109
- | OperationSuccessResponse
110
- | OperationErrorResponse;
97
+ export type OperationSuccessResponse = z.infer<typeof OperationSuccessResponseSchema>;
98
+ export type OperationErrorResponse = z.infer<typeof OperationErrorResponseSchema>;
99
+ export type OperationResponse = OperationSuccessResponse | OperationErrorResponse;
111
100
  export type AuthFlowRequest = z.infer<typeof AuthFlowRequestSchema>;
112
- export type AuthFlowSuccessResponse = z.infer<
113
- typeof AuthFlowSuccessResponseSchema
114
- >;
101
+ export type AuthFlowSuccessResponse = z.infer<typeof AuthFlowSuccessResponseSchema>;
115
102
  export type AuthFlowErrorResponse = z.infer<typeof AuthFlowErrorResponseSchema>;
116
103
  export type AuthFlowResponse = AuthFlowSuccessResponse | AuthFlowErrorResponse;