@vmz/vmz 0.1.29 → 0.1.31
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/dist/cli.js +27 -18
- package/dist/index.d.ts +2 -2
- package/dist/index.js +21 -11
- package/dist/locale-route-emit.d.ts +4 -0
- package/dist/locale-route-emit.js +10 -1
- package/dist/pack.js +1 -1
- package/dist/project-build.js +12 -0
- package/dist/route-catalog-emit.d.ts +28 -0
- package/dist/route-catalog-emit.js +63 -0
- package/dist/static-emit.js +31 -21
- package/package.json +14 -14
package/dist/cli.js
CHANGED
|
@@ -4,30 +4,31 @@
|
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
5
|
import { existsSync } from 'node:fs';
|
|
6
6
|
import path from 'node:path';
|
|
7
|
-
import {
|
|
7
|
+
import { createCli } from '@vmz/commander';
|
|
8
|
+
import { registerApplicationCommands } from './application-cmd.js';
|
|
9
|
+
import { assembleDelivery, emitBuildProof } from './build-assemble.js';
|
|
10
|
+
import { resolveCliLocalesRoot } from './cli-localize.js';
|
|
11
|
+
import { normalizeDeliveryAuthoring, resolveProfileArtifactDir, selectBuildProfile } from './delivery-profile.js';
|
|
8
12
|
import { createDevSession } from './dev-session.js';
|
|
9
|
-
import { gateGlobalProjectCommand, getInvocationContext, isGlobalAllowedCommand } from './invocation.js';
|
|
10
|
-
import { log } from './log.js';
|
|
11
|
-
import { findAvailablePort } from './port.js';
|
|
12
|
-
import { readPackageMeta, resolveWorkspaceDirs } from './resolve.js';
|
|
13
|
-
import { registerTestCommand } from './test-cmd.js';
|
|
14
13
|
import { registerDocumentCommands } from './document-cmd.js';
|
|
15
14
|
import { buildIntegratedDocuments, projectHasDocuments } from './document-integrate.js';
|
|
16
|
-
import {
|
|
15
|
+
import { registerExplainCommand } from './explain-cmd.js';
|
|
16
|
+
import { registerGithubActionsCommand } from './github-actions-cmd.js';
|
|
17
|
+
import { createWorkspace, getProtocolVersions, HOST_PROTOCOL, materializeServeHostRuntime, resolveCoreRuntimeDist, resolveNativePath, } from './index.js';
|
|
18
|
+
import { gateGlobalProjectCommand, getInvocationContext, isGlobalAllowedCommand } from './invocation.js';
|
|
17
19
|
import { emitLocaleRuntimeModules, localeHasErrors } from './locale-check.js';
|
|
20
|
+
import { registerLocaleCommands } from './locale-cmd.js';
|
|
18
21
|
import { emitLocaleRouteRealization } from './locale-route-emit.js';
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import { registerRefactorCommands } from './refactor-cmd.js';
|
|
22
|
-
import { registerExplainCommand } from './explain-cmd.js';
|
|
22
|
+
import { log } from './log.js';
|
|
23
|
+
import { packFromDeploymentIr } from './pack.js';
|
|
23
24
|
import { registerPlanCommands } from './plan-cmd.js';
|
|
24
|
-
import { registerGithubActionsCommand } from './github-actions-cmd.js';
|
|
25
25
|
import { loadVmzConfig } from './plugin-host.js';
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
26
|
+
import { findAvailablePort } from './port.js';
|
|
27
|
+
import { registerRefactorCommands } from './refactor-cmd.js';
|
|
28
|
+
import { registerArtifactCommands } from './release-cmd.js';
|
|
29
|
+
import { readPackageMeta, resolveWorkspaceDirs } from './resolve.js';
|
|
30
|
+
import { emitRouteCatalog } from './route-catalog-emit.js';
|
|
31
|
+
import { registerTestCommand } from './test-cmd.js';
|
|
31
32
|
export function printGlobalHelp() {
|
|
32
33
|
return buildProductCli({ mode: 'global' }).parse(['help']);
|
|
33
34
|
}
|
|
@@ -224,6 +225,14 @@ async function cmdBuild(args) {
|
|
|
224
225
|
if (localeRoutes.written.length) {
|
|
225
226
|
log.info(`locale route realization (${localeRoutes.written.length} artifact(s))`);
|
|
226
227
|
}
|
|
228
|
+
const routeCatalog = emitRouteCatalog(outDir);
|
|
229
|
+
if (!routeCatalog.ok) {
|
|
230
|
+
log.error(routeCatalog.error || 'route catalog emit failed');
|
|
231
|
+
return 1;
|
|
232
|
+
}
|
|
233
|
+
if (routeCatalog.written.length) {
|
|
234
|
+
log.info(`route catalog (${routeCatalog.written.length} artifact(s))`);
|
|
235
|
+
}
|
|
227
236
|
if (projectHasDocuments(project)) {
|
|
228
237
|
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir });
|
|
229
238
|
if (!docs.ok)
|
|
@@ -409,7 +418,7 @@ async function cmdDev(args) {
|
|
|
409
418
|
}
|
|
410
419
|
const outDir = resolveProfileArtifactDir(outDirRoot, selected.profile);
|
|
411
420
|
const host = typeof args.host === 'string' ? args.host : '127.0.0.1';
|
|
412
|
-
const portLocked = Object.
|
|
421
|
+
const portLocked = Object.hasOwn(args, 'port');
|
|
413
422
|
let port;
|
|
414
423
|
if (portLocked) {
|
|
415
424
|
port = Number(args.port);
|
package/dist/index.d.ts
CHANGED
|
@@ -30,9 +30,9 @@ export declare function getProtocolVersions(): ProtocolVersions;
|
|
|
30
30
|
export declare function handshake(host?: ProtocolVersions): void;
|
|
31
31
|
/** Resolve `@vmz/core` package `dist/` for runtime JS copies into app outDir. */
|
|
32
32
|
export declare function resolveCoreRuntimeDist(): string | null;
|
|
33
|
-
/** Runtime companions required by dist/vmz-serve-host.mjs relative imports. */
|
|
33
|
+
/** Runtime companions required by dist/_vmz/host/vmz-serve-host.mjs relative imports. */
|
|
34
34
|
export declare const SERVE_HOST_RUNTIME_FILES: ReadonlyArray<readonly [string, string]>;
|
|
35
|
-
/** Copy serve-host + registry bootstrap modules from `@vmz/core` into
|
|
35
|
+
/** Copy serve-host + registry bootstrap modules from `@vmz/core` into `_vmz/host/`. */
|
|
36
36
|
export declare function materializeServeHostRuntime(outDir: string, coreDist?: string | null): void;
|
|
37
37
|
/** Create a long-lived compile workspace. */
|
|
38
38
|
export declare function createWorkspace(options: WorkspaceOptions): VmzNativeAddon;
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Coarse-grained only — no transform hooks / per-AST callbacks.
|
|
4
4
|
*/
|
|
5
5
|
import { createRequire } from 'node:module';
|
|
6
|
-
import { copyFileSync, existsSync } from 'node:fs';
|
|
6
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import { materializeWechatPackaging } from './wechat-packaging.js';
|
|
@@ -119,17 +119,17 @@ export function resolveCoreRuntimeDist() {
|
|
|
119
119
|
return nested;
|
|
120
120
|
return null;
|
|
121
121
|
}
|
|
122
|
-
/** Runtime companions required by dist/vmz-serve-host.mjs relative imports. */
|
|
122
|
+
/** Runtime companions required by dist/_vmz/host/vmz-serve-host.mjs relative imports. */
|
|
123
123
|
export const SERVE_HOST_RUNTIME_FILES = [
|
|
124
|
-
['serve-host.mjs', 'vmz-serve-host.mjs'],
|
|
125
|
-
['native-addon.js', 'native-addon.js'],
|
|
126
|
-
['list-client-components.js', 'list-client-components.js'],
|
|
127
|
-
['deployment-registry.js', 'deployment-registry.js'],
|
|
128
|
-
['render-host.js', 'render-host.js'],
|
|
129
|
-
['route-layout-chain.js', 'route-layout-chain.js'],
|
|
130
|
-
['localize-body-links.js', 'localize-body-links.js'],
|
|
124
|
+
['serve-host.mjs', '_vmz/host/vmz-serve-host.mjs'],
|
|
125
|
+
['native-addon.js', '_vmz/host/native-addon.js'],
|
|
126
|
+
['list-client-components.js', '_vmz/host/list-client-components.js'],
|
|
127
|
+
['deployment-registry.js', '_vmz/host/deployment-registry.js'],
|
|
128
|
+
['render-host.js', '_vmz/host/render-host.js'],
|
|
129
|
+
['route-layout-chain.js', '_vmz/host/route-layout-chain.js'],
|
|
130
|
+
['localize-body-links.js', '_vmz/host/localize-body-links.js'],
|
|
131
131
|
];
|
|
132
|
-
/** Copy serve-host + registry bootstrap modules from `@vmz/core` into
|
|
132
|
+
/** Copy serve-host + registry bootstrap modules from `@vmz/core` into `_vmz/host/`. */
|
|
133
133
|
export function materializeServeHostRuntime(outDir, coreDist = resolveCoreRuntimeDist()) {
|
|
134
134
|
if (!coreDist) {
|
|
135
135
|
throw new Error('materializeServeHostRuntime: @vmz/core dist not found');
|
|
@@ -140,8 +140,18 @@ export function materializeServeHostRuntime(outDir, coreDist = resolveCoreRuntim
|
|
|
140
140
|
if (!existsSync(src)) {
|
|
141
141
|
throw new Error(`materializeServeHostRuntime: missing ${src}`);
|
|
142
142
|
}
|
|
143
|
-
|
|
143
|
+
mkdirSync(path.dirname(dst), { recursive: true });
|
|
144
|
+
if (srcName === 'serve-host.mjs') {
|
|
145
|
+
// Nested under `_vmz/host/`: delivery-root `vmz-runtime.js` is two levels up.
|
|
146
|
+
const text = readFileSync(src, 'utf8').replace(/from\s+(['"])\.\/vmz-runtime\.js\1/g, 'from $1../../vmz-runtime.js$1');
|
|
147
|
+
writeFileSync(dst, text, 'utf8');
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
copyFileSync(src, dst);
|
|
151
|
+
}
|
|
144
152
|
}
|
|
153
|
+
const stub = path.join(outDir, 'vmz-serve-host.mjs');
|
|
154
|
+
writeFileSync(stub, "// Generated launcher — host companions live under `_vmz/host/` (0.1.31).\nimport './_vmz/host/vmz-serve-host.mjs';\n", 'utf8');
|
|
145
155
|
}
|
|
146
156
|
/** Create a long-lived compile workspace. */
|
|
147
157
|
export function createWorkspace(options) {
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
* Emit RouteId × LocaleId realization (+ PageMeta / hreflang seed) into dist/_vmz.
|
|
3
3
|
* Consumed by serve-host + static-emit; LocaleId stays out of stable RouteId.
|
|
4
4
|
*/
|
|
5
|
+
import { LOCALE_LINK_PLAN_SCHEMA } from '@vmz/core/localize-body-links';
|
|
5
6
|
export declare const LOCALE_ROUTE_REALIZATION_ARTIFACT_SCHEMA = "vmz.locale.route_realization.v0";
|
|
7
|
+
export declare const LOCALE_LINK_PLAN_REL = "_vmz/locale-link-plan.json";
|
|
8
|
+
export { LOCALE_LINK_PLAN_SCHEMA };
|
|
6
9
|
export interface EmitLocaleRouteRealizationOpts {
|
|
7
10
|
origin?: string;
|
|
8
11
|
}
|
|
@@ -46,6 +49,7 @@ export declare function emitLocaleRouteRealization(projectRoot: string, distDir:
|
|
|
46
49
|
diagnostics: import("./locale-router.js").LocaleDiagnostic[];
|
|
47
50
|
status: string;
|
|
48
51
|
}[];
|
|
52
|
+
linkRouteAliases: import("@vmz/core/localize-body-links").LinkRouteAlias[];
|
|
49
53
|
};
|
|
50
54
|
diagnostics: any[];
|
|
51
55
|
};
|
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import fs from 'node:fs';
|
|
6
6
|
import path from 'node:path';
|
|
7
|
+
import { buildLocaleLinkPlan, LOCALE_LINK_PLAN_SCHEMA, linkRouteAliasesFromUnits } from '@vmz/core/localize-body-links';
|
|
7
8
|
import { checkLocales, localeHasErrors } from './locale-check.js';
|
|
8
9
|
import { buildLocalePageMeta, buildLocaleRouteRealizationTable } from './locale-router.js';
|
|
9
10
|
import { writePrettyJsonFile } from './pretty-json.js';
|
|
10
11
|
import { listPublicPageUnits, unitBrowserPathPattern } from './route-path.js';
|
|
11
12
|
export const LOCALE_ROUTE_REALIZATION_ARTIFACT_SCHEMA = 'vmz.locale.route_realization.v0';
|
|
13
|
+
export const LOCALE_LINK_PLAN_REL = '_vmz/locale-link-plan.json';
|
|
14
|
+
export { LOCALE_LINK_PLAN_SCHEMA };
|
|
12
15
|
export function emitLocaleRouteRealization(projectRoot, distDir, opts = {}) {
|
|
13
16
|
const report = checkLocales({ projectRoot, checkUnused: false });
|
|
14
17
|
if (localeHasErrors(report)) {
|
|
@@ -81,6 +84,7 @@ export function emitLocaleRouteRealization(projectRoot, distDir, opts = {}) {
|
|
|
81
84
|
routes,
|
|
82
85
|
realizations: table.realizations,
|
|
83
86
|
pageMetas,
|
|
87
|
+
linkRouteAliases: linkRouteAliasesFromUnits(pages),
|
|
84
88
|
};
|
|
85
89
|
const vmzDir = path.join(distDir, '_vmz');
|
|
86
90
|
fs.mkdirSync(vmzDir, { recursive: true });
|
|
@@ -93,9 +97,14 @@ export function emitLocaleRouteRealization(projectRoot, distDir, opts = {}) {
|
|
|
93
97
|
locales: artifact.locales,
|
|
94
98
|
routing: artifact.routing,
|
|
95
99
|
});
|
|
100
|
+
const linkPlan = buildLocaleLinkPlan(artifact);
|
|
101
|
+
writePrettyJsonFile(path.join(distDir, ...LOCALE_LINK_PLAN_REL.split('/')), {
|
|
102
|
+
schema: LOCALE_LINK_PLAN_SCHEMA,
|
|
103
|
+
rows: linkPlan.rows,
|
|
104
|
+
});
|
|
96
105
|
return {
|
|
97
106
|
ok: true,
|
|
98
|
-
written: ['_vmz/locale-route-realization.json', '_vmz/locale-manifest.json'],
|
|
107
|
+
written: ['_vmz/locale-route-realization.json', '_vmz/locale-manifest.json', LOCALE_LINK_PLAN_REL],
|
|
99
108
|
artifact,
|
|
100
109
|
diagnostics: [],
|
|
101
110
|
};
|
package/dist/pack.js
CHANGED
|
@@ -20,7 +20,7 @@ export const PACK_MANIFEST_SCHEMA = 'vmz.pack.manifest.v0';
|
|
|
20
20
|
export function ensureRuntimeCompanions(outDir, coreDist) {
|
|
21
21
|
if (!coreDist)
|
|
22
22
|
return [];
|
|
23
|
-
const names = ['dom-core.js', 'dom-ssr.js', 'dom.client.js', 'direct-host-box.js', 'unknown-component.js'];
|
|
23
|
+
const names = ['dom-core.js', 'dom-ssr.js', 'dom.client.js', 'dom.browser.js', 'direct-host-box.js', 'unknown-component.js'];
|
|
24
24
|
const copied = [];
|
|
25
25
|
for (const name of names) {
|
|
26
26
|
const src = path.join(coreDist, name);
|
package/dist/project-build.js
CHANGED
|
@@ -11,6 +11,7 @@ import { emitLocaleRuntimeModules, localeHasErrors } from './locale-check.js';
|
|
|
11
11
|
import { emitLocaleRouteRealization } from './locale-route-emit.js';
|
|
12
12
|
import { packFromDeploymentIr } from './pack.js';
|
|
13
13
|
import { loadVmzConfig } from './plugin-host.js';
|
|
14
|
+
import { emitRouteCatalog } from './route-catalog-emit.js';
|
|
14
15
|
function dedupeDiagnostics(list) {
|
|
15
16
|
const seen = new Set();
|
|
16
17
|
const out = [];
|
|
@@ -129,6 +130,17 @@ export async function buildProjectToOutDirRoot(project, outDirRoot, opts = {}) {
|
|
|
129
130
|
error: 'locale route realization emit failed',
|
|
130
131
|
};
|
|
131
132
|
}
|
|
133
|
+
const routeCatalog = emitRouteCatalog(artifactDir);
|
|
134
|
+
if (!routeCatalog.ok) {
|
|
135
|
+
return {
|
|
136
|
+
ok: false,
|
|
137
|
+
outDirRoot: root,
|
|
138
|
+
artifactDir,
|
|
139
|
+
deliveryName,
|
|
140
|
+
diagnostics,
|
|
141
|
+
error: routeCatalog.error || 'route catalog emit failed',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
132
144
|
if (projectHasDocuments(project)) {
|
|
133
145
|
const docs = await buildIntegratedDocuments({ projectRoot: project, outDir: artifactDir });
|
|
134
146
|
if (!docs.ok) {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiled route catalog (`_vmz/route-catalog.json`) — 0.1.30 authority for page matching.
|
|
3
|
+
* Hosts load this artifact; they must not re-parse deployment pathPattern into a live catalog.
|
|
4
|
+
*/
|
|
5
|
+
import { type DeploymentPageUnit, type PathSeg } from './route-path.js';
|
|
6
|
+
export declare const ROUTE_CATALOG_SCHEMA = "vmz.route.catalog.v0";
|
|
7
|
+
export declare const ROUTE_CATALOG_REL = "_vmz/route-catalog.json";
|
|
8
|
+
export type RouteCatalogPage = {
|
|
9
|
+
chunkId: string;
|
|
10
|
+
routeId: string;
|
|
11
|
+
pathPattern: string;
|
|
12
|
+
pageRel: string;
|
|
13
|
+
segs: PathSeg[];
|
|
14
|
+
};
|
|
15
|
+
export type RouteCatalog = {
|
|
16
|
+
schema: typeof ROUTE_CATALOG_SCHEMA;
|
|
17
|
+
pages: RouteCatalogPage[];
|
|
18
|
+
};
|
|
19
|
+
export declare function buildRouteCatalogFromDeployment(deployment: {
|
|
20
|
+
units?: DeploymentPageUnit[];
|
|
21
|
+
} | null | undefined): RouteCatalog;
|
|
22
|
+
export declare function emitRouteCatalog(distDir: string): {
|
|
23
|
+
ok: boolean;
|
|
24
|
+
written: string[];
|
|
25
|
+
catalog: RouteCatalog | null;
|
|
26
|
+
error?: string;
|
|
27
|
+
};
|
|
28
|
+
export declare function loadRouteCatalog(distDir: string): RouteCatalog | null;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiled route catalog (`_vmz/route-catalog.json`) — 0.1.30 authority for page matching.
|
|
3
|
+
* Hosts load this artifact; they must not re-parse deployment pathPattern into a live catalog.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { writePrettyJsonFile } from './pretty-json.js';
|
|
8
|
+
import { listPublicPageUnits, parsePathPattern, unitBrowserPathPattern } from './route-path.js';
|
|
9
|
+
export const ROUTE_CATALOG_SCHEMA = 'vmz.route.catalog.v0';
|
|
10
|
+
export const ROUTE_CATALOG_REL = '_vmz/route-catalog.json';
|
|
11
|
+
export function buildRouteCatalogFromDeployment(deployment) {
|
|
12
|
+
const pages = [];
|
|
13
|
+
for (const unit of listPublicPageUnits(deployment)) {
|
|
14
|
+
const chunkId = String(unit.chunkId || '').replace(/\\/g, '/');
|
|
15
|
+
const pathPattern = unitBrowserPathPattern(unit);
|
|
16
|
+
const pageRel = String(unit.clientEntry || `${chunkId}.client.js`).replace(/\\/g, '/');
|
|
17
|
+
const routeId = typeof unit.routeId === 'string' && unit.routeId.trim() ? unit.routeId.trim() : chunkId;
|
|
18
|
+
pages.push({
|
|
19
|
+
chunkId,
|
|
20
|
+
routeId,
|
|
21
|
+
pathPattern,
|
|
22
|
+
pageRel,
|
|
23
|
+
segs: parsePathPattern(pathPattern),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
pages.sort((a, b) => a.chunkId.localeCompare(b.chunkId));
|
|
27
|
+
return { schema: ROUTE_CATALOG_SCHEMA, pages };
|
|
28
|
+
}
|
|
29
|
+
export function emitRouteCatalog(distDir) {
|
|
30
|
+
const deploymentPath = path.join(distDir, 'vmz-deployment.json');
|
|
31
|
+
if (!fs.existsSync(deploymentPath)) {
|
|
32
|
+
return { ok: false, written: [], catalog: null, error: `missing ${deploymentPath}` };
|
|
33
|
+
}
|
|
34
|
+
let deployment;
|
|
35
|
+
try {
|
|
36
|
+
deployment = JSON.parse(fs.readFileSync(deploymentPath, 'utf8'));
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
return { ok: false, written: [], catalog: null, error: err instanceof Error ? err.message : String(err) };
|
|
40
|
+
}
|
|
41
|
+
const catalog = buildRouteCatalogFromDeployment(deployment);
|
|
42
|
+
if (!catalog.pages.length) {
|
|
43
|
+
return { ok: false, written: [], catalog: null, error: 'no page units with pathPattern' };
|
|
44
|
+
}
|
|
45
|
+
const vmzDir = path.join(distDir, '_vmz');
|
|
46
|
+
fs.mkdirSync(vmzDir, { recursive: true });
|
|
47
|
+
writePrettyJsonFile(path.join(distDir, ...ROUTE_CATALOG_REL.split('/')), catalog);
|
|
48
|
+
return { ok: true, written: [ROUTE_CATALOG_REL], catalog };
|
|
49
|
+
}
|
|
50
|
+
export function loadRouteCatalog(distDir) {
|
|
51
|
+
const p = path.join(distDir, ...ROUTE_CATALOG_REL.split('/'));
|
|
52
|
+
if (!fs.existsSync(p))
|
|
53
|
+
return null;
|
|
54
|
+
try {
|
|
55
|
+
const raw = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
56
|
+
if (raw?.schema !== ROUTE_CATALOG_SCHEMA || !Array.isArray(raw.pages))
|
|
57
|
+
return null;
|
|
58
|
+
return raw;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
package/dist/static-emit.js
CHANGED
|
@@ -11,11 +11,12 @@ import { createRenderHost } from '@vmz/core/render-host';
|
|
|
11
11
|
import { resolveRouteLayoutChain } from '@vmz/core/route-layout-chain';
|
|
12
12
|
import { emitCdnPolicy } from './cdn-policy.js';
|
|
13
13
|
import { emitContentAddressedAssets, hashedAssetHref } from './content-addressed-assets.js';
|
|
14
|
+
import { LOCALE_LINK_PLAN_REL } from './locale-route-emit.js';
|
|
14
15
|
import { absoluteUrl, applyLocaleLinkPlan, buildLocaleLinkPlan, buildLocalePageMeta, linkRouteAliasesFromUnits } from './locale-router.js';
|
|
15
16
|
import { requireNativeAddon } from './native-addon.js';
|
|
16
17
|
import { writePrettyJsonFile } from './pretty-json.js';
|
|
17
18
|
import { emitPublicStaticAssets } from './public-static-assets.js';
|
|
18
|
-
import {
|
|
19
|
+
import { emitRouteCatalog, loadRouteCatalog, ROUTE_CATALOG_SCHEMA } from './route-catalog-emit.js';
|
|
19
20
|
import { emitSiteFavicon, readSiteFaviconHeadHtml } from './site-favicon.js';
|
|
20
21
|
export const STATIC_DELIVERY_MANIFEST_SCHEMA = 'vmz.static.delivery_manifest.v0';
|
|
21
22
|
export const STATIC_EMIT_PLAN_SCHEMA = 'vmz.static.emit_plan.v0';
|
|
@@ -42,7 +43,7 @@ export async function emitWebStatic(distDir, opts = {}) {
|
|
|
42
43
|
const cssEntry = hashedAssetHref(assets.rewrites, cssLogical) || hashedAssetHref(assets.rewrites, 'vmz.css');
|
|
43
44
|
const moduleScriptSrc = hashedAssetHref(assets.rewrites, 'entry-client.js') || '/entry-client.js';
|
|
44
45
|
const localeArt = loadLocaleArtifact(distDir);
|
|
45
|
-
const localeLinkPlan = buildLocaleLinkPlan(withLinkRouteAliases(localeArt, distDir, pageCatalog));
|
|
46
|
+
const localeLinkPlan = loadLocaleLinkPlan(distDir) || buildLocaleLinkPlan(withLinkRouteAliases(localeArt, distDir, pageCatalog));
|
|
46
47
|
for (const page of pageCatalog) {
|
|
47
48
|
const pattern = page.pathPattern || patternFromSegs(page.segs);
|
|
48
49
|
const routeId = guessRouteId(distDir, page.chunkId);
|
|
@@ -284,26 +285,21 @@ function sortKeys(value) {
|
|
|
284
285
|
* @param {string} distDir
|
|
285
286
|
*/
|
|
286
287
|
function listPageClientFiles(distDir) {
|
|
287
|
-
|
|
288
|
-
if (!
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
* @param {string} distDir
|
|
295
|
-
*/
|
|
296
|
-
function listPagesFromDeployment(distDir) {
|
|
297
|
-
const deploymentPath = path.join(distDir, 'vmz-deployment.json');
|
|
298
|
-
if (!fs.existsSync(deploymentPath)) {
|
|
299
|
-
throw new Error(`emitWebStatic: missing ${deploymentPath} (plan-only host)`);
|
|
288
|
+
let catalog = loadRouteCatalog(distDir);
|
|
289
|
+
if (!catalog?.pages?.length) {
|
|
290
|
+
const emitted = emitRouteCatalog(distDir);
|
|
291
|
+
if (!emitted.ok || !emitted.catalog?.pages?.length) {
|
|
292
|
+
throw new Error(`emitWebStatic: missing compiled ${ROUTE_CATALOG_SCHEMA} at _vmz/route-catalog.json (${emitted.error || 'empty'})`);
|
|
293
|
+
}
|
|
294
|
+
catalog = emitted.catalog;
|
|
300
295
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
296
|
+
return catalog.pages.map((p) => ({
|
|
297
|
+
chunkId: p.chunkId,
|
|
298
|
+
pathPattern: p.pathPattern,
|
|
299
|
+
pageRel: p.pageRel,
|
|
300
|
+
segs: p.segs,
|
|
301
|
+
routeId: p.routeId,
|
|
302
|
+
}));
|
|
307
303
|
}
|
|
308
304
|
/**
|
|
309
305
|
* @param {ReturnType<typeof parsePathPattern>} segs
|
|
@@ -381,6 +377,20 @@ function loadLocaleArtifact(distDir) {
|
|
|
381
377
|
return null;
|
|
382
378
|
}
|
|
383
379
|
}
|
|
380
|
+
function loadLocaleLinkPlan(distDir) {
|
|
381
|
+
const p = path.join(distDir, ...LOCALE_LINK_PLAN_REL.split('/'));
|
|
382
|
+
if (!fs.existsSync(p))
|
|
383
|
+
return null;
|
|
384
|
+
try {
|
|
385
|
+
const raw = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
386
|
+
if (raw?.schema !== 'vmz.static.locale_link_plan.v0' || !Array.isArray(raw.rows))
|
|
387
|
+
return null;
|
|
388
|
+
return raw;
|
|
389
|
+
}
|
|
390
|
+
catch {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
384
394
|
/** Bridge Link class RouteId ↔ realization chunk routeId for locale href rewrite. */
|
|
385
395
|
function withLinkRouteAliases(localeArt, distDir, pageCatalog) {
|
|
386
396
|
if (!localeArt)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vmz/vmz",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "VMZ Node toolchain — N-API workspace session + CLI (publish name @vmz/vmz)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,16 +48,16 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@vmz/commander": "0.1.
|
|
52
|
-
"@vmz/core": "0.1.
|
|
53
|
-
"@vmz/diagnostic": "0.1.
|
|
54
|
-
"@vmz/plugin": "0.1.
|
|
55
|
-
"@vmz/protocol": "0.1.
|
|
51
|
+
"@vmz/commander": "0.1.31",
|
|
52
|
+
"@vmz/core": "0.1.31",
|
|
53
|
+
"@vmz/diagnostic": "0.1.31",
|
|
54
|
+
"@vmz/plugin": "0.1.31",
|
|
55
|
+
"@vmz/protocol": "0.1.31",
|
|
56
56
|
"jiti": "^2.6.1"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@vmz/plugin-markdown-it": "0.1.
|
|
60
|
-
"@vmz/test": "0.1.
|
|
59
|
+
"@vmz/plugin-markdown-it": "0.1.31",
|
|
60
|
+
"@vmz/test": "0.1.31",
|
|
61
61
|
"typescript": "^5.8.3"
|
|
62
62
|
},
|
|
63
63
|
"peerDependenciesMeta": {
|
|
@@ -92,12 +92,12 @@
|
|
|
92
92
|
"cli"
|
|
93
93
|
],
|
|
94
94
|
"optionalDependencies": {
|
|
95
|
-
"@vmz/vmz-win32-x64": "0.1.
|
|
96
|
-
"@vmz/vmz-win32-arm64": "0.1.
|
|
97
|
-
"@vmz/vmz-darwin-x64": "0.1.
|
|
98
|
-
"@vmz/vmz-darwin-arm64": "0.1.
|
|
99
|
-
"@vmz/vmz-linux-x64": "0.1.
|
|
100
|
-
"@vmz/vmz-linux-arm64": "0.1.
|
|
95
|
+
"@vmz/vmz-win32-x64": "0.1.31",
|
|
96
|
+
"@vmz/vmz-win32-arm64": "0.1.31",
|
|
97
|
+
"@vmz/vmz-darwin-x64": "0.1.31",
|
|
98
|
+
"@vmz/vmz-darwin-arm64": "0.1.31",
|
|
99
|
+
"@vmz/vmz-linux-x64": "0.1.31",
|
|
100
|
+
"@vmz/vmz-linux-arm64": "0.1.31"
|
|
101
101
|
},
|
|
102
102
|
"publishConfig": {
|
|
103
103
|
"access": "public"
|