chmlib-ts
v0.3.0
Published
TypeScript port of chmlib - CHM archive reader
Readme
chmlib-ts
A pure TypeScript library for reading Microsoft HTML Help (.chm) archives. Port of chmlib by Jed Wing, with LZX decompression derived from cabextract by Stuart Caie.
Installation
npm install chmlib-tsLibrary Usage
import { ChmFile, ChmEnumerateFlags, ChmSpace } from 'chmlib-ts';
import { chmReaderFromFile, chmReaderFromBuffer } from 'chmlib-ts/reader';
// Open from a file path (Node.js)
const chm = await ChmFile.open(chmReaderFromFile('/path/to/file.chm'));
// Or from a Uint8Array
const chm = await ChmFile.open(chmReaderFromBuffer(uint8Array));
// Resolve and retrieve a file
const entry = await chm.resolve('/index.html');
if (entry) {
const data = await chm.retrieve(entry);
console.log(new TextDecoder().decode(data));
}
// Retrieve a byte range
const partial = await chm.retrieve(entry, 0n, 256n);
// Enumerate entries
for await (const entry of chm.enumerate(ChmEnumerateFlags.All)) {
console.log(entry.path, entry.length, entry.space === ChmSpace.Compressed ? 'compressed' : 'uncompressed');
}
// Parse /#SYSTEM metadata
import { parseSystemInfo } from 'chmlib-ts/system';
const raw = await chm.getSystemRaw();
const sys = parseSystemInfo(raw!);
console.log(sys.title, sys.defaultTopic);
// Parse .hhc/.hhk table of contents
import { parseToc } from 'chmlib-ts/toc';
const tocEntry = await chm.resolve(sys.tocFile!);
const tocData = await chm.retrieve(tocEntry!);
const toc = parseToc(new TextDecoder().decode(tocData));
chm.close();CLI
npx chmlib-ts <command> <file.chm> [options]| Command | Description |
|---|---|
| info | Display metadata (title, default topic, file/dir counts); --json available |
| list | List all entries with size and compression (--dir <prefix> supported); --json available |
| extract <outdir> | Extract files to a directory; --only html|assets and --exclude-meta available |
| extract-file <path> <outfile> | Extract a single file by its archive path |
| cat <path> | Print a decoded text file; --charset <encoding> overrides auto-detection |
| toc | Print the table of contents (--format tree for a tree view, --json available). When /#SYSTEM does not point to a text TOC, the CLI falls back to archive .hhc discovery |
| index | Print the keyword index (--format tree or --json); falls back to archive .hhk discovery |
| manifest | Print a JSON-friendly archive manifest including detected TOC/index files and canonical file list |
Examples
npx chmlib-ts info docs.chm
npx chmlib-ts info docs.chm --json
npx chmlib-ts list docs.chm
npx chmlib-ts list docs.chm --json
npx chmlib-ts extract docs.chm ./out
npx chmlib-ts extract docs.chm ./out --only html --exclude-meta
npx chmlib-ts extract-file docs.chm /index.html ./index.html
npx chmlib-ts cat docs.chm /index.html
npx chmlib-ts toc docs.chm
npx chmlib-ts toc docs.chm --json
npx chmlib-ts index docs.chm --json
npx chmlib-ts manifest docs.chm --jsonBuilding
npm install
npm run build # tsc → dist/
npm testAPI Reference
ChmFile
| Method | Description |
|---|---|
| static open(reader) | Parse a CHM archive and return a ChmFile |
| resolve(path) | Look up an entry by path; returns ChmUnitInfo \| null |
| retrieve(entry, offset?, length?) | Read entry data (or a sub-range) as Uint8Array |
| enumerate(flags) | Async generator yielding ChmUnitInfo for matching entries |
| enumerateDir(prefix, flags) | Async generator yielding ChmUnitInfo under a directory prefix |
| getSystemRaw() | Return the raw bytes of the /#SYSTEM metadata block |
| close() | Release file handle / resources |
ChmEnumerateFlags
enum ChmEnumerateFlags {
Normal = 1, // regular files
Meta = 2, // meta-files (names starting with #)
Special = 4, // special files (names starting with $)
Files = 8, // entries that are files
Dirs = 16, // entries that are directories
All = 31,
}ChmUnitInfo
interface ChmUnitInfo {
path: string;
space: ChmSpace; // Uncompressed | Compressed
start: bigint;
length: bigint;
flags: number;
}License
LGPL-2.1 — same as the original chmlib. LZX decompression code by Stuart Caie, originally from cabextract.
