1
1
/* eslint-disable no-console */
2
- const {
3
- getInternals,
4
- npmView
5
- } = require ( './helpers/versioning' )
2
+ 'use strict'
3
+
4
+ const { getInternals } = require ( './helpers/versioning' )
6
5
const path = require ( 'path' )
7
6
const fs = require ( 'fs' )
8
7
const semver = require ( 'semver' )
8
+ const childProcess = require ( 'child_process' )
9
9
10
10
const latestsPath = path . join (
11
11
__dirname ,
@@ -17,25 +17,83 @@ const latestsPath = path.join(
17
17
'latests.json'
18
18
)
19
19
20
- // Get internal package names from existing getInternals helper
21
20
const internalsNames = Array . from ( new Set ( getInternals ( ) . map ( n => n . name ) ) )
22
21
. filter ( x => typeof x === 'string' && x !== 'child_process' && ! x . startsWith ( 'node:' ) )
23
22
24
- // Initial structure with placeholder for configuration
25
- const initialStructure = {
26
- pinned : [ 'ENTER_PACKAGE_NAME_HERE' ] ,
27
- onlyUseLatestTag : [ 'ENTER_PACKAGE_NAME_HERE' ] ,
23
+ // Packages that should be ignored during version checking - these won't be included in latests.json
24
+ const IGNORED_PACKAGES = [
25
+ // Add package names here
26
+ 'aerospike' , // I think this is due to architecture issues?
27
+ 'mariadb' , // mariadb esm tests were failing
28
+ 'microgateway-core' , // 'microgateway-core' was failing to find a directory
29
+ 'winston' // winston esm tests were failing
30
+ ]
31
+
32
+ // Packages that should be pinned to specific versions
33
+ const PINNED_PACKAGES = {
34
+ // Example: 'express': '4.17.3'
35
+ fastify : '4.28.1' // v5+ is not supported
36
+ }
37
+
38
+ // Packages that should only use the 'latest' tag (not 'next' or other dist-tags)
39
+ // Some packages have a next tag that is a stable semver version
40
+ const ONLY_USE_LATEST_TAG = [
41
+ // Example: 'router'
42
+ ]
43
+
44
+ // Initial structure for latests.json that will be recreated each run
45
+ const outputData = {
46
+ pinned : Object . keys ( PINNED_PACKAGES ) ,
47
+ onlyUseLatestTag : ONLY_USE_LATEST_TAG ,
48
+ ignored : IGNORED_PACKAGES ,
28
49
latests : { }
29
50
}
30
51
31
- /**
32
- * Gets the highest version that's compatible with our instrumentation
33
- * This handles cases where a package has newer versions that might break compatibility
34
- */
35
- async function getHighestCompatibleVersion ( name , config = { } ) {
52
+ function npmView ( input ) {
53
+ return new Promise ( ( resolve , reject ) => {
54
+ childProcess . exec ( `npm view ${ input } --json` , ( err , stdout ) => {
55
+ if ( err ) {
56
+ reject ( err )
57
+ return
58
+ }
59
+ try {
60
+ resolve ( JSON . parse ( stdout . toString ( 'utf8' ) ) )
61
+ } catch ( e ) {
62
+ reject ( new Error ( `Failed to parse npm output for ${ input } : ${ e . message } ` ) )
63
+ }
64
+ } )
65
+ } )
66
+ }
67
+
68
+ async function getHighestCompatibleVersion ( name ) {
36
69
try {
70
+ if ( IGNORED_PACKAGES . includes ( name ) ) {
71
+ console . log ( `Skipping "${ name } " as it's in the ignored list` )
72
+ return null
73
+ }
74
+
75
+ // If package is hardcoded as pinned, return the pinned version but also check latest
76
+ // this is for logging purposes
77
+ if ( PINNED_PACKAGES [ name ] ) {
78
+ const pinnedVersion = PINNED_PACKAGES [ name ]
79
+
80
+ try {
81
+ const distTags = await npmView ( `${ name } dist-tags` )
82
+ const latestTagged = distTags . latest
83
+
84
+ if ( latestTagged && semver . gt ( latestTagged , pinnedVersion ) ) {
85
+ console . log ( `Note: "${ name } " is pinned to ${ pinnedVersion } , but ${ latestTagged } is available` )
86
+ }
87
+ } catch ( err ) {
88
+ // Just log the error but continue with the pinned version
89
+ console . log ( `Warning: Could not fetch latest version for pinned package "${ name } ": ${ err . message } ` )
90
+ }
91
+
92
+ return pinnedVersion
93
+ }
94
+
37
95
// Get all distribution tags (including 'latest')
38
- const distTags = await npmView ( name + ' dist-tags' )
96
+ const distTags = await npmView ( ` ${ name } dist-tags` )
39
97
40
98
// Get the latest tagged version
41
99
const latestTagged = distTags . latest
@@ -46,12 +104,12 @@ async function getHighestCompatibleVersion (name, config = {}) {
46
104
}
47
105
48
106
// If package is in the onlyUseLatestTag list, always use the 'latest' tag
49
- if ( config . onlyUseLatestTag && config . onlyUseLatestTag . includes ( name ) ) {
107
+ if ( ONLY_USE_LATEST_TAG . includes ( name ) ) {
50
108
return latestTagged
51
109
}
52
110
53
111
// Get all available versions
54
- const allVersions = await npmView ( name + ' versions' )
112
+ const allVersions = await npmView ( ` ${ name } versions` )
55
113
56
114
// Find the highest non-prerelease version available
57
115
const stableVersions = allVersions . filter ( v => ! semver . prerelease ( v ) )
@@ -77,12 +135,7 @@ async function fix () {
77
135
console . log ( 'Starting fix operation...' )
78
136
console . log ( `Found ${ internalsNames . length } packages to process` )
79
137
80
- let outputData = initialStructure
81
- if ( fs . existsSync ( latestsPath ) ) {
82
- console . log ( 'Found existing latests.json, loading it...' )
83
- outputData = require ( latestsPath )
84
- }
85
-
138
+ // Process packages
86
139
const latests = { }
87
140
let processed = 0
88
141
const total = internalsNames . length
@@ -91,87 +144,48 @@ async function fix () {
91
144
processed ++
92
145
process . stdout . write ( `Processing package ${ processed } /${ total } : ${ name } ...` )
93
146
147
+ // Skip ignored packages
148
+ if ( IGNORED_PACKAGES . includes ( name ) ) {
149
+ process . stdout . write ( ' IGNORED\n' )
150
+ continue
151
+ }
152
+
94
153
try {
95
- const latestVersion = await getHighestCompatibleVersion ( name , outputData )
154
+ // Handle hardcoded pinned packages
155
+ if ( PINNED_PACKAGES [ name ] ) {
156
+ const pinnedVersion = PINNED_PACKAGES [ name ]
157
+ latests [ name ] = pinnedVersion
158
+ process . stdout . write ( ` PINNED to version ${ pinnedVersion } \n` )
159
+ continue
160
+ }
161
+
162
+ // Normal package processing
163
+ const latestVersion = await getHighestCompatibleVersion ( name )
96
164
if ( latestVersion ) {
97
165
latests [ name ] = latestVersion
98
166
process . stdout . write ( ` found version ${ latestVersion } \n` )
99
167
} else {
100
168
process . stdout . write ( ' WARNING: no version found\n' )
101
- console . log ( `Warning: Could not fetch latest version for "${ name } "` )
102
169
}
103
170
} catch ( error ) {
104
171
process . stdout . write ( ' ERROR\n' )
105
- console . error ( `Error fetching version for "${ name } ":` , error . message )
172
+ console . error ( `Error processing "${ name } ":` , error . message )
106
173
}
107
174
}
108
175
176
+ // Update the output data
109
177
outputData . latests = latests
110
- console . log ( '\nWriting updated versions to latests.json...' )
111
- fs . writeFileSync ( latestsPath , JSON . stringify ( outputData , null , 2 ) )
112
- console . log ( 'Successfully updated latests.json' )
113
- console . log ( `Processed ${ total } packages` )
114
- }
115
178
116
- /**
117
- * Checks if latests.json matches current npm versions
118
- */
119
- async function check ( ) {
120
- console . log ( 'Starting version check...' )
121
-
122
- if ( ! fs . existsSync ( latestsPath ) ) {
123
- console . log ( 'latests.json does not exist. Run with "fix" to create it.' )
124
- process . exitCode = 1
125
- return
126
- }
127
-
128
- const currentData = require ( latestsPath )
129
- console . log ( `Found ${ internalsNames . length } packages to check` )
130
-
131
- let processed = 0
132
- let mismatches = 0
133
- const total = internalsNames . length
134
-
135
- for ( const name of internalsNames ) {
136
- processed ++
137
- process . stdout . write ( `Checking package ${ processed } /${ total } : ${ name } ...` )
138
-
139
- const latest = currentData . latests [ name ]
140
- if ( ! latest ) {
141
- process . stdout . write ( ' MISSING\n' )
142
- console . log ( `No latest version found for "${ name } "` )
143
- process . exitCode = 1
144
- continue
145
- }
179
+ // Write the updated configuration with a comment at the top
180
+ console . log ( '\nWriting updated versions to latests.json...' )
146
181
147
- try {
148
- const latestVersion = await getHighestCompatibleVersion ( name , currentData )
149
- if ( ! latestVersion ) {
150
- process . stdout . write ( ' ERROR\n' )
151
- console . error ( `Error fetching latest version for "${ name } "` )
152
- continue
153
- }
182
+ // Convert to JSON with proper indentation
183
+ const jsonContent = JSON . stringify ( outputData , null , 2 )
154
184
155
- if ( latestVersion !== latest ) {
156
- process . stdout . write ( ' MISMATCH\n' )
157
- console . log ( `"latests.json: is not up to date for "${ name } ": expected "${ latestVersion } ", got "${ latest } "` )
158
- process . exitCode = 1
159
- mismatches ++
160
- } else {
161
- process . stdout . write ( ' OK\n' )
162
- }
163
- } catch ( error ) {
164
- process . stdout . write ( ' ERROR\n' )
165
- console . error ( `Error checking version for "${ name } ":` , error . message )
166
- }
167
- }
185
+ fs . writeFileSync ( latestsPath , jsonContent )
168
186
169
- console . log ( '\nCheck completed:' )
170
- console . log ( `- Total packages checked: ${ total } ` )
171
- console . log ( `- Version mismatches found: ${ mismatches } ` )
172
- if ( mismatches > 0 ) {
173
- console . log ( 'Run with "fix" to update versions' )
174
- }
187
+ console . log ( 'Successfully updated latests.json' )
188
+ console . log ( `Processed ${ total } packages` )
175
189
}
176
- if ( process . argv . includes ( 'fix' ) ) fix ( )
177
- else check ( )
190
+
191
+ fix ( )
0 commit comments