@xndrjs/i18n 0.8.1 → 0.8.2-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.
Files changed (93) hide show
  1. package/README.md +1 -2
  2. package/dist/cli/audit.js +739 -0
  3. package/dist/cli/audit.js.map +1 -0
  4. package/dist/cli/codegen.js +1471 -0
  5. package/dist/cli/codegen.js.map +1 -0
  6. package/dist/cli/setup.js +148 -0
  7. package/dist/cli/setup.js.map +1 -0
  8. package/dist/codegen/index.js +43 -40
  9. package/dist/codegen/index.js.map +1 -1
  10. package/package.json +6 -9
  11. package/bin/audit.mjs +0 -14
  12. package/bin/codegen.mjs +0 -17
  13. package/bin/setup.mjs +0 -14
  14. package/src/IcuTranslationProviderMulti.test.ts +0 -215
  15. package/src/IcuTranslationProviderMulti.ts +0 -188
  16. package/src/audit/audit-dictionaries.test.ts +0 -134
  17. package/src/audit/audit-dictionaries.ts +0 -178
  18. package/src/audit/run-audit.test.ts +0 -169
  19. package/src/audit/run-audit.ts +0 -94
  20. package/src/builder-load-registry.test.ts +0 -44
  21. package/src/builder-load-registry.ts +0 -78
  22. package/src/builder-loaders.ts +0 -15
  23. package/src/builder-types.test.ts +0 -57
  24. package/src/builder-types.ts +0 -24
  25. package/src/builder.test.ts +0 -303
  26. package/src/builder.ts +0 -15
  27. package/src/codegen/codegen-config-schema.ts +0 -156
  28. package/src/codegen/config.test.ts +0 -231
  29. package/src/codegen/config.ts +0 -42
  30. package/src/codegen/constants.ts +0 -9
  31. package/src/codegen/delivery-artifacts.test.ts +0 -167
  32. package/src/codegen/delivery-artifacts.ts +0 -154
  33. package/src/codegen/dictionary-spec-contract.test.ts +0 -28
  34. package/src/codegen/dictionary-spec-contract.ts +0 -138
  35. package/src/codegen/emit/dictionary-schema-file.ts +0 -113
  36. package/src/codegen/emit/instance-file.test.ts +0 -71
  37. package/src/codegen/emit/instance-file.ts +0 -257
  38. package/src/codegen/emit/namespace-loaders-file.test.ts +0 -251
  39. package/src/codegen/emit/namespace-loaders-file.ts +0 -229
  40. package/src/codegen/emit/types-file.test.ts +0 -96
  41. package/src/codegen/emit/types-file.ts +0 -142
  42. package/src/codegen/fixtures/billing-namespace.json +0 -6
  43. package/src/codegen/generate-i18n-types.test.ts +0 -1137
  44. package/src/codegen/generate-i18n-types.ts +0 -20
  45. package/src/codegen/icu-analysis.ts +0 -110
  46. package/src/codegen/locale-fallback.ts +0 -73
  47. package/src/codegen/locale-policy.test.ts +0 -35
  48. package/src/codegen/locale-policy.ts +0 -30
  49. package/src/codegen/paths.ts +0 -44
  50. package/src/codegen/project-locales-set-namespace.test.ts +0 -134
  51. package/src/codegen/read-dictionary.test.ts +0 -594
  52. package/src/codegen/read-dictionary.ts +0 -260
  53. package/src/codegen/regenerate-namespaces.ts +0 -180
  54. package/src/codegen/run-codegen.test.ts +0 -230
  55. package/src/codegen/run-codegen.ts +0 -252
  56. package/src/codegen/types.ts +0 -10
  57. package/src/codegen/write-file-if-changed.test.ts +0 -42
  58. package/src/codegen/write-file-if-changed.ts +0 -20
  59. package/src/codegen-config/build-config.ts +0 -15
  60. package/src/codegen-config/codegen-config.test.ts +0 -36
  61. package/src/codegen-config/index.ts +0 -37
  62. package/src/codegen-config/type-names.ts +0 -20
  63. package/src/codegen-config/write-config.ts +0 -8
  64. package/src/engine.ts +0 -47
  65. package/src/fetch-artifact.ts +0 -16
  66. package/src/format-core.ts +0 -91
  67. package/src/i18n-handle.ts +0 -216
  68. package/src/icu/extract-variables.test.ts +0 -199
  69. package/src/icu/extract-variables.ts +0 -227
  70. package/src/icu/parse-template.ts +0 -31
  71. package/src/index.ts +0 -63
  72. package/src/load-state.ts +0 -15
  73. package/src/project-locales.test.ts +0 -280
  74. package/src/project-locales.ts +0 -211
  75. package/src/resolve-locale.test.ts +0 -91
  76. package/src/resolve-locale.ts +0 -88
  77. package/src/scope-multi.ts +0 -105
  78. package/src/scope-types.ts +0 -35
  79. package/src/scope.test.ts +0 -172
  80. package/src/serialized-state.test.ts +0 -114
  81. package/src/serialized-state.ts +0 -28
  82. package/src/setup/setup-i18n.test.ts +0 -85
  83. package/src/setup/setup-i18n.ts +0 -156
  84. package/src/types.ts +0 -65
  85. package/src/validation/create-args-schema.ts +0 -76
  86. package/src/validation/create-normalized-schema.ts +0 -52
  87. package/src/validation/errors.ts +0 -43
  88. package/src/validation/index.ts +0 -202
  89. package/src/validation/normalize.ts +0 -299
  90. package/src/validation/to-dictionary.ts +0 -67
  91. package/src/validation/types.ts +0 -82
  92. package/src/validation/validate-normalized.ts +0 -133
  93. package/src/validation/validation.test.ts +0 -562
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import path8 from 'path';
2
+ import path6 from 'path';
3
3
  import fs3 from 'fs';
