Files

48 lines
1.7 KiB
TypeScript

import * as zlib from "zlib"
const LOCAL_FILE_HEADER = 0x04034b50
const CENTRAL_DIRECTORY_HEADER = 0x02014b50
const END_OF_CENTRAL_DIRECTORY = 0x06054b50
const ZIP_VERSION = 20
const LOCAL_HEADER_SIZE = 30
const CENTRAL_ENTRY_SIZE = 46
const END_RECORD_SIZE = 22
export function storedZip(files: {[name: string]: string}): Buffer {
const local: Buffer[] = []
const central: Buffer[] = []
let offset = 0
for (const [name, content] of Object.entries(files)) {
const nameBuf = Buffer.from(name)
const data = Buffer.from(content)
const crc = zlib.crc32(data)
const header = Buffer.alloc(LOCAL_HEADER_SIZE)
header.writeUInt32LE(LOCAL_FILE_HEADER, 0)
header.writeUInt16LE(ZIP_VERSION, 4)
header.writeUInt32LE(crc, 14)
header.writeUInt32LE(data.length, 18)
header.writeUInt32LE(data.length, 22)
header.writeUInt16LE(nameBuf.length, 26)
local.push(header, nameBuf, data)
const entry = Buffer.alloc(CENTRAL_ENTRY_SIZE)
entry.writeUInt32LE(CENTRAL_DIRECTORY_HEADER, 0)
entry.writeUInt16LE(ZIP_VERSION, 4)
entry.writeUInt16LE(ZIP_VERSION, 6)
entry.writeUInt32LE(crc, 16)
entry.writeUInt32LE(data.length, 20)
entry.writeUInt32LE(data.length, 24)
entry.writeUInt16LE(nameBuf.length, 28)
entry.writeUInt32LE(offset, 42)
central.push(entry, nameBuf)
offset += header.length + nameBuf.length + data.length
}
const centralBuf = Buffer.concat(central)
const end = Buffer.alloc(END_RECORD_SIZE)
end.writeUInt32LE(END_OF_CENTRAL_DIRECTORY, 0)
end.writeUInt16LE(Object.keys(files).length, 8)
end.writeUInt16LE(Object.keys(files).length, 10)
end.writeUInt32LE(centralBuf.length, 12)
end.writeUInt32LE(offset, 16)
return Buffer.concat([...local, centralBuf, end])
}