@vmz/vmz 0.1.13 → 0.1.14

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 (51) hide show
  1. package/dist/build-assemble.js +18 -7
  2. package/dist/cdn-policy.js +5 -4
  3. package/dist/cli.js +106 -38
  4. package/dist/content-addressed-assets.d.ts +23 -2
  5. package/dist/content-addressed-assets.js +178 -32
  6. package/dist/delivery-profile.d.ts +30 -2
  7. package/dist/delivery-profile.js +139 -5
  8. package/dist/dev-session.d.ts +1 -0
  9. package/dist/dev-session.js +269 -65
  10. package/dist/dev-watch-roots.d.ts +80 -0
  11. package/dist/dev-watch-roots.js +245 -0
  12. package/dist/document-build.d.ts +2 -1
  13. package/dist/document-build.js +104 -82
  14. package/dist/document-cmd.js +2 -9
  15. package/dist/document-enrich.d.ts +2 -1
  16. package/dist/document-enrich.js +15 -4
  17. package/dist/document-integrate.js +29 -21
  18. package/dist/document-layout-render.d.ts +20 -0
  19. package/dist/document-layout-render.js +87 -0
  20. package/dist/document-routing-config.d.ts +13 -0
  21. package/dist/document-routing-config.js +40 -0
  22. package/dist/embedded-packaging.js +2 -1
  23. package/dist/index.d.ts +18 -2
  24. package/dist/index.js +63 -4
  25. package/dist/locale-check.js +28 -61
  26. package/dist/locale-cmd.js +10 -42
  27. package/dist/locale-route-emit.d.ts +4 -1
  28. package/dist/locale-route-emit.js +7 -32
  29. package/dist/locale-router.js +26 -8
  30. package/dist/native-addon.d.ts +9 -0
  31. package/dist/native-addon.js +84 -0
  32. package/dist/pack.js +3 -2
  33. package/dist/pretty-json.d.ts +19 -0
  34. package/dist/pretty-json.js +43 -0
  35. package/dist/production-observability.js +3 -2
  36. package/dist/production-test-pack.js +4 -3
  37. package/dist/public-static-assets.d.ts +24 -0
  38. package/dist/public-static-assets.js +140 -0
  39. package/dist/release-pack.js +5 -18
  40. package/dist/route-path.d.ts +35 -0
  41. package/dist/route-path.js +77 -0
  42. package/dist/server-artifact.js +4 -3
  43. package/dist/site-delivery.js +4 -3
  44. package/dist/site-favicon.d.ts +31 -0
  45. package/dist/site-favicon.js +140 -0
  46. package/dist/static-emit.d.ts +21 -0
  47. package/dist/static-emit.js +134 -97
  48. package/dist/test-cmd.js +2 -1
  49. package/dist/wechat-packaging.d.ts +22 -0
  50. package/dist/wechat-packaging.js +59 -0
  51. package/package.json +12 -12
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export declare const DELIVERY_PROFILE_AUTHORING_SCHEMA = "vmz.delivery.authoring.v0";
6
6
  export declare const BUILD_PROFILE_SELECTION_SCHEMA = "vmz.build.profile_selection.v0";
7
- /** Browser-era assembly kinds (04 B5). */
7
+ /** Browser-era assembly kinds (04 B5). `static-cdn` was renamed to `web-static`. */
8
8
  export declare const ASSEMBLIES: readonly string[];
9
9
  export declare const SERVER_RUNTIMES: readonly string[];
10
10
  /** Official built-in aliases when not overridden in config. */
@@ -13,7 +13,7 @@ export declare const BUILTIN_PROFILES: Readonly<{
13
13
  host: string;
14
14
  assembly: string;
15
15
  };
16
- 'web-static': {
16
+ static: {
17
17
  host: string;
18
18
  assembly: string;
19
19
  };
@@ -28,10 +28,36 @@ export declare const BUILTIN_PROFILES: Readonly<{
28
28
  serverRuntime: string;
29
29
  };
30
30
  }>;
