@verbaly/compiler 0.13.1 → 0.14.5

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/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":["parse","parseArgs"],"sources":["../src/catalog.ts","../src/check.ts","../src/params.ts","../src/codegen.ts","../src/config.ts","../src/key.ts","../src/analyze.ts","../src/registry.ts","../src/extract.ts","../src/init.ts","../src/doctor.ts","../src/pseudo.ts","../src/render.ts","../src/translate.ts","../src/cli.ts"],"sourcesContent":["import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ResolvedConfig } from './config';\n\nexport type Catalog = Record<string, string>;\nexport type Catalogs = Record<string, Catalog>;\n\nexport function catalogPath(cfg: ResolvedConfig, locale: string): string {\n return join(cfg.dir, `${locale}.json`);\n}\n\nexport function readCatalog(cfg: ResolvedConfig, locale: string): Catalog {\n try {\n return JSON.parse(readFileSync(catalogPath(cfg, locale), 'utf8')) as Catalog;\n } catch {\n return {};\n }\n}\n\nexport function loadCatalogs(cfg: ResolvedConfig): Catalogs {\n const catalogs: Catalogs = {};\n for (const locale of cfg.locales) catalogs[locale] = readCatalog(cfg, locale);\n return catalogs;\n}\n\nexport function serializeCatalog(catalog: Catalog): string {\n const sorted: Catalog = {};\n for (const key of Object.keys(catalog).sort()) {\n const value = catalog[key];\n if (value !== undefined) sorted[key] = value;\n }\n return JSON.stringify(sorted, null, 2) + '\\n';\n}\n\nexport function writeCatalog(cfg: ResolvedConfig, locale: string, catalog: Catalog): string {\n const serialized = serializeCatalog(catalog);\n mkdirSync(cfg.dir, { recursive: true });\n writeFileSync(catalogPath(cfg, locale), serialized);\n return serialized;\n}\n","import type { Catalogs } from './catalog';\nimport type { ResolvedConfig } from './config';\nimport type { MessageRegistry } from './registry';\n\nexport interface MissingEntry {\n locale: string;\n key: string;\n source?: string;\n}\n\nexport interface UnknownEntry {\n key: string;\n files: string[];\n}\n\nexport interface CheckResult {\n ok: boolean;\n missing: MissingEntry[];\n unknown: UnknownEntry[];\n}\n\nexport function check(\n cfg: ResolvedConfig,\n catalogs: Catalogs,\n registry: MessageRegistry,\n): CheckResult {\n const source = catalogs[cfg.sourceLocale] ?? {};\n const extracted = registry.messages();\n\n const unknown: UnknownEntry[] = [];\n for (const [key, files] of registry.usedKeys()) {\n const known =\n extracted.has(key) || cfg.locales.some((locale) => catalogs[locale]?.[key] !== undefined);\n if (!known) unknown.push({ key, files });\n }\n\n const needed = new Set<string>([...extracted.keys(), ...Object.keys(source)]);\n\n const missing: MissingEntry[] = [];\n for (const key of extracted.keys()) {\n if (!source[key]) {\n missing.push({ locale: cfg.sourceLocale, key, source: extracted.get(key)?.message });\n }\n }\n for (const locale of cfg.locales) {\n if (locale === cfg.sourceLocale) continue;\n for (const key of needed) {\n if (!catalogs[locale]?.[key]) {\n missing.push({ locale, key, source: source[key] ?? extracted.get(key)?.message });\n }\n }\n }\n\n return { ok: missing.length === 0 && unknown.length === 0, missing, unknown };\n}\n\nexport function formatCheckResult(result: CheckResult): string {\n const lines: string[] = [];\n if (result.missing.length > 0) {\n lines.push('missing translations:');\n for (const entry of result.missing) {\n const hint = entry.source ? ` — \"${truncate(entry.source, 40)}\"` : '';\n lines.push(` [${entry.locale}] ${entry.key}${hint}`);\n }\n }\n if (result.unknown.length > 0) {\n lines.push('unknown keys (not in any catalog):');\n for (const entry of result.unknown) {\n lines.push(` ${entry.key} — used in ${entry.files.join(', ')}`);\n }\n }\n return lines.join('\\n');\n}\n\nfunction truncate(text: string, max: number): string {\n return text.length > max ? text.slice(0, max - 1) + '…' : text;\n}\n","import { parse, type MessageNode } from 'verbaly';\n\nexport type ParamType = 'number' | 'string' | 'date' | 'unknown';\n\nconst PLURAL_KEYS = new Set(['zero', 'one', 'two', 'few', 'many']);\nconst NUMBER_FORMATS = new Set(['number', 'integer', 'percent', 'currency']);\nconst DATE_FORMATS = new Set(['date', 'time']);\n\nexport function collectParams(message: string): Map<string, Set<ParamType>> {\n const out = new Map<string, Set<ParamType>>();\n visit(parse(message), out);\n return out;\n}\n\nfunction visit(nodes: MessageNode[], out: Map<string, Set<ParamType>>): void {\n for (const node of nodes) {\n if (node.kind !== 'param') continue;\n const types = out.get(node.name) ?? new Set<ParamType>();\n out.set(node.name, types);\n\n if (node.variants) {\n for (const [key, body] of node.variants) {\n if (PLURAL_KEYS.has(key) || /^=\\d+$/.test(key)) types.add('number');\n else if (key !== 'other') types.add('string');\n visit(body, out);\n }\n if (types.size === 0) types.add('string');\n } else if (node.format && NUMBER_FORMATS.has(node.format)) {\n types.add('number');\n } else if (node.format && DATE_FORMATS.has(node.format)) {\n types.add('date');\n } else {\n types.add('unknown');\n }\n }\n}\n\nexport function renderParamType(types: Set<ParamType>): string {\n if (types.has('unknown') || types.size === 0) return 'unknown';\n const parts: string[] = [];\n if (types.has('number')) parts.push('number');\n if (types.has('string')) parts.push('string');\n if (types.has('date')) parts.push('Date | number | string');\n return parts.join(' | ');\n}\n","import { writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { Catalog } from './catalog';\nimport type { ResolvedConfig } from './config';\nimport { collectParams, renderParamType } from './params';\n\nexport const VIRTUAL_ID = 'virtual:verbaly';\n\nexport function generateRuntimeModule(cfg: ResolvedConfig): string {\n const others = cfg.locales.filter((locale) => locale !== cfg.sourceLocale);\n const src = JSON.stringify(cfg.sourceLocale);\n const loaders = others\n .map(\n (locale) => ` ${JSON.stringify(locale)}: () => import('${VIRTUAL_ID}/locale/${locale}'),`,\n )\n .join('\\n');\n\n return `import { createVerbaly } from 'verbaly';\nimport source from '${VIRTUAL_ID}/locale/${cfg.sourceLocale}';\n\nconst v = createVerbaly({\n locale: ${src},\n fallback: ${src},\n messages: { [${src}]: source },\n loaders: {\n${loaders}\n },\n});\n\nexport const verbaly = v;\nexport const t = v.t;\n\nexport function getLocale() {\n return v.locale;\n}\n\nexport function subscribe(listener) {\n return v.subscribe(listener);\n}\n\nexport async function setLocale(locale) {\n await v.loadLocale(locale);\n v.setLocale(locale);\n}\n`;\n}\n\nexport function generateLocaleModule(catalog: Catalog): string {\n return `export default ${JSON.stringify(catalog)};\\n`;\n}\n\nexport function generateDts(entries: Map<string, string>): string {\n const lines: string[] = [];\n for (const [key, message] of [...entries.entries()].sort(([a], [b]) => a.localeCompare(b))) {\n const params = collectParams(message);\n if (params.size === 0) {\n lines.push(` ${JSON.stringify(key)}: never;`);\n } else {\n const fields = [...params.entries()]\n .map(([name, types]) => `${JSON.stringify(name)}: ${renderParamType(types)}`)\n .join('; ');\n lines.push(` ${JSON.stringify(key)}: { ${fields} };`);\n }\n }\n\n return `// generated by verbaly — do not edit\ndeclare module 'virtual:verbaly' {\n export interface VerbalyMessages {\n${lines.join('\\n')}\n }\n export type VerbalyKey = keyof VerbalyMessages & string;\n\n export const verbaly: import('verbaly').Verbaly<VerbalyKey>;\n\n export function t<K extends VerbalyKey>(\n key: K,\n ...args: [VerbalyMessages[K]] extends [never] ? [] : [VerbalyMessages[K]]\n ): string;\n export function t(strings: TemplateStringsArray, ...values: unknown[]): string;\n export namespace t {\n export function id(\n key: string,\n ): (strings: TemplateStringsArray, ...values: unknown[]) => string;\n }\n\n export function setLocale(locale: string): Promise<void>;\n export function getLocale(): string;\n export function subscribe(listener: () => void): () => void;\n}\n\ndeclare module 'virtual:verbaly/locale/*' {\n const messages: Record<string, string>;\n export default messages;\n}\n`;\n}\n\nexport function writeDts(cfg: ResolvedConfig, entries: Map<string, string>): void {\n writeFileSync(join(cfg.root, 'verbaly.d.ts'), generateDts(entries));\n}\n","import { existsSync, readFileSync, readdirSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { RichLink } from 'verbaly';\nimport type { TranslateProvider } from './translate';\n\nexport interface TranslateConfig {\n provider?: 'claude' | TranslateProvider;\n model?: string;\n batchSize?: number;\n}\n\nexport interface RenderConfig {\n links?: Record<string, RichLink>;\n}\n\nexport interface VerbalyConfig {\n root?: string;\n dir?: string;\n sourceLocale?: string;\n locales?: string[];\n include?: string[];\n exclude?: string[];\n translate?: TranslateConfig;\n render?: RenderConfig;\n}\n\nexport interface ResolvedConfig {\n root: string;\n dir: string;\n sourceLocale: string;\n locales: string[];\n include: string[];\n exclude: string[];\n translate: TranslateConfig;\n render: RenderConfig;\n}\n\nexport function resolveConfig(config: VerbalyConfig = {}): ResolvedConfig {\n const root = resolve(config.root ?? process.cwd());\n const dir = resolve(root, config.dir ?? 'locales');\n const sourceLocale = config.sourceLocale ?? 'en';\n\n const locales = new Set<string>([sourceLocale, ...(config.locales ?? [])]);\n if (existsSync(dir)) {\n for (const file of readdirSync(dir)) {\n if (file.endsWith('.json')) locales.add(file.slice(0, -5));\n }\n }\n\n return {\n root,\n dir,\n sourceLocale,\n locales: [...locales],\n include: config.include ?? ['src/**/*.{js,jsx,ts,tsx,mjs,mts}'],\n exclude: config.exclude ?? ['**/node_modules/**', '**/dist/**'],\n translate: config.translate ?? {},\n render: config.render ?? {},\n };\n}\n\nconst CONFIG_FILES = [\n 'verbaly.config.js',\n 'verbaly.config.mjs',\n 'verbaly.config.ts',\n 'verbaly.config.mts',\n 'verbaly.config.json',\n];\n\nexport function findConfigFile(root: string): string | undefined {\n return CONFIG_FILES.find((name) => existsSync(join(root, name)));\n}\n\nexport async function loadConfigFile(root: string): Promise<VerbalyConfig> {\n for (const name of ['verbaly.config.js', 'verbaly.config.mjs']) {\n const path = join(root, name);\n if (existsSync(path)) {\n const mod = (await import(pathToFileURL(path).href)) as { default?: VerbalyConfig };\n return mod.default ?? {};\n }\n }\n for (const name of ['verbaly.config.ts', 'verbaly.config.mts']) {\n const path = join(root, name);\n if (existsSync(path)) return loadTsConfig(path);\n }\n const jsonPath = join(root, 'verbaly.config.json');\n if (existsSync(jsonPath)) {\n return JSON.parse(readFileSync(jsonPath, 'utf8')) as VerbalyConfig;\n }\n return {};\n}\n\nasync function loadTsConfig(path: string): Promise<VerbalyConfig> {\n try {\n const { bundleRequire } = await import('bundle-require');\n const { mod } = await bundleRequire<{ default?: VerbalyConfig }>({ filepath: path });\n return mod.default ?? {};\n } catch (error) {\n if (isModuleNotFound(error, 'esbuild')) {\n throw new Error(`[verbaly] ${path} needs esbuild — install it: pnpm add -D esbuild`, {\n cause: error,\n });\n }\n throw error;\n }\n}\n\nfunction isModuleNotFound(error: unknown, name: string): boolean {\n return (\n error instanceof Error &&\n (error as { code?: string }).code === 'ERR_MODULE_NOT_FOUND' &&\n error.message.includes(name)\n );\n}\n\n// file config + inline overrides\nexport async function loadConfig(\n root: string,\n overrides: VerbalyConfig = {},\n): Promise<ResolvedConfig> {\n const fileConfig = await loadConfigFile(root);\n return resolveConfig({ ...fileConfig, ...definedOnly(overrides), root });\n}\n\nfunction definedOnly(config: VerbalyConfig): VerbalyConfig {\n return Object.fromEntries(\n Object.entries(config).filter(([, value]) => value !== undefined),\n ) as VerbalyConfig;\n}\n","import { createHash } from 'node:crypto';\n\nexport function stableKey(message: string): string {\n return createHash('sha256').update(message).digest('base64url').slice(0, 8);\n}\n","import { parse } from '@babel/parser';\nimport { stableKey } from './key';\n\nexport interface TaggedParam {\n name: string;\n start: number;\n end: number;\n}\n\nexport interface TransComponent {\n name: string;\n source: string;\n}\n\nexport interface TaggedMessage {\n key: string;\n message: string;\n params: TaggedParam[];\n start: number;\n end: number;\n tagStart: number;\n tagEnd: number;\n file: string;\n jsx?: { name: string; components: TransComponent[] };\n}\n\nexport interface UsedKey {\n key: string;\n file: string;\n}\n\nexport interface Analysis {\n tagged: TaggedMessage[];\n usedKeys: UsedKey[];\n}\n\ninterface AstNode {\n type: string;\n start: number;\n end: number;\n [key: string]: unknown;\n}\n\nconst SKIP_KEYS = new Set(['loc', 'leadingComments', 'trailingComments', 'innerComments', 'extra']);\n\nexport function analyze(code: string, file: string): Analysis {\n const jsx = /\\.[jt]sx$/.test(file);\n const ast = parse(code, {\n sourceType: 'module',\n errorRecovery: true,\n plugins: jsx ? ['typescript', 'jsx'] : ['typescript'],\n });\n\n const tagged: TaggedMessage[] = [];\n const usedKeys: UsedKey[] = [];\n\n walk(ast.program as unknown as AstNode, (node) => {\n if (node.type === 'TaggedTemplateExpression') {\n const tag = node.tag as AstNode;\n const explicit = explicitId(tag);\n if (!explicit && !isTReference(tag)) return;\n const quasi = node.quasi as AstNode;\n const message = buildMessage(code, quasi);\n if (!message) return;\n tagged.push({\n key: explicit ? explicit.key : stableKey(message.text),\n message: message.text,\n params: message.params,\n start: node.start,\n end: node.end,\n tagStart: explicit ? explicit.refStart : tag.start,\n tagEnd: explicit ? explicit.refEnd : tag.end,\n file,\n });\n } else if (node.type === 'CallExpression') {\n const callee = node.callee as AstNode;\n if (!isTReference(callee)) return;\n const args = node.arguments as AstNode[];\n const first = args[0];\n if (first?.type === 'StringLiteral') {\n usedKeys.push({ key: first.value as string, file });\n }\n } else if (node.type === 'JSXElement') {\n handleTrans(code, node, file, tagged, usedKeys);\n }\n });\n\n return { tagged, usedKeys };\n}\n\nfunction handleTrans(\n code: string,\n node: AstNode,\n file: string,\n tagged: TaggedMessage[],\n usedKeys: UsedKey[],\n): void {\n const opening = node.openingElement as AstNode;\n const nameNode = opening.name as AstNode;\n if (nameNode.type !== 'JSXIdentifier' || nameNode.name !== 'Trans') return;\n\n const attrs = opening.attributes as AstNode[];\n const idAttr = attrs.find((a) => a.type === 'JSXAttribute' && (a.name as AstNode).name === 'id');\n const children = node.children as AstNode[] | undefined;\n\n if (idAttr) {\n const value = idAttr.value as AstNode | null;\n if (value?.type !== 'StringLiteral') return;\n const id = value.value as string;\n // id + children → extract under the explicit key\n if (attrs.length === 1 && children?.length) {\n const built = buildTransMessage(code, children);\n if (built?.text.trim()) {\n tagged.push({\n key: id,\n message: built.text,\n params: built.params,\n start: node.start,\n end: node.end,\n tagStart: nameNode.start,\n tagEnd: nameNode.end,\n file,\n jsx: { name: nameNode.name as string, components: built.components },\n });\n return;\n }\n }\n usedKeys.push({ key: id, file });\n return; // runtime-first, untouched\n }\n if (attrs.length > 0) return; // hand-written props → don't guess\n\n if (!children?.length) return;\n\n const built = buildTransMessage(code, children);\n if (!built || !built.text.trim()) return;\n\n tagged.push({\n key: stableKey(built.text),\n message: built.text,\n params: built.params,\n start: node.start,\n end: node.end,\n tagStart: nameNode.start,\n tagEnd: nameNode.end,\n file,\n jsx: { name: nameNode.name as string, components: built.components },\n });\n}\n\n// t.id('key')`…` → explicit readable key\nfunction explicitId(tag: AstNode): { key: string; refStart: number; refEnd: number } | undefined {\n if (tag.type !== 'CallExpression') return undefined;\n const callee = tag.callee as AstNode;\n if (callee.type !== 'MemberExpression' || callee.computed) return undefined;\n const prop = callee.property as AstNode;\n if (prop.type !== 'Identifier' || prop.name !== 'id') return undefined;\n const obj = callee.object as AstNode;\n if (!isTReference(obj)) return undefined;\n const args = tag.arguments as AstNode[];\n const first = args[0];\n if (args.length !== 1 || first?.type !== 'StringLiteral') return undefined;\n return { key: first.value as string, refStart: obj.start, refEnd: obj.end };\n}\n\ninterface BuiltTrans {\n text: string;\n params: TaggedParam[];\n components: TransComponent[];\n}\n\nfunction buildTransMessage(code: string, children: AstNode[]): BuiltTrans | undefined {\n const params: TaggedParam[] = [];\n const components: TransComponent[] = [];\n const takenParams = new Map<string, string>();\n const takenTags = new Map<string, string>();\n\n function walkChildren(nodes: AstNode[]): string | undefined {\n let text = '';\n for (const child of nodes) {\n if (child.type === 'JSXText') {\n text += escapeText(cleanJsxText(child.value as string));\n } else if (child.type === 'JSXExpressionContainer') {\n const expr = child.expression as AstNode;\n if (expr.type === 'JSXEmptyExpression') continue;\n if (expr.type === 'StringLiteral') {\n text += escapeText(expr.value as string);\n continue;\n }\n if (expr.type === 'TaggedTemplateExpression') return undefined; // overlap hazard\n const source = code.slice(expr.start, expr.end);\n const name = uniqueName(deriveName(expr, params.length), source, takenParams);\n params.push({ name, start: expr.start, end: expr.end });\n text += `{${name}}`;\n } else if (child.type === 'JSXElement') {\n const opening = child.openingElement as AstNode;\n const nameNode = opening.name as AstNode;\n if (nameNode.type !== 'JSXIdentifier' || nameNode.name === 'Trans') return undefined;\n const source = selfClosedSource(code, opening);\n const tag = uniqueName((nameNode.name as string).toLowerCase(), source, takenTags);\n if (!components.some((c) => c.name === tag)) components.push({ name: tag, source });\n if (!child.closingElement) {\n text += `<${tag}/>`;\n } else {\n const inner = walkChildren(child.children as AstNode[]);\n if (inner === undefined) return undefined;\n text += `<${tag}>${inner}</${tag}>`;\n }\n } else {\n return undefined; // fragments / spread children → bail\n }\n }\n return text;\n }\n\n const text = walkChildren(children);\n if (text === undefined) return undefined;\n return { text, params, components };\n}\n\n// JSX text semantics: newline-indent boundaries removed, interior joins = one space\nfunction cleanJsxText(raw: string): string {\n const lines = raw.split(/\\r\\n|[\\r\\n]/);\n let out = '';\n for (let i = 0; i < lines.length; i++) {\n let line = lines[i]!.replace(/\\t/g, ' ');\n if (i !== 0) line = line.replace(/^ +/, '');\n if (i !== lines.length - 1) line = line.replace(/ +$/, '');\n if (!line) continue;\n if (out && i !== 0) out += ' ';\n out += line;\n }\n return out;\n}\n\nfunction selfClosedSource(code: string, opening: AstNode): string {\n const src = code.slice(opening.start, opening.end);\n return src.endsWith('/>') ? src : `${src.slice(0, -1).trimEnd()} />`;\n}\n\nfunction isTReference(node: AstNode): boolean {\n if (node.type === 'Identifier') return node.name === 't';\n if (node.type === 'MemberExpression' && !node.computed) {\n const prop = node.property as AstNode;\n return prop.type === 'Identifier' && prop.name === 't';\n }\n return false;\n}\n\ninterface BuiltMessage {\n text: string;\n params: TaggedParam[];\n}\n\nfunction buildMessage(code: string, quasi: AstNode): BuiltMessage | undefined {\n const quasis = quasi.quasis as AstNode[];\n const expressions = quasi.expressions as AstNode[];\n const params: TaggedParam[] = [];\n const taken = new Map<string, string>();\n\n let text = escapeText(cookedValue(quasis[0]));\n\n for (let i = 0; i < expressions.length; i++) {\n const expr = expressions[i];\n if (!expr) return undefined;\n const source = code.slice(expr.start, expr.end);\n const name = uniqueName(deriveName(expr, i), source, taken);\n params.push({ name, start: expr.start, end: expr.end });\n text += `{${name}}` + escapeText(cookedValue(quasis[i + 1]));\n }\n return { text, params };\n}\n\nfunction cookedValue(element: AstNode | undefined): string {\n if (!element) return '';\n const value = element.value as { cooked?: string; raw: string };\n return value.cooked ?? value.raw;\n}\n\n// literal braces → escaped\nfunction escapeText(text: string): string {\n return text.replace(/[{}]/g, (m) => m + m);\n}\n\nfunction deriveName(expr: AstNode, index: number): string {\n if (expr.type === 'Identifier') return expr.name as string;\n if (expr.type === 'MemberExpression' && !expr.computed) {\n const prop = expr.property as AstNode;\n if (prop.type === 'Identifier') return prop.name as string;\n }\n return `_${index}`;\n}\n\nfunction uniqueName(base: string, source: string, taken: Map<string, string>): string {\n let name = base;\n let n = 2;\n while (taken.has(name) && taken.get(name) !== source) {\n name = `${base}${n}`;\n n += 1;\n }\n taken.set(name, source);\n return name;\n}\n\nfunction walk(node: AstNode, visit: (node: AstNode) => void): void {\n visit(node);\n for (const [key, value] of Object.entries(node)) {\n if (SKIP_KEYS.has(key)) continue;\n if (Array.isArray(value)) {\n for (const item of value) {\n if (isNode(item)) walk(item, visit);\n }\n } else if (isNode(value)) {\n walk(value, visit);\n }\n }\n}\n\nfunction isNode(value: unknown): value is AstNode {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as { type?: unknown }).type === 'string'\n );\n}\n","import type { Analysis, TaggedMessage } from './analyze';\n\nexport class MessageRegistry {\n private files = new Map<string, Analysis>();\n\n update(file: string, analysis: Analysis): void {\n this.files.set(file, analysis);\n }\n\n remove(file: string): void {\n this.files.delete(file);\n }\n\n messages(): Map<string, TaggedMessage> {\n const out = new Map<string, TaggedMessage>();\n for (const analysis of this.files.values()) {\n for (const msg of analysis.tagged) {\n const existing = out.get(msg.key);\n if (existing) {\n if (existing.message !== msg.message) {\n console.warn(\n `[verbaly] key collision \"${msg.key}\": ` +\n `${JSON.stringify(existing.message)} vs ${JSON.stringify(msg.message)} — second dropped.`,\n );\n }\n continue;\n }\n out.set(msg.key, msg);\n }\n }\n return out;\n }\n\n usedKeys(): Map<string, string[]> {\n const out = new Map<string, string[]>();\n for (const analysis of this.files.values()) {\n for (const used of analysis.usedKeys) {\n const files = out.get(used.key) ?? [];\n if (!files.includes(used.file)) files.push(used.file);\n out.set(used.key, files);\n }\n }\n return out;\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { glob } from 'tinyglobby';\nimport { analyze } from './analyze';\nimport type { Catalogs } from './catalog';\nimport type { ResolvedConfig } from './config';\nimport { MessageRegistry } from './registry';\n\nexport async function extractProject(cfg: ResolvedConfig): Promise<MessageRegistry> {\n const files = await glob(cfg.include, {\n cwd: cfg.root,\n ignore: cfg.exclude,\n absolute: true,\n });\n const registry = new MessageRegistry();\n for (const file of files) {\n registry.update(file, analyze(readFileSync(file, 'utf8'), file));\n }\n return registry;\n}\n\nexport interface SyncResult {\n added: Record<string, string[]>;\n}\n\n// fills source texts + '' placeholders\nexport function syncCatalogs(\n cfg: ResolvedConfig,\n catalogs: Catalogs,\n registry: MessageRegistry,\n): SyncResult {\n const added: Record<string, string[]> = {};\n const source = (catalogs[cfg.sourceLocale] ??= {});\n\n for (const [key, msg] of registry.messages()) {\n if (source[key] !== msg.message) {\n source[key] = msg.message;\n (added[cfg.sourceLocale] ??= []).push(key);\n }\n }\n\n const needed = Object.keys(source);\n for (const locale of cfg.locales) {\n if (locale === cfg.sourceLocale) continue;\n const catalog = (catalogs[locale] ??= {});\n for (const key of needed) {\n if (catalog[key] === undefined) {\n catalog[key] = '';\n (added[locale] ??= []).push(key);\n }\n }\n }\n return { added };\n}\n\n// drops keys no longer referenced\nexport function pruneCatalogs(\n cfg: ResolvedConfig,\n catalogs: Catalogs,\n registry: MessageRegistry,\n): Record<string, string[]> {\n const keep = new Set([...registry.messages().keys(), ...registry.usedKeys().keys()]);\n const removed: Record<string, string[]> = {};\n for (const locale of cfg.locales) {\n const catalog = catalogs[locale];\n if (!catalog) continue;\n for (const key of Object.keys(catalog)) {\n if (!keep.has(key)) {\n delete catalog[key];\n (removed[locale] ??= []).push(key);\n }\n }\n }\n return removed;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join, relative } from 'node:path';\nimport { findConfigFile } from './config';\n\nexport interface InitOptions {\n root?: string;\n dir?: string;\n sourceLocale?: string;\n locales?: string[];\n}\n\nexport interface InitResult {\n created: string[];\n skipped: string[];\n bundler: 'vite' | 'webpack' | 'rollup' | 'rspack' | 'esbuild' | undefined;\n configFile: string;\n next: string[];\n}\n\nconst BUNDLERS = ['vite', 'webpack', 'rollup', 'rspack', 'esbuild'] as const;\n\nexport function detectBundler(root: string): InitResult['bundler'] {\n const path = join(root, 'package.json');\n if (!existsSync(path)) return undefined;\n try {\n const pkg = JSON.parse(readFileSync(path, 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return BUNDLERS.find((name) => deps[name]);\n } catch {\n return undefined;\n }\n}\n\nfunction configSource(options: InitOptions, typescript: boolean): string {\n const fields = [` sourceLocale: '${options.sourceLocale ?? 'en'}',`];\n if (options.locales?.length) {\n fields.push(` locales: [${options.locales.map((l) => `'${l}'`).join(', ')}],`);\n }\n if (options.dir) fields.push(` dir: '${options.dir}',`);\n const body = `export default {\\n${fields.join('\\n')}\\n}`;\n if (typescript) {\n return `import type { VerbalyConfig } from '@verbaly/compiler';\\n\\n${body} satisfies VerbalyConfig;\\n`;\n }\n return `/** @type {import('@verbaly/compiler').VerbalyConfig} */\\n${body};\\n`;\n}\n\nexport function init(options: InitOptions = {}): InitResult {\n const root = options.root ?? process.cwd();\n const created: string[] = [];\n const skipped: string[] = [];\n\n const existing = findConfigFile(root);\n const typescript = existsSync(join(root, 'tsconfig.json'));\n const configFile = existing ?? (typescript ? 'verbaly.config.ts' : 'verbaly.config.mjs');\n if (existing) {\n skipped.push(existing);\n } else {\n writeFileSync(join(root, configFile), configSource(options, typescript));\n created.push(configFile);\n }\n\n const dir = join(root, options.dir ?? 'locales');\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n for (const locale of new Set([options.sourceLocale ?? 'en', ...(options.locales ?? [])])) {\n const file = join(dir, `${locale}.json`);\n const label = relative(root, file).replaceAll('\\\\', '/');\n if (existsSync(file)) {\n skipped.push(label);\n } else {\n writeFileSync(file, '{}\\n');\n created.push(label);\n }\n }\n\n const bundler = detectBundler(root);\n const next: string[] = [];\n if (bundler === 'vite') {\n next.push(\n 'install the plugin: pnpm add -D @verbaly/vite',\n 'add verbaly() to the plugins in vite.config',\n );\n } else if (bundler) {\n next.push(\n 'install the plugin: pnpm add -D @verbaly/unplugin',\n `add the verbaly ${bundler} plugin to your build config`,\n );\n } else {\n next.push('run \"verbaly extract\" after writing your first t`…` message');\n }\n\n return { created, skipped, bundler, configFile, next };\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join, relative } from 'node:path';\nimport type { Catalogs } from './catalog';\nimport { check } from './check';\nimport { generateDts } from './codegen';\nimport { findConfigFile, type ResolvedConfig } from './config';\nimport { extractProject } from './extract';\nimport { detectBundler } from './init';\n\nexport interface DoctorEntry {\n level: 'ok' | 'warn' | 'error';\n check: string;\n message: string;\n fix?: string;\n}\n\nexport interface DoctorResult {\n ok: boolean; // no error-level entries (warns allowed)\n entries: DoctorEntry[];\n}\n\nconst PREVIEW = 5; // keys shown before \"…\"\n\nexport async function doctor(cfg: ResolvedConfig): Promise<DoctorResult> {\n const entries: DoctorEntry[] = [];\n const ok = (check: string, message: string) => entries.push({ level: 'ok', check, message });\n const warn = (check: string, message: string, fix: string) =>\n entries.push({ level: 'warn', check, message, fix });\n const error = (check: string, message: string, fix: string) =>\n entries.push({ level: 'error', check, message, fix });\n const rel = (path: string) => relative(cfg.root, path).replaceAll('\\\\', '/');\n\n const configFile = findConfigFile(cfg.root);\n if (configFile) ok('config', `${configFile} found`);\n else warn('config', 'no config file — running on defaults', 'run `npx verbaly init`');\n\n const catalogs: Catalogs = {};\n let catalogsHealthy = true;\n if (!existsSync(cfg.dir)) {\n catalogsHealthy = false;\n error(\n 'catalogs',\n `catalogs directory ${rel(cfg.dir)}/ does not exist`,\n 'run `npx verbaly init` to scaffold it',\n );\n } else {\n for (const locale of cfg.locales) {\n const file = join(cfg.dir, `${locale}.json`);\n if (!existsSync(file)) {\n catalogsHealthy = false;\n error(\n `locale ${locale}`,\n `${rel(file)} is missing`,\n 'run `npx verbaly extract` to create it',\n );\n continue;\n }\n try {\n const parsed = JSON.parse(readFileSync(file, 'utf8')) as Record<string, unknown>;\n const bad = Object.entries(parsed).find(([, value]) => typeof value !== 'string');\n if (bad) {\n catalogsHealthy = false;\n error(\n `locale ${locale}`,\n `${rel(file)} has a non-string value at \"${bad[0]}\"`,\n 'catalogs are flat key → string JSON; fix the value',\n );\n } else {\n catalogs[locale] = parsed as Record<string, string>;\n }\n } catch {\n catalogsHealthy = false;\n error(\n `locale ${locale}`,\n `${rel(file)} is not valid JSON`,\n 'repair the file (or delete it and run `npx verbaly extract`)',\n );\n }\n }\n if (catalogsHealthy) {\n ok(\n 'catalogs',\n `${cfg.locales.length} locales (${cfg.locales.join(', ')}) in ${rel(cfg.dir)}/`,\n );\n }\n }\n\n const source = catalogs[cfg.sourceLocale];\n if (source && Object.keys(source).length === 0) {\n warn(\n 'source',\n `source catalog ${cfg.sourceLocale}.json is empty`,\n 'write your first t`…` message and run `npx verbaly extract`',\n );\n }\n\n const deps = readDeps(cfg.root);\n const bundler = detectBundler(cfg.root);\n const wired = deps['@verbaly/vite'] || deps['@verbaly/unplugin'];\n if (!bundler) {\n ok('plugin', 'no bundler detected — CLI flow (extract/check) applies');\n } else if (wired) {\n ok(\n 'plugin',\n `${deps['@verbaly/vite'] ? '@verbaly/vite' : '@verbaly/unplugin'} installed for ${bundler}`,\n );\n } else if (bundler === 'vite') {\n warn(\n 'plugin',\n 'vite detected but @verbaly/vite is not installed',\n 'pnpm add -D @verbaly/vite and add verbaly() to the plugins in vite.config',\n );\n } else {\n warn(\n 'plugin',\n `${bundler} detected but @verbaly/unplugin is not installed`,\n `pnpm add -D @verbaly/unplugin and add the verbaly ${bundler} plugin to your build config`,\n );\n }\n\n if (source) {\n const dtsPath = join(cfg.root, 'verbaly.d.ts');\n if (!existsSync(dtsPath)) {\n warn('types', 'verbaly.d.ts has not been generated', 'run `npx verbaly extract`');\n } else if (readFileSync(dtsPath, 'utf8') !== generateDts(new Map(Object.entries(source)))) {\n warn('types', 'verbaly.d.ts is stale', 'run `npx verbaly extract`');\n } else {\n ok('types', 'verbaly.d.ts is up to date');\n }\n }\n\n const registry = await extractProject(cfg);\n if (source) {\n const extracted = registry.messages();\n const used = registry.usedKeys();\n const orphans = Object.keys(source).filter((key) => !extracted.has(key) && !used.has(key));\n if (orphans.length > 0) {\n warn(\n 'orphans',\n `${orphans.length} catalog ${orphans.length === 1 ? 'key is' : 'keys are'} no longer referenced (${preview(orphans)})`,\n 'run `npx verbaly extract --prune` to drop them',\n );\n } else {\n ok('orphans', 'no orphan keys');\n }\n }\n\n if (catalogsHealthy) {\n const result = check(cfg, catalogs, registry);\n if (result.unknown.length > 0) {\n error(\n 'keys',\n `${result.unknown.length} unknown ${result.unknown.length === 1 ? 'key' : 'keys'} used in code (${preview(result.unknown.map((u) => u.key))})`,\n 'fix the key or add it to the catalogs — `npx verbaly check` for details',\n );\n }\n if (result.missing.length > 0) {\n const locales = [...new Set(result.missing.map((m) => m.locale))];\n warn(\n 'translations',\n `${result.missing.length} missing ${result.missing.length === 1 ? 'translation' : 'translations'} (${locales.join(', ')})`,\n 'run `npx verbaly translate` or fill the catalogs — `npx verbaly check` for details',\n );\n }\n if (result.ok) ok('translations', 'all translations complete');\n }\n\n return { ok: entries.every((entry) => entry.level !== 'error'), entries };\n}\n\nfunction preview(keys: string[]): string {\n const head = keys.slice(0, PREVIEW).join(', ');\n return keys.length > PREVIEW ? `${head}, …` : head;\n}\n\nfunction readDeps(root: string): Record<string, string> {\n try {\n const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n return { ...pkg.dependencies, ...pkg.devDependencies };\n } catch {\n return {};\n }\n}\n","import type { Catalog, Catalogs } from './catalog';\nimport type { ResolvedConfig } from './config';\n\nexport const PSEUDO_LOCALE = 'en-XA';\n\nconst ACCENTS: Record<string, string> = {\n a: 'á',\n b: 'ƀ',\n c: 'ç',\n d: 'đ',\n e: 'é',\n f: 'ƒ',\n g: 'ğ',\n h: 'ĥ',\n i: 'í',\n j: 'ĵ',\n k: 'ķ',\n l: 'ĺ',\n m: 'ɱ',\n n: 'ñ',\n o: 'ó',\n p: 'þ',\n q: 'ǫ',\n r: 'ŕ',\n s: 'š',\n t: 'ţ',\n u: 'ú',\n v: 'ṽ',\n w: 'ŵ',\n x: 'ẋ',\n y: 'ý',\n z: 'ž',\n A: 'Á',\n B: 'Ɓ',\n C: 'Ç',\n D: 'Đ',\n E: 'É',\n F: 'Ƒ',\n G: 'Ğ',\n H: 'Ĥ',\n I: 'Í',\n J: 'Ĵ',\n K: 'Ķ',\n L: 'Ĺ',\n M: 'Ḿ',\n N: 'Ñ',\n O: 'Ó',\n P: 'Þ',\n Q: 'Ǫ',\n R: 'Ŕ',\n S: 'Š',\n T: 'Ţ',\n U: 'Ú',\n V: 'Ṽ',\n W: 'Ŵ',\n X: 'Ẍ',\n Y: 'Ý',\n Z: 'Ž',\n};\n\nconst TAG_AT = /<\\/?[a-zA-Z][\\w-]*\\/?>/y;\n\n// params, variant blocks, tags and escapes survive verbatim\nexport function pseudoLocalize(message: string): string {\n let out = '';\n let letters = 0;\n let i = 0;\n while (i < message.length) {\n const two = message.slice(i, i + 2);\n if (two === '{{' || two === '}}' || two === '||' || two === '##') {\n out += two;\n i += 2;\n continue;\n }\n const ch = message[i]!;\n if (ch === '{') {\n const end = matchBrace(message, i);\n out += message.slice(i, end);\n i = end;\n continue;\n }\n if (ch === '<') {\n TAG_AT.lastIndex = i;\n const m = TAG_AT.exec(message);\n if (m) {\n out += m[0];\n i += m[0].length;\n continue;\n }\n }\n const mapped = ACCENTS[ch];\n if (mapped) {\n out += mapped;\n letters += 1;\n } else {\n out += ch;\n }\n i += 1;\n }\n const pad = '~'.repeat(Math.ceil(letters / 3));\n return `⟦${out}${pad ? ' ' + pad : ''}⟧`;\n}\n\nfunction matchBrace(message: string, start: number): number {\n let depth = 0;\n for (let i = start; i < message.length; i++) {\n const two = message.slice(i, i + 2);\n if (two === '{{' || two === '}}') {\n i += 1;\n continue;\n }\n const ch = message[i];\n if (ch === '{') depth += 1;\n else if (ch === '}') {\n depth -= 1;\n if (depth === 0) return i + 1;\n }\n }\n return message.length; // unbalanced → verbatim\n}\n\n// regenerates the whole pseudo catalog from the source catalog\nexport function pseudoCatalogs(\n cfg: ResolvedConfig,\n catalogs: Catalogs,\n locale: string = PSEUDO_LOCALE,\n): string[] {\n const source = catalogs[cfg.sourceLocale] ?? {};\n const target: Catalog = {};\n for (const [key, msg] of Object.entries(source)) {\n target[key] = msg ? pseudoLocalize(msg) : '';\n }\n catalogs[locale] = target;\n return Object.keys(target).filter((key) => target[key]);\n}\n","import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join, relative } from 'node:path';\nimport MagicString from 'magic-string';\nimport { glob } from 'tinyglobby';\nimport {\n createVerbaly,\n parseTags,\n RICH_TAGS,\n safeHref,\n type Params,\n type RichLink,\n type TagNode,\n} from 'verbaly';\nimport type { Catalogs } from './catalog';\nimport { loadCatalogs } from './catalog';\nimport type { ResolvedConfig } from './config';\n\nexport interface RenderHtmlOptions {\n locale: string;\n catalogs: Catalogs;\n sourceLocale?: string;\n attribute?: string;\n richTags?: string[];\n richLinks?: Record<string, RichLink>;\n setLang?: boolean;\n}\n\nexport interface RenderHtmlResult {\n html: string;\n missing: string[];\n}\n\nconst VOID_TAGS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n]);\n\nconst START_TAG = /<([a-zA-Z][a-zA-Z0-9-]*)((?:\"[^\"]*\"|'[^']*'|[^\"'>])*)>/g;\nconst ATTR = /([^\\s=/\"'<>]+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]+)))?/g;\n\n// pre-fills data-verbaly elements for one locale; the runtime stays functional\nexport function renderHtml(html: string, options: RenderHtmlOptions): RenderHtmlResult {\n const attr = options.attribute ?? 'data-verbaly';\n const argsAttr = `${attr}-args`;\n const attrsAttr = `${attr}-attr`;\n const richAttr = `${attr}-rich`;\n const linksAttr = `${attr}-links`;\n const richTags = new Set(options.richTags ?? RICH_TAGS);\n const globalLinks = options.richLinks;\n const sourceLocale = options.sourceLocale ?? 'en';\n\n // '' entries count as untranslated → fall back\n const messages: Record<string, Record<string, string>> = {};\n for (const [locale, catalog] of Object.entries(options.catalogs)) {\n const clean: Record<string, string> = {};\n for (const [key, msg] of Object.entries(catalog)) if (msg) clean[key] = msg;\n messages[locale] = clean;\n }\n const v = createVerbaly({ locale: options.locale, fallback: sourceLocale, messages });\n const t = v.t as unknown as (key: string, params?: Params) => string;\n\n const ms = new MagicString(html);\n const missing = new Set<string>();\n const skip = protectedRanges(html);\n const inSkip = (index: number): boolean => skip.some(([from, to]) => index >= from && index < to);\n\n START_TAG.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = START_TAG.exec(html)) !== null) {\n if (inSkip(m.index)) continue;\n const [full, rawName, attrChunk] = m as unknown as [string, string, string];\n const tagName = rawName.toLowerCase();\n const openEnd = m.index + full.length;\n\n const chunkStart = m.index + 1 + rawName.length;\n\n if (tagName === 'html' && options.setLang !== false) {\n setAttribute(ms, html, chunkStart, openEnd, attrChunk, 'lang', options.locale);\n continue;\n }\n\n const attrs = parseAttrs(attrChunk);\n const key = attrs.get(attr);\n const attrMapRaw = attrs.get(attrsAttr);\n if (key === undefined && attrMapRaw === undefined) continue;\n\n const args = parseArgs(attrs.get(argsAttr));\n\n if (key) {\n if (!v.has(key)) {\n missing.add(key);\n } else if (!VOID_TAGS.has(tagName) && !attrChunk.trimEnd().endsWith('/')) {\n const close = findClose(html, tagName, openEnd, inSkip);\n if (close) {\n const text = t(key, args);\n const own = parseArgs(attrs.get(linksAttr)) as Record<string, RichLink> | undefined;\n const links = own ? (globalLinks ? { ...globalLinks, ...own } : own) : globalLinks;\n const content = attrs.has(richAttr)\n ? richToHtml(parseTags(text), richTags, links)\n : escapeHtml(text);\n if (html.slice(openEnd, close.contentEnd) !== content) {\n if (openEnd === close.contentEnd) ms.appendLeft(openEnd, content);\n else ms.overwrite(openEnd, close.contentEnd, content);\n }\n }\n }\n }\n\n if (attrMapRaw !== undefined) {\n const map = parseArgs(attrMapRaw);\n if (map) {\n for (const [name, attrKey] of Object.entries(map)) {\n if (typeof attrKey !== 'string' || name.toLowerCase().startsWith('on')) continue;\n if (!v.has(attrKey)) {\n missing.add(attrKey);\n continue;\n }\n setAttribute(ms, html, chunkStart, openEnd, attrChunk, name, t(attrKey, args));\n }\n }\n }\n }\n\n return { html: ms.toString(), missing: [...missing] };\n}\n\nexport interface RenderSiteOptions {\n site?: string;\n locales?: string[];\n attribute?: string;\n richTags?: string[];\n richLinks?: Record<string, RichLink>;\n}\n\nexport interface RenderSiteResult {\n files: number;\n locales: string[];\n missing: Record<string, string[]>;\n}\n\n// mirrors the built site per locale: dist/index.html → dist/<locale>/index.html\nexport async function renderSite(\n cfg: ResolvedConfig,\n options: RenderSiteOptions = {},\n): Promise<RenderSiteResult> {\n const site = join(cfg.root, options.site ?? 'dist');\n const locales = options.locales ?? cfg.locales;\n const catalogs = loadCatalogs(cfg);\n const files = await glob('**/*.html', {\n cwd: site,\n absolute: true,\n ignore: locales.map((locale) => `${locale}/**`),\n });\n\n const missing: Record<string, string[]> = {};\n for (const file of files) {\n const html = readFileSync(file, 'utf8');\n const rel = relative(site, file);\n for (const locale of locales) {\n const result = renderHtml(html, {\n locale,\n catalogs,\n sourceLocale: cfg.sourceLocale,\n attribute: options.attribute,\n richTags: options.richTags,\n richLinks: options.richLinks ?? cfg.render.links,\n });\n for (const key of result.missing) {\n const list = (missing[locale] ??= []);\n if (!list.includes(key)) list.push(key);\n }\n const out = locale === cfg.sourceLocale ? file : join(site, locale, rel);\n mkdirSync(dirname(out), { recursive: true });\n writeFileSync(out, result.html);\n }\n }\n return { files: files.length, locales: [...locales], missing };\n}\n\nfunction parseAttrs(chunk: string): Map<string, string> {\n const attrs = new Map<string, string>();\n ATTR.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = ATTR.exec(chunk)) !== null) {\n attrs.set(m[1]!.toLowerCase(), m[2] ?? m[3] ?? m[4] ?? '');\n }\n return attrs;\n}\n\nfunction parseArgs(raw: string | undefined): Params | undefined {\n if (!raw) return undefined;\n try {\n return JSON.parse(decodeEntities(raw)) as Params;\n } catch {\n console.warn(`[verbaly] invalid args JSON: ${raw}`);\n return undefined;\n }\n}\n\n// comments and script/style bodies are opaque to the scanner\nfunction protectedRanges(html: string): Array<[number, number]> {\n const ranges: Array<[number, number]> = [];\n const re = /<!--[\\s\\S]*?-->|<script\\b[\\s\\S]*?<\\/script\\s*>|<style\\b[\\s\\S]*?<\\/style\\s*>/gi;\n let m: RegExpExecArray | null;\n while ((m = re.exec(html)) !== null) {\n // keep script/style open tags scannable; protect only their bodies\n const openEnd = m[0].startsWith('<!--') ? m.index : html.indexOf('>', m.index) + 1;\n ranges.push([openEnd, m.index + m[0].length]);\n }\n return ranges;\n}\n\nfunction findClose(\n html: string,\n tagName: string,\n from: number,\n inSkip: (index: number) => boolean,\n): { contentEnd: number } | null {\n const re = new RegExp(\n `<${tagName}(?=[\\\\s/>])(?:\"[^\"]*\"|'[^']*'|[^\"'>])*>|</${tagName}\\\\s*>`,\n 'gi',\n );\n re.lastIndex = from;\n let depth = 1;\n let m: RegExpExecArray | null;\n while ((m = re.exec(html)) !== null) {\n if (inSkip(m.index)) continue;\n if (m[0][1] === '/') {\n depth -= 1;\n if (depth === 0) return { contentEnd: m.index };\n } else if (!m[0].endsWith('/>')) {\n depth += 1;\n }\n }\n return null;\n}\n\nfunction setAttribute(\n ms: MagicString,\n html: string,\n chunkStart: number,\n openEnd: number,\n attrChunk: string,\n name: string,\n value: string,\n): void {\n const escaped = escapeAttr(value);\n const existing = new RegExp(`(\\\\s${name}\\\\s*=\\\\s*)(\"[^\"]*\"|'[^']*'|[^\\\\s>]+)`, 'i').exec(\n attrChunk,\n );\n if (existing) {\n const valueStart = chunkStart + existing.index + existing[1]!.length;\n const valueEnd = valueStart + existing[2]!.length;\n if (html.slice(valueStart, valueEnd) !== `\"${escaped}\"`) {\n ms.overwrite(valueStart, valueEnd, `\"${escaped}\"`);\n }\n return;\n }\n const selfClosing = html.slice(openEnd - 2, openEnd) === '/>';\n const insertAt = openEnd - (selfClosing ? 2 : 1);\n ms.appendLeft(insertAt, ` ${name}=\"${escaped}\"`);\n}\n\nfunction richToHtml(\n nodes: TagNode[],\n allowed: Set<string>,\n links?: Record<string, RichLink>,\n): string {\n let out = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n out += escapeHtml(node);\n } else if (links?.[node.name] !== undefined) {\n const link = links[node.name]!;\n const { href, target, rel }: Exclude<RichLink, string> =\n typeof link === 'string' ? { href: link } : link;\n const safe = safeHref(href);\n let attrs = safe !== undefined ? ` href=\"${escapeAttr(safe)}\"` : '';\n if (target) attrs += ` target=\"${escapeAttr(target)}\"`;\n if (rel) attrs += ` rel=\"${escapeAttr(rel)}\"`;\n out += `<a${attrs}>${richToHtml(node.children, allowed, links)}</a>`;\n } else if (allowed.has(node.name)) {\n out += `<${node.name}>${richToHtml(node.children, allowed, links)}</${node.name}>`;\n } else {\n out += richToHtml(node.children, allowed, links); // unknown tag → unwrap\n }\n }\n return out;\n}\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\nfunction escapeAttr(text: string): string {\n return escapeHtml(text).replace(/\"/g, '&quot;');\n}\n\nfunction decodeEntities(text: string): string {\n return text\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&amp;/g, '&');\n}\n","import type { Catalogs } from './catalog';\nimport type { ResolvedConfig } from './config';\nimport { collectParams } from './params';\n\nexport interface TranslateRequest {\n sourceLocale: string;\n targetLocale: string;\n messages: Record<string, string>;\n}\n\nexport type TranslateProvider = (request: TranslateRequest) => Promise<Record<string, string>>;\n\nexport interface TranslateOptions {\n locales?: string[];\n batchSize?: number;\n dryRun?: boolean;\n}\n\nexport interface TranslateResult {\n translated: Record<string, string[]>;\n invalid: Record<string, string[]>;\n pending: Record<string, string[]>;\n}\n\n// fills '' entries via the provider; invalid translations stay '' (check keeps failing)\nexport async function translateCatalogs(\n cfg: ResolvedConfig,\n catalogs: Catalogs,\n provider: TranslateProvider,\n options: TranslateOptions = {},\n): Promise<TranslateResult> {\n const batchSize = options.batchSize ?? 20;\n const targets = (options.locales ?? cfg.locales).filter(\n (locale) => locale !== cfg.sourceLocale && cfg.locales.includes(locale),\n );\n const source = catalogs[cfg.sourceLocale] ?? {};\n const result: TranslateResult = { translated: {}, invalid: {}, pending: {} };\n\n for (const locale of targets) {\n const catalog = (catalogs[locale] ??= {});\n const missing = Object.keys(source).filter((key) => source[key] && !catalog[key]);\n if (missing.length === 0) continue;\n\n if (options.dryRun) {\n result.pending[locale] = missing;\n continue;\n }\n\n for (let i = 0; i < missing.length; i += batchSize) {\n const keys = missing.slice(i, i + batchSize);\n const messages = Object.fromEntries(keys.map((key) => [key, source[key]!]));\n const out = await provider({\n sourceLocale: cfg.sourceLocale,\n targetLocale: locale,\n messages,\n });\n for (const key of keys) {\n const text = out[key];\n if (typeof text === 'string' && text.trim() && structureMatches(source[key]!, text)) {\n catalog[key] = text;\n (result.translated[locale] ??= []).push(key);\n } else {\n (result.invalid[locale] ??= []).push(key);\n }\n }\n }\n }\n return result;\n}\n\n// params and tags must survive translation verbatim\nexport function structureMatches(source: string, translated: string): boolean {\n return (\n sameMembers(paramNames(source), paramNames(translated)) &&\n sameMembers(tagTokens(source), tagTokens(translated))\n );\n}\n\nfunction paramNames(message: string): string[] {\n try {\n return [...collectParams(message).keys()].sort();\n } catch {\n return ['\u0000invalid'];\n }\n}\n\nconst TAG = /<(\\/?)([a-zA-Z][\\w-]*)(\\/?)>/g;\n\nfunction tagTokens(message: string): string[] {\n const out: string[] = [];\n for (const match of message.matchAll(TAG)) {\n out.push(`${match[1]}${match[2]}${match[3]}`);\n }\n return out.sort();\n}\n\nfunction sameMembers(a: string[], b: string[]): boolean {\n return a.length === b.length && a.every((value, i) => value === b[i]);\n}\n","#!/usr/bin/env node\nimport { parseArgs } from 'node:util';\nimport { loadCatalogs, writeCatalog } from './catalog';\nimport { check, formatCheckResult } from './check';\nimport { writeDts } from './codegen';\nimport { loadConfig } from './config';\nimport { doctor } from './doctor';\nimport { extractProject, pruneCatalogs, syncCatalogs } from './extract';\nimport { init } from './init';\nimport { PSEUDO_LOCALE, pseudoCatalogs } from './pseudo';\nimport { renderSite } from './render';\nimport { translateCatalogs, type TranslateProvider } from './translate';\nimport type { ResolvedConfig } from './config';\n\nconst HELP = `verbaly — i18n compiler\n\nUsage:\n verbaly init scaffold config + locale catalogs (detects your bundler)\n verbaly doctor diagnose the setup (config, catalogs, plugin, types, keys)\n verbaly extract scan sources, update catalogs and types\n verbaly check verify translations are complete (CI)\n verbaly translate fill missing translations via a provider (default: claude)\n verbaly pseudo generate a pseudo-locale catalog for i18n QA (default: en-XA)\n verbaly render pre-fill data-verbaly HTML per locale (SSG, kills the FOUC)\n\nOptions:\n --root <path> project root (default: cwd)\n --dir <path> catalogs directory (default: locales)\n --source <locale> source locale (default: en)\n --locales <csv> extra locales; for translate: target locales to fill\n --prune drop keys no longer referenced (extract)\n --model <id> model override for the claude provider (translate)\n --dry-run list what would be translated, write nothing (translate)\n --locale <id> pseudo-locale id (pseudo, default: en-XA)\n --site <path> built site directory (render, default: dist)\n\nConfig file: verbaly.config.{js,mjs,ts,mts,json} at root (flags win).\nThe claude provider needs @anthropic-ai/sdk installed and ANTHROPIC_API_KEY set.\n`;\n\nasync function main(): Promise<void> {\n const { positionals, values } = parseArgs({\n allowPositionals: true,\n options: {\n root: { type: 'string' },\n dir: { type: 'string' },\n source: { type: 'string' },\n locales: { type: 'string' },\n prune: { type: 'boolean' },\n model: { type: 'string' },\n locale: { type: 'string' },\n site: { type: 'string' },\n 'dry-run': { type: 'boolean' },\n help: { type: 'boolean', short: 'h' },\n },\n });\n\n const command = positionals[0];\n if (values.help || !command) {\n console.log(HELP);\n process.exitCode = command ? 0 : 1;\n return;\n }\n\n if (command === 'init') {\n const result = init({\n root: values.root,\n dir: values.dir,\n sourceLocale: values.source,\n locales: values.locales?.split(','),\n });\n if (result.created.length) console.log(`[verbaly] created: ${result.created.join(', ')}`);\n if (result.skipped.length) console.log(` kept (already there): ${result.skipped.join(', ')}`);\n if (result.bundler) console.log(` detected bundler: ${result.bundler}`);\n console.log(\n [' next steps:', ...result.next.map((step, i) => ` ${i + 1}. ${step}`)].join('\\n'),\n );\n return;\n }\n\n const cfg = await loadConfig(values.root ?? process.cwd(), {\n dir: values.dir,\n sourceLocale: values.source,\n locales: values.locales?.split(','),\n });\n\n if (command === 'doctor') {\n const result = await doctor(cfg);\n const icon = { ok: '✓', warn: '⚠', error: '✗' } as const;\n console.log(`[verbaly] doctor — ${result.entries.length} checks`);\n for (const entry of result.entries) {\n const line = ` ${icon[entry.level]} ${entry.check}: ${entry.message}`;\n if (entry.level === 'error') console.error(line);\n else if (entry.level === 'warn') console.warn(line);\n else console.log(line);\n if (entry.fix) console.log(` fix: ${entry.fix}`);\n }\n if (result.ok) {\n console.log('[verbaly] setup looks healthy ✓');\n } else {\n console.error('[verbaly] doctor found problems');\n process.exitCode = 1;\n }\n return;\n }\n\n if (command === 'extract') {\n const registry = await extractProject(cfg);\n const catalogs = loadCatalogs(cfg);\n if (values.prune) {\n const removed = pruneCatalogs(cfg, catalogs, registry);\n for (const [locale, keys] of Object.entries(removed)) {\n console.log(` ${locale}: -${keys.length} pruned`);\n }\n }\n const { added } = syncCatalogs(cfg, catalogs, registry);\n for (const locale of cfg.locales) {\n writeCatalog(cfg, locale, catalogs[locale] ?? {});\n }\n writeDts(cfg, new Map(Object.entries(catalogs[cfg.sourceLocale] ?? {})));\n const total = registry.messages().size;\n console.log(`[verbaly] ${total} messages · locales: ${cfg.locales.join(', ')}`);\n for (const [locale, keys] of Object.entries(added)) {\n console.log(` ${locale}: +${keys.length}`);\n }\n return;\n }\n\n if (command === 'check') {\n const registry = await extractProject(cfg);\n const result = check(cfg, loadCatalogs(cfg), registry);\n if (result.ok) {\n console.log('[verbaly] all translations complete ✓');\n return;\n }\n console.error(`[verbaly] check failed\\n${formatCheckResult(result)}`);\n process.exitCode = 1;\n return;\n }\n\n if (command === 'translate') {\n const catalogs = loadCatalogs(cfg);\n const provider = await resolveProvider(cfg, values.model);\n const result = await translateCatalogs(cfg, catalogs, provider, {\n locales: values.locales?.split(','),\n batchSize: cfg.translate.batchSize,\n dryRun: values['dry-run'],\n });\n\n if (values['dry-run']) {\n const entries = Object.entries(result.pending);\n if (entries.length === 0) {\n console.log('[verbaly] nothing to translate ✓');\n return;\n }\n for (const [locale, keys] of entries) {\n console.log(` ${locale}: ${keys.length} missing — ${keys.join(', ')}`);\n }\n return;\n }\n\n for (const locale of Object.keys(result.translated)) {\n writeCatalog(cfg, locale, catalogs[locale] ?? {});\n console.log(` ${locale}: +${result.translated[locale]!.length} translated`);\n }\n for (const [locale, keys] of Object.entries(result.invalid)) {\n console.warn(\n ` ${locale}: ${keys.length} rejected (params/tags not preserved): ${keys.join(', ')}`,\n );\n }\n if (Object.keys(result.translated).length === 0 && Object.keys(result.invalid).length === 0) {\n console.log('[verbaly] nothing to translate ✓');\n }\n return;\n }\n\n if (command === 'render') {\n const result = await renderSite(cfg, {\n site: values.site,\n locales: values.locales?.split(','),\n });\n console.log(\n `[verbaly] ${result.files} pages × ${result.locales.length} locales (${result.locales.join(', ')})`,\n );\n for (const [locale, keys] of Object.entries(result.missing)) {\n console.warn(` ${locale}: ${keys.length} keys not pre-filled — ${keys.join(', ')}`);\n }\n return;\n }\n\n if (command === 'pseudo') {\n const catalogs = loadCatalogs(cfg);\n const locale = values.locale ?? PSEUDO_LOCALE;\n const keys = pseudoCatalogs(cfg, catalogs, locale);\n writeCatalog(cfg, locale, catalogs[locale] ?? {});\n console.log(`[verbaly] ${keys.length} messages pseudo-localized → ${locale}`);\n return;\n }\n\n console.error(`[verbaly] unknown command \"${command}\"\\n${HELP}`);\n process.exitCode = 1;\n}\n\nasync function resolveProvider(\n cfg: ResolvedConfig,\n model: string | undefined,\n): Promise<TranslateProvider> {\n const configured = cfg.translate.provider;\n if (typeof configured === 'function') return configured;\n const { claudeProvider } = await import('./providers/claude');\n return claudeProvider({ model: model ?? cfg.translate.model });\n}\n\nmain().catch((error: unknown) => {\n console.error('[verbaly]', error instanceof Error ? error.message : error);\n process.exitCode = 1;\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":["parse","parseArgs"],"sources":["../src/catalog.ts","../src/check.ts","../src/params.ts","../src/codegen.ts","../src/config.ts","../src/key.ts","../src/analyze.ts","../src/registry.ts","../src/extract.ts","../src/init.ts","../src/doctor.ts","../src/pseudo.ts","../src/render.ts","../src/translate.ts","../src/cli.ts"],"sourcesContent":["import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ResolvedConfig } from './config';\n\nexport type Catalog = Record<string, string>;\nexport type Catalogs = Record<string, Catalog>;\n\nexport function catalogPath(cfg: ResolvedConfig, locale: string): string {\n return join(cfg.dir, `${locale}.json`);\n}\n\nexport function readCatalog(cfg: ResolvedConfig, locale: string): Catalog {\n try {\n return JSON.parse(readFileSync(catalogPath(cfg, locale), 'utf8')) as Catalog;\n } catch {\n return {};\n }\n}\n\nexport function loadCatalogs(cfg: ResolvedConfig): Catalogs {\n const catalogs: Catalogs = {};\n for (const locale of cfg.locales) catalogs[locale] = readCatalog(cfg, locale);\n return catalogs;\n}\n\nexport function serializeCatalog(catalog: Catalog): string {\n const sorted: Catalog = {};\n for (const key of Object.keys(catalog).sort()) {\n const value = catalog[key];\n if (value !== undefined) sorted[key] = value;\n }\n return JSON.stringify(sorted, null, 2) + '\\n';\n}\n\nexport function writeCatalog(cfg: ResolvedConfig, locale: string, catalog: Catalog): string {\n const serialized = serializeCatalog(catalog);\n mkdirSync(cfg.dir, { recursive: true });\n writeFileSync(catalogPath(cfg, locale), serialized);\n return serialized;\n}\n","import type { Catalogs } from './catalog';\nimport type { ResolvedConfig } from './config';\nimport type { MessageRegistry } from './registry';\n\nexport interface MissingEntry {\n locale: string;\n key: string;\n source?: string;\n}\n\nexport interface UnknownEntry {\n key: string;\n files: string[];\n}\n\nexport interface CheckResult {\n ok: boolean;\n missing: MissingEntry[];\n unknown: UnknownEntry[];\n}\n\nexport function check(\n cfg: ResolvedConfig,\n catalogs: Catalogs,\n registry: MessageRegistry,\n): CheckResult {\n const source = catalogs[cfg.sourceLocale] ?? {};\n const extracted = registry.messages();\n\n const unknown: UnknownEntry[] = [];\n for (const [key, files] of registry.usedKeys()) {\n const known =\n extracted.has(key) || cfg.locales.some((locale) => catalogs[locale]?.[key] !== undefined);\n if (!known) unknown.push({ key, files });\n }\n\n const needed = new Set<string>([...extracted.keys(), ...Object.keys(source)]);\n\n const missing: MissingEntry[] = [];\n for (const key of extracted.keys()) {\n if (!source[key]) {\n missing.push({ locale: cfg.sourceLocale, key, source: extracted.get(key)?.message });\n }\n }\n for (const locale of cfg.locales) {\n if (locale === cfg.sourceLocale) continue;\n for (const key of needed) {\n if (!catalogs[locale]?.[key]) {\n missing.push({ locale, key, source: source[key] ?? extracted.get(key)?.message });\n }\n }\n }\n\n return { ok: missing.length === 0 && unknown.length === 0, missing, unknown };\n}\n\nexport function formatCheckResult(result: CheckResult): string {\n const lines: string[] = [];\n if (result.missing.length > 0) {\n lines.push('missing translations:');\n for (const entry of result.missing) {\n const hint = entry.source ? ` — \"${truncate(entry.source, 40)}\"` : '';\n lines.push(` [${entry.locale}] ${entry.key}${hint}`);\n }\n }\n if (result.unknown.length > 0) {\n lines.push('unknown keys (not in any catalog):');\n for (const entry of result.unknown) {\n lines.push(` ${entry.key} — used in ${entry.files.join(', ')}`);\n }\n }\n return lines.join('\\n');\n}\n\nfunction truncate(text: string, max: number): string {\n return text.length > max ? text.slice(0, max - 1) + '…' : text;\n}\n","import { parse, type MessageNode } from 'verbaly';\n\nexport type ParamType = 'number' | 'string' | 'date' | 'unknown';\n\nconst PLURAL_KEYS = new Set(['zero', 'one', 'two', 'few', 'many']);\nconst NUMBER_FORMATS = new Set(['number', 'integer', 'percent', 'currency']);\nconst DATE_FORMATS = new Set(['date', 'time']);\n\nexport function collectParams(message: string): Map<string, Set<ParamType>> {\n const out = new Map<string, Set<ParamType>>();\n visit(parse(message), out);\n return out;\n}\n\nfunction visit(nodes: MessageNode[], out: Map<string, Set<ParamType>>): void {\n for (const node of nodes) {\n if (node.kind !== 'param') continue;\n const types = out.get(node.name) ?? new Set<ParamType>();\n out.set(node.name, types);\n\n if (node.variants) {\n for (const [key, body] of node.variants) {\n if (PLURAL_KEYS.has(key) || /^=\\d+$/.test(key)) types.add('number');\n else if (key !== 'other') types.add('string');\n visit(body, out);\n }\n if (types.size === 0) types.add('string');\n } else if (node.format && NUMBER_FORMATS.has(node.format)) {\n types.add('number');\n } else if (node.format && DATE_FORMATS.has(node.format)) {\n types.add('date');\n } else {\n types.add('unknown');\n }\n }\n}\n\nexport function renderParamType(types: Set<ParamType>): string {\n if (types.has('unknown') || types.size === 0) return 'unknown';\n const parts: string[] = [];\n if (types.has('number')) parts.push('number');\n if (types.has('string')) parts.push('string');\n if (types.has('date')) parts.push('Date | number | string');\n return parts.join(' | ');\n}\n","import { writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { Catalog } from './catalog';\nimport type { ResolvedConfig } from './config';\nimport { collectParams, renderParamType } from './params';\n\nexport const VIRTUAL_ID = 'virtual:verbaly';\n\nexport function generateRuntimeModule(cfg: ResolvedConfig): string {\n const others = cfg.locales.filter((locale) => locale !== cfg.sourceLocale);\n const src = JSON.stringify(cfg.sourceLocale);\n const loaders = others\n .map(\n (locale) => ` ${JSON.stringify(locale)}: () => import('${VIRTUAL_ID}/locale/${locale}'),`,\n )\n .join('\\n');\n\n return `import { createVerbaly } from 'verbaly';\nimport source from '${VIRTUAL_ID}/locale/${cfg.sourceLocale}';\n\nconst v = createVerbaly({\n locale: ${src},\n fallback: ${src},\n messages: { [${src}]: source },\n loaders: {\n${loaders}\n },\n});\n\nexport const verbaly = v;\nexport const t = v.t;\n\nexport function getLocale() {\n return v.locale;\n}\n\nexport function subscribe(listener) {\n return v.subscribe(listener);\n}\n\nexport async function setLocale(locale) {\n await v.loadLocale(locale);\n v.setLocale(locale);\n}\n`;\n}\n\nexport function generateLocaleModule(catalog: Catalog): string {\n return `export default ${JSON.stringify(catalog)};\\n`;\n}\n\nexport function generateDts(entries: Map<string, string>): string {\n const lines: string[] = [];\n for (const [key, message] of [...entries.entries()].sort(([a], [b]) => a.localeCompare(b))) {\n const params = collectParams(message);\n if (params.size === 0) {\n lines.push(` ${JSON.stringify(key)}: never;`);\n } else {\n const fields = [...params.entries()]\n .map(([name, types]) => `${JSON.stringify(name)}: ${renderParamType(types)}`)\n .join('; ');\n lines.push(` ${JSON.stringify(key)}: { ${fields} };`);\n }\n }\n\n return `// generated by verbaly — do not edit\ndeclare module 'virtual:verbaly' {\n export interface VerbalyMessages {\n${lines.join('\\n')}\n }\n export type VerbalyKey = keyof VerbalyMessages & string;\n\n export const verbaly: import('verbaly').Verbaly<VerbalyKey>;\n\n export function t<K extends VerbalyKey>(\n key: K,\n ...args: [VerbalyMessages[K]] extends [never] ? [] : [VerbalyMessages[K]]\n ): string;\n export function t(strings: TemplateStringsArray, ...values: unknown[]): string;\n export namespace t {\n export function id(\n key: string,\n ): (strings: TemplateStringsArray, ...values: unknown[]) => string;\n }\n\n export function setLocale(locale: string): Promise<void>;\n export function getLocale(): string;\n export function subscribe(listener: () => void): () => void;\n}\n\ndeclare module 'virtual:verbaly/locale/*' {\n const messages: Record<string, string>;\n export default messages;\n}\n`;\n}\n\nexport function writeDts(cfg: ResolvedConfig, entries: Map<string, string>): void {\n writeFileSync(join(cfg.root, 'verbaly.d.ts'), generateDts(entries));\n}\n","import { existsSync, readFileSync, readdirSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { RichLink } from 'verbaly';\nimport type { TranslateProvider } from './translate';\n\nexport interface TranslateConfig {\n provider?: 'claude' | TranslateProvider;\n model?: string;\n batchSize?: number;\n}\n\nexport interface RenderConfig {\n links?: Record<string, RichLink>;\n site?: string;\n attribute?: string;\n baseUrl?: string;\n hreflang?: boolean;\n sitemap?: boolean | string;\n clean?: boolean;\n}\n\nexport interface VerbalyConfig {\n root?: string;\n dir?: string;\n sourceLocale?: string;\n locales?: string[];\n include?: string[];\n exclude?: string[];\n translate?: TranslateConfig;\n render?: RenderConfig;\n}\n\nexport interface ResolvedConfig {\n root: string;\n dir: string;\n sourceLocale: string;\n locales: string[];\n include: string[];\n exclude: string[];\n translate: TranslateConfig;\n render: RenderConfig;\n}\n\nexport function resolveConfig(config: VerbalyConfig = {}): ResolvedConfig {\n const root = resolve(config.root ?? process.cwd());\n const dir = resolve(root, config.dir ?? 'locales');\n const sourceLocale = config.sourceLocale ?? 'en';\n\n const locales = new Set<string>([sourceLocale, ...(config.locales ?? [])]);\n if (existsSync(dir)) {\n for (const file of readdirSync(dir)) {\n if (file.endsWith('.json')) locales.add(file.slice(0, -5));\n }\n }\n\n return {\n root,\n dir,\n sourceLocale,\n locales: [...locales],\n include: config.include ?? ['src/**/*.{js,jsx,ts,tsx,mjs,mts}'],\n exclude: config.exclude ?? ['**/node_modules/**', '**/dist/**'],\n translate: config.translate ?? {},\n render: config.render ?? {},\n };\n}\n\nconst CONFIG_FILES = [\n 'verbaly.config.js',\n 'verbaly.config.mjs',\n 'verbaly.config.ts',\n 'verbaly.config.mts',\n 'verbaly.config.json',\n];\n\nexport function findConfigFile(root: string): string | undefined {\n return CONFIG_FILES.find((name) => existsSync(join(root, name)));\n}\n\nexport async function loadConfigFile(root: string): Promise<VerbalyConfig> {\n for (const name of ['verbaly.config.js', 'verbaly.config.mjs']) {\n const path = join(root, name);\n if (existsSync(path)) {\n const mod = (await import(pathToFileURL(path).href)) as { default?: VerbalyConfig };\n return mod.default ?? {};\n }\n }\n for (const name of ['verbaly.config.ts', 'verbaly.config.mts']) {\n const path = join(root, name);\n if (existsSync(path)) return loadTsConfig(path);\n }\n const jsonPath = join(root, 'verbaly.config.json');\n if (existsSync(jsonPath)) {\n return JSON.parse(readFileSync(jsonPath, 'utf8')) as VerbalyConfig;\n }\n return {};\n}\n\nasync function loadTsConfig(path: string): Promise<VerbalyConfig> {\n try {\n const { bundleRequire } = await import('bundle-require');\n const { mod } = await bundleRequire<{ default?: VerbalyConfig }>({ filepath: path });\n return mod.default ?? {};\n } catch (error) {\n if (isModuleNotFound(error, 'esbuild')) {\n throw new Error(`[verbaly] ${path} needs esbuild — install it: pnpm add -D esbuild`, {\n cause: error,\n });\n }\n throw error;\n }\n}\n\nfunction isModuleNotFound(error: unknown, name: string): boolean {\n return (\n error instanceof Error &&\n (error as { code?: string }).code === 'ERR_MODULE_NOT_FOUND' &&\n error.message.includes(name)\n );\n}\n\n// file config + inline overrides\nexport async function loadConfig(\n root: string,\n overrides: VerbalyConfig = {},\n): Promise<ResolvedConfig> {\n const fileConfig = await loadConfigFile(root);\n return resolveConfig({ ...fileConfig, ...definedOnly(overrides), root });\n}\n\nfunction definedOnly(config: VerbalyConfig): VerbalyConfig {\n return Object.fromEntries(\n Object.entries(config).filter(([, value]) => value !== undefined),\n ) as VerbalyConfig;\n}\n","import { createHash } from 'node:crypto';\n\nexport function stableKey(message: string): string {\n return createHash('sha256').update(message).digest('base64url').slice(0, 8);\n}\n","import { parse } from '@babel/parser';\nimport { stableKey } from './key';\n\nexport interface TaggedParam {\n name: string;\n start: number;\n end: number;\n}\n\nexport interface TransComponent {\n name: string;\n source: string;\n}\n\nexport interface TaggedMessage {\n key: string;\n message: string;\n params: TaggedParam[];\n start: number;\n end: number;\n tagStart: number;\n tagEnd: number;\n file: string;\n jsx?: { name: string; components: TransComponent[] };\n}\n\nexport interface UsedKey {\n key: string;\n file: string;\n}\n\nexport interface Analysis {\n tagged: TaggedMessage[];\n usedKeys: UsedKey[];\n}\n\ninterface AstNode {\n type: string;\n start: number;\n end: number;\n [key: string]: unknown;\n}\n\nconst SKIP_KEYS = new Set(['loc', 'leadingComments', 'trailingComments', 'innerComments', 'extra']);\n\nexport function analyze(code: string, file: string): Analysis {\n const jsx = /\\.[jt]sx$/.test(file);\n const ast = parse(code, {\n sourceType: 'module',\n errorRecovery: true,\n plugins: jsx ? ['typescript', 'jsx'] : ['typescript'],\n });\n\n const tagged: TaggedMessage[] = [];\n const usedKeys: UsedKey[] = [];\n\n walk(ast.program as unknown as AstNode, (node) => {\n if (node.type === 'TaggedTemplateExpression') {\n const tag = node.tag as AstNode;\n const explicit = explicitId(tag);\n if (!explicit && !isTReference(tag)) return;\n const quasi = node.quasi as AstNode;\n const message = buildMessage(code, quasi);\n if (!message) return;\n tagged.push({\n key: explicit ? explicit.key : stableKey(message.text),\n message: message.text,\n params: message.params,\n start: node.start,\n end: node.end,\n tagStart: explicit ? explicit.refStart : tag.start,\n tagEnd: explicit ? explicit.refEnd : tag.end,\n file,\n });\n } else if (node.type === 'CallExpression') {\n const callee = node.callee as AstNode;\n if (!isTReference(callee)) return;\n const args = node.arguments as AstNode[];\n const first = args[0];\n if (first?.type === 'StringLiteral') {\n usedKeys.push({ key: first.value as string, file });\n }\n } else if (node.type === 'JSXElement') {\n handleTrans(code, node, file, tagged, usedKeys);\n }\n });\n\n return { tagged, usedKeys };\n}\n\nfunction handleTrans(\n code: string,\n node: AstNode,\n file: string,\n tagged: TaggedMessage[],\n usedKeys: UsedKey[],\n): void {\n const opening = node.openingElement as AstNode;\n const nameNode = opening.name as AstNode;\n if (nameNode.type !== 'JSXIdentifier' || nameNode.name !== 'Trans') return;\n\n const attrs = opening.attributes as AstNode[];\n const idAttr = attrs.find((a) => a.type === 'JSXAttribute' && (a.name as AstNode).name === 'id');\n const children = node.children as AstNode[] | undefined;\n\n if (idAttr) {\n const value = idAttr.value as AstNode | null;\n if (value?.type !== 'StringLiteral') return;\n const id = value.value as string;\n // id + children → extract under the explicit key\n if (attrs.length === 1 && children?.length) {\n const built = buildTransMessage(code, children);\n if (built?.text.trim()) {\n tagged.push({\n key: id,\n message: built.text,\n params: built.params,\n start: node.start,\n end: node.end,\n tagStart: nameNode.start,\n tagEnd: nameNode.end,\n file,\n jsx: { name: nameNode.name as string, components: built.components },\n });\n return;\n }\n }\n usedKeys.push({ key: id, file });\n return; // runtime-first, untouched\n }\n if (attrs.length > 0) return; // hand-written props → don't guess\n\n if (!children?.length) return;\n\n const built = buildTransMessage(code, children);\n if (!built || !built.text.trim()) return;\n\n tagged.push({\n key: stableKey(built.text),\n message: built.text,\n params: built.params,\n start: node.start,\n end: node.end,\n tagStart: nameNode.start,\n tagEnd: nameNode.end,\n file,\n jsx: { name: nameNode.name as string, components: built.components },\n });\n}\n\n// t.id('key')`…` → explicit readable key\nfunction explicitId(tag: AstNode): { key: string; refStart: number; refEnd: number } | undefined {\n if (tag.type !== 'CallExpression') return undefined;\n const callee = tag.callee as AstNode;\n if (callee.type !== 'MemberExpression' || callee.computed) return undefined;\n const prop = callee.property as AstNode;\n if (prop.type !== 'Identifier' || prop.name !== 'id') return undefined;\n const obj = callee.object as AstNode;\n if (!isTReference(obj)) return undefined;\n const args = tag.arguments as AstNode[];\n const first = args[0];\n if (args.length !== 1 || first?.type !== 'StringLiteral') return undefined;\n return { key: first.value as string, refStart: obj.start, refEnd: obj.end };\n}\n\ninterface BuiltTrans {\n text: string;\n params: TaggedParam[];\n components: TransComponent[];\n}\n\nfunction buildTransMessage(code: string, children: AstNode[]): BuiltTrans | undefined {\n const params: TaggedParam[] = [];\n const components: TransComponent[] = [];\n const takenParams = new Map<string, string>();\n const takenTags = new Map<string, string>();\n\n function walkChildren(nodes: AstNode[]): string | undefined {\n let text = '';\n for (const child of nodes) {\n if (child.type === 'JSXText') {\n text += escapeText(cleanJsxText(child.value as string));\n } else if (child.type === 'JSXExpressionContainer') {\n const expr = child.expression as AstNode;\n if (expr.type === 'JSXEmptyExpression') continue;\n if (expr.type === 'StringLiteral') {\n text += escapeText(expr.value as string);\n continue;\n }\n if (expr.type === 'TaggedTemplateExpression') return undefined; // overlap hazard\n const source = code.slice(expr.start, expr.end);\n const name = uniqueName(deriveName(expr, params.length), source, takenParams);\n params.push({ name, start: expr.start, end: expr.end });\n text += `{${name}}`;\n } else if (child.type === 'JSXElement') {\n const opening = child.openingElement as AstNode;\n const nameNode = opening.name as AstNode;\n if (nameNode.type !== 'JSXIdentifier' || nameNode.name === 'Trans') return undefined;\n const source = selfClosedSource(code, opening);\n const tag = uniqueName((nameNode.name as string).toLowerCase(), source, takenTags);\n if (!components.some((c) => c.name === tag)) components.push({ name: tag, source });\n if (!child.closingElement) {\n text += `<${tag}/>`;\n } else {\n const inner = walkChildren(child.children as AstNode[]);\n if (inner === undefined) return undefined;\n text += `<${tag}>${inner}</${tag}>`;\n }\n } else {\n return undefined; // fragments / spread children → bail\n }\n }\n return text;\n }\n\n const text = walkChildren(children);\n if (text === undefined) return undefined;\n return { text, params, components };\n}\n\n// JSX text semantics: newline-indent boundaries removed, interior joins = one space\nfunction cleanJsxText(raw: string): string {\n const lines = raw.split(/\\r\\n|[\\r\\n]/);\n let out = '';\n for (let i = 0; i < lines.length; i++) {\n let line = lines[i]!.replace(/\\t/g, ' ');\n if (i !== 0) line = line.replace(/^ +/, '');\n if (i !== lines.length - 1) line = line.replace(/ +$/, '');\n if (!line) continue;\n if (out && i !== 0) out += ' ';\n out += line;\n }\n return out;\n}\n\nfunction selfClosedSource(code: string, opening: AstNode): string {\n const src = code.slice(opening.start, opening.end);\n return src.endsWith('/>') ? src : `${src.slice(0, -1).trimEnd()} />`;\n}\n\nfunction isTReference(node: AstNode): boolean {\n if (node.type === 'Identifier') return node.name === 't';\n if (node.type === 'MemberExpression' && !node.computed) {\n const prop = node.property as AstNode;\n return prop.type === 'Identifier' && prop.name === 't';\n }\n return false;\n}\n\ninterface BuiltMessage {\n text: string;\n params: TaggedParam[];\n}\n\nfunction buildMessage(code: string, quasi: AstNode): BuiltMessage | undefined {\n const quasis = quasi.quasis as AstNode[];\n const expressions = quasi.expressions as AstNode[];\n const params: TaggedParam[] = [];\n const taken = new Map<string, string>();\n\n let text = escapeText(cookedValue(quasis[0]));\n\n for (let i = 0; i < expressions.length; i++) {\n const expr = expressions[i];\n if (!expr) return undefined;\n const source = code.slice(expr.start, expr.end);\n const name = uniqueName(deriveName(expr, i), source, taken);\n params.push({ name, start: expr.start, end: expr.end });\n text += `{${name}}` + escapeText(cookedValue(quasis[i + 1]));\n }\n return { text, params };\n}\n\nfunction cookedValue(element: AstNode | undefined): string {\n if (!element) return '';\n const value = element.value as { cooked?: string; raw: string };\n return value.cooked ?? value.raw;\n}\n\n// literal braces → escaped\nfunction escapeText(text: string): string {\n return text.replace(/[{}]/g, (m) => m + m);\n}\n\nfunction deriveName(expr: AstNode, index: number): string {\n if (expr.type === 'Identifier') return expr.name as string;\n if (expr.type === 'MemberExpression' && !expr.computed) {\n const prop = expr.property as AstNode;\n if (prop.type === 'Identifier') return prop.name as string;\n }\n return `_${index}`;\n}\n\nfunction uniqueName(base: string, source: string, taken: Map<string, string>): string {\n let name = base;\n let n = 2;\n while (taken.has(name) && taken.get(name) !== source) {\n name = `${base}${n}`;\n n += 1;\n }\n taken.set(name, source);\n return name;\n}\n\nfunction walk(node: AstNode, visit: (node: AstNode) => void): void {\n visit(node);\n for (const [key, value] of Object.entries(node)) {\n if (SKIP_KEYS.has(key)) continue;\n if (Array.isArray(value)) {\n for (const item of value) {\n if (isNode(item)) walk(item, visit);\n }\n } else if (isNode(value)) {\n walk(value, visit);\n }\n }\n}\n\nfunction isNode(value: unknown): value is AstNode {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as { type?: unknown }).type === 'string'\n );\n}\n","import type { Analysis, TaggedMessage } from './analyze';\n\nexport class MessageRegistry {\n private files = new Map<string, Analysis>();\n\n update(file: string, analysis: Analysis): void {\n this.files.set(file, analysis);\n }\n\n remove(file: string): void {\n this.files.delete(file);\n }\n\n messages(): Map<string, TaggedMessage> {\n const out = new Map<string, TaggedMessage>();\n for (const analysis of this.files.values()) {\n for (const msg of analysis.tagged) {\n const existing = out.get(msg.key);\n if (existing) {\n if (existing.message !== msg.message) {\n console.warn(\n `[verbaly] key collision \"${msg.key}\": ` +\n `${JSON.stringify(existing.message)} vs ${JSON.stringify(msg.message)} — second dropped.`,\n );\n }\n continue;\n }\n out.set(msg.key, msg);\n }\n }\n return out;\n }\n\n usedKeys(): Map<string, string[]> {\n const out = new Map<string, string[]>();\n for (const analysis of this.files.values()) {\n for (const used of analysis.usedKeys) {\n const files = out.get(used.key) ?? [];\n if (!files.includes(used.file)) files.push(used.file);\n out.set(used.key, files);\n }\n }\n return out;\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { glob } from 'tinyglobby';\nimport { analyze } from './analyze';\nimport type { Catalogs } from './catalog';\nimport type { ResolvedConfig } from './config';\nimport { MessageRegistry } from './registry';\n\nexport async function extractProject(cfg: ResolvedConfig): Promise<MessageRegistry> {\n const files = await glob(cfg.include, {\n cwd: cfg.root,\n ignore: cfg.exclude,\n absolute: true,\n });\n const registry = new MessageRegistry();\n for (const file of files) {\n registry.update(file, analyze(readFileSync(file, 'utf8'), file));\n }\n return registry;\n}\n\nexport interface SyncResult {\n added: Record<string, string[]>;\n}\n\n// fills source texts + '' placeholders\nexport function syncCatalogs(\n cfg: ResolvedConfig,\n catalogs: Catalogs,\n registry: MessageRegistry,\n): SyncResult {\n const added: Record<string, string[]> = {};\n const source = (catalogs[cfg.sourceLocale] ??= {});\n\n for (const [key, msg] of registry.messages()) {\n if (source[key] !== msg.message) {\n source[key] = msg.message;\n (added[cfg.sourceLocale] ??= []).push(key);\n }\n }\n\n const needed = Object.keys(source);\n for (const locale of cfg.locales) {\n if (locale === cfg.sourceLocale) continue;\n const catalog = (catalogs[locale] ??= {});\n for (const key of needed) {\n if (catalog[key] === undefined) {\n catalog[key] = '';\n (added[locale] ??= []).push(key);\n }\n }\n }\n return { added };\n}\n\n// drops keys no longer referenced\nexport function pruneCatalogs(\n cfg: ResolvedConfig,\n catalogs: Catalogs,\n registry: MessageRegistry,\n): Record<string, string[]> {\n const keep = new Set([...registry.messages().keys(), ...registry.usedKeys().keys()]);\n const removed: Record<string, string[]> = {};\n for (const locale of cfg.locales) {\n const catalog = catalogs[locale];\n if (!catalog) continue;\n for (const key of Object.keys(catalog)) {\n if (!keep.has(key)) {\n delete catalog[key];\n (removed[locale] ??= []).push(key);\n }\n }\n }\n return removed;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join, relative } from 'node:path';\nimport { findConfigFile } from './config';\n\nexport interface InitOptions {\n root?: string;\n dir?: string;\n sourceLocale?: string;\n locales?: string[];\n}\n\nexport interface InitResult {\n created: string[];\n skipped: string[];\n bundler: 'vite' | 'webpack' | 'rollup' | 'rspack' | 'esbuild' | undefined;\n configFile: string;\n next: string[];\n}\n\nconst BUNDLERS = ['vite', 'webpack', 'rollup', 'rspack', 'esbuild'] as const;\n\nexport function detectBundler(root: string): InitResult['bundler'] {\n const path = join(root, 'package.json');\n if (!existsSync(path)) return undefined;\n try {\n const pkg = JSON.parse(readFileSync(path, 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return BUNDLERS.find((name) => deps[name]);\n } catch {\n return undefined;\n }\n}\n\nfunction configSource(options: InitOptions, typescript: boolean): string {\n const fields = [` sourceLocale: '${options.sourceLocale ?? 'en'}',`];\n if (options.locales?.length) {\n fields.push(` locales: [${options.locales.map((l) => `'${l}'`).join(', ')}],`);\n }\n if (options.dir) fields.push(` dir: '${options.dir}',`);\n const body = `export default {\\n${fields.join('\\n')}\\n}`;\n if (typescript) {\n return `import type { VerbalyConfig } from '@verbaly/compiler';\\n\\n${body} satisfies VerbalyConfig;\\n`;\n }\n return `/** @type {import('@verbaly/compiler').VerbalyConfig} */\\n${body};\\n`;\n}\n\nexport function init(options: InitOptions = {}): InitResult {\n const root = options.root ?? process.cwd();\n const created: string[] = [];\n const skipped: string[] = [];\n\n const existing = findConfigFile(root);\n const typescript = existsSync(join(root, 'tsconfig.json'));\n const configFile = existing ?? (typescript ? 'verbaly.config.ts' : 'verbaly.config.mjs');\n if (existing) {\n skipped.push(existing);\n } else {\n writeFileSync(join(root, configFile), configSource(options, typescript));\n created.push(configFile);\n }\n\n const dir = join(root, options.dir ?? 'locales');\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n for (const locale of new Set([options.sourceLocale ?? 'en', ...(options.locales ?? [])])) {\n const file = join(dir, `${locale}.json`);\n const label = relative(root, file).replaceAll('\\\\', '/');\n if (existsSync(file)) {\n skipped.push(label);\n } else {\n writeFileSync(file, '{}\\n');\n created.push(label);\n }\n }\n\n const bundler = detectBundler(root);\n const next: string[] = [];\n if (bundler === 'vite') {\n next.push(\n 'install the plugin: pnpm add -D @verbaly/vite',\n 'add verbaly() to the plugins in vite.config',\n );\n } else if (bundler) {\n next.push(\n 'install the plugin: pnpm add -D @verbaly/unplugin',\n `add the verbaly ${bundler} plugin to your build config`,\n );\n } else {\n next.push('run \"verbaly extract\" after writing your first t`…` message');\n }\n\n return { created, skipped, bundler, configFile, next };\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join, relative } from 'node:path';\nimport type { Catalogs } from './catalog';\nimport { check } from './check';\nimport { generateDts } from './codegen';\nimport { findConfigFile, type ResolvedConfig } from './config';\nimport { extractProject } from './extract';\nimport { detectBundler } from './init';\n\nexport interface DoctorEntry {\n level: 'ok' | 'warn' | 'error';\n check: string;\n message: string;\n fix?: string;\n}\n\nexport interface DoctorResult {\n ok: boolean; // no error-level entries (warns allowed)\n entries: DoctorEntry[];\n}\n\nconst PREVIEW = 5; // keys shown before \"…\"\n\nexport async function doctor(cfg: ResolvedConfig): Promise<DoctorResult> {\n const entries: DoctorEntry[] = [];\n const ok = (check: string, message: string) => entries.push({ level: 'ok', check, message });\n const warn = (check: string, message: string, fix: string) =>\n entries.push({ level: 'warn', check, message, fix });\n const error = (check: string, message: string, fix: string) =>\n entries.push({ level: 'error', check, message, fix });\n const rel = (path: string) => relative(cfg.root, path).replaceAll('\\\\', '/');\n\n const configFile = findConfigFile(cfg.root);\n if (configFile) ok('config', `${configFile} found`);\n else warn('config', 'no config file — running on defaults', 'run `npx verbaly init`');\n\n const catalogs: Catalogs = {};\n let catalogsHealthy = true;\n if (!existsSync(cfg.dir)) {\n catalogsHealthy = false;\n error(\n 'catalogs',\n `catalogs directory ${rel(cfg.dir)}/ does not exist`,\n 'run `npx verbaly init` to scaffold it',\n );\n } else {\n for (const locale of cfg.locales) {\n const file = join(cfg.dir, `${locale}.json`);\n if (!existsSync(file)) {\n catalogsHealthy = false;\n error(\n `locale ${locale}`,\n `${rel(file)} is missing`,\n 'run `npx verbaly extract` to create it',\n );\n continue;\n }\n try {\n const parsed = JSON.parse(readFileSync(file, 'utf8')) as Record<string, unknown>;\n const bad = Object.entries(parsed).find(([, value]) => typeof value !== 'string');\n if (bad) {\n catalogsHealthy = false;\n error(\n `locale ${locale}`,\n `${rel(file)} has a non-string value at \"${bad[0]}\"`,\n 'catalogs are flat key → string JSON; fix the value',\n );\n } else {\n catalogs[locale] = parsed as Record<string, string>;\n }\n } catch {\n catalogsHealthy = false;\n error(\n `locale ${locale}`,\n `${rel(file)} is not valid JSON`,\n 'repair the file (or delete it and run `npx verbaly extract`)',\n );\n }\n }\n if (catalogsHealthy) {\n ok(\n 'catalogs',\n `${cfg.locales.length} locales (${cfg.locales.join(', ')}) in ${rel(cfg.dir)}/`,\n );\n }\n }\n\n const source = catalogs[cfg.sourceLocale];\n if (source && Object.keys(source).length === 0) {\n warn(\n 'source',\n `source catalog ${cfg.sourceLocale}.json is empty`,\n 'write your first t`…` message and run `npx verbaly extract`',\n );\n }\n\n const deps = readDeps(cfg.root);\n const bundler = detectBundler(cfg.root);\n const wired = deps['@verbaly/vite'] || deps['@verbaly/unplugin'];\n if (!bundler) {\n ok('plugin', 'no bundler detected — CLI flow (extract/check) applies');\n } else if (wired) {\n ok(\n 'plugin',\n `${deps['@verbaly/vite'] ? '@verbaly/vite' : '@verbaly/unplugin'} installed for ${bundler}`,\n );\n } else if (bundler === 'vite') {\n warn(\n 'plugin',\n 'vite detected but @verbaly/vite is not installed',\n 'pnpm add -D @verbaly/vite and add verbaly() to the plugins in vite.config',\n );\n } else {\n warn(\n 'plugin',\n `${bundler} detected but @verbaly/unplugin is not installed`,\n `pnpm add -D @verbaly/unplugin and add the verbaly ${bundler} plugin to your build config`,\n );\n }\n\n if (source) {\n const dtsPath = join(cfg.root, 'verbaly.d.ts');\n if (!existsSync(dtsPath)) {\n warn('types', 'verbaly.d.ts has not been generated', 'run `npx verbaly extract`');\n } else if (readFileSync(dtsPath, 'utf8') !== generateDts(new Map(Object.entries(source)))) {\n warn('types', 'verbaly.d.ts is stale', 'run `npx verbaly extract`');\n } else {\n ok('types', 'verbaly.d.ts is up to date');\n }\n }\n\n const registry = await extractProject(cfg);\n if (source) {\n const extracted = registry.messages();\n const used = registry.usedKeys();\n const orphans = Object.keys(source).filter((key) => !extracted.has(key) && !used.has(key));\n if (orphans.length > 0) {\n warn(\n 'orphans',\n `${orphans.length} catalog ${orphans.length === 1 ? 'key is' : 'keys are'} no longer referenced (${preview(orphans)})`,\n 'run `npx verbaly extract --prune` to drop them',\n );\n } else {\n ok('orphans', 'no orphan keys');\n }\n }\n\n if (catalogsHealthy) {\n const result = check(cfg, catalogs, registry);\n if (result.unknown.length > 0) {\n error(\n 'keys',\n `${result.unknown.length} unknown ${result.unknown.length === 1 ? 'key' : 'keys'} used in code (${preview(result.unknown.map((u) => u.key))})`,\n 'fix the key or add it to the catalogs — `npx verbaly check` for details',\n );\n }\n if (result.missing.length > 0) {\n const locales = [...new Set(result.missing.map((m) => m.locale))];\n warn(\n 'translations',\n `${result.missing.length} missing ${result.missing.length === 1 ? 'translation' : 'translations'} (${locales.join(', ')})`,\n 'run `npx verbaly translate` or fill the catalogs — `npx verbaly check` for details',\n );\n }\n if (result.ok) ok('translations', 'all translations complete');\n }\n\n return { ok: entries.every((entry) => entry.level !== 'error'), entries };\n}\n\nfunction preview(keys: string[]): string {\n const head = keys.slice(0, PREVIEW).join(', ');\n return keys.length > PREVIEW ? `${head}, …` : head;\n}\n\nfunction readDeps(root: string): Record<string, string> {\n try {\n const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n return { ...pkg.dependencies, ...pkg.devDependencies };\n } catch {\n return {};\n }\n}\n","import type { Catalog, Catalogs } from './catalog';\nimport type { ResolvedConfig } from './config';\n\nexport const PSEUDO_LOCALE = 'en-XA';\n\nconst ACCENTS: Record<string, string> = {\n a: 'á',\n b: 'ƀ',\n c: 'ç',\n d: 'đ',\n e: 'é',\n f: 'ƒ',\n g: 'ğ',\n h: 'ĥ',\n i: 'í',\n j: 'ĵ',\n k: 'ķ',\n l: 'ĺ',\n m: 'ɱ',\n n: 'ñ',\n o: 'ó',\n p: 'þ',\n q: 'ǫ',\n r: 'ŕ',\n s: 'š',\n t: 'ţ',\n u: 'ú',\n v: 'ṽ',\n w: 'ŵ',\n x: 'ẋ',\n y: 'ý',\n z: 'ž',\n A: 'Á',\n B: 'Ɓ',\n C: 'Ç',\n D: 'Đ',\n E: 'É',\n F: 'Ƒ',\n G: 'Ğ',\n H: 'Ĥ',\n I: 'Í',\n J: 'Ĵ',\n K: 'Ķ',\n L: 'Ĺ',\n M: 'Ḿ',\n N: 'Ñ',\n O: 'Ó',\n P: 'Þ',\n Q: 'Ǫ',\n R: 'Ŕ',\n S: 'Š',\n T: 'Ţ',\n U: 'Ú',\n V: 'Ṽ',\n W: 'Ŵ',\n X: 'Ẍ',\n Y: 'Ý',\n Z: 'Ž',\n};\n\nconst TAG_AT = /<\\/?[a-zA-Z][\\w-]*\\/?>/y;\n\n// params, variant blocks, tags and escapes survive verbatim\nexport function pseudoLocalize(message: string): string {\n let out = '';\n let letters = 0;\n let i = 0;\n while (i < message.length) {\n const two = message.slice(i, i + 2);\n if (two === '{{' || two === '}}' || two === '||' || two === '##') {\n out += two;\n i += 2;\n continue;\n }\n const ch = message[i]!;\n if (ch === '{') {\n const end = matchBrace(message, i);\n out += message.slice(i, end);\n i = end;\n continue;\n }\n if (ch === '<') {\n TAG_AT.lastIndex = i;\n const m = TAG_AT.exec(message);\n if (m) {\n out += m[0];\n i += m[0].length;\n continue;\n }\n }\n const mapped = ACCENTS[ch];\n if (mapped) {\n out += mapped;\n letters += 1;\n } else {\n out += ch;\n }\n i += 1;\n }\n const pad = '~'.repeat(Math.ceil(letters / 3));\n return `⟦${out}${pad ? ' ' + pad : ''}⟧`;\n}\n\nfunction matchBrace(message: string, start: number): number {\n let depth = 0;\n for (let i = start; i < message.length; i++) {\n const two = message.slice(i, i + 2);\n if (two === '{{' || two === '}}') {\n i += 1;\n continue;\n }\n const ch = message[i];\n if (ch === '{') depth += 1;\n else if (ch === '}') {\n depth -= 1;\n if (depth === 0) return i + 1;\n }\n }\n return message.length; // unbalanced → verbatim\n}\n\n// regenerates the whole pseudo catalog from the source catalog\nexport function pseudoCatalogs(\n cfg: ResolvedConfig,\n catalogs: Catalogs,\n locale: string = PSEUDO_LOCALE,\n): string[] {\n const source = catalogs[cfg.sourceLocale] ?? {};\n const target: Catalog = {};\n for (const [key, msg] of Object.entries(source)) {\n target[key] = msg ? pseudoLocalize(msg) : '';\n }\n catalogs[locale] = target;\n return Object.keys(target).filter((key) => target[key]);\n}\n","import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { dirname, join, relative } from 'node:path';\nimport MagicString from 'magic-string';\nimport { glob } from 'tinyglobby';\nimport {\n createVerbaly,\n parseTags,\n RICH_TAGS,\n safeHref,\n type MessageTree,\n type Params,\n type RichLink,\n type TagNode,\n} from 'verbaly';\nimport type { Catalogs } from './catalog';\nimport { loadCatalogs } from './catalog';\nimport type { ResolvedConfig } from './config';\n\nexport interface Alternate {\n hreflang: string;\n href: string;\n}\n\nexport interface RenderHtmlOptions {\n locale: string;\n // nested trees welcome — the runtime flattens them (verbaly-web's shape)\n catalogs: Catalogs | Record<string, MessageTree>;\n sourceLocale?: string;\n attribute?: string;\n richTags?: string[];\n richLinks?: Record<string, RichLink>;\n setLang?: boolean;\n alternates?: Alternate[];\n}\n\nexport interface RenderHtmlResult {\n html: string;\n missing: string[];\n}\n\nconst HREFLANG_OPEN = '<!--verbaly:hreflang-->';\nconst HREFLANG_CLOSE = '<!--/verbaly:hreflang-->';\n\nconst VOID_TAGS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n]);\n\nconst START_TAG = /<([a-zA-Z][a-zA-Z0-9-]*)((?:\"[^\"]*\"|'[^']*'|[^\"'>])*)>/g;\nconst ATTR = /([^\\s=/\"'<>]+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]+)))?/g;\n\n// pre-fills data-verbaly elements for one locale; the runtime stays functional\nexport function renderHtml(html: string, options: RenderHtmlOptions): RenderHtmlResult {\n const attr = options.attribute ?? 'data-verbaly';\n const argsAttr = `${attr}-args`;\n const attrsAttr = `${attr}-attr`;\n const richAttr = `${attr}-rich`;\n const linksAttr = `${attr}-links`;\n const richTags = new Set(options.richTags ?? RICH_TAGS);\n const globalLinks = options.richLinks;\n const sourceLocale = options.sourceLocale ?? 'en';\n\n // '' = untranslated — the runtime lookup falls back on its own (nested or flat)\n const v = createVerbaly({\n locale: options.locale,\n fallback: sourceLocale,\n messages: options.catalogs,\n });\n const t = v.t as unknown as (key: string, params?: Params) => string;\n\n const ms = new MagicString(html);\n const missing = new Set<string>();\n const skip = protectedRanges(html);\n const inSkip = (index: number): boolean => skip.some(([from, to]) => index >= from && index < to);\n\n // per-locale canonical/og:url — a cross-locale canonical would void the hreflang set\n const selfUrl = options.alternates?.find((a) => a.hreflang === options.locale)?.href;\n const sourceUrl = options.alternates?.find((a) => a.hreflang === 'x-default')?.href;\n const rewriteUrl = selfUrl !== undefined && selfUrl !== sourceUrl;\n\n START_TAG.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = START_TAG.exec(html)) !== null) {\n if (inSkip(m.index)) continue;\n const [full, rawName, attrChunk] = m as unknown as [string, string, string];\n const tagName = rawName.toLowerCase();\n const openEnd = m.index + full.length;\n\n const chunkStart = m.index + 1 + rawName.length;\n\n if (tagName === 'html' && options.setLang !== false) {\n setAttribute(ms, html, chunkStart, openEnd, attrChunk, 'lang', options.locale);\n continue;\n }\n\n const attrs = parseAttrs(attrChunk);\n\n if (\n rewriteUrl &&\n tagName === 'link' &&\n attrs.get('rel')?.toLowerCase() === 'canonical' &&\n decodeEntities(attrs.get('href') ?? '') === sourceUrl\n ) {\n setAttribute(ms, html, chunkStart, openEnd, attrChunk, 'href', selfUrl!);\n }\n if (\n rewriteUrl &&\n tagName === 'meta' &&\n attrs.get('property') === 'og:url' &&\n decodeEntities(attrs.get('content') ?? '') === sourceUrl\n ) {\n setAttribute(ms, html, chunkStart, openEnd, attrChunk, 'content', selfUrl!);\n }\n\n const key = attrs.get(attr);\n const attrMapRaw = attrs.get(attrsAttr);\n if (key === undefined && attrMapRaw === undefined) continue;\n\n const args = parseArgs(attrs.get(argsAttr));\n\n if (key) {\n if (!v.has(key)) {\n missing.add(key);\n } else if (!VOID_TAGS.has(tagName) && !attrChunk.trimEnd().endsWith('/')) {\n const close = findClose(html, tagName, openEnd, inSkip);\n if (close) {\n const text = t(key, args);\n const own = parseArgs(attrs.get(linksAttr)) as Record<string, RichLink> | undefined;\n const links = own ? (globalLinks ? { ...globalLinks, ...own } : own) : globalLinks;\n const content = attrs.has(richAttr)\n ? richToHtml(parseTags(text), richTags, links)\n : escapeHtml(text);\n if (html.slice(openEnd, close.contentEnd) !== content) {\n if (openEnd === close.contentEnd) ms.appendLeft(openEnd, content);\n else ms.overwrite(openEnd, close.contentEnd, content);\n }\n }\n }\n }\n\n if (attrMapRaw !== undefined) {\n const map = parseArgs(attrMapRaw);\n if (map) {\n for (const [name, attrKey] of Object.entries(map)) {\n if (typeof attrKey !== 'string' || name.toLowerCase().startsWith('on')) continue;\n if (!v.has(attrKey)) {\n missing.add(attrKey);\n continue;\n }\n setAttribute(ms, html, chunkStart, openEnd, attrChunk, name, t(attrKey, args));\n }\n }\n }\n }\n\n if (options.alternates?.length) injectAlternates(ms, html, options.alternates);\n\n return { html: ms.toString(), missing: [...missing] };\n}\n\n// injects <link rel=\"alternate\" hreflang> into <head>, idempotent via markers\nfunction injectAlternates(ms: MagicString, html: string, alternates: Alternate[]): void {\n const links = alternates\n .map((a) => `<link rel=\"alternate\" hreflang=\"${escapeAttr(a.hreflang)}\" href=\"${escapeAttr(a.href)}\">`)\n .join('');\n const block = `${HREFLANG_OPEN}${links}${HREFLANG_CLOSE}`;\n const from = html.indexOf(HREFLANG_OPEN);\n if (from !== -1) {\n const to = html.indexOf(HREFLANG_CLOSE, from);\n if (to !== -1) {\n const end = to + HREFLANG_CLOSE.length;\n if (html.slice(from, end) !== block) ms.overwrite(from, end, block);\n return;\n }\n }\n const head = /<\\/head\\s*>/i.exec(html);\n if (head) ms.appendLeft(head.index, block);\n}\n\nexport interface RenderSiteOptions {\n site?: string;\n locales?: string[];\n attribute?: string;\n richTags?: string[];\n richLinks?: Record<string, RichLink>;\n baseUrl?: string;\n hreflang?: boolean;\n sitemap?: boolean | string;\n clean?: boolean;\n}\n\nexport interface RenderSiteResult {\n files: number;\n locales: string[];\n missing: Record<string, string[]>;\n}\n\n// mirrors the built site per locale: dist/index.html → dist/<locale>/index.html\nexport async function renderSite(\n cfg: ResolvedConfig,\n options: RenderSiteOptions = {},\n): Promise<RenderSiteResult> {\n const site = join(cfg.root, options.site ?? cfg.render.site ?? 'dist');\n const locales = options.locales ?? cfg.locales;\n const attribute = options.attribute ?? cfg.render.attribute;\n const baseUrl = (options.baseUrl ?? cfg.render.baseUrl)?.replace(/\\/+$/, '');\n const wantHreflang = (options.hreflang ?? cfg.render.hreflang ?? true) && baseUrl !== undefined;\n const wantSitemap = (options.sitemap ?? cfg.render.sitemap ?? false) && baseUrl !== undefined;\n const clean = options.clean ?? cfg.render.clean ?? false;\n const catalogs = loadCatalogs(cfg);\n\n if (clean) {\n for (const locale of locales) {\n if (locale !== cfg.sourceLocale) rmSync(join(site, locale), { recursive: true, force: true });\n }\n }\n\n const files = await glob('**/*.html', {\n cwd: site,\n absolute: true,\n ignore: locales.map((locale) => `${locale}/**`),\n });\n\n const missing: Record<string, string[]> = {};\n const urls: Array<{ rel: string; alternates: Alternate[] }> = [];\n for (const file of files) {\n const html = readFileSync(file, 'utf8');\n const rel = relative(site, file).replace(/\\\\/g, '/');\n const alternates = wantHreflang ? pageAlternates(baseUrl!, rel, locales, cfg.sourceLocale) : [];\n if (wantHreflang) urls.push({ rel, alternates });\n for (const locale of locales) {\n const result = renderHtml(html, {\n locale,\n catalogs,\n sourceLocale: cfg.sourceLocale,\n attribute,\n richTags: options.richTags,\n richLinks: options.richLinks ?? cfg.render.links,\n alternates,\n });\n for (const key of result.missing) {\n const list = (missing[locale] ??= []);\n if (!list.includes(key)) list.push(key);\n }\n const out = locale === cfg.sourceLocale ? file : join(site, locale, rel);\n mkdirSync(dirname(out), { recursive: true });\n writeFileSync(out, result.html);\n }\n }\n\n if (wantSitemap && urls.length) {\n const name = typeof wantSitemap === 'string' ? wantSitemap : 'sitemap-i18n.xml';\n writeFileSync(join(site, name), buildSitemap(urls));\n }\n\n return { files: files.length, locales: [...locales], missing };\n}\n\n// public URL of a built page path (index.html → directory URL)\nfunction pageUrl(baseUrl: string, prefix: string, rel: string): string {\n const path = rel.replace(/(^|\\/)index\\.html$/, '$1');\n return `${baseUrl}${prefix}${path ? `/${path}` : '/'}`;\n}\n\n// reciprocal hreflang set for one page across every locale (+ x-default = source)\nfunction pageAlternates(\n baseUrl: string,\n rel: string,\n locales: string[],\n sourceLocale: string,\n): Alternate[] {\n const alternates: Alternate[] = [];\n for (const locale of locales) {\n const prefix = locale === sourceLocale ? '' : `/${locale}`;\n alternates.push({ hreflang: locale, href: pageUrl(baseUrl, prefix, rel) });\n }\n alternates.push({ hreflang: 'x-default', href: pageUrl(baseUrl, '', rel) });\n return alternates;\n}\n\nfunction buildSitemap(urls: Array<{ rel: string; alternates: Alternate[] }>): string {\n const body = urls\n .flatMap(({ alternates }) => {\n const alts = alternates\n .map(\n (a) =>\n `<xhtml:link rel=\"alternate\" hreflang=\"${a.hreflang}\" href=\"${escapeAttr(a.href)}\"/>`,\n )\n .join('');\n return alternates\n .filter((a) => a.hreflang !== 'x-default')\n .map((self) => `<url><loc>${escapeAttr(self.href)}</loc>${alts}</url>`);\n })\n .join('');\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">${body}</urlset>\\n`;\n}\n\nfunction parseAttrs(chunk: string): Map<string, string> {\n const attrs = new Map<string, string>();\n ATTR.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = ATTR.exec(chunk)) !== null) {\n attrs.set(m[1]!.toLowerCase(), m[2] ?? m[3] ?? m[4] ?? '');\n }\n return attrs;\n}\n\nfunction parseArgs(raw: string | undefined): Params | undefined {\n if (!raw) return undefined;\n try {\n return JSON.parse(decodeEntities(raw)) as Params;\n } catch {\n console.warn(`[verbaly] invalid args JSON: ${raw}`);\n return undefined;\n }\n}\n\n// comments and script/style bodies are opaque to the scanner\nfunction protectedRanges(html: string): Array<[number, number]> {\n const ranges: Array<[number, number]> = [];\n const re = /<!--[\\s\\S]*?-->|<script\\b[\\s\\S]*?<\\/script\\s*>|<style\\b[\\s\\S]*?<\\/style\\s*>/gi;\n let m: RegExpExecArray | null;\n while ((m = re.exec(html)) !== null) {\n // keep script/style open tags scannable; protect only their bodies\n const openEnd = m[0].startsWith('<!--') ? m.index : html.indexOf('>', m.index) + 1;\n ranges.push([openEnd, m.index + m[0].length]);\n }\n return ranges;\n}\n\nfunction findClose(\n html: string,\n tagName: string,\n from: number,\n inSkip: (index: number) => boolean,\n): { contentEnd: number } | null {\n const re = new RegExp(\n `<${tagName}(?=[\\\\s/>])(?:\"[^\"]*\"|'[^']*'|[^\"'>])*>|</${tagName}\\\\s*>`,\n 'gi',\n );\n re.lastIndex = from;\n let depth = 1;\n let m: RegExpExecArray | null;\n while ((m = re.exec(html)) !== null) {\n if (inSkip(m.index)) continue;\n if (m[0][1] === '/') {\n depth -= 1;\n if (depth === 0) return { contentEnd: m.index };\n } else if (!m[0].endsWith('/>')) {\n depth += 1;\n }\n }\n return null;\n}\n\nfunction setAttribute(\n ms: MagicString,\n html: string,\n chunkStart: number,\n openEnd: number,\n attrChunk: string,\n name: string,\n value: string,\n): void {\n const escaped = escapeAttr(value);\n const existing = new RegExp(`(\\\\s${name}\\\\s*=\\\\s*)(\"[^\"]*\"|'[^']*'|[^\\\\s>]+)`, 'i').exec(\n attrChunk,\n );\n if (existing) {\n const valueStart = chunkStart + existing.index + existing[1]!.length;\n const valueEnd = valueStart + existing[2]!.length;\n if (html.slice(valueStart, valueEnd) !== `\"${escaped}\"`) {\n ms.overwrite(valueStart, valueEnd, `\"${escaped}\"`);\n }\n return;\n }\n const selfClosing = html.slice(openEnd - 2, openEnd) === '/>';\n const insertAt = openEnd - (selfClosing ? 2 : 1);\n ms.appendLeft(insertAt, ` ${name}=\"${escaped}\"`);\n}\n\nfunction richToHtml(\n nodes: TagNode[],\n allowed: Set<string>,\n links?: Record<string, RichLink>,\n): string {\n let out = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n out += escapeHtml(node);\n } else if (links?.[node.name] !== undefined) {\n const link = links[node.name]!;\n const { href, target, rel }: Exclude<RichLink, string> =\n typeof link === 'string' ? { href: link } : link;\n const safe = safeHref(href);\n let attrs = safe !== undefined ? ` href=\"${escapeAttr(safe)}\"` : '';\n if (target) attrs += ` target=\"${escapeAttr(target)}\"`;\n if (rel) attrs += ` rel=\"${escapeAttr(rel)}\"`;\n out += `<a${attrs}>${richToHtml(node.children, allowed, links)}</a>`;\n } else if (allowed.has(node.name)) {\n out += `<${node.name}>${richToHtml(node.children, allowed, links)}</${node.name}>`;\n } else {\n out += richToHtml(node.children, allowed, links); // unknown tag → unwrap\n }\n }\n return out;\n}\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\nfunction escapeAttr(text: string): string {\n return escapeHtml(text).replace(/\"/g, '&quot;');\n}\n\nfunction decodeEntities(text: string): string {\n return text\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&amp;/g, '&');\n}\n","import type { Catalogs } from './catalog';\nimport type { ResolvedConfig } from './config';\nimport { collectParams } from './params';\n\nexport interface TranslateRequest {\n sourceLocale: string;\n targetLocale: string;\n messages: Record<string, string>;\n}\n\nexport type TranslateProvider = (request: TranslateRequest) => Promise<Record<string, string>>;\n\nexport interface TranslateOptions {\n locales?: string[];\n batchSize?: number;\n dryRun?: boolean;\n}\n\nexport interface TranslateResult {\n translated: Record<string, string[]>;\n invalid: Record<string, string[]>;\n pending: Record<string, string[]>;\n}\n\n// fills '' entries via the provider; invalid translations stay '' (check keeps failing)\nexport async function translateCatalogs(\n cfg: ResolvedConfig,\n catalogs: Catalogs,\n provider: TranslateProvider,\n options: TranslateOptions = {},\n): Promise<TranslateResult> {\n const batchSize = options.batchSize ?? 20;\n const targets = (options.locales ?? cfg.locales).filter(\n (locale) => locale !== cfg.sourceLocale && cfg.locales.includes(locale),\n );\n const source = catalogs[cfg.sourceLocale] ?? {};\n const result: TranslateResult = { translated: {}, invalid: {}, pending: {} };\n\n for (const locale of targets) {\n const catalog = (catalogs[locale] ??= {});\n const missing = Object.keys(source).filter((key) => source[key] && !catalog[key]);\n if (missing.length === 0) continue;\n\n if (options.dryRun) {\n result.pending[locale] = missing;\n continue;\n }\n\n for (let i = 0; i < missing.length; i += batchSize) {\n const keys = missing.slice(i, i + batchSize);\n const messages = Object.fromEntries(keys.map((key) => [key, source[key]!]));\n const out = await provider({\n sourceLocale: cfg.sourceLocale,\n targetLocale: locale,\n messages,\n });\n for (const key of keys) {\n const text = out[key];\n if (typeof text === 'string' && text.trim() && structureMatches(source[key]!, text)) {\n catalog[key] = text;\n (result.translated[locale] ??= []).push(key);\n } else {\n (result.invalid[locale] ??= []).push(key);\n }\n }\n }\n }\n return result;\n}\n\n// params and tags must survive translation verbatim\nexport function structureMatches(source: string, translated: string): boolean {\n return (\n sameMembers(paramNames(source), paramNames(translated)) &&\n sameMembers(tagTokens(source), tagTokens(translated))\n );\n}\n\nfunction paramNames(message: string): string[] {\n try {\n return [...collectParams(message).keys()].sort();\n } catch {\n return ['\u0000invalid'];\n }\n}\n\nconst TAG = /<(\\/?)([a-zA-Z][\\w-]*)(\\/?)>/g;\n\nfunction tagTokens(message: string): string[] {\n const out: string[] = [];\n for (const match of message.matchAll(TAG)) {\n out.push(`${match[1]}${match[2]}${match[3]}`);\n }\n return out.sort();\n}\n\nfunction sameMembers(a: string[], b: string[]): boolean {\n return a.length === b.length && a.every((value, i) => value === b[i]);\n}\n","#!/usr/bin/env node\nimport { parseArgs } from 'node:util';\nimport { loadCatalogs, writeCatalog } from './catalog';\nimport { check, formatCheckResult } from './check';\nimport { writeDts } from './codegen';\nimport { loadConfig } from './config';\nimport { doctor } from './doctor';\nimport { extractProject, pruneCatalogs, syncCatalogs } from './extract';\nimport { init } from './init';\nimport { PSEUDO_LOCALE, pseudoCatalogs } from './pseudo';\nimport { renderSite } from './render';\nimport { translateCatalogs, type TranslateProvider } from './translate';\nimport type { ResolvedConfig } from './config';\n\nconst HELP = `verbaly — i18n compiler\n\nUsage:\n verbaly init scaffold config + locale catalogs (detects your bundler)\n verbaly doctor diagnose the setup (config, catalogs, plugin, types, keys)\n verbaly extract scan sources, update catalogs and types\n verbaly check verify translations are complete (CI)\n verbaly translate fill missing translations via a provider (default: claude)\n verbaly pseudo generate a pseudo-locale catalog for i18n QA (default: en-XA)\n verbaly render pre-fill data-verbaly HTML per locale (SSG, kills the FOUC)\n\nOptions:\n --root <path> project root (default: cwd)\n --dir <path> catalogs directory (default: locales)\n --source <locale> source locale (default: en)\n --locales <csv> extra locales; for translate: target locales to fill\n --prune drop keys no longer referenced (extract)\n --model <id> model override for the claude provider (translate)\n --dry-run list what would be translated, write nothing (translate)\n --locale <id> pseudo-locale id (pseudo, default: en-XA)\n --site <path> built site directory (render, default: dist)\n --attribute <name> base data attribute (render, default: data-verbaly)\n --base-url <url> site origin — enables hreflang alternates (render)\n --sitemap emit sitemap-i18n.xml with per-locale alternates (render)\n --clean remove existing locale dirs before mirroring (render)\n\nConfig file: verbaly.config.{js,mjs,ts,mts,json} at root (flags win).\nThe claude provider needs @anthropic-ai/sdk installed and ANTHROPIC_API_KEY set.\n`;\n\nasync function main(): Promise<void> {\n const { positionals, values } = parseArgs({\n allowPositionals: true,\n options: {\n root: { type: 'string' },\n dir: { type: 'string' },\n source: { type: 'string' },\n locales: { type: 'string' },\n prune: { type: 'boolean' },\n model: { type: 'string' },\n locale: { type: 'string' },\n site: { type: 'string' },\n attribute: { type: 'string' },\n 'base-url': { type: 'string' },\n sitemap: { type: 'boolean' },\n clean: { type: 'boolean' },\n 'dry-run': { type: 'boolean' },\n help: { type: 'boolean', short: 'h' },\n },\n });\n\n const command = positionals[0];\n if (values.help || !command) {\n console.log(HELP);\n process.exitCode = command ? 0 : 1;\n return;\n }\n\n if (command === 'init') {\n const result = init({\n root: values.root,\n dir: values.dir,\n sourceLocale: values.source,\n locales: values.locales?.split(','),\n });\n if (result.created.length) console.log(`[verbaly] created: ${result.created.join(', ')}`);\n if (result.skipped.length) console.log(` kept (already there): ${result.skipped.join(', ')}`);\n if (result.bundler) console.log(` detected bundler: ${result.bundler}`);\n console.log(\n [' next steps:', ...result.next.map((step, i) => ` ${i + 1}. ${step}`)].join('\\n'),\n );\n return;\n }\n\n const cfg = await loadConfig(values.root ?? process.cwd(), {\n dir: values.dir,\n sourceLocale: values.source,\n locales: values.locales?.split(','),\n });\n\n if (command === 'doctor') {\n const result = await doctor(cfg);\n const icon = { ok: '✓', warn: '⚠', error: '✗' } as const;\n console.log(`[verbaly] doctor — ${result.entries.length} checks`);\n for (const entry of result.entries) {\n const line = ` ${icon[entry.level]} ${entry.check}: ${entry.message}`;\n if (entry.level === 'error') console.error(line);\n else if (entry.level === 'warn') console.warn(line);\n else console.log(line);\n if (entry.fix) console.log(` fix: ${entry.fix}`);\n }\n if (result.ok) {\n console.log('[verbaly] setup looks healthy ✓');\n } else {\n console.error('[verbaly] doctor found problems');\n process.exitCode = 1;\n }\n return;\n }\n\n if (command === 'extract') {\n const registry = await extractProject(cfg);\n const catalogs = loadCatalogs(cfg);\n if (values.prune) {\n const removed = pruneCatalogs(cfg, catalogs, registry);\n for (const [locale, keys] of Object.entries(removed)) {\n console.log(` ${locale}: -${keys.length} pruned`);\n }\n }\n const { added } = syncCatalogs(cfg, catalogs, registry);\n for (const locale of cfg.locales) {\n writeCatalog(cfg, locale, catalogs[locale] ?? {});\n }\n writeDts(cfg, new Map(Object.entries(catalogs[cfg.sourceLocale] ?? {})));\n const total = registry.messages().size;\n console.log(`[verbaly] ${total} messages · locales: ${cfg.locales.join(', ')}`);\n for (const [locale, keys] of Object.entries(added)) {\n console.log(` ${locale}: +${keys.length}`);\n }\n return;\n }\n\n if (command === 'check') {\n const registry = await extractProject(cfg);\n const result = check(cfg, loadCatalogs(cfg), registry);\n if (result.ok) {\n console.log('[verbaly] all translations complete ✓');\n return;\n }\n console.error(`[verbaly] check failed\\n${formatCheckResult(result)}`);\n process.exitCode = 1;\n return;\n }\n\n if (command === 'translate') {\n const catalogs = loadCatalogs(cfg);\n const provider = await resolveProvider(cfg, values.model);\n const result = await translateCatalogs(cfg, catalogs, provider, {\n locales: values.locales?.split(','),\n batchSize: cfg.translate.batchSize,\n dryRun: values['dry-run'],\n });\n\n if (values['dry-run']) {\n const entries = Object.entries(result.pending);\n if (entries.length === 0) {\n console.log('[verbaly] nothing to translate ✓');\n return;\n }\n for (const [locale, keys] of entries) {\n console.log(` ${locale}: ${keys.length} missing — ${keys.join(', ')}`);\n }\n return;\n }\n\n for (const locale of Object.keys(result.translated)) {\n writeCatalog(cfg, locale, catalogs[locale] ?? {});\n console.log(` ${locale}: +${result.translated[locale]!.length} translated`);\n }\n for (const [locale, keys] of Object.entries(result.invalid)) {\n console.warn(\n ` ${locale}: ${keys.length} rejected (params/tags not preserved): ${keys.join(', ')}`,\n );\n }\n if (Object.keys(result.translated).length === 0 && Object.keys(result.invalid).length === 0) {\n console.log('[verbaly] nothing to translate ✓');\n }\n return;\n }\n\n if (command === 'render') {\n const result = await renderSite(cfg, {\n site: values.site,\n locales: values.locales?.split(','),\n attribute: values.attribute,\n baseUrl: values['base-url'],\n sitemap: values.sitemap,\n clean: values.clean,\n });\n console.log(\n `[verbaly] ${result.files} pages × ${result.locales.length} locales (${result.locales.join(', ')})`,\n );\n for (const [locale, keys] of Object.entries(result.missing)) {\n console.warn(` ${locale}: ${keys.length} keys not pre-filled — ${keys.join(', ')}`);\n }\n return;\n }\n\n if (command === 'pseudo') {\n const catalogs = loadCatalogs(cfg);\n const locale = values.locale ?? PSEUDO_LOCALE;\n const keys = pseudoCatalogs(cfg, catalogs, locale);\n writeCatalog(cfg, locale, catalogs[locale] ?? {});\n console.log(`[verbaly] ${keys.length} messages pseudo-localized → ${locale}`);\n return;\n }\n\n console.error(`[verbaly] unknown command \"${command}\"\\n${HELP}`);\n process.exitCode = 1;\n}\n\nasync function resolveProvider(\n cfg: ResolvedConfig,\n model: string | undefined,\n): Promise<TranslateProvider> {\n const configured = cfg.translate.provider;\n if (typeof configured === 'function') return configured;\n const { claudeProvider } = await import('./providers/claude');\n return claudeProvider({ model: model ?? cfg.translate.model });\n}\n\nmain().catch((error: unknown) => {\n console.error('[verbaly]', error instanceof Error ? error.message : error);\n process.exitCode = 1;\n});\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { RichLink } from "verbaly";
1
+ import { MessageTree, RichLink } from "verbaly";
2
2
  import MagicString from "magic-string";
3
3
  //#region src/analyze.d.ts
4
4
  interface TaggedParam {
@@ -62,6 +62,12 @@ interface TranslateConfig {
62
62
  }
63
63
  interface RenderConfig {
64
64
  links?: Record<string, RichLink>;
65
+ site?: string;
66
+ attribute?: string;
67
+ baseUrl?: string;
68
+ hreflang?: boolean;
69
+ sitemap?: boolean | string;
70
+ clean?: boolean;
65
71
  }
66
72
  interface VerbalyConfig {
67
73
  root?: string;
@@ -191,14 +197,19 @@ declare function pseudoLocalize(message: string): string;
191
197
  declare function pseudoCatalogs(cfg: ResolvedConfig, catalogs: Catalogs, locale?: string): string[];
192
198
  //#endregion
193
199
  //#region src/render.d.ts
200
+ interface Alternate {
201
+ hreflang: string;
202
+ href: string;
203
+ }
194
204
  interface RenderHtmlOptions {
195
205
  locale: string;
196
- catalogs: Catalogs;
206
+ catalogs: Catalogs | Record<string, MessageTree>;
197
207
  sourceLocale?: string;
198
208
  attribute?: string;
199
209
  richTags?: string[];
200
210
  richLinks?: Record<string, RichLink>;
201
211
  setLang?: boolean;
212
+ alternates?: Alternate[];
202
213
  }
203
214
  interface RenderHtmlResult {
204
215
  html: string;
@@ -211,6 +222,10 @@ interface RenderSiteOptions {
211
222
  attribute?: string;
212
223
  richTags?: string[];
213
224
  richLinks?: Record<string, RichLink>;
225
+ baseUrl?: string;
226
+ hreflang?: boolean;
227
+ sitemap?: boolean | string;
228
+ clean?: boolean;
214
229
  }
215
230
  interface RenderSiteResult {
216
231
  files: number;
@@ -226,5 +241,5 @@ interface TransformResult {
226
241
  }
227
242
  declare function transformCode(code: string, file: string, analysis?: Analysis): TransformResult | null;
228
243
  //#endregion
229
- export { type Analysis, type Catalog, type Catalogs, type CheckResult, type ClaudeProviderOptions, type DoctorEntry, type DoctorResult, type InitOptions, type InitResult, MessageRegistry, type MissingEntry, PSEUDO_LOCALE, type ParamType, type RenderConfig, type RenderHtmlOptions, type RenderHtmlResult, type RenderSiteOptions, type RenderSiteResult, type ResolvedConfig, type SyncResult, type TaggedMessage, type TaggedParam, type TransComponent, type TransformResult, type TranslateConfig, type TranslateOptions, type TranslateProvider, type TranslateRequest, type TranslateResult, type UnknownEntry, type UsedKey, VIRTUAL_ID, type VerbalyConfig, analyze, catalogPath, check, claudeProvider, collectParams, detectBundler, doctor, extractProject, findConfigFile, formatCheckResult, generateDts, generateLocaleModule, generateRuntimeModule, init, loadCatalogs, loadConfig, loadConfigFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, serializeCatalog, stableKey, structureMatches, syncCatalogs, transformCode, translateCatalogs, writeCatalog, writeDts };
244
+ export { type Alternate, type Analysis, type Catalog, type Catalogs, type CheckResult, type ClaudeProviderOptions, type DoctorEntry, type DoctorResult, type InitOptions, type InitResult, MessageRegistry, type MissingEntry, PSEUDO_LOCALE, type ParamType, type RenderConfig, type RenderHtmlOptions, type RenderHtmlResult, type RenderSiteOptions, type RenderSiteResult, type ResolvedConfig, type SyncResult, type TaggedMessage, type TaggedParam, type TransComponent, type TransformResult, type TranslateConfig, type TranslateOptions, type TranslateProvider, type TranslateRequest, type TranslateResult, type UnknownEntry, type UsedKey, VIRTUAL_ID, type VerbalyConfig, analyze, catalogPath, check, claudeProvider, collectParams, detectBundler, doctor, extractProject, findConfigFile, formatCheckResult, generateDts, generateLocaleModule, generateRuntimeModule, init, loadCatalogs, loadConfig, loadConfigFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, serializeCatalog, stableKey, structureMatches, syncCatalogs, transformCode, translateCatalogs, writeCatalog, writeDts };
230
245
  //# sourceMappingURL=index.d.ts.map