@gjsify/fetch 0.3.13 → 0.3.14

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.
@@ -1,148 +1,157 @@
1
- import GLib from "@girs/glib-2.0";
2
- import Gio from "@girs/gio-2.0";
3
- import Headers from "./headers.js";
4
1
  import Body, { clone, extractContentType } from "./body.js";
2
+ import Headers from "./headers.js";
5
3
  import { isRedirect } from "./utils/is-redirect.js";
6
4
  import { URL } from "@gjsify/url";
7
- const INTERNALS = /* @__PURE__ */ Symbol("Response internals");
8
- class Response extends Body {
9
- [INTERNALS];
10
- _inputStream = null;
11
- constructor(body = null, options = {}) {
12
- super(body, options);
13
- const status = options.status != null ? options.status : 200;
14
- const headers = new Headers(options.headers);
15
- if (body !== null && !headers.has("Content-Type")) {
16
- const contentType = extractContentType(body, this);
17
- if (contentType) {
18
- headers.append("Content-Type", contentType);
19
- }
20
- }
21
- this[INTERNALS] = {
22
- type: "default",
23
- url: options.url,
24
- status,
25
- statusText: options.statusText || "",
26
- headers,
27
- counter: options.counter,
28
- highWaterMark: options.highWaterMark
29
- };
30
- }
31
- get type() {
32
- return this[INTERNALS].type;
33
- }
34
- get url() {
35
- return this[INTERNALS].url || "";
36
- }
37
- get status() {
38
- return this[INTERNALS].status;
39
- }
40
- /**
41
- * Convenience property representing if the request ended normally
42
- */
43
- get ok() {
44
- return this[INTERNALS].status >= 200 && this[INTERNALS].status < 300;
45
- }
46
- get redirected() {
47
- return this[INTERNALS].counter > 0;
48
- }
49
- get statusText() {
50
- return this[INTERNALS].statusText;
51
- }
52
- get headers() {
53
- return this[INTERNALS].headers;
54
- }
55
- get highWaterMark() {
56
- return this[INTERNALS].highWaterMark;
57
- }
58
- /**
59
- * Clone this response
60
- *
61
- * @return Response
62
- */
63
- clone() {
64
- return new Response(clone(this, this.highWaterMark), {
65
- type: this.type,
66
- url: this.url,
67
- status: this.status,
68
- statusText: this.statusText,
69
- headers: this.headers,
70
- ok: this.ok,
71
- redirected: this.redirected,
72
- size: this.size,
73
- highWaterMark: this.highWaterMark
74
- });
75
- }
76
- /**
77
- * @param url The URL that the new response is to originate from.
78
- * @param status An optional status code for the response (e.g., 302.)
79
- * @returns A Response object.
80
- */
81
- static redirect(url, status = 302) {
82
- if (!isRedirect(status)) {
83
- throw new RangeError('Failed to execute "redirect" on "response": Invalid status code');
84
- }
85
- return new Response(null, {
86
- headers: {
87
- location: new URL(url).toString()
88
- },
89
- status
90
- });
91
- }
92
- static error() {
93
- const response = new Response(null, { status: 0, statusText: "" });
94
- response[INTERNALS].type = "error";
95
- return response;
96
- }
97
- /**
98
- * Create a Response with a JSON body.
99
- * @param data The data to serialize as JSON.
100
- * @param init Optional response init options.
101
- * @returns A Response with the JSON body and appropriate content-type header.
102
- */
103
- static json(data, init) {
104
- const body = JSON.stringify(data);
105
- const options = { ...init };
106
- const headers = new Headers(options.headers);
107
- if (!headers.has("content-type")) {
108
- headers.set("content-type", "application/json");
109
- }
110
- options.headers = headers;
111
- return new Response(body, options);
112
- }
113
- get [Symbol.toStringTag]() {
114
- return "Response";
115
- }
116
- async text() {
117
- if (!this._inputStream) {
118
- return super.text();
119
- }
120
- const outputStream = Gio.MemoryOutputStream.new_resizable();
121
- await new Promise((resolve, reject) => {
122
- outputStream.splice_async(this._inputStream, Gio.OutputStreamSpliceFlags.CLOSE_TARGET | Gio.OutputStreamSpliceFlags.CLOSE_SOURCE, GLib.PRIORITY_DEFAULT, null, (_self, res) => {
123
- try {
124
- resolve(outputStream.splice_finish(res));
125
- } catch (error) {
126
- reject(error);
127
- }
128
- });
129
- });
130
- const bytes = outputStream.steal_as_bytes();
131
- return new TextDecoder().decode(bytes.toArray());
132
- }
133
- }
5
+ import GLib from "@girs/glib-2.0";
6
+ import Gio from "@girs/gio-2.0";
7
+
8
+ //#region src/response.ts
9
+ const INTERNALS = Symbol("Response internals");
10
+ /**
11
+ * Response class
12
+ *
13
+ * Ref: https://fetch.spec.whatwg.org/#response-class
14
+ *
15
+ * @param body Readable stream
16
+ * @param opts Response options
17
+ */
18
+ var Response = class Response extends Body {
19
+ [INTERNALS];
20
+ _inputStream = null;
21
+ constructor(body = null, options = {}) {
22
+ super(body, options);
23
+ const status = options.status != null ? options.status : 200;
24
+ const headers = new Headers(options.headers);
25
+ if (body !== null && !headers.has("Content-Type")) {
26
+ const contentType = extractContentType(body, this);
27
+ if (contentType) {
28
+ headers.append("Content-Type", contentType);
29
+ }
30
+ }
31
+ this[INTERNALS] = {
32
+ type: "default",
33
+ url: options.url,
34
+ status,
35
+ statusText: options.statusText || "",
36
+ headers,
37
+ counter: options.counter,
38
+ highWaterMark: options.highWaterMark
39
+ };
40
+ }
41
+ get type() {
42
+ return this[INTERNALS].type;
43
+ }
44
+ get url() {
45
+ return this[INTERNALS].url || "";
46
+ }
47
+ get status() {
48
+ return this[INTERNALS].status;
49
+ }
50
+ /**
51
+ * Convenience property representing if the request ended normally
52
+ */
53
+ get ok() {
54
+ return this[INTERNALS].status >= 200 && this[INTERNALS].status < 300;
55
+ }
56
+ get redirected() {
57
+ return this[INTERNALS].counter > 0;
58
+ }
59
+ get statusText() {
60
+ return this[INTERNALS].statusText;
61
+ }
62
+ get headers() {
63
+ return this[INTERNALS].headers;
64
+ }
65
+ get highWaterMark() {
66
+ return this[INTERNALS].highWaterMark;
67
+ }
68
+ /**
69
+ * Clone this response
70
+ *
71
+ * @return Response
72
+ */
73
+ clone() {
74
+ return new Response(clone(this, this.highWaterMark), {
75
+ type: this.type,
76
+ url: this.url,
77
+ status: this.status,
78
+ statusText: this.statusText,
79
+ headers: this.headers,
80
+ ok: this.ok,
81
+ redirected: this.redirected,
82
+ size: this.size,
83
+ highWaterMark: this.highWaterMark
84
+ });
85
+ }
86
+ /**
87
+ * @param url The URL that the new response is to originate from.
88
+ * @param status An optional status code for the response (e.g., 302.)
89
+ * @returns A Response object.
90
+ */
91
+ static redirect(url, status = 302) {
92
+ if (!isRedirect(status)) {
93
+ throw new RangeError("Failed to execute \"redirect\" on \"response\": Invalid status code");
94
+ }
95
+ return new Response(null, {
96
+ headers: { location: new URL(url).toString() },
97
+ status
98
+ });
99
+ }
100
+ static error() {
101
+ const response = new Response(null, {
102
+ status: 0,
103
+ statusText: ""
104
+ });
105
+ response[INTERNALS].type = "error";
106
+ return response;
107
+ }
108
+ /**
109
+ * Create a Response with a JSON body.
110
+ * @param data The data to serialize as JSON.
111
+ * @param init Optional response init options.
112
+ * @returns A Response with the JSON body and appropriate content-type header.
113
+ */
114
+ static json(data, init) {
115
+ const body = JSON.stringify(data);
116
+ const options = { ...init };
117
+ const headers = new Headers(options.headers);
118
+ if (!headers.has("content-type")) {
119
+ headers.set("content-type", "application/json");
120
+ }
121
+ options.headers = headers;
122
+ return new Response(body, options);
123
+ }
124
+ get [Symbol.toStringTag]() {
125
+ return "Response";
126
+ }
127
+ async text() {
128
+ if (!this._inputStream) {
129
+ return super.text();
130
+ }
131
+ const outputStream = Gio.MemoryOutputStream.new_resizable();
132
+ await new Promise((resolve, reject) => {
133
+ outputStream.splice_async(this._inputStream, Gio.OutputStreamSpliceFlags.CLOSE_TARGET | Gio.OutputStreamSpliceFlags.CLOSE_SOURCE, GLib.PRIORITY_DEFAULT, null, (_self, res) => {
134
+ try {
135
+ resolve(outputStream.splice_finish(res));
136
+ } catch (error) {
137
+ reject(error);
138
+ }
139
+ });
140
+ });
141
+ const bytes = outputStream.steal_as_bytes();
142
+ return new TextDecoder().decode(bytes.toArray());
143
+ }
144
+ };
134
145
  Object.defineProperties(Response.prototype, {
135
- type: { enumerable: true },
136
- url: { enumerable: true },
137
- status: { enumerable: true },
138
- ok: { enumerable: true },
139
- redirected: { enumerable: true },
140
- statusText: { enumerable: true },
141
- headers: { enumerable: true },
142
- clone: { enumerable: true }
146
+ type: { enumerable: true },
147
+ url: { enumerable: true },
148
+ status: { enumerable: true },
149
+ ok: { enumerable: true },
150
+ redirected: { enumerable: true },
151
+ statusText: { enumerable: true },
152
+ headers: { enumerable: true },
153
+ clone: { enumerable: true }
143
154
  });
