typedapi-client-helpers 0.3.5 → 0.4.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A small Fetch runtime and OpenAPI 3 TypeScript generator designed to work with `TypedApi.Swagger` on ASP.NET Core.
4
4
 
5
- ## Version 0.3.5 highlights
5
+ ## Version 0.4.0 highlights
6
6
 
7
7
  * Supports `[TypedApiFilterForm]` endpoints through the `x-typedapi-filter-form` OpenAPI extension.
8
8
  * Generates grouped filter-form arguments containing normal query values and `FilterFormValues`.
@@ -14,6 +14,8 @@ A small Fetch runtime and OpenAPI 3 TypeScript generator designed to work with `
14
14
  * Consumes readable generic schema IDs such as `ApiPaginationResponseOfProjectModel`.
15
15
  * Generates method-specific unions from typed `ProblemDetails` error responses.
16
16
  * Validates TypedApi OpenAPI contract version 2.
17
+ * Converts HTTP and transport failures into a readable `error: string` for toasts, while preserving the original typed body in `rawError`.
18
+ * Formats ASP.NET Core validation errors, `ProblemDetails`, custom JSON/text errors, and unknown error objects without displaying `[object Object]`.
17
19
 
18
20
  ## Filter-form endpoints
19
21
 
@@ -165,9 +167,9 @@ export type EmailNotificationModel = NotificationModelBase & {
165
167
  };
166
168
  ```
167
169
 
168
- ## Typed errors
170
+ ## Typed error contracts
169
171
 
170
- When the OpenAPI operation contains typed error response bodies, generated methods expose the union directly:
172
+ When an OpenAPI operation documents an error body, the generated method keeps its error type (or union) for `rawError`. `error` is always a human-readable `string`, suitable for a toast:
171
173
 
172
174
  ```ts
173
175
  ApiResult<
@@ -176,10 +178,12 @@ ApiResult<
176
178
  >
177
179
  ```
178
180
 
