import type { SqlCommenterQueryInfo } from '@prisma/sqlcommenter'
import { describe, expect, it } from 'vitest'
import { PARAM_PLACEHOLDER } from '../parameterize/parameterize'
import { formatQueryInsight, toBase64Url } from './format'
// Helper to decode base64url for test assertions
function fromBase64Url(data: string): string {
return Buffer.from(data, 'base64url').toString('utf-8')
}
// Helper to parse the prismaQuery value and extract the payload
function parseQueryInsight(insight: string): { prefix: string; payload?: unknown } {
const colonIndex = insight.indexOf(':')
if (colonIndex === -1) {
return { prefix: insight }
}
const prefix = insight.slice(0, colonIndex)
const encoded = insight.slice(colonIndex + 1)
const payload = JSON.parse(fromBase64Url(encoded))
return { prefix, payload }
}
describe('toBase64Url', () => {
it('encodes simple strings without padding', () => {
expect(toBase64Url('hello')).toBe('aGVsbG8')
})
it('encodes JSON objects', () => {
const json = JSON.stringify({ foo: 'bar' })
const encoded = toBase64Url(json)
expect(fromBase64Url(encoded)).toBe(json)
})
it('handles unicode characters', () => {
const text = 'héllo wörld 你好世界'
const encoded = toBase64Url(text)
expect(fromBase64Url(encoded)).toBe(text)
})
it('produces URL-safe output without + / or =', () => {
// This string produces + and / in standard base64
const data = '>>>???'
const encoded = toBase64Url(data)
expect(encoded).not.toContain('+')
expect(encoded).not.toContain('/')
expect(encoded).not.toContain('=')
expect(fromBase64Url(encoded)).toBe(data)
})
})
describe('formatQueryInsight', () => {
describe('raw queries', () => {
it('formats queryRaw without payload', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
action: 'queryRaw',
query: {},
}
expect(formatQueryInsight(queryInfo)).toBe('queryRaw')
})
it('formats executeRaw without payload', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
action: 'executeRaw',
query: {},
}
expect(formatQueryInsight(queryInfo)).toBe('executeRaw')
})
})
describe('single queries', () => {
it('formats findMany query with $scalars to empty object', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
modelName: 'User',
action: 'findMany',
query: { selection: { $scalars: true } },
}
const result = formatQueryInsight(queryInfo)
const parsed = parseQueryInsight(result)
expect(parsed.prefix).toBe('User.findMany')
// After shaping: $scalars only = no select/include needed
expect(parsed.payload).toEqual({})
})
it('formats findUnique query with shaped where clause', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
modelName: 'User',
action: 'findUnique',
query: {
arguments: { where: { id: 123 } },
selection: { $scalars: true },
},
}
const result = formatQueryInsight(queryInfo)
const parsed = parseQueryInsight(result)
expect(parsed.prefix).toBe('User.findUnique')
// After shaping: arguments spread to top level, $scalars only = no select/include
expect(parsed.payload).toEqual({
where: { id: PARAM_PLACEHOLDER },
})
})
it('formats createOne query with shaped data', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
modelName: 'User',
action: 'createOne',
query: {
arguments: {
data: { email: 'test@example.com', name: 'Test User' },
},
selection: { $scalars: true },
},
}
const result = formatQueryInsight(queryInfo)
const parsed = parseQueryInsight(result)
expect(parsed.prefix).toBe('User.createOne')
// After shaping: arguments spread to top level, $scalars only = no select/include
expect(parsed.payload).toEqual({
data: { email: PARAM_PLACEHOLDER, name: PARAM_PLACEHOLDER },
})
})
it('formats query with relation using include', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
modelName: 'User',
action: 'findMany',
query: {
arguments: { where: { active: true } },
selection: {
$scalars: true,
$composites: true,
posts: {
$scalars: true,
$composites: true,
},
},
},
}
const result = formatQueryInsight(queryInfo)
const parsed = parseQueryInsight(result)
expect(parsed.prefix).toBe('User.findMany')
// After shaping: $scalars + relation = include
expect(parsed.payload).toEqual({
where: { active: PARAM_PLACEHOLDER },
include: { posts: true },
})
})
it('formats query with explicit field selection using select', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
modelName: 'User',
action: 'findMany',
query: {
arguments: {},
selection: {
name: true,
email: true,
},
},
}
const result = formatQueryInsight(queryInfo)
const parsed = parseQueryInsight(result)
expect(parsed.prefix).toBe('User.findMany')
// After shaping: explicit fields without $scalars = select
expect(parsed.payload).toEqual({
select: { name: true, email: true },
})
})
})
describe('compacted queries', () => {
it('formats compacted findUnique batch with shaped queries', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'compacted',
modelName: 'User',
action: 'findUnique',
queries: [
{ arguments: { where: { id: 1 } }, selection: { $scalars: true } },
{ arguments: { where: { id: 2 } }, selection: { $scalars: true } },
],
}
const result = formatQueryInsight(queryInfo)
const parsed = parseQueryInsight(result)
expect(parsed.prefix).toBe('User.findUnique')
// After shaping: each query has arguments spread and $scalars removed
expect(parsed.payload).toEqual([{ where: { id: PARAM_PLACEHOLDER } }, { where: { id: PARAM_PLACEHOLDER } }])
})
it('formats compacted batch with relations', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'compacted',
modelName: 'User',
action: 'findUnique',
queries: [
{
arguments: { where: { id: 1 } },
selection: { $scalars: true, posts: { $scalars: true, $composites: true } },
},
{
arguments: { where: { id: 2 } },
selection: { $scalars: true, posts: { $scalars: true, $composites: true } },
},
],
}
const result = formatQueryInsight(queryInfo)
const parsed = parseQueryInsight(result)
expect(parsed.prefix).toBe('User.findUnique')
expect(parsed.payload).toEqual([
{ where: { id: PARAM_PLACEHOLDER }, include: { posts: true } },
{ where: { id: PARAM_PLACEHOLDER }, include: { posts: true } },
])
})
})
describe('edge cases', () => {
it('handles empty query object', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
modelName: 'User',
action: 'findMany',
query: {},
}
const result = formatQueryInsight(queryInfo)
expect(result).toMatch(/^User\.findMany:/)
const parsed = parseQueryInsight(result)
expect(parsed.payload).toEqual({})
})
it('handles query with only explicit field selection', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
modelName: 'User',
action: 'findMany',
query: { selection: { id: true, email: true } },
}
const result = formatQueryInsight(queryInfo)
const parsed = parseQueryInsight(result)
expect(parsed.prefix).toBe('User.findMany')
// After shaping: explicit fields = select
expect(parsed.payload).toEqual({ select: { id: true, email: true } })
})
it('handles empty compacted queries array', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'compacted',
modelName: 'User',
action: 'findUnique',
queries: [],
}
const result = formatQueryInsight(queryInfo)
const parsed = parseQueryInsight(result)
expect(parsed.prefix).toBe('User.findUnique')
expect(parsed.payload).toEqual([])
})
it('handles very long queries with explicit field selection', () => {
const manyFields: Record<string, boolean> = {}
for (let i = 0; i < 100; i++) {
manyFields[`field${i}`] = true
}
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
modelName: 'LargeModel',
action: 'findMany',
query: { selection: manyFields },
}
const result = formatQueryInsight(queryInfo)
expect(result).toMatch(/^LargeModel\.findMany:/)
// Should not throw and should produce valid base64url
const parsed = parseQueryInsight(result)
// After shaping: explicit fields = select with all 100 fields
expect(Object.keys((parsed.payload as Record<string, unknown>).select as object).length).toBe(100)
})
it('handles special characters in values', () => {
const specialValue = 'test\'value"with<special>chars&more'
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
modelName: 'User',
action: 'findFirst',
query: {
arguments: { where: { name: specialValue } },
selection: { $scalars: true },
},
}
const result = formatQueryInsight(queryInfo)
// Should not contain the special value
expect(result).not.toContain(specialValue)
// Should still be valid
expect(() => parseQueryInsight(result)).not.toThrow()
})
it('handles nested relations with mixed select/include', () => {
const queryInfo: SqlCommenterQueryInfo = {
type: 'single',
modelName: 'User',
action: 'findMany',
query: {
arguments: { where: { active: true } },
selection: {
name: true,
posts: {
arguments: { take: 10 },
selection: {
$scalars: true,
$composites: true,
comments: {
arguments: {},
selection: {
$scalars: true,
$composites: true,
},
},
},
},
},
},
}
const result = formatQueryInsight(queryInfo)
const parsed = parseQueryInsight(result)
expect(parsed.prefix).toBe('User.findMany')
// After shaping: top level uses select (no $scalars), posts uses include ($scalars)
expect(parsed.payload).toEqual({
where: { active: PARAM_PLACEHOLDER },
select: {
name: true,
posts: {
take: 10, // take is preserved as structural pagination value
include: {
comments: true,
},
},
},
})
})
})
})