@hashrytech/quick-components-kit 0.14.3 → 0.15.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @hashrytech/quick-components-kit
2
2
 
3
+ ## 0.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - refactor: Renaming ApiClient to FetchClient
8
+
3
9
  ## 0.14.3
4
10
 
5
11
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ export * from './actions/disable-scroll.js';
12
12
  export * from './actions/on-keydown.js';
13
13
  export * from './actions/lock-scroll.js';
14
14
  export * from './actions/scroll-to.js';
15
- export * from './modules/api-client.js';
15
+ export * from './modules/fetch-client.js';
16
16
  export * from './modules/api-proxy.js';
17
17
  export * from './modules/crypto.js';
18
18
  export * from './modules/problem-details.js';
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ export * from './actions/disable-scroll.js';
14
14
  export * from './actions/on-keydown.js';
15
15
  export * from './actions/lock-scroll.js';
16
16
  export * from './actions/scroll-to.js';
17
- export * from './modules/api-client.js';
17
+ export * from './modules/fetch-client.js';
18
18
  export * from './modules/api-proxy.js';
19
19
  export * from './modules/crypto.js';
20
20
  export * from './modules/problem-details.js';
@@ -15,19 +15,21 @@ export interface AutoRedirectRule {
15
15
  errorValue?: string;
16
16
  redirectTo: string;
17
17
  }