144
- var response_default = Response;
145
- export {
146
- Response,
147
- response_default as default
148
- };
155
+
156
+ //#endregion
157
+ export { Response, Response as default };
@@ -1 +1 @@
1
- export * from "./system-error.js";
1
+ import "./system-error.js";
@@ -1 +1,4 @@
1
+ //#region src/types/system-error.ts
1
2
  ;
3
+
4
+ //#endregion
@@ -1,5 +1,3 @@
1
1
  import { Blob, File } from "node:buffer";
2
- export {
3
- Blob,
4
- File
5
- };
2
+
3
+ export { Blob, File };
@@ -1,23 +1,33 @@
1
+ //#region src/utils/data-uri.ts
2
+ /**
3
+ * Parse a data: URI into its components.
4
+ * Replaces the `data-uri-to-buffer` npm package.
5
+ *
6
+ * Format: data:[<mediatype>][;base64],<data>
7
+ */
1
8
  function parseDataUri(uri) {
2
- const match = uri.match(/^data:([^,]*?)(;base64)?,(.*)$/s);
3
- if (!match) {
4
- throw new TypeError(`Invalid data URI: ${uri.slice(0, 50)}...`);
5
- }
6
- const typeFull = match[1] || "text/plain;charset=US-ASCII";
7
- const isBase64 = !!match[2];
8
- const data = match[3];
9
- let buffer;
10
- if (isBase64) {
11
- const binaryString = atob(data);
12
- buffer = new Uint8Array(binaryString.length);
13
- for (let i = 0; i < binaryString.length; i++) {
14
- buffer[i] = binaryString.charCodeAt(i);
15
- }
16
- } else {
17
- buffer = new TextEncoder().encode(decodeURIComponent(data));
18
- }
19
- return { buffer, typeFull };
9
+ const match = uri.match(/^data:([^,]*?)(;base64)?,(.*)$/s);
10
+ if (!match) {
11
+ throw new TypeError(`Invalid data URI: ${uri.slice(0, 50)}...`);
12
+ }
13
+ const typeFull = match[1] || "text/plain;charset=US-ASCII";
14
+ const isBase64 = !!match[2];
15
+ const data = match[3];
16
+ let buffer;
17
+ if (isBase64) {
18
+ const binaryString = atob(data);
19
+ buffer = new Uint8Array(binaryString.length);
20
+ for (let i = 0; i < binaryString.length; i++) {
21
+ buffer[i] = binaryString.charCodeAt(i);
22
+ }
23
+ } else {
24
+ buffer = new TextEncoder().encode(decodeURIComponent(data));
25
+ }
26
+ return {
27
+ buffer,
28
+ typeFull
29
+ };
20
30
  }
