@hashrytech/quick-components-kit 0.13.4 → 0.14.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,19 @@
|
|
|
1
1
|
# @hashrytech/quick-components-kit
|
|
2
2
|
|
|
3
|
+
## 0.14.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- refactor: Changing the setAuthToken method to setAccessToken and removing the getAccessToken method
|
|
8
|
+
|
|
9
|
+
## 0.13.5
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- refactor: setting placeholder text size to text-base default
|
|
14
|
+
- refactor: set text size for lg TextInput to text-base
|
|
15
|
+
- patch: adding evaluation of redirect rule to apiclient
|
|
16
|
+
|
|
3
17
|
## 0.13.4
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
let sizeStyle: Record<TextInputSize, string> = {
|
|
64
64
|
sm: "h-[2.05rem] text-sm placeholder:text-sm",
|
|
65
65
|
md: "h-[2.375rem] text-sm placeholder:text-sm",
|
|
66
|
-
lg: "h-[2.8rem] text-
|
|
66
|
+
lg: "h-[2.8rem] text-base placeholder:text-base"
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
</script>
|
|
@@ -9,6 +9,12 @@ import { type ProblemDetail } from "./problem-details.js";
|
|
|
9
9
|
* and API routes) to automatically benefit from its enhancements (e.g., cookie forwarding,
|
|
10
10
|
* built-in request/response interception via SvelteKit's `handleFetch` hook).
|
|
11
11
|
*/
|
|
12
|
+
export interface AutoRedirectRule {
|
|
13
|
+
status: number;
|
|
14
|
+
errorKey: string;
|
|
15
|
+
errorValue?: string;
|
|
16
|
+
redirectTo: string;
|
|
17
|
+
}
|
|
12
18
|
export type ApiResponse<T> = {
|
|
13
19
|
ok: boolean;
|
|
14
20
|
status: number;
|
|
@@ -20,12 +26,8 @@ export interface ApiClientConfig {
|
|
|
20
26
|
baseURL: string;
|
|
21
27
|
/** Default headers to be sent with every request. */
|
|
22
28
|
defaultHeaders?: HeadersInit;
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
* For server-side operations using SvelteKit's `fetch`, the token is typically
|
|
26
|
-
* handled by `src/hooks.server.ts` via `handleFetch`.
|
|
27
|
-
*/
|
|
28
|
-
getAccessToken?: () => string | undefined;
|
|
29
|
+
/** Specified redirects if the response matches the specified rules. */
|
|
30
|
+
autoRedirects?: AutoRedirectRule[];
|
|
29
31
|
}
|
|
30
32
|
export interface RequestOptions extends RequestInit {
|
|
31
33
|
/** If true, the Authorization header will not be added to this request. */
|
|
@@ -79,9 +81,9 @@ export interface ApiClientEvents {
|
|
|
79
81
|
export declare class ApiClient {
|
|
80
82
|
private baseURL;
|
|
81
83
|
private defaultHeaders;
|
|
82
|
-
private
|
|
83
|
-
private getAccessTokenFromStore;
|
|
84
|
+
private accessToken;
|
|
84
85
|
private fetchInstance?;
|
|
86
|
+
private autoRedirects;
|
|
85
87
|
private requestInterceptors;
|
|
86
88
|
private responseInterceptors;
|
|
87
89
|
private errorHandlers;
|
|
@@ -95,10 +97,9 @@ export declare class ApiClient {
|
|
|
95
97
|
});
|
|
96
98
|
/**
|
|
97
99
|
* Sets the Bearer token for client-side requests.
|
|
98
|
-
* This will override `getAccessToken` for subsequent requests using this client instance.
|
|
99
100
|
* @param token - The access token string, or undefined to clear it.
|
|
100
101
|
*/
|
|
101
|
-
|
|
102
|
+
setAccessToken(token: string | undefined): void;
|
|
102
103
|
/**
|
|
103
104
|
* Sets a custom fetch implementation globally for all requests made by this client.
|
|
104
105
|
* Useful for passing enhanced `fetch` from SvelteKit's load functions.
|
|
@@ -155,6 +156,7 @@ export declare class ApiClient {
|
|
|
155
156
|
* @template T - Expected type of the response data.
|
|
156
157
|
*/
|
|
157
158
|
request<T>(endpoint: string, method: string, body: BodyInit | object | null | undefined, options?: RequestOptions): Promise<ApiResponse<T>>;
|
|
159
|
+
private evaluateRedirect;
|
|
158
160
|
/**
|
|
159
161
|
* Sends a GET request to the specified API endpoint.
|
|
160
162
|
*
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// src/lib/api/client.ts
|
|
2
|
+
import { redirect } from "@sveltejs/kit";
|
|
2
3
|
import { getProblemDetail } from "./problem-details.js";
|
|
4
|
+
import { browser } from "$app/environment";
|
|
3
5
|
/**
|
|
4
6
|
* Custom error class for API responses.
|
|
5
7
|
* Provides access to the HTTP status code.
|
|
@@ -30,11 +32,9 @@ export class ApiError extends Error {
|
|
|
30
32
|
export class ApiClient {
|
|
31
33
|
baseURL;
|
|
32
34
|
defaultHeaders;
|
|
33
|
-
|
|
34
|
-
// otherwise relies on getAccessTokenFromStore or SvelteKit's `handleFetch`.
|
|
35
|
-
clientAuthToken;
|
|
36
|
-
getAccessTokenFromStore;
|
|
35
|
+
accessToken;
|
|
37
36
|
fetchInstance;
|
|
37
|
+
autoRedirects = [];
|
|
38
38
|
requestInterceptors = [];
|
|
39
39
|
responseInterceptors = [];
|
|
40
40
|
errorHandlers = [];
|
|
@@ -46,15 +46,14 @@ export class ApiClient {
|
|
|
46
46
|
constructor(config) {
|
|
47
47
|
this.baseURL = config.baseURL;
|
|
48
48
|
this.defaultHeaders = config.defaultHeaders || { 'Content-Type': 'application/json' };
|
|
49
|
-
this.
|
|
49
|
+
this.autoRedirects = config.autoRedirects || [];
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
52
|
* Sets the Bearer token for client-side requests.
|
|
53
|
-
* This will override `getAccessToken` for subsequent requests using this client instance.
|
|
54
53
|
* @param token - The access token string, or undefined to clear it.
|
|
55
54
|
*/
|
|
56
|
-
|
|
57
|
-
this.
|
|
55
|
+
setAccessToken(token) {
|
|
56
|
+
this.accessToken = token;
|
|
58
57
|
}
|
|
59
58
|
/**
|
|
60
59
|
* Sets a custom fetch implementation globally for all requests made by this client.
|
|
@@ -109,12 +108,8 @@ export class ApiClient {
|
|
|
109
108
|
}
|
|
110
109
|
}
|
|
111
110
|
// Add auth token unless skipped
|
|
112
|
-
if (!options.skipAuth) {
|
|
113
|
-
|
|
114
|
-
const token = this.clientAuthToken || (this.getAccessTokenFromStore ? this.getAccessTokenFromStore() : undefined);
|
|
115
|
-
if (token) {
|
|
116
|
-
requestHeaders.set('Authorization', `Bearer ${token}`);
|
|
117
|
-
}
|
|
111
|
+
if (!options.skipAuth && this.accessToken) {
|
|
112
|
+
requestHeaders.set('Authorization', `Bearer ${this.accessToken}`);
|
|
118
113
|
}
|
|
119
114
|
let processedBody = undefined;
|
|
120
115
|
if (body instanceof FormData) {
|
|
@@ -247,6 +242,7 @@ export class ApiClient {
|
|
|
247
242
|
const message = error instanceof Error ? error.message : 'Unexpected error occurred';
|
|
248
243
|
const errorObj = isApiError && error.json ? error.json : getProblemDetail({ status, title: "Server fetch error", type: "/exceptions/fetch-error/", detail: message });
|
|
249
244
|
//const errorObj = status != 503 ? message : getProblemDetail({status, title: "Server fetch error", type: "/exceptions/fetch-error/", detail: "Error fetching data from API", server: message });
|
|
245
|
+
this.evaluateRedirect(errorObj, status);
|
|
250
246
|
return {
|
|
251
247
|
ok: false,
|
|
252
248
|
status,
|
|
@@ -254,6 +250,24 @@ export class ApiClient {
|
|
|
254
250
|
};
|
|
255
251
|
}
|
|
256
252
|
}
|
|
253
|
+
evaluateRedirect(errorObj, status) {
|
|
254
|
+
for (const rule of this.autoRedirects) {
|
|
255
|
+
// Checks if the error matches the redirect rule value can be undefined to match if no value is specified.
|
|
256
|
+
if (status === rule.status && rule.errorKey in errorObj && (rule.errorValue === undefined || errorObj[rule.errorKey] === rule.errorValue)) {
|
|
257
|
+
if (browser) {
|
|
258
|
+
// Client-side redirect
|
|
259
|
+
import('$app/navigation').then(({ goto }) => {
|
|
260
|
+
goto(rule.redirectTo, { replaceState: true });
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
// Server-side redirect
|
|
265
|
+
throw redirect(303, rule.redirectTo);
|
|
266
|
+
}
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
257
271
|
// --- HTTP Method Shorthands ---
|
|
258
272
|
/**
|
|
259
273
|
* Sends a GET request to the specified API endpoint.
|
|
@@ -377,7 +391,7 @@ export class ApiClient {
|
|
|
377
391
|
const url = new URL(endpoint, this.baseURL).toString();
|
|
378
392
|
const formData = new FormData();
|
|
379
393
|
formData.append(fieldName, file);
|
|
380
|
-
const token = this.
|
|
394
|
+
const token = this.accessToken;
|
|
381
395
|
const headers = new Headers(this.defaultHeaders);
|
|
382
396
|
// Merge user-supplied headers
|
|
383
397
|
if (options.headers) {
|