Files
Compass/backend/shared/src/supabase/sql-builder.ts
Martin Braquet ba9b3cfb06 Add pretty formatting (#29)
* Test

* Add pretty formatting

* Fix Tests

* Fix Tests

* Fix Tests

* Fix

* Add pretty formatting fix

* Fix

* Test

* Fix tests

* Clean typeckech

* Add prettier check

* Fix api tsconfig

* Fix api tsconfig

* Fix tsconfig

* Fix

* Fix

* Prettier
2026-02-20 17:32:27 +01:00

121 lines
3.2 KiB
TypeScript

import {buildArray} from 'common/util/array'
import {last} from 'lodash'
import {pgp} from './init'
export type SqlBuilder = {
with: string[]
select: string[]
from: string | undefined
join: string[]
leftJoin: string[]
where: string[]
orderBy: string[]
groupBy: string[]
limit: number | undefined
offset: number | undefined
}
export type SqlParts = {
with?: string
select?: string
from?: string
join?: string
leftJoin?: string
groupBy?: string
where?: string
orderBy?: string
limit?: number
offset?: number
}
type Args = (Args | SqlParts | SqlBuilder | undefined | false | 0 | '')[]
export function buildSql(...parts: Args): SqlBuilder {
const definedParts = buildArray(parts)
return {
with: definedParts.flatMap((part) => part.with || []),
select: definedParts.flatMap((part) => part.select || []),
from: last(definedParts.filter((part) => part.from))?.from,
join: definedParts.flatMap((part) => part.join || []),
leftJoin: definedParts.flatMap((part) => part.leftJoin || []),
where: definedParts.flatMap((part) => part.where || []),
orderBy: definedParts.flatMap((part) => part.orderBy || []),
groupBy: definedParts.flatMap((part) => part.groupBy || []),
limit: last(definedParts.filter((part) => part.limit))?.limit,
offset: last(definedParts.filter((part) => part.offset))?.offset,
}
}
export function withClause(clause: string, formatValues?: any) {
const formattedWith = pgp.as.format(clause, formatValues)
return buildSql({with: formattedWith})
}
export function select(clause: string) {
return buildSql({select: clause})
}
export function from(clause: string, formatValues?: any) {
const from = pgp.as.format(clause, formatValues)
return buildSql({from})
}
export function join(clause: string, formatValues?: any) {
const join = pgp.as.format(clause, formatValues)
return buildSql({join})
}
export function leftJoin(clause: string, formatValues?: any) {
const leftJoin = pgp.as.format(clause, formatValues)
return buildSql({leftJoin})
}
export function groupBy(clause: string) {
return buildSql({groupBy: clause})
}
export function where(clause: string, formatValues?: any) {
const where = pgp.as.format(clause, formatValues)
return buildSql({where})
}
export function orderBy(clause: string, formatValues?: any) {
const orderBy = pgp.as.format(clause, formatValues)
return buildSql({orderBy})
}
export function limit(limit: number, offset?: number) {
return buildSql({limit, offset})
}
export function renderSql(...args: Args) {
const builder = buildSql(...args)
const {
with: withClause,
select,
from,
join,
where,
orderBy,
limit,
offset,
leftJoin,
groupBy,
} = builder
return buildArray(
withClause.length && `with ${withClause.join(', ')}`,
select.length && `select ${select.join(', ')}`,
from && `from ${from}`,
join.length && `join ${join.join(' join ')}`,
leftJoin.length && `left join ${leftJoin.join(' left join ')}`,
where.length && `where ${where.map((clause) => `(${clause})`).join(' and ')}`,
groupBy.length && `group by ${groupBy.join(', ')}`,
orderBy.length && `order by ${orderBy.join(', ')}`,
limit && `limit ${limit}`,
limit && offset && `offset ${offset}`,
).join('\n')
}