@nomalism-com/api 0.45.63 → 0.45.64
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/index.d.ts +2 -0
- package/dist/index.js +78 -3
- package/dist/lib/apiError.d.ts +52 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -129,9 +129,77 @@ __export(main_exports, {
|
|
|
129
129
|
Workflow: () => workflow_exports,
|
|
130
130
|
ZipCode: () => zipCode_exports
|
|
131
131
|
});
|
|
132
|
-
import
|
|
132
|
+
import axios2, { AxiosHeaders } from "axios";
|
|
133
133
|
import Nomalism from "@nomalism-com/types";
|
|
134
134
|
|
|
135
|
+
// src/lib/apiError.ts
|
|
136
|
+
import axios from "axios";
|
|
137
|
+
var ApiError = class _ApiError extends Error {
|
|
138
|
+
constructor(fields, cause) {
|
|
139
|
+
super(fields.message);
|
|
140
|
+
this.name = "ApiError";
|
|
141
|
+
this.kind = fields.kind;
|
|
142
|
+
this.status = fields.status;
|
|
143
|
+
this.code = fields.code;
|
|
144
|
+
this.method = fields.method;
|
|
145
|
+
this.url = fields.url;
|
|
146
|
+
this.data = fields.data;
|
|
147
|
+
Object.defineProperty(this, "cause", {
|
|
148
|
+
value: cause,
|
|
149
|
+
enumerable: false,
|
|
150
|
+
writable: false,
|
|
151
|
+
configurable: true
|
|
152
|
+
});
|
|
153
|
+
const captureStackTrace = Error.captureStackTrace;
|
|
154
|
+
captureStackTrace?.(this, _ApiError);
|
|
155
|
+
}
|
|
156
|
+
/** Controls what `JSON.stringify(err)` and most loggers emit — kept compact. */
|
|
157
|
+
toJSON() {
|
|
158
|
+
return {
|
|
159
|
+
kind: this.kind,
|
|
160
|
+
message: this.message,
|
|
161
|
+
status: this.status,
|
|
162
|
+
code: this.code,
|
|
163
|
+
method: this.method,
|
|
164
|
+
url: this.url,
|
|
165
|
+
data: this.data
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
function isApiError(error) {
|
|
170
|
+
return error instanceof ApiError;
|
|
171
|
+
}
|
|
172
|
+
function extractServerMessage(data, fallback) {
|
|
173
|
+
if (typeof data === "string" && data.trim()) return data;
|
|
174
|
+
if (data && typeof data === "object") {
|
|
175
|
+
const record = data;
|
|
176
|
+
const candidate = record.message ?? record.error ?? record.detail ?? record.title;
|
|
177
|
+
if (typeof candidate === "string" && candidate.trim()) return candidate;
|
|
178
|
+
}
|
|
179
|
+
return fallback;
|
|
180
|
+
}
|
|
181
|
+
function parseApiError(error) {
|
|
182
|
+
if (error instanceof ApiError) return error;
|
|
183
|
+
if (!axios.isAxiosError(error)) {
|
|
184
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
185
|
+
return new ApiError({ kind: "unknown", message }, error);
|
|
186
|
+
}
|
|
187
|
+
const axiosError = error;
|
|
188
|
+
const method = axiosError.config?.method?.toUpperCase();
|
|
189
|
+
const url = axiosError.config?.url;
|
|
190
|
+
const code = axiosError.code;
|
|
191
|
+
if (axiosError.response) {
|
|
192
|
+
const { status, data } = axiosError.response;
|
|
193
|
+
const message = extractServerMessage(data, `Request failed with status ${status}`);
|
|
194
|
+
return new ApiError({ kind: "response", message, status, code, method, url, data }, error);
|
|
195
|
+
}
|
|
196
|
+
if (axiosError.request) {
|
|
197
|
+
const message = code === "ECONNABORTED" ? `Request timed out${url ? ` (${method} ${url})` : ""}` : `No response received${url ? ` from ${method} ${url}` : ""}`;
|
|
198
|
+
return new ApiError({ kind: "request", message, code, method, url }, error);
|
|
199
|
+
}
|
|
200
|
+
return new ApiError({ kind: "setup", message: axiosError.message, code, method, url }, error);
|
|
201
|
+
}
|
|
202
|
+
|
|
135
203
|
// src/modules/view/webSocket.ts
|
|
136
204
|
var CLOSE_AUTH_REJECTED = 4401;
|
|
137
205
|
var CLOSE_AUTH_UNAVAILABLE = 4503;
|
|
@@ -4453,10 +4521,14 @@ var API = class {
|
|
|
4453
4521
|
if (tokenBearer) {
|
|
4454
4522
|
this.defaultHeaders.setAuthorization(tokenBearer);
|
|
4455
4523
|
}
|
|
4456
|
-
this.client =
|
|
4524
|
+
this.client = axios2.create({
|
|
4457
4525
|
baseURL: gatewayUrl,
|
|
4458
4526
|
headers: this.defaultHeaders
|
|
4459
4527
|
});
|
|
4528
|
+
this.client.interceptors.response.use(
|
|
4529
|
+
(response) => response,
|
|
4530
|
+
(error) => Promise.reject(parseApiError(error))
|
|
4531
|
+
);
|
|
4460
4532
|
const getServicePath = (service) => {
|
|
4461
4533
|
const baseUrl = services[service];
|
|
4462
4534
|
const servicePath = processEnvironment === "localhost" ? "/" : `${service}/`;
|
|
@@ -4749,5 +4821,8 @@ var API = class {
|
|
|
4749
4821
|
// src/index.ts
|
|
4750
4822
|
var index_default = main_exports;
|
|
4751
4823
|
export {
|
|
4752
|
-
|
|
4824
|
+
ApiError,
|
|
4825
|
+
index_default as default,
|
|
4826
|
+
isApiError,
|
|
4827
|
+
parseApiError
|
|
4753
4828
|
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the failure happened in the axios lifecycle.
|
|
3
|
+
*
|
|
4
|
+
* - `response` — the server replied with a non-2xx status (HTTP / application layer).
|
|
5
|
+
* - `request` — the request was sent but no response came back (network, timeout, CORS, offline).
|
|
6
|
+
* - `setup` — the request was never sent (bad config, invalid URL, serialization error).
|
|
7
|
+
* - `unknown` — the thrown value was not an axios error at all.
|
|
8
|
+
*/
|
|
9
|
+
export type ApiErrorKind = 'response' | 'request' | 'setup' | 'unknown';
|
|
10
|
+
export interface IApiErrorFields {
|
|
11
|
+
kind: ApiErrorKind;
|
|
12
|
+
message: string;
|
|
13
|
+
status?: number;
|
|
14
|
+
code?: string;
|
|
15
|
+
method?: string;
|
|
16
|
+
url?: string;
|
|
17
|
+
data?: unknown;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A compact, log-friendly error that replaces axios's huge error object.
|
|
21
|
+
*
|
|
22
|
+
* Only small primitives are kept as enumerable fields, so `console.log(err)`,
|
|
23
|
+
* `JSON.stringify(err)` and `err.stack` stay short. The original axios error is
|
|
24
|
+
* preserved on a NON-enumerable `cause` property — available for deep debugging,
|
|
25
|
+
* but never dumped when the error is logged.
|
|
26
|
+
*/
|
|
27
|
+
export declare class ApiError extends Error {
|
|
28
|
+
readonly kind: ApiErrorKind;
|
|
29
|
+
/** HTTP status code, when the server responded. */
|
|
30
|
+
readonly status?: number;
|
|
31
|
+
/** Axios error code, e.g. 'ECONNABORTED', 'ERR_NETWORK', 'ERR_BAD_REQUEST'. */
|
|
32
|
+
readonly code?: string;
|
|
33
|
+
/** HTTP method of the failed request, uppercased. */
|
|
34
|
+
readonly method?: string;
|
|
35
|
+
/** Request URL (baseURL + path) of the failed request. */
|
|
36
|
+
readonly url?: string;
|
|
37
|
+
/** The server-provided error payload (response body), when present. */
|
|
38
|
+
readonly data?: unknown;
|
|
39
|
+
constructor(fields: IApiErrorFields, cause?: unknown);
|
|
40
|
+
/** Controls what `JSON.stringify(err)` and most loggers emit — kept compact. */
|
|
41
|
+
toJSON(): IApiErrorFields;
|
|
42
|
+
}
|
|
43
|
+
/** Type guard for the simplified error. */
|
|
44
|
+
export declare function isApiError(error: unknown): error is ApiError;
|
|
45
|
+
/**
|
|
46
|
+
* Convert ANY thrown value into a compact {@link ApiError}.
|
|
47
|
+
*
|
|
48
|
+
* This is the single, DRY place that understands axios's four failure modes,
|
|
49
|
+
* so individual modules never have to inspect `error.response` / `error.request`
|
|
50
|
+
* themselves.
|
|
51
|
+
*/
|
|
52
|
+
export declare function parseApiError(error: unknown): ApiError;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomalism-com/api",
|
|
3
3
|
"description": "A nomalism API package for performing HTTP requests on API endpoints",
|
|
4
|
-
"version": "0.45.
|
|
4
|
+
"version": "0.45.64",
|
|
5
5
|
"author": "Nomalism <it.nomalism@gmail.com> (https://https://nomalism.com/)",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"type": "module",
|