@orpc/server 2.0.0-beta.2 → 2.0.0-beta.21

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 (46) hide show
  1. package/README.md +32 -21
  2. package/dist/adapters/crossws/index.d.mts +11 -8
  3. package/dist/adapters/crossws/index.d.ts +11 -8
  4. package/dist/adapters/crossws/index.mjs +10 -7
  5. package/dist/adapters/fetch/index.d.mts +8 -56
  6. package/dist/adapters/fetch/index.d.ts +8 -56
  7. package/dist/adapters/fetch/index.mjs +6 -136
  8. package/dist/adapters/message-port/index.d.mts +11 -13
  9. package/dist/adapters/message-port/index.d.ts +11 -13
  10. package/dist/adapters/message-port/index.mjs +28 -32
  11. package/dist/adapters/node/index.d.mts +7 -37
  12. package/dist/adapters/node/index.d.ts +7 -37
  13. package/dist/adapters/node/index.mjs +6 -112
  14. package/dist/adapters/standard/index.d.mts +6 -6
  15. package/dist/adapters/standard/index.d.ts +6 -6
  16. package/dist/adapters/standard/index.mjs +3 -3
  17. package/dist/adapters/standard-peer/index.d.mts +2 -2
  18. package/dist/adapters/standard-peer/index.d.ts +2 -2
  19. package/dist/adapters/websocket/index.d.mts +36 -26
  20. package/dist/adapters/websocket/index.d.ts +36 -26
  21. package/dist/adapters/websocket/index.mjs +33 -25
  22. package/dist/extensions/callable.d.mts +1 -1
  23. package/dist/extensions/callable.d.ts +1 -1
  24. package/dist/extensions/callable.mjs +2 -2
  25. package/dist/helpers/index.d.mts +3 -3
  26. package/dist/helpers/index.d.ts +3 -3
  27. package/dist/helpers/index.mjs +13 -5
  28. package/dist/index.d.mts +19 -16
  29. package/dist/index.d.ts +19 -16
  30. package/dist/index.mjs +36 -22
  31. package/dist/plugins/index.d.mts +136 -5
  32. package/dist/plugins/index.d.ts +136 -5
  33. package/dist/plugins/index.mjs +394 -6
  34. package/dist/shared/{server.BsNNjG5J.d.mts → server.15O7oC1p.d.mts} +1 -1
  35. package/dist/shared/{server.B_U9y00a.d.mts → server.B4BnEWWm.d.mts} +6 -5
  36. package/dist/shared/{server.EOHJ3NJr.d.ts → server.BhsVw7m7.d.ts} +2 -2
  37. package/dist/shared/{server.BwHnWUuN.mjs → server.BoiFpNT7.mjs} +4 -2
  38. package/dist/shared/{server.GDpX6Df8.mjs → server.COPVXhDG.mjs} +3 -3
  39. package/dist/shared/{server.BL22TloH.d.mts → server.CcR4kgje.d.mts} +25 -3
  40. package/dist/shared/{server.BL22TloH.d.ts → server.CcR4kgje.d.ts} +25 -3
  41. package/dist/shared/{server.T9F3bzZx.d.ts → server.CnN50DHH.d.ts} +6 -5
  42. package/dist/shared/{server.CjOb6ItT.mjs → server.DBs0rrf9.mjs} +1 -1
  43. package/dist/shared/{server.BB_Ik9Ph.d.mts → server.DDFizwfU.d.mts} +2 -2
  44. package/dist/shared/{server.CrlKQucM.mjs → server.DofEOwf-.mjs} +11 -7
  45. package/dist/shared/{server.Pa0F03f_.d.ts → server.m3szVJGU.d.ts} +1 -1
  46. package/package.json +9 -10
@@ -1,9 +1,9 @@
1
- import { toArray, value } from '@orpc/shared';
2
- import { flattenStandardHeader, parseStandardUrl, mergeStandardHeaders } from '@standardserver/core';
1
+ import { toArray, value, isCompressibleContentType, isAsyncIteratorObject, stringifyJSON } from '@orpc/shared';
2
+ import { flattenStandardHeader, parseStandardUrl, generateContentDisposition, mergeStandardHeaders } from '@standardserver/core';
3
3
  import { isClientPeerSendMessage, ServerPeer, encodePeerMessage } from '@standardserver/peer';
4
4
  export { C as CSRFGuardHandlerPlugin } from '../shared/server.D_QauotT.mjs';
5
- import { toFetchHeaders, toStandardHeaders } from '@standardserver/fetch';
6
- import '@orpc/client';
5
+ import { toFetchHeaders, toStandardBody, toStandardHeaders } from '@standardserver/fetch';
6
+ import { ORPCError } from '@orpc/client';
7
7
 
