mirror of
https://github.com/supabase/supabase.git
synced 2026-10-11 20:35:07 +03:00
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import { parse } from 'libpg-query'
|
|
import { NextApiRequest, NextApiResponse } from 'next'
|
|
|
|
const getOperation = async (sql: string) => {
|
|
const ast = await parse(sql)
|
|
const stmt = ast.stmts?.[0]?.stmt
|
|
|
|
if (!stmt) return null
|
|
|
|
if ('SelectStmt' in stmt) return 'SELECT'
|
|
if ('InsertStmt' in stmt) return 'INSERT'
|
|
if ('UpdateStmt' in stmt) return 'UPDATE'
|
|
if ('DeleteStmt' in stmt) return 'DELETE'
|
|
}
|
|
|
|
const getTablesInQuery = async (sql: string) => {
|
|
const ast = await parse(sql)
|
|
const tables: string[] = []
|
|
|
|
function traverse(node: unknown): void {
|
|
if (!node || typeof node !== 'object') return
|
|
const obj = node as Record<string, unknown>
|
|
|
|
if ('RangeVar' in obj) {
|
|
const rv = obj.RangeVar as { relname?: string; schemaname?: string }
|
|
if (rv.relname) tables.push(rv.schemaname ? `${rv.schemaname}.${rv.relname}` : rv.relname)
|
|
}
|
|
|
|
if ('relation' in obj && obj.relation && typeof obj.relation === 'object') {
|
|
const rv = obj.relation as { relname?: string; schemaname?: string }
|
|
if (rv.relname) tables.push(rv.schemaname ? `${rv.schemaname}.${rv.relname}` : rv.relname)
|
|
}
|
|
|
|
for (const value of Object.values(obj)) {
|
|
Array.isArray(value) ? value.forEach(traverse) : traverse(value)
|
|
}
|
|
}
|
|
|
|
traverse(ast)
|
|
return [...new Set(tables)].sort((a, b) => a.localeCompare(b))
|
|
}
|
|
|
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
if (req.method !== 'POST') {
|
|
res.setHeader('Allow', ['POST'])
|
|
return res.status(405).json({ error: `Method ${req.method} Not Allowed` })
|
|
}
|
|
|
|
try {
|
|
const { sql } = req.body
|
|
const tables = await getTablesInQuery(sql)
|
|
const operation = await getOperation(sql)
|
|
return res.status(200).json({ tables, operation })
|
|
} catch (error) {
|
|
return res
|
|
.status(400)
|
|
.json({ error: (error as unknown as { sqlDetails: { message: string } }).sqlDetails.message })
|
|
}
|
|
}
|