@@ -10,6 +10,7 @@ const kReadFileMaxChunkSize = 2 ** 14;
10
10
const kWriteFileMaxChunkSize = 2 ** 14 ;
11
11
12
12
const {
13
+ ArrayIsArray,
13
14
ArrayPrototypePush,
14
15
Error,
15
16
MathMax,
@@ -21,6 +22,8 @@ const {
21
22
PromiseResolve,
22
23
SafeArrayIterator,
23
24
Symbol,
25
+ SymbolAsyncIterator,
26
+ SymbolIterator,
24
27
Uint8Array,
25
28
} = primordials ;
26
29
@@ -41,7 +44,7 @@ const {
41
44
ERR_INVALID_ARG_VALUE ,
42
45
ERR_METHOD_NOT_IMPLEMENTED ,
43
46
} = codes ;
44
- const { isArrayBufferView } = require ( 'internal/util/types' ) ;
47
+ const { isArrayBufferView, isTypedArray } = require ( 'internal/util/types' ) ;
45
48
const { rimrafPromises } = require ( 'internal/fs/rimraf' ) ;
46
49
const {
47
50
copyObject,
@@ -273,7 +276,18 @@ async function fsCall(fn, handle, ...args) {
273
276
}
274
277
275
278
async function writeFileHandle ( filehandle , data , signal ) {
276
- // `data` could be any kind of typed array.
279
+ if ( isIterable ( data ) ) {
280
+ for await ( const buf of data ) {
281
+ if ( signal ?. aborted ) {
282
+ throw lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ;
283
+ }
284
+ await filehandle . write ( buf ) ;
285
+ if ( signal ?. aborted ) {
286
+ throw lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ;
287
+ }
288
+ }
289
+ return ;
290
+ }
277
291
data = new Uint8Array ( data . buffer , data . byteOffset , data . byteLength ) ;
278
292
let remaining = data . length ;
279
293
if ( remaining === 0 ) return ;
@@ -663,13 +677,14 @@ async function writeFile(path, data, options) {
663
677
options = getOptions ( options , { encoding : 'utf8' , mode : 0o666 , flag : 'w' } ) ;
664
678
const flag = options . flag || 'w' ;
665
679
666
- if ( ! isArrayBufferView ( data ) ) {
680
+ if ( ! isIterable ( data ) && ! isArrayBufferView ( data ) ) {
667
681
validateStringAfterArrayBufferView ( data , 'data' ) ;
668
682
data = Buffer . from ( data , options . encoding || 'utf8' ) ;
669
683
}
670
684
671
- if ( path instanceof FileHandle )
685
+ if ( path instanceof FileHandle ) {
672
686
return writeFileHandle ( path , data , options . signal ) ;
687
+ }
673
688
674
689
const fd = await open ( path , flag , options . mode ) ;
675
690
if ( options . signal ?. aborted ) {
@@ -678,6 +693,18 @@ async function writeFile(path, data, options) {
678
693
return PromisePrototypeFinally ( writeFileHandle ( fd , data ) , fd . close ) ;
679
694
}
680
695
696
+ function isIterable ( obj ) {
697
+ if ( obj == null ) {
698
+ return false ;
699
+ }
700
+
701
+ return SymbolAsyncIterator in obj || (
702
+ SymbolIterator in obj &&
703
+ typeof obj !== 'string' &&
704
+ ! ArrayIsArray ( obj ) &&
705
+ ! isTypedArray ( obj ) ) ;
706
+ }
707
+
681
708
async function appendFile ( path , data , options ) {
682
709
options = getOptions ( options , { encoding : 'utf8' , mode : 0o666 , flag : 'a' } ) ;
683
710
options = copyObject ( options ) ;
0 commit comments