g1t/apps/web/app/lib/workspace-deletion.ts

39 lines1,750 bytesCodeBlame
1/**
2 * What the danger zone of a workspace's settings says about deleting it:
3 * what goes with it, and why it cannot go. No Workers or React imports, so
4 * it can be tested under Node.
5 */
6import type { WorkspaceDeletion } from "@g1t/contracts";
7
8const plural = (n: number, one: string, many: string) => `${n} ${n === 1 ? one : many}`;
9
10/**
11 * What deleting the workspace takes with it, one line each, from what
12 * identity counted and the apps deployments has up (null when unknown).
13 * Nothing it does not hold is listed.
14 */
15export function whatGoes(deletion: WorkspaceDeletion, apps: number | null): string[] {
16 const lines: string[] = [];
17 if (deletion.repositories > 0) {
18 const their = deletion.repositories === 1 ? "its" : "their";
19 lines.push(`${plural(deletion.repositories, "repository", "repositories")}, with ${their} issues, pull requests and workflow runs`);
20 }
21 if (deletion.projects > 0) lines.push(plural(deletion.projects, "project", "projects"));
22 if (apps && apps > 0) lines.push(`${plural(apps, "live app", "live apps")}, taken offline`);
23 if (deletion.members > 0) {
24 lines.push(`Access for ${plural(deletion.members, "member", "members")}; their own accounts stay`);
25 }
26 return lines;
27}
28
29/** Why the workspace cannot be deleted, as a sentence, or null. */
30export function deletionRefusal(slug: string, deletion: WorkspaceDeletion | null): string | null {
31 if (!deletion) return null;
32 if (deletion.protected) return `${slug} is protected and can never be deleted.`;
33 return deletion.billing;
34}
35
36/** Whether what was typed confirms the slug: the slug itself, in any case. */
37export function confirmsSlug(slug: string, typed: string): boolean {
38 return typed.trim().toLowerCase() === slug.toLowerCase();
39}