domflax 0.1.0 → 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 +159 -0
- package/dist/{chunk-4HHISSMR.js → chunk-DNHOGPYV.js} +2675 -1503
- package/dist/chunk-DNHOGPYV.js.map +1 -0
- package/dist/{chunk-ZJ2S36GY.js → chunk-DOQEBGWB.js} +33 -20
- package/dist/chunk-DOQEBGWB.js.map +1 -0
- package/dist/{chunk-77SLHRN6.js → chunk-DWLB7FRR.js} +341 -176
- package/dist/chunk-DWLB7FRR.js.map +1 -0
- package/dist/cli.cjs +2209 -774
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +234 -116
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +3021 -1699
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +477 -54
- package/dist/index.d.ts +477 -54
- package/dist/index.js +49 -3
- package/dist/pattern-CV607P87.d.ts +547 -0
- package/dist/pattern-F5xBtIE-.d.cts +547 -0
- package/dist/pattern-kit.cjs +60 -39
- package/dist/pattern-kit.cjs.map +1 -1
- package/dist/pattern-kit.d.cts +3 -18
- package/dist/pattern-kit.d.ts +3 -18
- package/dist/pattern-kit.js +3 -1
- package/dist/pattern-kit.js.map +1 -1
- package/dist/{types-BQ7l6dVe.d.ts → resolve-ops-DIwEelH-.d.cts} +26 -251
- package/dist/{types-BQ7l6dVe.d.cts → resolve-ops-DIwEelH-.d.ts} +26 -251
- package/dist/verify.d.cts +1 -1
- package/dist/verify.d.ts +1 -1
- package/dist/webpack-loader.cjs +2975 -1699
- package/dist/webpack-loader.cjs.map +1 -1
- package/dist/webpack-loader.d.cts +2 -2
- package/dist/webpack-loader.d.ts +2 -2
- package/dist/webpack-loader.js +3 -3
- package/package.json +3 -6
- package/dist/chunk-4HHISSMR.js.map +0 -1
- package/dist/chunk-77SLHRN6.js.map +0 -1
- package/dist/chunk-ZJ2S36GY.js.map +0 -1
- package/dist/pattern-CX6iBzTD.d.ts +0 -237
- package/dist/pattern-P4FIKAUB.d.cts +0 -237
package/dist/cli.js
CHANGED
|
@@ -5,14 +5,14 @@ import {
|
|
|
5
5
|
createJsxBackend,
|
|
6
6
|
createJsxFrontend,
|
|
7
7
|
createTailwindResolver
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DNHOGPYV.js";
|
|
9
9
|
import {
|
|
10
10
|
buildSelectorIndex,
|
|
11
11
|
createSyntheticSink,
|
|
12
12
|
normalizer,
|
|
13
13
|
runPasses,
|
|
14
14
|
syncClassesFromComputed
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-DWLB7FRR.js";
|
|
16
16
|
import {
|
|
17
17
|
__commonJS,
|
|
18
18
|
__toESM,
|
|
@@ -156,8 +156,7 @@ init_esm_shims();
|
|
|
156
156
|
// ../cli/src/index.ts
|
|
157
157
|
init_esm_shims();
|
|
158
158
|
import { mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
159
|
-
import * as
|
|
160
|
-
import { fileURLToPath } from "url";
|
|
159
|
+
import * as path4 from "path";
|
|
161
160
|
|
|
162
161
|
// ../cli/src/options.ts
|
|
163
162
|
init_esm_shims();
|
|
@@ -358,87 +357,91 @@ function createTransform(options) {
|
|
|
358
357
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
359
358
|
const resolver = buildResolver(options.provider, options.css, projectRoot);
|
|
360
359
|
const patterns = selectPatterns(options.passes);
|
|
360
|
+
function prepare(code, id, kind, gate) {
|
|
361
|
+
const parsed = createJsxFrontend().parse(code, {
|
|
362
|
+
id,
|
|
363
|
+
kind,
|
|
364
|
+
resolver,
|
|
365
|
+
normalizer,
|
|
366
|
+
config: {},
|
|
367
|
+
onDiagnostic: () => {
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
const doc = parsed.doc;
|
|
371
|
+
const nodesIn = doc.nodes.size;
|
|
372
|
+
for (const node of doc.nodes.values()) node.meta.safetyFloor = 3;
|
|
373
|
+
const ctx = {
|
|
374
|
+
doc,
|
|
375
|
+
safetyCeiling: options.safety,
|
|
376
|
+
normalizer,
|
|
377
|
+
// Real CSS-selector-safety index from the active resolver (custom-CSS reports combinator /
|
|
378
|
+
// structural-pseudo coupling; Tailwind has none → null index, behaviour unchanged).
|
|
379
|
+
selectors: buildSelectorIndex(doc, resolver),
|
|
380
|
+
resolver,
|
|
381
|
+
gate
|
|
382
|
+
};
|
|
383
|
+
return { doc, ctx, passes: buildPasses(patterns), nodesIn };
|
|
384
|
+
}
|
|
385
|
+
function finish(code, optimized, id, nodesIn) {
|
|
386
|
+
syncClassesFromComputed(optimized, resolver, normalizer);
|
|
387
|
+
const printed = createJsxBackend().print(
|
|
388
|
+
optimized,
|
|
389
|
+
{ moduleId: id, ops: [], provenance: /* @__PURE__ */ new Map() },
|
|
390
|
+
{ normalizer, resolver, sink: createSyntheticSink(), eol: "\n", onDiagnostic: () => {
|
|
391
|
+
} }
|
|
392
|
+
);
|
|
393
|
+
const out = printed.code;
|
|
394
|
+
const nodesOut = optimized.nodes.size;
|
|
395
|
+
const classesBefore = countClassTokens(code);
|
|
396
|
+
const classesAfter = countClassTokens(out);
|
|
397
|
+
return {
|
|
398
|
+
code: out,
|
|
399
|
+
changed: out !== code,
|
|
400
|
+
passthrough: false,
|
|
401
|
+
stats: {
|
|
402
|
+
nodesIn,
|
|
403
|
+
nodesOut,
|
|
404
|
+
nodesRemoved: Math.max(0, nodesIn - nodesOut),
|
|
405
|
+
classesBefore,
|
|
406
|
+
classesAfter,
|
|
407
|
+
classesSaved: Math.max(0, classesBefore - classesAfter),
|
|
408
|
+
bytesBefore: bytes(code),
|
|
409
|
+
bytesAfter: bytes(out),
|
|
410
|
+
bytesSaved: bytes(code) - bytes(out)
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
}
|
|
361
414
|
return {
|
|
362
415
|
resolver,
|
|
363
416
|
transformFile(code, id) {
|
|
364
417
|
const kind = jsxKindOf(id);
|
|
365
418
|
if (kind === null) return passthroughResult(code);
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
resolver,
|
|
370
|
-
normalizer,
|
|
371
|
-
config: {},
|
|
372
|
-
onDiagnostic: () => {
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
const doc = parsed.doc;
|
|
376
|
-
const nodesIn = doc.nodes.size;
|
|
377
|
-
for (const node of doc.nodes.values()) node.meta.safetyFloor = 3;
|
|
378
|
-
const ctx = {
|
|
379
|
-
doc,
|
|
380
|
-
safetyCeiling: options.safety,
|
|
381
|
-
normalizer,
|
|
382
|
-
// Real CSS-selector-safety index from the active resolver (custom-CSS reports combinator /
|
|
383
|
-
// structural-pseudo coupling; Tailwind has none → null index, behaviour unchanged).
|
|
384
|
-
selectors: buildSelectorIndex(doc, resolver),
|
|
385
|
-
resolver
|
|
386
|
-
};
|
|
387
|
-
const { doc: optimized } = runPasses(doc, buildPasses(patterns), ctx);
|
|
388
|
-
syncClassesFromComputed(optimized, resolver, normalizer);
|
|
389
|
-
const printed = createJsxBackend().print(
|
|
390
|
-
optimized,
|
|
391
|
-
{ moduleId: id, ops: [], provenance: /* @__PURE__ */ new Map() },
|
|
392
|
-
{
|
|
393
|
-
normalizer,
|
|
394
|
-
resolver,
|
|
395
|
-
sink: createSyntheticSink(),
|
|
396
|
-
eol: "\n",
|
|
397
|
-
onDiagnostic: () => {
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
);
|
|
401
|
-
const out = printed.code;
|
|
402
|
-
const nodesOut = optimized.nodes.size;
|
|
403
|
-
const classesBefore = countClassTokens(code);
|
|
404
|
-
const classesAfter = countClassTokens(out);
|
|
405
|
-
return {
|
|
406
|
-
code: out,
|
|
407
|
-
changed: out !== code,
|
|
408
|
-
passthrough: false,
|
|
409
|
-
stats: {
|
|
410
|
-
nodesIn,
|
|
411
|
-
nodesOut,
|
|
412
|
-
nodesRemoved: Math.max(0, nodesIn - nodesOut),
|
|
413
|
-
classesBefore,
|
|
414
|
-
classesAfter,
|
|
415
|
-
classesSaved: Math.max(0, classesBefore - classesAfter),
|
|
416
|
-
bytesBefore: bytes(code),
|
|
417
|
-
bytesAfter: bytes(out),
|
|
418
|
-
bytesSaved: bytes(code) - bytes(out)
|
|
419
|
-
}
|
|
420
|
-
};
|
|
419
|
+
const { doc, ctx, passes, nodesIn } = prepare(code, id, kind, "provably-safe");
|
|
420
|
+
const { doc: optimized } = runPasses(doc, passes, ctx);
|
|
421
|
+
return finish(code, optimized, id, nodesIn);
|
|
421
422
|
}
|
|
422
423
|
};
|
|
423
424
|
}
|
|
424
|
-
function builtinPatternNames() {
|
|
425
|
-
return builtinPatterns.map((p2) => p2.name);
|
|
426
|
-
}
|
|
427
425
|
|
|
428
426
|
// ../cli/src/walk.ts
|
|
429
427
|
init_esm_shims();
|
|
430
428
|
import * as fs from "fs";
|
|
431
429
|
import * as path2 from "path";
|
|
432
|
-
var SUPPORTED_EXTS = [".jsx", ".tsx"
|
|
430
|
+
var SUPPORTED_EXTS = [".jsx", ".tsx"];
|
|
431
|
+
var HTML_EXTS = [".html", ".htm"];
|
|
433
432
|
var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "domflax-out"]);
|
|
434
433
|
function isSupported(file) {
|
|
435
434
|
const lower = file.toLowerCase();
|
|
436
435
|
return SUPPORTED_EXTS.some((ext) => lower.endsWith(ext));
|
|
437
436
|
}
|
|
437
|
+
function isHtml(file) {
|
|
438
|
+
const lower = file.toLowerCase();
|
|
439
|
+
return HTML_EXTS.some((ext) => lower.endsWith(ext));
|
|
440
|
+
}
|
|
438
441
|
function hasGlobMagic(p2) {
|
|
439
442
|
return /[*?[\]{}]/.test(p2);
|
|
440
443
|
}
|
|
441
|
-
function walkDir(dir, out) {
|
|
444
|
+
function walkDir(dir, out, counts) {
|
|
442
445
|
let entries;
|
|
443
446
|
try {
|
|
444
447
|
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
@@ -449,9 +452,10 @@ function walkDir(dir, out) {
|
|
|
449
452
|
const full = path2.join(dir, entry.name);
|
|
450
453
|
if (entry.isDirectory()) {
|
|
451
454
|
if (SKIP_DIRS.has(entry.name)) continue;
|
|
452
|
-
walkDir(full, out);
|
|
453
|
-
} else if (entry.isFile()
|
|
454
|
-
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;
|
|
455
459
|
}
|
|
456
460
|
}
|
|
457
461
|
}
|
|
@@ -462,6 +466,7 @@ function globSyncMaybe() {
|
|
|
462
466
|
function discoverInputs(paths) {
|
|
463
467
|
const files = [];
|
|
464
468
|
const warnings = [];
|
|
469
|
+
const counts = { html: 0 };
|
|
465
470
|
const seen = /* @__PURE__ */ new Set();
|
|
466
471
|
const push = (f) => {
|
|
467
472
|
const abs = path2.resolve(f);
|
|
@@ -485,11 +490,13 @@ function discoverInputs(paths) {
|
|
|
485
490
|
stat = null;
|
|
486
491
|
}
|
|
487
492
|
if (stat?.isDirectory()) {
|
|
488
|
-
walkDir(path2.resolve(p2), files);
|
|
493
|
+
walkDir(path2.resolve(p2), files, counts);
|
|
489
494
|
continue;
|
|
490
495
|
}
|
|
491
496
|
if (stat?.isFile()) {
|
|
492
|
-
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}`);
|
|
493
500
|
continue;
|
|
494
501
|
}
|
|
495
502
|
if (hasGlobMagic(p2)) {
|
|
@@ -498,9 +505,11 @@ function discoverInputs(paths) {
|
|
|
498
505
|
warnings.push(`glob not supported on this Node version, skipped: ${p2}`);
|
|
499
506
|
continue;
|
|
500
507
|
}
|
|
501
|
-
const
|
|
502
|
-
|
|
503
|
-
|
|
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);
|
|
504
513
|
continue;
|
|
505
514
|
}
|
|
506
515
|
warnings.push(`no such file or directory: ${p2}`);
|
|
@@ -514,6 +523,11 @@ function discoverInputs(paths) {
|
|
|
514
523
|
deduped.push(abs);
|
|
515
524
|
}
|
|
516
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
|
+
}
|
|
517
531
|
return { files: deduped, inputRoot, warnings };
|
|
518
532
|
}
|
|
519
533
|
|
|
@@ -1098,19 +1112,122 @@ ${import_picocolors2.default.gray(d2)} ${t}
|
|
|
1098
1112
|
};
|
|
1099
1113
|
var J2 = `${import_picocolors2.default.gray(o)} `;
|
|
1100
1114
|
|
|
1115
|
+
// ../cli/src/detect.ts
|
|
1116
|
+
init_esm_shims();
|
|
1117
|
+
import * as fs2 from "fs";
|
|
1118
|
+
import * as path3 from "path";
|
|
1119
|
+
var SKIP_DIRS2 = /* @__PURE__ */ new Set([
|
|
1120
|
+
"node_modules",
|
|
1121
|
+
"dist",
|
|
1122
|
+
"build",
|
|
1123
|
+
".next",
|
|
1124
|
+
"out",
|
|
1125
|
+
"coverage",
|
|
1126
|
+
".git",
|
|
1127
|
+
"domflax-out"
|
|
1128
|
+
]);
|
|
1129
|
+
var COMMON_INPUT_DIRS = ["src", "app", "components", "pages", "lib", "ui", "public"];
|
|
1130
|
+
var CSS_FILE_CAP = 200;
|
|
1131
|
+
var DEFAULT_CSS_DEPTH = 10;
|
|
1132
|
+
function toRelative(root, abs) {
|
|
1133
|
+
const rel = path3.relative(root, abs);
|
|
1134
|
+
return rel.split(path3.sep).join("/");
|
|
1135
|
+
}
|
|
1136
|
+
function detectCssFiles(root, scanRoots = [], maxDepth = DEFAULT_CSS_DEPTH) {
|
|
1137
|
+
const base = path3.resolve(root);
|
|
1138
|
+
const found = /* @__PURE__ */ new Map();
|
|
1139
|
+
let capped = false;
|
|
1140
|
+
const walk = (dir, depth) => {
|
|
1141
|
+
if (capped || depth > maxDepth) return;
|
|
1142
|
+
let entries;
|
|
1143
|
+
try {
|
|
1144
|
+
entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
1145
|
+
} catch {
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
for (const entry of entries) {
|
|
1149
|
+
const full = path3.join(dir, entry.name);
|
|
1150
|
+
if (entry.isDirectory()) {
|
|
1151
|
+
if (SKIP_DIRS2.has(entry.name)) continue;
|
|
1152
|
+
walk(full, depth + 1);
|
|
1153
|
+
if (capped) return;
|
|
1154
|
+
} else if (entry.isFile() && entry.name.toLowerCase().endsWith(".css")) {
|
|
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
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
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));
|
|
1173
|
+
if (capped) {
|
|
1174
|
+
console.error(`domflax: more than ${CSS_FILE_CAP} CSS files found; showing the first ${CSS_FILE_CAP}.`);
|
|
1175
|
+
}
|
|
1176
|
+
return list;
|
|
1177
|
+
}
|
|
1178
|
+
function detectInputDirs(root) {
|
|
1179
|
+
const resolved = path3.resolve(root);
|
|
1180
|
+
return COMMON_INPUT_DIRS.filter((name) => {
|
|
1181
|
+
try {
|
|
1182
|
+
return fs2.statSync(path3.join(resolved, name)).isDirectory();
|
|
1183
|
+
} catch {
|
|
1184
|
+
return false;
|
|
1185
|
+
}
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1101
1189
|
// ../cli/src/wizard.ts
|
|
1190
|
+
var OTHER_INPUT = "\0domflax.other";
|
|
1102
1191
|
var WIZARD_CANCELLED = /* @__PURE__ */ Symbol("domflax.wizard.cancelled");
|
|
1103
1192
|
function cancelled(value) {
|
|
1104
1193
|
return pD(value);
|
|
1105
1194
|
}
|
|
1106
1195
|
async function runWizard(base) {
|
|
1107
1196
|
Ie("domflax \u2014 optimize your markup");
|
|
1108
|
-
const
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1197
|
+
const root = base.projectRoot ?? process.cwd();
|
|
1198
|
+
const detectedInputs = detectInputDirs(root);
|
|
1199
|
+
let inputPath;
|
|
1200
|
+
if (detectedInputs.length > 0) {
|
|
1201
|
+
const defaultInput = detectedInputs.includes("src") ? "src" : detectedInputs[0];
|
|
1202
|
+
const choice = await ve({
|
|
1203
|
+
message: "Which folder should domflax optimize?",
|
|
1204
|
+
options: [
|
|
1205
|
+
...detectedInputs.map((dir) => ({ value: dir, label: dir, hint: "detected" })),
|
|
1206
|
+
{ value: OTHER_INPUT, label: "Other (type a path)\u2026" }
|
|
1207
|
+
],
|
|
1208
|
+
initialValue: defaultInput
|
|
1209
|
+
});
|
|
1210
|
+
if (cancelled(choice)) return done();
|
|
1211
|
+
if (choice === OTHER_INPUT) {
|
|
1212
|
+
const typed = await he({
|
|
1213
|
+
message: "Which folder, glob, or file should domflax optimize?",
|
|
1214
|
+
placeholder: "src",
|
|
1215
|
+
defaultValue: "src"
|
|
1216
|
+
});
|
|
1217
|
+
if (cancelled(typed)) return done();
|
|
1218
|
+
inputPath = String(typed);
|
|
1219
|
+
} else {
|
|
1220
|
+
inputPath = String(choice);
|
|
1221
|
+
}
|
|
1222
|
+
} else {
|
|
1223
|
+
const typed = await he({
|
|
1224
|
+
message: "Which folder, glob, or file should domflax optimize?",
|
|
1225
|
+
placeholder: "src",
|
|
1226
|
+
defaultValue: "src"
|
|
1227
|
+
});
|
|
1228
|
+
if (cancelled(typed)) return done();
|
|
1229
|
+
inputPath = String(typed);
|
|
1230
|
+
}
|
|
1114
1231
|
const outputMode = await ve({
|
|
1115
1232
|
message: "Where should the optimized files go?",
|
|
1116
1233
|
options: [
|
|
@@ -1138,15 +1255,6 @@ async function runWizard(base) {
|
|
|
1138
1255
|
} else if (outputMode === "overwrite") {
|
|
1139
1256
|
dangerouslyOverwriteSource = true;
|
|
1140
1257
|
}
|
|
1141
|
-
const allPasses = builtinPatternNames();
|
|
1142
|
-
const passSelection = await fe({
|
|
1143
|
-
message: "Which optimization passes should run?",
|
|
1144
|
-
options: allPasses.map((name) => ({ value: name, label: name })),
|
|
1145
|
-
initialValues: [...allPasses],
|
|
1146
|
-
required: true
|
|
1147
|
-
});
|
|
1148
|
-
if (cancelled(passSelection)) return done();
|
|
1149
|
-
const passes = passSelection;
|
|
1150
1258
|
const provider = await ve({
|
|
1151
1259
|
message: "How should class names resolve to styles?",
|
|
1152
1260
|
options: [
|
|
@@ -1159,23 +1267,35 @@ async function runWizard(base) {
|
|
|
1159
1267
|
if (cancelled(provider)) return done();
|
|
1160
1268
|
let css = base.css;
|
|
1161
1269
|
if (provider === "custom") {
|
|
1162
|
-
const
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1270
|
+
const detectedCss = detectCssFiles(root, [inputPath]);
|
|
1271
|
+
if (detectedCss.length > 0) {
|
|
1272
|
+
const picked = await fe({
|
|
1273
|
+
message: "Which CSS files should resolve your classes? (all detected files are pre-selected)",
|
|
1274
|
+
options: detectedCss.map((file) => ({ value: file, label: file })),
|
|
1275
|
+
initialValues: [...detectedCss],
|
|
1276
|
+
required: false
|
|
1277
|
+
});
|
|
1278
|
+
if (cancelled(picked)) return done();
|
|
1279
|
+
css = picked;
|
|
1280
|
+
} else {
|
|
1281
|
+
const cssInput = await he({
|
|
1282
|
+
message: "CSS files (space-separated):",
|
|
1283
|
+
placeholder: "src/styles.css"
|
|
1284
|
+
});
|
|
1285
|
+
if (cancelled(cssInput)) return done();
|
|
1286
|
+
css = String(cssInput).split(/\s+/).filter((s) => s.length > 0);
|
|
1287
|
+
}
|
|
1168
1288
|
}
|
|
1169
1289
|
Se("Ready \u2014 running domflax.");
|
|
1170
1290
|
return {
|
|
1171
1291
|
...base,
|
|
1172
|
-
paths: [
|
|
1292
|
+
paths: [inputPath],
|
|
1173
1293
|
out,
|
|
1174
1294
|
provider,
|
|
1175
1295
|
css,
|
|
1176
1296
|
dryRun,
|
|
1177
1297
|
dangerouslyOverwriteSource,
|
|
1178
|
-
passes:
|
|
1298
|
+
passes: null,
|
|
1179
1299
|
safety: base.safety ?? DEFAULT_SAFETY
|
|
1180
1300
|
};
|
|
1181
1301
|
function done() {
|
|
@@ -1201,11 +1321,11 @@ function printReport(totals) {
|
|
|
1201
1321
|
console.log(` classes saved : ${totals.classesSaved}`);
|
|
1202
1322
|
console.log(` bytes saved : ${totals.bytesSaved}`);
|
|
1203
1323
|
}
|
|
1204
|
-
function execute(options) {
|
|
1324
|
+
async function execute(options) {
|
|
1205
1325
|
const { files, inputRoot, warnings } = discoverInputs(options.paths);
|
|
1206
1326
|
for (const w2 of warnings) console.error(`domflax: ${w2}`);
|
|
1207
1327
|
if (files.length === 0) {
|
|
1208
|
-
console.error("domflax: no .jsx/.tsx
|
|
1328
|
+
console.error("domflax: no .jsx/.tsx files found for the given paths");
|
|
1209
1329
|
return { exitCode: 1 };
|
|
1210
1330
|
}
|
|
1211
1331
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
@@ -1231,7 +1351,7 @@ function execute(options) {
|
|
|
1231
1351
|
const result = transform.transformFile(code, file);
|
|
1232
1352
|
addStats(totals, result.stats, result.changed);
|
|
1233
1353
|
if (options.dryRun) {
|
|
1234
|
-
const rel =
|
|
1354
|
+
const rel = path4.relative(inputRoot, file) || path4.basename(file);
|
|
1235
1355
|
if (result.changed) console.log(unifiedDiff(code, result.code, rel));
|
|
1236
1356
|
else if (!options.report) console.log(` (unchanged) ${rel}`);
|
|
1237
1357
|
continue;
|
|
@@ -1244,16 +1364,28 @@ function execute(options) {
|
|
|
1244
1364
|
continue;
|
|
1245
1365
|
}
|
|
1246
1366
|
try {
|
|
1247
|
-
mkdirSync(
|
|
1367
|
+
mkdirSync(path4.dirname(target.value), { recursive: true });
|
|
1248
1368
|
writeFileSync(target.value, result.code, "utf8");
|
|
1249
|
-
console.log(`domflax: wrote ${
|
|
1369
|
+
console.log(`domflax: wrote ${path4.relative(process.cwd(), target.value) || target.value}`);
|
|
1250
1370
|
} catch (err) {
|
|
1251
1371
|
console.error(`domflax: cannot write ${target.value}: ${String(err?.message ?? err)}`);
|
|
1252
1372
|
failures += 1;
|
|
1253
1373
|
}
|
|
1254
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
|
+
}
|
|
1255
1388
|
if (options.report) printReport(totals);
|
|
1256
|
-
if (options.dryRun) console.log("\ndomflax: dry run \u2014 no files were written.");
|
|
1257
1389
|
return { exitCode: failures > 0 ? 1 : 0 };
|
|
1258
1390
|
}
|
|
1259
1391
|
async function main(argv = process.argv.slice(2)) {
|
|
@@ -1283,27 +1415,13 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
1283
1415
|
return;
|
|
1284
1416
|
}
|
|
1285
1417
|
try {
|
|
1286
|
-
const result = execute(options);
|
|
1418
|
+
const result = await execute(options);
|
|
1287
1419
|
process.exitCode = result.exitCode;
|
|
1288
1420
|
} catch (err) {
|
|
1289
1421
|
console.error(`domflax: ${err instanceof Error ? err.message : String(err)}`);
|
|
1290
1422
|
process.exitCode = 1;
|
|
1291
1423
|
}
|
|
1292
1424
|
}
|
|
1293
|
-
function isMainEntry() {
|
|
1294
|
-
const entry = process.argv[1];
|
|
1295
|
-
if (entry === void 0) return false;
|
|
1296
|
-
try {
|
|
1297
|
-
const self = path3.resolve(fileURLToPath(import.meta.url));
|
|
1298
|
-
const argv = path3.resolve(entry);
|
|
1299
|
-
return process.platform === "win32" ? self.toLowerCase() === argv.toLowerCase() : self === argv;
|
|
1300
|
-
} catch {
|
|
1301
|
-
return false;
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
if (isMainEntry()) {
|
|
1305
|
-
void main();
|
|
1306
|
-
}
|
|
1307
1425
|
|
|
1308
1426
|
// src/cli.ts
|
|
1309
1427
|
main(process.argv.slice(2));
|