@@ -9,17 +9,51 @@ export function encodePackageName(name: string): string {
99 return encodeURIComponent ( name )
1010}
1111
12- export function isValidPrefix ( c : string ) {
13- return c === '^' || c === '~'
14- }
12+ const WORKSPACE_PREFIX = 'workspace:'
13+ const CATALOG_PREFIX = 'catalog:'
14+ const NPM_PREFIX = 'npm:'
15+ const JSR_PREFIX = 'jsr:'
16+ const URL_PREFIXES = [ 'http://' , 'https://' , 'git://' , 'git+' ]
17+
18+ export type VersionProtocol = 'npm' | null
1519
16- export function extractVersionPrefix ( v : string ) {
17- const firstChar = v [ 0 ]
18- const valid = isValidPrefix ( firstChar )
20+ export interface ParsedVersion {
21+ protocol : VersionProtocol
22+ prefix : '' | '^' | '~'
23+ semver : string
24+ }
1925
20- return valid ? firstChar : ''
26+ export function formatVersion ( parsed : ParsedVersion ) : string {
27+ const protocol = parsed . protocol ? `${ parsed . protocol } :` : ''
28+ return `${ protocol } ${ parsed . prefix } ${ parsed . semver } `
2129}
2230
23- export function extractVersion ( versionRange : string ) : string {
24- return versionRange . replace ( / ^ [ \^ ~ ] / , '' )
31+ export function parseVersion ( rawVersion : string ) : ParsedVersion | null {
32+ // Skip special protocols that aren't standard npm versions
33+ if (
34+ [
35+ WORKSPACE_PREFIX ,
36+ CATALOG_PREFIX ,
37+ JSR_PREFIX ,
38+ ...URL_PREFIXES ,
39+ ] . some ( ( p ) => rawVersion . startsWith ( p ) )
40+ ) {
41+ return null
42+ }
43+
44+ let protocol : VersionProtocol = null
45+ let versionStr = rawVersion
46+
47+ // Handle npm: protocol (e.g., npm:^1.0.0)
48+ if ( rawVersion . startsWith ( NPM_PREFIX ) ) {
49+ protocol = 'npm'
50+ versionStr = rawVersion . slice ( 4 /* NPM_PREFIX.length */ )
51+ }
52+
53+ const firstChar = versionStr [ 0 ]
54+ const hasPrefix = firstChar === '^' || firstChar === '~'
55+ const prefix = hasPrefix ? firstChar : ''
56+ const semver = hasPrefix ? versionStr . slice ( 1 ) : versionStr
57+
58+ return { protocol, prefix, semver }
2559}
0 commit comments