g1t/services/projects/src/description.ts
| 1 | /** |
| 2 | * A project's description follows its repository's until someone gives the |
| 3 | * project one of its own. The `description` column holds only that own |
| 4 | * text (null: inherit); `repo_description` is the repository's, kept from |
| 5 | * repos like its visibility and default branch. |
| 6 | */ |
| 7 | |
| 8 | /** The longest description a project keeps of its own. */ |
| 9 | export const MAX_DESCRIPTION = 200; |
| 10 | |
| 11 | /** The description a project shows, and whether it is its repository's. */ |
| 12 | export function effectiveDescription(row: { description: string | null; repo_description?: string | null }): { |
| 13 | description: string | null; |
| 14 | inherited: boolean; |
| 15 | } { |
| 16 | if (row.description != null) return { description: row.description, inherited: false }; |
| 17 | return { description: row.repo_description ?? null, inherited: true }; |
| 18 | } |
| 19 | |
| 20 | /** |
| 21 | * The own description to store for a change: unchanged when none is given, |
| 22 | * null (follow the repository) for null or blank text, otherwise the text. |
| 23 | */ |
| 24 | export function ownDescription(current: string | null, change: string | null | undefined): string | null { |
| 25 | if (change === undefined) return current; |
| 26 | const text = change?.trim() ?? ""; |
| 27 | return text ? text.slice(0, MAX_DESCRIPTION) : null; |
| 28 | } |