Feat: Allow dynamic database binding via request body

This commit is contained in:
2025-09-24 15:07:19 -07:00
parent 6ed213ec41
commit 3359bf839d

View File

@@ -11,14 +11,15 @@ export default {
if (!request.headers.get('content-type')?.includes('application/json')) return new Response(JSON.stringify({ error: 'Request must be application/json' }), { status: 400, headers }); if (!request.headers.get('content-type')?.includes('application/json')) return new Response(JSON.stringify({ error: 'Request must be application/json' }), { status: 400, headers });
try { try {
const { query, params = [] } = await request.json(); const { query, params = [], binding } = await request.json();
// Basic query validation and security checks. // Validate binding, query, and permissions.
if (!binding || !env[binding]) return new Response(JSON.stringify({ error: 'Invalid or missing binding provided.' }), { status: 400, headers });
if (!query || typeof query !== 'string' || query.trim().includes(';')) return new Response(JSON.stringify({ error: 'Invalid or forbidden query provided.' }), { status: 400, headers }); if (!query || typeof query !== 'string' || query.trim().includes(';')) return new Response(JSON.stringify({ error: 'Invalid or forbidden query provided.' }), { status: 400, headers });
if (!['select', 'insert', 'explain'].some(verb => query.trim().toLowerCase().startsWith(verb))) return new Response(JSON.stringify({ error: 'Forbidden: Only SELECT, INSERT, and EXPLAIN are permitted.' }), { status: 403, headers }); if (!/^(select|insert|explain)\b/i.test(query.trim())) return new Response(JSON.stringify({ error: 'Forbidden: Only SELECT, INSERT, and EXPLAIN are permitted.' }), { status: 403, headers });
// Execute the prepared statement against D1. // Execute the prepared statement against the specified D1 binding.
const result = await env.D1_SUNE.prepare(query).bind(...params).all(); const result = await env[binding].prepare(query).bind(...params).all();
// Return results with correct content-type. // Return results with correct content-type.
return new Response(JSON.stringify(result, null, 2), { headers: { ...headers, 'Content-Type': 'application/json' } }); return new Response(JSON.stringify(result, null, 2), { headers: { ...headers, 'Content-Type': 'application/json' } });