@vmz/vmz 0.0.2 → 0.0.4
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 +19 -13
- package/dist/application-cmd.d.ts +1 -2
- package/dist/application-cmd.js +9 -10
- package/dist/bundler-adapter.d.ts +2 -3
- package/dist/bundler-adapter.js +2 -3
- package/dist/cdn-policy.d.ts +178 -0
- package/dist/cdn-policy.js +344 -0
- package/dist/cli.d.ts +10 -2
- package/dist/cli.js +179 -16
- package/dist/content-addressed-assets.d.ts +69 -0
- package/dist/content-addressed-assets.js +206 -0
- package/dist/dev-session.d.ts +2 -2
- package/dist/dev-session.js +51 -16
- package/dist/document-build.js +1 -2
- package/dist/document-check.d.ts +1 -1
- package/dist/document-check.js +4 -4
- package/dist/document-cmd.d.ts +1 -2
- package/dist/document-cmd.js +2 -3
- package/dist/document-designs.js +31 -3
- package/dist/document-enrich.js +2 -3
- package/dist/document-evidence.d.ts +4 -4
- package/dist/document-evidence.js +20 -12
- package/dist/document-integrate.d.ts +0 -1
- package/dist/document-integrate.js +0 -1
- package/dist/document-interactive.d.ts +11 -11
- package/dist/document-interactive.js +12 -13
- package/dist/document-locale.d.ts +1 -1
- package/dist/document-locale.js +1 -1
- package/dist/document-markdown.d.ts +1 -2
- package/dist/document-markdown.js +13 -7
- package/dist/document-scan.d.ts +4 -4
- package/dist/document-scan.js +4 -4
- package/dist/document-schema.d.ts +28 -29
- package/dist/document-schema.js +28 -29
- package/dist/explain-cmd.js +3 -3
- package/dist/index.d.ts +349 -789
- package/dist/index.js +109 -85
- package/dist/invocation.d.ts +68 -0
- package/dist/invocation.js +169 -0
- package/dist/locale-check.d.ts +19 -3
- package/dist/locale-check.js +130 -6
- package/dist/locale-cmd.js +6 -7
- package/dist/locale-delivery.d.ts +38 -38
- package/dist/locale-delivery.js +39 -40
- package/dist/locale-router.d.ts +39 -40
- package/dist/locale-router.js +39 -40
- package/dist/locale-runtime.d.ts +39 -39
- package/dist/locale-runtime.js +44 -45
- package/dist/locale-schema.d.ts +1 -2
- package/dist/locale-schema.js +1 -2
- package/dist/locale-tooling.d.ts +13 -13
- package/dist/locale-tooling.js +14 -15
- package/dist/log.d.ts +1 -1
- package/dist/log.js +1 -1
- package/dist/packages.d.ts +1 -2
- package/dist/packages.js +1 -2
- package/dist/plugin-host.d.ts +11 -3
- package/dist/plugin-host.js +21 -5
- package/dist/port.d.ts +10 -0
- package/dist/port.js +46 -0
- package/dist/production-observability.d.ts +286 -0
- package/dist/production-observability.js +469 -0
- package/dist/production-test-pack.d.ts +158 -0
- package/dist/production-test-pack.js +452 -0
- package/dist/refactor-cmd.d.ts +1 -1
- package/dist/refactor-cmd.js +6 -6
- package/dist/release-cmd.d.ts +8 -0
- package/dist/release-cmd.js +126 -0
- package/dist/release-pack.d.ts +96 -0
- package/dist/release-pack.js +337 -0
- package/dist/resolve-native-cli.d.ts +14 -0
- package/dist/resolve-native-cli.js +84 -0
- package/dist/resolve.d.ts +1 -2
- package/dist/resolve.js +1 -2
- package/dist/site-delivery.d.ts +134 -0
- package/dist/site-delivery.js +345 -0
- package/dist/static-emit.d.ts +136 -0
- package/dist/static-emit.js +463 -0
- package/dist/test-cmd.d.ts +2 -2
- package/dist/test-cmd.js +37 -17
- package/dist/watch-diff.d.ts +1 -1
- package/dist/watch-diff.js +1 -1
- package/package.json +32 -17
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* `vmz` CLI invocation modes (JS gate only; Rust binary stays full).
|
|
4
|
+
*
|
|
5
|
+
* Product install face: workspace `vmz` / publish `@vmz/vmz` (bin still `vmz`).
|
|
6
|
+
*
|
|
7
|
+
* Three modes — do not collapse them:
|
|
8
|
+
* - **developer**: monorepo source checkout (`packages/runtimes/vmz`, not under node_modules)
|
|
9
|
+
* - **project**: app's nearest `node_modules/vmz` or `node_modules/@vmz/vmz`
|
|
10
|
+
* - **global**: npm/pnpm global (or any install under node_modules that is not the nearest project one)
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
import { spawn } from 'node:child_process';
|
|
14
|
+
import { existsSync, realpathSync } from 'node:fs';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
17
|
+
/** @typedef {'developer' | 'project' | 'global'} InvocationMode */
|
|
18
|
+
const PROJECT_PKG_SEGMENTS = [['@vmz', 'vmz'], ['vmz']];
|
|
19
|
+
/**
|
|
20
|
+
* Package root of the running `vmz` / `@vmz/vmz` install.
|
|
21
|
+
* @param {string} [fromUrl]
|
|
22
|
+
*/
|
|
23
|
+
export function resolveThisPackageRoot(fromUrl = import.meta.url) {
|
|
24
|
+
return path.resolve(path.dirname(fileURLToPath(fromUrl)), '..');
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* @param {string} p
|
|
28
|
+
*/
|
|
29
|
+
function tryRealpath(p) {
|
|
30
|
+
try {
|
|
31
|
+
return realpathSync(p);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return path.resolve(p);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Walk from `startDir` for nearest project CLI package root.
|
|
39
|
+
* @param {string} startDir
|
|
40
|
+
* @returns {string | null}
|
|
41
|
+
*/
|
|
42
|
+
export function findNearestProjectVmz(startDir) {
|
|
43
|
+
let dir = path.resolve(startDir);
|
|
44
|
+
for (;;) {
|
|
45
|
+
for (const segments of PROJECT_PKG_SEGMENTS) {
|
|
46
|
+
const candidate = path.join(dir, 'node_modules', ...segments);
|
|
47
|
+
const pkgJson = path.join(candidate, 'package.json');
|
|
48
|
+
if (existsSync(pkgJson)) {
|
|
49
|
+
return tryRealpath(candidate);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const parent = path.dirname(dir);
|
|
53
|
+
if (parent === dir)
|
|
54
|
+
return null;
|
|
55
|
+
dir = parent;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve CLI entry (`bin/vmz.js`).
|
|
60
|
+
* @param {string} packageRoot
|
|
61
|
+
* @returns {string | null}
|
|
62
|
+
*/
|
|
63
|
+
export function resolveVmzBin(packageRoot) {
|
|
64
|
+
const bin = path.join(packageRoot, 'bin', 'vmz.js');
|
|
65
|
+
if (existsSync(bin))
|
|
66
|
+
return tryRealpath(bin);
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* @param {string} packageRoot
|
|
71
|
+
*/
|
|
72
|
+
export function isUnderNodeModules(packageRoot) {
|
|
73
|
+
const norm = path.normalize(packageRoot);
|
|
74
|
+
const parts = norm.split(path.sep);
|
|
75
|
+
return parts.includes('node_modules');
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* @param {{
|
|
79
|
+
* cwd?: string,
|
|
80
|
+
* thisPackageRoot?: string,
|
|
81
|
+
* }} [opts]
|
|
82
|
+
*/
|
|
83
|
+
export function getInvocationContext(opts = {}) {
|
|
84
|
+
const cwd = path.resolve(opts.cwd ?? process.cwd());
|
|
85
|
+
const thisPackageRoot = tryRealpath(opts.thisPackageRoot ?? resolveThisPackageRoot());
|
|
86
|
+
const nearestProjectVmz = findNearestProjectVmz(cwd);
|
|
87
|
+
const underNm = isUnderNodeModules(thisPackageRoot);
|
|
88
|
+
/** @type {InvocationMode} */
|
|
89
|
+
let mode;
|
|
90
|
+
if (!underNm) {
|
|
91
|
+
mode = 'developer';
|
|
92
|
+
}
|
|
93
|
+
else if (nearestProjectVmz != null && nearestProjectVmz === thisPackageRoot) {
|
|
94
|
+
mode = 'project';
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
mode = 'global';
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
mode,
|
|
101
|
+
cwd,
|
|
102
|
+
thisPackageRoot,
|
|
103
|
+
nearestProjectVmz,
|
|
104
|
+
isDeveloper: mode === 'developer',
|
|
105
|
+
isProjectLocal: mode === 'project',
|
|
106
|
+
/** @deprecated prefer `mode === 'global'`; kept for call sites */
|
|
107
|
+
isGlobalLike: mode === 'global',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* @param {string | undefined} cmd
|
|
112
|
+
*/
|
|
113
|
+
export function isGlobalAllowedCommand(cmd) {
|
|
114
|
+
if (!cmd)
|
|
115
|
+
return true;
|
|
116
|
+
return (cmd === 'help' ||
|
|
117
|
+
cmd === '-h' ||
|
|
118
|
+
cmd === '--help' ||
|
|
119
|
+
cmd === 'version' ||
|
|
120
|
+
cmd === '-V' ||
|
|
121
|
+
cmd === '--version' ||
|
|
122
|
+
cmd === 'new' ||
|
|
123
|
+
cmd === 'init');
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* @param {string} bin
|
|
127
|
+
* @param {string[]} argv
|
|
128
|
+
* @returns {Promise<number>}
|
|
129
|
+
*/
|
|
130
|
+
export function reexecProjectVmz(bin, argv) {
|
|
131
|
+
return new Promise((resolve) => {
|
|
132
|
+
const child = spawn(process.execPath, [bin, ...argv], {
|
|
133
|
+
stdio: 'inherit',
|
|
134
|
+
env: process.env,
|
|
135
|
+
});
|
|
136
|
+
child.on('error', () => resolve(1));
|
|
137
|
+
child.on('exit', (code, signal) => {
|
|
138
|
+
if (signal)
|
|
139
|
+
resolve(1);
|
|
140
|
+
else
|
|
141
|
+
resolve(code ?? 1);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* @returns {Promise<{ action: 'proceed' } | { action: 'exit', code: number }>}
|
|
147
|
+
*/
|
|
148
|
+
export async function gateGlobalProjectCommand(opts) {
|
|
149
|
+
const { argv, cwd = process.cwd(), thisPackageRoot, reexec = reexecProjectVmz, logError = (msg) => console.error(msg) } = opts;
|
|
150
|
+
const ctx = getInvocationContext({ cwd, thisPackageRoot });
|
|
151
|
+
if (ctx.mode !== 'global') {
|
|
152
|
+
return { action: 'proceed' };
|
|
153
|
+
}
|
|
154
|
+
if (ctx.nearestProjectVmz && ctx.nearestProjectVmz !== ctx.thisPackageRoot) {
|
|
155
|
+
const bin = resolveVmzBin(ctx.nearestProjectVmz);
|
|
156
|
+
if (!bin) {
|
|
157
|
+
logError('found project `vmz` / `@vmz/vmz` but bin/vmz.js is missing.');
|
|
158
|
+
return { action: 'exit', code: 1 };
|
|
159
|
+
}
|
|
160
|
+
const code = await reexec(bin, argv);
|
|
161
|
+
return { action: 'exit', code };
|
|
162
|
+
}
|
|
163
|
+
logError('this `vmz` is a global install (mode=global); project commands need a project install.');
|
|
164
|
+
logError('Install in the app: pnpm add -D @vmz/vmz');
|
|
165
|
+
logError('Or scaffold: vmz new <dir>');
|
|
166
|
+
logError('Then run: pnpm exec vmz <command>');
|
|
167
|
+
logError('(developer mode: run from vmz-framework packages/runtimes/vmz source — full CLI)');
|
|
168
|
+
return { action: 'exit', code: 1 };
|
|
169
|
+
}
|
package/dist/locale-check.d.ts
CHANGED
|
@@ -67,7 +67,7 @@ export declare function checkLocales(opts: any): {
|
|
|
67
67
|
};
|
|
68
68
|
/**
|
|
69
69
|
* Scan src for `#locales/<catalog>` imports and `messageId` string literals after import.
|
|
70
|
-
* First-slice heuristic — full VPG edges land with compiler
|
|
70
|
+
* First-slice heuristic — full VPG edges land with compiler deepen.
|
|
71
71
|
*/
|
|
72
72
|
export declare function scanLocaleUsages(projectRoot: any): {
|
|
73
73
|
catalogs: Set<unknown>;
|
|
@@ -75,13 +75,29 @@ export declare function scanLocaleUsages(projectRoot: any): {
|
|
|
75
75
|
importedNames: Map<any, any>;
|
|
76
76
|
};
|
|
77
77
|
/**
|
|
78
|
-
* Emit typed module stubs for `#locales/*` (
|
|
78
|
+
* Emit typed module stubs for `#locales/*` ( surface).
|
|
79
79
|
* @param {ReturnType<typeof checkLocales>} report
|
|
80
80
|
* @param {string} outDir
|
|
81
81
|
*/
|
|
82
82
|
export declare function emitLocaleTypedModules(report: any, outDir: any): any[];
|
|
83
83
|
/**
|
|
84
|
-
*
|
|
84
|
+
* Emit runtime `#locales/<catalog>.js` into application `dist/` and rewrite
|
|
85
|
+
* client imports from `#locales/...` to relative ESM paths.
|
|
86
|
+
*
|
|
87
|
+
* Variant pick reads `html[data-locale]` (else defaultLocale). Thin bridge until
|
|
88
|
+
* host LocaleTransition reloads locale-scoped chunks (I2/I4).
|
|
89
|
+
*
|
|
90
|
+
* @param {string} projectRoot
|
|
91
|
+
* @param {string} distDir
|
|
92
|
+
* @returns {{ ok: boolean, written: string[], diagnostics: any[] }}
|
|
93
|
+
*/
|
|
94
|
+
export declare function emitLocaleRuntimeModules(projectRoot: any, distDir: any): {
|
|
95
|
+
ok: boolean;
|
|
96
|
+
written: any[];
|
|
97
|
+
diagnostics: any;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* MessageId rename plan — WorkspaceEdit-shaped, no parallel rename IR.
|
|
85
101
|
* @param {ReturnType<typeof checkLocales>} report
|
|
86
102
|
* @param {string} fromId
|
|
87
103
|
* @param {string} toId
|
package/dist/locale-check.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* Locale
|
|
4
|
-
* Design: 规划设计/vmz/28 · I0/I1
|
|
3
|
+
* Locale check + message contracts / typed module projection.
|
|
5
4
|
*
|
|
6
5
|
* Not an I18n IR: filesystem + MessageCatalogManifest projection into VPG-shaped views.
|
|
7
6
|
*/
|
|
@@ -485,7 +484,7 @@ export function checkLocales(opts) {
|
|
|
485
484
|
}
|
|
486
485
|
}
|
|
487
486
|
}
|
|
488
|
-
//
|
|
487
|
+
// scan source for #locales/* imports / message references.
|
|
489
488
|
const used = scanLocaleUsages(projectRoot);
|
|
490
489
|
/** @type {any[]} */
|
|
491
490
|
const typedModules = [];
|
|
@@ -611,7 +610,7 @@ function walkCatalogFiles(dir, fn) {
|
|
|
611
610
|
}
|
|
612
611
|
/**
|
|
613
612
|
* Scan src for `#locales/<catalog>` imports and `messageId` string literals after import.
|
|
614
|
-
* First-slice heuristic — full VPG edges land with compiler
|
|
613
|
+
* First-slice heuristic — full VPG edges land with compiler deepen.
|
|
615
614
|
*/
|
|
616
615
|
export function scanLocaleUsages(projectRoot) {
|
|
617
616
|
/** @type {Set<string>} */
|
|
@@ -658,7 +657,7 @@ function walkSource(dir, fn) {
|
|
|
658
657
|
}
|
|
659
658
|
}
|
|
660
659
|
/**
|
|
661
|
-
* Emit typed module stubs for `#locales/*` (
|
|
660
|
+
* Emit typed module stubs for `#locales/*` ( surface).
|
|
662
661
|
* @param {ReturnType<typeof checkLocales>} report
|
|
663
662
|
* @param {string} outDir
|
|
664
663
|
*/
|
|
@@ -696,7 +695,132 @@ export function emitLocaleTypedModules(report, outDir) {
|
|
|
696
695
|
return written;
|
|
697
696
|
}
|
|
698
697
|
/**
|
|
699
|
-
*
|
|
698
|
+
* Emit runtime `#locales/<catalog>.js` into application `dist/` and rewrite
|
|
699
|
+
* client imports from `#locales/...` to relative ESM paths.
|
|
700
|
+
*
|
|
701
|
+
* Variant pick reads `html[data-locale]` (else defaultLocale). Thin bridge until
|
|
702
|
+
* host LocaleTransition reloads locale-scoped chunks (I2/I4).
|
|
703
|
+
*
|
|
704
|
+
* @param {string} projectRoot
|
|
705
|
+
* @param {string} distDir
|
|
706
|
+
* @returns {{ ok: boolean, written: string[], diagnostics: any[] }}
|
|
707
|
+
*/
|
|
708
|
+
export function emitLocaleRuntimeModules(projectRoot, distDir) {
|
|
709
|
+
const localesRoot = path.join(projectRoot, 'locales');
|
|
710
|
+
if (!fs.existsSync(localesRoot)) {
|
|
711
|
+
return { ok: true, written: [], diagnostics: [] };
|
|
712
|
+
}
|
|
713
|
+
const report = checkLocales({ projectRoot, checkUnused: false });
|
|
714
|
+
if (localeHasErrors(report)) {
|
|
715
|
+
return { ok: false, written: [], diagnostics: report.diagnostics || [] };
|
|
716
|
+
}
|
|
717
|
+
const defaultLocale = report.manifest?.defaultLocale || 'zh-hans';
|
|
718
|
+
const byId = new Map((report.messageCatalog?.messages || []).map((m) => [m.messageId, m]));
|
|
719
|
+
/** @type {string[]} */
|
|
720
|
+
const written = [];
|
|
721
|
+
const localesOut = path.join(distDir, 'locales');
|
|
722
|
+
fs.mkdirSync(localesOut, { recursive: true });
|
|
723
|
+
for (const mod of report.typedModules || []) {
|
|
724
|
+
const lines = [
|
|
725
|
+
`/** Generated ${mod.module} — runtime LocalizedText (defaultLocale=${defaultLocale}) */`,
|
|
726
|
+
`const __vmzDefaultLocale = ${JSON.stringify(defaultLocale)};`,
|
|
727
|
+
`function __vmzLocaleId() {`,
|
|
728
|
+
` try {`,
|
|
729
|
+
` const stored = localStorage.getItem("vmz.locale");`,
|
|
730
|
+
` if (stored) return stored;`,
|
|
731
|
+
` } catch {}`,
|
|
732
|
+
` if (typeof document !== "undefined") {`,
|
|
733
|
+
` const d = document.documentElement?.getAttribute("data-locale");`,
|
|
734
|
+
` if (d) return d;`,
|
|
735
|
+
` const lang = document.documentElement?.lang;`,
|
|
736
|
+
` if (lang === "en" || lang === "en-US" || lang === "en-us") return "en-us";`,
|
|
737
|
+
` if (lang === "zh" || lang === "zh-CN" || lang === "zh-Hans" || lang === "zh-hans") return "zh-hans";`,
|
|
738
|
+
` }`,
|
|
739
|
+
` return __vmzDefaultLocale;`,
|
|
740
|
+
`}`,
|
|
741
|
+
`function __vmzFormat(template, args) {`,
|
|
742
|
+
` if (!args) return String(template ?? "");`,
|
|
743
|
+
` return String(template ?? "").replace(/\\{(\\w+)(?:,\\s*\\w+)?\\}/g, (m, name) =>`,
|
|
744
|
+
` Object.prototype.hasOwnProperty.call(args, name) ? String(args[name]) : m`,
|
|
745
|
+
` );`,
|
|
746
|
+
`}`,
|
|
747
|
+
`function __vmzPick(variants, args) {`,
|
|
748
|
+
` const id = __vmzLocaleId();`,
|
|
749
|
+
` const template = variants[id] ?? variants[__vmzDefaultLocale] ?? "";`,
|
|
750
|
+
` return __vmzFormat(template, args);`,
|
|
751
|
+
`}`,
|
|
752
|
+
'',
|
|
753
|
+
];
|
|
754
|
+
for (const exp of mod.exports || []) {
|
|
755
|
+
const node = byId.get(exp.messageId);
|
|
756
|
+
const variants = {};
|
|
757
|
+
if (node?.variants) {
|
|
758
|
+
for (const [loc, v] of Object.entries(node.variants)) {
|
|
759
|
+
variants[loc] = v.template;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
const lit = JSON.stringify(variants);
|
|
763
|
+
if ((exp.params || []).length) {
|
|
764
|
+
lines.push(`export function ${exp.exportName}(args) { return __vmzPick(${lit}, args); }`);
|
|
765
|
+
}
|
|
766
|
+
else {
|
|
767
|
+
lines.push(`export function ${exp.exportName}() { return __vmzPick(${lit}); }`);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
lines.push('');
|
|
771
|
+
const file = path.join(localesOut, `${mod.catalogId}.js`);
|
|
772
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
773
|
+
fs.writeFileSync(file, lines.join('\n'), 'utf8');
|
|
774
|
+
written.push(file);
|
|
775
|
+
}
|
|
776
|
+
rewriteLocaleImportsInDist(distDir);
|
|
777
|
+
return { ok: true, written, diagnostics: report.diagnostics || [] };
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* @param {string} distDir
|
|
781
|
+
*/
|
|
782
|
+
function rewriteLocaleImportsInDist(distDir) {
|
|
783
|
+
/** @type {string[]} */
|
|
784
|
+
const files = [];
|
|
785
|
+
walkDistJs(distDir, (file) => files.push(file));
|
|
786
|
+
for (const file of files) {
|
|
787
|
+
let text = fs.readFileSync(file, 'utf8');
|
|
788
|
+
if (!text.includes('#locales/'))
|
|
789
|
+
continue;
|
|
790
|
+
const fromDir = path.dirname(file);
|
|
791
|
+
// Emit path is dist/locales/*.js — `#` cannot appear in ESM file URLs (fragment).
|
|
792
|
+
const next = text.replace(/from\s*(["'])#locales\/([^"']+)\1/g, (_m, quote, id) => {
|
|
793
|
+
const target = path.join(distDir, 'locales', `${id}.js`);
|
|
794
|
+
let rel = path.relative(fromDir, target).replace(/\\/g, '/');
|
|
795
|
+
if (!rel.startsWith('.'))
|
|
796
|
+
rel = `./${rel}`;
|
|
797
|
+
return `from ${quote}${rel}${quote}`;
|
|
798
|
+
});
|
|
799
|
+
if (next !== text)
|
|
800
|
+
fs.writeFileSync(file, next, 'utf8');
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* @param {string} dir
|
|
805
|
+
* @param {(file: string) => void} fn
|
|
806
|
+
*/
|
|
807
|
+
function walkDistJs(dir, fn) {
|
|
808
|
+
if (!fs.existsSync(dir))
|
|
809
|
+
return;
|
|
810
|
+
for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
811
|
+
const full = path.join(dir, ent.name);
|
|
812
|
+
if (ent.isDirectory()) {
|
|
813
|
+
if (ent.name === 'node_modules')
|
|
814
|
+
continue;
|
|
815
|
+
walkDistJs(full, fn);
|
|
816
|
+
}
|
|
817
|
+
else if (ent.name.endsWith('.js') || ent.name.endsWith('.mjs')) {
|
|
818
|
+
fn(full);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* MessageId rename plan — WorkspaceEdit-shaped, no parallel rename IR.
|
|
700
824
|
* @param {ReturnType<typeof checkLocales>} report
|
|
701
825
|
* @param {string} fromId
|
|
702
826
|
* @param {string} toId
|
package/dist/locale-cmd.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* `vmz locale` CLI (
|
|
4
|
-
* Design: 规划设计/vmz/28 §12
|
|
3
|
+
* `vmz locale` CLI (–).
|
|
5
4
|
*/
|
|
6
5
|
import fs from 'node:fs';
|
|
7
6
|
import path from 'node:path';
|
|
@@ -14,7 +13,7 @@ import { checkLocaleRuntime } from './locale-runtime.js';
|
|
|
14
13
|
import { checkLocaleConformance, diffLocaleCatalogs, explainLocaleMessage, extractHardcodedText, pseudoLocalizeCatalog, } from './locale-tooling.js';
|
|
15
14
|
import { log } from './log.js';
|
|
16
15
|
function printLocaleHelp() {
|
|
17
|
-
console.log(`vmz locale — /locales application i18n (
|
|
16
|
+
console.log(`vmz locale — /locales application i18n (–)
|
|
18
17
|
|
|
19
18
|
Usage:
|
|
20
19
|
vmz locale check [project] Check locales.json5 + catalogs + param contracts
|
|
@@ -160,7 +159,7 @@ function cmdLocaleRename(args) {
|
|
|
160
159
|
else {
|
|
161
160
|
log.info(`rename plan ${fromId} → ${toId} edits=${plan.edits.length}`);
|
|
162
161
|
for (const e of plan.edits)
|
|
163
|
-
console.log(`
|
|
162
|
+
console.log(` ${e.path}`);
|
|
164
163
|
}
|
|
165
164
|
return plan.status === 'ready' ? 0 : 1;
|
|
166
165
|
}
|
|
@@ -329,7 +328,7 @@ function cmdLocaleExplain(args) {
|
|
|
329
328
|
else {
|
|
330
329
|
log.info(`explain ${report.messageId}: resolved=${report.resolvedLocale} params=${(report.params || []).map((p) => p.name).join(',') || '(none)'}`);
|
|
331
330
|
for (const [loc, v] of Object.entries(report.variants || {})) {
|
|
332
|
-
console.log(`
|
|
331
|
+
console.log(` ${loc}\t${v.template}`);
|
|
333
332
|
}
|
|
334
333
|
}
|
|
335
334
|
return report.status === 'ready' ? 0 : 1;
|
|
@@ -355,9 +354,9 @@ function cmdLocaleDiff(args) {
|
|
|
355
354
|
else {
|
|
356
355
|
log.info(`diff ${baseLocale} → ${targetLocale}: missing=${report.summary.missingInTarget} changed=${report.summary.changed} params=${report.summary.paramMismatches}`);
|
|
357
356
|
for (const id of report.missingInTarget || [])
|
|
358
|
-
console.log(`
|
|
357
|
+
console.log(` - missing ${id}`);
|
|
359
358
|
for (const c of report.changed || [])
|
|
360
|
-
console.log(`
|
|
359
|
+
console.log(` ~ ${c.messageId}`);
|
|
361
360
|
}
|
|
362
361
|
return 0;
|
|
363
362
|
}
|
|
@@ -12,18 +12,18 @@ export declare function messageCatalogHash(messages: any, localeId: any, reachab
|
|
|
12
12
|
/**
|
|
13
13
|
* Build LocaleDeliveryResolution for one Host surface.
|
|
14
14
|
* @param {{
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
15
|
+
* host: 'web'|'mini'|'native'|'server',
|
|
16
|
+
* applicationId: string,
|
|
17
|
+
* deliveryId: string,
|
|
18
|
+
* planVersion?: string,
|
|
19
|
+
* supportedLocales: string[],
|
|
20
|
+
* defaultLocale: string,
|
|
21
|
+
* fallback?: Record<string, string[]>,
|
|
22
|
+
* routingRealization?: unknown,
|
|
23
|
+
* messages: Array<{ messageId: string, variants: Record<string, { template: string }> }>,
|
|
24
|
+
* reachableMessageIds?: string[],
|
|
25
|
+
* bundledLocales?: string[],
|
|
26
|
+
* allowFullClientBundle?: boolean,
|
|
27
27
|
* }} input
|
|
28
28
|
*/
|
|
29
29
|
export declare function buildLocaleDeliveryResolution(input: any): {
|
|
@@ -55,19 +55,19 @@ export declare function buildLocaleDeliveryResolution(input: any): {
|
|
|
55
55
|
/**
|
|
56
56
|
* Validate a Native optional locale pack (signed, no JS, bound to app/plan/schema).
|
|
57
57
|
* @param {{
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
58
|
+
* pack: {
|
|
59
|
+
* schema?: string,
|
|
60
|
+
* applicationId: string,
|
|
61
|
+
* planVersion: string,
|
|
62
|
+
* localeId: string,
|
|
63
|
+
* signature?: string,
|
|
64
|
+
* catalog?: Record<string, string>,
|
|
65
|
+
* formatterDataVersion?: string,
|
|
66
|
+
* entries?: Array<{ path: string, kind?: string }>,
|
|
67
|
+
* executable?: boolean,
|
|
68
|
+
* },
|
|
69
|
+
* expectedApplicationId: string,
|
|
70
|
+
* expectedPlanVersion: string,
|
|
71
71
|
* }} input
|
|
72
72
|
*/
|
|
73
73
|
export declare function validateNativeLocalePack(input: any): {
|
|
@@ -88,8 +88,8 @@ export declare function validateNativeLocalePack(input: any): {
|
|
|
88
88
|
/**
|
|
89
89
|
* Mini cross-subpackage message dependencies must be proven.
|
|
90
90
|
* @param {{
|
|
91
|
-
*
|
|
92
|
-
*
|
|
91
|
+
* packages: Array<{ id: string, messageIds: string[] }>,
|
|
92
|
+
* edges: Array<{ fromPackage: string, toPackage: string, messageId: string }>,
|
|
93
93
|
* }} input
|
|
94
94
|
*/
|
|
95
95
|
export declare function proveMiniPackageMessages(input: any): {
|
|
@@ -134,18 +134,18 @@ export declare function assertHostMessageInvariant(resolutions: any): {
|
|
|
134
134
|
diagnostics: any[];
|
|
135
135
|
};
|
|
136
136
|
/**
|
|
137
|
-
* Aggregate
|
|
137
|
+
* Aggregate delivery proof for fixture / CLI.
|
|
138
138
|
* @param {{
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
139
|
+
* manifest: {
|
|
140
|
+
* defaultLocale: string,
|
|
141
|
+
* locales: Array<{ id: string }>,
|
|
142
|
+
* fallback?: Record<string, string[]>,
|
|
143
|
+
* routing?: unknown,
|
|
144
|
+
* },
|
|
145
|
+
* messages: Array<{ messageId: string, variants: Record<string, { template: string }> }>,
|
|
146
|
+
* applicationId?: string,
|
|
147
|
+
* planVersion?: string,
|
|
148
|
+
* reachableMessageIds?: string[],
|
|
149
149
|
* }} input
|
|
150
150
|
*/
|
|
151
151
|
export declare function checkLocaleDelivery(input: any): {
|
package/dist/locale-delivery.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* Locale
|
|
3
|
+
* Locale multi-host delivery: Web chunks · Mini packages · Native packs ·
|
|
4
4
|
* Server error envelope / formatter resources.
|
|
5
|
-
* Design: 规划设计/vmz/28 §9–§10
|
|
6
5
|
*
|
|
7
6
|
* Same MessageNode projects to all Surfaces; LocaleId is not a WebSurface concern.
|
|
8
7
|
*/
|
|
@@ -49,18 +48,18 @@ export function messageCatalogHash(messages, localeId, reachableIds) {
|
|
|
49
48
|
/**
|
|
50
49
|
* Build LocaleDeliveryResolution for one Host surface.
|
|
51
50
|
* @param {{
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
51
|
+
* host: 'web'|'mini'|'native'|'server',
|
|
52
|
+
* applicationId: string,
|
|
53
|
+
* deliveryId: string,
|
|
54
|
+
* planVersion?: string,
|
|
55
|
+
* supportedLocales: string[],
|
|
56
|
+
* defaultLocale: string,
|
|
57
|
+
* fallback?: Record<string, string[]>,
|
|
58
|
+
* routingRealization?: unknown,
|
|
59
|
+
* messages: Array<{ messageId: string, variants: Record<string, { template: string }> }>,
|
|
60
|
+
* reachableMessageIds?: string[],
|
|
61
|
+
* bundledLocales?: string[],
|
|
62
|
+
* allowFullClientBundle?: boolean,
|
|
64
63
|
* }} input
|
|
65
64
|
*/
|
|
66
65
|
export function buildLocaleDeliveryResolution(input) {
|
|
@@ -131,19 +130,19 @@ export function buildLocaleDeliveryResolution(input) {
|
|
|
131
130
|
/**
|
|
132
131
|
* Validate a Native optional locale pack (signed, no JS, bound to app/plan/schema).
|
|
133
132
|
* @param {{
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
133
|
+
* pack: {
|
|
134
|
+
* schema?: string,
|
|
135
|
+
* applicationId: string,
|
|
136
|
+
* planVersion: string,
|
|
137
|
+
* localeId: string,
|
|
138
|
+
* signature?: string,
|
|
139
|
+
* catalog?: Record<string, string>,
|
|
140
|
+
* formatterDataVersion?: string,
|
|
141
|
+
* entries?: Array<{ path: string, kind?: string }>,
|
|
142
|
+
* executable?: boolean,
|
|
143
|
+
* },
|
|
144
|
+
* expectedApplicationId: string,
|
|
145
|
+
* expectedPlanVersion: string,
|
|
147
146
|
* }} input
|
|
148
147
|
*/
|
|
149
148
|
export function validateNativeLocalePack(input) {
|
|
@@ -215,8 +214,8 @@ export function validateNativeLocalePack(input) {
|
|
|
215
214
|
/**
|
|
216
215
|
* Mini cross-subpackage message dependencies must be proven.
|
|
217
216
|
* @param {{
|
|
218
|
-
*
|
|
219
|
-
*
|
|
217
|
+
* packages: Array<{ id: string, messageIds: string[] }>,
|
|
218
|
+
* edges: Array<{ fromPackage: string, toPackage: string, messageId: string }>,
|
|
220
219
|
* }} input
|
|
221
220
|
*/
|
|
222
221
|
export function proveMiniPackageMessages(input) {
|
|
@@ -347,18 +346,18 @@ export function assertHostMessageInvariant(resolutions) {
|
|
|
347
346
|
return { ok: diagnostics.length === 0, diagnostics };
|
|
348
347
|
}
|
|
349
348
|
/**
|
|
350
|
-
* Aggregate
|
|
349
|
+
* Aggregate delivery proof for fixture / CLI.
|
|
351
350
|
* @param {{
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
351
|
+
* manifest: {
|
|
352
|
+
* defaultLocale: string,
|
|
353
|
+
* locales: Array<{ id: string }>,
|
|
354
|
+
* fallback?: Record<string, string[]>,
|
|
355
|
+
* routing?: unknown,
|
|
356
|
+
* },
|
|
357
|
+
* messages: Array<{ messageId: string, variants: Record<string, { template: string }> }>,
|
|
358
|
+
* applicationId?: string,
|
|
359
|
+
* planVersion?: string,
|
|
360
|
+
* reachableMessageIds?: string[],
|
|
362
361
|
* }} input
|
|
363
362
|
*/
|
|
364
363
|
export function checkLocaleDelivery(input) {
|