@wc-toolkit/cem-generator-cli 0.1.13 → 0.2.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 (2) hide show
  1. package/dist/cli.js +89 -8
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ import readline from "node:readline/promises";
7
7
  import { stdin as input, stdout as output } from "node:process";
8
8
  import { spawnSync } from "node:child_process";
9
9
  import inquirer from "inquirer";
10
- import { generateCem, loadConfig, mergeConfig } from "@wc-toolkit/cem-generator";
10
+ import { generateCemWithProgram, loadConfig, mergeConfig, } from "@wc-toolkit/cem-generator";
11
11
  const __filename = fileURLToPath(import.meta.url);
12
12
  const __dirname = path.dirname(__filename);
13
13
  const PLUGIN_CHOICES = [
@@ -76,6 +76,7 @@ program
76
76
  .option("--deprecated-last", "Move deprecated items to end of sorted lists")
77
77
  .option("--validate-exported-types <severity>", "Exported-type validation: off | warning | error")
78
78
  .option("--validation-invariants <severity>", "Manifest invariant validation: off | warning | error")
79
+ .option("--watch", "Regenerate when source files change")
79
80
  .action(async (options) => {
80
81
  try {
81
82
  const cwd = process.cwd();
@@ -129,14 +130,21 @@ program
129
130
  if (configPath) {
130
131
  console.log(`Using config file: ${configPath}`);
131
132
  }
132
- const manifest = generateCem(mergedOptions);
133
133
  const outputPath = path.resolve(options.output ?? mergedOptions.filePath ?? "./custom-elements.json");
134
- const outputDir = path.dirname(outputPath);
135
- if (!fs.existsSync(outputDir)) {
136
- fs.mkdirSync(outputDir, { recursive: true });
137
- }
138
- fs.writeFileSync(outputPath, JSON.stringify(manifest, null, 2) + "\n", "utf-8");
139
- console.log(`Generated manifest at ${outputPath}`);
134
+ let previousProgram;
135
+ const generate = () => {
136
+ const result = generateCemWithProgram(mergedOptions, previousProgram);
137
+ previousProgram = result.programResult.program;
138
+ const outputDir = path.dirname(outputPath);
139
+ if (!fs.existsSync(outputDir)) {
140
+ fs.mkdirSync(outputDir, { recursive: true });
141
+ }
142
+ fs.writeFileSync(outputPath, JSON.stringify(result.manifest, null, 2) + "\n", "utf-8");
143
+ console.log(`Generated manifest at ${outputPath}`);
144
+ };
145
+ generate();
146
+ if (options.watch)
147
+ await watchProject(cwd, outputPath, generate);
140
148
  }
141
149
  catch (error) {
142
150
  console.error("Error generating manifest:", error instanceof Error ? error.message : error);
@@ -518,6 +526,79 @@ function parseSelection(answer, choices, label) {
518
526
  });
519
527
  return names;
520
528
  }
529
+ function watchProject(root, outputPath, generate) {
530
+ const watchedExtensions = new Set([
531
+ ".css",
532
+ ".cjs",
533
+ ".js",
534
+ ".jsx",
535
+ ".mjs",
536
+ ".cts",
537
+ ".mts",
538
+ ".ts",
539
+ ".tsx",
540
+ ]);
541
+ let timer;
542
+ let running = false;
543
+ let lastGeneratedAt = Date.now();
544
+ console.log("Watching for source changes. Press Ctrl+C to stop.");
545
+ return new Promise((resolve, reject) => {
546
+ const watcher = fs.watch(root, { recursive: true }, (_event, filename) => {
547
+ if (!filename)
548
+ return;
549
+ const relativePath = filename.toString().replaceAll(path.sep, "/");
550
+ const pathSegments = relativePath.split("/");
551
+ if (pathSegments.includes("node_modules") ||
552
+ pathSegments.includes("dist") ||
553
+ pathSegments.includes(".git") ||
554
+ pathSegments.includes(".astro")) {
555
+ return;
556
+ }
557
+ const filePath = path.resolve(root, relativePath);
558
+ if (filePath === outputPath)
559
+ return;
560
+ try {
561
+ if (fs.statSync(filePath).mtimeMs <= lastGeneratedAt)
562
+ return;
563
+ }
564
+ catch {
565
+ // A removed file still needs to trigger regeneration.
566
+ }
567
+ if (!watchedExtensions.has(path.extname(relativePath))) {
568
+ return;
569
+ }
570
+ if (timer)
571
+ clearTimeout(timer);
572
+ timer = setTimeout(() => {
573
+ timer = undefined;
574
+ if (running)
575
+ return;
576
+ running = true;
577
+ try {
578
+ generate();
579
+ lastGeneratedAt = Date.now();
580
+ }
581
+ catch (error) {
582
+ console.error("Error generating manifest:", error instanceof Error ? error.message : error);
583
+ }
584
+ finally {
585
+ running = false;
586
+ }
587
+ }, 120);
588
+ });
589
+ const stop = () => {
590
+ if (timer)
591
+ clearTimeout(timer);
592
+ watcher.close();
593
+ process.off("SIGINT", stop);
594
+ process.off("SIGTERM", stop);
595
+ resolve();
596
+ };
597
+ watcher.on("error", reject);
598
+ process.once("SIGINT", stop);
599
+ process.once("SIGTERM", stop);
600
+ });
601
+ }
521
602
  function createConfigSource(plugins, integrations = [], include, exclude = DEFAULT_SOURCE_EXCLUDE) {
522
603
  const choices = [...plugins, ...integrations];
523
604
  const imports = choices.map((plugin) => `import { ${plugin.factory} } from "${plugin.packageName}";`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wc-toolkit/cem-generator-cli",
3
- "version": "0.1.13",
3
+ "version": "0.2.0",
4
4
  "description": "CLI for generating Custom Elements Manifests.",
5
5
  "keywords": [
6
6
  "cli",
@@ -35,7 +35,7 @@
35
35
  "commander": "^12.1.0",
36
36
  "custom-elements-manifest": "^2.1.0",
37
37
  "inquirer": "^14.2.2",
38
- "@wc-toolkit/cem-generator": "0.1.12",
38
+ "@wc-toolkit/cem-generator": "0.2.0",
39
39
  "@wc-toolkit/cem-generator-utils": "0.1.4"
40
40
  },
41
41
  "devDependencies": {