@common-stack/store-mongo 8.0.2-alpha.0 → 8.1.1-alpha.13

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 (77) hide show
  1. package/LICENSE +34 -21
  2. package/lib/containers/container.d.ts +14 -0
  3. package/lib/containers/container.js +17 -0
  4. package/lib/containers/container.js.map +1 -0
  5. package/lib/containers/index.d.ts +1 -0
  6. package/lib/dataloaders/bulk-dataloader-v2.d.ts +40 -0
  7. package/lib/dataloaders/bulk-dataloader-v2.js +118 -0
  8. package/lib/dataloaders/bulk-dataloader-v2.js.map +1 -0
  9. package/lib/dataloaders/bulk-dataloader-v2.test.d.ts +1 -0
  10. package/lib/dataloaders/bulk-dataloader.d.ts +1 -1
  11. package/lib/dataloaders/bulk-dataloader.js.map +1 -1
  12. package/lib/dataloaders/bulk-dataloader.test.d.ts +1 -0
  13. package/lib/dataloaders/index.d.ts +1 -0
  14. package/lib/graphql/schema/base-services.graphql +238 -0
  15. package/lib/helpers/mongoose-connection.js.map +1 -1
  16. package/lib/index.d.ts +2 -1
  17. package/lib/index.js +1 -1
  18. package/lib/interfaces/base-repository.d.ts +1 -5
  19. package/lib/interfaces/base-service.d.ts +1 -1
  20. package/lib/interfaces/getAllArgs.d.ts +135 -0
  21. package/lib/interfaces/getAllArgs.js +39 -0
  22. package/lib/interfaces/getAllArgs.js.map +1 -0
  23. package/lib/interfaces/index.d.ts +1 -4
  24. package/lib/interfaces/index.old.d.ts +3 -0
  25. package/lib/mixins/BaseServiceMixin.d.ts +45 -0
  26. package/lib/mixins/BaseServiceMixin.js +212 -0
  27. package/lib/mixins/BaseServiceMixin.js.map +1 -0
  28. package/lib/mixins/__tests__/BaseServiceMixin.test.d.ts +1 -0
  29. package/lib/mixins/base-service-mixin.js.map +1 -1
  30. package/lib/mixins/index.d.ts +1 -0
  31. package/lib/module.d.ts +2 -0
  32. package/lib/module.js +4 -0
  33. package/lib/module.js.map +1 -0
  34. package/lib/services/BaseProxyService.d.ts +28 -0
  35. package/lib/services/BaseProxyService.js +52 -0
  36. package/lib/services/BaseProxyService.js.map +1 -0
  37. package/lib/services/BaseService.d.ts +23 -0
  38. package/lib/services/BaseService.js +65 -0
  39. package/lib/services/BaseService.js.map +1 -0
  40. package/lib/services/BaseService.test.d.ts +1 -0
  41. package/lib/services/ConnectionPoolManager.d.ts +54 -0
  42. package/lib/services/ConnectionPoolManager.js +163 -0
  43. package/lib/services/ConnectionPoolManager.js.map +1 -0
  44. package/lib/services/base-proxy-service.d.ts +2 -1
  45. package/lib/services/base-proxy-service.js.map +1 -1
  46. package/lib/services/base-service.d.ts +2 -1
  47. package/lib/services/base-service.js.map +1 -1
  48. package/lib/services/index.d.ts +3 -0
  49. package/lib/store/models/common-options-v2.d.ts +16 -0
  50. package/lib/store/models/common-options-v2.js +40 -0
  51. package/lib/store/models/common-options-v2.js.map +1 -0
  52. package/lib/store/models/common-options.js.map +1 -1
  53. package/lib/store/models/index.d.ts +1 -0
  54. package/lib/store/repositories/BaseMongoRepository.d.ts +72 -0
  55. package/lib/store/repositories/BaseMongoRepository.js +423 -0
  56. package/lib/store/repositories/BaseMongoRepository.js.map +1 -0
  57. package/lib/store/repositories/BaseMongoRepository.test.d.ts +1 -0
  58. package/lib/store/repositories/CustomIdRepository.test.d.ts +1 -0
  59. package/lib/store/repositories/base-repository.d.ts +2 -1
  60. package/lib/store/repositories/base-repository.js +1 -1
  61. package/lib/store/repositories/base-repository.js.map +1 -1
  62. package/lib/store/repositories/index.d.ts +1 -0
  63. package/lib/templates/constants/SERVER_TYPES.ts.template +7 -0
  64. package/lib/templates/repositories/DataLoader.ts.template +211 -0
  65. package/lib/templates/repositories/DatabaseMigration.ts.template +13 -0
  66. package/lib/templates/repositories/IBaseMongoRepository.ts.template +284 -0
  67. package/lib/templates/repositories/IBaseService.ts.template +231 -0
  68. package/lib/templates/repositories/IBaseServiceMixin.ts.template +477 -0
  69. package/lib/templates/repositories/dbCommonTypes.ts.template +140 -0
  70. package/lib/templates/repositories/moleculerEventHandler.ts.template.toberemoved +118 -0
  71. package/lib/templates/repositories/mongoCommonTypes.ts.template +21 -0
  72. package/lib/templates/repositories/typedMoleculerService.ts.template.toberemoved +1188 -0
  73. package/lib/templates/repositories/zodToMoleculer.ts.template.toberemoved +133 -0
  74. package/package.json +22 -5
  75. package/lib/interfaces/base-repository.js +0 -5
  76. package/lib/interfaces/base-repository.js.map +0 -1
  77. package/lib/interfaces/get-all-args.d.ts +0 -9
