@@ -45,6 +45,14 @@ import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/use
45
45
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity' ;
46
46
47
47
type GalleryExtensionInfo = { readonly id : string ; preRelease ?: boolean ; migrateStorageFrom ?: string } ;
48
+ interface HostedExtensionInfo {
49
+ readonly location : UriComponents ;
50
+ readonly preRelease ?: boolean ;
51
+ readonly packageNLSUris ?: Map < string , UriComponents > ;
52
+ readonly fallbackPackageNLSUri ?: UriComponents ;
53
+ readonly readmeUri ?: UriComponents ;
54
+ readonly changelogUri ?: UriComponents ;
55
+ }
48
56
type ExtensionInfo = { readonly id : string ; preRelease : boolean } ;
49
57
50
58
function isGalleryExtensionInfo ( obj : unknown ) : obj is GalleryExtensionInfo {
@@ -54,6 +62,23 @@ function isGalleryExtensionInfo(obj: unknown): obj is GalleryExtensionInfo {
54
62
&& ( galleryExtensionInfo . migrateStorageFrom === undefined || typeof galleryExtensionInfo . migrateStorageFrom === 'string' ) ;
55
63
}
56
64
65
+ function isHostedExtensionInfo ( obj : unknown ) : obj is HostedExtensionInfo {
66
+ const hostedExtensionInfo = obj as HostedExtensionInfo | undefined ;
67
+ return isUriComponents ( hostedExtensionInfo ?. location )
68
+ && ( hostedExtensionInfo ?. preRelease === undefined || typeof hostedExtensionInfo . preRelease === 'boolean' )
69
+ && ( hostedExtensionInfo ?. fallbackPackageNLSUri === undefined || isUriComponents ( hostedExtensionInfo ?. fallbackPackageNLSUri ) )
70
+ && ( hostedExtensionInfo ?. changelogUri === undefined || isUriComponents ( hostedExtensionInfo ?. changelogUri ) )
71
+ && ( hostedExtensionInfo ?. readmeUri === undefined || isUriComponents ( hostedExtensionInfo ?. readmeUri ) ) ;
72
+ }
73
+
74
+ function isUriComponents ( thing : unknown ) : thing is UriComponents {
75
+ if ( ! thing ) {
76
+ return false ;
77
+ }
78
+ return isString ( ( < any > thing ) . path ) &&
79
+ isString ( ( < any > thing ) . scheme ) ;
80
+ }
81
+
57
82
interface IStoredWebExtension {
58
83
readonly identifier : IExtensionIdentifier ;
59
84
readonly version : string ;
@@ -117,12 +142,12 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten
117
142
}
118
143
}
119
144
120
- private _customBuiltinExtensionsInfoPromise : Promise < { extensions : ExtensionInfo [ ] ; extensionsToMigrate : [ string , string ] [ ] ; extensionLocations : URI [ ] } > | undefined ;
121
- private readCustomBuiltinExtensionsInfoFromEnv ( ) : Promise < { extensions : ExtensionInfo [ ] ; extensionsToMigrate : [ string , string ] [ ] ; extensionLocations : URI [ ] } > {
145
+ private _customBuiltinExtensionsInfoPromise : Promise < { extensions : ExtensionInfo [ ] ; extensionsToMigrate : [ string , string ] [ ] ; extensionLocations : HostedExtensionInfo [ ] } > | undefined ;
146
+ private readCustomBuiltinExtensionsInfoFromEnv ( ) : Promise < { extensions : ExtensionInfo [ ] ; extensionsToMigrate : [ string , string ] [ ] ; extensionLocations : HostedExtensionInfo [ ] } > {
122
147
if ( ! this . _customBuiltinExtensionsInfoPromise ) {
123
148
this . _customBuiltinExtensionsInfoPromise = ( async ( ) => {
124
149
let extensions : ExtensionInfo [ ] = [ ] ;
125
- const extensionLocations : URI [ ] = [ ] ;
150
+ const extensionLocations : HostedExtensionInfo [ ] = [ ] ;
126
151
const extensionsToMigrate : [ string , string ] [ ] = [ ] ;
127
152
const customBuiltinExtensionsInfo = this . environmentService . options && Array . isArray ( this . environmentService . options . additionalBuiltinExtensions )
128
153
? this . environmentService . options . additionalBuiltinExtensions . map ( additionalBuiltinExtension => isString ( additionalBuiltinExtension ) ? { id : additionalBuiltinExtension } : additionalBuiltinExtension )
@@ -134,7 +159,11 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten
134
159
extensionsToMigrate . push ( [ e . migrateStorageFrom , e . id ] ) ;
135
160
}
136
161
} else {
137
- extensionLocations . push ( URI . revive ( e ) ) ;
162
+ if ( isHostedExtensionInfo ( e ) ) {
163
+ extensionLocations . push ( e ) ;
164
+ } else {
165
+ extensionLocations . push ( { location : e } ) ;
166
+ }
138
167
}
139
168
}
140
169
if ( extensions . length ) {
@@ -212,9 +241,14 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten
212
241
return [ ] ;
213
242
}
214
243
const result : IScannedExtension [ ] = [ ] ;
215
- await Promise . allSettled ( extensionLocations . map ( async location => {
244
+ await Promise . allSettled ( extensionLocations . map ( async ( { location, preRelease , packageNLSUris , fallbackPackageNLSUri , readmeUri , changelogUri } ) => {
216
245
try {
217
- const webExtension = await this . toWebExtension ( location ) ;
246
+ const webExtension = await this . toWebExtension ( URI . revive ( location ) , undefined ,
247
+ packageNLSUris ? [ ...packageNLSUris . entries ( ) ] . reduce ( ( result , [ key , value ] ) => { result . set ( key , URI . revive ( value ) ) ; return result ; } , new Map < string , URI > ( ) ) : undefined ,
248
+ URI . revive ( fallbackPackageNLSUri ) ,
249
+ URI . revive ( readmeUri ) ,
250
+ URI . revive ( changelogUri ) ,
251
+ { preRelease } ) ;
218
252
const extension = await this . toScannedExtension ( webExtension , true ) ;
219
253
if ( extension . isValid || ! scanOptions ?. skipInvalidExtensions ) {
220
254
result . push ( extension ) ;
0 commit comments