@seam-rpc/client 4.3.21 → 5.0.0
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.
- package/dist/index.d.ts +10 -9
- package/dist/index.js +25 -21
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { RpcError };
|
|
1
|
+
import { ApiError, type Result } from "@seam-rpc/core";
|
|
2
|
+
export { ApiError as RpcError };
|
|
3
3
|
export type { Result };
|
|
4
4
|
export type SeamRequestMiddleware = (context: SeamRequestMiddlewareContext) => void | Promise<void>;
|
|
5
5
|
export type SeamResponseMiddleware = (context: SeamResponseMiddlewareContext) => void | Promise<void>;
|
|
@@ -19,23 +19,24 @@ export interface SeamClientOptions {
|
|
|
19
19
|
response?: SeamResponseMiddleware[];
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
-
export declare class SeamClient {
|
|
22
|
+
export declare class SeamClient<ApiType> {
|
|
23
23
|
readonly baseUrl: string;
|
|
24
|
-
static _instance: SeamClient;
|
|
25
24
|
options: SeamClientOptions;
|
|
25
|
+
readonly api: ApiType;
|
|
26
26
|
constructor(baseUrl: string, options?: SeamClientOptions);
|
|
27
27
|
preRequest(middleware: SeamRequestMiddleware): void;
|
|
28
28
|
postRequest(middleware: SeamResponseMiddleware): void;
|
|
29
29
|
}
|
|
30
|
-
export declare class SeamError extends
|
|
30
|
+
export declare class SeamError extends ApiError {
|
|
31
31
|
constructor(code: string);
|
|
32
32
|
}
|
|
33
|
-
type SeamClientErrorType = "REQUEST_FAILED" | "
|
|
33
|
+
type SeamClientErrorType = "REQUEST_FAILED" | "INVALID_CONTENT_TYPE";
|
|
34
34
|
export declare class SeamClientError extends Error {
|
|
35
35
|
readonly type: SeamClientErrorType;
|
|
36
|
+
readonly url: string;
|
|
36
37
|
readonly request: RequestInit;
|
|
37
38
|
readonly cause: unknown;
|
|
38
|
-
constructor(type: SeamClientErrorType, message: string, request: RequestInit, cause: unknown);
|
|
39
|
+
constructor(type: SeamClientErrorType, message: string, url: string, request: RequestInit, cause: unknown);
|
|
39
40
|
}
|
|
40
|
-
export declare function createSeamClient(baseUrl: string, options?: SeamClientOptions): SeamClient
|
|
41
|
-
export declare function callApi(routerName: string, funcName: string, input?: Record<string, any>): Promise<any>;
|
|
41
|
+
export declare function createSeamClient<ApiType>(baseUrl: string, options?: SeamClientOptions): SeamClient<ApiType>;
|
|
42
|
+
export declare function callApi(seamClient: SeamClient<any>, routerName: string, funcName: string, input?: Record<string, any>): Promise<any>;
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
import { extractFiles, injectFiles,
|
|
2
|
-
export { RpcError };
|
|
1
|
+
import { extractFiles, injectFiles, ApiError } from "@seam-rpc/core";
|
|
2
|
+
export { ApiError as RpcError };
|
|
3
3
|
export class SeamClient {
|
|
4
4
|
constructor(baseUrl, options) {
|
|
5
5
|
this.baseUrl = baseUrl;
|
|
6
|
-
SeamClient._instance = this;
|
|
7
6
|
this.options = {
|
|
8
7
|
middleware: {
|
|
9
8
|
request: options?.middleware?.request || [],
|
|
10
9
|
response: options?.middleware?.response || [],
|
|
11
10
|
}
|
|
12
11
|
};
|
|
12
|
+
const client = this;
|
|
13
|
+
this.api = new Proxy({}, {
|
|
14
|
+
get(_target, routerName) {
|
|
15
|
+
return new Proxy({}, {
|
|
16
|
+
get(_subTarget, procName) {
|
|
17
|
+
return async (input) => {
|
|
18
|
+
return callApi(client, String(routerName), String(procName), input);
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
});
|
|
13
24
|
}
|
|
14
25
|
preRequest(middleware) {
|
|
15
26
|
this.options?.middleware?.request?.push(middleware);
|
|
@@ -18,15 +29,16 @@ export class SeamClient {
|
|
|
18
29
|
this.options?.middleware?.response?.push(middleware);
|
|
19
30
|
}
|
|
20
31
|
}
|
|
21
|
-
export class SeamError extends
|
|
32
|
+
export class SeamError extends ApiError {
|
|
22
33
|
constructor(code) {
|
|
23
34
|
super(code, undefined);
|
|
24
35
|
}
|
|
25
36
|
}
|
|
26
37
|
export class SeamClientError extends Error {
|
|
27
|
-
constructor(type, message, request, cause) {
|
|
38
|
+
constructor(type, message, url, request, cause) {
|
|
28
39
|
super(message);
|
|
29
40
|
this.type = type;
|
|
41
|
+
this.url = url;
|
|
30
42
|
this.request = request;
|
|
31
43
|
this.cause = cause;
|
|
32
44
|
this.name = "SeamClientError";
|
|
@@ -35,10 +47,7 @@ export class SeamClientError extends Error {
|
|
|
35
47
|
export function createSeamClient(baseUrl, options) {
|
|
36
48
|
return new SeamClient(baseUrl, options);
|
|
37
49
|
}
|
|
38
|
-
export async function callApi(routerName, funcName, input) {
|
|
39
|
-
if (!SeamClient._instance)
|
|
40
|
-
throw new Error("Seam Client not instantiated.");
|
|
41
|
-
const seamClient = SeamClient._instance;
|
|
50
|
+
export async function callApi(seamClient, routerName, funcName, input) {
|
|
42
51
|
const req = buildRequest(input);
|
|
43
52
|
const url = `${seamClient.baseUrl}/${routerName}/${funcName}`;
|
|
44
53
|
if (seamClient.options?.middleware?.request) {
|
|
@@ -56,30 +65,27 @@ export async function callApi(routerName, funcName, input) {
|
|
|
56
65
|
res = await fetch(url, req);
|
|
57
66
|
}
|
|
58
67
|
catch (err) {
|
|
59
|
-
throw new SeamClientError("REQUEST_FAILED", "Failed to send request.", req, err);
|
|
68
|
+
throw new SeamClientError("REQUEST_FAILED", "Failed to send request.", url, req, err);
|
|
60
69
|
}
|
|
61
70
|
if (!res.ok) {
|
|
62
71
|
if (res.status == 400) {
|
|
63
72
|
const resError = await res.json();
|
|
64
|
-
if (resError.
|
|
73
|
+
if (resError.isApiError) {
|
|
65
74
|
return {
|
|
66
75
|
ok: false,
|
|
67
|
-
error:
|
|
76
|
+
error: ApiError.fromJSON(resError.error),
|
|
68
77
|
};
|
|
69
78
|
}
|
|
70
|
-
|
|
71
|
-
return { ok: false, error: null };
|
|
72
|
-
}
|
|
79
|
+
throw new SeamClientError("REQUEST_FAILED", `Request failed with status ${res.status} ${res.statusText} and non-api error.`, url, req, null);
|
|
73
80
|
}
|
|
74
|
-
|
|
75
|
-
return { ok: false, error: null };
|
|
81
|
+
throw new SeamClientError("REQUEST_FAILED", `Request failed with status ${res.status} ${res.statusText}.`, url, req, null);
|
|
76
82
|
}
|
|
77
83
|
const contentType = res.headers.get("content-type") || "";
|
|
78
84
|
if (contentType.startsWith("application/json")) {
|
|
79
85
|
const data = await res.json();
|
|
80
86
|
return data.result;
|
|
81
87
|
}
|
|
82
|
-
|
|
88
|
+
if (contentType.startsWith("multipart/form-data")) {
|
|
83
89
|
const formData = await res.formData();
|
|
84
90
|
const jsonPart = JSON.parse(formData.get("json")?.toString() || "[]");
|
|
85
91
|
const pathsPart = JSON.parse(formData.get("paths")?.toString() || "[]");
|
|
@@ -109,9 +115,7 @@ export async function callApi(routerName, funcName, input) {
|
|
|
109
115
|
}
|
|
110
116
|
return jsonPart.result;
|
|
111
117
|
}
|
|
112
|
-
|
|
113
|
-
return { ok: false, error: null };
|
|
114
|
-
}
|
|
118
|
+
throw new SeamClientError("INVALID_CONTENT_TYPE", `Response has invalid content type ${contentType}.`, url, req, null);
|
|
115
119
|
}
|
|
116
120
|
function buildRequest(input = {}) {
|
|
117
121
|
let req;
|