@vmz/vmz 0.1.12 → 0.1.13

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 (46) hide show
  1. package/dist/build-assemble.js +3 -4
  2. package/dist/cdn-policy.js +4 -5
  3. package/dist/cli.js +15 -50
  4. package/dist/content-addressed-assets.d.ts +2 -8
  5. package/dist/content-addressed-assets.js +34 -111
  6. package/dist/delivery-profile.d.ts +1 -11
  7. package/dist/delivery-profile.js +1 -70
  8. package/dist/dev-session.d.ts +0 -1
  9. package/dist/dev-session.js +65 -268
  10. package/dist/document-build.d.ts +1 -2
  11. package/dist/document-build.js +82 -104
  12. package/dist/document-cmd.js +9 -2
  13. package/dist/document-enrich.d.ts +1 -2
  14. package/dist/document-enrich.js +4 -15
  15. package/dist/document-integrate.js +21 -29
  16. package/dist/embedded-packaging.js +1 -2
  17. package/dist/index.d.ts +1 -15
  18. package/dist/index.js +3 -59
  19. package/dist/locale-check.js +61 -28
  20. package/dist/locale-cmd.js +42 -10
  21. package/dist/locale-route-emit.d.ts +1 -4
  22. package/dist/locale-route-emit.js +32 -7
  23. package/dist/locale-router.js +8 -26
  24. package/dist/pack.js +2 -3
  25. package/dist/production-observability.js +2 -3
  26. package/dist/production-test-pack.js +3 -4
  27. package/dist/release-pack.js +18 -5
  28. package/dist/server-artifact.js +3 -4
  29. package/dist/site-delivery.js +3 -4
  30. package/dist/static-emit.js +97 -118
  31. package/dist/test-cmd.js +1 -2
  32. package/package.json +12 -12
  33. package/dist/dev-watch-roots.d.ts +0 -80
  34. package/dist/dev-watch-roots.js +0 -245
  35. package/dist/document-layout-render.d.ts +0 -20
  36. package/dist/document-layout-render.js +0 -87
  37. package/dist/document-routing-config.d.ts +0 -13
  38. package/dist/document-routing-config.js +0 -40
  39. package/dist/native-addon.d.ts +0 -9
  40. package/dist/native-addon.js +0 -84
  41. package/dist/pretty-json.d.ts +0 -19
  42. package/dist/pretty-json.js +0 -43
  43. package/dist/route-path.d.ts +0 -35
  44. package/dist/route-path.js +0 -77
  45. package/dist/wechat-packaging.d.ts +0 -22
  46. package/dist/wechat-packaging.js +0 -59
@@ -14,10 +14,9 @@ import { spawn } from 'node:child_process';
14
14
  import { existsSync } from 'node:fs';
15
15
  import path from 'node:path';
16
16
  import { buildIntegratedDocuments, projectHasDocuments } from './document-integrate.js';
17
- import { createWorkspace, resolveNativePath } from './index.js';
17
+ import { createWorkspace } from './index.js';
18
18
  import { emitLocaleRuntimeModules, localeHasErrors } from './locale-check.js';
19
19
  import { log } from './log.js';
20
- import { coalesceRootBurst, collectDevWatchRoots, classifyWatchRoot, isDependencyPath, mergeDirtySets } from './dev-watch-roots.js';
21
20
  import { diffFingerprints, fileFingerprintMap } from './watch-diff.js';
