@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
package/dist/dev-session.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* Long-lived Node dev session (
|
|
3
|
+
* Long-lived Node dev session (/session).
|
|
4
4
|
*
|
|
5
5
|
* Rebuilds go through the N-API `Workspace` — never spawn `cargo` / `vmz-tools`.
|
|
6
|
-
*
|
|
6
|
+
* session: only dirty leaves are marked; Workspace emits affected deployment units.
|
|
7
7
|
*/
|
|
8
8
|
import { spawn } from 'node:child_process';
|
|
9
9
|
import { existsSync } from 'node:fs';
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import { buildIntegratedDocuments, projectHasDocuments } from './document-integrate.js';
|
|
12
12
|
import { createWorkspace } from './index.js';
|
|
13
|
+
import { emitLocaleRuntimeModules, localeHasErrors } from './locale-check.js';
|
|
13
14
|
import { log } from './log.js';
|
|
14
15
|
import { diffFingerprints, fileFingerprintMap } from './watch-diff.js';
|
|
15
16
|
/**
|
|
@@ -48,12 +49,23 @@ export function createDevSession(options) {
|
|
|
48
49
|
ws.updateFiles(changes);
|
|
49
50
|
return ws.build();
|
|
50
51
|
}
|
|
52
|
+
function emitLocales() {
|
|
53
|
+
const localeEmit = emitLocaleRuntimeModules(project, outDir);
|
|
54
|
+
if (!localeEmit.ok || localeHasErrors({ diagnostics: localeEmit.diagnostics })) {
|
|
55
|
+
log.diagnostics(localeEmit.diagnostics ?? []);
|
|
56
|
+
log.error('locale runtime emit failed');
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
51
61
|
function printReport(report, label) {
|
|
52
62
|
const errors = log.diagnostics(report.diagnostics ?? []);
|
|
53
63
|
if (errors) {
|
|
54
64
|
log.error(`${label} failed (${errors} error(s))`);
|
|
55
65
|
return false;
|
|
56
66
|
}
|
|
67
|
+
if (!emitLocales())
|
|
68
|
+
return false;
|
|
57
69
|
const mode = report.full ? 'full' : 'affected';
|
|
58
70
|
const chunks = (report.affectedChunks || []).join(', ') || '(none)';
|
|
59
71
|
log.info(`${label} ok (${mode}; chunks=[${chunks}]; ${(report.emitted ?? []).length} emitted)`);
|
|
@@ -65,7 +77,7 @@ export function createDevSession(options) {
|
|
|
65
77
|
throw new Error(`vmz dev: missing src/ under ${project}`);
|
|
66
78
|
}
|
|
67
79
|
log.info('initial build (N-API workspace, full)…');
|
|
68
|
-
// Empty dirty → full project build (
|
|
80
|
+
// Empty dirty → full project build (session).
|
|
69
81
|
const initial = rebuild();
|
|
70
82
|
if (!printReport(initial, 'build')) {
|
|
71
83
|
throw new Error('vmz dev: initial build failed');
|
|
@@ -82,7 +94,8 @@ export function createDevSession(options) {
|
|
|
82
94
|
}
|
|
83
95
|
child = spawnHost({ project, outDir, host, port });
|
|
84
96
|
const docsRoot = path.join(project, 'documents');
|
|
85
|
-
const
|
|
97
|
+
const localesRoot = path.join(project, 'locales');
|
|
98
|
+
const watchRoots = [src].concat(existsSync(docsRoot) ? [docsRoot] : []).concat(existsSync(localesRoot) ? [localesRoot] : []);
|
|
86
99
|
log.info(`dev → http://${host}:${port} (watching ${watchRoots.join(', ')})`);
|
|
87
100
|
/** @type {Map<string, Map<string, string>>} */
|
|
88
101
|
let fingerprints = new Map();
|
|
@@ -100,10 +113,12 @@ export function createDevSession(options) {
|
|
|
100
113
|
if (stopped || signal?.aborted)
|
|
101
114
|
break;
|
|
102
115
|
if (child && child.exitCode != null) {
|
|
103
|
-
|
|
116
|
+
log.warn(`serve-host exited (${child.exitCode}) — respawning…`);
|
|
117
|
+
child = spawnHost({ project, outDir, host, port });
|
|
118
|
+
continue;
|
|
104
119
|
}
|
|
105
|
-
/** @type {{ srcChanged: string[], srcDeleted: string[], docsDirty: boolean }} */
|
|
106
|
-
let batch = { srcChanged: [], srcDeleted: [], docsDirty: false };
|
|
120
|
+
/** @type {{ srcChanged: string[], srcDeleted: string[], docsDirty: boolean, localesDirty: boolean }} */
|
|
121
|
+
let batch = { srcChanged: [], srcDeleted: [], docsDirty: false, localesDirty: false };
|
|
107
122
|
try {
|
|
108
123
|
// Probe only — keep prior fingerprints until debounce resample
|
|
109
124
|
// (same contract as pre-docs watcher: empty second pass would miss soft reload).
|
|
@@ -115,6 +130,10 @@ export function createDevSession(options) {
|
|
|
115
130
|
batch.srcChanged = diff.changed;
|
|
116
131
|
batch.srcDeleted = diff.deleted;
|
|
117
132
|
}
|
|
133
|
+
else if (root === localesRoot) {
|
|
134
|
+
if (diff.changed.length || diff.deleted.length)
|
|
135
|
+
batch.localesDirty = true;
|
|
136
|
+
}
|
|
118
137
|
else if (diff.changed.length || diff.deleted.length) {
|
|
119
138
|
batch.docsDirty = true;
|
|
120
139
|
}
|
|
@@ -124,11 +143,11 @@ export function createDevSession(options) {
|
|
|
124
143
|
log.warn('watch error:', err);
|
|
125
144
|
continue;
|
|
126
145
|
}
|
|
127
|
-
if (!batch.srcChanged.length && !batch.srcDeleted.length && !batch.docsDirty)
|
|
146
|
+
if (!batch.srcChanged.length && !batch.srcDeleted.length && !batch.docsDirty && !batch.localesDirty)
|
|
128
147
|
continue;
|
|
129
148
|
await sleep(200);
|
|
130
149
|
// Resample against the same prior fingerprints, then commit.
|
|
131
|
-
batch = { srcChanged: [], srcDeleted: [], docsDirty: false };
|
|
150
|
+
batch = { srcChanged: [], srcDeleted: [], docsDirty: false, localesDirty: false };
|
|
132
151
|
for (const root of watchRoots) {
|
|
133
152
|
const prev = fingerprints.get(root) || new Map();
|
|
134
153
|
const next = fileFingerprintMap(root);
|
|
@@ -138,11 +157,15 @@ export function createDevSession(options) {
|
|
|
138
157
|
batch.srcChanged = diff.changed;
|
|
139
158
|
batch.srcDeleted = diff.deleted;
|
|
140
159
|
}
|
|
160
|
+
else if (root === localesRoot) {
|
|
161
|
+
if (diff.changed.length || diff.deleted.length)
|
|
162
|
+
batch.localesDirty = true;
|
|
163
|
+
}
|
|
141
164
|
else if (diff.changed.length || diff.deleted.length) {
|
|
142
165
|
batch.docsDirty = true;
|
|
143
166
|
}
|
|
144
167
|
}
|
|
145
|
-
if (!batch.srcChanged.length && !batch.srcDeleted.length && !batch.docsDirty)
|
|
168
|
+
if (!batch.srcChanged.length && !batch.srcDeleted.length && !batch.docsDirty && !batch.localesDirty)
|
|
146
169
|
continue;
|
|
147
170
|
let needFullReload = batch.docsDirty;
|
|
148
171
|
if (batch.srcChanged.length || batch.srcDeleted.length) {
|
|
@@ -180,12 +203,26 @@ export function createDevSession(options) {
|
|
|
180
203
|
: 'soft reload ok (full page)');
|
|
181
204
|
}
|
|
182
205
|
catch (err) {
|
|
183
|
-
log.warn(`soft reload failed (${err}) —
|
|
184
|
-
killChild(child);
|
|
185
|
-
child = spawnHost({ project, outDir, host, port });
|
|
206
|
+
log.warn(`soft reload failed (${err}) — keeping previous serve-host (fix and save)`);
|
|
186
207
|
}
|
|
187
208
|
continue;
|
|
188
209
|
}
|
|
210
|
+
if (batch.localesDirty) {
|
|
211
|
+
log.info('locales change detected — re-emitting #locales runtime…');
|
|
212
|
+
if (!emitLocales()) {
|
|
213
|
+
log.warn('locale runtime emit failed — keeping previous modules');
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
try {
|
|
217
|
+
await softReload(host, port, { full: true, islandHmr: false });
|
|
218
|
+
log.info('soft reload ok (full page; locales)');
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
log.warn(`soft reload failed (${err}) — keeping previous serve-host (fix and save)`);
|
|
222
|
+
}
|
|
223
|
+
if (!batch.docsDirty)
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
189
226
|
if (batch.docsDirty) {
|
|
190
227
|
log.info('documents change detected — rebuilding document mount…');
|
|
191
228
|
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir });
|
|
@@ -198,9 +235,7 @@ export function createDevSession(options) {
|
|
|
198
235
|
log.info('soft reload ok (full page; docs)');
|
|
199
236
|
}
|
|
200
237
|
catch (err) {
|
|
201
|
-
log.warn(`soft reload failed (${err}) —
|
|
202
|
-
killChild(child);
|
|
203
|
-
child = spawnHost({ project, outDir, host, port });
|
|
238
|
+
log.warn(`soft reload failed (${err}) — keeping previous serve-host (fix and save)`);
|
|
204
239
|
}
|
|
205
240
|
}
|
|
206
241
|
}
|
package/dist/document-build.js
CHANGED
package/dist/document-check.d.ts
CHANGED
package/dist/document-check.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* Build DocumentManifest + run
|
|
3
|
+
* Build DocumentManifest + run / --strict checks.
|
|
4
4
|
*/
|
|
5
5
|
import fs from 'node:fs';
|
|
6
6
|
import path from 'node:path';
|
|
@@ -44,7 +44,7 @@ export function loadDocumentsConfig(documentsRoot) {
|
|
|
44
44
|
return { config: null, diagnostics, configPath: null };
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
|
|
47
|
+
*: only declaration objects — no arbitrary hooks.
|
|
48
48
|
* @param {string} raw
|
|
49
49
|
* @param {string} filename
|
|
50
50
|
*/
|
|
@@ -88,7 +88,7 @@ export function checkDocuments(opts) {
|
|
|
88
88
|
diagnostics.push({
|
|
89
89
|
code: DIAG.CONFIG_MISSING,
|
|
90
90
|
severity: strict ? 'error' : 'warning',
|
|
91
|
-
message: 'documents.config.json|ts missing;
|
|
91
|
+
message: 'documents.config.json|ts missing; strict mode requires defaultLocale + locales for strict coverage checks',
|
|
92
92
|
path: documentsRoot,
|
|
93
93
|
});
|
|
94
94
|
}
|
|
@@ -175,7 +175,7 @@ export function checkDocuments(opts) {
|
|
|
175
175
|
});
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
|
-
//
|
|
178
|
+
// no silent whole-page fallback by default
|
|
179
179
|
if (config && config.fallback === true) {
|
|
180
180
|
diagnostics.push({
|
|
181
181
|
code: DIAG.FALLBACK_SILENT,
|
package/dist/document-cmd.d.ts
CHANGED
package/dist/document-cmd.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* `vmz document` / `vmz docs` CLI
|
|
4
|
-
* Design: 规划设计/vmz/19 §1 · §8
|
|
3
|
+
* `vmz document` / `vmz docs` CLI .
|
|
5
4
|
*/
|
|
6
5
|
import fs from 'node:fs';
|
|
7
6
|
import path from 'node:path';
|
|
@@ -14,7 +13,7 @@ import { createWorkspace } from './index.js';
|
|
|
14
13
|
import { log } from './log.js';
|
|
15
14
|
import { parseArgs } from './cli.js';
|
|
16
15
|
function printDocumentHelp() {
|
|
17
|
-
console.log(`vmz document — project /documents domain
|
|
16
|
+
console.log(`vmz document — project /documents domain
|
|
18
17
|
|
|
19
18
|
Usage:
|
|
20
19
|
vmz document check [project] Check locale tree + links/anchors + fence/API evidence
|
package/dist/document-designs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* Document
|
|
3
|
+
* Document — wire project `/designs` into static document assets.
|
|
4
4
|
* Prefer compiled `vmz-designs.css` / `vmz.css`; else emit a minimal token CSS.
|
|
5
5
|
*/
|
|
6
6
|
import fs from 'node:fs';
|
|
@@ -64,12 +64,17 @@ function emitMinimalDesignsCss(designsDir) {
|
|
|
64
64
|
const vars = {};
|
|
65
65
|
const tokenDir = path.join(designsDir, 'tokens');
|
|
66
66
|
if (fs.existsSync(tokenDir)) {
|
|
67
|
-
walkJson(tokenDir, (obj, prefix) =>
|
|
67
|
+
walkJson(tokenDir, (obj, prefix) => {
|
|
68
|
+
collectStyleThemeEntries(obj, vars);
|
|
69
|
+
flattenTokens(obj, prefix, vars);
|
|
70
|
+
});
|
|
68
71
|
}
|
|
69
72
|
const themeJson = path.join(designsDir, 'theme.json');
|
|
70
73
|
if (fs.existsSync(themeJson)) {
|
|
71
74
|
try {
|
|
72
|
-
|
|
75
|
+
const theme = JSON.parse(fs.readFileSync(themeJson, 'utf8'));
|
|
76
|
+
collectStyleThemeEntries(theme, vars);
|
|
77
|
+
flattenTokens(theme, '', vars);
|
|
73
78
|
}
|
|
74
79
|
catch {
|
|
75
80
|
/* ignore */
|
|
@@ -89,10 +94,33 @@ function cssVar(key) {
|
|
|
89
94
|
.replace(/^-|-$/g, '');
|
|
90
95
|
return `--${name}`;
|
|
91
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Style Theme entries (`key.path` + `value`) → `vmz-*` CSS vars (same naming as application compile).
|
|
99
|
+
* @param {unknown} obj
|
|
100
|
+
* @param {Record<string, string>} out
|
|
101
|
+
*/
|
|
102
|
+
function collectStyleThemeEntries(obj, out) {
|
|
103
|
+
if (obj == null || typeof obj !== 'object' || Array.isArray(obj))
|
|
104
|
+
return;
|
|
105
|
+
const entries = /** @type {{ key?: { path?: unknown }, value?: unknown }[]} */ ( /** @type {{ entries?: unknown }} */(obj).entries);
|
|
106
|
+
if (!Array.isArray(entries))
|
|
107
|
+
return;
|
|
108
|
+
for (const e of entries) {
|
|
109
|
+
const pathParts = e?.key?.path;
|
|
110
|
+
if (!Array.isArray(pathParts) || pathParts.length === 0)
|
|
111
|
+
continue;
|
|
112
|
+
if (typeof e.value !== 'string' && typeof e.value !== 'number')
|
|
113
|
+
continue;
|
|
114
|
+
const dotted = pathParts.map(String).join('-');
|
|
115
|
+
out[`vmz-${dotted}`] = String(e.value);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
92
118
|
function flattenTokens(obj, prefix, out) {
|
|
93
119
|
if (obj == null || typeof obj !== 'object' || Array.isArray(obj))
|
|
94
120
|
return;
|
|
95
121
|
for (const [k, v] of Object.entries(obj)) {
|
|
122
|
+
if (k === 'entries')
|
|
123
|
+
continue;
|
|
96
124
|
const key = prefix ? `${prefix}-${k}` : k;
|
|
97
125
|
if (v != null && typeof v === 'object' && !Array.isArray(v)) {
|
|
98
126
|
if ('value' in v && (typeof v.value === 'string' || typeof v.value === 'number')) {
|
package/dist/document-enrich.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* Document
|
|
4
|
-
* Design: 规划设计/vmz/19 §5–6
|
|
3
|
+
* Document — enrich manifest with routes, anchors, nav; diagnose links.
|
|
5
4
|
*/
|
|
6
5
|
import fs from 'node:fs';
|
|
7
6
|
import path from 'node:path';
|
|
@@ -115,7 +114,7 @@ export function enrichDocumentContent(manifest, ctx) {
|
|
|
115
114
|
if (!href || href.startsWith('mailto:') || href.startsWith('http://') || href.startsWith('https://')) {
|
|
116
115
|
continue;
|
|
117
116
|
}
|
|
118
|
-
//
|
|
117
|
+
// API refs are resolved by evidence, not as page links.
|
|
119
118
|
if (href.startsWith('vmz-api:') || href.startsWith('api:')) {
|
|
120
119
|
continue;
|
|
121
120
|
}
|
|
@@ -30,10 +30,10 @@ export declare function resolveApiSymbol(index: any, query: any): {
|
|
|
30
30
|
/**
|
|
31
31
|
* @param {import('./document-schema.js').DocumentManifest} manifest
|
|
32
32
|
* @param {{
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
33
|
+
* analyzeMarkdown: Function,
|
|
34
|
+
* projectRoot: string,
|
|
35
|
+
* createWorkspace?: Function,
|
|
36
|
+
* ensureProgramGraph?: boolean,
|
|
37
37
|
* }} ctx
|
|
38
38
|
*/
|
|
39
39
|
export declare function enrichDocumentEvidence(manifest: any, ctx: any): Promise<{
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* Document
|
|
4
|
-
* Design: 规划设计/vmz/19 §4 · §8 D2
|
|
3
|
+
* Document Evidence — fence check + API refs from Program Graph.
|
|
5
4
|
*
|
|
6
5
|
* Not a Doc IR: filesystem/manifest projection + Workspace/Program Graph queries.
|
|
7
6
|
*/
|
|
@@ -117,10 +116,10 @@ export function resolveApiSymbol(index, query) {
|
|
|
117
116
|
/**
|
|
118
117
|
* @param {import('./document-schema.js').DocumentManifest} manifest
|
|
119
118
|
* @param {{
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
119
|
+
* analyzeMarkdown: Function,
|
|
120
|
+
* projectRoot: string,
|
|
121
|
+
* createWorkspace?: Function,
|
|
122
|
+
* ensureProgramGraph?: boolean,
|
|
124
123
|
* }} ctx
|
|
125
124
|
*/
|
|
126
125
|
export async function enrichDocumentEvidence(manifest, ctx) {
|
|
@@ -424,22 +423,31 @@ function checkScriptFence({ fence, meta, sourcePath, page }) {
|
|
|
424
423
|
diagnostics.push({
|
|
425
424
|
code: DIAG.FENCE_CHECK,
|
|
426
425
|
severity: 'error',
|
|
427
|
-
message: `${meta.lang} fence parse produced
|
|
426
|
+
message: `${meta.lang} fence parse produced no SourceFile`,
|
|
428
427
|
path: `${sourcePath}:${fence.lineStart}`,
|
|
429
428
|
});
|
|
430
|
-
return { record: { status: 'failed' }, diagnostics };
|
|
429
|
+
return { record: { status: 'failed', detail: 'parse' }, diagnostics };
|
|
431
430
|
}
|
|
432
|
-
return { record: { status: 'ok'
|
|
431
|
+
return { record: { status: 'ok' }, diagnostics };
|
|
433
432
|
}
|
|
434
433
|
catch (e) {
|
|
434
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
435
|
+
if (/Cannot find module ['\"]typescript['\"]/i.test(msg) || e?.code === 'MODULE_NOT_FOUND') {
|
|
436
|
+
diagnostics.push({
|
|
437
|
+
code: DIAG.FENCE_CHECK,
|
|
438
|
+
severity: 'error',
|
|
439
|
+
message: 'TS/JS fence check needs `typescript` (optional peer of `@vmz/vmz`). Install: pnpm add -D typescript',
|
|
440
|
+
path: `${sourcePath}:${fence.lineStart}`,
|
|
441
|
+
});
|
|
442
|
+
return { record: { status: 'failed', detail: 'missing-typescript' }, diagnostics };
|
|
443
|
+
}
|
|
435
444
|
diagnostics.push({
|
|
436
445
|
code: DIAG.FENCE_CHECK,
|
|
437
446
|
severity: 'error',
|
|
438
|
-
message: `${meta.lang} fence check
|
|
447
|
+
message: `${meta.lang} fence check failed: ${msg}`,
|
|
439
448
|
path: `${sourcePath}:${fence.lineStart}`,
|
|
440
|
-
pageKey: page?.identity?.pageKey,
|
|
441
449
|
});
|
|
442
|
-
return { record: { status: 'failed', detail: '
|
|
450
|
+
return { record: { status: 'failed', detail: 'exception' }, diagnostics };
|
|
443
451
|
}
|
|
444
452
|
}
|
|
445
453
|
function walkFiles(dir, fn) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Integrated DocumentMount — build /documents into the host app dist so
|
|
3
3
|
* routeBase (e.g. /d) is served as static HTML next to SSR pages.
|
|
4
|
-
* Design: 规划设计/vmz/19 · Integrated DocumentMount (same project, no separate package).
|
|
5
4
|
*/
|
|
6
5
|
/**
|
|
7
6
|
* @param {string} projectRoot
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Integrated DocumentMount — build /documents into the host app dist so
|
|
4
4
|
* routeBase (e.g. /d) is served as static HTML next to SSR pages.
|
|
5
|
-
* Design: 规划设计/vmz/19 · Integrated DocumentMount (same project, no separate package).
|
|
6
5
|
*/
|
|
7
6
|
import fs from 'node:fs';
|
|
8
7
|
import path from 'node:path';
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
export declare function htmlToSearchText(html: any): string;
|
|
6
6
|
/**
|
|
7
7
|
* @param {{
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* manifest: any,
|
|
9
|
+
* enriched: { byId: Map<string, any> },
|
|
10
|
+
* evidence: any,
|
|
11
|
+
* version?: string | null,
|
|
12
12
|
* }} opts
|
|
13
13
|
*/
|
|
14
14
|
export declare function buildDocumentSearch(opts: any): {
|
|
@@ -20,9 +20,9 @@ export declare function buildDocumentSearch(opts: any): {
|
|
|
20
20
|
/**
|
|
21
21
|
* Island-only resume plan for document surfaces.
|
|
22
22
|
* @param {{
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* evidence: any,
|
|
24
|
+
* searchHref?: string,
|
|
25
|
+
* fenceBodies?: Map<string, string>,
|
|
26
26
|
* }} opts
|
|
27
27
|
*/
|
|
28
28
|
export declare function buildDocumentIslands(opts: any): {
|
|
@@ -57,10 +57,10 @@ export declare function collectFenceBodies(analyzedByPageId: any, pages: any): M
|
|
|
57
57
|
/**
|
|
58
58
|
* Render SSR island shells (no script — resume later).
|
|
59
59
|
* @param {{
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
60
|
+
* islands: any,
|
|
61
|
+
* searchIndexHref: string,
|
|
62
|
+
* pageKey: string,
|
|
63
|
+
* locale: string,
|
|
64
64
|
* }} opts
|
|
65
65
|
*/
|
|
66
66
|
export declare function renderIslandShellsHtml(opts: any): {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* Document
|
|
4
|
-
* Design: 规划设计/vmz/19 §5–6 · §8 D3
|
|
3
|
+
* Document Interactive — search index + Island-only resume plan.
|
|
5
4
|
*
|
|
6
5
|
* Not a Doc IR: build artifacts + ResumeEntry-shaped island hosts.
|
|
7
6
|
* Static HTML stays no-JS readable; islands resume later, never full-page hydrate.
|
|
@@ -27,10 +26,10 @@ export function htmlToSearchText(html) {
|
|
|
27
26
|
}
|
|
28
27
|
/**
|
|
29
28
|
* @param {{
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
29
|
+
* manifest: any,
|
|
30
|
+
* enriched: { byId: Map<string, any> },
|
|
31
|
+
* evidence: any,
|
|
32
|
+
* version?: string | null,
|
|
34
33
|
* }} opts
|
|
35
34
|
*/
|
|
36
35
|
export function buildDocumentSearch(opts) {
|
|
@@ -114,9 +113,9 @@ export function buildDocumentSearch(opts) {
|
|
|
114
113
|
/**
|
|
115
114
|
* Island-only resume plan for document surfaces.
|
|
116
115
|
* @param {{
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
116
|
+
* evidence: any,
|
|
117
|
+
* searchHref?: string,
|
|
118
|
+
* fenceBodies?: Map<string, string>,
|
|
120
119
|
* }} opts
|
|
121
120
|
*/
|
|
122
121
|
export function buildDocumentIslands(opts) {
|
|
@@ -216,10 +215,10 @@ export function collectFenceBodies(analyzedByPageId, pages) {
|
|
|
216
215
|
/**
|
|
217
216
|
* Render SSR island shells (no script — resume later).
|
|
218
217
|
* @param {{
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
218
|
+
* islands: any,
|
|
219
|
+
* searchIndexHref: string,
|
|
220
|
+
* pageKey: string,
|
|
221
|
+
* locale: string,
|
|
223
222
|
* }} opts
|
|
224
223
|
*/
|
|
225
224
|
export function renderIslandShellsHtml(opts) {
|
package/dist/document-locale.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Document
|
|
3
|
-
* Design: 规划设计/vmz/19 §3 · 23 §0(runtime.ts;与 plugin-host 同一 importMaybeTs).
|
|
2
|
+
* Document — resolve engines.markdown via the official plugin runtime.
|
|
4
3
|
*/
|
|
5
4
|
/**
|
|
6
5
|
* @param {{ engines?: { markdown?: string } }} [opts]
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* Document
|
|
4
|
-
* Design: 规划设计/vmz/19 §3 · 23 §0(runtime.ts;与 plugin-host 同一 importMaybeTs).
|
|
3
|
+
* Document — resolve engines.markdown via the official plugin runtime.
|
|
5
4
|
*/
|
|
6
5
|
import { createRequire } from 'node:module';
|
|
6
|
+
import { existsSync } from 'node:fs';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import { importMaybeTs } from './plugin-host.js';
|
|
@@ -14,17 +14,23 @@ const require = createRequire(import.meta.url);
|
|
|
14
14
|
export async function resolveMarkdownEngine(opts = {}) {
|
|
15
15
|
const id = opts.engines?.markdown || 'markdown-it';
|
|
16
16
|
if (id !== 'markdown-it') {
|
|
17
|
-
throw new Error(`unsupported engines.markdown ${JSON.stringify(id)} (
|
|
17
|
+
throw new Error(`unsupported engines.markdown ${JSON.stringify(id)} (markdown-it only)`);
|
|
18
18
|
}
|
|
19
|
-
let runtimeFile;
|
|
19
|
+
let runtimeFile = null;
|
|
20
20
|
try {
|
|
21
21
|
const pkg = require.resolve('@vmz/plugin-markdown-it/package.json');
|
|
22
22
|
runtimeFile = path.join(path.dirname(pkg), 'runtime.ts');
|
|
23
23
|
}
|
|
24
|
-
catch
|
|
25
|
-
//
|
|
24
|
+
catch {
|
|
25
|
+
// Developer mode: monorepo source checkout.
|
|
26
26
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
27
|
-
|
|
27
|
+
const fallback = path.resolve(here, '../../../plugins/vmz-plugin-markdown-it/runtime.ts');
|
|
28
|
+
if (existsSync(fallback))
|
|
29
|
+
runtimeFile = fallback;
|
|
30
|
+
}
|
|
31
|
+
if (!runtimeFile || !existsSync(runtimeFile)) {
|
|
32
|
+
throw new Error('markdown engine needs `@vmz/plugin-markdown-it` (optional peer of `@vmz/vmz`).\n' +
|
|
33
|
+
' Install: pnpm add -D @vmz/plugin-markdown-it');
|
|
28
34
|
}
|
|
29
35
|
const mod = await importMaybeTs(runtimeFile);
|
|
30
36
|
if (typeof mod.analyzeMarkdown !== 'function') {
|
package/dist/document-scan.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Scan /documents tree → pages + locale dirs
|
|
2
|
+
* Scan /documents tree → pages + locale dirs .
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* PageKey from locale-relative markdown path (strip extension; index → parent or "index").
|
|
@@ -9,9 +9,9 @@ export declare function pageKeyFromRel(relMd: any): any;
|
|
|
9
9
|
/**
|
|
10
10
|
* @param {string} documentsRoot absolute path to .../documents
|
|
11
11
|
* @returns {{
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* locales: string[],
|
|
13
|
+
* pages: Array<{ identity: { pageKey: string, locale: string }, sourcePath: string }>,
|
|
14
|
+
* diagnostics: Array<{ code: string, severity: string, message: string, path?: string }>,
|
|
15
15
|
* }}
|
|
16
16
|
*/
|
|
17
17
|
export declare function scanDocumentsTree(documentsRoot: any): {
|
package/dist/document-scan.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* Scan /documents tree → pages + locale dirs
|
|
3
|
+
* Scan /documents tree → pages + locale dirs .
|
|
4
4
|
*/
|
|
5
5
|
import fs from 'node:fs';
|
|
6
6
|
import path from 'node:path';
|
|
@@ -50,9 +50,9 @@ export function pageKeyFromRel(relMd) {
|
|
|
50
50
|
/**
|
|
51
51
|
* @param {string} documentsRoot absolute path to .../documents
|
|
52
52
|
* @returns {{
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
53
|
+
* locales: string[],
|
|
54
|
+
* pages: Array<{ identity: { pageKey: string, locale: string }, sourcePath: string }>,
|
|
55
|
+
* diagnostics: Array<{ code: string, severity: string, message: string, path?: string }>,
|
|
56
56
|
* }}
|
|
57
57
|
*/
|
|
58
58
|
export function scanDocumentsTree(documentsRoot) {
|