This repository has been archived by the owner on Dec 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from meisZWFLZ/master
Add rudimentary package resolution via Github
- Loading branch information
Showing
9 changed files
with
818 additions
and
282 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
#!/usr/bin/env sh | ||
. "$(dirname -- "$0")/_/husky.sh" | ||
|
||
npm run check-format | ||
npm run pre-commit |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { type Octokit } from "octokit"; | ||
import { type PackageIdentifier, PackageResolver } from "../package"; | ||
import { GithubPackage } from "./package"; | ||
|
||
export class GithubPackageResolver extends PackageResolver<GithubPackage> { | ||
public constructor(protected readonly client: Octokit) { | ||
super(); | ||
} | ||
|
||
public override async resolvePackage( | ||
id: PackageIdentifier, | ||
): Promise<GithubPackage> { | ||
return new GithubPackage(this.client, id); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { type Octokit } from "octokit"; | ||
import { PackageVersion, type PackageIdentifier } from "../package"; | ||
import { type SemVer, parse } from "semver"; | ||
import { type GithubPackageReleaseData } from "./package"; | ||
|
||
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<Buffer | undefined> { | ||
const index = this.getAssetIndex(); | ||
|
||
const res = await this.client.rest.repos.getReleaseAsset({ | ||
repo: this.packId.repo, | ||
owner: this.packId.owner, | ||
asset_id: this.data.assets[index].id, | ||
headers: { accept: "application/octet-stream" }, | ||
}); | ||
|
||
const data = res.data; | ||
|
||
if (data instanceof ArrayBuffer) { | ||
return Buffer.from(data); | ||
} | ||
throw new Error( | ||
"github api response was not Array. res status: " + res.status, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { eq as verEquals, type Range, type SemVer } from "semver"; | ||
|
||
export interface PackageIdentifier { | ||
/** | ||
* does not include @ sign | ||
* @example lemlib | ||
*/ | ||
readonly owner: string; | ||
/** | ||
* @example lemlink | ||
*/ | ||
readonly repo: string; | ||
} | ||
|
||
export abstract class PackageVersion implements PackageIdentifier { | ||
readonly owner: string; | ||
readonly repo: string; | ||
public constructor( | ||
packId: PackageIdentifier, | ||
public readonly version: SemVer, | ||
) { | ||
this.owner = packId.owner; | ||
this.repo = packId.repo; | ||
} | ||
public abstract download(): Promise<Buffer | undefined>; | ||
} | ||
|
||
export abstract class Package< | ||
V extends PackageVersion, | ||
ID extends PackageIdentifier, | ||
> implements PackageIdentifier | ||
{ | ||
public readonly owner: string; | ||
public readonly repo: string; | ||
|
||
constructor(id: ID) { | ||
this.owner = id.owner; | ||
this.repo = id.repo; | ||
} | ||
|
||
public abstract getVersions(): Promise<V[]>; | ||
public abstract getLatest(): Promise<V | null>; | ||
|
||
public async getVersion(version: SemVer): Promise<V | undefined> { | ||
return (await this.getVersions()).find((v) => | ||
verEquals(v.version, version), | ||
); | ||
} | ||
|
||
public async getVersionsInRange(range: Range): Promise<V[]> { | ||
const versions = await this.getVersions(); | ||
return versions.filter((v) => range.test(v.version)); | ||
} | ||
|
||
public async getLatestInRange(range: Range): Promise<V | undefined> { | ||
return (await this.getVersionsInRange(range)) | ||
.sort((a, b) => a.version.compare(b.version)) | ||
.pop(); | ||
} | ||
} | ||
|
||
export abstract class PackageResolver< | ||
P extends Package<PackageVersion, PackageIdentifier>, | ||
> { | ||
public abstract resolvePackage(id: PackageIdentifier): Promise<P | null>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters