@classytic/mongokit 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +221 -7
  2. package/dist/actions/index.cjs +479 -0
  3. package/dist/actions/index.cjs.map +1 -0
  4. package/dist/actions/index.d.cts +3 -0
  5. package/dist/actions/index.d.ts +3 -0
  6. package/dist/actions/index.js +473 -0
  7. package/dist/actions/index.js.map +1 -0
  8. package/dist/index-BfVJZF-3.d.cts +337 -0
  9. package/dist/index-CgOJ2pqz.d.ts +337 -0
  10. package/dist/index.cjs +2142 -0
  11. package/dist/index.cjs.map +1 -0
  12. package/dist/index.d.cts +239 -0
  13. package/dist/index.d.ts +239 -0
  14. package/dist/index.js +2108 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/memory-cache-DG2oSSbx.d.ts +142 -0
  17. package/dist/memory-cache-DqfFfKes.d.cts +142 -0
  18. package/dist/pagination/PaginationEngine.cjs +375 -0
  19. package/dist/pagination/PaginationEngine.cjs.map +1 -0
  20. package/dist/pagination/PaginationEngine.d.cts +117 -0
  21. package/dist/pagination/PaginationEngine.d.ts +117 -0
  22. package/dist/pagination/PaginationEngine.js +369 -0
  23. package/dist/pagination/PaginationEngine.js.map +1 -0
  24. package/dist/plugins/index.cjs +874 -0
  25. package/dist/plugins/index.cjs.map +1 -0
  26. package/dist/plugins/index.d.cts +275 -0
  27. package/dist/plugins/index.d.ts +275 -0
  28. package/dist/plugins/index.js +857 -0
  29. package/dist/plugins/index.js.map +1 -0
  30. package/dist/types-Nxhmi1aI.d.cts +510 -0
  31. package/dist/types-Nxhmi1aI.d.ts +510 -0
  32. package/dist/utils/index.cjs +667 -0
  33. package/dist/utils/index.cjs.map +1 -0
  34. package/dist/utils/index.d.cts +189 -0
  35. package/dist/utils/index.d.ts +189 -0
  36. package/dist/utils/index.js +643 -0
  37. package/dist/utils/index.js.map +1 -0
  38. package/package.json +44 -21
  39. package/src/Repository.js +0 -296
  40. package/src/actions/aggregate.js +0 -266
  41. package/src/actions/create.js +0 -59
  42. package/src/actions/delete.js +0 -88
  43. package/src/actions/index.js +0 -11
  44. package/src/actions/read.js +0 -188
  45. package/src/actions/update.js +0 -176
  46. package/src/hooks/lifecycle.js +0 -146
  47. package/src/index.js +0 -71
  48. package/src/pagination/PaginationEngine.js +0 -348
  49. package/src/pagination/utils/cursor.js +0 -119
  50. package/src/pagination/utils/filter.js +0 -42
  51. package/src/pagination/utils/limits.js +0 -82
  52. package/src/pagination/utils/sort.js +0 -101
  53. package/src/plugins/aggregate-helpers.plugin.js +0 -71
  54. package/src/plugins/audit-log.plugin.js +0 -60
  55. package/src/plugins/batch-operations.plugin.js +0 -66
  56. package/src/plugins/field-filter.plugin.js +0 -27
  57. package/src/plugins/index.js +0 -19
  58. package/src/plugins/method-registry.plugin.js +0 -140
  59. package/src/plugins/mongo-operations.plugin.js +0 -317
  60. package/src/plugins/soft-delete.plugin.js +0 -46
  61. package/src/plugins/subdocument.plugin.js +0 -66
  62. package/src/plugins/timestamp.plugin.js +0 -19
  63. package/src/plugins/validation-chain.plugin.js +0 -145
  64. package/src/types.d.ts +0 -87
  65. package/src/utils/error.js +0 -12
  66. package/src/utils/field-selection.js +0 -156
  67. package/src/utils/index.js +0 -12
  68. package/types/Repository.d.ts +0 -95
  69. package/types/Repository.d.ts.map +0 -1
  70. package/types/actions/aggregate.d.ts +0 -112
  71. package/types/actions/aggregate.d.ts.map +0 -1
  72. package/types/actions/create.d.ts +0 -21
  73. package/types/actions/create.d.ts.map +0 -1
  74. package/types/actions/delete.d.ts +0 -37
  75. package/types/actions/delete.d.ts.map +0 -1
  76. package/types/actions/index.d.ts +0 -6
  77. package/types/actions/index.d.ts.map +0 -1
  78. package/types/actions/read.d.ts +0 -135
  79. package/types/actions/read.d.ts.map +0 -1
  80. package/types/actions/update.d.ts +0 -58
  81. package/types/actions/update.d.ts.map +0 -1
  82. package/types/hooks/lifecycle.d.ts +0 -44
  83. package/types/hooks/lifecycle.d.ts.map +0 -1
  84. package/types/index.d.ts +0 -25
  85. package/types/index.d.ts.map +0 -1
  86. package/types/pagination/PaginationEngine.d.ts +0 -386
  87. package/types/pagination/PaginationEngine.d.ts.map +0 -1
  88. package/types/pagination/utils/cursor.d.ts +0 -40
  89. package/types/pagination/utils/cursor.d.ts.map +0 -1
  90. package/types/pagination/utils/filter.d.ts +0 -28
  91. package/types/pagination/utils/filter.d.ts.map +0 -1
  92. package/types/pagination/utils/limits.d.ts +0 -64
  93. package/types/pagination/utils/limits.d.ts.map +0 -1
  94. package/types/pagination/utils/sort.d.ts +0 -41
  95. package/types/pagination/utils/sort.d.ts.map +0 -1
  96. package/types/plugins/aggregate-helpers.plugin.d.ts +0 -6
  97. package/types/plugins/aggregate-helpers.plugin.d.ts.map +0 -1
  98. package/types/plugins/audit-log.plugin.d.ts +0 -6
  99. package/types/plugins/audit-log.plugin.d.ts.map +0 -1
  100. package/types/plugins/batch-operations.plugin.d.ts +0 -6
  101. package/types/plugins/batch-operations.plugin.d.ts.map +0 -1
  102. package/types/plugins/field-filter.plugin.d.ts +0 -6
  103. package/types/plugins/field-filter.plugin.d.ts.map +0 -1
  104. package/types/plugins/index.d.ts +0 -11
  105. package/types/plugins/index.d.ts.map +0 -1
  106. package/types/plugins/method-registry.plugin.d.ts +0 -3
  107. package/types/plugins/method-registry.plugin.d.ts.map +0 -1
  108. package/types/plugins/mongo-operations.plugin.d.ts +0 -4
  109. package/types/plugins/mongo-operations.plugin.d.ts.map +0 -1
  110. package/types/plugins/soft-delete.plugin.d.ts +0 -6
  111. package/types/plugins/soft-delete.plugin.d.ts.map +0 -1
  112. package/types/plugins/subdocument.plugin.d.ts +0 -6
  113. package/types/plugins/subdocument.plugin.d.ts.map +0 -1
  114. package/types/plugins/timestamp.plugin.d.ts +0 -6
  115. package/types/plugins/timestamp.plugin.d.ts.map +0 -1
  116. package/types/plugins/validation-chain.plugin.d.ts +0 -31
  117. package/types/plugins/validation-chain.plugin.d.ts.map +0 -1
  118. package/types/utils/error.d.ts +0 -11
  119. package/types/utils/error.d.ts.map +0 -1
  120. package/types/utils/field-selection.d.ts +0 -9
  121. package/types/utils/field-selection.d.ts.map +0 -1
  122. package/types/utils/index.d.ts +0 -2
  123. package/types/utils/index.d.ts.map +0 -1
