@adminide-stack/marketplace-module-server 12.0.4-alpha.92 → 13.0.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) 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 +16 -5
  5. package/lib/containers/module.js.map +1 -1
  6. package/lib/dataloaders/index.d.ts +2 -0
  7. package/lib/dataloaders/index.d.ts.map +1 -0
  8. package/lib/dataloaders/publisher-data-loader.d.ts +6 -0
  9. package/lib/dataloaders/publisher-data-loader.d.ts.map +1 -0
  10. package/lib/demo/test-graphql-examples.d.ts +73 -0
  11. package/lib/demo/test-graphql-examples.d.ts.map +1 -0
  12. package/lib/graphql/resolvers/form-templates-resolver.d.ts +220 -0
  13. package/lib/graphql/resolvers/form-templates-resolver.d.ts.map +1 -0
  14. package/lib/graphql/resolvers/form-templates-resolver.js +170 -0
  15. package/lib/graphql/resolvers/form-templates-resolver.js.map +1 -0
  16. package/lib/graphql/resolvers/gallery-resolver.d.ts +15 -0
  17. package/lib/graphql/resolvers/gallery-resolver.d.ts.map +1 -0
  18. package/lib/graphql/resolvers/gallery-resolver.js +35 -0
  19. package/lib/graphql/resolvers/gallery-resolver.js.map +1 -0
  20. package/lib/graphql/resolvers/index.d.ts +247 -1
  21. package/lib/graphql/resolvers/index.d.ts.map +1 -1
  22. package/lib/graphql/resolvers/index.js +1 -0
  23. package/lib/graphql/resolvers/index.js.map +1 -0
  24. package/lib/graphql/resolvers/installed-extension-resolver.d.ts +5 -0
  25. package/lib/graphql/resolvers/installed-extension-resolver.d.ts.map +1 -0
  26. package/lib/graphql/resolvers/installed-extension-resolver.js +309 -0
  27. package/lib/graphql/resolvers/installed-extension-resolver.js.map +1 -0
  28. package/lib/graphql/resolvers/marketplace-form-resolver.d.ts +13 -0
  29. package/lib/graphql/resolvers/marketplace-form-resolver.d.ts.map +1 -0
  30. package/lib/graphql/resolvers/marketplace-form-resolver.js +90 -0
  31. package/lib/graphql/resolvers/marketplace-form-resolver.js.map +1 -0
  32. package/lib/graphql/resolvers/publisher-analytics-resolver.d.ts +14 -0
  33. package/lib/graphql/resolvers/publisher-analytics-resolver.d.ts.map +1 -0
  34. package/lib/graphql/resolvers/publisher-analytics-resolver.js +221 -0
  35. package/lib/graphql/resolvers/publisher-analytics-resolver.js.map +1 -0
  36. package/lib/graphql/resolvers/publisher-resolver.d.ts +5 -0
  37. package/lib/graphql/resolvers/publisher-resolver.d.ts.map +1 -0
  38. package/lib/graphql/resolvers/publisher-resolver.js +183 -0
  39. package/lib/graphql/resolvers/publisher-resolver.js.map +1 -0
  40. package/lib/graphql/resolvers/registry-extension-resolver.d.ts +5 -0
  41. package/lib/graphql/resolvers/registry-extension-resolver.d.ts.map +1 -0
  42. package/lib/graphql/resolvers/registry-extension-resolver.js +46 -0
  43. package/lib/graphql/resolvers/registry-extension-resolver.js.map +1 -0
  44. package/lib/graphql/schemas/extension-pricing.graphql +546 -0
  45. package/lib/graphql/schemas/extension-pricing.graphql.js +1 -0
  46. package/lib/graphql/schemas/extension-pricing.graphql.js.map +1 -0
  47. package/lib/graphql/schemas/extension-registry.graphql +107 -0
  48. package/lib/graphql/schemas/extension-registry.graphql.js +1 -0
  49. package/lib/graphql/schemas/extension-registry.graphql.js.map +1 -0
  50. package/lib/graphql/schemas/form-templates.graphql +269 -0
  51. package/lib/graphql/schemas/form-templates.graphql.js +1 -0
  52. package/lib/graphql/schemas/form-templates.graphql.js.map +1 -0
  53. package/lib/graphql/schemas/gallery-schema.graphql +247 -0
  54. package/lib/graphql/schemas/gallery-schema.graphql.js +1 -0
  55. package/lib/graphql/schemas/gallery-schema.graphql.js.map +1 -0
  56. package/lib/graphql/schemas/index.d.ts.map +1 -1
  57. package/lib/graphql/schemas/index.js +3 -4
  58. package/lib/graphql/schemas/index.js.map +1 -1
  59. package/lib/graphql/schemas/installed-extension.graphql +324 -0
  60. package/lib/graphql/schemas/installed-extension.graphql.js +1 -0
  61. package/lib/graphql/schemas/installed-extension.graphql.js.map +1 -0
  62. package/lib/graphql/schemas/publisher-analytics.graphql +305 -0
  63. package/lib/graphql/schemas/publisher-analytics.graphql.js +1 -0
  64. package/lib/graphql/schemas/publisher-analytics.graphql.js.map +1 -0
  65. package/lib/graphql/schemas/publisher.graphql +584 -0
  66. package/lib/graphql/schemas/publisher.graphql.js +1 -0
  67. package/lib/graphql/schemas/publisher.graphql.js.map +1 -0
  68. package/lib/graphql/schemas/service.graphql +196 -0
  69. package/lib/index.d.ts +3 -1
  70. package/lib/index.d.ts.map +1 -1
  71. package/lib/index.js +1 -1
  72. package/lib/index.js.map +1 -1
  73. package/lib/migrations/dbMigrations/DropOldPublisherIndexMigration.d.ts +20 -0
  74. package/lib/migrations/dbMigrations/DropOldPublisherIndexMigration.d.ts.map +1 -0
  75. package/lib/migrations/dbMigrations/DropOldPublisherIndexMigration.js +61 -0
  76. package/lib/migrations/dbMigrations/DropOldPublisherIndexMigration.js.map +1 -0
  77. package/lib/migrations/index.d.ts +2 -0
  78. package/lib/migrations/index.d.ts.map +1 -0
  79. package/lib/module.d.ts +1 -1
  80. package/lib/module.d.ts.map +1 -1
  81. package/lib/module.js +12 -25
  82. package/lib/module.js.map +1 -1
  83. package/lib/plugins/extension-moleculer-service.d.ts +86 -0
  84. package/lib/plugins/extension-moleculer-service.d.ts.map +1 -0
  85. package/lib/plugins/index.d.ts +2 -0
  86. package/lib/plugins/index.d.ts.map +1 -0
  87. package/lib/services/extension-gallery-repository.d.ts +17 -0
  88. package/lib/services/extension-gallery-repository.d.ts.map +1 -0
  89. package/lib/services/extension-gallery-repository.js +192 -0
  90. package/lib/services/extension-gallery-repository.js.map +1 -0
  91. package/lib/services/extension-gallery-service-new.d.ts +39 -0
  92. package/lib/services/extension-gallery-service-new.d.ts.map +1 -0
  93. package/lib/services/extension-gallery-service.d.ts +30 -0
  94. package/lib/services/extension-gallery-service.d.ts.map +1 -0
  95. package/lib/services/extension-gallery-service.js +334 -0
  96. package/lib/services/extension-gallery-service.js.map +1 -0
  97. package/lib/services/index.d.ts +6 -1
  98. package/lib/services/index.d.ts.map +1 -1
  99. package/lib/services/installed-extension-service-ext.d.ts +16 -0
  100. package/lib/services/installed-extension-service-ext.d.ts.map +1 -0
  101. package/lib/services/installed-extension-service-ext.js +518 -0
  102. package/lib/services/installed-extension-service-ext.js.map +1 -0
  103. package/lib/services/installed-extension-service.d.ts +110 -0
  104. package/lib/services/installed-extension-service.d.ts.map +1 -0
  105. package/lib/services/installed-extension-service.js +633 -0
  106. package/lib/services/installed-extension-service.js.map +1 -0
  107. package/lib/services/installed-extension-service.test.d.ts +1 -0
  108. package/lib/services/installed-extension-service.test.d.ts.map +1 -0
  109. package/lib/services/publisher-analytics-service.d.ts +128 -0
  110. package/lib/services/publisher-analytics-service.d.ts.map +1 -0
  111. package/lib/services/publisher-event-service.d.ts +48 -0
  112. package/lib/services/publisher-event-service.d.ts.map +1 -0
  113. package/lib/services/publisher-event-service.js +296 -0
  114. package/lib/services/publisher-event-service.js.map +1 -0
  115. package/lib/services/publisher-service-context.d.ts +1 -0
  116. package/lib/services/publisher-service-context.d.ts.map +1 -0
  117. package/lib/services/publisher-service.d.ts +62 -0
  118. package/lib/services/publisher-service.d.ts.map +1 -0
  119. package/lib/services/publisher-service.js +135 -0
  120. package/lib/services/publisher-service.js.map +1 -0
  121. package/lib/store/index.d.ts +1 -1
  122. package/lib/store/index.d.ts.map +1 -1
  123. package/lib/store/models/index.d.ts +2 -1
  124. package/lib/store/models/index.d.ts.map +1 -1
  125. package/lib/store/models/installed-extension-model.d.ts +4 -0
  126. package/lib/store/models/installed-extension-model.d.ts.map +1 -0
  127. package/lib/store/models/installed-extension-model.js +269 -0
  128. package/lib/store/models/installed-extension-model.js.map +1 -0
  129. package/lib/store/models/publisher-event-model.d.ts +11 -0
  130. package/lib/store/models/publisher-event-model.d.ts.map +1 -0
  131. package/lib/store/models/publisher-model.d.ts +5 -0
  132. package/lib/store/models/publisher-model.d.ts.map +1 -0
  133. package/lib/store/models/publisher-model.js +117 -0
  134. package/lib/store/models/publisher-model.js.map +1 -0
  135. package/lib/store/models/publisher-stats-model.d.ts +1 -0
  136. package/lib/store/models/publisher-stats-model.d.ts.map +1 -0
  137. package/lib/store/repositories/index.d.ts +3 -0
  138. package/lib/store/repositories/index.d.ts.map +1 -0
  139. package/lib/store/repositories/installed-extension-repository.d.ts +77 -0
  140. package/lib/store/repositories/installed-extension-repository.d.ts.map +1 -0
  141. package/lib/store/repositories/installed-extension-repository.js +462 -0
  142. package/lib/store/repositories/installed-extension-repository.js.map +1 -0
  143. package/lib/store/repositories/publisher-analytics-repository.d.ts +1 -0
  144. package/lib/store/repositories/publisher-analytics-repository.d.ts.map +1 -0
  145. package/lib/store/repositories/publisher-repository.d.ts +19 -0
  146. package/lib/store/repositories/publisher-repository.d.ts.map +1 -0
  147. package/lib/store/repositories/publisher-repository.js +87 -0
  148. package/lib/store/repositories/publisher-repository.js.map +1 -0
  149. package/lib/templates/constants/DB_COLL_NAMES.ts.template +5 -0
  150. package/lib/templates/constants/SERVER_TYPES.ts.template +10 -4
  151. package/lib/templates/repositories/ExtensionGalleryRepository.ts.template +44 -0
  152. package/lib/templates/repositories/InstalledExtensionRepository.ts.template +99 -0
  153. package/lib/templates/repositories/MarketplacePublisherRepository.ts.template +24 -0
  154. package/lib/templates/repositories/RegistryExtensionRepository.ts.template +10 -15
  155. package/lib/templates/services/ExtensionGalleryDataLoader.ts.template +2 -0
  156. package/lib/templates/services/ExtensionGalleryService.ts.template +79 -0
  157. package/lib/templates/services/InstalledExtensionDataLoader.ts.template +2 -0
  158. package/lib/templates/services/InstalledExtensionService.ts.template +199 -0
  159. package/lib/templates/services/MarketplacePublisherService.ts.template +51 -0
  160. package/lib/templates/services/PublisherDataLoader.ts.template +3 -0
  161. package/lib/templates/services/PublisherEventService.ts.template +56 -0
  162. package/lib/templates/services/RegistryExtensionService.ts.template +62 -18
  163. package/lib/tests/extension-integration.test.d.ts +1 -0
  164. package/lib/tests/extension-integration.test.d.ts.map +1 -0
  165. package/lib/tests/install-extension-graphql.test.d.ts +2 -0
  166. package/lib/tests/install-extension-graphql.test.d.ts.map +1 -0
  167. package/lib/tests/test-extension-services.d.ts +1 -0
  168. package/lib/tests/test-extension-services.d.ts.map +1 -0
  169. package/lib/utils/publisherValidation.d.ts +23 -0
  170. package/lib/utils/publisherValidation.d.ts.map +1 -0
  171. package/lib/utils/publisherValidation.js +144 -0
  172. package/lib/utils/publisherValidation.js.map +1 -0
  173. package/package.json +16 -7
  174. package/lib/graphql/resolvers/resolvers.d.ts +0 -2
  175. package/lib/graphql/resolvers/resolvers.d.ts.map +0 -1
  176. package/lib/graphql/resolvers/resolvers.js +0 -167
  177. package/lib/graphql/resolvers/resolvers.js.map +0 -1
  178. package/lib/graphql/schemas/extension.graphql +0 -57
  179. package/lib/graphql/schemas/extension.graphql.js +0 -1
  180. package/lib/graphql/schemas/extension.graphql.js.map +0 -1
  181. package/lib/services/extension-service.d.ts +0 -54
  182. package/lib/services/extension-service.d.ts.map +0 -1
  183. package/lib/services/extension-service.js +0 -42
  184. package/lib/services/extension-service.js.map +0 -1
  185. package/lib/store/models/registry-extension-model.d.ts +0 -10
  186. package/lib/store/models/registry-extension-model.d.ts.map +0 -1
  187. package/lib/store/models/registry-extension-model.js +0 -62
  188. package/lib/store/models/registry-extension-model.js.map +0 -1
  189. package/lib/store/repository/index.d.ts +0 -2
  190. package/lib/store/repository/index.d.ts.map +0 -1
  191. package/lib/store/repository/registry-extension-repository.d.ts +0 -31
  192. package/lib/store/repository/registry-extension-repository.d.ts.map +0 -1
  193. package/lib/store/repository/registry-extension-repository.js +0 -135
  194. package/lib/store/repository/registry-extension-repository.js.map +0 -1
