@orpc/client 0.0.0-next.a15ca72 → 0.0.0-next.a16ca72

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 (31) hide show
  1. package/README.md +15 -10
  2. package/dist/adapters/fetch/index.d.mts +25 -12
  3. package/dist/adapters/fetch/index.d.ts +25 -12
  4. package/dist/adapters/fetch/index.mjs +25 -8
  5. package/dist/adapters/message-port/index.d.mts +30 -9
  6. package/dist/adapters/message-port/index.d.ts +30 -9
  7. package/dist/adapters/message-port/index.mjs +26 -10
  8. package/dist/adapters/standard/index.d.mts +6 -5
  9. package/dist/adapters/standard/index.d.ts +6 -5
  10. package/dist/adapters/standard/index.mjs +4 -2
  11. package/dist/adapters/websocket/index.d.mts +5 -5
  12. package/dist/adapters/websocket/index.d.ts +5 -5
  13. package/dist/adapters/websocket/index.mjs +7 -4
  14. package/dist/index.d.mts +55 -10
  15. package/dist/index.d.ts +55 -10
  16. package/dist/index.mjs +36 -6
  17. package/dist/plugins/index.d.mts +56 -9
  18. package/dist/plugins/index.d.ts +56 -9
  19. package/dist/plugins/index.mjs +121 -25
  20. package/dist/shared/{client.CXXEPIbK.d.ts → client.2jUAqzYU.d.ts} +1 -2
  21. package/dist/shared/{client.WCinBImJ.d.ts → client.B3pNRBih.d.ts} +3 -3
  22. package/dist/shared/{client.aTp4sII-.d.mts → client.BFAVy68H.d.mts} +3 -3
  23. package/dist/shared/client.BLtwTQUg.mjs +40 -0
  24. package/dist/shared/{client.BngOL3Ai.mjs → client.BbIS_l12.mjs} +30 -32
  25. package/dist/shared/{client.C4VxIexA.d.mts → client.CpCa3si8.d.mts} +1 -2
  26. package/dist/shared/client.i2uoJbEp.d.mts +83 -0
  27. package/dist/shared/client.i2uoJbEp.d.ts +83 -0
  28. package/dist/shared/{client.BvXDSBF5.mjs → client.qLXZI_yO.mjs} +69 -20
  29. package/package.json +8 -9
  30. package/dist/shared/client.BOYsZIRq.d.mts +0 -29
  31. package/dist/shared/client.BOYsZIRq.d.ts +0 -29
@@ -1,6 +1,8 @@
1
- import { toArray, intercept, isObject, value, isAsyncIteratorObject, stringifyJSON } from '@orpc/shared';
1
+ import { toArray, runWithSpan, ORPC_NAME, isAsyncIteratorObject, asyncIteratorWithSpan, intercept, getGlobalOtelConfig, isObject, value, stringifyJSON } from '@orpc/shared';
2
2
  import { mergeStandardHeaders, ErrorEvent } from '@orpc/standard-server';
3
- import { C as COMMON_ORPC_ERROR_DEFS, b as isORPCErrorStatus, c as isORPCErrorJson, d as createORPCErrorFromJson, O as ORPCError, m as mapEventIterator, t as toORPCError } from './client.BngOL3Ai.mjs';
3
+ import { C as COMMON_ORPC_ERROR_DEFS, d as isORPCErrorStatus, e as isORPCErrorJson, g as createORPCErrorFromJson, c as ORPCError, t as toORPCError } from './client.BbIS_l12.mjs';
4
+ import { toStandardHeaders as toStandardHeaders$1 } from '@orpc/standard-server-fetch';
5
+ import { m as mapEventIterator } from './client.BLtwTQUg.mjs';
4
6
 
