@gjsify/fetch 0.5.1 → 0.6.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/lib/esm/index.js +1 -1
- package/lib/index.js +11 -6
- package/package.json +7 -7
package/lib/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{Blob as e,File as t}from"./utils/blob-from.js";import{FetchError as n}from"./errors/fetch-error.js";import{isDomainOrSubdomain as r,isSameProtocol as i}from"./utils/is.js";import{clone as a}from"./body.js";import o from"./headers.js";import{parseDataUri as s}from"./utils/data-uri.js";import{isRedirect as c}from"./utils/is-redirect.js";import{Response as l}from"./response.js";import{parseReferrerPolicyFromHeader as u}from"./utils/referrer.js";import{Request as d,getSoupRequestOptions as f}from"./request.js";import{AbortError as p}from"./errors/abort-error.js";import{XMLHttpRequest as m,XMLHttpRequestUpload as h}from"./xhr.js";import{URL as g}from"@gjsify/url";import _ from"node:stream";import{FormData as v}from"@gjsify/formdata";import y from"@girs/glib-2.0";const b=new Set([`data:`,`http:`,`https:`,`file:`]);function rewriteRootRelativeUrl(e){if(typeof e!=`string`||!e.startsWith(`/`)||e.startsWith(`//`))return e;let t=globalThis,n=t.__GJSIFY_DEBUG_FETCH===!0;try{let r=t.imports?.system?.programPath??t.imports?.system?.programInvocationName??``;if(!r)return e;let i=`file://${y.path_get_dirname(r)}${e}`;return n&&console.log(`[fetch] rewrite ${e} → ${i}`),i}catch(t){return n&&console.warn(`[fetch] rewrite FAILED: ${t instanceof Error?t.message:String(t)}`),e}}async function fetch(
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{Blob as e,File as t}from"./utils/blob-from.js";import{FetchError as n}from"./errors/fetch-error.js";import{isDomainOrSubdomain as r,isSameProtocol as i}from"./utils/is.js";import{clone as a}from"./body.js";import o from"./headers.js";import{parseDataUri as s}from"./utils/data-uri.js";import{isRedirect as c}from"./utils/is-redirect.js";import{Response as l}from"./response.js";import{parseReferrerPolicyFromHeader as u}from"./utils/referrer.js";import{Request as d,getSoupRequestOptions as f}from"./request.js";import{AbortError as p}from"./errors/abort-error.js";import{XMLHttpRequest as m,XMLHttpRequestUpload as h}from"./xhr.js";import{URL as g}from"@gjsify/url";import _ from"node:stream";import{FormData as v}from"@gjsify/formdata";import y from"@girs/glib-2.0";const b=new Set([`data:`,`http:`,`https:`,`file:`]);function rewriteRootRelativeUrl(e){if(typeof e!=`string`||!e.startsWith(`/`)||e.startsWith(`//`))return e;let t=globalThis,n=t.__GJSIFY_DEBUG_FETCH===!0;try{let r=t.imports?.system?.programPath??t.imports?.system?.programInvocationName??``;if(!r)return e;let i=`file://${y.path_get_dirname(r)}${e}`;return n&&console.log(`[fetch] rewrite ${e} → ${i}`),i}catch(t){return n&&console.warn(`[fetch] rewrite FAILED: ${t instanceof Error?t.message:String(t)}`),e}}async function fetch(t,m={}){t=rewriteRootRelativeUrl(t);let h=new d(t,m),{parsedURL:v,options:x}=f(h);if(!b.has(v.protocol))throw TypeError(`@gjsify/fetch cannot load ${t}. URL scheme "${v.protocol.replace(/:$/,``)}" is not supported.`);if(v.protocol===`data:`){let{buffer:e,typeFull:t}=s(h.url);return new l(Buffer.from(e),{headers:{"Content-Type":t}})}if(v.protocol===`file:`){let e=globalThis.__GJSIFY_DEBUG_FETCH===!0;e&&console.log(`[fetch] file:// ${h.url}`);try{let t=y.filename_from_uri(h.url)[0];e&&console.log(`[fetch] file:// path=${t}`);let[r,i]=y.file_get_contents(t);if(e&&console.log(`[fetch] file:// ok=${r} bytes=${i?.byteLength??`?`}`),!r)throw new n(`Failed to read file: ${t}`,`system`);let a=i,o=new Uint8Array(a.byteLength);o.set(a);let s=new l(o);return e&&console.log(`[fetch] file:// response created`),s}catch(t){let r=t instanceof Error?t:Error(String(t));throw e&&console.warn(`[fetch] file:// FAIL: ${r.message}`),new n(`request to ${h.url} failed, reason: ${r.message}`,`system`,r)}}let{signal:S}=h;if(S&&S.aborted)throw new p(`The operation was aborted.`);let C,w;try{let e=await h._send(x);C=e.readable,w=e.cancellable}catch(e){let t=e instanceof Error?e:Error(String(e));throw new n(`request to ${h.url} failed, reason: ${t.message}`,`system`,t)}let abortHandler=()=>{w.cancel()};S&&S.addEventListener(`abort`,abortHandler,{once:!0});let finalize=()=>{S&&S.removeEventListener(`abort`,abortHandler)};w.connect(()=>{C.destroy(new p(`The operation was aborted.`))}),C.on(`error`,e=>{finalize()});let T=h._message,E=o._newFromSoupMessage(T),D=T.status_code,O=T.get_reason_phrase();if(c(D)){let e=E.get(`Location`),t=null;try{t=e===null?null:new g(e,h.url)}catch{if(h.redirect!==`manual`)throw finalize(),new n(`uri requested responds with an invalid redirect URL: ${e}`,`invalid-redirect`)}switch(h.redirect){case`error`:throw finalize(),new n(`uri requested responds with a redirect, redirect mode is set to error: ${h.url}`,`no-redirect`);case`manual`:break;case`follow`:{if(t===null)break;if(h.counter>=h.follow)throw finalize(),new n(`maximum redirect reached at: ${h.url}`,`max-redirect`);let e={headers:new o(h.headers),follow:h.follow,counter:h.counter+1,agent:h.agent,compress:h.compress,method:h.method,body:a(h),signal:h.signal,size:h.size,referrer:h.referrer,referrerPolicy:h.referrerPolicy};if(!r(h.url,t)||!i(h.url,t))for(let t of[`authorization`,`www-authenticate`,`cookie`,`cookie2`])e.headers.delete(t);if(D!==303&&h.body&&m.body instanceof _.Readable)throw finalize(),new n(`Cannot follow redirect with body being a readable stream`,`unsupported-redirect`);(D===303||(D===301||D===302)&&h.method===`POST`)&&(e.method=`GET`,e.body=void 0,e.headers.delete(`content-length`));let s=u(E);return s&&(e.referrerPolicy=s),finalize(),fetch(new d(t,e))}default:throw TypeError(`Redirect option '${h.redirect}' is not a valid value of RequestRedirect`)}}let k={url:h.url,status:D,statusText:O,headers:E,size:h.size,counter:h.counter,highWaterMark:h.highWaterMark},A=E.get(`Content-Encoding`);if(!h.compress||h.method===`HEAD`||A===null||D===204||D===304)return finalize(),new l(C,k);if(typeof DecompressionStream<`u`){let t=null;if(A===`gzip`||A===`x-gzip`?t=`gzip`:(A===`deflate`||A===`x-deflate`)&&(t=`deflate`),t){let n=new e([await new l(C,k).arrayBuffer()]).stream().pipeThrough(new DecompressionStream(t));return finalize(),new l(n,k)}}return finalize(),new l(C,k)}export{p as AbortError,e as Blob,n as FetchError,t as File,v as FormData,o as Headers,d as Request,l as Response,m as XMLHttpRequest,h as XMLHttpRequestUpload,fetch as default,c as isRedirect};
|
package/lib/index.js
CHANGED
|
@@ -248,12 +248,17 @@ export default async function fetch(url, init = {}) {
|
|
|
248
248
|
format = 'deflate';
|
|
249
249
|
}
|
|
250
250
|
if (format) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
251
|
+
// Buffer the full compressed body before decompressing.
|
|
252
|
+
// Streaming pipeThrough(DecompressionStream) directly from the Soup
|
|
253
|
+
// body ReadableStream trips Gio.IOErrorEnum: G_IO_ERROR_PARTIAL_INPUT
|
|
254
|
+
// when libsoup closes the connection at a non-chunk boundary (observed
|
|
255
|
+
// on npm-CDN gzip responses). The full body is received intact — only
|
|
256
|
+
// the streaming decode is fragile. Buffer first, then decompress the
|
|
257
|
+
// complete in-memory blob — the same pattern @gjsify/tar uses for .tgz.
|
|
258
|
+
const rawBuffer = await new Response(readable, responseOptions).arrayBuffer();
|
|
259
|
+
const decompressed = new Blob([rawBuffer]).stream().pipeThrough(new DecompressionStream(format));
|
|
260
|
+
finalize();
|
|
261
|
+
return new Response(decompressed, responseOptions);
|
|
257
262
|
}
|
|
258
263
|
}
|
|
259
264
|
// Fallback: return the body as-is (no streaming decompression available)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/fetch",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Web and Node.js fetch module for Gjs",
|
|
5
5
|
"module": "lib/esm/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"fetch"
|
|
52
52
|
],
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@gjsify/cli": "^0.
|
|
55
|
-
"@gjsify/unit": "^0.
|
|
54
|
+
"@gjsify/cli": "^0.6.0",
|
|
55
|
+
"@gjsify/unit": "^0.6.0",
|
|
56
56
|
"@types/node": "^25.9.2",
|
|
57
57
|
"typescript": "^6.0.3"
|
|
58
58
|
},
|
|
@@ -61,10 +61,10 @@
|
|
|
61
61
|
"@girs/gjs": "4.0.4",
|
|
62
62
|
"@girs/glib-2.0": "2.88.0-4.0.4",
|
|
63
63
|
"@girs/soup-3.0": "3.6.6-4.0.4",
|
|
64
|
-
"@gjsify/formdata": "^0.
|
|
65
|
-
"@gjsify/http": "^0.
|
|
66
|
-
"@gjsify/url": "^0.
|
|
67
|
-
"@gjsify/utils": "^0.
|
|
64
|
+
"@gjsify/formdata": "^0.6.0",
|
|
65
|
+
"@gjsify/http": "^0.6.0",
|
|
66
|
+
"@gjsify/url": "^0.6.0",
|
|
67
|
+
"@gjsify/utils": "^0.6.0"
|
|
68
68
|
},
|
|
69
69
|
"gjsify": {
|
|
70
70
|
"runtimes": {
|