@@ -145,6 +145,62 @@ export class DenoLand implements RegistryUrl {
145145 regexp = / h t t p s ? : \/ \/ d e n o .l a n d \/ (?: s t d \@ [ ^ \' \" ] * | x \/ [ ^ \/ \" \' ] * ?\@ [ ^ \' \" ] * ) / ;
146146}
147147
148+ const NPM_CACHE : Map < string , string [ ] > = new Map < string , string [ ] > ( ) ;
149+ export class Npm implements RegistryUrl {
150+ url : string ;
151+ parseRegex = / ^ n p m : ( \@ [ ^ / ] + \/ [ ^ @ / ] + | [ ^ @ / ] + ) (?: \@ ( [ ^ / ] + ) ) ? ( .* ) / ;
152+
153+ constructor ( url : string ) {
154+ this . url = url ;
155+ }
156+
157+ name ( ) : string {
158+ const [ , name ] = this . url . match ( this . parseRegex ) ! ;
159+
160+ return name ;
161+ }
162+
163+ async all ( ) : Promise < string [ ] > {
164+ const name = this . name ( ) ;
165+ if ( NPM_CACHE . has ( name ) ) {
166+ return NPM_CACHE . get ( name ) ! ;
167+ }
168+
169+ try {
170+ const json : VersionsJson =
171+ await ( await fetch ( `https://registry.npmjs.org/${ name } ` ) )
172+ . json ( ) ;
173+ if ( ! json . versions ) {
174+ throw new Error ( `versions.json for ${ name } has incorrect format` ) ;
175+ }
176+
177+ const versions = Object . keys ( json . versions ) . reverse ( ) ;
178+ NPM_CACHE . set ( name , versions ) ;
179+ return versions ;
180+ } catch ( err ) {
181+ // TODO this could be a permissions error e.g. no --allow-net...
182+ console . error ( `error getting versions for ${ name } ` ) ;
183+ throw err ;
184+ }
185+ }
186+
187+ at ( version : string ) : RegistryUrl {
188+ const [ , name , _ , files ] = this . url . match ( this . parseRegex ) ! ;
189+ const url = `npm:${ name } @${ version } ${ files } ` ;
190+ return new Npm ( url ) ;
191+ }
192+
193+ version ( ) : string {
194+ const [ , _ , version ] = this . url . match ( this . parseRegex ) ! ;
195+ if ( version === null ) {
196+ throw Error ( `Unable to find version in ${ this . url } ` ) ;
197+ }
198+ return version ;
199+ }
200+
201+ regexp = / n p m : ( \@ [ ^ / ] + \/ [ ^ @ / ] + | [ ^ @ / ] + ) (?: \@ ( [ ^ / ] + ) ) ? [ ^ \' \" ] / ;
202+ }
203+
148204async function unpkgVersions ( name : string ) : Promise < string [ ] > {
149205 const page = await fetch ( `https://unpkg.com/browse/${ name } /` ) ;
150206 const text = await page . text ( ) ;
@@ -710,4 +766,5 @@ export const REGISTRIES = [
710766 GitlabRaw ,
711767 JsDelivr ,
712768 NestLand ,
769+ Npm ,
713770] ;
0 commit comments