From 4f6bcb081ffeca6615cb91f537f2b841b1753584 Mon Sep 17 00:00:00 2001 From: DecDuck Date: Tue, 12 Aug 2025 10:36:49 +1000 Subject: [PATCH 1/5] fix: #181 --- server/internal/library/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/internal/library/index.ts b/server/internal/library/index.ts index 56bed15b..3ce164fc 100644 --- a/server/internal/library/index.ts +++ b/server/internal/library/index.ts @@ -177,7 +177,7 @@ class LibraryManager { for (const filename of files) { const basename = path.basename(filename); const dotLocation = filename.lastIndexOf("."); - const ext = dotLocation == -1 ? "" : filename.slice(dotLocation); + const ext = dotLocation == -1 ? "" : filename.slice(dotLocation).toLowerCase(); for (const [platform, checkExts] of Object.entries(fileExts)) { for (const checkExt of checkExts) { if (checkExt != ext) continue; From 20462679c817ce310b5602cf88de3fcf8a2dcfc7 Mon Sep 17 00:00:00 2001 From: DecDuck Date: Fri, 15 Aug 2025 11:52:06 +1000 Subject: [PATCH 2/5] fix: use taskHandler as source of truth for imports --- package.json | 2 +- .../migration.sql | 15 ++ prisma/models/task.prisma | 4 +- server/api/v2/client/chunk.post.ts | 1 + server/internal/library/index.ts | 97 ++------ .../internal/library/providers/filesystem.ts | 42 ++-- server/internal/library/providers/flat.ts | 13 +- server/internal/metadata/index.ts | 9 +- server/internal/tasks/index.ts | 14 +- yarn.lock | 226 +++++++++++++----- 10 files changed, 245 insertions(+), 178 deletions(-) create mode 100644 prisma/migrations/20250815014713_use_task_id_started_composite_id/migration.sql diff --git a/package.json b/package.json index 4f846929..cdc8652b 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "dependencies": { "@discordapp/twemoji": "^16.0.1", - "@drop-oss/droplet": "1.6.0", + "@drop-oss/droplet": "2.0.2", "@headlessui/vue": "^1.7.23", "@heroicons/vue": "^2.1.5", "@lobomfz/prismark": "0.0.3", diff --git a/prisma/migrations/20250815014713_use_task_id_started_composite_id/migration.sql b/prisma/migrations/20250815014713_use_task_id_started_composite_id/migration.sql new file mode 100644 index 00000000..7f096a14 --- /dev/null +++ b/prisma/migrations/20250815014713_use_task_id_started_composite_id/migration.sql @@ -0,0 +1,15 @@ +/* + Warnings: + + - The primary key for the `Task` table will be changed. If it partially fails, the table could be left without primary key constraint. + +*/ +-- DropIndex +DROP INDEX "GameTag_name_idx"; + +-- AlterTable +ALTER TABLE "Task" DROP CONSTRAINT "Task_pkey", +ADD CONSTRAINT "Task_pkey" PRIMARY KEY ("id", "started"); + +-- CreateIndex +CREATE INDEX "GameTag_name_idx" ON "GameTag" USING GIST ("name" gist_trgm_ops(siglen=32)); diff --git a/prisma/models/task.prisma b/prisma/models/task.prisma index 6d3aed19..9edac6f7 100644 --- a/prisma/models/task.prisma +++ b/prisma/models/task.prisma @@ -1,5 +1,5 @@ model Task { - id String @id + id String taskGroup String name String @@ -12,4 +12,6 @@ model Task { log String[] acls String[] + + @@id([id, started]) } diff --git a/server/api/v2/client/chunk.post.ts b/server/api/v2/client/chunk.post.ts index af67c07e..a1658504 100644 --- a/server/api/v2/client/chunk.post.ts +++ b/server/api/v2/client/chunk.post.ts @@ -58,6 +58,7 @@ export default defineEventHandler(async (h3) => { statusCode: 500, statusMessage: "Failed to create read stream", }); + console.log(`sending stream for ${file.filename} for ${body.context}`); await gameReadStream.pipeTo( new WritableStream({ write(chunk) { diff --git a/server/internal/library/index.ts b/server/internal/library/index.ts index 3ce164fc..b26f6df0 100644 --- a/server/internal/library/index.ts +++ b/server/internal/library/index.ts @@ -15,12 +15,17 @@ import { GameNotFoundError, type LibraryProvider } from "./provider"; import { logger } from "../logging"; import type { GameModel } from "~/prisma/client/models"; +export function createGameImportTaskId(libraryId: string, libraryPath: string) { + return btoa(`import:${libraryId}:${libraryPath}`); +} + +export function createVersionImportTaskId(gameId: string, versionName: string) { + return btoa(`import:${gameId}:${versionName}`); +} + class LibraryManager { private libraries: Map> = new Map(); - private gameImportLocks: Map> = new Map(); // Library ID to Library Path - private versionImportLocks: Map> = new Map(); // Game ID to Version Name - addLibrary(library: LibraryProvider) { this.libraries.set(library.id(), library); } @@ -58,12 +63,10 @@ class LibraryManager { for (const [id, library] of this.libraries.entries()) { const providerGames = await library.listGames(); - const locks = this.gameImportLocks.get(id) ?? []; const providerUnimportedGames = providerGames.filter( (libraryPath) => - instanceGames[id] && - !instanceGames[id][libraryPath] && - !locks.includes(libraryPath), + !instanceGames[id]?.[libraryPath] && + !taskHandler.hasTask(createGameImportTaskId(id, libraryPath)), ); unimportedGames[id] = providerUnimportedGames; } @@ -93,7 +96,7 @@ class LibraryManager { const unimportedVersions = versions.filter( (e) => game.versions.findIndex((v) => v.versionName == e) == -1 && - !(this.versionImportLocks.get(game.id) ?? []).includes(e), + !taskHandler.hasTask(createVersionImportTaskId(game.id, e)), ); return unimportedVersions; } catch (e) { @@ -177,7 +180,8 @@ class LibraryManager { for (const filename of files) { const basename = path.basename(filename); const dotLocation = filename.lastIndexOf("."); - const ext = dotLocation == -1 ? "" : filename.slice(dotLocation).toLowerCase(); + const ext = + dotLocation == -1 ? "" : filename.slice(dotLocation).toLowerCase(); for (const [platform, checkExts] of Object.entries(fileExts)) { for (const checkExt of checkExts) { if (checkExt != ext) continue; @@ -215,70 +219,6 @@ class LibraryManager { } */ - /** - * Locks the game so you can't be imported - * @param libraryId - * @param libraryPath - */ - async lockGame(libraryId: string, libraryPath: string) { - let games = this.gameImportLocks.get(libraryId); - if (!games) this.gameImportLocks.set(libraryId, (games = [])); - - if (!games.includes(libraryPath)) games.push(libraryPath); - - this.gameImportLocks.set(libraryId, games); - } - - /** - * Unlocks the game, call once imported - * @param libraryId - * @param libraryPath - */ - async unlockGame(libraryId: string, libraryPath: string) { - let games = this.gameImportLocks.get(libraryId); - if (!games) this.gameImportLocks.set(libraryId, (games = [])); - - if (games.includes(libraryPath)) - games.splice( - games.findIndex((e) => e === libraryPath), - 1, - ); - - this.gameImportLocks.set(libraryId, games); - } - - /** - * Locks a version so it can't be imported - * @param gameId - * @param versionName - */ - async lockVersion(gameId: string, versionName: string) { - let versions = this.versionImportLocks.get(gameId); - if (!versions) this.versionImportLocks.set(gameId, (versions = [])); - - if (!versions.includes(versionName)) versions.push(versionName); - - this.versionImportLocks.set(gameId, versions); - } - - /** - * Unlocks the version, call once imported - * @param libraryId - * @param libraryPath - */ - async unlockVersion(gameId: string, versionName: string) { - let versions = this.versionImportLocks.get(gameId); - if (!versions) this.versionImportLocks.set(gameId, (versions = [])); - - if (versions.includes(gameId)) - versions.splice( - versions.findIndex((e) => e === versionName), - 1, - ); - - this.versionImportLocks.set(gameId, versions); - } - async importVersion( gameId: string, versionName: string, @@ -295,7 +235,7 @@ class LibraryManager { umuId: string; }, ) { - const taskId = `import:${gameId}:${versionName}`; + const taskId = createVersionImportTaskId(gameId, versionName); const platform = parsePlatform(metadata.platform); if (!platform) return undefined; @@ -309,8 +249,6 @@ class LibraryManager { const library = this.libraries.get(game.libraryId); if (!library) return undefined; - await this.lockVersion(gameId, versionName); - taskHandler.create({ id: taskId, taskGroup: "import:game", @@ -387,9 +325,6 @@ class LibraryManager { progress(100); }, - async finally() { - await libraryManager.unlockVersion(gameId, versionName); - }, }); return taskId; @@ -403,7 +338,7 @@ class LibraryManager { ) { const library = this.libraries.get(libraryId); if (!library) return undefined; - return library.peekFile(game, version, filename); + return await library.peekFile(game, version, filename); } async readFile( @@ -415,7 +350,7 @@ class LibraryManager { ) { const library = this.libraries.get(libraryId); if (!library) return undefined; - return library.readFile(game, version, filename, options); + return await library.readFile(game, version, filename, options); } } diff --git a/server/internal/library/providers/filesystem.ts b/server/internal/library/providers/filesystem.ts index 1b8f5499..de59b468 100644 --- a/server/internal/library/providers/filesystem.ts +++ b/server/internal/library/providers/filesystem.ts @@ -7,12 +7,14 @@ import { import { LibraryBackend } from "~/prisma/client/enums"; import fs from "fs"; import path from "path"; -import droplet from "@drop-oss/droplet"; +import droplet, { DropletHandler } from "@drop-oss/droplet"; export const FilesystemProviderConfig = type({ baseDir: "string", }); +export const DROPLET_HANDLER = new DropletHandler(); + export class FilesystemProvider implements LibraryProvider { @@ -57,7 +59,7 @@ export class FilesystemProvider const versionDirs = fs.readdirSync(gameDir); const validVersionDirs = versionDirs.filter((e) => { const fullDir = path.join(this.config.baseDir, game, e); - return droplet.hasBackendForPath(fullDir); + return DROPLET_HANDLER.hasBackendForPath(fullDir); }); return validVersionDirs; } @@ -65,7 +67,7 @@ export class FilesystemProvider async versionReaddir(game: string, version: string): Promise { const versionDir = path.join(this.config.baseDir, game, version); if (!fs.existsSync(versionDir)) throw new VersionNotFoundError(); - return droplet.listFiles(versionDir); + return DROPLET_HANDLER.listFiles(versionDir); } async generateDropletManifest( @@ -77,10 +79,16 @@ export class FilesystemProvider const versionDir = path.join(this.config.baseDir, game, version); if (!fs.existsSync(versionDir)) throw new VersionNotFoundError(); const manifest = await new Promise((r, j) => - droplet.generateManifest(versionDir, progress, log, (err, result) => { - if (err) return j(err); - r(result); - }), + droplet.generateManifest( + DROPLET_HANDLER, + versionDir, + progress, + log, + (err, result) => { + if (err) return j(err); + r(result); + }, + ), ); return manifest; } @@ -88,7 +96,7 @@ export class FilesystemProvider async peekFile(game: string, version: string, filename: string) { const filepath = path.join(this.config.baseDir, game, version); if (!fs.existsSync(filepath)) return undefined; - const stat = droplet.peekFile(filepath, filename); + const stat = DROPLET_HANDLER.peekFile(filepath, filename); return { size: Number(stat) }; } @@ -100,13 +108,17 @@ export class FilesystemProvider ) { const filepath = path.join(this.config.baseDir, game, version); if (!fs.existsSync(filepath)) return undefined; - const stream = droplet.readFile( - filepath, - filename, - options?.start ? BigInt(options.start) : undefined, - options?.end ? BigInt(options.end) : undefined, - ); - if (!stream) return undefined; + let stream; + while (!(stream instanceof ReadableStream)) { + const v = DROPLET_HANDLER.readFile( + filepath, + filename, + options?.start ? BigInt(options.start) : undefined, + options?.end ? BigInt(options.end) : undefined, + ); + if (!v) return undefined; + stream = v.getStream() as ReadableStream; + } return stream; } diff --git a/server/internal/library/providers/flat.ts b/server/internal/library/providers/flat.ts index 5bb71575..d717879c 100644 --- a/server/internal/library/providers/flat.ts +++ b/server/internal/library/providers/flat.ts @@ -5,6 +5,7 @@ import { LibraryBackend } from "~/prisma/client/enums"; import fs from "fs"; import path from "path"; import droplet from "@drop-oss/droplet"; +import { DROPLET_HANDLER } from "./filesystem"; export const FlatFilesystemProviderConfig = type({ baseDir: "string", @@ -46,7 +47,7 @@ export class FlatFilesystemProvider const versionDirs = fs.readdirSync(this.config.baseDir); const validVersionDirs = versionDirs.filter((e) => { const fullDir = path.join(this.config.baseDir, e); - return droplet.hasBackendForPath(fullDir); + return DROPLET_HANDLER.hasBackendForPath(fullDir); }); return validVersionDirs; } @@ -63,7 +64,7 @@ export class FlatFilesystemProvider async versionReaddir(game: string, _version: string) { const versionDir = path.join(this.config.baseDir, game); if (!fs.existsSync(versionDir)) throw new VersionNotFoundError(); - return droplet.listFiles(versionDir); + return DROPLET_HANDLER.listFiles(versionDir); } async generateDropletManifest( @@ -75,7 +76,7 @@ export class FlatFilesystemProvider const versionDir = path.join(this.config.baseDir, game); if (!fs.existsSync(versionDir)) throw new VersionNotFoundError(); const manifest = await new Promise((r, j) => - droplet.generateManifest(versionDir, progress, log, (err, result) => { + droplet.generateManifest(DROPLET_HANDLER, versionDir, progress, log, (err, result) => { if (err) return j(err); r(result); }), @@ -85,7 +86,7 @@ export class FlatFilesystemProvider async peekFile(game: string, _version: string, filename: string) { const filepath = path.join(this.config.baseDir, game); if (!fs.existsSync(filepath)) return undefined; - const stat = droplet.peekFile(filepath, filename); + const stat = DROPLET_HANDLER.peekFile(filepath, filename); return { size: Number(stat) }; } async readFile( @@ -96,7 +97,7 @@ export class FlatFilesystemProvider ) { const filepath = path.join(this.config.baseDir, game); if (!fs.existsSync(filepath)) return undefined; - const stream = droplet.readFile( + const stream = DROPLET_HANDLER.readFile( filepath, filename, options?.start ? BigInt(options.start) : undefined, @@ -104,6 +105,6 @@ export class FlatFilesystemProvider ); if (!stream) return undefined; - return stream; + return stream.getStream(); } } diff --git a/server/internal/metadata/index.ts b/server/internal/metadata/index.ts index 05a22674..88025e87 100644 --- a/server/internal/metadata/index.ts +++ b/server/internal/metadata/index.ts @@ -18,7 +18,7 @@ import taskHandler, { wrapTaskContext } from "../tasks"; import { randomUUID } from "crypto"; import { fuzzy } from "fast-fuzzy"; import { logger } from "~/server/internal/logging"; -import libraryManager from "../library"; +import { createGameImportTaskId } from "../library"; import type { GameTagModel } from "~/prisma/client/models"; export class MissingMetadataProviderConfig extends Error { @@ -185,11 +185,9 @@ export class MetadataHandler { }); if (existing) return undefined; - await libraryManager.lockGame(libraryId, libraryPath); - const gameId = randomUUID(); - const taskId = `import:${gameId}`; + const taskId = createGameImportTaskId(libraryId, libraryPath); await taskHandler.create({ name: `Import game "${result.name}" (${libraryPath})`, id: taskId, @@ -280,9 +278,6 @@ export class MetadataHandler { logger.info(`Finished game import.`); progress(100); }, - async finally() { - await libraryManager.unlockGame(libraryId, libraryPath); - }, }); return taskId; diff --git a/server/internal/tasks/index.ts b/server/internal/tasks/index.ts index e7ee65fc..f6f93fe7 100644 --- a/server/internal/tasks/index.ts +++ b/server/internal/tasks/index.ts @@ -73,6 +73,8 @@ class TaskHandler { } async create(task: Task) { + if (this.hasTask(task.id)) throw new Error("Task with ID already exists."); + let updateCollectTimeout: NodeJS.Timeout | undefined; let updateCollectResolves: Array<(value: unknown) => void> = []; let logOffset: number = 0; @@ -206,8 +208,6 @@ class TaskHandler { }; } - if (task.finally) await task.finally(); - taskEntry.endTime = new Date().toISOString(); await updateAllClients(); @@ -247,7 +247,10 @@ class TaskHandler { ) { const task = this.taskPool.get(taskId) ?? - (await prisma.task.findUnique({ where: { id: taskId } })); + (await prisma.task.findFirst({ + where: { id: taskId }, + orderBy: { started: "desc" }, + })); if (!task) { peer.send( `error/${taskId}/Unknown task/Drop couldn't find the task you're looking for.`, @@ -324,6 +327,10 @@ class TaskHandler { .toArray(); } + hasTask(id: string) { + return this.taskPool.has(id); + } + dailyTasks() { return this.dailyScheduledTasks; } @@ -429,7 +436,6 @@ export interface Task { taskGroup: TaskGroup; name: string; run: (context: TaskRunContext) => Promise; - finally?: () => Promise | void; acls: GlobalACL[]; } diff --git a/yarn.lock b/yarn.lock index d6bd269f..fd128474 100644 --- a/yarn.lock +++ b/yarn.lock @@ -342,71 +342,73 @@ jsonfile "^5.0.0" universalify "^0.1.2" -"@drop-oss/droplet-darwin-arm64@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-arm64/-/droplet-darwin-arm64-1.6.0.tgz#9697e38c46b02192e8e180b7deaaa20a389a9b0d" - integrity sha512-EqTx+Mk5SHP17n19r5coacUDd7lklT4opJ2keNQyGsQjrcf+9FeCX1O5Y+PGIjpQK6UkAVdnBqM+jR7NeFmkAQ== +"@drop-oss/droplet-darwin-arm64@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-arm64/-/droplet-darwin-arm64-2.0.2.tgz#99a9537ac8dd0f29248b3df82f2131f73e054c58" + integrity sha512-o4B0w0E7KzNsVroRvmH0gOtqJJUYbnTJowyZr5oPZMouM1PthIFR0GHjYiwTsvChyvk+DYIfoy6yH+OBlrcBuw== -"@drop-oss/droplet-darwin-universal@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-universal/-/droplet-darwin-universal-1.6.0.tgz#2f780416052ac7d1752b0a7828dc3ef9d1789c92" - integrity sha512-TxVpoVDI9aGuBCHA8HktbrIkS/C1gu5laM5+ZbIZkXnIUpTicJIbHRyneXJ4MLnW703gUbW8LTISgm7xKwZJsg== +"@drop-oss/droplet-darwin-universal@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-universal/-/droplet-darwin-universal-2.0.2.tgz#eb3f51e71e2b5252c650e9778db12f4cb5a0aa8f" + integrity sha512-EASNWev/4qzi0ztWBZ4h5waiFAjxsVATV3mTFNo947Z9juVlTm0QYtttQSpRuounzwhpOtTmTzfWpd7rzz87Sg== -"@drop-oss/droplet-darwin-x64@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-x64/-/droplet-darwin-x64-1.6.0.tgz#5d6a3c596eca706e40b35cdf49ada65e59c51b8d" - integrity sha512-V/1xh4s16AmesDOEHiQ4vj9XQq6AWmXRY5RQf4RKBQqkxsHzmQoa37CTLK25Wf9OUoiJFGpnjViqKOFG4y5Q+g== +"@drop-oss/droplet-darwin-x64@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-x64/-/droplet-darwin-x64-2.0.2.tgz#788904c1ecde832ed5a523a6cab063448cb30fa2" + integrity sha512-u2GYs7gC/Udv4uUgvBx3Eg5xVePZI8IO9z5M1bOVKeKrq1nmjq6TmCTOnKOyxvWVOoKXsfBwe9Qrk4dwvZEsTw== -"@drop-oss/droplet-linux-arm64-gnu@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-arm64-gnu/-/droplet-linux-arm64-gnu-1.6.0.tgz#265d5e7854c4c61081b8fd74b3e8305ea2c7b5ac" - integrity sha512-WjaRl9VW0qE+YkOCaYuNIXzyBbps2lopbpeXELZ9/f/1jBfzfmIe4m6C2hMy4NWUcWnrBbiVTEjnq2cHj/TaBA== +"@drop-oss/droplet-linux-arm64-gnu@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-arm64-gnu/-/droplet-linux-arm64-gnu-2.0.2.tgz#fa3f5bf1aa32e8245acfb7ad5993e66b6fa38fc8" + integrity sha512-LMiPvtjAbsie4mkOLEpUkAtMNzOn6fqKy2b0ja2kPEnsrcH/MmytHX0IJRznhevoFN22M12B/5PtUeUKpMuzfQ== -"@drop-oss/droplet-linux-arm64-musl@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-arm64-musl/-/droplet-linux-arm64-musl-1.6.0.tgz#7126e194e5ef9018d61ef7dd0cc3af80734e00e2" - integrity sha512-B8KoBYk0YVUZIL+etCcOc99NuoBcTm6KDOIQkN9SHWC4YLRu8um3w8DHzv4VV3arUnEGjyDHuraaOSONfP6NqA== +"@drop-oss/droplet-linux-arm64-musl@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-arm64-musl/-/droplet-linux-arm64-musl-2.0.2.tgz#934f5f5a57fda26cdfd00377e13584edbed42aa5" + integrity sha512-aOkVor56k10iR6X2Dta0QnaGuYrRt8gR6APS25eFN9Tp/YRlCT0bQHmKobLB69n4Fv3ARxPr0u9xKCSg0aEimg== -"@drop-oss/droplet-linux-riscv64-gnu@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-riscv64-gnu/-/droplet-linux-riscv64-gnu-1.6.0.tgz#40d060eafaca08b47a468950d7dc5ec4f1fb2a5a" - integrity sha512-nbNr/38EX8Mjj20+paohlOD35apmaNKZan4OO97KOwvq5oZ/pXbkjOGC0zkpsizyxbwKx7Jl4Se7teRVPWWVWw== +"@drop-oss/droplet-linux-riscv64-gnu@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-riscv64-gnu/-/droplet-linux-riscv64-gnu-2.0.2.tgz#6c02c147e575e18c2259cdabee036ec6eca3a250" + integrity sha512-eYIbXYk/PHzZoJUgh4ClT0NCoRxSXsLjTmRjoDle8+4Pp6bq8FFJEwhR4/X7xd10wHFyc/dP1dGJwO0hUtFzzg== -"@drop-oss/droplet-linux-x64-gnu@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-x64-gnu/-/droplet-linux-x64-gnu-1.6.0.tgz#c3a8408644194e59ac2110229e9a99885b3bc533" - integrity sha512-n/zA1ftqGey5yQK/1HiCok3MaLA4stVTzQEuRUzyq8BQ1BC6TmKCgdFnI4Q3tuGm3/Mz2CCbfbHY4bYwND9qOQ== +"@drop-oss/droplet-linux-x64-gnu@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-x64-gnu/-/droplet-linux-x64-gnu-2.0.2.tgz#efe99e008c7839c4342e3fe770bf482e5406f262" + integrity sha512-p4r7I4JOMGPgjbA1GjXg46nuMF3MbQj29IB3Y4VqXJ1dZALpBcXiMNy1G696TW+T9onifXLX8wH2b2BPpwQMLw== -"@drop-oss/droplet-linux-x64-musl@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-x64-musl/-/droplet-linux-x64-musl-1.6.0.tgz#206b5c85b02b7fdf53bc5f0cdf68a9d9a7d501cd" - integrity sha512-egZWqKK1+vHoVKNuMle2Kn8WbbJ7Y9WJScUNXjF8hdUDNo9eHwJT/DfnA+BhvFQuJXkU58vwv6MqZ5VLdOsGiA== +"@drop-oss/droplet-linux-x64-musl@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-x64-musl/-/droplet-linux-x64-musl-2.0.2.tgz#a420fa27ccaff3dfb96b4d2f4f6913a66fad136d" + integrity sha512-SvqcLYcbNtjKBx/IEjdQrM2IpzfrS8VAm7Nh5yzKO0QHdzaoA8G2l6Saf9LNc/tmQ8a+EtI5+g4jVsr9RREzgA== -"@drop-oss/droplet-win32-arm64-msvc@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-win32-arm64-msvc/-/droplet-win32-arm64-msvc-1.6.0.tgz#fbb0387536f5b2a88f03877d730f7f863646ce08" - integrity sha512-AwGYHae8ZmQV2QGp+3B0DhsBdYynrZ4AS1xNc+U1tXt5CiMp9wLLM/4a+WySYHX7XrEo8pKmRRa0I8QdAdxk5A== +"@drop-oss/droplet-win32-arm64-msvc@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-win32-arm64-msvc/-/droplet-win32-arm64-msvc-2.0.2.tgz#f07c404735623c2b0f13f9f9dca8616e4fe5245d" + integrity sha512-R6N1zo93xHY6bxXlIhSjd04tBJRQwM6eotQ2ayhMWFfg+IxS56X4yRk30e8LO4lFzeeQmNpsXI2NF4uCfSTtUA== -"@drop-oss/droplet-win32-x64-msvc@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-win32-x64-msvc/-/droplet-win32-x64-msvc-1.6.0.tgz#600058775641b4c5c051291e5a13135aa1ae28bb" - integrity sha512-Viz+J87rF7I++nLpPBvdhsjUQAHivA6wSHrBXa+4MwIymUvlQXcvNReFqzObRH4eiuiY4e3s3t9X7+paqd847Q== +"@drop-oss/droplet-win32-x64-msvc@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-win32-x64-msvc/-/droplet-win32-x64-msvc-2.0.2.tgz#fe43c4ee99a2fa8ed63d930931c664f106a94791" + integrity sha512-V3UfZ4hznzI5nys8sjDid4t4EmBxyG3IGe9r32+R7J8zYm5/OKTtjAoURRjoatAUbBm9/Bc0BIM5VFkPfXyTfQ== -"@drop-oss/droplet@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet/-/droplet-1.6.0.tgz#b6aa382dc5df494c4233a2bd8f19721878edad71" - integrity sha512-nTZvLo+GFLlpxgFlObP4zitVctz02bRD3ZSVDiMv7jXxYK0V/GktITJFcKK0J87ZRxneoFHYbLs1lH3MFYoSIw== +"@drop-oss/droplet@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet/-/droplet-2.0.2.tgz#a1049d0ba3848c373a672125ffb807bc5a385e49" + integrity sha512-7JJkduBweG2W9g1VD/ecDbNO9AXY0BGa2PLLtY78PmWt/p+XnJT2OgyxFoH1ArUz/+j4Dz7jk1gBYXhiCpSM2w== + dependencies: + tsimp "^2.0.12" optionalDependencies: - "@drop-oss/droplet-darwin-arm64" "1.6.0" - "@drop-oss/droplet-darwin-universal" "1.6.0" - "@drop-oss/droplet-darwin-x64" "1.6.0" - "@drop-oss/droplet-linux-arm64-gnu" "1.6.0" - "@drop-oss/droplet-linux-arm64-musl" "1.6.0" - "@drop-oss/droplet-linux-riscv64-gnu" "1.6.0" - "@drop-oss/droplet-linux-x64-gnu" "1.6.0" - "@drop-oss/droplet-linux-x64-musl" "1.6.0" - "@drop-oss/droplet-win32-arm64-msvc" "1.6.0" - "@drop-oss/droplet-win32-x64-msvc" "1.6.0" + "@drop-oss/droplet-darwin-arm64" "2.0.2" + "@drop-oss/droplet-darwin-universal" "2.0.2" + "@drop-oss/droplet-darwin-x64" "2.0.2" + "@drop-oss/droplet-linux-arm64-gnu" "2.0.2" + "@drop-oss/droplet-linux-arm64-musl" "2.0.2" + "@drop-oss/droplet-linux-riscv64-gnu" "2.0.2" + "@drop-oss/droplet-linux-x64-gnu" "2.0.2" + "@drop-oss/droplet-linux-x64-musl" "2.0.2" + "@drop-oss/droplet-win32-arm64-msvc" "2.0.2" + "@drop-oss/droplet-win32-x64-msvc" "2.0.2" "@emnapi/core@^1.4.3": version "1.4.5" @@ -987,6 +989,18 @@ dependencies: "@isaacs/balanced-match" "^4.0.1" +"@isaacs/cached@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@isaacs/cached/-/cached-1.0.1.tgz#b6ad07c346f843fb3f117a0f3401ea8b7f7d4eea" + integrity sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw== + dependencies: + "@isaacs/catcher" "^1.0.0" + +"@isaacs/catcher@^1.0.0", "@isaacs/catcher@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@isaacs/catcher/-/catcher-1.0.4.tgz#fa5aa6fa43d255b9fe32e1e1f40db6623de2c80d" + integrity sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -4945,7 +4959,7 @@ fontkit@^2.0.2: unicode-properties "^1.4.0" unicode-trie "^2.0.0" -foreground-child@^3.1.0: +foreground-child@^3.1.0, foreground-child@^3.1.1, foreground-child@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== @@ -5131,7 +5145,7 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob@^10.0.0, glob@^10.3.3, glob@^10.4.5: +glob@^10.0.0, glob@^10.3.3, glob@^10.3.7, glob@^10.4.5: version "10.4.5" resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== @@ -5143,6 +5157,18 @@ glob@^10.0.0, glob@^10.3.3, glob@^10.4.5: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" +glob@^11.0.0: + version "11.0.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.3.tgz#9d8087e6d72ddb3c4707b1d2778f80ea3eaefcd6" + integrity sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA== + dependencies: + foreground-child "^3.3.1" + jackspeak "^4.1.1" + minimatch "^10.0.3" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^2.0.0" + global-directory@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/global-directory/-/global-directory-4.0.1.tgz#4d7ac7cfd2cb73f304c53b8810891748df5e361e" @@ -5628,6 +5654,13 @@ jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" +jackspeak@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.1.1.tgz#96876030f450502047fc7e8c7fcf8ce8124e43ae" + integrity sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + jdenticon@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/jdenticon/-/jdenticon-3.3.0.tgz#64bae9f9b3cf5c2a210e183648117afe3a89b367" @@ -6016,6 +6049,11 @@ lru-cache@^10.0.1, lru-cache@^10.2.0, lru-cache@^10.4.3: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== +lru-cache@^11.0.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.1.0.tgz#afafb060607108132dbc1cf8ae661afb69486117" + integrity sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -6359,6 +6397,13 @@ mini-svg-data-uri@^1.2.3: resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939" integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg== +minimatch@^10.0.3, "minimatch@^9.0.3 || ^10.0.1": + version "10.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.3.tgz#cf7a0314a16c4d9ab73a7730a0e8e3c3502d47aa" + integrity sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw== + dependencies: + "@isaacs/brace-expansion" "^5.0.0" + minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -6380,13 +6425,6 @@ minimatch@^9.0.0, minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -"minimatch@^9.0.3 || ^10.0.1": - version "10.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.3.tgz#cf7a0314a16c4d9ab73a7730a0e8e3c3502d47aa" - integrity sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw== - dependencies: - "@isaacs/brace-expansion" "^5.0.0" - minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" @@ -7129,6 +7167,14 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-scurry@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" + integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== + dependencies: + lru-cache "^11.0.0" + minipass "^7.1.2" + path-type@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-6.0.0.tgz#2f1bb6791a91ce99194caede5d6c5920ed81eb51" @@ -7222,6 +7268,11 @@ pino@^9.7.0: sonic-boom "^4.0.1" thread-stream "^3.0.0" +pirates@^4.0.6: + version "4.0.7" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22" + integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== + pkg-types@^1.0.3, pkg-types@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.3.1.tgz#bd7cc70881192777eef5326c19deb46e890917df" @@ -7847,6 +7898,21 @@ rfdc@^1.4.1: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== +rimraf@^5.0.5: + version "5.0.10" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.10.tgz#23b9843d3dc92db71f96e1a2ce92e39fd2a8221c" + integrity sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ== + dependencies: + glob "^10.3.7" + +rimraf@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-6.0.1.tgz#ffb8ad8844dd60332ab15f52bc104bc3ed71ea4e" + integrity sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A== + dependencies: + glob "^11.0.0" + package-json-from-dist "^1.0.0" + rollup-plugin-visualizer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/rollup-plugin-visualizer/-/rollup-plugin-visualizer-6.0.3.tgz#d05bd17e358a6d04bf593cf73556219c9c6d8dad" @@ -8146,6 +8212,20 @@ smob@^1.0.0: resolved "https://registry.yarnpkg.com/smob/-/smob-1.5.0.tgz#85d79a1403abf128d24d3ebc1cdc5e1a9548d3ab" integrity sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig== +sock-daemon@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/sock-daemon/-/sock-daemon-1.4.2.tgz#b9d5d1f8b156b20a7c1ceba095da8b8745fac405" + integrity sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg== + dependencies: + rimraf "^5.0.5" + signal-exit "^4.1.0" + socket-post-message "^1.0.3" + +socket-post-message@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/socket-post-message/-/socket-post-message-1.0.3.tgz#638dfca32064eee9a784bb5be9634b19e649ac39" + integrity sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg== + sonic-boom@^4.0.1: version "4.2.0" resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-4.2.0.tgz#e59a525f831210fa4ef1896428338641ac1c124d" @@ -8652,6 +8732,21 @@ ts-api-utils@^2.1.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.1.0.tgz#595f7094e46eed364c13fd23e75f9513d29baf91" integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== +tsimp@^2.0.12: + version "2.0.12" + resolved "https://registry.yarnpkg.com/tsimp/-/tsimp-2.0.12.tgz#aa65a2db98e273fae81a91bc7f531abe8ac1fcdf" + integrity sha512-0XbhMfDB1BlN4iuheUaCUVB2iAjWb9z6Ik/6WcxREc4MhjYmkScK+CRNf34wkDO8wMvmFBb0lYdrd8H44g9yjg== + dependencies: + "@isaacs/cached" "^1.0.1" + "@isaacs/catcher" "^1.0.4" + foreground-child "^3.1.1" + mkdirp "^3.0.1" + pirates "^4.0.6" + rimraf "^6.0.1" + signal-exit "^4.1.0" + sock-daemon "^1.4.2" + walk-up-path "^4.0.0" + tslib@^2.4.0, tslib@^2.6.3, tslib@^2.8.0, tslib@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" @@ -9225,6 +9320,11 @@ vuedraggable@^4.1.0: dependencies: sortablejs "1.14.0" +walk-up-path@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-4.0.0.tgz#590666dcf8146e2d72318164f1f2ac6ef51d4198" + integrity sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A== + web-streams-polyfill@^3.0.3: version "3.3.3" resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b" From 2f2395fce03dba4d416bb1ee409ecb8851ddcb21 Mon Sep 17 00:00:00 2001 From: DecDuck Date: Fri, 15 Aug 2025 11:58:25 +1000 Subject: [PATCH 3/5] fix: task formatting --- pages/admin/task/index.vue | 4 ++-- utils/parseTaskLog.ts | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pages/admin/task/index.vue b/pages/admin/task/index.vue index 29b9740c..b9f3f6ce 100644 --- a/pages/admin/task/index.vue +++ b/pages/admin/task/index.vue @@ -47,7 +47,7 @@ />

