@common-stack/store-mongo 7.2.1-alpha.3 → 7.2.1-alpha.31

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 (28) hide show
  1. package/lib/dataloaders/bulk-dataloader-v2.d.ts +34 -1
  2. package/lib/dataloaders/bulk-dataloader-v2.js +89 -5
  3. package/lib/dataloaders/bulk-dataloader-v2.js.map +1 -1
  4. package/lib/dataloaders/bulk-dataloader-v2.test.d.ts +1 -0
  5. package/lib/index.d.ts +1 -0
  6. package/lib/index.js +1 -1
  7. package/lib/module.d.ts +1 -2
  8. package/lib/module.js +1 -1
  9. package/lib/module.js.map +1 -1
  10. package/lib/moleculer-generation/index.d.ts +15 -0
  11. package/lib/moleculer-generation/moleculerEventHandler.d.ts +73 -0
  12. package/lib/moleculer-generation/moleculerEventHandler.js +91 -0
  13. package/lib/moleculer-generation/moleculerEventHandler.js.map +1 -0
  14. package/lib/moleculer-generation/serviceGenerationUtils.d.ts +99 -0
  15. package/lib/moleculer-generation/serviceGenerationUtils.js +146 -0
  16. package/lib/moleculer-generation/serviceGenerationUtils.js.map +1 -0
  17. package/lib/moleculer-generation/typedMoleculerService.d.ts +491 -0
  18. package/lib/moleculer-generation/typedMoleculerService.js +656 -0
  19. package/lib/moleculer-generation/typedMoleculerService.js.map +1 -0
  20. package/lib/moleculer-generation/typedProxyService.d.ts +116 -0
  21. package/lib/moleculer-generation/typedProxyService.js +205 -0
  22. package/lib/moleculer-generation/typedProxyService.js.map +1 -0
  23. package/lib/services/BaseProxyService.d.ts +1 -1
  24. package/lib/services/BaseProxyService.js.map +1 -1
  25. package/lib/templates/repositories/moleculerEventHandler.ts.template +118 -0
  26. package/lib/templates/repositories/typedMoleculerService.ts.template +1188 -0
  27. package/lib/templates/repositories/zodToMoleculer.ts.template +133 -0
  28. package/package.json +9 -6
@@ -1,7 +1,40 @@
1
1
  import DataLoader from 'dataloader';
2
2
  import { IBaseService, IDataLoader, AsDomainType } from 'common/server';
3
+ /**
4
+ * BulkDataLoader2 with Dual ID System Support
5
+ *
6
+ * Supports both ObjectId and UUID lookups:
7
+ * - ObjectId: MongoDB's native `_id` field
8
+ * - UUID: External identifier stored as `<collection>Id` (e.g., projectId, organizationId)
9
+ *
10
+ * The loader automatically detects the ID format and queries appropriately:
11
+ * - UUIDs contain hyphens (e.g., "550e8400-e29b-41d4-a957-446655440000")
12
+ * - ObjectIds are 24-character hex strings (e.g., "507f1f77bcf86cd799439011")
13
+ */
3
14
  export declare class BulkDataLoader2<SchemaType> extends DataLoader<string, AsDomainType<SchemaType> | null> implements IDataLoader<SchemaType> {
4
15
  private readonly service;
5
- constructor(service: IBaseService<SchemaType>);
16
+ /**
17
+ * Optional UUID field name for this collection (e.g., 'projectId', 'organizationId')
18
+ * If not provided, the loader will only support ObjectId lookups
19
+ */
20
+ private readonly uuidFieldName?;
21
+ constructor(service: IBaseService<SchemaType>, uuidFieldName?: string);
22
+ /**
23
+ * Detects if an ID is a UUID (contains hyphens) or ObjectId (24-char hex)
24
+ */
25
+ private isUUID;
26
+ /**
27
+ * Detects if an ID is a valid ObjectId
28
+ */
29
+ private isObjectId;
30
+ /**
31
+ * Loads records by IDs, supporting both UUID and ObjectId formats
32
+ * Performs a single query with $or conditions for efficient lookup
33
+ */
34
+ private loadByIds;
35
+ /**
36
+ * Finds a record by ID, checking both ObjectId and UUID fields
37
+ */
38
+ private findRecordById;
6
39
  withOptions: DataLoader<DataLoaderOptions<SchemaType>, AsDomainType<SchemaType>[], DataLoaderOptions<SchemaType>>;
7
40
  }
