@hashrytech/quick-components-kit 0.19.11 → 0.19.13

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,17 @@
1
1
  # @hashrytech/quick-components-kit
2
2
 
3
+ ## 0.19.13
4
+
5
+ ### Patch Changes
6
+
7
+ - fix: Fixing problem details return
8
+
9
+ ## 0.19.12
10
+
11
+ ### Patch Changes
12
+
13
+ - fix: Adjusting 2 error handlers so that 1 returns problem details and the other returns the default error
14
+
3
15
  ## 0.19.11
4
16
 
5
17
  ### Patch Changes
@@ -65,7 +65,7 @@ export declare class FetchError extends Error {
65
65
  export interface FetchClientEvents {
66
66
  onRequest?: (request: Request) => Promise<void> | void;
67
67
  onResponse?: (response: Response) => Promise<void> | void;
68
- onError?: (error: Error) => Promise<void> | void;
68
+ onError?: (error: ProblemDetail) => Promise<void> | void;
69
69
  }
70
70
  /**
71
71
  * A generic REST API client.
@@ -1,6 +1,6 @@
1
1
  // src/lib/api/client.ts
2
2
  import { redirect } from "@sveltejs/kit";
3
- import { getProblemDetail } from "./problem-details.js";
3
+ import { getProblemDetail, isProblemDetail } from "./problem-details.js";
4
4
  import { browser } from "$app/environment";
5
5
  /**
6
6
  * Custom error class for API responses.
@@ -279,20 +279,17 @@ export class FetchClient {
279
279
  catch (error) {
280
280
  if (this.debug)
281
281
  console.debug(`Fetch Client: Error occurred while processing request to ${endpoint} with method ${method}`, error);
282
- const err = error instanceof Error ? error : new Error(String(error));
283
- await this.emit('onError', err);
284
- //this.events.onError?.(err);
282
+ await this.handleError(error);
285
283
  const isApiError = error instanceof FetchError;
286
284
  const status = isApiError ? error.status : 503; // Service Unavailable fallback
287
285
  const message = error instanceof Error ? error.message : 'Unexpected error occurred';
288
- const errorObj = isApiError && error.json ? error.json : getProblemDetail({ status, title: "Server fetch error", type: "/exceptions/fetch-error/", detail: message });
289
- await this.handleError(errorObj);
290
- //const errorObj = status != 503 ? message : getProblemDetail({status, title: "Server fetch error", type: "/exceptions/fetch-error/", detail: "Error fetching data from API", server: message });
291
- this.evaluateRedirect(errorObj, status);
286
+ const problemError = isApiError && error.json && isProblemDetail(error.json) ? error.json : getProblemDetail({ status, title: "Server fetch error", type: "/exceptions/fetch-error/", detail: message });
287
+ await this.emit('onError', problemError);
288
+ this.evaluateRedirect(problemError, status);
292
289
  return {
293
290
  ok: false,
294
291
  status,
295
- error: errorObj
292
+ error: problemError
296
293
  };
297
294
  }
298
295
  }
@@ -60,3 +60,22 @@ export declare function getProblemDetail(input: {
60
60
  type?: string;
61
61
  [key: string]: string | number | undefined;
62
62
  }): ProblemDetail;
63
+ /**
64
+ * Type guard for RFC 7807 "Problem Details" objects.
65
+ *
66
+ * Why:
67
+ * - Network errors and server responses can be `unknown` at the callsite.
68
+ * - This guard lets TypeScript safely narrow `unknown` to `ProblemDetail`
69
+ * so you can access `title`, `status`, etc. without extra checks.
70
+ *
71
+ * Contract (RFC 7807):
72
+ * - `title`: human-readable summary (required string)
73
+ * - `status`: HTTP status code (required number)
74
+ * - `type`, `detail`, `instance`: optional strings
75
+ * - Implementations may include arbitrary extension members (we allow them).
76
+ *
77
+ * Note:
78
+ * - Some backends serialize `status` as a string. If that happens in your stack,
79
+ * consider accepting `"number-like"` values or coercing before validation.
80
+ */
81
+ export declare function isProblemDetail(v: unknown): v is ProblemDetail;
@@ -78,3 +78,36 @@ export function getProblemDetail(input) {
78
78
  }
79
79
  return problem;
80
80
  }
81
+ /**
82
+ * Type guard for RFC 7807 "Problem Details" objects.
83
+ *
84
+ * Why:
85
+ * - Network errors and server responses can be `unknown` at the callsite.
86
+ * - This guard lets TypeScript safely narrow `unknown` to `ProblemDetail`
87
+ * so you can access `title`, `status`, etc. without extra checks.
88
+ *
89
+ * Contract (RFC 7807):
90
+ * - `title`: human-readable summary (required string)
91
+ * - `status`: HTTP status code (required number)
92
+ * - `type`, `detail`, `instance`: optional strings
93
+ * - Implementations may include arbitrary extension members (we allow them).
94
+ *
95
+ * Note:
96
+ * - Some backends serialize `status` as a string. If that happens in your stack,
97
+ * consider accepting `"number-like"` values or coercing before validation.
98
+ */
99
+ export function isProblemDetail(v) {
100
+ // Must be a non-null object
101
+ if (!v || typeof v !== 'object')
102
+ return false;
103
+ // Treat as a generic dictionary to inspect fields at runtime
104
+ const o = v;
105
+ // Required members with exact types
106
+ const hasTitle = typeof o.title === 'string';
107
+ const hasStatus = typeof o.status === 'number';
108
+ // Optional RFC 7807 members (if present, must be strings)
109
+ const typeOk = o.type === undefined || typeof o.type === 'string';
110
+ const detailOk = o.detail === undefined || typeof o.detail === 'string';
111
+ const instanceOk = o.instance === undefined || typeof o.instance === 'string';
112
+ return hasTitle && hasStatus && typeOk && detailOk && instanceOk;
113
+ }
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.19.11",
8
+ "version": "0.19.13",
9
9
  "license": "MIT",
10
10
  "author": "Hashry Tech",
11
11
  "files": [