# @stackline/fstream `@stackline/fstream` is a compatibility-first maintained continuation of [`fstream@1.0.12`](https://www.npmjs.com/package/fstream). It exposes stat-bearing filesystem object streams for files, directories, links, sockets, and recursive directory trees. This project is independent. It is not affiliated with or endorsed by Isaac Z. Schlueter, the npm organization, or the upstream project. ## Runtime and compatibility - Node.js 14.15.1 or newer; - the exact 16-key CommonJS namespace and callable/newable Reader and Writer factories from `fstream@1.0.12`; - all 14 historical `lib/` entry points, with and without `.js`; - additive ESM default/named exports and TypeScript 3.9-compatible types; - deterministic termination for ancestor symbolic-link cycles; and - traversal-local hard-link state. This is a Node.js filesystem package. It does not ship or claim a browser build. ## Install ```sh npm install @stackline/fstream ``` To keep existing `require('fstream')` calls unchanged, use an npm alias: ```json { "dependencies": { "fstream": "npm:@stackline/fstream@1.0.0" } } ``` ## Copy a tree with CommonJS ```js const fstream = require('@stackline/fstream') const reader = fstream.Reader({ path: 'source', sort: 'alpha' }) const writer = fstream.Writer('destination') reader.on('error', console.error) writer.on('error', console.error) reader.pipe(writer) ``` ## Inspect a tree with ESM ```js import path from 'node:path' import { Reader } from '@stackline/fstream' const target = path.resolve(process.argv[2] || '.') const reader = Reader({ path: target, sort: 'alpha' }) reader.on('child', (entry) => { console.log(entry.type, path.relative(target, entry.path)) }) reader.on('error', console.error) ``` Runnable examples: - [CommonJS tree reader](./examples/commonjs.cjs) - [ESM tree reader](./examples/esm.mjs) ## Main API - `Reader(pathOrOptions[, currentStat])` selects a specialized Reader and exposes filesystem metadata and events. - `Writer(pathOrOptions[, currentStat])` creates a compatible specialized Writer and applies supported metadata. - `collect(stream)` pauses and buffers a compatible legacy stream until its replacement `pipe()` is called. - `Abstract`, `File`, `Dir`, `Link`, `Proxy`, the eight historical root constructor aliases, and 14 historical deep modules remain available. See the [complete API reference](./API.md). ## Common options | Option | Meaning | | --- | --- | | `path` | Required filesystem path. | | `type` | Explicit entry type or historical constructor selector. | | `filter(entry, stat)` | Include or exclude an entry. | | `sort` | `'alpha'` or a directory-entry comparator. | | `follow` | Follow symbolic links; ancestor cycles warn with `ELOOP`. | | `hardlinks` | Set `false` to read each multiply-linked path as a File. | | `size` | Validate the expected byte count. | | `mode`, `uid`, `gid` | Request output permissions and ownership. | | `atime`, `mtime` | Request access and modification timestamps. | | `flags`, `linkpath`, `clobber` | Control applicable Writer behavior. | ## Filesystem boundary Writers mutate caller-selected paths and may replace incompatible destinations. `follow: true` may traverse outside the lexical source directory. Validate paths, enforce an allowed root, and define resource limits around untrusted input. Cycle detection is a termination guarantee, not a sandbox or archive extraction policy. Read the [security boundary](./SECURITY.md) before processing untrusted paths or metadata. ## Reference - [API](./API.md) - [Compatibility contract](./COMPATIBILITY_CONTRACT.md) - [Migration](./MIGRATION.md) - [Security](./SECURITY.md) - [Third-party licenses](./THIRD_PARTY_LICENSES.md) - [Machine-readable package metadata](./package-meta.json) ## License ISC. Upstream copyright and attribution are retained in [LICENSE](./LICENSE), [NOTICE](./NOTICE), and [THIRD_PARTY_LICENSES.md](./THIRD_PARTY_LICENSES.md).