@veloxts/client 0.1.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/LICENSE +21 -0
- package/README.md +263 -0
- package/dist/client.d.ts +56 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +376 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +164 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +250 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +173 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-safe API client implementation
|
|
3
|
+
*
|
|
4
|
+
* Provides a fetch-based client that calls REST endpoints with full type safety
|
|
5
|
+
* inferred from backend procedure definitions.
|
|
6
|
+
*
|
|
7
|
+
* @module client
|
|
8
|
+
*/
|
|
9
|
+
import { NetworkError, parseErrorResponse } from './errors.js';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Naming Convention Mapping
|
|
12
|
+
// ============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Maps procedure naming convention to HTTP method
|
|
15
|
+
*
|
|
16
|
+
* Matches the same logic used in @veloxts/router REST adapter
|
|
17
|
+
*/
|
|
18
|
+
const PROCEDURE_METHOD_MAP = {
|
|
19
|
+
get: 'GET',
|
|
20
|
+
list: 'GET',
|
|
21
|
+
find: 'GET',
|
|
22
|
+
create: 'POST',
|
|
23
|
+
add: 'POST',
|
|
24
|
+
update: 'PUT',
|
|
25
|
+
edit: 'PUT',
|
|
26
|
+
patch: 'PATCH',
|
|
27
|
+
delete: 'DELETE',
|
|
28
|
+
remove: 'DELETE',
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Pre-compiled regex pattern for path parameters
|
|
32
|
+
*
|
|
33
|
+
* PERFORMANCE: Compiled once at module load instead of per-request.
|
|
34
|
+
* The pattern matches :paramName format (e.g., :id, :userId, :post_id)
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
const PATH_PARAM_PATTERN = /:([a-zA-Z_][a-zA-Z0-9_]*)/g;
|
|
39
|
+
/**
|
|
40
|
+
* Infers HTTP method from procedure name
|
|
41
|
+
*
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
function inferMethodFromName(procedureName) {
|
|
45
|
+
// Check each prefix
|
|
46
|
+
for (const [prefix, method] of Object.entries(PROCEDURE_METHOD_MAP)) {
|
|
47
|
+
if (procedureName.startsWith(prefix)) {
|
|
48
|
+
return method;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Default to POST for mutations (conservative default)
|
|
52
|
+
return 'POST';
|
|
53
|
+
}
|
|
54
|
+
// Note: extractResourceFromName is reserved for future use in path building enhancements
|
|
55
|
+
// Keeping it commented for now to avoid unused code warnings
|
|
56
|
+
// function extractResourceFromName(procedureName: string): string | undefined {
|
|
57
|
+
// for (const prefix of Object.keys(PROCEDURE_METHOD_MAP)) {
|
|
58
|
+
// if (procedureName.startsWith(prefix)) {
|
|
59
|
+
// const remainder = procedureName.slice(prefix.length);
|
|
60
|
+
// if (remainder.length > 0) {
|
|
61
|
+
// return remainder.charAt(0).toLowerCase() + remainder.slice(1);
|
|
62
|
+
// }
|
|
63
|
+
// }
|
|
64
|
+
// }
|
|
65
|
+
// return undefined;
|
|
66
|
+
// }
|
|
67
|
+
/**
|
|
68
|
+
* Builds REST path from namespace and procedure name
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* - namespace='users', name='getUser' -> '/users/:id'
|
|
72
|
+
* - namespace='users', name='listUsers' -> '/users'
|
|
73
|
+
* - namespace='posts', name='createPost' -> '/posts'
|
|
74
|
+
*
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
function buildRestPath(namespace, procedureName) {
|
|
78
|
+
const method = inferMethodFromName(procedureName);
|
|
79
|
+
// List operations: /namespace
|
|
80
|
+
if (procedureName.startsWith('list')) {
|
|
81
|
+
return `/${namespace}`;
|
|
82
|
+
}
|
|
83
|
+
// Single resource operations (get, update, delete): /namespace/:id
|
|
84
|
+
if (procedureName.startsWith('get') ||
|
|
85
|
+
procedureName.startsWith('update') ||
|
|
86
|
+
procedureName.startsWith('delete')) {
|
|
87
|
+
return `/${namespace}/:id`;
|
|
88
|
+
}
|
|
89
|
+
// Create operations: /namespace
|
|
90
|
+
if (method === 'POST') {
|
|
91
|
+
return `/${namespace}`;
|
|
92
|
+
}
|
|
93
|
+
// Default: /namespace
|
|
94
|
+
return `/${namespace}`;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Replaces path parameters with actual values from input
|
|
98
|
+
*
|
|
99
|
+
* PERFORMANCE: Uses pre-compiled PATH_PARAM_PATTERN instead of creating
|
|
100
|
+
* a new RegExp on each call. Resets lastIndex for safe reuse.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* - path='/users/:id', input={ id: '123' } -> '/users/123'
|
|
104
|
+
* - path='/posts/:postId/comments/:id', input={ postId: 'abc', id: '456' } -> '/posts/abc/comments/456'
|
|
105
|
+
*
|
|
106
|
+
* @internal
|
|
107
|
+
*/
|
|
108
|
+
function resolvePathParams(path, input) {
|
|
109
|
+
// Reset lastIndex for safe reuse of global regex
|
|
110
|
+
PATH_PARAM_PATTERN.lastIndex = 0;
|
|
111
|
+
return path.replace(PATH_PARAM_PATTERN, (_match, paramName) => {
|
|
112
|
+
const value = input[paramName];
|
|
113
|
+
if (value === undefined || value === null) {
|
|
114
|
+
throw new Error(`Missing path parameter: ${paramName}`);
|
|
115
|
+
}
|
|
116
|
+
return String(value);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Builds query string from input object, excluding path params
|
|
121
|
+
*
|
|
122
|
+
* @internal
|
|
123
|
+
*/
|
|
124
|
+
function buildQueryString(input, pathParams) {
|
|
125
|
+
const params = new URLSearchParams();
|
|
126
|
+
for (const [key, value] of Object.entries(input)) {
|
|
127
|
+
// Skip path parameters
|
|
128
|
+
if (pathParams.has(key)) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
// Skip undefined values
|
|
132
|
+
if (value === undefined) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
// Handle arrays
|
|
136
|
+
if (Array.isArray(value)) {
|
|
137
|
+
for (const item of value) {
|
|
138
|
+
params.append(key, String(item));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
params.append(key, String(value));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const queryString = params.toString();
|
|
146
|
+
return queryString ? `?${queryString}` : '';
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Extracts path parameter names from a path pattern
|
|
150
|
+
*
|
|
151
|
+
* PERFORMANCE: Uses pre-compiled PATH_PARAM_PATTERN instead of creating
|
|
152
|
+
* a new RegExp on each call. Uses matchAll which handles lastIndex internally.
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* - '/users/:id' -> Set(['id'])
|
|
156
|
+
* - '/posts/:postId/comments/:commentId' -> Set(['postId', 'commentId'])
|
|
157
|
+
*
|
|
158
|
+
* @internal
|
|
159
|
+
*/
|
|
160
|
+
function extractPathParams(path) {
|
|
161
|
+
const params = new Set();
|
|
162
|
+
// matchAll creates an iterator that handles lastIndex internally
|
|
163
|
+
for (const match of path.matchAll(PATH_PARAM_PATTERN)) {
|
|
164
|
+
params.add(match[1]);
|
|
165
|
+
}
|
|
166
|
+
return params;
|
|
167
|
+
}
|
|
168
|
+
// ============================================================================
|
|
169
|
+
// Request Building
|
|
170
|
+
// ============================================================================
|
|
171
|
+
/**
|
|
172
|
+
* Builds the full URL and request options for a procedure call
|
|
173
|
+
*
|
|
174
|
+
* @internal
|
|
175
|
+
*/
|
|
176
|
+
function buildRequest(call, baseUrl, config) {
|
|
177
|
+
const method = inferMethodFromName(call.procedureName);
|
|
178
|
+
const path = buildRestPath(call.namespace, call.procedureName);
|
|
179
|
+
// Prepare headers
|
|
180
|
+
const headers = {
|
|
181
|
+
'Content-Type': 'application/json',
|
|
182
|
+
...config.headers,
|
|
183
|
+
};
|
|
184
|
+
let finalPath = path;
|
|
185
|
+
let body;
|
|
186
|
+
// Handle input based on method
|
|
187
|
+
if (method === 'GET') {
|
|
188
|
+
// GET: params in URL
|
|
189
|
+
const pathParams = extractPathParams(path);
|
|
190
|
+
const input = (call.input || {});
|
|
191
|
+
// Resolve path parameters
|
|
192
|
+
finalPath = resolvePathParams(path, input);
|
|
193
|
+
// Add query string for remaining parameters
|
|
194
|
+
const queryString = buildQueryString(input, pathParams);
|
|
195
|
+
finalPath = `${finalPath}${queryString}`;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// POST/PUT/PATCH/DELETE: body as JSON
|
|
199
|
+
// But first resolve path params if any
|
|
200
|
+
const pathParams = extractPathParams(path);
|
|
201
|
+
if (pathParams.size > 0 && call.input && typeof call.input === 'object') {
|
|
202
|
+
const input = call.input;
|
|
203
|
+
finalPath = resolvePathParams(path, input);
|
|
204
|
+
// For POST with path params, body is the input minus path params
|
|
205
|
+
const bodyInput = {};
|
|
206
|
+
for (const [key, value] of Object.entries(input)) {
|
|
207
|
+
if (!pathParams.has(key)) {
|
|
208
|
+
bodyInput[key] = value;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
body = JSON.stringify(bodyInput);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
body = JSON.stringify(call.input);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// Build full URL
|
|
218
|
+
const url = `${baseUrl}${finalPath}`;
|
|
219
|
+
return {
|
|
220
|
+
url,
|
|
221
|
+
options: {
|
|
222
|
+
method,
|
|
223
|
+
headers,
|
|
224
|
+
body,
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Executes a procedure call against the API
|
|
230
|
+
*
|
|
231
|
+
* @internal
|
|
232
|
+
*/
|
|
233
|
+
async function executeProcedure(call, state) {
|
|
234
|
+
const { url, options } = buildRequest(call, state.config.baseUrl, state.config);
|
|
235
|
+
// Call onRequest interceptor
|
|
236
|
+
if (state.config.onRequest) {
|
|
237
|
+
await state.config.onRequest(url, options);
|
|
238
|
+
}
|
|
239
|
+
let response;
|
|
240
|
+
try {
|
|
241
|
+
response = await state.fetch(url, options);
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
// Network error - couldn't reach server
|
|
245
|
+
const networkError = new NetworkError('Network request failed', {
|
|
246
|
+
url,
|
|
247
|
+
method: options.method || 'GET',
|
|
248
|
+
cause: error instanceof Error ? error : undefined,
|
|
249
|
+
});
|
|
250
|
+
// Call onError interceptor
|
|
251
|
+
if (state.config.onError) {
|
|
252
|
+
await state.config.onError(networkError);
|
|
253
|
+
}
|
|
254
|
+
throw networkError;
|
|
255
|
+
}
|
|
256
|
+
// Parse response body
|
|
257
|
+
let body;
|
|
258
|
+
const contentType = response.headers.get('content-type');
|
|
259
|
+
if (contentType?.includes('application/json')) {
|
|
260
|
+
try {
|
|
261
|
+
body = await response.json();
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
// Couldn't parse JSON - use text
|
|
265
|
+
body = await response.text();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
body = await response.text();
|
|
270
|
+
}
|
|
271
|
+
// Handle error responses
|
|
272
|
+
if (!response.ok) {
|
|
273
|
+
const error = parseErrorResponse(response, body, url, options.method || 'GET');
|
|
274
|
+
// Call onError interceptor
|
|
275
|
+
if (state.config.onError) {
|
|
276
|
+
await state.config.onError(error);
|
|
277
|
+
}
|
|
278
|
+
throw error;
|
|
279
|
+
}
|
|
280
|
+
// Call onResponse interceptor
|
|
281
|
+
if (state.config.onResponse) {
|
|
282
|
+
await state.config.onResponse(response);
|
|
283
|
+
}
|
|
284
|
+
return body;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Creates a proxy for a namespace that intercepts procedure calls
|
|
288
|
+
*
|
|
289
|
+
* @internal
|
|
290
|
+
*/
|
|
291
|
+
function createNamespaceProxy(namespace, state) {
|
|
292
|
+
return new Proxy({}, {
|
|
293
|
+
get(_target, procedureName) {
|
|
294
|
+
// Return a function that executes the procedure
|
|
295
|
+
return (input) => {
|
|
296
|
+
return executeProcedure({
|
|
297
|
+
namespace,
|
|
298
|
+
procedureName,
|
|
299
|
+
input,
|
|
300
|
+
}, state);
|
|
301
|
+
};
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Creates the root client proxy
|
|
307
|
+
*
|
|
308
|
+
* @internal
|
|
309
|
+
*/
|
|
310
|
+
function createClientProxy(state) {
|
|
311
|
+
return new Proxy({}, {
|
|
312
|
+
get(_target, namespace) {
|
|
313
|
+
return createNamespaceProxy(namespace, state);
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
// ============================================================================
|
|
318
|
+
// Public API
|
|
319
|
+
// ============================================================================
|
|
320
|
+
/**
|
|
321
|
+
* Creates a type-safe API client for a VeloxTS backend
|
|
322
|
+
*
|
|
323
|
+
* The client uses TypeScript's type system to infer the full API shape from
|
|
324
|
+
* backend procedure definitions, providing autocomplete and compile-time type checking.
|
|
325
|
+
*
|
|
326
|
+
* @template TRouter - The router type (typeof imported procedures)
|
|
327
|
+
* @param config - Client configuration
|
|
328
|
+
* @returns Fully typed API client with namespaced procedures
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```typescript
|
|
332
|
+
* // Import procedure types from backend
|
|
333
|
+
* import type { userProcedures, postProcedures } from '../server/procedures';
|
|
334
|
+
*
|
|
335
|
+
* // Create client with inferred types
|
|
336
|
+
* const api = createClient<{
|
|
337
|
+
* users: typeof userProcedures;
|
|
338
|
+
* posts: typeof postProcedures;
|
|
339
|
+
* }>({
|
|
340
|
+
* baseUrl: 'https://api.example.com/api',
|
|
341
|
+
* });
|
|
342
|
+
*
|
|
343
|
+
* // Fully typed calls
|
|
344
|
+
* const user = await api.users.getUser({ id: '123' });
|
|
345
|
+
* const newPost = await api.posts.createPost({ title: 'Hello', content: '...' });
|
|
346
|
+
* ```
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```typescript
|
|
350
|
+
* // With custom configuration
|
|
351
|
+
* const api = createClient<Router>({
|
|
352
|
+
* baseUrl: '/api',
|
|
353
|
+
* headers: {
|
|
354
|
+
* 'Authorization': 'Bearer token123',
|
|
355
|
+
* },
|
|
356
|
+
* onRequest: async (url, options) => {
|
|
357
|
+
* console.log(`${options.method} ${url}`);
|
|
358
|
+
* },
|
|
359
|
+
* onError: async (error) => {
|
|
360
|
+
* console.error('API Error:', error.message);
|
|
361
|
+
* },
|
|
362
|
+
* });
|
|
363
|
+
* ```
|
|
364
|
+
*/
|
|
365
|
+
export function createClient(config) {
|
|
366
|
+
// Use provided fetch or global fetch
|
|
367
|
+
const fetchImpl = config.fetch || fetch;
|
|
368
|
+
// Create client state
|
|
369
|
+
const state = {
|
|
370
|
+
config,
|
|
371
|
+
fetch: fetchImpl,
|
|
372
|
+
};
|
|
373
|
+
// Return the proxy-based client
|
|
374
|
+
return createClientProxy(state);
|
|
375
|
+
}
|
|
376
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side error handling
|
|
3
|
+
*
|
|
4
|
+
* Provides error classes that mirror the server-side VeloxError structure,
|
|
5
|
+
* with additional context about the failed request.
|
|
6
|
+
*
|
|
7
|
+
* @module errors
|
|
8
|
+
*/
|
|
9
|
+
import type { ClientError } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Base error response fields from server
|
|
12
|
+
*/
|
|
13
|
+
interface BaseErrorResponse {
|
|
14
|
+
error: string;
|
|
15
|
+
message: string;
|
|
16
|
+
statusCode: number;
|
|
17
|
+
code?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Validation error response from server
|
|
21
|
+
*/
|
|
22
|
+
interface ValidationErrorResponse extends BaseErrorResponse {
|
|
23
|
+
error: 'ValidationError';
|
|
24
|
+
statusCode: 400;
|
|
25
|
+
code: 'VALIDATION_ERROR';
|
|
26
|
+
fields?: Record<string, string>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Not found error response from server
|
|
30
|
+
*/
|
|
31
|
+
interface NotFoundErrorResponse extends BaseErrorResponse {
|
|
32
|
+
error: 'NotFoundError';
|
|
33
|
+
statusCode: 404;
|
|
34
|
+
code: 'NOT_FOUND';
|
|
35
|
+
resource: string;
|
|
36
|
+
resourceId?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Generic error response from server
|
|
40
|
+
*/
|
|
41
|
+
interface GenericErrorResponse extends BaseErrorResponse {
|
|
42
|
+
error: string;
|
|
43
|
+
statusCode: number;
|
|
44
|
+
code?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Union of all error response types from server
|
|
48
|
+
*/
|
|
49
|
+
export type ErrorResponse = ValidationErrorResponse | NotFoundErrorResponse | GenericErrorResponse;
|
|
50
|
+
/**
|
|
51
|
+
* Base error class for all client errors
|
|
52
|
+
*
|
|
53
|
+
* Represents an error that occurred during an API request, including
|
|
54
|
+
* both network errors and server-returned error responses.
|
|
55
|
+
*/
|
|
56
|
+
export declare class VeloxClientError extends Error implements ClientError {
|
|
57
|
+
readonly statusCode?: number;
|
|
58
|
+
readonly code?: string;
|
|
59
|
+
readonly body?: unknown;
|
|
60
|
+
readonly url: string;
|
|
61
|
+
readonly method: string;
|
|
62
|
+
constructor(message: string, options: {
|
|
63
|
+
statusCode?: number;
|
|
64
|
+
code?: string;
|
|
65
|
+
body?: unknown;
|
|
66
|
+
url: string;
|
|
67
|
+
method: string;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Network error when request fails to reach server
|
|
72
|
+
*
|
|
73
|
+
* Thrown when the request cannot be completed due to network issues,
|
|
74
|
+
* CORS problems, or other transport-level failures.
|
|
75
|
+
*/
|
|
76
|
+
export declare class NetworkError extends VeloxClientError {
|
|
77
|
+
readonly cause?: Error;
|
|
78
|
+
constructor(message: string, options: {
|
|
79
|
+
url: string;
|
|
80
|
+
method: string;
|
|
81
|
+
cause?: Error;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Validation error from server (400 status)
|
|
86
|
+
*
|
|
87
|
+
* Thrown when request data fails server-side validation.
|
|
88
|
+
* Includes field-level error details if provided by server.
|
|
89
|
+
*/
|
|
90
|
+
export declare class ClientValidationError extends VeloxClientError {
|
|
91
|
+
readonly fields?: Record<string, string>;
|
|
92
|
+
constructor(message: string, options: {
|
|
93
|
+
url: string;
|
|
94
|
+
method: string;
|
|
95
|
+
fields?: Record<string, string>;
|
|
96
|
+
body?: unknown;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Not found error from server (404 status)
|
|
101
|
+
*
|
|
102
|
+
* Thrown when a requested resource doesn't exist.
|
|
103
|
+
*/
|
|
104
|
+
export declare class ClientNotFoundError extends VeloxClientError {
|
|
105
|
+
readonly resource?: string;
|
|
106
|
+
readonly resourceId?: string;
|
|
107
|
+
constructor(message: string, options: {
|
|
108
|
+
url: string;
|
|
109
|
+
method: string;
|
|
110
|
+
resource?: string;
|
|
111
|
+
resourceId?: string;
|
|
112
|
+
body?: unknown;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Server error (5xx status)
|
|
117
|
+
*
|
|
118
|
+
* Thrown when server returns an internal error.
|
|
119
|
+
*/
|
|
120
|
+
export declare class ServerError extends VeloxClientError {
|
|
121
|
+
constructor(message: string, options: {
|
|
122
|
+
statusCode: number;
|
|
123
|
+
code?: string;
|
|
124
|
+
url: string;
|
|
125
|
+
method: string;
|
|
126
|
+
body?: unknown;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Type guard for VeloxClientError
|
|
131
|
+
*/
|
|
132
|
+
export declare function isVeloxClientError(error: unknown): error is VeloxClientError;
|
|
133
|
+
/**
|
|
134
|
+
* Type guard for NetworkError
|
|
135
|
+
*/
|
|
136
|
+
export declare function isNetworkError(error: unknown): error is NetworkError;
|
|
137
|
+
/**
|
|
138
|
+
* Type guard for ClientValidationError
|
|
139
|
+
*/
|
|
140
|
+
export declare function isClientValidationError(error: unknown): error is ClientValidationError;
|
|
141
|
+
/**
|
|
142
|
+
* Type guard for ClientNotFoundError
|
|
143
|
+
*/
|
|
144
|
+
export declare function isClientNotFoundError(error: unknown): error is ClientNotFoundError;
|
|
145
|
+
/**
|
|
146
|
+
* Type guard for ServerError
|
|
147
|
+
*/
|
|
148
|
+
export declare function isServerError(error: unknown): error is ServerError;
|
|
149
|
+
/**
|
|
150
|
+
* Type guard for validation error response
|
|
151
|
+
*/
|
|
152
|
+
export declare function isValidationErrorResponse(response: ErrorResponse): response is ValidationErrorResponse;
|
|
153
|
+
/**
|
|
154
|
+
* Type guard for not found error response
|
|
155
|
+
*/
|
|
156
|
+
export declare function isNotFoundErrorResponse(response: ErrorResponse): response is NotFoundErrorResponse;
|
|
157
|
+
/**
|
|
158
|
+
* Parses an error response from the server and creates appropriate error instance
|
|
159
|
+
*
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
export declare function parseErrorResponse(response: Response, body: unknown, url: string, method: string): VeloxClientError;
|
|
163
|
+
export {};
|
|
164
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|