react-ultra-fetch 1.0.4 → 1.0.6

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.js CHANGED
@@ -135,10 +135,11 @@ var Methods = class {
135
135
  ...fBody === void 0 ? {} : { body: fBody },
136
136
  credentials: options.cookie ? "include" : "same-origin"
137
137
  });
138
+ const clone = res.clone();
138
139
  const parse = await parserResponse_default(res);
139
140
  if (!res.ok) {
140
141
  const status = res.status;
141
- const text = await res.clone().text();
142
+ const text = await clone.text();
142
143
  const contentType = res.headers.get("content-type") ?? "";
143
144
  const message = parseServerError_default({ status, contentType, text });
144
145
  return { success: false, error: message, status: res.status };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/shared/UltraFetchError.ts","../src/useFetch.tsx","../src/utils/body.ts","../src/utils/headers.ts","../src/utils/parserError.ts","../src/utils/parserResponse.ts","../src/utils/parseServerError.ts","../src/methods.ts"],"sourcesContent":["export { useFetch } from \"@/useFetch\";\r\n","class UltraFetchError extends Error {\r\n constructor(text: string, status?: number) {\r\n super(text);\r\n this.name = \"UltraFetchError\";\r\n Object.setPrototypeOf(this, UltraFetchError.prototype);\r\n }\r\n}\r\n\r\nexport default UltraFetchError;\r\n","import type { fetchDataProps, useFetchProps, useResults } from \"@/types\";\r\nimport UltraFetchError from \"@/shared/UltraFetchError\";\r\nimport { useCallback, useState } from \"react\";\r\nimport Methods from \"@/methods\";\r\n\r\nconst METHODS = [\"POST\", \"GET\", \"DEL\", \"PUT\"] as const;\r\n\r\nconst useFetch = <T, E = unknown>(url: string): useFetchProps<T, E> => {\r\n if (!url || typeof url !== \"string\") {\r\n throw new UltraFetchError(\r\n \"URL is required and must be a non-empty string.\",\r\n );\r\n }\r\n const [loading, setLoading] = useState<boolean>(false);\r\n const [error, setError] = useState<E | null>(null);\r\n const [data, setData] = useState<T | null>(null);\r\n\r\n const fetchData = useCallback(\r\n async (options?: fetchDataProps) => {\r\n const opts = options ?? {};\r\n\r\n const body = opts.body;\r\n const headers = opts.headers ?? {};\r\n const cookie = opts.cookie ?? false;\r\n const method = opts.method ?? \"POST\";\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n const client = new Methods(url);\r\n let results: useResults<T, E>;\r\n\r\n try {\r\n switch (method) {\r\n case \"POST\":\r\n results = await client.Post<T, E>({ headers, body, cookie });\r\n break;\r\n default: {\r\n const text = `Unsupported HTTP method: \"${method}\". Supported methods: ${METHODS.join(\", \")}.`;\r\n throw new UltraFetchError(text);\r\n }\r\n }\r\n\r\n if (results.success) {\r\n setData(results.data ?? null);\r\n } else {\r\n setError(results.error ?? null);\r\n }\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : \"Unknown error\";\r\n setError(message as unknown as E);\r\n } finally {\r\n setLoading(false);\r\n }\r\n },\r\n [url],\r\n );\r\n\r\n return { loading, error, data, fetchData };\r\n};\r\n\r\nexport { useFetch };\r\n","const Body = (body: unknown) => {\r\n if (body instanceof FormData || typeof body === \"string\") return body;\r\n if (body === null || body === undefined) return undefined;\r\n return JSON.stringify(body);\r\n};\r\n\r\nexport default Body;\r\n","const Headers = (body: unknown) => {\r\n if (body instanceof FormData) return {};\r\n if (typeof body === \"object\") return { \"Content-Type\": \"application/json\" };\r\n if (typeof body === \"string\") return { \"Content-Type\": \"text/plain\" };\r\n return {};\r\n};\r\n\r\nexport default Headers;\r\n","const parserError = (err: unknown): string => {\r\n if (err instanceof DOMException && err.name === \"AbortError\") {\r\n return \"The request has been canceled or timed out.\";\r\n }\r\n\r\n if (err instanceof TypeError) {\r\n const msg = err.message.toLowerCase();\r\n\r\n if (msg.includes(\"failed to fetch\")) {\r\n return \"Unable to connect to the server. Check your internet connection or the server address (URL).\";\r\n }\r\n\r\n if (msg.includes(\"networkerror\")) {\r\n return \"A network error has occurred. The server may be down or malfunctioning due to CORS.\";\r\n }\r\n\r\n if (msg.includes(\"load failed\")) {\r\n return \"The request failed. Check the URL or server status.\";\r\n }\r\n }\r\n\r\n if (err instanceof SyntaxError) {\r\n return \"Unable to read response from server (invalid format).\";\r\n }\r\n\r\n if (err instanceof Error) {\r\n return err.message;\r\n }\r\n\r\n return \"An unknown error occurred.\";\r\n};\r\n\r\nexport default parserError;\r\n","const parserResponse = async (res: Response) => {\r\n const contentType = res.headers.get(\"content-type\") ?? \"\";\r\n\r\n const text = await res.text();\r\n if (!text) return null;\r\n\r\n if (contentType.includes(\"application/json\")) {\r\n try {\r\n return JSON.parse(text);\r\n } catch (err) {\r\n return text;\r\n }\r\n }\r\n\r\n try {\r\n return JSON.parse(text);\r\n } catch (err) {\r\n return text;\r\n }\r\n};\r\n\r\nexport default parserResponse;\r\n","interface parserErrorOptions {\r\n status: number;\r\n contentType: string;\r\n text: string;\r\n}\r\n\r\nconst isHtmlError = (contentType: string, text: string): boolean => {\r\n return (\r\n contentType.includes(\"text/html\") || text.trim().startsWith(\"<DOCTYPE\")\r\n );\r\n};\r\n\r\nconst parserServerError = (options: parserErrorOptions): string => {\r\n if (isHtmlError(options.contentType, options.text)) {\r\n if (options.status === 404) {\r\n return \"The requested address was not found (404). The URL or route may be invalid.\";\r\n }\r\n if (options.status >= 500) {\r\n return `An internal error occurred on the server (${options.status}).`;\r\n }\r\n return \"Check the backend route or address.\";\r\n }\r\n\r\n return options.text;\r\n};\r\n\r\nexport default parserServerError;\r\n","import Body from \"@/utils/body\";\r\nimport Headers from \"@/utils/headers\";\r\nimport parserError from \"@/utils/parserError\";\r\nimport parserResponse from \"@/utils/parserResponse\";\r\nimport type { MethodsPostProps, useResults } from \"@/types\";\r\nimport parserServerError from \"./utils/parseServerError\";\r\n\r\nclass Methods {\r\n constructor(public url: string) {}\r\n\r\n async Post<T = unknown, E = unknown>(\r\n options: MethodsPostProps,\r\n ): Promise<useResults<T, E>> {\r\n const fHeaders = { ...Headers(options.body), ...options.headers };\r\n const fBody = Body(options.body);\r\n\r\n try {\r\n const res = await fetch(this.url, {\r\n method: \"POST\",\r\n headers: fHeaders,\r\n ...(fBody === undefined ? {} : { body: fBody }),\r\n credentials: options.cookie ? \"include\" : \"same-origin\",\r\n });\r\n\r\n const parse = await parserResponse(res);\r\n\r\n if (!res.ok) {\r\n const status = res.status;\r\n const text = await res.clone().text();\r\n const contentType = res.headers.get(\"content-type\") ?? \"\";\r\n const message = parserServerError({ status, contentType, text });\r\n return { success: false, error: message as E, status: res.status };\r\n }\r\n\r\n return { success: res.ok, data: parse as T, status: res.status };\r\n } catch (err) {\r\n const message = parserError(err);\r\n return { success: false, error: message as E };\r\n }\r\n }\r\n}\r\n\r\nexport default Methods;\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/shared/UltraFetchError.ts","../src/useFetch.tsx","../src/utils/body.ts","../src/utils/headers.ts","../src/utils/parserError.ts","../src/utils/parserResponse.ts","../src/utils/parseServerError.ts","../src/methods.ts"],"sourcesContent":["export { useFetch } from \"@/useFetch\";\r\n","class UltraFetchError extends Error {\r\n constructor(text: string, status?: number) {\r\n super(text);\r\n this.name = \"UltraFetchError\";\r\n Object.setPrototypeOf(this, UltraFetchError.prototype);\r\n }\r\n}\r\n\r\nexport default UltraFetchError;\r\n","import type { fetchDataProps, useFetchProps, useResults } from \"@/types\";\r\nimport UltraFetchError from \"@/shared/UltraFetchError\";\r\nimport { useCallback, useState } from \"react\";\r\nimport Methods from \"@/methods\";\r\n\r\nconst METHODS = [\"POST\", \"GET\", \"DEL\", \"PUT\"] as const;\r\n\r\nconst useFetch = <T, E = unknown>(url: string): useFetchProps<T, E> => {\r\n if (!url || typeof url !== \"string\") {\r\n throw new UltraFetchError(\r\n \"URL is required and must be a non-empty string.\",\r\n );\r\n }\r\n const [loading, setLoading] = useState<boolean>(false);\r\n const [error, setError] = useState<E | null>(null);\r\n const [data, setData] = useState<T | null>(null);\r\n\r\n const fetchData = useCallback(\r\n async (options?: fetchDataProps) => {\r\n const opts = options ?? {};\r\n\r\n const body = opts.body;\r\n const headers = opts.headers ?? {};\r\n const cookie = opts.cookie ?? false;\r\n const method = opts.method ?? \"POST\";\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n const client = new Methods(url);\r\n let results: useResults<T, E>;\r\n\r\n try {\r\n switch (method) {\r\n case \"POST\":\r\n results = await client.Post<T, E>({ headers, body, cookie });\r\n break;\r\n default: {\r\n const text = `Unsupported HTTP method: \"${method}\". Supported methods: ${METHODS.join(\", \")}.`;\r\n throw new UltraFetchError(text);\r\n }\r\n }\r\n\r\n if (results.success) {\r\n setData(results.data ?? null);\r\n } else {\r\n setError(results.error ?? null);\r\n }\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : \"Unknown error\";\r\n setError(message as unknown as E);\r\n } finally {\r\n setLoading(false);\r\n }\r\n },\r\n [url],\r\n );\r\n\r\n return { loading, error, data, fetchData };\r\n};\r\n\r\nexport { useFetch };\r\n","const Body = (body: unknown) => {\r\n if (body instanceof FormData || typeof body === \"string\") return body;\r\n if (body === null || body === undefined) return undefined;\r\n return JSON.stringify(body);\r\n};\r\n\r\nexport default Body;\r\n","const Headers = (body: unknown) => {\r\n if (body instanceof FormData) return {};\r\n if (typeof body === \"object\") return { \"Content-Type\": \"application/json\" };\r\n if (typeof body === \"string\") return { \"Content-Type\": \"text/plain\" };\r\n return {};\r\n};\r\n\r\nexport default Headers;\r\n","const parserError = (err: unknown): string => {\r\n if (err instanceof DOMException && err.name === \"AbortError\") {\r\n return \"The request has been canceled or timed out.\";\r\n }\r\n\r\n if (err instanceof TypeError) {\r\n const msg = err.message.toLowerCase();\r\n\r\n if (msg.includes(\"failed to fetch\")) {\r\n return \"Unable to connect to the server. Check your internet connection or the server address (URL).\";\r\n }\r\n\r\n if (msg.includes(\"networkerror\")) {\r\n return \"A network error has occurred. The server may be down or malfunctioning due to CORS.\";\r\n }\r\n\r\n if (msg.includes(\"load failed\")) {\r\n return \"The request failed. Check the URL or server status.\";\r\n }\r\n }\r\n\r\n if (err instanceof SyntaxError) {\r\n return \"Unable to read response from server (invalid format).\";\r\n }\r\n\r\n if (err instanceof Error) {\r\n return err.message;\r\n }\r\n\r\n return \"An unknown error occurred.\";\r\n};\r\n\r\nexport default parserError;\r\n","const parserResponse = async (res: Response) => {\r\n const contentType = res.headers.get(\"content-type\") ?? \"\";\r\n\r\n const text = await res.text();\r\n if (!text) return null;\r\n\r\n if (contentType.includes(\"application/json\")) {\r\n try {\r\n return JSON.parse(text);\r\n } catch (err) {\r\n return text;\r\n }\r\n }\r\n\r\n try {\r\n return JSON.parse(text);\r\n } catch (err) {\r\n return text;\r\n }\r\n};\r\n\r\nexport default parserResponse;\r\n","interface parserErrorOptions {\r\n status: number;\r\n contentType: string;\r\n text: string;\r\n}\r\n\r\nconst isHtmlError = (contentType: string, text: string): boolean => {\r\n return (\r\n contentType.includes(\"text/html\") || text.trim().startsWith(\"<DOCTYPE\")\r\n );\r\n};\r\n\r\nconst parserServerError = (options: parserErrorOptions): string => {\r\n if (isHtmlError(options.contentType, options.text)) {\r\n if (options.status === 404) {\r\n return \"The requested address was not found (404). The URL or route may be invalid.\";\r\n }\r\n if (options.status >= 500) {\r\n return `An internal error occurred on the server (${options.status}).`;\r\n }\r\n return \"Check the backend route or address.\";\r\n }\r\n\r\n return options.text;\r\n};\r\n\r\nexport default parserServerError;\r\n","import Body from \"@/utils/body\";\r\nimport Headers from \"@/utils/headers\";\r\nimport parserError from \"@/utils/parserError\";\r\nimport parserResponse from \"@/utils/parserResponse\";\r\nimport type { MethodsPostProps, useResults } from \"@/types\";\r\nimport parserServerError from \"./utils/parseServerError\";\r\n\r\nclass Methods {\r\n constructor(public url: string) {}\r\n\r\n async Post<T = unknown, E = unknown>(\r\n options: MethodsPostProps,\r\n ): Promise<useResults<T, E>> {\r\n const fHeaders = { ...Headers(options.body), ...options.headers };\r\n const fBody = Body(options.body);\r\n\r\n try {\r\n const res = await fetch(this.url, {\r\n method: \"POST\",\r\n headers: fHeaders,\r\n ...(fBody === undefined ? {} : { body: fBody }),\r\n credentials: options.cookie ? \"include\" : \"same-origin\",\r\n });\r\n\r\n const clone = res.clone();\r\n const parse = await parserResponse(res);\r\n\r\n if (!res.ok) {\r\n const status = res.status;\r\n const text = await clone.text();\r\n const contentType = res.headers.get(\"content-type\") ?? \"\";\r\n const message = parserServerError({ status, contentType, text });\r\n return { success: false, error: message as E, status: res.status };\r\n }\r\n\r\n return { success: res.ok, data: parse as T, status: res.status };\r\n } catch (err) {\r\n const message = parserError(err);\r\n return { success: false, error: message as E };\r\n }\r\n }\r\n}\r\n\r\nexport default Methods;\r\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -109,10 +109,11 @@ var Methods = class {
109
109
  ...fBody === void 0 ? {} : { body: fBody },
110
110
  credentials: options.cookie ? "include" : "same-origin"
111
111
  });
