formatting, loadPack

This commit is contained in:
2026-02-15 04:27:28 -08:00
parent 81f6abad50
commit 0acd26dc8e
+58 -21
View File
@@ -1,6 +1,6 @@
import type { File, FileSystemDirectoryHandle, FileSystemFileHandle, FileSystemGetDirectoryOptions, FileSystemGetFileOptions, FileSystemWriteChunkType, Response } from "@sugoidogo/importable-types-web"
import type { FileSystemDirectoryHandle, FileSystemFileHandle, FileSystemGetDirectoryOptions, FileSystemGetFileOptions, FileSystemWriteChunkType, Response } from "@sugoidogo/importable-types-web"
import type { Hash, HashFormat, PackFileMetaData, PackIndex, PackMetaData, Path, Url } from "./types"
import { parseTOML, stringifyTOML } from "confbox"
import { parseTOML } from "confbox"
import { forAsync } from "@sugoidogo/js-util"
const pathSeperatorRegex = /[\\\/]/
@@ -13,31 +13,31 @@ export interface PackwizPack {
packFiles: { [key: Path]: PackFileMetaData | undefined }
}
function assertOK(response:Response) {
function assertOK(response: Response) {
if (!response.ok) {
throw new Error(response.statusText, { "cause": response })
}
return response as Response & {"ok":true}
return response as Response & { "ok": true }
}
async function getDirectoryHandle(directoryHandle:FileSystemDirectoryHandle,path:Path,options?:FileSystemGetDirectoryOptions) {
async function getDirectoryHandle(directoryHandle: FileSystemDirectoryHandle, path: Path, options?: FileSystemGetDirectoryOptions) {
const pathSegments = path.split(pathSeperatorRegex)
for (const segment of pathSegments) {
if(!segment) continue
directoryHandle=await directoryHandle.getDirectoryHandle(segment,options)
if (!segment) continue
directoryHandle = await directoryHandle.getDirectoryHandle(segment, options)
}
return directoryHandle
}
async function getFileHandle(directoryHandle:FileSystemDirectoryHandle,path:Path,options?:FileSystemGetFileOptions) {
async function getFileHandle(directoryHandle: FileSystemDirectoryHandle, path: Path, options?: FileSystemGetFileOptions) {
const pathSegments = path.split(pathSeperatorRegex)
const basename = pathSegments.pop()
const dirname = pathSegments.join('/')
directoryHandle = await getDirectoryHandle(directoryHandle, dirname, options)
return directoryHandle.getFileHandle(basename,options)
return directoryHandle.getFileHandle(basename, options)
}
async function writeFile(fileHandle: FileSystemFileHandle, data:FileSystemWriteChunkType) {
async function writeFile(fileHandle: FileSystemFileHandle, data: FileSystemWriteChunkType) {
const writable = await fileHandle.createWritable()
writable.write(data)
writable.close()
@@ -76,26 +76,26 @@ async function assertHashMatch(bytes: Uint8Array<ArrayBuffer>, hashFormat: HashF
}
}
export async function fetchPack(packUrl: Url, packDirectoryHandle:FileSystemDirectoryHandle) {
const {packMetaData,packFileName} = await fetch(packUrl).then(async response => {
export async function fetchPack(packUrl: Url, packDirectoryHandle: FileSystemDirectoryHandle) {
const { packMetaData, packFileName } = await fetch(packUrl).then(async response => {
const packFileText = await assertOK(response).text()
const packMetaData = parseTOML(packFileText) as PackMetaData
const packFileName = packUrl.split(pathSeperatorRegex).pop()
const packFileHandle = await getFileHandle(packDirectoryHandle, packFileName, {"create":true})
const packFileHandle = await getFileHandle(packDirectoryHandle, packFileName, { "create": true })
await writeFile(packFileHandle, packFileText)
return {packMetaData,packFileName}
return { packMetaData, packFileName }
})
const packIndexURL = new URL(packMetaData.index.file, packUrl)
const {packIndex,indexDirname} = await fetch(packIndexURL).then(async response => {
const { packIndex, indexDirname: packIndexDirname } = await fetch(packIndexURL).then(async response => {
const packIndexBytes = await assertOK(response).bytes()
assertHashMatch(packIndexBytes, packMetaData.index["hash-format"], packMetaData.index.hash)
const packIndex = parseTOML(packIndexBytes.toString()) as PackIndex
const packIndexFileHandle = await getFileHandle(packDirectoryHandle, packMetaData.index.file, { "create": true })
await writeFile(packIndexFileHandle, packIndexBytes)
const indexPathSegments = packIndexURL.pathname.split("/")
indexPathSegments.pop()
const indexDirname=indexPathSegments.join("/")
return {packIndex,indexDirname}
const packIndexPathSegments = packIndexURL.pathname.split("/")
packIndexPathSegments.pop()
const indexDirname = packIndexPathSegments.join("/")
return { packIndex, indexDirname }
})
const pack: PackwizPack = {
packDirectoryHandle,
@@ -109,9 +109,46 @@ export async function fetchPack(packUrl: Url, packDirectoryHandle:FileSystemDire
const fileBytes = await fetch(fileURL)
.then(response => assertOK(response).bytes())
assertHashMatch(fileBytes, entry["hash-format"] || packIndex["hash-format"], entry.hash)
const fileHandle = await getFileHandle(packDirectoryHandle, indexDirname + "/" + entry.file, { "create": true })
const fileHandle = await getFileHandle(packDirectoryHandle, packIndexDirname + "/" + entry.file, { "create": true })
await writeFile(fileHandle, fileBytes)
if (entry.metafile) pack.packFiles[entry.file]=parseTOML(fileBytes.toString())
if (entry.metafile) pack.packFiles[entry.file] = parseTOML(fileBytes.toString())
})
return pack
}
export async function loadPack(packDirectoryHandle: FileSystemDirectoryHandle, packFileName = "pack.toml") {
const packMetaData = await getFileHandle(packDirectoryHandle, packFileName).then(async packDirectoryHandle => {
const packFile = await packDirectoryHandle.getFile()
const packFileText = await packFile.text()
return parseTOML(packFileText) as PackMetaData
})
const { packIndex, packIndexDirname } = await getFileHandle(packDirectoryHandle, packMetaData.index.file).then(async indexFileHandle => {
const packIndexFile = await indexFileHandle.getFile()
const packIndexBytes = await packIndexFile.bytes()
if (!packMetaData.options || !packMetaData.options["no-internal-hashes"]) {
assertHashMatch(packIndexBytes, packMetaData.index["hash-format"], packMetaData.index.hash)
}
const packIndexPathSegments = packMetaData.index.file.split(pathSeperatorRegex)
packIndexPathSegments.pop()
const packIndexDirname = packIndexPathSegments.join("/")
const packIndex = parseTOML(packIndexBytes.toString()) as PackIndex
return { packIndex, packIndexDirname }
})
const pack: PackwizPack = {
packDirectoryHandle,
packFileName,
packMetaData,
packIndex,
packFiles: {}
}
await forAsync(packIndex.files, async entry => {
const fileHandle = await getFileHandle(packDirectoryHandle, packIndexDirname + "/" + entry.file)
const file = await fileHandle.getFile()
const fileBytes = await file.bytes()
if (!packMetaData.options || !packMetaData.options["no-internal-hashes"]) {
assertHashMatch(fileBytes,entry["hash-format"]||packIndex["hash-format"],entry.hash)
}
if (entry.metafile) pack.packFiles[entry.file] = parseTOML(fileBytes.toString())
})
return pack
}