Skip to main content
Glama
config.tsβ€’9.23 kB
/** * Storage Configuration Module * * Defines the configuration schemas for the storage system using Zod for * runtime validation and type safety. Supports multiple backend types * with different configuration requirements. * * The storage system uses a dual-backend architecture: * - Cache Backend: For fast, ephemeral storage * - Database Backend: For persistent, reliable storage * * Supported backends: * - In-Memory: Fast local storage for development/testing * - Redis: Distributed cache for production use * - SQLite: Lightweight file-based database * - PostgreSQL: Full-featured relational database (planned) * * @module storage/config */ import { z } from 'zod'; /** * Base Backend Configuration Schema * * Common configuration options shared by all backend types. * These options control connection pooling and timeout behavior. */ const BaseBackendSchema = z.object({ /** Maximum number of concurrent connections to the backend */ maxConnections: z.number().int().positive().optional().describe('Maximum connections'), /** Time in milliseconds before an idle connection is closed */ idleTimeoutMillis: z .number() .int() .positive() .optional() .describe('Idle timeout in milliseconds'), /** Time in milliseconds to wait for a connection to be established */ connectionTimeoutMillis: z .number() .int() .positive() .optional() .describe('Connection timeout in milliseconds'), /** Backend-specific options that vary by implementation */ options: z.record(z.any()).optional().describe('Backend-specific options'), }); /** * In-Memory Backend Configuration * * Simple in-memory storage for development and testing. * Data is lost when the process exits. * * @example * ```typescript * const config: InMemoryBackendConfig = { * type: 'in-memory', * maxConnections: 1, * options: { maxSize: '100mb' } * }; * ``` */ const InMemoryBackendSchema = BaseBackendSchema.extend({ type: z.literal('in-memory'), }).strict(); export type InMemoryBackendConfig = z.infer<typeof InMemoryBackendSchema>; /** * Redis Backend Configuration * * Configuration for Redis-based cache backend. * Supports both direct connection parameters and connection URLs. * * @example * ```typescript * // Using connection URL * const config: RedisBackendConfig = { * type: 'redis', * url: 'redis://user:pass@localhost:6379/0' * }; * * // Using individual parameters * const config: RedisBackendConfig = { * type: 'redis', * host: 'localhost', * port: 6379, * password: 'secret', * database: 0 * }; * ``` */ const RedisBackendSchema = BaseBackendSchema.extend({ type: z.literal('redis'), /** Redis connection URL (redis://...) - overrides individual params if provided */ url: z.string().optional().describe('Redis connection URL (redis://...)'), /** Redis server hostname */ host: z.string().optional().describe('Redis host'), /** Redis server port (default: 6379) */ port: z.number().int().positive().optional().describe('Redis port'), /** Redis authentication username */ username: z.string().optional().describe('Redis username'), /** Redis authentication password */ password: z.string().optional().describe('Redis password'), /** Redis database number (0-15, default: 0) */ database: z.number().int().nonnegative().optional().describe('Redis database number'), }).strict(); export type RedisBackendConfig = z.infer<typeof RedisBackendSchema>; /** * SQLite Backend Configuration * * Configuration for SQLite file-based database backend. * Supports automatic path resolution if path is not provided. * * @example * ```typescript * const config: SqliteBackendConfig = { * type: 'sqlite', * path: './data', // Directory for database file * database: 'myapp.db', // Database filename * connectionTimeoutMillis: 5000 * }; * ``` */ const SqliteBackendSchema = BaseBackendSchema.extend({ type: z.literal('sqlite'), /** * SQLite database file path. * If not provided, will auto-detect using the path resolver. */ path: z .string() .optional() .describe( 'SQLite database file path (optional, will auto-detect using path resolver if not provided)' ), /** Database filename (default: cipher.db) */ database: z.string().optional().describe('Database filename (default: cipher.db)'), }).strict(); export type SqliteBackendConfig = z.infer<typeof SqliteBackendSchema>; /** * PostgreSQL Backend Configuration * * Configuration for PostgreSQL database backend. * Supports both connection URL and individual connection parameters. * * @example * ```typescript * // Using connection URL * const config: PostgresBackendConfig = { * type: 'postgres', * url: 'postgresql://user:password@localhost:5432/mydb' * }; * * // Using individual parameters * const config: PostgresBackendConfig = { * type: 'postgres', * host: 'localhost', * port: 5432, * database: 'mydb', * user: 'postgres', * password: 'secret' * }; * ``` */ const PostgresBackendSchema = BaseBackendSchema.extend({ type: z.literal('postgres'), /** PostgreSQL connection URL (postgresql://...) - overrides individual params if provided */ url: z.string().optional().describe('PostgreSQL connection URL (postgresql://...)'), /** PostgreSQL server hostname */ host: z.string().optional().describe('PostgreSQL host'), /** PostgreSQL server port (default: 5432) */ port: z.number().int().positive().optional().describe('PostgreSQL port'), /** Database name */ database: z.string().optional().describe('Database name'), /** Username for authentication */ user: z.string().optional().describe('Username'), /** Password for authentication */ password: z.string().optional().describe('Password'), /** Enable SSL connection (default: false) */ ssl: z.boolean().optional().describe('Enable SSL connection'), /** Connection pool settings */ pool: z .object({ /** Minimum number of connections in pool */ min: z.number().int().nonnegative().optional().describe('Minimum pool size'), /** Maximum number of connections in pool */ max: z.number().int().positive().optional().describe('Maximum pool size'), /** Connection idle timeout in ms */ idleTimeoutMillis: z.number().int().positive().optional().describe('Connection idle timeout'), /** Connection acquire timeout in ms */ acquireTimeoutMillis: z .number() .int() .positive() .optional() .describe('Connection acquire timeout'), }) .optional() .describe('Connection pool settings'), }).strict(); export type PostgresBackendConfig = z.infer<typeof PostgresBackendSchema>; /** * Backend Configuration Union Schema * * Discriminated union of all supported backend configurations. * Uses the 'type' field to determine which configuration schema to apply. * * Includes custom validation to ensure Redis backends have required connection info. */ const BackendConfigSchema = z .discriminatedUnion( 'type', [InMemoryBackendSchema, RedisBackendSchema, SqliteBackendSchema, PostgresBackendSchema], { errorMap: (issue, ctx) => { if (issue.code === z.ZodIssueCode.invalid_union_discriminator) { return { message: `Invalid backend type. Expected 'in-memory', 'redis', 'sqlite', or 'postgres'.`, }; } return { message: ctx.defaultError }; }, } ) .describe('Backend configuration for storage system') .superRefine((data, ctx) => { // Validate Redis backend requirements if (data.type === 'redis') { // Redis requires either a connection URL or a host if (!data.url && !data.host) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Redis backend requires either 'url' or 'host' to be specified", path: ['url'], }); } } // Validate PostgreSQL backend requirements if (data.type === 'postgres') { // PostgreSQL requires either a connection URL or host + database if (!data.url && (!data.host || !data.database)) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "PostgreSQL backend requires either 'url' or both 'host' and 'database' to be specified", path: ['url'], }); } } }); export type BackendConfig = z.infer<typeof BackendConfigSchema>; /** * Storage System Configuration Schema * * Top-level configuration for the dual-backend storage system. * Requires configuration for both cache and database backends. * * @example * ```typescript * const storageConfig: StorageConfig = { * cache: { * type: 'redis', * host: 'localhost', * port: 6379 * }, * database: { * type: 'sqlite', * path: './data', * database: 'app.db' * } * }; * ``` */ export const StorageSchema = z .object({ /** Cache backend for fast, ephemeral storage (Redis, In-Memory) */ cache: BackendConfigSchema.describe('Cache backend configuration (fast, ephemeral)'), /** Database backend for persistent, reliable storage (SQLite, PostgreSQL) */ database: BackendConfigSchema.describe('Database backend configuration (persistent, reliable)'), }) .strict() .describe('Storage configuration with cache and database backends'); export type StorageConfig = z.infer<typeof StorageSchema>;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/campfirein/cipher'

If you have feedback or need assistance with the MCP directory API, please join our Discord server