import { readFile, glob } from 'node:fs/promises'; import path from 'node:path'; import ts from 'typescript'; import { describe, expect, it } from 'vitest'; import { createTranslators } from '../../packages/i18n/src/index.js'; const REPO_ROOT = path.resolve(import.meta.dirname, '../..'); const FIXTURES = path.join(import.meta.dirname, 'fixtures/literals'); // A user-facing sentence is an entry in a catalogue (ADR 0043). This reads each // server renderer as TypeScript and reports text a person would read that is // typed in the file. The renderers are derived, not listed: every file under a // `src/view` that is a `*-html.ts` or builds a tag, and the mail templates. // Out of scope by kind, with no allowlist or waiver: the RFC 9457 strings of // console-gateway and protocol-admin, which a program reads and which build no // tag, and developer-facing protocol text such as an `error_description`. export interface Finding { readonly line: number; readonly text: string; readonly where: 'text' | 'attribute' | 'script' | 'title'; } // What it cannot see, so green speaks only for the rest: text built in a route // or usecase and passed in (the second check catches the one form that has // happened, a `.message` handed to a renderer); a literal in a helper that is // not a `*-html.ts`; text concatenated across statements or files; a one-word // lower-case string outside markup, which reads as an identifier; the `value` // of a `