1- /* eslint-disable no-console */
21const { execSync } = require ( 'node:child_process' ) ;
32const fs = require ( 'node:fs' ) ;
43const path = require ( 'node:path' ) ;
@@ -12,7 +11,6 @@ function execCommand(command, options = {}) {
1211 console . error ( `Command failed: ${ command } ` ) ;
1312 console . error ( error . message ) ;
1413 process . exit ( 1 ) ;
15- return null ; // Ensure a return value for all code paths
1614 }
1715}
1816
@@ -21,7 +19,7 @@ function getPackageInfo() {
2119 return {
2220 name : pkgJson . name ,
2321 version : pkgJson . version ,
24- pkgJson,
22+ pkgJson
2523 } ;
2624}
2725
@@ -38,93 +36,127 @@ function getBaseVersionFromGit() {
3836 }
3937}
4038
39+ function incrementVersion ( version , type = 'patch' ) {
40+ const [ major , minor , patch ] = version . split ( '.' ) . map ( Number ) ;
41+
42+ switch ( type ) {
43+ case 'major' :
44+ return `${ major + 1 } .0.0` ;
45+ case 'minor' :
46+ return `${ major } .${ minor + 1 } .0` ;
47+ case 'patch' :
48+ default :
49+ return `${ major } .${ minor } .${ patch + 1 } ` ;
50+ }
51+ }
52+
53+ function findNextAvailableVersion ( packageName , baseVersion ) {
54+ console . log ( `Finding next available version starting from: ${ baseVersion } ` ) ;
55+
56+ try {
57+ const versionString = execCommand ( `npm show ${ packageName } versions --json` ) ;
58+ const versions = JSON . parse ( versionString ) ;
59+
60+ let currentVersion = baseVersion ;
61+
62+ // Keep incrementing patch version until we find one that doesn't exist
63+ while ( versions . includes ( currentVersion ) ) {
64+ console . log ( `Version ${ currentVersion } already exists as stable, incrementing...` ) ;
65+ currentVersion = incrementVersion ( currentVersion , 'patch' ) ;
66+ }
67+
68+ console . log ( `Next available base version: ${ currentVersion } ` ) ;
69+ return currentVersion ;
70+ } catch ( error ) {
71+ console . log ( 'Could not check NPM versions, using provided base version' ) ;
72+ return baseVersion ;
73+ }
74+ }
75+
4176function getNextBetaVersion ( packageName , baseVersion ) {
4277 console . log ( `Calculating next beta version for base: ${ baseVersion } ` ) ;
43-
78+
4479 // Validate base version format
4580 if ( ! / ^ \d + \. \d + \. \d + $ / . test ( baseVersion ) ) {
4681 console . error ( `Invalid base version format: ${ baseVersion } ` ) ;
4782 process . exit ( 1 ) ;
4883 }
4984
85+ // Find the next available base version if current one exists as stable
86+ const availableBaseVersion = findNextAvailableVersion ( packageName , baseVersion ) ;
87+
5088 let npmBetaNumber = 0 ;
5189 let gitBetaNumber = 0 ;
5290
53- // Check NPM for existing beta versions
91+ // Check NPM for existing beta versions of the available base version
5492 try {
5593 const versionString = execCommand ( `npm show ${ packageName } versions --json` ) ;
5694 const versions = JSON . parse ( versionString ) ;
5795
58- // Check if base version already exists as stable
59- if ( versions . includes ( baseVersion ) ) {
60- console . error ( `Base version ${ baseVersion } already exists as stable on NPM!` ) ;
61- process . exit ( 1 ) ;
62- }
63-
64- const versionPrefix = `${ baseVersion } -beta.` ;
96+ const versionPrefix = `${ availableBaseVersion } -beta.` ;
6597 const npmBetas = versions
66- . filter ( ( v ) => v . startsWith ( versionPrefix ) )
67- . map ( ( v ) => {
98+ . filter ( v => v . startsWith ( versionPrefix ) )
99+ . map ( v => {
68100 const match = v . match ( / ^ .+ - b e t a \. ( \d + ) $ / ) ;
69101 return match ? parseInt ( match [ 1 ] , 10 ) : 0 ;
70102 } ) ;
71-
103+
72104 npmBetaNumber = npmBetas . length > 0 ? Math . max ( ...npmBetas ) : 0 ;
73- console . log ( `Latest beta on NPM: ${ npmBetaNumber } ` ) ;
74- } catch {
75- console . log ( 'No existing versions found on NPM' ) ;
105+ console . log ( `Latest beta on NPM for ${ availableBaseVersion } : ${ npmBetaNumber } ` ) ;
106+ } catch ( error ) {
107+ console . log ( 'No existing beta versions found on NPM' ) ;
76108 }
77109
78- // Check Git tags for existing beta versions
110+ // Check Git tags for existing beta versions of the available base version
79111 try {
80- const tagPattern = `v${ baseVersion } -beta.*` ;
112+ const tagPattern = `v${ availableBaseVersion } -beta.*` ;
81113 const tags = execCommand ( `git tag -l "${ tagPattern } " --sort=-version:refname` ) ;
82-
114+
83115 if ( tags ) {
84- const tagList = tags . split ( '\n' ) . filter ( ( tag ) => tag . trim ( ) ) ;
116+ const tagList = tags . split ( '\n' ) . filter ( tag => tag . trim ( ) ) ;
85117 if ( tagList . length > 0 ) {
86118 const latestTag = tagList [ 0 ] ;
87119 const match = latestTag . match ( / v \d + \. \d + \. \d + - b e t a \. ( \d + ) $ / ) ;
88120 if ( match ) {
89121 gitBetaNumber = parseInt ( match [ 1 ] , 10 ) ;
90- console . log ( `Latest beta in Git: ${ gitBetaNumber } ` ) ;
122+ console . log ( `Latest beta in Git for ${ availableBaseVersion } : ${ gitBetaNumber } ` ) ;
91123 }
92124 }
93125 }
94- } catch {
126+ } catch ( error ) {
95127 console . log ( 'No existing beta tags found in Git' ) ;
96128 }
97129
98130 // Use the higher number to avoid conflicts
99131 const nextBetaNumber = Math . max ( npmBetaNumber , gitBetaNumber ) + 1 ;
100- const nextVersion = `${ baseVersion } -beta.${ nextBetaNumber } ` ;
101-
132+ const nextVersion = `${ availableBaseVersion } -beta.${ nextBetaNumber } ` ;
133+
102134 console . log ( `Next beta version: ${ nextVersion } ` ) ;
103135 return nextVersion ;
104136}
105137
106138function updatePackageVersion ( newVersion ) {
107139 const { pkgJson } = getPackageInfo ( ) ;
108140 pkgJson . version = newVersion ;
109- fs . writeFileSync ( PKG_JSON_PATH , ` ${ JSON . stringify ( pkgJson , null , 2 ) } \n` ) ;
141+ fs . writeFileSync ( PKG_JSON_PATH , JSON . stringify ( pkgJson , null , 2 ) + '\n' ) ;
110142 console . log ( `Updated package.json to ${ newVersion } ` ) ;
111143}
112144
113145function main ( ) {
114146 console . log ( '🚀 Starting beta version calculation...' ) ;
115-
147+
116148 const { name : packageName } = getPackageInfo ( ) ;
117-
149+
118150 // Get the base version from Git (what was committed by release_metadata)
119151 const baseVersion = getBaseVersionFromGit ( ) ;
120152 console . log ( `Base version from Git: ${ baseVersion } ` ) ;
121-
122- // Calculate next beta version
153+
154+ // Calculate next beta version (will auto-increment if base version exists as stable)
123155 const nextBetaVersion = getNextBetaVersion ( packageName , baseVersion ) ;
124-
156+
125157 // Update package.json with the beta version
126158 updatePackageVersion ( nextBetaVersion ) ;
127-
159+
128160 console . log ( '✅ Beta version preparation completed!' ) ;
129161 console . log ( `Package will be published as: ${ nextBetaVersion } ` ) ;
130162}
0 commit comments