@orpc/client 0.0.0-next.d137cdf → 0.0.0-next.d7b5662
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/fetch.js +46 -0
- package/dist/index.js +28 -72
- package/dist/src/adapters/fetch/index.d.ts +3 -0
- package/dist/src/adapters/fetch/orpc-link.d.ts +19 -0
- package/dist/src/adapters/fetch/types.d.ts +4 -0
- package/dist/src/client.d.ts +11 -0
- package/dist/src/dynamic-link.d.ts +15 -0
- package/dist/src/index.d.ts +3 -4
- package/dist/src/types.d.ts +5 -0
- package/package.json +12 -8
- package/dist/src/procedure.d.ts +0 -27
- package/dist/src/router.d.ts +0 -34
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,83 +1,39 @@
|
|
1
|
-
// src/
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
const deserializer = new ORPCDeserializer();
|
12
|
-
const client = async (input) => {
|
13
|
-
const fetch_ = options.fetch ?? fetch;
|
14
|
-
const url = `${trim(options.baseURL, "/")}/${options.path.map(encodeURIComponent).join("/")}`;
|
15
|
-
let headers = await options.headers?.(input);
|
16
|
-
headers = headers instanceof Headers ? headers : new Headers(headers);
|
17
|
-
const { body, headers: headers_ } = serializer.serialize(input);
|
18
|
-
for (const [key, value] of headers_.entries()) {
|
19
|
-
headers.set(key, value);
|
20
|
-
}
|
21
|
-
headers.set(ORPC_HEADER, ORPC_HEADER_VALUE);
|
22
|
-
const response = await fetch_(url, {
|
23
|
-
method: "POST",
|
24
|
-
headers,
|
25
|
-
body
|
26
|
-
});
|
27
|
-
const json = await (async () => {
|
28
|
-
try {
|
29
|
-
return await deserializer.deserialize(response);
|
30
|
-
} catch (e) {
|
31
|
-
throw new ORPCError({
|
32
|
-
code: "INTERNAL_SERVER_ERROR",
|
33
|
-
message: "Cannot parse response.",
|
34
|
-
cause: e
|
35
|
-
});
|
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);
|
36
11
|
}
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
status: response.status,
|
41
|
-
code: "INTERNAL_SERVER_ERROR",
|
42
|
-
message: "Internal server error"
|
12
|
+
return createORPCClient(link, {
|
13
|
+
...options,
|
14
|
+
path: [...path, key]
|
43
15
|
});
|
44
16
|
}
|
45
|
-
|
46
|
-
|
47
|
-
return client;
|
17
|
+
});
|
18
|
+
return recursive;
|
48
19
|
}
|
49
20
|
|
50
|
-
// src/
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
get(target, key) {
|
62
|
-
if (typeof key !== "string") {
|
63
|
-
return Reflect.get(target, key);
|
64
|
-
}
|
65
|
-
return createRouterClient({
|
66
|
-
...options,
|
67
|
-
path: [...path, key]
|
68
|
-
});
|
69
|
-
}
|
70
|
-
}
|
71
|
-
);
|
72
|
-
return client;
|
73
|
-
}
|
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
|
+
};
|
74
32
|
|
75
33
|
// src/index.ts
|
76
34
|
export * from "@orpc/shared/error";
|
77
|
-
var createORPCClient = createRouterClient;
|
78
35
|
export {
|
79
|
-
|
80
|
-
|
81
|
-
createRouterClient
|
36
|
+
DynamicLink,
|
37
|
+
createORPCClient
|
82
38
|
};
|
83
39
|
//# sourceMappingURL=index.js.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,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
|
package/dist/src/index.d.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
/** unnoq */
|
2
|
-
|
3
|
-
export * from './
|
4
|
-
export * from './
|
2
|
+
export * from './client';
|
3
|
+
export * from './dynamic-link';
|
4
|
+
export * from './types';
|
5
5
|
export * from '@orpc/shared/error';
|
6
|
-
export declare const createORPCClient: typeof createRouterClient;
|
7
6
|
//# sourceMappingURL=index.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.d7b5662",
|
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,19 +34,18 @@
|
|
29
34
|
"dist"
|
30
35
|
],
|
31
36
|
"peerDependencies": {
|
32
|
-
"@orpc/
|
33
|
-
"@orpc/contract": "0.0.0-next.d137cdf"
|
37
|
+
"@orpc/contract": "0.0.0-next.d7b5662"
|
34
38
|
},
|
35
39
|
"dependencies": {
|
36
|
-
"@orpc/
|
37
|
-
"@orpc/
|
40
|
+
"@orpc/server": "0.0.0-next.d7b5662",
|
41
|
+
"@orpc/shared": "0.0.0-next.d7b5662"
|
38
42
|
},
|
39
43
|
"devDependencies": {
|
40
|
-
"zod": "^3.
|
41
|
-
"@orpc/openapi": "0.0.0-next.
|
44
|
+
"zod": "^3.24.1",
|
45
|
+
"@orpc/openapi": "0.0.0-next.d7b5662"
|
42
46
|
},
|
43
47
|
"scripts": {
|
44
|
-
"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'",
|
45
49
|
"build:watch": "pnpm run build --watch",
|
46
50
|
"type:check": "tsc -b"
|
47
51
|
}
|
package/dist/src/procedure.d.ts
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
import type { Promisable } from '@orpc/shared';
|
2
|
-
import { type Schema, type SchemaInput, type SchemaOutput } from '@orpc/contract';
|
3
|
-
export interface ProcedureClient<TInputSchema extends Schema, TOutputSchema extends Schema, TFuncOutput extends SchemaOutput<TOutputSchema>> {
|
4
|
-
(input: SchemaInput<TInputSchema>): Promise<SchemaOutput<TOutputSchema, TFuncOutput>>;
|
5
|
-
}
|
6
|
-
export interface CreateProcedureClientOptions {
|
7
|
-
/**
|
8
|
-
* The base url of the server.
|
9
|
-
*/
|
10
|
-
baseURL: string;
|
11
|
-
/**
|
12
|
-
* The fetch function used to make the request.
|
13
|
-
* @default global fetch
|
14
|
-
*/
|
15
|
-
fetch?: typeof fetch;
|
16
|
-
/**
|
17
|
-
* The headers used to make the request.
|
18
|
-
* Invoked before the request is made.
|
19
|
-
*/
|
20
|
-
headers?: (input: unknown) => Promisable<Headers | Record<string, string>>;
|
21
|
-
/**
|
22
|
-
* The path of the procedure on server.
|
23
|
-
*/
|
24
|
-
path: string[];
|
25
|
-
}
|
26
|
-
export declare function createProcedureClient<TInputSchema extends Schema, TOutputSchema extends Schema, TFuncOutput extends SchemaOutput<TOutputSchema>>(options: CreateProcedureClientOptions): ProcedureClient<TInputSchema, TOutputSchema, TFuncOutput>;
|
27
|
-
//# sourceMappingURL=procedure.d.ts.map
|
package/dist/src/router.d.ts
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
import type { ContractProcedure, ContractRouter, SchemaOutput } from '@orpc/contract';
|
2
|
-
import type { Lazy, Procedure, Router } from '@orpc/server';
|
3
|
-
import type { Promisable } from '@orpc/shared';
|
4
|
-
import { type ProcedureClient } from './procedure';
|
5
|
-
export type RouterClientWithContractRouter<TRouter extends ContractRouter> = {
|
6
|
-
[K in keyof TRouter]: TRouter[K] extends ContractProcedure<infer UInputSchema, infer UOutputSchema> ? ProcedureClient<UInputSchema, UOutputSchema, SchemaOutput<UOutputSchema>> : TRouter[K] extends ContractRouter ? RouterClientWithContractRouter<TRouter[K]> : never;
|
7
|
-
};
|
8
|
-
export type RouterClientWithRouter<TRouter extends Router<any>> = {
|
9
|
-
[K in keyof TRouter]: TRouter[K] extends Procedure<any, any, infer UInputSchema, infer UOutputSchema, infer UFuncOutput> | Lazy<Procedure<any, any, infer UInputSchema, infer UOutputSchema, infer UFuncOutput>> ? ProcedureClient<UInputSchema, UOutputSchema, UFuncOutput> : TRouter[K] extends Router<any> ? RouterClientWithRouter<TRouter[K]> : never;
|
10
|
-
};
|
11
|
-
export interface CreateRouterClientOptions {
|
12
|
-
/**
|
13
|
-
* The base url of the server.
|
14
|
-
*/
|
15
|
-
baseURL: string;
|
16
|
-
/**
|
17
|
-
* The fetch function used to make the request.
|
18
|
-
* @default global fetch
|
19
|
-
*/
|
20
|
-
fetch?: typeof fetch;
|
21
|
-
/**
|
22
|
-
* The headers used to make the request.
|
23
|
-
* Invoked before the request is made.
|
24
|
-
*/
|
25
|
-
headers?: (input: unknown) => Promisable<Headers | Record<string, string>>;
|
26
|
-
/**
|
27
|
-
* This used for internal purpose only.
|
28
|
-
*
|
29
|
-
* @internal
|
30
|
-
*/
|
31
|
-
path?: string[];
|
32
|
-
}
|
33
|
-
export declare function createRouterClient<TRouter extends Router<any> | ContractRouter>(options: CreateRouterClientOptions): TRouter extends Router<any> ? RouterClientWithRouter<TRouter> : TRouter extends ContractRouter ? RouterClientWithContractRouter<TRouter> : never;
|
34
|
-
//# sourceMappingURL=router.d.ts.map
|