@@ -47,13 +47,12 @@ const QUICKBOOKS_FILE_TYPES: Record<string, readonly string[]> = {
4747 ods : [ 'application/vnd.oasis.opendocument.spreadsheet' ] ,
4848 pdf : [ 'application/pdf' ] ,
4949 png : [ 'image/png' ] ,
50- rtf : [ 'application/rtf' , ' text/rtf'] ,
50+ rtf : [ 'text/rtf' ] ,
5151 tif : [ 'image/tiff' ] ,
52- tiff : [ 'image/tiff' ] ,
5352 txt : [ 'text/plain' ] ,
5453 xls : [ 'application/vnd.ms-excel' ] ,
5554 xlsx : [ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ] ,
56- xml : [ 'application/xml' , ' text/xml'] ,
55+ xml : [ 'text/xml' ] ,
5756}
5857
5958export function getQuickBooksDocumentTransaction ( type : QuickBooksDocumentTransactionType ) {
@@ -79,15 +78,17 @@ export function validateQuickBooksRecipient(recipient?: string): string | undefi
7978}
8079
8180export function sanitizeQuickBooksFileName ( value : string | undefined , fallback : string ) : string {
82- const raw = value ?. trim ( ) || fallback
83- const leaf = raw . split ( / [ \\ / ] / ) . pop ( ) || fallback
84- const sanitized = leaf
85- . replace ( / [ \u0000 - \u001f \u007f ] / g, '' )
86- . replace ( / [ ^ \w . ( ) - ] / g, '_' )
87- . trim ( )
88- const bounded = sanitized . slice ( 0 , 180 )
89- if ( ! bounded || bounded === '.' || bounded === '..' ) return fallback
90- return bounded
81+ const sanitize = ( candidate : string ) : string | undefined => {
82+ const leaf = candidate . trim ( ) . split ( / [ \\ / ] / ) . pop ( ) ?? ''
83+ const bounded = leaf
84+ . replace ( / [ \u0000 - \u001f \u007f ] / g, '' )
85+ . replace ( / [ ^ \w . ( ) - ] / g, '_' )
86+ . trim ( )
87+ . slice ( 0 , 180 )
88+ return bounded && bounded !== '.' && bounded !== '..' ? bounded : undefined
89+ }
90+
91+ return ( value ? sanitize ( value ) : undefined ) ?? sanitize ( fallback ) ?? 'quickbooks-file'
9192}
9293
9394export function validateQuickBooksAttachmentFileType ( fileName : string , mimeType : string ) : string {
@@ -123,6 +124,13 @@ export async function parseQuickBooksAttachableResponse(
123124 response ,
124125 'QuickBooks Attachable response'
125126 )
127+ const nestedFault = data . AttachableResponse ?. find ( ( entry ) => entry . Fault ) ?. Fault
128+ const sanitizedFault = sanitizeQuickBooksFaultData ( { Fault : nestedFault } )
129+ if ( sanitizedFault ) {
130+ throw new Error (
131+ `QuickBooks attachment upload failed: ${ formatQuickBooksFaultDetail ( sanitizedFault ) } `
132+ )
133+ }
126134 const attachment = data . Attachable ?? data . AttachableResponse ?. [ 0 ] ?. Attachable
127135 if ( ! attachment || typeof attachment !== 'object' || Array . isArray ( attachment ) ) {
128136 throw new Error ( 'QuickBooks Attachable response is missing a valid attachment' )
0 commit comments