@zpress/cli 0.5.3 → 0.6.0

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 (3) hide show
  1. package/dist/145.mjs +171 -160
  2. package/dist/watcher.mjs +10 -10
  3. package/package.json +4 -4
package/dist/145.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { cli, command } from "@kidd-cli/core";
3
- import { configError, createPaths, generateAssets, hasGlobChars, loadConfig, loadManifest, normalizeInclude, resolveEntries, sync } from "@zpress/core";
3
+ import promises from "node:fs/promises";
4
+ import { checkWorkspaceIncludes, configError, createPaths, generateAssets, hasGlobChars, loadConfig, loadManifest, normalizeInclude, resolveEntries, sync } from "@zpress/core";
4
5
  import { z } from "zod";
5
6
  import node_path from "node:path";
6
7
  import { execFileSync, spawn } from "node:child_process";
@@ -11,7 +12,6 @@ import { build, dev, serve } from "@rspress/core";
11
12
  import { createRspressConfig } from "@zpress/ui";
12
13
  import get_port, { portNumbers } from "get-port";
13
14
  import { P, match as external_ts_pattern_match } from "ts-pattern";
14
- import promises from "node:fs/promises";
15
15
  import { compact, uniq } from "es-toolkit";
16
16
  import { createRegistry, render, toSlug } from "@zpress/templates";
17
17
  import node_fs from "node:fs";
@@ -30,7 +30,7 @@ async function startDevServer(options) {
30
30
  port: portNumbers(preferred, preferred + DEV_PORT_RANGE)
31
31
  });
32
32
  let serverInstance = null;
33
- async function startServer(config) {
33
+ async function startServer(config, internalOptions) {
34
34
  const rspressConfig = createRspressConfig({
35
35
  config,
36
36
  paths,
@@ -48,7 +48,8 @@ async function startDevServer(options) {
48
48
  server: {
49
49
  port,
50
50
  strictPort: true
51
- }
51
+ },
52
+ ...buildCacheOverride(internalOptions)
52
53
  }
53
54
  });
54
55
  return true;
@@ -57,7 +58,9 @@ async function startDevServer(options) {
57
58
  return false;
58
59
  }
59
60
  }
60
- const started = await startServer(options.config);
61
+ const started = await startServer(options.config, {
62
+ skipBuildCache: false
63
+ });
61
64
  if (!started) process.exit(1);
62
65
  return async (newConfig)=>{
63
66
  process.stdout.write('\nšŸ”„ Config changed — restarting dev server...\n');
@@ -78,7 +81,9 @@ async function startDevServer(options) {
78
81
  }
79
82
  serverInstance = null;
80
83
  }
81
- const restarted = await startServer(newConfig);
84
+ const restarted = await startServer(newConfig, {
85
+ skipBuildCache: true
86
+ });
82
87
  if (restarted) process.stdout.write('āœ… Dev server restarted\n\n');
83
88
  else process.stderr.write('āš ļø Dev server failed to restart — fix the config and save again\n\n');
84
89
  };
@@ -154,6 +159,14 @@ function createCloseEvent(httpServer) {
154
159
  if (!httpServer.listening) return null;
155
160
  return once(httpServer, 'close');
156
161
  }
162
+ function buildCacheOverride(options) {
163
+ if (options.skipBuildCache) return {
164
+ performance: {
165
+ buildCache: false
166
+ }
167
+ };
168
+ return {};
169
+ }
157
170
  function getHttpServer(instance) {
158
171
  const record = instance;
159
172
  const value = record['httpServer'];
@@ -162,6 +175,7 @@ function getHttpServer(instance) {
162
175
  }
163
176
  const ANSI_PATTERN = /\u001B\[[0-9;]*m/g;
164
177
  const RED = '\u001B[31m';
178
+ const YELLOW = '\u001B[33m';
165
179
  const DIM = '\u001B[2m';
166
180
  const RESET = '\u001B[0m';
167
181
  function runConfigCheck(params) {
@@ -170,17 +184,21 @@ function runConfigCheck(params) {
170
184
  passed: false,
171
185
  errors: [
172
186
  loadError
173
- ]
187
+ ],
188
+ warnings: []
174
189
  };
175
190
  if (!config) return {
176
191
  passed: false,
177
192
  errors: [
178
193
  configError('empty_sections', 'Config is missing')
179
- ]
194
+ ],
195
+ warnings: []
180
196
  };
197
+ const warnings = checkWorkspaceIncludes(config);
181
198
  return {
182
199
  passed: true,
183
- errors: []
200
+ errors: [],
201
+ warnings
184
202
  };
185
203
  }
