kumarabhirup 039cbe6a43
feat: async I/O, tags field type, rich chat messages, deploy verification
- Convert sync filesystem and DuckDB operations to async across API routes,
  workspace lib, and active-runs to prevent event loop blocking during tree
  discovery, object lookups, and database queries
- Add "tags" field type for free-form string arrays with parse-tags utility,
  TagsBadges/TagsInput UI components, filter operators, and CRM skill docs
- Preserve rich text formatting (bold, italic, code, @mentions) in user chat
  messages by sending HTML alongside plain text through the transport layer
- Detect empty-stream errors, improve agent error emission, and add file
  mutation queues for concurrent write safety in active-runs
- Add pre-publish standalone node_modules verification in deploy script
  checking serverExternalPackages are present
- Extract syncManagedSkills and discoverWorkspaceDirs for multi-workspace
  skill syncing, add ensureSeedAssets for runtime app dir
- Bump version 2.1.1 → 2.1.4
2026-03-08 19:53:18 -07:00

44 lines
1.0 KiB
TypeScript

import { duckdbQueryAsync } from "@/lib/workspace";
export const dynamic = "force-dynamic";
export const runtime = "nodejs";
export async function POST(req: Request) {
let body: { sql?: string };
try {
body = await req.json();
} catch {
return Response.json(
{ error: "Invalid JSON body" },
{ status: 400 },
);
}
const { sql } = body;
if (!sql || typeof sql !== "string") {
return Response.json(
{ error: "Missing 'sql' field in request body" },
{ status: 400 },
);
}
// Basic SQL safety: reject obviously dangerous statements
const upper = sql.toUpperCase().trim();
if (
upper.startsWith("DROP") ||
upper.startsWith("DELETE") ||
upper.startsWith("INSERT") ||
upper.startsWith("UPDATE") ||
upper.startsWith("ALTER") ||
upper.startsWith("CREATE")
) {
return Response.json(
{ error: "Only SELECT queries are allowed" },
{ status: 403 },
);
}
const rows = await duckdbQueryAsync(sql);
return Response.json({ rows });
}