@dreamboard-games/sdk 0.4.0-alpha.12 → 0.4.0-alpha.13

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/testing.js CHANGED
@@ -872,9 +872,10 @@ var checkpointComparisons = [
872
872
  { path: "interactionId", code: "interaction-resolution-mismatch" },
873
873
  { path: "actuatorId", code: "interaction-resolution-mismatch" },
874
874
  { path: "descriptorDigest", code: "interaction-resolution-mismatch" },
875
- { path: "gameVersion", code: "projection-mismatch" },
876
- { path: "actionSetVersion", code: "projection-mismatch" },
877
- { path: "perspectivePlayerId", code: "projection-mismatch" },
875
+ { path: "basis.generation", code: "projection-mismatch" },
876
+ { path: "basis.version", code: "projection-mismatch" },
877
+ { path: "basis.actionSetVersion", code: "projection-mismatch" },
878
+ { path: "basis.perspectivePlayerId", code: "projection-mismatch" },
878
879
  { path: "projectionDigest", code: "projection-mismatch" },
879
880
  { path: "semanticDigest", code: "semantic-snapshot-mismatch" },
880
881
  { path: "draftDigest", code: "draft-mismatch" },
@@ -923,9 +924,7 @@ function createUIParityObservationFromFixture({
923
924
  actuatorId: identity?.actuatorId,
924
925
  descriptorDigest: identity?.descriptorDigest,
925
926
  draftDigest: step.expect.draftDigest ?? identity?.draftDigest,
926
- gameVersion: frame.frame.basis.version,
927
- actionSetVersion: frame.frame.basis.actionSetVersion,
928
- perspectivePlayerId: frame.frame.basis.perspectivePlayerId,
927
+ basis: frame.frame.basis,
929
928
  projectionDigest,
930
929
  semanticDigest,
931
930
  submissionDigest,
@@ -933,7 +932,7 @@ function createUIParityObservationFromFixture({
933
932
  };
934
933
  });
935
934
  return {
936
- schemaVersion: 1,
935
+ schemaVersion: 2,
937
936
  scenarioId: fixture.id,
938
937
  fixtureDigest,
939
938
  sdkCandidateDigest,
@@ -947,10 +946,10 @@ function createUIParityObservationFromFixture({
947
946
  diagnostics
948
947
  };
949
948
  }
950
- function parseUIParityObservationV1(value) {
949
+ function parseUIParityObservation(value) {
951
950
  const observation = assertRecord(value, "observation");
952
- if (observation.schemaVersion !== 1) {
953
- throw new Error("UI parity observation schemaVersion must be 1.");
951
+ if (observation.schemaVersion !== 2) {
952
+ throw new Error("UI parity observation schemaVersion must be 2.");
954
953
  }
955
954
  assertString(observation.scenarioId, "scenarioId");
956
955
  assertString(observation.fixtureDigest, "fixtureDigest");
@@ -977,6 +976,9 @@ function parseUIParityObservationV1(value) {
977
976
  );
978
977
  }
979
978
  assertOptionalString(provenance.evidence, "observation.provenance.evidence");
979
+ if (typeof provenance.evidence === "string") {
980
+ assertPortablePath(provenance.evidence, "observation.provenance.evidence");
981
+ }
980
982
  const checkpoints = assertArray(observation.checkpoints, "checkpoints");
981
983
  for (let index = 0; index < checkpoints.length; index += 1) {
982
984
  const checkpoint = assertRecord(
@@ -1004,16 +1006,7 @@ function parseUIParityObservationV1(value) {
1004
1006
  checkpoint.draftDigest,
1005
1007
  `checkpoints[${index}].draftDigest`
1006
1008
  );
1007
- assertNumber(checkpoint.gameVersion, `checkpoints[${index}].gameVersion`);
1008
- assertString(
1009
- checkpoint.actionSetVersion,
1010
- `checkpoints[${index}].actionSetVersion`
1011
- );
1012
- if (checkpoint.perspectivePlayerId !== null && typeof checkpoint.perspectivePlayerId !== "string") {
1013
- throw new Error(
1014
- `checkpoints[${index}].perspectivePlayerId must be a string or null.`
1015
- );
1016
- }
1009
+ parseGameplayBasis(checkpoint.basis, `checkpoints[${index}].basis`);
1017
1010
  assertString(
1018
1011
  checkpoint.projectionDigest,
1019
1012
  `checkpoints[${index}].projectionDigest`
@@ -1086,6 +1079,86 @@ function compareUIParityObservations(expected, actual) {
1086
1079
  }
1087
1080
  return { ok: true };
1088
1081
  }
1082
+ function parseUIParityRunInput(value) {
1083
+ const input = assertRecord(value, "input");
1084
+ if (input.schemaVersion !== 2) {
1085
+ throw new Error("UI parity run input schemaVersion must be 2.");
1086
+ }
1087
+ const sdk = assertRecord(input.sdk, "input.sdk");
1088
+ parseArtifactReference(sdk.tarball, "input.sdk.tarball");
1089
+ parseArtifactReference(input.referenceBundle, "input.referenceBundle");
1090
+ const fixtureBundle = assertRecord(
1091
+ input.fixtureBundle,
1092
+ "input.fixtureBundle"
1093
+ );
1094
+ parseArtifactReference(fixtureBundle.index, "input.fixtureBundle.index");
1095
+ const scenarios = assertArray(
1096
+ fixtureBundle.scenarios,
1097
+ "input.fixtureBundle.scenarios"
1098
+ );
1099
+ if (scenarios.length === 0) {
1100
+ throw new Error("input.fixtureBundle.scenarios must not be empty.");
1101
+ }
1102
+ const ids = /* @__PURE__ */ new Set();
1103
+ for (let index = 0; index < scenarios.length; index += 1) {
1104
+ const path = `input.fixtureBundle.scenarios[${index}]`;
1105
+ const scenario = assertRecord(scenarios[index], path);
1106
+ assertString(scenario.id, `${path}.id`);
1107
+ const id = scenario.id;
1108
+ if (ids.has(id)) {
1109
+ throw new Error(`${path}.id duplicates scenario '${id}'.`);
1110
+ }
1111
+ ids.add(id);
1112
+ parseArtifactReference(scenario.fixture, `${path}.fixture`);
1113
+ parseArtifactReference(scenario.renderModule, `${path}.renderModule`);
1114
+ parseArtifactReference(scenario.expectation, `${path}.expectation`);
1115
+ parseArtifactReference(scenario.source, `${path}.source`);
1116
+ }
1117
+ assertString(input.project, "input.project");
1118
+ return input;
1119
+ }
1120
+ function parseUIParityRealHostReceipt(value) {
1121
+ const receipt = assertRecord(value, "receipt");
1122
+ if (receipt.schemaVersion !== 2) {
1123
+ throw new Error("UI parity real-host receipt schemaVersion must be 2.");
1124
+ }
1125
+ if (receipt.kind !== "dreamboard-ui-real-host-parity" || receipt.mode !== "real-host-parity" || receipt.result !== "passed" || receipt.realHostExecutor !== true) {
1126
+ throw new Error(
1127
+ "UI parity real-host receipt must be a passing real-host proof."
1128
+ );
1129
+ }
1130
+ parseArtifactReference(receipt.input, "receipt.input");
1131
+ assertString(receipt.sdkTarballSha256, "receipt.sdkTarballSha256");
1132
+ assertString(receipt.fixtureBundleSha256, "receipt.fixtureBundleSha256");
1133
+ assertString(receipt.project, "receipt.project");
1134
+ const scenarios = assertArray(receipt.scenarios, "receipt.scenarios");
1135
+ if (scenarios.length === 0) {
1136
+ throw new Error("receipt.scenarios must not be empty.");
1137
+ }
1138
+ for (let index = 0; index < scenarios.length; index += 1) {
1139
+ const scenario = assertRecord(
1140
+ scenarios[index],
1141
+ `receipt.scenarios[${index}]`
1142
+ );
1143
+ assertString(scenario.id, `receipt.scenarios[${index}].id`);
1144
+ assertString(
1145
+ scenario.fixtureDigest,
1146
+ `receipt.scenarios[${index}].fixtureDigest`
1147
+ );
1148
+ }
1149
+ parseReceiptComparisonGroup(receipt.source, "receipt.source", false);
1150
+ parseReceiptComparisonGroup(receipt.internal, "receipt.internal", true);
1151
+ const host = assertRecord(receipt.host, "receipt.host");
1152
+ assertString(host.route, "receipt.host.route");
1153
+ assertString(host.webLogPath, "receipt.host.webLogPath");
1154
+ assertPortablePath(host.webLogPath, "receipt.host.webLogPath");
1155
+ if (host.pluginIframe !== true || host.pluginSessionGateway !== true || host.playwright !== "chromium") {
1156
+ throw new Error(
1157
+ "receipt.host must prove PluginIframe, PluginSessionGateway, and Chromium."
1158
+ );
1159
+ }
1160
+ return receipt;
1161
+ }
1089
1162
  function comparePath(expected, actual, comparison, options = {}) {
1090
1163
  const expectedValue = getPath(expected, comparison.path);
1091
1164
  const actualValue = getPath(actual, comparison.path);
@@ -1125,6 +1198,70 @@ function getPath(value, path) {
1125
1198
  return current[key];
1126
1199
  }, value);
1127
1200
  }
1201
+ function parseGameplayBasis(value, path) {
1202
+ const basis = assertRecord(value, path);
1203
+ assertNonNegativeInteger(basis.generation, `${path}.generation`);
1204
+ assertNonNegativeInteger(basis.version, `${path}.version`);
1205
+ assertString(basis.actionSetVersion, `${path}.actionSetVersion`);
1206
+ assertString(basis.perspectivePlayerId, `${path}.perspectivePlayerId`);
1207
+ return basis;
1208
+ }
1209
+ function parseArtifactReference(value, path) {
1210
+ const reference = assertRecord(value, path);
1211
+ assertString(reference.path, `${path}.path`);
1212
+ assertPortablePath(reference.path, `${path}.path`);
1213
+ assertString(reference.sha256, `${path}.sha256`);
1214
+ if (!reference.sha256.startsWith("sha256:")) {
1215
+ throw new Error(`${path}.sha256 must be a sha256 digest.`);
1216
+ }
1217
+ return reference;
1218
+ }
1219
+ function parseReceiptComparisonGroup(value, path, internal) {
1220
+ const group = assertRecord(value, path);
1221
+ if (group.result !== "passed") {
1222
+ throw new Error(`${path}.result must be passed.`);
1223
+ }
1224
+ const comparisons = assertArray(group.comparisons, `${path}.comparisons`);
1225
+ for (let index = 0; index < comparisons.length; index += 1) {
1226
+ const itemPath = `${path}.comparisons[${index}]`;
1227
+ const comparison = assertRecord(comparisons[index], itemPath);
1228
+ assertString(comparison.scenarioId, `${itemPath}.scenarioId`);
1229
+ assertString(comparison.actual, `${itemPath}.actual`);
1230
+ assertPortablePath(comparison.actual, `${itemPath}.actual`);
1231
+ if (internal) {
1232
+ assertString(
1233
+ comparison.expectationComparison,
1234
+ `${itemPath}.expectationComparison`
1235
+ );
1236
+ assertString(comparison.sourceComparison, `${itemPath}.sourceComparison`);
1237
+ assertPortablePath(
1238
+ comparison.expectationComparison,
1239
+ `${itemPath}.expectationComparison`
1240
+ );
1241
+ assertPortablePath(
1242
+ comparison.sourceComparison,
1243
+ `${itemPath}.sourceComparison`
1244
+ );
1245
+ } else {
1246
+ assertString(comparison.comparison, `${itemPath}.comparison`);
1247
+ assertOptionalString(comparison.evidence, `${itemPath}.evidence`);
1248
+ assertPortablePath(
1249
+ comparison.comparison,
1250
+ `${itemPath}.comparison`
1251
+ );
1252
+ if (typeof comparison.evidence === "string") {
1253
+ assertPortablePath(comparison.evidence, `${itemPath}.evidence`);
1254
+ }
1255
+ }
1256
+ }
1257
+ }
1258
+ function assertPortablePath(value, path) {
1259
+ if (value.length === 0 || value.startsWith("/") || value.startsWith("\\") || /^[a-zA-Z]:[\\/]/.test(value) || value.split(/[\\/]+/).includes("..")) {
1260
+ throw new Error(
1261
+ `${path} must be a relative path within its portable bundle.`
1262
+ );
1263
+ }
1264
+ }
1128
1265
  function assertRecord(value, path) {
1129
1266
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
1130
1267
  throw new Error(`${path} must be an object.`);
@@ -1152,6 +1289,11 @@ function assertNumber(value, path) {
1152
1289
  throw new Error(`${path} must be a finite number.`);
1153
1290
  }
1154
1291
  }
1292
+ function assertNonNegativeInteger(value, path) {
1293
+ if (!Number.isInteger(value) || value < 0) {
1294
+ throw new Error(`${path} must be a non-negative integer.`);
1295
+ }
1296
+ }
1155
1297
 
1156
1298
  // src/testing/ui-fixture/create-fixture-host-harness.ts
1157
1299
  var DEFAULT_CHANNEL_ID = "fixture-channel";
@@ -1976,7 +2118,9 @@ export {
1976
2118
  inspectScenario,
1977
2119
  isSha256Digest,
1978
2120
  isStaleContractArtifactError,
1979
- parseUIParityObservationV1,
2121
+ parseUIParityObservation,
2122
+ parseUIParityRealHostReceipt,
2123
+ parseUIParityRunInput,
1980
2124
  parseUIScenarioFixture,
1981
2125
  parseUIScenarioFixtureBundleIndex,
1982
2126
  pluginProtocolTapeSchema,