66 createBase64DecoderTransformStream ,
77 createBase64EncoderTransformStream ,
88} from 'cloudflare-internal:streaming-base64' ;
9- import { withSpan , type Span } from 'cloudflare-internal:tracing-helpers' ;
9+ import { withSpan } from 'cloudflare-internal:tracing-helpers' ;
1010
1111type Fetcher = {
1212 fetch : typeof fetch ;
@@ -122,51 +122,40 @@ class ImageTransformerImpl implements ImageTransformer {
122122 async output (
123123 options : ImageOutputOptions
124124 ) : Promise < ImageTransformationResult > {
125- return await withSpan ( 'images_output' , async ( span ) => {
126- span . setAttribute ( 'cloudflare.binding.type' , 'Images' ) ;
127- const formData = new StreamableFormData ( ) ;
125+ const formData = new StreamableFormData ( ) ;
128126
129- this . #consume( ) ;
130- formData . append ( 'image' , this . #stream, { type : 'file' } ) ;
127+ this . #consume( ) ;
128+ formData . append ( 'image' , this . #stream, { type : 'file' } ) ;
131129
132- this . #serializeTransforms( formData , span ) ;
130+ this . #serializeTransforms( formData ) ;
133131
134- span . setAttribute ( 'cloudflare.images.options.format' , options . format ) ;
135- formData . append ( 'output_format' , options . format ) ;
132+ formData . append ( 'output_format' , options . format ) ;
133+ if ( options . quality !== undefined ) {
134+ formData . append ( 'output_quality' , options . quality . toString ( ) ) ;
135+ }
136136
137- if ( options . quality !== undefined ) {
138- span . setAttribute ( 'cloudflare.images.options.quality' , options . quality ) ;
139- formData . append ( 'output_quality' , options . quality . toString ( ) ) ;
140- }
137+ if ( options . background !== undefined ) {
138+ formData . append ( 'background' , options . background ) ;
139+ }
141140
142- if ( options . background !== undefined ) {
143- span . setAttribute (
144- 'cloudflare.images.options.background' ,
145- options . background
146- ) ;
147- formData . append ( 'background' , options . background ) ;
148- }
141+ if ( options . anim !== undefined ) {
142+ formData . append ( 'anim' , options . anim . toString ( ) ) ;
143+ }
149144
150- if ( options . anim !== undefined ) {
151- span . setAttribute ( 'cloudflare.images.options.anim' , options . anim ) ;
152- formData . append ( 'anim' , options . anim . toString ( ) ) ;
145+ const response = await this . #fetcher. fetch (
146+ 'https://js.images.cloudflare.com/transform' ,
147+ {
148+ method : 'POST' ,
149+ headers : {
150+ 'content-type' : formData . contentType ( ) ,
151+ } ,
152+ body : formData . stream ( ) ,
153153 }
154+ ) ;
154155
155- const response = await this . #fetcher. fetch (
156- 'https://js.images.cloudflare.com/transform' ,
157- {
158- method : 'POST' ,
159- headers : {
160- 'content-type' : formData . contentType ( ) ,
161- } ,
162- body : formData . stream ( ) ,
163- }
164- ) ;
165-
166- await throwErrorIfErrorResponse ( 'TRANSFORM' , response , span ) ;
156+ await throwErrorIfErrorResponse ( 'TRANSFORM' , response ) ;
167157
168- return new TransformationResultImpl ( response ) ;
169- } ) ;
158+ return new TransformationResultImpl ( response ) ;
170159 }
171160
172161 #consume( ) : void {
@@ -180,7 +169,7 @@ class ImageTransformerImpl implements ImageTransformer {
180169 this . #consumed = true ;
181170 }
182171
183- #serializeTransforms( formData : StreamableFormData , span : Span ) : void {
172+ #serializeTransforms( formData : StreamableFormData ) : void {
184173 const transforms : ( TargetedTransform | DrawCommand ) [ ] = [ ] ;
185174
186175 // image 0 is the canvas, so the first draw_image has index 1
@@ -222,16 +211,6 @@ class ImageTransformerImpl implements ImageTransformer {
222211 }
223212
224213 walkTransforms ( 0 , this . #transforms) ;
225-
226- // The transforms are a set of operations which are applied to the image in order.
227- // Attaching an attribute as JSON is a little odd, but I'm not sure if there is
228- // a better way to do this.
229- if ( transforms . length > 0 ) {
230- span . setAttribute (
231- 'cloudflare.images.options.transforms' ,
232- JSON . stringify ( transforms )
233- ) ;
234- }
235214 formData . append ( 'transforms' , JSON . stringify ( transforms ) ) ;
236215 }
237216}
@@ -256,18 +235,15 @@ class ImagesBindingImpl implements ImagesBinding {
256235 options ?: ImageInputOptions
257236 ) : Promise < ImageInfoResponse > {
258237 return await withSpan ( 'images_info' , async ( span ) => {
259- span . setAttribute ( 'cloudflare.binding.type' , 'Images' ) ;
260238 const body = new StreamableFormData ( ) ;
261239
262- span . setAttribute (
263- 'cloudflare.images.options.encoding' ,
264- options ?. encoding ?? 'base64'
265- ) ;
266240 const decodedStream =
267241 options ?. encoding === 'base64'
268242 ? stream . pipeThrough ( createBase64DecoderTransformStream ( ) )
269243 : stream ;
270244
245+ span . setAttribute ( 'cloudflare.images.info.encoding' , options ?. encoding ) ;
246+
271247 body . append ( 'image' , decodedStream , { type : 'file' } ) ;
272248
273249 const response = await this . #fetcher. fetch (
@@ -281,23 +257,22 @@ class ImagesBindingImpl implements ImagesBinding {
281257 }
282258 ) ;
283259
284- await throwErrorIfErrorResponse ( 'INFO' , response , span ) ;
260+ await throwErrorIfErrorResponse ( 'INFO' , response ) ;
285261
286262 const r = ( await response . json ( ) ) as RawInfoResponse ;
287263
288- span . setAttribute ( 'cloudflare.images.result .format' , r . format ) ;
264+ span . setAttribute ( 'cloudflare.images.info .format' , r . format ) ;
289265
290266 if ( 'file_size' in r ) {
291- const ret = {
267+ span . setAttribute ( 'cloudflare.images.info.file_size' , r . file_size ) ;
268+ span . setAttribute ( 'cloudflare.images.info.width' , r . width ) ;
269+ span . setAttribute ( 'cloudflare.images.info.height' , r . height ) ;
270+ return {
292271 fileSize : r . file_size ,
293272 width : r . width ,
294273 height : r . height ,
295274 format : r . format ,
296275 } ;
297- span . setAttribute ( 'cloudflare.images.result.file_size' , ret . fileSize ) ;
298- span . setAttribute ( 'cloudflare.images.result.width' , ret . width ) ;
299- span . setAttribute ( 'cloudflare.images.result.height' , ret . height ) ;
300- return ret ;
301276 }
302277
303278 return r ;
@@ -327,29 +302,24 @@ class ImagesErrorImpl extends Error implements ImagesError {
327302
328303async function throwErrorIfErrorResponse (
329304 operation : string ,
330- response : Response ,
331- span : Span
305+ response : Response
332306) : Promise < void > {
333307 const statusHeader = response . headers . get ( 'cf-images-binding' ) || '' ;
334308
335309 const match = / e r r = ( \d + ) / . exec ( statusHeader ) ;
336310
337311 if ( match && match [ 1 ] ) {
338- const errorMessage = await response . text ( ) ;
339- span . setAttribute ( 'cloudflare.images.error.code' , match [ 1 ] ) ;
340- span . setAttribute ( 'error.type' , errorMessage ) ;
341312 throw new ImagesErrorImpl (
342- `IMAGES_${ operation } _${ errorMessage } ` . trim ( ) ,
313+ `IMAGES_${ operation } _${ await response . text ( ) } ` . trim ( ) ,
343314 Number . parseInt ( match [ 1 ] )
344315 ) ;
345316 }
346317
347318 if ( response . status > 399 ) {
348- const errorMessage = await response . text ( ) ;
349- span . setAttribute ( 'cloudflare.images.error.code' , '9523' ) ;
350- span . setAttribute ( 'error.type' , errorMessage ) ;
351319 throw new ImagesErrorImpl (
352- `Unexpected error response ${ response . status } : ${ errorMessage . trim ( ) } ` ,
320+ `Unexpected error response ${ response . status } : ${ (
321+ await response . text ( )
322+ ) . trim ( ) } `,
353323 9523
354324 ) ;
355325 }
0 commit comments