@classytic/mongokit 2.0.0 → 3.0.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.
Files changed (105) hide show
  1. package/README.md +221 -7
  2. package/dist/actions/index.d.ts +3 -0
  3. package/dist/actions/index.js +473 -0
  4. package/dist/actions/index.js.map +1 -0
  5. package/dist/index-CgOJ2pqz.d.ts +337 -0
  6. package/dist/index.d.ts +239 -0
  7. package/dist/index.js +2108 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/memory-cache-DG2oSSbx.d.ts +142 -0
  10. package/dist/pagination/PaginationEngine.d.ts +117 -0
  11. package/dist/pagination/PaginationEngine.js +369 -0
  12. package/dist/pagination/PaginationEngine.js.map +1 -0
  13. package/dist/plugins/index.d.ts +275 -0
  14. package/dist/plugins/index.js +857 -0
  15. package/dist/plugins/index.js.map +1 -0
  16. package/dist/types-Nxhmi1aI.d.ts +510 -0
  17. package/dist/utils/index.d.ts +189 -0
  18. package/dist/utils/index.js +643 -0
  19. package/dist/utils/index.js.map +1 -0
  20. package/package.json +38 -21
  21. package/src/Repository.js +0 -296
  22. package/src/actions/aggregate.js +0 -266
  23. package/src/actions/create.js +0 -59
  24. package/src/actions/delete.js +0 -88
  25. package/src/actions/index.js +0 -11
  26. package/src/actions/read.js +0 -188
  27. package/src/actions/update.js +0 -176
  28. package/src/hooks/lifecycle.js +0 -146
  29. package/src/index.js +0 -71
  30. package/src/pagination/PaginationEngine.js +0 -348
  31. package/src/pagination/utils/cursor.js +0 -119
  32. package/src/pagination/utils/filter.js +0 -42
  33. package/src/pagination/utils/limits.js +0 -82
  34. package/src/pagination/utils/sort.js +0 -101
  35. package/src/plugins/aggregate-helpers.plugin.js +0 -71
  36. package/src/plugins/audit-log.plugin.js +0 -60
  37. package/src/plugins/batch-operations.plugin.js +0 -66
  38. package/src/plugins/field-filter.plugin.js +0 -27
  39. package/src/plugins/index.js +0 -19
  40. package/src/plugins/method-registry.plugin.js +0 -140
  41. package/src/plugins/mongo-operations.plugin.js +0 -317
  42. package/src/plugins/soft-delete.plugin.js +0 -46
  43. package/src/plugins/subdocument.plugin.js +0 -66
  44. package/src/plugins/timestamp.plugin.js +0 -19
  45. package/src/plugins/validation-chain.plugin.js +0 -145
  46. package/src/types.d.ts +0 -87
  47. package/src/utils/error.js +0 -12
  48. package/src/utils/field-selection.js +0 -156
  49. package/src/utils/index.js +0 -12
  50. package/types/Repository.d.ts +0 -95
  51. package/types/Repository.d.ts.map +0 -1
  52. package/types/actions/aggregate.d.ts +0 -112
  53. package/types/actions/aggregate.d.ts.map +0 -1
  54. package/types/actions/create.d.ts +0 -21
  55. package/types/actions/create.d.ts.map +0 -1
  56. package/types/actions/delete.d.ts +0 -37
  57. package/types/actions/delete.d.ts.map +0 -1
  58. package/types/actions/index.d.ts +0 -6
  59. package/types/actions/index.d.ts.map +0 -1
  60. package/types/actions/read.d.ts +0 -135
  61. package/types/actions/read.d.ts.map +0 -1
  62. package/types/actions/update.d.ts +0 -58
  63. package/types/actions/update.d.ts.map +0 -1
  64. package/types/hooks/lifecycle.d.ts +0 -44
  65. package/types/hooks/lifecycle.d.ts.map +0 -1
  66. package/types/index.d.ts +0 -25
  67. package/types/index.d.ts.map +0 -1
  68. package/types/pagination/PaginationEngine.d.ts +0 -386
  69. package/types/pagination/PaginationEngine.d.ts.map +0 -1
  70. package/types/pagination/utils/cursor.d.ts +0 -40
  71. package/types/pagination/utils/cursor.d.ts.map +0 -1
  72. package/types/pagination/utils/filter.d.ts +0 -28
  73. package/types/pagination/utils/filter.d.ts.map +0 -1
  74. package/types/pagination/utils/limits.d.ts +0 -64
  75. package/types/pagination/utils/limits.d.ts.map +0 -1
  76. package/types/pagination/utils/sort.d.ts +0 -41
  77. package/types/pagination/utils/sort.d.ts.map +0 -1
  78. package/types/plugins/aggregate-helpers.plugin.d.ts +0 -6
  79. package/types/plugins/aggregate-helpers.plugin.d.ts.map +0 -1
  80. package/types/plugins/audit-log.plugin.d.ts +0 -6
  81. package/types/plugins/audit-log.plugin.d.ts.map +0 -1
  82. package/types/plugins/batch-operations.plugin.d.ts +0 -6
  83. package/types/plugins/batch-operations.plugin.d.ts.map +0 -1
  84. package/types/plugins/field-filter.plugin.d.ts +0 -6
  85. package/types/plugins/field-filter.plugin.d.ts.map +0 -1
  86. package/types/plugins/index.d.ts +0 -11
  87. package/types/plugins/index.d.ts.map +0 -1
  88. package/types/plugins/method-registry.plugin.d.ts +0 -3
  89. package/types/plugins/method-registry.plugin.d.ts.map +0 -1
  90. package/types/plugins/mongo-operations.plugin.d.ts +0 -4
  91. package/types/plugins/mongo-operations.plugin.d.ts.map +0 -1
  92. package/types/plugins/soft-delete.plugin.d.ts +0 -6
  93. package/types/plugins/soft-delete.plugin.d.ts.map +0 -1
  94. package/types/plugins/subdocument.plugin.d.ts +0 -6
  95. package/types/plugins/subdocument.plugin.d.ts.map +0 -1
  96. package/types/plugins/timestamp.plugin.d.ts +0 -6
  97. package/types/plugins/timestamp.plugin.d.ts.map +0 -1
  98. package/types/plugins/validation-chain.plugin.d.ts +0 -31
  99. package/types/plugins/validation-chain.plugin.d.ts.map +0 -1
  100. package/types/utils/error.d.ts +0 -11
  101. package/types/utils/error.d.ts.map +0 -1
  102. package/types/utils/field-selection.d.ts +0 -9
  103. package/types/utils/field-selection.d.ts.map +0 -1
  104. package/types/utils/index.d.ts +0 -2
  105. package/types/utils/index.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/pagination/utils/cursor.ts","../../src/pagination/utils/sort.ts","../../src/pagination/utils/filter.ts","../../src/pagination/utils/limits.ts","../../src/utils/error.ts","../../src/pagination/PaginationEngine.ts"],"names":[],"mappings":"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","file":"PaginationEngine.js","sourcesContent":["/**\r\n * Cursor Utilities\r\n * \r\n * Encoding and decoding of cursor tokens for keyset pagination.\r\n * Cursors are base64-encoded JSON containing position data and metadata.\r\n */\r\n\r\nimport mongoose from 'mongoose';\r\nimport type { SortSpec, DecodedCursor, ObjectId, CursorPayload, ValueType } from '../../types.js';\r\n\r\n/**\r\n * Encodes document values and sort metadata into a base64 cursor token\r\n *\r\n * @param doc - Document to extract cursor values from\r\n * @param primaryField - Primary sort field name\r\n * @param sort - Normalized sort specification\r\n * @param version - Cursor version for forward compatibility\r\n * @returns Base64-encoded cursor token\r\n */\r\nexport function encodeCursor(\r\n doc: Record<string, unknown>,\r\n primaryField: string,\r\n sort: SortSpec,\r\n version: number = 1\r\n): string {\r\n const primaryValue = doc[primaryField];\r\n const idValue = doc._id;\r\n\r\n const payload: CursorPayload = {\r\n v: serializeValue(primaryValue),\r\n t: getValueType(primaryValue),\r\n id: serializeValue(idValue) as string,\r\n idType: getValueType(idValue),\r\n sort,\r\n ver: version,\r\n };\r\n\r\n return Buffer.from(JSON.stringify(payload)).toString('base64');\r\n}\r\n\r\n/**\r\n * Decodes a cursor token back into document values and sort metadata\r\n *\r\n * @param token - Base64-encoded cursor token\r\n * @returns Decoded cursor data\r\n * @throws Error if token is invalid or malformed\r\n */\r\nexport function decodeCursor(token: string): DecodedCursor {\r\n try {\r\n const json = Buffer.from(token, 'base64').toString('utf-8');\r\n const payload = JSON.parse(json) as CursorPayload;\r\n\r\n return {\r\n value: rehydrateValue(payload.v, payload.t),\r\n id: rehydrateValue(payload.id, payload.idType) as ObjectId | string,\r\n sort: payload.sort,\r\n version: payload.ver,\r\n };\r\n } catch {\r\n throw new Error('Invalid cursor token');\r\n }\r\n}\r\n\r\n/**\r\n * Validates that cursor sort matches current query sort\r\n *\r\n * @param cursorSort - Sort specification from cursor\r\n * @param currentSort - Sort specification from query\r\n * @throws Error if sorts don't match\r\n */\r\nexport function validateCursorSort(cursorSort: SortSpec, currentSort: SortSpec): void {\r\n const cursorSortStr = JSON.stringify(cursorSort);\r\n const currentSortStr = JSON.stringify(currentSort);\r\n\r\n if (cursorSortStr !== currentSortStr) {\r\n throw new Error('Cursor sort does not match current query sort');\r\n }\r\n}\r\n\r\n/**\r\n * Validates cursor version matches expected version\r\n *\r\n * @param cursorVersion - Version from cursor\r\n * @param expectedVersion - Expected version from config\r\n * @throws Error if versions don't match\r\n */\r\nexport function validateCursorVersion(cursorVersion: number, expectedVersion: number): void {\r\n if (cursorVersion !== expectedVersion) {\r\n throw new Error(`Cursor version ${cursorVersion} does not match expected version ${expectedVersion}`);\r\n }\r\n}\r\n\r\n/**\r\n * Serializes a value for cursor storage\r\n */\r\nfunction serializeValue(value: unknown): string | number | boolean {\r\n if (value instanceof Date) return value.toISOString();\r\n if (value instanceof mongoose.Types.ObjectId) return value.toString();\r\n return value as string | number | boolean;\r\n}\r\n\r\n/**\r\n * Gets the type identifier for a value\r\n */\r\nfunction getValueType(value: unknown): ValueType {\r\n if (value instanceof Date) return 'date';\r\n if (value instanceof mongoose.Types.ObjectId) return 'objectid';\r\n if (typeof value === 'boolean') return 'boolean';\r\n if (typeof value === 'number') return 'number';\r\n if (typeof value === 'string') return 'string';\r\n return 'unknown';\r\n}\r\n\r\n/**\r\n * Rehydrates a serialized value back to its original type\r\n */\r\nfunction rehydrateValue(serialized: unknown, type: ValueType): unknown {\r\n switch (type) {\r\n case 'date':\r\n return new Date(serialized as string);\r\n case 'objectid':\r\n return new mongoose.Types.ObjectId(serialized as string);\r\n case 'boolean':\r\n return Boolean(serialized);\r\n case 'number':\r\n return Number(serialized);\r\n default:\r\n return serialized;\r\n }\r\n}\r\n","/**\r\n * Sort Utilities\r\n * \r\n * Normalization and validation of sort specifications for pagination.\r\n */\r\n\r\nimport type { SortSpec, SortDirection } from '../../types.js';\r\n\r\n/**\r\n * Normalizes sort object to ensure stable key order\r\n * Primary fields first, _id last (not alphabetical)\r\n *\r\n * @param sort - Sort specification\r\n * @returns Normalized sort with stable key order\r\n */\r\nexport function normalizeSort(sort: SortSpec): SortSpec {\r\n const normalized: SortSpec = {};\r\n\r\n Object.keys(sort).forEach(key => {\r\n if (key !== '_id') normalized[key] = sort[key];\r\n });\r\n\r\n if (sort._id !== undefined) {\r\n normalized._id = sort._id;\r\n }\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * Validates and normalizes sort for keyset pagination\r\n * Auto-adds _id tie-breaker if needed\r\n * Ensures _id direction matches primary field\r\n *\r\n * @param sort - Sort specification\r\n * @returns Validated and normalized sort\r\n * @throws Error if sort is invalid for keyset pagination\r\n */\r\nexport function validateKeysetSort(sort: SortSpec): SortSpec {\r\n const keys = Object.keys(sort);\r\n\r\n if (keys.length === 1 && keys[0] !== '_id') {\r\n const field = keys[0];\r\n const direction = sort[field];\r\n return normalizeSort({ [field]: direction, _id: direction });\r\n }\r\n\r\n if (keys.length === 1 && keys[0] === '_id') {\r\n return normalizeSort(sort);\r\n }\r\n\r\n if (keys.length === 2) {\r\n if (!keys.includes('_id')) {\r\n throw new Error('Keyset pagination requires _id as tie-breaker');\r\n }\r\n\r\n const primaryField = keys.find(k => k !== '_id')!;\r\n const primaryDirection = sort[primaryField];\r\n const idDirection = sort._id;\r\n\r\n if (primaryDirection !== idDirection) {\r\n throw new Error('_id direction must match primary field direction');\r\n }\r\n\r\n return normalizeSort(sort);\r\n }\r\n\r\n throw new Error('Keyset pagination only supports single field + _id');\r\n}\r\n\r\n/**\r\n * Inverts sort directions (1 becomes -1, -1 becomes 1)\r\n *\r\n * @param sort - Sort specification\r\n * @returns Inverted sort\r\n */\r\nexport function invertSort(sort: SortSpec): SortSpec {\r\n const inverted: SortSpec = {};\r\n\r\n Object.keys(sort).forEach(key => {\r\n inverted[key] = (sort[key] === 1 ? -1 : 1) as SortDirection;\r\n });\r\n\r\n return inverted;\r\n}\r\n\r\n/**\r\n * Extracts primary sort field (first non-_id field)\r\n *\r\n * @param sort - Sort specification\r\n * @returns Primary field name\r\n */\r\nexport function getPrimaryField(sort: SortSpec): string {\r\n const keys = Object.keys(sort);\r\n return keys.find(k => k !== '_id') || '_id';\r\n}\r\n\r\n/**\r\n * Gets sort direction for a specific field\r\n *\r\n * @param sort - Sort specification\r\n * @param field - Field name\r\n * @returns Sort direction\r\n */\r\nexport function getDirection(sort: SortSpec, field: string): SortDirection | undefined {\r\n return sort[field];\r\n}\r\n","/**\r\n * Filter Utilities\r\n * \r\n * Build MongoDB filters for keyset pagination with proper cursor positioning.\r\n */\r\n\r\nimport type { SortSpec, FilterQuery, AnyDocument, ObjectId } from '../../types.js';\r\n\r\n/**\r\n * Builds MongoDB filter for keyset pagination\r\n * Creates compound $or condition for proper cursor-based filtering\r\n *\r\n * @param baseFilters - Existing query filters\r\n * @param sort - Normalized sort specification\r\n * @param cursorValue - Primary field value from cursor\r\n * @param cursorId - _id value from cursor\r\n * @returns MongoDB filter with keyset condition\r\n *\r\n * @example\r\n * buildKeysetFilter(\r\n * { status: 'active' },\r\n * { createdAt: -1, _id: -1 },\r\n * new Date('2024-01-01'),\r\n * new ObjectId('...')\r\n * )\r\n * // Returns:\r\n * // {\r\n * // status: 'active',\r\n * // $or: [\r\n * // { createdAt: { $lt: Date('2024-01-01') } },\r\n * // { createdAt: Date('2024-01-01'), _id: { $lt: ObjectId('...') } }\r\n * // ]\r\n * // }\r\n */\r\nexport function buildKeysetFilter(\r\n baseFilters: FilterQuery<AnyDocument>,\r\n sort: SortSpec,\r\n cursorValue: unknown,\r\n cursorId: ObjectId | string\r\n): FilterQuery<AnyDocument> {\r\n const primaryField = Object.keys(sort).find(k => k !== '_id') || '_id';\r\n const direction = sort[primaryField];\r\n const operator = direction === 1 ? '$gt' : '$lt';\r\n\r\n return {\r\n ...baseFilters,\r\n $or: [\r\n { [primaryField]: { [operator]: cursorValue } },\r\n {\r\n [primaryField]: cursorValue,\r\n _id: { [operator]: cursorId },\r\n },\r\n ],\r\n } as FilterQuery<AnyDocument>;\r\n}\r\n","/**\r\n * Limit Utilities\r\n * \r\n * Validation and calculation helpers for pagination limits and pages.\r\n */\r\n\r\nimport type { PaginationConfig } from '../../types.js';\r\n\r\n/**\r\n * Validates and sanitizes limit value\r\n * Parses strings to numbers and prevents NaN bugs\r\n *\r\n * @param limit - Requested limit\r\n * @param config - Pagination configuration\r\n * @returns Sanitized limit between 1 and maxLimit\r\n */\r\nexport function validateLimit(limit: number | string, config: PaginationConfig): number {\r\n const parsed = Number(limit);\r\n\r\n if (!Number.isFinite(parsed) || parsed < 1) {\r\n return config.defaultLimit || 10;\r\n }\r\n\r\n return Math.min(Math.floor(parsed), config.maxLimit || 100);\r\n}\r\n\r\n/**\r\n * Validates and sanitizes page number\r\n * Parses strings to numbers and prevents NaN bugs\r\n *\r\n * @param page - Requested page (1-indexed)\r\n * @param config - Pagination configuration\r\n * @returns Sanitized page number >= 1\r\n * @throws Error if page exceeds maxPage\r\n */\r\nexport function validatePage(page: number | string, config: PaginationConfig): number {\r\n const parsed = Number(page);\r\n\r\n if (!Number.isFinite(parsed) || parsed < 1) {\r\n return 1;\r\n }\r\n\r\n const sanitized = Math.floor(parsed);\r\n\r\n if (sanitized > (config.maxPage || 10000)) {\r\n throw new Error(`Page ${sanitized} exceeds maximum ${config.maxPage || 10000}`);\r\n }\r\n\r\n return sanitized;\r\n}\r\n\r\n/**\r\n * Checks if page number should trigger deep pagination warning\r\n *\r\n * @param page - Current page number\r\n * @param threshold - Warning threshold\r\n * @returns True if warning should be shown\r\n */\r\nexport function shouldWarnDeepPagination(page: number, threshold: number): boolean {\r\n return page > threshold;\r\n}\r\n\r\n/**\r\n * Calculates number of documents to skip for offset pagination\r\n *\r\n * @param page - Page number (1-indexed)\r\n * @param limit - Documents per page\r\n * @returns Number of documents to skip\r\n */\r\nexport function calculateSkip(page: number, limit: number): number {\r\n return (page - 1) * limit;\r\n}\r\n\r\n/**\r\n * Calculates total number of pages\r\n *\r\n * @param total - Total document count\r\n * @param limit - Documents per page\r\n * @returns Total number of pages\r\n */\r\nexport function calculateTotalPages(total: number, limit: number): number {\r\n return Math.ceil(total / limit);\r\n}\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 * Pagination Engine\r\n * \r\n * Production-grade pagination for MongoDB with support for:\r\n * - Offset pagination (page-based) - Best for small datasets, random page access\r\n * - Keyset pagination (cursor-based) - Best for large datasets, infinite scroll\r\n * - Aggregate pagination - Best for complex queries requiring aggregation\r\n * \r\n * @example\r\n * ```typescript\r\n * const engine = new PaginationEngine(UserModel, {\r\n * defaultLimit: 20,\r\n * maxLimit: 100,\r\n * useEstimatedCount: true\r\n * });\r\n *\r\n * // Offset pagination\r\n * const page1 = await engine.paginate({ page: 1, limit: 20 });\r\n *\r\n * // Keyset pagination (better for large datasets)\r\n * const stream1 = await engine.stream({ sort: { createdAt: -1 }, limit: 20 });\r\n * const stream2 = await engine.stream({ sort: { createdAt: -1 }, after: stream1.next });\r\n * ```\r\n */\r\n\r\nimport type { Model } from 'mongoose';\r\nimport { encodeCursor, decodeCursor, validateCursorSort, validateCursorVersion } from './utils/cursor.js';\r\nimport { validateKeysetSort, getPrimaryField } from './utils/sort.js';\r\nimport { buildKeysetFilter } from './utils/filter.js';\r\nimport {\r\n validateLimit,\r\n validatePage,\r\n shouldWarnDeepPagination,\r\n calculateSkip,\r\n calculateTotalPages,\r\n} from './utils/limits.js';\r\nimport { createError } from '../utils/error.js';\r\nimport type {\r\n PaginationConfig,\r\n OffsetPaginationOptions,\r\n KeysetPaginationOptions,\r\n AggregatePaginationOptions,\r\n OffsetPaginationResult,\r\n KeysetPaginationResult,\r\n AggregatePaginationResult,\r\n AnyDocument,\r\n} from '../types.js';\r\n\r\n/**\r\n * Internal pagination config with required values\r\n */\r\ninterface ResolvedPaginationConfig {\r\n defaultLimit: number;\r\n maxLimit: number;\r\n maxPage: number;\r\n deepPageThreshold: number;\r\n cursorVersion: number;\r\n useEstimatedCount: boolean;\r\n}\r\n\r\n/**\r\n * Production-grade pagination engine for MongoDB\r\n * Supports offset, keyset (cursor), and aggregate pagination\r\n */\r\nexport class PaginationEngine<TDoc = AnyDocument> {\r\n public readonly Model: Model<TDoc>;\r\n public readonly config: ResolvedPaginationConfig;\r\n\r\n /**\r\n * Create a new pagination engine\r\n *\r\n * @param Model - Mongoose model to paginate\r\n * @param config - Pagination configuration\r\n */\r\n constructor(Model: Model<TDoc>, config: PaginationConfig = {}) {\r\n this.Model = Model;\r\n this.config = {\r\n defaultLimit: config.defaultLimit || 10,\r\n maxLimit: config.maxLimit || 100,\r\n maxPage: config.maxPage || 10000,\r\n deepPageThreshold: config.deepPageThreshold || 100,\r\n cursorVersion: config.cursorVersion || 1,\r\n useEstimatedCount: config.useEstimatedCount || false,\r\n };\r\n }\r\n\r\n /**\r\n * Offset-based pagination using skip/limit\r\n * Best for small datasets and when users need random page access\r\n * O(n) performance - slower for deep pages\r\n *\r\n * @param options - Pagination options\r\n * @returns Pagination result with total count\r\n *\r\n * @example\r\n * const result = await engine.paginate({\r\n * filters: { status: 'active' },\r\n * sort: { createdAt: -1 },\r\n * page: 1,\r\n * limit: 20\r\n * });\r\n * console.log(result.docs, result.total, result.hasNext);\r\n */\r\n async paginate(options: OffsetPaginationOptions = {}): Promise<OffsetPaginationResult<TDoc>> {\r\n const {\r\n filters = {},\r\n sort = { _id: -1 },\r\n page = 1,\r\n limit = this.config.defaultLimit,\r\n select,\r\n populate = [],\r\n lean = true,\r\n session,\r\n } = options;\r\n\r\n const sanitizedPage = validatePage(page, this.config);\r\n const sanitizedLimit = validateLimit(limit, this.config);\r\n const skip = calculateSkip(sanitizedPage, sanitizedLimit);\r\n\r\n let query = this.Model.find(filters as Record<string, unknown>);\r\n if (select) query = query.select(select);\r\n if (populate && (Array.isArray(populate) ? populate.length : populate)) {\r\n query = query.populate(populate as string | string[]);\r\n }\r\n query = query.sort(sort).skip(skip).limit(sanitizedLimit).lean(lean);\r\n if (session) query = query.session(session);\r\n\r\n const hasFilters = Object.keys(filters).length > 0;\r\n const useEstimated = this.config.useEstimatedCount && !hasFilters;\r\n\r\n // Note: estimatedDocumentCount() doesn't support sessions or filters\r\n // It reads collection metadata (O(1) instant), not actual documents\r\n // Falls back to countDocuments() when filters are present\r\n const [docs, total] = await Promise.all([\r\n query.exec(),\r\n useEstimated\r\n ? this.Model.estimatedDocumentCount()\r\n : this.Model.countDocuments(filters as Record<string, unknown>).session(session ?? null),\r\n ]);\r\n\r\n const totalPages = calculateTotalPages(total, sanitizedLimit);\r\n const warning = shouldWarnDeepPagination(sanitizedPage, this.config.deepPageThreshold)\r\n ? `Deep pagination (page ${sanitizedPage}). Consider getAll({ after, sort, limit }) for better performance.`\r\n : undefined;\r\n\r\n return {\r\n method: 'offset',\r\n docs: docs as TDoc[],\r\n page: sanitizedPage,\r\n limit: sanitizedLimit,\r\n total,\r\n pages: totalPages,\r\n hasNext: sanitizedPage < totalPages,\r\n hasPrev: sanitizedPage > 1,\r\n ...(warning && { warning }),\r\n };\r\n }\r\n\r\n /**\r\n * Keyset (cursor-based) pagination for high-performance streaming\r\n * Best for large datasets, infinite scroll, real-time feeds\r\n * O(1) performance - consistent speed regardless of position\r\n *\r\n * @param options - Pagination options (sort is required)\r\n * @returns Pagination result with next cursor\r\n *\r\n * @example\r\n * // First page\r\n * const page1 = await engine.stream({\r\n * sort: { createdAt: -1 },\r\n * limit: 20\r\n * });\r\n *\r\n * // Next page using cursor\r\n * const page2 = await engine.stream({\r\n * sort: { createdAt: -1 },\r\n * after: page1.next,\r\n * limit: 20\r\n * });\r\n */\r\n async stream(options: KeysetPaginationOptions): Promise<KeysetPaginationResult<TDoc>> {\r\n const {\r\n filters = {},\r\n sort,\r\n after,\r\n limit = this.config.defaultLimit,\r\n select,\r\n populate = [],\r\n lean = true,\r\n session,\r\n } = options;\r\n\r\n if (!sort) {\r\n throw createError(400, 'sort is required for keyset pagination');\r\n }\r\n\r\n const sanitizedLimit = validateLimit(limit, this.config);\r\n const normalizedSort = validateKeysetSort(sort);\r\n\r\n let query: Record<string, unknown> = { ...filters };\r\n\r\n if (after) {\r\n const cursor = decodeCursor(after);\r\n validateCursorVersion(cursor.version, this.config.cursorVersion);\r\n validateCursorSort(cursor.sort, normalizedSort);\r\n query = buildKeysetFilter(query, normalizedSort, cursor.value, cursor.id);\r\n }\r\n\r\n let mongoQuery = this.Model.find(query);\r\n if (select) mongoQuery = mongoQuery.select(select);\r\n if (populate && (Array.isArray(populate) ? populate.length : populate)) {\r\n mongoQuery = mongoQuery.populate(populate as string | string[]);\r\n }\r\n mongoQuery = mongoQuery.sort(normalizedSort).limit(sanitizedLimit + 1).lean(lean);\r\n if (session) mongoQuery = mongoQuery.session(session);\r\n\r\n const docs = await mongoQuery.exec() as (TDoc & Record<string, unknown>)[];\r\n\r\n const hasMore = docs.length > sanitizedLimit;\r\n if (hasMore) docs.pop();\r\n\r\n const primaryField = getPrimaryField(normalizedSort);\r\n const nextCursor = hasMore && docs.length > 0\r\n ? encodeCursor(docs[docs.length - 1], primaryField, normalizedSort, this.config.cursorVersion)\r\n : null;\r\n\r\n return {\r\n method: 'keyset',\r\n docs,\r\n limit: sanitizedLimit,\r\n hasMore,\r\n next: nextCursor,\r\n };\r\n }\r\n\r\n /**\r\n * Aggregate pipeline with pagination\r\n * Best for complex queries requiring aggregation stages\r\n * Uses $facet to combine results and count in single query\r\n *\r\n * @param options - Aggregation options\r\n * @returns Pagination result with total count\r\n *\r\n * @example\r\n * const result = await engine.aggregatePaginate({\r\n * pipeline: [\r\n * { $match: { status: 'active' } },\r\n * { $group: { _id: '$category', count: { $sum: 1 } } },\r\n * { $sort: { count: -1 } }\r\n * ],\r\n * page: 1,\r\n * limit: 20\r\n * });\r\n */\r\n async aggregatePaginate(options: AggregatePaginationOptions = {}): Promise<AggregatePaginationResult<TDoc>> {\r\n const {\r\n pipeline = [],\r\n page = 1,\r\n limit = this.config.defaultLimit,\r\n session,\r\n } = options;\r\n\r\n const sanitizedPage = validatePage(page, this.config);\r\n const sanitizedLimit = validateLimit(limit, this.config);\r\n const skip = calculateSkip(sanitizedPage, sanitizedLimit);\r\n\r\n const facetPipeline = [\r\n ...pipeline,\r\n {\r\n $facet: {\r\n docs: [{ $skip: skip }, { $limit: sanitizedLimit }],\r\n total: [{ $count: 'count' }],\r\n },\r\n },\r\n ];\r\n\r\n const aggregation = this.Model.aggregate(facetPipeline);\r\n if (session) aggregation.session(session);\r\n\r\n const [result] = await aggregation.exec() as [{ docs: TDoc[]; total: { count: number }[] }];\r\n const docs = result.docs;\r\n const total = result.total[0]?.count || 0;\r\n const totalPages = calculateTotalPages(total, sanitizedLimit);\r\n\r\n const warning = shouldWarnDeepPagination(sanitizedPage, this.config.deepPageThreshold)\r\n ? `Deep pagination in aggregate (page ${sanitizedPage}). Uses $skip internally.`\r\n : undefined;\r\n\r\n return {\r\n method: 'aggregate',\r\n docs,\r\n page: sanitizedPage,\r\n limit: sanitizedLimit,\r\n total,\r\n pages: totalPages,\r\n hasNext: sanitizedPage < totalPages,\r\n hasPrev: sanitizedPage > 1,\r\n ...(warning && { warning }),\r\n };\r\n }\r\n}\r\n"]}
@@ -0,0 +1,275 @@
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.js';
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 };