@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/errors.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
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
|
+
// ============================================================================
|
|
10
|
+
// Client Error Classes
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Base error class for all client errors
|
|
14
|
+
*
|
|
15
|
+
* Represents an error that occurred during an API request, including
|
|
16
|
+
* both network errors and server-returned error responses.
|
|
17
|
+
*/
|
|
18
|
+
export class VeloxClientError extends Error {
|
|
19
|
+
statusCode;
|
|
20
|
+
code;
|
|
21
|
+
body;
|
|
22
|
+
url;
|
|
23
|
+
method;
|
|
24
|
+
constructor(message, options) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = 'VeloxClientError';
|
|
27
|
+
this.statusCode = options.statusCode;
|
|
28
|
+
this.code = options.code;
|
|
29
|
+
this.body = options.body;
|
|
30
|
+
this.url = options.url;
|
|
31
|
+
this.method = options.method;
|
|
32
|
+
// Maintains proper stack trace for where error was thrown (V8 only)
|
|
33
|
+
if (Error.captureStackTrace) {
|
|
34
|
+
Error.captureStackTrace(this, VeloxClientError);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Network error when request fails to reach server
|
|
40
|
+
*
|
|
41
|
+
* Thrown when the request cannot be completed due to network issues,
|
|
42
|
+
* CORS problems, or other transport-level failures.
|
|
43
|
+
*/
|
|
44
|
+
export class NetworkError extends VeloxClientError {
|
|
45
|
+
cause;
|
|
46
|
+
constructor(message, options) {
|
|
47
|
+
super(message, {
|
|
48
|
+
url: options.url,
|
|
49
|
+
method: options.method,
|
|
50
|
+
});
|
|
51
|
+
this.name = 'NetworkError';
|
|
52
|
+
this.cause = options.cause;
|
|
53
|
+
if (Error.captureStackTrace) {
|
|
54
|
+
Error.captureStackTrace(this, NetworkError);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Validation error from server (400 status)
|
|
60
|
+
*
|
|
61
|
+
* Thrown when request data fails server-side validation.
|
|
62
|
+
* Includes field-level error details if provided by server.
|
|
63
|
+
*/
|
|
64
|
+
export class ClientValidationError extends VeloxClientError {
|
|
65
|
+
fields;
|
|
66
|
+
constructor(message, options) {
|
|
67
|
+
super(message, {
|
|
68
|
+
statusCode: 400,
|
|
69
|
+
code: 'VALIDATION_ERROR',
|
|
70
|
+
url: options.url,
|
|
71
|
+
method: options.method,
|
|
72
|
+
body: options.body,
|
|
73
|
+
});
|
|
74
|
+
this.name = 'ClientValidationError';
|
|
75
|
+
this.fields = options.fields;
|
|
76
|
+
if (Error.captureStackTrace) {
|
|
77
|
+
Error.captureStackTrace(this, ClientValidationError);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Not found error from server (404 status)
|
|
83
|
+
*
|
|
84
|
+
* Thrown when a requested resource doesn't exist.
|
|
85
|
+
*/
|
|
86
|
+
export class ClientNotFoundError extends VeloxClientError {
|
|
87
|
+
resource;
|
|
88
|
+
resourceId;
|
|
89
|
+
constructor(message, options) {
|
|
90
|
+
super(message, {
|
|
91
|
+
statusCode: 404,
|
|
92
|
+
code: 'NOT_FOUND',
|
|
93
|
+
url: options.url,
|
|
94
|
+
method: options.method,
|
|
95
|
+
body: options.body,
|
|
96
|
+
});
|
|
97
|
+
this.name = 'ClientNotFoundError';
|
|
98
|
+
this.resource = options.resource;
|
|
99
|
+
this.resourceId = options.resourceId;
|
|
100
|
+
if (Error.captureStackTrace) {
|
|
101
|
+
Error.captureStackTrace(this, ClientNotFoundError);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Server error (5xx status)
|
|
107
|
+
*
|
|
108
|
+
* Thrown when server returns an internal error.
|
|
109
|
+
*/
|
|
110
|
+
export class ServerError extends VeloxClientError {
|
|
111
|
+
constructor(message, options) {
|
|
112
|
+
super(message, options);
|
|
113
|
+
this.name = 'ServerError';
|
|
114
|
+
if (Error.captureStackTrace) {
|
|
115
|
+
Error.captureStackTrace(this, ServerError);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// ============================================================================
|
|
120
|
+
// Type Guards
|
|
121
|
+
// ============================================================================
|
|
122
|
+
/**
|
|
123
|
+
* Type guard for VeloxClientError
|
|
124
|
+
*/
|
|
125
|
+
export function isVeloxClientError(error) {
|
|
126
|
+
return error instanceof VeloxClientError;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Type guard for NetworkError
|
|
130
|
+
*/
|
|
131
|
+
export function isNetworkError(error) {
|
|
132
|
+
return error instanceof NetworkError;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Type guard for ClientValidationError
|
|
136
|
+
*/
|
|
137
|
+
export function isClientValidationError(error) {
|
|
138
|
+
return error instanceof ClientValidationError;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Type guard for ClientNotFoundError
|
|
142
|
+
*/
|
|
143
|
+
export function isClientNotFoundError(error) {
|
|
144
|
+
return error instanceof ClientNotFoundError;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Type guard for ServerError
|
|
148
|
+
*/
|
|
149
|
+
export function isServerError(error) {
|
|
150
|
+
return error instanceof ServerError;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Type guard for validation error response
|
|
154
|
+
*/
|
|
155
|
+
export function isValidationErrorResponse(response) {
|
|
156
|
+
return response.error === 'ValidationError';
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Type guard for not found error response
|
|
160
|
+
*/
|
|
161
|
+
export function isNotFoundErrorResponse(response) {
|
|
162
|
+
return response.error === 'NotFoundError';
|
|
163
|
+
}
|
|
164
|
+
// ============================================================================
|
|
165
|
+
// Error Parsing
|
|
166
|
+
// ============================================================================
|
|
167
|
+
/**
|
|
168
|
+
* Parses an error response from the server and creates appropriate error instance
|
|
169
|
+
*
|
|
170
|
+
* @internal
|
|
171
|
+
*/
|
|
172
|
+
export function parseErrorResponse(response, body, url, method) {
|
|
173
|
+
// Try to parse as ErrorResponse
|
|
174
|
+
if (isErrorResponseLike(body)) {
|
|
175
|
+
const errorResponse = body;
|
|
176
|
+
// Validation error
|
|
177
|
+
if (isValidationErrorResponse(errorResponse)) {
|
|
178
|
+
return new ClientValidationError(errorResponse.message, {
|
|
179
|
+
url,
|
|
180
|
+
method,
|
|
181
|
+
fields: errorResponse.fields,
|
|
182
|
+
body,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
// Not found error
|
|
186
|
+
if (isNotFoundErrorResponse(errorResponse)) {
|
|
187
|
+
return new ClientNotFoundError(errorResponse.message, {
|
|
188
|
+
url,
|
|
189
|
+
method,
|
|
190
|
+
resource: errorResponse.resource,
|
|
191
|
+
resourceId: errorResponse.resourceId,
|
|
192
|
+
body,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
// Server error (5xx)
|
|
196
|
+
if (response.status >= 500) {
|
|
197
|
+
return new ServerError(errorResponse.message, {
|
|
198
|
+
statusCode: errorResponse.statusCode,
|
|
199
|
+
code: errorResponse.code,
|
|
200
|
+
url,
|
|
201
|
+
method,
|
|
202
|
+
body,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
// Generic error
|
|
206
|
+
return new VeloxClientError(errorResponse.message, {
|
|
207
|
+
statusCode: errorResponse.statusCode,
|
|
208
|
+
code: errorResponse.code,
|
|
209
|
+
url,
|
|
210
|
+
method,
|
|
211
|
+
body,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
// Fallback for non-standard error responses
|
|
215
|
+
const message = typeof body === 'object' &&
|
|
216
|
+
body !== null &&
|
|
217
|
+
'message' in body &&
|
|
218
|
+
typeof body.message === 'string'
|
|
219
|
+
? body.message
|
|
220
|
+
: `Request failed with status ${response.status}`;
|
|
221
|
+
if (response.status >= 500) {
|
|
222
|
+
return new ServerError(message, {
|
|
223
|
+
statusCode: response.status,
|
|
224
|
+
url,
|
|
225
|
+
method,
|
|
226
|
+
body,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return new VeloxClientError(message, {
|
|
230
|
+
statusCode: response.status,
|
|
231
|
+
url,
|
|
232
|
+
method,
|
|
233
|
+
body,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Type guard to check if body looks like an error response
|
|
238
|
+
*
|
|
239
|
+
* @internal
|
|
240
|
+
*/
|
|
241
|
+
function isErrorResponseLike(body) {
|
|
242
|
+
if (typeof body !== 'object' || body === null) {
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
const obj = body;
|
|
246
|
+
return (typeof obj.error === 'string' &&
|
|
247
|
+
typeof obj.message === 'string' &&
|
|
248
|
+
typeof obj.statusCode === 'number');
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @veloxts/client - Type-safe API client for frontend applications
|
|
3
|
+
*
|
|
4
|
+
* Provides a fully typed client for consuming VeloxTS APIs from frontend code.
|
|
5
|
+
* Types are inferred directly from backend procedure definitions without code generation.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // Import procedure types from backend
|
|
10
|
+
* import type { userProcedures } from '../server/procedures';
|
|
11
|
+
*
|
|
12
|
+
* // Create client with full type safety
|
|
13
|
+
* const api = createClient<{ users: typeof userProcedures }>({
|
|
14
|
+
* baseUrl: '/api'
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* // Fully typed API calls
|
|
18
|
+
* const user = await api.users.getUser({ id: '123' });
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @module @veloxts/client
|
|
22
|
+
*/
|
|
23
|
+
export { createClient } from './client.js';
|
|
24
|
+
export type { ClientConfig, ClientError, ClientFromCollection, ClientFromRouter, ClientProcedure, HttpMethod, InferProcedureInput, InferProcedureOutput, ProcedureCall, ProcedureCollection, ProcedureRecord, } from './types.js';
|
|
25
|
+
export { ClientNotFoundError, ClientValidationError, NetworkError, ServerError, VeloxClientError, } from './errors.js';
|
|
26
|
+
export { isClientNotFoundError, isClientValidationError, isNetworkError, isNotFoundErrorResponse, isServerError, isValidationErrorResponse, isVeloxClientError, } from './errors.js';
|
|
27
|
+
export type { ErrorResponse } from './errors.js';
|
|
28
|
+
export declare const CLIENT_VERSION = "0.1.0";
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO3C,YAAY,EACV,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,eAAe,GAChB,MAAM,YAAY,CAAC;AAMpB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,EACZ,WAAW,EACX,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAMrB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,uBAAuB,EACvB,aAAa,EACb,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAMrB,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD,eAAO,MAAM,cAAc,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @veloxts/client - Type-safe API client for frontend applications
|
|
3
|
+
*
|
|
4
|
+
* Provides a fully typed client for consuming VeloxTS APIs from frontend code.
|
|
5
|
+
* Types are inferred directly from backend procedure definitions without code generation.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // Import procedure types from backend
|
|
10
|
+
* import type { userProcedures } from '../server/procedures';
|
|
11
|
+
*
|
|
12
|
+
* // Create client with full type safety
|
|
13
|
+
* const api = createClient<{ users: typeof userProcedures }>({
|
|
14
|
+
* baseUrl: '/api'
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* // Fully typed API calls
|
|
18
|
+
* const user = await api.users.getUser({ id: '123' });
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @module @veloxts/client
|
|
22
|
+
*/
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Core Client
|
|
25
|
+
// ============================================================================
|
|
26
|
+
export { createClient } from './client.js';
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// Error Classes
|
|
29
|
+
// ============================================================================
|
|
30
|
+
export { ClientNotFoundError, ClientValidationError, NetworkError, ServerError, VeloxClientError, } from './errors.js';
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Type Guards
|
|
33
|
+
// ============================================================================
|
|
34
|
+
export { isClientNotFoundError, isClientValidationError, isNetworkError, isNotFoundErrorResponse, isServerError, isValidationErrorResponse, isVeloxClientError, } from './errors.js';
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// Version
|
|
37
|
+
// ============================================================================
|
|
38
|
+
export const CLIENT_VERSION = '0.1.0';
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAqB3C,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,EACZ,WAAW,EACX,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,uBAAuB,EACvB,aAAa,EACb,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAQrB,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type inference utilities for the VeloxTS client
|
|
3
|
+
*
|
|
4
|
+
* Provides type extraction from backend procedure collections to enable
|
|
5
|
+
* full-stack type safety without code generation.
|
|
6
|
+
*
|
|
7
|
+
* @module types
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Procedure operation type (matches @veloxts/router)
|
|
11
|
+
*/
|
|
12
|
+
export type ProcedureType = 'query' | 'mutation';
|
|
13
|
+
/**
|
|
14
|
+
* Minimal interface representing a compiled procedure
|
|
15
|
+
*
|
|
16
|
+
* This interface is designed to be structurally compatible with @veloxts/router's
|
|
17
|
+
* CompiledProcedure type, enabling type inference without requiring a direct
|
|
18
|
+
* package dependency. The client only needs the schema types for inference.
|
|
19
|
+
*
|
|
20
|
+
* @template TInput - The validated input type
|
|
21
|
+
* @template TOutput - The handler output type
|
|
22
|
+
*
|
|
23
|
+
* @see {@link https://github.com/veloxts/velox-ts-framework/velox | @veloxts/router CompiledProcedure}
|
|
24
|
+
*/
|
|
25
|
+
export interface ClientProcedure<TInput = unknown, TOutput = unknown> {
|
|
26
|
+
/** Whether this is a query or mutation */
|
|
27
|
+
readonly type: ProcedureType;
|
|
28
|
+
/** The procedure handler function */
|
|
29
|
+
readonly handler: (args: {
|
|
30
|
+
input: TInput;
|
|
31
|
+
ctx: unknown;
|
|
32
|
+
}) => TOutput | Promise<TOutput>;
|
|
33
|
+
/** Input validation schema (if specified) */
|
|
34
|
+
readonly inputSchema?: {
|
|
35
|
+
parse: (input: unknown) => TInput;
|
|
36
|
+
};
|
|
37
|
+
/** Output validation schema (if specified) */
|
|
38
|
+
readonly outputSchema?: {
|
|
39
|
+
parse: (output: unknown) => TOutput;
|
|
40
|
+
};
|
|
41
|
+
/** Middleware chain (not used by client, but part of CompiledProcedure) */
|
|
42
|
+
readonly middlewares?: ReadonlyArray<unknown>;
|
|
43
|
+
/** REST route override (not used by client, but part of CompiledProcedure) */
|
|
44
|
+
readonly restOverride?: {
|
|
45
|
+
method?: string;
|
|
46
|
+
path?: string;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Record of named procedures
|
|
51
|
+
*
|
|
52
|
+
* NOTE: Uses `any` for variance compatibility with @veloxts/router's ProcedureRecord
|
|
53
|
+
*/
|
|
54
|
+
export type ProcedureRecord = Record<string, ClientProcedure<any, any>>;
|
|
55
|
+
/**
|
|
56
|
+
* Procedure collection with namespace
|
|
57
|
+
*
|
|
58
|
+
* Matches the structure of @veloxts/router's ProcedureCollection
|
|
59
|
+
*/
|
|
60
|
+
export interface ProcedureCollection<TProcedures extends ProcedureRecord = ProcedureRecord> {
|
|
61
|
+
/** Resource namespace (e.g., 'users', 'posts') */
|
|
62
|
+
readonly namespace: string;
|
|
63
|
+
/** Named procedures in this collection */
|
|
64
|
+
readonly procedures: TProcedures;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Extracts the input type from a procedure
|
|
68
|
+
*
|
|
69
|
+
* Works with both ClientProcedure and @veloxts/router's CompiledProcedure
|
|
70
|
+
*/
|
|
71
|
+
export type InferProcedureInput<T> = T extends ClientProcedure<infer I, unknown> ? I : never;
|
|
72
|
+
/**
|
|
73
|
+
* Extracts the output type from a procedure
|
|
74
|
+
*
|
|
75
|
+
* Works with both ClientProcedure and @veloxts/router's CompiledProcedure
|
|
76
|
+
*/
|
|
77
|
+
export type InferProcedureOutput<T> = T extends ClientProcedure<unknown, infer O> ? O : never;
|
|
78
|
+
/**
|
|
79
|
+
* Builds a callable client interface from a single procedure collection
|
|
80
|
+
*
|
|
81
|
+
* For each procedure, creates a method that:
|
|
82
|
+
* - Takes the procedure's input type as parameter
|
|
83
|
+
* - Returns a Promise of the procedure's output type
|
|
84
|
+
*/
|
|
85
|
+
export type ClientFromCollection<TCollection extends ProcedureCollection> = {
|
|
86
|
+
[K in keyof TCollection['procedures']]: (input: InferProcedureInput<TCollection['procedures'][K]>) => Promise<InferProcedureOutput<TCollection['procedures'][K]>>;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Builds a complete client interface from a router (collection of collections)
|
|
90
|
+
*
|
|
91
|
+
* For each collection namespace, creates a property with all callable procedures.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* // Backend defines:
|
|
96
|
+
* const userProcedures = defineProcedures('users', {
|
|
97
|
+
* getUser: procedure().input(...).output(...).query(...),
|
|
98
|
+
* createUser: procedure().input(...).output(...).mutation(...),
|
|
99
|
+
* });
|
|
100
|
+
*
|
|
101
|
+
* // Frontend gets:
|
|
102
|
+
* type Client = ClientFromRouter<{ users: typeof userProcedures }>;
|
|
103
|
+
* // Client = {
|
|
104
|
+
* // users: {
|
|
105
|
+
* // getUser: (input: { id: string }) => Promise<User>;
|
|
106
|
+
* // createUser: (input: CreateUserInput) => Promise<User>;
|
|
107
|
+
* // }
|
|
108
|
+
* // }
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export type ClientFromRouter<TRouter> = {
|
|
112
|
+
[K in keyof TRouter]: TRouter[K] extends ProcedureCollection ? ClientFromCollection<TRouter[K]> : never;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Configuration for creating a client instance
|
|
116
|
+
*/
|
|
117
|
+
export interface ClientConfig {
|
|
118
|
+
/** Base URL for API requests (e.g., 'https://api.example.com' or '/api') */
|
|
119
|
+
baseUrl: string;
|
|
120
|
+
/** Optional custom headers to include in all requests */
|
|
121
|
+
headers?: Record<string, string>;
|
|
122
|
+
/**
|
|
123
|
+
* Optional request interceptor
|
|
124
|
+
* Called before each request is sent
|
|
125
|
+
*/
|
|
126
|
+
onRequest?: (url: string, options: RequestInit) => void | Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Optional response interceptor
|
|
129
|
+
* Called after each successful response
|
|
130
|
+
*/
|
|
131
|
+
onResponse?: (response: Response) => void | Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Optional error interceptor
|
|
134
|
+
* Called when a request fails or returns an error response
|
|
135
|
+
*/
|
|
136
|
+
onError?: (error: ClientError) => void | Promise<void>;
|
|
137
|
+
/**
|
|
138
|
+
* Optional custom fetch implementation
|
|
139
|
+
* Defaults to global fetch
|
|
140
|
+
*/
|
|
141
|
+
fetch?: typeof fetch;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Client error with full context about the failed request
|
|
145
|
+
*/
|
|
146
|
+
export interface ClientError extends Error {
|
|
147
|
+
/** HTTP status code (if available) */
|
|
148
|
+
statusCode?: number;
|
|
149
|
+
/** Error code from server (if available) */
|
|
150
|
+
code?: string;
|
|
151
|
+
/** Original response body (if available) */
|
|
152
|
+
body?: unknown;
|
|
153
|
+
/** URL that was requested */
|
|
154
|
+
url: string;
|
|
155
|
+
/** HTTP method used */
|
|
156
|
+
method: string;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Internal representation of a procedure call
|
|
160
|
+
*/
|
|
161
|
+
export interface ProcedureCall {
|
|
162
|
+
/** Namespace (e.g., 'users') */
|
|
163
|
+
namespace: string;
|
|
164
|
+
/** Procedure name (e.g., 'getUser') */
|
|
165
|
+
procedureName: string;
|
|
166
|
+
/** Input data */
|
|
167
|
+
input: unknown;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* HTTP method inferred from procedure name
|
|
171
|
+
*/
|
|
172
|
+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
173
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type inference utilities for the VeloxTS client
|
|
3
|
+
*
|
|
4
|
+
* Provides type extraction from backend procedure collections to enable
|
|
5
|
+
* full-stack type safety without code generation.
|
|
6
|
+
*
|
|
7
|
+
* @module types
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@veloxts/client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Type-safe frontend API client for VeloxTS framework",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"typescript": "5.9.3",
|
|
21
|
+
"vitest": "4.0.15"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"velox",
|
|
25
|
+
"client",
|
|
26
|
+
"api",
|
|
27
|
+
"fetch",
|
|
28
|
+
"typescript"
|
|
29
|
+
],
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/veloxts/velox-ts-framework",
|
|
34
|
+
"directory": "packages/client"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20.0.0"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc",
|
|
44
|
+
"dev": "tsc --watch",
|
|
45
|
+
"type-check": "tsc --noEmit",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"test:watch": "vitest",
|
|
48
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo"
|
|
49
|
+
}
|
|
50
|
+
}
|