g1t/packages/contracts/src/packages.ts

111 lines4,725 bytesCodeBlame

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 member1import type { AuditSurface } from "./audit";
2import type { User, Viewer } from "./identity";
3import type { Result } from "./result";
4
5/**
6 * The packages service: the registries a workspace publishes to and
7 * installs from, beside its code (docs/PACKAGES.md). Container images
8 * first, on `g1t.sh/v2/`. Mirrors `crates/contracts/src/packages.rs`.
9 *
10 * A package linked to a repository has its visibility and roles (Read
11 * pulls, Write publishes, Admin deletes and changes settings); an unlinked
12 * one is its workspace's: members by the base permission, owners delete.
13 */
14
15/** Which registry a package is in. */
16export const ECOSYSTEMS = ["container", "npm", "composer", "cargo", "go"] as const;
17export type Ecosystem = (typeof ECOSYSTEMS)[number];
18
19export type PackageVisibility = "public" | "private";
20
21export type LinkedRepo = { id: string; namespace: string; name: string };
22
23/** A package as listings show it. */
24export type PackageSummary = {
25 id: string;
26 workspace: string;
27 ecosystem: Ecosystem;
28 /** Without the workspace: `web` for `g1t.sh/acme/web`. */
29 name: string;
30 /** What a client is given: `g1t.sh/acme/web` for a container image. */
31 address: string;
32 /** Linked packages follow their repository's visibility. */
33 visibility: PackageVisibility;
34 repo: LinkedRepo | null;
35 description: string | null;
36 versions: number;
37 /** The newest version's tag (`latest` when it has one) or version. */
38 latest: string | null;
39 /** Bytes its versions hold, each file counted once. */
40 size: number;
41 /** Pulls and installs, counted approximately. */
42 downloads: number;
43 created_at: string;
44 updated_at: string;
45};
46
47/** One version: for a container image, one manifest, by digest. */
48export type PackageVersion = {
49 id: string;
50 version: string;
51 digest: string;
52 size: number;
53 media_type: string | null;
54 /** For an OCI artifact: what it is, such as a signature or an SBOM. */
55 artifact_type: string | null;
56 /** For an artifact attached to another version: that version's digest. */
57 subject: string | null;
58 /** For an image index: the platforms it holds, such as `linux/amd64`. */
59 platforms: string[];
60 tags: string[];
61 published_by: string | null;
62 published_at: string;
63};
64
65export type PackageTag = { tag: string; digest: string; updated_at: string };
66
67/** What the viewer may do with a package. `admin`: change its visibility and link. */
68export type PackagePermissions = { pull: boolean; push: boolean; delete: boolean; admin: boolean };
69
70export type PackageDetail = {
71 package: PackageSummary;
72 /** Newest first. */
73 versions: PackageVersion[];
74 tags: PackageTag[];
75 permissions: PackagePermissions;
76};
77
78/** What a workspace's packages hold, for billing: each file once, public when any public package uses it. */
79export type PackageStorage = { public_bytes: number; private_bytes: number };
80
81/** `storage_all`: every workspace with packages, by workspace, for billing's daily measure. */
82export type WorkspacePackageStorage = { workspace: string; public_bytes: number; private_bytes: number };
83
84export type PackageFilter = { ecosystem?: Ecosystem | null; repoId?: string | null; query?: string | null };
85
86export type PackageChange = {
87 visibility?: PackageVisibility;
88 /** A repository of the package's workspace, by name. */
89 link?: string;
90 /** Take the link away. */
91 unlink?: boolean;
92};
93
94export type PackagesApi = {
95 /** The workspace's packages the viewer may pull, newest first. */
96 list(workspace: string, viewer: Viewer, filter?: PackageFilter): Promise<Result<PackageSummary[]>>;
97 /** Not found when the viewer may not pull it. */
98 get(workspace: string, ecosystem: Ecosystem, name: string, viewer: Viewer): Promise<Result<PackageDetail>>;
99 /** A version by version, digest or tag; its tags go with it. */
100 deleteVersion(actor: User, workspace: string, ecosystem: Ecosystem, name: string, version: string, surface?: AuditSurface): Promise<Result<null>>;
101 deletePackage(actor: User, workspace: string, ecosystem: Ecosystem, name: string, surface?: AuditSurface): Promise<Result<null>>;
102 /** Needs Admin. A linked package's visibility is its repository's. */
103 set(actor: User, workspace: string, ecosystem: Ecosystem, name: string, change: PackageChange, surface?: AuditSurface): Promise<Result<PackageSummary>>;
104 /** For billing. */
105 storage(workspace: string): Promise<PackageStorage>;
106 /** For billing: every workspace with packages, from one query. */
107 storageAll(): Promise<WorkspacePackageStorage[]>;
108};
109
110/** The RPC method behind each call, as the Rust service names them. */
111export const PACKAGES_METHODS = ["list_packages", "get_package", "delete_version", "delete_package", "set_package", "storage", "storage_all"] as const;