@@ -1,46 +0,0 @@
1
- export const softDeletePlugin = (options = {}) => ({
2
- name: 'softDelete',
3
-
4
- apply(repo) {
5
- const deletedField = options.deletedField || 'deletedAt';
6
- const deletedByField = options.deletedByField || 'deletedBy';
7
-
8
- repo.on('before:delete', async (context) => {
9
- if (options.soft !== false) {
10
- const updateData = {
11
- [deletedField]: new Date(),
12
- };
13
-
14
- if (context.user) {
15
- updateData[deletedByField] = context.user._id || context.user.id;
16
- }
17
-
18
- await repo.Model.findByIdAndUpdate(context.id, updateData, { session: context.session });
19
-
20
- context.softDeleted = true;
21
- }
22
- });
23
-
24
- repo.on('before:getAll', (context) => {
25
- if (!context.includeDeleted && options.soft !== false) {
26
- const queryParams = context.queryParams || {};
27
- queryParams.filters = {
28
- ...(queryParams.filters || {}),
29
- [deletedField]: { $exists: false },
30
- };
31
- context.queryParams = queryParams;
32
- }
33
- });
34
-
35
- repo.on('before:getById', (context) => {
36
- if (!context.includeDeleted && options.soft !== false) {
37
- context.query = {
38
- ...(context.query || {}),
39
- [deletedField]: { $exists: false },
40
- };
41
- }
42
- });
43
- },
44
- });
45
-
46
- export default softDeletePlugin;
@@ -1,66 +0,0 @@
1
- /**
2
- * Subdocument Plugin
3
- * Adds subdocument array operations
4
- */
5
-
6
- import { createError } from '../utils/error.js';
7
-
8
- export const subdocumentPlugin = () => ({
9
- name: 'subdocument',
10
-
11
- apply(repo) {
12
- if (!repo.registerMethod) {
13
- throw new Error('subdocumentPlugin requires methodRegistryPlugin');
14
- }
15
-
16
- /**
17
- * Add subdocument to array
18
- */
19
- repo.registerMethod('addSubdocument', async function (parentId, arrayPath, subData, options = {}) {
20
- return this.update(parentId, { $push: { [arrayPath]: subData } }, options);
21
- });
22
-
23
- /**
24
- * Get subdocument from array
25
- */
26
- repo.registerMethod('getSubdocument', async function (parentId, arrayPath, subId, options = {}) {
27
- return this._executeQuery(async (Model) => {
28
- const parent = await Model.findById(parentId).session(options.session).exec();
29
- if (!parent) throw createError(404, 'Parent not found');
30
-
31
- const sub = parent[arrayPath].id(subId);
32
- if (!sub) throw createError(404, 'Subdocument not found');
33
-
34
- return options.lean ? sub.toObject() : sub;
35
- });
36
- });
37
-
38
- /**
39
- * Update subdocument in array
40
- */
41
- repo.registerMethod('updateSubdocument', async function (parentId, arrayPath, subId, updateData, options = {}) {
42
- return this._executeQuery(async (Model) => {
43
- const query = { _id: parentId, [`${arrayPath}._id`]: subId };
44
- const update = { $set: { [`${arrayPath}.$`]: { ...updateData, _id: subId } } };
45
-
46
- const result = await Model.findOneAndUpdate(query, update, {
47
- new: true,
48
- runValidators: true,
49
- session: options.session,
50
- }).exec();
51
-
52
- if (!result) throw createError(404, 'Parent or subdocument not found');
53
- return result;
54
- });
55
- });
56
-
57
- /**
58
- * Delete subdocument from array
59
- */
60
- repo.registerMethod('deleteSubdocument', async function (parentId, arrayPath, subId, options = {}) {
61
- return this.update(parentId, { $pull: { [arrayPath]: { _id: subId } } }, options);
62
- });
63
- }
64
- });
65
-
66
- export default subdocumentPlugin;
@@ -1,19 +0,0 @@
1
- export const timestampPlugin = () => ({
2
- name: 'timestamp',
3
-
4
- apply(repo) {
5
- repo.on('before:create', (context) => {
6
- if (!context.data) return;
7
- const now = new Date();
8
- if (!context.data.createdAt) context.data.createdAt = now;
9
- if (!context.data.updatedAt) context.data.updatedAt = now;
10
- });
11
-
12
- repo.on('before:update', (context) => {
13
- if (!context.data) return;
14
- context.data.updatedAt = new Date();
15
- });
16
- },
17
- });
18
-
19
- export default timestampPlugin;
@@ -1,145 +0,0 @@
1
- import { createError } from '../utils/error.js';
2
-
3
- export const validationChainPlugin = (validators = [], options = {}) => {
4
- const { stopOnFirstError = true } = options;
5
-
6
- validators.forEach((v, idx) => {
7
- if (!v.name || typeof v.name !== 'string') {
8
- throw new Error(`Validator at index ${idx} missing 'name' (string)`);
9
- }
10
- if (typeof v.validate !== 'function') {
11
- throw new Error(`Validator '${v.name}' missing 'validate' function`);
12
- }
13
- });
14
-
15
- const validatorsByOperation = { create: [], update: [], delete: [], createMany: [] };
16
- const allOperationsValidators = [];
17
-
18
- validators.forEach(v => {
19
- if (!v.operations || v.operations.length === 0) {
20
- allOperationsValidators.push(v);
21
- } else {
22
- v.operations.forEach(op => {
23
- if (validatorsByOperation[op]) {
24
- validatorsByOperation[op].push(v);
25
- }
26
- });
27
- }
28
- });
29
-
30
- return {
31
- name: 'validation-chain',
32
-
33
- apply(repo) {
34
- const getValidatorsForOperation = (operation) => {
35
- const specific = validatorsByOperation[operation] || [];
36
- return [...allOperationsValidators, ...specific];
37
- };
38
-
39
- const runValidators = async (operation, context) => {
40
- const validators = getValidatorsForOperation(operation);
41
- const errors = [];
42
-
43
- for (const validator of validators) {
44
- try {
45
- await validator.validate(context, repo);
46
- } catch (error) {
47
- if (stopOnFirstError) {
48
- throw error;
49
- }
50
- errors.push({
51
- validator: validator.name,
52
- error: error.message || String(error)
53
- });
54
- }
55
- }
56
-
57
- if (errors.length > 0) {
58
- const error = /** @type {Error & {status: number, validationErrors: any[]}} */ (createError(
59
- 400,
60
- `Validation failed: ${errors.map(e => `[${e.validator}] ${e.error}`).join('; ')}`
61
- ));
62
- error.validationErrors = errors;
63
- throw error;
64
- }
65
- };
66
-
67
- repo.on('before:create', async (context) => await runValidators('create', context));
68
- repo.on('before:createMany', async (context) => await runValidators('createMany', context));
69
- repo.on('before:update', async (context) => await runValidators('update', context));
70
- repo.on('before:delete', async (context) => await runValidators('delete', context));
71
- }
72
- };
73
- };
74
-
75
- /**
76
- * Block operation if condition is true
77
- * @param {string} name - Validator name
78
- * @param {string[]} operations - Operations to block on
79
- * @param {Function} condition - Condition function (context) => boolean
80
- * @param {string} errorMessage - Error message to throw
81
- * @example blockIf('block-library', ['delete'], ctx => ctx.data.managed, 'Cannot delete managed records')
82
- */
83
- export const blockIf = (name, operations, condition, errorMessage) => ({
84
- name,
85
- operations,
86
- validate: (context) => {
87
- if (condition(context)) {
88
- throw createError(403, errorMessage);
89
- }
90
- }
91
- });
92
-
93
- export const requireField = (field, operations = ['create']) => ({
94
- name: `require-${field}`,
95
- operations,
96
- validate: (context) => {
97
- if (!context.data || context.data[field] === undefined || context.data[field] === null) {
98
- throw createError(400, `Field '${field}' is required`);
99
- }
100
- }
101
- });
102
-
103
- export const autoInject = (field, getter, operations = ['create']) => ({
104
- name: `auto-inject-${field}`,
105
- operations,
106
- validate: (context) => {
107
- if (context.data && !(field in context.data)) {
108
- const value = getter(context);
109
- if (value !== null && value !== undefined) {
110
- context.data[field] = value;
111
- }
112
- }
113
- }
114
- });
115
-
116
- export const immutableField = (field) => ({
117
- name: `immutable-${field}`,
118
- operations: ['update'],
119
- validate: (context) => {
120
- if (context.data && field in context.data) {
121
- throw createError(400, `Field '${field}' cannot be modified`);
122
- }
123
- }
124
- });
125
-
126
- export const uniqueField = (field, errorMessage) => ({
127
- name: `unique-${field}`,
128
- operations: ['create', 'update'],
129
- validate: async (context, repo) => {
130
- if (!context.data || !context.data[field]) return;
131
-
132
- const query = { [field]: context.data[field] };
133
- const existing = await repo.getByQuery(query, {
134
- select: '_id',
135
- lean: true,
136
- throwOnNotFound: false
137
- });
138
-
139
- if (existing && existing._id.toString() !== context.id?.toString()) {
140
- throw createError(409, errorMessage || `${field} already exists`);
141
- }
142
- }
143
- });
144
-
145
- export default validationChainPlugin;
package/src/types.d.ts DELETED
@@ -1,87 +0,0 @@
1
- /**
2
- * Type definitions for MongoKit
3
- * Used for type checking and auto-completion
4
- */
5
-
6
- import { Model, Document, PopulateOptions, ClientSession, Types } from 'mongoose';
7
-
8
- // Re-export mongoose ObjectId
9
- export type ObjectId = Types.ObjectId;
10
-
11
- // Pagination configuration
12
- export interface PaginationConfig {
13
- defaultLimit?: number;
14
- maxLimit?: number;
15
- maxPage?: number;
16
- deepPageThreshold?: number;
17
- cursorVersion?: number;
18
- useEstimatedCount?: boolean;
19
- }
20
-
21
- // Pagination options
22
- export interface OffsetPaginationOptions {
23
- filters?: Record<string, any>;
24
- sort?: Record<string, 1 | -1>;
25
- page?: number;
26
- limit?: number;
27
- select?: string | string[];
28
- populate?: string | string[] | PopulateOptions | PopulateOptions[];
29
- lean?: boolean;
30
- session?: ClientSession;
31
- }
32
-
33
- export interface KeysetPaginationOptions {
34
- filters?: Record<string, any>;
35
- sort: Record<string, 1 | -1>;
36
- after?: string;
37
- limit?: number;
38
- select?: string | string[] | Record<string, any>;
39
- populate?: string | string[] | PopulateOptions | PopulateOptions[];
40
- lean?: boolean;
41
- session?: ClientSession;
42
- }
43
-
44
- export interface AggregatePaginationOptions {
45
- pipeline?: any[];
46
- page?: number;
47
- limit?: number;
48
- session?: ClientSession;
49
- }
50
-
51
- // Pagination result types
52
- export interface OffsetPaginationResult<T = any> {
53
- method: 'offset';
54
- docs: T[];
55
- page: number;
56
- limit: number;
57
- total: number;
58
- pages: number;
59
- hasNext: boolean;
60
- hasPrev: boolean;
61
- warning?: string;
62
- }
63
-
64
- export interface KeysetPaginationResult<T = any> {
65
- method: 'keyset';
66
- docs: T[];
67
- limit: number;
68
- hasMore: boolean;
69
- next: string | null;
70
- }
71
-
72
- export interface AggregatePaginationResult<T = any> {
73
- method: 'aggregate';
74
- docs: T[];
75
- page: number;
76
- limit: number;
77
- total: number;
78
- pages: number;
79
- hasNext: boolean;
80
- hasPrev: boolean;
81
- warning?: string;
82
- }
83
-
84
- export type PaginationResult<T = any> =
85
- | OffsetPaginationResult<T>
86
- | KeysetPaginationResult<T>
87
- | AggregatePaginationResult<T>;
@@ -1,12 +0,0 @@
1
- /**
2
- * Creates an error with HTTP status code
3
- *
4
- * @param {number} status - HTTP status code
5
- * @param {string} message - Error message
6
- * @returns {Error & {status: number}} Error with status property
7
- */
8
- export function createError(status, message) {
9
- const error = /** @type {Error & {status: number}} */ (new Error(message));
10
- error.status = status;
11
- return error;
12
- }
@@ -1,156 +0,0 @@
1
- /**
2
- * Field Selection Utilities
3
- *
4
- * Provides explicit, performant field filtering using Mongoose projections.
5
- *
6
- * Philosophy:
7
- * - Explicit is better than implicit
8
- * - Filter at DB level (10x faster than in-memory)
9
- * - Progressive disclosure (show more fields as trust increases)
10
- *
11
- * Usage:
12
- * ```javascript
13
- * // For Mongoose queries (PREFERRED - 90% of cases)
14
- * const projection = getMongooseProjection(request.user, fieldPresets.gymPlans);
15
- * const plans = await GymPlan.find().select(projection).lean();
16
- *
17
- * // For complex data (10% of cases - aggregations, multiple sources)
18
- * const filtered = filterResponseData(complexData, fieldPresets.gymPlans, request.user);
19
- * ```
20
- */
21
-
22
- /**
23
- * Get allowed fields for a user based on their context
24
- *
25
- * @param {Object} user - User object from request.user (or null for public)
26
- * @param {Object} preset - Field preset configuration
27
- * @param {string[]} preset.public - Fields visible to everyone
28
- * @param {string[]} preset.authenticated - Additional fields for authenticated users
29
- * @param {string[]} preset.admin - Additional fields for admins
30
- * @returns {string[]} Array of allowed field names
31
- */
32
- export const getFieldsForUser = (user, preset) => {
33
- if (!preset) {
34
- throw new Error('Field preset is required');
35
- }
36
-
37
- // Start with public fields
38
- let fields = [...(preset.public || [])];
39
-
40
- // Add authenticated fields if user is logged in
41
- if (user) {
42
- fields.push(...(preset.authenticated || []));
43
-
44
- // Add admin fields if user is admin/superadmin
45
- const roles = Array.isArray(user.roles) ? user.roles : (user.roles ? [user.roles] : []);
46
- if (roles.includes('admin') || roles.includes('superadmin')) {
47
- fields.push(...(preset.admin || []));
48
- }
49
- }
50
-
51
- // Remove duplicates
52
- return [...new Set(fields)];
53
- };
54
-
55
- /**
56
- * Get Mongoose projection string for query .select()
57
- *
58
- * @param {Object} user - User object from request.user
59
- * @param {Object} preset - Field preset configuration
60
- * @returns {string} Space-separated field names for Mongoose .select()
61
- *
62
- * @example
63
- * const projection = getMongooseProjection(request.user, fieldPresets.gymPlans);
64
- * const plans = await GymPlan.find({ organizationId }).select(projection).lean();
65
- */
66
- export const getMongooseProjection = (user, preset) => {
67
- const fields = getFieldsForUser(user, preset);
68
- return fields.join(' ');
69
- };
70
-
71
- /**
72
- * Filter response data to include only allowed fields
73
- *
74
- * Use this for complex responses where Mongoose projections aren't applicable:
75
- * - Aggregation pipeline results
76
- * - Data from multiple sources
77
- * - Custom computed fields
78
- *
79
- * For simple DB queries, prefer getMongooseProjection() (10x faster)
80
- *
81
- * @param {Object|Array} data - Data to filter
82
- * @param {Object} preset - Field preset configuration
83
- * @param {Object} user - User object from request.user
84
- * @returns {Object|Array} Filtered data
85
- *
86
- * @example
87
- * const stats = await calculateComplexStats();
88
- * const filtered = filterResponseData(stats, fieldPresets.dashboard, request.user);
89
- * return reply.send(filtered);
90
- */
91
- export const filterResponseData = (data, preset, user = null) => {
92
- const allowedFields = getFieldsForUser(user, preset);
93
-
94
- // Handle arrays
95
- if (Array.isArray(data)) {
96
- return data.map(item => filterObject(item, allowedFields));
97
- }
98
-
99
- // Handle single object
100
- return filterObject(data, allowedFields);
101
- };
102
-
103
- /**
104
- * Filter a single object to include only allowed fields
105
- *
106
- * @private
107
- * @param {Object} obj - Object to filter
108
- * @param {string[]} allowedFields - Array of allowed field names
109
- * @returns {Object} Filtered object
110
- */
111
- const filterObject = (obj, allowedFields) => {
112
- if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
113
- return obj;
114
- }
115
-
116
- const filtered = {};
117
-
118
- for (const field of allowedFields) {
119
- if (field in obj) {
120
- filtered[field] = obj[field];
121
- }
122
- }
123
-
124
- return filtered;
125
- };
126
-
127
- /**
128
- * Helper to create field presets (module-level)
129
- *
130
- * Each module should define its own field preset in its own directory.
131
- * This keeps modules independent and self-contained.
132
- *
133
- * @param {Object} config - Field configuration
134
- * @returns {Object} Field preset
135
- *
136
- * @example
137
- * // In modules/gym-plan/gym-plan.fields.js
138
- * import { createFieldPreset } from '#common/utils/field-selection.js';
139
- *
140
- * export const gymPlanFieldPreset = createFieldPreset({
141
- * public: ['id', 'name', 'price'],
142
- * authenticated: ['features', 'description'],
143
- * admin: ['createdAt', 'updatedAt', 'internalNotes']
144
- * });
145
- *
146
- * // Then in controller:
147
- * import { gymPlanFieldPreset } from './gym-plan.fields.js';
148
- * super(gymPlanRepository, { fieldPreset: gymPlanFieldPreset });
149
- */
150
- export const createFieldPreset = (config) => {
151
- return {
152
- public: config.public || [],
153
- authenticated: config.authenticated || [],
154
- admin: config.admin || [],
155
- };
156
- };
@@ -1,12 +0,0 @@
1
- /**
2
- * Utility Functions for MongoKit
3
- * Reusable helpers for field selection, filtering, and more
4
- */
5
-
6
- export {
7
- getFieldsForUser,
8
- getMongooseProjection,
9
- filterResponseData,
10
- createFieldPreset,
11
- } from './field-selection.js';
12
-
@@ -1,95 +0,0 @@
1
- /**
2
- * @typedef {import('./types.js').OffsetPaginationResult} OffsetPaginationResult
3
- * @typedef {import('./types.js').KeysetPaginationResult} KeysetPaginationResult
4
- * @typedef {import('./types.js').AggregatePaginationResult} AggregatePaginationResult
5
- * @typedef {import('./types.js').ObjectId} ObjectId
6
- */
7
- export class Repository {
8
- constructor(Model: any, plugins?: any[], paginationConfig?: {});
9
- Model: any;
10
- model: any;
11
- _hooks: Map<any, any>;
12
- _pagination: PaginationEngine;
13
- use(plugin: any): this;
14
- on(event: any, listener: any): this;
15
- emit(event: any, data: any): void;
16
- create(data: any, options?: {}): Promise<any>;
17
- createMany(dataArray: any, options?: {}): Promise<any>;
18
- getById(id: any, options?: {}): Promise<any>;
19
- getByQuery(query: any, options?: {}): Promise<any>;
20
- /**
21
- * Unified pagination - auto-detects offset vs keyset based on params
22
- *
23
- * Auto-detection logic:
24
- * - If params has 'cursor' or 'after' → uses keyset pagination (stream)
25
- * - If params has 'pagination' or 'page' → uses offset pagination (paginate)
26
- * - Else → defaults to offset pagination with page=1
27
- *
28
- * @param {Object} params - Query and pagination parameters
29
- * @param {Object} [params.filters] - MongoDB query filters
30
- * @param {string|Object} [params.sort] - Sort specification
31
- * @param {string} [params.cursor] - Cursor token for keyset pagination
32
- * @param {string} [params.after] - Alias for cursor
33
- * @param {number} [params.page] - Page number for offset pagination
34
- * @param {Object} [params.pagination] - Pagination config { page, limit }
35
- * @param {number} [params.limit] - Documents per page
36
- * @param {string} [params.search] - Full-text search query
37
- * @param {Object} [options] - Additional options (select, populate, lean, session)
38
- * @returns {Promise<OffsetPaginationResult|KeysetPaginationResult>} Discriminated union based on method
39
- *
40
- * @example
41
- * // Offset pagination (page-based)
42
- * await repo.getAll({ page: 1, limit: 50, filters: { status: 'active' } });
43
- * await repo.getAll({ pagination: { page: 2, limit: 20 } });
44
- *
45
- * // Keyset pagination (cursor-based)
46
- * await repo.getAll({ cursor: 'eyJ2Ij...', limit: 50 });
47
- * await repo.getAll({ after: 'eyJ2Ij...', sort: { createdAt: -1 } });
48
- *
49
- * // Simple query (defaults to page 1)
50
- * await repo.getAll({ filters: { status: 'active' } });
51
- */
52
- getAll(params?: {
53
- filters?: any;
54
- sort?: string | any;
55
- cursor?: string;
56
- after?: string;
57
- page?: number;
58
- pagination?: any;
59
- limit?: number;
60
- search?: string;
61
- }, options?: any): Promise<OffsetPaginationResult | KeysetPaginationResult>;
62
- getOrCreate(query: any, createData: any, options?: {}): Promise<any>;
63
- count(query?: {}, options?: {}): Promise<number>;
64
- exists(query: any, options?: {}): Promise<{
65
- _id: any;
66
- }>;
67
- update(id: any, data: any, options?: {}): Promise<any>;
68
- delete(id: any, options?: {}): Promise<{
69
- success: boolean;
70
- message: string;
71
- }>;
72
- aggregate(pipeline: any, options?: {}): Promise<any[]>;
73
- /**
74
- * Aggregate pipeline with pagination
75
- * Best for: Complex queries, grouping, joins
76
- *
77
- * @param {Object} options - Aggregate pagination options
78
- * @returns {Promise<AggregatePaginationResult>}
79
- */
80
- aggregatePaginate(options?: any): Promise<AggregatePaginationResult>;
81
- distinct(field: any, query?: {}, options?: {}): Promise<any>;
82
- withTransaction(callback: any): Promise<any>;
83
- _executeQuery(buildQuery: any): Promise<any>;
84
- _buildContext(operation: any, options: any): Promise<any>;
85
- _parseSort(sort: any): any;
86
- _parsePopulate(populate: any): any[];
87
- _handleError(error: any): any;
88
- }
89
- export default Repository;
90
- export type OffsetPaginationResult = import("./types.js").OffsetPaginationResult;
91
- export type KeysetPaginationResult = import("./types.js").KeysetPaginationResult;
92
- export type AggregatePaginationResult = import("./types.js").AggregatePaginationResult;
93
- export type ObjectId = import("./types.js").ObjectId;
94
- import { PaginationEngine } from './pagination/PaginationEngine.js';
95
- //# sourceMappingURL=Repository.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Repository.d.ts","sourceRoot":"","sources":["../src/Repository.js"],"names":[],"mappings":"AASA;;;;;GAKG;AAEH;IACE,gEAMC;IALC,WAAkB;IAClB,WAA4B;IAC5B,sBAAuB;IACvB,8BAAgE;IAIlE,uBAOC;IAED,oCAMC;IAED,kCAGC;IAED,8CAWC;IAED,uDAWC;IAED,6CAGC;IAED,mDAGC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,gBAvBG;QAAwB,OAAO;QACA,IAAI,GAA3B,MAAM,MAAO;QACG,MAAM,GAAtB,MAAM;QACU,KAAK,GAArB,MAAM;QACU,IAAI,GAApB,MAAM;QACU,UAAU;QACV,KAAK,GAArB,MAAM;QACU,MAAM,GAAtB,MAAM;KACd,kBACU,OAAO,CAAC,sBAAsB,GAAC,sBAAsB,CAAC,CAgElE;IAED,qEAEC;IAED,iDAEC;IAED;;OAEC;IAED,uDAWC;IAED;;;OAWC;IAED,uDAEC;IAED;;;;;;OAMG;IACH,kCAFa,OAAO,CAAC,yBAAyB,CAAC,CAK9C;IAED,6DAEC;IAED,6CAaC;IAED,6CAYC;IAED,0DAUC;IAED,2BAOC;IAED,qCAKC;IAED,8BAUC;CACF;;qCA3RY,OAAO,YAAY,EAAE,sBAAsB;qCAC3C,OAAO,YAAY,EAAE,sBAAsB;wCAC3C,OAAO,YAAY,EAAE,yBAAyB;uBAC9C,OAAO,YAAY,EAAE,QAAQ;iCANT,kCAAkC"}