@ahoo-wang/fetcher-decorator 0.6.0 → 0.6.5
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 +55 -16
- package/README.zh-CN.md +48 -15
- package/dist/index.es.js +419 -346
- package/dist/index.umd.js +2 -2
- package/dist/parameterDecorator.d.ts +106 -2
- package/dist/parameterDecorator.d.ts.map +1 -1
- package/dist/requestExecutor.d.ts +60 -1
- package/dist/requestExecutor.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
[](https://github.com/Ahoo-Wang/fetcher/blob/main/LICENSE)
|
|
7
7
|
[](https://www.npmjs.com/package/@ahoo-wang/fetcher-decorator)
|
|
8
8
|
[](https://www.npmjs.com/package/@ahoo-wang/fetcher-decorator)
|
|
9
|
+
[](https://deepwiki.com/Ahoo-Wang/fetcher)
|
|
9
10
|
|
|
10
11
|
Decorator support for Fetcher HTTP client. Enables clean, declarative API service definitions using TypeScript
|
|
11
12
|
decorators.
|
|
@@ -62,10 +63,7 @@ class UserService {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
@get('/{id}')
|
|
65
|
-
getUser(
|
|
66
|
-
@path('id') id: number,
|
|
67
|
-
@query('include') include: string,
|
|
68
|
-
): Promise<Response> {
|
|
66
|
+
getUser(@path() id: number, @query() include: string): Promise<Response> {
|
|
69
67
|
throw new Error('Implementation will be generated automatically.');
|
|
70
68
|
}
|
|
71
69
|
}
|
|
@@ -147,7 +145,7 @@ Defines an OPTIONS endpoint.
|
|
|
147
145
|
```typescript
|
|
148
146
|
class UserService {
|
|
149
147
|
@get('/{id}', { timeout: 3000 })
|
|
150
|
-
getUser(@path(
|
|
148
|
+
getUser(@path() id: number): Promise<Response> {
|
|
151
149
|
throw new Error('Implementation will be generated automatically.');
|
|
152
150
|
}
|
|
153
151
|
|
|
@@ -162,31 +160,40 @@ class UserService {
|
|
|
162
160
|
|
|
163
161
|
#### `@path(name)`
|
|
164
162
|
|
|
165
|
-
Defines a path parameter.
|
|
163
|
+
Defines a path parameter. The name is optional - if not provided, it will be automatically extracted from the method
|
|
164
|
+
parameter name.
|
|
166
165
|
|
|
167
166
|
**Parameters:**
|
|
168
167
|
|
|
169
|
-
- `name`: Name of the parameter (used in the path template)
|
|
168
|
+
- `name`: Name of the parameter (used in the path template, optional - auto-extracted if not provided)
|
|
170
169
|
|
|
171
170
|
#### `@query(name)`
|
|
172
171
|
|
|
173
|
-
Defines a query parameter.
|
|
172
|
+
Defines a query parameter. The name is optional - if not provided, it will be automatically extracted from the method
|
|
173
|
+
parameter name.
|
|
174
174
|
|
|
175
175
|
**Parameters:**
|
|
176
176
|
|
|
177
|
-
- `name`: Name of the parameter (used in the query string)
|
|
177
|
+
- `name`: Name of the parameter (used in the query string, optional - auto-extracted if not provided)
|
|
178
178
|
|
|
179
179
|
#### `@body()`
|
|
180
180
|
|
|
181
|
-
Defines a request body.
|
|
181
|
+
Defines a request body. Body parameters don't have names since there's only one body per request.
|
|
182
182
|
|
|
183
183
|
#### `@header(name)`
|
|
184
184
|
|
|
185
|
-
Defines a header parameter.
|
|
185
|
+
Defines a header parameter. The name is optional - if not provided, it will be automatically extracted from the method
|
|
186
|
+
parameter name.
|
|
186
187
|
|
|
187
188
|
**Parameters:**
|
|
188
189
|
|
|
189
|
-
- `name`: Name of the header
|
|
190
|
+
- `name`: Name of the header (optional - auto-extracted if not provided)
|
|
191
|
+
|
|
192
|
+
#### `@request()`
|
|
193
|
+
|
|
194
|
+
Defines a request parameter that will be used as the base request object. This allows you to pass a complete
|
|
195
|
+
FetcherRequest
|
|
196
|
+
object to customize the request configuration.
|
|
190
197
|
|
|
191
198
|
**Example:**
|
|
192
199
|
|
|
@@ -195,14 +202,19 @@ class UserService {
|
|
|
195
202
|
@get('/search')
|
|
196
203
|
searchUsers(
|
|
197
204
|
@query('q') query: string,
|
|
198
|
-
@query(
|
|
205
|
+
@query() limit: number,
|
|
199
206
|
@header('Authorization') auth: string,
|
|
200
207
|
): Promise<Response> {
|
|
201
208
|
throw new Error('Implementation will be generated automatically.');
|
|
202
209
|
}
|
|
203
210
|
|
|
211
|
+
@post('/users')
|
|
212
|
+
createUsers(@request() request: FetcherRequest): Promise<Response> {
|
|
213
|
+
throw new Error('Implementation will be generated automatically.');
|
|
214
|
+
}
|
|
215
|
+
|
|
204
216
|
@put('/{id}')
|
|
205
|
-
updateUser(@path(
|
|
217
|
+
updateUser(@path() id: number, @body() user: User): Promise<Response> {
|
|
206
218
|
throw new Error('Implementation will be generated automatically.');
|
|
207
219
|
}
|
|
208
220
|
}
|
|
@@ -224,7 +236,7 @@ class BaseService {
|
|
|
224
236
|
@api('/users')
|
|
225
237
|
class UserService extends BaseService {
|
|
226
238
|
@get('/{id}')
|
|
227
|
-
getUser(@path(
|
|
239
|
+
getUser(@path() id: number): Promise<Response> {
|
|
228
240
|
throw new Error('Implementation will be generated automatically.');
|
|
229
241
|
}
|
|
230
242
|
}
|
|
@@ -239,8 +251,35 @@ class ComplexService {
|
|
|
239
251
|
batchOperation(
|
|
240
252
|
@body() items: Item[],
|
|
241
253
|
@header('X-Request-ID') requestId: string,
|
|
242
|
-
@query(
|
|
254
|
+
@query() dryRun: boolean = false,
|
|
255
|
+
): Promise<Response> {
|
|
256
|
+
throw new Error('Implementation will be generated automatically.');
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Request Merging
|
|
262
|
+
|
|
263
|
+
When using the `@request()` decorator, the provided `FetcherRequest` object is merged with endpoint-specific
|
|
264
|
+
configuration using a sophisticated merging strategy:
|
|
265
|
+
|
|
266
|
+
- **Nested objects** (path, query, headers) are recursively merged, with parameter values taking precedence
|
|
267
|
+
- **Primitive values** (method, body, timeout, signal) from the parameter request override endpoint values
|
|
268
|
+
- **Empty objects** are handled gracefully, falling back to endpoint configuration
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
|
|
272
|
+
@api('/users')
|
|
273
|
+
class UserService {
|
|
274
|
+
@post('/')
|
|
275
|
+
createUsers(
|
|
276
|
+
@body() user: User,
|
|
277
|
+
@request() request: FetcherRequest,
|
|
243
278
|
): Promise<Response> {
|
|
279
|
+
// The final request will merge:
|
|
280
|
+
// - Endpoint method (POST)
|
|
281
|
+
// - Body parameter (user object)
|
|
282
|
+
// - Any configuration from the request parameter
|
|
244
283
|
throw new Error('Implementation will be generated automatically.');
|
|
245
284
|
}
|
|
246
285
|
}
|
package/README.zh-CN.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
[](https://github.com/Ahoo-Wang/fetcher/blob/main/LICENSE)
|
|
7
7
|
[](https://www.npmjs.com/package/@ahoo-wang/fetcher-decorator)
|
|
8
8
|
[](https://www.npmjs.com/package/@ahoo-wang/fetcher-decorator)
|
|
9
|
+
[](https://deepwiki.com/Ahoo-Wang/fetcher)
|
|
9
10
|
|
|
10
11
|
Fetcher HTTP 客户端的装饰器支持。使用 TypeScript 装饰器实现简洁、声明式的 API 服务定义。
|
|
11
12
|
|
|
@@ -61,10 +62,7 @@ class UserService {
|
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
@get('/{id}')
|
|
64
|
-
getUser(
|
|
65
|
-
@path('id') id: number,
|
|
66
|
-
@query('include') include: string,
|
|
67
|
-
): Promise<Response> {
|
|
65
|
+
getUser(@path() id: number, @query() include: string): Promise<Response> {
|
|
68
66
|
throw new Error('实现将自动生成');
|
|
69
67
|
}
|
|
70
68
|
}
|
|
@@ -146,7 +144,7 @@ class ApiService {
|
|
|
146
144
|
```typescript
|
|
147
145
|
class UserService {
|
|
148
146
|
@get('/{id}', { timeout: 3000 })
|
|
149
|
-
getUser(@path(
|
|
147
|
+
getUser(@path() id: number): Promise<Response> {
|
|
150
148
|
throw new Error('实现将自动生成');
|
|
151
149
|
}
|
|
152
150
|
|
|
@@ -161,31 +159,35 @@ class UserService {
|
|
|
161
159
|
|
|
162
160
|
#### `@path(name)`
|
|
163
161
|
|
|
164
|
-
|
|
162
|
+
定义路径参数。名称是可选的 - 如果未提供,将使用反射从方法参数名自动提取。
|
|
165
163
|
|
|
166
164
|
**参数:**
|
|
167
165
|
|
|
168
|
-
- `name`:
|
|
166
|
+
- `name`: 参数名称(在路径模板中使用,可选 - 如果未提供则自动提取)
|
|
169
167
|
|
|
170
168
|
#### `@query(name)`
|
|
171
169
|
|
|
172
|
-
|
|
170
|
+
定义查询参数。名称是可选的 - 如果未提供,将使用反射从方法参数名自动提取。
|
|
173
171
|
|
|
174
172
|
**参数:**
|
|
175
173
|
|
|
176
|
-
- `name`:
|
|
174
|
+
- `name`: 参数名称(在查询字符串中使用,可选 - 如果未提供则自动提取)
|
|
177
175
|
|
|
178
176
|
#### `@body()`
|
|
179
177
|
|
|
180
|
-
|
|
178
|
+
定义请求体。请求体参数没有名称,因为每个请求只有一个请求体。
|
|
181
179
|
|
|
182
180
|
#### `@header(name)`
|
|
183
181
|
|
|
184
|
-
|
|
182
|
+
定义头部参数。名称是可选的 - 如果未提供,将使用反射从方法参数名自动提取。
|
|
185
183
|
|
|
186
184
|
**参数:**
|
|
187
185
|
|
|
188
|
-
- `name`:
|
|
186
|
+
- `name`: 头部名称(可选 - 如果未提供则自动提取)
|
|
187
|
+
|
|
188
|
+
#### `@request()`
|
|
189
|
+
|
|
190
|
+
定义请求参数,将用作基础请求对象。这允许您传递一个完整的 FetcherRequest 对象来自定义请求配置。
|
|
189
191
|
|
|
190
192
|
**示例:**
|
|
191
193
|
|
|
@@ -194,12 +196,17 @@ class UserService {
|
|
|
194
196
|
@get('/search')
|
|
195
197
|
searchUsers(
|
|
196
198
|
@query('q') query: string,
|
|
197
|
-
@query(
|
|
199
|
+
@query() limit: number,
|
|
198
200
|
@header('Authorization') auth: string,
|
|
199
201
|
): Promise<Response> {
|
|
200
202
|
throw new Error('实现将自动生成');
|
|
201
203
|
}
|
|
202
204
|
|
|
205
|
+
@post('/users')
|
|
206
|
+
createUsers(@request() request: FetcherRequest): Promise<Response> {
|
|
207
|
+
throw new Error('实现将自动生成');
|
|
208
|
+
}
|
|
209
|
+
|
|
203
210
|
@put('/{id}')
|
|
204
211
|
updateUser(@path('id') id: number, @body() user: User): Promise<Response> {
|
|
205
212
|
throw new Error('实现将自动生成');
|
|
@@ -223,7 +230,7 @@ class BaseService {
|
|
|
223
230
|
@api('/users')
|
|
224
231
|
class UserService extends BaseService {
|
|
225
232
|
@get('/{id}')
|
|
226
|
-
getUser(@path(
|
|
233
|
+
getUser(@path() id: number): Promise<Response> {
|
|
227
234
|
throw new Error('实现将自动生成');
|
|
228
235
|
}
|
|
229
236
|
}
|
|
@@ -238,8 +245,34 @@ class ComplexService {
|
|
|
238
245
|
batchOperation(
|
|
239
246
|
@body() items: Item[],
|
|
240
247
|
@header('X-Request-ID') requestId: string,
|
|
241
|
-
@query(
|
|
248
|
+
@query() dryRun: boolean = false,
|
|
249
|
+
): Promise<Response> {
|
|
250
|
+
throw new Error('实现将自动生成');
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### 请求合并
|
|
256
|
+
|
|
257
|
+
当使用 `@request()` 装饰器时,提供的 `FetcherRequest` 对象会使用复杂的合并策略与端点特定配置进行合并:
|
|
258
|
+
|
|
259
|
+
- **嵌套对象**(路径、查询、头部)会被递归合并,参数值优先
|
|
260
|
+
- **基本值**(方法、请求体、超时、信号)来自参数请求的值会覆盖端点值
|
|
261
|
+
- **空对象**会被优雅地处理,回退到端点配置
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
|
|
265
|
+
@api('/users')
|
|
266
|
+
class UserService {
|
|
267
|
+
@post('/')
|
|
268
|
+
createUsers(
|
|
269
|
+
@body() user: User,
|
|
270
|
+
@request() request: FetcherRequest,
|
|
242
271
|
): Promise<Response> {
|
|
272
|
+
// 最终请求将合并:
|
|
273
|
+
// - 端点方法(POST)
|
|
274
|
+
// - 请求体参数(user 对象)
|
|
275
|
+
// - 来自 request 参数的任何配置
|
|
243
276
|
throw new Error('实现将自动生成');
|
|
244
277
|
}
|
|
245
278
|
}
|