@riddledc/riddle-proof 0.7.39 → 0.7.40

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/README.md CHANGED
@@ -182,7 +182,35 @@ before navigation, records each hit, and adds an implicit
182
182
  `network_mocks_succeeded` check when mocks are present. A mock supports
183
183
  `url`/`glob`/`pattern`, optional `method`, `status`, `content_type`, `headers`,
184
184
  string `body`, JSON `json` / `body_json`, and `required: false` for
185
- best-effort mocks.
185
+ best-effort mocks. Use `responses` for retry or recovery profiles where the
186
+ same endpoint should return a sequence, such as first `503` and then `200`.
187
+ Each response accepts the same payload fields plus an optional label:
188
+
189
+ ```json
190
+ {
191
+ "label": "builder-build",
192
+ "url": "**/api/build",
193
+ "method": "POST",
194
+ "responses": [
195
+ {
196
+ "label": "first-build-fails",
197
+ "status": 503,
198
+ "json": { "error": "Synthetic build outage" }
199
+ },
200
+ {
201
+ "label": "second-build-succeeds",
202
+ "status": 200,
203
+ "json": { "previewUrl": "https://cdn.example/game/index.html" }
204
+ }
205
+ ]
206
+ }
207
+ ```
208
+
209
+ When `responses` is present, `network_mocks_succeeded` requires each configured
210
+ response to be hit at least once by default and records `hit_index`,
211
+ `response_index`, and `response_label` for each request. Set
212
+ `required_hit_count` / `min_hits` or `required: false` when a different
213
+ contract is intentional.
186
214
 
187
215
  `target.setup_actions` is optional. Use it when the meaningful proof surface
188
216
  appears only after a picker, tab, login stub, storage seed, form fill,
@@ -246,24 +246,57 @@ function normalizeNetworkMock(input, index) {
246
246
  if (!isRecord(input)) throw new Error(`target.network_mocks[${index}] must be an object.`);
247
247
  const url = stringValue(input.url) || stringValue(input.glob) || stringValue(input.pattern);
248
248
  if (!url) throw new Error(`target.network_mocks[${index}] requires url.`);
249
- const status = numberValue(input.status) ?? 200;
250
- if (!Number.isInteger(status) || status < 100 || status > 599) {
251
- throw new Error(`target.network_mocks[${index}].status must be an HTTP status code.`);
249
+ const payload = normalizeNetworkMockResponsePayload(input, `target.network_mocks[${index}]`);
250
+ const responsesInput = input.responses ?? input.sequence;
251
+ const responses = normalizeNetworkMockResponses(responsesInput, index, payload);
252
+ const requiredHitCount = numberValue(
253
+ input.required_hit_count ?? input.requiredHitCount ?? input.required_hits ?? input.requiredHits ?? input.min_hits ?? input.minHits
254
+ );
255
+ if (requiredHitCount !== void 0 && (!Number.isInteger(requiredHitCount) || requiredHitCount < 1)) {
256
+ throw new Error(`target.network_mocks[${index}].required_hit_count must be a positive integer.`);
252
257
  }
253
- const body = stringValue(input.body) ?? stringValue(input.body_text) ?? stringValue(input.bodyText);
254
- const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
255
258
  return {
259
+ ...payload,
256
260
  label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
257
261
  url,
258
262
  method: stringValue(input.method)?.toUpperCase(),
263
+ responses,
264
+ required_hit_count: requiredHitCount,
265
+ required: input.required === false ? false : true
266
+ };
267
+ }
268
+ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
269
+ const status = numberValue(input.status) ?? defaults.status ?? 200;
270
+ if (!Number.isInteger(status) || status < 100 || status > 599) {
271
+ throw new Error(`${label}.status must be an HTTP status code.`);
272
+ }
273
+ const body = stringValue(input.body) ?? stringValue(input.body_text) ?? stringValue(input.bodyText) ?? defaults.body;
274
+ const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
275
+ return {
276
+ label: stringValue(input.label) || stringValue(input.name) || defaults.label,
259
277
  status,
260
- content_type: stringValue(input.content_type) || stringValue(input.contentType),
261
- headers: stringRecord(input.headers),
278
+ content_type: stringValue(input.content_type) || stringValue(input.contentType) || defaults.content_type,
279
+ headers: stringRecord(input.headers) || defaults.headers,
262
280
  body,
263
- body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : void 0,
264
- required: input.required === false ? false : true
281
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json
265
282
  };
266
283
  }
284
+ function normalizeNetworkMockResponses(value, mockIndex, defaults) {
285
+ if (value === void 0) return void 0;
286
+ if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
287
+ if (!value.length) throw new Error(`target.network_mocks[${mockIndex}].responses must not be empty.`);
288
+ const responseDefaults = { ...defaults, label: void 0 };
289
+ return value.map((response, responseIndex) => {
290
+ if (!isRecord(response)) {
291
+ throw new Error(`target.network_mocks[${mockIndex}].responses[${responseIndex}] must be an object.`);
292
+ }
293
+ return normalizeNetworkMockResponsePayload(
294
+ response,
295
+ `target.network_mocks[${mockIndex}].responses[${responseIndex}]`,
296
+ responseDefaults
297
+ );
298
+ });
299
+ }
267
300
  function normalizeNetworkMocks(value) {
268
301
  if (value === void 0) return void 0;
269
302
  if (!Array.isArray(value)) throw new Error("target.network_mocks must be an array.");
@@ -909,12 +942,15 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
909
942
  const requiredMocks = mocks.filter((mock) => mock.required !== false);
910
943
  for (const mock of requiredMocks) {
911
944
  const hits = events.filter((event) => event.label === mock.label && event.ok !== false).length;
912
- if (hits < 1) {
945
+ const requiredHitCount = requiredNetworkMockHitCount(mock);
946
+ if (hits < requiredHitCount) {
913
947
  failed.push({
914
948
  label: mock.label,
915
949
  url: mock.url,
916
950
  method: mock.method || null,
917
- reason: "required_mock_not_hit"
951
+ reason: hits < 1 ? "required_mock_not_hit" : "required_mock_hit_count_not_met",
952
+ required_hit_count: requiredHitCount,
953
+ hit_count: hits
918
954
  });
919
955
  }
920
956
  }
@@ -940,11 +976,21 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
940
976
  mock.label,
941
977
  events.filter((event) => event.label === mock.label && event.ok !== false).length
942
978
  ])),
979
+ required_hits_by_label: Object.fromEntries(requiredMocks.map((mock) => [
980
+ mock.label,
981
+ requiredNetworkMockHitCount(mock)
982
+ ])),
943
983
  failed
