mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-05-01 18:28:38 +00:00
refactor(database): move db into typescript
- Implemented githubTokensDb for managing GitHub tokens with CRUD operations. - Created otificationPreferencesDb to handle user notification preferences. - Added projectsDb for project path management and related operations. - Introduced pushSubscriptionsDb for managing browser push subscriptions. - Developed scanStateDb to track the last scanned timestamp. - Established sessionsDb for session management with CRUD functionalities. - Created userDb for user management, including authentication and onboarding. - Implemented apidKeysDb for storing and managing VAPID keys. feat(database): define schema for new database tables - Added SQL schema definitions for users, API keys, user credentials, notification preferences, VAPID keys, push subscriptions, projects, sessions, scan state, and app configuration. - Included necessary indexes for performance optimization. refactor(shared): enhance type definitions and utility functions - Updated shared types and interfaces for improved clarity and consistency. - Added new types for credential management and provider-specific operations. - Refined utility functions for better error handling and message normalization.
This commit is contained in:
@@ -9,6 +9,7 @@ import type {
|
||||
UpsertProviderMcpServerInput,
|
||||
} from '@/shared/types.js';
|
||||
|
||||
//----------------- PROVIDER CONTRACT INTERFACES ------------
|
||||
/**
|
||||
* Main provider contract for CLI and SDK integrations.
|
||||
*
|
||||
@@ -22,9 +23,13 @@ export interface IProvider {
|
||||
readonly sessions: IProviderSessions;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------
|
||||
//----------------- PROVIDER AUTH INTERFACE ------------
|
||||
/**
|
||||
* Auth contract for one provider.
|
||||
*
|
||||
* Implementations should return a complete installation/authentication status
|
||||
* without throwing for normal "not installed" or "not authenticated" states.
|
||||
*/
|
||||
export interface IProviderAuth {
|
||||
/**
|
||||
@@ -33,8 +38,13 @@ export interface IProviderAuth {
|
||||
getStatus(): Promise<ProviderAuthStatus>;
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
//----------------- PROVIDER MCP INTERFACE ------------
|
||||
/**
|
||||
* MCP contract for one provider.
|
||||
*
|
||||
* Implementations must map provider-native MCP config formats to shared
|
||||
* `ProviderMcpServer` records used by routes and frontend state.
|
||||
*/
|
||||
export interface IProviderMcp {
|
||||
listServers(options?: { workspacePath?: string }): Promise<Record<McpScope, ProviderMcpServer[]>>;
|
||||
@@ -45,8 +55,13 @@ export interface IProviderMcp {
|
||||
): Promise<{ removed: boolean; provider: LLMProvider; name: string; scope: McpScope }>;
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
//----------------- PROVIDER SESSION INTERFACE ------------
|
||||
/**
|
||||
* Session/history contract for one provider.
|
||||
*
|
||||
* Implementations normalize provider-specific events and message history into
|
||||
* shared transport shapes consumed by API routes and realtime streams.
|
||||
*/
|
||||
export interface IProviderSessions {
|
||||
normalizeMessage(raw: unknown, sessionId: string | null): NormalizedMessage[];
|
||||
|
||||
@@ -1,18 +1,38 @@
|
||||
// -------------- HTTP API response shapes for the server, shared across modules --------------
|
||||
|
||||
//----------------- HTTP RESPONSE SHAPES ------------
|
||||
/**
|
||||
* Canonical success envelope used by backend APIs that return a structured payload.
|
||||
*
|
||||
* Use this for route handlers that need a stable `success/data` shape so frontend
|
||||
* consumers can parse responses consistently across endpoints.
|
||||
*/
|
||||
export type ApiSuccessShape<TData = unknown> = {
|
||||
success: true;
|
||||
data: TData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic plain-object record used when parsing loosely typed JSON payloads.
|
||||
*
|
||||
* Use this only after runtime shape checks, not as a replacement for validated
|
||||
* domain models.
|
||||
*/
|
||||
export type AnyRecord = Record<string, any>;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
// ---------------------------
|
||||
//----------------- PROVIDER MESSAGE MODEL ------------
|
||||
/**
|
||||
* Providers supported by the unified server runtime.
|
||||
*
|
||||
* Use this as the source of truth whenever a function or payload needs to identify
|
||||
* a specific LLM integration.
|
||||
*/
|
||||
export type LLMProvider = 'claude' | 'codex' | 'gemini' | 'cursor';
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Message/event variants emitted by provider adapters and normalized transports.
|
||||
*
|
||||
* Keep this union in sync with event kinds produced by provider session adapters.
|
||||
*/
|
||||
export type MessageKind =
|
||||
| 'text'
|
||||
| 'tool_use'
|
||||
@@ -30,11 +50,10 @@ export type MessageKind =
|
||||
| 'task_notification';
|
||||
|
||||
/**
|
||||
* Provider-neutral message event emitted over REST and realtime transports.
|
||||
* Provider-neutral message envelope used in REST responses and realtime channels.
|
||||
*
|
||||
* Providers all produce their own native SDK/CLI event shapes, so this type keeps
|
||||
* the common envelope strict while allowing provider-specific details to ride
|
||||
* along as optional properties.
|
||||
* Every provider-specific message must be converted into this shape before being
|
||||
* emitted outside provider-specific modules.
|
||||
*/
|
||||
export type NormalizedMessage = {
|
||||
id: string;
|
||||
@@ -73,21 +92,22 @@ export type NormalizedMessage = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Pagination and provider lookup options for reading persisted session history.
|
||||
* Shared options used to fetch historical provider messages.
|
||||
*
|
||||
* Consumers should pass provider-specific lookup hints (`projectName`, `projectPath`)
|
||||
* only when the selected provider requires them.
|
||||
*/
|
||||
export type FetchHistoryOptions = {
|
||||
/** Claude project folder name. Required by Claude history lookup. */
|
||||
projectName?: string;
|
||||
/** Absolute workspace path. Required by Cursor to compute its chat hash. */
|
||||
projectPath?: string;
|
||||
/** Page size. `null` means all messages. */
|
||||
limit?: number | null;
|
||||
/** Pagination offset from the newest messages. */
|
||||
offset?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provider-neutral history result returned by the unified messages endpoint.
|
||||
* Standardized response payload returned from provider history readers.
|
||||
*
|
||||
* Use this as the contract for APIs that return paginated conversation history.
|
||||
*/
|
||||
export type FetchHistoryResult = {
|
||||
messages: NormalizedMessage[];
|
||||
@@ -98,21 +118,40 @@ export type FetchHistoryResult = {
|
||||
tokenUsage?: unknown;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
// ---------------------------
|
||||
//----------------- SHARED ERROR TYPES ------------
|
||||
/**
|
||||
* Optional metadata used when constructing application-level errors.
|
||||
*
|
||||
* `statusCode` should reflect the HTTP response status, while `code` identifies
|
||||
* the stable machine-readable error category.
|
||||
*/
|
||||
export type AppErrorOptions = {
|
||||
code?: string;
|
||||
statusCode?: number;
|
||||
details?: unknown;
|
||||
};
|
||||
|
||||
// -------------------- MCP related shared types --------------------
|
||||
// ---------------------------
|
||||
//----------------- MCP TYPES ------------
|
||||
/**
|
||||
* Scope where an MCP server definition is stored and resolved.
|
||||
*
|
||||
* `user` is global for a user account, `local` is provider-local, and `project`
|
||||
* is tied to a specific project path.
|
||||
*/
|
||||
export type McpScope = 'user' | 'local' | 'project';
|
||||
|
||||
/**
|
||||
* Transport protocol used by an MCP server definition.
|
||||
*/
|
||||
export type McpTransport = 'stdio' | 'http' | 'sse';
|
||||
|
||||
/**
|
||||
* Provider MCP server descriptor normalized for frontend consumption.
|
||||
* Normalized MCP server model exposed to frontend and route handlers.
|
||||
*
|
||||
* Provider adapters should map provider-native config to this structure before
|
||||
* returning results.
|
||||
*/
|
||||
export type ProviderMcpServer = {
|
||||
provider: LLMProvider;
|
||||
@@ -131,7 +170,10 @@ export type ProviderMcpServer = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Shared payload shape for MCP server create/update operations.
|
||||
* Payload for create/update MCP server operations.
|
||||
*
|
||||
* Routes and services should accept this type, validate it, and then persist it
|
||||
* through provider-specific MCP repositories.
|
||||
*/
|
||||
export type UpsertProviderMcpServerInput = {
|
||||
name: string;
|
||||
@@ -149,18 +191,13 @@ export type UpsertProviderMcpServerInput = {
|
||||
envHttpHeaders?: Record<string, string>;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
// -------------------- Provider auth status types --------------------
|
||||
// ---------------------------
|
||||
//----------------- PROVIDER AUTH TYPES ------------
|
||||
/**
|
||||
* Result of a provider status check (installation + authentication).
|
||||
* Authentication status result returned by provider health checks.
|
||||
*
|
||||
* installed - Whether the provider's CLI/SDK is available
|
||||
* provider - Provider id the status belongs to
|
||||
* authenticated - Whether valid credentials exist
|
||||
* email - User email or auth method identifier
|
||||
* method - Auth method (e.g. 'api_key', 'credentials_file')
|
||||
* [error] - Error message if not installed or not authenticated
|
||||
* This shape is consumed by settings/status endpoints to report installation and
|
||||
* credential state for each provider.
|
||||
*/
|
||||
export type ProviderAuthStatus = {
|
||||
installed: boolean;
|
||||
@@ -170,3 +207,32 @@ export type ProviderAuthStatus = {
|
||||
method: string | null;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
// ---------------------------
|
||||
//----------------- SHARED DATABASE CREDENTIAL TYPES ------------
|
||||
/**
|
||||
* Safe credential view returned by credential listing APIs.
|
||||
*
|
||||
* This intentionally excludes the raw credential secret while still exposing
|
||||
* metadata needed for UI rendering and management operations.
|
||||
*/
|
||||
export type CredentialPublicRow = {
|
||||
id: number;
|
||||
credential_name: string;
|
||||
credential_type: string;
|
||||
description: string | null;
|
||||
created_at: string;
|
||||
is_active: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Result returned after creating a credential record.
|
||||
*
|
||||
* Use this return shape when callers need the created id and display metadata,
|
||||
* but must never receive the stored secret value.
|
||||
*/
|
||||
export type CreateCredentialResult = {
|
||||
id: number | bigint;
|
||||
credentialName: string;
|
||||
credentialType: string;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
@@ -12,6 +11,14 @@ import type {
|
||||
NormalizedMessage,
|
||||
} from '@/shared/types.js';
|
||||
|
||||
//----------------- NORMALIZED MESSAGE HELPER INPUT TYPES ------------
|
||||
/**
|
||||
* Input payload accepted by `createNormalizedMessage`.
|
||||
*
|
||||
* Callers provide provider-specific fields plus the required `kind/provider`
|
||||
* pair; this helper fills missing envelope fields (`id`, `sessionId`,
|
||||
* `timestamp`) in a consistent way.
|
||||
*/
|
||||
type NormalizedMessageInput =
|
||||
{
|
||||
kind: NormalizedMessage['kind'];
|
||||
@@ -21,6 +28,14 @@ type NormalizedMessageInput =
|
||||
timestamp?: string | null;
|
||||
} & Record<string, unknown>;
|
||||
|
||||
// ---------------------------
|
||||
//----------------- HTTP HANDLER UTILITIES ------------
|
||||
/**
|
||||
* Wraps arbitrary data in the standard API success envelope.
|
||||
*
|
||||
* Use this helper in route handlers to keep successful JSON responses consistent
|
||||
* across endpoints.
|
||||
*/
|
||||
export function createApiSuccessResponse<TData>(
|
||||
data: TData,
|
||||
): ApiSuccessShape<TData> {
|
||||
@@ -30,6 +45,12 @@ export function createApiSuccessResponse<TData>(
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an async Express handler into a standard `RequestHandler` and routes
|
||||
* rejected promises to Express error middleware.
|
||||
*
|
||||
* Use this to avoid repeating `try/catch(next)` in every async route.
|
||||
*/
|
||||
export function asyncHandler(
|
||||
handler: (req: Request, res: Response, next: NextFunction) => Promise<unknown>
|
||||
): RequestHandler {
|
||||
@@ -38,7 +59,14 @@ export function asyncHandler(
|
||||
};
|
||||
}
|
||||
|
||||
// --------- Global app error class for consistent error handling across the server ---------
|
||||
// ---------------------------
|
||||
//----------------- SHARED ERROR UTILITIES ------------
|
||||
/**
|
||||
* Shared application error with HTTP status and machine-readable code metadata.
|
||||
*
|
||||
* Throw this from service/route layers when the caller should receive a
|
||||
* controlled error response rather than a generic 500.
|
||||
*/
|
||||
export class AppError extends Error {
|
||||
readonly code: string;
|
||||
readonly statusCode: number;
|
||||
@@ -53,9 +81,8 @@ export class AppError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
||||
// ------------------------ Normalized provider message helpers ------------------------
|
||||
// ---------------------------
|
||||
//----------------- NORMALIZED PROVIDER MESSAGE UTILITIES ------------
|
||||
/**
|
||||
* Generates a stable unique id for normalized provider messages.
|
||||
*/
|
||||
@@ -80,9 +107,8 @@ export function createNormalizedMessage(fields: NormalizedMessageInput): Normali
|
||||
};
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
||||
// ------------------------ The following are mainly for provider MCP runtimes ------------------------
|
||||
// ---------------------------
|
||||
//----------------- MCP CONFIG PARSING UTILITIES ------------
|
||||
/**
|
||||
* Safely narrows an unknown value to a plain object record.
|
||||
*
|
||||
@@ -189,5 +215,3 @@ export const writeJsonConfig = async (filePath: string, data: Record<string, unk
|
||||
await writeFile(filePath, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user