22
21
  /**
23
22
  * @typedef {object} DevSessionOptions
@@ -26,7 +25,6 @@ import { diffFingerprints, fileFingerprintMap } from './watch-diff.js';
26
25
  * @property {string} [host]
27
26
  * @property {number} [port]
28
27
  * @property {number} [pollMs]
29
- * @property {'browser' | 'mini-program-wechat'} [target]
30
28
  * @property {AbortSignal} [signal]
31
29
  * @property {typeof createWorkspace} [createWorkspaceFn]
32
30
  * @property {(opts: { project: string, outDir: string, host: string, port: number }) => import('node:child_process').ChildProcess} [spawnHostFn]
@@ -41,7 +39,6 @@ export function createDevSession(options) {
41
39
  const host = options.host ?? '127.0.0.1';
42
40
  const port = options.port ?? 5173;
43
41
  const pollMs = Math.max(50, options.pollMs ?? 300);
44
- const wechatPreview = options.target === 'mini-program-wechat';
45
42
  const createWs = options.createWorkspaceFn ?? createWorkspace;
46
43
  const spawnHost = options.spawnHostFn ?? defaultSpawnHost;
47
44
  const softReload = options.softReloadFn ?? defaultSoftReload;
@@ -79,33 +76,6 @@ export function createDevSession(options) {
79
76
  log.info(`${label} ok (${mode}; chunks=[${chunks}]; ${(report.emitted ?? []).length} emitted)`);
80
77
  return true;
81
78
  }
82
- /**
83
- * Rewrite `dist/wechat` so WeChat DevTools (already open) recompiles WXSS.
84
- * Preview is vendor compile, not the browser serve-host.
85
- */
86
- function packWechatPreview() {
87
- if (typeof ws.lowerMiniprogramWechatPackaging !== 'function') {
88
- log.error('wechat pack: workspace missing lowerMiniprogramWechatPackaging');
89
- return false;
90
- }
91
- let report;
92
- try {
93
- const raw = ws.lowerMiniprogramWechatPackaging();
94
- report = typeof raw === 'string' ? JSON.parse(raw) : raw;
95
- }
96
- catch (err) {
97
- log.error(`wechat pack failed: ${err}`);
98
- return false;
99
- }
100
- log.diagnostics(report.diagnostics ?? []);
101
- if (report.status !== 'ready') {
102
- log.error(`wechat pack ${report.status || 'failed'}`);
103
- return false;
104
- }
105
- const packRoot = report.packRoot || 'dist/wechat';
106
- log.info(`wechat pack ok → ${path.join(project, packRoot)} (WeChat DevTools compiles WXSS here)`);
107
- return true;
108
- }
109
79
  async function waitHostReady(timeoutMs = 8000) {
110
80
  const start = Date.now();
111
81
  while (Date.now() - start < timeoutMs) {
@@ -173,38 +143,18 @@ export function createDevSession(options) {
173
143
  throw new Error('vmz dev: integrated document build failed');
174
144
  }
175
145
  }
176
- if (wechatPreview) {
177
- if (!packWechatPreview()) {
178
- throw new Error('vmz dev: wechat pack failed');
179
- }
180
- }
181
- else {
182
- const hostJs = path.join(outDir, 'vmz-serve-host.mjs');
183
- if (!existsSync(hostJs)) {
184
- throw new Error(`vmz dev: missing ${hostJs}`);
185
- }
186
- child = spawnHost({ project, outDir, host, port });
187
- await waitHostReady().catch((err) => {
188
- log.warn(String(err));
189
- });
146
+ const hostJs = path.join(outDir, 'vmz-serve-host.mjs');
147
+ if (!existsSync(hostJs)) {
148
+ throw new Error(`vmz dev: missing ${hostJs}`);
190
149
  }
150
+ child = spawnHost({ project, outDir, host, port });
151
+ await waitHostReady().catch((err) => {
152
+ log.warn(String(err));
153
+ });
191
154
  const docsRoot = path.join(project, 'documents');
192
155
  const localesRoot = path.join(project, 'locales');
193
- const designsRoot = path.join(project, 'designs');
194
- const watched = collectDevWatchRoots({ project, outDir });
195
- /** @type {string[]} */
196
- const watchRoots = [...watched.roots];
197
- /** @type {string[]} */
198
- let dependencyRoots = [...watched.dependencyRoots];
199
- if (wechatPreview) {
200
- log.info(`dev → WeChat DevTools (watching ${watchRoots.join(', ')}; keep dist/wechat open)`);
201
- }
202
- else {
203
- log.info(`dev → http://${host}:${port} (watching ${watchRoots.join(', ')})`);
204
- }
205
- if (dependencyRoots.length) {
206
- log.info(`dev dependency watch roots (${dependencyRoots.length}): ${dependencyRoots.join(', ')}`);
207
- }
156
+ const watchRoots = [src].concat(existsSync(docsRoot) ? [docsRoot] : []).concat(existsSync(localesRoot) ? [localesRoot] : []);
157
+ log.info(`dev http://${host}:${port} (watching ${watchRoots.join(', ')})`);
208
158
  /** @type {Map<string, Map<string, string>>} */
209
159
  const fingerprints = new Map();
210
160
  for (const root of watchRoots) {
@@ -216,57 +166,18 @@ export function createDevSession(options) {
216
166
  };
217
167
  signal?.addEventListener('abort', onAbort, { once: true });
218
168
  /**
219
- * Scan all watch roots into a batch. Does not update fingerprints.
169
+ * Wait until src/ stops changing (multi-file agent edits).
220
170
  */
221
- function scanBatch() {
222
- /** @type {{ srcChanged: string[], srcDeleted: string[], depChanged: string[], depDeleted: string[], designsChanged: string[], designsDeleted: string[], docsDirty: boolean, localesDirty: boolean, designsDirty: boolean }} */
223
- const batch = {
224
- srcChanged: [],
225
- srcDeleted: [],
226
- depChanged: [],
227
- depDeleted: [],
228
- designsChanged: [],
229
- designsDeleted: [],
230
- docsDirty: false,
231
- localesDirty: false,
232
- designsDirty: false,
233
- };
234
- const watchCtx = { src, docsRoot, localesRoot, designsRoot, dependencyRoots };
235
- for (const root of watchRoots) {
236
- const prev = fingerprints.get(root) || new Map();
237
- const next = fileFingerprintMap(root);
171
+ async function coalesceSrcBurst() {
172
+ let guard = 0;
173
+ while (guard++ < 20) {
174
+ await sleep(220);
175
+ const prev = fingerprints.get(src) || new Map();
176
+ const next = fileFingerprintMap(src);
238
177
  const diff = diffFingerprints(prev, next);
239
178
  if (!diff.changed.length && !diff.deleted.length)
240
- continue;
241
- const kind = classifyWatchRoot(root, watchCtx);
242
- if (kind === 'src') {
243
- batch.srcChanged.push(...diff.changed);
244
- batch.srcDeleted.push(...diff.deleted);
245
- }
246
- else if (kind === 'locales') {
247
- batch.localesDirty = true;
248
- }
249
- else if (kind === 'docs') {
250
- batch.docsDirty = true;
251
- }
252
- else if (kind === 'designs') {
253
- batch.designsDirty = true;
254
- batch.designsChanged.push(...diff.changed);
255
- batch.designsDeleted.push(...diff.deleted);
256
- }
257
- else if (kind === 'dep') {
258
- batch.depChanged.push(...diff.changed);
259
- batch.depDeleted.push(...diff.deleted);
260
- }
261
- else {
262
- batch.docsDirty = true;
263
- }
264
- }
265
- return batch;
266
- }
267
- function commitFingerprints() {
268
- for (const root of watchRoots) {
269
- fingerprints.set(root, fileFingerprintMap(root));
179
+ break;
180
+ fingerprints.set(src, next);
270
181
  }
271
182
  }
272
183
  try {
@@ -274,125 +185,65 @@ export function createDevSession(options) {
274
185
  await sleep(pollMs);
275
186
  if (stopped || signal?.aborted)
276
187
  break;
277
- if (!wechatPreview && child && child.exitCode != null) {
188
+ if (child && child.exitCode != null) {
278
189
  log.warn(`serve-host exited (${child.exitCode}) — respawning…`);
279
190
  child = spawnHost({ project, outDir, host, port });
280
191
  await waitHostReady().catch(() => { });
281
192
  continue;
282
193
  }
283
- let batch;
194
+ /** @type {{ srcChanged: string[], srcDeleted: string[], docsDirty: boolean, localesDirty: boolean }} */
195
+ let batch = { srcChanged: [], srcDeleted: [], docsDirty: false, localesDirty: false };
284
196
  try {
285
- batch = scanBatch();
197
+ for (const root of watchRoots) {
198
+ const prev = fingerprints.get(root) || new Map();
199
+ const next = fileFingerprintMap(root);
200
+ const diff = diffFingerprints(prev, next);
201
+ if (root === src) {
202
+ batch.srcChanged = diff.changed;
203
+ batch.srcDeleted = diff.deleted;
204
+ }
205
+ else if (root === localesRoot) {
206
+ if (diff.changed.length || diff.deleted.length)
207
+ batch.localesDirty = true;
208
+ }
209
+ else if (diff.changed.length || diff.deleted.length) {
210
+ batch.docsDirty = true;
211
+ }
212
+ }
286
213
  }
287
214
  catch (err) {
288
215
  log.warn('watch error:', err);
289
216
  continue;
290
217
  }
291
- const srcDirty = batch.srcChanged.length + batch.srcDeleted.length;
292
- const depDirty = batch.depChanged.length + batch.depDeleted.length;
293
- const designsDirty = batch.designsDirty || batch.designsChanged.length + batch.designsDeleted.length;
294
- if (!srcDirty && !depDirty && !batch.docsDirty && !batch.localesDirty && !designsDirty)
218
+ if (!batch.srcChanged.length && !batch.srcDeleted.length && !batch.docsDirty && !batch.localesDirty)
295
219
  continue;
296
- // Coalesce multi-file bursts without dropping the initial dirty set.
297
- if (srcDirty > 1) {
298
- const coalesced = await coalesceRootBurst(src, fingerprints, {
299
- changed: batch.srcChanged,
300
- deleted: batch.srcDeleted,
301
- });
302
- batch.srcChanged = coalesced.changed;
303
- batch.srcDeleted = coalesced.deleted;
220
+ if (batch.srcChanged.length + batch.srcDeleted.length > 1) {
221
+ await coalesceSrcBurst();
304
222
  }
305
- if (depDirty > 1) {
306
- // Coalesce each dirty dependency root independently, then merge.
307
- /** @type {{ changed: string[], deleted: string[] }} */
308
- let acc = { changed: [...batch.depChanged], deleted: [...batch.depDeleted] };
309
- for (const root of dependencyRoots) {
310
- const prev = fingerprints.get(root) || new Map();
311
- const next = fileFingerprintMap(root);
312
- const peek = diffFingerprints(prev, next);
313
- if (peek.changed.length + peek.deleted.length <= 1 && !acc.changed.some((f) => isDependencyPath(f, [root]))) {
314
- continue;
315
- }
316
- const coalesced = await coalesceRootBurst(root, fingerprints, {
317
- changed: acc.changed.filter((f) => isDependencyPath(f, [root])),
318
- deleted: acc.deleted.filter((f) => isDependencyPath(f, [root])),
319
- });
320
- const others = {
321
- changed: acc.changed.filter((f) => !isDependencyPath(f, [root])),
322
- deleted: acc.deleted.filter((f) => !isDependencyPath(f, [root])),
323
- };
324
- acc = mergeDirtySets(others, coalesced);
325
- }
326
- batch.depChanged = acc.changed;
327
- batch.depDeleted = acc.deleted;
328
- }
329
- else if (srcDirty === 1 || depDirty === 1) {
223
+ else {
330
224
  await sleep(200);
331
225
  }
332
- // Refresh residual dirty after settle (without discarding coalesced sets).
333
- const residual = scanBatch();
334
- {
335
- const srcMerged = mergeDirtySets({ changed: batch.srcChanged, deleted: batch.srcDeleted }, { changed: residual.srcChanged, deleted: residual.srcDeleted });
336
- batch.srcChanged = srcMerged.changed;
337
- batch.srcDeleted = srcMerged.deleted;
338
- const depMerged = mergeDirtySets({ changed: batch.depChanged, deleted: batch.depDeleted }, { changed: residual.depChanged, deleted: residual.depDeleted });
339
- batch.depChanged = depMerged.changed;
340
- batch.depDeleted = depMerged.deleted;
341
- batch.docsDirty = batch.docsDirty || residual.docsDirty;
342
- batch.localesDirty = batch.localesDirty || residual.localesDirty;
343
- batch.designsDirty = batch.designsDirty || residual.designsDirty;
344
- const designsMerged = mergeDirtySets({ changed: batch.designsChanged, deleted: batch.designsDeleted }, { changed: residual.designsChanged, deleted: residual.designsDeleted });
345
- batch.designsChanged = designsMerged.changed;
346
- batch.designsDeleted = designsMerged.deleted;
347
- }
348
- commitFingerprints();
349
- if (!batch.srcChanged.length &&
350
- !batch.srcDeleted.length &&
351
- !batch.depChanged.length &&
352
- !batch.depDeleted.length &&
353
- !batch.docsDirty &&
354
- !batch.localesDirty &&
355
- !(batch.designsDirty || batch.designsChanged.length || batch.designsDeleted.length)) {
356
- continue;
357
- }
358
- // Dependency changes: conservative full rebuild + full reload (v0.1.5).
359
- if (batch.depChanged.length || batch.depDeleted.length) {
360
- log.info(`dependency change detected (${batch.depChanged.length} update, ${batch.depDeleted.length} delete) — full rebuild…`);
361
- const report = rebuild();
362
- if (!printReport(report, 'rebuild')) {
363
- log.warn('rebuild failed — keeping previous server');
364
- continue;
365
- }
366
- // Refresh watch roots in case the graph gained new packages.
367
- const refreshed = collectDevWatchRoots({ project, outDir });
368
- for (const r of refreshed.roots) {
369
- if (!watchRoots.includes(r)) {
370
- watchRoots.push(r);
371
- fingerprints.set(r, fileFingerprintMap(r));
372
- }
226
+ batch = { srcChanged: [], srcDeleted: [], docsDirty: false, localesDirty: false };
227
+ for (const root of watchRoots) {
228
+ const prev = fingerprints.get(root) || new Map();
229
+ const next = fileFingerprintMap(root);
230
+ const diff = diffFingerprints(prev, next);
231
+ fingerprints.set(root, next);
232
+ if (root === src) {
233
+ batch.srcChanged = diff.changed;
234
+ batch.srcDeleted = diff.deleted;
373
235
  }
374
- dependencyRoots = [...refreshed.dependencyRoots];
375
- if (batch.docsDirty || projectHasDocuments(project)) {
376
- const docs = await buildIntegratedDocuments({ projectRoot: project, outDir });
377
- if (!docs.ok)
378
- log.warn('document mount rebuild failed — keeping previous docs');
236
+ else if (root === localesRoot) {
237
+ if (diff.changed.length || diff.deleted.length)
238
+ batch.localesDirty = true;
379
239
  }
380
- if (wechatPreview) {
381
- if (!packWechatPreview())
382
- log.warn('wechat pack failed — keeping previous dist/wechat');
383
- continue;
240
+ else if (diff.changed.length || diff.deleted.length) {
241
+ batch.docsDirty = true;
384
242
  }
385
- const kind = await reloadAfterBuild({
386
- affectedChunks: report.affectedChunks ?? [],
387
- seedChunks: report.seedChunks ?? [],
388
- emitted: report.emitted ?? [],
389
- full: true,
390
- islandHmr: false,
391
- });
392
- log.info(kind === 'respawn' ? 'reload ok (respawned; deps)' : 'soft reload ok (full page; deps)');
393
- continue;
394
243
  }
395
- let needFullReload = batch.docsDirty || batch.designsDirty;
244
+ if (!batch.srcChanged.length && !batch.srcDeleted.length && !batch.docsDirty && !batch.localesDirty)
245
+ continue;
246
+ let needFullReload = batch.docsDirty;
396
247
  if (batch.srcChanged.length || batch.srcDeleted.length) {
397
248
  log.info(`change detected (${batch.srcChanged.length} update, ${batch.srcDeleted.length} delete) — affected rebuild…`);
398
249
  const changes = [
@@ -413,12 +264,6 @@ export function createDevSession(options) {
413
264
  needFullReload = true;
414
265
  }
415
266
  }
416
- if (wechatPreview) {
417
- if (!packWechatPreview()) {
418
- log.warn('wechat pack failed — keeping previous dist/wechat');
419
- }
420
- continue;
421
- }
422
267
  const kind = await reloadAfterBuild({
423
268
  affectedChunks: report.affectedChunks ?? [],
424
269
  seedChunks: report.seedChunks ?? [],
@@ -435,56 +280,16 @@ export function createDevSession(options) {
435
280
  : 'soft reload ok');
436
281
  continue;
437
282
  }
438
- if (batch.designsChanged.length || batch.designsDeleted.length || batch.designsDirty) {
439
- log.info(`designs change detected (${batch.designsChanged.length} update, ${batch.designsDeleted.length} delete) — rebuilding styles…`);
440
- const changes = [
441
- ...batch.designsChanged.map((p) => ({ path: p, kind: /** @type {'update'} */ ('update') })),
442
- ...batch.designsDeleted.map((p) => ({ path: p, kind: /** @type {'delete'} */ ('delete') })),
443
- ];
444
- const report = rebuild(changes.length ? changes : undefined);
445
- if (!printReport(report, 'rebuild')) {
446
- log.warn('designs rebuild failed — keeping previous styles');
447
- continue;
448
- }
449
- if (batch.docsDirty || projectHasDocuments(project)) {
450
- const docs = await buildIntegratedDocuments({ projectRoot: project, outDir });
451
- if (!docs.ok)
452
- log.warn('document mount rebuild failed — keeping previous docs');
453
- }
454
- if (wechatPreview) {
455
- if (!packWechatPreview())
456
- log.warn('wechat pack failed — keeping previous dist/wechat');
457
- continue;
458
- }
459
- const kind = await reloadAfterBuild({
460
- affectedChunks: report.affectedChunks ?? [],
461
- seedChunks: report.seedChunks ?? [],
462
- emitted: report.emitted ?? [],
463
- full: true,
464
- islandHmr: false,
465
- });
466
- log.info(kind === 'respawn' ? 'reload ok (respawned; designs)' : 'soft reload ok (full page; designs)');
467
- continue;
468
- }
469
283
  if (batch.localesDirty) {
470
284
  log.info('locales change detected — re-emitting #locales runtime…');
471
285
  if (!emitLocales()) {
472
286
  log.warn('locale runtime emit failed — keeping previous modules');
473
287
  continue;
474
288
  }
475
- if (wechatPreview) {
476
- if (!packWechatPreview()) {
477
- log.warn('wechat pack failed — keeping previous dist/wechat');
478
- }
479
- if (!batch.docsDirty)
480
- continue;
481
- }
482
- else {
483
- const kind = await reloadAfterBuild({ full: true, islandHmr: false, emitted: [] });
484
- log.info(kind === 'respawn' ? 'reload ok (respawned; locales)' : 'soft reload ok (full page; locales)');
485
- if (!batch.docsDirty)
486
- continue;
487
- }
289
+ const kind = await reloadAfterBuild({ full: true, islandHmr: false, emitted: [] });
290
+ log.info(kind === 'respawn' ? 'reload ok (respawned; locales)' : 'soft reload ok (full page; locales)');
291
+ if (!batch.docsDirty)
292
+ continue;
488
293
  }
489
294
  if (batch.docsDirty) {
490
295
  log.info('documents change detected — rebuilding document mount…');
@@ -493,15 +298,8 @@ export function createDevSession(options) {
493
298
  log.warn('document mount rebuild failed — keeping previous docs');
494
299
  continue;
495
300
  }
496
- if (wechatPreview) {
497
- if (!packWechatPreview()) {
498
- log.warn('wechat pack failed — keeping previous dist/wechat');
499
- }
500
- }
501
- else {
502
- const kind = await reloadAfterBuild({ full: true, islandHmr: false, emitted: [] });
503
- log.info(kind === 'respawn' ? 'reload ok (respawned; docs)' : 'soft reload ok (full page; docs)');
504
- }
301
+ const kind = await reloadAfterBuild({ full: true, islandHmr: false, emitted: [] });
302
+ log.info(kind === 'respawn' ? 'reload ok (respawned; docs)' : 'soft reload ok (full page; docs)');
505
303
  }
506
304
  }
507
305
  }
@@ -552,7 +350,6 @@ function defaultSpawnHost(opts) {
552
350
  VMZ_PORT: String(opts.port),
553
351
  VMZ_HOST: opts.host,
554
352
  VMZ_DEV: '1',
555
- VMZ_NATIVE_NODE: resolveNativePath(),
556
353
  },
557
354
  stdio: ['ignore', 'inherit', 'inherit'],
558
355
  });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @param {{ projectRoot: string, outDir?: string, appDistDir?: string, strict?: boolean, engines?: { markdown?: string } }} opts
2
+ * @param {{ projectRoot: string, outDir?: string, strict?: boolean, engines?: { markdown?: string } }} opts
3
3
  */
4
4
  export declare function buildDocuments(opts: any): Promise<{
5
5
  ok: boolean;
@@ -57,7 +57,6 @@ export declare function buildDocuments(opts: any): Promise<{
57
57
  outDir: string;
58
58
  designs: string;
59
59
  designsCss: any;
60
- hostShell: string;
61
60
  pages: any[];
62
61
  evidence: string;
63
62
  search: string;