/* * This file is part of TREB. * * TREB is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any * later version. * * TREB is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with TREB. If not, see . * * Copyright 2022-2026 trebco, llc. * info@treb.app * */ import UZip from 'uzip'; import Base64JS from 'base64-js'; export class ZipWrapper { public records: UZip.UZIPFiles; public text: Map = new Map(); public constructor(buffer: ArrayBuffer) { this.records = UZip.parse(buffer); } /** * check if entry exists */ public Has(path: string) { return this.text.has(path) || !!this.records?.[path]; } /** * nondestructive */ public ArrayBuffer() { const records: Record = {}; if (this.records) { for (const [key, value] of Object.entries(this.records)) { records[key] = new Uint8Array(value); } } const encoder = new TextEncoder(); for (const [key, value] of this.text.entries()) { records[key] = encoder.encode(value); } return UZip.encode(records); } /** * set a binary file. set this directly in the records table, * instead of the text table. */ public SetBinary(path: string, data: string, encoding?: 'base64'|'binary') { if (encoding === 'base64') { const bytes = Base64JS.toByteArray(data); this.records[path] = bytes; } else { throw new Error('unsupported encoding: ' + encoding); } } public Set(path: string, text: string) { this.text.set(path, text); if (this.records[path]) { delete this.records[path]; } } public GetBinary(path: string) { const data = this.records[path]; if (data) { return new Uint8Array(data); } throw new Error('path not in records: ' + path); } public Get(path: string) { let text = this.text.get(path); if (text) { return text; } const data = this.records[path]; if (data) { text = new TextDecoder().decode(data); this.text.set(path, text); delete this.records[path]; return text; } console.info(this); throw new Error('path not in zip file: ' + path); } }