@jsenv/fetch 1.2.9 → 1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/fetch",
3
- "version": "1.2.9",
3
+ "version": "1.3.0",
4
4
  "description": "Unified url fetcher (http, http, file, data)",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -33,11 +33,11 @@
33
33
  ],
34
34
  "sideEffects": false,
35
35
  "dependencies": {
36
- "@jsenv/urls": "2.7.1",
37
- "@jsenv/server": "16.0.7",
36
+ "@jsenv/urls": "2.7.3",
37
+ "@jsenv/server": "16.1.1",
38
38
  "node-fetch": "3.3.2"
39
39
  },
40
40
  "devDependencies": {
41
- "@jsenv/server": "16.0.7"
41
+ "@jsenv/server": "16.1.1"
42
42
  }
43
43
  }
@@ -1,6 +1,6 @@
1
1
  // https://github.com/node-fetch/node-fetch/blob/8c197f8982a238b3c345c64b17bfa92e16b4f7c4/src/response.js#L1
2
2
 
3
- import { createFileSystemFetch } from "@jsenv/server";
3
+ import { createFileSystemFetch } from "@jsenv/server/src/filesystem/fetch_filesystem.js";
4
4
  import {
5
5
  fileHandleToReadableStream,
6
6
  isFileHandle,
@@ -0,0 +1,92 @@
1
+ import { observableFromNodeStream } from "@jsenv/server/src/interfacing_with_node/observable_from_node_stream.js";
2
+
3
+ export const fetchUsingNodeRequest = async (
4
+ url,
5
+ { signal, method = "GET", headers = {}, body, path, ignoreHttpsError } = {},
6
+ ) => {
7
+ let createNodeRequest;
8
+ if (url.startsWith("http:")) {
9
+ const { request } = await import("node:http");
10
+ createNodeRequest = request;
11
+ } else {
12
+ const { request } = await import("node:https");
13
+ createNodeRequest = request;
14
+ }
15
+
16
+ const urlObject = new URL(url);
17
+ const { port, hostname } = urlObject;
18
+ const options = {
19
+ signal,
20
+ hostname,
21
+ port,
22
+ method,
23
+ headers: {
24
+ ...(body ? { "content-length": Buffer.byteLength(body) } : {}),
25
+ ...headers,
26
+ },
27
+ path: path || urlObject.pathname,
28
+ };
29
+ if (ignoreHttpsError && url.startsWith("https")) {
30
+ const { Agent } = await import("node:https");
31
+ options.agent = new Agent({
32
+ rejectUnauthorized: false,
33
+ });
34
+ }
35
+
36
+ const nodeRequest = createNodeRequest(options);
37
+ if (body) {
38
+ nodeRequest.write(body);
39
+ }
40
+ nodeRequest.end();
41
+
42
+ const nodeResponse = await new Promise((resolve, reject) => {
43
+ nodeRequest.on("error", (error) => {
44
+ console.error(`error event triggered on request to ${url}`);
45
+ reject(error);
46
+ });
47
+ nodeRequest.on("response", (nodeResponse) => {
48
+ resolve(nodeResponse);
49
+ });
50
+ });
51
+ const responseBody = observableFromNodeStream(nodeResponse);
52
+ // ideally we would not wait for the response to return a response object
53
+ // for now I can't make node.fetch + Response + all things work together here
54
+ // and this util is not used in production so it's good enough for now
55
+ const responseBodyBuffer = await new Promise((resolve, reject) => {
56
+ const bufferArray = [];
57
+ responseBody.subscribe(
58
+ {
59
+ next: (data) => {
60
+ bufferArray.push(data);
61
+ },
62
+ error: (value) => {
63
+ reject(value);
64
+ },
65
+ complete: () => {
66
+ resolve(Buffer.concat(bufferArray));
67
+ },
68
+ },
69
+ { signal },
70
+ );
71
+ });
72
+
73
+ return {
74
+ url,
75
+ status: nodeResponse.statusCode,
76
+ statusText: nodeResponse.statusMessage,
77
+ headers: new Map(Object.entries(nodeResponse.headers)),
78
+ body: responseBodyBuffer,
79
+ arrayBuffer: async () => {
80
+ return responseBodyBuffer;
81
+ },
82
+ text: async () => {
83
+ const responseBodyString = responseBodyBuffer.toString();
84
+ return responseBodyString;
85
+ },
86
+ json: async () => {
87
+ const responseBodyString = responseBodyBuffer.toString();
88
+ const responseBodyJSON = JSON.parse(responseBodyString);
89
+ return responseBodyJSON;
90
+ },
91
+ };
92
+ };