@adminide-stack/marketplace-module-server 12.0.4-alpha.44 → 12.0.4-alpha.441

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 (185) hide show
  1. package/Readme.md +321 -0
  2. package/lib/containers/module.d.ts +8 -0
  3. package/lib/containers/module.d.ts.map +1 -1
  4. package/lib/containers/module.js +15 -5
  5. package/lib/containers/module.js.map +1 -1
  6. package/lib/dataloaders/index.d.ts +1 -0
  7. package/lib/dataloaders/index.d.ts.map +1 -0
  8. package/lib/demo/test-graphql-examples.d.ts +73 -0
  9. package/lib/demo/test-graphql-examples.d.ts.map +1 -0
  10. package/lib/graphql/resolvers/form-templates-resolver.d.ts +220 -0
  11. package/lib/graphql/resolvers/form-templates-resolver.d.ts.map +1 -0
  12. package/lib/graphql/resolvers/form-templates-resolver.js +170 -0
  13. package/lib/graphql/resolvers/form-templates-resolver.js.map +1 -0
  14. package/lib/graphql/resolvers/gallery-resolver.d.ts +15 -0
  15. package/lib/graphql/resolvers/gallery-resolver.d.ts.map +1 -0
  16. package/lib/graphql/resolvers/gallery-resolver.js +35 -0
  17. package/lib/graphql/resolvers/gallery-resolver.js.map +1 -0
  18. package/lib/graphql/resolvers/index.d.ts +247 -1
  19. package/lib/graphql/resolvers/index.d.ts.map +1 -1
  20. package/lib/graphql/resolvers/index.js +1 -0
  21. package/lib/graphql/resolvers/index.js.map +1 -0
  22. package/lib/graphql/resolvers/installed-extension-resolver.d.ts +5 -0
  23. package/lib/graphql/resolvers/installed-extension-resolver.d.ts.map +1 -0
  24. package/lib/graphql/resolvers/installed-extension-resolver.js +309 -0
  25. package/lib/graphql/resolvers/installed-extension-resolver.js.map +1 -0
  26. package/lib/graphql/resolvers/marketplace-form-resolver.d.ts +13 -0
  27. package/lib/graphql/resolvers/marketplace-form-resolver.d.ts.map +1 -0
  28. package/lib/graphql/resolvers/marketplace-form-resolver.js +90 -0
  29. package/lib/graphql/resolvers/marketplace-form-resolver.js.map +1 -0
  30. package/lib/graphql/resolvers/publisher-analytics-resolver.d.ts +14 -0
  31. package/lib/graphql/resolvers/publisher-analytics-resolver.d.ts.map +1 -0
  32. package/lib/graphql/resolvers/publisher-analytics-resolver.js +221 -0
  33. package/lib/graphql/resolvers/publisher-analytics-resolver.js.map +1 -0
  34. package/lib/graphql/resolvers/publisher-resolver.d.ts +5 -0
  35. package/lib/graphql/resolvers/publisher-resolver.d.ts.map +1 -0
  36. package/lib/graphql/resolvers/publisher-resolver.js +176 -0
  37. package/lib/graphql/resolvers/publisher-resolver.js.map +1 -0
  38. package/lib/graphql/resolvers/registry-extension-resolver.d.ts +5 -0
  39. package/lib/graphql/resolvers/registry-extension-resolver.d.ts.map +1 -0
  40. package/lib/graphql/resolvers/registry-extension-resolver.js +46 -0
  41. package/lib/graphql/resolvers/registry-extension-resolver.js.map +1 -0
  42. package/lib/graphql/schemas/extension-pricing.graphql +546 -0
  43. package/lib/graphql/schemas/extension-pricing.graphql.js +1 -0
  44. package/lib/graphql/schemas/extension-pricing.graphql.js.map +1 -0
  45. package/lib/graphql/schemas/extension-registry.graphql +107 -0
  46. package/lib/graphql/schemas/extension-registry.graphql.js +1 -0
  47. package/lib/graphql/schemas/extension-registry.graphql.js.map +1 -0
  48. package/lib/graphql/schemas/form-templates.graphql +269 -0
  49. package/lib/graphql/schemas/form-templates.graphql.js +1 -0
  50. package/lib/graphql/schemas/form-templates.graphql.js.map +1 -0
  51. package/lib/graphql/schemas/gallery-schema.graphql +247 -0
  52. package/lib/graphql/schemas/gallery-schema.graphql.js +1 -0
  53. package/lib/graphql/schemas/gallery-schema.graphql.js.map +1 -0
  54. package/lib/graphql/schemas/index.d.ts.map +1 -1
  55. package/lib/graphql/schemas/index.js +3 -4
  56. package/lib/graphql/schemas/index.js.map +1 -1
  57. package/lib/graphql/schemas/installed-extension.graphql +324 -0
  58. package/lib/graphql/schemas/installed-extension.graphql.js +1 -0
  59. package/lib/graphql/schemas/installed-extension.graphql.js.map +1 -0
  60. package/lib/graphql/schemas/publisher-analytics.graphql +305 -0
  61. package/lib/graphql/schemas/publisher-analytics.graphql.js +1 -0
  62. package/lib/graphql/schemas/publisher-analytics.graphql.js.map +1 -0
  63. package/lib/graphql/schemas/publisher.graphql +376 -0
  64. package/lib/graphql/schemas/publisher.graphql.js +1 -0
  65. package/lib/graphql/schemas/publisher.graphql.js.map +1 -0
  66. package/lib/graphql/schemas/service.graphql +196 -0
  67. package/lib/index.d.ts +3 -1
  68. package/lib/index.d.ts.map +1 -1
  69. package/lib/index.js +1 -1
  70. package/lib/index.js.map +1 -1
  71. package/lib/module.d.ts +1 -1
  72. package/lib/module.d.ts.map +1 -1
  73. package/lib/module.js +10 -23
  74. package/lib/module.js.map +1 -1
  75. package/lib/plugins/extension-moleculer-service.d.ts +86 -0
  76. package/lib/plugins/extension-moleculer-service.d.ts.map +1 -0
  77. package/lib/plugins/index.d.ts +2 -0
  78. package/lib/plugins/index.d.ts.map +1 -0
  79. package/lib/services/extension-gallery-repository.d.ts +17 -0
  80. package/lib/services/extension-gallery-repository.d.ts.map +1 -0
  81. package/lib/services/extension-gallery-repository.js +192 -0
  82. package/lib/services/extension-gallery-repository.js.map +1 -0
  83. package/lib/services/extension-gallery-service-new.d.ts +39 -0
  84. package/lib/services/extension-gallery-service-new.d.ts.map +1 -0
  85. package/lib/services/extension-gallery-service.d.ts +30 -0
  86. package/lib/services/extension-gallery-service.d.ts.map +1 -0
  87. package/lib/services/extension-gallery-service.js +311 -0
  88. package/lib/services/extension-gallery-service.js.map +1 -0
  89. package/lib/services/index.d.ts +6 -1
  90. package/lib/services/index.d.ts.map +1 -1
  91. package/lib/services/installed-extension-service-ext.d.ts +16 -0
  92. package/lib/services/installed-extension-service-ext.d.ts.map +1 -0
  93. package/lib/services/installed-extension-service-ext.js +518 -0
  94. package/lib/services/installed-extension-service-ext.js.map +1 -0
  95. package/lib/services/installed-extension-service.d.ts +105 -0
  96. package/lib/services/installed-extension-service.d.ts.map +1 -0
  97. package/lib/services/installed-extension-service.js +600 -0
  98. package/lib/services/installed-extension-service.js.map +1 -0
  99. package/lib/services/installed-extension-service.test.d.ts +1 -0
  100. package/lib/services/installed-extension-service.test.d.ts.map +1 -0
  101. package/lib/services/publisher-analytics-service.d.ts +128 -0
  102. package/lib/services/publisher-analytics-service.d.ts.map +1 -0
  103. package/lib/services/publisher-event-service.d.ts +48 -0
  104. package/lib/services/publisher-event-service.d.ts.map +1 -0
  105. package/lib/services/publisher-event-service.js +296 -0
  106. package/lib/services/publisher-event-service.js.map +1 -0
  107. package/lib/services/publisher-service-context.d.ts +1 -0
  108. package/lib/services/publisher-service-context.d.ts.map +1 -0
  109. package/lib/services/publisher-service.d.ts +60 -0
  110. package/lib/services/publisher-service.d.ts.map +1 -0
  111. package/lib/services/publisher-service.js +134 -0
  112. package/lib/services/publisher-service.js.map +1 -0
  113. package/lib/store/index.d.ts +1 -1
  114. package/lib/store/index.d.ts.map +1 -1
  115. package/lib/store/models/index.d.ts +2 -1
  116. package/lib/store/models/index.d.ts.map +1 -1
  117. package/lib/store/models/installed-extension-model.d.ts +4 -0
  118. package/lib/store/models/installed-extension-model.d.ts.map +1 -0
  119. package/lib/store/models/installed-extension-model.js +269 -0
  120. package/lib/store/models/installed-extension-model.js.map +1 -0
  121. package/lib/store/models/publisher-event-model.d.ts +11 -0
  122. package/lib/store/models/publisher-event-model.d.ts.map +1 -0
  123. package/lib/store/models/publisher-model.d.ts +5 -0
  124. package/lib/store/models/publisher-model.d.ts.map +1 -0
  125. package/lib/store/models/publisher-model.js +103 -0
  126. package/lib/store/models/publisher-model.js.map +1 -0
  127. package/lib/store/models/publisher-stats-model.d.ts +1 -0
  128. package/lib/store/models/publisher-stats-model.d.ts.map +1 -0
  129. package/lib/store/repositories/index.d.ts +3 -0
  130. package/lib/store/repositories/index.d.ts.map +1 -0
  131. package/lib/store/repositories/installed-extension-repository.d.ts +73 -0
  132. package/lib/store/repositories/installed-extension-repository.d.ts.map +1 -0
  133. package/lib/store/repositories/installed-extension-repository.js +442 -0
  134. package/lib/store/repositories/installed-extension-repository.js.map +1 -0
  135. package/lib/store/repositories/publisher-analytics-repository.d.ts +1 -0
  136. package/lib/store/repositories/publisher-analytics-repository.d.ts.map +1 -0
  137. package/lib/store/repositories/publisher-repository.d.ts +19 -0
  138. package/lib/store/repositories/publisher-repository.d.ts.map +1 -0
  139. package/lib/store/repositories/publisher-repository.js +87 -0
  140. package/lib/store/repositories/publisher-repository.js.map +1 -0
  141. package/lib/templates/constants/DB_COLL_NAMES.ts.template +5 -0
  142. package/lib/templates/constants/SERVER_TYPES.ts.template +10 -4
  143. package/lib/templates/repositories/ExtensionGalleryRepository.ts.template +44 -0
  144. package/lib/templates/repositories/InstalledExtensionRepository.ts.template +94 -0
  145. package/lib/templates/repositories/MarketplacePublisherRepository.ts.template +24 -0
  146. package/lib/templates/repositories/RegistryExtensionRepository.ts.template +10 -15
  147. package/lib/templates/services/ExtensionGalleryDataLoader.ts.template +2 -0
  148. package/lib/templates/services/ExtensionGalleryService.ts.template +79 -0
  149. package/lib/templates/services/InstalledExtensionDataLoader.ts.template +2 -0
  150. package/lib/templates/services/InstalledExtensionService.ts.template +193 -0
  151. package/lib/templates/services/MarketplacePublisherService.ts.template +49 -0
  152. package/lib/templates/services/PublisherEventService.ts.template +56 -0
  153. package/lib/templates/services/RegistryExtensionService.ts.template +62 -18
  154. package/lib/tests/extension-integration.test.d.ts +1 -0
  155. package/lib/tests/extension-integration.test.d.ts.map +1 -0
  156. package/lib/tests/install-extension-graphql.test.d.ts +2 -0
  157. package/lib/tests/install-extension-graphql.test.d.ts.map +1 -0
  158. package/lib/tests/test-extension-services.d.ts +1 -0
  159. package/lib/tests/test-extension-services.d.ts.map +1 -0
  160. package/lib/utils/publisherValidation.d.ts +23 -0
  161. package/lib/utils/publisherValidation.d.ts.map +1 -0
  162. package/lib/utils/publisherValidation.js +144 -0
  163. package/lib/utils/publisherValidation.js.map +1 -0
  164. package/package.json +15 -7
  165. package/lib/graphql/resolvers/resolvers.d.ts +0 -2
  166. package/lib/graphql/resolvers/resolvers.d.ts.map +0 -1
  167. package/lib/graphql/resolvers/resolvers.js +0 -167
  168. package/lib/graphql/resolvers/resolvers.js.map +0 -1
  169. package/lib/graphql/schemas/extension.graphql +0 -57
  170. package/lib/graphql/schemas/extension.graphql.js +0 -1
  171. package/lib/graphql/schemas/extension.graphql.js.map +0 -1
  172. package/lib/services/extension-service.d.ts +0 -54
  173. package/lib/services/extension-service.d.ts.map +0 -1
  174. package/lib/services/extension-service.js +0 -42
  175. package/lib/services/extension-service.js.map +0 -1
  176. package/lib/store/models/registry-extension-model.d.ts +0 -10
  177. package/lib/store/models/registry-extension-model.d.ts.map +0 -1
  178. package/lib/store/models/registry-extension-model.js +0 -62
  179. package/lib/store/models/registry-extension-model.js.map +0 -1
  180. package/lib/store/repository/index.d.ts +0 -2
  181. package/lib/store/repository/index.d.ts.map +0 -1
  182. package/lib/store/repository/registry-extension-repository.d.ts +0 -31
  183. package/lib/store/repository/registry-extension-repository.d.ts.map +0 -1
  184. package/lib/store/repository/registry-extension-repository.js +0 -135
  185. package/lib/store/repository/registry-extension-repository.js.map +0 -1
