@afoures/http-client 0.1.1 → 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.
@@ -56,7 +56,9 @@ type ServerErrorResponse<Error> = {
56
56
 
57
57
  Define a `data` parser for successful responses:
58
58
 
59
- ### JSON (Default)
59
+ ### JSON
60
+
61
+ Use `parse: 'json'` to parse the response body as JSON:
60
62
 
61
63
  ```typescript
62
64
  const endpoint = new Endpoint({
@@ -67,6 +69,7 @@ const endpoint = new Endpoint({
67
69
  id: z.string(),
68
70
  name: z.string(),
69
71
  }),
72
+ parse: 'json',
70
73
  },
71
74
  })
72
75
 
@@ -84,7 +87,7 @@ const endpoint = new Endpoint({
84
87
  pathname: '/health',
85
88
  data: {
86
89
  schema: z.string(),
87
- deserialization: 'text',
90
+ parse: 'text',
88
91
  },
89
92
  })
90
93
  ```
@@ -97,7 +100,7 @@ const endpoint = new Endpoint({
97
100
  pathname: '/data',
98
101
  data: {
99
102
  schema: z.object({ value: z.number() }),
100
- deserialization: async (body) => {
103
+ parse: async (body) => {
101
104
  const text = await new Response(body).text()
102
105
  return JSON.parse(text)
103
106
  },
@@ -129,13 +132,13 @@ Define an `error` parser for error responses:
129
132
  const endpoint = new Endpoint({
130
133
  method: 'POST',
131
134
  pathname: '/users',
132
- body: { schema: z.object({ name: z.string() }) },
135
+ body: { schema: z.object({ name: z.string() }), serialize: 'json' },
133
136
  error: {
134
137
  schema: z.object({
135
138
  message: z.string(),
136
139
  code: z.string(),
137
140
  }),
138
- deserialization: 'json',
141
+ parse: 'json',
139
142
  },
140
143
  })
141
144
 
@@ -154,7 +157,7 @@ const endpoint = new Endpoint({
154
157
  pathname: '/users/(:id)',
155
158
  error: {
156
159
  schema: z.string(),
157
- deserialization: 'text',
160
+ parse: 'text',
158
161
  },
159
162
  })
160
163
 
@@ -193,6 +196,7 @@ const endpoint = new Endpoint({
193
196
  name: z.string().transform(s => s.toUpperCase()),
194
197
  createdAt: z.string().transform(s => new Date(s)),
195
198
  }),
199
+ parse: 'json',
196
200
  },
197
201
  })
198
202
 
@@ -203,15 +207,15 @@ if (result.ok) {
203
207
  }
204
208
  ```
205
209
 
206
- ## Deserialization Errors
210
+ ## Parse Errors
207
211
 
208
- If response parsing fails validation, a `DeserializationError` is returned:
212
+ If response parsing fails validation, a `ParseError` is returned:
209
213
 
210
214
  ```typescript
211
215
  const result = await endpoint.parse_response(response)
212
216
 
213
- if (result instanceof DeserializationError) {
214
- console.log(result.message) // "Response deserialization failed"
217
+ if (result instanceof ParseError) {
218
+ console.log(result.message) // "Response parsing failed"
215
219
  console.log(result.cause) // Schema validation issues
216
220
  }
217
221
  ```
@@ -177,7 +177,7 @@ const result = await api.users.get({
177
177
 
178
178
  ```typescript
179
179
  const api = http_client({
180
- origin: 'https://api.example.com',
180
+ base_url: 'https://api.example.com',
181
181
  endpoints: {
182
182
  users: new Endpoint({
183
183
  method: 'GET',
@@ -15,6 +15,7 @@ const endpoint = new Endpoint({
15
15
  name: z.string().min(1),
16
16
  email: z.string().email(),
17
17
  }),
18
+ serialize: 'json',
18
19
  },
19
20
  data: {
20
21
  schema: z.object({
@@ -22,6 +23,7 @@ const endpoint = new Endpoint({
22
23
  name: z.string(),
23
24
  createdAt: z.string().datetime(),
24
25
  }),
26
+ parse: 'json',
25
27
  },
26
28
  })
27
29
  ```
@@ -43,6 +45,7 @@ const endpoint = new Endpoint({
43
45
  schema: z.object({
44
46
  createdAt: z.string().transform(s => new Date(s)), // parse ISO to Date
45
47
  }),
48
+ parse: 'json',
46
49
  },
47
50
  })
48
51
 
@@ -66,6 +69,7 @@ const endpoint = new Endpoint({
66
69
  email: 'string',
67
70
  age: 'number?',
68
71
  }),
72
+ serialize: 'json',
69
73
  },
70
74
  data: {
71
75
  schema: type({
@@ -73,6 +77,7 @@ const endpoint = new Endpoint({
73
77
  name: 'string',
74
78
  'email?': 'string',
75
79
  }),
80
+ parse: 'json',
76
81
  },
77
82
  })
78
83
  ```
@@ -90,6 +95,7 @@ const endpoint = new Endpoint({
90
95
  id: 'string',
91
96
  'createdAt': 'string.parse(v => new Date(v))',
92
97
  }),
98
+ parse: 'json',
93
99
  },
94
100
  })
95
101
  ```
@@ -107,12 +113,14 @@ const endpoint = new Endpoint({
107
113
  name: v.pipe(v.string(), v.minLength(1)),
108
114
  email: v.pipe(v.string(), v.email()),
109
115
  }),
116
+ serialize: 'json',
110
117
  },
111
118
  data: {
112
119
  schema: v.object({
113
120
  id: v.string(),
114
121
  name: v.string(),
115
122
  }),
123
+ parse: 'json',
116
124
  },
117
125
  })
118
126
  ```
@@ -130,6 +138,7 @@ const endpoint = new Endpoint({
130
138
  id: v.string(),
131
139
  createdAt: v.pipe(v.string(), v.transform(s => new Date(s))),
132
140
  }),
141
+ parse: 'json',
133
142
  },
134
143
  })
135
144
  ```
@@ -180,24 +189,24 @@ const UserSchema = z.object({
180
189
  const CreateUserSchema = UserSchema.omit({ id: true })
181
190
 
182
191
  const api = http_client({
183
- origin: 'https://api.example.com',
192
+ base_url: 'https://api.example.com',
184
193
  endpoints: {
185
194
  users: {
186
195
  list: new Endpoint({
187
196
  method: 'GET',
188
197
  pathname: '/users',
189
- data: { schema: z.array(UserSchema) },
198
+ data: { schema: z.array(UserSchema), parse: 'json' },
190
199
  }),
191
200
  get: new Endpoint({
192
201
  method: 'GET',
193
202
  pathname: '/users/(:id)',
194
- data: { schema: UserSchema },
203
+ data: { schema: UserSchema, parse: 'json' },
195
204
  }),
196
205
  create: new Endpoint({
197
206
  method: 'POST',
198
207
  pathname: '/users',
199
- body: { schema: CreateUserSchema },
200
- data: { schema: UserSchema },
208
+ body: { schema: CreateUserSchema, serialize: 'json' },
209
+ data: { schema: UserSchema, parse: 'json' },
201
210
  }),
202
211
  },
203
212
  },
@@ -17,7 +17,7 @@ const endpoint = new Endpoint({
17
17
  })
18
18
 
19
19
  const url = await endpoint.generate_url({
20
- origin: 'https://api.example.com',
20
+ base_url: 'https://api.example.com',
21
21
  params: { id: '123' },
22
22
  })
23
23
  // https://api.example.com/users/123
@@ -41,7 +41,7 @@ const endpoint = new Endpoint({
41
41
 
42
42
  ### Custom Serialization
43
43
 
44
- Provide a `serialization` function to transform validated params:
44
+ Provide a `serialize` function to transform validated params:
45
45
 
46
46
  ```typescript
47
47
  const endpoint = new Endpoint({
@@ -49,12 +49,12 @@ const endpoint = new Endpoint({
49
49
  pathname: '/users/(:id)',
50
50
  params: {
51
51
  schema: z.object({ id: z.number() }),
52
- serialization: (data) => ({ id: `user-${data.id}` }),
52
+ serialize: (data) => ({ id: `user-${data.id}` }),
53
53
  },
54
54
  })
55
55
 
56
56
  const url = await endpoint.generate_url({
57
- origin: 'https://api.example.com',
57
+ base_url: 'https://api.example.com',
58
58
  params: { id: 123 },
59
59
  })
60
60
  // https://api.example.com/users/user-123
@@ -79,7 +79,7 @@ const endpoint = new Endpoint({
79
79
  })
80
80
 
81
81
  const url = await endpoint.generate_url({
82
- origin: 'https://api.example.com',
82
+ base_url: 'https://api.example.com',
83
83
  query: { page: 1, search: 'john' },
84
84
  })
85
85
  // https://api.example.com/users?page=1&search=john
@@ -95,7 +95,7 @@ const endpoint = new Endpoint({
95
95
  schema: z.object({
96
96
  tags: z.array(z.string()),
97
97
  }),
98
- serialization: (data) => {
98
+ serialize: (data) => {
99
99
  const params = new URLSearchParams()
100
100
  params.set('tags', data.tags.join(','))
101
101
  return params
@@ -104,7 +104,7 @@ const endpoint = new Endpoint({
104
104
  })
105
105
 
106
106
  const url = await endpoint.generate_url({
107
- origin: 'https://api.example.com',
107
+ base_url: 'https://api.example.com',
108
108
  query: { tags: ['admin', 'active'] },
109
109
  })
110
110
  // https://api.example.com/users?tags=admin,active
@@ -114,9 +114,9 @@ const url = await endpoint.generate_url({
114
114
 
115
115
  Request bodies are serialized for POST, PUT, PATCH, and DELETE methods.
116
116
 
117
- ### JSON (Default)
117
+ ### JSON
118
118
 
119
- For JSON-compatible schemas, JSON serialization is automatic:
119
+ Use `serialize: 'json'` to serialize the body as JSON:
120
120
 
121
121
  ```typescript
122
122
  const endpoint = new Endpoint({
@@ -127,6 +127,7 @@ const endpoint = new Endpoint({
127
127
  name: z.string(),
128
128
  email: z.string().email(),
129
129
  }),
130
+ serialize: 'json',
130
131
  },
131
132
  })
132
133
 
@@ -150,7 +151,7 @@ const endpoint = new Endpoint({
150
151
  file: z.instanceof(File),
151
152
  name: z.string(),
152
153
  }),
153
- serialization: (data) => {
154
+ serialize: (data) => {
154
155
  const formData = new FormData()
155
156
  formData.append('file', data.file)
156
157
  formData.append('name', data.name)
@@ -171,7 +172,7 @@ const endpoint = new Endpoint({
171
172
  username: z.string(),
172
173
  password: z.string(),
173
174
  }),
174
- serialization: (data) => {
175
+ serialize: (data) => {
175
176
  const params = new URLSearchParams()
176
177
  params.set('username', data.username)
177
178
  params.set('password', data.password)
@@ -189,7 +190,7 @@ const endpoint = new Endpoint({
189
190
  pathname: '/echo',
190
191
  body: {
191
192
  schema: z.string(),
192
- serialization: (text) => ({
193
+ serialize: (text) => ({
193
194
  body: text,
194
195
  content_type: 'text/plain',
195
196
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afoures/http-client",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "A typesafe and robust HTTP client",
5
5
  "homepage": "https://github.com/afoures/http-client#readme",
6
6
  "bugs": {
@@ -35,12 +35,12 @@
35
35
  "@standard-schema/spec": "^1.1.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@afoures/auto-release": "^0.4.1",
38
+ "@afoures/auto-release": "^0.5.0",
39
39
  "@arktype/attest": "^0.56.0",
40
- "@types/node": "^24.12.0",
41
- "msw": "^2.12.10",
40
+ "@types/node": "^24.12.2",
41
+ "msw": "^2.13.2",
42
42
  "oxfmt": "^0.36.0",
43
- "oxlint": "^1.51.0",
43
+ "oxlint": "^1.59.0",
44
44
  "tsdown": "^0.21.0",
45
45
  "typescript": "^5.9.3",
46
46
  "zod": "^4.3.6"