186
204
  async function runBuildCheck(params) {
@@ -218,6 +236,13 @@ function presentResults(params) {
218
236
  return null;
219
237
  });
220
238
  }
239
+ if (configResult.warnings.length > 0) {
240
+ logger.warn(`${configResult.warnings.length} config warning(s):`);
241
+ configResult.warnings.map((w)=>{
242
+ logger.message(` ${YELLOW}⚠${RESET} ${w.message}`);
243
+ return null;
244
+ });
245
+ }
221
246
  if ('passed' === buildResult.status) logger.success('No broken links');
222
247
  else if ('skipped' === buildResult.status) ;
223
248
  else if ('error' === buildResult.status) logger.error(`Build failed: ${buildResult.message}`);
@@ -355,11 +380,11 @@ const cleanCommand = command({
355
380
  description: 'Remove build artifacts, synced content, and build cache',
356
381
  handler: async (ctx)=>{
357
382
  const paths = createPaths(process.cwd());
358
- ctx.logger.intro('zpress clean');
383
+ ctx.log.intro('zpress clean');
359
384
  const removed = await clean_clean(paths);
360
- if (removed.length > 0) ctx.logger.success(`Removed: ${removed.join(', ')}`);
361
- else ctx.logger.info('Nothing to clean');
362
- ctx.logger.outro('Done');
385
+ if (removed.length > 0) ctx.log.success(`Removed: ${removed.join(', ')}`);
386
+ else ctx.log.info('Nothing to clean');
387
+ ctx.log.outro('Done');
363
388
  }
364
389
  });
365
390
  function cleanTargets(paths) {
@@ -379,7 +404,7 @@ function cleanTargets(paths) {
379
404
  ];
380
405
  }