@@ -0,0 +1,442 @@
1
+ import {__decorate,__param,__metadata}from'tslib';import {injectable,inject,optional}from'inversify';import {DB_COLL_NAMES}from'common/server';import {BaseMongoRepository}from'@common-stack/store-mongo';import*as mongoose from'mongoose';import {InstalledExtensionModelFunc}from'../models/installed-extension-model.js';import'../models/publisher-model.js';let InstalledExtensionRepository = class InstalledExtensionRepository extends BaseMongoRepository {
2
+ constructor(db, logger, options) {
3
+ super(InstalledExtensionModelFunc, db, logger, options);
4
+ if (!db) {
5
+ throw new Error('A database connection is required');
6
+ }
7
+ this.logger = logger.child({
8
+ className: 'InstalledExtensionRepository'
9
+ });
10
+ }
11
+ async findByOrgAndId(orgId, extensionSlug) {
12
+ try {
13
+ // Since we store extension as ObjectId, we need to look up by extension reference
14
+ // For now, we'll return null and let the service handle this differently
15
+ this.logger.info('findByOrgAndId called with extensionSlug, but we store extension ObjectIds', {
16
+ orgId,
17
+ extensionSlug
18
+ });
19
+ return null;
20
+ } catch (error) {
21
+ this.logger.error('Error in findByOrgAndId', {
22
+ error,
23
+ orgId,
24
+ extensionSlug
25
+ });
26
+ return null;
27
+ }
28
+ }
29
+ async findByOrgAndExtensionId(organizationId, extensionId) {
30
+ try {
31
+ // Convert organizationId string to ObjectId for organization field lookup
32
+ return await this.get({
33
+ organization: new mongoose.Types.ObjectId(organizationId),
34
+ extension: new mongoose.Types.ObjectId(extensionId)
35
+ });
36
+ } catch (error) {
37
+ this.logger.error('Error in findByOrgAndExtensionId', {
38
+ error,
39
+ organizationId,
40
+ extensionId
41
+ });
42
+ return null;
43
+ }
44
+ }
45
+ async countExtensions(filter) {
46
+ try {
47
+ const mongoQuery = {};
48
+ if (filter.orgId) {
49
+ // Convert orgId string to ObjectId for organization field lookup
50
+ mongoQuery.organization = new mongoose.Types.ObjectId(filter.orgId);
51
+ }
52
+ if (filter.status) {
53
+ mongoQuery.status = Array.isArray(filter.status) ? {
54
+ $in: filter.status
55
+ } : filter.status;
56
+ }
57
+ if (filter['lifecycle.registryStatus']) {
58
+ mongoQuery['lifecycle.registryStatus'] = Array.isArray(filter['lifecycle.registryStatus']) ? {
59
+ $in: filter['lifecycle.registryStatus']
60
+ } : filter['lifecycle.registryStatus'];
61
+ }
62
+ if (filter['lifecycle.isOrphaned'] !== undefined) {
63
+ mongoQuery['lifecycle.isOrphaned'] = filter['lifecycle.isOrphaned'];
64
+ }
65
+ if (filter['settings.effectiveEnabled'] !== undefined) {
66
+ mongoQuery['settings.effectiveEnabled'] = filter['settings.effectiveEnabled'];
67
+ }
68
+ if (filter.installedBy) {
69
+ mongoQuery.installedBy = filter.installedBy;
70
+ }
71
+ return await this.count(mongoQuery);
72
+ } catch (error) {
73
+ this.logger.error('Error in countExtensions', {
74
+ error,
75
+ filter
76
+ });
77
+ return 0;
78
+ }
79
+ }
80
+ /**
81
+ * Create a new installed extension record
82
+ */
83
+ async createExtension(input) {
84
+ try {
85
+ this.logger.trace('Creating installed extension with params (%j)', input);
86
+ const extensionData = {
87
+ ...input,
88
+ organization: new mongoose.Types.ObjectId(input.orgId),
89
+ // Convert orgId to ObjectId for organization field
90
+ extension: input.extensionId,
91
+ // Store ObjectId reference to extension registry
92
+ installedBy: new mongoose.Types.ObjectId(input.installedBy),
93
+ installedAt: new Date(),
94
+ status: 'installed',
95
+ lifecycle: {
96
+ registryStatus: 'active',
97
+ isOrphaned: false,
98
+ deprecationWarningShown: false,
99
+ autoUpdateBlocked: false,
100
+ lastRegistryCheck: new Date().toISOString()
101
+ },
102
+ policies: {
103
+ allowOrphanedExecution: false,
104
+ requireSecurityUpdates: true,
105
+ autoRemoveDeprecated: false,
106
+ deprecationGracePeriod: 30,
107
+ ...input.policies
108
+ },
109
+ settings: {
110
+ userEnabled: true,
111
+ systemEnabled: true,
112
+ effectiveEnabled: true,
113
+ userConfig: {},
114
+ systemConfig: {},
115
+ ...input.settings
116
+ },
117
+ runtime: {
118
+ activationState: 'enabled'
119
+ },
120
+ auditLog: [{
121
+ action: 'installed',
122
+ timestamp: new Date(),
123
+ user: new mongoose.Types.ObjectId(input.installedBy),
124
+ details: {
125
+ version: input.version,
126
+ source: 'manual'
127
+ }
128
+ }]
129
+ };
130
+ return await this.create(extensionData);
131
+ } catch (error) {
132
+ this.logger.error('Error creating installed extension', {
133
+ error,
134
+ input
135
+ });
136
+ throw error;
137
+ }
138
+ }
139
+ /**
140
+ * Update an existing installed extension
141
+ */
142
+ async updateExtension(orgId, extensionId, update) {
143
+ try {
144
+ const updateData = {
145
+ ...update,
146
+ lastUpdated: new Date(),
147
+ ...(update.lastUpdatedBy && {
148
+ lastUpdatedBy: new mongoose.Types.ObjectId(update.lastUpdatedBy)
149
+ })
150
+ };
151
+ return await this.update({
152
+ organization: new mongoose.Types.ObjectId(orgId),
153
+ extension: new mongoose.Types.ObjectId(extensionId)
154
+ }, {
155
+ $set: updateData
156
+ });
157
+ } catch (error) {
158
+ this.logger.error('Error updating installed extension', {
159
+ error,
160
+ orgId,
161
+ extensionId
162
+ });
163
+ throw error;
164
+ }
165
+ }
166
+ /**
167
+ * Find a specific installed extension by organization and extension ObjectIds
168
+ */
169
+ async findOne(orgId, extensionId) {
170
+ try {
171
+ return await this.get({
172
+ organization: new mongoose.Types.ObjectId(orgId),
173
+ extension: new mongoose.Types.ObjectId(extensionId)
174
+ });
175
+ } catch (error) {
176
+ this.logger.error('Error finding installed extension', {
177
+ error,
178
+ orgId,
179
+ extensionId
180
+ });
181
+ return null;
182
+ }
183
+ }
184
+ /**
185
+ * Find installed extensions with optional filtering
186
+ * Uses BaseMongoRepository getAll with population to ensure proper _id to id transformation
187
+ */
188
+ async findExtensions(query) {
189
+ try {
190
+ const mongoQuery = {};
191
+ // Handle organization-based queries (preferred)
192
+ if (query.orgId) {
193
+ mongoQuery.organization = new mongoose.Types.ObjectId(query.orgId);
194
+ }
195
+ // Support accountId as a fallback mapping to organization for backward compatibility
196
+ else if (query.accountId) {
197
+ mongoQuery.organization = new mongoose.Types.ObjectId(query.accountId);
198
+ }
199
+ // Skip extensionSlug filtering at repository level since we store extension as ObjectId
200
+ // The GraphQL field resolver will handle mapping extension ObjectId to extension details
201
+ if (query.status) {
202
+ mongoQuery.status = Array.isArray(query.status) ? {
203
+ $in: query.status
204
+ } : query.status;
205
+ }
206
+ if (query['lifecycle.registryStatus']) {
207
+ mongoQuery['lifecycle.registryStatus'] = Array.isArray(query['lifecycle.registryStatus']) ? {
208
+ $in: query['lifecycle.registryStatus']
209
+ } : query['lifecycle.registryStatus'];
210
+ }
211
+ if (query['lifecycle.isOrphaned'] !== undefined) {
212
+ mongoQuery['lifecycle.isOrphaned'] = query['lifecycle.isOrphaned'];
213
+ }
214
+ if (query['settings.effectiveEnabled'] !== undefined) {
215
+ mongoQuery['settings.effectiveEnabled'] = query['settings.effectiveEnabled'];
216
+ }
217
+ if (query.installedBy) {
218
+ mongoQuery.installedBy = query.installedBy;
219
+ }
220
+ // Use BaseMongoRepository getAll with population
221
+ // This ensures proper _id to id transformation through virtual fields
222
+ const extensions = await this.model.find(mongoQuery).exec();
223
+ return extensions.map(ext => ext.toJSON({
224
+ virtuals: true
225
+ }));
226
+ } catch (error) {
227
+ this.logger.error('Error finding installed extensions', {
228
+ error,
229
+ query
230
+ });
231
+ return [];
232
+ }
233
+ }
234
+ /**
235
+ * Delete an installed extension
236
+ */
237
+ async deleteExtension(orgId, extensionId) {
238
+ try {
239
+ return await this.delete({
240
+ organization: new mongoose.Types.ObjectId(orgId),
241
+ extension: new mongoose.Types.ObjectId(extensionId)
242
+ });
243
+ } catch (error) {
244
+ this.logger.error('Error deleting installed extension', {
245
+ error,
246
+ orgId,
247
+ extensionId
248
+ });
249
+ return false;
250
+ }
251
+ }
252
+ /**
253
+ * Get installed extensions joined with registry information
254
+ */
255
+ async findWithRegistryInfo(query) {
256
+ try {
257
+ const mongoQuery = {};
258
+ if (query.orgId) {
259
+ mongoQuery.organization = new mongoose.Types.ObjectId(query.orgId);
260
+ }
261
+ const pipeline = [{
262
+ $match: mongoQuery
263
+ }, {
264
+ $lookup: {
265
+ from: 'extensionregistry',
266
+ localField: 'extension',
267
+ foreignField: '_id',
268
+ as: 'registryInfo'
269
+ }
270
+ }, {
271
+ $unwind: {
272
+ path: '$registryInfo',
273
+ preserveNullAndEmptyArrays: true
274
+ }
275
+ }];
276
+ const extensions = await this.model.aggregate(pipeline);
277
+ return extensions;
278
+ } catch (error) {
279
+ this.logger.error('Error finding extensions with registry info', {
280
+ error,
281
+ query
282
+ });
283
+ return [];
284
+ }
285
+ }
286
+ /**
287
+ * Check if extension exists for organization
288
+ */
289
+ async exists(extensionId, orgId) {
290
+ try {
291
+ const query = orgId ? {
292
+ organization: new mongoose.Types.ObjectId(orgId),
293
+ extension: new mongoose.Types.ObjectId(extensionId)
294
+ } : {
295
+ extension: new mongoose.Types.ObjectId(extensionId)
296
+ };
297
+ const count = await this.count(query);
298
+ return count > 0;
299
+ } catch (error) {
300
+ this.logger.error('Error checking extension existence', {
301
+ error,
302
+ orgId,
303
+ extensionId
304
+ });
305
+ return false;
306
+ }
307
+ }
308
+ /**
309
+ * Bulk update multiple extensions
310
+ */
311
+ async bulkUpdateExtensions(tenantId, filter, update) {
312
+ try {
313
+ const mongoQuery = {
314
+ tenantId,
315
+ ...filter
316
+ };
317
+ const result = await this.model.updateMany(mongoQuery, {
318
+ $set: update
319
+ });
320
+ return result.modifiedCount;
321
+ } catch (error) {
322
+ this.logger.error('Error bulk updating extensions', {
323
+ error,
324
+ tenantId,
325
+ filter,
326
+ update
327
+ });
328
+ return 0;
329
+ }
330
+ }
331
+ /**
332
+ * Get extension dependency graph for a tenant
333
+ */
334
+ async getDependencyGraph(tenantId) {
335
+ try {
336
+ const extensions = await this.model.find({
337
+ tenantId
338
+ }).populate(DB_COLL_NAMES.ExtensionRegistries).exec();
339
+ const extensionObjects = extensions.map(ext => ext.toJSON({
340
+ virtuals: true
341
+ }));
342
+ const dependencies = extensionObjects.map(ext => ({
343
+ extensionId: ext.extension?.toString() || '',
344
+ dependsOn: ext.dependencies || [],
345
+ dependents: ext.dependents || []
346
+ }));
347
+ return {
348
+ extensions: extensionObjects,
349
+ dependencies
350
+ };
351
+ } catch (error) {
352
+ this.logger.error('Error getting dependency graph', {
353
+ error,
354
+ tenantId
355
+ });
356
+ return {
357
+ extensions: [],
358
+ dependencies: []
359
+ };
360
+ }
361
+ }
362
+ /**
363
+ * Count installed extensions matching query
364
+ */
365
+ async countByQuery(query) {
366
+ try {
367
+ const mongoQuery = {};
368
+ if (query.orgId) {
369
+ mongoQuery.organization = new mongoose.Types.ObjectId(query.orgId);
370
+ }
371
+ if (query.status) {
372
+ mongoQuery.status = Array.isArray(query.status) ? {
373
+ $in: query.status
374
+ } : query.status;
375
+ }
376
+ return await this.count(mongoQuery);
377
+ } catch (error) {
378
+ this.logger.error('Error counting extensions', {
379
+ error,
380
+ query
381
+ });
382
+ return 0;
383
+ }
384
+ }
385
+ /**
386
+ * Find extensions that need registry sync
387
+ */
388
+ async findStaleExtensions(tenantId, maxAge) {
389
+ try {
390
+ const staleDate = new Date(Date.now() - maxAge);
391
+ const extensions = await this.model.find({
392
+ tenantId,
393
+ 'lifecycle.lastRegistryCheck': {
394
+ $lt: staleDate.toISOString()
395
+ }
396
+ }).exec();
397
+ return extensions.map(ext => ext.toJSON({
398
+ virtuals: true
399
+ }));
400
+ } catch (error) {
401
+ this.logger.error('Error finding stale extensions', {
402
+ error,
403
+ tenantId,
404
+ maxAge
405
+ });
406
+ return [];
407
+ }
408
+ }
409
+ /**
410
+ * Update registry status for multiple extensions
411
+ */
412
+ async syncRegistryStatus(updates) {
413
+ try {
414
+ const bulkOps = updates.map(update => ({
415
+ updateOne: {
416
+ filter: {
417
+ tenantId: update.orgId,
418
+ extensionSlug: update.extensionId
419
+ },
420
+ update: {
421
+ $set: {
422
+ 'lifecycle.registryStatus': update.registryStatus,
423
+ 'lifecycle.isOrphaned': update.isOrphaned,
424
+ 'lifecycle.lastRegistryCheck': new Date().toISOString(),
425
+ ...(update.latestVersion && {
426
+ availableVersion: update.latestVersion
427
+ })
428
+ }
429
+ }
430
+ }
431
+ }));
432
+ await this.model.bulkWrite(bulkOps);
433
+ } catch (error) {
434
+ this.logger.error('Error syncing registry status', {
435
+ error,
436
+ updates
437
+ });
438
+ throw error;
439
+ }
440
+ }
441
+ };
442
+ InstalledExtensionRepository = __decorate([injectable(), __param(0, inject('MongoDBConnection')), __param(1, inject('Logger')), __param(2, inject('MongoOptions')), __param(2, optional()), __metadata("design:paramtypes", [mongoose.Connection, Object, Object])], InstalledExtensionRepository);export{InstalledExtensionRepository};//# sourceMappingURL=installed-extension-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installed-extension-repository.js","sources":["../../../src/store/repositories/installed-extension-repository.ts"],"sourcesContent":[null],"names":[],"mappings":"mWAiCU,IAAA,4BAA4B,qCAAkC,SAAY;AAe1E,EAAA,WAAA,CAAA,EAAA,EAAA,MAAA,EAAA,OACF,EAAA;IAeE,KAAA,CAAA,2BAAwB,EAAA,EAAA,EAAA,MAAA,EAAA,OAA4B,CAAA;AA+B1D,IAAA,IAAA,CAAA,EAAA,EAAA;;AAEG,IAAA;IACU,IAAA,CAAA,MAAA,GAAA,MACT,CAAK,KAAE,CAAA;AAwDX,MAAA,SAAA,EAAA;;AAEG,EAAA;QACU,oBACF,EAAA,aACP,EAAA;AAyBJ,IAAA,IAAA;;AAEG;AACU,MAAA,IAAA,CAAO,MAAM,CAAA,IAAE,CAAA;AAY5B,QAAA,KAAA;;;AAGG,MAAA,OAAA,IAAA;AACU,IAAA,CAAA,CAAA,OAAA,KAAc,EAAC;AAgD5B,MAAA,IAAA,CAAA,MAAA,CAAA,KAAA,CAAA,yBAAA,EAAA;;AAEG,QAAA,KAAA;AACU,QAAA;AAYb,OAAA,CAAA;;AAEG,IAAA;;AAmCH,EAAA,MAAA,uBAAA,CAAA,cAAA,EAAA,WAAA,EAAA;;AAEG;AACU,MAAA,OAAO,MAAA,IAAW,CAAE,GAAA,CAAA;AAgBjC,QAAA,YAAA,EAAA,IAAA,QAAA,CAAA,KAAA,CAAA,QAAA,CAAA,cAAA,CAAA;;AAEG,OAAA,CAAA;IACU,CAAA,CAAA,OAAA,KAAA,EAAA;AAeb,MAAA,IAAA,CAAA,MAAA,CAAA,KAAA,CAAA,kCAAA,EAAA;;AAEG,QAAA,cAAA;AACU,QAAA;AACT,OAAA,CAAA;aACA,IAAA;;;uBAGc,CAAE,MAAM,EAAE;AACvB,IAAA,IAAA;MACH,MAAA,UAAA,GAAA,EAAA;AAoBF,MAAA,IAAA,MAAA,CAAA,KAAA,EAAA;;AAEG,QAAA,UAAA,CAAA,YAAA,GAAA,IAAA,QAAA,CAAA,KAAA,CAAA,QAAA,CAAA,MAAA,CAAA,KAAA,CAAA;MACU;AAmBb,MAAA,IAAA,MAAA,CAAA,MAAA,EAAA;;AAEG,UAAA,GAAA,EAAA,MAAA,CAAA;AACU,SAAA,GAAA,MAAA,CAAA,MACT;AAmBJ,MAAA;;AAEG,QAAA,UAAA,CAAA,0BAAA,CAAA,GAAA,KAAA,CAAA,OAAA,CAAA,MAAA,CAAA,0BAAA,CAAA,CAAA,GAAA;AACU,UAAA,GAAA,EAAA,MAAA,CAAkB,0BACZ;SACX,GAAA,iCAAc,CAAA;;UAEd,MAAA,CAAA,sBAAuB,CAAA,KAAA,SAAA,EAAA;QACvB,UAAA,CAAA,sBAAuB,CAAA,GAAA,MAAA,CAAA,sBAAA,CAAA;;AAE1B,MAAC,IACH,MAAO,CAAC,2BAAK,CAAA,KAAA,SAAA,EAAA;AAyBnB,QAAA,UAAA,CAAA,2BAAA,CAAA,GAAA,MAAA,CAAA,2BAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=publisher-analytics-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publisher-analytics-repository.d.ts","sourceRoot":"","sources":["../../../src/store/repositories/publisher-analytics-repository.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import * as mongoose from 'mongoose';
2
+ import { CdmLogger } from '@cdm-logger/core';
3
+ import { BaseMongoRepository } from '@common-stack/store-mongo';
4
+ import { AsDomainType, IMarketplacePublisherRepository, IMarketplacePublisherModel } from 'common/server';
5
+ export declare class MarketplacePublisherRepository extends BaseMongoRepository<IMarketplacePublisherModel> implements IMarketplacePublisherRepository {
6
+ constructor(db: mongoose.Connection, logger: CdmLogger.ILogger, options?: unknown);
7
+ findByPublisherName(publisherName: string): Promise<AsDomainType<IMarketplacePublisherModel> | null>;
8
+ findPublishers(search?: string, orderBy?: string, orderDirection?: 'ASC' | 'DESC', limit?: number, offset?: number): Promise<{
9
+ publishers: AsDomainType<IMarketplacePublisherModel>[];
10
+ totalCount: number;
11
+ }>;
12
+ updatePublisherStats(publisherId: string, stats: {
13
+ extensionCount?: number;
14
+ totalInstalls?: number;
15
+ averageRating?: number;
16
+ }): Promise<AsDomainType<IMarketplacePublisherModel> | null>;
17
+ verifyPublisher(publisherId: string): Promise<AsDomainType<IMarketplacePublisherModel> | null>;
18
+ }
19
+ //# sourceMappingURL=publisher-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publisher-repository.d.ts","sourceRoot":"","sources":["../../../src/store/repositories/publisher-repository.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,+BAA+B,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAG1G,qBACa,8BACT,SAAQ,mBAAmB,CAAC,0BAA0B,CACtD,YAAW,+BAA+B;gBAGT,EAAE,EAAE,QAAQ,CAAC,UAAU,EAClC,MAAM,EAAE,SAAS,CAAC,OAAO,EACP,OAAO,CAAC,EAAE,OAAO;IAS5C,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC,GAAG,IAAI,CAAC;IAKpG,cAAc,CACvB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,SAAc,EACrB,cAAc,GAAE,KAAK,GAAG,MAAe,EACvC,KAAK,SAAK,EACV,MAAM,SAAI,GACX,OAAO,CAAC;QACP,UAAU,EAAE,YAAY,CAAC,0BAA0B,CAAC,EAAE,CAAC;QACvD,UAAU,EAAE,MAAM,CAAC;KACtB,CAAC;IA2CW,oBAAoB,CAC7B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,CAAC;KAC1B,GACF,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC,GAAG,IAAI,CAAC;IAkB9C,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC,GAAG,IAAI,CAAC;CAa9G"}
@@ -0,0 +1,87 @@
1
+ import {__decorate,__param,__metadata}from'tslib';import {injectable,inject,optional}from'inversify';import*as mongoose from'mongoose';import'@cdm-logger/core';import {BaseMongoRepository}from'@common-stack/store-mongo';import'../models/installed-extension-model.js';import {PublisherModelFunc}from'../models/publisher-model.js';var MarketplacePublisherRepository_1;
2
+ let MarketplacePublisherRepository = MarketplacePublisherRepository_1 = class MarketplacePublisherRepository extends BaseMongoRepository {
3
+ constructor(db, logger, options) {
4
+ super(PublisherModelFunc, db, logger, options);
5
+ if (!db) {
6
+ throw new Error('MongoDB connection is not provided');
7
+ }
8
+ this.logger = logger.child({
9
+ className: MarketplacePublisherRepository_1.name
10
+ });
11
+ }
12
+ async findByPublisherName(publisherName) {
13
+ this.logger.trace('findByPublisherName with publisherName [%s]', publisherName);
14
+ return this.model.findOne({
15
+ publisherName: publisherName.toLowerCase()
16
+ }).exec();
17
+ }
18
+ async findPublishers(search, orderBy = 'createdAt', orderDirection = 'DESC', limit = 20, offset = 0) {
19
+ this.logger.trace('findPublishers with limit [%d], offset [%d], search [%s]', limit, offset, search);
20
+ const query = this.model.find();
21
+ // Apply search filter
22
+ if (search && search.trim()) {
23
+ const searchRegex = new RegExp(search.trim(), 'i');
24
+ query.or([{
25
+ displayName: searchRegex
26
+ }, {
27
+ publisherName: searchRegex
28
+ }, {
29
+ description: searchRegex
30
+ }]);
31
+ }
32
+ // Get total count for pagination
33
+ const totalCount = await this.model.countDocuments(query.getQuery()).exec();
34
+ // Apply ordering
35
+ const sortDirection = orderDirection === 'ASC' ? 1 : -1;
36
+ let sortField;
37
+ if (orderBy === 'displayName') {
38
+ sortField = 'displayName';
39
+ } else if (orderBy === 'extensionCount') {
40
+ sortField = 'extensionCount';
41
+ } else if (orderBy === 'totalInstalls') {
42
+ sortField = 'totalInstalls';
43
+ } else if (orderBy === 'averageRating') {
44
+ sortField = 'averageRating';
45
+ } else {
46
+ sortField = 'createdAt';
47
+ }
48
+ query.sort({
49
+ [sortField]: sortDirection
50
+ });
51
+ // Apply pagination
52
+ query.skip(offset).limit(limit);
53
+ const publishers = await query.exec();
54
+ return {
55
+ publishers,
56
+ totalCount
57
+ };
58
+ }
59
+ async updatePublisherStats(publisherId, stats) {
60
+ this.logger.trace('updatePublisherStats for publisher [%s] with stats [%j]', publisherId, stats);
61
+ const updateData = {
62
+ updatedAt: new Date()
63
+ };
64
+ if (stats.extensionCount !== undefined) {
65
+ updateData.extensionCount = stats.extensionCount;
66
+ }
67
+ if (stats.totalInstalls !== undefined) {
68
+ updateData.totalInstalls = stats.totalInstalls;
69
+ }
70
+ if (stats.averageRating !== undefined) {
71
+ updateData.averageRating = Math.max(0, Math.min(5, stats.averageRating)); // Clamp between 0-5
72
+ }
73
+ return this.model.findByIdAndUpdate(publisherId, updateData, {
74
+ new: true
75
+ }).exec();
76
+ }
77
+ async verifyPublisher(publisherId) {
78
+ this.logger.trace('verifyPublisher with publisherId [%s]', publisherId);
79
+ return this.model.findByIdAndUpdate(publisherId, {
80
+ verified: true,
81
+ updatedAt: new Date()
82
+ }, {
83
+ new: true
84
+ }).exec();
85
+ }
86
+ };
87
+ MarketplacePublisherRepository = MarketplacePublisherRepository_1 = __decorate([injectable(), __param(0, inject('MongoDBConnection')), __param(1, inject('Logger')), __param(2, inject('MongoOptions')), __param(2, optional()), __metadata("design:paramtypes", [mongoose.Connection, Object, Object])], MarketplacePublisherRepository);export{MarketplacePublisherRepository};//# sourceMappingURL=publisher-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publisher-repository.js","sources":["../../../src/store/repositories/publisher-repository.ts"],"sourcesContent":[null],"names":[],"mappings":"yUACA,IAAA,gCAAoC;IA4BnB,8BACM,GACf,gCACc,SAAO,8BAErB,SAAM,mBACC,CAAA;AACP,EAAA,WAAA,CAAA,EAAA,EAAU,MAAE,EAAA,OAAa,EAAA;SACzB,CAAA,kBAAmB,EAAA,EAAA,EAAA,MAAA,EAAA,OAAA,CAAA;QACrB,CAAA,EAAA,EAAA;AA2CW,MAAA,MAAA,IAAA,KAAA,CAAA,oCAEF,CAAA;;QAEH,CAAA,MAAA,GAAA,MAAgB,CAAA,KAAM,CAAC;eACvB,EAAA,gCAAuB,CAAA;KAC1B,CAAA;AAmBQ,EAAA;AAahB,EAAA,MAAA,mBAAA,CAAA,aAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,5 @@
1
+ export const DB_COLL_NAMES = {
2
+ // from package: marketplace-server
3
+ InstalledExtensions: 'installed_extensions',
4
+ MarketplacePublisher: 'marketplace_publishers',
5
+ };
@@ -1,6 +1,12 @@
1
-
2
1
  export const SERVER_TYPES = {
3
- IExtensionMongoConnection: Symbol('ExtensionMongoConnection'),
4
- IRegistryExtensionService: Symbol('IRegistryExtensionService'),
5
- IRegistryExtensionRepository: Symbol('IRegistryExtensionRepository'),
2
+
3
+ IInstalledExtensionService: Symbol('IInstalledExtensionService'),
4
+ IInstalledExtensionRepository: Symbol('IInstalledExtensionRepository'),
5
+ IMarketplacePublisherService: Symbol('IMarketplacePublisherService'),
6
+ IMarketplacePublisherRepository: Symbol('IMarketplacePublisherRepository'),
7
+ IPublisherEventService: Symbol('IPublisherEventService'),
8
+ // Extension Gallery Services
9
+ IExtensionGalleryService: Symbol.for('IExtensionGalleryService'),
10
+ IExtensionGalleryRepository: Symbol.for('IExtensionGalleryRepository'),
11
+ ExtensionGalleryDataLoader: Symbol.for('ExtensionGalleryDataLoader'),
6
12
  };
