stitchkit 0.77.0 → 0.79.0

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 (99) hide show
  1. package/dist/agent-runtime-browser.js +53 -581
  2. package/dist/agent-runtime-coding-tools.js +6 -5
  3. package/dist/agent-runtime-harness.js +20 -93
  4. package/dist/agent-runtime-openrouter.js +1 -1
  5. package/dist/agent-runtime.js +65 -61
  6. package/dist/application/decisions.d.ts +28 -25
  7. package/dist/application/decisions.d.ts.map +1 -1
  8. package/dist/application/kernel.d.ts +2 -0
  9. package/dist/application/kernel.d.ts.map +1 -1
  10. package/dist/application/keyspace.d.ts +11 -1
  11. package/dist/application/keyspace.d.ts.map +1 -1
  12. package/dist/application/schedule.d.ts.map +1 -1
  13. package/dist/application/schemas.d.ts +2 -0
  14. package/dist/application/schemas.d.ts.map +1 -1
  15. package/dist/application/server-resource.d.ts.map +1 -1
  16. package/dist/application/watch-hub.d.ts.map +1 -1
  17. package/dist/application-diagnostic-journal.d.ts +21 -0
  18. package/dist/application-diagnostic-journal.d.ts.map +1 -0
  19. package/dist/application-diagnostic-journal.js +632 -0
  20. package/dist/application-opentelemetry.js +3 -2
  21. package/dist/application-schemas.js +14 -98
  22. package/dist/application.d.ts +1 -2
  23. package/dist/application.d.ts.map +1 -1
  24. package/dist/application.js +155 -882
  25. package/dist/cli.js +13 -11
  26. package/dist/contract/index.js +15 -10
  27. package/dist/files/boundary.d.ts.map +1 -1
  28. package/dist/files.js +1 -1
  29. package/dist/{index-7b188kmz.js → index-2qzskm8h.js} +15 -1
  30. package/dist/{index-k2zczx1g.js → index-2rwwmr7v.js} +3 -3
  31. package/dist/{index-8eywc9zv.js → index-3gye9wzb.js} +6 -3
  32. package/dist/index-4fpa9dy2.js +51 -0
  33. package/dist/{index-7qy2ex0m.js → index-5mtc969c.js} +2 -2
  34. package/dist/index-5s3zajp8.js +192 -0
  35. package/dist/{index-3cwck0rm.js → index-6s7n2v50.js} +60 -374
  36. package/dist/{index-s4c8wy8m.js → index-758zx2ha.js} +11 -90
  37. package/dist/{index-qyrqwr4c.js → index-77fekveh.js} +4 -1
  38. package/dist/{index-58jzmnn4.js → index-7ag81v2f.js} +355 -34
  39. package/dist/index-7gnkny4z.js +326 -0
  40. package/dist/index-7zbps32p.js +89 -0
  41. package/dist/index-85vfqd7m.js +135 -0
  42. package/dist/{index-m668wzyc.js → index-9s6z8vgf.js} +17 -141
  43. package/dist/{index-bfcpjw20.js → index-actkayzn.js} +7 -3
  44. package/dist/index-b9aefrqd.js +20 -0
  45. package/dist/index-dre2ywck.js +48 -0
  46. package/dist/{index-nemjkxjp.js → index-dwf1f2ap.js} +16 -12
  47. package/dist/{index-wwst0td5.js → index-dx9xehwt.js} +1 -1
  48. package/dist/{index-ezmn6ac6.js → index-dxesg10d.js} +4 -4
  49. package/dist/{index-aczggrty.js → index-dxjjv399.js} +2 -2
  50. package/dist/{index-jqtsc9mj.js → index-egaabxkz.js} +3 -3
  51. package/dist/{index-vc1b0b1b.js → index-evcnmsc3.js} +49 -8
  52. package/dist/{index-nt1mp8km.js → index-fxz0v7vg.js} +84 -84
  53. package/dist/index-h4pj6fta.js +87 -0
  54. package/dist/{index-1rxswfbv.js → index-hb5pf3s4.js} +1 -1
  55. package/dist/{index-t8qyvrvg.js → index-k9ay6v6d.js} +21 -272
  56. package/dist/index-kzfs85xp.js +9 -0
  57. package/dist/{index-vbf2p6me.js → index-m9kzax52.js} +91 -89
  58. package/dist/{index-22by16v6.js → index-mgtxfe6b.js} +1 -1
  59. package/dist/index-p7hgdyhb.js +22 -0
  60. package/dist/index-pq95qkbf.js +0 -0
  61. package/dist/index-t0z5p5w6.js +318 -0
  62. package/dist/{index-s2rchahr.js → index-vwp69871.js} +13 -11
  63. package/dist/index-wc4x00bn.js +103 -0
  64. package/dist/{index-da1aqnhb.js → index-xcetq6j3.js} +8 -6
  65. package/dist/{index-f6n5n7nz.js → index-y01f4223.js} +33 -126
  66. package/dist/{index-35z5h2ty.js → index-ywd0y6m1.js} +18 -218
  67. package/dist/index.js +65 -1588
  68. package/dist/internal/deadline.d.ts +17 -0
  69. package/dist/internal/deadline.d.ts.map +1 -0
  70. package/dist/live.js +15 -89
  71. package/dist/node.js +17 -15
  72. package/dist/observability/context.d.ts.map +1 -1
  73. package/dist/observability/index.js +7 -6
  74. package/dist/primitives.js +5 -2
  75. package/dist/react.js +1 -1
  76. package/dist/remote.js +7 -6
  77. package/dist/server/event-bus.d.ts.map +1 -1
  78. package/dist/server/index.js +26 -38
  79. package/dist/telegram.js +1 -1
  80. package/dist/testing.js +86 -97
  81. package/dist/tool-invoker.js +11 -9
  82. package/dist/tools/async-operation-contract.d.ts +61 -0
  83. package/dist/tools/async-operation-contract.d.ts.map +1 -0
  84. package/dist/tools/async-operation.d.ts +2 -47
  85. package/dist/tools/async-operation.d.ts.map +1 -1
  86. package/dist/tools/view-file-contract.d.ts +98 -0
  87. package/dist/tools/view-file-contract.d.ts.map +1 -0
  88. package/dist/tools/view-file.d.ts +4 -83
  89. package/dist/tools/view-file.d.ts.map +1 -1
  90. package/dist/tools-contract.d.ts +29 -0
  91. package/dist/tools-contract.d.ts.map +1 -0
  92. package/dist/tools-contract.js +24 -0
  93. package/dist/tools.d.ts +3 -3
  94. package/dist/tools.d.ts.map +1 -1
  95. package/dist/tools.js +59 -95
  96. package/llms-full.txt +146 -14
  97. package/package.json +14 -7
  98. package/dist/index-ksp6e2ye.js +0 -24
  99. package/dist/index-vj3vvpaa.js +0 -307
