@classytic/mongokit 1.0.2 → 2.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.
- package/README.md +562 -155
- package/package.json +17 -10
- package/src/Repository.js +296 -225
- package/src/actions/aggregate.js +266 -191
- package/src/actions/create.js +47 -47
- package/src/actions/delete.js +88 -88
- package/src/actions/index.js +11 -11
- package/src/actions/read.js +176 -144
- package/src/actions/update.js +144 -144
- package/src/hooks/lifecycle.js +146 -146
- package/src/index.js +71 -60
- package/src/pagination/PaginationEngine.js +348 -0
- package/src/pagination/utils/cursor.js +119 -0
- package/src/pagination/utils/filter.js +42 -0
- package/src/pagination/utils/limits.js +82 -0
- package/src/pagination/utils/sort.js +101 -0
- package/src/plugins/aggregate-helpers.plugin.js +71 -71
- package/src/plugins/audit-log.plugin.js +60 -60
- package/src/plugins/batch-operations.plugin.js +66 -66
- package/src/plugins/field-filter.plugin.js +27 -27
- package/src/plugins/index.js +19 -19
- package/src/plugins/method-registry.plugin.js +140 -140
- package/src/plugins/mongo-operations.plugin.js +317 -313
- package/src/plugins/soft-delete.plugin.js +46 -46
- package/src/plugins/subdocument.plugin.js +66 -66
- package/src/plugins/timestamp.plugin.js +19 -19
- package/src/plugins/validation-chain.plugin.js +145 -145
- package/src/types.d.ts +87 -0
- package/src/utils/error.js +12 -0
- package/src/utils/field-selection.js +156 -156
- package/src/utils/index.js +12 -12
- package/types/Repository.d.ts +95 -0
- package/types/Repository.d.ts.map +1 -0
- package/types/actions/aggregate.d.ts +112 -0
- package/types/actions/aggregate.d.ts.map +1 -0
- package/types/actions/create.d.ts +21 -0
- package/types/actions/create.d.ts.map +1 -0
- package/types/actions/delete.d.ts +37 -0
- package/types/actions/delete.d.ts.map +1 -0
- package/types/actions/index.d.ts +6 -121
- package/types/actions/index.d.ts.map +1 -0
- package/types/actions/read.d.ts +135 -0
- package/types/actions/read.d.ts.map +1 -0
- package/types/actions/update.d.ts +58 -0
- package/types/actions/update.d.ts.map +1 -0
- package/types/hooks/lifecycle.d.ts +44 -0
- package/types/hooks/lifecycle.d.ts.map +1 -0
- package/types/index.d.ts +25 -104
- package/types/index.d.ts.map +1 -0
- package/types/pagination/PaginationEngine.d.ts +386 -0
- package/types/pagination/PaginationEngine.d.ts.map +1 -0
- package/types/pagination/utils/cursor.d.ts +40 -0
- package/types/pagination/utils/cursor.d.ts.map +1 -0
- package/types/pagination/utils/filter.d.ts +28 -0
- package/types/pagination/utils/filter.d.ts.map +1 -0
- package/types/pagination/utils/limits.d.ts +64 -0
- package/types/pagination/utils/limits.d.ts.map +1 -0
- package/types/pagination/utils/sort.d.ts +41 -0
- package/types/pagination/utils/sort.d.ts.map +1 -0
- package/types/plugins/aggregate-helpers.plugin.d.ts +6 -0
- package/types/plugins/aggregate-helpers.plugin.d.ts.map +1 -0
- package/types/plugins/audit-log.plugin.d.ts +6 -0
- package/types/plugins/audit-log.plugin.d.ts.map +1 -0
- package/types/plugins/batch-operations.plugin.d.ts +6 -0
- package/types/plugins/batch-operations.plugin.d.ts.map +1 -0
- package/types/plugins/field-filter.plugin.d.ts +6 -0
- package/types/plugins/field-filter.plugin.d.ts.map +1 -0
- package/types/plugins/index.d.ts +11 -88
- package/types/plugins/index.d.ts.map +1 -0
- package/types/plugins/method-registry.plugin.d.ts +3 -0
- package/types/plugins/method-registry.plugin.d.ts.map +1 -0
- package/types/plugins/mongo-operations.plugin.d.ts +4 -0
- package/types/plugins/mongo-operations.plugin.d.ts.map +1 -0
- package/types/plugins/soft-delete.plugin.d.ts +6 -0
- package/types/plugins/soft-delete.plugin.d.ts.map +1 -0
- package/types/plugins/subdocument.plugin.d.ts +6 -0
- package/types/plugins/subdocument.plugin.d.ts.map +1 -0
- package/types/plugins/timestamp.plugin.d.ts +6 -0
- package/types/plugins/timestamp.plugin.d.ts.map +1 -0
- package/types/plugins/validation-chain.plugin.d.ts +31 -0
- package/types/plugins/validation-chain.plugin.d.ts.map +1 -0
- package/types/utils/error.d.ts +11 -0
- package/types/utils/error.d.ts.map +1 -0
- package/types/utils/field-selection.d.ts +9 -0
- package/types/utils/field-selection.d.ts.map +1 -0
- package/types/utils/index.d.ts +2 -24
- package/types/utils/index.d.ts.map +1 -0
|
@@ -1,140 +1,140 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Method Registry Plugin
|
|
3
|
-
*
|
|
4
|
-
* Enables plugins to dynamically add methods to repository instances.
|
|
5
|
-
* Foundation for extensibility - allows other plugins to extend repositories
|
|
6
|
-
* with custom methods while maintaining type safety and proper binding.
|
|
7
|
-
*
|
|
8
|
-
* **Pattern:** Inspired by Stripe's extension system
|
|
9
|
-
* **Philosophy:** Repositories start minimal, plugins add capabilities
|
|
10
|
-
*
|
|
11
|
-
* @module common/repositories/plugins/method-registry
|
|
12
|
-
*
|
|
13
|
-
* @example Basic Usage
|
|
14
|
-
* ```js
|
|
15
|
-
* import { Repository } from '../Repository.js';
|
|
16
|
-
* import { methodRegistryPlugin } from './method-registry.plugin.js';
|
|
17
|
-
*
|
|
18
|
-
* class UserRepository extends Repository {
|
|
19
|
-
* constructor() {
|
|
20
|
-
* super(User, [methodRegistryPlugin()]);
|
|
21
|
-
*
|
|
22
|
-
* // Now you can register custom methods
|
|
23
|
-
* this.registerMethod('findActive', async function() {
|
|
24
|
-
* return this.getAll({ filters: { status: 'active' } });
|
|
25
|
-
* });
|
|
26
|
-
* }
|
|
27
|
-
* }
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* @example Plugin Using Method Registry
|
|
31
|
-
* ```js
|
|
32
|
-
* // Other plugins can use registerMethod to add functionality
|
|
33
|
-
* export const mongoOperationsPlugin = () => ({
|
|
34
|
-
* name: 'mongo-operations',
|
|
35
|
-
* apply(repo) {
|
|
36
|
-
* repo.registerMethod('increment', async function(id, field, value = 1, options = {}) {
|
|
37
|
-
* return this.update(id, { $inc: { [field]: value } }, options);
|
|
38
|
-
* });
|
|
39
|
-
* }
|
|
40
|
-
* });
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Method Registry Plugin
|
|
46
|
-
*
|
|
47
|
-
* Adds `registerMethod()` to repository instance, allowing dynamic method addition.
|
|
48
|
-
*
|
|
49
|
-
* @returns {Object} Plugin configuration
|
|
50
|
-
*/
|
|
51
|
-
export const methodRegistryPlugin = () => ({
|
|
52
|
-
name: 'method-registry',
|
|
53
|
-
|
|
54
|
-
apply(repo) {
|
|
55
|
-
/**
|
|
56
|
-
* Register a new method on the repository instance
|
|
57
|
-
*
|
|
58
|
-
* **Rules:**
|
|
59
|
-
* - Method name must not conflict with existing methods
|
|
60
|
-
* - Method is automatically bound to repository instance
|
|
61
|
-
* - Method has access to all repository methods via `this`
|
|
62
|
-
* - Async methods are recommended for consistency
|
|
63
|
-
*
|
|
64
|
-
* @param {string} name - Method name
|
|
65
|
-
* @param {Function} fn - Method implementation (will be bound to repo)
|
|
66
|
-
* @throws {Error} If method name already exists
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* repo.registerMethod('findByEmail', async function(email) {
|
|
70
|
-
* return this.getByQuery({ email }, { lean: true });
|
|
71
|
-
* });
|
|
72
|
-
*
|
|
73
|
-
* @example With options
|
|
74
|
-
* repo.registerMethod('incrementViews', async function(id, amount = 1) {
|
|
75
|
-
* return this.update(id, { $inc: { views: amount } });
|
|
76
|
-
* });
|
|
77
|
-
*/
|
|
78
|
-
repo.registerMethod = function (name, fn) {
|
|
79
|
-
// Check for naming conflicts
|
|
80
|
-
if (repo[name]) {
|
|
81
|
-
throw new Error(
|
|
82
|
-
`Cannot register method '${name}': Method already exists on repository. ` +
|
|
83
|
-
`Choose a different name or use a plugin that doesn't conflict.`
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Validate method name
|
|
88
|
-
if (!name || typeof name !== 'string') {
|
|
89
|
-
throw new Error('Method name must be a non-empty string');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Validate function
|
|
93
|
-
if (typeof fn !== 'function') {
|
|
94
|
-
throw new Error(`Method '${name}' must be a function`);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Bind function to repository instance
|
|
98
|
-
repo[name] = fn.bind(repo);
|
|
99
|
-
|
|
100
|
-
// Emit event for plugin system awareness
|
|
101
|
-
repo.emit('method:registered', { name, fn });
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Check if a method is registered
|
|
106
|
-
*
|
|
107
|
-
* @param {string} name - Method name to check
|
|
108
|
-
* @returns {boolean} True if method exists
|
|
109
|
-
*
|
|
110
|
-
* @example
|
|
111
|
-
* if (repo.hasMethod('increment')) {
|
|
112
|
-
* await repo.increment(id, 'count', 1);
|
|
113
|
-
* }
|
|
114
|
-
*/
|
|
115
|
-
repo.hasMethod = function (name) {
|
|
116
|
-
return typeof repo[name] === 'function';
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Get list of all dynamically registered methods
|
|
121
|
-
*
|
|
122
|
-
* @returns {Array<string>} Array of method names
|
|
123
|
-
*
|
|
124
|
-
* @example
|
|
125
|
-
* const methods = repo.getRegisteredMethods();
|
|
126
|
-
* console.log('Available methods:', methods);
|
|
127
|
-
*/
|
|
128
|
-
repo.getRegisteredMethods = function () {
|
|
129
|
-
const registeredMethods = [];
|
|
130
|
-
|
|
131
|
-
repo.on('method:registered', ({ name }) => {
|
|
132
|
-
registeredMethods.push(name);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
return registeredMethods;
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
export default methodRegistryPlugin;
|
|
1
|
+
/**
|
|
2
|
+
* Method Registry Plugin
|
|
3
|
+
*
|
|
4
|
+
* Enables plugins to dynamically add methods to repository instances.
|
|
5
|
+
* Foundation for extensibility - allows other plugins to extend repositories
|
|
6
|
+
* with custom methods while maintaining type safety and proper binding.
|
|
7
|
+
*
|
|
8
|
+
* **Pattern:** Inspired by Stripe's extension system
|
|
9
|
+
* **Philosophy:** Repositories start minimal, plugins add capabilities
|
|
10
|
+
*
|
|
11
|
+
* @module common/repositories/plugins/method-registry
|
|
12
|
+
*
|
|
13
|
+
* @example Basic Usage
|
|
14
|
+
* ```js
|
|
15
|
+
* import { Repository } from '../Repository.js';
|
|
16
|
+
* import { methodRegistryPlugin } from './method-registry.plugin.js';
|
|
17
|
+
*
|
|
18
|
+
* class UserRepository extends Repository {
|
|
19
|
+
* constructor() {
|
|
20
|
+
* super(User, [methodRegistryPlugin()]);
|
|
21
|
+
*
|
|
22
|
+
* // Now you can register custom methods
|
|
23
|
+
* this.registerMethod('findActive', async function() {
|
|
24
|
+
* return this.getAll({ filters: { status: 'active' } });
|
|
25
|
+
* });
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example Plugin Using Method Registry
|
|
31
|
+
* ```js
|
|
32
|
+
* // Other plugins can use registerMethod to add functionality
|
|
33
|
+
* export const mongoOperationsPlugin = () => ({
|
|
34
|
+
* name: 'mongo-operations',
|
|
35
|
+
* apply(repo) {
|
|
36
|
+
* repo.registerMethod('increment', async function(id, field, value = 1, options = {}) {
|
|
37
|
+
* return this.update(id, { $inc: { [field]: value } }, options);
|
|
38
|
+
* });
|
|
39
|
+
* }
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Method Registry Plugin
|
|
46
|
+
*
|
|
47
|
+
* Adds `registerMethod()` to repository instance, allowing dynamic method addition.
|
|
48
|
+
*
|
|
49
|
+
* @returns {Object} Plugin configuration
|
|
50
|
+
*/
|
|
51
|
+
export const methodRegistryPlugin = () => ({
|
|
52
|
+
name: 'method-registry',
|
|
53
|
+
|
|
54
|
+
apply(repo) {
|
|
55
|
+
/**
|
|
56
|
+
* Register a new method on the repository instance
|
|
57
|
+
*
|
|
58
|
+
* **Rules:**
|
|
59
|
+
* - Method name must not conflict with existing methods
|
|
60
|
+
* - Method is automatically bound to repository instance
|
|
61
|
+
* - Method has access to all repository methods via `this`
|
|
62
|
+
* - Async methods are recommended for consistency
|
|
63
|
+
*
|
|
64
|
+
* @param {string} name - Method name
|
|
65
|
+
* @param {Function} fn - Method implementation (will be bound to repo)
|
|
66
|
+
* @throws {Error} If method name already exists
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* repo.registerMethod('findByEmail', async function(email) {
|
|
70
|
+
* return this.getByQuery({ email }, { lean: true });
|
|
71
|
+
* });
|
|
72
|
+
*
|
|
73
|
+
* @example With options
|
|
74
|
+
* repo.registerMethod('incrementViews', async function(id, amount = 1) {
|
|
75
|
+
* return this.update(id, { $inc: { views: amount } });
|
|
76
|
+
* });
|
|
77
|
+
*/
|
|
78
|
+
repo.registerMethod = function (name, fn) {
|
|
79
|
+
// Check for naming conflicts
|
|
80
|
+
if (repo[name]) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`Cannot register method '${name}': Method already exists on repository. ` +
|
|
83
|
+
`Choose a different name or use a plugin that doesn't conflict.`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Validate method name
|
|
88
|
+
if (!name || typeof name !== 'string') {
|
|
89
|
+
throw new Error('Method name must be a non-empty string');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Validate function
|
|
93
|
+
if (typeof fn !== 'function') {
|
|
94
|
+
throw new Error(`Method '${name}' must be a function`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Bind function to repository instance
|
|
98
|
+
repo[name] = fn.bind(repo);
|
|
99
|
+
|
|
100
|
+
// Emit event for plugin system awareness
|
|
101
|
+
repo.emit('method:registered', { name, fn });
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Check if a method is registered
|
|
106
|
+
*
|
|
107
|
+
* @param {string} name - Method name to check
|
|
108
|
+
* @returns {boolean} True if method exists
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* if (repo.hasMethod('increment')) {
|
|
112
|
+
* await repo.increment(id, 'count', 1);
|
|
113
|
+
* }
|
|
114
|
+
*/
|
|
115
|
+
repo.hasMethod = function (name) {
|
|
116
|
+
return typeof repo[name] === 'function';
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Get list of all dynamically registered methods
|
|
121
|
+
*
|
|
122
|
+
* @returns {Array<string>} Array of method names
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* const methods = repo.getRegisteredMethods();
|
|
126
|
+
* console.log('Available methods:', methods);
|
|
127
|
+
*/
|
|
128
|
+
repo.getRegisteredMethods = function () {
|
|
129
|
+
const registeredMethods = [];
|
|
130
|
+
|
|
131
|
+
repo.on('method:registered', ({ name }) => {
|
|
132
|
+
registeredMethods.push(name);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
return registeredMethods;
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
export default methodRegistryPlugin;
|