file
File read and write streams for Node.js and the browser.
Install
npm install @datastream/file fileReadStream Readable
Reads a file as a stream.
- Node.js: Uses
fs.createReadStream - Browser: Uses
window.showOpenFilePicker(File System Access API)
Options
| Option | Type | Description |
|---|---|---|
path | string | File path (Node.js) |
basePath | string | When provided, enforces that path resolves within basePath. Prevents path traversal and rejects symbolic links |
types | object[] | File type filter for the file picker (see below) |
Example — Node.js
import { pipeline } from '@datastream/core'
import { fileReadStream } from '@datastream/file'
await pipeline([
fileReadStream({ path: './data.csv' }),
]) Example — Browser
import { fileReadStream } from '@datastream/file'
const stream = await fileReadStream({
types: [{ accept: { 'text/csv': ['.csv'] } }],
}) fileWriteStream Writable
Writes a stream to a file.
- Node.js: Uses
fs.createWriteStream - Browser: Uses
window.showSaveFilePicker(File System Access API)
Options
| Option | Type | Description |
|---|---|---|
path | string | File path (Node.js), suggested file name (Browser) |
basePath | string | When provided, enforces that path resolves within basePath. Prevents path traversal and rejects symbolic links |
types | object[] | File type filter |
Example — Node.js
import { pipeline, createReadableStream } from '@datastream/core'
import { fileWriteStream } from '@datastream/file'
await pipeline([
createReadableStream('hello world'),
fileWriteStream({ path: './output.txt' }),
]) Example — Browser
import { fileWriteStream } from '@datastream/file'
const writable = await fileWriteStream({
path: 'output.csv',
types: [{ accept: { 'text/csv': ['.csv'] } }],
}) File type filtering
The types option validates file extensions (Node.js) and configures the file picker dialog (Browser):
const types = [
{
accept: {
'text/csv': ['.csv'],
'application/json': ['.json'],
},
},
] On Node.js, if types is provided and the file extension doesn’t match, an "Invalid extension" error is thrown.
Security
When accepting file paths from user input, always use an absolute path or set basePath to prevent path traversal attacks (e.g., ../../etc/passwd). Relative paths without a basePath constraint can resolve outside the intended directory.
basePath is opt-in. When provided, paths are resolved and checked with path.resolve().startsWith(basePath), and symbolic links are rejected. When omitted, no path restriction is applied.
// Restrict reads to a specific directory
fileReadStream({ path: userInput, basePath: '/data/uploads', types })
// Convenience helper for cwd-scoped reads
const safeFileRead = (path, types) =>
fileReadStream({ path, basePath: process.cwd(), types })