Giter Club home page Giter Club logo

node-unrar.js's Introduction

node-unrar-js

Build Status npm version MIT License TypeScript

node-unrar.js is a npm module to extract rar archive in pure JavaScript. It's combined by a Javascript adoption layer and JavaScript unRar library compiled by Emscripten from the C++ unrar library which hosted on http://www.rarlab.com/rar_add.htm .

Installation

You can install the module via npm:

npm install node-unrar-js

Features

  • Fully support for RAR archive, because it comes from the official source code.
  • Unicode support, for both comment and file path/name.
  • API for Extraction to both memory and file system.
  • Both Commonjs module (for nodejs) and ES2015 module (for webpack) are supported.

Unsupported Features

  • Volume archives are not supported.
  • Synchronize File System IO functions are used in File Extraction.

API to create the extractor

  • async function createExtractorFromData(options: ExtractorFromDataOptions): Promise<Extractor<Uint8Array>> - Create the in Memory Extractor

    Options ExtractorFromDataOptions:

    • data: ArrayBuffer : ArrayBuffer object of the RAR archive file
    • password?: string : Optional password
    • wasmBinary? ArrayBuffer; : Optional Use in browser/webpack, the wasm binary must be loaded in the code and send to this function to load the wasm code
  • async function createExtractorFromFile(options: ExtractorFromFileOptions): Promise<Extractor> - Get the File Extractor

    Options ExtractorFromFileOptions:

    • filepath: string : File path of the RAR archive file
    • targetPath?: string : Optional target folder
    • password?: string : Optional password
    • filenameTransform?: (filename: string) => string: Optional transform the file name before it's created on file system
    • wasmBinary? ArrayBuffer; : Optional Use in nodejs/webpack, the wasm binary must be loaded in the code and send to this function to load the wasm code in webpack based nodejs project (please read Used in Webpack-bundled NodeJS Project for more details).

    Node: This function is not available in EM2015 Module since the EM2015 Module is used for webpack in Browser.

