@@ -98,7 +98,7 @@ class ParseFile {
9898 * JSON encoding if metadata or tags are set.
9999 * 6. (Node.js only) a Readable stream, or a Web ReadableStream.
100100 * Streamed as raw binary data directly into the upload request.
101- * Throws if metadata or tags are set .
101+ * Supports metadata, tags, and directory when Parse Server >= 9.5.0 .
102102 * For example:
103103 * <pre>
104104 * var fileUploadControl = $("#profilePhotoFileUpload")[0];
@@ -289,8 +289,8 @@ class ParseFile {
289289 * In Node.js, files created with Buffer or ReadableStream are uploaded as
290290 * raw binary data, avoiding base64 encoding overhead. If metadata
291291 * or tags are set on a Buffer-backed file, the upload falls back to base64
292- * JSON encoding (since the binary endpoint does not support metadata).
293- * Stream-backed files with metadata or tags will throw an error .
292+ * JSON encoding. Stream-backed files support metadata, tags, and directory
293+ * when Parse Server >= 9.5.0 .
294294 *
295295 * @param {object } options
296296 * Valid options are:<ul>
@@ -322,24 +322,19 @@ class ParseFile {
322322 const controller = CoreManager . getFileController ( ) ;
323323 if ( ! this . _previousSave ) {
324324 if ( this . _source . format === 'buffer' || this . _source . format === 'stream' ) {
325- const hasFileData =
326- ( this . _metadata && Object . keys ( this . _metadata ) . length > 0 ) ||
327- ( this . _tags && Object . keys ( this . _tags ) . length > 0 ) ||
328- ! ! this . _directory ;
329-
330- if ( this . _source . format === 'stream' && hasFileData ) {
331- throw new Error (
332- 'Cannot save a stream-based file with metadata, tags, or directory. Use a Buffer instead.'
333- ) ;
334- }
335325 if ( this . _source . format === 'stream' && ! controller . saveBinary ) {
336326 throw new Error (
337327 'Cannot save a stream-based file without saveBinary support on the FileController.'
338328 ) ;
339329 }
340330
341- if ( ! hasFileData && controller . saveBinary ) {
342- // Binary upload via ajax
331+ const hasFileData =
332+ ( this . _metadata && Object . keys ( this . _metadata ) . length > 0 ) ||
333+ ( this . _tags && Object . keys ( this . _tags ) . length > 0 ) ||
334+ ! ! this . _directory ;
335+
336+ if ( controller . saveBinary && ( this . _source . format === 'stream' || ! hasFileData ) ) {
337+ // Binary upload via ajax (file data sent via headers for streams)
343338 this . _previousSave = controller
344339 . saveBinary ( this . _name , this . _source , options )
345340 . then ( res => {
@@ -469,7 +464,8 @@ class ParseFile {
469464 }
470465
471466 /**
472- * Sets metadata to be saved with file object. Overwrites existing metadata
467+ * Sets metadata to be saved with file object. Overwrites existing metadata.
468+ * When used with a stream-based file, requires Parse Server >= 9.5.0.
473469 *
474470 * @param {object } metadata Key value pairs to be stored with file object
475471 */
@@ -483,6 +479,7 @@ class ParseFile {
483479
484480 /**
485481 * Sets metadata to be saved with file object. Adds to existing metadata.
482+ * When used with a stream-based file, requires Parse Server >= 9.5.0.
486483 *
487484 * @param {string } key key to store the metadata
488485 * @param {* } value metadata
@@ -494,7 +491,8 @@ class ParseFile {
494491 }
495492
496493 /**
497- * Sets tags to be saved with file object. Overwrites existing tags
494+ * Sets tags to be saved with file object. Overwrites existing tags.
495+ * When used with a stream-based file, requires Parse Server >= 9.5.0.
498496 *
499497 * @param {object } tags Key value pairs to be stored with file object
500498 */
@@ -508,6 +506,7 @@ class ParseFile {
508506
509507 /**
510508 * Sets tags to be saved with file object. Adds to existing tags.
509+ * When used with a stream-based file, requires Parse Server >= 9.5.0.
511510 *
512511 * @param {string } key key to store tags
513512 * @param {* } value tag
@@ -521,7 +520,7 @@ class ParseFile {
521520 /**
522521 * Sets the directory where the file will be stored.
523522 * Requires the Master Key when saving.
524- * Requires Parse Server >= 9.4.0.
523+ * Requires Parse Server >= 9.4.0; when used with a stream-based file, requires Parse Server >= 9.5.0 .
525524 *
526525 * @param {string } directory the directory path
527526 */
@@ -624,6 +623,15 @@ const DefaultController = {
624623 'X-Parse-Upload-Mode' : 'stream' ,
625624 } ;
626625 headers [ 'Content-Type' ] = ( source . type || 'application/octet-stream' ) . replace ( / [ \r \n ] / g, '' ) ;
626+ if ( options . directory ) {
627+ headers [ 'X-Parse-File-Directory' ] = options . directory . replace ( / [ \r \n ] / g, '' ) ;
628+ }
629+ if ( options . metadata && Object . keys ( options . metadata ) . length > 0 ) {
630+ headers [ 'X-Parse-File-Metadata' ] = JSON . stringify ( options . metadata ) ;
631+ }
632+ if ( options . tags && Object . keys ( options . tags ) . length > 0 ) {
633+ headers [ 'X-Parse-File-Tags' ] = JSON . stringify ( options . tags ) ;
634+ }
627635 const jsKey = CoreManager . get ( 'JAVASCRIPT_KEY' ) ;
628636 if ( jsKey ) {
629637 headers [ 'X-Parse-JavaScript-Key' ] = jsKey ;
0 commit comments