@orpc/client 0.0.0-next.c12be86 → 0.0.0-next.c3068b4
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/fetch.js +59 -43
- package/dist/index.js +5 -2
- package/dist/src/adapters/fetch/orpc-link.d.ts +12 -13
- package/dist/src/client.d.ts +3 -3
- package/dist/src/dynamic-link.d.ts +2 -2
- package/dist/src/index.d.ts +1 -1
- package/dist/src/types.d.ts +2 -2
- package/package.json +6 -7
package/dist/fetch.js
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
// src/adapters/fetch/orpc-link.ts
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
|
2
|
+
import { ORPCError } from "@orpc/contract";
|
3
|
+
import { fetchReToStandardBody } from "@orpc/server/fetch";
|
4
|
+
import { RPCSerializer } from "@orpc/server/standard";
|
5
|
+
import { isPlainObject, trim } from "@orpc/shared";
|
6
|
+
import cd from "content-disposition";
|
7
|
+
var RPCLink = class {
|
6
8
|
fetch;
|
7
|
-
|
9
|
+
rpcSerializer;
|
8
10
|
maxURLLength;
|
9
11
|
fallbackMethod;
|
10
12
|
getMethod;
|
@@ -12,7 +14,7 @@ var ORPCLink = class {
|
|
12
14
|
url;
|
13
15
|
constructor(options) {
|
14
16
|
this.fetch = options.fetch ?? globalThis.fetch.bind(globalThis);
|
15
|
-
this.
|
17
|
+
this.rpcSerializer = options.rpcSerializer ?? new RPCSerializer();
|
16
18
|
this.maxURLLength = options.maxURLLength ?? 2083;
|
17
19
|
this.fallbackMethod = options.fallbackMethod ?? "POST";
|
18
20
|
this.url = options.url;
|
@@ -26,62 +28,76 @@ var ORPCLink = class {
|
|
26
28
|
async call(path, input, options) {
|
27
29
|
const clientContext = options.context;
|
28
30
|
const encoded = await this.encode(path, input, options);
|
31
|
+
if (encoded.body instanceof Blob && !encoded.headers.has("content-disposition")) {
|
32
|
+
encoded.headers.set("content-disposition", cd(encoded.body instanceof File ? encoded.body.name : "blob"));
|
33
|
+
}
|
29
34
|
const response = await this.fetch(encoded.url, {
|
30
35
|
method: encoded.method,
|
31
36
|
headers: encoded.headers,
|
32
37
|
body: encoded.body,
|
33
38
|
signal: options.signal
|
34
39
|
}, clientContext);
|
35
|
-
const
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
const body = await fetchReToStandardBody(response);
|
41
|
+
const deserialized = (() => {
|
42
|
+
try {
|
43
|
+
return this.rpcSerializer.deserialize(body);
|
44
|
+
} catch (error) {
|
45
|
+
if (response.ok) {
|
46
|
+
throw new ORPCError("INTERNAL_SERVER_ERROR", {
|
47
|
+
message: "Invalid RPC response",
|
48
|
+
cause: error
|
49
|
+
});
|
50
|
+
}
|
51
|
+
throw new ORPCError(response.status.toString(), {
|
52
|
+
message: response.statusText
|
53
|
+
});
|
54
|
+
}
|
55
|
+
})();
|
56
|
+
if (response.ok) {
|
57
|
+
return deserialized;
|
44
58
|
}
|
45
|
-
|
59
|
+
throw ORPCError.fromJSON(deserialized);
|
46
60
|
}
|
47
61
|
async encode(path, input, options) {
|
48
62
|
const clientContext = options.context;
|
49
63
|
const expectMethod = await this.getMethod(path, input, clientContext);
|
50
|
-
const
|
51
|
-
const
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
const
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
64
|
+
const headers = await this.getHeaders(path, input, clientContext);
|
65
|
+
const url = new URL(`${trim(this.url, "/")}/${path.map(encodeURIComponent).join("/")}`);
|
66
|
+
headers.append("x-orpc-handler", "rpc");
|
67
|
+
const serialized = this.rpcSerializer.serialize(input);
|
68
|
+
if (expectMethod === "GET" && isPlainObject(serialized)) {
|
69
|
+
const tryURL = new URL(url);
|
70
|
+
tryURL.searchParams.append("data", JSON.stringify(serialized));
|
71
|
+
if (tryURL.toString().length <= this.maxURLLength) {
|
72
|
+
return {
|
73
|
+
body: void 0,
|
74
|
+
method: expectMethod,
|
75
|
+
headers,
|
76
|
+
url: tryURL
|
77
|
+
};
|
62
78
|
}
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
if (
|
67
|
-
|
68
|
-
headers.append(key, value);
|
69
|
-
}
|
79
|
+
}
|
80
|
+
const method = expectMethod === "GET" ? this.fallbackMethod : expectMethod;
|
81
|
+
if (isPlainObject(serialized)) {
|
82
|
+
if (!headers.has("content-type")) {
|
83
|
+
headers.set("content-type", "application/json");
|
70
84
|
}
|
71
85
|
return {
|
72
|
-
|
86
|
+
body: JSON.stringify(serialized),
|
87
|
+
method,
|
73
88
|
headers,
|
74
|
-
|
75
|
-
body: encoded.body
|
89
|
+
url
|
76
90
|
};
|
77
91
|
}
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
92
|
+
return {
|
93
|
+
body: serialized,
|
94
|
+
method,
|
95
|
+
headers,
|
96
|
+
url
|
97
|
+
};
|
82
98
|
}
|
83
99
|
};
|
84
100
|
export {
|
85
|
-
|
101
|
+
RPCLink
|
86
102
|
};
|
87
103
|
//# sourceMappingURL=fetch.js.map
|
package/dist/index.js
CHANGED
@@ -31,9 +31,12 @@ var DynamicLink = class {
|
|
31
31
|
};
|
32
32
|
|
33
33
|
// src/index.ts
|
34
|
-
|
34
|
+
import { isDefinedError, ORPCError, safe } from "@orpc/contract";
|
35
35
|
export {
|
36
36
|
DynamicLink,
|
37
|
-
|
37
|
+
ORPCError,
|
38
|
+
createORPCClient,
|
39
|
+
isDefinedError,
|
40
|
+
safe
|
38
41
|
};
|
39
42
|
//# sourceMappingURL=index.js.map
|
@@ -1,10 +1,9 @@
|
|
1
|
-
import type { HTTPMethod } from '@orpc/contract';
|
2
|
-
import type { ProcedureClientOptions } from '@orpc/server';
|
1
|
+
import type { ClientOptions, HTTPMethod } from '@orpc/contract';
|
3
2
|
import type { Promisable } from '@orpc/shared';
|
4
3
|
import type { ClientLink } from '../../types';
|
5
4
|
import type { FetchWithContext } from './types';
|
6
|
-
import {
|
7
|
-
export interface
|
5
|
+
import { RPCSerializer } from '@orpc/server/standard';
|
6
|
+
export interface RPCLinkOptions<TClientContext> {
|
8
7
|
/**
|
9
8
|
* Base url for all requests.
|
10
9
|
*/
|
@@ -20,28 +19,28 @@ export interface ORPCLinkOptions<TClientContext> {
|
|
20
19
|
*
|
21
20
|
* @default 'POST'
|
22
21
|
*/
|
23
|
-
method
|
22
|
+
method?(path: readonly string[], input: unknown, context: TClientContext): Promisable<HTTPMethod | undefined>;
|
24
23
|
/**
|
25
24
|
* The method to use when the payload cannot safely pass to the server with method return from method function.
|
26
|
-
*
|
25
|
+
* GET is not allowed, it's very dangerous.
|
27
26
|
*
|
28
27
|
* @default 'POST'
|
29
28
|
*/
|
30
|
-
fallbackMethod?: HTTPMethod
|
31
|
-
headers
|
29
|
+
fallbackMethod?: Exclude<HTTPMethod, 'GET'>;
|
30
|
+
headers?(path: readonly string[], input: unknown, context: TClientContext): Promisable<Headers | Record<string, string>>;
|
32
31
|
fetch?: FetchWithContext<TClientContext>;
|
33
|
-
|
32
|
+
rpcSerializer?: RPCSerializer;
|
34
33
|
}
|
35
|
-
export declare class
|
34
|
+
export declare class RPCLink<TClientContext> implements ClientLink<TClientContext> {
|
36
35
|
private readonly fetch;
|
37
|
-
private readonly
|
36
|
+
private readonly rpcSerializer;
|
38
37
|
private readonly maxURLLength;
|
39
38
|
private readonly fallbackMethod;
|
40
39
|
private readonly getMethod;
|
41
40
|
private readonly getHeaders;
|
42
41
|
private readonly url;
|
43
|
-
constructor(options:
|
44
|
-
call(path: readonly string[], input: unknown, options:
|
42
|
+
constructor(options: RPCLinkOptions<TClientContext>);
|
43
|
+
call(path: readonly string[], input: unknown, options: ClientOptions<TClientContext>): Promise<unknown>;
|
45
44
|
private encode;
|
46
45
|
}
|
47
46
|
//# sourceMappingURL=orpc-link.d.ts.map
|
package/dist/src/client.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import type {
|
2
|
-
import type {
|
1
|
+
import type { AnyContractRouter, ContractRouterClient } from '@orpc/contract';
|
2
|
+
import type { AnyRouter, RouterClient } from '@orpc/server';
|
3
3
|
import type { ClientLink } from './types';
|
4
4
|
export interface createORPCClientOptions {
|
5
5
|
/**
|
@@ -7,5 +7,5 @@ export interface createORPCClientOptions {
|
|
7
7
|
*/
|
8
8
|
path?: string[];
|
9
9
|
}
|
10
|
-
export declare function createORPCClient<TRouter extends
|
10
|
+
export declare function createORPCClient<TRouter extends AnyRouter | AnyContractRouter, TClientContext = unknown>(link: ClientLink<TClientContext>, options?: createORPCClientOptions): TRouter extends AnyRouter ? RouterClient<TRouter, TClientContext> : TRouter extends AnyContractRouter ? ContractRouterClient<TRouter, TClientContext> : never;
|
11
11
|
//# sourceMappingURL=client.d.ts.map
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import type {
|
1
|
+
import type { ClientOptions } from '@orpc/contract';
|
2
2
|
import type { Promisable } from '@orpc/shared';
|
3
3
|
import type { ClientLink } from './types';
|
4
4
|
/**
|
@@ -8,6 +8,6 @@ import type { ClientLink } from './types';
|
|
8
8
|
export declare class DynamicLink<TClientContext> implements ClientLink<TClientContext> {
|
9
9
|
private readonly linkResolver;
|
10
10
|
constructor(linkResolver: (path: readonly string[], input: unknown, context: TClientContext) => Promisable<ClientLink<TClientContext>>);
|
11
|
-
call(path: readonly string[], input: unknown, options:
|
11
|
+
call(path: readonly string[], input: unknown, options: ClientOptions<TClientContext>): Promise<unknown>;
|
12
12
|
}
|
13
13
|
//# sourceMappingURL=dynamic-link.d.ts.map
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/types.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import type {
|
1
|
+
import type { ClientOptions } from '@orpc/contract';
|
2
2
|
export interface ClientLink<TClientContext> {
|
3
|
-
call
|
3
|
+
call(path: readonly string[], input: unknown, options: ClientOptions<TClientContext>): Promise<unknown>;
|
4
4
|
}
|
5
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.0.0-next.
|
4
|
+
"version": "0.0.0-next.c3068b4",
|
5
5
|
"license": "MIT",
|
6
6
|
"homepage": "https://orpc.unnoq.com",
|
7
7
|
"repository": {
|
@@ -33,16 +33,15 @@
|
|
33
33
|
"!**/*.tsbuildinfo",
|
34
34
|
"dist"
|
35
35
|
],
|
36
|
-
"peerDependencies": {
|
37
|
-
"@orpc/contract": "0.0.0-next.c12be86"
|
38
|
-
},
|
39
36
|
"dependencies": {
|
40
|
-
"
|
41
|
-
"@orpc/
|
37
|
+
"content-disposition": "^0.5.4",
|
38
|
+
"@orpc/contract": "0.0.0-next.c3068b4",
|
39
|
+
"@orpc/shared": "0.0.0-next.c3068b4",
|
40
|
+
"@orpc/server": "0.0.0-next.c3068b4"
|
42
41
|
},
|
43
42
|
"devDependencies": {
|
44
43
|
"zod": "^3.24.1",
|
45
|
-
"@orpc/openapi": "0.0.0-next.
|
44
|
+
"@orpc/openapi": "0.0.0-next.c3068b4"
|
46
45
|
},
|
47
46
|
"scripts": {
|
48
47
|
"build": "tsup --clean --sourcemap --entry.index=src/index.ts --entry.fetch=src/adapters/fetch/index.ts --format=esm --onSuccess='tsc -b --noCheck'",
|