{"_id":"@codecraftkit/fetch","_rev":"6-063755310a909af01d332e3de7339d70","name":"@codecraftkit/fetch","dist-tags":{"latest":"0.5.1"},"versions":{"0.1.0":{"name":"@codecraftkit/fetch","version":"0.1.0","keywords":["fetch","http","nextjs","api","client","data-cache"],"author":{"name":"development code craft","email":"development.fino@finocompany.com"},"license":"MIT","_id":"@codecraftkit/fetch@0.1.0","maintainers":[{"name":"development.fino","email":"development@noblenex.us"},{"name":"cc-dev04","email":"dev04@codecraftdev.com"}],"homepage":"https://github.com/codecraftdevteam/fetch#readme","bugs":{"url":"https://github.com/codecraftdevteam/fetch/issues"},"dist":{"shasum":"c595f8feb8492e8a54bbd14e9195a119bed1ee6e","tarball":"https://registry.npmjs.org/@codecraftkit/fetch/-/fetch-0.1.0.tgz","fileCount":3,"integrity":"sha512-ezwVGM7rzDK4VyuAr7ql3WginRMeP9tN95vHeG4bTgO7rfRHUS4n2jGtVuHCQdV3MmKyz+P58hxkDy1Kt6+E4g==","signatures":[{"sig":"MEUCIQCrwRHCnYGvuwpAuGC6J2wnBd5A9/ocrwPGS7rFbGO9jAIgduc+qa9s3cFNYum6E/vLxqOJ/N1J2EEwPWivmwekI8s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":7190},"jest":{"testEnvironment":"node"},"main":"index.js","engines":{"node":">=18"},"gitHead":"a4aa34c4d3a21b03dfe7d3ce37bbe1df0d35c470","scripts":{"test":"jest"},"_npmUser":{"name":"development.fino","email":"development@noblenex.us"},"repository":{"url":"git+https://github.com/codecraftdevteam/fetch.git","type":"git"},"_npmVersion":"11.11.0","description":"Native fetch-based HTTP client for Next.js (Data Cache aware) with injectable token and logger.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch_0.1.0_1778102545610_0.09737785345698602","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@codecraftkit/fetch","version":"0.2.0","keywords":["fetch","http","nextjs","api","client","data-cache","interceptors"],"author":{"name":"development code craft","email":"development.fino@finocompany.com"},"license":"MIT","_id":"@codecraftkit/fetch@0.2.0","maintainers":[{"name":"development.fino","email":"development@noblenex.us"},{"name":"cc-dev04","email":"dev04@codecraftdev.com"}],"homepage":"https://github.com/codecraftdevteam/fetch#readme","bugs":{"url":"https://github.com/codecraftdevteam/fetch/issues"},"dist":{"shasum":"ddb3fa7e38a22f277b0085a098e1527314c78cff","tarball":"https://registry.npmjs.org/@codecraftkit/fetch/-/fetch-0.2.0.tgz","fileCount":3,"integrity":"sha512-ay/Ts/VDufZRdbWU2dcpwSQmtSvEcHVQblLsYzIdVbFFOmShmRI/KAdXJjlwHJtl+IhsDLCDT5NxNsdkhjY01Q==","signatures":[{"sig":"MEUCIGUdXYpjFSoSvLowZCaEQ+J7O3u7Ne1VaCyObHcEYl/YAiEAq8d4mv2S9a95A01da9Tv6umNvHePdQXWWy8PjQNJmLE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":11137},"jest":{"testEnvironment":"node"},"main":"index.js","engines":{"node":">=18"},"gitHead":"6fd9f9840dcc04617297fb1b13d284766cd5cee8","scripts":{"test":"jest"},"_npmUser":{"name":"development.fino","email":"development@noblenex.us"},"repository":{"url":"git+https://github.com/codecraftdevteam/fetch.git","type":"git"},"_npmVersion":"11.11.0","description":"Native fetch-based HTTP client for Next.js (Data Cache aware) with axios-style interceptors, injectable token and logger.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch_0.2.0_1778106006493_0.9727036596888377","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@codecraftkit/fetch","version":"0.3.0","keywords":["fetch","http","nextjs","api","client","data-cache","interceptors","multipart","formdata","upload"],"author":{"name":"development code craft","email":"development.fino@finocompany.com"},"license":"MIT","_id":"@codecraftkit/fetch@0.3.0","maintainers":[{"name":"development.fino","email":"development@noblenex.us"},{"name":"cc-dev04","email":"dev04@codecraftdev.com"}],"homepage":"https://github.com/codecraftdevteam/fetch#readme","bugs":{"url":"https://github.com/codecraftdevteam/fetch/issues"},"dist":{"shasum":"5a425410877e6467e31dffd2cfb492052f678e3b","tarball":"https://registry.npmjs.org/@codecraftkit/fetch/-/fetch-0.3.0.tgz","fileCount":3,"integrity":"sha512-Oax49g+svAnq+m1emcIhWmM42uMFwfm80WQX0Wardj4kB+YN/83ljeWLEVyKEfhJVlmlL8uG4vzNIXuSPxWBGw==","signatures":[{"sig":"MEUCIQD3qtcCjgdN4SegEFpJuHMRCG3+osl/9RfGxbW5tLcIEAIgbesGXb62hhFKDEI7DEwAIICpmZ5vsqv6GJk7MbH7mhE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14780},"jest":{"testEnvironment":"node"},"main":"index.js","engines":{"node":">=18"},"gitHead":"95338ff5c138455f7cb8473e7ba4568019709cba","scripts":{"test":"jest"},"_npmUser":{"name":"development.fino","email":"development@noblenex.us"},"repository":{"url":"git+https://github.com/codecraftdevteam/fetch.git","type":"git"},"_npmVersion":"11.11.0","description":"Native fetch-based HTTP client for Next.js (Data Cache aware) with axios-style interceptors, multipart/FormData support, injectable token and logger.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch_0.3.0_1778599866280_0.814461694339635","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@codecraftkit/fetch","version":"0.4.0","keywords":["fetch","http","nextjs","api","client","data-cache","interceptors","multipart","formdata","upload"],"author":{"name":"development code craft","email":"development.fino@finocompany.com"},"license":"MIT","_id":"@codecraftkit/fetch@0.4.0","maintainers":[{"name":"development.fino","email":"development@noblenex.us"},{"name":"cc-dev04","email":"dev04@codecraftdev.com"}],"homepage":"https://github.com/codecraftdevteam/fetch#readme","bugs":{"url":"https://github.com/codecraftdevteam/fetch/issues"},"dist":{"shasum":"38f4216f82a201ae78f8578ddfc7577a61b9a282","tarball":"https://registry.npmjs.org/@codecraftkit/fetch/-/fetch-0.4.0.tgz","fileCount":3,"integrity":"sha512-9TiN7mIV0YFEB/vZZ3zUGbIVfjuU/TRISVoRZQ75J3j9m05TEr5RtreBRNqplVITGv0BMg8oY6U+J2J/PSfFVw==","signatures":[{"sig":"MEQCIEJXn/AytUUEKNFbfNAekFCojUhZQIYUmmUoEZ50C+mwAiBgW+x0TokDOZj683eAcK+P2acrZknmFEg4Qe3Uf46gCA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":15977},"jest":{"testEnvironment":"node"},"main":"index.js","engines":{"node":">=18"},"gitHead":"1308447ac72c93c65701f61d0eb694b56397736a","scripts":{"test":"jest"},"_npmUser":{"name":"development.fino","email":"development@noblenex.us"},"repository":{"url":"git+https://github.com/codecraftdevteam/fetch.git","type":"git"},"_npmVersion":"11.11.0","description":"Native fetch-based HTTP client for Next.js (Data Cache aware) with axios-style interceptors, multipart/FormData support, dual call/request API, injectable token and logger.","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch_0.4.0_1778704648882_0.874364732523524","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@codecraftkit/fetch","version":"0.5.0","keywords":["fetch","http","nextjs","api","client","data-cache","interceptors","multipart","formdata","upload"],"author":{"name":"development code craft","email":"development.fino@finocompany.com"},"license":"MIT","_id":"@codecraftkit/fetch@0.5.0","maintainers":[{"name":"development.fino","email":"development@noblenex.us"},{"name":"cc-dev04","email":"dev04@codecraftdev.com"}],"homepage":"https://github.com/codecraftkit/fetch#readme","bugs":{"url":"https://github.com/codecraftkit/fetch/issues"},"dist":{"shasum":"8dcdb5f445dd1bc093fe5672149dabd2eb82c9c0","tarball":"https://registry.npmjs.org/@codecraftkit/fetch/-/fetch-0.5.0.tgz","fileCount":3,"integrity":"sha512-t1mSCV8yscMsmTehXG1i9n/qgjM/l42CIpni/k0LntAPGJcmhSKCnVnq5l6qnEtQofpxRSZdzINil6yTJl1cxw==","signatures":[{"sig":"MEYCIQCqawsz+0yhSGDWw1Q5HPW9FVY5gA/Oiwfc5aYg833c3gIhAIbGwX2YFlUdWdovfWBmIR7z6AT7qZWUM7MIb1bFdmrm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":21844},"jest":{"testEnvironment":"node"},"main":"index.js","engines":{"node":">=18"},"gitHead":"43ec63763362c253015e211223b18d2247ed0b07","scripts":{"test":"jest"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ee897fa8-2735-4609-92dc-4bdcc274d6fd"}},"repository":{"url":"git+https://github.com/codecraftkit/fetch.git","type":"git"},"_npmVersion":"11.17.0","description":"Native fetch-based HTTP client for Next.js (Data Cache aware) with axios-style interceptors, multipart/FormData support, dual call/request API, injectable token and logger.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch_0.5.0_1787176674196_0.8351773098439517","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@codecraftkit/fetch","version":"0.5.1","description":"Native fetch-based HTTP client for Next.js (Data Cache aware) with axios-style interceptors, multipart/FormData support, dual call/request API, injectable token and logger.","main":"index.js","scripts":{"test":"jest"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/codecraftkit/fetch.git"},"keywords":["fetch","http","nextjs","api","client","data-cache","interceptors","multipart","formdata","upload"],"author":{"name":"development code craft","email":"development.fino@finocompany.com"},"license":"MIT","engines":{"node":">=18"},"devDependencies":{"jest":"^29.7.0"},"jest":{"testEnvironment":"node"},"gitHead":"067479111d98ee7b135d408dcb718828322903ec","_id":"@codecraftkit/fetch@0.5.1","bugs":{"url":"https://github.com/codecraftkit/fetch/issues"},"homepage":"https://github.com/codecraftkit/fetch#readme","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-2MMcufozRMfnDBp60KwGi5EYUT+u/rMczc5ssxwX2b/n2wucxU8uzk96Z5ssO9HEtni3GhOD3OP5Nyqt65U8NQ==","shasum":"0e16a3f7760668bab63f5ac83fe33140f9f321b4","tarball":"https://registry.npmjs.org/@codecraftkit/fetch/-/fetch-0.5.1.tgz","fileCount":3,"unpackedSize":21844,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCwKYP7KnbzCLRY4309xgo8qe03JWIR4ZEUSfuKtY0B0wIgRukXfWonUGIFtJ8d7PB5CCPasX2mUdsp4JdeZr11m1c="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ee897fa8-2735-4609-92dc-4bdcc274d6fd"}},"directories":{},"maintainers":[{"name":"development.fino","email":"development@noblenex.us"},{"name":"cc-dev04","email":"dev04@codecraftdev.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/fetch_0.5.1_1787177430855_0.6893146793804896"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-06T21:22:25.488Z","modified":"2026-08-19T22:10:31.181Z","0.1.0":"2026-05-06T21:22:25.743Z","0.2.0":"2026-05-06T22:20:06.662Z","0.3.0":"2026-05-12T15:31:06.444Z","0.4.0":"2026-05-13T20:37:29.031Z","0.5.0":"2026-08-19T21:57:54.341Z","0.5.1":"2026-08-19T22:10:30.996Z"},"bugs":{"url":"https://github.com/codecraftkit/fetch/issues"},"author":{"name":"development code craft","email":"development.fino@finocompany.com"},"license":"MIT","homepage":"https://github.com/codecraftkit/fetch#readme","keywords":["fetch","http","nextjs","api","client","data-cache","interceptors","multipart","formdata","upload"],"repository":{"type":"git","url":"git+https://github.com/codecraftkit/fetch.git"},"description":"Native fetch-based HTTP client for Next.js (Data Cache aware) with axios-style interceptors, multipart/FormData support, dual call/request API, injectable token and logger.","maintainers":[{"name":"development.fino","email":"development@noblenex.us"},{"name":"cc-dev04","email":"dev04@codecraftdev.com"}],"readme":"# @codecraftkit/fetch\n\n> Native fetch-based HTTP client for Next.js App Router. Forwards Data Cache options (`cache`, `next: { revalidate, tags }`) and `AbortSignal` per call. Pluggable token resolver and logger. Zero runtime dependencies.\n\n## Install\n\n```bash\nnpm install @codecraftkit/fetch\n```\n\nRequires Node `>=18` (uses global `fetch`).\n\n## Usage\n\n### Server components (App Router)\n\n```js\nimport 'server-only'\nimport { cookies } from 'next/headers'\nimport { createFetchClient } from '@codecraftkit/fetch'\n\nexport const api = createFetchClient({\n  baseUrl: process.env.API_URL,\n  secret: process.env.API_SECRET,\n  getToken: async () => (await cookies()).get('token')?.value\n})\n\n// Forward Data Cache controls per call\nexport const getBrokers = (q) => api.call(`/brokers?${q}`, null, { cache: 'no-store' })\nexport const getStats   = (q) => api.call(`/stats?${q}`, null, { next: { revalidate: 60, tags: ['stats'] } })\n```\n\n### Client components\n\n```js\n'use client'\nimport { createFetchClient } from '@codecraftkit/fetch'\n\nconst api = createFetchClient({\n  baseUrl: process.env.NEXT_PUBLIC_API_URL,\n  getToken: () => document.cookie.match(/token=([^;]+)/)?.[1]\n})\n```\n\n## Options\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `baseUrl` | `string` | **required** | Prepended to every `path` passed to `call()`. |\n| `secret` | `string` | — | Sent as `x-secret` header on every request. |\n| `getToken` | `() => string \\| Promise<string>` | — | Resolves the auth token per request. Called on each `call()`. |\n| `headersType` | `'x-token' \\| 'bearer'` | `'x-token'` | How to attach the token. `bearer` sets `Authorization: Bearer <token>`. |\n| `defaultHeaders` | `object` | `{}` | Extra headers merged into every request. |\n| `logger` | `{ debug, error }` | no-op | Inject `console` to enable debug logs. |\n\n## Per-call config\n\n```js\napi.call(path, data, {\n  method: 'POST',           // default GET\n  timeout: 5000,            // ms; sin default — ver abajo\n  headers: { ... },         // merged on top of defaults\n  cache: 'no-store',        // Next.js Data Cache\n  next: { revalidate, tags },\n  signal: abortController.signal,\n  asBlob: false             // force blob() regardless of content-type\n})\n```\n\nVerb shortcuts:\n\n```js\napi.get(path, config)\napi.post(path, data, config)\napi.put(path, data, config)\napi.delete(path, data, config)\n```\n\n## `call` vs `request`\n\nThe client exposes two entry points sharing the same interceptor pipeline:\n\n| Method | Returns | Use when |\n|--------|---------|----------|\n| `api.call(path, data, config)` (and verb shortcuts) | parsed body only | You only need the response data (95% of cases) |\n| `api.request(path, data, config)` | `{ data, status, headers, response, config }` | You need status code or response headers (pagination, ETag, rate limits) |\n\n```js\n// Common case\nconst users = await api.get('/users')\n\n// Need pagination headers\nconst { data: users, headers } = await api.request('/users')\nconst total = headers.get('x-total-count')\n\n// Need status code\nconst { data, status } = await api.request('/users', { id: 1 }, { method: 'POST' })\nif (status === 201) toast.success('Created')\n```\n\nBoth methods run request and response interceptors identically. The only difference is whether the final result is unwrapped to `.data` (`call`) or left as the full shape (`request`).\n\n## Response handling\n\n- `application/json` → parsed object\n- `application/pdf`, `application/octet-stream`, `xlsx` → `Blob`\n- `asBlob: true` → `Blob` regardless of content-type\n- Non-2xx → throws `Error` with message from JSON `message`/`error` or text body\n\n## Sending raw bodies (multipart, blob, url-encoded, binary)\n\nThe client auto-detects raw body types and skips JSON serialization. The default `Content-Type: application/json` is stripped so the runtime can set the correct header (with boundary for multipart, blob type for `Blob`, etc.).\n\n### Multipart `FormData`\n\n```js\nconst form = new FormData()\nform.append('name', 'doc.pdf')\nform.append('file', fileBlob, 'doc.pdf')\n\nawait api.post('/upload', form)\n// → Content-Type: multipart/form-data; boundary=... (set by runtime)\n```\n\n**Never set `Content-Type` manually for `FormData`** — the boundary is auto-generated and a manual header breaks parsing on the server. The library strips it even if you try to set it.\n\n### `Blob` / `File`\n\n```js\nconst blob = new Blob([data], { type: 'image/png' })\nawait api.post('/upload', blob)\n// → Content-Type: image/png (from blob.type)\n\n// Override:\nawait api.post('/upload', blob, { headers: { 'Content-Type': 'application/octet-stream' } })\n```\n\n### `URLSearchParams` (form-urlencoded)\n\n```js\nawait api.post('/form', new URLSearchParams({ a: '1', b: '2' }))\n// → Content-Type: application/x-www-form-urlencoded;charset=UTF-8\n```\n\n### `ArrayBuffer` / `TypedArray` / `ReadableStream`\n\nPass-through without serialization. **You must set `Content-Type` explicitly** — the runtime cannot infer it.\n\n```js\nawait api.post('/binary', new Uint8Array([1, 2, 3]), {\n  headers: { 'Content-Type': 'application/octet-stream' }\n})\n```\n\n### Supported raw types\n\n| Type | Content-Type behavior |\n|------|----------------------|\n| `FormData` | Always stripped (runtime sets multipart + boundary) |\n| `Blob` / `File` | Default JSON stripped; runtime uses `blob.type`; user override wins |\n| `URLSearchParams` | Default JSON stripped; runtime sets form-urlencoded |\n| `ArrayBuffer`, `TypedArray` | Default JSON stripped; user must set Content-Type |\n| `ReadableStream` | Default JSON stripped; user must set Content-Type |\n| `string` | Default JSON kept (assumes JSON string) |\n| plain object / array | JSON.stringify + `Content-Type: application/json` |\n\n## Interceptors\n\nAxios-compatible API. Use `interceptors.request.use` to mutate the outgoing request and `interceptors.response.use` to transform the response or recover from errors. Both return an `id` for `eject()`.\n\n### Request interceptor\n\n```js\nconst api = createFetchClient({ baseUrl: process.env.NEXT_PUBLIC_API_URL })\n\napi.interceptors.request.use(async (config) => {\n  try {\n    const raw = window.localStorage.getItem('organization-tokens')\n    const store = raw ? JSON.parse(raw) : null\n\n    if (store) {\n      const state = store.state\n      config.headers['x-organization-id'] = state?.organizationToken\n      config.headers['x-organization-app-integration-id'] = state?.organizationAppIntegrationToken\n    }\n  } catch (e) {}\n\n  return config\n})\n```\n\nThe `config` object exposes `url`, `method`, `headers`, `data`, `cache`, `next`, `signal`, `asBlob`. Mutate and return it, or return a new object. Interceptors run **after** `getToken`, so they can override the auth header.\n\n### Response interceptor\n\nHandlers receive a wrapped object `{ data, status, headers, response, config }` (axios-shaped). Mutate `data` to transform what the caller receives. The library returns `result.data` after the chain runs.\n\n```js\napi.interceptors.response.use(\n  (res) => {\n    res.data = res.data.payload // unwrap envelope\n    return res\n  },\n  (error) => { throw error }\n)\n```\n\n### Error recovery and refresh-token retry\n\nThe error handler receives an `Error` augmented with `status`, `response`, and `config`. Returning a value recovers the call; throwing forwards to the next error handler.\n\n```js\napi.interceptors.response.use(null, async (error) => {\n  if (error.status !== 401) throw error\n  await refreshToken()\n  return api.call(error.config.url.replace(baseUrl, ''), error.config.data, {\n    method: error.config.method\n  })\n})\n```\n\n### Eject\n\n```js\nconst id = api.interceptors.request.use(fn)\napi.interceptors.request.eject(id)\n```\n\n## Why this and not axios?\n\nNative `fetch` integrates with the Next.js Data Cache. Axios does not. Forwarding `cache`, `next`, and `signal` lets each caller opt into caching strategies without monkey-patching the client.\n\n## License\n\nMIT\n\n\n## `timeout` — por llamada, nunca global\n\n```js\napi.call('/reporte', filtro, { method: 'POST', timeout: 10000 })\n```\n\n**No hay default, y es deliberado.** Un tope a nivel cliente parece la comodidad\nobvia y rompe cualquier stream de larga duración: un SSE vive horas, y ahí el que\ncorta la conexión es un bug, no una protección. Por eso se decide por llamada, donde\nquien la escribe sabe si pide una respuesta o un caudal.\n\nAl vencer, la promesa rechaza con un error `name: 'TimeoutError'`.\n\nSe **compone** con el `signal` que le pases, no lo reemplaza: los dos motivos de\naborto conviven — el caller aborta cuando su consumidor se va (cerrar una pestaña,\ndesmontar un componente) y el timeout cuando el upstream no contesta. El que llegue\nprimero gana.\n\n> Si estás usando el cliente para SSE, **no le pongas `timeout`**. El resto de la\n> configuración es la misma: el cliente devuelve la `Response` cruda cuando el\n> `Content-Type` no es JSON ni binario, y resuelve al llegar los headers sin esperar\n> a que cierre el stream. Acordate de pisar `Accept: 'text/event-stream'`, que por\n> defecto es `application/json`.\n\n## El cuerpo de un error\n\nUn HTTP no-2xx rechaza con un `Error` que trae:\n\n| | |\n|---|---|\n| `error.message` | `body.message ?? body.error ?? 'HTTP <status>'` |\n| `error.status` | el status HTTP |\n| `error.data` | **el cuerpo ya parseado** |\n| `error.response` | la `Response`, para headers y status |\n| `error.config` | el request que lo produjo |\n\n`error.data` existe porque armar el mensaje **consume el stream**: después,\n`error.response.json()` tira `body stream already read`. Sin `error.data`, todo lo\nque la API mandara además del mensaje —un código interno, un campo con el detalle—\nera irrecuperable justo cuando más se necesita.\n","readmeFilename":"README.md"}