4
4
  import { parse } from '@formatjs/icu-messageformat-parser';
5
5
  import { parse as parse$1 } from 'yaml';
@@ -211,10 +211,10 @@ function resolveCodegenPaths(config) {
211
211
  const codegenPath = config.codegenPath;
212
212
  return {
213
213
  codegenPath,
214
- typesOutput: path8.join(codegenPath, GENERATED_BASENAMES.types),
215
- instanceOutput: path8.join(codegenPath, GENERATED_BASENAMES.instance),
216
- namespaceLoadersOutput: path8.join(codegenPath, GENERATED_BASENAMES.namespaceLoaders),
217
- dictionarySchemaOutput: path8.join(codegenPath, GENERATED_BASENAMES.dictionarySchema),
214
+ typesOutput: path6.join(codegenPath, GENERATED_BASENAMES.types),
215
+ instanceOutput: path6.join(codegenPath, GENERATED_BASENAMES.instance),
216
+ namespaceLoadersOutput: path6.join(codegenPath, GENERATED_BASENAMES.namespaceLoaders),
217
+ dictionarySchemaOutput: path6.join(codegenPath, GENERATED_BASENAMES.dictionarySchema),
218
218
  artifactsPath: config.artifactsPath ?? codegenPath,
219
219
  paramsTypeName: typeNames.paramsTypeName,
220
220
  schemaTypeName: typeNames.schemaTypeName,
@@ -274,24 +274,27 @@ function buildCodegenConfig(project) {
274
274
  };
275
275
  }
276
276
  function writeCodegenConfig(configPath, config) {
277
- fs3.mkdirSync(path8.dirname(configPath), { recursive: true });
277
+ fs3.mkdirSync(path6.dirname(configPath), { recursive: true });
278
278
  fs3.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
279
279
  `);
280
280
  }
281
281
  var GENERATED_FILE_BANNER = "// Automatically generated code. Do not edit manually.\n";
282
282
  var DEFAULT_IMPORT_EXTENSION = "none";
283
+ function relativePosixPath(from, to) {
284
+ return path6.relative(from, to).replace(/\\/g, "/");
285
+ }
283
286
  function reportCodegenIssues(issues) {
284
287
  for (const issue of issues) {
285
288
  console.error(`[Codegen Error] ${issue.message}`);
286
289
  }
287
290
  }
288
291
  function toImportPath(fromFile, toFile) {
289
- const relative = path8.relative(path8.dirname(fromFile), toFile).replace(/\\/g, "/");
292
+ const relative = path6.relative(path6.dirname(fromFile), toFile).replace(/\\/g, "/");
290
293
  const withoutExt = relative.replace(/\.(json|ya?ml)$/i, "");
291
294
  return withoutExt.startsWith(".") ? withoutExt : `./${withoutExt}`;
292
295
  }
293
296
  function toModuleBasename(filePath) {
294
- return path8.basename(filePath).replace(/\.ts$/, "");
297
+ return path6.basename(filePath).replace(/\.ts$/, "");
295
298
  }
296
299
  function importExtensionSuffix(importExtension) {
297
300
  return importExtension === "none" ? "" : importExtension;
@@ -572,7 +575,7 @@ function formatPartitionedTypesImport(options, paramTypeName) {
572
575
  `;
573
576
  }
574
577
  function formatImportCase(loadersOutputPath, projectRoot, splitRelativePath) {
575
- const importPath = toImportPath(loadersOutputPath, path8.resolve(projectRoot, splitRelativePath));
578
+ const importPath = toImportPath(loadersOutputPath, path6.resolve(projectRoot, splitRelativePath));
576
579
  return `return import('${importPath}.json').then((m) => m.default);`;
577
580
  }
578
581
  function indentBlock(text, spaces) {
@@ -1062,14 +1065,14 @@ function writeFileIfChanged(absolutePath, content) {
1062
1065
  return false;
1063
1066
  }
1064
1067
  }
1065
- fs3.mkdirSync(path8.dirname(absolutePath), { recursive: true });
1068
+ fs3.mkdirSync(path6.dirname(absolutePath), { recursive: true });
1066
1069
  fs3.writeFileSync(absolutePath, content);
1067
1070
  return true;
1068
1071
  }
