@@ -13,19 +13,19 @@ const SQL_SELECT_REGEX = /^SELECT (.*) FROM (\w+)( WHERE .*)? ORDER BY (["\w,\s]
1313 */
1414export function assertSafeQuery ( sql : string , collection : string ) {
1515 if ( ! sql ) {
16- throw new Error ( 'Invalid query' )
16+ throw new Error ( 'Invalid query: Query cannot be empty ' )
1717 }
1818
1919 const cleanedupQuery = cleanupQuery ( sql )
2020
2121 // Query is invalid if the cleaned up query is not the same as the original query (it contains comments)
2222 if ( cleanedupQuery !== sql ) {
23- throw new Error ( 'Invalid query' )
23+ throw new Error ( 'Invalid query: SQL comments are not allowed ' )
2424 }
2525
2626 const match = sql . match ( SQL_SELECT_REGEX )
2727 if ( ! match ) {
28- throw new Error ( 'Invalid query' )
28+ throw new Error ( 'Invalid query: Query must be a valid SELECT statement with proper syntax ' )
2929 }
3030
3131 const [ _ , select , from , where , orderBy , order , limit , offset ] = match
@@ -38,43 +38,44 @@ export function assertSafeQuery(sql: string, collection: string) {
3838 && ! columns [ 0 ] ?. match ( SQL_COUNT_REGEX )
3939 && ! columns [ 0 ] ?. match ( / ^ " [ a - z _ ] \w + " $ / i)
4040 ) {
41- throw new Error ( ' Invalid query' )
41+ throw new Error ( ` Invalid query: Column ' ${ columns [ 0 ] } ' has invalid format. Expected *, COUNT(), or a quoted column name` )
4242 }
4343 }
4444 else if ( ! columns . every ( column => column . match ( / ^ " [ a - z _ ] \w + " $ / i) ) ) {
45- throw new Error ( 'Invalid query' )
45+ throw new Error ( 'Invalid query: Multiple columns must be properly quoted and alphanumeric ' )
4646 }
4747
4848 // FROM
4949 if ( from !== `_content_${ collection } ` ) {
50- throw new Error ( 'Invalid query' )
50+ const collection = String ( from || '' ) . replace ( / ^ _ c o n t e n t _ / , '' )
51+ throw new Error ( `Invalid query: Collection '${ collection } ' does not exist` )
5152 }
5253
5354 // WHERE
5455 if ( where ) {
5556 if ( ! where . startsWith ( ' WHERE (' ) || ! where . endsWith ( ')' ) ) {
56- throw new Error ( 'Invalid query' )
57+ throw new Error ( 'Invalid query: WHERE clause must be properly enclosed in parentheses ' )
5758 }
5859 const noString = cleanupQuery ( where , { removeString : true } )
5960 if ( noString . match ( SQL_COMMANDS ) ) {
60- throw new Error ( 'Invalid query' )
61+ throw new Error ( 'Invalid query: WHERE clause contains unsafe SQL commands ' )
6162 }
6263 }
6364
6465 // ORDER BY
6566 const _order = ( orderBy + ' ' + order ) . split ( ', ' )
6667 if ( ! _order . every ( column => column . match ( / ^ ( " [ a - z A - Z _ ] + " | [ a - z A - Z _ ] + ) ( A S C | D E S C ) $ / ) ) ) {
67- throw new Error ( 'Invalid query' )
68+ throw new Error ( 'Invalid query: ORDER BY clause must contain valid column names followed by ASC or DESC ' )
6869 }
6970
7071 // LIMIT
7172 if ( limit !== undefined && ! limit . match ( / ^ L I M I T \d + $ / ) ) {
72- throw new Error ( 'Invalid query' )
73+ throw new Error ( 'Invalid query: LIMIT clause must be a positive number ' )
7374 }
7475
7576 // OFFSET
7677 if ( offset !== undefined && ! offset . match ( / ^ O F F S E T \d + $ / ) ) {
77- throw new Error ( 'Invalid query' )
78+ throw new Error ( 'Invalid query: OFFSET clause must be a positive number ' )
7879 }
7980
8081 return true
0 commit comments