@riddledc/riddle-proof 0.7.21 → 0.7.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/basic-gameplay.cjs +128 -8
- package/dist/basic-gameplay.d.cts +28 -5
- package/dist/basic-gameplay.d.ts +28 -5
- package/dist/basic-gameplay.js +1 -1
- package/dist/{chunk-E6O3EOEI.js → chunk-ELZSPOWV.js} +128 -8
- package/dist/{chunk-TPUR67H5.js → chunk-XOM2OYAB.js} +250 -14
- package/dist/cli.cjs +250 -14
- package/dist/cli.js +1 -1
- package/dist/index.cjs +378 -22
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/profile.cjs +250 -14
- package/dist/profile.d.cts +19 -1
- package/dist/profile.d.ts +19 -1
- package/dist/profile.js +1 -1
- package/package.json +1 -1
|
@@ -38,6 +38,79 @@ function stringValue(value) {
|
|
|
38
38
|
function numberValue(value) {
|
|
39
39
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
40
40
|
}
|
|
41
|
+
function horizontalBoundsOverflowPx(value) {
|
|
42
|
+
if (!isRecord(value)) return 0;
|
|
43
|
+
let max = maxPositiveNumber(
|
|
44
|
+
value.overflow_px,
|
|
45
|
+
value.overflow,
|
|
46
|
+
value.bounds_overflow_px,
|
|
47
|
+
value.horizontal_overflow_px,
|
|
48
|
+
value.left_overflow_px,
|
|
49
|
+
value.right_overflow_px
|
|
50
|
+
);
|
|
51
|
+
for (const offender of boundsOffendersForEvidence(value)) {
|
|
52
|
+
max = Math.max(max, horizontalOffenderOverflowPx(offender));
|
|
53
|
+
}
|
|
54
|
+
return roundPixels(max);
|
|
55
|
+
}
|
|
56
|
+
function horizontalOffenderOverflowPx(value) {
|
|
57
|
+
if (!isRecord(value)) return 0;
|
|
58
|
+
let max = maxPositiveNumber(
|
|
59
|
+
value.overflow,
|
|
60
|
+
value.overflow_px,
|
|
61
|
+
value.bounds_overflow_px,
|
|
62
|
+
value.horizontal_overflow_px,
|
|
63
|
+
value.left_overflow_px,
|
|
64
|
+
value.right_overflow_px,
|
|
65
|
+
value.leftOverflowPx,
|
|
66
|
+
value.rightOverflowPx
|
|
67
|
+
);
|
|
68
|
+
const clipped = isRecord(value.clipped || value.clip || value.clipping) ? value.clipped || value.clip || value.clipping : void 0;
|
|
69
|
+
if (isRecord(clipped)) {
|
|
70
|
+
max = Math.max(max, maxPositiveNumber(
|
|
71
|
+
clipped.left,
|
|
72
|
+
clipped.right,
|
|
73
|
+
clipped.left_px,
|
|
74
|
+
clipped.right_px,
|
|
75
|
+
clipped.leftPx,
|
|
76
|
+
clipped.rightPx
|
|
77
|
+
));
|
|
78
|
+
}
|
|
79
|
+
const rect = isRecord(value.rect || value.bounds || value.bounding_rect || value.boundingRect) ? value.rect || value.bounds || value.bounding_rect || value.boundingRect : void 0;
|
|
80
|
+
const viewportWidth = numberValue(value.viewport_width ?? value.viewportWidth);
|
|
81
|
+
if (isRecord(rect) && viewportWidth !== void 0) {
|
|
82
|
+
const left = numberValue(rect.left);
|
|
83
|
+
const right = numberValue(rect.right);
|
|
84
|
+
if (left !== void 0 && left < 0) max = Math.max(max, Math.abs(left));
|
|
85
|
+
if (right !== void 0 && right > viewportWidth) max = Math.max(max, right - viewportWidth);
|
|
86
|
+
}
|
|
87
|
+
return roundPixels(max);
|
|
88
|
+
}
|
|
89
|
+
function boundsOffendersForEvidence(value) {
|
|
90
|
+
if (!isRecord(value)) return [];
|
|
91
|
+
const offenders = [
|
|
92
|
+
...Array.isArray(value.overflow_offenders) ? value.overflow_offenders : [],
|
|
93
|
+
...Array.isArray(value.overflowOffenders) ? value.overflowOffenders : [],
|
|
94
|
+
...Array.isArray(value.bounds_offenders) ? value.bounds_offenders : [],
|
|
95
|
+
...Array.isArray(value.boundsOffenders) ? value.boundsOffenders : [],
|
|
96
|
+
...Array.isArray(value.clipped_elements) ? value.clipped_elements : [],
|
|
97
|
+
...Array.isArray(value.clippedElements) ? value.clippedElements : [],
|
|
98
|
+
...Array.isArray(value.clipping_offenders) ? value.clipping_offenders : [],
|
|
99
|
+
...Array.isArray(value.clippingOffenders) ? value.clippingOffenders : []
|
|
100
|
+
];
|
|
101
|
+
return offenders.filter((item) => isRecord(item)).sort((a, b) => horizontalOffenderOverflowPx(b) - horizontalOffenderOverflowPx(a));
|
|
102
|
+
}
|
|
103
|
+
function maxPositiveNumber(...values) {
|
|
104
|
+
let max = 0;
|
|
105
|
+
for (const value of values) {
|
|
106
|
+
const number = numberValue(value);
|
|
107
|
+
if (number !== void 0 && number > max) max = number;
|
|
108
|
+
}
|
|
109
|
+
return max;
|
|
110
|
+
}
|
|
111
|
+
function roundPixels(value) {
|
|
112
|
+
return Math.round(value * 100) / 100;
|
|
113
|
+
}
|
|
41
114
|
function timeoutSecValue(value) {
|
|
42
115
|
const number = numberValue(value);
|
|
43
116
|
return number && number > 0 ? Math.ceil(number) : void 0;
|
|
@@ -380,7 +453,7 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
380
453
|
message: "No applicable viewport evidence was captured for overflow check."
|
|
381
454
|
};
|
|
382
455
|
}
|
|
383
|
-
const failed = applicable.filter((viewport) => (viewport
|
|
456
|
+
const failed = applicable.filter((viewport) => horizontalBoundsOverflowPx(viewport) > maxOverflow);
|
|
384
457
|
return {
|
|
385
458
|
type: check.type,
|
|
386
459
|
label: checkLabel(check),
|
|
@@ -388,9 +461,11 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
388
461
|
evidence: {
|
|
389
462
|
max_overflow_px: maxOverflow,
|
|
390
463
|
overflow_px: applicable.map((viewport) => viewport.overflow_px ?? null),
|
|
464
|
+
bounds_overflow_px: applicable.map((viewport) => horizontalBoundsOverflowPx(viewport)),
|
|
465
|
+
overflow_offender_counts: applicable.map((viewport) => boundsOffendersForEvidence(viewport).length),
|
|
391
466
|
viewports: applicable.map((viewport) => viewport.name)
|
|
392
467
|
},
|
|
393
|
-
message: failed.length ? `Horizontal overflow exceeded ${maxOverflow}px in ${failed.length} viewport(s).` : void 0
|
|
468
|
+
message: failed.length ? `Horizontal bounds overflow exceeded ${maxOverflow}px in ${failed.length} viewport(s).` : void 0
|
|
394
469
|
};
|
|
395
470
|
}
|
|
396
471
|
if (check.type === "no_fatal_console_errors") {
|
|
@@ -612,6 +687,77 @@ function textMatches(sample, check) {
|
|
|
612
687
|
}
|
|
613
688
|
return String(sample || "").includes(check.text || "");
|
|
614
689
|
}
|
|
690
|
+
function numberValue(value) {
|
|
691
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
692
|
+
}
|
|
693
|
+
function maxPositiveNumber() {
|
|
694
|
+
let max = 0;
|
|
695
|
+
for (const value of arguments) {
|
|
696
|
+
const number = numberValue(value);
|
|
697
|
+
if (number !== undefined && number > max) max = number;
|
|
698
|
+
}
|
|
699
|
+
return max;
|
|
700
|
+
}
|
|
701
|
+
function roundPixels(value) {
|
|
702
|
+
return Math.round(value * 100) / 100;
|
|
703
|
+
}
|
|
704
|
+
function isRecord(value) {
|
|
705
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
706
|
+
}
|
|
707
|
+
function boundsOffendersForEvidence(value) {
|
|
708
|
+
if (!isRecord(value)) return [];
|
|
709
|
+
const offenders = []
|
|
710
|
+
.concat(Array.isArray(value.overflow_offenders) ? value.overflow_offenders : [])
|
|
711
|
+
.concat(Array.isArray(value.overflowOffenders) ? value.overflowOffenders : [])
|
|
712
|
+
.concat(Array.isArray(value.bounds_offenders) ? value.bounds_offenders : [])
|
|
713
|
+
.concat(Array.isArray(value.boundsOffenders) ? value.boundsOffenders : [])
|
|
714
|
+
.concat(Array.isArray(value.clipped_elements) ? value.clipped_elements : [])
|
|
715
|
+
.concat(Array.isArray(value.clippedElements) ? value.clippedElements : [])
|
|
716
|
+
.concat(Array.isArray(value.clipping_offenders) ? value.clipping_offenders : [])
|
|
717
|
+
.concat(Array.isArray(value.clippingOffenders) ? value.clippingOffenders : []);
|
|
718
|
+
return offenders.filter(isRecord).sort((a, b) => horizontalOffenderOverflowPx(b) - horizontalOffenderOverflowPx(a));
|
|
719
|
+
}
|
|
720
|
+
function horizontalOffenderOverflowPx(value) {
|
|
721
|
+
if (!isRecord(value)) return 0;
|
|
722
|
+
let max = maxPositiveNumber(
|
|
723
|
+
value.overflow,
|
|
724
|
+
value.overflow_px,
|
|
725
|
+
value.bounds_overflow_px,
|
|
726
|
+
value.horizontal_overflow_px,
|
|
727
|
+
value.left_overflow_px,
|
|
728
|
+
value.right_overflow_px,
|
|
729
|
+
value.leftOverflowPx,
|
|
730
|
+
value.rightOverflowPx
|
|
731
|
+
);
|
|
732
|
+
const clipped = value.clipped || value.clip || value.clipping;
|
|
733
|
+
if (isRecord(clipped)) {
|
|
734
|
+
max = Math.max(max, maxPositiveNumber(clipped.left, clipped.right, clipped.left_px, clipped.right_px, clipped.leftPx, clipped.rightPx));
|
|
735
|
+
}
|
|
736
|
+
const rect = value.rect || value.bounds || value.bounding_rect || value.boundingRect;
|
|
737
|
+
const viewportWidth = numberValue(value.viewport_width != null ? value.viewport_width : value.viewportWidth);
|
|
738
|
+
if (isRecord(rect) && viewportWidth !== undefined) {
|
|
739
|
+
const left = numberValue(rect.left);
|
|
740
|
+
const right = numberValue(rect.right);
|
|
741
|
+
if (left !== undefined && left < 0) max = Math.max(max, Math.abs(left));
|
|
742
|
+
if (right !== undefined && right > viewportWidth) max = Math.max(max, right - viewportWidth);
|
|
743
|
+
}
|
|
744
|
+
return roundPixels(max);
|
|
745
|
+
}
|
|
746
|
+
function horizontalBoundsOverflowPx(value) {
|
|
747
|
+
if (!isRecord(value)) return 0;
|
|
748
|
+
let max = maxPositiveNumber(
|
|
749
|
+
value.overflow_px,
|
|
750
|
+
value.overflow,
|
|
751
|
+
value.bounds_overflow_px,
|
|
752
|
+
value.horizontal_overflow_px,
|
|
753
|
+
value.left_overflow_px,
|
|
754
|
+
value.right_overflow_px
|
|
755
|
+
);
|
|
756
|
+
for (const offender of boundsOffendersForEvidence(value)) {
|
|
757
|
+
max = Math.max(max, horizontalOffenderOverflowPx(offender));
|
|
758
|
+
}
|
|
759
|
+
return roundPixels(max);
|
|
760
|
+
}
|
|
615
761
|
function assessProfile(profile, evidence) {
|
|
616
762
|
const checks = [];
|
|
617
763
|
const viewports = evidence.viewports || [];
|
|
@@ -729,13 +875,19 @@ function assessProfile(profile, evidence) {
|
|
|
729
875
|
});
|
|
730
876
|
continue;
|
|
731
877
|
}
|
|
732
|
-
const failed = applicable.filter((viewport) => (viewport
|
|
878
|
+
const failed = applicable.filter((viewport) => horizontalBoundsOverflowPx(viewport) > maxOverflow);
|
|
733
879
|
checks.push({
|
|
734
880
|
type: check.type,
|
|
735
881
|
label: check.label || check.type,
|
|
736
882
|
status: failed.length ? "failed" : "passed",
|
|
737
|
-
evidence: {
|
|
738
|
-
|
|
883
|
+
evidence: {
|
|
884
|
+
max_overflow_px: maxOverflow,
|
|
885
|
+
overflow_px: applicable.map((viewport) => viewport.overflow_px ?? null),
|
|
886
|
+
bounds_overflow_px: applicable.map((viewport) => horizontalBoundsOverflowPx(viewport)),
|
|
887
|
+
overflow_offender_counts: applicable.map((viewport) => boundsOffendersForEvidence(viewport).length),
|
|
888
|
+
viewports: applicable.map((viewport) => viewport.name)
|
|
889
|
+
},
|
|
890
|
+
message: failed.length ? "Horizontal bounds overflow exceeded " + maxOverflow + "px in " + failed.length + " viewport(s)." : undefined,
|
|
739
891
|
});
|
|
740
892
|
continue;
|
|
741
893
|
}
|
|
@@ -965,14 +1117,55 @@ async function captureViewport(viewport) {
|
|
|
965
1117
|
const body = document.body;
|
|
966
1118
|
const documentElement = document.documentElement;
|
|
967
1119
|
const text = (body ? body.innerText : "").replace(/\s+/g, " ").trim();
|
|
1120
|
+
const clientWidth = documentElement ? documentElement.clientWidth : window.innerWidth;
|
|
1121
|
+
const scrollWidth = documentElement ? documentElement.scrollWidth : 0;
|
|
1122
|
+
const viewportWidth = clientWidth || window.innerWidth;
|
|
1123
|
+
const overflowOffenders = [];
|
|
1124
|
+
for (const element of Array.from(body ? body.querySelectorAll("*") : [])) {
|
|
1125
|
+
const rect = element.getBoundingClientRect();
|
|
1126
|
+
if (!rect || rect.width < 1 || rect.height < 1) continue;
|
|
1127
|
+
const style = window.getComputedStyle(element);
|
|
1128
|
+
if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0") continue;
|
|
1129
|
+
const leftOverflow = Math.max(0, -rect.left);
|
|
1130
|
+
const rightOverflow = Math.max(0, rect.right - viewportWidth);
|
|
1131
|
+
const overflow = Math.max(leftOverflow, rightOverflow);
|
|
1132
|
+
if (overflow <= 0.5) continue;
|
|
1133
|
+
const tag = element.tagName ? element.tagName.toLowerCase() : "element";
|
|
1134
|
+
const id = element.id ? "#" + element.id : "";
|
|
1135
|
+
const className = typeof element.className === "string"
|
|
1136
|
+
? element.className.trim().split(/\s+/).filter(Boolean).slice(0, 2).join(".")
|
|
1137
|
+
: "";
|
|
1138
|
+
overflowOffenders.push({
|
|
1139
|
+
selector: tag + id + (className ? "." + className : ""),
|
|
1140
|
+
tag,
|
|
1141
|
+
text: (element.textContent || "").replace(/\s+/g, " ").trim().slice(0, 120),
|
|
1142
|
+
overflow,
|
|
1143
|
+
left_overflow_px: leftOverflow,
|
|
1144
|
+
right_overflow_px: rightOverflow,
|
|
1145
|
+
viewport_width: viewportWidth,
|
|
1146
|
+
rect: {
|
|
1147
|
+
left: rect.left,
|
|
1148
|
+
right: rect.right,
|
|
1149
|
+
width: rect.width,
|
|
1150
|
+
},
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
overflowOffenders.sort((a, b) => b.overflow - a.overflow);
|
|
1154
|
+
const boundsOverflowPx = Math.max(
|
|
1155
|
+
0,
|
|
1156
|
+
scrollWidth - (clientWidth || viewportWidth),
|
|
1157
|
+
...overflowOffenders.map((offender) => offender.overflow),
|
|
1158
|
+
);
|
|
968
1159
|
return {
|
|
969
1160
|
url: location.href,
|
|
970
1161
|
pathname: location.pathname,
|
|
971
1162
|
title: document.title,
|
|
972
1163
|
body_text_length: text.length,
|
|
973
1164
|
body_text_sample: text.slice(0, 8000),
|
|
974
|
-
scroll_width:
|
|
975
|
-
client_width:
|
|
1165
|
+
scroll_width: scrollWidth,
|
|
1166
|
+
client_width: clientWidth,
|
|
1167
|
+
bounds_overflow_px: Math.round(boundsOverflowPx * 100) / 100,
|
|
1168
|
+
overflow_offenders: overflowOffenders.slice(0, 10),
|
|
976
1169
|
};
|
|
977
1170
|
}).catch((error) => ({
|
|
978
1171
|
url: page.url(),
|
|
@@ -982,6 +1175,8 @@ async function captureViewport(viewport) {
|
|
|
982
1175
|
body_text_sample: "",
|
|
983
1176
|
scroll_width: 0,
|
|
984
1177
|
client_width: viewport.width,
|
|
1178
|
+
bounds_overflow_px: 0,
|
|
1179
|
+
overflow_offenders: [],
|
|
985
1180
|
evaluation_error: String(error && error.message ? error.message : error).slice(0, 1000),
|
|
986
1181
|
}));
|
|
987
1182
|
const selectors = {};
|
|
@@ -1020,6 +1215,8 @@ async function captureViewport(viewport) {
|
|
|
1020
1215
|
scroll_width: dom.scroll_width,
|
|
1021
1216
|
client_width: dom.client_width,
|
|
1022
1217
|
overflow_px: Math.max(0, (dom.scroll_width || 0) - (dom.client_width || viewport.width)),
|
|
1218
|
+
bounds_overflow_px: dom.bounds_overflow_px,
|
|
1219
|
+
overflow_offenders: dom.overflow_offenders || [],
|
|
1023
1220
|
selectors,
|
|
1024
1221
|
text_matches,
|
|
1025
1222
|
setup_action_results: setupActionResults,
|
|
@@ -1051,6 +1248,8 @@ function buildProfileEvidence(currentViewports) {
|
|
|
1051
1248
|
routes: currentViewports.map((viewport) => viewport.route),
|
|
1052
1249
|
titles: currentViewports.map((viewport) => viewport.title),
|
|
1053
1250
|
overflow_px: currentViewports.map((viewport) => viewport.overflow_px),
|
|
1251
|
+
bounds_overflow_px: currentViewports.map((viewport) => viewport.bounds_overflow_px),
|
|
1252
|
+
overflow_offender_counts: currentViewports.map((viewport) => (viewport.overflow_offenders || []).length),
|
|
1054
1253
|
},
|
|
1055
1254
|
};
|
|
1056
1255
|
}
|
|
@@ -1074,24 +1273,36 @@ return result;
|
|
|
1074
1273
|
}
|
|
1075
1274
|
function collectRiddleProfileArtifactRefs(input) {
|
|
1076
1275
|
const refs = [];
|
|
1077
|
-
const
|
|
1276
|
+
const indexes = /* @__PURE__ */ new Map();
|
|
1277
|
+
const priorities = /* @__PURE__ */ new Map();
|
|
1078
1278
|
function add(item, source) {
|
|
1079
1279
|
if (!isRecord(item)) return;
|
|
1080
|
-
const name = stringValue(item.name) || stringValue(item.filename) || "";
|
|
1081
1280
|
const url = stringValue(item.url);
|
|
1082
1281
|
const path = stringValue(item.path);
|
|
1282
|
+
const rawName = stringValue(item.name) || stringValue(item.filename) || artifactNameFromPath(url || path) || "";
|
|
1283
|
+
const name = normalizeRiddleProfileArtifactName(rawName);
|
|
1083
1284
|
if (!name && !url && !path) return;
|
|
1084
|
-
const key =
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
refs.push({
|
|
1285
|
+
const key = profileArtifactDedupeKey(name, url || path || "");
|
|
1286
|
+
const priority = profileArtifactPriority(rawName, name);
|
|
1287
|
+
const ref = {
|
|
1088
1288
|
name,
|
|
1089
1289
|
url,
|
|
1090
1290
|
path,
|
|
1091
1291
|
kind: stringValue(item.kind) || stringValue(item.type),
|
|
1092
1292
|
content_type: stringValue(item.content_type) || stringValue(item.contentType),
|
|
1093
1293
|
source
|
|
1094
|
-
}
|
|
1294
|
+
};
|
|
1295
|
+
const existingIndex = indexes.get(key);
|
|
1296
|
+
if (existingIndex !== void 0) {
|
|
1297
|
+
if (priority > (priorities.get(key) || 0)) {
|
|
1298
|
+
refs[existingIndex] = ref;
|
|
1299
|
+
priorities.set(key, priority);
|
|
1300
|
+
}
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
indexes.set(key, refs.length);
|
|
1304
|
+
priorities.set(key, priority);
|
|
1305
|
+
refs.push(ref);
|
|
1095
1306
|
}
|
|
1096
1307
|
function visit(value, source) {
|
|
1097
1308
|
if (Array.isArray(value)) {
|
|
@@ -1106,6 +1317,31 @@ function collectRiddleProfileArtifactRefs(input) {
|
|
|
1106
1317
|
visit(input, "artifacts");
|
|
1107
1318
|
return refs;
|
|
1108
1319
|
}
|
|
1320
|
+
function normalizeRiddleProfileArtifactName(name) {
|
|
1321
|
+
return name.replace(/\.json\.json$/i, ".json");
|
|
1322
|
+
}
|
|
1323
|
+
function profileArtifactDedupeKey(name, location) {
|
|
1324
|
+
if (PROFILE_SINGLETON_ARTIFACT_NAMES.has(name.toLowerCase())) return name.toLowerCase();
|
|
1325
|
+
return `${name}:${location}`;
|
|
1326
|
+
}
|
|
1327
|
+
function profileArtifactPriority(rawName, normalizedName) {
|
|
1328
|
+
const lower = normalizedName.toLowerCase();
|
|
1329
|
+
if (!PROFILE_SINGLETON_ARTIFACT_NAMES.has(lower)) return 1;
|
|
1330
|
+
return /\.json\.json$/i.test(rawName) ? 2 : 1;
|
|
1331
|
+
}
|
|
1332
|
+
function artifactNameFromPath(value) {
|
|
1333
|
+
if (!value) return "";
|
|
1334
|
+
try {
|
|
1335
|
+
return new URL(value).pathname.split("/").filter(Boolean).pop() || "";
|
|
1336
|
+
} catch {
|
|
1337
|
+
return value.split(/[\\/]/).filter(Boolean).pop() || "";
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
var PROFILE_SINGLETON_ARTIFACT_NAMES = /* @__PURE__ */ new Set([
|
|
1341
|
+
"proof.json",
|
|
1342
|
+
"console.json",
|
|
1343
|
+
"dom-summary.json"
|
|
1344
|
+
]);
|
|
1109
1345
|
function extractRiddleProofProfileResult(input) {
|
|
1110
1346
|
if (!isRecord(input)) return void 0;
|
|
1111
1347
|
if (input.version === RIDDLE_PROOF_PROFILE_RESULT_VERSION) return input;
|