@riddledc/riddle-proof 0.7.94 → 0.7.96

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/index.cjs CHANGED
@@ -9514,6 +9514,12 @@ function normalizeCheck(input, index) {
9514
9514
  `checks[${index}] allowed_statuses`
9515
9515
  ) : void 0;
9516
9516
  const maxLinks = isLinkStatusCheck ? normalizePositiveInteger(input.max_links ?? input.maxLinks ?? input.limit, `checks[${index}] max_links`, 500) : void 0;
9517
+ const minBytes = isLinkStatusCheck ? normalizePositiveInteger(input.min_bytes ?? input.minBytes ?? input.min_response_bytes ?? input.minResponseBytes, `checks[${index}] min_bytes`) : void 0;
9518
+ const expectedContentType = isLinkStatusCheck ? stringValue5(input.expected_content_type) || stringValue5(input.expectedContentType) || stringValue5(input.content_type) || stringValue5(input.contentType) : void 0;
9519
+ const allowedContentTypes = isLinkStatusCheck ? normalizeStringList(
9520
+ input.allowed_content_types ?? input.allowedContentTypes ?? input.expected_content_types ?? input.expectedContentTypes,
9521
+ `checks[${index}] allowed_content_types`
9522
+ ) ?? (expectedContentType ? [expectedContentType] : void 0) : void 0;
9517
9523
  if (isLinkStatusCheck) {
9518
9524
  if (minCount !== void 0 && (!Number.isInteger(minCount) || minCount < 0)) {
9519
9525
  throw new Error(`checks[${index}] ${type} min_count must be a non-negative integer.`);
@@ -9555,6 +9561,8 @@ function normalizeCheck(input, index) {
9555
9561
  same_origin_only: isLinkStatusCheck ? input.same_origin_only === true || input.sameOriginOnly === true : void 0,
9556
9562
  dedupe: isLinkStatusCheck ? input.dedupe === false ? false : true : void 0,
9557
9563
  require_nonzero_bytes: isLinkStatusCheck ? input.require_nonzero_bytes === true || input.requireNonzeroBytes === true : void 0,
9564
+ min_bytes: minBytes,
9565
+ allowed_content_types: allowedContentTypes,
9558
9566
  allow_get_fallback: isLinkStatusCheck ? input.allow_get_fallback === false || input.allowGetFallback === false ? false : true : void 0,
9559
9567
  max_overflow_px: numberValue3(input.max_overflow_px),
9560
9568
  timeout_ms: numberValue3(input.timeout_ms) ?? numberValue3(input.timeoutMs),
@@ -9661,15 +9669,40 @@ function linkStatusIsAllowed(status, check) {
9661
9669
  const allowed = linkStatusAllowedStatuses(check);
9662
9670
  return allowed?.length ? allowed.includes(status) : status >= 200 && status < 400;
9663
9671
  }
9672
+ function linkStatusObservedBytes(result) {
9673
+ const bytes = numberValue3(result.bytes);
9674
+ const contentLength = numberValue3(result.content_length);
9675
+ return Math.max(bytes ?? 0, contentLength ?? 0) || void 0;
9676
+ }
9677
+ function normalizeLinkStatusContentType(value) {
9678
+ const normalized = value?.split(";")[0]?.trim().toLowerCase();
9679
+ return normalized || void 0;
9680
+ }
9681
+ function linkStatusContentTypeOk(result, check) {
9682
+ const expected = check.allowed_content_types;
9683
+ if (!expected?.length) return true;
9684
+ const actual = normalizeLinkStatusContentType(stringValue5(result.content_type));
9685
+ if (!actual) return false;
9686
+ return expected.some((contentType) => {
9687
+ const normalized = normalizeLinkStatusContentType(contentType);
9688
+ if (!normalized) return false;
9689
+ if (normalized.endsWith("/*")) return actual.startsWith(normalized.slice(0, -1));
9690
+ return actual === normalized;
9691
+ });
9692
+ }
9664
9693
  function linkStatusResultOk(result, check) {
9665
9694
  const status = numberValue3(result.status);
9666
9695
  if (!linkStatusIsAllowed(status, check)) return false;
9667
9696
  if (stringValue5(result.error)) return false;
9668
9697
  if (result.ok === false) return false;
9698
+ if (!linkStatusContentTypeOk(result, check)) return false;
9669
9699
  if (check.require_nonzero_bytes) {
9670
- const bytes = numberValue3(result.bytes);
9671
- const contentLength = numberValue3(result.content_length);
9672
- return bytes !== void 0 && bytes > 0 || contentLength !== void 0 && contentLength > 0;
9700
+ const observedBytes = linkStatusObservedBytes(result);
9701
+ if (observedBytes === void 0 || observedBytes <= 0) return false;
9702
+ }
9703
+ if (check.min_bytes !== void 0) {
9704
+ const observedBytes = linkStatusObservedBytes(result);
9705
+ if (observedBytes === void 0 || observedBytes < check.min_bytes) return false;
9673
9706
  }
9674
9707
  return true;
9675
9708
  }
@@ -9691,6 +9724,10 @@ function summarizeLinkStatusEvidence(viewport, check) {
9691
9724
  }
9692
9725
  const results = Array.isArray(linkEvidence.results) ? linkEvidence.results.filter(isRecord2) : [];
9693
9726
  const totalCount = numberValue3(linkEvidence.total_count) ?? results.length;
9727
+ const resultCount = numberValue3(linkEvidence.result_count) ?? totalCount;
9728
+ const storedResultCount = numberValue3(linkEvidence.stored_result_count) ?? results.length;
9729
+ const omittedResultCount = numberValue3(linkEvidence.omitted_result_count) ?? Math.max(0, resultCount - storedResultCount);
9730
+ const omittedSuccessCount = numberValue3(linkEvidence.omitted_success_count) ?? 0;
9694
9731
  const okCount = results.filter((result) => linkStatusResultOk(result, check)).length;
9695
9732
  const failures = results.filter((result) => !linkStatusResultOk(result, check)).map((result) => ({
9696
9733
  code: "link_status_failed",
@@ -9698,7 +9735,10 @@ function summarizeLinkStatusEvidence(viewport, check) {
9698
9735
  status: numberValue3(result.status) ?? null,
9699
9736
  method: stringValue5(result.method) ?? null,
9700
9737
  error: stringValue5(result.error) ?? null,
9701
- bytes: numberValue3(result.bytes) ?? numberValue3(result.content_length) ?? null
9738
+ content_type: stringValue5(result.content_type) ?? null,
9739
+ bytes: linkStatusObservedBytes(result) ?? null,
9740
+ min_bytes: check.min_bytes ?? null,
9741
+ allowed_content_types: check.allowed_content_types ?? null
9702
9742
  }));
9703
9743
  if (stringValue5(linkEvidence.error)) {
9704
9744
  failures.push({ code: "link_status_capture_failed", error: stringValue5(linkEvidence.error) ?? "" });
@@ -9735,6 +9775,13 @@ function summarizeLinkStatusEvidence(viewport, check) {
9735
9775
  failed_count: failures.length,
9736
9776
  truncated: linkEvidence.truncated === true,
9737
9777
  max_links: numberValue3(linkEvidence.max_links) ?? check.max_links ?? 100,
9778
+ result_count: resultCount,
9779
+ stored_result_count: storedResultCount,
9780
+ omitted_result_count: omittedResultCount,
9781
+ omitted_success_count: omittedSuccessCount,
9782
+ results_compacted: linkEvidence.results_compacted === true || omittedResultCount > 0,
9783
+ min_bytes: check.min_bytes ?? null,
9784
+ allowed_content_types: check.allowed_content_types ?? null,
9738
9785
  status_counts: statusCounts,
9739
9786
  failures: failures.slice(0, 20)
9740
9787
  };
@@ -10263,6 +10310,8 @@ function assessCheckFromEvidence(check, evidence) {
10263
10310
  min_count: check.min_count ?? null,
10264
10311
  allowed_statuses: linkStatusAllowedStatuses(check) || ["2xx", "3xx"],
10265
10312
  require_nonzero_bytes: check.require_nonzero_bytes === true,
10313
+ min_bytes: check.min_bytes ?? null,
10314
+ allowed_content_types: check.allowed_content_types ?? null,
10266
10315
  viewports: summaries.map((summary) => toJsonValue(summary)),
10267
10316
  failures: failed.flatMap((summary) => Array.isArray(summary.failures) ? summary.failures.map((failure) => toJsonValue({ viewport: stringValue5(summary.viewport) ?? null, failure })) : [])
10268
10317
  },
@@ -10866,15 +10915,41 @@ function linkStatusIsAllowed(status, check) {
10866
10915
  const allowed = linkStatusAllowedStatuses(check);
10867
10916
  return Array.isArray(allowed) && allowed.length ? allowed.includes(status) : status >= 200 && status < 400;
10868
10917
  }
10918
+ function linkStatusObservedBytes(result) {
10919
+ const bytes = typeof result.bytes === "number" && Number.isFinite(result.bytes) ? result.bytes : undefined;
10920
+ const contentLength = typeof result.content_length === "number" && Number.isFinite(result.content_length) ? result.content_length : undefined;
10921
+ const observed = Math.max(bytes || 0, contentLength || 0);
10922
+ return observed > 0 ? observed : undefined;
10923
+ }
10924
+ function normalizeLinkStatusContentType(value) {
10925
+ if (typeof value !== "string") return undefined;
10926
+ const normalized = (value.split(";")[0] || "").trim().toLowerCase();
10927
+ return normalized || undefined;
10928
+ }
10929
+ function linkStatusContentTypeOk(result, check) {
10930
+ if (!Array.isArray(check.allowed_content_types) || !check.allowed_content_types.length) return true;
10931
+ const actual = normalizeLinkStatusContentType(result.content_type);
10932
+ if (!actual) return false;
10933
+ return check.allowed_content_types.some((contentType) => {
10934
+ const normalized = normalizeLinkStatusContentType(contentType);
10935
+ if (!normalized) return false;
10936
+ if (normalized.endsWith("/*")) return actual.startsWith(normalized.slice(0, -1));
10937
+ return actual === normalized;
10938
+ });
10939
+ }
10869
10940
  function linkStatusResultOk(result, check) {
10870
10941
  if (!result || typeof result !== "object" || Array.isArray(result)) return false;
10871
10942
  if (!linkStatusIsAllowed(result.status, check)) return false;
10872
10943
  if (typeof result.error === "string" && result.error.trim()) return false;
10873
10944
  if (result.ok === false) return false;
10945
+ if (!linkStatusContentTypeOk(result, check)) return false;
10874
10946
  if (check.require_nonzero_bytes === true) {
10875
- const bytes = typeof result.bytes === "number" && Number.isFinite(result.bytes) ? result.bytes : undefined;
10876
- const contentLength = typeof result.content_length === "number" && Number.isFinite(result.content_length) ? result.content_length : undefined;
10877
- return (bytes !== undefined && bytes > 0) || (contentLength !== undefined && contentLength > 0);
10947
+ const observedBytes = linkStatusObservedBytes(result);
10948
+ if (observedBytes === undefined || observedBytes <= 0) return false;
10949
+ }
10950
+ if (typeof check.min_bytes === "number" && Number.isFinite(check.min_bytes)) {
10951
+ const observedBytes = linkStatusObservedBytes(result);
10952
+ if (observedBytes === undefined || observedBytes < check.min_bytes) return false;
10878
10953
  }
10879
10954
  return true;
10880
10955
  }
@@ -10893,6 +10968,10 @@ function summarizeLinkStatusEvidence(viewport, check) {
10893
10968
  }
10894
10969
  const results = Array.isArray(linkEvidence.results) ? linkEvidence.results.filter((result) => result && typeof result === "object" && !Array.isArray(result)) : [];
10895
10970
  const totalCount = typeof linkEvidence.total_count === "number" && Number.isFinite(linkEvidence.total_count) ? linkEvidence.total_count : results.length;
10971
+ const resultCount = typeof linkEvidence.result_count === "number" && Number.isFinite(linkEvidence.result_count) ? linkEvidence.result_count : totalCount;
10972
+ const storedResultCount = typeof linkEvidence.stored_result_count === "number" && Number.isFinite(linkEvidence.stored_result_count) ? linkEvidence.stored_result_count : results.length;
10973
+ const omittedResultCount = typeof linkEvidence.omitted_result_count === "number" && Number.isFinite(linkEvidence.omitted_result_count) ? linkEvidence.omitted_result_count : Math.max(0, resultCount - storedResultCount);
10974
+ const omittedSuccessCount = typeof linkEvidence.omitted_success_count === "number" && Number.isFinite(linkEvidence.omitted_success_count) ? linkEvidence.omitted_success_count : 0;
10896
10975
  const okCount = results.filter((result) => linkStatusResultOk(result, check)).length;
10897
10976
  const failures = results
10898
10977
  .filter((result) => !linkStatusResultOk(result, check))
@@ -10902,11 +10981,10 @@ function summarizeLinkStatusEvidence(viewport, check) {
10902
10981
  status: typeof result.status === "number" && Number.isFinite(result.status) ? result.status : null,
10903
10982
  method: typeof result.method === "string" ? result.method : null,
10904
10983
  error: typeof result.error === "string" ? result.error : null,
10905
- bytes: typeof result.bytes === "number" && Number.isFinite(result.bytes)
10906
- ? result.bytes
10907
- : typeof result.content_length === "number" && Number.isFinite(result.content_length)
10908
- ? result.content_length
10909
- : null,
10984
+ content_type: typeof result.content_type === "string" ? result.content_type : null,
10985
+ bytes: linkStatusObservedBytes(result) ?? null,
10986
+ min_bytes: typeof check.min_bytes === "number" && Number.isFinite(check.min_bytes) ? check.min_bytes : null,
10987
+ allowed_content_types: Array.isArray(check.allowed_content_types) ? check.allowed_content_types : null,
10910
10988
  }));
10911
10989
  if (typeof linkEvidence.error === "string" && linkEvidence.error.trim()) {
10912
10990
  failures.push({ code: "link_status_capture_failed", error: linkEvidence.error });
@@ -10941,6 +11019,13 @@ function summarizeLinkStatusEvidence(viewport, check) {
10941
11019
  failed_count: failures.length,
10942
11020
  truncated: linkEvidence.truncated === true,
10943
11021
  max_links: typeof linkEvidence.max_links === "number" ? linkEvidence.max_links : check.max_links || 100,
11022
+ result_count: resultCount,
11023
+ stored_result_count: storedResultCount,
11024
+ omitted_result_count: omittedResultCount,
11025
+ omitted_success_count: omittedSuccessCount,
11026
+ results_compacted: linkEvidence.results_compacted === true || omittedResultCount > 0,
11027
+ min_bytes: typeof check.min_bytes === "number" && Number.isFinite(check.min_bytes) ? check.min_bytes : null,
11028
+ allowed_content_types: Array.isArray(check.allowed_content_types) ? check.allowed_content_types : null,
10944
11029
  status_counts: linkEvidence.status_counts && typeof linkEvidence.status_counts === "object" && !Array.isArray(linkEvidence.status_counts) ? linkEvidence.status_counts : {},
10945
11030
  failures: failures.slice(0, 20),
10946
11031
  };
@@ -11637,6 +11722,8 @@ function assessProfile(profile, evidence) {
11637
11722
  min_count: check.min_count ?? null,
11638
11723
  allowed_statuses: linkStatusAllowedStatuses(check) || ["2xx", "3xx"],
11639
11724
  require_nonzero_bytes: check.require_nonzero_bytes === true,
11725
+ min_bytes: check.min_bytes ?? null,
11726
+ allowed_content_types: check.allowed_content_types ?? null,
11640
11727
  viewports: summaries,
11641
11728
  failures: failed.flatMap((summary) => Array.isArray(summary.failures)
11642
11729
  ? summary.failures.map((failure) => ({ viewport: summary.viewport || null, failure }))
@@ -12784,6 +12871,28 @@ function linkProbeAllowed(status, check) {
12784
12871
  : null;
12785
12872
  return allowed ? allowed.includes(status) : status >= 200 && status < 400;
12786
12873
  }
12874
+ function linkProbeObservedBytes(result) {
12875
+ const bytes = typeof result.bytes === "number" && Number.isFinite(result.bytes) ? result.bytes : undefined;
12876
+ const contentLength = typeof result.content_length === "number" && Number.isFinite(result.content_length) ? result.content_length : undefined;
12877
+ const observed = Math.max(bytes || 0, contentLength || 0);
12878
+ return observed > 0 ? observed : undefined;
12879
+ }
12880
+ function normalizeLinkProbeContentType(value) {
12881
+ if (typeof value !== "string") return undefined;
12882
+ const normalized = (value.split(";")[0] || "").trim().toLowerCase();
12883
+ return normalized || undefined;
12884
+ }
12885
+ function linkProbeContentTypeAllowed(result, check) {
12886
+ if (!Array.isArray(check.allowed_content_types) || !check.allowed_content_types.length) return true;
12887
+ const actual = normalizeLinkProbeContentType(result.content_type);
12888
+ if (!actual) return false;
12889
+ return check.allowed_content_types.some((contentType) => {
12890
+ const normalized = normalizeLinkProbeContentType(contentType);
12891
+ if (!normalized) return false;
12892
+ if (normalized.endsWith("/*")) return actual.startsWith(normalized.slice(0, -1));
12893
+ return actual === normalized;
12894
+ });
12895
+ }
12787
12896
  function linkProbeResponseFields(response, method) {
12788
12897
  const contentLengthHeader = response.headers && typeof response.headers.get === "function" ? response.headers.get("content-length") : null;
12789
12898
  const contentLength = contentLengthHeader && /^\d+$/.test(contentLengthHeader) ? Number(contentLengthHeader) : null;
@@ -12798,6 +12907,7 @@ function linkProbeResponseFields(response, method) {
12798
12907
  }
12799
12908
  async function probeLinkStatus(candidate, check) {
12800
12909
  const requireNonzeroBytes = check.require_nonzero_bytes === true;
12910
+ const minBytes = typeof check.min_bytes === "number" && Number.isFinite(check.min_bytes) ? Math.max(1, Math.floor(check.min_bytes)) : null;
12801
12911
  const allowGetFallback = check.allow_get_fallback !== false;
12802
12912
  const result = {
12803
12913
  url: candidate.url,
@@ -12815,7 +12925,7 @@ async function probeLinkStatus(candidate, check) {
12815
12925
  };
12816
12926
  const applyResponse = async (response, method, readBytes) => {
12817
12927
  Object.assign(result, linkProbeResponseFields(response, method));
12818
- if (readBytes || requireNonzeroBytes) {
12928
+ if (readBytes) {
12819
12929
  try {
12820
12930
  const buffer = await response.arrayBuffer();
12821
12931
  result.bytes = buffer.byteLength;
@@ -12824,7 +12934,9 @@ async function probeLinkStatus(candidate, check) {
12824
12934
  }
12825
12935
  }
12826
12936
  result.ok = linkProbeAllowed(result.status, check)
12827
- && (!requireNonzeroBytes || (typeof result.bytes === "number" ? result.bytes > 0 : typeof result.content_length === "number" && result.content_length > 0))
12937
+ && linkProbeContentTypeAllowed(result, check)
12938
+ && (!requireNonzeroBytes || ((linkProbeObservedBytes(result) || 0) > 0))
12939
+ && (minBytes === null || ((linkProbeObservedBytes(result) || 0) >= minBytes))
12828
12940
  && !result.error;
12829
12941
  };
12830
12942
  try {
@@ -12841,9 +12953,9 @@ async function probeLinkStatus(candidate, check) {
12841
12953
  method: "GET",
12842
12954
  redirect: "follow",
12843
12955
  cache: "no-store",
12844
- headers: { Range: "bytes=0-0" },
12956
+ headers: { Range: "bytes=0-" + String((minBytes || 1) - 1) },
12845
12957
  });
12846
- await applyResponse(response, "GET", requireNonzeroBytes);
12958
+ await applyResponse(response, "GET", requireNonzeroBytes || minBytes !== null);
12847
12959
  return result;
12848
12960
  } catch (error) {
12849
12961
  result.error = String(error && error.message ? error.message : error).slice(0, 500);
@@ -12851,6 +12963,30 @@ async function probeLinkStatus(candidate, check) {
12851
12963
  return result;
12852
12964
  }
12853
12965
  }
12966
+ function compactLinkProbeResults(results) {
12967
+ const allResults = Array.isArray(results) ? results : [];
12968
+ if (allResults.length <= 20) {
12969
+ return {
12970
+ result_count: allResults.length,
12971
+ stored_result_count: allResults.length,
12972
+ omitted_result_count: 0,
12973
+ omitted_success_count: 0,
12974
+ results_compacted: false,
12975
+ results: allResults,
12976
+ };
12977
+ }
12978
+ const successResults = allResults.filter((result) => result && result.ok);
12979
+ const sampledSuccesses = new Set(successResults.slice(0, 5));
12980
+ const storedResults = allResults.filter((result) => result && (!result.ok || sampledSuccesses.has(result)));
12981
+ return {
12982
+ result_count: allResults.length,
12983
+ stored_result_count: storedResults.length,
12984
+ omitted_result_count: allResults.length - storedResults.length,
12985
+ omitted_success_count: Math.max(0, successResults.length - sampledSuccesses.size),
12986
+ results_compacted: storedResults.length < allResults.length,
12987
+ results: storedResults,
12988
+ };
12989
+ }
12854
12990
  async function collectLinkStatus(check) {
12855
12991
  const selector = linkStatusSelector(check);
12856
12992
  const candidateResult = await collectLinkCandidates(selector);
@@ -12897,13 +13033,17 @@ async function collectLinkStatus(check) {
12897
13033
  status: result.status,
12898
13034
  method: result.method,
12899
13035
  error: result.error,
12900
- bytes: result.bytes == null ? result.content_length : result.bytes,
13036
+ content_type: result.content_type,
13037
+ bytes: linkProbeObservedBytes(result) || null,
13038
+ min_bytes: typeof check.min_bytes === "number" && Number.isFinite(check.min_bytes) ? check.min_bytes : null,
13039
+ allowed_content_types: Array.isArray(check.allowed_content_types) ? check.allowed_content_types : null,
12901
13040
  }));
12902
13041
  const statusCounts = {};
12903
13042
  for (const result of results) {
12904
13043
  const key = result.status == null ? "error" : String(result.status);
12905
13044
  statusCounts[key] = (statusCounts[key] || 0) + 1;
12906
13045
  }
13046
+ const compactedResults = compactLinkProbeResults(results);
12907
13047
  return {
12908
13048
  version: "riddle-proof.link-status.v1",
12909
13049
  selector,
@@ -12911,6 +13051,8 @@ async function collectLinkStatus(check) {
12911
13051
  same_origin_only: linkProbeSameOriginOnly(check),
12912
13052
  dedupe: linkProbeDedupe(check),
12913
13053
  require_nonzero_bytes: check.require_nonzero_bytes === true,
13054
+ min_bytes: typeof check.min_bytes === "number" && Number.isFinite(check.min_bytes) ? check.min_bytes : null,
13055
+ allowed_content_types: Array.isArray(check.allowed_content_types) ? check.allowed_content_types : null,
12914
13056
  allowed_statuses: Array.isArray(check.allowed_statuses) && check.allowed_statuses.length
12915
13057
  ? check.allowed_statuses
12916
13058
  : typeof check.expected_status === "number"
@@ -12923,7 +13065,7 @@ async function collectLinkStatus(check) {
12923
13065
  failed_count: failures.length,
12924
13066
  status_counts: statusCounts,
12925
13067
  failures: failures.slice(0, 20),
12926
- results,
13068
+ ...compactedResults,
12927
13069
  };
12928
13070
  }
12929
13071
  async function frameEvidence(selector) {
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  resolveRiddleProofProfileTimeoutSec,
59
59
  slugifyRiddleProofProfileName,
60
60
  summarizeRiddleProofProfileResult
61
- } from "./chunk-FQ4QBY2N.js";
61
+ } from "./chunk-G3UY3SHZ.js";
62
62
  import {
63
63
  DEFAULT_RIDDLE_API_BASE_URL,
64
64
  DEFAULT_RIDDLE_API_KEY_FILE,