@@ -41,10 +41,10 @@ import type { StitchToolClientSpec } from './spec/client.js';
4141import {
4242 SUPPORTED_MIME_TYPES ,
4343 type SupportedExtension ,
44- type UploadImageInput ,
45- type UploadImageResult ,
46- type UploadImageErrorCode ,
47- type UploadImageSpec ,
44+ type UploadInput ,
45+ type UploadResult ,
46+ type UploadErrorCode ,
47+ type UploadSpec ,
4848} from './spec/upload.js' ;
4949import { Screen } from '../generated/src/screen.js' ;
5050
@@ -53,17 +53,25 @@ function buildBatchCreateScreensBody(
5353 projectId : string ,
5454 fileContentBase64 : string ,
5555 mimeType : string ,
56- input : UploadImageInput ,
56+ input : UploadInput ,
5757) {
58+ const fileObj = {
59+ fileContentBase64,
60+ mimeType,
61+ } ;
62+
63+ const isHtml = mimeType === 'text/html' ;
5864 const screen : Record < string , unknown > = {
59- screenshot : {
60- fileContentBase64,
61- mimeType,
62- } ,
63- screenType : 'IMAGE' ,
65+ screenType : isHtml ? 'DOCUMENT' : 'IMAGE' ,
6466 isCreatedByClient : true ,
6567 } ;
6668
69+ if ( isHtml ) {
70+ screen [ 'htmlCode' ] = fileObj ;
71+ } else {
72+ screen [ 'screenshot' ] = fileObj ;
73+ }
74+
6775 if ( input . title ) {
6876 screen [ 'title' ] = input . title ;
6977 }
@@ -76,16 +84,14 @@ function buildBatchCreateScreensBody(
7684}
7785
7886/**
79- * Handler for uploadImage — implements UploadImageSpec.
80- *
81- * Never throws. All failures are returned as UploadImageResult with a typed
82- * error code. The caller (Project.uploadImage) surfaces failures as StitchError.
87+ * Handler for the upload capability — implements UploadSpec.
88+ * Never throws. All failures return an UploadResult value with a classified error code.
8389 */
84- export class UploadImageHandler implements UploadImageSpec {
90+ export class UploadHandler implements UploadSpec {
8591 constructor ( private readonly client : StitchToolClientSpec ) { }
8692
87- async execute ( projectId : string , input : UploadImageInput ) : Promise < UploadImageResult > {
88- // ── Step 1: Validate extension → typed error code ────────────────────────
93+ async execute ( projectId : string , input : UploadInput ) : Promise < UploadResult > {
94+ // ── Step 1: Validate extension ─────────────────── ────────────────────────
8995 const ext = path . extname ( input . filePath ) . toLowerCase ( ) ;
9096 const mimeType = SUPPORTED_MIME_TYPES [ ext as SupportedExtension ] ;
9197 if ( ! mimeType ) {
@@ -117,12 +123,10 @@ export class UploadImageHandler implements UploadImageSpec {
117123 body ,
118124 ) ;
119125
120- // ── Step 3: Project the response into Screen[] ───────────────────────
121- // BatchCreateScreens returns { results: [{ screen: { ... } }] }
126+ // ── Step 3: Project the response into Screen[] ─────────────────────────
122127 const results : Array < { screen : any } > = raw ?. results ?? [ ] ;
123128 const screens : Screen [ ] = results . map ( ( r ) => {
124129 const screenData = { ...r . screen , projectId } ;
125- // If API didn't return an ID but returned a file name, extract ID from it
126130 if ( ! screenData . id && screenData . screenshot ?. name ) {
127131 const parts = screenData . screenshot . name . split ( '/files/' ) ;
128132 if ( parts . length === 2 ) {
@@ -132,7 +136,6 @@ export class UploadImageHandler implements UploadImageSpec {
132136 return new Screen ( this . client as any , screenData ) ;
133137 } ) ;
134138
135-
136139 return { success : true , screens } ;
137140 } catch ( err ) {
138141 if ( err && typeof err === 'object' && 'code' in err && err . code === 'ENOENT' ) {
@@ -146,7 +149,7 @@ export class UploadImageHandler implements UploadImageSpec {
146149 } ;
147150 }
148151 const msg = err instanceof Error ? err . message : String ( err ) ;
149- const code : UploadImageErrorCode =
152+ const code : UploadErrorCode =
150153 msg . includes ( '401' ) || msg . includes ( '403' ) || msg . toLowerCase ( ) . includes ( 'auth' )
151154 ? 'AUTH_FAILED'
152155 : 'UPLOAD_FAILED' ;
@@ -158,3 +161,5 @@ export class UploadImageHandler implements UploadImageSpec {
158161 }
159162 }
160163}
164+
165+
0 commit comments