@classytic/mongokit 2.1.0 → 3.0.1

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.
Files changed (38) hide show
  1. package/README.md +35 -4
  2. package/dist/actions/index.d.ts +2 -2
  3. package/dist/actions/index.js +0 -2
  4. package/dist/{index-CgOJ2pqz.d.ts → index-CKy3H2SY.d.ts} +1 -1
  5. package/dist/index.d.ts +10 -6
  6. package/dist/index.js +183 -6
  7. package/dist/{memory-cache-DG2oSSbx.d.ts → memory-cache-tn3v1xgG.d.ts} +1 -1
  8. package/dist/pagination/PaginationEngine.d.ts +1 -1
  9. package/dist/pagination/PaginationEngine.js +0 -2
  10. package/dist/plugins/index.d.ts +37 -2
  11. package/dist/plugins/index.js +173 -3
  12. package/dist/{types-Nxhmi1aI.d.cts → types-vDtcOhyx.d.ts} +19 -1
  13. package/dist/utils/index.d.ts +2 -2
  14. package/dist/utils/index.js +0 -2
  15. package/package.json +6 -12
  16. package/dist/actions/index.cjs +0 -479
  17. package/dist/actions/index.cjs.map +0 -1
  18. package/dist/actions/index.d.cts +0 -3
  19. package/dist/actions/index.js.map +0 -1
  20. package/dist/index-BfVJZF-3.d.cts +0 -337
  21. package/dist/index.cjs +0 -2142
  22. package/dist/index.cjs.map +0 -1
  23. package/dist/index.d.cts +0 -239
  24. package/dist/index.js.map +0 -1
  25. package/dist/memory-cache-DqfFfKes.d.cts +0 -142
  26. package/dist/pagination/PaginationEngine.cjs +0 -375
  27. package/dist/pagination/PaginationEngine.cjs.map +0 -1
  28. package/dist/pagination/PaginationEngine.d.cts +0 -117
  29. package/dist/pagination/PaginationEngine.js.map +0 -1
  30. package/dist/plugins/index.cjs +0 -874
  31. package/dist/plugins/index.cjs.map +0 -1
  32. package/dist/plugins/index.d.cts +0 -275
  33. package/dist/plugins/index.js.map +0 -1
  34. package/dist/types-Nxhmi1aI.d.ts +0 -510
  35. package/dist/utils/index.cjs +0 -667
  36. package/dist/utils/index.cjs.map +0 -1
  37. package/dist/utils/index.d.cts +0 -189
  38. package/dist/utils/index.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utils/field-selection.ts","../../src/plugins/field-filter.plugin.ts","../../src/plugins/timestamp.plugin.ts","../../src/plugins/audit-log.plugin.ts","../../src/plugins/soft-delete.plugin.ts","../../src/plugins/method-registry.plugin.ts","../../src/utils/error.ts","../../src/plugins/validation-chain.plugin.ts","../../src/actions/create.ts","../../src/plugins/mongo-operations.plugin.ts","../../src/plugins/batch-operations.plugin.ts","../../src/plugins/aggregate-helpers.plugin.ts","../../src/plugins/subdocument.plugin.ts","../../src/utils/cache-keys.ts","../../src/plugins/cache.plugin.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Field Selection Utilities\r\n *\r\n * Provides explicit, performant field filtering using Mongoose projections.\r\n *\r\n * Philosophy:\r\n * - Explicit is better than implicit\r\n * - Filter at DB level (10x faster than in-memory)\r\n * - Progressive disclosure (show more fields as trust increases)\r\n *\r\n * @example\r\n * ```typescript\r\n * // For Mongoose queries (PREFERRED - 90% of cases)\r\n * const projection = getMongooseProjection(request.user, fieldPresets.gymPlans);\r\n * const plans = await GymPlan.find().select(projection).lean();\r\n *\r\n * // For complex data (10% of cases - aggregations, multiple sources)\r\n * const filtered = filterResponseData(complexData, fieldPresets.gymPlans, request.user);\r\n * ```\r\n */\r\n\r\nimport type { FieldPreset, UserContext } from '../types.js';\r\n\r\n/**\r\n * Get allowed fields for a user based on their context\r\n *\r\n * @param user - User object from request.user (or null for public)\r\n * @param preset - Field preset configuration\r\n * @returns Array of allowed field names\r\n * \r\n * @example\r\n * const fields = getFieldsForUser(request.user, {\r\n * public: ['id', 'name', 'price'],\r\n * authenticated: ['description', 'features'],\r\n * admin: ['createdAt', 'internalNotes']\r\n * });\r\n */\r\nexport function getFieldsForUser(user: UserContext | null | undefined, preset: FieldPreset): string[] {\r\n if (!preset) {\r\n throw new Error('Field preset is required');\r\n }\r\n\r\n // Start with public fields\r\n const fields: string[] = [...(preset.public || [])];\r\n\r\n // Add authenticated fields if user is logged in\r\n if (user) {\r\n fields.push(...(preset.authenticated || []));\r\n\r\n // Add admin fields if user is admin/superadmin\r\n const roles = Array.isArray(user.roles) ? user.roles : (user.roles ? [user.roles] : []);\r\n if (roles.includes('admin') || roles.includes('superadmin')) {\r\n fields.push(...(preset.admin || []));\r\n }\r\n }\r\n\r\n // Remove duplicates\r\n return [...new Set(fields)];\r\n}\r\n\r\n/**\r\n * Get Mongoose projection string for query .select()\r\n *\r\n * @param user - User object from request.user\r\n * @param preset - Field preset configuration\r\n * @returns Space-separated field names for Mongoose .select()\r\n *\r\n * @example\r\n * const projection = getMongooseProjection(request.user, fieldPresets.gymPlans);\r\n * const plans = await GymPlan.find({ organizationId }).select(projection).lean();\r\n */\r\nexport function getMongooseProjection(user: UserContext | null | undefined, preset: FieldPreset): string {\r\n const fields = getFieldsForUser(user, preset);\r\n return fields.join(' ');\r\n}\r\n\r\n/**\r\n * Filter a single object to include only allowed fields\r\n */\r\nfunction filterObject<T extends Record<string, unknown>>(\r\n obj: T,\r\n allowedFields: string[]\r\n): Partial<T> {\r\n if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {\r\n return obj;\r\n }\r\n\r\n const filtered: Partial<T> = {};\r\n\r\n for (const field of allowedFields) {\r\n if (field in obj) {\r\n (filtered as Record<string, unknown>)[field] = obj[field];\r\n }\r\n }\r\n\r\n return filtered;\r\n}\r\n\r\n/**\r\n * Filter response data to include only allowed fields\r\n *\r\n * Use this for complex responses where Mongoose projections aren't applicable:\r\n * - Aggregation pipeline results\r\n * - Data from multiple sources\r\n * - Custom computed fields\r\n *\r\n * For simple DB queries, prefer getMongooseProjection() (10x faster)\r\n *\r\n * @param data - Data to filter\r\n * @param preset - Field preset configuration\r\n * @param user - User object from request.user\r\n * @returns Filtered data\r\n *\r\n * @example\r\n * const stats = await calculateComplexStats();\r\n * const filtered = filterResponseData(stats, fieldPresets.dashboard, request.user);\r\n * return reply.send(filtered);\r\n */\r\nexport function filterResponseData<T extends Record<string, unknown>>(\r\n data: T | T[],\r\n preset: FieldPreset,\r\n user: UserContext | null = null\r\n): Partial<T> | Partial<T>[] {\r\n const allowedFields = getFieldsForUser(user, preset);\r\n\r\n // Handle arrays\r\n if (Array.isArray(data)) {\r\n return data.map(item => filterObject(item, allowedFields));\r\n }\r\n\r\n // Handle single object\r\n return filterObject(data, allowedFields);\r\n}\r\n\r\n/**\r\n * Helper to create field presets (module-level)\r\n *\r\n * Each module should define its own field preset in its own directory.\r\n * This keeps modules independent and self-contained.\r\n *\r\n * @param config - Field configuration\r\n * @returns Field preset\r\n *\r\n * @example\r\n * // In modules/gym-plan/gym-plan.fields.ts\r\n * export const gymPlanFieldPreset = createFieldPreset({\r\n * public: ['id', 'name', 'price'],\r\n * authenticated: ['features', 'description'],\r\n * admin: ['createdAt', 'updatedAt', 'internalNotes']\r\n * });\r\n */\r\nexport function createFieldPreset(config: Partial<FieldPreset>): FieldPreset {\r\n return {\r\n public: config.public || [],\r\n authenticated: config.authenticated || [],\r\n admin: config.admin || [],\r\n };\r\n}\r\n","/**\r\n * Field Filter Plugin\r\n * Automatically filters response fields based on user roles\r\n */\r\n\r\nimport { getFieldsForUser } from '../utils/field-selection.js';\r\nimport type { Plugin, RepositoryContext, RepositoryInstance, FieldPreset } from '../types.js';\r\n\r\n/**\r\n * Field filter plugin that restricts fields based on user context\r\n * \r\n * @example\r\n * const fieldPreset = {\r\n * public: ['id', 'name'],\r\n * authenticated: ['email'],\r\n * admin: ['createdAt', 'internalNotes']\r\n * };\r\n * \r\n * const repo = new Repository(Model, [fieldFilterPlugin(fieldPreset)]);\r\n */\r\nexport function fieldFilterPlugin(fieldPreset: FieldPreset): Plugin {\r\n return {\r\n name: 'fieldFilter',\r\n\r\n apply(repo: RepositoryInstance): void {\r\n const applyFieldFiltering = (context: RepositoryContext): void => {\r\n if (!fieldPreset) return;\r\n\r\n const user = (context as any).context?.user || (context as any).user;\r\n const fields = getFieldsForUser(user, fieldPreset);\r\n const presetSelect = fields.join(' ');\r\n\r\n if (context.select) {\r\n context.select = `${presetSelect} ${context.select}`;\r\n } else {\r\n context.select = presetSelect;\r\n }\r\n };\r\n\r\n repo.on('before:getAll', applyFieldFiltering);\r\n repo.on('before:getById', applyFieldFiltering);\r\n repo.on('before:getByQuery', applyFieldFiltering);\r\n },\r\n };\r\n}\r\n\r\nexport default fieldFilterPlugin;\r\n","/**\r\n * Timestamp Plugin\r\n * Auto-injects createdAt/updatedAt timestamps on create/update\r\n */\r\n\r\nimport type { Plugin, RepositoryContext, RepositoryInstance } from '../types.js';\r\n\r\n/**\r\n * Timestamp plugin that auto-injects timestamps\r\n * \r\n * @example\r\n * const repo = new Repository(Model, [timestampPlugin()]);\r\n */\r\nexport function timestampPlugin(): Plugin {\r\n return {\r\n name: 'timestamp',\r\n\r\n apply(repo: RepositoryInstance): void {\r\n repo.on('before:create', (context: RepositoryContext) => {\r\n if (!context.data) return;\r\n const now = new Date();\r\n if (!context.data.createdAt) context.data.createdAt = now;\r\n if (!context.data.updatedAt) context.data.updatedAt = now;\r\n });\r\n\r\n repo.on('before:update', (context: RepositoryContext) => {\r\n if (!context.data) return;\r\n context.data.updatedAt = new Date();\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport default timestampPlugin;\r\n","/**\r\n * Audit Log Plugin\r\n * Logs repository operations for auditing purposes\r\n */\r\n\r\nimport type { Plugin, RepositoryContext, RepositoryInstance, Logger } from '../types.js';\r\n\r\n/**\r\n * Audit log plugin that logs all repository operations\r\n * \r\n * @example\r\n * const repo = new Repository(Model, [auditLogPlugin(console)]);\r\n */\r\nexport function auditLogPlugin(logger: Logger): Plugin {\r\n return {\r\n name: 'auditLog',\r\n\r\n apply(repo: RepositoryInstance): void {\r\n repo.on('after:create', ({ context, result }: { context: RepositoryContext; result: unknown }) => {\r\n logger?.info?.('Document created', {\r\n model: context.model || repo.model,\r\n id: (result as Record<string, unknown>)?._id,\r\n userId: context.user?._id || context.user?.id,\r\n organizationId: context.organizationId,\r\n });\r\n });\r\n\r\n repo.on('after:update', ({ context, result }: { context: RepositoryContext; result: unknown }) => {\r\n logger?.info?.('Document updated', {\r\n model: context.model || repo.model,\r\n id: context.id || (result as Record<string, unknown>)?._id,\r\n userId: context.user?._id || context.user?.id,\r\n organizationId: context.organizationId,\r\n });\r\n });\r\n\r\n repo.on('after:delete', ({ context }: { context: RepositoryContext }) => {\r\n logger?.info?.('Document deleted', {\r\n model: context.model || repo.model,\r\n id: context.id,\r\n userId: context.user?._id || context.user?.id,\r\n organizationId: context.organizationId,\r\n });\r\n });\r\n\r\n repo.on('error:create', ({ context, error }: { context: RepositoryContext; error: Error }) => {\r\n logger?.error?.('Create failed', {\r\n model: context.model || repo.model,\r\n error: error.message,\r\n userId: context.user?._id || context.user?.id,\r\n });\r\n });\r\n\r\n repo.on('error:update', ({ context, error }: { context: RepositoryContext; error: Error }) => {\r\n logger?.error?.('Update failed', {\r\n model: context.model || repo.model,\r\n id: context.id,\r\n error: error.message,\r\n userId: context.user?._id || context.user?.id,\r\n });\r\n });\r\n\r\n repo.on('error:delete', ({ context, error }: { context: RepositoryContext; error: Error }) => {\r\n logger?.error?.('Delete failed', {\r\n model: context.model || repo.model,\r\n id: context.id,\r\n error: error.message,\r\n userId: context.user?._id || context.user?.id,\r\n });\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport default auditLogPlugin;\r\n","/**\r\n * Soft Delete Plugin\r\n * Implements soft delete pattern - marks documents as deleted instead of removing\r\n */\r\n\r\nimport type { Plugin, RepositoryContext, RepositoryInstance, SoftDeleteOptions } from '../types.js';\r\n\r\n/**\r\n * Soft delete plugin\r\n * \r\n * @example\r\n * const repo = new Repository(Model, [\r\n * softDeletePlugin({ deletedField: 'deletedAt' })\r\n * ]);\r\n */\r\nexport function softDeletePlugin(options: SoftDeleteOptions = {}): Plugin {\r\n const deletedField = options.deletedField || 'deletedAt';\r\n const deletedByField = options.deletedByField || 'deletedBy';\r\n\r\n return {\r\n name: 'softDelete',\r\n\r\n apply(repo: RepositoryInstance): void {\r\n repo.on('before:delete', async (context: RepositoryContext) => {\r\n if (options.soft !== false) {\r\n const updateData: Record<string, unknown> = {\r\n [deletedField]: new Date(),\r\n };\r\n\r\n if (context.user) {\r\n updateData[deletedByField] = context.user._id || context.user.id;\r\n }\r\n\r\n await repo.Model.findByIdAndUpdate(context.id, updateData, { session: context.session });\r\n\r\n (context as Record<string, unknown>).softDeleted = true;\r\n }\r\n });\r\n\r\n repo.on('before:getAll', (context: RepositoryContext) => {\r\n if (!context.includeDeleted && options.soft !== false) {\r\n const queryParams = (context as Record<string, unknown>).queryParams as Record<string, unknown> || {};\r\n queryParams.filters = {\r\n ...((queryParams.filters as Record<string, unknown>) || {}),\r\n [deletedField]: { $exists: false },\r\n };\r\n (context as Record<string, unknown>).queryParams = queryParams;\r\n }\r\n });\r\n\r\n repo.on('before:getById', (context: RepositoryContext) => {\r\n if (!context.includeDeleted && options.soft !== false) {\r\n context.query = {\r\n ...(context.query || {}),\r\n [deletedField]: { $exists: false },\r\n };\r\n }\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport default softDeletePlugin;\r\n","/**\r\n * Method Registry Plugin\r\n *\r\n * Enables plugins to dynamically add methods to repository instances.\r\n * Foundation for extensibility - allows other plugins to extend repositories\r\n * with custom methods while maintaining type safety and proper binding.\r\n *\r\n * @example\r\n * ```typescript\r\n * const repo = new Repository(User, [methodRegistryPlugin()]);\r\n *\r\n * // Now you can register custom methods\r\n * repo.registerMethod('findActive', async function() {\r\n * return this.getAll({ filters: { status: 'active' } });\r\n * });\r\n * ```\r\n */\r\n\r\nimport type { Plugin, RepositoryInstance } from '../types.js';\r\n\r\n/**\r\n * Extended repository interface with method registry\r\n */\r\nexport interface MethodRegistryRepository extends RepositoryInstance {\r\n registerMethod(name: string, fn: Function): void;\r\n hasMethod(name: string): boolean;\r\n getRegisteredMethods(): string[];\r\n}\r\n\r\n/**\r\n * Method registry plugin that enables dynamic method registration\r\n */\r\nexport function methodRegistryPlugin(): Plugin {\r\n return {\r\n name: 'method-registry',\r\n\r\n apply(repo: RepositoryInstance): void {\r\n const registeredMethods: string[] = [];\r\n\r\n /**\r\n * Register a new method on the repository instance\r\n */\r\n repo.registerMethod = function (name: string, fn: Function): void {\r\n // Check for naming conflicts\r\n if ((repo as Record<string, unknown>)[name]) {\r\n throw new Error(\r\n `Cannot register method '${name}': Method already exists on repository. ` +\r\n `Choose a different name or use a plugin that doesn't conflict.`\r\n );\r\n }\r\n\r\n // Validate method name\r\n if (!name || typeof name !== 'string') {\r\n throw new Error('Method name must be a non-empty string');\r\n }\r\n\r\n // Validate function\r\n if (typeof fn !== 'function') {\r\n throw new Error(`Method '${name}' must be a function`);\r\n }\r\n\r\n // Bind function to repository instance\r\n (repo as Record<string, unknown>)[name] = fn.bind(repo);\r\n registeredMethods.push(name);\r\n\r\n // Emit event for plugin system awareness\r\n repo.emit('method:registered', { name, fn });\r\n };\r\n\r\n /**\r\n * Check if a method is registered\r\n */\r\n repo.hasMethod = function (name: string): boolean {\r\n return typeof (repo as Record<string, unknown>)[name] === 'function';\r\n };\r\n\r\n /**\r\n * Get list of all dynamically registered methods\r\n */\r\n (repo as MethodRegistryRepository).getRegisteredMethods = function (): string[] {\r\n return [...registeredMethods];\r\n };\r\n },\r\n };\r\n}\r\n\r\nexport default methodRegistryPlugin;\r\n","/**\r\n * Error Utilities\r\n * \r\n * HTTP-compatible error creation for repository operations\r\n */\r\n\r\nimport type { HttpError } from '../types.js';\r\n\r\n/**\r\n * Creates an error with HTTP status code\r\n *\r\n * @param status - HTTP status code\r\n * @param message - Error message\r\n * @returns Error with status property\r\n * \r\n * @example\r\n * throw createError(404, 'Document not found');\r\n * throw createError(400, 'Invalid input');\r\n * throw createError(403, 'Access denied');\r\n */\r\nexport function createError(status: number, message: string): HttpError {\r\n const error = new Error(message) as HttpError;\r\n error.status = status;\r\n return error;\r\n}\r\n","/**\r\n * Validation Chain Plugin\r\n * \r\n * Composable validation for repository operations with customizable rules.\r\n */\r\n\r\nimport { createError } from '../utils/error.js';\r\nimport type {\r\n Plugin,\r\n RepositoryInstance,\r\n RepositoryContext,\r\n ValidatorDefinition,\r\n ValidationChainOptions,\r\n HttpError,\r\n} from '../types.js';\r\n\r\ntype OperationType = 'create' | 'createMany' | 'update' | 'delete';\r\n\r\n/**\r\n * Validation chain plugin\r\n * \r\n * @example\r\n * const repo = new Repository(Model, [\r\n * validationChainPlugin([\r\n * requireField('email'),\r\n * uniqueField('email', 'Email already exists'),\r\n * blockIf('no-delete-admin', ['delete'], ctx => ctx.data?.role === 'admin', 'Cannot delete admin'),\r\n * ])\r\n * ]);\r\n */\r\nexport function validationChainPlugin(\r\n validators: ValidatorDefinition[] = [],\r\n options: ValidationChainOptions = {}\r\n): Plugin {\r\n const { stopOnFirstError = true } = options;\r\n\r\n // Validate all validators have required properties\r\n validators.forEach((v, idx) => {\r\n if (!v.name || typeof v.name !== 'string') {\r\n throw new Error(`Validator at index ${idx} missing 'name' (string)`);\r\n }\r\n if (typeof v.validate !== 'function') {\r\n throw new Error(`Validator '${v.name}' missing 'validate' function`);\r\n }\r\n });\r\n\r\n // Group validators by operation\r\n const validatorsByOperation: Record<OperationType, ValidatorDefinition[]> = {\r\n create: [],\r\n update: [],\r\n delete: [],\r\n createMany: [],\r\n };\r\n const allOperationsValidators: ValidatorDefinition[] = [];\r\n\r\n validators.forEach(v => {\r\n if (!v.operations || v.operations.length === 0) {\r\n allOperationsValidators.push(v);\r\n } else {\r\n v.operations.forEach(op => {\r\n if (validatorsByOperation[op]) {\r\n validatorsByOperation[op].push(v);\r\n }\r\n });\r\n }\r\n });\r\n\r\n return {\r\n name: 'validation-chain',\r\n\r\n apply(repo: RepositoryInstance): void {\r\n const getValidatorsForOperation = (operation: OperationType): ValidatorDefinition[] => {\r\n const specific = validatorsByOperation[operation] || [];\r\n return [...allOperationsValidators, ...specific];\r\n };\r\n\r\n const runValidators = async (operation: OperationType, context: RepositoryContext): Promise<void> => {\r\n const operationValidators = getValidatorsForOperation(operation);\r\n const errors: Array<{ validator: string; error: string }> = [];\r\n\r\n for (const validator of operationValidators) {\r\n try {\r\n await validator.validate(context, repo);\r\n } catch (error) {\r\n if (stopOnFirstError) {\r\n throw error;\r\n }\r\n errors.push({\r\n validator: validator.name,\r\n error: (error as Error).message || String(error),\r\n });\r\n }\r\n }\r\n\r\n if (errors.length > 0) {\r\n const err = createError(\r\n 400,\r\n `Validation failed: ${errors.map(e => `[${e.validator}] ${e.error}`).join('; ')}`\r\n ) as HttpError;\r\n err.validationErrors = errors;\r\n throw err;\r\n }\r\n };\r\n\r\n repo.on('before:create', async (context: RepositoryContext) => runValidators('create', context));\r\n repo.on('before:createMany', async (context: RepositoryContext) => runValidators('createMany', context));\r\n repo.on('before:update', async (context: RepositoryContext) => runValidators('update', context));\r\n repo.on('before:delete', async (context: RepositoryContext) => runValidators('delete', context));\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Block operation if condition is true\r\n * \r\n * @example\r\n * blockIf('block-library', ['delete'], ctx => ctx.data?.managed, 'Cannot delete managed records')\r\n */\r\nexport function blockIf(\r\n name: string,\r\n operations: OperationType[],\r\n condition: (context: RepositoryContext) => boolean,\r\n errorMessage: string\r\n): ValidatorDefinition {\r\n return {\r\n name,\r\n operations,\r\n validate: (context: RepositoryContext) => {\r\n if (condition(context)) {\r\n throw createError(403, errorMessage);\r\n }\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Require a field to be present\r\n */\r\nexport function requireField(\r\n field: string,\r\n operations: OperationType[] = ['create']\r\n): ValidatorDefinition {\r\n return {\r\n name: `require-${field}`,\r\n operations,\r\n validate: (context: RepositoryContext) => {\r\n if (!context.data || context.data[field] === undefined || context.data[field] === null) {\r\n throw createError(400, `Field '${field}' is required`);\r\n }\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Auto-inject a value if not present\r\n */\r\nexport function autoInject(\r\n field: string,\r\n getter: (context: RepositoryContext) => unknown,\r\n operations: OperationType[] = ['create']\r\n): ValidatorDefinition {\r\n return {\r\n name: `auto-inject-${field}`,\r\n operations,\r\n validate: (context: RepositoryContext) => {\r\n if (context.data && !(field in context.data)) {\r\n const value = getter(context);\r\n if (value !== null && value !== undefined) {\r\n context.data[field] = value;\r\n }\r\n }\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Make a field immutable (cannot be updated)\r\n */\r\nexport function immutableField(field: string): ValidatorDefinition {\r\n return {\r\n name: `immutable-${field}`,\r\n operations: ['update'],\r\n validate: (context: RepositoryContext) => {\r\n if (context.data && field in context.data) {\r\n throw createError(400, `Field '${field}' cannot be modified`);\r\n }\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Ensure field value is unique\r\n */\r\nexport function uniqueField(field: string, errorMessage?: string): ValidatorDefinition {\r\n return {\r\n name: `unique-${field}`,\r\n operations: ['create', 'update'],\r\n validate: async (context: RepositoryContext, repo?: RepositoryInstance) => {\r\n if (!context.data || !context.data[field] || !repo) return;\r\n\r\n const query = { [field]: context.data[field] };\r\n \r\n // Use repo's getByQuery method\r\n const getByQuery = (repo as Record<string, Function>).getByQuery;\r\n if (typeof getByQuery !== 'function') return;\r\n\r\n const existing = await getByQuery.call(repo, query, {\r\n select: '_id',\r\n lean: true,\r\n throwOnNotFound: false,\r\n }) as Record<string, unknown> | null;\r\n\r\n if (existing && String(existing._id) !== String(context.id)) {\r\n throw createError(409, errorMessage || `${field} already exists`);\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport default validationChainPlugin;\r\n","/**\r\n * Create Actions\r\n * Pure functions for document creation\r\n */\r\n\r\nimport type { Model, ClientSession, SchemaType } from 'mongoose';\r\nimport type { CreateOptions, AnyDocument } from '../types.js';\r\n\r\n/**\r\n * Create single document\r\n */\r\nexport async function create<TDoc = AnyDocument>(\r\n Model: Model<TDoc>,\r\n data: Record<string, unknown>,\r\n options: CreateOptions = {}\r\n): Promise<TDoc> {\r\n const document = new Model(data);\r\n await document.save({ session: options.session });\r\n return document as TDoc;\r\n}\r\n\r\n/**\r\n * Create multiple documents\r\n */\r\nexport async function createMany<TDoc = AnyDocument>(\r\n Model: Model<TDoc>,\r\n dataArray: Record<string, unknown>[],\r\n options: CreateOptions = {}\r\n): Promise<TDoc[]> {\r\n return Model.insertMany(dataArray, {\r\n session: options.session,\r\n ordered: options.ordered !== false,\r\n }) as Promise<TDoc[]>;\r\n}\r\n\r\n/**\r\n * Create with defaults (useful for initialization)\r\n */\r\nexport async function createDefault<TDoc = AnyDocument>(\r\n Model: Model<TDoc>,\r\n overrides: Record<string, unknown> = {},\r\n options: CreateOptions = {}\r\n): Promise<TDoc> {\r\n const defaults: Record<string, unknown> = {};\r\n\r\n // Extract defaults from schema\r\n Model.schema.eachPath((path: string, schemaType: SchemaType) => {\r\n const schemaOptions = schemaType.options as { default?: unknown };\r\n if (schemaOptions.default !== undefined && path !== '_id') {\r\n defaults[path] = typeof schemaOptions.default === 'function'\r\n ? schemaOptions.default()\r\n : schemaOptions.default;\r\n }\r\n });\r\n\r\n return create(Model, { ...defaults, ...overrides }, options);\r\n}\r\n\r\n/**\r\n * Upsert (create or update)\r\n */\r\nexport async function upsert<TDoc = AnyDocument>(\r\n Model: Model<TDoc>,\r\n query: Record<string, unknown>,\r\n data: Record<string, unknown>,\r\n options: { session?: ClientSession; updatePipeline?: boolean } = {}\r\n): Promise<TDoc | null> {\r\n return Model.findOneAndUpdate(\r\n query,\r\n { $setOnInsert: data },\r\n {\r\n upsert: true,\r\n new: true,\r\n runValidators: true,\r\n session: options.session,\r\n ...(options.updatePipeline !== undefined ? { updatePipeline: options.updatePipeline } : {}),\r\n }\r\n );\r\n}\r\n","/**\r\n * MongoDB Operations Plugin\r\n *\r\n * Adds MongoDB-specific operations to repositories.\r\n * Requires method-registry.plugin.js to be loaded first.\r\n */\r\n\r\nimport { createError } from '../utils/error.js';\r\nimport * as createActions from '../actions/create.js';\r\nimport type { Plugin, RepositoryInstance, ObjectId } from '../types.js';\r\n\r\n/**\r\n * MongoDB operations plugin\r\n * \r\n * @example\r\n * const repo = new Repository(Model, [\r\n * methodRegistryPlugin(),\r\n * mongoOperationsPlugin(),\r\n * ]);\r\n * \r\n * await repo.increment(productId, 'views', 1);\r\n * await repo.pushToArray(productId, 'tags', 'featured');\r\n */\r\nexport function mongoOperationsPlugin(): Plugin {\r\n return {\r\n name: 'mongo-operations',\r\n\r\n apply(repo: RepositoryInstance): void {\r\n // Check if method-registry is available\r\n if (!repo.registerMethod) {\r\n throw new Error(\r\n 'mongoOperationsPlugin requires methodRegistryPlugin. ' +\r\n 'Add methodRegistryPlugin() before mongoOperationsPlugin() in plugins array.'\r\n );\r\n }\r\n\r\n /**\r\n * Update existing document or insert new one\r\n */\r\n repo.registerMethod('upsert', async function (\r\n this: RepositoryInstance,\r\n query: Record<string, unknown>,\r\n data: Record<string, unknown>,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return createActions.upsert(this.Model, query, data, options);\r\n });\r\n\r\n // Helper: Validate and perform numeric operation\r\n const validateAndUpdateNumeric = async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n field: string,\r\n value: number,\r\n operator: string,\r\n operationName: string,\r\n options: Record<string, unknown>\r\n ) {\r\n if (typeof value !== 'number') {\r\n throw createError(400, `${operationName} value must be a number`);\r\n }\r\n return (this as Record<string, Function>).update(id, { [operator]: { [field]: value } }, options);\r\n };\r\n\r\n /**\r\n * Atomically increment numeric field\r\n */\r\n repo.registerMethod('increment', async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n field: string,\r\n value: number = 1,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return validateAndUpdateNumeric.call(this, id, field, value, '$inc', 'Increment', options);\r\n });\r\n\r\n /**\r\n * Atomically decrement numeric field\r\n */\r\n repo.registerMethod('decrement', async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n field: string,\r\n value: number = 1,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return validateAndUpdateNumeric.call(this, id, field, -value, '$inc', 'Decrement', options);\r\n });\r\n\r\n // Helper: Generic MongoDB operator update\r\n const applyOperator = function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n field: string,\r\n value: unknown,\r\n operator: string,\r\n options: Record<string, unknown>\r\n ) {\r\n return (this as Record<string, Function>).update(id, { [operator]: { [field]: value } }, options);\r\n };\r\n\r\n /**\r\n * Push value to array field\r\n */\r\n repo.registerMethod('pushToArray', async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n field: string,\r\n value: unknown,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return applyOperator.call(this, id, field, value, '$push', options);\r\n });\r\n\r\n /**\r\n * Remove value from array field\r\n */\r\n repo.registerMethod('pullFromArray', async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n field: string,\r\n value: unknown,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return applyOperator.call(this, id, field, value, '$pull', options);\r\n });\r\n\r\n /**\r\n * Add value to array only if not already present (unique)\r\n */\r\n repo.registerMethod('addToSet', async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n field: string,\r\n value: unknown,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return applyOperator.call(this, id, field, value, '$addToSet', options);\r\n });\r\n\r\n /**\r\n * Set field value (alias for update with $set)\r\n */\r\n repo.registerMethod('setField', async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n field: string,\r\n value: unknown,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return applyOperator.call(this, id, field, value, '$set', options);\r\n });\r\n\r\n /**\r\n * Unset (remove) field from document\r\n */\r\n repo.registerMethod('unsetField', async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n fields: string | string[],\r\n options: Record<string, unknown> = {}\r\n ) {\r\n const fieldArray = Array.isArray(fields) ? fields : [fields];\r\n const unsetObj = fieldArray.reduce((acc, field) => {\r\n acc[field] = '';\r\n return acc;\r\n }, {} as Record<string, string>);\r\n\r\n return (this as Record<string, Function>).update(id, { $unset: unsetObj }, options);\r\n });\r\n\r\n /**\r\n * Rename field in document\r\n */\r\n repo.registerMethod('renameField', async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n oldName: string,\r\n newName: string,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return (this as Record<string, Function>).update(id, { $rename: { [oldName]: newName } }, options);\r\n });\r\n\r\n /**\r\n * Multiply numeric field by value\r\n */\r\n repo.registerMethod('multiplyField', async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n field: string,\r\n multiplier: number,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return validateAndUpdateNumeric.call(this, id, field, multiplier, '$mul', 'Multiplier', options);\r\n });\r\n\r\n /**\r\n * Set field to minimum value (only if current value is greater)\r\n */\r\n repo.registerMethod('setMin', async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n field: string,\r\n value: unknown,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return applyOperator.call(this, id, field, value, '$min', options);\r\n });\r\n\r\n /**\r\n * Set field to maximum value (only if current value is less)\r\n */\r\n repo.registerMethod('setMax', async function (\r\n this: RepositoryInstance,\r\n id: string | ObjectId,\r\n field: string,\r\n value: unknown,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return applyOperator.call(this, id, field, value, '$max', options);\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport default mongoOperationsPlugin;\r\n","/**\r\n * Batch Operations Plugin\r\n * Adds bulk update/delete operations with proper event emission\r\n */\r\n\r\nimport type { ClientSession } from 'mongoose';\r\nimport type { Plugin, RepositoryInstance, RepositoryContext, HttpError } from '../types.js';\r\n\r\n/**\r\n * Batch operations plugin\r\n * \r\n * @example\r\n * const repo = new Repository(Model, [\r\n * methodRegistryPlugin(),\r\n * batchOperationsPlugin(),\r\n * ]);\r\n * \r\n * await repo.updateMany({ status: 'pending' }, { status: 'active' });\r\n * await repo.deleteMany({ status: 'deleted' });\r\n */\r\nexport function batchOperationsPlugin(): Plugin {\r\n return {\r\n name: 'batch-operations',\r\n\r\n apply(repo: RepositoryInstance): void {\r\n if (!repo.registerMethod) {\r\n throw new Error('batchOperationsPlugin requires methodRegistryPlugin');\r\n }\r\n\r\n /**\r\n * Update multiple documents\r\n */\r\n repo.registerMethod('updateMany', async function (\r\n this: RepositoryInstance,\r\n query: Record<string, unknown>,\r\n data: Record<string, unknown>,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n const _buildContext = (this as Record<string, Function>)._buildContext;\r\n const context = await _buildContext.call(this, 'updateMany', { query, data, options }) as RepositoryContext;\r\n\r\n try {\r\n this.emit('before:updateMany', context);\r\n\r\n const result = await this.Model.updateMany(query, data, {\r\n runValidators: true,\r\n session: options.session as ClientSession | undefined,\r\n }).exec();\r\n\r\n this.emit('after:updateMany', { context, result });\r\n return result;\r\n } catch (error) {\r\n this.emit('error:updateMany', { context, error });\r\n const _handleError = (this as Record<string, Function>)._handleError;\r\n throw _handleError.call(this, error as Error) as HttpError;\r\n }\r\n });\r\n\r\n /**\r\n * Delete multiple documents\r\n */\r\n repo.registerMethod('deleteMany', async function (\r\n this: RepositoryInstance,\r\n query: Record<string, unknown>,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n const _buildContext = (this as Record<string, Function>)._buildContext;\r\n const context = await _buildContext.call(this, 'deleteMany', { query, options }) as RepositoryContext;\r\n\r\n try {\r\n this.emit('before:deleteMany', context);\r\n\r\n const result = await this.Model.deleteMany(query, {\r\n session: options.session as ClientSession | undefined,\r\n }).exec();\r\n\r\n this.emit('after:deleteMany', { context, result });\r\n return result;\r\n } catch (error) {\r\n this.emit('error:deleteMany', { context, error });\r\n const _handleError = (this as Record<string, Function>)._handleError;\r\n throw _handleError.call(this, error as Error) as HttpError;\r\n }\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport default batchOperationsPlugin;\r\n","/**\r\n * Aggregate Helpers Plugin\r\n * Adds common aggregation helper methods\r\n */\r\n\r\nimport type { PipelineStage } from 'mongoose';\r\nimport type { Plugin, RepositoryInstance } from '../types.js';\r\n\r\n/**\r\n * Aggregate helpers plugin\r\n * \r\n * @example\r\n * const repo = new Repository(Model, [\r\n * methodRegistryPlugin(),\r\n * aggregateHelpersPlugin(),\r\n * ]);\r\n * \r\n * const groups = await repo.groupBy('category');\r\n * const total = await repo.sum('amount', { status: 'completed' });\r\n */\r\nexport function aggregateHelpersPlugin(): Plugin {\r\n return {\r\n name: 'aggregate-helpers',\r\n\r\n apply(repo: RepositoryInstance): void {\r\n if (!repo.registerMethod) {\r\n throw new Error('aggregateHelpersPlugin requires methodRegistryPlugin');\r\n }\r\n\r\n /**\r\n * Group by field\r\n */\r\n repo.registerMethod('groupBy', async function (\r\n this: RepositoryInstance,\r\n field: string,\r\n options: { limit?: number; session?: unknown } = {}\r\n ) {\r\n const pipeline: PipelineStage[] = [\r\n { $group: { _id: `$${field}`, count: { $sum: 1 } } },\r\n { $sort: { count: -1 } },\r\n ];\r\n\r\n if (options.limit) {\r\n pipeline.push({ $limit: options.limit });\r\n }\r\n\r\n const aggregate = (this as Record<string, Function>).aggregate;\r\n return aggregate.call(this, pipeline, options);\r\n });\r\n\r\n // Helper: Generic aggregation operation\r\n const aggregateOperation = async function (\r\n this: RepositoryInstance,\r\n field: string,\r\n operator: string,\r\n resultKey: string,\r\n query: Record<string, unknown> = {},\r\n options: Record<string, unknown> = {}\r\n ): Promise<number> {\r\n const pipeline: PipelineStage[] = [\r\n { $match: query },\r\n { $group: { _id: null, [resultKey]: { [operator]: `$${field}` } } },\r\n ];\r\n\r\n const aggregate = (this as Record<string, Function>).aggregate;\r\n const result = await aggregate.call(this, pipeline, options) as Array<Record<string, number>>;\r\n return result[0]?.[resultKey] || 0;\r\n };\r\n\r\n /**\r\n * Sum field values\r\n */\r\n repo.registerMethod('sum', async function (\r\n this: RepositoryInstance,\r\n field: string,\r\n query: Record<string, unknown> = {},\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return aggregateOperation.call(this, field, '$sum', 'total', query, options);\r\n });\r\n\r\n /**\r\n * Average field values\r\n */\r\n repo.registerMethod('average', async function (\r\n this: RepositoryInstance,\r\n field: string,\r\n query: Record<string, unknown> = {},\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return aggregateOperation.call(this, field, '$avg', 'avg', query, options);\r\n });\r\n\r\n /**\r\n * Get minimum value\r\n */\r\n repo.registerMethod('min', async function (\r\n this: RepositoryInstance,\r\n field: string,\r\n query: Record<string, unknown> = {},\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return aggregateOperation.call(this, field, '$min', 'min', query, options);\r\n });\r\n\r\n /**\r\n * Get maximum value\r\n */\r\n repo.registerMethod('max', async function (\r\n this: RepositoryInstance,\r\n field: string,\r\n query: Record<string, unknown> = {},\r\n options: Record<string, unknown> = {}\r\n ) {\r\n return aggregateOperation.call(this, field, '$max', 'max', query, options);\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport default aggregateHelpersPlugin;\r\n","/**\r\n * Subdocument Plugin\r\n * Adds subdocument array operations\r\n */\r\n\r\nimport type { ClientSession } from 'mongoose';\r\nimport { createError } from '../utils/error.js';\r\nimport type { Plugin, RepositoryInstance, ObjectId } from '../types.js';\r\n\r\n/**\r\n * Subdocument plugin for managing nested arrays\r\n * \r\n * @example\r\n * const repo = new Repository(Model, [\r\n * methodRegistryPlugin(),\r\n * subdocumentPlugin(),\r\n * ]);\r\n * \r\n * await repo.addSubdocument(parentId, 'items', { name: 'Item 1' });\r\n * await repo.updateSubdocument(parentId, 'items', itemId, { name: 'Updated Item' });\r\n */\r\nexport function subdocumentPlugin(): Plugin {\r\n return {\r\n name: 'subdocument',\r\n\r\n apply(repo: RepositoryInstance): void {\r\n if (!repo.registerMethod) {\r\n throw new Error('subdocumentPlugin requires methodRegistryPlugin');\r\n }\r\n\r\n /**\r\n * Add subdocument to array\r\n */\r\n repo.registerMethod('addSubdocument', async function (\r\n this: RepositoryInstance,\r\n parentId: string | ObjectId,\r\n arrayPath: string,\r\n subData: Record<string, unknown>,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n const update = (this as Record<string, Function>).update;\r\n return update.call(this, parentId, { $push: { [arrayPath]: subData } }, options);\r\n });\r\n\r\n /**\r\n * Get subdocument from array\r\n */\r\n repo.registerMethod('getSubdocument', async function (\r\n this: RepositoryInstance,\r\n parentId: string | ObjectId,\r\n arrayPath: string,\r\n subId: string | ObjectId,\r\n options: { lean?: boolean; session?: unknown } = {}\r\n ) {\r\n const _executeQuery = (this as Record<string, Function>)._executeQuery;\r\n return _executeQuery.call(this, async (Model: typeof this.Model) => {\r\n const parent = await Model.findById(parentId).session(options.session as never).exec();\r\n if (!parent) throw createError(404, 'Parent not found');\r\n\r\n const parentObj = parent as Record<string, unknown>;\r\n const arrayField = parentObj[arrayPath] as { id: (id: string | ObjectId) => Record<string, unknown> | null } | undefined;\r\n \r\n if (!arrayField || typeof arrayField.id !== 'function') {\r\n throw createError(404, 'Array field not found');\r\n }\r\n\r\n const sub = arrayField.id(subId);\r\n if (!sub) throw createError(404, 'Subdocument not found');\r\n\r\n return options.lean && typeof (sub as Record<string, unknown>).toObject === 'function'\r\n ? (sub as { toObject: () => Record<string, unknown> }).toObject()\r\n : sub;\r\n });\r\n });\r\n\r\n /**\r\n * Update subdocument in array\r\n */\r\n repo.registerMethod('updateSubdocument', async function (\r\n this: RepositoryInstance,\r\n parentId: string | ObjectId,\r\n arrayPath: string,\r\n subId: string | ObjectId,\r\n updateData: Record<string, unknown>,\r\n options: { session?: unknown } = {}\r\n ) {\r\n const _executeQuery = (this as Record<string, Function>)._executeQuery;\r\n return _executeQuery.call(this, async (Model: typeof this.Model) => {\r\n const query = { _id: parentId, [`${arrayPath}._id`]: subId };\r\n const update = { $set: { [`${arrayPath}.$`]: { ...updateData, _id: subId } } };\r\n\r\n const result = await Model.findOneAndUpdate(query, update, {\r\n new: true,\r\n runValidators: true,\r\n session: options.session as ClientSession | undefined,\r\n }).exec();\r\n\r\n if (!result) throw createError(404, 'Parent or subdocument not found');\r\n return result;\r\n });\r\n });\r\n\r\n /**\r\n * Delete subdocument from array\r\n */\r\n repo.registerMethod('deleteSubdocument', async function (\r\n this: RepositoryInstance,\r\n parentId: string | ObjectId,\r\n arrayPath: string,\r\n subId: string | ObjectId,\r\n options: Record<string, unknown> = {}\r\n ) {\r\n const update = (this as Record<string, Function>).update;\r\n return update.call(this, parentId, { $pull: { [arrayPath]: { _id: subId } } }, options);\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport default subdocumentPlugin;\r\n","/**\r\n * Cache Key Utilities\r\n * \r\n * Generates deterministic, collision-free cache keys for MongoDB queries.\r\n * Key design inspired by Next.js cache tags and best practices from Stripe/Meta.\r\n */\r\n\r\nimport type { SortSpec, SelectSpec, PopulateSpec } from '../types.js';\r\n\r\n/**\r\n * Simple hash function for query parameters\r\n * Using djb2 algorithm - fast and good distribution\r\n */\r\nfunction hashString(str: string): string {\r\n let hash = 5381;\r\n for (let i = 0; i < str.length; i++) {\r\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i);\r\n }\r\n // Convert to positive hex string\r\n return (hash >>> 0).toString(16);\r\n}\r\n\r\n/**\r\n * Normalize and stringify an object for hashing\r\n * Ensures deterministic key generation regardless of property order\r\n */\r\nfunction stableStringify(obj: unknown): string {\r\n if (obj === null || obj === undefined) return '';\r\n if (typeof obj !== 'object') return String(obj);\r\n if (Array.isArray(obj)) {\r\n return '[' + obj.map(stableStringify).join(',') + ']';\r\n }\r\n \r\n const sorted = Object.keys(obj as Record<string, unknown>)\r\n .sort()\r\n .map(key => `${key}:${stableStringify((obj as Record<string, unknown>)[key])}`);\r\n return '{' + sorted.join(',') + '}';\r\n}\r\n\r\n/**\r\n * Generate cache key for getById operations\r\n * \r\n * Format: {prefix}:id:{model}:{documentId}\r\n * \r\n * @example\r\n * byIdKey('mk', 'User', '507f1f77bcf86cd799439011')\r\n * // => 'mk:id:User:507f1f77bcf86cd799439011'\r\n */\r\nexport function byIdKey(prefix: string, model: string, id: string): string {\r\n return `${prefix}:id:${model}:${id}`;\r\n}\r\n\r\n/**\r\n * Generate cache key for single-document queries\r\n * \r\n * Format: {prefix}:one:{model}:{queryHash}\r\n * \r\n * @example\r\n * byQueryKey('mk', 'User', { email: 'john@example.com' })\r\n * // => 'mk:one:User:a1b2c3d4'\r\n */\r\nexport function byQueryKey(\r\n prefix: string,\r\n model: string,\r\n query: Record<string, unknown>,\r\n options?: { select?: SelectSpec; populate?: PopulateSpec }\r\n): string {\r\n const hashInput = stableStringify({ q: query, s: options?.select, p: options?.populate });\r\n return `${prefix}:one:${model}:${hashString(hashInput)}`;\r\n}\r\n\r\n/**\r\n * Generate cache key for paginated list queries\r\n * \r\n * Format: {prefix}:list:{model}:{version}:{queryHash}\r\n * \r\n * The version component enables efficient bulk invalidation:\r\n * - On any mutation, bump the version\r\n * - All list cache keys become invalid without scanning/deleting each\r\n * \r\n * @example\r\n * listQueryKey('mk', 'User', 1, { filters: { status: 'active' }, page: 1, limit: 20 })\r\n * // => 'mk:list:User:1:e5f6g7h8'\r\n */\r\nexport function listQueryKey(\r\n prefix: string,\r\n model: string,\r\n version: number,\r\n params: {\r\n filters?: Record<string, unknown>;\r\n sort?: SortSpec;\r\n page?: number;\r\n limit?: number;\r\n after?: string;\r\n select?: SelectSpec;\r\n populate?: PopulateSpec;\r\n }\r\n): string {\r\n const hashInput = stableStringify({\r\n f: params.filters,\r\n s: params.sort,\r\n pg: params.page,\r\n lm: params.limit,\r\n af: params.after,\r\n sl: params.select,\r\n pp: params.populate,\r\n });\r\n return `${prefix}:list:${model}:${version}:${hashString(hashInput)}`;\r\n}\r\n\r\n/**\r\n * Generate cache key for collection version tag\r\n * \r\n * Format: {prefix}:ver:{model}\r\n * \r\n * Used to track mutation version for list invalidation\r\n */\r\nexport function versionKey(prefix: string, model: string): string {\r\n return `${prefix}:ver:${model}`;\r\n}\r\n\r\n/**\r\n * Generate pattern for clearing all cache keys for a model\r\n * \r\n * Format: {prefix}:*:{model}:*\r\n * \r\n * @example\r\n * modelPattern('mk', 'User')\r\n * // => 'mk:*:User:*'\r\n */\r\nexport function modelPattern(prefix: string, model: string): string {\r\n return `${prefix}:*:${model}:*`;\r\n}\r\n\r\n/**\r\n * Generate pattern for clearing all list cache keys for a model\r\n * \r\n * Format: {prefix}:list:{model}:*\r\n */\r\nexport function listPattern(prefix: string, model: string): string {\r\n return `${prefix}:list:${model}:*`;\r\n}\r\n\r\n","/**\r\n * Cache Plugin\r\n * \r\n * Optional caching layer for MongoKit with automatic invalidation.\r\n * Bring-your-own cache adapter (Redis, Memcached, in-memory, etc.)\r\n * \r\n * Features:\r\n * - Cache-aside (read-through) pattern with configurable TTLs\r\n * - Automatic invalidation on create/update/delete\r\n * - Collection version tags for efficient list cache invalidation\r\n * - Manual invalidation methods for microservice scenarios\r\n * - Skip cache per-operation with `skipCache: true`\r\n * \r\n * @example\r\n * ```typescript\r\n * import { Repository, cachePlugin } from '@classytic/mongokit';\r\n * import Redis from 'ioredis';\r\n * \r\n * const redis = new Redis();\r\n * \r\n * const userRepo = new Repository(UserModel, [\r\n * cachePlugin({\r\n * adapter: {\r\n * async get(key) { return JSON.parse(await redis.get(key) || 'null'); },\r\n * async set(key, value, ttl) { await redis.setex(key, ttl, JSON.stringify(value)); },\r\n * async del(key) { await redis.del(key); },\r\n * async clear(pattern) {\r\n * const keys = await redis.keys(pattern || '*');\r\n * if (keys.length) await redis.del(...keys);\r\n * }\r\n * },\r\n * ttl: 60, // 1 minute default\r\n * })\r\n * ]);\r\n * \r\n * // Reads check cache first\r\n * const user = await userRepo.getById(id); // cached\r\n * \r\n * // Skip cache for fresh data\r\n * const fresh = await userRepo.getById(id, { skipCache: true });\r\n * \r\n * // Mutations auto-invalidate\r\n * await userRepo.update(id, { name: 'New Name' }); // invalidates cache\r\n * \r\n * // Manual invalidation for microservice sync\r\n * await userRepo.invalidateCache(id); // invalidate single doc\r\n * await userRepo.invalidateAllCache(); // invalidate all for this model\r\n * ```\r\n */\r\n\r\nimport type {\r\n Plugin,\r\n RepositoryContext,\r\n RepositoryInstance,\r\n CacheAdapter,\r\n CacheOptions,\r\n CacheStats,\r\n SortSpec,\r\n} from '../types.js';\r\nimport {\r\n byIdKey,\r\n byQueryKey,\r\n listQueryKey,\r\n versionKey,\r\n modelPattern,\r\n} from '../utils/cache-keys.js';\r\n\r\n/** Internal resolved options */\r\ninterface ResolvedCacheOptions {\r\n adapter: CacheAdapter;\r\n ttl: number;\r\n byIdTtl: number;\r\n queryTtl: number;\r\n prefix: string;\r\n debug: boolean;\r\n skipIfLargeLimit: number;\r\n}\r\n\r\n/**\r\n * Cache plugin factory\r\n * \r\n * @param options - Cache configuration\r\n * @returns Plugin instance\r\n */\r\nexport function cachePlugin(options: CacheOptions): Plugin {\r\n const config: ResolvedCacheOptions = {\r\n adapter: options.adapter,\r\n ttl: options.ttl ?? 60,\r\n byIdTtl: options.byIdTtl ?? options.ttl ?? 60,\r\n queryTtl: options.queryTtl ?? options.ttl ?? 60,\r\n prefix: options.prefix ?? 'mk',\r\n debug: options.debug ?? false,\r\n skipIfLargeLimit: options.skipIf?.largeLimit ?? 100,\r\n };\r\n\r\n // Stats for monitoring\r\n const stats: CacheStats = {\r\n hits: 0,\r\n misses: 0,\r\n sets: 0,\r\n invalidations: 0,\r\n };\r\n\r\n // Collection version for list invalidation (in-memory, synced to cache)\r\n let collectionVersion = 0;\r\n\r\n const log = (msg: string, data?: unknown) => {\r\n if (config.debug) {\r\n console.log(`[mongokit:cache] ${msg}`, data ?? '');\r\n }\r\n };\r\n\r\n return {\r\n name: 'cache',\r\n\r\n apply(repo: RepositoryInstance): void {\r\n const model = repo.model;\r\n\r\n // Initialize version from cache on startup\r\n (async () => {\r\n try {\r\n const cached = await config.adapter.get<number>(versionKey(config.prefix, model));\r\n if (cached !== null) {\r\n collectionVersion = cached;\r\n log(`Initialized version for ${model}:`, collectionVersion);\r\n }\r\n } catch (e) {\r\n log(`Failed to initialize version for ${model}:`, e);\r\n }\r\n })();\r\n\r\n /**\r\n * Helper to bump collection version (invalidates all list caches)\r\n */\r\n async function bumpVersion(): Promise<void> {\r\n collectionVersion++;\r\n try {\r\n await config.adapter.set(versionKey(config.prefix, model), collectionVersion, config.ttl * 10);\r\n stats.invalidations++;\r\n log(`Bumped version for ${model} to:`, collectionVersion);\r\n } catch (e) {\r\n log(`Failed to bump version for ${model}:`, e);\r\n }\r\n }\r\n\r\n /**\r\n * Helper to invalidate a specific document by ID\r\n */\r\n async function invalidateById(id: string): Promise<void> {\r\n const key = byIdKey(config.prefix, model, id);\r\n try {\r\n await config.adapter.del(key);\r\n stats.invalidations++;\r\n log(`Invalidated byId cache:`, key);\r\n } catch (e) {\r\n log(`Failed to invalidate byId cache:`, e);\r\n }\r\n }\r\n\r\n // ============================================================\r\n // READ HOOKS - Check cache before DB query\r\n // ============================================================\r\n\r\n /**\r\n * before:getById - Check cache for document\r\n */\r\n repo.on('before:getById', async (context: RepositoryContext) => {\r\n if ((context as Record<string, unknown>).skipCache) {\r\n log(`Skipping cache for getById: ${context.id}`);\r\n return;\r\n }\r\n\r\n const id = String(context.id);\r\n const key = byIdKey(config.prefix, model, id);\r\n\r\n try {\r\n const cached = await config.adapter.get(key);\r\n if (cached !== null) {\r\n stats.hits++;\r\n log(`Cache HIT for getById:`, key);\r\n // Store in context for Repository to use\r\n (context as Record<string, unknown>)._cacheHit = true;\r\n (context as Record<string, unknown>)._cachedResult = cached;\r\n } else {\r\n stats.misses++;\r\n log(`Cache MISS for getById:`, key);\r\n }\r\n } catch (e) {\r\n log(`Cache error for getById:`, e);\r\n stats.misses++;\r\n }\r\n });\r\n\r\n /**\r\n * before:getByQuery - Check cache for single-doc query\r\n */\r\n repo.on('before:getByQuery', async (context: RepositoryContext) => {\r\n if ((context as Record<string, unknown>).skipCache) {\r\n log(`Skipping cache for getByQuery`);\r\n return;\r\n }\r\n\r\n const query = (context.query || {}) as Record<string, unknown>;\r\n const key = byQueryKey(config.prefix, model, query, {\r\n select: context.select,\r\n populate: context.populate,\r\n });\r\n\r\n try {\r\n const cached = await config.adapter.get(key);\r\n if (cached !== null) {\r\n stats.hits++;\r\n log(`Cache HIT for getByQuery:`, key);\r\n (context as Record<string, unknown>)._cacheHit = true;\r\n (context as Record<string, unknown>)._cachedResult = cached;\r\n } else {\r\n stats.misses++;\r\n log(`Cache MISS for getByQuery:`, key);\r\n }\r\n } catch (e) {\r\n log(`Cache error for getByQuery:`, e);\r\n stats.misses++;\r\n }\r\n });\r\n\r\n /**\r\n * before:getAll - Check cache for list query\r\n */\r\n repo.on('before:getAll', async (context: RepositoryContext) => {\r\n if ((context as Record<string, unknown>).skipCache) {\r\n log(`Skipping cache for getAll`);\r\n return;\r\n }\r\n\r\n // Skip caching large result sets\r\n const limit = (context as Record<string, unknown>).limit as number | undefined;\r\n if (limit && limit > config.skipIfLargeLimit) {\r\n log(`Skipping cache for large query (limit: ${limit})`);\r\n return;\r\n }\r\n\r\n const params = {\r\n filters: (context as Record<string, unknown>).filters as Record<string, unknown> | undefined,\r\n sort: (context as Record<string, unknown>).sort as SortSpec | undefined,\r\n page: (context as Record<string, unknown>).page as number | undefined,\r\n limit,\r\n after: (context as Record<string, unknown>).after as string | undefined,\r\n select: context.select,\r\n populate: context.populate,\r\n };\r\n\r\n const key = listQueryKey(config.prefix, model, collectionVersion, params);\r\n\r\n try {\r\n const cached = await config.adapter.get(key);\r\n if (cached !== null) {\r\n stats.hits++;\r\n log(`Cache HIT for getAll:`, key);\r\n (context as Record<string, unknown>)._cacheHit = true;\r\n (context as Record<string, unknown>)._cachedResult = cached;\r\n } else {\r\n stats.misses++;\r\n log(`Cache MISS for getAll:`, key);\r\n }\r\n } catch (e) {\r\n log(`Cache error for getAll:`, e);\r\n stats.misses++;\r\n }\r\n });\r\n\r\n // ============================================================\r\n // AFTER HOOKS - Store results in cache\r\n // ============================================================\r\n\r\n /**\r\n * after:getById - Cache the result\r\n */\r\n repo.on('after:getById', async (payload: { context: RepositoryContext; result: unknown }) => {\r\n const { context, result } = payload;\r\n \r\n // Don't cache if we got a cache hit (result came from cache)\r\n if ((context as Record<string, unknown>)._cacheHit) return;\r\n if ((context as Record<string, unknown>).skipCache) return;\r\n if (result === null) return; // Don't cache not-found\r\n\r\n const id = String(context.id);\r\n const key = byIdKey(config.prefix, model, id);\r\n const ttl = ((context as Record<string, unknown>).cacheTtl as number) ?? config.byIdTtl;\r\n\r\n try {\r\n await config.adapter.set(key, result, ttl);\r\n stats.sets++;\r\n log(`Cached getById result:`, key);\r\n } catch (e) {\r\n log(`Failed to cache getById:`, e);\r\n }\r\n });\r\n\r\n /**\r\n * after:getByQuery - Cache the result\r\n */\r\n repo.on('after:getByQuery', async (payload: { context: RepositoryContext; result: unknown }) => {\r\n const { context, result } = payload;\r\n \r\n if ((context as Record<string, unknown>)._cacheHit) return;\r\n if ((context as Record<string, unknown>).skipCache) return;\r\n if (result === null) return;\r\n\r\n const query = (context.query || {}) as Record<string, unknown>;\r\n const key = byQueryKey(config.prefix, model, query, {\r\n select: context.select,\r\n populate: context.populate,\r\n });\r\n const ttl = ((context as Record<string, unknown>).cacheTtl as number) ?? config.queryTtl;\r\n\r\n try {\r\n await config.adapter.set(key, result, ttl);\r\n stats.sets++;\r\n log(`Cached getByQuery result:`, key);\r\n } catch (e) {\r\n log(`Failed to cache getByQuery:`, e);\r\n }\r\n });\r\n\r\n /**\r\n * after:getAll - Cache the result\r\n */\r\n repo.on('after:getAll', async (payload: { context: RepositoryContext; result: unknown }) => {\r\n const { context, result } = payload;\r\n \r\n if ((context as Record<string, unknown>)._cacheHit) return;\r\n if ((context as Record<string, unknown>).skipCache) return;\r\n\r\n const limit = (context as Record<string, unknown>).limit as number | undefined;\r\n if (limit && limit > config.skipIfLargeLimit) return;\r\n\r\n const params = {\r\n filters: (context as Record<string, unknown>).filters as Record<string, unknown> | undefined,\r\n sort: (context as Record<string, unknown>).sort as SortSpec | undefined,\r\n page: (context as Record<string, unknown>).page as number | undefined,\r\n limit,\r\n after: (context as Record<string, unknown>).after as string | undefined,\r\n select: context.select,\r\n populate: context.populate,\r\n };\r\n\r\n const key = listQueryKey(config.prefix, model, collectionVersion, params);\r\n const ttl = ((context as Record<string, unknown>).cacheTtl as number) ?? config.queryTtl;\r\n\r\n try {\r\n await config.adapter.set(key, result, ttl);\r\n stats.sets++;\r\n log(`Cached getAll result:`, key);\r\n } catch (e) {\r\n log(`Failed to cache getAll:`, e);\r\n }\r\n });\r\n\r\n // ============================================================\r\n // WRITE HOOKS - Invalidate cache on mutations\r\n // ============================================================\r\n\r\n /**\r\n * after:create - Bump version to invalidate list caches\r\n */\r\n repo.on('after:create', async () => {\r\n await bumpVersion();\r\n });\r\n\r\n /**\r\n * after:createMany - Bump version to invalidate list caches\r\n */\r\n repo.on('after:createMany', async () => {\r\n await bumpVersion();\r\n });\r\n\r\n /**\r\n * after:update - Invalidate by ID and bump version\r\n */\r\n repo.on('after:update', async (payload: { context: RepositoryContext; result: unknown }) => {\r\n const { context } = payload;\r\n const id = String(context.id);\r\n \r\n await Promise.all([\r\n invalidateById(id),\r\n bumpVersion(),\r\n ]);\r\n });\r\n\r\n /**\r\n * after:updateMany - Bump version (can't track individual IDs efficiently)\r\n */\r\n repo.on('after:updateMany', async () => {\r\n await bumpVersion();\r\n });\r\n\r\n /**\r\n * after:delete - Invalidate by ID and bump version\r\n */\r\n repo.on('after:delete', async (payload: { context: RepositoryContext }) => {\r\n const { context } = payload;\r\n const id = String(context.id);\r\n \r\n await Promise.all([\r\n invalidateById(id),\r\n bumpVersion(),\r\n ]);\r\n });\r\n\r\n /**\r\n * after:deleteMany - Bump version\r\n */\r\n repo.on('after:deleteMany', async () => {\r\n await bumpVersion();\r\n });\r\n\r\n // ============================================================\r\n // PUBLIC METHODS - Manual invalidation for microservices\r\n // ============================================================\r\n\r\n /**\r\n * Invalidate cache for a specific document\r\n * Use when document was updated outside this service\r\n * \r\n * @example\r\n * await userRepo.invalidateCache('507f1f77bcf86cd799439011');\r\n */\r\n repo.invalidateCache = async (id: string): Promise<void> => {\r\n await invalidateById(id);\r\n log(`Manual invalidation for ID:`, id);\r\n };\r\n\r\n /**\r\n * Invalidate all list caches for this model\r\n * Use when bulk changes happened outside this service\r\n * \r\n * @example\r\n * await userRepo.invalidateListCache();\r\n */\r\n repo.invalidateListCache = async (): Promise<void> => {\r\n await bumpVersion();\r\n log(`Manual list cache invalidation for ${model}`);\r\n };\r\n\r\n /**\r\n * Invalidate ALL cache entries for this model\r\n * Nuclear option - use sparingly\r\n * \r\n * @example\r\n * await userRepo.invalidateAllCache();\r\n */\r\n repo.invalidateAllCache = async (): Promise<void> => {\r\n if (config.adapter.clear) {\r\n try {\r\n await config.adapter.clear(modelPattern(config.prefix, model));\r\n stats.invalidations++;\r\n log(`Full cache invalidation for ${model}`);\r\n } catch (e) {\r\n log(`Failed full cache invalidation for ${model}:`, e);\r\n }\r\n } else {\r\n // Fallback: just bump version (invalidates lists) \r\n await bumpVersion();\r\n log(`Partial cache invalidation for ${model} (adapter.clear not available)`);\r\n }\r\n };\r\n\r\n /**\r\n * Get cache statistics for monitoring\r\n * \r\n * @example\r\n * const stats = userRepo.getCacheStats();\r\n * console.log(`Hit rate: ${stats.hits / (stats.hits + stats.misses) * 100}%`);\r\n */\r\n repo.getCacheStats = (): CacheStats => ({ ...stats });\r\n\r\n /**\r\n * Reset cache statistics\r\n */\r\n repo.resetCacheStats = (): void => {\r\n stats.hits = 0;\r\n stats.misses = 0;\r\n stats.sets = 0;\r\n stats.invalidations = 0;\r\n };\r\n },\r\n };\r\n}\r\n\r\nexport default cachePlugin;\r\n\r\n"]}
@@ -1,275 +0,0 @@
1
- import { F as FieldPreset, p as Plugin, L as Logger, B as SoftDeleteOptions, r as RepositoryInstance, y as ValidatorDefinition, z as ValidationChainOptions, R as RepositoryContext, Q as CacheOptions } from '../types-Nxhmi1aI.cjs';
2
- import 'mongoose';
3
-
4
- /**
5
- * Field Filter Plugin
6
- * Automatically filters response fields based on user roles
7
- */
8
-
9
- /**
10
- * Field filter plugin that restricts fields based on user context
11
- *
12
- * @example
13
- * const fieldPreset = {
14
- * public: ['id', 'name'],
15
- * authenticated: ['email'],
16
- * admin: ['createdAt', 'internalNotes']
17
- * };
18
- *
19
- * const repo = new Repository(Model, [fieldFilterPlugin(fieldPreset)]);
20
- */
21
- declare function fieldFilterPlugin(fieldPreset: FieldPreset): Plugin;
22
-
23
- /**
24
- * Timestamp Plugin
25
- * Auto-injects createdAt/updatedAt timestamps on create/update
26
- */
27
-
28
- /**
29
- * Timestamp plugin that auto-injects timestamps
30
- *
31
- * @example
32
- * const repo = new Repository(Model, [timestampPlugin()]);
33
- */
34
- declare function timestampPlugin(): Plugin;
35
-
36
- /**
37
- * Audit Log Plugin
38
- * Logs repository operations for auditing purposes
39
- */
40
-
41
- /**
42
- * Audit log plugin that logs all repository operations
43
- *
44
- * @example
45
- * const repo = new Repository(Model, [auditLogPlugin(console)]);
46
- */
47
- declare function auditLogPlugin(logger: Logger): Plugin;
48
-
49
- /**
50
- * Soft Delete Plugin
51
- * Implements soft delete pattern - marks documents as deleted instead of removing
52
- */
53
-
54
- /**
55
- * Soft delete plugin
56
- *
57
- * @example
58
- * const repo = new Repository(Model, [
59
- * softDeletePlugin({ deletedField: 'deletedAt' })
60
- * ]);
61
- */
62
- declare function softDeletePlugin(options?: SoftDeleteOptions): Plugin;
63
-
64
- /**
65
- * Method Registry Plugin
66
- *
67
- * Enables plugins to dynamically add methods to repository instances.
68
- * Foundation for extensibility - allows other plugins to extend repositories
69
- * with custom methods while maintaining type safety and proper binding.
70
- *
71
- * @example
72
- * ```typescript
73
- * const repo = new Repository(User, [methodRegistryPlugin()]);
74
- *
75
- * // Now you can register custom methods
76
- * repo.registerMethod('findActive', async function() {
77
- * return this.getAll({ filters: { status: 'active' } });
78
- * });
79
- * ```
80
- */
81
-
82
- /**
83
- * Extended repository interface with method registry
84
- */
85
- interface MethodRegistryRepository extends RepositoryInstance {
86
- registerMethod(name: string, fn: Function): void;
87
- hasMethod(name: string): boolean;
88
- getRegisteredMethods(): string[];
89
- }
90
- /**
91
- * Method registry plugin that enables dynamic method registration
92
- */
93
- declare function methodRegistryPlugin(): Plugin;
94
-
95
- /**
96
- * Validation Chain Plugin
97
- *
98
- * Composable validation for repository operations with customizable rules.
99
- */
100
-
101
- type OperationType = 'create' | 'createMany' | 'update' | 'delete';
102
- /**
103
- * Validation chain plugin
104
- *
105
- * @example
106
- * const repo = new Repository(Model, [
107
- * validationChainPlugin([
108
- * requireField('email'),
109
- * uniqueField('email', 'Email already exists'),
110
- * blockIf('no-delete-admin', ['delete'], ctx => ctx.data?.role === 'admin', 'Cannot delete admin'),
111
- * ])
112
- * ]);
113
- */
114
- declare function validationChainPlugin(validators?: ValidatorDefinition[], options?: ValidationChainOptions): Plugin;
115
- /**
116
- * Block operation if condition is true
117
- *
118
- * @example
119
- * blockIf('block-library', ['delete'], ctx => ctx.data?.managed, 'Cannot delete managed records')
120
- */
121
- declare function blockIf(name: string, operations: OperationType[], condition: (context: RepositoryContext) => boolean, errorMessage: string): ValidatorDefinition;
122
- /**
123
- * Require a field to be present
124
- */
125
- declare function requireField(field: string, operations?: OperationType[]): ValidatorDefinition;
126
- /**
127
- * Auto-inject a value if not present
128
- */
129
- declare function autoInject(field: string, getter: (context: RepositoryContext) => unknown, operations?: OperationType[]): ValidatorDefinition;
130
- /**
131
- * Make a field immutable (cannot be updated)
132
- */
133
- declare function immutableField(field: string): ValidatorDefinition;
134
- /**
135
- * Ensure field value is unique
136
- */
137
- declare function uniqueField(field: string, errorMessage?: string): ValidatorDefinition;
138
-
139
- /**
140
- * MongoDB Operations Plugin
141
- *
142
- * Adds MongoDB-specific operations to repositories.
143
- * Requires method-registry.plugin.js to be loaded first.
144
- */
145
-
146
- /**
147
- * MongoDB operations plugin
148
- *
149
- * @example
150
- * const repo = new Repository(Model, [
151
- * methodRegistryPlugin(),
152
- * mongoOperationsPlugin(),
153
- * ]);
154
- *
155
- * await repo.increment(productId, 'views', 1);
156
- * await repo.pushToArray(productId, 'tags', 'featured');
157
- */
158
- declare function mongoOperationsPlugin(): Plugin;
159
-
160
- /**
161
- * Batch Operations Plugin
162
- * Adds bulk update/delete operations with proper event emission
163
- */
164
-
165
- /**
166
- * Batch operations plugin
167
- *
168
- * @example
169
- * const repo = new Repository(Model, [
170
- * methodRegistryPlugin(),
171
- * batchOperationsPlugin(),
172
- * ]);
173
- *
174
- * await repo.updateMany({ status: 'pending' }, { status: 'active' });
175
- * await repo.deleteMany({ status: 'deleted' });
176
- */
177
- declare function batchOperationsPlugin(): Plugin;
178
-
179
- /**
180
- * Aggregate Helpers Plugin
181
- * Adds common aggregation helper methods
182
- */
183
-
184
- /**
185
- * Aggregate helpers plugin
186
- *
187
- * @example
188
- * const repo = new Repository(Model, [
189
- * methodRegistryPlugin(),
190
- * aggregateHelpersPlugin(),
191
- * ]);
192
- *
193
- * const groups = await repo.groupBy('category');
194
- * const total = await repo.sum('amount', { status: 'completed' });
195
- */
196
- declare function aggregateHelpersPlugin(): Plugin;
197
-
198
- /**
199
- * Subdocument Plugin
200
- * Adds subdocument array operations
201
- */
202
-
203
- /**
204
- * Subdocument plugin for managing nested arrays
205
- *
206
- * @example
207
- * const repo = new Repository(Model, [
208
- * methodRegistryPlugin(),
209
- * subdocumentPlugin(),
210
- * ]);
211
- *
212
- * await repo.addSubdocument(parentId, 'items', { name: 'Item 1' });
213
- * await repo.updateSubdocument(parentId, 'items', itemId, { name: 'Updated Item' });
214
- */
215
- declare function subdocumentPlugin(): Plugin;
216
-
217
- /**
218
- * Cache Plugin
219
- *
220
- * Optional caching layer for MongoKit with automatic invalidation.
221
- * Bring-your-own cache adapter (Redis, Memcached, in-memory, etc.)
222
- *
223
- * Features:
224
- * - Cache-aside (read-through) pattern with configurable TTLs
225
- * - Automatic invalidation on create/update/delete
226
- * - Collection version tags for efficient list cache invalidation
227
- * - Manual invalidation methods for microservice scenarios
228
- * - Skip cache per-operation with `skipCache: true`
229
- *
230
- * @example
231
- * ```typescript
232
- * import { Repository, cachePlugin } from '@classytic/mongokit';
233
- * import Redis from 'ioredis';
234
- *
235
- * const redis = new Redis();
236
- *
237
- * const userRepo = new Repository(UserModel, [
238
- * cachePlugin({
239
- * adapter: {
240
- * async get(key) { return JSON.parse(await redis.get(key) || 'null'); },
241
- * async set(key, value, ttl) { await redis.setex(key, ttl, JSON.stringify(value)); },
242
- * async del(key) { await redis.del(key); },
243
- * async clear(pattern) {
244
- * const keys = await redis.keys(pattern || '*');
245
- * if (keys.length) await redis.del(...keys);
246
- * }
247
- * },
248
- * ttl: 60, // 1 minute default
249
- * })
250
- * ]);
251
- *
252
- * // Reads check cache first
253
- * const user = await userRepo.getById(id); // cached
254
- *
255
- * // Skip cache for fresh data
256
- * const fresh = await userRepo.getById(id, { skipCache: true });
257
- *
258
- * // Mutations auto-invalidate
259
- * await userRepo.update(id, { name: 'New Name' }); // invalidates cache
260
- *
261
- * // Manual invalidation for microservice sync
262
- * await userRepo.invalidateCache(id); // invalidate single doc
263
- * await userRepo.invalidateAllCache(); // invalidate all for this model
264
- * ```
265
- */
266
-
267
- /**
268
- * Cache plugin factory
269
- *
270
- * @param options - Cache configuration
271
- * @returns Plugin instance
272
- */
273
- declare function cachePlugin(options: CacheOptions): Plugin;
274
-
275
- export { type MethodRegistryRepository, aggregateHelpersPlugin, auditLogPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, fieldFilterPlugin, immutableField, methodRegistryPlugin, mongoOperationsPlugin, requireField, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin };