@adminide-stack/marketplace-module-server 12.0.4-alpha.95 ā 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.
- package/lib/containers/module.d.ts +4 -4
- package/lib/containers/module.d.ts.map +1 -1
- package/lib/containers/module.js +12 -7
- package/lib/containers/module.js.map +1 -1
- package/lib/dataloaders/index.d.ts +1 -1
- package/lib/dataloaders/index.d.ts.map +1 -1
- package/lib/dataloaders/publisher-data-loader.d.ts +6 -0
- package/lib/dataloaders/publisher-data-loader.d.ts.map +1 -0
- package/lib/demo/test-graphql-examples.d.ts +73 -0
- package/lib/demo/test-graphql-examples.d.ts.map +1 -0
- package/lib/graphql/resolvers/form-templates-resolver.d.ts +220 -0
- package/lib/graphql/resolvers/form-templates-resolver.d.ts.map +1 -0
- package/lib/graphql/resolvers/form-templates-resolver.js +170 -0
- package/lib/graphql/resolvers/form-templates-resolver.js.map +1 -0
- package/lib/graphql/resolvers/gallery-resolver.d.ts +15 -0
- package/lib/graphql/resolvers/gallery-resolver.d.ts.map +1 -0
- package/lib/graphql/resolvers/gallery-resolver.js +35 -0
- package/lib/graphql/resolvers/gallery-resolver.js.map +1 -0
- package/lib/graphql/resolvers/index.d.ts +247 -1
- package/lib/graphql/resolvers/index.d.ts.map +1 -1
- package/lib/graphql/resolvers/index.js +1 -1
- package/lib/graphql/resolvers/installed-extension-resolver.d.ts.map +1 -1
- package/lib/graphql/resolvers/installed-extension-resolver.js +161 -35
- package/lib/graphql/resolvers/installed-extension-resolver.js.map +1 -1
- package/lib/graphql/resolvers/marketplace-form-resolver.d.ts +13 -0
- package/lib/graphql/resolvers/marketplace-form-resolver.d.ts.map +1 -0
- package/lib/graphql/resolvers/marketplace-form-resolver.js +90 -0
- package/lib/graphql/resolvers/marketplace-form-resolver.js.map +1 -0
- package/lib/graphql/resolvers/publisher-analytics-resolver.d.ts +14 -0
- package/lib/graphql/resolvers/publisher-analytics-resolver.d.ts.map +1 -0
- package/lib/graphql/resolvers/publisher-analytics-resolver.js +221 -0
- package/lib/graphql/resolvers/publisher-analytics-resolver.js.map +1 -0
- package/lib/graphql/resolvers/publisher-resolver.d.ts +5 -0
- package/lib/graphql/resolvers/publisher-resolver.d.ts.map +1 -0
- package/lib/graphql/resolvers/publisher-resolver.js +183 -0
- package/lib/graphql/resolvers/publisher-resolver.js.map +1 -0
- package/lib/graphql/resolvers/registry-extension-resolver.d.ts.map +1 -1
- package/lib/graphql/resolvers/registry-extension-resolver.js +34 -167
- package/lib/graphql/resolvers/registry-extension-resolver.js.map +1 -1
- package/lib/graphql/schemas/extension-pricing.graphql +546 -0
- package/lib/graphql/schemas/extension-pricing.graphql.js +1 -0
- package/lib/graphql/schemas/extension-pricing.graphql.js.map +1 -0
- package/lib/graphql/schemas/extension-registry.graphql +91 -58
- package/lib/graphql/schemas/extension-registry.graphql.js +1 -1
- package/lib/graphql/schemas/form-templates.graphql +269 -0
- package/lib/graphql/schemas/form-templates.graphql.js +1 -0
- package/lib/graphql/schemas/form-templates.graphql.js.map +1 -0
- package/lib/graphql/schemas/gallery-schema.graphql +247 -0
- package/lib/graphql/schemas/gallery-schema.graphql.js +1 -0
- package/lib/graphql/schemas/gallery-schema.graphql.js.map +1 -0
- package/lib/graphql/schemas/index.d.ts.map +1 -1
- package/lib/graphql/schemas/index.js +3 -1
- package/lib/graphql/schemas/index.js.map +1 -1
- package/lib/graphql/schemas/installed-extension.graphql +37 -7
- package/lib/graphql/schemas/installed-extension.graphql.js +1 -1
- package/lib/graphql/schemas/publisher-analytics.graphql +305 -0
- package/lib/graphql/schemas/publisher-analytics.graphql.js +1 -0
- package/lib/graphql/schemas/publisher-analytics.graphql.js.map +1 -0
- package/lib/graphql/schemas/publisher.graphql +584 -0
- package/lib/graphql/schemas/publisher.graphql.js +1 -0
- package/lib/graphql/schemas/publisher.graphql.js.map +1 -0
- package/lib/graphql/schemas/service.graphql +15 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/migrations/dbMigrations/DropOldPublisherIndexMigration.d.ts +20 -0
- package/lib/migrations/dbMigrations/DropOldPublisherIndexMigration.d.ts.map +1 -0
- package/lib/migrations/dbMigrations/DropOldPublisherIndexMigration.js +61 -0
- package/lib/migrations/dbMigrations/DropOldPublisherIndexMigration.js.map +1 -0
- package/lib/migrations/index.d.ts +2 -0
- package/lib/migrations/index.d.ts.map +1 -0
- package/lib/module.d.ts +1 -1
- package/lib/module.d.ts.map +1 -1
- package/lib/module.js +11 -26
- package/lib/module.js.map +1 -1
- package/lib/services/extension-gallery-repository.d.ts +17 -0
- package/lib/services/extension-gallery-repository.d.ts.map +1 -0
- package/lib/services/extension-gallery-repository.js +192 -0
- package/lib/services/extension-gallery-repository.js.map +1 -0
- package/lib/services/extension-gallery-service-new.d.ts +39 -0
- package/lib/services/extension-gallery-service-new.d.ts.map +1 -0
- package/lib/services/extension-gallery-service.d.ts +30 -0
- package/lib/services/extension-gallery-service.d.ts.map +1 -0
- package/lib/services/extension-gallery-service.js +334 -0
- package/lib/services/extension-gallery-service.js.map +1 -0
- package/lib/services/index.d.ts +4 -1
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/installed-extension-service-ext.d.ts +5 -2
- package/lib/services/installed-extension-service-ext.d.ts.map +1 -1
- package/lib/services/installed-extension-service-ext.js +364 -117
- package/lib/services/installed-extension-service-ext.js.map +1 -1
- package/lib/services/installed-extension-service.d.ts +30 -13
- package/lib/services/installed-extension-service.d.ts.map +1 -1
- package/lib/services/installed-extension-service.js +301 -68
- package/lib/services/installed-extension-service.js.map +1 -1
- package/lib/services/installed-extension-service.test.d.ts +0 -1
- package/lib/services/publisher-analytics-service.d.ts +128 -0
- package/lib/services/publisher-analytics-service.d.ts.map +1 -0
- package/lib/services/publisher-event-service.d.ts +48 -0
- package/lib/services/publisher-event-service.d.ts.map +1 -0
- package/lib/services/publisher-event-service.js +296 -0
- package/lib/services/publisher-event-service.js.map +1 -0
- package/lib/services/publisher-service-context.d.ts +1 -0
- package/lib/services/publisher-service-context.d.ts.map +1 -0
- package/lib/services/publisher-service.d.ts +62 -0
- package/lib/services/publisher-service.d.ts.map +1 -0
- package/lib/services/publisher-service.js +135 -0
- package/lib/services/publisher-service.js.map +1 -0
- package/lib/store/models/index.d.ts +1 -1
- package/lib/store/models/index.d.ts.map +1 -1
- package/lib/store/models/installed-extension-model.d.ts.map +1 -1
- package/lib/store/models/installed-extension-model.js +17 -45
- package/lib/store/models/installed-extension-model.js.map +1 -1
- package/lib/store/models/publisher-event-model.d.ts +11 -0
- package/lib/store/models/publisher-event-model.d.ts.map +1 -0
- package/lib/store/models/publisher-model.d.ts +5 -0
- package/lib/store/models/publisher-model.d.ts.map +1 -0
- package/lib/store/models/publisher-model.js +117 -0
- package/lib/store/models/publisher-model.js.map +1 -0
- package/lib/store/models/publisher-stats-model.d.ts +1 -0
- package/lib/store/models/publisher-stats-model.d.ts.map +1 -0
- package/lib/store/repositories/index.d.ts +1 -1
- package/lib/store/repositories/index.d.ts.map +1 -1
- package/lib/store/repositories/installed-extension-repository.d.ts +17 -11
- package/lib/store/repositories/installed-extension-repository.d.ts.map +1 -1
- package/lib/store/repositories/installed-extension-repository.js +123 -75
- package/lib/store/repositories/installed-extension-repository.js.map +1 -1
- package/lib/store/repositories/publisher-analytics-repository.d.ts +1 -0
- package/lib/store/repositories/publisher-analytics-repository.d.ts.map +1 -0
- package/lib/store/repositories/publisher-repository.d.ts +19 -0
- package/lib/store/repositories/publisher-repository.d.ts.map +1 -0
- package/lib/store/repositories/publisher-repository.js +87 -0
- package/lib/store/repositories/publisher-repository.js.map +1 -0
- package/lib/templates/constants/DB_COLL_NAMES.ts.template +1 -1
- package/lib/templates/constants/SERVER_TYPES.ts.template +8 -5
- package/lib/templates/repositories/ExtensionGalleryRepository.ts.template +44 -0
- package/lib/templates/repositories/InstalledExtensionRepository.ts.template +19 -14
- package/lib/templates/repositories/MarketplacePublisherRepository.ts.template +24 -0
- package/lib/templates/repositories/RegistryExtensionRepository.ts.template +2 -2
- package/lib/templates/services/ExtensionGalleryDataLoader.ts.template +2 -0
- package/lib/templates/services/ExtensionGalleryService.ts.template +79 -0
- package/lib/templates/services/InstalledExtensionService.ts.template +63 -32
- package/lib/templates/services/MarketplacePublisherService.ts.template +51 -0
- package/lib/templates/services/PublisherDataLoader.ts.template +3 -0
- package/lib/templates/services/PublisherEventService.ts.template +56 -0
- package/lib/templates/services/RegistryExtensionService.ts.template +46 -2
- package/lib/tests/extension-integration.test.d.ts +0 -1
- package/lib/tests/install-extension-graphql.test.d.ts +2 -0
- package/lib/tests/install-extension-graphql.test.d.ts.map +1 -0
- package/lib/utils/publisherValidation.d.ts +23 -0
- package/lib/utils/publisherValidation.d.ts.map +1 -0
- package/lib/utils/publisherValidation.js +144 -0
- package/lib/utils/publisherValidation.js.map +1 -0
- package/package.json +13 -9
- package/lib/constants/extension-events.d.ts +0 -136
- package/lib/constants/extension-events.d.ts.map +0 -1
- package/lib/dataloaders/registry-extension-data-loader.d.ts +0 -6
- package/lib/dataloaders/registry-extension-data-loader.d.ts.map +0 -1
- package/lib/dataloaders/registry-extension-data-loader.js +0 -6
- package/lib/dataloaders/registry-extension-data-loader.js.map +0 -1
- package/lib/graphql/schemas/service.graphql.js +0 -1
- package/lib/graphql/schemas/service.graphql.js.map +0 -1
- package/lib/services/extension-service.d.ts +0 -42
- package/lib/services/extension-service.d.ts.map +0 -1
- package/lib/services/extension-service.js +0 -60
- package/lib/services/extension-service.js.map +0 -1
- package/lib/store/models/registry-extension-model.d.ts +0 -5
- package/lib/store/models/registry-extension-model.d.ts.map +0 -1
- package/lib/store/models/registry-extension-model.js +0 -83
- package/lib/store/models/registry-extension-model.js.map +0 -1
- package/lib/store/repositories/registry-extension-repository.d.ts +0 -54
- package/lib/store/repositories/registry-extension-repository.d.ts.map +0 -1
- package/lib/store/repositories/registry-extension-repository.js +0 -137
- package/lib/store/repositories/registry-extension-repository.js.map +0 -1
- package/lib/templates/services/RegistryExtensionDataLoader.ts.template +0 -2
|
@@ -1,7 +1,8 @@
|
|
|
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 {
|
|
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
2
|
let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExtensionService extends BaseService2 {
|
|
3
3
|
installedExtensionRepository;
|
|
4
4
|
registryExtensionService;
|
|
5
|
+
slugService;
|
|
5
6
|
broker;
|
|
6
7
|
onExtensionInstalled = new Emitter();
|
|
7
8
|
onExtensionUninstalled = new Emitter();
|
|
@@ -18,10 +19,11 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
18
19
|
onExtensionOrphaned = new Emitter();
|
|
19
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);
|
|
20
21
|
logger;
|
|
21
|
-
constructor(installedExtensionRepository, registryExtensionService, broker, logger) {
|
|
22
|
+
constructor(installedExtensionRepository, registryExtensionService, slugService, broker, logger) {
|
|
22
23
|
super(installedExtensionRepository);
|
|
23
24
|
this.installedExtensionRepository = installedExtensionRepository;
|
|
24
25
|
this.registryExtensionService = registryExtensionService;
|
|
26
|
+
this.slugService = slugService;
|
|
25
27
|
this.broker = broker;
|
|
26
28
|
this.logger = logger.child({
|
|
27
29
|
className: InstalledExtensionService_1.name
|
|
@@ -30,34 +32,63 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
30
32
|
dispose() {
|
|
31
33
|
this.toDispose.dispose();
|
|
32
34
|
}
|
|
35
|
+
resolveExtensionSlug(extensionSlug) {
|
|
36
|
+
return this.slugService.resolveSlugWithProvider(DB_COLL_NAMES.ExtensionRegistries, 'extensionSlug', extensionSlug);
|
|
37
|
+
}
|
|
33
38
|
/**
|
|
34
39
|
* Install a new extension from the registry
|
|
35
40
|
*/
|
|
36
|
-
async installExtension(input) {
|
|
37
|
-
this.logger.
|
|
38
|
-
|
|
39
|
-
|
|
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);
|
|
40
54
|
if (existing) {
|
|
41
|
-
|
|
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}`);
|
|
42
57
|
}
|
|
43
58
|
// Get extension from registry to validate
|
|
59
|
+
this.logger.debug('Fetching extension [%s] from registry', input.extensionSlug);
|
|
44
60
|
const registryExtension = await this.registryExtensionService.findExtension(input.extensionSlug);
|
|
45
61
|
if (!registryExtension) {
|
|
62
|
+
this.logger.error('Extension [%s] not found in registry', input.extensionSlug);
|
|
46
63
|
throw new Error(`Extension ${input.extensionSlug} not found in registry`);
|
|
47
64
|
}
|
|
65
|
+
this.logger.debug('Registry extension found [%j]', {
|
|
66
|
+
id: registryExtension.id,
|
|
67
|
+
version: registryExtension.version,
|
|
68
|
+
name: registryExtension.name
|
|
69
|
+
});
|
|
48
70
|
// Delegate to the internal install method (validation already done)
|
|
49
|
-
|
|
71
|
+
this.logger.debug('Delegating to doInstallExtension for [%s]', input.extensionSlug);
|
|
72
|
+
return this.doInstallExtension(input, registryExtension, tenantId);
|
|
50
73
|
}
|
|
51
74
|
/**
|
|
52
75
|
* Internal method to perform the actual installation after validation
|
|
53
76
|
*/
|
|
54
|
-
async doInstallExtension(input, registryExtension) {
|
|
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);
|
|
55
86
|
// Create the installed extension record with proper defaults
|
|
56
87
|
const installedExtension = await this.installedExtensionRepository.create({
|
|
57
|
-
|
|
88
|
+
organization: input.orgId,
|
|
58
89
|
extensionSlug: input.extensionSlug,
|
|
59
90
|
extension: registryExtension.id,
|
|
60
|
-
version:
|
|
91
|
+
version: versionToUse,
|
|
61
92
|
installedVersion: registryExtension.version,
|
|
62
93
|
installedBy: input.installedBy,
|
|
63
94
|
policies: {
|
|
@@ -76,13 +107,14 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
76
107
|
// Fire installation event
|
|
77
108
|
const event = {
|
|
78
109
|
extensionSlug: input.extensionSlug,
|
|
79
|
-
tenantId: input.tenantId,
|
|
80
110
|
installedBy: input.installedBy,
|
|
81
111
|
installedVersion: installedExtension.installedVersion,
|
|
82
112
|
registryRef: registryExtension.id,
|
|
83
113
|
installedAt: new Date().toISOString(),
|
|
84
114
|
policies: input.policies,
|
|
85
|
-
settings: input.settings
|
|
115
|
+
settings: input.settings,
|
|
116
|
+
orgId: input.orgId,
|
|
117
|
+
tenantId
|
|
86
118
|
};
|
|
87
119
|
this.onExtensionInstalled.fire(event);
|
|
88
120
|
this.logger.info(`Successfully installed extension ${input.extensionSlug}`);
|
|
@@ -91,46 +123,117 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
91
123
|
/**
|
|
92
124
|
* Uninstall an extension
|
|
93
125
|
*/
|
|
94
|
-
async uninstallExtension(
|
|
95
|
-
this.logger.
|
|
96
|
-
|
|
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
|
|
97
144
|
if (!extension) {
|
|
98
|
-
|
|
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
|
+
}
|
|
99
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);
|
|
100
191
|
// Check dependencies - prevent uninstalling if other extensions depend on this
|
|
101
|
-
|
|
102
|
-
const
|
|
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);
|
|
103
195
|
if (extensionDeps && extensionDeps.dependents.length > 0) {
|
|
196
|
+
this.logger.warn('Cannot uninstall extension [%s]: required by dependents [%j]', extensionSlug, extensionDeps.dependents);
|
|
104
197
|
throw new Error(`Cannot uninstall ${extensionSlug}: Required by ${extensionDeps.dependents.join(', ')}`);
|
|
105
198
|
}
|
|
106
|
-
// Delete the extension
|
|
107
|
-
|
|
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);
|
|
108
203
|
if (deleted) {
|
|
204
|
+
this.logger.debug('Creating uninstall event for extension [%s]', extensionSlug);
|
|
109
205
|
// Fire uninstallation event
|
|
110
206
|
const event = {
|
|
111
207
|
extensionSlug,
|
|
208
|
+
orgId,
|
|
112
209
|
tenantId,
|
|
210
|
+
// Using accountId as tenantId for backward compatibility in events
|
|
113
211
|
uninstalledBy,
|
|
114
212
|
uninstalledAt: new Date().toISOString(),
|
|
115
213
|
wasEnabled: extension.settings?.userEnabled || false,
|
|
116
214
|
dependencies: extension.dependencies || []
|
|
117
215
|
};
|
|
216
|
+
this.logger.debug('Firing uninstall event [%j]', event);
|
|
118
217
|
this.onExtensionUninstalled.fire(event);
|
|
119
|
-
this.logger.info(
|
|
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);
|
|
120
221
|
}
|
|
121
222
|
return deleted;
|
|
122
223
|
}
|
|
123
224
|
/**
|
|
124
225
|
* Update an installed extension's configuration or status
|
|
125
226
|
*/
|
|
126
|
-
async updateInstalledExtension(
|
|
127
|
-
|
|
128
|
-
|
|
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, {
|
|
129
232
|
...update,
|
|
130
233
|
lastUpdatedBy: update.lastUpdatedBy
|
|
131
234
|
});
|
|
132
235
|
if (!updatedExtension) {
|
|
133
|
-
throw new Error(`Extension ${
|
|
236
|
+
throw new Error(`Extension ${extensionId} not found for org ${orgId}`);
|
|
134
237
|
}
|
|
135
238
|
// Fire update event if status changed
|
|
136
239
|
if (update.status || update.settings) {
|
|
@@ -148,8 +251,10 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
148
251
|
/**
|
|
149
252
|
* Get a specific installed extension
|
|
150
253
|
*/
|
|
151
|
-
async getInstalledExtension(
|
|
152
|
-
|
|
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);
|
|
153
258
|
return result ? result : null;
|
|
154
259
|
}
|
|
155
260
|
/**
|
|
@@ -159,12 +264,27 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
159
264
|
const results = await this.installedExtensionRepository.findExtensions(filter);
|
|
160
265
|
return results;
|
|
161
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
|
+
}
|
|
162
282
|
/**
|
|
163
283
|
* Enable/disable an installed extension
|
|
164
284
|
*/
|
|
165
|
-
async toggleExtension(
|
|
285
|
+
async toggleExtension(orgId, extensionSlug, enabled, toggledBy, tenantId) {
|
|
166
286
|
const activationState = enabled ? ExtensionActivationState.Enabled : ExtensionActivationState.DisabledByUser;
|
|
167
|
-
const updatedExtension = await this.updateInstalledExtension(
|
|
287
|
+
const updatedExtension = await this.updateInstalledExtension(orgId, extensionSlug, {
|
|
168
288
|
settings: {
|
|
169
289
|
userEnabled: enabled
|
|
170
290
|
},
|
|
@@ -177,7 +297,7 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
177
297
|
})
|
|
178
298
|
},
|
|
179
299
|
lastUpdatedBy: toggledBy
|
|
180
|
-
});
|
|
300
|
+
}, tenantId);
|
|
181
301
|
// Fire toggle event
|
|
182
302
|
const event = enabled ? {
|
|
183
303
|
extensionSlug,
|
|
@@ -203,13 +323,13 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
203
323
|
/**
|
|
204
324
|
* Update extension settings/configuration
|
|
205
325
|
*/
|
|
206
|
-
async updateExtensionSettings(
|
|
207
|
-
const updatedExtension = await this.updateInstalledExtension(
|
|
326
|
+
async updateExtensionSettings(orgId, extensionSlug, userConfig, updatedBy, tenantId) {
|
|
327
|
+
const updatedExtension = await this.updateInstalledExtension(orgId, extensionSlug, {
|
|
208
328
|
settings: {
|
|
209
329
|
userConfig
|
|
210
330
|
},
|
|
211
331
|
lastUpdatedBy: updatedBy
|
|
212
|
-
});
|
|
332
|
+
}, tenantId);
|
|
213
333
|
// Fire configuration update event
|
|
214
334
|
const event = {
|
|
215
335
|
extensionSlug,
|
|
@@ -217,8 +337,9 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
217
337
|
updatedBy,
|
|
218
338
|
updatedAt: new Date().toISOString(),
|
|
219
339
|
configType: 'user',
|
|
220
|
-
newConfig: userConfig
|
|
221
|
-
|
|
340
|
+
newConfig: userConfig
|
|
341
|
+
// configurationChanges: userConfig,
|
|
342
|
+
// previousConfiguration: updatedExtension.settings.userConfig,
|
|
222
343
|
};
|
|
223
344
|
// Fire configuration update event
|
|
224
345
|
this.onExtensionConfigurationUpdated.fire(event);
|
|
@@ -227,12 +348,13 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
227
348
|
/**
|
|
228
349
|
* Check for extension updates and return available updates
|
|
229
350
|
*/
|
|
230
|
-
async checkForUpdates(
|
|
351
|
+
async checkForUpdates(orgId, extensionSlug) {
|
|
231
352
|
const query = {
|
|
232
|
-
|
|
353
|
+
orgId
|
|
233
354
|
};
|
|
234
355
|
if (extensionSlug) {
|
|
235
|
-
|
|
356
|
+
const extensionId = await this.resolveExtensionSlug(extensionSlug);
|
|
357
|
+
query.extension = extensionId;
|
|
236
358
|
}
|
|
237
359
|
const installedExtensions = await this.installedExtensionRepository.findExtensions(query);
|
|
238
360
|
const updates = [];
|
|
@@ -240,7 +362,8 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
240
362
|
const registryExtension = await this.registryExtensionService.findExtension(installed.extension?.toString());
|
|
241
363
|
if (registryExtension && registryExtension.version !== installed.installedVersion) {
|
|
242
364
|
updates.push({
|
|
243
|
-
|
|
365
|
+
extensionId: installed.extension?.toString(),
|
|
366
|
+
extensionSlug,
|
|
244
367
|
currentVersion: installed.installedVersion,
|
|
245
368
|
availableVersion: registryExtension.version,
|
|
246
369
|
isSecurityUpdate: this.isSecurityUpdate(installed.installedVersion, registryExtension.version)
|
|
@@ -252,29 +375,29 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
252
375
|
/**
|
|
253
376
|
* Update an extension to a newer version
|
|
254
377
|
*/
|
|
255
|
-
async updateExtensionVersion(
|
|
256
|
-
const extension = await this.getInstalledExtension(
|
|
378
|
+
async updateExtensionVersion(orgId, extensionSlug, targetVersion, updatedBy, tenantId) {
|
|
379
|
+
const extension = await this.getInstalledExtension(orgId, extensionSlug);
|
|
257
380
|
if (!extension) {
|
|
258
|
-
throw new Error(`Extension ${extensionSlug} not found for
|
|
381
|
+
throw new Error(`Extension ${extensionSlug} not found for organization ${orgId}`);
|
|
259
382
|
}
|
|
260
383
|
// Validate target version exists in registry
|
|
261
384
|
const registryExtension = await this.registryExtensionService.findExtension(extensionSlug);
|
|
262
385
|
if (!registryExtension) {
|
|
263
386
|
throw new Error(`Extension ${extensionSlug} not found in registry`);
|
|
264
387
|
}
|
|
265
|
-
const updatedExtension = await this.updateInstalledExtension(
|
|
388
|
+
const updatedExtension = await this.updateInstalledExtension(orgId, extensionSlug, {
|
|
266
389
|
lastUpdatedBy: updatedBy
|
|
267
390
|
// Note: Version update should be handled at the model level, not through update input
|
|
268
|
-
});
|
|
391
|
+
}, tenantId);
|
|
269
392
|
// Fire version update event
|
|
270
393
|
const event = {
|
|
271
394
|
extensionSlug,
|
|
272
|
-
tenantId,
|
|
273
395
|
updatedBy,
|
|
274
396
|
fromVersion: extension.installedVersion,
|
|
275
397
|
toVersion: targetVersion,
|
|
276
398
|
updatedAt: new Date().toISOString(),
|
|
277
|
-
isSecurityUpdate: this.isSecurityUpdate(extension.installedVersion, targetVersion)
|
|
399
|
+
isSecurityUpdate: this.isSecurityUpdate(extension.installedVersion, targetVersion),
|
|
400
|
+
tenantId
|
|
278
401
|
};
|
|
279
402
|
// Fire version update event
|
|
280
403
|
this.onExtensionVersionUpdated.fire(event);
|
|
@@ -283,10 +406,10 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
283
406
|
/**
|
|
284
407
|
* Sync installed extensions with registry status
|
|
285
408
|
*/
|
|
286
|
-
async syncWithRegistry(tenantId) {
|
|
287
|
-
this.logger.info(`Syncing installed extensions with registry for
|
|
409
|
+
async syncWithRegistry(orgId, tenantId) {
|
|
410
|
+
this.logger.info(`Syncing installed extensions with registry for organization ${orgId}`);
|
|
288
411
|
const installedExtensions = await this.installedExtensionRepository.findExtensions({
|
|
289
|
-
|
|
412
|
+
orgId
|
|
290
413
|
});
|
|
291
414
|
const syncUpdates = [];
|
|
292
415
|
for (const installed of installedExtensions) {
|
|
@@ -294,33 +417,46 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
294
417
|
if (!registryExtension) {
|
|
295
418
|
// Extension removed from registry
|
|
296
419
|
syncUpdates.push({
|
|
297
|
-
|
|
298
|
-
|
|
420
|
+
orgId,
|
|
421
|
+
extensionId: installed.extension?.toString(),
|
|
299
422
|
registryStatus: 'removed',
|
|
300
423
|
isOrphaned: true
|
|
301
424
|
});
|
|
302
425
|
} else {
|
|
303
426
|
syncUpdates.push({
|
|
304
|
-
|
|
305
|
-
extensionSlug: installed.extension?.toString(),
|
|
427
|
+
extensionId: installed.extension?.toString(),
|
|
306
428
|
registryStatus: registryExtension.status || 'active',
|
|
307
429
|
latestVersion: registryExtension.version,
|
|
308
|
-
isOrphaned: false
|
|
430
|
+
isOrphaned: false,
|
|
431
|
+
orgId
|
|
309
432
|
});
|
|
310
433
|
}
|
|
311
434
|
}
|
|
312
|
-
|
|
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);
|
|
313
445
|
// Fire sync completion event
|
|
314
446
|
const orphanedUpdates = syncUpdates.filter(u => u.isOrphaned);
|
|
315
447
|
syncUpdates.filter(u => u.registryStatus === 'deprecated');
|
|
316
448
|
const versionsUpdates = syncUpdates.filter(u => u.latestVersion);
|
|
317
449
|
const event = {
|
|
318
|
-
tenantId,
|
|
319
450
|
syncedAt: new Date().toISOString(),
|
|
320
451
|
extensionsChecked: syncUpdates.length,
|
|
452
|
+
// syncedExtensions: versionsUpdates.length,
|
|
321
453
|
extensionsOrphaned: orphanedUpdates.length,
|
|
322
454
|
extensionsUpdated: versionsUpdates.length,
|
|
323
|
-
|
|
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),
|
|
324
460
|
};
|
|
325
461
|
// Fire sync completed event
|
|
326
462
|
this.onExtensionSyncCompleted.fire(event);
|
|
@@ -329,9 +465,9 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
329
465
|
/**
|
|
330
466
|
* Get extensions that need attention
|
|
331
467
|
*/
|
|
332
|
-
async getExtensionsNeedingAttention(
|
|
468
|
+
async getExtensionsNeedingAttention(orgId) {
|
|
333
469
|
const extensions = await this.getInstalledExtensions({
|
|
334
|
-
|
|
470
|
+
orgId
|
|
335
471
|
});
|
|
336
472
|
const filtered = extensions.filter(ext => {
|
|
337
473
|
// Check for conditions that need attention
|
|
@@ -345,28 +481,29 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
345
481
|
/**
|
|
346
482
|
* Clean up deprecated or removed extensions based on policies
|
|
347
483
|
*/
|
|
348
|
-
async cleanupExtensions(tenantId, dryRun
|
|
484
|
+
async cleanupExtensions(orgId, tenantId, dryRun) {
|
|
485
|
+
// For now, use accountId as tenantId for backward compatibility until repository is updated
|
|
349
486
|
const result = {
|
|
350
487
|
removed: [],
|
|
351
488
|
deprecated: [],
|
|
352
489
|
warnings: []
|
|
353
490
|
};
|
|
354
491
|
const extensions = await this.installedExtensionRepository.findExtensions({
|
|
355
|
-
|
|
492
|
+
orgId
|
|
356
493
|
});
|
|
357
494
|
for (const extension of extensions) {
|
|
358
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;
|
|
359
496
|
// Remove orphaned extensions
|
|
360
497
|
if (extension.lifecycle.isOrphaned && !extension.policies.allowOrphanedExecution) {
|
|
361
498
|
if (!dryRun) {
|
|
362
|
-
await this.uninstallExtension(
|
|
499
|
+
await this.uninstallExtension(orgId, extension.extension?.toString(), 'system-cleanup', tenantId);
|
|
363
500
|
}
|
|
364
501
|
result.removed.push(extension.extension?.toString());
|
|
365
502
|
}
|
|
366
503
|
// Remove deprecated extensions if auto-remove is enabled and grace period expired
|
|
367
504
|
else if (extension.lifecycle.registryStatus === 'deprecated' && extension.policies.autoRemoveDeprecated && gracePeriodExpired) {
|
|
368
505
|
if (!dryRun) {
|
|
369
|
-
await this.uninstallExtension(
|
|
506
|
+
await this.uninstallExtension(orgId, extension.extension?.toString(), 'system-cleanup', tenantId);
|
|
370
507
|
}
|
|
371
508
|
result.deprecated.push(extension.extension?.toString());
|
|
372
509
|
}
|
|
@@ -379,15 +516,111 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
379
516
|
const event = {
|
|
380
517
|
tenantId,
|
|
381
518
|
cleanedAt: new Date().toISOString(),
|
|
382
|
-
|
|
383
|
-
extensionsDeprecated: result.deprecated,
|
|
519
|
+
// cleanupAt: new Date().toISOString(),
|
|
384
520
|
warnings: result.warnings,
|
|
385
|
-
dryRun:
|
|
521
|
+
dryRun: false,
|
|
522
|
+
extensionsDeprecated: result.deprecated,
|
|
523
|
+
extensionsRemoved: result.removed
|
|
386
524
|
};
|
|
387
525
|
// Fire cleanup completed event
|
|
388
526
|
this.onExtensionCleanupCompleted.fire(event);
|
|
389
527
|
return result;
|
|
390
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
|
+
}
|
|
391
624
|
/**
|
|
392
625
|
* Check if update is a security update (simplified logic)
|
|
393
626
|
*/
|
|
@@ -397,4 +630,4 @@ let InstalledExtensionService = InstalledExtensionService_1 = class InstalledExt
|
|
|
397
630
|
return false;
|
|
398
631
|
}
|
|
399
632
|
};
|
|
400
|
-
InstalledExtensionService = InstalledExtensionService_1 = __decorate([injectable(), __param(0, inject(SERVER_TYPES.IInstalledExtensionRepository)), __param(1, inject(SERVER_TYPES.IRegistryExtensionService)), __param(2, inject(CommonType.MOLECULER_BROKER)), __param(
|
|
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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installed-extension-service.js","sources":["../../src/services/installed-extension-service.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"installed-extension-service.js","sources":["../../src/services/installed-extension-service.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|