@@ -0,0 +1,633 @@
1
+ import {__decorate,__param,__metadata}from'tslib';import {injectable,inject}from'inversify';import'@cdm-logger/core';import {ServiceBroker}from'moleculer';import {CommonType}from'@common-stack/core';import {Emitter,DisposableCollection}from'@adminide-stack/core';import {BaseService2}from'@common-stack/store-mongo';import {SERVER_TYPES,DB_COLL_NAMES,ExtensionActivationState}from'common/server';var InstalledExtensionService_1;
2
+ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExtensionService extends BaseService2 {
3
+ installedExtensionRepository;
4
+ registryExtensionService;
5
+ slugService;
6
+ broker;
7
+ onExtensionInstalled = new Emitter();
8
+ onExtensionUninstalled = new Emitter();
9
+ onExtensionEnabled = new Emitter();
10
+ onExtensionDisabled = new Emitter();
11
+ onExtensionUpdated = new Emitter();
12
+ onExtensionVersionUpdated = new Emitter();
13
+ onExtensionConfigurationUpdated = new Emitter();
14
+ onExtensionSyncCompleted = new Emitter();
15
+ onExtensionCleanupCompleted = new Emitter();
16
+ onExtensionStatusChanged = new Emitter();
17
+ onExtensionActivationFailed = new Emitter();
18
+ onExtensionDeprecated = new Emitter();
19
+ onExtensionOrphaned = new Emitter();
20
+ toDispose = new DisposableCollection(this.onExtensionInstalled, this.onExtensionUninstalled, this.onExtensionEnabled, this.onExtensionDisabled, this.onExtensionUpdated, this.onExtensionVersionUpdated, this.onExtensionConfigurationUpdated, this.onExtensionSyncCompleted, this.onExtensionCleanupCompleted, this.onExtensionStatusChanged, this.onExtensionActivationFailed, this.onExtensionDeprecated, this.onExtensionOrphaned);
21
+ logger;
22
+ constructor(installedExtensionRepository, registryExtensionService, slugService, broker, logger) {
23
+ super(installedExtensionRepository);
24
+ this.installedExtensionRepository = installedExtensionRepository;
25
+ this.registryExtensionService = registryExtensionService;
26
+ this.slugService = slugService;
27
+ this.broker = broker;
28
+ this.logger = logger.child({
29
+ className: InstalledExtensionService_1.name
30
+ });
31
+ }
32
+ dispose() {
33
+ this.toDispose.dispose();
34
+ }
35
+ resolveExtensionSlug(extensionSlug) {
36
+ return this.slugService.resolveSlugWithProvider(DB_COLL_NAMES.ExtensionRegistries, 'extensionSlug', extensionSlug);
37
+ }
38
+ /**
39
+ * Install a new extension from the registry
40
+ */
41
+ async installExtension(input, tenantId) {
42
+ this.logger.debug('Installing extension [%s] for organization [%s] with input [%j]', input.extensionSlug, input.orgId, input);
43
+ if (!input.orgId) {
44
+ this.logger.error('Organization ID missing for extension installation [%s]', input.extensionSlug);
45
+ throw new Error('Organization ID (orgId) is required for extension installation');
46
+ }
47
+ this.logger.info('Installing extension [%s] for organization [%s]', input.extensionSlug, input.orgId);
48
+ // Check if extension already exists for this organization
49
+ this.logger.debug('Resolving extension slug [%s] to extension ID', input.extensionSlug);
50
+ const extensionId = await this.resolveExtensionSlug(input.extensionSlug);
51
+ this.logger.debug('Extension slug [%s] resolved to ID [%s]', input.extensionSlug, extensionId);
52
+ this.logger.debug('Checking if extension [%s] already exists for organization [%s]', extensionId, input.orgId);
53
+ const existing = await this.installedExtensionRepository.exists(input.orgId, extensionId);
54
+ if (existing) {
55
+ this.logger.warn('Extension [%s] already installed for organization [%s]', input.extensionSlug, input.orgId);
56
+ throw new Error(`Extension ${input.extensionSlug} is already installed for organization ${input.orgId}`);
57
+ }
58
+ // Get extension from registry to validate
59
+ this.logger.debug('Fetching extension [%s] from registry', input.extensionSlug);
60
+ const registryExtension = await this.registryExtensionService.findExtension(input.extensionSlug);
61
+ if (!registryExtension) {
62
+ this.logger.error('Extension [%s] not found in registry', input.extensionSlug);
63
+ throw new Error(`Extension ${input.extensionSlug} not found in registry`);
64
+ }
65
+ this.logger.debug('Registry extension found [%j]', {
66
+ id: registryExtension.id,
67
+ version: registryExtension.version,
68
+ name: registryExtension.name
69
+ });
70
+ // Delegate to the internal install method (validation already done)
71
+ this.logger.debug('Delegating to doInstallExtension for [%s]', input.extensionSlug);
72
+ return this.doInstallExtension(input, registryExtension, tenantId);
73
+ }
74
+ /**
75
+ * Internal method to perform the actual installation after validation
76
+ */
77
+ async doInstallExtension(input, registryExtension, tenantId) {
78
+ this.logger.debug('doInstallExtension input [%j]', input);
79
+ this.logger.debug('doInstallExtension registryExtension [%j]', {
80
+ id: registryExtension.id,
81
+ version: registryExtension.version,
82
+ name: registryExtension.name
83
+ });
84
+ const versionToUse = input.version || registryExtension.version;
85
+ this.logger.debug('Version resolution: input.version=[%s], registryExtension.version=[%s], using=[%s]', input.version, registryExtension.version, versionToUse);
86
+ // Create the installed extension record with proper defaults
87
+ const installedExtension = await this.installedExtensionRepository.create({
88
+ organization: input.orgId,
89
+ extensionSlug: input.extensionSlug,
90
+ extension: registryExtension.id,
91
+ version: versionToUse,
92
+ installedVersion: registryExtension.version,
93
+ installedBy: input.installedBy,
94
+ policies: {
95
+ allowOrphanedExecution: false,
96
+ requireSecurityUpdates: true,
97
+ autoRemoveDeprecated: false,
98
+ deprecationGracePeriod: 30,
99
+ ...input.policies
100
+ },
101
+ settings: {
102
+ userEnabled: true,
103
+ systemEnabled: true,
104
+ ...input.settings
105
+ }
106
+ });
107
+ // Fire installation event
108
+ const event = {
109
+ extensionSlug: input.extensionSlug,
110
+ installedBy: input.installedBy,
111
+ installedVersion: installedExtension.installedVersion,
112
+ registryRef: registryExtension.id,
113
+ installedAt: new Date().toISOString(),
114
+ policies: input.policies,
115
+ settings: input.settings,
116
+ orgId: input.orgId,
117
+ tenantId
118
+ };
119
+ this.onExtensionInstalled.fire(event);
120
+ this.logger.info(`Successfully installed extension ${input.extensionSlug}`);
121
+ return installedExtension;
122
+ }
123
+ /**
124
+ * Uninstall an extension
125
+ */
126
+ async uninstallExtension(orgId, extensionSlug, uninstalledBy, tenantId) {
127
+ this.logger.debug('Uninstalling extension [%s] for org [%s] by user [%s] with tenantId [%s]', extensionSlug, orgId, uninstalledBy, tenantId);
128
+ this.logger.info('Uninstalling extension [%s] in org [%s]', extensionSlug, orgId);
129
+ this.logger.debug('Resolving extension slug [%s] to extension ID', extensionSlug);
130
+ const extensionId = await this.resolveExtensionSlug(extensionSlug);
131
+ this.logger.debug('Extension slug [%s] resolved to ID [%s]', extensionSlug, extensionId);
132
+ if (!extensionId) {
133
+ this.logger.error('Failed to resolve extension slug [%s] - not found in registry', extensionSlug);
134
+ throw new Error(`Extension ${extensionSlug} not found in registry`);
135
+ }
136
+ let extension = null;
137
+ if (extensionId) {
138
+ this.logger.debug('Finding extension by org [%s] and extension ID [%s]', orgId, extensionId);
139
+ // Try to find by extension ID first
140
+ extension = await this.installedExtensionRepository.findByOrgAndExtensionId(orgId, extensionId);
141
+ this.logger.debug('Extension found by ID lookup: [%s]', !!extension);
142
+ }
143
+ // If not found by extension ID, try alternative methods
144
+ if (!extension) {
145
+ this.logger.debug('Extension not found by ID, trying alternative lookup methods');
146
+ // Instead of complex lookups, let's search all installed extensions
147
+ // and match by checking if the registry extension has the matching slug
148
+ const allInstalled = await this.getInstalledExtensions({
149
+ orgId
150
+ });
151
+ this.logger.debug('Found [%d] installed extensions for org [%s]', allInstalled.length, orgId);
152
+ // For each installed extension, check if it matches our slug
153
+ for (const installed of allInstalled) {
154
+ this.logger.debug('Checking installed extension [%j]', {
155
+ id: installed.id,
156
+ extensionId: installed.extension
157
+ });
158
+ // Since we can't easily look up registry by ID, let's try a different approach
159
+ // Use the slug service to find if this matches
160
+ try {
161
+ // Get the extension slug from the registry extension directly if possible
162
+ if (installed.extension) {
163
+ // Try to resolve the extension ID back to slug for comparison
164
+ const extensionIdString = String(installed.extension);
165
+ // Check if this extension ID matches what we'd expect for this slug
166
+ const resolvedExtensionId = await this.resolveExtensionSlug(extensionSlug);
167
+ this.logger.debug('Comparing extension IDs: installed [%s] vs resolved [%s]', extensionIdString, resolvedExtensionId);
168
+ if (resolvedExtensionId && resolvedExtensionId === extensionIdString) {
169
+ this.logger.debug('Found matching extension via alternative lookup');
170
+ extension = installed;
171
+ break;
172
+ }
173
+ }
174
+ } catch (error) {
175
+ this.logger.warn('Error in alternative lookup for extension [%s]: [%s]', installed.id, error.message);
176
+ }
177
+ }
178
+ }
179
+ if (!extension) {
180
+ this.logger.error('Extension [%s] not found in org [%s] after all lookup attempts', extensionSlug, orgId);
181
+ throw new Error(`Extension ${extensionSlug} not found in org ${orgId}`);
182
+ }
183
+ this.logger.debug('Found extension to uninstall [%j]', {
184
+ id: extension.id,
185
+ extensionId: extension.extension,
186
+ slug: extension.extensionSlug
187
+ });
188
+ // Use the extension ID from the found extension record
189
+ const actualExtensionId = String(extension.extension);
190
+ this.logger.debug('Using actual extension ID [%s] for uninstall operations', actualExtensionId);
191
+ // Check dependencies - prevent uninstalling if other extensions depend on this
192
+ this.logger.debug('Checking dependency graph for org [%s]', orgId);
193
+ const dependencyGraph = await this.installedExtensionRepository.getDependencyGraph(orgId);
194
+ const extensionDeps = dependencyGraph.dependencies.find(dep => dep.extensionId === actualExtensionId);
195
+ if (extensionDeps && extensionDeps.dependents.length > 0) {
196
+ this.logger.warn('Cannot uninstall extension [%s]: required by dependents [%j]', extensionSlug, extensionDeps.dependents);
197
+ throw new Error(`Cannot uninstall ${extensionSlug}: Required by ${extensionDeps.dependents.join(', ')}`);
198
+ }
199
+ // Delete the extension using the installed extension's ID
200
+ this.logger.debug('Attempting to delete extension [%s] from org [%s]', actualExtensionId, orgId);
201
+ const deleted = await this.installedExtensionRepository.deleteExtension(orgId, actualExtensionId);
202
+ this.logger.debug('Extension deletion result: [%s]', deleted);
203
+ if (deleted) {
204
+ this.logger.debug('Creating uninstall event for extension [%s]', extensionSlug);
205
+ // Fire uninstallation event
206
+ const event = {
207
+ extensionSlug,
208
+ orgId,
209
+ tenantId,
210
+ // Using accountId as tenantId for backward compatibility in events
211
+ uninstalledBy,
212
+ uninstalledAt: new Date().toISOString(),
213
+ wasEnabled: extension.settings?.userEnabled || false,
214
+ dependencies: extension.dependencies || []
215
+ };
216
+ this.logger.debug('Firing uninstall event [%j]', event);
217
+ this.onExtensionUninstalled.fire(event);
218
+ this.logger.info('Successfully uninstalled extension [%s] ([%s])', extensionSlug, actualExtensionId);
219
+ } else {
220
+ this.logger.error('Failed to delete extension [%s] from database', actualExtensionId);
221
+ }
222
+ return deleted;
223
+ }
224
+ /**
225
+ * Update an installed extension's configuration or status
226
+ */
227
+ async updateInstalledExtension(orgId, extensionSlug, update, tenantId) {
228
+ // For now, use orgId as tenantId for backward compatibility until repository is updated
229
+ this.logger.info(`Updating installed extension ${extensionSlug} for org ${orgId}`);
230
+ const extensionId = await this.resolveExtensionSlug(extensionSlug);
231
+ const updatedExtension = await this.installedExtensionRepository.updateExtension(orgId, extensionId, {
232
+ ...update,
233
+ lastUpdatedBy: update.lastUpdatedBy
234
+ });
235
+ if (!updatedExtension) {
236
+ throw new Error(`Extension ${extensionId} not found for org ${orgId}`);
237
+ }
238
+ // Fire update event if status changed
239
+ if (update.status || update.settings) {
240
+ const event = {
241
+ extensionSlug,
242
+ tenantId,
243
+ updatedBy: update.lastUpdatedBy || 'system',
244
+ updatedAt: new Date().toISOString(),
245
+ changes: update
246
+ };
247
+ this.onExtensionUpdated.fire(event);
248
+ }
249
+ return updatedExtension;
250
+ }
251
+ /**
252
+ * Get a specific installed extension
253
+ */
254
+ async getInstalledExtension(orgId, extensionSlug) {
255
+ // For now, use accountId as tenantId for backward compatibility until repository is updated
256
+ const extensionId = await this.resolveExtensionSlug(extensionSlug);
257
+ const result = await this.installedExtensionRepository.findByOrgAndExtensionId(orgId, extensionId);
258
+ return result ? result : null;
259
+ }
260
+ /**
261
+ * Get all installed extensions for a tenant with optional filtering
262
+ */
263
+ async getInstalledExtensions(filter) {
264
+ const results = await this.installedExtensionRepository.findExtensions(filter);
265
+ return results;
266
+ }
267
+ /**
268
+ * Get all installed extensions for a specific extension by extensionSlug
269
+ * Useful for finding all organizations that have installed a specific extension
270
+ */
271
+ async getInstalledExtensionsBySlug(extensionSlug) {
272
+ const extensionId = await this.resolveExtensionSlug(extensionSlug);
273
+ if (!extensionId) {
274
+ this.logger.warn({
275
+ extensionSlug
276
+ }, 'Extension not found in registry');
277
+ return [];
278
+ }
279
+ const results = await this.installedExtensionRepository.findByExtensionId(extensionId);
280
+ return results;
281
+ }
282
+ /**
283
+ * Enable/disable an installed extension
284
+ */
285
+ async toggleExtension(orgId, extensionSlug, enabled, toggledBy, tenantId) {
286
+ const activationState = enabled ? ExtensionActivationState.Enabled : ExtensionActivationState.DisabledByUser;
287
+ const updatedExtension = await this.updateInstalledExtension(orgId, extensionSlug, {
288
+ settings: {
289
+ userEnabled: enabled
290
+ },
291
+ runtime: {
292
+ activationState,
293
+ ...(enabled ? {
294
+ lastActivated: new Date()
295
+ } : {
296
+ lastDeactivated: new Date()
297
+ })
298
+ },
299
+ lastUpdatedBy: toggledBy
300
+ }, tenantId);
301
+ // Fire toggle event
302
+ const event = enabled ? {
303
+ extensionSlug,
304
+ tenantId,
305
+ enabledBy: toggledBy,
306
+ enabledAt: new Date().toISOString(),
307
+ previousState: updatedExtension.runtime.activationState
308
+ } : {
309
+ extensionSlug,
310
+ tenantId,
311
+ disabledBy: toggledBy,
312
+ disabledAt: new Date().toISOString(),
313
+ reason: 'user'
314
+ };
315
+ // Fire status change event
316
+ if (enabled) {
317
+ this.onExtensionEnabled.fire(event);
318
+ } else {
319
+ this.onExtensionDisabled.fire(event);
320
+ }
321
+ return updatedExtension;
322
+ }
323
+ /**
324
+ * Update extension settings/configuration
325
+ */
326
+ async updateExtensionSettings(orgId, extensionSlug, userConfig, updatedBy, tenantId) {
327
+ const updatedExtension = await this.updateInstalledExtension(orgId, extensionSlug, {
328
+ settings: {
329
+ userConfig
330
+ },
331
+ lastUpdatedBy: updatedBy
332
+ }, tenantId);
333
+ // Fire configuration update event
334
+ const event = {
335
+ extensionSlug,
336
+ tenantId,
337
+ updatedBy,
338
+ updatedAt: new Date().toISOString(),
339
+ configType: 'user',
340
+ newConfig: userConfig
341
+ // configurationChanges: userConfig,
342
+ // previousConfiguration: updatedExtension.settings.userConfig,
343
+ };
344
+ // Fire configuration update event
345
+ this.onExtensionConfigurationUpdated.fire(event);
346
+ return updatedExtension;
347
+ }
348
+ /**
349
+ * Check for extension updates and return available updates
350
+ */
351
+ async checkForUpdates(orgId, extensionSlug) {
352
+ const query = {
353
+ orgId
354
+ };
355
+ if (extensionSlug) {
356
+ const extensionId = await this.resolveExtensionSlug(extensionSlug);
357
+ query.extension = extensionId;
358
+ }
359
+ const installedExtensions = await this.installedExtensionRepository.findExtensions(query);
360
+ const updates = [];
361
+ for (const installed of installedExtensions) {
362
+ const registryExtension = await this.registryExtensionService.findExtension(installed.extension?.toString());
363
+ if (registryExtension && registryExtension.version !== installed.installedVersion) {
364
+ updates.push({
365
+ extensionId: installed.extension?.toString(),
366
+ extensionSlug,
367
+ currentVersion: installed.installedVersion,
368
+ availableVersion: registryExtension.version,
369
+ isSecurityUpdate: this.isSecurityUpdate(installed.installedVersion, registryExtension.version)
370
+ });
371
+ }
372
+ }
373
+ return updates;
374
+ }
375
+ /**
376
+ * Update an extension to a newer version
377
+ */
378
+ async updateExtensionVersion(orgId, extensionSlug, targetVersion, updatedBy, tenantId) {
379
+ const extension = await this.getInstalledExtension(orgId, extensionSlug);
380
+ if (!extension) {
381
+ throw new Error(`Extension ${extensionSlug} not found for organization ${orgId}`);
382
+ }
383
+ // Validate target version exists in registry
384
+ const registryExtension = await this.registryExtensionService.findExtension(extensionSlug);
385
+ if (!registryExtension) {
386
+ throw new Error(`Extension ${extensionSlug} not found in registry`);
387
+ }
388
+ const updatedExtension = await this.updateInstalledExtension(orgId, extensionSlug, {
389
+ lastUpdatedBy: updatedBy
390
+ // Note: Version update should be handled at the model level, not through update input
391
+ }, tenantId);
392
+ // Fire version update event
393
+ const event = {
394
+ extensionSlug,
395
+ updatedBy,
396
+ fromVersion: extension.installedVersion,
397
+ toVersion: targetVersion,
398
+ updatedAt: new Date().toISOString(),
399
+ isSecurityUpdate: this.isSecurityUpdate(extension.installedVersion, targetVersion),
400
+ tenantId
401
+ };
402
+ // Fire version update event
403
+ this.onExtensionVersionUpdated.fire(event);
404
+ return updatedExtension;
405
+ }
406
+ /**
407
+ * Sync installed extensions with registry status
408
+ */
409
+ async syncWithRegistry(orgId, tenantId) {
410
+ this.logger.info(`Syncing installed extensions with registry for organization ${orgId}`);
411
+ const installedExtensions = await this.installedExtensionRepository.findExtensions({
412
+ orgId
413
+ });
414
+ const syncUpdates = [];
415
+ for (const installed of installedExtensions) {
416
+ const registryExtension = await this.registryExtensionService.findExtension(installed.extension?.toString());
417
+ if (!registryExtension) {
418
+ // Extension removed from registry
419
+ syncUpdates.push({
420
+ orgId,
421
+ extensionId: installed.extension?.toString(),
422
+ registryStatus: 'removed',
423
+ isOrphaned: true
424
+ });
425
+ } else {
426
+ syncUpdates.push({
427
+ extensionId: installed.extension?.toString(),
428
+ registryStatus: registryExtension.status || 'active',
429
+ latestVersion: registryExtension.version,
430
+ isOrphaned: false,
431
+ orgId
432
+ });
433
+ }
434
+ }
435
+ // For now, map to old format for repository compatibility
436
+ const repoCompatibleUpdates = syncUpdates.map(update => ({
437
+ orgId: update.orgId,
438
+ // Use orgId as tenantId for backward compatibility
439
+ extensionId: update.extensionId,
440
+ registryStatus: update.registryStatus,
441
+ latestVersion: update.latestVersion,
442
+ isOrphaned: update.isOrphaned
443
+ }));
444
+ await this.installedExtensionRepository.syncRegistryStatus(repoCompatibleUpdates);
445
+ // Fire sync completion event
446
+ const orphanedUpdates = syncUpdates.filter(u => u.isOrphaned);
447
+ syncUpdates.filter(u => u.registryStatus === 'deprecated');
448
+ const versionsUpdates = syncUpdates.filter(u => u.latestVersion);
449
+ const event = {
450
+ syncedAt: new Date().toISOString(),
451
+ extensionsChecked: syncUpdates.length,
452
+ // syncedExtensions: versionsUpdates.length,
453
+ extensionsOrphaned: orphanedUpdates.length,
454
+ extensionsUpdated: versionsUpdates.length,
455
+ tenantId,
456
+ errors: []
457
+ // orphanedExtensions: orphanedUpdates.map((u) => u.extensionId),
458
+ // deprecatedExtensions: deprecatedUpdates.map((u) => u.extensionId),
459
+ // updatedExtensions: versionsUpdates.map((u) => u.extensionId),
460
+ };
461
+ // Fire sync completed event
462
+ this.onExtensionSyncCompleted.fire(event);
463
+ this.logger.info(`Synced ${syncUpdates.length} extensions with registry`);
464
+ }
465
+ /**
466
+ * Get extensions that need attention
467
+ */
468
+ async getExtensionsNeedingAttention(orgId) {
469
+ const extensions = await this.getInstalledExtensions({
470
+ orgId
471
+ });
472
+ const filtered = extensions.filter(ext => {
473
+ // Check for conditions that need attention
474
+ const isOrphaned = ext.lifecycle?.isOrphaned;
475
+ const isDeprecated = ext.lifecycle?.registryStatus === 'deprecated';
476
+ const hasUpdates = ext.availableVersion && ext.availableVersion !== ext.installedVersion;
477
+ return isOrphaned || isDeprecated || hasUpdates;
478
+ });
479
+ return filtered;
480
+ }
481
+ /**
482
+ * Clean up deprecated or removed extensions based on policies
483
+ */
484
+ async cleanupExtensions(orgId, tenantId, dryRun) {
485
+ // For now, use accountId as tenantId for backward compatibility until repository is updated
486
+ const result = {
487
+ removed: [],
488
+ deprecated: [],
489
+ warnings: []
490
+ };
491
+ const extensions = await this.installedExtensionRepository.findExtensions({
492
+ orgId
493
+ });
494
+ for (const extension of extensions) {
495
+ const gracePeriodExpired = extension.policies.deprecationGracePeriod > 0 && extension.lifecycle.lastRegistryCheck && Date.now() - new Date(extension.lifecycle.lastRegistryCheck).getTime() > extension.policies.deprecationGracePeriod * 24 * 60 * 60 * 1000;
496
+ // Remove orphaned extensions
497
+ if (extension.lifecycle.isOrphaned && !extension.policies.allowOrphanedExecution) {
498
+ if (!dryRun) {
499
+ await this.uninstallExtension(orgId, extension.extension?.toString(), 'system-cleanup', tenantId);
500
+ }
501
+ result.removed.push(extension.extension?.toString());
502
+ }
503
+ // Remove deprecated extensions if auto-remove is enabled and grace period expired
504
+ else if (extension.lifecycle.registryStatus === 'deprecated' && extension.policies.autoRemoveDeprecated && gracePeriodExpired) {
505
+ if (!dryRun) {
506
+ await this.uninstallExtension(orgId, extension.extension?.toString(), 'system-cleanup', tenantId);
507
+ }
508
+ result.deprecated.push(extension.extension?.toString());
509
+ }
510
+ // Add warnings for extensions that need attention
511
+ else if (extension.lifecycle.registryStatus === 'deprecated' || extension.lifecycle.isOrphaned) {
512
+ result.warnings.push(extension.extension?.toString());
513
+ }
514
+ }
515
+ // Fire cleanup completion event
516
+ const event = {
517
+ tenantId,
518
+ cleanedAt: new Date().toISOString(),
519
+ // cleanupAt: new Date().toISOString(),
520
+ warnings: result.warnings,
521
+ dryRun: false,
522
+ extensionsDeprecated: result.deprecated,
523
+ extensionsRemoved: result.removed
524
+ };
525
+ // Fire cleanup completed event
526
+ this.onExtensionCleanupCompleted.fire(event);
527
+ return result;
528
+ }
529
+ /**
530
+ * Sync installed_extensions with system_extension registry
531
+ * Removes extensions from installed_extensions and configuration_registries
532
+ * if they are not present in system_extension registry
533
+ */
534
+ async cleanupOrphanedExtensions(orgId, tenantId, dryRun) {
535
+ const result = {
536
+ removed: [],
537
+ warnings: []
538
+ };
539
+ console.log('šŸ” SYNC: Starting extension registry sync...');
540
+ console.log(` OrgId: ${orgId}, TenantId: ${tenantId}, DryRun: ${dryRun}`);
541
+ // Get all installed extensions
542
+ const extensions = await this.installedExtensionRepository.findExtensions({
543
+ orgId
544
+ });
545
+ console.log(` Found ${extensions.length} installed extensions`);
546
+ // Get system_extension document
547
+ const systemExtensionDoc = await this.broker.call('ConfigurationRegistryService.getConfigurationNodeRegistry', {
548
+ context: {
549
+ schemaId: 'configuration',
550
+ tenantId,
551
+ extensionName: 'system_extension'
552
+ }
553
+ });
554
+ // Get list of extensions in system_extension
555
+ const systemExtensionSlugs = new Set();
556
+ if (systemExtensionDoc && typeof systemExtensionDoc === 'object' && 'configurationNodes' in systemExtensionDoc) {
557
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
558
+ const configNodes = systemExtensionDoc.configurationNodes || [];
559
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
560
+ const settingsNode = configNodes.find(node => node.id === 'settings');
561
+ if (settingsNode?.properties) {
562
+ Object.keys(settingsNode.properties).forEach(key => {
563
+ if (key.startsWith('extensions.')) {
564
+ const slug = key.replace('extensions.', '');
565
+ systemExtensionSlugs.add(slug);
566
+ }
567
+ });
568
+ }
569
+ }
570
+ console.log(` Found ${systemExtensionSlugs.size} extensions in system_extension registry`);
571
+ console.log(` System extensions:`, Array.from(systemExtensionSlugs));
572
+ // Check each installed extension
573
+ for (const extension of extensions) {
574
+ const extensionId = String(extension.extension);
575
+ // Get the registry extension to find its slug
576
+ let extensionSlug = null;
577
+ try {
578
+ const registryExtension = await this.registryExtensionService.get(extensionId);
579
+ if (registryExtension) {
580
+ extensionSlug = registryExtension.extensionSlug || extensionId;
581
+ }
582
+ } catch (error) {
583
+ this.logger.warn(`Failed to fetch registry extension ${extensionId}:`, error);
584
+ }
585
+ if (!extensionSlug) {
586
+ console.log(`āš ļø Could not determine slug for extension ID: ${extensionId}`);
587
+ result.warnings.push(`Could not determine slug for extension ID: ${extensionId}`);
588
+ } else if (!systemExtensionSlugs.has(extensionSlug)) {
589
+ // If extension is in installed_extensions but NOT in system_extension, it's orphaned
590
+ const orphanMsg = `āš ļø Found orphaned installed_extension: ${extensionSlug} (ID: ${extensionId}) (not in system_extension)`;
591
+ console.log(orphanMsg);
592
+ if (!dryRun) {
593
+ try {
594
+ // Remove from installed_extensions
595
+ await this.installedExtensionRepository.deleteExtension(orgId, extensionId);
596
+ console.log(` āœ… Deleted from installed_extensions: ${extensionSlug}`);
597
+ // Remove uiLayout configuration from configuration_registries
598
+ await this.broker.call('ConfigurationRegistryService.removeConfigurationNodeRegistry', {
599
+ context: {
600
+ schemaId: 'uiLayout',
601
+ tenantId,
602
+ extensionName: extensionSlug
603
+ }
604
+ });
605
+ console.log(` āœ… Deleted uiLayout config: ${extensionSlug}`);
606
+ result.removed.push(extensionSlug);
607
+ } catch (cleanupError) {
608
+ console.error(` āŒ Failed to cleanup ${extensionSlug}:`, cleanupError);
609
+ result.warnings.push(`Failed to cleanup ${extensionSlug}: ${cleanupError.message}`);
610
+ }
611
+ } else {
612
+ console.log(` [DRY RUN] Would remove: ${extensionSlug}`);
613
+ result.removed.push(extensionSlug);
614
+ }
615
+ } else {
616
+ console.log(`āœ… Extension ${extensionSlug} is registered in system_extension`);
617
+ }
618
+ }
619
+ console.log('\nāœ… SYNC COMPLETE');
620
+ console.log(` Removed: ${result.removed.length} extensions`);
621
+ console.log(` Warnings: ${result.warnings.length} items`);
622
+ return result;
623
+ }
624
+ /**
625
+ * Check if update is a security update (simplified logic)
626
+ */
627
+ isSecurityUpdate(_currentVersion, _targetVersion) {
628
+ // Simple heuristic - in a real implementation, this would check
629
+ // security advisories or version metadata
630
+ return false;
631
+ }
632
+ };
633
+ InstalledExtensionService = InstalledExtensionService_1 = __decorate([injectable(), __param(0, inject(SERVER_TYPES.IInstalledExtensionRepository)), __param(1, inject(SERVER_TYPES.IRegistryExtensionService)), __param(2, inject(SERVER_TYPES.SlugService)), __param(3, inject(CommonType.MOLECULER_BROKER)), __param(4, inject(CommonType.LOGGER)), __metadata("design:paramtypes", [Object, Object, Object, ServiceBroker, Object])], InstalledExtensionService);export{InstalledExtensionService};//# sourceMappingURL=installed-extension-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installed-extension-service.js","sources":["../../src/services/installed-extension-service.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=installed-extension-service.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installed-extension-service.test.d.ts","sourceRoot":"","sources":["../../src/services/installed-extension-service.test.ts"],"names":[],"mappings":""}