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/README.md +1 -1
- package/dist/cli.cjs +64 -38
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +64 -38
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
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"
|
|
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()
|
|
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
|
|
503
|
-
|
|
504
|
-
|
|
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
|
|
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
|
-
|
|
1141
|
-
if (found.
|
|
1142
|
-
|
|
1143
|
-
|
|
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(
|
|
1149
|
-
|
|
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
|
|
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:
|
|
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
|
|
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)) {
|