{"version":3,"file":"tar.mjs","names":["createReadStream","Readable","Archive","Entry","PathType","itTar","streamFromBufferListGenerator","gen","r","read","next","then","done","value","push","slice","err","emit","EntryTar","sizeComp","atime","_readRsrc","constructor","info","archive","size","mode","uid","gid","uname","gname","mtime","linkname","ArchiveTar","FILE_EXTENSIONS","path","itter","_read","each","header","stream","type","FILE","SYMLINK","DIRECTORY","pathRaw","name","linknameBuffer","Buffer","from","readData","readSymlink","Error","length","entry","ret","trigger","cancel","input","extract","body","_decompress","destroy","chunk"],"sources":["../../src/archive/tar.ts"],"sourcesContent":["/* eslint-disable max-classes-per-file */\n\nimport {createReadStream} from 'node:fs';\nimport {Readable} from 'node:stream';\n\nimport {Archive, Entry, IEntryInfo} from '../archive.ts';\nimport {PathType} from '../types.ts';\n\n// Based on it-tar TarEntryHeader.\ninterface IHeader {\n\tname: string;\n\tuid: number;\n\tgid: number;\n\tsize: number;\n\tmode: number;\n\tmtime: Date;\n\ttype?: string;\n\ttypeflag?: number;\n\tlinkname?: string;\n\tuname?: string;\n\tgname?: string;\n}\n\ninterface IBufferList {\n\tslice: () => Buffer;\n}\n\n/**\n * Load it-tar, even in CommonJS.\n *\n * @returns The it-tar module.\n */\nconst itTar = async () =>\n\timport('it-tar' as string) as Promise<{\n\t\textract: () => (input: AsyncGenerator<Buffer>) => AsyncIterable<{\n\t\t\theader: IHeader;\n\t\t\tbody: AsyncGenerator<IBufferList>;\n\t\t}>;\n\t}>;\n\n/**\n * Create stream from a BufferList generator.\n *\n * @param gen BufferList generator.\n * @returns Readable stream.\n */\nconst streamFromBufferListGenerator = (gen: AsyncGenerator<IBufferList>) => {\n\tconst r = new Readable({\n\t\t/**\n\t\t * Read method.\n\t\t */\n\t\tread: () => {\n\t\t\tgen.next().then(\n\t\t\t\t({done, value}) => {\n\t\t\t\t\t// eslint-disable-next-line unicorn/prefer-spread\n\t\t\t\t\tr.push(done ? null : value.slice());\n\t\t\t\t},\n\t\t\t\terr => {\n\t\t\t\t\tr.emit('error', err);\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t});\n\treturn r;\n};\n\nexport interface IEntryInfoTar extends IEntryInfo {\n\t/**\n\t * @inheritdoc\n\t */\n\tarchive: ArchiveTar;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tsize: number;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tsizeComp?: null;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tmode: number;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuid: number;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tgid: number;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tuname?: string;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tgname?: string;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tatime?: null;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tmtime: Date;\n\n\t/**\n\t * Entry linkname if present.\n\t */\n\tlinkname: string | null;\n\n\t/**\n\t * @inheritdoc\n\t */\n\treadRsrc?: null;\n}\n\n/**\n * EntryTar object.\n */\nexport class EntryTar extends Entry {\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic readonly archive: ArchiveTar;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic readonly size: number;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic readonly sizeComp: null = null;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic readonly mode: number;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic readonly uid: number;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic readonly gid: number;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic readonly uname: string | null;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic readonly gname: string | null;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic readonly atime: null = null;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic readonly mtime: Date;\n\n\t/**\n\t * Entry linkname if present.\n\t */\n\tpublic readonly linkname: string | null;\n\n\t/**\n\t * @inheritdoc\n\t */\n\tprotected readonly _readRsrc: null = null;\n\n\t/**\n\t * EntryTar constructor.\n\t *\n\t * @param info Info object.\n\t */\n\tconstructor(info: Readonly<IEntryInfoTar>) {\n\t\tsuper(info);\n\n\t\tthis.archive = info.archive;\n\t\tthis.size = info.size;\n\t\tthis.mode = info.mode;\n\t\tthis.uid = info.uid;\n\t\tthis.gid = info.gid;\n\t\tthis.uname = info.uname ?? null;\n\t\tthis.gname = info.gname ?? null;\n\t\tthis.mtime = info.mtime;\n\t\tthis.linkname = info.linkname ?? null;\n\t}\n}\n\n/**\n * ArchiveTar object.\n */\nexport class ArchiveTar extends Archive {\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic static readonly FILE_EXTENSIONS: readonly string[] | null = ['.tar'];\n\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic readonly Entry = EntryTar;\n\n\t/**\n\t * ArchiveTar constructor.\n\t *\n\t * @param path File path.\n\t */\n\tconstructor(path: string) {\n\t\tsuper(path);\n\t}\n\n\t/**\n\t * @inheritdoc\n\t */\n\tpublic async read(itter: (entry: EntryTar) => Promise<unknown>) {\n\t\tawait super.read(itter as Parameters<Archive['read']>[0]);\n\t}\n\n\t/**\n\t * @inheritdoc\n\t */\n\tprotected async _read(itter: (entry: EntryTar) => Promise<unknown>) {\n\t\t/**\n\t\t * Each itterator.\n\t\t *\n\t\t * @param header Entry header.\n\t\t * @param stream Entry stream.\n\t\t * @returns Recursion hint.\n\t\t */\n\t\tconst each = async (header: IHeader, stream: () => Readable) => {\n\t\t\t// Check type, skip unsupported.\n\t\t\tlet type: PathType;\n\t\t\tswitch (header.type) {\n\t\t\t\tcase 'file': {\n\t\t\t\t\ttype = PathType.FILE;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'symlink': {\n\t\t\t\t\ttype = PathType.SYMLINK;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'directory': {\n\t\t\t\t\ttype = PathType.DIRECTORY;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// These values should always be set.\n\t\t\tconst pathRaw = header.name;\n\t\t\tlet {size} = header;\n\t\t\tconst {mode, uid, gid, mtime, uname, gname} = header;\n\n\t\t\t// Used for symbolic links, convert to a buffer.\n\t\t\tconst linkname = header.linkname ?? null;\n\t\t\tconst linknameBuffer =\n\t\t\t\tlinkname === null ? null : Buffer.from(linkname, 'utf8');\n\n\t\t\tconst readData =\n\t\t\t\ttype === PathType.FILE ? async () => stream() : null;\n\t\t\tconst readSymlink = linknameBuffer\n\t\t\t\t? async () => linknameBuffer\n\t\t\t\t: null;\n\n\t\t\t// If a symbolic link, make it the size of the link data, not 0.\n\t\t\tif (type === PathType.SYMLINK) {\n\t\t\t\tif (!linknameBuffer) {\n\t\t\t\t\tthrow new Error('Internal error');\n\t\t\t\t}\n\t\t\t\tsize = linknameBuffer.length;\n\t\t\t}\n\n\t\t\tconst entry = new this.Entry({\n\t\t\t\tarchive: this,\n\t\t\t\ttype,\n\t\t\t\tpathRaw,\n\t\t\t\tsize,\n\t\t\t\tmode,\n\t\t\t\tuid,\n\t\t\t\tgid,\n\t\t\t\tuname,\n\t\t\t\tgname,\n\t\t\t\tmtime,\n\t\t\t\tlinkname,\n\t\t\t\treadData,\n\t\t\t\treadSymlink\n\t\t\t});\n\t\t\tconst ret = await entry.trigger(itter);\n\t\t\treturn ret === false;\n\t\t};\n\n\t\tlet cancel = false;\n\t\tconst input = createReadStream(this.path);\n\t\tconst {extract} = await itTar();\n\t\tfor await (const {header, body} of extract()(\n\t\t\tthis._decompress(input as unknown as AsyncGenerator<Buffer>)\n\t\t)) {\n\t\t\t// Call handler for each, break off on cancel.\n\t\t\tcancel = await each(header, () =>\n\t\t\t\tstreamFromBufferListGenerator(body)\n\t\t\t);\n\t\t\tif (cancel) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Finish reading the body if not read, get to the next entry.\n\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\twhile (!(await body.next()).done) {\n\t\t\t\t// Do nothing.\n\t\t\t}\n\t\t}\n\n\t\tif (cancel) {\n\t\t\tinput.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * A async buffer generator to decopress if needed.\n\t *\n\t * @param input Buffer generator.\n\t * @yields Decompressed data.\n\t */\n\tprotected async *_decompress(input: AsyncGenerator<Buffer>) {\n\t\t// Plain tar files are not compressed, just pass data through.\n\t\tfor await (const chunk of input) {\n\t\t\tyield chunk;\n\t\t}\n\t}\n}\n"],"mappings":"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","ignoreList":[]}