@marianmeres/http-utils 2.4.0 → 2.5.1

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/api.d.ts CHANGED
@@ -8,9 +8,9 @@
8
8
  * Request body data type.
9
9
  * Supports JSON-serializable objects, FormData for file uploads, or raw strings.
10
10
  */
11
- export type RequestData = Record<string, unknown> | FormData | string | null;
11
+ export type RequestData = object | FormData | string | null;
12
12
  interface BaseParams {
13
- method: 'GET' | 'POST' | 'PATCH' | 'DELETE' | 'PUT';
13
+ method: "GET" | "POST" | "PATCH" | "DELETE" | "PUT";
14
14
  path: string;
15
15
  }
16
16
  /**
@@ -22,11 +22,11 @@ export interface FetchParams {
22
22
  /** Bearer token (auto-adds `Authorization: Bearer {token}` header). */
23
23
  token?: string | null;
24
24
  /** Custom request headers. */
25
- headers?: Record<string, string> | null;
25
+ headers?: HeadersInit | Record<string, string> | null;
26
26
  /** AbortSignal for request cancellation. */
27
27
  signal?: AbortSignal;
28
28
  /** Credentials mode for the request. */
29
- credentials?: 'omit' | 'same-origin' | 'include' | null;
29
+ credentials?: "omit" | "same-origin" | "include" | null;
30
30
  /** If true, returns the raw Response object instead of parsed body. */
31
31
  raw?: boolean | null;
32
32
  /** If false, does not throw on HTTP errors (default: true). */
package/dist/api.js CHANGED
@@ -4,14 +4,14 @@
4
4
  * HTTP API client factory and related types.
5
5
  * Provides a convenient wrapper over the native `fetch` API with sensible defaults.
6
6
  */
7
- import { createHttpError } from './error.js';
7
+ import { createHttpError } from "./error.js";
8
8
  /**
9
9
  * Deep merges two objects. Later properties overwrite earlier properties.
10
10
  */
