@orpc/client 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
package/dist/fetch.js ADDED
@@ -0,0 +1,46 @@
1
+ // src/adapters/fetch/orpc-link.ts
2
+ import { ORPCPayloadCodec } from "@orpc/server/fetch";
3
+ import { ORPC_HANDLER_HEADER, ORPC_HANDLER_VALUE, trim } from "@orpc/shared";
4
+ import { ORPCError } from "@orpc/shared/error";
5
+ var ORPCLink = class {
6
+ constructor(options) {
7
+ this.options = options;
8
+ this.fetch = options.fetch ?? globalThis.fetch.bind(globalThis);
9
+ this.payloadCodec = options.payloadCodec ?? new ORPCPayloadCodec();
10
+ }
11
+ fetch;
12
+ payloadCodec;
13
+ async call(path, input, options) {
14
+ const url = `${trim(this.options.url, "/")}/${path.map(encodeURIComponent).join("/")}`;
15
+ const encoded = this.payloadCodec.encode(input);
16
+ const headers = new Headers(encoded.headers);
17
+ headers.append(ORPC_HANDLER_HEADER, ORPC_HANDLER_VALUE);
18
+ const clientContext = options.context;
19
+ let customHeaders = await this.options.headers?.(input, clientContext);
20
+ customHeaders = customHeaders instanceof Headers ? customHeaders : new Headers(customHeaders);
21
+ for (const [key, value] of customHeaders.entries()) {
22
+ headers.append(key, value);
23
+ }
24
+ const response = await this.fetch(url, {
25
+ method: "POST",
26
+ headers,
27
+ body: encoded.body,
28
+ signal: options.signal
29
+ }, clientContext);
30
+ const decoded = await this.payloadCodec.decode(response);
31
+ if (!response.ok) {
32
+ const error = ORPCError.fromJSON(decoded) ?? new ORPCError({
33
+ status: response.status,
34
+ code: "INTERNAL_SERVER_ERROR",
35
+ message: "Internal server error",
36
+ cause: decoded
37
+ });
38
+ throw error;
39
+ }
40
+ return decoded;
41
+ }
42
+ };
43
+ export {
44
+ ORPCLink
45
+ };
46
+ //# sourceMappingURL=fetch.js.map
package/dist/index.js CHANGED
@@ -1,78 +1,39 @@
1
- // src/procedure-fetch-client.ts
2
- import { ORPCPayloadCodec } from "@orpc/server/fetch";
3
- import { ORPC_HANDLER_HEADER, ORPC_HANDLER_VALUE, trim } from "@orpc/shared";
4
- import { ORPCError } from "@orpc/shared/error";
5
- var payloadCodec = new ORPCPayloadCodec();
6
- function createProcedureFetchClient(options) {
7
- const client = async (...[input, callerOptions]) => {
8
- const fetchClient = options.fetch ?? fetch;
9
- const url = `${trim(options.baseURL, "/")}/${options.path.map(encodeURIComponent).join("/")}`;
10
- const encoded = payloadCodec.encode(input);
11
- const headers = new Headers(encoded.headers);
12
- headers.append(ORPC_HANDLER_HEADER, ORPC_HANDLER_VALUE);
13
- let customHeaders = await options.headers?.(input);
14
- customHeaders = customHeaders instanceof Headers ? customHeaders : new Headers(customHeaders);
15
- for (const [key, value] of customHeaders.entries()) {
16
- headers.append(key, value);
17
- }
18
- const response = await fetchClient(url, {
19
- method: "POST",
20
- headers,
21
- body: encoded.body,
22
- signal: callerOptions?.signal
23
- });
24
- const json = await (async () => {
25
- try {
26
- return await payloadCodec.decode(response);
27
- } catch (e) {
28
- throw new ORPCError({
29
- code: "INTERNAL_SERVER_ERROR",
30
- message: "Cannot parse response.",
31
- cause: e
32
- });
1
+ // src/client.ts
2
+ function createORPCClient(link, options) {
3
+ const path = options?.path ?? [];
4
+ const procedureClient = async (...[input, options2]) => {
5
+ return await link.call(path, input, options2 ?? {});
6
+ };
7
+ const recursive = new Proxy(procedureClient, {
8
+ get(target, key) {
9
+ if (typeof key !== "string") {
10
+ return Reflect.get(target, key);
33
11
  }
34
- })();
35
- if (!response.ok) {
36
- throw ORPCError.fromJSON(json) ?? new ORPCError({
37
- status: response.status,
38
- code: "INTERNAL_SERVER_ERROR",
39
- message: "Internal server error"
12
+ return createORPCClient(link, {
13
+ ...options,
14
+ path: [...path, key]
40
15
  });
41
16
  }
42
- return json;
43
- };
44
- return client;
17
+ });
18
+ return recursive;
45
19
  }
46
20
 
47
- // src/router-fetch-client.ts
48
- function createRouterFetchClient(options) {
49
- const path = options?.path ?? [];
50
- const client = new Proxy(
51
- createProcedureFetchClient({
52
- ...options,
53
- path
54
- }),
55
- {
56
- get(target, key) {
57
- if (typeof key !== "string") {
58
- return Reflect.get(target, key);
59
- }
60
- return createRouterFetchClient({
61
- ...options,
62
- path: [...path, key]
63
- });
64
- }
65
- }
66
- );
67
- return client;
68
- }
21
+ // src/dynamic-link.ts
22
+ var DynamicLink = class {
23
+ constructor(linkResolver) {
24
+ this.linkResolver = linkResolver;
25
+ }
26
+ async call(path, input, options) {
27
+ const resolvedLink = await this.linkResolver(path, input, options);
28
+ const output = await resolvedLink.call(path, input, options);
29
+ return output;
30
+ }
31
+ };
69
32
 
70
33
  // src/index.ts
71
34
  export * from "@orpc/shared/error";
72
- var createORPCFetchClient = createRouterFetchClient;
73
35
  export {
74
- createORPCFetchClient,
75
- createProcedureFetchClient,
76
- createRouterFetchClient
36
+ DynamicLink,
37
+ createORPCClient
77
38
  };
78
39
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,3 @@
1
+ export * from './orpc-link';
2
+ export * from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,19 @@
1
+ import type { ProcedureClientOptions } from '@orpc/server';
2
+ import type { Promisable } from '@orpc/shared';
3
+ import type { ClientLink } from '../../types';
4
+ import type { FetchWithContext } from './types';
5
+ import { type PublicORPCPayloadCodec } from '@orpc/server/fetch';
6
+ export interface ORPCLinkOptions<TClientContext> {
7
+ url: string;
8
+ headers?: (input: unknown, context: TClientContext) => Promisable<Headers | Record<string, string>>;
9
+ fetch?: FetchWithContext<TClientContext>;
10
+ payloadCodec?: PublicORPCPayloadCodec;
11
+ }
12
+ export declare class ORPCLink<TClientContext> implements ClientLink<TClientContext> {
13
+ private readonly options;
14
+ private readonly fetch;
15
+ private readonly payloadCodec;
16
+ constructor(options: ORPCLinkOptions<TClientContext>);
17
+ call(path: readonly string[], input: unknown, options: ProcedureClientOptions<TClientContext>): Promise<unknown>;
18
+ }
19
+ //# sourceMappingURL=orpc-link.d.ts.map
@@ -0,0 +1,4 @@
1
+ export interface FetchWithContext<TClientContext> {
2
+ (input: RequestInfo | URL, init: RequestInit | undefined, context: TClientContext): Promise<Response>;
3
+ }
4
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,11 @@
1
+ import type { ContractRouter } from '@orpc/contract';
2
+ import type { ANY_ROUTER, RouterClient } from '@orpc/server';
3
+ import type { ClientLink } from './types';
4
+ export interface createORPCClientOptions {
5
+ /**
6
+ * Use as base path for all procedure, useful when you only want to call a subset of the procedure.
7
+ */
8
+ path?: string[];
9
+ }
10
+ export declare function createORPCClient<TRouter extends ANY_ROUTER | ContractRouter, TClientContext = unknown>(link: ClientLink<TClientContext>, options?: createORPCClientOptions): RouterClient<TRouter, TClientContext>;
11
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1,15 @@
1
+ import type { ProcedureClientOptions } from '@orpc/server';
2
+ import type { Promisable } from '@orpc/shared';
3
+ import type { ClientLink } from './types';
4
+ /**
5
+ * DynamicLink provides a way to dynamically resolve and delegate calls to other ClientLinks
6
+ * based on the request path, input, and context.
7
+ */
8
+ export declare class DynamicLink<TClientContext> implements ClientLink<TClientContext> {
9
+ private readonly linkResolver;
10
+ constructor(linkResolver: (path: readonly string[], input: unknown, options: ProcedureClientOptions<TClientContext> & {
11
+ context: TClientContext;
12
+ }) => Promisable<ClientLink<TClientContext>>);
13
+ call(path: readonly string[], input: unknown, options: ProcedureClientOptions<TClientContext>): Promise<unknown>;
14
+ }
15
+ //# sourceMappingURL=dynamic-link.d.ts.map
@@ -1,7 +1,6 @@
1
1
  /** unnoq */
2
- import { createRouterFetchClient } from './router-fetch-client';
3
- export * from './procedure-fetch-client';
4
- export * from './router-fetch-client';
2
+ export * from './client';
3
+ export * from './dynamic-link';
4
+ export * from './types';
5
5
  export * from '@orpc/shared/error';
6
- export declare const createORPCFetchClient: typeof createRouterFetchClient;
7
6
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,5 @@
1
+ import type { ProcedureClientOptions } from '@orpc/server';
2
+ export interface ClientLink<TClientContext> {
3
+ call: (path: readonly string[], input: unknown, options: ProcedureClientOptions<TClientContext>) => Promise<unknown>;
4
+ }
5
+ //# sourceMappingURL=types.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/client",
3
3
  "type": "module",
4
- "version": "0.19.0",
4
+ "version": "0.20.0",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -19,6 +19,11 @@
19
19
  "import": "./dist/index.js",
20
20
  "default": "./dist/index.js"
21
21
  },
22
+ "./fetch": {
23
+ "types": "./dist/src/adapters/fetch/index.d.ts",
24
+ "import": "./dist/fetch.js",
25
+ "default": "./dist/fetch.js"
26
+ },
22
27
  "./🔒/*": {
23
28
  "types": "./dist/src/*.d.ts"
24
29
  }
@@ -29,18 +34,18 @@
29
34
  "dist"
30
35
  ],
31
36
  "peerDependencies": {
32
- "@orpc/contract": "0.19.0"
37
+ "@orpc/contract": "0.20.0"
33
38
  },
34
39
  "dependencies": {
35
- "@orpc/server": "0.19.0",
36
- "@orpc/shared": "0.19.0"
40
+ "@orpc/server": "0.20.0",
41
+ "@orpc/shared": "0.20.0"
37
42
  },
38
43
  "devDependencies": {
39
44
  "zod": "^3.24.1",
40
- "@orpc/openapi": "0.19.0"
45
+ "@orpc/openapi": "0.20.0"
41
46
  },
42
47
  "scripts": {
43
- "build": "tsup --clean --sourcemap --entry.index=src/index.ts --format=esm --onSuccess='tsc -b --noCheck'",
48
+ "build": "tsup --clean --sourcemap --entry.index=src/index.ts --entry.fetch=src/adapters/fetch/index.ts --format=esm --onSuccess='tsc -b --noCheck'",
44
49
  "build:watch": "pnpm run build --watch",
45
50
  "type:check": "tsc -b"
46
51
  }
@@ -1,24 +0,0 @@
1
- import type { ProcedureClient } from '@orpc/server';
2
- import type { Promisable } from '@orpc/shared';
3
- export interface CreateProcedureClientOptions {
4
- /**
5
- * The base url of the server.
6
- */
7
- baseURL: string;
8
- /**
9
- * The fetch function used to make the request.
10
- * @default global fetch
11
- */
12
- fetch?: typeof fetch;
13
- /**
14
- * The headers used to make the request.
15
- * Invoked before the request is made.
16
- */
17
- headers?: (input: unknown) => Promisable<Headers | Record<string, string>>;
18
- /**
19
- * The path of the procedure on server.
20
- */
21
- path: string[];
22
- }
23
- export declare function createProcedureFetchClient<TInput, TOutput>(options: CreateProcedureClientOptions): ProcedureClient<TInput, TOutput>;
24
- //# sourceMappingURL=procedure-fetch-client.d.ts.map
@@ -1,6 +0,0 @@
1
- import type { ContractRouter } from '@orpc/contract';
2
- import type { ANY_ROUTER, RouterClient } from '@orpc/server';
3
- import type { SetOptional } from '@orpc/shared';
4
- import type { CreateProcedureClientOptions } from './procedure-fetch-client';
5
- export declare function createRouterFetchClient<T extends ANY_ROUTER | ContractRouter>(options: SetOptional<CreateProcedureClientOptions, 'path'>): RouterClient<T>;
6
- //# sourceMappingURL=router-fetch-client.d.ts.map