8
8
  class BatchHandlerPlugin {
9
9
  name = "~batch";
@@ -16,6 +16,8 @@ class BatchHandlerPlugin {
16
16
  mapSubrequest;
17
17
  successStatus;
18
18
  headers;
19
+ keepAliveEnabled;
20
+ keepAliveInterval;
19
21
  constructor(options = {}) {
20
22
  this.maxSize = options.maxSize ?? 10;
21
23
  this.mapSubrequest = options.mapSubrequest ?? ((subRequest, { request: batchRequest }) => ({
@@ -29,6 +31,8 @@ class BatchHandlerPlugin {
29
31
  }));
30
32
  this.successStatus = options.successStatus ?? 207;
31
33
  this.headers = options.headers ?? {};
34
+ this.keepAliveEnabled = options.keepAlive?.enabled ?? true;
35
+ this.keepAliveInterval = options.keepAlive?.interval ?? 15e3;
32
36
  }
33
37
  init(options) {
34
38
  const routingInterceptor = async (interceptorOptions) => {
@@ -127,9 +131,35 @@ class BatchHandlerPlugin {
127
131
  };
128
132
  }
129
133
  let streamController;
134
+ let keepAliveTimer;
135
+ const clearKeepAlive = () => {
136
+ if (keepAliveTimer !== void 0) {
137
+ clearInterval(keepAliveTimer);
138
+ keepAliveTimer = void 0;
139
+ }
140
+ };
141
+ const scheduleKeepAlive = () => {
142
+ if (!this.keepAliveEnabled) {
143
+ return;
144
+ }
145
+ clearKeepAlive();
146
+ keepAliveTimer = setInterval(() => {
147
+ try {
148
+ const lengthBuffer = new ArrayBuffer(4);
149
+ new DataView(lengthBuffer).setUint32(0, 0, false);
150
+ streamController.enqueue(new Uint8Array(lengthBuffer));
151
+ } catch {
152
+ clearKeepAlive();
153
+ }
154
+ }, this.keepAliveInterval);
155
+ };
130
156
  const stream = new ReadableStream({
131
157
  start(controller) {
132
158
  streamController = controller;
159
+ scheduleKeepAlive();
160
+ },
161
+ cancel() {
162
+ clearKeepAlive();
133
163
  }
134
164
  });
135
165
  const peer = new ServerPeer(async (message) => {
@@ -139,11 +169,14 @@ class BatchHandlerPlugin {
139
169
  new DataView(lengthBuffer).setUint32(0, bytes.byteLength, false);
140
170
  streamController.enqueue(new Uint8Array(lengthBuffer));
141
171
  streamController.enqueue(bytes);
172
+ scheduleKeepAlive();
142
173
  });
143
174
  Promise.all(messages.map((msg) => peer.message(msg, handleIndividualRequest))).then(async () => {
175
+ clearKeepAlive();
144
176
  streamController.close();
145
177
  await peer.close();
146
178
  }).catch(async (error) => {
179
+ clearKeepAlive();
147
180
  streamController.error(error);
148
181
  await peer.close(error);
149
182
  });
@@ -193,7 +226,10 @@ class CORSHandlerPlugin {
193
226
  if (allowedOrigins.includes(origin)) {
194
227
  resHeaders["access-control-allow-origin"] = origin;
195
228
  }
196
- resHeaders.vary = interceptorOptions.request.headers.vary ?? "origin";
229
+ const existingVary = flattenStandardHeader(resHeaders.vary);
230
+ if (!existingVary?.split(",").some((v) => v.trim().toLowerCase() === "origin")) {
231
+ resHeaders.vary = existingVary ? `${existingVary}, Origin` : "Origin";
232
+ }
197
233
  }
198
234
  const allowedTimingOrigins = toArray(await value(this.options.timingOrigin, origin, interceptorOptions));
199
235
  if (allowedTimingOrigins.includes("*")) {
@@ -244,6 +280,69 @@ class CORSHandlerPlugin {
244
280
  }
245
281
  }
246
282
 
283
+ class RequestCompressionHandlerPlugin {
284
+ name = "~request-compression";
285
+ /**
286
+ * Should decompress the original batch request body instead of sub-requests.
287
+ */
288
+ after = ["~batch"];
289
+ init(options) {
290
+ const routingInterceptor = async ({ next, ...interceptorOptions }) => {
291
+ const encodings = parseContentEncodings(
292
+ flattenStandardHeader(interceptorOptions.request.headers["content-encoding"])
293
+ );
294
+ if (encodings.length === 0 || !encodings.every(isSupportedEncoding)) {
295
+ return next();
296
+ }
297
+ const decompressedHeaders = {
298
+ ...interceptorOptions.request.headers,
299
+ "content-length": void 0,
300
+ "content-encoding": void 0
301
+ };
302
+ return next({
303
+ ...interceptorOptions,
304
+ request: {
305
+ ...interceptorOptions.request,
306
+ headers: decompressedHeaders,
307
+ async resolveBody(hint) {
308
+ const stream = await interceptorOptions.request.resolveBody("octet-stream");
309
+ if (!(stream instanceof ReadableStream)) {
310
+ return stream;
311
+ }
312
+ let decompressedStream = stream;
313
+ for (let i = encodings.length - 1; i >= 0; i--) {
314
+ decompressedStream = decompressedStream.pipeThrough(
315
+ new DecompressionStream(encodings[i])
316
+ );
317
+ }
318
+ const response = new Response(decompressedStream, {
319
+ headers: toFetchHeaders(decompressedHeaders)
320
+ });
321
+ return toStandardBody(response, { hint });
322
+ }
323
+ }
324
+ });
325
+ };
326
+ return {
327
+ ...options,
328
+ routingInterceptors: [
329
+ routingInterceptor,
330
+ ...toArray(options.routingInterceptors)
331
+ ]
332
+ };
333
+ }
334
+ }
335
+ const SUPPORTED_ENCODINGS = ["gzip", "deflate", "deflate-raw"];
336
+ function isSupportedEncoding(encoding) {
337
+ return SUPPORTED_ENCODINGS.includes(encoding);
338
+ }
339
+ function parseContentEncodings(header) {
340
+ if (header === void 0) {
341
+ return [];
342
+ }
343
+ return header.split(",").map((part) => part.trim().toLowerCase());
344
+ }
345
+
247
346
  class RequestHeadersHandlerPlugin {
248
347
  name = "~request-headers";
249
348
  init(options) {
@@ -266,6 +365,243 @@ class RequestHeadersHandlerPlugin {
266
365
  }
267
366
  }
268
367
 
368
+ class RequestLimitHandlerPlugin {
369
+ name = "~request-limit";
370
+ /**
371
+ * Should limit the original batch request body instead of sub-requests.
372
+ */
373
+ after = ["~batch"];
374
+ /**
375
+ * Should limit the final body size instead of the compressed one.
376
+ */
377
+ before = ["~request-compression"];
378
+ maxBodySize;
379
+ constructor(options) {
380
+ this.maxBodySize = options.maxBodySize;
381
+ }
382
+ init(options) {
383
+ const maxBodySize = this.maxBodySize;
384
+ const routingInterceptor = async ({ next, ...interceptorOptions }) => {
385
+ return next({
386
+ ...interceptorOptions,
387
+ request: {
388
+ ...interceptorOptions.request,
389
+ async resolveBody(hint) {
390
+ const contentLength = Number(
391
+ flattenStandardHeader(interceptorOptions.request.headers["content-length"])
392
+ );
393
+ if (Number.isFinite(contentLength) && contentLength > maxBodySize) {
394
+ throw new ORPCError("PAYLOAD_TOO_LARGE");
395
+ }
396
+ const stream = await interceptorOptions.request.resolveBody("octet-stream");
397
+ if (!(stream instanceof ReadableStream)) {
398
+ return stream;
399
+ }
400
+ let currentBodySize = 0;
401
+ const limitedStream = stream.pipeThrough(
402
+ new TransformStream({
403
+ transform(chunk, controller) {
404
+ currentBodySize += chunk.byteLength;
405
+ if (currentBodySize > maxBodySize) {
406
+ controller.error(new ORPCError("PAYLOAD_TOO_LARGE"));
407
+ return;
408
+ }
409
+ controller.enqueue(chunk);
410
+ }
411
+ })
412
+ );
413
+ const response = new Response(limitedStream, {
414
+ headers: toFetchHeaders(interceptorOptions.request.headers)
415
+ });
416
+ return toStandardBody(response, { hint });
417
+ }
418
+ }
419
+ });
420
+ };
421
+ return {
422
+ ...options,
423
+ routingInterceptors: [
424
+ routingInterceptor,
425
+ ...toArray(options.routingInterceptors)
426
+ ]
427
+ };
428
+ }
429
+ }
430
+
431
+ const AVG_BYTES_PER_CHAR = 1.2;
432
+ class ResponseCompressionHandlerPlugin {
433
+ name = "~response-compression";
434
+ /**
435
+ * Compression should be done after batching, to compress the final response.
436
+ * Compression should also be done after response headers are set, to access final headers like Content-Type and Cache-Control.
437
+ */
438
+ after = ["~batch", "~response-headers"];
439
+ encodings;
440
+ threshold;
441
+ constructor(options = {}) {
442
+ this.encodings = options.encodings ?? ["gzip", "deflate"];
443
+ this.threshold = options.threshold ?? 1024;
444
+ }
445
+ init(options) {
446
+ const routingInterceptor = async ({ next, ...interceptorOptions }) => {
447
+ const result = await next();
448
+ if (!result.matched) {
449
+ return result;
450
+ }
451
+ const response = result.response;
452
+ const contentEncoding = flattenStandardHeader(response.headers["content-encoding"])?.trim()?.toLowerCase();
453
+ if (contentEncoding !== void 0) {
454
+ return result;
455
+ }
456
+ if (isNoTransformCacheControl(flattenStandardHeader(response.headers["cache-control"]))) {
457
+ return result;
458
+ }
459
+ const acceptEncodings = parseAcceptEncodings(
460
+ flattenStandardHeader(interceptorOptions.request.headers["accept-encoding"])
461
+ );
462
+ const encoding = this.encodings.find((enc) => acceptEncodings.includes(enc));
463
+ if (encoding === void 0) {
464
+ return result;
465
+ }
466
+ const body = response.body;
467
+ const headers = response.headers;
468
+ if (body instanceof ReadableStream) {
469
+ const contentLength = Number(flattenStandardHeader(headers["content-length"]));
470
+ if ((!Number.isFinite(contentLength) || contentLength >= this.threshold) && isCompressibleContentType(flattenStandardHeader(headers["content-type"]))) {
471
+ return {
472
+ ...result,
473
+ response: {
474
+ ...response,
475
+ body: body.pipeThrough(new CompressionStream(encoding)),
476
+ headers: {
477
+ ...headers,
478
+ "standard-server": "octet-stream",
479
+ "content-length": [],
480
+ "content-encoding": encoding
481
+ }
482
+ }
483
+ };
484
+ }
485
+ } else if (body instanceof Blob) {
486
+ if ((!Number.isFinite(body.size) || body.size >= this.threshold) && isCompressibleContentType(body.type)) {
487
+ const contentDisposition = headers["content-disposition"] ?? generateContentDisposition(
488
+ body instanceof File ? body.name : "blob"
489
+ );
490
+ return {
491
+ ...result,
492
+ response: {
493
+ ...response,
494
+ body: body.stream().pipeThrough(new CompressionStream(encoding)),
495
+ headers: {
496
+ ...headers,
497
+ "standard-server": "file",
498
+ "content-type": body.type,
499
+ "content-length": [],
500
+ "content-disposition": contentDisposition,
501
+ "content-encoding": encoding
502
+ }
503
+ }
504
+ };
505
+ }
506
+ } else if (body instanceof FormData) {
507
+ const PART_OVERHEAD = 64;
508
+ let contentLength = 0;
509
+ for (const [key, value] of body) {
510
+ contentLength += PART_OVERHEAD + key.length;
511
+ if (value instanceof Blob) {
512
+ if (!Number.isFinite(value.size)) {
513
+ if (!isCompressibleContentType(value.type)) {
514
+ contentLength = -Infinity;
515
+ break;
516
+ }
517
+ contentLength = Infinity;
518
+ } else {
519
+ contentLength += isCompressibleContentType(value.type) ? value.size : -value.size;
520
+ }
521
+ } else {
522
+ contentLength += value.length * AVG_BYTES_PER_CHAR;
523
+ }
524
+ }
525
+ if (contentLength >= this.threshold) {
526
+ const res = new Response(body);
527
+ const compressedStream = res.body.pipeThrough(new CompressionStream(encoding));
528
+ return {
529
+ ...result,
530
+ response: {
531
+ ...response,
532
+ body: compressedStream,
533
+ headers: {
534
+ ...headers,
535
+ "standard-server": [],
536
+ "content-type": res.headers.get("content-type"),
537
+ "content-length": [],
538
+ "content-encoding": encoding
539
+ }
540
+ }
541
+ };
542
+ }
543
+ } else if (body instanceof URLSearchParams) {
544
+ const string = body.toString();
545
+ if (string.length * AVG_BYTES_PER_CHAR >= this.threshold) {
546
+ return {
547
+ ...result,
548
+ response: {
549
+ ...response,
550
+ body: new Blob([string]).stream().pipeThrough(new CompressionStream(encoding)),
551
+ headers: {
552
+ ...headers,
553
+ "standard-server": [],
554
+ "content-type": "application/x-www-form-urlencoded",
555
+ "content-length": [],
556
+ "content-encoding": encoding
557
+ }
558
+ }
559
+ };
560
+ }
561
+ } else if (body !== void 0 && !isAsyncIteratorObject(body)) {
562
+ const string = stringifyJSON(body);
563
+ if (string.length * AVG_BYTES_PER_CHAR >= this.threshold) {
564
+ return {
565
+ ...result,
566
+ response: {
567
+ ...response,
568
+ body: new Blob([string]).stream().pipeThrough(new CompressionStream(encoding)),
569
+ headers: {
570
+ ...headers,
571
+ "standard-server": [],
572
+ "content-type": "application/json",
573
+ "content-length": [],
574
+ "content-encoding": encoding
575
+ }
576
+ }
577
+ };
578
+ }
579
+ }
580
+ return result;
581
+ };
582
+ return {
583
+ ...options,
584
+ routingInterceptors: [
585
+ routingInterceptor,
586
+ ...toArray(options.routingInterceptors)
587
+ ]
588
+ };
589
+ }
590
+ }
591
+ function parseAcceptEncodings(header) {
592
+ if (header === void 0) {
593
+ return [];
594
+ }
595
+ return header.split(",").map((part) => part.trim().split(";")[0].trim().toLowerCase()).filter(Boolean);
596
+ }
597
+ const CACHE_CONTROL_NO_TRANSFORM_REGEX = /(?:^|,)\s*no-transform\s*(?:,|$)/i;
598
+ function isNoTransformCacheControl(cacheControl) {
599
+ if (cacheControl === void 0) {
600
+ return false;
601
+ }
602
+ return CACHE_CONTROL_NO_TRANSFORM_REGEX.test(cacheControl);
603
+ }
604
+
269
605
  class ResponseHeadersHandlerPlugin {
270
606
  name = "~response-headers";
271
607
  /**
@@ -302,4 +638,56 @@ class ResponseHeadersHandlerPlugin {
302
638
  }
303
639
  }
304
640
 
305
- export { BatchHandlerPlugin, CORSHandlerPlugin, RequestHeadersHandlerPlugin, ResponseHeadersHandlerPlugin };
641
+ class RethrowHandlerPlugin {
642
+ name = "~rethrow";
643
+ filter;
644
+ CONTEXT_SYMBOL = Symbol("ORPC_RETHROW_HANDLER_PLUGIN_CONTEXT");
645
+ constructor(options) {
646
+ this.filter = options.filter;
647
+ }
648
+ init(options) {
649
+ const routingInterceptor = async (options2) => {
650
+ const pluginContext = {};
651
+ const result = await options2.next({
652
+ ...options2,
653
+ context: {
654
+ ...options2.context,
655
+ [this.CONTEXT_SYMBOL]: pluginContext
656
+ }
657
+ });
658
+ if (pluginContext.error) {
659
+ throw pluginContext.error.value;
660
+ }
661
+ return result;
662
+ };
663
+ const interceptor = async (options2) => {
664
+ const pluginContext = options2.context[this.CONTEXT_SYMBOL];
665
+ if (!pluginContext) {
666
+ throw new TypeError("[RethrowHandlerPlugin] Rethrow handler context has been corrupted or modified by another plugin or interceptor");
667
+ }
668
+ try {
669
+ return await options2.next();
670
+ } catch (error) {
671
+ if (this.filter(error, options2)) {
672
+ pluginContext.error = { value: error };
673
+ }
674
+ throw error;
675
+ }
676
+ };
677
+ return {
678
+ ...options,
679
+ routingInterceptors: [
680
+ ...toArray(options.routingInterceptors),
681
+ routingInterceptor
682
+ // rethrow as early as possible and keep it close to `interceptor` to avoid a corrupted or modified context
683
+ ],
684
+ interceptors: [
685
+ interceptor,
686
+ // catch as many errors as possible
687
+ ...toArray(options.interceptors)
688
+ ]
689
+ };
690
+ }
691
+ }
692
+
693
+ export { BatchHandlerPlugin, CORSHandlerPlugin, RequestCompressionHandlerPlugin, RequestHeadersHandlerPlugin, RequestLimitHandlerPlugin, ResponseCompressionHandlerPlugin, ResponseHeadersHandlerPlugin, RethrowHandlerPlugin };
@@ -1,5 +1,5 @@
1
1
  import { RouterContract, ProcedureContract, ORPCErrorFromErrorMap, ThrowableError, InferSchemaInput, InferSchemaOutput } from '@orpc/contract';
2
- import { C as Context, a as Procedure, L as Lazyable, M as MergedContext } from './server.BL22TloH.mjs';
2
+ import { C as Context, a as Procedure, L as Lazyable, M as MergedContext } from './server.CcR4kgje.mjs';
3
3
 
4
4
  type Router<TInitialContext extends Context> = Procedure<TInitialContext, any, any, any, any, any> | {
5
5
  [k: string]: Lazyable<Router<TInitialContext>>;
@@ -1,10 +1,10 @@
1
1
  import { RPCSerializer, AnyORPCError } from '@orpc/client';
2
2
  import { Value, Promisable } from '@orpc/shared';
3
3
  import { StandardMethod, StandardLazyRequest, StandardResponse } from '@standardserver/core';
4
- import { A as AnyProcedure, C as Context } from './server.BL22TloH.mjs';
5
- import { A as AnyRouter } from './server.BsNNjG5J.mjs';
4
+ import { A as AnyProcedure, C as Context } from './server.CcR4kgje.mjs';
5
+ import { A as AnyRouter } from './server.15O7oC1p.mjs';
6
6
  import { AnyProcedureContract } from '@orpc/contract';
7
- import { b as StandardHandlerHandleOptions, c as StandardHandlerCodec, d as StandardHandlerCodecResolvedProcedure } from './server.BB_Ik9Ph.mjs';
7
+ import { b as StandardHandlerHandleOptions, c as StandardHandlerCodec, d as StandardHandlerCodecResolvedProcedure } from './server.DDFizwfU.mjs';
8
8
 
9
9
  interface RPCMatcherOptions {
10
10
  /**
@@ -38,14 +38,15 @@ interface RPCHandlerCodecOptions<T extends Context> extends RPCMatcherOptions {
38
38
  /**
39
39
  * Resolve HTTP status for encoded successful outputs.
40
40
  *
41
- * Value should be in range `200-299`
41
+ * Value should be in the `2xx` range and must be less than `400`.
42
42
  * Return `undefined` or `null` to fallback to default
43
43
  *
44
- * @default DEFAULT_ERROR_STATUS, DEFAULT_ERROR_STATUS
44
+ * @default DEFAULT_SUCCESS_STATUS (200)
45
45
  */
46
46
  outputStatus?: Value<number | undefined | null, [output: unknown, procedure: AnyProcedure, path: string[], options: StandardHandlerHandleOptions<T>]>;
47
47
  /**
48
48
  * Mapping ORPCError Code -> HTTP Status Code
49
+ * The status code should be in the `4xx` or `5xx` range (must be greater than or equal to `400`).
49
50
  *
50
51
  * @default COMMON_ERROR_STATUS_MAP
51
52
  */
@@ -1,7 +1,7 @@
1
1
  import { AnyORPCError } from '@orpc/client';
2
2
  import { OrderablePlugin, Interceptor, Promisable } from '@orpc/shared';
3
3
  import { StandardLazyRequest, StandardResponse } from '@standardserver/core';
4
- import { C as Context, c as ProcedureClientInterceptor, A as AnyProcedure } from './server.BL22TloH.js';
4
+ import { C as Context, c as ProcedureClientInterceptor, A as AnyProcedure } from './server.CcR4kgje.js';
5
5
  import { Schema, ErrorMap } from '@orpc/contract';
6
6
 
7
7
  interface StandardHandlerPlugin<T extends Context> extends OrderablePlugin {
@@ -101,4 +101,4 @@ interface StandardHandlerCodec<T extends Context> {
101
101
  }
102
102
 
103
103
  export { CompositeStandardHandlerPlugin as C, OtelHandlerPlugin as O, StandardHandler as S };
104
- export type { StandardHandlerOptions as a, StandardHandlerHandleOptions as b, StandardHandlerCodec as c, StandardHandlerCodecResolvedProcedure as d, StandardHandlerPlugin as e, StandardHandlerRoutingInterceptorOptions as f, StandardHandlerHandleResult as g, StandardHandlerInterceptor as h, StandardHandlerInterceptorOptions as i, StandardHandlerRoutingInterceptor as j };
104
+ export type { StandardHandlerOptions as a, StandardHandlerHandleOptions as b, StandardHandlerCodec as c, StandardHandlerCodecResolvedProcedure as d, StandardHandlerPlugin as e, StandardHandlerRoutingInterceptorOptions as f, StandardHandlerInterceptorOptions as g, StandardHandlerHandleResult as h, StandardHandlerInterceptor as i, StandardHandlerRoutingInterceptor as j };
@@ -1,6 +1,6 @@
1
- import { c as createProcedureClient, P as Procedure, L as Lazy, u as unlazy } from './server.CrlKQucM.mjs';
1
+ import { c as createProcedureClient, P as Procedure, L as Lazy, u as unlazy } from './server.DofEOwf-.mjs';
2
2
  import { resolveMetaPlugins, mergeErrorMap, ProcedureContract } from '@orpc/contract';
3
- import { getOrBind, isTypescriptObject } from '@orpc/shared';
3
+ import { getOrBind, omit, isTypescriptObject } from '@orpc/shared';
4
4
 
5
5
  const DEFAULT_SUCCESS_STATUS = 200;
6
6
  const DEFAULT_ERROR_STATUS = 500;
@@ -77,6 +77,7 @@ function augmentRouter(router, options) {
77
77
  router["~orpc"].metaPlugins
78
78
  );
79
79
  const enhanced2 = new Procedure({
80
+ ...omit(options, ["middlewares", "errorMap", "meta", "metaPlugins"]),
80
81
  ...router["~orpc"],
81
82
  meta,
82
83
  metaPlugins,
@@ -111,6 +112,7 @@ function augmentImplementedRouter(router, options) {
111
112
  }
112
113
  if (router instanceof Procedure) {
113
114
  const enhanced2 = new Procedure({
115
+ ...omit(options, ["middlewares"]),
114
116
  ...router["~orpc"],
115
117
  orderedMiddlewares: [
116
118
  ...options.middlewares.map((middleware) => ({ middleware, inputSchemasLengthAtUse: 0, outputSchemasLengthAtUse: 0 })),
@@ -1,8 +1,8 @@
1
1
  import { ORPCError, toORPCError, RPCSerializer, COMMON_ERROR_STATUS_MAP } from '@orpc/client';
2
2
  import { sortPlugins, getOpenTelemetryConfig, runWithSpan, toArray, matchesHttpPathPrefix, intercept, ORPC_NAME, isAsyncIteratorObject, override, traceAsyncIterator, recordSpanError, pathToHttpPath, normalizeHttpPath, value, parseEmptyableJSON } from '@orpc/shared';
3
3
  import { flattenStandardHeader, parseStandardUrl } from '@standardserver/core';
4
- import { c as createProcedureClient, u as unlazy, P as Procedure } from './server.CrlKQucM.mjs';
5
- import { w as walkProcedureContractsSync, g as getRouter, c as createContractProcedure, D as DEFAULT_SUCCESS_STATUS, a as DEFAULT_ERROR_STATUS } from './server.BwHnWUuN.mjs';
4
+ import { c as createProcedureClient, u as unlazy, P as Procedure } from './server.DofEOwf-.mjs';
5
+ import { w as walkProcedureContractsSync, g as getRouter, c as createContractProcedure, D as DEFAULT_SUCCESS_STATUS, a as DEFAULT_ERROR_STATUS } from './server.BoiFpNT7.mjs';
6
6
 
7
7
  class CompositeStandardHandlerPlugin {
8
8
  name = "~composite";
@@ -64,7 +64,7 @@ class StandardHandler {
64
64
  let input = await runWithSpan("decode_input", decodeInput2);
65
65
  step = void 0;
66
66
  if (isAsyncIteratorObject(input)) {
67
- input = override(input, traceAsyncIterator("consume_event_iterator_input", input));
67
+ input = override(input, traceAsyncIterator("consume_async_iterator_object_input", input));
68
68
  }
69
69
  const client = createProcedureClient(procedure2, {
70
70
  context: context3,
@@ -119,7 +119,29 @@ interface OrderedMiddleware {
119
119
  outputSchemasLengthAtUse?: number | undefined;
120
120
  middleware: AnyMiddleware;
121
121
  }
122
- interface ProcedureDefinition<TInitialContext extends Context, TInjectedContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TReturnedError extends AnyORPCError> extends ProcedureContractDefinition<TInputSchema, TOutputSchema, TErrorMap> {
122
+ interface ProcedureConfig {
123
+ /**
124
+ * When enabled, input schemas are not validated at runtime.
125
+ * Schemas are still used for type inference and OpenAPI generation.
126
+ *
127
+ * @warning Do not disable validation for schemas that transform values.
128
+ *
129
+ * @default false
130
+ */
131
+ disableInputValidation?: boolean | undefined;
132
+ /**
133
+ * When enabled, output schemas are not validated at runtime.
134
+ * Schemas are still used for type inference and OpenAPI generation.
135
+ *
136
+ * Useful when output schemas exist only for specification generation.
137
+ *
138
+ * @warning Do not disable validation for schemas that transform values.
139
+ *
140
+ * @default false
141
+ */
142
+ disableOutputValidation?: boolean | undefined;
143
+ }
144
+ interface ProcedureDefinition<TInitialContext extends Context, TInjectedContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TReturnedError extends AnyORPCError> extends ProcedureContractDefinition<TInputSchema, TOutputSchema, TErrorMap>, ProcedureConfig {
123
145
  __TInitialContext?: (type: TInitialContext) => unknown;
124
146
  __TInjectedContext?: (type: TInjectedContext) => unknown;
125
147
  __TReturnedError?: () => TReturnedError;
@@ -180,5 +202,5 @@ type ProcedureClientOptions<TInitialContext extends Context, TOutputSchema exten
180
202
  });
181
203
  declare function createProcedureClient<TInitialContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TReturnedError extends AnyORPCError, TClientContext extends ClientContext = object>(lazyableProcedure: Lazyable<Procedure<TInitialContext, any, TInputSchema, TOutputSchema, TErrorMap, TReturnedError>>, ...rest: MaybeOptionalOptions<ProcedureClientOptions<TInitialContext, TOutputSchema, TErrorMap, TReturnedError, TClientContext>>): ProcedureClient<TClientContext, TInputSchema, TOutputSchema, TErrorMap, TReturnedError>;
182
204
 
183
- export { Procedure as a, Lazy as g, createORPCErrorConstructorMap as w, createProcedureClient as x, unlazy as y };
184
- export type { AnyProcedure as A, Context as C, Lazyable as L, MergedContext as M, ORPCErrorConstructorMap as O, ProcedureClientOptions as P, ProcedureClient as b, ProcedureClientInterceptor as c, Middleware as d, MergedInitialContext as e, AnyMiddleware as f, ProcedureHandler as h, OrderedMiddleware as i, LazyDefinition as j, MiddlewareDefinition as k, MiddlewareDone as l, MiddlewareDoneOptions as m, MiddlewareNext as n, MiddlewareNextOptions as o, MiddlewareOptions as p, MiddlewareResult as q, ORPCErrorConstructorMapItem as r, ORPCErrorConstructorMapItemOptions as s, ProcedureClientInterceptorOptions as t, ProcedureDefinition as u, ProcedureHandlerOptions as v };
205
+ export { Procedure as a, Lazy as h, createORPCErrorConstructorMap as x, createProcedureClient as y, unlazy as z };
206
+ export type { AnyProcedure as A, Context as C, Lazyable as L, MergedContext as M, ORPCErrorConstructorMap as O, ProcedureClientOptions as P, ProcedureClient as b, ProcedureClientInterceptor as c, Middleware as d, MergedInitialContext as e, ProcedureConfig as f, AnyMiddleware as g, ProcedureHandler as i, OrderedMiddleware as j, LazyDefinition as k, MiddlewareDefinition as l, MiddlewareDone as m, MiddlewareDoneOptions as n, MiddlewareNext as o, MiddlewareNextOptions as p, MiddlewareOptions as q, MiddlewareResult as r, ORPCErrorConstructorMapItem as s, ORPCErrorConstructorMapItemOptions as t, ProcedureClientInterceptorOptions as u, ProcedureDefinition as v, ProcedureHandlerOptions as w };
@@ -119,7 +119,29 @@ interface OrderedMiddleware {
119
119
  outputSchemasLengthAtUse?: number | undefined;
120
120
  middleware: AnyMiddleware;
121
121
  }
122
- interface ProcedureDefinition<TInitialContext extends Context, TInjectedContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TReturnedError extends AnyORPCError> extends ProcedureContractDefinition<TInputSchema, TOutputSchema, TErrorMap> {
122
+ interface ProcedureConfig {
123
+ /**
124
+ * When enabled, input schemas are not validated at runtime.
125
+ * Schemas are still used for type inference and OpenAPI generation.
126
+ *
127
+ * @warning Do not disable validation for schemas that transform values.
128
+ *
129
+ * @default false
130
+ */
131
+ disableInputValidation?: boolean | undefined;
132
+ /**
133
+ * When enabled, output schemas are not validated at runtime.
134
+ * Schemas are still used for type inference and OpenAPI generation.
135
+ *
136
+ * Useful when output schemas exist only for specification generation.
137
+ *
138
+ * @warning Do not disable validation for schemas that transform values.
139
+ *
140
+ * @default false
141
+ */
142
+ disableOutputValidation?: boolean | undefined;
143
+ }
144
+ interface ProcedureDefinition<TInitialContext extends Context, TInjectedContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TReturnedError extends AnyORPCError> extends ProcedureContractDefinition<TInputSchema, TOutputSchema, TErrorMap>, ProcedureConfig {
123
145
  __TInitialContext?: (type: TInitialContext) => unknown;
124
146
  __TInjectedContext?: (type: TInjectedContext) => unknown;
125
147
  __TReturnedError?: () => TReturnedError;
@@ -180,5 +202,5 @@ type ProcedureClientOptions<TInitialContext extends Context, TOutputSchema exten
180
202
  });
181
203
  declare function createProcedureClient<TInitialContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TReturnedError extends AnyORPCError, TClientContext extends ClientContext = object>(lazyableProcedure: Lazyable<Procedure<TInitialContext, any, TInputSchema, TOutputSchema, TErrorMap, TReturnedError>>, ...rest: MaybeOptionalOptions<ProcedureClientOptions<TInitialContext, TOutputSchema, TErrorMap, TReturnedError, TClientContext>>): ProcedureClient<TClientContext, TInputSchema, TOutputSchema, TErrorMap, TReturnedError>;
182
204
 
183
- export { Procedure as a, Lazy as g, createORPCErrorConstructorMap as w, createProcedureClient as x, unlazy as y };
184
- export type { AnyProcedure as A, Context as C, Lazyable as L, MergedContext as M, ORPCErrorConstructorMap as O, ProcedureClientOptions as P, ProcedureClient as b, ProcedureClientInterceptor as c, Middleware as d, MergedInitialContext as e, AnyMiddleware as f, ProcedureHandler as h, OrderedMiddleware as i, LazyDefinition as j, MiddlewareDefinition as k, MiddlewareDone as l, MiddlewareDoneOptions as m, MiddlewareNext as n, MiddlewareNextOptions as o, MiddlewareOptions as p, MiddlewareResult as q, ORPCErrorConstructorMapItem as r, ORPCErrorConstructorMapItemOptions as s, ProcedureClientInterceptorOptions as t, ProcedureDefinition as u, ProcedureHandlerOptions as v };
205
+ export { Procedure as a, Lazy as h, createORPCErrorConstructorMap as x, createProcedureClient as y, unlazy as z };
206
+ export type { AnyProcedure as A, Context as C, Lazyable as L, MergedContext as M, ORPCErrorConstructorMap as O, ProcedureClientOptions as P, ProcedureClient as b, ProcedureClientInterceptor as c, Middleware as d, MergedInitialContext as e, ProcedureConfig as f, AnyMiddleware as g, ProcedureHandler as i, OrderedMiddleware as j, LazyDefinition as k, MiddlewareDefinition as l, MiddlewareDone as m, MiddlewareDoneOptions as n, MiddlewareNext as o, MiddlewareNextOptions as p, MiddlewareOptions as q, MiddlewareResult as r, ORPCErrorConstructorMapItem as s, ORPCErrorConstructorMapItemOptions as t, ProcedureClientInterceptorOptions as u, ProcedureDefinition as v, ProcedureHandlerOptions as w };