@ticatec/restful_service_api 0.6.1 → 0.7.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-CN.md CHANGED
@@ -18,6 +18,32 @@
18
18
  - 🌐 **浏览器优先**: 专为前端应用程序设计
19
19
  - ✨ **PATCH 支持**: 完整支持 HTTP PATCH 方法进行部分更新
20
20
 
21
+ ## ⚠️ v0.7.0 重大变更
22
+
23
+ **`RestfulOptions.contentType` 已被移除,改为使用通用的 `headers` 字段。**
24
+
25
+ ### 对您的影响
26
+
27
+ - `RestfulOptions`(用于 `post`/`put`/`del`/`patch`)不再识别 `contentType` 字段,
28
+ 请把 `{ contentType: 'multipart/form-data' }` 改为
29
+ `{ headers: { 'Content-Type': 'multipart/form-data' } }`。
30
+ - `get()` 新增了一个可选的第 4 个参数:`get(url, params?, dataProcessor?, headers?)`。
31
+ 已有的按位置调用方式(`get(url)`、`get(url, params)`、`get(url, params, dataProcessor)`)不受影响。
32
+ - 这也让单次请求携带任意自定义请求头成为可能(不仅限于 Content-Type),例如通过
33
+ `If-None-Match` 实现条件 GET —— 参见"自定义请求头(例如条件请求)"一节。
34
+
35
+ ### 迁移指南
36
+
37
+ **之前(v0.6.x 及更早版本):**
38
+ ```typescript
39
+ await api.post('/upload', formData, { contentType: 'multipart/form-data' });
40
+ ```
41
+
42
+ **之后(v0.7.0+):**
43
+ ```typescript
44
+ await api.post('/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } });
45
+ ```
46
+
21
47
  ## ⚠️ v0.5.0 重大变更
22
48
 
23
49
  **从 0.5.0 版本开始,此包已迁移到 ESM (ECMAScript Modules) 格式。**
@@ -59,7 +85,7 @@ import RestService, { FileService } from '@ticatec/restful_service_api';
59
85
 
60
86
  // 实现 RestService 接口
