1000fetches 0.2.2 → 0.3.0
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/README.md +122 -89
- package/dist/client/index.d.ts +23 -0
- package/dist/contract/index.d.ts +6 -0
- package/dist/core.d.ts +36 -10
- package/dist/{errors.d.ts → errors/errors.d.ts} +42 -7
- package/dist/errors/handling.d.ts +2 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -12
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/request/abort/abort.d.ts +12 -0
- package/dist/request/abort/index.d.ts +1 -0
- package/dist/request/fetchErrors/fetchErrors.d.ts +4 -0
- package/dist/request/fetchErrors/index.d.ts +1 -0
- package/dist/request/middleware/index.d.ts +1 -0
- package/dist/request/middleware/middleware.d.ts +7 -0
- package/dist/request/request.d.ts +16 -0
- package/dist/request/retry/index.d.ts +1 -0
- package/dist/request/retry/retry.d.ts +20 -0
- package/dist/request/serialization/index.d.ts +1 -0
- package/dist/request/serialization/serialization.d.ts +9 -0
- package/dist/request/url.d.ts +3 -0
- package/dist/response.d.ts +12 -0
- package/dist/retry-BWvlSmME.cjs +2 -0
- package/dist/retry-BWvlSmME.cjs.map +1 -0
- package/dist/retry-D07aIs-1.js +2 -0
- package/dist/retry-D07aIs-1.js.map +1 -0
- package/dist/{schema.d.ts → schema/index.d.ts} +1 -1
- package/dist/status.d.ts +2 -0
- package/dist/types.d.ts +26 -21
- package/dist/utils/index.d.ts +1 -2
- package/dist/utils/path.d.ts +6 -8
- package/docs/BEST_PRACTICES.md +124 -45
- package/package.json +30 -21
- package/skills/1000fetches/SKILL.md +35 -0
- package/skills/1000fetches/references/client-setup-and-defaults.md +49 -0
- package/skills/1000fetches/references/contracts-and-errors.md +50 -0
- package/skills/1000fetches/references/path-params-and-urls.md +39 -0
- package/skills/1000fetches/references/retries-timeouts-and-middleware.md +32 -0
- package/skills/1000fetches/references/serialization-and-body-types.md +22 -0
- package/dist/client-C7dvgNnD.js +0 -2
- package/dist/client-C7dvgNnD.js.map +0 -1
- package/dist/client-DOv6m2TJ.mjs +0 -2
- package/dist/client-DOv6m2TJ.mjs.map +0 -1
- package/dist/client.d.ts +0 -22
- package/dist/http.cjs +0 -2
- package/dist/http.cjs.map +0 -1
- package/dist/http.d.ts +0 -9
- package/dist/http.mjs +0 -2
- package/dist/http.mjs.map +0 -1
- package/dist/utils/streaming.d.ts +0 -9
- package/docs/API.md +0 -754
- package/docs/MIGRATION.md +0 -719
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "1000fetches",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A modern, type-safe HTTP client for TypeScript with built-in schema validation, middleware, opt-in retry logic, and compile-time path parameter validation. Features full TypeScript support, request/response middleware, and schema validation using Standard Schema-compatible libraries.",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "dist/index.cjs",
|
|
6
7
|
"module": "dist/index.mjs",
|
|
7
8
|
"types": "dist/index.d.ts",
|
|
@@ -10,21 +11,17 @@
|
|
|
10
11
|
"types": "./dist/index.d.ts",
|
|
11
12
|
"import": "./dist/index.mjs",
|
|
12
13
|
"require": "./dist/index.cjs"
|
|
13
|
-
},
|
|
14
|
-
"./http": {
|
|
15
|
-
"types": "./dist/http.d.ts",
|
|
16
|
-
"import": "./dist/http.mjs",
|
|
17
|
-
"require": "./dist/http.cjs"
|
|
18
14
|
}
|
|
19
15
|
},
|
|
20
16
|
"files": [
|
|
21
17
|
"dist",
|
|
22
18
|
"docs",
|
|
19
|
+
"skills",
|
|
23
20
|
"LICENSE"
|
|
24
21
|
],
|
|
25
22
|
"sideEffects": false,
|
|
26
23
|
"scripts": {
|
|
27
|
-
"build": "tsc && vite build",
|
|
24
|
+
"build": "tsc --noEmit && vite build",
|
|
28
25
|
"dev": "vite build --watch",
|
|
29
26
|
"test": "yarn test:types && yarn test:unit",
|
|
30
27
|
"test:unit": "vitest --run",
|
|
@@ -33,13 +30,16 @@
|
|
|
33
30
|
"test:coverage": "yarn test:types && vitest --coverage",
|
|
34
31
|
"test:types": "tsc --noEmit && tsc --noEmit --project tsconfig.test.json",
|
|
35
32
|
"tsc": "yarn test:types",
|
|
36
|
-
"lint": "prettier --check .",
|
|
37
|
-
"lint:
|
|
33
|
+
"lint": "yarn lint:code && prettier --check .",
|
|
34
|
+
"lint:code": "eslint src vite.config.ts vitest.config.ts",
|
|
35
|
+
"lint:fix": "eslint src vite.config.ts vitest.config.ts --fix && prettier --write .",
|
|
38
36
|
"bundle:analyze": "LIB_BUILD=true vite build --mode analyze",
|
|
39
|
-
"bundle:size": "node
|
|
37
|
+
"bundle:size": "node scripts/bundle-size.js",
|
|
40
38
|
"bundle": "LIB_BUILD=true vite build && yarn bundle:size",
|
|
41
39
|
"package:smoke": "yarn build && yarn test:exports && npm pack --dry-run --json",
|
|
42
|
-
"clean": "rm -rf dist coverage"
|
|
40
|
+
"clean": "rm -rf dist coverage",
|
|
41
|
+
"format": "prettier --write .",
|
|
42
|
+
"format:check": "prettier --check ."
|
|
43
43
|
},
|
|
44
44
|
"keywords": [
|
|
45
45
|
"http",
|
|
@@ -57,21 +57,30 @@
|
|
|
57
57
|
"author": "Max Tarsis <tarsis.maksym@gmail.com>",
|
|
58
58
|
"license": "MIT",
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@
|
|
61
|
-
"@
|
|
62
|
-
"
|
|
63
|
-
"
|
|
60
|
+
"@eslint/js": "^10.0.1",
|
|
61
|
+
"@types/node": "22.20.0",
|
|
62
|
+
"@vitest/coverage-v8": "4.1.9",
|
|
63
|
+
"arktype": "2.2.1",
|
|
64
|
+
"eslint": "^10.6.0",
|
|
65
|
+
"eslint-config-prettier": "^10.1.8",
|
|
66
|
+
"expect-type": "1.4.0",
|
|
64
67
|
"msw": "2.14.6",
|
|
65
|
-
"rollup-plugin-visualizer": "
|
|
68
|
+
"rollup-plugin-visualizer": "7.0.1",
|
|
66
69
|
"terser": "5.48.0",
|
|
67
70
|
"typescript": "6.0.3",
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"vite
|
|
71
|
-
"
|
|
72
|
-
"
|
|
71
|
+
"typescript-eslint": "^8.62.0",
|
|
72
|
+
"valibot": "1.4.2",
|
|
73
|
+
"vite": "8.1.0",
|
|
74
|
+
"vite-plugin-dts": "5.0.3",
|
|
75
|
+
"vitest": "4.1.9",
|
|
76
|
+
"zod": "4.4.3",
|
|
77
|
+
"prettier": "3.9.1"
|
|
73
78
|
},
|
|
74
79
|
"dependencies": {
|
|
75
80
|
"@standard-schema/spec": "^1.1.0"
|
|
81
|
+
},
|
|
82
|
+
"packageManager": "yarn@1.22.22",
|
|
83
|
+
"resolutions": {
|
|
84
|
+
"vite": "8.1.0"
|
|
76
85
|
}
|
|
77
86
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 1000fetches
|
|
3
|
+
description: Use when an AI coding agent is building or modifying TypeScript code that uses 1000fetches, including client setup, dynamic defaults, path params, contracts, retries, middleware, serialization, body typing, or public API changes in this library.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 1000fetches
|
|
7
|
+
|
|
8
|
+
Use this skill to write or modify TypeScript code that uses `1000fetches`, and to preserve the library's design when changing the library itself.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. Prefer `createHttpClient` and the method API: `get`, `post`, `put`, `patch`, `delete`, and `request`.
|
|
13
|
+
2. Use path params instead of string interpolation for templated paths.
|
|
14
|
+
3. Use `.contract()` at network boundaries when response shape matters; finish with `.data()` or `.void()` when the caller does not need the full response.
|
|
15
|
+
4. Use dynamic `defaults` for auth and request-shaped defaults.
|
|
16
|
+
5. Import the public types and errors used in examples from `1000fetches`; do not reach into package internals.
|
|
17
|
+
6. Use middleware only for observation or deliberate mutation that defaults cannot express.
|
|
18
|
+
7. Keep retries conservative and opt-in.
|
|
19
|
+
8. Do not recommend streaming callbacks; streaming telemetry is intentionally not part of the core API.
|
|
20
|
+
|
|
21
|
+
## Reference Routing
|
|
22
|
+
|
|
23
|
+
- Read `references/client-setup-and-defaults.md` when creating clients, configuring auth, setting headers, params, timeouts, retry defaults, or fetch options.
|
|
24
|
+
- Read `references/contracts-and-errors.md` when adding validation, status-specific contracts, typed data extraction, or error handling.
|
|
25
|
+
- Read `references/path-params-and-urls.md` when building URLs, path templates, base URLs, or query params.
|
|
26
|
+
- Read `references/retries-timeouts-and-middleware.md` when configuring retries, cancellation, timeouts, logging, telemetry, or middleware.
|
|
27
|
+
- Read `references/serialization-and-body-types.md` when sending bodies, using custom `serializeBody`, or modifying body-related library types.
|
|
28
|
+
|
|
29
|
+
## Library-Change Rules
|
|
30
|
+
|
|
31
|
+
- Preserve the public API shape and type inference unless the requested change explicitly changes the API.
|
|
32
|
+
- Update runtime tests, type tests, exports, and docs for public behavior changes.
|
|
33
|
+
- Keep runtime dependencies light; do not add runtime dependencies unless explicitly approved.
|
|
34
|
+
- Keep source imports extensionless and local imports relative.
|
|
35
|
+
- Do not add release notes, changelogs, or changesets unless release preparation is requested.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Client Setup And Defaults
|
|
2
|
+
|
|
3
|
+
Use `createHttpClient` once per API surface and share that client.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { createHttpClient } from '1000fetches'
|
|
7
|
+
|
|
8
|
+
export const api = createHttpClient({
|
|
9
|
+
baseUrl: 'https://api.example.com',
|
|
10
|
+
timeout: 10_000,
|
|
11
|
+
})
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Dynamic Defaults
|
|
15
|
+
|
|
16
|
+
Use `defaults` for values that should be resolved per request without mutating the final request context. The callback receives `path`, `resolvedPath`, `method`, `params`, `pathParams`, `body`, `hasBody`, a readonly `requestOptions` snapshot, and static client fields such as `baseUrl`, `headers`, `timeout`, and `retry`.
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
const api = createHttpClient({
|
|
20
|
+
baseUrl: 'https://api.example.com',
|
|
21
|
+
defaults: async ({ resolvedPath, method, hasBody }) => {
|
|
22
|
+
const token = await getToken()
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
headers: {
|
|
26
|
+
Authorization: `Bearer ${token}`,
|
|
27
|
+
...(hasBody ? { 'X-Write': method } : {}),
|
|
28
|
+
},
|
|
29
|
+
timeout: resolvedPath.startsWith('/reports') ? 60_000 : 10_000,
|
|
30
|
+
retry: method === 'GET',
|
|
31
|
+
params: { locale: 'en-US' },
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Merge order is static client config, then dynamic defaults, then request options, then request middleware. Request options win over defaults.
|
|
38
|
+
|
|
39
|
+
Use request options for one-off overrides:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
await api.get('/health', {
|
|
43
|
+
timeout: 2_000,
|
|
44
|
+
retry: false,
|
|
45
|
+
headers: { 'X-Probe': 'health' },
|
|
46
|
+
})
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Do not use `defaults` to rewrite hosts or paths. Pass an absolute request URL or use request middleware when host/path mutation is truly needed. Dynamic defaults may set `headers`, `params`, `timeout`, `retry`, `responseType`, `fetchOptions`, `cache`, `credentials`, `mode`, and `redirect`; request options still win.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Contracts And Errors
|
|
2
|
+
|
|
3
|
+
Use `.contract()` when response data should be validated at runtime and inferred at compile time. Pass Standard Schema-compatible schemas such as Zod, Valibot, or ArkType schemas.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { HttpError } from '1000fetches'
|
|
7
|
+
import { z } from 'zod'
|
|
8
|
+
|
|
9
|
+
const UserSchema = z.object({ id: z.string(), name: z.string() })
|
|
10
|
+
|
|
11
|
+
const user = await api
|
|
12
|
+
.get('/users/:id', { pathParams: { id } })
|
|
13
|
+
.contract(UserSchema)
|
|
14
|
+
.data()
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Use status-specific contracts for APIs with known success or error shapes.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
await api.post('/transactions', input).contract({
|
|
21
|
+
success: {
|
|
22
|
+
default: TransactionSchema,
|
|
23
|
+
202: AcceptedSchema,
|
|
24
|
+
},
|
|
25
|
+
error: {
|
|
26
|
+
default: ApiErrorSchema,
|
|
27
|
+
409: ConflictSchema,
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Success status maps accept `2xx` and `3xx` keys. Error status maps accept `4xx` and `5xx` keys.
|
|
33
|
+
|
|
34
|
+
Handle specific errors instead of broad `Error` checks when behavior differs:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
try {
|
|
38
|
+
return await api
|
|
39
|
+
.get('/users/:id', { pathParams: { id } })
|
|
40
|
+
.contract(UserSchema)
|
|
41
|
+
} catch (error) {
|
|
42
|
+
if (error instanceof HttpError && error.status === 404) {
|
|
43
|
+
return null
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
throw error
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Prefer `.data()` when the caller only needs the parsed body. Use `.void()` for endpoints where a successful response body should be ignored. Keep the full response when status, headers, URL, or raw `Response` matters.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Path Params And URLs
|
|
2
|
+
|
|
3
|
+
Use path params for templated URL segments. Do not interpolate path params manually.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
await api.get('/users/:userId/projects/:projectId', {
|
|
7
|
+
pathParams: { userId, projectId },
|
|
8
|
+
})
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Use `params` for query string values.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
await api.get('/search', {
|
|
15
|
+
params: {
|
|
16
|
+
q: query,
|
|
17
|
+
page,
|
|
18
|
+
tags,
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For Node native `fetch`, provide an absolute `baseUrl` unless using a custom fetch implementation that supports relative URLs.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
const api = createHttpClient({
|
|
27
|
+
baseUrl: 'https://api.example.com',
|
|
28
|
+
})
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Root-relative base URLs are useful in browser apps:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
const api = createHttpClient({
|
|
35
|
+
baseUrl: '/api',
|
|
36
|
+
})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Use `serializeParams` only when the default `URLSearchParams` behavior does not match the target API.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Retries, Timeouts, And Middleware
|
|
2
|
+
|
|
3
|
+
Retries are opt-in. Default retry methods are idempotent: `GET`, `HEAD`, `OPTIONS`, `PUT`, and `DELETE`.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
const api = createHttpClient({
|
|
7
|
+
retry: {
|
|
8
|
+
maxRetries: 3,
|
|
9
|
+
retryDelay: 250,
|
|
10
|
+
jitter: 'full',
|
|
11
|
+
},
|
|
12
|
+
})
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Use `retry: false` for operations that must not be retried.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
await api.post('/payments', payment, { retry: false })
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Use timeouts at the client level for normal requests, dynamic defaults for route-shaped timeouts, and request options for one-off overrides.
|
|
22
|
+
|
|
23
|
+
Middleware is allowed to observe and mutate request or response state. Keep it side-effect-light. Use dynamic defaults for auth, headers, params, timeout, retry, response type, and fetch options before reaching for middleware.
|
|
24
|
+
|
|
25
|
+
Good middleware uses:
|
|
26
|
+
|
|
27
|
+
- log request and response metadata
|
|
28
|
+
- add a generated request id
|
|
29
|
+
- normalize response data
|
|
30
|
+
- rewrite URL or method only when mutation is required
|
|
31
|
+
|
|
32
|
+
Do not add broad lifecycle hooks. Do not recommend streaming callbacks; streaming telemetry is intentionally not part of the core API.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Serialization And Body Types
|
|
2
|
+
|
|
3
|
+
Without a custom serializer, objects and arrays are JSON stringified and get `content-type: application/json` when no explicit content type is set.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
await api.post('/users', { name: 'Ada' })
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Native body values such as `FormData`, `URLSearchParams`, `Blob`, `ArrayBuffer`, `ArrayBufferView`, strings, and `ReadableStream` are passed as fetch bodies. When sending a `ReadableStream` in Node/native fetch contexts that require it, set `fetchOptions: { duplex: 'half' }`.
|
|
10
|
+
|
|
11
|
+
Use `serializeBody` when an API needs a custom wire format. A narrow serializer narrows accepted bodies for write methods.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const uploadApi = createHttpClient({
|
|
15
|
+
baseUrl: 'https://api.example.com',
|
|
16
|
+
serializeBody: (body: FormData): BodyInit => body,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
await uploadApi.post('/files', formData)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
When modifying this library, preserve runtime serializer behavior and add type tests for accepted and rejected body types. Do not weaken normal JSON/object body inference for clients without a custom serializer.
|
package/dist/client-C7dvgNnD.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var e=class extends Error{name="HttpError";status;statusText;data;response;url;method;cause;constructor(e,t,r,n,a,o,s,i){const c=`HTTP ${t>=500?"Server Error":t>=400?"Client Error":t>=300?"Redirect":"Success"} (${t}): ${e}\nRequest: ${s} ${o}\nData: ${function(e){if(null==e||""===e)return"No response data";let t;try{t="string"==typeof e?e:JSON.stringify(e)}catch{t=String(e)}return t.length>500?t.substring(0,500)+"...":t}(n)}`;super(c,{cause:i}),this.status=t,this.statusText=r,this.data=n,this.response=a,this.url=o,this.method=s,this.cause=i}},t=class extends Error{name="NetworkError";cause;constructor(e,t){super(e,{cause:t}),this.cause=t}},r=class extends Error{name="SchemaValidationError";schema;data;issues;cause;constructor(e,t,r,n,a){super(e,{cause:n}),this.schema=t,this.data=r,this.issues=a,this.cause=n}},n=class extends Error{name="TimeoutError";cause;constructor(e,t){super(e,{cause:t}),this.cause=t}},a=class extends Error{name="PathParameterError";url;requiredParams;providedParams;cause;constructor(e,t,r,n,a){super(`${e}\nURL Template: ${t}\nExpected: [${r.map(e=>`"${e}"`).join(", ")}], Actual: [${n.map(e=>`"${e}"`).join(", ")}]`,{cause:a}),this.url=t,this.requiredParams=r,this.providedParams=n,this.cause=a}},o=class extends Error{name="MiddlewareError";type;url;method;cause;constructor(e,t,r,n,a){const o=r?`Request: ${n||"UNKNOWN"} ${r}`:"";super(o?`${e}\n${o}`:e,{cause:a}),this.type=t,this.url=r,this.method=n,this.cause=a}},s=class extends Error{name="SerializationError";cause;constructor(e,t){super(e,{cause:t}),this.cause=t}},i=class extends Error{name="InvalidSchemaError";schema;cause;constructor(e,t,r){super(e,{cause:r}),this.schema=t,this.cause=r}},c=class extends Error{name="AsyncSchemaValidationError";schema;cause;constructor(e,t,r){super(e,{cause:r}),this.schema=t,this.cause=r}},u=class extends Error{name="InvalidBaseUrlError";baseUrl;cause;constructor(e,t,r){super(`${e}\nBase URL: ${t}`,{cause:r}),this.baseUrl=t,this.cause=r}};function d(e,t={}){return function(e,t){const r=e.match(/(^|\/):([^/\s?#]+)\?(?=\/)/);if(!r)return;const[,,n]=r;throw new a(`Optional path parameter "${n}" is not supported here. Optional path parameters are only supported at the end of the path.`,e,[n],t)}(e,Object.keys(t)),e.replace(/(^|\/):([^/\s?#]+?)(\?)?(?=\/|$|[?#])/g,(r,n,o,s)=>{const i="?"===s;if(!/^[a-zA-Z0-9_]+$/.test(o))throw new a(`Invalid path parameter name: "${o}"`,e,[o],Object.keys(t));const c=t[o];if(void 0===c){if(i)return"";throw new a(`Missing required path parameter: "${o}"`,e,[o],Object.keys(t))}return`${n}${encodeURIComponent(String(c))}`})}function l(e,t,r,n){let a=0,o=!1,s=!1;const i=()=>{if(!o){o=!0;try{e.releaseLock()}catch{}}},c=()=>{s=!0,i()};return n?.addEventListener("abort",c),new ReadableStream({async start(o){try{for(;!s;){const{done:n,value:s}=await e.read();if(n)break;a+=s.length,t(s,r,a),o.enqueue(s)}s||o.close()}catch(u){throw s||o.error(u),u}finally{n?.removeEventListener("abort",c),i()}},cancel(){s=!0,n?.removeEventListener("abort",c),i()}})}async function f(e,t){if(!t||!e.body)return e;if(!e.body.getReader)return e;const r=l(e.body.getReader(),(e,r,n)=>{t({chunk:e,totalBytes:r,transferredBytes:n})},e.headers.get("content-length")?parseInt(e.headers.get("content-length")||"0",10):void 0,e.signal);return new Request(e.url,{method:e.method,headers:e.headers,body:r,signal:e.signal,credentials:e.credentials,cache:e.cache,mode:e.mode,redirect:e.redirect,referrer:e.referrer,referrerPolicy:e.referrerPolicy,integrity:e.integrity,keepalive:e.keepalive,duplex:"half"})}async function h(e,t){if(!t||!e.body)return e;if(!e.body.getReader)return e;const r=l(e.body.getReader(),(e,r,n)=>{t({chunk:e,totalBytes:r,transferredBytes:n})},e.headers.get("content-length")?parseInt(e.headers.get("content-length")||"0",10):void 0);return new Response(r,{status:e.status,statusText:e.statusText,headers:e.headers})}var p={maxRetries:3,retryDelay:300,backoffFactor:2,retryStatusCodes:[408,429,500,502,503,504],retryNetworkErrors:!0,maxRetryDelay:3e4,retryMethods:["GET","HEAD","OPTIONS","PUT","DELETE"],retryUnsafeMethods:!1,jitter:"none",respectRetryAfter:!0};function m(e={}){const{baseUrl:t="",headers:r={},timeout:a=3e4,fetch:s,serializeBody:i,serializeParams:c,onRequestMiddleware:l,onResponseMiddleware:m}=e,x=void 0===s;return async function(N,q={}){const{method:D="GET",headers:k={},params:B,pathParams:C,body:I,timeout:H=a,signal:W,credentials:z,cache:V,mode:F,redirect:J,fetchOptions:G,onUploadStreaming:Z,onDownloadStreaming:K,responseType:_,retry:Q}=q;let X=void 0===C?d(N):d(N,C);t&&(X=function(e,t){return L(t)?t:L(e)?function(e,t){const r=new URL(e),n=r.pathname.replace(/\/$/,""),{path:a,search:o,hash:s}=T(t);a.startsWith("/")?r.pathname=n+a:a&&(r.pathname=n+"/"+a);o&&(r.search=O(r.search,o));s&&(r.hash=s);return r.toString()}(e,t):function(e,t){const{path:r,search:n,hash:a}=T(e),{path:o,search:s,hash:i}=T(t);return`${o?function(e,t){return e?t?t.startsWith("/")?`${e}${t}`:`${e}/${t}`:e:t.startsWith("/")?t:`/${t}`}(r,o):r||o}${O(n,s)}${i||a}`}(e,t)}(t,X));const Y=function(e,t){const r={...e??{}};void 0!==t.cache&&(r.cache=t.cache);void 0!==t.credentials&&(r.credentials=t.credentials);void 0!==t.mode&&(r.mode=t.mode);void 0!==t.redirect&&(r.redirect=t.redirect);return r}(G,{cache:V,credentials:z,mode:F,redirect:J}),ee={url:X,method:D,params:B,headers:new Headers({...r,...k}),body:I,signal:W,fetchOptions:Y};let te=ee;if(l)try{te=await l({...ee,headers:new Headers(ee.headers),fetchOptions:{...ee.fetchOptions}})}catch(ie){throw new o(v("Request middleware failed",ie),"request",te.url,te.method,R(ie,"Request middleware"))}if(te.params){const e=c?c(te.params):function(e){const t=new URLSearchParams;for(const[r,n]of Object.entries(e))if(Array.isArray(n))for(const e of n)null!=e&&t.append(r,String(e));else null!=n&&t.append(r,String(n));return t.toString()}(te.params);e&&(te.url=function(e,t){const r=t.startsWith("?")?t.slice(1):t;if(!r)return e;const{path:n,search:a,hash:o}=T(e);return`${n}${a?`${a}&${r}`:`?${r}`}${o}`}(te.url,e))}!function(e,t){if(!t||L(e)||"undefined"!=typeof window&&void 0!==window.location&&"null"!==window.location.origin)return;throw new u(`Relative request URL "${e}" requires an absolute baseUrl in non-browser environments. Pass an absolute baseUrl or use a custom fetch implementation.`,e)}(te.url,x);const re={method:te.method,headers:te.headers,...te.fetchOptions};if(void 0!==te.body&&"GET"!==te.method&&"HEAD"!==te.method){let e,t;if(i){const t=i(te.body);e=null==t?"":t}else{const r=function(e){if(ArrayBuffer.isView(e)){const t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);return{body:new Uint8Array(t).buffer}}return"string"==typeof e||e instanceof FormData||e instanceof URLSearchParams||e instanceof ArrayBuffer||e instanceof Blob||e instanceof ReadableStream?{body:e}:function(e){return null!==e&&"object"==typeof e&&(Array.isArray(e)||"toJSON"in e&&"function"==typeof e.toJSON||"[object Object]"===Object.prototype.toString.call(e))}(e)?{body:JSON.stringify(e),contentType:"application/json"}:null==e?{body:""}:{body:String(e)}}(te.body);e=r.body,t=r.contentType}re.body=e,t&&te.headers.set("content-type",t),re.duplex="half"}const ne=function(e,t){const r="object"==typeof e?e:void 0,n=!0===e||void 0!==r||!0===t||"object"==typeof t;if(!1===t)return;if(!n)return;const a={...p,...r};return!0===t?a:"object"==typeof t?{...a,...t}:a}(e.retry,Q),ae=ne?.maxRetries??0,oe=function(e){return!(e instanceof ReadableStream)}(re.body);let se;for(let e=0;e<=ae;e+=1){const t=new AbortController;let r=!1;const a=setTimeout(()=>{r=!0,t.abort()},H),{signal:i,cleanup:c}=$(te.signal,t.signal);let u=!1;const d=()=>{u||(u=!0,clearTimeout(a),c())};try{const e={...re,headers:te.headers,signal:i,...te.fetchOptions};if(Z&&void 0!==e.body){const t=await f(P(te.url,e),Z);e.body=t.body??void 0,e.headers=t.headers}const t=await j(s??globalThis.fetch,te.url,e),r=K?await h(t,K):t,n=await y(r,{responseType:_,method:te.method,url:te.url,tolerateParseError:!U(r.status)});let a=n;if(m)try{const e=await m(n);if(!A(e))throw new o("Response middleware must return a valid ResponseType object","response",te.url,te.method);a=e}catch(ie){throw new o(v("Response middleware failed",ie),"response",te.url,te.method,R(ie,"Response middleware"))}if(!U(a.status))throw S(a,n.parseError);return a}catch(ie){if(se=R(ie,"Request execution"),M(se)&&r&&(se=new n(`Request timeout after ${H}ms`,se)),e>=ae||!(await b(se,e,ne,{bodyReplayable:oe,method:te.method,url:te.url})))throw se;const t=w(e,ne,se);await g(ne,{bodyReplayable:oe,delay:t,error:se,method:te.method,nextAttempt:e+1,retryCount:e,url:te.url}),d(),await E(t,te.signal)}finally{d()}}throw new Error("Retry loop terminated unexpectedly")}}async function y(e,t){const r=Object.fromEntries(e.headers.entries());let n,a;const o=e.clone();try{const r=t.responseType,a=e.headers.get("content-type")??"",s=a.includes("application/json")?"json":a.includes("text/")?"text":a.includes("application/octet-stream")||a.includes("application/pdf")||a.includes("image/")||a.includes("video/")||a.includes("audio/")?"arrayBuffer":a.includes("multipart/form-data")||a.includes("application/x-www-form-urlencoded")?"formData":void 0,i=r??s;if("json"===i)n=await e.json();else if("text"===i)n=await e.text();else if("blob"===i)n=await e.blob();else if("arrayBuffer"===i)n=await e.arrayBuffer();else if("formData"===i)n=await e.formData();else try{n=await e.json()}catch{n=await o.text()}}catch(i){if(a=new s(v("Failed to parse response body",i),i instanceof Error?i:void 0),!t.tolerateParseError)throw a;try{n=await o.text()}catch{n=""}}return{data:n,status:e.status,statusText:e.statusText,headers:r,method:t.method,url:t.url,raw:e,parseError:a}}async function b(r,n,a,o){if(!a)return!1;const s={...o,error:r,retryCount:n};return a.shouldRetry?await a.shouldRetry(r,n,s):!(!o.bodyReplayable||!function(e,t){if(t.retryUnsafeMethods)return!0;const r=e.toUpperCase();return t.retryMethods.some(e=>e.toUpperCase()===r)}(o.method,a))&&(r instanceof e?a.retryStatusCodes.includes(r.status):(r instanceof t||"TypeError"===r.name&&!function(e){return e.message.includes("Invalid URL")||e.message.includes("Failed to parse URL")}(r))&&a.retryNetworkErrors)}function w(t,r,n){if(!r)return 0;const a=r.respectRetryAfter?function(t){if(!(t instanceof e))return;const r=t.response.headers.get("retry-after");if(!r)return;const n=Number(r);if(Number.isFinite(n))return Math.max(0,1e3*n);const a=Date.parse(r);if(Number.isNaN(a))return;return Math.max(0,a-Date.now())}(n):void 0;if(void 0!==a)return Math.min(a,r.maxRetryDelay);const o=r.retryDelay*Math.pow(r.backoffFactor,t);return function(e,t,r){return"function"==typeof t?Math.max(0,t(e,r)):"full"===t?Math.floor(Math.random()*e):"equal"===t?Math.floor(e/2+Math.random()*(e/2)):e}(Math.min(o,r.maxRetryDelay),r.jitter,t)}async function g(e,t){await(e?.onRetry?.(t))}function v(e,t){return`${e}: ${t instanceof Error?t.message:String(t)}`}function E(e,t){return e<=0?Promise.resolve():t?.aborted?Promise.reject(x(t.reason)):new Promise((r,n)=>{const a=setTimeout(()=>{t?.removeEventListener("abort",o),r()},e),o=()=>{clearTimeout(a),t?.removeEventListener("abort",o),n(x(t?.reason))};t?.addEventListener("abort",o,{once:!0})})}function x(e){if(e instanceof Error)return e;const t=new Error("The operation was aborted");return t.name="AbortError",t}function $(e,t){if(!e&&!t)return{signal:void 0,cleanup:()=>{}};if(!e)return{signal:t,cleanup:()=>{}};if(!t)return{signal:e,cleanup:()=>{}};if(e?.aborted)return{signal:e,cleanup:()=>{}};if(t.aborted)return{signal:t,cleanup:()=>{}};const r=new AbortController,n=e=>{const t=e.target;t instanceof AbortSignal?r.abort(t.reason):r.abort()};return e.addEventListener("abort",n,{once:!0}),t.addEventListener("abort",n,{once:!0}),{signal:r.signal,cleanup:()=>{e.removeEventListener("abort",n),t.removeEventListener("abort",n)}}}function R(e,t){return e instanceof Error?e:new Error(`${t}: ${String(e)}`)}async function j(e,r,n){try{return await e(r,n)}catch(a){const e=R(a,"Network request failed");if(M(e)||e instanceof t)throw e;throw new t(e.message,e)}}function S(t,r){return new e(`HTTP ${t.status} ${t.statusText}`,t.status,t.statusText,t.data,t.raw,t.url,t.method,r)}function T(e){const t=e.indexOf("#"),r=-1===t?"":e.slice(t),n=-1===t?e:e.slice(0,t),a=n.indexOf("?");return{path:-1===a?n:n.slice(0,a),search:-1===a?"":n.slice(a),hash:r}}function O(e,t){return e?t?`${e}&${t.slice(1)}`:e:t}function P(e,t){return new Request(function(e){return L(e)?e:e?`https://1000fetches.local${e.startsWith("/")?e:`/${e}`}`:"https://1000fetches.local/"}(e),t)}function U(e){return e>=200&&e<300}function A(e){return null!==e&&"object"==typeof e&&"data"in e&&"status"in e&&"number"==typeof e.status&&"statusText"in e&&"string"==typeof e.statusText&&"headers"in e&&"object"==typeof e.headers&&null!==e.headers&&"method"in e&&"string"==typeof e.method&&"url"in e&&"string"==typeof e.url&&"raw"in e&&e.raw instanceof Response}function L(e){return/^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(e)}function M(e){return e instanceof Error&&"AbortError"===e.name}function N(e,t,n){if(n.issues)throw new r(JSON.stringify(n.issues),e,t,void 0,n.issues);return n.value}function q(){return{validate(e,t){if(null===(r=e)||"object"!=typeof r&&"function"!=typeof r||!("~standard"in r)||"object"!=typeof r["~standard"]||null===r["~standard"]||!("validate"in r["~standard"])||"function"!=typeof r["~standard"].validate||!("version"in r["~standard"])||1!==r["~standard"].version||!("vendor"in r["~standard"])||"string"!=typeof r["~standard"].vendor)throw new i("Schema must implement the Standard Schema interface",e);var r;const n=e["~standard"].validate(t);return null===(a=n)||"object"!=typeof a&&"function"!=typeof a||!("then"in a)||"function"!=typeof a.then?N(e,t,n):Promise.resolve(n).then(r=>N(e,t,r));var a}}}function D(e){if(!e)return"";if(e.startsWith("/"))return e.replace(/\/$/,"");try{new URL(e)}catch{throw new u(`Invalid baseUrl: "${e}". Must be a valid absolute URL or relative path starting with "/".`,e)}return e.endsWith("/")?e.slice(0,-1):e}function k(e,t,n,a){const o=n(e,t);return Object.assign(o,{schema:e=>function(e){const t=e;return t.data=async()=>(await e).data,t.void=async()=>{await e},t}(o.then(async t=>{try{const r=await a.validate(e,t.data);return{...t,data:r}}catch(n){if(n instanceof i||n instanceof r)throw n;throw new r(n instanceof Error?n.message:"Schema validation failed",e,t.data,n instanceof Error?n:void 0)}})),data:async()=>(await o).data,async void(){await o}})}function B(e={}){const t=m({...e,baseUrl:D(e.baseUrl)}),r=e.schemaValidator??q();return{get:function(e,...n){return k(e,{...n[0]??{},method:"GET"},t,r)},post:(e,n,...a)=>k(e,{...a[0]??{},method:"POST",body:n},t,r),put:(e,n,...a)=>k(e,{...a[0]??{},method:"PUT",body:n},t,r),patch:(e,n,...a)=>k(e,{...a[0]??{},method:"PATCH",body:n},t,r),delete:(e,...n)=>k(e,{...n[0]??{},method:"DELETE"},t,r),request:(e,...n)=>k(e,n[0]??{},t,r)}}Object.defineProperty(exports,"AsyncSchemaValidationError",{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,"HttpError",{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,"InvalidBaseUrlError",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"InvalidSchemaError",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"MiddlewareError",{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,"NetworkError",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"PathParameterError",{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,"SchemaValidationError",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"SerializationError",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"TimeoutError",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"createHttpClient",{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,"createSchemaValidator",{enumerable:!0,get:function(){return q}});
|
|
2
|
-
//# sourceMappingURL=client-C7dvgNnD.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client-C7dvgNnD.js","names":[],"sources":["../src/errors.ts","../src/utils/path.ts","../src/utils/streaming.ts","../src/core.ts","../src/schema.ts","../src/client.ts"],"sourcesContent":["import type { StandardSchemaV1 } from '@standard-schema/spec'\n\ninterface HttpClientError {\n name: string\n message: string\n cause?: Error\n stack?: string\n}\n\nfunction formatErrorData(data: unknown): string {\n if (data === null || data === undefined || data === '') {\n return 'No response data'\n }\n\n let dataString: string\n\n try {\n dataString = typeof data === 'string' ? data : JSON.stringify(data)\n } catch {\n dataString = String(data)\n }\n\n return dataString.length > 500\n ? dataString.substring(0, 500) + '...'\n : dataString\n}\n\nexport class HttpError<TErrorData = unknown>\n extends Error\n implements HttpClientError\n{\n public readonly name = 'HttpError'\n public readonly status: number\n public readonly statusText: string\n public readonly data: TErrorData\n public readonly response: Response\n public readonly url: string\n public readonly method: string\n public override readonly cause?: Error\n\n constructor(\n message: string,\n status: number,\n statusText: string,\n data: TErrorData,\n response: Response,\n url: string,\n method: string,\n cause?: Error\n ) {\n const statusCategory =\n status >= 500\n ? 'Server Error'\n : status >= 400\n ? 'Client Error'\n : status >= 300\n ? 'Redirect'\n : 'Success'\n\n const enhancedMessage = `HTTP ${statusCategory} (${status}): ${message}\nRequest: ${method} ${url}\nData: ${formatErrorData(data)}`\n\n super(enhancedMessage, { cause })\n this.status = status\n this.statusText = statusText\n this.data = data\n this.response = response\n this.url = url\n this.method = method\n this.cause = cause\n }\n}\n\nexport class NetworkError extends Error implements HttpClientError {\n public readonly name = 'NetworkError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n this.cause = cause\n }\n}\n\nexport class SchemaValidationError extends Error implements HttpClientError {\n public readonly name = 'SchemaValidationError'\n public readonly schema: unknown\n public readonly data: unknown\n public readonly issues?: ReadonlyArray<StandardSchemaV1.Issue>\n public override readonly cause?: Error\n\n constructor(\n message: string,\n schema: unknown,\n data: unknown,\n cause?: Error,\n issues?: ReadonlyArray<StandardSchemaV1.Issue>\n ) {\n super(message, { cause })\n this.schema = schema\n this.data = data\n this.issues = issues\n this.cause = cause\n }\n}\n\nexport class TimeoutError extends Error implements HttpClientError {\n public readonly name = 'TimeoutError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n this.cause = cause\n }\n}\n\nexport class PathParameterError extends Error implements HttpClientError {\n public readonly name = 'PathParameterError'\n public readonly url: string\n public readonly requiredParams: string[]\n public readonly providedParams: string[]\n public override readonly cause?: Error\n\n constructor(\n message: string,\n url: string,\n requiredParams: string[],\n providedParams: string[],\n cause?: Error\n ) {\n const enhancedMessage = `${message}\nURL Template: ${url}\nExpected: [${requiredParams.map(p => `\"${p}\"`).join(', ')}], Actual: [${providedParams.map(p => `\"${p}\"`).join(', ')}]`\n\n super(enhancedMessage, { cause })\n this.url = url\n this.requiredParams = requiredParams\n this.providedParams = providedParams\n this.cause = cause\n }\n}\n\nexport class MiddlewareError extends Error implements HttpClientError {\n public readonly name = 'MiddlewareError'\n public readonly type: 'request' | 'response'\n public readonly url?: string\n public readonly method?: string\n public override readonly cause?: Error\n\n constructor(\n message: string,\n type: 'request' | 'response',\n url?: string,\n method?: string,\n cause?: Error\n ) {\n const requestInfo = url ? `Request: ${method || 'UNKNOWN'} ${url}` : ''\n const enhancedMessage = requestInfo ? `${message}\\n${requestInfo}` : message\n\n super(enhancedMessage, { cause })\n this.type = type\n this.url = url\n this.method = method\n this.cause = cause\n }\n}\n\nexport class SerializationError extends Error implements HttpClientError {\n public readonly name = 'SerializationError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n this.cause = cause\n }\n}\n\nexport class InvalidSchemaError extends Error implements HttpClientError {\n public readonly name = 'InvalidSchemaError'\n public readonly schema: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n this.cause = cause\n }\n}\n\nexport class AsyncSchemaValidationError\n extends Error\n implements HttpClientError\n{\n public readonly name = 'AsyncSchemaValidationError'\n public readonly schema: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n this.cause = cause\n }\n}\n\nexport class InvalidBaseUrlError extends Error implements HttpClientError {\n public readonly name = 'InvalidBaseUrlError'\n public readonly baseUrl: string\n public override readonly cause?: Error\n\n constructor(message: string, baseUrl: string, cause?: Error) {\n const enhancedMessage = `${message}\nBase URL: ${baseUrl}`\n\n super(enhancedMessage, { cause })\n this.baseUrl = baseUrl\n this.cause = cause\n }\n}\n","import { PathParameterError } from '../errors'\n\n/**\n * Strips protocol from URL (e.g., https://, http://)\n */\ntype StripProtocol<T extends string> = T extends `${string}://${infer After}`\n ? After\n : T\n\n/**\n * Strips host and optional port from URL, keeping only the path\n * Handles cases like \"localhost:3000/users\" -> \"/users\"\n */\ntype StripHost<T extends string> = T extends `${infer _Host}/${infer Path}`\n ? `/${Path}`\n : T\n\n/**\n * Strips query string from path (e.g., \"/users?x=1\" -> \"/users\")\n * Only strips ? that comes after the path, not ? that's part of path parameters\n */\ntype StripQuery<T extends string> = T extends `${infer Path}?${infer Query}`\n ? Query extends\n | `${string}=${string}`\n | `${string}&${string}`\n | `${string}=${string}&${string}`\n ? Path // Contains query parameters (has = or &)\n : Query extends `/${string}`\n ? T // It's another path segment, not a query\n : Query extends ``\n ? T // It's an optional param marker (?)\n : Path // Plain query params like ?param\n : T\n\n/**\n * Normalizes URL to path only, stripping protocol, host, port, and query\n */\ntype NormalizePath<T extends string> = StripQuery<StripHost<StripProtocol<T>>>\n\n/**\n * Removes optional suffix from param name (e.g., \":id?\" -> \"id\", \":id\" -> \"id\")\n */\ntype CleanParamName<S extends string> = S extends `:${infer Name}?`\n ? Name\n : S extends `:${infer Name}`\n ? Name\n : S\n\n/**\n * Extracts required path parameters from a route\n */\ntype ExtractRequiredRouteParams<T extends string> =\n NormalizePath<T> extends `${infer _Before}:${infer AfterColon}`\n ? AfterColon extends `${infer Param}/${infer Rest}`\n ? Param extends `${string}?`\n ? ExtractRequiredRouteParams<`/${Rest}`>\n : CleanParamName<`:${Param}`> | ExtractRequiredRouteParams<`/${Rest}`>\n : AfterColon extends `${string}?`\n ? never\n : CleanParamName<`:${AfterColon}`>\n : never\n\n/**\n * Extracts optional path parameters from a route\n */\ntype ExtractOptionalRouteParams<T extends string> =\n NormalizePath<T> extends `${infer _Before}:${infer AfterColon}`\n ? AfterColon extends `${infer Param}/${infer Rest}`\n ?\n | (Param extends `${string}?` ? CleanParamName<`:${Param}`> : never)\n | ExtractOptionalRouteParams<`/${Rest}`>\n : AfterColon extends `${string}?`\n ? CleanParamName<`:${AfterColon}`>\n : never\n : never\n\ntype ExtractRouteParams<T extends string> =\n | ExtractRequiredRouteParams<T>\n | ExtractOptionalRouteParams<T>\n\ntype HasNonTrailingOptionalRouteParams<T extends string> = string extends T\n ? false\n : NormalizePath<T> extends `${infer _Before}:${infer AfterColon}`\n ? AfterColon extends `${infer Param}/${infer Rest}`\n ? Param extends `${string}?`\n ? true\n : HasNonTrailingOptionalRouteParams<`/${Rest}`>\n : false\n : false\n\nexport type AssertSupportedPath<Path extends string> = string extends Path\n ? Path\n : HasNonTrailingOptionalRouteParams<Path> extends true\n ? never\n : Path\n\nexport type HasRequiredParams<T extends string> = [\n ExtractRequiredRouteParams<T>,\n] extends [never]\n ? false\n : true\n\ntype HasPathParams<T extends string> = [ExtractRouteParams<T>] extends [never]\n ? false\n : true\n\ntype Simplify<T> = { [K in keyof T]: T[K] }\n\n/**\n * PathParams type - extracts parameter names and their types\n */\nexport type PathParams<Path extends string> = [\n AssertSupportedPath<Path>,\n] extends [never]\n ? never\n : Simplify<\n {\n [K in ExtractRequiredRouteParams<Path>]: string | number\n } & {\n [K in ExtractOptionalRouteParams<Path>]?: string | number\n }\n >\n\n/**\n * RequirePathParams enforces pathParams when needed\n */\nexport type RequirePathParams<Path extends string, T> = [\n AssertSupportedPath<Path>,\n] extends [never]\n ? never\n : HasRequiredParams<Path> extends true\n ? T & { pathParams: PathParams<Path> }\n : HasPathParams<Path> extends true\n ? T & { pathParams?: PathParams<Path> }\n : T\n\n/**\n * Interpolates parameters into a URL template\n * Similar to React Router's generatePath function\n *\n * @example\n * ```ts\n * const path = generatePath('/users/:id/posts/:postId', { id: '123', postId: '456' });\n * // => '/users/123/posts/456'\n * ```\n */\nexport function generatePath<Path extends string>(\n path: AssertSupportedPath<Path>\n): string\nexport function generatePath<Path extends string>(\n path: AssertSupportedPath<Path>,\n params: PathParams<Path>\n): string\nexport function generatePath(\n path: string,\n params: Record<string, string | number | undefined> = {}\n): string {\n validateSupportedOptionalPath(path, Object.keys(params))\n\n return path.replace(\n /(^|\\/):([^/\\s?#]+?)(\\?)?(?=\\/|$|[?#])/g,\n (_match, prefix: string, paramName: string, optionalMarker?: string) => {\n const isOptional = optionalMarker === '?'\n\n // Validate parameter name\n if (!/^[a-zA-Z0-9_]+$/.test(paramName)) {\n throw new PathParameterError(\n `Invalid path parameter name: \"${paramName}\"`,\n path,\n [paramName],\n Object.keys(params)\n )\n }\n\n // Get and validate parameter value\n const paramValue = params[paramName]\n\n if (paramValue === undefined) {\n if (isOptional) {\n return ''\n }\n\n throw new PathParameterError(\n `Missing required path parameter: \"${paramName}\"`,\n path,\n [paramName],\n Object.keys(params)\n )\n }\n\n return `${prefix}${encodeURIComponent(String(paramValue))}`\n }\n )\n}\n\nfunction validateSupportedOptionalPath(\n path: string,\n providedParams: string[]\n): void {\n const invalidOptionalMatch = path.match(/(^|\\/):([^/\\s?#]+)\\?(?=\\/)/)\n\n if (!invalidOptionalMatch) {\n return\n }\n\n const [, , paramName] = invalidOptionalMatch\n\n throw new PathParameterError(\n `Optional path parameter \"${paramName}\" is not supported here. Optional path parameters are only supported at the end of the path.`,\n path,\n [paramName],\n providedParams\n )\n}\n","import type { DownloadStreamingEvent, UploadStreamingEvent } from '../types'\n\nfunction createStreamingStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n onChunk: (\n chunk: Uint8Array,\n totalBytes: number | undefined,\n transferredBytes: number\n ) => void,\n totalBytes: number | undefined,\n signal?: AbortSignal\n): ReadableStream<Uint8Array> {\n let transferredBytes = 0\n let readerReleased = false\n let isAborted = false\n\n const releaseReader = () => {\n if (!readerReleased) {\n readerReleased = true\n try {\n reader.releaseLock()\n } catch {\n // Reader might already be released, ignore\n }\n }\n }\n\n // Handle abort signal\n const abortHandler = () => {\n isAborted = true\n releaseReader()\n }\n\n signal?.addEventListener('abort', abortHandler)\n\n return new ReadableStream({\n async start(controller) {\n try {\n while (!isAborted) {\n const { done, value } = await reader.read()\n if (done) break\n\n transferredBytes += value.length\n onChunk(value, totalBytes, transferredBytes)\n controller.enqueue(value)\n }\n\n if (!isAborted) {\n controller.close()\n }\n } catch (error) {\n if (!isAborted) {\n controller.error(error)\n }\n throw error\n } finally {\n signal?.removeEventListener('abort', abortHandler)\n releaseReader()\n }\n },\n cancel() {\n isAborted = true\n signal?.removeEventListener('abort', abortHandler)\n releaseReader()\n },\n })\n}\n\n/**\n * Creates a request with upload streaming tracking\n */\nexport async function toStreamableRequest(\n request: Request,\n onUploadStreaming?: (event: UploadStreamingEvent) => void\n): Promise<Request> {\n if (!onUploadStreaming || !request.body) {\n return request\n }\n\n if (!request.body.getReader) {\n return request\n }\n\n const reader = request.body.getReader()\n const totalBytes = request.headers.get('content-length')\n ? parseInt(request.headers.get('content-length') || '0', 10)\n : undefined\n\n const stream = createStreamingStream(\n reader,\n (chunk, totalBytes, transferredBytes) => {\n onUploadStreaming({\n chunk,\n totalBytes,\n transferredBytes,\n })\n },\n totalBytes,\n request.signal\n )\n\n return new Request(request.url, {\n method: request.method,\n headers: request.headers,\n body: stream,\n signal: request.signal,\n credentials: request.credentials,\n cache: request.cache,\n mode: request.mode,\n redirect: request.redirect,\n referrer: request.referrer,\n referrerPolicy: request.referrerPolicy,\n integrity: request.integrity,\n keepalive: request.keepalive,\n duplex: 'half',\n } as RequestInit)\n}\n\n/**\n * Creates a response with download streaming tracking\n */\nexport async function toStreamableResponse(\n response: Response,\n onDownloadStreaming?: (event: DownloadStreamingEvent) => void\n): Promise<Response> {\n if (!onDownloadStreaming || !response.body) {\n return response\n }\n\n if (!response.body.getReader) {\n return response\n }\n\n const reader = response.body.getReader()\n const totalBytes = response.headers.get('content-length')\n ? parseInt(response.headers.get('content-length') || '0', 10)\n : undefined\n\n const stream = createStreamingStream(\n reader,\n (chunk, totalBytes, transferredBytes) => {\n onDownloadStreaming({\n chunk,\n totalBytes,\n transferredBytes,\n })\n },\n totalBytes\n )\n\n return new Response(stream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n })\n}\n","import {\n HttpError,\n InvalidBaseUrlError,\n MiddlewareError,\n NetworkError,\n SerializationError,\n TimeoutError,\n} from './errors'\nimport type { SchemaValidator } from './schema'\nimport type {\n CustomFetch,\n DownloadStreamingEvent,\n ExtendedRequestInit,\n FetchOptions,\n HttpHeaders,\n HttpMethod,\n RequestContext,\n RequestParamsType,\n ResponseType,\n RetryContext,\n RetryEvent,\n RetryOptions,\n SerializeBody,\n SerializeParams,\n UploadStreamingEvent,\n} from './types'\nimport {\n type AssertSupportedPath,\n generatePath,\n toStreamableRequest,\n toStreamableResponse,\n type PathParams,\n} from './utils'\n\ntype ResolvedRetryOptions = {\n maxRetries: number\n retryDelay: number\n backoffFactor: number\n retryStatusCodes: number[]\n retryNetworkErrors: boolean\n maxRetryDelay: number\n retryMethods: readonly HttpMethod[]\n retryUnsafeMethods: boolean\n jitter: NonNullable<RetryOptions['jitter']>\n respectRetryAfter: boolean\n shouldRetry?: RetryOptions['shouldRetry']\n onRetry?: RetryOptions['onRetry']\n}\n\ntype ParsedResponse<T> = ResponseType<T> & {\n parseError?: SerializationError\n}\n\nconst DEFAULT_RETRY_OPTIONS: Omit<\n ResolvedRetryOptions,\n 'shouldRetry' | 'onRetry'\n> = {\n maxRetries: 3,\n retryDelay: 300,\n backoffFactor: 2,\n retryStatusCodes: [408, 429, 500, 502, 503, 504],\n retryNetworkErrors: true,\n maxRetryDelay: 30_000,\n retryMethods: ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'],\n retryUnsafeMethods: false,\n jitter: 'none',\n respectRetryAfter: true,\n}\n\nexport interface HttpRequestOptions<\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n> {\n method?: HttpMethod\n headers?: HttpHeaders\n /** Query parameters */\n params?: TParams\n /** Path parameters for URL template */\n pathParams?: Record<string, string | number | undefined>\n /** Request body */\n body?: TBody\n timeout?: number\n signal?: AbortSignal\n /** Fetch options */\n credentials?: RequestCredentials\n cache?: RequestCache\n mode?: RequestMode\n redirect?: RequestRedirect\n /** Additional Fetch/Node options passed through to the underlying fetch call */\n fetchOptions?: FetchOptions\n /** Upload streaming tracking for this specific request */\n onUploadStreaming?: (event: UploadStreamingEvent) => void\n /** Download streaming tracking for this specific request */\n onDownloadStreaming?: (event: DownloadStreamingEvent) => void\n /** Response type override */\n responseType?: 'json' | 'text' | 'blob' | 'arrayBuffer' | 'formData'\n /** Per-request retry configuration */\n retry?: RetryOptions | boolean\n}\n\nexport interface HttpClientConfig {\n /** Base URL for all requests */\n baseUrl?: string\n /** Default headers */\n headers?: HttpHeaders\n /** Default timeout */\n timeout?: number\n /** Schema validator */\n schemaValidator?: SchemaValidator\n /** Default retry configuration */\n retry?: RetryOptions | boolean\n /** Custom fetch implementation */\n fetch?: CustomFetch\n /** Custom body serializer */\n serializeBody?: SerializeBody\n /** Custom params serializer */\n serializeParams?: SerializeParams\n /** Request middleware - can modify request before sending */\n onRequestMiddleware?: <TBody = unknown>(\n context: RequestContext<TBody>\n ) => RequestContext<TBody> | Promise<RequestContext<TBody>>\n /** Response middleware - can modify response after receiving */\n onResponseMiddleware?: (\n response: ResponseType<unknown>\n ) => ResponseType<unknown> | Promise<ResponseType<unknown>>\n}\n\n/**\n * Creates an HTTP request handler with the given configuration.\n * This is the core function that handles all HTTP requests with retry logic,\n * interceptors, and streaming.\n */\nexport function createHttpRequest(config: HttpClientConfig = {}) {\n const {\n baseUrl = '',\n headers: defaultHeaders = {},\n timeout: defaultTimeout = 30_000,\n fetch: customFetch,\n serializeBody: customSerializeBody,\n serializeParams: customSerializeParams,\n onRequestMiddleware,\n onResponseMiddleware,\n } = config\n const usesNativeFetch = customFetch === undefined\n\n return async function fetcher<\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options: HttpRequestOptions<TBody, TParams> = {}\n ): Promise<ResponseType<TResponse>> {\n const {\n method = 'GET',\n headers = {},\n params,\n pathParams,\n body,\n timeout = defaultTimeout,\n signal,\n credentials,\n cache,\n mode,\n redirect,\n fetchOptions,\n onUploadStreaming,\n onDownloadStreaming,\n responseType,\n retry: requestRetry,\n } = options\n\n let resolvedUrl =\n pathParams === undefined\n ? generatePath(url as AssertSupportedPath<Path>)\n : generatePath(\n url as AssertSupportedPath<Path>,\n pathParams as PathParams<Path>\n )\n\n if (baseUrl) {\n resolvedUrl = constructUrl(baseUrl, resolvedUrl)\n }\n\n const requestFetchOptions = mergeFetchOptions(fetchOptions, {\n cache,\n credentials,\n mode,\n redirect,\n })\n\n const baseRequestContext: RequestContext<TBody> = {\n url: resolvedUrl,\n method,\n params,\n headers: new Headers({ ...defaultHeaders, ...headers }),\n body,\n signal,\n fetchOptions: requestFetchOptions,\n }\n\n let requestContext: RequestContext<TBody> = baseRequestContext\n\n if (onRequestMiddleware) {\n try {\n // prevent middleware from mutating the original context\n const contextCopy: RequestContext<TBody> = {\n ...baseRequestContext,\n headers: new Headers(baseRequestContext.headers),\n fetchOptions: { ...baseRequestContext.fetchOptions },\n }\n\n requestContext = await onRequestMiddleware(contextCopy)\n } catch (error) {\n throw new MiddlewareError(\n createErrorMessage('Request middleware failed', error),\n 'request',\n requestContext.url,\n requestContext.method,\n createStandardizedError(error, 'Request middleware')\n )\n }\n }\n\n if (requestContext.params) {\n const serializedParams = customSerializeParams\n ? customSerializeParams(requestContext.params)\n : serializeQueryParams(requestContext.params)\n\n if (serializedParams) {\n requestContext.url = appendQueryString(\n requestContext.url,\n serializedParams\n )\n }\n }\n\n assertRequestUrlSupported(requestContext.url, usesNativeFetch)\n\n const baseRequestInit: ExtendedRequestInit = {\n method: requestContext.method,\n headers: requestContext.headers,\n ...requestContext.fetchOptions,\n }\n\n if (\n requestContext.body !== undefined &&\n requestContext.method !== 'GET' &&\n requestContext.method !== 'HEAD'\n ) {\n let body: BodyInit\n let contentType: string | undefined\n\n if (customSerializeBody) {\n const serializedBody = customSerializeBody(requestContext.body)\n if (serializedBody == null) {\n body = ''\n } else {\n body = serializedBody\n }\n } else {\n const serialized = serializeRequestBody(requestContext.body)\n body = serialized.body\n contentType = serialized.contentType\n }\n\n baseRequestInit.body = body\n\n if (contentType) {\n requestContext.headers.set('content-type', contentType)\n }\n\n baseRequestInit.duplex = 'half'\n }\n\n const mergedRetryOptions = resolveRetryOptions(config.retry, requestRetry)\n const maxRetries = mergedRetryOptions?.maxRetries ?? 0\n const bodyReplayable = isReplayableBody(baseRequestInit.body)\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt += 1) {\n const controller = new AbortController()\n let didTimeout = false\n const timeoutId = setTimeout(() => {\n didTimeout = true\n controller.abort()\n }, timeout)\n\n const { signal: finalSignal, cleanup: cleanupSignal } =\n createCombinedSignal(requestContext.signal, controller.signal)\n let attemptCleanedUp = false\n const cleanupAttempt = () => {\n if (attemptCleanedUp) {\n return\n }\n\n attemptCleanedUp = true\n clearTimeout(timeoutId)\n cleanupSignal()\n }\n\n try {\n const requestInit: ExtendedRequestInit = {\n ...baseRequestInit,\n headers: requestContext.headers,\n signal: finalSignal,\n ...requestContext.fetchOptions,\n }\n\n if (onUploadStreaming && requestInit.body !== undefined) {\n const streamableRequest = await toStreamableRequest(\n createInternalRequest(requestContext.url, requestInit),\n onUploadStreaming\n )\n\n requestInit.body = streamableRequest.body ?? undefined\n requestInit.headers = streamableRequest.headers\n }\n\n const response = await fetchWithNetworkError(\n customFetch ?? globalThis.fetch,\n requestContext.url,\n requestInit\n )\n\n const trackedResponse = onDownloadStreaming\n ? await toStreamableResponse(response, onDownloadStreaming)\n : response\n\n const responseData = await processResponse<TResponse>(trackedResponse, {\n responseType,\n method: requestContext.method,\n url: requestContext.url,\n tolerateParseError: !isSuccessfulStatus(trackedResponse.status),\n })\n\n let finalResponse = responseData\n\n if (onResponseMiddleware) {\n try {\n const middlewareResult = await onResponseMiddleware(responseData)\n if (!isResponseTypeLike(middlewareResult)) {\n throw new MiddlewareError(\n 'Response middleware must return a valid ResponseType object',\n 'response',\n requestContext.url,\n requestContext.method\n )\n }\n finalResponse = middlewareResult as ResponseType<TResponse>\n } catch (error) {\n throw new MiddlewareError(\n createErrorMessage('Response middleware failed', error),\n 'response',\n requestContext.url,\n requestContext.method,\n createStandardizedError(error, 'Response middleware')\n )\n }\n }\n\n if (!isSuccessfulStatus(finalResponse.status)) {\n throw createHttpError(finalResponse, responseData.parseError)\n }\n\n return finalResponse\n } catch (error) {\n lastError = createStandardizedError(error, 'Request execution')\n\n if (isAbortError(lastError) && didTimeout) {\n lastError = new TimeoutError(\n `Request timeout after ${timeout}ms`,\n lastError\n )\n }\n\n if (\n attempt >= maxRetries ||\n !(await shouldRetry(lastError, attempt, mergedRetryOptions, {\n bodyReplayable,\n method: requestContext.method,\n url: requestContext.url,\n }))\n ) {\n throw lastError\n }\n\n const delay = calculateRetryDelay(\n attempt,\n mergedRetryOptions,\n lastError\n )\n await notifyRetry(mergedRetryOptions, {\n bodyReplayable,\n delay,\n error: lastError,\n method: requestContext.method,\n nextAttempt: attempt + 1,\n retryCount: attempt,\n url: requestContext.url,\n })\n cleanupAttempt()\n await sleep(delay, requestContext.signal)\n } finally {\n cleanupAttempt()\n }\n }\n\n throw new Error('Retry loop terminated unexpectedly')\n }\n}\n\nasync function processResponse<T = unknown>(\n response: Response,\n options: {\n responseType?: 'json' | 'text' | 'blob' | 'arrayBuffer' | 'formData'\n method: HttpMethod\n url: string\n tolerateParseError?: boolean\n }\n): Promise<ParsedResponse<T>> {\n const headers = Object.fromEntries(response.headers.entries())\n\n let data: unknown\n let parseError: SerializationError | undefined\n const responseClone = response.clone()\n\n try {\n const requestedType = options.responseType\n const contentType = response.headers.get('content-type') ?? ''\n\n const detectedType:\n | 'json'\n | 'text'\n | 'arrayBuffer'\n | 'formData'\n | undefined = contentType.includes('application/json')\n ? 'json'\n : contentType.includes('text/')\n ? 'text'\n : contentType.includes('application/octet-stream') ||\n contentType.includes('application/pdf') ||\n contentType.includes('image/') ||\n contentType.includes('video/') ||\n contentType.includes('audio/')\n ? 'arrayBuffer'\n : contentType.includes('multipart/form-data') ||\n contentType.includes('application/x-www-form-urlencoded')\n ? 'formData'\n : undefined\n\n const finalType:\n | 'json'\n | 'text'\n | 'arrayBuffer'\n | 'blob'\n | 'formData'\n | undefined = requestedType ?? detectedType\n\n if (finalType === 'json') {\n data = await response.json()\n } else if (finalType === 'text') {\n data = await response.text()\n } else if (finalType === 'blob') {\n data = await response.blob()\n } else if (finalType === 'arrayBuffer') {\n data = await response.arrayBuffer()\n } else if (finalType === 'formData') {\n data = await response.formData()\n } else {\n try {\n data = await response.json()\n } catch {\n data = await responseClone.text()\n }\n }\n } catch (error) {\n parseError = new SerializationError(\n createErrorMessage('Failed to parse response body', error),\n error instanceof Error ? error : undefined\n )\n\n if (!options.tolerateParseError) {\n throw parseError\n }\n\n try {\n data = await responseClone.text()\n } catch {\n data = ''\n }\n }\n\n return {\n data: data as T,\n status: response.status,\n statusText: response.statusText,\n headers,\n method: options.method,\n url: options.url,\n raw: response,\n parseError,\n }\n}\n\nasync function shouldRetry(\n error: Error,\n retryCount: number,\n retryConfig: ResolvedRetryOptions | undefined,\n context: Pick<RetryContext, 'bodyReplayable' | 'method' | 'url'>\n): Promise<boolean> {\n if (!retryConfig) return false\n\n const retryContext: RetryContext = {\n ...context,\n error,\n retryCount,\n }\n\n if (retryConfig.shouldRetry) {\n return await retryConfig.shouldRetry(error, retryCount, retryContext)\n }\n\n if (\n !context.bodyReplayable ||\n !isRetryMethodAllowed(context.method, retryConfig)\n ) {\n return false\n }\n\n if (error instanceof HttpError) {\n return retryConfig.retryStatusCodes.includes(error.status)\n }\n\n if (\n error instanceof NetworkError ||\n (error.name === 'TypeError' && !isInvalidUrlError(error))\n ) {\n return retryConfig.retryNetworkErrors\n }\n\n return false\n}\n\nfunction calculateRetryDelay(\n attempt: number,\n retryConfig: ResolvedRetryOptions | undefined,\n error: Error\n): number {\n if (!retryConfig) return 0\n\n const retryAfterDelay = retryConfig.respectRetryAfter\n ? getRetryAfterDelay(error)\n : undefined\n\n if (retryAfterDelay !== undefined) {\n return Math.min(retryAfterDelay, retryConfig.maxRetryDelay)\n }\n\n const delay =\n retryConfig.retryDelay * Math.pow(retryConfig.backoffFactor, attempt)\n\n return applyJitter(\n Math.min(delay, retryConfig.maxRetryDelay),\n retryConfig.jitter,\n attempt\n )\n}\n\nasync function notifyRetry(\n retryConfig: ResolvedRetryOptions | undefined,\n event: RetryEvent\n): Promise<void> {\n await retryConfig?.onRetry?.(event)\n}\n\nfunction resolveRetryOptions(\n clientRetry?: RetryOptions | boolean,\n requestRetry?: RetryOptions | boolean\n): ResolvedRetryOptions | undefined {\n const clientRetryOptions =\n typeof clientRetry === 'object' ? clientRetry : undefined\n const shouldEnableRetries =\n clientRetry === true ||\n clientRetryOptions !== undefined ||\n requestRetry === true ||\n typeof requestRetry === 'object'\n\n if (requestRetry === false) {\n return undefined\n }\n\n if (!shouldEnableRetries) {\n return undefined\n }\n\n const baseRetryOptions = {\n ...DEFAULT_RETRY_OPTIONS,\n ...clientRetryOptions,\n }\n\n if (requestRetry === true) {\n return baseRetryOptions\n }\n\n if (typeof requestRetry === 'object') {\n return {\n ...baseRetryOptions,\n ...requestRetry,\n }\n }\n\n return baseRetryOptions\n}\n\nfunction mergeFetchOptions(\n fetchOptions: FetchOptions | undefined,\n aliases: Pick<RequestInit, 'cache' | 'credentials' | 'mode' | 'redirect'>\n): FetchOptions {\n const merged: FetchOptions = { ...(fetchOptions ?? {}) }\n\n if (aliases.cache !== undefined) {\n merged.cache = aliases.cache\n }\n\n if (aliases.credentials !== undefined) {\n merged.credentials = aliases.credentials\n }\n\n if (aliases.mode !== undefined) {\n merged.mode = aliases.mode\n }\n\n if (aliases.redirect !== undefined) {\n merged.redirect = aliases.redirect\n }\n\n return merged\n}\n\nfunction isRetryMethodAllowed(\n method: HttpMethod,\n retryConfig: ResolvedRetryOptions\n): boolean {\n if (retryConfig.retryUnsafeMethods) {\n return true\n }\n\n const normalizedMethod = method.toUpperCase()\n return retryConfig.retryMethods.some(\n retryMethod => retryMethod.toUpperCase() === normalizedMethod\n )\n}\n\nfunction getRetryAfterDelay(error: Error): number | undefined {\n if (!(error instanceof HttpError)) {\n return undefined\n }\n\n const retryAfter = error.response.headers.get('retry-after')\n if (!retryAfter) {\n return undefined\n }\n\n const retryAfterSeconds = Number(retryAfter)\n if (Number.isFinite(retryAfterSeconds)) {\n return Math.max(0, retryAfterSeconds * 1000)\n }\n\n const retryAfterDate = Date.parse(retryAfter)\n if (Number.isNaN(retryAfterDate)) {\n return undefined\n }\n\n return Math.max(0, retryAfterDate - Date.now())\n}\n\nfunction applyJitter(\n delay: number,\n jitter: ResolvedRetryOptions['jitter'],\n attempt: number\n): number {\n if (typeof jitter === 'function') {\n return Math.max(0, jitter(delay, attempt))\n }\n\n if (jitter === 'full') {\n return Math.floor(Math.random() * delay)\n }\n\n if (jitter === 'equal') {\n return Math.floor(delay / 2 + Math.random() * (delay / 2))\n }\n\n return delay\n}\n\nfunction isObjectLike(\n value: unknown\n): value is Record<string, unknown> | unknown[] | { toJSON(): unknown } {\n return (\n value !== null &&\n typeof value === 'object' &&\n (Array.isArray(value) ||\n ('toJSON' in value && typeof value.toJSON === 'function') ||\n Object.prototype.toString.call(value) === '[object Object]')\n )\n}\n\nfunction serializeQueryParams(params: RequestParamsType): string {\n const searchParams = new URLSearchParams()\n\n for (const [key, value] of Object.entries(params)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item !== undefined && item !== null) {\n searchParams.append(key, String(item))\n }\n }\n } else if (value !== undefined && value !== null) {\n searchParams.append(key, String(value))\n }\n }\n\n return searchParams.toString()\n}\n\nfunction serializeRequestBody(body: unknown): {\n body: BodyInit\n contentType?: string\n} {\n if (ArrayBuffer.isView(body)) {\n const bytes = new Uint8Array(body.buffer, body.byteOffset, body.byteLength)\n return { body: new Uint8Array(bytes).buffer }\n }\n\n if (\n typeof body === 'string' ||\n body instanceof FormData ||\n body instanceof URLSearchParams ||\n body instanceof ArrayBuffer ||\n body instanceof Blob ||\n body instanceof ReadableStream\n ) {\n return { body: body }\n }\n\n if (isObjectLike(body)) {\n return {\n body: JSON.stringify(body),\n contentType: 'application/json',\n }\n }\n\n if (body === null || body === undefined) {\n return { body: '' }\n }\n\n return { body: String(body) }\n}\n\nfunction createErrorMessage(context: string, error: unknown): string {\n return `${context}: ${error instanceof Error ? error.message : String(error)}`\n}\n\nfunction isReplayableBody(body: BodyInit | null | undefined): boolean {\n return !(body instanceof ReadableStream)\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (ms <= 0) {\n return Promise.resolve()\n }\n\n if (signal?.aborted) {\n return Promise.reject(createAbortError(signal.reason))\n }\n\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n signal?.removeEventListener('abort', handleAbort)\n resolve()\n }, ms)\n\n const handleAbort = () => {\n clearTimeout(timeoutId)\n signal?.removeEventListener('abort', handleAbort)\n reject(createAbortError(signal?.reason))\n }\n\n signal?.addEventListener('abort', handleAbort, { once: true })\n })\n}\n\nfunction createAbortError(reason: unknown): Error {\n if (reason instanceof Error) {\n return reason\n }\n\n const error = new Error('The operation was aborted')\n error.name = 'AbortError'\n return error\n}\n\nfunction createCombinedSignal(\n requestSignal?: AbortSignal,\n timeoutSignal?: AbortSignal\n): { signal?: AbortSignal; cleanup: () => void } {\n if (!requestSignal && !timeoutSignal) {\n return {\n signal: undefined,\n cleanup: () => undefined,\n }\n }\n\n if (!requestSignal) {\n return {\n signal: timeoutSignal,\n cleanup: () => undefined,\n }\n }\n\n if (!timeoutSignal) {\n return {\n signal: requestSignal,\n cleanup: () => undefined,\n }\n }\n\n if (requestSignal?.aborted) {\n return {\n signal: requestSignal,\n cleanup: () => undefined,\n }\n }\n\n if (timeoutSignal.aborted) {\n return {\n signal: timeoutSignal,\n cleanup: () => undefined,\n }\n }\n\n const combinedController = new AbortController()\n\n const handleAbort = (event: Event) => {\n const sourceSignal = event.target\n\n if (sourceSignal instanceof AbortSignal) {\n combinedController.abort(sourceSignal.reason)\n return\n }\n\n combinedController.abort()\n }\n\n requestSignal.addEventListener('abort', handleAbort, { once: true })\n timeoutSignal.addEventListener('abort', handleAbort, { once: true })\n\n return {\n signal: combinedController.signal,\n cleanup: () => {\n requestSignal.removeEventListener('abort', handleAbort)\n timeoutSignal.removeEventListener('abort', handleAbort)\n },\n }\n}\n\nfunction createStandardizedError(error: unknown, context: string): Error {\n if (error instanceof Error) {\n return error\n }\n\n return new Error(`${context}: ${String(error)}`)\n}\n\nasync function fetchWithNetworkError(\n fetchImplementation: CustomFetch,\n url: string,\n requestInit: RequestInit\n): Promise<Response> {\n try {\n return await fetchImplementation(url, requestInit)\n } catch (error) {\n const standardizedError = createStandardizedError(\n error,\n 'Network request failed'\n )\n\n if (\n isAbortError(standardizedError) ||\n standardizedError instanceof NetworkError\n ) {\n throw standardizedError\n }\n\n throw new NetworkError(standardizedError.message, standardizedError)\n }\n}\n\nfunction createHttpError(\n response: ResponseType<unknown>,\n cause?: Error\n): HttpError {\n return new HttpError(\n `HTTP ${response.status} ${response.statusText}`,\n response.status,\n response.statusText,\n response.data,\n response.raw,\n response.url,\n response.method,\n cause\n )\n}\n\nfunction constructUrl(baseUrl: string, requestUrl: string): string {\n if (isAbsoluteUrl(requestUrl)) {\n return requestUrl\n }\n\n return isAbsoluteUrl(baseUrl)\n ? constructAbsoluteUrl(baseUrl, requestUrl)\n : constructRelativeUrl(baseUrl, requestUrl)\n}\n\nfunction constructAbsoluteUrl(baseUrl: string, requestUrl: string): string {\n const baseUrlObj = new URL(baseUrl)\n const basePath = baseUrlObj.pathname.replace(/\\/$/, '')\n const { path, search, hash } = splitUrl(requestUrl)\n\n if (path.startsWith('/')) {\n baseUrlObj.pathname = basePath + path\n } else if (path) {\n baseUrlObj.pathname = basePath + '/' + path\n }\n\n if (search) {\n baseUrlObj.search = mergeSearch(baseUrlObj.search, search)\n }\n\n if (hash) {\n baseUrlObj.hash = hash\n }\n\n return baseUrlObj.toString()\n}\n\nfunction constructRelativeUrl(baseUrl: string, requestUrl: string): string {\n const {\n path: basePath,\n search: baseSearch,\n hash: baseHash,\n } = splitUrl(baseUrl)\n const {\n path: requestPath,\n search: requestSearch,\n hash: requestHash,\n } = splitUrl(requestUrl)\n\n const pathname = requestPath\n ? joinPathSegments(basePath, requestPath)\n : basePath || requestPath\n\n return `${pathname}${mergeSearch(baseSearch, requestSearch)}${\n requestHash || baseHash\n }`\n}\n\nfunction appendQueryString(url: string, queryString: string): string {\n const normalizedQuery = queryString.startsWith('?')\n ? queryString.slice(1)\n : queryString\n\n if (!normalizedQuery) {\n return url\n }\n\n const { path, search, hash } = splitUrl(url)\n const nextSearch = search\n ? `${search}&${normalizedQuery}`\n : `?${normalizedQuery}`\n\n return `${path}${nextSearch}${hash}`\n}\n\nfunction splitUrl(url: string): {\n path: string\n search: string\n hash: string\n} {\n const hashIndex = url.indexOf('#')\n const hash = hashIndex === -1 ? '' : url.slice(hashIndex)\n const withoutHash = hashIndex === -1 ? url : url.slice(0, hashIndex)\n const searchIndex = withoutHash.indexOf('?')\n\n return {\n path: searchIndex === -1 ? withoutHash : withoutHash.slice(0, searchIndex),\n search: searchIndex === -1 ? '' : withoutHash.slice(searchIndex),\n hash,\n }\n}\n\nfunction mergeSearch(baseSearch: string, requestSearch: string): string {\n if (!baseSearch) {\n return requestSearch\n }\n\n if (!requestSearch) {\n return baseSearch\n }\n\n return `${baseSearch}&${requestSearch.slice(1)}`\n}\n\nfunction joinPathSegments(basePath: string, requestPath: string): string {\n if (!basePath) {\n return requestPath.startsWith('/') ? requestPath : `/${requestPath}`\n }\n\n if (!requestPath) {\n return basePath\n }\n\n return requestPath.startsWith('/')\n ? `${basePath}${requestPath}`\n : `${basePath}/${requestPath}`\n}\n\nfunction createInternalRequest(\n url: string,\n requestInit: ExtendedRequestInit\n): Request {\n return new Request(toInternalRequestUrl(url), requestInit)\n}\n\nfunction isSuccessfulStatus(status: number): boolean {\n return status >= 200 && status < 300\n}\n\nfunction isResponseTypeLike(value: unknown): value is ResponseType<unknown> {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'data' in value &&\n 'status' in value &&\n typeof value.status === 'number' &&\n 'statusText' in value &&\n typeof value.statusText === 'string' &&\n 'headers' in value &&\n typeof value.headers === 'object' &&\n value.headers !== null &&\n 'method' in value &&\n typeof value.method === 'string' &&\n 'url' in value &&\n typeof value.url === 'string' &&\n 'raw' in value &&\n value.raw instanceof Response\n )\n}\n\nfunction assertRequestUrlSupported(\n url: string,\n usesNativeFetch: boolean\n): void {\n if (!usesNativeFetch || isAbsoluteUrl(url) || supportsRelativeRequestUrls()) {\n return\n }\n\n throw new InvalidBaseUrlError(\n `Relative request URL \"${url}\" requires an absolute baseUrl in non-browser environments. Pass an absolute baseUrl or use a custom fetch implementation.`,\n url\n )\n}\n\nfunction isAbsoluteUrl(url: string): boolean {\n return /^[a-zA-Z][a-zA-Z\\d+\\-.]*:\\/\\//.test(url)\n}\n\nfunction supportsRelativeRequestUrls(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof window.location !== 'undefined' &&\n window.location.origin !== 'null'\n )\n}\n\nfunction toInternalRequestUrl(url: string): string {\n if (isAbsoluteUrl(url)) {\n return url\n }\n\n if (!url) {\n return 'https://1000fetches.local/'\n }\n\n return `https://1000fetches.local${url.startsWith('/') ? url : `/${url}`}`\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n\nfunction isInvalidUrlError(error: Error): boolean {\n return (\n error.message.includes('Invalid URL') ||\n error.message.includes('Failed to parse URL')\n )\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { InvalidSchemaError, SchemaValidationError } from './errors'\nimport { Schema } from './types'\n\n/**\n * Type guard to check if an object conforms to the Standard Schema V1 specification\n */\nfunction isStandardSchema(obj: unknown): obj is StandardSchemaV1 {\n return (\n obj !== null &&\n (typeof obj === 'object' || typeof obj === 'function') &&\n '~standard' in obj &&\n typeof obj['~standard'] === 'object' &&\n obj['~standard'] !== null &&\n 'validate' in obj['~standard'] &&\n typeof obj['~standard'].validate === 'function' &&\n 'version' in obj['~standard'] &&\n obj['~standard'].version === 1 &&\n 'vendor' in obj['~standard'] &&\n typeof obj['~standard'].vendor === 'string'\n )\n}\n\n/**\n * Interface for schema validators that can validate data against schemas.\n *\n * This interface allows you to create custom schema validators that work\n * with different validation libraries (Zod, Valibot, Arktype, etc.).\n */\nexport interface SchemaValidator {\n /**\n * Validate data against a schema.\n *\n * @template T - The expected type after validation\n * @param schema - The schema to validate against\n * @param data - The data to validate\n * @returns The validated data with the correct type, synchronously or asynchronously\n * @throws {SchemaValidationError} If the data doesn't match the schema\n */\n validate<T>(schema: Schema<T>, data: unknown): T | Promise<T>\n}\n\nfunction isPromiseLike<T>(value: unknown): value is PromiseLike<T> {\n return (\n value !== null &&\n (typeof value === 'object' || typeof value === 'function') &&\n 'then' in value &&\n typeof value.then === 'function'\n )\n}\n\nfunction readValidationResult<T>(\n schema: Schema<T>,\n data: unknown,\n result: StandardSchemaV1.Result<T>\n): T {\n if (result.issues) {\n throw new SchemaValidationError(\n JSON.stringify(result.issues),\n schema,\n data,\n undefined,\n result.issues\n )\n }\n\n return result.value\n}\n\n/**\n * Create a default schema validator that supports Standard Schema.\n *\n * This validator works with schemas that implement the Standard Schema\n * interface, including both synchronous and asynchronous validators.\n *\n * @returns A schema validator instance\n *\n * @example\n * ```ts\n * const validator = createSchemaValidator()\n *\n * const parsed = validator.validate(schema, data)\n * ```\n */\nexport function createSchemaValidator(): SchemaValidator {\n return {\n validate<T>(schema: Schema<T>, data: unknown): T | Promise<T> {\n if (!isStandardSchema(schema)) {\n throw new InvalidSchemaError(\n 'Schema must implement the Standard Schema interface',\n schema\n )\n }\n\n const result = schema['~standard'].validate(data) as\n | StandardSchemaV1.Result<T>\n | PromiseLike<StandardSchemaV1.Result<T>>\n\n if (isPromiseLike<StandardSchemaV1.Result<T>>(result)) {\n return Promise.resolve(result).then(asyncResult =>\n readValidationResult(schema, data, asyncResult)\n )\n }\n\n return readValidationResult(schema, data, result)\n },\n }\n}\n","import type { HttpClientConfig, HttpRequestOptions } from './core'\nimport { createHttpRequest } from './core'\nimport {\n InvalidBaseUrlError,\n InvalidSchemaError,\n SchemaValidationError,\n} from './errors'\nimport { createSchemaValidator } from './schema'\nimport type { SchemaValidator } from './schema'\nimport type {\n EnforcedPathParamsOptions,\n ExtractableResponse,\n InferSchemaOutput,\n RequestParamsType,\n ResponseType,\n Schema,\n SchemaableResponse,\n} from './types'\nimport type {\n AssertSupportedPath,\n HasRequiredParams,\n RequirePathParams,\n} from './utils'\n\ntype PathOptionsArgs<Path extends string, TOptions> = [\n AssertSupportedPath<Path>,\n] extends [never]\n ? [options: never]\n : HasRequiredParams<AssertSupportedPath<Path>> extends true\n ? [options: TOptions]\n : [options?: TOptions]\n\ntype EnforcedHttpRequestOptions<\n TBody,\n TParams extends RequestParamsType,\n Path extends string,\n> = RequirePathParams<\n AssertSupportedPath<Path>,\n string extends Path\n ? HttpRequestOptions<TBody, TParams>\n : Omit<HttpRequestOptions<TBody, TParams>, 'pathParams'>\n>\n\nfunction validateAndNormalizeBaseUrl(baseUrl?: string): string {\n if (!baseUrl) {\n return ''\n }\n\n if (baseUrl.startsWith('/')) {\n return baseUrl.replace(/\\/$/, '')\n }\n\n try {\n new URL(baseUrl)\n } catch {\n throw new InvalidBaseUrlError(\n `Invalid baseUrl: \"${baseUrl}\". Must be a valid absolute URL or relative path starting with \"/\".`,\n baseUrl\n )\n }\n\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n}\n\nfunction createExtractableResponse<T>(\n promise: Promise<ResponseType<T>>\n): ExtractableResponse<T> {\n const extractable = promise as ExtractableResponse<T>\n extractable.data = async () => (await promise).data\n extractable.void = async () => {\n await promise\n }\n return extractable\n}\n\n/**\n * Creates a chainable response that allows adding schema validation and extracting data\n */\nfunction createSchemaableResponse<\n Path extends string,\n TResponse,\n TBody,\n TParams extends RequestParamsType,\n>(\n url: Path,\n options: HttpRequestOptions<TBody, TParams>,\n requestHandler: ReturnType<typeof createHttpRequest>,\n schemaValidator: SchemaValidator\n): SchemaableResponse<TResponse> {\n const basePromise = requestHandler<Path, TResponse, TBody, TParams>(\n url,\n options\n )\n\n return Object.assign(basePromise, {\n schema<S extends Schema>(\n schema: S\n ): ExtractableResponse<InferSchemaOutput<S>> {\n const validatedPromise = basePromise.then(async response => {\n try {\n const validatedData = (await schemaValidator.validate(\n schema,\n response.data\n )) as InferSchemaOutput<S>\n return {\n ...response,\n data: validatedData,\n }\n } catch (error) {\n if (\n error instanceof InvalidSchemaError ||\n error instanceof SchemaValidationError\n ) {\n throw error\n }\n\n throw new SchemaValidationError(\n error instanceof Error ? error.message : 'Schema validation failed',\n schema,\n response.data,\n error instanceof Error ? error : undefined\n )\n }\n })\n\n return createExtractableResponse(validatedPromise)\n },\n async data() {\n return (await basePromise).data\n },\n async void() {\n await basePromise\n },\n })\n}\n\n/**\n * Creates a complete HTTP client with method builders\n */\nexport function createHttpClient(config: HttpClientConfig = {}) {\n const validatedConfig = {\n ...config,\n baseUrl: validateAndNormalizeBaseUrl(config.baseUrl),\n }\n\n const requestHandler = createHttpRequest(validatedConfig)\n const schemaValidator = config.schemaValidator ?? createSchemaValidator()\n\n function get<\n Path extends string = string,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n ...args: PathOptionsArgs<\n Path,\n EnforcedPathParamsOptions<never, TParams, Path>\n >\n ) {\n return createSchemaableResponse<Path, unknown, never, TParams>(\n url,\n {\n ...(args[0] ?? {}),\n method: 'GET',\n },\n requestHandler,\n schemaValidator\n )\n }\n\n return {\n get,\n\n post: <\n Path extends string = string,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: PathOptionsArgs<\n Path,\n EnforcedPathParamsOptions<TBody, TParams, Path>\n >\n ) =>\n createSchemaableResponse<Path, unknown, TBody, TParams>(\n url,\n {\n ...(args[0] ?? {}),\n method: 'POST',\n body,\n },\n requestHandler,\n schemaValidator\n ),\n\n put: <\n Path extends string = string,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: PathOptionsArgs<\n Path,\n EnforcedPathParamsOptions<TBody, TParams, Path>\n >\n ) =>\n createSchemaableResponse<Path, unknown, TBody, TParams>(\n url,\n {\n ...(args[0] ?? {}),\n method: 'PUT',\n body,\n },\n requestHandler,\n schemaValidator\n ),\n\n patch: <\n Path extends string = string,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: PathOptionsArgs<\n Path,\n EnforcedPathParamsOptions<TBody, TParams, Path>\n >\n ) =>\n createSchemaableResponse<Path, unknown, TBody, TParams>(\n url,\n {\n ...(args[0] ?? {}),\n method: 'PATCH',\n body,\n },\n requestHandler,\n schemaValidator\n ),\n\n delete: <\n Path extends string = string,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n ...args: PathOptionsArgs<\n Path,\n EnforcedPathParamsOptions<never, TParams, Path>\n >\n ) =>\n createSchemaableResponse<Path, unknown, never, TParams>(\n url,\n {\n ...(args[0] ?? {}),\n method: 'DELETE',\n },\n requestHandler,\n schemaValidator\n ),\n\n /**\n * Generic request method for custom HTTP methods and full control\n */\n request: <\n Path extends string = string,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n ...args: PathOptionsArgs<\n Path,\n EnforcedHttpRequestOptions<TBody, TParams, Path>\n >\n ) =>\n createSchemaableResponse<Path, unknown, TBody, TParams>(\n url,\n args[0] ?? {},\n requestHandler,\n schemaValidator\n ),\n }\n}\n"],"mappings":"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"}
|
package/dist/client-DOv6m2TJ.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var e=class extends Error{name="HttpError";status;statusText;data;response;url;method;cause;constructor(e,t,r,n,a,s,o,i){const c=`HTTP ${t>=500?"Server Error":t>=400?"Client Error":t>=300?"Redirect":"Success"} (${t}): ${e}\nRequest: ${o} ${s}\nData: ${function(e){if(null==e||""===e)return"No response data";let t;try{t="string"==typeof e?e:JSON.stringify(e)}catch{t=String(e)}return t.length>500?t.substring(0,500)+"...":t}(n)}`;super(c,{cause:i}),this.status=t,this.statusText=r,this.data=n,this.response=a,this.url=s,this.method=o,this.cause=i}},t=class extends Error{name="NetworkError";cause;constructor(e,t){super(e,{cause:t}),this.cause=t}},r=class extends Error{name="SchemaValidationError";schema;data;issues;cause;constructor(e,t,r,n,a){super(e,{cause:n}),this.schema=t,this.data=r,this.issues=a,this.cause=n}},n=class extends Error{name="TimeoutError";cause;constructor(e,t){super(e,{cause:t}),this.cause=t}},a=class extends Error{name="PathParameterError";url;requiredParams;providedParams;cause;constructor(e,t,r,n,a){super(`${e}\nURL Template: ${t}\nExpected: [${r.map(e=>`"${e}"`).join(", ")}], Actual: [${n.map(e=>`"${e}"`).join(", ")}]`,{cause:a}),this.url=t,this.requiredParams=r,this.providedParams=n,this.cause=a}},s=class extends Error{name="MiddlewareError";type;url;method;cause;constructor(e,t,r,n,a){const s=r?`Request: ${n||"UNKNOWN"} ${r}`:"";super(s?`${e}\n${s}`:e,{cause:a}),this.type=t,this.url=r,this.method=n,this.cause=a}},o=class extends Error{name="SerializationError";cause;constructor(e,t){super(e,{cause:t}),this.cause=t}},i=class extends Error{name="InvalidSchemaError";schema;cause;constructor(e,t,r){super(e,{cause:r}),this.schema=t,this.cause=r}},c=class extends Error{name="AsyncSchemaValidationError";schema;cause;constructor(e,t,r){super(e,{cause:r}),this.schema=t,this.cause=r}},u=class extends Error{name="InvalidBaseUrlError";baseUrl;cause;constructor(e,t,r){super(`${e}\nBase URL: ${t}`,{cause:r}),this.baseUrl=t,this.cause=r}};function d(e,t={}){return function(e,t){const r=e.match(/(^|\/):([^/\s?#]+)\?(?=\/)/);if(!r)return;const[,,n]=r;throw new a(`Optional path parameter "${n}" is not supported here. Optional path parameters are only supported at the end of the path.`,e,[n],t)}(e,Object.keys(t)),e.replace(/(^|\/):([^/\s?#]+?)(\?)?(?=\/|$|[?#])/g,(r,n,s,o)=>{const i="?"===o;if(!/^[a-zA-Z0-9_]+$/.test(s))throw new a(`Invalid path parameter name: "${s}"`,e,[s],Object.keys(t));const c=t[s];if(void 0===c){if(i)return"";throw new a(`Missing required path parameter: "${s}"`,e,[s],Object.keys(t))}return`${n}${encodeURIComponent(String(c))}`})}function l(e,t,r,n){let a=0,s=!1,o=!1;const i=()=>{if(!s){s=!0;try{e.releaseLock()}catch{}}},c=()=>{o=!0,i()};return n?.addEventListener("abort",c),new ReadableStream({async start(s){try{for(;!o;){const{done:n,value:o}=await e.read();if(n)break;a+=o.length,t(o,r,a),s.enqueue(o)}o||s.close()}catch(u){throw o||s.error(u),u}finally{n?.removeEventListener("abort",c),i()}},cancel(){o=!0,n?.removeEventListener("abort",c),i()}})}async function h(e,t){if(!t||!e.body)return e;if(!e.body.getReader)return e;const r=l(e.body.getReader(),(e,r,n)=>{t({chunk:e,totalBytes:r,transferredBytes:n})},e.headers.get("content-length")?parseInt(e.headers.get("content-length")||"0",10):void 0,e.signal);return new Request(e.url,{method:e.method,headers:e.headers,body:r,signal:e.signal,credentials:e.credentials,cache:e.cache,mode:e.mode,redirect:e.redirect,referrer:e.referrer,referrerPolicy:e.referrerPolicy,integrity:e.integrity,keepalive:e.keepalive,duplex:"half"})}async function f(e,t){if(!t||!e.body)return e;if(!e.body.getReader)return e;const r=l(e.body.getReader(),(e,r,n)=>{t({chunk:e,totalBytes:r,transferredBytes:n})},e.headers.get("content-length")?parseInt(e.headers.get("content-length")||"0",10):void 0);return new Response(r,{status:e.status,statusText:e.statusText,headers:e.headers})}var p={maxRetries:3,retryDelay:300,backoffFactor:2,retryStatusCodes:[408,429,500,502,503,504],retryNetworkErrors:!0,maxRetryDelay:3e4,retryMethods:["GET","HEAD","OPTIONS","PUT","DELETE"],retryUnsafeMethods:!1,jitter:"none",respectRetryAfter:!0};function m(e={}){const{baseUrl:t="",headers:r={},timeout:a=3e4,fetch:o,serializeBody:i,serializeParams:c,onRequestMiddleware:l,onResponseMiddleware:m}=e,$=void 0===o;return async function(M,N={}){const{method:D="GET",headers:k={},params:B,pathParams:C,body:I,timeout:H=a,signal:W,credentials:z,cache:F,mode:J,redirect:G,fetchOptions:V,onUploadStreaming:Z,onDownloadStreaming:K,responseType:_,retry:Q}=N;let X=void 0===C?d(M):d(M,C);t&&(X=function(e,t){return L(t)?t:L(e)?function(e,t){const r=new URL(e),n=r.pathname.replace(/\/$/,""),{path:a,search:s,hash:o}=j(t);a.startsWith("/")?r.pathname=n+a:a&&(r.pathname=n+"/"+a);s&&(r.search=U(r.search,s));o&&(r.hash=o);return r.toString()}(e,t):function(e,t){const{path:r,search:n,hash:a}=j(e),{path:s,search:o,hash:i}=j(t);return`${s?function(e,t){return e?t?t.startsWith("/")?`${e}${t}`:`${e}/${t}`:e:t.startsWith("/")?t:`/${t}`}(r,s):r||s}${U(n,o)}${i||a}`}(e,t)}(t,X));const Y=function(e,t){const r={...e??{}};void 0!==t.cache&&(r.cache=t.cache);void 0!==t.credentials&&(r.credentials=t.credentials);void 0!==t.mode&&(r.mode=t.mode);void 0!==t.redirect&&(r.redirect=t.redirect);return r}(V,{cache:F,credentials:z,mode:J,redirect:G}),ee={url:X,method:D,params:B,headers:new Headers({...r,...k}),body:I,signal:W,fetchOptions:Y};let te=ee;if(l)try{te=await l({...ee,headers:new Headers(ee.headers),fetchOptions:{...ee.fetchOptions}})}catch(ie){throw new s(g("Request middleware failed",ie),"request",te.url,te.method,x(ie,"Request middleware"))}if(te.params){const e=c?c(te.params):function(e){const t=new URLSearchParams;for(const[r,n]of Object.entries(e))if(Array.isArray(n))for(const e of n)null!=e&&t.append(r,String(e));else null!=n&&t.append(r,String(n));return t.toString()}(te.params);e&&(te.url=function(e,t){const r=t.startsWith("?")?t.slice(1):t;if(!r)return e;const{path:n,search:a,hash:s}=j(e);return`${n}${a?`${a}&${r}`:`?${r}`}${s}`}(te.url,e))}!function(e,t){if(!t||L(e)||"undefined"!=typeof window&&void 0!==window.location&&"null"!==window.location.origin)return;throw new u(`Relative request URL "${e}" requires an absolute baseUrl in non-browser environments. Pass an absolute baseUrl or use a custom fetch implementation.`,e)}(te.url,$);const re={method:te.method,headers:te.headers,...te.fetchOptions};if(void 0!==te.body&&"GET"!==te.method&&"HEAD"!==te.method){let e,t;if(i){const t=i(te.body);e=null==t?"":t}else{const r=function(e){if(ArrayBuffer.isView(e)){const t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);return{body:new Uint8Array(t).buffer}}return"string"==typeof e||e instanceof FormData||e instanceof URLSearchParams||e instanceof ArrayBuffer||e instanceof Blob||e instanceof ReadableStream?{body:e}:function(e){return null!==e&&"object"==typeof e&&(Array.isArray(e)||"toJSON"in e&&"function"==typeof e.toJSON||"[object Object]"===Object.prototype.toString.call(e))}(e)?{body:JSON.stringify(e),contentType:"application/json"}:null==e?{body:""}:{body:String(e)}}(te.body);e=r.body,t=r.contentType}re.body=e,t&&te.headers.set("content-type",t),re.duplex="half"}const ne=function(e,t){const r="object"==typeof e?e:void 0,n=!0===e||void 0!==r||!0===t||"object"==typeof t;if(!1===t)return;if(!n)return;const a={...p,...r};return!0===t?a:"object"==typeof t?{...a,...t}:a}(e.retry,Q),ae=ne?.maxRetries??0,se=function(e){return!(e instanceof ReadableStream)}(re.body);let oe;for(let e=0;e<=ae;e+=1){const t=new AbortController;let r=!1;const a=setTimeout(()=>{r=!0,t.abort()},H),{signal:i,cleanup:c}=R(te.signal,t.signal);let u=!1;const d=()=>{u||(u=!0,clearTimeout(a),c())};try{const e={...re,headers:te.headers,signal:i,...te.fetchOptions};if(Z&&void 0!==e.body){const t=await h(O(te.url,e),Z);e.body=t.body??void 0,e.headers=t.headers}const t=await T(o??globalThis.fetch,te.url,e),r=K?await f(t,K):t,n=await y(r,{responseType:_,method:te.method,url:te.url,tolerateParseError:!P(r.status)});let a=n;if(m)try{const e=await m(n);if(!A(e))throw new s("Response middleware must return a valid ResponseType object","response",te.url,te.method);a=e}catch(ie){throw new s(g("Response middleware failed",ie),"response",te.url,te.method,x(ie,"Response middleware"))}if(!P(a.status))throw S(a,n.parseError);return a}catch(ie){if(oe=x(ie,"Request execution"),q(oe)&&r&&(oe=new n(`Request timeout after ${H}ms`,oe)),e>=ae||!(await w(oe,e,ne,{bodyReplayable:se,method:te.method,url:te.url})))throw oe;const t=b(e,ne,oe);await v(ne,{bodyReplayable:se,delay:t,error:oe,method:te.method,nextAttempt:e+1,retryCount:e,url:te.url}),d(),await E(t,te.signal)}finally{d()}}throw new Error("Retry loop terminated unexpectedly")}}async function y(e,t){const r=Object.fromEntries(e.headers.entries());let n,a;const s=e.clone();try{const r=t.responseType,a=e.headers.get("content-type")??"",o=a.includes("application/json")?"json":a.includes("text/")?"text":a.includes("application/octet-stream")||a.includes("application/pdf")||a.includes("image/")||a.includes("video/")||a.includes("audio/")?"arrayBuffer":a.includes("multipart/form-data")||a.includes("application/x-www-form-urlencoded")?"formData":void 0,i=r??o;if("json"===i)n=await e.json();else if("text"===i)n=await e.text();else if("blob"===i)n=await e.blob();else if("arrayBuffer"===i)n=await e.arrayBuffer();else if("formData"===i)n=await e.formData();else try{n=await e.json()}catch{n=await s.text()}}catch(i){if(a=new o(g("Failed to parse response body",i),i instanceof Error?i:void 0),!t.tolerateParseError)throw a;try{n=await s.text()}catch{n=""}}return{data:n,status:e.status,statusText:e.statusText,headers:r,method:t.method,url:t.url,raw:e,parseError:a}}async function w(r,n,a,s){if(!a)return!1;const o={...s,error:r,retryCount:n};return a.shouldRetry?await a.shouldRetry(r,n,o):!(!s.bodyReplayable||!function(e,t){if(t.retryUnsafeMethods)return!0;const r=e.toUpperCase();return t.retryMethods.some(e=>e.toUpperCase()===r)}(s.method,a))&&(r instanceof e?a.retryStatusCodes.includes(r.status):(r instanceof t||"TypeError"===r.name&&!function(e){return e.message.includes("Invalid URL")||e.message.includes("Failed to parse URL")}(r))&&a.retryNetworkErrors)}function b(t,r,n){if(!r)return 0;const a=r.respectRetryAfter?function(t){if(!(t instanceof e))return;const r=t.response.headers.get("retry-after");if(!r)return;const n=Number(r);if(Number.isFinite(n))return Math.max(0,1e3*n);const a=Date.parse(r);if(Number.isNaN(a))return;return Math.max(0,a-Date.now())}(n):void 0;if(void 0!==a)return Math.min(a,r.maxRetryDelay);const s=r.retryDelay*Math.pow(r.backoffFactor,t);return function(e,t,r){return"function"==typeof t?Math.max(0,t(e,r)):"full"===t?Math.floor(Math.random()*e):"equal"===t?Math.floor(e/2+Math.random()*(e/2)):e}(Math.min(s,r.maxRetryDelay),r.jitter,t)}async function v(e,t){await(e?.onRetry?.(t))}function g(e,t){return`${e}: ${t instanceof Error?t.message:String(t)}`}function E(e,t){return e<=0?Promise.resolve():t?.aborted?Promise.reject($(t.reason)):new Promise((r,n)=>{const a=setTimeout(()=>{t?.removeEventListener("abort",s),r()},e),s=()=>{clearTimeout(a),t?.removeEventListener("abort",s),n($(t?.reason))};t?.addEventListener("abort",s,{once:!0})})}function $(e){if(e instanceof Error)return e;const t=/* @__PURE__ */new Error("The operation was aborted");return t.name="AbortError",t}function R(e,t){if(!e&&!t)return{signal:void 0,cleanup:()=>{}};if(!e)return{signal:t,cleanup:()=>{}};if(!t)return{signal:e,cleanup:()=>{}};if(e?.aborted)return{signal:e,cleanup:()=>{}};if(t.aborted)return{signal:t,cleanup:()=>{}};const r=new AbortController,n=e=>{const t=e.target;t instanceof AbortSignal?r.abort(t.reason):r.abort()};return e.addEventListener("abort",n,{once:!0}),t.addEventListener("abort",n,{once:!0}),{signal:r.signal,cleanup:()=>{e.removeEventListener("abort",n),t.removeEventListener("abort",n)}}}function x(e,t){return e instanceof Error?e:/* @__PURE__ */new Error(`${t}: ${String(e)}`)}async function T(e,r,n){try{return await e(r,n)}catch(a){const e=x(a,"Network request failed");if(q(e)||e instanceof t)throw e;throw new t(e.message,e)}}function S(t,r){return new e(`HTTP ${t.status} ${t.statusText}`,t.status,t.statusText,t.data,t.raw,t.url,t.method,r)}function j(e){const t=e.indexOf("#"),r=-1===t?"":e.slice(t),n=-1===t?e:e.slice(0,t),a=n.indexOf("?");return{path:-1===a?n:n.slice(0,a),search:-1===a?"":n.slice(a),hash:r}}function U(e,t){return e?t?`${e}&${t.slice(1)}`:e:t}function O(e,t){return new Request(function(e){return L(e)?e:e?`https://1000fetches.local${e.startsWith("/")?e:`/${e}`}`:"https://1000fetches.local/"}(e),t)}function P(e){return e>=200&&e<300}function A(e){return null!==e&&"object"==typeof e&&"data"in e&&"status"in e&&"number"==typeof e.status&&"statusText"in e&&"string"==typeof e.statusText&&"headers"in e&&"object"==typeof e.headers&&null!==e.headers&&"method"in e&&"string"==typeof e.method&&"url"in e&&"string"==typeof e.url&&"raw"in e&&e.raw instanceof Response}function L(e){return/^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(e)}function q(e){return e instanceof Error&&"AbortError"===e.name}function M(e,t,n){if(n.issues)throw new r(JSON.stringify(n.issues),e,t,void 0,n.issues);return n.value}function N(){return{validate(e,t){if(null===(r=e)||"object"!=typeof r&&"function"!=typeof r||!("~standard"in r)||"object"!=typeof r["~standard"]||null===r["~standard"]||!("validate"in r["~standard"])||"function"!=typeof r["~standard"].validate||!("version"in r["~standard"])||1!==r["~standard"].version||!("vendor"in r["~standard"])||"string"!=typeof r["~standard"].vendor)throw new i("Schema must implement the Standard Schema interface",e);var r;const n=e["~standard"].validate(t);return null===(a=n)||"object"!=typeof a&&"function"!=typeof a||!("then"in a)||"function"!=typeof a.then?M(e,t,n):Promise.resolve(n).then(r=>M(e,t,r));var a}}}function D(e){if(!e)return"";if(e.startsWith("/"))return e.replace(/\/$/,"");try{new URL(e)}catch{throw new u(`Invalid baseUrl: "${e}". Must be a valid absolute URL or relative path starting with "/".`,e)}return e.endsWith("/")?e.slice(0,-1):e}function k(e,t,n,a){const s=n(e,t);return Object.assign(s,{schema:e=>function(e){const t=e;return t.data=async()=>(await e).data,t.void=async()=>{await e},t}(s.then(async t=>{try{const r=await a.validate(e,t.data);return{...t,data:r}}catch(n){if(n instanceof i||n instanceof r)throw n;throw new r(n instanceof Error?n.message:"Schema validation failed",e,t.data,n instanceof Error?n:void 0)}})),data:async()=>(await s).data,async void(){await s}})}function B(e={}){const t=m({...e,baseUrl:D(e.baseUrl)}),r=e.schemaValidator??N();return{get:function(e,...n){return k(e,{...n[0]??{},method:"GET"},t,r)},post:(e,n,...a)=>k(e,{...a[0]??{},method:"POST",body:n},t,r),put:(e,n,...a)=>k(e,{...a[0]??{},method:"PUT",body:n},t,r),patch:(e,n,...a)=>k(e,{...a[0]??{},method:"PATCH",body:n},t,r),delete:(e,...n)=>k(e,{...n[0]??{},method:"DELETE"},t,r),request:(e,...n)=>k(e,n[0]??{},t,r)}}export{u as a,t as c,o as d,n as f,e as i,a as l,N as n,i as o,c as r,s,B as t,r as u};
|
|
2
|
-
//# sourceMappingURL=client-DOv6m2TJ.mjs.map
|