css-is-awesome 1.16.0 → 1.16.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/AGENTS.md +3 -3
- package/CHANGELOG.md +25 -123
- package/CONTRACT.md +1 -0
- package/MIGRATION.md +148 -0
- package/README.md +6 -4
- package/VERSIONING.md +4 -0
- package/dist/tokens.d.ts +2 -4
- package/llm.txt +2 -2
- package/package.json +11 -3
- package/scripts/theme-contract.json +3 -3
- package/scripts/theme-validator.js +28 -2
- package/ROADMAP.md +0 -717
|
@@ -334,7 +334,15 @@ function validateTokenSet(declared, contract) {
|
|
|
334
334
|
for (const required of contract.required) {
|
|
335
335
|
if (!declared.has(required)) missing.push(required);
|
|
336
336
|
}
|
|
337
|
-
|
|
337
|
+
// Optional tokens (contract 1.1+) are reported as INFO, never as failures:
|
|
338
|
+
// the library or the theme generator supplies a default for each of them.
|
|
339
|
+
// `--space-unit` is the canonical case — it was wrongly listed as required
|
|
340
|
+
// in 1.12.0–1.16.0 and broke every consumer's custom theme on a MINOR.
|
|
341
|
+
const optionalMissing = [];
|
|
342
|
+
for (const optional of Array.isArray(contract.optional) ? contract.optional : []) {
|
|
343
|
+
if (!declared.has(optional)) optionalMissing.push(optional);
|
|
344
|
+
}
|
|
345
|
+
return { ok: missing.length === 0, missing, optionalMissing, declaredCount: declared.size };
|
|
338
346
|
}
|
|
339
347
|
|
|
340
348
|
// -----------------------------------------------------------
|
|
@@ -358,6 +366,7 @@ function validateText(text, contract, options) {
|
|
|
358
366
|
ok: false,
|
|
359
367
|
declaredCount: 0,
|
|
360
368
|
missing: [],
|
|
369
|
+
optionalMissing: [],
|
|
361
370
|
themes: null,
|
|
362
371
|
a11y: null,
|
|
363
372
|
error: null,
|
|
@@ -379,6 +388,7 @@ function validateText(text, contract, options) {
|
|
|
379
388
|
ok: v.ok,
|
|
380
389
|
declaredCount: v.declaredCount,
|
|
381
390
|
missing: v.missing,
|
|
391
|
+
optionalMissing: v.optionalMissing,
|
|
382
392
|
a11y: null,
|
|
383
393
|
};
|
|
384
394
|
if (wantA11y) theme.a11y = a11y.auditThemeTokens({ name: b.name, values: b.values });
|
|
@@ -406,6 +416,7 @@ function validateText(text, contract, options) {
|
|
|
406
416
|
const v = validateTokenSet(root.tokens, contract);
|
|
407
417
|
result.declaredCount = v.declaredCount;
|
|
408
418
|
result.missing = v.missing;
|
|
419
|
+
result.optionalMissing = v.optionalMissing;
|
|
409
420
|
result.ok = v.ok;
|
|
410
421
|
if (wantA11y) {
|
|
411
422
|
const inferredName = label !== '(pasted CSS)' ? (path.basename(path.dirname(label)) || path.basename(label, '.css')) : 'theme';
|
|
@@ -443,6 +454,15 @@ function relForDisplay(p) {
|
|
|
443
454
|
return rel || p;
|
|
444
455
|
}
|
|
445
456
|
|
|
457
|
+
// Optional tokens a theme leaves to the library default. Info only — shown as
|
|
458
|
+
// a count, or listed with --show-optional. Never affects the exit code.
|
|
459
|
+
function optionalInfo(optionalMissing, indent) {
|
|
460
|
+
const list = Array.isArray(optionalMissing) ? optionalMissing : [];
|
|
461
|
+
if (!list.length) return;
|
|
462
|
+
console.log(`${indent}${dim(`i ${list.length} optional token(s) not declared — library default applies`)}`);
|
|
463
|
+
if (SHOW_OPTIONAL) for (const token of list) console.log(`${indent} ${dim(token)}`);
|
|
464
|
+
}
|
|
465
|
+
|
|
446
466
|
function reportResult(result) {
|
|
447
467
|
const rel = relForDisplay(result.file);
|
|
448
468
|
|
|
@@ -463,6 +483,7 @@ function reportResult(result) {
|
|
|
463
483
|
console.log(
|
|
464
484
|
` ${green('✓')} [data-theme="${t.name}"] ${dim(`(${t.declaredCount} tokens)`)}`
|
|
465
485
|
);
|
|
486
|
+
optionalInfo(t.optionalMissing, ' ');
|
|
466
487
|
} else {
|
|
467
488
|
const n = t.missing.length;
|
|
468
489
|
console.log(
|
|
@@ -481,6 +502,7 @@ function reportResult(result) {
|
|
|
481
502
|
console.log(
|
|
482
503
|
`${green('✓')} ${bold(rel)} ${dim(`passes (${result.declaredCount} tokens declared)`)}`
|
|
483
504
|
);
|
|
505
|
+
optionalInfo(result.optionalMissing, ' ');
|
|
484
506
|
return;
|
|
485
507
|
}
|
|
486
508
|
|
|
@@ -561,6 +583,7 @@ function printUsage() {
|
|
|
561
583
|
' --all validate every theme.css under public/ (CI mode)',
|
|
562
584
|
' --no-a11y skip the WCAG 2.2 AA contrast audit',
|
|
563
585
|
' --allow-a11y-fail do NOT exit non-zero on a11y FAILs (report only)',
|
|
586
|
+
' --show-optional list optional contract tokens a theme leaves to the library default (info only)',
|
|
564
587
|
' --strict accepted for backwards compatibility (no-op; FAIL is now the default)',
|
|
565
588
|
'',
|
|
566
589
|
'Exit codes:',
|
|
@@ -573,8 +596,11 @@ function printUsage() {
|
|
|
573
596
|
console.log(u);
|
|
574
597
|
}
|
|
575
598
|
|
|
599
|
+
let SHOW_OPTIONAL = false;
|
|
600
|
+
|
|
576
601
|
function main(argv) {
|
|
577
602
|
const argsRaw = argv.slice(2).filter(function (a) { return a !== '--watch'; });
|
|
603
|
+
SHOW_OPTIONAL = argsRaw.includes('--show-optional');
|
|
578
604
|
if (argsRaw.length === 0 || argsRaw.includes('-h') || argsRaw.includes('--help')) {
|
|
579
605
|
printUsage();
|
|
580
606
|
process.exit(argsRaw.length === 0 ? 2 : 0);
|
|
@@ -583,7 +609,7 @@ function main(argv) {
|
|
|
583
609
|
const wantLenient = argsRaw.includes('--allow-a11y-fail');
|
|
584
610
|
// --strict is accepted as a no-op for backwards compatibility — a11y FAIL is now the default
|
|
585
611
|
const args = argsRaw.filter(function (a) {
|
|
586
|
-
return a !== '--no-a11y' && a !== '--strict' && a !== '--allow-a11y-fail';
|
|
612
|
+
return a !== '--no-a11y' && a !== '--strict' && a !== '--allow-a11y-fail' && a !== '--show-optional';
|
|
587
613
|
});
|
|
588
614
|
|
|
589
615
|
const contract = loadContract();
|