@@ -0,0 +1,44 @@
1
+ // from package: marketplace-server
2
+ import { IGalleryExtension } from 'common/server';
3
+
4
+ /**
5
+ * Gallery query result interface for repository operations
6
+ */
7
+ export interface IGalleryQueryResult {
8
+ results: IGalleryExtension[];
9
+ total: number;
10
+ pageSize: number;
11
+ }
12
+
13
+ /**
14
+ * Extension asset interface
15
+ */
16
+ export interface IExtensionAsset {
17
+ uri: string;
18
+ fallbackUri?: string;
19
+ }
20
+
21
+ /**
22
+ * Repository interface for ExtensionGallery data access
23
+ */
24
+ export interface IExtensionGalleryRepository {
25
+ /**
26
+ * Get asset content for an extension
27
+ */
28
+ asset<T>(extensionSlug: string, version: string, asset: string): Promise<T>;
29
+
30
+ /**
31
+ * Get extensions by ID
32
+ */
33
+ get(id: string, fields: string[]): Promise<IGalleryExtension[]>;
34
+
35
+ /**
36
+ * Download an extension
37
+ */
38
+ download(extension: IGalleryExtension): Promise<boolean>;
39
+
40
+ /**
41
+ * Query extensions
42
+ */
43
+ query(query: Record<string, unknown>): Promise<IGalleryQueryResult>;
44
+ }