prosebook 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +357 -26
- package/dist/bind-BIZNv8nU.js +62 -0
- package/dist/bind-BIZNv8nU.js.map +1 -0
- package/dist/bind-ZS86jHXk.d.ts +31 -0
- package/dist/bind-ZS86jHXk.d.ts.map +1 -0
- package/dist/bun.d.ts +12 -3
- package/dist/bun.d.ts.map +1 -1
- package/dist/bun.js +77 -26
- package/dist/bun.js.map +1 -1
- package/dist/{bundle-KD-DiiFa.d.ts → bundle-CLHY_97D.d.ts} +3 -3
- package/dist/bundle-CLHY_97D.d.ts.map +1 -0
- package/dist/bundle-Ut6Y2X6N.js +217 -0
- package/dist/bundle-Ut6Y2X6N.js.map +1 -0
- package/dist/cli.js +55 -12
- package/dist/cli.js.map +1 -1
- package/dist/{config-BPSmoYel.js → config-7T4hX_f7.js} +13 -5
- package/dist/{config-BPSmoYel.js.map → config-7T4hX_f7.js.map} +1 -1
- package/dist/{config-DdMkKt_N.d.ts → config-CzaJJQ60.d.ts} +19 -5
- package/dist/{config-DdMkKt_N.d.ts.map → config-CzaJJQ60.d.ts.map} +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/{copy-B3V_QRkT.d.ts → copy-BXn0aYQn.d.ts} +37 -3
- package/dist/copy-BXn0aYQn.d.ts.map +1 -0
- package/dist/copy-Bv6S-Hr2.js +235 -0
- package/dist/copy-Bv6S-Hr2.js.map +1 -0
- package/dist/endpoints-Dhgowovz.js +217 -0
- package/dist/endpoints-Dhgowovz.js.map +1 -0
- package/dist/generate-1BeQAd1O.d.ts +72 -0
- package/dist/generate-1BeQAd1O.d.ts.map +1 -0
- package/dist/{generate-9pR3i5Bj.js → generate-CKv86Iki.js} +1724 -627
- package/dist/generate-CKv86Iki.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/next-loader.d.ts +9 -2
- package/dist/next-loader.d.ts.map +1 -1
- package/dist/next-loader.js +12 -3
- package/dist/next-loader.js.map +1 -1
- package/dist/next.d.ts +11 -3
- package/dist/next.d.ts.map +1 -1
- package/dist/next.js +94 -21
- package/dist/next.js.map +1 -1
- package/dist/preact/index.d.ts +34 -0
- package/dist/preact/index.d.ts.map +1 -0
- package/dist/preact/index.js +72 -0
- package/dist/preact/index.js.map +1 -0
- package/dist/react/index.d.ts +5 -14
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +9 -33
- package/dist/react/index.js.map +1 -1
- package/dist/react/server.d.ts +1 -1
- package/dist/react/server.js +1 -1
- package/dist/{sarif-CWyTAQ0y.js → sarif-BnwYC78_.js} +8 -98
- package/dist/sarif-BnwYC78_.js.map +1 -0
- package/dist/{scan-Bx0_yDSi.js → scan-C0ap4Mpp.js} +145 -20
- package/dist/scan-C0ap4Mpp.js.map +1 -0
- package/dist/solid/index.d.ts +29 -0
- package/dist/solid/index.d.ts.map +1 -0
- package/dist/solid/index.js +48 -0
- package/dist/solid/index.js.map +1 -0
- package/dist/svelte/Text.svelte +13 -0
- package/dist/svelte/Text.svelte.d.ts +20 -0
- package/dist/svelte/index.d.ts +31 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +35 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/tools.d.ts +44 -65
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +5 -5
- package/dist/vite.d.ts +13 -3
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +82 -25
- package/dist/vite.js.map +1 -1
- package/dist/vue/index.d.ts +43 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue/index.js +76 -0
- package/dist/vue/index.js.map +1 -0
- package/package.json +63 -7
- package/src/bun.ts +77 -20
- package/src/cli.ts +62 -8
- package/src/index.ts +1 -1
- package/src/next-loader.ts +17 -5
- package/src/next.ts +120 -16
- package/src/preact/index.ts +91 -0
- package/src/react/index.tsx +12 -42
- package/src/runtime/bind.ts +96 -0
- package/src/runtime/copy.ts +148 -24
- package/src/solid/index.ts +67 -0
- package/src/svelte/Text.svelte +13 -0
- package/src/svelte/Text.svelte.d.ts +20 -0
- package/src/svelte/index.ts +65 -0
- package/src/tools/bundle.ts +143 -2
- package/src/tools/catalog.ts +10 -1
- package/src/tools/chunks.ts +142 -0
- package/src/tools/config.ts +25 -7
- package/src/tools/entry.ts +19 -20
- package/src/tools/exchange.ts +275 -0
- package/src/tools/extract.ts +2 -2
- package/src/tools/generate.ts +7 -1
- package/src/tools/index.ts +2 -1
- package/src/tools/native/android.ts +186 -0
- package/src/tools/native/apple.ts +201 -0
- package/src/tools/native/date.ts +219 -0
- package/src/tools/native/index.ts +17 -5
- package/src/tools/native/kotlin.ts +47 -6
- package/src/tools/native/model.ts +67 -29
- package/src/tools/native/printf.ts +137 -0
- package/src/tools/native/rust.ts +86 -5
- package/src/tools/native/swift.ts +62 -6
- package/src/tools/scan.ts +146 -25
- package/src/tools/todo.ts +6 -1
- package/src/vite.ts +121 -28
- package/src/vue/index.ts +117 -0
- package/dist/bundle-DboItAre.js +0 -111
- package/dist/bundle-DboItAre.js.map +0 -1
- package/dist/bundle-KD-DiiFa.d.ts.map +0 -1
- package/dist/compile-xF3F4oIp.d.ts +0 -16
- package/dist/compile-xF3F4oIp.d.ts.map +0 -1
- package/dist/copy-B3V_QRkT.d.ts.map +0 -1
- package/dist/copy-Bo_FIoLy.js +0 -154
- package/dist/copy-Bo_FIoLy.js.map +0 -1
- package/dist/endpoints-CnUfCkIk.js +0 -96
- package/dist/endpoints-CnUfCkIk.js.map +0 -1
- package/dist/generate-9pR3i5Bj.js.map +0 -1
- package/dist/sarif-CWyTAQ0y.js.map +0 -1
- package/dist/scan-Bx0_yDSi.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sarif-CWyTAQ0y.js","names":[],"sources":["../src/tools/types.ts","../src/tools/extract.ts","../src/tools/migrate.ts","../src/tools/todo.ts","../src/tools/sarif.ts"],"sourcesContent":["/**\n * What kind of value an expression in JSX holds, so `extract` can write `{n, number}` for a number and\n * `{d, date, medium}` for a date instead of a bare `{x}`, which is text and prints a number unformatted.\n *\n * The project's own TypeScript (7 or later, through its `unstable/async` API) answers where it can; the\n * syntax of the expression answers where it can't: a JavaScript project, a file outside any tsconfig,\n * or no TypeScript installed. Not the `unstable/sync` API: on Linux and macOS it reads the compiler's\n * pipes through a Node internal (`stdout._handle.fd`) that Bun doesn't have, so under Bun it throws.\n */\nimport { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\n\nimport type * as TsAsync from 'typescript/unstable/async';\nimport type { Checker, Type } from 'typescript/unstable/async';\n\n// oxlint-disable-next-line typescript/no-explicit-any -- a loose ESTree node: the walk reads whichever fields each node type has\ntype Node = { type: string; start: number; end: number; [field: string]: any };\n\ntype TsNode = { pos: number; end: number; forEachChild(visit: (child: TsNode) => unknown): unknown };\n\n/** `node` is markup or an object, which a message can't hold as text. */\nexport type ValueKind = 'string' | 'number' | 'date' | 'node' | 'unknown';\n\nexport interface Span {\n start: number;\n end: number;\n}\n\nexport interface TypeOracle {\n /** Where the answers come from, for the report. */\n readonly source: string;\n /** The kind of each span's expression in `file`, or nothing where the oracle can't say. */\n kinds(file: string, spans: readonly Span[]): Promise<(ValueKind | undefined)[]>;\n close(): Promise<void>;\n}\n\n/** The nearest `tsconfig.json` at or above the file's folder. */\nfunction tsconfigFor(file: string): string | undefined {\n for (let dir = dirname(resolve(file)); ; dir = dirname(dir)) {\n const candidate = join(dir, 'tsconfig.json');\n if (existsSync(candidate)) return candidate;\n if (dirname(dir) === dir) return undefined;\n }\n}\n\n// TypeFlags, as the TypeScript 7 API numbers them.\nconst ANY_OR_UNKNOWN = 3;\nconst NUMBER_LIKE = 67648 | 4224;\nconst STRING_LIKE = 12583968;\nconst UNION = 134217728;\nconst OBJECT = 1048576;\n\n/**\n * An oracle over the projects the files belong to, or nothing where TypeScript 7 isn't installed or\n * none of the files has a tsconfig. One compiler process serves every project and is closed by `close`.\n */\nexport async function typescriptOracle(root: string, files: readonly string[]): Promise<TypeOracle | undefined> {\n const configs = [...new Set(files.map(tsconfigFor).filter((c) => c !== undefined))];\n if (configs.length === 0) return undefined;\n let ts: typeof TsAsync;\n try {\n ts = await import('typescript/unstable/async');\n } catch {\n return undefined;\n }\n let api: InstanceType<typeof ts.API>;\n let snapshot: Awaited<ReturnType<InstanceType<typeof ts.API>['updateSnapshot']>>;\n try {\n api = new ts.API({ cwd: root });\n snapshot = await api.updateSnapshot({ openProjects: configs });\n } catch {\n return undefined;\n }\n\n const classify = async (checker: Checker, type: Type | undefined): Promise<ValueKind | undefined> => {\n if (type === undefined) return undefined;\n const t = (await checker.getNonNullableType(type)) ?? type;\n if ((t.flags & ANY_OR_UNKNOWN) !== 0) return 'unknown';\n if ((t.flags & UNION) !== 0) {\n const members = (await (t as Type & { getTypes(): Promise<readonly Type[] | undefined> }).getTypes()) ?? [];\n const kinds = new Set(await Promise.all(members.map((m) => classify(checker, m))));\n if (kinds.size === 1) return [...kinds][0];\n return kinds.has('node') ? 'node' : 'unknown';\n }\n if ((t.flags & NUMBER_LIKE) !== 0) return 'number';\n if ((t.flags & STRING_LIKE) !== 0) return 'string';\n if ((await checker.typeToString(t)) === 'Date') return 'date';\n if ((t.flags & OBJECT) !== 0) return 'node';\n return 'unknown';\n };\n\n return {\n source: 'TypeScript',\n async kinds(file, spans) {\n const project = await snapshot.getDefaultProjectForFile(resolve(file));\n const sourceFile = await project?.program.getSourceFile(resolve(file));\n if (project === undefined || sourceFile === undefined) return spans.map(() => undefined);\n // The smallest node covering each span is the expression itself.\n const nodes = spans.map(({ start, end }) => {\n let node: TsNode = sourceFile;\n for (;;) {\n let next: TsNode | undefined;\n node.forEachChild((child) => {\n if (next === undefined && child.pos <= start && child.end >= end) next = child;\n });\n if (next === undefined) return node;\n node = next;\n }\n });\n const types = await project.checker.getTypeAtLocation(nodes as never[]);\n return Promise.all(types.map((type) => classify(project.checker, type)));\n },\n close() {\n return api.close();\n },\n };\n}\n\n/** The kind an expression's syntax gives away, where it does: `items.length`, `a * b`, `new Date()`. */\nexport function syntaxKind(expr: Node): ValueKind | undefined {\n switch (expr.type) {\n case 'Literal':\n return typeof expr.value === 'number' ? 'number' : typeof expr.value === 'string' ? 'string' : undefined;\n case 'TemplateLiteral':\n return 'string';\n case 'MemberExpression':\n return !expr.computed && ['length', 'size', 'count'].includes(expr.property?.name as string) ? 'number' : undefined;\n case 'BinaryExpression':\n return ['-', '*', '/', '%', '**'].includes(expr.operator as string) ? 'number' : undefined;\n case 'NewExpression':\n return expr.callee?.type === 'Identifier' && expr.callee.name === 'Date' ? 'date' : undefined;\n case 'CallExpression':\n return expr.callee?.type === 'MemberExpression' && expr.callee.object?.name === 'Math' ? 'number' : undefined;\n default:\n return undefined;\n }\n}\n","/**\n * `prosebook extract`: moves hardcoded JSX text into the catalog and rewrites the code to read it.\n *\n * It works on runs, not fragments. The children of an element that together make one sentence, text,\n * simple expressions and inline elements holding only text, become one message: `Hi {user.name}, <a\n * href=\"/x\">go</a>!` is `Hi {name}, <a>go</a>!`, so a translator can reorder the whole sentence. A run\n * becomes `<Text id=… />`, which needs no hook; a readable attribute becomes `t('…')`, with `useCopy()`\n * added to its component. Keys, kinds, surfaces and contexts are suggestions, marked for review.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { basename, dirname, extname, join, relative } from 'node:path';\n\nimport { parseSync } from 'oxc-parser';\nimport { stringify } from 'yaml';\n\nimport { CatalogError, KEY_PATTERN, loadCatalog } from './catalog.ts';\nimport type { ResolvedConfig } from './config.ts';\nimport { parseMessage } from './icu.ts';\nimport { singularOf } from './lint.ts';\nimport { looksLikeCode } from './scan.ts';\nimport { writeMessage } from './syntax.ts';\nimport { syntaxKind, typescriptOracle, type Span, type ValueKind } from './types.ts';\n\n// oxlint-disable-next-line typescript/no-explicit-any -- a loose ESTree node: the walk reads whichever fields each node type has\ntype Node = { type: string; start: number; end: number; [field: string]: any };\n\nexport interface Extraction {\n file: string;\n line: number;\n column: number;\n key: string;\n /** The ICU message. */\n message: string;\n /** Whether an entry with this key and message already exists, so none is added. */\n reused: boolean;\n where: string;\n /** The code that replaces the hardcoded text. */\n replacement: string;\n}\n\nexport interface NewEntry {\n key: string;\n area: string;\n message: string;\n kind?: string;\n surface?: string;\n context: string;\n args: Record<string, string>;\n}\n\ninterface Edit {\n start: number;\n end: number;\n text: string;\n}\n\nexport interface FilePlan {\n path: string;\n file: string;\n code: string;\n edits: Edit[];\n extractions: Extraction[];\n warnings: string[];\n}\n\nexport interface ExtractPlan {\n files: FilePlan[];\n entries: NewEntry[];\n /** What said which placeholders are numbers and dates: `TypeScript`, or `syntax` alone. */\n types: string;\n}\n\nconst MODULE = 'prosebook/react';\nconst NON_PROSE = new Set(['code', 'pre', 'kbd', 'samp', 'script', 'style', 'svg', 'path', 'Text']);\nconst LETTER = /\\p{L}/u;\n\n/** Elements that sit inside a sentence, and so become a tag in its message rather than ending it. */\nconst INLINE = new Set([\n 'a',\n 'abbr',\n 'b',\n 'bdi',\n 'cite',\n 'del',\n 'dfn',\n 'em',\n 'i',\n 'ins',\n 'kbd',\n 'mark',\n 'q',\n 's',\n 'small',\n 'span',\n 'strong',\n 'sub',\n 'sup',\n 'time',\n 'u',\n 'var',\n]);\nconst isInline = (name: string) => INLINE.has(name) || /^[A-Z]\\w*Link$|^Link$/.test(name);\n\n/** Elements whose text has an obvious kind and surface. */\nconst ROLES: Record<string, [kind: string, surface: string]> = {\n button: ['action', 'action'],\n h1: ['name', 'heading'],\n h2: ['name', 'heading'],\n h3: ['name', 'heading'],\n h4: ['name', 'heading'],\n h5: ['name', 'heading'],\n h6: ['name', 'heading'],\n th: ['name', 'heading'],\n legend: ['name', 'heading'],\n caption: ['name', 'heading'],\n label: ['name', 'label'],\n option: ['name', 'choice'],\n title: ['name', 'title'],\n};\n\n/** Readable attributes: the kind and surface their value has, and the key suffix that says which it is. */\nconst ATTRIBUTE_ROLES: Record<string, [kind: string | undefined, surface: string, suffix: string]> = {\n placeholder: [undefined, 'placeholder', 'placeholder'],\n title: ['name', 'tooltip', 'tooltip'],\n 'aria-label': ['name', 'aria', 'aria'],\n 'aria-description': ['description', 'aria', 'aria-description'],\n 'aria-placeholder': [undefined, 'aria', 'aria-placeholder'],\n alt: [undefined, 'aria', 'alt'],\n label: ['name', 'label', 'label'],\n};\n\n/** The area a file's strings go in: its name in kebab case, or its folder's for an `index`. */\nexport function areaOf(file: string): string {\n let name = basename(file, extname(file));\n if (['index', 'page', 'layout', 'route', 'main'].includes(name)) name = basename(dirname(file));\n const kebab = name\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return kebab === '' ? 'app' : kebab;\n}\n\n/** A key segment from the words of a message: its first four, plain ASCII, lowercase. */\nexport function slugOf(message: string): string {\n const words = message\n .replace(/<\\/?[\\w-]+>|\\{[^}]*\\}/g, ' ')\n .replace(/ı/g, 'i')\n .normalize('NFKD')\n .replace(/[̀-ͯ]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .trim()\n .split(' ')\n .filter(Boolean)\n .slice(0, 4);\n return words.length === 0 ? 'text' : words.join('-');\n}\n\n/**\n * A count followed by a plural noun, `{n, number} files`, as the plural it needs: `{n, plural, one {#\n * file} other {# files}}`. English only, and a draft: the TODO above the entry asks for a look.\n */\nexport function draftPlurals(message: string): string {\n return message.replace(/\\{(\\w+), number\\} (\\p{L}+)(?![\\p{L}'])/gu, (whole, name: string, word: string) => {\n const one = singularOf(word);\n return one === undefined ? whole : `{${name}, plural, one {# ${one}} other {# ${word}}}`;\n });\n}\n\n/** A message built as MF1, as the catalog writes messages: an MF2 catalog gets it in MF2. */\nfunction inSyntax(config: ResolvedConfig, mf1: string): string {\n return config.messageFormat === 2 ? writeMessage(2, parseMessage(mf1), config.source) : mf1;\n}\n\n/** Text written literally inside an ICU message. */\nfunction escapeIcu(text: string): string {\n return text.replace(/[{}<]/g, (c) => `'${c}'`);\n}\n\n/** JSX text as React renders it: lines trimmed where they meet a line break, blank lines dropped. */\nfunction jsxText(value: string): string {\n const lines = value.split(/\\r\\n|\\n|\\r/);\n // As Babel does: a value with no visible characters still keeps its one line, so a lone space renders.\n let lastNonEmpty = 0;\n lines.forEach((line, i) => {\n if (/[^ \\t]/.test(line)) lastNonEmpty = i;\n });\n let out = '';\n lines.forEach((line, i) => {\n let trimmed = line.replace(/\\t/g, ' ');\n if (i !== 0) trimmed = trimmed.replace(/^ +/, '');\n if (i !== lines.length - 1) trimmed = trimmed.replace(/ +$/, '');\n if (trimmed === '') return;\n out += i === lastNonEmpty ? trimmed : `${trimmed} `;\n });\n return out;\n}\n\nconst SIMPLE_EXPRESSIONS = new Set([\n 'Identifier',\n 'MemberExpression',\n 'CallExpression',\n 'TemplateLiteral',\n 'Literal',\n 'BinaryExpression',\n 'TSNonNullExpression',\n 'ChainExpression',\n]);\n\n/** A value that reads as a placeholder: no JSX and no functions inside it, which would be markup or logic. */\nfunction simple(expr: Node): boolean {\n if (!SIMPLE_EXPRESSIONS.has(expr.type)) return false;\n let found = false;\n const walk = (node: Node) => {\n if (found) return;\n if (/^JSX|FunctionExpression$/.test(node.type)) found = true;\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) value.forEach((v) => isNode(v) && walk(v));\n else if (isNode(value)) walk(value);\n }\n };\n walk(expr);\n return !found;\n}\n\n/** Every name bound inside a node: declarations, parameters, catch clauses, imports. With `deep` false, only its own scope's. */\nfunction bindingsIn(root: Node, deep = true): Set<string> {\n const names = new Set<string>();\n const pattern = (p: Node | null | undefined) => {\n if (!p) return;\n if (p.type === 'Identifier') names.add(p.name as string);\n else if (p.type === 'ObjectPattern')\n for (const prop of p.properties as Node[]) pattern(prop.type === 'RestElement' ? prop : prop.value);\n else if (p.type === 'ArrayPattern') for (const el of p.elements as (Node | null)[]) pattern(el);\n else if (p.type === 'AssignmentPattern') pattern(p.left);\n else if (p.type === 'RestElement') pattern(p.argument);\n };\n const walk = (node: Node, top: boolean) => {\n if (node.type === 'VariableDeclarator') pattern(node.id);\n if (node.type === 'ImportSpecifier' || node.type === 'ImportDefaultSpecifier' || node.type === 'ImportNamespaceSpecifier')\n pattern(node.local);\n if ((node.type === 'FunctionDeclaration' || node.type === 'ClassDeclaration') && node.id) pattern(node.id);\n if (node.type === 'CatchClause') pattern(node.param);\n const isFunction = /Function(?:Declaration|Expression)$|^ArrowFunctionExpression$/.test(node.type);\n if (isFunction && (deep || top)) for (const param of node.params as Node[]) pattern(param);\n if (isFunction && !deep && !top) return;\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) {\n for (const child of value) if (isNode(child)) walk(child, false);\n } else if (isNode(value)) {\n walk(value, false);\n }\n }\n };\n walk(root, true);\n return names;\n}\n\nfunction elementName(el: Node): string | undefined {\n const name = el.openingElement?.name as Node | undefined;\n return name?.type === 'JSXIdentifier' ? (name.name as string) : undefined;\n}\n\nfunction isNode(value: unknown): value is Node {\n return typeof value === 'object' && value !== null && typeof (value as Node).type === 'string';\n}\n\ninterface Context {\n config: ResolvedConfig;\n area: string;\n /** Every key's source message, the catalog's and those added in this run. */\n known: Map<string, string>;\n entries: NewEntry[];\n /** The kind of value each JSX expression holds, by `start:end`. */\n kinds: Map<string, ValueKind>;\n}\n\n/** Plans the extraction from one file: the edits and the entries, without writing anything. */\nfunction planFile(path: string, ctx: Context): FilePlan {\n const code = readFileSync(path, 'utf8');\n const file = relative(ctx.config.root, path).replaceAll('\\\\', '/');\n const plan: FilePlan = { path, file, code, edits: [], extractions: [], warnings: [] };\n const { program } = parseSync(file, code);\n const topLevel = bindingsIn(program, false);\n const lines = code.split('\\n');\n const lineStarts: number[] = [];\n let offset = 0;\n for (const line of lines) {\n lineStarts.push(offset);\n offset += line.length + 1;\n }\n const position = (at: number) => {\n let line = lineStarts.findIndex((s) => s > at);\n line = line === -1 ? lineStarts.length : line;\n return { line, column: at - lineStarts[line - 1]! + 1 };\n };\n const ignored = (at: number) => {\n const { line } = position(at);\n return (lines[line - 1] ?? '').includes('prosebook-ignore') || (lines[line - 2] ?? '').includes('prosebook-ignore');\n };\n\n let needText = false;\n let needUseCopy = false;\n /** Per component, by where it starts: the call that reads the catalog there. */\n const hooked = new Map<number, string>();\n /** Children now inside a `<Text>`, which the walk does not enter. */\n const consumed = new Set<Node>();\n /** Enclosing functions, innermost last: the component each belongs to, and whether it is one. */\n const components: { fn: Node; name: string | undefined; isComponent: boolean }[] = [];\n\n const componentName = (fn: Node, parent: Node | undefined): string | undefined => {\n if (fn.id?.name) return fn.id.name as string;\n if (parent?.type === 'VariableDeclarator' && parent.id?.type === 'Identifier') return parent.id.name as string;\n return undefined;\n };\n\n const entryFor = (\n message: string,\n args: Record<string, string>,\n role: [string | undefined, string | undefined],\n context: string,\n suffix?: string,\n ) => {\n for (const [key, text] of ctx.known) if (text === message && key.startsWith(`${ctx.area}.`)) return { key, reused: true };\n\n const base = `${ctx.area}.${slugOf(message)}${suffix ? `-${suffix}` : ''}`;\n let key = base;\n for (let n = 2; ctx.known.has(key); n++) key = `${base}-${n}`;\n ctx.known.set(key, message);\n const [kind, surface] = role;\n ctx.entries.push({\n key,\n area: ctx.area,\n message,\n ...(kind !== undefined && kind in ctx.config.kinds ? { kind } : {}),\n ...(surface !== undefined && surface in ctx.config.surfaces ? { surface } : {}),\n context,\n args,\n });\n return { key, reused: false };\n };\n\n const where = (element: string | undefined) => {\n const component = components.at(-1)?.name;\n return `${component ? `In ${component}` : `In ${file}`}${element ? `, the text of a <${element}>` : ''}.`;\n };\n\n /** The children of one element, split into runs at anything that cannot sit inside a sentence. */\n const extractChildren = (parent: Node, children: Node[]) => {\n const parentName = parent.type === 'JSXElement' ? elementName(parent) : undefined;\n let run: Node[] = [];\n const flush = () => {\n if (run.length > 0) extractRun(run, parentName);\n run = [];\n };\n for (const child of children) {\n if (inlineable(child)) run.push(child);\n else flush();\n }\n flush();\n };\n\n const inlineable = (child: Node): boolean => {\n if (child.type === 'JSXText') return true;\n if (child.type === 'JSXExpressionContainer') return simple(child.expression as Node);\n if (child.type === 'JSXElement') {\n const name = elementName(child);\n if (name === undefined || child.openingElement.selfClosing || !isInline(name)) return false;\n return (child.children as Node[]).every(inlineable);\n }\n return false;\n };\n\n const extractRun = (run: Node[], parentName: string | undefined) => {\n // Whitespace-only text at either end stays where it is, so the layout around the run is unchanged.\n const blank = (n: Node) => n.type === 'JSXText' && jsxText(n.value as string).trim() === '';\n const from = run.findIndex((n) => !blank(n));\n if (from === -1) return;\n const nodes = run.slice(from, run.findLastIndex((n) => !blank(n)) + 1);\n // Elements with nothing but whitespace between them are layout, not a sentence: each one's text is\n // its own, as `<li><a href>Home</a></li>` is \"Home\".\n if (nodes.every((n) => n.type === 'JSXElement' || blank(n))) return;\n const first = nodes[0]!;\n const last = nodes.at(-1)!;\n const values = new Map<string, string>();\n const argDocs: Record<string, string> = {};\n const names = new Map<string, string>();\n const tags = new Set<string>();\n\n const argName = (expr: Node): string => {\n const source = code.slice(expr.start, expr.end);\n const known = names.get(source);\n if (known !== undefined) return known;\n let inner = expr;\n while (inner.type === 'TSNonNullExpression' || inner.type === 'ChainExpression') inner = inner.expression;\n let name =\n inner.type === 'Identifier'\n ? (inner.name as string)\n : inner.type === 'MemberExpression' && !inner.computed && inner.property?.type === 'Identifier'\n ? (inner.property.name as string)\n : 'value';\n const base = name;\n for (let n = 2; values.has(name) || tags.has(name); n++) name = `${base}${n}`;\n names.set(source, name);\n values.set(name, source);\n argDocs[name] = `TODO: what \\`${source}\\` holds`;\n return name;\n };\n\n const piece = (node: Node): string => {\n if (node.type === 'JSXText') return escapeIcu(jsxText(node.value as string));\n if (node.type === 'JSXElement') {\n let tag = elementName(node)!.toLowerCase();\n const base = tag;\n for (let n = 2; tags.has(tag) || values.has(tag); n++) tag = `${base}${n}`;\n tags.add(tag);\n const open = code.slice(node.openingElement.start, node.openingElement.end);\n const close = code.slice(node.closingElement.start, node.closingElement.end);\n values.set(tag, `(chunks) => ${open}{chunks}${close}`);\n return `<${tag}>${(node.children as Node[]).map(piece).join('')}</${tag}>`;\n }\n const expr = node.expression as Node;\n if (expr.type === 'Literal' && typeof expr.value === 'string') return escapeIcu(expr.value);\n if (expr.type === 'TemplateLiteral' && expr.expressions.length === 0) return escapeIcu(expr.quasis[0].value.cooked as string);\n const kind = ctx.kinds.get(`${expr.start}:${expr.end}`) ?? syntaxKind(expr);\n if (kind === 'node') markup.push(code.slice(expr.start, expr.end));\n return `{${argName(expr)}${kind === 'number' ? ', number' : kind === 'date' ? ', date, medium' : ''}}`;\n };\n\n const markup: string[] = [];\n let message = nodes.map(piece).join('').trim();\n if (markup.length > 0) {\n const at = position(first.start);\n plan.warnings.push(\n `${file}:${at.line}:${at.column} {${markup.join('}, {')}} holds markup, not text, so this sentence was left as it is: make it a tag, or give the text around it entries of its own`,\n );\n return;\n }\n if (/^en\\b/.test(ctx.config.source)) message = draftPlurals(message);\n // A run of spaces, placeholders and punctuation is layout, not words.\n const words = message.replace(/\\{[^}]*\\}|<\\/?[\\w-]+>|'[{}<]'/g, '');\n if (!LETTER.test(words) || (values.size === 0 && looksLikeCode(message))) return;\n // The whitespace at either end stays in the code as it was: a space still renders as one, and a\n // line break still renders as nothing.\n const start = first.type === 'JSXText' ? first.start + (/^\\s*/.exec(first.value as string)?.[0].length ?? 0) : first.start;\n const end = last.type === 'JSXText' ? last.end - (/\\s*$/.exec(last.value as string)?.[0].length ?? 0) : last.end;\n if (ignored(start)) return;\n\n message = inSyntax(ctx.config, message);\n const role = parentName !== undefined ? ROLES[parentName] : undefined;\n const { key, reused } = entryFor(message, argDocs, role ?? [undefined, undefined], where(parentName));\n const props = [...values].map(([name, source]) => `${/^[A-Za-z_$][\\w$]*$/.test(name) ? name : JSON.stringify(name)}: ${source}`);\n const replacement = `<Text id=${JSON.stringify(key)}${props.length > 0 ? ` values={{ ${props.join(', ')} }}` : ''} />`;\n plan.edits.push({ start, end, text: replacement });\n for (const n of nodes) consumed.add(n);\n plan.extractions.push({ file, ...position(start), key, message, reused, where: 'text', replacement });\n needText = true;\n };\n\n const extractAttribute = (attr: Node, element: Node) => {\n const name = attr.name?.type === 'JSXIdentifier' ? (attr.name.name as string) : '';\n if (!ctx.config.scan.attributes.includes(name) || attr.value === null) return;\n const value = attr.value as Node;\n let text: string | undefined;\n if (value.type === 'Literal' && typeof value.value === 'string') {\n text = value.value;\n } else if (value.type === 'JSXExpressionContainer') {\n const expr = value.expression as Node;\n if (expr.type === 'Literal' && typeof expr.value === 'string') text = expr.value;\n if (expr.type === 'TemplateLiteral' && expr.expressions.length === 0) text = expr.quasis[0].value.cooked as string;\n }\n if (text === undefined || !LETTER.test(text) || looksLikeCode(text) || ignored(attr.start)) return;\n const at = position(value.start);\n const fn = components.findLast((c) => c.isComponent)?.fn;\n if (fn === undefined || fn.body?.type !== 'BlockStatement') {\n plan.warnings.push(\n `${file}:${at.line}:${at.column} ${name}=\"${text}\" is not inside a component with a body, so it has no t() to read; left as it is`,\n );\n return;\n }\n const call = hookFor(fn);\n if (call === undefined) {\n plan.warnings.push(\n `${file}:${at.line}:${at.column} ${name}=\"${text}\": its component binds both \\`t\\` and \\`copy\\` already; left as it is`,\n );\n return;\n }\n const [kind, surface, suffix] = ATTRIBUTE_ROLES[name] ?? [undefined, undefined, name];\n const tag = elementName(element) ?? 'element';\n const component = components.at(-1)?.name;\n const context = `${component ? `In ${component}` : `In ${file}`}, the ${name} of a <${tag}>.`;\n const message = inSyntax(ctx.config, escapeIcu(text));\n const { key, reused } = entryFor(message, {}, [kind, surface], context, suffix);\n const replacement = `{${call}(${JSON.stringify(key)})}`;\n plan.edits.push({ start: value.start, end: value.end, text: replacement });\n plan.extractions.push({ file, ...at, key, message, reused, where: name, replacement });\n };\n\n /**\n * Makes sure the component can read the catalog, and returns the call that does: `t` from\n * `useCopy()`, or `copy.t` where the component or the module already binds a `t` of its own.\n */\n const hookFor = (fn: Node): string | undefined => {\n const chosen = hooked.get(fn.start);\n if (chosen !== undefined) return chosen;\n const taken = new Set([...topLevel, ...bindingsIn(fn)]);\n const body = code.slice(fn.body.start, fn.body.end);\n const insert = (text: string) => plan.edits.push({ start: fn.body.start + 1, end: fn.body.start + 1, text });\n const firstStatement = fn.body.body[0] as Node | undefined;\n const indent = firstStatement ? ' '.repeat(position(firstStatement.start).column - 1) : ' ';\n let call: string | undefined;\n const destructured = /\\{([^{}]*)\\}\\s*=\\s*useCopy\\(\\)/.exec(body);\n const whole = /\\b(?:const|let|var)\\s+([A-Za-z_$][\\w$]*)\\s*=\\s*useCopy\\(\\)/.exec(body);\n if (destructured !== null && /(^|[\\s,])t(\\s*[,}]|\\s*$)/.test(destructured[1]!)) {\n call = 't';\n } else if (whole !== null) {\n call = `${whole[1]}.t`;\n } else if (destructured !== null && !taken.has('t')) {\n const at = fn.body.start + destructured.index + 1;\n plan.edits.push({ start: at, end: at, text: ' t,' });\n call = 't';\n } else if (!taken.has('t')) {\n insert(`\n${indent}const { t } = useCopy();`);\n call = 't';\n } else if (!taken.has('copy')) {\n insert(`\n${indent}const copy = useCopy();`);\n call = 'copy.t';\n }\n if (call !== undefined && destructured === null && whole === null) needUseCopy = true;\n if (call !== undefined) hooked.set(fn.start, call);\n return call;\n };\n\n const visit = (node: Node, parent: Node | undefined) => {\n const isFunction = node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';\n if (isFunction) {\n const own = componentName(node, parent);\n const isComponent = own !== undefined && /^(?:[A-Z]|use[A-Z])/.test(own);\n components.push({ fn: node, name: isComponent ? own : components.at(-1)?.name, isComponent });\n }\n if (node.type === 'JSXElement' || node.type === 'JSXFragment') {\n const name = node.type === 'JSXElement' ? elementName(node) : undefined;\n if (node.type === 'JSXElement') {\n for (const attr of node.openingElement.attributes as Node[]) {\n if (attr.type !== 'JSXAttribute') continue;\n extractAttribute(attr, node);\n // `render={() => <p>Hi</p>}` holds JSX of its own.\n if (attr.value?.type === 'JSXExpressionContainer') visit(attr.value as Node, attr);\n }\n }\n if (name === undefined || !NON_PROSE.has(name)) {\n extractChildren(node, node.children as Node[]);\n for (const child of node.children as Node[]) if (!consumed.has(child)) visit(child, node);\n }\n return;\n }\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) {\n for (const child of value) if (isNode(child)) visit(child, node);\n } else if (isNode(value)) {\n visit(value, node);\n }\n }\n if (isFunction) components.pop();\n };\n\n visit(program, undefined);\n plan.extractions.sort((a, b) => (a.line !== b.line ? a.line - b.line : a.column - b.column));\n if (needText || needUseCopy) importEdit(program, code, plan, [...(needText ? ['Text'] : []), ...(needUseCopy ? ['useCopy'] : [])]);\n return plan;\n}\n\n/** Adds the names to an existing `prosebook/react` import, or a new import after the last one. */\nfunction importEdit(program: Node, code: string, plan: FilePlan, wanted: string[]) {\n const imports = (program.body as Node[]).filter((s) => s.type === 'ImportDeclaration');\n const existing = imports.find((s) => s.source.value === MODULE && s.importKind !== 'type');\n if (existing) {\n const named = (existing.specifiers as Node[]).filter((s) => s.type === 'ImportSpecifier');\n const have = new Set(named.map((s) => s.local.name as string));\n const missing = wanted.filter((w) => !have.has(w));\n if (missing.length === 0) return;\n if (named.length > 0) {\n plan.edits.push({ start: named.at(-1)!.end, end: named.at(-1)!.end, text: `, ${missing.join(', ')}` });\n return;\n }\n }\n const line = `import { ${wanted.join(', ')} } from '${MODULE}';`;\n const last = imports.at(-1);\n if (last) {\n plan.edits.push({ start: last.end, end: last.end, text: `\\n${line}` });\n } else {\n const directive = /^(?:\\s*(['\"])use \\w+\\1;?\\s*\\n)*/.exec(code)?.[0] ?? '';\n plan.edits.push({ start: directive.length, end: directive.length, text: `${line}\\n${directive === '' ? '\\n' : ''}` });\n }\n}\n\n/** The spans of every expression inside JSX, which are the ones that may become placeholders. */\nfunction jsxExpressions(file: string, code: string): Span[] {\n const spans: Span[] = [];\n const walk = (node: Node) => {\n if (node.type === 'JSXExpressionContainer' && node.expression.type !== 'JSXEmptyExpression')\n spans.push({ start: node.expression.start as number, end: node.expression.end as number });\n\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) {\n for (const child of value) if (isNode(child)) walk(child);\n } else if (isNode(value)) {\n walk(value);\n }\n }\n };\n walk(parseSync(file, code).program);\n return spans;\n}\n\n/**\n * Plans an extraction over the files in `paths` against the current catalog. With `types` (the\n * default), the project's TypeScript says which placeholders are numbers and dates.\n */\nexport async function planExtract(\n config: ResolvedConfig,\n paths: string[],\n options: { area?: string; types?: boolean } = {},\n): Promise<ExtractPlan> {\n if (options.area !== undefined && !KEY_PATTERN.test(`${options.area}.x`))\n throw new Error(`prosebook: \"${options.area}\" is not an area: lowercase words joined by -`);\n const known = new Map<string, string>();\n if (existsSync(config.catalog)) {\n try {\n for (const m of loadCatalog(config).messages) known.set(m.key, m.text);\n } catch (e) {\n if (!(e instanceof CatalogError)) throw e;\n throw new Error(`prosebook: fix the catalog before extracting into it:\\n${e.message}`, { cause: e });\n }\n }\n const entries: NewEntry[] = [];\n const oracle = options.types === false ? undefined : await typescriptOracle(config.root, paths);\n try {\n // One file at a time: each plan sees the entries the ones before it added.\n const files: FilePlan[] = [];\n for (const path of paths) {\n const kinds = new Map<string, ValueKind>();\n if (oracle) {\n const spans = jsxExpressions(path, readFileSync(path, 'utf8'));\n (await oracle.kinds(path, spans)).forEach((kind, i) => {\n if (kind !== undefined && kind !== 'unknown') kinds.set(`${spans[i]!.start}:${spans[i]!.end}`, kind);\n });\n }\n files.push(planFile(path, { config, area: options.area ?? areaOf(path), known, entries, kinds }));\n }\n return { files, entries, types: oracle?.source ?? 'syntax' };\n } finally {\n await oracle?.close();\n }\n}\n\n/** Applies a plan: rewrites the files and appends the new entries to their area's catalog file. */\nexport function applyExtract(config: ResolvedConfig, plan: ExtractPlan): string[] {\n const written: string[] = [];\n for (const file of plan.files) {\n if (file.edits.length === 0) continue;\n let code = file.code;\n for (const edit of [...file.edits].sort((a, b) => (a.start !== b.start ? b.start - a.start : b.end - a.end)))\n code = code.slice(0, edit.start) + edit.text + code.slice(edit.end);\n\n writeFileSync(file.path, code);\n written.push(file.path);\n }\n const byArea = new Map<string, NewEntry[]>();\n for (const entry of plan.entries) byArea.set(entry.area, [...(byArea.get(entry.area) ?? []), entry]);\n for (const [area, entries] of byArea) {\n const path = join(config.catalog, `${area}.yaml`);\n // Written as YAML 1.1, which quotes `n`, `yes` and `on`: they then read the same under 1.1 and 1.2,\n // as the catalog requires.\n const blocks = entries.map((e) => {\n const body: Record<string, unknown> = {};\n if (e.kind) body.kind = e.kind;\n if (e.surface) body.surface = e.surface;\n body.context = e.context;\n if (Object.keys(e.args).length > 0) body.args = e.args;\n body[config.source] = e.message;\n return `# TODO(prosebook extract): check the key, kind and context.\\n${stringify({ [e.key]: body }, { lineWidth: 0, version: '1.1' })}`;\n });\n mkdirSync(config.catalog, { recursive: true });\n const current = existsSync(path) ? readFileSync(path, 'utf8') : '# yaml-language-server: $schema=./catalog.schema.json\\n';\n writeFileSync(path, `${current.replace(/\\n*$/, '\\n')}\\n${blocks.join('\\n')}`);\n written.push(path);\n }\n return written;\n}\n","/**\n * `prosebook migrate`: a catalog and its translations rewritten from one syntax to the other. Each\n * message is written in the target syntax, read back, and rendered both ways over sample values, so\n * one that can't be written, or would come out different, is reported before anything changes.\n */\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport { isMap, parseDocument, Scalar } from 'yaml';\n\nimport { createHelpers, flatten } from '#src/runtime/helpers.ts';\nimport type { CompiledMessages } from '#src/runtime/types.ts';\n\nimport { loadCatalog } from './catalog.ts';\nimport { compileLocale, localeExpression } from './compile.ts';\nimport type { ResolvedConfig } from './config.ts';\nimport { argsOf, tagsOf, type MessageFormatElement } from './icu.ts';\nimport { readMessage, writeMessage, type MessageFormatVersion } from './syntax.ts';\n\ninterface Located {\n key: string;\n locale: string;\n /** The file, relative to the project root. */\n file: string;\n}\n\nexport interface MigratePlan {\n to: MessageFormatVersion;\n rewrites: (Located & { before: string; after: string })[];\n /** Messages the target syntax can't say, and why. Nothing is written while there are any. */\n blocked: (Located & { reason: string })[];\n /** Messages that would render differently, with the first values that show it. */\n changed: (Located & { values: string; before: string; after: string })[];\n}\n\nexport function planMigrate(config: ResolvedConfig, to: MessageFormatVersion): MigratePlan {\n // Both syntaxes read without isolation marks, which MF1 never has, so their renders compare.\n const catalog = loadCatalog({ ...config, isolate: false });\n const plan: MigratePlan = { to, rewrites: [], blocked: [], changed: [] };\n for (const m of catalog.messages) {\n const versions = [\n { locale: config.source, text: m.text, ast: m.ast, file: m.file },\n ...[...m.translations].map(([locale, t]) => ({ locale, text: t.text, ast: t.ast, file: t.file })),\n ];\n for (const { locale, text, ast, file } of versions) {\n const at = { key: m.key, locale, file };\n let after: string;\n let back: MessageFormatElement[];\n try {\n after = writeMessage(to, ast, locale);\n back = readMessage(to, after, locale, false);\n } catch (e) {\n plan.blocked.push({ ...at, reason: (e as Error).message });\n continue;\n }\n const difference = firstDifference(ast, back, locale);\n if (difference !== undefined) plan.changed.push({ ...at, ...difference });\n if (after !== text) plan.rewrites.push({ ...at, before: text, after });\n }\n }\n return plan;\n}\n\n/** Writes the plan's rewrites into the YAML files, keeping their comments and layout. Returns the files written. */\nexport function applyMigrate(config: ResolvedConfig, plan: MigratePlan): string[] {\n if (plan.blocked.length > 0) throw new Error('prosebook: some messages have no equivalent in the target syntax; nothing was written');\n const byFile = Map.groupBy(plan.rewrites, (r) => r.file);\n for (const [file, rewrites] of byFile) {\n const path = join(config.root, file);\n // As YAML 1.1, so a new value that 1.1 would read differently, like `n`, is quoted.\n const doc = parseDocument(readFileSync(path, 'utf8'), { version: '1.1' });\n for (const r of rewrites) {\n const value = doc.createNode(r.after);\n if (r.after.includes('\\n')) value.type = Scalar.BLOCK_LITERAL;\n const entry = doc.get(r.key, true);\n if (isMap(entry)) entry.set(config.source, value);\n else doc.set(r.key, value);\n }\n writeFileSync(path, doc.toString({ lineWidth: 0 }));\n }\n return [...byFile.keys()];\n}\n\nconst NUMBERS = [0, 1, 2, 3, 5, 11, 21, 101, 1.5, 1234.5];\nconst DATE = new Date(Date.UTC(2026, 0, 5, 14, 30, 15));\n\nfunction samplesOf(type: string): unknown[] {\n if (type === 'number') return NUMBERS;\n if (type === 'Date | number') return [DATE];\n const named = [...type.matchAll(/\"((?:[^\"\\\\]|\\\\.)*)\"/g)].map((m) => JSON.parse(`\"${m[1]}\"`) as string);\n return named.length > 0 ? [...named, 'zzz'] : ['Ada'];\n}\n\n/** Every combination of sample values, or each argument varied alone where there are too many. */\nfunction* samples(a: MessageFormatElement[], b: MessageFormatElement[]): Generator<Record<string, unknown>> {\n const types = new Map<string, Set<unknown>>();\n for (const [name, type] of [...argsOf(a), ...argsOf(b)]) {\n const set = types.get(name) ?? new Set();\n for (const value of samplesOf(type)) set.add(value);\n types.set(name, set);\n }\n const tags = Object.fromEntries(\n [...new Set([...tagsOf(a), ...tagsOf(b)])].map((t) => [t, (c: unknown[]) => `<${t}>${c.join('')}</${t}>`]),\n );\n const names = [...types.keys()];\n const lists = names.map((n) => [...types.get(n)!]);\n if (lists.reduce((n, l) => n * l.length, 1) <= 1000) {\n let combos: unknown[][] = [[]];\n for (const list of lists) combos = combos.flatMap((c) => list.map((v) => [...c, v]));\n for (const combo of combos) yield { ...tags, ...Object.fromEntries(names.map((n, i) => [n, combo[i]])) };\n return;\n }\n const base = Object.fromEntries(names.map((n, i) => [n, lists[i]![0]]));\n for (const [i, n] of names.entries()) for (const value of lists[i]!) yield { ...tags, ...base, [n]: value };\n}\n\nfunction renderer(ast: MessageFormatElement[], locale: string): (values: Record<string, unknown>) => string {\n // oxlint-disable-next-line no-new-func, typescript/no-implied-eval -- evaluating our own compiled message, as the bundle would\n const messages = new Function(`return ${localeExpression(compileLocale([['m', ast]]))};`)() as CompiledMessages;\n const message = messages.m!;\n const h = createHelpers(locale);\n return (values) => (typeof message === 'string' ? message : flatten(message(values, h)).join(''));\n}\n\nfunction firstDifference(a: MessageFormatElement[], b: MessageFormatElement[], locale: string) {\n const before = renderer(a, locale);\n const after = renderer(b, locale);\n for (const values of samples(a, b)) {\n const x = before(values);\n const y = after(values);\n if (x !== y) {\n const shown = Object.entries(values)\n .filter(([, v]) => typeof v !== 'function')\n .map(([k, v]) => `${k}: ${v instanceof Date ? v.toISOString() : JSON.stringify(v)}`);\n return { values: `{ ${shown.join(', ')} }`, before: x, after: y };\n }\n }\n return undefined;\n}\n","/**\n * `prosebook todo`: a locale's missing and stale entries, each with what a translator needs above it,\n * as the YAML to fill in. `prosebook import` reads it back filled.\n *\n * With `prompt`, it leads with what a model must be told to reply in that form. prosebook writes the\n * prompt and checks the reply; which model answers it, and how, is left to whoever runs it.\n */\nimport { stringify } from 'yaml';\n\nimport type { Catalog, Message } from './catalog.ts';\nimport type { ResolvedConfig } from './config.ts';\nimport { TYPE, walk } from './icu.ts';\nimport { changeOf, type StaleTranslation } from './lock.ts';\nimport { SYNTAX_NAME } from './syntax.ts';\n\nexport interface Todo {\n /** How many entries want a translation. */\n count: number;\n /** The entries as YAML, by area, with the prompt first when one was asked for. */\n text: string;\n}\n\nexport function todoOf(\n config: ResolvedConfig,\n catalog: Catalog,\n stale: ReadonlyMap<string, StaleTranslation>,\n locale: string,\n prompt = false,\n): Todo {\n const wanted = catalog.messages.filter((m) => !m.translations.has(locale) || stale.has(m.key));\n if (wanted.length === 0) return { count: 0, text: `# ${locale} is complete` };\n const byArea = new Map<string, string[]>();\n for (const m of wanted) {\n const lines = byArea.get(m.area) ?? [];\n lines.push('');\n if (m.context) lines.push(`# ${m.context}`);\n const what = [m.kind && `kind: ${m.kind}`, m.surface && `surface: ${m.surface}`].filter(Boolean).join(', ');\n if (what) lines.push(`# ${what}`);\n for (const [arg, said] of m.argDocs) lines.push(`# {${arg}}: ${said}`);\n lines.push(`# ${config.source}: ${m.text.replaceAll('\\n', ' ')}`);\n const change = stale.get(m.key);\n if (change !== undefined) lines.push(`# stale, the source changed: ${changeOf(change)}`);\n lines.push(stringify({ [m.key]: m.translations.get(locale)?.text ?? '' }, { lineWidth: 0 }).trimEnd());\n byArea.set(m.area, lines);\n }\n const entries = [...byArea].map(([area, lines]) => `\\n# ── ${area}.yaml ──\\n${lines.join('\\n')}`).join('\\n');\n const count = wanted.length;\n if (prompt) {\n const head = promptFor(\n config,\n wanted,\n locale,\n wanted.some((m) => stale.has(m.key)),\n );\n return { count, text: `${head}\\n${entries.trimStart()}\\n\\`\\`\\`` };\n }\n const head = `# prosebook todo: ${count} entr${count === 1 ? 'y' : 'ies'} for ${locale}. Fill them in, then \\`prosebook import ${locale} <this file>\\`.`;\n return { count, text: `${head}\\n${entries}` };\n}\n\nfunction promptFor(config: ResolvedConfig, wanted: Message[], locale: string, anyStale: boolean): string {\n const mf2 = config.messageFormat === 2;\n const [target, source] = [nameOf(locale), nameOf(config.source)];\n const plurals = { cardinal: false, ordinal: false };\n for (const m of wanted) {\n walk(m.ast, (el) => {\n if (el.type === TYPE.plural) plurals[el.pluralType === 'ordinal' ? 'ordinal' : 'cardinal'] = true;\n });\n }\n const categories = (type: Intl.PluralRuleType) => {\n const forms = new Intl.PluralRules(locale, { type }).resolvedOptions().pluralCategories;\n return forms.length === 1 ? `only the form ${forms[0]}` : `the forms ${new Intl.ListFormat('en').format(forms)}`;\n };\n const exact = mf2 ? '`0`' : '`=0`';\n\n const rules = [\n mf2\n ? `Each message is in MessageFormat 2. Keep every {$placeholder}, every markup tag ({#b}…{/b}) around the same words, and every .input, .local and .match line; translate the text, not the names.`\n : `Each message is in ICU MessageFormat. Keep every {placeholder}, and every <tag> around the same words; translate the text inside plural and select arms, not the arm or argument names.`,\n plurals.cardinal &&\n `A plural in ${target} takes ${categories('cardinal')}: give each its own ${mf2 ? 'variant' : 'arm'}, and keep exact ones such as ${exact} where the ${source} has them.`,\n plurals.ordinal && `An ordinal in ${target} takes ${categories('ordinal')}.`,\n 'The comments above an entry say where it appears, what kind of string it is, and what each placeholder holds. Hold each to its kind, as described below: a button stays as short as the source.',\n anyStale &&\n 'An entry marked stale has a translation made from an earlier source. The diff shows what changed in the source ({+added+}, [-removed-]): change the translation only as much as that needs, and give it back unchanged if it still holds.',\n 'Quote a value in single quotes when it starts with { or holds \": \", as YAML needs, and double any single quote inside it.',\n ].filter((r): r is string => typeof r === 'string');\n\n const kinds = new Set(wanted.flatMap((m) => (m.kind === undefined ? [] : [m.kind])));\n const surfaces = new Set(wanted.flatMap((m) => (m.surface === undefined ? [] : [m.surface])));\n const legend = [\n ...(kinds.size > 0 ? ['', 'Kinds of string:'] : []),\n ...[...kinds].map((k) => `- ${k}: ${config.kinds[k]?.doc ?? ''}`),\n ...(surfaces.size > 0 ? ['', 'Surfaces:'] : []),\n ...[...surfaces].map((s) => `- ${s}: ${config.surfaces[s] ?? ''}`),\n ];\n\n return [\n `Translate the entries below from ${source} (${config.source}) into ${target} (${locale}). They are the text of an app's interface.`,\n '',\n 'Reply with one YAML code block holding every key below, each with its translation as the value, and nothing else in the block.',\n '',\n ...rules.map((r) => `- ${r}`),\n ...legend,\n '',\n `The entries, in ${SYNTAX_NAME[config.messageFormat]}:`,\n '',\n '```yaml',\n ].join('\\n');\n}\n\nfunction nameOf(locale: string): string {\n try {\n return new Intl.DisplayNames(['en'], { type: 'language' }).of(locale) ?? locale;\n } catch {\n return locale;\n }\n}\n","/**\n * Findings as SARIF 2.1.0, the static-analysis format code scanning reads (GitHub's among them), so\n * `lint`, `scan`, `status` and `check` can annotate a pull request on the line the string is written.\n *\n * Paths are relative to the project root under `%SRCROOT%`, which the log maps to the root itself:\n * a project that isn't at the top of its repository still resolves to the right files.\n */\nimport { pathToFileURL } from 'node:url';\n\nexport interface SarifResult {\n /** A rule the report describes, or one of a lint plugin's. */\n rule: string;\n level: 'error' | 'warning';\n message: string;\n /** Relative to the project root, with forward slashes; none for a problem that isn't in a file. */\n file?: string;\n /** From 1; none for the file as a whole. */\n line?: number;\n column?: number;\n}\n\nexport interface SarifTool {\n name: string;\n version: string;\n informationUri: string;\n}\n\n/** Collects what a command found, then writes it as one SARIF run. */\nexport class SarifReport {\n readonly results: SarifResult[] = [];\n private readonly rules = new Map<string, string | undefined>();\n\n /** Describes a rule in one sentence; the first description given for an id stands. */\n rule(id: string, description?: string): void {\n if (this.rules.get(id) === undefined) this.rules.set(id, description);\n }\n\n add(result: SarifResult): void {\n if (!this.rules.has(result.rule)) this.rules.set(result.rule, undefined);\n this.results.push(result);\n }\n\n toJSON(root: string, tool: SarifTool): object {\n const ids = [...this.rules.keys()];\n return {\n $schema: 'https://json.schemastore.org/sarif-2.1.0.json',\n version: '2.1.0',\n runs: [\n {\n tool: {\n driver: {\n ...tool,\n rules: ids.map((id) => {\n const description = this.rules.get(id);\n return description === undefined ? { id } : { id, shortDescription: { text: description } };\n }),\n },\n },\n originalUriBaseIds: { '%SRCROOT%': { uri: pathToFileURL(root).href.replace(/\\/?$/, '/') } },\n results: this.results.map((r) => ({\n ruleId: r.rule,\n ruleIndex: ids.indexOf(r.rule),\n level: r.level,\n message: { text: r.message },\n locations: r.file === undefined ? [] : [location(r.file, r.line, r.column)],\n })),\n },\n ],\n };\n }\n}\n\nfunction location(file: string, line: number | undefined, column: number | undefined): object {\n return {\n physicalLocation: {\n artifactLocation: { uri: encodeURI(file), uriBaseId: '%SRCROOT%' },\n ...(line === undefined ? {} : { region: { startLine: line, startColumn: column ?? 1 } }),\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scan-Bx0_yDSi.js","names":["TYPE"],"sources":["../src/tools/compile.ts","../src/tools/scan.ts"],"sourcesContent":["/**\n * Compiles ICU ASTs to JavaScript.\n *\n * A message with no placeholders becomes its string. Any other becomes `(a, h) => …`, where `a` holds\n * the arguments and `h` the locale's helpers (see `runtime/helpers.ts`): a plural is a call picking an\n * arm, a number is a call to a cached `Intl.NumberFormat`. A placeholder without a value, or with one\n * `Intl` refuses, shows as `{name}` and is reported (`h.e`) rather than throwing, so every such\n * message uses `h`. Formatting options are resolved here and\n * hoisted to module constants, so a skeleton costs nothing at runtime and its formatter is built once.\n * Options an argument gives (MF2's `currency=$code`) follow them as an object built per call, and the\n * runtime keeps a formatter per value.\n */\nimport { isDateElement, isNumberElement, isTimeElement } from '@formatjs/icu-messageformat-parser';\n\nimport {\n dateOptions,\n numberOptions,\n optionArgsOf,\n placeholderOf,\n selectionOf,\n staticLiteral,\n TYPE,\n type MessageFormatElement,\n type OptionArgs,\n} from './icu.ts';\n\nexport type Entry = readonly [key: string, ast: MessageFormatElement[]];\n\n/** Module-level constants for formatting options, one per distinct object. */\nclass Hoisted {\n private readonly byJson = new Map<string, string>();\n\n /** `, oN` naming the hoisted options, or nothing when there are none. */\n arg(options: object | undefined): string {\n // `{}` (a bare `:number`) formats as no options do, so it needs no constant.\n if (options === undefined || Object.keys(options).length === 0) return '';\n const json = JSON.stringify(options);\n let name = this.byJson.get(json);\n if (name === undefined) this.byJson.set(json, (name = `o${this.byJson.size}`));\n return `, ${name}`;\n }\n\n declarations(): string[] {\n return [...this.byJson].map(([json, name]) => `const ${name} = ${json};`);\n }\n}\n\nfunction access(name: string): string {\n return /^[A-Za-z_$][\\w$]*$/.test(name) ? `a.${name}` : `a[${JSON.stringify(name)}]`;\n}\n\n/** The plural a `#` prints the value of. */\ntype Pound = { name: string; offset: number } | null;\n\nfunction nodes(elements: MessageFormatElement[], hoisted: Hoisted, pound: Pound): string {\n if (elements.length === 0) return '\"\"';\n const parts = elements.map((el) => node(el, hoisted, pound));\n return parts.length === 1 ? parts[0]! : `[${parts.join(', ')}]`;\n}\n\nfunction arms(options: Record<string, { value: MessageFormatElement[] }>, hoisted: Hoisted, pound: Pound): string {\n const body = Object.entries(options).map(([arm, option]) => `${JSON.stringify(arm)}: () => ${nodes(option.value, hoisted, pound)}`);\n return `{ ${body.join(', ')} }`;\n}\n\n/** The hoisted options, then the options arguments give as `{ currency: a.code }`, where there are any. */\nfunction formatting(options: object | undefined, args: OptionArgs | undefined, hoisted: Hoisted): string {\n const given = Object.entries(args ?? {});\n const fixed = hoisted.arg(options);\n if (given.length === 0) return fixed;\n return `${fixed || ', undefined'}, { ${given.map(([option, { arg }]) => `${option}: ${access(arg)}`).join(', ')} }`;\n}\n\n/** A string literal, its invisible direction marks escaped so the generated code shows them. */\nfunction text(value: string): string {\n return JSON.stringify(value).replace(/[\\u2066-\\u2069]/g, (c) => `\\\\u${c.charCodeAt(0).toString(16)}`);\n}\n\n/**\n * A placeholder's value, or its fallback (`{name}`, reported through `h.e`) where it has none or\n * `Intl` refuses it, between the marks isolating its direction where it has them.\n */\nfunction placed(el: MessageFormatElement, name: string, value: string): string {\n const { fallback, isolate } = placeholderOf(el, name);\n const shown = `${value} ?? h.e(${text(fallback)})`;\n return isolate === undefined ? shown : `[${text(isolate[0])}, ${shown}, ${text(isolate[1])}]`;\n}\n\nfunction node(el: MessageFormatElement, hoisted: Hoisted, pound: Pound): string {\n const formatted = (helper: string, name: string, options: object | undefined) =>\n placed(el, name, `h.${helper}(${access(name)}${formatting(options, optionArgsOf(el), hoisted)})`);\n if (isNumberElement(el)) return formatted('n', el.value, numberOptions(el));\n if (isDateElement(el) || isTimeElement(el)) return formatted('d', el.value, dateOptions(el));\n switch (el.type) {\n case TYPE.literal:\n return JSON.stringify(el.value);\n case TYPE.argument:\n return placed(el, el.value, access(el.value));\n case TYPE.pound:\n // `#` is its plural's own value less its offset, formatted as a number.\n if (pound === null) return '\"#\"';\n return placed(el, pound.name, `h.n(${access(pound.name)}${pound.offset !== 0 ? ` - ${pound.offset}` : ''})`);\n case TYPE.select:\n return `h.s(${access(el.value)}, ${arms(el.options, hoisted, pound)})`;\n case TYPE.plural: {\n // Read from MF2, a plural selects on the number as formatted, and on what `:integer` and `:percent` make of it.\n const selection = selectionOf(el);\n const value = access(el.value);\n const on = selection?.value === 'round' ? `Math.round(${value})` : selection?.value === 'percent' ? `${value} * 100` : value;\n const rules = selection === undefined ? '' : formatting(selection.options, selection.args, hoisted);\n const own = { name: el.value, offset: el.offset };\n return `h.p(${on}, ${el.offset}, ${el.pluralType === 'ordinal'}, ${arms(el.options, hoisted, own)}${rules})`;\n }\n case TYPE.tag:\n return `h.t(a, ${JSON.stringify(el.value)}, ${nodes(el.children, hoisted, pound)})`;\n default:\n throw new Error(`prosebook: no compiler for ICU element type ${(el as MessageFormatElement).type}`);\n }\n}\n\nfunction message(ast: MessageFormatElement[], hoisted: Hoisted): string {\n const literal = staticLiteral(ast);\n if (literal !== undefined) return JSON.stringify(literal);\n return `(a, h) => ${nodes(ast, hoisted, null)}`;\n}\n\nexport interface CompiledLocale {\n /** `const oN = {…};` lines the messages refer to. */\n declarations: string[];\n /** `\"key\": message,` lines. */\n rows: string[];\n}\n\n/** One locale's messages as code, keeping only `keep` when given. */\nexport function compileLocale(entries: Iterable<Entry>, keep?: (key: string) => boolean): CompiledLocale {\n const hoisted = new Hoisted();\n const rows: string[] = [];\n for (const [key, ast] of entries) {\n if (keep && !keep(key)) continue;\n rows.push(` ${JSON.stringify(key)}: ${message(ast, hoisted)},`);\n }\n return { declarations: hoisted.declarations(), rows };\n}\n\n/** The locale as an ES module whose default export is its messages. */\nexport function localeModule(compiled: CompiledLocale, banner: string, ts: boolean): string {\n const head = ts ? `${banner}\\nimport type { CompiledMessages } from 'prosebook';\\n` : `${banner}\\n`;\n // `as const` keeps `style: \"currency\"` a literal, which is what `Intl`'s option types ask for.\n const declarations = ts ? compiled.declarations.map((d) => d.replace(/;$/, ' as const;')) : compiled.declarations;\n const consts = declarations.length > 0 ? `\\n${declarations.join('\\n')}\\n` : '';\n const close = ts ? '} satisfies CompiledMessages;' : '};';\n return `${head}${consts}\\nexport default {\\n${compiled.rows.join('\\n')}\\n${close}\\n`;\n}\n\n/** The locale as one expression, for a bundler to inline in place of the module. */\nexport function localeExpression(compiled: CompiledLocale): string {\n return `(() => {\\n${compiled.declarations.join('\\n')}\\nreturn {\\n${compiled.rows.join('\\n')}\\n};\\n})()`;\n}\n","/**\n * What the code says: text a person reads that is still written in a component, and which catalog\n * keys the code names.\n *\n * Key references are found by reading string literals, not by tracing calls, so a key kept in an\n * array or a map still counts, and `nav.${id}` or `'nav.' + id` keeps every key under `nav.`. That\n * errs towards keeping a key, which is the safe direction both for `unused` and for pruning a bundle.\n */\nimport { readdirSync, readFileSync, statSync } from 'node:fs';\nimport { extname, join, relative } from 'node:path';\n\nimport { parseSync } from 'oxc-parser';\n\nconst SKIP_DIRS = new Set(['node_modules', 'dist', 'build', 'out', 'coverage', '.git']);\n\nexport function sourceFiles(dirs: string[], extensions: string[], skip: string[] = []): string[] {\n const files: string[] = [];\n const visit = (dir: string) => {\n let names: string[];\n try {\n names = readdirSync(dir);\n } catch {\n return;\n }\n for (const name of names) {\n const path = join(dir, name);\n if (skip.some((s) => path === s || path.startsWith(`${s}/`) || path.startsWith(`${s}\\\\`))) continue;\n if (statSync(path).isDirectory()) {\n if (!SKIP_DIRS.has(name) && !name.startsWith('.')) visit(path);\n } else if (extensions.includes(extname(name)) && !name.endsWith('.d.ts')) {\n files.push(path);\n }\n }\n };\n for (const dir of dirs) visit(dir);\n return files.sort();\n}\n\nexport interface KeyRefs {\n exact: Set<string>;\n /** `nav.` from `nav.${id}` or `'nav.' + id`: every key under it may be read. */\n prefixes: Set<string>;\n}\n\nconst LITERAL_KEY = /(['\"`])([a-z0-9][\\w-]*(?:\\.[\\w-]+)+)\\1/g;\nconst KEY_PREFIX = /(['\"`])([a-z0-9][\\w-]*(?:\\.[\\w-]+)*\\.)(?:\\1|\\$\\{)/g;\n\nexport function keyRefs(code: string, into: KeyRefs = { exact: new Set(), prefixes: new Set() }): KeyRefs {\n for (const m of code.matchAll(LITERAL_KEY)) into.exact.add(m[2]!);\n for (const m of code.matchAll(KEY_PREFIX)) into.prefixes.add(m[2]!);\n return into;\n}\n\nexport function isReferenced(key: string, refs: KeyRefs): boolean {\n if (refs.exact.has(key)) return true;\n for (const prefix of refs.prefixes) if (key.startsWith(prefix)) return true;\n return false;\n}\n\nexport interface Hardcoded {\n file: string;\n line: number;\n column: number;\n text: string;\n /** Where it sits: `text`, or the attribute it is the value of. */\n where: string;\n}\n\ntype Node = { type: string; start: number; end: number; [field: string]: unknown };\n\n/**\n * Text that reads as code rather than prose: one token holding a path, a call, an identifier with an\n * underscore or a dotted name, as in `form.json()` or `src/index.ts`. Trailing punctuation doesn't\n * count, so `Done.` is still prose.\n */\nexport function looksLikeCode(text: string): boolean {\n const token = text.trim().replace(/[.!?:,…]+$/, '');\n return token !== '' && !/\\s/.test(token) && /[/()_=<>{}[\\].]|::/.test(token);\n}\n\nconst NON_PROSE_ELEMENTS = new Set(['code', 'pre', 'kbd', 'samp', 'script', 'style', 'svg', 'path']);\nconst LETTER = /\\p{L}/u;\n\n/** Offsets in `code` as lines and columns, and whether a line is marked `prosebook-ignore`, on it or the line above. */\nfunction lineIndex(code: string) {\n const lines = code.split('\\n');\n const lineStarts: number[] = [];\n let offset = 0;\n for (const line of lines) {\n lineStarts.push(offset);\n offset += line.length + 1;\n }\n const position = (at: number) => {\n let lo = 0;\n let hi = lineStarts.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (lineStarts[mid]! <= at) lo = mid;\n else hi = mid - 1;\n }\n return { line: lo + 1, column: at - lineStarts[lo]! + 1 };\n };\n const ignored = (line: number) =>\n (lines[line - 1] ?? '').includes('prosebook-ignore') || (lines[line - 2] ?? '').includes('prosebook-ignore');\n return { position, ignored };\n}\n\n/** Literal text in JSX that a person reads, where it should be a catalog entry. */\nexport function hardcodedText(file: string, code: string, attributes: string[]): Hardcoded[] {\n const { program } = parseSync(file, code);\n const found: Hardcoded[] = [];\n const { position, ignored } = lineIndex(code);\n const report = (node: Node, text: string, where: string) => {\n const trimmed = text.replace(/\\s+/g, ' ').trim();\n if (!LETTER.test(trimmed) || looksLikeCode(trimmed)) return;\n const at = position(node.start + Math.max(0, code.slice(node.start, node.end).search(/\\S/)));\n if (ignored(at.line)) return;\n found.push({ file, ...at, text: trimmed, where });\n };\n\n const visit = (node: Node, inProse: boolean) => {\n let prose = inProse;\n if (node.type === 'JSXElement') {\n const opening = node.openingElement as Node & { name: Node & { name?: string } };\n if (opening.name.type === 'JSXIdentifier' && NON_PROSE_ELEMENTS.has(opening.name.name ?? '')) prose = false;\n }\n if (node.type === 'JSXText' && prose) report(node, node.value as string, 'text');\n if (node.type === 'JSXExpressionContainer' && prose) {\n const expr = node.expression as Node;\n if (expr.type === 'Literal' && typeof expr.value === 'string') report(expr, expr.value, 'text');\n if (expr.type === 'TemplateLiteral' && (expr.expressions as Node[]).length === 0)\n report(expr, String((expr.quasis as { value: { cooked: string } }[])[0]?.value.cooked), 'text');\n }\n if (node.type === 'JSXAttribute') {\n const name = node.name as Node & { name?: string };\n const value = node.value as Node | null;\n const attr = name.type === 'JSXIdentifier' ? (name.name ?? '') : '';\n if (attributes.includes(attr) && value !== null) {\n if (value.type === 'Literal' && typeof value.value === 'string') report(value, value.value, attr);\n if (value.type === 'JSXExpressionContainer') {\n const expr = value.expression as Node;\n if (expr.type === 'Literal' && typeof expr.value === 'string') report(expr, expr.value, attr);\n }\n }\n return;\n }\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) {\n for (const child of value) if (isNode(child)) visit(child, prose);\n } else if (isNode(value)) {\n visit(value, prose);\n }\n }\n };\n visit(program as unknown as Node, true);\n return found;\n}\n\nfunction isNode(value: unknown): value is Node {\n return typeof value === 'object' && value !== null && typeof (value as Node).type === 'string';\n}\n\nexport interface ScanResult {\n hardcoded: Hardcoded[];\n refs: KeyRefs;\n files: number;\n}\n\nexport function scan(dirs: string[], extensions: string[], attributes: string[], root: string, skip: string[] = []): ScanResult {\n const refs: KeyRefs = { exact: new Set(), prefixes: new Set() };\n const hardcoded: Hardcoded[] = [];\n const files = sourceFiles(dirs, extensions, skip);\n for (const path of files) {\n const code = readFileSync(path, 'utf8');\n keyRefs(code, refs);\n if (/\\.[jt]sx$/.test(path)) hardcoded.push(...hardcodedText(relative(root, path).replaceAll('\\\\', '/'), code, attributes));\n }\n return { hardcoded, refs, files: files.length };\n}\n\n/** A copy's methods that take a key first. */\nexport const READERS = new Set(['t', 'rich']);\n\nexport interface UnseenRead {\n file: string;\n line: number;\n column: number;\n /** The read as written, on one line. */\n code: string;\n /** What it calls: a reader, the name it was imported by, or `Text`. */\n name: string;\n}\n\nexport interface Reads {\n /** Reads whose key a build can't see, in calls that may be to a copy's `t` or `rich`. */\n unseen: UnseenRead[];\n /** Names a copy's readers are bound to here, as in `const { rich: tRich } = copy`. */\n aliases: Set<string>;\n}\n\nconst PREFIX = /^[a-z0-9][\\w-]*(?:\\.[\\w-]+)*\\.$/;\nconst WRAPPERS = new Set(['ParenthesizedExpression', 'TSAsExpression', 'TSSatisfiesExpression', 'TSNonNullExpression', 'TSTypeAssertion']);\n\n/** Whether `keyRefs` finds every key an expression can be: a literal, or a template or sum after a key prefix. */\nfunction keySeen(node: Node | undefined): boolean {\n if (node === undefined) return false;\n if (WRAPPERS.has(node.type)) return keySeen(node.expression as Node);\n switch (node.type) {\n case 'Literal':\n return typeof node.value === 'string';\n case 'TemplateLiteral': {\n const [head] = node.quasis as { value: { cooked: string | null } }[];\n return (node.expressions as Node[]).length === 0 || PREFIX.test(head?.value.cooked ?? '');\n }\n case 'BinaryExpression': {\n const left = node.left as Node;\n return node.operator === '+' && left.type === 'Literal' && typeof left.value === 'string' && PREFIX.test(left.value);\n }\n case 'ConditionalExpression':\n return keySeen(node.consequent as Node) && keySeen(node.alternate as Node);\n case 'LogicalExpression':\n return keySeen(node.left as Node) && keySeen(node.right as Node);\n default:\n return false;\n }\n}\n\nconst nameOf = (node: Node | undefined): string | undefined =>\n node?.type === 'Identifier' || node?.type === 'JSXIdentifier'\n ? (node.name as string)\n : node?.type === 'Literal'\n ? String(node.value)\n : undefined;\n\n/**\n * The reads in a module whose key a pruned build can't see, as in `t(item.key)` or `<Text id={id} />`:\n * the build would leave the message out, and the key would show in its place. A build has no types,\n * so readers are known by name: `t` and `rich` called alone or as methods, and any name imported here,\n * which may be bound to one elsewhere (`aliases`); the caller keeps those whose name turns out to be a\n * reader. `<Text>` counts where it is imported from `prosebook/react`. Lines marked `prosebook-ignore`\n * are skipped.\n */\nexport function unseenReads(file: string, code: string): Reads {\n const { program } = parseSync(file, code);\n const { position, ignored } = lineIndex(code);\n const unseen: UnseenRead[] = [];\n const aliases = new Set<string>();\n /** Local name to the name it was imported by. */\n const imported = new Map<string, string>();\n const texts = new Set<string>();\n for (const statement of (program as unknown as Node).body as Node[]) {\n if (statement.type !== 'ImportDeclaration') continue;\n for (const s of statement.specifiers as Node[]) {\n const name = s.type === 'ImportSpecifier' ? nameOf(s.imported as Node) : undefined;\n const local = nameOf(s.local as Node);\n if (name === undefined || local === undefined) continue;\n if (name === 'Text' && (statement.source as Node).value === 'prosebook/react') texts.add(local);\n else imported.set(local, name);\n }\n }\n const report = (node: Node, name: string) => {\n const at = position(node.start);\n if (ignored(at.line)) return;\n const text = code.slice(node.start, node.end).replace(/\\s+/g, ' ');\n unseen.push({ file, ...at, name, code: text.length > 80 ? `${text.slice(0, 77)}...` : text });\n };\n // Calls by a plain name, kept until every alias in the module is known.\n const calls: [Node, string][] = [];\n const visit = (node: Node) => {\n if (node.type === 'ObjectPattern') {\n for (const p of node.properties as Node[]) {\n if (p.type === 'Property' && READERS.has(nameOf(p.key as Node) ?? '') && (p.value as Node).type === 'Identifier')\n aliases.add(nameOf(p.value as Node)!);\n }\n }\n if (node.type === 'CallExpression' && !keySeen((node.arguments as Node[])[0])) {\n const callee = node.callee as Node;\n if (callee.type === 'Identifier') calls.push([node, callee.name as string]);\n else if (callee.type === 'MemberExpression' && !callee.computed && READERS.has(nameOf(callee.property as Node) ?? ''))\n report(node, nameOf(callee.property as Node)!);\n }\n if (node.type === 'JSXOpeningElement' && texts.has(nameOf(node.name as Node) ?? '')) {\n const id = (node.attributes as Node[]).find((a) => a.type === 'JSXAttribute' && nameOf(a.name as Node) === 'id');\n const value = id?.value as Node | null | undefined;\n if (value !== null && value !== undefined && !keySeen(value.type === 'JSXExpressionContainer' ? (value.expression as Node) : value))\n report(node, 'Text');\n }\n for (const value of Object.values(node)) {\n if (Array.isArray(value)) {\n for (const child of value) if (isNode(child)) visit(child);\n } else if (isNode(value)) {\n visit(value);\n }\n }\n };\n visit(program as unknown as Node);\n for (const [node, local] of calls) {\n if (READERS.has(local) || aliases.has(local)) report(node, local);\n else if (imported.has(local)) report(node, imported.get(local)!);\n }\n unseen.sort((a, b) => (a.line === b.line ? a.column - b.column : a.line - b.line));\n return { unseen, aliases };\n}\n"],"mappings":"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"}
|