@@ -100,6 +100,33 @@ export function buildFromClause(entity: ReportOptions["entity"]): FromClause {
100100 return ` ${ QueryKeywords . FROM } ${ entity } ` as const ;
101101}
102102
103+ function formatGaqlString ( val : string ) : string {
104+ const len = val . length ;
105+ const startsWithSingle = val . startsWith ( "'" ) ;
106+ const endsWithSingle = val . endsWith ( "'" ) ;
107+ const startsWithDouble = val . startsWith ( '"' ) ;
108+ const endsWithDouble = val . endsWith ( '"' ) ;
109+
110+ // Returns the original string if it seems correctly quoted already.
111+ if ( len >= 2 ) {
112+ if ( startsWithSingle && endsWithSingle && ! val . slice ( 1 , - 1 ) . includes ( "'" ) ) {
113+ return val ;
114+ }
115+ if ( startsWithDouble && endsWithDouble && ! val . slice ( 1 , - 1 ) . includes ( '"' ) ) {
116+ return val ;
117+ }
118+ }
119+
120+ // Always use double quotes and escape internal double quotes and backslashes
121+ if ( val . includes ( '"' ) || val . includes ( "\\" ) ) {
122+ const escapedVal = val . replace ( / \\ / g, "\\\\" ) . replace ( / " / g, '\\"' ) ; // Escape backslashes first, then double quotes
123+ return `"${ escapedVal } "` ;
124+ } else {
125+ // No escaping needed, just wrap in double quotes
126+ return `"${ val } "` ;
127+ }
128+ }
129+
103130export function validateConstraintKeyAndValue (
104131 key : ConstraintKey ,
105132 op : ConstraintOperation ,
@@ -116,18 +143,14 @@ export function validateConstraintKeyAndValue(
116143 if ( dateConstants . includes ( val as DateConstant ) ) {
117144 return { op, val } ;
118145 }
119-
120- return {
121- op : "=" ,
122- val : new RegExp ( / ^ ' .* ' $ | ^ " .* " $ / g) . test ( val ) ? val : `"${ val } "` ,
123- } ; // must start and end in either single or double quotation marks
146+ return { op : "=" , val : formatGaqlString ( val ) } ;
124147 }
125148
126149 if ( Array . isArray ( val ) ) {
127150 const stringifiedValue = val
128151 . map ( ( v : number | string ) => {
129152 if ( typeof v === "string" ) {
130- return `" ${ v } "` ;
153+ return formatGaqlString ( v ) ;
131154 } else {
132155 return convertNumericEnumToString ( key , v ) ;
133156 }
0 commit comments