11
11
  function deepMerge(target, source) {
12
12
  const output = { ...target };
13
13
  if (isObject(target) && isObject(source)) {
14
- Object.keys(source).forEach(key => {
14
+ Object.keys(source).forEach((key) => {
15
15
  const sourceVal = source[key];
16
16
  const targetVal = target[key];
17
17
  if (isObject(sourceVal)) {
@@ -30,10 +30,10 @@ function deepMerge(target, source) {
30
30
  return output;
31
31
  }
32
32
  function isObject(item) {
33
- return item !== null && typeof item === 'object' && !Array.isArray(item);
33
+ return item !== null && typeof item === "object" && !Array.isArray(item);
34
34
  }
35
35
  /** Symbol marker for explicit options API detection. */
36
- const OPTIONS_MARKER = Symbol('options');
36
+ const OPTIONS_MARKER = Symbol("options");
37
37
  /**
38
38
  * Marks an options object for the new options API.
39
39
  * Use this to explicitly indicate you're using the options-based API.
@@ -75,7 +75,7 @@ function parseGetOptions(paramsOrOptions, legacyRespHeaders, legacyErrorExtracto
75
75
  */
76
76
  function parseDataOptions(dataOrOptions, legacyParams, legacyRespHeaders, legacyErrorExtractor) {
77
77
  if (dataOrOptions &&
78
- typeof dataOrOptions === 'object' &&
78
+ typeof dataOrOptions === "object" &&
79
79
  OPTIONS_MARKER in dataOrOptions) {
80
80
  // New options API (explicit via opts() wrapper)
81
81
  const o = dataOrOptions;
@@ -95,15 +95,20 @@ function parseDataOptions(dataOrOptions, legacyParams, legacyRespHeaders, legacy
95
95
  };
96
96
  }
97
97
  const _fetchRaw = async ({ method, path, data = null, token = null, headers = null, signal, credentials, }) => {
98
- const normalizedHeaders = Object.entries(headers || {}).reduce((m, [k, v]) => ({ ...m, [k.toLowerCase()]: v }), {});
98
+ const normalizedHeaders = {};
99
+ if (headers) {
100
+ new Headers(headers).forEach((value, key) => {
101
+ normalizedHeaders[key] = value;
102
+ });
103
+ }
99
104
  const opts = {
100
105
  method,
101
106
  credentials: credentials ?? undefined,
102
107
  headers: normalizedHeaders,
103
- signal
108
+ signal,
104
109
  };
105
110
  if (data) {
106
- const isObj = typeof data === 'object';
111
+ const isObj = typeof data === "object";
107
112
  // FormData: multipart/form-data -- no explicit Content-Type
108
113
  if (data instanceof FormData) {
109
114
  opts.body = data;
@@ -111,15 +116,15 @@ const _fetchRaw = async ({ method, path, data = null, token = null, headers = nu
111
116
  // Cover 99% of use cases (may not fit all scenarios)
112
117
  else {
113
118
  // If not explicitly stated, assume JSON
114
- if (isObj || !normalizedHeaders['content-type']) {
115
- normalizedHeaders['content-type'] = 'application/json';
119
+ if (isObj || !normalizedHeaders["content-type"]) {
120
+ normalizedHeaders["content-type"] = "application/json";
116
121
  }
117
122
  opts.body = JSON.stringify(data);
118
123
  }
119
124
  }
120
125
  // Opinionated convention: auto-add Bearer token
121
126
  if (token) {
122
- normalizedHeaders['authorization'] = `Bearer ${token}`;
127
+ normalizedHeaders["authorization"] = `Bearer ${token}`;
123
128
  }
124
129
  opts.headers = normalizedHeaders;
125
130
  return await fetch(path, opts);
@@ -159,7 +164,7 @@ const _fetch = async (params, respHeaders = null, errorMessageExtractor = null,
159
164
  b?.message ||
160
165
  b?.error ||
161
166
  _response?.statusText ||
162
- 'Unknown error');
167
+ "Unknown error");
163
168
  if (msg.length > 255)
164
169
  msg = `[Shortened]: ${msg.slice(0, 255)}`;
165
170
  return msg;
@@ -200,40 +205,60 @@ export class HttpApi {
200
205
  return deepMerge(a, b);
201
206
  }
202
207
  async #getDefs() {
203
- if (typeof this.#defaults === 'function') {
208
+ if (typeof this.#defaults === "function") {
204
209
  return { ...(await this.#defaults()) };
205
210
  }
206
211
  return { ...(this.#defaults || {}) };
207
212
  }
208
213
  #buildPath(path, base) {
209
- base = `${base || ''}`;
210
- path = `${path || ''}`;
214
+ base = `${base || ""}`;
215
+ path = `${path || ""}`;
211
216
  return /^https?:/.test(path) ? path : base + path;
212
217
  }
213
218
  async get(path, paramsOrOptions, respHeaders, errorMessageExtractor, _dumpParams = false) {
214
- const { params, respHeaders: headers, errorExtractor } = parseGetOptions(paramsOrOptions, respHeaders, errorMessageExtractor);
219
+ const { params, respHeaders: headers, errorExtractor, } = parseGetOptions(paramsOrOptions, respHeaders, errorMessageExtractor);
215
220
  path = this.#buildPath(path, this.#base);
216
- return _fetch(this.#merge(await this.#getDefs(), { ...params, method: 'GET', path }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
221
+ return _fetch(this.#merge(await this.#getDefs(), { ...params, method: "GET", path }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
217
222
  }
218
223
  async post(path, dataOrOptions, params, respHeaders, errorMessageExtractor, _dumpParams = false) {
219
- const { data, params: fetchParams, respHeaders: headers, errorExtractor } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
224
+ const { data, params: fetchParams, respHeaders: headers, errorExtractor, } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
220
225
  path = this.#buildPath(path, this.#base);
221
- return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'POST', path }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
226
+ return _fetch(this.#merge(await this.#getDefs(), {
227
+ ...(fetchParams || {}),
228
+ data,
229
+ method: "POST",
230
+ path,
231
+ }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
222
232
  }
223
233
  async put(path, dataOrOptions, params, respHeaders, errorMessageExtractor, _dumpParams = false) {
224
- const { data, params: fetchParams, respHeaders: headers, errorExtractor } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
234
+ const { data, params: fetchParams, respHeaders: headers, errorExtractor, } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
225
235
  path = this.#buildPath(path, this.#base);
226
- return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'PUT', path }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
236
+ return _fetch(this.#merge(await this.#getDefs(), {
237
+ ...(fetchParams || {}),
238
+ data,
239
+ method: "PUT",
240
+ path,
241
+ }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
227
242
  }
228
243
  async patch(path, dataOrOptions, params, respHeaders, errorMessageExtractor, _dumpParams = false) {
229
- const { data, params: fetchParams, respHeaders: headers, errorExtractor } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
244
+ const { data, params: fetchParams, respHeaders: headers, errorExtractor, } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
230
245
  path = this.#buildPath(path, this.#base);
231
- return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'PATCH', path }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
246
+ return _fetch(this.#merge(await this.#getDefs(), {
247
+ ...(fetchParams || {}),
248
+ data,
249
+ method: "PATCH",
250
+ path,
251
+ }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
232
252
  }
233
253
  async del(path, dataOrOptions, params, respHeaders, errorMessageExtractor, _dumpParams = false) {
234
- const { data, params: fetchParams, respHeaders: headers, errorExtractor } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
254
+ const { data, params: fetchParams, respHeaders: headers, errorExtractor, } = parseDataOptions(dataOrOptions, params, respHeaders, errorMessageExtractor);
235
255
  path = this.#buildPath(path, this.#base);
236
- return _fetch(this.#merge(await this.#getDefs(), { ...(fetchParams || {}), data, method: 'DELETE', path }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
256
+ return _fetch(this.#merge(await this.#getDefs(), {
257
+ ...(fetchParams || {}),
258
+ data,
259
+ method: "DELETE",
260
+ path,
261
+ }), headers, errorExtractor ?? this.#factoryErrorMessageExtractor, _dumpParams);
237
262
  }
238
263
  /**
239
264
  * Helper method to build the full URL from a path.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/http-utils",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "type": "module",
5
5
  "main": "dist/mod.js",
6
6
  "types": "dist/mod.d.ts",