@@ -1,12 +1,95 @@
1
- import {__decorate,__param,__metadata}from'tslib';import DataLoader from'dataloader';import {injectable,unmanaged}from'inversify';import {IBaseService}from'common/server';var _a;
1
+ import {__decorate,__param,__metadata}from'tslib';import DataLoader from'dataloader';import {injectable,unmanaged}from'inversify';import {Types}from'mongoose';import {IBaseService}from'common/server';var _a;
2
+ /**
3
+ * BulkDataLoader2 with Dual ID System Support
4
+ *
5
+ * Supports both ObjectId and UUID lookups:
6
+ * - ObjectId: MongoDB's native `_id` field
7
+ * - UUID: External identifier stored as `<collection>Id` (e.g., projectId, organizationId)
8
+ *
9
+ * The loader automatically detects the ID format and queries appropriately:
10
+ * - UUIDs contain hyphens (e.g., "550e8400-e29b-41d4-a957-446655440000")
11
+ * - ObjectIds are 24-character hex strings (e.g., "507f1f77bcf86cd799439011")
12
+ */
2
13
  let BulkDataLoader2 = class BulkDataLoader2 extends DataLoader {
3
14
  service;
4
- constructor(service) {
15
+ /**
16
+ * Optional UUID field name for this collection (e.g., 'projectId', 'organizationId')
17
+ * If not provided, the loader will only support ObjectId lookups
18
+ */
19
+ uuidFieldName;
20
+ constructor(service, uuidFieldName) {
5
21
  super(async (ids) => {
6
- const data = await this.service.getByIds(ids);
7
- return ids.map((id) => data.find((record) => record.id === id) || null);
22
+ const data = await this.loadByIds(ids);
23
+ return ids.map((id) => this.findRecordById(data, id));
8
24
  });
9
25
  this.service = service;
26
+ this.uuidFieldName = uuidFieldName;
27
+ }
28
+ /**
29
+ * Detects if an ID is a UUID (contains hyphens) or ObjectId (24-char hex)
30
+ */
31
+ isUUID(id) {
32
+ return id.includes('-');
33
+ }
34
+ /**
35
+ * Detects if an ID is a valid ObjectId
36
+ */
37
+ isObjectId(id) {
38
+ return Types.ObjectId.isValid(id) && !this.isUUID(id);
39
+ }
40
+ /**
41
+ * Loads records by IDs, supporting both UUID and ObjectId formats
42
+ * Performs a single query with $or conditions for efficient lookup
43
+ */
44
+ async loadByIds(ids) {
45
+ // Separate UUIDs and ObjectIds for optimized querying
46
+ const uuidIds = [];
47
+ const objectIds = [];
48
+ ids.forEach((id) => {
49
+ if (this.isUUID(id)) {
50
+ uuidIds.push(id);
51
+ }
52
+ else if (this.isObjectId(id)) {
53
+ objectIds.push(id);
54
+ }
55
+ });
56
+ // If no UUID field is configured, only support ObjectId lookups
57
+ if (!this.uuidFieldName && uuidIds.length > 0) {
58
+ console.warn(`[BulkDataLoader2] UUID IDs detected but no uuidFieldName configured. UUIDs will not be resolved: ${uuidIds.join(', ')}`);
59
+ }
60
+ // Build query criteria using $or for mixed ID types
61
+ const criteria = [];
62
+ if (objectIds.length > 0) {
63
+ // Query by _id (ObjectId)
64
+ criteria.push({ _id: { $in: objectIds } });
65
+ }
66
+ if (uuidIds.length > 0 && this.uuidFieldName) {
67
+ // Query by UUID field (e.g., projectId, organizationId)
68
+ criteria.push({ [this.uuidFieldName]: { $in: uuidIds } });
69
+ }
70
+ // If no valid IDs, return empty array
71
+ if (criteria.length === 0) {
72
+ return [];
73
+ }
74
+ // Execute query with $or combining both lookup strategies
75
+ const query = criteria.length === 1 ? criteria[0] : { $or: criteria };
76
+ return await this.service.getAll({ criteria: query });
77
+ }
78
+ /**
79
+ * Finds a record by ID, checking both ObjectId and UUID fields
80
+ */
81
+ findRecordById(records, id) {
82
+ return (records.find((record) => {
83
+ // Check if ID matches the record's id field (transformed from _id)
84
+ if (record.id === id) {
85
+ return true;
86
+ }
87
+ // If UUID field is configured, check that field too
88
+ if (this.uuidFieldName && record[this.uuidFieldName] === id) {
89
+ return true;
90
+ }
91
+ return false;
92
+ }) || null);
10
93
  }
11
94
  withOptions = new DataLoader(async (options) => {
12
95
  const [{ searchKey, comparator, ...rest }] = options;
@@ -30,5 +113,6 @@ let BulkDataLoader2 = class BulkDataLoader2 extends DataLoader {
30
113
  BulkDataLoader2 = __decorate([
31
114
  injectable(),
32
115
  __param(0, unmanaged()),
33
- __metadata("design:paramtypes", [typeof (_a = typeof IBaseService !== "undefined" && IBaseService) === "function" ? _a : Object])
116
+ __param(1, unmanaged()),
117
+ __metadata("design:paramtypes", [typeof (_a = typeof IBaseService !== "undefined" && IBaseService) === "function" ? _a : Object, String])
34
118
  ], BulkDataLoader2);export{BulkDataLoader2};//# sourceMappingURL=bulk-dataloader-v2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bulk-dataloader-v2.js","sources":["../../src/dataloaders/bulk-dataloader-v2.ts"],"sourcesContent":["/* eslint-disable import/no-extraneous-dependencies */\nimport DataLoader from 'dataloader';\nimport { injectable, unmanaged } from 'inversify';\nimport { FilterQuery } from 'mongoose';\nimport { IBaseService, IDataLoader, AsDomainType, DataLoaderOptions } from 'common/server';\n\n@injectable()\nexport class BulkDataLoader2<SchemaType>\n extends DataLoader<string, AsDomainType<SchemaType> | null>\n implements IDataLoader<SchemaType>\n{\n constructor(@unmanaged() private readonly service: IBaseService<SchemaType>) {\n super(async (ids: string[]) => {\n const data = await this.service.getByIds(ids);\n return ids.map((id) => data.find((record) => record.id === id) || null);\n });\n }\n\n withOptions = new DataLoader<DataLoaderOptions<SchemaType>, AsDomainType<SchemaType>[]>(async (options) => {\n const [{ searchKey, comparator, ...rest }] = options;\n const ids = options.map((option) => option.id);\n\n // Create a properly typed criteria object with explicit type assertion\n const criteria = {\n ...(rest.criteria || {}),\n [searchKey as string]: { $in: ids },\n } as FilterQuery<SchemaType>;\n\n const results = await this.service.getAll({\n ...rest,\n criteria,\n });\n\n return options.map((option) =>\n results.filter((item) => {\n if (typeof comparator === 'function') return comparator(option, item);\n return item[searchKey as keyof AsDomainType<SchemaType>]?.toString() === option.id.toString();\n }),\n );\n });\n}\n"],"names":[],"mappings":";AAOO,IAAM,eAAe,GAArB,MAAM,eACT,SAAQ,UAAmD,CAAA;AAGjB,IAAA,OAAA,CAAA;AAA1C,IAAA,WAAA,CAA0C,OAAiC,EAAA;AACvE,QAAA,KAAK,CAAC,OAAO,GAAa,KAAI;YAC1B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9C,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC;AAC5E,SAAC,CAAC,CAAC;QAJmC,IAAO,CAAA,OAAA,GAAP,OAAO,CAA0B;KAK1E;IAED,WAAW,GAAG,IAAI,UAAU,CAA4D,OAAO,OAAO,KAAI;AACtG,QAAA,MAAM,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;AACrD,QAAA,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC;;AAG/C,QAAA,MAAM,QAAQ,GAAG;AACb,YAAA,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;AACxB,YAAA,CAAC,SAAmB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;SACX,CAAC;QAE7B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;AACtC,YAAA,GAAG,IAAI;YACP,QAAQ;AACX,SAAA,CAAC,CAAC;AAEH,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KACtB,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,KAAI;YACpB,IAAI,OAAO,UAAU,KAAK,UAAU;AAAE,gBAAA,OAAO,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACtE,YAAA,OAAO,IAAI,CAAC,SAA2C,CAAC,EAAE,QAAQ,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;SACjG,CAAC,CACL,CAAC;AACN,KAAC,CAAC,CAAC;EACN;AAjCY,eAAe,GAAA,UAAA,CAAA;AAD3B,IAAA,UAAU,EAAE;IAKI,OAAA,CAAA,CAAA,EAAA,SAAS,EAAE,CAAA;AAA2B,IAAA,UAAA,CAAA,mBAAA,EAAA,CAAA,QAAA,EAAA,GAAA,OAAA,YAAY,oBAAZ,YAAY,CAAA,KAAA,UAAA,GAAA,EAAA,GAAA,MAAA,CAAA,CAAA;AAJtD,CAAA,EAAA,eAAe,CAiC3B"}
1
+ {"version":3,"file":"bulk-dataloader-v2.js","sources":["../../src/dataloaders/bulk-dataloader-v2.ts"],"sourcesContent":["/* eslint-disable import/no-extraneous-dependencies */\nimport DataLoader from 'dataloader';\nimport { injectable, unmanaged } from 'inversify';\nimport { FilterQuery, Types } from 'mongoose';\nimport { IBaseService, IDataLoader, AsDomainType, DataLoaderOptions } from 'common/server';\n\n/**\n * BulkDataLoader2 with Dual ID System Support\n *\n * Supports both ObjectId and UUID lookups:\n * - ObjectId: MongoDB's native `_id` field\n * - UUID: External identifier stored as `<collection>Id` (e.g., projectId, organizationId)\n *\n * The loader automatically detects the ID format and queries appropriately:\n * - UUIDs contain hyphens (e.g., \"550e8400-e29b-41d4-a957-446655440000\")\n * - ObjectIds are 24-character hex strings (e.g., \"507f1f77bcf86cd799439011\")\n */\n@injectable()\nexport class BulkDataLoader2<SchemaType>\n extends DataLoader<string, AsDomainType<SchemaType> | null>\n implements IDataLoader<SchemaType>\n{\n /**\n * Optional UUID field name for this collection (e.g., 'projectId', 'organizationId')\n * If not provided, the loader will only support ObjectId lookups\n */\n private readonly uuidFieldName?: string;\n\n constructor(\n @unmanaged() private readonly service: IBaseService<SchemaType>,\n @unmanaged() uuidFieldName?: string,\n ) {\n super(async (ids: string[]) => {\n const data = await this.loadByIds(ids);\n return ids.map((id) => this.findRecordById(data, id));\n });\n this.uuidFieldName = uuidFieldName;\n }\n\n /**\n * Detects if an ID is a UUID (contains hyphens) or ObjectId (24-char hex)\n */\n private isUUID(id: string): boolean {\n return id.includes('-');\n }\n\n /**\n * Detects if an ID is a valid ObjectId\n */\n private isObjectId(id: string): boolean {\n return Types.ObjectId.isValid(id) && !this.isUUID(id);\n }\n\n /**\n * Loads records by IDs, supporting both UUID and ObjectId formats\n * Performs a single query with $or conditions for efficient lookup\n */\n private async loadByIds(ids: string[]): Promise<AsDomainType<SchemaType>[]> {\n // Separate UUIDs and ObjectIds for optimized querying\n const uuidIds: string[] = [];\n const objectIds: string[] = [];\n\n ids.forEach((id) => {\n if (this.isUUID(id)) {\n uuidIds.push(id);\n } else if (this.isObjectId(id)) {\n objectIds.push(id);\n }\n });\n\n // If no UUID field is configured, only support ObjectId lookups\n if (!this.uuidFieldName && uuidIds.length > 0) {\n console.warn(\n `[BulkDataLoader2] UUID IDs detected but no uuidFieldName configured. UUIDs will not be resolved: ${uuidIds.join(', ')}`,\n );\n }\n\n // Build query criteria using $or for mixed ID types\n const criteria: FilterQuery<SchemaType>[] = [];\n\n if (objectIds.length > 0) {\n // Query by _id (ObjectId)\n criteria.push({ _id: { $in: objectIds } } as FilterQuery<SchemaType>);\n }\n\n if (uuidIds.length > 0 && this.uuidFieldName) {\n // Query by UUID field (e.g., projectId, organizationId)\n criteria.push({ [this.uuidFieldName]: { $in: uuidIds } } as FilterQuery<SchemaType>);\n }\n\n // If no valid IDs, return empty array\n if (criteria.length === 0) {\n return [];\n }\n\n // Execute query with $or combining both lookup strategies\n const query: FilterQuery<SchemaType> =\n criteria.length === 1 ? criteria[0] : ({ $or: criteria } as FilterQuery<SchemaType>);\n\n return await this.service.getAll({ criteria: query });\n }\n\n /**\n * Finds a record by ID, checking both ObjectId and UUID fields\n */\n private findRecordById(records: AsDomainType<SchemaType>[], id: string): AsDomainType<SchemaType> | null {\n return (\n records.find((record) => {\n // Check if ID matches the record's id field (transformed from _id)\n if (record.id === id) {\n return true;\n }\n\n // If UUID field is configured, check that field too\n if (this.uuidFieldName && (record as any)[this.uuidFieldName] === id) {\n return true;\n }\n\n return false;\n }) || null\n );\n }\n\n withOptions = new DataLoader<DataLoaderOptions<SchemaType>, AsDomainType<SchemaType>[]>(async (options) => {\n const [{ searchKey, comparator, ...rest }] = options;\n const ids = options.map((option) => option.id);\n\n // Create a properly typed criteria object with explicit type assertion\n const criteria = {\n ...(rest.criteria || {}),\n [searchKey as string]: { $in: ids },\n } as FilterQuery<SchemaType>;\n\n const results = await this.service.getAll({\n ...rest,\n criteria,\n });\n\n return options.map((option) =>\n results.filter((item) => {\n if (typeof comparator === 'function') return comparator(option, item);\n return item[searchKey as keyof AsDomainType<SchemaType>]?.toString() === option.id.toString();\n }),\n );\n });\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ import 'reflect-metadata';
package/lib/index.d.ts CHANGED
@@ -5,3 +5,4 @@ export * from './dataloaders';
5
5
  export * from './mixins';
6
6
  export * from './interfaces';
7
7
  export * from './interfaces/index.old';
8
+ export * from './moleculer-generation';
package/lib/index.js CHANGED
@@ -1 +1 @@
1
- export{generateMongo}from'./helpers/mongoose-connection.js';export{BaseService2}from'./services/BaseService.js';export{BaseProxyService2}from'./services/BaseProxyService.js';export{BaseService}from'./services/base-service.js';export{BaseProxyService}from'./services/base-proxy-service.js';export{addIdVirtualFields2,commonModelSchemaOptions2}from'./store/models/common-options-v2.js';export{addIdVirtualFields,commonModeSchemaOptions}from'./store/models/common-options.js';export{BaseMongoRepository}from'./store/repositories/BaseMongoRepository.js';export{BaseRepository}from'./store/repositories/base-repository.js';export{BulkDataLoader2}from'./dataloaders/bulk-dataloader-v2.js';export{BulkDataLoader}from'./dataloaders/bulk-dataloader.js';export{BaseServiceMixin as BaseServiceMixin2}from'./mixins/BaseServiceMixin.js';export{BaseServiceMixin}from'./mixins/base-service-mixin.js';export{PAGINATION_OPTIONS}from'./interfaces/getAllArgs.js';//# sourceMappingURL=index.js.map
1
+ export{generateMongo}from'./helpers/mongoose-connection.js';export{BaseService2}from'./services/BaseService.js';export{BaseProxyService2}from'./services/BaseProxyService.js';export{BaseService}from'./services/base-service.js';export{BaseProxyService}from'./services/base-proxy-service.js';export{addIdVirtualFields2,commonModelSchemaOptions2}from'./store/models/common-options-v2.js';export{addIdVirtualFields,commonModeSchemaOptions}from'./store/models/common-options.js';export{BaseMongoRepository}from'./store/repositories/BaseMongoRepository.js';export{BaseRepository}from'./store/repositories/base-repository.js';export{BulkDataLoader2}from'./dataloaders/bulk-dataloader-v2.js';export{BulkDataLoader}from'./dataloaders/bulk-dataloader.js';export{BaseServiceMixin as BaseServiceMixin2}from'./mixins/BaseServiceMixin.js';export{BaseServiceMixin}from'./mixins/base-service-mixin.js';export{PAGINATION_OPTIONS}from'./interfaces/getAllArgs.js';export{buildActionPath,getActionName,getAllMethodNames,isExcludedMethod,toPascalCase}from'./moleculer-generation/serviceGenerationUtils.js';export{Moleculer}from'./moleculer-generation/moleculerEventHandler.js';export{createTypedAction,debugServiceParams,generateAutoInferredServiceActions,generateServiceActions,generateServiceActionsAndEvents,generateTypeSafeServiceActions,printServiceParams,verifyAllParamsDefined}from'./moleculer-generation/typedMoleculerService.js';export{ProxyService,generateProxyMethods}from'./moleculer-generation/typedProxyService.js';//# sourceMappingURL=index.js.map
package/lib/module.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- import { Feature } from '@common-stack/server-core';
2
- declare const _default: Feature<any, any>;
1
+ declare const _default: any;
3
2
  export default _default;
package/lib/module.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import {Feature}from'@common-stack/server-core';import {localContainerModule,externalContainerModule}from'./containers/container.js';var module = new Feature({
2
2
  createContainerFunc: [localContainerModule],
3
- createHemeraContainerFunc: [externalContainerModule],
3
+ createMicroServiceContainerFunc: [externalContainerModule],
4
4
  });export{module as default};//# sourceMappingURL=module.js.map
package/lib/module.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"module.js","sources":["../src/module.ts"],"sourcesContent":["import { Feature } from '@common-stack/server-core';\nimport { externalContainerModule, localContainerModule } from './containers';\n\nexport default new Feature({\n createContainerFunc: [localContainerModule],\n createHemeraContainerFunc: [externalContainerModule],\n});\n"],"names":[],"mappings":"qIAGA,aAAe,IAAI,OAAO,CAAC;IACvB,mBAAmB,EAAE,CAAC,oBAAoB,CAAC;IAC3C,yBAAyB,EAAE,CAAC,uBAAuB,CAAC;AACvD,CAAA,CAAC"}
1
+ {"version":3,"file":"module.js","sources":["../src/module.ts"],"sourcesContent":["import { Feature } from '@common-stack/server-core';\nimport { externalContainerModule, localContainerModule } from './containers';\n\nexport default new Feature({\n createContainerFunc: [localContainerModule],\n createMicroServiceContainerFunc: [externalContainerModule],\n});\n"],"names":[],"mappings":"qIAGA,aAAe,IAAI,OAAO,CAAC;IACvB,mBAAmB,EAAE,CAAC,oBAAoB,CAAC;IAC3C,+BAA+B,EAAE,CAAC,uBAAuB,CAAC;AAC7D,CAAA,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @file moleculer-generation/index.ts
3
+ * @description Auto-generation utilities for Moleculer services and proxy services
4
+ *
5
+ * This module provides utilities for auto-generating:
6
+ * - Server-side Moleculer service actions and events
7
+ * - Client-side proxy service methods
8
+ *
9
+ * All utilities ensure consistent naming conventions (camelCase) across
10
+ * the entire microservice architecture.
11
+ */
12
+ export * from './serviceGenerationUtils';
13
+ export * from './moleculerEventHandler';
14
+ export * from './typedMoleculerService';
15
+ export * from './typedProxyService';
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @file moleculer-event-handler.ts
3
+ * @description Decorator for marking service methods as Moleculer event handlers
4
+ *
5
+ * This allows event handlers to be defined directly in the service class
6
+ * and automatically registered as Moleculer events.
7
+ */
8
+ import 'reflect-metadata';
9
+ /**
10
+ * Moleculer namespace containing event handler utilities
11
+ */
12
+ export declare namespace Moleculer {
13
+ /**
14
+ * Metadata key for storing event handler information
15
+ */
16
+ const EVENT_HANDLER_METADATA_KEY = "moleculer:eventHandler";
17
+ /**
18
+ * Event handler metadata interface
19
+ */
20
+ interface EventHandlerMetadata {
21
+ eventName: string;
22
+ methodName: string;
23
+ group?: string;
24
+ }
25
+ /**
26
+ * Decorator for marking a service method as a Moleculer event handler
27
+ *
28
+ * @param eventName - The event name to listen for
29
+ * @param options - Optional event configuration
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * class OrganizationService implements IOrganizationService {
34
+ * @Moleculer.EventHandler(UserBroadcasterAction.OnUserCreated)
35
+ * async onUserCreated(event: IUserCreationEvent): Promise<void> {
36
+ * await this.createDefaultOrganization(event.user);
37
+ * }
38
+ *
39
+ * @Moleculer.EventHandler(OrganizationServiceAction.OnOrganizationCreated, { group: 'org-setup' })
40
+ * async onOrganizationCreated(event: IOrganizationCreatedEvent): Promise<void> {
41
+ * // Handle organization creation
42
+ * }
43
+ * }
44
+ * ```
45
+ */
46
+ function EventHandler(eventName: string, options?: {
47
+ group?: string;
48
+ }): MethodDecorator;
49
+ /**
50
+ * Get all Moleculer event handlers defined on a service class
51
+ *
52
+ * @param serviceClassOrInstance - The service class constructor or instance
53
+ * @returns Array of event handler metadata
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const handlers = Moleculer.getEventHandlers(OrganizationService);
58
+ * // Returns: [
59
+ * // { eventName: 'user.created', methodName: 'onUserCreated' },
60
+ * // { eventName: 'org.created', methodName: 'onOrganizationCreated' }
61
+ * // ]
62
+ * ```
63
+ */
64
+ function getEventHandlers(serviceClassOrInstance: (new (...args: unknown[]) => unknown) | object): EventHandlerMetadata[];
65
+ /**
66
+ * Check if a method is marked as a Moleculer event handler
67
+ *
68
+ * @param serviceClassOrInstance - The service class constructor or instance
69
+ * @param methodName - The method name to check
70
+ * @returns Event handler metadata if found, undefined otherwise
71
+ */
72
+ function isEventHandler(serviceClassOrInstance: (new (...args: unknown[]) => unknown) | object, methodName: string): EventHandlerMetadata | undefined;
73
+ }
@@ -0,0 +1,91 @@
1
+ import'reflect-metadata';// from package: store-mongo
2
+ /* eslint-disable @typescript-eslint/no-namespace */
3
+ /**
4
+ * @file moleculer-event-handler.ts
5
+ * @description Decorator for marking service methods as Moleculer event handlers
6
+ *
7
+ * This allows event handlers to be defined directly in the service class
8
+ * and automatically registered as Moleculer events.
9
+ */
10
+ /**
11
+ * Moleculer namespace containing event handler utilities
12
+ */
13
+ var Moleculer;
14
+ (function (Moleculer) {
15
+ /**
16
+ * Metadata key for storing event handler information
17
+ */
18
+ Moleculer.EVENT_HANDLER_METADATA_KEY = 'moleculer:eventHandler';
19
+ /**
20
+ * Decorator for marking a service method as a Moleculer event handler
21
+ *
22
+ * @param eventName - The event name to listen for
23
+ * @param options - Optional event configuration
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * class OrganizationService implements IOrganizationService {
28
+ * @Moleculer.EventHandler(UserBroadcasterAction.OnUserCreated)
29
+ * async onUserCreated(event: IUserCreationEvent): Promise<void> {
30
+ * await this.createDefaultOrganization(event.user);
31
+ * }
32
+ *
33
+ * @Moleculer.EventHandler(OrganizationServiceAction.OnOrganizationCreated, { group: 'org-setup' })
34
+ * async onOrganizationCreated(event: IOrganizationCreatedEvent): Promise<void> {
35
+ * // Handle organization creation
36
+ * }
37
+ * }
38
+ * ```
39
+ */
40
+ function EventHandler(eventName, options) {
41
+ return function moleculerEventHandlerDecorator(target, propertyKey, descriptor) {
42
+ // Get existing event handlers for this class
43
+ const existingHandlers = Reflect.getMetadata(Moleculer.EVENT_HANDLER_METADATA_KEY, target.constructor) || [];
44
+ // Add this handler to the list
45
+ const metadata = {
46
+ eventName,
47
+ methodName: propertyKey.toString(),
48
+ group: options?.group,
49
+ };
50
+ existingHandlers.push(metadata);
51
+ // Store the updated list
52
+ Reflect.defineMetadata(Moleculer.EVENT_HANDLER_METADATA_KEY, existingHandlers, target.constructor);
53
+ return descriptor;
54
+ };
55
+ }
56
+ Moleculer.EventHandler = EventHandler;
57
+ /**
58
+ * Get all Moleculer event handlers defined on a service class
59
+ *
60
+ * @param serviceClassOrInstance - The service class constructor or instance
61
+ * @returns Array of event handler metadata
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const handlers = Moleculer.getEventHandlers(OrganizationService);
66
+ * // Returns: [
67
+ * // { eventName: 'user.created', methodName: 'onUserCreated' },
68
+ * // { eventName: 'org.created', methodName: 'onOrganizationCreated' }
69
+ * // ]
70
+ * ```
71
+ */
72
+ function getEventHandlers(serviceClassOrInstance) {
73
+ const target = typeof serviceClassOrInstance === 'function'
74
+ ? serviceClassOrInstance
75
+ : serviceClassOrInstance.constructor;
76
+ return Reflect.getMetadata(Moleculer.EVENT_HANDLER_METADATA_KEY, target) || [];
77
+ }
78
+ Moleculer.getEventHandlers = getEventHandlers;
79
+ /**
80
+ * Check if a method is marked as a Moleculer event handler
81
+ *
82
+ * @param serviceClassOrInstance - The service class constructor or instance
83
+ * @param methodName - The method name to check
84
+ * @returns Event handler metadata if found, undefined otherwise
85
+ */
86
+ function isEventHandler(serviceClassOrInstance, methodName) {
87
+ const handlers = getEventHandlers(serviceClassOrInstance);
88
+ return handlers.find(h => h.methodName === methodName);
89
+ }
90
+ Moleculer.isEventHandler = isEventHandler;
91
+ })(Moleculer || (Moleculer = {}));export{Moleculer};//# sourceMappingURL=moleculerEventHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moleculerEventHandler.js","sources":["../../src/moleculer-generation/moleculerEventHandler.ts"],"sourcesContent":["// from package: store-mongo\n/* eslint-disable @typescript-eslint/no-namespace */\n/**\n * @file moleculer-event-handler.ts\n * @description Decorator for marking service methods as Moleculer event handlers\n * \n * This allows event handlers to be defined directly in the service class\n * and automatically registered as Moleculer events.\n */\n\nimport 'reflect-metadata';\n\n/**\n * Moleculer namespace containing event handler utilities\n */\nexport namespace Moleculer {\n /**\n * Metadata key for storing event handler information\n */\n export const EVENT_HANDLER_METADATA_KEY = 'moleculer:eventHandler';\n\n /**\n * Event handler metadata interface\n */\n export interface EventHandlerMetadata {\n eventName: string;\n methodName: string;\n group?: string;\n }\n\n /**\n * Decorator for marking a service method as a Moleculer event handler\n * \n * @param eventName - The event name to listen for\n * @param options - Optional event configuration\n * \n * @example\n * ```typescript\n * class OrganizationService implements IOrganizationService {\n * @Moleculer.EventHandler(UserBroadcasterAction.OnUserCreated)\n * async onUserCreated(event: IUserCreationEvent): Promise<void> {\n * await this.createDefaultOrganization(event.user);\n * }\n * \n * @Moleculer.EventHandler(OrganizationServiceAction.OnOrganizationCreated, { group: 'org-setup' })\n * async onOrganizationCreated(event: IOrganizationCreatedEvent): Promise<void> {\n * // Handle organization creation\n * }\n * }\n * ```\n */\n export function EventHandler(\n eventName: string,\n options?: { group?: string }\n ): MethodDecorator {\n return function moleculerEventHandlerDecorator(\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ): PropertyDescriptor {\n // Get existing event handlers for this class\n const existingHandlers: EventHandlerMetadata[] = \n Reflect.getMetadata(EVENT_HANDLER_METADATA_KEY, target.constructor) || [];\n \n // Add this handler to the list\n const metadata: EventHandlerMetadata = {\n eventName,\n methodName: propertyKey.toString(),\n group: options?.group,\n };\n \n existingHandlers.push(metadata);\n \n // Store the updated list\n Reflect.defineMetadata(EVENT_HANDLER_METADATA_KEY, existingHandlers, target.constructor);\n \n return descriptor;\n };\n }\n\n /**\n * Get all Moleculer event handlers defined on a service class\n * \n * @param serviceClassOrInstance - The service class constructor or instance\n * @returns Array of event handler metadata\n * \n * @example\n * ```typescript\n * const handlers = Moleculer.getEventHandlers(OrganizationService);\n * // Returns: [\n * // { eventName: 'user.created', methodName: 'onUserCreated' },\n * // { eventName: 'org.created', methodName: 'onOrganizationCreated' }\n * // ]\n * ```\n */\n export function getEventHandlers(\n serviceClassOrInstance: (new (...args: unknown[]) => unknown) | object\n ): EventHandlerMetadata[] {\n const target = typeof serviceClassOrInstance === 'function' \n ? serviceClassOrInstance \n : (serviceClassOrInstance as { constructor: new (...args: unknown[]) => unknown }).constructor;\n return Reflect.getMetadata(EVENT_HANDLER_METADATA_KEY, target) || [];\n }\n\n /**\n * Check if a method is marked as a Moleculer event handler\n * \n * @param serviceClassOrInstance - The service class constructor or instance\n * @param methodName - The method name to check\n * @returns Event handler metadata if found, undefined otherwise\n */\n export function isEventHandler(\n serviceClassOrInstance: (new (...args: unknown[]) => unknown) | object,\n methodName: string\n ): EventHandlerMetadata | undefined {\n const handlers = getEventHandlers(serviceClassOrInstance);\n return handlers.find(h => h.methodName === methodName);\n }\n}\n"],"names":[],"mappings":"yBAAA;AACA;AACA;;;;;;AAMG;AAIH;;AAEG;AACG,IAAW,UAuGhB;AAvGD,CAAA,UAAiB,SAAS,EAAA;AACtB;;AAEG;IACU,SAA0B,CAAA,0BAAA,GAAG,wBAAwB,CAAC;AAWnE;;;;;;;;;;;;;;;;;;;;AAoBG;AACH,IAAA,SAAgB,YAAY,CACxB,SAAiB,EACjB,OAA4B,EAAA;AAE5B,QAAA,OAAO,SAAS,8BAA8B,CAC1C,MAAc,EACd,WAA4B,EAC5B,UAA8B,EAAA;;AAG9B,YAAA,MAAM,gBAAgB,GAClB,OAAO,CAAC,WAAW,CAAC,SAAA,CAAA,0BAA0B,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;;AAG9E,YAAA,MAAM,QAAQ,GAAyB;gBACnC,SAAS;AACT,gBAAA,UAAU,EAAE,WAAW,CAAC,QAAQ,EAAE;gBAClC,KAAK,EAAE,OAAO,EAAE,KAAK;aACxB,CAAC;AAEF,YAAA,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;;AAGhC,YAAA,OAAO,CAAC,cAAc,CAAC,SAAA,CAAA,0BAA0B,EAAE,gBAAgB,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;AAEzF,YAAA,OAAO,UAAU,CAAC;AACtB,SAAC,CAAC;KACL;AA3Be,IAAA,SAAA,CAAA,YAAY,eA2B3B,CAAA;AAED;;;;;;;;;;;;;;AAcG;IACH,SAAgB,gBAAgB,CAC5B,sBAAsE,EAAA;AAEtE,QAAA,MAAM,MAAM,GAAG,OAAO,sBAAsB,KAAK,UAAU;AACvD,cAAE,sBAAsB;AACxB,cAAG,sBAA+E,CAAC,WAAW,CAAC;QACnG,OAAO,OAAO,CAAC,WAAW,CAAC,SAAA,CAAA,0BAA0B,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;KACxE;AAPe,IAAA,SAAA,CAAA,gBAAgB,mBAO/B,CAAA;AAED;;;;;;AAMG;AACH,IAAA,SAAgB,cAAc,CAC1B,sBAAsE,EACtE,UAAkB,EAAA;AAElB,QAAA,MAAM,QAAQ,GAAG,gBAAgB,CAAC,sBAAsB,CAAC,CAAC;AAC1D,QAAA,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;KAC1D;AANe,IAAA,SAAA,CAAA,cAAc,iBAM7B,CAAA;AACL,CAAC,EAvGgB,SAAS,KAAT,SAAS,GAuGzB,EAAA,CAAA,CAAA"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @file serviceGenerationUtils.ts
3
+ * @description Shared utilities for auto-generating Moleculer services and proxy services.
4
+ *
5
+ * This module provides common functionality used by both:
6
+ * - typedMoleculerService.ts (server-side Moleculer service generation)
7
+ * - typedProxyService.ts (client-side proxy service generation)
8
+ *
9
+ * Centralizing these utilities ensures consistency in action naming conventions
10
+ * and method discovery across the entire microservice architecture.
11
+ */
12
+ /**
13
+ * Excluded base service methods that should not be auto-generated as actions
14
+ */
15
+ export type ExcludedServiceMethods = 'dispose' | 'get' | 'getAll' | 'bulkDelete' | 'delete' | 'count' | 'getByName' | 'getByIds' | 'getAllWithCount' | 'create' | 'update' | 'bulkCreate' | 'insert' | 'broker' | 'logger' | 'topic' | 'callAction';
16
+ /**
17
+ * Check if a method should be excluded from auto-generation
18
+ *
19
+ * @param methodName - The method name to check
20
+ * @returns true if the method should be excluded
21
+ */
22
+ export declare function isExcludedMethod(methodName: string): boolean;
23
+ /**
24
+ * Get all method names from a service instance, traversing the prototype chain.
25
+ *
26
+ * This function walks up the prototype chain to include inherited methods from
27
+ * parent classes, which is essential for services that extend base classes.
28
+ *
29
+ * @param obj - The service instance to analyze
30
+ * @returns Array of method names (includes inherited methods)
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * class BaseService {
35
+ * get() {}
36
+ * getAll() {}
37
+ * }
38
+ *
39
+ * class UserService extends BaseService {
40
+ * createUser() {}
41
+ * }
42
+ *
43
+ * const service = new UserService();
44
+ * const methods = getAllMethodNames(service);
45
+ * // Returns: ['createUser', 'get', 'getAll', 'constructor']
46
+ * ```
47
+ */
48
+ export declare function getAllMethodNames(obj: unknown): string[];
49
+ /**
50
+ * Convert method name to action name using camelCase convention.
51
+ *
52
+ * **IMPORTANT**: We use camelCase (method name as-is) for action names to match
53
+ * the Moleculer service action registration pattern. Both server-side Moleculer
54
+ * services and client-side proxy services must use the same convention.
55
+ *
56
+ * @param methodName - The method name (e.g., 'getTags', 'createTag')
57
+ * @returns The action name in camelCase (same as method name)
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * getActionName('getTags') // Returns: 'getTags'
62
+ * getActionName('createTag') // Returns: 'createTag'
63
+ * getActionName('removeTag') // Returns: 'removeTag'
64
+ * ```
65
+ *
66
+ * @deprecated PascalCase conversion (e.g., GetTags, CreateTag) is no longer used.
67
+ * Previous behavior caused mismatches between proxy and Moleculer services.
68
+ */
69
+ export declare function getActionName(methodName: string): string;
70
+ /**
71
+ * Convert string to PascalCase (first letter uppercase).
72
+ *
73
+ * **DEPRECATED**: This function is kept for backward compatibility with command enums
74
+ * but should NOT be used for action name generation. Use getActionName() instead.
75
+ *
76
+ * @param str - The string to convert
77
+ * @returns String with first letter uppercase
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * toPascalCase('getTags') // Returns: 'GetTags'
82
+ * toPascalCase('createTag') // Returns: 'CreateTag'
83
+ * ```
84
+ */
85
+ export declare function toPascalCase(str: string): string;
86
+ /**
87
+ * Build the full Moleculer action path from topic and action name.
88
+ *
89
+ * @param topic - The Moleculer service topic (e.g., 'Tag', 'User')
90
+ * @param actionName - The action name (e.g., 'getTags', 'createTag')
91
+ * @returns Full action path (e.g., 'Tag.getTags', 'User.createUser')
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * buildActionPath('Tag', 'getTags') // Returns: 'Tag.getTags'
96
+ * buildActionPath('User', 'createUser') // Returns: 'User.createUser'
97
+ * ```
98
+ */
99
+ export declare function buildActionPath(topic: string, actionName: string): string;
@@ -0,0 +1,146 @@
1
+ /**
2
+ * @file serviceGenerationUtils.ts
3
+ * @description Shared utilities for auto-generating Moleculer services and proxy services.
4
+ *
5
+ * This module provides common functionality used by both:
6
+ * - typedMoleculerService.ts (server-side Moleculer service generation)
7
+ * - typedProxyService.ts (client-side proxy service generation)
8
+ *
9
+ * Centralizing these utilities ensures consistency in action naming conventions
10
+ * and method discovery across the entire microservice architecture.
11
+ */
12
+ /**
13
+ * Check if a method should be excluded from auto-generation
14
+ *
15
+ * @param methodName - The method name to check
16
+ * @returns true if the method should be excluded
17
+ */
18
+ function isExcludedMethod(methodName) {
19
+ const excludedMethods = [
20
+ 'dispose',
21
+ 'get',
22
+ 'getAll',
23
+ 'bulkDelete',
24
+ 'delete',
25
+ 'count',
26
+ 'getByName',
27
+ 'getByIds',
28
+ 'getAllWithCount',
29
+ 'create',
30
+ 'update',
31
+ 'bulkCreate',
32
+ 'insert',
33
+ 'broker',
34
+ 'logger',
35
+ 'topic',
36
+ 'callAction',
37
+ ];
38
+ return excludedMethods.includes(methodName);
39
+ }
40
+ /**
41
+ * Get all method names from a service instance, traversing the prototype chain.
42
+ *
43
+ * This function walks up the prototype chain to include inherited methods from
44
+ * parent classes, which is essential for services that extend base classes.
45
+ *
46
+ * @param obj - The service instance to analyze
47
+ * @returns Array of method names (includes inherited methods)
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * class BaseService {
52
+ * get() {}
53
+ * getAll() {}
54
+ * }
55
+ *
56
+ * class UserService extends BaseService {
57
+ * createUser() {}
58
+ * }
59
+ *
60
+ * const service = new UserService();
61
+ * const methods = getAllMethodNames(service);
62
+ * // Returns: ['createUser', 'get', 'getAll', 'constructor']
63
+ * ```
64
+ */
65
+ function getAllMethodNames(obj) {
66
+ const methods = new Set();
67
+ let current = obj;
68
+ // Traverse prototype chain
69
+ while (current && current !== Object.prototype) {
70
+ const props = Object.getOwnPropertyNames(current);
71
+ for (const prop of props) {
72
+ if (prop !== 'constructor') {
73
+ try {
74
+ const descriptor = Object.getOwnPropertyDescriptor(current, prop);
75
+ if (descriptor && typeof descriptor.value === 'function') {
76
+ methods.add(prop);
77
+ }
78
+ }
79
+ catch (error) {
80
+ // Skip properties that can't be accessed
81
+ }
82
+ }
83
+ }
84
+ current = Object.getPrototypeOf(current);
85
+ }
86
+ return Array.from(methods);
87
+ }
88
+ /**
89
+ * Convert method name to action name using camelCase convention.
90
+ *
91
+ * **IMPORTANT**: We use camelCase (method name as-is) for action names to match
92
+ * the Moleculer service action registration pattern. Both server-side Moleculer
93
+ * services and client-side proxy services must use the same convention.
94
+ *
95
+ * @param methodName - The method name (e.g., 'getTags', 'createTag')
96
+ * @returns The action name in camelCase (same as method name)
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * getActionName('getTags') // Returns: 'getTags'
101
+ * getActionName('createTag') // Returns: 'createTag'
102
+ * getActionName('removeTag') // Returns: 'removeTag'
103
+ * ```
104
+ *
105
+ * @deprecated PascalCase conversion (e.g., GetTags, CreateTag) is no longer used.
106
+ * Previous behavior caused mismatches between proxy and Moleculer services.
107
+ */
108
+ function getActionName(methodName) {
109
+ // Use method name as-is (camelCase) for action names
110
+ // This ensures proxy services and Moleculer services use the same action keys
111
+ return methodName;
112
+ }
113
+ /**
114
+ * Convert string to PascalCase (first letter uppercase).
115
+ *
116
+ * **DEPRECATED**: This function is kept for backward compatibility with command enums
117
+ * but should NOT be used for action name generation. Use getActionName() instead.
118
+ *
119
+ * @param str - The string to convert
120
+ * @returns String with first letter uppercase
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * toPascalCase('getTags') // Returns: 'GetTags'
125
+ * toPascalCase('createTag') // Returns: 'CreateTag'
126
+ * ```
127
+ */
128
+ function toPascalCase(str) {
129
+ return str.charAt(0).toUpperCase() + str.slice(1);
130
+ }
131
+ /**
132
+ * Build the full Moleculer action path from topic and action name.
133
+ *
134
+ * @param topic - The Moleculer service topic (e.g., 'Tag', 'User')
135
+ * @param actionName - The action name (e.g., 'getTags', 'createTag')
136
+ * @returns Full action path (e.g., 'Tag.getTags', 'User.createUser')
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * buildActionPath('Tag', 'getTags') // Returns: 'Tag.getTags'
141
+ * buildActionPath('User', 'createUser') // Returns: 'User.createUser'
142
+ * ```
143
+ */
144
+ function buildActionPath(topic, actionName) {
145
+ return `${topic}.${actionName}`;
146
+ }export{buildActionPath,getActionName,getAllMethodNames,isExcludedMethod,toPascalCase};//# sourceMappingURL=serviceGenerationUtils.js.map