@@ -4,13 +4,79 @@ import path from 'node:path';
44const ROOT = process . cwd ( ) ;
55const META_DIR = process . env . UPGRADE_DEPS_META_DIR ;
66
7- const isFullSha = ( s ) => / ^ [ 0 - 9 a - f ] { 40 } $ / . test ( s ) ;
7+ type Change = {
8+ old : string | null ;
9+ new : string ;
10+ tag ?: string ;
11+ } ;
12+
13+ type GitHubTag = {
14+ name ?: unknown ;
15+ commit ?: {
16+ sha ?: unknown ;
17+ } ;
18+ } ;
19+
20+ type LatestTag = {
21+ sha : string ;
22+ tag : string ;
23+ } ;
824
9- /** @type {Map<string, { old: string | null, new: string, tag?: string }> } */
10- const changes = new Map ( ) ;
25+ type NpmLatestResponse = {
26+ version ?: unknown ;
27+ } ;
1128
12- function recordChange ( name , oldValue , newValue , tag ) {
13- const entry = { old : oldValue ?? null , new : newValue } ;
29+ type UpstreamVersions = {
30+ rolldown : {
31+ hash : string ;
32+ } ;
33+ vite : {
34+ hash : string ;
35+ } ;
36+ } ;
37+
38+ type PnpmWorkspaceVersions = {
39+ vitest : string ;
40+ tsdown : string ;
41+ oxcNodeCli : string ;
42+ oxcNodeCore : string ;
43+ oxfmt : string ;
44+ oxlint : string ;
45+ oxlintTsgolint : string ;
46+ oxcProjectRuntime : string ;
47+ oxcProjectTypes : string ;
48+ oxcMinify : string ;
49+ oxcParser : string ;
50+ oxcTransform : string ;
51+ } ;
52+
53+ type PnpmWorkspaceEntry = {
54+ name : string ;
55+ pattern : RegExp ;
56+ replacement : string ;
57+ newVersion : string ;
58+ } ;
59+
60+ type PackageJson = {
61+ devDependencies ?: Record < string , string > ;
62+ peerDependencies ?: Record < string , string > ;
63+ } ;
64+
65+ const isFullSha = ( s : string ) : boolean => / ^ [ 0 - 9 a - f ] { 40 } $ / . test ( s ) ;
66+
67+ const changes = new Map < string , Change > ( ) ;
68+
69+ function readJsonFile ( filePath : string ) {
70+ return JSON . parse ( fs . readFileSync ( filePath , 'utf8' ) ) ;
71+ }
72+
73+ function recordChange (
74+ name : string ,
75+ oldValue : string | null | undefined ,
76+ newValue : string ,
77+ tag ?: string ,
78+ ) {
79+ const entry : Change = { old : oldValue ?? null , new : newValue } ;
1480 if ( tag ) {
1581 entry . tag = tag ;
1682 }
@@ -23,7 +89,7 @@ function recordChange(name, oldValue, newValue, tag) {
2389}
2490
2591// ============ GitHub API ============
26- async function getLatestTag ( owner , repo ) {
92+ async function getLatestTag ( owner : string , repo : string ) : Promise < LatestTag > {
2793 const res = await fetch ( `https://api.github.com/repos/${ owner } /${ repo } /tags?per_page=1` , {
2894 headers : {
2995 Authorization : `token ${ process . env . GITHUB_TOKEN } ` ,
@@ -33,45 +99,46 @@ async function getLatestTag(owner, repo) {
3399 if ( ! res . ok ) {
34100 throw new Error ( `Failed to fetch tags for ${ owner } /${ repo } : ${ res . status } ${ res . statusText } ` ) ;
35101 }
36- const tags = await res . json ( ) ;
102+ const tags = ( await res . json ( ) ) as GitHubTag [ ] ;
37103 if ( ! Array . isArray ( tags ) || ! tags . length ) {
38104 throw new Error ( `No tags found for ${ owner } /${ repo } ` ) ;
39105 }
40- if ( ! tags [ 0 ] ?. commit ?. sha || ! tags [ 0 ] ?. name ) {
106+ const [ latest ] = tags ;
107+ if ( typeof latest ?. commit ?. sha !== 'string' || typeof latest . name !== 'string' ) {
41108 throw new Error ( `Invalid tag structure for ${ owner } /${ repo } : missing SHA or name` ) ;
42109 }
43- console . log ( `${ repo } -> ${ tags [ 0 ] . name } (${ tags [ 0 ] . commit . sha . slice ( 0 , 7 ) } )` ) ;
44- return { sha : tags [ 0 ] . commit . sha , tag : tags [ 0 ] . name } ;
110+ console . log ( `${ repo } -> ${ latest . name } (${ latest . commit . sha . slice ( 0 , 7 ) } )` ) ;
111+ return { sha : latest . commit . sha , tag : latest . name } ;
45112}
46113
47114// ============ npm Registry ============
48- async function getLatestNpmVersion ( packageName ) {
115+ async function getLatestNpmVersion ( packageName : string ) : Promise < string > {
49116 const res = await fetch ( `https://registry.npmjs.org/${ packageName } /latest` ) ;
50117 if ( ! res . ok ) {
51118 throw new Error (
52119 `Failed to fetch npm version for ${ packageName } : ${ res . status } ${ res . statusText } ` ,
53120 ) ;
54121 }
55- const data = await res . json ( ) ;
56- if ( ! data ? .version ) {
122+ const data = ( await res . json ( ) ) as NpmLatestResponse ;
123+ if ( typeof data . version !== 'string' ) {
57124 throw new Error ( `Invalid npm response for ${ packageName } : missing version field` ) ;
58125 }
59126 return data . version ;
60127}
61128
62129// ============ Update .upstream-versions.json ============
63- async function updateUpstreamVersions ( ) {
130+ async function updateUpstreamVersions ( ) : Promise < void > {
64131 const filePath = path . join ( ROOT , 'packages/tools/.upstream-versions.json' ) ;
65- const data = JSON . parse ( fs . readFileSync ( filePath , 'utf8' ) ) ;
132+ const data : UpstreamVersions = readJsonFile ( filePath ) ;
66133
67134 const oldRolldownHash = data . rolldown . hash ;
68- const oldViteHash = data [ ' vite' ] . hash ;
135+ const oldViteHash = data . vite . hash ;
69136 const [ rolldown , vite ] = await Promise . all ( [
70137 getLatestTag ( 'rolldown' , 'rolldown' ) ,
71138 getLatestTag ( 'vitejs' , 'vite' ) ,
72139 ] ) ;
73140 data . rolldown . hash = rolldown . sha ;
74- data [ ' vite' ] . hash = vite . sha ;
141+ data . vite . hash = vite . sha ;
75142 recordChange ( 'rolldown' , oldRolldownHash , rolldown . sha , rolldown . tag ) ;
76143 recordChange ( 'vite' , oldViteHash , vite . sha , vite . tag ) ;
77144
@@ -80,12 +147,12 @@ async function updateUpstreamVersions() {
80147}
81148
82149// ============ Update pnpm-workspace.yaml ============
83- async function updatePnpmWorkspace ( versions ) {
150+ async function updatePnpmWorkspace ( versions : PnpmWorkspaceVersions ) : Promise < void > {
84151 const filePath = path . join ( ROOT , 'pnpm-workspace.yaml' ) ;
85152 let content = fs . readFileSync ( filePath , 'utf8' ) ;
86153
87154 // oxlint's trailing \n in the pattern disambiguates from oxlint-tsgolint.
88- const entries = [
155+ const entries : PnpmWorkspaceEntry [ ] = [
89156 {
90157 name : 'vitest' ,
91158 pattern : / v i t e s t - d e v : n p m : v i t e s t @ \^ ( [ \d . ] + (?: - [ \w . ] + ) ? ) / ,
@@ -161,15 +228,15 @@ async function updatePnpmWorkspace(versions) {
161228 ] ;
162229
163230 for ( const { name, pattern, replacement, newVersion } of entries ) {
164- let oldVersion ;
165- content = content . replace ( pattern , ( _match , captured ) => {
231+ let oldVersion : string | undefined ;
232+ content = content . replace ( pattern , ( _match : string , captured : string ) => {
166233 oldVersion = captured ;
167234 return replacement ;
168235 } ) ;
169236 if ( oldVersion === undefined ) {
170237 throw new Error (
171238 `Failed to match ${ name } in pnpm-workspace.yaml — the pattern ${ pattern } is stale, ` +
172- `please update it in .github/scripts/upgrade-deps.mjs ` ,
239+ `please update it in .github/scripts/upgrade-deps.ts ` ,
173240 ) ;
174241 }
175242 recordChange ( name , oldVersion , newVersion ) ;
@@ -180,20 +247,24 @@ async function updatePnpmWorkspace(versions) {
180247}
181248
182249// ============ Update packages/test/package.json ============
183- async function updateTestPackage ( vitestVersion ) {
250+ async function updateTestPackage ( vitestVersion : string ) : Promise < void > {
184251 const filePath = path . join ( ROOT , 'packages/test/package.json' ) ;
185- const pkg = JSON . parse ( fs . readFileSync ( filePath , 'utf8' ) ) ;
252+ const pkg : PackageJson = readJsonFile ( filePath ) ;
253+ const devDependencies = pkg . devDependencies ;
254+ if ( ! devDependencies ) {
255+ throw new Error ( 'packages/test/package.json is missing devDependencies' ) ;
256+ }
186257
187258 // Update all @vitest /* devDependencies
188- for ( const dep of Object . keys ( pkg . devDependencies ) ) {
259+ for ( const dep of Object . keys ( devDependencies ) ) {
189260 if ( dep . startsWith ( '@vitest/' ) ) {
190- pkg . devDependencies [ dep ] = vitestVersion ;
261+ devDependencies [ dep ] = vitestVersion ;
191262 }
192263 }
193264
194265 // Update vitest-dev devDependency
195- if ( pkg . devDependencies [ 'vitest-dev' ] ) {
196- pkg . devDependencies [ 'vitest-dev' ] = `^${ vitestVersion } ` ;
266+ if ( devDependencies [ 'vitest-dev' ] ) {
267+ devDependencies [ 'vitest-dev' ] = `^${ vitestVersion } ` ;
197268 }
198269
199270 // Update @vitest /ui peerDependency if present
@@ -206,23 +277,24 @@ async function updateTestPackage(vitestVersion) {
206277}
207278
208279// ============ Update packages/core/package.json ============
209- async function updateCorePackage ( devtoolsVersion ) {
280+ async function updateCorePackage ( devtoolsVersion : string ) : Promise < void > {
210281 const filePath = path . join ( ROOT , 'packages/core/package.json' ) ;
211- const pkg = JSON . parse ( fs . readFileSync ( filePath , 'utf8' ) ) ;
282+ const pkg : PackageJson = readJsonFile ( filePath ) ;
212283
213- const currentDevtools = pkg . devDependencies ?. [ '@vitejs/devtools' ] ;
284+ const devDependencies = pkg . devDependencies ;
285+ const currentDevtools = devDependencies ?. [ '@vitejs/devtools' ] ;
214286 if ( ! currentDevtools ) {
215287 return ;
216288 }
217- pkg . devDependencies [ '@vitejs/devtools' ] = `^${ devtoolsVersion } ` ;
289+ devDependencies [ '@vitejs/devtools' ] = `^${ devtoolsVersion } ` ;
218290 recordChange ( '@vitejs/devtools' , currentDevtools . replace ( / ^ [ \^ ~ ] / , '' ) , devtoolsVersion ) ;
219291
220292 fs . writeFileSync ( filePath , JSON . stringify ( pkg , null , 2 ) + '\n' ) ;
221293 console . log ( 'Updated packages/core/package.json' ) ;
222294}
223295
224296// ============ Write metadata files for PR description ============
225- function writeMetaFiles ( ) {
297+ function writeMetaFiles ( ) : void {
226298 if ( ! META_DIR ) {
227299 return ;
228300 }
@@ -238,7 +310,7 @@ function writeMetaFiles() {
238310 const changed = [ ...changes . entries ( ) ] . filter ( ( [ , v ] ) => v . old !== v . new ) ;
239311 const unchanged = [ ...changes . entries ( ) ] . filter ( ( [ , v ] ) => v . old === v . new ) ;
240312
241- const formatVersion = ( v ) => {
313+ const formatVersion = ( v : Change ) : string => {
242314 if ( v . tag ) {
243315 return `${ v . tag } (${ v . new . slice ( 0 , 7 ) } )` ;
244316 }
@@ -247,7 +319,7 @@ function writeMetaFiles() {
247319 }
248320 return v . new ;
249321 } ;
250- const formatOld = ( v ) => {
322+ const formatOld = ( v : Change ) : string => {
251323 if ( ! v . old ) {
252324 return '(unset)' ;
253325 }
0 commit comments