@@ -9,85 +9,93 @@ import os from 'node:os';
99import path from 'node:path' ;
1010import { StringDecoder } from 'node:string_decoder' ;
1111import once from 'once' ;
12+
1213import FormidableError , * as errors from './FormidableError.js' ;
13- import PersistentFile from './PersistentFile.js' ;
14- import VolatileFile from './VolatileFile.js' ;
1514import DummyParser from './parsers/Dummy.js' ;
1615import MultipartParser from './parsers/Multipart.js' ;
17- import { json , multipart , octetstream , querystring } from './plugins/index.js' ;
16+ import PersistentFile from './PersistentFile.js' ;
17+ import {
18+ json ,
19+ multipart ,
20+ octetstream ,
21+ querystring ,
22+ } from './plugins/index.js' ;
23+ import VolatileFile from './VolatileFile.js' ;
1824
19- const CUID2_FINGERPRINT = `${ process . env . NODE_ENV } -${ os . platform ( ) } -${ os . hostname ( ) } `
20- const createId = cuid2init ( { length : 25 , fingerprint : CUID2_FINGERPRINT . toLowerCase ( ) } ) ;
25+ const CUID2_FINGERPRINT = `${ process . env . NODE_ENV } -${ os . platform ( ) } -${ os . hostname ( ) } ` ;
26+ const createId = cuid2init ( { fingerprint : CUID2_FINGERPRINT . toLowerCase ( ) , length : 25 } ) ;
2127
2228const DEFAULT_OPTIONS = {
23- maxFields : 1000 ,
24- maxFieldsSize : 20 * 1024 * 1024 ,
25- maxFiles : Infinity ,
26- maxFileSize : 200 * 1024 * 1024 ,
27- maxTotalFileSize : undefined ,
28- minFileSize : 1 ,
2929 allowEmptyFiles : false ,
3030 createDirsFromUploads : false ,
31- keepExtensions : false ,
32- encoding : 'utf-8' ,
33- hashAlgorithm : false ,
34- uploadDir : os . tmpdir ( ) ,
31+ defaultInvalidName : 'invalid-name' ,
3532 enabledPlugins : [ octetstream , querystring , multipart , json ] ,
33+ encoding : 'utf-8' ,
34+ filename : undefined ,
3635 fileWriteStreamHandler : null ,
37- defaultInvalidName : 'invalid-name' ,
3836 filter ( _part ) {
3937 return true ;
4038 } ,
41- filename : undefined ,
39+ hashAlgorithm : false ,
40+ keepExtensions : false ,
41+ maxFields : 1000 ,
42+ maxFieldsSize : 20 * 1024 * 1024 ,
43+ maxFiles : Infinity ,
44+ maxFileSize : 200 * 1024 * 1024 ,
45+ maxTotalFileSize : undefined ,
46+ minFileSize : 1 ,
47+ uploadDir : os . tmpdir ( ) ,
4248} ;
4349
4450function hasOwnProp ( obj , key ) {
45- return Object . prototype . hasOwnProperty . call ( obj , key ) ;
51+ return Object . hasOwn ( obj , key ) ;
4652}
4753
48-
49- const decorateForceSequential = function ( promiseCreator ) {
54+ function decorateForceSequential ( promiseCreator ) {
5055 /* forces a function that returns a promise to be sequential
5156 useful for fs for example */
5257 let lastPromise = Promise . resolve ( ) ;
58+
5359 return async function ( ...x ) {
54- const promiseWeAreWaitingFor = lastPromise ;
55- let currentPromise ;
56- let callback ;
57- // we need to change lastPromise before await anything,
58- // otherwise 2 calls might wait the same thing
59- lastPromise = new Promise ( function ( resolve ) {
60- callback = resolve ;
61- } ) ;
62- await promiseWeAreWaitingFor ;
63- currentPromise = promiseCreator ( ...x ) ;
64- currentPromise . then ( callback ) . catch ( callback ) ;
65- return currentPromise ;
60+ const promiseWeAreWaitingFor = lastPromise ;
61+ let currentPromise ;
62+ let callback ;
63+ // we need to change lastPromise before await anything,
64+ // otherwise 2 calls might wait the same thing
65+ lastPromise = new Promise ( ( resolve ) => {
66+ callback = resolve ;
67+ } ) ;
68+ await promiseWeAreWaitingFor ;
69+ currentPromise = promiseCreator ( ...x ) ;
70+ currentPromise . then ( callback ) . catch ( callback ) ;
71+ return currentPromise ;
6672 } ;
67- } ;
73+ }
6874
69- const createNecessaryDirectoriesAsync = decorateForceSequential ( function ( filePath ) {
75+ const createNecessaryDirectoriesAsync = decorateForceSequential ( ( filePath ) => {
7076 const directoryname = path . dirname ( filePath ) ;
77+
7178 return fsPromises . mkdir ( directoryname , { recursive : true } ) ;
7279} ) ;
7380
74- const invalidExtensionChar = ( c ) => {
81+ function invalidExtensionChar ( c ) {
7582 const code = c . charCodeAt ( 0 ) ;
83+
7684 return ! (
77- code === 46 || // .
78- ( code >= 48 && code <= 57 ) ||
79- ( code >= 65 && code <= 90 ) ||
80- ( code >= 97 && code <= 122 )
85+ code === 46 // .
86+ || ( code >= 48 && code <= 57 )
87+ || ( code >= 65 && code <= 90 )
88+ || ( code >= 97 && code <= 122 )
8189 ) ;
82- } ;
90+ }
8391
8492class IncomingForm extends EventEmitter {
8593 constructor ( options = { } ) {
8694 super ( ) ;
8795
8896 this . options = { ...DEFAULT_OPTIONS , ...options } ;
8997 if ( ! this . options . maxTotalFileSize ) {
90- this . options . maxTotalFileSize = this . options . maxFileSize
98+ this . options . maxTotalFileSize = this . options . maxFileSize ;
9199 }
92100
93101 const dir = path . resolve (
@@ -150,7 +158,7 @@ class IncomingForm extends EventEmitter {
150158 return this ;
151159 }
152160
153- pause ( ) {
161+ pause ( ) {
154162 try {
155163 this . req . pause ( ) ;
156164 } catch ( err ) {
@@ -164,7 +172,7 @@ class IncomingForm extends EventEmitter {
164172 return true ;
165173 }
166174
167- resume ( ) {
175+ resume ( ) {
168176 try {
169177 this . req . resume ( ) ;
170178 } catch ( err ) {
@@ -198,7 +206,7 @@ class IncomingForm extends EventEmitter {
198206 } else {
199207 resolveRef ( [ fields , files ] ) ;
200208 }
201- }
209+ } ;
202210 }
203211 const callback = once ( dezalgo ( cb ) ) ;
204212 this . fields = { } ;
@@ -256,6 +264,7 @@ class IncomingForm extends EventEmitter {
256264 this . _parser . end ( ) ;
257265 }
258266 } ) ;
267+
259268 if ( promise ) {
260269 return promise ;
261270 }
@@ -365,10 +374,10 @@ class IncomingForm extends EventEmitter {
365374 const newFilename = this . _getNewName ( part ) ;
366375 const filepath = this . _joinDirectoryName ( newFilename ) ;
367376 const file = await this . _newFile ( {
368- newFilename,
369377 filepath,
370- originalFilename : part . originalFilename ,
371378 mimetype : part . mimetype ,
379+ newFilename,
380+ originalFilename : part . originalFilename ,
372381 } ) ;
373382 file . on ( 'error' , ( err ) => {
374383 this . _error ( err ) ;
@@ -459,7 +468,6 @@ class IncomingForm extends EventEmitter {
459468 return ;
460469 }
461470
462-
463471 new DummyParser ( this , this . options ) ;
464472
465473 const results = [ ] ;
@@ -517,21 +525,26 @@ class IncomingForm extends EventEmitter {
517525 return new MultipartParser ( this . options ) ;
518526 }
519527
520- async _newFile ( { filepath, originalFilename, mimetype, newFilename } ) {
528+ async _newFile ( {
529+ filepath,
530+ mimetype,
531+ newFilename,
532+ originalFilename,
533+ } ) {
521534 if ( this . options . fileWriteStreamHandler ) {
522535 return new VolatileFile ( {
523- newFilename,
524- filepath,
525- originalFilename,
526- mimetype,
527536 createFileWriteStream : this . options . fileWriteStreamHandler ,
537+ filepath,
528538 hashAlgorithm : this . options . hashAlgorithm ,
539+ mimetype,
540+ newFilename,
541+ originalFilename,
529542 } ) ;
530543 }
531544 if ( this . options . createDirsFromUploads ) {
532545 try {
533546 await createNecessaryDirectoriesAsync ( filepath ) ;
534- } catch ( errorCreatingDir ) {
547+ } catch ( err ) {
535548 this . _error ( new FormidableError (
536549 `cannot create directory` ,
537550 errors . cannotCreateDir ,
@@ -540,27 +553,26 @@ class IncomingForm extends EventEmitter {
540553 }
541554 }
542555 return new PersistentFile ( {
543- newFilename,
544556 filepath,
545- originalFilename,
546- mimetype,
547557 hashAlgorithm : this . options . hashAlgorithm ,
558+ mimetype,
559+ newFilename,
560+ originalFilename,
548561 } ) ;
549562 }
550563
551564 _getFileName ( headerValue ) {
552565 // matches either a quoted-string or a token (RFC 2616 section 19.5.1)
553566 const m = headerValue . match (
554- / \b f i l e n a m e = ( " ( .* ?) " | ( [ ^ ( ) < > { } [ \] @ , ; : " ? = \s / \t ] + ) ) ( $ | ; \s ) / i,
567+ / \b f i l e n a m e = ( " ( .* ?) " | ( [ ^ ( ) < > { } [ \] @ , ; : " ? = \s / ] + ) ) ( $ | ; \s ) / i,
555568 ) ;
556- if ( ! m ) return null ;
569+ if ( ! m )
570+ return null ;
557571
558572 const match = m [ 2 ] || m [ 3 ] || '' ;
559573 let originalFilename = match . substr ( match . lastIndexOf ( '\\' ) + 1 ) ;
560574 originalFilename = originalFilename . replace ( / % 2 2 / g, '"' ) ;
561- originalFilename = originalFilename . replace ( / & # ( [ \d ] { 4 } ) ; / g, ( _ , code ) =>
562- String . fromCharCode ( code ) ,
563- ) ;
575+ originalFilename = originalFilename . replace ( / & # ( \d { 4 } ) ; / g, ( _ , code ) => String . fromCharCode ( code ) ) ;
564576
565577 return originalFilename ;
566578 }
@@ -579,7 +591,7 @@ class IncomingForm extends EventEmitter {
579591 let rawExtname = path . extname ( basename ) ;
580592
581593 if ( firstDot !== lastDot ) {
582- rawExtname = basename . slice ( firstDot ) ;
594+ rawExtname = basename . slice ( firstDot ) ;
583595 }
584596
585597 let filtered ;
@@ -626,8 +638,9 @@ class IncomingForm extends EventEmitter {
626638 const name = createId ( ) ;
627639
628640 if ( part && this . options . keepExtensions ) {
629- const originalFilename =
630- typeof part === 'string' ? part : part . originalFilename ;
641+ const originalFilename
642+ = typeof part === 'string' ? part : part . originalFilename ;
643+
631644 return `${ name } ${ this . _getExtension ( originalFilename ) } ` ;
632645 }
633646
0 commit comments