18
- export type ApiResponse<T> = {
18
+ export type FetchResponse<T> = {
19
19
  ok: boolean;
20
20
  status: number;
21
21
  data?: T;
22
22
  error?: ProblemDetail;
23
23
  };
24
- export interface ApiClientConfig {
24
+ export interface FetchClientConfig {
25
25
  /** The base URL for your API (e.g., 'https://api.yourapi.com/v1'). */
26
26
  baseURL: string;
27
27
  /** Default headers to be sent with every request. */
28
28
  defaultHeaders?: HeadersInit;
29
29
  /** Specified redirects if the response matches the specified rules. */
30
30
  autoRedirects?: AutoRedirectRule[];
31
+ /** Optional flag to enable debug logging */
32
+ debug?: boolean;
31
33
  }
32
34
  export interface RequestOptions extends RequestInit {
33
35
  /** If true, the Authorization header will not be added to this request. */
@@ -55,12 +57,12 @@ export type ErrorHandler = (error: Error) => Promise<void> | void;
55
57
  * Custom error class for API responses.
56
58
  * Provides access to the HTTP status code.
57
59
  */
58
- export declare class ApiError extends Error {
60
+ export declare class FetchError extends Error {
59
61
  status: number;
60
62
  json?: object;
61
63
  constructor(message: string, status: number, json?: object);
62
64
  }
63
- export interface ApiClientEvents {
65
+ export interface FetchClientEvents {
64
66
  onRequest?: (request: Request) => void;
65
67
  onResponse?: (response: Response) => void;
66
68
  onError?: (error: Error) => void;
@@ -78,8 +80,9 @@ export interface ApiClientEvents {
78
80
  * - Supports file downloads (returns Blob).
79
81
  * - Integrates with SvelteKit's `fetch` for server-side benefits.
80
82
  */
81
- export declare class ApiClient {
83
+ export declare class FetchClient {
82
84
  private baseURL;
85
+ private debug;
83
86
  private defaultHeaders;
84
87
  private accessToken;
85
88
  private fetchInstance?;
@@ -92,8 +95,8 @@ export declare class ApiClient {
92
95
  * Creates an instance of ApiClient.
93
96
  * @param config - Configuration for the API client.
94
97
  */
95
- constructor(config: ApiClientConfig & {
96
- events?: ApiClientEvents;
98
+ constructor(config: FetchClientConfig & {
99
+ events?: FetchClientEvents;
97
100
  });
98
101
  /**
99
102
  * Sets the Bearer token for client-side requests.
@@ -122,7 +125,7 @@ export declare class ApiClient {
122
125
  * @param handler - A function that takes an `Error` object.
123
126
  */
124
127
  addErrorHandler(handler: ErrorHandler): void;
125
- setEventHooks(events: Partial<ApiClientEvents>): void;
128
+ setEventHooks(events: Partial<FetchClientEvents>): void;
126
129
  /**
127
130
  * Processes the request, applying default headers, auth token, and request interceptors.
128
131
  * @param endpoint - The API endpoint (e.g., '/products', '/users/123').
@@ -155,7 +158,7 @@ export declare class ApiClient {
155
158
  * @returns A Promise resolving to the parsed response data or raw Response/Blob.
156
159
  * @template T - Expected type of the response data.
157
160
  */
158
- request<T>(endpoint: string, method: string, body: BodyInit | object | null | undefined, options?: RequestOptions): Promise<ApiResponse<T>>;
161
+ request<T>(endpoint: string, method: string, body: BodyInit | object | null | undefined, options?: RequestOptions): Promise<FetchResponse<T>>;
159
162
  private evaluateRedirect;
160
163
  /**
161
164
  * Sends a GET request to the specified API endpoint.
@@ -165,7 +168,7 @@ export declare class ApiClient {
165
168
  * @returns A Promise resolving to the parsed response or raw Response object.
166
169
  * @template T - Expected shape of the JSON response.
167
170
  */
168
- get<T>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>>;
171
+ get<T>(endpoint: string, options?: RequestOptions): Promise<FetchResponse<T>>;
169
172
  /**
170
173
  * Sends a POST request to the specified API endpoint.
171
174
  *
@@ -175,7 +178,7 @@ export declare class ApiClient {
175
178
  * @returns A Promise resolving to the parsed response or raw Response object.
176
179
  * @template T - Expected shape of the JSON response.
177
180
  */
178
- post<T>(endpoint: string, data?: BodyInit | object | null, options?: RequestOptions): Promise<ApiResponse<T>>;
181
+ post<T>(endpoint: string, data?: BodyInit | object | null, options?: RequestOptions): Promise<FetchResponse<T>>;
179
182
  /**
180
183
  * Sends a PUT request to the specified API endpoint.
181
184
  * Typically used for full resource replacement.
@@ -186,7 +189,7 @@ export declare class ApiClient {
186
189
  * @returns A Promise resolving to the parsed response or raw Response object.
187
190
  * @template T - Expected shape of the JSON response.
188
191
  */
189
- put<T>(endpoint: string, data?: BodyInit | object | null, options?: RequestOptions): Promise<ApiResponse<T>>;
192
+ put<T>(endpoint: string, data?: BodyInit | object | null, options?: RequestOptions): Promise<FetchResponse<T>>;
190
193
  /**
191
194
  * Sends a PATCH request to the specified API endpoint.
192
195
  * Typically used for partial updates.
@@ -197,7 +200,7 @@ export declare class ApiClient {
197
200
  * @returns A Promise resolving to the parsed response or raw Response object.
198
201
  * @template T - Expected shape of the JSON response.
199
202
  */
200
- patch<T>(endpoint: string, data?: BodyInit | object | null, options?: RequestOptions): Promise<ApiResponse<T>>;
203
+ patch<T>(endpoint: string, data?: BodyInit | object | null, options?: RequestOptions): Promise<FetchResponse<T>>;
201
204
  /**
202
205
  * Sends a DELETE request to the specified API endpoint.
203
206
  *
@@ -206,7 +209,7 @@ export declare class ApiClient {
206
209
  * @returns A Promise resolving to the parsed response or raw Response object.
207
210
  * @template T - Expected shape of the JSON response (if any).
208
211
  */
209
- delete<T>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>>;
212
+ delete<T>(endpoint: string, options?: RequestOptions): Promise<FetchResponse<T>>;
210
213
  /**
211
214
  * Handles file uploads.
212
215
  * @param endpoint - The API endpoint for file upload.
@@ -216,7 +219,7 @@ export declare class ApiClient {
216
219
  * @returns A Promise resolving to the parsed response data.
217
220
  * @template T - Expected type of the response data after upload.
218
221
  */
219
- uploadFile<T>(endpoint: string, file: File | Blob | FormData, fieldName?: string, options?: RequestOptions): Promise<ApiResponse<T>>;
222
+ uploadFile<T>(endpoint: string, file: File | Blob | FormData, fieldName?: string, options?: RequestOptions): Promise<FetchResponse<T>>;
220
223
  /**
221
224
  * Handles file downloads.
222
225
  * @param endpoint - The API endpoint for file download.
@@ -6,12 +6,12 @@ import { browser } from "$app/environment";
6
6
  * Custom error class for API responses.
7
7
  * Provides access to the HTTP status code.
8
8
  */
9
- export class ApiError extends Error {
9
+ export class FetchError extends Error {
10
10
  status;
11
11
  json;
12
12
  constructor(message, status, json) {
13
13
  super(message);
14
- this.name = 'ApiError';
14
+ this.name = 'FetchError';
15
15
  this.status = status;
16
16
  this.json = json;
17
17
  }
@@ -29,8 +29,9 @@ export class ApiError extends Error {
29
29
  * - Supports file downloads (returns Blob).
30
30
  * - Integrates with SvelteKit's `fetch` for server-side benefits.
31
31
  */
32
- export class ApiClient {
32
+ export class FetchClient {
33
33
  baseURL;
34
+ debug = false;
34
35
  defaultHeaders;
35
36
  accessToken;
36
37
  fetchInstance;
@@ -47,6 +48,7 @@ export class ApiClient {
47
48
  this.baseURL = config.baseURL;
48
49
  this.defaultHeaders = config.defaultHeaders || { 'Content-Type': 'application/json' };
49
50
  this.autoRedirects = config.autoRedirects || [];
51
+ this.debug = config.debug || false;
50
52
  }
51
53
  /**
52
54
  * Sets the Bearer token for client-side requests.
@@ -98,6 +100,8 @@ export class ApiClient {
98
100
  */
99
101
  async processRequest(endpoint, method, body, options) {
100
102
  const url = this.baseURL ? new URL(endpoint, this.baseURL).toString() : endpoint; // Resolve endpoint relative to baseURL
103
+ if (this.debug)
104
+ console.debug(`Fetch Client: Processing request to ${url} with method ${method}`);
101
105
  const requestHeaders = new Headers(this.defaultHeaders);
102
106
  // Merge custom headers from options using Headers constructor for robustness
103
107
  if (options.headers) {
@@ -172,7 +176,7 @@ export class ApiClient {
172
176
  // If response is not JSON, use default status text or log parsing error
173
177
  console.warn('API Client: Failed to parse error response as JSON.', e);
174
178
  }
175
- throw new ApiError(errorMessage, response.status, errorJson);
179
+ throw new FetchError(errorMessage, response.status, errorJson);
176
180
  }
177
181
  switch (options.responseType) {
178
182
  case 'text':
@@ -224,6 +228,8 @@ export class ApiClient {
224
228
  * @template T - Expected type of the response data.
225
229
  */
226
230
  async request(endpoint, method, body, options = {}) {
231
+ if (this.debug)
232
+ console.debug(`Fetch Client: ${options.fetchInstance || this.fetchInstance ? "Using sveltekit fetch instance..." : "Using default fetch instance"}`);
227
233
  const currentFetch = options.fetchInstance || this.fetchInstance || fetch; // Use provided fetch first then the class instance fetch or the global fetch if not specified.
228
234
  try {
229
235
  const request = await this.processRequest(endpoint, method, body, options);
@@ -236,8 +242,10 @@ export class ApiClient {
236
242
  };
237
243
  }
238
244
  catch (error) {
245
+ if (this.debug)
246
+ console.debug(`Fetch Client: Error occurred while processing request to ${endpoint} with method ${method}`, error);
239
247
  await this.handleError(error);
240
- const isApiError = error instanceof ApiError;
248
+ const isApiError = error instanceof FetchError;
241
249
  const status = isApiError ? error.status : 503; // Service Unavailable fallback
242
250
  const message = error instanceof Error ? error.message : 'Unexpected error occurred';
243
251
  const errorObj = isApiError && error.json ? error.json : getProblemDetail({ status, title: "Server fetch error", type: "/exceptions/fetch-error/", detail: message });
@@ -254,6 +262,8 @@ export class ApiClient {
254
262
  for (const rule of this.autoRedirects) {
255
263
  // Checks if the error matches the redirect rule value can be undefined to match if no value is specified.
256
264
  if (status === rule.status && rule.errorKey in errorObj && (rule.errorValue === undefined || errorObj[rule.errorKey] === rule.errorValue)) {
265
+ if (this.debug)
266
+ console.debug(`Fetch Client: Redirecting to ${rule.redirectTo} for status ${status} with error key "${rule.errorKey}" and value "${rule.errorValue}"`);
257
267
  if (browser) {
258
268
  // Client-side redirect
259
269
  import('$app/navigation').then(({ goto }) => {
@@ -435,7 +445,7 @@ export class ApiClient {
435
445
  }
436
446
  }
437
447
  else {
438
- reject(new ApiError(xhr.statusText, xhr.status));
448
+ reject(new FetchError(xhr.statusText, xhr.status));
439
449
  }
440
450
  };
441
451
  xhr.onerror = () => reject(new Error('Upload failed'));
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/hashrytech/quick-components-kit.git"
7
7
  },
8
- "version": "0.14.3",
8
+ "version": "0.15.0",
9
9
  "license": "MIT",
10
10
  "author": "Hashry Tech",
11
11
  "files": [