@@ -290,9 +290,17 @@ async function resolveUniquePrereleaseVersion(
290290 const base = `${ parsed . major } .${ parsed . minor } .${ parsed . patch } ` ;
291291 const build = parsed . build ; // preserve build metadata if present
292292
293- // Current numeric index if present, otherwise default to 0
294- const currentNum =
295- typeof parsed . prerelease [ 1 ] === 'number' ? parsed . prerelease [ 1 ] : 0 ;
293+ // Determine current numeric index depending on named vs unnamed prerelease
294+ let currentNum = 0 ;
295+ if ( Array . isArray ( parsed . prerelease ) && parsed . prerelease . length ) {
296+ if ( prereleaseId === '' && typeof parsed . prerelease [ 0 ] === 'number' ) {
297+ // unnamed prerelease like 1.2.3-0
298+ currentNum = parsed . prerelease [ 0 ] ;
299+ } else if ( typeof parsed . prerelease [ 1 ] === 'number' ) {
300+ // named prerelease like 1.2.3-alpha.0
301+ currentNum = parsed . prerelease [ 1 ] ;
302+ }
303+ }
296304
297305 const tags = await new Promise ( ( resolve , reject ) => {
298306 gitSemverTags ( { tagPrefix } , ( err , t ) =>
@@ -306,22 +314,29 @@ async function resolveUniquePrereleaseVersion(
306314 . map ( ( t ) => ( semver . valid ( t ) ? semver . clean ( t ) : null ) )
307315 . filter ( Boolean ) ;
308316
309- // collect numeric suffix for same base and prerelease id
317+ // collect numeric suffix for same base and prerelease id (or unnamed prerelease)
310318 const nums = cleaned
311319 . filter ( ( t ) => {
312320 const v = new semver . SemVer ( t ) ;
313321 if ( ! Array . isArray ( v . prerelease ) || v . prerelease . length === 0 )
314322 return false ;
315- // same base version and same prerelease id
316- return (
323+ const sameBase =
317324 v . major === parsed . major &&
318325 v . minor === parsed . minor &&
319- v . patch === parsed . patch &&
320- String ( v . prerelease [ 0 ] ) === String ( prereleaseId )
321- ) ;
326+ v . patch === parsed . patch ;
327+ if ( ! sameBase ) return false ;
328+ if ( prereleaseId === '' ) {
329+ // unnamed prerelease: include tags where first prerelease token is numeric
330+ return typeof v . prerelease [ 0 ] === 'number' ;
331+ }
332+ // named prerelease: match by identifier
333+ return String ( v . prerelease [ 0 ] ) === String ( prereleaseId ) ;
322334 } )
323335 . map ( ( t ) => {
324336 const v = new semver . SemVer ( t ) ;
337+ if ( prereleaseId === '' ) {
338+ return typeof v . prerelease [ 0 ] === 'number' ? v . prerelease [ 0 ] : 0 ;
339+ }
325340 return typeof v . prerelease [ 1 ] === 'number' ? v . prerelease [ 1 ] : 0 ;
326341 } ) ;
327342
@@ -333,7 +348,10 @@ async function resolveUniquePrereleaseVersion(
333348 const maxExisting = Math . max ( ...nums ) ;
334349 // If our proposed numeric index is already used or below max, bump to max + 1
335350 if ( currentNum <= maxExisting ) {
336- let candidate = `${ base } -${ prereleaseId } .${ maxExisting + 1 } ` ;
351+ let candidate =
352+ prereleaseId === ''
353+ ? `${ base } -${ maxExisting + 1 } `
354+ : `${ base } -${ prereleaseId } .${ maxExisting + 1 } ` ;
337355 // re-append build metadata if any
338356 if ( build && build . length ) {
339357 candidate = semvarToVersionStr ( candidate , build ) ;
0 commit comments