@terrazzo/parser 2.0.0-beta.0 → 2.0.0-beta.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/CHANGELOG.md +5 -1
- package/dist/index.d.ts +10 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +827 -869
- package/dist/index.js.map +1 -1
- package/package.json +3 -4
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@ import wcmatch from "wildcard-match";
|
|
|
2
2
|
import * as momoa from "@humanwhocodes/momoa";
|
|
3
3
|
import pc from "picocolors";
|
|
4
4
|
import { merge } from "merge-anything";
|
|
5
|
-
import { BORDER_REQUIRED_PROPERTIES,
|
|
6
|
-
import {
|
|
5
|
+
import { BORDER_REQUIRED_PROPERTIES, COLOR_SPACE, FONT_WEIGHTS, GRADIENT_REQUIRED_STOP_PROPERTIES, SHADOW_REQUIRED_PROPERTIES, STROKE_STYLE_LINE_CAP_VALUES, STROKE_STYLE_OBJECT_REQUIRED_PROPERTIES, STROKE_STYLE_STRING_VALUES, TRANSITION_REQUIRED_PROPERTIES, isAlias, parseAlias, parseColor, pluralize, tokenToColor } from "@terrazzo/token-tools";
|
|
6
|
+
import { contrastWCAG21, inGamut } from "colorjs.io/fn";
|
|
7
7
|
import { camelCase, kebabCase, pascalCase, snakeCase } from "scule";
|
|
8
8
|
import { bundle, encodeFragment, findNode, getObjMember, getObjMembers, isPure$ref, maybeRawJSON, mergeObjects, parseRef, replaceNode, traverse } from "@terrazzo/json-schema-tools";
|
|
9
9
|
|
|
@@ -236,7 +236,7 @@ async function build(tokens, { resolver, sources, logger = new Logger(), config
|
|
|
236
236
|
const formats = {};
|
|
237
237
|
const result = { outputFiles: [] };
|
|
238
238
|
function getTransforms(plugin) {
|
|
239
|
-
return function getTransforms
|
|
239
|
+
return function getTransforms(params) {
|
|
240
240
|
if (!params?.format) {
|
|
241
241
|
logger.warn({
|
|
242
242
|
group: "plugin",
|
|
@@ -408,7 +408,7 @@ const rule$26 = {
|
|
|
408
408
|
if (tokens[foreground].$type !== "color") throw new Error(`Token ${foreground} isn’t a color`);
|
|
409
409
|
if (!tokens[background]) throw new Error(`Token ${background} does not exist`);
|
|
410
410
|
if (tokens[background].$type !== "color") throw new Error(`Token ${background} isn’t a color`);
|
|
411
|
-
const contrast =
|
|
411
|
+
const contrast = contrastWCAG21(tokenToColor(tokens[foreground].$value), tokenToColor(tokens[background].$value));
|
|
412
412
|
const min = WCAG2_MIN_CONTRAST[options.level ?? "AA"][largeText ? "large" : "default"];
|
|
413
413
|
if (contrast < min) report({
|
|
414
414
|
messageId: ERROR_INSUFFICIENT_CONTRAST,
|
|
@@ -422,7 +422,6 @@ const rule$26 = {
|
|
|
422
422
|
}
|
|
423
423
|
}
|
|
424
424
|
};
|
|
425
|
-
var a11y_min_contrast_default = rule$26;
|
|
426
425
|
|
|
427
426
|
//#endregion
|
|
428
427
|
//#region src/lint/plugin-core/rules/a11y-min-font-size.ts
|
|
@@ -456,11 +455,10 @@ const rule$25 = {
|
|
|
456
455
|
}
|
|
457
456
|
}
|
|
458
457
|
};
|
|
459
|
-
var a11y_min_font_size_default = rule$25;
|
|
460
458
|
|
|
461
459
|
//#endregion
|
|
462
460
|
//#region src/lint/plugin-core/rules/colorspace.ts
|
|
463
|
-
const COLORSPACE
|
|
461
|
+
const COLORSPACE = "core/colorspace";
|
|
464
462
|
const ERROR_COLOR$1 = "COLOR";
|
|
465
463
|
const ERROR_BORDER$1 = "BORDER";
|
|
466
464
|
const ERROR_GRADIENT$1 = "GRADIENT";
|
|
@@ -475,7 +473,7 @@ const rule$24 = {
|
|
|
475
473
|
},
|
|
476
474
|
docs: {
|
|
477
475
|
description: "Enforce that all colors are in a specific colorspace.",
|
|
478
|
-
url: docsLink(COLORSPACE
|
|
476
|
+
url: docsLink(COLORSPACE)
|
|
479
477
|
}
|
|
480
478
|
},
|
|
481
479
|
defaultOptions: { colorSpace: "srgb" },
|
|
@@ -534,7 +532,6 @@ const rule$24 = {
|
|
|
534
532
|
}
|
|
535
533
|
}
|
|
536
534
|
};
|
|
537
|
-
var colorspace_default = rule$24;
|
|
538
535
|
|
|
539
536
|
//#endregion
|
|
540
537
|
//#region src/lint/plugin-core/rules/consistent-naming.ts
|
|
@@ -578,7 +575,6 @@ const rule$23 = {
|
|
|
578
575
|
}
|
|
579
576
|
}
|
|
580
577
|
};
|
|
581
|
-
var consistent_naming_default = rule$23;
|
|
582
578
|
|
|
583
579
|
//#endregion
|
|
584
580
|
//#region src/lint/plugin-core/rules/descriptions.ts
|
|
@@ -605,7 +601,6 @@ const rule$22 = {
|
|
|
605
601
|
}
|
|
606
602
|
}
|
|
607
603
|
};
|
|
608
|
-
var descriptions_default = rule$22;
|
|
609
604
|
|
|
610
605
|
//#endregion
|
|
611
606
|
//#region src/lint/plugin-core/rules/duplicate-values.ts
|
|
@@ -650,32 +645,10 @@ const rule$21 = {
|
|
|
650
645
|
}
|
|
651
646
|
}
|
|
652
647
|
};
|
|
653
|
-
var duplicate_values_default = rule$21;
|
|
654
648
|
|
|
655
649
|
//#endregion
|
|
656
650
|
//#region src/lint/plugin-core/rules/max-gamut.ts
|
|
657
651
|
const MAX_GAMUT = "core/max-gamut";
|
|
658
|
-
const TOLERANCE = 1e-6;
|
|
659
|
-
/** is a Culori-parseable color within the specified gamut? */
|
|
660
|
-
function isWithinGamut(color, gamut) {
|
|
661
|
-
const parsed = tokenToCulori(color);
|
|
662
|
-
if (!parsed) return false;
|
|
663
|
-
if ([
|
|
664
|
-
"rgb",
|
|
665
|
-
"hsl",
|
|
666
|
-
"hwb"
|
|
667
|
-
].includes(parsed.mode)) return true;
|
|
668
|
-
return isWithinThreshold(parsed, clampChroma(parsed, parsed.mode, gamut === "srgb" ? "rgb" : gamut));
|
|
669
|
-
}
|
|
670
|
-
/** is Color A close enough to Color B? */
|
|
671
|
-
function isWithinThreshold(a, b, tolerance = TOLERANCE) {
|
|
672
|
-
for (const k in a) {
|
|
673
|
-
if (k === "mode" || k === "alpha") continue;
|
|
674
|
-
if (!(k in b)) throw new Error(`Can’t compare ${a.mode} to ${b.mode}`);
|
|
675
|
-
if (Math.abs(a[k] - b[k]) > tolerance) return false;
|
|
676
|
-
}
|
|
677
|
-
return true;
|
|
678
|
-
}
|
|
679
652
|
const ERROR_COLOR = "COLOR";
|
|
680
653
|
const ERROR_BORDER = "BORDER";
|
|
681
654
|
const ERROR_GRADIENT = "GRADIENT";
|
|
@@ -703,7 +676,7 @@ const rule$20 = {
|
|
|
703
676
|
if (t.aliasOf) continue;
|
|
704
677
|
switch (t.$type) {
|
|
705
678
|
case "color":
|
|
706
|
-
if (!
|
|
679
|
+
if (!inGamut(tokenToColor(t.$value), options.gamut)) report({
|
|
707
680
|
messageId: ERROR_COLOR,
|
|
708
681
|
data: {
|
|
709
682
|
id: t.id,
|
|
@@ -714,7 +687,7 @@ const rule$20 = {
|
|
|
714
687
|
});
|
|
715
688
|
break;
|
|
716
689
|
case "border":
|
|
717
|
-
if (!t.partialAliasOf?.color && !
|
|
690
|
+
if (!t.partialAliasOf?.color && !inGamut(tokenToColor(t.$value.color), options.gamut)) report({
|
|
718
691
|
messageId: ERROR_BORDER,
|
|
719
692
|
data: {
|
|
720
693
|
id: t.id,
|
|
@@ -725,7 +698,7 @@ const rule$20 = {
|
|
|
725
698
|
});
|
|
726
699
|
break;
|
|
727
700
|
case "gradient":
|
|
728
|
-
for (let stopI = 0; stopI < t.$value.length; stopI++) if (!t.partialAliasOf?.[stopI]?.color && !
|
|
701
|
+
for (let stopI = 0; stopI < t.$value.length; stopI++) if (!t.partialAliasOf?.[stopI]?.color && !inGamut(tokenToColor(t.$value[stopI].color), options.gamut)) report({
|
|
729
702
|
messageId: ERROR_GRADIENT,
|
|
730
703
|
data: {
|
|
731
704
|
id: t.id,
|
|
@@ -736,7 +709,7 @@ const rule$20 = {
|
|
|
736
709
|
});
|
|
737
710
|
break;
|
|
738
711
|
case "shadow":
|
|
739
|
-
for (let shadowI = 0; shadowI < t.$value.length; shadowI++) if (!t.partialAliasOf?.[shadowI]?.color && !
|
|
712
|
+
for (let shadowI = 0; shadowI < t.$value.length; shadowI++) if (!t.partialAliasOf?.[shadowI]?.color && !inGamut(tokenToColor(t.$value[shadowI].color), options.gamut)) report({
|
|
740
713
|
messageId: ERROR_SHADOW,
|
|
741
714
|
data: {
|
|
742
715
|
id: t.id,
|
|
@@ -750,7 +723,6 @@ const rule$20 = {
|
|
|
750
723
|
}
|
|
751
724
|
}
|
|
752
725
|
};
|
|
753
|
-
var max_gamut_default = rule$20;
|
|
754
726
|
|
|
755
727
|
//#endregion
|
|
756
728
|
//#region src/lint/plugin-core/rules/required-children.ts
|
|
@@ -816,7 +788,6 @@ const rule$19 = {
|
|
|
816
788
|
}
|
|
817
789
|
}
|
|
818
790
|
};
|
|
819
|
-
var required_children_default = rule$19;
|
|
820
791
|
|
|
821
792
|
//#endregion
|
|
822
793
|
//#region src/lint/plugin-core/rules/required-modes.ts
|
|
@@ -852,7 +823,6 @@ const rule$18 = {
|
|
|
852
823
|
}
|
|
853
824
|
}
|
|
854
825
|
};
|
|
855
|
-
var required_modes_default = rule$18;
|
|
856
826
|
|
|
857
827
|
//#endregion
|
|
858
828
|
//#region src/lint/plugin-core/rules/required-type.ts
|
|
@@ -875,7 +845,6 @@ const rule$17 = {
|
|
|
875
845
|
});
|
|
876
846
|
}
|
|
877
847
|
};
|
|
878
|
-
var required_type_default = rule$17;
|
|
879
848
|
|
|
880
849
|
//#endregion
|
|
881
850
|
//#region src/lint/plugin-core/rules/required-typography-properties.ts
|
|
@@ -909,265 +878,135 @@ const rule$16 = {
|
|
|
909
878
|
}
|
|
910
879
|
}
|
|
911
880
|
};
|
|
912
|
-
var required_typography_properties_default = rule$16;
|
|
913
881
|
|
|
914
882
|
//#endregion
|
|
915
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
916
|
-
const
|
|
883
|
+
//#region src/lint/plugin-core/rules/valid-font-family.ts
|
|
884
|
+
const VALID_FONT_FAMILY = "core/valid-font-family";
|
|
917
885
|
const ERROR$9 = "ERROR";
|
|
918
886
|
const rule$15 = {
|
|
919
887
|
meta: {
|
|
920
|
-
messages: { [ERROR$9]: "Must be a
|
|
888
|
+
messages: { [ERROR$9]: "Must be a string, or array of strings." },
|
|
921
889
|
docs: {
|
|
922
|
-
description: "Require
|
|
923
|
-
url: docsLink(
|
|
890
|
+
description: "Require fontFamily tokens to follow the format.",
|
|
891
|
+
url: docsLink(VALID_FONT_FAMILY)
|
|
924
892
|
}
|
|
925
893
|
},
|
|
926
894
|
defaultOptions: {},
|
|
927
895
|
create({ tokens, report }) {
|
|
928
896
|
for (const t of Object.values(tokens)) {
|
|
929
|
-
if (t.aliasOf || !t.originalValue
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
897
|
+
if (t.aliasOf || !t.originalValue) continue;
|
|
898
|
+
switch (t.$type) {
|
|
899
|
+
case "fontFamily":
|
|
900
|
+
validateFontFamily(t.originalValue.$value, {
|
|
901
|
+
node: getObjMember(t.source.node, "$value"),
|
|
902
|
+
filename: t.source.filename
|
|
903
|
+
});
|
|
904
|
+
break;
|
|
905
|
+
case "typography":
|
|
906
|
+
if (typeof t.originalValue.$value === "object" && t.originalValue.$value.fontFamily) {
|
|
907
|
+
if (t.partialAliasOf?.fontFamily) continue;
|
|
908
|
+
const properties = getObjMembers(getObjMember(t.source.node, "$value"));
|
|
909
|
+
validateFontFamily(t.originalValue.$value.fontFamily, {
|
|
910
|
+
node: properties.fontFamily,
|
|
911
|
+
filename: t.source.filename
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
break;
|
|
915
|
+
}
|
|
916
|
+
function validateFontFamily(value, { node, filename }) {
|
|
917
|
+
if (typeof value === "string") {
|
|
918
|
+
if (!value) report({
|
|
919
|
+
messageId: ERROR$9,
|
|
920
|
+
node,
|
|
921
|
+
filename
|
|
922
|
+
});
|
|
923
|
+
} else if (Array.isArray(value)) {
|
|
924
|
+
if (!value.every((v) => v && typeof v === "string")) report({
|
|
925
|
+
messageId: ERROR$9,
|
|
926
|
+
node,
|
|
927
|
+
filename
|
|
928
|
+
});
|
|
929
|
+
} else report({
|
|
936
930
|
messageId: ERROR$9,
|
|
937
|
-
|
|
938
|
-
|
|
931
|
+
node,
|
|
932
|
+
filename
|
|
939
933
|
});
|
|
940
934
|
}
|
|
941
935
|
}
|
|
942
936
|
}
|
|
943
937
|
};
|
|
944
|
-
var valid_boolean_default = rule$15;
|
|
945
938
|
|
|
946
939
|
//#endregion
|
|
947
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
948
|
-
const
|
|
940
|
+
//#region src/lint/plugin-core/rules/valid-font-weight.ts
|
|
941
|
+
const VALID_FONT_WEIGHT = "core/valid-font-weight";
|
|
949
942
|
const ERROR$8 = "ERROR";
|
|
950
|
-
const
|
|
943
|
+
const ERROR_STYLE = "ERROR_STYLE";
|
|
951
944
|
const rule$14 = {
|
|
952
945
|
meta: {
|
|
953
946
|
messages: {
|
|
954
|
-
[ERROR$8]: `
|
|
955
|
-
[
|
|
956
|
-
},
|
|
957
|
-
docs: {
|
|
958
|
-
description: "Require border tokens to follow the format.",
|
|
959
|
-
url: docsLink(VALID_BORDER)
|
|
960
|
-
}
|
|
961
|
-
},
|
|
962
|
-
defaultOptions: {},
|
|
963
|
-
create({ tokens, report }) {
|
|
964
|
-
for (const t of Object.values(tokens)) {
|
|
965
|
-
if (t.aliasOf || !t.originalValue || t.$type !== "border") continue;
|
|
966
|
-
validateBorder(t.originalValue.$value, {
|
|
967
|
-
node: getObjMember(t.source.node, "$value"),
|
|
968
|
-
filename: t.source.filename
|
|
969
|
-
});
|
|
970
|
-
}
|
|
971
|
-
function validateBorder(value, { node, filename }) {
|
|
972
|
-
if (!value || typeof value !== "object" || !BORDER_REQUIRED_PROPERTIES.every((property) => property in value)) report({
|
|
973
|
-
messageId: ERROR$8,
|
|
974
|
-
filename,
|
|
975
|
-
node
|
|
976
|
-
});
|
|
977
|
-
else for (const key of Object.keys(value)) if (!BORDER_REQUIRED_PROPERTIES.includes(key)) report({
|
|
978
|
-
messageId: ERROR_INVALID_PROP$7,
|
|
979
|
-
data: { key: JSON.stringify(key) },
|
|
980
|
-
node: getObjMember(node, key) ?? node,
|
|
981
|
-
filename
|
|
982
|
-
});
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
};
|
|
986
|
-
var valid_border_default = rule$14;
|
|
987
|
-
|
|
988
|
-
//#endregion
|
|
989
|
-
//#region src/lint/plugin-core/rules/valid-color.ts
|
|
990
|
-
const VALID_COLOR = "core/valid-color";
|
|
991
|
-
const ERROR_ALPHA = "ERROR_ALPHA";
|
|
992
|
-
const ERROR_INVALID_COLOR = "ERROR_INVALID_COLOR";
|
|
993
|
-
const ERROR_INVALID_COLOR_SPACE = "ERROR_INVALID_COLOR_SPACE";
|
|
994
|
-
const ERROR_INVALID_COMPONENT_LENGTH = "ERROR_INVALID_COMPONENT_LENGTH";
|
|
995
|
-
const ERROR_INVALID_HEX8 = "ERROR_INVALID_HEX8";
|
|
996
|
-
const ERROR_INVALID_PROP$6 = "ERROR_INVALID_PROP";
|
|
997
|
-
const ERROR_MISSING_COMPONENTS = "ERROR_MISSING_COMPONENTS";
|
|
998
|
-
const ERROR_OBJ_FORMAT = "ERROR_OBJ_FORMAT";
|
|
999
|
-
const ERROR_OUT_OF_RANGE = "ERROR_OUT_OF_RANGE";
|
|
1000
|
-
const rule$13 = {
|
|
1001
|
-
meta: {
|
|
1002
|
-
messages: {
|
|
1003
|
-
[ERROR_ALPHA]: `Alpha {{ alpha }} not in range 0 – 1.`,
|
|
1004
|
-
[ERROR_INVALID_COLOR_SPACE]: `Invalid color space: {{ colorSpace }}. Expected ${new Intl.ListFormat("en-us", { type: "disjunction" }).format(Object.keys(COLORSPACE))}`,
|
|
1005
|
-
[ERROR_INVALID_COLOR]: `Could not parse color {{ color }}.`,
|
|
1006
|
-
[ERROR_INVALID_COMPONENT_LENGTH]: "Expected {{ expected }} components, received {{ got }}.",
|
|
1007
|
-
[ERROR_INVALID_HEX8]: `Hex value can’t be semi-transparent.`,
|
|
1008
|
-
[ERROR_INVALID_PROP$6]: `Unknown property {{ key }}.`,
|
|
1009
|
-
[ERROR_MISSING_COMPONENTS]: "Expected components to be array of numbers, received {{ got }}.",
|
|
1010
|
-
[ERROR_OBJ_FORMAT]: "Migrate to the new object format, e.g. \"#ff0000\" → { \"colorSpace\": \"srgb\", \"components\": [1, 0, 0] } }",
|
|
1011
|
-
[ERROR_OUT_OF_RANGE]: `Invalid range for color space {{ colorSpace }}. Expected {{ range }}.`
|
|
947
|
+
[ERROR$8]: `Must either be a valid number (0 - 999) or a valid font weight: ${new Intl.ListFormat("en-us", { type: "disjunction" }).format(Object.keys(FONT_WEIGHTS))}.`,
|
|
948
|
+
[ERROR_STYLE]: "Expected style {{ style }}, received {{ value }}."
|
|
1012
949
|
},
|
|
1013
950
|
docs: {
|
|
1014
|
-
description: "Require
|
|
1015
|
-
url: docsLink(
|
|
951
|
+
description: "Require number tokens to follow the format.",
|
|
952
|
+
url: docsLink(VALID_FONT_WEIGHT)
|
|
1016
953
|
}
|
|
1017
954
|
},
|
|
1018
|
-
defaultOptions: {
|
|
1019
|
-
legacyFormat: false,
|
|
1020
|
-
ignoreRanges: false
|
|
1021
|
-
},
|
|
955
|
+
defaultOptions: { style: void 0 },
|
|
1022
956
|
create({ tokens, options, report }) {
|
|
1023
957
|
for (const t of Object.values(tokens)) {
|
|
1024
958
|
if (t.aliasOf || !t.originalValue) continue;
|
|
1025
959
|
switch (t.$type) {
|
|
1026
|
-
case "
|
|
1027
|
-
|
|
960
|
+
case "fontWeight":
|
|
961
|
+
validateFontWeight(t.originalValue.$value, {
|
|
1028
962
|
node: getObjMember(t.source.node, "$value"),
|
|
1029
963
|
filename: t.source.filename
|
|
1030
964
|
});
|
|
1031
965
|
break;
|
|
1032
|
-
case "
|
|
1033
|
-
if (t.originalValue.$value
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
case "gradient": {
|
|
1039
|
-
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1040
|
-
for (let i = 0; i < t.originalValue.$value.length; i++) {
|
|
1041
|
-
const stop = t.originalValue.$value[i];
|
|
1042
|
-
if (!stop.color || isAlias(stop.color)) continue;
|
|
1043
|
-
validateColor(stop.color, {
|
|
1044
|
-
node: getObjMember($valueNode.elements[i].value, "color"),
|
|
1045
|
-
filename: t.source.filename
|
|
1046
|
-
});
|
|
1047
|
-
}
|
|
1048
|
-
break;
|
|
1049
|
-
}
|
|
1050
|
-
case "shadow": {
|
|
1051
|
-
const $value = Array.isArray(t.originalValue.$value) ? t.originalValue.$value : [t.originalValue.$value];
|
|
1052
|
-
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1053
|
-
for (let i = 0; i < $value.length; i++) {
|
|
1054
|
-
const layer = $value[i];
|
|
1055
|
-
if (!layer.color || isAlias(layer.color)) continue;
|
|
1056
|
-
validateColor(layer.color, {
|
|
1057
|
-
node: $valueNode.type === "Object" ? getObjMember($valueNode, "color") : getObjMember($valueNode.elements[i].value, "color"),
|
|
966
|
+
case "typography":
|
|
967
|
+
if (typeof t.originalValue.$value === "object" && t.originalValue.$value.fontWeight) {
|
|
968
|
+
if (t.partialAliasOf?.fontWeight) continue;
|
|
969
|
+
const properties = getObjMembers(getObjMember(t.source.node, "$value"));
|
|
970
|
+
validateFontWeight(t.originalValue.$value.fontWeight, {
|
|
971
|
+
node: properties.fontWeight,
|
|
1058
972
|
filename: t.source.filename
|
|
1059
973
|
});
|
|
1060
974
|
}
|
|
1061
975
|
break;
|
|
1062
|
-
}
|
|
1063
976
|
}
|
|
1064
|
-
function
|
|
1065
|
-
if (
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
node,
|
|
1069
|
-
filename
|
|
1070
|
-
});
|
|
1071
|
-
else if (typeof value === "object") {
|
|
1072
|
-
for (const key of Object.keys(value)) if (![
|
|
1073
|
-
"colorSpace",
|
|
1074
|
-
"components",
|
|
1075
|
-
"channels",
|
|
1076
|
-
"hex",
|
|
1077
|
-
"alpha"
|
|
1078
|
-
].includes(key)) report({
|
|
1079
|
-
messageId: ERROR_INVALID_PROP$6,
|
|
1080
|
-
data: { key: JSON.stringify(key) },
|
|
1081
|
-
node: getObjMember(node, key) ?? node,
|
|
1082
|
-
filename
|
|
1083
|
-
});
|
|
1084
|
-
const colorSpace = "colorSpace" in value && typeof value.colorSpace === "string" ? value.colorSpace : void 0;
|
|
1085
|
-
const csData = COLORSPACE[colorSpace] || void 0;
|
|
1086
|
-
if (!("colorSpace" in value) || !csData) {
|
|
1087
|
-
report({
|
|
1088
|
-
messageId: ERROR_INVALID_COLOR_SPACE,
|
|
1089
|
-
data: { colorSpace },
|
|
1090
|
-
node: getObjMember(node, "colorSpace") ?? node,
|
|
1091
|
-
filename
|
|
1092
|
-
});
|
|
1093
|
-
return;
|
|
1094
|
-
}
|
|
1095
|
-
const components = "components" in value ? value.components : void 0;
|
|
1096
|
-
if (Array.isArray(components)) if (csData?.ranges && components?.length === csData.ranges.length) {
|
|
1097
|
-
for (let i = 0; i < components.length; i++) if (!Number.isFinite(components[i]) || components[i] < csData.ranges[i][0] || components[i] > csData.ranges[i][1]) {
|
|
1098
|
-
if (!(colorSpace === "hsl" && components[0] === null) && !(colorSpace === "hwb" && components[0] === null) && !(colorSpace === "lch" && components[2] === null) && !(colorSpace === "oklch" && components[2] === null)) report({
|
|
1099
|
-
messageId: ERROR_OUT_OF_RANGE,
|
|
1100
|
-
data: {
|
|
1101
|
-
colorSpace,
|
|
1102
|
-
range: `[${csData.ranges.map((r) => `${r[0]}–${r[1]}`).join(", ")}]`
|
|
1103
|
-
},
|
|
1104
|
-
node: getObjMember(node, "components") ?? node,
|
|
1105
|
-
filename
|
|
1106
|
-
});
|
|
1107
|
-
}
|
|
1108
|
-
} else report({
|
|
1109
|
-
messageId: ERROR_INVALID_COMPONENT_LENGTH,
|
|
977
|
+
function validateFontWeight(value, { node, filename }) {
|
|
978
|
+
if (typeof value === "string") {
|
|
979
|
+
if (options.style === "numbers") report({
|
|
980
|
+
messageId: ERROR_STYLE,
|
|
1110
981
|
data: {
|
|
1111
|
-
|
|
1112
|
-
|
|
982
|
+
style: "numbers",
|
|
983
|
+
value
|
|
1113
984
|
},
|
|
1114
|
-
node
|
|
985
|
+
node,
|
|
1115
986
|
filename
|
|
1116
987
|
});
|
|
1117
|
-
else report({
|
|
1118
|
-
messageId:
|
|
1119
|
-
|
|
1120
|
-
node: getObjMember(node, "components") ?? node,
|
|
988
|
+
else if (!(value in FONT_WEIGHTS)) report({
|
|
989
|
+
messageId: ERROR$8,
|
|
990
|
+
node,
|
|
1121
991
|
filename
|
|
1122
992
|
});
|
|
1123
|
-
|
|
1124
|
-
if (
|
|
1125
|
-
messageId:
|
|
1126
|
-
data: {
|
|
1127
|
-
|
|
993
|
+
} else if (typeof value === "number") {
|
|
994
|
+
if (options.style === "names") report({
|
|
995
|
+
messageId: ERROR_STYLE,
|
|
996
|
+
data: {
|
|
997
|
+
style: "names",
|
|
998
|
+
value
|
|
999
|
+
},
|
|
1000
|
+
node,
|
|
1128
1001
|
filename
|
|
1129
1002
|
});
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
let color;
|
|
1133
|
-
try {
|
|
1134
|
-
color = parseColor(hex);
|
|
1135
|
-
} catch {
|
|
1136
|
-
report({
|
|
1137
|
-
messageId: ERROR_INVALID_COLOR,
|
|
1138
|
-
data: { color: hex },
|
|
1139
|
-
node: getObjMember(node, "hex") ?? node,
|
|
1140
|
-
filename
|
|
1141
|
-
});
|
|
1142
|
-
return;
|
|
1143
|
-
}
|
|
1144
|
-
if (color.alpha !== 1) report({
|
|
1145
|
-
messageId: ERROR_INVALID_HEX8,
|
|
1146
|
-
data: { color: hex },
|
|
1147
|
-
node: getObjMember(node, "hex") ?? node,
|
|
1148
|
-
filename
|
|
1149
|
-
});
|
|
1150
|
-
}
|
|
1151
|
-
} else if (typeof value === "string") {
|
|
1152
|
-
if (isAlias(value)) return;
|
|
1153
|
-
if (!options.legacyFormat) report({
|
|
1154
|
-
messageId: ERROR_OBJ_FORMAT,
|
|
1155
|
-
data: { color: JSON.stringify(value) },
|
|
1003
|
+
else if (!(value >= 0 && value < 1e3)) report({
|
|
1004
|
+
messageId: ERROR$8,
|
|
1156
1005
|
node,
|
|
1157
1006
|
filename
|
|
1158
1007
|
});
|
|
1159
|
-
else try {
|
|
1160
|
-
parseColor(value);
|
|
1161
|
-
} catch {
|
|
1162
|
-
report({
|
|
1163
|
-
messageId: ERROR_INVALID_COLOR,
|
|
1164
|
-
data: { color: JSON.stringify(value) },
|
|
1165
|
-
node,
|
|
1166
|
-
filename
|
|
1167
|
-
});
|
|
1168
|
-
}
|
|
1169
1008
|
} else report({
|
|
1170
|
-
messageId:
|
|
1009
|
+
messageId: ERROR$8,
|
|
1171
1010
|
node,
|
|
1172
1011
|
filename
|
|
1173
1012
|
});
|
|
@@ -1175,64 +1014,94 @@ const rule$13 = {
|
|
|
1175
1014
|
}
|
|
1176
1015
|
}
|
|
1177
1016
|
};
|
|
1178
|
-
var valid_color_default = rule$13;
|
|
1179
1017
|
|
|
1180
1018
|
//#endregion
|
|
1181
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1182
|
-
const
|
|
1183
|
-
const
|
|
1184
|
-
const
|
|
1185
|
-
const
|
|
1186
|
-
const rule$
|
|
1019
|
+
//#region src/lint/plugin-core/rules/valid-gradient.ts
|
|
1020
|
+
const VALID_GRADIENT = "core/valid-gradient";
|
|
1021
|
+
const ERROR_MISSING$1 = "ERROR_MISSING";
|
|
1022
|
+
const ERROR_POSITION = "ERROR_POSITION";
|
|
1023
|
+
const ERROR_INVALID_PROP$7 = "ERROR_INVALID_PROP";
|
|
1024
|
+
const rule$13 = {
|
|
1187
1025
|
meta: {
|
|
1188
1026
|
messages: {
|
|
1189
|
-
[
|
|
1190
|
-
[
|
|
1191
|
-
[
|
|
1027
|
+
[ERROR_MISSING$1]: "Must be an array of { color, position } objects.",
|
|
1028
|
+
[ERROR_POSITION]: "Expected number 0-1, received {{ value }}.",
|
|
1029
|
+
[ERROR_INVALID_PROP$7]: "Unknown property {{ key }}."
|
|
1192
1030
|
},
|
|
1193
1031
|
docs: {
|
|
1194
|
-
description: "Require
|
|
1195
|
-
url: docsLink(
|
|
1032
|
+
description: "Require gradient tokens to follow the format.",
|
|
1033
|
+
url: docsLink(VALID_GRADIENT)
|
|
1196
1034
|
}
|
|
1197
1035
|
},
|
|
1198
1036
|
defaultOptions: {},
|
|
1199
1037
|
create({ tokens, report }) {
|
|
1200
1038
|
for (const t of Object.values(tokens)) {
|
|
1201
|
-
if (t.aliasOf || !t.originalValue) continue;
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1039
|
+
if (t.aliasOf || !t.originalValue || t.$type !== "gradient") continue;
|
|
1040
|
+
validateGradient(t.originalValue.$value, {
|
|
1041
|
+
node: getObjMember(t.source.node, "$value"),
|
|
1042
|
+
filename: t.source.filename
|
|
1043
|
+
});
|
|
1044
|
+
function validateGradient(value, { node, filename }) {
|
|
1045
|
+
if (Array.isArray(value)) for (let i = 0; i < value.length; i++) {
|
|
1046
|
+
const stop = value[i];
|
|
1047
|
+
if (!stop || typeof stop !== "object") {
|
|
1048
|
+
report({
|
|
1049
|
+
messageId: ERROR_MISSING$1,
|
|
1050
|
+
node,
|
|
1051
|
+
filename
|
|
1052
|
+
});
|
|
1053
|
+
continue;
|
|
1054
|
+
}
|
|
1055
|
+
for (const property of GRADIENT_REQUIRED_STOP_PROPERTIES) if (!(property in stop)) report({
|
|
1056
|
+
messageId: ERROR_MISSING$1,
|
|
1057
|
+
node: node.elements[i],
|
|
1058
|
+
filename
|
|
1207
1059
|
});
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1060
|
+
for (const key of Object.keys(stop)) if (!GRADIENT_REQUIRED_STOP_PROPERTIES.includes(key)) report({
|
|
1061
|
+
messageId: ERROR_INVALID_PROP$7,
|
|
1062
|
+
data: { key: JSON.stringify(key) },
|
|
1063
|
+
node: node.elements[i],
|
|
1064
|
+
filename
|
|
1065
|
+
});
|
|
1066
|
+
if ("position" in stop && typeof stop.position !== "number" && !isAlias(stop.position)) report({
|
|
1067
|
+
messageId: ERROR_POSITION,
|
|
1068
|
+
data: { value: stop.position },
|
|
1069
|
+
node: getObjMember(node.elements[i].value, "position"),
|
|
1070
|
+
filename
|
|
1214
1071
|
});
|
|
1215
1072
|
}
|
|
1073
|
+
else report({
|
|
1074
|
+
messageId: ERROR_MISSING$1,
|
|
1075
|
+
node,
|
|
1076
|
+
filename
|
|
1077
|
+
});
|
|
1216
1078
|
}
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
//#endregion
|
|
1084
|
+
//#region src/lint/plugin-core/rules/valid-link.ts
|
|
1085
|
+
const VALID_LINK = "core/valid-link";
|
|
1086
|
+
const ERROR$7 = "ERROR";
|
|
1087
|
+
const rule$12 = {
|
|
1088
|
+
meta: {
|
|
1089
|
+
messages: { [ERROR$7]: "Must be a string." },
|
|
1090
|
+
docs: {
|
|
1091
|
+
description: "Require link tokens to follow the Terrazzo extension.",
|
|
1092
|
+
url: docsLink(VALID_LINK)
|
|
1093
|
+
}
|
|
1094
|
+
},
|
|
1095
|
+
defaultOptions: {},
|
|
1096
|
+
create({ tokens, report }) {
|
|
1097
|
+
for (const t of Object.values(tokens)) {
|
|
1098
|
+
if (t.aliasOf || !t.originalValue || t.$type !== "link") continue;
|
|
1099
|
+
validateLink(t.originalValue.$value, {
|
|
1100
|
+
node: getObjMember(t.source.node, "$value"),
|
|
1101
|
+
filename: t.source.filename
|
|
1102
|
+
});
|
|
1103
|
+
function validateLink(value, { node, filename }) {
|
|
1104
|
+
if (!value || typeof value !== "string") report({
|
|
1236
1105
|
messageId: ERROR$7,
|
|
1237
1106
|
node,
|
|
1238
1107
|
filename
|
|
@@ -1241,160 +1110,43 @@ const rule$12 = {
|
|
|
1241
1110
|
}
|
|
1242
1111
|
}
|
|
1243
1112
|
};
|
|
1244
|
-
var valid_cubic_bezier_default = rule$12;
|
|
1245
1113
|
|
|
1246
1114
|
//#endregion
|
|
1247
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1248
|
-
const
|
|
1249
|
-
const
|
|
1250
|
-
const ERROR_INVALID_PROP$5 = "ERROR_INVALID_PROP";
|
|
1251
|
-
const ERROR_LEGACY$1 = "ERROR_LEGACY";
|
|
1252
|
-
const ERROR_UNIT$1 = "ERROR_UNIT";
|
|
1253
|
-
const ERROR_VALUE$1 = "ERROR_VALUE";
|
|
1115
|
+
//#region src/lint/plugin-core/rules/valid-number.ts
|
|
1116
|
+
const VALID_NUMBER = "core/valid-number";
|
|
1117
|
+
const ERROR_NAN = "ERROR_NAN";
|
|
1254
1118
|
const rule$11 = {
|
|
1255
1119
|
meta: {
|
|
1256
|
-
messages: {
|
|
1257
|
-
[ERROR_FORMAT$1]: "Invalid dimension: {{ value }}. Expected object with \"value\" and \"unit\".",
|
|
1258
|
-
[ERROR_LEGACY$1]: "Migrate to the new object format: { \"value\": 10, \"unit\": \"px\" }.",
|
|
1259
|
-
[ERROR_UNIT$1]: "Unit {{ unit }} not allowed. Expected {{ allowed }}.",
|
|
1260
|
-
[ERROR_INVALID_PROP$5]: "Unknown property {{ key }}.",
|
|
1261
|
-
[ERROR_VALUE$1]: "Expected number, received {{ value }}."
|
|
1262
|
-
},
|
|
1120
|
+
messages: { [ERROR_NAN]: "Must be a number." },
|
|
1263
1121
|
docs: {
|
|
1264
|
-
description: "Require
|
|
1265
|
-
url: docsLink(
|
|
1122
|
+
description: "Require number tokens to follow the format.",
|
|
1123
|
+
url: docsLink(VALID_NUMBER)
|
|
1266
1124
|
}
|
|
1267
1125
|
},
|
|
1268
|
-
defaultOptions: {
|
|
1269
|
-
|
|
1270
|
-
allowedUnits: [
|
|
1271
|
-
"px",
|
|
1272
|
-
"em",
|
|
1273
|
-
"rem"
|
|
1274
|
-
]
|
|
1275
|
-
},
|
|
1276
|
-
create({ tokens, options, report }) {
|
|
1126
|
+
defaultOptions: {},
|
|
1127
|
+
create({ tokens, report }) {
|
|
1277
1128
|
for (const t of Object.values(tokens)) {
|
|
1278
1129
|
if (t.aliasOf || !t.originalValue) continue;
|
|
1279
1130
|
switch (t.$type) {
|
|
1280
|
-
case "
|
|
1281
|
-
|
|
1131
|
+
case "number":
|
|
1132
|
+
validateNumber(t.originalValue.$value, {
|
|
1282
1133
|
node: getObjMember(t.source.node, "$value"),
|
|
1283
1134
|
filename: t.source.filename
|
|
1284
1135
|
});
|
|
1285
1136
|
break;
|
|
1286
|
-
case "
|
|
1287
|
-
if (typeof t.originalValue.$value === "object" && Array.isArray(t.originalValue.$value.dashArray)) {
|
|
1288
|
-
const dashArray = getObjMember(getObjMember(t.source.node, "$value"), "dashArray");
|
|
1289
|
-
for (let i = 0; i < t.originalValue.$value.dashArray.length; i++) {
|
|
1290
|
-
if (isAlias(t.originalValue.$value.dashArray[i])) continue;
|
|
1291
|
-
validateDimension(t.originalValue.$value.dashArray[i], {
|
|
1292
|
-
node: dashArray.elements[i].value,
|
|
1293
|
-
filename: t.source.filename
|
|
1294
|
-
});
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
break;
|
|
1298
|
-
case "border": {
|
|
1137
|
+
case "typography": {
|
|
1299
1138
|
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1300
1139
|
if (typeof t.originalValue.$value === "object") {
|
|
1301
|
-
if (t.originalValue.$value.
|
|
1302
|
-
node: getObjMember($valueNode, "
|
|
1140
|
+
if (t.originalValue.$value.lineHeight && !isAlias(t.originalValue.$value.lineHeight) && typeof t.originalValue.$value.lineHeight !== "object") validateNumber(t.originalValue.$value.lineHeight, {
|
|
1141
|
+
node: getObjMember($valueNode, "lineHeight"),
|
|
1303
1142
|
filename: t.source.filename
|
|
1304
1143
|
});
|
|
1305
|
-
if (typeof t.originalValue.$value.style === "object" && Array.isArray(t.originalValue.$value.style.dashArray)) {
|
|
1306
|
-
const dashArray = getObjMember(getObjMember($valueNode, "style"), "dashArray");
|
|
1307
|
-
for (let i = 0; i < t.originalValue.$value.style.dashArray.length; i++) {
|
|
1308
|
-
if (isAlias(t.originalValue.$value.style.dashArray[i])) continue;
|
|
1309
|
-
validateDimension(t.originalValue.$value.style.dashArray[i], {
|
|
1310
|
-
node: dashArray.elements[i].value,
|
|
1311
|
-
filename: t.source.filename
|
|
1312
|
-
});
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
break;
|
|
1317
|
-
}
|
|
1318
|
-
case "shadow":
|
|
1319
|
-
if (t.originalValue.$value && typeof t.originalValue.$value === "object") {
|
|
1320
|
-
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1321
|
-
const valueArray = Array.isArray(t.originalValue.$value) ? t.originalValue.$value : [t.originalValue.$value];
|
|
1322
|
-
for (let i = 0; i < valueArray.length; i++) {
|
|
1323
|
-
const node = $valueNode.type === "Array" ? $valueNode.elements[i].value : $valueNode;
|
|
1324
|
-
for (const property of [
|
|
1325
|
-
"offsetX",
|
|
1326
|
-
"offsetY",
|
|
1327
|
-
"blur",
|
|
1328
|
-
"spread"
|
|
1329
|
-
]) {
|
|
1330
|
-
if (isAlias(valueArray[i][property])) continue;
|
|
1331
|
-
validateDimension(valueArray[i][property], {
|
|
1332
|
-
node: getObjMember(node, property),
|
|
1333
|
-
filename: t.source.filename
|
|
1334
|
-
});
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
break;
|
|
1339
|
-
case "typography": {
|
|
1340
|
-
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1341
|
-
if (typeof t.originalValue.$value === "object") {
|
|
1342
|
-
for (const property of [
|
|
1343
|
-
"fontSize",
|
|
1344
|
-
"lineHeight",
|
|
1345
|
-
"letterSpacing"
|
|
1346
|
-
]) if (property in t.originalValue.$value) {
|
|
1347
|
-
if (isAlias(t.originalValue.$value[property]) || property === "lineHeight" && typeof t.originalValue.$value[property] === "number") continue;
|
|
1348
|
-
validateDimension(t.originalValue.$value[property], {
|
|
1349
|
-
node: getObjMember($valueNode, property),
|
|
1350
|
-
filename: t.source.filename
|
|
1351
|
-
});
|
|
1352
|
-
}
|
|
1353
1144
|
}
|
|
1354
|
-
break;
|
|
1355
1145
|
}
|
|
1356
1146
|
}
|
|
1357
|
-
function
|
|
1358
|
-
if (
|
|
1359
|
-
|
|
1360
|
-
messageId: ERROR_INVALID_PROP$5,
|
|
1361
|
-
data: { key: JSON.stringify(key) },
|
|
1362
|
-
node: getObjMember(node, key) ?? node,
|
|
1363
|
-
filename
|
|
1364
|
-
});
|
|
1365
|
-
const { unit, value: numValue } = value;
|
|
1366
|
-
if (!("value" in value || "unit" in value)) {
|
|
1367
|
-
report({
|
|
1368
|
-
messageId: ERROR_FORMAT$1,
|
|
1369
|
-
data: { value },
|
|
1370
|
-
node,
|
|
1371
|
-
filename
|
|
1372
|
-
});
|
|
1373
|
-
return;
|
|
1374
|
-
}
|
|
1375
|
-
if (!options.allowedUnits.includes(unit)) report({
|
|
1376
|
-
messageId: ERROR_UNIT$1,
|
|
1377
|
-
data: {
|
|
1378
|
-
unit,
|
|
1379
|
-
allowed: new Intl.ListFormat("en-us", { type: "disjunction" }).format(options.allowedUnits)
|
|
1380
|
-
},
|
|
1381
|
-
node: getObjMember(node, "unit") ?? node,
|
|
1382
|
-
filename
|
|
1383
|
-
});
|
|
1384
|
-
if (!Number.isFinite(numValue)) report({
|
|
1385
|
-
messageId: ERROR_VALUE$1,
|
|
1386
|
-
data: { value },
|
|
1387
|
-
node: getObjMember(node, "value") ?? node,
|
|
1388
|
-
filename
|
|
1389
|
-
});
|
|
1390
|
-
} else if (typeof value === "string" && !options.legacyFormat) report({
|
|
1391
|
-
messageId: ERROR_LEGACY$1,
|
|
1392
|
-
node,
|
|
1393
|
-
filename
|
|
1394
|
-
});
|
|
1395
|
-
else report({
|
|
1396
|
-
messageId: ERROR_FORMAT$1,
|
|
1397
|
-
data: { value },
|
|
1147
|
+
function validateNumber(value, { node, filename }) {
|
|
1148
|
+
if (typeof value !== "number" || Number.isNaN(value)) report({
|
|
1149
|
+
messageId: ERROR_NAN,
|
|
1398
1150
|
node,
|
|
1399
1151
|
filename
|
|
1400
1152
|
});
|
|
@@ -1402,150 +1154,72 @@ const rule$11 = {
|
|
|
1402
1154
|
}
|
|
1403
1155
|
}
|
|
1404
1156
|
};
|
|
1405
|
-
var valid_dimension_default = rule$11;
|
|
1406
1157
|
|
|
1407
1158
|
//#endregion
|
|
1408
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1409
|
-
const
|
|
1410
|
-
const
|
|
1411
|
-
const ERROR_INVALID_PROP$
|
|
1412
|
-
const ERROR_LEGACY = "ERROR_LEGACY";
|
|
1413
|
-
const ERROR_UNIT = "ERROR_UNIT";
|
|
1414
|
-
const ERROR_VALUE = "ERROR_VALUE";
|
|
1159
|
+
//#region src/lint/plugin-core/rules/valid-shadow.ts
|
|
1160
|
+
const VALID_SHADOW = "core/valid-shadow";
|
|
1161
|
+
const ERROR$6 = "ERROR";
|
|
1162
|
+
const ERROR_INVALID_PROP$6 = "ERROR_INVALID_PROP";
|
|
1415
1163
|
const rule$10 = {
|
|
1416
1164
|
meta: {
|
|
1417
1165
|
messages: {
|
|
1418
|
-
[
|
|
1419
|
-
[
|
|
1420
|
-
[ERROR_INVALID_PROP$4]: "Unknown property: {{ key }}.",
|
|
1421
|
-
[ERROR_UNIT]: "Unknown unit {{ unit }}. Expected \"ms\" or \"s\".",
|
|
1422
|
-
[ERROR_VALUE]: "Expected number, received {{ value }}."
|
|
1166
|
+
[ERROR$6]: `Missing required properties: ${new Intl.ListFormat("en-us", { type: "conjunction" }).format(SHADOW_REQUIRED_PROPERTIES)}.`,
|
|
1167
|
+
[ERROR_INVALID_PROP$6]: "Unknown property {{ key }}."
|
|
1423
1168
|
},
|
|
1424
1169
|
docs: {
|
|
1425
|
-
description: "Require
|
|
1426
|
-
url: docsLink(
|
|
1170
|
+
description: "Require shadow tokens to follow the format.",
|
|
1171
|
+
url: docsLink(VALID_SHADOW)
|
|
1427
1172
|
}
|
|
1428
1173
|
},
|
|
1429
|
-
defaultOptions: {
|
|
1430
|
-
|
|
1431
|
-
unknownUnits: false
|
|
1432
|
-
},
|
|
1433
|
-
create({ tokens, options, report }) {
|
|
1174
|
+
defaultOptions: {},
|
|
1175
|
+
create({ tokens, report }) {
|
|
1434
1176
|
for (const t of Object.values(tokens)) {
|
|
1435
|
-
if (t.aliasOf || !t.originalValue) continue;
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
if (typeof t.originalValue.$value === "object") {
|
|
1445
|
-
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1446
|
-
for (const property of ["duration", "delay"]) if (t.originalValue.$value[property] && !isAlias(t.originalValue.$value[property])) validateDuration(t.originalValue.$value[property], {
|
|
1447
|
-
node: getObjMember($valueNode, property),
|
|
1448
|
-
filename: t.source.filename
|
|
1449
|
-
});
|
|
1450
|
-
}
|
|
1451
|
-
break;
|
|
1452
|
-
}
|
|
1453
|
-
function validateDuration(value, { node, filename }) {
|
|
1454
|
-
if (value && typeof value === "object") {
|
|
1455
|
-
for (const key of Object.keys(value)) if (!["value", "unit"].includes(key)) report({
|
|
1456
|
-
messageId: ERROR_INVALID_PROP$4,
|
|
1457
|
-
data: { key: JSON.stringify(key) },
|
|
1458
|
-
node: getObjMember(node, key) ?? node,
|
|
1459
|
-
filename
|
|
1460
|
-
});
|
|
1461
|
-
const { unit, value: numValue } = value;
|
|
1462
|
-
if (!("value" in value || "unit" in value)) {
|
|
1463
|
-
report({
|
|
1464
|
-
messageId: ERROR_FORMAT,
|
|
1465
|
-
data: { value },
|
|
1466
|
-
node,
|
|
1467
|
-
filename
|
|
1468
|
-
});
|
|
1469
|
-
return;
|
|
1470
|
-
}
|
|
1471
|
-
if (!options.unknownUnits && !["ms", "s"].includes(unit)) report({
|
|
1472
|
-
messageId: ERROR_UNIT,
|
|
1473
|
-
data: { unit },
|
|
1474
|
-
node: getObjMember(node, "unit") ?? node,
|
|
1475
|
-
filename
|
|
1476
|
-
});
|
|
1477
|
-
if (!Number.isFinite(numValue)) report({
|
|
1478
|
-
messageId: ERROR_VALUE,
|
|
1479
|
-
data: { value },
|
|
1480
|
-
node: getObjMember(node, "value") ?? node,
|
|
1481
|
-
filename
|
|
1482
|
-
});
|
|
1483
|
-
} else if (typeof value === "string" && !options.legacyFormat) report({
|
|
1484
|
-
messageId: ERROR_FORMAT,
|
|
1177
|
+
if (t.aliasOf || !t.originalValue || t.$type !== "shadow") continue;
|
|
1178
|
+
validateShadow(t.originalValue.$value, {
|
|
1179
|
+
node: getObjMember(t.source.node, "$value"),
|
|
1180
|
+
filename: t.source.filename
|
|
1181
|
+
});
|
|
1182
|
+
function validateShadow(value, { node, filename }) {
|
|
1183
|
+
const wrappedValue = Array.isArray(value) ? value : [value];
|
|
1184
|
+
for (let i = 0; i < wrappedValue.length; i++) if (!wrappedValue[i] || typeof wrappedValue[i] !== "object" || !SHADOW_REQUIRED_PROPERTIES.every((property) => property in wrappedValue[i])) report({
|
|
1185
|
+
messageId: ERROR$6,
|
|
1485
1186
|
node,
|
|
1486
1187
|
filename
|
|
1487
1188
|
});
|
|
1488
|
-
else report({
|
|
1489
|
-
messageId:
|
|
1490
|
-
data: {
|
|
1491
|
-
node,
|
|
1189
|
+
else for (const key of Object.keys(wrappedValue[i])) if (![...SHADOW_REQUIRED_PROPERTIES, "inset"].includes(key)) report({
|
|
1190
|
+
messageId: ERROR_INVALID_PROP$6,
|
|
1191
|
+
data: { key: JSON.stringify(key) },
|
|
1192
|
+
node: getObjMember(node.type === "Array" ? node.elements[i].value : node, key),
|
|
1492
1193
|
filename
|
|
1493
1194
|
});
|
|
1494
1195
|
}
|
|
1495
1196
|
}
|
|
1496
1197
|
}
|
|
1497
1198
|
};
|
|
1498
|
-
var valid_duration_default = rule$10;
|
|
1499
1199
|
|
|
1500
1200
|
//#endregion
|
|
1501
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1502
|
-
const
|
|
1503
|
-
const ERROR$
|
|
1201
|
+
//#region src/lint/plugin-core/rules/valid-string.ts
|
|
1202
|
+
const VALID_STRING = "core/valid-string";
|
|
1203
|
+
const ERROR$5 = "ERROR";
|
|
1504
1204
|
const rule$9 = {
|
|
1505
1205
|
meta: {
|
|
1506
|
-
messages: { [ERROR$
|
|
1206
|
+
messages: { [ERROR$5]: "Must be a string." },
|
|
1507
1207
|
docs: {
|
|
1508
|
-
description: "Require
|
|
1509
|
-
url: docsLink(
|
|
1208
|
+
description: "Require string tokens to follow the Terrazzo extension.",
|
|
1209
|
+
url: docsLink(VALID_STRING)
|
|
1510
1210
|
}
|
|
1511
1211
|
},
|
|
1512
1212
|
defaultOptions: {},
|
|
1513
1213
|
create({ tokens, report }) {
|
|
1514
1214
|
for (const t of Object.values(tokens)) {
|
|
1515
|
-
if (t.aliasOf || !t.originalValue) continue;
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
case "typography":
|
|
1524
|
-
if (typeof t.originalValue.$value === "object" && t.originalValue.$value.fontFamily) {
|
|
1525
|
-
if (t.partialAliasOf?.fontFamily) continue;
|
|
1526
|
-
const properties = getObjMembers(getObjMember(t.source.node, "$value"));
|
|
1527
|
-
validateFontFamily(t.originalValue.$value.fontFamily, {
|
|
1528
|
-
node: properties.fontFamily,
|
|
1529
|
-
filename: t.source.filename
|
|
1530
|
-
});
|
|
1531
|
-
}
|
|
1532
|
-
break;
|
|
1533
|
-
}
|
|
1534
|
-
function validateFontFamily(value, { node, filename }) {
|
|
1535
|
-
if (typeof value === "string") {
|
|
1536
|
-
if (!value) report({
|
|
1537
|
-
messageId: ERROR$6,
|
|
1538
|
-
node,
|
|
1539
|
-
filename
|
|
1540
|
-
});
|
|
1541
|
-
} else if (Array.isArray(value)) {
|
|
1542
|
-
if (!value.every((v) => v && typeof v === "string")) report({
|
|
1543
|
-
messageId: ERROR$6,
|
|
1544
|
-
node,
|
|
1545
|
-
filename
|
|
1546
|
-
});
|
|
1547
|
-
} else report({
|
|
1548
|
-
messageId: ERROR$6,
|
|
1215
|
+
if (t.aliasOf || !t.originalValue || t.$type !== "string") continue;
|
|
1216
|
+
validateString(t.originalValue.$value, {
|
|
1217
|
+
node: getObjMember(t.source.node, "$value"),
|
|
1218
|
+
filename: t.source.filename
|
|
1219
|
+
});
|
|
1220
|
+
function validateString(value, { node, filename }) {
|
|
1221
|
+
if (typeof value !== "string") report({
|
|
1222
|
+
messageId: ERROR$5,
|
|
1549
1223
|
node,
|
|
1550
1224
|
filename
|
|
1551
1225
|
});
|
|
@@ -1553,79 +1227,82 @@ const rule$9 = {
|
|
|
1553
1227
|
}
|
|
1554
1228
|
}
|
|
1555
1229
|
};
|
|
1556
|
-
var valid_font_family_default = rule$9;
|
|
1557
1230
|
|
|
1558
1231
|
//#endregion
|
|
1559
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1560
|
-
const
|
|
1561
|
-
const
|
|
1562
|
-
const
|
|
1232
|
+
//#region src/lint/plugin-core/rules/valid-stroke-style.ts
|
|
1233
|
+
const VALID_STROKE_STYLE = "core/valid-stroke-style";
|
|
1234
|
+
const ERROR_STR = "ERROR_STR";
|
|
1235
|
+
const ERROR_OBJ = "ERROR_OBJ";
|
|
1236
|
+
const ERROR_LINE_CAP = "ERROR_LINE_CAP";
|
|
1237
|
+
const ERROR_INVALID_PROP$5 = "ERROR_INVALID_PROP";
|
|
1563
1238
|
const rule$8 = {
|
|
1564
1239
|
meta: {
|
|
1565
1240
|
messages: {
|
|
1566
|
-
[
|
|
1567
|
-
[
|
|
1241
|
+
[ERROR_STR]: `Value most be one of ${new Intl.ListFormat("en-us", { type: "disjunction" }).format(STROKE_STYLE_STRING_VALUES)}.`,
|
|
1242
|
+
[ERROR_OBJ]: `Missing required properties: ${new Intl.ListFormat("en-us", { type: "conjunction" }).format(TRANSITION_REQUIRED_PROPERTIES)}.`,
|
|
1243
|
+
[ERROR_LINE_CAP]: `lineCap must be one of ${new Intl.ListFormat("en-us", { type: "disjunction" }).format(STROKE_STYLE_LINE_CAP_VALUES)}.`,
|
|
1244
|
+
[ERROR_INVALID_PROP$5]: "Unknown property: {{ key }}."
|
|
1568
1245
|
},
|
|
1569
1246
|
docs: {
|
|
1570
|
-
description: "Require
|
|
1571
|
-
url: docsLink(
|
|
1247
|
+
description: "Require strokeStyle tokens to follow the format.",
|
|
1248
|
+
url: docsLink(VALID_STROKE_STYLE)
|
|
1572
1249
|
}
|
|
1573
1250
|
},
|
|
1574
|
-
defaultOptions: {
|
|
1575
|
-
create({ tokens,
|
|
1251
|
+
defaultOptions: {},
|
|
1252
|
+
create({ tokens, report }) {
|
|
1576
1253
|
for (const t of Object.values(tokens)) {
|
|
1577
1254
|
if (t.aliasOf || !t.originalValue) continue;
|
|
1578
1255
|
switch (t.$type) {
|
|
1579
|
-
case "
|
|
1580
|
-
|
|
1256
|
+
case "strokeStyle":
|
|
1257
|
+
validateStrokeStyle(t.originalValue.$value, {
|
|
1581
1258
|
node: getObjMember(t.source.node, "$value"),
|
|
1582
1259
|
filename: t.source.filename
|
|
1583
1260
|
});
|
|
1584
1261
|
break;
|
|
1585
|
-
case "
|
|
1586
|
-
if (typeof t.originalValue.$value === "object"
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
node: properties.fontWeight,
|
|
1262
|
+
case "border":
|
|
1263
|
+
if (t.originalValue.$value && typeof t.originalValue.$value === "object") {
|
|
1264
|
+
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1265
|
+
if (t.originalValue.$value.style) validateStrokeStyle(t.originalValue.$value.style, {
|
|
1266
|
+
node: getObjMember($valueNode, "style"),
|
|
1591
1267
|
filename: t.source.filename
|
|
1592
1268
|
});
|
|
1593
1269
|
}
|
|
1594
1270
|
break;
|
|
1595
1271
|
}
|
|
1596
|
-
function
|
|
1272
|
+
function validateStrokeStyle(value, { node, filename }) {
|
|
1597
1273
|
if (typeof value === "string") {
|
|
1598
|
-
if (
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
}
|
|
1274
|
+
if (!isAlias(value) && !STROKE_STYLE_STRING_VALUES.includes(value)) {
|
|
1275
|
+
report({
|
|
1276
|
+
messageId: ERROR_STR,
|
|
1277
|
+
node,
|
|
1278
|
+
filename
|
|
1279
|
+
});
|
|
1280
|
+
return;
|
|
1281
|
+
}
|
|
1282
|
+
} else if (value && typeof value === "object") {
|
|
1283
|
+
if (!STROKE_STYLE_OBJECT_REQUIRED_PROPERTIES.every((property) => property in value)) report({
|
|
1284
|
+
messageId: ERROR_OBJ,
|
|
1604
1285
|
node,
|
|
1605
1286
|
filename
|
|
1606
1287
|
});
|
|
1607
|
-
|
|
1608
|
-
messageId:
|
|
1609
|
-
node,
|
|
1288
|
+
if (!Array.isArray(value.dashArray)) report({
|
|
1289
|
+
messageId: ERROR_OBJ,
|
|
1290
|
+
node: getObjMember(node, "dashArray"),
|
|
1610
1291
|
filename
|
|
1611
1292
|
});
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
data: {
|
|
1616
|
-
style: "names",
|
|
1617
|
-
value
|
|
1618
|
-
},
|
|
1619
|
-
node,
|
|
1293
|
+
if (!STROKE_STYLE_LINE_CAP_VALUES.includes(value.lineCap)) report({
|
|
1294
|
+
messageId: ERROR_OBJ,
|
|
1295
|
+
node: getObjMember(node, "lineCap"),
|
|
1620
1296
|
filename
|
|
1621
1297
|
});
|
|
1622
|
-
|
|
1623
|
-
messageId:
|
|
1624
|
-
|
|
1298
|
+
for (const key of Object.keys(value)) if (!["dashArray", "lineCap"].includes(key)) report({
|
|
1299
|
+
messageId: ERROR_INVALID_PROP$5,
|
|
1300
|
+
data: { key: JSON.stringify(key) },
|
|
1301
|
+
node: getObjMember(node, key),
|
|
1625
1302
|
filename
|
|
1626
1303
|
});
|
|
1627
1304
|
} else report({
|
|
1628
|
-
messageId:
|
|
1305
|
+
messageId: ERROR_OBJ,
|
|
1629
1306
|
node,
|
|
1630
1307
|
filename
|
|
1631
1308
|
});
|
|
@@ -1633,97 +1310,90 @@ const rule$8 = {
|
|
|
1633
1310
|
}
|
|
1634
1311
|
}
|
|
1635
1312
|
};
|
|
1636
|
-
var valid_font_weight_default = rule$8;
|
|
1637
1313
|
|
|
1638
1314
|
//#endregion
|
|
1639
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1640
|
-
const
|
|
1641
|
-
const
|
|
1642
|
-
const
|
|
1643
|
-
const ERROR_INVALID_PROP$3 = "ERROR_INVALID_PROP";
|
|
1315
|
+
//#region src/lint/plugin-core/rules/valid-transition.ts
|
|
1316
|
+
const VALID_TRANSITION = "core/valid-transition";
|
|
1317
|
+
const ERROR$4 = "ERROR";
|
|
1318
|
+
const ERROR_INVALID_PROP$4 = "ERROR_INVALID_PROP";
|
|
1644
1319
|
const rule$7 = {
|
|
1645
1320
|
meta: {
|
|
1646
1321
|
messages: {
|
|
1647
|
-
[
|
|
1648
|
-
[
|
|
1649
|
-
[ERROR_INVALID_PROP$3]: "Unknown property {{ key }}."
|
|
1322
|
+
[ERROR$4]: `Missing required properties: ${new Intl.ListFormat("en-us", { type: "conjunction" }).format(TRANSITION_REQUIRED_PROPERTIES)}.`,
|
|
1323
|
+
[ERROR_INVALID_PROP$4]: "Unknown property: {{ key }}."
|
|
1650
1324
|
},
|
|
1651
1325
|
docs: {
|
|
1652
|
-
description: "Require
|
|
1653
|
-
url: docsLink(
|
|
1326
|
+
description: "Require transition tokens to follow the format.",
|
|
1327
|
+
url: docsLink(VALID_TRANSITION)
|
|
1654
1328
|
}
|
|
1655
1329
|
},
|
|
1656
1330
|
defaultOptions: {},
|
|
1657
1331
|
create({ tokens, report }) {
|
|
1658
1332
|
for (const t of Object.values(tokens)) {
|
|
1659
|
-
if (t.aliasOf || !t.originalValue || t.$type !== "
|
|
1660
|
-
|
|
1333
|
+
if (t.aliasOf || !t.originalValue || t.$type !== "transition") continue;
|
|
1334
|
+
validateTransition(t.originalValue.$value, {
|
|
1661
1335
|
node: getObjMember(t.source.node, "$value"),
|
|
1662
1336
|
filename: t.source.filename
|
|
1663
1337
|
});
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
node: node.elements[i],
|
|
1678
|
-
filename
|
|
1679
|
-
});
|
|
1680
|
-
for (const key of Object.keys(stop)) if (!GRADIENT_REQUIRED_STOP_PROPERTIES.includes(key)) report({
|
|
1681
|
-
messageId: ERROR_INVALID_PROP$3,
|
|
1682
|
-
data: { key: JSON.stringify(key) },
|
|
1683
|
-
node: node.elements[i],
|
|
1684
|
-
filename
|
|
1685
|
-
});
|
|
1686
|
-
if ("position" in stop && typeof stop.position !== "number" && !isAlias(stop.position)) report({
|
|
1687
|
-
messageId: ERROR_POSITION,
|
|
1688
|
-
data: { value: stop.position },
|
|
1689
|
-
node: getObjMember(node.elements[i].value, "position"),
|
|
1690
|
-
filename
|
|
1691
|
-
});
|
|
1692
|
-
}
|
|
1693
|
-
else report({
|
|
1694
|
-
messageId: ERROR_MISSING$1,
|
|
1695
|
-
node,
|
|
1696
|
-
filename
|
|
1697
|
-
});
|
|
1698
|
-
}
|
|
1338
|
+
}
|
|
1339
|
+
function validateTransition(value, { node, filename }) {
|
|
1340
|
+
if (!value || typeof value !== "object" || !TRANSITION_REQUIRED_PROPERTIES.every((property) => property in value)) report({
|
|
1341
|
+
messageId: ERROR$4,
|
|
1342
|
+
node,
|
|
1343
|
+
filename
|
|
1344
|
+
});
|
|
1345
|
+
else for (const key of Object.keys(value)) if (!TRANSITION_REQUIRED_PROPERTIES.includes(key)) report({
|
|
1346
|
+
messageId: ERROR_INVALID_PROP$4,
|
|
1347
|
+
data: { key: JSON.stringify(key) },
|
|
1348
|
+
node: getObjMember(node, key),
|
|
1349
|
+
filename
|
|
1350
|
+
});
|
|
1699
1351
|
}
|
|
1700
1352
|
}
|
|
1701
1353
|
};
|
|
1702
|
-
var valid_gradient_default = rule$7;
|
|
1703
1354
|
|
|
1704
1355
|
//#endregion
|
|
1705
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1706
|
-
const
|
|
1707
|
-
const ERROR$
|
|
1356
|
+
//#region src/lint/plugin-core/rules/valid-typography.ts
|
|
1357
|
+
const VALID_TYPOGRAPHY = "core/valid-typography";
|
|
1358
|
+
const ERROR$3 = "ERROR";
|
|
1359
|
+
const ERROR_MISSING = "ERROR_MISSING";
|
|
1708
1360
|
const rule$6 = {
|
|
1709
1361
|
meta: {
|
|
1710
|
-
messages: {
|
|
1362
|
+
messages: {
|
|
1363
|
+
[ERROR$3]: `Expected object, received {{ value }}.`,
|
|
1364
|
+
[ERROR_MISSING]: `Missing required property "{{ property }}".`
|
|
1365
|
+
},
|
|
1711
1366
|
docs: {
|
|
1712
|
-
description: "Require
|
|
1713
|
-
url: docsLink(
|
|
1367
|
+
description: "Require typography tokens to follow the format.",
|
|
1368
|
+
url: docsLink(VALID_TYPOGRAPHY)
|
|
1714
1369
|
}
|
|
1715
1370
|
},
|
|
1716
|
-
defaultOptions: {
|
|
1717
|
-
|
|
1371
|
+
defaultOptions: { requiredProperties: [
|
|
1372
|
+
"fontFamily",
|
|
1373
|
+
"fontSize",
|
|
1374
|
+
"fontWeight",
|
|
1375
|
+
"letterSpacing",
|
|
1376
|
+
"lineHeight"
|
|
1377
|
+
] },
|
|
1378
|
+
create({ tokens, options, report }) {
|
|
1379
|
+
const isIgnored = options.ignore ? wcmatch(options.ignore) : () => false;
|
|
1718
1380
|
for (const t of Object.values(tokens)) {
|
|
1719
|
-
if (t.aliasOf || !t.originalValue || t.$type !== "
|
|
1720
|
-
|
|
1381
|
+
if (t.aliasOf || !t.originalValue || t.$type !== "typography" || isIgnored(t.id)) continue;
|
|
1382
|
+
validateTypography(t.originalValue.$value, {
|
|
1721
1383
|
node: getObjMember(t.source.node, "$value"),
|
|
1722
1384
|
filename: t.source.filename
|
|
1723
1385
|
});
|
|
1724
|
-
function
|
|
1725
|
-
if (
|
|
1726
|
-
|
|
1386
|
+
function validateTypography(value, { node, filename }) {
|
|
1387
|
+
if (value && typeof value === "object") {
|
|
1388
|
+
for (const property of options.requiredProperties) if (!(property in value)) report({
|
|
1389
|
+
messageId: ERROR_MISSING,
|
|
1390
|
+
data: { property },
|
|
1391
|
+
node,
|
|
1392
|
+
filename
|
|
1393
|
+
});
|
|
1394
|
+
} else report({
|
|
1395
|
+
messageId: ERROR$3,
|
|
1396
|
+
data: { value: JSON.stringify(value) },
|
|
1727
1397
|
node,
|
|
1728
1398
|
filename
|
|
1729
1399
|
});
|
|
@@ -1731,203 +1401,266 @@ const rule$6 = {
|
|
|
1731
1401
|
}
|
|
1732
1402
|
}
|
|
1733
1403
|
};
|
|
1734
|
-
var valid_link_default = rule$6;
|
|
1735
1404
|
|
|
1736
1405
|
//#endregion
|
|
1737
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1738
|
-
const
|
|
1739
|
-
const
|
|
1406
|
+
//#region src/lint/plugin-core/rules/valid-boolean.ts
|
|
1407
|
+
const VALID_BOOLEAN = "core/valid-boolean";
|
|
1408
|
+
const ERROR$2 = "ERROR";
|
|
1740
1409
|
const rule$5 = {
|
|
1741
1410
|
meta: {
|
|
1742
|
-
messages: { [
|
|
1411
|
+
messages: { [ERROR$2]: "Must be a boolean." },
|
|
1743
1412
|
docs: {
|
|
1744
|
-
description: "Require
|
|
1745
|
-
url: docsLink(
|
|
1413
|
+
description: "Require boolean tokens to follow the Terrazzo extension.",
|
|
1414
|
+
url: docsLink(VALID_BOOLEAN)
|
|
1746
1415
|
}
|
|
1747
1416
|
},
|
|
1748
1417
|
defaultOptions: {},
|
|
1749
1418
|
create({ tokens, report }) {
|
|
1750
1419
|
for (const t of Object.values(tokens)) {
|
|
1751
|
-
if (t.aliasOf || !t.originalValue) continue;
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
if (typeof t.originalValue.$value === "object") {
|
|
1762
|
-
if (t.originalValue.$value.lineHeight && !isAlias(t.originalValue.$value.lineHeight) && typeof t.originalValue.$value.lineHeight !== "object") validateNumber(t.originalValue.$value.lineHeight, {
|
|
1763
|
-
node: getObjMember($valueNode, "lineHeight"),
|
|
1764
|
-
filename: t.source.filename
|
|
1765
|
-
});
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
}
|
|
1769
|
-
function validateNumber(value, { node, filename }) {
|
|
1770
|
-
if (typeof value !== "number" || Number.isNaN(value)) report({
|
|
1771
|
-
messageId: ERROR_NAN,
|
|
1772
|
-
node,
|
|
1773
|
-
filename
|
|
1420
|
+
if (t.aliasOf || !t.originalValue || t.$type !== "boolean") continue;
|
|
1421
|
+
validateBoolean(t.originalValue.$value, {
|
|
1422
|
+
node: getObjMember(t.source.node, "$value"),
|
|
1423
|
+
filename: t.source.filename
|
|
1424
|
+
});
|
|
1425
|
+
function validateBoolean(value, { node, filename }) {
|
|
1426
|
+
if (typeof value !== "boolean") report({
|
|
1427
|
+
messageId: ERROR$2,
|
|
1428
|
+
filename,
|
|
1429
|
+
node
|
|
1774
1430
|
});
|
|
1775
1431
|
}
|
|
1776
1432
|
}
|
|
1777
1433
|
}
|
|
1778
1434
|
};
|
|
1779
|
-
var valid_number_default = rule$5;
|
|
1780
1435
|
|
|
1781
1436
|
//#endregion
|
|
1782
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1783
|
-
const
|
|
1784
|
-
const ERROR$
|
|
1785
|
-
const ERROR_INVALID_PROP$
|
|
1437
|
+
//#region src/lint/plugin-core/rules/valid-border.ts
|
|
1438
|
+
const VALID_BORDER = "core/valid-border";
|
|
1439
|
+
const ERROR$1 = "ERROR";
|
|
1440
|
+
const ERROR_INVALID_PROP$3 = "ERROR_INVALID_PROP";
|
|
1786
1441
|
const rule$4 = {
|
|
1787
1442
|
meta: {
|
|
1788
1443
|
messages: {
|
|
1789
|
-
[ERROR$
|
|
1790
|
-
[ERROR_INVALID_PROP$
|
|
1444
|
+
[ERROR$1]: `Border token missing required properties: ${new Intl.ListFormat("en-us", { type: "conjunction" }).format(BORDER_REQUIRED_PROPERTIES)}.`,
|
|
1445
|
+
[ERROR_INVALID_PROP$3]: "Unknown property: {{ key }}."
|
|
1791
1446
|
},
|
|
1792
1447
|
docs: {
|
|
1793
|
-
description: "Require
|
|
1794
|
-
url: docsLink(
|
|
1448
|
+
description: "Require border tokens to follow the format.",
|
|
1449
|
+
url: docsLink(VALID_BORDER)
|
|
1795
1450
|
}
|
|
1796
1451
|
},
|
|
1797
1452
|
defaultOptions: {},
|
|
1798
1453
|
create({ tokens, report }) {
|
|
1799
1454
|
for (const t of Object.values(tokens)) {
|
|
1800
|
-
if (t.aliasOf || !t.originalValue || t.$type !== "
|
|
1801
|
-
|
|
1455
|
+
if (t.aliasOf || !t.originalValue || t.$type !== "border") continue;
|
|
1456
|
+
validateBorder(t.originalValue.$value, {
|
|
1802
1457
|
node: getObjMember(t.source.node, "$value"),
|
|
1803
1458
|
filename: t.source.filename
|
|
1804
1459
|
});
|
|
1805
|
-
function validateShadow(value, { node, filename }) {
|
|
1806
|
-
const wrappedValue = Array.isArray(value) ? value : [value];
|
|
1807
|
-
for (let i = 0; i < wrappedValue.length; i++) if (!wrappedValue[i] || typeof wrappedValue[i] !== "object" || !SHADOW_REQUIRED_PROPERTIES.every((property) => property in wrappedValue[i])) report({
|
|
1808
|
-
messageId: ERROR$3,
|
|
1809
|
-
node,
|
|
1810
|
-
filename
|
|
1811
|
-
});
|
|
1812
|
-
else for (const key of Object.keys(wrappedValue[i])) if (![...SHADOW_REQUIRED_PROPERTIES, "inset"].includes(key)) report({
|
|
1813
|
-
messageId: ERROR_INVALID_PROP$2,
|
|
1814
|
-
data: { key: JSON.stringify(key) },
|
|
1815
|
-
node: getObjMember(node.type === "Array" ? node.elements[i].value : node, key),
|
|
1816
|
-
filename
|
|
1817
|
-
});
|
|
1818
|
-
}
|
|
1819
1460
|
}
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
const
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
docs: {
|
|
1832
|
-
description: "Require string tokens to follow the Terrazzo extension.",
|
|
1833
|
-
url: docsLink(VALID_STRING)
|
|
1834
|
-
}
|
|
1835
|
-
},
|
|
1836
|
-
defaultOptions: {},
|
|
1837
|
-
create({ tokens, report }) {
|
|
1838
|
-
for (const t of Object.values(tokens)) {
|
|
1839
|
-
if (t.aliasOf || !t.originalValue || t.$type !== "string") continue;
|
|
1840
|
-
validateString(t.originalValue.$value, {
|
|
1841
|
-
node: getObjMember(t.source.node, "$value"),
|
|
1842
|
-
filename: t.source.filename
|
|
1461
|
+
function validateBorder(value, { node, filename }) {
|
|
1462
|
+
if (!value || typeof value !== "object" || !BORDER_REQUIRED_PROPERTIES.every((property) => property in value)) report({
|
|
1463
|
+
messageId: ERROR$1,
|
|
1464
|
+
filename,
|
|
1465
|
+
node
|
|
1466
|
+
});
|
|
1467
|
+
else for (const key of Object.keys(value)) if (!BORDER_REQUIRED_PROPERTIES.includes(key)) report({
|
|
1468
|
+
messageId: ERROR_INVALID_PROP$3,
|
|
1469
|
+
data: { key: JSON.stringify(key) },
|
|
1470
|
+
node: getObjMember(node, key) ?? node,
|
|
1471
|
+
filename
|
|
1843
1472
|
});
|
|
1844
|
-
function validateString(value, { node, filename }) {
|
|
1845
|
-
if (typeof value !== "string") report({
|
|
1846
|
-
messageId: ERROR$2,
|
|
1847
|
-
node,
|
|
1848
|
-
filename
|
|
1849
|
-
});
|
|
1850
|
-
}
|
|
1851
1473
|
}
|
|
1852
1474
|
}
|
|
1853
1475
|
};
|
|
1854
|
-
var valid_string_default = rule$3;
|
|
1855
1476
|
|
|
1856
1477
|
//#endregion
|
|
1857
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1858
|
-
const
|
|
1859
|
-
const
|
|
1860
|
-
const
|
|
1861
|
-
const
|
|
1862
|
-
const
|
|
1863
|
-
const
|
|
1478
|
+
//#region src/lint/plugin-core/rules/valid-color.ts
|
|
1479
|
+
const VALID_COLOR = "core/valid-color";
|
|
1480
|
+
const ERROR_ALPHA = "ERROR_ALPHA";
|
|
1481
|
+
const ERROR_INVALID_COLOR = "ERROR_INVALID_COLOR";
|
|
1482
|
+
const ERROR_INVALID_COLOR_SPACE = "ERROR_INVALID_COLOR_SPACE";
|
|
1483
|
+
const ERROR_INVALID_COMPONENT_LENGTH = "ERROR_INVALID_COMPONENT_LENGTH";
|
|
1484
|
+
const ERROR_INVALID_HEX8 = "ERROR_INVALID_HEX8";
|
|
1485
|
+
const ERROR_INVALID_PROP$2 = "ERROR_INVALID_PROP";
|
|
1486
|
+
const ERROR_MISSING_COMPONENTS = "ERROR_MISSING_COMPONENTS";
|
|
1487
|
+
const ERROR_OBJ_FORMAT = "ERROR_OBJ_FORMAT";
|
|
1488
|
+
const ERROR_OUT_OF_RANGE = "ERROR_OUT_OF_RANGE";
|
|
1489
|
+
const rule$3 = {
|
|
1864
1490
|
meta: {
|
|
1865
1491
|
messages: {
|
|
1866
|
-
[
|
|
1867
|
-
[
|
|
1868
|
-
[
|
|
1869
|
-
[
|
|
1492
|
+
[ERROR_ALPHA]: `Alpha {{ alpha }} not in range 0 – 1.`,
|
|
1493
|
+
[ERROR_INVALID_COLOR_SPACE]: `Invalid color space: {{ colorSpace }}. Expected ${new Intl.ListFormat("en-us", { type: "disjunction" }).format(Object.keys(COLOR_SPACE))}.`,
|
|
1494
|
+
[ERROR_INVALID_COLOR]: `Could not parse color {{ color }}.`,
|
|
1495
|
+
[ERROR_INVALID_COMPONENT_LENGTH]: "Expected {{ expected }} components, received {{ got }}.",
|
|
1496
|
+
[ERROR_INVALID_HEX8]: `Hex value can’t be semi-transparent.`,
|
|
1497
|
+
[ERROR_INVALID_PROP$2]: `Unknown property {{ key }}.`,
|
|
1498
|
+
[ERROR_MISSING_COMPONENTS]: "Expected components to be array of numbers, received {{ got }}.",
|
|
1499
|
+
[ERROR_OBJ_FORMAT]: "Migrate to the new object format, e.g. \"#ff0000\" → { \"colorSpace\": \"srgb\", \"components\": [1, 0, 0] } }",
|
|
1500
|
+
[ERROR_OUT_OF_RANGE]: `Invalid range for color space {{ colorSpace }}. Expected {{ range }}.`
|
|
1870
1501
|
},
|
|
1871
1502
|
docs: {
|
|
1872
|
-
description: "Require
|
|
1873
|
-
url: docsLink(
|
|
1503
|
+
description: "Require color tokens to follow the format.",
|
|
1504
|
+
url: docsLink(VALID_COLOR)
|
|
1874
1505
|
}
|
|
1875
1506
|
},
|
|
1876
|
-
defaultOptions: {
|
|
1877
|
-
|
|
1507
|
+
defaultOptions: {
|
|
1508
|
+
legacyFormat: false,
|
|
1509
|
+
ignoreRanges: false
|
|
1510
|
+
},
|
|
1511
|
+
create({ tokens, options, report }) {
|
|
1878
1512
|
for (const t of Object.values(tokens)) {
|
|
1879
1513
|
if (t.aliasOf || !t.originalValue) continue;
|
|
1880
1514
|
switch (t.$type) {
|
|
1881
|
-
case "
|
|
1882
|
-
|
|
1515
|
+
case "color":
|
|
1516
|
+
validateColor(t.originalValue.$value, {
|
|
1883
1517
|
node: getObjMember(t.source.node, "$value"),
|
|
1884
1518
|
filename: t.source.filename
|
|
1885
1519
|
});
|
|
1886
1520
|
break;
|
|
1887
1521
|
case "border":
|
|
1888
|
-
if (t.originalValue.$value &&
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1522
|
+
if (t.originalValue.$value.color && !isAlias(t.originalValue.$value.color)) validateColor(t.originalValue.$value.color, {
|
|
1523
|
+
node: getObjMember(getObjMember(t.source.node, "$value"), "color"),
|
|
1524
|
+
filename: t.source.filename
|
|
1525
|
+
});
|
|
1526
|
+
break;
|
|
1527
|
+
case "gradient": {
|
|
1528
|
+
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1529
|
+
for (let i = 0; i < t.originalValue.$value.length; i++) {
|
|
1530
|
+
const stop = t.originalValue.$value[i];
|
|
1531
|
+
if (!stop.color || isAlias(stop.color)) continue;
|
|
1532
|
+
validateColor(stop.color, {
|
|
1533
|
+
node: getObjMember($valueNode.elements[i].value, "color"),
|
|
1534
|
+
filename: t.source.filename
|
|
1535
|
+
});
|
|
1536
|
+
}
|
|
1537
|
+
break;
|
|
1538
|
+
}
|
|
1539
|
+
case "shadow": {
|
|
1540
|
+
const $value = Array.isArray(t.originalValue.$value) ? t.originalValue.$value : [t.originalValue.$value];
|
|
1541
|
+
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1542
|
+
for (let i = 0; i < $value.length; i++) {
|
|
1543
|
+
const layer = $value[i];
|
|
1544
|
+
if (!layer.color || isAlias(layer.color)) continue;
|
|
1545
|
+
validateColor(layer.color, {
|
|
1546
|
+
node: $valueNode.type === "Object" ? getObjMember($valueNode, "color") : getObjMember($valueNode.elements[i].value, "color"),
|
|
1892
1547
|
filename: t.source.filename
|
|
1893
1548
|
});
|
|
1894
1549
|
}
|
|
1895
1550
|
break;
|
|
1551
|
+
}
|
|
1896
1552
|
}
|
|
1897
|
-
function
|
|
1898
|
-
if (
|
|
1899
|
-
|
|
1553
|
+
function validateColor(value, { node, filename }) {
|
|
1554
|
+
if (!value) report({
|
|
1555
|
+
messageId: ERROR_INVALID_COLOR,
|
|
1556
|
+
data: { color: JSON.stringify(value) },
|
|
1557
|
+
node,
|
|
1558
|
+
filename
|
|
1559
|
+
});
|
|
1560
|
+
else if (typeof value === "object") {
|
|
1561
|
+
for (const key of Object.keys(value)) if (![
|
|
1562
|
+
"colorSpace",
|
|
1563
|
+
"components",
|
|
1564
|
+
"channels",
|
|
1565
|
+
"hex",
|
|
1566
|
+
"alpha"
|
|
1567
|
+
].includes(key)) report({
|
|
1568
|
+
messageId: ERROR_INVALID_PROP$2,
|
|
1569
|
+
data: { key: JSON.stringify(key) },
|
|
1570
|
+
node: getObjMember(node, key) ?? node,
|
|
1571
|
+
filename
|
|
1572
|
+
});
|
|
1573
|
+
const colorSpace = "colorSpace" in value && typeof value.colorSpace === "string" ? value.colorSpace : void 0;
|
|
1574
|
+
const csData = COLOR_SPACE[colorSpace] || void 0;
|
|
1575
|
+
if (!("colorSpace" in value) || !csData) {
|
|
1900
1576
|
report({
|
|
1901
|
-
messageId:
|
|
1902
|
-
|
|
1577
|
+
messageId: ERROR_INVALID_COLOR_SPACE,
|
|
1578
|
+
data: { colorSpace },
|
|
1579
|
+
node: getObjMember(node, "colorSpace") ?? node,
|
|
1903
1580
|
filename
|
|
1904
1581
|
});
|
|
1905
1582
|
return;
|
|
1906
1583
|
}
|
|
1907
|
-
|
|
1908
|
-
if (
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1584
|
+
const components = "components" in value ? value.components : void 0;
|
|
1585
|
+
if (Array.isArray(components)) {
|
|
1586
|
+
const coords = Object.values(csData.coords);
|
|
1587
|
+
if (components?.length === coords.length) for (let i = 0; i < components.length; i++) {
|
|
1588
|
+
const range = coords[i]?.range ?? coords[i]?.refRange;
|
|
1589
|
+
if (!Number.isFinite(components[i]) || components[i] < (range?.[0] ?? -Infinity) || components[i] > (range?.[1] ?? Infinity)) {
|
|
1590
|
+
if (!(colorSpace === "hsl" && components[0] === null) && !(colorSpace === "hwb" && components[0] === null) && !(colorSpace === "lch" && components[2] === null) && !(colorSpace === "oklch" && components[2] === null)) report({
|
|
1591
|
+
messageId: ERROR_OUT_OF_RANGE,
|
|
1592
|
+
data: {
|
|
1593
|
+
colorSpace,
|
|
1594
|
+
range: `[${range?.[0]}–${range?.[1]}]`
|
|
1595
|
+
},
|
|
1596
|
+
node: getObjMember(node, "components") ?? node,
|
|
1597
|
+
filename
|
|
1598
|
+
});
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
else report({
|
|
1602
|
+
messageId: ERROR_INVALID_COMPONENT_LENGTH,
|
|
1603
|
+
data: {
|
|
1604
|
+
expected: coords.length ?? 0,
|
|
1605
|
+
got: components?.length
|
|
1606
|
+
},
|
|
1607
|
+
node: getObjMember(node, "components") ?? node,
|
|
1608
|
+
filename
|
|
1609
|
+
});
|
|
1610
|
+
} else report({
|
|
1611
|
+
messageId: ERROR_MISSING_COMPONENTS,
|
|
1612
|
+
data: { got: JSON.stringify(components) },
|
|
1613
|
+
node: getObjMember(node, "components") ?? node,
|
|
1916
1614
|
filename
|
|
1917
1615
|
});
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1616
|
+
const alpha = "alpha" in value ? value.alpha : void 0;
|
|
1617
|
+
if (alpha !== void 0 && (typeof alpha !== "number" || alpha < 0 || alpha > 1)) report({
|
|
1618
|
+
messageId: ERROR_ALPHA,
|
|
1619
|
+
data: { alpha },
|
|
1620
|
+
node: getObjMember(node, "alpha") ?? node,
|
|
1921
1621
|
filename
|
|
1922
1622
|
});
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1623
|
+
const hex = "hex" in value ? value.hex : void 0;
|
|
1624
|
+
if (hex) {
|
|
1625
|
+
let color;
|
|
1626
|
+
try {
|
|
1627
|
+
color = parseColor(hex);
|
|
1628
|
+
} catch {
|
|
1629
|
+
report({
|
|
1630
|
+
messageId: ERROR_INVALID_COLOR,
|
|
1631
|
+
data: { color: hex },
|
|
1632
|
+
node: getObjMember(node, "hex") ?? node,
|
|
1633
|
+
filename
|
|
1634
|
+
});
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1637
|
+
if (color.alpha !== 1) report({
|
|
1638
|
+
messageId: ERROR_INVALID_HEX8,
|
|
1639
|
+
data: { color: hex },
|
|
1640
|
+
node: getObjMember(node, "hex") ?? node,
|
|
1641
|
+
filename
|
|
1642
|
+
});
|
|
1643
|
+
}
|
|
1644
|
+
} else if (typeof value === "string") {
|
|
1645
|
+
if (isAlias(value)) return;
|
|
1646
|
+
if (!options.legacyFormat) report({
|
|
1647
|
+
messageId: ERROR_OBJ_FORMAT,
|
|
1648
|
+
data: { color: JSON.stringify(value) },
|
|
1649
|
+
node,
|
|
1927
1650
|
filename
|
|
1928
1651
|
});
|
|
1652
|
+
else try {
|
|
1653
|
+
parseColor(value);
|
|
1654
|
+
} catch {
|
|
1655
|
+
report({
|
|
1656
|
+
messageId: ERROR_INVALID_COLOR,
|
|
1657
|
+
data: { color: JSON.stringify(value) },
|
|
1658
|
+
node,
|
|
1659
|
+
filename
|
|
1660
|
+
});
|
|
1661
|
+
}
|
|
1929
1662
|
} else report({
|
|
1930
|
-
messageId:
|
|
1663
|
+
messageId: ERROR_INVALID_COLOR,
|
|
1931
1664
|
node,
|
|
1932
1665
|
filename
|
|
1933
1666
|
});
|
|
@@ -1935,92 +1668,316 @@ const rule$2 = {
|
|
|
1935
1668
|
}
|
|
1936
1669
|
}
|
|
1937
1670
|
};
|
|
1938
|
-
var valid_stroke_style_default = rule$2;
|
|
1939
1671
|
|
|
1940
1672
|
//#endregion
|
|
1941
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1942
|
-
const
|
|
1943
|
-
const ERROR
|
|
1944
|
-
const
|
|
1945
|
-
const
|
|
1673
|
+
//#region src/lint/plugin-core/rules/valid-cubic-bezier.ts
|
|
1674
|
+
const VALID_CUBIC_BEZIER = "core/valid-cubic-bezier";
|
|
1675
|
+
const ERROR = "ERROR";
|
|
1676
|
+
const ERROR_X = "ERROR_X";
|
|
1677
|
+
const ERROR_Y = "ERROR_Y";
|
|
1678
|
+
const rule$2 = {
|
|
1946
1679
|
meta: {
|
|
1947
1680
|
messages: {
|
|
1948
|
-
[ERROR
|
|
1949
|
-
[
|
|
1681
|
+
[ERROR]: "Expected [number, number, number, number].",
|
|
1682
|
+
[ERROR_X]: "x values must be between 0-1.",
|
|
1683
|
+
[ERROR_Y]: "y values must be a valid number."
|
|
1950
1684
|
},
|
|
1951
1685
|
docs: {
|
|
1952
|
-
description: "Require
|
|
1953
|
-
url: docsLink(
|
|
1686
|
+
description: "Require cubicBezier tokens to follow the format.",
|
|
1687
|
+
url: docsLink(VALID_CUBIC_BEZIER)
|
|
1954
1688
|
}
|
|
1955
1689
|
},
|
|
1956
1690
|
defaultOptions: {},
|
|
1957
1691
|
create({ tokens, report }) {
|
|
1958
1692
|
for (const t of Object.values(tokens)) {
|
|
1959
|
-
if (t.aliasOf || !t.originalValue
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1693
|
+
if (t.aliasOf || !t.originalValue) continue;
|
|
1694
|
+
switch (t.$type) {
|
|
1695
|
+
case "cubicBezier":
|
|
1696
|
+
validateCubicBezier(t.originalValue.$value, {
|
|
1697
|
+
node: getObjMember(t.source.node, "$value"),
|
|
1698
|
+
filename: t.source.filename
|
|
1699
|
+
});
|
|
1700
|
+
break;
|
|
1701
|
+
case "transition": if (typeof t.originalValue.$value === "object" && t.originalValue.$value.timingFunction && !isAlias(t.originalValue.$value.timingFunction)) {
|
|
1702
|
+
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1703
|
+
validateCubicBezier(t.originalValue.$value.timingFunction, {
|
|
1704
|
+
node: getObjMember($valueNode, "timingFunction"),
|
|
1705
|
+
filename: t.source.filename
|
|
1706
|
+
});
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
function validateCubicBezier(value, { node, filename }) {
|
|
1710
|
+
if (Array.isArray(value) && value.length === 4) {
|
|
1711
|
+
for (const pos of [0, 2]) {
|
|
1712
|
+
if (isAlias(value[pos]) || isPure$ref(value[pos])) continue;
|
|
1713
|
+
if (!(value[pos] >= 0 && value[pos] <= 1)) report({
|
|
1714
|
+
messageId: ERROR_X,
|
|
1715
|
+
node: node.elements[pos],
|
|
1716
|
+
filename
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1719
|
+
for (const pos of [1, 3]) {
|
|
1720
|
+
if (isAlias(value[pos]) || isPure$ref(value[pos])) continue;
|
|
1721
|
+
if (typeof value[pos] !== "number") report({
|
|
1722
|
+
messageId: ERROR_Y,
|
|
1723
|
+
node: node.elements[pos],
|
|
1724
|
+
filename
|
|
1725
|
+
});
|
|
1726
|
+
}
|
|
1727
|
+
} else report({
|
|
1728
|
+
messageId: ERROR,
|
|
1729
|
+
node,
|
|
1730
|
+
filename
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1964
1733
|
}
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1734
|
+
}
|
|
1735
|
+
};
|
|
1736
|
+
|
|
1737
|
+
//#endregion
|
|
1738
|
+
//#region src/lint/plugin-core/rules/valid-dimension.ts
|
|
1739
|
+
const VALID_DIMENSION = "core/valid-dimension";
|
|
1740
|
+
const ERROR_FORMAT$1 = "ERROR_FORMAT";
|
|
1741
|
+
const ERROR_INVALID_PROP$1 = "ERROR_INVALID_PROP";
|
|
1742
|
+
const ERROR_LEGACY$1 = "ERROR_LEGACY";
|
|
1743
|
+
const ERROR_UNIT$1 = "ERROR_UNIT";
|
|
1744
|
+
const ERROR_VALUE$1 = "ERROR_VALUE";
|
|
1745
|
+
const rule$1 = {
|
|
1746
|
+
meta: {
|
|
1747
|
+
messages: {
|
|
1748
|
+
[ERROR_FORMAT$1]: "Invalid dimension: {{ value }}. Expected object with \"value\" and \"unit\".",
|
|
1749
|
+
[ERROR_LEGACY$1]: "Migrate to the new object format: { \"value\": 10, \"unit\": \"px\" }.",
|
|
1750
|
+
[ERROR_UNIT$1]: "Unit {{ unit }} not allowed. Expected {{ allowed }}.",
|
|
1751
|
+
[ERROR_INVALID_PROP$1]: "Unknown property {{ key }}.",
|
|
1752
|
+
[ERROR_VALUE$1]: "Expected number, received {{ value }}."
|
|
1753
|
+
},
|
|
1754
|
+
docs: {
|
|
1755
|
+
description: "Require dimension tokens to follow the format",
|
|
1756
|
+
url: docsLink(VALID_DIMENSION)
|
|
1757
|
+
}
|
|
1758
|
+
},
|
|
1759
|
+
defaultOptions: {
|
|
1760
|
+
legacyFormat: false,
|
|
1761
|
+
allowedUnits: [
|
|
1762
|
+
"px",
|
|
1763
|
+
"em",
|
|
1764
|
+
"rem"
|
|
1765
|
+
]
|
|
1766
|
+
},
|
|
1767
|
+
create({ tokens, options, report }) {
|
|
1768
|
+
for (const t of Object.values(tokens)) {
|
|
1769
|
+
if (t.aliasOf || !t.originalValue) continue;
|
|
1770
|
+
switch (t.$type) {
|
|
1771
|
+
case "dimension":
|
|
1772
|
+
validateDimension(t.originalValue.$value, {
|
|
1773
|
+
node: getObjMember(t.source.node, "$value"),
|
|
1774
|
+
filename: t.source.filename
|
|
1775
|
+
});
|
|
1776
|
+
break;
|
|
1777
|
+
case "strokeStyle":
|
|
1778
|
+
if (typeof t.originalValue.$value === "object" && Array.isArray(t.originalValue.$value.dashArray)) {
|
|
1779
|
+
const dashArray = getObjMember(getObjMember(t.source.node, "$value"), "dashArray");
|
|
1780
|
+
for (let i = 0; i < t.originalValue.$value.dashArray.length; i++) {
|
|
1781
|
+
if (isAlias(t.originalValue.$value.dashArray[i])) continue;
|
|
1782
|
+
validateDimension(t.originalValue.$value.dashArray[i], {
|
|
1783
|
+
node: dashArray.elements[i].value,
|
|
1784
|
+
filename: t.source.filename
|
|
1785
|
+
});
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
break;
|
|
1789
|
+
case "border": {
|
|
1790
|
+
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1791
|
+
if (typeof t.originalValue.$value === "object") {
|
|
1792
|
+
if (t.originalValue.$value.width && !isAlias(t.originalValue.$value.width)) validateDimension(t.originalValue.$value.width, {
|
|
1793
|
+
node: getObjMember($valueNode, "width"),
|
|
1794
|
+
filename: t.source.filename
|
|
1795
|
+
});
|
|
1796
|
+
if (typeof t.originalValue.$value.style === "object" && Array.isArray(t.originalValue.$value.style.dashArray)) {
|
|
1797
|
+
const dashArray = getObjMember(getObjMember($valueNode, "style"), "dashArray");
|
|
1798
|
+
for (let i = 0; i < t.originalValue.$value.style.dashArray.length; i++) {
|
|
1799
|
+
if (isAlias(t.originalValue.$value.style.dashArray[i])) continue;
|
|
1800
|
+
validateDimension(t.originalValue.$value.style.dashArray[i], {
|
|
1801
|
+
node: dashArray.elements[i].value,
|
|
1802
|
+
filename: t.source.filename
|
|
1803
|
+
});
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
break;
|
|
1808
|
+
}
|
|
1809
|
+
case "shadow":
|
|
1810
|
+
if (t.originalValue.$value && typeof t.originalValue.$value === "object") {
|
|
1811
|
+
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1812
|
+
const valueArray = Array.isArray(t.originalValue.$value) ? t.originalValue.$value : [t.originalValue.$value];
|
|
1813
|
+
for (let i = 0; i < valueArray.length; i++) {
|
|
1814
|
+
const node = $valueNode.type === "Array" ? $valueNode.elements[i].value : $valueNode;
|
|
1815
|
+
for (const property of [
|
|
1816
|
+
"offsetX",
|
|
1817
|
+
"offsetY",
|
|
1818
|
+
"blur",
|
|
1819
|
+
"spread"
|
|
1820
|
+
]) {
|
|
1821
|
+
if (isAlias(valueArray[i][property])) continue;
|
|
1822
|
+
validateDimension(valueArray[i][property], {
|
|
1823
|
+
node: getObjMember(node, property),
|
|
1824
|
+
filename: t.source.filename
|
|
1825
|
+
});
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
break;
|
|
1830
|
+
case "typography": {
|
|
1831
|
+
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1832
|
+
if (typeof t.originalValue.$value === "object") {
|
|
1833
|
+
for (const property of [
|
|
1834
|
+
"fontSize",
|
|
1835
|
+
"lineHeight",
|
|
1836
|
+
"letterSpacing"
|
|
1837
|
+
]) if (property in t.originalValue.$value) {
|
|
1838
|
+
if (isAlias(t.originalValue.$value[property]) || property === "lineHeight" && typeof t.originalValue.$value[property] === "number") continue;
|
|
1839
|
+
validateDimension(t.originalValue.$value[property], {
|
|
1840
|
+
node: getObjMember($valueNode, property),
|
|
1841
|
+
filename: t.source.filename
|
|
1842
|
+
});
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
break;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
function validateDimension(value, { node, filename }) {
|
|
1849
|
+
if (value && typeof value === "object") {
|
|
1850
|
+
for (const key of Object.keys(value)) if (!["value", "unit"].includes(key)) report({
|
|
1851
|
+
messageId: ERROR_INVALID_PROP$1,
|
|
1852
|
+
data: { key: JSON.stringify(key) },
|
|
1853
|
+
node: getObjMember(node, key) ?? node,
|
|
1854
|
+
filename
|
|
1855
|
+
});
|
|
1856
|
+
const { unit, value: numValue } = value;
|
|
1857
|
+
if (!("value" in value || "unit" in value)) {
|
|
1858
|
+
report({
|
|
1859
|
+
messageId: ERROR_FORMAT$1,
|
|
1860
|
+
data: { value },
|
|
1861
|
+
node,
|
|
1862
|
+
filename
|
|
1863
|
+
});
|
|
1864
|
+
return;
|
|
1865
|
+
}
|
|
1866
|
+
if (!options.allowedUnits.includes(unit)) report({
|
|
1867
|
+
messageId: ERROR_UNIT$1,
|
|
1868
|
+
data: {
|
|
1869
|
+
unit,
|
|
1870
|
+
allowed: new Intl.ListFormat("en-us", { type: "disjunction" }).format(options.allowedUnits)
|
|
1871
|
+
},
|
|
1872
|
+
node: getObjMember(node, "unit") ?? node,
|
|
1873
|
+
filename
|
|
1874
|
+
});
|
|
1875
|
+
if (!Number.isFinite(numValue)) report({
|
|
1876
|
+
messageId: ERROR_VALUE$1,
|
|
1877
|
+
data: { value },
|
|
1878
|
+
node: getObjMember(node, "value") ?? node,
|
|
1879
|
+
filename
|
|
1880
|
+
});
|
|
1881
|
+
} else if (typeof value === "string" && !options.legacyFormat) report({
|
|
1882
|
+
messageId: ERROR_LEGACY$1,
|
|
1883
|
+
node,
|
|
1884
|
+
filename
|
|
1885
|
+
});
|
|
1886
|
+
else report({
|
|
1887
|
+
messageId: ERROR_FORMAT$1,
|
|
1888
|
+
data: { value },
|
|
1889
|
+
node,
|
|
1890
|
+
filename
|
|
1891
|
+
});
|
|
1892
|
+
}
|
|
1977
1893
|
}
|
|
1978
1894
|
}
|
|
1979
1895
|
};
|
|
1980
|
-
var valid_transition_default = rule$1;
|
|
1981
1896
|
|
|
1982
1897
|
//#endregion
|
|
1983
|
-
//#region src/lint/plugin-core/rules/valid-
|
|
1984
|
-
const
|
|
1985
|
-
const
|
|
1986
|
-
const
|
|
1898
|
+
//#region src/lint/plugin-core/rules/valid-duration.ts
|
|
1899
|
+
const VALID_DURATION = "core/valid-duration";
|
|
1900
|
+
const ERROR_FORMAT = "ERROR_FORMAT";
|
|
1901
|
+
const ERROR_INVALID_PROP = "ERROR_INVALID_PROP";
|
|
1902
|
+
const ERROR_LEGACY = "ERROR_LEGACY";
|
|
1903
|
+
const ERROR_UNIT = "ERROR_UNIT";
|
|
1904
|
+
const ERROR_VALUE = "ERROR_VALUE";
|
|
1987
1905
|
const rule = {
|
|
1988
1906
|
meta: {
|
|
1989
1907
|
messages: {
|
|
1990
|
-
[
|
|
1991
|
-
[
|
|
1908
|
+
[ERROR_FORMAT]: "Migrate to the new object format: { \"value\": 2, \"unit\": \"ms\" }.",
|
|
1909
|
+
[ERROR_LEGACY]: "Migrate to the new object format: { \"value\": 10, \"unit\": \"px\" }.",
|
|
1910
|
+
[ERROR_INVALID_PROP]: "Unknown property: {{ key }}.",
|
|
1911
|
+
[ERROR_UNIT]: "Unknown unit {{ unit }}. Expected \"ms\" or \"s\".",
|
|
1912
|
+
[ERROR_VALUE]: "Expected number, received {{ value }}."
|
|
1992
1913
|
},
|
|
1993
1914
|
docs: {
|
|
1994
|
-
description: "Require
|
|
1995
|
-
url: docsLink(
|
|
1915
|
+
description: "Require duration tokens to follow the format",
|
|
1916
|
+
url: docsLink(VALID_DURATION)
|
|
1996
1917
|
}
|
|
1997
1918
|
},
|
|
1998
|
-
defaultOptions: {
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
"letterSpacing",
|
|
2003
|
-
"lineHeight"
|
|
2004
|
-
] },
|
|
1919
|
+
defaultOptions: {
|
|
1920
|
+
legacyFormat: false,
|
|
1921
|
+
unknownUnits: false
|
|
1922
|
+
},
|
|
2005
1923
|
create({ tokens, options, report }) {
|
|
2006
|
-
const isIgnored = options.ignore ? wcmatch(options.ignore) : () => false;
|
|
2007
1924
|
for (const t of Object.values(tokens)) {
|
|
2008
|
-
if (t.aliasOf || !t.originalValue
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
1925
|
+
if (t.aliasOf || !t.originalValue) continue;
|
|
1926
|
+
switch (t.$type) {
|
|
1927
|
+
case "duration":
|
|
1928
|
+
validateDuration(t.originalValue.$value, {
|
|
1929
|
+
node: getObjMember(t.source.node, "$value"),
|
|
1930
|
+
filename: t.source.filename
|
|
1931
|
+
});
|
|
1932
|
+
break;
|
|
1933
|
+
case "transition":
|
|
1934
|
+
if (typeof t.originalValue.$value === "object") {
|
|
1935
|
+
const $valueNode = getObjMember(t.source.node, "$value");
|
|
1936
|
+
for (const property of ["duration", "delay"]) if (t.originalValue.$value[property] && !isAlias(t.originalValue.$value[property])) validateDuration(t.originalValue.$value[property], {
|
|
1937
|
+
node: getObjMember($valueNode, property),
|
|
1938
|
+
filename: t.source.filename
|
|
1939
|
+
});
|
|
1940
|
+
}
|
|
1941
|
+
break;
|
|
1942
|
+
}
|
|
1943
|
+
function validateDuration(value, { node, filename }) {
|
|
2014
1944
|
if (value && typeof value === "object") {
|
|
2015
|
-
for (const
|
|
2016
|
-
messageId:
|
|
2017
|
-
data: {
|
|
2018
|
-
node,
|
|
1945
|
+
for (const key of Object.keys(value)) if (!["value", "unit"].includes(key)) report({
|
|
1946
|
+
messageId: ERROR_INVALID_PROP,
|
|
1947
|
+
data: { key: JSON.stringify(key) },
|
|
1948
|
+
node: getObjMember(node, key) ?? node,
|
|
2019
1949
|
filename
|
|
2020
1950
|
});
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
1951
|
+
const { unit, value: numValue } = value;
|
|
1952
|
+
if (!("value" in value || "unit" in value)) {
|
|
1953
|
+
report({
|
|
1954
|
+
messageId: ERROR_FORMAT,
|
|
1955
|
+
data: { value },
|
|
1956
|
+
node,
|
|
1957
|
+
filename
|
|
1958
|
+
});
|
|
1959
|
+
return;
|
|
1960
|
+
}
|
|
1961
|
+
if (!options.unknownUnits && !["ms", "s"].includes(unit)) report({
|
|
1962
|
+
messageId: ERROR_UNIT,
|
|
1963
|
+
data: { unit },
|
|
1964
|
+
node: getObjMember(node, "unit") ?? node,
|
|
1965
|
+
filename
|
|
1966
|
+
});
|
|
1967
|
+
if (!Number.isFinite(numValue)) report({
|
|
1968
|
+
messageId: ERROR_VALUE,
|
|
1969
|
+
data: { value },
|
|
1970
|
+
node: getObjMember(node, "value") ?? node,
|
|
1971
|
+
filename
|
|
1972
|
+
});
|
|
1973
|
+
} else if (typeof value === "string" && !options.legacyFormat) report({
|
|
1974
|
+
messageId: ERROR_FORMAT,
|
|
1975
|
+
node,
|
|
1976
|
+
filename
|
|
1977
|
+
});
|
|
1978
|
+
else report({
|
|
1979
|
+
messageId: ERROR_FORMAT,
|
|
1980
|
+
data: { value },
|
|
2024
1981
|
node,
|
|
2025
1982
|
filename
|
|
2026
1983
|
});
|
|
@@ -2028,38 +1985,37 @@ const rule = {
|
|
|
2028
1985
|
}
|
|
2029
1986
|
}
|
|
2030
1987
|
};
|
|
2031
|
-
var valid_typography_default = rule;
|
|
2032
1988
|
|
|
2033
1989
|
//#endregion
|
|
2034
1990
|
//#region src/lint/plugin-core/index.ts
|
|
2035
1991
|
const ALL_RULES = {
|
|
2036
|
-
[VALID_COLOR]:
|
|
2037
|
-
[VALID_DIMENSION]:
|
|
2038
|
-
[VALID_FONT_FAMILY]:
|
|
2039
|
-
[VALID_FONT_WEIGHT]:
|
|
2040
|
-
[VALID_DURATION]:
|
|
2041
|
-
[VALID_CUBIC_BEZIER]:
|
|
2042
|
-
[VALID_NUMBER]:
|
|
2043
|
-
[VALID_LINK]:
|
|
2044
|
-
[VALID_BOOLEAN]:
|
|
2045
|
-
[VALID_STRING]:
|
|
2046
|
-
[VALID_STROKE_STYLE]:
|
|
2047
|
-
[VALID_BORDER]:
|
|
2048
|
-
[VALID_TRANSITION]:
|
|
2049
|
-
[VALID_SHADOW]:
|
|
2050
|
-
[VALID_GRADIENT]:
|
|
2051
|
-
[VALID_TYPOGRAPHY]:
|
|
2052
|
-
[COLORSPACE
|
|
2053
|
-
[CONSISTENT_NAMING]:
|
|
2054
|
-
[DESCRIPTIONS]:
|
|
2055
|
-
[DUPLICATE_VALUES]:
|
|
2056
|
-
[MAX_GAMUT]:
|
|
2057
|
-
[REQUIRED_CHILDREN]:
|
|
2058
|
-
[REQUIRED_MODES]:
|
|
2059
|
-
[REQUIRED_TYPE]:
|
|
2060
|
-
[REQUIRED_TYPOGRAPHY_PROPERTIES]:
|
|
2061
|
-
[A11Y_MIN_CONTRAST]:
|
|
2062
|
-
[A11Y_MIN_FONT_SIZE]:
|
|
1992
|
+
[VALID_COLOR]: rule$3,
|
|
1993
|
+
[VALID_DIMENSION]: rule$1,
|
|
1994
|
+
[VALID_FONT_FAMILY]: rule$15,
|
|
1995
|
+
[VALID_FONT_WEIGHT]: rule$14,
|
|
1996
|
+
[VALID_DURATION]: rule,
|
|
1997
|
+
[VALID_CUBIC_BEZIER]: rule$2,
|
|
1998
|
+
[VALID_NUMBER]: rule$11,
|
|
1999
|
+
[VALID_LINK]: rule$12,
|
|
2000
|
+
[VALID_BOOLEAN]: rule$5,
|
|
2001
|
+
[VALID_STRING]: rule$9,
|
|
2002
|
+
[VALID_STROKE_STYLE]: rule$8,
|
|
2003
|
+
[VALID_BORDER]: rule$4,
|
|
2004
|
+
[VALID_TRANSITION]: rule$7,
|
|
2005
|
+
[VALID_SHADOW]: rule$10,
|
|
2006
|
+
[VALID_GRADIENT]: rule$13,
|
|
2007
|
+
[VALID_TYPOGRAPHY]: rule$6,
|
|
2008
|
+
[COLORSPACE]: rule$24,
|
|
2009
|
+
[CONSISTENT_NAMING]: rule$23,
|
|
2010
|
+
[DESCRIPTIONS]: rule$22,
|
|
2011
|
+
[DUPLICATE_VALUES]: rule$21,
|
|
2012
|
+
[MAX_GAMUT]: rule$20,
|
|
2013
|
+
[REQUIRED_CHILDREN]: rule$19,
|
|
2014
|
+
[REQUIRED_MODES]: rule$18,
|
|
2015
|
+
[REQUIRED_TYPE]: rule$17,
|
|
2016
|
+
[REQUIRED_TYPOGRAPHY_PROPERTIES]: rule$16,
|
|
2017
|
+
[A11Y_MIN_CONTRAST]: rule$26,
|
|
2018
|
+
[A11Y_MIN_FONT_SIZE]: rule$25
|
|
2063
2019
|
};
|
|
2064
2020
|
function coreLintPlugin() {
|
|
2065
2021
|
return {
|
|
@@ -2245,13 +2201,13 @@ function normalizeLint({ config, logger }) {
|
|
|
2245
2201
|
});
|
|
2246
2202
|
continue;
|
|
2247
2203
|
}
|
|
2248
|
-
for (const rule
|
|
2249
|
-
if (allRules.get(rule
|
|
2204
|
+
for (const rule of Object.keys(pluginRules)) {
|
|
2205
|
+
if (allRules.get(rule) && allRules.get(rule) !== plugin.name) logger.error({
|
|
2250
2206
|
group: "config",
|
|
2251
2207
|
label: `plugin › ${plugin.name}`,
|
|
2252
|
-
message: `Duplicate rule ${rule
|
|
2208
|
+
message: `Duplicate rule ${rule} already registered by plugin ${allRules.get(rule)}`
|
|
2253
2209
|
});
|
|
2254
|
-
allRules.set(rule
|
|
2210
|
+
allRules.set(rule, plugin.name);
|
|
2255
2211
|
}
|
|
2256
2212
|
}
|
|
2257
2213
|
for (const id of Object.keys(config.lint.rules)) {
|
|
@@ -2334,13 +2290,13 @@ async function lintRunner({ tokens, filename, config = {}, sources, logger }) {
|
|
|
2334
2290
|
for (const plugin of plugins) if (typeof plugin.lint === "function") {
|
|
2335
2291
|
const s = performance.now();
|
|
2336
2292
|
const linter = plugin.lint();
|
|
2337
|
-
await Promise.all(Object.entries(linter).map(async ([id, rule
|
|
2293
|
+
await Promise.all(Object.entries(linter).map(async ([id, rule]) => {
|
|
2338
2294
|
if (!(id in lint.rules) || lint.rules[id] === null) return;
|
|
2339
2295
|
const unusedLintRuleI = unusedLintRules.indexOf(id);
|
|
2340
2296
|
if (unusedLintRuleI !== -1) unusedLintRules.splice(unusedLintRuleI, 1);
|
|
2341
2297
|
const [severity, options] = lint.rules[id];
|
|
2342
2298
|
if (severity === "off") return;
|
|
2343
|
-
await rule
|
|
2299
|
+
await rule.create({
|
|
2344
2300
|
id,
|
|
2345
2301
|
report(descriptor) {
|
|
2346
2302
|
let message = "";
|
|
@@ -2351,12 +2307,12 @@ async function lintRunner({ tokens, filename, config = {}, sources, logger }) {
|
|
|
2351
2307
|
});
|
|
2352
2308
|
if (descriptor.message) message = descriptor.message;
|
|
2353
2309
|
else {
|
|
2354
|
-
if (!(descriptor.messageId in (rule
|
|
2310
|
+
if (!(descriptor.messageId in (rule.meta?.messages ?? {}))) logger.error({
|
|
2355
2311
|
group: "lint",
|
|
2356
2312
|
label: `${plugin.name} › lint › ${id}`,
|
|
2357
2313
|
message: `messageId "${descriptor.messageId}" does not exist`
|
|
2358
2314
|
});
|
|
2359
|
-
message = rule
|
|
2315
|
+
message = rule.meta?.messages?.[descriptor.messageId] ?? "";
|
|
2360
2316
|
}
|
|
2361
2317
|
if (descriptor.data && typeof descriptor.data === "object") for (const [k, v] of Object.entries(descriptor.data)) {
|
|
2362
2318
|
const formatted = [
|
|
@@ -2380,7 +2336,7 @@ async function lintRunner({ tokens, filename, config = {}, sources, logger }) {
|
|
|
2380
2336
|
tokens,
|
|
2381
2337
|
filename,
|
|
2382
2338
|
sources,
|
|
2383
|
-
options: merge(rule
|
|
2339
|
+
options: merge(rule.meta?.defaultOptions ?? [], rule.defaultOptions ?? [], options)
|
|
2384
2340
|
});
|
|
2385
2341
|
}));
|
|
2386
2342
|
logger.debug({
|
|
@@ -2840,7 +2796,9 @@ const EXPECTED_NESTED_ALIAS = {
|
|
|
2840
2796
|
fontWeight: ["fontWeight"],
|
|
2841
2797
|
fontSize: ["dimension"],
|
|
2842
2798
|
lineHeight: ["dimension", "number"],
|
|
2843
|
-
letterSpacing: ["dimension"]
|
|
2799
|
+
letterSpacing: ["dimension"],
|
|
2800
|
+
paragraphSpacing: ["dimension", "string"],
|
|
2801
|
+
wordSpacing: ["dimension", "string"]
|
|
2844
2802
|
}
|
|
2845
2803
|
};
|
|
2846
2804
|
/**
|
|
@@ -3737,12 +3695,12 @@ function createResolver(resolverSource, { config, logger, sources }) {
|
|
|
3737
3695
|
break;
|
|
3738
3696
|
case "modifier": {
|
|
3739
3697
|
const context = input[item.name];
|
|
3740
|
-
const sources
|
|
3741
|
-
if (!sources
|
|
3698
|
+
const sources = item.contexts[context];
|
|
3699
|
+
if (!sources) logger.error({
|
|
3742
3700
|
group: "resolver",
|
|
3743
3701
|
message: `Modifier ${item.name} has no context ${JSON.stringify(context)}.`
|
|
3744
3702
|
});
|
|
3745
|
-
for (const s of sources
|
|
3703
|
+
for (const s of sources ?? []) tokensRaw = merge(tokensRaw, s);
|
|
3746
3704
|
break;
|
|
3747
3705
|
}
|
|
3748
3706
|
}
|