@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,192 @@
1
+ import {__decorate,__param,__metadata}from'tslib';import {injectable,inject}from'inversify';import'@cdm-logger/core';import*as fs from'fs';import*as https from'https';import*as http from'http';let ExtensionGalleryRepository = class ExtensionGalleryRepository {
2
+ logger;
3
+ constructor(logger) {
4
+ this.logger = logger;
5
+ this.logger = logger;
6
+ }
7
+ async asset(extensionSlug, version, asset) {
8
+ this.logger.trace('ExtensionGalleryRepository.asset: %s@%s/%s', extensionSlug, version, asset);
9
+ try {
10
+ // Try to fetch asset from different sources
11
+ const assetUrl = this.buildAssetUrl(extensionSlug, version, asset);
12
+ if (assetUrl.startsWith('http')) {
13
+ // Fetch from remote URL
14
+ return await this.fetchHttpAsset(assetUrl);
15
+ }
16
+ // Try to read from local filesystem
17
+ return await this.readLocalAsset(assetUrl);
18
+ } catch (error) {
19
+ this.logger.warn('Failed to fetch asset %s@%s/%s: %s', extensionSlug, version, asset, error.message);
20
+ return null;
21
+ }
22
+ }
23
+ buildAssetUrl(extensionSlug, version, asset) {
24
+ // Build URL based on common extension repository patterns
25
+ const baseUrl = process.env.EXTENSION_REGISTRY_URL || 'https://marketplace.visualstudio.com/_apis/public/gallery';
26
+ return `${baseUrl}/publishers/${extensionSlug}/vsextensions/${version}/vspackage/${asset}`;
27
+ }
28
+ async fetchHttpAsset(url) {
29
+ return new Promise((resolve, reject) => {
30
+ const client = url.startsWith('https') ? https : http;
31
+ const req = client.get(url, response => {
32
+ if (response.statusCode !== 200) {
33
+ reject(new Error(`HTTP ${response.statusCode}: ${response.statusMessage}`));
34
+ return;
35
+ }
36
+ let data = '';
37
+ response.setEncoding('utf8');
38
+ response.on('data', chunk => {
39
+ data += chunk;
40
+ });
41
+ response.on('end', () => {
42
+ try {
43
+ // Try to parse as JSON first, fallback to string
44
+ const result = data.startsWith('{') || data.startsWith('[') ? JSON.parse(data) : data;
45
+ resolve(result);
46
+ } catch (parseError) {
47
+ resolve(data);
48
+ }
49
+ });
50
+ });
51
+ req.on('error', error => {
52
+ reject(error);
53
+ });
54
+ req.setTimeout(10000, () => {
55
+ req.destroy();
56
+ reject(new Error('Request timeout'));
57
+ });
58
+ });
59
+ }
60
+ async readLocalAsset(filePath) {
61
+ return new Promise((resolve, reject) => {
62
+ fs.readFile(filePath, 'utf8', (err, data) => {
63
+ if (err) {
64
+ reject(err);
65
+ return;
66
+ }
67
+ try {
68
+ // Try to parse as JSON first, fallback to string
69
+ const result = data.startsWith('{') || data.startsWith('[') ? JSON.parse(data) : data;
70
+ resolve(result);
71
+ } catch (parseError) {
72
+ resolve(data);
73
+ }
74
+ });
75
+ });
76
+ }
77
+ async get(id, fields) {
78
+ this.logger.trace('ExtensionGalleryRepository.get: %s fields: %j', id, fields);
79
+ try {
80
+ // In a real implementation, this would:
81
+ // 1. Parse the ID (could be extension slug, UUID, etc.)
82
+ // 2. Query the database/registry for matching extensions
83
+ // 3. Apply field filtering to optimize response size
84
+ // 4. Handle multiple IDs if the id parameter supports it
85
+ // For now, we validate the inputs and return empty result
86
+ if (!id || !id.trim()) {
87
+ throw new Error('Extension ID is required');
88
+ }
89
+ // Validate fields array
90
+ const validFields = this.validateFields(fields);
91
+ this.logger.info('Looking for extension with ID: %s, fields: %j', id, validFields);
92
+ // This would be replaced with actual database/API query
93
+ const extensions = [];
94
+ return extensions;
95
+ } catch (error) {
96
+ this.logger.error('Failed to get extension %s: %s', id, error.message);
97
+ return [];
98
+ }
99
+ }
100
+ validateFields(fields) {
101
+ if (!fields || fields.length === 0) {
102
+ // Return default fields if none specified
103
+ return ['id', 'name', 'version', 'displayName', 'description', 'publisher'];
104
+ }
105
+ // Define allowed fields to prevent data leakage
106
+ const allowedFields = ['id', 'name', 'version', 'displayName', 'description', 'publisher', 'assets', 'categories', 'tags', 'statistics', 'releaseDate', 'lastUpdated', 'shortDescription', 'installCount'];
107
+ return fields.filter(field => allowedFields.includes(field));
108
+ }
109
+ async download(extension) {
110
+ this.logger.trace('ExtensionGalleryRepository.download: %s', extension.id);
111
+ try {
112
+ // Get download URL from extension assets
113
+ const downloadAsset = extension.assets?.download;
114
+ if (!downloadAsset?.uri) {
115
+ throw new Error('No download URL available');
116
+ }
117
+ // Verify the download is accessible
118
+ const isAccessible = await this.verifyDownloadUrl(downloadAsset.uri);
119
+ if (!isAccessible) {
120
+ throw new Error('Download URL is not accessible');
121
+ }
122
+ // In a real implementation, you might:
123
+ // 1. Download the file to a local cache
124
+ // 2. Verify the package integrity
125
+ // 3. Store download metrics
126
+ // 4. Return download stream or file path
127
+ this.logger.info('Extension %s download verified successfully', extension.id);
128
+ return true;
129
+ } catch (error) {
130
+ this.logger.error('Download failed for %s: %s', extension.id, error.message);
131
+ return false;
132
+ }
133
+ }
134
+ async verifyDownloadUrl(url) {
135
+ return new Promise(resolve => {
136
+ const client = url.startsWith('https') ? https : http;
137
+ const req = client.request(url, {
138
+ method: 'HEAD'
139
+ }, response => {
140
+ const isSuccess = response.statusCode >= 200 && response.statusCode < 300;
141
+ resolve(isSuccess);
142
+ });
143
+ req.on('error', () => {
144
+ resolve(false);
145
+ });
146
+ req.setTimeout(5000, () => {
147
+ req.destroy();
148
+ resolve(false);
149
+ });
150
+ req.end();
151
+ });
152
+ }
153
+ async query(query) {
154
+ this.logger.trace('ExtensionGalleryRepository.query: %j', query);
155
+ try {
156
+ // Extract common query parameters
157
+ const pageSize = Math.min(query.pageSize || 50, 100); // Cap at 100
158
+ // In a real implementation, this would:
159
+ // 1. Query a search engine (Elasticsearch, etc.)
160
+ // 2. Query a database with proper indexing
161
+ // 3. Call external APIs like VS Code Marketplace
162
+ // 4. Apply filters like: query.search, query.category, query.publisher, etc.
163
+ // For now, return a structured empty result with proper pagination
164
+ const mockResult = {
165
+ results: [],
166
+ total: 0,
167
+ pageSize
168
+ };
169
+ this.logger.info('Extension query completed: %d results', mockResult.total);
170
+ return mockResult;
171
+ } catch (error) {
172
+ this.logger.error('Extension query failed: %s', error.message);
173
+ // Return empty result on error
174
+ return {
175
+ results: [],
176
+ total: 0,
177
+ pageSize: 50
178
+ };
179
+ }
180
+ }
181
+ extractFilters(query) {
182
+ const filters = {};
183
+ // Extract common filter parameters
184
+ if (query.category) filters.category = query.category;
185
+ if (query.publisher) filters.publisher = query.publisher;
186
+ if (query.featured) filters.featured = query.featured;
187
+ if (query.verified) filters.verified = query.verified;
188
+ if (query.targetPlatform) filters.targetPlatform = query.targetPlatform;
189
+ return filters;
190
+ }
191
+ };
192
+ ExtensionGalleryRepository = __decorate([injectable(), __param(0, inject('Logger')), __metadata("design:paramtypes", [Object])], ExtensionGalleryRepository);export{ExtensionGalleryRepository};//# sourceMappingURL=extension-gallery-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-gallery-repository.js","sources":["../../src/services/extension-gallery-repository.ts"],"sourcesContent":[null],"names":[],"mappings":"iMAgCI,IAAA,0BAAqB,GAAA,MAAA,0BAAA,CAAA;;aA2CP,CAAA,MAAA,EAAA;AAmBD,IAAA,IAAI,CAAA,MAAI,GAAM,MAAE;AA8B7B,IAAA,IAAA,CAAA,MAAQ,GAAA,MAAA;;aA0DM,CAAA,aAAA,EAAiB,OAAA,EAAA,KAAA,EAAA;AAqBlB,IAAA,IAAA,CAAK,MAAM,CAAA,KAAE,CAAA,2DAAsD,EAAA,OAAA,EAAA,KAAA,CAAA;AAkChF,IAAA,IAAA;AAYH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,39 @@
1
+ import { CdmLogger } from '@cdm-logger/core';
2
+ import { IMarketplacePublisherService, IRegistryExtensionService, IGalleryExtension, IExtensionIdentifier, IExtensionManifest } from 'common/server';
3
+ export interface IExtensionGalleryService {
4
+ isEnabled(): boolean;
5
+ query(options?: any): Promise<any>;
6
+ getExtension(identifier: IExtensionIdentifier | string, version?: string): Promise<IGalleryExtension | null>;
7
+ download(extension: IGalleryExtension, operation: any): Promise<string>;
8
+ getReadme(extension: IGalleryExtension, token?: unknown): Promise<string>;
9
+ getManifest(extension: IGalleryExtension, token?: unknown): Promise<IExtensionManifest | null>;
10
+ getChangelog(extension: IGalleryExtension, token?: unknown): Promise<string>;
11
+ getLicense(extension: IGalleryExtension, token?: unknown): Promise<string>;
12
+ loadCompatibleVersion(extension: IGalleryExtension): Promise<IGalleryExtension>;
13
+ }
14
+ export declare class ExtensionGalleryService implements IExtensionGalleryService {
15
+ private readonly logger;
16
+ private readonly registryExtensionService;
17
+ private readonly publisherService;
18
+ private readonly disposables;
19
+ private readonly _onDidChange;
20
+ readonly onDidChange: import("@adminide-stack/core").Event<void>;
21
+ constructor(logger: CdmLogger.ILogger, registryExtensionService: IRegistryExtensionService, publisherService: IMarketplacePublisherService);
22
+ isEnabled(): boolean;
23
+ query(options?: any): Promise<any>;
24
+ getExtension(identifier: IExtensionIdentifier | string, version?: string): Promise<IGalleryExtension | null>;
25
+ download(extension: IGalleryExtension, operation: any): Promise<string>;
26
+ getReadme(extension: IGalleryExtension, token?: unknown): Promise<string>;
27
+ getManifest(extension: IGalleryExtension, token?: unknown): Promise<IExtensionManifest | null>;
28
+ getChangelog(extension: IGalleryExtension, token?: unknown): Promise<string>;
29
+ getLicense(extension: IGalleryExtension, token?: unknown): Promise<string>;
30
+ loadCompatibleVersion(extension: IGalleryExtension): Promise<IGalleryExtension>;
31
+ private toGalleryExtension;
32
+ /**
33
+ * Helper method to get manifest from the current release
34
+ * Since manifests are stored in releases, not directly in the registry extension
35
+ */
36
+ private getManifestFromRelease;
37
+ dispose(): void;
38
+ }
39
+ //# sourceMappingURL=extension-gallery-service-new.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-gallery-service-new.d.ts","sourceRoot":"","sources":["../../src/services/extension-gallery-service-new.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EACH,4BAA4B,EAC5B,yBAAyB,EAGzB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAIrB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,wBAAwB;IACrC,SAAS,IAAI,OAAO,CAAC;IACrB,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,YAAY,CAAC,UAAU,EAAE,oBAAoB,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC7G,QAAQ,CAAC,SAAS,EAAE,iBAAiB,EAAE,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxE,SAAS,CAAC,SAAS,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1E,WAAW,CAAC,SAAS,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAC/F,YAAY,CAAC,SAAS,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7E,UAAU,CAAC,SAAS,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3E,qBAAqB,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACnF;AAED,qBACa,uBAAwB,YAAW,wBAAwB;IAO9C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAEzC,OAAO,CAAC,QAAQ,CAAC,wBAAwB;IAEzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAVrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IAEpD,SAAgB,WAAW,6CAA2B;gBAGf,MAAM,EAAE,SAAS,CAAC,OAAO,EAE3C,wBAAwB,EAAE,yBAAyB,EAEnD,gBAAgB,EAAE,4BAA4B;IAK5D,SAAS,IAAI,OAAO;IAId,KAAK,CAAC,OAAO,GAAE,GAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAkCtC,YAAY,CACrB,UAAU,EAAE,oBAAoB,GAAG,MAAM,EACzC,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAqBvB,QAAQ,CAAC,SAAS,EAAE,iBAAiB,EAAE,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAKvE,SAAS,CAAC,SAAS,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAOzE,WAAW,CAAC,SAAS,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAK9F,YAAY,CAAC,SAAS,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAO5E,UAAU,CAAC,SAAS,EAAE,iBAAiB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAO1E,qBAAqB,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAI9E,kBAAkB;IAwIhC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAoEvB,OAAO,IAAI,IAAI;CAGzB"}
@@ -0,0 +1,30 @@
1
+ import { CdmLogger } from '@cdm-logger/core';
2
+ import { IMarketplacePublisherService, IRegistryExtensionService, IGalleryExtension, IExtensionIdentifier, IExtensionManifest, IGalleryPager, IExtensionGalleryService, IQueryOptions, IExtensionGalleryRepository } from 'common/server';
3
+ export declare class ExtensionGalleryService implements IExtensionGalleryService {
4
+ private readonly logger;
5
+ private readonly registryExtensionService;
6
+ private readonly publisherService;
7
+ private readonly galleryRepository;
8
+ private readonly disposables;
9
+ private readonly _onDidChange;
10
+ readonly onDidChange: import("@adminide-stack/core").Event<void>;
11
+ constructor(logger: CdmLogger.ILogger, registryExtensionService: IRegistryExtensionService, publisherService: IMarketplacePublisherService, galleryRepository: IExtensionGalleryRepository);
12
+ isEnabled(): boolean;
13
+ query(options?: IQueryOptions): Promise<IGalleryPager>;
14
+ getExtension(identifier: IExtensionIdentifier | string): Promise<IGalleryExtension | null>;
15
+ download(extension: IGalleryExtension): Promise<string>;
16
+ getReadme(extension: IGalleryExtension): Promise<string>;
17
+ getManifest(extension: IGalleryExtension): Promise<IExtensionManifest | null>;
18
+ getChangelog(extension: IGalleryExtension): Promise<string>;
19
+ getLicense(extension: IGalleryExtension): Promise<string>;
20
+ loadCompatibleVersion(extension: IGalleryExtension): Promise<IGalleryExtension>;
21
+ private toGalleryExtension;
22
+ getAllVersions(extension: IGalleryExtension): Promise<IGalleryExtension[]>;
23
+ /**
24
+ * Helper method to get manifest from the current release
25
+ * Since manifests are stored in releases, not directly in the registry extension
26
+ */
27
+ private getManifestFromRelease;
28
+ dispose(): void;
29
+ }
30
+ //# sourceMappingURL=extension-gallery-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-gallery-service.d.ts","sourceRoot":"","sources":["../../src/services/extension-gallery-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EACH,4BAA4B,EAC5B,yBAAyB,EAGzB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EAGb,wBAAwB,EACxB,aAAa,EACb,2BAA2B,EAC9B,MAAM,eAAe,CAAC;AAEvB,qBACa,uBAAwB,YAAW,wBAAwB;IAQ9C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAEzC,OAAO,CAAC,QAAQ,CAAC,wBAAwB;IAEzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAEjC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAbtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;IAE1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IAEpD,SAAgB,WAAW,6CAA2B;gBAGf,MAAM,EAAE,SAAS,CAAC,OAAO,EAE3C,wBAAwB,EAAE,yBAAyB,EAEnD,gBAAgB,EAAE,4BAA4B,EAE9C,iBAAiB,EAAE,2BAA2B;IAK5D,SAAS,IAAI,OAAO;IAId,KAAK,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAkC1D,YAAY,CAAC,UAAU,EAAE,oBAAoB,GAAG,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAqB1F,QAAQ,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBvD,SAAS,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAsBxD,WAAW,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAuB7E,YAAY,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAsB3D,UAAU,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAsBzD,qBAAqB,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAsC9E,kBAAkB;IA0InB,cAAc,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IA2BvF;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IA8CvB,OAAO,IAAI,IAAI;CAGzB"}
@@ -0,0 +1,334 @@
1
+ import {__decorate,__param,__metadata}from'tslib';import {injectable,inject}from'inversify';import'@cdm-logger/core';import {DisposableCollection,Emitter}from'@adminide-stack/core';import {SERVER_TYPES,ExtensionRegistryStatus}from'common/server';let ExtensionGalleryService = class ExtensionGalleryService {
2
+ logger;
3
+ registryExtensionService;
4
+ publisherService;
5
+ galleryRepository;
6
+ disposables = new DisposableCollection();
7
+ _onDidChange = new Emitter();
8
+ onDidChange = this._onDidChange.event;
9
+ constructor(logger, registryExtensionService, publisherService, galleryRepository) {
10
+ this.logger = logger;
11
+ this.registryExtensionService = registryExtensionService;
12
+ this.publisherService = publisherService;
13
+ this.galleryRepository = galleryRepository;
14
+ this.disposables.push(this._onDidChange);
15
+ }
16
+ isEnabled() {
17
+ return true;
18
+ }
19
+ async query(options = {}) {
20
+ this.logger.trace('ExtensionGalleryService.query with options: %j', options);
21
+ try {
22
+ const {
23
+ text = '',
24
+ pageSize = 50
25
+ } = options;
26
+ const extensions = await this.registryExtensionService.findExtensions(pageSize, text, false,
27
+ // local
28
+ true);
29
+ const galleryExtensions = await Promise.all(extensions.map(ext => this.toGalleryExtension(ext)));
30
+ return {
31
+ __typename: 'GalleryPager',
32
+ firstPage: galleryExtensions,
33
+ total: galleryExtensions.length,
34
+ pageSize,
35
+ page: 0
36
+ };
37
+ } catch (error) {
38
+ this.logger.error('ExtensionGalleryService.query error: %s', error.message);
39
+ return {
40
+ __typename: 'GalleryPager',
41
+ firstPage: [],
42
+ total: 0,
43
+ pageSize: options.pageSize || 50,
44
+ page: 0
45
+ };
46
+ }
47
+ }
48
+ async getExtension(identifier) {
49
+ this.logger.trace('ExtensionGalleryService.getExtension: %s', typeof identifier === 'string' ? identifier : identifier.id);
50
+ try {
51
+ const extensionId = typeof identifier === 'string' ? identifier : identifier.id;
52
+ const extension = await this.registryExtensionService.findExtension(extensionId);
53
+ if (!extension) {
54
+ return null;
55
+ }
56
+ return this.toGalleryExtension(extension);
57
+ } catch (error) {
58
+ this.logger.error('ExtensionGalleryService.getExtension error: %s', error.message);
59
+ return null;
60
+ }
61
+ }
62
+ async download(extension) {
63
+ this.logger.trace('ExtensionGalleryService.download: %s', extension.id);
64
+ try {
65
+ const success = await this.galleryRepository.download(extension);
66
+ if (success) {
67
+ // Return the download URL for the extension
68
+ const downloadUrl = extension.assets?.download?.uri || `${extension.url}/${extension.version}.vsix`;
69
+ this.logger.info('Extension download prepared: %s -> %s', extension.id, downloadUrl);
70
+ return downloadUrl;
71
+ }
72
+ throw new Error(`Failed to prepare download for extension: ${extension.id}`);
73
+ } catch (error) {
74
+ this.logger.error('ExtensionGalleryService.download error: %s', error.message);
75
+ throw error;
76
+ }
77
+ }
78
+ async getReadme(extension) {
79
+ this.logger.trace('ExtensionGalleryService.getReadme: %s', extension.id);
80
+ try {
81
+ const readmeUrl = extension.assets?.readme?.uri;
82
+ if (!readmeUrl) {
83
+ return 'No README available for this extension.';
84
+ }
85
+ const readmeAsset = await this.galleryRepository.asset(extension.extensionSlug || extension.id, extension.version, 'README.md');
86
+ return readmeAsset || 'README content could not be loaded.';
87
+ } catch (error) {
88
+ this.logger.warn('Failed to fetch README for %s: %s', extension.id, error.message);
89
+ return 'Error loading README content.';
90
+ }
91
+ }
92
+ async getManifest(extension) {
93
+ this.logger.trace('ExtensionGalleryService.getManifest: %s', extension.id);
94
+ try {
95
+ // First try to return the already loaded manifest
96
+ if (extension.manifest) {
97
+ return extension.manifest;
98
+ }
99
+ // If not available, try to fetch from repository
100
+ const manifestAsset = await this.galleryRepository.asset(extension.extensionSlug || extension.id, extension.version, 'package.json');
101
+ return manifestAsset;
102
+ } catch (error) {
103
+ this.logger.warn('Failed to fetch manifest for %s: %s', extension.id, error.message);
104
+ return null;
105
+ }
106
+ }
107
+ async getChangelog(extension) {
108
+ this.logger.trace('ExtensionGalleryService.getChangelog: %s', extension.id);
109
+ try {
110
+ const changelogUrl = extension.assets?.changelog?.uri;
111
+ if (!changelogUrl) {
112
+ return 'No changelog available for this extension.';
113
+ }
114
+ const changelogAsset = await this.galleryRepository.asset(extension.extensionSlug || extension.id, extension.version, 'CHANGELOG.md');
115
+ return changelogAsset || 'Changelog content could not be loaded.';
116
+ } catch (error) {
117
+ this.logger.warn('Failed to fetch changelog for %s: %s', extension.id, error.message);
118
+ return 'Error loading changelog content.';
119
+ }
120
+ }
121
+ async getLicense(extension) {
122
+ this.logger.trace('ExtensionGalleryService.getLicense: %s', extension.id);
123
+ try {
124
+ const licenseUrl = extension.assets?.license?.uri;
125
+ if (!licenseUrl) {
126
+ return 'No license information available for this extension.';
127
+ }
128
+ const licenseAsset = await this.galleryRepository.asset(extension.extensionSlug || extension.id, extension.version, 'LICENSE');
129
+ return licenseAsset || 'License content could not be loaded.';
130
+ } catch (error) {
131
+ this.logger.warn('Failed to fetch license for %s: %s', extension.id, error.message);
132
+ return 'Error loading license information.';
133
+ }
134
+ }
135
+ async loadCompatibleVersion(extension) {
136
+ this.logger.trace('ExtensionGalleryService.loadCompatibleVersion: %s', extension.id);
137
+ try {
138
+ // Get all extensions from registry (search for this specific extension)
139
+ const allExtensions = await this.registryExtensionService.findExtensions(100, `${extension.publisher.displayName}.${extension.name}`, true, true);
140
+ // Filter to get versions of the same extension
141
+ const extensionVersions = allExtensions.filter(ext => ext.name === extension.name);
142
+ if (!extensionVersions || extensionVersions.length === 0) {
143
+ // If no versions found, return the current extension
144
+ return extension;
145
+ }
146
+ // Find the latest compatible version
147
+ const latestVersion = extensionVersions.sort((a, b) => b.version.localeCompare(a.version, undefined, {
148
+ numeric: true
149
+ }))[0];
150
+ // Convert to gallery extension if different from current
151
+ if (latestVersion.version !== extension.version) {
152
+ return this.toGalleryExtension(latestVersion);
153
+ }
154
+ return extension;
155
+ } catch (error) {
156
+ this.logger.warn('Failed to load compatible version for %s: %s', extension.id, error.message);
157
+ // Return original extension if we can't find a compatible version
158
+ return extension;
159
+ }
160
+ }
161
+ async toGalleryExtension(registryExt) {
162
+ let publisherInfo = null;
163
+ try {
164
+ const publisherId = registryExt.publisherId || registryExt.publisher;
165
+ if (publisherId) {
166
+ publisherInfo = await this.publisherService.findById(publisherId);
167
+ }
168
+ } catch (error) {
169
+ this.logger.warn('Failed to get publisher info: %s', error.message);
170
+ }
171
+ const manifest = this.getManifestFromRelease(registryExt);
172
+ // Get the raw manifest as JSON string for resources.manifest
173
+ const rawManifest = manifest ? JSON.stringify(manifest) : null;
174
+ const galleryExtension = {
175
+ __typename: 'GalleryExtension',
176
+ id: registryExt.id || registryExt._id?.toString() || '',
177
+ uuid: registryExt.uuid,
178
+ name: registryExt.name,
179
+ displayName: manifest?.displayName || registryExt.name,
180
+ description: manifest?.description || '',
181
+ version: registryExt.version || '0.0.1',
182
+ extensionSlug: registryExt.extensionSlug,
183
+ manifest: {
184
+ ...manifest,
185
+ raw: rawManifest || undefined,
186
+ // Include raw manifest in manifest object
187
+ screenshots: manifest?.screenshots || [],
188
+ author: manifest?.author || undefined,
189
+ license: manifest?.license || undefined,
190
+ preview: manifest?.preview || false
191
+ },
192
+ publisher: publisherInfo,
193
+ publisherId: publisherInfo?.id || '',
194
+ installed: registryExt.installed || false,
195
+ updatedAt: registryExt.updatedAt,
196
+ url: registryExt.url,
197
+ remoteURL: registryExt.remoteURL,
198
+ status: ExtensionRegistryStatus.Active,
199
+ viewerCanAdminister: registryExt.viewerCanAdminister || false,
200
+ isLocal: registryExt.isLocal || false,
201
+ categories: manifest?.categories || [],
202
+ tags: manifest?.tags || manifest?.keywords || [],
203
+ releases: registryExt.releases || [],
204
+ downloadCount: 0,
205
+ installCount: 0,
206
+ weeklyDownloads: 0,
207
+ rating: 0,
208
+ ratingCount: 0,
209
+ featured: false,
210
+ preview: manifest?.preview || false,
211
+ date: registryExt.updatedAt?.toISOString(),
212
+ assets: {
213
+ __typename: 'GalleryExtensionAssets',
214
+ icon: {
215
+ __typename: 'GalleryExtensionAsset',
216
+ uri: manifest?.icon || './media/defaultIcon.png',
217
+ fallbackUri: './media/defaultIcon.png'
218
+ },
219
+ readme: {
220
+ __typename: 'GalleryExtensionAsset',
221
+ uri: `${registryExt.url}/README.md`,
222
+ fallbackUri: `${registryExt.url}/README.md`
223
+ },
224
+ changelog: {
225
+ __typename: 'GalleryExtensionAsset',
226
+ uri: `${registryExt.url}/CHANGELOG.md`,
227
+ fallbackUri: `${registryExt.url}/CHANGELOG.md`
228
+ },
229
+ license: {
230
+ __typename: 'GalleryExtensionAsset',
231
+ uri: `${registryExt.url}/LICENSE`,
232
+ fallbackUri: `${registryExt.url}/LICENSE`
233
+ },
234
+ download: {
235
+ __typename: 'GalleryExtensionAsset',
236
+ uri: `${registryExt.url}/${registryExt.version}.vsix`,
237
+ fallbackUri: `${registryExt.url}/${registryExt.version}.vsix`
238
+ },
239
+ manifest: {
240
+ __typename: 'GalleryExtensionAsset',
241
+ uri: `${registryExt.url}/package.json`,
242
+ fallbackUri: `${registryExt.url}/package.json`
243
+ }
244
+ },
245
+ properties: {
246
+ __typename: 'GalleryExtensionProperties',
247
+ dependencies: manifest?.extensionDependencies || [],
248
+ extensionPack: manifest?.extensionPack || [],
249
+ engine: manifest?.engines?.vscode || 'unknown',
250
+ localizedLanguages: []
251
+ },
252
+ resources: {
253
+ __typename: 'GalleryExtensionResources',
254
+ license: `${registryExt.url}/LICENSE`,
255
+ repository: manifest?.repository?.url || '',
256
+ changelog: `${registryExt.url}/CHANGELOG.md`,
257
+ download: `${registryExt.url}/${registryExt.version}.vsix`,
258
+ icon: manifest?.icon || './media/defaultIcon.png',
259
+ manifest: rawManifest || `${registryExt.url}/package.json`,
260
+ // Store raw manifest JSON string
261
+ readme: `${registryExt.url}/README.md`
262
+ },
263
+ coreExtension: registryExt,
264
+ identifier: {
265
+ __typename: 'ExtensionIdentifier',
266
+ id: registryExt.extensionSlug || registryExt.id,
267
+ uuid: registryExt.uuid
268
+ }
269
+ };
270
+ return galleryExtension;
271
+ }
272
+ async getAllVersions(extension) {
273
+ this.logger.trace('ExtensionGalleryService.getAllVersions: %s', extension.id);
274
+ try {
275
+ // Get all versions from registry
276
+ const allExtensions = await this.registryExtensionService.findExtensions(1000,
277
+ // Get more versions
278
+ `${extension.publisher.displayName}.${extension.name}`, true, true);
279
+ // Filter to get all versions of the same extension
280
+ const extensionVersions = allExtensions.filter(ext => ext.name === extension.name);
281
+ // Convert all to gallery extensions and sort by version (newest first)
282
+ const galleryVersions = await Promise.all(extensionVersions.map(ext => this.toGalleryExtension(ext)));
283
+ // Sort by version (descending)
284
+ return galleryVersions.sort((a, b) => b.version.localeCompare(a.version, undefined, {
285
+ numeric: true
286
+ }));
287
+ } catch (error) {
288
+ this.logger.warn('Failed to get all versions for %s: %s', extension.id, error.message);
289
+ // Return empty array if we can't find versions
290
+ return [];
291
+ }
292
+ }
293
+ /**
294
+ * Helper method to get manifest from the current release
295
+ * Since manifests are stored in releases, not directly in the registry extension
296
+ */
297
+ getManifestFromRelease(registryExt) {
298
+ const {
299
+ releases
300
+ } = registryExt;
301
+ if (!releases || releases.length === 0) {
302
+ return null;
303
+ }
304
+ // Find the current release that matches the extension's version
305
+ const currentRelease = releases.find(release => release.version === registryExt.version);
306
+ if (!currentRelease || !currentRelease.manifest) {
307
+ // If no matching release, try the first release
308
+ const firstRelease = releases[0];
309
+ if (!firstRelease || !firstRelease.manifest) {
310
+ return null;
311
+ }
312
+ try {
313
+ // Parse the manifest from the release (stored as JSON string or object)
314
+ const parsedManifest = typeof firstRelease.manifest === 'string' ? JSON.parse(firstRelease.manifest) : firstRelease.manifest;
315
+ return parsedManifest;
316
+ } catch (error) {
317
+ this.logger.warn('Failed to parse extension manifest for', registryExt.extensionSlug, ':', error);
318
+ return null;
319
+ }
320
+ }
321
+ try {
322
+ // Parse the manifest from the release (stored as JSON string or object)
323
+ const parsedManifest = typeof currentRelease.manifest === 'string' ? JSON.parse(currentRelease.manifest) : currentRelease.manifest;
324
+ return parsedManifest;
325
+ } catch (error) {
326
+ this.logger.warn('Failed to parse extension manifest for', registryExt.extensionSlug, ':', error);
327
+ return null;
328
+ }
329
+ }
330
+ dispose() {
331
+ this.disposables.dispose();
332
+ }
333
+ };
334
+ ExtensionGalleryService = __decorate([injectable(), __param(0, inject('Logger')), __param(1, inject(SERVER_TYPES.IRegistryExtensionService)), __param(2, inject(SERVER_TYPES.IMarketplacePublisherService)), __param(3, inject(SERVER_TYPES.IExtensionGalleryRepository)), __metadata("design:paramtypes", [Object, Object, Object, Object])], ExtensionGalleryService);export{ExtensionGalleryService};//# sourceMappingURL=extension-gallery-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-gallery-service.js","sources":["../../src/services/extension-gallery-service.ts"],"sourcesContent":[null],"names":[],"mappings":"0PAgCQ,uBAAiB,GAAA,MAAA,uBAAgB,CAAA;QAEjC;AAbJ,EAAA,wBAAiB;AAEjB,EAAA,gBAAQ;AAER,EAAA;AAGuC,EAAA,WAAA,GAAA,IAAA,oBAAkB;AAWlD,EAAA,eAAa,IAAA,OAAO,EAAA;oBAIC,CAAA,YAAkB,MAAG;AAkCpC,EAAA,WAAA,CAAA,MAAa,EAAA,wBAAY,EAAA,gBAAgC,EAAA,iBAAQ,EAAA;IAqBjE,IAAA,CAAA,eAAoB;IAkBpB,IAAA,CAAA,wBAAqB,GAAA,wBAAmC;IAsBxD,IAAA,CAAA,gBAAqB,GAAE,gBAAiB;IAuBxC,IAAA,CAAA,iBAAsB,GAAE;IAsBxB,IAAA,CAAA,gBAAoB,CAAE,IAAA,CAAA,YAAiB;;cA4DtC;IA0ID,OAAA,IAAA;AA2Bb,EAAA;;;AAGG,IAAA,IAAA;AACH,MAAA,MAAQ;AA8CD,QAAA,OAAW,EAAA;AAGrB,QAAA,QAAA,GAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,2 +1,7 @@
1
- export * from './extension-service';
1
+ export * from './installed-extension-service';
2
+ export * from './installed-extension-service-ext';
3
+ export * from './publisher-service';
4
+ export * from './publisher-event-service';
5
+ export * from './extension-gallery-service';
6
+ export * from './extension-gallery-repository';
2
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { ServiceBroker } from 'moleculer';
2
+ import { CdmLogger } from '@cdm-logger/core';
3
+ import { IRegistryExtensionService, IInstalledExtensionRepository, ISlugService, IRedisCacheManager } from 'common/server';
4
+ import { InstalledExtensionService } from './installed-extension-service';
5
+ /**
6
+ * Extended InstalledExtensionService that handles Moleculer event broadcasting
7
+ * Follows the pattern of AccountService/AccountServiceExt
8
+ */
9
+ export declare class InstalledExtensionServiceExt extends InstalledExtensionService {
10
+ protected slugService: ISlugService;
11
+ protected readonly redisCacheManager: IRedisCacheManager;
12
+ constructor(repository: IInstalledExtensionRepository, registryService: IRegistryExtensionService, slugService: ISlugService, redisCacheManager: IRedisCacheManager, broker: ServiceBroker, logger: CdmLogger.ILogger);
13
+ private setupEventListeners;
14
+ private dropCache;
15
+ }
16
+ //# sourceMappingURL=installed-extension-service-ext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installed-extension-service-ext.d.ts","sourceRoot":"","sources":["../../src/services/installed-extension-service-ext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAgBH,yBAAyB,EACzB,6BAA6B,EAO7B,YAAY,EACZ,kBAAkB,EACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AA0D1E;;;GAGG;AACH,qBACa,4BAA6B,SAAQ,yBAAyB;IAKnE,SAAS,CAAC,WAAW,EAAE,YAAY;IAEnC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,kBAAkB;gBALJ,UAAU,EAAE,6BAA6B,EAC7C,eAAe,EAAE,yBAAyB,EAEhF,WAAW,EAAE,YAAY,EAEhB,iBAAiB,EAAE,kBAAkB,EACnB,MAAM,EAAE,aAAa,EAC/B,MAAM,EAAE,SAAS,CAAC,OAAO;IAMxD,OAAO,CAAC,mBAAmB;YA6gBb,SAAS;CA8C1B"}