diff --git a/apps/desktop/global.d.ts b/apps/desktop/global.d.ts
index 12bc240d1..ed9a11a10 100644
--- a/apps/desktop/global.d.ts
+++ b/apps/desktop/global.d.ts
@@ -19,9 +19,40 @@ along with this program. If not, see .
/* eslint-disable no-var */
import { BrowserWindow } from "electron";
+import {
+ type FormData as FormDataType,
+ type Headers as HeadersType,
+ type Request as RequestType,
+ type Response as ResponseType
+} from "undici";
declare global {
var window: BrowserWindow | null;
var RELEASE: boolean;
var MAC_APP_STORE: boolean;
+
+ // Re-export undici fetch function and various classes to global scope.
+ // These are classes and functions expected to be at global scope according to Node.js v18 API
+ // documentation.
+ // See: https://nodejs.org/dist/latest-v18.x/docs/api/globals.html
+ // eslint-disable-next-line no-var
+ export var {
+ FormData,
+ Headers,
+ Request,
+ Response,
+ fetch
+ }: typeof import("undici");
+
+ type FormData = FormDataType;
+ type Headers = HeadersType;
+ type Request = RequestType;
+ type Response = ResponseType;
}
+
+// NOTE: the import in the global block above needs to be a var for this to work properly.
+globalThis.fetch = fetch;
+globalThis.FormData = FormData;
+globalThis.Headers = Headers;
+globalThis.Request = Request;
+globalThis.Response = Response;
diff --git a/apps/desktop/src/utils/protocol.ts b/apps/desktop/src/utils/protocol.ts
index b95393e16..b4ca93326 100644
--- a/apps/desktop/src/utils/protocol.ts
+++ b/apps/desktop/src/utils/protocol.ts
@@ -17,16 +17,14 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import { protocol, ProtocolRequest } from "electron";
+import { protocol, net } from "electron";
import { isDevelopment } from "./index";
import { createReadStream } from "fs";
import { extname, normalize } from "path";
import { URL } from "url";
-import fetch, { Response } from "node-fetch";
const BASE_PATH = isDevelopment() ? "../public" : "";
const HOSTNAME = `app.notesnook.com`;
-const FILE_NOT_FOUND = -6;
const SCHEME = "https";
const extensionToMimeType: Record = {
html: "text/html",
@@ -34,101 +32,47 @@ const extensionToMimeType: Record = {
js: "application/javascript",
css: "text/css",
svg: "image/svg+xml",
- png: "image/png"
+ png: "image/png",
+ jpg: "image/jpg",
+ ttf: "font/ttf",
+ woff: "font/woff",
+ woff2: "font/woff2"
};
function registerProtocol() {
- const protocolInterceptionResult = protocol.interceptStreamProtocol(
- SCHEME,
- async (request, callback) => {
- const url = new URL(request.url);
- if (shouldInterceptRequest(url)) {
- console.info("Intercepting request:", request.url);
-
- const loadIndex = !extname(url.pathname);
- const filePath = normalize(
- `${__dirname}${
- loadIndex
- ? `${BASE_PATH}/index.html`
- : `${BASE_PATH}/${url.pathname}`
- }`
- );
- if (!filePath) {
- console.error("Local asset file not found at", filePath);
- callback({ error: FILE_NOT_FOUND });
- return;
- }
- const fileExtension = extname(filePath).replace(".", "");
-
- const data = createReadStream(filePath);
- callback({
- data,
- mimeType: extensionToMimeType[fileExtension]
- });
- } else {
- let response: Response;
- try {
- const body = await getBody(request);
- response = await fetch(request.url, {
- ...request,
- body,
- headers: {
- ...request.headers
- // origin: `${PROTOCOL}://${HOSTNAME}/`
- },
- referrer: request.referrer,
- redirect: "manual"
- });
- } catch (e) {
- console.error(e);
- console.error(`Error sending request to `, request.url, "Error: ", e);
- callback({ statusCode: 400 });
- return;
- }
- callback({
- statusCode: response.status,
- data: response.body || undefined,
- headers: Object.fromEntries(response.headers.entries()),
- mimeType: response.headers.get("Content-Type") || undefined
+ protocol.handle(SCHEME, async (request) => {
+ const url = new URL(request.url);
+ if (shouldInterceptRequest(url)) {
+ console.info("Intercepting request:", request.url);
+ const loadIndex = !extname(url.pathname);
+ const filePath = normalize(
+ `${__dirname}${
+ loadIndex ? `${BASE_PATH}/index.html` : `${BASE_PATH}/${url.pathname}`
+ }`
+ );
+ if (!filePath) {
+ console.error("Local asset file not found at", filePath);
+ return new Response(undefined, {
+ status: 404,
+ statusText: "FILE_NOT_FOUND"
});
}
+ const fileExtension = extname(filePath).replace(".", "");
+ return new Response(createReadStream(filePath), {
+ headers: { "Content-Type": extensionToMimeType[fileExtension] }
+ });
+ } else {
+ try {
+ return net.fetch(request, {
+ bypassCustomProtocolHandlers: true
+ });
+ } catch (e) {
+ console.error(e);
+ }
+ return Response.error();
}
- );
-
- console.info(
- `${SCHEME} protocol inteception ${
- protocolInterceptionResult ? "successful" : "failed"
- }.`
- );
-
- // protocol.handle(SCHEME, (request) => {
- // const url = new URL(request.url);
- // if (shouldInterceptRequest(url)) {
- // console.info("Intercepting request:", request.url);
- // const loadIndex = !extname(url.pathname);
- // const absoluteFilePath = normalize(
- // `${__dirname}${
- // loadIndex ? `${BASE_PATH}/index.html` : `${BASE_PATH}/${url.pathname}`
- // }`
- // );
- // const filePath = getPath(absoluteFilePath);
- // if (!filePath) {
- // console.error("Local asset file not found at", filePath);
- // return new Response(undefined, {
- // status: 404,
- // statusText: "FILE_NOT_FOUND"
- // });
- // }
- // const fileExtension = extname(filePath).replace(".", "");
- // const data = createReadStream(filePath);
- // return new Response(data, {
- // headers: { "Content-Type": extensionToMimeType[fileExtension] }
- // });
- // } else {
- // return net.fetch(request);
- // }
- // });
- // console.info(`${SCHEME} protocol inteception "successful"`);
+ });
+ console.info(`${SCHEME} protocol inteception "successful"`);
}
const bypassedRoutes: string[] = [];
@@ -139,22 +83,3 @@ function shouldInterceptRequest(url: URL) {
const PROTOCOL_URL = `${SCHEME}://${HOSTNAME}/`;
export { registerProtocol, PROTOCOL_URL };
-
-async function getBody(request: ProtocolRequest) {
- const session = globalThis?.window?.webContents?.session;
-
- const blobParts = [];
- if (!request.uploadData || !request.uploadData.length) return null;
- for (const data of request.uploadData) {
- if (data.bytes) {
- blobParts.push(new Uint8Array(data.bytes));
- } else if (session && data.blobUUID) {
- const buffer = await session.getBlobData(data.blobUUID);
- if (!buffer) continue;
- blobParts.push(new Uint8Array(buffer));
- }
- }
- const blob = new Blob(blobParts);
- return blob;
-}
-