@happy-ts/fetch-t 1.0.6 → 1.0.8

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 CHANGED
@@ -1,6 +1,7 @@
1
1
  # fetchT
2
2
 
3
- [![NPM version](http://img.shields.io/npm/v/@happy-ts/fetch-t.svg)](https://npmjs.org/package/@happy-ts/fetch-t)
3
+ [![NPM version](https://img.shields.io/npm/v/@happy-ts/fetch-t.svg)](https://npmjs.org/package/@happy-ts/fetch-t)
4
+ [![NPM downloads](https://badgen.net/npm/dm/@happy-ts/fetch-t)](https://npmjs.org/package/@happy-ts/fetch-t)
4
5
  [![JSR Version](https://jsr.io/badges/@happy-ts/fetch-t)](https://jsr.io/@happy-ts/fetch-t)
5
6
  [![JSR Score](https://jsr.io/badges/@happy-ts/fetch-t/score)](https://jsr.io/@happy-ts/fetch-t/score)
6
7
  [![Build Status](https://github.com/jiangjie/fetch-t/actions/workflows/test.yml/badge.svg)](https://github.com/jiangjie/fetch-t/actions/workflows/test.yml)
@@ -20,31 +21,37 @@ The return data of fetchT is of a specific type, which can be either `string`, `
20
21
  ## Installation
21
22
 
22
23
  via pnpm
24
+
23
25
  ```
24
- pnpm add happy-rusty
26
+ pnpm add @happy-ts/fetch-t
25
27
  ```
26
28
 
27
29
  or via yarn
30
+
28
31
  ```
29
32
  yarn add @happy-ts/fetch-t
30
33
  ```
31
34
 
32
35
  or just from npm
36
+
33
37
  ```
34
38
  npm install --save @happy-ts/fetch-t
35
39
  ```
36
40
 
37
41
  via JSR
42
+
38
43
  ```
39
44
  jsr add @happy-ts/fetch-t
40
45
  ```
41
46
 
42
47
  for deno
48
+
43
49
  ```
44
50
  deno add @happy-ts/fetch-t
45
51
  ```
46
52
 
47
53
  for bun
54
+
48
55
  ```
49
56
  bunx jsr add @happy-ts/fetch-t
50
57
  ```
@@ -53,8 +60,8 @@ bunx jsr add @happy-ts/fetch-t
53
60
 
54
61
  fetchT is a simple encapsulation of the [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) API, with two main modifications:
55
62
 
56
- * It adds the `abortable` parameter. If `abortable: true` is passed, fetchT will return a `FetchTask` object that allows you to abort the request by calling `FetchTask.abort()`.
57
- * It supports generic return values by adding the responseType parameter. The optional values for `responseType` include `'text' | 'arraybuffer' | 'blob' | 'json'`. The return value corresponds to the parameter and can be either `string | ArrayBuffer | Blob | T`, where T is the generic type. All return values are of the [Result](https://github.com/JiangJie/happy-rusty) type, which facilitates error handling.
63
+ - It adds the `abortable` parameter. If `abortable: true` is passed, fetchT will return a `FetchTask` object that allows you to abort the request by calling `FetchTask.abort()`.
64
+ - It supports generic return values by adding the responseType parameter. The optional values for `responseType` include `'text' | 'arraybuffer' | 'blob' | 'json'`. The return value corresponds to the parameter and can be either `string | ArrayBuffer | Blob | T`, where T is the generic type. All return values are of the [Result](https://github.com/JiangJie/happy-rusty) type, which facilitates error handling.
58
65
 
59
66
  If you don't have these requirements, it is recommended to use the vanilla [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
60
67
 
@@ -80,4 +87,4 @@ if (res.isErr()) {
80
87
  }
81
88
  ```
82
89
 
83
- For more examples, please refer to test case <a href="tests/fetch.test.ts">fetch.test.ts</a>.
90
+ For more examples, please refer to test case <a href="tests/fetch.test.ts">fetch.test.ts</a>.
package/dist/main.cjs CHANGED
@@ -7,13 +7,13 @@ function invariant(expr, createMsg) {
7
7
  throw new TypeError(createMsg());
8
8
  }
9
9
  }
10
- function assertUrl(url) {
11
- invariant(typeof url === "string", () => `Url must be a string. Received ${JSON.stringify(url)}`);
10
+ function assertURL(url) {
11
+ invariant(url instanceof URL, () => `Url must be an URL object. Received ${JSON.stringify(url)}`);
12
12
  }
13
13
 
14
14
  function fetchT(url, init) {
15
- if (typeof url === "string") {
16
- assertUrl(url);
15
+ if (typeof url !== "string") {
16
+ assertURL(url);
17
17
  }
18
18
  const { abortable = false, responseType, ...rest } = init ?? {};
19
19
  let controller;
package/dist/main.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.cjs","sources":["../src/fetch/assertions.ts","../src/fetch/fetch.ts"],"sourcesContent":["/**\n * assert function\n * @param expr\n * @param createMsg return a string message to throw\n */\nfunction invariant(expr: unknown, createMsg: () => string): void {\n if (!expr) {\n throw new TypeError(createMsg());\n }\n}\n\n/**\n * assert url is a string\n *\n * @param url\n */\nexport function assertUrl(url: string): void {\n invariant(typeof url === 'string', () => `Url must be a string. Received ${ JSON.stringify(url) }`);\n}","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Err, Ok } from 'happy-rusty';\nimport { assertUrl } from './assertions.ts';\nimport type { FetchInit, FetchResponse, FetchTask } from './defines.ts';\n\n/**\n * Return `FetchTask<string>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'text';\n}): FetchTask<string>;\n/**\n * Return `FetchTask<ArrayBuffer>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'arraybuffer';\n}): FetchTask<ArrayBuffer>;\n/**\n * Return `FetchTask<Blob>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'blob';\n}): FetchTask<Blob>;\n/**\n * Return `FetchTask<T>`.\n */\nexport function fetchT<T>(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'json';\n}): FetchTask<T>;\n/**\n * Return `FetchResponse<string>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'text';\n}): FetchResponse<string>;\n/**\n * Return `FetchResponse<ArrayBuffer>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'arraybuffer';\n}): FetchResponse<ArrayBuffer>;\n/**\n * Return `FetchResponse<Blob>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'blob';\n}): FetchResponse<Blob>;\n/**\n * Return `FetchResponse<T>`.\n * @param url\n * @param init\n */\nexport function fetchT<T>(url: string | URL, init: FetchInit & {\n responseType: 'json';\n}): FetchResponse<T>;\n/**\n * Return `FetchTask<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n}): FetchTask<Response>;\n/**\n * Return `FetchResponse<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: false;\n}): FetchResponse<Response>;\n/**\n * Return `FetchTask<T>` or `FetchResponse<T>`.\n * @param url\n * @param init\n */\nexport function fetchT<T = any>(url: string | URL, init: FetchInit): FetchTask<T> | FetchResponse<T>;\n/**\n * Return `FetchResponse<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init?: RequestInit): FetchResponse<Response>;\n/**\n * Request the url and return the corresponding type based on the responseType.\n * @param url url to fetch\n * @param init fetch init\n * @returns {FetchTask<T> | FetchResponse<T>} an abort able fetch task or just response\n */\nexport function fetchT<T = any>(url: string | URL, init?: FetchInit): FetchTask<T> | FetchResponse<T> {\n if (typeof url === 'string') {\n assertUrl(url);\n }\n\n // default not abort able\n const { abortable = false, responseType, ...rest } = init ?? {};\n\n let controller: AbortController;\n\n if (abortable) {\n controller = new AbortController();\n rest.signal = controller.signal;\n }\n\n const response: FetchResponse<T> = fetch(url, rest).then(async (res): FetchResponse<T> => {\n if (!res.ok) {\n return Err(new Error(`fetch status: ${ res.status }`));\n }\n\n switch (responseType) {\n case 'arraybuffer': {\n return Ok(await res.arrayBuffer() as T);\n }\n case 'blob': {\n return Ok(await res.blob() as T);\n }\n case 'json': {\n try {\n return Ok(await res.json() as T);\n } catch {\n return Err(new Error('Response is invalid json while responseType is json'));\n }\n }\n case 'text': {\n return Ok(await res.text() as T);\n }\n default: {\n // default return the Response object\n return Ok(res as T);\n }\n }\n }).catch((err) => {\n return Err(err);\n });\n\n if (abortable) {\n return {\n abort(reason?: any): void {\n controller.abort(reason);\n },\n get aborted(): boolean {\n return controller.signal.aborted;\n },\n response,\n };\n } else {\n return response;\n }\n}"],"names":["Err","Ok"],"mappings":";;;;AAKA,SAAS,SAAA,CAAU,MAAe,SAA+B,EAAA;AAC7D,EAAA,IAAI,CAAC,IAAM,EAAA;AACP,IAAM,MAAA,IAAI,SAAU,CAAA,SAAA,EAAW,CAAA,CAAA;AAAA,GACnC;AACJ,CAAA;AAOO,SAAS,UAAU,GAAmB,EAAA;AACzC,EAAU,SAAA,CAAA,OAAO,QAAQ,QAAU,EAAA,MAAM,kCAAmC,IAAK,CAAA,SAAA,CAAU,GAAG,CAAE,CAAE,CAAA,CAAA,CAAA;AACtG;;ACuFgB,SAAA,MAAA,CAAgB,KAAmB,IAAmD,EAAA;AAClG,EAAI,IAAA,OAAO,QAAQ,QAAU,EAAA;AACzB,IAAA,SAAA,CAAU,GAAG,CAAA,CAAA;AAAA,GACjB;AAGA,EAAM,MAAA,EAAE,YAAY,KAAO,EAAA,YAAA,EAAc,GAAG,IAAK,EAAA,GAAI,QAAQ,EAAC,CAAA;AAE9D,EAAI,IAAA,UAAA,CAAA;AAEJ,EAAA,IAAI,SAAW,EAAA;AACX,IAAA,UAAA,GAAa,IAAI,eAAgB,EAAA,CAAA;AACjC,IAAA,IAAA,CAAK,SAAS,UAAW,CAAA,MAAA,CAAA;AAAA,GAC7B;AAEA,EAAA,MAAM,WAA6B,KAAM,CAAA,GAAA,EAAK,IAAI,CAAE,CAAA,IAAA,CAAK,OAAO,GAA0B,KAAA;AACtF,IAAI,IAAA,CAAC,IAAI,EAAI,EAAA;AACT,MAAA,OAAOA,eAAI,IAAI,KAAA,CAAM,iBAAkB,GAAI,CAAA,MAAO,EAAE,CAAC,CAAA,CAAA;AAAA,KACzD;AAEA,IAAA,QAAQ,YAAc;AAAA,MAClB,KAAK,aAAe,EAAA;AAChB,QAAA,OAAOC,aAAG,CAAA,MAAM,GAAI,CAAA,WAAA,EAAkB,CAAA,CAAA;AAAA,OAC1C;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAA,OAAOA,aAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,OACnC;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAI,IAAA;AACA,UAAA,OAAOA,aAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,SAC3B,CAAA,MAAA;AACJ,UAAA,OAAOD,cAAI,CAAA,IAAI,KAAM,CAAA,qDAAqD,CAAC,CAAA,CAAA;AAAA,SAC/E;AAAA,OACJ;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAA,OAAOC,aAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,OACnC;AAAA,MACA,SAAS;AAEL,QAAA,OAAOA,cAAG,GAAQ,CAAA,CAAA;AAAA,OACtB;AAAA,KACJ;AAAA,GACH,CAAA,CAAE,KAAM,CAAA,CAAC,GAAQ,KAAA;AACd,IAAA,OAAOD,eAAI,GAAG,CAAA,CAAA;AAAA,GACjB,CAAA,CAAA;AAED,EAAA,IAAI,SAAW,EAAA;AACX,IAAO,OAAA;AAAA,MACH,MAAM,MAAoB,EAAA;AACtB,QAAA,UAAA,CAAW,MAAM,MAAM,CAAA,CAAA;AAAA,OAC3B;AAAA,MACA,IAAI,OAAmB,GAAA;AACnB,QAAA,OAAO,WAAW,MAAO,CAAA,OAAA,CAAA;AAAA,OAC7B;AAAA,MACA,QAAA;AAAA,KACJ,CAAA;AAAA,GACG,MAAA;AACH,IAAO,OAAA,QAAA,CAAA;AAAA,GACX;AACJ;;;;"}
1
+ {"version":3,"file":"main.cjs","sources":["../src/fetch/assertions.ts","../src/fetch/fetch.ts"],"sourcesContent":["/**\n * assert function\n * @param expr\n * @param createMsg return a string message to throw\n */\nfunction invariant(expr: unknown, createMsg: () => string): void {\n if (!expr) {\n throw new TypeError(createMsg());\n }\n}\n\n/**\n * assert url is an URL object\n *\n * @param url\n */\nexport function assertURL(url: URL): void {\n invariant(url instanceof URL, () => `Url must be an URL object. Received ${ JSON.stringify(url) }`);\n}","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Err, Ok } from 'happy-rusty';\nimport { assertURL } from './assertions.ts';\nimport type { FetchInit, FetchResponse, FetchTask } from './defines.ts';\n\n/**\n * Return `FetchTask<string>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'text';\n}): FetchTask<string>;\n/**\n * Return `FetchTask<ArrayBuffer>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'arraybuffer';\n}): FetchTask<ArrayBuffer>;\n/**\n * Return `FetchTask<Blob>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'blob';\n}): FetchTask<Blob>;\n/**\n * Return `FetchTask<T>`.\n */\nexport function fetchT<T>(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'json';\n}): FetchTask<T>;\n/**\n * Return `FetchResponse<string>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'text';\n}): FetchResponse<string>;\n/**\n * Return `FetchResponse<ArrayBuffer>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'arraybuffer';\n}): FetchResponse<ArrayBuffer>;\n/**\n * Return `FetchResponse<Blob>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'blob';\n}): FetchResponse<Blob>;\n/**\n * Return `FetchResponse<T>`.\n * @param url\n * @param init\n */\nexport function fetchT<T>(url: string | URL, init: FetchInit & {\n responseType: 'json';\n}): FetchResponse<T>;\n/**\n * Return `FetchTask<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n}): FetchTask<Response>;\n/**\n * Return `FetchResponse<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: false;\n}): FetchResponse<Response>;\n/**\n * Return `FetchTask<T>` or `FetchResponse<T>`.\n * @param url\n * @param init\n */\nexport function fetchT<T = any>(url: string | URL, init: FetchInit): FetchTask<T> | FetchResponse<T>;\n/**\n * Return `FetchResponse<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init?: RequestInit): FetchResponse<Response>;\n/**\n * Request the url and return the corresponding type based on the responseType.\n * @param url url to fetch\n * @param init fetch init\n * @returns {FetchTask<T> | FetchResponse<T>} an abort able fetch task or just response\n */\nexport function fetchT<T = any>(url: string | URL, init?: FetchInit): FetchTask<T> | FetchResponse<T> {\n if (typeof url !== 'string') {\n assertURL(url);\n }\n\n // default not abort able\n const { abortable = false, responseType, ...rest } = init ?? {};\n\n let controller: AbortController;\n\n if (abortable) {\n controller = new AbortController();\n rest.signal = controller.signal;\n }\n\n const response: FetchResponse<T> = fetch(url, rest).then(async (res): FetchResponse<T> => {\n if (!res.ok) {\n return Err(new Error(`fetch status: ${ res.status }`));\n }\n\n switch (responseType) {\n case 'arraybuffer': {\n return Ok(await res.arrayBuffer() as T);\n }\n case 'blob': {\n return Ok(await res.blob() as T);\n }\n case 'json': {\n try {\n return Ok(await res.json() as T);\n } catch {\n return Err(new Error('Response is invalid json while responseType is json'));\n }\n }\n case 'text': {\n return Ok(await res.text() as T);\n }\n default: {\n // default return the Response object\n return Ok(res as T);\n }\n }\n }).catch((err) => {\n return Err(err);\n });\n\n if (abortable) {\n return {\n abort(reason?: any): void {\n controller.abort(reason);\n },\n get aborted(): boolean {\n return controller.signal.aborted;\n },\n response,\n };\n } else {\n return response;\n }\n}"],"names":["Err","Ok"],"mappings":";;;;AAKA,SAAS,SAAA,CAAU,MAAe,SAA+B,EAAA;AAC7D,EAAA,IAAI,CAAC,IAAM,EAAA;AACP,IAAM,MAAA,IAAI,SAAU,CAAA,SAAA,EAAW,CAAA,CAAA;AAAA,GACnC;AACJ,CAAA;AAOO,SAAS,UAAU,GAAgB,EAAA;AACtC,EAAU,SAAA,CAAA,GAAA,YAAe,KAAK,MAAM,CAAA,oCAAA,EAAwC,KAAK,SAAU,CAAA,GAAG,CAAE,CAAE,CAAA,CAAA,CAAA;AACtG;;ACuFgB,SAAA,MAAA,CAAgB,KAAmB,IAAmD,EAAA;AAClG,EAAI,IAAA,OAAO,QAAQ,QAAU,EAAA;AACzB,IAAA,SAAA,CAAU,GAAG,CAAA,CAAA;AAAA,GACjB;AAGA,EAAM,MAAA,EAAE,YAAY,KAAO,EAAA,YAAA,EAAc,GAAG,IAAK,EAAA,GAAI,QAAQ,EAAC,CAAA;AAE9D,EAAI,IAAA,UAAA,CAAA;AAEJ,EAAA,IAAI,SAAW,EAAA;AACX,IAAA,UAAA,GAAa,IAAI,eAAgB,EAAA,CAAA;AACjC,IAAA,IAAA,CAAK,SAAS,UAAW,CAAA,MAAA,CAAA;AAAA,GAC7B;AAEA,EAAA,MAAM,WAA6B,KAAM,CAAA,GAAA,EAAK,IAAI,CAAE,CAAA,IAAA,CAAK,OAAO,GAA0B,KAAA;AACtF,IAAI,IAAA,CAAC,IAAI,EAAI,EAAA;AACT,MAAA,OAAOA,eAAI,IAAI,KAAA,CAAM,iBAAkB,GAAI,CAAA,MAAO,EAAE,CAAC,CAAA,CAAA;AAAA,KACzD;AAEA,IAAA,QAAQ,YAAc;AAAA,MAClB,KAAK,aAAe,EAAA;AAChB,QAAA,OAAOC,aAAG,CAAA,MAAM,GAAI,CAAA,WAAA,EAAkB,CAAA,CAAA;AAAA,OAC1C;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAA,OAAOA,aAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,OACnC;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAI,IAAA;AACA,UAAA,OAAOA,aAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,SAC3B,CAAA,MAAA;AACJ,UAAA,OAAOD,cAAI,CAAA,IAAI,KAAM,CAAA,qDAAqD,CAAC,CAAA,CAAA;AAAA,SAC/E;AAAA,OACJ;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAA,OAAOC,aAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,OACnC;AAAA,MACA,SAAS;AAEL,QAAA,OAAOA,cAAG,GAAQ,CAAA,CAAA;AAAA,OACtB;AAAA,KACJ;AAAA,GACH,CAAA,CAAE,KAAM,CAAA,CAAC,GAAQ,KAAA;AACd,IAAA,OAAOD,eAAI,GAAG,CAAA,CAAA;AAAA,GACjB,CAAA,CAAA;AAED,EAAA,IAAI,SAAW,EAAA;AACX,IAAO,OAAA;AAAA,MACH,MAAM,MAAoB,EAAA;AACtB,QAAA,UAAA,CAAW,MAAM,MAAM,CAAA,CAAA;AAAA,OAC3B;AAAA,MACA,IAAI,OAAmB,GAAA;AACnB,QAAA,OAAO,WAAW,MAAO,CAAA,OAAA,CAAA;AAAA,OAC7B;AAAA,MACA,QAAA;AAAA,KACJ,CAAA;AAAA,GACG,MAAA;AACH,IAAO,OAAA,QAAA,CAAA;AAAA,GACX;AACJ;;;;"}
package/dist/main.mjs CHANGED
@@ -5,13 +5,13 @@ function invariant(expr, createMsg) {
5
5
  throw new TypeError(createMsg());
6
6
  }
7
7
  }
8
- function assertUrl(url) {
9
- invariant(typeof url === "string", () => `Url must be a string. Received ${JSON.stringify(url)}`);
8
+ function assertURL(url) {
9
+ invariant(url instanceof URL, () => `Url must be an URL object. Received ${JSON.stringify(url)}`);
10
10
  }
11
11
 
12
12
  function fetchT(url, init) {
13
- if (typeof url === "string") {
14
- assertUrl(url);
13
+ if (typeof url !== "string") {
14
+ assertURL(url);
15
15
  }
16
16
  const { abortable = false, responseType, ...rest } = init ?? {};
17
17
  let controller;
package/dist/main.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.mjs","sources":["../src/fetch/assertions.ts","../src/fetch/fetch.ts"],"sourcesContent":["/**\n * assert function\n * @param expr\n * @param createMsg return a string message to throw\n */\nfunction invariant(expr: unknown, createMsg: () => string): void {\n if (!expr) {\n throw new TypeError(createMsg());\n }\n}\n\n/**\n * assert url is a string\n *\n * @param url\n */\nexport function assertUrl(url: string): void {\n invariant(typeof url === 'string', () => `Url must be a string. Received ${ JSON.stringify(url) }`);\n}","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Err, Ok } from 'happy-rusty';\nimport { assertUrl } from './assertions.ts';\nimport type { FetchInit, FetchResponse, FetchTask } from './defines.ts';\n\n/**\n * Return `FetchTask<string>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'text';\n}): FetchTask<string>;\n/**\n * Return `FetchTask<ArrayBuffer>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'arraybuffer';\n}): FetchTask<ArrayBuffer>;\n/**\n * Return `FetchTask<Blob>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'blob';\n}): FetchTask<Blob>;\n/**\n * Return `FetchTask<T>`.\n */\nexport function fetchT<T>(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'json';\n}): FetchTask<T>;\n/**\n * Return `FetchResponse<string>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'text';\n}): FetchResponse<string>;\n/**\n * Return `FetchResponse<ArrayBuffer>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'arraybuffer';\n}): FetchResponse<ArrayBuffer>;\n/**\n * Return `FetchResponse<Blob>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'blob';\n}): FetchResponse<Blob>;\n/**\n * Return `FetchResponse<T>`.\n * @param url\n * @param init\n */\nexport function fetchT<T>(url: string | URL, init: FetchInit & {\n responseType: 'json';\n}): FetchResponse<T>;\n/**\n * Return `FetchTask<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n}): FetchTask<Response>;\n/**\n * Return `FetchResponse<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: false;\n}): FetchResponse<Response>;\n/**\n * Return `FetchTask<T>` or `FetchResponse<T>`.\n * @param url\n * @param init\n */\nexport function fetchT<T = any>(url: string | URL, init: FetchInit): FetchTask<T> | FetchResponse<T>;\n/**\n * Return `FetchResponse<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init?: RequestInit): FetchResponse<Response>;\n/**\n * Request the url and return the corresponding type based on the responseType.\n * @param url url to fetch\n * @param init fetch init\n * @returns {FetchTask<T> | FetchResponse<T>} an abort able fetch task or just response\n */\nexport function fetchT<T = any>(url: string | URL, init?: FetchInit): FetchTask<T> | FetchResponse<T> {\n if (typeof url === 'string') {\n assertUrl(url);\n }\n\n // default not abort able\n const { abortable = false, responseType, ...rest } = init ?? {};\n\n let controller: AbortController;\n\n if (abortable) {\n controller = new AbortController();\n rest.signal = controller.signal;\n }\n\n const response: FetchResponse<T> = fetch(url, rest).then(async (res): FetchResponse<T> => {\n if (!res.ok) {\n return Err(new Error(`fetch status: ${ res.status }`));\n }\n\n switch (responseType) {\n case 'arraybuffer': {\n return Ok(await res.arrayBuffer() as T);\n }\n case 'blob': {\n return Ok(await res.blob() as T);\n }\n case 'json': {\n try {\n return Ok(await res.json() as T);\n } catch {\n return Err(new Error('Response is invalid json while responseType is json'));\n }\n }\n case 'text': {\n return Ok(await res.text() as T);\n }\n default: {\n // default return the Response object\n return Ok(res as T);\n }\n }\n }).catch((err) => {\n return Err(err);\n });\n\n if (abortable) {\n return {\n abort(reason?: any): void {\n controller.abort(reason);\n },\n get aborted(): boolean {\n return controller.signal.aborted;\n },\n response,\n };\n } else {\n return response;\n }\n}"],"names":[],"mappings":";;AAKA,SAAS,SAAA,CAAU,MAAe,SAA+B,EAAA;AAC7D,EAAA,IAAI,CAAC,IAAM,EAAA;AACP,IAAM,MAAA,IAAI,SAAU,CAAA,SAAA,EAAW,CAAA,CAAA;AAAA,GACnC;AACJ,CAAA;AAOO,SAAS,UAAU,GAAmB,EAAA;AACzC,EAAU,SAAA,CAAA,OAAO,QAAQ,QAAU,EAAA,MAAM,kCAAmC,IAAK,CAAA,SAAA,CAAU,GAAG,CAAE,CAAE,CAAA,CAAA,CAAA;AACtG;;ACuFgB,SAAA,MAAA,CAAgB,KAAmB,IAAmD,EAAA;AAClG,EAAI,IAAA,OAAO,QAAQ,QAAU,EAAA;AACzB,IAAA,SAAA,CAAU,GAAG,CAAA,CAAA;AAAA,GACjB;AAGA,EAAM,MAAA,EAAE,YAAY,KAAO,EAAA,YAAA,EAAc,GAAG,IAAK,EAAA,GAAI,QAAQ,EAAC,CAAA;AAE9D,EAAI,IAAA,UAAA,CAAA;AAEJ,EAAA,IAAI,SAAW,EAAA;AACX,IAAA,UAAA,GAAa,IAAI,eAAgB,EAAA,CAAA;AACjC,IAAA,IAAA,CAAK,SAAS,UAAW,CAAA,MAAA,CAAA;AAAA,GAC7B;AAEA,EAAA,MAAM,WAA6B,KAAM,CAAA,GAAA,EAAK,IAAI,CAAE,CAAA,IAAA,CAAK,OAAO,GAA0B,KAAA;AACtF,IAAI,IAAA,CAAC,IAAI,EAAI,EAAA;AACT,MAAA,OAAO,IAAI,IAAI,KAAA,CAAM,iBAAkB,GAAI,CAAA,MAAO,EAAE,CAAC,CAAA,CAAA;AAAA,KACzD;AAEA,IAAA,QAAQ,YAAc;AAAA,MAClB,KAAK,aAAe,EAAA;AAChB,QAAA,OAAO,EAAG,CAAA,MAAM,GAAI,CAAA,WAAA,EAAkB,CAAA,CAAA;AAAA,OAC1C;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAA,OAAO,EAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,OACnC;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAI,IAAA;AACA,UAAA,OAAO,EAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,SAC3B,CAAA,MAAA;AACJ,UAAA,OAAO,GAAI,CAAA,IAAI,KAAM,CAAA,qDAAqD,CAAC,CAAA,CAAA;AAAA,SAC/E;AAAA,OACJ;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAA,OAAO,EAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,OACnC;AAAA,MACA,SAAS;AAEL,QAAA,OAAO,GAAG,GAAQ,CAAA,CAAA;AAAA,OACtB;AAAA,KACJ;AAAA,GACH,CAAA,CAAE,KAAM,CAAA,CAAC,GAAQ,KAAA;AACd,IAAA,OAAO,IAAI,GAAG,CAAA,CAAA;AAAA,GACjB,CAAA,CAAA;AAED,EAAA,IAAI,SAAW,EAAA;AACX,IAAO,OAAA;AAAA,MACH,MAAM,MAAoB,EAAA;AACtB,QAAA,UAAA,CAAW,MAAM,MAAM,CAAA,CAAA;AAAA,OAC3B;AAAA,MACA,IAAI,OAAmB,GAAA;AACnB,QAAA,OAAO,WAAW,MAAO,CAAA,OAAA,CAAA;AAAA,OAC7B;AAAA,MACA,QAAA;AAAA,KACJ,CAAA;AAAA,GACG,MAAA;AACH,IAAO,OAAA,QAAA,CAAA;AAAA,GACX;AACJ;;;;"}
1
+ {"version":3,"file":"main.mjs","sources":["../src/fetch/assertions.ts","../src/fetch/fetch.ts"],"sourcesContent":["/**\n * assert function\n * @param expr\n * @param createMsg return a string message to throw\n */\nfunction invariant(expr: unknown, createMsg: () => string): void {\n if (!expr) {\n throw new TypeError(createMsg());\n }\n}\n\n/**\n * assert url is an URL object\n *\n * @param url\n */\nexport function assertURL(url: URL): void {\n invariant(url instanceof URL, () => `Url must be an URL object. Received ${ JSON.stringify(url) }`);\n}","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Err, Ok } from 'happy-rusty';\nimport { assertURL } from './assertions.ts';\nimport type { FetchInit, FetchResponse, FetchTask } from './defines.ts';\n\n/**\n * Return `FetchTask<string>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'text';\n}): FetchTask<string>;\n/**\n * Return `FetchTask<ArrayBuffer>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'arraybuffer';\n}): FetchTask<ArrayBuffer>;\n/**\n * Return `FetchTask<Blob>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'blob';\n}): FetchTask<Blob>;\n/**\n * Return `FetchTask<T>`.\n */\nexport function fetchT<T>(url: string | URL, init: FetchInit & {\n abortable: true;\n responseType: 'json';\n}): FetchTask<T>;\n/**\n * Return `FetchResponse<string>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'text';\n}): FetchResponse<string>;\n/**\n * Return `FetchResponse<ArrayBuffer>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'arraybuffer';\n}): FetchResponse<ArrayBuffer>;\n/**\n * Return `FetchResponse<Blob>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n responseType: 'blob';\n}): FetchResponse<Blob>;\n/**\n * Return `FetchResponse<T>`.\n * @param url\n * @param init\n */\nexport function fetchT<T>(url: string | URL, init: FetchInit & {\n responseType: 'json';\n}): FetchResponse<T>;\n/**\n * Return `FetchTask<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: true;\n}): FetchTask<Response>;\n/**\n * Return `FetchResponse<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init: FetchInit & {\n abortable: false;\n}): FetchResponse<Response>;\n/**\n * Return `FetchTask<T>` or `FetchResponse<T>`.\n * @param url\n * @param init\n */\nexport function fetchT<T = any>(url: string | URL, init: FetchInit): FetchTask<T> | FetchResponse<T>;\n/**\n * Return `FetchResponse<Response>`.\n * @param url\n * @param init\n */\nexport function fetchT(url: string | URL, init?: RequestInit): FetchResponse<Response>;\n/**\n * Request the url and return the corresponding type based on the responseType.\n * @param url url to fetch\n * @param init fetch init\n * @returns {FetchTask<T> | FetchResponse<T>} an abort able fetch task or just response\n */\nexport function fetchT<T = any>(url: string | URL, init?: FetchInit): FetchTask<T> | FetchResponse<T> {\n if (typeof url !== 'string') {\n assertURL(url);\n }\n\n // default not abort able\n const { abortable = false, responseType, ...rest } = init ?? {};\n\n let controller: AbortController;\n\n if (abortable) {\n controller = new AbortController();\n rest.signal = controller.signal;\n }\n\n const response: FetchResponse<T> = fetch(url, rest).then(async (res): FetchResponse<T> => {\n if (!res.ok) {\n return Err(new Error(`fetch status: ${ res.status }`));\n }\n\n switch (responseType) {\n case 'arraybuffer': {\n return Ok(await res.arrayBuffer() as T);\n }\n case 'blob': {\n return Ok(await res.blob() as T);\n }\n case 'json': {\n try {\n return Ok(await res.json() as T);\n } catch {\n return Err(new Error('Response is invalid json while responseType is json'));\n }\n }\n case 'text': {\n return Ok(await res.text() as T);\n }\n default: {\n // default return the Response object\n return Ok(res as T);\n }\n }\n }).catch((err) => {\n return Err(err);\n });\n\n if (abortable) {\n return {\n abort(reason?: any): void {\n controller.abort(reason);\n },\n get aborted(): boolean {\n return controller.signal.aborted;\n },\n response,\n };\n } else {\n return response;\n }\n}"],"names":[],"mappings":";;AAKA,SAAS,SAAA,CAAU,MAAe,SAA+B,EAAA;AAC7D,EAAA,IAAI,CAAC,IAAM,EAAA;AACP,IAAM,MAAA,IAAI,SAAU,CAAA,SAAA,EAAW,CAAA,CAAA;AAAA,GACnC;AACJ,CAAA;AAOO,SAAS,UAAU,GAAgB,EAAA;AACtC,EAAU,SAAA,CAAA,GAAA,YAAe,KAAK,MAAM,CAAA,oCAAA,EAAwC,KAAK,SAAU,CAAA,GAAG,CAAE,CAAE,CAAA,CAAA,CAAA;AACtG;;ACuFgB,SAAA,MAAA,CAAgB,KAAmB,IAAmD,EAAA;AAClG,EAAI,IAAA,OAAO,QAAQ,QAAU,EAAA;AACzB,IAAA,SAAA,CAAU,GAAG,CAAA,CAAA;AAAA,GACjB;AAGA,EAAM,MAAA,EAAE,YAAY,KAAO,EAAA,YAAA,EAAc,GAAG,IAAK,EAAA,GAAI,QAAQ,EAAC,CAAA;AAE9D,EAAI,IAAA,UAAA,CAAA;AAEJ,EAAA,IAAI,SAAW,EAAA;AACX,IAAA,UAAA,GAAa,IAAI,eAAgB,EAAA,CAAA;AACjC,IAAA,IAAA,CAAK,SAAS,UAAW,CAAA,MAAA,CAAA;AAAA,GAC7B;AAEA,EAAA,MAAM,WAA6B,KAAM,CAAA,GAAA,EAAK,IAAI,CAAE,CAAA,IAAA,CAAK,OAAO,GAA0B,KAAA;AACtF,IAAI,IAAA,CAAC,IAAI,EAAI,EAAA;AACT,MAAA,OAAO,IAAI,IAAI,KAAA,CAAM,iBAAkB,GAAI,CAAA,MAAO,EAAE,CAAC,CAAA,CAAA;AAAA,KACzD;AAEA,IAAA,QAAQ,YAAc;AAAA,MAClB,KAAK,aAAe,EAAA;AAChB,QAAA,OAAO,EAAG,CAAA,MAAM,GAAI,CAAA,WAAA,EAAkB,CAAA,CAAA;AAAA,OAC1C;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAA,OAAO,EAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,OACnC;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAI,IAAA;AACA,UAAA,OAAO,EAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,SAC3B,CAAA,MAAA;AACJ,UAAA,OAAO,GAAI,CAAA,IAAI,KAAM,CAAA,qDAAqD,CAAC,CAAA,CAAA;AAAA,SAC/E;AAAA,OACJ;AAAA,MACA,KAAK,MAAQ,EAAA;AACT,QAAA,OAAO,EAAG,CAAA,MAAM,GAAI,CAAA,IAAA,EAAW,CAAA,CAAA;AAAA,OACnC;AAAA,MACA,SAAS;AAEL,QAAA,OAAO,GAAG,GAAQ,CAAA,CAAA;AAAA,OACtB;AAAA,KACJ;AAAA,GACH,CAAA,CAAE,KAAM,CAAA,CAAC,GAAQ,KAAA;AACd,IAAA,OAAO,IAAI,GAAG,CAAA,CAAA;AAAA,GACjB,CAAA,CAAA;AAED,EAAA,IAAI,SAAW,EAAA;AACX,IAAO,OAAA;AAAA,MACH,MAAM,MAAoB,EAAA;AACtB,QAAA,UAAA,CAAW,MAAM,MAAM,CAAA,CAAA;AAAA,OAC3B;AAAA,MACA,IAAI,OAAmB,GAAA;AACnB,QAAA,OAAO,WAAW,MAAO,CAAA,OAAA,CAAA;AAAA,OAC7B;AAAA,MACA,QAAA;AAAA,KACJ,CAAA;AAAA,GACG,MAAA;AACH,IAAO,OAAA,QAAA,CAAA;AAAA,GACX;AACJ;;;;"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@happy-ts/fetch-t",
3
- "description": "Cancelable fetch wrapper with the ability to specify the return type.",
3
+ "description": "Abortable fetch wrapper with the ability to specify the return type.",
4
4
  "author": "jiang115jie@gmail.com",
5
5
  "license": "GPL-3.0",
6
- "version": "1.0.6",
6
+ "version": "1.0.8",
7
7
  "type": "module",
8
8
  "source": "src/mod.ts",
9
9
  "main": "dist/main.cjs",
@@ -33,21 +33,22 @@
33
33
  "keywords": [
34
34
  "fetch",
35
35
  "abort",
36
+ "cancel",
36
37
  "responseType"
37
38
  ],
38
39
  "devDependencies": {
39
40
  "@jest/globals": "^29.7.0",
40
- "@typescript-eslint/eslint-plugin": "^7.8.0",
41
- "@typescript-eslint/parser": "^7.8.0",
41
+ "@typescript-eslint/eslint-plugin": "^7.9.0",
42
+ "@typescript-eslint/parser": "^7.9.0",
42
43
  "eslint": "^8.57.0",
43
- "rimraf": "^5.0.5",
44
+ "rimraf": "^5.0.7",
44
45
  "rollup": "^4.17.2",
45
46
  "rollup-plugin-dts": "^6.1.0",
46
47
  "rollup-plugin-esbuild": "^6.1.1",
47
48
  "typescript": "^5.4.5"
48
49
  },
49
50
  "dependencies": {
50
- "happy-rusty": "^1.0.8"
51
+ "happy-rusty": "^1.0.9"
51
52
  },
52
53
  "packageManager": "pnpm@9.1.1+sha512.14e915759c11f77eac07faba4d019c193ec8637229e62ec99eefb7cf3c3b75c64447882b7c485142451ee3a6b408059cdfb7b7fa0341b975f12d0f7629c71195"
53
54
  }
@@ -10,10 +10,10 @@ function invariant(expr: unknown, createMsg: () => string): void {
10
10
  }
11
11
 
12
12
  /**
13
- * assert url is a string
13
+ * assert url is an URL object
14
14
  *
15
15
  * @param url
16
16
  */
17
- export function assertUrl(url: string): void {
18
- invariant(typeof url === 'string', () => `Url must be a string. Received ${ JSON.stringify(url) }`);
17
+ export function assertURL(url: URL): void {
18
+ invariant(url instanceof URL, () => `Url must be an URL object. Received ${ JSON.stringify(url) }`);
19
19
  }
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import { Err, Ok } from 'happy-rusty';
3
- import { assertUrl } from './assertions.ts';
3
+ import { assertURL } from './assertions.ts';
4
4
  import type { FetchInit, FetchResponse, FetchTask } from './defines.ts';
5
5
 
6
6
  /**
@@ -104,8 +104,8 @@ export function fetchT(url: string | URL, init?: RequestInit): FetchResponse<Res
104
104
  * @returns {FetchTask<T> | FetchResponse<T>} an abort able fetch task or just response
105
105
  */
106
106
  export function fetchT<T = any>(url: string | URL, init?: FetchInit): FetchTask<T> | FetchResponse<T> {
107
- if (typeof url === 'string') {
108
- assertUrl(url);
107
+ if (typeof url !== 'string') {
108
+ assertURL(url);
109
109
  }
110
110
 
111
111
  // default not abort able