@xndrjs/i18n 0.3.3 → 0.5.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +193 -44
- package/dist/codegen/index.d.ts +85 -0
- package/dist/codegen/index.js +181 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/index.d.ts +34 -18
- package/dist/index.js +174 -145
- package/dist/index.js.map +1 -1
- package/dist/validation/index.d.ts +86 -4
- package/dist/validation/index.js.map +1 -1
- package/package.json +6 -1
- package/src/IcuTranslationProviderMulti.test.ts +48 -1
- package/src/IcuTranslationProviderMulti.ts +41 -61
- package/src/IcuTranslationProviderSingle.test.ts +67 -0
- package/src/IcuTranslationProviderSingle.ts +27 -51
- package/src/audit/audit-dictionaries.ts +4 -1
- package/src/audit/run-audit.test.ts +35 -1
- package/src/audit/run-audit.ts +15 -7
- package/src/codegen/codegen-config-schema.ts +68 -1
- package/src/codegen/config.test.ts +174 -39
- package/src/codegen/config.ts +14 -5
- package/src/codegen/constants.ts +8 -0
- package/src/codegen/delivery-artifacts.test.ts +142 -0
- package/src/codegen/delivery-artifacts.ts +124 -0
- package/src/codegen/emit/dictionary-file.test.ts +190 -0
- package/src/codegen/emit/dictionary-file.ts +165 -2
- package/src/codegen/emit/dictionary-schema-file.ts +5 -0
- package/src/codegen/emit/instance-file.ts +119 -38
- package/src/codegen/emit/namespace-loaders-file.test.ts +176 -0
- package/src/codegen/emit/namespace-loaders-file.ts +118 -32
- package/src/codegen/emit/types-file.test.ts +114 -0
- package/src/codegen/emit/types-file.ts +48 -11
- package/src/codegen/generate-i18n-types.test.ts +765 -22
- package/src/codegen/generate-i18n-types.ts +111 -58
- package/src/codegen/icu-analysis.ts +9 -2
- package/src/codegen/locale-fallback.ts +19 -10
- package/src/codegen/locale-policy.ts +4 -0
- package/src/codegen/paths.ts +9 -5
- package/src/codegen/project-locales-set-namespace.test.ts +11 -9
- package/src/codegen/read-dictionary.test.ts +474 -2
- package/src/codegen/read-dictionary.ts +164 -15
- package/src/codegen/write-file-if-changed.test.ts +42 -0
- package/src/codegen/write-file-if-changed.ts +20 -0
- package/src/codegen-config/build-config.ts +34 -0
- package/src/codegen-config/codegen-config.test.ts +32 -0
- package/src/codegen-config/index.ts +21 -0
- package/src/codegen-config/write-config.ts +8 -0
- package/src/deep-freeze.test.ts +13 -0
- package/src/deep-freeze.ts +5 -0
- package/src/format-core.ts +91 -0
- package/src/index.ts +8 -5
- package/src/project-locales.test.ts +129 -10
- package/src/project-locales.ts +90 -3
- package/src/setup/setup-i18n.test.ts +1 -1
- package/src/setup/setup-i18n.ts +9 -32
- package/src/types.ts +19 -4
- package/src/validation/normalize.ts +4 -0
- package/dist/types-C1CpXVOJ.d.ts +0 -83
- package/src/ensure-namespace.integration.test.ts +0 -66
- package/src/ensure-namespace.test.ts +0 -125
- package/src/ensure-namespace.ts +0 -70
- /package/src/{setup → codegen-config}/type-names.ts +0 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
|
|
5
|
+
// src/codegen/codegen-config-schema.ts
|
|
6
|
+
|
|
7
|
+
// src/codegen/constants.ts
|
|
8
|
+
var SUPPORTED_IMPORT_EXTENSIONS = ["none", ".ts", ".js"];
|
|
9
|
+
var IDENTIFIER_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
10
|
+
var IDENTIFIER_NAME_REQUIREMENT = "allowed: letters, digits, underscore; must not start with a digit";
|
|
11
|
+
|
|
12
|
+
// src/codegen/delivery-artifacts.ts
|
|
13
|
+
var DELIVERY_AREA_NAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
|
|
14
|
+
function getDeliveryArtifactsStructureIssues(deliveryArtifacts) {
|
|
15
|
+
const issues = [];
|
|
16
|
+
for (const [area, locales] of Object.entries(deliveryArtifacts)) {
|
|
17
|
+
if (!DELIVERY_AREA_NAME_PATTERN.test(area)) {
|
|
18
|
+
issues.push({
|
|
19
|
+
path: ["deliveryArtifacts", area],
|
|
20
|
+
message: `Invalid delivery area name "${area}": must match ${DELIVERY_AREA_NAME_PATTERN.source}`
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
if (locales.length === 0) {
|
|
24
|
+
issues.push({
|
|
25
|
+
path: ["deliveryArtifacts", area],
|
|
26
|
+
message: `Delivery area "${area}" must include at least one locale.`
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const localeToArea = /* @__PURE__ */ new Map();
|
|
31
|
+
for (const [area, locales] of Object.entries(deliveryArtifacts)) {
|
|
32
|
+
for (const locale of locales) {
|
|
33
|
+
const previousArea = localeToArea.get(locale);
|
|
34
|
+
if (previousArea) {
|
|
35
|
+
issues.push({
|
|
36
|
+
path: ["deliveryArtifacts", area],
|
|
37
|
+
message: `Locale "${locale}" appears in both "${previousArea}" and "${area}".`
|
|
38
|
+
});
|
|
39
|
+
} else {
|
|
40
|
+
localeToArea.set(locale, area);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return issues;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/codegen/codegen-config-schema.ts
|
|
48
|
+
var localeFallbackSchema = z.record(z.string(), z.union([z.string(), z.null()]));
|
|
49
|
+
var deliveryArtifactsSchema = z.record(z.string(), z.array(z.string().min(1)));
|
|
50
|
+
var DELIVERY_MODES = ["canonical", "split-by-locale", "custom"];
|
|
51
|
+
var codegenConfigShape = {
|
|
52
|
+
dictionary: z.string().min(1).optional(),
|
|
53
|
+
namespaces: z.record(z.string(), z.string().min(1)).optional(),
|
|
54
|
+
defaultNamespace: z.string().min(1).optional(),
|
|
55
|
+
typesOutput: z.string().min(1),
|
|
56
|
+
dictionaryOutput: z.string().min(1),
|
|
57
|
+
instanceOutput: z.string().min(1),
|
|
58
|
+
dictionarySchemaOutput: z.string().min(1).optional(),
|
|
59
|
+
loadOnInit: z.array(z.string().min(1)).optional(),
|
|
60
|
+
namespaceLoadersOutput: z.string().min(1).optional(),
|
|
61
|
+
importExtension: z.enum(SUPPORTED_IMPORT_EXTENSIONS).optional(),
|
|
62
|
+
paramsTypeName: z.string().min(1),
|
|
63
|
+
schemaTypeName: z.string().min(1),
|
|
64
|
+
localeTypeName: z.string().min(1).optional(),
|
|
65
|
+
localeFallbackConstName: z.string().min(1).optional(),
|
|
66
|
+
localeFallback: localeFallbackSchema.optional(),
|
|
67
|
+
factoryName: z.string().min(1).optional(),
|
|
68
|
+
delivery: z.enum(DELIVERY_MODES).optional().default("canonical"),
|
|
69
|
+
deliveryArtifacts: deliveryArtifactsSchema.optional(),
|
|
70
|
+
deliveryOutput: z.string().min(1).optional()
|
|
71
|
+
};
|
|
72
|
+
var codegenConfigKeys = Object.keys(
|
|
73
|
+
codegenConfigShape
|
|
74
|
+
);
|
|
75
|
+
z.object(codegenConfigShape).strict().superRefine((config, ctx) => {
|
|
76
|
+
const hasDictionary = config.dictionary !== void 0;
|
|
77
|
+
const hasNamespaces = config.namespaces !== void 0;
|
|
78
|
+
if (hasDictionary === hasNamespaces) {
|
|
79
|
+
ctx.addIssue({
|
|
80
|
+
code: "custom",
|
|
81
|
+
message: 'Specify exactly one of "dictionary" or "namespaces".'
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
if (config.namespaces) {
|
|
85
|
+
for (const namespace of Object.keys(config.namespaces)) {
|
|
86
|
+
if (!IDENTIFIER_NAME_PATTERN.test(namespace)) {
|
|
87
|
+
ctx.addIssue({
|
|
88
|
+
code: "custom",
|
|
89
|
+
path: ["namespaces", namespace],
|
|
90
|
+
message: `Invalid namespace name "${namespace}" (${IDENTIFIER_NAME_REQUIREMENT}).`
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (config.defaultNamespace !== void 0 && !IDENTIFIER_NAME_PATTERN.test(config.defaultNamespace)) {
|
|
96
|
+
ctx.addIssue({
|
|
97
|
+
code: "custom",
|
|
98
|
+
path: ["defaultNamespace"],
|
|
99
|
+
message: `Invalid namespace name "${config.defaultNamespace}" (${IDENTIFIER_NAME_REQUIREMENT}).`
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (config.delivery === "custom") {
|
|
103
|
+
if (!config.deliveryArtifacts) {
|
|
104
|
+
ctx.addIssue({
|
|
105
|
+
code: "custom",
|
|
106
|
+
path: ["deliveryArtifacts"],
|
|
107
|
+
message: 'deliveryArtifacts is required when delivery is "custom".'
|
|
108
|
+
});
|
|
109
|
+
} else {
|
|
110
|
+
for (const issue of getDeliveryArtifactsStructureIssues(config.deliveryArtifacts)) {
|
|
111
|
+
ctx.addIssue({
|
|
112
|
+
code: "custom",
|
|
113
|
+
path: issue.path,
|
|
114
|
+
message: issue.message
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} else if (config.deliveryArtifacts !== void 0) {
|
|
119
|
+
ctx.addIssue({
|
|
120
|
+
code: "custom",
|
|
121
|
+
path: ["deliveryArtifacts"],
|
|
122
|
+
message: 'deliveryArtifacts is only allowed when delivery is "custom".'
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
function resolveDeliveryOutputDir(config) {
|
|
127
|
+
return config.deliveryOutput ?? path.dirname(config.typesOutput);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/codegen-config/type-names.ts
|
|
131
|
+
function inferProjectName(dirName) {
|
|
132
|
+
const parts = dirName.split(/[-_]+/).filter(Boolean);
|
|
133
|
+
if (parts.length === 0) {
|
|
134
|
+
return "App";
|
|
135
|
+
}
|
|
136
|
+
return parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
137
|
+
}
|
|
138
|
+
function typeNamesForProject(project) {
|
|
139
|
+
return {
|
|
140
|
+
paramsTypeName: `${project}Params`,
|
|
141
|
+
schemaTypeName: `${project}Schema`,
|
|
142
|
+
localeTypeName: `${project}Locale`
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/codegen-config/build-config.ts
|
|
147
|
+
var GENERATED_DIR = "generated";
|
|
148
|
+
var TRANSLATIONS_DIR = "translations";
|
|
149
|
+
function buildCodegenConfig(mode, project) {
|
|
150
|
+
const typeNames = typeNamesForProject(project);
|
|
151
|
+
const base = {
|
|
152
|
+
typesOutput: `${GENERATED_DIR}/i18n-types.generated.ts`,
|
|
153
|
+
dictionaryOutput: `${GENERATED_DIR}/dictionary.generated.ts`,
|
|
154
|
+
instanceOutput: `${GENERATED_DIR}/instance.generated.ts`,
|
|
155
|
+
paramsTypeName: typeNames.paramsTypeName,
|
|
156
|
+
schemaTypeName: typeNames.schemaTypeName,
|
|
157
|
+
localeTypeName: typeNames.localeTypeName,
|
|
158
|
+
factoryName: "createI18n"
|
|
159
|
+
};
|
|
160
|
+
if (mode === "single") {
|
|
161
|
+
return {
|
|
162
|
+
dictionary: `${TRANSLATIONS_DIR}/translations.json`,
|
|
163
|
+
...base
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
namespaces: {
|
|
168
|
+
default: `${TRANSLATIONS_DIR}/default.json`
|
|
169
|
+
},
|
|
170
|
+
...base
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function writeCodegenConfig(configPath, config) {
|
|
174
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
175
|
+
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
|
|
176
|
+
`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export { DELIVERY_MODES, SUPPORTED_IMPORT_EXTENSIONS, buildCodegenConfig, codegenConfigKeys, inferProjectName, resolveDeliveryOutputDir, typeNamesForProject, writeCodegenConfig };
|
|
180
|
+
//# sourceMappingURL=index.js.map
|
|
181
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/codegen/constants.ts","../../src/codegen/delivery-artifacts.ts","../../src/codegen/codegen-config-schema.ts","../../src/codegen-config/type-names.ts","../../src/codegen-config/build-config.ts","../../src/codegen-config/write-config.ts"],"names":["path"],"mappings":"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","file":"index.js","sourcesContent":["export const SUPPORTED_IMPORT_EXTENSIONS = [\"none\", \".ts\", \".js\"] as const;\nexport type SupportedImportExtension = (typeof SUPPORTED_IMPORT_EXTENSIONS)[number];\n\n// Translation keys and namespace names become TypeScript identifiers and\n// template-literal type segments in the generated code, so they must be valid\n// identifiers (e.g. \"app.title\" would emit the broken type `\"app.title:...\"`).\nexport const IDENTIFIER_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\nexport const IDENTIFIER_NAME_REQUIREMENT =\n \"allowed: letters, digits, underscore; must not start with a digit\";\n","/** Valid TypeScript identifier / filename segment for a delivery area id. */\nexport const DELIVERY_AREA_NAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;\n\nexport type DeliveryArtifactsMap = Record<string, readonly string[]>;\n\nexport type DeliveryArtifactsIssue = {\n path: (string | number)[];\n message: string;\n};\n\nexport function getDeliveryArtifactsStructureIssues(\n deliveryArtifacts: DeliveryArtifactsMap\n): DeliveryArtifactsIssue[] {\n const issues: DeliveryArtifactsIssue[] = [];\n\n for (const [area, locales] of Object.entries(deliveryArtifacts)) {\n if (!DELIVERY_AREA_NAME_PATTERN.test(area)) {\n issues.push({\n path: [\"deliveryArtifacts\", area],\n message: `Invalid delivery area name \"${area}\": must match ${DELIVERY_AREA_NAME_PATTERN.source}`,\n });\n }\n\n if (locales.length === 0) {\n issues.push({\n path: [\"deliveryArtifacts\", area],\n message: `Delivery area \"${area}\" must include at least one locale.`,\n });\n }\n }\n\n const localeToArea = new Map<string, string>();\n for (const [area, locales] of Object.entries(deliveryArtifacts)) {\n for (const locale of locales) {\n const previousArea = localeToArea.get(locale);\n if (previousArea) {\n issues.push({\n path: [\"deliveryArtifacts\", area],\n message: `Locale \"${locale}\" appears in both \"${previousArea}\" and \"${area}\".`,\n });\n } else {\n localeToArea.set(locale, area);\n }\n }\n }\n\n return issues;\n}\n\nexport function getDeliveryArtifactsPartitionIssues(\n deliveryArtifacts: DeliveryArtifactsMap,\n requestLocales: ReadonlySet<string>\n): DeliveryArtifactsIssue[] {\n const issues: DeliveryArtifactsIssue[] = [];\n const artifactLocales = new Set<string>();\n\n for (const locales of Object.values(deliveryArtifacts)) {\n for (const locale of locales) {\n artifactLocales.add(locale);\n }\n }\n\n const missing = [...requestLocales].filter((locale) => !artifactLocales.has(locale)).sort();\n if (missing.length > 0) {\n issues.push({\n path: [\"deliveryArtifacts\"],\n message: `deliveryArtifacts is missing locales required by dictionaries and localeFallback: ${missing.join(\", \")}`,\n });\n }\n\n const excess = [...artifactLocales].filter((locale) => !requestLocales.has(locale)).sort();\n if (excess.length > 0) {\n issues.push({\n path: [\"deliveryArtifacts\"],\n message: `deliveryArtifacts includes locales not required by dictionaries and localeFallback: ${excess.join(\", \")}`,\n });\n }\n\n return issues;\n}\n\n/** Pre-emit validation gate for `deliveryArtifacts` in custom delivery mode. */\nexport function getDeliveryArtifactsIssues(\n deliveryArtifacts: DeliveryArtifactsMap,\n requestLocales: ReadonlySet<string>\n): DeliveryArtifactsIssue[] {\n return [\n ...getDeliveryArtifactsStructureIssues(deliveryArtifacts),\n ...getDeliveryArtifactsPartitionIssues(deliveryArtifacts, requestLocales),\n ];\n}\n\nexport function getDeliveryAreaNames(deliveryArtifacts: DeliveryArtifactsMap): string[] {\n return Object.keys(deliveryArtifacts).sort();\n}\n\nexport function getLocaleDeliveryAreaMap(\n deliveryArtifacts: DeliveryArtifactsMap\n): Record<string, string> {\n const localeToArea: Record<string, string> = {};\n\n for (const [area, locales] of Object.entries(deliveryArtifacts)) {\n for (const locale of locales) {\n localeToArea[locale] = area;\n }\n }\n\n return localeToArea;\n}\n\nexport function formatLocaleDeliveryAreaBlock(\n deliveryArtifacts: DeliveryArtifactsMap,\n constName: string,\n localeTypeName: string,\n deliveryAreaTypeName: string\n): string {\n const localeToArea = getLocaleDeliveryAreaMap(deliveryArtifacts);\n const lines = Object.keys(localeToArea)\n .sort()\n .map((locale) => ` ${JSON.stringify(locale)}: ${JSON.stringify(localeToArea[locale])},`)\n .join(\"\\n\");\n\n return `export const ${constName} = {\\n${lines}\\n} as const satisfies Record<${localeTypeName}, ${deliveryAreaTypeName}>;\\n\\n`;\n}\n","import { z } from \"zod\";\nimport path from \"node:path\";\nimport {\n IDENTIFIER_NAME_PATTERN,\n IDENTIFIER_NAME_REQUIREMENT,\n SUPPORTED_IMPORT_EXTENSIONS,\n} from \"./constants.js\";\nimport { getDeliveryArtifactsStructureIssues } from \"./delivery-artifacts.js\";\n\nconst localeFallbackSchema = z.record(z.string(), z.union([z.string(), z.null()]));\nconst deliveryArtifactsSchema = z.record(z.string(), z.array(z.string().min(1)));\n\nexport const DELIVERY_MODES = [\"canonical\", \"split-by-locale\", \"custom\"] as const;\nexport type DeliveryMode = (typeof DELIVERY_MODES)[number];\n\nconst codegenConfigShape = {\n dictionary: z.string().min(1).optional(),\n namespaces: z.record(z.string(), z.string().min(1)).optional(),\n defaultNamespace: z.string().min(1).optional(),\n typesOutput: z.string().min(1),\n dictionaryOutput: z.string().min(1),\n instanceOutput: z.string().min(1),\n dictionarySchemaOutput: z.string().min(1).optional(),\n loadOnInit: z.array(z.string().min(1)).optional(),\n namespaceLoadersOutput: z.string().min(1).optional(),\n importExtension: z.enum(SUPPORTED_IMPORT_EXTENSIONS).optional(),\n paramsTypeName: z.string().min(1),\n schemaTypeName: z.string().min(1),\n localeTypeName: z.string().min(1).optional(),\n localeFallbackConstName: z.string().min(1).optional(),\n localeFallback: localeFallbackSchema.optional(),\n factoryName: z.string().min(1).optional(),\n delivery: z.enum(DELIVERY_MODES).optional().default(\"canonical\"),\n deliveryArtifacts: deliveryArtifactsSchema.optional(),\n deliveryOutput: z.string().min(1).optional(),\n};\n\nexport const codegenConfigKeys = Object.keys(\n codegenConfigShape\n) as (keyof typeof codegenConfigShape)[];\n\nexport const codegenConfigSchema = z\n .object(codegenConfigShape)\n .strict()\n .superRefine((config, ctx) => {\n const hasDictionary = config.dictionary !== undefined;\n const hasNamespaces = config.namespaces !== undefined;\n\n if (hasDictionary === hasNamespaces) {\n ctx.addIssue({\n code: \"custom\",\n message: 'Specify exactly one of \"dictionary\" or \"namespaces\".',\n });\n }\n\n if (config.namespaces) {\n for (const namespace of Object.keys(config.namespaces)) {\n if (!IDENTIFIER_NAME_PATTERN.test(namespace)) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"namespaces\", namespace],\n message: `Invalid namespace name \"${namespace}\" (${IDENTIFIER_NAME_REQUIREMENT}).`,\n });\n }\n }\n }\n\n if (\n config.defaultNamespace !== undefined &&\n !IDENTIFIER_NAME_PATTERN.test(config.defaultNamespace)\n ) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"defaultNamespace\"],\n message: `Invalid namespace name \"${config.defaultNamespace}\" (${IDENTIFIER_NAME_REQUIREMENT}).`,\n });\n }\n\n if (config.delivery === \"custom\") {\n if (!config.deliveryArtifacts) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"deliveryArtifacts\"],\n message: 'deliveryArtifacts is required when delivery is \"custom\".',\n });\n } else {\n for (const issue of getDeliveryArtifactsStructureIssues(config.deliveryArtifacts)) {\n ctx.addIssue({\n code: \"custom\",\n path: issue.path,\n message: issue.message,\n });\n }\n }\n } else if (config.deliveryArtifacts !== undefined) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"deliveryArtifacts\"],\n message: 'deliveryArtifacts is only allowed when delivery is \"custom\".',\n });\n }\n });\n\nexport type CodegenConfigInput = z.input<typeof codegenConfigSchema>;\nexport type CodegenConfig = z.infer<typeof codegenConfigSchema>;\n\nexport function resolveDeliveryOutputDir(\n config: Pick<CodegenConfig, \"typesOutput\" | \"deliveryOutput\">\n): string {\n return config.deliveryOutput ?? path.dirname(config.typesOutput);\n}\n\nexport function formatCodegenConfigIssues(error: z.ZodError): string {\n const issueLines = error.issues.map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"(root)\";\n return ` - ${path}: ${issue.message}`;\n });\n\n return [\n \"[Codegen Error] Invalid i18n.codegen.json:\",\n ...issueLines,\n \"\",\n `Allowed keys: ${codegenConfigKeys.join(\", \")}`,\n ].join(\"\\n\");\n}\n","export function inferProjectName(dirName: string): string {\n const parts = dirName.split(/[-_]+/).filter(Boolean);\n if (parts.length === 0) {\n return \"App\";\n }\n\n return parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(\"\");\n}\n\nexport function typeNamesForProject(project: string): {\n paramsTypeName: string;\n schemaTypeName: string;\n localeTypeName: string;\n} {\n return {\n paramsTypeName: `${project}Params`,\n schemaTypeName: `${project}Schema`,\n localeTypeName: `${project}Locale`,\n };\n}\n","import type { CodegenConfigInput } from \"../codegen/codegen-config-schema.js\";\nimport { typeNamesForProject } from \"./type-names.js\";\n\nexport type SetupMode = \"single\" | \"multi\";\n\nconst GENERATED_DIR = \"generated\";\nconst TRANSLATIONS_DIR = \"translations\";\n\nexport function buildCodegenConfig(mode: SetupMode, project: string): CodegenConfigInput {\n const typeNames = typeNamesForProject(project);\n const base = {\n typesOutput: `${GENERATED_DIR}/i18n-types.generated.ts`,\n dictionaryOutput: `${GENERATED_DIR}/dictionary.generated.ts`,\n instanceOutput: `${GENERATED_DIR}/instance.generated.ts`,\n paramsTypeName: typeNames.paramsTypeName,\n schemaTypeName: typeNames.schemaTypeName,\n localeTypeName: typeNames.localeTypeName,\n factoryName: \"createI18n\",\n } satisfies CodegenConfigInput;\n\n if (mode === \"single\") {\n return {\n dictionary: `${TRANSLATIONS_DIR}/translations.json`,\n ...base,\n };\n }\n\n return {\n namespaces: {\n default: `${TRANSLATIONS_DIR}/default.json`,\n },\n ...base,\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { CodegenConfigInput } from \"../codegen/codegen-config-schema.js\";\n\nexport function writeCodegenConfig(configPath: string, config: CodegenConfigInput): void {\n fs.mkdirSync(path.dirname(configPath), { recursive: true });\n fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`);\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { V as ValidationResult } from './types-C1CpXVOJ.js';
|
|
2
|
-
import '@formatjs/icu-messageformat-parser';
|
|
3
|
-
|
|
4
1
|
type LocaleDictionary = Record<string, string>;
|
|
5
2
|
type KeyDictionary = Record<string, LocaleDictionary>;
|
|
6
3
|
type MultiDictionary = Record<string, KeyDictionary>;
|
|
@@ -13,9 +10,23 @@ type LocaleOfMulti<Schema extends MultiDictionary> = {
|
|
|
13
10
|
}[keyof Schema[NS]];
|
|
14
11
|
}[keyof Schema] & string;
|
|
15
12
|
type LocaleFallbackMap$1 = Record<string, string | null>;
|
|
16
|
-
type
|
|
13
|
+
type MissingTranslationContext = {
|
|
14
|
+
/** Only set by the multi-namespace provider. */
|
|
15
|
+
namespace?: string;
|
|
16
|
+
key: string;
|
|
17
|
+
locale: string;
|
|
18
|
+
fallbackChain: string;
|
|
19
|
+
};
|
|
20
|
+
type OnMissingTranslation = "throw" | "key" | ((context: MissingTranslationContext) => string);
|
|
17
21
|
type IcuTranslationProviderOptions<Fallback extends LocaleFallbackMap$1 | undefined = undefined> = {
|
|
18
22
|
localeFallback?: Fallback;
|
|
23
|
+
/**
|
|
24
|
+
* Strategy when no template resolves for a key/locale (after walking the
|
|
25
|
+
* fallback chain). "throw" (default) raises an error, "key" returns the
|
|
26
|
+
* translation key itself, a function receives the context and returns the
|
|
27
|
+
* string to display. ICU syntax and formatting errors always throw.
|
|
28
|
+
*/
|
|
29
|
+
onMissing?: OnMissingTranslation;
|
|
19
30
|
};
|
|
20
31
|
|
|
21
32
|
interface TranslationProviderSingleForLocale<Schema extends KeyDictionary, Params extends {
|
|
@@ -46,8 +57,10 @@ declare class IcuTranslationProviderSingle<Schema extends KeyDictionary, Params
|
|
|
46
57
|
private dictionary;
|
|
47
58
|
private compiledCache;
|
|
48
59
|
private readonly localeFallback?;
|
|
60
|
+
private readonly onMissing;
|
|
49
61
|
constructor(dictionary: Schema, options?: IcuTranslationProviderOptions<Fallback>);
|
|
50
62
|
get<K extends keyof Schema & string>(key: K, locale: RequestLocales, ...args: Params[K] extends never ? [] : [params: Params[K]]): string;
|
|
63
|
+
getWithLocale(key: string, locale: string, params?: Record<string, unknown>): string;
|
|
51
64
|
forLocale<Locale extends RequestLocales>(locale: Locale): IcuTranslationProviderSingleForLocale<Schema, Params, RequestLocales, Locale, Fallback>;
|
|
52
65
|
getAll(): Schema;
|
|
53
66
|
setAll(values: Schema): void;
|
|
@@ -91,9 +104,11 @@ declare class IcuTranslationProviderMulti<Schema extends MultiDictionary, Params
|
|
|
91
104
|
private dictionary;
|
|
92
105
|
private compiledCache;
|
|
93
106
|
private readonly localeFallback?;
|
|
107
|
+
private readonly onMissing;
|
|
94
108
|
private loadedNamespaces;
|
|
95
109
|
constructor(dictionary: Partial<Schema>, options?: IcuTranslationProviderOptions<Fallback>);
|
|
96
110
|
get<NS extends keyof Schema, K extends keyof Schema[NS] & keyof Params[NS] & string>(namespace: NS, key: K, locale: RequestLocales, ...args: Params[NS][K] extends never ? [] : [params: Params[NS][K]]): string;
|
|
111
|
+
getWithLocale(namespace: string, key: string, locale: string, params?: Record<string, unknown>): string;
|
|
97
112
|
forLocale<Locale extends RequestLocales>(locale: Locale): IcuTranslationProviderMultiForLocale<Schema, Params, RequestLocales, Locale, Fallback>;
|
|
98
113
|
getAll(): Schema;
|
|
99
114
|
hasNamespace<NS extends keyof Schema & string>(namespace: NS): boolean;
|
|
@@ -112,24 +127,25 @@ declare function resolveLocaleTemplate(localeByKey: Record<string, string | unde
|
|
|
112
127
|
declare function formatLocaleFallbackChain(requestedLocale: string, fallbackMap?: LocaleFallbackMap): string;
|
|
113
128
|
|
|
114
129
|
/**
|
|
115
|
-
* Builds a dictionary that contains only the requested locales.
|
|
130
|
+
* Builds a namespace dictionary that contains only the requested locales.
|
|
116
131
|
* For each key and target locale, copies the direct template when present;
|
|
117
132
|
* otherwise resolves through `localeFallback` (same rules as `.get()` at runtime).
|
|
118
133
|
*/
|
|
119
|
-
declare function
|
|
134
|
+
declare function projectNamespaceLocalesCore<T extends KeyDictionary>(dictionary: T, locales: readonly string[], localeFallback?: LocaleFallbackMap$1): T;
|
|
135
|
+
/**
|
|
136
|
+
* Projects a single namespace for a custom delivery area.
|
|
137
|
+
* Full locales resolve through `localeFallback` (e.g. external chains like `it → en-US`);
|
|
138
|
+
* preserve locales copy only their direct canonical entry when present.
|
|
139
|
+
*/
|
|
140
|
+
declare function projectNamespaceForDeliveryAreaCore<T extends KeyDictionary>(dictionary: T, areaLocales: readonly string[], localeFallback?: LocaleFallbackMap$1): T;
|
|
141
|
+
/**
|
|
142
|
+
* Projects a multi-namespace dictionary for a custom delivery area.
|
|
143
|
+
* Each namespace uses the same delivery-area rules as `projectNamespaceForDeliveryAreaCore`.
|
|
144
|
+
*/
|
|
145
|
+
declare function projectDictionaryForDeliveryAreaCore<T extends MultiDictionary>(dictionary: T, areaLocales: readonly string[], localeFallback?: LocaleFallbackMap$1): T;
|
|
120
146
|
/**
|
|
121
147
|
* Projects every namespace in a multi-namespace dictionary.
|
|
122
148
|
*/
|
|
123
|
-
declare function
|
|
124
|
-
|
|
125
|
-
interface EnsureNamespacesLoadedOptions<Schema extends MultiDictionary, NS extends keyof Schema & string> {
|
|
126
|
-
provider: Pick<{
|
|
127
|
-
hasNamespace(namespace: NS): boolean;
|
|
128
|
-
setNamespace(namespace: NS, values: Schema[NS]): void;
|
|
129
|
-
}, "hasNamespace" | "setNamespace">;
|
|
130
|
-
resolveLoader: (namespace: NS) => () => Promise<unknown>;
|
|
131
|
-
validate: (namespace: NS, raw: unknown) => ValidationResult<Schema[NS]>;
|
|
132
|
-
}
|
|
133
|
-
declare function ensureNamespacesLoadedImpl<Schema extends MultiDictionary, NS extends keyof Schema & string>(options: EnsureNamespacesLoadedOptions<Schema, NS>, namespaces: NS[]): Promise<void>;
|
|
149
|
+
declare function projectDictionaryLocalesCore<T extends MultiDictionary>(dictionary: T, locales: readonly string[], localeFallback?: LocaleFallbackMap$1): T;
|
|
134
150
|
|
|
135
|
-
export {
|
|
151
|
+
export { IcuTranslationProviderMulti, type IcuTranslationProviderOptions, IcuTranslationProviderSingle, type KeyDictionary, type LocaleDictionary, type LocaleFallbackMap$1 as LocaleFallbackMap, type LocaleOfMulti, type LocaleOfSingle, type MissingTranslationContext, type MultiDictionary, type OnMissingTranslation, type ResolvedLocaleTemplate, type TranslationProviderMulti, type TranslationProviderMultiForLocale, type TranslationProviderSingle, type TranslationProviderSingleForLocale, formatLocaleFallbackChain, projectDictionaryForDeliveryAreaCore, projectDictionaryLocalesCore, projectNamespaceForDeliveryAreaCore, projectNamespaceLocalesCore, resolveLocaleTemplate, validateLocaleFallback };
|