21
- export {
22
- parseDataUri
23
- };
31
+
32
+ //#endregion
33
+ export { parseDataUri };
@@ -1,11 +1,12 @@
1
+ //#region src/utils/get-search.ts
1
2
  const getSearch = (parsedURL) => {
2
- if (parsedURL.search) {
3
- return parsedURL.search;
4
- }
5
- const lastOffset = parsedURL.href.length - 1;
6
- const hash = parsedURL.hash || (parsedURL.href[lastOffset] === "#" ? "#" : "");
7
- return parsedURL.href[lastOffset - hash.length] === "?" ? "?" : "";
8
- };
9
- export {
10
- getSearch
3
+ if (parsedURL.search) {
4
+ return parsedURL.search;
5
+ }
6
+ const lastOffset = parsedURL.href.length - 1;
7
+ const hash = parsedURL.hash || (parsedURL.href[lastOffset] === "#" ? "#" : "");
8
+ return parsedURL.href[lastOffset - hash.length] === "?" ? "?" : "";
11
9
  };
10
+
11
+ //#endregion
12
+ export { getSearch };
@@ -1,7 +1,20 @@
1
- const redirectStatus = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
1
+ //#region src/utils/is-redirect.ts
2
+ const redirectStatus = new Set([
3
+ 301,
4
+ 302,
5
+ 303,
6
+ 307,
7
+ 308
8
+ ]);
9
+ /**
10
+ * Redirect code matching
11
+ *
12
+ * @param {number} code - Status code
13
+ * @return {boolean}
14
+ */
2
15
  const isRedirect = (code) => {
3
- return redirectStatus.has(code);
4
- };
5
- export {
6
- isRedirect
16
+ return redirectStatus.has(code);
7
17
  };
