diff --git a/src/js/node/fs.promises.ts b/src/js/node/fs.promises.ts index 13d29f8b14..6f0a0e2dec 100644 --- a/src/js/node/fs.promises.ts +++ b/src/js/node/fs.promises.ts @@ -3,6 +3,8 @@ const types = require("node:util/types"); const EventEmitter = require("node:events"); const fs = $zig("node_fs_binding.zig", "createBinding") as $ZigGeneratedClasses.NodeJSFS; const { glob } = require("internal/fs/glob"); +const { validateInteger } = require("internal/validators"); + const constants = $processBindingConstants.fs; var PromisePrototypeFinally = $Promise.prototype.finally; //TODO @@ -22,7 +24,7 @@ const kDeserialize = Symbol("kDeserialize"); const kEmptyObject = ObjectFreeze(Object.create(null)); const kFlag = Symbol("kFlag"); -const { validateInteger } = require("internal/validators"); +let Interface; // lazy value for require("node:readline").Interface. function watch( filename: string | Buffer | URL, @@ -413,8 +415,12 @@ function asyncWrap(fn: any, name: string) { } } - readLines(_options = undefined) { - throw new Error("BUN TODO FileHandle.readLines"); + readLines(options = undefined) { + if (Interface === undefined) Interface = require("node:readline").Interface; + return new Interface({ + input: this.createReadStream(options), + crlfDelay: Infinity, + }); } async stat(options) { @@ -513,7 +519,7 @@ function asyncWrap(fn: any, name: string) { } } - close = () => { + async close() { const fd = this[kFd]; if (fd === -1) { return Promise.$resolve(); @@ -544,7 +550,7 @@ function asyncWrap(fn: any, name: string) { this.emit("close"); return this[kClosePromise]; - }; + } async [SymbolAsyncDispose]() { return this.close(); diff --git a/test/js/node/test/parallel/test-fs-promises-file-handle-readLines.mjs b/test/js/node/test/parallel/test-fs-promises-file-handle-readLines.mjs new file mode 100644 index 0000000000..bd1577e23f --- /dev/null +++ b/test/js/node/test/parallel/test-fs-promises-file-handle-readLines.mjs @@ -0,0 +1,39 @@ +import '../common/index.mjs'; +import tmpdir from '../common/tmpdir.js'; + +import assert from 'node:assert'; +import { open, writeFile } from 'node:fs/promises'; + +tmpdir.refresh(); + +const filePath = tmpdir.resolve('file.txt'); + +await writeFile(filePath, '1\n\n2\n'); + +let file; +try { + file = await open(filePath); + + let i = 0; + for await (const line of file.readLines()) { + switch (i++) { + case 0: + assert.strictEqual(line, '1'); + break; + + case 1: + assert.strictEqual(line, ''); + break; + + case 2: + assert.strictEqual(line, '2'); + break; + + default: + assert.fail(); + break; + } + } +} finally { + await file?.close(); +} diff --git a/test/no-validate-exceptions.txt b/test/no-validate-exceptions.txt index 4c4aa54228..2d31e15934 100644 --- a/test/no-validate-exceptions.txt +++ b/test/no-validate-exceptions.txt @@ -49,6 +49,7 @@ test/bundler/esbuild/default.test.ts test/cli/install/bun-repl.test.ts test/js/third_party/astro/astro-post.test.js test/regression/issue/ctrl-c.test.ts +test/js/node/test/parallel/test-fs-promises-file-handle-readLines.mjs # trips asan on my macos test machine test/js/node/test/parallel/test-fs-watch.js