@tokenoftrust/cli 4.4.1 → 4.4.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/package.json +1 -1
- package/src/declared-config.d.mts +5 -0
- package/src/declared-config.mjs +43 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/cli",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.2",
|
|
4
4
|
"description": "Token of Trust developer CLI — clone a tenant store, run it locally with save→reload, and submit it for preview. Installs the `tot` command.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Token of Trust",
|
|
@@ -68,6 +68,9 @@ export interface NicotineWarningPresentation {
|
|
|
68
68
|
textTransform: "uppercase" | "none";
|
|
69
69
|
fontWeight: number;
|
|
70
70
|
fontSizePx: number;
|
|
71
|
+
borderWidthPx?: number;
|
|
72
|
+
paddingYPx?: number;
|
|
73
|
+
letterSpacingPx?: number;
|
|
71
74
|
}
|
|
72
75
|
export interface ResolvedNicotineWarning {
|
|
73
76
|
enabled: boolean;
|
|
@@ -79,6 +82,8 @@ export interface ResolvedNicotineWarning {
|
|
|
79
82
|
export const NICOTINE_WARNING_TEXT: string;
|
|
80
83
|
export const CONSPICUITY_FLOOR: Readonly<{ contrast: number; fontSizePx: number; fontWeight: number }>;
|
|
81
84
|
export const DEFAULT_NICOTINE_WARNING_PRESET: string;
|
|
85
|
+
export const NICOTINE_WARNING_BOX_BOUNDS: Readonly<Record<"borderWidthPx" | "paddingYPx" | "letterSpacingPx", Readonly<{ min: number; max: number; integer: boolean }>>>;
|
|
86
|
+
export const MEDIUM_WEIGHT_REQUIREMENTS: Readonly<{ fontSizePx: number; contrast: number; borderWidthPx: number }>;
|
|
82
87
|
export const NICOTINE_WARNING_PRESETS: Readonly<Record<string, Readonly<NicotineWarningPresentation>>>;
|
|
83
88
|
export const NICOTINE_WARNING_KEYS: readonly string[];
|
|
84
89
|
export const NICOTINE_WARNING_STYLE_KEYS: readonly string[];
|
package/src/declared-config.mjs
CHANGED
|
@@ -782,6 +782,16 @@ export const CONSPICUITY_FLOOR = Object.freeze({ contrast: 7, fontSizePx: 12, fo
|
|
|
782
782
|
/** Bounds on the size a custom style may declare, so the bar cannot swallow the header. */
|
|
783
783
|
const MAX_FONT_SIZE_PX = 24;
|
|
784
784
|
|
|
785
|
+
/** Bounds on the optional box and spacing keys; an unset key renders the preset's own frame. */
|
|
786
|
+
export const NICOTINE_WARNING_BOX_BOUNDS = Object.freeze({
|
|
787
|
+
borderWidthPx: Object.freeze({ min: 0, max: 8, integer: true }),
|
|
788
|
+
paddingYPx: Object.freeze({ min: 0, max: 24, integer: true }),
|
|
789
|
+
letterSpacingPx: Object.freeze({ min: 0, max: 4, integer: false }),
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
/** Weight 500 is allowed only on a boxed bar that is at least this large, contrasty and bordered. */
|
|
793
|
+
export const MEDIUM_WEIGHT_REQUIREMENTS = Object.freeze({ fontSizePx: 16, contrast: 7, borderWidthPx: 2 });
|
|
794
|
+
|
|
785
795
|
export const DEFAULT_NICOTINE_WARNING_PRESET = "dark";
|
|
786
796
|
|
|
787
797
|
/**
|
|
@@ -816,6 +826,9 @@ export const NICOTINE_WARNING_PRESETS = Object.freeze({
|
|
|
816
826
|
* textTransform: "uppercase" | "none",
|
|
817
827
|
* fontWeight: number,
|
|
818
828
|
* fontSizePx: number,
|
|
829
|
+
* borderWidthPx?: number,
|
|
830
|
+
* paddingYPx?: number,
|
|
831
|
+
* letterSpacingPx?: number,
|
|
819
832
|
* }} NicotineWarningPresentation
|
|
820
833
|
*/
|
|
821
834
|
|
|
@@ -824,9 +837,10 @@ export const NICOTINE_WARNING_KEYS = Object.freeze(["preset", "style", "checkWid
|
|
|
824
837
|
|
|
825
838
|
export const NICOTINE_WARNING_STYLE_KEYS = Object.freeze([
|
|
826
839
|
"background", "text", "border", "textTransform", "fontWeight", "fontSizePx",
|
|
840
|
+
"borderWidthPx", "paddingYPx", "letterSpacingPx",
|
|
827
841
|
]);
|
|
828
842
|
const TEXT_TRANSFORMS = ["uppercase", "none"];
|
|
829
|
-
const FONT_WEIGHTS = [600, 700, 800, 900];
|
|
843
|
+
const FONT_WEIGHTS = [500, 600, 700, 800, 900];
|
|
830
844
|
const HEX = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
|
|
831
845
|
|
|
832
846
|
/** `#abc` / `#AABBCC` → `#aabbcc`. */
|
|
@@ -865,7 +879,15 @@ export function conspicuityProblems(p) {
|
|
|
865
879
|
out.push(`font size ${p.fontSizePx}px is below the ${CONSPICUITY_FLOOR.fontSizePx}px floor`);
|
|
866
880
|
}
|
|
867
881
|
if (p.fontWeight < CONSPICUITY_FLOOR.fontWeight) {
|
|
868
|
-
|
|
882
|
+
const need = MEDIUM_WEIGHT_REQUIREMENTS;
|
|
883
|
+
const medium = p.fontWeight === 500 && p.fontSizePx >= need.fontSizePx && ratio >= need.contrast
|
|
884
|
+
&& (p.borderWidthPx ?? 0) >= need.borderWidthPx;
|
|
885
|
+
if (!medium) {
|
|
886
|
+
out.push(`font weight ${p.fontWeight} is below the ${CONSPICUITY_FLOOR.fontWeight} floor` +
|
|
887
|
+
(p.fontWeight === 500
|
|
888
|
+
? ` (500 needs font size >= ${need.fontSizePx}px, contrast >= ${need.contrast}:1 and borderWidthPx >= ${need.borderWidthPx})`
|
|
889
|
+
: ""));
|
|
890
|
+
}
|
|
869
891
|
}
|
|
870
892
|
return out;
|
|
871
893
|
}
|
|
@@ -885,6 +907,14 @@ function styleValueProblem(key, value) {
|
|
|
885
907
|
return typeof value === "number" && Number.isFinite(value) && value >= CONSPICUITY_FLOOR.fontSizePx && value <= MAX_FONT_SIZE_PX
|
|
886
908
|
? null
|
|
887
909
|
: `\`fontSizePx\` must be a number from ${CONSPICUITY_FLOOR.fontSizePx} to ${MAX_FONT_SIZE_PX}`;
|
|
910
|
+
case "borderWidthPx":
|
|
911
|
+
case "paddingYPx":
|
|
912
|
+
case "letterSpacingPx": {
|
|
913
|
+
const { min, max, integer } = NICOTINE_WARNING_BOX_BOUNDS[key];
|
|
914
|
+
return typeof value === "number" && Number.isFinite(value) && value >= min && value <= max && (!integer || Number.isInteger(value))
|
|
915
|
+
? null
|
|
916
|
+
: `\`${key}\` must be ${integer ? "a whole number" : "a number"} from ${min} to ${max}`;
|
|
917
|
+
}
|
|
888
918
|
default:
|
|
889
919
|
return `\`${key}\` is not a nicotine-warning style key (allowed: ${NICOTINE_WARNING_STYLE_KEYS.join(", ")})`;
|
|
890
920
|
}
|
|
@@ -993,7 +1023,10 @@ export function nicotineWarningCheckWidths(declaration) {
|
|
|
993
1023
|
*/
|
|
994
1024
|
export function describeNicotineWarningPresentation(p) {
|
|
995
1025
|
return `background ${p.background}, text ${p.text}, border ${p.border}, ` +
|
|
996
|
-
`${p.textTransform === "uppercase" ? "uppercase" : "normal case"}, weight ${p.fontWeight}, ${p.fontSizePx}px
|
|
1026
|
+
`${p.textTransform === "uppercase" ? "uppercase" : "normal case"}, weight ${p.fontWeight}, ${p.fontSizePx}px` +
|
|
1027
|
+
(p.borderWidthPx === undefined ? "" : `, border width ${p.borderWidthPx}px`) +
|
|
1028
|
+
(p.paddingYPx === undefined ? "" : `, vertical padding ${p.paddingYPx}px`) +
|
|
1029
|
+
(p.letterSpacingPx === undefined ? "" : `, letter spacing ${p.letterSpacingPx}px`);
|
|
997
1030
|
}
|
|
998
1031
|
|
|
999
1032
|
/**
|
|
@@ -1017,11 +1050,12 @@ export function describeNicotineWarningPresentation(p) {
|
|
|
1017
1050
|
*/
|
|
1018
1051
|
export function nicotineWarningHtml(declaration, variant) {
|
|
1019
1052
|
const { presentation, preset } = resolveNicotineWarning(declaration);
|
|
1053
|
+
const barPadding = presentation.paddingYPx === undefined ? "0.5rem" : `${presentation.paddingYPx}px`;
|
|
1020
1054
|
const attrs = `style="${nicotineWarningStyle(presentation, variant)}" role="note" aria-label="Health warning" ` +
|
|
1021
1055
|
`data-compliance="nicotine-warning" data-nicotine-warning-preset="${preset ?? "custom"}"`;
|
|
1022
1056
|
const text = NICOTINE_WARNING_TEXT_LOCK;
|
|
1023
1057
|
return variant === "bar"
|
|
1024
|
-
? `<div ${attrs}><p class="container-prose" style="margin-block:0;padding-block
|
|
1058
|
+
? `<div ${attrs}><p class="container-prose" style="margin-block:0;padding-block:${barPadding};text-align:center;${text}">${NICOTINE_WARNING_TEXT}</p></div>`
|
|
1025
1059
|
: `<div ${attrs}><p style="margin:0;${text}">${NICOTINE_WARNING_TEXT}</p></div>`;
|
|
1026
1060
|
}
|
|
1027
1061
|
|
|
@@ -1061,15 +1095,17 @@ const NICOTINE_WARNING_TEXT_LOCK = [
|
|
|
1061
1095
|
*/
|
|
1062
1096
|
export function nicotineWarningStyle(p, variant) {
|
|
1063
1097
|
const size = variant === "block" ? Math.max(p.fontSizePx, 14) : p.fontSizePx;
|
|
1098
|
+
const boxed = `${p.borderWidthPx ?? 2}px`;
|
|
1064
1099
|
const frame = variant === "bar"
|
|
1065
|
-
? [`border-bottom:2px solid ${p.border}`]
|
|
1066
|
-
: [`border
|
|
1100
|
+
? [p.borderWidthPx === undefined ? `border-bottom:2px solid ${p.border}` : `border:${boxed} solid ${p.border}`]
|
|
1101
|
+
: [`border:${boxed} solid ${p.border}`, "border-radius:var(--radius-md)",
|
|
1102
|
+
`padding:${p.paddingYPx === undefined ? "0.75rem" : `${p.paddingYPx}px`} 1rem`];
|
|
1067
1103
|
return [
|
|
1068
1104
|
...frame,
|
|
1069
1105
|
`background-color:${p.background}`,
|
|
1070
1106
|
`color:${p.text}`,
|
|
1071
1107
|
`text-transform:${p.textTransform}`,
|
|
1072
|
-
`letter-spacing:${p.textTransform === "uppercase" ? "0.06em" : "normal"}`,
|
|
1108
|
+
`letter-spacing:${p.letterSpacingPx !== undefined ? `${p.letterSpacingPx}px` : p.textTransform === "uppercase" ? "0.06em" : "normal"}`,
|
|
1073
1109
|
`font-weight:${p.fontWeight}`,
|
|
1074
1110
|
`font-size:${size}px`,
|
|
1075
1111
|
"line-height:1.4",
|