@orpc/client 0.20.0 → 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/fetch.js +56 -15
- package/dist/index.js +1 -1
- package/dist/src/adapters/fetch/orpc-link.d.ts +30 -2
- package/dist/src/dynamic-link.d.ts +1 -3
- package/package.json +5 -5
package/dist/fetch.js
CHANGED
@@ -3,27 +3,32 @@ import { ORPCPayloadCodec } from "@orpc/server/fetch";
|
|
3
3
|
import { ORPC_HANDLER_HEADER, ORPC_HANDLER_VALUE, trim } from "@orpc/shared";
|
4
4
|
import { ORPCError } from "@orpc/shared/error";
|
5
5
|
var ORPCLink = class {
|
6
|
+
fetch;
|
7
|
+
payloadCodec;
|
8
|
+
maxURLLength;
|
9
|
+
fallbackMethod;
|
10
|
+
getMethod;
|
11
|
+
getHeaders;
|
12
|
+
url;
|
6
13
|
constructor(options) {
|
7
|
-
this.options = options;
|
8
14
|
this.fetch = options.fetch ?? globalThis.fetch.bind(globalThis);
|
9
15
|
this.payloadCodec = options.payloadCodec ?? new ORPCPayloadCodec();
|
16
|
+
this.maxURLLength = options.maxURLLength ?? 2083;
|
17
|
+
this.fallbackMethod = options.fallbackMethod ?? "POST";
|
18
|
+
this.url = options.url;
|
19
|
+
this.getMethod = async (path, input, context) => {
|
20
|
+
return await options.method?.(path, input, context) ?? this.fallbackMethod;
|
21
|
+
};
|
22
|
+
this.getHeaders = async (path, input, context) => {
|
23
|
+
return new Headers(await options.headers?.(path, input, context));
|
24
|
+
};
|
10
25
|
}
|
11
|
-
fetch;
|
12
|
-
payloadCodec;
|
13
26
|
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
27
|
const clientContext = options.context;
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
headers.
|
23
|
-
}
|
24
|
-
const response = await this.fetch(url, {
|
25
|
-
method: "POST",
|
26
|
-
headers,
|
28
|
+
const encoded = await this.encode(path, input, options);
|
29
|
+
const response = await this.fetch(encoded.url, {
|
30
|
+
method: encoded.method,
|
31
|
+
headers: encoded.headers,
|
27
32
|
body: encoded.body,
|
28
33
|
signal: options.signal
|
29
34
|
}, clientContext);
|
@@ -39,6 +44,42 @@ var ORPCLink = class {
|
|
39
44
|
}
|
40
45
|
return decoded;
|
41
46
|
}
|
47
|
+
async encode(path, input, options) {
|
48
|
+
const clientContext = options.context;
|
49
|
+
const expectMethod = await this.getMethod(path, input, clientContext);
|
50
|
+
const methods = /* @__PURE__ */ new Set([expectMethod, this.fallbackMethod]);
|
51
|
+
const baseHeaders = await this.getHeaders(path, input, clientContext);
|
52
|
+
const baseUrl = new URL(`${trim(this.url, "/")}/${path.map(encodeURIComponent).join("/")}`);
|
53
|
+
baseHeaders.append(ORPC_HANDLER_HEADER, ORPC_HANDLER_VALUE);
|
54
|
+
for (const method of methods) {
|
55
|
+
const url = new URL(baseUrl);
|
56
|
+
const headers = new Headers(baseHeaders);
|
57
|
+
const encoded = this.payloadCodec.encode(input, method, this.fallbackMethod);
|
58
|
+
if (encoded.query) {
|
59
|
+
for (const [key, value] of encoded.query.entries()) {
|
60
|
+
url.searchParams.append(key, value);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
if (url.toString().length > this.maxURLLength) {
|
64
|
+
continue;
|
65
|
+
}
|
66
|
+
if (encoded.headers) {
|
67
|
+
for (const [key, value] of encoded.headers.entries()) {
|
68
|
+
headers.append(key, value);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
return {
|
72
|
+
url,
|
73
|
+
headers,
|
74
|
+
method: encoded.method,
|
75
|
+
body: encoded.body
|
76
|
+
};
|
77
|
+
}
|
78
|
+
throw new ORPCError({
|
79
|
+
code: "BAD_REQUEST",
|
80
|
+
message: "Cannot encode the request, please check the url length or payload."
|
81
|
+
});
|
82
|
+
}
|
42
83
|
};
|
43
84
|
export {
|
44
85
|
ORPCLink
|
package/dist/index.js
CHANGED
@@ -24,7 +24,7 @@ var DynamicLink = class {
|
|
24
24
|
this.linkResolver = linkResolver;
|
25
25
|
}
|
26
26
|
async call(path, input, options) {
|
27
|
-
const resolvedLink = await this.linkResolver(path, input, options);
|
27
|
+
const resolvedLink = await this.linkResolver(path, input, options.context);
|
28
28
|
const output = await resolvedLink.call(path, input, options);
|
29
29
|
return output;
|
30
30
|
}
|
@@ -1,19 +1,47 @@
|
|
1
|
+
import type { HTTPMethod } from '@orpc/contract';
|
1
2
|
import type { ProcedureClientOptions } from '@orpc/server';
|
2
3
|
import type { Promisable } from '@orpc/shared';
|
3
4
|
import type { ClientLink } from '../../types';
|
4
5
|
import type { FetchWithContext } from './types';
|
5
6
|
import { type PublicORPCPayloadCodec } from '@orpc/server/fetch';
|
6
7
|
export interface ORPCLinkOptions<TClientContext> {
|
8
|
+
/**
|
9
|
+
* Base url for all requests.
|
10
|
+
*/
|
7
11
|
url: string;
|
8
|
-
|
12
|
+
/**
|
13
|
+
* The maximum length of the URL.
|
14
|
+
*
|
15
|
+
* @default 2083
|
16
|
+
*/
|
17
|
+
maxURLLength?: number;
|
18
|
+
/**
|
19
|
+
* The method used to make the request.
|
20
|
+
*
|
21
|
+
* @default 'POST'
|
22
|
+
*/
|
23
|
+
method?: (path: readonly string[], input: unknown, context: TClientContext) => Promisable<HTTPMethod | undefined>;
|
24
|
+
/**
|
25
|
+
* The method to use when the payload cannot safely pass to the server with method return from method function.
|
26
|
+
* Do not use GET as fallback method, it's very dangerous.
|
27
|
+
*
|
28
|
+
* @default 'POST'
|
29
|
+
*/
|
30
|
+
fallbackMethod?: HTTPMethod;
|
31
|
+
headers?: (path: readonly string[], input: unknown, context: TClientContext) => Promisable<Headers | Record<string, string>>;
|
9
32
|
fetch?: FetchWithContext<TClientContext>;
|
10
33
|
payloadCodec?: PublicORPCPayloadCodec;
|
11
34
|
}
|
12
35
|
export declare class ORPCLink<TClientContext> implements ClientLink<TClientContext> {
|
13
|
-
private readonly options;
|
14
36
|
private readonly fetch;
|
15
37
|
private readonly payloadCodec;
|
38
|
+
private readonly maxURLLength;
|
39
|
+
private readonly fallbackMethod;
|
40
|
+
private readonly getMethod;
|
41
|
+
private readonly getHeaders;
|
42
|
+
private readonly url;
|
16
43
|
constructor(options: ORPCLinkOptions<TClientContext>);
|
17
44
|
call(path: readonly string[], input: unknown, options: ProcedureClientOptions<TClientContext>): Promise<unknown>;
|
45
|
+
private encode;
|
18
46
|
}
|
19
47
|
//# sourceMappingURL=orpc-link.d.ts.map
|
@@ -7,9 +7,7 @@ import type { ClientLink } from './types';
|
|
7
7
|
*/
|
8
8
|
export declare class DynamicLink<TClientContext> implements ClientLink<TClientContext> {
|
9
9
|
private readonly linkResolver;
|
10
|
-
constructor(linkResolver: (path: readonly string[], input: unknown,
|
11
|
-
context: TClientContext;
|
12
|
-
}) => Promisable<ClientLink<TClientContext>>);
|
10
|
+
constructor(linkResolver: (path: readonly string[], input: unknown, context: TClientContext) => Promisable<ClientLink<TClientContext>>);
|
13
11
|
call(path: readonly string[], input: unknown, options: ProcedureClientOptions<TClientContext>): Promise<unknown>;
|
14
12
|
}
|
15
13
|
//# sourceMappingURL=dynamic-link.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.
|
4
|
+
"version": "0.22.0",
|
5
5
|
"license": "MIT",
|
6
6
|
"homepage": "https://orpc.unnoq.com",
|
7
7
|
"repository": {
|
@@ -34,15 +34,15 @@
|
|
34
34
|
"dist"
|
35
35
|
],
|
36
36
|
"peerDependencies": {
|
37
|
-
"@orpc/contract": "0.
|
37
|
+
"@orpc/contract": "0.22.0"
|
38
38
|
},
|
39
39
|
"dependencies": {
|
40
|
-
"@orpc/
|
41
|
-
"@orpc/
|
40
|
+
"@orpc/shared": "0.22.0",
|
41
|
+
"@orpc/server": "0.22.0"
|
42
42
|
},
|
43
43
|
"devDependencies": {
|
44
44
|
"zod": "^3.24.1",
|
45
|
-
"@orpc/openapi": "0.
|
45
|
+
"@orpc/openapi": "0.22.0"
|
46
46
|
},
|
47
47
|
"scripts": {
|
48
48
|
"build": "tsup --clean --sourcemap --entry.index=src/index.ts --entry.fetch=src/adapters/fetch/index.ts --format=esm --onSuccess='tsc -b --noCheck'",
|