- {{ parseTaskLog(task.value.log.at(-1) ?? "").message }} + {{ parseTaskLog(task.value.log.at(-1)).message }}

- {{ parseTaskLog(task.log.at(-1) ?? "").message }} + {{ parseTaskLog(task.log.at(-1)).message }}

Date: Fri, 15 Aug 2025 22:20:54 +1000 Subject: [PATCH 4/5] fix: zip downloads --- components/LanguageSelector.vue | 23 ++- package.json | 2 +- server/api/v2/client/chunk.post.ts | 14 +- yarn.lock | 226 ++++++++--------------------- 4 files changed, 87 insertions(+), 178 deletions(-) diff --git a/components/LanguageSelector.vue b/components/LanguageSelector.vue index d929c297..1ff633d4 100644 --- a/components/LanguageSelector.vue +++ b/components/LanguageSelector.vue @@ -1,25 +1,22 @@ + + \ No newline at end of file diff --git a/package.json b/package.json index cdc8652b..3a68d92b 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "dependencies": { "@discordapp/twemoji": "^16.0.1", - "@drop-oss/droplet": "2.0.2", + "@drop-oss/droplet": "2.3.0", "@headlessui/vue": "^1.7.23", "@heroicons/vue": "^2.1.5", "@lobomfz/prismark": "0.0.3", diff --git a/server/api/v2/client/chunk.post.ts b/server/api/v2/client/chunk.post.ts index a1658504..bffb9262 100644 --- a/server/api/v2/client/chunk.post.ts +++ b/server/api/v2/client/chunk.post.ts @@ -2,6 +2,7 @@ import { type } from "arktype"; import { readDropValidatedBody, throwingArktype } from "~/server/arktype"; import contextManager from "~/server/internal/downloads/coordinator"; import libraryManager from "~/server/internal/library"; +import { logger } from "~/server/internal/logging"; const GetChunk = type({ context: "string", @@ -58,14 +59,25 @@ export default defineEventHandler(async (h3) => { statusCode: 500, statusMessage: "Failed to create read stream", }); - console.log(`sending stream for ${file.filename} for ${body.context}`); + let length = 0; await gameReadStream.pipeTo( new WritableStream({ write(chunk) { h3.node.res.write(chunk); + length += chunk.length; }, }), ); + + if (length != file.end - file.start) { + logger.warn( + `failed to read enough from ${file.filename}. read ${length}, required: ${file.end - file.start}`, + ); + throw createError({ + statusCode: 500, + statusMessage: "Failed to read enough from stream.", + }); + } } await h3.node.res.end(); diff --git a/yarn.lock b/yarn.lock index fd128474..bcba175d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -342,73 +342,71 @@ jsonfile "^5.0.0" universalify "^0.1.2" -"@drop-oss/droplet-darwin-arm64@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-arm64/-/droplet-darwin-arm64-2.0.2.tgz#99a9537ac8dd0f29248b3df82f2131f73e054c58" - integrity sha512-o4B0w0E7KzNsVroRvmH0gOtqJJUYbnTJowyZr5oPZMouM1PthIFR0GHjYiwTsvChyvk+DYIfoy6yH+OBlrcBuw== +"@drop-oss/droplet-darwin-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-arm64/-/droplet-darwin-arm64-2.3.0.tgz#f4f0ded9c9f5b5cac25dd56f59817e1c13e865ab" + integrity sha512-5k1VwGZTFc61FvKyL4cvYxFYB7aCY5cWCo0Q7yTkkj+KR+ewH6ucylU8kDG7M+aBLvbC/zbntXUp4RtYZi4AZQ== -"@drop-oss/droplet-darwin-universal@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-universal/-/droplet-darwin-universal-2.0.2.tgz#eb3f51e71e2b5252c650e9778db12f4cb5a0aa8f" - integrity sha512-EASNWev/4qzi0ztWBZ4h5waiFAjxsVATV3mTFNo947Z9juVlTm0QYtttQSpRuounzwhpOtTmTzfWpd7rzz87Sg== +"@drop-oss/droplet-darwin-universal@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-universal/-/droplet-darwin-universal-2.3.0.tgz#1d8659bc2869e5d30308622bcc6cb230030d738e" + integrity sha512-4V/HMnNtmHgn156pTpa3mVTAwTmO9jqtZrDcVko7PdSotEbXiwBpTFzbgb4bPafbPmkSNoRh4G9d3BLQCh4mgw== -"@drop-oss/droplet-darwin-x64@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-x64/-/droplet-darwin-x64-2.0.2.tgz#788904c1ecde832ed5a523a6cab063448cb30fa2" - integrity sha512-u2GYs7gC/Udv4uUgvBx3Eg5xVePZI8IO9z5M1bOVKeKrq1nmjq6TmCTOnKOyxvWVOoKXsfBwe9Qrk4dwvZEsTw== +"@drop-oss/droplet-darwin-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-darwin-x64/-/droplet-darwin-x64-2.3.0.tgz#c7ff5dae8ba520866b7cd49714625ada8fa0a7c2" + integrity sha512-PUcNjE09N7qEFsbssKxL8rjmCt9AUYPz1yK34d8N2W9DboS1KI+PShWdd/NOk4GYzTJQuJhMp8wNcUrljfqXmQ== -"@drop-oss/droplet-linux-arm64-gnu@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-arm64-gnu/-/droplet-linux-arm64-gnu-2.0.2.tgz#fa3f5bf1aa32e8245acfb7ad5993e66b6fa38fc8" - integrity sha512-LMiPvtjAbsie4mkOLEpUkAtMNzOn6fqKy2b0ja2kPEnsrcH/MmytHX0IJRznhevoFN22M12B/5PtUeUKpMuzfQ== +"@drop-oss/droplet-linux-arm64-gnu@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-arm64-gnu/-/droplet-linux-arm64-gnu-2.3.0.tgz#8819b34c5ff8bd8182c5cd0c3f1784dc2afd9507" + integrity sha512-6VyOwYu9sMrCL82UZOvvjU9G/4wHdA8P6q3+EDIVdABg5jVEYZsxkrT0Kp/5h9Xs0mPFNB/su8ZwB9FRQ63o1w== -"@drop-oss/droplet-linux-arm64-musl@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-arm64-musl/-/droplet-linux-arm64-musl-2.0.2.tgz#934f5f5a57fda26cdfd00377e13584edbed42aa5" - integrity sha512-aOkVor56k10iR6X2Dta0QnaGuYrRt8gR6APS25eFN9Tp/YRlCT0bQHmKobLB69n4Fv3ARxPr0u9xKCSg0aEimg== +"@drop-oss/droplet-linux-arm64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-arm64-musl/-/droplet-linux-arm64-musl-2.3.0.tgz#06601aa8af4bffeb26956ff79ed494265e313342" + integrity sha512-2BZreAg1XOBxr+iY2hFcX4x6bFC7AKXkIHa9130rmStH/HxnGq6K5H49eJd6ezzNMH/lQ7Sm7uJP2+sH8mjeCw== -"@drop-oss/droplet-linux-riscv64-gnu@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-riscv64-gnu/-/droplet-linux-riscv64-gnu-2.0.2.tgz#6c02c147e575e18c2259cdabee036ec6eca3a250" - integrity sha512-eYIbXYk/PHzZoJUgh4ClT0NCoRxSXsLjTmRjoDle8+4Pp6bq8FFJEwhR4/X7xd10wHFyc/dP1dGJwO0hUtFzzg== +"@drop-oss/droplet-linux-riscv64-gnu@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-riscv64-gnu/-/droplet-linux-riscv64-gnu-2.3.0.tgz#6d5629631aeeceadb292998e21b6e2b2cf839bdc" + integrity sha512-E7i86Q8IU7rh2FVtXa0NxoGRhB7AZU+AWPumTAuDQS3xPg3sj+c3q/A7YI1Ay4lnvzR/fevP2p/7iSJUEDcchQ== -"@drop-oss/droplet-linux-x64-gnu@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-x64-gnu/-/droplet-linux-x64-gnu-2.0.2.tgz#efe99e008c7839c4342e3fe770bf482e5406f262" - integrity sha512-p4r7I4JOMGPgjbA1GjXg46nuMF3MbQj29IB3Y4VqXJ1dZALpBcXiMNy1G696TW+T9onifXLX8wH2b2BPpwQMLw== +"@drop-oss/droplet-linux-x64-gnu@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-x64-gnu/-/droplet-linux-x64-gnu-2.3.0.tgz#a924aada38dbc54f6967b17435c10bf3b6e6ffb0" + integrity sha512-eIHhhoSgpvMAc9tn/K0ldZRXvDe1Xyd9okSSqaclCEKjdVfWU8UMycUz1SzQH9YefiqEB4Qjd3y1iRgaEa8niA== -"@drop-oss/droplet-linux-x64-musl@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-x64-musl/-/droplet-linux-x64-musl-2.0.2.tgz#a420fa27ccaff3dfb96b4d2f4f6913a66fad136d" - integrity sha512-SvqcLYcbNtjKBx/IEjdQrM2IpzfrS8VAm7Nh5yzKO0QHdzaoA8G2l6Saf9LNc/tmQ8a+EtI5+g4jVsr9RREzgA== +"@drop-oss/droplet-linux-x64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-linux-x64-musl/-/droplet-linux-x64-musl-2.3.0.tgz#4eb71112f7641e1fad3b53f5f8d1b98b9cb84bf0" + integrity sha512-0taR945NvK+xNBicSYriKDJgBxpcozzgcALDp/cX2UaYV9cb5PF/xw80DArCyUDvKOfRzeFALx4KRC2ghPr6tw== -"@drop-oss/droplet-win32-arm64-msvc@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-win32-arm64-msvc/-/droplet-win32-arm64-msvc-2.0.2.tgz#f07c404735623c2b0f13f9f9dca8616e4fe5245d" - integrity sha512-R6N1zo93xHY6bxXlIhSjd04tBJRQwM6eotQ2ayhMWFfg+IxS56X4yRk30e8LO4lFzeeQmNpsXI2NF4uCfSTtUA== +"@drop-oss/droplet-win32-arm64-msvc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-win32-arm64-msvc/-/droplet-win32-arm64-msvc-2.3.0.tgz#36568f87024eb48ce7e82d76ea83a2c6ec25a856" + integrity sha512-5HkO98h/PboM+/wPulKVGFTklijlqht8w13iW1ipUcRFsOHmS1o8nejjLL7KEr2X8G4JwYOqBeX8tY3OhaU9bw== -"@drop-oss/droplet-win32-x64-msvc@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet-win32-x64-msvc/-/droplet-win32-x64-msvc-2.0.2.tgz#fe43c4ee99a2fa8ed63d930931c664f106a94791" - integrity sha512-V3UfZ4hznzI5nys8sjDid4t4EmBxyG3IGe9r32+R7J8zYm5/OKTtjAoURRjoatAUbBm9/Bc0BIM5VFkPfXyTfQ== +"@drop-oss/droplet-win32-x64-msvc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet-win32-x64-msvc/-/droplet-win32-x64-msvc-2.3.0.tgz#e794ea7cfdc0ea148707e4f3e60f2aa547328c03" + integrity sha512-6lNXOMyy9sPaO4wbklOIr2jbuvZHIVrd+dXu2UOI2YqFlHdxiDD1sZnqSZmlfCP58yeA+SpTfhxDHwUHJTFI/g== -"@drop-oss/droplet@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@drop-oss/droplet/-/droplet-2.0.2.tgz#a1049d0ba3848c373a672125ffb807bc5a385e49" - integrity sha512-7JJkduBweG2W9g1VD/ecDbNO9AXY0BGa2PLLtY78PmWt/p+XnJT2OgyxFoH1ArUz/+j4Dz7jk1gBYXhiCpSM2w== - dependencies: - tsimp "^2.0.12" +"@drop-oss/droplet@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@drop-oss/droplet/-/droplet-2.3.0.tgz#eb2891346cf7fadcc847d5dee37674fc1106d2fc" + integrity sha512-ffEoS3LYBfPm0++p7f7F/NkYH5PfauQzuj1gTz7qVWZOSP5VQWYhOc9BEg0fsCCzTB/mct0jwOsK92URmthpxA== optionalDependencies: - "@drop-oss/droplet-darwin-arm64" "2.0.2" - "@drop-oss/droplet-darwin-universal" "2.0.2" - "@drop-oss/droplet-darwin-x64" "2.0.2" - "@drop-oss/droplet-linux-arm64-gnu" "2.0.2" - "@drop-oss/droplet-linux-arm64-musl" "2.0.2" - "@drop-oss/droplet-linux-riscv64-gnu" "2.0.2" - "@drop-oss/droplet-linux-x64-gnu" "2.0.2" - "@drop-oss/droplet-linux-x64-musl" "2.0.2" - "@drop-oss/droplet-win32-arm64-msvc" "2.0.2" - "@drop-oss/droplet-win32-x64-msvc" "2.0.2" + "@drop-oss/droplet-darwin-arm64" "2.3.0" + "@drop-oss/droplet-darwin-universal" "2.3.0" + "@drop-oss/droplet-darwin-x64" "2.3.0" + "@drop-oss/droplet-linux-arm64-gnu" "2.3.0" + "@drop-oss/droplet-linux-arm64-musl" "2.3.0" + "@drop-oss/droplet-linux-riscv64-gnu" "2.3.0" + "@drop-oss/droplet-linux-x64-gnu" "2.3.0" + "@drop-oss/droplet-linux-x64-musl" "2.3.0" + "@drop-oss/droplet-win32-arm64-msvc" "2.3.0" + "@drop-oss/droplet-win32-x64-msvc" "2.3.0" "@emnapi/core@^1.4.3": version "1.4.5" @@ -989,18 +987,6 @@ dependencies: "@isaacs/balanced-match" "^4.0.1" -"@isaacs/cached@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@isaacs/cached/-/cached-1.0.1.tgz#b6ad07c346f843fb3f117a0f3401ea8b7f7d4eea" - integrity sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw== - dependencies: - "@isaacs/catcher" "^1.0.0" - -"@isaacs/catcher@^1.0.0", "@isaacs/catcher@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@isaacs/catcher/-/catcher-1.0.4.tgz#fa5aa6fa43d255b9fe32e1e1f40db6623de2c80d" - integrity sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA== - "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -4959,7 +4945,7 @@ fontkit@^2.0.2: unicode-properties "^1.4.0" unicode-trie "^2.0.0" -foreground-child@^3.1.0, foreground-child@^3.1.1, foreground-child@^3.3.1: +foreground-child@^3.1.0: version "3.3.1" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== @@ -5145,7 +5131,7 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob@^10.0.0, glob@^10.3.3, glob@^10.3.7, glob@^10.4.5: +glob@^10.0.0, glob@^10.3.3, glob@^10.4.5: version "10.4.5" resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== @@ -5157,18 +5143,6 @@ glob@^10.0.0, glob@^10.3.3, glob@^10.3.7, glob@^10.4.5: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" -glob@^11.0.0: - version "11.0.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.3.tgz#9d8087e6d72ddb3c4707b1d2778f80ea3eaefcd6" - integrity sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA== - dependencies: - foreground-child "^3.3.1" - jackspeak "^4.1.1" - minimatch "^10.0.3" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^2.0.0" - global-directory@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/global-directory/-/global-directory-4.0.1.tgz#4d7ac7cfd2cb73f304c53b8810891748df5e361e" @@ -5654,13 +5628,6 @@ jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" -jackspeak@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.1.1.tgz#96876030f450502047fc7e8c7fcf8ce8124e43ae" - integrity sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - jdenticon@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/jdenticon/-/jdenticon-3.3.0.tgz#64bae9f9b3cf5c2a210e183648117afe3a89b367" @@ -6049,11 +6016,6 @@ lru-cache@^10.0.1, lru-cache@^10.2.0, lru-cache@^10.4.3: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== -lru-cache@^11.0.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.1.0.tgz#afafb060607108132dbc1cf8ae661afb69486117" - integrity sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A== - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -6397,13 +6359,6 @@ mini-svg-data-uri@^1.2.3: resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939" integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg== -minimatch@^10.0.3, "minimatch@^9.0.3 || ^10.0.1": - version "10.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.3.tgz#cf7a0314a16c4d9ab73a7730a0e8e3c3502d47aa" - integrity sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw== - dependencies: - "@isaacs/brace-expansion" "^5.0.0" - minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -6425,6 +6380,13 @@ minimatch@^9.0.0, minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" +"minimatch@^9.0.3 || ^10.0.1": + version "10.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.3.tgz#cf7a0314a16c4d9ab73a7730a0e8e3c3502d47aa" + integrity sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw== + dependencies: + "@isaacs/brace-expansion" "^5.0.0" + minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" @@ -7167,14 +7129,6 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" -path-scurry@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" - integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== - dependencies: - lru-cache "^11.0.0" - minipass "^7.1.2" - path-type@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-6.0.0.tgz#2f1bb6791a91ce99194caede5d6c5920ed81eb51" @@ -7268,11 +7222,6 @@ pino@^9.7.0: sonic-boom "^4.0.1" thread-stream "^3.0.0" -pirates@^4.0.6: - version "4.0.7" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22" - integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== - pkg-types@^1.0.3, pkg-types@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.3.1.tgz#bd7cc70881192777eef5326c19deb46e890917df" @@ -7898,21 +7847,6 @@ rfdc@^1.4.1: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== -rimraf@^5.0.5: - version "5.0.10" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.10.tgz#23b9843d3dc92db71f96e1a2ce92e39fd2a8221c" - integrity sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ== - dependencies: - glob "^10.3.7" - -rimraf@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-6.0.1.tgz#ffb8ad8844dd60332ab15f52bc104bc3ed71ea4e" - integrity sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A== - dependencies: - glob "^11.0.0" - package-json-from-dist "^1.0.0" - rollup-plugin-visualizer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/rollup-plugin-visualizer/-/rollup-plugin-visualizer-6.0.3.tgz#d05bd17e358a6d04bf593cf73556219c9c6d8dad" @@ -8212,20 +8146,6 @@ smob@^1.0.0: resolved "https://registry.yarnpkg.com/smob/-/smob-1.5.0.tgz#85d79a1403abf128d24d3ebc1cdc5e1a9548d3ab" integrity sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig== -sock-daemon@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/sock-daemon/-/sock-daemon-1.4.2.tgz#b9d5d1f8b156b20a7c1ceba095da8b8745fac405" - integrity sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg== - dependencies: - rimraf "^5.0.5" - signal-exit "^4.1.0" - socket-post-message "^1.0.3" - -socket-post-message@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/socket-post-message/-/socket-post-message-1.0.3.tgz#638dfca32064eee9a784bb5be9634b19e649ac39" - integrity sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg== - sonic-boom@^4.0.1: version "4.2.0" resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-4.2.0.tgz#e59a525f831210fa4ef1896428338641ac1c124d" @@ -8732,21 +8652,6 @@ ts-api-utils@^2.1.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.1.0.tgz#595f7094e46eed364c13fd23e75f9513d29baf91" integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== -tsimp@^2.0.12: - version "2.0.12" - resolved "https://registry.yarnpkg.com/tsimp/-/tsimp-2.0.12.tgz#aa65a2db98e273fae81a91bc7f531abe8ac1fcdf" - integrity sha512-0XbhMfDB1BlN4iuheUaCUVB2iAjWb9z6Ik/6WcxREc4MhjYmkScK+CRNf34wkDO8wMvmFBb0lYdrd8H44g9yjg== - dependencies: - "@isaacs/cached" "^1.0.1" - "@isaacs/catcher" "^1.0.4" - foreground-child "^3.1.1" - mkdirp "^3.0.1" - pirates "^4.0.6" - rimraf "^6.0.1" - signal-exit "^4.1.0" - sock-daemon "^1.4.2" - walk-up-path "^4.0.0" - tslib@^2.4.0, tslib@^2.6.3, tslib@^2.8.0, tslib@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" @@ -9320,11 +9225,6 @@ vuedraggable@^4.1.0: dependencies: sortablejs "1.14.0" -walk-up-path@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-4.0.0.tgz#590666dcf8146e2d72318164f1f2ac6ef51d4198" - integrity sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A== - web-streams-polyfill@^3.0.3: version "3.3.3" resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b" From 5e4f0eb8c24b82917c5a4ab9f5baf6a2d817f41b Mon Sep 17 00:00:00 2001 From: DecDuck Date: Fri, 15 Aug 2025 22:55:33 +1000 Subject: [PATCH 5/5] feat: re-enable import version button on delete + lint --- components/GameEditor/Version.vue | 19 +++++++++++-------- components/LanguageSelector.vue | 17 ++++++++++++----- server/api/v2/client/chunk.post.ts | 2 +- server/internal/library/providers/flat.ts | 14 ++++++++++---- utils/parseTaskLog.ts | 4 +++- 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/components/GameEditor/Version.vue b/components/GameEditor/Version.vue index 4e832b7e..d2d38ad6 100644 --- a/components/GameEditor/Version.vue +++ b/components/GameEditor/Version.vue @@ -22,21 +22,17 @@ {{ - unimportedVersions.length > 0 + canImport ? $t("library.admin.import.version.import") : $t("library.admin.import.version.noVersions") }} @@ -124,10 +120,16 @@ import { ExclamationCircleIcon } from "@heroicons/vue/24/outline"; // TODO implement UI for this page -defineProps<{ unimportedVersions: string[] }>(); +const props = defineProps<{ unimportedVersions: string[] }>(); const { t } = useI18n(); +const hasDeleted = ref(false); + +const canImport = computed( + () => hasDeleted.value || props.unimportedVersions.length > 0, +); + type GameAndVersions = GameModel & { versions: GameVersionModel[] }; const game = defineModel>() as Ref< SerializeObject @@ -176,6 +178,7 @@ async function deleteVersion(versionName: string) { game.value.versions.findIndex((e) => e.versionName === versionName), 1, ); + hasDeleted.value = true; } catch (e) { createModal( ModalType.Notification, diff --git a/components/LanguageSelector.vue b/components/LanguageSelector.vue index 1ff633d4..3f84e80d 100644 --- a/components/LanguageSelector.vue +++ b/components/LanguageSelector.vue @@ -1,10 +1,17 @@