944
984
  },
945
985
  message: failed.length ? `Network mocks failed or were not hit for ${failed.length} mock(s).` : void 0
946
986
  };
947
987
  }
988
+ function requiredNetworkMockHitCount(mock) {
989
+ if (mock.required === false) return 0;
990
+ if (mock.required_hit_count !== void 0) return mock.required_hit_count;
991
+ if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
992
+ return 1;
993
+ }
948
994
  function profileStatusFromEvidence(profile, evidence, checks) {
949
995
  if (!evidence) return "proof_insufficient";
950
996
  const viewports = evidence.viewports || [];
@@ -1239,6 +1285,12 @@ function horizontalBoundsOverflowPx(value) {
1239
1285
  }
1240
1286
  return roundPixels(max);
1241
1287
  }
1288
+ function requiredNetworkMockHitCount(mock) {
1289
+ if (!mock || mock.required === false) return 0;
1290
+ if (Number.isInteger(mock.required_hit_count) && mock.required_hit_count > 0) return mock.required_hit_count;
1291
+ if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
1292
+ return 1;
1293
+ }
1242
1294
  function assessProfile(profile, evidence) {
1243
1295
  const checks = [];
1244
1296
  const viewports = evidence.viewports || [];
@@ -1248,12 +1300,15 @@ function assessProfile(profile, evidence) {
1248
1300
  const failed = [];
1249
1301
  for (const mock of requiredMocks) {
1250
1302
  const hits = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
1251
- if (hits < 1) {
1303
+ const requiredHitCount = requiredNetworkMockHitCount(mock);
1304
+ if (hits < requiredHitCount) {
1252
1305
  failed.push({
1253
1306
  label: mock.label,
1254
1307
  url: mock.url,
1255
1308
  method: mock.method || null,
1256
- reason: "required_mock_not_hit",
1309
+ reason: hits < 1 ? "required_mock_not_hit" : "required_mock_hit_count_not_met",
1310
+ required_hit_count: requiredHitCount,
1311
+ hit_count: hits,
1257
1312
  });
1258
1313
  }
1259
1314
  }
@@ -1268,8 +1323,10 @@ function assessProfile(profile, evidence) {
1268
1323
  }
1269
1324
  }
1270
1325
  const hitsByLabel = {};
1326
+ const requiredHitsByLabel = {};
1271
1327
  for (const mock of profile.target.network_mocks) {
1272
1328
  hitsByLabel[mock.label] = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
1329
+ if (mock && mock.required !== false) requiredHitsByLabel[mock.label] = requiredNetworkMockHitCount(mock);
1273
1330
  }
1274
1331
  checks.push({
1275
1332
  type: "network_mocks_succeeded",
@@ -1280,6 +1337,7 @@ function assessProfile(profile, evidence) {
1280
1337
  required_count: requiredMocks.length,
1281
1338
  hit_count: events.filter((event) => event && event.ok !== false).length,
1282
1339
  hits_by_label: hitsByLabel,
1340
+ required_hits_by_label: requiredHitsByLabel,
1283
1341
  failed,
1284
1342
  },
1285
1343
  message: failed.length ? "Network mocks failed or were not hit for " + failed.length + " mock(s)." : undefined,
@@ -1678,6 +1736,7 @@ async function setupLocatorVisible(locator, index) {
1678
1736
  }
1679
1737
  async function registerNetworkMocks(mocks) {
1680
1738
  for (const mock of mocks || []) {
1739
+ let hitCount = 0;
1681
1740
  await page.route(mock.url, async (route) => {
1682
1741
  const request = route.request();
1683
1742
  const method = request.method ? request.method() : "";
@@ -1686,22 +1745,31 @@ async function registerNetworkMocks(mocks) {
1686
1745
  return;
1687
1746
  }
1688
1747
  try {
1689
- const headers = { ...(mock.headers || {}) };
1690
- let body = mock.body || "";
1691
- let contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
1692
- if (mock.body_json !== undefined) {
1693
- body = JSON.stringify(mock.body_json);
1694
- contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
1748
+ const responses = Array.isArray(mock.responses) ? mock.responses : [];
1749
+ const hitIndex = hitCount;
1750
+ hitCount += 1;
1751
+ const responseIndex = responses.length ? Math.min(hitIndex, responses.length - 1) : null;
1752
+ const response = responseIndex === null ? mock : responses[responseIndex];
1753
+ const headers = { ...(response.headers || mock.headers || {}) };
1754
+ let body = response.body || "";
1755
+ let contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
1756
+ if (response.body_json !== undefined) {
1757
+ body = JSON.stringify(response.body_json);
1758
+ contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
1695
1759
  }
1696
1760
  networkMockEvents.push({
1697
1761
  ok: true,
1698
1762
  label: mock.label,
1763
+ response_label: response.label || null,
1764
+ hit_index: hitIndex,
1765
+ response_index: responseIndex,
1766
+ sequence_reused: responseIndex !== null && hitIndex >= responses.length,
1699
1767
  url: request.url(),
1700
1768
  method,
1701
- status: mock.status || 200,
1769
+ status: response.status || mock.status || 200,
1702
1770
  });
1703
1771
  await route.fulfill({
1704
- status: mock.status || 200,
1772
+ status: response.status || mock.status || 200,
1705
1773
  headers,
1706
1774
  contentType,
1707
1775
  body,
package/dist/cli.cjs CHANGED
@@ -7119,24 +7119,57 @@ function normalizeNetworkMock(input, index) {
7119
7119
  if (!isRecord(input)) throw new Error(`target.network_mocks[${index}] must be an object.`);
7120
7120
  const url = stringValue2(input.url) || stringValue2(input.glob) || stringValue2(input.pattern);
7121
7121
  if (!url) throw new Error(`target.network_mocks[${index}] requires url.`);
7122
- const status = numberValue(input.status) ?? 200;
7123
- if (!Number.isInteger(status) || status < 100 || status > 599) {
7124
- throw new Error(`target.network_mocks[${index}].status must be an HTTP status code.`);
7122
+ const payload = normalizeNetworkMockResponsePayload(input, `target.network_mocks[${index}]`);
7123
+ const responsesInput = input.responses ?? input.sequence;
7124
+ const responses = normalizeNetworkMockResponses(responsesInput, index, payload);
7125
+ const requiredHitCount = numberValue(
7126
+ input.required_hit_count ?? input.requiredHitCount ?? input.required_hits ?? input.requiredHits ?? input.min_hits ?? input.minHits
7127
+ );
7128
+ if (requiredHitCount !== void 0 && (!Number.isInteger(requiredHitCount) || requiredHitCount < 1)) {
7129
+ throw new Error(`target.network_mocks[${index}].required_hit_count must be a positive integer.`);
7125
7130
  }
7126
- const body = stringValue2(input.body) ?? stringValue2(input.body_text) ?? stringValue2(input.bodyText);
7127
- const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
7128
7131
  return {
7132
+ ...payload,
7129
7133
  label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
7130
7134
  url,
7131
7135
  method: stringValue2(input.method)?.toUpperCase(),
7136
+ responses,
7137
+ required_hit_count: requiredHitCount,
7138
+ required: input.required === false ? false : true
7139
+ };
7140
+ }
7141
+ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
7142
+ const status = numberValue(input.status) ?? defaults.status ?? 200;
7143
+ if (!Number.isInteger(status) || status < 100 || status > 599) {
7144
+ throw new Error(`${label}.status must be an HTTP status code.`);
7145
+ }
7146
+ const body = stringValue2(input.body) ?? stringValue2(input.body_text) ?? stringValue2(input.bodyText) ?? defaults.body;
7147
+ const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
7148
+ return {
7149
+ label: stringValue2(input.label) || stringValue2(input.name) || defaults.label,
7132
7150
  status,
7133
- content_type: stringValue2(input.content_type) || stringValue2(input.contentType),
7134
- headers: stringRecord(input.headers),
7151
+ content_type: stringValue2(input.content_type) || stringValue2(input.contentType) || defaults.content_type,
7152
+ headers: stringRecord(input.headers) || defaults.headers,
7135
7153
  body,
7136
- body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : void 0,
7137
- required: input.required === false ? false : true
7154
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json
7138
7155
  };
7139
7156
  }
7157
+ function normalizeNetworkMockResponses(value, mockIndex, defaults) {
7158
+ if (value === void 0) return void 0;
7159
+ if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
7160
+ if (!value.length) throw new Error(`target.network_mocks[${mockIndex}].responses must not be empty.`);
7161
+ const responseDefaults = { ...defaults, label: void 0 };
7162
+ return value.map((response, responseIndex) => {
7163
+ if (!isRecord(response)) {
7164
+ throw new Error(`target.network_mocks[${mockIndex}].responses[${responseIndex}] must be an object.`);
7165
+ }
7166
+ return normalizeNetworkMockResponsePayload(
7167
+ response,
7168
+ `target.network_mocks[${mockIndex}].responses[${responseIndex}]`,
7169
+ responseDefaults
7170
+ );
7171
+ });
7172
+ }
7140
7173
  function normalizeNetworkMocks(value) {
7141
7174
  if (value === void 0) return void 0;
7142
7175
  if (!Array.isArray(value)) throw new Error("target.network_mocks must be an array.");
@@ -7782,12 +7815,15 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
7782
7815
  const requiredMocks = mocks.filter((mock) => mock.required !== false);
7783
7816
  for (const mock of requiredMocks) {
7784
7817
  const hits = events.filter((event) => event.label === mock.label && event.ok !== false).length;
7785
- if (hits < 1) {
7818
+ const requiredHitCount = requiredNetworkMockHitCount(mock);
7819
+ if (hits < requiredHitCount) {
7786
7820
  failed.push({
7787
7821
  label: mock.label,
7788
7822
  url: mock.url,
7789
7823
  method: mock.method || null,
7790
- reason: "required_mock_not_hit"
7824
+ reason: hits < 1 ? "required_mock_not_hit" : "required_mock_hit_count_not_met",
7825
+ required_hit_count: requiredHitCount,
7826
+ hit_count: hits
7791
7827
  });
7792
7828
  }
7793
7829
  }
@@ -7813,11 +7849,21 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
7813
7849
  mock.label,
7814
7850
  events.filter((event) => event.label === mock.label && event.ok !== false).length
7815
7851
  ])),
7852
+ required_hits_by_label: Object.fromEntries(requiredMocks.map((mock) => [
7853
+ mock.label,
7854
+ requiredNetworkMockHitCount(mock)
7855
+ ])),
7816
7856
  failed
7817
7857
  },
7818
7858
  message: failed.length ? `Network mocks failed or were not hit for ${failed.length} mock(s).` : void 0
7819
7859
  };
7820
7860
  }
7861
+ function requiredNetworkMockHitCount(mock) {
7862
+ if (mock.required === false) return 0;
7863
+ if (mock.required_hit_count !== void 0) return mock.required_hit_count;
7864
+ if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
7865
+ return 1;
7866
+ }
7821
7867
  function profileStatusFromEvidence(profile, evidence, checks) {
7822
7868
  if (!evidence) return "proof_insufficient";
7823
7869
  const viewports = evidence.viewports || [];
@@ -8096,6 +8142,12 @@ function horizontalBoundsOverflowPx(value) {
8096
8142
  }
8097
8143
  return roundPixels(max);
8098
8144
  }
8145
+ function requiredNetworkMockHitCount(mock) {
8146
+ if (!mock || mock.required === false) return 0;
8147
+ if (Number.isInteger(mock.required_hit_count) && mock.required_hit_count > 0) return mock.required_hit_count;
8148
+ if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
8149
+ return 1;
8150
+ }
8099
8151
  function assessProfile(profile, evidence) {
8100
8152
  const checks = [];
8101
8153
  const viewports = evidence.viewports || [];
@@ -8105,12 +8157,15 @@ function assessProfile(profile, evidence) {
8105
8157
  const failed = [];
8106
8158
  for (const mock of requiredMocks) {
8107
8159
  const hits = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
8108
- if (hits < 1) {
8160
+ const requiredHitCount = requiredNetworkMockHitCount(mock);
8161
+ if (hits < requiredHitCount) {
8109
8162
  failed.push({
8110
8163
  label: mock.label,
8111
8164
  url: mock.url,
8112
8165
  method: mock.method || null,
8113
- reason: "required_mock_not_hit",
8166
+ reason: hits < 1 ? "required_mock_not_hit" : "required_mock_hit_count_not_met",
8167
+ required_hit_count: requiredHitCount,
8168
+ hit_count: hits,
8114
8169
  });
8115
8170
  }
8116
8171
  }
@@ -8125,8 +8180,10 @@ function assessProfile(profile, evidence) {
8125
8180
  }
8126
8181
  }
8127
8182
  const hitsByLabel = {};
8183
+ const requiredHitsByLabel = {};
8128
8184
  for (const mock of profile.target.network_mocks) {
8129
8185
  hitsByLabel[mock.label] = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
8186
+ if (mock && mock.required !== false) requiredHitsByLabel[mock.label] = requiredNetworkMockHitCount(mock);
8130
8187
  }
8131
8188
  checks.push({
8132
8189
  type: "network_mocks_succeeded",
@@ -8137,6 +8194,7 @@ function assessProfile(profile, evidence) {
8137
8194
  required_count: requiredMocks.length,
8138
8195
  hit_count: events.filter((event) => event && event.ok !== false).length,
8139
8196
  hits_by_label: hitsByLabel,
8197
+ required_hits_by_label: requiredHitsByLabel,
8140
8198
  failed,
8141
8199
  },
8142
8200
  message: failed.length ? "Network mocks failed or were not hit for " + failed.length + " mock(s)." : undefined,
@@ -8535,6 +8593,7 @@ async function setupLocatorVisible(locator, index) {
8535
8593
  }
8536
8594
  async function registerNetworkMocks(mocks) {
8537
8595
  for (const mock of mocks || []) {
8596
+ let hitCount = 0;
8538
8597
  await page.route(mock.url, async (route) => {
8539
8598
  const request = route.request();
8540
8599
  const method = request.method ? request.method() : "";
@@ -8543,22 +8602,31 @@ async function registerNetworkMocks(mocks) {
8543
8602
  return;
8544
8603
  }
8545
8604
  try {
8546
- const headers = { ...(mock.headers || {}) };
8547
- let body = mock.body || "";
8548
- let contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
8549
- if (mock.body_json !== undefined) {
8550
- body = JSON.stringify(mock.body_json);
8551
- contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
8605
+ const responses = Array.isArray(mock.responses) ? mock.responses : [];
8606
+ const hitIndex = hitCount;
8607
+ hitCount += 1;
8608
+ const responseIndex = responses.length ? Math.min(hitIndex, responses.length - 1) : null;
8609
+ const response = responseIndex === null ? mock : responses[responseIndex];
8610
+ const headers = { ...(response.headers || mock.headers || {}) };
8611
+ let body = response.body || "";
8612
+ let contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
8613
+ if (response.body_json !== undefined) {
8614
+ body = JSON.stringify(response.body_json);
8615
+ contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
8552
8616
  }
8553
8617
  networkMockEvents.push({
8554
8618
  ok: true,
8555
8619
  label: mock.label,
8620
+ response_label: response.label || null,
8621
+ hit_index: hitIndex,
8622
+ response_index: responseIndex,
8623
+ sequence_reused: responseIndex !== null && hitIndex >= responses.length,
8556
8624
  url: request.url(),
8557
8625
  method,
8558
- status: mock.status || 200,
8626
+ status: response.status || mock.status || 200,
8559
8627
  });
8560
8628
  await route.fulfill({
8561
- status: mock.status || 200,
8629
+ status: response.status || mock.status || 200,
8562
8630
  headers,
8563
8631
  contentType,
8564
8632
  body,
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  profileStatusExitCode,
11
11
  resolveRiddleProofProfileTargetUrl,
12
12
  resolveRiddleProofProfileTimeoutSec
13
- } from "./chunk-L4FLSU7L.js";
13
+ } from "./chunk-RAVOICNN.js";
14
14
  import {
15
15
  createRiddleApiClient,
16
16
  parseRiddleViewport
package/dist/index.cjs CHANGED
@@ -8960,24 +8960,57 @@ function normalizeNetworkMock(input, index) {
8960
8960
  if (!isRecord2(input)) throw new Error(`target.network_mocks[${index}] must be an object.`);
8961
8961
  const url = stringValue5(input.url) || stringValue5(input.glob) || stringValue5(input.pattern);
8962
8962
  if (!url) throw new Error(`target.network_mocks[${index}] requires url.`);
8963
- const status = numberValue3(input.status) ?? 200;
8964
- if (!Number.isInteger(status) || status < 100 || status > 599) {
8965
- throw new Error(`target.network_mocks[${index}].status must be an HTTP status code.`);
8963
+ const payload = normalizeNetworkMockResponsePayload(input, `target.network_mocks[${index}]`);
8964
+ const responsesInput = input.responses ?? input.sequence;
8965
+ const responses = normalizeNetworkMockResponses(responsesInput, index, payload);
8966
+ const requiredHitCount = numberValue3(
8967
+ input.required_hit_count ?? input.requiredHitCount ?? input.required_hits ?? input.requiredHits ?? input.min_hits ?? input.minHits
8968
+ );
8969
+ if (requiredHitCount !== void 0 && (!Number.isInteger(requiredHitCount) || requiredHitCount < 1)) {
8970
+ throw new Error(`target.network_mocks[${index}].required_hit_count must be a positive integer.`);
8966
8971
  }
8967
- const body = stringValue5(input.body) ?? stringValue5(input.body_text) ?? stringValue5(input.bodyText);
8968
- const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
8969
8972
  return {
8973
+ ...payload,
8970
8974
  label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
8971
8975
  url,
8972
8976
  method: stringValue5(input.method)?.toUpperCase(),
8977
+ responses,
8978
+ required_hit_count: requiredHitCount,
8979
+ required: input.required === false ? false : true
8980
+ };
8981
+ }
8982
+ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
8983
+ const status = numberValue3(input.status) ?? defaults.status ?? 200;
8984
+ if (!Number.isInteger(status) || status < 100 || status > 599) {
8985
+ throw new Error(`${label}.status must be an HTTP status code.`);
8986
+ }
8987
+ const body = stringValue5(input.body) ?? stringValue5(input.body_text) ?? stringValue5(input.bodyText) ?? defaults.body;
8988
+ const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
8989
+ return {
8990
+ label: stringValue5(input.label) || stringValue5(input.name) || defaults.label,
8973
8991
  status,
8974
- content_type: stringValue5(input.content_type) || stringValue5(input.contentType),
8975
- headers: stringRecord(input.headers),
8992
+ content_type: stringValue5(input.content_type) || stringValue5(input.contentType) || defaults.content_type,
8993
+ headers: stringRecord(input.headers) || defaults.headers,
8976
8994
  body,
8977
- body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : void 0,
8978
- required: input.required === false ? false : true
8995
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json
8979
8996
  };
8980
8997
  }
8998
+ function normalizeNetworkMockResponses(value, mockIndex, defaults) {
8999
+ if (value === void 0) return void 0;
9000
+ if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
9001
+ if (!value.length) throw new Error(`target.network_mocks[${mockIndex}].responses must not be empty.`);
9002
+ const responseDefaults = { ...defaults, label: void 0 };
9003
+ return value.map((response, responseIndex) => {
9004
+ if (!isRecord2(response)) {
9005
+ throw new Error(`target.network_mocks[${mockIndex}].responses[${responseIndex}] must be an object.`);
9006
+ }
9007
+ return normalizeNetworkMockResponsePayload(
9008
+ response,
9009
+ `target.network_mocks[${mockIndex}].responses[${responseIndex}]`,
9010
+ responseDefaults
9011
+ );
9012
+ });
9013
+ }
8981
9014
  function normalizeNetworkMocks(value) {
8982
9015
  if (value === void 0) return void 0;
8983
9016
  if (!Array.isArray(value)) throw new Error("target.network_mocks must be an array.");
@@ -9623,12 +9656,15 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
9623
9656
  const requiredMocks = mocks.filter((mock) => mock.required !== false);
9624
9657
  for (const mock of requiredMocks) {
9625
9658
  const hits = events.filter((event) => event.label === mock.label && event.ok !== false).length;
9626
- if (hits < 1) {
9659
+ const requiredHitCount = requiredNetworkMockHitCount(mock);
9660
+ if (hits < requiredHitCount) {
9627
9661
  failed.push({
9628
9662
  label: mock.label,
9629
9663
  url: mock.url,
9630
9664
  method: mock.method || null,
9631
- reason: "required_mock_not_hit"
9665
+ reason: hits < 1 ? "required_mock_not_hit" : "required_mock_hit_count_not_met",
9666
+ required_hit_count: requiredHitCount,
9667
+ hit_count: hits
9632
9668
  });
9633
9669
  }
9634
9670
  }
@@ -9654,11 +9690,21 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
9654
9690
  mock.label,
9655
9691
  events.filter((event) => event.label === mock.label && event.ok !== false).length
9656
9692
  ])),
9693
+ required_hits_by_label: Object.fromEntries(requiredMocks.map((mock) => [
9694
+ mock.label,
9695
+ requiredNetworkMockHitCount(mock)
9696
+ ])),
9657
9697
  failed
9658
9698
  },
9659
9699
  message: failed.length ? `Network mocks failed or were not hit for ${failed.length} mock(s).` : void 0
9660
9700
  };
9661
9701
  }
9702
+ function requiredNetworkMockHitCount(mock) {
9703
+ if (mock.required === false) return 0;
9704
+ if (mock.required_hit_count !== void 0) return mock.required_hit_count;
9705
+ if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
9706
+ return 1;
9707
+ }
9662
9708
  function profileStatusFromEvidence(profile, evidence, checks) {
9663
9709
  if (!evidence) return "proof_insufficient";
9664
9710
  const viewports = evidence.viewports || [];
@@ -9953,6 +9999,12 @@ function horizontalBoundsOverflowPx(value) {
9953
9999
  }
9954
10000
  return roundPixels(max);
9955
10001
  }
10002
+ function requiredNetworkMockHitCount(mock) {
10003
+ if (!mock || mock.required === false) return 0;
10004
+ if (Number.isInteger(mock.required_hit_count) && mock.required_hit_count > 0) return mock.required_hit_count;
10005
+ if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
10006
+ return 1;
10007
+ }
9956
10008
  function assessProfile(profile, evidence) {
9957
10009
  const checks = [];
9958
10010
  const viewports = evidence.viewports || [];
@@ -9962,12 +10014,15 @@ function assessProfile(profile, evidence) {
9962
10014
  const failed = [];
9963
10015
  for (const mock of requiredMocks) {
9964
10016
  const hits = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
9965
- if (hits < 1) {
10017
+ const requiredHitCount = requiredNetworkMockHitCount(mock);
10018
+ if (hits < requiredHitCount) {
9966
10019
  failed.push({
9967
10020
  label: mock.label,
9968
10021
  url: mock.url,
9969
10022
  method: mock.method || null,
9970
- reason: "required_mock_not_hit",
10023
+ reason: hits < 1 ? "required_mock_not_hit" : "required_mock_hit_count_not_met",
10024
+ required_hit_count: requiredHitCount,
10025
+ hit_count: hits,
9971
10026
  });
9972
10027
  }
9973
10028
  }
@@ -9982,8 +10037,10 @@ function assessProfile(profile, evidence) {
9982
10037
  }
9983
10038
  }
9984
10039
  const hitsByLabel = {};
10040
+ const requiredHitsByLabel = {};
9985
10041
  for (const mock of profile.target.network_mocks) {
9986
10042
  hitsByLabel[mock.label] = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
10043
+ if (mock && mock.required !== false) requiredHitsByLabel[mock.label] = requiredNetworkMockHitCount(mock);
9987
10044
  }
9988
10045
  checks.push({
9989
10046
  type: "network_mocks_succeeded",
@@ -9994,6 +10051,7 @@ function assessProfile(profile, evidence) {
9994
10051
  required_count: requiredMocks.length,
9995
10052
  hit_count: events.filter((event) => event && event.ok !== false).length,
9996
10053
  hits_by_label: hitsByLabel,
10054
+ required_hits_by_label: requiredHitsByLabel,
9997
10055
  failed,
9998
10056
  },
9999
10057
  message: failed.length ? "Network mocks failed or were not hit for " + failed.length + " mock(s)." : undefined,
@@ -10392,6 +10450,7 @@ async function setupLocatorVisible(locator, index) {
10392
10450
  }
10393
10451
  async function registerNetworkMocks(mocks) {
10394
10452
  for (const mock of mocks || []) {
10453
+ let hitCount = 0;
10395
10454
  await page.route(mock.url, async (route) => {
10396
10455
  const request = route.request();
10397
10456
  const method = request.method ? request.method() : "";
@@ -10400,22 +10459,31 @@ async function registerNetworkMocks(mocks) {
10400
10459
  return;
10401
10460
  }
10402
10461
  try {
10403
- const headers = { ...(mock.headers || {}) };
10404
- let body = mock.body || "";
10405
- let contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
10406
- if (mock.body_json !== undefined) {
10407
- body = JSON.stringify(mock.body_json);
10408
- contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
10462
+ const responses = Array.isArray(mock.responses) ? mock.responses : [];
10463
+ const hitIndex = hitCount;
10464
+ hitCount += 1;
10465
+ const responseIndex = responses.length ? Math.min(hitIndex, responses.length - 1) : null;
10466
+ const response = responseIndex === null ? mock : responses[responseIndex];
10467
+ const headers = { ...(response.headers || mock.headers || {}) };
10468
+ let body = response.body || "";
10469
+ let contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
10470
+ if (response.body_json !== undefined) {
10471
+ body = JSON.stringify(response.body_json);
10472
+ contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
10409
10473
  }
10410
10474
  networkMockEvents.push({
10411
10475
  ok: true,
10412
10476
  label: mock.label,
10477
+ response_label: response.label || null,
10478
+ hit_index: hitIndex,
10479
+ response_index: responseIndex,
10480
+ sequence_reused: responseIndex !== null && hitIndex >= responses.length,
10413
10481
  url: request.url(),
10414
10482
  method,
10415
- status: mock.status || 200,
10483
+ status: response.status || mock.status || 200,
10416
10484
  });
10417
10485
  await route.fulfill({
10418
- status: mock.status || 200,
10486
+ status: response.status || mock.status || 200,
10419
10487
  headers,
10420
10488
  contentType,
10421
10489
  body,
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_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileNetworkMock, RiddleProofProfileResult, RiddleProofProfileRouteEvidence, RiddleProofProfileRouteInventoryRoute, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, 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_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileNetworkMock, RiddleProofProfileNetworkMockResponse, RiddleProofProfileResult, RiddleProofProfileRouteEvidence, RiddleProofProfileRouteInventoryRoute, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, 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, RiddleRunScriptInput, RiddleServerPreviewInput, RiddleServerPreviewResult, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript, runRiddleServerPreview } from './riddle-client.cjs';
package/dist/index.d.ts 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.js';
11
11
  export { AssessPlayabilityOptions, RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION, RIDDLE_PROOF_PLAYABILITY_VERSION, RiddleProofPlayabilityAssessment, RiddleProofPlayabilityEvidence, assessPlayabilityEvidence, extractPlayabilityEvidence, isRiddleProofPlayabilityMode } from './playability.js';
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.js';
13
- export { NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileNetworkMock, RiddleProofProfileResult, RiddleProofProfileRouteEvidence, RiddleProofProfileRouteInventoryRoute, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult } from './profile.js';
13
+ export { NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileNetworkMock, RiddleProofProfileNetworkMockResponse, RiddleProofProfileResult, RiddleProofProfileRouteEvidence, RiddleProofProfileRouteInventoryRoute, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult } from './profile.js';
14
14
  export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleClientConfig, RiddleFetch, RiddlePollJobOptions, RiddlePollJobResult, RiddlePollProgressSnapshot, RiddlePollSummary, RiddlePreviewDeployResult, RiddleRunScriptInput, RiddleServerPreviewInput, RiddleServerPreviewResult, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript, runRiddleServerPreview } from './riddle-client.js';
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  resolveRiddleProofProfileTimeoutSec,
59
59
  slugifyRiddleProofProfileName,
60
60
  summarizeRiddleProofProfileResult
61
- } from "./chunk-L4FLSU7L.js";
61
+ } from "./chunk-RAVOICNN.js";
62
62
  import {
63
63
  DEFAULT_RIDDLE_API_BASE_URL,
64
64
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -289,24 +289,57 @@ function normalizeNetworkMock(input, index) {
289
289
  if (!isRecord(input)) throw new Error(`target.network_mocks[${index}] must be an object.`);
290
290
  const url = stringValue(input.url) || stringValue(input.glob) || stringValue(input.pattern);
291
291
  if (!url) throw new Error(`target.network_mocks[${index}] requires url.`);
292
- const status = numberValue(input.status) ?? 200;
293
- if (!Number.isInteger(status) || status < 100 || status > 599) {
294
- throw new Error(`target.network_mocks[${index}].status must be an HTTP status code.`);
292
+ const payload = normalizeNetworkMockResponsePayload(input, `target.network_mocks[${index}]`);
293
+ const responsesInput = input.responses ?? input.sequence;
294
+ const responses = normalizeNetworkMockResponses(responsesInput, index, payload);
295
+ const requiredHitCount = numberValue(
296
+ input.required_hit_count ?? input.requiredHitCount ?? input.required_hits ?? input.requiredHits ?? input.min_hits ?? input.minHits
297
+ );
298
+ if (requiredHitCount !== void 0 && (!Number.isInteger(requiredHitCount) || requiredHitCount < 1)) {
299
+ throw new Error(`target.network_mocks[${index}].required_hit_count must be a positive integer.`);
295
300
  }
296
- const body = stringValue(input.body) ?? stringValue(input.body_text) ?? stringValue(input.bodyText);
297
- const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
298
301
  return {
302
+ ...payload,
299
303
  label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
300
304
  url,
301
305
  method: stringValue(input.method)?.toUpperCase(),
306
+ responses,
307
+ required_hit_count: requiredHitCount,
308
+ required: input.required === false ? false : true
309
+ };
310
+ }
311
+ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
312
+ const status = numberValue(input.status) ?? defaults.status ?? 200;
313
+ if (!Number.isInteger(status) || status < 100 || status > 599) {
314
+ throw new Error(`${label}.status must be an HTTP status code.`);
315
+ }
316
+ const body = stringValue(input.body) ?? stringValue(input.body_text) ?? stringValue(input.bodyText) ?? defaults.body;
317
+ const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
318
+ return {
319
+ label: stringValue(input.label) || stringValue(input.name) || defaults.label,
302
320
  status,
303
- content_type: stringValue(input.content_type) || stringValue(input.contentType),
304
- headers: stringRecord(input.headers),
321
+ content_type: stringValue(input.content_type) || stringValue(input.contentType) || defaults.content_type,
322
+ headers: stringRecord(input.headers) || defaults.headers,
305
323
  body,
306
- body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : void 0,
307
- required: input.required === false ? false : true
324
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json
308
325
  };
309
326
  }
327
+ function normalizeNetworkMockResponses(value, mockIndex, defaults) {
328
+ if (value === void 0) return void 0;
329
+ if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
330
+ if (!value.length) throw new Error(`target.network_mocks[${mockIndex}].responses must not be empty.`);
331
+ const responseDefaults = { ...defaults, label: void 0 };
332
+ return value.map((response, responseIndex) => {
333
+ if (!isRecord(response)) {
334
+ throw new Error(`target.network_mocks[${mockIndex}].responses[${responseIndex}] must be an object.`);
335
+ }
336
+ return normalizeNetworkMockResponsePayload(
337
+ response,
338
+ `target.network_mocks[${mockIndex}].responses[${responseIndex}]`,
339
+ responseDefaults
340
+ );
341
+ });
342
+ }
310
343
  function normalizeNetworkMocks(value) {
311
344
  if (value === void 0) return void 0;
312
345
  if (!Array.isArray(value)) throw new Error("target.network_mocks must be an array.");
@@ -952,12 +985,15 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
952
985
  const requiredMocks = mocks.filter((mock) => mock.required !== false);
953
986
  for (const mock of requiredMocks) {
954
987
  const hits = events.filter((event) => event.label === mock.label && event.ok !== false).length;
955
- if (hits < 1) {
988
+ const requiredHitCount = requiredNetworkMockHitCount(mock);
989
+ if (hits < requiredHitCount) {
956
990
  failed.push({
957
991
  label: mock.label,
958
992
  url: mock.url,
959
993
  method: mock.method || null,
960
- reason: "required_mock_not_hit"
994
+ reason: hits < 1 ? "required_mock_not_hit" : "required_mock_hit_count_not_met",
995
+ required_hit_count: requiredHitCount,
996
+ hit_count: hits
961
997
  });
962
998
  }
963
999
  }
@@ -983,11 +1019,21 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
983
1019
  mock.label,
984
1020
  events.filter((event) => event.label === mock.label && event.ok !== false).length
985
1021
  ])),
1022
+ required_hits_by_label: Object.fromEntries(requiredMocks.map((mock) => [
1023
+ mock.label,
1024
+ requiredNetworkMockHitCount(mock)
1025
+ ])),
986
1026
  failed
987
1027
  },
988
1028
  message: failed.length ? `Network mocks failed or were not hit for ${failed.length} mock(s).` : void 0
989
1029
  };
990
1030
  }
1031
+ function requiredNetworkMockHitCount(mock) {
1032
+ if (mock.required === false) return 0;
1033
+ if (mock.required_hit_count !== void 0) return mock.required_hit_count;
1034
+ if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
1035
+ return 1;
1036
+ }
991
1037
  function profileStatusFromEvidence(profile, evidence, checks) {
992
1038
  if (!evidence) return "proof_insufficient";
993
1039
  const viewports = evidence.viewports || [];
@@ -1282,6 +1328,12 @@ function horizontalBoundsOverflowPx(value) {
1282
1328
  }
1283
1329
  return roundPixels(max);
1284
1330
  }
1331
+ function requiredNetworkMockHitCount(mock) {
1332
+ if (!mock || mock.required === false) return 0;
1333
+ if (Number.isInteger(mock.required_hit_count) && mock.required_hit_count > 0) return mock.required_hit_count;
1334
+ if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
1335
+ return 1;
1336
+ }
1285
1337
  function assessProfile(profile, evidence) {
1286
1338
  const checks = [];
1287
1339
  const viewports = evidence.viewports || [];
@@ -1291,12 +1343,15 @@ function assessProfile(profile, evidence) {
1291
1343
  const failed = [];
1292
1344
  for (const mock of requiredMocks) {
1293
1345
  const hits = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
1294
- if (hits < 1) {
1346
+ const requiredHitCount = requiredNetworkMockHitCount(mock);
1347
+ if (hits < requiredHitCount) {
1295
1348
  failed.push({
1296
1349
  label: mock.label,
1297
1350
  url: mock.url,
1298
1351
  method: mock.method || null,
1299
- reason: "required_mock_not_hit",
1352
+ reason: hits < 1 ? "required_mock_not_hit" : "required_mock_hit_count_not_met",
1353
+ required_hit_count: requiredHitCount,
1354
+ hit_count: hits,
1300
1355
  });
1301
1356
  }
1302
1357
  }
@@ -1311,8 +1366,10 @@ function assessProfile(profile, evidence) {
1311
1366
  }
1312
1367
  }
1313
1368
  const hitsByLabel = {};
1369
+ const requiredHitsByLabel = {};
1314
1370
  for (const mock of profile.target.network_mocks) {
1315
1371
  hitsByLabel[mock.label] = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
1372
+ if (mock && mock.required !== false) requiredHitsByLabel[mock.label] = requiredNetworkMockHitCount(mock);
1316
1373
  }
1317
1374
  checks.push({
1318
1375
  type: "network_mocks_succeeded",
@@ -1323,6 +1380,7 @@ function assessProfile(profile, evidence) {
1323
1380
  required_count: requiredMocks.length,
1324
1381
  hit_count: events.filter((event) => event && event.ok !== false).length,
1325
1382
  hits_by_label: hitsByLabel,
1383
+ required_hits_by_label: requiredHitsByLabel,
1326
1384
  failed,
1327
1385
  },
1328
1386
  message: failed.length ? "Network mocks failed or were not hit for " + failed.length + " mock(s)." : undefined,
@@ -1721,6 +1779,7 @@ async function setupLocatorVisible(locator, index) {
1721
1779
  }
1722
1780
  async function registerNetworkMocks(mocks) {
1723
1781
  for (const mock of mocks || []) {
1782
+ let hitCount = 0;
1724
1783
  await page.route(mock.url, async (route) => {
1725
1784
  const request = route.request();
1726
1785
  const method = request.method ? request.method() : "";
@@ -1729,22 +1788,31 @@ async function registerNetworkMocks(mocks) {
1729
1788
  return;
1730
1789
  }
1731
1790
  try {
1732
- const headers = { ...(mock.headers || {}) };
1733
- let body = mock.body || "";
1734
- let contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
1735
- if (mock.body_json !== undefined) {
1736
- body = JSON.stringify(mock.body_json);
1737
- contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
1791
+ const responses = Array.isArray(mock.responses) ? mock.responses : [];
1792
+ const hitIndex = hitCount;
1793
+ hitCount += 1;
1794
+ const responseIndex = responses.length ? Math.min(hitIndex, responses.length - 1) : null;
1795
+ const response = responseIndex === null ? mock : responses[responseIndex];
1796
+ const headers = { ...(response.headers || mock.headers || {}) };
1797
+ let body = response.body || "";
1798
+ let contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
1799
+ if (response.body_json !== undefined) {
1800
+ body = JSON.stringify(response.body_json);
1801
+ contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
1738
1802
  }
1739
1803
  networkMockEvents.push({
1740
1804
  ok: true,
1741
1805
  label: mock.label,
1806
+ response_label: response.label || null,
1807
+ hit_index: hitIndex,
1808
+ response_index: responseIndex,
1809
+ sequence_reused: responseIndex !== null && hitIndex >= responses.length,
1742
1810
  url: request.url(),
1743
1811
  method,
1744
- status: mock.status || 200,
1812
+ status: response.status || mock.status || 200,
1745
1813
  });
1746
1814
  await route.fulfill({
1747
- status: mock.status || 200,
1815
+ status: response.status || mock.status || 200,
1748
1816
  headers,
1749
1817
  contentType,
1750
1818
  body,
@@ -34,15 +34,20 @@ interface RiddleProofProfileSetupAction {
34
34
  storage?: "local" | "session" | "both";
35
35
  continue_on_failure?: boolean;
36
36
  }
37
- interface RiddleProofProfileNetworkMock {
38
- label: string;
39
- url: string;
40
- method?: string;
37
+ interface RiddleProofProfileNetworkMockResponse {
38
+ label?: string;
41
39
  status: number;
42
40
  content_type?: string;
43
41
  headers?: Record<string, string>;
44
42
  body?: string;
45
43
  body_json?: JsonValue;
44
+ }
45
+ interface RiddleProofProfileNetworkMock extends RiddleProofProfileNetworkMockResponse {
46
+ label: string;
47
+ url: string;
48
+ method?: string;
49
+ responses?: RiddleProofProfileNetworkMockResponse[];
50
+ required_hit_count?: number;
46
51
  required?: boolean;
47
52
  }
48
53
  interface RiddleProofProfileRouteInventoryRoute {
@@ -254,4 +259,4 @@ declare function buildRiddleProofProfileScript(profile: RiddleProofProfile): str
254
259
  declare function collectRiddleProfileArtifactRefs(input: unknown): RiddleProofProfileArtifactRef[];
255
260
  declare function extractRiddleProofProfileResult(input: unknown): RiddleProofProfileResult | undefined;
256
261
 
257
- export { type NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, type RiddleProofProfile, type RiddleProofProfileArtifactRef, type RiddleProofProfileBaselinePolicy, type RiddleProofProfileBoundsOffender, type RiddleProofProfileCheck, type RiddleProofProfileCheckResult, type RiddleProofProfileCheckType, type RiddleProofProfileEvidence, type RiddleProofProfileFailureAction, type RiddleProofProfileNetworkMock, type RiddleProofProfileResult, type RiddleProofProfileRouteEvidence, type RiddleProofProfileRouteInventoryRoute, type RiddleProofProfileRunner, type RiddleProofProfileSetupAction, type RiddleProofProfileSetupActionType, type RiddleProofProfileStatus, type RiddleProofProfileTarget, type RiddleProofProfileViewport, type RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
262
+ export { type NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, type RiddleProofProfile, type RiddleProofProfileArtifactRef, type RiddleProofProfileBaselinePolicy, type RiddleProofProfileBoundsOffender, type RiddleProofProfileCheck, type RiddleProofProfileCheckResult, type RiddleProofProfileCheckType, type RiddleProofProfileEvidence, type RiddleProofProfileFailureAction, type RiddleProofProfileNetworkMock, type RiddleProofProfileNetworkMockResponse, type RiddleProofProfileResult, type RiddleProofProfileRouteEvidence, type RiddleProofProfileRouteInventoryRoute, type RiddleProofProfileRunner, type RiddleProofProfileSetupAction, type RiddleProofProfileSetupActionType, type RiddleProofProfileStatus, type RiddleProofProfileTarget, type RiddleProofProfileViewport, type RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
package/dist/profile.d.ts CHANGED
@@ -34,15 +34,20 @@ interface RiddleProofProfileSetupAction {
34
34
  storage?: "local" | "session" | "both";
35
35
  continue_on_failure?: boolean;
36
36
  }
37
- interface RiddleProofProfileNetworkMock {
38
- label: string;
39
- url: string;
40
- method?: string;
37
+ interface RiddleProofProfileNetworkMockResponse {
38
+ label?: string;
41
39
  status: number;
42
40
  content_type?: string;
43
41
  headers?: Record<string, string>;
44
42
  body?: string;
45
43
  body_json?: JsonValue;
44
+ }
45
+ interface RiddleProofProfileNetworkMock extends RiddleProofProfileNetworkMockResponse {
46
+ label: string;
47
+ url: string;
48
+ method?: string;
49
+ responses?: RiddleProofProfileNetworkMockResponse[];
50
+ required_hit_count?: number;
46
51
  required?: boolean;
47
52
  }
48
53
  interface RiddleProofProfileRouteInventoryRoute {
@@ -254,4 +259,4 @@ declare function buildRiddleProofProfileScript(profile: RiddleProofProfile): str
254
259
  declare function collectRiddleProfileArtifactRefs(input: unknown): RiddleProofProfileArtifactRef[];
255
260
  declare function extractRiddleProofProfileResult(input: unknown): RiddleProofProfileResult | undefined;
256
261
 
257
- export { type NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, type RiddleProofProfile, type RiddleProofProfileArtifactRef, type RiddleProofProfileBaselinePolicy, type RiddleProofProfileBoundsOffender, type RiddleProofProfileCheck, type RiddleProofProfileCheckResult, type RiddleProofProfileCheckType, type RiddleProofProfileEvidence, type RiddleProofProfileFailureAction, type RiddleProofProfileNetworkMock, type RiddleProofProfileResult, type RiddleProofProfileRouteEvidence, type RiddleProofProfileRouteInventoryRoute, type RiddleProofProfileRunner, type RiddleProofProfileSetupAction, type RiddleProofProfileSetupActionType, type RiddleProofProfileStatus, type RiddleProofProfileTarget, type RiddleProofProfileViewport, type RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
262
+ export { type NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, type RiddleProofProfile, type RiddleProofProfileArtifactRef, type RiddleProofProfileBaselinePolicy, type RiddleProofProfileBoundsOffender, type RiddleProofProfileCheck, type RiddleProofProfileCheckResult, type RiddleProofProfileCheckType, type RiddleProofProfileEvidence, type RiddleProofProfileFailureAction, type RiddleProofProfileNetworkMock, type RiddleProofProfileNetworkMockResponse, type RiddleProofProfileResult, type RiddleProofProfileRouteEvidence, type RiddleProofProfileRouteInventoryRoute, type RiddleProofProfileRunner, type RiddleProofProfileSetupAction, type RiddleProofProfileSetupActionType, type RiddleProofProfileStatus, type RiddleProofProfileTarget, type RiddleProofProfileViewport, type RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
package/dist/profile.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  resolveRiddleProofProfileTimeoutSec,
20
20
  slugifyRiddleProofProfileName,
21
21
  summarizeRiddleProofProfileResult
22
- } from "./chunk-L4FLSU7L.js";
22
+ } from "./chunk-RAVOICNN.js";
23
23
  export {
24
24
  RIDDLE_PROOF_PROFILE_CHECK_TYPES,
25
25
  RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.39",
3
+ "version": "0.7.40",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",