Skip to content

Commit

Permalink
refactor: 🚚 move github package resolution into its own directory
Browse files Browse the repository at this point in the history
  • Loading branch information
meisZWFLZ committed Dec 14, 2023
1 parent cf076dc commit fad9c81
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 111 deletions.
3 changes: 3 additions & 0 deletions src/packages/github/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { GithubPackage, type GithubPackageReleaseData } from "./package";
export { GithubPackageResolver } from "./resolver";
export { GithubPackageVersion } from "./version";
43 changes: 43 additions & 0 deletions src/packages/github/package.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { type Octokit } from "octokit";
import { Package, type PackageIdentifier } from "../package";
import { GithubPackageVersion } from "./version";

export type GithubPackageReleaseData = Awaited<
ReturnType<Octokit["rest"]["repos"]["listReleases"]>
>["data"][number];

export class GithubPackage extends Package<
GithubPackageVersion,
PackageIdentifier
> {
constructor(
protected readonly client: Octokit,
protected readonly id: PackageIdentifier,
) {
super(id);
}

public override async getVersions(): Promise<GithubPackageVersion[]> {
return (
await this.client.rest.repos.listReleases({
...this.id,
})
).data
.map((release) =>
GithubPackageVersion.create(this.client, this.id, release),
)
.filter((release): release is GithubPackageVersion => release != null);
}

public async getLatest(): Promise<GithubPackageVersion | null> {
return GithubPackageVersion.create(
this.client,
this.id,
(
await this.client.rest.repos.getLatestRelease({
...this.id,
})
).data,
);
}
}
23 changes: 23 additions & 0 deletions src/packages/github/resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Octokit } from "octokit";
import { type PackageIdentifier, PackageResolver } from "../package";
import { GithubPackage } from "./package";

export class GithubPackageResolver extends PackageResolver<GithubPackage> {
private static readonly client: Octokit = new Octokit();
private static readonly singleton: GithubPackageResolver =
new GithubPackageResolver(GithubPackageResolver.client);

protected constructor(protected readonly client: Octokit) {
super();
}

public static get(): GithubPackageResolver {
return GithubPackageResolver.singleton;
}

public override async resolvePackage(
id: PackageIdentifier,
): Promise<GithubPackage> {
return new GithubPackage(this.client, id);
}
}
53 changes: 53 additions & 0 deletions src/packages/github/version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { type Octokit } from "octokit";
import { PackageVersion, type PackageIdentifier } from "../package";
import { type SemVer, parse } from "semver";
import { type GithubPackageReleaseData } from "./package";
import { type IncomingMessage } from "http";
import { get as httpsGet, type RequestOptions } from "https";

export class GithubPackageVersion extends PackageVersion {
protected constructor(
protected readonly client: Octokit,
public readonly packId: PackageIdentifier,
public readonly data: GithubPackageReleaseData,
version: SemVer,
) {
super(packId, version);
}

public static create(
client: Octokit,
packId: PackageIdentifier,
data: GithubPackageReleaseData,
): GithubPackageVersion | null {
const version = parse(data.tag_name);
if (version == null) return null;
return new GithubPackageVersion(client, packId, data, version);
}

protected getAssetIndex(): number {
return 0;
}

public override async download(): Promise<NodeJS.ReadableStream | undefined> {
const index = this.getAssetIndex();
const auth = await this.client.auth();
const opts: RequestOptions = {};

if (
typeof auth === "object" &&
auth != null &&
"token" in auth &&
typeof auth.token === "string"
)
opts.headers = {
Authorization: `Bearer ${auth.token}`,
};

const response = await new Promise<IncomingMessage>((resolve) =>
httpsGet(this.data.assets[index].url, opts, resolve),
);

return response;
}
}
112 changes: 1 addition & 111 deletions src/packages/package.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { Octokit } from "octokit";
import { type Range, SemVer, parse, maxSatisfying } from "semver";
import { type IncomingMessage } from "http";
import { get as httpsGet, type RequestOptions } from "https";
import { type Range, SemVer, maxSatisfying } from "semver";

export interface PackageIdentifier {
/**
Expand All @@ -15,10 +12,6 @@ export interface PackageIdentifier {
readonly repo: string;
}

export type GithubPackageReleaseData = Awaited<
ReturnType<Octokit["rest"]["repos"]["listReleases"]>
>["data"][number];

export abstract class PackageVersion
extends SemVer
implements PackageIdentifier
Expand All @@ -34,53 +27,6 @@ export abstract class PackageVersion
public abstract download(): Promise<NodeJS.ReadableStream | undefined>;
}

export class GithubPackageVersion extends PackageVersion {
protected constructor(
protected readonly client: Octokit,
public readonly packId: PackageIdentifier,
public readonly data: GithubPackageReleaseData,
version: SemVer,
) {
super(packId, version);
}

public static create(
client: Octokit,
packId: PackageIdentifier,
data: GithubPackageReleaseData,
): GithubPackageVersion | null {
const version = parse(data.tag_name);
if (version == null) return null;
return new GithubPackageVersion(client, packId, data, version);
}

protected getAssetIndex(): number {
return 0;
}

public override async download(): Promise<NodeJS.ReadableStream | undefined> {
const index = this.getAssetIndex();
const auth = await this.client.auth();
const opts: RequestOptions = {};

if (
typeof auth === "object" &&
auth != null &&
"token" in auth &&
typeof auth.token === "string"
)
opts.headers = {
Authorization: `Bearer ${auth.token}`,
};

const response = await new Promise<IncomingMessage>((resolve) =>
httpsGet(this.data.assets[index].url, opts, resolve),
);

return response;
}
}

export abstract class Package<
V extends PackageVersion,
ID extends PackageIdentifier,
Expand All @@ -107,64 +53,8 @@ export abstract class Package<
}
}

export class GithubPackage extends Package<
GithubPackageVersion,
PackageIdentifier
> {
constructor(
protected readonly client: Octokit,
protected readonly id: PackageIdentifier,
) {
super(id);
}

public override async getVersions(): Promise<GithubPackageVersion[]> {
return (
await this.client.rest.repos.listReleases({
...this.id,
})
).data
.map((release) =>
GithubPackageVersion.create(this.client, this.id, release),
)
.filter((release): release is GithubPackageVersion => release != null);
}

public async getLatest(): Promise<GithubPackageVersion | null> {
return GithubPackageVersion.create(
this.client,
this.id,
(
await this.client.rest.repos.getLatestRelease({
...this.id,
})
).data,
);
}
}

export abstract class PackageResolver<
P extends Package<PackageVersion, PackageIdentifier>,
> {
public abstract resolvePackage(id: PackageIdentifier): Promise<P | null>;
}

export class GithubPackageResolver extends PackageResolver<GithubPackage> {
private static readonly client: Octokit = new Octokit();
private static readonly singleton: GithubPackageResolver =
new GithubPackageResolver(GithubPackageResolver.client);

protected constructor(protected readonly client: Octokit) {
super();
}

public static get(): GithubPackageResolver {
return GithubPackageResolver.singleton;
}

public override async resolvePackage(
id: PackageIdentifier,
): Promise<GithubPackage> {
return new GithubPackage(this.client, id);
}
}

0 comments on commit fad9c81

Please sign in to comment.