@blimu/fetch
Advanced tools
+70
-19
@@ -571,3 +571,16 @@ "use strict"; | ||
| } | ||
| const url = new URL(normalizedPath, baseUrl); | ||
| let normalizedBaseUrl = baseUrl || ""; | ||
| if (normalizedBaseUrl) { | ||
| try { | ||
| const baseUrlObj = new URL(normalizedBaseUrl); | ||
| if (baseUrlObj.pathname && baseUrlObj.pathname !== "/" && !normalizedBaseUrl.endsWith("/")) { | ||
| normalizedBaseUrl = normalizedBaseUrl + "/"; | ||
| } | ||
| } catch { | ||
| } | ||
| } | ||
| if (normalizedPath.startsWith("/")) { | ||
| normalizedPath = normalizedPath.slice(1); | ||
| } | ||
| const url = new URL(normalizedPath, normalizedBaseUrl); | ||
| if (query) { | ||
@@ -610,3 +623,3 @@ const params = serializeQueryParams(query); | ||
| __name(getContentType, "getContentType"); | ||
| function serializeBody(body) { | ||
| function serializeBody(body, contentType) { | ||
| if (body === null || body === void 0) { | ||
@@ -618,2 +631,17 @@ return null; | ||
| } | ||
| if (contentType === "application/x-www-form-urlencoded" && typeof body === "object" && body !== null && !Array.isArray(body)) { | ||
| const params = new URLSearchParams(); | ||
| for (const [key, value] of Object.entries(body)) { | ||
| if (value !== null && value !== void 0) { | ||
| if (Array.isArray(value)) { | ||
| for (const item of value) { | ||
| params.append(key, String(item)); | ||
| } | ||
| } else { | ||
| params.append(key, String(value)); | ||
| } | ||
| } | ||
| } | ||
| return params; | ||
| } | ||
| if (typeof body === "object") { | ||
@@ -702,11 +730,23 @@ return JSON.stringify(body); | ||
| let url = buildUrl(this.cfg.baseURL || "", init.path, init.query); | ||
| const headers = new Headers({ | ||
| ...this.cfg.headers || {}, | ||
| ...init.headers | ||
| }); | ||
| const headers = new Headers(this.cfg.headers || {}); | ||
| if (init.headers) { | ||
| if (init.headers instanceof Headers) { | ||
| init.headers.forEach((value, key) => { | ||
| headers.set(key, value); | ||
| }); | ||
| } else { | ||
| Object.entries(init.headers).forEach(([key, value]) => { | ||
| headers.set(key, String(value)); | ||
| }); | ||
| } | ||
| } | ||
| await this.applyAuthentication(headers, url); | ||
| let bodyContentType; | ||
| if (init.body !== void 0) { | ||
| const contentType = getContentType(init.body); | ||
| if (contentType && !headers.has("Content-Type")) { | ||
| headers.set("Content-Type", contentType); | ||
| bodyContentType = headers.get("Content-Type") || void 0; | ||
| if (!bodyContentType) { | ||
| bodyContentType = getContentType(init.body); | ||
| if (bodyContentType) { | ||
| headers.set("Content-Type", bodyContentType); | ||
| } | ||
| } | ||
@@ -730,3 +770,3 @@ } | ||
| await this.applyAuthentication(attemptHeaders, attemptUrl); | ||
| return await this.doRequest(attemptUrl, init, attemptHeaders, attempt); | ||
| return await this.doRequest(attemptUrl, init, attemptHeaders, attempt, bodyContentType); | ||
| } catch (err) { | ||
@@ -775,13 +815,24 @@ lastError = err; | ||
| let url = buildUrl(this.cfg.baseURL || "", init.path, init.query); | ||
| const headers = new Headers({ | ||
| ...this.cfg.headers || {}, | ||
| ...init.headers | ||
| }); | ||
| const headers = new Headers(this.cfg.headers || {}); | ||
| if (init.headers) { | ||
| if (init.headers instanceof Headers) { | ||
| init.headers.forEach((value, key) => { | ||
| headers.set(key, value); | ||
| }); | ||
| } else { | ||
| Object.entries(init.headers).forEach(([key, value]) => { | ||
| headers.set(key, String(value)); | ||
| }); | ||
| } | ||
| } | ||
| await this.applyAuthentication(headers, url); | ||
| if (init.contentType && !headers.has("Content-Type")) { | ||
| headers.set("Content-Type", init.contentType); | ||
| let bodyContentType = headers.get("Content-Type") || void 0; | ||
| if (init.contentType && !bodyContentType) { | ||
| bodyContentType = init.contentType; | ||
| headers.set("Content-Type", bodyContentType); | ||
| } | ||
| const fetchInit = { | ||
| ...init, | ||
| headers | ||
| headers, | ||
| body: serializeBody(init.body, bodyContentType) | ||
| }; | ||
@@ -925,3 +976,3 @@ if (this.cfg.credentials !== void 0) { | ||
| */ | ||
| async doRequest(url, init, baseHeaders, attempt) { | ||
| async doRequest(url, init, baseHeaders, attempt, contentType) { | ||
| const requestHeaders = baseHeaders; | ||
@@ -931,3 +982,3 @@ const fetchInit = { | ||
| headers: requestHeaders, | ||
| body: serializeBody(init.body) | ||
| body: serializeBody(init.body, contentType) | ||
| }; | ||
@@ -934,0 +985,0 @@ if (this.cfg.credentials !== void 0) { |
+2
-1
@@ -488,5 +488,6 @@ /** | ||
| * @param body - Request body to serialize | ||
| * @param contentType - Optional content type hint to guide serialization | ||
| * @returns Serialized body (string, FormData, Blob, ArrayBuffer, etc.) | ||
| */ | ||
| declare function serializeBody(body: unknown): RequestInit["body"] | null; | ||
| declare function serializeBody(body: unknown, contentType?: string): RequestInit['body'] | null; | ||
@@ -493,0 +494,0 @@ /** |
+2
-1
@@ -488,5 +488,6 @@ /** | ||
| * @param body - Request body to serialize | ||
| * @param contentType - Optional content type hint to guide serialization | ||
| * @returns Serialized body (string, FormData, Blob, ArrayBuffer, etc.) | ||
| */ | ||
| declare function serializeBody(body: unknown): RequestInit["body"] | null; | ||
| declare function serializeBody(body: unknown, contentType?: string): RequestInit['body'] | null; | ||
@@ -493,0 +494,0 @@ /** |
+70
-19
@@ -511,3 +511,16 @@ var __defProp = Object.defineProperty; | ||
| } | ||
| const url = new URL(normalizedPath, baseUrl); | ||
| let normalizedBaseUrl = baseUrl || ""; | ||
| if (normalizedBaseUrl) { | ||
| try { | ||
| const baseUrlObj = new URL(normalizedBaseUrl); | ||
| if (baseUrlObj.pathname && baseUrlObj.pathname !== "/" && !normalizedBaseUrl.endsWith("/")) { | ||
| normalizedBaseUrl = normalizedBaseUrl + "/"; | ||
| } | ||
| } catch { | ||
| } | ||
| } | ||
| if (normalizedPath.startsWith("/")) { | ||
| normalizedPath = normalizedPath.slice(1); | ||
| } | ||
| const url = new URL(normalizedPath, normalizedBaseUrl); | ||
| if (query) { | ||
@@ -550,3 +563,3 @@ const params = serializeQueryParams(query); | ||
| __name(getContentType, "getContentType"); | ||
| function serializeBody(body) { | ||
| function serializeBody(body, contentType) { | ||
| if (body === null || body === void 0) { | ||
@@ -558,2 +571,17 @@ return null; | ||
| } | ||
| if (contentType === "application/x-www-form-urlencoded" && typeof body === "object" && body !== null && !Array.isArray(body)) { | ||
| const params = new URLSearchParams(); | ||
| for (const [key, value] of Object.entries(body)) { | ||
| if (value !== null && value !== void 0) { | ||
| if (Array.isArray(value)) { | ||
| for (const item of value) { | ||
| params.append(key, String(item)); | ||
| } | ||
| } else { | ||
| params.append(key, String(value)); | ||
| } | ||
| } | ||
| } | ||
| return params; | ||
| } | ||
| if (typeof body === "object") { | ||
@@ -642,11 +670,23 @@ return JSON.stringify(body); | ||
| let url = buildUrl(this.cfg.baseURL || "", init.path, init.query); | ||
| const headers = new Headers({ | ||
| ...this.cfg.headers || {}, | ||
| ...init.headers | ||
| }); | ||
| const headers = new Headers(this.cfg.headers || {}); | ||
| if (init.headers) { | ||
| if (init.headers instanceof Headers) { | ||
| init.headers.forEach((value, key) => { | ||
| headers.set(key, value); | ||
| }); | ||
| } else { | ||
| Object.entries(init.headers).forEach(([key, value]) => { | ||
| headers.set(key, String(value)); | ||
| }); | ||
| } | ||
| } | ||
| await this.applyAuthentication(headers, url); | ||
| let bodyContentType; | ||
| if (init.body !== void 0) { | ||
| const contentType = getContentType(init.body); | ||
| if (contentType && !headers.has("Content-Type")) { | ||
| headers.set("Content-Type", contentType); | ||
| bodyContentType = headers.get("Content-Type") || void 0; | ||
| if (!bodyContentType) { | ||
| bodyContentType = getContentType(init.body); | ||
| if (bodyContentType) { | ||
| headers.set("Content-Type", bodyContentType); | ||
| } | ||
| } | ||
@@ -670,3 +710,3 @@ } | ||
| await this.applyAuthentication(attemptHeaders, attemptUrl); | ||
| return await this.doRequest(attemptUrl, init, attemptHeaders, attempt); | ||
| return await this.doRequest(attemptUrl, init, attemptHeaders, attempt, bodyContentType); | ||
| } catch (err) { | ||
@@ -715,13 +755,24 @@ lastError = err; | ||
| let url = buildUrl(this.cfg.baseURL || "", init.path, init.query); | ||
| const headers = new Headers({ | ||
| ...this.cfg.headers || {}, | ||
| ...init.headers | ||
| }); | ||
| const headers = new Headers(this.cfg.headers || {}); | ||
| if (init.headers) { | ||
| if (init.headers instanceof Headers) { | ||
| init.headers.forEach((value, key) => { | ||
| headers.set(key, value); | ||
| }); | ||
| } else { | ||
| Object.entries(init.headers).forEach(([key, value]) => { | ||
| headers.set(key, String(value)); | ||
| }); | ||
| } | ||
| } | ||
| await this.applyAuthentication(headers, url); | ||
| if (init.contentType && !headers.has("Content-Type")) { | ||
| headers.set("Content-Type", init.contentType); | ||
| let bodyContentType = headers.get("Content-Type") || void 0; | ||
| if (init.contentType && !bodyContentType) { | ||
| bodyContentType = init.contentType; | ||
| headers.set("Content-Type", bodyContentType); | ||
| } | ||
| const fetchInit = { | ||
| ...init, | ||
| headers | ||
| headers, | ||
| body: serializeBody(init.body, bodyContentType) | ||
| }; | ||
@@ -865,3 +916,3 @@ if (this.cfg.credentials !== void 0) { | ||
| */ | ||
| async doRequest(url, init, baseHeaders, attempt) { | ||
| async doRequest(url, init, baseHeaders, attempt, contentType) { | ||
| const requestHeaders = baseHeaders; | ||
@@ -871,3 +922,3 @@ const fetchInit = { | ||
| headers: requestHeaders, | ||
| body: serializeBody(init.body) | ||
| body: serializeBody(init.body, contentType) | ||
| }; | ||
@@ -874,0 +925,0 @@ if (this.cfg.credentials !== void 0) { |
+1
-1
| { | ||
| "name": "@blimu/fetch", | ||
| "version": "0.1.0", | ||
| "version": "0.2.0", | ||
| "description": "Universal HTTP fetch client with hooks, retries, and streaming support for browser and Node.js", | ||
@@ -5,0 +5,0 @@ "type": "module", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
239681
5.59%2782
3.84%