grab-url 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- "use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let e=null;async function t(){if(e)return e;if("undefined"!=typeof process&&process?.versions?.node){if(!(await async function(){if("undefined"!=typeof navigator&&"Cloudflare-Workers"===navigator.userAgent)return!1;try{return require.resolve("libarchive.js"),!0}catch{}try{const{spawn:e}=await import("node:child_process");return await new Promise(t=>{const r=e("npm",["i","-g","libarchive.js"],{stdio:"ignore"});r.on("close",()=>t()),r.on("error",()=>t())}),!0}catch{return!1}}()))throw console.error("libarchive.js not available (install failed). Use browser fallback or manual npm i -g libarchive.js."),new Error("libarchive.js Node.js unavailable");const t=await import("libarchive.js/dist/libarchive-node.mjs");e=t.Archive}else{const t=await import("libarchive.js/main.js");e=t.Archive,e.init({workerUrl:"libarchive.js/dist/worker-bundle.js"})}return e}exports._setArchiveClass=function(t){e=t},exports.compress=async function(e){const{files:r,outputName:o,format:a="USTAR",compression:i="NONE",compressionLevel:n=6,passphrase:s}=e,c=r.map(({path:e,content:t})=>{let r;if("string"==typeof t)r=new Blob([t]);else if(t instanceof Uint8Array)r=new Blob([t]);else if(t instanceof ArrayBuffer)r=new Blob([t]);else{if(!(t instanceof Blob))throw new Error(`Unsupported content type for ${e}`);r=t}return{file:r,pathname:e}}),l=await t();return{blob:await l.write({files:c,outputFileName:o,compression:i,format:a,compressionLevel:n,passphrase:s||null}),mime:"application/zip",downloadName:o}},exports.extract=async function(e){const{archiveBuffer:r,folderPath:o="",password:a}=e;if(!r)throw new Error("Must provide archiveBuffer");const i=new Blob([new Uint8Array(r)]),n=await t(),s=await n.open(i);a&&await s.usePassword(a);const c=await s.getFilesObject(),l=[],p=async(e,t="")=>{for(const[r,a]of Object.entries(e)){const e=t?`${t}/${r}`:r;if(e.startsWith(o)&&!e.endsWith("/")){const t=e.slice(o.length).replace(/^\//,""),r=await a.extract();let i;try{i=await r.text()}catch{const e=await r.arrayBuffer();i=btoa(String.fromCharCode(...new Uint8Array(e)))}l.push({path:t,size:r.size,content:i,mime:r.type||"application/octet-stream"})}"object"!=typeof a||a?.extract||await p(a,e)}};return await p(c),l};
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("jszip");exports.compress=async function(t){const{files:r,outputName:o,compressionLevel:n=6}=t,i=new e;for(const{path:e,content:s}of r){let t;if("string"==typeof s)t=s;else if(s instanceof Uint8Array)t=s;else if(s instanceof ArrayBuffer)t=new Uint8Array(s);else{if(!(s instanceof Blob))throw new Error(`Unsupported content type for ${e}`);t=await s.arrayBuffer().then(e=>new Uint8Array(e))}i.file(e,t)}return{blob:await i.generateAsync({type:"blob",compression:"DEFLATE",compressionOptions:{level:n}}),mime:"application/zip",downloadName:o}},exports.extract=async function(t){const{archiveBuffer:r,folderPath:o="",password:n}=t;if(!r)throw new Error("Must provide archiveBuffer");if(n)throw new Error("Password-protected archives are not supported");const i=await e.loadAsync(r),s=[];for(const[e,a]of Object.entries(i.files)){if(a.dir)continue;if(o&&!e.startsWith(o))continue;const t=o?e.slice(o.length).replace(/^\//,""):e;if(!t)continue;let r;const n=await a.async("uint8array"),i=n.byteLength;try{r=await a.async("text")}catch{r=btoa(String.fromCharCode(...n))}s.push({path:t,size:i,content:r,mime:"application/octet-stream"})}return s};
2
2
  //# sourceMappingURL=archiver-web.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"archiver-web.cjs.js","sources":["../packages/archiver-web/src/index.ts"],"sourcesContent":["/**\r\n * Universal Archive Extractor & Creator using libarchive.js (WASM).\r\n * Supports: ZIP/7z/RAR4/5/TAR + GZIP/BZIP2/LZMA. Node.js/browser.\r\n * No streaming extract (full download first). Create archives from files.\r\n * @module archiveUtils\r\n * @example\r\n * const files = await extractFolder({ archiveUrl: 'https://ex.zip', folderPath: 'src/' });\r\n * const archiveBlob = await createArchive({ files: [...], outputName: 'out.tar.gz' });\r\n */\r\n\r\n\r\nlet ArchiveClass: any = null;\r\n\r\n/** @internal For testing: inject a mock Archive class. */\r\nexport function _setArchiveClass(cls: any) {\r\n ArchiveClass = cls;\r\n}\r\n\r\nasync function ensureLibarchiveNode(): Promise<boolean> {\r\n // Skip in Cloudflare Workers\r\n if (typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers') {\r\n return false;\r\n }\r\n\r\n // Check if already installed (silent resolve)\r\n try {\r\n require.resolve('libarchive.js');\r\n return true;\r\n } catch {}\r\n\r\n // Lazy load child_process and install globally\r\n let spawn: typeof import('child_process').spawn;\r\n try {\r\n const { spawn } = await import('node:child_process');\r\n await new Promise<void>((resolve) => {\r\n const proc = spawn('npm', ['i', '-g', 'libarchive.js'], { stdio: 'ignore' });\r\n proc.on('close', () => resolve());\r\n proc.on('error', () => resolve()); // npm unavailable: silent fail\r\n });\r\n return true;\r\n } catch {\r\n return false; // Silent fail if spawn/import fails\r\n }\r\n}\r\n\r\nasync function getArchive() {\r\n if (ArchiveClass) return ArchiveClass;\r\n\r\n if (typeof process !== 'undefined' && process?.versions?.node) {\r\n const installed = await ensureLibarchiveNode();\r\n if (!installed) {\r\n console.error('libarchive.js not available (install failed). Use browser fallback or manual npm i -g libarchive.js.');\r\n throw new Error('libarchive.js Node.js unavailable');\r\n }\r\n const mod = await import('libarchive.js/dist/libarchive-node.mjs');\r\n ArchiveClass = mod.Archive;\r\n } else {\r\n const mod = await import('libarchive.js/main.js');\r\n ArchiveClass = mod.Archive;\r\n ArchiveClass.init({\r\n workerUrl: 'libarchive.js/dist/worker-bundle.js'\r\n });\r\n }\r\n return ArchiveClass;\r\n}\r\n\r\n\r\nimport type { ExtractEvent, \r\n ArchiveCompression,\r\n ArchiveFormat,\r\n CreateOptions, \r\n ArchiveFile } from \"./types.js\";\r\n\r\n/**\r\n * Extract files from an archive ArrayBuffer.\r\n * @param options - Extract configuration\r\n * @param options.archiveBuffer - The archive to extract (ArrayBuffer)\r\n * @param options.folderPath - Folder to extract (e.g., 'src/'), empty=root\r\n * @param options.password - Optional password\r\n * @returns Array of extracted files\r\n * @throws Error on unsupported format\r\n */\r\nexport async function extract(options: {\r\n archiveBuffer: ArrayBuffer;\r\n folderPath?: string;\r\n password?: string;\r\n}): Promise<ExtractEvent[]> {\r\n const { archiveBuffer, folderPath = \"\", password } = options;\r\n\r\n if (!archiveBuffer) {\r\n throw new Error(\"Must provide archiveBuffer\");\r\n }\r\n const blob = new Blob([new Uint8Array(archiveBuffer)]);\r\n\r\n /** Open with libarchive.js */\r\n const Archive = await getArchive();\r\n const archive = await Archive.open(blob as File);\r\n if (password) await archive.usePassword(password);\r\n\r\n /** Get file tree */\r\n const filesObj = await archive.getFilesObject();\r\n const files: ExtractEvent[] = [];\r\n\r\n /**\r\n * Recursively walk file tree, filter by folderPath, extract matching files.\r\n * @param obj - Nested file/dir object\r\n * @param prefix - Current path prefix\r\n */\r\n const walker = async (obj: any, prefix: string = \"\"): Promise<void> => {\r\n for (const [name, entry] of Object.entries(obj)) {\r\n const fullPath = prefix ? `${prefix}/${name}` : name;\r\n if (fullPath.startsWith(folderPath) && !fullPath.endsWith(\"/\")) {\r\n const relativePath = fullPath\r\n .slice(folderPath.length)\r\n .replace(/^\\//, \"\");\r\n const fileBlob = await (entry as any).extract();\r\n let content: string;\r\n try {\r\n content = await fileBlob.text();\r\n } catch {\r\n const buffer = await fileBlob.arrayBuffer();\r\n content = btoa(String.fromCharCode(...new Uint8Array(buffer))); // Base64 binary\r\n }\r\n files.push({\r\n path: relativePath,\r\n size: fileBlob.size,\r\n content,\r\n mime: fileBlob.type || \"application/octet-stream\",\r\n });\r\n }\r\n if (typeof entry === 'object' && !(entry as any)?.extract) {\r\n // Subdir (directories don't have .extract, files do)\r\n await walker(entry, fullPath);\r\n }\r\n }\r\n };\r\n\r\n await walker(filesObj);\r\n return files;\r\n}\r\n\r\n\r\n\r\n/**\r\n * Create archive from files array.\r\n * @param options - Create configuration\r\n * @param options.files - Array of {path: string, content: string|Uint8Array|ArrayBuffer|Blob}\r\n * @param options.outputName - Archive filename (e.g., 'out.tar.gz')\r\n * @param options.format - Archive format (defaults USTAR)\r\n * @param options.compression - Compression (defaults NONE)\r\n * @param options.compressionLevel - 1-9 (defaults 6, format-dependent)\r\n * @param options.passphrase - Optional password\r\n * @returns Blob of archive (download/save as)\r\n * @throws Error on invalid options\r\n */\r\nexport async function compress(\r\n options: CreateOptions,\r\n): Promise<ArchiveFile> {\r\n const {\r\n files,\r\n outputName,\r\n format = \"USTAR\",\r\n compression = \"NONE\",\r\n compressionLevel = 6,\r\n passphrase,\r\n } = options;\r\n\r\n /** Convert files to Blobs with pathnames */\r\n const archiveFiles: { file: Blob; pathname: string }[] = files.map(\r\n ({ path, content }) => {\r\n let blobContent: Blob;\r\n if (typeof content === \"string\") {\r\n blobContent = new Blob([content]);\r\n } else if (content instanceof Uint8Array) {\r\n blobContent = new Blob([content as BlobPart]);\r\n } else if (content instanceof ArrayBuffer) {\r\n blobContent = new Blob([content]);\r\n } else if (content instanceof Blob) {\r\n blobContent = content;\r\n } else {\r\n throw new Error(`Unsupported content type for ${path}`);\r\n }\r\n return { file: blobContent, pathname: path };\r\n },\r\n );\r\n\r\n /** Create archive */\r\n const Archive = await getArchive();\r\n //@ts-ignore\r\n const archiveBlob = await Archive.write({\r\n files: archiveFiles,\r\n outputFileName: outputName,\r\n compression,\r\n format,\r\n compressionLevel, // Passed if supported\r\n passphrase: passphrase || null,\r\n });\r\n\r\n return {\r\n blob: archiveBlob,\r\n mime: \"application/zip\", // Adjust per format\r\n downloadName: outputName,\r\n };\r\n}\r\n\r\nexport type { ArchiveFormat, ArchiveCompression };\r\nexport type { ExtractEvent, CreateOptions, ArchiveFile };\r\n"],"names":["ArchiveClass","async","getArchive","process","versions","node","navigator","userAgent","require","resolve","spawn","import","Promise","proc","stdio","on","ensureLibarchiveNode","console","error","Error","mod","Archive","init","workerUrl","cls","options","files","outputName","format","compression","compressionLevel","passphrase","archiveFiles","map","path","content","blobContent","Blob","Uint8Array","ArrayBuffer","file","pathname","blob","write","outputFileName","mime","downloadName","archiveBuffer","folderPath","password","archive","open","usePassword","filesObj","getFilesObject","walker","obj","prefix","name","entry","Object","entries","fullPath","startsWith","endsWith","relativePath","slice","length","replace","fileBlob","extract","text","buffer","arrayBuffer","btoa","String","fromCharCode","push","size","type"],"mappings":"qOAWA,IAAIA,EAAoB,KAkCxBC,eAAeC,IACb,GAAIF,EAAc,OAAOA,EAEzB,GAAuB,oBAAZG,SAA2BA,SAASC,UAAUC,KAAM,CAE7D,WAhCJJ,iBAEE,GAAyB,oBAAdK,WAAqD,uBAAxBA,UAAUC,UAChD,OAAO,EAIT,IAEE,OADAC,QAAAC,QAAgB,kBACT,CACT,CAAA,MAAS,CAIT,IACE,MAAQC,MAAAA,SAAgBC,OAAO,sBAM/B,aALM,IAAIC,QAAeH,IACvB,MAAMI,EAAOH,EAAM,MAAO,CAAC,IAAK,KAAM,iBAAkB,CAAEI,MAAO,WACjED,EAAKE,GAAG,QAAS,IAAMN,KACvBI,EAAKE,GAAG,QAAS,IAAMN,QAElB,CACT,CAAA,MACE,OAAO,CACT,CACF,CAM4BO,IAGtB,MADAC,QAAQC,MAAM,wGACR,IAAIC,MAAM,qCAElB,MAAMC,QAAYT,OAAO,0CACzBX,EAAeoB,EAAIC,OACrB,KAAO,CACL,MAAMD,QAAYT,OAAO,yBACzBX,EAAeoB,EAAIC,QACnBrB,EAAasB,KAAK,CAChBC,UAAW,uCAEf,CACA,OAAOvB,CACT,0BAlDO,SAA0BwB,GAC/BxB,EAAewB,CACjB,mBA2IAvB,eACEwB,GAEA,MAAMC,MACJA,EAAAC,WACAA,EAAAC,OACAA,EAAS,QAAAC,YACTA,EAAc,OAAAC,iBACdA,EAAmB,EAAAC,WACnBA,GACEN,EAGEO,EAAmDN,EAAMO,IAC7D,EAAGC,OAAMC,cACP,IAAIC,EACJ,GAAuB,iBAAZD,EACTC,EAAc,IAAIC,KAAK,CAACF,SAC1B,GAAWA,aAAmBG,WAC5BF,EAAc,IAAIC,KAAK,CAACF,SAC1B,GAAWA,aAAmBI,YAC5BH,EAAc,IAAIC,KAAK,CAACF,QAC1B,MAAWA,aAAmBE,MAG5B,MAAM,IAAIlB,MAAM,gCAAgCe,KAFhDE,EAAcD,CAGhB,CACA,MAAO,CAAEK,KAAMJ,EAAaK,SAAUP,KAKpCb,QAAgBnB,IAWtB,MAAO,CACLwC,WAVwBrB,EAAQsB,MAAM,CACtCjB,MAAOM,EACPY,eAAgBjB,EAChBE,cACAD,SACAE,mBACAC,WAAYA,GAAc,OAK1Bc,KAAM,kBACNC,aAAcnB,EAElB,kBAzHA1B,eAA8BwB,GAK5B,MAAMsB,cAAEA,EAAAC,WAAeA,EAAa,GAAAC,SAAIA,GAAaxB,EAErD,IAAKsB,EACH,MAAM,IAAI5B,MAAM,8BAElB,MAAMuB,EAAO,IAAIL,KAAK,CAAC,IAAIC,WAAWS,KAGhC1B,QAAgBnB,IAChBgD,QAAgB7B,EAAQ8B,KAAKT,GAC/BO,SAAgBC,EAAQE,YAAYH,GAGxC,MAAMI,QAAiBH,EAAQI,iBACzB5B,EAAwB,GAOxB6B,EAAStD,MAAOuD,EAAUC,EAAiB,MAC/C,IAAA,MAAYC,EAAMC,KAAUC,OAAOC,QAAQL,GAAM,CAC/C,MAAMM,EAAWL,EAAS,GAAGA,KAAUC,IAASA,EAChD,GAAII,EAASC,WAAWf,KAAgBc,EAASE,SAAS,KAAM,CAC9D,MAAMC,EAAeH,EAClBI,MAAMlB,EAAWmB,QACjBC,QAAQ,MAAO,IACZC,QAAkBV,EAAcW,UACtC,IAAInC,EACJ,IACEA,QAAgBkC,EAASE,MAC3B,CAAA,MACE,MAAMC,QAAeH,EAASI,cAC9BtC,EAAUuC,KAAKC,OAAOC,gBAAgB,IAAItC,WAAWkC,IACvD,CACA9C,EAAMmD,KAAK,CACT3C,KAAM+B,EACNa,KAAMT,EAASS,KACf3C,UACAU,KAAMwB,EAASU,MAAQ,4BAE3B,CACqB,iBAAVpB,GAAwBA,GAAeW,eAE1Cf,EAAOI,EAAOG,EAExB,GAIF,aADMP,EAAOF,GACN3B,CACT"}
1
+ {"version":3,"file":"archiver-web.cjs.js","sources":["../packages/archiver-web/src/index.ts"],"sourcesContent":["/**\r\n * Universal Archive Extractor & Creator using JSZip (pure JS).\r\n * Supports ZIP format. Works in Node.js and browser with no WASM/workers.\r\n * @module archiveUtils\r\n * @example\r\n * const files = await extract({ archiveBuffer: buf, folderPath: 'src/' });\r\n * const archiveBlob = await compress({ files: [...], outputName: 'out.zip' });\r\n */\r\n\r\nimport JSZip from \"jszip\";\r\n\r\nimport type {\r\n ExtractEvent,\r\n CreateOptions,\r\n ArchiveFile,\r\n} from \"./types.js\";\r\n\r\n/**\r\n * Extract files from a ZIP ArrayBuffer.\r\n * @param options - Extract configuration\r\n * @param options.archiveBuffer - The archive to extract (ArrayBuffer)\r\n * @param options.folderPath - Folder to extract (e.g., 'src/'), empty=root\r\n * @param options.password - Optional password (not supported by JSZip - throws if provided)\r\n * @returns Array of extracted files\r\n */\r\nexport async function extract(options: {\r\n archiveBuffer: ArrayBuffer;\r\n folderPath?: string;\r\n password?: string;\r\n}): Promise<ExtractEvent[]> {\r\n const { archiveBuffer, folderPath = \"\", password } = options;\r\n\r\n if (!archiveBuffer) {\r\n throw new Error(\"Must provide archiveBuffer\");\r\n }\r\n\r\n if (password) {\r\n throw new Error(\"Password-protected archives are not supported\");\r\n }\r\n\r\n const zip = await JSZip.loadAsync(archiveBuffer);\r\n const files: ExtractEvent[] = [];\r\n\r\n for (const [relativePath, zipEntry] of Object.entries(zip.files)) {\r\n if (zipEntry.dir) continue;\r\n\r\n if (folderPath && !relativePath.startsWith(folderPath)) continue;\r\n\r\n const strippedPath = folderPath\r\n ? relativePath.slice(folderPath.length).replace(/^\\//, \"\")\r\n : relativePath;\r\n\r\n if (!strippedPath) continue;\r\n\r\n let content: string;\r\n const data = await zipEntry.async(\"uint8array\");\r\n const size = data.byteLength;\r\n\r\n try {\r\n content = await zipEntry.async(\"text\");\r\n } catch {\r\n content = btoa(String.fromCharCode(...data));\r\n }\r\n\r\n files.push({ path: strippedPath, size, content, mime: \"application/octet-stream\" });\r\n }\r\n\r\n return files;\r\n}\r\n\r\n/**\r\n * Create a ZIP archive from files array.\r\n * @param options - Create configuration\r\n * @param options.files - Array of {path, content} pairs\r\n * @param options.outputName - Archive filename (e.g., 'out.zip')\r\n * @param options.compressionLevel - 1-9 (defaults 6)\r\n * @returns Blob of archive\r\n */\r\nexport async function compress(options: CreateOptions): Promise<ArchiveFile> {\r\n const {\r\n files,\r\n outputName,\r\n compressionLevel = 6,\r\n } = options;\r\n\r\n const zip = new JSZip();\r\n\r\n for (const { path, content } of files) {\r\n let data: string | Uint8Array | ArrayBuffer | Blob;\r\n if (typeof content === \"string\") {\r\n data = content;\r\n } else if (content instanceof Uint8Array) {\r\n data = content;\r\n } else if (content instanceof ArrayBuffer) {\r\n data = new Uint8Array(content);\r\n } else if (content instanceof Blob) {\r\n data = await content.arrayBuffer().then((b) => new Uint8Array(b));\r\n } else {\r\n throw new Error(`Unsupported content type for ${path}`);\r\n }\r\n zip.file(path, data);\r\n }\r\n\r\n const blob = await zip.generateAsync({\r\n type: \"blob\",\r\n compression: \"DEFLATE\",\r\n compressionOptions: { level: compressionLevel },\r\n });\r\n\r\n return {\r\n blob,\r\n mime: \"application/zip\",\r\n downloadName: outputName,\r\n };\r\n}\r\n\r\nexport type { ExtractEvent, CreateOptions, ArchiveFile };\r\n"],"names":["async","options","files","outputName","compressionLevel","zip","JSZip","path","content","data","Uint8Array","ArrayBuffer","Blob","Error","arrayBuffer","then","b","file","blob","generateAsync","type","compression","compressionOptions","level","mime","downloadName","archiveBuffer","folderPath","password","loadAsync","relativePath","zipEntry","Object","entries","dir","startsWith","strippedPath","slice","length","replace","size","byteLength","btoa","String","fromCharCode","push"],"mappings":"0HA8EAA,eAA+BC,GAC7B,MAAMC,MACJA,EAAAC,WACAA,EAAAC,iBACAA,EAAmB,GACjBH,EAEEI,EAAM,IAAIC,EAEhB,IAAA,MAAWC,KAAEA,EAAAC,QAAMA,KAAaN,EAAO,CACrC,IAAIO,EACJ,GAAuB,iBAAZD,EACTC,EAAOD,OACT,GAAWA,aAAmBE,WAC5BD,EAAOD,OACT,GAAWA,aAAmBG,YAC5BF,EAAO,IAAIC,WAAWF,OACxB,MAAWA,aAAmBI,MAG5B,MAAM,IAAIC,MAAM,gCAAgCN,KAFhDE,QAAaD,EAAQM,cAAcC,KAAMC,GAAM,IAAIN,WAAWM,GAGhE,CACAX,EAAIY,KAAKV,EAAME,EACjB,CAQA,MAAO,CACLS,WAPiBb,EAAIc,cAAc,CACnCC,KAAM,OACNC,YAAa,UACbC,mBAAoB,CAAEC,MAAOnB,KAK7BoB,KAAM,kBACNC,aAActB,EAElB,kBAzFAH,eAA8BC,GAK5B,MAAMyB,cAAEA,EAAAC,WAAeA,EAAa,GAAAC,SAAIA,GAAa3B,EAErD,IAAKyB,EACH,MAAM,IAAIb,MAAM,8BAGlB,GAAIe,EACF,MAAM,IAAIf,MAAM,iDAGlB,MAAMR,QAAYC,EAAMuB,UAAUH,GAC5BxB,EAAwB,GAE9B,IAAA,MAAY4B,EAAcC,KAAaC,OAAOC,QAAQ5B,EAAIH,OAAQ,CAChE,GAAI6B,EAASG,IAAK,SAElB,GAAIP,IAAeG,EAAaK,WAAWR,GAAa,SAExD,MAAMS,EAAeT,EACjBG,EAAaO,MAAMV,EAAWW,QAAQC,QAAQ,MAAO,IACrDT,EAEJ,IAAKM,EAAc,SAEnB,IAAI5B,EACJ,MAAMC,QAAasB,EAAS/B,MAAM,cAC5BwC,EAAO/B,EAAKgC,WAElB,IACEjC,QAAgBuB,EAAS/B,MAAM,OACjC,CAAA,MACEQ,EAAUkC,KAAKC,OAAOC,gBAAgBnC,GACxC,CAEAP,EAAM2C,KAAK,CAAEtC,KAAM6B,EAAcI,OAAMhC,UAASgB,KAAM,4BACxD,CAEA,OAAOtB,CACT"}
@@ -1,5 +1,3 @@
1
- export declare type ArchiveCompression = "NONE" | "GZIP" | "BZIP2" | "LZMA" | "XZ";
2
-
3
1
  /**
4
2
  * Created archive result.
5
3
  */
@@ -12,24 +10,18 @@ export declare interface ArchiveFile {
12
10
  downloadName: string;
13
11
  }
14
12
 
15
- export declare type ArchiveFormat = "ZIP" | "USTAR" | "_7ZIP" | "RAW" | "XAR" | "CPIO_NEWC";
16
-
17
13
  /**
18
- * Create archive from files array.
14
+ * Create a ZIP archive from files array.
19
15
  * @param options - Create configuration
20
- * @param options.files - Array of {path: string, content: string|Uint8Array|ArrayBuffer|Blob}
21
- * @param options.outputName - Archive filename (e.g., 'out.tar.gz')
22
- * @param options.format - Archive format (defaults USTAR)
23
- * @param options.compression - Compression (defaults NONE)
24
- * @param options.compressionLevel - 1-9 (defaults 6, format-dependent)
25
- * @param options.passphrase - Optional password
26
- * @returns Blob of archive (download/save as)
27
- * @throws Error on invalid options
16
+ * @param options.files - Array of {path, content} pairs
17
+ * @param options.outputName - Archive filename (e.g., 'out.zip')
18
+ * @param options.compressionLevel - 1-9 (defaults 6)
19
+ * @returns Blob of archive
28
20
  */
29
21
  export declare function compress(options: CreateOptions): Promise<ArchiveFile>;
30
22
 
31
23
  /**
32
- * Options for createArchive.
24
+ * Options for compress().
33
25
  */
34
26
  export declare interface CreateOptions {
35
27
  /** Files to pack: path/content pairs */
@@ -37,26 +29,19 @@ export declare interface CreateOptions {
37
29
  path: string;
38
30
  content: string | Uint8Array | ArrayBuffer | Blob;
39
31
  }>;
40
- /** Output filename (.tar.gz etc.) */
32
+ /** Output filename (.zip) */
41
33
  outputName: string;
42
- /** Archive format */
43
- format?: ArchiveFormat;
44
- /** Compression type */
45
- compression?: ArchiveCompression;
46
- /** Compression level 1-9 */
34
+ /** Compression level 1-9 (default 6) */
47
35
  compressionLevel?: number;
48
- /** Password */
49
- passphrase?: string;
50
36
  }
51
37
 
52
38
  /**
53
- * Extract files from an archive ArrayBuffer.
39
+ * Extract files from a ZIP ArrayBuffer.
54
40
  * @param options - Extract configuration
55
41
  * @param options.archiveBuffer - The archive to extract (ArrayBuffer)
56
42
  * @param options.folderPath - Folder to extract (e.g., 'src/'), empty=root
57
- * @param options.password - Optional password
43
+ * @param options.password - Optional password (not supported by JSZip - throws if provided)
58
44
  * @returns Array of extracted files
59
- * @throws Error on unsupported format
60
45
  */
61
46
  export declare function extract(options: {
62
47
  archiveBuffer: ArrayBuffer;
@@ -78,6 +63,4 @@ export declare interface ExtractEvent {
78
63
  mime: string;
79
64
  }
80
65
 
81
- /* Excluded from this release type: _setArchiveClass */
82
-
83
66
  export { }
@@ -1,2 +1,2 @@
1
- let e=null;function t(t){e=t}async function r(){if(e)return e;if("undefined"!=typeof process&&process?.versions?.node){if(!(await async function(){if("undefined"!=typeof navigator&&"Cloudflare-Workers"===navigator.userAgent)return!1;try{return require.resolve("libarchive.js"),!0}catch{}try{const{spawn:e}=await import("node:child_process");return await new Promise(t=>{const r=e("npm",["i","-g","libarchive.js"],{stdio:"ignore"});r.on("close",()=>t()),r.on("error",()=>t())}),!0}catch{return!1}}()))throw console.error("libarchive.js not available (install failed). Use browser fallback or manual npm i -g libarchive.js."),new Error("libarchive.js Node.js unavailable");const t=await import("libarchive.js/dist/libarchive-node.mjs");e=t.Archive}else{const t=await import("libarchive.js/main.js");e=t.Archive,e.init({workerUrl:"libarchive.js/dist/worker-bundle.js"})}return e}async function i(e){const{archiveBuffer:t,folderPath:i="",password:a}=e;if(!t)throw new Error("Must provide archiveBuffer");const n=new Blob([new Uint8Array(t)]),o=await r(),s=await o.open(n);a&&await s.usePassword(a);const c=await s.getFilesObject(),l=[],f=async(e,t="")=>{for(const[r,a]of Object.entries(e)){const e=t?`${t}/${r}`:r;if(e.startsWith(i)&&!e.endsWith("/")){const t=e.slice(i.length).replace(/^\//,""),r=await a.extract();let n;try{n=await r.text()}catch{const e=await r.arrayBuffer();n=btoa(String.fromCharCode(...new Uint8Array(e)))}l.push({path:t,size:r.size,content:n,mime:r.type||"application/octet-stream"})}"object"!=typeof a||a?.extract||await f(a,e)}};return await f(c),l}async function a(e){const{files:t,outputName:i,format:a="USTAR",compression:n="NONE",compressionLevel:o=6,passphrase:s}=e,c=t.map(({path:e,content:t})=>{let r;if("string"==typeof t)r=new Blob([t]);else if(t instanceof Uint8Array)r=new Blob([t]);else if(t instanceof ArrayBuffer)r=new Blob([t]);else{if(!(t instanceof Blob))throw new Error(`Unsupported content type for ${e}`);r=t}return{file:r,pathname:e}}),l=await r();return{blob:await l.write({files:c,outputFileName:i,compression:n,format:a,compressionLevel:o,passphrase:s||null}),mime:"application/zip",downloadName:i}}export{t as _setArchiveClass,a as compress,i as extract};
1
+ import t from"jszip";async function e(e){const{archiveBuffer:n,folderPath:r="",password:o}=e;if(!n)throw new Error("Must provide archiveBuffer");if(o)throw new Error("Password-protected archives are not supported");const i=await t.loadAsync(n),a=[];for(const[t,s]of Object.entries(i.files)){if(s.dir)continue;if(r&&!t.startsWith(r))continue;const e=r?t.slice(r.length).replace(/^\//,""):t;if(!e)continue;let n;const o=await s.async("uint8array"),i=o.byteLength;try{n=await s.async("text")}catch{n=btoa(String.fromCharCode(...o))}a.push({path:e,size:i,content:n,mime:"application/octet-stream"})}return a}async function n(e){const{files:n,outputName:r,compressionLevel:o=6}=e,i=new t;for(const{path:t,content:a}of n){let e;if("string"==typeof a)e=a;else if(a instanceof Uint8Array)e=a;else if(a instanceof ArrayBuffer)e=new Uint8Array(a);else{if(!(a instanceof Blob))throw new Error(`Unsupported content type for ${t}`);e=await a.arrayBuffer().then(t=>new Uint8Array(t))}i.file(t,e)}return{blob:await i.generateAsync({type:"blob",compression:"DEFLATE",compressionOptions:{level:o}}),mime:"application/zip",downloadName:r}}export{n as compress,e as extract};
2
2
  //# sourceMappingURL=archiver-web.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"archiver-web.es.js","sources":["../packages/archiver-web/src/index.ts"],"sourcesContent":["/**\r\n * Universal Archive Extractor & Creator using libarchive.js (WASM).\r\n * Supports: ZIP/7z/RAR4/5/TAR + GZIP/BZIP2/LZMA. Node.js/browser.\r\n * No streaming extract (full download first). Create archives from files.\r\n * @module archiveUtils\r\n * @example\r\n * const files = await extractFolder({ archiveUrl: 'https://ex.zip', folderPath: 'src/' });\r\n * const archiveBlob = await createArchive({ files: [...], outputName: 'out.tar.gz' });\r\n */\r\n\r\n\r\nlet ArchiveClass: any = null;\r\n\r\n/** @internal For testing: inject a mock Archive class. */\r\nexport function _setArchiveClass(cls: any) {\r\n ArchiveClass = cls;\r\n}\r\n\r\nasync function ensureLibarchiveNode(): Promise<boolean> {\r\n // Skip in Cloudflare Workers\r\n if (typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers') {\r\n return false;\r\n }\r\n\r\n // Check if already installed (silent resolve)\r\n try {\r\n require.resolve('libarchive.js');\r\n return true;\r\n } catch {}\r\n\r\n // Lazy load child_process and install globally\r\n let spawn: typeof import('child_process').spawn;\r\n try {\r\n const { spawn } = await import('node:child_process');\r\n await new Promise<void>((resolve) => {\r\n const proc = spawn('npm', ['i', '-g', 'libarchive.js'], { stdio: 'ignore' });\r\n proc.on('close', () => resolve());\r\n proc.on('error', () => resolve()); // npm unavailable: silent fail\r\n });\r\n return true;\r\n } catch {\r\n return false; // Silent fail if spawn/import fails\r\n }\r\n}\r\n\r\nasync function getArchive() {\r\n if (ArchiveClass) return ArchiveClass;\r\n\r\n if (typeof process !== 'undefined' && process?.versions?.node) {\r\n const installed = await ensureLibarchiveNode();\r\n if (!installed) {\r\n console.error('libarchive.js not available (install failed). Use browser fallback or manual npm i -g libarchive.js.');\r\n throw new Error('libarchive.js Node.js unavailable');\r\n }\r\n const mod = await import('libarchive.js/dist/libarchive-node.mjs');\r\n ArchiveClass = mod.Archive;\r\n } else {\r\n const mod = await import('libarchive.js/main.js');\r\n ArchiveClass = mod.Archive;\r\n ArchiveClass.init({\r\n workerUrl: 'libarchive.js/dist/worker-bundle.js'\r\n });\r\n }\r\n return ArchiveClass;\r\n}\r\n\r\n\r\nimport type { ExtractEvent, \r\n ArchiveCompression,\r\n ArchiveFormat,\r\n CreateOptions, \r\n ArchiveFile } from \"./types.js\";\r\n\r\n/**\r\n * Extract files from an archive ArrayBuffer.\r\n * @param options - Extract configuration\r\n * @param options.archiveBuffer - The archive to extract (ArrayBuffer)\r\n * @param options.folderPath - Folder to extract (e.g., 'src/'), empty=root\r\n * @param options.password - Optional password\r\n * @returns Array of extracted files\r\n * @throws Error on unsupported format\r\n */\r\nexport async function extract(options: {\r\n archiveBuffer: ArrayBuffer;\r\n folderPath?: string;\r\n password?: string;\r\n}): Promise<ExtractEvent[]> {\r\n const { archiveBuffer, folderPath = \"\", password } = options;\r\n\r\n if (!archiveBuffer) {\r\n throw new Error(\"Must provide archiveBuffer\");\r\n }\r\n const blob = new Blob([new Uint8Array(archiveBuffer)]);\r\n\r\n /** Open with libarchive.js */\r\n const Archive = await getArchive();\r\n const archive = await Archive.open(blob as File);\r\n if (password) await archive.usePassword(password);\r\n\r\n /** Get file tree */\r\n const filesObj = await archive.getFilesObject();\r\n const files: ExtractEvent[] = [];\r\n\r\n /**\r\n * Recursively walk file tree, filter by folderPath, extract matching files.\r\n * @param obj - Nested file/dir object\r\n * @param prefix - Current path prefix\r\n */\r\n const walker = async (obj: any, prefix: string = \"\"): Promise<void> => {\r\n for (const [name, entry] of Object.entries(obj)) {\r\n const fullPath = prefix ? `${prefix}/${name}` : name;\r\n if (fullPath.startsWith(folderPath) && !fullPath.endsWith(\"/\")) {\r\n const relativePath = fullPath\r\n .slice(folderPath.length)\r\n .replace(/^\\//, \"\");\r\n const fileBlob = await (entry as any).extract();\r\n let content: string;\r\n try {\r\n content = await fileBlob.text();\r\n } catch {\r\n const buffer = await fileBlob.arrayBuffer();\r\n content = btoa(String.fromCharCode(...new Uint8Array(buffer))); // Base64 binary\r\n }\r\n files.push({\r\n path: relativePath,\r\n size: fileBlob.size,\r\n content,\r\n mime: fileBlob.type || \"application/octet-stream\",\r\n });\r\n }\r\n if (typeof entry === 'object' && !(entry as any)?.extract) {\r\n // Subdir (directories don't have .extract, files do)\r\n await walker(entry, fullPath);\r\n }\r\n }\r\n };\r\n\r\n await walker(filesObj);\r\n return files;\r\n}\r\n\r\n\r\n\r\n/**\r\n * Create archive from files array.\r\n * @param options - Create configuration\r\n * @param options.files - Array of {path: string, content: string|Uint8Array|ArrayBuffer|Blob}\r\n * @param options.outputName - Archive filename (e.g., 'out.tar.gz')\r\n * @param options.format - Archive format (defaults USTAR)\r\n * @param options.compression - Compression (defaults NONE)\r\n * @param options.compressionLevel - 1-9 (defaults 6, format-dependent)\r\n * @param options.passphrase - Optional password\r\n * @returns Blob of archive (download/save as)\r\n * @throws Error on invalid options\r\n */\r\nexport async function compress(\r\n options: CreateOptions,\r\n): Promise<ArchiveFile> {\r\n const {\r\n files,\r\n outputName,\r\n format = \"USTAR\",\r\n compression = \"NONE\",\r\n compressionLevel = 6,\r\n passphrase,\r\n } = options;\r\n\r\n /** Convert files to Blobs with pathnames */\r\n const archiveFiles: { file: Blob; pathname: string }[] = files.map(\r\n ({ path, content }) => {\r\n let blobContent: Blob;\r\n if (typeof content === \"string\") {\r\n blobContent = new Blob([content]);\r\n } else if (content instanceof Uint8Array) {\r\n blobContent = new Blob([content as BlobPart]);\r\n } else if (content instanceof ArrayBuffer) {\r\n blobContent = new Blob([content]);\r\n } else if (content instanceof Blob) {\r\n blobContent = content;\r\n } else {\r\n throw new Error(`Unsupported content type for ${path}`);\r\n }\r\n return { file: blobContent, pathname: path };\r\n },\r\n );\r\n\r\n /** Create archive */\r\n const Archive = await getArchive();\r\n //@ts-ignore\r\n const archiveBlob = await Archive.write({\r\n files: archiveFiles,\r\n outputFileName: outputName,\r\n compression,\r\n format,\r\n compressionLevel, // Passed if supported\r\n passphrase: passphrase || null,\r\n });\r\n\r\n return {\r\n blob: archiveBlob,\r\n mime: \"application/zip\", // Adjust per format\r\n downloadName: outputName,\r\n };\r\n}\r\n\r\nexport type { ArchiveFormat, ArchiveCompression };\r\nexport type { ExtractEvent, CreateOptions, ArchiveFile };\r\n"],"names":["ArchiveClass","_setArchiveClass","cls","async","getArchive","process","versions","node","navigator","userAgent","require","resolve","spawn","import","Promise","proc","stdio","on","ensureLibarchiveNode","console","error","Error","mod","Archive","init","workerUrl","extract","options","archiveBuffer","folderPath","password","blob","Blob","Uint8Array","archive","open","usePassword","filesObj","getFilesObject","files","walker","obj","prefix","name","entry","Object","entries","fullPath","startsWith","endsWith","relativePath","slice","length","replace","fileBlob","content","text","buffer","arrayBuffer","btoa","String","fromCharCode","push","path","size","mime","type","compress","outputName","format","compression","compressionLevel","passphrase","archiveFiles","map","blobContent","ArrayBuffer","file","pathname","write","outputFileName","downloadName"],"mappings":"AAWA,IAAIA,EAAoB,KAGjB,SAASC,EAAiBC,GAC/BF,EAAeE,CACjB,CA6BAC,eAAeC,IACb,GAAIJ,EAAc,OAAOA,EAEzB,GAAuB,oBAAZK,SAA2BA,SAASC,UAAUC,KAAM,CAE7D,WAhCJJ,iBAEE,GAAyB,oBAAdK,WAAqD,uBAAxBA,UAAUC,UAChD,OAAO,EAIT,IAEE,OADAC,QAAAC,QAAgB,kBACT,CACT,CAAA,MAAS,CAIT,IACE,MAAQC,MAAAA,SAAgBC,OAAO,sBAM/B,aALM,IAAIC,QAAeH,IACvB,MAAMI,EAAOH,EAAM,MAAO,CAAC,IAAK,KAAM,iBAAkB,CAAEI,MAAO,WACjED,EAAKE,GAAG,QAAS,IAAMN,KACvBI,EAAKE,GAAG,QAAS,IAAMN,QAElB,CACT,CAAA,MACE,OAAO,CACT,CACF,CAM4BO,IAGtB,MADAC,QAAQC,MAAM,wGACR,IAAIC,MAAM,qCAElB,MAAMC,QAAYT,OAAO,0CACzBb,EAAesB,EAAIC,OACrB,KAAO,CACL,MAAMD,QAAYT,OAAO,yBACzBb,EAAesB,EAAIC,QACnBvB,EAAawB,KAAK,CAChBC,UAAW,uCAEf,CACA,OAAOzB,CACT,CAkBAG,eAAsBuB,EAAQC,GAK5B,MAAMC,cAAEA,EAAAC,WAAeA,EAAa,GAAAC,SAAIA,GAAaH,EAErD,IAAKC,EACH,MAAM,IAAIP,MAAM,8BAElB,MAAMU,EAAO,IAAIC,KAAK,CAAC,IAAIC,WAAWL,KAGhCL,QAAgBnB,IAChB8B,QAAgBX,EAAQY,KAAKJ,GAC/BD,SAAgBI,EAAQE,YAAYN,GAGxC,MAAMO,QAAiBH,EAAQI,iBACzBC,EAAwB,GAOxBC,EAASrC,MAAOsC,EAAUC,EAAiB,MAC/C,IAAA,MAAYC,EAAMC,KAAUC,OAAOC,QAAQL,GAAM,CAC/C,MAAMM,EAAWL,EAAS,GAAGA,KAAUC,IAASA,EAChD,GAAII,EAASC,WAAWnB,KAAgBkB,EAASE,SAAS,KAAM,CAC9D,MAAMC,EAAeH,EAClBI,MAAMtB,EAAWuB,QACjBC,QAAQ,MAAO,IACZC,QAAkBV,EAAclB,UACtC,IAAI6B,EACJ,IACEA,QAAgBD,EAASE,MAC3B,CAAA,MACE,MAAMC,QAAeH,EAASI,cAC9BH,EAAUI,KAAKC,OAAOC,gBAAgB,IAAI5B,WAAWwB,IACvD,CACAlB,EAAMuB,KAAK,CACTC,KAAMb,EACNc,KAAMV,EAASU,KACfT,UACAU,KAAMX,EAASY,MAAQ,4BAE3B,CACqB,iBAAVtB,GAAwBA,GAAelB,eAE1Cc,EAAOI,EAAOG,EAExB,GAIF,aADMP,EAAOH,GACNE,CACT,CAgBApC,eAAsBgE,EACpBxC,GAEA,MAAMY,MACJA,EAAA6B,WACAA,EAAAC,OACAA,EAAS,QAAAC,YACTA,EAAc,OAAAC,iBACdA,EAAmB,EAAAC,WACnBA,GACE7C,EAGE8C,EAAmDlC,EAAMmC,IAC7D,EAAGX,OAAMR,cACP,IAAIoB,EACJ,GAAuB,iBAAZpB,EACToB,EAAc,IAAI3C,KAAK,CAACuB,SAC1B,GAAWA,aAAmBtB,WAC5B0C,EAAc,IAAI3C,KAAK,CAACuB,SAC1B,GAAWA,aAAmBqB,YAC5BD,EAAc,IAAI3C,KAAK,CAACuB,QAC1B,MAAWA,aAAmBvB,MAG5B,MAAM,IAAIX,MAAM,gCAAgC0C,KAFhDY,EAAcpB,CAGhB,CACA,MAAO,CAAEsB,KAAMF,EAAaG,SAAUf,KAKpCxC,QAAgBnB,IAWtB,MAAO,CACL2B,WAVwBR,EAAQwD,MAAM,CACtCxC,MAAOkC,EACPO,eAAgBZ,EAChBE,cACAD,SACAE,mBACAC,WAAYA,GAAc,OAK1BP,KAAM,kBACNgB,aAAcb,EAElB"}
1
+ {"version":3,"file":"archiver-web.es.js","sources":["../packages/archiver-web/src/index.ts"],"sourcesContent":["/**\r\n * Universal Archive Extractor & Creator using JSZip (pure JS).\r\n * Supports ZIP format. Works in Node.js and browser with no WASM/workers.\r\n * @module archiveUtils\r\n * @example\r\n * const files = await extract({ archiveBuffer: buf, folderPath: 'src/' });\r\n * const archiveBlob = await compress({ files: [...], outputName: 'out.zip' });\r\n */\r\n\r\nimport JSZip from \"jszip\";\r\n\r\nimport type {\r\n ExtractEvent,\r\n CreateOptions,\r\n ArchiveFile,\r\n} from \"./types.js\";\r\n\r\n/**\r\n * Extract files from a ZIP ArrayBuffer.\r\n * @param options - Extract configuration\r\n * @param options.archiveBuffer - The archive to extract (ArrayBuffer)\r\n * @param options.folderPath - Folder to extract (e.g., 'src/'), empty=root\r\n * @param options.password - Optional password (not supported by JSZip - throws if provided)\r\n * @returns Array of extracted files\r\n */\r\nexport async function extract(options: {\r\n archiveBuffer: ArrayBuffer;\r\n folderPath?: string;\r\n password?: string;\r\n}): Promise<ExtractEvent[]> {\r\n const { archiveBuffer, folderPath = \"\", password } = options;\r\n\r\n if (!archiveBuffer) {\r\n throw new Error(\"Must provide archiveBuffer\");\r\n }\r\n\r\n if (password) {\r\n throw new Error(\"Password-protected archives are not supported\");\r\n }\r\n\r\n const zip = await JSZip.loadAsync(archiveBuffer);\r\n const files: ExtractEvent[] = [];\r\n\r\n for (const [relativePath, zipEntry] of Object.entries(zip.files)) {\r\n if (zipEntry.dir) continue;\r\n\r\n if (folderPath && !relativePath.startsWith(folderPath)) continue;\r\n\r\n const strippedPath = folderPath\r\n ? relativePath.slice(folderPath.length).replace(/^\\//, \"\")\r\n : relativePath;\r\n\r\n if (!strippedPath) continue;\r\n\r\n let content: string;\r\n const data = await zipEntry.async(\"uint8array\");\r\n const size = data.byteLength;\r\n\r\n try {\r\n content = await zipEntry.async(\"text\");\r\n } catch {\r\n content = btoa(String.fromCharCode(...data));\r\n }\r\n\r\n files.push({ path: strippedPath, size, content, mime: \"application/octet-stream\" });\r\n }\r\n\r\n return files;\r\n}\r\n\r\n/**\r\n * Create a ZIP archive from files array.\r\n * @param options - Create configuration\r\n * @param options.files - Array of {path, content} pairs\r\n * @param options.outputName - Archive filename (e.g., 'out.zip')\r\n * @param options.compressionLevel - 1-9 (defaults 6)\r\n * @returns Blob of archive\r\n */\r\nexport async function compress(options: CreateOptions): Promise<ArchiveFile> {\r\n const {\r\n files,\r\n outputName,\r\n compressionLevel = 6,\r\n } = options;\r\n\r\n const zip = new JSZip();\r\n\r\n for (const { path, content } of files) {\r\n let data: string | Uint8Array | ArrayBuffer | Blob;\r\n if (typeof content === \"string\") {\r\n data = content;\r\n } else if (content instanceof Uint8Array) {\r\n data = content;\r\n } else if (content instanceof ArrayBuffer) {\r\n data = new Uint8Array(content);\r\n } else if (content instanceof Blob) {\r\n data = await content.arrayBuffer().then((b) => new Uint8Array(b));\r\n } else {\r\n throw new Error(`Unsupported content type for ${path}`);\r\n }\r\n zip.file(path, data);\r\n }\r\n\r\n const blob = await zip.generateAsync({\r\n type: \"blob\",\r\n compression: \"DEFLATE\",\r\n compressionOptions: { level: compressionLevel },\r\n });\r\n\r\n return {\r\n blob,\r\n mime: \"application/zip\",\r\n downloadName: outputName,\r\n };\r\n}\r\n\r\nexport type { ExtractEvent, CreateOptions, ArchiveFile };\r\n"],"names":["async","extract","options","archiveBuffer","folderPath","password","Error","zip","JSZip","loadAsync","files","relativePath","zipEntry","Object","entries","dir","startsWith","strippedPath","slice","length","replace","content","data","size","byteLength","btoa","String","fromCharCode","push","path","mime","compress","outputName","compressionLevel","Uint8Array","ArrayBuffer","Blob","arrayBuffer","then","b","file","blob","generateAsync","type","compression","compressionOptions","level","downloadName"],"mappings":"qBAyBAA,eAAsBC,EAAQC,GAK5B,MAAMC,cAAEA,EAAAC,WAAeA,EAAa,GAAAC,SAAIA,GAAaH,EAErD,IAAKC,EACH,MAAM,IAAIG,MAAM,8BAGlB,GAAID,EACF,MAAM,IAAIC,MAAM,iDAGlB,MAAMC,QAAYC,EAAMC,UAAUN,GAC5BO,EAAwB,GAE9B,IAAA,MAAYC,EAAcC,KAAaC,OAAOC,QAAQP,EAAIG,OAAQ,CAChE,GAAIE,EAASG,IAAK,SAElB,GAAIX,IAAeO,EAAaK,WAAWZ,GAAa,SAExD,MAAMa,EAAeb,EACjBO,EAAaO,MAAMd,EAAWe,QAAQC,QAAQ,MAAO,IACrDT,EAEJ,IAAKM,EAAc,SAEnB,IAAII,EACJ,MAAMC,QAAaV,EAASZ,MAAM,cAC5BuB,EAAOD,EAAKE,WAElB,IACEH,QAAgBT,EAASZ,MAAM,OACjC,CAAA,MACEqB,EAAUI,KAAKC,OAAOC,gBAAgBL,GACxC,CAEAZ,EAAMkB,KAAK,CAAEC,KAAMZ,EAAcM,OAAMF,UAASS,KAAM,4BACxD,CAEA,OAAOpB,CACT,CAUAV,eAAsB+B,EAAS7B,GAC7B,MAAMQ,MACJA,EAAAsB,WACAA,EAAAC,iBACAA,EAAmB,GACjB/B,EAEEK,EAAM,IAAIC,EAEhB,IAAA,MAAWqB,KAAEA,EAAAR,QAAMA,KAAaX,EAAO,CACrC,IAAIY,EACJ,GAAuB,iBAAZD,EACTC,EAAOD,OACT,GAAWA,aAAmBa,WAC5BZ,EAAOD,OACT,GAAWA,aAAmBc,YAC5Bb,EAAO,IAAIY,WAAWb,OACxB,MAAWA,aAAmBe,MAG5B,MAAM,IAAI9B,MAAM,gCAAgCuB,KAFhDP,QAAaD,EAAQgB,cAAcC,KAAMC,GAAM,IAAIL,WAAWK,GAGhE,CACAhC,EAAIiC,KAAKX,EAAMP,EACjB,CAQA,MAAO,CACLmB,WAPiBlC,EAAImC,cAAc,CACnCC,KAAM,OACNC,YAAa,UACbC,mBAAoB,CAAEC,MAAOb,KAK7BH,KAAM,kBACNiB,aAAcf,EAElB"}
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- "use strict";const e=require("util"),o=require("fs"),r=require("path"),t=require("./archiver-web.cjs.js");function s(e){const o=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const t=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(o,r,t.get?t:{enumerable:!0,get:()=>e[r]})}return o.default=e,Object.freeze(o)}const n=s(o),i=s(r);(async function(){const{values:o,positionals:r}=e.parseArgs({args:process.argv.slice(2),options:{format:{type:"string",short:"f",default:"ZIP"},compression:{type:"string",short:"c",default:"NONE"},out:{type:"string",short:"o"},password:{type:"string",short:"p"},help:{type:"boolean",short:"h"}},allowPositionals:!0});o.help&&(console.error("Usage: compress [files...] [options]"),console.error("If [files...] are omitted, reads from stdin."),console.error("Options:"),console.error(" -o, --out <file> Output file. If absent and not TTY, outputs to stdout."),console.error(" -f, --format <format> Format for archiving (default: ZIP)."),console.error(" -c, --compression <c> Compression type."),console.error(" -p, --password <pwd> Password for the archive."),process.exit(0));const s=[];if(r.length>0)for(let e=0;e<r.length;e++){const o=r[e];n.statSync(o).isDirectory()&&(console.error("Directory archiving not implemented for CLI basic args yet ("+o+")"),process.exit(1));const t=n.readFileSync(o);s.push({path:i.basename(o),content:new Blob([new Uint8Array(t)])})}else{process.stdin.isTTY&&(console.error("Error: Must provide files to archive or pipe input via stdin."),process.exit(1));const e=await async function(e){const o=[];for await(const r of e)o.push(Buffer.from(r));return Buffer.concat(o)}(process.stdin);s.push({path:"piped-content",content:new Blob([new Uint8Array(e)])})}const c=await t.compress({files:s,outputName:o.out?i.basename(o.out):"archive",format:o.format,compression:o.compression,passphrase:o.password}),a=Buffer.from(await c.blob.arrayBuffer());o.out?(n.writeFileSync(i.resolve(o.out),a),console.error("Created archive at "+o.out)):process.stdout.write(a)})().catch(e=>{console.error("Compress Error:",e),process.exit(1)});
2
+ "use strict";const e=require("util"),o=require("fs"),r=require("path"),t=require("./archiver-web.cjs.js");function s(e){const o=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const t=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(o,r,t.get?t:{enumerable:!0,get:()=>e[r]})}return o.default=e,Object.freeze(o)}const n=s(o),i=s(r);(async function(){const{values:o,positionals:r}=e.parseArgs({args:process.argv.slice(2),options:{out:{type:"string",short:"o"},level:{type:"string",short:"l",default:"6"},help:{type:"boolean",short:"h"}},allowPositionals:!0});o.help&&(console.error("Usage: compress [files...] [options]"),console.error("If [files...] are omitted, reads from stdin."),console.error("Options:"),console.error(" -o, --out <file> Output file. If absent and not TTY, outputs to stdout."),console.error(" -l, --level <1-9> Compression level (default: 6)."),process.exit(0));const s=[];if(r.length>0)for(const e of r){n.statSync(e).isDirectory()&&(console.error("Directory archiving not supported yet ("+e+")"),process.exit(1));const o=n.readFileSync(e);s.push({path:i.basename(e),content:new Blob([new Uint8Array(o)])})}else{process.stdin.isTTY&&(console.error("Error: Must provide files to archive or pipe input via stdin."),process.exit(1));const e=await async function(e){const o=[];for await(const r of e)o.push(Buffer.from(r));return Buffer.concat(o)}(process.stdin);s.push({path:"piped-content",content:new Blob([new Uint8Array(e)])})}const c=await t.compress({files:s,outputName:o.out?i.basename(o.out):"archive.zip",compressionLevel:parseInt(o.level||"6",10)}),a=Buffer.from(await c.blob.arrayBuffer());o.out?(n.writeFileSync(i.resolve(o.out),a),console.error("Created archive at "+o.out)):process.stdout.write(a)})().catch(e=>{console.error("Compress Error:",e),process.exit(1)});
3
3
  //# sourceMappingURL=bin-compress.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bin-compress.cjs.js","sources":["../packages/archiver-web/src/bin-compress.ts"],"sourcesContent":["\r\nimport { parseArgs } from \"util\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { compress } from \"./index.js\";\r\nimport { ArchiveFormat, ArchiveCompression } from \"./types.js\";\r\n\r\nasync function readStreamToBuffer(stream: NodeJS.ReadStream): Promise<Buffer> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stream) {\r\n chunks.push(Buffer.from(chunk));\r\n }\r\n return Buffer.concat(chunks);\r\n}\r\n\r\nasync function main() {\r\n const options = {\r\n format: { type: \"string\" as const, short: \"f\", default: \"ZIP\" },\r\n compression: { type: \"string\" as const, short: \"c\", default: \"NONE\" },\r\n out: { type: \"string\" as const, short: \"o\" },\r\n password: { type: \"string\" as const, short: \"p\" },\r\n help: { type: \"boolean\" as const, short: \"h\" }\r\n };\r\n\r\n const { values, positionals } = parseArgs({\r\n args: process.argv.slice(2),\r\n options,\r\n allowPositionals: true\r\n });\r\n\r\n if (values.help) {\r\n console.error(\"Usage: compress [files...] [options]\");\r\n console.error(\"If [files...] are omitted, reads from stdin.\");\r\n console.error(\"Options:\");\r\n console.error(\" -o, --out <file> Output file. If absent and not TTY, outputs to stdout.\");\r\n console.error(\" -f, --format <format> Format for archiving (default: ZIP).\");\r\n console.error(\" -c, --compression <c> Compression type.\");\r\n console.error(\" -p, --password <pwd> Password for the archive.\");\r\n process.exit(0);\r\n }\r\n\r\n const filesToArchive: Array<{ path: string; content: Blob | string }> = [];\r\n\r\n // If filenames are provided\r\n if (positionals.length > 0) {\r\n for (let i = 0; i < positionals.length; i++) {\r\n const filePath = positionals[i];\r\n const stat = fs.statSync(filePath);\r\n if (stat.isDirectory()) {\r\n console.error(\"Directory archiving not implemented for CLI basic args yet (\" + filePath + \")\");\r\n process.exit(1);\r\n }\r\n const buf = fs.readFileSync(filePath);\r\n filesToArchive.push({\r\n path: path.basename(filePath),\r\n content: new Blob([new Uint8Array(buf)])\r\n });\r\n }\r\n } else {\r\n // Read from stdin\r\n if (process.stdin.isTTY) {\r\n console.error(\"Error: Must provide files to archive or pipe input via stdin.\");\r\n process.exit(1);\r\n }\r\n const stdinBuffer = await readStreamToBuffer(process.stdin);\r\n filesToArchive.push({\r\n path: \"piped-content\", // generic name for piped data\r\n content: new Blob([new Uint8Array(stdinBuffer)])\r\n });\r\n }\r\n\r\n const archive = await compress({\r\n files: filesToArchive,\r\n outputName: values.out ? path.basename(values.out) : \"archive\",\r\n format: values.format as ArchiveFormat,\r\n compression: values.compression as ArchiveCompression,\r\n passphrase: values.password\r\n });\r\n\r\n const archiveBuffer = Buffer.from(await archive.blob.arrayBuffer());\r\n\r\n if (values.out) {\r\n fs.writeFileSync(path.resolve(values.out), archiveBuffer);\r\n console.error(\"Created archive at \" + values.out);\r\n } else {\r\n process.stdout.write(archiveBuffer);\r\n }\r\n}\r\n\r\nmain().catch((err) => {\r\n console.error(\"Compress Error:\", err);\r\n process.exit(1);\r\n});\r\n"],"names":["async","values","positionals","parseArgs","args","process","argv","slice","options","format","type","short","default","compression","out","password","help","allowPositionals","console","error","exit","filesToArchive","length","i","filePath","fs","statSync","isDirectory","buf","readFileSync","push","path","basename","content","Blob","Uint8Array","stdin","isTTY","stdinBuffer","stream","chunks","chunk","Buffer","from","concat","readStreamToBuffer","archive","compress","files","outputName","passphrase","archiveBuffer","blob","arrayBuffer","writeFileSync","resolve","stdout","write","main","catch","err"],"mappings":";0YAeAA,iBACE,MAQMC,OAAEA,EAAAC,YAAQA,GAAgBC,YAAU,CACxCC,KAAMC,QAAQC,KAAKC,MAAM,GACzBC,QAVc,CACdC,OAAQ,CAAEC,KAAM,SAAmBC,MAAO,IAAKC,QAAS,OACxDC,YAAa,CAAEH,KAAM,SAAmBC,MAAO,IAAKC,QAAS,QAC7DE,IAAK,CAAEJ,KAAM,SAAmBC,MAAO,KACvCI,SAAU,CAAEL,KAAM,SAAmBC,MAAO,KAC5CK,KAAM,CAAEN,KAAM,UAAoBC,MAAO,MAMzCM,kBAAkB,IAGhBhB,EAAOe,OACTE,QAAQC,MAAM,wCACdD,QAAQC,MAAM,gDACdD,QAAQC,MAAM,YACdD,QAAQC,MAAM,oFACdD,QAAQC,MAAM,kEACdD,QAAQC,MAAM,+CACdD,QAAQC,MAAM,uDACdd,QAAQe,KAAK,IAGf,MAAMC,EAAkE,GAGxE,GAAInB,EAAYoB,OAAS,EACvB,IAAA,IAASC,EAAI,EAAGA,EAAIrB,EAAYoB,OAAQC,IAAK,CACzC,MAAMC,EAAWtB,EAAYqB,GAChBE,EAAGC,SAASF,GAChBG,gBACLT,QAAQC,MAAM,+DAAiEK,EAAW,KAC1FnB,QAAQe,KAAK,IAEjB,MAAMQ,EAAMH,EAAGI,aAAaL,GAC5BH,EAAeS,KAAK,CAClBC,KAAMA,EAAKC,SAASR,GACpBS,QAAS,IAAIC,KAAK,CAAC,IAAIC,WAAWP,MAExC,KACK,CAEDvB,QAAQ+B,MAAMC,QAChBnB,QAAQC,MAAM,iEACdd,QAAQe,KAAK,IAEf,MAAMkB,QAzDVtC,eAAkCuC,GAChC,MAAMC,EAAmB,GACzB,UAAA,MAAiBC,KAASF,EACxBC,EAAOV,KAAKY,OAAOC,KAAKF,IAE1B,OAAOC,OAAOE,OAAOJ,EACvB,CAmD8BK,CAAmBxC,QAAQ+B,OACrDf,EAAeS,KAAK,CAClBC,KAAM,gBACNE,QAAS,IAAIC,KAAK,CAAC,IAAIC,WAAWG,MAEtC,CAEA,MAAMQ,QAAgBC,WAAS,CAC7BC,MAAO3B,EACP4B,WAAYhD,EAAOa,IAAMiB,EAAKC,SAAS/B,EAAOa,KAAO,UACrDL,OAAQR,EAAOQ,OACfI,YAAaZ,EAAOY,YACpBqC,WAAYjD,EAAOc,WAGfoC,EAAgBT,OAAOC,WAAWG,EAAQM,KAAKC,eAEjDpD,EAAOa,KACTW,EAAG6B,cAAcvB,EAAKwB,QAAQtD,EAAOa,KAAMqC,GAC3CjC,QAAQC,MAAM,sBAAwBlB,EAAOa,MAE7CT,QAAQmD,OAAOC,MAAMN,EAEzB,EAEAO,GAAOC,MAAOC,IACZ1C,QAAQC,MAAM,kBAAmByC,GACjCvD,QAAQe,KAAK"}
1
+ {"version":3,"file":"bin-compress.cjs.js","sources":["../packages/archiver-web/src/bin-compress.ts"],"sourcesContent":["import { parseArgs } from \"util\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { compress } from \"./index.js\";\r\n\r\nasync function readStreamToBuffer(stream: NodeJS.ReadStream): Promise<Buffer> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stream) {\r\n chunks.push(Buffer.from(chunk));\r\n }\r\n return Buffer.concat(chunks);\r\n}\r\n\r\nasync function main() {\r\n const options = {\r\n out: { type: \"string\" as const, short: \"o\" },\r\n level: { type: \"string\" as const, short: \"l\", default: \"6\" },\r\n help: { type: \"boolean\" as const, short: \"h\" },\r\n };\r\n\r\n const { values, positionals } = parseArgs({\r\n args: process.argv.slice(2),\r\n options,\r\n allowPositionals: true,\r\n });\r\n\r\n if (values.help) {\r\n console.error(\"Usage: compress [files...] [options]\");\r\n console.error(\"If [files...] are omitted, reads from stdin.\");\r\n console.error(\"Options:\");\r\n console.error(\" -o, --out <file> Output file. If absent and not TTY, outputs to stdout.\");\r\n console.error(\" -l, --level <1-9> Compression level (default: 6).\");\r\n process.exit(0);\r\n }\r\n\r\n const filesToArchive: Array<{ path: string; content: Blob | string }> = [];\r\n\r\n if (positionals.length > 0) {\r\n for (const filePath of positionals) {\r\n const stat = fs.statSync(filePath);\r\n if (stat.isDirectory()) {\r\n console.error(\"Directory archiving not supported yet (\" + filePath + \")\");\r\n process.exit(1);\r\n }\r\n const buf = fs.readFileSync(filePath);\r\n filesToArchive.push({\r\n path: path.basename(filePath),\r\n content: new Blob([new Uint8Array(buf)]),\r\n });\r\n }\r\n } else {\r\n if (process.stdin.isTTY) {\r\n console.error(\"Error: Must provide files to archive or pipe input via stdin.\");\r\n process.exit(1);\r\n }\r\n const stdinBuffer = await readStreamToBuffer(process.stdin);\r\n filesToArchive.push({\r\n path: \"piped-content\",\r\n content: new Blob([new Uint8Array(stdinBuffer)]),\r\n });\r\n }\r\n\r\n const archive = await compress({\r\n files: filesToArchive,\r\n outputName: values.out ? path.basename(values.out) : \"archive.zip\",\r\n compressionLevel: parseInt(values.level || \"6\", 10),\r\n });\r\n\r\n const archiveBuffer = Buffer.from(await archive.blob.arrayBuffer());\r\n\r\n if (values.out) {\r\n fs.writeFileSync(path.resolve(values.out), archiveBuffer);\r\n console.error(\"Created archive at \" + values.out);\r\n } else {\r\n process.stdout.write(archiveBuffer);\r\n }\r\n}\r\n\r\nmain().catch((err) => {\r\n console.error(\"Compress Error:\", err);\r\n process.exit(1);\r\n});\r\n"],"names":["async","values","positionals","parseArgs","args","process","argv","slice","options","out","type","short","level","default","help","allowPositionals","console","error","exit","filesToArchive","length","filePath","fs","statSync","isDirectory","buf","readFileSync","push","path","basename","content","Blob","Uint8Array","stdin","isTTY","stdinBuffer","stream","chunks","chunk","Buffer","from","concat","readStreamToBuffer","archive","compress","files","outputName","compressionLevel","parseInt","archiveBuffer","blob","arrayBuffer","writeFileSync","resolve","stdout","write","main","catch","err"],"mappings":";0YAaAA,iBACE,MAMMC,OAAEA,EAAAC,YAAQA,GAAgBC,YAAU,CACxCC,KAAMC,QAAQC,KAAKC,MAAM,GACzBC,QARc,CACdC,IAAK,CAAEC,KAAM,SAAmBC,MAAO,KACvCC,MAAO,CAAEF,KAAM,SAAmBC,MAAO,IAAKE,QAAS,KACvDC,KAAM,CAAEJ,KAAM,UAAoBC,MAAO,MAMzCI,kBAAkB,IAGhBd,EAAOa,OACTE,QAAQC,MAAM,wCACdD,QAAQC,MAAM,gDACdD,QAAQC,MAAM,YACdD,QAAQC,MAAM,oFACdD,QAAQC,MAAM,6DACdZ,QAAQa,KAAK,IAGf,MAAMC,EAAkE,GAExE,GAAIjB,EAAYkB,OAAS,EACvB,IAAA,MAAWC,KAAYnB,EAAa,CACrBoB,EAAGC,SAASF,GAChBG,gBACPR,QAAQC,MAAM,0CAA4CI,EAAW,KACrEhB,QAAQa,KAAK,IAEf,MAAMO,EAAMH,EAAGI,aAAaL,GAC5BF,EAAeQ,KAAK,CAClBC,KAAMA,EAAKC,SAASR,GACpBS,QAAS,IAAIC,KAAK,CAAC,IAAIC,WAAWP,MAEtC,KACK,CACDpB,QAAQ4B,MAAMC,QAChBlB,QAAQC,MAAM,iEACdZ,QAAQa,KAAK,IAEf,MAAMiB,QAlDVnC,eAAkCoC,GAChC,MAAMC,EAAmB,GACzB,UAAA,MAAiBC,KAASF,EACxBC,EAAOV,KAAKY,OAAOC,KAAKF,IAE1B,OAAOC,OAAOE,OAAOJ,EACvB,CA4C8BK,CAAmBrC,QAAQ4B,OACrDd,EAAeQ,KAAK,CAClBC,KAAM,gBACNE,QAAS,IAAIC,KAAK,CAAC,IAAIC,WAAWG,MAEtC,CAEA,MAAMQ,QAAgBC,WAAS,CAC7BC,MAAO1B,EACP2B,WAAY7C,EAAOQ,IAAMmB,EAAKC,SAAS5B,EAAOQ,KAAO,cACrDsC,iBAAkBC,SAAS/C,EAAOW,OAAS,IAAK,MAG5CqC,EAAgBV,OAAOC,WAAWG,EAAQO,KAAKC,eAEjDlD,EAAOQ,KACTa,EAAG8B,cAAcxB,EAAKyB,QAAQpD,EAAOQ,KAAMwC,GAC3CjC,QAAQC,MAAM,sBAAwBhB,EAAOQ,MAE7CJ,QAAQiD,OAAOC,MAAMN,EAEzB,EAEAO,GAAOC,MAAOC,IACZ1C,QAAQC,MAAM,kBAAmByC,GACjCrD,QAAQa,KAAK"}
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import{parseArgs as o}from"util";import*as r from"fs";import*as e from"path";import{compress as s}from"./archiver-web.es.js";(async function(){const{values:t,positionals:n}=o({args:process.argv.slice(2),options:{format:{type:"string",short:"f",default:"ZIP"},compression:{type:"string",short:"c",default:"NONE"},out:{type:"string",short:"o"},password:{type:"string",short:"p"},help:{type:"boolean",short:"h"}},allowPositionals:!0});t.help&&(console.error("Usage: compress [files...] [options]"),console.error("If [files...] are omitted, reads from stdin."),console.error("Options:"),console.error(" -o, --out <file> Output file. If absent and not TTY, outputs to stdout."),console.error(" -f, --format <format> Format for archiving (default: ZIP)."),console.error(" -c, --compression <c> Compression type."),console.error(" -p, --password <pwd> Password for the archive."),process.exit(0));const i=[];if(n.length>0)for(let o=0;o<n.length;o++){const s=n[o];r.statSync(s).isDirectory()&&(console.error("Directory archiving not implemented for CLI basic args yet ("+s+")"),process.exit(1));const t=r.readFileSync(s);i.push({path:e.basename(s),content:new Blob([new Uint8Array(t)])})}else{process.stdin.isTTY&&(console.error("Error: Must provide files to archive or pipe input via stdin."),process.exit(1));const o=await async function(o){const r=[];for await(const e of o)r.push(Buffer.from(e));return Buffer.concat(r)}(process.stdin);i.push({path:"piped-content",content:new Blob([new Uint8Array(o)])})}const a=await s({files:i,outputName:t.out?e.basename(t.out):"archive",format:t.format,compression:t.compression,passphrase:t.password}),c=Buffer.from(await a.blob.arrayBuffer());t.out?(r.writeFileSync(e.resolve(t.out),c),console.error("Created archive at "+t.out)):process.stdout.write(c)})().catch(o=>{console.error("Compress Error:",o),process.exit(1)});
2
+ import{parseArgs as o}from"util";import*as e from"fs";import*as r from"path";import{compress as t}from"./archiver-web.es.js";(async function(){const{values:s,positionals:n}=o({args:process.argv.slice(2),options:{out:{type:"string",short:"o"},level:{type:"string",short:"l",default:"6"},help:{type:"boolean",short:"h"}},allowPositionals:!0});s.help&&(console.error("Usage: compress [files...] [options]"),console.error("If [files...] are omitted, reads from stdin."),console.error("Options:"),console.error(" -o, --out <file> Output file. If absent and not TTY, outputs to stdout."),console.error(" -l, --level <1-9> Compression level (default: 6)."),process.exit(0));const i=[];if(n.length>0)for(const o of n){e.statSync(o).isDirectory()&&(console.error("Directory archiving not supported yet ("+o+")"),process.exit(1));const t=e.readFileSync(o);i.push({path:r.basename(o),content:new Blob([new Uint8Array(t)])})}else{process.stdin.isTTY&&(console.error("Error: Must provide files to archive or pipe input via stdin."),process.exit(1));const o=await async function(o){const e=[];for await(const r of o)e.push(Buffer.from(r));return Buffer.concat(e)}(process.stdin);i.push({path:"piped-content",content:new Blob([new Uint8Array(o)])})}const a=await t({files:i,outputName:s.out?r.basename(s.out):"archive.zip",compressionLevel:parseInt(s.level||"6",10)}),c=Buffer.from(await a.blob.arrayBuffer());s.out?(e.writeFileSync(r.resolve(s.out),c),console.error("Created archive at "+s.out)):process.stdout.write(c)})().catch(o=>{console.error("Compress Error:",o),process.exit(1)});
3
3
  //# sourceMappingURL=bin-compress.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bin-compress.es.js","sources":["../packages/archiver-web/src/bin-compress.ts"],"sourcesContent":["\r\nimport { parseArgs } from \"util\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { compress } from \"./index.js\";\r\nimport { ArchiveFormat, ArchiveCompression } from \"./types.js\";\r\n\r\nasync function readStreamToBuffer(stream: NodeJS.ReadStream): Promise<Buffer> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stream) {\r\n chunks.push(Buffer.from(chunk));\r\n }\r\n return Buffer.concat(chunks);\r\n}\r\n\r\nasync function main() {\r\n const options = {\r\n format: { type: \"string\" as const, short: \"f\", default: \"ZIP\" },\r\n compression: { type: \"string\" as const, short: \"c\", default: \"NONE\" },\r\n out: { type: \"string\" as const, short: \"o\" },\r\n password: { type: \"string\" as const, short: \"p\" },\r\n help: { type: \"boolean\" as const, short: \"h\" }\r\n };\r\n\r\n const { values, positionals } = parseArgs({\r\n args: process.argv.slice(2),\r\n options,\r\n allowPositionals: true\r\n });\r\n\r\n if (values.help) {\r\n console.error(\"Usage: compress [files...] [options]\");\r\n console.error(\"If [files...] are omitted, reads from stdin.\");\r\n console.error(\"Options:\");\r\n console.error(\" -o, --out <file> Output file. If absent and not TTY, outputs to stdout.\");\r\n console.error(\" -f, --format <format> Format for archiving (default: ZIP).\");\r\n console.error(\" -c, --compression <c> Compression type.\");\r\n console.error(\" -p, --password <pwd> Password for the archive.\");\r\n process.exit(0);\r\n }\r\n\r\n const filesToArchive: Array<{ path: string; content: Blob | string }> = [];\r\n\r\n // If filenames are provided\r\n if (positionals.length > 0) {\r\n for (let i = 0; i < positionals.length; i++) {\r\n const filePath = positionals[i];\r\n const stat = fs.statSync(filePath);\r\n if (stat.isDirectory()) {\r\n console.error(\"Directory archiving not implemented for CLI basic args yet (\" + filePath + \")\");\r\n process.exit(1);\r\n }\r\n const buf = fs.readFileSync(filePath);\r\n filesToArchive.push({\r\n path: path.basename(filePath),\r\n content: new Blob([new Uint8Array(buf)])\r\n });\r\n }\r\n } else {\r\n // Read from stdin\r\n if (process.stdin.isTTY) {\r\n console.error(\"Error: Must provide files to archive or pipe input via stdin.\");\r\n process.exit(1);\r\n }\r\n const stdinBuffer = await readStreamToBuffer(process.stdin);\r\n filesToArchive.push({\r\n path: \"piped-content\", // generic name for piped data\r\n content: new Blob([new Uint8Array(stdinBuffer)])\r\n });\r\n }\r\n\r\n const archive = await compress({\r\n files: filesToArchive,\r\n outputName: values.out ? path.basename(values.out) : \"archive\",\r\n format: values.format as ArchiveFormat,\r\n compression: values.compression as ArchiveCompression,\r\n passphrase: values.password\r\n });\r\n\r\n const archiveBuffer = Buffer.from(await archive.blob.arrayBuffer());\r\n\r\n if (values.out) {\r\n fs.writeFileSync(path.resolve(values.out), archiveBuffer);\r\n console.error(\"Created archive at \" + values.out);\r\n } else {\r\n process.stdout.write(archiveBuffer);\r\n }\r\n}\r\n\r\nmain().catch((err) => {\r\n console.error(\"Compress Error:\", err);\r\n process.exit(1);\r\n});\r\n"],"names":["async","values","positionals","parseArgs","args","process","argv","slice","options","format","type","short","default","compression","out","password","help","allowPositionals","console","error","exit","filesToArchive","length","i","filePath","fs","statSync","isDirectory","buf","readFileSync","push","path","basename","content","Blob","Uint8Array","stdin","isTTY","stdinBuffer","stream","chunks","chunk","Buffer","from","concat","readStreamToBuffer","archive","compress","files","outputName","passphrase","archiveBuffer","blob","arrayBuffer","writeFileSync","resolve","stdout","write","main","catch","err"],"mappings":";8HAeAA,iBACE,MAQMC,OAAEA,EAAAC,YAAQA,GAAgBC,EAAU,CACxCC,KAAMC,QAAQC,KAAKC,MAAM,GACzBC,QAVc,CACdC,OAAQ,CAAEC,KAAM,SAAmBC,MAAO,IAAKC,QAAS,OACxDC,YAAa,CAAEH,KAAM,SAAmBC,MAAO,IAAKC,QAAS,QAC7DE,IAAK,CAAEJ,KAAM,SAAmBC,MAAO,KACvCI,SAAU,CAAEL,KAAM,SAAmBC,MAAO,KAC5CK,KAAM,CAAEN,KAAM,UAAoBC,MAAO,MAMzCM,kBAAkB,IAGhBhB,EAAOe,OACTE,QAAQC,MAAM,wCACdD,QAAQC,MAAM,gDACdD,QAAQC,MAAM,YACdD,QAAQC,MAAM,oFACdD,QAAQC,MAAM,kEACdD,QAAQC,MAAM,+CACdD,QAAQC,MAAM,uDACdd,QAAQe,KAAK,IAGf,MAAMC,EAAkE,GAGxE,GAAInB,EAAYoB,OAAS,EACvB,IAAA,IAASC,EAAI,EAAGA,EAAIrB,EAAYoB,OAAQC,IAAK,CACzC,MAAMC,EAAWtB,EAAYqB,GAChBE,EAAGC,SAASF,GAChBG,gBACLT,QAAQC,MAAM,+DAAiEK,EAAW,KAC1FnB,QAAQe,KAAK,IAEjB,MAAMQ,EAAMH,EAAGI,aAAaL,GAC5BH,EAAeS,KAAK,CAClBC,KAAMA,EAAKC,SAASR,GACpBS,QAAS,IAAIC,KAAK,CAAC,IAAIC,WAAWP,MAExC,KACK,CAEDvB,QAAQ+B,MAAMC,QAChBnB,QAAQC,MAAM,iEACdd,QAAQe,KAAK,IAEf,MAAMkB,QAzDVtC,eAAkCuC,GAChC,MAAMC,EAAmB,GACzB,UAAA,MAAiBC,KAASF,EACxBC,EAAOV,KAAKY,OAAOC,KAAKF,IAE1B,OAAOC,OAAOE,OAAOJ,EACvB,CAmD8BK,CAAmBxC,QAAQ+B,OACrDf,EAAeS,KAAK,CAClBC,KAAM,gBACNE,QAAS,IAAIC,KAAK,CAAC,IAAIC,WAAWG,MAEtC,CAEA,MAAMQ,QAAgBC,EAAS,CAC7BC,MAAO3B,EACP4B,WAAYhD,EAAOa,IAAMiB,EAAKC,SAAS/B,EAAOa,KAAO,UACrDL,OAAQR,EAAOQ,OACfI,YAAaZ,EAAOY,YACpBqC,WAAYjD,EAAOc,WAGfoC,EAAgBT,OAAOC,WAAWG,EAAQM,KAAKC,eAEjDpD,EAAOa,KACTW,EAAG6B,cAAcvB,EAAKwB,QAAQtD,EAAOa,KAAMqC,GAC3CjC,QAAQC,MAAM,sBAAwBlB,EAAOa,MAE7CT,QAAQmD,OAAOC,MAAMN,EAEzB,EAEAO,GAAOC,MAAOC,IACZ1C,QAAQC,MAAM,kBAAmByC,GACjCvD,QAAQe,KAAK"}
1
+ {"version":3,"file":"bin-compress.es.js","sources":["../packages/archiver-web/src/bin-compress.ts"],"sourcesContent":["import { parseArgs } from \"util\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { compress } from \"./index.js\";\r\n\r\nasync function readStreamToBuffer(stream: NodeJS.ReadStream): Promise<Buffer> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stream) {\r\n chunks.push(Buffer.from(chunk));\r\n }\r\n return Buffer.concat(chunks);\r\n}\r\n\r\nasync function main() {\r\n const options = {\r\n out: { type: \"string\" as const, short: \"o\" },\r\n level: { type: \"string\" as const, short: \"l\", default: \"6\" },\r\n help: { type: \"boolean\" as const, short: \"h\" },\r\n };\r\n\r\n const { values, positionals } = parseArgs({\r\n args: process.argv.slice(2),\r\n options,\r\n allowPositionals: true,\r\n });\r\n\r\n if (values.help) {\r\n console.error(\"Usage: compress [files...] [options]\");\r\n console.error(\"If [files...] are omitted, reads from stdin.\");\r\n console.error(\"Options:\");\r\n console.error(\" -o, --out <file> Output file. If absent and not TTY, outputs to stdout.\");\r\n console.error(\" -l, --level <1-9> Compression level (default: 6).\");\r\n process.exit(0);\r\n }\r\n\r\n const filesToArchive: Array<{ path: string; content: Blob | string }> = [];\r\n\r\n if (positionals.length > 0) {\r\n for (const filePath of positionals) {\r\n const stat = fs.statSync(filePath);\r\n if (stat.isDirectory()) {\r\n console.error(\"Directory archiving not supported yet (\" + filePath + \")\");\r\n process.exit(1);\r\n }\r\n const buf = fs.readFileSync(filePath);\r\n filesToArchive.push({\r\n path: path.basename(filePath),\r\n content: new Blob([new Uint8Array(buf)]),\r\n });\r\n }\r\n } else {\r\n if (process.stdin.isTTY) {\r\n console.error(\"Error: Must provide files to archive or pipe input via stdin.\");\r\n process.exit(1);\r\n }\r\n const stdinBuffer = await readStreamToBuffer(process.stdin);\r\n filesToArchive.push({\r\n path: \"piped-content\",\r\n content: new Blob([new Uint8Array(stdinBuffer)]),\r\n });\r\n }\r\n\r\n const archive = await compress({\r\n files: filesToArchive,\r\n outputName: values.out ? path.basename(values.out) : \"archive.zip\",\r\n compressionLevel: parseInt(values.level || \"6\", 10),\r\n });\r\n\r\n const archiveBuffer = Buffer.from(await archive.blob.arrayBuffer());\r\n\r\n if (values.out) {\r\n fs.writeFileSync(path.resolve(values.out), archiveBuffer);\r\n console.error(\"Created archive at \" + values.out);\r\n } else {\r\n process.stdout.write(archiveBuffer);\r\n }\r\n}\r\n\r\nmain().catch((err) => {\r\n console.error(\"Compress Error:\", err);\r\n process.exit(1);\r\n});\r\n"],"names":["async","values","positionals","parseArgs","args","process","argv","slice","options","out","type","short","level","default","help","allowPositionals","console","error","exit","filesToArchive","length","filePath","fs","statSync","isDirectory","buf","readFileSync","push","path","basename","content","Blob","Uint8Array","stdin","isTTY","stdinBuffer","stream","chunks","chunk","Buffer","from","concat","readStreamToBuffer","archive","compress","files","outputName","compressionLevel","parseInt","archiveBuffer","blob","arrayBuffer","writeFileSync","resolve","stdout","write","main","catch","err"],"mappings":";8HAaAA,iBACE,MAMMC,OAAEA,EAAAC,YAAQA,GAAgBC,EAAU,CACxCC,KAAMC,QAAQC,KAAKC,MAAM,GACzBC,QARc,CACdC,IAAK,CAAEC,KAAM,SAAmBC,MAAO,KACvCC,MAAO,CAAEF,KAAM,SAAmBC,MAAO,IAAKE,QAAS,KACvDC,KAAM,CAAEJ,KAAM,UAAoBC,MAAO,MAMzCI,kBAAkB,IAGhBd,EAAOa,OACTE,QAAQC,MAAM,wCACdD,QAAQC,MAAM,gDACdD,QAAQC,MAAM,YACdD,QAAQC,MAAM,oFACdD,QAAQC,MAAM,6DACdZ,QAAQa,KAAK,IAGf,MAAMC,EAAkE,GAExE,GAAIjB,EAAYkB,OAAS,EACvB,IAAA,MAAWC,KAAYnB,EAAa,CACrBoB,EAAGC,SAASF,GAChBG,gBACPR,QAAQC,MAAM,0CAA4CI,EAAW,KACrEhB,QAAQa,KAAK,IAEf,MAAMO,EAAMH,EAAGI,aAAaL,GAC5BF,EAAeQ,KAAK,CAClBC,KAAMA,EAAKC,SAASR,GACpBS,QAAS,IAAIC,KAAK,CAAC,IAAIC,WAAWP,MAEtC,KACK,CACDpB,QAAQ4B,MAAMC,QAChBlB,QAAQC,MAAM,iEACdZ,QAAQa,KAAK,IAEf,MAAMiB,QAlDVnC,eAAkCoC,GAChC,MAAMC,EAAmB,GACzB,UAAA,MAAiBC,KAASF,EACxBC,EAAOV,KAAKY,OAAOC,KAAKF,IAE1B,OAAOC,OAAOE,OAAOJ,EACvB,CA4C8BK,CAAmBrC,QAAQ4B,OACrDd,EAAeQ,KAAK,CAClBC,KAAM,gBACNE,QAAS,IAAIC,KAAK,CAAC,IAAIC,WAAWG,MAEtC,CAEA,MAAMQ,QAAgBC,EAAS,CAC7BC,MAAO1B,EACP2B,WAAY7C,EAAOQ,IAAMmB,EAAKC,SAAS5B,EAAOQ,KAAO,cACrDsC,iBAAkBC,SAAS/C,EAAOW,OAAS,IAAK,MAG5CqC,EAAgBV,OAAOC,WAAWG,EAAQO,KAAKC,eAEjDlD,EAAOQ,KACTa,EAAG8B,cAAcxB,EAAKyB,QAAQpD,EAAOQ,KAAMwC,GAC3CjC,QAAQC,MAAM,sBAAwBhB,EAAOQ,MAE7CJ,QAAQiD,OAAOC,MAAMN,EAEzB,EAEAO,GAAOC,MAAOC,IACZ1C,QAAQC,MAAM,kBAAmByC,GACjCrD,QAAQa,KAAK"}
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- "use strict";const e=require("util"),t=require("fs"),r=require("path"),o=require("./archiver-web.cjs.js");function s(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const o=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,o.get?o:{enumerable:!0,get:()=>e[r]})}return t.default=e,Object.freeze(t)}const n=s(t),c=s(r);(async function(){const{values:t,positionals:r}=e.parseArgs({args:process.argv.slice(2),options:{out:{type:"string",short:"o"},password:{type:"string",short:"p"},folder:{type:"string",short:"d",default:""},help:{type:"boolean",short:"h"}},allowPositionals:!0});let s;if(t.help&&(console.error("Usage: extract [archive-file] [options]"),console.error("If [archive-file] is omitted, reads from stdin."),console.error("Options:"),console.error(" -o, --out <dir> Output directory. If absent, outputs to stdout (only works if 1 file)."),console.error(" -p, --password <pwd> Password for the archive."),console.error(" -d, --folder <dir> Folder to extract from archive."),process.exit(0)),r.length>0){const e=r[0];s=n.readFileSync(c.resolve(e))}else process.stdin.isTTY&&(console.error("Error: Must provide an archive file or pipe input via stdin."),process.exit(1)),s=await async function(e){const t=[];for await(const r of e)t.push(Buffer.from(r));return Buffer.concat(t)}(process.stdin);const i=s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength),f=await o.extract({archiveBuffer:i,folderPath:t.folder,password:t.password});if(t.out){for(const e of f){const r=c.join(t.out,e.path);let o;if(n.mkdirSync(c.dirname(r),{recursive:!0}),e.content.startsWith("data:")||e.content.match(/^[A-Za-z0-9+/=]+$/))try{o=Buffer.from(e.content,"base64")}catch{o=Buffer.from(e.content,"utf8")}else o=Buffer.from(e.content,"utf8");n.writeFileSync(r,o)}console.error("Extracted "+f.length+" files to "+t.out)}else if(1===f.length){let e;e=f[0].content.match(/^[A-Za-z0-9+/=]*$/)&&f[0].content.length>50?Buffer.from(f[0].content,"base64"):Buffer.from(f[0].content,"utf8"),process.stdout.write(e)}else console.error("Archive contains "+f.length+" files. Please specify -o/--out directory to extract them."),process.exit(1)})().catch(e=>{console.error("Extract Error:",e),process.exit(1)});
2
+ "use strict";const e=require("util"),t=require("fs"),r=require("path"),o=require("./archiver-web.cjs.js");function s(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const o=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,o.get?o:{enumerable:!0,get:()=>e[r]})}return t.default=e,Object.freeze(t)}const n=s(t),c=s(r);(async function(){const{values:t,positionals:r}=e.parseArgs({args:process.argv.slice(2),options:{out:{type:"string",short:"o"},folder:{type:"string",short:"d",default:""},help:{type:"boolean",short:"h"}},allowPositionals:!0});let s;t.help&&(console.error("Usage: extract [archive-file] [options]"),console.error("If [archive-file] is omitted, reads from stdin."),console.error("Options:"),console.error(" -o, --out <dir> Output directory. If absent, outputs to stdout (only works if 1 file)."),console.error(" -d, --folder <dir> Folder to extract from archive."),process.exit(0)),r.length>0?s=n.readFileSync(c.resolve(r[0])):(process.stdin.isTTY&&(console.error("Error: Must provide an archive file or pipe input via stdin."),process.exit(1)),s=await async function(e){const t=[];for await(const r of e)t.push(Buffer.from(r));return Buffer.concat(t)}(process.stdin));const i=s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength),f=await o.extract({archiveBuffer:i,folderPath:t.folder});if(t.out){for(const e of f){const r=c.join(t.out,e.path);let o;if(n.mkdirSync(c.dirname(r),{recursive:!0}),e.content.match(/^[A-Za-z0-9+/=]+$/)&&e.content.length>50)try{o=Buffer.from(e.content,"base64")}catch{o=Buffer.from(e.content,"utf8")}else o=Buffer.from(e.content,"utf8");n.writeFileSync(r,o)}console.error("Extracted "+f.length+" files to "+t.out)}else if(1===f.length){let e;e=f[0].content.match(/^[A-Za-z0-9+/=]*$/)&&f[0].content.length>50?Buffer.from(f[0].content,"base64"):Buffer.from(f[0].content,"utf8"),process.stdout.write(e)}else console.error("Archive contains "+f.length+" files. Please specify -o/--out directory to extract them."),process.exit(1)})().catch(e=>{console.error("Extract Error:",e),process.exit(1)});
3
3
  //# sourceMappingURL=bin-extract.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bin-extract.cjs.js","sources":["../packages/archiver-web/src/bin-extract.ts"],"sourcesContent":["\r\nimport { parseArgs } from \"util\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { extract } from \"./index.js\";\r\n\r\nasync function readStreamToBuffer(stream: NodeJS.ReadStream): Promise<Buffer> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stream) {\r\n chunks.push(Buffer.from(chunk));\r\n }\r\n return Buffer.concat(chunks);\r\n}\r\n\r\nasync function main() {\r\n const options = {\r\n out: { type: \"string\" as const, short: \"o\" },\r\n password: { type: \"string\" as const, short: \"p\" },\r\n folder: { type: \"string\" as const, short: \"d\", default: \"\" },\r\n help: { type: \"boolean\" as const, short: \"h\" }\r\n };\r\n\r\n const { values, positionals } = parseArgs({\r\n args: process.argv.slice(2),\r\n options,\r\n allowPositionals: true\r\n });\r\n\r\n if (values.help) {\r\n console.error(\"Usage: extract [archive-file] [options]\");\r\n console.error(\"If [archive-file] is omitted, reads from stdin.\");\r\n console.error(\"Options:\");\r\n console.error(\" -o, --out <dir> Output directory. If absent, outputs to stdout (only works if 1 file).\");\r\n console.error(\" -p, --password <pwd> Password for the archive.\");\r\n console.error(\" -d, --folder <dir> Folder to extract from archive.\");\r\n process.exit(0);\r\n }\r\n\r\n let archiveBuffer: Buffer;\r\n\r\n if (positionals.length > 0) {\r\n const inputFile = positionals[0];\r\n archiveBuffer = fs.readFileSync(path.resolve(inputFile));\r\n } else {\r\n // Read from stdin\r\n if (process.stdin.isTTY) {\r\n console.error(\"Error: Must provide an archive file or pipe input via stdin.\");\r\n process.exit(1);\r\n }\r\n archiveBuffer = await readStreamToBuffer(process.stdin);\r\n }\r\n\r\n const arrayBuf = archiveBuffer.buffer.slice(\r\n archiveBuffer.byteOffset,\r\n archiveBuffer.byteOffset + archiveBuffer.byteLength\r\n ) as ArrayBuffer;\r\n\r\n const files = await extract({\r\n archiveBuffer: arrayBuf,\r\n folderPath: values.folder,\r\n password: values.password\r\n });\r\n\r\n if (values.out) {\r\n for (const file of files) {\r\n const outPath = path.join(values.out, file.path);\r\n fs.mkdirSync(path.dirname(outPath), { recursive: true });\r\n let buf: Buffer;\r\n if (file.content.startsWith(\"data:\") || file.content.match(/^[A-Za-z0-9+/=]+$/)) {\r\n try {\r\n buf = Buffer.from(file.content, \"base64\");\r\n } catch {\r\n buf = Buffer.from(file.content, \"utf8\");\r\n }\r\n } else {\r\n buf = Buffer.from(file.content, \"utf8\");\r\n }\r\n fs.writeFileSync(outPath, buf);\r\n }\r\n console.error(\"Extracted \" + files.length + \" files to \" + values.out);\r\n } else {\r\n // Write to stdout\r\n if (files.length === 1) {\r\n let buf: Buffer;\r\n if (files[0].content.match(/^[A-Za-z0-9+/=]*$/) && files[0].content.length > 50) {\r\n buf = Buffer.from(files[0].content, \"base64\");\r\n } else {\r\n buf = Buffer.from(files[0].content, \"utf8\");\r\n }\r\n process.stdout.write(buf);\r\n } else {\r\n console.error(\"Archive contains \" + files.length + \" files. Please specify -o/--out directory to extract them.\");\r\n process.exit(1);\r\n }\r\n }\r\n}\r\n\r\nmain().catch((err) => {\r\n console.error(\"Extract Error:\", err);\r\n process.exit(1);\r\n});\r\n"],"names":["async","values","positionals","parseArgs","args","process","argv","slice","options","out","type","short","password","folder","default","help","allowPositionals","archiveBuffer","console","error","exit","length","inputFile","fs","readFileSync","path","resolve","stdin","isTTY","stream","chunks","chunk","push","Buffer","from","concat","readStreamToBuffer","arrayBuf","buffer","byteOffset","byteLength","files","extract","folderPath","file","outPath","join","buf","mkdirSync","dirname","recursive","content","startsWith","match","writeFileSync","stdout","write","main","catch","err"],"mappings":";0YAcAA,iBACE,MAOMC,OAAEA,EAAAC,YAAQA,GAAgBC,YAAU,CACxCC,KAAMC,QAAQC,KAAKC,MAAM,GACzBC,QATc,CACdC,IAAK,CAAEC,KAAM,SAAmBC,MAAO,KACvCC,SAAU,CAAEF,KAAM,SAAmBC,MAAO,KAC5CE,OAAQ,CAAEH,KAAM,SAAmBC,MAAO,IAAKG,QAAS,IACxDC,KAAM,CAAEL,KAAM,UAAoBC,MAAO,MAMzCK,kBAAkB,IAapB,IAAIC,EAEJ,GAZIhB,EAAOc,OACTG,QAAQC,MAAM,2CACdD,QAAQC,MAAM,mDACdD,QAAQC,MAAM,YACdD,QAAQC,MAAM,oGACdD,QAAQC,MAAM,uDACdD,QAAQC,MAAM,6DACdd,QAAQe,KAAK,IAKXlB,EAAYmB,OAAS,EAAG,CAC1B,MAAMC,EAAYpB,EAAY,GAC9Be,EAAgBM,EAAGC,aAAaC,EAAKC,QAAQJ,GAC/C,MAEMjB,QAAQsB,MAAMC,QAChBV,QAAQC,MAAM,gEACdd,QAAQe,KAAK,IAEfH,QA3CJjB,eAAkC6B,GAChC,MAAMC,EAAmB,GACzB,UAAA,MAAiBC,KAASF,EACxBC,EAAOE,KAAKC,OAAOC,KAAKH,IAE1B,OAAOE,OAAOE,OAAOL,EACvB,CAqC0BM,CAAmB/B,QAAQsB,OAGnD,MAAMU,EAAWpB,EAAcqB,OAAO/B,MACpCU,EAAcsB,WACdtB,EAAcsB,WAAatB,EAAcuB,YAGrCC,QAAcC,UAAQ,CAC1BzB,cAAeoB,EACfM,WAAY1C,EAAOY,OACnBD,SAAUX,EAAOW,WAGnB,GAAIX,EAAOQ,IAAK,CACd,IAAA,MAAWmC,KAAQH,EAAO,CACxB,MAAMI,EAAUpB,EAAKqB,KAAK7C,EAAOQ,IAAKmC,EAAKnB,MAE3C,IAAIsB,EACJ,GAFAxB,EAAGyB,UAAUvB,EAAKwB,QAAQJ,GAAU,CAAEK,WAAW,IAE7CN,EAAKO,QAAQC,WAAW,UAAYR,EAAKO,QAAQE,MAAM,qBACzD,IACGN,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,SACnC,CAAA,MACGJ,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,OACnC,MAEAJ,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,QAElC5B,EAAG+B,cAAcT,EAASE,EAC5B,CACA7B,QAAQC,MAAM,aAAesB,EAAMpB,OAAS,aAAepB,EAAOQ,IACpE,MAEE,GAAqB,IAAjBgC,EAAMpB,OAAc,CACtB,IAAI0B,EAEDA,EADCN,EAAM,GAAGU,QAAQE,MAAM,sBAAwBZ,EAAM,GAAGU,QAAQ9B,OAAS,GACpEY,OAAOC,KAAKO,EAAM,GAAGU,QAAS,UAE9BlB,OAAOC,KAAKO,EAAM,GAAGU,QAAS,QAEvC9C,QAAQkD,OAAOC,MAAMT,EACvB,MACE7B,QAAQC,MAAM,oBAAsBsB,EAAMpB,OAAS,8DACnDhB,QAAQe,KAAK,EAGnB,EAEAqC,GAAOC,MAAOC,IACZzC,QAAQC,MAAM,iBAAkBwC,GAChCtD,QAAQe,KAAK"}
1
+ {"version":3,"file":"bin-extract.cjs.js","sources":["../packages/archiver-web/src/bin-extract.ts"],"sourcesContent":["import { parseArgs } from \"util\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { extract } from \"./index.js\";\r\n\r\nasync function readStreamToBuffer(stream: NodeJS.ReadStream): Promise<Buffer> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stream) {\r\n chunks.push(Buffer.from(chunk));\r\n }\r\n return Buffer.concat(chunks);\r\n}\r\n\r\nasync function main() {\r\n const options = {\r\n out: { type: \"string\" as const, short: \"o\" },\r\n folder: { type: \"string\" as const, short: \"d\", default: \"\" },\r\n help: { type: \"boolean\" as const, short: \"h\" },\r\n };\r\n\r\n const { values, positionals } = parseArgs({\r\n args: process.argv.slice(2),\r\n options,\r\n allowPositionals: true,\r\n });\r\n\r\n if (values.help) {\r\n console.error(\"Usage: extract [archive-file] [options]\");\r\n console.error(\"If [archive-file] is omitted, reads from stdin.\");\r\n console.error(\"Options:\");\r\n console.error(\" -o, --out <dir> Output directory. If absent, outputs to stdout (only works if 1 file).\");\r\n console.error(\" -d, --folder <dir> Folder to extract from archive.\");\r\n process.exit(0);\r\n }\r\n\r\n let archiveBuffer: Buffer;\r\n\r\n if (positionals.length > 0) {\r\n archiveBuffer = fs.readFileSync(path.resolve(positionals[0]));\r\n } else {\r\n if (process.stdin.isTTY) {\r\n console.error(\"Error: Must provide an archive file or pipe input via stdin.\");\r\n process.exit(1);\r\n }\r\n archiveBuffer = await readStreamToBuffer(process.stdin);\r\n }\r\n\r\n const arrayBuf = archiveBuffer.buffer.slice(\r\n archiveBuffer.byteOffset,\r\n archiveBuffer.byteOffset + archiveBuffer.byteLength,\r\n ) as ArrayBuffer;\r\n\r\n const files = await extract({\r\n archiveBuffer: arrayBuf,\r\n folderPath: values.folder,\r\n });\r\n\r\n if (values.out) {\r\n for (const file of files) {\r\n const outPath = path.join(values.out, file.path);\r\n fs.mkdirSync(path.dirname(outPath), { recursive: true });\r\n let buf: Buffer;\r\n if (file.content.match(/^[A-Za-z0-9+/=]+$/) && file.content.length > 50) {\r\n try {\r\n buf = Buffer.from(file.content, \"base64\");\r\n } catch {\r\n buf = Buffer.from(file.content, \"utf8\");\r\n }\r\n } else {\r\n buf = Buffer.from(file.content, \"utf8\");\r\n }\r\n fs.writeFileSync(outPath, buf);\r\n }\r\n console.error(\"Extracted \" + files.length + \" files to \" + values.out);\r\n } else {\r\n if (files.length === 1) {\r\n let buf: Buffer;\r\n if (files[0].content.match(/^[A-Za-z0-9+/=]*$/) && files[0].content.length > 50) {\r\n buf = Buffer.from(files[0].content, \"base64\");\r\n } else {\r\n buf = Buffer.from(files[0].content, \"utf8\");\r\n }\r\n process.stdout.write(buf);\r\n } else {\r\n console.error(\"Archive contains \" + files.length + \" files. Please specify -o/--out directory to extract them.\");\r\n process.exit(1);\r\n }\r\n }\r\n}\r\n\r\nmain().catch((err) => {\r\n console.error(\"Extract Error:\", err);\r\n process.exit(1);\r\n});\r\n"],"names":["async","values","positionals","parseArgs","args","process","argv","slice","options","out","type","short","folder","default","help","allowPositionals","archiveBuffer","console","error","exit","length","fs","readFileSync","path","resolve","stdin","isTTY","stream","chunks","chunk","push","Buffer","from","concat","readStreamToBuffer","arrayBuf","buffer","byteOffset","byteLength","files","extract","folderPath","file","outPath","join","buf","mkdirSync","dirname","recursive","content","match","writeFileSync","stdout","write","main","catch","err"],"mappings":";0YAaAA,iBACE,MAMMC,OAAEA,EAAAC,YAAQA,GAAgBC,YAAU,CACxCC,KAAMC,QAAQC,KAAKC,MAAM,GACzBC,QARc,CACdC,IAAK,CAAEC,KAAM,SAAmBC,MAAO,KACvCC,OAAQ,CAAEF,KAAM,SAAmBC,MAAO,IAAKE,QAAS,IACxDC,KAAM,CAAEJ,KAAM,UAAoBC,MAAO,MAMzCI,kBAAkB,IAYpB,IAAIC,EATAf,EAAOa,OACTG,QAAQC,MAAM,2CACdD,QAAQC,MAAM,mDACdD,QAAQC,MAAM,YACdD,QAAQC,MAAM,oGACdD,QAAQC,MAAM,6DACdb,QAAQc,KAAK,IAKXjB,EAAYkB,OAAS,EACvBJ,EAAgBK,EAAGC,aAAaC,EAAKC,QAAQtB,EAAY,MAErDG,QAAQoB,MAAMC,QAChBT,QAAQC,MAAM,gEACdb,QAAQc,KAAK,IAEfH,QAvCJhB,eAAkC2B,GAChC,MAAMC,EAAmB,GACzB,UAAA,MAAiBC,KAASF,EACxBC,EAAOE,KAAKC,OAAOC,KAAKH,IAE1B,OAAOE,OAAOE,OAAOL,EACvB,CAiC0BM,CAAmB7B,QAAQoB,QAGnD,MAAMU,EAAWnB,EAAcoB,OAAO7B,MACpCS,EAAcqB,WACdrB,EAAcqB,WAAarB,EAAcsB,YAGrCC,QAAcC,UAAQ,CAC1BxB,cAAemB,EACfM,WAAYxC,EAAOW,SAGrB,GAAIX,EAAOQ,IAAK,CACd,IAAA,MAAWiC,KAAQH,EAAO,CACxB,MAAMI,EAAUpB,EAAKqB,KAAK3C,EAAOQ,IAAKiC,EAAKnB,MAE3C,IAAIsB,EACJ,GAFAxB,EAAGyB,UAAUvB,EAAKwB,QAAQJ,GAAU,CAAEK,WAAW,IAE7CN,EAAKO,QAAQC,MAAM,sBAAwBR,EAAKO,QAAQ7B,OAAS,GACnE,IACEyB,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,SAClC,CAAA,MACEJ,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,OAClC,MAEAJ,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,QAElC5B,EAAG8B,cAAcR,EAASE,EAC5B,CACA5B,QAAQC,MAAM,aAAeqB,EAAMnB,OAAS,aAAenB,EAAOQ,IACpE,MACE,GAAqB,IAAjB8B,EAAMnB,OAAc,CACtB,IAAIyB,EAEFA,EADEN,EAAM,GAAGU,QAAQC,MAAM,sBAAwBX,EAAM,GAAGU,QAAQ7B,OAAS,GACrEW,OAAOC,KAAKO,EAAM,GAAGU,QAAS,UAE9BlB,OAAOC,KAAKO,EAAM,GAAGU,QAAS,QAEtC5C,QAAQ+C,OAAOC,MAAMR,EACvB,MACE5B,QAAQC,MAAM,oBAAsBqB,EAAMnB,OAAS,8DACnDf,QAAQc,KAAK,EAGnB,EAEAmC,GAAOC,MAAOC,IACZvC,QAAQC,MAAM,iBAAkBsC,GAChCnD,QAAQc,KAAK"}
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import{parseArgs as e}from"util";import*as o from"fs";import*as t from"path";import{extract as r}from"./archiver-web.es.js";(async function(){const{values:s,positionals:n}=e({args:process.argv.slice(2),options:{out:{type:"string",short:"o"},password:{type:"string",short:"p"},folder:{type:"string",short:"d",default:""},help:{type:"boolean",short:"h"}},allowPositionals:!0});let i;if(s.help&&(console.error("Usage: extract [archive-file] [options]"),console.error("If [archive-file] is omitted, reads from stdin."),console.error("Options:"),console.error(" -o, --out <dir> Output directory. If absent, outputs to stdout (only works if 1 file)."),console.error(" -p, --password <pwd> Password for the archive."),console.error(" -d, --folder <dir> Folder to extract from archive."),process.exit(0)),n.length>0){const e=n[0];i=o.readFileSync(t.resolve(e))}else process.stdin.isTTY&&(console.error("Error: Must provide an archive file or pipe input via stdin."),process.exit(1)),i=await async function(e){const o=[];for await(const t of e)o.push(Buffer.from(t));return Buffer.concat(o)}(process.stdin);const c=i.buffer.slice(i.byteOffset,i.byteOffset+i.byteLength),f=await r({archiveBuffer:c,folderPath:s.folder,password:s.password});if(s.out){for(const e of f){const r=t.join(s.out,e.path);let n;if(o.mkdirSync(t.dirname(r),{recursive:!0}),e.content.startsWith("data:")||e.content.match(/^[A-Za-z0-9+/=]+$/))try{n=Buffer.from(e.content,"base64")}catch{n=Buffer.from(e.content,"utf8")}else n=Buffer.from(e.content,"utf8");o.writeFileSync(r,n)}console.error("Extracted "+f.length+" files to "+s.out)}else if(1===f.length){let e;e=f[0].content.match(/^[A-Za-z0-9+/=]*$/)&&f[0].content.length>50?Buffer.from(f[0].content,"base64"):Buffer.from(f[0].content,"utf8"),process.stdout.write(e)}else console.error("Archive contains "+f.length+" files. Please specify -o/--out directory to extract them."),process.exit(1)})().catch(e=>{console.error("Extract Error:",e),process.exit(1)});
2
+ import{parseArgs as e}from"util";import*as t from"fs";import*as o from"path";import{extract as r}from"./archiver-web.es.js";(async function(){const{values:s,positionals:n}=e({args:process.argv.slice(2),options:{out:{type:"string",short:"o"},folder:{type:"string",short:"d",default:""},help:{type:"boolean",short:"h"}},allowPositionals:!0});let i;s.help&&(console.error("Usage: extract [archive-file] [options]"),console.error("If [archive-file] is omitted, reads from stdin."),console.error("Options:"),console.error(" -o, --out <dir> Output directory. If absent, outputs to stdout (only works if 1 file)."),console.error(" -d, --folder <dir> Folder to extract from archive."),process.exit(0)),n.length>0?i=t.readFileSync(o.resolve(n[0])):(process.stdin.isTTY&&(console.error("Error: Must provide an archive file or pipe input via stdin."),process.exit(1)),i=await async function(e){const t=[];for await(const o of e)t.push(Buffer.from(o));return Buffer.concat(t)}(process.stdin));const c=i.buffer.slice(i.byteOffset,i.byteOffset+i.byteLength),f=await r({archiveBuffer:c,folderPath:s.folder});if(s.out){for(const e of f){const r=o.join(s.out,e.path);let n;if(t.mkdirSync(o.dirname(r),{recursive:!0}),e.content.match(/^[A-Za-z0-9+/=]+$/)&&e.content.length>50)try{n=Buffer.from(e.content,"base64")}catch{n=Buffer.from(e.content,"utf8")}else n=Buffer.from(e.content,"utf8");t.writeFileSync(r,n)}console.error("Extracted "+f.length+" files to "+s.out)}else if(1===f.length){let e;e=f[0].content.match(/^[A-Za-z0-9+/=]*$/)&&f[0].content.length>50?Buffer.from(f[0].content,"base64"):Buffer.from(f[0].content,"utf8"),process.stdout.write(e)}else console.error("Archive contains "+f.length+" files. Please specify -o/--out directory to extract them."),process.exit(1)})().catch(e=>{console.error("Extract Error:",e),process.exit(1)});
3
3
  //# sourceMappingURL=bin-extract.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bin-extract.es.js","sources":["../packages/archiver-web/src/bin-extract.ts"],"sourcesContent":["\r\nimport { parseArgs } from \"util\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { extract } from \"./index.js\";\r\n\r\nasync function readStreamToBuffer(stream: NodeJS.ReadStream): Promise<Buffer> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stream) {\r\n chunks.push(Buffer.from(chunk));\r\n }\r\n return Buffer.concat(chunks);\r\n}\r\n\r\nasync function main() {\r\n const options = {\r\n out: { type: \"string\" as const, short: \"o\" },\r\n password: { type: \"string\" as const, short: \"p\" },\r\n folder: { type: \"string\" as const, short: \"d\", default: \"\" },\r\n help: { type: \"boolean\" as const, short: \"h\" }\r\n };\r\n\r\n const { values, positionals } = parseArgs({\r\n args: process.argv.slice(2),\r\n options,\r\n allowPositionals: true\r\n });\r\n\r\n if (values.help) {\r\n console.error(\"Usage: extract [archive-file] [options]\");\r\n console.error(\"If [archive-file] is omitted, reads from stdin.\");\r\n console.error(\"Options:\");\r\n console.error(\" -o, --out <dir> Output directory. If absent, outputs to stdout (only works if 1 file).\");\r\n console.error(\" -p, --password <pwd> Password for the archive.\");\r\n console.error(\" -d, --folder <dir> Folder to extract from archive.\");\r\n process.exit(0);\r\n }\r\n\r\n let archiveBuffer: Buffer;\r\n\r\n if (positionals.length > 0) {\r\n const inputFile = positionals[0];\r\n archiveBuffer = fs.readFileSync(path.resolve(inputFile));\r\n } else {\r\n // Read from stdin\r\n if (process.stdin.isTTY) {\r\n console.error(\"Error: Must provide an archive file or pipe input via stdin.\");\r\n process.exit(1);\r\n }\r\n archiveBuffer = await readStreamToBuffer(process.stdin);\r\n }\r\n\r\n const arrayBuf = archiveBuffer.buffer.slice(\r\n archiveBuffer.byteOffset,\r\n archiveBuffer.byteOffset + archiveBuffer.byteLength\r\n ) as ArrayBuffer;\r\n\r\n const files = await extract({\r\n archiveBuffer: arrayBuf,\r\n folderPath: values.folder,\r\n password: values.password\r\n });\r\n\r\n if (values.out) {\r\n for (const file of files) {\r\n const outPath = path.join(values.out, file.path);\r\n fs.mkdirSync(path.dirname(outPath), { recursive: true });\r\n let buf: Buffer;\r\n if (file.content.startsWith(\"data:\") || file.content.match(/^[A-Za-z0-9+/=]+$/)) {\r\n try {\r\n buf = Buffer.from(file.content, \"base64\");\r\n } catch {\r\n buf = Buffer.from(file.content, \"utf8\");\r\n }\r\n } else {\r\n buf = Buffer.from(file.content, \"utf8\");\r\n }\r\n fs.writeFileSync(outPath, buf);\r\n }\r\n console.error(\"Extracted \" + files.length + \" files to \" + values.out);\r\n } else {\r\n // Write to stdout\r\n if (files.length === 1) {\r\n let buf: Buffer;\r\n if (files[0].content.match(/^[A-Za-z0-9+/=]*$/) && files[0].content.length > 50) {\r\n buf = Buffer.from(files[0].content, \"base64\");\r\n } else {\r\n buf = Buffer.from(files[0].content, \"utf8\");\r\n }\r\n process.stdout.write(buf);\r\n } else {\r\n console.error(\"Archive contains \" + files.length + \" files. Please specify -o/--out directory to extract them.\");\r\n process.exit(1);\r\n }\r\n }\r\n}\r\n\r\nmain().catch((err) => {\r\n console.error(\"Extract Error:\", err);\r\n process.exit(1);\r\n});\r\n"],"names":["async","values","positionals","parseArgs","args","process","argv","slice","options","out","type","short","password","folder","default","help","allowPositionals","archiveBuffer","console","error","exit","length","inputFile","fs","readFileSync","path","resolve","stdin","isTTY","stream","chunks","chunk","push","Buffer","from","concat","readStreamToBuffer","arrayBuf","buffer","byteOffset","byteLength","files","extract","folderPath","file","outPath","join","buf","mkdirSync","dirname","recursive","content","startsWith","match","writeFileSync","stdout","write","main","catch","err"],"mappings":";6HAcAA,iBACE,MAOMC,OAAEA,EAAAC,YAAQA,GAAgBC,EAAU,CACxCC,KAAMC,QAAQC,KAAKC,MAAM,GACzBC,QATc,CACdC,IAAK,CAAEC,KAAM,SAAmBC,MAAO,KACvCC,SAAU,CAAEF,KAAM,SAAmBC,MAAO,KAC5CE,OAAQ,CAAEH,KAAM,SAAmBC,MAAO,IAAKG,QAAS,IACxDC,KAAM,CAAEL,KAAM,UAAoBC,MAAO,MAMzCK,kBAAkB,IAapB,IAAIC,EAEJ,GAZIhB,EAAOc,OACTG,QAAQC,MAAM,2CACdD,QAAQC,MAAM,mDACdD,QAAQC,MAAM,YACdD,QAAQC,MAAM,oGACdD,QAAQC,MAAM,uDACdD,QAAQC,MAAM,6DACdd,QAAQe,KAAK,IAKXlB,EAAYmB,OAAS,EAAG,CAC1B,MAAMC,EAAYpB,EAAY,GAC9Be,EAAgBM,EAAGC,aAAaC,EAAKC,QAAQJ,GAC/C,MAEMjB,QAAQsB,MAAMC,QAChBV,QAAQC,MAAM,gEACdd,QAAQe,KAAK,IAEfH,QA3CJjB,eAAkC6B,GAChC,MAAMC,EAAmB,GACzB,UAAA,MAAiBC,KAASF,EACxBC,EAAOE,KAAKC,OAAOC,KAAKH,IAE1B,OAAOE,OAAOE,OAAOL,EACvB,CAqC0BM,CAAmB/B,QAAQsB,OAGnD,MAAMU,EAAWpB,EAAcqB,OAAO/B,MACpCU,EAAcsB,WACdtB,EAAcsB,WAAatB,EAAcuB,YAGrCC,QAAcC,EAAQ,CAC1BzB,cAAeoB,EACfM,WAAY1C,EAAOY,OACnBD,SAAUX,EAAOW,WAGnB,GAAIX,EAAOQ,IAAK,CACd,IAAA,MAAWmC,KAAQH,EAAO,CACxB,MAAMI,EAAUpB,EAAKqB,KAAK7C,EAAOQ,IAAKmC,EAAKnB,MAE3C,IAAIsB,EACJ,GAFAxB,EAAGyB,UAAUvB,EAAKwB,QAAQJ,GAAU,CAAEK,WAAW,IAE7CN,EAAKO,QAAQC,WAAW,UAAYR,EAAKO,QAAQE,MAAM,qBACzD,IACGN,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,SACnC,CAAA,MACGJ,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,OACnC,MAEAJ,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,QAElC5B,EAAG+B,cAAcT,EAASE,EAC5B,CACA7B,QAAQC,MAAM,aAAesB,EAAMpB,OAAS,aAAepB,EAAOQ,IACpE,MAEE,GAAqB,IAAjBgC,EAAMpB,OAAc,CACtB,IAAI0B,EAEDA,EADCN,EAAM,GAAGU,QAAQE,MAAM,sBAAwBZ,EAAM,GAAGU,QAAQ9B,OAAS,GACpEY,OAAOC,KAAKO,EAAM,GAAGU,QAAS,UAE9BlB,OAAOC,KAAKO,EAAM,GAAGU,QAAS,QAEvC9C,QAAQkD,OAAOC,MAAMT,EACvB,MACE7B,QAAQC,MAAM,oBAAsBsB,EAAMpB,OAAS,8DACnDhB,QAAQe,KAAK,EAGnB,EAEAqC,GAAOC,MAAOC,IACZzC,QAAQC,MAAM,iBAAkBwC,GAChCtD,QAAQe,KAAK"}
1
+ {"version":3,"file":"bin-extract.es.js","sources":["../packages/archiver-web/src/bin-extract.ts"],"sourcesContent":["import { parseArgs } from \"util\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { extract } from \"./index.js\";\r\n\r\nasync function readStreamToBuffer(stream: NodeJS.ReadStream): Promise<Buffer> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stream) {\r\n chunks.push(Buffer.from(chunk));\r\n }\r\n return Buffer.concat(chunks);\r\n}\r\n\r\nasync function main() {\r\n const options = {\r\n out: { type: \"string\" as const, short: \"o\" },\r\n folder: { type: \"string\" as const, short: \"d\", default: \"\" },\r\n help: { type: \"boolean\" as const, short: \"h\" },\r\n };\r\n\r\n const { values, positionals } = parseArgs({\r\n args: process.argv.slice(2),\r\n options,\r\n allowPositionals: true,\r\n });\r\n\r\n if (values.help) {\r\n console.error(\"Usage: extract [archive-file] [options]\");\r\n console.error(\"If [archive-file] is omitted, reads from stdin.\");\r\n console.error(\"Options:\");\r\n console.error(\" -o, --out <dir> Output directory. If absent, outputs to stdout (only works if 1 file).\");\r\n console.error(\" -d, --folder <dir> Folder to extract from archive.\");\r\n process.exit(0);\r\n }\r\n\r\n let archiveBuffer: Buffer;\r\n\r\n if (positionals.length > 0) {\r\n archiveBuffer = fs.readFileSync(path.resolve(positionals[0]));\r\n } else {\r\n if (process.stdin.isTTY) {\r\n console.error(\"Error: Must provide an archive file or pipe input via stdin.\");\r\n process.exit(1);\r\n }\r\n archiveBuffer = await readStreamToBuffer(process.stdin);\r\n }\r\n\r\n const arrayBuf = archiveBuffer.buffer.slice(\r\n archiveBuffer.byteOffset,\r\n archiveBuffer.byteOffset + archiveBuffer.byteLength,\r\n ) as ArrayBuffer;\r\n\r\n const files = await extract({\r\n archiveBuffer: arrayBuf,\r\n folderPath: values.folder,\r\n });\r\n\r\n if (values.out) {\r\n for (const file of files) {\r\n const outPath = path.join(values.out, file.path);\r\n fs.mkdirSync(path.dirname(outPath), { recursive: true });\r\n let buf: Buffer;\r\n if (file.content.match(/^[A-Za-z0-9+/=]+$/) && file.content.length > 50) {\r\n try {\r\n buf = Buffer.from(file.content, \"base64\");\r\n } catch {\r\n buf = Buffer.from(file.content, \"utf8\");\r\n }\r\n } else {\r\n buf = Buffer.from(file.content, \"utf8\");\r\n }\r\n fs.writeFileSync(outPath, buf);\r\n }\r\n console.error(\"Extracted \" + files.length + \" files to \" + values.out);\r\n } else {\r\n if (files.length === 1) {\r\n let buf: Buffer;\r\n if (files[0].content.match(/^[A-Za-z0-9+/=]*$/) && files[0].content.length > 50) {\r\n buf = Buffer.from(files[0].content, \"base64\");\r\n } else {\r\n buf = Buffer.from(files[0].content, \"utf8\");\r\n }\r\n process.stdout.write(buf);\r\n } else {\r\n console.error(\"Archive contains \" + files.length + \" files. Please specify -o/--out directory to extract them.\");\r\n process.exit(1);\r\n }\r\n }\r\n}\r\n\r\nmain().catch((err) => {\r\n console.error(\"Extract Error:\", err);\r\n process.exit(1);\r\n});\r\n"],"names":["async","values","positionals","parseArgs","args","process","argv","slice","options","out","type","short","folder","default","help","allowPositionals","archiveBuffer","console","error","exit","length","fs","readFileSync","path","resolve","stdin","isTTY","stream","chunks","chunk","push","Buffer","from","concat","readStreamToBuffer","arrayBuf","buffer","byteOffset","byteLength","files","extract","folderPath","file","outPath","join","buf","mkdirSync","dirname","recursive","content","match","writeFileSync","stdout","write","main","catch","err"],"mappings":";6HAaAA,iBACE,MAMMC,OAAEA,EAAAC,YAAQA,GAAgBC,EAAU,CACxCC,KAAMC,QAAQC,KAAKC,MAAM,GACzBC,QARc,CACdC,IAAK,CAAEC,KAAM,SAAmBC,MAAO,KACvCC,OAAQ,CAAEF,KAAM,SAAmBC,MAAO,IAAKE,QAAS,IACxDC,KAAM,CAAEJ,KAAM,UAAoBC,MAAO,MAMzCI,kBAAkB,IAYpB,IAAIC,EATAf,EAAOa,OACTG,QAAQC,MAAM,2CACdD,QAAQC,MAAM,mDACdD,QAAQC,MAAM,YACdD,QAAQC,MAAM,oGACdD,QAAQC,MAAM,6DACdb,QAAQc,KAAK,IAKXjB,EAAYkB,OAAS,EACvBJ,EAAgBK,EAAGC,aAAaC,EAAKC,QAAQtB,EAAY,MAErDG,QAAQoB,MAAMC,QAChBT,QAAQC,MAAM,gEACdb,QAAQc,KAAK,IAEfH,QAvCJhB,eAAkC2B,GAChC,MAAMC,EAAmB,GACzB,UAAA,MAAiBC,KAASF,EACxBC,EAAOE,KAAKC,OAAOC,KAAKH,IAE1B,OAAOE,OAAOE,OAAOL,EACvB,CAiC0BM,CAAmB7B,QAAQoB,QAGnD,MAAMU,EAAWnB,EAAcoB,OAAO7B,MACpCS,EAAcqB,WACdrB,EAAcqB,WAAarB,EAAcsB,YAGrCC,QAAcC,EAAQ,CAC1BxB,cAAemB,EACfM,WAAYxC,EAAOW,SAGrB,GAAIX,EAAOQ,IAAK,CACd,IAAA,MAAWiC,KAAQH,EAAO,CACxB,MAAMI,EAAUpB,EAAKqB,KAAK3C,EAAOQ,IAAKiC,EAAKnB,MAE3C,IAAIsB,EACJ,GAFAxB,EAAGyB,UAAUvB,EAAKwB,QAAQJ,GAAU,CAAEK,WAAW,IAE7CN,EAAKO,QAAQC,MAAM,sBAAwBR,EAAKO,QAAQ7B,OAAS,GACnE,IACEyB,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,SAClC,CAAA,MACEJ,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,OAClC,MAEAJ,EAAMd,OAAOC,KAAKU,EAAKO,QAAS,QAElC5B,EAAG8B,cAAcR,EAASE,EAC5B,CACA5B,QAAQC,MAAM,aAAeqB,EAAMnB,OAAS,aAAenB,EAAOQ,IACpE,MACE,GAAqB,IAAjB8B,EAAMnB,OAAc,CACtB,IAAIyB,EAEFA,EADEN,EAAM,GAAGU,QAAQC,MAAM,sBAAwBX,EAAM,GAAGU,QAAQ7B,OAAS,GACrEW,OAAOC,KAAKO,EAAM,GAAGU,QAAS,UAE9BlB,OAAOC,KAAKO,EAAM,GAAGU,QAAS,QAEtC5C,QAAQ+C,OAAOC,MAAMR,EACvB,MACE5B,QAAQC,MAAM,oBAAsBqB,EAAMnB,OAAS,8DACnDf,QAAQc,KAAK,EAGnB,EAEAmC,GAAOC,MAAOC,IACZvC,QAAQC,MAAM,iBAAkBsC,GAChCnD,QAAQc,KAAK"}
@@ -158,7 +158,7 @@ export declare interface GrabMockHandler<TParams = any, TResponse = any> {
158
158
  * @template TResponse The expected shape of the response data.
159
159
  * @template TParams The shape of the request parameters.
160
160
  */
161
- export declare type GrabOptions<TResponse = any, TParams = any> = TParams & {
161
+ export declare type GrabOptions<TResponse = any, TParams = any> = {
162
162
  /** include headers and authorization in the request */
163
163
  headers?: Record<string, string>;
164
164
  /** Pre-initialized object which becomes response JSON, no need for .data */
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- "use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("fs"),t=require("path"),o=require("url"),r=require("chalk"),a=require("cli-table3"),s=require("readline"),n=require("stream/promises"),l=require("stream"),i=require("cli-progress"),d=require("./grab-api.cjs.js"),c=require("@grab-url/log");var u="undefined"!=typeof document?document.currentScript:null;class p{commands={};options={};examples=[];helpText="";versionText="1.0.0";usage(e){return this.helpText=e,this}command(e,t,o){const r=e.match(/\$0 <(\w+)>/);return r&&(this.commands[r[1]]={desc:t,handler:o,required:!0}),this}option(e,t={}){return this.options[e]=t,this}example(e,t){return this.examples.push({cmd:e,desc:t}),this}help(){return this}alias(e,t){return this.options[t]&&(this.options[t].alias=e),this}version(e){return e&&(this.versionText=e),this}strict(){return this}parseSync(){const e=process.argv.slice(2),t={},o=[];(e.includes("--help")||e.includes("-h"))&&(this.showHelp(),process.exit(0)),e.includes("--version")&&(console.log(this.versionText),process.exit(0));for(let r=0;r<e.length;r++){const a=e[r];if(a.startsWith("--")){const[o,s]=a.split("="),n=o.slice(2);if(void 0!==s)t[n]=this.coerceValue(n,s);else if("boolean"===this.options[n]?.type)t[n]=!0;else{const o=e[r+1];o&&!o.startsWith("-")?(t[n]=this.coerceValue(n,o),r++):t[n]=!0}}else if(a.startsWith("-")&&2===a.length){const o=a[1],s=this.findLongName(o);if(s)if("boolean"===this.options[s]?.type)t[s]=!0;else{const o=e[r+1];o&&!o.startsWith("-")&&(t[s]=this.coerceValue(s,o),r++)}}else o.push(a)}return o.length>0&&(t.urls=o),Object.keys(this.options).forEach(e=>{void 0===t[e]&&void 0!==this.options[e].default&&(t[e]=this.options[e].default)}),t.urls&&0!==t.urls.length||!this.commands.url?.required||(console.error("Error: Missing required argument: url"),this.showHelp(),process.exit(1)),t}coerceValue(e,t){const o=this.options[e];if(!o)return t;if(o.coerce)return o.coerce(t);switch(o.type){case"number":return Number(t);case"boolean":return"true"===t||"1"===t;default:return t}}findLongName(e){return Object.keys(this.options).find(t=>this.options[t].alias===e)}showHelp(){console.log(this.helpText||"Usage: grab-url <url> [options]"),console.log("\nPositional arguments:"),Object.keys(this.commands).forEach(e=>{console.log(` ${e.padEnd(20)} ${this.commands[e].desc}`)}),console.log("\nOptions:"),Object.keys(this.options).forEach(e=>{const t=this.options[e],o=t.alias?`-${t.alias}, --${e}`:`--${e}`;console.log(` ${o.padEnd(20)} ${t.describe||""}`)}),this.examples.length>0&&(console.log("\nExamples:"),this.examples.forEach(e=>{console.log(` ${e.cmd}`),console.log(` ${e.desc}`)}))}}function h(e){return/\.[a-zA-Z0-9]{1,5}(?:\.[a-zA-Z0-9]{1,5})*$/.test(e.split("?")[0])}const g=15,m={primary:r.cyan,success:r.green,warning:r.yellow,error:r.red,info:r.blue,purple:r.magenta,pink:r.magentaBright,yellow:r.yellowBright,cyan:r.cyanBright,green:r.green,red:r.red,gradient:[r.blue,r.magenta,r.cyan,r.green,r.yellow,r.red]};function f(e,t=2){if(0===e)return m.info("0 B");const o=Math.max(t,0),r=[{unit:"B",color:m.info},{unit:"KB",color:m.cyan},{unit:"MB",color:m.yellow},{unit:"GB",color:m.purple},{unit:"TB",color:m.pink},{unit:"PB",color:m.primary}],a=Math.floor(Math.log(e)/Math.log(1024)),s=parseFloat((e/Math.pow(1024,a)).toFixed(o)),n=r[a]??r[r.length-1];return n.color.bold(`${s} ${n.unit}`)}function y(e){if(0===e)return"0B";const t=1024,o=e/t;return o<100?`${Math.round(o)}KB`:`${(e/(t*t)).toFixed(1)}`}function w(e,o=25){if(e.length<=o)return e.padEnd(o);const r=t.extname(e),a=t.basename(e,r);if(a.length<=3)return e.padEnd(o);const s=Math.ceil((o-r.length-3)/2),n=Math.floor((o-r.length-3)/2);return`${a.slice(0,s)+"..."+a.slice(-n)}${r}`.padEnd(o)}function b(e,t=10){if(!e||!isFinite(e)||e<0)return" -- ";const o=Math.floor(e/3600),r=Math.floor(e%3600/60),a=Math.round(e%60);return`${o}:${String(r).padStart(2,"0")}:${String(a).padStart(2,"0")}`.padEnd(t)}function S(e,t,o=16){const r=1024,a=e/(r*r);return t/(r*r)>=1024?`${(a/1024).toFixed(1)}GB`.padEnd(o):`${a.toFixed(1)}MB`.padEnd(o)}function D(e,t,o=16){return y(e).padEnd(o)}function B(e,t=10){if(0===e)return"0MB".padEnd(t);const o=e/1048576;return o>=1024?`${(o/1024).toFixed(1)}GB`.padEnd(t):o<1?`${o.toFixed(2)}MB`.padEnd(t):`${o.toFixed(1)}MB`.padEnd(t)}const C=B;function x(e,t=10){return e.padEnd(t)}function P(e){if(0===e)return"0B";const t=1024,o=e/t;return o<100?`${Math.round(o)}KB`:`${(e/(t*t)).toFixed(1)}`}function F(e,t=10){return P(e).padEnd(t)}const v="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏",M=Object.freeze(Object.defineProperty({__proto__:null,aesthetic:["▰▱▱▱▱▱▱▰▰▱▱▱▱▱▰▰▰▱▱▱▱▰▰▰▰▱▱▱▰▰▰▰▰▱▱▰▰▰▰▰▰▱▰▰▰▰▰▰▰▰▱▱▱▱▱▱",7],arc:"◜◠◝◞◡◟",arrow:"←↖↑↗→↘↓↙",arrow2:["⬆️ ↗️ ➡️ ↘️ ⬇️ ↙️ ⬅️ ↖️ ",3],arrow3:["▹▹▹▹▹▸▹▹▹▹▹▸▹▹▹▹▹▸▹▹▹▹▹▸▹▹▹▹▹▸",5],balloon:" .oO@* ",balloon2:".oO°Oo.",betaWave:["ρβββββββρβββββββρβββββββρβββββββρβββββββρβββββββρ",7],binary:["010010001100100101111010111101010111101011111000110011110101",6],bluePulse:["🔹 🔷 🔵 🔵 🔷 ",3],bouncingBall:["( ● )( ● )( ● )( ● )( ●)( ● )( ● )( ● )( ● )(● )",8],bouncingBar:["[ ][= ][== ][=== ][====][ ===][ ==][ =][ ][ =][ ==][ ===][====][=== ][== ][= ]",6],boxBounce:"▖▘▝▗",boxBounce2:"▌▀▐▄",christmas:["🌲🎄",2],circle:"◡⊙◠",circleHalves:"◐◓◑◒",circleQuarters:"◴◷◶◵",clock:["🕛 🕐 🕑 🕒 🕓 🕔 🕕 🕖 🕗 🕘 🕙 🕚 ",3],dots:v,dots10:"⢄⢂⢁⡁⡈⡐⡠",dots11:"⠁⠂⠄⡀⢀⠠⠐⠈",dots12:["⢀⠀⡀⠀⠄⠀⢂⠀⡂⠀⠅⠀⢃⠀⡃⠀⠍⠀⢋⠀⡋⠀⠍⠁⢋⠁⡋⠁⠍⠉⠋⠉⠋⠉⠉⠙⠉⠙⠉⠩⠈⢙⠈⡙⢈⠩⡀⢙⠄⡙⢂⠩⡂⢘⠅⡘⢃⠨⡃⢐⠍⡐⢋⠠⡋⢀⠍⡁⢋⠁⡋⠁⠍⠉⠋⠉⠋⠉⠉⠙⠉⠙⠉⠩⠈⢙⠈⡙⠈⠩⠀⢙⠀⡙⠀⠩⠀⢘⠀⡘⠀⠨⠀⢐⠀⡐⠀⠠⠀⢀⠀⡀",2],dots13:"⣼⣹⢻⠿⡟⣏⣧⣶",dots14:["⠉⠉⠈⠙⠀⠹⠀⢸⠀⣰⢀⣠⣀⣀⣄⡀⣆⠀⡇⠀⠏⠀⠋⠁",2],dots2:"⣾⣽⣻⢿⡿⣟⣯⣷",dots3:"⠋⠙⠚⠞⠖⠦⠴⠲⠳⠓",dots4:"⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆",dots5:"⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋",dots6:"⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠴⠲⠒⠂⠂⠒⠚⠙⠉⠁",dots7:"⠈⠉⠋⠓⠒⠐⠐⠒⠖⠦⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈",dots8:"⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈",dots9:"⢹⢺⢼⣸⣇⡧⡗⡏",dotsCircle:["⢎ ⠎⠁⠊⠑⠈⠱ ⡱⢀⡰⢄⡠⢆⡀",2],earth:["🌍 🌎 🌏 ",3],fingerDance:["🤘 🤟 🖖 ✋ 🤚 👆 ",3],flip:"___-``'´-___",grenade:["، ′ ´ ‾ ⸌ ⸊ | ⁎ ⁕ ෴ ⁓ ",3],growHorizontal:"▏▎▍▌▋▊▉▊▋▌▍▎",growVertical:"▁▃▄▅▆▇▆▅▄▃",hearts:["💛 💙 💜 💚 ❤️ ",3],line:"-\\|/",mindblown:["😐 😐 😮 😮 😦 😦 😧 😧 🤯 💥 ✨       ",3],monkey:["🙈 🙈 🙉 🙊 ",3],moon:["🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘 ",3],noise:"▓▒░",orangeBluePulse:["🔸 🔶 🟠 🟠 🔶 🔹 🔷 🔵 🔵 🔷 ",3],orangePulse:["🔸 🔶 🟠 🟠 🔶 ",3],pipe:"┤┘┴└├┌┬┐",point:["∙∙∙●∙∙∙●∙∙∙●∙∙∙",3],runner:["🚶 🏃 ",3],sand:"⠁⠂⠄⡀⡈⡐⡠⣀⣁⣂⣄⣌⣔⣤⣥⣦⣮⣶⣷⣿⡿⠿⢟⠟⡛⠛⠫⢋⠋⠍⡉⠉⠑⠡⢁",simpleDotsScrolling:[". .. ... .. . ",3],smiley:["😄 😝 ",3],speaker:["🔈 🔉 🔊 🔉 ",3],squareCorners:"◰◳◲◱",squish:"╫╪",star:"✶✸✹✺✹✷",timeTravel:["🕛 🕚 🕙 🕘 🕗 🕖 🕕 🕔 🕓 🕒 🕑 🕐 ",3],toggle10:"㊂㊀㊁",toggle11:"⧇⧆",toggle12:"☗☖",toggle3:"□■",toggle4:"■□▪▫",toggle5:"▮▯",toggle6:"ဝ၀",toggle7:"⦾⦿",toggle8:"◍◌",toggle9:"◉◎",triangle:"◢◣◤◥",weather:["☀️ ☀️ ☀️ 🌤 ⛅️ 🌥 ☁️ 🌧 🌨 🌧 🌨 🌧 🌨 ⛈ 🌨 🌧 🌨 ☁️ 🌥 ⛅️ 🌤 ☀️ ☀️ ",3]},Symbol.toStringTag,{value:"Module"}));function T(e){const t="string"==typeof e?e:e[0],o="string"==typeof e?1:e[1],r=[];for(let a=0;a<t.length;a+=o)r.push(t.slice(a,a+o));return r}const $=Object.keys(M);function O(e){const t=M[e];return T(t||v)}function E(){return $[Math.floor(Math.random()*$.length)]}const A=E;function R(e){let t=0;for(const o of e){const e=o.codePointAt(0);t+=e>=126976&&e<=128767||e>=127744&&e<=128511||e>=128512&&e<=128591||e>=128640&&e<=128767||e>=128768&&e<=128895||e>=128896&&e<=129023||e>=129024&&e<=129279||e>=9728&&e<=9983||e>=9984&&e<=10175?2:1}return t}function z(e,t=20){const o=(process.stdout.columns||120)-59-20-R(e);return Math.max(10,Math.min(t,o))}const U=["","","","","","","","","","",""],L=["","","","","","",""];function k(){return U[Math.floor(Math.random()*U.length)]}function j(){return L[Math.floor(Math.random()*L.length)]}function I(e,o){return t.join(e,t.basename(o)+".download-state")}function _(t){try{e.existsSync(t)&&e.unlinkSync(t)}catch{}}function q(t){try{if(e.existsSync(t))return JSON.parse(e.readFileSync(t,"utf8"))}catch{}return null}function N(t,o){try{e.writeFileSync(t,JSON.stringify(o,null,2))}catch{}}function G(t){try{if(e.existsSync(t))return e.statSync(t).size}catch{}return 0}async function K(e,t){try{const o=await fetch(e,{method:"HEAD",...t?{signal:t}:{}});if(!o.ok)throw new Error(`HTTP ${o.status}`);return{supportsResume:"bytes"===o.headers.get("accept-ranges"),totalSize:parseInt(o.headers.get("content-length")??"0",10)||0,lastModified:o.headers.get("last-modified"),etag:o.headers.get("etag"),headers:o.headers}}catch{return console.log(m.warning("⚠️ Could not check server resume support")),{supportsResume:!1,totalSize:0,lastModified:null,etag:null,headers:null}}}function W(t,o,r,a,s){if(t.supportsResume&&r>0&&o){if(!(t.lastModified&&t.lastModified!==o.lastModified||t.etag&&t.etag!==o.etag||t.totalSize!==o.totalSize)&&r<t.totalSize)return{startByte:r,resuming:!0};e.existsSync(a)&&e.unlinkSync(a),_(s)}else r>0&&e.existsSync(a)&&e.unlinkSync(a);return{startByte:0,resuming:!1}}function H(o){process.stdin.isTTY&&(process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",async r=>{""===r&&(console.log(m.warning.bold("\n🛑 Downloads cancelled by user")),process.exit(0)),"p"===r.toLowerCase()&&(o.isPaused()?o.resumeAll():o.pauseAll()),"a"!==r.toLowerCase()||o.isAddingUrl()||await async function(o){o.setAddingUrl(!0);try{console.log(m.cyan("\n📥 Enter URL to add (or press Enter to cancel):"));const a=s.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>a.question("",t=>{a.close(),e(t.trim())}));if(n&&J(n)){const a=V(n),s=t.isAbsolute(a)?a:t.join(process.cwd(),a);try{const o=t.dirname(s);e.existsSync(o)||e.mkdirSync(o,{recursive:!0})}catch(r){return void console.error(m.error.bold("❌ Could not create output dir: ")+r.message)}o.hasMultiBar()?await o.addToMultipleDownloads(n,s,a):o.downloadFile(n,s).catch(e=>console.error(m.error(`❌ ${e.message}`))),console.log(m.success("🚀 New download started!"))}else n?console.log(m.error("❌ Invalid URL.")):console.log(m.warning("⚠️ Cancelled."))}catch(r){console.error(m.error("❌ Error: ")+r.message)}finally{o.setAddingUrl(!1),console.log(o.isPaused()?m.warning("⏸️ Still paused. Press p to resume, a to add URL."):m.success("▶️ Downloads active. Press p to pause, a to add URL."))}}(o)}))}function J(e){try{return new URL(e),!0}catch{return!1}}function V(e){try{return t.basename(new URL(e).pathname)||"downloaded-file"}catch{return"downloaded-file"}}function Y(e){try{return t.extname(new URL(e).pathname).toLowerCase()}catch{return""}}function Z(e){return m.yellow("{filename}")+" "+m.cyan("{spinner}")+" "+e+"{bar} "+m.success("{percentage}%")+" "+m.info("{downloadedDisplay}")+" "+m.info("{totalDisplay}")+" "+m.purple("{speed}")+" "+m.pink("{etaFormatted}")}function Q(e,t,o){return{format:Z(e),barCompleteChar:"█",barIncompleteChar:"░",barGlue:t,barsize:o}}function X(e){return{filename:"",spinner:e[0],speed:x("0B"),progress:D(0),downloadedDisplay:y(0),totalDisplay:B(0),etaFormatted:b(0),percentage:" 0".padStart(3)}}async function ee(t,o,r,a){const{bar:s,spinnerFrames:i,download:d}=t,{url:c,outputPath:u,filename:p}=d,h=a.stateFilePath(u),f=u+".tmp";try{const d=new AbortController;a.pushAbortController(d);const p=await K(c,d.signal),m=q(h),w=G(f),{startByte:C,resuming:x}=W(p,m,w,f,h),P={};x&&C>0&&(P.Range=`bytes=${C}-`);const F=await fetch(c,{headers:P,signal:d.signal});if(!F.ok)throw new Error(`HTTP ${F.status}`);const v=F.headers.get("content-length"),M=x?p.totalSize:v?parseInt(v,10):0;N(h,{url:c,outputPath:u,totalSize:M,startByte:C,lastModified:p.lastModified,etag:p.etag,timestamp:(new Date).toISOString()}),s.setTotal(M||100),s.update(C,{progress:D(C),downloadedDisplay:y(C),totalDisplay:B(M)});const T=e.createWriteStream(f,{flags:x?"a":"w"});let $=C,A=Date.now(),R=$;const U=new l.Readable({read(){}}),L=F.body.getReader();(async()=>{try{for(;;){for(;a.isPaused;)await new Promise(e=>setTimeout(e,100));const{done:e,value:n}=await L.read();if(e){U.push(null);break}$+=n.length;const l=Date.now(),d=(l-A)/1e3;l-t.lastFrameUpdate>=150&&(t.spinnerIndex=(t.spinnerIndex+1)%i.length,t.lastFrameUpdate=l,s.options.barsize=z(i[t.spinnerIndex],g)),l-t.lastSpinnerUpdate>=45e3&&(t.spinnerFrames=O(E()),t.spinnerIndex=0,t.lastSpinnerUpdate=l);const c={spinner:i[t.spinnerIndex],progress:D($),downloadedDisplay:y($),totalDisplay:B(M)};if(d>=.3){s.update($,c);const e=t.download.index??0;r.totalDownloaded+=$-R,r.individualDownloaded[e]=$,r.individualSizes[e]=M,r.totalSize=r.individualSizes.reduce((e,t)=>e+t,0),void 0!==r.actualTotalSize&&(r.actualTotalSize=r.totalSize),M>0&&r.individualSizes[e]===M&&o?.setTotal(r.totalSize),A=l,R=$}else s.update($,c);U.push(Buffer.from(n))}}catch(e){U.destroy(e)}})(),await n.pipeline(U,T),e.existsSync(u)&&e.unlinkSync(u),e.renameSync(f,u),_(h);const k=r.individualSizes.reduce((e,t)=>e+t,0),j=k>0?k:r.actualTotalSize||r.totalSize;o?.update(r.totalDownloaded,{progress:S(r.totalDownloaded,j),downloadedDisplay:y(r.totalDownloaded),totalDisplay:B(j),etaFormatted:b((Date.now()-(r.individualStartTimes?.[0]??Date.now()))/1e3)})}catch(w){throw s.update(s.total,{spinner:"❌",speed:x("FAILED"),downloadedDisplay:y(0),totalDisplay:B(0)}),console.log(m.info(`💾 Partial download saved for ${p}. Restart to resume.`)),w}}class te{progressBar=null;multiBar=null;loadingSpinner=null;abortController=null;abortControllers=[];isPaused=!1;pauseCallback=null;resumeCallback=null;isAddingUrl=!1;stateDir;COL_FILENAME=25;COL_SPINNER=2;COL_BAR=g;COL_PERCENT=4;COL_DOWNLOADED=16;COL_TOTAL=10;COL_SPEED=10;COL_ETA=10;colors=m;formatBytes=f;formatBytesCompact=y;formatTotalDisplay=B;formatTotal=C;formatETA=b;formatMasterProgress=S;formatProgress=D;formatSpeed=x;formatSpeedDisplay=P;formatTotalSpeed=F;truncateFilename=w;getSpinnerFrames=O;getRandomSpinner=E;getRandomOraSpinner=A;getSpinnerWidth=R;calculateBarSize=z;getRandomBarColor=k;getRandomBarGlueColor=j;isValidUrl=J;generateFilename=V;getFileExtension=Y;getRandomColor(){return m.gradient[Math.floor(Math.random()*m.gradient.length)]}constructor(){this.stateDir=function(t){try{return e.existsSync(t)||e.mkdirSync(t,{recursive:!0}),t}catch{return console.log(m.warning("⚠️ Could not create state directory, using current directory")),process.cwd()}}(process.env.GRAB_DOWNLOAD_STATE_DIR||t.join(process.cwd(),".grab-downloads"))}setPauseCallback(e){this.pauseCallback=e}setResumeCallback(e){this.resumeCallback=e}pauseAll(){this.isPaused=!0,console.log(m.warning("⏸️ Pausing all downloads...")),this.pauseCallback?.()}resumeAll(){this.isPaused=!1,console.log(m.success("▶️ Resuming all downloads...")),this.resumeCallback?.()}cleanup(){this.loadingSpinner?.isSpinning&&this.loadingSpinner.stop(),this.progressBar&&this.progressBar.stop(),this.multiBar&&this.multiBar.stop(),this.abortController&&this.abortController.abort(),process.stdin.isTTY&&(process.stdin.setRawMode(!1),process.stdin.pause())}setupGlobalKeyboardListener(){H({isPaused:()=>this.isPaused,pauseAll:()=>this.pauseAll(),resumeAll:()=>this.resumeAll(),isAddingUrl:()=>this.isAddingUrl,setAddingUrl:e=>{this.isAddingUrl=e},hasMultiBar:()=>!!this.multiBar,addToMultipleDownloads:(e,t,o)=>this.addToMultipleDownloads(e,t,o),downloadFile:(e,t)=>this.downloadFile(e,t)})}async downloadFile(t,o){const a={isPaused:this.isPaused,progressBar:this.progressBar,abortController:this.abortController,stateFilePath:e=>I(this.stateDir,e),setupKeyboard:()=>this.setupGlobalKeyboardListener()};Object.defineProperty(a,"isPaused",{get:()=>this.isPaused}),await async function(t,o,a){const s=a.stateFilePath(o),d=o+".tmp";try{a.abortController=new AbortController;const{default:c}=await import("ora"),u=c({text:m.primary("🌐 Checking server capabilities..."),spinner:A(),color:"cyan"}).start(),p=await K(t,a.abortController.signal),h=q(s),w=G(d);let{startByte:S,resuming:C}=W(p,h,w,d,s);C?(u.succeed(m.success(`✅ Resuming from ${f(S)} of ${B(p.totalSize)}`)),console.log(m.info(`🔄 Starting at byte ${S}`))):(u.stop(),w>0&&console.log(m.warning("⚠️ Server does not support resume, starting fresh")));const F={};C&&S>0&&(F.Range=`bytes=${S}-`);const v=await fetch(t,{headers:F,signal:a.abortController.signal});if(!v.ok)throw new Error(`HTTP ${v.status}`);const M=v.headers.get("content-length"),T=C?p.totalSize:M?parseInt(M,10):0;C||(0===T?console.log(m.warning("⚠️ Content-Length not provided")):console.log(m.info(`📦 File size: ${B(T)}`))),N(s,{url:t,outputPath:o,totalSize:T,startByte:S,lastModified:p.lastModified,etag:p.etag,timestamp:(new Date).toISOString()});const $=k(),R=j();let U=O(E()),L=0,I=Date.now(),H=Date.now();a.setupKeyboard(),a.progressBar=new i.SingleBar({format:m.success("{percentage}%")+" "+m.cyan("{spinner}")+" "+$+"{bar} "+m.info("{downloadedDisplay}")+" "+m.info("{totalDisplay}")+" "+m.purple("{speed}")+" "+m.pink("{etaFormatted}"),barCompleteChar:"█",barIncompleteChar:"░",barGlue:R,hideCursor:!0,barsize:z(U[0],g),stopOnComplete:!0,clearOnComplete:!1}),a.progressBar.start(T||100,S,{speed:x("0B/s"),etaFormatted:b(0),spinner:U[0],progress:D(S),downloadedDisplay:y(S),totalDisplay:B(T)});const J=e.createWriteStream(d,{flags:C?"a":"w"});let V=S,Y=0,Z=Date.now(),Q=V;const X=new l.Readable({read(){}}),ee=v.body.getReader();(async()=>{try{for(;;){for(;a.isPaused;)await new Promise(e=>setTimeout(e,100));const{done:e,value:t}=await ee.read();if(e){X.push(null);break}Y+=t.length,V+=t.length;const o=Date.now(),r=(o-Z)/1e3;o-I>=45e3&&(U=O(E()),L=0,I=o),o-H>=120&&(L=(L+1)%U.length,H=o,a.progressBar.options.barsize=z(U[L],g));const s={spinner:U[L],progress:D(V),downloadedDisplay:y(V),totalDisplay:B(T)};if(r>=.3){const e=(V-Q)/r;a.progressBar.update(V,{...s,speed:x(P(e)),etaFormatted:b(T>0?(T-V)/e:0)}),Z=o,Q=V}else a.progressBar.update(V,s);X.push(Buffer.from(t))}}catch(e){X.destroy(e)}})(),await n.pipeline(X,J),a.progressBar.stop(),e.existsSync(o)&&e.unlinkSync(o),e.renameSync(d,o),_(s),console.log(m.success("✅ Download completed!")),console.log(m.primary("📁 Saved to: ")+r.underline(o)),console.log(m.purple("📊 Total: ")+f(V)),C&&(console.log(m.info("🔄 Resumed from: ")+f(S)),console.log(m.info("📥 This session: ")+f(Y)));const te=["🥳","🎊","🎈","🌟","💯","🚀","✨","🔥"];console.log(m.success(`${te[Math.floor(Math.random()*te.length)]} Done!`))}catch(c){throw a.progressBar&&a.progressBar.stop(),console.error(m.error.bold("💥 Download failed: ")+m.warning(c.message)),console.log("AbortError"===c.name?m.info("💾 State saved. Run the same command to resume."):m.info("💾 Partial download saved. Restart to resume.")),c}}(t,o,a),this.progressBar=a.progressBar,this.abortController=a.abortController}async downloadMultipleFiles(e){const t={isPaused:!1,multiBar:null,abortControllers:this.abortControllers,stateFilePath:e=>I(this.stateDir,e),setupKeyboard:()=>this.setupGlobalKeyboardListener(),pushAbortController:e=>this.abortControllers.push(e)};Object.defineProperty(t,"isPaused",{get:()=>this.isPaused}),await async function(e,t){try{t.setupKeyboard();const o=k(),r=j();t.multiBar=new i.MultiBar({format:m.success("{percentage}%")+" "+m.yellow("{filename}")+" "+m.cyan("{spinner}")+" "+o+"{bar} "+m.info("{downloadedDisplay}")+" "+m.info("{totalDisplay}")+" "+m.purple("{speed}")+" "+m.pink("{etaFormatted}"),hideCursor:!0,clearOnComplete:!1,stopOnComplete:!0,autopadding:!1,barCompleteChar:"█",barIncompleteChar:"░",barGlue:r,barsize:g});const a=e.length,s=1===a,n=new Array(a).fill(0),l=new Array(a).fill(0),d=new Array(a).fill(0),c=new Array(a).fill(Date.now());let u=new Array(a).fill(0),p=Date.now(),h=e.reduce((e,t)=>e+(t.estimatedSize??104857600),0),f=null;if(!s){const e=R("⬇️");f=t.multiBar.create(h,0,{filename:"Total".padEnd(25-e),spinner:"⬇️",speed:"0B".padEnd(10),progress:S(0,h),downloadedDisplay:y(0),totalDisplay:B(h),etaFormatted:b(0),percentage:" 0".padStart(3)},{format:m.success("{percentage}%")+" "+m.yellow.bold("{filename}")+" "+m.success("{spinner}")+" {bar} "+m.info("{downloadedDisplay}")+" "+m.info("{totalDisplay}")+" "+m.purple("{speed}")+" "+m.pink("{etaFormatted}"),barCompleteChar:"▶",barIncompleteChar:"▷",barGlue:"",barsize:z("⬇️",g)})}const C=e.map((e,o)=>{const r=O(E()),a=R(r[0]),s=k(),n=j();return{bar:t.multiBar.create(100,0,{...X(r),filename:w(e.filename,25-a)},Q(s,n,z(r[0],g))),spinnerFrames:r,spinnerIndex:0,lastSpinnerUpdate:Date.now(),lastFrameUpdate:Date.now(),download:{...e,index:o}}}),v=setInterval(()=>{const e=Date.now(),t=(e-p)/1e3;for(let c=0;c<a;c++)t>0&&(n[c]=(d[c]-u[c])/t,C[c]?.bar?.update(d[c],{speed:x(P(n[c])),progress:D(d[c],l[c]),downloadedDisplay:y(d[c]),totalDisplay:B(l[c]),etaFormatted:l[c]>0?b((l[c]-d[c])/n[c]):b(0)}));p=e,u=[...d];const o=n.reduce((e,t)=>e+t,0),r=d.reduce((e,t)=>e+t,0),s=l.reduce((e,t)=>e+t,0),i=s>0?s:h;f?.update(r,{speed:F(o),progress:S(r,i),downloadedDisplay:y(r),totalDisplay:B(i),etaFormatted:b((e-c[0])/1e3),percentage:i>0?Math.round(r/i*100):0})},1e3),M={totalDownloaded:0,totalSize:h,individualSpeeds:n,individualSizes:l,individualDownloaded:d,individualStartTimes:c,lastTotalUpdate:Date.now(),lastTotalDownloaded:0,actualTotalSize:0},T=await Promise.allSettled(C.map(async(e,o)=>{try{return await ee(e,f,M,t),{success:!0,i:o,filename:e.download.filename}}catch(r){return{success:!1,i:o,filename:e.download.filename,error:r}}}));clearInterval(v),t.multiBar.stop();const $=T.filter(e=>"fulfilled"===e.status&&e.value.success).length,A=T.length-$;A>0&&(console.log(m.error(`❌ Failed: ${A}/${a}`)),T.forEach((t,o)=>{if("rejected"===t.status||!t.value.success){const r=t.reason??t.value?.error??"unknown";console.log(m.error(` • ${e[o].filename}: ${r.message??r}`))}}));const U=["🥳","🎊","🎈","🌟","💯","🚀","✨","🔥"];console.log(m.green(`${U[Math.floor(Math.random()*U.length)]} Success: ${$}/${a}`)),t.abortControllers=[]}catch(o){throw t.multiBar&&t.multiBar.stop(),console.error(m.error.bold("💥 Batch download failed: ")+m.warning(o.message)),o}}(e,t),this.multiBar=t.multiBar,this.abortControllers=t.abortControllers}async downloadSingleFileWithBar(e,t,o,r){const a={isPaused:!1,multiBar:this.multiBar,abortControllers:this.abortControllers,stateFilePath:e=>I(this.stateDir,e),setupKeyboard:()=>this.setupGlobalKeyboardListener(),pushAbortController:e=>this.abortControllers.push(e)};Object.defineProperty(a,"isPaused",{get:()=>this.isPaused}),await ee(e,t,r,a)}async addToMultipleDownloads(e,t,o){const r={isPaused:!1,multiBar:this.multiBar,abortControllers:this.abortControllers,stateFilePath:e=>I(this.stateDir,e),setupKeyboard:()=>{},pushAbortController:e=>this.abortControllers.push(e)};Object.defineProperty(r,"isPaused",{get:()=>this.isPaused}),await async function(e,t,o,r){const a=O(E()),s=R(a[0]),n=k(),l=j(),i=z(a[0],g);ee({bar:r.multiBar.create(100,0,{...X(a),filename:w(o,25-s)},Q(n,l,i)),spinnerFrames:a,spinnerIndex:0,lastSpinnerUpdate:Date.now(),lastFrameUpdate:Date.now(),download:{url:e,outputPath:t,filename:o,index:1}},null,{totalDownloaded:0,totalSize:0,individualSpeeds:[],individualSizes:[],individualDownloaded:[],individualStartTimes:[],lastTotalUpdate:Date.now(),lastTotalDownloaded:0,actualTotalSize:0},r).catch(e=>console.error(m.error(`❌ ${o}: ${e.message}`)))}(e,t,o,r)}}t.dirname(o.fileURLToPath("undefined"==typeof document?require("url").pathToFileURL(__filename).href:u&&"SCRIPT"===u.tagName.toUpperCase()&&u.src||new URL("grab-url-cli.cjs.js",document.baseURI).href));if((()=>{try{const e=process.argv[1]?t.resolve(process.argv[1]):"";return!!e&&("undefined"==typeof document?require("url").pathToFileURL(__filename).href:u&&"SCRIPT"===u.tagName.toUpperCase()&&u.src||new URL("grab-url-cli.cjs.js",document.baseURI).href)===o.pathToFileURL(e).href}catch{return!1}})()){const o=(new p).usage("Usage: grab-url <url...> [options]").command("$0 <url>","Fetch data or download files; pass one or more URLs").option("no-save",{type:"boolean",default:!1,describe:"Don't save output to file, just print to console"}).option("output",{alias:"o",type:"string",describe:"Output filename (default: output.json)",default:null}).option("params",{alias:"p",type:"string",describe:'JSON string of query parameters (e.g., \'{"key":"value"}\')',coerce:e=>{if(!e)return{};try{return JSON.parse(e)}catch{throw new Error(`Invalid JSON in params: ${e}`)}}}).help().alias("h","help").example("grab-url https://api.example.com/data","Fetch JSON/text from an API and save to output.json").example("grab-url https://example.com/file1.zip https://example.com/file2.zip","Download multiple files concurrently").example("grab-url https://example.com/file.iso -o ubuntu.iso","Save the first URL to a custom filename").version("1.1.0").strict().parseSync(),s=o.urls||[],n=o.params||{},l=o.output,i=o["no-save"],u=s.some(h),g=s.length>1||u;(async()=>{if(g){const n=new te,i=s.map((o,a)=>{let s=0===a&&l?l:n.generateFilename(o);const i=t.isAbsolute(s)?s:t.join(process.cwd(),s),d=t.dirname(i);try{e.existsSync(d)||e.mkdirSync(d,{recursive:!0})}catch(c){console.error(r.red.bold("❌ Could not create output directory: ")+c.message),process.exit(1)}return{url:o,outputPath:i,filename:t.basename(s)}});try{await n.downloadMultipleFiles(i);const t=new a({head:["Filename","Size","Created"],colWidths:[32,14,25],colAligns:["left","right","left"],style:{"padding-left":1,"padding-right":1,head:[],border:[]}});i.forEach(o=>{try{const r=e.statSync(o.outputPath);t.push([o.filename,n.formatBytes(r.size),r.birthtime.toLocaleString()])}catch{t.push([o.filename,"Error","Could not read"])}}),console.log(r.cyan.bold("\nFile Details:")),console.log(t.toString())}catch(o){console.error(r.red.bold("Failed to download files: ")+r.yellow(o.message)),process.exit(1)}n.cleanup()}else{const r=s[0],a=process.hrtime();try{const o=await d.default(r,n);o.error&&c.log(`\n\nStatus: ❌ ${o.error}`);let s,u=null,p=!1;if("string"==typeof o.data?(s=o.data,p=!0):Buffer.isBuffer(o.data)||o.data instanceof Uint8Array?(s=o.data,p=!1):o.data instanceof Blob?(s=Buffer.from(await o.data.arrayBuffer()),p=!1):o.data&&"object"==typeof o.data?(s=JSON.stringify(o.data,null,2),p=!0):(s=String(o.data),p=!0),i)p?c.log(s):c.log(`Binary data received (${s.length} bytes). Use --output to save to file.`);else{const o=new URL(r).pathname,n=t.extname(o),i=p?".json":n||".bin";u=l?t.resolve(l):t.resolve(process.cwd(),`output${i}`),p?e.writeFileSync(u,s,"utf8"):e.writeFileSync(u,s);const[d,h]=process.hrtime(a),g=(d+h/1e9).toFixed(2),m=(e.statSync(u).size/1048576).toFixed(1);c.log(`⏱️ ${g}s 📦 ${m}MB ✅ Saved to: ${u}`)}}catch(o){c.log(`Error: ${o.message}`,{color:"red"}),process.exit(1)}}})()}exports.ArgParser=p,exports.MultiColorFileDownloaderCLI=te,exports.generateFilename=V,exports.getFileExtension=Y,exports.isFileUrl=h,exports.isValidUrl=J;
2
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("fs"),t=require("path"),o=require("url"),r=require("chalk"),a=require("cli-table3"),s=require("readline"),n=require("stream/promises"),l=require("stream"),i=require("cli-progress"),d=require("./grab-api.cjs.js"),c=require("@grab-url/log");var u="undefined"!=typeof document?document.currentScript:null;class p{commands={};options={};examples=[];helpText="";versionText="1.0.0";usage(e){return this.helpText=e,this}command(e,t,o){const r=e.match(/\$0 <(\w+)>/);return r&&(this.commands[r[1]]={desc:t,handler:o,required:!0}),this}option(e,t={}){return this.options[e]=t,this}example(e,t){return this.examples.push({cmd:e,desc:t}),this}help(){return this}alias(e,t){return this.options[t]&&(this.options[t].alias=e),this}version(e){return e&&(this.versionText=e),this}strict(){return this}parseSync(){const e=process.argv.slice(2),t={},o=[];(e.includes("--help")||e.includes("-h"))&&(this.showHelp(),process.exit(0)),e.includes("--version")&&(console.log(this.versionText),process.exit(0));for(let r=0;r<e.length;r++){const a=e[r];if(a.startsWith("--")){const[o,s]=a.split("="),n=o.slice(2);if(void 0!==s)t[n]=this.coerceValue(n,s);else if("boolean"===this.options[n]?.type)t[n]=!0;else{const o=e[r+1];o&&!o.startsWith("-")?(t[n]=this.coerceValue(n,o),r++):t[n]=!0}}else if(a.startsWith("-")&&2===a.length){const o=a[1],s=this.findLongName(o);if(s)if("boolean"===this.options[s]?.type)t[s]=!0;else{const o=e[r+1];o&&!o.startsWith("-")&&(t[s]=this.coerceValue(s,o),r++)}}else o.push(a)}return o.length>0&&(t.urls=o),Object.keys(this.options).forEach(e=>{void 0===t[e]&&void 0!==this.options[e].default&&(t[e]=this.options[e].default)}),t.urls&&0!==t.urls.length||!this.commands.url?.required||(console.error("Error: Missing required argument: url"),this.showHelp(),process.exit(1)),t}coerceValue(e,t){const o=this.options[e];if(!o)return t;if(o.coerce)return o.coerce(t);switch(o.type){case"number":return Number(t);case"boolean":return"true"===t||"1"===t;default:return t}}findLongName(e){return Object.keys(this.options).find(t=>this.options[t].alias===e)}showHelp(){console.log(this.helpText||"Usage: grab-url <url> [options]"),console.log("\nPositional arguments:"),Object.keys(this.commands).forEach(e=>{console.log(` ${e.padEnd(20)} ${this.commands[e].desc}`)}),console.log("\nOptions:"),Object.keys(this.options).forEach(e=>{const t=this.options[e],o=t.alias?`-${t.alias}, --${e}`:`--${e}`;console.log(` ${o.padEnd(20)} ${t.describe||""}`)}),this.examples.length>0&&(console.log("\nExamples:"),this.examples.forEach(e=>{console.log(` ${e.cmd}`),console.log(` ${e.desc}`)}))}}function h(e){return/\.[a-zA-Z0-9]{1,5}(?:\.[a-zA-Z0-9]{1,5})*$/.test(e.split("?")[0])}const m=15,g={primary:r.cyan,success:r.green,warning:r.yellow,error:r.red,info:r.blue,purple:r.magenta,pink:r.magentaBright,yellow:r.yellowBright,cyan:r.cyanBright,green:r.green,red:r.red,gradient:[r.blue,r.magenta,r.cyan,r.green,r.yellow,r.red]};function f(e,t=2){if(0===e)return g.info("0 B");const o=Math.max(t,0),r=[{unit:"B",color:g.info},{unit:"KB",color:g.cyan},{unit:"MB",color:g.yellow},{unit:"GB",color:g.purple},{unit:"TB",color:g.pink},{unit:"PB",color:g.primary}],a=Math.floor(Math.log(e)/Math.log(1024)),s=parseFloat((e/Math.pow(1024,a)).toFixed(o)),n=r[a]??r[r.length-1];return n.color.bold(`${s} ${n.unit}`)}function y(e){if(0===e)return"0B";const t=1024,o=e/t;return o<100?`${Math.round(o)}KB`:`${(e/(t*t)).toFixed(1)}`}function w(e,o=25){if(e.length<=o)return e.padEnd(o);const r=t.extname(e),a=t.basename(e,r);if(a.length<=3)return e.padEnd(o);const s=Math.ceil((o-r.length-3)/2),n=Math.floor((o-r.length-3)/2);return`${a.slice(0,s)+"..."+a.slice(-n)}${r}`.padEnd(o)}function b(e,t=10){if(!e||!isFinite(e)||e<0)return" -- ";const o=Math.floor(e/3600),r=Math.floor(e%3600/60),a=Math.round(e%60);return`${o}:${String(r).padStart(2,"0")}:${String(a).padStart(2,"0")}`.padEnd(t)}function S(e,t,o=16){const r=1024,a=e/(r*r);return t/(r*r)>=1024?`${(a/1024).toFixed(1)}GB`.padEnd(o):`${a.toFixed(1)}MB`.padEnd(o)}function B(e,t,o=16){return y(e).padEnd(o)}function D(e,t=10){if(0===e)return"0MB".padEnd(t);const o=e/1048576;return o>=1024?`${(o/1024).toFixed(1)}GB`.padEnd(t):o<1?`${o.toFixed(2)}MB`.padEnd(t):`${o.toFixed(1)}MB`.padEnd(t)}const C=D;function x(e,t=10){return e.padEnd(t)}function F(e){if(0===e)return"0B";const t=1024,o=e/t;return o<100?`${Math.round(o)}KB`:`${(e/(t*t)).toFixed(1)}`}function P(e,t=10){return F(e).padEnd(t)}const v="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏",M=Object.freeze(Object.defineProperty({__proto__:null,aesthetic:["▰▱▱▱▱▱▱▰▰▱▱▱▱▱▰▰▰▱▱▱▱▰▰▰▰▱▱▱▰▰▰▰▰▱▱▰▰▰▰▰▰▱▰▰▰▰▰▰▰▰▱▱▱▱▱▱",7],arc:"◜◠◝◞◡◟",arrow:"←↖↑↗→↘↓↙",arrow2:["⬆️ ↗️ ➡️ ↘️ ⬇️ ↙️ ⬅️ ↖️ ",3],arrow3:["▹▹▹▹▹▸▹▹▹▹▹▸▹▹▹▹▹▸▹▹▹▹▹▸▹▹▹▹▹▸",5],balloon:" .oO@* ",balloon2:".oO°Oo.",betaWave:["ρβββββββρβββββββρβββββββρβββββββρβββββββρβββββββρ",7],bluePulse:["🔹 🔷 🔵 🔵 🔷 ",3],bouncingBall:["( ● )( ● )( ● )( ● )( ●)( ● )( ● )( ● )( ● )(● )",8],bouncingBar:["[ ][= ][== ][=== ][====][ ===][ ==][ =][ ][ =][ ==][ ===][====][=== ][== ][= ]",6],boxBounce:"▖▘▝▗",boxBounce2:"▌▀▐▄",christmas:["🌲🎄",2],circle:"◡⊙◠",circleHalves:"◐◓◑◒",circleQuarters:"◴◷◶◵",clock:["🕛 🕐 🕑 🕒 🕓 🕔 🕕 🕖 🕗 🕘 🕙 🕚 ",3],dots:v,dots10:"⢄⢂⢁⡁⡈⡐⡠",dots11:"⠁⠂⠄⡀⢀⠠⠐⠈",dots12:["⢀⠀⡀⠀⠄⠀⢂⠀⡂⠀⠅⠀⢃⠀⡃⠀⠍⠀⢋⠀⡋⠀⠍⠁⢋⠁⡋⠁⠍⠉⠋⠉⠋⠉⠉⠙⠉⠙⠉⠩⠈⢙⠈⡙⢈⠩⡀⢙⠄⡙⢂⠩⡂⢘⠅⡘⢃⠨⡃⢐⠍⡐⢋⠠⡋⢀⠍⡁⢋⠁⡋⠁⠍⠉⠋⠉⠋⠉⠉⠙⠉⠙⠉⠩⠈⢙⠈⡙⠈⠩⠀⢙⠀⡙⠀⠩⠀⢘⠀⡘⠀⠨⠀⢐⠀⡐⠀⠠⠀⢀⠀⡀",2],dots13:"⣼⣹⢻⠿⡟⣏⣧⣶",dots14:["⠉⠉⠈⠙⠀⠹⠀⢸⠀⣰⢀⣠⣀⣀⣄⡀⣆⠀⡇⠀⠏⠀⠋⠁",2],dots2:"⣾⣽⣻⢿⡿⣟⣯⣷",dots3:"⠋⠙⠚⠞⠖⠦⠴⠲⠳⠓",dots4:"⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆",dots5:"⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋",dots6:"⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠴⠲⠒⠂⠂⠒⠚⠙⠉⠁",dots7:"⠈⠉⠋⠓⠒⠐⠐⠒⠖⠦⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈",dots8:"⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈",dots9:"⢹⢺⢼⣸⣇⡧⡗⡏",dotsCircle:["⢎ ⠎⠁⠊⠑⠈⠱ ⡱⢀⡰⢄⡠⢆⡀",2],earth:["🌍 🌎 🌏 ",3],fingerDance:["🤘 🤟 🖖 ✋ 🤚 👆 ",3],flip:"___-``'´-___",grenade:["، ′ ´ ‾ ⸌ ⸊ | ⁎ ⁕ ෴ ⁓ ",3],growHorizontal:"▏▎▍▌▋▊▉▊▋▌▍▎",growVertical:"▁▃▄▅▆▇▆▅▄▃",hearts:["💛 💙 💜 💚 ❤️ ",3],line:"-\\|/",mindblown:["😐 😐 😮 😮 😦 😦 😧 😧 🤯 💥 ✨       ",3],monkey:["🙈 🙈 🙉 🙊 ",3],moon:["🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘 ",3],noise:"▓▒░",orangeBluePulse:["🔸 🔶 🟠 🟠 🔶 🔹 🔷 🔵 🔵 🔷 ",3],orangePulse:["🔸 🔶 🟠 🟠 🔶 ",3],pipe:"┤┘┴└├┌┬┐",point:["∙∙∙●∙∙∙●∙∙∙●∙∙∙",3],runner:["🚶 🏃 ",3],sand:"⠁⠂⠄⡀⡈⡐⡠⣀⣁⣂⣄⣌⣔⣤⣥⣦⣮⣶⣷⣿⡿⠿⢟⠟⡛⠛⠫⢋⠋⠍⡉⠉⠑⠡⢁",simpleDotsScrolling:[". .. ... .. . ",3],smiley:["😄 😝 ",3],speaker:["🔈 🔉 🔊 🔉 ",3],squareCorners:"◰◳◲◱",squish:"╫╪",star:"✶✸✹✺✹✷",timeTravel:["🕛 🕚 🕙 🕘 🕗 🕖 🕕 🕔 🕓 🕒 🕑 🕐 ",3],toggle10:"㊂㊀㊁",toggle11:"⧇⧆",toggle12:"☗☖",toggle3:"□■",toggle4:"■□▪▫",toggle5:"▮▯",toggle6:"ဝ၀",toggle7:"⦾⦿",toggle8:"◍◌",toggle9:"◉◎",triangle:"◢◣◤◥",weather:["☀️ ☀️ ☀️ 🌤 ⛅️ 🌥 ☁️ 🌧 🌨 🌧 🌨 🌧 🌨 ⛈ 🌨 🌧 🌨 ☁️ 🌥 ⛅️ 🌤 ☀️ ☀️ ",3]},Symbol.toStringTag,{value:"Module"}));function T(e){const t="string"==typeof e?e:e[0],o="string"==typeof e?1:e[1],r=[];for(let a=0;a<t.length;a+=o)r.push(t.slice(a,a+o));return r}const $=Object.keys(M);function E(e){const t=M[e];return T(t||v)}function A(){return $[Math.floor(Math.random()*$.length)]}const R=A;function z(e){let t=0;for(const o of e){const e=o.codePointAt(0);t+=e>=126976&&e<=128767||e>=127744&&e<=128511||e>=128512&&e<=128591||e>=128640&&e<=128767||e>=128768&&e<=128895||e>=128896&&e<=129023||e>=129024&&e<=129279||e>=9728&&e<=9983||e>=9984&&e<=10175?2:1}return t}function U(e,t=20){const o=(process.stdout.columns||120)-59-20-z(e);return Math.max(10,Math.min(t,o))}const O=["","","","","","","","","","",""],L=["","","","","","",""];function k(){return O[Math.floor(Math.random()*O.length)]}function I(){return L[Math.floor(Math.random()*L.length)]}function j(e,o){return t.join(e,t.basename(o)+".download-state")}function _(t){try{e.existsSync(t)&&e.unlinkSync(t)}catch{}}function q(t){try{if(e.existsSync(t))return JSON.parse(e.readFileSync(t,"utf8"))}catch{}return null}function N(t,o){try{e.writeFileSync(t,JSON.stringify(o,null,2))}catch{}}function G(t){try{if(e.existsSync(t))return e.statSync(t).size}catch{}return 0}async function K(e,t){try{const o=await fetch(e,{method:"HEAD",...t?{signal:t}:{}});if(!o.ok)throw new Error(`HTTP ${o.status}`);return{supportsResume:"bytes"===o.headers.get("accept-ranges"),totalSize:parseInt(o.headers.get("content-length")??"0",10)||0,lastModified:o.headers.get("last-modified"),etag:o.headers.get("etag"),headers:o.headers}}catch{return console.log(g.warning("⚠️ Could not check server resume support")),{supportsResume:!1,totalSize:0,lastModified:null,etag:null,headers:null}}}function W(t,o,r,a,s){if(t.supportsResume&&r>0&&o){if(!(t.lastModified&&t.lastModified!==o.lastModified||t.etag&&t.etag!==o.etag||t.totalSize!==o.totalSize)&&r<t.totalSize)return{startByte:r,resuming:!0};e.existsSync(a)&&e.unlinkSync(a),_(s)}else r>0&&e.existsSync(a)&&e.unlinkSync(a);return{startByte:0,resuming:!1}}function H(o){process.stdin.isTTY&&(process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",async r=>{""===r&&(console.log(g.warning.bold("\n🛑 Downloads cancelled by user")),process.exit(0)),"p"===r.toLowerCase()&&(o.isPaused()?o.resumeAll():o.pauseAll()),"a"!==r.toLowerCase()||o.isAddingUrl()||await async function(o){o.setAddingUrl(!0);try{console.log(g.cyan("\n📥 Enter URL to add (or press Enter to cancel):"));const a=s.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>a.question("",t=>{a.close(),e(t.trim())}));if(n&&J(n)){const a=V(n,process.cwd()),s=t.isAbsolute(a)?a:t.join(process.cwd(),a);try{const o=t.dirname(s);e.existsSync(o)||e.mkdirSync(o,{recursive:!0})}catch(r){return void console.error(g.error.bold("❌ Could not create output dir: ")+r.message)}o.hasMultiBar()?await o.addToMultipleDownloads(n,s,a):o.downloadFile(n,s).catch(e=>console.error(g.error(`❌ ${e.message}`))),console.log(g.success("🚀 New download started!"))}else n?console.log(g.error("❌ Invalid URL.")):console.log(g.warning("⚠️ Cancelled."))}catch(r){console.error(g.error("❌ Error: ")+r.message)}finally{o.setAddingUrl(!1),console.log(o.isPaused()?g.warning("⏸️ Still paused. Press p to resume, a to add URL."):g.success("▶️ Downloads active. Press p to pause, a to add URL."))}}(o)}))}function J(e){try{return new URL(e),!0}catch{return!1}}function V(o,r){let a;try{a=t.basename(new URL(o).pathname)||"downloaded-file"}catch{a="downloaded-file"}if(!r)return a;const s=t.extname(a),n=s?a.slice(0,-s.length):a;let l=a,i=1;for(;e.existsSync(t.join(r,l));)l=`${n}(${i})${s}`,i++;return l}function Y(e){try{return t.extname(new URL(e).pathname).toLowerCase()}catch{return""}}function Z(e){return g.yellow("{filename}")+" "+g.cyan("{spinner}")+" "+e+"{bar} "+g.success("{percentage}%")+" "+g.info("{downloadedDisplay}")+" "+g.info("{totalDisplay}")+" "+g.purple("{speed}")+" "+g.pink("{etaFormatted}")}function Q(e,t,o){return{format:Z(e),barCompleteChar:"█",barIncompleteChar:"░",barGlue:t,barsize:o}}function X(e){return{filename:"",spinner:e[0],speed:x("0B"),progress:B(0),downloadedDisplay:y(0),totalDisplay:D(0),etaFormatted:b(0),percentage:" 0".padStart(3)}}async function ee(t,o,r,a){const{bar:s,spinnerFrames:i,download:d}=t,{url:c,outputPath:u,filename:p}=d,h=a.stateFilePath(u),f=u+".tmp";try{const d=new AbortController;a.pushAbortController(d);const p=await K(c,d.signal),g=q(h),w=G(f),{startByte:C,resuming:x}=W(p,g,w,f,h),F={};x&&C>0&&(F.Range=`bytes=${C}-`);const P=await fetch(c,{headers:F,signal:d.signal});if(!P.ok)throw new Error(`HTTP ${P.status}`);const v=P.headers.get("content-length"),M=x?p.totalSize:v?parseInt(v,10):0;N(h,{url:c,outputPath:u,totalSize:M,startByte:C,lastModified:p.lastModified,etag:p.etag,timestamp:(new Date).toISOString()}),s.setTotal(M||100),s.update(C,{progress:B(C),downloadedDisplay:y(C),totalDisplay:D(M)});const T=e.createWriteStream(f,{flags:x?"a":"w"});let $=C,R=Date.now(),z=$;const O=new l.Readable({read(){}}),L=P.body.getReader();(async()=>{try{for(;;){for(;a.isPaused;)await new Promise(e=>setTimeout(e,100));const{done:e,value:n}=await L.read();if(e){O.push(null);break}$+=n.length;const l=Date.now(),d=(l-R)/1e3;l-t.lastFrameUpdate>=150&&(t.spinnerIndex=(t.spinnerIndex+1)%i.length,t.lastFrameUpdate=l,s.options.barsize=U(i[t.spinnerIndex],m)),l-t.lastSpinnerUpdate>=45e3&&(t.spinnerFrames=E(A()),t.spinnerIndex=0,t.lastSpinnerUpdate=l);const c={spinner:i[t.spinnerIndex],progress:B($),downloadedDisplay:y($),totalDisplay:D(M)};if(d>=.3){s.update($,c);const e=t.download.index??0;r.totalDownloaded+=$-z,r.individualDownloaded[e]=$,r.individualSizes[e]=M,r.totalSize=r.individualSizes.reduce((e,t)=>e+t,0),void 0!==r.actualTotalSize&&(r.actualTotalSize=r.totalSize),M>0&&r.individualSizes[e]===M&&o?.setTotal(r.totalSize),R=l,z=$}else s.update($,c);O.push(Buffer.from(n))}}catch(e){O.destroy(e)}})(),await n.pipeline(O,T),e.existsSync(u)&&e.unlinkSync(u),e.renameSync(f,u),_(h);const k=r.individualSizes.reduce((e,t)=>e+t,0),I=k>0?k:r.actualTotalSize||r.totalSize;o?.update(r.totalDownloaded,{progress:S(r.totalDownloaded,I),downloadedDisplay:y(r.totalDownloaded),totalDisplay:D(I),etaFormatted:b((Date.now()-(r.individualStartTimes?.[0]??Date.now()))/1e3)})}catch(w){throw s.update(s.total,{spinner:"❌",speed:x("FAILED"),downloadedDisplay:y(0),totalDisplay:D(0)}),console.log(g.info(`💾 Partial download saved for ${p}. Restart to resume.`)),w}}class te{progressBar=null;multiBar=null;loadingSpinner=null;abortController=null;abortControllers=[];isPaused=!1;pauseCallback=null;resumeCallback=null;isAddingUrl=!1;stateDir;COL_FILENAME=25;COL_SPINNER=2;COL_BAR=m;COL_PERCENT=4;COL_DOWNLOADED=16;COL_TOTAL=10;COL_SPEED=10;COL_ETA=10;colors=g;formatBytes=f;formatBytesCompact=y;formatTotalDisplay=D;formatTotal=C;formatETA=b;formatMasterProgress=S;formatProgress=B;formatSpeed=x;formatSpeedDisplay=F;formatTotalSpeed=P;truncateFilename=w;getSpinnerFrames=E;getRandomSpinner=A;getRandomOraSpinner=R;getSpinnerWidth=z;calculateBarSize=U;getRandomBarColor=k;getRandomBarGlueColor=I;isValidUrl=J;generateFilename=V;getFileExtension=Y;getRandomColor(){return g.gradient[Math.floor(Math.random()*g.gradient.length)]}constructor(){this.stateDir=function(t){try{return e.existsSync(t)||e.mkdirSync(t,{recursive:!0}),t}catch{return console.log(g.warning("⚠️ Could not create state directory, using current directory")),process.cwd()}}(process.env.GRAB_DOWNLOAD_STATE_DIR||t.join(process.cwd(),".grab-downloads"))}setPauseCallback(e){this.pauseCallback=e}setResumeCallback(e){this.resumeCallback=e}pauseAll(){this.isPaused=!0,console.log(g.warning("⏸️ Pausing all downloads...")),this.pauseCallback?.()}resumeAll(){this.isPaused=!1,console.log(g.success("▶️ Resuming all downloads...")),this.resumeCallback?.()}cleanup(){this.loadingSpinner?.isSpinning&&this.loadingSpinner.stop(),this.progressBar&&this.progressBar.stop(),this.multiBar&&this.multiBar.stop(),this.abortController&&this.abortController.abort(),process.stdin.isTTY&&(process.stdin.setRawMode(!1),process.stdin.pause())}setupGlobalKeyboardListener(){H({isPaused:()=>this.isPaused,pauseAll:()=>this.pauseAll(),resumeAll:()=>this.resumeAll(),isAddingUrl:()=>this.isAddingUrl,setAddingUrl:e=>{this.isAddingUrl=e},hasMultiBar:()=>!!this.multiBar,addToMultipleDownloads:(e,t,o)=>this.addToMultipleDownloads(e,t,o),downloadFile:(e,t)=>this.downloadFile(e,t)})}async downloadFile(t,o){const a={isPaused:this.isPaused,progressBar:this.progressBar,abortController:this.abortController,stateFilePath:e=>j(this.stateDir,e),setupKeyboard:()=>this.setupGlobalKeyboardListener()};Object.defineProperty(a,"isPaused",{get:()=>this.isPaused}),await async function(t,o,a){const s=a.stateFilePath(o),d=o+".tmp";try{a.abortController=new AbortController;const c=await K(t,a.abortController.signal),u=q(s),p=G(d);let{startByte:h,resuming:w}=W(c,u,p,d,s);const S={};w&&h>0&&(S.Range=`bytes=${h}-`);const C=await fetch(t,{headers:S,signal:a.abortController.signal});if(!C.ok)throw new Error(`HTTP ${C.status}`);const P=C.headers.get("content-length"),v=w?c.totalSize:P?parseInt(P,10):0;w||(0===v?console.log(g.warning("⚠️ Content-Length not provided")):console.log(g.info(`📦 File size: ${D(v)}`))),N(s,{url:t,outputPath:o,totalSize:v,startByte:h,lastModified:c.lastModified,etag:c.etag,timestamp:(new Date).toISOString()});const M=k(),T=I();let $=E(A()),R=0,z=Date.now(),O=Date.now();a.setupKeyboard(),a.progressBar=new i.SingleBar({format:g.success("{percentage}%")+" "+g.cyan("{spinner}")+" "+M+"{bar} "+g.info("{downloadedDisplay}")+" "+g.info("{totalDisplay}")+" "+g.purple("{speed}")+" "+g.pink("{etaFormatted}"),barCompleteChar:"█",barIncompleteChar:"░",barGlue:T,hideCursor:!0,barsize:U($[0],m),stopOnComplete:!0,clearOnComplete:!1}),a.progressBar.start(v||100,h,{speed:x("0B/s"),etaFormatted:b(0),spinner:$[0],progress:B(h),downloadedDisplay:y(h),totalDisplay:D(v)});const L=e.createWriteStream(d,{flags:w?"a":"w"});let j=h,H=0,J=Date.now(),V=j;const Y=new l.Readable({read(){}}),Z=C.body.getReader();(async()=>{try{for(;;){for(;a.isPaused;)await new Promise(e=>setTimeout(e,100));const{done:e,value:t}=await Z.read();if(e){Y.push(null);break}H+=t.length,j+=t.length;const o=Date.now(),r=(o-J)/1e3;o-z>=45e3&&($=E(A()),R=0,z=o),o-O>=120&&(R=(R+1)%$.length,O=o,a.progressBar.options.barsize=U($[R],m));const s={spinner:$[R],progress:B(j),downloadedDisplay:y(j),totalDisplay:D(v)};if(r>=.3){const e=(j-V)/r;a.progressBar.update(j,{...s,speed:x(F(e)),etaFormatted:b(v>0?(v-j)/e:0)}),J=o,V=j}else a.progressBar.update(j,s);Y.push(Buffer.from(t))}}catch(e){Y.destroy(e)}})(),await n.pipeline(Y,L),a.progressBar.stop(),e.existsSync(o)&&e.unlinkSync(o),e.renameSync(d,o),_(s),console.log(g.success("✅ Download completed!")),console.log(g.primary("📁 Saved to: ")+r.underline(o)),console.log(g.purple("📊 Total: ")+f(j)),w&&(console.log(g.info("🔄 Resumed from: ")+f(h)),console.log(g.info("📥 This session: ")+f(H)));const Q=["🥳","🎊","🎈","🌟","💯","🚀","✨","🔥"];console.log(g.success(`${Q[Math.floor(Math.random()*Q.length)]} Done!`))}catch(c){throw a.progressBar&&a.progressBar.stop(),console.error(g.error.bold("💥 Download failed: ")+g.warning(c.message)),console.log("AbortError"===c.name?g.info("💾 State saved. Run the same command to resume."):g.info("💾 Partial download saved. Restart to resume.")),c}}(t,o,a),this.progressBar=a.progressBar,this.abortController=a.abortController}async downloadMultipleFiles(e){const t={isPaused:!1,multiBar:null,abortControllers:this.abortControllers,stateFilePath:e=>j(this.stateDir,e),setupKeyboard:()=>this.setupGlobalKeyboardListener(),pushAbortController:e=>this.abortControllers.push(e)};Object.defineProperty(t,"isPaused",{get:()=>this.isPaused}),await async function(e,t){try{t.setupKeyboard();const o=k(),r=I();t.multiBar=new i.MultiBar({format:g.success("{percentage}%")+" "+g.yellow("{filename}")+" "+g.cyan("{spinner}")+" "+o+"{bar} "+g.info("{downloadedDisplay}")+" "+g.info("{totalDisplay}")+" "+g.purple("{speed}")+" "+g.pink("{etaFormatted}"),hideCursor:!0,clearOnComplete:!1,stopOnComplete:!0,autopadding:!1,barCompleteChar:"█",barIncompleteChar:"░",barGlue:r,barsize:m});const a=e.length,s=1===a,n=new Array(a).fill(0),l=new Array(a).fill(0),d=new Array(a).fill(0),c=new Array(a).fill(Date.now());let u=new Array(a).fill(0),p=Date.now(),h=e.reduce((e,t)=>e+(t.estimatedSize??104857600),0),f=null;if(!s){const e=z("⬇️");f=t.multiBar.create(h,0,{filename:"Total".padEnd(25-e),spinner:"⬇️",speed:"0B".padEnd(10),progress:S(0,h),downloadedDisplay:y(0),totalDisplay:D(h),etaFormatted:b(0),percentage:" 0".padStart(3)},{format:g.success("{percentage}%")+" "+g.yellow.bold("{filename}")+" "+g.success("{spinner}")+" {bar} "+g.info("{downloadedDisplay}")+" "+g.info("{totalDisplay}")+" "+g.purple("{speed}")+" "+g.pink("{etaFormatted}"),barCompleteChar:"▶",barIncompleteChar:"▷",barGlue:"",barsize:U("⬇️",m)})}const C=e.map((e,o)=>{const r=E(A()),a=z(r[0]),s=k(),n=I();return{bar:t.multiBar.create(100,0,{...X(r),filename:w(e.filename,25-a)},Q(s,n,U(r[0],m))),spinnerFrames:r,spinnerIndex:0,lastSpinnerUpdate:Date.now(),lastFrameUpdate:Date.now(),download:{...e,index:o}}}),v=setInterval(()=>{const e=Date.now(),t=(e-p)/1e3;for(let c=0;c<a;c++)t>0&&(n[c]=(d[c]-u[c])/t,C[c]?.bar?.update(d[c],{speed:x(F(n[c])),progress:B(d[c],l[c]),downloadedDisplay:y(d[c]),totalDisplay:D(l[c]),etaFormatted:l[c]>0?b((l[c]-d[c])/n[c]):b(0)}));p=e,u=[...d];const o=n.reduce((e,t)=>e+t,0),r=d.reduce((e,t)=>e+t,0),s=l.reduce((e,t)=>e+t,0),i=s>0?s:h;f?.update(r,{speed:P(o),progress:S(r,i),downloadedDisplay:y(r),totalDisplay:D(i),etaFormatted:b((e-c[0])/1e3),percentage:i>0?Math.round(r/i*100):0})},1e3),M={totalDownloaded:0,totalSize:h,individualSpeeds:n,individualSizes:l,individualDownloaded:d,individualStartTimes:c,lastTotalUpdate:Date.now(),lastTotalDownloaded:0,actualTotalSize:0},T=await Promise.allSettled(C.map(async(e,o)=>{try{return await ee(e,f,M,t),{success:!0,i:o,filename:e.download.filename}}catch(r){return{success:!1,i:o,filename:e.download.filename,error:r}}}));clearInterval(v),t.multiBar.stop();const $=T.filter(e=>"fulfilled"===e.status&&e.value.success).length,R=T.length-$;R>0&&(console.log(g.error(`❌ Failed: ${R}/${a}`)),T.forEach((t,o)=>{if("rejected"===t.status||!t.value.success){const r=t.reason??t.value?.error??"unknown";console.log(g.error(` • ${e[o].filename}: ${r.message??r}`))}}));const O=["🥳","🎊","🎈","🌟","💯","🚀","✨","🔥"];console.log(g.green(`${O[Math.floor(Math.random()*O.length)]} Success: ${$}/${a}`)),t.abortControllers=[]}catch(o){throw t.multiBar&&t.multiBar.stop(),console.error(g.error.bold("💥 Batch download failed: ")+g.warning(o.message)),o}}(e,t),this.multiBar=t.multiBar,this.abortControllers=t.abortControllers}async downloadSingleFileWithBar(e,t,o,r){const a={isPaused:!1,multiBar:this.multiBar,abortControllers:this.abortControllers,stateFilePath:e=>j(this.stateDir,e),setupKeyboard:()=>this.setupGlobalKeyboardListener(),pushAbortController:e=>this.abortControllers.push(e)};Object.defineProperty(a,"isPaused",{get:()=>this.isPaused}),await ee(e,t,r,a)}async addToMultipleDownloads(e,t,o){const r={isPaused:!1,multiBar:this.multiBar,abortControllers:this.abortControllers,stateFilePath:e=>j(this.stateDir,e),setupKeyboard:()=>{},pushAbortController:e=>this.abortControllers.push(e)};Object.defineProperty(r,"isPaused",{get:()=>this.isPaused}),await async function(e,t,o,r){const a=E(A()),s=z(a[0]),n=k(),l=I(),i=U(a[0],m);ee({bar:r.multiBar.create(100,0,{...X(a),filename:w(o,25-s)},Q(n,l,i)),spinnerFrames:a,spinnerIndex:0,lastSpinnerUpdate:Date.now(),lastFrameUpdate:Date.now(),download:{url:e,outputPath:t,filename:o,index:1}},null,{totalDownloaded:0,totalSize:0,individualSpeeds:[],individualSizes:[],individualDownloaded:[],individualStartTimes:[],lastTotalUpdate:Date.now(),lastTotalDownloaded:0,actualTotalSize:0},r).catch(e=>console.error(g.error(`❌ ${o}: ${e.message}`)))}(e,t,o,r)}}t.dirname(o.fileURLToPath("undefined"==typeof document?require("url").pathToFileURL(__filename).href:u&&"SCRIPT"===u.tagName.toUpperCase()&&u.src||new URL("grab-url-cli.cjs.js",document.baseURI).href));if((()=>{try{const e=process.argv[1]?t.resolve(process.argv[1]):"";return!!e&&("undefined"==typeof document?require("url").pathToFileURL(__filename).href:u&&"SCRIPT"===u.tagName.toUpperCase()&&u.src||new URL("grab-url-cli.cjs.js",document.baseURI).href)===o.pathToFileURL(e).href}catch{return!1}})()){const o=(new p).usage("Usage: grab-url <url...> [options]").command("$0 <url>","Fetch data or download files; pass one or more URLs").option("no-save",{type:"boolean",default:!1,describe:"Don't save output to file, just print to console"}).option("output",{alias:"o",type:"string",describe:"Output filename (default: output.json)",default:null}).option("params",{alias:"p",type:"string",describe:'JSON string of query parameters (e.g., \'{"key":"value"}\')',coerce:e=>{if(!e)return{};try{return JSON.parse(e)}catch{throw new Error(`Invalid JSON in params: ${e}`)}}}).help().alias("h","help").example("grab-url https://api.example.com/data","Fetch JSON/text from an API and save to output.json").example("grab-url https://example.com/file1.zip https://example.com/file2.zip","Download multiple files concurrently").example("grab-url https://example.com/file.iso -o ubuntu.iso","Save the first URL to a custom filename").version("1.1.0").strict().parseSync(),s=o.urls||[],n=o.params||{},l=o.output,i=o["no-save"],u=s.some(h),m=s.length>1||u;(async()=>{if(m){const n=new te,i=s.map((o,a)=>{let s=0===a&&l?l:n.generateFilename(o,process.cwd());const i=t.isAbsolute(s)?s:t.join(process.cwd(),s),d=t.dirname(i);try{e.existsSync(d)||e.mkdirSync(d,{recursive:!0})}catch(c){console.error(r.red.bold("❌ Could not create output directory: ")+c.message),process.exit(1)}return{url:o,outputPath:i,filename:t.basename(s)}});try{await n.downloadMultipleFiles(i);const t=new a({head:["Filename","Size","Created"],colWidths:[32,14,25],colAligns:["left","right","left"],style:{"padding-left":1,"padding-right":1,head:[],border:[]}});i.forEach(o=>{try{const r=e.statSync(o.outputPath);t.push([o.filename,n.formatBytes(r.size),r.birthtime.toLocaleString()])}catch{t.push([o.filename,"Error","Could not read"])}}),console.log(r.cyan.bold("\nFile Details:")),console.log(t.toString())}catch(o){console.error(r.red.bold("Failed to download files: ")+r.yellow(o.message)),process.exit(1)}n.cleanup()}else{const r=s[0],a=process.hrtime();try{const o=await d.default(r,n);o.error&&c.log(`\n\nStatus: ❌ ${o.error}`);let s,u=null,p=!1;if("string"==typeof o.data?(s=o.data,p=!0):Buffer.isBuffer(o.data)||o.data instanceof Uint8Array?(s=o.data,p=!1):o.data instanceof Blob?(s=Buffer.from(await o.data.arrayBuffer()),p=!1):o.data&&"object"==typeof o.data?(s=JSON.stringify(o.data,null,2),p=!0):(s=String(o.data),p=!0),i)p?c.log(s):c.log(`Binary data received (${s.length} bytes). Use --output to save to file.`);else{const o=new URL(r).pathname,n=t.extname(o),i=p?".json":n||".bin";u=l?t.resolve(l):t.resolve(process.cwd(),`output${i}`),p?e.writeFileSync(u,s,"utf8"):e.writeFileSync(u,s);const[d,h]=process.hrtime(a),m=(d+h/1e9).toFixed(2),g=(e.statSync(u).size/1048576).toFixed(1);c.log(`⏱️ ${m}s 📦 ${g}MB ✅ Saved to: ${u}`)}}catch(o){c.log(`Error: ${o.message}`,{color:"red"}),process.exit(1)}}})()}exports.ArgParser=p,exports.MultiColorFileDownloaderCLI=te,exports.generateFilename=V,exports.getFileExtension=Y,exports.isFileUrl=h,exports.isValidUrl=J;
3
3
  //# sourceMappingURL=grab-url-cli.cjs.js.map