5
7
  class CompositeStandardLinkPlugin {
6
8
  plugins;
@@ -26,20 +28,52 @@ class StandardLink {
26
28
  interceptors;
27
29
  clientInterceptors;
28
30
  call(path, input, options) {
29
- return intercept(this.interceptors, { ...options, path, input }, async ({ path: path2, input: input2, ...options2 }) => {
30
- const output = await this.#call(path2, input2, options2);
31
- return output;
32
- });
33
- }
34
- async #call(path, input, options) {
35
- const request = await this.codec.encode(path, input, options);
36
- const response = await intercept(
37
- this.clientInterceptors,
38
- { ...options, input, path, request },
39
- ({ input: input2, path: path2, request: request2, ...options2 }) => this.sender.call(request2, options2, path2, input2)
31
+ return runWithSpan(
32
+ { name: `${ORPC_NAME}.${path.join("/")}`, signal: options.signal },
33
+ (span) => {
34
+ span?.setAttribute("rpc.system", ORPC_NAME);
35
+ span?.setAttribute("rpc.method", path.join("."));
36
+ if (isAsyncIteratorObject(input)) {
37
+ input = asyncIteratorWithSpan(
38
+ { name: "consume_event_iterator_input", signal: options.signal },
39
+ input
40
+ );
41
+ }
42
+ return intercept(this.interceptors, { ...options, path, input }, async ({ path: path2, input: input2, ...options2 }) => {
43
+ const otelConfig = getGlobalOtelConfig();
44
+ let otelContext;
45
+ const currentSpan = otelConfig?.trace.getActiveSpan() ?? span;
46
+ if (currentSpan && otelConfig) {
47
+ otelContext = otelConfig?.trace.setSpan(otelConfig.context.active(), currentSpan);
48
+ }
49
+ const request = await runWithSpan(
50
+ { name: "encode_request", context: otelContext },
51
+ () => this.codec.encode(path2, input2, options2)
52
+ );
53
+ const response = await intercept(
54
+ this.clientInterceptors,
55
+ { ...options2, input: input2, path: path2, request },
56
+ ({ input: input3, path: path3, request: request2, ...options3 }) => {
57
+ return runWithSpan(
58
+ { name: "send_request", signal: options3.signal, context: otelContext },
59
+ () => this.sender.call(request2, options3, path3, input3)
60
+ );
61
+ }
62
+ );
63
+ const output = await runWithSpan(
64
+ { name: "decode_response", context: otelContext },
65
+ () => this.codec.decode(response, options2, path2, input2)
66
+ );
67
+ if (isAsyncIteratorObject(output)) {
68
+ return asyncIteratorWithSpan(
69
+ { name: "consume_event_iterator_output", signal: options2.signal },
70
+ output
71
+ );
72
+ }
73
+ return output;
74
+ });
75
+ }
40
76
  );
41
- const output = await this.codec.decode(response, options, path, input);
42
- return output;
43
77
  }
44
78
  }
45
79
 
@@ -138,6 +172,9 @@ class StandardRPCJsonSerializer {
138
172
  segments.forEach((segment) => {
139
173
  currentRef = currentRef[preSegment];
140
174
  preSegment = segment;
175
+ if (!Object.hasOwn(currentRef, preSegment)) {
176
+ throw new Error(`Security error: accessing non-existent path during deserialization. Path segment: ${preSegment}`);
177
+ }
141
178
  });
142
179
  currentRef[preSegment] = getBlob(i);
143
180
  });