package/dist/index.js CHANGED
@@ -1,1590 +1,87 @@
1
+ import {
2
+ defineRealtimeContract
3
+ } from "./index-p7hgdyhb.js";
4
+ import {
5
+ BackoffPolicySchema,
6
+ createBackoff,
7
+ resumableIterator
8
+ } from "./index-h4pj6fta.js";
9
+ import {
10
+ REALTIME_REJECTION_KEY,
11
+ asRealtimeRejection,
12
+ createValidatedRealtimeSocket,
13
+ isModuleNotFound,
14
+ parseRealtimeRequestAcknowledgement,
15
+ parseRealtimeRequestArguments
16
+ } from "./index-t0z5p5w6.js";
17
+ import {
18
+ RealtimeRequestDisconnectedError,
19
+ RealtimeRequestInvalidAcknowledgementError,
20
+ RealtimeRequestPhaseEventSchema,
21
+ RealtimeRequestPhaseSchema,
22
+ RealtimeRequestRejectedError,
23
+ RealtimeRequestTimeoutError
24
+ } from "./index-2qzskm8h.js";
1
25
  import {
2
26
  LiveStateControllerStatusSchema,
3
27
  LiveStatePhaseSchema,
4
28
  LiveStateStopReasonSchema,
5
29
  createLiveStateController
6
- } from "./index-35z5h2ty.js";
30
+ } from "./index-ywd0y6m1.js";
31
+ import"./index-7gnkny4z.js";
32
+ import {
33
+ ApiError,
34
+ contractEndpointMatchers,
35
+ createClient,
36
+ createClients,
37
+ createHttpClient,
38
+ createScopedClients,
39
+ createScopedUrlBuilders,
40
+ createUrlBuilder,
41
+ createUrlBuilders,
42
+ parseNDJSON
43
+ } from "./index-7ag81v2f.js";
44
+ import {
45
+ parseSSE
46
+ } from "./index-hb5pf3s4.js";
47
+ import {
48
+ childSpan,
49
+ createTraceContext,
50
+ formatTraceparent,
51
+ formatZodError,
52
+ parseTraceparent,
53
+ randomHex,
54
+ zodIssues
55
+ } from "./index-fxz0v7vg.js";
7
56
  import {
8
57
  ALL_TRANSPORTS,
9
- AppError,
10
58
  ContractStreamFrameSchema,
11
59
  DEFAULT_CONTRACT_STREAM_FRAME_BYTES,
12
- ManagedFilePathSchema,
13
- ManagedFileRefSchema,
14
- STITCH_ERROR_STATUS,
15
- appError,
16
- badRequest,
17
- conflict,
18
60
  createContractFactory,
19
61
  decodeCursor,
20
62
  defineContract,
21
63
  defineErrors,
22
64
  encodeCursor,
65
+ paginatedSchema
66
+ } from "./index-y01f4223.js";
67
+ import {
68
+ ManagedFilePathSchema,
69
+ ManagedFileRefSchema
70
+ } from "./index-6k1937bx.js";
71
+ import {
72
+ AppError,
73
+ STITCH_ERROR_STATUS,
74
+ appError,
75
+ badRequest,
76
+ conflict,
23
77
  forbidden,
24
78
  isStitchErrorCode,
25
79
  notFound,
26
- paginatedSchema,
27
- parseTrailingWildcard,
28
80
  rateLimited,
29
81
  unauthorized
30
- } from "./index-f6n5n7nz.js";
31
- import {
32
- isRecord,
33
- mapObject,
34
- transportResult,
35
- typedEntries
36
- } from "./index-ksp6e2ye.js";
37
-
38
- // src/browser/cancellation.ts
39
- class RequestCancellationError extends Error {
40
- cause;
41
- constructor(cause) {
42
- super(cause === "caller" ? "Request was aborted" : "Request timed out");
43
- this.cause = cause;
44
- this.name = "RequestCancellationError";
45
- }
46
- }
47
- function createRequestCancellation(caller, timeoutMs) {
48
- if (!caller && timeoutMs === undefined) {
49
- return { signal: undefined, run: (operation) => operation() };
50
- }
51
- const timeoutController = timeoutMs === undefined ? undefined : new AbortController;
52
- const signal = caller && timeoutController ? AbortSignal.any([caller, timeoutController.signal]) : caller ?? timeoutController?.signal;
53
- let cause;
54
- let timer;
55
- const abortFromCaller = () => {
56
- if (cause)
57
- return;
58
- cause = "caller";
59
- };
60
- if (caller?.aborted)
61
- abortFromCaller();
62
- else
63
- caller?.addEventListener("abort", abortFromCaller, { once: true });
64
- if (timeoutMs !== undefined && timeoutController) {
65
- timer = setTimeout(() => {
66
- if (cause)
67
- return;
68
- cause = "timeout";
69
- timeoutController.abort(new DOMException("Request timed out", "TimeoutError"));
70
- }, timeoutMs);
71
- }
72
- return {
73
- signal,
74
- async run(operation) {
75
- try {
76
- if (cause === "caller")
77
- throw cancellationError(cause);
78
- return await operation(signal);
79
- } catch (error) {
80
- if (cause)
81
- throw cancellationError(cause);
82
- throw error;
83
- } finally {
84
- if (timer !== undefined)
85
- clearTimeout(timer);
86
- caller?.removeEventListener("abort", abortFromCaller);
87
- }
88
- }
89
- };
90
- }
91
- function cancellationError(cause) {
92
- return new RequestCancellationError(cause);
93
- }
94
-
95
- // src/browser/http.ts
96
- import ky, {
97
- isHTTPError,
98
- isNetworkError,
99
- isTimeoutError
100
- } from "ky";
101
-
102
- // src/internal/random-hex.ts
103
- function randomHex(bytes) {
104
- const arr = new Uint8Array(bytes);
105
- crypto.getRandomValues(arr);
106
- let hex = "";
107
- for (const byte of arr)
108
- hex += byte.toString(16).padStart(2, "0");
109
- return hex;
110
- }
111
-
112
- // src/observability/trace.ts
113
- var TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})(.*)$/i;
114
- function createTraceContext() {
115
- return { traceId: randomHex(16), spanId: randomHex(8) };
116
- }
117
- function parseTraceparent(header) {
118
- if (!header)
119
- return null;
120
- const match = TRACEPARENT_RE.exec(header.trim());
121
- if (!match?.[1] || !match[2] || !match[3] || !match[4] || match[5] === undefined)
122
- return null;
123
- const version = match[1].toLowerCase();
124
- if (version === "ff")
125
- return null;
126
- const suffix = match[5];
127
- if (version === "00" ? suffix !== "" : suffix !== "" && !/^(?:-[0-9a-f]{2,})+$/i.test(suffix)) {
128
- return null;
129
- }
130
- const traceId = match[2].toLowerCase();
131
- const parentSpanId = match[3].toLowerCase();
132
- const traceFlags = match[4].toLowerCase();
133
- if (/^0+$/.test(traceId) || /^0+$/.test(parentSpanId))
134
- return null;
135
- return { traceId, spanId: randomHex(8), parentSpanId, traceFlags };
136
- }
137
- function formatTraceparent(ctx) {
138
- return `00-${ctx.traceId}-${ctx.spanId}-${ctx.traceFlags ?? "01"}`;
139
- }
140
- function childSpan(parent) {
141
- return {
142
- traceId: parent.traceId,
143
- spanId: randomHex(8),
144
- parentSpanId: parent.spanId,
145
- ...parent.tracestate !== undefined && { tracestate: parent.tracestate },
146
- ...parent.baggage !== undefined && { baggage: parent.baggage },
147
- ...parent.traceFlags !== undefined && { traceFlags: parent.traceFlags }
148
- };
149
- }
150
- var encoder = new TextEncoder;
151
-
152
- // src/browser/request-id.ts
153
- var REQUEST_ID_HEADER = "x-request-id";
154
- function responseTraceId(response) {
155
- return response?.headers.get(REQUEST_ID_HEADER) ?? undefined;
156
- }
157
-
158
- // src/browser/http.ts
159
- var API_ERROR_BRAND = Symbol.for("stitchkit.ApiError");
160
- function messageForCode(code, message) {
161
- return message !== undefined && message.length > 0 ? message : `${code} (no message supplied)`;
162
- }
163
-
164
- class ApiError extends Error {
165
- code;
166
- status;
167
- details;
168
- hint;
169
- traceId;
170
- constructor(code, status = 0, details, message, hint, traceId, options) {
171
- super(messageForCode(code, message), options);
172
- this.code = code;
173
- this.status = status;
174
- this.details = details;
175
- this.hint = hint;
176
- this.traceId = traceId;
177
- this.name = "ApiError";
178
- Object.defineProperty(this, API_ERROR_BRAND, { value: true });
179
- }
180
- static is(error) {
181
- return typeof error === "object" && error !== null && API_ERROR_BRAND in error;
182
- }
183
- }
184
- function refuseLocally(path, message) {
185
- return new ApiError("VALIDATION_ERROR", 0, { issues: [{ path, code: "invalid_type", message }] }, message);
186
- }
187
- function shouldRetryBunNetworkError(error) {
188
- if (ApiError.is(error) || isHTTPError(error) || isNetworkError(error) || isTimeoutError(error) || error instanceof RequestCancellationError || error instanceof DOMException && (error.name === "AbortError" || error.name === "TimeoutError")) {
189
- return;
190
- }
191
- if (!(error instanceof Error))
192
- return;
193
- const code = Object.getOwnPropertyDescriptor(error, "code");
194
- return code && "value" in code && code.value === "ConnectionRefused" ? true : undefined;
195
- }
196
- function parseApiErrorBody(body) {
197
- if (!isRecord(body) || !isRecord(body.error))
198
- return null;
199
- const error = body.error;
200
- if (typeof error.code !== "string")
201
- return null;
202
- return {
203
- code: error.code,
204
- message: typeof error.message === "string" ? error.message : undefined,
205
- details: error.details,
206
- hint: typeof error.hint === "string" ? error.hint : undefined
207
- };
208
- }
209
- function createRetryAwareFetch(transportFetch, unix) {
210
- const runtimeFetch = transportFetch;
211
- let attempt = 0;
212
- return (input, init) => {
213
- attempt += 1;
214
- if (unix === undefined && attempt === 1) {
215
- return runtimeFetch(input, init);
216
- }
217
- if (!(input instanceof Request)) {
218
- if (unix === undefined)
219
- return runtimeFetch(input, init);
220
- const unixInit = { ...init, unix };
221
- return runtimeFetch(input, unixInit);
222
- }
223
- const streamedBody = input.body ? { body: input.body, duplex: "half" } : {};
224
- const materialized = {
225
- ...init,
226
- ...unix !== undefined && { unix },
227
- method: input.method,
228
- headers: input.headers,
229
- ...streamedBody,
230
- cache: input.cache,
231
- credentials: input.credentials,
232
- integrity: input.integrity,
233
- keepalive: input.keepalive,
234
- mode: input.mode,
235
- redirect: input.redirect,
236
- referrer: input.referrer,
237
- referrerPolicy: input.referrerPolicy,
238
- signal: input.signal
239
- };
240
- return runtimeFetch(input.url, materialized);
241
- };
242
- }
243
- function createHttpClient(config) {
244
- if (config.fetch && config.unix) {
245
- throw new TypeError("HttpClientConfig.fetch and unix are mutually exclusive");
246
- }
247
- if (config.unix !== undefined) {
248
- if (!config.unix.startsWith("/") || config.unix.includes("\x00")) {
249
- throw new TypeError("HttpClientConfig.unix must be an absolute Unix socket path");
250
- }
251
- if (typeof Reflect.get(globalThis, "Bun") !== "object") {
252
- throw new TypeError("HttpClientConfig.unix requires Bun; on Bun or Node use createUnixClientTransport().fetch for an explicit portable transport");
253
- }
254
- }
255
- let ssrCookies = null;
256
- let isLoggedOut = false;
257
- const listeners = new Set;
258
- const suppressUnauthorizedFor = config.suppressUnauthorizedFor ?? [];
259
- const parseError = config.parseError ?? parseApiErrorBody;
260
- function emit(event) {
261
- for (const fn of listeners) {
262
- try {
263
- fn(event);
264
- } catch {}
265
- }
266
- }
267
- const client = ky.create({
268
- prefix: config.baseUrl,
269
- credentials: config.credentials ?? "include",
270
- timeout: false,
271
- retry: {
272
- limit: config.retry?.limit ?? 2,
273
- methods: config.retry?.methods ?? ["get"],
274
- statusCodes: config.retry?.statusCodes ?? [],
275
- shouldRetry: ({ error }) => shouldRetryBunNetworkError(error)
276
- },
277
- hooks: {
278
- beforeRequest: [
279
- ({ request: request2 }) => {
280
- if (ssrCookies) {
281
- request2.headers.set("Cookie", ssrCookies);
282
- }
283
- const extra = typeof config.headers === "function" ? config.headers() : config.headers;
284
- if (extra) {
285
- for (const [key, value] of Object.entries(extra)) {
286
- request2.headers.set(key, value);
287
- }
288
- }
289
- if (config.trace && !request2.headers.has("traceparent")) {
290
- request2.headers.set("traceparent", formatTraceparent(createTraceContext()));
291
- }
292
- }
293
- ],
294
- afterResponse: [
295
- async ({ request: request2, response }) => {
296
- if (response.status === 401) {
297
- const url = new URL(request2.url).pathname;
298
- if (!isLoggedOut && !suppressUnauthorizedFor.some((matches) => matches(url))) {
299
- isLoggedOut = true;
300
- emit({ type: "unauthorized" });
301
- }
302
- }
303
- if (!response.ok) {
304
- const body = await response.clone().json().catch(() => null);
305
- if (body) {
306
- const parsed = parseError(body);
307
- if (parsed) {
308
- throw new ApiError(parsed.code, response.status, parsed.details, parsed.message, parsed.hint, responseTraceId(response));
309
- }
310
- }
311
- }
312
- }
313
- ]
314
- }
315
- });
316
- async function request(method, url, data, options = {}) {
317
- const cancellation = createRequestCancellation(options.signal, options.timeout ?? config.timeout ?? 30000);
318
- const kyOptions = {
319
- fetch: createRetryAwareFetch(config.fetch ?? globalThis.fetch.bind(globalThis), config.unix),
320
- timeout: false,
321
- signal: cancellation.signal
322
- };
323
- if (options.params) {
324
- const searchParams = new URLSearchParams;
325
- for (const [key, value] of Object.entries(options.params)) {
326
- if (value === undefined)
327
- continue;
328
- if (Array.isArray(value)) {
329
- for (const item of value)
330
- searchParams.append(key, String(item));
331
- } else {
332
- searchParams.set(key, String(value));
333
- }
334
- }
335
- if (searchParams.size > 0) {
336
- kyOptions.searchParams = searchParams;
337
- }
338
- }
339
- if (data instanceof FormData) {
340
- kyOptions.body = data;
341
- } else if (data !== undefined) {
342
- kyOptions.json = data;
343
- }
344
- try {
345
- return await cancellation.run(async () => {
346
- if (options.responseType === "blob") {
347
- return transportResult(await client[method](url, kyOptions).blob());
348
- }
349
- if (options.responseType === "response") {
350
- return transportResult(await client[method](url, kyOptions));
351
- }
352
- const response = await client[method](url, kyOptions);
353
- if (options.responseType === "void") {
354
- const text = await response.text();
355
- if (text.length > 0) {
356
- throw new Error("Server returned data for an endpoint with no output contract");
357
- }
358
- }
359
- if (options.responseType === "void" || response.status === 204 || response.headers.get("content-length") === "0") {
360
- return transportResult(undefined);
361
- }
362
- return await response.json();
363
- });
364
- } catch (error) {
365
- if (error instanceof RequestCancellationError) {
366
- throw new ApiError(error.cause === "caller" ? "REQUEST_ABORTED" : "REQUEST_TIMEOUT", 0, undefined, error.message);
367
- }
368
- if (ApiError.is(error))
369
- throw error;
370
- emit({ type: "network_error" });
371
- const response = isHTTPError(error) ? error.response : undefined;
372
- const status = response?.status ?? 0;
373
- const msg = error instanceof Error ? error.message : undefined;
374
- throw new ApiError("UNKNOWN_ERROR", status, msg ? { message: msg } : undefined, msg, undefined, responseTraceId(response), { cause: error });
375
- }
376
- }
377
- return {
378
- baseUrl: config.baseUrl,
379
- get: (url, options) => request("get", url, undefined, options),
380
- head: (url, options) => request("head", url, undefined, options),
381
- post: (url, data, options) => request("post", url, data, options),
382
- put: (url, data, options) => request("put", url, data, options),
383
- patch: (url, data, options) => request("patch", url, data, options),
384
- delete: (url, options) => request("delete", url, undefined, options),
385
- setServerContext(cookies) {
386
- ssrCookies = cookies;
387
- },
388
- subscribe(listener) {
389
- listeners.add(listener);
390
- return () => listeners.delete(listener);
391
- },
392
- logout() {
393
- isLoggedOut = true;
394
- emit({ type: "logout" });
395
- },
396
- resetLogoutState() {
397
- isLoggedOut = false;
398
- }
399
- };
400
- }
401
-
402
- // src/browser/client-multipart.ts
403
- function isFileDescriptor(value) {
404
- return typeof value === "object" && value !== null && !(value instanceof Blob) && "uri" in value && typeof value.uri === "string" && "name" in value && typeof value.name === "string" && "type" in value && typeof value.type === "string";
405
- }
406
- function isMultipartFile(value) {
407
- return value instanceof Blob || isFileDescriptor(value);
408
- }
409
- function appendMultipartFile(form, field, file) {
410
- const sink = form;
411
- sink.append(field, file);
412
- }
413
- function appendFormFields(formData, values, skipKeys) {
414
- for (const [key, value] of Object.entries(values)) {
415
- if (skipKeys.has(key) || value === undefined || value === null)
416
- continue;
417
- formData.append(key, typeof value === "string" ? value : JSON.stringify(value));
418
- }
419
- }
420
- function buildMultipartForm(descriptor, values) {
421
- const formData = new FormData;
422
- const fileFields = new Set(Object.keys(descriptor.files));
423
- for (const [field, policy] of Object.entries(descriptor.files)) {
424
- const value = values[field];
425
- if (value === undefined) {
426
- if (policy.required !== false) {
427
- throw refuseLocally(field, `Missing multipart file field: ${field}`);
428
- }
429
- continue;
430
- }
431
- if (policy.multiple === true) {
432
- if (!Array.isArray(value) || value.length === 0) {
433
- throw refuseLocally(field, `Multipart file field "${field}" must be a non-empty array`);
434
- }
435
- for (const file of value) {
436
- if (!isMultipartFile(file)) {
437
- throw refuseLocally(field, `Invalid multipart file field: ${field}`);
438
- }
439
- appendMultipartFile(formData, field, file);
440
- }
441
- continue;
442
- }
443
- if (!isMultipartFile(value)) {
444
- throw refuseLocally(field, `Invalid multipart file field: ${field}`);
445
- }
446
- appendMultipartFile(formData, field, value);
447
- }
448
- appendFormFields(formData, values, fileFields);
449
- return formData;
450
- }
451
-
452
- // src/internal/http-input.ts
453
- function inputIsQuery(method) {
454
- return method === "GET" || method === "DELETE";
455
- }
456
-
457
- // src/browser/client-url.ts
458
- function isParamArray(value) {
459
- return Array.isArray(value) && value.every((item) => typeof item === "string" || typeof item === "number");
460
- }
461
- function collectQueryParams(args, endpoint) {
462
- const params = {};
463
- let hasParams = false;
464
- for (const [key, value] of Object.entries(args)) {
465
- if (value === undefined || value === null)
466
- continue;
467
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || isParamArray(value)) {
468
- params[key] = value;
469
- hasParams = true;
470
- continue;
471
- }
472
- const what = Array.isArray(value) ? "an array with non-primitive items" : typeof value === "object" ? "a nested object" : `a ${typeof value}`;
473
- throw refuseLocally(key, `${endpoint.method} ${endpoint.path}: input field "${key}" is ${what} — it cannot ` + "travel as a query parameter. GET / DELETE input must be flat (string / number / " + "boolean, or an array of string / number); flatten the field or move the " + "operation to a body verb (POST).");
474
- }
475
- return hasParams ? params : undefined;
476
- }
477
- function hasStringKeys(args, keys) {
478
- for (const key of keys) {
479
- if (typeof args[key] !== "string")
480
- return false;
481
- }
482
- return true;
483
- }
484
- function resolvePathPrefix(config, args) {
485
- if (!config?.pathPrefix)
486
- return "";
487
- if (typeof config.pathPrefix === "string")
488
- return config.pathPrefix;
489
- const keys = config.stripPrefixKeys ?? [];
490
- if (!hasStringKeys(args, keys)) {
491
- const missing = keys.find((key) => typeof args[key] !== "string");
492
- throw refuseLocally(String(missing), `Missing path prefix key: ${missing}`);
493
- }
494
- return config.pathPrefix(args);
495
- }
496
- function escapeRegex(value) {
497
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
498
- }
499
- function decodePathSegment(value) {
500
- try {
501
- return decodeURIComponent(value);
502
- } catch {
503
- return value;
504
- }
505
- }
506
- function createClientRouteMatcher(endpoint, contractPrefix, config) {
507
- if (typeof config?.pathPrefix === "function" && (!config.stripPrefixKeys || config.stripPrefixKeys.length === 0)) {
508
- throw new Error("Dynamic pathPrefix matchers require stripPrefixKeys");
509
- }
510
- const markerByKey = {};
511
- for (const [index, key] of (config?.stripPrefixKeys ?? []).entries()) {
512
- markerByKey[key] = `__stitch_scope_${index}__`;
513
- }
514
- const pathPrefix = resolvePathPrefix(config, markerByKey);
515
- const route = [pathPrefix, contractPrefix, endpoint.path === "/" ? "" : endpoint.path].filter(Boolean).join("/");
516
- const patternSegments = route.split("/").filter(Boolean);
517
- const wildcard = patternSegments.at(-1)?.startsWith("*") === true;
518
- const fixedCount = wildcard ? patternSegments.length - 1 : patternSegments.length;
519
- const markers = Object.values(markerByKey);
520
- return (pathname) => {
521
- const actualSegments = pathname.split("/").filter(Boolean).map(decodePathSegment);
522
- if (wildcard ? actualSegments.length < fixedCount : actualSegments.length !== fixedCount) {
523
- return false;
524
- }
525
- for (let index = 0;index < fixedCount; index += 1) {
526
- const pattern = patternSegments[index];
527
- const actual = actualSegments[index];
528
- if (!pattern || actual === undefined)
529
- return false;
530
- if (pattern.startsWith(":"))
531
- continue;
532
- let source = escapeRegex(pattern);
533
- for (const marker of markers) {
534
- source = source.replaceAll(escapeRegex(marker), "[^/]+");
535
- }
536
- if (!new RegExp(`^${source}$`).test(actual))
537
- return false;
538
- }
539
- return true;
540
- };
541
- }
542
- function extractParamNames(path) {
543
- const matches = path.match(/:(\w+)/g);
544
- const names = matches ? matches.map((match) => match.slice(1)) : [];
545
- const wildcard = parseTrailingWildcard(path);
546
- if (wildcard)
547
- names.push(wildcard.name);
548
- return names;
549
- }
550
- function fillPathParams(path, args) {
551
- const wildcard = parseTrailingWildcard(path);
552
- let filled = path.replace(/:(\w+)/g, (_, key) => {
553
- const value = args[key];
554
- if (value === undefined || value === null) {
555
- throw refuseLocally(String(key), `Missing path param: ${key}`);
556
- }
557
- return encodeURIComponent(String(value));
558
- });
559
- if (!wildcard)
560
- return filled;
561
- const wildcardValue = args[wildcard.name];
562
- if (wildcardValue === undefined || wildcardValue === null) {
563
- throw refuseLocally(wildcard.name, `Missing path param: ${wildcard.name}`);
564
- }
565
- const remainder = String(wildcardValue).split("/").map((segment) => encodeURIComponent(segment)).join("/");
566
- filled = `${filled.slice(0, -(wildcard.name.length + 1))}${remainder}`;
567
- return filled;
568
- }
569
- function stripConsumedArgs(args, path, scopeKeys) {
570
- const consumed = new Set(scopeKeys);
571
- for (const name of extractParamNames(path))
572
- consumed.add(name);
573
- const remaining = {};
574
- for (const [key, value] of Object.entries(args)) {
575
- if (!consumed.has(key) && value !== undefined)
576
- remaining[key] = value;
577
- }
578
- return remaining;
579
- }
580
- function appendQuery(relativeUrl, params) {
581
- if (!params)
582
- return relativeUrl;
583
- const search = new URLSearchParams;
584
- for (const [key, value] of Object.entries(params)) {
585
- if (Array.isArray(value)) {
586
- for (const item of value)
587
- search.append(key, String(item));
588
- } else {
589
- search.set(key, String(value));
590
- }
591
- }
592
- return search.size > 0 ? `${relativeUrl}?${search}` : relativeUrl;
593
- }
594
- function planClientRequest(endpoint, contractPrefix, args, config) {
595
- let pathPrefix = resolvePathPrefix(config, args);
596
- if (pathPrefix && !pathPrefix.endsWith("/"))
597
- pathPrefix += "/";
598
- if (pathPrefix.startsWith("/"))
599
- pathPrefix = pathPrefix.slice(1);
600
- const endpointPath = endpoint.path === "/" ? "" : endpoint.path;
601
- let relativeUrl = fillPathParams(`${pathPrefix}${contractPrefix}${endpointPath}`, args);
602
- if (relativeUrl.endsWith("/"))
603
- relativeUrl = relativeUrl.slice(0, -1);
604
- const remainingArgs = stripConsumedArgs(args, endpoint.path, config?.stripPrefixKeys ?? []);
605
- if (inputIsQuery(endpoint.method)) {
606
- relativeUrl = appendQuery(relativeUrl, collectQueryParams(remainingArgs, endpoint));
607
- }
608
- return { relativeUrl, remainingArgs };
609
- }
610
- function joinClientBaseUrl(baseUrl, relativeUrl) {
611
- const base = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
612
- const path = relativeUrl.startsWith("/") ? relativeUrl : `/${relativeUrl}`;
613
- return `${base}${path}`;
614
- }
615
-
616
- // src/internal/bounded-lines.ts
617
- var DEFAULT_STREAM_LINE_BYTES = 1024 * 1024;
618
- function lineLimit(value) {
619
- const resolved = value ?? DEFAULT_STREAM_LINE_BYTES;
620
- if (!Number.isSafeInteger(resolved) || resolved <= 0) {
621
- throw new TypeError("maxLineBytes must be a positive safe integer");
622
- }
623
- return resolved;
624
- }
625
- function joinBytes(left, right) {
626
- if (left.byteLength === 0)
627
- return right.slice();
628
- const result = new Uint8Array(left.byteLength + right.byteLength);
629
- result.set(left);
630
- result.set(right, left.byteLength);
631
- return result;
632
- }
633
- async function* readBoundedUtf8Lines(response, maxLineBytes, requireFinalNewline = false) {
634
- const reader = response.body?.getReader();
635
- if (!reader)
636
- return;
637
- const limit = lineLimit(maxLineBytes);
638
- const decoder = new TextDecoder("utf-8", { fatal: true });
639
- let pending = new Uint8Array;
640
- try {
641
- for (;; ) {
642
- const chunk = await reader.read();
643
- if (chunk.done)
644
- break;
645
- let start = 0;
646
- for (let index = 0;index < chunk.value.byteLength; index += 1) {
647
- if (chunk.value[index] !== 10)
648
- continue;
649
- const lineBytes = joinBytes(pending, chunk.value.slice(start, index));
650
- if (lineBytes.byteLength > limit) {
651
- throw new RangeError(`Stream line exceeds the ${limit} byte limit`);
652
- }
653
- yield decoder.decode(lineBytes);
654
- pending = new Uint8Array;
655
- start = index + 1;
656
- }
657
- pending = joinBytes(pending, chunk.value.slice(start));
658
- if (pending.byteLength > limit) {
659
- throw new RangeError(`Stream line exceeds the ${limit} byte limit`);
660
- }
661
- }
662
- if (pending.byteLength > 0) {
663
- if (requireFinalNewline) {
664
- throw new SyntaxError("Stream ended with an unterminated final line");
665
- }
666
- yield decoder.decode(pending);
667
- }
668
- } finally {
669
- await reader.cancel().catch(() => {
670
- return;
671
- });
672
- reader.releaseLock();
673
- }
674
- }
675
-
676
- // src/internal/errors.ts
677
- import { z } from "zod";
678
- function issuePath(path) {
679
- return path.length > 0 ? path.map(String).join(".") : "(root)";
680
- }
681
- function formatZodError(error) {
682
- const issues = error.issues.slice(0, 5);
683
- const lines = issues.map((issue) => `${issuePath(issue.path)}: ${issue.message}`);
684
- const suffix = error.issues.length > 5 ? `
685
- ...and ${error.issues.length - 5} more issues` : "";
686
- return lines.join(`
687
- `) + suffix;
688
- }
689
- function zodIssues(error) {
690
- return error.issues.map((issue) => ({
691
- path: issuePath(issue.path),
692
- code: issue.code,
693
- message: issue.message
694
- }));
695
- }
696
-
697
- // src/server/stream.ts
698
- async function* parseSSE(response, options) {
699
- try {
700
- for await (const rawLine of readBoundedUtf8Lines(response, options?.maxLineBytes ?? DEFAULT_STREAM_LINE_BYTES)) {
701
- const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
702
- if (!line.startsWith("data:"))
703
- continue;
704
- const data = line.slice(5).replace(/^ /, "");
705
- if (data === "[DONE]")
706
- return;
707
- try {
708
- yield JSON.parse(data);
709
- } catch (error) {
710
- const failure = error instanceof Error ? error : new Error(String(error));
711
- if (!options?.onParseError)
712
- throw failure;
713
- options.onParseError(data, failure);
714
- }
715
- }
716
- } catch (error) {
717
- const failure = error instanceof Error ? error : new Error(String(error));
718
- if (!options?.onParseError)
719
- throw failure;
720
- options.onParseError("", failure);
721
- }
722
- }
723
- // src/browser/stream.ts
724
- function parseFailure(raw, error, onParseError) {
725
- const failure = error instanceof Error ? error : new Error(String(error));
726
- if (!onParseError)
727
- throw failure;
728
- onParseError(raw, failure);
729
- }
730
- async function* parseNDJSON(response, options) {
731
- try {
732
- for await (const rawLine of readBoundedUtf8Lines(response, options?.maxLineBytes ?? DEFAULT_STREAM_LINE_BYTES, options?.finalLine === "require-newline")) {
733
- const line = (rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine).trim();
734
- if (line === "")
735
- continue;
736
- try {
737
- yield JSON.parse(line);
738
- } catch (error) {
739
- parseFailure(line, error, options?.onParseError);
740
- }
741
- }
742
- } catch (error) {
743
- parseFailure("", error, options?.onParseError);
744
- }
745
- }
746
-
747
- // src/browser/contract-stream.ts
748
- function sourceFor(response, descriptor) {
749
- const options = {
750
- maxLineBytes: descriptor.maxFrameBytes ?? DEFAULT_CONTRACT_STREAM_FRAME_BYTES,
751
- finalLine: descriptor.finalLine
752
- };
753
- return descriptor.format === "sse" ? parseSSE(response, options) : parseNDJSON(response, options);
754
- }
755
- async function* readContractStream(response, descriptor, abort) {
756
- let ended = false;
757
- let terminalSeen = descriptor.terminal === undefined;
758
- const source = sourceFor(response, descriptor);
759
- try {
760
- for (;; ) {
761
- const next = await source.next();
762
- if (next.done)
763
- break;
764
- let candidate = next.value;
765
- if (descriptor.framing !== "item") {
766
- const parsedFrame = ContractStreamFrameSchema.safeParse(candidate);
767
- if (!parsedFrame.success) {
768
- throw new ApiError("STREAM_PROTOCOL_ERROR", 0, undefined, "Stream frame did not match the protocol envelope");
769
- }
770
- const frame = parsedFrame.data;
771
- if (frame.type === "error") {
772
- throw new ApiError(frame.error.code, 0, frame.error.details, frame.error.message, frame.error.hint);
773
- }
774
- if (frame.type === "end") {
775
- if (!terminalSeen) {
776
- throw new ApiError("STREAM_TERMINAL_MISSING", 0, undefined, "Stream completed before its declared terminal item");
777
- }
778
- ended = true;
779
- return;
780
- }
781
- candidate = frame.data;
782
- }
783
- const parsedItem = descriptor.item.safeParse(candidate);
784
- if (!parsedItem.success) {
785
- throw new ApiError("STREAM_ITEM_INVALID", 0, undefined, "Stream item did not match its contract");
786
- }
787
- const item = parsedItem.data;
788
- const terminal = descriptor.terminal?.safeParse(item).success ?? false;
789
- if (terminal)
790
- terminalSeen = true;
791
- if (terminal && descriptor.completion === "terminal") {
792
- abort();
793
- await source.return(undefined);
794
- ended = true;
795
- }
796
- yield item;
797
- if (ended)
798
- return;
799
- }
800
- if (descriptor.framing === "item") {
801
- if (terminalSeen)
802
- return;
803
- throw new ApiError("STREAM_TERMINAL_MISSING", 0, undefined, "Stream completed before its declared terminal item");
804
- }
805
- if (!ended) {
806
- throw new ApiError("STREAM_TRUNCATED", 0, undefined, "Stream ended without its protocol terminal frame");
807
- }
808
- } finally {
809
- abort();
810
- await source.return(undefined);
811
- }
812
- }
813
-
814
- class OwnedContractStream {
815
- #inner;
816
- #abort;
817
- constructor(inner, abort) {
818
- this.#inner = inner;
819
- this.#abort = abort;
820
- }
821
- [Symbol.asyncIterator]() {
822
- return this;
823
- }
824
- next() {
825
- return this.#inner.next();
826
- }
827
- return() {
828
- this.#abort();
829
- return this.#inner.return(undefined);
830
- }
831
- throw(error) {
832
- this.#abort();
833
- return this.#inner.throw(error);
834
- }
835
- }
836
- function parseContractStream(response, descriptor, abort) {
837
- return new OwnedContractStream(readContractStream(response, descriptor, abort), abort);
838
- }
839
-
840
- // src/browser/client.ts
841
- function withTimeout(options, endpoint) {
842
- const responseType = endpoint.rawResponse || "stream" in endpoint ? "response" : endpoint.output ? undefined : "void";
843
- if (endpoint.timeout === undefined && responseType === undefined)
844
- return options;
845
- return {
846
- ...options,
847
- ...endpoint.timeout !== undefined && { timeout: endpoint.timeout },
848
- ...responseType && { responseType }
849
- };
850
- }
851
- function withOutput(endpoint, result, abortStream) {
852
- if (endpoint.rawResponse)
853
- return result;
854
- if ("stream" in endpoint && endpoint.stream) {
855
- return result.then((value) => {
856
- if (!(value instanceof Response)) {
857
- abortStream?.();
858
- throw new Error("Streaming endpoint did not return a Response");
859
- }
860
- return parseContractStream(value, endpoint.stream, abortStream ?? (() => {
861
- return;
862
- }));
863
- }, (error) => {
864
- abortStream?.();
865
- throw error;
866
- });
867
- }
868
- const schema = endpoint.output;
869
- return result.then((value) => {
870
- if (!schema) {
871
- if (value === undefined || value === null)
872
- return;
873
- throw new Error("Server returned data for an endpoint with no output contract");
874
- }
875
- if (value === undefined) {
876
- throw new Error("Server returned no body for an endpoint with an output contract");
877
- }
878
- return schema.parse(value);
879
- });
880
- }
881
- function contractEndpointMatchers(contract, endpointNames, contractConfig) {
882
- const selected = endpointNames ? new Set(endpointNames) : null;
883
- const matchers = [];
884
- for (const [key, endpoint] of typedEntries(contract.endpoints)) {
885
- if (selected && !selected.has(key))
886
- continue;
887
- if (endpoint.expose && !endpoint.expose.includes("HTTP")) {
888
- if (selected) {
889
- throw new Error(`Cannot create an HTTP route matcher for non-HTTP endpoint: ${String(key)}`);
890
- }
891
- continue;
892
- }
893
- matchers.push(createClientRouteMatcher(endpoint, contract.meta.prefix, contractConfig));
894
- }
895
- if (selected && matchers.length !== selected.size) {
896
- throw new Error("Cannot create an HTTP route matcher for an unknown endpoint");
897
- }
898
- return matchers;
899
- }
900
- function createClient(contract, configOrClient, contractConfig) {
901
- const client = {};
902
- const makeExecutor = isHttpAdapter(configOrClient) ? (endpoint) => createHttpExecutor(endpoint, contract.meta.prefix, configOrClient, contractConfig) : (endpoint) => createFetchExecutor(endpoint, contract.meta.prefix, configOrClient, contractConfig);
903
- for (const [key, endpoint] of typedEntries(contract.endpoints)) {
904
- if (endpoint.expose && !endpoint.expose.includes("HTTP"))
905
- continue;
906
- setClientMethod(client, key, createEndpointMethod(endpoint, makeExecutor(endpoint), contractConfig));
907
- }
908
- return client;
909
- }
910
- function createClients(contracts, configOrClient, contractConfig) {
911
- return mapObject(contracts, (_key, contract) => createClient(contract, configOrClient, contractConfig));
912
- }
913
- function buildScopedRegistry(contracts, scopeConfigs, surfaceName, build) {
914
- const registry = {};
915
- for (const [namespace, value] of Object.entries(contracts)) {
916
- const list = Array.isArray(value) ? value : [value];
917
- const surface = {};
918
- for (const contract of list) {
919
- const scope = contract.meta.scope;
920
- if (!scope) {
921
- throw new Error(`Contract in ${surfaceName} namespace "${namespace}" has no scope`);
922
- }
923
- const scopeConfig = scopeConfigs[scope];
924
- if (!scopeConfig) {
925
- throw new Error(`Missing ${surfaceName} config for scope: ${scope}`);
926
- }
927
- for (const [methodName, method] of Object.entries(build(contract, scopeConfig))) {
928
- if (Object.hasOwn(surface, methodName)) {
929
- throw new Error(`${surfaceName[0]?.toUpperCase()}${surfaceName.slice(1)} namespace "${namespace}" has duplicate method: ${methodName}`);
930
- }
931
- surface[methodName] = method;
932
- }
933
- }
934
- registry[namespace] = surface;
935
- }
936
- return registry;
937
- }
938
- function createScopedClients(contracts, configOrClient, scopeConfigs) {
939
- return buildScopedRegistry(contracts, scopeConfigs, "client", (contract, config) => createClient(contract, configOrClient, config));
940
- }
941
- function isHttpAdapter(value) {
942
- return typeof value === "object" && "get" in value && typeof value.get === "function";
943
- }
944
- function setClientMethod(target, key, method) {
945
- target[key] = method;
946
- }
947
- function createEndpointMethod(endpoint, execute, contractConfig) {
948
- const hasScopedArguments = (contractConfig?.stripPrefixKeys?.length ?? 0) > 0;
949
- if (endpointHasArguments(endpoint) || hasScopedArguments) {
950
- const method2 = (requestArgs) => settle(execute, readClientRequestArgs(requestArgs), undefined);
951
- return Object.assign(method2, {
952
- withOptions: (...args) => {
953
- refuseExtraWithOptionsArguments(endpoint, args.length, 2);
954
- return settle(execute, readClientRequestArgs(args[0]), readClientRequestOptions(args[1]));
955
- }
956
- });
957
- }
958
- const method = () => settle(execute, {}, undefined);
959
- return Object.assign(method, {
960
- withOptions: (...args) => {
961
- refuseExtraWithOptionsArguments(endpoint, args.length, 1);
962
- return settle(execute, {}, readClientRequestOptions(args[0]));
963
- }
964
- });
965
- }
966
- function settle(execute, requestArgs, options) {
967
- try {
968
- return execute(requestArgs, options);
969
- } catch (error) {
970
- return Promise.reject(error);
971
- }
972
- }
973
- function refuseExtraWithOptionsArguments(endpoint, received, expected) {
974
- if (received <= expected)
975
- return;
976
- const shape = expected === 1 ? "withOptions(options)" : "withOptions(args, options)";
977
- throw new TypeError(`${endpoint.method} ${endpoint.path}: this endpoint declares ${expected === 1 ? "no input" : "an input"}, so its method is ${shape} — it received ${received} arguments. ` + "An extra argument here is dropped, and a request options object in the dropped position " + "sends the request without them: an abort signal placed there never reaches the server.");
978
- }
979
- function createHttpExecutor(endpoint, prefix, client, config) {
980
- const httpMethod = endpoint.method.toLowerCase();
981
- return (requestArgs, options) => {
982
- const plan = planClientRequest(endpoint, prefix, requestArgs, config);
983
- const streamAbort = "stream" in endpoint ? new AbortController : undefined;
984
- const requestOptions = streamAbort ? {
985
- ...options,
986
- signal: options?.signal ? AbortSignal.any([options.signal, streamAbort.signal]) : streamAbort.signal
987
- } : options;
988
- const finishStream = streamAbort ? () => streamAbort.abort() : undefined;
989
- if (endpoint.multipart) {
990
- if (httpMethod === "get" || httpMethod === "head" || httpMethod === "delete") {
991
- throw new Error(`Multipart endpoint ${endpoint.method} ${endpoint.path} must be POST / PUT / PATCH`);
992
- }
993
- const formData = buildMultipartForm(endpoint.multipart, plan.remainingArgs);
994
- return withOutput(endpoint, client[httpMethod](plan.relativeUrl, formData, withTimeout(requestOptions, endpoint)), finishStream);
995
- }
996
- if (httpMethod === "get" || httpMethod === "head") {
997
- return withOutput(endpoint, client[httpMethod](plan.relativeUrl, withTimeout(requestOptions, endpoint)), finishStream);
998
- }
999
- if (httpMethod === "delete") {
1000
- return withOutput(endpoint, client.delete(plan.relativeUrl, withTimeout(requestOptions, endpoint)), finishStream);
1001
- }
1002
- return withOutput(endpoint, client[httpMethod](plan.relativeUrl, Object.keys(plan.remainingArgs).length > 0 ? plan.remainingArgs : undefined, withTimeout(requestOptions, endpoint)), finishStream);
1003
- };
1004
- }
1005
- function createFetchExecutor(endpoint, prefix, config, contractConfig) {
1006
- const executeFetch = config.fetch ?? globalThis.fetch;
1007
- return async (requestArgs, options) => {
1008
- const plan = planClientRequest(endpoint, prefix, requestArgs, contractConfig);
1009
- const url = joinClientBaseUrl(config.baseUrl, plan.relativeUrl);
1010
- const headers = {
1011
- Accept: "application/json",
1012
- ...typeof config.headers === "function" ? config.headers() : config.headers
1013
- };
1014
- const streamAbort = "stream" in endpoint ? new AbortController : undefined;
1015
- const requestSignal = streamAbort ? options?.signal ? AbortSignal.any([options.signal, streamAbort.signal]) : streamAbort.signal : options?.signal;
1016
- const openTimeoutMs = endpoint.timeout ?? config.timeout ?? 30000;
1017
- const cancellation = streamAbort ? {
1018
- signal: requestSignal,
1019
- async run(operation) {
1020
- let timedOut = false;
1021
- const timer = setTimeout(() => {
1022
- timedOut = true;
1023
- streamAbort.abort(new DOMException("Request timed out", "TimeoutError"));
1024
- }, openTimeoutMs);
1025
- try {
1026
- if (options?.signal?.aborted)
1027
- throw new RequestCancellationError("caller");
1028
- return await operation(requestSignal);
1029
- } catch (error) {
1030
- if (timedOut)
1031
- throw new RequestCancellationError("timeout");
1032
- if (options?.signal?.aborted)
1033
- throw new RequestCancellationError("caller");
1034
- throw error;
1035
- } finally {
1036
- clearTimeout(timer);
1037
- }
1038
- }
1039
- } : createRequestCancellation(requestSignal, openTimeoutMs);
1040
- const hasBody = endpoint.method !== "GET" && endpoint.method !== "HEAD" && endpoint.method !== "DELETE" && !endpoint.multipart && endpoint.input && Object.keys(plan.remainingArgs).length > 0;
1041
- if (hasBody)
1042
- headers["Content-Type"] = "application/json";
1043
- try {
1044
- return await cancellation.run(async (signal) => {
1045
- const body = endpoint.multipart ? buildMultipartForm(endpoint.multipart, plan.remainingArgs) : hasBody ? JSON.stringify(plan.remainingArgs) : undefined;
1046
- const res = await executeFetch(url, {
1047
- method: endpoint.method,
1048
- headers,
1049
- credentials: config.credentials,
1050
- signal,
1051
- ...body !== undefined && { body }
1052
- });
1053
- if (!res.ok) {
1054
- await throwForErrorResponse(res, config, { error: res.statusText });
1055
- }
1056
- if (endpoint.rawResponse)
1057
- return res;
1058
- if ("stream" in endpoint && endpoint.stream) {
1059
- return parseContractStream(res, endpoint.stream, () => streamAbort?.abort());
1060
- }
1061
- if (!endpoint.output) {
1062
- const text = await res.text();
1063
- if (text.length > 0) {
1064
- throw new Error("Server returned data for an endpoint with no output contract");
1065
- }
1066
- return;
1067
- }
1068
- return endpoint.output.parse(await res.json());
1069
- });
1070
- } catch (error) {
1071
- if (error instanceof RequestCancellationError) {
1072
- throw new ApiError(error.cause === "caller" ? "REQUEST_ABORTED" : "REQUEST_TIMEOUT", 0, undefined, error.message);
1073
- }
1074
- if (ApiError.is(error))
1075
- throw error;
1076
- const message = error instanceof Error ? error.message : undefined;
1077
- throw new ApiError("UNKNOWN_ERROR", 0, message ? { message } : undefined, message, undefined, undefined, { cause: error });
1078
- }
1079
- };
1080
- }
1081
- function endpointHasArguments(endpoint) {
1082
- return Boolean(endpoint.params || endpoint.input || endpoint.multipart);
1083
- }
1084
- function readClientRequestArgs(requestArgs) {
1085
- if (requestArgs !== undefined && !isRecord(requestArgs)) {
1086
- throw new TypeError("Endpoint arguments must be an object");
1087
- }
1088
- return requestArgs ?? {};
1089
- }
1090
- function readClientRequestOptions(value) {
1091
- if (!isRecord(value))
1092
- throw new TypeError("Client request options must be an object");
1093
- const signal = value.signal;
1094
- if (signal === undefined)
1095
- return {};
1096
- if (!isAbortSignal(signal)) {
1097
- throw new TypeError("Client request signal must be an AbortSignal");
1098
- }
1099
- return { signal };
1100
- }
1101
- function isAbortSignal(value) {
1102
- return typeof value === "object" && value !== null && "aborted" in value && typeof value.aborted === "boolean" && "addEventListener" in value && typeof value.addEventListener === "function" && "removeEventListener" in value && typeof value.removeEventListener === "function";
1103
- }
1104
- async function throwForErrorResponse(res, config, fallbackBody) {
1105
- const body = await res.json().catch(() => fallbackBody);
1106
- config.onError?.(res.status, body);
1107
- const parsed = parseApiErrorBody(body);
1108
- if (parsed) {
1109
- throw new ApiError(parsed.code, res.status, parsed.details, parsed.message, parsed.hint, responseTraceId(res));
1110
- }
1111
- throw new ApiError("HTTP_ERROR", res.status, { body }, undefined, undefined, responseTraceId(res));
1112
- }
1113
- function createUrlBuilder(contract, source, contractConfig) {
1114
- const builder = {};
1115
- for (const [key, endpoint] of typedEntries(contract.endpoints)) {
1116
- if (endpoint.expose && !endpoint.expose.includes("HTTP"))
1117
- continue;
1118
- setClientMethod(builder, key, (args) => {
1119
- const plan = planClientRequest(endpoint, contract.meta.prefix, args ?? {}, contractConfig);
1120
- if (endpoint.method !== "GET" && endpoint.method !== "DELETE" && Object.keys(plan.remainingArgs).length > 0) {
1121
- const fields = Object.keys(plan.remainingArgs).join(", ");
1122
- throw new Error(`URL builder for ${endpoint.method} ${endpoint.path} received non-URL fields: ${fields}`);
1123
- }
1124
- return joinClientBaseUrl(source.baseUrl, plan.relativeUrl);
1125
- });
1126
- }
1127
- return builder;
1128
- }
1129
- function createUrlBuilders(contracts, source, contractConfig) {
1130
- return mapObject(contracts, (_key, contract) => createUrlBuilder(contract, source, contractConfig));
1131
- }
1132
- function createScopedUrlBuilders(contracts, source, scopeConfigs) {
1133
- return buildScopedRegistry(contracts, scopeConfigs, "URL builder", (contract, config) => createUrlBuilder(contract, source, config));
1134
- }
1135
- // src/browser/resumable.ts
1136
- import { z as z2 } from "zod";
1137
- var PositiveSafeIntegerSchema = z2.number().int().positive().safe();
1138
- var BackoffPolicySchema = z2.object({
1139
- minDelayMs: PositiveSafeIntegerSchema,
1140
- maxDelayMs: PositiveSafeIntegerSchema,
1141
- jitter: z2.number().min(0).max(1)
1142
- }).strict().readonly().refine((policy) => policy.maxDelayMs >= policy.minDelayMs, {
1143
- message: "maxDelayMs must be at least minDelayMs"
1144
- });
1145
- function createBackoff(policy, random = Math.random) {
1146
- const { minDelayMs, maxDelayMs, jitter } = BackoffPolicySchema.parse(policy);
1147
- let attempt = 0;
1148
- return {
1149
- next() {
1150
- const exponential = Math.min(maxDelayMs, minDelayMs * 2 ** attempt);
1151
- attempt += 1;
1152
- const spread = exponential * jitter * random();
1153
- return Math.max(1, Math.round(exponential - spread));
1154
- },
1155
- reset() {
1156
- attempt = 0;
1157
- }
1158
- };
1159
- }
1160
- var DEFAULT_RETRY = { minDelayMs: 100, maxDelayMs: 30000, jitter: 0.5 };
1161
-
1162
- class ResumableAbortError extends Error {
1163
- constructor() {
1164
- super("Resumable iterator was aborted");
1165
- this.name = "ResumableAbortError";
1166
- }
1167
- }
1168
- function sleep(ms, signal) {
1169
- return new Promise((resolve, reject) => {
1170
- const timer = setTimeout(() => {
1171
- signal?.removeEventListener("abort", onAbort);
1172
- resolve();
1173
- }, ms);
1174
- function onAbort() {
1175
- clearTimeout(timer);
1176
- reject(new ResumableAbortError);
1177
- }
1178
- if (signal?.aborted) {
1179
- clearTimeout(timer);
1180
- reject(new ResumableAbortError);
1181
- return;
1182
- }
1183
- signal?.addEventListener("abort", onAbort, { once: true });
1184
- });
1185
- }
1186
- async function* resumableIterator(config) {
1187
- const backoff = createBackoff(config.retry ?? DEFAULT_RETRY, config.random);
1188
- let cursor;
1189
- let attempt = 0;
1190
- for (;; ) {
1191
- if (config.signal?.aborted)
1192
- return;
1193
- try {
1194
- const source = await config.open(cursor);
1195
- for await (const item of source) {
1196
- if (config.signal?.aborted)
1197
- return;
1198
- attempt = 0;
1199
- backoff.reset();
1200
- cursor = config.advance(item, cursor);
1201
- yield item;
1202
- if (config.isTerminal?.(item))
1203
- return;
1204
- }
1205
- throw new Error("Resumable source ended without a terminal item");
1206
- } catch (error) {
1207
- if (config.signal?.aborted || error instanceof ResumableAbortError)
1208
- return;
1209
- attempt += 1;
1210
- const delayMs = backoff.next();
1211
- config.onAttempt?.({ number: attempt, delayMs, error });
1212
- try {
1213
- await sleep(delayMs, config.signal);
1214
- } catch {
1215
- return;
1216
- }
1217
- }
1218
- }
1219
- }
1220
- // src/internal/optional-peer.ts
1221
- function isModuleNotFound(error) {
1222
- if (typeof error !== "object" || error === null)
1223
- return false;
1224
- const code = "code" in error ? error.code : undefined;
1225
- const message = "message" in error && typeof error.message === "string" ? error.message : "";
1226
- return code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND" || message.includes("Cannot find module") || message.includes("Cannot find package");
1227
- }
1228
-
1229
- // src/realtime/request.ts
1230
- import { z as z3 } from "zod";
1231
- var RealtimeRequestPhaseSchema = z3.enum([
1232
- "engine-handoff",
1233
- "engine-ack-received",
1234
- "settled",
1235
- "timeout",
1236
- "disconnected"
1237
- ]);
1238
- var RealtimeRequestPhaseEventSchema = z3.object({
1239
- requestId: z3.string().min(1),
1240
- event: z3.string().min(1),
1241
- phase: RealtimeRequestPhaseSchema,
1242
- elapsedMs: z3.number().finite().nonnegative()
1243
- }).strict();
1244
-
1245
- class RealtimeRequestTimeoutError extends Error {
1246
- code = "REALTIME_REQUEST_TIMEOUT";
1247
- event;
1248
- timeoutMs;
1249
- constructor(event, timeoutMs) {
1250
- super(`Realtime request "${event}" timed out after ${timeoutMs}ms`);
1251
- this.name = "RealtimeRequestTimeoutError";
1252
- this.event = event;
1253
- this.timeoutMs = timeoutMs;
1254
- }
1255
- }
1256
-
1257
- class RealtimeRequestDisconnectedError extends Error {
1258
- code = "REALTIME_REQUEST_DISCONNECTED";
1259
- event;
1260
- constructor(event) {
1261
- super(`Realtime request "${event}" was interrupted by disconnect`);
1262
- this.name = "RealtimeRequestDisconnectedError";
1263
- this.event = event;
1264
- }
1265
- }
1266
-
1267
- class RealtimeRequestInvalidAcknowledgementError extends Error {
1268
- code = "REALTIME_REQUEST_INVALID_ACKNOWLEDGEMENT";
1269
- event;
1270
- constructor(event, cause) {
1271
- super(`Realtime request "${event}" received an invalid acknowledgement`, { cause });
1272
- this.name = "RealtimeRequestInvalidAcknowledgementError";
1273
- this.event = event;
1274
- }
1275
- }
1276
-
1277
- class RealtimeRequestRejectedError extends Error {
1278
- code = "REALTIME_REQUEST_REJECTED";
1279
- event;
1280
- reason;
1281
- issues;
1282
- constructor(event, reason, detail, issues) {
1283
- super(`Realtime request "${event}" was rejected by the peer (${reason}): ${detail}`);
1284
- this.name = "RealtimeRequestRejectedError";
1285
- this.event = event;
1286
- this.reason = reason;
1287
- this.issues = issues;
1288
- }
1289
- }
1290
-
1291
- // src/realtime/rejected-frame.ts
1292
- var REALTIME_REJECTION_KEY = "@stitchkit/realtime-rejected";
1293
- var MAX_REJECTION_ISSUES = 20;
1294
- function realtimeRejectionEnvelope(report) {
1295
- return { [REALTIME_REJECTION_KEY]: report };
1296
- }
1297
- function asRealtimeRejection(value) {
1298
- if (typeof value !== "object" || value === null)
1299
- return null;
1300
- const report = Reflect.get(value, REALTIME_REJECTION_KEY);
1301
- if (typeof report !== "object" || report === null)
1302
- return null;
1303
- const event = Reflect.get(report, "event");
1304
- const reason = Reflect.get(report, "reason");
1305
- const message = Reflect.get(report, "message");
1306
- if (typeof event !== "string" || typeof reason !== "string" || typeof message !== "string") {
1307
- return null;
1308
- }
1309
- if (reason.length === 0)
1310
- return null;
1311
- const issues = parseIssues(Reflect.get(report, "issues"));
1312
- return { event, reason, message, ...issues !== undefined && { issues } };
1313
- }
1314
- function parseIssues(value) {
1315
- if (!Array.isArray(value))
1316
- return;
1317
- const issues = [];
1318
- for (const entry of value.slice(0, MAX_REJECTION_ISSUES)) {
1319
- if (typeof entry !== "object" || entry === null)
1320
- continue;
1321
- const path = Reflect.get(entry, "path");
1322
- const code = Reflect.get(entry, "code");
1323
- const message = Reflect.get(entry, "message");
1324
- if (typeof path === "string" && typeof code === "string" && typeof message === "string") {
1325
- issues.push({ path, code, message });
1326
- }
1327
- }
1328
- return issues.length > 0 ? issues : undefined;
1329
- }
1330
-
1331
- // src/realtime/rejection.ts
1332
- import { z as z4 } from "zod";
1333
- function realtimeContractViolation(options) {
1334
- const issues = options.cause instanceof z4.ZodError ? zodIssues(options.cause) : undefined;
1335
- const reason = options.reason.replaceAll("-", " ");
1336
- const error = new AppError("REALTIME_CONTRACT_VIOLATION", `Realtime event "${options.event}" (${options.direction}, ${options.phase}): ${reason}`, 500, {
1337
- event: options.event,
1338
- direction: options.direction,
1339
- phase: options.phase,
1340
- reason: options.reason,
1341
- fault: options.fault,
1342
- ...issues !== undefined && { issues }
1343
- });
1344
- if (options.cause !== undefined)
1345
- error.cause = options.cause;
1346
- return { ...options, error };
1347
- }
1348
-
1349
- // src/realtime/socket.ts
1350
- function method(target, name) {
1351
- const value = Reflect.get(target, name);
1352
- if (typeof value !== "function") {
1353
- throw new Error(`Realtime target does not implement ${name}()`);
1354
- }
1355
- return (...args) => Reflect.apply(value, target, args);
1356
- }
1357
- function splitWireArguments(definition, args) {
1358
- const trailing = args.at(-1);
1359
- const replyTo = typeof trailing === "function" ? (...callbackArgs) => Reflect.apply(trailing, undefined, callbackArgs) : undefined;
1360
- if (!definition.ack || !replyTo)
1361
- return { values: args, ...replyTo && { replyTo } };
1362
- return { values: args.slice(0, -1), acknowledgement: replyTo, replyTo };
1363
- }
1364
- function eventDefinition(registry, event, direction) {
1365
- const definition = registry[event];
1366
- if (!definition) {
1367
- throw realtimeContractViolation({
1368
- event,
1369
- direction,
1370
- phase: "arguments",
1371
- reason: "unknown-event",
1372
- fault: "local"
1373
- }).error;
1374
- }
1375
- return definition;
1376
- }
1377
- function reportRejected(rejected, hook, logger) {
1378
- if (!hook) {
1379
- if (logger) {
1380
- logger.warn(rejected.error.message, rejected.error.details);
1381
- return;
1382
- }
1383
- console.warn(`[stitchkit] rejected realtime ${rejected.direction} event "${rejected.event}" (${rejected.phase})`, rejected.error);
1384
- return;
1385
- }
1386
- Promise.resolve(hook(rejected)).catch((error) => {
1387
- console.error("[stitchkit] realtime rejection hook failed", error);
1388
- });
1389
- }
1390
- function answerWithRejection(acknowledgement, report, logger) {
1391
- if (!acknowledgement)
1392
- return;
1393
- try {
1394
- acknowledgement(realtimeRejectionEnvelope(report));
1395
- } catch (error) {
1396
- const message = "[stitchkit] could not answer a rejected realtime frame";
1397
- if (logger)
1398
- logger.warn(message, { error });
1399
- else
1400
- console.warn(message, error);
1401
- }
1402
- }
1403
- function parseRealtimeRequestArguments(registry, event, direction, args) {
1404
- const definition = eventDefinition(registry, event, direction);
1405
- const parsed = definition.args.safeParse(args);
1406
- if (!parsed.success) {
1407
- throw realtimeContractViolation({
1408
- event,
1409
- direction,
1410
- phase: "arguments",
1411
- reason: "invalid-arguments",
1412
- fault: "local",
1413
- cause: parsed.error
1414
- }).error;
1415
- }
1416
- if (!definition.ack) {
1417
- throw realtimeContractViolation({
1418
- event,
1419
- direction,
1420
- phase: "acknowledgement",
1421
- reason: "missing-acknowledgement",
1422
- fault: "local"
1423
- }).error;
1424
- }
1425
- return parsed.data;
1426
- }
1427
- function parseRealtimeRequestAcknowledgement(schema, event, direction, value, hook, logger) {
1428
- const refusal = asRealtimeRejection(value);
1429
- if (refusal) {
1430
- reportRejected(realtimeContractViolation({
1431
- event,
1432
- direction,
1433
- phase: "arguments",
1434
- reason: "rejected-by-peer",
1435
- fault: "local"
1436
- }), hook, logger);
1437
- throw new RealtimeRequestRejectedError(event, refusal.reason, refusal.message, refusal.issues);
1438
- }
1439
- const parsed = schema.safeParse(value);
1440
- if (parsed.success)
1441
- return parsed.data;
1442
- const rejected = realtimeContractViolation({
1443
- event,
1444
- direction,
1445
- phase: "acknowledgement",
1446
- reason: "invalid-acknowledgement-value",
1447
- fault: "peer",
1448
- cause: parsed.error
1449
- });
1450
- reportRejected(rejected, hook, logger);
1451
- throw new RealtimeRequestInvalidAcknowledgementError(event, rejected.error);
1452
- }
1453
- function createValidatedRealtimeSocket({
1454
- target,
1455
- inbound,
1456
- outbound,
1457
- inboundDirection,
1458
- outboundDirection,
1459
- onRejected,
1460
- logger,
1461
- subscribe
1462
- }) {
1463
- const emitTarget = method(target, "emit");
1464
- return {
1465
- on: (event, handler) => {
1466
- const definition = eventDefinition(inbound, event, inboundDirection);
1467
- const wrapped = (...wireArgs) => {
1468
- const { values, acknowledgement, replyTo } = splitWireArguments(definition, wireArgs);
1469
- const parsed = definition.args.safeParse(values);
1470
- if (!parsed.success) {
1471
- const rejected = realtimeContractViolation({
1472
- event,
1473
- direction: inboundDirection,
1474
- phase: "arguments",
1475
- reason: "invalid-arguments",
1476
- fault: "peer",
1477
- cause: parsed.error
1478
- });
1479
- reportRejected(rejected, onRejected, logger);
1480
- answerWithRejection(replyTo, {
1481
- event,
1482
- reason: "invalid-arguments",
1483
- message: rejected.error.message,
1484
- issues: zodIssues(parsed.error).slice(0, MAX_REJECTION_ISSUES)
1485
- }, logger);
1486
- return;
1487
- }
1488
- if (definition.ack && !acknowledgement) {
1489
- reportRejected(realtimeContractViolation({
1490
- event,
1491
- direction: inboundDirection,
1492
- phase: "acknowledgement",
1493
- reason: "missing-acknowledgement",
1494
- fault: "peer"
1495
- }), onRejected, logger);
1496
- return;
1497
- }
1498
- const applicationArgs = [...parsed.data];
1499
- if (definition.ack) {
1500
- applicationArgs.push((value) => {
1501
- const ack = definition.ack?.safeParse(value);
1502
- if (!ack?.success) {
1503
- if (ack) {
1504
- reportRejected(realtimeContractViolation({
1505
- event,
1506
- direction: outboundDirection,
1507
- phase: "acknowledgement",
1508
- reason: "invalid-acknowledgement-value",
1509
- fault: "local",
1510
- cause: ack.error
1511
- }), onRejected, logger);
1512
- }
1513
- return;
1514
- }
1515
- acknowledgement?.(ack.data);
1516
- });
1517
- }
1518
- Reflect.apply(handler, undefined, applicationArgs);
1519
- };
1520
- if (subscribe)
1521
- return subscribe(event, wrapped);
1522
- const onTarget = method(target, "on");
1523
- const offTarget = method(target, "off");
1524
- onTarget(event, wrapped);
1525
- return () => {
1526
- offTarget(event, wrapped);
1527
- };
1528
- },
1529
- emit: (event, ...args) => {
1530
- const definition = eventDefinition(outbound, event, outboundDirection);
1531
- const { values, acknowledgement } = splitWireArguments(definition, args);
1532
- const parsed = definition.args.safeParse(values);
1533
- if (!parsed.success) {
1534
- throw realtimeContractViolation({
1535
- event,
1536
- direction: outboundDirection,
1537
- phase: "arguments",
1538
- reason: "invalid-arguments",
1539
- fault: "local",
1540
- cause: parsed.error
1541
- }).error;
1542
- }
1543
- if (definition.ack && !acknowledgement) {
1544
- throw realtimeContractViolation({
1545
- event,
1546
- direction: outboundDirection,
1547
- phase: "acknowledgement",
1548
- reason: "missing-acknowledgement",
1549
- fault: "local"
1550
- }).error;
1551
- }
1552
- const wireArgs = [...parsed.data];
1553
- if (definition.ack && acknowledgement) {
1554
- wireArgs.push((value) => {
1555
- const refusal = asRealtimeRejection(value);
1556
- if (refusal) {
1557
- reportRejected(realtimeContractViolation({
1558
- event,
1559
- direction: outboundDirection,
1560
- phase: "arguments",
1561
- reason: "rejected-by-peer",
1562
- fault: "local"
1563
- }), onRejected, logger);
1564
- return;
1565
- }
1566
- const ack = definition.ack?.safeParse(value);
1567
- if (!ack?.success) {
1568
- if (ack) {
1569
- reportRejected(realtimeContractViolation({
1570
- event,
1571
- direction: inboundDirection,
1572
- phase: "acknowledgement",
1573
- reason: "invalid-acknowledgement-value",
1574
- fault: "peer",
1575
- cause: ack.error
1576
- }), onRejected, logger);
1577
- }
1578
- return;
1579
- }
1580
- acknowledgement(ack.data);
1581
- });
1582
- }
1583
- return emitTarget(event, ...wireArgs) !== false;
1584
- }
1585
- };
1586
- }
1587
-
82
+ } from "./index-0w9abg87.js";
83
+ import"./index-kzfs85xp.js";
84
+ import"./index-77fekveh.js";
1588
85
  // src/retained.ts
1589
86
  function createRetainedTopics() {
1590
87
  const last = {};
@@ -2066,26 +563,6 @@ function createSocketIOClientInternal(config, onRequestPhase) {
2066
563
  }
2067
564
  };
2068
565
  }
2069
- // src/realtime/contract.ts
2070
- import { z as z5 } from "zod";
2071
- function defineRealtimeContract(contract) {
2072
- return contract;
2073
- }
2074
- var RealtimeRejectDirectionSchema = z5.enum([
2075
- "client-inbound",
2076
- "client-outbound",
2077
- "server-inbound",
2078
- "server-outbound"
2079
- ]);
2080
- var RealtimeRejectPhaseSchema = z5.enum(["arguments", "acknowledgement"]);
2081
- var RealtimeRejectReasonSchema = z5.enum([
2082
- "unknown-event",
2083
- "invalid-arguments",
2084
- "invalid-acknowledgement-value",
2085
- "missing-acknowledgement",
2086
- "rejected-by-peer"
2087
- ]);
2088
- var RealtimeRejectFaultSchema = z5.enum(["peer", "local"]);
2089
566
  export {
2090
567
  zodIssues,
2091
568
  unauthorized,