@richie-rpc/client 1.2.1 → 1.2.2
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/README.md +73 -1
- package/dist/cjs/index.cjs +4 -1
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/index.mjs +4 -1
- package/dist/mjs/index.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -88,6 +88,76 @@ const data = await client.getData({
|
|
|
88
88
|
});
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
+
### Canceling Requests
|
|
92
|
+
|
|
93
|
+
You can cancel in-flight requests using `AbortController`:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
const controller = new AbortController();
|
|
97
|
+
|
|
98
|
+
// Pass the abort signal to the request
|
|
99
|
+
const promise = client.getUser({
|
|
100
|
+
params: { id: '123' },
|
|
101
|
+
abortSignal: controller.signal,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Cancel the request
|
|
105
|
+
controller.abort();
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
await promise;
|
|
109
|
+
} catch (error) {
|
|
110
|
+
if (error.name === 'AbortError') {
|
|
111
|
+
console.log('Request was cancelled');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**React Example:**
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
const controller = new AbortController();
|
|
121
|
+
|
|
122
|
+
client.getConversation({
|
|
123
|
+
params: { projectId, sessionId },
|
|
124
|
+
abortSignal: controller.signal,
|
|
125
|
+
}).then((response) => {
|
|
126
|
+
if (response.status === 200) {
|
|
127
|
+
setData(response.data);
|
|
128
|
+
}
|
|
129
|
+
}).catch((error) => {
|
|
130
|
+
if (error.name !== 'AbortError') {
|
|
131
|
+
console.error('Request failed:', error);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Cleanup: abort request if component unmounts
|
|
136
|
+
return () => controller.abort();
|
|
137
|
+
}, [projectId, sessionId]);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Timeout Example:**
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
const controller = new AbortController();
|
|
144
|
+
|
|
145
|
+
// Abort after 5 seconds
|
|
146
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
const response = await client.getData({
|
|
150
|
+
abortSignal: controller.signal,
|
|
151
|
+
});
|
|
152
|
+
clearTimeout(timeoutId);
|
|
153
|
+
console.log(response.data);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
if (error.name === 'AbortError') {
|
|
156
|
+
console.log('Request timed out');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
91
161
|
## Features
|
|
92
162
|
|
|
93
163
|
- ✅ Full type safety based on contract
|
|
@@ -99,6 +169,7 @@ const data = await client.getData({
|
|
|
99
169
|
- ✅ Detailed error information
|
|
100
170
|
- ✅ Support for all HTTP methods
|
|
101
171
|
- ✅ Custom headers per request
|
|
172
|
+
- ✅ Request cancellation with AbortController
|
|
102
173
|
|
|
103
174
|
## Configuration
|
|
104
175
|
|
|
@@ -192,8 +263,9 @@ Each client method accepts an options object with the following fields (based on
|
|
|
192
263
|
- `query`: Query parameters (if endpoint has query schema)
|
|
193
264
|
- `headers`: Custom headers (if endpoint has headers schema)
|
|
194
265
|
- `body`: Request body (if endpoint has body schema)
|
|
266
|
+
- `abortSignal`: AbortSignal for request cancellation (optional, always available)
|
|
195
267
|
|
|
196
|
-
Only the fields defined in the contract are available and typed.
|
|
268
|
+
Only the fields defined in the contract are available and typed (except `abortSignal`, which is always available).
|
|
197
269
|
|
|
198
270
|
## Validation
|
|
199
271
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -115,6 +115,9 @@ async function makeRequest(config, endpoint, options) {
|
|
|
115
115
|
method: endpoint.method,
|
|
116
116
|
headers
|
|
117
117
|
};
|
|
118
|
+
if (options.abortSignal) {
|
|
119
|
+
init.signal = options.abortSignal;
|
|
120
|
+
}
|
|
118
121
|
if (options.body !== undefined) {
|
|
119
122
|
headers.set("content-type", "application/json");
|
|
120
123
|
init.body = JSON.stringify(options.body);
|
|
@@ -184,4 +187,4 @@ function createTypedClient(_config) {
|
|
|
184
187
|
}
|
|
185
188
|
})
|
|
186
189
|
|
|
187
|
-
//# debugId=
|
|
190
|
+
//# debugId=D503DD5C58FB58D864756E2164756E21
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type {\n Contract,\n EndpointDefinition,\n ExtractBody,\n ExtractHeaders,\n ExtractParams,\n ExtractQuery,\n} from '@richie-rpc/core';\nimport { buildUrl, interpolatePath } from '@richie-rpc/core';\nimport type { z } from 'zod';\n\n// Client configuration\nexport interface ClientConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n validateRequest?: boolean;\n validateResponse?: boolean;\n}\n\n// Request options for an endpoint\nexport type EndpointRequestOptions<T extends EndpointDefinition> = {\n params?: ExtractParams<T> extends never ? never : ExtractParams<T>;\n query?: ExtractQuery<T> extends never ? never : ExtractQuery<T>;\n headers?: ExtractHeaders<T> extends never ? never : ExtractHeaders<T>;\n body?: ExtractBody<T> extends never ? never : ExtractBody<T>;\n};\n\n// Response type for an endpoint (union of all possible responses)\nexport type EndpointResponse<T extends EndpointDefinition> = {\n [Status in keyof T['responses']]: {\n status: Status;\n data: T['responses'][Status] extends z.ZodTypeAny ? z.infer<T['responses'][Status]> : never;\n };\n}[keyof T['responses']];\n\n// Client method type for an endpoint\nexport type ClientMethod<T extends EndpointDefinition> = (\n options: EndpointRequestOptions<T>,\n) => Promise<EndpointResponse<T>>;\n\n// Client type for a contract\nexport type Client<T extends Contract> = {\n [K in keyof T]: ClientMethod<T[K]>;\n};\n\n// Validation error\nexport class ClientValidationError extends Error {\n constructor(\n public field: string,\n public issues: z.ZodIssue[],\n ) {\n super(`Validation failed for ${field}`);\n this.name = 'ClientValidationError';\n }\n}\n\n// HTTP error\nexport class HTTPError extends Error {\n constructor(\n public status: number,\n public statusText: string,\n public body: unknown,\n ) {\n super(`HTTP Error ${status}: ${statusText}`);\n this.name = 'HTTPError';\n }\n}\n\n/**\n * Validate request data before sending\n */\nfunction validateRequest<T extends EndpointDefinition>(\n endpoint: T,\n options: EndpointRequestOptions<T>,\n): void {\n // Validate params\n if (endpoint.params && options.params) {\n const result = endpoint.params.safeParse(options.params);\n if (!result.success) {\n throw new ClientValidationError('params', result.error.issues);\n }\n }\n\n // Validate query\n if (endpoint.query && options.query) {\n const result = endpoint.query.safeParse(options.query);\n if (!result.success) {\n throw new ClientValidationError('query', result.error.issues);\n }\n }\n\n // Validate headers\n if (endpoint.headers && options.headers) {\n const result = endpoint.headers.safeParse(options.headers);\n if (!result.success) {\n throw new ClientValidationError('headers', result.error.issues);\n }\n }\n\n // Validate body\n if (endpoint.body && options.body) {\n const result = endpoint.body.safeParse(options.body);\n if (!result.success) {\n throw new ClientValidationError('body', result.error.issues);\n }\n }\n}\n\n/**\n * Validate response data after receiving\n */\nfunction validateResponse<T extends EndpointDefinition>(\n endpoint: T,\n status: number,\n data: unknown,\n): void {\n const responseSchema = endpoint.responses[status];\n if (responseSchema) {\n const result = responseSchema.safeParse(data);\n if (!result.success) {\n throw new ClientValidationError(`response[${status}]`, result.error.issues);\n }\n }\n}\n\n/**\n * Make a request to an endpoint\n */\nasync function makeRequest<T extends EndpointDefinition>(\n config: ClientConfig,\n endpoint: T,\n options: EndpointRequestOptions<T>,\n): Promise<EndpointResponse<T>> {\n // Validate request if enabled\n if (config.validateRequest !== false) {\n validateRequest(endpoint, options);\n }\n\n // Build URL\n let path = endpoint.path;\n if (options.params) {\n path = interpolatePath(path, options.params as Record<string, string | number>);\n }\n\n const url = buildUrl(\n config.baseUrl,\n path,\n options.query as Record<string, string | number | boolean | string[]> | undefined,\n );\n\n // Build headers\n const headers = new Headers(config.headers);\n if (options.headers) {\n for (const [key, value] of Object.entries(options.headers)) {\n headers.set(key, String(value));\n }\n }\n\n // Build request init\n const init: RequestInit = {\n method: endpoint.method,\n headers,\n };\n\n // Add body if present\n if (options.body !== undefined) {\n headers.set('content-type', 'application/json');\n init.body = JSON.stringify(options.body);\n }\n\n // Make request\n const response = await fetch(url, init);\n\n // Parse response\n let data: unknown;\n\n // Handle 204 No Content\n if (response.status === 204) {\n data = {};\n } else {\n const contentType = response.headers.get('content-type') || '';\n\n if (contentType.includes('application/json')) {\n data = await response.json();\n } else if (contentType.includes('text/')) {\n data = await response.text();\n } else {\n // Check if there's any content\n const text = await response.text();\n if (text) {\n data = text;\n } else {\n data = {};\n }\n }\n }\n\n // Check for HTTP errors\n if (!response.ok && !(response.status in endpoint.responses)) {\n throw new HTTPError(response.status, response.statusText, data);\n }\n\n // Validate response if enabled\n if (config.validateResponse !== false) {\n validateResponse(endpoint, response.status, data);\n }\n\n return {\n status: response.status,\n data,\n } as EndpointResponse<T>;\n}\n\n/**\n * Resolve relative baseUrl to absolute URL in browser contexts\n */\nfunction resolveBaseUrl(baseUrl: string): string {\n // If baseUrl is already absolute, return as-is\n if (baseUrl.startsWith('http://') || baseUrl.startsWith('https://')) {\n return baseUrl;\n }\n\n // If baseUrl is relative (starts with /), resolve it using window.location in browser\n if (baseUrl.startsWith('/')) {\n const g = globalThis as unknown as { location?: { origin?: string } };\n const origin = g?.location?.origin || 'http://localhost';\n return origin + baseUrl;\n }\n\n // Otherwise, assume it's a full URL\n return baseUrl;\n}\n\n/**\n * Create a typesafe client for a contract\n */\nexport function createClient<T extends Contract>(contract: T, config: ClientConfig): Client<T> {\n // Resolve relative baseUrl to absolute URL\n const resolvedConfig = {\n ...config,\n baseUrl: resolveBaseUrl(config.baseUrl),\n };\n\n const client: Record<string, unknown> = {};\n\n for (const [name, endpoint] of Object.entries(contract)) {\n client[name] = (options: EndpointRequestOptions<EndpointDefinition> = {}) => {\n return makeRequest(resolvedConfig, endpoint, options);\n };\n }\n\n return client as Client<T>;\n}\n\n/**\n * Create a client without providing the contract at runtime\n * Useful when you only need types and want a lighter bundle\n */\nexport function createTypedClient<T extends Contract>(_config: ClientConfig): Client<T> {\n return new Proxy({} as Client<T>, {\n get(_target, _prop: string) {\n return async (_options: EndpointRequestOptions<EndpointDefinition> = {}) => {\n // Without the contract, we can't validate or infer the endpoint\n // This is just a basic fetch wrapper with typing\n throw new Error(\n 'createTypedClient requires contract at runtime for validation. Use createClient instead.',\n );\n };\n },\n });\n}\n"
|
|
5
|
+
"import type {\n Contract,\n EndpointDefinition,\n ExtractBody,\n ExtractHeaders,\n ExtractParams,\n ExtractQuery,\n} from '@richie-rpc/core';\nimport { buildUrl, interpolatePath } from '@richie-rpc/core';\nimport type { z } from 'zod';\n\n// Client configuration\nexport interface ClientConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n validateRequest?: boolean;\n validateResponse?: boolean;\n}\n\n// Request options for an endpoint\nexport type EndpointRequestOptions<T extends EndpointDefinition> = {\n params?: ExtractParams<T> extends never ? never : ExtractParams<T>;\n query?: ExtractQuery<T> extends never ? never : ExtractQuery<T>;\n headers?: ExtractHeaders<T> extends never ? never : ExtractHeaders<T>;\n body?: ExtractBody<T> extends never ? never : ExtractBody<T>;\n abortSignal?: AbortSignal;\n};\n\n// Response type for an endpoint (union of all possible responses)\nexport type EndpointResponse<T extends EndpointDefinition> = {\n [Status in keyof T['responses']]: {\n status: Status;\n data: T['responses'][Status] extends z.ZodTypeAny ? z.infer<T['responses'][Status]> : never;\n };\n}[keyof T['responses']];\n\n// Client method type for an endpoint\nexport type ClientMethod<T extends EndpointDefinition> = (\n options: EndpointRequestOptions<T>,\n) => Promise<EndpointResponse<T>>;\n\n// Client type for a contract\nexport type Client<T extends Contract> = {\n [K in keyof T]: ClientMethod<T[K]>;\n};\n\n// Validation error\nexport class ClientValidationError extends Error {\n constructor(\n public field: string,\n public issues: z.ZodIssue[],\n ) {\n super(`Validation failed for ${field}`);\n this.name = 'ClientValidationError';\n }\n}\n\n// HTTP error\nexport class HTTPError extends Error {\n constructor(\n public status: number,\n public statusText: string,\n public body: unknown,\n ) {\n super(`HTTP Error ${status}: ${statusText}`);\n this.name = 'HTTPError';\n }\n}\n\n/**\n * Validate request data before sending\n */\nfunction validateRequest<T extends EndpointDefinition>(\n endpoint: T,\n options: EndpointRequestOptions<T>,\n): void {\n // Validate params\n if (endpoint.params && options.params) {\n const result = endpoint.params.safeParse(options.params);\n if (!result.success) {\n throw new ClientValidationError('params', result.error.issues);\n }\n }\n\n // Validate query\n if (endpoint.query && options.query) {\n const result = endpoint.query.safeParse(options.query);\n if (!result.success) {\n throw new ClientValidationError('query', result.error.issues);\n }\n }\n\n // Validate headers\n if (endpoint.headers && options.headers) {\n const result = endpoint.headers.safeParse(options.headers);\n if (!result.success) {\n throw new ClientValidationError('headers', result.error.issues);\n }\n }\n\n // Validate body\n if (endpoint.body && options.body) {\n const result = endpoint.body.safeParse(options.body);\n if (!result.success) {\n throw new ClientValidationError('body', result.error.issues);\n }\n }\n}\n\n/**\n * Validate response data after receiving\n */\nfunction validateResponse<T extends EndpointDefinition>(\n endpoint: T,\n status: number,\n data: unknown,\n): void {\n const responseSchema = endpoint.responses[status];\n if (responseSchema) {\n const result = responseSchema.safeParse(data);\n if (!result.success) {\n throw new ClientValidationError(`response[${status}]`, result.error.issues);\n }\n }\n}\n\n/**\n * Make a request to an endpoint\n */\nasync function makeRequest<T extends EndpointDefinition>(\n config: ClientConfig,\n endpoint: T,\n options: EndpointRequestOptions<T>,\n): Promise<EndpointResponse<T>> {\n // Validate request if enabled\n if (config.validateRequest !== false) {\n validateRequest(endpoint, options);\n }\n\n // Build URL\n let path = endpoint.path;\n if (options.params) {\n path = interpolatePath(path, options.params as Record<string, string | number>);\n }\n\n const url = buildUrl(\n config.baseUrl,\n path,\n options.query as Record<string, string | number | boolean | string[]> | undefined,\n );\n\n // Build headers\n const headers = new Headers(config.headers);\n if (options.headers) {\n for (const [key, value] of Object.entries(options.headers)) {\n headers.set(key, String(value));\n }\n }\n\n // Build request init\n const init: RequestInit = {\n method: endpoint.method,\n headers,\n };\n\n // Add abort signal if present\n if (options.abortSignal) {\n init.signal = options.abortSignal;\n }\n\n // Add body if present\n if (options.body !== undefined) {\n headers.set('content-type', 'application/json');\n init.body = JSON.stringify(options.body);\n }\n\n // Make request\n const response = await fetch(url, init);\n\n // Parse response\n let data: unknown;\n\n // Handle 204 No Content\n if (response.status === 204) {\n data = {};\n } else {\n const contentType = response.headers.get('content-type') || '';\n\n if (contentType.includes('application/json')) {\n data = await response.json();\n } else if (contentType.includes('text/')) {\n data = await response.text();\n } else {\n // Check if there's any content\n const text = await response.text();\n if (text) {\n data = text;\n } else {\n data = {};\n }\n }\n }\n\n // Check for HTTP errors\n if (!response.ok && !(response.status in endpoint.responses)) {\n throw new HTTPError(response.status, response.statusText, data);\n }\n\n // Validate response if enabled\n if (config.validateResponse !== false) {\n validateResponse(endpoint, response.status, data);\n }\n\n return {\n status: response.status,\n data,\n } as EndpointResponse<T>;\n}\n\n/**\n * Resolve relative baseUrl to absolute URL in browser contexts\n */\nfunction resolveBaseUrl(baseUrl: string): string {\n // If baseUrl is already absolute, return as-is\n if (baseUrl.startsWith('http://') || baseUrl.startsWith('https://')) {\n return baseUrl;\n }\n\n // If baseUrl is relative (starts with /), resolve it using window.location in browser\n if (baseUrl.startsWith('/')) {\n const g = globalThis as unknown as { location?: { origin?: string } };\n const origin = g?.location?.origin || 'http://localhost';\n return origin + baseUrl;\n }\n\n // Otherwise, assume it's a full URL\n return baseUrl;\n}\n\n/**\n * Create a typesafe client for a contract\n */\nexport function createClient<T extends Contract>(contract: T, config: ClientConfig): Client<T> {\n // Resolve relative baseUrl to absolute URL\n const resolvedConfig = {\n ...config,\n baseUrl: resolveBaseUrl(config.baseUrl),\n };\n\n const client: Record<string, unknown> = {};\n\n for (const [name, endpoint] of Object.entries(contract)) {\n client[name] = (options: EndpointRequestOptions<EndpointDefinition> = {}) => {\n return makeRequest(resolvedConfig, endpoint, options);\n };\n }\n\n return client as Client<T>;\n}\n\n/**\n * Create a client without providing the contract at runtime\n * Useful when you only need types and want a lighter bundle\n */\nexport function createTypedClient<T extends Contract>(_config: ClientConfig): Client<T> {\n return new Proxy({} as Client<T>, {\n get(_target, _prop: string) {\n return async (_options: EndpointRequestOptions<EndpointDefinition> = {}) => {\n // Without the contract, we can't validate or infer the endpoint\n // This is just a basic fetch wrapper with typing\n throw new Error(\n 'createTypedClient requires contract at runtime for validation. Use createClient instead.',\n );\n };\n },\n });\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQ0C,IAA1C;AAAA;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "D503DD5C58FB58D864756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/cjs/package.json
CHANGED
package/dist/mjs/index.mjs
CHANGED
|
@@ -79,6 +79,9 @@ async function makeRequest(config, endpoint, options) {
|
|
|
79
79
|
method: endpoint.method,
|
|
80
80
|
headers
|
|
81
81
|
};
|
|
82
|
+
if (options.abortSignal) {
|
|
83
|
+
init.signal = options.abortSignal;
|
|
84
|
+
}
|
|
82
85
|
if (options.body !== undefined) {
|
|
83
86
|
headers.set("content-type", "application/json");
|
|
84
87
|
init.body = JSON.stringify(options.body);
|
|
@@ -153,4 +156,4 @@ export {
|
|
|
153
156
|
ClientValidationError
|
|
154
157
|
};
|
|
155
158
|
|
|
156
|
-
//# debugId=
|
|
159
|
+
//# debugId=6F3D291F14313CF764756E2164756E21
|
package/dist/mjs/index.mjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type {\n Contract,\n EndpointDefinition,\n ExtractBody,\n ExtractHeaders,\n ExtractParams,\n ExtractQuery,\n} from '@richie-rpc/core';\nimport { buildUrl, interpolatePath } from '@richie-rpc/core';\nimport type { z } from 'zod';\n\n// Client configuration\nexport interface ClientConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n validateRequest?: boolean;\n validateResponse?: boolean;\n}\n\n// Request options for an endpoint\nexport type EndpointRequestOptions<T extends EndpointDefinition> = {\n params?: ExtractParams<T> extends never ? never : ExtractParams<T>;\n query?: ExtractQuery<T> extends never ? never : ExtractQuery<T>;\n headers?: ExtractHeaders<T> extends never ? never : ExtractHeaders<T>;\n body?: ExtractBody<T> extends never ? never : ExtractBody<T>;\n};\n\n// Response type for an endpoint (union of all possible responses)\nexport type EndpointResponse<T extends EndpointDefinition> = {\n [Status in keyof T['responses']]: {\n status: Status;\n data: T['responses'][Status] extends z.ZodTypeAny ? z.infer<T['responses'][Status]> : never;\n };\n}[keyof T['responses']];\n\n// Client method type for an endpoint\nexport type ClientMethod<T extends EndpointDefinition> = (\n options: EndpointRequestOptions<T>,\n) => Promise<EndpointResponse<T>>;\n\n// Client type for a contract\nexport type Client<T extends Contract> = {\n [K in keyof T]: ClientMethod<T[K]>;\n};\n\n// Validation error\nexport class ClientValidationError extends Error {\n constructor(\n public field: string,\n public issues: z.ZodIssue[],\n ) {\n super(`Validation failed for ${field}`);\n this.name = 'ClientValidationError';\n }\n}\n\n// HTTP error\nexport class HTTPError extends Error {\n constructor(\n public status: number,\n public statusText: string,\n public body: unknown,\n ) {\n super(`HTTP Error ${status}: ${statusText}`);\n this.name = 'HTTPError';\n }\n}\n\n/**\n * Validate request data before sending\n */\nfunction validateRequest<T extends EndpointDefinition>(\n endpoint: T,\n options: EndpointRequestOptions<T>,\n): void {\n // Validate params\n if (endpoint.params && options.params) {\n const result = endpoint.params.safeParse(options.params);\n if (!result.success) {\n throw new ClientValidationError('params', result.error.issues);\n }\n }\n\n // Validate query\n if (endpoint.query && options.query) {\n const result = endpoint.query.safeParse(options.query);\n if (!result.success) {\n throw new ClientValidationError('query', result.error.issues);\n }\n }\n\n // Validate headers\n if (endpoint.headers && options.headers) {\n const result = endpoint.headers.safeParse(options.headers);\n if (!result.success) {\n throw new ClientValidationError('headers', result.error.issues);\n }\n }\n\n // Validate body\n if (endpoint.body && options.body) {\n const result = endpoint.body.safeParse(options.body);\n if (!result.success) {\n throw new ClientValidationError('body', result.error.issues);\n }\n }\n}\n\n/**\n * Validate response data after receiving\n */\nfunction validateResponse<T extends EndpointDefinition>(\n endpoint: T,\n status: number,\n data: unknown,\n): void {\n const responseSchema = endpoint.responses[status];\n if (responseSchema) {\n const result = responseSchema.safeParse(data);\n if (!result.success) {\n throw new ClientValidationError(`response[${status}]`, result.error.issues);\n }\n }\n}\n\n/**\n * Make a request to an endpoint\n */\nasync function makeRequest<T extends EndpointDefinition>(\n config: ClientConfig,\n endpoint: T,\n options: EndpointRequestOptions<T>,\n): Promise<EndpointResponse<T>> {\n // Validate request if enabled\n if (config.validateRequest !== false) {\n validateRequest(endpoint, options);\n }\n\n // Build URL\n let path = endpoint.path;\n if (options.params) {\n path = interpolatePath(path, options.params as Record<string, string | number>);\n }\n\n const url = buildUrl(\n config.baseUrl,\n path,\n options.query as Record<string, string | number | boolean | string[]> | undefined,\n );\n\n // Build headers\n const headers = new Headers(config.headers);\n if (options.headers) {\n for (const [key, value] of Object.entries(options.headers)) {\n headers.set(key, String(value));\n }\n }\n\n // Build request init\n const init: RequestInit = {\n method: endpoint.method,\n headers,\n };\n\n // Add body if present\n if (options.body !== undefined) {\n headers.set('content-type', 'application/json');\n init.body = JSON.stringify(options.body);\n }\n\n // Make request\n const response = await fetch(url, init);\n\n // Parse response\n let data: unknown;\n\n // Handle 204 No Content\n if (response.status === 204) {\n data = {};\n } else {\n const contentType = response.headers.get('content-type') || '';\n\n if (contentType.includes('application/json')) {\n data = await response.json();\n } else if (contentType.includes('text/')) {\n data = await response.text();\n } else {\n // Check if there's any content\n const text = await response.text();\n if (text) {\n data = text;\n } else {\n data = {};\n }\n }\n }\n\n // Check for HTTP errors\n if (!response.ok && !(response.status in endpoint.responses)) {\n throw new HTTPError(response.status, response.statusText, data);\n }\n\n // Validate response if enabled\n if (config.validateResponse !== false) {\n validateResponse(endpoint, response.status, data);\n }\n\n return {\n status: response.status,\n data,\n } as EndpointResponse<T>;\n}\n\n/**\n * Resolve relative baseUrl to absolute URL in browser contexts\n */\nfunction resolveBaseUrl(baseUrl: string): string {\n // If baseUrl is already absolute, return as-is\n if (baseUrl.startsWith('http://') || baseUrl.startsWith('https://')) {\n return baseUrl;\n }\n\n // If baseUrl is relative (starts with /), resolve it using window.location in browser\n if (baseUrl.startsWith('/')) {\n const g = globalThis as unknown as { location?: { origin?: string } };\n const origin = g?.location?.origin || 'http://localhost';\n return origin + baseUrl;\n }\n\n // Otherwise, assume it's a full URL\n return baseUrl;\n}\n\n/**\n * Create a typesafe client for a contract\n */\nexport function createClient<T extends Contract>(contract: T, config: ClientConfig): Client<T> {\n // Resolve relative baseUrl to absolute URL\n const resolvedConfig = {\n ...config,\n baseUrl: resolveBaseUrl(config.baseUrl),\n };\n\n const client: Record<string, unknown> = {};\n\n for (const [name, endpoint] of Object.entries(contract)) {\n client[name] = (options: EndpointRequestOptions<EndpointDefinition> = {}) => {\n return makeRequest(resolvedConfig, endpoint, options);\n };\n }\n\n return client as Client<T>;\n}\n\n/**\n * Create a client without providing the contract at runtime\n * Useful when you only need types and want a lighter bundle\n */\nexport function createTypedClient<T extends Contract>(_config: ClientConfig): Client<T> {\n return new Proxy({} as Client<T>, {\n get(_target, _prop: string) {\n return async (_options: EndpointRequestOptions<EndpointDefinition> = {}) => {\n // Without the contract, we can't validate or infer the endpoint\n // This is just a basic fetch wrapper with typing\n throw new Error(\n 'createTypedClient requires contract at runtime for validation. Use createClient instead.',\n );\n };\n },\n });\n}\n"
|
|
5
|
+
"import type {\n Contract,\n EndpointDefinition,\n ExtractBody,\n ExtractHeaders,\n ExtractParams,\n ExtractQuery,\n} from '@richie-rpc/core';\nimport { buildUrl, interpolatePath } from '@richie-rpc/core';\nimport type { z } from 'zod';\n\n// Client configuration\nexport interface ClientConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n validateRequest?: boolean;\n validateResponse?: boolean;\n}\n\n// Request options for an endpoint\nexport type EndpointRequestOptions<T extends EndpointDefinition> = {\n params?: ExtractParams<T> extends never ? never : ExtractParams<T>;\n query?: ExtractQuery<T> extends never ? never : ExtractQuery<T>;\n headers?: ExtractHeaders<T> extends never ? never : ExtractHeaders<T>;\n body?: ExtractBody<T> extends never ? never : ExtractBody<T>;\n abortSignal?: AbortSignal;\n};\n\n// Response type for an endpoint (union of all possible responses)\nexport type EndpointResponse<T extends EndpointDefinition> = {\n [Status in keyof T['responses']]: {\n status: Status;\n data: T['responses'][Status] extends z.ZodTypeAny ? z.infer<T['responses'][Status]> : never;\n };\n}[keyof T['responses']];\n\n// Client method type for an endpoint\nexport type ClientMethod<T extends EndpointDefinition> = (\n options: EndpointRequestOptions<T>,\n) => Promise<EndpointResponse<T>>;\n\n// Client type for a contract\nexport type Client<T extends Contract> = {\n [K in keyof T]: ClientMethod<T[K]>;\n};\n\n// Validation error\nexport class ClientValidationError extends Error {\n constructor(\n public field: string,\n public issues: z.ZodIssue[],\n ) {\n super(`Validation failed for ${field}`);\n this.name = 'ClientValidationError';\n }\n}\n\n// HTTP error\nexport class HTTPError extends Error {\n constructor(\n public status: number,\n public statusText: string,\n public body: unknown,\n ) {\n super(`HTTP Error ${status}: ${statusText}`);\n this.name = 'HTTPError';\n }\n}\n\n/**\n * Validate request data before sending\n */\nfunction validateRequest<T extends EndpointDefinition>(\n endpoint: T,\n options: EndpointRequestOptions<T>,\n): void {\n // Validate params\n if (endpoint.params && options.params) {\n const result = endpoint.params.safeParse(options.params);\n if (!result.success) {\n throw new ClientValidationError('params', result.error.issues);\n }\n }\n\n // Validate query\n if (endpoint.query && options.query) {\n const result = endpoint.query.safeParse(options.query);\n if (!result.success) {\n throw new ClientValidationError('query', result.error.issues);\n }\n }\n\n // Validate headers\n if (endpoint.headers && options.headers) {\n const result = endpoint.headers.safeParse(options.headers);\n if (!result.success) {\n throw new ClientValidationError('headers', result.error.issues);\n }\n }\n\n // Validate body\n if (endpoint.body && options.body) {\n const result = endpoint.body.safeParse(options.body);\n if (!result.success) {\n throw new ClientValidationError('body', result.error.issues);\n }\n }\n}\n\n/**\n * Validate response data after receiving\n */\nfunction validateResponse<T extends EndpointDefinition>(\n endpoint: T,\n status: number,\n data: unknown,\n): void {\n const responseSchema = endpoint.responses[status];\n if (responseSchema) {\n const result = responseSchema.safeParse(data);\n if (!result.success) {\n throw new ClientValidationError(`response[${status}]`, result.error.issues);\n }\n }\n}\n\n/**\n * Make a request to an endpoint\n */\nasync function makeRequest<T extends EndpointDefinition>(\n config: ClientConfig,\n endpoint: T,\n options: EndpointRequestOptions<T>,\n): Promise<EndpointResponse<T>> {\n // Validate request if enabled\n if (config.validateRequest !== false) {\n validateRequest(endpoint, options);\n }\n\n // Build URL\n let path = endpoint.path;\n if (options.params) {\n path = interpolatePath(path, options.params as Record<string, string | number>);\n }\n\n const url = buildUrl(\n config.baseUrl,\n path,\n options.query as Record<string, string | number | boolean | string[]> | undefined,\n );\n\n // Build headers\n const headers = new Headers(config.headers);\n if (options.headers) {\n for (const [key, value] of Object.entries(options.headers)) {\n headers.set(key, String(value));\n }\n }\n\n // Build request init\n const init: RequestInit = {\n method: endpoint.method,\n headers,\n };\n\n // Add abort signal if present\n if (options.abortSignal) {\n init.signal = options.abortSignal;\n }\n\n // Add body if present\n if (options.body !== undefined) {\n headers.set('content-type', 'application/json');\n init.body = JSON.stringify(options.body);\n }\n\n // Make request\n const response = await fetch(url, init);\n\n // Parse response\n let data: unknown;\n\n // Handle 204 No Content\n if (response.status === 204) {\n data = {};\n } else {\n const contentType = response.headers.get('content-type') || '';\n\n if (contentType.includes('application/json')) {\n data = await response.json();\n } else if (contentType.includes('text/')) {\n data = await response.text();\n } else {\n // Check if there's any content\n const text = await response.text();\n if (text) {\n data = text;\n } else {\n data = {};\n }\n }\n }\n\n // Check for HTTP errors\n if (!response.ok && !(response.status in endpoint.responses)) {\n throw new HTTPError(response.status, response.statusText, data);\n }\n\n // Validate response if enabled\n if (config.validateResponse !== false) {\n validateResponse(endpoint, response.status, data);\n }\n\n return {\n status: response.status,\n data,\n } as EndpointResponse<T>;\n}\n\n/**\n * Resolve relative baseUrl to absolute URL in browser contexts\n */\nfunction resolveBaseUrl(baseUrl: string): string {\n // If baseUrl is already absolute, return as-is\n if (baseUrl.startsWith('http://') || baseUrl.startsWith('https://')) {\n return baseUrl;\n }\n\n // If baseUrl is relative (starts with /), resolve it using window.location in browser\n if (baseUrl.startsWith('/')) {\n const g = globalThis as unknown as { location?: { origin?: string } };\n const origin = g?.location?.origin || 'http://localhost';\n return origin + baseUrl;\n }\n\n // Otherwise, assume it's a full URL\n return baseUrl;\n}\n\n/**\n * Create a typesafe client for a contract\n */\nexport function createClient<T extends Contract>(contract: T, config: ClientConfig): Client<T> {\n // Resolve relative baseUrl to absolute URL\n const resolvedConfig = {\n ...config,\n baseUrl: resolveBaseUrl(config.baseUrl),\n };\n\n const client: Record<string, unknown> = {};\n\n for (const [name, endpoint] of Object.entries(contract)) {\n client[name] = (options: EndpointRequestOptions<EndpointDefinition> = {}) => {\n return makeRequest(resolvedConfig, endpoint, options);\n };\n }\n\n return client as Client<T>;\n}\n\n/**\n * Create a client without providing the contract at runtime\n * Useful when you only need types and want a lighter bundle\n */\nexport function createTypedClient<T extends Contract>(_config: ClientConfig): Client<T> {\n return new Proxy({} as Client<T>, {\n get(_target, _prop: string) {\n return async (_options: EndpointRequestOptions<EndpointDefinition> = {}) => {\n // Without the contract, we can't validate or infer the endpoint\n // This is just a basic fetch wrapper with typing\n throw new Error(\n 'createTypedClient requires contract at runtime for validation. Use createClient instead.',\n );\n };\n },\n });\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;AAQA;AAAA;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;AAQA;AAAA;AAuCO,MAAM,8BAA8B,MAAM;AAAA,EAEtC;AAAA,EACA;AAAA,EAFT,WAAW,CACF,OACA,QACP;AAAA,IACA,MAAM,yBAAyB,OAAO;AAAA,IAH/B;AAAA,IACA;AAAA,IAGP,KAAK,OAAO;AAAA;AAEhB;AAAA;AAGO,MAAM,kBAAkB,MAAM;AAAA,EAE1B;AAAA,EACA;AAAA,EACA;AAAA,EAHT,WAAW,CACF,QACA,YACA,MACP;AAAA,IACA,MAAM,cAAc,WAAW,YAAY;AAAA,IAJpC;AAAA,IACA;AAAA,IACA;AAAA,IAGP,KAAK,OAAO;AAAA;AAEhB;AAKA,SAAS,eAA6C,CACpD,UACA,SACM;AAAA,EAEN,IAAI,SAAS,UAAU,QAAQ,QAAQ;AAAA,IACrC,MAAM,SAAS,SAAS,OAAO,UAAU,QAAQ,MAAM;AAAA,IACvD,IAAI,CAAC,OAAO,SAAS;AAAA,MACnB,MAAM,IAAI,sBAAsB,UAAU,OAAO,MAAM,MAAM;AAAA,IAC/D;AAAA,EACF;AAAA,EAGA,IAAI,SAAS,SAAS,QAAQ,OAAO;AAAA,IACnC,MAAM,SAAS,SAAS,MAAM,UAAU,QAAQ,KAAK;AAAA,IACrD,IAAI,CAAC,OAAO,SAAS;AAAA,MACnB,MAAM,IAAI,sBAAsB,SAAS,OAAO,MAAM,MAAM;AAAA,IAC9D;AAAA,EACF;AAAA,EAGA,IAAI,SAAS,WAAW,QAAQ,SAAS;AAAA,IACvC,MAAM,SAAS,SAAS,QAAQ,UAAU,QAAQ,OAAO;AAAA,IACzD,IAAI,CAAC,OAAO,SAAS;AAAA,MACnB,MAAM,IAAI,sBAAsB,WAAW,OAAO,MAAM,MAAM;AAAA,IAChE;AAAA,EACF;AAAA,EAGA,IAAI,SAAS,QAAQ,QAAQ,MAAM;AAAA,IACjC,MAAM,SAAS,SAAS,KAAK,UAAU,QAAQ,IAAI;AAAA,IACnD,IAAI,CAAC,OAAO,SAAS;AAAA,MACnB,MAAM,IAAI,sBAAsB,QAAQ,OAAO,MAAM,MAAM;AAAA,IAC7D;AAAA,EACF;AAAA;AAMF,SAAS,gBAA8C,CACrD,UACA,QACA,MACM;AAAA,EACN,MAAM,iBAAiB,SAAS,UAAU;AAAA,EAC1C,IAAI,gBAAgB;AAAA,IAClB,MAAM,SAAS,eAAe,UAAU,IAAI;AAAA,IAC5C,IAAI,CAAC,OAAO,SAAS;AAAA,MACnB,MAAM,IAAI,sBAAsB,YAAY,WAAW,OAAO,MAAM,MAAM;AAAA,IAC5E;AAAA,EACF;AAAA;AAMF,eAAe,WAAyC,CACtD,QACA,UACA,SAC8B;AAAA,EAE9B,IAAI,OAAO,oBAAoB,OAAO;AAAA,IACpC,gBAAgB,UAAU,OAAO;AAAA,EACnC;AAAA,EAGA,IAAI,OAAO,SAAS;AAAA,EACpB,IAAI,QAAQ,QAAQ;AAAA,IAClB,OAAO,gBAAgB,MAAM,QAAQ,MAAyC;AAAA,EAChF;AAAA,EAEA,MAAM,MAAM,SACV,OAAO,SACP,MACA,QAAQ,KACV;AAAA,EAGA,MAAM,UAAU,IAAI,QAAQ,OAAO,OAAO;AAAA,EAC1C,IAAI,QAAQ,SAAS;AAAA,IACnB,YAAY,KAAK,UAAU,OAAO,QAAQ,QAAQ,OAAO,GAAG;AAAA,MAC1D,QAAQ,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,IAChC;AAAA,EACF;AAAA,EAGA,MAAM,OAAoB;AAAA,IACxB,QAAQ,SAAS;AAAA,IACjB;AAAA,EACF;AAAA,EAGA,IAAI,QAAQ,aAAa;AAAA,IACvB,KAAK,SAAS,QAAQ;AAAA,EACxB;AAAA,EAGA,IAAI,QAAQ,SAAS,WAAW;AAAA,IAC9B,QAAQ,IAAI,gBAAgB,kBAAkB;AAAA,IAC9C,KAAK,OAAO,KAAK,UAAU,QAAQ,IAAI;AAAA,EACzC;AAAA,EAGA,MAAM,WAAW,MAAM,MAAM,KAAK,IAAI;AAAA,EAGtC,IAAI;AAAA,EAGJ,IAAI,SAAS,WAAW,KAAK;AAAA,IAC3B,OAAO,CAAC;AAAA,EACV,EAAO;AAAA,IACL,MAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAAA,IAE5D,IAAI,YAAY,SAAS,kBAAkB,GAAG;AAAA,MAC5C,OAAO,MAAM,SAAS,KAAK;AAAA,IAC7B,EAAO,SAAI,YAAY,SAAS,OAAO,GAAG;AAAA,MACxC,OAAO,MAAM,SAAS,KAAK;AAAA,IAC7B,EAAO;AAAA,MAEL,MAAM,OAAO,MAAM,SAAS,KAAK;AAAA,MACjC,IAAI,MAAM;AAAA,QACR,OAAO;AAAA,MACT,EAAO;AAAA,QACL,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA,EAMd,IAAI,CAAC,SAAS,MAAM,EAAE,SAAS,UAAU,SAAS,YAAY;AAAA,IAC5D,MAAM,IAAI,UAAU,SAAS,QAAQ,SAAS,YAAY,IAAI;AAAA,EAChE;AAAA,EAGA,IAAI,OAAO,qBAAqB,OAAO;AAAA,IACrC,iBAAiB,UAAU,SAAS,QAAQ,IAAI;AAAA,EAClD;AAAA,EAEA,OAAO;AAAA,IACL,QAAQ,SAAS;AAAA,IACjB;AAAA,EACF;AAAA;AAMF,SAAS,cAAc,CAAC,SAAyB;AAAA,EAE/C,IAAI,QAAQ,WAAW,SAAS,KAAK,QAAQ,WAAW,UAAU,GAAG;AAAA,IACnE,OAAO;AAAA,EACT;AAAA,EAGA,IAAI,QAAQ,WAAW,GAAG,GAAG;AAAA,IAC3B,MAAM,IAAI;AAAA,IACV,MAAM,SAAS,GAAG,UAAU,UAAU;AAAA,IACtC,OAAO,SAAS;AAAA,EAClB;AAAA,EAGA,OAAO;AAAA;AAMF,SAAS,YAAgC,CAAC,UAAa,QAAiC;AAAA,EAE7F,MAAM,iBAAiB;AAAA,OAClB;AAAA,IACH,SAAS,eAAe,OAAO,OAAO;AAAA,EACxC;AAAA,EAEA,MAAM,SAAkC,CAAC;AAAA,EAEzC,YAAY,MAAM,aAAa,OAAO,QAAQ,QAAQ,GAAG;AAAA,IACvD,OAAO,QAAQ,CAAC,UAAsD,CAAC,MAAM;AAAA,MAC3E,OAAO,YAAY,gBAAgB,UAAU,OAAO;AAAA;AAAA,EAExD;AAAA,EAEA,OAAO;AAAA;AAOF,SAAS,iBAAqC,CAAC,SAAkC;AAAA,EACtF,OAAO,IAAI,MAAM,CAAC,GAAgB;AAAA,IAChC,GAAG,CAAC,SAAS,OAAe;AAAA,MAC1B,OAAO,OAAO,WAAuD,CAAC,MAAM;AAAA,QAG1E,MAAM,IAAI,MACR,0FACF;AAAA;AAAA;AAAA,EAGN,CAAC;AAAA;",
|
|
8
|
+
"debugId": "6F3D291F14313CF764756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/mjs/package.json
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export type EndpointRequestOptions<T extends EndpointDefinition> = {
|
|
|
11
11
|
query?: ExtractQuery<T> extends never ? never : ExtractQuery<T>;
|
|
12
12
|
headers?: ExtractHeaders<T> extends never ? never : ExtractHeaders<T>;
|
|
13
13
|
body?: ExtractBody<T> extends never ? never : ExtractBody<T>;
|
|
14
|
+
abortSignal?: AbortSignal;
|
|
14
15
|
};
|
|
15
16
|
export type EndpointResponse<T extends EndpointDefinition> = {
|
|
16
17
|
[Status in keyof T['responses']]: {
|