Skip to content

Commit d96d0cb

Browse files
authored
Merge pull request #90 from oscarotero/master
Added support for npm
2 parents e32af2b + cff165a commit d96d0cb

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

registry.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,62 @@ export class DenoLand implements RegistryUrl {
145145
regexp = /https?:\/\/deno.land\/(?:std\@[^\'\"]*|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 = /^npm:(\@[^/]+\/[^@/]+|[^@/]+)(?:\@([^/]+))?(.*)/;
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 = /npm:(\@[^/]+\/[^@/]+|[^@/]+)(?:\@([^/]+))?[^\'\"]/;
202+
}
203+
148204
async 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
];

registry_test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,21 @@ Deno.test("registryNestLand", () => {
170170
const vAt = v.at("0.2.0");
171171
assertEquals(vAt.url, "https://x.nest.land/foo@0.2.0/foo.ts");
172172
});
173+
174+
Deno.test("registryNpm", () => {
175+
const url = "npm:foo@0.1.0/foo";
176+
const v = lookup(url, REGISTRIES);
177+
assert(v !== undefined);
178+
179+
const vAt = v.at("0.2.0");
180+
assertEquals(vAt.url, "npm:foo@0.2.0/foo");
181+
});
182+
183+
Deno.test("registryNpmOrg", () => {
184+
const url = "npm:@foo/foo@0.1.0/foo";
185+
const v = lookup(url, REGISTRIES);
186+
assert(v !== undefined);
187+
188+
const vAt = v.at("0.2.0");
189+
assertEquals(vAt.url, "npm:@foo/foo@0.2.0/foo");
190+
});

0 commit comments

Comments
 (0)