@@ -310,6 +310,96 @@ describe('set', () => {
310310 await blobs . set ( key , value , { ttl } )
311311 } )
312312
313+ test ( 'Sets content-length when sending a stream' , async ( ) => {
314+ const fetcher = async ( ...args : Parameters < typeof globalThis . fetch > ) => {
315+ const [ url , options ] = args
316+ const headers = options ?. headers as Record < string , string >
317+
318+ if ( url === `https://api.netlify.com/api/v1/sites/${ siteID } /blobs/${ key } ?context=production` ) {
319+ const data = JSON . stringify ( { url : signedURL } )
320+
321+ expect ( headers . authorization ) . toBe ( `Bearer ${ apiToken } ` )
322+
323+ return new Response ( data )
324+ }
325+ expect ( headers [ 'content-length' ] ) . toBe ( '100' )
326+ return new Response ( 'OK' )
327+ }
328+
329+ const blobs = new Blobs ( {
330+ authentication : {
331+ token : apiToken ,
332+ } ,
333+ fetcher,
334+ siteID,
335+ } )
336+
337+ const stream = new ReadableStream ( )
338+
339+ await blobs . set ( key , stream , { contentLength : 100 } )
340+ } )
341+
342+ test ( 'Throws if a stream is passed with no contentLength' , async ( ) => {
343+ const fetcher = async ( ...args : Parameters < typeof globalThis . fetch > ) => {
344+ const [ url , options ] = args
345+ const headers = options ?. headers as Record < string , string >
346+
347+ if ( url === `https://api.netlify.com/api/v1/sites/${ siteID } /blobs/${ key } ?context=production` ) {
348+ const data = JSON . stringify ( { url : signedURL } )
349+
350+ expect ( headers . authorization ) . toBe ( `Bearer ${ apiToken } ` )
351+
352+ return new Response ( data )
353+ }
354+ expect ( headers [ 'content-length' ] ) . toBe ( '100' )
355+ return new Response ( 'OK' )
356+ }
357+
358+ const blobs = new Blobs ( {
359+ authentication : {
360+ token : apiToken ,
361+ } ,
362+ fetcher,
363+ siteID,
364+ } )
365+
366+ const stream = new ReadableStream ( )
367+ // @ts -expect-error - we're testing the error case
368+ await expect ( blobs . set ( key , stream ) ) . rejects . toThrowError (
369+ 'You must specify a `contentLength` parameter when `data` is a ReadableStream' ,
370+ )
371+ } )
372+
373+ test ( 'Ignores content-length when data is not a stream' , async ( ) => {
374+ const fetcher = async ( ...args : Parameters < typeof globalThis . fetch > ) => {
375+ const [ url , options ] = args
376+ const headers = options ?. headers as Record < string , string >
377+
378+ expect ( options ?. method ) . toBe ( 'put' )
379+
380+ if ( url === `https://api.netlify.com/api/v1/sites/${ siteID } /blobs/${ key } ?context=production` ) {
381+ const data = JSON . stringify ( { url : signedURL } )
382+
383+ expect ( headers . authorization ) . toBe ( `Bearer ${ apiToken } ` )
384+
385+ return new Response ( data )
386+ }
387+
388+ expect ( headers [ 'content-length' ] ) . toBeUndefined ( )
389+ return new Response ( 'OK' )
390+ }
391+
392+ const blobs = new Blobs ( {
393+ authentication : {
394+ token : apiToken ,
395+ } ,
396+ fetcher,
397+ siteID,
398+ } )
399+ // @ts -expect-error - we're testing the error case
400+ await blobs . set ( key , 'value' , { contentLength : 100 } )
401+ } )
402+
313403 test ( 'Throws when the API returns a non-200 status code' , async ( ) => {
314404 const fetcher = async ( ...args : Parameters < typeof globalThis . fetch > ) => {
315405 const [ url , options ] = args
0 commit comments