domflax 0.1.0 → 0.1.1
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 +2169 -760
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +183 -91
- 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,66 +357,68 @@ 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
|
}
|
|
@@ -1098,19 +1099,112 @@ ${import_picocolors2.default.gray(d2)} ${t}
|
|
|
1098
1099
|
};
|
|
1099
1100
|
var J2 = `${import_picocolors2.default.gray(o)} `;
|
|
1100
1101
|
|
|
1102
|
+
// ../cli/src/detect.ts
|
|
1103
|
+
init_esm_shims();
|
|
1104
|
+
import * as fs2 from "fs";
|
|
1105
|
+
import * as path3 from "path";
|
|
1106
|
+
var SKIP_DIRS2 = /* @__PURE__ */ new Set([
|
|
1107
|
+
"node_modules",
|
|
1108
|
+
"dist",
|
|
1109
|
+
"build",
|
|
1110
|
+
".next",
|
|
1111
|
+
"out",
|
|
1112
|
+
"coverage",
|
|
1113
|
+
".git",
|
|
1114
|
+
"domflax-out"
|
|
1115
|
+
]);
|
|
1116
|
+
var COMMON_INPUT_DIRS = ["src", "app", "components", "pages", "lib", "ui", "public"];
|
|
1117
|
+
var CSS_FILE_CAP = 200;
|
|
1118
|
+
function toRelative(root, abs) {
|
|
1119
|
+
const rel = path3.relative(root, abs);
|
|
1120
|
+
return rel.split(path3.sep).join("/");
|
|
1121
|
+
}
|
|
1122
|
+
function detectCssFiles(root) {
|
|
1123
|
+
const found = [];
|
|
1124
|
+
let capped = false;
|
|
1125
|
+
const walk = (dir) => {
|
|
1126
|
+
if (capped) return;
|
|
1127
|
+
let entries;
|
|
1128
|
+
try {
|
|
1129
|
+
entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
1130
|
+
} catch {
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
for (const entry of entries) {
|
|
1134
|
+
const full = path3.join(dir, entry.name);
|
|
1135
|
+
if (entry.isDirectory()) {
|
|
1136
|
+
if (SKIP_DIRS2.has(entry.name)) continue;
|
|
1137
|
+
walk(full);
|
|
1138
|
+
if (capped) return;
|
|
1139
|
+
} 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;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
};
|
|
1148
|
+
walk(path3.resolve(root));
|
|
1149
|
+
found.sort((a, b3) => a.localeCompare(b3));
|
|
1150
|
+
if (capped) {
|
|
1151
|
+
console.error(`domflax: more than ${CSS_FILE_CAP} CSS files found; showing the first ${CSS_FILE_CAP}.`);
|
|
1152
|
+
}
|
|
1153
|
+
return found;
|
|
1154
|
+
}
|
|
1155
|
+
function detectInputDirs(root) {
|
|
1156
|
+
const resolved = path3.resolve(root);
|
|
1157
|
+
return COMMON_INPUT_DIRS.filter((name) => {
|
|
1158
|
+
try {
|
|
1159
|
+
return fs2.statSync(path3.join(resolved, name)).isDirectory();
|
|
1160
|
+
} catch {
|
|
1161
|
+
return false;
|
|
1162
|
+
}
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1101
1166
|
// ../cli/src/wizard.ts
|
|
1167
|
+
var OTHER_INPUT = "\0domflax.other";
|
|
1102
1168
|
var WIZARD_CANCELLED = /* @__PURE__ */ Symbol("domflax.wizard.cancelled");
|
|
1103
1169
|
function cancelled(value) {
|
|
1104
1170
|
return pD(value);
|
|
1105
1171
|
}
|
|
1106
1172
|
async function runWizard(base) {
|
|
1107
1173
|
Ie("domflax \u2014 optimize your markup");
|
|
1108
|
-
const
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1174
|
+
const root = base.projectRoot ?? process.cwd();
|
|
1175
|
+
const detectedInputs = detectInputDirs(root);
|
|
1176
|
+
let inputPath;
|
|
1177
|
+
if (detectedInputs.length > 0) {
|
|
1178
|
+
const defaultInput = detectedInputs.includes("src") ? "src" : detectedInputs[0];
|
|
1179
|
+
const choice = await ve({
|
|
1180
|
+
message: "Which folder should domflax optimize?",
|
|
1181
|
+
options: [
|
|
1182
|
+
...detectedInputs.map((dir) => ({ value: dir, label: dir, hint: "detected" })),
|
|
1183
|
+
{ value: OTHER_INPUT, label: "Other (type a path)\u2026" }
|
|
1184
|
+
],
|
|
1185
|
+
initialValue: defaultInput
|
|
1186
|
+
});
|
|
1187
|
+
if (cancelled(choice)) return done();
|
|
1188
|
+
if (choice === OTHER_INPUT) {
|
|
1189
|
+
const typed = await he({
|
|
1190
|
+
message: "Which folder, glob, or file should domflax optimize?",
|
|
1191
|
+
placeholder: "src",
|
|
1192
|
+
defaultValue: "src"
|
|
1193
|
+
});
|
|
1194
|
+
if (cancelled(typed)) return done();
|
|
1195
|
+
inputPath = String(typed);
|
|
1196
|
+
} else {
|
|
1197
|
+
inputPath = String(choice);
|
|
1198
|
+
}
|
|
1199
|
+
} else {
|
|
1200
|
+
const typed = await he({
|
|
1201
|
+
message: "Which folder, glob, or file should domflax optimize?",
|
|
1202
|
+
placeholder: "src",
|
|
1203
|
+
defaultValue: "src"
|
|
1204
|
+
});
|
|
1205
|
+
if (cancelled(typed)) return done();
|
|
1206
|
+
inputPath = String(typed);
|
|
1207
|
+
}
|
|
1114
1208
|
const outputMode = await ve({
|
|
1115
1209
|
message: "Where should the optimized files go?",
|
|
1116
1210
|
options: [
|
|
@@ -1159,17 +1253,29 @@ async function runWizard(base) {
|
|
|
1159
1253
|
if (cancelled(provider)) return done();
|
|
1160
1254
|
let css = base.css;
|
|
1161
1255
|
if (provider === "custom") {
|
|
1162
|
-
const
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1256
|
+
const detectedCss = detectCssFiles(root);
|
|
1257
|
+
if (detectedCss.length > 0) {
|
|
1258
|
+
const picked = await fe({
|
|
1259
|
+
message: "Which CSS files should resolve your classes? (all detected files are pre-selected)",
|
|
1260
|
+
options: detectedCss.map((file) => ({ value: file, label: file })),
|
|
1261
|
+
initialValues: [...detectedCss],
|
|
1262
|
+
required: false
|
|
1263
|
+
});
|
|
1264
|
+
if (cancelled(picked)) return done();
|
|
1265
|
+
css = picked;
|
|
1266
|
+
} else {
|
|
1267
|
+
const cssInput = await he({
|
|
1268
|
+
message: "CSS files (space-separated):",
|
|
1269
|
+
placeholder: "src/styles.css"
|
|
1270
|
+
});
|
|
1271
|
+
if (cancelled(cssInput)) return done();
|
|
1272
|
+
css = String(cssInput).split(/\s+/).filter((s) => s.length > 0);
|
|
1273
|
+
}
|
|
1168
1274
|
}
|
|
1169
1275
|
Se("Ready \u2014 running domflax.");
|
|
1170
1276
|
return {
|
|
1171
1277
|
...base,
|
|
1172
|
-
paths: [
|
|
1278
|
+
paths: [inputPath],
|
|
1173
1279
|
out,
|
|
1174
1280
|
provider,
|
|
1175
1281
|
css,
|
|
@@ -1201,7 +1307,7 @@ function printReport(totals) {
|
|
|
1201
1307
|
console.log(` classes saved : ${totals.classesSaved}`);
|
|
1202
1308
|
console.log(` bytes saved : ${totals.bytesSaved}`);
|
|
1203
1309
|
}
|
|
1204
|
-
function execute(options) {
|
|
1310
|
+
async function execute(options) {
|
|
1205
1311
|
const { files, inputRoot, warnings } = discoverInputs(options.paths);
|
|
1206
1312
|
for (const w2 of warnings) console.error(`domflax: ${w2}`);
|
|
1207
1313
|
if (files.length === 0) {
|
|
@@ -1231,7 +1337,7 @@ function execute(options) {
|
|
|
1231
1337
|
const result = transform.transformFile(code, file);
|
|
1232
1338
|
addStats(totals, result.stats, result.changed);
|
|
1233
1339
|
if (options.dryRun) {
|
|
1234
|
-
const rel =
|
|
1340
|
+
const rel = path4.relative(inputRoot, file) || path4.basename(file);
|
|
1235
1341
|
if (result.changed) console.log(unifiedDiff(code, result.code, rel));
|
|
1236
1342
|
else if (!options.report) console.log(` (unchanged) ${rel}`);
|
|
1237
1343
|
continue;
|
|
@@ -1244,9 +1350,9 @@ function execute(options) {
|
|
|
1244
1350
|
continue;
|
|
1245
1351
|
}
|
|
1246
1352
|
try {
|
|
1247
|
-
mkdirSync(
|
|
1353
|
+
mkdirSync(path4.dirname(target.value), { recursive: true });
|
|
1248
1354
|
writeFileSync(target.value, result.code, "utf8");
|
|
1249
|
-
console.log(`domflax: wrote ${
|
|
1355
|
+
console.log(`domflax: wrote ${path4.relative(process.cwd(), target.value) || target.value}`);
|
|
1250
1356
|
} catch (err) {
|
|
1251
1357
|
console.error(`domflax: cannot write ${target.value}: ${String(err?.message ?? err)}`);
|
|
1252
1358
|
failures += 1;
|
|
@@ -1283,27 +1389,13 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
1283
1389
|
return;
|
|
1284
1390
|
}
|
|
1285
1391
|
try {
|
|
1286
|
-
const result = execute(options);
|
|
1392
|
+
const result = await execute(options);
|
|
1287
1393
|
process.exitCode = result.exitCode;
|
|
1288
1394
|
} catch (err) {
|
|
1289
1395
|
console.error(`domflax: ${err instanceof Error ? err.message : String(err)}`);
|
|
1290
1396
|
process.exitCode = 1;
|
|
1291
1397
|
}
|
|
1292
1398
|
}
|
|
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
1399
|
|
|
1308
1400
|
// src/cli.ts
|
|
1309
1401
|
main(process.argv.slice(2));
|