From c6daf369e3f68ffb76bbc9d3bd4aa2ecffa3d1a6 Mon Sep 17 00:00:00 2001 From: Kwaroran Date: Wed, 19 Feb 2025 16:40:21 +0900 Subject: [PATCH] Add Userscript proxy --- src/ts/globalApi.svelte.ts | 69 ++++++++++++++++++------------------- src/vite-env.d.ts | 3 +- util/risuUserscript.user.js | 11 ++++++ 3 files changed, 46 insertions(+), 37 deletions(-) create mode 100644 util/risuUserscript.user.js diff --git a/src/ts/globalApi.svelte.ts b/src/ts/globalApi.svelte.ts index 6e5b1aae..a0a3104c 100644 --- a/src/ts/globalApi.svelte.ts +++ b/src/ts/globalApi.svelte.ts @@ -815,10 +815,13 @@ export async function globalFetch(url: string, arg: GlobalFetchArgs = {}): Promi return { ok: false, headers: {}, data: 'You are trying local request on web version. This is not allowed due to browser security policy. Use the desktop version instead, or use a tunneling service like ngrok and set the CORS to allow all.' }; } - // Simplify the globalFetch function: Detach built-in functions if (forcePlainFetch) { return await fetchWithPlainFetch(url, arg); } + //userScriptFetch is provided by userscript + if(window.userScriptFetch){ + return await fetchWithUSFetch(url, arg); + } if (isTauri) { return await fetchWithTauri(url, arg); } @@ -890,6 +893,26 @@ async function fetchWithPlainFetch(url: string, arg: GlobalFetchArgs): Promise} - The result of the fetch request. + */ +async function fetchWithUSFetch(url: string, arg: GlobalFetchArgs): Promise { + try { + const headers = { 'Content-Type': 'application/json', ...arg.headers }; + const response = await userScriptFetch(url, { body: JSON.stringify(arg.body), headers, method: arg.method ?? "POST", signal: arg.abortSignal }); + const data = arg.rawResponse ? new Uint8Array(await response.arrayBuffer()) : await response.json(); + const ok = response.ok && response.status >= 200 && response.status < 300; + addFetchLogInGlobalFetch(data, ok, url, arg); + return { ok, data, headers: Object.fromEntries(response.headers) }; + } catch (error) { + return { ok: false, data: `${error}`, headers: {} }; + } + } + /** * Performs a fetch request using Tauri. * @@ -1866,40 +1889,6 @@ export async function fetchNative(url:string, arg:{ throw new Error('Body is required for POST and PUT requests') } - const jsonizer = (body:ReadableStream) => { - return async () => { - const text = await textifyReadableStream(body) - return JSON.parse(text) - } - } - const textizer = (body:ReadableStream) => { - return async () => { - const text = await textifyReadableStream(body) - return text - } - } - const arrayBufferizer = (body:ReadableStream) => { - return async () => { - const chunks:Uint8Array[] = [] - const reader = body.getReader() - while(true){ - const {done, value} = await reader.read() - if(done){ - break - } - chunks.push(value) - } - const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0) - const arrayBuffer = new Uint8Array(totalLength) - let offset = 0 - for(const chunk of chunks){ - arrayBuffer.set(chunk, offset) - offset += chunk.length - } - return arrayBuffer.buffer - } - } - arg.method = arg.method ?? 'POST' let headers = arg.headers ?? {} @@ -1932,7 +1921,15 @@ export async function fetchNative(url:string, arg:{ resType: 'stream', chatId: arg.chatId, }) - if(isTauri){ + if(window.userScriptFetch){ + return await window.userScriptFetch(url,{ + body: realBody, + headers: headers, + method: arg.method, + signal: arg.signal + }) + } + else if(isTauri){ fetchIndex++ if(arg.signal && arg.signal.aborted){ throw new Error('aborted') diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 206ed21e..42756ba0 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -3,4 +3,5 @@ declare var Buffer: BufferConstructor -declare var safeStructuredClone: (data: T) => T \ No newline at end of file +declare var safeStructuredClone: (data: T) => T +declare var userScriptFetch: (url: string,arg:RequestInit) => Promise \ No newline at end of file diff --git a/util/risuUserscript.user.js b/util/risuUserscript.user.js new file mode 100644 index 00000000..72a55165 --- /dev/null +++ b/util/risuUserscript.user.js @@ -0,0 +1,11 @@ +// ==UserScript== +// @name RisuAI Requester +// @version 1.0.0 +// @match https://risuai.xyz/* +// @grant GM.xmlHttpRequest +// @require https://cdn.jsdelivr.net/npm/@trim21/gm-fetch@0.2.3 +// @run-at document-end +// @connect * +// ==/UserScript== + +window.fetchWithUSFetch = GM_fetch \ No newline at end of file