61
87
  class MyApiClient implements RestService {
62
- async get(url: string, params?: any, dataProcessor?: DataProcessor) {
88
+ async get(url: string, params?: any, dataProcessor?: DataProcessor, headers?: Record<string, string>) {
63
89
  // 在这里实现
64
90
  }
65
91
 
@@ -109,7 +135,7 @@ const result = await fileApi.upload('/upload', { userId: 123 }, file);
109
135
 
110
136
  ```typescript
111
137
  interface RestService {
112
- get(url: string, params?: any, dataProcessor?: DataProcessor): Promise<any>;
138
+ get(url: string, params?: any, dataProcessor?: DataProcessor, headers?: Record<string, string>): Promise<any>;
113
139
  post(url: string, data?: any, options?: RestfulOptions): Promise<any>;
114
140
  put(url: string, data?: any, options?: RestfulOptions): Promise<any>;
115
141
  patch(url: string, data?: any, options?: RestfulOptions): Promise<any>;
@@ -131,11 +157,12 @@ interface FileService {
131
157
 
132
158
  ### RestService 方法
133
159
 
134
- #### `get(url, params?, dataProcessor?)`
160
+ #### `get(url, params?, dataProcessor?, headers?)`
135
161
  执行 HTTP GET 请求获取资源。
136
162
  - **url**: 接口端点 URL
137
163
  - **params**: 查询参数(可选)
138
164
  - **dataProcessor**: 处理响应数据的函数(可选)
165
+ - **headers**: 本次调用的自定义请求头(可选),例如条件请求:`{ 'If-None-Match': contentHash }`
139
166
 
140
167
  #### `post(url, data?, options?)`
141
168
  执行 HTTP POST 请求创建新资源。
@@ -143,7 +170,8 @@ interface FileService {
143
170
  - **data**: 请求载荷(可选)
144
171
  - **options**: 可选的配置对象,包含:
145
172
  - **params**: 查询参数(可选)
146
- - **contentType**: Content-Type 请求头(可选,默认为 application/json)
173
+ - **headers**: 本次调用的自定义请求头(可选)。可用于覆盖默认的 `Content-Type`
174
+ (`application/json`),例如 `{ 'Content-Type': 'multipart/form-data' }`
147
175
  - **dataProcessor**: 处理响应数据的函数(可选)
148
176
 
149
177
  #### `put(url, data?, options?)`
@@ -152,7 +180,7 @@ interface FileService {
152
180
  - **data**: 请求载荷(可选)
153
181
  - **options**: 可选的配置对象,包含:
154
182
  - **params**: 查询参数(可选)
155
- - **contentType**: Content-Type 请求头(可选,默认为 application/json)
183
+ - **headers**: 本次调用的自定义请求头(可选)
156
184
  - **dataProcessor**: 处理响应数据的函数(可选)
157
185
 
158
186
  #### `patch(url, data?, options?)`
@@ -161,7 +189,7 @@ interface FileService {
161
189
  - **data**: 包含要更新字段的请求载荷(可选)
162
190
  - **options**: 可选的配置对象,包含:
163
191
  - **params**: 查询参数(可选)
164
- - **contentType**: Content-Type 请求头(可选,默认为 application/json)
192
+ - **headers**: 本次调用的自定义请求头(可选)
165
193
  - **dataProcessor**: 处理响应数据的函数(可选)
166
194
 
167
195
  #### `del(url, data?, options?)`
@@ -170,7 +198,7 @@ interface FileService {
170
198
  - **data**: 请求体数据(可选)
171
199
  - **options**: 可选的配置对象,包含:
172
200
  - **params**: 查询参数(可选)
173
- - **contentType**: Content-Type 请求头(可选,默认为 application/json)
201
+ - **headers**: 本次调用的自定义请求头(可选)
174
202
  - **dataProcessor**: 处理响应数据的函数(可选)
175
203
 
176
204
  ### FileService 方法
@@ -232,7 +260,7 @@ import {
232
260
  // RestfulOptions 用于配置请求
233
261
  const options: RestfulOptions = {
234
262
  params: { page: 1, limit: 10 },
235
- contentType: 'application/json',
263
+ headers: { 'Content-Type': 'application/json' },
236
264
  dataProcessor: (data: any) => data.results || data
237
265
  };
238
266
 
@@ -278,8 +306,34 @@ import {
278
306
  TYPE_TEXT
279
307
  } from '@ticatec/restful_service_api';
280
308
 
281
- // 使用示例
282
- await api.post('/upload', data, {}, { contentType: TYPE_JSON });
309
+ // 使用示例 - 通过 RestfulOptions.headers 显式设置请求头
310
+ await api.post('/upload', data, { headers: { [CONTENT_TYPE_NAME]: TYPE_JSON } });
311
+ ```
312
+
313
+ ### 自定义请求头(例如条件请求)
314
+
315
+ `RestfulOptions.headers`(以及 `get()` 的第 4 个参数 `headers`)允许为单次请求附加自定义请求头。
316
+ 一个常见场景是基于本地缓存的 ETag/hash 发起条件 GET 请求:
317
+
318
+ ```typescript
319
+ // 第一次请求:还没有缓存的 hash
320
+ const pack = await api.get('/messages/node1');
321
+ localStorage.setItem('node1-hash', pack.contentHash);
322
+
323
+ // 之后:把缓存的 hash 作为 If-None-Match 发送
324
+ const cachedHash = localStorage.getItem('node1-hash');
325
+ try {
326
+ const updated = await api.get('/messages/node1', undefined, undefined, {
327
+ 'If-None-Match': cachedHash ?? ''
328
+ });
329
+ // 服务端返回 200 —— 内容有变化,使用 `updated`
330
+ } catch (error) {
331
+ if (error instanceof ApiError && Number(error.status) === 304) {
332
+ // 服务端返回 304 Not Modified —— 本地缓存仍然有效
333
+ } else {
334
+ throw error;
335
+ }
336
+ }
283
337
  ```
284
338
 
285
339
  ## 实现示例
@@ -309,48 +363,45 @@ class FetchRestService implements RestService {
309
363
  this.postInterceptor = postInterceptor;
310
364
  }
311
365
 
312
- async get(url: string, params?: any, dataProcessor?: DataProcessor): Promise<any> {
366
+ async get(url: string, params?: any, dataProcessor?: DataProcessor, headers?: Record<string, string>): Promise<any> {
313
367
  const queryString = params ? '?' + new URLSearchParams(params).toString() : '';
314
- return this.request('GET', url + queryString, null, undefined, dataProcessor);
368
+ return this.request('GET', url + queryString, null, headers, dataProcessor);
315
369
  }
316
370
 
317
371
  async post(url: string, data?: any, options?: RestfulOptions): Promise<any> {
318
- const contentType = options?.contentType || TYPE_JSON;
319
372
  const params = options?.params;
320
373
  const queryString = params ? '?' + new URLSearchParams(params).toString() : '';
321
- return this.request('POST', url + queryString, data, contentType, options?.dataProcessor);
374
+ return this.request('POST', url + queryString, data, options?.headers, options?.dataProcessor);
322
375
  }
323
376
 
324
377
  async put(url: string, data?: any, options?: RestfulOptions): Promise<any> {
325
- const contentType = options?.contentType || TYPE_JSON;
326
378
  const params = options?.params;
327
379
  const queryString = params ? '?' + new URLSearchParams(params).toString() : '';
328
- return this.request('PUT', url + queryString, data, contentType, options?.dataProcessor);
380
+ return this.request('PUT', url + queryString, data, options?.headers, options?.dataProcessor);
329
381
  }
330
382
 
331
383
  async patch(url: string, data?: any, options?: RestfulOptions): Promise<any> {
332
- const contentType = options?.contentType || TYPE_JSON;
333
384
  const params = options?.params;
334
385
  const queryString = params ? '?' + new URLSearchParams(params).toString() : '';
335
- return this.request('PATCH', url + queryString, data, contentType, options?.dataProcessor);
386
+ return this.request('PATCH', url + queryString, data, options?.headers, options?.dataProcessor);
336
387
  }
337
388
 
338
389
  async del(url: string, data?: any, options?: RestfulOptions): Promise<any> {
339
- const contentType = options?.contentType || TYPE_JSON;
340
390
  const params = options?.params;
341
391
  const queryString = params ? '?' + new URLSearchParams(params).toString() : '';
342
- return this.request('DELETE', url + queryString, data, contentType, options?.dataProcessor);
392
+ return this.request('DELETE', url + queryString, data, options?.headers, options?.dataProcessor);
343
393
  }
344
394
 
345
- private async request(method: string, url: string, body?: any, contentType?: string, dataProcessor?: DataProcessor): Promise<any> {
395
+ private async request(method: string, url: string, body?: any, customHeaders?: Record<string, string>, dataProcessor?: DataProcessor): Promise<any> {
346
396
  const fullUrl = this.baseURL + url;
347
397
 
348
398
  // 应用请求前拦截器
349
399
  const interceptorResult = this.preInterceptor?.(method, fullUrl) || { headers: {} };
350
400
 
351
401
  const headers = {
402
+ 'Content-Type': TYPE_JSON,
352
403
  ...interceptorResult.headers,
353
- ...(contentType && { 'Content-Type': contentType })
404
+ ...customHeaders
354
405
  };
355
406
 
356
407
  try {
package/README.md CHANGED
@@ -18,6 +18,31 @@ A lightweight TypeScript RESTful API client for browsers with comprehensive erro
18
18
  - 🌐 **Browser-First**: Designed specifically for frontend applications
19
19
  - ✨ **PATCH Support**: Full support for HTTP PATCH method for partial updates
20
20
 
21
+ ## ⚠️ Breaking Changes in v0.7.0
22
+
23
+ **`RestfulOptions.contentType` has been removed in favor of a general-purpose `headers` field.**
24
+
25
+ ### What This Means for You
26
+
27
+ - `contentType` is no longer a recognized field on `RestfulOptions` (used by `post`/`put`/`del`/`patch`).
28
+ Replace `{ contentType: 'multipart/form-data' }` with `{ headers: { 'Content-Type': 'multipart/form-data' } }`.
29
+ - `get()` gained a new, optional 4th parameter: `get(url, params?, dataProcessor?, headers?)`. Existing
30
+ positional calls (`get(url)`, `get(url, params)`, `get(url, params, dataProcessor)`) are unaffected.
31
+ - This also enables custom per-call headers in general (not just Content-Type), e.g. a conditional
32
+ GET via `If-None-Match` — see [Custom Headers (e.g. Conditional Requests)](#custom-headers-eg-conditional-requests).
33
+
34
+ ### Migration Guide
35
+
36
+ **Before (v0.6.x and earlier):**
37
+ ```typescript
38
+ await api.post('/upload', formData, { contentType: 'multipart/form-data' });
39
+ ```
40
+
41
+ **After (v0.7.0+):**
42
+ ```typescript
43
+ await api.post('/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } });
44
+ ```
45
+
21
46
  ## ⚠️ Breaking Changes in v0.5.0
22
47
 
23
48
  **Starting from version 0.5.0, this package has migrated to ESM (ECMAScript Modules) format.**
@@ -58,7 +83,7 @@ import RestService, { FileService } from '@ticatec/restful_service_api';
58
83
 
59
84
  // Your implementation of RestService interface
60
85
  class MyApiClient implements RestService {
61
- async get(url: string, params?: any, dataProcessor?: DataProcessor) {
86
+ async get(url: string, params?: any, dataProcessor?: DataProcessor, headers?: Record<string, string>) {
62
87
  // Implementation here
63
88
  }
64
89
 
@@ -108,7 +133,7 @@ The main interface for standard HTTP REST operations:
108
133
 
109
134
  ```typescript
110
135
  interface RestService {
111
- get(url: string, params?: any, dataProcessor?: DataProcessor): Promise<any>;
136
+ get(url: string, params?: any, dataProcessor?: DataProcessor, headers?: Record<string, string>): Promise<any>;
112
137
  post(url: string, data?: any, options?: RestfulOptions): Promise<any>;
113
138
  put(url: string, data?: any, options?: RestfulOptions): Promise<any>;
114
139
  patch(url: string, data?: any, options?: RestfulOptions): Promise<any>;
@@ -130,11 +155,13 @@ interface FileService {
130
155
 
131
156
  ### RestService Methods
132
157
 
133
- #### `get(url, params?, dataProcessor?)`
158
+ #### `get(url, params?, dataProcessor?, headers?)`
134
159
  Performs HTTP GET request to retrieve a resource.
135
160
  - **url**: The endpoint URL
136
161
  - **params**: Query parameters (optional)
137
162
  - **dataProcessor**: Function to process response data (optional)
163
+ - **headers**: Custom request headers for this single call (optional), e.g. for a conditional
164
+ request: `{ 'If-None-Match': contentHash }`
138
165
 
139
166
  #### `post(url, data?, options?)`
140
167
  Performs HTTP POST request to create a new resource.
@@ -142,7 +169,8 @@ Performs HTTP POST request to create a new resource.
142
169
  - **data**: Request payload (optional)
143
170
  - **options**: Optional configuration object containing:
144
171
  - **params**: Query parameters (optional)
145
- - **contentType**: Content-Type header (optional, defaults to application/json)
172
+ - **headers**: Custom request headers for this single call (optional). Use this to override
173
+ the default `Content-Type` (`application/json`), e.g. `{ 'Content-Type': 'multipart/form-data' }`
146
174
  - **dataProcessor**: Function to process response data (optional)
147
175
 
148
176
  #### `put(url, data?, options?)`
@@ -151,7 +179,7 @@ Performs HTTP PUT request to update an entire resource.
151
179
  - **data**: Request payload (optional)
152
180
  - **options**: Optional configuration object containing:
153
181
  - **params**: Query parameters (optional)
154
- - **contentType**: Content-Type header (optional, defaults to application/json)
182
+ - **headers**: Custom request headers for this single call (optional)
155
183
  - **dataProcessor**: Function to process response data (optional)
156
184
 
157
185
  #### `patch(url, data?, options?)`
@@ -160,7 +188,7 @@ Performs HTTP PATCH request to partially update a resource.
160
188
  - **data**: Request payload with fields to update (optional)
161
189
  - **options**: Optional configuration object containing:
162
190
  - **params**: Query parameters (optional)
163
- - **contentType**: Content-Type header (optional, defaults to application/json)
191
+ - **headers**: Custom request headers for this single call (optional)
164
192
  - **dataProcessor**: Function to process response data (optional)
165
193
 
166
194
  #### `del(url, data?, options?)`
@@ -169,7 +197,7 @@ Performs HTTP DELETE request to delete a resource.
169
197
  - **data**: Request body data (optional)
170
198
  - **options**: Optional configuration object containing:
171
199
  - **params**: Query parameters (optional)
172
- - **contentType**: Content-Type header (optional, defaults to application/json)
200
+ - **headers**: Custom request headers for this single call (optional)
173
201
  - **dataProcessor**: Function to process response data (optional)
174
202
 
175
203
  ### FileService Methods
@@ -231,7 +259,7 @@ import {
231
259
  // RestfulOptions for configuring requests
232
260
  const options: RestfulOptions = {
233
261
  params: { page: 1, limit: 10 },
234
- contentType: 'application/json',
262
+ headers: { 'Content-Type': 'application/json' },
235
263
  dataProcessor: (data: any) => data.results || data
236
264
  };
237
265
 
@@ -277,8 +305,35 @@ import {
277
305
  TYPE_TEXT
278
306
  } from '@ticatec/restful_service_api';
279
307
 
280
- // Usage
281
- await api.post('/upload', data, {}, { contentType: TYPE_JSON });
308
+ // Usage - set a header explicitly via RestfulOptions.headers
309
+ await api.post('/upload', data, { headers: { [CONTENT_TYPE_NAME]: TYPE_JSON } });
310
+ ```
311
+
312
+ ### Custom Headers (e.g. Conditional Requests)
313
+
314
+ `RestfulOptions.headers` (and the 4th `headers` parameter of `get()`) let you attach custom
315
+ request headers to a single call. A common use case is a conditional GET based on a
316
+ previously-cached ETag/hash:
317
+
318
+ ```typescript
319
+ // First request: no cached hash yet
320
+ const pack = await api.get('/messages/node1');
321
+ localStorage.setItem('node1-hash', pack.contentHash);
322
+
323
+ // Later: send the cached hash as If-None-Match
324
+ const cachedHash = localStorage.getItem('node1-hash');
325
+ try {
326
+ const updated = await api.get('/messages/node1', undefined, undefined, {
327
+ 'If-None-Match': cachedHash ?? ''
328
+ });
329
+ // Server responded 200 - content changed, use `updated`
330
+ } catch (error) {
331
+ if (error instanceof ApiError && Number(error.status) === 304) {
332
+ // Server responded 304 Not Modified - the local cache is still valid
333
+ } else {
334
+ throw error;
335
+ }
336
+ }
282
337
  ```
283
338
 
284
339
  ## Implementation Example
@@ -308,48 +363,45 @@ class FetchRestService implements RestService {
308
363
  this.postInterceptor = postInterceptor;
309
364
  }
310
365
 
311
- async get(url: string, params?: any, dataProcessor?: DataProcessor): Promise<any> {
366
+ async get(url: string, params?: any, dataProcessor?: DataProcessor, headers?: Record<string, string>): Promise<any> {
312
367
  const queryString = params ? '?' + new URLSearchParams(params).toString() : '';
313
- return this.request('GET', url + queryString, null, undefined, dataProcessor);
368
+ return this.request('GET', url + queryString, null, headers, dataProcessor);
314
369
  }
315
370
 
316
371
  async post(url: string, data?: any, options?: RestfulOptions): Promise<any> {
317
- const contentType = options?.contentType || TYPE_JSON;
318
372
  const params = options?.params;
319
373
  const queryString = params ? '?' + new URLSearchParams(params).toString() : '';
320
- return this.request('POST', url + queryString, data, contentType, options?.dataProcessor);
374
+ return this.request('POST', url + queryString, data, options?.headers, options?.dataProcessor);
321
375
  }
322
376
 
323
377
  async put(url: string, data?: any, options?: RestfulOptions): Promise<any> {
324
- const contentType = options?.contentType || TYPE_JSON;
325
378
  const params = options?.params;
326
379
  const queryString = params ? '?' + new URLSearchParams(params).toString() : '';
327
- return this.request('PUT', url + queryString, data, contentType, options?.dataProcessor);
380
+ return this.request('PUT', url + queryString, data, options?.headers, options?.dataProcessor);
328
381
  }
329
382
 
330
383
  async patch(url: string, data?: any, options?: RestfulOptions): Promise<any> {
331
- const contentType = options?.contentType || TYPE_JSON;
332
384
  const params = options?.params;
333
385
  const queryString = params ? '?' + new URLSearchParams(params).toString() : '';
334
- return this.request('PATCH', url + queryString, data, contentType, options?.dataProcessor);
386
+ return this.request('PATCH', url + queryString, data, options?.headers, options?.dataProcessor);
335
387
  }
336
388
 
337
389
  async del(url: string, data?: any, options?: RestfulOptions): Promise<any> {
338
- const contentType = options?.contentType || TYPE_JSON;
339
390
  const params = options?.params;
340
391
  const queryString = params ? '?' + new URLSearchParams(params).toString() : '';
341
- return this.request('DELETE', url + queryString, data, contentType, options?.dataProcessor);
392
+ return this.request('DELETE', url + queryString, data, options?.headers, options?.dataProcessor);
342
393
  }
343
394
 
344
- private async request(method: string, url: string, body?: any, contentType?: string, dataProcessor?: DataProcessor): Promise<any> {
395
+ private async request(method: string, url: string, body?: any, customHeaders?: Record<string, string>, dataProcessor?: DataProcessor): Promise<any> {
345
396
  const fullUrl = this.baseURL + url;
346
397
 
347
398
  // Apply pre-interceptor
348
399
  const interceptorResult = this.preInterceptor?.(method, fullUrl) || { headers: {} };
349
400
 
350
401
  const headers = {
402
+ 'Content-Type': TYPE_JSON,
351
403
  ...interceptorResult.headers,
352
- ...(contentType && { 'Content-Type': contentType })
404
+ ...customHeaders
353
405
  };
354
406
 
355
407
  try {
@@ -45,20 +45,20 @@ export default interface FileService {
45
45
  * { userId: 123 },
46
46
  * file,
47
47
  * {
48
- * onProgress: (loaded, total, percent) => {
49
- * console.log(`Upload: ${percent}%`);
48
+ * progressUpdate: (uploadBytes) => {
49
+ * console.log(`Uploaded: ${uploadBytes} bytes`);
50
50
  * },
51
51
  * onCompleted: (data) => {
52
52
  * console.log('Upload complete:', data);
53
53
  * },
54
- * onError: (error) => {
54
+ * handleError: (error) => {
55
55
  * console.error('Upload failed:', error);
56
56
  * }
57
57
  * }
58
58
  * );
59
59
  *
60
60
  * // Cancel the upload
61
- * progress.abort();
61
+ * progress.cancel();
62
62
  * ```
63
63
  */
64
64
  asyncUpload(url: string, params: any, file: File, callback: UploadCallback, fileKey?: string): Promise<UploadProgress>;
@@ -38,10 +38,6 @@ export type ErrorHandler = (ex: Error) => boolean | void;
38
38
  * RESTful API request options
39
39
  */
40
40
  export type RestfulOptions<T = any> = {
41
- /**
42
- * Optional Content-Type header, defaults to 'application/json'
43
- */
44
- contentType?: string;
45
41
  /**
46
42
  * Optional data processing function to transform response data before returning
47
43
  */
@@ -50,6 +46,13 @@ export type RestfulOptions<T = any> = {
50
46
  * Optional query parameters object that will be converted to URL query string
51
47
  */
52
48
  params?: any;
49
+ /**
50
+ * Optional custom request headers for this single call (e.g. { 'If-None-Match': contentHash },
51
+ * or { 'Content-Type': 'multipart/form-data' } to override the default JSON content type).
52
+ * These are merged on top of any headers produced by the PreInterceptor, and take precedence
53
+ * over them when the same header name is used.
54
+ */
55
+ headers?: Record<string, string>;
53
56
  };
54
57
  /**
55
58
  * HTTP header name for Content-Type
@@ -76,6 +79,7 @@ export default interface RestService {
76
79
  * @param url The target URL path for the request
77
80
  * @param params Query parameters object that will be converted to URL query string
78
81
  * @param dataProcessor Optional data processing function to transform response data before returning
82
+ * @param headers Optional custom request headers for this single call (e.g. conditional GET via If-None-Match)
79
83
  * @returns Promise that resolves to the server response data
80
84
  *
81
85
  * @example
@@ -88,14 +92,17 @@ export default interface RestService {
88
92
  *
89
93
  * // GET with data processor
90
94
  * const users = await restService.get('/api/users', null, (data) => data.items);
95
+ *
96
+ * // GET with a custom header (e.g. conditional GET)
97
+ * const pack = await restService.get('/api/messages/node1', null, undefined, { 'If-None-Match': contentHash });
91
98
  * ```
92
99
  */
93
- get<T = any>(url: string, params?: any, dataProcessor?: DataProcessor<T>): Promise<T>;
100
+ get<T = any>(url: string, params?: any, dataProcessor?: DataProcessor<T>, headers?: Record<string, string>): Promise<T>;
94
101
  /**
95
102
  * Performs an HTTP POST request to create a new resource
96
103
  * @param url The target URL path for the request
97
104
  * @param data Request body data to be sent, typically an object or string
98
- * @param options Optional request configuration options, including contentType and dataProcessor
105
+ * @param options Optional request configuration options, including headers and dataProcessor
99
106
  * @returns Promise that resolves to the server response data
100
107
  *
101
108
  * @example
@@ -103,9 +110,9 @@ export default interface RestService {
103
110
  * // Simple POST request
104
111
  * const newUser = await restService.post('/api/users', { name: 'John', age: 30 });
105
112
  *
106
- * // POST with custom content type
113
+ * // POST with a custom Content-Type header
107
114
  * const result = await restService.post('/api/data', formData, {
108
- * contentType: 'multipart/form-data'
115
+ * headers: { 'Content-Type': 'multipart/form-data' }
109
116
  * });
110
117
  *
111
118
  * // POST with data processor
@@ -119,7 +126,7 @@ export default interface RestService {
119
126
  * Performs an HTTP PUT request to update an existing resource
120
127
  * @param url The target URL path for the request
121
128
  * @param data Optional request body data to be sent for updating the resource
122
- * @param options Optional request configuration options, including contentType and dataProcessor
129
+ * @param options Optional request configuration options, including headers and dataProcessor
123
130
  * @returns Promise that resolves to the server response data
124
131
  *
125
132
  * @example
@@ -136,7 +143,7 @@ export default interface RestService {
136
143
  * Performs an HTTP DELETE request to delete a resource
137
144
  * @param url The target URL path for the request
138
145
  * @param data Optional request body data, some DELETE operations may require sending data
139
- * @param options Optional request configuration options, including contentType and dataProcessor
146
+ * @param options Optional request configuration options, including headers and dataProcessor
140
147
  * @returns Promise that resolves to the server response data
141
148
  *
142
149
  * @example
@@ -153,7 +160,7 @@ export default interface RestService {
153
160
  * Performs an HTTP PATCH request to partially update a resource
154
161
  * @param url The target URL path for the request
155
162
  * @param data Optional request body data to be sent for partially updating the resource
156
- * @param options Optional request configuration options, including contentType and dataProcessor
163
+ * @param options Optional request configuration options, including headers and dataProcessor
157
164
  * @returns Promise that resolves to the server response data
158
165
  *
159
166
  * @example
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@ticatec/restful_service_api",
4
- "version": "0.6.1",
4
+ "version": "0.7.0",
5
5
  "description": "A lightweight TypeScript RESTful API client for browsers with error handling. (ESM only, v0.6.0+)",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",