Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 1 | /** |
| 2 | * Words and commands for the Packages pages: sizes, digests, and how each | |
| 3 | * registry's own tool logs in and installs. | |
| 4 | */ | |
| 5 | import type { Ecosystem, PackageSummary } from "@g1t/contracts"; | |
| 6 | ||
| 7 | /** What each registry is called on the pages. */ | |
| 8 | export const ECOSYSTEM_LABEL: Record<Ecosystem, string> = { | |
| 9 | container: "Container", | |
| 10 | npm: "npm", | |
| 11 | composer: "Composer", | |
| 12 | cargo: "Cargo", | |
| 13 | go: "Go", | |
| 14 | }; | |
| 15 | ||
| Packages lists like a registry: Type, search, Visibility and Sort in one bar, richer rows, and a registry to choose from to start | 16 | /** |
| 17 | * Each registry as the Packages page introduces it: what it is for, the | |
| 18 | * command that starts one, its guide, and whether it is open yet. | |
| 19 | */ | |
| 20 | export const REGISTRIES: { ecosystem: Ecosystem; blurb: string; start: string; guide: string; ready: boolean }[] = [ | |
| 21 | { | |
| 22 | ecosystem: "container", | |
| 23 | blurb: "Docker and OCI images, signatures and attestations, pulled by anyone the image's repository lets read it.", | |
| 24 | start: "docker push g1t.sh/<workspace>/<name>:<tag>", | |
| 25 | guide: "/guides/containers/", | |
| 26 | ready: true, | |
| 27 | }, | |
| 28 | { | |
| 29 | ecosystem: "npm", | |
| 30 | blurb: "JavaScript and TypeScript packages under the workspace's scope, installed with npm, pnpm or yarn.", | |
| 31 | start: "npm publish", | |
| 32 | guide: "/guides/npm/", | |
| 33 | ready: true, | |
| 34 | }, | |
| 35 | { | |
| 36 | ecosystem: "composer", | |
| 37 | blurb: "PHP packages straight from the workspace's repositories: each tag is a version, nothing to upload.", | |
| 38 | start: "git tag v1.0.0 && git push --tags", | |
| 39 | guide: "/guides/composer/", | |
| 40 | ready: true, | |
| 41 | }, | |
| 42 | { | |
| 43 | ecosystem: "go", | |
| 44 | blurb: "Go modules fetched from the repositories themselves with go get, private ones with a token.", | |
| 45 | start: "go get g1t.sh/<workspace>/<repo>", | |
| 46 | guide: "/guides/go/", | |
| 47 | ready: true, | |
| 48 | }, | |
| 49 | { | |
| 50 | ecosystem: "cargo", | |
| 51 | blurb: "Rust crates in a registry of the workspace's own, published with cargo publish.", | |
| 52 | start: "cargo publish --registry <workspace>", | |
| 53 | guide: "/guides/packages/", | |
| 54 | ready: false, | |
| 55 | }, | |
| 56 | ]; | |
| 57 | ||
| 58 | export type PackageSort = "updated" | "downloads" | "name"; | |
| 59 | export type VisibilityFilter = "all" | "public" | "private"; | |
| 60 | ||
| 61 | export const SORT_LABEL: Record<PackageSort, string> = { | |
| 62 | updated: "Recently updated", | |
| 63 | downloads: "Most downloads", | |
| 64 | name: "Name", | |
| 65 | }; | |
| 66 | ||
| 67 | export const VISIBILITY_LABEL: Record<VisibilityFilter, string> = { all: "All", public: "Public", private: "Private" }; | |
| 68 | ||
| 69 | /** The packages to list: those of the visibility asked for, in the order asked for. */ | |
| 70 | export function arrange<T extends Pick<PackageSummary, "visibility" | "updated_at" | "downloads" | "name">>( | |
| 71 | list: T[], | |
| 72 | visibility: VisibilityFilter, | |
| 73 | sort: PackageSort, | |
| 74 | ): T[] { | |
| 75 | const shown = visibility === "all" ? [...list] : list.filter((pkg) => pkg.visibility === visibility); | |
| 76 | const byName = (a: T, b: T) => a.name.localeCompare(b.name); | |
| 77 | if (sort === "name") return shown.sort(byName); | |
| 78 | if (sort === "downloads") return shown.sort((a, b) => b.downloads - a.downloads || byName(a, b)); | |
| 79 | return shown.sort((a, b) => b.updated_at.localeCompare(a.updated_at) || byName(a, b)); | |
| 80 | } | |
| 81 | ||
| 82 | /** "940", "16.1k", "2.3M": download counts, short. */ | |
| 83 | export function shortCount(n: number): string { | |
| 84 | if (n >= 1_000_000) return `${Number((n / 1_000_000).toFixed(1))}M`; | |
| 85 | if (n >= 1_000) return `${Number((n / 1_000).toFixed(1))}k`; | |
| 86 | return String(Math.max(0, Math.round(n))); | |
| 87 | } | |
| 88 | ||
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 89 | /** "0 B", "812 KB", "12.3 MB", "1.4 GB", in powers of 1,000 as registries show them. */ |
| 90 | export function formatBytes(bytes: number): string { | |
| 91 | if (!Number.isFinite(bytes) || bytes <= 0) return "0 B"; | |
| 92 | const units = ["B", "KB", "MB", "GB", "TB"]; | |
| 93 | let value = bytes; | |
| 94 | let unit = 0; | |
| 95 | while (value >= 1000 && unit < units.length - 1) { | |
| 96 | value /= 1000; | |
| 97 | unit++; | |
| 98 | } | |
| 99 | const shown = unit === 0 || value >= 100 ? Math.round(value) : Number(value.toFixed(1)); | |
| 100 | return `${shown} ${units[unit]}`; | |
| 101 | } | |
| 102 | ||
| 103 | /** `sha256:3f2a…` shortened to `3f2a9c1b7d0e` for lists. */ | |
| 104 | export function shortDigest(digest: string): string { | |
| 105 | return digest.replace(/^sha256:/, "").slice(0, 12); | |
| 106 | } | |
| 107 | ||
| 108 | /** The host packages are published to and installed from. */ | |
| 109 | export function registryHost(address: string): string { | |
| 110 | return address.split("/")[0] || "g1t.sh"; | |
| 111 | } | |
| 112 | ||
| 113 | /** | |
| 114 | * How to log in and install `pkg` at `version` (a tag or version) with its | |
| 115 | * tool. `you` stands in the username a login takes. | |
| 116 | */ | |
| npm on g1t.sh: publish and install @<workspace>/<name> with the npm CLI and a g1t token | 117 | export function installCommands( |
| 118 | pkg: Pick<PackageSummary, "ecosystem" | "address" | "name" | "workspace">, | |
| 119 | version: string | null, | |
| 120 | you: string, | |
| 121 | ): { login: string; install: string; registry?: string } { | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 122 | const host = registryHost(pkg.address); |
| 123 | switch (pkg.ecosystem) { | |
| 124 | case "container": | |
| 125 | return { | |
| 126 | login: `docker login ${host} -u ${you}`, | |
| 127 | install: `docker pull ${pkg.address}${version ? `:${version}` : ""}`, | |
| 128 | }; | |
| 129 | case "npm": | |
| npm on g1t.sh: publish and install @<workspace>/<name> with the npm CLI and a g1t token | 130 | // The scope's registry (in .npmrc, needed for any install), then the |
| 131 | // token a private package also needs. | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 132 | return { |
| npm on g1t.sh: publish and install @<workspace>/<name> with the npm CLI and a g1t token | 133 | registry: `npm config set @${pkg.workspace}:registry=https://${host}/-/npm/`, |
| 134 | login: `npm config set //${host}/-/npm/:_authToken=YOUR_TOKEN`, | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 135 | install: `npm install @${pkg.workspace}/${pkg.name}${version ? `@${version}` : ""}`, |
| 136 | }; | |
| 137 | case "composer": | |
| Composer from the workspace's own repositories, and go get from g1t.sh | 138 | // The workspace's repository (in composer.json, needed for any |
| 139 | // install), then the credentials a private package also needs. | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 140 | return { |
| Composer from the workspace's own repositories, and go get from g1t.sh | 141 | registry: `composer config repositories.${pkg.workspace} composer https://${host}/-/composer/${pkg.workspace}/`, |
| 142 | login: `composer config --global --auth http-basic.${host} ${you} YOUR_TOKEN`, | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 143 | install: `composer require ${pkg.name}${version ? `:${version}` : ""}`, |
| 144 | }; | |
| 145 | case "cargo": | |
| 146 | return { | |
| 147 | login: `cargo login --registry ${pkg.workspace}`, | |
| 148 | install: `cargo add ${pkg.name} --registry ${pkg.workspace}${version ? ` --vers ${version}` : ""}`, | |
| 149 | }; | |
| 150 | case "go": | |
| 151 | return { | |
| 152 | login: `go env -w GOPRIVATE=${host}/${pkg.workspace}`, | |
| 153 | install: `go get ${pkg.address}${version ? `@${version}` : ""}`, | |
| 154 | }; | |
| 155 | } | |
| 156 | } |