import { AND , AND_VERBOSE , isLogicOperator , OR , OR_VERBOSE , ReservedChars , ComparisonNode , ExpressionNode , isComparisonNode , isLogicNode , LogicNode , SelectorNode , ValueNode , } from "@rsql/ast" ; function escapeQuotes ( value , quote ) { let escapedValue = value ; let previousPosition = 0 ; let currentPosition = value . indexOf ( quote ) ; while ( currentPosition !== - 1 ) { let escaped = false ; for ( let scanPosition = currentPosition - 1 ; escapedValue [ scanPosition ] === "\\" && scanPosition > previousPosition ; scanPosition -- ) { escaped = ! escaped ; } if ( ! escaped ) { escapedValue = escapedValue . slice ( 0 , currentPosition - 1 ) + "\\" + escapedValue . slice ( currentPosition ) ; } previousPosition = currentPosition ; currentPosition = value . indexOf ( quote , previousPosition + 1 ) ; } return escapedValue ; } function escapeValue ( value , quote = '"' ) { if ( value === "" ) { return quote + quote ; } if ( ReservedChars . some ( ( reservedChar ) => value . includes ( reservedChar ) ) ) { return `${ quote }${ escapeQuotes ( value , quote ) }${ quote }` ; } return value ; } function emitSelector ( node ) { return node . selector ; } function emitValue ( node , quote = '"' ) { return Array . isArray ( node . value ) ? `(${ node . value . map ( ( value ) => escapeValue ( value , quote ) ) . join ( "," ) })` : escapeValue ( node . value , quote ) ; } function emitComparison ( node ) { return `${ emitSelector ( node . left ) }${ node . operator }${ emitValue ( node . right ) }` ; } function emitLogic ( node ) { let left = emit ( node . left ) ; let right = emit ( node . right ) ; if ( isLogicOperator ( node . operator , AND ) ) { if ( isLogicNode ( node . left , OR ) ) { left = `(${ left })` ; } if ( isLogicNode ( node . right , OR ) ) { right = `(${ right })` ; } } const operator = node . operator === AND_VERBOSE || node . operator === OR_VERBOSE ? ` ${ node . operator } ` : node . operator ; return `${ left }${ operator }${ right }` ; } function emit ( expression ) { if ( isComparisonNode ( expression ) ) { return emitComparison ( expression ) ; } else if ( isLogicNode ( expression ) ) { return emitLogic ( expression ) ; } throw new TypeError ( `The "expression" has to be a valid "ExpressionNode", ${ String ( expression ) } passed.` ) ; } export { emit } ;