381
406
  const buildCommand = command({
382
- description: 'Run sync and build the Rspress site',
407
+ description: 'Sync content, generate assets, and build the site',
383
408
  options: z.object({
384
409
  quiet: z.boolean().optional().default(false),
385
410
  clean: z.boolean().optional().default(false),
@@ -389,32 +414,38 @@ const buildCommand = command({
389
414
  handler: async (ctx)=>{
390
415
  const { quiet, check, verbose } = ctx.args;
391
416
  const paths = createPaths(process.cwd());
392
- ctx.logger.intro('zpress build');
417
+ ctx.log.intro('zpress build');
393
418
  if (ctx.args.clean) {
394
419
  const removed = await clean_clean(paths);
395
- if (removed.length > 0 && !quiet) ctx.logger.info(`Cleaned: ${removed.join(', ')}`);
420
+ if (removed.length > 0 && !quiet) ctx.log.info(`Cleaned: ${removed.join(', ')}`);
396
421
  }
397
422
  const [configErr, config] = await loadConfig(paths.repoRoot);
398
423
  if (configErr) {
399
- ctx.logger.error(configErr.message);
400
- if (configErr.errors && configErr.errors.length > 0) configErr.errors.map((err)=>{
401
- const path = err.path.join('.');
402
- return ctx.logger.error(` ${path}: ${err.message}`);
403
- });
424
+ ctx.log.error(configErr.message);
425
+ if (configErr.errors && configErr.errors.length > 0) {
426
+ const details = configErr.errors.map((err)=>` ${err.path.join('.')}: ${err.message}`).join('\n');
427
+ ctx.log.error(details);
428
+ }
404
429
  process.exit(1);
405
430
  }
406
431
  if (check) {
407
- ctx.logger.step('Validating config...');
432
+ ctx.log.step('Validating config...');
408
433
  const configResult = runConfigCheck({
409
434
  config,
410
435
  loadError: configErr
411
436
  });
412
- ctx.logger.step('Syncing content...');
437
+ ctx.log.step('Syncing content...');
413
438
  await sync(config, {
414
439
  paths,
415
440
  quiet: true
416
441
  });
417
- ctx.logger.step('Building & checking for broken links...');
442
+ await runAssetGeneration({
443
+ config,
444
+ paths,
445
+ log: ctx.log,
446
+ quiet: true
447
+ });
448
+ ctx.log.step('Building & checking for broken links...');
418
449
  const buildResult = await runBuildCheck({
419
450
  config,
420
451
  paths,
@@ -423,32 +454,65 @@ const buildCommand = command({
423
454
  const passed = presentResults({
424
455
  configResult,
425
456
  buildResult,
426
- logger: ctx.logger
457
+ logger: ctx.log
427
458
  });
428
459
  if (!passed) {
429
- ctx.logger.outro('Build failed');
460
+ ctx.log.outro('Build failed');
430
461
  process.exit(1);
431
462
  }
432
- ctx.logger.outro('Done');
463
+ ctx.log.outro('Done');
433
464
  } else {
434
465
  await sync(config, {
435
466
  paths,
436
467
  quiet
437
468
  });
469
+ await runAssetGeneration({
470
+ config,
471
+ paths,
472
+ log: ctx.log,
473
+ quiet
474
+ });
438
475
  await buildSite({
439
476
  config,
440
477
  paths
441
478
  });
442
- ctx.logger.outro('Done');
479
+ ctx.log.outro('Done');
443
480
  }
444
481
  }
445
482
  });
483
+ function buildAssetConfig(config) {
484
+ if (!config.title) return null;
485
+ return {
486
+ title: config.title,
487
+ tagline: config.tagline
488
+ };
489
+ }
490
+ async function runAssetGeneration(params) {
491
+ const assetConfig = buildAssetConfig(params.config);
492
+ if (!assetConfig) return;
493
+ if (!params.quiet) params.log.step('Generating assets...');
494
+ const mkdirResult = await promises.mkdir(params.paths.publicDir, {
495
+ recursive: true
496
+ }).then(()=>[
497
+ null
498
+ ]).catch((error)=>[
499
+ toError(error)
500
+ ]);
501
+ const [mkdirErr] = mkdirResult;
502
+ if (mkdirErr) return void params.log.info(`Asset generation skipped: ${mkdirErr.message}`);
503
+ const [assetErr, written] = await generateAssets({
504
+ config: assetConfig,
505
+ publicDir: params.paths.publicDir
506
+ });
507
+ if (assetErr) return void params.log.info(`Asset generation skipped: ${assetErr.message}`);
508
+ if (written.length > 0 && !params.quiet) params.log.info(`Generated ${written.join(', ')}`);
509
+ }
446
510
  const checkCommand = command({
447
511
  description: 'Validate config and check for broken links',
448
512
  handler: async (ctx)=>{
449
513
  const paths = createPaths(process.cwd());
450
- ctx.logger.intro('zpress check');
451
- ctx.logger.step('Validating config...');
514
+ ctx.log.intro('zpress check');
515
+ ctx.log.step('Validating config...');
452
516
  const [configErr, config] = await loadConfig(paths.repoRoot);
453
517
  const configResult = runConfigCheck({
454
518
  config,
@@ -461,18 +525,18 @@ const checkCommand = command({
461
525
  presentResults({
462
526
  configResult,
463
527
  buildResult,
464
- logger: ctx.logger
528
+ logger: ctx.log
465
529
  });
466
- ctx.logger.outro('Checks failed');
530
+ ctx.log.outro('Checks failed');
467
531
  process.exit(1);
468
532
  }
469
- ctx.logger.step('Syncing content...');
533
+ ctx.log.step('Syncing content...');
470
534
  const syncResult = await sync(config, {
471
535
  paths,
472
536
  quiet: true
473
537
  });
474
- ctx.logger.success(`Synced (${syncResult.pagesWritten} written, ${syncResult.pagesSkipped} unchanged)`);
475
- ctx.logger.step('Checking for broken links...');
538
+ ctx.log.success(`Synced (${syncResult.pagesWritten} written, ${syncResult.pagesSkipped} unchanged)`);
539
+ ctx.log.step('Checking for broken links...');
476
540
  const buildResult = await runBuildCheck({
477
541
  config,
478
542
  paths
@@ -480,11 +544,11 @@ const checkCommand = command({
480
544
  const passed = presentResults({
481
545
  configResult,
482
546
  buildResult,
483
- logger: ctx.logger
547
+ logger: ctx.log
484
548
  });
485
- if (passed) ctx.logger.outro('All checks passed');
549
+ if (passed) ctx.log.outro('All checks passed');
486
550
  else {
487
- ctx.logger.outro('Checks failed');
551
+ ctx.log.outro('Checks failed');
488
552
  process.exit(1);
489
553
  }
490
554
  }
@@ -502,17 +566,17 @@ const devCommand = command({
502
566
  handler: async (ctx)=>{
503
567
  const { quiet } = ctx.args;
504
568
  const paths = createPaths(process.cwd());
505
- ctx.logger.intro('zpress dev');
569
+ ctx.log.intro('zpress dev');
506
570
  if (ctx.args.clean) {
507
571
  const removed = await clean_clean(paths);
508
- if (removed.length > 0 && !quiet) ctx.logger.info(`Cleaned: ${removed.join(', ')}`);
572
+ if (removed.length > 0 && !quiet) ctx.log.info(`Cleaned: ${removed.join(', ')}`);
509
573
  }
510
574
  const [configErr, config] = await loadConfig(paths.repoRoot);
511
575
  if (configErr) {
512
- ctx.logger.error(configErr.message);
576
+ ctx.log.error(configErr.message);
513
577
  if (configErr.errors && configErr.errors.length > 0) configErr.errors.forEach((err)=>{
514
578
  const path = err.path.join('.');
515
- ctx.logger.error(` ${path}: ${err.message}`);
579
+ ctx.log.error(` ${path}: ${err.message}`);
516
580
  });
517
581
  process.exit(1);
518
582
  }
@@ -529,7 +593,12 @@ const devCommand = command({
529
593
  vscode: ctx.args.vscode
530
594
  });
531
595
  const { createWatcher } = await import("./watcher.mjs");
532
- const watcher = createWatcher(config, paths, onConfigReload);
596
+ const watcher = createWatcher({
597
+ initialConfig: config,
598
+ paths,
599
+ log: ctx.log,
600
+ onConfigReload
601
+ });
533
602
  function cleanup() {
534
603
  watcher.close();
535
604
  }
@@ -558,11 +627,11 @@ const diffCommand = command({
558
627
  const [configErr, config] = await loadConfig(paths.repoRoot);
559
628
  if (configErr) {
560
629
  if (pretty) {
561
- ctx.logger.intro('zpress diff');
562
- ctx.logger.error(configErr.message);
630
+ ctx.log.intro('zpress diff');
631
+ ctx.log.error(configErr.message);
563
632
  if (configErr.errors && configErr.errors.length > 0) configErr.errors.forEach((err)=>{
564
633
  const p = err.path.join('.');
565
- ctx.logger.error(` ${p}: ${err.message}`);
634
+ ctx.log.error(` ${p}: ${err.message}`);
566
635
  });
567
636
  }
568
637
  process.exit(1);
@@ -570,9 +639,9 @@ const diffCommand = command({
570
639
  const dirs = collectWatchPaths(config);
571
640
  if (0 === dirs.length) {
572
641
  if (pretty) {
573
- ctx.logger.intro('zpress diff');
574
- ctx.logger.warn('No source directories found in config');
575
- ctx.logger.outro('Done');
642
+ ctx.log.intro('zpress diff');
643
+ ctx.log.warn('No source directories found in config');
644
+ ctx.log.outro('Done');
576
645
  }
577
646
  return;
578
647
  }
@@ -586,25 +655,25 @@ const diffCommand = command({
586
655
  }));
587
656
  if (gitErr) {
588
657
  if (pretty) {
589
- ctx.logger.intro('zpress diff');
590
- ctx.logger.error(`Git failed: ${gitErr.message}`);
591
- ctx.logger.outro('Done');
658
+ ctx.log.intro('zpress diff');
659
+ ctx.log.error(`Git failed: ${gitErr.message}`);
660
+ ctx.log.outro('Done');
592
661
  }
593
662
  process.exit(1);
594
663
  }
595
664
  if (0 === changed.length) {
596
665
  if (pretty) {
597
- ctx.logger.intro('zpress diff');
598
- ctx.logger.success('No changes detected');
599
- ctx.logger.outro('Done');
666
+ ctx.log.intro('zpress diff');
667
+ ctx.log.success('No changes detected');
668
+ ctx.log.outro('Done');
600
669
  }
601
670
  return;
602
671
  }
603
672
  if (pretty) {
604
- ctx.logger.intro('zpress diff');
605
- ctx.logger.step(`Watching ${dirs.length} path(s)`);
606
- ctx.logger.note(changed.join('\n'), `${changed.length} changed file(s)`);
607
- ctx.logger.outro('Done');
673
+ ctx.log.intro('zpress diff');
674
+ ctx.log.step(`Watching ${dirs.length} path(s)`);
675
+ ctx.log.note(changed.join('\n'), `${changed.length} changed file(s)`);
676
+ ctx.log.outro('Done');
608
677
  } else process.stdout.write(`${changed.join(' ')}\n`);
609
678
  if (ref) process.exit(1);
610
679
  }
@@ -742,7 +811,7 @@ const draftCommand = command({
742
811
  out: z.string().optional().default('.')
743
812
  }),
744
813
  handler: async (ctx)=>{
745
- ctx.logger.intro('zpress draft');
814
+ ctx.log.intro('zpress draft');
746
815
  const typeArg = ctx.args.type;
747
816
  const hasValidType = external_ts_pattern_match(typeArg).with(P.string.minLength(1), (t)=>registry.has(t)).otherwise(()=>false);
748
817
  const selectedType = await external_ts_pattern_match(hasValidType).with(true, ()=>Promise.resolve(typeArg)).otherwise(()=>ctx.prompts.select({
@@ -754,7 +823,7 @@ const draftCommand = command({
754
823
  }))
755
824
  }));
756
825
  const template = registry.get(selectedType);
757
- if (!template) return void ctx.logger.error(`Unknown template type: ${selectedType}`);
826
+ if (!template) return void ctx.log.error(`Unknown template type: ${selectedType}`);
758
827
  const title = await external_ts_pattern_match(ctx.args.title).with(P.string.minLength(1), (t)=>Promise.resolve(t)).otherwise(()=>ctx.prompts.text({
759
828
  message: 'Document title',
760
829
  placeholder: 'e.g. Authentication',
@@ -763,7 +832,7 @@ const draftCommand = command({
763
832
  }
764
833
  }));
765
834
  const slug = toSlug(title);
766
- if (0 === slug.length) return void ctx.logger.error('Title must include at least one letter or number');
835
+ if (0 === slug.length) return void ctx.log.error('Title must include at least one letter or number');
767
836
  const content = render(template, {
768
837
  title
769
838
  });
@@ -771,13 +840,13 @@ const draftCommand = command({
771
840
  const outDir = node_path.resolve(process.cwd(), ctx.args.out);
772
841
  const filePath = node_path.join(outDir, filename);
773
842
  const exists = await promises.access(filePath).then(()=>true).catch(()=>false);
774
- if (exists) return void ctx.logger.error(`File already exists: ${node_path.relative(process.cwd(), filePath)}`);
843
+ if (exists) return void ctx.log.error(`File already exists: ${node_path.relative(process.cwd(), filePath)}`);
775
844
  await promises.mkdir(outDir, {
776
845
  recursive: true
777
846
  });
778
847
  await promises.writeFile(filePath, content, 'utf8');
779
- ctx.logger.success(`Created ${node_path.relative(process.cwd(), filePath)}`);
780
- ctx.logger.outro('Done');
848
+ ctx.log.success(`Created ${node_path.relative(process.cwd(), filePath)}`);
849
+ ctx.log.outro('Done');
781
850
  }
782
851
  });
783
852
  const dumpCommand = command({
@@ -786,10 +855,10 @@ const dumpCommand = command({
786
855
  const paths = createPaths(process.cwd());
787
856
  const [configErr, config] = await loadConfig(paths.repoRoot);
788
857
  if (configErr) {
789
- ctx.logger.error(configErr.message);
858
+ ctx.log.error(configErr.message);
790
859
  if (configErr.errors && configErr.errors.length > 0) configErr.errors.map((err)=>{
791
860
  const path = err.path.join('.');
792
- return ctx.logger.error(` ${path}: ${err.message}`);
861
+ return ctx.log.error(` ${path}: ${err.message}`);
793
862
  });
794
863
  process.exit(1);
795
864
  }
@@ -807,7 +876,7 @@ const dumpCommand = command({
807
876
  };
808
877
  const [resolveErr, resolved] = await resolveEntries(config.sections, syncCtx);
809
878
  if (resolveErr) {
810
- ctx.logger.error(resolveErr.message);
879
+ ctx.log.error(resolveErr.message);
811
880
  process.exit(1);
812
881
  }
813
882
  const tree = toTree(resolved);
@@ -857,50 +926,6 @@ function buildDumpEntry(entry) {
857
926
  ...maybeItems(entry.items)
858
927
  };
859
928
  }
860
- const generateCommand = command({
861
- description: 'Generate banner, logo, and icon SVG assets from project title',
862
- handler: async (ctx)=>{
863
- ctx.logger.intro('zpress generate');
864
- const paths = createPaths(process.cwd());
865
- const [configErr, config] = await loadConfig(paths.repoRoot);
866
- if (configErr) {
867
- ctx.logger.error(configErr.message);
868
- if (configErr.errors && configErr.errors.length > 0) configErr.errors.map((err)=>{
869
- const path = err.path.join('.');
870
- return ctx.logger.error(` ${path}: ${err.message}`);
871
- });
872
- process.exit(1);
873
- }
874
- const assetConfig = buildAssetConfig(config);
875
- if (!assetConfig) {
876
- ctx.logger.warn('No title configured — skipping asset generation');
877
- ctx.logger.outro('Done');
878
- return;
879
- }
880
- await promises.mkdir(paths.publicDir, {
881
- recursive: true
882
- });
883
- const [err, written] = await generateAssets({
884
- config: assetConfig,
885
- publicDir: paths.publicDir
886
- });
887
- if (err) {
888
- ctx.logger.error(err.message);
889
- ctx.logger.outro('Failed');
890
- return;
891
- }
892
- if (0 === written.length) ctx.logger.info('All assets are user-customized — nothing to generate');
893
- else ctx.logger.success(`Generated ${written.join(', ')}`);
894
- ctx.logger.outro('Done');
895
- }
896
- });
897
- function buildAssetConfig(config) {
898
- if (!config.title) return null;
899
- return {
900
- title: config.title,
901
- tagline: config.tagline
902
- };
903
- }
904
929
  const serveCommand = command({
905
930
  description: 'Preview the built Rspress site',
906
931
  options: z.object({
@@ -911,14 +936,14 @@ const serveCommand = command({
911
936
  vscode: z.boolean().optional().default(false)
912
937
  }),
913
938
  handler: async (ctx)=>{
914
- ctx.logger.intro('zpress serve');
939
+ ctx.log.intro('zpress serve');
915
940
  const paths = createPaths(process.cwd());
916
941
  const [configErr, config] = await loadConfig(paths.repoRoot);
917
942
  if (configErr) {
918
- ctx.logger.error(configErr.message);
943
+ ctx.log.error(configErr.message);
919
944
  if (configErr.errors && configErr.errors.length > 0) configErr.errors.map((err)=>{
920
945
  const path = err.path.join('.');
921
- return ctx.logger.error(` ${path}: ${err.message}`);
946
+ return ctx.log.error(` ${path}: ${err.message}`);
922
947
  });
923
948
  process.exit(1);
924
949
  }
@@ -940,16 +965,16 @@ const setupCommand = command({
940
965
  const cwd = process.cwd();
941
966
  const paths = createPaths(cwd);
942
967
  const configPath = node_path.join(paths.repoRoot, CONFIG_FILENAME);
943
- ctx.logger.intro('zpress setup');
968
+ ctx.log.intro('zpress setup');
944
969
  if (node_fs.existsSync(configPath)) {
945
- ctx.logger.warn(`${CONFIG_FILENAME} already exists — skipping`);
946
- ctx.logger.outro('Done');
970
+ ctx.log.warn(`${CONFIG_FILENAME} already exists — skipping`);
971
+ ctx.log.outro('Done');
947
972
  return;
948
973
  }
949
974
  const title = deriveTitle(cwd);
950
975
  node_fs.writeFileSync(configPath, buildConfigTemplate(title), 'utf8');
951
- ctx.logger.success(`Created ${CONFIG_FILENAME} (title: "${title}")`);
952
- await ensureGitignore(paths, ctx.logger);
976
+ ctx.log.success(`Created ${CONFIG_FILENAME} (title: "${title}")`);
977
+ await ensureGitignore(paths, ctx.log);
953
978
  await promises.mkdir(paths.publicDir, {
954
979
  recursive: true
955
980
  });
@@ -961,11 +986,11 @@ const setupCommand = command({
961
986
  publicDir: paths.publicDir
962
987
  });
963
988
  if (assetErr) {
964
- ctx.logger.error(`Asset generation failed: ${assetErr.message}`);
989
+ ctx.log.error(`Asset generation failed: ${assetErr.message}`);
965
990
  process.exit(1);
966
991
  }
967
- if (written.length > 0) ctx.logger.success(`Generated ${written.join(', ')}`);
968
- ctx.logger.outro('Done');
992
+ if (written.length > 0) ctx.log.success(`Generated ${written.join(', ')}`);
993
+ ctx.log.outro('Done');
969
994
  }
970
995
  });
971
996
  function extractGitRepoName(cwd) {
@@ -1042,47 +1067,33 @@ async function ensureGitignore(paths, logger) {
1042
1067
  await promises.writeFile(node_path.join(paths.outputRoot, '.gitignore'), NESTED_GITIGNORE_CONTENT, 'utf8');
1043
1068
  logger.success('Created .zpress/.gitignore');
1044
1069
  }
1045
- const syncCommand = command({
1046
- description: 'Sync documentation sources into .zpress/',
1047
- options: z.object({
1048
- quiet: z.boolean().optional().default(false)
1049
- }),
1050
- handler: async (ctx)=>{
1051
- const { quiet } = ctx.args;
1052
- const paths = createPaths(process.cwd());
1053
- if (!quiet) ctx.logger.intro('zpress sync');
1054
- const [configErr, config] = await loadConfig(paths.repoRoot);
1055
- if (configErr) {
1056
- ctx.logger.error(configErr.message);
1057
- if (configErr.errors && configErr.errors.length > 0) configErr.errors.map((err)=>{
1058
- const path = err.path.join('.');
1059
- return ctx.logger.error(` ${path}: ${err.message}`);
1060
- });
1061
- process.exit(1);
1062
- }
1063
- await sync(config, {
1064
- paths,
1065
- quiet
1066
- });
1067
- if (!quiet) ctx.logger.outro('Done');
1068
- }
1069
- });
1070
1070
  await cli({
1071
1071
  name: 'zpress',
1072
- version: "0.5.3",
1072
+ version: "0.6.0",
1073
1073
  description: 'CLI for building and serving documentation',
1074
1074
  commands: {
1075
- sync: syncCommand,
1076
- dev: devCommand,
1077
- diff: diffCommand,
1078
- build: buildCommand,
1079
- check: checkCommand,
1080
- draft: draftCommand,
1081
- serve: serveCommand,
1082
- clean: cleanCommand,
1083
- dump: dumpCommand,
1084
- setup: setupCommand,
1085
- generate: generateCommand
1075
+ commands: {
1076
+ setup: setupCommand,
1077
+ dev: devCommand,
1078
+ build: buildCommand,
1079
+ serve: serveCommand,
1080
+ check: checkCommand,
1081
+ diff: diffCommand,
1082
+ draft: draftCommand,
1083
+ clean: cleanCommand,
1084
+ dump: dumpCommand
1085
+ },
1086
+ order: [
1087
+ 'setup',
1088
+ 'dev',
1089
+ 'build',
1090
+ 'serve',
1091
+ 'check',
1092
+ 'diff',
1093
+ 'draft',
1094
+ 'clean',
1095
+ 'dump'
1096
+ ]
1086
1097
  }
1087
1098
  });
1088
1099
  export { toError };
package/dist/watcher.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  import { watch } from "node:fs";
2
2
  import node_path from "node:path";
3
- import { cliLogger } from "@kidd-cli/core/logger";
4
3
  import { loadConfig, sync } from "@zpress/core";
5
4
  import { debounce } from "es-toolkit";
6
5
  import { toError } from "./145.mjs";
@@ -25,11 +24,12 @@ const IGNORED_DIRS = new Set([
25
24
  'dist',
26
25
  '.turbo'
27
26
  ]);
28
- function createWatcher(initialConfig, paths, onConfigReload) {
27
+ function createWatcher(params) {
28
+ const { initialConfig, paths, log, onConfigReload } = params;
29
29
  const { repoRoot } = paths;
30
30
  const configFileNames = new Set(CONFIG_EXTENSIONS.map((ext)=>`zpress.config${ext}`));
31
31
  let config = initialConfig;
32
- cliLogger.info(`Watching ${repoRoot}`);
32
+ log.info(`Watching ${repoRoot}`);
33
33
  let syncing = false;
34
34
  let pendingReloadConfig = null;
35
35
  let consecutiveFailures = 0;
@@ -45,15 +45,15 @@ function createWatcher(initialConfig, paths, onConfigReload) {
45
45
  if (reloadConfig) {
46
46
  const [configErr, newConfig] = await loadConfig(paths.repoRoot);
47
47
  if (configErr) {
48
- cliLogger.error(`Config reload failed: ${configErr.message}`);
48
+ log.error(`Config reload failed: ${configErr.message}`);
49
49
  if (configErr.errors && configErr.errors.length > 0) configErr.errors.forEach((err)=>{
50
50
  const pathStr = err.path.join('.');
51
- cliLogger.error(` ${pathStr}: ${err.message}`);
51
+ log.error(` ${pathStr}: ${err.message}`);
52
52
  });
53
53
  return;
54
54
  }
55
55
  config = newConfig;
56
- cliLogger.info('Config reloaded');
56
+ log.info('Config reloaded');
57
57
  didReloadConfig = true;
58
58
  }
59
59
  await sync(config, {
@@ -63,11 +63,11 @@ function createWatcher(initialConfig, paths, onConfigReload) {
63
63
  if (didReloadConfig && onConfigReload) await onConfigReload(config);
64
64
  } catch (error) {
65
65
  consecutiveFailures += 1;
66
- cliLogger.error(`Sync error: ${toError(error).message}`);
66
+ log.error(`Sync error: ${toError(error).message}`);
67
67
  } finally{
68
68
  syncing = false;
69
69
  if (null !== pendingReloadConfig) if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
70
- cliLogger.error(`Sync failed ${consecutiveFailures} consecutive times, dropping pending resync. Will retry on next file change.`);
70
+ log.error(`Sync failed ${consecutiveFailures} consecutive times, dropping pending resync. Will retry on next file change.`);
71
71
  pendingReloadConfig = null;
72
72
  consecutiveFailures = 0;
73
73
  } else {
@@ -91,12 +91,12 @@ function createWatcher(initialConfig, paths, onConfigReload) {
91
91
  if (isIgnored(filename)) return;
92
92
  const basename = node_path.basename(filename);
93
93
  if (isConfigFile(basename, filename)) {
94
- cliLogger.info(`Config changed: ${basename}`);
94
+ log.info(`Config changed: ${basename}`);
95
95
  debouncedConfigSync();
96
96
  return;
97
97
  }
98
98
  if (!isMarkdownFile(filename)) return;
99
- cliLogger.step(`Changed: ${filename}`);
99
+ log.step(`Changed: ${filename}`);
100
100
  debouncedSync();
101
101
  });
102
102
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zpress/cli",
3
- "version": "0.5.3",
3
+ "version": "0.6.0",
4
4
  "description": "CLI for building and serving zpress documentation sites",
5
5
  "keywords": [
6
6
  "cli",
@@ -34,15 +34,15 @@
34
34
  "provenance": true
35
35
  },
36
36
  "dependencies": {
37
- "@kidd-cli/core": "^0.10.0",
37
+ "@kidd-cli/core": "^0.13.0",
38
38
  "@rspress/core": "^2.0.6",
39
39
  "es-toolkit": "^1.45.1",
40
40
  "get-port": "^7.2.0",
41
41
  "ts-pattern": "^5.9.0",
42
42
  "zod": "^4.3.6",
43
- "@zpress/core": "0.8.0",
43
+ "@zpress/core": "0.8.1",
44
44
  "@zpress/templates": "0.1.2",
45
- "@zpress/ui": "0.8.7"
45
+ "@zpress/ui": "0.8.8"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@rslib/core": "^0.20.0",