UNPKG

@stackmemoryai/stackmemory

Version:

Project-scoped memory for AI coding tools. Durable context across sessions with MCP integration, frames, smart retrieval, Claude Code skills, and automatic hooks.

61 lines (60 loc) 1.73 kB
import { fileURLToPath as __fileURLToPath } from 'url'; import { dirname as __pathDirname } from 'path'; const __filename = __fileURLToPath(import.meta.url); const __dirname = __pathDirname(__filename); class DatabaseAdapter { projectId; config; constructor(projectId, config) { this.projectId = projectId; this.config = config || {}; } // Utility methods generateId() { return crypto.randomUUID(); } sanitizeQuery(query) { console.warn( "sanitizeQuery() is deprecated and unsafe - use parameterized queries" ); return query.replace(/[;'"\\]/g, ""); } buildWhereClause(conditions) { const clauses = Object.entries(conditions).map(([key, value]) => { if (value === null) { return `${key} IS NULL`; } else if (Array.isArray(value)) { return `${key} IN (${value.map(() => "?").join(",")})`; } else { return `${key} = ?`; } }); return clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : ""; } buildOrderByClause(orderBy, direction) { if (!orderBy) return ""; const isSafe = /^[a-zA-Z0-9_.]+$/.test(orderBy); if (!isSafe) { return ""; } const dir = direction === "DESC" ? "DESC" : "ASC"; return ` ORDER BY ${orderBy} ${dir}`; } buildLimitClause(limit, offset) { if (!limit) return ""; let clause = ` LIMIT ${limit}`; if (offset) clause += ` OFFSET ${offset}`; return clause; } } class FeatureAwareDatabaseAdapter extends DatabaseAdapter { async canUseFeature(feature) { const features = this.getFeatures(); return features[feature] || false; } } export { DatabaseAdapter, FeatureAwareDatabaseAdapter }; //# sourceMappingURL=database-adapter.js.map