pr_01m47d15m3e54sn21z27rpy5n9/services/deployments/src/names.ts

48 lines1,909 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.

Deployments: a preview for every pull request, production on g1t.page1/**
2 * Where an app is served. Production is `<repo>--<owner>.g1t.page` and a
3 * pull request's preview `pr-<n>--<repo>--<owner>.g1t.page`; the first label
4 * is also the app's script name in the dispatch namespace, so the
5 * dispatcher needs nothing but the hostname to find it.
6 */
7
8import { DEPLOYMENTS_DOMAIN, type RepoPath } from "@g1t/contracts";
9
10/** A hostname label is at most this long. */
11const MAX_LABEL = 63;
12
13/** Lowercase letters, digits and single hyphens, as a label allows. */
14function clean(text: string): string {
15 return text
16 .toLowerCase()
17 .replace(/[^a-z0-9]+/g, "-")
18 .replace(/-{2,}/g, "-")
19 .replace(/^-|-$/g, "");
20}
21
22/** A short, stable fingerprint, for names that must be shortened. */
23async function fingerprint(text: string): Promise<string> {
24 const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(text));
25 return [...new Uint8Array(digest).slice(0, 4)].map((b) => b.toString(16).padStart(2, "0")).join("");
26}
27
28/**
29 * The script name, and hostname label, for production (`number` null) or a
30 * pull request's preview. Single hyphens inside names are kept; the `--`
31 * separators cannot occur in a cleaned name, so two repositories never
32 * share one. Names too long for a label are shortened with a fingerprint of
33 * the whole.
34 */
35export async function scriptName(repo: RepoPath, number: number | null): Promise<string> {
36 const prefix = number == null ? "" : `pr-${number}--`;
37 const full = `${prefix}${clean(repo.name)}--${clean(repo.namespace)}`;
38 if (full.length <= MAX_LABEL) return full;
39 const tail = `--${await fingerprint(`${repo.namespace}/${repo.name}`)}`;
40 return `${prefix}${clean(`${repo.name}-${repo.namespace}`).slice(0, MAX_LABEL - prefix.length - tail.length)}${tail}`.replace(
41 /-{3,}/g,
42 "--",
43 );
44}
45
46export function appUrl(script: string): string {
47 return `https://${script}.${DEPLOYMENTS_DOMAIN}`;
48}