@@ -0,0 +1,231 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /**
3
+ * @file BaseService.ts
4
+ * @description Defines the IBaseService interface that provides a standardized set of service methods for business logic operations.
5
+ * This interface acts as an abstraction layer between controllers and repositories, implementing domain-specific logic.
6
+ * It offers methods for retrieving, creating, updating, and deleting domain entities, with support for filtering and pagination.
7
+ *
8
+ * The interface is generic, accepting a SchemaType parameter that represents the underlying data structure.
9
+ * Methods operate on and return domain objects (with 'id' instead of '_id') using the AsDomainType transformation.
10
+ *
11
+ * Key features:
12
+ * - Abstraction layer between controllers and repositories
13
+ * - Consistent API for business logic operations
14
+ * - Database-agnostic design
15
+ * - Domain-focused data manipulation
16
+ * - Support for single and bulk operations
17
+ * - Type-safe method signatures
18
+ *
19
+ * This service layer helps maintain separation of concerns and promotes code reusability across the application.
20
+ * Services typically use repositories for data access but add business rules, validation, and orchestration.
21
+ *
22
+ * @see IBaseMongoRepository - MongoDB data access layer used by services
23
+ * @see AsDomainType - Type transformation for domain objects
24
+ * @see GetAllArgs - Query options for retrieving collections
25
+ */
26
+
27
+ import { GetAllArgs, AsDomainType, CreateType, UpdateType, FilterCriteria } from './dbCommonTypes';
28
+
29
+ export interface IBaseService<SchemaType, CreateInterface = CreateType<SchemaType>, UpdateInterface = UpdateType<SchemaType>> {
30
+ /**
31
+ * Retrieves documents with pagination and total count
32
+ * Useful for implementing paginated UIs that need to know total pages
33
+ *
34
+ * @param options - Query options including filtering, sorting, pagination, and field selection
35
+ * @returns Promise resolving to object with data array and total count
36
+ *
37
+ * @example
38
+ * // Get paginated users with total count for UI pagination
39
+ * const { data, totalCount } = await userService.getAllWithCount({
40
+ * criteria: { role: 'user' },
41
+ * skip: 20,
42
+ * limit: 10,
43
+ * sort: { createdAt: -1 }
44
+ * });
45
+ */
46
+ getAllWithCount(options: GetAllArgs<SchemaType>): Promise<{
47
+ data: AsDomainType<SchemaType>[];
48
+ totalCount: number;
49
+ }>;
50
+
51
+ /**
52
+ * Counts documents matching the specified conditions
53
+ *
54
+ * @param conditions - Optional filter criteria to count specific documents
55
+ * @returns Promise resolving to the count of matching documents
56
+ *
57
+ * @example
58
+ * // Count all active users
59
+ * const activeUserCount = await userService.count({ active: true });
60
+ */
61
+ count(conditions?: FilterCriteria<SchemaType>): Promise<number>;
62
+
63
+ /**
64
+ * Retrieves a single document by ID or matching the specified conditions
65
+ *
66
+ * @param conditions - Document ID as string or filter criteria to find the document
67
+ * @returns Promise resolving to a domain object or null if not found
68
+ *
69
+ * @example
70
+ * // Get user by ID
71
+ * const user = await userService.get('60d21b4667d0d8992e610c85');
72
+ *
73
+ * // Get user by email
74
+ * const user = await userService.get({ email: 'user@example.com' });
75
+ */
76
+ get(conditions: string | FilterCriteria<SchemaType>): Promise<AsDomainType<SchemaType> | null>;
77
+
78
+ /**
79
+ * Retrieves a single document by name field
80
+ * Commonly used for entities that have a unique name identifier
81
+ *
82
+ * @param name - Name value to search for
83
+ * @returns Promise resolving to a domain object or null if not found
84
+ *
85
+ * @example
86
+ * // Get product by name
87
+ * const product = await productService.getByName('Premium Subscription');
88
+ */
89
+ getByName(name: string): Promise<AsDomainType<SchemaType> | null>;
90
+
91
+ /**
92
+ * Retrieves documents matching the specified options
93
+ *
94
+ * @param options - Query options including filtering, sorting, pagination, and field selection
95
+ * @returns Promise resolving to an array of domain objects
96
+ *
97
+ * @example
98
+ * // Get recently created users with pagination
99
+ * const users = await userService.getAll({
100
+ * criteria: { active: true },
101
+ * sort: { createdAt: -1 },
102
+ * skip: 0,
103
+ * limit: 10
104
+ * });
105
+ */
106
+ getAll(options: GetAllArgs<SchemaType>): Promise<AsDomainType<SchemaType>[]>;
107
+
108
+ /**
109
+ * Retrieves multiple documents by their IDs
110
+ *
111
+ * @param ids - Array of document IDs to retrieve
112
+ * @returns Promise resolving to an array of domain objects
113
+ *
114
+ * @example
115
+ * // Get multiple users by their IDs
116
+ * const users = await userService.getByIds(['id1', 'id2', 'id3']);
117
+ */
118
+ getByIds(ids: string[]): Promise<AsDomainType<SchemaType>[]>;
119
+
120
+ /**
121
+ * Creates a new document
122
+ *
123
+ * @param data - Data for the new document
124
+ * @returns Promise resolving to the created domain object
125
+ *
126
+ * @example
127
+ * // Create a new user
128
+ * const newUser = await userService.create({
129
+ * name: 'John Doe',
130
+ * email: 'john@example.com',
131
+ * role: 'user'
132
+ * });
133
+ */
134
+ create(data: CreateInterface): Promise<AsDomainType<SchemaType>>;
135
+
136
+ /**
137
+ * Creates multiple documents in a single operation
138
+ *
139
+ * @param data - Array of data for the new documents
140
+ * @returns Promise resolving to an array of created domain objects
141
+ *
142
+ * @example
143
+ * // Create multiple users at once
144
+ * const newUsers = await userService.bulkCreate([
145
+ * { name: 'John', email: 'john@example.com' },
146
+ * { name: 'Jane', email: 'jane@example.com' }
147
+ * ]);
148
+ */
149
+ bulkCreate(data: CreateInterface[]): Promise<AsDomainType<SchemaType>[]>;
150
+
151
+ /**
152
+ * Updates a document by ID
153
+ *
154
+ * @param id - ID of the document to update
155
+ * @param data - Data to update the document
156
+ * @param overwrite - Whether to completely replace the document (true) or merge with existing (false)
157
+ * @returns Promise resolving to the updated domain object
158
+ *
159
+ * @example
160
+ * // Update a user's role
161
+ * const updatedUser = await userService.update(
162
+ * 'user123',
163
+ * { role: 'admin', active: true }
164
+ * );
165
+ *
166
+ * // Replace a user document entirely
167
+ * const replacedUser = await userService.update(
168
+ * 'user123',
169
+ * { name: 'New Name', email: 'new@example.com', role: 'user' },
170
+ * true
171
+ * );
172
+ */
173
+ update(id: string, data: Partial<UpdateInterface>, overwrite?: boolean): Promise<AsDomainType<SchemaType>>;
174
+
175
+ /**
176
+ * Creates a new document or updates it if ID is provided
177
+ * Useful for forms that handle both creation and updates
178
+ *
179
+ * @param data - Data for the new or updated document, optionally including an ID
180
+ * @param overwrite - Whether to completely replace the document (true) or merge with existing (false)
181
+ * @returns Promise resolving to the created or updated domain object
182
+ *
183
+ * @example
184
+ * // Create a new product
185
+ * const newProduct = await productService.insert({
186
+ * name: 'New Product',
187
+ * price: 99.99
188
+ * });
189
+ *
190
+ * // Update an existing product
191
+ * const updatedProduct = await productService.insert({
192
+ * id: 'product123',
193
+ * name: 'Updated Product',
194
+ * price: 129.99
195
+ * });
196
+ */
197
+ insert(
198
+ data: (CreateInterface | UpdateInterface) & { id?: string },
199
+ overwrite?: boolean,
200
+ ): Promise<AsDomainType<SchemaType>>;
201
+
202
+ /**
203
+ * Deletes a document by ID or matching criteria
204
+ *
205
+ * @param id - Document ID as string or filter criteria to find the document to delete
206
+ * @returns Promise resolving to boolean indicating success
207
+ *
208
+ * @example
209
+ * // Delete a user by ID
210
+ * const success = await userService.delete('user123');
211
+ *
212
+ * // Delete a user by email
213
+ * const success = await userService.delete({ email: 'user@example.com' });
214
+ */
215
+ delete(id: string | FilterCriteria<SchemaType>): Promise<boolean>;
216
+
217
+ /**
218
+ * Deletes multiple documents matching the criteria
219
+ *
220
+ * @param criteria - Filter criteria to find documents to delete
221
+ * @returns Promise resolving to the number of deleted documents
222
+ *
223
+ * @example
224
+ * // Delete all inactive users
225
+ * const deletedCount = await userService.bulkDelete({ active: false });
226
+ *
227
+ * // Delete users with a specific role
228
+ * const deletedCount = await userService.bulkDelete({ role: 'guest' });
229
+ */
230
+ bulkDelete(criteria: FilterCriteria<SchemaType>): Promise<number>;
231
+ }
@@ -0,0 +1,477 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /**
3
+ * @file IBaseServiceMixin.ts
4
+ * @description Defines the interface and types for the BaseServiceMixin functionality.
5
+ * This file documents the contract and behavior of the BaseServiceMixin without implementation details.
6
+ *
7
+ * The BaseServiceMixin provides a way to add standardized service methods to Moleculer service schemas.
8
+ * It implements the IBaseService interface and connects it to Moleculer's service framework,
9
+ * creating action handlers for all standard service operations.
10
+ *
11
+ * Architecture Context:
12
+ * - Part of the service layer in a microservices architecture
13
+ * - Bridges domain services with the Moleculer microservice framework
14
+ * - Follows a consistent pattern for exposing domain operations as microservice actions
15
+ * - Implements an event-driven architecture by emitting events on data changes
16
+ * - Provides automatic parameter validation through Moleculer's built-in validator
17
+ *
18
+ * Key features:
19
+ * - Automatic action creation for all IBaseService methods
20
+ * - Event emission for data changes (create, update, delete)
21
+ * - Parameter validation for all actions
22
+ * - Consistent error handling
23
+ * - Type safety through generics
24
+ *
25
+ * Usage Patterns:
26
+ * - Include this mixin in any Moleculer service that needs standard CRUD operations
27
+ * - Customize event emission by providing a custom events array
28
+ * - Extend with additional service-specific actions
29
+ * - Use with any implementation of IBaseService (typically a concrete service class)
30
+ *
31
+ * @see IBaseService - The interface this mixin implements
32
+ * @see IBaseMongoRepository - The repository interface used for data access
33
+ * @see BaseServiceCommands - Enum of standard service commands used as action names
34
+ */
35
+
36
+ import type { ServiceBroker, ServiceSchema } from 'moleculer';
37
+ import { BaseServiceCommands } from 'common';
38
+ import { IBaseService } from './IBaseService';
39
+ import { CreateType, UpdateType } from './dbCommonTypes';
40
+
41
+ /**
42
+ * Interface for the BaseServiceMixin function
43
+ * This function creates a Moleculer service mixin that implements the IBaseService interface
44
+ *
45
+ * @param service - Implementation of IBaseService that will handle the actual business logic
46
+ * @param broker - Moleculer service broker for event emission
47
+ * @param name - Service name used for event naming
48
+ * @param events - List of operations that should emit events
49
+ * @returns A partial ServiceSchema that can be merged with other service definitions
50
+ *
51
+ * @example
52
+ * // Create a user service with the base service mixin
53
+ * const UserService: ServiceSchema = {
54
+ * name: "users",
55
+ * mixins: [
56
+ * BaseServiceMixin(userService, broker, "users")
57
+ * ],
58
+ * // Additional service-specific actions and methods
59
+ * actions: {
60
+ * changePassword: { ... }
61
+ * }
62
+ * };
63
+ *
64
+ * // Example of customizing event emission
65
+ * const ProductService: ServiceSchema = {
66
+ * name: "products",
67
+ * mixins: [
68
+ * // Only emit events for create and update operations
69
+ * BaseServiceMixin(
70
+ * productService,
71
+ * broker,
72
+ * "products",
73
+ * [BaseServiceCommands.Create, BaseServiceCommands.Update]
74
+ * )
75
+ * ]
76
+ * };
77
+ */
78
+ export interface IBaseServiceMixinFunction {
79
+ <T, C = CreateType<T>, U = UpdateType<T>>(
80
+ service: IBaseService<T, C, U>,
81
+ broker?: ServiceBroker,
82
+ name?: string,
83
+ events?: BaseServiceCommands[],
84
+ ): Partial<ServiceSchema>;
85
+ }
86
+
87
+ /**
88
+ * Interface describing the actions created by the BaseServiceMixin
89
+ * Each action corresponds to a method in the IBaseService interface
90
+ */
91
+ export interface IBaseServiceMixinActions {
92
+ /**
93
+ * Get a single document by ID
94
+ *
95
+ * This action retrieves a single entity by its unique identifier.
96
+ * It maps to the IBaseService.get method and handles parameter validation.
97
+ *
98
+ * @param id - The unique identifier of the document to retrieve
99
+ * @returns The domain entity or null if not found
100
+ *
101
+ * @example
102
+ * // Call from another service
103
+ * const user = await broker.call('users.get', { id: '123' });
104
+ *
105
+ * // Call from API
106
+ * app.get('/api/users/:id', async (req, res) => {
107
+ * const user = await broker.call('users.get', { id: req.params.id });
108
+ * res.json(user);
109
+ * });
110
+ */
111
+ [BaseServiceCommands.Get]: {
112
+ params: {
113
+ id: string;
114
+ };
115
+ };
116
+
117
+ /**
118
+ * Get multiple documents by their IDs
119
+ *
120
+ * This action retrieves multiple entities by their unique identifiers.
121
+ * It maps to the IBaseService.getByIds method and handles parameter validation.
122
+ * Useful for retrieving a specific set of entities in a single operation.
123
+ */
124
+ [BaseServiceCommands.GetByIds]: {
125
+ params: {
126
+ ids: {
127
+ type: 'array',
128
+ items: 'string',
129
+ optional: false
130
+ };
131
+ };
132
+ };
133
+
134
+ /**
135
+ * Count documents matching criteria
136
+ *
137
+ * This action counts entities matching the provided filter criteria.
138
+ * It maps to the IBaseService.count method and handles parameter validation.
139
+ *
140
+ * @param criteria - Optional filter criteria to count specific documents
141
+ * @returns The count of matching documents
142
+ *
143
+ * @example
144
+ * // Count active users
145
+ * const count = await broker.call('users.count', {
146
+ * criteria: { active: true }
147
+ * });
148
+ */
149
+ [BaseServiceCommands.Count]: {
150
+ params: {
151
+ criteria?: Record<string, any>;
152
+ };
153
+ };
154
+
155
+ /**
156
+ * Create multiple documents
157
+ *
158
+ * This action creates multiple entities in a single operation.
159
+ * It maps to the IBaseService.bulkCreate method and handles parameter validation.
160
+ * It also emits events for the created entities if configured.
161
+ *
162
+ * @param data - Array of data objects for the new documents
163
+ * @returns Array of created domain entities
164
+ *
165
+ * @example
166
+ * // Create multiple users
167
+ * const users = await broker.call('users.bulkCreate', {
168
+ * data: [
169
+ * { name: 'John', email: 'john@example.com' },
170
+ * { name: 'Jane', email: 'jane@example.com' }
171
+ * ]
172
+ * });
173
+ */
174
+ [BaseServiceCommands.BulkCreate]: {
175
+ params: {
176
+ data: any[];
177
+ };
178
+ };
179
+
180
+ /**
181
+ * Create a single document
182
+ *
183
+ * This action creates a single entity.
184
+ * It maps to the IBaseService.create method and handles parameter validation.
185
+ * It also emits an event for the created entity if configured.
186
+ *
187
+ * @param data - Data object for the new document
188
+ * @returns The created domain entity
189
+ *
190
+ * @example
191
+ * // Create a new user
192
+ * const user = await broker.call('users.create', {
193
+ * data: { name: 'John', email: 'john@example.com' }
194
+ * });
195
+ */
196
+ [BaseServiceCommands.Create]: {
197
+ params: {
198
+ data: any;
199
+ };
200
+ };
201
+
202
+ /**
203
+ * Delete a document by ID
204
+ *
205
+ * This action deletes a single entity by its unique identifier.
206
+ * It maps to the IBaseService.delete method and handles parameter validation.
207
+ * It also emits an event for the deleted entity if configured.
208
+ *
209
+ * @param id - The unique identifier of the document to delete
210
+ * @returns Boolean indicating success
211
+ *
212
+ * @example
213
+ * // Delete a user
214
+ * const success = await broker.call('users.delete', { id: '123' });
215
+ */
216
+ [BaseServiceCommands.Delete]: {
217
+ params: {
218
+ id: string;
219
+ };
220
+ };
221
+
222
+ /**
223
+ * Get documents with pagination
224
+ *
225
+ * This action retrieves multiple entities with filtering, sorting, and pagination.
226
+ * It maps to the IBaseService.getAll method and handles parameter validation.
227
+ *
228
+ * @param criteria - Optional filter criteria
229
+ * @param sort - Optional sorting configuration
230
+ * @param skip - Optional number of documents to skip (for pagination)
231
+ * @param limit - Optional maximum number of documents to return
232
+ * @param selectedFields - Optional space-separated list of fields to include
233
+ * @returns Array of domain entities
234
+ *
235
+ * @example
236
+ * // Get active users sorted by creation date
237
+ * const users = await broker.call('users.getAll', {
238
+ * criteria: { active: true },
239
+ * sort: { createdAt: -1 },
240
+ * skip: 0,
241
+ * limit: 10
242
+ * });
243
+ */
244
+ [BaseServiceCommands.GetAll]: {
245
+ params: {
246
+ criteria?: Record<string, any>;
247
+ sort?: Record<string, 1 | -1>;
248
+ skip?: number;
249
+ limit?: number;
250
+ selectedFields?: string;
251
+ };
252
+ };
253
+
254
+ /**
255
+ * Get documents with pagination and total count
256
+ *
257
+ * This action retrieves multiple entities with filtering, sorting, pagination,
258
+ * and includes the total count of matching documents (useful for UI pagination).
259
+ * It maps to the IBaseService.getAllWithCount method and handles parameter validation.
260
+ *
261
+ * @param criteria - Optional filter criteria
262
+ * @param sort - Optional sorting configuration
263
+ * @param skip - Optional number of documents to skip (for pagination)
264
+ * @param limit - Optional maximum number of documents to return
265
+ * @param selectedFields - Optional space-separated list of fields to include
266
+ * @returns Object with data array and total count
267
+ *
268
+ * @example
269
+ * // Get paginated users with total count for UI pagination
270
+ * const { data, totalCount } = await broker.call('users.getAllWithCount', {
271
+ * criteria: { role: 'user' },
272
+ * skip: 20,
273
+ * limit: 10,
274
+ * sort: { createdAt: -1 }
275
+ * });
276
+ */
277
+ [BaseServiceCommands.GetAllWithCount]: {
278
+ params: {
279
+ criteria?: Record<string, any>;
280
+ sort?: Record<string, 1 | -1>;
281
+ skip?: number;
282
+ limit?: number;
283
+ selectedFields?: string;
284
+ };
285
+ };
286
+
287
+ /**
288
+ * Create or update a document
289
+ *
290
+ * This action creates a new entity or updates an existing one if an ID is provided.
291
+ * It maps to the IBaseService.insert method and handles parameter validation.
292
+ * It also emits an event for the created or updated entity if configured.
293
+ *
294
+ * @param data - Data object for the new or updated document
295
+ * @param overwrite - Optional flag to completely replace the document instead of merging
296
+ * @returns The created or updated domain entity
297
+ *
298
+ * @example
299
+ * // Create a new product
300
+ * const newProduct = await broker.call('products.insert', {
301
+ * data: { name: 'New Product', price: 99.99 }
302
+ * });
303
+ *
304
+ * // Update an existing product
305
+ * const updatedProduct = await broker.call('products.insert', {
306
+ * data: { id: 'product123', name: 'Updated Product', price: 129.99 }
307
+ * });
308
+ */
309
+ [BaseServiceCommands.Insert]: {
310
+ params: {
311
+ data: any & { id?: string };
312
+ overwrite?: boolean;
313
+ };
314
+ };
315
+
316
+ /**
317
+ * Update a document by ID
318
+ *
319
+ * This action updates an existing entity by its unique identifier.
320
+ * It maps to the IBaseService.update method and handles parameter validation.
321
+ * It also emits an event for the updated entity if configured.
322
+ *
323
+ * @param id - The unique identifier of the document to update
324
+ * @param data - Data object with fields to update
325
+ * @param overwrite - Optional flag to completely replace the document instead of merging
326
+ * @returns The updated domain entity
327
+ *
328
+ * @example
329
+ * // Update a user's role
330
+ * const updatedUser = await broker.call('users.update', {
331
+ * id: 'user123',
332
+ * data: { role: 'admin', active: true }
333
+ * });
334
+ *
335
+ * // Replace a user document entirely
336
+ * const replacedUser = await broker.call('users.update', {
337
+ * id: 'user123',
338
+ * data: { name: 'New Name', email: 'new@example.com', role: 'user' },
339
+ * overwrite: true
340
+ * });
341
+ */
342
+ [BaseServiceCommands.Update]: {
343
+ params: {
344
+ id: string;
345
+ data: any;
346
+ overwrite?: boolean;
347
+ };
348
+ };
349
+
350
+ /**
351
+ * Delete multiple documents matching criteria
352
+ *
353
+ * This action deletes multiple entities matching the provided filter criteria.
354
+ * It maps to the IBaseService.delete method and handles parameter validation.
355
+ * It also emits an event with the deletion criteria if configured.
356
+ *
357
+ * @param criteria - Filter criteria to find documents to delete
358
+ * @returns Number of deleted documents
359
+ *
360
+ * @example
361
+ * // Delete all inactive users
362
+ * const deletedCount = await broker.call('users.deleteMany', {
363
+ * criteria: { active: false }
364
+ * });
365
+ *
366
+ * // Delete users with a specific role
367
+ * const deletedCount = await broker.call('users.deleteMany', {
368
+ * criteria: { role: 'guest' }
369
+ * });
370
+ */
371
+ [BaseServiceCommands.DeleteMany]: {
372
+ params: {
373
+ criteria: Record<string, any>;
374
+ };
375
+ };
376
+ }
377
+
378
+ /**
379
+ * Interface describing the events emitted by the BaseServiceMixin
380
+ * Events follow a consistent naming pattern: `${serviceName}.on${CommandName}`
381
+ */
382
+ export interface IBaseServiceMixinEvents {
383
+ /**
384
+ * Event emitted when a document is created
385
+ * Event name format: `${serviceName}.onCreate`
386
+ * Payload: The created domain entity
387
+ *
388
+ * @example
389
+ * // Listen for user creation events
390
+ * broker.createService({
391
+ * name: 'notification',
392
+ * events: {
393
+ * 'users.onCreate': function(payload) {
394
+ * // Send welcome email to new user
395
+ * this.sendWelcomeEmail(payload.email);
396
+ * }
397
+ * }
398
+ * });
399
+ */
400
+ onCreate: any;
401
+
402
+ /**
403
+ * Event emitted when multiple documents are created
404
+ * Event name format: `${serviceName}.onBulkCreate`
405
+ * Payload: Array of created domain entities
406
+ *
407
+ * @example
408
+ * // Listen for bulk user creation events
409
+ * broker.createService({
410
+ * name: 'notification',
411
+ * events: {
412
+ * 'users.onBulkCreate': function(payload) {
413
+ * // Send welcome emails to all new users
414
+ * payload.forEach(user => this.sendWelcomeEmail(user.email));
415
+ * }
416
+ * }
417
+ * });
418
+ */
419
+ onBulkCreate: any[];
420
+
421
+ /**
422
+ * Event emitted when a document is updated
423
+ * Event name format: `${serviceName}.onUpdate`
424
+ * Payload: The updated domain entity
425
+ *
426
+ * @example
427
+ * // Listen for user update events
428
+ * broker.createService({
429
+ * name: 'audit',
430
+ * events: {
431
+ * 'users.onUpdate': function(payload) {
432
+ * // Log user update for audit trail
433
+ * this.logAuditEvent('user_updated', payload.id);
434
+ * }
435
+ * }
436
+ * });
437
+ */
438
+ onUpdate: any;
439
+
440
+ /**
441
+ * Event emitted when a document is deleted
442
+ * Event name format: `${serviceName}.onDelete`
443
+ * Payload: Object containing the ID of the deleted entity
444
+ *
445
+ * @example
446
+ * // Listen for user deletion events
447
+ * broker.createService({
448
+ * name: 'cleanup',
449
+ * events: {
450
+ * 'users.onDelete': function(payload) {
451
+ * // Clean up related user data
452
+ * this.cleanupUserData(payload.id);
453
+ * }
454
+ * }
455
+ * });
456
+ */
457
+ onDelete: { id: string };
458
+
459
+ /**
460
+ * Event emitted when multiple documents are deleted
461
+ * Event name format: `${serviceName}.onDeleteMany`
462
+ * Payload: The criteria used for deletion
463
+ *
464
+ * @example
465
+ * // Listen for bulk user deletion events
466
+ * broker.createService({
467
+ * name: 'cleanup',
468
+ * events: {
469
+ * 'users.onDeleteMany': function(payload) {
470
+ * // Clean up related data for deleted users
471
+ * this.cleanupBulkUserData(payload.criteria);
472
+ * }
473
+ * }
474
+ * });
475
+ */
476
+ onDeleteMany: { criteria: Record<string, any> };
477
+ }