rar-stream 3.2.0 → 3.3.0

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.
package/README.md CHANGED
@@ -30,9 +30,8 @@ const rarFilesPackage = new RarFilesPackage(localRarFiles);
30
30
  async function writeInnerRarFilesToDisk() {
31
31
  const innerFiles = await rarFilesPackage.parse();
32
32
  for (const innerFile of innerFiles) {
33
- innerFile
34
- .createReadStream({ start: 0, end: innerFile.length - 1 })
35
- .pipe(fs.createWriteStream(innerFile.name));
33
+ const stream = await innerFile.createReadStream({ start: 0, end: innerFile.length - 1 })
34
+ stream.pipe(fs.createWriteStream(innerFile.name));
36
35
  }
37
36
  }
38
37
 
@@ -60,6 +59,31 @@ npm i rar-stream
60
59
  | _constructor_ | Takes an array of local file paths as strings or instances that satifies the [`FileMedia`](#filemedia-interface) interface mentioned below. |
61
60
  | parse | Parses all rar files and returns a Promise with [`InnerFile`](#innerfile-api)s. |
62
61
 
62
+ #### Filtering:
63
+
64
+ The `RarFilesPackage.parse()` method accepts one optional parameter that should be an object of options.
65
+
66
+ As parsing is done sequencially, `opts.filter` and `opts.maxFiles` can be used to filter and limit results.
67
+
68
+ Here is an example:
69
+ ```
70
+ {
71
+ filter: (fileName, fileIdx) => {
72
+ if (fileName.includes('Lorem Ipsum')) {
73
+ return true;
74
+ } else if (fileIdx === 9) {
75
+ return true;
76
+ }
77
+ return false;
78
+ },
79
+ maxFiles: 1
80
+ }
81
+ ```
82
+
83
+ The filter function will be called on each file entry from within the RAR archive and it will always include the name of the file and the file index. The filter function is expected to return a boolean value, if the returned value is `true` the file will be included in the parser's results.
84
+
85
+ The parser will stop processing the file list once it reaches the `maxFiles` limit of returned files.
86
+
63
87
  #### Events:
64
88
 
65
89
  | Event | Description |
@@ -84,10 +108,10 @@ Implements the [`FileMedia`](#filemedia-interface) interface.
84
108
 
85
109
  #### Methods:
86
110
 
87
- | Method | Description |
88
- | ---------------------------------------------- | ----------------------------------------------------------------------- |
89
- | createReadStream({start: number, end: number}) | Returns a `Readable` stream. The start and end interval is inclusive. |
90
- | readToEnd | Returns a Promise with a Buffer containing all the content of the file. |
111
+ | Method | Description |
112
+ | ---------------------------------------------- | ------------------------------------------------------------------------------------ |
113
+ | createReadStream({start: number, end: number}) | Returns a Promise with a `Readable` stream. The start and end interval is inclusive. |
114
+ | readToEnd | Returns a Promise with a Buffer containing all the content of the file. |
91
115
 
92
116
  #### Properties:
93
117
 
@@ -100,7 +124,7 @@ Implements the [`FileMedia`](#filemedia-interface) interface.
100
124
 
101
125
  ```
102
126
  const innerFiles = await rarStreamPackage.parse();
103
- const innerFileStream = innerFiles[0].createReadStream({ start: 0, end: 30});
127
+ const innerFileStream = await innerFiles[0].createReadStream({ start: 0, end: 30});
104
128
  ```
105
129
 
106
130
  ### _FileMedia Interface_
@@ -112,7 +136,7 @@ Should have the following shape:
112
136
  ```javascript
113
137
  // FileMedia
114
138
  {
115
- createReadStream(interval: Interval): Readable,
139
+ createReadStream(interval: Interval): Promise<Readable>,
116
140
  name: string,
117
141
  length: number // Length or size of the file in bytes
118
142
  }
package/dist/index.cjs CHANGED
@@ -4,7 +4,7 @@ var _events = require('events');
4
4
  // src/rar-file-bundle.ts
5
5
  var RXX_EXTENSION = /\.R(\d\d)$|.RAR$/i;
6
6
  var RAR_EXTENSION = /.RAR$/i;
7
- var PARTXX_RAR_EXTENSION = /.PART(\d\d).RAR/i;
7
+ var PARTXX_RAR_EXTENSION = /.PART(\d\d?\d?).RAR/i;
8
8
  var isPartXXExtension = (fileMedias = []) => {
9
9
  let anyPartXXTypes = fileMedias.filter(
10
10
  (file) => file.name && file.name.match(PARTXX_RAR_EXTENSION)
@@ -137,12 +137,12 @@ var InnerFileStream = class extends _stream.Readable {
137
137
  get isStarted() {
138
138
  return !!this.stream;
139
139
  }
140
- next() {
140
+ async next() {
141
141
  const chunk = this.rarFileChunks.shift();
142
142
  if (!chunk) {
143
143
  this.push(null);
144
144
  } else {
145
- this.stream = chunk.getStream();
145
+ this.stream = await chunk.getStream();
146
146
  _optionalChain([this, 'access', _4 => _4.stream, 'optionalAccess', _5 => _5.on, 'call', _6 => _6("data", (data) => this.pushData(data))]);
147
147
  _optionalChain([this, 'access', _7 => _7.stream, 'optionalAccess', _8 => _8.on, 'call', _9 => _9("end", () => this.next())]);
148
148
  }
@@ -193,10 +193,9 @@ var InnerFile = class {
193
193
  }
194
194
 
195
195
 
196
- readToEnd() {
197
- return streamToBuffer(
198
- this.createReadStream({ start: 0, end: this.length - 1 })
199
- );
196
+ async readToEnd() {
197
+ const stream = await this.createReadStream({ start: 0, end: this.length - 1 });
198
+ return streamToBuffer(stream);
200
199
  }
201
200
  getChunksToStream(fileStart, fileEnd) {
202
201
  const { index: startIndex, start: startOffset } = this.findMappedChunk(fileStart);
@@ -224,7 +223,9 @@ var InnerFile = class {
224
223
  if (start < 0 || end >= this.length) {
225
224
  throw Error("Illegal start/end offset");
226
225
  }
227
- return new InnerFileStream(this.getChunksToStream(start, end));
226
+ return Promise.resolve(
227
+ new InnerFileStream(this.getChunksToStream(start, end))
228
+ );
228
229
  }
229
230
  calculateChunkMap(rarFileChunks) {
230
231
  const chunkMap = [];
@@ -404,7 +405,7 @@ var TerminatorHeaderParser = (_class4 = class {
404
405
 
405
406
  // src/rar-files-package.ts
406
407
  var parseHeader = async (Parser, fileMedia, offset = 0) => {
407
- const stream = fileMedia.createReadStream({
408
+ const stream = await fileMedia.createReadStream({
408
409
  start: offset,
409
410
  end: offset + Parser.HEADER_SIZE
410
411
  });
@@ -418,7 +419,7 @@ var RarFilesPackage = class extends _events.EventEmitter {
418
419
  super();
419
420
  this.rarFileBundle = makeRarFileBundle(fileMedias);
420
421
  }
421
- async parseFile(rarFile) {
422
+ async parseFile(rarFile, opts) {
422
423
  const fileChunks = [];
423
424
  let fileOffset = 0;
424
425
  const markerHead = await parseHeader(MarkerHeaderParser, rarFile);
@@ -429,36 +430,58 @@ var RarFilesPackage = class extends _events.EventEmitter {
429
430
  fileOffset
430
431
  );
431
432
  fileOffset += archiveHeader.size;
433
+ let countFiles = 0;
434
+ let retrievedFiles = 0;
432
435
  while (fileOffset < rarFile.length - TerminatorHeaderParser.HEADER_SIZE) {
436
+ let getFileChunk2 = function() {
437
+ if (fileHead.method !== 48) {
438
+ throw new Error("Decompression is not implemented");
439
+ }
440
+ return {
441
+ name: fileHead.name,
442
+ fileHead,
443
+ chunk: new RarFileChunk(
444
+ rarFile,
445
+ fileOffset,
446
+ fileOffset + fileHead.size - 1
447
+ )
448
+ };
449
+ };
450
+ var getFileChunk = getFileChunk2;
433
451
  const fileHead = await parseHeader(FileHeaderParser, rarFile, fileOffset);
434
452
  if (fileHead.type !== 116) {
435
453
  break;
436
454
  }
437
- if (fileHead.method !== 48) {
438
- throw new Error("Decompression is not implemented");
439
- }
440
455
  fileOffset += fileHead.headSize;
441
- fileChunks.push({
442
- name: fileHead.name,
443
- fileHead,
444
- chunk: new RarFileChunk(
445
- rarFile,
446
- fileOffset,
447
- fileOffset + fileHead.size - 1
448
- )
449
- });
456
+ if (opts.filter) {
457
+ if (opts.filter(fileHead.name, countFiles)) {
458
+ fileChunks.push(getFileChunk2());
459
+ retrievedFiles++;
460
+ if (opts.hasOwnProperty("maxFiles") && retrievedFiles === opts.maxFiles) {
461
+ break;
462
+ }
463
+ }
464
+ } else {
465
+ fileChunks.push(getFileChunk2());
466
+ }
450
467
  fileOffset += fileHead.size;
468
+ countFiles++;
451
469
  }
452
470
  this.emit("file-parsed", rarFile);
453
471
  return fileChunks;
454
472
  }
455
- async parse() {
473
+ async parse(opts) {
474
+ opts = opts || {};
456
475
  this.emit("parsing-start", this.rarFileBundle);
457
476
  const parsedFileChunks = [];
458
477
  const { files } = this.rarFileBundle;
459
478
  for (let i = 0; i < files.length; ++i) {
460
479
  const file = files[i];
461
- const chunks = await this.parseFile(file);
480
+ const chunks = await this.parseFile(file, opts);
481
+ if (!chunks.length) {
482
+ this.emit("parsing-complete", []);
483
+ return [];
484
+ }
462
485
  const { fileHead, chunk } = chunks[chunks.length - 1];
463
486
  const chunkSize = Math.abs(chunk.endOffset - chunk.startOffset);
464
487
  let innerFileSize = fileHead.unpackedSize;
@@ -506,7 +529,9 @@ var LocalFileMedia = class {
506
529
 
507
530
 
508
531
  createReadStream(interval) {
509
- return _fs.createReadStream.call(void 0, this.path, interval);
532
+ return Promise.resolve(
533
+ _fs.createReadStream.call(void 0, this.path, interval)
534
+ );
510
535
  }
511
536
  };
512
537
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/rar-files-package.ts","../src/rar-file-bundle.ts","../src/rar-file-chunk.ts","../src/inner-file-stream.ts","../src/stream-utils.ts","../src/utils.ts","../src/inner-file.ts","../src/parsing/marker-header-parser.ts","../src/parsing/archive-header-parser.ts","../src/parsing/file-header-parser.ts","../src/parsing/terminator-header-parser.ts","../src/local-file-media.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventEmitter } from \"events\";\nimport { makeRarFileBundle, RarFileBundle } from \"./rar-file-bundle.js\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\nimport { InnerFile } from \"./inner-file.js\";\n\nimport { MarkerHeaderParser } from \"./parsing/marker-header-parser.js\";\nimport { ArchiveHeaderParser } from \"./parsing/archive-header-parser.js\";\nimport { FileHeaderParser, IFileHeader } from \"./parsing/file-header-parser.js\";\nimport { TerminatorHeaderParser } from \"./parsing/terminator-header-parser.js\";\n\nimport { streamToBuffer } from \"./stream-utils.js\";\nimport { IFileMedia, IParser, IParsers } from \"./interfaces.js\";\nimport { groupBy, mapValues } from \"./utils.js\";\n\nconst parseHeader = async <T extends IParsers>(\n Parser: IParser<T>,\n fileMedia: IFileMedia,\n offset = 0\n) => {\n const stream = fileMedia.createReadStream({\n start: offset,\n end: offset + Parser.HEADER_SIZE,\n });\n const headerBuffer = await streamToBuffer(stream);\n const parser = new Parser(headerBuffer);\n return parser.parse() as ReturnType<T[\"parse\"]>;\n};\ninterface ParsedFileChunkMapping {\n name: string;\n chunk: RarFileChunk;\n}\ninterface FileChunkMapping extends ParsedFileChunkMapping {\n fileHead: IFileHeader;\n}\n\nexport class RarFilesPackage extends EventEmitter {\n rarFileBundle: RarFileBundle;\n constructor(fileMedias: IFileMedia[]) {\n super();\n this.rarFileBundle = makeRarFileBundle(fileMedias);\n }\n async parseFile(rarFile: IFileMedia) {\n const fileChunks: FileChunkMapping[] = [];\n let fileOffset = 0;\n const markerHead = await parseHeader(MarkerHeaderParser, rarFile);\n fileOffset += markerHead.size;\n\n const archiveHeader = await parseHeader(\n ArchiveHeaderParser,\n rarFile,\n fileOffset\n );\n fileOffset += archiveHeader.size;\n\n while (fileOffset < rarFile.length - TerminatorHeaderParser.HEADER_SIZE) {\n const fileHead = await parseHeader(FileHeaderParser, rarFile, fileOffset);\n if (fileHead.type !== 116) {\n break;\n }\n if (fileHead.method !== 0x30) {\n throw new Error(\"Decompression is not implemented\");\n }\n fileOffset += fileHead.headSize;\n\n fileChunks.push({\n name: fileHead.name,\n fileHead,\n chunk: new RarFileChunk(\n rarFile,\n fileOffset,\n fileOffset + fileHead.size - 1\n ),\n });\n fileOffset += fileHead.size;\n }\n this.emit(\"file-parsed\", rarFile);\n return fileChunks;\n }\n async parse(): Promise<InnerFile[]> {\n this.emit(\"parsing-start\", this.rarFileBundle);\n const parsedFileChunks: ParsedFileChunkMapping[][] = [];\n const { files } = this.rarFileBundle;\n for (let i = 0; i < files.length; ++i) {\n const file = files[i]!;\n\n const chunks = await this.parseFile(file);\n const { fileHead, chunk } = chunks[chunks.length - 1]!;\n const chunkSize = Math.abs(chunk.endOffset - chunk.startOffset);\n let innerFileSize = fileHead.unpackedSize;\n parsedFileChunks.push(chunks);\n\n if (fileHead.continuesInNext) {\n while (Math.abs(innerFileSize - chunkSize) >= chunkSize) {\n const nextFile = files[++i]!;\n\n parsedFileChunks.push([\n {\n name: fileHead.name,\n chunk: new RarFileChunk(\n nextFile,\n chunk.startOffset,\n chunk.endOffset\n ),\n },\n ]);\n this.emit(\"file-parsed\", nextFile);\n innerFileSize -= chunkSize;\n }\n }\n }\n\n const fileChunks = parsedFileChunks.flat();\n\n const grouped = mapValues(\n groupBy(fileChunks, (f) => f.name),\n (value) => value.map((v) => v.chunk)\n );\n\n const innerFiles = Object.entries(grouped).map(\n ([name, chunks]) => new InnerFile(name, chunks)\n );\n\n this.emit(\"parsing-complete\", innerFiles);\n return innerFiles;\n }\n}\n","const RXX_EXTENSION = /\\.R(\\d\\d)$|.RAR$/i;\nconst RAR_EXTENSION = /.RAR$/i;\nconst PARTXX_RAR_EXTENSION = /.PART(\\d\\d).RAR/i;\nimport { IFileMedia } from \"./interfaces.js\";\n\nconst isPartXXExtension = (fileMedias: IFileMedia[] = []) => {\n let anyPartXXTypes = fileMedias.filter(\n (file) => file.name && file.name.match(PARTXX_RAR_EXTENSION)\n );\n\n if (anyPartXXTypes.length > 0) {\n return true;\n } else {\n return false;\n }\n};\n\nclass NumericRarFileBundle {\n constructor(private fileMedias: IFileMedia[] = []) {\n if (this.fileMedias.length > 0) {\n this.filter();\n this.sort();\n }\n }\n filter() {\n this.fileMedias = this.fileMedias.filter(\n (file) => file.name && file.name.match(RXX_EXTENSION)\n );\n }\n sort() {\n this.fileMedias.sort((first, second) => {\n if (first.name.match(RAR_EXTENSION)) {\n return -1;\n } else if (second.name.match(RAR_EXTENSION)) {\n return 1;\n } else {\n const firstMatch = first.name.match(RXX_EXTENSION);\n const secondMatch = second.name.match(RXX_EXTENSION);\n const firstNumber = +((firstMatch && firstMatch[1]) || 0);\n const secondNumber = +((secondMatch && secondMatch[1]) || 0);\n return firstNumber - secondNumber;\n }\n });\n }\n\n get length() {\n return this.fileMedias.length;\n }\n get fileNames() {\n return this.fileMedias.map((file) => file.name);\n }\n get files() {\n return this.fileMedias;\n }\n}\n\nclass PartXXRarBundle {\n constructor(private fileMedias: IFileMedia[] = []) {\n if (this.fileMedias.length > 0) {\n this.filter();\n this.sort();\n }\n }\n filter() {\n this.fileMedias = this.fileMedias.filter((file) =>\n file.name.match(PARTXX_RAR_EXTENSION)\n );\n }\n sort() {\n this.fileMedias.sort((first, second) => {\n const firstMatch = first.name.match(PARTXX_RAR_EXTENSION);\n const secondMatch = second.name.match(PARTXX_RAR_EXTENSION);\n const firstNumber = +((firstMatch && firstMatch[1]) || 0);\n const secondNumber = +((secondMatch && secondMatch[1]) || 0);\n return firstNumber - secondNumber;\n });\n }\n\n get length() {\n return this.fileMedias.length;\n }\n get fileNames() {\n return this.fileMedias.map((file) => file.name);\n }\n get files() {\n return this.fileMedias;\n }\n}\n\nexport type RarFileBundle = PartXXRarBundle | NumericRarFileBundle;\nexport const makeRarFileBundle = (\n fileMedias: IFileMedia[] = []\n): RarFileBundle => {\n return isPartXXExtension(fileMedias)\n ? new PartXXRarBundle(fileMedias)\n : new NumericRarFileBundle(fileMedias);\n};\n","import { IFileMedia } from \"./interfaces.js\";\n\nexport class RarFileChunk {\n constructor(\n private fileMedia: IFileMedia,\n public startOffset: number,\n public endOffset: number\n ) {}\n padEnd(endPadding: number) {\n return new RarFileChunk(\n this.fileMedia,\n this.startOffset,\n this.endOffset - endPadding\n );\n }\n padStart(startPadding: number) {\n return new RarFileChunk(\n this.fileMedia,\n this.startOffset + startPadding,\n this.endOffset\n );\n }\n get length() {\n return Math.max(0, this.endOffset - this.startOffset);\n }\n getStream() {\n return this.fileMedia.createReadStream({\n start: this.startOffset,\n end: this.endOffset,\n });\n }\n}\n","import { Readable, ReadableOptions } from \"stream\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\n\nexport class InnerFileStream extends Readable {\n stream?: NodeJS.ReadableStream;\n constructor(\n private rarFileChunks: RarFileChunk[],\n options?: ReadableOptions\n ) {\n super(options);\n }\n pushData(data: Uint16Array) {\n if (!this.push(data)) {\n this.stream?.pause();\n }\n }\n get isStarted() {\n return !!this.stream;\n }\n next() {\n const chunk = this.rarFileChunks.shift();\n\n if (!chunk) {\n this.push(null);\n } else {\n this.stream = chunk.getStream();\n this.stream?.on(\"data\", (data) => this.pushData(data));\n this.stream?.on(\"end\", () => this.next());\n }\n }\n override _read() {\n if (!this.isStarted) {\n this.next();\n } else {\n this.stream?.resume();\n }\n }\n}\n","import { Stream, Duplex } from \"stream\";\n\nexport const streamToBuffer = async (stream: Stream | NodeJS.ReadableStream): Promise<Buffer> =>\n new Promise((resolve, reject) => {\n const buffers: Uint8Array[] = [];\n stream.on(\"error\", reject);\n stream.on(\"data\", (data) => buffers.push(data));\n stream.on(\"end\", () => resolve(Buffer.concat(buffers)));\n });\n\nexport const bufferToStream = (buffer: Buffer): Stream => {\n const stream = new Duplex();\n stream.push(buffer);\n stream.push(null);\n return stream;\n};\n","export function groupBy<T>(arr: T[], fn: (item: T) => any) {\n return arr.reduce<Record<string, T[]>>((prev, curr) => {\n const groupKey = fn(curr);\n const group = prev[groupKey] || [];\n group.push(curr);\n return { ...prev, [groupKey]: group };\n }, {});\n}\n\nexport function sum(arr: number[]) {\n return arr.reduce((s, n) => s + n);\n}\nexport function mapValues<T extends Object, S>(\n object: T,\n mapper: (value: T[keyof T]) => S\n) {\n return Object.fromEntries(\n Object.entries(object).map(([key, value]) => [key, mapper(value)])\n ) as { [key in keyof T]: S };\n}\n","import { IFileMedia, IReadInterval } from \"./interfaces.js\";\nimport { InnerFileStream } from \"./inner-file-stream.js\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\nimport { streamToBuffer } from \"./stream-utils.js\";\nimport { sum } from \"./utils.js\";\ntype ChunkMapEntry = {\n index: number;\n start: number;\n end: number;\n chunk: RarFileChunk;\n};\n\nexport class InnerFile implements IFileMedia {\n length: number;\n\n chunkMap: ChunkMapEntry[];\n constructor(public name: string, private rarFileChunks: RarFileChunk[]) {\n this.length = sum(rarFileChunks.map((c) => c.length));\n this.chunkMap = this.calculateChunkMap(rarFileChunks);\n\n this.name = name;\n }\n readToEnd() {\n return streamToBuffer(\n this.createReadStream({ start: 0, end: this.length - 1 })\n );\n }\n getChunksToStream(fileStart: number, fileEnd: number) {\n const { index: startIndex, start: startOffset } =\n this.findMappedChunk(fileStart);\n let { index: endIndex, end: endOffset } = this.findMappedChunk(fileEnd);\n\n const chunksToStream = this.rarFileChunks.slice(startIndex, endIndex + 1);\n\n const last = chunksToStream.length - 1;\n const first = 0;\n chunksToStream[first] = chunksToStream[first]!.padStart(\n Math.abs(startOffset - fileStart)\n );\n\n let diff = Math.abs(endOffset - fileEnd);\n if (diff === this.rarFileChunks.length) {\n diff = 0;\n }\n if (diff !== 0) {\n chunksToStream[last] = chunksToStream[last]!.padEnd(diff);\n }\n\n return chunksToStream;\n }\n createReadStream(interval: IReadInterval) {\n if (!interval) {\n interval = { start: 0, end: this.length - 1 };\n }\n let { start, end } = interval;\n\n if (start < 0 || end >= this.length) {\n throw Error(\"Illegal start/end offset\");\n }\n\n return new InnerFileStream(this.getChunksToStream(start, end));\n }\n calculateChunkMap(rarFileChunks: RarFileChunk[]) {\n const chunkMap: ChunkMapEntry[] = [];\n let index = 0;\n let fileOffset = 0;\n for (const chunk of rarFileChunks) {\n const start = fileOffset;\n const end = fileOffset + chunk.length;\n fileOffset = end + 1;\n\n chunkMap.push({ index, start, end, chunk });\n index++;\n }\n\n return chunkMap;\n }\n findMappedChunk(offset: number) {\n let selectedMap = this.chunkMap[0]!;\n for (const chunkMapping of this.chunkMap) {\n if (offset >= chunkMapping.start && offset <= chunkMapping.end) {\n selectedMap = chunkMapping;\n break;\n }\n }\n return selectedMap;\n }\n}\n","export class MarkerHeaderParser {\n static HEADER_SIZE = 11;\n constructor(private headerBuffer: Buffer) {}\n\n parse() {\n const crc = this.headerBuffer.readUInt16LE(0);\n const type = this.headerBuffer.readUInt8(2);\n const flags = this.headerBuffer.readUInt16LE(3);\n let size = this.headerBuffer.readUInt16LE(5);\n if ((flags & 0x8000) !== 0) {\n let addSize = this.headerBuffer.readUint32LE(7);\n size += addSize || 0;\n }\n return { crc, type, flags, size };\n }\n}\n","interface IArchiveHeader {\n crc: number;\n type: number;\n flags: number;\n size: number;\n reserved1: number;\n reserved2: number;\n}\n\nfunction parseFlags(parsedVars: IArchiveHeader) {\n return {\n hasVolumeAttributes: (parsedVars.flags & 0x0001) !== 0,\n hasComment: (parsedVars.flags & 0x0002) !== 0,\n isLocked: (parsedVars.flags & 0x0004) !== 0,\n hasSolidAttributes: (parsedVars.flags & 0x0008) !== 0,\n isNewNameScheme: (parsedVars.flags & 0x00010) !== 0,\n hasAuthInfo: (parsedVars.flags & 0x0020) !== 0,\n hasRecovery: (parsedVars.flags & 0x0040) !== 0,\n isBlockEncoded: (parsedVars.flags & 0x0080) !== 0,\n isFirstVolume: (parsedVars.flags & 0x0100) !== 0,\n };\n}\nexport class ArchiveHeaderParser {\n static HEADER_SIZE = 13;\n constructor(private buffer: Buffer) {}\n parse() {\n const crc = this.buffer.readUInt16LE(0);\n const type = this.buffer.readUInt8(2);\n const flags = this.buffer.readUInt16LE(3);\n let size = this.buffer.readUInt16LE(5);\n const reserved1 = this.buffer.readUInt16LE(7);\n const reserved2 = this.buffer.readUInt32LE(9);\n\n let vars = { crc, type, flags, size, reserved1, reserved2 };\n\n return { ...parseFlags(vars), ...vars };\n }\n}\n","interface IFileHeaderFlags {\n continuesFromPrevious: boolean;\n continuesInNext: boolean;\n isEncrypted: boolean;\n hasComment: boolean;\n hasInfoFromPrevious: boolean;\n hasHighSize: boolean;\n hasSpecialName: boolean;\n hasSalt: boolean;\n isOldVersion: boolean;\n hasExtendedTime: boolean;\n}\n\ninterface IFileHeaderRaw {\n crc: number;\n type: number;\n flags: number;\n headSize: number;\n size: number;\n unpackedSize: number;\n host: number;\n fileCrc: number;\n timestamp: number;\n version: number;\n method: number;\n nameSize: number;\n attributes: number;\n name: string;\n}\n\nexport type IFileHeader = IFileHeaderRaw & IFileHeaderFlags;\nexport class FileHeaderParser {\n static HEADER_SIZE = 280;\n offset = 0;\n constructor(private buffer: Buffer) {}\n private handleHighFileSize(parsedVars: IFileHeader) {\n if (parsedVars.hasHighSize) {\n const highPackSize = this.buffer.readInt32LE(this.offset);\n this.offset += 4;\n const highUnpackSize = this.buffer.readInt32LE(this.offset);\n this.offset += 4;\n parsedVars.size = highPackSize * 0x100000000 + parsedVars.size;\n parsedVars.unpackedSize =\n highUnpackSize * 0x100000000 + parsedVars.unpackedSize;\n }\n }\n private parseFileName(parsedVars: IFileHeaderRaw) {\n parsedVars.name = this.buffer\n .subarray(this.offset, this.offset + parsedVars.nameSize)\n .toString(\"utf-8\");\n }\n private parseFlags(parsedVars: IFileHeaderRaw): IFileHeaderFlags {\n return {\n continuesFromPrevious: (parsedVars.flags & 0x01) !== 0,\n continuesInNext: (parsedVars.flags & 0x02) !== 0,\n isEncrypted: (parsedVars.flags & 0x04) !== 0,\n hasComment: (parsedVars.flags & 0x08) !== 0,\n hasInfoFromPrevious: (parsedVars.flags & 0x10) !== 0,\n hasHighSize: (parsedVars.flags & 0x100) !== 0,\n hasSpecialName: (parsedVars.flags & 0x200) !== 0,\n hasSalt: (parsedVars.flags & 0x400) !== 0,\n isOldVersion: (parsedVars.flags & 0x800) !== 0,\n hasExtendedTime: (parsedVars.flags & 0x1000) !== 0,\n };\n }\n parse(): IFileHeader {\n const crc = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const type = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const flags = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const headSize = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const size = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const unpackedSize = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const host = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const fileCrc = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const timestamp = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const version = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const method = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const nameSize = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const attributes = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n let vars: IFileHeaderRaw = {\n crc,\n type,\n flags,\n headSize,\n size,\n unpackedSize,\n host,\n fileCrc,\n timestamp,\n version,\n method,\n nameSize,\n attributes,\n name: \"\",\n };\n\n const boolFlags = this.parseFlags(vars);\n const header = { ...vars, ...boolFlags };\n this.handleHighFileSize(header);\n this.parseFileName(header);\n this.offset = 0;\n return header;\n }\n}\n","export class TerminatorHeaderParser {\n static HEADER_SIZE = 27;\n constructor(private headerBuffer: Buffer) {}\n parse() {\n const crc = this.headerBuffer.readUInt16LE(0);\n const type = this.headerBuffer.readUInt8(2);\n const flags = this.headerBuffer.readUInt16LE(3);\n const size = this.headerBuffer.readUInt16LE(5);\n return { crc, type, flags, size };\n }\n}\n","import { basename } from \"path\";\nimport { statSync, createReadStream } from \"fs\";\nimport { IFileMedia, IReadInterval } from \"./interfaces.js\";\n\nexport class LocalFileMedia implements IFileMedia {\n name: string;\n length: number;\n constructor(private path: string) {\n this.name = basename(path);\n this.length = statSync(path).size;\n }\n createReadStream(interval: IReadInterval) {\n return createReadStream(this.path, interval);\n }\n}\n"]}
1
+ {"version":3,"sources":["/Users/pejo/projects/rar-stream/dist/index.cjs","../src/rar-files-package.ts","../src/rar-file-bundle.ts","../src/rar-file-chunk.ts","../src/inner-file-stream.ts","../src/stream-utils.ts","../src/utils.ts","../src/inner-file.ts","../src/parsing/marker-header-parser.ts","../src/parsing/archive-header-parser.ts","../src/parsing/file-header-parser.ts","../src/parsing/terminator-header-parser.ts","../src/local-file-media.ts"],"names":["getFileChunk"],"mappings":"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","file":"/Users/pejo/projects/rar-stream/dist/index.cjs","sourcesContent":[null,"import { EventEmitter } from \"events\";\nimport { makeRarFileBundle, RarFileBundle } from \"./rar-file-bundle.js\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\nimport { InnerFile } from \"./inner-file.js\";\n\nimport { MarkerHeaderParser } from \"./parsing/marker-header-parser.js\";\nimport { ArchiveHeaderParser } from \"./parsing/archive-header-parser.js\";\nimport { FileHeaderParser, IFileHeader } from \"./parsing/file-header-parser.js\";\nimport { TerminatorHeaderParser } from \"./parsing/terminator-header-parser.js\";\n\nimport { streamToBuffer } from \"./stream-utils.js\";\nimport { IFileMedia, IParser, IParsers, FindOpts } from \"./interfaces.js\";\nimport { groupBy, mapValues } from \"./utils.js\";\n\nconst parseHeader = async <T extends IParsers>(\n Parser: IParser<T>,\n fileMedia: IFileMedia,\n offset = 0\n) => {\n const stream = await fileMedia.createReadStream({\n start: offset,\n end: offset + Parser.HEADER_SIZE,\n });\n const headerBuffer = await streamToBuffer(stream);\n const parser = new Parser(headerBuffer);\n return parser.parse() as ReturnType<T[\"parse\"]>;\n};\ninterface ParsedFileChunkMapping {\n name: string;\n chunk: RarFileChunk;\n}\ninterface FileChunkMapping extends ParsedFileChunkMapping {\n fileHead: IFileHeader;\n}\n\nexport class RarFilesPackage extends EventEmitter {\n rarFileBundle: RarFileBundle;\n constructor(fileMedias: IFileMedia[]) {\n super();\n this.rarFileBundle = makeRarFileBundle(fileMedias);\n }\n async parseFile(rarFile: IFileMedia, opts: FindOpts) {\n const fileChunks: FileChunkMapping[] = [];\n let fileOffset = 0;\n const markerHead = await parseHeader(MarkerHeaderParser, rarFile);\n fileOffset += markerHead.size;\n\n const archiveHeader = await parseHeader(\n ArchiveHeaderParser,\n rarFile,\n fileOffset\n );\n fileOffset += archiveHeader.size;\n\n let countFiles = 0;\n let retrievedFiles = 0;\n while (fileOffset < rarFile.length - TerminatorHeaderParser.HEADER_SIZE) {\n const fileHead = await parseHeader(FileHeaderParser, rarFile, fileOffset);\n if (fileHead.type !== 116) {\n break;\n }\n fileOffset += fileHead.headSize;\n function getFileChunk() {\n if (fileHead.method !== 0x30) {\n throw new Error(\"Decompression is not implemented\");\n }\n return {\n name: fileHead.name,\n fileHead,\n chunk: new RarFileChunk(\n rarFile,\n fileOffset,\n fileOffset + fileHead.size - 1\n ),\n };\n }\n if (opts.filter) {\n if (opts.filter(fileHead.name, countFiles)) {\n fileChunks.push(getFileChunk());\n retrievedFiles++;\n if (opts.hasOwnProperty('maxFiles') && retrievedFiles === opts.maxFiles) {\n break;\n }\n }\n } else {\n fileChunks.push(getFileChunk());\n }\n fileOffset += fileHead.size;\n countFiles++;\n }\n this.emit(\"file-parsed\", rarFile);\n return fileChunks;\n }\n async parse(opts: FindOpts): Promise<InnerFile[]> {\n opts = opts || {};\n this.emit(\"parsing-start\", this.rarFileBundle);\n const parsedFileChunks: ParsedFileChunkMapping[][] = [];\n const { files } = this.rarFileBundle;\n for (let i = 0; i < files.length; ++i) {\n const file = files[i]!;\n\n const chunks = await this.parseFile(file, opts);\n if (!chunks.length) {\n this.emit(\"parsing-complete\", []);\n return [];\n }\n const { fileHead, chunk } = chunks[chunks.length - 1]!;\n const chunkSize = Math.abs(chunk.endOffset - chunk.startOffset);\n let innerFileSize = fileHead.unpackedSize;\n parsedFileChunks.push(chunks);\n\n if (fileHead.continuesInNext) {\n while (Math.abs(innerFileSize - chunkSize) >= chunkSize) {\n const nextFile = files[++i]!;\n\n parsedFileChunks.push([\n {\n name: fileHead.name,\n chunk: new RarFileChunk(\n nextFile,\n chunk.startOffset,\n chunk.endOffset\n ),\n },\n ]);\n this.emit(\"file-parsed\", nextFile);\n innerFileSize -= chunkSize;\n }\n }\n }\n\n const fileChunks = parsedFileChunks.flat();\n\n const grouped = mapValues(\n groupBy(fileChunks, (f) => f.name),\n (value) => value.map((v) => v.chunk)\n );\n\n const innerFiles = Object.entries(grouped).map(\n ([name, chunks]) => new InnerFile(name, chunks)\n );\n\n this.emit(\"parsing-complete\", innerFiles);\n return innerFiles;\n }\n}\n","const RXX_EXTENSION = /\\.R(\\d\\d)$|.RAR$/i;\nconst RAR_EXTENSION = /.RAR$/i;\nconst PARTXX_RAR_EXTENSION = /.PART(\\d\\d?\\d?).RAR/i;\nimport { IFileMedia } from \"./interfaces.js\";\n\nconst isPartXXExtension = (fileMedias: IFileMedia[] = []) => {\n let anyPartXXTypes = fileMedias.filter(\n (file) => file.name && file.name.match(PARTXX_RAR_EXTENSION)\n );\n\n if (anyPartXXTypes.length > 0) {\n return true;\n } else {\n return false;\n }\n};\n\nclass NumericRarFileBundle {\n constructor(private fileMedias: IFileMedia[] = []) {\n if (this.fileMedias.length > 0) {\n this.filter();\n this.sort();\n }\n }\n filter() {\n this.fileMedias = this.fileMedias.filter(\n (file) => file.name && file.name.match(RXX_EXTENSION)\n );\n }\n sort() {\n this.fileMedias.sort((first, second) => {\n if (first.name.match(RAR_EXTENSION)) {\n return -1;\n } else if (second.name.match(RAR_EXTENSION)) {\n return 1;\n } else {\n const firstMatch = first.name.match(RXX_EXTENSION);\n const secondMatch = second.name.match(RXX_EXTENSION);\n const firstNumber = +((firstMatch && firstMatch[1]) || 0);\n const secondNumber = +((secondMatch && secondMatch[1]) || 0);\n return firstNumber - secondNumber;\n }\n });\n }\n\n get length() {\n return this.fileMedias.length;\n }\n get fileNames() {\n return this.fileMedias.map((file) => file.name);\n }\n get files() {\n return this.fileMedias;\n }\n}\n\nclass PartXXRarBundle {\n constructor(private fileMedias: IFileMedia[] = []) {\n if (this.fileMedias.length > 0) {\n this.filter();\n this.sort();\n }\n }\n filter() {\n this.fileMedias = this.fileMedias.filter((file) =>\n file.name.match(PARTXX_RAR_EXTENSION)\n );\n }\n sort() {\n this.fileMedias.sort((first, second) => {\n const firstMatch = first.name.match(PARTXX_RAR_EXTENSION);\n const secondMatch = second.name.match(PARTXX_RAR_EXTENSION);\n const firstNumber = +((firstMatch && firstMatch[1]) || 0);\n const secondNumber = +((secondMatch && secondMatch[1]) || 0);\n return firstNumber - secondNumber;\n });\n }\n\n get length() {\n return this.fileMedias.length;\n }\n get fileNames() {\n return this.fileMedias.map((file) => file.name);\n }\n get files() {\n return this.fileMedias;\n }\n}\n\nexport type RarFileBundle = PartXXRarBundle | NumericRarFileBundle;\nexport const makeRarFileBundle = (\n fileMedias: IFileMedia[] = []\n): RarFileBundle => {\n return isPartXXExtension(fileMedias)\n ? new PartXXRarBundle(fileMedias)\n : new NumericRarFileBundle(fileMedias);\n};\n","import { IFileMedia } from \"./interfaces.js\";\n\nexport class RarFileChunk {\n constructor(\n private fileMedia: IFileMedia,\n public startOffset: number,\n public endOffset: number\n ) {}\n padEnd(endPadding: number) {\n return new RarFileChunk(\n this.fileMedia,\n this.startOffset,\n this.endOffset - endPadding\n );\n }\n padStart(startPadding: number) {\n return new RarFileChunk(\n this.fileMedia,\n this.startOffset + startPadding,\n this.endOffset\n );\n }\n get length() {\n return Math.max(0, this.endOffset - this.startOffset);\n }\n getStream() {\n return this.fileMedia.createReadStream({\n start: this.startOffset,\n end: this.endOffset,\n });\n }\n}\n","import { Readable, ReadableOptions } from \"stream\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\n\nexport class InnerFileStream extends Readable {\n stream?: NodeJS.ReadableStream;\n constructor(\n private rarFileChunks: RarFileChunk[],\n options?: ReadableOptions\n ) {\n super(options);\n }\n pushData(data: Uint16Array) {\n if (!this.push(data)) {\n this.stream?.pause();\n }\n }\n get isStarted() {\n return !!this.stream;\n }\n async next() {\n const chunk = this.rarFileChunks.shift();\n\n if (!chunk) {\n this.push(null);\n } else {\n this.stream = await chunk.getStream();\n this.stream?.on(\"data\", (data) => this.pushData(data));\n this.stream?.on(\"end\", () => this.next());\n }\n }\n override _read() {\n if (!this.isStarted) {\n this.next();\n } else {\n this.stream?.resume();\n }\n }\n}\n","import { Stream, Duplex } from \"stream\";\n\nexport const streamToBuffer = async (stream: Stream | NodeJS.ReadableStream): Promise<Buffer> =>\n new Promise((resolve, reject) => {\n const buffers: Uint8Array[] = [];\n stream.on(\"error\", reject);\n stream.on(\"data\", (data) => buffers.push(data));\n stream.on(\"end\", () => resolve(Buffer.concat(buffers)));\n });\n\nexport const bufferToStream = (buffer: Buffer): Stream => {\n const stream = new Duplex();\n stream.push(buffer);\n stream.push(null);\n return stream;\n};\n","export function groupBy<T>(arr: T[], fn: (item: T) => any) {\n return arr.reduce<Record<string, T[]>>((prev, curr) => {\n const groupKey = fn(curr);\n const group = prev[groupKey] || [];\n group.push(curr);\n return { ...prev, [groupKey]: group };\n }, {});\n}\n\nexport function sum(arr: number[]) {\n return arr.reduce((s, n) => s + n);\n}\nexport function mapValues<T extends Object, S>(\n object: T,\n mapper: (value: T[keyof T]) => S\n) {\n return Object.fromEntries(\n Object.entries(object).map(([key, value]) => [key, mapper(value)])\n ) as { [key in keyof T]: S };\n}\n","import { IFileMedia, IReadInterval } from \"./interfaces.js\";\nimport { InnerFileStream } from \"./inner-file-stream.js\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\nimport { streamToBuffer } from \"./stream-utils.js\";\nimport { sum } from \"./utils.js\";\ntype ChunkMapEntry = {\n index: number;\n start: number;\n end: number;\n chunk: RarFileChunk;\n};\n\nexport class InnerFile implements IFileMedia {\n length: number;\n\n chunkMap: ChunkMapEntry[];\n constructor(public name: string, private rarFileChunks: RarFileChunk[]) {\n this.length = sum(rarFileChunks.map((c) => c.length));\n this.chunkMap = this.calculateChunkMap(rarFileChunks);\n\n this.name = name;\n }\n async readToEnd() {\n const stream = await this.createReadStream({ start: 0, end: this.length - 1 });\n return streamToBuffer(stream);\n }\n getChunksToStream(fileStart: number, fileEnd: number) {\n const { index: startIndex, start: startOffset } =\n this.findMappedChunk(fileStart);\n let { index: endIndex, end: endOffset } = this.findMappedChunk(fileEnd);\n\n const chunksToStream = this.rarFileChunks.slice(startIndex, endIndex + 1);\n\n const last = chunksToStream.length - 1;\n const first = 0;\n chunksToStream[first] = chunksToStream[first]!.padStart(\n Math.abs(startOffset - fileStart)\n );\n\n let diff = Math.abs(endOffset - fileEnd);\n if (diff === this.rarFileChunks.length) {\n diff = 0;\n }\n if (diff !== 0) {\n chunksToStream[last] = chunksToStream[last]!.padEnd(diff);\n }\n\n return chunksToStream;\n }\n createReadStream(interval: IReadInterval) {\n if (!interval) {\n interval = { start: 0, end: this.length - 1 };\n }\n let { start, end } = interval;\n\n if (start < 0 || end >= this.length) {\n throw Error(\"Illegal start/end offset\");\n }\n\n return Promise.resolve(\n new InnerFileStream(this.getChunksToStream(start, end))\n );\n }\n calculateChunkMap(rarFileChunks: RarFileChunk[]) {\n const chunkMap: ChunkMapEntry[] = [];\n let index = 0;\n let fileOffset = 0;\n for (const chunk of rarFileChunks) {\n const start = fileOffset;\n const end = fileOffset + chunk.length;\n fileOffset = end + 1;\n\n chunkMap.push({ index, start, end, chunk });\n index++;\n }\n\n return chunkMap;\n }\n findMappedChunk(offset: number) {\n let selectedMap = this.chunkMap[0]!;\n for (const chunkMapping of this.chunkMap) {\n if (offset >= chunkMapping.start && offset <= chunkMapping.end) {\n selectedMap = chunkMapping;\n break;\n }\n }\n return selectedMap;\n }\n}\n","export class MarkerHeaderParser {\n static HEADER_SIZE = 11;\n constructor(private headerBuffer: Buffer) {}\n\n parse() {\n const crc = this.headerBuffer.readUInt16LE(0);\n const type = this.headerBuffer.readUInt8(2);\n const flags = this.headerBuffer.readUInt16LE(3);\n let size = this.headerBuffer.readUInt16LE(5);\n if ((flags & 0x8000) !== 0) {\n let addSize = this.headerBuffer.readUint32LE(7);\n size += addSize || 0;\n }\n return { crc, type, flags, size };\n }\n}\n","interface IArchiveHeader {\n crc: number;\n type: number;\n flags: number;\n size: number;\n reserved1: number;\n reserved2: number;\n}\n\nfunction parseFlags(parsedVars: IArchiveHeader) {\n return {\n hasVolumeAttributes: (parsedVars.flags & 0x0001) !== 0,\n hasComment: (parsedVars.flags & 0x0002) !== 0,\n isLocked: (parsedVars.flags & 0x0004) !== 0,\n hasSolidAttributes: (parsedVars.flags & 0x0008) !== 0,\n isNewNameScheme: (parsedVars.flags & 0x00010) !== 0,\n hasAuthInfo: (parsedVars.flags & 0x0020) !== 0,\n hasRecovery: (parsedVars.flags & 0x0040) !== 0,\n isBlockEncoded: (parsedVars.flags & 0x0080) !== 0,\n isFirstVolume: (parsedVars.flags & 0x0100) !== 0,\n };\n}\nexport class ArchiveHeaderParser {\n static HEADER_SIZE = 13;\n constructor(private buffer: Buffer) {}\n parse() {\n const crc = this.buffer.readUInt16LE(0);\n const type = this.buffer.readUInt8(2);\n const flags = this.buffer.readUInt16LE(3);\n let size = this.buffer.readUInt16LE(5);\n const reserved1 = this.buffer.readUInt16LE(7);\n const reserved2 = this.buffer.readUInt32LE(9);\n\n let vars = { crc, type, flags, size, reserved1, reserved2 };\n\n return { ...parseFlags(vars), ...vars };\n }\n}\n","interface IFileHeaderFlags {\n continuesFromPrevious: boolean;\n continuesInNext: boolean;\n isEncrypted: boolean;\n hasComment: boolean;\n hasInfoFromPrevious: boolean;\n hasHighSize: boolean;\n hasSpecialName: boolean;\n hasSalt: boolean;\n isOldVersion: boolean;\n hasExtendedTime: boolean;\n}\n\ninterface IFileHeaderRaw {\n crc: number;\n type: number;\n flags: number;\n headSize: number;\n size: number;\n unpackedSize: number;\n host: number;\n fileCrc: number;\n timestamp: number;\n version: number;\n method: number;\n nameSize: number;\n attributes: number;\n name: string;\n}\n\nexport type IFileHeader = IFileHeaderRaw & IFileHeaderFlags;\nexport class FileHeaderParser {\n static HEADER_SIZE = 280;\n offset = 0;\n constructor(private buffer: Buffer) {}\n private handleHighFileSize(parsedVars: IFileHeader) {\n if (parsedVars.hasHighSize) {\n const highPackSize = this.buffer.readInt32LE(this.offset);\n this.offset += 4;\n const highUnpackSize = this.buffer.readInt32LE(this.offset);\n this.offset += 4;\n parsedVars.size = highPackSize * 0x100000000 + parsedVars.size;\n parsedVars.unpackedSize =\n highUnpackSize * 0x100000000 + parsedVars.unpackedSize;\n }\n }\n private parseFileName(parsedVars: IFileHeaderRaw) {\n parsedVars.name = this.buffer\n .subarray(this.offset, this.offset + parsedVars.nameSize)\n .toString(\"utf-8\");\n }\n private parseFlags(parsedVars: IFileHeaderRaw): IFileHeaderFlags {\n return {\n continuesFromPrevious: (parsedVars.flags & 0x01) !== 0,\n continuesInNext: (parsedVars.flags & 0x02) !== 0,\n isEncrypted: (parsedVars.flags & 0x04) !== 0,\n hasComment: (parsedVars.flags & 0x08) !== 0,\n hasInfoFromPrevious: (parsedVars.flags & 0x10) !== 0,\n hasHighSize: (parsedVars.flags & 0x100) !== 0,\n hasSpecialName: (parsedVars.flags & 0x200) !== 0,\n hasSalt: (parsedVars.flags & 0x400) !== 0,\n isOldVersion: (parsedVars.flags & 0x800) !== 0,\n hasExtendedTime: (parsedVars.flags & 0x1000) !== 0,\n };\n }\n parse(): IFileHeader {\n const crc = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const type = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const flags = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const headSize = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const size = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const unpackedSize = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const host = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const fileCrc = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const timestamp = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const version = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const method = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const nameSize = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const attributes = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n let vars: IFileHeaderRaw = {\n crc,\n type,\n flags,\n headSize,\n size,\n unpackedSize,\n host,\n fileCrc,\n timestamp,\n version,\n method,\n nameSize,\n attributes,\n name: \"\",\n };\n\n const boolFlags = this.parseFlags(vars);\n const header = { ...vars, ...boolFlags };\n this.handleHighFileSize(header);\n this.parseFileName(header);\n this.offset = 0;\n return header;\n }\n}\n","export class TerminatorHeaderParser {\n static HEADER_SIZE = 27;\n constructor(private headerBuffer: Buffer) {}\n parse() {\n const crc = this.headerBuffer.readUInt16LE(0);\n const type = this.headerBuffer.readUInt8(2);\n const flags = this.headerBuffer.readUInt16LE(3);\n const size = this.headerBuffer.readUInt16LE(5);\n return { crc, type, flags, size };\n }\n}\n","import { basename } from \"path\";\nimport { statSync, createReadStream } from \"fs\";\nimport { IFileMedia, IReadInterval } from \"./interfaces.js\";\n\nexport class LocalFileMedia implements IFileMedia {\n name: string;\n length: number;\n constructor(private path: string) {\n this.name = basename(path);\n this.length = statSync(path).size;\n }\n createReadStream(interval: IReadInterval) {\n return Promise.resolve(\n createReadStream(this.path, interval)\n );\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -35,12 +35,16 @@ type IFileHeader = IFileHeaderRaw & IFileHeaderFlags;
35
35
  interface IFileMedia {
36
36
  length: number;
37
37
  name: string;
38
- createReadStream(opts?: IReadInterval): NodeJS.ReadableStream;
38
+ createReadStream(opts?: IReadInterval): Promise<NodeJS.ReadableStream> | NodeJS.ReadableStream;
39
39
  }
40
40
  interface IReadInterval {
41
41
  start: number;
42
42
  end: number;
43
43
  }
44
+ interface FindOpts {
45
+ filter(filename: string, idx: number): boolean;
46
+ maxFiles: number;
47
+ }
44
48
 
45
49
  declare class NumericRarFileBundle {
46
50
  private fileMedias;
@@ -70,7 +74,7 @@ declare class RarFileChunk {
70
74
  padEnd(endPadding: number): RarFileChunk;
71
75
  padStart(startPadding: number): RarFileChunk;
72
76
  get length(): number;
73
- getStream(): NodeJS.ReadableStream;
77
+ getStream(): NodeJS.ReadableStream | Promise<NodeJS.ReadableStream>;
74
78
  }
75
79
 
76
80
  declare class InnerFileStream extends Readable {
@@ -79,7 +83,7 @@ declare class InnerFileStream extends Readable {
79
83
  constructor(rarFileChunks: RarFileChunk[], options?: ReadableOptions);
80
84
  pushData(data: Uint16Array): void;
81
85
  get isStarted(): boolean;
82
- next(): void;
86
+ next(): Promise<void>;
83
87
  _read(): void;
84
88
  }
85
89
 
@@ -95,9 +99,9 @@ declare class InnerFile implements IFileMedia {
95
99
  length: number;
96
100
  chunkMap: ChunkMapEntry[];
97
101
  constructor(name: string, rarFileChunks: RarFileChunk[]);
98
- readToEnd(): Promise<Buffer>;
102
+ readToEnd(): Promise<Buffer<ArrayBufferLike>>;
99
103
  getChunksToStream(fileStart: number, fileEnd: number): RarFileChunk[];
100
- createReadStream(interval: IReadInterval): InnerFileStream;
104
+ createReadStream(interval: IReadInterval): Promise<InnerFileStream>;
101
105
  calculateChunkMap(rarFileChunks: RarFileChunk[]): ChunkMapEntry[];
102
106
  findMappedChunk(offset: number): ChunkMapEntry;
103
107
  }
@@ -112,8 +116,8 @@ interface FileChunkMapping extends ParsedFileChunkMapping {
112
116
  declare class RarFilesPackage extends EventEmitter {
113
117
  rarFileBundle: RarFileBundle;
114
118
  constructor(fileMedias: IFileMedia[]);
115
- parseFile(rarFile: IFileMedia): Promise<FileChunkMapping[]>;
116
- parse(): Promise<InnerFile[]>;
119
+ parseFile(rarFile: IFileMedia, opts: FindOpts): Promise<FileChunkMapping[]>;
120
+ parse(opts: FindOpts): Promise<InnerFile[]>;
117
121
  }
118
122
 
119
123
  declare class LocalFileMedia implements IFileMedia {
@@ -121,7 +125,7 @@ declare class LocalFileMedia implements IFileMedia {
121
125
  name: string;
122
126
  length: number;
123
127
  constructor(path: string);
124
- createReadStream(interval: IReadInterval): fs.ReadStream;
128
+ createReadStream(interval: IReadInterval): Promise<fs.ReadStream>;
125
129
  }
126
130
 
127
131
  export { LocalFileMedia, RarFilesPackage };
package/dist/index.d.ts CHANGED
@@ -35,12 +35,16 @@ type IFileHeader = IFileHeaderRaw & IFileHeaderFlags;
35
35
  interface IFileMedia {
36
36
  length: number;
37
37
  name: string;
38
- createReadStream(opts?: IReadInterval): NodeJS.ReadableStream;
38
+ createReadStream(opts?: IReadInterval): Promise<NodeJS.ReadableStream> | NodeJS.ReadableStream;
39
39
  }
40
40
  interface IReadInterval {
41
41
  start: number;
42
42
  end: number;
43
43
  }
44
+ interface FindOpts {
45
+ filter(filename: string, idx: number): boolean;
46
+ maxFiles: number;
47
+ }
44
48
 
45
49
  declare class NumericRarFileBundle {
46
50
  private fileMedias;
@@ -70,7 +74,7 @@ declare class RarFileChunk {
70
74
  padEnd(endPadding: number): RarFileChunk;
71
75
  padStart(startPadding: number): RarFileChunk;
72
76
  get length(): number;
73
- getStream(): NodeJS.ReadableStream;
77
+ getStream(): NodeJS.ReadableStream | Promise<NodeJS.ReadableStream>;
74
78
  }
75
79
 
76
80
  declare class InnerFileStream extends Readable {
@@ -79,7 +83,7 @@ declare class InnerFileStream extends Readable {
79
83
  constructor(rarFileChunks: RarFileChunk[], options?: ReadableOptions);
80
84
  pushData(data: Uint16Array): void;
81
85
  get isStarted(): boolean;
82
- next(): void;
86
+ next(): Promise<void>;
83
87
  _read(): void;
84
88
  }
85
89
 
@@ -95,9 +99,9 @@ declare class InnerFile implements IFileMedia {
95
99
  length: number;
96
100
  chunkMap: ChunkMapEntry[];
97
101
  constructor(name: string, rarFileChunks: RarFileChunk[]);
98
- readToEnd(): Promise<Buffer>;
102
+ readToEnd(): Promise<Buffer<ArrayBufferLike>>;
99
103
  getChunksToStream(fileStart: number, fileEnd: number): RarFileChunk[];
100
- createReadStream(interval: IReadInterval): InnerFileStream;
104
+ createReadStream(interval: IReadInterval): Promise<InnerFileStream>;
101
105
  calculateChunkMap(rarFileChunks: RarFileChunk[]): ChunkMapEntry[];
102
106
  findMappedChunk(offset: number): ChunkMapEntry;
103
107
  }
@@ -112,8 +116,8 @@ interface FileChunkMapping extends ParsedFileChunkMapping {
112
116
  declare class RarFilesPackage extends EventEmitter {
113
117
  rarFileBundle: RarFileBundle;
114
118
  constructor(fileMedias: IFileMedia[]);
115
- parseFile(rarFile: IFileMedia): Promise<FileChunkMapping[]>;
116
- parse(): Promise<InnerFile[]>;
119
+ parseFile(rarFile: IFileMedia, opts: FindOpts): Promise<FileChunkMapping[]>;
120
+ parse(opts: FindOpts): Promise<InnerFile[]>;
117
121
  }
118
122
 
119
123
  declare class LocalFileMedia implements IFileMedia {
@@ -121,7 +125,7 @@ declare class LocalFileMedia implements IFileMedia {
121
125
  name: string;
122
126
  length: number;
123
127
  constructor(path: string);
124
- createReadStream(interval: IReadInterval): fs.ReadStream;
128
+ createReadStream(interval: IReadInterval): Promise<fs.ReadStream>;
125
129
  }
126
130
 
127
131
  export { LocalFileMedia, RarFilesPackage };
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { EventEmitter } from "events";
4
4
  // src/rar-file-bundle.ts
5
5
  var RXX_EXTENSION = /\.R(\d\d)$|.RAR$/i;
6
6
  var RAR_EXTENSION = /.RAR$/i;
7
- var PARTXX_RAR_EXTENSION = /.PART(\d\d).RAR/i;
7
+ var PARTXX_RAR_EXTENSION = /.PART(\d\d?\d?).RAR/i;
8
8
  var isPartXXExtension = (fileMedias = []) => {
9
9
  let anyPartXXTypes = fileMedias.filter(
10
10
  (file) => file.name && file.name.match(PARTXX_RAR_EXTENSION)
@@ -137,12 +137,12 @@ var InnerFileStream = class extends Readable {
137
137
  get isStarted() {
138
138
  return !!this.stream;
139
139
  }
140
- next() {
140
+ async next() {
141
141
  const chunk = this.rarFileChunks.shift();
142
142
  if (!chunk) {
143
143
  this.push(null);
144
144
  } else {
145
- this.stream = chunk.getStream();
145
+ this.stream = await chunk.getStream();
146
146
  this.stream?.on("data", (data) => this.pushData(data));
147
147
  this.stream?.on("end", () => this.next());
148
148
  }
@@ -193,10 +193,9 @@ var InnerFile = class {
193
193
  }
194
194
  length;
195
195
  chunkMap;
196
- readToEnd() {
197
- return streamToBuffer(
198
- this.createReadStream({ start: 0, end: this.length - 1 })
199
- );
196
+ async readToEnd() {
197
+ const stream = await this.createReadStream({ start: 0, end: this.length - 1 });
198
+ return streamToBuffer(stream);
200
199
  }
201
200
  getChunksToStream(fileStart, fileEnd) {
202
201
  const { index: startIndex, start: startOffset } = this.findMappedChunk(fileStart);
@@ -224,7 +223,9 @@ var InnerFile = class {
224
223
  if (start < 0 || end >= this.length) {
225
224
  throw Error("Illegal start/end offset");
226
225
  }
227
- return new InnerFileStream(this.getChunksToStream(start, end));
226
+ return Promise.resolve(
227
+ new InnerFileStream(this.getChunksToStream(start, end))
228
+ );
228
229
  }
229
230
  calculateChunkMap(rarFileChunks) {
230
231
  const chunkMap = [];
@@ -404,7 +405,7 @@ var TerminatorHeaderParser = class {
404
405
 
405
406
  // src/rar-files-package.ts
406
407
  var parseHeader = async (Parser, fileMedia, offset = 0) => {
407
- const stream = fileMedia.createReadStream({
408
+ const stream = await fileMedia.createReadStream({
408
409
  start: offset,
409
410
  end: offset + Parser.HEADER_SIZE
410
411
  });
@@ -418,7 +419,7 @@ var RarFilesPackage = class extends EventEmitter {
418
419
  super();
419
420
  this.rarFileBundle = makeRarFileBundle(fileMedias);
420
421
  }
421
- async parseFile(rarFile) {
422
+ async parseFile(rarFile, opts) {
422
423
  const fileChunks = [];
423
424
  let fileOffset = 0;
424
425
  const markerHead = await parseHeader(MarkerHeaderParser, rarFile);
@@ -429,36 +430,58 @@ var RarFilesPackage = class extends EventEmitter {
429
430
  fileOffset
430
431
  );
431
432
  fileOffset += archiveHeader.size;
433
+ let countFiles = 0;
434
+ let retrievedFiles = 0;
432
435
  while (fileOffset < rarFile.length - TerminatorHeaderParser.HEADER_SIZE) {
436
+ let getFileChunk2 = function() {
437
+ if (fileHead.method !== 48) {
438
+ throw new Error("Decompression is not implemented");
439
+ }
440
+ return {
441
+ name: fileHead.name,
442
+ fileHead,
443
+ chunk: new RarFileChunk(
444
+ rarFile,
445
+ fileOffset,
446
+ fileOffset + fileHead.size - 1
447
+ )
448
+ };
449
+ };
450
+ var getFileChunk = getFileChunk2;
433
451
  const fileHead = await parseHeader(FileHeaderParser, rarFile, fileOffset);
434
452
  if (fileHead.type !== 116) {
435
453
  break;
436
454
  }
437
- if (fileHead.method !== 48) {
438
- throw new Error("Decompression is not implemented");
439
- }
440
455
  fileOffset += fileHead.headSize;
441
- fileChunks.push({
442
- name: fileHead.name,
443
- fileHead,
444
- chunk: new RarFileChunk(
445
- rarFile,
446
- fileOffset,
447
- fileOffset + fileHead.size - 1
448
- )
449
- });
456
+ if (opts.filter) {
457
+ if (opts.filter(fileHead.name, countFiles)) {
458
+ fileChunks.push(getFileChunk2());
459
+ retrievedFiles++;
460
+ if (opts.hasOwnProperty("maxFiles") && retrievedFiles === opts.maxFiles) {
461
+ break;
462
+ }
463
+ }
464
+ } else {
465
+ fileChunks.push(getFileChunk2());
466
+ }
450
467
  fileOffset += fileHead.size;
468
+ countFiles++;
451
469
  }
452
470
  this.emit("file-parsed", rarFile);
453
471
  return fileChunks;
454
472
  }
455
- async parse() {
473
+ async parse(opts) {
474
+ opts = opts || {};
456
475
  this.emit("parsing-start", this.rarFileBundle);
457
476
  const parsedFileChunks = [];
458
477
  const { files } = this.rarFileBundle;
459
478
  for (let i = 0; i < files.length; ++i) {
460
479
  const file = files[i];
461
- const chunks = await this.parseFile(file);
480
+ const chunks = await this.parseFile(file, opts);
481
+ if (!chunks.length) {
482
+ this.emit("parsing-complete", []);
483
+ return [];
484
+ }
462
485
  const { fileHead, chunk } = chunks[chunks.length - 1];
463
486
  const chunkSize = Math.abs(chunk.endOffset - chunk.startOffset);
464
487
  let innerFileSize = fileHead.unpackedSize;
@@ -506,7 +529,9 @@ var LocalFileMedia = class {
506
529
  name;
507
530
  length;
508
531
  createReadStream(interval) {
509
- return createReadStream(this.path, interval);
532
+ return Promise.resolve(
533
+ createReadStream(this.path, interval)
534
+ );
510
535
  }
511
536
  };
512
537
  export {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/rar-files-package.ts","../src/rar-file-bundle.ts","../src/rar-file-chunk.ts","../src/inner-file-stream.ts","../src/stream-utils.ts","../src/utils.ts","../src/inner-file.ts","../src/parsing/marker-header-parser.ts","../src/parsing/archive-header-parser.ts","../src/parsing/file-header-parser.ts","../src/parsing/terminator-header-parser.ts","../src/local-file-media.ts"],"sourcesContent":["import { EventEmitter } from \"events\";\nimport { makeRarFileBundle, RarFileBundle } from \"./rar-file-bundle.js\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\nimport { InnerFile } from \"./inner-file.js\";\n\nimport { MarkerHeaderParser } from \"./parsing/marker-header-parser.js\";\nimport { ArchiveHeaderParser } from \"./parsing/archive-header-parser.js\";\nimport { FileHeaderParser, IFileHeader } from \"./parsing/file-header-parser.js\";\nimport { TerminatorHeaderParser } from \"./parsing/terminator-header-parser.js\";\n\nimport { streamToBuffer } from \"./stream-utils.js\";\nimport { IFileMedia, IParser, IParsers } from \"./interfaces.js\";\nimport { groupBy, mapValues } from \"./utils.js\";\n\nconst parseHeader = async <T extends IParsers>(\n Parser: IParser<T>,\n fileMedia: IFileMedia,\n offset = 0\n) => {\n const stream = fileMedia.createReadStream({\n start: offset,\n end: offset + Parser.HEADER_SIZE,\n });\n const headerBuffer = await streamToBuffer(stream);\n const parser = new Parser(headerBuffer);\n return parser.parse() as ReturnType<T[\"parse\"]>;\n};\ninterface ParsedFileChunkMapping {\n name: string;\n chunk: RarFileChunk;\n}\ninterface FileChunkMapping extends ParsedFileChunkMapping {\n fileHead: IFileHeader;\n}\n\nexport class RarFilesPackage extends EventEmitter {\n rarFileBundle: RarFileBundle;\n constructor(fileMedias: IFileMedia[]) {\n super();\n this.rarFileBundle = makeRarFileBundle(fileMedias);\n }\n async parseFile(rarFile: IFileMedia) {\n const fileChunks: FileChunkMapping[] = [];\n let fileOffset = 0;\n const markerHead = await parseHeader(MarkerHeaderParser, rarFile);\n fileOffset += markerHead.size;\n\n const archiveHeader = await parseHeader(\n ArchiveHeaderParser,\n rarFile,\n fileOffset\n );\n fileOffset += archiveHeader.size;\n\n while (fileOffset < rarFile.length - TerminatorHeaderParser.HEADER_SIZE) {\n const fileHead = await parseHeader(FileHeaderParser, rarFile, fileOffset);\n if (fileHead.type !== 116) {\n break;\n }\n if (fileHead.method !== 0x30) {\n throw new Error(\"Decompression is not implemented\");\n }\n fileOffset += fileHead.headSize;\n\n fileChunks.push({\n name: fileHead.name,\n fileHead,\n chunk: new RarFileChunk(\n rarFile,\n fileOffset,\n fileOffset + fileHead.size - 1\n ),\n });\n fileOffset += fileHead.size;\n }\n this.emit(\"file-parsed\", rarFile);\n return fileChunks;\n }\n async parse(): Promise<InnerFile[]> {\n this.emit(\"parsing-start\", this.rarFileBundle);\n const parsedFileChunks: ParsedFileChunkMapping[][] = [];\n const { files } = this.rarFileBundle;\n for (let i = 0; i < files.length; ++i) {\n const file = files[i]!;\n\n const chunks = await this.parseFile(file);\n const { fileHead, chunk } = chunks[chunks.length - 1]!;\n const chunkSize = Math.abs(chunk.endOffset - chunk.startOffset);\n let innerFileSize = fileHead.unpackedSize;\n parsedFileChunks.push(chunks);\n\n if (fileHead.continuesInNext) {\n while (Math.abs(innerFileSize - chunkSize) >= chunkSize) {\n const nextFile = files[++i]!;\n\n parsedFileChunks.push([\n {\n name: fileHead.name,\n chunk: new RarFileChunk(\n nextFile,\n chunk.startOffset,\n chunk.endOffset\n ),\n },\n ]);\n this.emit(\"file-parsed\", nextFile);\n innerFileSize -= chunkSize;\n }\n }\n }\n\n const fileChunks = parsedFileChunks.flat();\n\n const grouped = mapValues(\n groupBy(fileChunks, (f) => f.name),\n (value) => value.map((v) => v.chunk)\n );\n\n const innerFiles = Object.entries(grouped).map(\n ([name, chunks]) => new InnerFile(name, chunks)\n );\n\n this.emit(\"parsing-complete\", innerFiles);\n return innerFiles;\n }\n}\n","const RXX_EXTENSION = /\\.R(\\d\\d)$|.RAR$/i;\nconst RAR_EXTENSION = /.RAR$/i;\nconst PARTXX_RAR_EXTENSION = /.PART(\\d\\d).RAR/i;\nimport { IFileMedia } from \"./interfaces.js\";\n\nconst isPartXXExtension = (fileMedias: IFileMedia[] = []) => {\n let anyPartXXTypes = fileMedias.filter(\n (file) => file.name && file.name.match(PARTXX_RAR_EXTENSION)\n );\n\n if (anyPartXXTypes.length > 0) {\n return true;\n } else {\n return false;\n }\n};\n\nclass NumericRarFileBundle {\n constructor(private fileMedias: IFileMedia[] = []) {\n if (this.fileMedias.length > 0) {\n this.filter();\n this.sort();\n }\n }\n filter() {\n this.fileMedias = this.fileMedias.filter(\n (file) => file.name && file.name.match(RXX_EXTENSION)\n );\n }\n sort() {\n this.fileMedias.sort((first, second) => {\n if (first.name.match(RAR_EXTENSION)) {\n return -1;\n } else if (second.name.match(RAR_EXTENSION)) {\n return 1;\n } else {\n const firstMatch = first.name.match(RXX_EXTENSION);\n const secondMatch = second.name.match(RXX_EXTENSION);\n const firstNumber = +((firstMatch && firstMatch[1]) || 0);\n const secondNumber = +((secondMatch && secondMatch[1]) || 0);\n return firstNumber - secondNumber;\n }\n });\n }\n\n get length() {\n return this.fileMedias.length;\n }\n get fileNames() {\n return this.fileMedias.map((file) => file.name);\n }\n get files() {\n return this.fileMedias;\n }\n}\n\nclass PartXXRarBundle {\n constructor(private fileMedias: IFileMedia[] = []) {\n if (this.fileMedias.length > 0) {\n this.filter();\n this.sort();\n }\n }\n filter() {\n this.fileMedias = this.fileMedias.filter((file) =>\n file.name.match(PARTXX_RAR_EXTENSION)\n );\n }\n sort() {\n this.fileMedias.sort((first, second) => {\n const firstMatch = first.name.match(PARTXX_RAR_EXTENSION);\n const secondMatch = second.name.match(PARTXX_RAR_EXTENSION);\n const firstNumber = +((firstMatch && firstMatch[1]) || 0);\n const secondNumber = +((secondMatch && secondMatch[1]) || 0);\n return firstNumber - secondNumber;\n });\n }\n\n get length() {\n return this.fileMedias.length;\n }\n get fileNames() {\n return this.fileMedias.map((file) => file.name);\n }\n get files() {\n return this.fileMedias;\n }\n}\n\nexport type RarFileBundle = PartXXRarBundle | NumericRarFileBundle;\nexport const makeRarFileBundle = (\n fileMedias: IFileMedia[] = []\n): RarFileBundle => {\n return isPartXXExtension(fileMedias)\n ? new PartXXRarBundle(fileMedias)\n : new NumericRarFileBundle(fileMedias);\n};\n","import { IFileMedia } from \"./interfaces.js\";\n\nexport class RarFileChunk {\n constructor(\n private fileMedia: IFileMedia,\n public startOffset: number,\n public endOffset: number\n ) {}\n padEnd(endPadding: number) {\n return new RarFileChunk(\n this.fileMedia,\n this.startOffset,\n this.endOffset - endPadding\n );\n }\n padStart(startPadding: number) {\n return new RarFileChunk(\n this.fileMedia,\n this.startOffset + startPadding,\n this.endOffset\n );\n }\n get length() {\n return Math.max(0, this.endOffset - this.startOffset);\n }\n getStream() {\n return this.fileMedia.createReadStream({\n start: this.startOffset,\n end: this.endOffset,\n });\n }\n}\n","import { Readable, ReadableOptions } from \"stream\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\n\nexport class InnerFileStream extends Readable {\n stream?: NodeJS.ReadableStream;\n constructor(\n private rarFileChunks: RarFileChunk[],\n options?: ReadableOptions\n ) {\n super(options);\n }\n pushData(data: Uint16Array) {\n if (!this.push(data)) {\n this.stream?.pause();\n }\n }\n get isStarted() {\n return !!this.stream;\n }\n next() {\n const chunk = this.rarFileChunks.shift();\n\n if (!chunk) {\n this.push(null);\n } else {\n this.stream = chunk.getStream();\n this.stream?.on(\"data\", (data) => this.pushData(data));\n this.stream?.on(\"end\", () => this.next());\n }\n }\n override _read() {\n if (!this.isStarted) {\n this.next();\n } else {\n this.stream?.resume();\n }\n }\n}\n","import { Stream, Duplex } from \"stream\";\n\nexport const streamToBuffer = async (stream: Stream | NodeJS.ReadableStream): Promise<Buffer> =>\n new Promise((resolve, reject) => {\n const buffers: Uint8Array[] = [];\n stream.on(\"error\", reject);\n stream.on(\"data\", (data) => buffers.push(data));\n stream.on(\"end\", () => resolve(Buffer.concat(buffers)));\n });\n\nexport const bufferToStream = (buffer: Buffer): Stream => {\n const stream = new Duplex();\n stream.push(buffer);\n stream.push(null);\n return stream;\n};\n","export function groupBy<T>(arr: T[], fn: (item: T) => any) {\n return arr.reduce<Record<string, T[]>>((prev, curr) => {\n const groupKey = fn(curr);\n const group = prev[groupKey] || [];\n group.push(curr);\n return { ...prev, [groupKey]: group };\n }, {});\n}\n\nexport function sum(arr: number[]) {\n return arr.reduce((s, n) => s + n);\n}\nexport function mapValues<T extends Object, S>(\n object: T,\n mapper: (value: T[keyof T]) => S\n) {\n return Object.fromEntries(\n Object.entries(object).map(([key, value]) => [key, mapper(value)])\n ) as { [key in keyof T]: S };\n}\n","import { IFileMedia, IReadInterval } from \"./interfaces.js\";\nimport { InnerFileStream } from \"./inner-file-stream.js\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\nimport { streamToBuffer } from \"./stream-utils.js\";\nimport { sum } from \"./utils.js\";\ntype ChunkMapEntry = {\n index: number;\n start: number;\n end: number;\n chunk: RarFileChunk;\n};\n\nexport class InnerFile implements IFileMedia {\n length: number;\n\n chunkMap: ChunkMapEntry[];\n constructor(public name: string, private rarFileChunks: RarFileChunk[]) {\n this.length = sum(rarFileChunks.map((c) => c.length));\n this.chunkMap = this.calculateChunkMap(rarFileChunks);\n\n this.name = name;\n }\n readToEnd() {\n return streamToBuffer(\n this.createReadStream({ start: 0, end: this.length - 1 })\n );\n }\n getChunksToStream(fileStart: number, fileEnd: number) {\n const { index: startIndex, start: startOffset } =\n this.findMappedChunk(fileStart);\n let { index: endIndex, end: endOffset } = this.findMappedChunk(fileEnd);\n\n const chunksToStream = this.rarFileChunks.slice(startIndex, endIndex + 1);\n\n const last = chunksToStream.length - 1;\n const first = 0;\n chunksToStream[first] = chunksToStream[first]!.padStart(\n Math.abs(startOffset - fileStart)\n );\n\n let diff = Math.abs(endOffset - fileEnd);\n if (diff === this.rarFileChunks.length) {\n diff = 0;\n }\n if (diff !== 0) {\n chunksToStream[last] = chunksToStream[last]!.padEnd(diff);\n }\n\n return chunksToStream;\n }\n createReadStream(interval: IReadInterval) {\n if (!interval) {\n interval = { start: 0, end: this.length - 1 };\n }\n let { start, end } = interval;\n\n if (start < 0 || end >= this.length) {\n throw Error(\"Illegal start/end offset\");\n }\n\n return new InnerFileStream(this.getChunksToStream(start, end));\n }\n calculateChunkMap(rarFileChunks: RarFileChunk[]) {\n const chunkMap: ChunkMapEntry[] = [];\n let index = 0;\n let fileOffset = 0;\n for (const chunk of rarFileChunks) {\n const start = fileOffset;\n const end = fileOffset + chunk.length;\n fileOffset = end + 1;\n\n chunkMap.push({ index, start, end, chunk });\n index++;\n }\n\n return chunkMap;\n }\n findMappedChunk(offset: number) {\n let selectedMap = this.chunkMap[0]!;\n for (const chunkMapping of this.chunkMap) {\n if (offset >= chunkMapping.start && offset <= chunkMapping.end) {\n selectedMap = chunkMapping;\n break;\n }\n }\n return selectedMap;\n }\n}\n","export class MarkerHeaderParser {\n static HEADER_SIZE = 11;\n constructor(private headerBuffer: Buffer) {}\n\n parse() {\n const crc = this.headerBuffer.readUInt16LE(0);\n const type = this.headerBuffer.readUInt8(2);\n const flags = this.headerBuffer.readUInt16LE(3);\n let size = this.headerBuffer.readUInt16LE(5);\n if ((flags & 0x8000) !== 0) {\n let addSize = this.headerBuffer.readUint32LE(7);\n size += addSize || 0;\n }\n return { crc, type, flags, size };\n }\n}\n","interface IArchiveHeader {\n crc: number;\n type: number;\n flags: number;\n size: number;\n reserved1: number;\n reserved2: number;\n}\n\nfunction parseFlags(parsedVars: IArchiveHeader) {\n return {\n hasVolumeAttributes: (parsedVars.flags & 0x0001) !== 0,\n hasComment: (parsedVars.flags & 0x0002) !== 0,\n isLocked: (parsedVars.flags & 0x0004) !== 0,\n hasSolidAttributes: (parsedVars.flags & 0x0008) !== 0,\n isNewNameScheme: (parsedVars.flags & 0x00010) !== 0,\n hasAuthInfo: (parsedVars.flags & 0x0020) !== 0,\n hasRecovery: (parsedVars.flags & 0x0040) !== 0,\n isBlockEncoded: (parsedVars.flags & 0x0080) !== 0,\n isFirstVolume: (parsedVars.flags & 0x0100) !== 0,\n };\n}\nexport class ArchiveHeaderParser {\n static HEADER_SIZE = 13;\n constructor(private buffer: Buffer) {}\n parse() {\n const crc = this.buffer.readUInt16LE(0);\n const type = this.buffer.readUInt8(2);\n const flags = this.buffer.readUInt16LE(3);\n let size = this.buffer.readUInt16LE(5);\n const reserved1 = this.buffer.readUInt16LE(7);\n const reserved2 = this.buffer.readUInt32LE(9);\n\n let vars = { crc, type, flags, size, reserved1, reserved2 };\n\n return { ...parseFlags(vars), ...vars };\n }\n}\n","interface IFileHeaderFlags {\n continuesFromPrevious: boolean;\n continuesInNext: boolean;\n isEncrypted: boolean;\n hasComment: boolean;\n hasInfoFromPrevious: boolean;\n hasHighSize: boolean;\n hasSpecialName: boolean;\n hasSalt: boolean;\n isOldVersion: boolean;\n hasExtendedTime: boolean;\n}\n\ninterface IFileHeaderRaw {\n crc: number;\n type: number;\n flags: number;\n headSize: number;\n size: number;\n unpackedSize: number;\n host: number;\n fileCrc: number;\n timestamp: number;\n version: number;\n method: number;\n nameSize: number;\n attributes: number;\n name: string;\n}\n\nexport type IFileHeader = IFileHeaderRaw & IFileHeaderFlags;\nexport class FileHeaderParser {\n static HEADER_SIZE = 280;\n offset = 0;\n constructor(private buffer: Buffer) {}\n private handleHighFileSize(parsedVars: IFileHeader) {\n if (parsedVars.hasHighSize) {\n const highPackSize = this.buffer.readInt32LE(this.offset);\n this.offset += 4;\n const highUnpackSize = this.buffer.readInt32LE(this.offset);\n this.offset += 4;\n parsedVars.size = highPackSize * 0x100000000 + parsedVars.size;\n parsedVars.unpackedSize =\n highUnpackSize * 0x100000000 + parsedVars.unpackedSize;\n }\n }\n private parseFileName(parsedVars: IFileHeaderRaw) {\n parsedVars.name = this.buffer\n .subarray(this.offset, this.offset + parsedVars.nameSize)\n .toString(\"utf-8\");\n }\n private parseFlags(parsedVars: IFileHeaderRaw): IFileHeaderFlags {\n return {\n continuesFromPrevious: (parsedVars.flags & 0x01) !== 0,\n continuesInNext: (parsedVars.flags & 0x02) !== 0,\n isEncrypted: (parsedVars.flags & 0x04) !== 0,\n hasComment: (parsedVars.flags & 0x08) !== 0,\n hasInfoFromPrevious: (parsedVars.flags & 0x10) !== 0,\n hasHighSize: (parsedVars.flags & 0x100) !== 0,\n hasSpecialName: (parsedVars.flags & 0x200) !== 0,\n hasSalt: (parsedVars.flags & 0x400) !== 0,\n isOldVersion: (parsedVars.flags & 0x800) !== 0,\n hasExtendedTime: (parsedVars.flags & 0x1000) !== 0,\n };\n }\n parse(): IFileHeader {\n const crc = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const type = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const flags = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const headSize = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const size = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const unpackedSize = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const host = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const fileCrc = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const timestamp = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const version = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const method = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const nameSize = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const attributes = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n let vars: IFileHeaderRaw = {\n crc,\n type,\n flags,\n headSize,\n size,\n unpackedSize,\n host,\n fileCrc,\n timestamp,\n version,\n method,\n nameSize,\n attributes,\n name: \"\",\n };\n\n const boolFlags = this.parseFlags(vars);\n const header = { ...vars, ...boolFlags };\n this.handleHighFileSize(header);\n this.parseFileName(header);\n this.offset = 0;\n return header;\n }\n}\n","export class TerminatorHeaderParser {\n static HEADER_SIZE = 27;\n constructor(private headerBuffer: Buffer) {}\n parse() {\n const crc = this.headerBuffer.readUInt16LE(0);\n const type = this.headerBuffer.readUInt8(2);\n const flags = this.headerBuffer.readUInt16LE(3);\n const size = this.headerBuffer.readUInt16LE(5);\n return { crc, type, flags, size };\n }\n}\n","import { basename } from \"path\";\nimport { statSync, createReadStream } from \"fs\";\nimport { IFileMedia, IReadInterval } from \"./interfaces.js\";\n\nexport class LocalFileMedia implements IFileMedia {\n name: string;\n length: number;\n constructor(private path: string) {\n this.name = basename(path);\n this.length = statSync(path).size;\n }\n createReadStream(interval: IReadInterval) {\n return createReadStream(this.path, interval);\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/rar-files-package.ts","../src/rar-file-bundle.ts","../src/rar-file-chunk.ts","../src/inner-file-stream.ts","../src/stream-utils.ts","../src/utils.ts","../src/inner-file.ts","../src/parsing/marker-header-parser.ts","../src/parsing/archive-header-parser.ts","../src/parsing/file-header-parser.ts","../src/parsing/terminator-header-parser.ts","../src/local-file-media.ts"],"sourcesContent":["import { EventEmitter } from \"events\";\nimport { makeRarFileBundle, RarFileBundle } from \"./rar-file-bundle.js\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\nimport { InnerFile } from \"./inner-file.js\";\n\nimport { MarkerHeaderParser } from \"./parsing/marker-header-parser.js\";\nimport { ArchiveHeaderParser } from \"./parsing/archive-header-parser.js\";\nimport { FileHeaderParser, IFileHeader } from \"./parsing/file-header-parser.js\";\nimport { TerminatorHeaderParser } from \"./parsing/terminator-header-parser.js\";\n\nimport { streamToBuffer } from \"./stream-utils.js\";\nimport { IFileMedia, IParser, IParsers, FindOpts } from \"./interfaces.js\";\nimport { groupBy, mapValues } from \"./utils.js\";\n\nconst parseHeader = async <T extends IParsers>(\n Parser: IParser<T>,\n fileMedia: IFileMedia,\n offset = 0\n) => {\n const stream = await fileMedia.createReadStream({\n start: offset,\n end: offset + Parser.HEADER_SIZE,\n });\n const headerBuffer = await streamToBuffer(stream);\n const parser = new Parser(headerBuffer);\n return parser.parse() as ReturnType<T[\"parse\"]>;\n};\ninterface ParsedFileChunkMapping {\n name: string;\n chunk: RarFileChunk;\n}\ninterface FileChunkMapping extends ParsedFileChunkMapping {\n fileHead: IFileHeader;\n}\n\nexport class RarFilesPackage extends EventEmitter {\n rarFileBundle: RarFileBundle;\n constructor(fileMedias: IFileMedia[]) {\n super();\n this.rarFileBundle = makeRarFileBundle(fileMedias);\n }\n async parseFile(rarFile: IFileMedia, opts: FindOpts) {\n const fileChunks: FileChunkMapping[] = [];\n let fileOffset = 0;\n const markerHead = await parseHeader(MarkerHeaderParser, rarFile);\n fileOffset += markerHead.size;\n\n const archiveHeader = await parseHeader(\n ArchiveHeaderParser,\n rarFile,\n fileOffset\n );\n fileOffset += archiveHeader.size;\n\n let countFiles = 0;\n let retrievedFiles = 0;\n while (fileOffset < rarFile.length - TerminatorHeaderParser.HEADER_SIZE) {\n const fileHead = await parseHeader(FileHeaderParser, rarFile, fileOffset);\n if (fileHead.type !== 116) {\n break;\n }\n fileOffset += fileHead.headSize;\n function getFileChunk() {\n if (fileHead.method !== 0x30) {\n throw new Error(\"Decompression is not implemented\");\n }\n return {\n name: fileHead.name,\n fileHead,\n chunk: new RarFileChunk(\n rarFile,\n fileOffset,\n fileOffset + fileHead.size - 1\n ),\n };\n }\n if (opts.filter) {\n if (opts.filter(fileHead.name, countFiles)) {\n fileChunks.push(getFileChunk());\n retrievedFiles++;\n if (opts.hasOwnProperty('maxFiles') && retrievedFiles === opts.maxFiles) {\n break;\n }\n }\n } else {\n fileChunks.push(getFileChunk());\n }\n fileOffset += fileHead.size;\n countFiles++;\n }\n this.emit(\"file-parsed\", rarFile);\n return fileChunks;\n }\n async parse(opts: FindOpts): Promise<InnerFile[]> {\n opts = opts || {};\n this.emit(\"parsing-start\", this.rarFileBundle);\n const parsedFileChunks: ParsedFileChunkMapping[][] = [];\n const { files } = this.rarFileBundle;\n for (let i = 0; i < files.length; ++i) {\n const file = files[i]!;\n\n const chunks = await this.parseFile(file, opts);\n if (!chunks.length) {\n this.emit(\"parsing-complete\", []);\n return [];\n }\n const { fileHead, chunk } = chunks[chunks.length - 1]!;\n const chunkSize = Math.abs(chunk.endOffset - chunk.startOffset);\n let innerFileSize = fileHead.unpackedSize;\n parsedFileChunks.push(chunks);\n\n if (fileHead.continuesInNext) {\n while (Math.abs(innerFileSize - chunkSize) >= chunkSize) {\n const nextFile = files[++i]!;\n\n parsedFileChunks.push([\n {\n name: fileHead.name,\n chunk: new RarFileChunk(\n nextFile,\n chunk.startOffset,\n chunk.endOffset\n ),\n },\n ]);\n this.emit(\"file-parsed\", nextFile);\n innerFileSize -= chunkSize;\n }\n }\n }\n\n const fileChunks = parsedFileChunks.flat();\n\n const grouped = mapValues(\n groupBy(fileChunks, (f) => f.name),\n (value) => value.map((v) => v.chunk)\n );\n\n const innerFiles = Object.entries(grouped).map(\n ([name, chunks]) => new InnerFile(name, chunks)\n );\n\n this.emit(\"parsing-complete\", innerFiles);\n return innerFiles;\n }\n}\n","const RXX_EXTENSION = /\\.R(\\d\\d)$|.RAR$/i;\nconst RAR_EXTENSION = /.RAR$/i;\nconst PARTXX_RAR_EXTENSION = /.PART(\\d\\d?\\d?).RAR/i;\nimport { IFileMedia } from \"./interfaces.js\";\n\nconst isPartXXExtension = (fileMedias: IFileMedia[] = []) => {\n let anyPartXXTypes = fileMedias.filter(\n (file) => file.name && file.name.match(PARTXX_RAR_EXTENSION)\n );\n\n if (anyPartXXTypes.length > 0) {\n return true;\n } else {\n return false;\n }\n};\n\nclass NumericRarFileBundle {\n constructor(private fileMedias: IFileMedia[] = []) {\n if (this.fileMedias.length > 0) {\n this.filter();\n this.sort();\n }\n }\n filter() {\n this.fileMedias = this.fileMedias.filter(\n (file) => file.name && file.name.match(RXX_EXTENSION)\n );\n }\n sort() {\n this.fileMedias.sort((first, second) => {\n if (first.name.match(RAR_EXTENSION)) {\n return -1;\n } else if (second.name.match(RAR_EXTENSION)) {\n return 1;\n } else {\n const firstMatch = first.name.match(RXX_EXTENSION);\n const secondMatch = second.name.match(RXX_EXTENSION);\n const firstNumber = +((firstMatch && firstMatch[1]) || 0);\n const secondNumber = +((secondMatch && secondMatch[1]) || 0);\n return firstNumber - secondNumber;\n }\n });\n }\n\n get length() {\n return this.fileMedias.length;\n }\n get fileNames() {\n return this.fileMedias.map((file) => file.name);\n }\n get files() {\n return this.fileMedias;\n }\n}\n\nclass PartXXRarBundle {\n constructor(private fileMedias: IFileMedia[] = []) {\n if (this.fileMedias.length > 0) {\n this.filter();\n this.sort();\n }\n }\n filter() {\n this.fileMedias = this.fileMedias.filter((file) =>\n file.name.match(PARTXX_RAR_EXTENSION)\n );\n }\n sort() {\n this.fileMedias.sort((first, second) => {\n const firstMatch = first.name.match(PARTXX_RAR_EXTENSION);\n const secondMatch = second.name.match(PARTXX_RAR_EXTENSION);\n const firstNumber = +((firstMatch && firstMatch[1]) || 0);\n const secondNumber = +((secondMatch && secondMatch[1]) || 0);\n return firstNumber - secondNumber;\n });\n }\n\n get length() {\n return this.fileMedias.length;\n }\n get fileNames() {\n return this.fileMedias.map((file) => file.name);\n }\n get files() {\n return this.fileMedias;\n }\n}\n\nexport type RarFileBundle = PartXXRarBundle | NumericRarFileBundle;\nexport const makeRarFileBundle = (\n fileMedias: IFileMedia[] = []\n): RarFileBundle => {\n return isPartXXExtension(fileMedias)\n ? new PartXXRarBundle(fileMedias)\n : new NumericRarFileBundle(fileMedias);\n};\n","import { IFileMedia } from \"./interfaces.js\";\n\nexport class RarFileChunk {\n constructor(\n private fileMedia: IFileMedia,\n public startOffset: number,\n public endOffset: number\n ) {}\n padEnd(endPadding: number) {\n return new RarFileChunk(\n this.fileMedia,\n this.startOffset,\n this.endOffset - endPadding\n );\n }\n padStart(startPadding: number) {\n return new RarFileChunk(\n this.fileMedia,\n this.startOffset + startPadding,\n this.endOffset\n );\n }\n get length() {\n return Math.max(0, this.endOffset - this.startOffset);\n }\n getStream() {\n return this.fileMedia.createReadStream({\n start: this.startOffset,\n end: this.endOffset,\n });\n }\n}\n","import { Readable, ReadableOptions } from \"stream\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\n\nexport class InnerFileStream extends Readable {\n stream?: NodeJS.ReadableStream;\n constructor(\n private rarFileChunks: RarFileChunk[],\n options?: ReadableOptions\n ) {\n super(options);\n }\n pushData(data: Uint16Array) {\n if (!this.push(data)) {\n this.stream?.pause();\n }\n }\n get isStarted() {\n return !!this.stream;\n }\n async next() {\n const chunk = this.rarFileChunks.shift();\n\n if (!chunk) {\n this.push(null);\n } else {\n this.stream = await chunk.getStream();\n this.stream?.on(\"data\", (data) => this.pushData(data));\n this.stream?.on(\"end\", () => this.next());\n }\n }\n override _read() {\n if (!this.isStarted) {\n this.next();\n } else {\n this.stream?.resume();\n }\n }\n}\n","import { Stream, Duplex } from \"stream\";\n\nexport const streamToBuffer = async (stream: Stream | NodeJS.ReadableStream): Promise<Buffer> =>\n new Promise((resolve, reject) => {\n const buffers: Uint8Array[] = [];\n stream.on(\"error\", reject);\n stream.on(\"data\", (data) => buffers.push(data));\n stream.on(\"end\", () => resolve(Buffer.concat(buffers)));\n });\n\nexport const bufferToStream = (buffer: Buffer): Stream => {\n const stream = new Duplex();\n stream.push(buffer);\n stream.push(null);\n return stream;\n};\n","export function groupBy<T>(arr: T[], fn: (item: T) => any) {\n return arr.reduce<Record<string, T[]>>((prev, curr) => {\n const groupKey = fn(curr);\n const group = prev[groupKey] || [];\n group.push(curr);\n return { ...prev, [groupKey]: group };\n }, {});\n}\n\nexport function sum(arr: number[]) {\n return arr.reduce((s, n) => s + n);\n}\nexport function mapValues<T extends Object, S>(\n object: T,\n mapper: (value: T[keyof T]) => S\n) {\n return Object.fromEntries(\n Object.entries(object).map(([key, value]) => [key, mapper(value)])\n ) as { [key in keyof T]: S };\n}\n","import { IFileMedia, IReadInterval } from \"./interfaces.js\";\nimport { InnerFileStream } from \"./inner-file-stream.js\";\nimport { RarFileChunk } from \"./rar-file-chunk.js\";\nimport { streamToBuffer } from \"./stream-utils.js\";\nimport { sum } from \"./utils.js\";\ntype ChunkMapEntry = {\n index: number;\n start: number;\n end: number;\n chunk: RarFileChunk;\n};\n\nexport class InnerFile implements IFileMedia {\n length: number;\n\n chunkMap: ChunkMapEntry[];\n constructor(public name: string, private rarFileChunks: RarFileChunk[]) {\n this.length = sum(rarFileChunks.map((c) => c.length));\n this.chunkMap = this.calculateChunkMap(rarFileChunks);\n\n this.name = name;\n }\n async readToEnd() {\n const stream = await this.createReadStream({ start: 0, end: this.length - 1 });\n return streamToBuffer(stream);\n }\n getChunksToStream(fileStart: number, fileEnd: number) {\n const { index: startIndex, start: startOffset } =\n this.findMappedChunk(fileStart);\n let { index: endIndex, end: endOffset } = this.findMappedChunk(fileEnd);\n\n const chunksToStream = this.rarFileChunks.slice(startIndex, endIndex + 1);\n\n const last = chunksToStream.length - 1;\n const first = 0;\n chunksToStream[first] = chunksToStream[first]!.padStart(\n Math.abs(startOffset - fileStart)\n );\n\n let diff = Math.abs(endOffset - fileEnd);\n if (diff === this.rarFileChunks.length) {\n diff = 0;\n }\n if (diff !== 0) {\n chunksToStream[last] = chunksToStream[last]!.padEnd(diff);\n }\n\n return chunksToStream;\n }\n createReadStream(interval: IReadInterval) {\n if (!interval) {\n interval = { start: 0, end: this.length - 1 };\n }\n let { start, end } = interval;\n\n if (start < 0 || end >= this.length) {\n throw Error(\"Illegal start/end offset\");\n }\n\n return Promise.resolve(\n new InnerFileStream(this.getChunksToStream(start, end))\n );\n }\n calculateChunkMap(rarFileChunks: RarFileChunk[]) {\n const chunkMap: ChunkMapEntry[] = [];\n let index = 0;\n let fileOffset = 0;\n for (const chunk of rarFileChunks) {\n const start = fileOffset;\n const end = fileOffset + chunk.length;\n fileOffset = end + 1;\n\n chunkMap.push({ index, start, end, chunk });\n index++;\n }\n\n return chunkMap;\n }\n findMappedChunk(offset: number) {\n let selectedMap = this.chunkMap[0]!;\n for (const chunkMapping of this.chunkMap) {\n if (offset >= chunkMapping.start && offset <= chunkMapping.end) {\n selectedMap = chunkMapping;\n break;\n }\n }\n return selectedMap;\n }\n}\n","export class MarkerHeaderParser {\n static HEADER_SIZE = 11;\n constructor(private headerBuffer: Buffer) {}\n\n parse() {\n const crc = this.headerBuffer.readUInt16LE(0);\n const type = this.headerBuffer.readUInt8(2);\n const flags = this.headerBuffer.readUInt16LE(3);\n let size = this.headerBuffer.readUInt16LE(5);\n if ((flags & 0x8000) !== 0) {\n let addSize = this.headerBuffer.readUint32LE(7);\n size += addSize || 0;\n }\n return { crc, type, flags, size };\n }\n}\n","interface IArchiveHeader {\n crc: number;\n type: number;\n flags: number;\n size: number;\n reserved1: number;\n reserved2: number;\n}\n\nfunction parseFlags(parsedVars: IArchiveHeader) {\n return {\n hasVolumeAttributes: (parsedVars.flags & 0x0001) !== 0,\n hasComment: (parsedVars.flags & 0x0002) !== 0,\n isLocked: (parsedVars.flags & 0x0004) !== 0,\n hasSolidAttributes: (parsedVars.flags & 0x0008) !== 0,\n isNewNameScheme: (parsedVars.flags & 0x00010) !== 0,\n hasAuthInfo: (parsedVars.flags & 0x0020) !== 0,\n hasRecovery: (parsedVars.flags & 0x0040) !== 0,\n isBlockEncoded: (parsedVars.flags & 0x0080) !== 0,\n isFirstVolume: (parsedVars.flags & 0x0100) !== 0,\n };\n}\nexport class ArchiveHeaderParser {\n static HEADER_SIZE = 13;\n constructor(private buffer: Buffer) {}\n parse() {\n const crc = this.buffer.readUInt16LE(0);\n const type = this.buffer.readUInt8(2);\n const flags = this.buffer.readUInt16LE(3);\n let size = this.buffer.readUInt16LE(5);\n const reserved1 = this.buffer.readUInt16LE(7);\n const reserved2 = this.buffer.readUInt32LE(9);\n\n let vars = { crc, type, flags, size, reserved1, reserved2 };\n\n return { ...parseFlags(vars), ...vars };\n }\n}\n","interface IFileHeaderFlags {\n continuesFromPrevious: boolean;\n continuesInNext: boolean;\n isEncrypted: boolean;\n hasComment: boolean;\n hasInfoFromPrevious: boolean;\n hasHighSize: boolean;\n hasSpecialName: boolean;\n hasSalt: boolean;\n isOldVersion: boolean;\n hasExtendedTime: boolean;\n}\n\ninterface IFileHeaderRaw {\n crc: number;\n type: number;\n flags: number;\n headSize: number;\n size: number;\n unpackedSize: number;\n host: number;\n fileCrc: number;\n timestamp: number;\n version: number;\n method: number;\n nameSize: number;\n attributes: number;\n name: string;\n}\n\nexport type IFileHeader = IFileHeaderRaw & IFileHeaderFlags;\nexport class FileHeaderParser {\n static HEADER_SIZE = 280;\n offset = 0;\n constructor(private buffer: Buffer) {}\n private handleHighFileSize(parsedVars: IFileHeader) {\n if (parsedVars.hasHighSize) {\n const highPackSize = this.buffer.readInt32LE(this.offset);\n this.offset += 4;\n const highUnpackSize = this.buffer.readInt32LE(this.offset);\n this.offset += 4;\n parsedVars.size = highPackSize * 0x100000000 + parsedVars.size;\n parsedVars.unpackedSize =\n highUnpackSize * 0x100000000 + parsedVars.unpackedSize;\n }\n }\n private parseFileName(parsedVars: IFileHeaderRaw) {\n parsedVars.name = this.buffer\n .subarray(this.offset, this.offset + parsedVars.nameSize)\n .toString(\"utf-8\");\n }\n private parseFlags(parsedVars: IFileHeaderRaw): IFileHeaderFlags {\n return {\n continuesFromPrevious: (parsedVars.flags & 0x01) !== 0,\n continuesInNext: (parsedVars.flags & 0x02) !== 0,\n isEncrypted: (parsedVars.flags & 0x04) !== 0,\n hasComment: (parsedVars.flags & 0x08) !== 0,\n hasInfoFromPrevious: (parsedVars.flags & 0x10) !== 0,\n hasHighSize: (parsedVars.flags & 0x100) !== 0,\n hasSpecialName: (parsedVars.flags & 0x200) !== 0,\n hasSalt: (parsedVars.flags & 0x400) !== 0,\n isOldVersion: (parsedVars.flags & 0x800) !== 0,\n hasExtendedTime: (parsedVars.flags & 0x1000) !== 0,\n };\n }\n parse(): IFileHeader {\n const crc = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const type = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const flags = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const headSize = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const size = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const unpackedSize = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const host = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const fileCrc = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const timestamp = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n const version = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const method = this.buffer.readUInt8(this.offset);\n this.offset += 1;\n\n const nameSize = this.buffer.readUInt16LE(this.offset);\n this.offset += 2;\n\n const attributes = this.buffer.readUInt32LE(this.offset);\n this.offset += 4;\n\n let vars: IFileHeaderRaw = {\n crc,\n type,\n flags,\n headSize,\n size,\n unpackedSize,\n host,\n fileCrc,\n timestamp,\n version,\n method,\n nameSize,\n attributes,\n name: \"\",\n };\n\n const boolFlags = this.parseFlags(vars);\n const header = { ...vars, ...boolFlags };\n this.handleHighFileSize(header);\n this.parseFileName(header);\n this.offset = 0;\n return header;\n }\n}\n","export class TerminatorHeaderParser {\n static HEADER_SIZE = 27;\n constructor(private headerBuffer: Buffer) {}\n parse() {\n const crc = this.headerBuffer.readUInt16LE(0);\n const type = this.headerBuffer.readUInt8(2);\n const flags = this.headerBuffer.readUInt16LE(3);\n const size = this.headerBuffer.readUInt16LE(5);\n return { crc, type, flags, size };\n }\n}\n","import { basename } from \"path\";\nimport { statSync, createReadStream } from \"fs\";\nimport { IFileMedia, IReadInterval } from \"./interfaces.js\";\n\nexport class LocalFileMedia implements IFileMedia {\n name: string;\n length: number;\n constructor(private path: string) {\n this.name = basename(path);\n this.length = statSync(path).size;\n }\n createReadStream(interval: IReadInterval) {\n return Promise.resolve(\n createReadStream(this.path, interval)\n );\n }\n}\n"],"mappings":"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","names":["getFileChunk"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rar-stream",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "Rar-Stream is a module for managing rar archives as node streams",
5
5
  "author": "1313",
6
6
  "repository": {
@@ -8,7 +8,6 @@
8
8
  "url": "https://github.com/1313/rar-stream.git"
9
9
  },
10
10
  "type": "module",
11
- "packageManager": "pnpm@7.18.2",
12
11
  "engines": {
13
12
  "node": ">=18"
14
13
  },
@@ -20,11 +19,11 @@
20
19
  ],
21
20
  "license": "MIT",
22
21
  "devDependencies": {
23
- "@types/node": "^20.11.17",
24
- "@vitest/coverage-v8": "^1.2.2",
25
- "tsup": "^8.0.2",
26
- "typescript": "5.3.3",
27
- "vitest": "1.2.2"
22
+ "@types/node": "^22.10.1",
23
+ "@vitest/coverage-v8": "^2.1.8",
24
+ "tsup": "^8.3.5",
25
+ "typescript": "5.7.2",
26
+ "vitest": "2.1.8"
28
27
  },
29
28
  "exports": {
30
29
  "import": {