18
+
19
+ //#endregion
20
+ export { isRedirect };
@@ -1,32 +1,64 @@
1
1
  import { URL } from "@gjsify/url";
2
+
3
+ //#region src/utils/is.ts
4
+ /**
5
+ * Is.js
6
+ *
7
+ * Object type checks.
8
+ */
2
9
  const NAME = Symbol.toStringTag;
10
+ /**
11
+ * Check if `obj` is a URLSearchParams object
12
+ * ref: https://github.com/node-fetch/node-fetch/issues/296#issuecomment-307598143
13
+ * @param {*} object - Object to check for
14
+ * @return {boolean}
15
+ */
3
16
  const isURLSearchParameters = (object) => {
4
- return typeof object === "object" && typeof object.append === "function" && typeof object.delete === "function" && typeof object.get === "function" && typeof object.getAll === "function" && typeof object.has === "function" && typeof object.set === "function" && typeof object.sort === "function" && object[NAME] === "URLSearchParams";
17
+ return typeof object === "object" && typeof object.append === "function" && typeof object.delete === "function" && typeof object.get === "function" && typeof object.getAll === "function" && typeof object.has === "function" && typeof object.set === "function" && typeof object.sort === "function" && object[NAME] === "URLSearchParams";
5
18
  };
19
+ /**
20
+ * Check if `object` is a W3C `Blob` object (which `File` inherits from)
21
+ * @param object Object to check for
22
+ */
6
23
  const isBlob = (value) => {
7
- if (!value || typeof value !== "object") return false;
8
- const obj = value;
9
- return typeof obj.arrayBuffer === "function" && typeof obj.type === "string" && typeof obj.stream === "function" && typeof obj.constructor === "function" && /^(Blob|File)$/.test(obj[NAME]);
24
+ if (!value || typeof value !== "object") return false;
25
+ const obj = value;
26
+ return typeof obj.arrayBuffer === "function" && typeof obj.type === "string" && typeof obj.stream === "function" && typeof obj.constructor === "function" && /^(Blob|File)$/.test(obj[NAME]);
10
27
  };
28
+ /**
29
+ * Check if `obj` is an instance of AbortSignal.
30
+ * @param object - Object to check for
31
+ */
11
32
  const isAbortSignal = (object) => {
12
- if (typeof object !== "object" || object === null) return false;
13
- const obj = object;
14
- return obj[NAME] === "AbortSignal" || obj[NAME] === "EventTarget";
33
+ if (typeof object !== "object" || object === null) return false;
34
+ const obj = object;
35
+ return obj[NAME] === "AbortSignal" || obj[NAME] === "EventTarget";
15
36
  };
37
+ /**
38
+ * isDomainOrSubdomain reports whether sub is a subdomain (or exact match) of
39
+ * the parent domain.
40
+ *
41
+ * Both domains must already be in canonical form.
42
+ * @param {string|URL} original
43
+ * @param {string|URL} destination
44
+ */
16
45
  const isDomainOrSubdomain = (destination, original) => {
17
- const orig = new URL(original).hostname;
18
- const dest = new URL(destination).hostname;
19
- return orig === dest || orig.endsWith(`.${dest}`);
46
+ const orig = new URL(original).hostname;
47
+ const dest = new URL(destination).hostname;
48
+ return orig === dest || orig.endsWith(`.${dest}`);
20
49
  };
50
+ /**
51
+ * isSameProtocol reports whether the two provided URLs use the same protocol.
52
+ *
53
+ * Both domains must already be in canonical form.
54
+ * @param {string|URL} original
55
+ * @param {string|URL} destination
56
+ */
21
57
  const isSameProtocol = (destination, original) => {
22
- const orig = new URL(original).protocol;
23
- const dest = new URL(destination).protocol;
24
- return orig === dest;
25
- };
26
- export {
27
- isAbortSignal,
28
- isBlob,
29
- isDomainOrSubdomain,
30
- isSameProtocol,
31
- isURLSearchParameters
58
+ const orig = new URL(original).protocol;
59
+ const dest = new URL(destination).protocol;
60
+ return orig === dest;
32
61
  };
62
+
63
+ //#endregion
64
+ export { isAbortSignal, isBlob, isDomainOrSubdomain, isSameProtocol, isURLSearchParameters };