@xndrjs/i18n 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +67 -872
  2. package/dist/codegen/index.d.ts +117 -51
  3. package/dist/codegen/index.js +1585 -93
  4. package/dist/codegen/index.js.map +1 -1
  5. package/dist/index.d.ts +100 -234
  6. package/dist/index.js +74 -638
  7. package/dist/index.js.map +1 -1
  8. package/dist/validation/index.d.ts +5 -0
  9. package/dist/validation/index.js.map +1 -1
  10. package/package.json +2 -2
  11. package/src/IcuTranslationProviderMulti.test.ts +18 -40
  12. package/src/IcuTranslationProviderMulti.ts +27 -37
  13. package/src/audit/audit-dictionaries.ts +1 -1
  14. package/src/audit/run-audit.test.ts +6 -7
  15. package/src/builder-load-registry.ts +26 -5
  16. package/src/builder-loaders.ts +8 -11
  17. package/src/builder-types.test.ts +11 -42
  18. package/src/builder.test.ts +82 -243
  19. package/src/builder.ts +8 -110
  20. package/src/codegen/codegen-config-schema.ts +82 -77
  21. package/src/codegen/config.test.ts +55 -143
  22. package/src/codegen/config.ts +10 -67
  23. package/src/codegen/dictionary-spec-contract.test.ts +28 -0
  24. package/src/codegen/dictionary-spec-contract.ts +138 -0
  25. package/src/codegen/emit/dictionary-schema-file.ts +7 -43
  26. package/src/codegen/emit/instance-file.test.ts +35 -52
  27. package/src/codegen/emit/instance-file.ts +170 -268
  28. package/src/codegen/emit/namespace-loaders-file.test.ts +72 -74
  29. package/src/codegen/emit/namespace-loaders-file.ts +147 -90
  30. package/src/codegen/emit/types-file.test.ts +20 -41
  31. package/src/codegen/emit/types-file.ts +48 -74
  32. package/src/codegen/generate-i18n-types.test.ts +163 -492
  33. package/src/codegen/generate-i18n-types.ts +7 -269
  34. package/src/codegen/paths.ts +0 -14
  35. package/src/codegen/project-locales-set-namespace.test.ts +44 -86
  36. package/src/codegen/read-dictionary.test.ts +27 -9
  37. package/src/codegen/read-dictionary.ts +18 -40
  38. package/src/codegen/regenerate-namespaces.ts +180 -0
  39. package/src/codegen/run-codegen.test.ts +230 -0
  40. package/src/codegen/run-codegen.ts +252 -0
  41. package/src/codegen/types.ts +0 -6
  42. package/src/codegen-config/build-config.ts +4 -23
  43. package/src/codegen-config/codegen-config.test.ts +10 -6
  44. package/src/codegen-config/index.ts +18 -3
  45. package/src/engine.ts +3 -27
  46. package/src/fetch-artifact.ts +16 -0
  47. package/src/i18n-handle.ts +202 -0
  48. package/src/index.ts +15 -34
  49. package/src/project-locales.ts +2 -2
  50. package/src/scope-multi.ts +1 -20
  51. package/src/scope-types.ts +14 -6
  52. package/src/scope.test.ts +3 -312
  53. package/src/serialized-state.test.ts +114 -0
  54. package/src/serialized-state.ts +28 -0
  55. package/src/setup/setup-i18n.test.ts +22 -33
  56. package/src/setup/setup-i18n.ts +22 -27
  57. package/src/types.ts +3 -3
  58. package/src/validation/index.ts +4 -0
  59. package/src/IcuTranslationProviderSingle.test.ts +0 -177
  60. package/src/IcuTranslationProviderSingle.ts +0 -114
  61. package/src/builder-multi.ts +0 -481
  62. package/src/codegen/emit/dictionary-file.test.ts +0 -215
  63. package/src/codegen/emit/dictionary-file.ts +0 -244
  64. package/src/deep-freeze.test.ts +0 -40
  65. package/src/deep-freeze.ts +0 -22
  66. package/src/patch-key.test.ts +0 -186
  67. package/src/patch-key.ts +0 -140
  68. package/src/scope-single.ts +0 -85
  69. package/src/single-builder.ts +0 -153
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/icu/extract-variables.ts","../../src/icu/parse-template.ts","../../src/validation/normalize.ts","../../src/validation/to-dictionary.ts","../../src/validation/create-args-schema.ts","../../src/validation/create-normalized-schema.ts","../../src/validation/validate-normalized.ts","../../src/validation/errors.ts","../../src/validation/index.ts"],"names":["dictionary","z","key","step1","input","spec"],"mappings":"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","file":"index.js","sourcesContent":["import type { parse } from \"@formatjs/icu-messageformat-parser\";\n\nexport type VariableType = \"string\" | \"number\" | \"date\";\nexport type VariableSpec = Record<string, VariableType>;\n\nexport type VariableRole =\n | \"simple\"\n | \"plural\"\n | \"selectordinal\"\n | \"select\"\n | \"number\"\n | \"date\"\n | \"time\";\n\nexport type VariableMeta = {\n type: VariableType;\n roles: Set<VariableRole>;\n};\n\nexport type VariableMetaSpec = Record<string, VariableMeta>;\n\ntype IcuAst = ReturnType<typeof parse>;\ntype IcuNode = IcuAst[number];\n\nfunction isPluralOrOrdinalNode(node: IcuNode): node is Extract<IcuNode, { type: 6 }> {\n return node.type === 6 && \"pluralType\" in node && Boolean(node.pluralType);\n}\n\nfunction hasVariableName(node: IcuNode): node is Extract<IcuNode, { value: string }> {\n return \"value\" in node && typeof node.value === \"string\";\n}\n\nfunction addVariableMeta(\n variables: VariableMetaSpec,\n name: string,\n type: VariableType,\n role: VariableRole\n): void {\n const existing = variables[name];\n if (!existing) {\n variables[name] = { type, roles: new Set([role]) };\n return;\n }\n\n existing.roles.add(role);\n existing.type = mergeVariableTypes(existing.type, type);\n}\n\nfunction mergeVariableTypes(left: VariableType, right: VariableType): VariableType {\n if (left === right) {\n return left;\n }\n\n if ((left === \"string\" && right === \"number\") || (left === \"number\" && right === \"string\")) {\n return \"number\";\n }\n\n return right;\n}\n\nexport function extractVariableMeta(nodes: IcuAst): VariableMetaSpec {\n const variables: VariableMetaSpec = {};\n\n const walk = (walkNodes: IcuAst) => {\n for (const node of walkNodes) {\n if (node.type === 1 && hasVariableName(node)) {\n addVariableMeta(variables, node.value, \"string\", \"simple\");\n } else if (node.type === 2 && hasVariableName(node)) {\n addVariableMeta(variables, node.value, \"number\", \"number\");\n } else if (isPluralOrOrdinalNode(node) && hasVariableName(node)) {\n const role = node.pluralType === \"ordinal\" ? \"selectordinal\" : \"plural\";\n addVariableMeta(variables, node.value, \"number\", role);\n } else if (node.type === 3 && hasVariableName(node)) {\n addVariableMeta(variables, node.value, \"date\", \"date\");\n } else if (node.type === 4 && hasVariableName(node)) {\n addVariableMeta(variables, node.value, \"date\", \"time\");\n } else if (node.type === 5 && hasVariableName(node)) {\n addVariableMeta(variables, node.value, \"string\", \"select\");\n }\n\n if (\"options\" in node && node.options) {\n for (const option of Object.values(node.options)) {\n walk(option.value);\n }\n }\n\n if (\"children\" in node && Array.isArray(node.children)) {\n walk(node.children);\n }\n }\n };\n\n walk(nodes);\n return variables;\n}\n\nexport function variableMetaToSpec(meta: VariableMetaSpec): VariableSpec {\n return Object.fromEntries(Object.entries(meta).map(([name, entry]) => [name, entry.type]));\n}\n\nexport function extractVariables(nodes: IcuAst): VariableSpec {\n return variableMetaToSpec(extractVariableMeta(nodes));\n}\n\nexport function inferMergedVariableType(roles: Set<VariableRole>): VariableType | \"CONFLICT\" {\n const hasPlural = roles.has(\"plural\");\n const hasSelectordinal = roles.has(\"selectordinal\");\n const hasSelect = roles.has(\"select\");\n const hasSimple = roles.has(\"simple\");\n const hasNumber = roles.has(\"number\");\n const hasDate = roles.has(\"date\");\n const hasTime = roles.has(\"time\");\n\n // Incompatible numeric ICU constructs on the same variable.\n if (hasPlural && hasSelectordinal) {\n return \"CONFLICT\";\n }\n\n // Select (string-family) vs plural / ordinal / number-format (number-family).\n if (hasSelect && (hasPlural || hasSelectordinal || hasNumber)) {\n return \"CONFLICT\";\n }\n\n // Legacy explicit pairs — covered by the rule above, kept for clarity.\n if (hasPlural && hasSelect) {\n return \"CONFLICT\";\n }\n\n if (hasSelectordinal && hasSelect) {\n return \"CONFLICT\";\n }\n\n if (hasDate || hasTime) {\n if (hasPlural || hasSelect || hasSelectordinal || hasSimple || hasNumber) {\n return \"CONFLICT\";\n }\n return \"date\";\n }\n\n if (hasPlural || hasSelectordinal || hasNumber) {\n return \"number\";\n }\n\n if (hasSelect || hasSimple) {\n return \"string\";\n }\n\n return \"string\";\n}\n\nexport function mergeVariableMetaAcrossLocales(\n localeMetas: readonly VariableMetaSpec[]\n): { ok: true; merged: VariableSpec } | { ok: false; message: string } {\n const keySignatures = localeMetas.map((meta) => Object.keys(meta).sort().join(\",\"));\n if (new Set(keySignatures).size > 1) {\n return {\n ok: false,\n message: `Inconsistent ICU variable names across locales (keys: ${keySignatures.join(\" vs \")})`,\n };\n }\n\n const merged: VariableSpec = {};\n const variableNames = new Set(localeMetas.flatMap((meta) => Object.keys(meta)));\n\n for (const variableName of variableNames) {\n const combinedRoles = new Set<VariableRole>();\n\n for (const meta of localeMetas) {\n for (const role of meta[variableName]?.roles ?? []) {\n combinedRoles.add(role);\n }\n }\n\n const mergedType = inferMergedVariableType(combinedRoles);\n if (mergedType === \"CONFLICT\") {\n const rolesByLocale = localeMetas\n .map((meta) => {\n const entry = meta[variableName];\n if (!entry) {\n return null;\n }\n return [...entry.roles].sort().join(\"|\");\n })\n .filter((value): value is string => value !== null);\n\n return {\n ok: false,\n message: `Incompatible ICU variable \"${variableName}\" across locales (roles: ${rolesByLocale.join(\" vs \")})`,\n };\n }\n\n merged[variableName] = mergedType;\n }\n\n return { ok: true, merged };\n}\n\nexport function mergeVariableSpecs(target: VariableSpec, source: VariableSpec): VariableSpec {\n const merged = { ...target };\n\n for (const [varName, varType] of Object.entries(source)) {\n const existing = merged[varName];\n if (existing && existing !== varType) {\n merged[varName] = \"number\";\n } else {\n merged[varName] = varType;\n }\n }\n\n return merged;\n}\n\nexport function variableSpecsEqual(a: VariableSpec, b: VariableSpec): boolean {\n const aKeys = Object.keys(a).sort();\n const bKeys = Object.keys(b).sort();\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every((key, index) => {\n if (key !== bKeys[index]) {\n return false;\n }\n return a[key] === b[key];\n });\n}\n","import { parse } from \"@formatjs/icu-messageformat-parser\";\nimport {\n extractVariableMeta,\n variableMetaToSpec,\n type VariableMetaSpec,\n type VariableSpec,\n} from \"./extract-variables.js\";\n\nexport type ParseTemplateSuccess = {\n readonly ok: true;\n readonly args: VariableSpec;\n readonly meta: VariableMetaSpec;\n};\n\nexport type ParseTemplateFailure = {\n readonly ok: false;\n readonly message: string;\n};\n\nexport type ParseTemplateResult = ParseTemplateSuccess | ParseTemplateFailure;\n\nexport function parseTemplate(template: string): ParseTemplateResult {\n try {\n const ast = parse(template);\n const meta = extractVariableMeta(ast);\n return { ok: true, args: variableMetaToSpec(meta), meta };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { ok: false, message };\n }\n}\n","import { mergeVariableMetaAcrossLocales, type VariableMetaSpec } from \"../icu/extract-variables.js\";\nimport { parseTemplate } from \"../icu/parse-template.js\";\nimport type { VariableSpec } from \"../icu/extract-variables.js\";\nimport type {\n DictionarySpec,\n NormalizedDictionary,\n NormalizedKeyDictionary,\n ParsedKeyEntry,\n ValidationIssue,\n ValidationResult,\n} from \"./types.js\";\n\nfunction failure(issues: ValidationIssue[]): ValidationResult<NormalizedDictionary> {\n return { ok: false, issues };\n}\n\nfunction success(data: NormalizedDictionary): ValidationResult<NormalizedDictionary> {\n return { ok: true, data };\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction normalizeSingleKey(\n key: string,\n keyValue: Record<string, unknown>,\n keyPathPrefix: readonly string[]\n): { entry: ParsedKeyEntry; issues: ValidationIssue[] } {\n const issues: ValidationIssue[] = [];\n const locales: Record<string, ParsedKeyEntry[\"locales\"][string]> = {};\n const localeMetas: VariableMetaSpec[] = [];\n let mergedArgs: ParsedKeyEntry[\"mergedArgs\"] = {};\n let localeArgsMismatch: ValidationIssue | undefined;\n\n for (const [locale, template] of Object.entries(keyValue)) {\n const localePath = [...keyPathPrefix, key, locale];\n\n if (typeof template !== \"string\") {\n issues.push({\n kind: \"invalid_locale_value\",\n path: localePath,\n message: `expected string, got ${typeof template}`,\n });\n continue;\n }\n\n const parsed = parseTemplate(template);\n if (!parsed.ok) {\n issues.push({\n kind: \"icu_syntax_error\",\n path: localePath,\n message: parsed.message,\n });\n continue;\n }\n\n locales[locale] = { template, args: parsed.args };\n localeMetas.push(parsed.meta);\n }\n\n if (localeMetas.length > 0) {\n const merged = mergeVariableMetaAcrossLocales(localeMetas);\n if (!merged.ok) {\n const localeArgs: Record<string, ParsedKeyEntry[\"mergedArgs\"]> = {};\n for (const [loc, entry] of Object.entries(locales)) {\n localeArgs[loc] = entry.args;\n }\n localeArgsMismatch = {\n kind: \"locale_args_mismatch\",\n path: [...keyPathPrefix, key],\n locales: localeArgs,\n message: merged.message,\n };\n } else {\n mergedArgs = merged.merged;\n }\n }\n\n if (localeArgsMismatch) {\n issues.push(localeArgsMismatch);\n }\n\n return { entry: { locales, mergedArgs }, issues };\n}\n\nfunction normalizeKeyDictionary(\n input: Record<string, unknown>,\n requiredKeys: readonly string[],\n keyPathPrefix: readonly string[]\n): ValidationResult<NormalizedKeyDictionary> {\n const issues: ValidationIssue[] = [];\n const keys: Record<string, ParsedKeyEntry> = {};\n\n for (const key of requiredKeys) {\n if (!(key in input)) {\n issues.push({ kind: \"missing_key\", path: [...keyPathPrefix, key] });\n continue;\n }\n\n const keyValue = input[key];\n if (!isPlainObject(keyValue)) {\n issues.push({\n kind: \"invalid_input\",\n message: `Expected object for key \"${key}\", got ${typeof keyValue}`,\n });\n continue;\n }\n\n const result = normalizeSingleKey(key, keyValue, keyPathPrefix);\n issues.push(...result.issues);\n keys[key] = result.entry;\n }\n\n if (issues.length > 0) {\n return { ok: false, issues };\n }\n\n return { ok: true, data: keys };\n}\n\n/**\n * Validation step 1 (partial): coerce external input into a normalized key dictionary\n * for only the keys present in the payload.\n */\nexport function normalizeKeyDictionaryPartial(\n input: unknown,\n knownKeys: readonly string[],\n _argsByKey: Readonly<Record<string, VariableSpec>>,\n keyPathPrefix: readonly string[]\n): ValidationResult<NormalizedKeyDictionary> {\n if (!isPlainObject(input)) {\n return {\n ok: false,\n issues: [\n {\n kind: \"invalid_input\",\n message: `Expected object, got ${input === null ? \"null\" : typeof input}`,\n },\n ],\n };\n }\n\n const knownKeysSet = new Set(knownKeys);\n const issues: ValidationIssue[] = [];\n const keys: Record<string, ParsedKeyEntry> = {};\n\n for (const key of Object.keys(input)) {\n if (!knownKeysSet.has(key)) {\n issues.push({ kind: \"unknown_key\", path: [...keyPathPrefix, key] });\n continue;\n }\n\n const keyValue = input[key];\n if (!isPlainObject(keyValue)) {\n issues.push({\n kind: \"invalid_input\",\n message: `Expected object for key \"${key}\", got ${typeof keyValue}`,\n });\n continue;\n }\n\n if (Object.keys(keyValue).length === 0) {\n issues.push({\n kind: \"invalid_input\",\n message: `Key \"${key}\" must include at least one locale`,\n });\n continue;\n }\n\n const result = normalizeSingleKey(key, keyValue, keyPathPrefix);\n issues.push(...result.issues);\n keys[key] = result.entry;\n }\n\n if (issues.length > 0) {\n return { ok: false, issues };\n }\n\n return { ok: true, data: keys };\n}\n\n/**\n * Validation step 1: coerce external input into a normalized dictionary shape\n * (keys, locales, ICU args) against a `DictionarySpec`.\n */\nexport function normalizeDictionary(\n input: unknown,\n spec: DictionarySpec\n): ValidationResult<NormalizedDictionary> {\n if (!isPlainObject(input)) {\n return failure([\n {\n kind: \"invalid_input\",\n message: `Expected object, got ${input === null ? \"null\" : typeof input}`,\n },\n ]);\n }\n\n if (spec.mode === \"single\") {\n const result = normalizeKeyDictionary(input, spec.requiredKeys, []);\n if (!result.ok) {\n return result;\n }\n\n return success({ mode: \"single\", keys: result.data });\n }\n\n const issues: ValidationIssue[] = [];\n const namespaces: Record<string, NormalizedKeyDictionary> = {};\n\n for (const [namespace, requiredKeys] of Object.entries(spec.requiredKeys)) {\n if (!(namespace in input)) {\n for (const key of requiredKeys) {\n issues.push({ kind: \"missing_key\", path: [namespace, key] });\n }\n continue;\n }\n\n const namespaceValue = input[namespace];\n if (!isPlainObject(namespaceValue)) {\n issues.push({\n kind: \"invalid_input\",\n message: `Expected object for namespace \"${namespace}\", got ${typeof namespaceValue}`,\n });\n continue;\n }\n\n const result = normalizeKeyDictionary(namespaceValue, requiredKeys, [namespace]);\n if (!result.ok) {\n issues.push(...result.issues);\n } else {\n namespaces[namespace] = result.data;\n }\n }\n\n if (issues.length > 0) {\n return failure(issues);\n }\n\n return success({ mode: \"multi\", namespaces });\n}\n\n/**\n * Validation step 1 (partial, multi): coerce external input into normalized namespace\n * slices for only the namespaces and keys present in the payload.\n */\nexport function normalizeDictionaryPartial(\n input: unknown,\n spec: Extract<DictionarySpec, { mode: \"multi\" }>\n): ValidationResult<NormalizedDictionary> {\n if (!isPlainObject(input)) {\n return failure([\n {\n kind: \"invalid_input\",\n message: `Expected object, got ${input === null ? \"null\" : typeof input}`,\n },\n ]);\n }\n\n const knownNamespaces = Object.keys(spec.requiredKeys);\n const knownNamespacesSet = new Set(knownNamespaces);\n const issues: ValidationIssue[] = [];\n const namespaces: Record<string, NormalizedKeyDictionary> = {};\n\n for (const namespace of Object.keys(input)) {\n if (!knownNamespacesSet.has(namespace)) {\n issues.push({ kind: \"unknown_key\", path: [namespace] });\n continue;\n }\n\n const namespaceValue = input[namespace];\n if (!isPlainObject(namespaceValue)) {\n issues.push({\n kind: \"invalid_input\",\n message: `Expected object for namespace \"${namespace}\", got ${typeof namespaceValue}`,\n });\n continue;\n }\n\n const result = normalizeKeyDictionaryPartial(\n namespaceValue,\n spec.requiredKeys[namespace] ?? [],\n spec.argsByKey[namespace] ?? {},\n [namespace]\n );\n if (!result.ok) {\n issues.push(...result.issues);\n } else {\n namespaces[namespace] = result.data;\n }\n }\n\n if (issues.length > 0) {\n return failure(issues);\n }\n\n return success({ mode: \"multi\", namespaces });\n}\n","import type { NormalizedDictionary } from \"./types.js\";\n\ntype LocaleDictionary = Record<string, string>;\ntype KeyDictionary = Record<string, LocaleDictionary>;\ntype MultiDictionary = Record<string, KeyDictionary>;\n\nexport function toDictionary(normalized: NormalizedDictionary): KeyDictionary | MultiDictionary {\n if (normalized.mode === \"single\") {\n const dictionary: KeyDictionary = {};\n\n for (const [key, entry] of Object.entries(normalized.keys)) {\n const locales: LocaleDictionary = {};\n for (const [locale, localeEntry] of Object.entries(entry.locales)) {\n locales[locale] = localeEntry.template;\n }\n dictionary[key] = locales;\n }\n\n return dictionary;\n }\n\n const dictionary: MultiDictionary = {};\n\n for (const [namespace, keys] of Object.entries(normalized.namespaces)) {\n const namespaceDictionary: KeyDictionary = {};\n\n for (const [key, entry] of Object.entries(keys)) {\n const locales: LocaleDictionary = {};\n for (const [locale, localeEntry] of Object.entries(entry.locales)) {\n locales[locale] = localeEntry.template;\n }\n namespaceDictionary[key] = locales;\n }\n\n dictionary[namespace] = namespaceDictionary;\n }\n\n return dictionary;\n}\n\nexport function toNamespaceDictionary(\n normalized: NormalizedDictionary,\n namespace: string\n): KeyDictionary {\n if (normalized.mode !== \"multi\") {\n throw new Error(\n `[i18n] toNamespaceDictionary requires multi-mode normalized dictionary, got \"${normalized.mode}\"`\n );\n }\n\n const keys = normalized.namespaces[namespace];\n if (!keys) {\n return {};\n }\n\n const dictionary: KeyDictionary = {};\n\n for (const [key, entry] of Object.entries(keys)) {\n const locales: LocaleDictionary = {};\n for (const [locale, localeEntry] of Object.entries(entry.locales)) {\n locales[locale] = localeEntry.template;\n }\n dictionary[key] = locales;\n }\n\n return dictionary;\n}\n","import { z } from \"zod\";\nimport type { VariableSpec, VariableType } from \"../icu/extract-variables.js\";\n\nexport const variableTypeSchema = z.enum([\"string\", \"number\", \"date\"]);\n\nfunction formatVariableMismatch(expected: VariableSpec, found: VariableSpec): string {\n const expectedKeys = Object.keys(expected).sort();\n const foundKeys = Object.keys(found).sort();\n return `Expected variables [${expectedKeys.join(\", \")}], found [${foundKeys.join(\", \")}]`;\n}\n\nexport function createArgsSchema(expected: VariableSpec): z.ZodType<VariableSpec> {\n return z.record(z.string(), variableTypeSchema).superRefine((found, ctx) => {\n const expectedKeys = Object.keys(expected).sort();\n const foundKeys = Object.keys(found).sort();\n\n if (expectedKeys.join() !== foundKeys.join()) {\n ctx.addIssue({\n code: \"custom\",\n message: formatVariableMismatch(expected, found),\n });\n return;\n }\n\n for (const [name, type] of Object.entries(expected)) {\n if (found[name] !== type) {\n ctx.addIssue({\n code: \"custom\",\n message: `Variable \"${name}\": expected ${type}, found ${found[name]}`,\n });\n }\n }\n });\n}\n\nexport function mapArgsSchemaError(\n expected: VariableSpec,\n found: VariableSpec,\n message: string,\n path: readonly string[]\n) {\n const expectedKeys = Object.keys(expected).sort();\n const foundKeys = Object.keys(found).sort();\n\n if (expectedKeys.join() !== foundKeys.join()) {\n return {\n kind: \"variable_mismatch\" as const,\n path,\n expected,\n found,\n message,\n };\n }\n\n for (const [name, type] of Object.entries(expected)) {\n const foundType = found[name];\n if (foundType !== undefined && foundType !== type) {\n return {\n kind: \"variable_type_mismatch\" as const,\n path,\n variable: name,\n expected: type,\n found: foundType as VariableType,\n message,\n };\n }\n }\n\n return {\n kind: \"variable_mismatch\" as const,\n path,\n expected,\n found,\n message,\n };\n}\n","import { z } from \"zod\";\nimport type { VariableSpec } from \"../icu/extract-variables.js\";\nimport { createArgsSchema, variableTypeSchema } from \"./create-args-schema.js\";\nimport type { DictionarySpec, NormalizedDictionary, ParsedKeyEntry } from \"./types.js\";\n\nconst parsedLocaleEntrySchema = z.object({\n template: z.string(),\n args: z.record(z.string(), variableTypeSchema),\n});\n\nconst parsedKeyEntrySchema = z.object({\n locales: z.record(z.string(), parsedLocaleEntrySchema),\n mergedArgs: z.record(z.string(), variableTypeSchema),\n});\n\nexport function createKeyDictionarySchema(\n argsByKey: Readonly<Record<string, VariableSpec>>\n): z.ZodType<Record<string, ParsedKeyEntry>> {\n const keySchemas = Object.fromEntries(\n Object.entries(argsByKey).map(([key, expectedArgs]) => [\n key,\n parsedKeyEntrySchema.extend({\n mergedArgs: createArgsSchema(expectedArgs),\n }),\n ])\n );\n\n return z.object(keySchemas);\n}\n\nexport function createNormalizedDictionarySchema(\n spec: DictionarySpec\n): z.ZodType<NormalizedDictionary> {\n if (spec.mode === \"single\") {\n return z.object({\n mode: z.literal(\"single\"),\n keys: createKeyDictionarySchema(spec.argsByKey),\n }) as z.ZodType<NormalizedDictionary>;\n }\n\n const namespaceSchemas = Object.fromEntries(\n Object.entries(spec.argsByKey).map(([namespace, argsByKey]) => [\n namespace,\n createKeyDictionarySchema(argsByKey),\n ])\n );\n\n return z.object({\n mode: z.literal(\"multi\"),\n namespaces: z.object(namespaceSchemas),\n }) as z.ZodType<NormalizedDictionary>;\n}\n","import type { ZodError } from \"zod\";\nimport { mapArgsSchemaError } from \"./create-args-schema.js\";\nimport {\n createKeyDictionarySchema,\n createNormalizedDictionarySchema,\n} from \"./create-normalized-schema.js\";\nimport type {\n DictionarySpec,\n NormalizedDictionary,\n NormalizedKeyDictionary,\n ValidationIssue,\n ValidationResult,\n VariableSpec,\n} from \"./types.js\";\n\nfunction getExpectedArgs(spec: DictionarySpec, path: readonly string[]): VariableSpec | undefined {\n if (spec.mode === \"single\") {\n const key = path[path.length - 1];\n if (typeof key !== \"string\") {\n return undefined;\n }\n return spec.argsByKey[key];\n }\n\n const namespace = path[0];\n const key = path[path.length - 1];\n if (typeof namespace !== \"string\" || typeof key !== \"string\") {\n return undefined;\n }\n\n return spec.argsByKey[namespace]?.[key];\n}\n\nfunction getFoundArgs(\n normalized: NormalizedDictionary,\n path: readonly string[]\n): VariableSpec | undefined {\n if (normalized.mode === \"single\") {\n const key = path[path.length - 1];\n if (typeof key !== \"string\") {\n return undefined;\n }\n return normalized.keys[key]?.mergedArgs;\n }\n\n const namespace = path[0];\n const key = path[path.length - 1];\n if (typeof namespace !== \"string\" || typeof key !== \"string\") {\n return undefined;\n }\n\n return normalized.namespaces[namespace]?.[key]?.mergedArgs;\n}\n\nfunction mapZodError(\n error: ZodError,\n spec: DictionarySpec,\n normalized: NormalizedDictionary\n): ValidationIssue[] {\n return error.issues.map((issue) => {\n const path = issue.path.map(String);\n\n if (path.includes(\"mergedArgs\")) {\n const keyPath = path.slice(0, path.indexOf(\"mergedArgs\"));\n const expected = getExpectedArgs(spec, keyPath);\n const found = getFoundArgs(normalized, keyPath);\n\n if (expected && found) {\n return mapArgsSchemaError(expected, found, issue.message, keyPath);\n }\n }\n\n return {\n kind: \"invalid_input\" as const,\n message: path.length > 0 ? `${path.join(\".\")}: ${issue.message}` : issue.message,\n };\n });\n}\n\nexport function validateNormalizedKeyDictionaryPartial(\n keys: NormalizedKeyDictionary,\n argsByKey: Readonly<Record<string, VariableSpec>>,\n spec: DictionarySpec,\n keyPathPrefix: readonly string[]\n): ValidationResult<NormalizedKeyDictionary> {\n const presentKeys = Object.keys(keys);\n const subsetArgsByKey = Object.fromEntries(\n presentKeys.filter((key) => key in argsByKey).map((key) => [key, argsByKey[key]!])\n );\n\n if (presentKeys.length === 0) {\n return { ok: true, data: keys };\n }\n\n const schema = createKeyDictionarySchema(subsetArgsByKey);\n const result = schema.safeParse(keys);\n\n if (result.success) {\n return { ok: true, data: result.data };\n }\n\n const normalized: NormalizedDictionary =\n spec.mode === \"single\"\n ? { mode: \"single\", keys }\n : {\n mode: \"multi\",\n namespaces: {\n [keyPathPrefix[0] ?? \"\"]: keys,\n },\n };\n\n return {\n ok: false,\n issues: mapZodError(result.error, spec, normalized),\n };\n}\n\nexport function validateNormalizedDictionary(\n normalized: NormalizedDictionary,\n spec: DictionarySpec\n): ValidationResult<NormalizedDictionary> {\n const schema = createNormalizedDictionarySchema(spec);\n const result = schema.safeParse(normalized);\n\n if (result.success) {\n return { ok: true, data: result.data };\n }\n\n return {\n ok: false,\n issues: mapZodError(result.error, spec, normalized),\n };\n}\n","import type { ValidationIssue, ValidationResult } from \"./types.js\";\n\nfunction issueMessage(issue: ValidationIssue): string {\n switch (issue.kind) {\n case \"missing_key\":\n return `Missing required key at ${issue.path.join(\".\")}`;\n case \"unknown_key\":\n return `Unknown key at ${issue.path.join(\".\")}`;\n case \"invalid_input\":\n case \"invalid_locale_value\":\n case \"icu_syntax_error\":\n case \"locale_args_mismatch\":\n case \"variable_mismatch\":\n case \"variable_type_mismatch\":\n return issue.message;\n }\n}\n\nexport function formatIssues(issues: readonly ValidationIssue[]): string {\n return issues\n .map((issue) => {\n if (\"path\" in issue && issue.path.length > 0) {\n return `[${issue.path.join(\".\")}] ${issue.kind}: ${issueMessage(issue)}`;\n }\n return `${issue.kind}: ${issueMessage(issue)}`;\n })\n .join(\"\\n\");\n}\n\nexport class DictionaryValidationError extends Error {\n constructor(public readonly issues: readonly ValidationIssue[]) {\n super(formatIssues(issues));\n this.name = \"DictionaryValidationError\";\n }\n}\n\nexport function assertValidDictionary<T>(\n result: ValidationResult<T>\n): asserts result is { ok: true; data: T } {\n if (!result.ok) {\n throw new DictionaryValidationError(result.issues);\n }\n}\n","import { normalizeDictionaryPartial, normalizeKeyDictionaryPartial } from \"./normalize.js\";\nimport { toDictionary, toNamespaceDictionary } from \"./to-dictionary.js\";\nimport type {\n DictionarySpec,\n NormalizedKeyDictionary,\n ValidationIssue,\n ValidationResult,\n} from \"./types.js\";\nimport { validateNormalizedKeyDictionaryPartial } from \"./validate-normalized.js\";\n\nexport function validateExternalDictionaryPartial<TSchema>(\n input: unknown,\n spec: DictionarySpec\n): ValidationResult<Partial<TSchema>> {\n if (spec.mode === \"single\") {\n const step1 = normalizeKeyDictionaryPartial(input, spec.requiredKeys, spec.argsByKey, []);\n if (!step1.ok) {\n return step1;\n }\n\n const step2 = validateNormalizedKeyDictionaryPartial(step1.data, spec.argsByKey, spec, []);\n if (!step2.ok) {\n return step2;\n }\n\n return {\n ok: true,\n data: toDictionary({ mode: \"single\", keys: step2.data }) as Partial<TSchema>,\n };\n }\n\n const step1 = normalizeDictionaryPartial(input, spec);\n if (!step1.ok) {\n return step1;\n }\n\n if (step1.data.mode !== \"multi\") {\n return {\n ok: false,\n issues: [\n {\n kind: \"invalid_input\",\n message: \"validateExternalDictionaryPartial requires multi-mode dictionary spec\",\n },\n ],\n };\n }\n\n const issues: ValidationIssue[] = [];\n const namespaces: Record<string, NormalizedKeyDictionary> = {};\n\n for (const [namespace, keys] of Object.entries(step1.data.namespaces)) {\n const step2 = validateNormalizedKeyDictionaryPartial(\n keys,\n spec.argsByKey[namespace] ?? {},\n spec,\n [namespace]\n );\n if (!step2.ok) {\n issues.push(...step2.issues);\n } else {\n namespaces[namespace] = step2.data;\n }\n }\n\n if (issues.length > 0) {\n return { ok: false, issues };\n }\n\n return {\n ok: true,\n data: toDictionary({ mode: \"multi\", namespaces }) as Partial<TSchema>,\n };\n}\n\nexport function validateExternalNamespacePartial<TNamespaceSchema>(\n namespace: string,\n input: unknown,\n spec: DictionarySpec\n): ValidationResult<Partial<TNamespaceSchema>> {\n if (spec.mode !== \"multi\") {\n return {\n ok: false,\n issues: [\n {\n kind: \"invalid_input\",\n message: \"validateExternalNamespacePartial requires multi-mode dictionary spec\",\n },\n ],\n };\n }\n\n const knownKeys = spec.requiredKeys[namespace];\n if (!knownKeys) {\n return {\n ok: false,\n issues: [{ kind: \"unknown_key\", path: [namespace] }],\n };\n }\n\n const step1 = normalizeKeyDictionaryPartial(input, knownKeys, spec.argsByKey[namespace] ?? {}, [\n namespace,\n ]);\n if (!step1.ok) {\n return step1;\n }\n\n const step2 = validateNormalizedKeyDictionaryPartial(\n step1.data,\n spec.argsByKey[namespace] ?? {},\n spec,\n [namespace]\n );\n if (!step2.ok) {\n return step2;\n }\n\n return {\n ok: true,\n data: toNamespaceDictionary(\n { mode: \"multi\", namespaces: { [namespace]: step2.data } },\n namespace\n ) as Partial<TNamespaceSchema>,\n };\n}\n\nexport function validateExternalKey<TKeySlice>(\n key: string,\n input: unknown,\n spec: Extract<DictionarySpec, { mode: \"single\" }>\n): ValidationResult<TKeySlice>;\n\nexport function validateExternalKey<TKeySlice>(\n namespace: string,\n key: string,\n input: unknown,\n spec: Extract<DictionarySpec, { mode: \"multi\" }>\n): ValidationResult<TKeySlice>;\n\nexport function validateExternalKey<TKeySlice>(\n namespaceOrKey: string,\n keyOrInput: string | unknown,\n inputOrSpec?: unknown,\n specMaybe?: DictionarySpec\n): ValidationResult<TKeySlice> {\n if (specMaybe?.mode === \"multi\") {\n const namespace = namespaceOrKey;\n const key = keyOrInput as string;\n const input = inputOrSpec;\n const spec = specMaybe;\n\n return validateExternalNamespacePartial<TKeySlice>(\n namespace,\n { [key]: input },\n spec\n ) as ValidationResult<TKeySlice>;\n }\n\n const key = namespaceOrKey;\n const input = keyOrInput;\n const spec = inputOrSpec as Extract<DictionarySpec, { mode: \"single\" }>;\n\n return validateExternalDictionaryPartial<TKeySlice>(\n { [key]: input },\n spec\n ) as ValidationResult<TKeySlice>;\n}\n\nexport {\n normalizeDictionaryPartial,\n normalizeKeyDictionaryPartial,\n toDictionary,\n toNamespaceDictionary,\n};\nexport { validateNormalizedKeyDictionaryPartial } from \"./validate-normalized.js\";\nexport { createArgsSchema } from \"./create-args-schema.js\";\nexport { createNormalizedDictionarySchema } from \"./create-normalized-schema.js\";\nexport { DictionaryValidationError, assertValidDictionary, formatIssues } from \"./errors.js\";\nexport type {\n DictionarySpec,\n NormalizedDictionary,\n NormalizedKeyDictionary,\n NormalizedMultiDictionary,\n ParsedKeyEntry,\n ParsedLocaleEntry,\n ValidationIssue,\n ValidationResult,\n VariableSpec,\n VariableType,\n} from \"./types.js\";\n\nexport type { ParseTemplateResult } from \"../icu/parse-template.js\";\nexport { parseTemplate } from \"../icu/parse-template.js\";\nexport {\n extractVariables,\n mergeVariableSpecs,\n variableSpecsEqual,\n} from \"../icu/extract-variables.js\";\n"]}
1
+ {"version":3,"sources":["../../src/icu/extract-variables.ts","../../src/icu/parse-template.ts","../../src/validation/normalize.ts","../../src/validation/to-dictionary.ts","../../src/validation/create-args-schema.ts","../../src/validation/create-normalized-schema.ts","../../src/validation/validate-normalized.ts","../../src/validation/errors.ts","../../src/validation/index.ts"],"names":["dictionary","z","key","step1","input","spec"],"mappings":"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","file":"index.js","sourcesContent":["import type { parse } from \"@formatjs/icu-messageformat-parser\";\n\nexport type VariableType = \"string\" | \"number\" | \"date\";\nexport type VariableSpec = Record<string, VariableType>;\n\nexport type VariableRole =\n | \"simple\"\n | \"plural\"\n | \"selectordinal\"\n | \"select\"\n | \"number\"\n | \"date\"\n | \"time\";\n\nexport type VariableMeta = {\n type: VariableType;\n roles: Set<VariableRole>;\n};\n\nexport type VariableMetaSpec = Record<string, VariableMeta>;\n\ntype IcuAst = ReturnType<typeof parse>;\ntype IcuNode = IcuAst[number];\n\nfunction isPluralOrOrdinalNode(node: IcuNode): node is Extract<IcuNode, { type: 6 }> {\n return node.type === 6 && \"pluralType\" in node && Boolean(node.pluralType);\n}\n\nfunction hasVariableName(node: IcuNode): node is Extract<IcuNode, { value: string }> {\n return \"value\" in node && typeof node.value === \"string\";\n}\n\nfunction addVariableMeta(\n variables: VariableMetaSpec,\n name: string,\n type: VariableType,\n role: VariableRole\n): void {\n const existing = variables[name];\n if (!existing) {\n variables[name] = { type, roles: new Set([role]) };\n return;\n }\n\n existing.roles.add(role);\n existing.type = mergeVariableTypes(existing.type, type);\n}\n\nfunction mergeVariableTypes(left: VariableType, right: VariableType): VariableType {\n if (left === right) {\n return left;\n }\n\n if ((left === \"string\" && right === \"number\") || (left === \"number\" && right === \"string\")) {\n return \"number\";\n }\n\n return right;\n}\n\nexport function extractVariableMeta(nodes: IcuAst): VariableMetaSpec {\n const variables: VariableMetaSpec = {};\n\n const walk = (walkNodes: IcuAst) => {\n for (const node of walkNodes) {\n if (node.type === 1 && hasVariableName(node)) {\n addVariableMeta(variables, node.value, \"string\", \"simple\");\n } else if (node.type === 2 && hasVariableName(node)) {\n addVariableMeta(variables, node.value, \"number\", \"number\");\n } else if (isPluralOrOrdinalNode(node) && hasVariableName(node)) {\n const role = node.pluralType === \"ordinal\" ? \"selectordinal\" : \"plural\";\n addVariableMeta(variables, node.value, \"number\", role);\n } else if (node.type === 3 && hasVariableName(node)) {\n addVariableMeta(variables, node.value, \"date\", \"date\");\n } else if (node.type === 4 && hasVariableName(node)) {\n addVariableMeta(variables, node.value, \"date\", \"time\");\n } else if (node.type === 5 && hasVariableName(node)) {\n addVariableMeta(variables, node.value, \"string\", \"select\");\n }\n\n if (\"options\" in node && node.options) {\n for (const option of Object.values(node.options)) {\n walk(option.value);\n }\n }\n\n if (\"children\" in node && Array.isArray(node.children)) {\n walk(node.children);\n }\n }\n };\n\n walk(nodes);\n return variables;\n}\n\nexport function variableMetaToSpec(meta: VariableMetaSpec): VariableSpec {\n return Object.fromEntries(Object.entries(meta).map(([name, entry]) => [name, entry.type]));\n}\n\nexport function extractVariables(nodes: IcuAst): VariableSpec {\n return variableMetaToSpec(extractVariableMeta(nodes));\n}\n\nexport function inferMergedVariableType(roles: Set<VariableRole>): VariableType | \"CONFLICT\" {\n const hasPlural = roles.has(\"plural\");\n const hasSelectordinal = roles.has(\"selectordinal\");\n const hasSelect = roles.has(\"select\");\n const hasSimple = roles.has(\"simple\");\n const hasNumber = roles.has(\"number\");\n const hasDate = roles.has(\"date\");\n const hasTime = roles.has(\"time\");\n\n // Incompatible numeric ICU constructs on the same variable.\n if (hasPlural && hasSelectordinal) {\n return \"CONFLICT\";\n }\n\n // Select (string-family) vs plural / ordinal / number-format (number-family).\n if (hasSelect && (hasPlural || hasSelectordinal || hasNumber)) {\n return \"CONFLICT\";\n }\n\n // Legacy explicit pairs — covered by the rule above, kept for clarity.\n if (hasPlural && hasSelect) {\n return \"CONFLICT\";\n }\n\n if (hasSelectordinal && hasSelect) {\n return \"CONFLICT\";\n }\n\n if (hasDate || hasTime) {\n if (hasPlural || hasSelect || hasSelectordinal || hasSimple || hasNumber) {\n return \"CONFLICT\";\n }\n return \"date\";\n }\n\n if (hasPlural || hasSelectordinal || hasNumber) {\n return \"number\";\n }\n\n if (hasSelect || hasSimple) {\n return \"string\";\n }\n\n return \"string\";\n}\n\nexport function mergeVariableMetaAcrossLocales(\n localeMetas: readonly VariableMetaSpec[]\n): { ok: true; merged: VariableSpec } | { ok: false; message: string } {\n const keySignatures = localeMetas.map((meta) => Object.keys(meta).sort().join(\",\"));\n if (new Set(keySignatures).size > 1) {\n return {\n ok: false,\n message: `Inconsistent ICU variable names across locales (keys: ${keySignatures.join(\" vs \")})`,\n };\n }\n\n const merged: VariableSpec = {};\n const variableNames = new Set(localeMetas.flatMap((meta) => Object.keys(meta)));\n\n for (const variableName of variableNames) {\n const combinedRoles = new Set<VariableRole>();\n\n for (const meta of localeMetas) {\n for (const role of meta[variableName]?.roles ?? []) {\n combinedRoles.add(role);\n }\n }\n\n const mergedType = inferMergedVariableType(combinedRoles);\n if (mergedType === \"CONFLICT\") {\n const rolesByLocale = localeMetas\n .map((meta) => {\n const entry = meta[variableName];\n if (!entry) {\n return null;\n }\n return [...entry.roles].sort().join(\"|\");\n })\n .filter((value): value is string => value !== null);\n\n return {\n ok: false,\n message: `Incompatible ICU variable \"${variableName}\" across locales (roles: ${rolesByLocale.join(\" vs \")})`,\n };\n }\n\n merged[variableName] = mergedType;\n }\n\n return { ok: true, merged };\n}\n\nexport function mergeVariableSpecs(target: VariableSpec, source: VariableSpec): VariableSpec {\n const merged = { ...target };\n\n for (const [varName, varType] of Object.entries(source)) {\n const existing = merged[varName];\n if (existing && existing !== varType) {\n merged[varName] = \"number\";\n } else {\n merged[varName] = varType;\n }\n }\n\n return merged;\n}\n\nexport function variableSpecsEqual(a: VariableSpec, b: VariableSpec): boolean {\n const aKeys = Object.keys(a).sort();\n const bKeys = Object.keys(b).sort();\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every((key, index) => {\n if (key !== bKeys[index]) {\n return false;\n }\n return a[key] === b[key];\n });\n}\n","import { parse } from \"@formatjs/icu-messageformat-parser\";\nimport {\n extractVariableMeta,\n variableMetaToSpec,\n type VariableMetaSpec,\n type VariableSpec,\n} from \"./extract-variables.js\";\n\nexport type ParseTemplateSuccess = {\n readonly ok: true;\n readonly args: VariableSpec;\n readonly meta: VariableMetaSpec;\n};\n\nexport type ParseTemplateFailure = {\n readonly ok: false;\n readonly message: string;\n};\n\nexport type ParseTemplateResult = ParseTemplateSuccess | ParseTemplateFailure;\n\nexport function parseTemplate(template: string): ParseTemplateResult {\n try {\n const ast = parse(template);\n const meta = extractVariableMeta(ast);\n return { ok: true, args: variableMetaToSpec(meta), meta };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { ok: false, message };\n }\n}\n","import { mergeVariableMetaAcrossLocales, type VariableMetaSpec } from \"../icu/extract-variables.js\";\nimport { parseTemplate } from \"../icu/parse-template.js\";\nimport type { VariableSpec } from \"../icu/extract-variables.js\";\nimport type {\n DictionarySpec,\n NormalizedDictionary,\n NormalizedKeyDictionary,\n ParsedKeyEntry,\n ValidationIssue,\n ValidationResult,\n} from \"./types.js\";\n\nfunction failure(issues: ValidationIssue[]): ValidationResult<NormalizedDictionary> {\n return { ok: false, issues };\n}\n\nfunction success(data: NormalizedDictionary): ValidationResult<NormalizedDictionary> {\n return { ok: true, data };\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction normalizeSingleKey(\n key: string,\n keyValue: Record<string, unknown>,\n keyPathPrefix: readonly string[]\n): { entry: ParsedKeyEntry; issues: ValidationIssue[] } {\n const issues: ValidationIssue[] = [];\n const locales: Record<string, ParsedKeyEntry[\"locales\"][string]> = {};\n const localeMetas: VariableMetaSpec[] = [];\n let mergedArgs: ParsedKeyEntry[\"mergedArgs\"] = {};\n let localeArgsMismatch: ValidationIssue | undefined;\n\n for (const [locale, template] of Object.entries(keyValue)) {\n const localePath = [...keyPathPrefix, key, locale];\n\n if (typeof template !== \"string\") {\n issues.push({\n kind: \"invalid_locale_value\",\n path: localePath,\n message: `expected string, got ${typeof template}`,\n });\n continue;\n }\n\n const parsed = parseTemplate(template);\n if (!parsed.ok) {\n issues.push({\n kind: \"icu_syntax_error\",\n path: localePath,\n message: parsed.message,\n });\n continue;\n }\n\n locales[locale] = { template, args: parsed.args };\n localeMetas.push(parsed.meta);\n }\n\n if (localeMetas.length > 0) {\n const merged = mergeVariableMetaAcrossLocales(localeMetas);\n if (!merged.ok) {\n const localeArgs: Record<string, ParsedKeyEntry[\"mergedArgs\"]> = {};\n for (const [loc, entry] of Object.entries(locales)) {\n localeArgs[loc] = entry.args;\n }\n localeArgsMismatch = {\n kind: \"locale_args_mismatch\",\n path: [...keyPathPrefix, key],\n locales: localeArgs,\n message: merged.message,\n };\n } else {\n mergedArgs = merged.merged;\n }\n }\n\n if (localeArgsMismatch) {\n issues.push(localeArgsMismatch);\n }\n\n return { entry: { locales, mergedArgs }, issues };\n}\n\nfunction normalizeKeyDictionary(\n input: Record<string, unknown>,\n requiredKeys: readonly string[],\n keyPathPrefix: readonly string[]\n): ValidationResult<NormalizedKeyDictionary> {\n const issues: ValidationIssue[] = [];\n const keys: Record<string, ParsedKeyEntry> = {};\n\n for (const key of requiredKeys) {\n if (!(key in input)) {\n issues.push({ kind: \"missing_key\", path: [...keyPathPrefix, key] });\n continue;\n }\n\n const keyValue = input[key];\n if (!isPlainObject(keyValue)) {\n issues.push({\n kind: \"invalid_input\",\n message: `Expected object for key \"${key}\", got ${typeof keyValue}`,\n });\n continue;\n }\n\n const result = normalizeSingleKey(key, keyValue, keyPathPrefix);\n issues.push(...result.issues);\n keys[key] = result.entry;\n }\n\n if (issues.length > 0) {\n return { ok: false, issues };\n }\n\n return { ok: true, data: keys };\n}\n\n/**\n * Validation step 1 (partial): coerce external input into a normalized key dictionary\n * for only the keys present in the payload.\n */\nexport function normalizeKeyDictionaryPartial(\n input: unknown,\n knownKeys: readonly string[],\n _argsByKey: Readonly<Record<string, VariableSpec>>,\n keyPathPrefix: readonly string[]\n): ValidationResult<NormalizedKeyDictionary> {\n if (!isPlainObject(input)) {\n return {\n ok: false,\n issues: [\n {\n kind: \"invalid_input\",\n message: `Expected object, got ${input === null ? \"null\" : typeof input}`,\n },\n ],\n };\n }\n\n const knownKeysSet = new Set(knownKeys);\n const issues: ValidationIssue[] = [];\n const keys: Record<string, ParsedKeyEntry> = {};\n\n for (const key of Object.keys(input)) {\n if (!knownKeysSet.has(key)) {\n issues.push({ kind: \"unknown_key\", path: [...keyPathPrefix, key] });\n continue;\n }\n\n const keyValue = input[key];\n if (!isPlainObject(keyValue)) {\n issues.push({\n kind: \"invalid_input\",\n message: `Expected object for key \"${key}\", got ${typeof keyValue}`,\n });\n continue;\n }\n\n if (Object.keys(keyValue).length === 0) {\n issues.push({\n kind: \"invalid_input\",\n message: `Key \"${key}\" must include at least one locale`,\n });\n continue;\n }\n\n const result = normalizeSingleKey(key, keyValue, keyPathPrefix);\n issues.push(...result.issues);\n keys[key] = result.entry;\n }\n\n if (issues.length > 0) {\n return { ok: false, issues };\n }\n\n return { ok: true, data: keys };\n}\n\n/**\n * Validation step 1: coerce external input into a normalized dictionary shape\n * (keys, locales, ICU args) against a `DictionarySpec`.\n */\nexport function normalizeDictionary(\n input: unknown,\n spec: DictionarySpec\n): ValidationResult<NormalizedDictionary> {\n if (!isPlainObject(input)) {\n return failure([\n {\n kind: \"invalid_input\",\n message: `Expected object, got ${input === null ? \"null\" : typeof input}`,\n },\n ]);\n }\n\n if (spec.mode === \"single\") {\n const result = normalizeKeyDictionary(input, spec.requiredKeys, []);\n if (!result.ok) {\n return result;\n }\n\n return success({ mode: \"single\", keys: result.data });\n }\n\n const issues: ValidationIssue[] = [];\n const namespaces: Record<string, NormalizedKeyDictionary> = {};\n\n for (const [namespace, requiredKeys] of Object.entries(spec.requiredKeys)) {\n if (!(namespace in input)) {\n for (const key of requiredKeys) {\n issues.push({ kind: \"missing_key\", path: [namespace, key] });\n }\n continue;\n }\n\n const namespaceValue = input[namespace];\n if (!isPlainObject(namespaceValue)) {\n issues.push({\n kind: \"invalid_input\",\n message: `Expected object for namespace \"${namespace}\", got ${typeof namespaceValue}`,\n });\n continue;\n }\n\n const result = normalizeKeyDictionary(namespaceValue, requiredKeys, [namespace]);\n if (!result.ok) {\n issues.push(...result.issues);\n } else {\n namespaces[namespace] = result.data;\n }\n }\n\n if (issues.length > 0) {\n return failure(issues);\n }\n\n return success({ mode: \"multi\", namespaces });\n}\n\n/**\n * Validation step 1 (partial, multi): coerce external input into normalized namespace\n * slices for only the namespaces and keys present in the payload.\n */\nexport function normalizeDictionaryPartial(\n input: unknown,\n spec: Extract<DictionarySpec, { mode: \"multi\" }>\n): ValidationResult<NormalizedDictionary> {\n if (!isPlainObject(input)) {\n return failure([\n {\n kind: \"invalid_input\",\n message: `Expected object, got ${input === null ? \"null\" : typeof input}`,\n },\n ]);\n }\n\n const knownNamespaces = Object.keys(spec.requiredKeys);\n const knownNamespacesSet = new Set(knownNamespaces);\n const issues: ValidationIssue[] = [];\n const namespaces: Record<string, NormalizedKeyDictionary> = {};\n\n for (const namespace of Object.keys(input)) {\n if (!knownNamespacesSet.has(namespace)) {\n issues.push({ kind: \"unknown_key\", path: [namespace] });\n continue;\n }\n\n const namespaceValue = input[namespace];\n if (!isPlainObject(namespaceValue)) {\n issues.push({\n kind: \"invalid_input\",\n message: `Expected object for namespace \"${namespace}\", got ${typeof namespaceValue}`,\n });\n continue;\n }\n\n const result = normalizeKeyDictionaryPartial(\n namespaceValue,\n spec.requiredKeys[namespace] ?? [],\n spec.argsByKey[namespace] ?? {},\n [namespace]\n );\n if (!result.ok) {\n issues.push(...result.issues);\n } else {\n namespaces[namespace] = result.data;\n }\n }\n\n if (issues.length > 0) {\n return failure(issues);\n }\n\n return success({ mode: \"multi\", namespaces });\n}\n","import type { NormalizedDictionary } from \"./types.js\";\n\ntype LocaleDictionary = Record<string, string>;\ntype KeyDictionary = Record<string, LocaleDictionary>;\ntype MultiDictionary = Record<string, KeyDictionary>;\n\nexport function toDictionary(normalized: NormalizedDictionary): KeyDictionary | MultiDictionary {\n if (normalized.mode === \"single\") {\n const dictionary: KeyDictionary = {};\n\n for (const [key, entry] of Object.entries(normalized.keys)) {\n const locales: LocaleDictionary = {};\n for (const [locale, localeEntry] of Object.entries(entry.locales)) {\n locales[locale] = localeEntry.template;\n }\n dictionary[key] = locales;\n }\n\n return dictionary;\n }\n\n const dictionary: MultiDictionary = {};\n\n for (const [namespace, keys] of Object.entries(normalized.namespaces)) {\n const namespaceDictionary: KeyDictionary = {};\n\n for (const [key, entry] of Object.entries(keys)) {\n const locales: LocaleDictionary = {};\n for (const [locale, localeEntry] of Object.entries(entry.locales)) {\n locales[locale] = localeEntry.template;\n }\n namespaceDictionary[key] = locales;\n }\n\n dictionary[namespace] = namespaceDictionary;\n }\n\n return dictionary;\n}\n\nexport function toNamespaceDictionary(\n normalized: NormalizedDictionary,\n namespace: string\n): KeyDictionary {\n if (normalized.mode !== \"multi\") {\n throw new Error(\n `[i18n] toNamespaceDictionary requires multi-mode normalized dictionary, got \"${normalized.mode}\"`\n );\n }\n\n const keys = normalized.namespaces[namespace];\n if (!keys) {\n return {};\n }\n\n const dictionary: KeyDictionary = {};\n\n for (const [key, entry] of Object.entries(keys)) {\n const locales: LocaleDictionary = {};\n for (const [locale, localeEntry] of Object.entries(entry.locales)) {\n locales[locale] = localeEntry.template;\n }\n dictionary[key] = locales;\n }\n\n return dictionary;\n}\n","import { z } from \"zod\";\nimport type { VariableSpec, VariableType } from \"../icu/extract-variables.js\";\n\nexport const variableTypeSchema = z.enum([\"string\", \"number\", \"date\"]);\n\nfunction formatVariableMismatch(expected: VariableSpec, found: VariableSpec): string {\n const expectedKeys = Object.keys(expected).sort();\n const foundKeys = Object.keys(found).sort();\n return `Expected variables [${expectedKeys.join(\", \")}], found [${foundKeys.join(\", \")}]`;\n}\n\nexport function createArgsSchema(expected: VariableSpec): z.ZodType<VariableSpec> {\n return z.record(z.string(), variableTypeSchema).superRefine((found, ctx) => {\n const expectedKeys = Object.keys(expected).sort();\n const foundKeys = Object.keys(found).sort();\n\n if (expectedKeys.join() !== foundKeys.join()) {\n ctx.addIssue({\n code: \"custom\",\n message: formatVariableMismatch(expected, found),\n });\n return;\n }\n\n for (const [name, type] of Object.entries(expected)) {\n if (found[name] !== type) {\n ctx.addIssue({\n code: \"custom\",\n message: `Variable \"${name}\": expected ${type}, found ${found[name]}`,\n });\n }\n }\n });\n}\n\nexport function mapArgsSchemaError(\n expected: VariableSpec,\n found: VariableSpec,\n message: string,\n path: readonly string[]\n) {\n const expectedKeys = Object.keys(expected).sort();\n const foundKeys = Object.keys(found).sort();\n\n if (expectedKeys.join() !== foundKeys.join()) {\n return {\n kind: \"variable_mismatch\" as const,\n path,\n expected,\n found,\n message,\n };\n }\n\n for (const [name, type] of Object.entries(expected)) {\n const foundType = found[name];\n if (foundType !== undefined && foundType !== type) {\n return {\n kind: \"variable_type_mismatch\" as const,\n path,\n variable: name,\n expected: type,\n found: foundType as VariableType,\n message,\n };\n }\n }\n\n return {\n kind: \"variable_mismatch\" as const,\n path,\n expected,\n found,\n message,\n };\n}\n","import { z } from \"zod\";\nimport type { VariableSpec } from \"../icu/extract-variables.js\";\nimport { createArgsSchema, variableTypeSchema } from \"./create-args-schema.js\";\nimport type { DictionarySpec, NormalizedDictionary, ParsedKeyEntry } from \"./types.js\";\n\nconst parsedLocaleEntrySchema = z.object({\n template: z.string(),\n args: z.record(z.string(), variableTypeSchema),\n});\n\nconst parsedKeyEntrySchema = z.object({\n locales: z.record(z.string(), parsedLocaleEntrySchema),\n mergedArgs: z.record(z.string(), variableTypeSchema),\n});\n\nexport function createKeyDictionarySchema(\n argsByKey: Readonly<Record<string, VariableSpec>>\n): z.ZodType<Record<string, ParsedKeyEntry>> {\n const keySchemas = Object.fromEntries(\n Object.entries(argsByKey).map(([key, expectedArgs]) => [\n key,\n parsedKeyEntrySchema.extend({\n mergedArgs: createArgsSchema(expectedArgs),\n }),\n ])\n );\n\n return z.object(keySchemas);\n}\n\nexport function createNormalizedDictionarySchema(\n spec: DictionarySpec\n): z.ZodType<NormalizedDictionary> {\n if (spec.mode === \"single\") {\n return z.object({\n mode: z.literal(\"single\"),\n keys: createKeyDictionarySchema(spec.argsByKey),\n }) as z.ZodType<NormalizedDictionary>;\n }\n\n const namespaceSchemas = Object.fromEntries(\n Object.entries(spec.argsByKey).map(([namespace, argsByKey]) => [\n namespace,\n createKeyDictionarySchema(argsByKey),\n ])\n );\n\n return z.object({\n mode: z.literal(\"multi\"),\n namespaces: z.object(namespaceSchemas),\n }) as z.ZodType<NormalizedDictionary>;\n}\n","import type { ZodError } from \"zod\";\nimport { mapArgsSchemaError } from \"./create-args-schema.js\";\nimport {\n createKeyDictionarySchema,\n createNormalizedDictionarySchema,\n} from \"./create-normalized-schema.js\";\nimport type {\n DictionarySpec,\n NormalizedDictionary,\n NormalizedKeyDictionary,\n ValidationIssue,\n ValidationResult,\n VariableSpec,\n} from \"./types.js\";\n\nfunction getExpectedArgs(spec: DictionarySpec, path: readonly string[]): VariableSpec | undefined {\n if (spec.mode === \"single\") {\n const key = path[path.length - 1];\n if (typeof key !== \"string\") {\n return undefined;\n }\n return spec.argsByKey[key];\n }\n\n const namespace = path[0];\n const key = path[path.length - 1];\n if (typeof namespace !== \"string\" || typeof key !== \"string\") {\n return undefined;\n }\n\n return spec.argsByKey[namespace]?.[key];\n}\n\nfunction getFoundArgs(\n normalized: NormalizedDictionary,\n path: readonly string[]\n): VariableSpec | undefined {\n if (normalized.mode === \"single\") {\n const key = path[path.length - 1];\n if (typeof key !== \"string\") {\n return undefined;\n }\n return normalized.keys[key]?.mergedArgs;\n }\n\n const namespace = path[0];\n const key = path[path.length - 1];\n if (typeof namespace !== \"string\" || typeof key !== \"string\") {\n return undefined;\n }\n\n return normalized.namespaces[namespace]?.[key]?.mergedArgs;\n}\n\nfunction mapZodError(\n error: ZodError,\n spec: DictionarySpec,\n normalized: NormalizedDictionary\n): ValidationIssue[] {\n return error.issues.map((issue) => {\n const path = issue.path.map(String);\n\n if (path.includes(\"mergedArgs\")) {\n const keyPath = path.slice(0, path.indexOf(\"mergedArgs\"));\n const expected = getExpectedArgs(spec, keyPath);\n const found = getFoundArgs(normalized, keyPath);\n\n if (expected && found) {\n return mapArgsSchemaError(expected, found, issue.message, keyPath);\n }\n }\n\n return {\n kind: \"invalid_input\" as const,\n message: path.length > 0 ? `${path.join(\".\")}: ${issue.message}` : issue.message,\n };\n });\n}\n\nexport function validateNormalizedKeyDictionaryPartial(\n keys: NormalizedKeyDictionary,\n argsByKey: Readonly<Record<string, VariableSpec>>,\n spec: DictionarySpec,\n keyPathPrefix: readonly string[]\n): ValidationResult<NormalizedKeyDictionary> {\n const presentKeys = Object.keys(keys);\n const subsetArgsByKey = Object.fromEntries(\n presentKeys.filter((key) => key in argsByKey).map((key) => [key, argsByKey[key]!])\n );\n\n if (presentKeys.length === 0) {\n return { ok: true, data: keys };\n }\n\n const schema = createKeyDictionarySchema(subsetArgsByKey);\n const result = schema.safeParse(keys);\n\n if (result.success) {\n return { ok: true, data: result.data };\n }\n\n const normalized: NormalizedDictionary =\n spec.mode === \"single\"\n ? { mode: \"single\", keys }\n : {\n mode: \"multi\",\n namespaces: {\n [keyPathPrefix[0] ?? \"\"]: keys,\n },\n };\n\n return {\n ok: false,\n issues: mapZodError(result.error, spec, normalized),\n };\n}\n\nexport function validateNormalizedDictionary(\n normalized: NormalizedDictionary,\n spec: DictionarySpec\n): ValidationResult<NormalizedDictionary> {\n const schema = createNormalizedDictionarySchema(spec);\n const result = schema.safeParse(normalized);\n\n if (result.success) {\n return { ok: true, data: result.data };\n }\n\n return {\n ok: false,\n issues: mapZodError(result.error, spec, normalized),\n };\n}\n","import type { ValidationIssue, ValidationResult } from \"./types.js\";\n\nfunction issueMessage(issue: ValidationIssue): string {\n switch (issue.kind) {\n case \"missing_key\":\n return `Missing required key at ${issue.path.join(\".\")}`;\n case \"unknown_key\":\n return `Unknown key at ${issue.path.join(\".\")}`;\n case \"invalid_input\":\n case \"invalid_locale_value\":\n case \"icu_syntax_error\":\n case \"locale_args_mismatch\":\n case \"variable_mismatch\":\n case \"variable_type_mismatch\":\n return issue.message;\n }\n}\n\nexport function formatIssues(issues: readonly ValidationIssue[]): string {\n return issues\n .map((issue) => {\n if (\"path\" in issue && issue.path.length > 0) {\n return `[${issue.path.join(\".\")}] ${issue.kind}: ${issueMessage(issue)}`;\n }\n return `${issue.kind}: ${issueMessage(issue)}`;\n })\n .join(\"\\n\");\n}\n\nexport class DictionaryValidationError extends Error {\n constructor(public readonly issues: readonly ValidationIssue[]) {\n super(formatIssues(issues));\n this.name = \"DictionaryValidationError\";\n }\n}\n\nexport function assertValidDictionary<T>(\n result: ValidationResult<T>\n): asserts result is { ok: true; data: T } {\n if (!result.ok) {\n throw new DictionaryValidationError(result.issues);\n }\n}\n","/**\n * External payload validation for server-side codegen/ingest (CMS → authoring files).\n * Not a runtime patch API — validate before writing authoring, then `regenerateNamespaces` / `load()`.\n */\nimport { normalizeDictionaryPartial, normalizeKeyDictionaryPartial } from \"./normalize.js\";\nimport { toDictionary, toNamespaceDictionary } from \"./to-dictionary.js\";\nimport type {\n DictionarySpec,\n NormalizedKeyDictionary,\n ValidationIssue,\n ValidationResult,\n} from \"./types.js\";\nimport { validateNormalizedKeyDictionaryPartial } from \"./validate-normalized.js\";\n\nexport function validateExternalDictionaryPartial<TSchema>(\n input: unknown,\n spec: DictionarySpec\n): ValidationResult<Partial<TSchema>> {\n if (spec.mode === \"single\") {\n const step1 = normalizeKeyDictionaryPartial(input, spec.requiredKeys, spec.argsByKey, []);\n if (!step1.ok) {\n return step1;\n }\n\n const step2 = validateNormalizedKeyDictionaryPartial(step1.data, spec.argsByKey, spec, []);\n if (!step2.ok) {\n return step2;\n }\n\n return {\n ok: true,\n data: toDictionary({ mode: \"single\", keys: step2.data }) as Partial<TSchema>,\n };\n }\n\n const step1 = normalizeDictionaryPartial(input, spec);\n if (!step1.ok) {\n return step1;\n }\n\n if (step1.data.mode !== \"multi\") {\n return {\n ok: false,\n issues: [\n {\n kind: \"invalid_input\",\n message: \"validateExternalDictionaryPartial requires multi-mode dictionary spec\",\n },\n ],\n };\n }\n\n const issues: ValidationIssue[] = [];\n const namespaces: Record<string, NormalizedKeyDictionary> = {};\n\n for (const [namespace, keys] of Object.entries(step1.data.namespaces)) {\n const step2 = validateNormalizedKeyDictionaryPartial(\n keys,\n spec.argsByKey[namespace] ?? {},\n spec,\n [namespace]\n );\n if (!step2.ok) {\n issues.push(...step2.issues);\n } else {\n namespaces[namespace] = step2.data;\n }\n }\n\n if (issues.length > 0) {\n return { ok: false, issues };\n }\n\n return {\n ok: true,\n data: toDictionary({ mode: \"multi\", namespaces }) as Partial<TSchema>,\n };\n}\n\nexport function validateExternalNamespacePartial<TNamespaceSchema>(\n namespace: string,\n input: unknown,\n spec: DictionarySpec\n): ValidationResult<Partial<TNamespaceSchema>> {\n if (spec.mode !== \"multi\") {\n return {\n ok: false,\n issues: [\n {\n kind: \"invalid_input\",\n message: \"validateExternalNamespacePartial requires multi-mode dictionary spec\",\n },\n ],\n };\n }\n\n const knownKeys = spec.requiredKeys[namespace];\n if (!knownKeys) {\n return {\n ok: false,\n issues: [{ kind: \"unknown_key\", path: [namespace] }],\n };\n }\n\n const step1 = normalizeKeyDictionaryPartial(input, knownKeys, spec.argsByKey[namespace] ?? {}, [\n namespace,\n ]);\n if (!step1.ok) {\n return step1;\n }\n\n const step2 = validateNormalizedKeyDictionaryPartial(\n step1.data,\n spec.argsByKey[namespace] ?? {},\n spec,\n [namespace]\n );\n if (!step2.ok) {\n return step2;\n }\n\n return {\n ok: true,\n data: toNamespaceDictionary(\n { mode: \"multi\", namespaces: { [namespace]: step2.data } },\n namespace\n ) as Partial<TNamespaceSchema>,\n };\n}\n\nexport function validateExternalKey<TKeySlice>(\n key: string,\n input: unknown,\n spec: Extract<DictionarySpec, { mode: \"single\" }>\n): ValidationResult<TKeySlice>;\n\nexport function validateExternalKey<TKeySlice>(\n namespace: string,\n key: string,\n input: unknown,\n spec: Extract<DictionarySpec, { mode: \"multi\" }>\n): ValidationResult<TKeySlice>;\n\nexport function validateExternalKey<TKeySlice>(\n namespaceOrKey: string,\n keyOrInput: string | unknown,\n inputOrSpec?: unknown,\n specMaybe?: DictionarySpec\n): ValidationResult<TKeySlice> {\n if (specMaybe?.mode === \"multi\") {\n const namespace = namespaceOrKey;\n const key = keyOrInput as string;\n const input = inputOrSpec;\n const spec = specMaybe;\n\n return validateExternalNamespacePartial<TKeySlice>(\n namespace,\n { [key]: input },\n spec\n ) as ValidationResult<TKeySlice>;\n }\n\n const key = namespaceOrKey;\n const input = keyOrInput;\n const spec = inputOrSpec as Extract<DictionarySpec, { mode: \"single\" }>;\n\n return validateExternalDictionaryPartial<TKeySlice>(\n { [key]: input },\n spec\n ) as ValidationResult<TKeySlice>;\n}\n\nexport {\n normalizeDictionaryPartial,\n normalizeKeyDictionaryPartial,\n toDictionary,\n toNamespaceDictionary,\n};\nexport { validateNormalizedKeyDictionaryPartial } from \"./validate-normalized.js\";\nexport { createArgsSchema } from \"./create-args-schema.js\";\nexport { createNormalizedDictionarySchema } from \"./create-normalized-schema.js\";\nexport { DictionaryValidationError, assertValidDictionary, formatIssues } from \"./errors.js\";\nexport type {\n DictionarySpec,\n NormalizedDictionary,\n NormalizedKeyDictionary,\n NormalizedMultiDictionary,\n ParsedKeyEntry,\n ParsedLocaleEntry,\n ValidationIssue,\n ValidationResult,\n VariableSpec,\n VariableType,\n} from \"./types.js\";\n\nexport type { ParseTemplateResult } from \"../icu/parse-template.js\";\nexport { parseTemplate } from \"../icu/parse-template.js\";\nexport {\n extractVariables,\n mergeVariableSpecs,\n variableSpecsEqual,\n} from \"../icu/extract-variables.js\";\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xndrjs/i18n",
3
- "version": "0.7.0",
4
- "description": "Compiler-first, type-safe ICU MessageFormat i18n with runtime dictionary override from external sources.",
3
+ "version": "0.8.0",
4
+ "description": "Compiler-first, type-safe ICU MessageFormat i18n with lazy delivery loading and external payload validation for content ingest.",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -89,27 +89,6 @@ describe("IcuTranslationProviderMulti", () => {
89
89
  );
90
90
  });
91
91
 
92
- it("patches a preloaded key and invalidates its cache", () => {
93
- const local = new IcuTranslationProviderMulti<TestSchema, TestParams>(dictionary);
94
- const view = () => local.toScope({ namespaces: ["default", "billing"] });
95
-
96
- expect(view().t("billing", "invoice_summary", "en", { count: 2, name: "Bob" })).toBe(
97
- "You have 2 invoices for Bob"
98
- );
99
-
100
- local.patchKeyMulti(
101
- "billing",
102
- "invoice_summary",
103
- "en",
104
- "{count, plural, one {1 bill} other {{count} bills}} for {name}"
105
- );
106
-
107
- expect(view().t("billing", "invoice_summary", "en", { count: 2, name: "Bob" })).toBe(
108
- "2 bills for Bob"
109
- );
110
- expect(view().t("default", "login_button", "en")).toBe("Login");
111
- });
112
-
113
92
  it("adds namespace to dictionary with applyLoadMergeNamespace", () => {
114
93
  const partial = new IcuTranslationProviderMulti<TestSchema, TestParams>({
115
94
  default: dictionary.default,
@@ -181,16 +160,6 @@ describe("IcuTranslationProviderMulti", () => {
181
160
  );
182
161
  });
183
162
 
184
- it("patches a preloaded default namespace key", () => {
185
- const local = new IcuTranslationProviderMulti<TestSchema, TestParams>(dictionary);
186
-
187
- local.patchKeyMulti("default", "login_button", "en", "Sign in");
188
-
189
- expect(local.toScope({ namespaces: ["default"] }).t("default", "login_button", "en")).toBe(
190
- "Sign in"
191
- );
192
- });
193
-
194
163
  it("merges namespaces with applyLoadMergeAll without dropping existing locales", () => {
195
164
  const local = new IcuTranslationProviderMulti<TestSchema, TestParams>({
196
165
  billing: {
@@ -219,19 +188,28 @@ describe("IcuTranslationProviderMulti", () => {
219
188
  expect(view().t("default", "login_button", "en")).toBe("Login");
220
189
  });
221
190
 
222
- it("returns a deep-frozen snapshot from getAll", () => {
191
+ it("returns the live dictionary from getAll (constructor clones the input)", () => {
223
192
  expect(engine.getAll()).toEqual(dictionary);
224
193
  expect(engine.getAll()).not.toBe(dictionary);
225
- expect(Object.isFrozen(engine.getAll().default)).toBe(true);
194
+ expect(engine.getAll()).toBe(engine.getAll());
226
195
  });
227
196
 
228
- it("does not mutate the engine when getAll snapshot is modified", () => {
229
- const snapshot = engine.getAll();
230
- expect(() => {
231
- snapshot.default.login_button.en = "Hacked";
232
- }).toThrow(TypeError);
233
- expect(engine.toScope({ namespaces: ["default"] }).t("default", "login_button", "en")).toBe(
234
- "Login"
197
+ it("invalidates compiled cache when applyLoadMergeNamespace overwrites a key", () => {
198
+ const local = new IcuTranslationProviderMulti<TestSchema, TestParams>(dictionary);
199
+ const view = () => local.toScope({ namespaces: ["billing"] });
200
+
201
+ expect(view().t("billing", "invoice_summary", "en", { count: 2, name: "Bob" })).toBe(
202
+ "You have 2 invoices for Bob"
203
+ );
204
+
205
+ local.applyLoadMergeNamespace("billing", {
206
+ invoice_summary: {
207
+ en: "{count, plural, one {1 bill} other {{count} bills}} for {name}",
208
+ },
209
+ });
210
+
211
+ expect(view().t("billing", "invoice_summary", "en", { count: 2, name: "Bob" })).toBe(
212
+ "2 bills for Bob"
235
213
  );
236
214
  });
237
215
  });
@@ -1,12 +1,7 @@
1
- import { cloneAndFreeze } from "./deep-freeze.js";
2
- import { BuilderLoadRegistry } from "./builder-load-registry.js";
1
+ import { BuilderLoadRegistry, type BuilderResourceEntry } from "./builder-load-registry.js";
3
2
  import type { I18nEngineMulti } from "./engine.js";
3
+ import type { I18nSerializedState } from "./serialized-state.js";
4
4
  import { resolveAndFormat } from "./format-core.js";
5
- import {
6
- assertPatchKeyMulti,
7
- recordPreloadedKeysMulti,
8
- seedPreloadedKeysMulti,
9
- } from "./patch-key.js";
10
5
  import { mergeNamespaceLocalesCore } from "./project-locales.js";
11
6
  import { validateLocaleFallback } from "./resolve-locale.js";
12
7
  import type {
@@ -31,19 +26,18 @@ export class IcuTranslationProviderMulti<
31
26
  > implements I18nEngineMulti<Schema, Params, RequestLocales> {
32
27
  readonly __i18nEngineMode = "multi" as const;
33
28
 
34
- private dictionary: Schema;
29
+ /** Loaded namespaces only — cold start is `{}`; never claim full Schema until loaded. */
30
+ private dictionary: PartialMultiDictionary<Schema, RequestLocales>;
35
31
  private compiledCache: MultiCompiledCache = {};
36
- private readonly preloadedKeys = new Set<string>();
37
32
  private readonly builderLoadRegistry = new BuilderLoadRegistry();
38
33
  private readonly localeFallback?: Fallback;
39
34
  private readonly onMissing: OnMissingTranslation;
40
35
 
41
36
  constructor(
42
- dictionary: PartialMultiDictionary<Schema, RequestLocales>,
37
+ dictionary: PartialMultiDictionary<Schema, RequestLocales> = {},
43
38
  options?: IcuTranslationProviderOptions<Fallback>
44
39
  ) {
45
- this.dictionary = structuredClone(dictionary) as Schema;
46
- seedPreloadedKeysMulti(this.dictionary, this.preloadedKeys);
40
+ this.dictionary = structuredClone(dictionary);
47
41
  if (options?.localeFallback) {
48
42
  validateLocaleFallback(options.localeFallback);
49
43
  this.localeFallback = options.localeFallback;
@@ -58,7 +52,9 @@ export class IcuTranslationProviderMulti<
58
52
  params?: Record<string, unknown>
59
53
  ): string {
60
54
  const localeByKey = (
61
- this.dictionary[namespace] as Record<string, Record<string, string>> | undefined
55
+ this.dictionary[namespace as keyof Schema] as
56
+ | Record<string, Record<string, string>>
57
+ | undefined
62
58
  )?.[key];
63
59
 
64
60
  return resolveAndFormat({
@@ -122,30 +118,41 @@ export class IcuTranslationProviderMulti<
122
118
  >;
123
119
  }
124
120
 
125
- getAll(): Schema {
126
- return cloneAndFreeze(this.dictionary);
121
+ /** Live dictionary reference (loaded namespaces only). Do not mutate. */
122
+ getAll(): PartialMultiDictionary<Schema, RequestLocales> {
123
+ return this.dictionary;
127
124
  }
128
125
 
129
- hasBuilderResourceLoaded(namespace: string, partition: string | undefined): boolean {
126
+ hasBuilderResourceLoaded(namespace: string, partition: string): boolean {
130
127
  return this.builderLoadRegistry.has(namespace, partition);
131
128
  }
132
129
 
133
- markBuilderResourceLoaded(namespace: string, partition: string | undefined): void {
130
+ markBuilderResourceLoaded(namespace: string, partition: string): void {
134
131
  this.builderLoadRegistry.mark(namespace, partition);
135
132
  }
136
133
 
134
+ seedBuilderResources(resources: readonly BuilderResourceEntry[]): void {
135
+ this.builderLoadRegistry.seed(resources);
136
+ }
137
+
138
+ serialize(): I18nSerializedState<PartialMultiDictionary<Schema, RequestLocales>> {
139
+ return {
140
+ dictionary: this.dictionary,
141
+ resources: this.builderLoadRegistry.entries(),
142
+ };
143
+ }
144
+
137
145
  applyLoadMergeNamespace<NS extends keyof Schema>(
138
146
  namespace: NS,
139
147
  values: PartialKeyDictionary<Schema[NS], RequestLocales>
140
148
  ): void {
141
- const existing = this.dictionary[namespace];
142
- const merged = mergeNamespaceLocalesCore((existing ?? {}) as Schema[NS], values);
149
+ const existing = (this.dictionary[namespace] ?? {}) as Schema[NS];
150
+ const merged = mergeNamespaceLocalesCore(existing, values);
143
151
 
144
152
  this.dictionary = {
145
153
  ...this.dictionary,
146
154
  [namespace]: merged,
147
155
  };
148
- recordPreloadedKeysMulti(namespace as string, values, this.preloadedKeys);
149
156
 
150
157
  for (const [key, incomingLocales] of Object.entries(values)) {
151
158
  if (incomingLocales === undefined || typeof incomingLocales !== "object") {
@@ -166,21 +173,4 @@ export class IcuTranslationProviderMulti<
166
173
  }
167
174
  }
168
175
  }
169
-
170
- patchKeyMulti(namespace: string, key: string, locale: string, template: string): void {
171
- const namespaceDictionary = this.dictionary[namespace] as
172
- | Record<string, Record<string, string>>
173
- | undefined;
174
- const localeByKey = namespaceDictionary?.[key];
175
-
176
- assertPatchKeyMulti(namespace, key, locale, template, this.preloadedKeys, localeByKey);
177
-
178
- this.applyLoadMergeNamespace(
179
- namespace as keyof Schema,
180
- { [key]: { [locale]: template } } as PartialKeyDictionary<
181
- Schema[keyof Schema],
182
- RequestLocales
183
- >
184
- );
185
- }
186
176
  }
@@ -16,7 +16,7 @@ export interface I18nAuditReport {
16
16
 
17
17
  export interface AuditDictionariesOptions {
18
18
  namespaces: Record<string, DictionaryJson>;
19
- config: Pick<CodegenConfig, "localeFallback" | "defaultNamespace">;
19
+ config: Pick<CodegenConfig, "localeFallback">;
20
20
  treatEmptyAsMissing?: boolean;
21
21
  }
22
22
 
@@ -47,16 +47,15 @@ describe("runAuditCli", () => {
47
47
  function writeFixture(dictionary: Record<string, Record<string, string>>) {
48
48
  tempDir = mkdtempSync(join(tmpdir(), "xndrjs-i18n-audit-"));
49
49
  mkdirSync(join(tempDir, "i18n/translations"), { recursive: true });
50
- writeFileSync(join(tempDir, "i18n/translations/translations.json"), JSON.stringify(dictionary));
50
+ writeFileSync(join(tempDir, "i18n/translations/default.json"), JSON.stringify(dictionary));
51
51
  writeFileSync(
52
52
  join(tempDir, "i18n/i18n.codegen.json"),
53
53
  JSON.stringify({
54
- dictionary: "translations/translations.json",
55
- typesOutput: "generated/i18n-types.generated.ts",
56
- dictionaryOutput: "generated/dictionary.generated.ts",
57
- instanceOutput: "generated/instance.generated.ts",
58
- paramsTypeName: "AppParams",
59
- schemaTypeName: "AppSchema",
54
+ projectName: "App",
55
+ namespaces: {
56
+ default: "translations/default.json",
57
+ },
58
+ codegenPath: "generated",
60
59
  localeFallback: {
61
60
  en: null,
62
61
  it: "en",
@@ -1,18 +1,39 @@
1
1
  /** Stable key for a lazy-loaded builder resource (namespace + locale or delivery area). */
2
- export function formatBuilderResourceKey(namespace: string, partition: string | undefined): string {
3
- return `${namespace}\0${partition ?? ""}`;
2
+ export function formatBuilderResourceKey(namespace: string, partition: string): string {
3
+ return `${namespace}\0${partition}`;
4
4
  }
5
5
 
6
- export const SINGLE_BUILDER_RESOURCE = "__dictionary__";
6
+ /** Serialized builder resource: namespace + partition (locale / delivery area). */
7
+ export type BuilderResourceEntry = readonly [namespace: string, partition: string];
7
8
 
9
+ /**
10
+ * Dedup cache for lazy-loaded builder resources (`namespace` × partition).
11
+ * A repeated `load()` for the same resource skips the loader (avoids re-fetch / re-merge).
12
+ */
8
13
  export class BuilderLoadRegistry {
9
14
  private readonly loaded = new Set<string>();
10
15
 
11
- has(namespace: string, partition: string | undefined): boolean {
16
+ has(namespace: string, partition: string): boolean {
12
17
  return this.loaded.has(formatBuilderResourceKey(namespace, partition));
13
18
  }
14
19
 
15
- mark(namespace: string, partition: string | undefined): void {
20
+ mark(namespace: string, partition: string): void {
16
21
  this.loaded.add(formatBuilderResourceKey(namespace, partition));
17
22
  }
23
+
24
+ /** Snapshot of loaded resources as `[namespace, partition]` tuples. */
25
+ entries(): BuilderResourceEntry[] {
26
+ const out: BuilderResourceEntry[] = [];
27
+ for (const key of this.loaded) {
28
+ const sep = key.indexOf("\0");
29
+ out.push([key.slice(0, sep), key.slice(sep + 1)]);
30
+ }
31
+ return out;
32
+ }
33
+
34
+ seed(resources: readonly BuilderResourceEntry[]): void {
35
+ for (const [namespace, partition] of resources) {
36
+ this.mark(namespace, partition);
37
+ }
38
+ }
18
39
  }
@@ -1,18 +1,15 @@
1
- /** Canonical lazy loader — no locale or delivery-area partition. */
2
- export type CanonicalLoader<T> = () => Promise<T> | T;
3
-
4
1
  /** Split-by-locale or custom-area loader — partition key is locale or area name. */
5
- export type PartitionedLoader<T> = (partition: string) => Promise<T> | T;
2
+ export type PartitionedLoader<T> = (
3
+ partition: string,
4
+ context: { locale: string }
5
+ ) => Promise<T> | T;
6
6
 
7
- export type NamespaceLoader<T> = CanonicalLoader<T> | PartitionedLoader<T>;
7
+ export type NamespaceLoader<T> = PartitionedLoader<T>;
8
8
 
9
9
  export async function invokeNamespaceLoader<T>(
10
10
  loader: NamespaceLoader<T>,
11
- partition: string | undefined
11
+ partition: string,
12
+ context: { locale: string }
12
13
  ): Promise<T> {
13
- if (partition === undefined) {
14
- return await (loader as CanonicalLoader<T>)();
15
- }
16
-
17
- return await (loader as PartitionedLoader<T>)(partition);
14
+ return await loader(partition, context);
18
15
  }