configuration/strings/catalog.strings.ts
configuration/strings/catalog.strings.ts is a file in Bane's Lab Site. 170 lines of code and 37 definitions.
import {
ALGO_DOMAIN_FACE,
ALGO_FACE,
ARCH_CATEGORY_FACE,
ARCH_FACE,
FORCE_FACE,
KIND_FACE,
LAYER_FACE,
LEX_CATEGORY_FACE,
LEX_FACE,
PAG_FACE,
REASON_FACE,
RELATION_FACE,
STAGE_FACE,
TENSION_FACE,
VOCABULARY_FACE,
} from "@govlab/constants";
import { ANATOMY_FACE, CHAPTER_FACE } from "#configuration/constants/vocabulary.constants";
const INDEX_GROUP = "api";
export const COLLECTION_TITLES: ReadonlyMap<string, string> = new Map([
[ALGO_FACE, "Algorithm contracts"],
[ARCH_FACE, "Architecture principles"],
[LEX_FACE, "Lexicon terms"],
[REASON_FACE, "Reasoning records"],
[STAGE_FACE, "Loop stages"],
[LAYER_FACE, "Layers"],
[TENSION_FACE, "Tensions"],
[ALGO_DOMAIN_FACE, "Algorithm domains"],
[ARCH_CATEGORY_FACE, "Principle categories"],
[FORCE_FACE, "Forces"],
[KIND_FACE, "Record kinds"],
[LEX_CATEGORY_FACE, "Term categories"],
[RELATION_FACE, "Relations"],
[PAG_FACE, "Grammar records"],
[VOCABULARY_FACE, "Controlled vocabularies"],
]);
export const ADDRESS_GROUP_TITLES: ReadonlyMap<string, string> = new Map([
[CHAPTER_FACE, "sections"],
[ANATOMY_FACE, "source files and folders"],
[INDEX_GROUP, "indexes"],
]);
export const recordCountPhrase = function recordCountPhrase(count: number): string {
return `${String(count)} ${count === 1 ? "record" : "records"}`;
};
export const facetTitle = function facetTitle(collection: string, field: string, value: string): string {
return `${collection} whose ${field} is ${value}`;
};
export const addressGroupTitle = function addressGroupTitle(group: string): string {
return `Every published address for ${group}`;
};
export const nameShardTitle = function nameShardTitle(letter: string): string {
return `Name lookup entries for names that start with ${letter}`;
};
const neighborsClause = function neighborsClause(previous: string | null, next: string | null): string {
const after = previous === null ? null : `after ${previous}`;
const before = next === null ? null : `before ${next}`;
const neighbors = [after, before].filter((part): part is string => part !== null).join(" and ");
return neighbors.length === 0 ? "" : `, ${neighbors}`;
};
export const routeStopSentence = function routeStopSentence(
position: number,
total: number,
previous: string | null,
next: string | null,
): string {
return `This section is stop ${String(position)} of ${String(total)} in the learning route${neighborsClause(previous, next)}.`;
};
export const facetCollectionTitle = function facetCollectionTitle(collection: string): string {
return `${collection} by field`;
};
export const facetFieldTitle = function facetFieldTitle(collection: string, field: string): string {
return `${collection} by ${field}`;
};
export const listedInSentence = function listedInSentence(
index: string,
previous: string | null,
next: string | null,
): string {
return `Listed in ${index}${neighborsClause(previous, next)}.`;
};
const GROUP_TITLES: ReadonlyMap<string, string> = new Map([
["agent-creation", "Agent creation"],
["agent-workflow", "Agent workflow"],
["anti-patterns", "Anti-patterns"],
["arch-relationships", "Architecture relationships"],
["architecture", "Architecture"],
["automation", "Automation"],
["centralization", "Centralization"],
["checklist-creation", "Checklist creation"],
["codebase-verification", "Codebase verification"],
["context-verification", "Context verification"],
["coordination", "Coordination"],
["css-cascade", "CSS cascade"],
["governed-plan-loop", "Governed plan loop"],
["living-profile", "Living profile"],
["mode-driven-response-schema", "Mode-driven response schema"],
["pag", "Pattern Abstract Grammar"],
["pattern-distillation", "Pattern distillation"],
["quality-engine", "Quality engine"],
["taxonomy", "Taxonomy"],
["test-coverage", "Test coverage"],
]);
const ID_SEPARATORS: ReadonlySet<string> = new Set(["_", "-"]);
const spacedOf = function spacedOf(id: string): string {
let out = "";
for (const char of id) {
out += ID_SEPARATORS.has(char) ? " " : char;
}
return out;
};
const capitalized = function capitalized(text: string): string {
return text.charAt(0).toUpperCase() + text.slice(1);
};
const countOf = function countOf(count: number, singular: string, plural: string): string {
return `${String(count)} ${count === 1 ? singular : plural}`;
};
const namesOf = function namesOf(names: readonly string[]): string {
return names.length < 2 ? names.join("") : `${names.slice(0, -1).join(", ")} and ${names.at(-1) ?? ""}`;
};
export const groupTitleOf = function groupTitleOf(id: string, name: string): string {
if (name !== id) {
return name;
}
const title = GROUP_TITLES.get(id);
if (title === undefined) {
throw new Error(`catalog: the group "${id}" has no title`);
}
return title;
};
export const forceTitleOf = function forceTitleOf(id: string): string {
return capitalized(spacedOf(id));
};
export const groupSummary = function groupSummary(
name: string,
group: "category" | "domain",
count: number,
member: readonly [string, string],
): string {
return `The ${name} ${group} holds ${countOf(count, member[0], member[1])}.`;
};
export const PRINCIPLE_MEMBER: readonly [string, string] = ["architecture principle", "architecture principles"];
export const TERM_MEMBER: readonly [string, string] = ["lexicon term", "lexicon terms"];
export const CONTRACT_MEMBER: readonly [string, string] = ["algorithm contract", "algorithm contracts"];
export const forceSummary = function forceSummary(contracts: number, principles: number): string {
const parts = [
contracts === 0 ? null : countOf(contracts, CONTRACT_MEMBER[0], CONTRACT_MEMBER[1]),
principles === 0 ? null : countOf(principles, PRINCIPLE_MEMBER[0], PRINCIPLE_MEMBER[1]),
].filter((part): part is string => part !== null);
const verb = contracts + principles === 1 ? "names" : "name";
return `${capitalized(parts.join(" and "))} ${verb} this force.`;
};
export const relationSummary = function relationSummary(kinds: readonly string[]): string {
return kinds.length === 1
? `This relation points only at ${kinds[0] ?? ""} records.`
: `This relation can point at ${String(kinds.length)} kinds of record.`;
};
export const nodeSummary = function nodeSummary(concept: string, axis: string, mathType: string): string {
return `This node covers the ${spacedOf(concept)} concept on the ${spacedOf(axis)} axis. Its mathematical type is ${spacedOf(mathType)}.`;
};
export const substrateSummary = function substrateSummary(
layer: string,
mathType: string,
models: readonly string[],
): string {
const base = `This node sits on the ${spacedOf(layer)} layer. Its mathematical type is ${spacedOf(mathType)}.`;
return models.length === 0 ? base : `${base} The ${namesOf(models)} models build on it.`;
};
export const loopSummary = function loopSummary(name: string, stages: readonly string[]): string {
return `The ${name.toLowerCase()} runs through ${countOf(stages.length, "stage", "stages")}, from ${stages[0] ?? ""} to ${stages.at(-1) ?? ""}.`;
};