@@ -12,6 +12,7 @@ import * as Parser from 'tree-sitter';
12
12
import fetch from 'node-fetch' ;
13
13
const { typescript } = require ( 'tree-sitter-typescript' ) ;
14
14
const product = require ( '../../product.json' ) ;
15
+ const packageJson = require ( '../../package.json' ) ;
15
16
16
17
type NlsString = { value : string ; nlsKey : string } ;
17
18
@@ -587,17 +588,13 @@ const Languages = {
587
588
type LanguageTranslations = { [ moduleName : string ] : { [ nlsKey : string ] : string } } ;
588
589
type Translations = { languageId : string ; languageTranslations : LanguageTranslations } [ ] ;
589
590
590
- async function getLatestStableVersion ( updateUrl : string ) {
591
- const res = await fetch ( `${ updateUrl } /api/update/darwin/stable/latest` ) ;
592
- const { name : version } = await res . json ( ) as { name : string } ;
593
- return version ;
594
- }
591
+ type Version = [ number , number , number ] ;
595
592
596
- async function getSpecificNLS ( resourceUrlTemplate : string , languageId : string , version : string ) {
593
+ async function getSpecificNLS ( resourceUrlTemplate : string , languageId : string , version : Version ) {
597
594
const resource = {
598
595
publisher : 'ms-ceintl' ,
599
596
name : `vscode-language-pack-${ languageId } ` ,
600
- version,
597
+ version : ` ${ version [ 0 ] } . ${ version [ 1 ] } . ${ version [ 2 ] } ` ,
601
598
path : 'extension/translations/main.i18n.json'
602
599
} ;
603
600
@@ -612,32 +609,50 @@ async function getSpecificNLS(resourceUrlTemplate: string, languageId: string, v
612
609
return result ;
613
610
}
614
611
615
- function previousVersion ( version : string ) : string {
616
- const [ , major , minor , patch ] = / ^ ( \d + ) \. ( \d + ) \. ( \d + ) $ / . exec ( version ) ! ;
617
- return `${ major } .${ parseInt ( minor ) - 1 } .${ patch } ` ;
618
- }
619
-
620
- async function getNLS ( resourceUrlTemplate : string , languageId : string , version : string ) {
621
- try {
622
- return await getSpecificNLS ( resourceUrlTemplate , languageId , version ) ;
623
- } catch ( err ) {
624
- if ( / \[ 4 0 4 \] / . test ( err . message ) ) {
625
- const thePreviousVersion = previousVersion ( version ) ;
626
- console . warn ( `Language pack ${ languageId } @${ version } is missing. Downloading previous version ${ thePreviousVersion } ...` ) ;
627
- try {
628
- return await getSpecificNLS ( resourceUrlTemplate , languageId , thePreviousVersion ) ;
629
- } catch ( err ) {
630
- if ( / \[ 4 0 4 \] / . test ( err . message ) ) {
631
- console . warn ( `Language pack ${ languageId } @${ thePreviousVersion } is missing. Downloading previous version...` ) ;
632
- return await getSpecificNLS ( resourceUrlTemplate , languageId , previousVersion ( thePreviousVersion ) ) ;
633
- } else {
634
- throw err ;
635
- }
636
- }
637
- } else {
638
- throw err ;
639
- }
612
+ function parseVersion ( version : string ) : Version {
613
+ const [ , major , minor , patch ] = / ^ ( \d + ) \. ( \d + ) \. ( \d + ) / . exec ( version ) ! ;
614
+ return [ parseInt ( major ) , parseInt ( minor ) , parseInt ( patch ) ] ;
615
+ }
616
+
617
+ function compareVersions ( a : Version , b : Version ) : number {
618
+ if ( a [ 0 ] !== b [ 0 ] ) { return a [ 0 ] - b [ 0 ] ; }
619
+ if ( a [ 1 ] !== b [ 1 ] ) { return a [ 1 ] - b [ 1 ] ; }
620
+ return a [ 2 ] - b [ 2 ] ;
621
+ }
622
+
623
+ async function queryVersions ( serviceUrl : string , languageId : string ) : Promise < Version [ ] > {
624
+ const res = await fetch ( `${ serviceUrl } /extensionquery` , {
625
+ method : 'POST' ,
626
+ headers : {
627
+ 'Accept' : 'application/json;api-version=3.0-preview.1' ,
628
+ 'Content-Type' : 'application/json' ,
629
+ 'User-Agent' : 'VS Code Build' ,
630
+ } ,
631
+ body : JSON . stringify ( {
632
+ filters : [ { criteria : [ { filterType : 7 , value : `ms-ceintl.vscode-language-pack-${ languageId } ` } ] } ] ,
633
+ flags : 0x1
634
+ } )
635
+ } ) ;
636
+
637
+ if ( res . status !== 200 ) {
638
+ throw new Error ( `[${ res . status } ] Error querying for extension: ${ languageId } ` ) ;
639
+ }
640
+
641
+ const result = await res . json ( ) as { results : [ { extensions : { versions : { version : string } [ ] } [ ] } ] } ;
642
+ return result . results [ 0 ] . extensions [ 0 ] . versions . map ( v => parseVersion ( v . version ) ) . sort ( compareVersions ) ;
643
+ }
644
+
645
+ async function getNLS ( extensionGalleryServiceUrl : string , resourceUrlTemplate : string , languageId : string , version : Version ) {
646
+ const versions = await queryVersions ( extensionGalleryServiceUrl , languageId ) ;
647
+ const nextMinor : Version = [ version [ 0 ] , version [ 1 ] + 1 , 0 ] ;
648
+ const compatibleVersions = versions . filter ( v => compareVersions ( v , nextMinor ) < 0 ) ;
649
+ const latestCompatibleVersion = compatibleVersions . at ( - 1 ) ! ; // order is newest to oldest
650
+
651
+ if ( ! latestCompatibleVersion ) {
652
+ throw new Error ( `No compatible language pack found for ${ languageId } for version ${ version } ` ) ;
640
653
}
654
+
655
+ return await getSpecificNLS ( resourceUrlTemplate , languageId , latestCompatibleVersion ) ;
641
656
}
642
657
643
658
async function parsePolicies ( ) : Promise < Policy [ ] > {
@@ -659,10 +674,10 @@ async function parsePolicies(): Promise<Policy[]> {
659
674
}
660
675
661
676
async function getTranslations ( ) : Promise < Translations > {
662
- const updateUrl = product . updateUrl ;
677
+ const extensionGalleryServiceUrl = product . extensionsGallery ?. serviceUrl ;
663
678
664
- if ( ! updateUrl ) {
665
- console . warn ( `Skipping policy localization: No 'updateUrl ' found in 'product.json'.` ) ;
679
+ if ( ! extensionGalleryServiceUrl ) {
680
+ console . warn ( `Skipping policy localization: No 'extensionGallery.serviceUrl ' found in 'product.json'.` ) ;
666
681
return [ ] ;
667
682
}
668
683
@@ -673,11 +688,11 @@ async function getTranslations(): Promise<Translations> {
673
688
return [ ] ;
674
689
}
675
690
676
- const version = await getLatestStableVersion ( updateUrl ) ;
691
+ const version = parseVersion ( packageJson . version ) ;
677
692
const languageIds = Object . keys ( Languages ) ;
678
693
679
694
return await Promise . all ( languageIds . map (
680
- languageId => getNLS ( resourceUrlTemplate , languageId , version )
695
+ languageId => getNLS ( extensionGalleryServiceUrl , resourceUrlTemplate , languageId , version )
681
696
. then ( languageTranslations => ( { languageId, languageTranslations } ) )
682
697
) ) ;
683
698
}
0 commit comments