formatting, loadPack
This commit is contained in:
+58
-21
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user