NeahNew/node_modules/electron-serve/index.js
2025-05-06 22:43:27 +02:00

88 lines
2.2 KiB
JavaScript

import fs from 'node:fs/promises';
import path from 'node:path';
import electron from 'electron';
// See https://cs.chromium.org/chromium/src/net/base/net_error_list.h
const FILE_NOT_FOUND = -6;
const getPath = async (path_, file) => {
try {
const result = await fs.stat(path_);
if (result.isFile()) {
return path_;
}
if (result.isDirectory()) {
return getPath(path.join(path_, `${file}.html`));
}
} catch {}
};
export default function electronServe(options) {
options = {
isCorsEnabled: true,
scheme: 'app',
hostname: '-',
file: 'index',
...options,
};
if (!options.directory) {
throw new Error('The `directory` option is required');
}
options.directory = path.resolve(electron.app.getAppPath(), options.directory);
const handler = async (request, callback) => {
const indexPath = path.join(options.directory, `${options.file}.html`);
const filePath = path.join(options.directory, decodeURIComponent(new URL(request.url).pathname));
const relativePath = path.relative(options.directory, filePath);
const isSafe = !relativePath.startsWith('..') && !path.isAbsolute(relativePath);
if (!isSafe) {
callback({error: FILE_NOT_FOUND});
return;
}
const finalPath = await getPath(filePath, options.file);
const fileExtension = path.extname(filePath);
if (!finalPath && fileExtension && fileExtension !== '.html' && fileExtension !== '.asar') {
callback({error: FILE_NOT_FOUND});
return;
}
callback({
path: finalPath || indexPath,
});
};
electron.protocol.registerSchemesAsPrivileged([
{
scheme: options.scheme,
privileges: {
standard: true,
secure: true,
allowServiceWorkers: true,
supportFetchAPI: true,
corsEnabled: options.isCorsEnabled,
},
},
]);
electron.app.on('ready', () => {
const session = options.partition
? electron.session.fromPartition(options.partition)
: electron.session.defaultSession;
session.protocol.registerFileProtocol(options.scheme, handler);
});
return async (window_, searchParameters) => {
const queryString = searchParameters ? '?' + new URLSearchParams(searchParameters).toString() : '';
await window_.loadURL(`${options.scheme}://${options.hostname}${queryString}`);
};
}