@phosphorco/bb-identity 0.3.0 → 0.4.0

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.
@@ -1,4 +1,27 @@
1
1
  // @bun
2
+ // external-person-output-runtime.ts
3
+ function record(value) {
4
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5
+ }
6
+ function normalizeExternalPersonOutput(value) {
7
+ if (!record(value) || !record(value.identity) || !record(value.presentation))
8
+ return value;
9
+ return {
10
+ identity: { kind: value.identity.kind, key: value.identity.key, issuer: value.identity.issuer, subject: value.identity.subject },
11
+ presentation: { displayName: value.presentation.displayName, handle: value.presentation.handle, avatarUrl: value.presentation.avatarUrl },
12
+ evidence: value.evidence
13
+ };
14
+ }
15
+ function normalizeContributionOutput(value) {
16
+ return record(value) && value.personAttribution !== undefined ? { ...value, personAttribution: normalizeExternalPersonOutput(value.personAttribution) } : value;
17
+ }
18
+ function normalizeProvenanceOutput(value) {
19
+ return record(value) && Array.isArray(value.contributions) ? { ...value, contributions: value.contributions.map(normalizeContributionOutput) } : value;
20
+ }
21
+ function normalizeEvidencePageOutput(value, normalize) {
22
+ return record(value) && Array.isArray(value.items) ? { ...value, items: value.items.map(normalize) } : value;
23
+ }
24
+
2
25
  // model-runtime.ts
3
26
  var ID_MAX_LENGTH = 256;
4
27
  var ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:@/-]*$/;
@@ -165,6 +188,7 @@ function hasCompleteCausality(groups, contributions, missing) {
165
188
  }
