synthesisui 0.10.0 → 0.10.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/dist/commands/doctor.js +8 -3
- package/dist/doctor/scan.js +33 -5
- package/package.json +1 -1
package/dist/commands/doctor.js
CHANGED
|
@@ -401,7 +401,10 @@ export async function doctor(opts) {
|
|
|
401
401
|
}
|
|
402
402
|
return false;
|
|
403
403
|
};
|
|
404
|
-
|
|
404
|
+
// Three acts, not two. `transform: none` does not leave the system - it
|
|
405
|
+
// REMOVES what the recipe sets, and no token can hold "no transform".
|
|
406
|
+
// Marking it as a raw value asked for something that cannot exist.
|
|
407
|
+
const offSystem = drifting.filter((o) => !onSystem(o) && !isReset(o.wrote)).length;
|
|
405
408
|
console.log(section("Overruled"));
|
|
406
409
|
console.log(body(`${drifting.length} place${drifting.length === 1 ? "" : "s"} where the code takes a component`));
|
|
407
410
|
console.log(body("the system defines, and then overrules it locally."));
|
|
@@ -434,8 +437,10 @@ export async function doctor(opts) {
|
|
|
434
437
|
console.log(` the recipe binds ${o.recipe}`);
|
|
435
438
|
else if (o.where)
|
|
436
439
|
console.log(` the recipe binds it ${o.where}`);
|
|
437
|
-
if (
|
|
438
|
-
console.log(
|
|
440
|
+
if (lawKept(o) === null && !onSystem(o)) {
|
|
441
|
+
console.log(isReset(o.wrote)
|
|
442
|
+
? " ↑ removes it rather than replacing it"
|
|
443
|
+
: " ↑ a raw value, not a token");
|
|
439
444
|
}
|
|
440
445
|
const kept = lawKept(o);
|
|
441
446
|
if (kept) {
|
package/dist/doctor/scan.js
CHANGED
|
@@ -40,6 +40,21 @@ const SPACING = /(?:\b[pmg](?:[trblxy])?-\[|gap-\[|(?:padding|margin|gap)\s*:\s*
|
|
|
40
40
|
const FONT = /font-family\s*:\s*([^;}\n]+)/g;
|
|
41
41
|
/** Uses of the system. Coverage is meaningless without them. */
|
|
42
42
|
const TOKEN_USE = /var\(\s*--ds-[a-z0-9-]+/gi;
|
|
43
|
+
/**
|
|
44
|
+
* `var(--ds-color-semantic-primary, #5266eb)` - the literal is the TOKEN'S OWN
|
|
45
|
+
* fallback, written for safety, and reporting it as drift told an author to
|
|
46
|
+
* tokenize something they had already tokenized (investidorez, 25/07). The
|
|
47
|
+
* spans below are the fallback arguments on a line.
|
|
48
|
+
*/
|
|
49
|
+
const VAR_FALLBACK = /var\(\s*--ds-[a-z0-9-]+\s*,([^()]*)\)/gi;
|
|
50
|
+
function fallbackSpans(line) {
|
|
51
|
+
const out = [];
|
|
52
|
+
for (const m of line.matchAll(VAR_FALLBACK)) {
|
|
53
|
+
const start = (m.index ?? 0) + m[0].indexOf(",") + 1;
|
|
54
|
+
out.push([start, start + m[1].length]);
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
43
58
|
/** Under this, a radius or spacing value is idiom rather than a decision. */
|
|
44
59
|
const IDIOM = new Set(["0", "0px", "1px", "9999px", "100%", "50%"]);
|
|
45
60
|
export function scanSource(file, source, table) {
|
|
@@ -77,10 +92,18 @@ export function scanSource(file, source, table) {
|
|
|
77
92
|
// written by hand - flagging it would be telling someone to tokenize a
|
|
78
93
|
// variable. And the same literal twice in one declaration (a two-stop
|
|
79
94
|
// shadow) is one decision, so it is reported once.
|
|
95
|
+
const spans = fallbackSpans(line);
|
|
96
|
+
const inFallback = (at) => spans.some(([a, b]) => at >= a && at <= b);
|
|
80
97
|
const seen = new Set();
|
|
81
|
-
|
|
98
|
+
// NOT named `at`: that is the line number in this scope, and shadowing it
|
|
99
|
+
// put column positions into the report as line numbers.
|
|
100
|
+
const push = (kind, literal, col = -1) => {
|
|
82
101
|
if (literal.includes("$") || literal.includes("{"))
|
|
83
102
|
return;
|
|
103
|
+
if (col >= 0 && inFallback(col)) {
|
|
104
|
+
aside++;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
84
107
|
const key = `${kind}:${literal}`;
|
|
85
108
|
if (seen.has(key))
|
|
86
109
|
return;
|
|
@@ -103,17 +126,17 @@ export function scanSource(file, source, table) {
|
|
|
103
126
|
aside++;
|
|
104
127
|
continue;
|
|
105
128
|
}
|
|
106
|
-
push("color", m[0]);
|
|
129
|
+
push("color", m[0], m.index ?? -1);
|
|
107
130
|
}
|
|
108
131
|
for (const m of line.matchAll(RADIUS)) {
|
|
109
132
|
const value = `${m[1]}${m[2]}`;
|
|
110
133
|
if (!IDIOM.has(value))
|
|
111
|
-
push("radius", value);
|
|
134
|
+
push("radius", value, m.index ?? -1);
|
|
112
135
|
}
|
|
113
136
|
for (const m of line.matchAll(SPACING)) {
|
|
114
137
|
const value = `${m[1]}${m[2]}`;
|
|
115
138
|
if (!IDIOM.has(value))
|
|
116
|
-
push("spacing", value);
|
|
139
|
+
push("spacing", value, m.index ?? -1);
|
|
117
140
|
}
|
|
118
141
|
for (const m of line.matchAll(FONT)) {
|
|
119
142
|
const stack = m[1].trim();
|
|
@@ -128,7 +151,12 @@ export function scanSource(file, source, table) {
|
|
|
128
151
|
findings,
|
|
129
152
|
tokenUses,
|
|
130
153
|
...(aside > 0
|
|
131
|
-
? {
|
|
154
|
+
? {
|
|
155
|
+
setAside: {
|
|
156
|
+
reason: "SVG artwork or a token's own fallback",
|
|
157
|
+
count: aside,
|
|
158
|
+
},
|
|
159
|
+
}
|
|
132
160
|
: null),
|
|
133
161
|
};
|
|
134
162
|
}
|
package/package.json
CHANGED