@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/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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"}
@@ -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"}
@@ -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
+ }