@@ -3,13 +3,37 @@ import { execSync } from "child_process";
3
3
import { outputFile , readFile , readJSON } from "fs-extra" ;
4
4
import { getVersionInformation } from "./util/vscode-versions" ;
5
5
import { fetchJson } from "./util/fetch" ;
6
+ import { SemVer } from "semver" ;
6
7
7
8
const extensionDirectory = resolve ( __dirname , ".." ) ;
8
9
9
10
interface Release {
10
11
tag_name : string ;
11
12
}
12
13
14
+ interface NpmViewError {
15
+ error : {
16
+ code : string ;
17
+ summary : string ;
18
+ detail : string ;
19
+ } ;
20
+ }
21
+
22
+ interface ExecError extends Error {
23
+ status : number ;
24
+ stdout : string ;
25
+ }
26
+
27
+ function isExecError ( e : unknown ) : e is ExecError {
28
+ return (
29
+ e instanceof Error &&
30
+ "status" in e &&
31
+ typeof e . status === "number" &&
32
+ "stdout" in e &&
33
+ typeof e . stdout === "string"
34
+ ) ;
35
+ }
36
+
13
37
async function updateNodeVersion ( ) {
14
38
const latestVsCodeRelease = await fetchJson < Release > (
15
39
"https://api.github.com/repos/microsoft/vscode/releases/latest" ,
@@ -49,20 +73,64 @@ async function updateNodeVersion() {
49
73
"utf8" ,
50
74
) ;
51
75
76
+ const nodeVersion = new SemVer ( versionInformation . nodeVersion ) ;
77
+
52
78
// The @types /node version needs to match the first two parts of the Node
53
79
// version, e.g. if the Node version is 18.17.3, the @types/node version
54
80
// should be 18.17.*. This corresponds with the documentation at
55
81
// https://github.com/definitelytyped/definitelytyped#how-do-definitely-typed-package-versions-relate-to-versions-of-the-corresponding-library
56
82
// "The patch version of the type declaration package is unrelated to the library patch version. This allows
57
83
// Definitely Typed to safely update type declarations for the same major/minor version of a library."
58
84
// 18.17.* is equivalent to >=18.17.0 <18.18.0
59
- const typesNodeVersion = versionInformation . nodeVersion
60
- . split ( "." )
61
- . slice ( 0 , 2 )
62
- . join ( "." ) ;
85
+ // In some cases, the @types/node version matching the exact Node version may not exist, in which case we'll try
86
+ // the next lower minor version, and so on, until we find a version that exists.
87
+ const typesNodeSemver = new SemVer ( nodeVersion ) ;
88
+ typesNodeSemver . patch = 0 ;
89
+
90
+ // eslint-disable-next-line no-constant-condition
91
+ while ( true ) {
92
+ const typesNodeVersion = `${ typesNodeSemver . major } .${ typesNodeSemver . minor } .*` ;
93
+
94
+ try {
95
+ // Check that this version actually exists
96
+ console . log ( `Checking if @types/node@${ typesNodeVersion } exists` ) ;
97
+
98
+ execSync ( `npm view --json "@types/node@${ typesNodeVersion } "` , {
99
+ encoding : "utf-8" ,
100
+ stdio : "pipe" ,
101
+ } ) ;
102
+
103
+ console . log ( `@types/node@${ typesNodeVersion } exists` ) ;
104
+
105
+ // If it exists, we can break out of this loop
106
+ break ;
107
+ } catch ( e : unknown ) {
108
+ if ( ! isExecError ( e ) ) {
109
+ throw e ;
110
+ }
111
+
112
+ const error = JSON . parse ( e . stdout ) as NpmViewError ;
113
+ if ( error . error . code !== "E404" ) {
114
+ throw new Error ( error . error . detail ) ;
115
+ }
116
+
117
+ console . log (
118
+ `@types/node package doesn't exist for ${ typesNodeVersion } , trying a lower version (${ error . error . summary } )` ,
119
+ ) ;
120
+
121
+ // This means the version doesn't exist, so we'll try decrementing the minor version
122
+ typesNodeSemver . minor -= 1 ;
123
+ if ( typesNodeSemver . minor < 0 ) {
124
+ throw new Error (
125
+ `Could not find a suitable @types/node version for Node ${ nodeVersion . format ( ) } ` ,
126
+ ) ;
127
+ }
128
+ }
129
+ }
63
130
64
131
packageJson . engines . node = `^${ versionInformation . nodeVersion } ` ;
65
- packageJson . devDependencies [ "@types/node" ] = `${ typesNodeVersion } .*` ;
132
+ packageJson . devDependencies [ "@types/node" ] =
133
+ `${ typesNodeSemver . major } .${ typesNodeSemver . minor } .*` ;
66
134
67
135
await outputFile (
68
136
join ( extensionDirectory , "package.json" ) ,
0 commit comments