domflax 0.1.1 → 0.1.2

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 CHANGED
@@ -422,24 +422,26 @@ function createTransform(options) {
422
422
  }
423
423
  };
424
424
  }
425
- function builtinPatternNames() {
426
- return builtinPatterns.map((p2) => p2.name);
427
- }
428
425
 
429
426
  // ../cli/src/walk.ts
430
427
  init_esm_shims();
431
428
  import * as fs from "fs";
432
429
  import * as path2 from "path";
433
- var SUPPORTED_EXTS = [".jsx", ".tsx", ".html", ".htm"];
430
+ var SUPPORTED_EXTS = [".jsx", ".tsx"];
431
+ var HTML_EXTS = [".html", ".htm"];
434
432
  var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "domflax-out"]);
435
433
  function isSupported(file) {
436
434
  const lower = file.toLowerCase();
437
435
  return SUPPORTED_EXTS.some((ext) => lower.endsWith(ext));
438
436
  }
437
+ function isHtml(file) {
438
+ const lower = file.toLowerCase();
439
+ return HTML_EXTS.some((ext) => lower.endsWith(ext));
440
+ }
439
441
  function hasGlobMagic(p2) {
440
442
  return /[*?[\]{}]/.test(p2);
441
443
  }
442
- function walkDir(dir, out) {
444
+ function walkDir(dir, out, counts) {
443
445
  let entries;
444
446
  try {
445
447
  entries = fs.readdirSync(dir, { withFileTypes: true });
@@ -450,9 +452,10 @@ function walkDir(dir, out) {
450
452
  const full = path2.join(dir, entry.name);
451
453
  if (entry.isDirectory()) {
452
454
  if (SKIP_DIRS.has(entry.name)) continue;
453
- walkDir(full, out);
454
- } else if (entry.isFile() && isSupported(entry.name)) {
455
- out.push(full);
455
+ walkDir(full, out, counts);
456
+ } else if (entry.isFile()) {
457
+ if (isSupported(entry.name)) out.push(full);
458
+ else if (isHtml(entry.name)) counts.html += 1;
456
459
  }
457
460
  }
458
461
  }
@@ -463,6 +466,7 @@ function globSyncMaybe() {
463
466
  function discoverInputs(paths) {
464
467
  const files = [];
465
468
  const warnings = [];
469
+ const counts = { html: 0 };
466
470
  const seen = /* @__PURE__ */ new Set();
467
471
  const push = (f) => {
468
472
  const abs = path2.resolve(f);
@@ -486,11 +490,13 @@ function discoverInputs(paths) {
486
490
  stat = null;
487
491
  }
488
492
  if (stat?.isDirectory()) {
489
- walkDir(path2.resolve(p2), files);
493
+ walkDir(path2.resolve(p2), files, counts);
490
494
  continue;
491
495
  }
492
496
  if (stat?.isFile()) {
493
- push(p2);
497
+ if (isSupported(p2)) push(p2);
498
+ else if (isHtml(p2)) counts.html += 1;
499
+ else warnings.push(`unsupported file type, skipped: ${p2}`);
494
500
  continue;
495
501
  }
496
502
  if (hasGlobMagic(p2)) {
@@ -499,9 +505,11 @@ function discoverInputs(paths) {
499
505
  warnings.push(`glob not supported on this Node version, skipped: ${p2}`);
500
506
  continue;
501
507
  }
502
- const matches = glob(p2).filter(isSupported);
503
- if (matches.length === 0) warnings.push(`no files matched: ${p2}`);
504
- for (const m2 of matches) push(m2);
508
+ const matched = glob(p2);
509
+ const supported = matched.filter(isSupported);
510
+ counts.html += matched.filter(isHtml).length;
511
+ if (supported.length === 0) warnings.push(`no .jsx/.tsx files matched: ${p2}`);
512
+ for (const m2 of supported) push(m2);
505
513
  continue;
506
514
  }
507
515
  warnings.push(`no such file or directory: ${p2}`);
@@ -515,6 +523,11 @@ function discoverInputs(paths) {
515
523
  deduped.push(abs);
516
524
  }
517
525
  }
526
+ if (deduped.length === 0 && counts.html > 0) {
527
+ warnings.push(
528
+ `found ${counts.html} .html file${counts.html === 1 ? "" : "s"} but HTML optimization isn't supported yet (domflax currently optimizes .jsx/.tsx source; HTML is on the roadmap: https://github.com/Krishnesh-Mishra/domflax#roadmap).`
529
+ );
530
+ }
518
531
  return { files: deduped, inputRoot, warnings };
519
532
  }
520
533
 
@@ -1115,15 +1128,17 @@ var SKIP_DIRS2 = /* @__PURE__ */ new Set([
1115
1128
  ]);
1116
1129
  var COMMON_INPUT_DIRS = ["src", "app", "components", "pages", "lib", "ui", "public"];
1117
1130
  var CSS_FILE_CAP = 200;
1131
+ var DEFAULT_CSS_DEPTH = 10;
1118
1132
  function toRelative(root, abs) {
1119
1133
  const rel = path3.relative(root, abs);
1120
1134
  return rel.split(path3.sep).join("/");
1121
1135
  }
1122
- function detectCssFiles(root) {
1123
- const found = [];
1136
+ function detectCssFiles(root, scanRoots = [], maxDepth = DEFAULT_CSS_DEPTH) {
1137
+ const base = path3.resolve(root);
1138
+ const found = /* @__PURE__ */ new Map();
1124
1139
  let capped = false;
1125
- const walk = (dir) => {
1126
- if (capped) return;
1140
+ const walk = (dir, depth) => {
1141
+ if (capped || depth > maxDepth) return;
1127
1142
  let entries;
1128
1143
  try {
1129
1144
  entries = fs2.readdirSync(dir, { withFileTypes: true });
@@ -1134,23 +1149,31 @@ function detectCssFiles(root) {
1134
1149
  const full = path3.join(dir, entry.name);
1135
1150
  if (entry.isDirectory()) {
1136
1151
  if (SKIP_DIRS2.has(entry.name)) continue;
1137
- walk(full);
1152
+ walk(full, depth + 1);
1138
1153
  if (capped) return;
1139
1154
  } else if (entry.isFile() && entry.name.toLowerCase().endsWith(".css")) {
1140
- found.push(toRelative(root, full));
1141
- if (found.length >= CSS_FILE_CAP) {
1142
- capped = true;
1143
- return;
1155
+ const abs = path3.resolve(full);
1156
+ if (!found.has(abs)) {
1157
+ found.set(abs, toRelative(base, abs));
1158
+ if (found.size >= CSS_FILE_CAP) {
1159
+ capped = true;
1160
+ return;
1161
+ }
1144
1162
  }
1145
1163
  }
1146
1164
  }
1147
1165
  };
1148
- walk(path3.resolve(root));
1149
- found.sort((a, b3) => a.localeCompare(b3));
1166
+ walk(base, 0);
1167
+ for (const r2 of scanRoots) {
1168
+ if (capped) break;
1169
+ const abs = path3.resolve(r2);
1170
+ if (abs !== base) walk(abs, 0);
1171
+ }
1172
+ const list = [...found.values()].sort((a, b3) => a.localeCompare(b3));
1150
1173
  if (capped) {
1151
1174
  console.error(`domflax: more than ${CSS_FILE_CAP} CSS files found; showing the first ${CSS_FILE_CAP}.`);
1152
1175
  }
1153
- return found;
1176
+ return list;
1154
1177
  }
1155
1178
  function detectInputDirs(root) {
1156
1179
  const resolved = path3.resolve(root);
@@ -1232,15 +1255,6 @@ async function runWizard(base) {
1232
1255
  } else if (outputMode === "overwrite") {
1233
1256
  dangerouslyOverwriteSource = true;
1234
1257
  }
1235
- const allPasses = builtinPatternNames();
1236
- const passSelection = await fe({
1237
- message: "Which optimization passes should run?",
1238
- options: allPasses.map((name) => ({ value: name, label: name })),
1239
- initialValues: [...allPasses],
1240
- required: true
1241
- });
1242
- if (cancelled(passSelection)) return done();
1243
- const passes = passSelection;
1244
1258
  const provider = await ve({
1245
1259
  message: "How should class names resolve to styles?",
1246
1260
  options: [
@@ -1253,7 +1267,7 @@ async function runWizard(base) {
1253
1267
  if (cancelled(provider)) return done();
1254
1268
  let css = base.css;
1255
1269
  if (provider === "custom") {
1256
- const detectedCss = detectCssFiles(root);
1270
+ const detectedCss = detectCssFiles(root, [inputPath]);
1257
1271
  if (detectedCss.length > 0) {
1258
1272
  const picked = await fe({
1259
1273
  message: "Which CSS files should resolve your classes? (all detected files are pre-selected)",
@@ -1281,7 +1295,7 @@ async function runWizard(base) {
1281
1295
  css,
1282
1296
  dryRun,
1283
1297
  dangerouslyOverwriteSource,
1284
- passes: passes.length === allPasses.length ? null : passes,
1298
+ passes: null,
1285
1299
  safety: base.safety ?? DEFAULT_SAFETY
1286
1300
  };
1287
1301
  function done() {
@@ -1311,7 +1325,7 @@ async function execute(options) {
1311
1325
  const { files, inputRoot, warnings } = discoverInputs(options.paths);
1312
1326
  for (const w2 of warnings) console.error(`domflax: ${w2}`);
1313
1327
  if (files.length === 0) {
1314
- console.error("domflax: no .jsx/.tsx/.html files found for the given paths");
1328
+ console.error("domflax: no .jsx/.tsx files found for the given paths");
1315
1329
  return { exitCode: 1 };
1316
1330
  }
1317
1331
  const projectRoot = options.projectRoot ?? process.cwd();
@@ -1358,8 +1372,20 @@ async function execute(options) {
1358
1372
  failures += 1;
1359
1373
  }
1360
1374
  }
1375
+ if (options.dryRun) {
1376
+ console.log("\ndomflax: dry run \u2014 no files were written.");
1377
+ } else if (totals.changed === 0) {
1378
+ console.log(
1379
+ `
1380
+ domflax: processed ${totals.files} file${totals.files === 1 ? "" : "s"} \u2014 nothing to optimize (0 changed).`
1381
+ );
1382
+ } else {
1383
+ console.log(
1384
+ `
1385
+ domflax: optimized ${totals.changed} of ${totals.files} file${totals.files === 1 ? "" : "s"} (${totals.nodesRemoved} nodes removed, ${totals.classesSaved} classes saved, ${totals.bytesSaved} bytes saved).`
1386
+ );
1387
+ }
1361
1388
  if (options.report) printReport(totals);
1362
- if (options.dryRun) console.log("\ndomflax: dry run \u2014 no files were written.");
1363
1389
  return { exitCode: failures > 0 ? 1 : 0 };
1364
1390
  }
1365
1391
  async function main(argv = process.argv.slice(2)) {