31
+ /**
32
+ * Profile artifact directory name under CLI `--out-dir` (default = profile id).
33
+ * @param {string} id
34
+ * @param {unknown} rawName
35
+ * @param {Array<{ code: string, message: string }>} diagnostics
36
+ * @returns {string | null}
37
+ */
38
+ export declare function normalizeProfileArtifactName(id: any, rawName: any, diagnostics: any): string;
39
+ /**
40
+ * Workspace `--out-dir` + profile `name` → artifact root.
41
+ * Always nests: `path.join(outDir, name)` where `name` defaults to profile id
42
+ * (`name: 'cdn'` → `dist/cdn`; omit → `dist/static` for profile `static`).
43
+ * @param {string} outDir
44
+ * @param {{ name?: string, id?: string } | null | undefined} profile
45
+ */
46
+ export declare function resolveProfileArtifactDir(outDir: any, profile: any): any;
31
47
  export declare function pickSiteAuthoring(raw: any): {
32
48
  artifact: string;
33
49
  sources: any;
34
50
  };
51
+ /**
52
+ * `delivery.packaging.wechat` — vendor identity, not WeChat JSON / wx APIs.
53
+ * @param {unknown} raw
54
+ * @param {Array<{ code: string, message: string }>} diagnostics
55
+ */
56
+ export declare function pickDeliveryPackaging(raw: any, diagnostics: any): {
57
+ wechat?: undefined;
58
+ } | {
59
+ wechat: {};
60
+ };
35
61
  export declare function normalizeDeliveryAuthoring(raw: any): {
36
62
  ok: boolean;
37
63
  table: {
@@ -59,6 +85,8 @@ export declare function selectBuildProfile(table: any, cliProfile?: string): {
59
85
  selection: {
60
86
  schema: string;
61
87
  profileId: any;
88
+ name: any;
89
+ nameExplicit: boolean;
62
90
  host: any;
63
91
  assembly: any;
64
92
  serverRuntime: any;
@@ -4,18 +4,67 @@
4
4
  */
5
5
  // @ts-nocheck
6
6
  import crypto from 'node:crypto';
7
+ import path from 'node:path';
7
8
  export const DELIVERY_PROFILE_AUTHORING_SCHEMA = 'vmz.delivery.authoring.v0';
8
9
  export const BUILD_PROFILE_SELECTION_SCHEMA = 'vmz.build.profile_selection.v0';
9
- /** Browser-era assembly kinds (04 B5). */
10
- export const ASSEMBLIES = Object.freeze(['local-static', 'static-cdn', 'server-host', 'cdn+server', 'rust-embedded']);
10
+ /** Browser-era assembly kinds (04 B5). `static-cdn` was renamed to `web-static`. */
11
+ export const ASSEMBLIES = Object.freeze(['local-static', 'web-static', 'server-host', 'cdn+server', 'rust-embedded']);
11
12
  export const SERVER_RUNTIMES = Object.freeze(['node', 'worker', 'deno', 'bun', 'rust-host']);
12
13
  /** Official built-in aliases when not overridden in config. */
13
14
  export const BUILTIN_PROFILES = Object.freeze({
14
15
  'web-client': { host: 'browser', assembly: 'local-static' },
15
- 'web-static': { host: 'browser', assembly: 'static-cdn' },
16
+ static: { host: 'browser', assembly: 'web-static' },
16
17
  'web-ssr': { host: 'browser', assembly: 'server-host', serverRuntime: 'node' },
17
18
  'web-hybrid': { host: 'browser', assembly: 'cdn+server', serverRuntime: 'node' },
18
19
  });
20
+ /**
21
+ * Profile artifact directory name under CLI `--out-dir` (default = profile id).
22
+ * @param {string} id
23
+ * @param {unknown} rawName
24
+ * @param {Array<{ code: string, message: string }>} diagnostics
25
+ * @returns {string | null}
26
+ */
27
+ export function normalizeProfileArtifactName(id, rawName, diagnostics) {
28
+ const fallback = String(id || '').trim();
29
+ if (rawName == null || rawName === '')
30
+ return fallback || null;
31
+ if (typeof rawName !== 'string') {
32
+ diagnostics.push({
33
+ code: 'delivery.profile.name',
34
+ message: `profiles.${id}.name must be a string (got ${typeof rawName})`,
35
+ });
36
+ return null;
37
+ }
38
+ const name = rawName.trim();
39
+ if (!name) {
40
+ diagnostics.push({
41
+ code: 'delivery.profile.name',
42
+ message: `profiles.${id}.name must be a non-empty string`,
43
+ });
44
+ return null;
45
+ }
46
+ if (name === '.' || name === '..' || name.includes('/') || name.includes('\\') || name.includes('\0')) {
47
+ diagnostics.push({
48
+ code: 'delivery.profile.name',
49
+ message: `profiles.${id}.name must be a single path segment under --out-dir (got '${name}')`,
50
+ });
51
+ return null;
52
+ }
53
+ return name;
54
+ }
55
+ /**
56
+ * Workspace `--out-dir` + profile `name` → artifact root.
57
+ * Always nests: `path.join(outDir, name)` where `name` defaults to profile id
58
+ * (`name: 'cdn'` → `dist/cdn`; omit → `dist/static` for profile `static`).
59
+ * @param {string} outDir
60
+ * @param {{ name?: string, id?: string } | null | undefined} profile
61
+ */
62
+ export function resolveProfileArtifactDir(outDir, profile) {
63
+ const name = String(profile?.name || profile?.id || '').trim();
64
+ if (!name)
65
+ return outDir;
66
+ return path.join(outDir, name);
67
+ }
19
68
  function isPlainObject(v) {
20
69
  return v != null && typeof v === 'object' && !Array.isArray(v);
21
70
  }
@@ -49,6 +98,67 @@ export function pickSiteAuthoring(raw) {
49
98
  }
50
99
  return site;
51
100
  }
101
+ /**
102
+ * `delivery.packaging.wechat` — vendor identity, not WeChat JSON / wx APIs.
103
+ * @param {unknown} raw
104
+ * @param {Array<{ code: string, message: string }>} diagnostics
105
+ */
106
+ export function pickDeliveryPackaging(raw, diagnostics) {
107
+ if (!isPlainObject(raw) || raw.packaging == null)
108
+ return null;
109
+ if (!isPlainObject(raw.packaging)) {
110
+ diagnostics.push({ code: 'delivery.packaging', message: 'delivery.packaging must be an object' });
111
+ return null;
112
+ }
113
+ for (const key of Object.keys(raw.packaging)) {
114
+ if (key !== 'wechat') {
115
+ diagnostics.push({
116
+ code: 'delivery.packaging.vendor',
117
+ message: `delivery.packaging.${key} is not a known vendor (wechat)`,
118
+ });
119
+ }
120
+ }
121
+ const wechat = raw.packaging.wechat;
122
+ if (wechat == null)
123
+ return {};
124
+ if (!isPlainObject(wechat)) {
125
+ diagnostics.push({
126
+ code: 'delivery.packaging.wechat',
127
+ message: 'delivery.packaging.wechat must be an object',
128
+ });
129
+ return null;
130
+ }
131
+ for (const [k, v] of Object.entries(wechat)) {
132
+ if (typeof v === 'function') {
133
+ diagnostics.push({
134
+ code: 'delivery.packaging.executable',
135
+ message: `delivery.packaging.wechat.${k} must be pure data (no functions)`,
136
+ });
137
+ continue;
138
+ }
139
+ if (k !== 'appId' && k !== 'projectName' && k !== 'title') {
140
+ diagnostics.push({
141
+ code: 'delivery.packaging.wechat.field',
142
+ message: `delivery.packaging.wechat.${k} is not a known field (appId|projectName|title)`,
143
+ });
144
+ }
145
+ else if (v != null && typeof v !== 'string') {
146
+ diagnostics.push({
147
+ code: 'delivery.packaging.wechat.type',
148
+ message: `delivery.packaging.wechat.${k} must be a string`,
149
+ });
150
+ }
151
+ }
152
+ const out = {};
153
+ if (typeof wechat.appId === 'string' && wechat.appId.trim())
154
+ out.appId = wechat.appId.trim();
155
+ if (typeof wechat.projectName === 'string' && wechat.projectName.trim()) {
156
+ out.projectName = wechat.projectName.trim();
157
+ }
158
+ if (typeof wechat.title === 'string' && wechat.title.trim())
159
+ out.title = wechat.title.trim();
160
+ return { wechat: out };
161
+ }
52
162
  function normalizeProfileEntry(entry, id, diagnostics) {
53
163
  if (!isPlainObject(entry)) {
54
164
  diagnostics.push({ code: 'delivery.profile.invalid', message: `profiles.${id} must be an object` });
@@ -61,7 +171,14 @@ function normalizeProfileEntry(entry, id, diagnostics) {
61
171
  message: `profiles.${id}.host: only 'browser' is supported before Browser Production (got ${host})`,
62
172
  });
63
173
  }
64
- const assembly = String(entry.assembly || '').trim();
174
+ let assembly = String(entry.assembly || '').trim();
175
+ if (assembly === 'static-cdn') {
176
+ diagnostics.push({
177
+ code: 'delivery.profile.assembly.renamed',
178
+ message: `profiles.${id}.assembly 'static-cdn' was renamed to 'web-static'`,
179
+ });
180
+ return null;
181
+ }
65
182
  if (!ASSEMBLIES.includes(assembly)) {
66
183
  diagnostics.push({
67
184
  code: 'delivery.profile.assembly',
@@ -69,6 +186,10 @@ function normalizeProfileEntry(entry, id, diagnostics) {
69
186
  });
70
187
  return null;
71
188
  }
189
+ const nameExplicit = entry.name != null && String(entry.name).trim() !== '';
190
+ const name = normalizeProfileArtifactName(id, nameExplicit ? entry.name : id, diagnostics);
191
+ if (!name)
192
+ return null;
72
193
  let serverRuntime = null;
73
194
  if (assembly === 'server-host' || assembly === 'cdn+server') {
74
195
  serverRuntime = String(entry.serverRuntime || 'node');
@@ -110,6 +231,9 @@ function normalizeProfileEntry(entry, id, diagnostics) {
110
231
  }
111
232
  return {
112
233
  id,
234
+ name,
235
+ /** True when author set `profiles.<id>.name`; false → `name` defaulted to profile id. */
236
+ nameExplicit,
113
237
  host: 'browser',
114
238
  assembly,
115
239
  serverRuntime,
@@ -183,6 +307,10 @@ export function normalizeDeliveryAuthoring(raw) {
183
307
  },
184
308
  };
185
309
  }
310
+ else if (isPlainObject(raw.packaging)) {
311
+ defaultId = String(raw.default || 'web-ssr').trim() || 'web-ssr';
312
+ profileInputs = { ...BUILTIN_PROFILES };
313
+ }
186
314
  else {
187
315
  return {
188
316
  ok: false,
@@ -206,6 +334,9 @@ export function normalizeDeliveryAuthoring(raw) {
206
334
  message: `delivery.default '${defaultId}' is not a known profile`,
207
335
  });
208
336
  }
337
+ if (diagnostics.length)
338
+ return { ok: false, diagnostics };
339
+ const packaging = pickDeliveryPackaging(raw, diagnostics);
209
340
  if (diagnostics.length)
210
341
  return { ok: false, diagnostics };
211
342
  const table = {
@@ -213,6 +344,7 @@ export function normalizeDeliveryAuthoring(raw) {
213
344
  default: defaultId,
214
345
  profiles,
215
346
  sugar,
347
+ ...(packaging ? { packaging } : {}),
216
348
  };
217
349
  table.digest = sha256Hex(canonicalJson(table));
218
350
  return { ok: true, table };
@@ -234,6 +366,8 @@ export function selectBuildProfile(table, cliProfile = '') {
234
366
  const selection = {
235
367
  schema: BUILD_PROFILE_SELECTION_SCHEMA,
236
368
  profileId: id,
369
+ name: profile.name,
370
+ nameExplicit: Boolean(profile.nameExplicit),
237
371
  host: profile.host,
238
372
  assembly: profile.assembly,
239
373
  serverRuntime: profile.serverRuntime,
@@ -246,7 +380,7 @@ export function selectBuildProfile(table, cliProfile = '') {
246
380
  }
247
381
  export function semanticIdsForAssembly(assembly) {
248
382
  switch (assembly) {
249
- case 'static-cdn':
383
+ case 'web-static':
250
384
  return ['static-delivery', 'asset-graph'];
251
385
  case 'server-host':
252
386
  return ['server-host', 'asset-graph'];
@@ -16,6 +16,7 @@
16
16
  * @property {string} [host]
17
17
  * @property {number} [port]
18
18
  * @property {number} [pollMs]
19
+ * @property {'browser' | 'mini-program-wechat'} [target]
19
20
  * @property {AbortSignal} [signal]
20
21
  * @property {typeof createWorkspace} [createWorkspaceFn]
21
22
  * @property {(opts: { project: string, outDir: string, host: string, port: number }) => import('node:child_process').ChildProcess} [spawnHostFn]