181
+ On failure, access the original documented payload through `result.rawError`; see [Error handling](#error-handling) for examples.
182
+
179
183
  ## Install
180
184
 
181
185
  ```bash
182
- npm install typedapi-client-helpers@0.3.5
186
+ npm install typedapi-client-helpers@0.4.0
183
187
  ```
184
188
 
185
189
  The generator expects an OpenAPI 3.x document. Swagger 2.0 documents are rejected with a clear error.
@@ -470,40 +474,71 @@ It does not add:
470
474
  * `sortBy`
471
475
  * `sortDirection`
472
476
 
473
- ## Typed errors
474
-
475
- When the OpenAPI document describes error response bodies, generated methods expose their generated type or union.
477
+ ## Error handling
476
478
 
477
- When no error schema is documented, the method uses `ApiHttpError` instead of `unknown`:
479
+ Version 0.4.0 separates **display text** from **structured diagnostics** on every failed request:
478
480
 
479
481
  ```ts
480
- const result = await cancelOrder({
481
- id,
482
- reason,
483
- });
482
+ const result = await cancelOrder({ id, reason });
484
483
 
485
484
  if (!result.ok) {
486
- if (result.error.kind === "http") {
487
- console.error(
488
- result.error.status,
489
- result.error.body,
490
- );
491
- } else {
492
- console.error(result.error);
493
- }
485
+ // Always text: safe to show in a toast, alert, or form message.
486
+ console.error(result.error);
487
+
488
+ // Original error body / transport failure, preserving types and details.
489
+ console.debug(result.rawError);
490
+ console.debug(result.status);
494
491
  }
495
492
  ```
496
493
 
497
- Structured client errors include:
494
+ Use `result.error` (not `result.rawError`) for a toast, e.g. `toast.error(result.error)` if your app uses a toast library. This also applies in `onError` callbacks. Existing success results and `onSuccess` callbacks are unchanged.
498
495
 
499
- * Network errors
500
- * Aborted requests
501
- * Timeout errors
502
- * Malformed response errors
496
+ Typical failure result:
497
+
498
+ ```ts
499
+ {
500
+ ok: false,
501
+ status: 400,
502
+ response: undefined,
503
+ error: "Setting value validation failed:\n• SettingValues[4].IntValue: 'Card transaction count notification threshold' must be between 1 and 100000 (inclusive).",
504
+ rawError: {
505
+ title: "Setting value validation failed",
506
+ status: 400,
507
+ errors: {
508
+ "SettingValues[4].IntValue": [
509
+ "'Card transaction count notification threshold' must be between 1 and 100000 (inclusive).",
510
+ ],
511
+ },
512
+ },
513
+ }
514
+ ```
503
515
 
504
- Malformed JSON is reported as a structured parse error instead of being cast to the expected response type.
516
+ The error message includes **every validation message**, retaining its original field path; the example above is shortened to one field. Messages are deduplicated. Other supported shapes include:
505
517
 
506
- Exceptions thrown by consumer `onSuccess` and `onError` callbacks propagate normally.
518
+ * ASP.NET Core `ValidationProblemDetails` and `HttpValidationProblemDetails`, `ModelState`, and validation arrays.
519
+ * RFC 7807 `ProblemDetails` (`title` and `detail`).
520
+ * JSON with `message`, `error`, `error_description`, or a nested `data` wrapper.
521
+ * Text responses and JSON-encoded strings.
522
+ * Undocumented/unknown JSON objects (formatted JSON rather than `[object Object]`).
523
+ * Empty HTTP error bodies (status-specific messages), binary bodies, network/abort/timeout errors, and malformed JSON.
524
+
525
+ For an HTTP response **without a documented OpenAPI error schema**, generated methods use `ApiHttpError` as the *typed raw error* instead of `unknown`. `result.rawError` can contain `{ kind: "http", status, body }`. Other client-generated raw errors have `kind: "network"`, `"aborted"`, or `"parse"`.
526
+
527
+ You can also format a payload outside the API client:
528
+
529
+ ```ts
530
+ import { formatApiError } from "typedapi-client-helpers";
531
+
532
+ const message = formatApiError(
533
+ { title: "Validation failed", errors: { Email: ["Email is required"] } },
534
+ 400,
535
+ );
536
+ // "Validation failed:\n• Email: Email is required"
537
+ ```
538
+
539
+ `handleApiResponse` supports a caller-provided `fallbackErrorMessage`, used when no usable error text or HTTP status is available. Unknown nonempty responses retain their content instead of being replaced by that fallback.
540
+
541
+ Malformed JSON yields a readable parsing error and preserves its raw response body in `rawError`. Exceptions thrown by consumer `onSuccess` or `onError` callbacks still propagate normally. See [`src/utils/README.md`](src/utils/README.md) and [`src/interfaces/README.md`](src/interfaces/README.md) for the full result shape.
507
542
 
508
543
  ## Runtime configuration
509
544
 
@@ -538,13 +573,14 @@ The runtime also exports:
538
573
  * `toRequestHeaders`
539
574
  * `toCookieHeader`
540
575
  * `handleApiResponse`
576
+ * `formatApiError`
541
577
  * `buildFilterQuery`
542
578
  * `buildQuery`
543
579
  * `toFormData`
544
580
 
545
581
  ## Backend pairing
546
582
 
547
- Use `TypedApi.Swagger` 0.3.2 or newer on the backend for:
583
+ Use `TypedApi.Swagger` 0.3.3 (or a compatible newer release) on the backend for:
548
584
 
549
585
  * `[TypedApiFilterForm]`
550
586
  * Generic reconstruction
@@ -556,3 +592,7 @@ Use `TypedApi.Swagger` 0.3.2 or newer on the backend for:
556
592
  The backend package emits `x-typedapi-filter-form` for opted-in filter endpoints.
557
593
 
558
594
  It also emits `x-typedapi.contractVersion = 2` for contract compatibility. The generator validates the contract version before replacing generated files.
595
+
596
+ ## Tests
597
+
598
+ For the npm package alone, run `npm run verify` from `npm/typed-api-client` to type-check, build, and run **every** `test/*.test.mjs` file. From the repository root, `npm test` runs the npm suite, test client lint/build, .NET tests, and real HTTP integration tests. See [`../../TESTING.md`](../../TESTING.md) for prerequisites and details.
package/dist/cjs/index.js CHANGED
@@ -22,6 +22,7 @@ __exportStar(require("./types/ApiMethodTypes"), exports);
22
22
  __exportStar(require("./types/ApiCallOptions"), exports);
23
23
  __exportStar(require("./types/ApiMethodOptions"), exports);
24
24
  __exportStar(require("./utils/buildQuery"), exports);
25
+ __exportStar(require("./utils/formatApiError"), exports);
25
26
  __exportStar(require("./utils/handleApiResponse"), exports);
26
27
  __exportStar(require("./utils/SortTypeFromSortDirection"), exports);
27
28
  __exportStar(require("./utils/toFormData"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAE7B,yDAAuC;AACvC,sDAAoC;AACpC,wDAAsC;AAEtC,yDAAuC;AACvC,yDAAuC;AACvC,2DAAyC;AAEzC,qDAAmC;AACnC,4DAA0C;AAC1C,oEAAkD;AAClD,qDAAmC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAE7B,yDAAuC;AACvC,sDAAoC;AACpC,wDAAsC;AAEtC,yDAAuC;AACvC,yDAAuC;AACvC,2DAAyC;AAEzC,qDAAmC;AACnC,yDAAuC;AACvC,4DAA0C;AAC1C,oEAAkD;AAClD,qDAAmC"}
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatApiError = formatApiError;
4
+ /** Format API errors for notifications without discarding the original payload. */
5
+ const defaultErrorMessage = "An unknown error occurred.";
6
+ const statusMessages = {
7
+ 400: "Bad request",
8
+ 401: "Authentication required",
9
+ 403: "Access denied",
10
+ 404: "Resource not found",
11
+ 405: "Method not allowed",
12
+ 408: "Request timed out",
13
+ 409: "Conflict",
14
+ 413: "Request too large",
15
+ 415: "Unsupported media type",
16
+ 422: "Validation failed",
17
+ 429: "Too many requests",
18
+ 500: "Internal server error",
19
+ 502: "Bad gateway",
20
+ 503: "Service unavailable",
21
+ 504: "Gateway timeout",
22
+ };
23
+ function isRecord(value) {
24
+ return typeof value === "object" && value !== null && !Array.isArray(value);
25
+ }
26
+ function property(record, key) {
27
+ if (Object.prototype.hasOwnProperty.call(record, key))
28
+ return record[key];
29
+ const matchingKey = Object.keys(record).find((candidate) => candidate.toLowerCase() === key.toLowerCase());
30
+ return matchingKey === undefined ? undefined : record[matchingKey];
31
+ }
32
+ function nonEmptyString(value) {
33
+ if (typeof value !== "string")
34
+ return undefined;
35
+ const trimmed = value.trim();
36
+ return trimmed || undefined;
37
+ }
38
+ function readableJson(value) {
39
+ const seen = new WeakSet();
40
+ try {
41
+ const json = JSON.stringify(value, (_key, entry) => {
42
+ if (typeof entry === "bigint")
43
+ return entry.toString();
44
+ if (entry instanceof Error)
45
+ return { name: entry.name, message: entry.message };
46
+ if (entry && typeof entry === "object") {
47
+ if (seen.has(entry))
48
+ return "[Circular]";
49
+ seen.add(entry);
50
+ }
51
+ return entry;
52
+ }, 2);
53
+ if (json && json !== "{}" && json !== "[]")
54
+ return json;
55
+ }
56
+ catch {
57
+ // Non-serializable input; use a status-based fallback below.
58
+ }
59
+ return undefined;
60
+ }
61
+ function parseJsonLikeString(text) {
62
+ if (!text.startsWith("{") && !text.startsWith("["))
63
+ return text;
64
+ try {
65
+ return JSON.parse(text);
66
+ }
67
+ catch {
68
+ return text;
69
+ }
70
+ }
71
+ /** ASP.NET ValidationProblemDetails, ModelState and common errors arrays. */
72
+ function validationMessages(value) {
73
+ const messages = [];
74
+ const seen = new WeakSet();
75
+ let visited = 0;
76
+ function visit(current, field) {
77
+ if (++visited > 500 || current === null || current === undefined)
78
+ return;
79
+ if (typeof current === "string" || typeof current === "number" || typeof current === "boolean") {
80
+ const message = String(current).trim();
81
+ if (message)
82
+ messages.push(field ? `${field}: ${message}` : message);
83
+ return;
84
+ }
85
+ if (typeof current !== "object" || current instanceof Blob || seen.has(current))
86
+ return;
87
+ seen.add(current);
88
+ if (Array.isArray(current)) {
89
+ for (const item of current)
90
+ visit(item, field);
91
+ return;
92
+ }
93
+ const record = current;
94
+ const message = nonEmptyString(property(record, "message"))
95
+ ?? nonEmptyString(property(record, "errorMessage"))
96
+ ?? nonEmptyString(property(record, "description"));
97
+ if (message) {
98
+ const specificField = nonEmptyString(property(record, "field"))
99
+ ?? nonEmptyString(property(record, "property"))
100
+ ?? nonEmptyString(property(record, "propertyName"))
101
+ ?? field;
102
+ messages.push(specificField ? `${specificField}: ${message}` : message);
103
+ return;
104
+ }
105
+ for (const [key, child] of Object.entries(record)) {
106
+ // Preserve the validation property path rather than collapsing all messages into "[object Object]".
107
+ visit(child, field ? `${field}.${key}` : key);
108
+ }
109
+ }
110
+ visit(value);
111
+ return [...new Set(messages)];
112
+ }
113
+ function fallback(status, fallbackMessage) {
114
+ const statusText = status ? statusMessages[status] : undefined;
115
+ if (statusText)
116
+ return `${statusText} (HTTP ${status}).`;
117
+ if (status)
118
+ return `Request failed (HTTP ${status}).`;
119
+ return nonEmptyString(fallbackMessage) ?? defaultErrorMessage;
120
+ }
121
+ /**
122
+ * Produce a readable string for .NET ProblemDetails, validation failures, plain-text
123
+ * errors, transport errors and unknown response shapes. Unknown payloads are returned
124
+ * as formatted JSON rather than being converted to "[object Object]".
125
+ */
126
+ function formatApiError(error, status, fallbackMessage) {
127
+ const seen = new WeakSet();
128
+ function format(value, depth, httpStatus) {
129
+ if (depth > 10 || value === null || value === undefined)
130
+ return undefined;
131
+ if (typeof value === "string") {
132
+ const trimmed = value.trim();
133
+ if (!trimmed)
134
+ return undefined;
135
+ const parsed = parseJsonLikeString(trimmed);
136
+ return parsed === trimmed ? trimmed : format(parsed, depth + 1, httpStatus) ?? trimmed;
137
+ }
138
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
139
+ return String(value);
140
+ }
141
+ if (value instanceof Error) {
142
+ return nonEmptyString(value.message)
143
+ ? `${value.name && value.name !== "Error" ? `${value.name}: ` : ""}${value.message}`
144
+ : value.name;
145
+ }
146
+ if (value instanceof Blob)
147
+ return `Server returned a ${value.type || "binary"} error response (${value.size} bytes).`;
148
+ if (typeof value !== "object" || seen.has(value))
149
+ return undefined;
150
+ seen.add(value);
151
+ if (Array.isArray(value)) {
152
+ const entries = value.map((item) => format(item, depth + 1, httpStatus)).filter((item) => !!item);
153
+ if (entries.length)
154
+ return entries.map((entry) => `• ${entry}`).join("\n");
155
+ return readableJson(value);
156
+ }
157
+ const record = value;
158
+ const kind = nonEmptyString(property(record, "kind"));
159
+ if (kind === "http") {
160
+ const wrappedStatus = property(record, "status");
161
+ const code = typeof wrappedStatus === "number" ? wrappedStatus : httpStatus;
162
+ return format(property(record, "body"), depth + 1, code) ?? fallback(code, fallbackMessage);
163
+ }
164
+ if (kind === "parse") {
165
+ const rawBody = nonEmptyString(property(record, "rawBody"));
166
+ const code = property(record, "status");
167
+ return `Invalid server response${typeof code === "number" ? ` (HTTP ${code})` : ""}: expected valid JSON${rawBody ? `. Received: ${rawBody}` : "."}`;
168
+ }
169
+ if (kind === "aborted")
170
+ return "Request was cancelled or timed out.";
171
+ if (kind === "network") {
172
+ const cause = format(property(record, "cause"), depth + 1, httpStatus);
173
+ return cause ? `Network error: ${cause}` : "Network error: Could not reach the server.";
174
+ }
175
+ const nestedData = property(record, "data");
176
+ const hasOwnMessage = property(record, "message") !== undefined
177
+ || property(record, "detail") !== undefined
178
+ || property(record, "title") !== undefined
179
+ || property(record, "errors") !== undefined;
180
+ if (!hasOwnMessage && nestedData !== undefined) {
181
+ const result = format(nestedData, depth + 1, httpStatus);
182
+ if (result)
183
+ return result;
184
+ }
185
+ const title = nonEmptyString(property(record, "title"));
186
+ const detail = nonEmptyString(property(record, "detail"));
187
+ const message = nonEmptyString(property(record, "message"))
188
+ ?? nonEmptyString(property(record, "error_description"))
189
+ ?? nonEmptyString(property(record, "description"));
190
+ const errors = property(record, "errors") ?? property(record, "modelState");
191
+ const validation = errors === undefined ? [] : validationMessages(errors);
192
+ if (validation.length) {
193
+ const heading = title ?? message ?? detail ?? "Validation failed";
194
+ return `${heading}:\n${validation.map((entry) => `• ${entry}`).join("\n")}`;
195
+ }
196
+ if (detail && title && detail.toLowerCase() !== title.toLowerCase())
197
+ return `${title}: ${detail}`;
198
+ if (detail)
199
+ return detail;
200
+ if (message)
201
+ return message;
202
+ if (title)
203
+ return title;
204
+ const nestedError = property(record, "error");
205
+ if (nestedError !== undefined) {
206
+ const formatted = format(nestedError, depth + 1, httpStatus);
207
+ if (formatted)
208
+ return formatted;
209
+ }
210
+ // Do not discard undocumented error objects. Display their original fields.
211
+ return readableJson(value);
212
+ }
213
+ return format(error, 0, status) ?? fallback(status, fallbackMessage);
214
+ }
215
+ //# sourceMappingURL=formatApiError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatApiError.js","sourceRoot":"","sources":["../../../src/utils/formatApiError.ts"],"names":[],"mappings":";;AAwHA,wCAqFC;AA7MD,mFAAmF;AACnF,MAAM,mBAAmB,GAAG,4BAA4B,CAAC;AAIzD,MAAM,cAAc,GAA2B;IAC7C,GAAG,EAAE,aAAa;IAClB,GAAG,EAAE,yBAAyB;IAC9B,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,oBAAoB;IACzB,GAAG,EAAE,oBAAoB;IACzB,GAAG,EAAE,mBAAmB;IACxB,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,mBAAmB;IACxB,GAAG,EAAE,wBAAwB;IAC7B,GAAG,EAAE,mBAAmB;IACxB,GAAG,EAAE,mBAAmB;IACxB,GAAG,EAAE,uBAAuB;IAC5B,GAAG,EAAE,aAAa;IAClB,GAAG,EAAE,qBAAqB;IAC1B,GAAG,EAAE,iBAAiB;CACvB,CAAC;AAEF,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,QAAQ,CAAC,MAAmB,EAAE,GAAW;IAChD,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1E,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3G,OAAO,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,OAAO,IAAI,SAAS,CAAC;AAC9B,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,MAAM,IAAI,GAAG,IAAI,OAAO,EAAU,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,KAAc,EAAE,EAAE;YAC1D,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;YACvD,IAAI,KAAK,YAAY,KAAK;gBAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;YAChF,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACvC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,OAAO,YAAY,CAAC;gBACzC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,EAAE,CAAC,CAAC,CAAC;QACN,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,6DAA6D;IAC/D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY;IACvC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChE,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,SAAS,kBAAkB,CAAC,KAAc;IACxC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,OAAO,EAAU,CAAC;IACnC,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,SAAS,KAAK,CAAC,OAAgB,EAAE,KAAc;QAC7C,IAAI,EAAE,OAAO,GAAG,GAAG,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO;QACzE,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/F,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YACvC,IAAI,OAAO;gBAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QACD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,YAAY,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO;QACxF,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClB,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,KAAK,MAAM,IAAI,IAAI,OAAO;gBAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC/C,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,OAAsB,CAAC;QACtC,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;eACtD,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;eAChD,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;QACrD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,aAAa,GAAG,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;mBAC1D,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;mBAC5C,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;mBAChD,KAAK,CAAC;YACX,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,aAAa,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YACxE,OAAO;QACT,CAAC;QACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAClD,oGAAoG;YACpG,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,CAAC;IACb,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,QAAQ,CAAC,MAAe,EAAE,eAAwB;IACzD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/D,IAAI,UAAU;QAAE,OAAO,GAAG,UAAU,UAAU,MAAM,IAAI,CAAC;IACzD,IAAI,MAAM;QAAE,OAAO,wBAAwB,MAAM,IAAI,CAAC;IACtD,OAAO,cAAc,CAAC,eAAe,CAAC,IAAI,mBAAmB,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAAC,KAAc,EAAE,MAAe,EAAE,eAAwB;IACtF,MAAM,IAAI,GAAG,IAAI,OAAO,EAAU,CAAC;IAEnC,SAAS,MAAM,CAAC,KAAc,EAAE,KAAa,EAAE,UAAmB;QAChE,IAAI,KAAK,GAAG,EAAE,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC1E,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO;gBAAE,OAAO,SAAS,CAAC;YAC/B,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;YAC5C,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,UAAU,CAAC,IAAI,OAAO,CAAC;QACzF,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACzF,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC;gBAClC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE;gBACpF,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QACjB,CAAC;QACD,IAAI,KAAK,YAAY,IAAI;YAAE,OAAO,qBAAqB,KAAK,CAAC,IAAI,IAAI,QAAQ,oBAAoB,KAAK,CAAC,IAAI,UAAU,CAAC;QACtH,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACnE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEhB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAClH,IAAI,OAAO,CAAC,MAAM;gBAAE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3E,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QAED,MAAM,MAAM,GAAG,KAAoB,CAAC;QACpC,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACtD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACjD,MAAM,IAAI,GAAG,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC;YAC5E,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAC9F,CAAC;QACD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;YAC5D,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACxC,OAAO,0BAA0B,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,wBAAwB,OAAO,CAAC,CAAC,CAAC,eAAe,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACvJ,CAAC;QACD,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,qCAAqC,CAAC;QACrE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;YACvE,OAAO,KAAK,CAAC,CAAC,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC,CAAC,4CAA4C,CAAC;QAC1F,CAAC;QAED,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,SAAS;eAC1D,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,SAAS;eACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,SAAS;eACvC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,SAAS,CAAC;QAC9C,IAAI,CAAC,aAAa,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,EAAE,KAAK,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;YACzD,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;QAC5B,CAAC;QAED,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;eACtD,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;eACrD,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAC5E,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC1E,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,KAAK,IAAI,OAAO,IAAI,MAAM,IAAI,mBAAmB,CAAC;YAClE,OAAO,GAAG,OAAO,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9E,CAAC;QAED,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE;YAAE,OAAO,GAAG,KAAK,KAAK,MAAM,EAAE,CAAC;QAClG,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAC1B,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;QAC5B,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QAExB,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9C,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;YAC7D,IAAI,SAAS;gBAAE,OAAO,SAAS,CAAC;QAClC,CAAC;QAED,4EAA4E;QAC5E,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AACvE,CAAC"}
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createApiHttpError = createApiHttpError;
4
4
  exports.handleApiResponse = handleApiResponse;
5
- const defaultUnknownErrorMessage = "An unknown error occurred.";
5
+ const formatApiError_1 = require("./formatApiError");
6
6
  class ResponseParseError extends Error {
7
7
  constructor(status, rawBody, parseCause) {
8
8
  super(`Could not parse JSON response with status ${status}.`);
@@ -49,7 +49,8 @@ function createApiHttpError(status, body) {
49
49
  body: body,
50
50
  };
51
51
  }
52
- function clientError(error, fallbackErrorMessage) {
52
+ /** Preserve the transport or parsing failure for callers that need details. */
53
+ function clientError(error) {
53
54
  if (error instanceof ResponseParseError) {
54
55
  return {
55
56
  kind: "parse",
@@ -64,7 +65,17 @@ function clientError(error, fallbackErrorMessage) {
64
65
  if (name === "AbortError" || name === "TimeoutError") {
65
66
  return { kind: "aborted", cause: error };
66
67
  }
67
- return fallbackErrorMessage ?? defaultUnknownErrorMessage;
68
+ return { kind: "network", cause: error };
69
+ }
70
+ /** Return an error as readable text but keep the original typed payload in `rawError`. */
71
+ function failure(status, rawError, fallbackErrorMessage) {
72
+ return {
73
+ ok: false,
74
+ status,
75
+ response: undefined,
76
+ error: (0, formatApiError_1.formatApiError)(rawError, status || undefined, fallbackErrorMessage),
77
+ rawError,
78
+ };
68
79
  }
69
80
  async function handleApiResponse(call, options) {
70
81
  let result;
@@ -82,12 +93,7 @@ async function handleApiResponse(call, options) {
82
93
  };
83
94
  }
84
95
  catch (error) {
85
- result = {
86
- ok: false,
87
- status: response.status,
88
- response: undefined,
89
- error: clientError(error, options?.fallbackErrorMessage),
90
- };
96
+ result = failure(response.status, clientError(error), options?.fallbackErrorMessage);
91
97
  }
92
98
  }
93
99
  catch (error) {
@@ -98,31 +104,16 @@ async function handleApiResponse(call, options) {
98
104
  ? options.transformError(rawErrorData, error)
99
105
  : rawErrorData;
100
106
  const errorData = transformedError === undefined
101
- ? options?.fallbackErrorMessage ?? defaultUnknownErrorMessage
107
+ ? createApiHttpError(error.status, undefined)
102
108
  : transformedError;
103
- result = {
104
- ok: false,
105
- status: error.status,
106
- response: undefined,
107
- error: errorData,
108
- };
109
+ result = failure(error.status, errorData, options?.fallbackErrorMessage);
109
110
  }
110
111
  catch (parseError) {
111
- result = {
112
- ok: false,
113
- status: error.status,
114
- response: undefined,
115
- error: clientError(parseError, options?.fallbackErrorMessage),
116
- };
112
+ result = failure(error.status, clientError(parseError), options?.fallbackErrorMessage);
117
113
  }
118
114
  }
119
115
  else {
120
- result = {
121
- ok: false,
122
- status: 0,
123
- response: undefined,
124
- error: clientError(error, options?.fallbackErrorMessage),
125
- };
116
+ result = failure(0, clientError(error), options?.fallbackErrorMessage);
126
117
  }
127
118
  }
128
119
  // Consumer callbacks intentionally execute outside the request-catching block.
@@ -1 +1 @@
1
- {"version":3,"file":"handleApiResponse.js","sourceRoot":"","sources":["../../../src/utils/handleApiResponse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handleApiResponse.js","sourceRoot":"","sources":["../../../src/utils/handleApiResponse.ts"],"names":[],"mappings":"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"}
package/dist/esm/index.js CHANGED
@@ -6,6 +6,7 @@ export * from "./types/ApiMethodTypes.js";
6
6
  export * from "./types/ApiCallOptions.js";
7
7
  export * from "./types/ApiMethodOptions.js";
8
8
  export * from "./utils/buildQuery.js";
9
+ export * from "./utils/formatApiError.js";
9
10
  export * from "./utils/handleApiResponse.js";
10
11
  export * from "./utils/SortTypeFromSortDirection.js";
11
12
  export * from "./utils/toFormData.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAE7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAE7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,212 @@
1
+ /** Format API errors for notifications without discarding the original payload. */
2
+ const defaultErrorMessage = "An unknown error occurred.";
3
+ const statusMessages = {
4
+ 400: "Bad request",
5
+ 401: "Authentication required",
6
+ 403: "Access denied",
7
+ 404: "Resource not found",
8
+ 405: "Method not allowed",
9
+ 408: "Request timed out",
10
+ 409: "Conflict",
11
+ 413: "Request too large",
12
+ 415: "Unsupported media type",
13
+ 422: "Validation failed",
14
+ 429: "Too many requests",
15
+ 500: "Internal server error",
16
+ 502: "Bad gateway",
17
+ 503: "Service unavailable",
18
+ 504: "Gateway timeout",
19
+ };
20
+ function isRecord(value) {
21
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22
+ }
23
+ function property(record, key) {
24
+ if (Object.prototype.hasOwnProperty.call(record, key))
25
+ return record[key];
26
+ const matchingKey = Object.keys(record).find((candidate) => candidate.toLowerCase() === key.toLowerCase());
27
+ return matchingKey === undefined ? undefined : record[matchingKey];
28
+ }
29
+ function nonEmptyString(value) {
30
+ if (typeof value !== "string")
31
+ return undefined;
32
+ const trimmed = value.trim();
33
+ return trimmed || undefined;
34
+ }
35
+ function readableJson(value) {
36
+ const seen = new WeakSet();
37
+ try {
38
+ const json = JSON.stringify(value, (_key, entry) => {
39
+ if (typeof entry === "bigint")
40
+ return entry.toString();
41
+ if (entry instanceof Error)
42
+ return { name: entry.name, message: entry.message };
43
+ if (entry && typeof entry === "object") {
44
+ if (seen.has(entry))
45
+ return "[Circular]";
46
+ seen.add(entry);
47
+ }
48
+ return entry;
49
+ }, 2);
50
+ if (json && json !== "{}" && json !== "[]")
51
+ return json;
52
+ }
53
+ catch {
54
+ // Non-serializable input; use a status-based fallback below.
55
+ }
56
+ return undefined;
57
+ }
58
+ function parseJsonLikeString(text) {
59
+ if (!text.startsWith("{") && !text.startsWith("["))
60
+ return text;
61
+ try {
62
+ return JSON.parse(text);
63
+ }
64
+ catch {
65
+ return text;
66
+ }
67
+ }
68
+ /** ASP.NET ValidationProblemDetails, ModelState and common errors arrays. */
69
+ function validationMessages(value) {
70
+ const messages = [];
71
+ const seen = new WeakSet();
72
+ let visited = 0;
73
+ function visit(current, field) {
74
+ if (++visited > 500 || current === null || current === undefined)
75
+ return;
76
+ if (typeof current === "string" || typeof current === "number" || typeof current === "boolean") {
77
+ const message = String(current).trim();
78
+ if (message)
79
+ messages.push(field ? `${field}: ${message}` : message);
80
+ return;
81
+ }
82
+ if (typeof current !== "object" || current instanceof Blob || seen.has(current))
83
+ return;
84
+ seen.add(current);
85
+ if (Array.isArray(current)) {
86
+ for (const item of current)
87
+ visit(item, field);
88
+ return;
89
+ }
90
+ const record = current;
91
+ const message = nonEmptyString(property(record, "message"))
92
+ ?? nonEmptyString(property(record, "errorMessage"))
93
+ ?? nonEmptyString(property(record, "description"));
94
+ if (message) {
95
+ const specificField = nonEmptyString(property(record, "field"))
96
+ ?? nonEmptyString(property(record, "property"))
97
+ ?? nonEmptyString(property(record, "propertyName"))
98
+ ?? field;
99
+ messages.push(specificField ? `${specificField}: ${message}` : message);
100
+ return;
101
+ }
102
+ for (const [key, child] of Object.entries(record)) {
103
+ // Preserve the validation property path rather than collapsing all messages into "[object Object]".
104
+ visit(child, field ? `${field}.${key}` : key);
105
+ }
106
+ }
107
+ visit(value);
108
+ return [...new Set(messages)];
109
+ }
110
+ function fallback(status, fallbackMessage) {
111
+ const statusText = status ? statusMessages[status] : undefined;
112
+ if (statusText)
113
+ return `${statusText} (HTTP ${status}).`;
114
+ if (status)
115
+ return `Request failed (HTTP ${status}).`;
116
+ return nonEmptyString(fallbackMessage) ?? defaultErrorMessage;
117
+ }
118
+ /**
119
+ * Produce a readable string for .NET ProblemDetails, validation failures, plain-text
120
+ * errors, transport errors and unknown response shapes. Unknown payloads are returned
121
+ * as formatted JSON rather than being converted to "[object Object]".
122
+ */
123
+ export function formatApiError(error, status, fallbackMessage) {
124
+ const seen = new WeakSet();
125
+ function format(value, depth, httpStatus) {
126
+ if (depth > 10 || value === null || value === undefined)
127
+ return undefined;
128
+ if (typeof value === "string") {
129
+ const trimmed = value.trim();
130
+ if (!trimmed)
131
+ return undefined;
132
+ const parsed = parseJsonLikeString(trimmed);
133
+ return parsed === trimmed ? trimmed : format(parsed, depth + 1, httpStatus) ?? trimmed;
134
+ }
135
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
136
+ return String(value);
137
+ }
138
+ if (value instanceof Error) {
139
+ return nonEmptyString(value.message)
140
+ ? `${value.name && value.name !== "Error" ? `${value.name}: ` : ""}${value.message}`
141
+ : value.name;
142
+ }
143
+ if (value instanceof Blob)
144
+ return `Server returned a ${value.type || "binary"} error response (${value.size} bytes).`;
145
+ if (typeof value !== "object" || seen.has(value))
146
+ return undefined;
147
+ seen.add(value);
148
+ if (Array.isArray(value)) {
149
+ const entries = value.map((item) => format(item, depth + 1, httpStatus)).filter((item) => !!item);
150
+ if (entries.length)
151
+ return entries.map((entry) => `• ${entry}`).join("\n");
152
+ return readableJson(value);
153
+ }
154
+ const record = value;
155
+ const kind = nonEmptyString(property(record, "kind"));
156
+ if (kind === "http") {
157
+ const wrappedStatus = property(record, "status");
158
+ const code = typeof wrappedStatus === "number" ? wrappedStatus : httpStatus;
159
+ return format(property(record, "body"), depth + 1, code) ?? fallback(code, fallbackMessage);
160
+ }
161
+ if (kind === "parse") {
162
+ const rawBody = nonEmptyString(property(record, "rawBody"));
163
+ const code = property(record, "status");
164
+ return `Invalid server response${typeof code === "number" ? ` (HTTP ${code})` : ""}: expected valid JSON${rawBody ? `. Received: ${rawBody}` : "."}`;
165
+ }
166
+ if (kind === "aborted")
167
+ return "Request was cancelled or timed out.";
168
+ if (kind === "network") {
169
+ const cause = format(property(record, "cause"), depth + 1, httpStatus);
170
+ return cause ? `Network error: ${cause}` : "Network error: Could not reach the server.";
171
+ }
172
+ const nestedData = property(record, "data");
173
+ const hasOwnMessage = property(record, "message") !== undefined
174
+ || property(record, "detail") !== undefined
175
+ || property(record, "title") !== undefined
176
+ || property(record, "errors") !== undefined;
177
+ if (!hasOwnMessage && nestedData !== undefined) {
178
+ const result = format(nestedData, depth + 1, httpStatus);
179
+ if (result)
180
+ return result;
181
+ }
182
+ const title = nonEmptyString(property(record, "title"));
183
+ const detail = nonEmptyString(property(record, "detail"));
184
+ const message = nonEmptyString(property(record, "message"))
185
+ ?? nonEmptyString(property(record, "error_description"))
186
+ ?? nonEmptyString(property(record, "description"));
187
+ const errors = property(record, "errors") ?? property(record, "modelState");
188
+ const validation = errors === undefined ? [] : validationMessages(errors);
189
+ if (validation.length) {
190
+ const heading = title ?? message ?? detail ?? "Validation failed";
191
+ return `${heading}:\n${validation.map((entry) => `• ${entry}`).join("\n")}`;
192
+ }
193
+ if (detail && title && detail.toLowerCase() !== title.toLowerCase())
194
+ return `${title}: ${detail}`;
195
+ if (detail)
196
+ return detail;
197
+ if (message)
198
+ return message;
199
+ if (title)
200
+ return title;
201
+ const nestedError = property(record, "error");
202
+ if (nestedError !== undefined) {
203
+ const formatted = format(nestedError, depth + 1, httpStatus);
204
+ if (formatted)
205
+ return formatted;
206
+ }
207
+ // Do not discard undocumented error objects. Display their original fields.
208
+ return readableJson(value);
209
+ }
210
+ return format(error, 0, status) ?? fallback(status, fallbackMessage);
211
+ }
212
+ //# sourceMappingURL=formatApiError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatApiError.js","sourceRoot":"","sources":["../../../src/utils/formatApiError.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- const defaultUnknownErrorMessage = "An unknown error occurred.";
1
+ import { formatApiError } from "./formatApiError.js";
2
2
  class ResponseParseError extends Error {
3
3
  constructor(status, rawBody, parseCause) {
4
4
  super(`Could not parse JSON response with status ${status}.`);
@@ -45,7 +45,8 @@ export function createApiHttpError(status, body) {
45
45
  body: body,
46
46
  };
47
47
  }
48
- function clientError(error, fallbackErrorMessage) {
48
+ /** Preserve the transport or parsing failure for callers that need details. */
49
+ function clientError(error) {
49
50
  if (error instanceof ResponseParseError) {
50
51
  return {
51
52
  kind: "parse",
@@ -60,7 +61,17 @@ function clientError(error, fallbackErrorMessage) {
60
61
  if (name === "AbortError" || name === "TimeoutError") {
61
62
  return { kind: "aborted", cause: error };
62
63
  }
63
- return fallbackErrorMessage ?? defaultUnknownErrorMessage;
64
+ return { kind: "network", cause: error };
65
+ }
66
+ /** Return an error as readable text but keep the original typed payload in `rawError`. */
67
+ function failure(status, rawError, fallbackErrorMessage) {
68
+ return {
69
+ ok: false,
70
+ status,
71
+ response: undefined,
72
+ error: formatApiError(rawError, status || undefined, fallbackErrorMessage),
73
+ rawError,
74
+ };
64
75
  }
65
76
  export async function handleApiResponse(call, options) {
66
77
  let result;
@@ -78,12 +89,7 @@ export async function handleApiResponse(call, options) {
78
89
  };
79
90
  }
80
91
  catch (error) {
81
- result = {
82
- ok: false,
83
- status: response.status,
84
- response: undefined,
85
- error: clientError(error, options?.fallbackErrorMessage),
86
- };
92
+ result = failure(response.status, clientError(error), options?.fallbackErrorMessage);
87
93
  }
88
94
  }
89
95
  catch (error) {
@@ -94,31 +100,16 @@ export async function handleApiResponse(call, options) {
94
100
  ? options.transformError(rawErrorData, error)
95
101
  : rawErrorData;
96
102
  const errorData = transformedError === undefined
97
- ? options?.fallbackErrorMessage ?? defaultUnknownErrorMessage
103
+ ? createApiHttpError(error.status, undefined)
98
104
  : transformedError;
99
- result = {
100
- ok: false,
101
- status: error.status,
102
- response: undefined,
103
- error: errorData,
104
- };
105
+ result = failure(error.status, errorData, options?.fallbackErrorMessage);
105
106
  }
106
107
  catch (parseError) {
107
- result = {
108
- ok: false,
109
- status: error.status,
110
- response: undefined,
111
- error: clientError(parseError, options?.fallbackErrorMessage),
112
- };
108
+ result = failure(error.status, clientError(parseError), options?.fallbackErrorMessage);
113
109
  }
114
110
  }
115
111
  else {
116
- result = {
117
- ok: false,
118
- status: 0,
119
- response: undefined,
120
- error: clientError(error, options?.fallbackErrorMessage),
121
- };
112
+ result = failure(0, clientError(error), options?.fallbackErrorMessage);
122
113
  }
123
114
  }
124
115
  // Consumer callbacks intentionally execute outside the request-catching block.
@@ -1 +1 @@
1
- {"version":3,"file":"handleApiResponse.js","sourceRoot":"","sources":["../../../src/utils/handleApiResponse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handleApiResponse.js","sourceRoot":"","sources":["../../../src/utils/handleApiResponse.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ export * from "./types/ApiMethodTypes";
6
6
  export * from "./types/ApiCallOptions";
7
7
  export * from "./types/ApiMethodOptions";
8
8
  export * from "./utils/buildQuery";
9
+ export * from "./utils/formatApiError";
9
10
  export * from "./utils/handleApiResponse";
10
11
  export * from "./utils/SortTypeFromSortDirection";
11
12
  export * from "./utils/toFormData";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAE7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAE7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,oBAAoB,CAAC"}
@@ -26,11 +26,15 @@ export type ApiResult<TResponse, TError = unknown> = {
26
26
  status: number;
27
27
  response: TResponse;
28
28
  error?: never;
29
+ rawError?: never;
29
30
  } | {
30
31
  ok: false;
31
32
  status: number;
32
33
  response?: undefined;
33
- error: TError | ApiClientError | string;
34
+ /** Human-readable error text, safe for toast notifications and UI messages. */
35
+ error: string;
36
+ /** Original typed error response or client error, without information loss. */
37
+ rawError: TError | ApiHttpError | ApiClientError | string;
34
38
  };
35
39
  export type ApiSuccessResult<TResponse, TError = unknown> = Extract<ApiResult<TResponse, TError>, {
36
40
  ok: true;
@@ -1 +1 @@
1
- {"version":3,"file":"ApiResult.d.ts","sourceRoot":"","sources":["../../../src/interfaces/ApiResult.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,SAAS,GACT,gBAAgB,EAAE,GAClB;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAAA;CAAE,CAAC;AAExC,wEAAwE;AACxE,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,gBAAgB,CAAC;CACxB,CAAC;AAEF,0FAA0F;AAC1F,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEN,yEAAyE;AACzE,MAAM,MAAM,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,IAC7C;IACE,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,MAAM,CAAC;CACzC,CAAC;AAEN,MAAM,MAAM,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,IAAI,OAAO,CACjE,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,EAC5B;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,CACb,CAAC;AAEF,MAAM,MAAM,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,IAAI,OAAO,CAC/D,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,EAC5B;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CACd,CAAC"}
1
+ {"version":3,"file":"ApiResult.d.ts","sourceRoot":"","sources":["../../../src/interfaces/ApiResult.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,SAAS,GACT,gBAAgB,EAAE,GAClB;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAAA;CAAE,CAAC;AAExC,wEAAwE;AACxE,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,gBAAgB,CAAC;CACxB,CAAC;AAEF,0FAA0F;AAC1F,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEN,yEAAyE;AACzE,MAAM,MAAM,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,IAC7C;IACE,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,cAAc,GAAG,MAAM,CAAC;CAC3D,CAAC;AAEN,MAAM,MAAM,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,IAAI,OAAO,CACjE,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,EAC5B;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,CACb,CAAC;AAEF,MAAM,MAAM,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,IAAI,OAAO,CAC/D,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,EAC5B;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CACd,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Produce a readable string for .NET ProblemDetails, validation failures, plain-text
3
+ * errors, transport errors and unknown response shapes. Unknown payloads are returned
4
+ * as formatted JSON rather than being converted to "[object Object]".
5
+ */
6
+ export declare function formatApiError(error: unknown, status?: number, fallbackMessage?: string): string;
7
+ //# sourceMappingURL=formatApiError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatApiError.d.ts","sourceRoot":"","sources":["../../../src/utils/formatApiError.ts"],"names":[],"mappings":"AAmHA;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAqFhG"}
@@ -1 +1 @@
1
- {"version":3,"file":"handleApiResponse.d.ts","sourceRoot":"","sources":["../../../src/utils/handleApiResponse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAoB,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzG,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAIlD,MAAM,MAAM,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,IAAI;IAClE,SAAS,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7C,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,SAAS,CAAC;IAClD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,MAAM,CAAC;IAChE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAoDF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,YAAY,CAM9E;AAwBD,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EACjE,IAAI,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,EACpD,OAAO,CAAC,EAAE,wBAAwB,CAAC,SAAS,EAAE,MAAM,CAAC,GACpD,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CA+DvC"}
1
+ {"version":3,"file":"handleApiResponse.d.ts","sourceRoot":"","sources":["../../../src/utils/handleApiResponse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAoB,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzG,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,MAAM,MAAM,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,IAAI;IAClE,SAAS,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7C,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,SAAS,CAAC;IAClD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,MAAM,CAAC;IAChE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAkDF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,YAAY,CAM9E;AAuCD,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EACjE,IAAI,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,EACpD,OAAO,CAAC,EAAE,wBAAwB,CAAC,SAAS,EAAE,MAAM,CAAC,GACpD,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CA0CvC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typedapi-client-helpers",
3
- "version": "0.3.5",
3
+ "version": "0.4.0",
4
4
  "description": "Reusable typed OpenAPI client helpers.",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -2,7 +2,10 @@
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- import { generateApi } from "./openapi-generator/index.mjs";
5
+ import {
6
+ cleanupGenerationArtifacts,
7
+ generateApi,
8
+ } from "./openapi-generator/index.mjs";
6
9
 
7
10
  const __filename = fileURLToPath(import.meta.url);
8
11
  const __dirname = path.dirname(__filename);
@@ -93,6 +96,28 @@ const apiRoot = path.resolve(
93
96
  ),
94
97
  );
95
98
 
99
+ let terminationSignalHandled = false;
100
+
101
+ function handleTerminationSignal(signal) {
102
+ if (terminationSignalHandled) return;
103
+
104
+ terminationSignalHandled = true;
105
+
106
+ try {
107
+ cleanupGenerationArtifacts(apiRoot);
108
+ } catch (error) {
109
+ console.error(
110
+ `Failed to clean TypedApi temporary files after ${signal}:`,
111
+ error,
112
+ );
113
+ }
114
+
115
+ process.exit(signal === "SIGINT" ? 130 : 143);
116
+ }
117
+
118
+ process.once("SIGINT", () => handleTerminationSignal("SIGINT"));
119
+ process.once("SIGTERM", () => handleTerminationSignal("SIGTERM"));
120
+
96
121
  const methodsDir = path.join(apiRoot, "methods");
97
122
 
98
123
  const defaultFunctionsPathSetting = getStringSetting(
@@ -222,7 +247,8 @@ function getMethodNameStyle(...values) {
222
247
  const normalized = value.replace(/[\s_-]/g, "").toLowerCase();
223
248
 
224
249
  if (["operationid", "operation"].includes(normalized)) return "operationId";
225
- if (["action", "actionname", "controllermethod"].includes(normalized)) return "action";
250
+ if (["action", "actionname", "controllermethod"].includes(normalized))
251
+ return "action";
226
252
 
227
253
  throw new Error(
228
254
  `Invalid typedApiMethodNameStyle ${JSON.stringify(value)}. Use "operationId" or "action".`,
@@ -284,7 +310,12 @@ function copySwaggerBackupFromFile(filePath) {
284
310
  async function downloadSwaggerBackupFromUrl(url) {
285
311
  const controller = new AbortController();
286
312
  const timeout = setTimeout(
287
- () => controller.abort(new Error(`Swagger download timed out after ${swaggerDownloadTimeoutMs}ms.`)),
313
+ () =>
314
+ controller.abort(
315
+ new Error(
316
+ `Swagger download timed out after ${swaggerDownloadTimeoutMs}ms.`,
317
+ ),
318
+ ),
288
319
  swaggerDownloadTimeoutMs,
289
320
  );
290
321
  let response;
@@ -323,7 +354,9 @@ function useBackupSwaggerInput(reason) {
323
354
  async function resolveSwaggerInput() {
324
355
  if (offlineMode) {
325
356
  if (!fileExists(swaggerBackupPath)) {
326
- throw new Error(`Offline mode requires an existing Swagger backup: ${swaggerBackupPath}`);
357
+ throw new Error(
358
+ `Offline mode requires an existing Swagger backup: ${swaggerBackupPath}`,
359
+ );
327
360
  }
328
361
  return { input: swaggerBackupPath, label: swaggerBackupPath };
329
362
  }
@@ -342,7 +375,9 @@ async function resolveSwaggerInput() {
342
375
 
343
376
  const backupInput = strictMode
344
377
  ? undefined
345
- : useBackupSwaggerInput(`Swagger file was not found: ${swaggerFilePath}.`);
378
+ : useBackupSwaggerInput(
379
+ `Swagger file was not found: ${swaggerFilePath}.`,
380
+ );
346
381
 
347
382
  if (backupInput) return backupInput;
348
383
 
@@ -452,7 +487,6 @@ export const ${defaultErrorMessageName} = "An unknown error occurred.";
452
487
  return resolvedFilePath;
453
488
  }
454
489
 
455
-
456
490
  function addDefaultErrorMessageIfMissing(filePath) {
457
491
  const source = fs.readFileSync(filePath, "utf8");
458
492
  if (fileExportsName(source, defaultErrorMessageName)) return;
@@ -527,10 +561,13 @@ function resolveDefaultHandlers() {
527
561
  ? defaultFunctionsFilePath
528
562
  : `${defaultFunctionsFilePath}.ts`;
529
563
  if (checkMode && !fs.existsSync(candidatePath)) {
530
- if (verboseMode) console.log("Skipping missing default handler file in check mode.");
564
+ if (verboseMode)
565
+ console.log("Skipping missing default handler file in check mode.");
531
566
  return undefined;
532
567
  }
533
- const defaultFunctionsFile = createDefaultFunctionsFileIfMissing(defaultFunctionsFilePath);
568
+ const defaultFunctionsFile = createDefaultFunctionsFileIfMissing(
569
+ defaultFunctionsFilePath,
570
+ );
534
571
  const source = fs.readFileSync(defaultFunctionsFile, "utf8");
535
572
  const hasSuccessHandler = fileExportsName(source, defaultSuccessHandlerName);
536
573
  const hasErrorHandler = fileExportsName(source, defaultErrorHandlerName);
@@ -562,6 +599,8 @@ function resolveDefaultHandlers() {
562
599
  }
563
600
 
564
601
  async function main() {
602
+ cleanupGenerationArtifacts(apiRoot);
603
+
565
604
  const swaggerInput = await resolveSwaggerInput();
566
605
 
567
606
  console.log(`Generating API from: ${swaggerInput.label}`);
@@ -588,7 +627,9 @@ async function main() {
588
627
  );
589
628
  }
590
629
 
591
- console.log(checkMode ? "Generated API is up to date." : "API generation completed.");
630
+ console.log(
631
+ checkMode ? "Generated API is up to date." : "API generation completed.",
632
+ );
592
633
  }
593
634
 
594
635
  main().catch((error) => {
@@ -1,7 +1,10 @@
1
1
  import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
- import { collectOperations, validateOpenApiDocument } from "./openapi-utils.mjs";
4
+ import {
5
+ collectOperations,
6
+ validateOpenApiDocument,
7
+ } from "./openapi-utils.mjs";
5
8
  import { generateDataContracts } from "./schema.mjs";
6
9
  import { generateHttpClient } from "./http-client-template.mjs";
7
10
  import {
@@ -54,13 +57,18 @@ export async function generateApi(options) {
54
57
 
55
58
  const controllers = new Map();
56
59
  for (const operationInfo of operations) {
57
- const controllerName = controllerNameForOperation(operationInfo, normalizedOptions);
60
+ const controllerName = controllerNameForOperation(
61
+ operationInfo,
62
+ normalizedOptions,
63
+ );
58
64
  const controllerOperations = controllers.get(controllerName) ?? [];
59
65
  controllerOperations.push(operationInfo);
60
66
  controllers.set(controllerName, controllerOperations);
61
67
  }
62
68
 
63
- const controllerNames = [...controllers.keys()].sort((a, b) => a.localeCompare(b));
69
+ const controllerNames = [...controllers.keys()].sort((a, b) =>
70
+ a.localeCompare(b),
71
+ );
64
72
  for (const controllerName of controllerNames) {
65
73
  files.set(
66
74
  `methods/${methodFileNameForController(controllerName)}`,
@@ -73,7 +81,6 @@ export async function generateApi(options) {
73
81
  );
74
82
  }
75
83
 
76
-
77
84
  const changes = compareOutput(output, files);
78
85
  if (options.check) {
79
86
  if (changes.length > 0) {
@@ -81,7 +88,10 @@ export async function generateApi(options) {
81
88
  `Generated API is out of date:\n${changes.map((item) => `- ${item}`).join("\n")}`,
82
89
  );
83
90
  }
84
- return { files: [...files.keys()].map((file) => path.join(output, file)), changed: false };
91
+ return {
92
+ files: [...files.keys()].map((file) => path.join(output, file)),
93
+ changed: false,
94
+ };
85
95
  }
86
96
 
87
97
  const writeStrategy = writeOutputTransactionally(
@@ -105,7 +115,8 @@ function compareOutput(output, files) {
105
115
  changes.push(`${relativePath} is missing`);
106
116
  continue;
107
117
  }
108
- if (fs.readFileSync(target, "utf8") !== expected) changes.push(`${relativePath} differs`);
118
+ if (fs.readFileSync(target, "utf8") !== expected)
119
+ changes.push(`${relativePath} differs`);
109
120
  }
110
121
 
111
122
  for (const relativePath of listManagedFiles(output)) {
@@ -123,7 +134,9 @@ function listManagedFiles(output) {
123
134
  result.push(topLevel);
124
135
  continue;
125
136
  }
126
- walk(target, (file) => result.push(path.relative(output, file).replaceAll(path.sep, "/")));
137
+ walk(target, (file) =>
138
+ result.push(path.relative(output, file).replaceAll(path.sep, "/")),
139
+ );
127
140
  }
128
141
  return result;
129
142
  }
@@ -142,6 +155,61 @@ function removeManagedOutput(root) {
142
155
  }
143
156
  }
144
157
 
158
+ export function cleanupGenerationArtifacts(output) {
159
+ const resolvedOutput = path.resolve(output);
160
+ const parent = path.dirname(resolvedOutput);
161
+
162
+ if (!fs.existsSync(parent)) return;
163
+
164
+ const outputName = path.basename(resolvedOutput);
165
+ const stagingPrefix = `.${outputName}.typedapi-staging-`;
166
+ const backupPrefix = `.${outputName}.typedapi-backup-`;
167
+ const managedBackupPrefix = `.${outputName}.typedapi-managed-backup-`;
168
+ const backups = [];
169
+
170
+ for (const entry of fs.readdirSync(parent, { withFileTypes: true })) {
171
+ if (!entry.isDirectory()) continue;
172
+
173
+ const entryPath = path.join(parent, entry.name);
174
+
175
+ if (
176
+ entry.name.startsWith(stagingPrefix) ||
177
+ entry.name.startsWith(managedBackupPrefix)
178
+ ) {
179
+ removePathWithRetry(entryPath);
180
+ continue;
181
+ }
182
+
183
+ if (entry.name.startsWith(backupPrefix)) {
184
+ backups.push(entryPath);
185
+ }
186
+ }
187
+
188
+ if (backups.length === 0) return;
189
+
190
+ if (!fs.existsSync(resolvedOutput)) {
191
+ backups.sort(
192
+ (left, right) => fs.statSync(right).mtimeMs - fs.statSync(left).mtimeMs,
193
+ );
194
+
195
+ const [backupToRestore, ...staleBackups] = backups;
196
+
197
+ retryFileSystemOperation(() =>
198
+ fs.renameSync(backupToRestore, resolvedOutput),
199
+ );
200
+
201
+ for (const backup of staleBackups) {
202
+ removePathWithRetry(backup);
203
+ }
204
+
205
+ return;
206
+ }
207
+
208
+ for (const backup of backups) {
209
+ removePathWithRetry(backup);
210
+ }
211
+ }
212
+
145
213
  const RETRYABLE_FS_ERROR_CODES = new Set([
146
214
  "EACCES",
147
215
  "EBUSY",
@@ -151,14 +219,25 @@ const RETRYABLE_FS_ERROR_CODES = new Set([
151
219
  "EPERM",
152
220
  ]);
153
221
 
154
- function writeOutputTransactionally(output, files, cleanOutput, forceInPlaceOutput = false) {
222
+ function writeOutputTransactionally(
223
+ output,
224
+ files,
225
+ cleanOutput,
226
+ forceInPlaceOutput = false,
227
+ ) {
155
228
  const parent = path.dirname(output);
156
229
  fs.mkdirSync(parent, { recursive: true });
157
- const staging = fs.mkdtempSync(path.join(parent, `.${path.basename(output)}.typedapi-staging-`));
158
- const backup = path.join(parent, `.${path.basename(output)}.typedapi-backup-${process.pid}-${Date.now()}`);
230
+ const staging = fs.mkdtempSync(
231
+ path.join(parent, `.${path.basename(output)}.typedapi-staging-`),
232
+ );
233
+ const backup = path.join(
234
+ parent,
235
+ `.${path.basename(output)}.typedapi-backup-${process.pid}-${Date.now()}`,
236
+ );
159
237
 
160
238
  try {
161
- if (fs.existsSync(output)) fs.cpSync(output, staging, { recursive: true, force: true });
239
+ if (fs.existsSync(output))
240
+ fs.cpSync(output, staging, { recursive: true, force: true });
162
241
  if (cleanOutput) removeManagedOutput(staging);
163
242
 
164
243
  for (const [relativePath, content] of files) {
@@ -212,7 +291,8 @@ function writeOutputTransactionally(output, files, cleanOutput, forceInPlaceOutp
212
291
  return "directory-swap";
213
292
  } finally {
214
293
  removePathWithRetry(staging);
215
- if (fs.existsSync(backup) && fs.existsSync(output)) removePathWithRetry(backup);
294
+ if (fs.existsSync(backup) && fs.existsSync(output))
295
+ removePathWithRetry(backup);
216
296
  }
217
297
  }
218
298
 
@@ -272,7 +352,8 @@ function syncPath(source, target) {
272
352
  syncPath(path.join(source, entry), path.join(target, entry));
273
353
  }
274
354
  for (const entry of fs.readdirSync(target)) {
275
- if (!sourceEntries.has(entry)) removePathWithRetry(path.join(target, entry));
355
+ if (!sourceEntries.has(entry))
356
+ removePathWithRetry(path.join(target, entry));
276
357
  }
277
358
  return;
278
359
  }
@@ -312,7 +393,8 @@ function retryFileSystemOperation(operation, attempts = 12) {
312
393
  return operation();
313
394
  } catch (error) {
314
395
  lastError = error;
315
- if (!isRetryableFileSystemError(error) || attempt === attempts - 1) throw error;
396
+ if (!isRetryableFileSystemError(error) || attempt === attempts - 1)
397
+ throw error;
316
398
  sleepSynchronously(Math.min(25 * 2 ** attempt, 250));
317
399
  }
318
400
  }
@@ -320,7 +402,11 @@ function retryFileSystemOperation(operation, attempts = 12) {
320
402
  }
321
403
 
322
404
  function isRetryableFileSystemError(error) {
323
- return Boolean(error && typeof error === "object" && RETRYABLE_FS_ERROR_CODES.has(error.code));
405
+ return Boolean(
406
+ error &&
407
+ typeof error === "object" &&
408
+ RETRYABLE_FS_ERROR_CODES.has(error.code),
409
+ );
324
410
  }
325
411
 
326
412
  function sleepSynchronously(milliseconds) {