express-model-binding 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BaseAdapter-BjvLQijd.d.mts → BaseAdapter-Dr9a8ZUY.d.mts} +17 -1
- package/dist/{BaseAdapter-BjvLQijd.d.ts → BaseAdapter-Dr9a8ZUY.d.ts} +17 -1
- package/dist/adapters/KnexAdapter.d.mts +1 -1
- package/dist/adapters/KnexAdapter.d.ts +1 -1
- package/dist/adapters/KnexAdapter.js +1 -257
- package/dist/adapters/KnexAdapter.mjs +1 -229
- package/dist/adapters/MongooseAdapter.d.mts +1 -1
- package/dist/adapters/MongooseAdapter.d.ts +1 -1
- package/dist/adapters/MongooseAdapter.js +1 -245
- package/dist/adapters/MongooseAdapter.mjs +1 -225
- package/dist/adapters/PrismaAdapter.d.mts +1 -1
- package/dist/adapters/PrismaAdapter.d.ts +1 -1
- package/dist/adapters/PrismaAdapter.js +1 -247
- package/dist/adapters/PrismaAdapter.mjs +1 -220
- package/dist/adapters/SequelizeAdapter.d.mts +1 -1
- package/dist/adapters/SequelizeAdapter.d.ts +1 -1
- package/dist/adapters/SequelizeAdapter.js +1 -280
- package/dist/adapters/SequelizeAdapter.mjs +1 -260
- package/dist/adapters/TypeORMAdapter.d.mts +1 -1
- package/dist/adapters/TypeORMAdapter.d.ts +1 -1
- package/dist/adapters/TypeORMAdapter.js +1 -294
- package/dist/adapters/TypeORMAdapter.mjs +1 -267
- package/dist/chunk-7I3EYD6K.js +1 -0
- package/dist/chunk-7OR75DD2.mjs +1 -0
- package/dist/chunk-A7LUHNSI.mjs +1 -0
- package/dist/chunk-B3DBSP2J.mjs +1 -0
- package/dist/chunk-CKT6LD2K.js +1 -0
- package/dist/chunk-DBYMXDVA.mjs +1 -0
- package/dist/chunk-EEPSARTF.js +1 -0
- package/dist/chunk-ISSVD3WP.js +1 -0
- package/dist/chunk-LLYCNTZ7.mjs +1 -0
- package/dist/chunk-OKPAWWZN.js +1 -0
- package/dist/chunk-Z6WU7X3A.mjs +1 -0
- package/dist/chunk-ZJ2WW53U.js +1 -0
- package/dist/index.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +1 -1514
- package/dist/index.mjs +1 -1450
- package/package.json +5 -3
- package/dist/adapters/KnexAdapter.js.map +0 -1
- package/dist/adapters/KnexAdapter.mjs.map +0 -1
- package/dist/adapters/MongooseAdapter.js.map +0 -1
- package/dist/adapters/MongooseAdapter.mjs.map +0 -1
- package/dist/adapters/PrismaAdapter.js.map +0 -1
- package/dist/adapters/PrismaAdapter.mjs.map +0 -1
- package/dist/adapters/SequelizeAdapter.js.map +0 -1
- package/dist/adapters/SequelizeAdapter.mjs.map +0 -1
- package/dist/adapters/TypeORMAdapter.js.map +0 -1
- package/dist/adapters/TypeORMAdapter.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors/index.ts","../src/utils/cache.ts","../src/utils/logger.ts","../src/core/ModelBinder.ts","../src/core/BaseAdapter.ts","../src/core/types.ts","../src/utils/validators.ts","../src/adapters/KnexAdapter.ts","../src/adapters/MongooseAdapter.ts","../src/adapters/TypeORMAdapter.ts","../src/adapters/SequelizeAdapter.ts","../src/adapters/PrismaAdapter.ts","../src/middleware/bindModel.ts","../src/utils/transformers.ts"],"sourcesContent":["// Core exports\nexport { ModelBinder } from './core/ModelBinder';\nexport { BaseAdapter } from './core/BaseAdapter';\n\n// Type exports\nexport type {\n IORMAdapter,\n QueryOptions,\n BindOptions,\n BindingContext,\n BindingResult,\n ModelMetadata,\n ModelBindingsConfig,\n ModelBindingGlobalConfig,\n CacheEntry,\n TypedRequest,\n TypedRequestHandler,\n ExtractModelType,\n MiddlewareFunction,\n} from './core/types';\n\n// Adapter exports\nexport { KnexAdapter, defineKnexModel } from './adapters/KnexAdapter';\nexport type { KnexModel } from './adapters/KnexAdapter';\nexport { MongooseAdapter } from './adapters/MongooseAdapter';\nexport { TypeORMAdapter } from './adapters/TypeORMAdapter';\nexport { SequelizeAdapter } from './adapters/SequelizeAdapter';\nexport { PrismaAdapter } from './adapters/PrismaAdapter';\n\n// Middleware exports\nexport {\n bindModel,\n bindModels,\n bindOptional,\n bindByKey,\n bindAs,\n bindCached,\n bindWithRelations,\n} from './middleware/bindModel';\n\n// Error exports\nexport {\n BindingError,\n ModelNotFoundError,\n AdapterNotSetError,\n InvalidModelError,\n ValidationError,\n} from './errors';\n\n// Utility exports\nexport { Cache } from './utils/cache';\nexport { logger } from './utils/logger';\nexport type { LogLevel, LoggerConfig } from './utils/logger';\nexport * from './utils/validators';\nexport * from './utils/transformers';\n\n// Version\nexport const VERSION = '1.0.0';\n","/**\n * Base error class for model binding errors\n */\nexport class BindingError extends Error {\n public readonly originalError?: Error;\n\n constructor(message: string, originalError?: Error) {\n super(message);\n this.name = 'BindingError';\n this.originalError = originalError;\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n originalError: this.originalError?.message,\n };\n }\n}\n\n/**\n * Error thrown when a model is not found (404)\n */\nexport class ModelNotFoundError extends Error {\n public readonly statusCode = 404;\n public readonly paramName: string;\n public readonly paramValue: string;\n public readonly modelName: string;\n\n constructor(paramName: string, paramValue: string, modelName: string, customMessage?: string) {\n super(customMessage || `${modelName} not found with ${paramName} = ${paramValue}`);\n this.name = 'ModelNotFoundError';\n this.paramName = paramName;\n this.paramValue = paramValue;\n this.modelName = modelName;\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n error: 'Not Found',\n message: this.message,\n statusCode: this.statusCode,\n param: this.paramName,\n value: this.paramValue,\n model: this.modelName,\n };\n }\n}\n\n/**\n * Error thrown when no adapter is configured\n */\nexport class AdapterNotSetError extends Error {\n constructor(\n message: string = 'No adapter set. Call ModelBinder.setAdapter() before using model binding.'\n ) {\n super(message);\n this.name = 'AdapterNotSetError';\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n };\n }\n}\n\n/**\n * Error thrown when a model is invalid for an adapter\n */\nexport class InvalidModelError extends Error {\n public readonly model: unknown;\n\n constructor(message: string, model: unknown) {\n super(message);\n this.name = 'InvalidModelError';\n this.model = model;\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n model: typeof this.model === 'string' ? this.model : String(this.model),\n };\n }\n}\n\n/**\n * Error thrown when validation fails\n */\nexport class ValidationError extends Error {\n public readonly statusCode: number;\n public readonly details?: unknown;\n\n constructor(message: string, statusCode: number = 400, details?: unknown) {\n super(message);\n this.name = 'ValidationError';\n this.statusCode = statusCode;\n this.details = details;\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n statusCode: this.statusCode,\n details: this.details,\n };\n }\n}\n","import { CacheEntry } from '../core/types';\n\n/**\n * Simple in-memory cache for model binding\n */\nexport class Cache {\n private store = new Map<string, CacheEntry>();\n private maxSize: number;\n\n constructor(maxSize: number = 1000) {\n this.maxSize = maxSize;\n }\n\n /**\n * Get a value from cache\n */\n get<T = unknown>(key: string): T | null {\n const entry = this.store.get(key);\n\n if (!entry) {\n return null;\n }\n\n // Check if expired\n if (Date.now() - entry.timestamp > entry.ttl) {\n this.store.delete(key);\n return null;\n }\n\n return entry.value as T;\n }\n\n /**\n * Set a value in cache\n */\n set<T = unknown>(key: string, value: T, ttl: number): void {\n // Evict oldest entries if cache is full\n if (this.store.size >= this.maxSize) {\n const firstKey = this.store.keys().next().value;\n if (firstKey) {\n this.store.delete(firstKey);\n }\n }\n\n this.store.set(key, {\n value,\n timestamp: Date.now(),\n ttl,\n });\n }\n\n /**\n * Delete a value from cache\n */\n delete(key: string): boolean {\n return this.store.delete(key);\n }\n\n /**\n * Clear all cached values\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Get cache size\n */\n get size(): number {\n return this.store.size;\n }\n\n /**\n * Check if key exists and is not expired\n */\n has(key: string): boolean {\n return this.get(key) !== null;\n }\n\n /**\n * Get all keys in the cache\n */\n keys(): string[] {\n return Array.from(this.store.keys());\n }\n\n /**\n * Remove expired entries\n */\n prune(): number {\n let removed = 0;\n const now = Date.now();\n\n for (const [key, entry] of this.store.entries()) {\n if (now - entry.timestamp > entry.ttl) {\n this.store.delete(key);\n removed++;\n }\n }\n\n return removed;\n }\n\n /**\n * Get cache statistics\n */\n getStats(): { size: number; maxSize: number } {\n return {\n size: this.store.size,\n maxSize: this.maxSize,\n };\n }\n}\n","/**\n * Log levels for the logger\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * Logger configuration\n */\nexport interface LoggerConfig {\n enabled: boolean;\n level: LogLevel;\n prefix: string;\n}\n\n/**\n * Simple logger utility for debugging\n */\nclass Logger {\n private config: LoggerConfig = {\n enabled: false,\n level: 'info',\n prefix: '[express-model-binding]',\n };\n\n private levelPriority: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n };\n\n /**\n * Enable debug logging\n */\n enable(): void {\n this.config.enabled = true;\n }\n\n /**\n * Disable debug logging\n */\n disable(): void {\n this.config.enabled = false;\n }\n\n /**\n * Check if logging is enabled\n */\n isEnabled(): boolean {\n return this.config.enabled;\n }\n\n /**\n * Set log level\n */\n setLevel(level: LogLevel): void {\n this.config.level = level;\n }\n\n /**\n * Get current log level\n */\n getLevel(): LogLevel {\n return this.config.level;\n }\n\n /**\n * Set custom prefix\n */\n setPrefix(prefix: string): void {\n this.config.prefix = prefix;\n }\n\n /**\n * Check if a message at the given level should be logged\n */\n private shouldLog(level: LogLevel): boolean {\n if (!this.config.enabled) {\n return false;\n }\n return this.levelPriority[level] >= this.levelPriority[this.config.level];\n }\n\n /**\n * Format log message\n */\n private formatMessage(level: LogLevel, message: string): string {\n const timestamp = new Date().toISOString();\n return `${this.config.prefix} [${timestamp}] [${level.toUpperCase()}] ${message}`;\n }\n\n /**\n * Log a debug message\n */\n debug(message: string, context?: unknown): void {\n if (this.shouldLog('debug')) {\n console.log(this.formatMessage('debug', message), context !== undefined ? context : '');\n }\n }\n\n /**\n * Log an info message\n */\n info(message: string, context?: unknown): void {\n if (this.shouldLog('info')) {\n console.info(this.formatMessage('info', message), context !== undefined ? context : '');\n }\n }\n\n /**\n * Log a warning message\n */\n warn(message: string, context?: unknown): void {\n if (this.shouldLog('warn')) {\n console.warn(this.formatMessage('warn', message), context !== undefined ? context : '');\n }\n }\n\n /**\n * Log an error message\n */\n error(message: string, error?: unknown): void {\n if (this.shouldLog('error')) {\n console.error(this.formatMessage('error', message), error !== undefined ? error : '');\n }\n }\n\n /**\n * Reset logger to default configuration\n */\n reset(): void {\n this.config = {\n enabled: false,\n level: 'info',\n prefix: '[express-model-binding]',\n };\n }\n\n /**\n * Get current configuration\n */\n getConfig(): LoggerConfig {\n return { ...this.config };\n }\n}\n\nexport const logger = new Logger();\n","import { Request, Response } from 'express';\nimport { IORMAdapter, BindOptions, BindingContext, BindingResult } from './types';\nimport { AdapterNotSetError, ModelNotFoundError, BindingError } from '../errors';\nimport { Cache } from '../utils/cache';\nimport { logger } from '../utils/logger';\n\n/**\n * Express request with bound models\n */\ninterface RequestWithModels extends Request {\n [key: string]: unknown;\n}\n\n/**\n * Central model binding orchestrator\n */\nexport class ModelBinder {\n private static adapter: IORMAdapter | null = null;\n private static cache = new Cache();\n private static debug = false;\n\n static setAdapter(adapter: IORMAdapter): void {\n if (!adapter) {\n throw new Error('Adapter cannot be null or undefined');\n }\n this.adapter = adapter;\n logger.debug(`Adapter set: ${adapter.name}`);\n }\n\n static getAdapter(): IORMAdapter {\n if (!this.adapter) {\n throw new AdapterNotSetError(\n 'No adapter set. Call ModelBinder.setAdapter() before using model binding.'\n );\n }\n return this.adapter;\n }\n\n static hasAdapter(): boolean {\n return this.adapter !== null;\n }\n\n static clearAdapter(): void {\n this.adapter = null;\n logger.debug('Adapter cleared');\n }\n\n static setDebug(enabled: boolean): void {\n this.debug = enabled;\n if (enabled) {\n logger.enable();\n } else {\n logger.disable();\n }\n }\n\n static isDebugEnabled(): boolean {\n return this.debug;\n }\n\n static clearCache(): void {\n this.cache.clear();\n logger.debug('Cache cleared');\n }\n\n static getCacheStats(): { size: number; maxSize: number } {\n return this.cache.getStats();\n }\n\n static async bind(\n req: Request,\n res: Response,\n paramName: string,\n model: unknown,\n options: BindOptions = {}\n ): Promise<BindingResult> {\n const startTime = Date.now();\n const adapter = this.getAdapter();\n const paramValue = req.params[paramName];\n\n const context: BindingContext = {\n req,\n res,\n paramName,\n paramValue,\n model,\n options,\n adapter,\n startTime,\n };\n\n try {\n if (paramValue === undefined || paramValue === null || paramValue === '') {\n if (options.optional) {\n const attachAs = options.as || paramName;\n this.attachToRequest(req, attachAs, undefined);\n\n return {\n success: true,\n model: undefined,\n duration: Date.now() - startTime,\n };\n }\n\n throw new BindingError(\n `Parameter '${paramName}' is required but was not provided`,\n new Error('Missing parameter')\n );\n }\n\n if (!adapter.isValidModel(model)) {\n throw new BindingError(\n `Invalid model for ${adapter.name} adapter`,\n new Error('Model validation failed')\n );\n }\n\n const key = options.key || adapter.getPrimaryKeyName(model);\n\n let value: unknown = context.paramValue;\n if (options.transformValue) {\n value = options.transformValue(paramValue);\n } else {\n value = adapter.transformValue(model, key, paramValue);\n }\n\n const cacheKey = this.getCacheKey(model, key, value, options);\n if (options.cache) {\n const cached = this.cache.get(cacheKey);\n if (cached !== null) {\n logger.debug(`Cache hit for ${paramName}:${value}`);\n\n const attachAs = options.as || paramName;\n this.attachToRequest(req, attachAs, cached);\n\n return {\n success: true,\n model: cached,\n duration: Date.now() - startTime,\n fromCache: true,\n };\n }\n }\n\n logger.debug(`Fetching ${paramName}:${value} using ${adapter.name}`);\n const result = await adapter.findByKey(model, key, value, options);\n\n if (!result) {\n if (options.optional) {\n const attachAs = options.as || paramName;\n this.attachToRequest(req, attachAs, undefined);\n\n return {\n success: true,\n model: undefined,\n duration: Date.now() - startTime,\n };\n }\n\n let error: Error;\n if (options.errorMessage) {\n error = new ModelNotFoundError(\n paramName,\n String(value),\n this.getModelName(model),\n options.errorMessage\n );\n } else if (options.onNotFound) {\n error =\n typeof options.onNotFound === 'function'\n ? options.onNotFound(paramName, String(value))\n : options.onNotFound;\n } else {\n error = new ModelNotFoundError(paramName, String(value), this.getModelName(model));\n }\n\n throw error;\n }\n\n if (options.validate) {\n await options.validate(result, req);\n }\n\n if (options.cache) {\n const ttl = options.cacheTTL || (typeof options.cache === 'number' ? options.cache : 60000);\n this.cache.set(cacheKey, result, ttl);\n logger.debug(`Cached ${paramName}:${value} for ${ttl}ms`);\n }\n\n const attachAs = options.as || paramName;\n this.attachToRequest(req, attachAs, result);\n\n logger.debug(`Successfully bound ${paramName}:${value}`);\n\n return {\n success: true,\n model: result,\n duration: Date.now() - startTime,\n fromCache: false,\n };\n } catch (error) {\n logger.error(`Failed to bind ${paramName}:${context.paramValue}`, error);\n\n return {\n success: false,\n error: error as Error,\n duration: Date.now() - startTime,\n };\n }\n }\n\n private static attachToRequest(req: Request, key: string, value: unknown): void {\n (req as RequestWithModels)[key] = value;\n }\n\n private static getCacheKey(\n model: unknown,\n key: string,\n value: unknown,\n options: BindOptions\n ): string {\n const modelName = this.getModelName(model);\n const optionsHash = JSON.stringify({\n key,\n include: options.include,\n where: options.where,\n select: options.select,\n });\n\n return `${modelName}:${key}:${String(value)}:${optionsHash}`;\n }\n\n private static getModelName(model: unknown): string {\n if (typeof model === 'string') {\n return model;\n }\n if (model && typeof model === 'object') {\n const obj = model as Record<string, unknown>;\n if (typeof obj.name === 'string') return obj.name;\n if (typeof obj.modelName === 'string') return obj.modelName;\n if (typeof obj.tableName === 'string') return obj.tableName;\n }\n if (model && typeof model === 'function') {\n return (model as { name: string }).name || 'Unknown';\n }\n return 'Unknown';\n }\n\n static reset(): void {\n this.adapter = null;\n this.cache.clear();\n this.debug = false;\n logger.disable();\n }\n}\n","import { IORMAdapter, QueryOptions, ModelMetadata, QueryModifier } from './types';\nimport { InvalidModelError } from '../errors';\n\n/**\n * Abstract base class providing common adapter functionality.\n * Extend this class to implement ORM-specific adapters.\n *\n * @typeParam TModel - Model type accepted by this adapter\n * @typeParam TResult - Result type returned by queries\n * @typeParam TQueryBuilder - ORM-specific query builder type\n */\nexport abstract class BaseAdapter<\n TModel = unknown,\n TResult = unknown,\n TQueryBuilder = unknown,\n> implements IORMAdapter<TModel, TResult> {\n abstract readonly name: string;\n\n abstract findByKey(\n model: TModel,\n key: string,\n value: unknown,\n options?: QueryOptions\n ): Promise<TResult | null>;\n\n abstract getPrimaryKeyName(model: TModel): string;\n\n abstract isValidModel(model: unknown): model is TModel;\n\n transformValue(_model: TModel, _key: string, value: string): unknown {\n if (/^\\d+$/.test(value)) {\n const num = parseInt(value, 10);\n if (!isNaN(num) && Number.isSafeInteger(num)) {\n return num;\n }\n }\n return value;\n }\n\n supportsSoftDeletes(_model: TModel): boolean {\n return false;\n }\n\n getModelMetadata(model: TModel): ModelMetadata {\n return {\n name: this.getModelName(model),\n primaryKey: this.getPrimaryKeyName(model),\n softDeletes: this.supportsSoftDeletes(model),\n adapter: this.name,\n };\n }\n\n protected validateModel(model: unknown): asserts model is TModel {\n if (!this.isValidModel(model)) {\n throw new InvalidModelError(`Invalid model for ${this.name} adapter`, model);\n }\n }\n\n protected getModelName(model: TModel): string {\n if (typeof model === 'string') {\n return model;\n }\n if (model && typeof model === 'object') {\n const obj = model as Record<string, unknown>;\n if (typeof obj.name === 'string') return obj.name;\n if (typeof obj.modelName === 'string') return obj.modelName;\n if (typeof obj.tableName === 'string') return obj.tableName;\n }\n if (model && typeof model === 'function') {\n return (model as { name: string }).name || 'Unknown';\n }\n return 'Unknown';\n }\n\n protected applySoftDeleteFilter(\n queryBuilder: TQueryBuilder,\n _options?: QueryOptions\n ): TQueryBuilder {\n return queryBuilder;\n }\n\n protected applyIncludes(\n queryBuilder: TQueryBuilder,\n _includes?: string[] | Record<string, unknown>\n ): TQueryBuilder {\n return queryBuilder;\n }\n\n protected applySelect(queryBuilder: TQueryBuilder, _select?: string[]): TQueryBuilder {\n return queryBuilder;\n }\n\n protected applyWhereConditions(\n queryBuilder: TQueryBuilder,\n _where?: Record<string, unknown>\n ): TQueryBuilder {\n return queryBuilder;\n }\n\n protected applyCustomQuery(\n queryBuilder: TQueryBuilder,\n queryFn?: QueryModifier<TQueryBuilder>\n ): TQueryBuilder {\n if (queryFn) {\n return queryFn(queryBuilder) as TQueryBuilder;\n }\n return queryBuilder;\n }\n}\n","import { Request, Response, NextFunction, RequestHandler } from 'express';\n\n/**\n * Generic query builder type - adapters can narrow this to their specific type\n */\nexport type QueryBuilder<T = unknown> = T;\n\n/**\n * Query modifier function type\n */\nexport type QueryModifier<T = unknown> = (queryBuilder: QueryBuilder<T>) => QueryBuilder<T>;\n\n/**\n * Base adapter interface that all ORM adapters must implement\n */\nexport interface IORMAdapter<TModel = unknown, TResult = unknown> {\n readonly name: string;\n\n findByKey(\n model: TModel,\n key: string,\n value: unknown,\n options?: QueryOptions\n ): Promise<TResult | null>;\n\n getPrimaryKeyName(model: TModel): string;\n\n isValidModel(model: unknown): model is TModel;\n\n transformValue(model: TModel, key: string, value: string): unknown;\n\n supportsSoftDeletes(model: TModel): boolean;\n\n getModelMetadata?(model: TModel): ModelMetadata;\n}\n\n/**\n * Query options for model lookups\n */\nexport interface QueryOptions {\n /**\n * Relations to eager load\n */\n include?: string[] | Record<string, unknown>;\n\n /**\n * Additional WHERE conditions\n */\n where?: Record<string, unknown>;\n\n /**\n * Custom query modifier - receives ORM-specific query builder\n */\n query?: QueryModifier;\n\n /**\n * Fields to select\n */\n select?: string[];\n\n /**\n * Include soft-deleted records\n */\n withTrashed?: boolean;\n\n /**\n * Only return soft-deleted records\n */\n onlyTrashed?: boolean;\n\n /**\n * Enable result caching\n */\n cache?: boolean | number;\n\n /**\n * Row locking for transactions\n */\n lock?: 'forUpdate' | 'forShare';\n}\n\n/**\n * Binding middleware options\n */\nexport interface BindOptions extends QueryOptions {\n /**\n * Field to search by (defaults to primary key)\n */\n key?: string;\n\n /**\n * Custom error when model not found\n */\n onNotFound?: Error | ((paramName: string, paramValue: string) => Error);\n\n /**\n * Transform parameter value before querying\n */\n transformValue?: (value: string) => unknown;\n\n /**\n * Property name for attaching model to request\n */\n as?: string;\n\n /**\n * Don't throw if model not found\n */\n optional?: boolean;\n\n /**\n * Custom 404 message\n */\n errorMessage?: string;\n\n /**\n * Validate loaded model\n */\n validate?: (model: unknown, req: Request) => void | Promise<void>;\n\n /**\n * Enable caching\n */\n cache?: boolean;\n\n /**\n * Cache TTL in milliseconds\n */\n cacheTTL?: number;\n}\n\n/**\n * Multi-model binding configuration\n */\nexport interface ModelBindingsConfig {\n [paramName: string]: {\n model: unknown;\n options?: BindOptions;\n };\n}\n\n/**\n * Binding operation context\n */\nexport interface BindingContext {\n req: Request;\n res: Response;\n paramName: string;\n paramValue: string;\n model: unknown;\n options: BindOptions;\n adapter: IORMAdapter;\n startTime: number;\n}\n\n/**\n * Binding operation result\n */\nexport interface BindingResult {\n success: boolean;\n model?: unknown;\n error?: Error;\n duration: number;\n fromCache?: boolean;\n}\n\n/**\n * Model metadata for debugging\n */\nexport interface ModelMetadata {\n name: string;\n primaryKey: string;\n tableName?: string;\n relations?: string[];\n softDeletes: boolean;\n adapter?: string;\n [key: string]: unknown;\n}\n\n/**\n * Cache entry structure\n */\nexport interface CacheEntry<T = unknown> {\n value: T;\n timestamp: number;\n ttl: number;\n}\n\n/**\n * Global configuration options\n */\nexport interface ModelBindingGlobalConfig {\n adapter?: IORMAdapter;\n cache?: {\n enabled: boolean;\n ttl: number;\n maxSize?: number;\n };\n debug?: boolean;\n logger?: (message: string, context?: unknown) => void;\n onError?: (error: Error, context: BindingContext) => void;\n}\n\n/**\n * Express request with bound models\n */\nexport interface TypedRequest<\n P = Record<string, string>,\n ResBody = unknown,\n ReqBody = unknown,\n ReqQuery = unknown,\n Models extends Record<string, unknown> = Record<string, unknown>,\n> extends Request<P, ResBody, ReqBody, ReqQuery> {\n [K: string]: unknown;\n models?: Models;\n}\n\n/**\n * Extract model type from binding config\n */\nexport type ExtractModelType<T> = T extends { model: infer M } ? M : never;\n\n/**\n * Typed request handler\n */\nexport type TypedRequestHandler<\n Models extends Record<string, unknown> = Record<string, unknown>,\n P = Record<string, string>,\n ResBody = unknown,\n ReqBody = unknown,\n ReqQuery = unknown,\n> = (\n req: TypedRequest<P, ResBody, ReqBody, ReqQuery, Models>,\n res: Response<ResBody>,\n next: NextFunction\n) => void | Promise<void>;\n\n/**\n * Middleware function type\n */\nexport type MiddlewareFunction = RequestHandler;\n\n/**\n * Operator condition for advanced WHERE clauses\n */\nexport interface OperatorCondition {\n operator: string;\n value: unknown;\n}\n\n/**\n * Check if value is an operator condition\n */\nexport function isOperatorCondition(value: unknown): value is OperatorCondition {\n return typeof value === 'object' && value !== null && 'operator' in value && 'value' in value;\n}\n","/**\n * UUID regex pattern\n */\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/**\n * MongoDB ObjectId regex pattern (24 hex characters)\n */\nconst OBJECT_ID_REGEX = /^[0-9a-f]{24}$/i;\n\n/**\n * Check if a value is a valid UUID\n */\nexport function isUUID(value: string): boolean {\n return UUID_REGEX.test(value);\n}\n\n/**\n * Check if a value is a valid MongoDB ObjectId\n */\nexport function isObjectId(value: string): boolean {\n return OBJECT_ID_REGEX.test(value);\n}\n\n/**\n * Check if a value is a numeric string\n */\nexport function isNumeric(value: string): boolean {\n return /^-?\\d+$/.test(value);\n}\n\n/**\n * Check if a value is a valid positive integer\n */\nexport function isPositiveInteger(value: string): boolean {\n return /^\\d+$/.test(value) && parseInt(value, 10) > 0;\n}\n\n/**\n * Check if a value is a valid slug (lowercase alphanumeric with hyphens)\n */\nexport function isSlug(value: string): boolean {\n return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value);\n}\n\n/**\n * Check if a value is a valid email\n */\nexport function isEmail(value: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value);\n}\n\n/**\n * Validate that a value is not empty\n */\nexport function isNotEmpty(value: unknown): boolean {\n if (value === null || value === undefined) {\n return false;\n }\n if (typeof value === 'string') {\n return value.trim().length > 0;\n }\n return true;\n}\n\n/**\n * Validate that a value is a non-empty string\n */\nexport function isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\n/**\n * Validate that a value is a plain object\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Validate that a value is a function\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function isFunction(value: unknown): value is Function {\n return typeof value === 'function';\n}\n\n/**\n * Validate route parameter name\n */\nexport function isValidParamName(value: string): boolean {\n return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(value);\n}\n","import type { Knex } from 'knex';\nimport { BaseAdapter } from '../core/BaseAdapter';\nimport { QueryOptions, ModelMetadata, isOperatorCondition } from '../core/types';\nimport { BindingError } from '../errors';\nimport { isUUID } from '../utils/validators';\n\n/**\n * Model definition for Knex tables with soft delete support\n */\nexport interface KnexModel {\n tableName: string;\n primaryKey?: string;\n softDeleteColumn?: string;\n}\n\n/**\n * Union type for Knex model inputs\n */\nexport type KnexModelInput = string | KnexModel;\n\n/**\n * Type guard for KnexModel\n */\nfunction isKnexModel(value: unknown): value is KnexModel {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as KnexModel).tableName === 'string'\n );\n}\n\n/**\n * Adapter for Knex query builder supporting PostgreSQL, MySQL, SQLite, MSSQL, Oracle\n */\nexport class KnexAdapter extends BaseAdapter<\n KnexModelInput,\n Record<string, unknown>,\n Knex.QueryBuilder\n> {\n readonly name = 'knex';\n\n constructor(private knex: Knex) {\n super();\n }\n\n getKnex(): Knex {\n return this.knex;\n }\n\n async findByKey(\n model: KnexModelInput,\n key: string,\n value: unknown,\n options: QueryOptions = {}\n ): Promise<Record<string, unknown> | null> {\n this.validateModel(model);\n\n const tableName = this.getTableName(model);\n\n try {\n let query = this.knex(tableName);\n\n query = query.where(key, value as Knex.Value);\n\n if (this.supportsSoftDeletes(model) && !options.withTrashed && !options.onlyTrashed) {\n const softDeleteColumn = this.getSoftDeleteColumn(model);\n query = query.whereNull(softDeleteColumn);\n } else if (options.onlyTrashed && this.supportsSoftDeletes(model)) {\n const softDeleteColumn = this.getSoftDeleteColumn(model);\n query = query.whereNotNull(softDeleteColumn);\n }\n\n if (options.where) {\n query = this.applyWhereConditions(query, options.where);\n }\n\n if (options.select && options.select.length > 0) {\n query = query.select(options.select);\n } else {\n query = query.select('*');\n }\n\n if (options.query) {\n query = this.applyCustomQuery(\n query,\n options.query as (qb: Knex.QueryBuilder) => Knex.QueryBuilder\n );\n }\n\n if (options.lock === 'forUpdate') {\n query = query.forUpdate();\n } else if (options.lock === 'forShare') {\n query = query.forShare();\n }\n\n const result = await query.first();\n return (result as Record<string, unknown>) || null;\n } catch (error) {\n throw new BindingError(\n `Failed to fetch ${this.getModelName(model)}: ${(error as Error).message}`,\n error as Error\n );\n }\n }\n\n getPrimaryKeyName(model: KnexModelInput): string {\n if (isKnexModel(model) && model.primaryKey) {\n return model.primaryKey;\n }\n return 'id';\n }\n\n isValidModel(model: unknown): model is KnexModelInput {\n return typeof model === 'string' || isKnexModel(model);\n }\n\n transformValue(model: KnexModelInput, key: string, value: string): unknown {\n const primaryKey = this.getPrimaryKeyName(model);\n\n if (key === primaryKey || key === 'id') {\n const num = parseInt(value, 10);\n if (!isNaN(num) && num.toString() === value && Number.isSafeInteger(num)) {\n return num;\n }\n }\n\n if (isUUID(value)) {\n return value;\n }\n\n return value;\n }\n\n supportsSoftDeletes(model: KnexModelInput): boolean {\n return isKnexModel(model) && !!model.softDeleteColumn;\n }\n\n getModelMetadata(model: KnexModelInput): ModelMetadata {\n return {\n name: this.getModelName(model),\n primaryKey: this.getPrimaryKeyName(model),\n tableName: this.getTableName(model),\n softDeletes: this.supportsSoftDeletes(model),\n adapter: this.name,\n };\n }\n\n private getTableName(model: KnexModelInput): string {\n return typeof model === 'string' ? model : model.tableName;\n }\n\n private getSoftDeleteColumn(model: KnexModelInput): string {\n if (isKnexModel(model) && model.softDeleteColumn) {\n return model.softDeleteColumn;\n }\n return 'deleted_at';\n }\n\n protected applyWhereConditions(\n query: Knex.QueryBuilder,\n where: Record<string, unknown>\n ): Knex.QueryBuilder {\n Object.entries(where).forEach(([column, value]) => {\n if (value === null) {\n query = query.whereNull(column);\n } else if (Array.isArray(value)) {\n query = query.whereIn(column, value as Knex.Value[]);\n } else if (isOperatorCondition(value)) {\n query = query.where(column, value.operator, value.value as Knex.Value);\n } else {\n query = query.where(column, value as Knex.Value);\n }\n });\n return query;\n }\n}\n\n/**\n * Create a Knex model definition\n */\nexport function defineKnexModel(config: {\n tableName: string;\n primaryKey?: string;\n softDeleteColumn?: string;\n}): KnexModel {\n return {\n tableName: config.tableName,\n primaryKey: config.primaryKey || 'id',\n softDeleteColumn: config.softDeleteColumn,\n };\n}\n","import type { Model, Document, Query, PopulateOptions, Schema } from 'mongoose';\nimport { BaseAdapter } from '../core/BaseAdapter';\nimport { QueryOptions, ModelMetadata, QueryModifier } from '../core/types';\nimport { BindingError } from '../errors';\nimport { isObjectId } from '../utils/validators';\n\n/**\n * Mongoose model type with required schema property\n */\ninterface MongooseModel extends Model<Document> {\n schema: Schema;\n modelName: string;\n}\n\n/**\n * Mongoose query type\n */\ntype MongooseQuery = Query<Document | null, Document>;\n\n/**\n * Type guard for Mongoose schema path\n */\ninterface SchemaPathType {\n instance: string;\n}\n\nfunction isSchemaPathType(value: unknown): value is SchemaPathType {\n return typeof value === 'object' && value !== null && 'instance' in value;\n}\n\n/**\n * Adapter for MongoDB using Mongoose ODM\n */\nexport class MongooseAdapter extends BaseAdapter<MongooseModel, Document, MongooseQuery> {\n readonly name = 'mongoose';\n\n async findByKey(\n model: MongooseModel,\n key: string,\n value: unknown,\n options: QueryOptions = {}\n ): Promise<Document | null> {\n this.validateModel(model);\n\n try {\n const transformedValue = this.transformValue(model, key, value as string);\n\n let query: MongooseQuery = model.findOne({ [key]: transformedValue });\n\n if (options.select && options.select.length > 0) {\n query = query.select(options.select.join(' '));\n }\n\n if (options.include) {\n query = this.applyIncludes(query, options.include);\n }\n\n if (options.where) {\n Object.entries(options.where).forEach(([field, val]) => {\n query = query.where(field).equals(val);\n });\n }\n\n if (options.query) {\n query = this.applyCustomQuery(query, options.query as QueryModifier<MongooseQuery>);\n }\n\n const result = await query.exec();\n\n if (result && this.supportsSoftDeletes(model)) {\n const doc = result as Document & {\n deleted?: boolean;\n deletedAt?: Date;\n isDeleted?: boolean;\n };\n const isDeleted = doc.deleted || doc.deletedAt || doc.isDeleted;\n\n if (!options.withTrashed && !options.onlyTrashed && isDeleted) {\n return null;\n }\n\n if (options.onlyTrashed && !isDeleted) {\n return null;\n }\n }\n\n return result;\n } catch (error) {\n throw new BindingError(\n `Failed to fetch ${model.modelName}: ${(error as Error).message}`,\n error as Error\n );\n }\n }\n\n getPrimaryKeyName(_model: MongooseModel): string {\n return '_id';\n }\n\n isValidModel(model: unknown): model is MongooseModel {\n if (!model || typeof model !== 'function') {\n return false;\n }\n const m = model as Partial<MongooseModel>;\n return (\n typeof m.findOne === 'function' && typeof m.modelName === 'string' && m.schema !== undefined\n );\n }\n\n transformValue(model: MongooseModel, key: string, value: string): unknown {\n if (key === '_id' || key === 'id') {\n if (isObjectId(value)) {\n try {\n // Mongoose must be loaded synchronously for ObjectId construction\n // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires\n const mongoose = require('mongoose');\n return new mongoose.Types.ObjectId(value);\n } catch {\n return value;\n }\n }\n return value;\n }\n\n const schemaType = model.schema.path(key);\n if (isSchemaPathType(schemaType) && schemaType.instance === 'Number') {\n const num = parseInt(value, 10);\n if (!isNaN(num)) {\n return num;\n }\n }\n\n return value;\n }\n\n supportsSoftDeletes(model: MongooseModel): boolean {\n const schema = model.schema;\n return (\n schema.path('deleted') !== undefined ||\n schema.path('deletedAt') !== undefined ||\n schema.path('isDeleted') !== undefined\n );\n }\n\n getModelMetadata(model: MongooseModel): ModelMetadata {\n const schema = model.schema;\n const paths = Object.keys(schema.paths);\n\n return {\n name: model.modelName,\n primaryKey: '_id',\n tableName: model.collection.name,\n softDeletes: this.supportsSoftDeletes(model),\n fields: paths,\n adapter: this.name,\n };\n }\n\n protected applyIncludes(\n query: MongooseQuery,\n includes: string[] | Record<string, unknown>\n ): MongooseQuery {\n if (Array.isArray(includes)) {\n includes.forEach(relation => {\n query = query.populate(relation);\n });\n } else {\n Object.entries(includes).forEach(([relation, options]) => {\n if (typeof options === 'boolean' && options) {\n query = query.populate(relation);\n } else if (typeof options === 'object' && options !== null) {\n query = query.populate({\n path: relation,\n ...options,\n } as PopulateOptions);\n }\n });\n }\n return query;\n }\n}\n","import type {\n DataSource,\n Repository,\n EntityTarget,\n ObjectLiteral,\n SelectQueryBuilder,\n} from 'typeorm';\nimport { BaseAdapter } from '../core/BaseAdapter';\nimport { QueryOptions, ModelMetadata, QueryModifier } from '../core/types';\nimport { BindingError } from '../errors';\nimport { isUUID } from '../utils/validators';\n\n/**\n * TypeORM entity type alias for better readability\n */\nexport type TypeORMEntity = EntityTarget<ObjectLiteral>;\n\n/**\n * TypeORM find options structure\n */\ninterface TypeORMFindOptions {\n where: Record<string, unknown>;\n select?: Record<string, boolean>;\n relations?: string[];\n withDeleted?: boolean;\n}\n\n/**\n * Adapter for TypeORM supporting SQL and NoSQL databases\n */\nexport class TypeORMAdapter extends BaseAdapter<\n TypeORMEntity,\n ObjectLiteral,\n SelectQueryBuilder<ObjectLiteral>\n> {\n readonly name = 'typeorm';\n\n constructor(private dataSource: DataSource) {\n super();\n }\n\n getDataSource(): DataSource {\n return this.dataSource;\n }\n\n async findByKey(\n entity: TypeORMEntity,\n key: string,\n value: unknown,\n options: QueryOptions = {}\n ): Promise<ObjectLiteral | null> {\n this.validateModel(entity);\n\n try {\n const repository = this.dataSource.getRepository(entity);\n const metadata = repository.metadata;\n\n const transformedValue = this.transformValue(entity, key, value as string);\n\n if (options.query || options.lock || options.onlyTrashed) {\n return await this.findWithQueryBuilder(repository, key, transformedValue, options);\n }\n\n const findOptions: TypeORMFindOptions = {\n where: { [key]: transformedValue },\n };\n\n if (options.select && options.select.length > 0) {\n findOptions.select = options.select.reduce<Record<string, boolean>>((acc, field) => {\n acc[field] = true;\n return acc;\n }, {});\n }\n\n if (options.include) {\n findOptions.relations = Array.isArray(options.include)\n ? options.include\n : Object.keys(options.include);\n }\n\n if (options.where) {\n findOptions.where = {\n ...findOptions.where,\n ...options.where,\n };\n }\n\n if (options.withTrashed && metadata.deleteDateColumn) {\n findOptions.withDeleted = true;\n }\n\n const result = await repository.findOne(findOptions);\n return result;\n } catch (error) {\n throw new BindingError(`Failed to fetch entity: ${(error as Error).message}`, error as Error);\n }\n }\n\n getPrimaryKeyName(entity: TypeORMEntity): string {\n try {\n const repository = this.dataSource.getRepository(entity);\n const metadata = repository.metadata;\n\n if (metadata.primaryColumns.length > 0) {\n return metadata.primaryColumns[0].propertyName;\n }\n } catch {\n // Fall through to default\n }\n return 'id';\n }\n\n isValidModel(model: unknown): model is TypeORMEntity {\n try {\n this.dataSource.getRepository(model as TypeORMEntity);\n return true;\n } catch {\n return false;\n }\n }\n\n transformValue(entity: TypeORMEntity, key: string, value: string): unknown {\n try {\n const repository = this.dataSource.getRepository(entity);\n const metadata = repository.metadata;\n const column = metadata.findColumnWithPropertyName(key);\n\n if (!column) {\n if (isUUID(value)) {\n return value;\n }\n const num = parseInt(value, 10);\n if (!isNaN(num) && num.toString() === value) {\n return num;\n }\n return value;\n }\n\n const columnType = String(column.type).toLowerCase();\n\n if (['int', 'integer', 'smallint', 'bigint', 'number'].includes(columnType)) {\n const num = parseInt(value, 10);\n return isNaN(num) ? value : num;\n }\n\n if (columnType === 'uuid') {\n return value;\n }\n\n if (columnType === 'boolean' || columnType === 'bool') {\n return value === 'true' || value === '1';\n }\n\n return value;\n } catch {\n return value;\n }\n }\n\n supportsSoftDeletes(entity: TypeORMEntity): boolean {\n try {\n const repository = this.dataSource.getRepository(entity);\n const metadata = repository.metadata;\n return !!metadata.deleteDateColumn;\n } catch {\n return false;\n }\n }\n\n getModelMetadata(entity: TypeORMEntity): ModelMetadata {\n try {\n const repository = this.dataSource.getRepository(entity);\n const metadata = repository.metadata;\n\n return {\n name: metadata.name,\n primaryKey: this.getPrimaryKeyName(entity),\n tableName: metadata.tableName,\n softDeletes: this.supportsSoftDeletes(entity),\n relations: metadata.relations.map(r => r.propertyName),\n adapter: this.name,\n };\n } catch {\n return {\n name: 'Unknown',\n primaryKey: 'id',\n softDeletes: false,\n adapter: this.name,\n };\n }\n }\n\n private async findWithQueryBuilder(\n repository: Repository<ObjectLiteral>,\n key: string,\n value: unknown,\n options: QueryOptions\n ): Promise<ObjectLiteral | null> {\n const metadata = repository.metadata;\n const alias = metadata.name.toLowerCase();\n\n let queryBuilder = repository\n .createQueryBuilder(alias)\n .where(`${alias}.${key} = :value`, { value });\n\n if (options.include) {\n const relations = Array.isArray(options.include)\n ? options.include\n : Object.keys(options.include);\n\n relations.forEach(relation => {\n queryBuilder = queryBuilder.leftJoinAndSelect(`${alias}.${relation}`, relation);\n });\n }\n\n if (options.where) {\n Object.entries(options.where).forEach(([field, val]) => {\n queryBuilder = queryBuilder.andWhere(`${alias}.${field} = :${field}`, { [field]: val });\n });\n }\n\n if (options.select && options.select.length > 0) {\n queryBuilder = queryBuilder.select(options.select.map(field => `${alias}.${field}`));\n }\n\n if (options.withTrashed) {\n queryBuilder = queryBuilder.withDeleted();\n } else if (options.onlyTrashed && metadata.deleteDateColumn) {\n queryBuilder = queryBuilder\n .withDeleted()\n .andWhere(`${alias}.${metadata.deleteDateColumn.propertyName} IS NOT NULL`);\n }\n\n if (options.lock === 'forUpdate') {\n queryBuilder = queryBuilder.setLock('pessimistic_write');\n } else if (options.lock === 'forShare') {\n queryBuilder = queryBuilder.setLock('pessimistic_read');\n }\n\n if (options.query) {\n queryBuilder = this.applyCustomQuery(\n queryBuilder,\n options.query as QueryModifier<SelectQueryBuilder<ObjectLiteral>>\n );\n }\n\n return await queryBuilder.getOne();\n }\n}\n","import type {\n Sequelize,\n Model,\n ModelStatic,\n FindOptions,\n Includeable,\n Transaction,\n} from 'sequelize';\nimport { BaseAdapter } from '../core/BaseAdapter';\nimport { QueryOptions, ModelMetadata, QueryModifier } from '../core/types';\nimport { BindingError } from '../errors';\nimport { isUUID } from '../utils/validators';\n\n/**\n * Sequelize model static type\n */\ntype SequelizeModelStatic = ModelStatic<Model>;\n\n/**\n * Type guard for Sequelize model\n */\nfunction isSequelizeModel(model: unknown): model is SequelizeModelStatic {\n if (!model || typeof model !== 'function') {\n return false;\n }\n const m = model as unknown as Record<string, unknown>;\n return (\n typeof m.findOne === 'function' &&\n typeof m.findAll === 'function' &&\n typeof m.rawAttributes === 'object'\n );\n}\n\n/**\n * Adapter for Sequelize ORM supporting PostgreSQL, MySQL, SQLite, MSSQL\n */\nexport class SequelizeAdapter extends BaseAdapter<SequelizeModelStatic, Model, FindOptions> {\n readonly name = 'sequelize';\n\n constructor(private sequelize: Sequelize) {\n super();\n }\n\n getSequelize(): Sequelize {\n return this.sequelize;\n }\n\n async findByKey(\n model: SequelizeModelStatic,\n key: string,\n value: unknown,\n options: QueryOptions = {}\n ): Promise<Model | null> {\n this.validateModel(model);\n\n try {\n const transformedValue = this.transformValue(model, key, value as string);\n\n const findOptions: FindOptions = {\n where: { [key]: transformedValue },\n };\n\n if (options.select && options.select.length > 0) {\n findOptions.attributes = options.select;\n }\n\n if (options.include) {\n findOptions.include = this.buildIncludes(options.include);\n }\n\n if (options.where) {\n findOptions.where = {\n ...findOptions.where,\n ...options.where,\n };\n }\n\n const isParanoid = model.options?.paranoid;\n if (isParanoid) {\n if (options.withTrashed) {\n findOptions.paranoid = false;\n } else if (options.onlyTrashed) {\n findOptions.paranoid = false;\n // Sequelize Op must be loaded synchronously for query construction\n // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires\n const { Op: SeqOp } = require('sequelize');\n const whereClause = findOptions.where as Record<string, unknown>;\n whereClause.deletedAt = { [SeqOp.ne]: null };\n }\n }\n\n if (options.lock === 'forUpdate') {\n findOptions.lock = true;\n } else if (options.lock === 'forShare') {\n // Sequelize Transaction must be loaded synchronously for lock types\n // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires\n const { Transaction: SeqTransaction } = require('sequelize') as {\n Transaction: typeof Transaction;\n };\n findOptions.lock = SeqTransaction.LOCK.SHARE;\n }\n\n let result = await model.findOne(findOptions);\n\n if (options.query && !result) {\n result = await this.findWithCustomQuery(model, key, transformedValue, options);\n }\n\n return result;\n } catch (error) {\n throw new BindingError(\n `Failed to fetch ${model.name}: ${(error as Error).message}`,\n error as Error\n );\n }\n }\n\n getPrimaryKeyName(model: SequelizeModelStatic): string {\n return model.primaryKeyAttribute || 'id';\n }\n\n isValidModel(model: unknown): model is SequelizeModelStatic {\n return isSequelizeModel(model);\n }\n\n transformValue(model: SequelizeModelStatic, key: string, value: string): unknown {\n const attributes = model.rawAttributes;\n const attribute = attributes?.[key];\n\n if (!attribute) {\n if (isUUID(value)) {\n return value;\n }\n const num = parseInt(value, 10);\n if (!isNaN(num) && num.toString() === value) {\n return num;\n }\n return value;\n }\n\n const attrType = attribute.type;\n const type = attrType?.constructor?.name || String(attrType);\n\n switch (type) {\n case 'INTEGER':\n case 'BIGINT':\n case 'SMALLINT': {\n const intNum = parseInt(value, 10);\n return isNaN(intNum) ? value : intNum;\n }\n\n case 'FLOAT':\n case 'DOUBLE':\n case 'DECIMAL': {\n const floatNum = parseFloat(value);\n return isNaN(floatNum) ? value : floatNum;\n }\n\n case 'BOOLEAN':\n return value === 'true' || value === '1';\n\n case 'UUID':\n return value;\n\n default:\n return value;\n }\n }\n\n supportsSoftDeletes(model: SequelizeModelStatic): boolean {\n return !!model.options?.paranoid;\n }\n\n getModelMetadata(model: SequelizeModelStatic): ModelMetadata {\n const tableName = model.tableName || model.name;\n const associations = Object.keys(model.associations || {});\n\n return {\n name: model.name,\n primaryKey: this.getPrimaryKeyName(model),\n tableName: tableName,\n softDeletes: this.supportsSoftDeletes(model),\n relations: associations,\n adapter: this.name,\n };\n }\n\n private buildIncludes(includes: string[] | Record<string, unknown>): Includeable[] {\n if (Array.isArray(includes)) {\n return includes.map(relation => ({ association: relation }));\n }\n\n return Object.entries(includes).map(([relation, opts]) => {\n if (typeof opts === 'boolean' && opts) {\n return { association: relation };\n }\n\n if (typeof opts === 'object' && opts !== null) {\n return {\n association: relation,\n ...opts,\n };\n }\n\n return { association: relation };\n });\n }\n\n private async findWithCustomQuery(\n model: SequelizeModelStatic,\n key: string,\n value: unknown,\n options: QueryOptions\n ): Promise<Model | null> {\n const findOptions: FindOptions = {\n where: { [key]: value },\n };\n\n if (options.query) {\n (options.query as QueryModifier<FindOptions>)(findOptions);\n }\n\n return await model.findOne(findOptions);\n }\n}\n","import { BaseAdapter } from '../core/BaseAdapter';\nimport { QueryOptions, ModelMetadata, QueryModifier } from '../core/types';\nimport { InvalidModelError, BindingError } from '../errors';\nimport { isUUID } from '../utils/validators';\n\n/**\n * Prisma model delegate (dynamic accessor on PrismaClient)\n */\ninterface PrismaModelDelegate {\n findUnique: (args: PrismaFindArgs) => Promise<unknown>;\n findFirst: (args: PrismaFindArgs) => Promise<unknown>;\n}\n\n/**\n * Prisma find operation arguments\n */\ninterface PrismaFindArgs {\n where: Record<string, unknown>;\n select?: Record<string, boolean>;\n include?: Record<string, unknown>;\n}\n\n/**\n * Prisma client interface (minimal required methods)\n */\ninterface PrismaClientLike {\n [modelName: string]: PrismaModelDelegate | ((...args: unknown[]) => unknown);\n}\n\n/**\n * Adapter for Prisma ORM with type-safe database access\n */\nexport class PrismaAdapter extends BaseAdapter<string, unknown, PrismaFindArgs> {\n readonly name = 'prisma';\n\n constructor(private prisma: PrismaClientLike) {\n super();\n }\n\n getPrisma(): PrismaClientLike {\n return this.prisma;\n }\n\n async findByKey(\n modelName: string,\n key: string,\n value: unknown,\n options: QueryOptions = {}\n ): Promise<unknown> {\n this.validateModel(modelName);\n\n try {\n const model = this.prisma[modelName] as PrismaModelDelegate;\n\n if (!model) {\n throw new InvalidModelError(`Model '${modelName}' not found in Prisma schema`, modelName);\n }\n\n const transformedValue = this.transformValue(modelName, key, value as string);\n\n const queryOptions: PrismaFindArgs = {\n where: { [key]: transformedValue },\n };\n\n if (options.where) {\n queryOptions.where = {\n ...queryOptions.where,\n ...options.where,\n };\n }\n\n if (options.select && options.select.length > 0) {\n queryOptions.select = options.select.reduce<Record<string, boolean>>((acc, field) => {\n acc[field] = true;\n return acc;\n }, {});\n }\n\n if (options.include) {\n queryOptions.include = this.buildIncludeOptions(options.include);\n delete queryOptions.select;\n }\n\n if (options.query) {\n (options.query as QueryModifier<PrismaFindArgs>)(queryOptions);\n }\n\n let result: unknown = null;\n try {\n result = await model.findUnique(queryOptions);\n } catch {\n result = await model.findFirst(queryOptions);\n }\n\n if (!result && key !== this.getPrimaryKeyName(modelName)) {\n result = await model.findFirst(queryOptions);\n }\n\n return result;\n } catch (error) {\n if (error instanceof InvalidModelError) {\n throw error;\n }\n throw new BindingError(\n `Failed to fetch ${modelName}: ${(error as Error).message}`,\n error as Error\n );\n }\n }\n\n getPrimaryKeyName(_modelName: string): string {\n return 'id';\n }\n\n isValidModel(modelName: unknown): modelName is string {\n if (typeof modelName !== 'string') {\n return false;\n }\n\n if (modelName.startsWith('$')) {\n return false;\n }\n\n return !!this.prisma[modelName];\n }\n\n transformValue(_modelName: string, key: string, value: string): unknown {\n if (key === 'id' || key.endsWith('Id')) {\n const num = parseInt(value, 10);\n if (!isNaN(num) && num.toString() === value && Number.isSafeInteger(num)) {\n return num;\n }\n }\n\n if (isUUID(value)) {\n return value;\n }\n\n return value;\n }\n\n supportsSoftDeletes(_modelName: string): boolean {\n return false;\n }\n\n getModelMetadata(modelName: string): ModelMetadata {\n return {\n name: modelName,\n primaryKey: this.getPrimaryKeyName(modelName),\n softDeletes: false,\n adapter: this.name,\n };\n }\n\n private buildIncludeOptions(\n includes: string[] | Record<string, unknown>\n ): Record<string, unknown> {\n if (Array.isArray(includes)) {\n return includes.reduce<Record<string, boolean>>((acc, relation) => {\n acc[relation] = true;\n return acc;\n }, {});\n }\n\n return Object.entries(includes).reduce<Record<string, unknown>>((acc, [relation, opts]) => {\n if (typeof opts === 'boolean') {\n acc[relation] = opts;\n } else if (typeof opts === 'object' && opts !== null) {\n const nestedOpts = opts as Record<string, unknown>;\n acc[relation] = {\n ...nestedOpts,\n include: nestedOpts.include\n ? this.buildIncludeOptions(nestedOpts.include as string[] | Record<string, unknown>)\n : undefined,\n };\n }\n return acc;\n }, {});\n }\n}\n","import { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { ModelBinder } from '../core/ModelBinder';\nimport { BindOptions, ModelBindingsConfig } from '../core/types';\nimport { logger } from '../utils/logger';\n\n/**\n * Create middleware that binds a model to a route parameter\n *\n * @param paramName - The route parameter name (without ':')\n * @param model - The model class/schema/table\n * @param options - Binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/:user', bindModel('user', User), (req, res) => {\n * res.json(req.user);\n * });\n */\nexport function bindModel(\n paramName: string,\n model: unknown,\n options: BindOptions = {}\n): RequestHandler {\n return async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n // Check if parameter exists in route\n if (!(paramName in req.params)) {\n logger.warn(`Parameter '${paramName}' not found in route`);\n if (options.optional) {\n return next();\n }\n }\n\n // Perform the binding\n const result = await ModelBinder.bind(req, res, paramName, model, options);\n\n if (!result.success) {\n return next(result.error);\n }\n\n next();\n } catch (error) {\n next(error);\n }\n };\n}\n\n/**\n * Bind multiple models in a single middleware\n *\n * @param bindings - Object mapping parameter names to model configs\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/:user/posts/:post',\n * bindModels({\n * user: { model: User },\n * post: { model: Post, options: { include: ['comments'] } }\n * }),\n * (req, res) => {\n * res.json({ user: req.user, post: req.post });\n * }\n * );\n */\nexport function bindModels(bindings: ModelBindingsConfig): RequestHandler {\n return async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n // Bind all models sequentially\n for (const [paramName, config] of Object.entries(bindings)) {\n if (!(paramName in req.params)) {\n logger.warn(`Parameter '${paramName}' not found in route`);\n if (config.options?.optional) {\n continue;\n }\n }\n\n const result = await ModelBinder.bind(\n req,\n res,\n paramName,\n config.model,\n config.options || {}\n );\n\n if (!result.success) {\n return next(result.error);\n }\n }\n\n next();\n } catch (error) {\n next(error);\n }\n };\n}\n\n/**\n * Bind a model optionally (don't throw 404 if not found)\n *\n * @param paramName - The route parameter name\n * @param model - The model class/schema/table\n * @param options - Binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/posts/:post?', bindOptional('post', Post), (req, res) => {\n * if (req.post) {\n * res.json(req.post);\n * } else {\n * res.json({ message: 'No specific post' });\n * }\n * });\n */\nexport function bindOptional(\n paramName: string,\n model: unknown,\n options: BindOptions = {}\n): RequestHandler {\n return bindModel(paramName, model, { ...options, optional: true });\n}\n\n/**\n * Create a middleware that binds a model using a custom key\n *\n * @param paramName - The route parameter name\n * @param model - The model class/schema/table\n * @param key - The field to search by\n * @param options - Additional binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/by-email/:email', bindByKey('email', User, 'email'), (req, res) => {\n * res.json(req.email);\n * });\n */\nexport function bindByKey(\n paramName: string,\n model: unknown,\n key: string,\n options: BindOptions = {}\n): RequestHandler {\n return bindModel(paramName, model, { ...options, key });\n}\n\n/**\n * Create a middleware that binds a model and attaches it with a custom name\n *\n * @param paramName - The route parameter name\n * @param model - The model class/schema/table\n * @param attachAs - The name to attach the model as on the request\n * @param options - Additional binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/:id', bindAs('id', User, 'currentUser'), (req, res) => {\n * res.json(req.currentUser);\n * });\n */\nexport function bindAs(\n paramName: string,\n model: unknown,\n attachAs: string,\n options: BindOptions = {}\n): RequestHandler {\n return bindModel(paramName, model, { ...options, as: attachAs });\n}\n\n/**\n * Create a middleware that binds a model with caching\n *\n * @param paramName - The route parameter name\n * @param model - The model class/schema/table\n * @param ttl - Cache TTL in milliseconds (default: 60000)\n * @param options - Additional binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/:user', bindCached('user', User, 300000), (req, res) => {\n * res.json(req.user);\n * });\n */\nexport function bindCached(\n paramName: string,\n model: unknown,\n ttl: number = 60000,\n options: BindOptions = {}\n): RequestHandler {\n return bindModel(paramName, model, { ...options, cache: true, cacheTTL: ttl });\n}\n\n/**\n * Create a middleware that binds a model with eager-loaded relations\n *\n * @param paramName - The route parameter name\n * @param model - The model class/schema/table\n * @param relations - Relations to eager load\n * @param options - Additional binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/:user', bindWithRelations('user', User, ['posts', 'profile']), (req, res) => {\n * res.json(req.user);\n * });\n */\nexport function bindWithRelations(\n paramName: string,\n model: unknown,\n relations: string[] | Record<string, unknown>,\n options: BindOptions = {}\n): RequestHandler {\n return bindModel(paramName, model, { ...options, include: relations });\n}\n","import { isNumeric, isUUID, isObjectId } from './validators';\n\n/**\n * Transform a string value to a number if it's numeric\n */\nexport function toNumber(value: string): number | string {\n if (isNumeric(value)) {\n const num = parseInt(value, 10);\n if (!isNaN(num) && Number.isSafeInteger(num)) {\n return num;\n }\n }\n return value;\n}\n\n/**\n * Transform a string value to a float if it's a valid decimal\n */\nexport function toFloat(value: string): number | string {\n const num = parseFloat(value);\n if (!isNaN(num) && isFinite(num)) {\n return num;\n }\n return value;\n}\n\n/**\n * Transform a string value to a boolean\n */\nexport function toBoolean(value: string): boolean {\n const lowered = value.toLowerCase();\n return lowered === 'true' || lowered === '1' || lowered === 'yes';\n}\n\n/**\n * Transform a string to lowercase\n */\nexport function toLowerCase(value: string): string {\n return value.toLowerCase();\n}\n\n/**\n * Transform a string to uppercase\n */\nexport function toUpperCase(value: string): string {\n return value.toUpperCase();\n}\n\n/**\n * Trim whitespace from a string\n */\nexport function trim(value: string): string {\n return value.trim();\n}\n\n/**\n * Transform a slug to underscore format\n */\nexport function slugToUnderscore(value: string): string {\n return value.replace(/-/g, '_');\n}\n\n/**\n * Transform underscores to dashes (slug format)\n */\nexport function underscoreToSlug(value: string): string {\n return value.replace(/_/g, '-');\n}\n\n/**\n * Auto-detect and transform value based on format\n */\nexport function autoTransform(value: string): unknown {\n // Check if it's a UUID - keep as string\n if (isUUID(value)) {\n return value;\n }\n\n // Check if it's a MongoDB ObjectId - keep as string\n if (isObjectId(value)) {\n return value;\n }\n\n // Check if it's a pure integer\n if (/^\\d+$/.test(value)) {\n const num = parseInt(value, 10);\n if (!isNaN(num) && Number.isSafeInteger(num)) {\n return num;\n }\n }\n\n // Check if it's a negative integer\n if (/^-\\d+$/.test(value)) {\n const num = parseInt(value, 10);\n if (!isNaN(num) && Number.isSafeInteger(num)) {\n return num;\n }\n }\n\n return value;\n}\n\n/**\n * Create a composed transformer from multiple transform functions\n */\nexport function compose(\n ...transformers: Array<(value: string) => unknown>\n): (value: string) => unknown {\n return (value: string): unknown => {\n let result: unknown = value;\n for (const transformer of transformers) {\n result = transformer(String(result));\n }\n return result;\n };\n}\n\n/**\n * Identity transformer - returns the value unchanged\n */\nexport function identity<T>(value: T): T {\n return value;\n}\n"],"mappings":"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","names":["attachAs"]}
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors/index.ts","../src/utils/cache.ts","../src/utils/logger.ts","../src/core/ModelBinder.ts","../src/core/BaseAdapter.ts","../src/core/types.ts","../src/utils/validators.ts","../src/adapters/KnexAdapter.ts","../src/adapters/MongooseAdapter.ts","../src/adapters/TypeORMAdapter.ts","../src/adapters/SequelizeAdapter.ts","../src/adapters/PrismaAdapter.ts","../src/middleware/bindModel.ts","../src/utils/transformers.ts","../src/index.ts"],"sourcesContent":["/**\n * Base error class for model binding errors\n */\nexport class BindingError extends Error {\n public readonly originalError?: Error;\n\n constructor(message: string, originalError?: Error) {\n super(message);\n this.name = 'BindingError';\n this.originalError = originalError;\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n originalError: this.originalError?.message,\n };\n }\n}\n\n/**\n * Error thrown when a model is not found (404)\n */\nexport class ModelNotFoundError extends Error {\n public readonly statusCode = 404;\n public readonly paramName: string;\n public readonly paramValue: string;\n public readonly modelName: string;\n\n constructor(paramName: string, paramValue: string, modelName: string, customMessage?: string) {\n super(customMessage || `${modelName} not found with ${paramName} = ${paramValue}`);\n this.name = 'ModelNotFoundError';\n this.paramName = paramName;\n this.paramValue = paramValue;\n this.modelName = modelName;\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n error: 'Not Found',\n message: this.message,\n statusCode: this.statusCode,\n param: this.paramName,\n value: this.paramValue,\n model: this.modelName,\n };\n }\n}\n\n/**\n * Error thrown when no adapter is configured\n */\nexport class AdapterNotSetError extends Error {\n constructor(\n message: string = 'No adapter set. Call ModelBinder.setAdapter() before using model binding.'\n ) {\n super(message);\n this.name = 'AdapterNotSetError';\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n };\n }\n}\n\n/**\n * Error thrown when a model is invalid for an adapter\n */\nexport class InvalidModelError extends Error {\n public readonly model: unknown;\n\n constructor(message: string, model: unknown) {\n super(message);\n this.name = 'InvalidModelError';\n this.model = model;\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n model: typeof this.model === 'string' ? this.model : String(this.model),\n };\n }\n}\n\n/**\n * Error thrown when validation fails\n */\nexport class ValidationError extends Error {\n public readonly statusCode: number;\n public readonly details?: unknown;\n\n constructor(message: string, statusCode: number = 400, details?: unknown) {\n super(message);\n this.name = 'ValidationError';\n this.statusCode = statusCode;\n this.details = details;\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n statusCode: this.statusCode,\n details: this.details,\n };\n }\n}\n","import { CacheEntry } from '../core/types';\n\n/**\n * Simple in-memory cache for model binding\n */\nexport class Cache {\n private store = new Map<string, CacheEntry>();\n private maxSize: number;\n\n constructor(maxSize: number = 1000) {\n this.maxSize = maxSize;\n }\n\n /**\n * Get a value from cache\n */\n get<T = unknown>(key: string): T | null {\n const entry = this.store.get(key);\n\n if (!entry) {\n return null;\n }\n\n // Check if expired\n if (Date.now() - entry.timestamp > entry.ttl) {\n this.store.delete(key);\n return null;\n }\n\n return entry.value as T;\n }\n\n /**\n * Set a value in cache\n */\n set<T = unknown>(key: string, value: T, ttl: number): void {\n // Evict oldest entries if cache is full\n if (this.store.size >= this.maxSize) {\n const firstKey = this.store.keys().next().value;\n if (firstKey) {\n this.store.delete(firstKey);\n }\n }\n\n this.store.set(key, {\n value,\n timestamp: Date.now(),\n ttl,\n });\n }\n\n /**\n * Delete a value from cache\n */\n delete(key: string): boolean {\n return this.store.delete(key);\n }\n\n /**\n * Clear all cached values\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Get cache size\n */\n get size(): number {\n return this.store.size;\n }\n\n /**\n * Check if key exists and is not expired\n */\n has(key: string): boolean {\n return this.get(key) !== null;\n }\n\n /**\n * Get all keys in the cache\n */\n keys(): string[] {\n return Array.from(this.store.keys());\n }\n\n /**\n * Remove expired entries\n */\n prune(): number {\n let removed = 0;\n const now = Date.now();\n\n for (const [key, entry] of this.store.entries()) {\n if (now - entry.timestamp > entry.ttl) {\n this.store.delete(key);\n removed++;\n }\n }\n\n return removed;\n }\n\n /**\n * Get cache statistics\n */\n getStats(): { size: number; maxSize: number } {\n return {\n size: this.store.size,\n maxSize: this.maxSize,\n };\n }\n}\n","/**\n * Log levels for the logger\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * Logger configuration\n */\nexport interface LoggerConfig {\n enabled: boolean;\n level: LogLevel;\n prefix: string;\n}\n\n/**\n * Simple logger utility for debugging\n */\nclass Logger {\n private config: LoggerConfig = {\n enabled: false,\n level: 'info',\n prefix: '[express-model-binding]',\n };\n\n private levelPriority: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n };\n\n /**\n * Enable debug logging\n */\n enable(): void {\n this.config.enabled = true;\n }\n\n /**\n * Disable debug logging\n */\n disable(): void {\n this.config.enabled = false;\n }\n\n /**\n * Check if logging is enabled\n */\n isEnabled(): boolean {\n return this.config.enabled;\n }\n\n /**\n * Set log level\n */\n setLevel(level: LogLevel): void {\n this.config.level = level;\n }\n\n /**\n * Get current log level\n */\n getLevel(): LogLevel {\n return this.config.level;\n }\n\n /**\n * Set custom prefix\n */\n setPrefix(prefix: string): void {\n this.config.prefix = prefix;\n }\n\n /**\n * Check if a message at the given level should be logged\n */\n private shouldLog(level: LogLevel): boolean {\n if (!this.config.enabled) {\n return false;\n }\n return this.levelPriority[level] >= this.levelPriority[this.config.level];\n }\n\n /**\n * Format log message\n */\n private formatMessage(level: LogLevel, message: string): string {\n const timestamp = new Date().toISOString();\n return `${this.config.prefix} [${timestamp}] [${level.toUpperCase()}] ${message}`;\n }\n\n /**\n * Log a debug message\n */\n debug(message: string, context?: unknown): void {\n if (this.shouldLog('debug')) {\n console.log(this.formatMessage('debug', message), context !== undefined ? context : '');\n }\n }\n\n /**\n * Log an info message\n */\n info(message: string, context?: unknown): void {\n if (this.shouldLog('info')) {\n console.info(this.formatMessage('info', message), context !== undefined ? context : '');\n }\n }\n\n /**\n * Log a warning message\n */\n warn(message: string, context?: unknown): void {\n if (this.shouldLog('warn')) {\n console.warn(this.formatMessage('warn', message), context !== undefined ? context : '');\n }\n }\n\n /**\n * Log an error message\n */\n error(message: string, error?: unknown): void {\n if (this.shouldLog('error')) {\n console.error(this.formatMessage('error', message), error !== undefined ? error : '');\n }\n }\n\n /**\n * Reset logger to default configuration\n */\n reset(): void {\n this.config = {\n enabled: false,\n level: 'info',\n prefix: '[express-model-binding]',\n };\n }\n\n /**\n * Get current configuration\n */\n getConfig(): LoggerConfig {\n return { ...this.config };\n }\n}\n\nexport const logger = new Logger();\n","import { Request, Response } from 'express';\nimport { IORMAdapter, BindOptions, BindingContext, BindingResult } from './types';\nimport { AdapterNotSetError, ModelNotFoundError, BindingError } from '../errors';\nimport { Cache } from '../utils/cache';\nimport { logger } from '../utils/logger';\n\n/**\n * Express request with bound models\n */\ninterface RequestWithModels extends Request {\n [key: string]: unknown;\n}\n\n/**\n * Central model binding orchestrator\n */\nexport class ModelBinder {\n private static adapter: IORMAdapter | null = null;\n private static cache = new Cache();\n private static debug = false;\n\n static setAdapter(adapter: IORMAdapter): void {\n if (!adapter) {\n throw new Error('Adapter cannot be null or undefined');\n }\n this.adapter = adapter;\n logger.debug(`Adapter set: ${adapter.name}`);\n }\n\n static getAdapter(): IORMAdapter {\n if (!this.adapter) {\n throw new AdapterNotSetError(\n 'No adapter set. Call ModelBinder.setAdapter() before using model binding.'\n );\n }\n return this.adapter;\n }\n\n static hasAdapter(): boolean {\n return this.adapter !== null;\n }\n\n static clearAdapter(): void {\n this.adapter = null;\n logger.debug('Adapter cleared');\n }\n\n static setDebug(enabled: boolean): void {\n this.debug = enabled;\n if (enabled) {\n logger.enable();\n } else {\n logger.disable();\n }\n }\n\n static isDebugEnabled(): boolean {\n return this.debug;\n }\n\n static clearCache(): void {\n this.cache.clear();\n logger.debug('Cache cleared');\n }\n\n static getCacheStats(): { size: number; maxSize: number } {\n return this.cache.getStats();\n }\n\n static async bind(\n req: Request,\n res: Response,\n paramName: string,\n model: unknown,\n options: BindOptions = {}\n ): Promise<BindingResult> {\n const startTime = Date.now();\n const adapter = this.getAdapter();\n const paramValue = req.params[paramName];\n\n const context: BindingContext = {\n req,\n res,\n paramName,\n paramValue,\n model,\n options,\n adapter,\n startTime,\n };\n\n try {\n if (paramValue === undefined || paramValue === null || paramValue === '') {\n if (options.optional) {\n const attachAs = options.as || paramName;\n this.attachToRequest(req, attachAs, undefined);\n\n return {\n success: true,\n model: undefined,\n duration: Date.now() - startTime,\n };\n }\n\n throw new BindingError(\n `Parameter '${paramName}' is required but was not provided`,\n new Error('Missing parameter')\n );\n }\n\n if (!adapter.isValidModel(model)) {\n throw new BindingError(\n `Invalid model for ${adapter.name} adapter`,\n new Error('Model validation failed')\n );\n }\n\n const key = options.key || adapter.getPrimaryKeyName(model);\n\n let value: unknown = context.paramValue;\n if (options.transformValue) {\n value = options.transformValue(paramValue);\n } else {\n value = adapter.transformValue(model, key, paramValue);\n }\n\n const cacheKey = this.getCacheKey(model, key, value, options);\n if (options.cache) {\n const cached = this.cache.get(cacheKey);\n if (cached !== null) {\n logger.debug(`Cache hit for ${paramName}:${value}`);\n\n const attachAs = options.as || paramName;\n this.attachToRequest(req, attachAs, cached);\n\n return {\n success: true,\n model: cached,\n duration: Date.now() - startTime,\n fromCache: true,\n };\n }\n }\n\n logger.debug(`Fetching ${paramName}:${value} using ${adapter.name}`);\n const result = await adapter.findByKey(model, key, value, options);\n\n if (!result) {\n if (options.optional) {\n const attachAs = options.as || paramName;\n this.attachToRequest(req, attachAs, undefined);\n\n return {\n success: true,\n model: undefined,\n duration: Date.now() - startTime,\n };\n }\n\n let error: Error;\n if (options.errorMessage) {\n error = new ModelNotFoundError(\n paramName,\n String(value),\n this.getModelName(model),\n options.errorMessage\n );\n } else if (options.onNotFound) {\n error =\n typeof options.onNotFound === 'function'\n ? options.onNotFound(paramName, String(value))\n : options.onNotFound;\n } else {\n error = new ModelNotFoundError(paramName, String(value), this.getModelName(model));\n }\n\n throw error;\n }\n\n if (options.validate) {\n await options.validate(result, req);\n }\n\n if (options.cache) {\n const ttl = options.cacheTTL || (typeof options.cache === 'number' ? options.cache : 60000);\n this.cache.set(cacheKey, result, ttl);\n logger.debug(`Cached ${paramName}:${value} for ${ttl}ms`);\n }\n\n const attachAs = options.as || paramName;\n this.attachToRequest(req, attachAs, result);\n\n logger.debug(`Successfully bound ${paramName}:${value}`);\n\n return {\n success: true,\n model: result,\n duration: Date.now() - startTime,\n fromCache: false,\n };\n } catch (error) {\n logger.error(`Failed to bind ${paramName}:${context.paramValue}`, error);\n\n return {\n success: false,\n error: error as Error,\n duration: Date.now() - startTime,\n };\n }\n }\n\n private static attachToRequest(req: Request, key: string, value: unknown): void {\n (req as RequestWithModels)[key] = value;\n }\n\n private static getCacheKey(\n model: unknown,\n key: string,\n value: unknown,\n options: BindOptions\n ): string {\n const modelName = this.getModelName(model);\n const optionsHash = JSON.stringify({\n key,\n include: options.include,\n where: options.where,\n select: options.select,\n });\n\n return `${modelName}:${key}:${String(value)}:${optionsHash}`;\n }\n\n private static getModelName(model: unknown): string {\n if (typeof model === 'string') {\n return model;\n }\n if (model && typeof model === 'object') {\n const obj = model as Record<string, unknown>;\n if (typeof obj.name === 'string') return obj.name;\n if (typeof obj.modelName === 'string') return obj.modelName;\n if (typeof obj.tableName === 'string') return obj.tableName;\n }\n if (model && typeof model === 'function') {\n return (model as { name: string }).name || 'Unknown';\n }\n return 'Unknown';\n }\n\n static reset(): void {\n this.adapter = null;\n this.cache.clear();\n this.debug = false;\n logger.disable();\n }\n}\n","import { IORMAdapter, QueryOptions, ModelMetadata, QueryModifier } from './types';\nimport { InvalidModelError } from '../errors';\n\n/**\n * Abstract base class providing common adapter functionality.\n * Extend this class to implement ORM-specific adapters.\n *\n * @typeParam TModel - Model type accepted by this adapter\n * @typeParam TResult - Result type returned by queries\n * @typeParam TQueryBuilder - ORM-specific query builder type\n */\nexport abstract class BaseAdapter<\n TModel = unknown,\n TResult = unknown,\n TQueryBuilder = unknown,\n> implements IORMAdapter<TModel, TResult> {\n abstract readonly name: string;\n\n abstract findByKey(\n model: TModel,\n key: string,\n value: unknown,\n options?: QueryOptions\n ): Promise<TResult | null>;\n\n abstract getPrimaryKeyName(model: TModel): string;\n\n abstract isValidModel(model: unknown): model is TModel;\n\n transformValue(_model: TModel, _key: string, value: string): unknown {\n if (/^\\d+$/.test(value)) {\n const num = parseInt(value, 10);\n if (!isNaN(num) && Number.isSafeInteger(num)) {\n return num;\n }\n }\n return value;\n }\n\n supportsSoftDeletes(_model: TModel): boolean {\n return false;\n }\n\n getModelMetadata(model: TModel): ModelMetadata {\n return {\n name: this.getModelName(model),\n primaryKey: this.getPrimaryKeyName(model),\n softDeletes: this.supportsSoftDeletes(model),\n adapter: this.name,\n };\n }\n\n protected validateModel(model: unknown): asserts model is TModel {\n if (!this.isValidModel(model)) {\n throw new InvalidModelError(`Invalid model for ${this.name} adapter`, model);\n }\n }\n\n protected getModelName(model: TModel): string {\n if (typeof model === 'string') {\n return model;\n }\n if (model && typeof model === 'object') {\n const obj = model as Record<string, unknown>;\n if (typeof obj.name === 'string') return obj.name;\n if (typeof obj.modelName === 'string') return obj.modelName;\n if (typeof obj.tableName === 'string') return obj.tableName;\n }\n if (model && typeof model === 'function') {\n return (model as { name: string }).name || 'Unknown';\n }\n return 'Unknown';\n }\n\n protected applySoftDeleteFilter(\n queryBuilder: TQueryBuilder,\n _options?: QueryOptions\n ): TQueryBuilder {\n return queryBuilder;\n }\n\n protected applyIncludes(\n queryBuilder: TQueryBuilder,\n _includes?: string[] | Record<string, unknown>\n ): TQueryBuilder {\n return queryBuilder;\n }\n\n protected applySelect(queryBuilder: TQueryBuilder, _select?: string[]): TQueryBuilder {\n return queryBuilder;\n }\n\n protected applyWhereConditions(\n queryBuilder: TQueryBuilder,\n _where?: Record<string, unknown>\n ): TQueryBuilder {\n return queryBuilder;\n }\n\n protected applyCustomQuery(\n queryBuilder: TQueryBuilder,\n queryFn?: QueryModifier<TQueryBuilder>\n ): TQueryBuilder {\n if (queryFn) {\n return queryFn(queryBuilder) as TQueryBuilder;\n }\n return queryBuilder;\n }\n}\n","import { Request, Response, NextFunction, RequestHandler } from 'express';\n\n/**\n * Generic query builder type - adapters can narrow this to their specific type\n */\nexport type QueryBuilder<T = unknown> = T;\n\n/**\n * Query modifier function type\n */\nexport type QueryModifier<T = unknown> = (queryBuilder: QueryBuilder<T>) => QueryBuilder<T>;\n\n/**\n * Base adapter interface that all ORM adapters must implement\n */\nexport interface IORMAdapter<TModel = unknown, TResult = unknown> {\n readonly name: string;\n\n findByKey(\n model: TModel,\n key: string,\n value: unknown,\n options?: QueryOptions\n ): Promise<TResult | null>;\n\n getPrimaryKeyName(model: TModel): string;\n\n isValidModel(model: unknown): model is TModel;\n\n transformValue(model: TModel, key: string, value: string): unknown;\n\n supportsSoftDeletes(model: TModel): boolean;\n\n getModelMetadata?(model: TModel): ModelMetadata;\n}\n\n/**\n * Query options for model lookups\n */\nexport interface QueryOptions {\n /**\n * Relations to eager load\n */\n include?: string[] | Record<string, unknown>;\n\n /**\n * Additional WHERE conditions\n */\n where?: Record<string, unknown>;\n\n /**\n * Custom query modifier - receives ORM-specific query builder\n */\n query?: QueryModifier;\n\n /**\n * Fields to select\n */\n select?: string[];\n\n /**\n * Include soft-deleted records\n */\n withTrashed?: boolean;\n\n /**\n * Only return soft-deleted records\n */\n onlyTrashed?: boolean;\n\n /**\n * Enable result caching\n */\n cache?: boolean | number;\n\n /**\n * Row locking for transactions\n */\n lock?: 'forUpdate' | 'forShare';\n}\n\n/**\n * Binding middleware options\n */\nexport interface BindOptions extends QueryOptions {\n /**\n * Field to search by (defaults to primary key)\n */\n key?: string;\n\n /**\n * Custom error when model not found\n */\n onNotFound?: Error | ((paramName: string, paramValue: string) => Error);\n\n /**\n * Transform parameter value before querying\n */\n transformValue?: (value: string) => unknown;\n\n /**\n * Property name for attaching model to request\n */\n as?: string;\n\n /**\n * Don't throw if model not found\n */\n optional?: boolean;\n\n /**\n * Custom 404 message\n */\n errorMessage?: string;\n\n /**\n * Validate loaded model\n */\n validate?: (model: unknown, req: Request) => void | Promise<void>;\n\n /**\n * Enable caching\n */\n cache?: boolean;\n\n /**\n * Cache TTL in milliseconds\n */\n cacheTTL?: number;\n}\n\n/**\n * Multi-model binding configuration\n */\nexport interface ModelBindingsConfig {\n [paramName: string]: {\n model: unknown;\n options?: BindOptions;\n };\n}\n\n/**\n * Binding operation context\n */\nexport interface BindingContext {\n req: Request;\n res: Response;\n paramName: string;\n paramValue: string;\n model: unknown;\n options: BindOptions;\n adapter: IORMAdapter;\n startTime: number;\n}\n\n/**\n * Binding operation result\n */\nexport interface BindingResult {\n success: boolean;\n model?: unknown;\n error?: Error;\n duration: number;\n fromCache?: boolean;\n}\n\n/**\n * Model metadata for debugging\n */\nexport interface ModelMetadata {\n name: string;\n primaryKey: string;\n tableName?: string;\n relations?: string[];\n softDeletes: boolean;\n adapter?: string;\n [key: string]: unknown;\n}\n\n/**\n * Cache entry structure\n */\nexport interface CacheEntry<T = unknown> {\n value: T;\n timestamp: number;\n ttl: number;\n}\n\n/**\n * Global configuration options\n */\nexport interface ModelBindingGlobalConfig {\n adapter?: IORMAdapter;\n cache?: {\n enabled: boolean;\n ttl: number;\n maxSize?: number;\n };\n debug?: boolean;\n logger?: (message: string, context?: unknown) => void;\n onError?: (error: Error, context: BindingContext) => void;\n}\n\n/**\n * Express request with bound models\n */\nexport interface TypedRequest<\n P = Record<string, string>,\n ResBody = unknown,\n ReqBody = unknown,\n ReqQuery = unknown,\n Models extends Record<string, unknown> = Record<string, unknown>,\n> extends Request<P, ResBody, ReqBody, ReqQuery> {\n [K: string]: unknown;\n models?: Models;\n}\n\n/**\n * Extract model type from binding config\n */\nexport type ExtractModelType<T> = T extends { model: infer M } ? M : never;\n\n/**\n * Typed request handler\n */\nexport type TypedRequestHandler<\n Models extends Record<string, unknown> = Record<string, unknown>,\n P = Record<string, string>,\n ResBody = unknown,\n ReqBody = unknown,\n ReqQuery = unknown,\n> = (\n req: TypedRequest<P, ResBody, ReqBody, ReqQuery, Models>,\n res: Response<ResBody>,\n next: NextFunction\n) => void | Promise<void>;\n\n/**\n * Middleware function type\n */\nexport type MiddlewareFunction = RequestHandler;\n\n/**\n * Operator condition for advanced WHERE clauses\n */\nexport interface OperatorCondition {\n operator: string;\n value: unknown;\n}\n\n/**\n * Check if value is an operator condition\n */\nexport function isOperatorCondition(value: unknown): value is OperatorCondition {\n return typeof value === 'object' && value !== null && 'operator' in value && 'value' in value;\n}\n","/**\n * UUID regex pattern\n */\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/**\n * MongoDB ObjectId regex pattern (24 hex characters)\n */\nconst OBJECT_ID_REGEX = /^[0-9a-f]{24}$/i;\n\n/**\n * Check if a value is a valid UUID\n */\nexport function isUUID(value: string): boolean {\n return UUID_REGEX.test(value);\n}\n\n/**\n * Check if a value is a valid MongoDB ObjectId\n */\nexport function isObjectId(value: string): boolean {\n return OBJECT_ID_REGEX.test(value);\n}\n\n/**\n * Check if a value is a numeric string\n */\nexport function isNumeric(value: string): boolean {\n return /^-?\\d+$/.test(value);\n}\n\n/**\n * Check if a value is a valid positive integer\n */\nexport function isPositiveInteger(value: string): boolean {\n return /^\\d+$/.test(value) && parseInt(value, 10) > 0;\n}\n\n/**\n * Check if a value is a valid slug (lowercase alphanumeric with hyphens)\n */\nexport function isSlug(value: string): boolean {\n return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value);\n}\n\n/**\n * Check if a value is a valid email\n */\nexport function isEmail(value: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value);\n}\n\n/**\n * Validate that a value is not empty\n */\nexport function isNotEmpty(value: unknown): boolean {\n if (value === null || value === undefined) {\n return false;\n }\n if (typeof value === 'string') {\n return value.trim().length > 0;\n }\n return true;\n}\n\n/**\n * Validate that a value is a non-empty string\n */\nexport function isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\n/**\n * Validate that a value is a plain object\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Validate that a value is a function\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function isFunction(value: unknown): value is Function {\n return typeof value === 'function';\n}\n\n/**\n * Validate route parameter name\n */\nexport function isValidParamName(value: string): boolean {\n return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(value);\n}\n","import type { Knex } from 'knex';\nimport { BaseAdapter } from '../core/BaseAdapter';\nimport { QueryOptions, ModelMetadata, isOperatorCondition } from '../core/types';\nimport { BindingError } from '../errors';\nimport { isUUID } from '../utils/validators';\n\n/**\n * Model definition for Knex tables with soft delete support\n */\nexport interface KnexModel {\n tableName: string;\n primaryKey?: string;\n softDeleteColumn?: string;\n}\n\n/**\n * Union type for Knex model inputs\n */\nexport type KnexModelInput = string | KnexModel;\n\n/**\n * Type guard for KnexModel\n */\nfunction isKnexModel(value: unknown): value is KnexModel {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as KnexModel).tableName === 'string'\n );\n}\n\n/**\n * Adapter for Knex query builder supporting PostgreSQL, MySQL, SQLite, MSSQL, Oracle\n */\nexport class KnexAdapter extends BaseAdapter<\n KnexModelInput,\n Record<string, unknown>,\n Knex.QueryBuilder\n> {\n readonly name = 'knex';\n\n constructor(private knex: Knex) {\n super();\n }\n\n getKnex(): Knex {\n return this.knex;\n }\n\n async findByKey(\n model: KnexModelInput,\n key: string,\n value: unknown,\n options: QueryOptions = {}\n ): Promise<Record<string, unknown> | null> {\n this.validateModel(model);\n\n const tableName = this.getTableName(model);\n\n try {\n let query = this.knex(tableName);\n\n query = query.where(key, value as Knex.Value);\n\n if (this.supportsSoftDeletes(model) && !options.withTrashed && !options.onlyTrashed) {\n const softDeleteColumn = this.getSoftDeleteColumn(model);\n query = query.whereNull(softDeleteColumn);\n } else if (options.onlyTrashed && this.supportsSoftDeletes(model)) {\n const softDeleteColumn = this.getSoftDeleteColumn(model);\n query = query.whereNotNull(softDeleteColumn);\n }\n\n if (options.where) {\n query = this.applyWhereConditions(query, options.where);\n }\n\n if (options.select && options.select.length > 0) {\n query = query.select(options.select);\n } else {\n query = query.select('*');\n }\n\n if (options.query) {\n query = this.applyCustomQuery(\n query,\n options.query as (qb: Knex.QueryBuilder) => Knex.QueryBuilder\n );\n }\n\n if (options.lock === 'forUpdate') {\n query = query.forUpdate();\n } else if (options.lock === 'forShare') {\n query = query.forShare();\n }\n\n const result = await query.first();\n return (result as Record<string, unknown>) || null;\n } catch (error) {\n throw new BindingError(\n `Failed to fetch ${this.getModelName(model)}: ${(error as Error).message}`,\n error as Error\n );\n }\n }\n\n getPrimaryKeyName(model: KnexModelInput): string {\n if (isKnexModel(model) && model.primaryKey) {\n return model.primaryKey;\n }\n return 'id';\n }\n\n isValidModel(model: unknown): model is KnexModelInput {\n return typeof model === 'string' || isKnexModel(model);\n }\n\n transformValue(model: KnexModelInput, key: string, value: string): unknown {\n const primaryKey = this.getPrimaryKeyName(model);\n\n if (key === primaryKey || key === 'id') {\n const num = parseInt(value, 10);\n if (!isNaN(num) && num.toString() === value && Number.isSafeInteger(num)) {\n return num;\n }\n }\n\n if (isUUID(value)) {\n return value;\n }\n\n return value;\n }\n\n supportsSoftDeletes(model: KnexModelInput): boolean {\n return isKnexModel(model) && !!model.softDeleteColumn;\n }\n\n getModelMetadata(model: KnexModelInput): ModelMetadata {\n return {\n name: this.getModelName(model),\n primaryKey: this.getPrimaryKeyName(model),\n tableName: this.getTableName(model),\n softDeletes: this.supportsSoftDeletes(model),\n adapter: this.name,\n };\n }\n\n private getTableName(model: KnexModelInput): string {\n return typeof model === 'string' ? model : model.tableName;\n }\n\n private getSoftDeleteColumn(model: KnexModelInput): string {\n if (isKnexModel(model) && model.softDeleteColumn) {\n return model.softDeleteColumn;\n }\n return 'deleted_at';\n }\n\n protected applyWhereConditions(\n query: Knex.QueryBuilder,\n where: Record<string, unknown>\n ): Knex.QueryBuilder {\n Object.entries(where).forEach(([column, value]) => {\n if (value === null) {\n query = query.whereNull(column);\n } else if (Array.isArray(value)) {\n query = query.whereIn(column, value as Knex.Value[]);\n } else if (isOperatorCondition(value)) {\n query = query.where(column, value.operator, value.value as Knex.Value);\n } else {\n query = query.where(column, value as Knex.Value);\n }\n });\n return query;\n }\n}\n\n/**\n * Create a Knex model definition\n */\nexport function defineKnexModel(config: {\n tableName: string;\n primaryKey?: string;\n softDeleteColumn?: string;\n}): KnexModel {\n return {\n tableName: config.tableName,\n primaryKey: config.primaryKey || 'id',\n softDeleteColumn: config.softDeleteColumn,\n };\n}\n","import type { Model, Document, Query, PopulateOptions, Schema } from 'mongoose';\nimport { BaseAdapter } from '../core/BaseAdapter';\nimport { QueryOptions, ModelMetadata, QueryModifier } from '../core/types';\nimport { BindingError } from '../errors';\nimport { isObjectId } from '../utils/validators';\n\n/**\n * Mongoose model type with required schema property\n */\ninterface MongooseModel extends Model<Document> {\n schema: Schema;\n modelName: string;\n}\n\n/**\n * Mongoose query type\n */\ntype MongooseQuery = Query<Document | null, Document>;\n\n/**\n * Type guard for Mongoose schema path\n */\ninterface SchemaPathType {\n instance: string;\n}\n\nfunction isSchemaPathType(value: unknown): value is SchemaPathType {\n return typeof value === 'object' && value !== null && 'instance' in value;\n}\n\n/**\n * Adapter for MongoDB using Mongoose ODM\n */\nexport class MongooseAdapter extends BaseAdapter<MongooseModel, Document, MongooseQuery> {\n readonly name = 'mongoose';\n\n async findByKey(\n model: MongooseModel,\n key: string,\n value: unknown,\n options: QueryOptions = {}\n ): Promise<Document | null> {\n this.validateModel(model);\n\n try {\n const transformedValue = this.transformValue(model, key, value as string);\n\n let query: MongooseQuery = model.findOne({ [key]: transformedValue });\n\n if (options.select && options.select.length > 0) {\n query = query.select(options.select.join(' '));\n }\n\n if (options.include) {\n query = this.applyIncludes(query, options.include);\n }\n\n if (options.where) {\n Object.entries(options.where).forEach(([field, val]) => {\n query = query.where(field).equals(val);\n });\n }\n\n if (options.query) {\n query = this.applyCustomQuery(query, options.query as QueryModifier<MongooseQuery>);\n }\n\n const result = await query.exec();\n\n if (result && this.supportsSoftDeletes(model)) {\n const doc = result as Document & {\n deleted?: boolean;\n deletedAt?: Date;\n isDeleted?: boolean;\n };\n const isDeleted = doc.deleted || doc.deletedAt || doc.isDeleted;\n\n if (!options.withTrashed && !options.onlyTrashed && isDeleted) {\n return null;\n }\n\n if (options.onlyTrashed && !isDeleted) {\n return null;\n }\n }\n\n return result;\n } catch (error) {\n throw new BindingError(\n `Failed to fetch ${model.modelName}: ${(error as Error).message}`,\n error as Error\n );\n }\n }\n\n getPrimaryKeyName(_model: MongooseModel): string {\n return '_id';\n }\n\n isValidModel(model: unknown): model is MongooseModel {\n if (!model || typeof model !== 'function') {\n return false;\n }\n const m = model as Partial<MongooseModel>;\n return (\n typeof m.findOne === 'function' && typeof m.modelName === 'string' && m.schema !== undefined\n );\n }\n\n transformValue(model: MongooseModel, key: string, value: string): unknown {\n if (key === '_id' || key === 'id') {\n if (isObjectId(value)) {\n try {\n // Mongoose must be loaded synchronously for ObjectId construction\n // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires\n const mongoose = require('mongoose');\n return new mongoose.Types.ObjectId(value);\n } catch {\n return value;\n }\n }\n return value;\n }\n\n const schemaType = model.schema.path(key);\n if (isSchemaPathType(schemaType) && schemaType.instance === 'Number') {\n const num = parseInt(value, 10);\n if (!isNaN(num)) {\n return num;\n }\n }\n\n return value;\n }\n\n supportsSoftDeletes(model: MongooseModel): boolean {\n const schema = model.schema;\n return (\n schema.path('deleted') !== undefined ||\n schema.path('deletedAt') !== undefined ||\n schema.path('isDeleted') !== undefined\n );\n }\n\n getModelMetadata(model: MongooseModel): ModelMetadata {\n const schema = model.schema;\n const paths = Object.keys(schema.paths);\n\n return {\n name: model.modelName,\n primaryKey: '_id',\n tableName: model.collection.name,\n softDeletes: this.supportsSoftDeletes(model),\n fields: paths,\n adapter: this.name,\n };\n }\n\n protected applyIncludes(\n query: MongooseQuery,\n includes: string[] | Record<string, unknown>\n ): MongooseQuery {\n if (Array.isArray(includes)) {\n includes.forEach(relation => {\n query = query.populate(relation);\n });\n } else {\n Object.entries(includes).forEach(([relation, options]) => {\n if (typeof options === 'boolean' && options) {\n query = query.populate(relation);\n } else if (typeof options === 'object' && options !== null) {\n query = query.populate({\n path: relation,\n ...options,\n } as PopulateOptions);\n }\n });\n }\n return query;\n }\n}\n","import type {\n DataSource,\n Repository,\n EntityTarget,\n ObjectLiteral,\n SelectQueryBuilder,\n} from 'typeorm';\nimport { BaseAdapter } from '../core/BaseAdapter';\nimport { QueryOptions, ModelMetadata, QueryModifier } from '../core/types';\nimport { BindingError } from '../errors';\nimport { isUUID } from '../utils/validators';\n\n/**\n * TypeORM entity type alias for better readability\n */\nexport type TypeORMEntity = EntityTarget<ObjectLiteral>;\n\n/**\n * TypeORM find options structure\n */\ninterface TypeORMFindOptions {\n where: Record<string, unknown>;\n select?: Record<string, boolean>;\n relations?: string[];\n withDeleted?: boolean;\n}\n\n/**\n * Adapter for TypeORM supporting SQL and NoSQL databases\n */\nexport class TypeORMAdapter extends BaseAdapter<\n TypeORMEntity,\n ObjectLiteral,\n SelectQueryBuilder<ObjectLiteral>\n> {\n readonly name = 'typeorm';\n\n constructor(private dataSource: DataSource) {\n super();\n }\n\n getDataSource(): DataSource {\n return this.dataSource;\n }\n\n async findByKey(\n entity: TypeORMEntity,\n key: string,\n value: unknown,\n options: QueryOptions = {}\n ): Promise<ObjectLiteral | null> {\n this.validateModel(entity);\n\n try {\n const repository = this.dataSource.getRepository(entity);\n const metadata = repository.metadata;\n\n const transformedValue = this.transformValue(entity, key, value as string);\n\n if (options.query || options.lock || options.onlyTrashed) {\n return await this.findWithQueryBuilder(repository, key, transformedValue, options);\n }\n\n const findOptions: TypeORMFindOptions = {\n where: { [key]: transformedValue },\n };\n\n if (options.select && options.select.length > 0) {\n findOptions.select = options.select.reduce<Record<string, boolean>>((acc, field) => {\n acc[field] = true;\n return acc;\n }, {});\n }\n\n if (options.include) {\n findOptions.relations = Array.isArray(options.include)\n ? options.include\n : Object.keys(options.include);\n }\n\n if (options.where) {\n findOptions.where = {\n ...findOptions.where,\n ...options.where,\n };\n }\n\n if (options.withTrashed && metadata.deleteDateColumn) {\n findOptions.withDeleted = true;\n }\n\n const result = await repository.findOne(findOptions);\n return result;\n } catch (error) {\n throw new BindingError(`Failed to fetch entity: ${(error as Error).message}`, error as Error);\n }\n }\n\n getPrimaryKeyName(entity: TypeORMEntity): string {\n try {\n const repository = this.dataSource.getRepository(entity);\n const metadata = repository.metadata;\n\n if (metadata.primaryColumns.length > 0) {\n return metadata.primaryColumns[0].propertyName;\n }\n } catch {\n // Fall through to default\n }\n return 'id';\n }\n\n isValidModel(model: unknown): model is TypeORMEntity {\n try {\n this.dataSource.getRepository(model as TypeORMEntity);\n return true;\n } catch {\n return false;\n }\n }\n\n transformValue(entity: TypeORMEntity, key: string, value: string): unknown {\n try {\n const repository = this.dataSource.getRepository(entity);\n const metadata = repository.metadata;\n const column = metadata.findColumnWithPropertyName(key);\n\n if (!column) {\n if (isUUID(value)) {\n return value;\n }\n const num = parseInt(value, 10);\n if (!isNaN(num) && num.toString() === value) {\n return num;\n }\n return value;\n }\n\n const columnType = String(column.type).toLowerCase();\n\n if (['int', 'integer', 'smallint', 'bigint', 'number'].includes(columnType)) {\n const num = parseInt(value, 10);\n return isNaN(num) ? value : num;\n }\n\n if (columnType === 'uuid') {\n return value;\n }\n\n if (columnType === 'boolean' || columnType === 'bool') {\n return value === 'true' || value === '1';\n }\n\n return value;\n } catch {\n return value;\n }\n }\n\n supportsSoftDeletes(entity: TypeORMEntity): boolean {\n try {\n const repository = this.dataSource.getRepository(entity);\n const metadata = repository.metadata;\n return !!metadata.deleteDateColumn;\n } catch {\n return false;\n }\n }\n\n getModelMetadata(entity: TypeORMEntity): ModelMetadata {\n try {\n const repository = this.dataSource.getRepository(entity);\n const metadata = repository.metadata;\n\n return {\n name: metadata.name,\n primaryKey: this.getPrimaryKeyName(entity),\n tableName: metadata.tableName,\n softDeletes: this.supportsSoftDeletes(entity),\n relations: metadata.relations.map(r => r.propertyName),\n adapter: this.name,\n };\n } catch {\n return {\n name: 'Unknown',\n primaryKey: 'id',\n softDeletes: false,\n adapter: this.name,\n };\n }\n }\n\n private async findWithQueryBuilder(\n repository: Repository<ObjectLiteral>,\n key: string,\n value: unknown,\n options: QueryOptions\n ): Promise<ObjectLiteral | null> {\n const metadata = repository.metadata;\n const alias = metadata.name.toLowerCase();\n\n let queryBuilder = repository\n .createQueryBuilder(alias)\n .where(`${alias}.${key} = :value`, { value });\n\n if (options.include) {\n const relations = Array.isArray(options.include)\n ? options.include\n : Object.keys(options.include);\n\n relations.forEach(relation => {\n queryBuilder = queryBuilder.leftJoinAndSelect(`${alias}.${relation}`, relation);\n });\n }\n\n if (options.where) {\n Object.entries(options.where).forEach(([field, val]) => {\n queryBuilder = queryBuilder.andWhere(`${alias}.${field} = :${field}`, { [field]: val });\n });\n }\n\n if (options.select && options.select.length > 0) {\n queryBuilder = queryBuilder.select(options.select.map(field => `${alias}.${field}`));\n }\n\n if (options.withTrashed) {\n queryBuilder = queryBuilder.withDeleted();\n } else if (options.onlyTrashed && metadata.deleteDateColumn) {\n queryBuilder = queryBuilder\n .withDeleted()\n .andWhere(`${alias}.${metadata.deleteDateColumn.propertyName} IS NOT NULL`);\n }\n\n if (options.lock === 'forUpdate') {\n queryBuilder = queryBuilder.setLock('pessimistic_write');\n } else if (options.lock === 'forShare') {\n queryBuilder = queryBuilder.setLock('pessimistic_read');\n }\n\n if (options.query) {\n queryBuilder = this.applyCustomQuery(\n queryBuilder,\n options.query as QueryModifier<SelectQueryBuilder<ObjectLiteral>>\n );\n }\n\n return await queryBuilder.getOne();\n }\n}\n","import type {\n Sequelize,\n Model,\n ModelStatic,\n FindOptions,\n Includeable,\n Transaction,\n} from 'sequelize';\nimport { BaseAdapter } from '../core/BaseAdapter';\nimport { QueryOptions, ModelMetadata, QueryModifier } from '../core/types';\nimport { BindingError } from '../errors';\nimport { isUUID } from '../utils/validators';\n\n/**\n * Sequelize model static type\n */\ntype SequelizeModelStatic = ModelStatic<Model>;\n\n/**\n * Type guard for Sequelize model\n */\nfunction isSequelizeModel(model: unknown): model is SequelizeModelStatic {\n if (!model || typeof model !== 'function') {\n return false;\n }\n const m = model as unknown as Record<string, unknown>;\n return (\n typeof m.findOne === 'function' &&\n typeof m.findAll === 'function' &&\n typeof m.rawAttributes === 'object'\n );\n}\n\n/**\n * Adapter for Sequelize ORM supporting PostgreSQL, MySQL, SQLite, MSSQL\n */\nexport class SequelizeAdapter extends BaseAdapter<SequelizeModelStatic, Model, FindOptions> {\n readonly name = 'sequelize';\n\n constructor(private sequelize: Sequelize) {\n super();\n }\n\n getSequelize(): Sequelize {\n return this.sequelize;\n }\n\n async findByKey(\n model: SequelizeModelStatic,\n key: string,\n value: unknown,\n options: QueryOptions = {}\n ): Promise<Model | null> {\n this.validateModel(model);\n\n try {\n const transformedValue = this.transformValue(model, key, value as string);\n\n const findOptions: FindOptions = {\n where: { [key]: transformedValue },\n };\n\n if (options.select && options.select.length > 0) {\n findOptions.attributes = options.select;\n }\n\n if (options.include) {\n findOptions.include = this.buildIncludes(options.include);\n }\n\n if (options.where) {\n findOptions.where = {\n ...findOptions.where,\n ...options.where,\n };\n }\n\n const isParanoid = model.options?.paranoid;\n if (isParanoid) {\n if (options.withTrashed) {\n findOptions.paranoid = false;\n } else if (options.onlyTrashed) {\n findOptions.paranoid = false;\n // Sequelize Op must be loaded synchronously for query construction\n // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires\n const { Op: SeqOp } = require('sequelize');\n const whereClause = findOptions.where as Record<string, unknown>;\n whereClause.deletedAt = { [SeqOp.ne]: null };\n }\n }\n\n if (options.lock === 'forUpdate') {\n findOptions.lock = true;\n } else if (options.lock === 'forShare') {\n // Sequelize Transaction must be loaded synchronously for lock types\n // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires\n const { Transaction: SeqTransaction } = require('sequelize') as {\n Transaction: typeof Transaction;\n };\n findOptions.lock = SeqTransaction.LOCK.SHARE;\n }\n\n let result = await model.findOne(findOptions);\n\n if (options.query && !result) {\n result = await this.findWithCustomQuery(model, key, transformedValue, options);\n }\n\n return result;\n } catch (error) {\n throw new BindingError(\n `Failed to fetch ${model.name}: ${(error as Error).message}`,\n error as Error\n );\n }\n }\n\n getPrimaryKeyName(model: SequelizeModelStatic): string {\n return model.primaryKeyAttribute || 'id';\n }\n\n isValidModel(model: unknown): model is SequelizeModelStatic {\n return isSequelizeModel(model);\n }\n\n transformValue(model: SequelizeModelStatic, key: string, value: string): unknown {\n const attributes = model.rawAttributes;\n const attribute = attributes?.[key];\n\n if (!attribute) {\n if (isUUID(value)) {\n return value;\n }\n const num = parseInt(value, 10);\n if (!isNaN(num) && num.toString() === value) {\n return num;\n }\n return value;\n }\n\n const attrType = attribute.type;\n const type = attrType?.constructor?.name || String(attrType);\n\n switch (type) {\n case 'INTEGER':\n case 'BIGINT':\n case 'SMALLINT': {\n const intNum = parseInt(value, 10);\n return isNaN(intNum) ? value : intNum;\n }\n\n case 'FLOAT':\n case 'DOUBLE':\n case 'DECIMAL': {\n const floatNum = parseFloat(value);\n return isNaN(floatNum) ? value : floatNum;\n }\n\n case 'BOOLEAN':\n return value === 'true' || value === '1';\n\n case 'UUID':\n return value;\n\n default:\n return value;\n }\n }\n\n supportsSoftDeletes(model: SequelizeModelStatic): boolean {\n return !!model.options?.paranoid;\n }\n\n getModelMetadata(model: SequelizeModelStatic): ModelMetadata {\n const tableName = model.tableName || model.name;\n const associations = Object.keys(model.associations || {});\n\n return {\n name: model.name,\n primaryKey: this.getPrimaryKeyName(model),\n tableName: tableName,\n softDeletes: this.supportsSoftDeletes(model),\n relations: associations,\n adapter: this.name,\n };\n }\n\n private buildIncludes(includes: string[] | Record<string, unknown>): Includeable[] {\n if (Array.isArray(includes)) {\n return includes.map(relation => ({ association: relation }));\n }\n\n return Object.entries(includes).map(([relation, opts]) => {\n if (typeof opts === 'boolean' && opts) {\n return { association: relation };\n }\n\n if (typeof opts === 'object' && opts !== null) {\n return {\n association: relation,\n ...opts,\n };\n }\n\n return { association: relation };\n });\n }\n\n private async findWithCustomQuery(\n model: SequelizeModelStatic,\n key: string,\n value: unknown,\n options: QueryOptions\n ): Promise<Model | null> {\n const findOptions: FindOptions = {\n where: { [key]: value },\n };\n\n if (options.query) {\n (options.query as QueryModifier<FindOptions>)(findOptions);\n }\n\n return await model.findOne(findOptions);\n }\n}\n","import { BaseAdapter } from '../core/BaseAdapter';\nimport { QueryOptions, ModelMetadata, QueryModifier } from '../core/types';\nimport { InvalidModelError, BindingError } from '../errors';\nimport { isUUID } from '../utils/validators';\n\n/**\n * Prisma model delegate (dynamic accessor on PrismaClient)\n */\ninterface PrismaModelDelegate {\n findUnique: (args: PrismaFindArgs) => Promise<unknown>;\n findFirst: (args: PrismaFindArgs) => Promise<unknown>;\n}\n\n/**\n * Prisma find operation arguments\n */\ninterface PrismaFindArgs {\n where: Record<string, unknown>;\n select?: Record<string, boolean>;\n include?: Record<string, unknown>;\n}\n\n/**\n * Prisma client interface (minimal required methods)\n */\ninterface PrismaClientLike {\n [modelName: string]: PrismaModelDelegate | ((...args: unknown[]) => unknown);\n}\n\n/**\n * Adapter for Prisma ORM with type-safe database access\n */\nexport class PrismaAdapter extends BaseAdapter<string, unknown, PrismaFindArgs> {\n readonly name = 'prisma';\n\n constructor(private prisma: PrismaClientLike) {\n super();\n }\n\n getPrisma(): PrismaClientLike {\n return this.prisma;\n }\n\n async findByKey(\n modelName: string,\n key: string,\n value: unknown,\n options: QueryOptions = {}\n ): Promise<unknown> {\n this.validateModel(modelName);\n\n try {\n const model = this.prisma[modelName] as PrismaModelDelegate;\n\n if (!model) {\n throw new InvalidModelError(`Model '${modelName}' not found in Prisma schema`, modelName);\n }\n\n const transformedValue = this.transformValue(modelName, key, value as string);\n\n const queryOptions: PrismaFindArgs = {\n where: { [key]: transformedValue },\n };\n\n if (options.where) {\n queryOptions.where = {\n ...queryOptions.where,\n ...options.where,\n };\n }\n\n if (options.select && options.select.length > 0) {\n queryOptions.select = options.select.reduce<Record<string, boolean>>((acc, field) => {\n acc[field] = true;\n return acc;\n }, {});\n }\n\n if (options.include) {\n queryOptions.include = this.buildIncludeOptions(options.include);\n delete queryOptions.select;\n }\n\n if (options.query) {\n (options.query as QueryModifier<PrismaFindArgs>)(queryOptions);\n }\n\n let result: unknown = null;\n try {\n result = await model.findUnique(queryOptions);\n } catch {\n result = await model.findFirst(queryOptions);\n }\n\n if (!result && key !== this.getPrimaryKeyName(modelName)) {\n result = await model.findFirst(queryOptions);\n }\n\n return result;\n } catch (error) {\n if (error instanceof InvalidModelError) {\n throw error;\n }\n throw new BindingError(\n `Failed to fetch ${modelName}: ${(error as Error).message}`,\n error as Error\n );\n }\n }\n\n getPrimaryKeyName(_modelName: string): string {\n return 'id';\n }\n\n isValidModel(modelName: unknown): modelName is string {\n if (typeof modelName !== 'string') {\n return false;\n }\n\n if (modelName.startsWith('$')) {\n return false;\n }\n\n return !!this.prisma[modelName];\n }\n\n transformValue(_modelName: string, key: string, value: string): unknown {\n if (key === 'id' || key.endsWith('Id')) {\n const num = parseInt(value, 10);\n if (!isNaN(num) && num.toString() === value && Number.isSafeInteger(num)) {\n return num;\n }\n }\n\n if (isUUID(value)) {\n return value;\n }\n\n return value;\n }\n\n supportsSoftDeletes(_modelName: string): boolean {\n return false;\n }\n\n getModelMetadata(modelName: string): ModelMetadata {\n return {\n name: modelName,\n primaryKey: this.getPrimaryKeyName(modelName),\n softDeletes: false,\n adapter: this.name,\n };\n }\n\n private buildIncludeOptions(\n includes: string[] | Record<string, unknown>\n ): Record<string, unknown> {\n if (Array.isArray(includes)) {\n return includes.reduce<Record<string, boolean>>((acc, relation) => {\n acc[relation] = true;\n return acc;\n }, {});\n }\n\n return Object.entries(includes).reduce<Record<string, unknown>>((acc, [relation, opts]) => {\n if (typeof opts === 'boolean') {\n acc[relation] = opts;\n } else if (typeof opts === 'object' && opts !== null) {\n const nestedOpts = opts as Record<string, unknown>;\n acc[relation] = {\n ...nestedOpts,\n include: nestedOpts.include\n ? this.buildIncludeOptions(nestedOpts.include as string[] | Record<string, unknown>)\n : undefined,\n };\n }\n return acc;\n }, {});\n }\n}\n","import { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { ModelBinder } from '../core/ModelBinder';\nimport { BindOptions, ModelBindingsConfig } from '../core/types';\nimport { logger } from '../utils/logger';\n\n/**\n * Create middleware that binds a model to a route parameter\n *\n * @param paramName - The route parameter name (without ':')\n * @param model - The model class/schema/table\n * @param options - Binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/:user', bindModel('user', User), (req, res) => {\n * res.json(req.user);\n * });\n */\nexport function bindModel(\n paramName: string,\n model: unknown,\n options: BindOptions = {}\n): RequestHandler {\n return async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n // Check if parameter exists in route\n if (!(paramName in req.params)) {\n logger.warn(`Parameter '${paramName}' not found in route`);\n if (options.optional) {\n return next();\n }\n }\n\n // Perform the binding\n const result = await ModelBinder.bind(req, res, paramName, model, options);\n\n if (!result.success) {\n return next(result.error);\n }\n\n next();\n } catch (error) {\n next(error);\n }\n };\n}\n\n/**\n * Bind multiple models in a single middleware\n *\n * @param bindings - Object mapping parameter names to model configs\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/:user/posts/:post',\n * bindModels({\n * user: { model: User },\n * post: { model: Post, options: { include: ['comments'] } }\n * }),\n * (req, res) => {\n * res.json({ user: req.user, post: req.post });\n * }\n * );\n */\nexport function bindModels(bindings: ModelBindingsConfig): RequestHandler {\n return async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n // Bind all models sequentially\n for (const [paramName, config] of Object.entries(bindings)) {\n if (!(paramName in req.params)) {\n logger.warn(`Parameter '${paramName}' not found in route`);\n if (config.options?.optional) {\n continue;\n }\n }\n\n const result = await ModelBinder.bind(\n req,\n res,\n paramName,\n config.model,\n config.options || {}\n );\n\n if (!result.success) {\n return next(result.error);\n }\n }\n\n next();\n } catch (error) {\n next(error);\n }\n };\n}\n\n/**\n * Bind a model optionally (don't throw 404 if not found)\n *\n * @param paramName - The route parameter name\n * @param model - The model class/schema/table\n * @param options - Binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/posts/:post?', bindOptional('post', Post), (req, res) => {\n * if (req.post) {\n * res.json(req.post);\n * } else {\n * res.json({ message: 'No specific post' });\n * }\n * });\n */\nexport function bindOptional(\n paramName: string,\n model: unknown,\n options: BindOptions = {}\n): RequestHandler {\n return bindModel(paramName, model, { ...options, optional: true });\n}\n\n/**\n * Create a middleware that binds a model using a custom key\n *\n * @param paramName - The route parameter name\n * @param model - The model class/schema/table\n * @param key - The field to search by\n * @param options - Additional binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/by-email/:email', bindByKey('email', User, 'email'), (req, res) => {\n * res.json(req.email);\n * });\n */\nexport function bindByKey(\n paramName: string,\n model: unknown,\n key: string,\n options: BindOptions = {}\n): RequestHandler {\n return bindModel(paramName, model, { ...options, key });\n}\n\n/**\n * Create a middleware that binds a model and attaches it with a custom name\n *\n * @param paramName - The route parameter name\n * @param model - The model class/schema/table\n * @param attachAs - The name to attach the model as on the request\n * @param options - Additional binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/:id', bindAs('id', User, 'currentUser'), (req, res) => {\n * res.json(req.currentUser);\n * });\n */\nexport function bindAs(\n paramName: string,\n model: unknown,\n attachAs: string,\n options: BindOptions = {}\n): RequestHandler {\n return bindModel(paramName, model, { ...options, as: attachAs });\n}\n\n/**\n * Create a middleware that binds a model with caching\n *\n * @param paramName - The route parameter name\n * @param model - The model class/schema/table\n * @param ttl - Cache TTL in milliseconds (default: 60000)\n * @param options - Additional binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/:user', bindCached('user', User, 300000), (req, res) => {\n * res.json(req.user);\n * });\n */\nexport function bindCached(\n paramName: string,\n model: unknown,\n ttl: number = 60000,\n options: BindOptions = {}\n): RequestHandler {\n return bindModel(paramName, model, { ...options, cache: true, cacheTTL: ttl });\n}\n\n/**\n * Create a middleware that binds a model with eager-loaded relations\n *\n * @param paramName - The route parameter name\n * @param model - The model class/schema/table\n * @param relations - Relations to eager load\n * @param options - Additional binding options\n * @returns Express middleware function\n *\n * @example\n * app.get('/users/:user', bindWithRelations('user', User, ['posts', 'profile']), (req, res) => {\n * res.json(req.user);\n * });\n */\nexport function bindWithRelations(\n paramName: string,\n model: unknown,\n relations: string[] | Record<string, unknown>,\n options: BindOptions = {}\n): RequestHandler {\n return bindModel(paramName, model, { ...options, include: relations });\n}\n","import { isNumeric, isUUID, isObjectId } from './validators';\n\n/**\n * Transform a string value to a number if it's numeric\n */\nexport function toNumber(value: string): number | string {\n if (isNumeric(value)) {\n const num = parseInt(value, 10);\n if (!isNaN(num) && Number.isSafeInteger(num)) {\n return num;\n }\n }\n return value;\n}\n\n/**\n * Transform a string value to a float if it's a valid decimal\n */\nexport function toFloat(value: string): number | string {\n const num = parseFloat(value);\n if (!isNaN(num) && isFinite(num)) {\n return num;\n }\n return value;\n}\n\n/**\n * Transform a string value to a boolean\n */\nexport function toBoolean(value: string): boolean {\n const lowered = value.toLowerCase();\n return lowered === 'true' || lowered === '1' || lowered === 'yes';\n}\n\n/**\n * Transform a string to lowercase\n */\nexport function toLowerCase(value: string): string {\n return value.toLowerCase();\n}\n\n/**\n * Transform a string to uppercase\n */\nexport function toUpperCase(value: string): string {\n return value.toUpperCase();\n}\n\n/**\n * Trim whitespace from a string\n */\nexport function trim(value: string): string {\n return value.trim();\n}\n\n/**\n * Transform a slug to underscore format\n */\nexport function slugToUnderscore(value: string): string {\n return value.replace(/-/g, '_');\n}\n\n/**\n * Transform underscores to dashes (slug format)\n */\nexport function underscoreToSlug(value: string): string {\n return value.replace(/_/g, '-');\n}\n\n/**\n * Auto-detect and transform value based on format\n */\nexport function autoTransform(value: string): unknown {\n // Check if it's a UUID - keep as string\n if (isUUID(value)) {\n return value;\n }\n\n // Check if it's a MongoDB ObjectId - keep as string\n if (isObjectId(value)) {\n return value;\n }\n\n // Check if it's a pure integer\n if (/^\\d+$/.test(value)) {\n const num = parseInt(value, 10);\n if (!isNaN(num) && Number.isSafeInteger(num)) {\n return num;\n }\n }\n\n // Check if it's a negative integer\n if (/^-\\d+$/.test(value)) {\n const num = parseInt(value, 10);\n if (!isNaN(num) && Number.isSafeInteger(num)) {\n return num;\n }\n }\n\n return value;\n}\n\n/**\n * Create a composed transformer from multiple transform functions\n */\nexport function compose(\n ...transformers: Array<(value: string) => unknown>\n): (value: string) => unknown {\n return (value: string): unknown => {\n let result: unknown = value;\n for (const transformer of transformers) {\n result = transformer(String(result));\n }\n return result;\n };\n}\n\n/**\n * Identity transformer - returns the value unchanged\n */\nexport function identity<T>(value: T): T {\n return value;\n}\n","// Core exports\nexport { ModelBinder } from './core/ModelBinder';\nexport { BaseAdapter } from './core/BaseAdapter';\n\n// Type exports\nexport type {\n IORMAdapter,\n QueryOptions,\n BindOptions,\n BindingContext,\n BindingResult,\n ModelMetadata,\n ModelBindingsConfig,\n ModelBindingGlobalConfig,\n CacheEntry,\n TypedRequest,\n TypedRequestHandler,\n ExtractModelType,\n MiddlewareFunction,\n} from './core/types';\n\n// Adapter exports\nexport { KnexAdapter, defineKnexModel } from './adapters/KnexAdapter';\nexport type { KnexModel } from './adapters/KnexAdapter';\nexport { MongooseAdapter } from './adapters/MongooseAdapter';\nexport { TypeORMAdapter } from './adapters/TypeORMAdapter';\nexport { SequelizeAdapter } from './adapters/SequelizeAdapter';\nexport { PrismaAdapter } from './adapters/PrismaAdapter';\n\n// Middleware exports\nexport {\n bindModel,\n bindModels,\n bindOptional,\n bindByKey,\n bindAs,\n bindCached,\n bindWithRelations,\n} from './middleware/bindModel';\n\n// Error exports\nexport {\n BindingError,\n ModelNotFoundError,\n AdapterNotSetError,\n InvalidModelError,\n ValidationError,\n} from './errors';\n\n// Utility exports\nexport { Cache } from './utils/cache';\nexport { logger } from './utils/logger';\nexport type { LogLevel, LoggerConfig } from './utils/logger';\nexport * from './utils/validators';\nexport * from './utils/transformers';\n\n// Version\nexport const VERSION = '1.0.0';\n"],"mappings":"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","names":["attachAs"]}
|