| 26 | * @param query The query string to parse e.g. "todos where completed = false, text like 'The' limit:10 order: created_at desc" |
| 27 | */ |
| 28 | export function parseQuery(queryText: string) { |
| 29 | const word = letter().pipe( |
| 30 | many(), |
| 31 | map((chars) => chars.join('')) |
| 32 | ); |
| 33 | // const bool = pipe(or(string('true'), string('false')), map((str) => str === 'true')); |
| 34 | const bool = anyStringOf('true', 'false').pipe(map((str) => str === 'true')); |
| 35 | const value = bool.pipe( |
| 36 | or(float(), word.pipe(between(string("'"), string("'")))) |
| 37 | ); |
| 38 | const operators = anyCharOf('=><'); |
| 39 | const filter = word.pipe( |
| 40 | thenq(whitespace()), |
| 41 | then(operators), |
| 42 | thenq(whitespace()), |
| 43 | // @ts-expect-error |
| 44 | then(value), |
| 45 | flatten() |
| 46 | ); |
| 47 | const whereStatement = string('where').pipe( |
| 48 | thenq(whitespace()), |
| 49 | then(filter.pipe(manySepBy(string(' and ')))), |
| 50 | map(([, filters]) => filters) |
| 51 | ); |
| 52 | const query = word.pipe( |
| 53 | thenq(whitespace()), |
| 54 | then( |
| 55 | whereStatement.pipe( |
| 56 | maybe(), |
| 57 | map((filters) => ({ where: filters })) |
| 58 | ) |
| 59 | ) |
| 60 | ); |
| 61 | return query.parse(queryText); |
| 62 | } |