API of the extractor

  • getFileList(): ArcList : Get the file header and file list of the archive.

    Members in ArcList:

    • arcHeader: ArcHeader : The header of the archive
    • fileHeaders: Generator<FileHeader> : The iterator of the FileHeader objects
{
  arcHeader: {
    comment: "",
    flags: {
      authInfo: false,
      headerEncrypted: false,
      lock: false,
      recoveryRecord: false,
      solid: false,
      volume: false,
    },
  }, fileHeaders: (Iterator)
    {
      crc: 0,
      flags: {
        directory: false,
        encrypted: false,
        solid: false,
      },
      method: "Storing",
      name: "FileName",
      packSize: 0,
      time: "2017-04-03T10:41:42.000",
      unpSize: 0,
      unpVer: "2.9",
      comment: "",
    },
}
  • extract(options: ExtractOptions): Extract the files.
    • Options ExtractOptions:
      • files?: string[] | ((fileHeader: FileHeader) => boolean) Optional Extract all the files if files is empty
        • string[]: Extract the specific files only
        • (fileHeader: FileHeader) => boolean: Extract only the filtered file (eg. extract only the files without password).
      • password?: string: Optional password for the extracted files only (Different password can be applied to any single file in RAR archive).
    • The return values are different for createExtractorFromData and createExtractorFromFile:
      • ArcFiles<Uint8Array> for createExtractorFromData
      • ArcFiles for createExtractorFromFile
    • Members in ArcFiles:
      • arcHeader: ArcHeader : The header of the archive
      • files: Generator<ArcFile> : The iterator of the ArcFile objects
      • Members in ArcFile:
        • fileHeader: FileHeader : The header of the extracted file
        • extraction?: Uint8Array : The extracted content of the file (createExtractorFromData only). If the ArcFile is a folder (ArcFile.fileHeader.flags.directory is true), the extraction will be undefined, otherwise it will be the content of the file (in `Uint8Array).
{
  arcHeader: {...} // Same as the arcHeader above
  files: (Iterator)
    {
      fileHeader: {...} // Same as the fileHeader above
      extraction?: Uint8Array // createExtractorFromData only
  ]
}

Note: The returned iterators from the two apis are lazy, it means the file header/content will not be parsed/extracted if any file is not iterated yet.

Exception

The customized Error Object UnrarError will be thrown for any exception in extracting. The definition of the Object is:

class UnrarError extends Error {
    reason: FailReason;
    file?: string | undefined; // Will be filled for any exception in extraction of a file
}

The following code is used in the FailReason:

FailReason Message
ERAR_NO_MEMORY Not enough memory
ERAR_BAD_DATA Archive header or data are damaged
ERAR_BAD_ARCHIVE File is not RAR archive
ERAR_UNKNOWN_FORMAT Unknown archive format
ERAR_EOPEN File open error
ERAR_ECREATE File create error
ERAR_ECLOSE File close error
ERAR_EREAD File read error
ERAR_EWRITE File write error
ERAR_SMALL_BUF Buffer for archive comment is too small, comment truncated
ERAR_UNKNOWN Unknown error
ERAR_MISSING_PASSWORD Password for encrypted file or header is not specified
ERAR_EREFERENCE Cannot open file source for reference record
ERAR_BAD_PASSWORD Wrong password is specified

Memory Leak

Note: although the return value fileHeaders and files are iterators, they must be traversed to the end! Otherwise the C++ object for archive extraction will not be destructed and cause memory leak.

Example

const fs = require("fs");
const unrar = require("node-unrar-js");

async function main() {
  // Read the archive file into a typedArray
  const buf = Uint8Array.from(fs.readFileSync("a.rar")).buffer;
  const extractor = await unrar.createExtractorFromData({ data: buf });

  const list = extractor.getFileList();
  const listArcHeader = list.arcHeader; // archive header
  const fileHeaders = [...list.fileHeaders]; // load the file headers

  const extracted = extractor.extract({ files: ["1.txt"] });
  // extracted.arcHeader  : archive header
  const files = [...extracted.files]; //load the files
  files[0].fileHeader; // file header
  files[0].extraction; // Uint8Array content, createExtractorFromData only
}
main();

Demo in Webpack

This package can also be used in browser by Webpack, please visit the demo project to see how to use it in webpack.

Use in Webpack-bundled NodeJS Project

In most cases the exported ESModule is used in browser by Webpack, but in case if the NodeJs project (or an Electron project) is bundled by Webpack, the wasmBinary data must be loaded manually just like the browser by Webpack, it can be loaded like this:

import fs from 'fs';
import { createExtractorFromFile } from 'node-unrar-js/esm';

const wasmBinary = fs.readFileSync(require.resolve('node-unrar-js/esm/js/unrar.wasm'));

const extractor = await createExtractorFromFile({ wasmBinary, filepath: './WithComment.rar' });

// const list = extractor.getFileList();

Note: the package must be loaded from 'node-unrar-js/esm' instead of 'node-unrar-js' to enable the function createExtractorFromFile in ES Module.

TypeScript

This module is written in TypeScript, you can import it directly in TypeScript and get the benefit of static type checking and auto-complete of IDE.

Development and Contribution

If you want to compile the module by yourself, please follow the steps below:

  • Install the docker

  • Download the c++ source of unRar library by:

npm run downloadUnrarSrc

  • Build for debug:

npm run build:debug

  • Build for release

npm run build:release

  • Run Test

npm run test

License

This module is licensed under MIT.

node-unrar.js's People

Contributors

dependabot[bot] avatar jianrong-yu avatar semantic-release-bot avatar yujianrong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

node-unrar.js's Issues

用新版本解压不出文件,但是也没有报错

[email protected]版本可以运行并且调用createExtractorFromFile({ filepath, targetPath })方法创建extrator,但是执行extrator.extract(),并没有把文件解压到targetPath,我以为是targetPath无效并且应该有个默认目录,但是我在finder中全局搜索了并没有找到压缩包中的文件,还是用之前的例子( #316 )把版本更新到2.1.0-beta.1就可以复现。

How unrar parts

Its posibble to unrar files rar like this:

archive.001.rar
archive.002.rar
archive.003.rar

How can extract this ?

Installing on windows fails

I've installed this package in my project before but when trying to move to a new package manager and reinstall my packages , I get an error with the following

OS : Windows 11 22H2
Node version : 21.1.0
PNPM Version: 8.10.3

node_modules/node-unrar-js postinstall$ wget https://www.rarlab.com/rar/unrarsrc-6.1.7.tar.gz && tar -xf unrarsrc-6.1.7.tar.gz -C …
│ --2023-11-22 03:50:22--  https://www.rarlab.com/rar/unrarsrc-6.1.7.tar.gz
│ Resolving www.rarlab.com (www.rarlab.com)... 51.195.68.162
│ Connecting to www.rarlab.com (www.rarlab.com)|51.195.68.162|:443... connected.
│ HTTP request sent, awaiting response... 200
│ Length: 236798 (231K) [application/x-gzip]
│ Saving to: 'unrarsrc-6.1.7.tar.gz'
│      0K .......... .......... .......... .......... .......... 21%  161K 1s
│     50K .......... .......... .......... .......... .......... 43%  251K 1s
│    100K .......... .......... .......... .......... .......... 64%  227K 0s
│    150K .......... .......... .......... .......... .......... 86%  305K 0s
│    200K .......... .......... .......... .                    100%  433K=1.0s
│ 2023-11-22 03:50:25 (239 KB/s) - 'unrarsrc-6.1.7.tar.gz' saved [236798/236798]
│ tar: could not chdir to 'src/cpp'

This error hadn't happened before

createExtractorFromFile extract file larger than 2GB

In my case, I would like to extract a 2GB file and use createExtractorFromFile instead of createExtractorFromData. (from issue #103)
Here is my code.

const unrar = require('node-unrar-js')
const extractObject = 'd:/testrar/wj2GB.rar'
const extractor = await unrar.createExtractorFromFile({ filepath: extractObject })
const list = extractor.getFileList() //line 81
const fileHeaders = [...list.fileHeaders] 

Error is:

UnrarError: File read error
    at ExtractorFile.getFailException (D:\gitlab\laborer\node_modules\?[4mnode-unrar-js?[24m\dist\js\Extractor.js:187:16)
    at ExtractorFile.openArc (D:\gitlab\laborer\node_modules\?[4mnode-unrar-js?[24m\dist\js\Extractor.js:108:24)
    at ExtractorFile.getFileList (D:\gitlab\laborer\node_modules\?[4mnode-unrar-js?[24m\dist\js\Extractor.js:54:32)
    at extractRAR (D:\gitlab\laborer\example\local\extractLocalObject.js:81:26) {
  reason: ?[32m'ERAR_EREAD'?[39m,
  file: ?[90mundefined?[39m
}

when I change wj2GB.rar to a smaller file, the program works well.

Wrong getFileList() from this file

UnrarError: File read error
    at ExtractorData.getFailException (/home/mx-vankaiser/Projects/test/node_modules/node-unrar-js/dist/js/Extractor.js:187:16)
    at ExtractorData.openArc (/home/mx-vankaiser/Projects/test/node_modules/node-unrar-js/dist/js/Extractor.js:108:24)
    at ExtractorData.getFileList (/home/mx-vankaiser/Projects/test/node_modules/node-unrar-js/dist/js/Extractor.js:54:32)
    at main (/home/mx-vankaiser/Projects/test/nodeunrarjs.js:9:26) {
  reason: 'ERAR_EREAD',
  file: undefined
}

the-rocky-horror-picture-show_spanish-138854.rar.zip

extractor.extractAll() doesn't work

I was able to view the extracted file lists but when I ran extractor.extractAll(), it didn't output anything to working dir.

I'm using Windows 10

Z_DATA_ERROR

Hi, trying to unzip the a GZ file and I get the following error:

Error: incorrect header check
    at Zlib.zlibOnError [as onerror] (node:zlib:190:17) {
  errno: -3,
  code: 'Z_DATA_ERROR'
}

on my windows machine I'm unable to extract it without any issue.
Any idea?

很高兴认识您!

很高兴认识您,我们在用c++来实现一套自己的flash player runtime,保留其强大的API功能,并能以wasm的方式运行在浏览器中,现已完成了基础部分。目的是让强大的flash API能继续运行在浏览器上使用wasm而不依赖flash player,同时支持JS/ TS以及原有AS3这些脚本语言在上层无缝运行,当然这套API也同时能在c++层使用当作一个跨平台底层(所有原生端,和wasm),大幅度提高c++前端开发的敏捷性。我们通过半年重构了embind以及编写了大量脚本层编译器和工具,渲染用的OpenGL(OpenGL3.0/4.0,提及gles2/es3),根据编译平台对应的各filesystem,IO等等(当编译wasm时,emsdk里实现了很多c++层的API映射,然后通过libXXX.js实现在c++层extern的回调,为了还原flash api,我们自己也做了很多libs)目前已经能将AS3和JS跑在我们这个wasm的runtime了,其功能和开发便利性和之前的flash player一样。这个是我们的github的 demo。readme里面有几个demo,原生c++ exe,c++ wasm, as3 js wam.
我们目前打算完善其API,并在18年4月开始制作一款3D全目标引擎基于这套API以及其工具层。我们现在在大量募集志同道合的国人兄弟们,咱们一起做一个国人自己的前沿平台,让这块领域不再是鬼佬的专利。我们现在资金充裕,是在一家国内大公司下的实验室,各方面都很稳定。我的Q:616267056,希望能得到你的注意!
https://github.com/JasonHuang3D/AJC-Flash-WebAssembly-Examples/

Unrar big files

Hi this is a very good package to work with ."rar", but it can't unpack the archive if it weighs more than 32 GB. My file weighs in at 6.5 GB when you unpack 58. WinRar on my windows handles well

Link to file

Stream-based Extractor

Currently, ExtractorData stores all data of the rar file in memory, and when extract() is called, each files inside are also kept in memory as Uint8Array extraction property.

This works fine for small rar file, but would run out of memory for big file.

Would you consider adding another Extractor that supports ReadableStream, both for the rar file, and the files inside it?

error:extractor.extract is not a function

const buf = Uint8Array.from(fs.readFileSync(zipFile)).buffer;
const extractor = unrar.createExtractorFromData({ data: buf });

      //  const list = extractor.getFileList();
      //  const listArcHeader = list.arcHeader; // archive header
       // const fileHeaders = [...list.fileHeaders]; // load the file headers
      
        const extracted = extractor.extract({ files: [zipTargetPath] });
        // extracted.arcHeader  : archive header
        const files = [...extracted.files]; //load the files

Error: File read error with any rar file.

import fs from 'fs/promises';
import unrar from 'node-unrar-js';

(async () => {
	const buf = Uint8Array.from(await fs.readFile("test.rar")).buffer;
	const extractor = await unrar.createExtractorFromData({ data: buf });
	const list = extractor.getFileList();
	const res = extractor.extract();
	console.log(list, res);
})();
Error: File read error
C:\Users\USER\DIR\node_modules\node-unrar-js\dist\js\unrar.js:9
var Module=typeof Module!=="undefined"?Module:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=true;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readBinary;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var getTempRet0=function(){return tempRet0};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm 
support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heap,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heap[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx<endPtr){var u0=heap[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heap[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heap[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heap[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function UTF16ToString(ptr,maxBytesToRead){var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343)++i;len+=4}return len}function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i<str.length;++i){HEAP8[buffer++>>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var wasmBinaryFile="unrar.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};

...
... *Char limit :(*
...





RuntimeError: abort(Error: File read error). Build with -s ASSERTIONS=1 for more info.

rar_inside.zip

createExtractorFromFile undefined with Electron (Webpack)

After digging for a while, I noticed the note at the bottom of your Webpack guide you mention createExtractorFromFile is unavailable due to fs and path requirements.

I wonder if you have any solution if I want to use this API in an Electron app that has Webpack. Here, both fs and path are available, so it should in theory work, unless I'm missing something?

I am by no means a pro when it comes to Webpack configuration so maybe it's not that complicated.

Reproduction

I use the Electron Forge template to get started.

yarn create electron-app my-app --template=typescript-webpack
yarn add node-unrar-js

If I now just open the index.ts file and import * as unrar from 'node-unrar-js' followed by console.log(unrar), it is now missing createExtractorFromFile. Is this fixable?

Note: using --template=typescript without Webpack works.

Support for custom extracted filename

It would be very helpful if there was a way to customize the name of the extracted file.

E.g. in my usecase I would append .partial to the extracted filename and when the extracting is finished I would remove that suffix. For a .rar file that contains 1 file, videofile.mkv, the library would extract to videofile.mkv.partial and like that it will not get picked up as 'complete' file by other software

a 模块未找到

env: macos M1
[email protected]
[email protected]

import { createExtractorFromFile } from 'node-unrar-js/esm';
const wasmBinary = fs.readFileSync(require.resolve('node-unrar-js/esm/js/unrar.wasm'));

const extractor = await createExtractorFromFile({
wasmBinary,
filepath,
targetPath
});

运行报错:
This dependency was not found:

  • a in ./node_modules/node-unrar-js/esm/js/unrar.wasm

To install it, you can run: npm install --save a
ERROR Build failed with errors.

Case sensitivity setting when extracting specific file

Given this code to extract ComicInfo.xml, from an archive, it is known that the filename will always be comicinfo.xml but the case is not known in advance.

// Read the archive file into a typedArray
const fileBuffer = await fse
    .readFile(filePath)
    .catch((err) => console.error("Failed to read file", err));
const extractor = await unrar.createExtractorFromData({
    data: fileBuffer,
});

const list = extractor.getFileList();
const listArcHeader = list.arcHeader; // archive header
const fileHeaders = [...list.fileHeaders]; // load the file headers

const extracted = extractor.extract({
    files: ["ComicInfo.xml"]
});
const files = [...extracted.files]; //load the files
console.log("asdas", files[0]);
return files[0].extraction;

How do I modify the code to extract all variations of comicinfo.xml (for e.g.: comicinfo.xml, ComicInfo.xml, comic_info.xml ?) Is there a regular expression I can use to match any variation?

Failed to fetch unrar.wasm

Confirmed on Windows 10, Ubuntu 22.04.
Since Node.js v18.1.0 I get the following error.

TypeError: Failed to parse URL from ...node-unrar-js/dist/js/unrar.wasm

const files = [...extracted.files] Hangs Entire Application

Hello, for some reason, when I run the command const files = [...extracted.files] it hangs my entire application. I have an app that downloads files, then is trying to unrar it. The files are only ~400mb, but, the whole app hangs on this line for ~5 seconds. Shows Not Responding on windows and the beachball on mac.

It is highly possible I am doing something wrong either in my node app or with this package. Any ideas on how to do this without hanging the rest of the application?

Thank you for your time.

Feature request: extract single archive entry to a specific file path

I would love an option to specify a specific extraction location for a single archive entry:

const rar = await unrar.createExtractorFromFile({filepath: 'some_file.rar'});

rar.extract({
  file: 'file_in_rar.txt',
  outputPath: '/home/some_other_filename.txt',
});

Specifying {targetPath: '/home'} doesn't solve the use case because I would still like to control the output filename.

Thank you!

Random force program exit (status code 7)

There is no extracting in progress, in this case the last extracted was 1 hour 22 minutes ago,

image

image

It seems that my extraction tasks are not exiting correctly; when the server encounters an error with exit status code 1, status code 7 always follows it!

async unrar(rardata) {
        try {
            const extractor = await unrar.createExtractorFromData({ data: rardata });
            const list = extractor.getFileList();
            //const listArcHeader = list.arcHeader; // archive header
            const fileHeaders = [...list.fileHeaders]; // load the file headers
            console.log('Rar files count:', fileHeaders.length);

            let files_head, file_head;
            files_head = fileHeaders.filter(header => this.checkExtension(header.name));

            if(files_head.length) {
                if(this.episode) {
                    if(files_head.length >= 2) {
                        file_head = files_head.find(header => this.checkEpisode(header.name).exactly());
                        if(!file_head)
                            file_head  = files_head.find(header => this.checkEpisode(header.name).estimate());
                    }
                }
            } else throw 'Unrar all files are not support!';

            if(!file_head) file_head = files_head[0];
            console.log("extract file:", file_head.name);
            
            const extracted = extractor.extract({ files: [file_head.name] });;
            // extracted.arcHeader  : archive header
            const files = [...extracted.files]; //load the files
            // files[0].fileHeader; // file header
            // files[0].extraction; // Uint8Array content, createExtractorFromData only

            return {
                name: files[0].fileHeader.name,
                data: files[0].extraction
            }
        } catch (err) {
            console.error(err);
        }
    }

Version: [email protected] (v2.0.1: #issue-2005466131)
Docker Images: node:18.18.2-bookworm-slim

Preserve order of uncompressed files

How can I ensure that the uncompressed files are in the exact order that they were inside the archive?

When I only want to extract the first file in the archive, I am getting different results each time. The file in question is a cbr comic archive. I'm trying to extract just the first file, naively assuming that it is the cover.

What is the best approach to go about this?

Iterator skips directory

v1.0.3

The iterator output by extractor.extract() does not contain a directory.
It is included in the iterator output by extractor.getFileList().
(As of v0.8.1, it was included in all APIs.)

const extracted = extractor.extract() 加一个选项吧 手动指定unrar的output目录...

特定环境云函数只有一个可读写/tmp 目录... 只能手动指定解压fromfile的时候 解压到 指定/tmp/自定义新目录,不然读写会报错

Error: ENOENT: no such file or directory, mkdir 'testfile1.htm'

    at Object.mkdirSync (fs.js:1013:3)

    at ExtractorFile.create (/var/user/node_modules/node-unrar-js/dist/js/ExtractorFile.js:54:16)

    at _jsCreate (/var/user/node_modules/node-unrar-js/dist/js/unrar.js:9:57667)

    at <anonymous>:wasm-function[278]:0x1bce6

    at <anonymous>:wasm-function[182]:0x12974

    at <anonymous>:wasm-function[417]:0x2cda4

    at invoke_iiii (/var/user/node_modules/node-unrar-js/dist/js/unrar.js:9:63577)

    at <anonymous>:wasm-function[420]:0x2e1f2

    at invoke_iiiii (/var/user/node_modules/node-unrar-js/dist/js/unrar.js:9:63411)

    at <anonymous>:wasm-function[216]:0x17021

Unable to decompress large file

I am extracting my data file about 5gb, I tried to filter out the necessary files, but after a while of unzipping, I get the following message.

image

How to use wasm file ?

hi,

i want to extract file by wasm , can you give me some suggestions ?

我想单独使用 wasm ,以使用各种功能,比如解压。我该怎么做?期待你的回复

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.