@orpc/client 2.0.0-beta.35 → 2.0.0-beta.37

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.
package/README.md CHANGED
@@ -46,29 +46,30 @@ You can read the documentation [here](https://orpc.dev).
46
46
 
47
47
  **Built-in features**
48
48
 
49
- | Package | Purpose | Docs |
50
- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
51
- | [@orpc/publisher](https://www.npmjs.com/package/@orpc/publisher) | Pub/Sub with memory, Redis, and Upstash adapters. | [Publisher](https://orpc.dev/docs/helpers/publisher) |
52
- | [@orpc/ratelimit](https://www.npmjs.com/package/@orpc/ratelimit) | Rate limiting with memory, Redis, and Upstash adapters. | [Rate Limit](https://orpc.dev/docs/helpers/ratelimit) |
53
- | [@orpc/hibernation](https://www.npmjs.com/package/@orpc/hibernation) | Leverage Hibernation APIs like [Cloudflare's Hibernation WebSocket](https://developers.cloudflare.com/durable-objects/best-practices/websockets/#durable-objects-hibernation-websocket-api). | [Hibernation](https://orpc.dev/docs/integrations/hibernation) |
54
- | [@orpc/json-schema](https://www.npmjs.com/package/@orpc/json-schema) | Smart coercion for OpenAPI requests. | [Smart Coercion](https://orpc.dev/docs/plugins/smart-coercion) |
49
+ | Package | Purpose | Docs |
50
+ | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
51
+ | [@orpc/publisher](https://www.npmjs.com/package/@orpc/publisher) | Pub/Sub with memory, Redis, and Upstash adapters. | [Publisher](https://orpc.dev/docs/helpers/publisher) |
52
+ | [@orpc/ratelimit](https://www.npmjs.com/package/@orpc/ratelimit) | Rate limiting with memory, Redis, and Upstash adapters. | [Rate Limit](https://orpc.dev/docs/helpers/ratelimit) |
53
+ | [@orpc/experimental-lock](https://www.npmjs.com/package/@orpc/experimental-lock) | Locking with memory, Redis, and Upstash adapters. | [Lock](https://orpc.dev/docs/helpers/lock) |
54
+ | [@orpc/hibernation](https://www.npmjs.com/package/@orpc/hibernation) | Leverage Hibernation APIs like [Cloudflare's Hibernation WebSocket](https://developers.cloudflare.com/durable-objects/best-practices/websockets/#durable-objects-hibernation-websocket-api). | [Hibernation](https://orpc.dev/docs/integrations/hibernation) |
55
+ | [@orpc/json-schema](https://www.npmjs.com/package/@orpc/json-schema) | Smart coercion for OpenAPI requests. | [Smart Coercion](https://orpc.dev/docs/plugins/smart-coercion) |
55
56
 
56
57
  **Framework & ecosystem integrations**
57
58
 
58
- | Package | Purpose | Docs |
59
- | ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
60
- | [@orpc/next](https://www.npmjs.com/package/@orpc/next) | Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data). | [Next.js](https://orpc.dev/docs/integrations/next) |
61
- | [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk) | Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools. | [AI SDK](https://orpc.dev/docs/integrations/ai-sdk) |
62
- | [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query) | Integrate with [TanStack Query](https://tanstack.com/query/latest). | [TanStack Query](https://orpc.dev/docs/integrations/tanstack-query) |
63
- | [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada) | Integrate with [Pinia Colada](https://pinia-colada.esm.dev/). | [Pinia Colada](https://orpc.dev/docs/integrations/pinia-colada) |
64
- | [@orpc/swr](https://www.npmjs.com/package/@orpc/swr) | Integrate with [SWR](https://swr.vercel.app/). | [SWR](https://orpc.dev/docs/integrations/swr) |
65
- | [@orpc/experimental-msw](https://www.npmjs.com/package/@orpc/experimental-msw) | Mock procedures with [Mock Service Worker](https://mswjs.io/). | [MSW](https://orpc.dev/docs/integrations/msw) |
66
- | [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect) | Integrate with [Effect](https://effect.website/). | [Effect](https://orpc.dev/docs/integrations/effect) |
67
- | [@orpc/nest](https://www.npmjs.com/package/@orpc/nest) | Implement your contract with [NestJS](https://nestjs.com/). | [NestJS](https://orpc.dev/docs/integrations/nest) |
68
- | [@orpc/node](https://www.npmjs.com/package/@orpc/node) | [Node.js](https://nodejs.org/) plugins for static file serving and large uploads. | [Static File](https://orpc.dev/docs/plugins/static-file), [Tmp File Upload](https://orpc.dev/docs/plugins/tmp-file-upload), [Batch Response Compression](https://orpc.dev/docs/plugins/batch-response-compression) |
69
- | [@orpc/bun](https://www.npmjs.com/package/@orpc/bun) | Adapters for [Bun's Redis](https://bun.sh/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit) |
70
- | [@orpc/cloudflare](https://www.npmjs.com/package/@orpc/cloudflare) | Adapters for [Cloudflare Workers](https://developers.cloudflare.com/workers/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit), [Traces](https://orpc.dev/docs/integrations/cloudflare-traces) |
71
- | [@orpc/trpc](https://www.npmjs.com/package/@orpc/trpc) | Reuse existing [tRPC](https://trpc.io/) routers within oRPC. | [tRPC](https://orpc.dev/docs/integrations/trpc) |
59
+ | Package | Purpose | Docs |
60
+ | ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
61
+ | [@orpc/next](https://www.npmjs.com/package/@orpc/next) | Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data). | [Next.js](https://orpc.dev/docs/integrations/next) |
62
+ | [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk) | Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools. | [AI SDK](https://orpc.dev/docs/integrations/ai-sdk) |
63
+ | [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query) | Integrate with [TanStack Query](https://tanstack.com/query/latest). | [TanStack Query](https://orpc.dev/docs/integrations/tanstack-query) |
64
+ | [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada) | Integrate with [Pinia Colada](https://pinia-colada.esm.dev/). | [Pinia Colada](https://orpc.dev/docs/integrations/pinia-colada) |
65
+ | [@orpc/swr](https://www.npmjs.com/package/@orpc/swr) | Integrate with [SWR](https://swr.vercel.app/). | [SWR](https://orpc.dev/docs/integrations/swr) |
66
+ | [@orpc/experimental-msw](https://www.npmjs.com/package/@orpc/experimental-msw) | Mock procedures with [Mock Service Worker](https://mswjs.io/). | [MSW](https://orpc.dev/docs/integrations/msw) |
67
+ | [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect) | Integrate with [Effect](https://effect.website/). | [Effect](https://orpc.dev/docs/integrations/effect) |
68
+ | [@orpc/nest](https://www.npmjs.com/package/@orpc/nest) | Implement your contract with [NestJS](https://nestjs.com/). | [NestJS](https://orpc.dev/docs/integrations/nest) |
69
+ | [@orpc/node](https://www.npmjs.com/package/@orpc/node) | [Node.js](https://nodejs.org/) plugins for static file serving and large uploads. | [Static File](https://orpc.dev/docs/plugins/static-file), [Tmp File Upload](https://orpc.dev/docs/plugins/tmp-file-upload), [Batch Response Compression](https://orpc.dev/docs/plugins/batch-response-compression) |
70
+ | [@orpc/bun](https://www.npmjs.com/package/@orpc/bun) | Adapters for [Bun's Redis](https://bun.sh/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit), [Lock](https://orpc.dev/docs/helpers/lock) |
71
+ | [@orpc/cloudflare](https://www.npmjs.com/package/@orpc/cloudflare) | Adapters for [Cloudflare Workers](https://developers.cloudflare.com/workers/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit), [Lock](https://orpc.dev/docs/helpers/lock), [Traces](https://orpc.dev/docs/integrations/cloudflare-traces) |
72
+ | [@orpc/trpc](https://www.npmjs.com/package/@orpc/trpc) | Reuse existing [tRPC](https://trpc.io/) routers within oRPC. | [tRPC](https://orpc.dev/docs/integrations/trpc) |
72
73
 
73
74
  **Observability**
74
75
 
@@ -94,6 +95,14 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
94
95
  </tr>
95
96
  </table>
96
97
 
98
+ ### Special Sponsors
99
+
100
+ <table>
101
+ <tr>
102
+ <td align="center"><a href="http://twitter.com/rauchg?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Guillermo Rauch"><img src="https://avatars.githubusercontent.com/u/13041?u=1ee8d111657cdd02ff6d253df00978d17ee6d722&amp;v=4" width="279" alt="Guillermo Rauch"/><br />Guillermo Rauch</a></td>
103
+ </tr>
104
+ </table>
105
+
97
106
  ### Organization Sponsors
98
107
 
99
108
  <table>
@@ -1,17 +1,11 @@
1
1
  import { ClientContext, ClientOptions } from '../../index.mjs';
2
- import { Value, Promisable, Interceptor } from '@orpc/shared';
2
+ import { Value, Promisable } from '@orpc/shared';
3
3
  import { StandardRequest, StandardLazyResponse } from '@standard-server/core';
4
4
  import { ToFetchBodyOptions } from '@standard-server/fetch';
5
- import { StandardLinkTransport, StandardLinkPlugin, StandardLink, StandardLinkOptions } from '../standard/index.mjs';
5
+ import { StandardLinkTransport, StandardLink, StandardLinkOptions } from '../standard/index.mjs';
6
6
  import { RPCLinkCodecOptions } from '../standard/index.mjs';
7
- import '../../shared/client.DPi5reJh.mjs';
7
+ import '../../shared/client.n8K9dFhY.mjs';
8
8
 
9
- interface FetchLinkTransportFetchInterceptorOptions<T extends ClientContext> extends ClientOptions<T> {
10
- path: string[];
11
- url: string;
12
- init: RequestInit;
13
- }
14
- type FetchLinkTransportFetchInterceptor<T extends ClientContext> = Interceptor<FetchLinkTransportFetchInterceptorOptions<T>, Promise<Response>>;
15
9
  interface FetchLinkTransportOptions<T extends ClientContext> {
16
10
  /**
17
11
  * The origin to prepend to all request URLs, useful for CORS requests.
@@ -30,32 +24,16 @@ interface FetchLinkTransportOptions<T extends ClientContext> {
30
24
  * @default (url, init) => globalThis.fetch(url, init)
31
25
  */
32
26
  fetch?(url: string, init: RequestInit, options: ClientOptions<T>, path: string[]): Promise<Response>;
33
- /**
34
- * Interceptors that execute before the actual fetch call, useful for modifying the fetch parameters, adding logging, etc.
35
- */
36
- fetchInterceptors?: FetchLinkTransportFetchInterceptor<T>[];
37
- plugins?: FetchLinkTransportPlugin<T>[];
38
27
  }
39
28
  declare class FetchLinkTransport<T extends ClientContext> implements StandardLinkTransport<T> {
40
29
  private readonly origin;
41
30
  private readonly fetch;
42
31
  private readonly toFetchRequestOptions;
43
- private readonly fetchInterceptors;
44
32
  constructor(options: FetchLinkTransportOptions<T>);
45
33
  send(standardRequest: StandardRequest, path: string[], options: ClientOptions<T>): Promise<StandardLazyResponse>;
46
34
  }
47
35
 
48
- interface FetchLinkTransportPlugin<T extends ClientContext> extends StandardLinkPlugin<T> {
49
- initFetchLinkTransportOptions?(options: FetchLinkTransportOptions<T>): FetchLinkTransportOptions<T>;
50
- }
51
- declare class CompositeFetchLinkTransportPlugin<T extends ClientContext> implements FetchLinkTransportPlugin<T> {
52
- protected readonly plugins: FetchLinkTransportPlugin<T>[];
53
- name: string;
54
- constructor(plugins?: FetchLinkTransportPlugin<T>[]);
55
- initFetchLinkTransportOptions(options: FetchLinkTransportOptions<T>): FetchLinkTransportOptions<T>;
56
- }
57
-
58
- interface RPCLinkOptions<T extends ClientContext> extends Omit<StandardLinkOptions<T>, 'plugins'>, FetchLinkTransportOptions<T>, RPCLinkCodecOptions<T> {
36
+ interface RPCLinkOptions<T extends ClientContext> extends StandardLinkOptions<T>, FetchLinkTransportOptions<T>, RPCLinkCodecOptions<T> {
59
37
  }
60
38
  /**
61
39
  * Client link that communicates with an RPC Handler over the Fetch API (HTTP).
@@ -66,5 +44,5 @@ declare class RPCLink<T extends ClientContext> extends StandardLink<T> {
66
44
  constructor(options: RPCLinkOptions<T>);
67
45
  }
68
46
 
69
- export { CompositeFetchLinkTransportPlugin, FetchLinkTransport, RPCLink };
70
- export type { FetchLinkTransportFetchInterceptor, FetchLinkTransportFetchInterceptorOptions, FetchLinkTransportOptions, FetchLinkTransportPlugin, RPCLinkOptions };
47
+ export { FetchLinkTransport, RPCLink };
48
+ export type { FetchLinkTransportOptions, RPCLinkOptions };
@@ -1,17 +1,11 @@
1
1
  import { ClientContext, ClientOptions } from '../../index.js';
2
- import { Value, Promisable, Interceptor } from '@orpc/shared';
2
+ import { Value, Promisable } from '@orpc/shared';
3
3
  import { StandardRequest, StandardLazyResponse } from '@standard-server/core';
4
4
  import { ToFetchBodyOptions } from '@standard-server/fetch';
5
- import { StandardLinkTransport, StandardLinkPlugin, StandardLink, StandardLinkOptions } from '../standard/index.js';
5
+ import { StandardLinkTransport, StandardLink, StandardLinkOptions } from '../standard/index.js';
6
6
  import { RPCLinkCodecOptions } from '../standard/index.js';
7
- import '../../shared/client.DPi5reJh.js';
7
+ import '../../shared/client.n8K9dFhY.js';
8
8
 
9
- interface FetchLinkTransportFetchInterceptorOptions<T extends ClientContext> extends ClientOptions<T> {
10
- path: string[];
11
- url: string;
12
- init: RequestInit;
13
- }
14
- type FetchLinkTransportFetchInterceptor<T extends ClientContext> = Interceptor<FetchLinkTransportFetchInterceptorOptions<T>, Promise<Response>>;
15
9
  interface FetchLinkTransportOptions<T extends ClientContext> {
16
10
  /**
17
11
  * The origin to prepend to all request URLs, useful for CORS requests.
@@ -30,32 +24,16 @@ interface FetchLinkTransportOptions<T extends ClientContext> {
30
24
  * @default (url, init) => globalThis.fetch(url, init)
31
25
  */
32
26
  fetch?(url: string, init: RequestInit, options: ClientOptions<T>, path: string[]): Promise<Response>;
33
- /**
34
- * Interceptors that execute before the actual fetch call, useful for modifying the fetch parameters, adding logging, etc.
35
- */
36
- fetchInterceptors?: FetchLinkTransportFetchInterceptor<T>[];
37
- plugins?: FetchLinkTransportPlugin<T>[];
38
27
  }
39
28
  declare class FetchLinkTransport<T extends ClientContext> implements StandardLinkTransport<T> {
40
29
  private readonly origin;
41
30
  private readonly fetch;
42
31
  private readonly toFetchRequestOptions;
43
- private readonly fetchInterceptors;
44
32
  constructor(options: FetchLinkTransportOptions<T>);
45
33
  send(standardRequest: StandardRequest, path: string[], options: ClientOptions<T>): Promise<StandardLazyResponse>;
46
34
  }
47
35
 
48
- interface FetchLinkTransportPlugin<T extends ClientContext> extends StandardLinkPlugin<T> {
49
- initFetchLinkTransportOptions?(options: FetchLinkTransportOptions<T>): FetchLinkTransportOptions<T>;
50
- }
51
- declare class CompositeFetchLinkTransportPlugin<T extends ClientContext> implements FetchLinkTransportPlugin<T> {
52
- protected readonly plugins: FetchLinkTransportPlugin<T>[];
53
- name: string;
54
- constructor(plugins?: FetchLinkTransportPlugin<T>[]);
55
- initFetchLinkTransportOptions(options: FetchLinkTransportOptions<T>): FetchLinkTransportOptions<T>;
56
- }
57
-
58
- interface RPCLinkOptions<T extends ClientContext> extends Omit<StandardLinkOptions<T>, 'plugins'>, FetchLinkTransportOptions<T>, RPCLinkCodecOptions<T> {
36
+ interface RPCLinkOptions<T extends ClientContext> extends StandardLinkOptions<T>, FetchLinkTransportOptions<T>, RPCLinkCodecOptions<T> {
59
37
  }
60
38
  /**
61
39
  * Client link that communicates with an RPC Handler over the Fetch API (HTTP).
@@ -66,5 +44,5 @@ declare class RPCLink<T extends ClientContext> extends StandardLink<T> {
66
44
  constructor(options: RPCLinkOptions<T>);
67
45
  }
68
46
 
69
- export { CompositeFetchLinkTransportPlugin, FetchLinkTransport, RPCLink };
70
- export type { FetchLinkTransportFetchInterceptor, FetchLinkTransportFetchInterceptorOptions, FetchLinkTransportOptions, FetchLinkTransportPlugin, RPCLinkOptions };
47
+ export { FetchLinkTransport, RPCLink };
48
+ export type { FetchLinkTransportOptions, RPCLinkOptions };
@@ -1,26 +1,10 @@
1
- import { sortPlugins, value, intercept, once } from '@orpc/shared';
1
+ import { value, once } from '@orpc/shared';
2
2
  import { toFetchBody, toFetchHeaders, toStandardLazyResponse } from '@standard-server/fetch';
3
- import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.BOUKaeVg.mjs';
3
+ import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.BtJ-utP9.mjs';
4
4
  import '@standard-server/core';
5
- import '../../shared/client.Cik8dxOF.mjs';
5
+ import '../../shared/client.CUxLdmiH.mjs';
6
6
  import '../../shared/client.Dtv1JPkU.mjs';
7
7
 
8
- class CompositeFetchLinkTransportPlugin {
9
- constructor(plugins = []) {
10
- this.plugins = plugins;
11
- this.plugins = sortPlugins(plugins);
12
- }
13
- name = "~composite/fetch";
14
- initFetchLinkTransportOptions(options) {
15
- for (const plugin of this.plugins) {
16
- if (plugin.initFetchLinkTransportOptions) {
17
- options = plugin.initFetchLinkTransportOptions(options);
18
- }
19
- }
20
- return options;
21
- }
22
- }
23
-
24
8
  const GET_SUPPORTED_DUPLEX_MODE = once(() => {
25
9
  try {
26
10
  let duplex;
@@ -44,13 +28,10 @@ class FetchLinkTransport {
44
28
  origin;
45
29
  fetch;
46
30
  toFetchRequestOptions;
47
- fetchInterceptors;
48
31
  constructor(options) {
49
- options = new CompositeFetchLinkTransportPlugin(options.plugins).initFetchLinkTransportOptions(options);
50
32
  this.origin = options.origin;
51
33
  this.fetch = options.fetch ?? ((url, init) => globalThis.fetch(url, init));
52
34
  this.toFetchRequestOptions = options.toFetchRequest;
53
- this.fetchInterceptors = options.fetchInterceptors;
54
35
  }
55
36
  async send(standardRequest, path, options) {
56
37
  let origin = await value(this.origin, options, path);
@@ -72,11 +53,7 @@ class FetchLinkTransport {
72
53
  init.duplex = duplex;
73
54
  }
74
55
  }
75
- const response = await intercept(
76
- this.fetchInterceptors,
77
- { ...options, url, path, init },
78
- ({ url: url2, path: path2, init: init2, ...options2 }) => this.fetch(url2, init2, options2, path2)
79
- );
56
+ const response = await this.fetch(url, init, options, path);
80
57
  const standardResponse = toStandardLazyResponse(response);
81
58
  return standardResponse;
82
59
  }
@@ -90,4 +67,4 @@ class RPCLink extends StandardLink {
90
67
  }
91
68
  }
92
69
 
93
- export { CompositeFetchLinkTransportPlugin, FetchLinkTransport, RPCLink };
70
+ export { FetchLinkTransport, RPCLink };
@@ -4,7 +4,7 @@ import { StandardRequest, StandardLazyResponse } from '@standard-server/core';
4
4
  import { ClientPeer, EncodePeerMessageOptions, DecodePeerMessageOptions } from '@standard-server/peer';
5
5
  import { StandardLinkTransport, StandardLink, StandardLinkOptions } from '../standard/index.mjs';
6
6
  import { RPCLinkCodecOptions } from '../standard/index.mjs';
7
- import '../../shared/client.DPi5reJh.mjs';
7
+ import '../../shared/client.n8K9dFhY.mjs';
8
8
 
9
9
  /**
10
10
  * The message port used by electron in main process
@@ -4,7 +4,7 @@ import { StandardRequest, StandardLazyResponse } from '@standard-server/core';
4
4
  import { ClientPeer, EncodePeerMessageOptions, DecodePeerMessageOptions } from '@standard-server/peer';
5
5
  import { StandardLinkTransport, StandardLink, StandardLinkOptions } from '../standard/index.js';
6
6
  import { RPCLinkCodecOptions } from '../standard/index.js';
7
- import '../../shared/client.DPi5reJh.js';
7
+ import '../../shared/client.n8K9dFhY.js';
8
8
 
9
9
  /**
10
10
  * The message port used by electron in main process
@@ -1,9 +1,9 @@
1
1
  import { value } from '@orpc/shared';
2
2
  import { ClientPeer, encodePeerMessage, decodePeerMessage, isServerPeerSendMessage, isPeerMessage } from '@standard-server/peer';
3
- import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.BOUKaeVg.mjs';
3
+ import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.BtJ-utP9.mjs';
4
4
  import '@standard-server/core';
5
5
  import '@standard-server/fetch';
6
- import '../../shared/client.Cik8dxOF.mjs';
6
+ import '../../shared/client.CUxLdmiH.mjs';
7
7
  import '../../shared/client.Dtv1JPkU.mjs';
8
8
 
9
9
  function postMessagePortMessage(port, data, transfer) {
@@ -1,6 +1,6 @@
1
- export { C as CompositeStandardLinkPlugin, R as RPCLinkCodec, S as StandardLink } from '../../shared/client.BOUKaeVg.mjs';
1
+ export { C as CompositeStandardLinkPlugin, R as RPCLinkCodec, S as StandardLink } from '../../shared/client.BtJ-utP9.mjs';
2
2
  import '@orpc/shared';
3
3
  import '@standard-server/core';
4
4
  import '@standard-server/fetch';
5
- import '../../shared/client.Cik8dxOF.mjs';
5
+ import '../../shared/client.CUxLdmiH.mjs';
6
6
  import '../../shared/client.Dtv1JPkU.mjs';
@@ -4,7 +4,7 @@ import { StandardRequest, StandardLazyResponse } from '@standard-server/core';
4
4
  import { EncodePeerMessageOptions, DecodePeerMessageOptions } from '@standard-server/peer';
5
5
  import { StandardLinkTransport, StandardLink, StandardLinkOptions } from '../standard/index.mjs';
6
6
  import { RPCLinkCodecOptions } from '../standard/index.mjs';
7
- import '../../shared/client.DPi5reJh.mjs';
7
+ import '../../shared/client.n8K9dFhY.mjs';
8
8
 
9
9
  type WebSocketLike = Pick<WebSocket, 'addEventListener' | 'removeEventListener' | 'send' | 'readyState'>;
10
10
  interface WebSocketLinkTransportAttemptInfo {
@@ -4,7 +4,7 @@ import { StandardRequest, StandardLazyResponse } from '@standard-server/core';
4
4
  import { EncodePeerMessageOptions, DecodePeerMessageOptions } from '@standard-server/peer';
5
5
  import { StandardLinkTransport, StandardLink, StandardLinkOptions } from '../standard/index.js';
6
6
  import { RPCLinkCodecOptions } from '../standard/index.js';
7
- import '../../shared/client.DPi5reJh.js';
7
+ import '../../shared/client.n8K9dFhY.js';
8
8
 
9
9
  type WebSocketLike = Pick<WebSocket, 'addEventListener' | 'removeEventListener' | 'send' | 'readyState'>;
10
10
  interface WebSocketLinkTransportAttemptInfo {
@@ -1,9 +1,9 @@
1
1
  import { runWithSignal, AbortError, sleep, promiseWithResolvers, sequential, loadBytes, toStringOrBytes } from '@orpc/shared';
2
2
  import { ClientPeer, encodePeerMessage, decodePeerMessage, isServerPeerSendMessage } from '@standard-server/peer';
3
- import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.BOUKaeVg.mjs';
3
+ import { S as StandardLink, R as RPCLinkCodec } from '../../shared/client.BtJ-utP9.mjs';
4
4
  import '@standard-server/core';
5
5
  import '@standard-server/fetch';
6
- import '../../shared/client.Cik8dxOF.mjs';
6
+ import '../../shared/client.CUxLdmiH.mjs';
7
7
  import '../../shared/client.Dtv1JPkU.mjs';
8
8
 
9
9
  const WEBSOCKET_CONNECTING = 0;
package/dist/index.d.mts CHANGED
@@ -4,7 +4,7 @@ import { C as ClientContext, a as ClientOptions, c as AnyNestedClient, I as Infe
4
4
  export { i as AnyORPCErrorJSON, j as COMMON_ERROR_STATUS_MAP, k as InferClientBodyInputs, l as InferClientBodyOutputs, m as InferClientErrors, n as InferClientInputs, o as InferClientOutputs, p as MalformedResponseError, N as NestedClient, q as ORPCErrorOptions } from './shared/client.BoXZCzuS.mjs';
5
5
  import { StandardResponse } from '@standard-server/core';
6
6
  export { ErrorEvent, EventMeta, StandardBody, StandardBodyHint, StandardHeaders, StandardLazyRequest, StandardLazyResponse, StandardMethod, StandardRequest, StandardResponse, StandardUrl, getEventMeta, unwrapEvent, withEventMeta } from '@standard-server/core';
7
- export { R as RPCJsonSerialization, a as RPCJsonSerializationMeta, b as RPCJsonSerializer, c as RPCJsonSerializerHandler, d as RPCJsonSerializerOptions, e as RPCSerializer, f as RPCSerializerOptions, g as RPCSerializerSerializeOptions } from './shared/client.DPi5reJh.mjs';
7
+ export { R as RPCJsonSerialization, a as RPCJsonSerializationMeta, b as RPCJsonSerializer, c as RPCJsonSerializerHandler, d as RPCJsonSerializerOptions, e as RPCSerializer, f as RPCSerializerOptions, g as RPCSerializerSerializeOptions } from './shared/client.n8K9dFhY.mjs';
8
8
 
9
9
  declare function wrapAsyncIteratorPreservingEventMeta<TYield, TReturn, TMappedYield = TYield, TMappedReturn = TReturn>(iterator: AsyncIterator<TYield, TReturn>, { mapResult, mapError, ...rest }: WrapAsyncIteratorOptions<TYield, TReturn, TMappedYield, TMappedReturn>): AsyncIteratorClass<TMappedYield, TMappedReturn>;
10
10
 
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ import { C as ClientContext, a as ClientOptions, c as AnyNestedClient, I as Infe
4
4
  export { i as AnyORPCErrorJSON, j as COMMON_ERROR_STATUS_MAP, k as InferClientBodyInputs, l as InferClientBodyOutputs, m as InferClientErrors, n as InferClientInputs, o as InferClientOutputs, p as MalformedResponseError, N as NestedClient, q as ORPCErrorOptions } from './shared/client.BoXZCzuS.js';
5
5
  import { StandardResponse } from '@standard-server/core';
6
6
  export { ErrorEvent, EventMeta, StandardBody, StandardBodyHint, StandardHeaders, StandardLazyRequest, StandardLazyResponse, StandardMethod, StandardRequest, StandardResponse, StandardUrl, getEventMeta, unwrapEvent, withEventMeta } from '@standard-server/core';
7
- export { R as RPCJsonSerialization, a as RPCJsonSerializationMeta, b as RPCJsonSerializer, c as RPCJsonSerializerHandler, d as RPCJsonSerializerOptions, e as RPCSerializer, f as RPCSerializerOptions, g as RPCSerializerSerializeOptions } from './shared/client.DPi5reJh.js';
7
+ export { R as RPCJsonSerialization, a as RPCJsonSerializationMeta, b as RPCJsonSerializer, c as RPCJsonSerializerHandler, d as RPCJsonSerializerOptions, e as RPCSerializer, f as RPCSerializerOptions, g as RPCSerializerSerializeOptions } from './shared/client.n8K9dFhY.js';
8
8
 
9
9
  declare function wrapAsyncIteratorPreservingEventMeta<TYield, TReturn, TMappedYield = TYield, TMappedReturn = TReturn>(iterator: AsyncIterator<TYield, TReturn>, { mapResult, mapError, ...rest }: WrapAsyncIteratorOptions<TYield, TReturn, TMappedYield, TMappedReturn>): AsyncIteratorClass<TMappedYield, TMappedReturn>;
10
10
 
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { b as isDefinedError } from './shared/client.Cik8dxOF.mjs';
2
- export { d as RPCJsonSerializer, R as RPCSerializer, e as cloneORPCError, a as createORPCErrorFromJson, c as createORPCErrorFromMalformedResponse, i as isORPCErrorJson, t as toORPCError, w as wrapAsyncIteratorPreservingEventMeta } from './shared/client.Cik8dxOF.mjs';
1
+ import { b as isDefinedError } from './shared/client.CUxLdmiH.mjs';
2
+ export { d as RPCJsonSerializer, R as RPCSerializer, e as cloneORPCError, a as createORPCErrorFromJson, c as createORPCErrorFromMalformedResponse, i as isORPCErrorJson, t as toORPCError, w as wrapAsyncIteratorPreservingEventMeta } from './shared/client.CUxLdmiH.mjs';
3
3
  import { toArray, intercept, isTypescriptObject } from '@orpc/shared';
4
4
  export { AsyncIteratorClass, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, consumeAsyncIterator, consumeAsyncIterator as consumeEventIterator, asyncIteratorToStream as eventIteratorToStream, asyncIteratorToUnproxiedDataStream as eventIteratorToUnproxiedDataStream, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, streamToAsyncIteratorObject, streamToAsyncIteratorObject as streamToEventIterator } from '@orpc/shared';
5
5
  export { C as COMMON_ERROR_STATUS_MAP, M as MalformedResponseError, O as ORPCError } from './shared/client.Dtv1JPkU.mjs';
@@ -1,4 +1,4 @@
1
- import { toArray, value, splitInHalf, stringifyJSON, once, isAsyncIteratorObject, defer, loadBytes, allAbortSignal, replicateAsyncIterator, replicateReadableStream, isCompressibleContentType, override, AsyncIteratorClass, sleep, AbortError, anyAbortSignal } from '@orpc/shared';
1
+ import { toArray, value, splitInHalf, safeEncodeURIComponent, stringifyJSON, once, isAsyncIteratorObject, defer, loadBytes, allAbortSignal, replicateAsyncIterator, replicateReadableStream, isCompressibleContentType, override, AsyncIteratorClass, sleep, AbortError, anyAbortSignal } from '@orpc/shared';
2
2
  import { parseStandardUrl, flattenStandardHeader, generateContentDisposition, getEventMeta } from '@standard-server/core';
3
3
  import { ClientPeer, isServerPeerSendMessage, decodePeerMessage } from '@standard-server/peer';
4
4
  import { toFetchHeaders, toStandardBody } from '@standard-server/fetch';
@@ -30,7 +30,8 @@ class BatchLinkPlugin {
30
30
  const headersList = options2.map((o) => o.request.headers);
31
31
  const commonHeaders = {};
32
32
  for (const headers of headersList) {
33
- for (const [key, value2] of Object.entries(headers)) {
33
+ for (const key of Object.keys(headers)) {
34
+ const value2 = headers[key];
34
35
  if (headersList.every((h) => h[key] === value2)) {
35
36
  commonHeaders[key] = value2;
36
37
  }
@@ -40,7 +41,8 @@ class BatchLinkPlugin {
40
41
  });
41
42
  this.mapSubrequest = options.mapSubrequest ?? (({ request }, { headers }) => {
42
43
  const subHeaders = { ...request.headers };
43
- for (const [key, value2] of Object.entries(headers)) {
44
+ for (const key of Object.keys(headers)) {
45
+ const value2 = headers[key];
44
46
  if (subHeaders[key] === value2) {
45
47
  subHeaders[key] = void 0;
46
48
  }
@@ -138,7 +140,7 @@ class BatchLinkPlugin {
138
140
  };
139
141
  if (method === "GET") {
140
142
  const [pathname, search, hash] = parseStandardUrl(url);
141
- const dataParam = `data=${encodeURIComponent(stringifyJSON(pendingMessages))}`;
143
+ const dataParam = `data=${safeEncodeURIComponent(stringifyJSON(pendingMessages))}`;
142
144
  const newUrl = search ? `${pathname}${search}&${dataParam}${hash ?? ""}` : `${pathname}?${dataParam}${hash ?? ""}`;
143
145
  const maxUrlLength = await value(this.maxUrlLength, subOptionsList);
144
146
  if (newUrl.length > maxUrlLength) {
@@ -1,7 +1,7 @@
1
1
  import { sortPlugins, runWithSpan, ORPC_NAME, getTracer, isAsyncIteratorObject, override, traceAsyncIterator, traceReadableStream, intercept, value, pathToHttpPath, stringifyJSON } from '@orpc/shared';
2
2
  import { mergeStandardHeaders, parseStandardUrl } from '@standard-server/core';
3
3
  import { toStandardHeaders } from '@standard-server/fetch';
4
- import { R as RPCSerializer, c as createORPCErrorFromMalformedResponse, i as isORPCErrorJson, a as createORPCErrorFromJson } from './client.Cik8dxOF.mjs';
4
+ import { R as RPCSerializer, c as createORPCErrorFromMalformedResponse, i as isORPCErrorJson, a as createORPCErrorFromJson } from './client.CUxLdmiH.mjs';
5
5
 
6
6
  class CompositeStandardLinkPlugin {
7
7
  name = "~composite";
@@ -87,7 +87,14 @@ function wrapAsyncIteratorPreservingEventMeta(iterator, { mapResult, mapError, .
87
87
  });
88
88
  }
89
89
 
90
- const REGEX_STRING_PATTERN = /^\/([\s\S]*)\/([a-z]*)$/;
90
+ function invalidSerializedData(detail) {
91
+ return new TypeError(`Invalid RPC serialized data: ${detail}`);
92
+ }
93
+ function assertSerializedType(ok, type, expected) {
94
+ if (!ok) {
95
+ throw invalidSerializedData(`type "${type}" expects ${expected}.`);
96
+ }
97
+ }
91
98
  const DEFAULT_RPC_JSON_SERIALIZER_HANDLERS = {
92
99
  undefined: {
93
100
  condition(data) {
@@ -96,7 +103,8 @@ const DEFAULT_RPC_JSON_SERIALIZER_HANDLERS = {
96
103
  serialize() {
97
104
  return null;
98
105
  },
99
- deserialize() {
106
+ deserialize(serialized) {
107
+ assertSerializedType(serialized === null, "undefined", "null");
100
108
  return void 0;
101
109
  },
102
110
  isTerminal: true
@@ -109,6 +117,7 @@ const DEFAULT_RPC_JSON_SERIALIZER_HANDLERS = {
109
117
  return data.toString();
110
118
  },
111
119
  deserialize(serialized) {
120
+ assertSerializedType(typeof serialized === "string", "bigint", "a string");
112
121
  return BigInt(serialized);
113
122
  },
114
123
  isTerminal: true
@@ -124,7 +133,8 @@ const DEFAULT_RPC_JSON_SERIALIZER_HANDLERS = {
124
133
  return data.toISOString();
125
134
  },
126
135
  deserialize(serialized) {
127
- return new Date(serialized ?? "Invalid Date");
136
+ assertSerializedType(typeof serialized === "string" || serialized === null, "date", "a string or null");
137
+ return new Date(serialized ?? Number.NaN);
128
138
  },
129
139
  isTerminal: true
130
140
  },
@@ -135,7 +145,8 @@ const DEFAULT_RPC_JSON_SERIALIZER_HANDLERS = {
135
145
  serialize() {
136
146
  return null;
137
147
  },
138
- deserialize() {
148
+ deserialize(serialized) {
149
+ assertSerializedType(serialized === null, "nan", "null");
139
150
  return Number.NaN;
140
151
  },
141
152
  isTerminal: true
@@ -148,23 +159,11 @@ const DEFAULT_RPC_JSON_SERIALIZER_HANDLERS = {
148
159
  return data.toString();
149
160
  },
150
161
  deserialize(serialized) {
162
+ assertSerializedType(typeof serialized === "string", "url", "a string");
151
163
  return new URL(serialized);
152
164
  },
153
165
  isTerminal: true
154
166
  },
155
- regexp: {
156
- condition(data) {
157
- return data instanceof RegExp;
158
- },
159
- serialize(data) {
160
- return data.toString();
161
- },
162
- deserialize(serialized) {
163
- const [, pattern, flags] = serialized.match(REGEX_STRING_PATTERN);
164
- return new RegExp(pattern, flags);
165
- },
166
- isTerminal: true
167
- },
168
167
  set: {
169
168
  condition(data) {
170
169
  return data instanceof Set;
@@ -173,6 +172,7 @@ const DEFAULT_RPC_JSON_SERIALIZER_HANDLERS = {
173
172
  return Array.from(data);
174
173
  },
175
174
  deserialize(serialized) {
175
+ assertSerializedType(Array.isArray(serialized), "set", "an array");
176
176
  return new Set(serialized);
177
177
  }
178
178
  },
@@ -184,6 +184,7 @@ const DEFAULT_RPC_JSON_SERIALIZER_HANDLERS = {
184
184
  return Array.from(data.entries());
185
185
  },
186
186
  deserialize(serialized) {
187
+ assertSerializedType(Array.isArray(serialized), "map", "an array");
187
188
  return new Map(serialized);
188
189
  }
189
190
  }
@@ -203,7 +204,7 @@ class RPCJsonSerializer {
203
204
  }
204
205
  let inlineBuiltInHandlers = true;
205
206
  let handlerEntries = [];
206
- for (const key in customHandlers) {
207
+ for (const key of Object.keys(customHandlers)) {
207
208
  const handler = customHandlers[key];
208
209
  this.handlers[key] = handler;
209
210
  if (inlineBuiltInHandlers && key in DEFAULT_RPC_JSON_SERIALIZER_HANDLERS) {
@@ -215,7 +216,7 @@ class RPCJsonSerializer {
215
216
  }
216
217
  if (!inlineBuiltInHandlers) {
217
218
  handlerEntries = [];
218
- for (const key in this.handlers) {
219
+ for (const key of Object.keys(this.handlers)) {
219
220
  const handler = this.handlers[key];
220
221
  if (handler !== void 0) {
221
222
  handlerEntries.push([key, handler]);
@@ -270,10 +271,6 @@ class RPCJsonSerializer {
270
271
  meta.push(["url", ...segments]);
271
272
  return data.toString();
272
273
  }
273
- if (data instanceof RegExp) {
274
- meta.push(["regexp", ...segments]);
275
- return data.toString();
276
- }
277
274
  if (data instanceof Set) {
278
275
  const result = this.serializeValue(Array.from(data), segments, meta, maps, blobs);
279
276
  meta.push(["set", ...segments]);
@@ -324,7 +321,7 @@ class RPCJsonSerializer {
324
321
  }
325
322
  if (isPlainObject(data)) {
326
323
  const json = new NullProtoObj();
327
- for (const k in data) {
324
+ for (const k of Object.keys(data)) {
328
325
  const v = data[k];
329
326
  if (k === "toJSON" && typeof v === "function") {
330
327
  continue;
@@ -351,7 +348,7 @@ class RPCJsonSerializer {
351
348
  currentRef = currentRef[preSegment];
352
349
  preSegment = segments[j];
353
350
  if (!Object.hasOwn(currentRef, preSegment)) {
354
- throw new Error(`Security error: Invalid serialized data. Segment "${preSegment}" does not exist.`);
351
+ throw invalidSerializedData(`segment "${preSegment}" does not exist.`);
355
352
  }
356
353
  }
357
354
  currentRef[preSegment] = serialized.blobs[i];
@@ -360,16 +357,20 @@ class RPCJsonSerializer {
360
357
  if (serialized.meta) {
361
358
  for (const item of serialized.meta) {
362
359
  const type = item[0];
360
+ const handler = this.handlers[type];
361
+ if (handler === void 0) {
362
+ throw invalidSerializedData(`type "${type}" is not supported.`);
363
+ }
363
364
  let currentRef = ref;
364
365
  let preSegment = "data";
365
366
  for (let i = 1; i < item.length; i++) {
366
367
  currentRef = currentRef[preSegment];
367
368
  preSegment = item[i];
368
369
  if (!Object.hasOwn(currentRef, preSegment)) {
369
- throw new Error(`Security error: Invalid serialized data. Segment "${preSegment}" does not exist.`);
370
+ throw invalidSerializedData(`segment "${preSegment}" does not exist.`);
370
371
  }
371
372
  }
372
- currentRef[preSegment] = this.handlers[type].deserialize(currentRef[preSegment]);
373
+ currentRef[preSegment] = handler.deserialize(currentRef[preSegment]);
373
374
  }
374
375
  }
375
376
  return ref.data;
@@ -16,7 +16,10 @@ type RPCJsonSerialization = {
16
16
  interface RPCJsonSerializerHandler {
17
17
  condition(value: unknown): boolean;
18
18
  serialize(value: any): unknown;
19
- deserialize(serialized: any): unknown;
19
+ /**
20
+ * `serialized` comes from the wire, so validate its type and throw on mismatch.
21
+ */
22
+ deserialize(serialized: unknown): unknown;
20
23
  /**
21
24
  * If false, the result of this serializer will not be further processed by other serializers,
22
25
  * even if it matches their conditions and treat it as final serialized value.
@@ -60,10 +63,10 @@ interface RPCJsonSerializerOptions {
60
63
  *
61
64
  * **Disabling:** Set a key to `undefined` to remove a built-in handler:
62
65
  * ```ts
63
- * handlers: { regexp: undefined }
66
+ * handlers: { url: undefined }
64
67
  * ```
65
68
  *
66
- * Built-in type keys: `undefined`, `bigint`, `date`, `nan`, `url`, `regexp`, `set`, `map`.
69
+ * Built-in type keys: `undefined`, `bigint`, `date`, `nan`, `url`, `set`, `map`.
67
70
  */
68
71
  handlers?: Record<string, undefined | RPCJsonSerializerHandler> | undefined;
69
72
  /**
@@ -16,7 +16,10 @@ type RPCJsonSerialization = {
16
16
  interface RPCJsonSerializerHandler {
17
17
  condition(value: unknown): boolean;
18
18
  serialize(value: any): unknown;
19
- deserialize(serialized: any): unknown;
19
+ /**
20
+ * `serialized` comes from the wire, so validate its type and throw on mismatch.
21
+ */
22
+ deserialize(serialized: unknown): unknown;
20
23
  /**
21
24
  * If false, the result of this serializer will not be further processed by other serializers,
22
25
  * even if it matches their conditions and treat it as final serialized value.
@@ -60,10 +63,10 @@ interface RPCJsonSerializerOptions {
60
63
  *
61
64
  * **Disabling:** Set a key to `undefined` to remove a built-in handler:
62
65
  * ```ts
63
- * handlers: { regexp: undefined }
66
+ * handlers: { url: undefined }
64
67
  * ```
65
68
  *
66
- * Built-in type keys: `undefined`, `bigint`, `date`, `nan`, `url`, `regexp`, `set`, `map`.
69
+ * Built-in type keys: `undefined`, `bigint`, `date`, `nan`, `url`, `set`, `map`.
67
70
  */
68
71
  handlers?: Record<string, undefined | RPCJsonSerializerHandler> | undefined;
69
72
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/client",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.35",
4
+ "version": "2.0.0-beta.37",
5
5
  "description": "Consume oRPC and OpenAPI APIs with end-to-end type safety over HTTP, WebSocket, or message ports",
6
6
  "license": "MIT",
7
7
  "funding": [
@@ -63,10 +63,10 @@
63
63
  "dist"
64
64
  ],
65
65
  "dependencies": {
66
- "@orpc/shared": "2.0.0-beta.35",
67
- "@standard-server/core": "~0.9.0",
68
- "@standard-server/fetch": "~0.9.0",
69
- "@standard-server/peer": "~0.9.0"
66
+ "@orpc/shared": "2.0.0-beta.37",
67
+ "@standard-server/core": "~0.9.2",
68
+ "@standard-server/fetch": "~0.9.2",
69
+ "@standard-server/peer": "~0.9.2"
70
70
  },
71
71
  "devDependencies": {
72
72
  "zod": "^4.5.4"