fix: resolve all TypeScript build errors across modules

- Change sql.unsafe() param arrays from unknown[] to any[] (9 modules)
- Exclude sw.ts and demo-sync.ts from tsconfig (separate build targets)
- Add type stub for @mkkellogg/gaussian-splats-3d (CDN-loaded)
- Rename private title → designTitle in folk-swag-designer (HTMLElement conflict)
- Fix Hono context typing and instanceof cast in splat module

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-02-23 19:42:44 -08:00
parent f6bb47bb8b
commit af17153a41
13 changed files with 40 additions and 31 deletions

View File

@ -138,7 +138,7 @@ routes.get("/api/events", async (c) => {
const { start, end, source, search, rTool, rEntityId, upcoming } = c.req.query();
let where = "WHERE 1=1";
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
if (start) { where += ` AND e.start_time >= $${idx}`; params.push(start); idx++; }
@ -211,7 +211,7 @@ routes.patch("/api/events/:id", async (c) => {
const body = await c.req.json();
const fields: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
const allowed = ["title", "description", "start_time", "end_time", "all_day", "timezone",
"status", "visibility", "location_name", "is_virtual", "virtual_url"];
@ -248,7 +248,7 @@ routes.delete("/api/events/:id", async (c) => {
routes.get("/api/sources", async (c) => {
const { is_active, is_visible, source_type } = c.req.query();
let where = "WHERE 1=1";
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
if (is_active !== undefined) { where += ` AND is_active = $${idx}`; params.push(is_active === "true"); idx++; }
@ -279,7 +279,7 @@ routes.post("/api/sources", async (c) => {
routes.get("/api/locations", async (c) => {
const { granularity, parent, search, root } = c.req.query();
let where = "WHERE 1=1";
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
if (root === "true") { where += " AND parent_id IS NULL"; }

View File

@ -89,7 +89,7 @@ routes.get("/api/catalog", async (c) => {
const { product_type, capability, tag, source_space, q, limit = "50", offset = "0" } = c.req.query();
const conditions: string[] = ["status = 'active'"];
const params: unknown[] = [];
const params: any[] = [];
let paramIdx = 1;
if (product_type) {
@ -246,7 +246,7 @@ routes.get("/api/orders", async (c) => {
const { status, provider_id, buyer_id, limit = "50", offset = "0" } = c.req.query();
const conditions: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let paramIdx = 1;
if (status) { conditions.push(`o.status = $${paramIdx}`); params.push(status); paramIdx++; }
@ -292,7 +292,7 @@ routes.patch("/api/orders/:id/status", async (c) => {
// Use parameterized query for payment info
let paymentSet = "";
const params: unknown[] = [status, c.req.param("id")];
const params: any[] = [status, c.req.param("id")];
if (status === "paid" && payment_tx) {
paymentSet = `, payment_tx = $3, payment_network = $4`;
params.push(payment_tx, payment_network || null);

View File

@ -34,7 +34,7 @@ async function logStep(
async function updateInstance(instanceId: string, fields: Record<string, unknown>) {
const sets: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
for (const [key, val] of Object.entries(fields)) {
sets.push(`${key} = $${idx}`);

View File

@ -115,7 +115,7 @@ routes.get("/api/mailboxes/:slug/threads", async (c) => {
if (mailbox.length === 0) return c.json({ error: "Mailbox not found" }, 404);
const conditions = ["mailbox_id = $1"];
const params: unknown[] = [mailbox[0].id];
const params: any[] = [mailbox[0].id];
let idx = 2;
if (status) {
@ -164,7 +164,7 @@ routes.patch("/api/threads/:id", async (c) => {
const body = await c.req.json();
const allowed = ["status", "is_read", "is_starred", "tags", "assigned_to"];
const updates: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
for (const key of allowed) {

View File

@ -197,7 +197,7 @@ routes.put("/api/notebooks/:id", async (c) => {
const { title, description, cover_color, is_public } = body;
const fields: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
if (title !== undefined) { fields.push(`title = $${idx}`); params.push(title); idx++; }
@ -233,7 +233,7 @@ routes.delete("/api/notebooks/:id", async (c) => {
routes.get("/api/notes", async (c) => {
const { notebook_id, type, q, limit = "50", offset = "0" } = c.req.query();
const conditions: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
if (notebook_id) { conditions.push(`n.notebook_id = $${idx}`); params.push(notebook_id); idx++; }
@ -324,7 +324,7 @@ routes.put("/api/notes/:id", async (c) => {
const { title, content, type, url, language, is_pinned, sort_order } = body;
const fields: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
if (title !== undefined) { fields.push(`title = $${idx}`); params.push(title); idx++; }

View File

@ -108,7 +108,7 @@ routes.get("/api/providers", async (c) => {
const { capability, substrate, community, lat, lng, radius_km, active, limit = "50", offset = "0" } = c.req.query();
const conditions: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let paramIdx = 1;
if (active !== "false") {
@ -183,7 +183,7 @@ routes.get("/api/providers/match", async (c) => {
const lngNum = parseFloat(lng);
const conditions = ["active = TRUE", "capabilities @> $1"];
const params: unknown[] = [caps, latNum, lngNum];
const params: any[] = [caps, latNum, lngNum];
let paramIdx = 4;
if (substrates) {
@ -274,7 +274,7 @@ routes.put("/api/providers/:id", async (c) => {
const body = await c.req.json();
const fields: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let paramIdx = 1;
const settable = ["name", "description", "capabilities", "substrates", "communities", "wallet", "active"];

View File

@ -253,12 +253,12 @@ routes.post("/api/splats", async (c) => {
await Bun.write(filepath, buffer);
// Insert into DB
const paymentTx = c.get("x402Payment") || null;
const paymentTx = (c as any).get("x402Payment") || null;
const rows = await sql.unsafe(
`INSERT INTO rsplat.splats (slug, title, description, file_path, file_format, file_size_bytes, tags, space_slug, contributor_id, contributor_name, payment_tx)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
RETURNING id, slug, title, description, file_format, file_size_bytes, tags, created_at`,
[slug, title, description, filename, format, buffer.length, tags, spaceSlug, claims.sub, claims.username || null, paymentTx]
[slug, title, description, filename, format, buffer.length, tags, spaceSlug, claims.sub, claims.username || null, paymentTx] as any[]
);
return c.json(rows[0], 201);
@ -301,8 +301,8 @@ routes.post("/api/splats/from-media", async (c) => {
// Collect all files from formdata
const files: File[] = [];
for (const [key, value] of formData.entries()) {
if (key === "files" && value instanceof File) {
files.push(value);
if (key === "files" && (value as unknown) instanceof File) {
files.push(value as unknown as File);
}
}
@ -360,12 +360,12 @@ routes.post("/api/splats/from-media", async (c) => {
}
// Insert splat record (pending processing)
const paymentTx = c.get("x402Payment") || null;
const paymentTx = (c as any).get("x402Payment") || null;
const splatRows = await sql.unsafe(
`INSERT INTO rsplat.splats (slug, title, description, file_path, file_format, file_size_bytes, tags, space_slug, contributor_id, contributor_name, source, processing_status, source_file_count, payment_tx)
VALUES ($1, $2, $3, '', 'ply', 0, $4, $5, $6, $7, 'media', 'pending', $8, $9)
RETURNING id, slug, title, description, file_format, tags, processing_status, source_file_count, created_at`,
[slug, title, description, tags, spaceSlug, claims.sub, claims.username || null, files.length, paymentTx]
[slug, title, description, tags, spaceSlug, claims.sub, claims.username || null, files.length, paymentTx] as any[]
);
const splatId = splatRows[0].id;

View File

@ -9,7 +9,7 @@ class FolkSwagDesigner extends HTMLElement {
private selectedProduct = "sticker";
private imageFile: File | null = null;
private imagePreview = "";
private title = "";
private designTitle = "";
private generating = false;
private artifact: any = null;
private error = "";
@ -40,7 +40,7 @@ class FolkSwagDesigner extends HTMLElement {
const formData = new FormData();
formData.append("image", this.imageFile);
formData.append("product", this.selectedProduct);
formData.append("title", this.title || "Untitled Design");
formData.append("title", this.designTitle || "Untitled Design");
const res = await fetch(`${this.getApiBase()}/api/artifact`, {
method: "POST",
@ -124,7 +124,7 @@ class FolkSwagDesigner extends HTMLElement {
<input type="file" accept="image/*">
</div>
<input class="title-input" type="text" placeholder="Design title" value="${this.esc(this.title)}">
<input class="title-input" type="text" placeholder="Design title" value="${this.esc(this.designTitle)}">
<button class="generate-btn" ${!this.imageFile || this.generating ? 'disabled' : ''}>
${this.generating ? '\u23F3 Generating...' : '\u{1F680} Generate Print-Ready Files'}
@ -172,7 +172,7 @@ class FolkSwagDesigner extends HTMLElement {
});
this.shadow.querySelector(".title-input")?.addEventListener("input", (e) => {
this.title = (e.target as HTMLInputElement).value;
this.designTitle = (e.target as HTMLInputElement).value;
});
this.shadow.querySelector(".generate-btn")?.addEventListener("click", () => this.generate());

View File

@ -94,7 +94,7 @@ routes.put("/api/trips/:id", async (c) => {
const { title, description, start_date, end_date, budget_total, budget_currency, status } = body;
const fields: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
if (title !== undefined) { fields.push(`title = $${idx}`); params.push(title); idx++; }

View File

@ -175,7 +175,7 @@ routes.get("/api/spaces/:slug", async (c) => {
routes.get("/api/proposals", async (c) => {
const { space_slug, status, limit = "50", offset = "0" } = c.req.query();
const conditions: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
if (space_slug) {

View File

@ -168,7 +168,7 @@ routes.patch("/api/tasks/:id", async (c) => {
const { title, description, status, priority, labels, sort_order, assignee_id } = body;
const fields: string[] = [];
const params: unknown[] = [];
const params: any[] = [];
let idx = 1;
if (title !== undefined) { fields.push(`title = $${idx}`); params.push(title); idx++; }

View File

@ -23,6 +23,6 @@
"@shared/*": ["shared/*"]
}
},
"include": ["**/*.ts", "vite.config.ts"],
"exclude": ["node_modules/**/*", "dist/**/*", "src/encryptid/**/*"]
"include": ["**/*.ts", "vite.config.ts", "types/**/*.d.ts"],
"exclude": ["node_modules/**/*", "dist/**/*", "src/encryptid/**/*", "website/sw.ts", "src/lib/demo-sync.ts"]
}

9
types/gaussian-splats-3d.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
declare module "@mkkellogg/gaussian-splats-3d" {
export class Viewer {
constructor(options?: Record<string, any>);
addSplatScene(url: string, options?: Record<string, any>): Promise<void>;
start(): void;
dispose(): void;
}
export default Viewer;
}