@@ -149,6 +186,9 @@ class StandardRPCJsonSerializer {
149
186
  for (let i = 1; i < item.length; i++) {
150
187
  currentRef = currentRef[preSegment];
151
188
  preSegment = item[i];
189
+ if (!Object.hasOwn(currentRef, preSegment)) {
190
+ throw new Error(`Security error: accessing non-existent path during deserialization. Path segment: ${preSegment}`);
191
+ }
152
192
  }
153
193
  for (const custom of this.customSerializers) {
154
194
  if (custom.type === type) {
@@ -192,6 +232,12 @@ class StandardRPCJsonSerializer {
192
232
  function toHttpPath(path) {
193
233
  return `/${path.map(encodeURIComponent).join("/")}`;
194
234
  }
235
+ function toStandardHeaders(headers) {
236
+ if (typeof headers.forEach === "function") {
237
+ return toStandardHeaders$1(headers);
238
+ }
239
+ return headers;
240
+ }
195
241
  function getMalformedResponseErrorCode(status) {
196
242
  return Object.entries(COMMON_ORPC_ERROR_DEFS).find(([, def]) => def.status === status)?.[0] ?? "MALFORMED_ORPC_ERROR_RESPONSE";
197
243
  }
@@ -211,14 +257,14 @@ class StandardRPCLinkCodec {
211
257
  expectedMethod;
212
258
  headers;
213
259
  async encode(path, input, options) {
260
+ let headers = toStandardHeaders(await value(this.headers, options, path, input));
261
+ if (options.lastEventId !== void 0) {
262
+ headers = mergeStandardHeaders(headers, { "last-event-id": options.lastEventId });
263
+ }
214
264
  const expectedMethod = await value(this.expectedMethod, options, path, input);
215
- let headers = await value(this.headers, options, path, input);
216
265
  const baseUrl = await value(this.baseUrl, options, path, input);
217
266
  const url = new URL(baseUrl);
218
267
  url.pathname = `${url.pathname.replace(/\/$/, "")}${toHttpPath(path)}`;
219
- if (options.lastEventId !== void 0) {
220
- headers = mergeStandardHeaders(headers, { "last-event-id": options.lastEventId });
221
- }
222
268
  const serialized = this.serializer.serialize(input);
223
269
  if (expectedMethod === "GET" && !(serialized instanceof FormData) && !isAsyncIteratorObject(serialized)) {
224
270
  const maxUrlLength = await value(this.maxUrlLength, options, path, input);
@@ -330,6 +376,9 @@ class StandardRPCSerializer {
330
376
  return this.#deserialize(data);
331
377
  }
332
378
  #deserialize(data) {
379
+ if (data === void 0) {
380
+ return void 0;
381
+ }
333
382
  if (!(data instanceof FormData)) {
334
383
  return this.jsonSerializer.deserialize(data.json, data.meta ?? []);
335
384
  }
@@ -352,4 +401,4 @@ class StandardRPCLink extends StandardLink {
352
401
  }
353
402
  }
354
403
 
355
- export { CompositeStandardLinkPlugin as C, StandardLink as S, STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES as a, StandardRPCJsonSerializer as b, StandardRPCLink as c, StandardRPCLinkCodec as d, StandardRPCSerializer as e, getMalformedResponseErrorCode as g, toHttpPath as t };
404
+ export { CompositeStandardLinkPlugin as C, StandardLink as S, STANDARD_RPC_JSON_SERIALIZER_BUILT_IN_TYPES as a, StandardRPCJsonSerializer as b, StandardRPCLink as c, StandardRPCLinkCodec as d, StandardRPCSerializer as e, toStandardHeaders as f, getMalformedResponseErrorCode as g, toHttpPath as t };
package/package.json CHANGED
@@ -1,16 +1,15 @@
1
1
  {
2
2
  "name": "@orpc/client",
3
3
  "type": "module",
4
- "version": "0.0.0-next.a15ca72",
4
+ "version": "0.0.0-next.a16ca72",
5
5
  "license": "MIT",
6
- "homepage": "https://orpc.unnoq.com",
6
+ "homepage": "https://orpc.dev",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/unnoq/orpc.git",
9
+ "url": "git+https://github.com/middleapi/orpc.git",
10
10
  "directory": "packages/client"
11
11
  },
12
12
  "keywords": [
13
- "unnoq",
14
13
  "orpc"
15
14
  ],
16
15
  "exports": {
@@ -49,13 +48,13 @@
49
48
  "dist"
50
49
  ],
51
50
  "dependencies": {
52
- "@orpc/shared": "0.0.0-next.a15ca72",
53
- "@orpc/standard-server": "0.0.0-next.a15ca72",
54
- "@orpc/standard-server-fetch": "0.0.0-next.a15ca72",
55
- "@orpc/standard-server-peer": "0.0.0-next.a15ca72"
51
+ "@orpc/shared": "0.0.0-next.a16ca72",
52
+ "@orpc/standard-server": "0.0.0-next.a16ca72",
53
+ "@orpc/standard-server-fetch": "0.0.0-next.a16ca72",
54
+ "@orpc/standard-server-peer": "0.0.0-next.a16ca72"
56
55
  },
57
56
  "devDependencies": {
58
- "zod": "^4.0.14"
57
+ "zod": "^4.3.6"
59
58
  },
60
59
  "scripts": {
61
60
  "build": "unbuild",
@@ -1,29 +0,0 @@
1
- import { PromiseWithError } from '@orpc/shared';
2
-
3
- type HTTPPath = `/${string}`;
4
- type HTTPMethod = 'HEAD' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
5
- type ClientContext = Record<PropertyKey, any>;
6
- interface ClientOptions<T extends ClientContext> {
7
- signal?: AbortSignal;
8
- lastEventId?: string | undefined;
9
- context: T;
10
- }
11
- type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (Record<never, never> extends T ? {
12
- context?: T;
13
- } : {
14
- context: T;
15
- });
16
- type ClientRest<TClientContext extends ClientContext, TInput> = Record<never, never> extends TClientContext ? undefined extends TInput ? [input?: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options: FriendlyClientOptions<TClientContext>];
17
- type ClientPromiseResult<TOutput, TError> = PromiseWithError<TOutput, TError>;
18
- interface Client<TClientContext extends ClientContext, TInput, TOutput, TError> {
19
- (...rest: ClientRest<TClientContext, TInput>): ClientPromiseResult<TOutput, TError>;
20
- }
21
- type NestedClient<TClientContext extends ClientContext> = Client<TClientContext, any, any, any> | {
22
- [k: string]: NestedClient<TClientContext>;
23
- };
24
- type InferClientContext<T extends NestedClient<any>> = T extends NestedClient<infer U> ? U : never;
25
- interface ClientLink<TClientContext extends ClientContext> {
26
- call: (path: readonly string[], input: unknown, options: ClientOptions<TClientContext>) => Promise<unknown>;
27
- }
28
-
29
- export type { ClientLink as C, FriendlyClientOptions as F, HTTPPath as H, InferClientContext as I, NestedClient as N, ClientPromiseResult as a, ClientContext as b, ClientOptions as c, Client as d, ClientRest as e, HTTPMethod as f };
@@ -1,29 +0,0 @@
1
- import { PromiseWithError } from '@orpc/shared';
2
-
3
- type HTTPPath = `/${string}`;
4
- type HTTPMethod = 'HEAD' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
5
- type ClientContext = Record<PropertyKey, any>;
6
- interface ClientOptions<T extends ClientContext> {
7
- signal?: AbortSignal;
8
- lastEventId?: string | undefined;
9
- context: T;
10
- }
11
- type FriendlyClientOptions<T extends ClientContext> = Omit<ClientOptions<T>, 'context'> & (Record<never, never> extends T ? {
12
- context?: T;
13
- } : {
14
- context: T;
15
- });
16
- type ClientRest<TClientContext extends ClientContext, TInput> = Record<never, never> extends TClientContext ? undefined extends TInput ? [input?: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options?: FriendlyClientOptions<TClientContext>] : [input: TInput, options: FriendlyClientOptions<TClientContext>];
17
- type ClientPromiseResult<TOutput, TError> = PromiseWithError<TOutput, TError>;
18
- interface Client<TClientContext extends ClientContext, TInput, TOutput, TError> {
19
- (...rest: ClientRest<TClientContext, TInput>): ClientPromiseResult<TOutput, TError>;
20
- }
21
- type NestedClient<TClientContext extends ClientContext> = Client<TClientContext, any, any, any> | {
22
- [k: string]: NestedClient<TClientContext>;
23
- };
24
- type InferClientContext<T extends NestedClient<any>> = T extends NestedClient<infer U> ? U : never;
25
- interface ClientLink<TClientContext extends ClientContext> {
26
- call: (path: readonly string[], input: unknown, options: ClientOptions<TClientContext>) => Promise<unknown>;
27
- }
28
-
29
- export type { ClientLink as C, FriendlyClientOptions as F, HTTPPath as H, InferClientContext as I, NestedClient as N, ClientPromiseResult as a, ClientContext as b, ClientOptions as c, Client as d, ClientRest as e, HTTPMethod as f };