@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.
- package/LICENSE +34 -21
- package/lib/containers/container.d.ts +14 -0
- package/lib/containers/container.js +17 -0
- package/lib/containers/container.js.map +1 -0
- package/lib/containers/index.d.ts +1 -0
- package/lib/dataloaders/bulk-dataloader-v2.d.ts +40 -0
- package/lib/dataloaders/bulk-dataloader-v2.js +118 -0
- package/lib/dataloaders/bulk-dataloader-v2.js.map +1 -0
- package/lib/dataloaders/bulk-dataloader-v2.test.d.ts +1 -0
- package/lib/dataloaders/bulk-dataloader.d.ts +1 -1
- package/lib/dataloaders/bulk-dataloader.js.map +1 -1
- package/lib/dataloaders/bulk-dataloader.test.d.ts +1 -0
- package/lib/dataloaders/index.d.ts +1 -0
- package/lib/graphql/schema/base-services.graphql +238 -0
- package/lib/helpers/mongoose-connection.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +1 -1
- package/lib/interfaces/base-repository.d.ts +1 -5
- package/lib/interfaces/base-service.d.ts +1 -1
- package/lib/interfaces/getAllArgs.d.ts +135 -0
- package/lib/interfaces/getAllArgs.js +39 -0
- package/lib/interfaces/getAllArgs.js.map +1 -0
- package/lib/interfaces/index.d.ts +1 -4
- package/lib/interfaces/index.old.d.ts +3 -0
- package/lib/mixins/BaseServiceMixin.d.ts +45 -0
- package/lib/mixins/BaseServiceMixin.js +212 -0
- package/lib/mixins/BaseServiceMixin.js.map +1 -0
- package/lib/mixins/__tests__/BaseServiceMixin.test.d.ts +1 -0
- package/lib/mixins/base-service-mixin.js.map +1 -1
- package/lib/mixins/index.d.ts +1 -0
- package/lib/module.d.ts +2 -0
- package/lib/module.js +4 -0
- package/lib/module.js.map +1 -0
- package/lib/services/BaseProxyService.d.ts +28 -0
- package/lib/services/BaseProxyService.js +52 -0
- package/lib/services/BaseProxyService.js.map +1 -0
- package/lib/services/BaseService.d.ts +23 -0
- package/lib/services/BaseService.js +65 -0
- package/lib/services/BaseService.js.map +1 -0
- package/lib/services/BaseService.test.d.ts +1 -0
- package/lib/services/ConnectionPoolManager.d.ts +54 -0
- package/lib/services/ConnectionPoolManager.js +163 -0
- package/lib/services/ConnectionPoolManager.js.map +1 -0
- package/lib/services/base-proxy-service.d.ts +2 -1
- package/lib/services/base-proxy-service.js.map +1 -1
- package/lib/services/base-service.d.ts +2 -1
- package/lib/services/base-service.js.map +1 -1
- package/lib/services/index.d.ts +3 -0
- package/lib/store/models/common-options-v2.d.ts +16 -0
- package/lib/store/models/common-options-v2.js +40 -0
- package/lib/store/models/common-options-v2.js.map +1 -0
- package/lib/store/models/common-options.js.map +1 -1
- package/lib/store/models/index.d.ts +1 -0
- package/lib/store/repositories/BaseMongoRepository.d.ts +72 -0
- package/lib/store/repositories/BaseMongoRepository.js +423 -0
- package/lib/store/repositories/BaseMongoRepository.js.map +1 -0
- package/lib/store/repositories/BaseMongoRepository.test.d.ts +1 -0
- package/lib/store/repositories/CustomIdRepository.test.d.ts +1 -0
- package/lib/store/repositories/base-repository.d.ts +2 -1
- package/lib/store/repositories/base-repository.js +1 -1
- package/lib/store/repositories/base-repository.js.map +1 -1
- package/lib/store/repositories/index.d.ts +1 -0
- package/lib/templates/constants/SERVER_TYPES.ts.template +7 -0
- package/lib/templates/repositories/DataLoader.ts.template +211 -0
- package/lib/templates/repositories/DatabaseMigration.ts.template +13 -0
- package/lib/templates/repositories/IBaseMongoRepository.ts.template +284 -0
- package/lib/templates/repositories/IBaseService.ts.template +231 -0
- package/lib/templates/repositories/IBaseServiceMixin.ts.template +477 -0
- package/lib/templates/repositories/dbCommonTypes.ts.template +140 -0
- package/lib/templates/repositories/moleculerEventHandler.ts.template.toberemoved +118 -0
- package/lib/templates/repositories/mongoCommonTypes.ts.template +21 -0
- package/lib/templates/repositories/typedMoleculerService.ts.template.toberemoved +1188 -0
- package/lib/templates/repositories/zodToMoleculer.ts.template.toberemoved +133 -0
- package/package.json +22 -5
- package/lib/interfaces/base-repository.js +0 -5
- package/lib/interfaces/base-repository.js.map +0 -1
- 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
|
+
}
|