@jsenv/fetch 1.0.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 +21 -0
- package/package.json +42 -0
- package/src/fetch_url.js +93 -0
- package/src/main.js +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# fetchUrl
|
|
2
|
+
|
|
3
|
+
`fetchUrl` is an async function requesting an url and returning a response object. It is a small wrapper on top of [node-fetch](https://github.com/node-fetch/node-fetch). It was created to provide a unified approach to request file and data urls.
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
import { fetchUrl } from "@jsenv/fetch"
|
|
7
|
+
|
|
8
|
+
const responseForFile = await fetchUrl("file:///Users/you/index.html", {
|
|
9
|
+
method: "GET",
|
|
10
|
+
headers: {
|
|
11
|
+
"if-modified-since": "Wed, 21 Oct 2015 07:28:00 GMT",
|
|
12
|
+
},
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const responseForHttp = await fetchUrl("http://example.com/file.js", {
|
|
16
|
+
method: "GET",
|
|
17
|
+
headers: {
|
|
18
|
+
"if-modified-since": "Wed, 21 Oct 2015 07:28:00 GMT",
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jsenv/fetch",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Unified url fetcher (http, http, file, data)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "dmail",
|
|
8
|
+
"email": "dmaillard06@gmail.com",
|
|
9
|
+
"url": "https://twitter.com/damienmaillard"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/jsenv/jsenv-core",
|
|
14
|
+
"directory": "packages/fetch"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=16.13.0"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public",
|
|
21
|
+
"registry": "https://registry.npmjs.org"
|
|
22
|
+
},
|
|
23
|
+
"type": "module",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"import": "./src/main.js"
|
|
27
|
+
},
|
|
28
|
+
"./*": "./*"
|
|
29
|
+
},
|
|
30
|
+
"main": "./src/main.js",
|
|
31
|
+
"files": [
|
|
32
|
+
"/src/"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"test": "node --conditions=development ./scripts/test.mjs"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@jsenv/urls": "1.2.5",
|
|
39
|
+
"@jsenv/server": "12.7.0",
|
|
40
|
+
"node-fetch": "2.6.7"
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/fetch_url.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// https://github.com/node-fetch/node-fetch/blob/8c197f8982a238b3c345c64b17bfa92e16b4f7c4/src/response.js#L1
|
|
2
|
+
|
|
3
|
+
import { Agent } from "node:https"
|
|
4
|
+
import nodeFetch, { Response } from "node-fetch"
|
|
5
|
+
|
|
6
|
+
import { DATA_URL } from "@jsenv/urls"
|
|
7
|
+
import { fetchFileSystem } from "@jsenv/server"
|
|
8
|
+
import {
|
|
9
|
+
isFileHandle,
|
|
10
|
+
fileHandleToReadableStream,
|
|
11
|
+
} from "@jsenv/server/src/internal/body.js"
|
|
12
|
+
|
|
13
|
+
export const fetchUrl = async (
|
|
14
|
+
url,
|
|
15
|
+
{
|
|
16
|
+
signal = new AbortController().signal,
|
|
17
|
+
ignoreHttpsError = false,
|
|
18
|
+
canReadDirectory,
|
|
19
|
+
contentTypeMap,
|
|
20
|
+
cacheStrategy,
|
|
21
|
+
method = "GET",
|
|
22
|
+
headers = {},
|
|
23
|
+
...rest
|
|
24
|
+
} = {},
|
|
25
|
+
) => {
|
|
26
|
+
try {
|
|
27
|
+
url = String(new URL(url))
|
|
28
|
+
} catch (e) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`fetchUrl first argument must be an absolute url, received ${url}`,
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (url.startsWith("file://")) {
|
|
35
|
+
const responseProperties = await fetchFileSystem(url, {
|
|
36
|
+
signal,
|
|
37
|
+
method,
|
|
38
|
+
headers,
|
|
39
|
+
rootDirectoryUrl: "file://",
|
|
40
|
+
cacheStrategy,
|
|
41
|
+
canReadDirectory,
|
|
42
|
+
contentTypeMap,
|
|
43
|
+
...rest,
|
|
44
|
+
})
|
|
45
|
+
const responseBody = responseProperties.body
|
|
46
|
+
|
|
47
|
+
const response = new Response(
|
|
48
|
+
typeof responseBody === "string"
|
|
49
|
+
? Buffer.from(responseBody)
|
|
50
|
+
: isFileHandle(responseBody)
|
|
51
|
+
? fileHandleToReadableStream(responseBody)
|
|
52
|
+
: responseBody,
|
|
53
|
+
{
|
|
54
|
+
url,
|
|
55
|
+
status: responseProperties.status,
|
|
56
|
+
statusText: responseProperties.statusText,
|
|
57
|
+
headers: responseProperties.headers,
|
|
58
|
+
},
|
|
59
|
+
)
|
|
60
|
+
return response
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (url.startsWith("data:")) {
|
|
64
|
+
const { contentType, base64Flag, data } = DATA_URL.parse(url)
|
|
65
|
+
const body = base64Flag ? Buffer.from(data, "base64") : Buffer.from(data)
|
|
66
|
+
const response = new Response(body, {
|
|
67
|
+
url,
|
|
68
|
+
status: 200,
|
|
69
|
+
headers: {
|
|
70
|
+
"content-type": contentType,
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
return response
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const response = await nodeFetch(url, {
|
|
77
|
+
signal,
|
|
78
|
+
method,
|
|
79
|
+
headers,
|
|
80
|
+
...(ignoreHttpsError && url.startsWith("https")
|
|
81
|
+
? {
|
|
82
|
+
agent: () => {
|
|
83
|
+
return new Agent({
|
|
84
|
+
rejectUnauthorized: false,
|
|
85
|
+
})
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
: {}),
|
|
89
|
+
...rest,
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
return response
|
|
93
|
+
}
|
package/src/main.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { fetchUrl } from "./fetch_url.js"
|