166
189
  var provenanceCodec = {
167
190
  decode(input) {
191
+ input = normalizeProvenanceOutput(input);
168
192
  if (!isRecord(input) || input.status !== "known" && input.status !== "partial" && input.status !== "unknown") {
169
193
  return err("invalid-input", "Invalid execution provenance.");
170
194
  }
@@ -467,11 +491,11 @@ function createEnhancedDirectory(protocol) {
467
491
  }
468
492
  mappings.set(key, mapping);
469
493
  };
470
- const profile = (source, record, revision) => {
471
- if (!isRecord2(record) || !source.issuers.includes(record.issuer) || !idCodec("issuer").decode(record.issuer).ok || !idCodec("subject").decode(record.subject).ok || !isProfilePresentation(record.presentation) || record.status !== "current" && record.status !== "historical" || !idCodec("revision").decode(revision).ok)
494
+ const profile = (source, record2, revision) => {
495
+ if (!isRecord2(record2) || !source.issuers.includes(record2.issuer) || !idCodec("issuer").decode(record2.issuer).ok || !idCodec("subject").decode(record2.subject).ok || !isProfilePresentation(record2.presentation) || record2.status !== "current" && record2.status !== "historical" || !idCodec("revision").decode(revision).ok)
472
496
  return err("incompatible", "Provider directory record is malformed.");
473
- const issuer = record.issuer;
474
- const subject = record.subject;
497
+ const issuer = record2.issuer;
498
+ const subject = record2.subject;
475
499
  if (typeof issuer !== "string" || typeof subject !== "string")
476
500
  return err("incompatible", "Provider directory record is malformed.");
477
501
  let person;
@@ -482,10 +506,10 @@ function createEnhancedDirectory(protocol) {
482
506
  }
483
507
  if (!person.ok)
484
508
  return person;
485
- if (person.value.kind !== "person" || person.value.issuer !== record.issuer || person.value.subject !== record.subject || !identityKeyCodec.decode(person.value.key).ok) {
509
+ if (person.value.kind !== "person" || person.value.issuer !== record2.issuer || person.value.subject !== record2.subject || !identityKeyCodec.decode(person.value.key).ok) {
486
510
  return err("incompatible", "Provider directory returned an invalid person reference.");
487
511
  }
488
- return profileCodec.decode({ identity: person.value, presentation: record.presentation, revision, status: record.status });
512
+ return profileCodec.decode({ identity: person.value, presentation: record2.presentation, revision, status: record2.status });
489
513
  };
490
514
  return {
491
515
  async search(input, options) {
@@ -511,8 +535,8 @@ function createEnhancedDirectory(protocol) {
511
535
  if (!Array.isArray(result.value.records) || result.value.records.length > input.limit || result.value.nextCursor !== null && !idCodec("cursor").decode(result.value.nextCursor).ok || !idCodec("revision").decode(result.value.revision).ok)
512
536
  return err("incompatible", "Provider directory page is malformed.");
513
537
  const profiles = [];
514
- for (const record of result.value.records) {
515
- const decoded = profile(current.value, record, result.value.revision);
538
+ for (const record2 of result.value.records) {
539
+ const decoded = profile(current.value, record2, result.value.revision);
516
540
  if (!decoded.ok)
517
541
  return decoded;
518
542
  if (input.history === "current" && decoded.value.status !== "current")
@@ -821,7 +845,7 @@ function createHostAdapter(options) {
821
845
  } catch {
822
846
  return err("unavailable", "Contribution history is unavailable.", "after-reconnect");
823
847
  }
824
- return result.ok ? decodeEvidencePage(result.value, isContribution2) : result;
848
+ return result.ok ? decodeEvidencePage(normalizeEvidencePageOutput(result.value, normalizeContributionOutput), isContribution2) : result;
825
849
  },
826
850
  async attempts(query, readOptions) {
827
851
  if (!validAttemptQuery(query))
@@ -834,7 +858,7 @@ function createHostAdapter(options) {
834
858
  } catch {
835
859
  return err("unavailable", "Execution history is unavailable.", "after-reconnect");
836
860
  }
837
- return result.ok ? decodeEvidencePage(result.value, (item) => provenanceCodec.decode(item).ok) : result;
861
+ return result.ok ? decodeEvidencePage(normalizeEvidencePageOutput(result.value, normalizeProvenanceOutput), (item) => provenanceCodec.decode(item).ok) : result;
838
862
  }
839
863
  };
840
864
  const subscription = protocol.subscribe((event) => {
@@ -931,16 +955,12 @@ function createHostAdapter(options) {
931
955
  };
932
956
  }
933
957
  function decodeExternalContribution(value, strict = true) {
934
- if (!isRecord2(value) || value.version !== 1 || !isRecord2(value.author) || strict && Object.keys(value).some((key) => !["version", "author", "personAttribution"].includes(key)) || strict && Object.keys(value.author).some((key) => !["subject", "presentation"].includes(key)) || strict && isRecord2(value.author.presentation) && Object.keys(value.author.presentation).some((key) => !["displayName", "handle", "avatarUrl"].includes(key)) || !idCodec("subject").decode(value.author.subject).ok || !isProfilePresentation(value.author.presentation)) {
958
+ if (!isRecord2(value) || value.version !== 1 || !isRecord2(value.author) || strict && Object.keys(value).some((key) => !["version", "author", "personAttribution"].includes(key)) || strict && Object.keys(value.author).some((key) => !["subject", "presentation"].includes(key)) || strict && isRecord2(value.author.presentation) && Object.keys(value.author.presentation).some((key) => !["displayName", "handle", "avatarUrl"].includes(key)) || (typeof value.author.subject !== "string" || value.author.subject.length === 0 || value.author.subject.length > 256) || !isProfilePresentation(value.author.presentation)) {
935
959
  return err("invalid-input", "Invalid V1 external contribution.");
936
960
  }
937
961
  let person = value.personAttribution;
938
- if (!strict && isRecord2(person) && isRecord2(person.identity))
939
- person = {
940
- identity: { kind: person.identity.kind, key: person.identity.key, issuer: person.identity.issuer, subject: person.identity.subject },
941
- presentation: isRecord2(person.presentation) ? { displayName: person.presentation.displayName, handle: person.presentation.handle, avatarUrl: person.presentation.avatarUrl } : person.presentation,
942
- evidence: person.evidence
943
- };
962
+ if (!strict)
963
+ person = normalizeExternalPersonOutput(person);
944
964
  if (strict && isRecord2(person) && isRecord2(person.presentation) && Object.keys(person.presentation).some((key) => !["displayName", "handle", "avatarUrl"].includes(key)))
945
965
  return err("invalid-input", "Unexpected presentation field.");
946
966
  const decoded = person === undefined ? null : externalPersonSnapshotCodec.decode(person);
@@ -963,6 +983,20 @@ function canonicalExternal(value) {
963
983
  return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalExternal(value[key])}`).join(",")}}`;
964
984
  return JSON.stringify(value);
965
985
  }
986
+ function decodeExternalContributionOutcomeV1(raw) {
987
+ const decoded = decodeAcceptance(raw);
988
+ if (!decoded.ok || decoded.value.status !== "submitted")
989
+ return decoded;
990
+ if (decoded.value.receipt.evidence !== "host-accepted")
991
+ return err("incompatible", "V1 needs durable native acceptance.");
992
+ const receipt = decoded.value.receipt;
993
+ const contribution = decodeExternalContribution(receipt.externalContribution, false);
994
+ return contribution.ok ? ok({ status: "submitted", receipt: { ...decoded.value.receipt, externalContribution: contribution.value } }) : err("incompatible", "Host receipt omitted or changed V1 attribution.");
995
+ }
996
+ var externalContributionOutcomeV1Codec = {
997
+ decode: decodeExternalContributionOutcomeV1,
998
+ encode: (value) => value
999
+ };
966
1000
  function externalContributionMethods(upstream, extension, disposed) {
967
1001
  const support = () => {
968
1002
  if (disposed())
@@ -982,16 +1016,6 @@ function externalContributionMethods(upstream, extension, disposed) {
982
1016
  return err("incompatible", "Malformed V1 external contribution capability.");
983
1017
  return ok(value);
984
1018
  };
985
- const outcome = (raw) => {
986
- const decoded = decodeAcceptance(raw);
987
- if (!decoded.ok || decoded.value.status !== "submitted")
988
- return decoded;
989
- if (decoded.value.receipt.evidence !== "host-accepted")
990
- return err("incompatible", "V1 needs durable native acceptance.");
991
- const receipt = decoded.value.receipt;
992
- const contribution = decodeExternalContribution(receipt.externalContribution, false);
993
- return contribution.ok ? ok({ status: "submitted", receipt: { ...decoded.value.receipt, externalContribution: contribution.value } }) : err("incompatible", "Host receipt omitted or changed V1 attribution.");
994
- };
995
1019
  return {
996
1020
  externalContributionCapabilities() {
997
1021
  const negotiated = support();
@@ -1012,7 +1036,7 @@ function externalContributionMethods(upstream, extension, disposed) {
1012
1036
  const frozen = JSON.parse(JSON.stringify(decoded.value));
1013
1037
  const wire = JSON.parse(JSON.stringify(wireInput(input, upstream.inputCodec)));
1014
1038
  try {
1015
- const result = outcome(await negotiated.value.acceptV1({ contribution: frozen, input: wire }, options));
1039
+ const result = decodeExternalContributionOutcomeV1(await negotiated.value.acceptV1({ contribution: frozen, input: wire }, options));
1016
1040
  if (!result.ok)
1017
1041
  return { status: "indeterminate", operationId, message: result.error.message };
1018
1042
  if (result.value.status === "submitted" && (result.value.receipt.operationId !== operationId || canonicalExternal(result.value.receipt.externalContribution) !== canonicalExternal(frozen))) {
@@ -1034,7 +1058,7 @@ function externalContributionMethods(upstream, extension, disposed) {
1034
1058
  if (!result.ok)
1035
1059
  return result;
1036
1060
  if (isRecord2(result.value) && result.value.status === "final") {
1037
- const decoded = outcome(result.value.outcome);
1061
+ const decoded = decodeExternalContributionOutcomeV1(result.value.outcome);
1038
1062
  if (decoded.ok && decoded.value.status === "submitted" && decoded.value.receipt.operationId !== operationId) {
1039
1063
  return err("incompatible", "Host lookup returned a receipt for another operation.");
1040
1064
  }
@@ -1060,5 +1084,6 @@ export {
1060
1084
  serverSessionCodec,
1061
1085
  inspectForkExtension,
1062
1086
  externalContributionV1Codec,
1087
+ externalContributionOutcomeV1Codec,
1063
1088
  createHostAdapter
1064
1089
  };
@@ -1,4 +1,24 @@
1
1
  // @bun
2
+ // external-person-output-runtime.ts
3
+ function record(value) {
4
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5
+ }
6
+ function normalizeExternalPersonOutput(value) {
7
+ if (!record(value) || !record(value.identity) || !record(value.presentation))
8
+ return value;
9
+ return {
10
+ identity: { kind: value.identity.kind, key: value.identity.key, issuer: value.identity.issuer, subject: value.identity.subject },
11
+ presentation: { displayName: value.presentation.displayName, handle: value.presentation.handle, avatarUrl: value.presentation.avatarUrl },
12
+ evidence: value.evidence
13
+ };
14
+ }
15
+ function normalizeContributionOutput(value) {
16
+ return record(value) && value.personAttribution !== undefined ? { ...value, personAttribution: normalizeExternalPersonOutput(value.personAttribution) } : value;
17
+ }
18
+ function normalizeProvenanceOutput(value) {
19
+ return record(value) && Array.isArray(value.contributions) ? { ...value, contributions: value.contributions.map(normalizeContributionOutput) } : value;
20
+ }
21
+
2
22
  // model-runtime.ts
3
23
  var ID_MAX_LENGTH = 256;
4
24
  var ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:@/-]*$/;
@@ -165,6 +185,7 @@ function hasCompleteCausality(groups, contributions, missing) {
165
185
  }
166
186
  var provenanceCodec = {
167
187
  decode(input) {
188
+ input = normalizeProvenanceOutput(input);
168
189
  if (!isRecord(input) || input.status !== "known" && input.status !== "partial" && input.status !== "unknown") {
169
190
  return err("invalid-input", "Invalid execution provenance.");
170
191
  }
@@ -1,4 +1,24 @@
1
1
  // @bun
2
+ // external-person-output-runtime.ts
3
+ function record(value) {
4
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5
+ }
6
+ function normalizeExternalPersonOutput(value) {
7
+ if (!record(value) || !record(value.identity) || !record(value.presentation))
8
+ return value;
9
+ return {
10
+ identity: { kind: value.identity.kind, key: value.identity.key, issuer: value.identity.issuer, subject: value.identity.subject },
11
+ presentation: { displayName: value.presentation.displayName, handle: value.presentation.handle, avatarUrl: value.presentation.avatarUrl },
12
+ evidence: value.evidence
13
+ };
14
+ }
15
+ function normalizeContributionOutput(value) {
16
+ return record(value) && value.personAttribution !== undefined ? { ...value, personAttribution: normalizeExternalPersonOutput(value.personAttribution) } : value;
17
+ }
18
+ function normalizeProvenanceOutput(value) {
19
+ return record(value) && Array.isArray(value.contributions) ? { ...value, contributions: value.contributions.map(normalizeContributionOutput) } : value;
20
+ }
21
+
2
22
  // model-runtime.ts
3
23
  var ID_MAX_LENGTH = 256;
4
24
  var ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:@/-]*$/;
@@ -165,6 +185,7 @@ function hasCompleteCausality(groups, contributions, missing) {
165
185
  }
166
186
  var provenanceCodec = {
167
187
  decode(input) {
188
+ input = normalizeProvenanceOutput(input);
168
189
  if (!isRecord(input) || input.status !== "known" && input.status !== "partial" && input.status !== "unknown") {
169
190
  return err("invalid-input", "Invalid execution provenance.");
170
191
  }