@riddledc/riddle-proof 0.7.126 → 0.7.127

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/cli.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  profileStatusExitCode,
13
13
  resolveRiddleProofProfileTargetUrl,
14
14
  resolveRiddleProofProfileTimeoutSec
15
- } from "./chunk-55KDZEB3.js";
15
+ } from "./chunk-JLINSUKO.js";
16
16
  import {
17
17
  createRiddleApiClient,
18
18
  parseRiddleViewport
@@ -741,6 +741,21 @@ function profileHttpStatusAssertionKeys(evidence, viewports, field) {
741
741
  }
742
742
  return [...keys];
743
743
  }
744
+ function profileHttpStatusJsonAssertionCount(viewports) {
745
+ if (!viewports.length) return void 0;
746
+ let passed = 0;
747
+ let total = 0;
748
+ for (const viewport of viewports) {
749
+ if (!Array.isArray(viewport.body_json_assertions)) continue;
750
+ for (const assertion of viewport.body_json_assertions) {
751
+ const record = cliRecord(assertion);
752
+ if (!record) continue;
753
+ total += 1;
754
+ if (record.ok === true) passed += 1;
755
+ }
756
+ }
757
+ return total ? { passed, total } : void 0;
758
+ }
744
759
  function profileHttpStatusSummaryMarkdown(result) {
745
760
  const httpStatusChecks = result.checks.filter((check) => check.type === "http_status");
746
761
  const lines = [];
@@ -771,10 +786,12 @@ function profileHttpStatusSummaryMarkdown(result) {
771
786
  profileHttpStatusAssertionKeys(evidence, viewports, "body_not_patterns"),
772
787
  false
773
788
  );
789
+ const bodyJsonAssertions = profileHttpStatusJsonAssertionCount(viewports);
774
790
  const bodyParts = [
775
791
  bodyContains ? `body_contains ${bodyContains.passed}/${bodyContains.total}` : "",
776
792
  bodyNotContains ? `body_not_contains clean ${bodyNotContains.passed}/${bodyNotContains.total}` : "",
777
- bodyNotPatterns ? `body_not_patterns clean ${bodyNotPatterns.passed}/${bodyNotPatterns.total}` : ""
793
+ bodyNotPatterns ? `body_not_patterns clean ${bodyNotPatterns.passed}/${bodyNotPatterns.total}` : "",
794
+ bodyJsonAssertions ? `body_json_assertions ${bodyJsonAssertions.passed}/${bodyJsonAssertions.total}` : ""
778
795
  ].filter(Boolean);
779
796
  lines.push(
780
797
  `- ${label}: ${method}${url ? ` ${markdownInlineCode(url)}` : ""}, statuses ${statuses.length ? statuses.join("/") : "unknown"}${bodyParts.length ? `, ${bodyParts.join(", ")}` : ""}, failures ${failedTotal}`
package/dist/index.cjs CHANGED
@@ -8872,6 +8872,9 @@ function valueFromOwn(input, ...keys) {
8872
8872
  function numberValue3(value) {
8873
8873
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
8874
8874
  }
8875
+ function booleanValue(value) {
8876
+ return typeof value === "boolean" ? value : void 0;
8877
+ }
8875
8878
  function horizontalBoundsOverflowPx2(value) {
8876
8879
  if (!isRecord2(value)) return 0;
8877
8880
  let max = maxPositiveNumber2(
@@ -8966,6 +8969,156 @@ function toJsonValue(value) {
8966
8969
  if (isRecord2(value)) return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
8967
8970
  return String(value);
8968
8971
  }
8972
+ function jsonValueType(value) {
8973
+ if (value === null) return "null";
8974
+ if (Array.isArray(value)) return "array";
8975
+ if (typeof value === "boolean") return "boolean";
8976
+ if (typeof value === "number") return "number";
8977
+ if (typeof value === "string") return "string";
8978
+ return "object";
8979
+ }
8980
+ function deepJsonEqual(left, right) {
8981
+ if (left === right) return true;
8982
+ if (typeof left !== typeof right) return false;
8983
+ if (left === null || right === null) return left === right;
8984
+ if (typeof left !== "object" || typeof right !== "object") return false;
8985
+ if (Array.isArray(left) || Array.isArray(right)) {
8986
+ if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) return false;
8987
+ return left.every((item, index) => deepJsonEqual(item, right[index]));
8988
+ }
8989
+ if (!isRecord2(left) || !isRecord2(right)) return false;
8990
+ const leftKeys = Object.keys(left).sort();
8991
+ const rightKeys = Object.keys(right).sort();
8992
+ if (!deepJsonEqual(leftKeys, rightKeys)) return false;
8993
+ return leftKeys.every((key) => deepJsonEqual(left[key], right[key]));
8994
+ }
8995
+ function jsonContains(observed, expected) {
8996
+ if (typeof observed === "string" && typeof expected === "string") {
8997
+ return observed.includes(expected);
8998
+ }
8999
+ if (Array.isArray(observed)) {
9000
+ return observed.some((item) => deepJsonEqual(item, expected));
9001
+ }
9002
+ if (isRecord2(observed) && isRecord2(expected)) {
9003
+ return Object.entries(expected).every(([key, value]) => hasOwn(observed, key) && deepJsonEqual(observed[key], value));
9004
+ }
9005
+ return false;
9006
+ }
9007
+ function parseJsonPathSegments(path6) {
9008
+ let input = path6.trim();
9009
+ if (!input) throw new Error("path is empty");
9010
+ if (input === "$") return [];
9011
+ if (input.startsWith("$.")) input = input.slice(2);
9012
+ else if (input.startsWith("$[")) input = input.slice(1);
9013
+ const segments = [];
9014
+ let token = "";
9015
+ const pushToken = () => {
9016
+ if (!token) return;
9017
+ segments.push(token);
9018
+ token = "";
9019
+ };
9020
+ for (let index = 0; index < input.length; index += 1) {
9021
+ const char = input[index];
9022
+ if (char === ".") {
9023
+ pushToken();
9024
+ continue;
9025
+ }
9026
+ if (char !== "[") {
9027
+ token += char;
9028
+ continue;
9029
+ }
9030
+ pushToken();
9031
+ const closeIndex = input.indexOf("]", index + 1);
9032
+ if (closeIndex === -1) throw new Error(`unterminated bracket at ${index}`);
9033
+ const bracket = input.slice(index + 1, closeIndex).trim();
9034
+ if (!bracket) throw new Error(`empty bracket at ${index}`);
9035
+ if (/^\d+$/.test(bracket)) {
9036
+ segments.push(Number(bracket));
9037
+ } else if (bracket.startsWith('"') && bracket.endsWith('"') || bracket.startsWith("'") && bracket.endsWith("'")) {
9038
+ const quoted = bracket.startsWith("'") ? `"${bracket.slice(1, -1).replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"` : bracket;
9039
+ segments.push(String(JSON.parse(quoted)));
9040
+ } else {
9041
+ segments.push(bracket);
9042
+ }
9043
+ index = closeIndex;
9044
+ }
9045
+ pushToken();
9046
+ return segments;
9047
+ }
9048
+ function resolveJsonPath(root, path6) {
9049
+ let segments;
9050
+ try {
9051
+ segments = parseJsonPathSegments(path6);
9052
+ } catch (error) {
9053
+ return { exists: false, error: String(error instanceof Error ? error.message : error) };
9054
+ }
9055
+ let current = root;
9056
+ for (const segment of segments) {
9057
+ if (typeof segment === "number") {
9058
+ if (!Array.isArray(current) || segment < 0 || segment >= current.length) return { exists: false };
9059
+ current = current[segment];
9060
+ continue;
9061
+ }
9062
+ if (!isRecord2(current) || !hasOwn(current, segment)) return { exists: false };
9063
+ current = current[segment];
9064
+ }
9065
+ return { exists: true, value: current };
9066
+ }
9067
+ function evaluateHttpStatusBodyJsonAssertion(root, assertion) {
9068
+ const resolved = resolveJsonPath(root, assertion.path);
9069
+ const errors = [];
9070
+ const result = {
9071
+ label: assertion.label || assertion.path,
9072
+ path: assertion.path,
9073
+ ok: true,
9074
+ exists: resolved.exists,
9075
+ observed_type: resolved.exists ? jsonValueType(resolved.value) : "missing"
9076
+ };
9077
+ if (resolved.exists) result.observed = toJsonValue(resolved.value);
9078
+ if (resolved.error) errors.push(resolved.error);
9079
+ if (hasOwn(assertion, "exists")) {
9080
+ result.expected_exists = assertion.exists;
9081
+ if (resolved.exists !== assertion.exists) errors.push(`expected exists=${assertion.exists}`);
9082
+ }
9083
+ if (hasOwn(assertion, "type")) {
9084
+ result.type = assertion.type;
9085
+ if (!resolved.exists || jsonValueType(resolved.value) !== assertion.type) errors.push(`expected type ${assertion.type}`);
9086
+ }
9087
+ if (hasOwn(assertion, "equals")) {
9088
+ result.equals = assertion.equals;
9089
+ if (!resolved.exists || !deepJsonEqual(resolved.value, assertion.equals)) errors.push("expected JSON value equality");
9090
+ }
9091
+ if (hasOwn(assertion, "not_equals")) {
9092
+ result.not_equals = assertion.not_equals;
9093
+ if (resolved.exists && deepJsonEqual(resolved.value, assertion.not_equals)) errors.push("expected JSON value inequality");
9094
+ }
9095
+ if (hasOwn(assertion, "contains")) {
9096
+ result.contains = assertion.contains;
9097
+ if (!resolved.exists || !jsonContains(resolved.value, assertion.contains)) errors.push("expected JSON value containment");
9098
+ }
9099
+ result.ok = errors.length === 0;
9100
+ if (errors.length) result.errors = errors;
9101
+ return result;
9102
+ }
9103
+ function evaluateHttpStatusBodyJsonAssertions(bodyText, assertions) {
9104
+ const expected = assertions?.filter((assertion) => assertion.path) ?? [];
9105
+ if (!expected.length) return [];
9106
+ let parsed;
9107
+ try {
9108
+ parsed = JSON.parse(bodyText);
9109
+ } catch (error) {
9110
+ const message = `response body is not valid JSON: ${String(error instanceof Error ? error.message : error).slice(0, 200)}`;
9111
+ return expected.map((assertion) => ({
9112
+ label: assertion.label || assertion.path,
9113
+ path: assertion.path,
9114
+ ok: false,
9115
+ exists: false,
9116
+ observed_type: "missing",
9117
+ errors: [message]
9118
+ }));
9119
+ }
9120
+ return expected.map((assertion) => evaluateHttpStatusBodyJsonAssertion(parsed, assertion));
9121
+ }
8969
9122
  function compactProfileSetupSummaryText(value, limit = 160) {
8970
9123
  const text = typeof value === "string" ? value.replace(/\s+/g, " ").trim() : "";
8971
9124
  if (!text) return void 0;
@@ -9620,6 +9773,46 @@ function validateRegexPatterns(patterns, label) {
9620
9773
  }
9621
9774
  }
9622
9775
  }
9776
+ function normalizeHttpStatusBodyJsonAssertions(value, label) {
9777
+ if (value === void 0) return void 0;
9778
+ if (!Array.isArray(value)) throw new Error(`${label} must be an array.`);
9779
+ if (!value.length) throw new Error(`${label} must not be empty.`);
9780
+ return value.map((item, index) => {
9781
+ const itemLabel = `${label}[${index}]`;
9782
+ if (typeof item === "string") {
9783
+ const path7 = stringValue5(item);
9784
+ if (!path7) throw new Error(`${itemLabel} path must not be empty.`);
9785
+ return { path: path7, exists: true };
9786
+ }
9787
+ if (!isRecord2(item)) throw new Error(`${itemLabel} must be an object or JSON path string.`);
9788
+ const path6 = stringFromOwn(item, "path", "json_path", "jsonPath", "key");
9789
+ if (!path6) throw new Error(`${itemLabel}.path is required.`);
9790
+ const assertion = {
9791
+ label: stringValue5(item.label),
9792
+ path: path6
9793
+ };
9794
+ const exists = booleanValue(valueFromOwn(item, "exists", "present"));
9795
+ if (exists !== void 0) assertion.exists = exists;
9796
+ const type = stringValue5(valueFromOwn(item, "type", "value_type", "valueType"));
9797
+ if (type !== void 0) {
9798
+ const allowedTypes = ["array", "boolean", "null", "number", "object", "string"];
9799
+ if (!allowedTypes.includes(type)) {
9800
+ throw new Error(`${itemLabel}.type must be one of ${allowedTypes.join(", ")}.`);
9801
+ }
9802
+ assertion.type = type;
9803
+ }
9804
+ const equalsValue = valueFromOwn(item, "equals", "expected", "expected_value", "expectedValue", "value");
9805
+ if (equalsValue !== void 0) assertion.equals = toJsonValue(equalsValue);
9806
+ const notEqualsValue = valueFromOwn(item, "not_equals", "notEquals", "forbidden", "forbidden_value", "forbiddenValue");
9807
+ if (notEqualsValue !== void 0) assertion.not_equals = toJsonValue(notEqualsValue);
9808
+ const containsValue = valueFromOwn(item, "contains", "includes", "contains_value", "containsValue", "include");
9809
+ if (containsValue !== void 0) assertion.contains = toJsonValue(containsValue);
9810
+ if (assertion.exists === void 0 && assertion.type === void 0 && !hasOwn(assertion, "equals") && !hasOwn(assertion, "not_equals") && !hasOwn(assertion, "contains")) {
9811
+ assertion.exists = true;
9812
+ }
9813
+ return assertion;
9814
+ });
9815
+ }
9623
9816
  function isDialogCountCheckType(type) {
9624
9817
  return type === "dialog_count_equals" || type === "dialog_accept_count_equals" || type === "dialog_dismiss_count_equals";
9625
9818
  }
@@ -9719,6 +9912,10 @@ function normalizeCheck(input, index) {
9719
9912
  `checks[${index}] body_not_patterns`
9720
9913
  ) : void 0;
9721
9914
  if (bodyNotPatterns?.length) validateRegexPatterns(bodyNotPatterns, `checks[${index}] body_not_patterns`);
9915
+ const bodyJsonAssertions = isHttpStatusCheck ? normalizeHttpStatusBodyJsonAssertions(
9916
+ input.body_json_assertions ?? input.bodyJsonAssertions ?? input.json_body_assertions ?? input.jsonBodyAssertions ?? input.json_assertions ?? input.jsonAssertions ?? input.response_json_assertions ?? input.responseJsonAssertions,
9917
+ `checks[${index}] body_json_assertions`
9918
+ ) : void 0;
9722
9919
  if (isLinkStatusCheck) {
9723
9920
  if (minCount !== void 0 && (!Number.isInteger(minCount) || minCount < 0)) {
9724
9921
  throw new Error(`checks[${index}] ${type} min_count must be a non-negative integer.`);
@@ -9744,6 +9941,7 @@ function normalizeCheck(input, index) {
9744
9941
  body_contains: bodyContains,
9745
9942
  body_not_contains: bodyNotContains,
9746
9943
  body_not_patterns: bodyNotPatterns,
9944
+ body_json_assertions: bodyJsonAssertions,
9747
9945
  expected_texts: expectedTexts,
9748
9946
  link_selector: stringValue5(input.link_selector) || stringValue5(input.linkSelector),
9749
9947
  source_selector: stringValue5(input.source_selector) || stringValue5(input.sourceSelector),
@@ -9950,6 +10148,34 @@ function httpStatusBodyNotPatternFailures(result, check) {
9950
10148
  const observed = isRecord2(result.body_not_patterns) ? result.body_not_patterns : {};
9951
10149
  return forbidden.filter((pattern) => observed[pattern] !== false);
9952
10150
  }
10151
+ function httpStatusBodyJsonAssertionFailures(result, check) {
10152
+ const expected = check.body_json_assertions?.filter((assertion) => assertion.path) ?? [];
10153
+ if (!expected.length) return [];
10154
+ if (!Array.isArray(result.body_json_assertions)) {
10155
+ return expected.map((assertion) => ({
10156
+ label: assertion.label || assertion.path,
10157
+ path: assertion.path,
10158
+ ok: false,
10159
+ exists: false,
10160
+ observed_type: "missing",
10161
+ errors: ["body_json_assertions evidence missing"]
10162
+ }));
10163
+ }
10164
+ return result.body_json_assertions.filter((assertion) => isRecord2(assertion) && assertion.ok !== true).map((assertion) => ({
10165
+ label: stringValue5(assertion.label) || stringValue5(assertion.path) || "json assertion",
10166
+ path: stringValue5(assertion.path) || "",
10167
+ ok: false,
10168
+ exists: assertion.exists === true,
10169
+ observed: hasOwn(assertion, "observed") ? toJsonValue(assertion.observed) : void 0,
10170
+ observed_type: stringValue5(assertion.observed_type) || "missing",
10171
+ expected_exists: booleanValue(assertion.expected_exists),
10172
+ equals: hasOwn(assertion, "equals") ? toJsonValue(assertion.equals) : void 0,
10173
+ not_equals: hasOwn(assertion, "not_equals") ? toJsonValue(assertion.not_equals) : void 0,
10174
+ contains: hasOwn(assertion, "contains") ? toJsonValue(assertion.contains) : void 0,
10175
+ type: stringValue5(assertion.type),
10176
+ errors: Array.isArray(assertion.errors) ? assertion.errors.map(String) : void 0
10177
+ }));
10178
+ }
9953
10179
  function linkStatusResultOk(result, check) {
9954
10180
  const status = numberValue3(result.status);
9955
10181
  if (!httpStatusIsAllowed(status, check)) return false;
@@ -9967,6 +10193,7 @@ function linkStatusResultOk(result, check) {
9967
10193
  if (httpStatusBodyContainsFailures(result, check).length) return false;
9968
10194
  if (httpStatusBodyNotContainsFailures(result, check).length) return false;
9969
10195
  if (httpStatusBodyNotPatternFailures(result, check).length) return false;
10196
+ if (httpStatusBodyJsonAssertionFailures(result, check).length) return false;
9970
10197
  return true;
9971
10198
  }
9972
10199
  function responseHeader(response, name) {
@@ -10035,7 +10262,7 @@ async function preflightHttpStatusCheck(check, index, targetUrl, fetchImpl) {
10035
10262
  statusText = typeof response.statusText === "string" ? response.statusText : "";
10036
10263
  result.content_type = responseHeader(response, "content-type");
10037
10264
  result.content_length = responseContentLength(response);
10038
- const shouldReadBody = check.require_nonzero_bytes === true || typeof check.min_bytes === "number" || Boolean(check.body_contains?.length) || Boolean(check.body_not_contains?.length) || Boolean(check.body_not_patterns?.length);
10265
+ const shouldReadBody = check.require_nonzero_bytes === true || typeof check.min_bytes === "number" || Boolean(check.body_contains?.length) || Boolean(check.body_not_contains?.length) || Boolean(check.body_not_patterns?.length) || Boolean(check.body_json_assertions?.length);
10039
10266
  if (shouldReadBody && method !== "HEAD") {
10040
10267
  const body = await responseBodyText(response);
10041
10268
  result.bytes = body.bytes;
@@ -10048,6 +10275,9 @@ async function preflightHttpStatusCheck(check, index, targetUrl, fetchImpl) {
10048
10275
  if (check.body_not_patterns?.length) {
10049
10276
  result.body_not_patterns = Object.fromEntries(check.body_not_patterns.filter(Boolean).map((pattern) => [pattern, new RegExp(pattern).test(body.text)]));
10050
10277
  }
10278
+ if (check.body_json_assertions?.length) {
10279
+ result.body_json_assertions = evaluateHttpStatusBodyJsonAssertions(body.text, check.body_json_assertions);
10280
+ }
10051
10281
  }
10052
10282
  } catch (caught) {
10053
10283
  error = String(caught instanceof Error ? caught.message : caught).slice(0, 500);
@@ -10056,6 +10286,7 @@ async function preflightHttpStatusCheck(check, index, targetUrl, fetchImpl) {
10056
10286
  const bodyContainsMissing = httpStatusBodyContainsFailures(result, check);
10057
10287
  const bodyNotContainsFound = httpStatusBodyNotContainsFailures(result, check);
10058
10288
  const bodyNotPatternsFound = httpStatusBodyNotPatternFailures(result, check);
10289
+ const bodyJsonAssertionsFailed = httpStatusBodyJsonAssertionFailures(result, check);
10059
10290
  const ok = !error && linkStatusResultOk(result, check);
10060
10291
  return {
10061
10292
  index,
@@ -10074,7 +10305,9 @@ async function preflightHttpStatusCheck(check, index, targetUrl, fetchImpl) {
10074
10305
  body_not_contains: isRecord2(result.body_not_contains) ? Object.fromEntries(Object.entries(result.body_not_contains).map(([key, value]) => [key, value === true])) : null,
10075
10306
  body_not_contains_found: bodyNotContainsFound,
10076
10307
  body_not_patterns: isRecord2(result.body_not_patterns) ? Object.fromEntries(Object.entries(result.body_not_patterns).map(([key, value]) => [key, value === true])) : null,
10077
- body_not_patterns_found: bodyNotPatternsFound
10308
+ body_not_patterns_found: bodyNotPatternsFound,
10309
+ body_json_assertions: Array.isArray(result.body_json_assertions) ? result.body_json_assertions : null,
10310
+ body_json_assertions_failed: bodyJsonAssertionsFailed
10078
10311
  };
10079
10312
  }
10080
10313
  async function preflightRiddleProofProfileHttpStatusChecks(profile, options = {}) {
@@ -10119,6 +10352,7 @@ function summarizeHttpStatusEvidence(viewport, check) {
10119
10352
  const bodyContainsMissing = httpStatusBodyContainsFailures(statusEvidence, check);
10120
10353
  const bodyNotContainsFound = httpStatusBodyNotContainsFailures(statusEvidence, check);
10121
10354
  const bodyNotPatternsFound = httpStatusBodyNotPatternFailures(statusEvidence, check);
10355
+ const bodyJsonAssertionsFailed = httpStatusBodyJsonAssertionFailures(statusEvidence, check);
10122
10356
  if (!linkStatusResultOk(statusEvidence, check)) {
10123
10357
  failures.push({
10124
10358
  code: "http_status_failed",
@@ -10137,6 +10371,8 @@ function summarizeHttpStatusEvidence(viewport, check) {
10137
10371
  body_not_contains_found: bodyNotContainsFound,
10138
10372
  body_not_patterns: check.body_not_patterns ?? null,
10139
10373
  body_not_patterns_found: bodyNotPatternsFound,
10374
+ body_json_assertions: check.body_json_assertions ?? null,
10375
+ body_json_assertions_failed: bodyJsonAssertionsFailed.map((assertion) => toJsonValue(assertion)),
10140
10376
  body_sample: stringValue5(statusEvidence.body_sample) ?? null
10141
10377
  });
10142
10378
  }
@@ -10158,6 +10394,8 @@ function summarizeHttpStatusEvidence(viewport, check) {
10158
10394
  body_not_contains_found: bodyNotContainsFound,
10159
10395
  body_not_patterns: isRecord2(statusEvidence.body_not_patterns) ? toJsonValue(statusEvidence.body_not_patterns) : null,
10160
10396
  body_not_patterns_found: bodyNotPatternsFound,
10397
+ body_json_assertions: Array.isArray(statusEvidence.body_json_assertions) ? toJsonValue(statusEvidence.body_json_assertions) : null,
10398
+ body_json_assertions_failed: bodyJsonAssertionsFailed.map((assertion) => toJsonValue(assertion)),
10161
10399
  body_sample: stringValue5(statusEvidence.body_sample) ?? null,
10162
10400
  failures
10163
10401
  };
@@ -10794,6 +11032,7 @@ function assessCheckFromEvidence(check, evidence) {
10794
11032
  body_contains: check.body_contains ?? [],
10795
11033
  body_not_contains: check.body_not_contains ?? [],
10796
11034
  body_not_patterns: check.body_not_patterns ?? [],
11035
+ body_json_assertions: toJsonValue(check.body_json_assertions ?? []),
10797
11036
  viewports: summaries.map((summary) => toJsonValue(summary)),
10798
11037
  failures: failed.flatMap((summary) => Array.isArray(summary.failures) ? summary.failures.map((failure) => toJsonValue({ viewport: stringValue5(summary.viewport) ?? null, failure })) : [])
10799
11038
  },
@@ -11537,6 +11776,36 @@ function httpStatusBodyNotPatternFailures(result, check) {
11537
11776
  : {};
11538
11777
  return forbidden.filter((pattern) => observed[pattern] !== false);
11539
11778
  }
11779
+ function httpStatusBodyJsonAssertionFailures(result, check) {
11780
+ const expected = Array.isArray(check.body_json_assertions) ? check.body_json_assertions.filter((assertion) => assertion && assertion.path) : [];
11781
+ if (!expected.length) return [];
11782
+ if (!Array.isArray(result.body_json_assertions)) {
11783
+ return expected.map((assertion) => ({
11784
+ label: assertion.label || assertion.path,
11785
+ path: assertion.path,
11786
+ ok: false,
11787
+ exists: false,
11788
+ observed_type: "missing",
11789
+ errors: ["body_json_assertions evidence missing"],
11790
+ }));
11791
+ }
11792
+ return result.body_json_assertions
11793
+ .filter((assertion) => assertion && typeof assertion === "object" && assertion.ok !== true)
11794
+ .map((assertion) => ({
11795
+ label: typeof assertion.label === "string" && assertion.label ? assertion.label : typeof assertion.path === "string" && assertion.path ? assertion.path : "json assertion",
11796
+ path: typeof assertion.path === "string" ? assertion.path : "",
11797
+ ok: false,
11798
+ exists: assertion.exists === true,
11799
+ observed: Object.hasOwn(assertion, "observed") ? assertion.observed : undefined,
11800
+ observed_type: typeof assertion.observed_type === "string" && assertion.observed_type ? assertion.observed_type : "missing",
11801
+ expected_exists: typeof assertion.expected_exists === "boolean" ? assertion.expected_exists : undefined,
11802
+ equals: Object.hasOwn(assertion, "equals") ? assertion.equals : undefined,
11803
+ not_equals: Object.hasOwn(assertion, "not_equals") ? assertion.not_equals : undefined,
11804
+ contains: Object.hasOwn(assertion, "contains") ? assertion.contains : undefined,
11805
+ type: typeof assertion.type === "string" ? assertion.type : undefined,
11806
+ errors: Array.isArray(assertion.errors) ? assertion.errors.map(String) : undefined,
11807
+ }));
11808
+ }
11540
11809
  function linkStatusResultOk(result, check) {
11541
11810
  if (!result || typeof result !== "object" || Array.isArray(result)) return false;
11542
11811
  if (!httpStatusIsAllowed(result.status, check)) return false;
@@ -11554,6 +11823,7 @@ function linkStatusResultOk(result, check) {
11554
11823
  if (httpStatusBodyContainsFailures(result, check).length) return false;
11555
11824
  if (httpStatusBodyNotContainsFailures(result, check).length) return false;
11556
11825
  if (httpStatusBodyNotPatternFailures(result, check).length) return false;
11826
+ if (httpStatusBodyJsonAssertionFailures(result, check).length) return false;
11557
11827
  return true;
11558
11828
  }
11559
11829
  function summarizeHttpStatusEvidence(viewport, check) {
@@ -11574,6 +11844,7 @@ function summarizeHttpStatusEvidence(viewport, check) {
11574
11844
  const bodyContainsMissing = httpStatusBodyContainsFailures(statusEvidence, check);
11575
11845
  const bodyNotContainsFound = httpStatusBodyNotContainsFailures(statusEvidence, check);
11576
11846
  const bodyNotPatternsFound = httpStatusBodyNotPatternFailures(statusEvidence, check);
11847
+ const bodyJsonAssertionsFailed = httpStatusBodyJsonAssertionFailures(statusEvidence, check);
11577
11848
  if (!linkStatusResultOk(statusEvidence, check)) {
11578
11849
  failures.push({
11579
11850
  code: "http_status_failed",
@@ -11592,6 +11863,8 @@ function summarizeHttpStatusEvidence(viewport, check) {
11592
11863
  body_not_contains_found: bodyNotContainsFound,
11593
11864
  body_not_patterns: Array.isArray(check.body_not_patterns) ? check.body_not_patterns : null,
11594
11865
  body_not_patterns_found: bodyNotPatternsFound,
11866
+ body_json_assertions: Array.isArray(check.body_json_assertions) ? check.body_json_assertions : null,
11867
+ body_json_assertions_failed: bodyJsonAssertionsFailed,
11595
11868
  body_sample: typeof statusEvidence.body_sample === "string" ? statusEvidence.body_sample : null,
11596
11869
  });
11597
11870
  }
@@ -11619,6 +11892,8 @@ function summarizeHttpStatusEvidence(viewport, check) {
11619
11892
  ? statusEvidence.body_not_patterns
11620
11893
  : null,
11621
11894
  body_not_patterns_found: bodyNotPatternsFound,
11895
+ body_json_assertions: Array.isArray(statusEvidence.body_json_assertions) ? statusEvidence.body_json_assertions : null,
11896
+ body_json_assertions_failed: bodyJsonAssertionsFailed,
11622
11897
  body_sample: typeof statusEvidence.body_sample === "string" ? statusEvidence.body_sample : null,
11623
11898
  failures,
11624
11899
  };
@@ -13721,6 +13996,155 @@ function linkProbeResponseFields(response, method) {
13721
13996
  content_length: contentLength,
13722
13997
  };
13723
13998
  }
13999
+ function jsonProbeValueType(value) {
14000
+ if (value === null) return "null";
14001
+ if (Array.isArray(value)) return "array";
14002
+ if (typeof value === "boolean") return "boolean";
14003
+ if (typeof value === "number") return "number";
14004
+ if (typeof value === "string") return "string";
14005
+ return "object";
14006
+ }
14007
+ function jsonProbeDeepEqual(left, right) {
14008
+ if (left === right) return true;
14009
+ if (typeof left !== typeof right) return false;
14010
+ if (left === null || right === null) return left === right;
14011
+ if (typeof left !== "object" || typeof right !== "object") return false;
14012
+ if (Array.isArray(left) || Array.isArray(right)) {
14013
+ if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) return false;
14014
+ return left.every((item, index) => jsonProbeDeepEqual(item, right[index]));
14015
+ }
14016
+ const leftKeys = Object.keys(left).sort();
14017
+ const rightKeys = Object.keys(right).sort();
14018
+ if (!jsonProbeDeepEqual(leftKeys, rightKeys)) return false;
14019
+ return leftKeys.every((key) => jsonProbeDeepEqual(left[key], right[key]));
14020
+ }
14021
+ function jsonProbeContains(observed, expected) {
14022
+ if (typeof observed === "string" && typeof expected === "string") return observed.includes(expected);
14023
+ if (Array.isArray(observed)) return observed.some((item) => jsonProbeDeepEqual(item, expected));
14024
+ if (observed && expected && typeof observed === "object" && typeof expected === "object" && !Array.isArray(observed) && !Array.isArray(expected)) {
14025
+ return Object.entries(expected).every(([key, value]) => Object.hasOwn(observed, key) && jsonProbeDeepEqual(observed[key], value));
14026
+ }
14027
+ return false;
14028
+ }
14029
+ function parseJsonProbePathSegments(path) {
14030
+ let input = String(path || "").trim();
14031
+ if (!input) throw new Error("path is empty");
14032
+ if (input === "$") return [];
14033
+ if (input.startsWith("$.")) input = input.slice(2);
14034
+ else if (input.startsWith("$[")) input = input.slice(1);
14035
+ const segments = [];
14036
+ let token = "";
14037
+ const pushToken = () => {
14038
+ if (!token) return;
14039
+ segments.push(token);
14040
+ token = "";
14041
+ };
14042
+ for (let index = 0; index < input.length; index += 1) {
14043
+ const char = input[index];
14044
+ if (char === ".") {
14045
+ pushToken();
14046
+ continue;
14047
+ }
14048
+ if (char !== "[") {
14049
+ token += char;
14050
+ continue;
14051
+ }
14052
+ pushToken();
14053
+ const closeIndex = input.indexOf("]", index + 1);
14054
+ if (closeIndex === -1) throw new Error("unterminated bracket at " + index);
14055
+ const bracket = input.slice(index + 1, closeIndex).trim();
14056
+ if (!bracket) throw new Error("empty bracket at " + index);
14057
+ if (/^\d+$/.test(bracket)) {
14058
+ segments.push(Number(bracket));
14059
+ } else if ((bracket.startsWith('"') && bracket.endsWith('"')) || (bracket.startsWith("'") && bracket.endsWith("'"))) {
14060
+ const quoted = bracket.startsWith("'")
14061
+ ? '"' + bracket.slice(1, -1).replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + '"'
14062
+ : bracket;
14063
+ segments.push(String(JSON.parse(quoted)));
14064
+ } else {
14065
+ segments.push(bracket);
14066
+ }
14067
+ index = closeIndex;
14068
+ }
14069
+ pushToken();
14070
+ return segments;
14071
+ }
14072
+ function resolveJsonProbePath(root, path) {
14073
+ let segments;
14074
+ try {
14075
+ segments = parseJsonProbePathSegments(path);
14076
+ } catch (error) {
14077
+ return { exists: false, error: String(error && error.message ? error.message : error) };
14078
+ }
14079
+ let current = root;
14080
+ for (const segment of segments) {
14081
+ if (typeof segment === "number") {
14082
+ if (!Array.isArray(current) || segment < 0 || segment >= current.length) return { exists: false };
14083
+ current = current[segment];
14084
+ continue;
14085
+ }
14086
+ if (!current || typeof current !== "object" || Array.isArray(current) || !Object.hasOwn(current, segment)) {
14087
+ return { exists: false };
14088
+ }
14089
+ current = current[segment];
14090
+ }
14091
+ return { exists: true, value: current };
14092
+ }
14093
+ function evaluateJsonProbeAssertion(root, assertion) {
14094
+ const resolved = resolveJsonProbePath(root, assertion.path);
14095
+ const errors = [];
14096
+ const result = {
14097
+ label: assertion.label || assertion.path,
14098
+ path: assertion.path,
14099
+ ok: true,
14100
+ exists: resolved.exists,
14101
+ observed_type: resolved.exists ? jsonProbeValueType(resolved.value) : "missing",
14102
+ };
14103
+ if (resolved.exists) result.observed = resolved.value;
14104
+ if (resolved.error) errors.push(resolved.error);
14105
+ if (Object.hasOwn(assertion, "exists")) {
14106
+ result.expected_exists = assertion.exists;
14107
+ if (resolved.exists !== assertion.exists) errors.push("expected exists=" + assertion.exists);
14108
+ }
14109
+ if (Object.hasOwn(assertion, "type")) {
14110
+ result.type = assertion.type;
14111
+ if (!resolved.exists || jsonProbeValueType(resolved.value) !== assertion.type) errors.push("expected type " + assertion.type);
14112
+ }
14113
+ if (Object.hasOwn(assertion, "equals")) {
14114
+ result.equals = assertion.equals;
14115
+ if (!resolved.exists || !jsonProbeDeepEqual(resolved.value, assertion.equals)) errors.push("expected JSON value equality");
14116
+ }
14117
+ if (Object.hasOwn(assertion, "not_equals")) {
14118
+ result.not_equals = assertion.not_equals;
14119
+ if (resolved.exists && jsonProbeDeepEqual(resolved.value, assertion.not_equals)) errors.push("expected JSON value inequality");
14120
+ }
14121
+ if (Object.hasOwn(assertion, "contains")) {
14122
+ result.contains = assertion.contains;
14123
+ if (!resolved.exists || !jsonProbeContains(resolved.value, assertion.contains)) errors.push("expected JSON value containment");
14124
+ }
14125
+ result.ok = errors.length === 0;
14126
+ if (errors.length) result.errors = errors;
14127
+ return result;
14128
+ }
14129
+ function evaluateJsonProbeAssertions(text, assertions) {
14130
+ const expected = Array.isArray(assertions) ? assertions.filter((assertion) => assertion && assertion.path) : [];
14131
+ if (!expected.length) return [];
14132
+ let parsed;
14133
+ try {
14134
+ parsed = JSON.parse(text);
14135
+ } catch (error) {
14136
+ const message = "response body is not valid JSON: " + String(error && error.message ? error.message : error).slice(0, 200);
14137
+ return expected.map((assertion) => ({
14138
+ label: assertion.label || assertion.path,
14139
+ path: assertion.path,
14140
+ ok: false,
14141
+ exists: false,
14142
+ observed_type: "missing",
14143
+ errors: [message],
14144
+ }));
14145
+ }
14146
+ return expected.map((assertion) => evaluateJsonProbeAssertion(parsed, assertion));
14147
+ }
13724
14148
  async function collectHttpStatus(check) {
13725
14149
  const url = httpStatusRequestUrl(check, page.url() || targetUrl);
13726
14150
  const method = httpStatusMethod(check);
@@ -13737,6 +14161,7 @@ async function collectHttpStatus(check) {
13737
14161
  const bodyContains = Array.isArray(check.body_contains) ? check.body_contains.filter(Boolean) : [];
13738
14162
  const bodyNotContains = Array.isArray(check.body_not_contains) ? check.body_not_contains.filter(Boolean) : [];
13739
14163
  const bodyNotPatterns = Array.isArray(check.body_not_patterns) ? check.body_not_patterns.filter(Boolean) : [];
14164
+ const bodyJsonAssertions = Array.isArray(check.body_json_assertions) ? check.body_json_assertions.filter((assertion) => assertion && assertion.path) : [];
13740
14165
  const options = {
13741
14166
  method,
13742
14167
  redirect: "follow",
@@ -13762,17 +14187,18 @@ async function collectHttpStatus(check) {
13762
14187
  Object.assign(result, linkProbeResponseFields(response, method));
13763
14188
  result.url = url;
13764
14189
  result.status_text = response.statusText || "";
13765
- const shouldReadBody = check.require_nonzero_bytes === true || (typeof check.min_bytes === "number" && Number.isFinite(check.min_bytes)) || bodyContains.length > 0 || bodyNotContains.length > 0 || bodyNotPatterns.length > 0;
14190
+ const shouldReadBody = check.require_nonzero_bytes === true || (typeof check.min_bytes === "number" && Number.isFinite(check.min_bytes)) || bodyContains.length > 0 || bodyNotContains.length > 0 || bodyNotPatterns.length > 0 || bodyJsonAssertions.length > 0;
13766
14191
  if (shouldReadBody) {
13767
14192
  try {
13768
14193
  const buffer = await response.arrayBuffer();
13769
14194
  result.bytes = buffer.byteLength;
13770
- if (bodyContains.length || bodyNotContains.length || bodyNotPatterns.length) {
14195
+ if (bodyContains.length || bodyNotContains.length || bodyNotPatterns.length || bodyJsonAssertions.length) {
13771
14196
  const text = new TextDecoder().decode(buffer);
13772
14197
  result.body_sample = text.slice(0, 1000);
13773
14198
  if (bodyContains.length) result.body_contains = Object.fromEntries(bodyContains.map((expected) => [expected, text.includes(expected)]));
13774
14199
  if (bodyNotContains.length) result.body_not_contains = Object.fromEntries(bodyNotContains.map((forbidden) => [forbidden, text.includes(forbidden)]));
13775
14200
  if (bodyNotPatterns.length) result.body_not_patterns = Object.fromEntries(bodyNotPatterns.map((pattern) => [pattern, new RegExp(pattern).test(text)]));
14201
+ if (bodyJsonAssertions.length) result.body_json_assertions = evaluateJsonProbeAssertions(text, bodyJsonAssertions);
13776
14202
  }
13777
14203
  } catch (error) {
13778
14204
  result.error = String(error && error.message ? error.message : error).slice(0, 500);
@@ -13785,6 +14211,7 @@ async function collectHttpStatus(check) {
13785
14211
  && (!bodyContains.length || bodyContains.every((expected) => result.body_contains && result.body_contains[expected] === true))
13786
14212
  && (!bodyNotContains.length || bodyNotContains.every((forbidden) => result.body_not_contains && result.body_not_contains[forbidden] === false))
13787
14213
  && (!bodyNotPatterns.length || bodyNotPatterns.every((pattern) => result.body_not_patterns && result.body_not_patterns[pattern] === false))
14214
+ && (!bodyJsonAssertions.length || (Array.isArray(result.body_json_assertions) && result.body_json_assertions.every((assertion) => assertion.ok === true)))
13788
14215
  && !result.error;
13789
14216
  return result;
13790
14217
  } catch (error) {
package/dist/index.d.cts CHANGED
@@ -10,5 +10,5 @@ export { CreateCaptureDiagnosticInput, DEFAULT_DIAGNOSTIC_ARRAY_LIMIT, DEFAULT_D
10
10
  export { BuildVisualProofSessionInput, RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION, RIDDLE_PROOF_VISUAL_SESSION_VERSION, VisualProofSessionMismatch, buildVisualProofSession, compareVisualProofSessionFingerprint, parseVisualProofSession, visualSessionFingerprint, visualSessionFingerprintBasis } from './proof-session.cjs';
11
11
  export { AssessPlayabilityOptions, RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION, RIDDLE_PROOF_PLAYABILITY_VERSION, RiddleProofPlayabilityAssessment, RiddleProofPlayabilityEvidence, assessPlayabilityEvidence, extractPlayabilityEvidence, isRiddleProofPlayabilityMode } from './playability.cjs';
12
12
  export { AssessBasicGameplayOptions, AttachBasicGameplayArtifactOptions, BASIC_GAMEPLAY_ACTION_TYPES, BASIC_GAMEPLAY_PROGRESS_CHECK_TYPES, BasicGameplayActionResult, BasicGameplayActionType, BasicGameplayArtifactResolution, BasicGameplayAssessmentSummary, BasicGameplayBoundsOffender, BasicGameplayCanvasState, BasicGameplayCatchRecord, BasicGameplayChangeSummary, BasicGameplayFailureCode, BasicGameplayFixReference, BasicGameplayMetric, BasicGameplayMobileEvidence, BasicGameplayProgressCheckType, BasicGameplayProgressionCheck, BasicGameplayProofArtifact, BasicGameplayResponsiveViewportEvidence, BasicGameplayRouteReference, BasicGameplaySnapshot, BasicGameplaySuiteFailure, BasicGameplayWarningCode, CreateBasicGameplayCatchSummaryInput, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, RiddleProofBasicGameplayAssessment, RiddleProofBasicGameplayCatchSummary, RiddleProofBasicGameplayEvidence, RiddleProofBasicGameplayRouteAssessment, RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayProgressionCheck, assessBasicGameplayProgressionChecks, assessBasicGameplayRoute, attachBasicGameplayArtifactScreenshotHashes, augmentBasicGameplayAssessmentWithProgressionChecks, compactBasicGameplayText, createBasicGameplayCatchRecords, createBasicGameplayCatchSummary, extractBasicGameplayEvidence, resolveBasicGameplayProgressionCheckWithArtifactScreenshots, sanitizeBasicGameplayJsonString } from './basic-gameplay.cjs';
13
- export { NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_NETWORK_ABORT_ERROR_CODES, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, RiddleProofArtifactBodyAssertionInput, RiddleProofArtifactBodyAssertionResult, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileHttpStatusPreflightCheckResult, RiddleProofProfileHttpStatusPreflightFetch, RiddleProofProfileHttpStatusPreflightFetchResponse, RiddleProofProfileHttpStatusPreflightOptions, RiddleProofProfileHttpStatusPreflightResult, RiddleProofProfileNetworkAbortErrorCode, RiddleProofProfileNetworkMock, RiddleProofProfileNetworkMockResponse, RiddleProofProfileResult, RiddleProofProfileRouteEvidence, RiddleProofProfileRouteInventoryRoute, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, collectRiddleProofProfileWarnings, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, deriveRiddleProofArtifactBodyAssertions, extractRiddleProofProfileResult, normalizeRiddleProofProfile, preflightRiddleProofProfileHttpStatusChecks, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult } from './profile.cjs';
13
+ export { NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_NETWORK_ABORT_ERROR_CODES, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, RiddleProofArtifactBodyAssertionInput, RiddleProofArtifactBodyAssertionResult, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileHttpStatusBodyJsonAssertion, RiddleProofProfileHttpStatusBodyJsonAssertionResult, RiddleProofProfileHttpStatusPreflightCheckResult, RiddleProofProfileHttpStatusPreflightFetch, RiddleProofProfileHttpStatusPreflightFetchResponse, RiddleProofProfileHttpStatusPreflightOptions, RiddleProofProfileHttpStatusPreflightResult, RiddleProofProfileJsonValueType, RiddleProofProfileNetworkAbortErrorCode, RiddleProofProfileNetworkMock, RiddleProofProfileNetworkMockResponse, RiddleProofProfileResult, RiddleProofProfileRouteEvidence, RiddleProofProfileRouteInventoryRoute, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, collectRiddleProofProfileWarnings, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, deriveRiddleProofArtifactBodyAssertions, extractRiddleProofProfileResult, normalizeRiddleProofProfile, preflightRiddleProofProfileHttpStatusChecks, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult } from './profile.cjs';
14
14
  export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleClientConfig, RiddleFetch, RiddlePollJobOptions, RiddlePollJobResult, RiddlePollProgressSnapshot, RiddlePollSummary, RiddlePreviewDeployResult, RiddlePreviewFramework, RiddleRunScriptInput, RiddleServerPreviewInput, RiddleServerPreviewResult, createRiddleApiClient, deployRiddlePreview, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript, runRiddleServerPreview } from './riddle-client.cjs';