@vmz/vmz 0.1.16 → 0.1.18

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 (131) hide show
  1. package/dist/application-cmd.d.ts +6 -16
  2. package/dist/application-cmd.js +34 -180
  3. package/dist/author-input.d.ts +40 -19
  4. package/dist/author-input.js +2 -16
  5. package/dist/build-assemble.d.ts +63 -41
  6. package/dist/build-assemble.js +42 -43
  7. package/dist/bundler-adapter.d.ts +46 -48
  8. package/dist/bundler-adapter.js +4 -43
  9. package/dist/cdn-policy.d.ts +77 -93
  10. package/dist/cdn-policy.js +10 -16
  11. package/dist/cli-localize.d.ts +34 -0
  12. package/dist/cli-localize.js +58 -0
  13. package/dist/cli.d.ts +8 -19
  14. package/dist/cli.js +69 -252
  15. package/dist/content-addressed-assets.d.ts +24 -10
  16. package/dist/content-addressed-assets.js +2 -7
  17. package/dist/delivery-profile.d.ts +54 -27
  18. package/dist/delivery-profile.js +15 -13
  19. package/dist/dev-session.d.ts +29 -23
  20. package/dist/dev-session.js +0 -21
  21. package/dist/dev-watch-roots.d.ts +34 -25
  22. package/dist/dev-watch-roots.js +0 -31
  23. package/dist/document-build.d.ts +22 -97
  24. package/dist/document-build.js +4 -19
  25. package/dist/document-check.d.ts +30 -53
  26. package/dist/document-check.js +14 -29
  27. package/dist/document-cmd.d.ts +3 -6
  28. package/dist/document-cmd.js +19 -79
  29. package/dist/document-designs.d.ts +5 -8
  30. package/dist/document-designs.js +2 -15
  31. package/dist/document-enrich.d.ts +52 -24
  32. package/dist/document-enrich.js +4 -32
  33. package/dist/document-evidence.d.ts +46 -43
  34. package/dist/document-evidence.js +6 -47
  35. package/dist/document-integrate.d.ts +13 -29
  36. package/dist/document-integrate.js +2 -13
  37. package/dist/document-interactive.d.ts +45 -67
  38. package/dist/document-interactive.js +9 -50
  39. package/dist/document-layout-render.d.ts +7 -16
  40. package/dist/document-layout-render.js +0 -17
  41. package/dist/document-locale.d.ts +12 -25
  42. package/dist/document-locale.js +3 -14
  43. package/dist/document-markdown.d.ts +9 -5
  44. package/dist/document-markdown.js +0 -4
  45. package/dist/document-routing-config.d.ts +7 -14
  46. package/dist/document-routing-config.js +0 -9
  47. package/dist/document-scan.d.ts +14 -18
  48. package/dist/document-scan.js +2 -23
  49. package/dist/document-schema.d.ts +154 -41
  50. package/dist/document-schema.js +0 -35
  51. package/dist/embedded-packaging.d.ts +20 -8
  52. package/dist/embedded-packaging.js +0 -1
  53. package/dist/explain-cmd.d.ts +4 -3
  54. package/dist/explain-cmd.js +16 -65
  55. package/dist/index.d.ts +70 -143
  56. package/dist/index.js +16 -136
  57. package/dist/invocation.d.ts +29 -50
  58. package/dist/invocation.js +11 -57
  59. package/dist/locale-check.d.ts +69 -70
  60. package/dist/locale-check.js +5 -66
  61. package/dist/locale-cmd.d.ts +2 -5
  62. package/dist/locale-cmd.js +62 -142
  63. package/dist/locale-delivery.d.ts +294 -191
  64. package/dist/locale-delivery.js +8 -94
  65. package/dist/locale-route-emit.d.ts +23 -9
  66. package/dist/locale-route-emit.js +0 -7
  67. package/dist/locale-router.d.ts +189 -162
  68. package/dist/locale-router.js +13 -122
  69. package/dist/locale-runtime.d.ts +292 -262
  70. package/dist/locale-runtime.js +8 -102
  71. package/dist/locale-schema.js +0 -1
  72. package/dist/locale-tooling.d.ts +100 -63
  73. package/dist/locale-tooling.js +7 -45
  74. package/dist/log.d.ts +22 -15
  75. package/dist/log.js +24 -21
  76. package/dist/native-addon.d.ts +10 -9
  77. package/dist/native-addon.js +1 -10
  78. package/dist/pack-client-packages.d.ts +5 -1
  79. package/dist/pack-client-packages.js +0 -6
  80. package/dist/pack.d.ts +17 -15
  81. package/dist/pack.js +0 -12
  82. package/dist/packages.d.ts +10 -23
  83. package/dist/packages.js +1 -37
  84. package/dist/plan-cmd.d.ts +6 -0
  85. package/dist/plan-cmd.js +35 -0
  86. package/dist/plugin-host.js +0 -1
  87. package/dist/port.d.ts +2 -10
  88. package/dist/port.js +2 -11
  89. package/dist/pretty-json.d.ts +9 -19
  90. package/dist/pretty-json.js +3 -17
  91. package/dist/production-observability.d.ts +37 -181
  92. package/dist/production-observability.js +1 -9
  93. package/dist/production-test-pack.d.ts +17 -3
  94. package/dist/production-test-pack.js +0 -2
  95. package/dist/public-static-assets.d.ts +6 -1
  96. package/dist/public-static-assets.js +0 -5
  97. package/dist/refactor-cmd.d.ts +3 -6
  98. package/dist/refactor-cmd.js +16 -69
  99. package/dist/release-cmd.d.ts +7 -6
  100. package/dist/release-cmd.js +17 -59
  101. package/dist/release-pack.d.ts +7 -3
  102. package/dist/release-pack.js +0 -6
  103. package/dist/resolve.d.ts +15 -19
  104. package/dist/resolve.js +1 -15
  105. package/dist/server-artifact.d.ts +30 -75
  106. package/dist/server-artifact.js +0 -10
  107. package/dist/server-language-backend.d.ts +22 -79
  108. package/dist/server-language-backend.js +0 -26
  109. package/dist/site-delivery.d.ts +46 -59
  110. package/dist/site-delivery.js +3 -8
  111. package/dist/site-favicon.d.ts +6 -1
  112. package/dist/site-favicon.js +0 -5
  113. package/dist/static-emit.d.ts +73 -103
  114. package/dist/static-emit.js +1 -26
  115. package/dist/test-cmd.d.ts +3 -5
  116. package/dist/test-cmd.js +15 -25
  117. package/dist/test-compile.js +0 -1
  118. package/dist/test-discover.js +0 -1
  119. package/dist/test-logic.js +0 -1
  120. package/dist/test-protocol.js +0 -1
  121. package/dist/toolchain-dx.d.ts +11 -0
  122. package/dist/toolchain-dx.js +10 -0
  123. package/dist/watch-diff.d.ts +4 -13
  124. package/dist/watch-diff.js +0 -17
  125. package/dist/wechat-packaging.d.ts +8 -7
  126. package/dist/wechat-packaging.js +0 -6
  127. package/locales/en-US/cli.json +105 -0
  128. package/locales/locales.json +4 -0
  129. package/package.json +15 -12
  130. package/dist/resolve-native-cli.d.ts +0 -14
  131. package/dist/resolve-native-cli.js +0 -84