112
+ const clone = res.clone();
112
113
  const parse = await parserResponse_default(res);
113
114
  if (!res.ok) {
114
115
  const status = res.status;
115
- const text = await res.clone().text();
116
+ const text = await clone.text();
116
117
  const contentType = res.headers.get("content-type") ?? "";
117
118
  const message = parseServerError_default({ status, contentType, text });
118
119
  return { success: false, error: message, status: res.status };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/UltraFetchError.ts","../src/useFetch.tsx","../src/utils/body.ts","../src/utils/headers.ts","../src/utils/parserError.ts","../src/utils/parserResponse.ts","../src/utils/parseServerError.ts","../src/methods.ts"],"sourcesContent":["class UltraFetchError extends Error {\r\n constructor(text: string, status?: number) {\r\n super(text);\r\n this.name = \"UltraFetchError\";\r\n Object.setPrototypeOf(this, UltraFetchError.prototype);\r\n }\r\n}\r\n\r\nexport default UltraFetchError;\r\n","import type { fetchDataProps, useFetchProps, useResults } from \"@/types\";\r\nimport UltraFetchError from \"@/shared/UltraFetchError\";\r\nimport { useCallback, useState } from \"react\";\r\nimport Methods from \"@/methods\";\r\n\r\nconst METHODS = [\"POST\", \"GET\", \"DEL\", \"PUT\"] as const;\r\n\r\nconst useFetch = <T, E = unknown>(url: string): useFetchProps<T, E> => {\r\n if (!url || typeof url !== \"string\") {\r\n throw new UltraFetchError(\r\n \"URL is required and must be a non-empty string.\",\r\n );\r\n }\r\n const [loading, setLoading] = useState<boolean>(false);\r\n const [error, setError] = useState<E | null>(null);\r\n const [data, setData] = useState<T | null>(null);\r\n\r\n const fetchData = useCallback(\r\n async (options?: fetchDataProps) => {\r\n const opts = options ?? {};\r\n\r\n const body = opts.body;\r\n const headers = opts.headers ?? {};\r\n const cookie = opts.cookie ?? false;\r\n const method = opts.method ?? \"POST\";\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n const client = new Methods(url);\r\n let results: useResults<T, E>;\r\n\r\n try {\r\n switch (method) {\r\n case \"POST\":\r\n results = await client.Post<T, E>({ headers, body, cookie });\r\n break;\r\n default: {\r\n const text = `Unsupported HTTP method: \"${method}\". Supported methods: ${METHODS.join(\", \")}.`;\r\n throw new UltraFetchError(text);\r\n }\r\n }\r\n\r\n if (results.success) {\r\n setData(results.data ?? null);\r\n } else {\r\n setError(results.error ?? null);\r\n }\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : \"Unknown error\";\r\n setError(message as unknown as E);\r\n } finally {\r\n setLoading(false);\r\n }\r\n },\r\n [url],\r\n );\r\n\r\n return { loading, error, data, fetchData };\r\n};\r\n\r\nexport { useFetch };\r\n","const Body = (body: unknown) => {\r\n if (body instanceof FormData || typeof body === \"string\") return body;\r\n if (body === null || body === undefined) return undefined;\r\n return JSON.stringify(body);\r\n};\r\n\r\nexport default Body;\r\n","const Headers = (body: unknown) => {\r\n if (body instanceof FormData) return {};\r\n if (typeof body === \"object\") return { \"Content-Type\": \"application/json\" };\r\n if (typeof body === \"string\") return { \"Content-Type\": \"text/plain\" };\r\n return {};\r\n};\r\n\r\nexport default Headers;\r\n","const parserError = (err: unknown): string => {\r\n if (err instanceof DOMException && err.name === \"AbortError\") {\r\n return \"The request has been canceled or timed out.\";\r\n }\r\n\r\n if (err instanceof TypeError) {\r\n const msg = err.message.toLowerCase();\r\n\r\n if (msg.includes(\"failed to fetch\")) {\r\n return \"Unable to connect to the server. Check your internet connection or the server address (URL).\";\r\n }\r\n\r\n if (msg.includes(\"networkerror\")) {\r\n return \"A network error has occurred. The server may be down or malfunctioning due to CORS.\";\r\n }\r\n\r\n if (msg.includes(\"load failed\")) {\r\n return \"The request failed. Check the URL or server status.\";\r\n }\r\n }\r\n\r\n if (err instanceof SyntaxError) {\r\n return \"Unable to read response from server (invalid format).\";\r\n }\r\n\r\n if (err instanceof Error) {\r\n return err.message;\r\n }\r\n\r\n return \"An unknown error occurred.\";\r\n};\r\n\r\nexport default parserError;\r\n","const parserResponse = async (res: Response) => {\r\n const contentType = res.headers.get(\"content-type\") ?? \"\";\r\n\r\n const text = await res.text();\r\n if (!text) return null;\r\n\r\n if (contentType.includes(\"application/json\")) {\r\n try {\r\n return JSON.parse(text);\r\n } catch (err) {\r\n return text;\r\n }\r\n }\r\n\r\n try {\r\n return JSON.parse(text);\r\n } catch (err) {\r\n return text;\r\n }\r\n};\r\n\r\nexport default parserResponse;\r\n","interface parserErrorOptions {\r\n status: number;\r\n contentType: string;\r\n text: string;\r\n}\r\n\r\nconst isHtmlError = (contentType: string, text: string): boolean => {\r\n return (\r\n contentType.includes(\"text/html\") || text.trim().startsWith(\"<DOCTYPE\")\r\n );\r\n};\r\n\r\nconst parserServerError = (options: parserErrorOptions): string => {\r\n if (isHtmlError(options.contentType, options.text)) {\r\n if (options.status === 404) {\r\n return \"The requested address was not found (404). The URL or route may be invalid.\";\r\n }\r\n if (options.status >= 500) {\r\n return `An internal error occurred on the server (${options.status}).`;\r\n }\r\n return \"Check the backend route or address.\";\r\n }\r\n\r\n return options.text;\r\n};\r\n\r\nexport default parserServerError;\r\n","import Body from \"@/utils/body\";\r\nimport Headers from \"@/utils/headers\";\r\nimport parserError from \"@/utils/parserError\";\r\nimport parserResponse from \"@/utils/parserResponse\";\r\nimport type { MethodsPostProps, useResults } from \"@/types\";\r\nimport parserServerError from \"./utils/parseServerError\";\r\n\r\nclass Methods {\r\n constructor(public url: string) {}\r\n\r\n async Post<T = unknown, E = unknown>(\r\n options: MethodsPostProps,\r\n ): Promise<useResults<T, E>> {\r\n const fHeaders = { ...Headers(options.body), ...options.headers };\r\n const fBody = Body(options.body);\r\n\r\n try {\r\n const res = await fetch(this.url, {\r\n method: \"POST\",\r\n headers: fHeaders,\r\n ...(fBody === undefined ? {} : { body: fBody }),\r\n credentials: options.cookie ? \"include\" : \"same-origin\",\r\n });\r\n\r\n const parse = await parserResponse(res);\r\n\r\n if (!res.ok) {\r\n const status = res.status;\r\n const text = await res.clone().text();\r\n const contentType = res.headers.get(\"content-type\") ?? \"\";\r\n const message = parserServerError({ status, contentType, text });\r\n return { success: false, error: message as E, status: res.status };\r\n }\r\n\r\n return { success: res.ok, data: parse as T, status: res.status };\r\n } catch (err) {\r\n const message = parserError(err);\r\n return { success: false, error: message as E };\r\n }\r\n }\r\n}\r\n\r\nexport default Methods;\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/shared/UltraFetchError.ts","../src/useFetch.tsx","../src/utils/body.ts","../src/utils/headers.ts","../src/utils/parserError.ts","../src/utils/parserResponse.ts","../src/utils/parseServerError.ts","../src/methods.ts"],"sourcesContent":["class UltraFetchError extends Error {\r\n constructor(text: string, status?: number) {\r\n super(text);\r\n this.name = \"UltraFetchError\";\r\n Object.setPrototypeOf(this, UltraFetchError.prototype);\r\n }\r\n}\r\n\r\nexport default UltraFetchError;\r\n","import type { fetchDataProps, useFetchProps, useResults } from \"@/types\";\r\nimport UltraFetchError from \"@/shared/UltraFetchError\";\r\nimport { useCallback, useState } from \"react\";\r\nimport Methods from \"@/methods\";\r\n\r\nconst METHODS = [\"POST\", \"GET\", \"DEL\", \"PUT\"] as const;\r\n\r\nconst useFetch = <T, E = unknown>(url: string): useFetchProps<T, E> => {\r\n if (!url || typeof url !== \"string\") {\r\n throw new UltraFetchError(\r\n \"URL is required and must be a non-empty string.\",\r\n );\r\n }\r\n const [loading, setLoading] = useState<boolean>(false);\r\n const [error, setError] = useState<E | null>(null);\r\n const [data, setData] = useState<T | null>(null);\r\n\r\n const fetchData = useCallback(\r\n async (options?: fetchDataProps) => {\r\n const opts = options ?? {};\r\n\r\n const body = opts.body;\r\n const headers = opts.headers ?? {};\r\n const cookie = opts.cookie ?? false;\r\n const method = opts.method ?? \"POST\";\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n const client = new Methods(url);\r\n let results: useResults<T, E>;\r\n\r\n try {\r\n switch (method) {\r\n case \"POST\":\r\n results = await client.Post<T, E>({ headers, body, cookie });\r\n break;\r\n default: {\r\n const text = `Unsupported HTTP method: \"${method}\". Supported methods: ${METHODS.join(\", \")}.`;\r\n throw new UltraFetchError(text);\r\n }\r\n }\r\n\r\n if (results.success) {\r\n setData(results.data ?? null);\r\n } else {\r\n setError(results.error ?? null);\r\n }\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : \"Unknown error\";\r\n setError(message as unknown as E);\r\n } finally {\r\n setLoading(false);\r\n }\r\n },\r\n [url],\r\n );\r\n\r\n return { loading, error, data, fetchData };\r\n};\r\n\r\nexport { useFetch };\r\n","const Body = (body: unknown) => {\r\n if (body instanceof FormData || typeof body === \"string\") return body;\r\n if (body === null || body === undefined) return undefined;\r\n return JSON.stringify(body);\r\n};\r\n\r\nexport default Body;\r\n","const Headers = (body: unknown) => {\r\n if (body instanceof FormData) return {};\r\n if (typeof body === \"object\") return { \"Content-Type\": \"application/json\" };\r\n if (typeof body === \"string\") return { \"Content-Type\": \"text/plain\" };\r\n return {};\r\n};\r\n\r\nexport default Headers;\r\n","const parserError = (err: unknown): string => {\r\n if (err instanceof DOMException && err.name === \"AbortError\") {\r\n return \"The request has been canceled or timed out.\";\r\n }\r\n\r\n if (err instanceof TypeError) {\r\n const msg = err.message.toLowerCase();\r\n\r\n if (msg.includes(\"failed to fetch\")) {\r\n return \"Unable to connect to the server. Check your internet connection or the server address (URL).\";\r\n }\r\n\r\n if (msg.includes(\"networkerror\")) {\r\n return \"A network error has occurred. The server may be down or malfunctioning due to CORS.\";\r\n }\r\n\r\n if (msg.includes(\"load failed\")) {\r\n return \"The request failed. Check the URL or server status.\";\r\n }\r\n }\r\n\r\n if (err instanceof SyntaxError) {\r\n return \"Unable to read response from server (invalid format).\";\r\n }\r\n\r\n if (err instanceof Error) {\r\n return err.message;\r\n }\r\n\r\n return \"An unknown error occurred.\";\r\n};\r\n\r\nexport default parserError;\r\n","const parserResponse = async (res: Response) => {\r\n const contentType = res.headers.get(\"content-type\") ?? \"\";\r\n\r\n const text = await res.text();\r\n if (!text) return null;\r\n\r\n if (contentType.includes(\"application/json\")) {\r\n try {\r\n return JSON.parse(text);\r\n } catch (err) {\r\n return text;\r\n }\r\n }\r\n\r\n try {\r\n return JSON.parse(text);\r\n } catch (err) {\r\n return text;\r\n }\r\n};\r\n\r\nexport default parserResponse;\r\n","interface parserErrorOptions {\r\n status: number;\r\n contentType: string;\r\n text: string;\r\n}\r\n\r\nconst isHtmlError = (contentType: string, text: string): boolean => {\r\n return (\r\n contentType.includes(\"text/html\") || text.trim().startsWith(\"<DOCTYPE\")\r\n );\r\n};\r\n\r\nconst parserServerError = (options: parserErrorOptions): string => {\r\n if (isHtmlError(options.contentType, options.text)) {\r\n if (options.status === 404) {\r\n return \"The requested address was not found (404). The URL or route may be invalid.\";\r\n }\r\n if (options.status >= 500) {\r\n return `An internal error occurred on the server (${options.status}).`;\r\n }\r\n return \"Check the backend route or address.\";\r\n }\r\n\r\n return options.text;\r\n};\r\n\r\nexport default parserServerError;\r\n","import Body from \"@/utils/body\";\r\nimport Headers from \"@/utils/headers\";\r\nimport parserError from \"@/utils/parserError\";\r\nimport parserResponse from \"@/utils/parserResponse\";\r\nimport type { MethodsPostProps, useResults } from \"@/types\";\r\nimport parserServerError from \"./utils/parseServerError\";\r\n\r\nclass Methods {\r\n constructor(public url: string) {}\r\n\r\n async Post<T = unknown, E = unknown>(\r\n options: MethodsPostProps,\r\n ): Promise<useResults<T, E>> {\r\n const fHeaders = { ...Headers(options.body), ...options.headers };\r\n const fBody = Body(options.body);\r\n\r\n try {\r\n const res = await fetch(this.url, {\r\n method: \"POST\",\r\n headers: fHeaders,\r\n ...(fBody === undefined ? {} : { body: fBody }),\r\n credentials: options.cookie ? \"include\" : \"same-origin\",\r\n });\r\n\r\n const clone = res.clone();\r\n const parse = await parserResponse(res);\r\n\r\n if (!res.ok) {\r\n const status = res.status;\r\n const text = await clone.text();\r\n const contentType = res.headers.get(\"content-type\") ?? \"\";\r\n const message = parserServerError({ status, contentType, text });\r\n return { success: false, error: message as E, status: res.status };\r\n }\r\n\r\n return { success: res.ok, data: parse as T, status: res.status };\r\n } catch (err) {\r\n const message = parserError(err);\r\n return { success: false, error: message as E };\r\n }\r\n }\r\n}\r\n\r\nexport default Methods;\r\n"],"mappings":";AAAA,IAAM,kBAAN,MAAM,yBAAwB,MAAM;AAAA,EAClC,YAAY,MAAc,QAAiB;AACzC,UAAM,IAAI;AACV,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,iBAAgB,SAAS;AAAA,EACvD;AACF;AAEA,IAAO,0BAAQ;;;ACNf,SAAS,aAAa,gBAAgB;;;ACFtC,IAAM,OAAO,CAAC,SAAkB;AAC9B,MAAI,gBAAgB,YAAY,OAAO,SAAS,SAAU,QAAO;AACjE,MAAI,SAAS,QAAQ,SAAS,OAAW,QAAO;AAChD,SAAO,KAAK,UAAU,IAAI;AAC5B;AAEA,IAAO,eAAQ;;;ACNf,IAAM,UAAU,CAAC,SAAkB;AACjC,MAAI,gBAAgB,SAAU,QAAO,CAAC;AACtC,MAAI,OAAO,SAAS,SAAU,QAAO,EAAE,gBAAgB,mBAAmB;AAC1E,MAAI,OAAO,SAAS,SAAU,QAAO,EAAE,gBAAgB,aAAa;AACpE,SAAO,CAAC;AACV;AAEA,IAAO,kBAAQ;;;ACPf,IAAM,cAAc,CAAC,QAAyB;AAC5C,MAAI,eAAe,gBAAgB,IAAI,SAAS,cAAc;AAC5D,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,WAAW;AAC5B,UAAM,MAAM,IAAI,QAAQ,YAAY;AAEpC,QAAI,IAAI,SAAS,iBAAiB,GAAG;AACnC,aAAO;AAAA,IACT;AAEA,QAAI,IAAI,SAAS,cAAc,GAAG;AAChC,aAAO;AAAA,IACT;AAEA,QAAI,IAAI,SAAS,aAAa,GAAG;AAC/B,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,eAAe,aAAa;AAC9B,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,OAAO;AACxB,WAAO,IAAI;AAAA,EACb;AAEA,SAAO;AACT;AAEA,IAAO,sBAAQ;;;AChCf,IAAM,iBAAiB,OAAO,QAAkB;AAC9C,QAAM,cAAc,IAAI,QAAQ,IAAI,cAAc,KAAK;AAEvD,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,MAAI,CAAC,KAAM,QAAO;AAElB,MAAI,YAAY,SAAS,kBAAkB,GAAG;AAC5C,QAAI;AACF,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,SAAS,KAAK;AACZ,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,SAAS,KAAK;AACZ,WAAO;AAAA,EACT;AACF;AAEA,IAAO,yBAAQ;;;ACff,IAAM,cAAc,CAAC,aAAqB,SAA0B;AAClE,SACE,YAAY,SAAS,WAAW,KAAK,KAAK,KAAK,EAAE,WAAW,UAAU;AAE1E;AAEA,IAAM,oBAAoB,CAAC,YAAwC;AACjE,MAAI,YAAY,QAAQ,aAAa,QAAQ,IAAI,GAAG;AAClD,QAAI,QAAQ,WAAW,KAAK;AAC1B,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,UAAU,KAAK;AACzB,aAAO,6CAA6C,QAAQ,MAAM;AAAA,IACpE;AACA,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ;AACjB;AAEA,IAAO,2BAAQ;;;ACnBf,IAAM,UAAN,MAAc;AAAA,EACZ,YAAmB,KAAa;AAAb;AAAA,EAAc;AAAA,EAAd;AAAA,EAEnB,MAAM,KACJ,SAC2B;AAC3B,UAAM,WAAW,EAAE,GAAG,gBAAQ,QAAQ,IAAI,GAAG,GAAG,QAAQ,QAAQ;AAChE,UAAM,QAAQ,aAAK,QAAQ,IAAI;AAE/B,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,KAAK,KAAK;AAAA,QAChC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM;AAAA,QAC7C,aAAa,QAAQ,SAAS,YAAY;AAAA,MAC5C,CAAC;AAED,YAAM,QAAQ,IAAI,MAAM;AACxB,YAAM,QAAQ,MAAM,uBAAe,GAAG;AAEtC,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,SAAS,IAAI;AACnB,cAAM,OAAO,MAAM,MAAM,KAAK;AAC9B,cAAM,cAAc,IAAI,QAAQ,IAAI,cAAc,KAAK;AACvD,cAAM,UAAU,yBAAkB,EAAE,QAAQ,aAAa,KAAK,CAAC;AAC/D,eAAO,EAAE,SAAS,OAAO,OAAO,SAAc,QAAQ,IAAI,OAAO;AAAA,MACnE;AAEA,aAAO,EAAE,SAAS,IAAI,IAAI,MAAM,OAAY,QAAQ,IAAI,OAAO;AAAA,IACjE,SAAS,KAAK;AACZ,YAAM,UAAU,oBAAY,GAAG;AAC/B,aAAO,EAAE,SAAS,OAAO,OAAO,QAAa;AAAA,IAC/C;AAAA,EACF;AACF;AAEA,IAAO,kBAAQ;;;ANtCf,IAAM,UAAU,CAAC,QAAQ,OAAO,OAAO,KAAK;AAE5C,IAAM,WAAW,CAAiB,QAAqC;AACrE,MAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACnC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,CAAC,SAAS,UAAU,IAAI,SAAkB,KAAK;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAmB,IAAI;AACjD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAmB,IAAI;AAE/C,QAAM,YAAY;AAAA,IAChB,OAAO,YAA6B;AAClC,YAAM,OAAO,WAAW,CAAC;AAEzB,YAAM,OAAO,KAAK;AAClB,YAAM,UAAU,KAAK,WAAW,CAAC;AACjC,YAAM,SAAS,KAAK,UAAU;AAC9B,YAAM,SAAS,KAAK,UAAU;AAE9B,iBAAW,IAAI;AACf,eAAS,IAAI;AAEb,YAAM,SAAS,IAAI,gBAAQ,GAAG;AAC9B,UAAI;AAEJ,UAAI;AACF,gBAAQ,QAAQ;AAAA,UACd,KAAK;AACH,sBAAU,MAAM,OAAO,KAAW,EAAE,SAAS,MAAM,OAAO,CAAC;AAC3D;AAAA,UACF,SAAS;AACP,kBAAM,OAAO,6BAA6B,MAAM,yBAAyB,QAAQ,KAAK,IAAI,CAAC;AAC3F,kBAAM,IAAI,wBAAgB,IAAI;AAAA,UAChC;AAAA,QACF;AAEA,YAAI,QAAQ,SAAS;AACnB,kBAAQ,QAAQ,QAAQ,IAAI;AAAA,QAC9B,OAAO;AACL,mBAAS,QAAQ,SAAS,IAAI;AAAA,QAChC;AAAA,MACF,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,iBAAS,OAAuB;AAAA,MAClC,UAAE;AACA,mBAAW,KAAK;AAAA,MAClB;AAAA,IACF;AAAA,IACA,CAAC,GAAG;AAAA,EACN;AAEA,SAAO,EAAE,SAAS,OAAO,MAAM,UAAU;AAC3C;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-ultra-fetch",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",