1069
1072
 
1070
1073
  // src/codegen/read-dictionary.ts
1071
1074
  function getDictionaryFormat(filePath) {
1072
- const extension = path8.extname(filePath).toLowerCase();
1075
+ const extension = path6.extname(filePath).toLowerCase();
1073
1076
  if (extension === ".json") {
1074
1077
  return "json";
1075
1078
  }
@@ -1079,12 +1082,12 @@ function getDictionaryFormat(filePath) {
1079
1082
  return null;
1080
1083
  }
1081
1084
  function resolveSplitJsonPath(sourcePath, locale, generatedDirRelative) {
1082
- const baseName = path8.basename(sourcePath, path8.extname(sourcePath));
1083
- return path8.join(generatedDirRelative, "translations", `${baseName}.${locale}.json`).replace(/\\/g, "/");
1085
+ const baseName = path6.basename(sourcePath, path6.extname(sourcePath));
1086
+ return path6.join(generatedDirRelative, "translations", `${baseName}.${locale}.json`).replace(/\\/g, "/");
1084
1087
  }
1085
1088
  function resolveAreaJsonPath(sourcePath, area, generatedDirRelative) {
1086
- const baseName = path8.basename(sourcePath, path8.extname(sourcePath));
1087
- return path8.join(generatedDirRelative, "translations", `${baseName}.${area}.json`).replace(/\\/g, "/");
1089
+ const baseName = path6.basename(sourcePath, path6.extname(sourcePath));
1090
+ return path6.join(generatedDirRelative, "translations", `${baseName}.${area}.json`).replace(/\\/g, "/");
1088
1091
  }
1089
1092
  function splitDictionaryByLocale(dictionary, locales, localeFallback) {
1090
1093
  const byLocale = {};
@@ -1126,7 +1129,7 @@ function readDictionaryFile(absolutePath) {
1126
1129
  const format = getDictionaryFormat(absolutePath);
1127
1130
  if (!format) {
1128
1131
  throw new Error(
1129
- `[Codegen Error] Unsupported dictionary format "${path8.extname(absolutePath)}" for ${absolutePath}. Use .json, .yaml, or .yml.`
1132
+ `[Codegen Error] Unsupported dictionary format "${path6.extname(absolutePath)}" for ${absolutePath}. Use .json, .yaml, or .yml.`
1130
1133
  );
1131
1134
  }
1132
1135
  const source = fs3.readFileSync(absolutePath, "utf8");
@@ -1159,7 +1162,7 @@ function prepareDictionaryEntries(projectRoot, entries, generatedDirRelative, op
1159
1162
  throw new Error("[Codegen Error] custom delivery requires deliveryArtifacts.");
1160
1163
  }
1161
1164
  for (const entry of entries) {
1162
- const sourceAbsolutePath = path8.resolve(projectRoot, entry.filePath);
1165
+ const sourceAbsolutePath = path6.resolve(projectRoot, entry.filePath);
1163
1166
  const format = getDictionaryFormat(entry.filePath);
1164
1167
  if (!format) {
1165
1168
  throw new Error(
@@ -1185,11 +1188,11 @@ function prepareDictionaryEntries(projectRoot, entries, generatedDirRelative, op
1185
1188
  locale,
1186
1189
  generatedDirRelative
1187
1190
  );
1188
- const splitAbsolutePath = path8.resolve(projectRoot, splitRelativePath);
1191
+ const splitAbsolutePath = path6.resolve(projectRoot, splitRelativePath);
1189
1192
  const wroteFile = writeCompiledJson(splitAbsolutePath, dictionariesByLocale[locale]);
1190
1193
  if (wroteFile) {
1191
1194
  compiledFiles.push(
1192
- `${path8.relative(projectRoot, sourceAbsolutePath)} \u2192 ${splitRelativePath}`
1195
+ `${relativePosixPath(projectRoot, sourceAbsolutePath)} \u2192 ${splitRelativePath}`
1193
1196
  );
1194
1197
  }
1195
1198
  splitPaths2[locale] = splitRelativePath;
@@ -1206,11 +1209,11 @@ function prepareDictionaryEntries(projectRoot, entries, generatedDirRelative, op
1206
1209
  );
1207
1210
  for (const area of Object.keys(deliveryArtifacts).sort()) {
1208
1211
  const areaRelativePath = resolveAreaJsonPath(entry.filePath, area, generatedDirRelative);
1209
- const areaAbsolutePath = path8.resolve(projectRoot, areaRelativePath);
1212
+ const areaAbsolutePath = path6.resolve(projectRoot, areaRelativePath);
1210
1213
  const wroteFile = writeCompiledJson(areaAbsolutePath, dictionariesByArea[area]);
1211
1214
  if (wroteFile) {
1212
1215
  compiledFiles.push(
1213
- `${path8.relative(projectRoot, sourceAbsolutePath)} \u2192 ${areaRelativePath}`
1216
+ `${relativePosixPath(projectRoot, sourceAbsolutePath)} \u2192 ${areaRelativePath}`
1214
1217
  );
1215
1218
  }
1216
1219
  splitPaths[area] = areaRelativePath;
@@ -1240,7 +1243,7 @@ function analyzeDictionaries(projectRoot, entries) {
1240
1243
  const dictionariesByNamespace = {};
1241
1244
  let hasErrors = false;
1242
1245
  for (const entry of entries) {
1243
- const absolutePath = path8.resolve(projectRoot, entry.filePath);
1246
+ const absolutePath = path6.resolve(projectRoot, entry.filePath);
1244
1247
  if (!fs3.existsSync(absolutePath)) {
1245
1248
  console.error(
1246
1249
  `[Codegen Error] Dictionary file not found for namespace "${entry.namespace}": ${absolutePath}`
@@ -1314,7 +1317,7 @@ function enrichLocaleFallback(dictionaryLocales, configFallback) {
1314
1317
  // src/codegen/run-codegen.ts
1315
1318
  function resolveRunCodegenInput(input) {
1316
1319
  if (typeof input === "string" || input === void 0) {
1317
- const configPath2 = path8.resolve(
1320
+ const configPath2 = path6.resolve(
1318
1321
  process.cwd(),
1319
1322
  typeof input === "string" ? input : "i18n/i18n.codegen.json"
1320
1323
  );
@@ -1322,22 +1325,22 @@ function resolveRunCodegenInput(input) {
1322
1325
  throw new Error(`[Codegen Error] Config file not found: ${configPath2}`);
1323
1326
  }
1324
1327
  return {
1325
- projectRoot: path8.dirname(configPath2),
1328
+ projectRoot: path6.dirname(configPath2),
1326
1329
  config: loadConfig(configPath2),
1327
1330
  log: true
1328
1331
  };
1329
1332
  }
1330
1333
  const log = input.log !== false;
1331
1334
  if (input.config !== void 0) {
1332
- const projectRoot = path8.resolve(input.projectRoot ?? process.cwd());
1335
+ const projectRoot = path6.resolve(input.projectRoot ?? process.cwd());
1333
1336
  return { projectRoot, config: input.config, log };
1334
1337
  }
1335
- const configPath = path8.resolve(process.cwd(), input.configPath ?? "i18n/i18n.codegen.json");
1338
+ const configPath = path6.resolve(process.cwd(), input.configPath ?? "i18n/i18n.codegen.json");
1336
1339
  if (!fs3.existsSync(configPath)) {
1337
1340
  throw new Error(`[Codegen Error] Config file not found: ${configPath}`);
1338
1341
  }
1339
1342
  return {
1340
- projectRoot: path8.dirname(configPath),
1343
+ projectRoot: path6.dirname(configPath),
1341
1344
  config: loadConfig(configPath),
1342
1345
  log
1343
1346
  };
@@ -1394,10 +1397,10 @@ function runCodegen(input) {
1394
1397
  requestLocales: delivery === "split-by-locale" ? requestLocalesList : void 0,
1395
1398
  deliveryArtifacts: delivery === "custom" ? config.deliveryArtifacts : void 0
1396
1399
  });
1397
- const typesOutputPath = path8.resolve(projectRoot, paths.typesOutput);
1398
- const instanceOutputPath = path8.resolve(projectRoot, paths.instanceOutput);
1399
- const namespaceLoadersOutputPath = path8.resolve(projectRoot, paths.namespaceLoadersOutput);
1400
- const dictionarySchemaOutputPath = path8.resolve(projectRoot, paths.dictionarySchemaOutput);
1400
+ const typesOutputPath = path6.resolve(projectRoot, paths.typesOutput);
1401
+ const instanceOutputPath = path6.resolve(projectRoot, paths.instanceOutput);
1402
+ const namespaceLoadersOutputPath = path6.resolve(projectRoot, paths.namespaceLoadersOutput);
1403
+ const dictionarySchemaOutputPath = path6.resolve(projectRoot, paths.dictionarySchemaOutput);
1401
1404
  const typesModule = toModuleBasename(typesOutputPath);
1402
1405
  const deliveryAreaNames = delivery === "custom" && config.deliveryArtifacts ? Object.keys(config.deliveryArtifacts).sort() : void 0;
1403
1406
  const deliveryAreaTypeName = delivery === "custom" ? resolvedDeliveryAreaTypeName : void 0;
@@ -1436,8 +1439,8 @@ function runCodegen(input) {
1436
1439
  });
1437
1440
  writeFileIfChanged(typesOutputPath, typesContent);
1438
1441
  const generatedFiles = [
1439
- path8.relative(projectRoot, typesOutputPath),
1440
- path8.relative(projectRoot, instanceOutputPath)
1442
+ relativePosixPath(projectRoot, typesOutputPath),
1443
+ relativePosixPath(projectRoot, instanceOutputPath)
1441
1444
  ];
1442
1445
  writeFileIfChanged(instanceOutputPath, instanceContent);
1443
1446
  const dictionarySpecBlock = formatDictionarySpecBlock(entries, argsSpecByNamespace);
@@ -1448,10 +1451,10 @@ function runCodegen(input) {
1448
1451
  importExtension
1449
1452
  );
1450
1453
  writeFileIfChanged(dictionarySchemaOutputPath, dictionarySchemaContent);
1451
- generatedFiles.push(path8.relative(projectRoot, dictionarySchemaOutputPath));
1454
+ generatedFiles.push(relativePosixPath(projectRoot, dictionarySchemaOutputPath));
1452
1455
  const lazyEntriesWithPaths = entries.map((entry) => ({
1453
1456
  ...entry,
1454
- absolutePath: path8.resolve(projectRoot, entry.filePath)
1457
+ absolutePath: path6.resolve(projectRoot, entry.filePath)
1455
1458
  }));
1456
1459
  const namespaceLoadersContent = formatNamespaceLoadersFile({
1457
1460
  loadersOutputPath: namespaceLoadersOutputPath,
@@ -1468,7 +1471,7 @@ function runCodegen(input) {
1468
1471
  ...delivery === "custom" && deliveryAreaTypeName && deliveryAreaNames ? { deliveryAreaTypeName, deliveryAreaNames } : {}
1469
1472
  });
1470
1473
  writeFileIfChanged(namespaceLoadersOutputPath, namespaceLoadersContent);
1471
- generatedFiles.push(path8.relative(projectRoot, namespaceLoadersOutputPath));
1474
+ generatedFiles.push(relativePosixPath(projectRoot, namespaceLoadersOutputPath));
1472
1475
  if (log) {
1473
1476
  console.log(`\u2705 Generated: ${generatedFiles.join(", ")}`);
1474
1477
  if (compiledFiles.length > 0) {
@@ -1576,18 +1579,18 @@ function resolveRegenerateInput(input) {
1576
1579
  const namespaces = input.namespaces;
1577
1580
  if (input.config !== void 0) {
1578
1581
  return {
1579
- projectRoot: path8.resolve(input.projectRoot ?? process.cwd()),
1582
+ projectRoot: path6.resolve(input.projectRoot ?? process.cwd()),
1580
1583
  config: input.config,
1581
1584
  namespaces,
1582
1585
  log
1583
1586
  };
1584
1587
  }
1585
- const configPath = path8.resolve(process.cwd(), input.configPath ?? "i18n/i18n.codegen.json");
1588
+ const configPath = path6.resolve(process.cwd(), input.configPath ?? "i18n/i18n.codegen.json");
1586
1589
  if (!fs3.existsSync(configPath)) {
1587
1590
  throw new Error(`[Codegen Error] Config file not found: ${configPath}`);
1588
1591
  }
1589
1592
  return {
1590
- projectRoot: path8.dirname(configPath),
1593
+ projectRoot: path6.dirname(configPath),
1591
1594
  config: loadConfig(configPath),
1592
1595
  namespaces,
1593
1596
  log
@@ -1609,7 +1612,7 @@ function regenerateNamespaces(input) {
1609
1612
  const requested = new Set(namespaces);
1610
1613
  const selectedEntries = sourceEntries.filter((entry) => requested.has(entry.namespace));
1611
1614
  const paths = resolveCodegenPaths(config);
1612
- const schemaPath = path8.resolve(projectRoot, paths.dictionarySchemaOutput);
1615
+ const schemaPath = path6.resolve(projectRoot, paths.dictionarySchemaOutput);
1613
1616
  const established = loadDictionarySpecFromSchemaFile(schemaPath);
1614
1617
  const artifactsPathRelative = resolveArtifactsPath(config);
1615
1618
  const delivery = config.delivery ?? "split-by-locale";