@@ -1,11 +1,9 @@
1
- // @ts-nocheck
2
1
  /**
3
- * `vmz locale` CLI (–).
2
+ * `vmz locale` — registered on `@vmz/commander`.
4
3
  */
5
4
  import fs from 'node:fs';
6
5
  import path from 'node:path';
7
6
  import { parseAuthorInput } from './author-input.js';
8
- import { parseArgs } from './cli.js';
9
7
  import { checkLocales, emitLocaleTypedModules, localeHasErrors, planLocaleRename } from './locale-check.js';
10
8
  import { checkLocaleDelivery } from './locale-delivery.js';
11
9
  import { checkLocaleRouter } from './locale-router.js';
@@ -13,95 +11,53 @@ import { checkLocaleRuntime } from './locale-runtime.js';
13
11
  import { checkLocaleConformance, diffLocaleCatalogs, explainLocaleMessage, extractHardcodedText, pseudoLocalizeCatalog, } from './locale-tooling.js';
14
12
  import { log } from './log.js';
15
13
  import { emitPrettyJson, generatePrettyJson } from './pretty-json.js';
16
- function printLocaleHelp() {
17
- console.log(`vmz locale — /locales application i18n (–)
18
-
19
- Usage:
20
- vmz locale check [project] Check locales.json5 + catalogs + param contracts
21
- vmz locale list [project] List LocaleIds (manifest order)
22
- vmz locale emit-types [project] Emit #locales/* .d.ts stubs (I1)
23
- vmz locale rename <from> <to> MessageId rename plan (I1)
24
- vmz locale runtime-check [project] LocaleContext / FormatterContext / SSR parity (I2)
25
- vmz locale router-check [project] Route realization / canonical / hreflang / PageMeta (I3)
26
- vmz locale delivery-check [project] Multi-host LocaleDeliveryResolution (I4)
27
- vmz locale explain <message-id> [project] Explain MessageId (I5)
28
- vmz locale diff <base> <target> [project] Diff two locales (I5)
29
- vmz locale extract [project] Hardcoded text sink check (I5)
30
- vmz locale pseudo <source> [project] Pseudo-localize catalog (I5, dev/test)
31
- vmz locale conformance [project] Cross-host MessageId/hash conformance (I5)
32
-
33
- Options:
34
- --root <dir> Project root (default: . or positional)
35
- --out <dir> emit-types / pseudo output
36
- --locale <id> explain requested locale
37
- --delivery <id> explain delivery id
38
- --strict Require variants or explicit fallback for every MessageId
39
- --check extract: treat CJK hardcoded as errors
40
- --production pseudo: fail (pseudo must not ship)
41
- --json [file] Emit check report JSON
42
- `);
43
- }
44
- /**
45
- * @param {string[]} argv
46
- * @returns {Promise<number>}
47
- */
48
- export async function cmdLocale(argv) {
49
- const [sub, ...rest] = argv;
50
- if (!sub || sub === 'help' || sub === '-h' || sub === '--help') {
51
- printLocaleHelp();
52
- return 0;
53
- }
54
- const args = parseArgs(rest);
55
- switch (sub) {
56
- case 'check':
57
- return cmdLocaleCheck(args);
58
- case 'list':
59
- return cmdLocaleList(args);
60
- case 'emit-types':
61
- return cmdLocaleEmitTypes(args);
62
- case 'rename':
63
- return cmdLocaleRename(args);
64
- case 'runtime-check':
65
- return cmdLocaleRuntimeCheck(args);
66
- case 'router-check':
67
- return cmdLocaleRouterCheck(args);
68
- case 'delivery-check':
69
- return cmdLocaleDeliveryCheck(args);
70
- case 'explain':
71
- return cmdLocaleExplain(args);
72
- case 'diff':
73
- return cmdLocaleDiff(args);
74
- case 'extract':
75
- return cmdLocaleExtract(args);
76
- case 'pseudo':
77
- return cmdLocalePseudo(args);
78
- case 'conformance':
79
- return cmdLocaleConformance(args);
80
- default:
81
- log.error(`unknown locale subcommand \`${sub}\``);
82
- printLocaleHelp();
83
- return 1;
84
- }
14
+ export function registerLocaleCommands(parent) {
15
+ const withCommon = (cmd) => cmd
16
+ .option('--root <dir>', 'cli.opt.root')
17
+ .option('--out <dir>', 'cli.opt.out')
18
+ .option('--locale <id>', 'cli.opt.locale')
19
+ .option('--delivery <id>', 'cli.opt.delivery')
20
+ .option('--timezone <tz>', 'cli.opt.timezone')
21
+ .option('--strict', 'cli.opt.strict')
22
+ .option('--check', 'cli.opt.check')
23
+ .option('--production', 'cli.opt.production')
24
+ .option('--json [file]', 'cli.opt.json');
25
+ withCommon(parent.command('check', 'cli.cmd.locale.check')).action((o) => cmdLocaleCheck(o));
26
+ withCommon(parent.command('list', 'cli.cmd.locale.list')).action((o) => cmdLocaleList(o));
27
+ withCommon(parent.command('emit-types', 'cli.cmd.locale.emit-types')).action((o) => cmdLocaleEmitTypes(o));
28
+ withCommon(parent.command('rename', 'cli.cmd.locale.rename')).action((o) => cmdLocaleRename(o));
29
+ withCommon(parent.command('runtime-check', 'cli.cmd.locale.runtime-check')).action((o) => cmdLocaleRuntimeCheck(o));
30
+ withCommon(parent.command('router-check', 'cli.cmd.locale.router-check')).action((o) => cmdLocaleRouterCheck(o));
31
+ withCommon(parent.command('delivery-check', 'cli.cmd.locale.delivery-check')).action((o) => cmdLocaleDeliveryCheck(o));
32
+ withCommon(parent.command('explain', 'cli.cmd.locale.explain')).action((o) => cmdLocaleExplain(o));
33
+ withCommon(parent.command('diff', 'cli.cmd.locale.diff')).action((o) => cmdLocaleDiff(o));
34
+ withCommon(parent.command('extract', 'cli.cmd.locale.extract')).action((o) => cmdLocaleExtract(o));
35
+ withCommon(parent.command('pseudo', 'cli.cmd.locale.pseudo')).action((o) => cmdLocalePseudo(o));
36
+ withCommon(parent.command('conformance', 'cli.cmd.locale.conformance')).action((o) => cmdLocaleConformance(o));
85
37
  }
86
38
  function resolveProject(args) {
87
39
  const project = (typeof args.root === 'string' && args.root) || (typeof args._[0] === 'string' && args._[0]) || '.';
88
40
  return path.resolve(project);
89
41
  }
42
+ function asJsonTarget(value) {
43
+ if (Array.isArray(value))
44
+ return true;
45
+ return value;
46
+ }
47
+ function emitJson(args, report) {
48
+ emitPrettyJson(asJsonTarget(args.json), report, {
49
+ logWrote: (p) => log.info(`wrote ${p}`),
50
+ });
51
+ }
90
52
  function cmdLocaleCheck(args) {
91
53
  const projectRoot = resolveProject(args);
92
54
  const report = checkLocales({ projectRoot, strict: Boolean(args.strict) });
93
- const jsonOut = args.json;
55
+ const jsonOut = asJsonTarget(args.json);
94
56
  if (jsonOut) {
95
57
  emitPrettyJson(jsonOut, report, { logWrote: (p) => log.info(`wrote ${p}`) });
96
58
  }
97
59
  else {
98
- for (const d of report.diagnostics) {
99
- const loc = d.path ? ` (${d.path})` : '';
100
- if (d.severity === 'error')
101
- log.error(`${d.code}: ${d.message}${loc}`);
102
- else
103
- console.warn(`vmz warn ${d.code}: ${d.message}${loc}`);
104
- }
60
+ log.diagnostics(report.diagnostics ?? []);
105
61
  const n = report.messageCatalog?.messages?.length || 0;
106
62
  log.info(`locale check: locales=${(report.manifest?.locales || []).map((l) => l.id).join(',') || '(none)'} messages=${n} status=${report.status}`);
107
63
  }
@@ -111,7 +67,7 @@ function cmdLocaleList(args) {
111
67
  const projectRoot = resolveProject(args);
112
68
  const report = checkLocales({ projectRoot, checkUnused: false });
113
69
  if (!report.manifest) {
114
- console.warn('vmz warn vmz::locale::manifest_missing: locales/locales.json5 missing');
70
+ log.diagnostics(report.diagnostics ?? []);
115
71
  return localeHasErrors(report) ? 1 : 0;
116
72
  }
117
73
  for (const loc of report.manifest.locales) {
@@ -125,9 +81,7 @@ function cmdLocaleEmitTypes(args) {
125
81
  const outDir = (typeof args.out === 'string' && args.out) || path.join(projectRoot, 'dist', 'locales-types');
126
82
  const report = checkLocales({ projectRoot, strict: Boolean(args.strict) });
127
83
  if (localeHasErrors(report)) {
128
- for (const d of report.diagnostics.filter((x) => x.severity === 'error')) {
129
- log.error(`${d.code}: ${d.message}`);
130
- }
84
+ log.diagnostics((report.diagnostics || []).filter((x) => x.severity === 'error'));
131
85
  return 1;
132
86
  }
133
87
  const written = emitLocaleTypedModules(report, outDir);
@@ -138,14 +92,14 @@ function cmdLocaleRename(args) {
138
92
  const fromId = typeof args._[0] === 'string' ? args._[0] : '';
139
93
  const toId = typeof args._[1] === 'string' ? args._[1] : '';
140
94
  if (!fromId || !toId) {
141
- log.error('usage: vmz locale rename <from-message-id> <to-message-id>');
95
+ log.errorId('cli.err.locale_rename_usage');
142
96
  return 1;
143
97
  }
144
98
  const projectRoot = resolveProject({ ...args, _: args._.slice(2) });
145
99
  const report = checkLocales({ projectRoot, checkUnused: false });
146
100
  const plan = planLocaleRename(report, fromId, toId);
147
101
  if (args.json) {
148
- emitPrettyJson(args.json, plan);
102
+ emitPrettyJson(asJsonTarget(args.json), plan);
149
103
  }
150
104
  else if (plan.status !== 'ready') {
151
105
  log.error(plan.error || 'rename failed');
@@ -161,9 +115,7 @@ function cmdLocaleRuntimeCheck(args) {
161
115
  const projectRoot = resolveProject(args);
162
116
  const base = checkLocales({ projectRoot, checkUnused: false });
163
117
  if (localeHasErrors(base) || !base.manifest) {
164
- for (const d of (base.diagnostics || []).filter((x) => x.severity === 'error')) {
165
- log.error(`${d.code}: ${d.message}`);
166
- }
118
+ log.diagnostics((base.diagnostics || []).filter((x) => x.severity === 'error'));
167
119
  return 1;
168
120
  }
169
121
  const report = checkLocaleRuntime({
@@ -178,12 +130,7 @@ function cmdLocaleRuntimeCheck(args) {
178
130
  emitJson(args, jsonReport);
179
131
  }
180
132
  else {
181
- for (const d of report.diagnostics) {
182
- if (d.severity === 'error')
183
- log.error(`${d.code}: ${d.message}`);
184
- else
185
- console.warn(`vmz warn ${d.code}: ${d.message}`);
186
- }
133
+ log.diagnostics(report.diagnostics ?? []);
187
134
  log.info(`locale runtime-check: locale=${report.applicationContext?.localeId} digest=${report.formatterDigest} status=${report.status}`);
188
135
  }
189
136
  return report.status === 'ready' ? 0 : 1;
@@ -192,7 +139,10 @@ function loadRoutesFixture(projectRoot) {
192
139
  const candidates = [path.join(projectRoot, 'locale-routes.json5'), path.join(projectRoot, 'locale-routes.json')];
193
140
  for (const p of candidates) {
194
141
  if (fs.existsSync(p)) {
195
- return parseAuthorInput(fs.readFileSync(p, 'utf8'));
142
+ const parsed = parseAuthorInput(fs.readFileSync(p, 'utf8'));
143
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
144
+ return parsed;
145
+ }
196
146
  }
197
147
  }
198
148
  return {
@@ -205,9 +155,7 @@ function cmdLocaleRouterCheck(args) {
205
155
  const projectRoot = resolveProject(args);
206
156
  const base = checkLocales({ projectRoot, checkUnused: false });
207
157
  if (localeHasErrors(base) || !base.manifest) {
208
- for (const d of (base.diagnostics || []).filter((x) => x.severity === 'error')) {
209
- log.error(`${d.code}: ${d.message}`);
210
- }
158
+ log.diagnostics((base.diagnostics || []).filter((x) => x.severity === 'error'));
211
159
  return 1;
212
160
  }
213
161
  const routesFile = loadRoutesFixture(projectRoot);
@@ -221,12 +169,7 @@ function cmdLocaleRouterCheck(args) {
221
169
  emitJson(args, report);
222
170
  }
223
171
  else {
224
- for (const d of report.diagnostics) {
225
- if (d.severity === 'error')
226
- log.error(`${d.code}: ${d.message}`);
227
- else
228
- console.warn(`vmz warn ${d.code}: ${d.message}`);
229
- }
172
+ log.diagnostics(report.diagnostics ?? []);
230
173
  const n = report.realizationTable?.realizations?.length || 0;
231
174
  log.info(`locale router-check: realizations=${n} pageMetas=${report.pageMetas?.length || 0} status=${report.status}`);
232
175
  }
@@ -236,9 +179,7 @@ function cmdLocaleDeliveryCheck(args) {
236
179
  const projectRoot = resolveProject(args);
237
180
  const base = checkLocales({ projectRoot, checkUnused: false });
238
181
  if (localeHasErrors(base) || !base.manifest) {
239
- for (const d of (base.diagnostics || []).filter((x) => x.severity === 'error')) {
240
- log.error(`${d.code}: ${d.message}`);
241
- }
182
+ log.diagnostics((base.diagnostics || []).filter((x) => x.severity === 'error'));
242
183
  return 1;
243
184
  }
244
185
  const report = checkLocaleDelivery({
@@ -251,34 +192,22 @@ function cmdLocaleDeliveryCheck(args) {
251
192
  emitJson(args, report);
252
193
  }
253
194
  else {
254
- for (const d of report.diagnostics) {
255
- if (d.severity === 'error')
256
- log.error(`${d.code}: ${d.message}`);
257
- else
258
- console.warn(`vmz warn ${d.code}: ${d.message}`);
259
- }
195
+ log.diagnostics(report.diagnostics ?? []);
260
196
  const hosts = Object.keys(report.resolutions || {}).join(',');
261
197
  log.info(`locale delivery-check: hosts=${hosts} status=${report.status}`);
262
198
  }
263
199
  return report.status === 'ready' ? 0 : 1;
264
200
  }
265
- function emitJson(args, report) {
266
- emitPrettyJson(args.json, report, {
267
- logWrote: (p) => log.info(`wrote ${p}`),
268
- });
269
- }
270
201
  function cmdLocaleExplain(args) {
271
202
  const messageId = typeof args._[0] === 'string' ? args._[0] : '';
272
203
  if (!messageId) {
273
- log.error('usage: vmz locale explain <message-id> [project]');
204
+ log.errorId('cli.err.locale_explain_usage');
274
205
  return 1;
275
206
  }
276
207
  const projectRoot = resolveProject({ ...args, _: args._.slice(1) });
277
208
  const base = checkLocales({ projectRoot, checkUnused: false });
278
209
  if (localeHasErrors(base) || !base.manifest) {
279
- for (const d of (base.diagnostics || []).filter((x) => x.severity === 'error')) {
280
- log.error(`${d.code}: ${d.message}`);
281
- }
210
+ log.diagnostics((base.diagnostics || []).filter((x) => x.severity === 'error'));
282
211
  return 1;
283
212
  }
284
213
  const report = explainLocaleMessage({
@@ -290,8 +219,7 @@ function cmdLocaleExplain(args) {
290
219
  if (args.json)
291
220
  emitJson(args, report);
292
221
  else if (report.status !== 'ready') {
293
- for (const d of report.diagnostics)
294
- log.error(`${d.code}: ${d.message}`);
222
+ log.diagnostics(report.diagnostics ?? []);
295
223
  }
296
224
  else {
297
225
  log.info(`explain ${report.messageId}: resolved=${report.resolvedLocale} params=${(report.params || []).map((p) => p.name).join(',') || '(none)'}`);
@@ -305,7 +233,7 @@ function cmdLocaleDiff(args) {
305
233
  const baseLocale = typeof args._[0] === 'string' ? args._[0] : '';
306
234
  const targetLocale = typeof args._[1] === 'string' ? args._[1] : '';
307
235
  if (!baseLocale || !targetLocale) {
308
- log.error('usage: vmz locale diff <base-locale> <target-locale> [project]');
236
+ log.errorId('cli.err.locale_diff_usage');
309
237
  return 1;
310
238
  }
311
239
  const projectRoot = resolveProject({ ...args, _: args._.slice(2) });
@@ -334,12 +262,7 @@ function cmdLocaleExtract(args) {
334
262
  if (args.json)
335
263
  emitJson(args, report);
336
264
  else {
337
- for (const d of report.diagnostics) {
338
- if (d.severity === 'error')
339
- log.error(`${d.code}: ${d.message}`);
340
- else
341
- console.warn(`vmz warn ${d.code}: ${d.message}`);
342
- }
265
+ log.diagnostics(report.diagnostics ?? []);
343
266
  log.info(`locale extract: findings=${report.findings?.length || 0} status=${report.status}`);
344
267
  }
345
268
  return report.status === 'ready' ? 0 : 1;
@@ -347,7 +270,7 @@ function cmdLocaleExtract(args) {
347
270
  function cmdLocalePseudo(args) {
348
271
  const sourceLocale = typeof args._[0] === 'string' ? args._[0] : '';
349
272
  if (!sourceLocale) {
350
- log.error('usage: vmz locale pseudo <source-locale> [project]');
273
+ log.errorId('cli.err.locale_pseudo_usage');
351
274
  return 1;
352
275
  }
353
276
  const projectRoot = resolveProject({ ...args, _: args._.slice(1) });
@@ -362,8 +285,7 @@ function cmdLocalePseudo(args) {
362
285
  if (args.json)
363
286
  emitJson(args, report);
364
287
  else if (report.status !== 'ready') {
365
- for (const d of report.diagnostics)
366
- log.error(`${d.code}: ${d.message}`);
288
+ log.diagnostics(report.diagnostics ?? []);
367
289
  }
368
290
  else {
369
291
  const outDir = (typeof args.out === 'string' && args.out) || path.join(projectRoot, 'dist', 'locales-pseudo');
@@ -384,7 +306,10 @@ function cmdLocaleConformance(args) {
384
306
  if (fs.existsSync(routesPath)) {
385
307
  try {
386
308
  const routesFile = parseAuthorInput(fs.readFileSync(routesPath, 'utf8'));
387
- routeIds = (routesFile.routes || []).map((r) => r.routeId);
309
+ if (routesFile && typeof routesFile === 'object' && !Array.isArray(routesFile) && 'routes' in routesFile) {
310
+ const routes = routesFile.routes || [];
311
+ routeIds = routes.map((r) => String(r.routeId || '')).filter(Boolean);
312
+ }
388
313
  }
389
314
  catch {
390
315
  /* ignore */
@@ -398,12 +323,7 @@ function cmdLocaleConformance(args) {
398
323
  if (args.json)
399
324
  emitJson(args, report);
400
325
  else {
401
- for (const d of report.diagnostics) {
402
- if (d.severity === 'error')
403
- log.error(`${d.code}: ${d.message}`);
404
- else
405
- console.warn(`vmz warn ${d.code}: ${d.message}`);
406
- }
326
+ log.diagnostics(report.diagnostics ?? []);
407
327
  log.info(`locale conformance: hosts=${(report.hosts || []).join(',')} messages=${report.messageIds?.length || 0} status=${report.status}`);
408
328
  }
409
329
  return report.status === 'ready' ? 0 : 1;