Skip to content

Commit 7d917a0

Browse files
authored
Merge pull request #53 from takker99/scope
Support URLs such as https://domain/@scope/package
2 parents 23b6f4f + 9aeb4e9 commit 7d917a0

File tree

2 files changed

+186
-0
lines changed

2 files changed

+186
-0
lines changed

registry.ts

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,66 @@ async function unpkgVersions(name: string): Promise<string[]> {
154154
return m.map((x) => x[1]);
155155
}
156156

157+
interface PackageInfo {
158+
parts: string[];
159+
scope: string;
160+
packageName: string;
161+
version: string;
162+
}
163+
function defaultInfo(that: RegistryUrl): PackageInfo {
164+
const parts = that.url.split("/");
165+
const [packageName, version] = parts[4].split("@");
166+
if (parts[3] === undefined) {
167+
throw new Error(`Package scope not found in ${that.url}`);
168+
}
169+
if (packageName === undefined) {
170+
throw new Error(`Package name not found in ${that.url}`);
171+
}
172+
if (version === undefined) {
173+
throw new Error(`Unable to find version in ${that.url}`);
174+
}
175+
return {
176+
scope: parts[3],
177+
packageName,
178+
version,
179+
parts,
180+
};
181+
}
182+
183+
function defaultScopeAt(that: RegistryUrl, version: string): string {
184+
const { parts, packageName } = defaultInfo(that);
185+
parts[4] = `${packageName}@${version}`;
186+
return parts.join("/");
187+
}
188+
189+
export class UnpkgScope implements RegistryUrl {
190+
url: string;
191+
192+
parts(): PackageInfo {
193+
return defaultInfo(this);
194+
}
195+
196+
constructor(url: string) {
197+
this.url = url;
198+
}
199+
200+
async all(): Promise<string[]> {
201+
const { scope, packageName } = this.parts();
202+
return await unpkgVersions(`${scope}/${packageName}`);
203+
}
204+
205+
at(version: string): RegistryUrl {
206+
const url = defaultScopeAt(this, version);
207+
return new UnpkgScope(url);
208+
}
209+
210+
version(): string {
211+
return this.parts().version;
212+
}
213+
214+
regexp = /https?:\/\/unpkg\.com\/@[^\/\"\']*?\/[^\/\"\']*?\@[^\'\"]*/;
215+
}
216+
157217
export class Unpkg implements RegistryUrl {
158218
url: string;
159219

@@ -239,6 +299,35 @@ export class Denopkg implements RegistryUrl {
239299
regexp = /https?:\/\/denopkg.com\/[^\/\"\']*?\/[^\/\"\']*?\@[^\'\"]*/;
240300
}
241301

302+
export class PikaScope implements RegistryUrl {
303+
url: string;
304+
305+
parts(): PackageInfo {
306+
return defaultInfo(this);
307+
}
308+
309+
constructor(url: string) {
310+
this.url = url;
311+
}
312+
313+
async all(): Promise<string[]> {
314+
const { scope, packageName } = this.parts();
315+
return await unpkgVersions(`${scope}/${packageName}`);
316+
}
317+
318+
at(version: string): RegistryUrl {
319+
const url = defaultScopeAt(this, version);
320+
return new PikaScope(url);
321+
}
322+
323+
version(): string {
324+
return this.parts().version;
325+
}
326+
327+
regexp =
328+
/https?:\/\/cdn\.pika\.dev(\/\_)?\/@[^\/\"\']*?\/[^\/\"\']*?\@[^\'\"]*/;
329+
}
330+
242331
export class Pika implements RegistryUrl {
243332
url: string;
244333

@@ -266,6 +355,35 @@ export class Pika implements RegistryUrl {
266355
regexp = /https?:\/\/cdn.pika.dev(\/\_)?\/[^\/\"\']*?\@[^\'\"]*/;
267356
}
268357

358+
export class SkypackScope implements RegistryUrl {
359+
url: string;
360+
361+
parts(): PackageInfo {
362+
return defaultInfo(this);
363+
}
364+
365+
constructor(url: string) {
366+
this.url = url;
367+
}
368+
369+
async all(): Promise<string[]> {
370+
const { scope, packageName } = this.parts();
371+
return await unpkgVersions(`${scope}/${packageName}`);
372+
}
373+
374+
at(version: string): RegistryUrl {
375+
const url = defaultScopeAt(this, version);
376+
return new SkypackScope(url);
377+
}
378+
379+
version(): string {
380+
return this.parts().version;
381+
}
382+
383+
regexp =
384+
/https?:\/\/cdn\.skypack\.dev(\/\_)?\/@[^\/\"\']*?\/[^\/\"\']*?\@[^\'\"]*/;
385+
}
386+
269387
export class Skypack implements RegistryUrl {
270388
url: string;
271389

@@ -293,6 +411,34 @@ export class Skypack implements RegistryUrl {
293411
regexp = /https?:\/\/cdn.skypack.dev(\/\_)?\/[^\/\"\']*?\@[^\'\"]*/;
294412
}
295413

414+
export class EsmShScope implements RegistryUrl {
415+
url: string;
416+
417+
parts(): PackageInfo {
418+
return defaultInfo(this);
419+
}
420+
421+
constructor(url: string) {
422+
this.url = url;
423+
}
424+
425+
async all(): Promise<string[]> {
426+
const { scope, packageName } = this.parts();
427+
return await unpkgVersions(`${scope}/${packageName}`);
428+
}
429+
430+
at(version: string): RegistryUrl {
431+
const url = defaultScopeAt(this, version);
432+
return new EsmShScope(url);
433+
}
434+
435+
version(): string {
436+
return this.parts().version;
437+
}
438+
439+
regexp = /https?:\/\/esm\.sh\/@[^\/\"\']*?\/[^\/\"\']*?\@[^\'\"]*/;
440+
}
441+
296442
export class EsmSh implements RegistryUrl {
297443
url: string;
298444

@@ -518,11 +664,15 @@ export class NestLand implements RegistryUrl {
518664

519665
export const REGISTRIES = [
520666
DenoLand,
667+
UnpkgScope,
521668
Unpkg,
522669
Denopkg,
523670
Jspm,
671+
PikaScope,
524672
Pika,
673+
SkypackScope,
525674
Skypack,
675+
EsmShScope,
526676
EsmSh,
527677
GithubRaw,
528678
GitlabRaw,

registry_test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ Deno.test("registryDenolandX", () => {
3333
assertEquals(vAt.url, "https://deno.land/x/foo@0.2.0/foo.ts");
3434
});
3535

36+
Deno.test("registryUnpkgScope", () => {
37+
const url = "https://unpkg.com/@bar/foo@0.1.0/foo.ts";
38+
const v = lookup(url, REGISTRIES);
39+
assert(v !== undefined);
40+
41+
const vAt = v.at("0.2.0");
42+
assertEquals(vAt.url, "https://unpkg.com/@bar/foo@0.2.0/foo.ts");
43+
});
44+
3645
Deno.test("registryUnpkg", () => {
3746
const url = "https://unpkg.com/foo@0.1.0/foo.ts";
3847
const v = lookup(url, REGISTRIES);
@@ -60,6 +69,15 @@ Deno.test("registryJspm", () => {
6069
assertEquals(vAt.url, "https://dev.jspm.io/npm:foo@0.2.0/");
6170
});
6271

72+
Deno.test("registryPikaScope", () => {
73+
const url = "https://cdn.pika.dev/@bar/foo@0.1.0/";
74+
const v = lookup(url, REGISTRIES);
75+
assert(v !== undefined);
76+
77+
const vAt = v.at("0.2.0");
78+
assertEquals(vAt.url, "https://cdn.pika.dev/@bar/foo@0.2.0/");
79+
});
80+
6381
Deno.test("registryPika", () => {
6482
const url = "https://cdn.pika.dev/foo@0.1.0/";
6583
const v = lookup(url, REGISTRIES);
@@ -69,6 +87,15 @@ Deno.test("registryPika", () => {
6987
assertEquals(vAt.url, "https://cdn.pika.dev/foo@0.2.0/");
7088
});
7189

90+
Deno.test("registrySkypackScope", () => {
91+
const url = "https://cdn.skypack.dev/@bar/foo@0.1.0/";
92+
const v = lookup(url, REGISTRIES);
93+
assert(v !== undefined);
94+
95+
const vAt = v.at("0.2.0");
96+
assertEquals(vAt.url, "https://cdn.skypack.dev/@bar/foo@0.2.0/");
97+
});
98+
7299
Deno.test("registrySkypack", () => {
73100
const url = "https://cdn.skypack.dev/foo@0.1.0/";
74101
const v = lookup(url, REGISTRIES);
@@ -78,6 +105,15 @@ Deno.test("registrySkypack", () => {
78105
assertEquals(vAt.url, "https://cdn.skypack.dev/foo@0.2.0/");
79106
});
80107

108+
Deno.test("registryEsmShScope", () => {
109+
const url = "https://esm.sh/@bar/foo@0.1.0/";
110+
const v = lookup(url, REGISTRIES);
111+
assert(v !== undefined);
112+
113+
const vAt = v.at("0.2.0");
114+
assertEquals(vAt.url, "https://esm.sh/@bar/foo@0.2.0/");
115+
});
116+
81117
Deno.test("registryEsmSh", () => {
82118
const url = "https://esm.sh/foo@0.1.0/";
83119
const v = lookup(url, REGISTRIES);

0 commit comments

Comments
 (0)