g1t/apps/web/app/lib/project-kind.ts

91 lines4,019 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.

A project is an app or a library: libraries show their package and how to ship a release, not production1/**
2 * Words and links for a project that is a library or a tool rather than an
3 * app: which of its repository's packages to show, and how to publish a
4 * first one. Whether a project is one is decided by the projects service
5 * (`Project.kind`); this only says it on the pages.
6 */
7import type { DeploysSetting, Ecosystem, PackageSummary, ProjectEcosystem } from "@g1t/contracts";
8
9/** As lib/packages.ts names each registry; repeated so this module stands alone in tests. */
Merge branch 'worktree-agent-a6a121745e81f639f'10const REGISTRY: Record<Ecosystem, string> = {
11 container: "Container",
12 npm: "npm",
13 composer: "Composer",
14 cargo: "Cargo",
15 go: "Go",
16 maven: "Maven",
17 nuget: "NuGet",
18 rubygems: "RubyGems",
19};
A project is an app or a library: libraries show their package and how to ship a release, not production20
21const DOCS = "https://docs.g1t.sh";
22
23/** The choices for "Deployments for this project" in a project's settings. */
24export const DEPLOYS_CHOICES: { value: DeploysSetting; label: string; hint: string }[] = [
25 { value: "auto", label: "Detect automatically", hint: "From whether Deployments are on, the packages it publishes and the files at its root." },
26 { value: "yes", label: "Deploys", hint: "An app: its overview shows production, previews and domains." },
27 { value: "no", label: "Doesn't deploy", hint: "A library or a tool: its overview shows its packages and releases, and offers no deploying." },
28];
29
30/** A registry's guide, and the command that publishes a first version there. */
31export type PublishGuide = { label: string; guide: string; start: string | null };
32
33/** The registries with a guide, for a library whose files do not say which it is. */
34export const PUBLISH_GUIDES: PublishGuide[] = [
35 { label: "Composer", guide: `${DOCS}/guides/composer/`, start: "git tag v1.0.0 && git push --tags" },
36 { label: "npm", guide: `${DOCS}/guides/npm/`, start: "npm publish" },
37 { label: "Go", guide: `${DOCS}/guides/go/`, start: "git tag v1.0.0 && git push --tags" },
38 { label: "Containers", guide: `${DOCS}/guides/containers/`, start: null },
39];
40
41/** How a library of `ecosystem` publishes its first version; null when its files do not say. */
42export function publishGuide(ecosystem: ProjectEcosystem | null): PublishGuide | null {
43 switch (ecosystem) {
44 case "composer":
45 return PUBLISH_GUIDES[0]!;
46 case "npm":
47 return PUBLISH_GUIDES[1]!;
48 case "go":
49 return PUBLISH_GUIDES[2]!;
50 case "cargo":
51 return { label: "Cargo", guide: `${DOCS}/guides/packages/`, start: null };
52 case "python":
53 return { label: "Python", guide: `${DOCS}/guides/packages/`, start: null };
54 default:
55 return null;
56 }
57}
58
59/** A package as its own tool names it: `@acme/ui` for npm, the name otherwise. */
60export function packageName(pkg: Pick<PackageSummary, "ecosystem" | "name" | "workspace">): string {
61 return pkg.ecosystem === "npm" ? `@${pkg.workspace}/${pkg.name}` : pkg.name;
62}
63
64/** `Composer · psr/log 3.0.2`, for a project's card. */
65export function packageLine(pkg: Pick<PackageSummary, "ecosystem" | "name" | "workspace" | "latest">): string {
66 return `${REGISTRY[pkg.ecosystem]} · ${packageName(pkg)}${pkg.latest ? ` ${pkg.latest}` : ""}`;
67}
68
69/** The package's page. */
70export function packagePath(pkg: Pick<PackageSummary, "ecosystem" | "name" | "workspace">): string {
71 return `/${pkg.workspace}/-/packages/${pkg.ecosystem}/${pkg.name}`;
72}
73
74/**
75 * The packages a library's overview shows, from its repository's: what it
76 * publishes for others to install first, a container image last, as an
77 * image is how apps ship too.
78 */
79export function libraryPackages<T extends Pick<PackageSummary, "ecosystem" | "versions" | "updated_at">>(list: T[]): T[] {
80 return [...list].sort(
81 (a, b) =>
82 Number(a.ecosystem === "container") - Number(b.ecosystem === "container") ||
83 Number(b.versions > 0) - Number(a.versions > 0) ||
84 b.updated_at.localeCompare(a.updated_at),
85 );
86}
87
88/** Whether any of the packages has a version: a release is out. */
89export function hasRelease(list: Pick<PackageSummary, "versions">[]): boolean {
90 return list.some((pkg) => pkg.versions > 0);
91}

This file's history is long; its oldest lines are credited to the oldest commit read.