Add Prettier and ESLint tooling (Refs #77)

This commit is contained in:
2026-10-09 15:56:13 -04:00
parent 8ed059b8d3
commit 16469e2d43
711 changed files with 99737 additions and 28286 deletions
+26 -8
View File
@@ -1,5 +1,12 @@
export interface SelectedGameFile { path: string; file: File }
export interface SelectedGameFolder { name: string; files: SelectedGameFile[]; size: number }
export interface SelectedGameFile {
path: string;
file: File;
}
export interface SelectedGameFolder {
name: string;
files: SelectedGameFile[];
size: number;
}
/** Directory inputs include the selected folder in every relative path. Remove
* that one component and retain the complete game directory below it. */
@@ -10,29 +17,40 @@ export function selectGameFolder(selection: Iterable<File>): SelectedGameFolder
let size = 0;
for (const file of selection) {
const [root, ...parts] = file.webkitRelativePath.split('/');
if (!root || root === '.' || root === '..' || !parts.length || name && root !== name) throw new Error('Choose one game folder with the folder picker.');
if (!root || root === '.' || root === '..' || !parts.length || (name && root !== name))
throw new Error('Choose one game folder with the folder picker.');
name = root;
const path = parts.join('/');
if (path.length > 1024 || /[\\\x00-\x1f\x7f:]/.test(path) || parts.some(part => !part || part === '.' || part === '..' || /[. ]$/.test(part))) {
if (
path.length > 1024 ||
// eslint-disable-next-line no-control-regex -- Game paths must reject control characters.
/[\\\x00-\x1f\x7f:]/.test(path) ||
parts.some((part) => !part || part === '.' || part === '..' || /[. ]$/.test(part))
) {
throw new Error(`This file has an unsupported game path: ${file.webkitRelativePath}`);
}
const key = path.toLowerCase();
if (paths.has(key)) throw new Error(`This folder has duplicate game paths: ${path}`);
paths.add(key);
size += file.size;
if (!Number.isSafeInteger(size)) throw new Error('This folder exceeds the supported upload size.');
if (!Number.isSafeInteger(size))
throw new Error('This folder exceeds the supported upload size.');
files.push({ path, file });
if (files.length > 200_000) throw new Error('Choose a folder with no more than 200,000 files.');
if (files.length > 200_000)
throw new Error('Choose a folder with no more than 200,000 files.');
}
if (!files.length) throw new Error('The selected folder contains no files.');
for (const { path } of files) {
const parents = path.toLowerCase().split('/');
parents.pop();
while (parents.length) {
if (paths.has(parents.join('/'))) throw new Error(`This folder uses the same game path for a file and a directory: ${path}`);
if (paths.has(parents.join('/')))
throw new Error(
`This folder uses the same game path for a file and a directory: ${path}`
);
parents.pop();
}
}
files.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
files.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
return { name, files, size };
}