@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,10 +1,61 @@
|
|
|
1
|
-
import {__decorate,__param,__metadata}from'tslib';import {injectable,inject}from'inversify';import {ServiceBroker}from'moleculer';import {CommonType}from'@common-stack/core';import'@cdm-logger/core';import {SERVER_TYPES,ConfigurationSchemaId,
|
|
1
|
+
import {__decorate,__param,__metadata}from'tslib';import {injectable,inject}from'inversify';import {ServiceBroker}from'moleculer';import {CommonType}from'@common-stack/core';import'@cdm-logger/core';import {SERVER_TYPES,ContributionFragmentName,ConfigurationSchemaId,SystemContributionExtensionNames,ExtensionServiceAction,MoleculerServiceName}from'common/server';import {InstalledExtensionService}from'./installed-extension-service.js';/**
|
|
2
|
+
* Convert scope string values from package.json to ConfigurationScope enum numbers
|
|
3
|
+
* Maps: "application" -> 1, "machine" -> 2, "window" -> 3, "resource" -> 4
|
|
4
|
+
*/
|
|
5
|
+
function convertScopeStringToNumber(scope) {
|
|
6
|
+
if (typeof scope === 'number') {
|
|
7
|
+
return scope; // Already a number
|
|
8
|
+
}
|
|
9
|
+
if (typeof scope === 'string') {
|
|
10
|
+
const scopeMap = {
|
|
11
|
+
application: 1 /* ConfigurationScope.APPLICATION */,
|
|
12
|
+
machine: 2 /* ConfigurationScope.MACHINE */,
|
|
13
|
+
window: 3 /* ConfigurationScope.WINDOW */,
|
|
14
|
+
resource: 4 /* ConfigurationScope.RESOURCE */
|
|
15
|
+
};
|
|
16
|
+
const normalizedScope = scope.toLowerCase();
|
|
17
|
+
if (normalizedScope in scopeMap) {
|
|
18
|
+
return scopeMap[normalizedScope];
|
|
19
|
+
}
|
|
20
|
+
console.warn(`Unknown scope string: "${scope}", defaulting to WINDOW`);
|
|
21
|
+
}
|
|
22
|
+
// Default to WINDOW scope if undefined or unknown
|
|
23
|
+
return 3 /* ConfigurationScope.WINDOW */;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Recursively process configuration properties to convert scope strings to numbers
|
|
27
|
+
*/
|
|
28
|
+
function processConfigurationProperties(properties) {
|
|
29
|
+
if (!properties || typeof properties !== 'object') {
|
|
30
|
+
return properties;
|
|
31
|
+
}
|
|
32
|
+
const processedProperties = {
|
|
33
|
+
...properties
|
|
34
|
+
};
|
|
35
|
+
for (const [key, value] of Object.entries(processedProperties)) {
|
|
36
|
+
if (value && typeof value === 'object') {
|
|
37
|
+
const objectValue = value;
|
|
38
|
+
// If this property has a scope, convert it
|
|
39
|
+
if ('scope' in objectValue) {
|
|
40
|
+
objectValue.scope = convertScopeStringToNumber(objectValue.scope);
|
|
41
|
+
}
|
|
42
|
+
// Recursively process nested properties
|
|
43
|
+
processedProperties[key] = processConfigurationProperties(objectValue);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return processedProperties;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
2
49
|
* Extended InstalledExtensionService that handles Moleculer event broadcasting
|
|
3
50
|
* Follows the pattern of AccountService/AccountServiceExt
|
|
4
51
|
*/
|
|
5
52
|
let InstalledExtensionServiceExt = class InstalledExtensionServiceExt extends InstalledExtensionService {
|
|
6
|
-
|
|
7
|
-
|
|
53
|
+
slugService;
|
|
54
|
+
redisCacheManager;
|
|
55
|
+
constructor(repository, registryService, slugService, redisCacheManager, broker, logger) {
|
|
56
|
+
super(repository, registryService, slugService, broker, logger);
|
|
57
|
+
this.slugService = slugService;
|
|
58
|
+
this.redisCacheManager = redisCacheManager;
|
|
8
59
|
this.setupEventListeners();
|
|
9
60
|
}
|
|
10
61
|
setupEventListeners() {
|
|
@@ -16,24 +67,20 @@ let InstalledExtensionServiceExt = class InstalledExtensionServiceExt extends In
|
|
|
16
67
|
const registryExtension = await this.registryExtensionService.findExtension(event.extensionSlug);
|
|
17
68
|
let configurationNodes = [];
|
|
18
69
|
let configurationDefaults = [];
|
|
19
|
-
if (registryExtension
|
|
20
|
-
console.log('Extension found
|
|
21
|
-
|
|
22
|
-
// The manifest is
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
console.log('Found parsed contributes:', Object.keys(contributes));
|
|
29
|
-
}
|
|
30
|
-
// Fallback: try to parse raw if contributes not found but raw exists
|
|
31
|
-
else if (registryExtension.manifest.raw) {
|
|
70
|
+
if (registryExtension) {
|
|
71
|
+
console.log('Extension found:', event.extensionSlug);
|
|
72
|
+
// Get the current release to access the manifest
|
|
73
|
+
// The manifest is stored in the release, not directly in the registry extension
|
|
74
|
+
const currentRelease = registryExtension.releases?.find(release => release.version === registryExtension.version);
|
|
75
|
+
if (currentRelease && currentRelease.manifest) {
|
|
76
|
+
console.log('Found current release with manifest:', registryExtension.version);
|
|
77
|
+
let contributes = null;
|
|
78
|
+
let parsedManifest = null;
|
|
32
79
|
try {
|
|
33
|
-
|
|
80
|
+
// Parse the manifest from the release (stored as JSON string)
|
|
81
|
+
parsedManifest = typeof currentRelease.manifest === 'string' ? JSON.parse(currentRelease.manifest) : currentRelease.manifest;
|
|
34
82
|
console.log('Parsed manifest keys:', Object.keys(parsedManifest));
|
|
35
83
|
contributes = parsedManifest.contributes;
|
|
36
|
-
console.log('Parsed contributes from manifest.raw:', contributes ? 'found' : 'not found');
|
|
37
84
|
if (contributes) {
|
|
38
85
|
console.log('Contributes keys:', Object.keys(contributes));
|
|
39
86
|
console.log('Configuration exists:', !!contributes.configuration);
|
|
@@ -42,68 +89,78 @@ let InstalledExtensionServiceExt = class InstalledExtensionServiceExt extends In
|
|
|
42
89
|
}
|
|
43
90
|
}
|
|
44
91
|
} catch (error) {
|
|
45
|
-
console.warn('Failed to parse
|
|
92
|
+
console.warn('Failed to parse release manifest:', error);
|
|
46
93
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
94
|
+
// Extract configuration contributions if they exist
|
|
95
|
+
if (contributes && contributes.configuration) {
|
|
96
|
+
console.log('Configuration contributions found, processing...');
|
|
97
|
+
const configurations = Array.isArray(contributes.configuration) ? contributes.configuration : [contributes.configuration];
|
|
98
|
+
// Format contributions for configuration registry
|
|
99
|
+
configurationNodes = configurations.map(config => {
|
|
100
|
+
// Process properties to convert scope strings to numbers
|
|
101
|
+
const processedProperties = processConfigurationProperties(config.properties || {});
|
|
102
|
+
return {
|
|
103
|
+
id: ContributionFragmentName.Settings,
|
|
104
|
+
title: config.title || registryExtension.name,
|
|
105
|
+
description: config.description,
|
|
106
|
+
properties: processedProperties,
|
|
107
|
+
type: config.type || ['object']
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
// Create configuration defaults
|
|
111
|
+
configurationDefaults = [{
|
|
112
|
+
source: {
|
|
113
|
+
id: event.extensionSlug,
|
|
114
|
+
displayName: registryExtension.name
|
|
115
|
+
},
|
|
116
|
+
overrides: {} // Default empty overrides
|
|
117
|
+
}];
|
|
118
|
+
console.log(`Processed ${configurationNodes.length} configuration nodes`);
|
|
119
|
+
} else {
|
|
120
|
+
console.log('No configuration contributions found in manifest');
|
|
121
|
+
}
|
|
122
|
+
console.log('CONTRIBUTES========>', JSON.stringify(contributes));
|
|
123
|
+
// Extract UILayout contributions if they exist (same structure as configuration)
|
|
124
|
+
if (contributes && contributes.uiLayout) {
|
|
125
|
+
console.log('UILayout contributions found, processing...');
|
|
126
|
+
const uiLayoutContributions = Array.isArray(contributes.uiLayout) ? contributes.uiLayout : [contributes.uiLayout];
|
|
127
|
+
console.log(`Found ${uiLayoutContributions.length} UILayout contribution(s) in manifest`);
|
|
128
|
+
// Format UILayout contributions (same structure as configuration)
|
|
129
|
+
const uiLayoutNodes = uiLayoutContributions.map(uiLayout => {
|
|
130
|
+
// Process properties to convert scope strings to numbers (same as configuration)
|
|
131
|
+
const processedProperties = processConfigurationProperties(uiLayout.properties || {});
|
|
132
|
+
return {
|
|
133
|
+
id: ContributionFragmentName.Settings,
|
|
134
|
+
title: uiLayout.title || registryExtension.name,
|
|
135
|
+
description: uiLayout.description,
|
|
136
|
+
properties: processedProperties,
|
|
137
|
+
type: uiLayout.type || ['object']
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
if (uiLayoutNodes.length > 0) {
|
|
141
|
+
console.log(`Registering ${uiLayoutNodes.length} UILayout configuration nodes`);
|
|
142
|
+
try {
|
|
143
|
+
// Register UILayout contributions (exact same as configuration, just different schema)
|
|
144
|
+
await this.broker.call('ConfigurationRegistryService.registerUILayoutContributions', {
|
|
145
|
+
tenantId: event.tenantId,
|
|
146
|
+
extensionID: event.extensionSlug,
|
|
147
|
+
uiLayoutNodes
|
|
148
|
+
});
|
|
149
|
+
console.log(`✅ UILayout contributions registered successfully for ${event.extensionSlug}`);
|
|
150
|
+
} catch (uiLayoutError) {
|
|
151
|
+
console.error('❌ Failed to register UILayout contributions:', uiLayoutError);
|
|
152
|
+
// This is not fatal, log and continue
|
|
153
|
+
}
|
|
66
154
|
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
source: {
|
|
71
|
-
id: event.extensionSlug,
|
|
72
|
-
displayName: registryExtension.name
|
|
73
|
-
},
|
|
74
|
-
overrides: {} // Default empty overrides
|
|
75
|
-
}];
|
|
76
|
-
console.log(`Processed ${configurationNodes.length} configuration nodes`);
|
|
155
|
+
} else {
|
|
156
|
+
console.log('No UILayout contributions found in manifest');
|
|
157
|
+
}
|
|
77
158
|
} else {
|
|
78
|
-
console.log('No
|
|
159
|
+
console.log('No current release or manifest found for version:', registryExtension.version);
|
|
79
160
|
}
|
|
80
161
|
} else {
|
|
81
|
-
console.log('No extension
|
|
162
|
+
console.log('No extension found for:', event.extensionSlug);
|
|
82
163
|
}
|
|
83
|
-
// Add the extension's enabled/disabled state to configuration nodes
|
|
84
|
-
// This tracks the extension status regardless of whether it has configuration contributions
|
|
85
|
-
const extensionStatusNode = {
|
|
86
|
-
id: `${event.extensionSlug}.status`,
|
|
87
|
-
title: `${registryExtension?.name || event.extensionSlug} Status`,
|
|
88
|
-
description: `Extension enabled/disabled status for ${event.extensionSlug}`,
|
|
89
|
-
properties: {
|
|
90
|
-
[`extensions.${event.extensionSlug}`]: {
|
|
91
|
-
type: 'boolean',
|
|
92
|
-
default: true,
|
|
93
|
-
// Default to enabled when installed
|
|
94
|
-
description: `Enable/disable ${event.extensionSlug} extension`,
|
|
95
|
-
scope: 'window'
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
type: ['object'],
|
|
99
|
-
scope: 3 /* ConfigurationScope.WINDOW */,
|
|
100
|
-
extensionInfo: {
|
|
101
|
-
id: event.extensionSlug,
|
|
102
|
-
displayName: registryExtension?.name || event.extensionSlug
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
// Add the extension status node to configurationNodes
|
|
106
|
-
// configurationNodes.push(extensionStatusNode);
|
|
107
164
|
// Create the configuration node data that configuration registry expects
|
|
108
165
|
const configurationNode = {
|
|
109
166
|
schemaId: ConfigurationSchemaId.Configuration,
|
|
@@ -127,67 +184,224 @@ let InstalledExtensionServiceExt = class InstalledExtensionServiceExt extends In
|
|
|
127
184
|
},
|
|
128
185
|
context
|
|
129
186
|
});
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
context,
|
|
133
|
-
timestamp: new Date()
|
|
134
|
-
}, [MoleculerServiceName.ConfigurationRegistryService
|
|
135
|
-
// MoleculerServiceName.MailService, // Using MailService instead of NotificationService
|
|
136
|
-
]);
|
|
137
|
-
// Create separate configuration node for system extension status
|
|
138
|
-
const systemExtensionNode = {
|
|
139
|
-
schemaId: ConfigurationSchemaId.Configuration,
|
|
140
|
-
tenantId: event.tenantId,
|
|
141
|
-
extensionName: SystemContributionExtensionNames.SystemExtension,
|
|
142
|
-
policyConfigs: null,
|
|
143
|
-
configurationNodes: [extensionStatusNode]
|
|
144
|
-
};
|
|
187
|
+
// STEP 1: MANDATORY - Register extension in system_extension FIRST (REQUIRED FOR ALL EXTENSIONS)
|
|
188
|
+
console.log('\n🔧 STEP 1: Registering extension in SYSTEM_EXTENSION (MANDATORY)');
|
|
145
189
|
const systemContext = {
|
|
146
190
|
schemaId: ConfigurationSchemaId.Configuration,
|
|
147
191
|
tenantId: event.tenantId,
|
|
148
192
|
extensionName: SystemContributionExtensionNames.SystemExtension,
|
|
149
193
|
accountId: event.installedBy
|
|
150
194
|
};
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
195
|
+
let systemExtensionRegistered = false;
|
|
196
|
+
try {
|
|
197
|
+
console.log('Fetching current system_extension document...');
|
|
198
|
+
// Get existing system_extension document
|
|
199
|
+
const existingSystemDoc = await this.broker.call('ConfigurationRegistryService.getConfigurationNodeRegistry', {
|
|
200
|
+
context: systemContext
|
|
201
|
+
});
|
|
202
|
+
// Prepare the merged configuration node
|
|
203
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
204
|
+
const mergedNode = {
|
|
205
|
+
id: ContributionFragmentName.Settings,
|
|
206
|
+
type: ['object'],
|
|
207
|
+
properties: {},
|
|
208
|
+
restrictedProperties: []
|
|
209
|
+
};
|
|
210
|
+
// If document exists, merge existing properties
|
|
211
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
212
|
+
if (existingSystemDoc && existingSystemDoc.configurationNodes) {
|
|
213
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
214
|
+
const existingNodes = existingSystemDoc.configurationNodes || [];
|
|
215
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
216
|
+
const existingSettingsNode = existingNodes.find(
|
|
217
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
218
|
+
node => node.id === ContributionFragmentName.Settings);
|
|
219
|
+
if (existingSettingsNode?.properties) {
|
|
220
|
+
mergedNode.properties = {
|
|
221
|
+
...existingSettingsNode.properties
|
|
222
|
+
};
|
|
223
|
+
const existingCount = Object.keys(existingSettingsNode.properties).length;
|
|
224
|
+
console.log(`📝 Merging with ${existingCount} existing properties`);
|
|
225
|
+
}
|
|
226
|
+
} else {
|
|
227
|
+
console.log('📝 Creating new system_extension document');
|
|
228
|
+
}
|
|
229
|
+
// Add/update the property for this extension
|
|
230
|
+
mergedNode.properties[`extensions.${event.extensionSlug}`] = {
|
|
231
|
+
type: 'boolean',
|
|
232
|
+
default: true,
|
|
233
|
+
description: `Enable/disable ${event.extensionSlug} extension`,
|
|
234
|
+
scope: 3 /* ConfigurationScope.WINDOW */
|
|
235
|
+
};
|
|
236
|
+
// Prepare final data
|
|
237
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
238
|
+
const finalSystemExtensionNode = {
|
|
239
|
+
schemaId: ConfigurationSchemaId.Configuration,
|
|
240
|
+
tenantId: event.tenantId,
|
|
241
|
+
extensionName: SystemContributionExtensionNames.SystemExtension,
|
|
242
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
243
|
+
policyConfigs: existingSystemDoc?.policyConfigs || null,
|
|
244
|
+
configurationNodes: [mergedNode],
|
|
245
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
246
|
+
configurationDefaults: existingSystemDoc?.configurationDefaults || []
|
|
247
|
+
};
|
|
248
|
+
// Use update if exists, create if new
|
|
249
|
+
const serviceMethod = existingSystemDoc ? 'ConfigurationRegistryService.updateConfigurationNodeRegistry' : 'ConfigurationRegistryService.createConfigurationNodeRegistry';
|
|
250
|
+
await this.broker.call(serviceMethod, {
|
|
251
|
+
data: finalSystemExtensionNode,
|
|
252
|
+
context: systemContext
|
|
253
|
+
});
|
|
254
|
+
systemExtensionRegistered = true;
|
|
255
|
+
const totalExtensions = Object.keys(mergedNode.properties).length;
|
|
256
|
+
console.log(`✅ STEP 1 SUCCESS: Extension registered (total: ${totalExtensions} extensions)`);
|
|
257
|
+
} catch (systemError) {
|
|
258
|
+
console.error('❌ STEP 1 FAILED: System extension registration failed:', systemError);
|
|
259
|
+
throw new Error(`Extension installation failed: Could not register in system (${systemError.message})`);
|
|
260
|
+
}
|
|
261
|
+
// STEP 2: CONDITIONAL - Create extension configuration ONLY IF CONTRIBUTIONS EXIST
|
|
262
|
+
let extensionConfigCreated = false;
|
|
263
|
+
if (configurationNodes.length > 0) {
|
|
264
|
+
console.log('\n📝 STEP 2: Creating extension configuration (contributions exist)');
|
|
265
|
+
try {
|
|
266
|
+
console.log('Broadcasting extension configuration registry...');
|
|
267
|
+
await this.broker.call('ConfigurationRegistryService.createConfigurationNodeRegistry', {
|
|
268
|
+
data: configurationNode,
|
|
269
|
+
context
|
|
270
|
+
});
|
|
271
|
+
extensionConfigCreated = true;
|
|
272
|
+
console.log('✅ STEP 2 SUCCESS: Extension configuration created');
|
|
273
|
+
} catch (configError) {
|
|
274
|
+
console.error('❌ STEP 2 FAILED: Extension configuration creation failed:', configError);
|
|
275
|
+
// This is not fatal since system extension is already registered
|
|
276
|
+
console.warn('⚠️ Extension is registered in system but configuration creation failed');
|
|
277
|
+
}
|
|
278
|
+
} else {
|
|
279
|
+
console.log('\nℹ️ STEP 2: Skipping extension configuration (no contributions found)');
|
|
280
|
+
}
|
|
281
|
+
await this.dropCache();
|
|
282
|
+
console.log('\n=== EXTENSION INSTALLATION COMPLETED ===');
|
|
283
|
+
console.log('System Extension Registered:', systemExtensionRegistered ? '✅' : '❌');
|
|
284
|
+
console.log('Extension Config Created:', extensionConfigCreated ? '✅' : 'ℹ️ Not needed');
|
|
285
|
+
console.log('Overall Installation:', systemExtensionRegistered ? '✅ SUCCESS' : '❌ FAILED');
|
|
158
286
|
} catch (error) {
|
|
159
287
|
console.error('Error processing extension installed event:', error);
|
|
160
288
|
}
|
|
161
289
|
});
|
|
162
290
|
// Listen to extension uninstalled events
|
|
163
291
|
this.onExtensionUninstalled.event(async event => {
|
|
292
|
+
console.log('=== EXTENSION UNINSTALLATION STARTED ===');
|
|
293
|
+
console.log('Extension slug:', event.extensionSlug);
|
|
294
|
+
console.log('Tenant:', event.tenantId);
|
|
295
|
+
let uninstallationSuccessful = false;
|
|
296
|
+
let extensionConfigRemoved = false;
|
|
297
|
+
let systemExtensionUpdated = false;
|
|
164
298
|
try {
|
|
165
|
-
// Remove extension
|
|
299
|
+
// STEP 1: Remove the extension's own configuration registry entry (if it exists)
|
|
300
|
+
console.log('\n🗑️ STEP 1: Removing extension configuration registry');
|
|
166
301
|
const context = {
|
|
167
302
|
schemaId: ConfigurationSchemaId.Configuration,
|
|
168
303
|
tenantId: event.tenantId,
|
|
169
304
|
extensionName: event.extensionSlug,
|
|
170
305
|
accountId: event.uninstalledBy
|
|
171
306
|
};
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
307
|
+
try {
|
|
308
|
+
console.log('Removing extension configuration document...');
|
|
309
|
+
await this.broker.call('ConfigurationRegistryService.removeConfigurationNodeRegistry', {
|
|
310
|
+
context
|
|
311
|
+
});
|
|
312
|
+
extensionConfigRemoved = true;
|
|
313
|
+
console.log('✅ STEP 1 SUCCESS: Extension configuration removed');
|
|
314
|
+
} catch (configError) {
|
|
315
|
+
console.warn('⚠️ STEP 1 WARNING: Extension configuration removal failed (may not exist):', configError);
|
|
316
|
+
// This is not fatal - extension might not have had configuration
|
|
317
|
+
}
|
|
318
|
+
// STEP 1.5: Remove UILayout contributions (if any exist)
|
|
319
|
+
console.log('\n🗑️ STEP 1.5: Removing UILayout contributions (if exist)');
|
|
320
|
+
try {
|
|
321
|
+
console.log('Attempting to remove UILayout contributions...');
|
|
322
|
+
await this.broker.call('ConfigurationRegistryService.removeUILayoutContributions', {
|
|
323
|
+
tenantId: event.tenantId,
|
|
324
|
+
extensionID: event.extensionSlug
|
|
325
|
+
});
|
|
326
|
+
console.log('✅ STEP 1.5 SUCCESS: UILayout contributions removed');
|
|
327
|
+
} catch (uiLayoutError) {
|
|
328
|
+
console.warn('⚠️ STEP 1.5 WARNING: UILayout contributions removal failed (may not exist):', uiLayoutError);
|
|
329
|
+
// This is not fatal - extension might not have had UILayout contributions
|
|
330
|
+
}
|
|
331
|
+
// STEP 2: MANDATORY - Remove extension node from system_extension document
|
|
332
|
+
console.log('\n🔧 STEP 2: Unregistering extension from SYSTEM_EXTENSION (MANDATORY)');
|
|
333
|
+
try {
|
|
334
|
+
// First, get the current system_extension document
|
|
335
|
+
const systemContext = {
|
|
336
|
+
schemaId: ConfigurationSchemaId.Configuration,
|
|
337
|
+
tenantId: event.tenantId,
|
|
338
|
+
extensionName: SystemContributionExtensionNames.SystemExtension,
|
|
339
|
+
accountId: event.uninstalledBy
|
|
340
|
+
};
|
|
341
|
+
console.log('Fetching current system_extension document...');
|
|
342
|
+
const currentSystemDoc = await this.broker.call('ConfigurationRegistryService.getConfigurationNodeRegistry', {
|
|
343
|
+
context: systemContext
|
|
344
|
+
});
|
|
345
|
+
if (currentSystemDoc && currentSystemDoc.configurationNodes) {
|
|
346
|
+
const systemDoc = currentSystemDoc;
|
|
347
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
348
|
+
const configurationNodes = systemDoc.configurationNodes;
|
|
349
|
+
// Find the settings node and remove the extension property
|
|
350
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
351
|
+
const settingsNode = configurationNodes.find(
|
|
352
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
353
|
+
node => node.id === ContributionFragmentName.Settings);
|
|
354
|
+
if (settingsNode?.properties) {
|
|
355
|
+
const propertyKey = `extensions.${event.extensionSlug}`;
|
|
356
|
+
delete settingsNode.properties[propertyKey];
|
|
357
|
+
console.log(`Removing extension property: ${propertyKey}`);
|
|
358
|
+
console.log(`Remaining properties: ${Object.keys(settingsNode.properties).length}`);
|
|
359
|
+
}
|
|
360
|
+
const updatedConfigurationNodes = configurationNodes;
|
|
361
|
+
// Update the system_extension document with the updated nodes
|
|
362
|
+
const updatedSystemExtensionNode = {
|
|
363
|
+
schemaId: ConfigurationSchemaId.Configuration,
|
|
364
|
+
tenantId: event.tenantId,
|
|
365
|
+
extensionName: SystemContributionExtensionNames.SystemExtension,
|
|
366
|
+
policyConfigs: systemDoc.policyConfigs || null,
|
|
367
|
+
configurationNodes: updatedConfigurationNodes,
|
|
368
|
+
configurationDefaults: systemDoc.configurationDefaults || []
|
|
369
|
+
};
|
|
370
|
+
console.log('Updating system_extension document...');
|
|
371
|
+
await this.broker.call('ConfigurationRegistryService.updateConfigurationNodeRegistry', {
|
|
372
|
+
data: updatedSystemExtensionNode,
|
|
373
|
+
context: systemContext
|
|
374
|
+
});
|
|
375
|
+
systemExtensionUpdated = true;
|
|
376
|
+
console.log('✅ STEP 2 SUCCESS: Extension unregistered from system_extension');
|
|
377
|
+
} else {
|
|
378
|
+
console.warn('⚠️ STEP 2 WARNING: No system_extension document found or no configuration nodes');
|
|
379
|
+
systemExtensionUpdated = true; // Consider it successful if document doesn't exist
|
|
380
|
+
}
|
|
381
|
+
} catch (systemError) {
|
|
382
|
+
console.error('❌ STEP 2 FAILED: System extension unregistration failed:', systemError);
|
|
383
|
+
throw new Error(`Extension uninstallation failed: Could not unregister from system (${systemError.message})`);
|
|
384
|
+
}
|
|
385
|
+
// Uninstallation is successful if system extension is updated
|
|
386
|
+
uninstallationSuccessful = systemExtensionUpdated;
|
|
387
|
+
await this.dropCache();
|
|
388
|
+
console.log('\n=== EXTENSION UNINSTALLATION COMPLETED ===');
|
|
389
|
+
console.log('Extension Config Removed:', extensionConfigRemoved ? '✅' : 'ℹ️ Not found');
|
|
390
|
+
console.log('System Extension Updated:', systemExtensionUpdated ? '✅' : '❌');
|
|
391
|
+
console.log('Overall Uninstallation:', uninstallationSuccessful ? '✅ SUCCESS' : '❌ FAILED');
|
|
188
392
|
} catch (error) {
|
|
189
|
-
console.error('
|
|
393
|
+
console.error('❌ EXTENSION UNINSTALLATION FAILED:', error);
|
|
394
|
+
console.error('Error details:', {
|
|
395
|
+
message: error.message,
|
|
396
|
+
stack: error.stack,
|
|
397
|
+
extensionSlug: event.extensionSlug,
|
|
398
|
+
tenantId: event.tenantId,
|
|
399
|
+
extensionConfigRemoved,
|
|
400
|
+
systemExtensionUpdated
|
|
401
|
+
});
|
|
402
|
+
throw error; // Re-throw to ensure calling code knows uninstallation failed
|
|
190
403
|
}
|
|
404
|
+
// Notify other services about the uninstallation
|
|
191
405
|
this.broker.broadcast(ExtensionServiceAction.OnExtensionUninstalled, {
|
|
192
406
|
event
|
|
193
407
|
}, [MoleculerServiceName.ConfigurationService, 'WorkbenchService',
|
|
@@ -239,9 +453,9 @@ let InstalledExtensionServiceExt = class InstalledExtensionServiceExt extends In
|
|
|
239
453
|
]);
|
|
240
454
|
});
|
|
241
455
|
// Listen to extension cleanup completed events
|
|
242
|
-
this.onExtensionCleanupCompleted.event(
|
|
456
|
+
this.onExtensionCleanupCompleted.event(e => {
|
|
243
457
|
this.broker.broadcast(ExtensionServiceAction.OnExtensionCleanupCompleted, {
|
|
244
|
-
event
|
|
458
|
+
event: e
|
|
245
459
|
}, [MoleculerServiceName.MailService // Using MailService instead of NotificationService
|
|
246
460
|
]);
|
|
247
461
|
});
|
|
@@ -267,5 +481,38 @@ let InstalledExtensionServiceExt = class InstalledExtensionServiceExt extends In
|
|
|
267
481
|
]);
|
|
268
482
|
});
|
|
269
483
|
}
|
|
484
|
+
async dropCache() {
|
|
485
|
+
console.log('Start dropping GraphQL query cache keys');
|
|
486
|
+
try {
|
|
487
|
+
// Get Redis client from redisCacheManager
|
|
488
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
489
|
+
const {
|
|
490
|
+
redisClient
|
|
491
|
+
} = this.redisCacheManager;
|
|
492
|
+
if (!redisClient) {
|
|
493
|
+
console.error('❌ Redis client not found in redisCacheManager');
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
const appName = process.env.APP_NAME || 'adminide-stack';
|
|
497
|
+
// Only delete GraphQL query caches, not session/auth data
|
|
498
|
+
// These are the specific queries we want to invalidate
|
|
499
|
+
const queryPatterns = [`${appName}*pageSettings*`, `${appName}*GetPageSettings*`, `${appName}*CurrentPagePermissions*`, `${appName}*IntegrationConfigurations*`, `${appName}*ContributionRoles*`];
|
|
500
|
+
let totalDeleted = 0;
|
|
501
|
+
for (const pattern of queryPatterns) {
|
|
502
|
+
console.log(`🔍 Searching for keys matching: ${pattern}`);
|
|
503
|
+
const keys = await redisClient.keys(pattern);
|
|
504
|
+
if (keys.length > 0) {
|
|
505
|
+
console.log(`📋 Found ${keys.length} keys for pattern: ${pattern}`);
|
|
506
|
+
console.log(`📝 Sample keys:`, keys.slice(0, 3));
|
|
507
|
+
await redisClient.del(...keys);
|
|
508
|
+
totalDeleted += keys.length;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
console.log(`✅ Successfully deleted ${totalDeleted} query cache keys`);
|
|
512
|
+
} catch (error) {
|
|
513
|
+
console.error('❌ Failed to drop cache:', error);
|
|
514
|
+
// Don't throw - cache clearing failure shouldn't break extension installation
|
|
515
|
+
}
|
|
516
|
+
}
|
|
270
517
|
};
|
|
271
|
-
InstalledExtensionServiceExt = __decorate([injectable(), __param(0, inject(SERVER_TYPES.IInstalledExtensionRepository)), __param(1, inject(SERVER_TYPES.IRegistryExtensionService)), __param(2, inject(CommonType.MOLECULER_BROKER)), __param(
|
|
518
|
+
InstalledExtensionServiceExt = __decorate([injectable(), __param(0, inject(SERVER_TYPES.IInstalledExtensionRepository)), __param(1, inject(SERVER_TYPES.IRegistryExtensionService)), __param(2, inject(SERVER_TYPES.SlugService)), __param(3, inject(SERVER_TYPES.IRedisCacheManager)), __param(4, inject(CommonType.MOLECULER_BROKER)), __param(5, inject(CommonType.LOGGER)), __metadata("design:paramtypes", [Object, Object, Object, Object, ServiceBroker, Object])], InstalledExtensionServiceExt);export{InstalledExtensionServiceExt};//# sourceMappingURL=installed-extension-service-ext.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installed-extension-service-ext.js","sources":["../../src/services/installed-extension-service-ext.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"installed-extension-service-ext.js","sources":["../../src/services/installed-extension-service-ext.ts"],"sourcesContent":[null],"names":[],"mappings":"qbA4FG;AACH;;AAQQ;;AAQJ,EAAA,IAAA,OAAQ,KAAA,KAAA,QAAmB,EAAA;gBA6gBb,CAAA;AA8CjB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|