@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.
- package/EDITING.md +131 -0
- package/NATIVE-SOURCES.md +222 -0
- package/README.md +18 -0
- package/dist/bb-entry-runtime.js +107 -87
- package/dist/client-entry-runtime.js +128 -36
- package/dist/editing-runtime.js +1845 -0
- package/dist/host-runtime.js +54 -29
- package/dist/index-runtime.js +21 -0
- package/dist/model-runtime.js +21 -0
- package/dist/native-runtime.js +476 -0
- package/dist/native-testing-runtime.js +11 -0
- package/dist/react-entry-runtime.js +253 -51
- package/dist/state-controller-runtime.js +96 -11
- package/dist/state-runtime.js +95 -11
- package/dist/testing-runtime.js +112 -92
- package/editing.d.ts +137 -0
- package/host.d.ts +1 -0
- package/native-testing.d.ts +15 -0
- package/native.d.ts +100 -0
- package/package.json +20 -3
- package/react.d.ts +16 -0
package/dist/host-runtime.js
CHANGED
|
@@ -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,
|
|
471
|
-
if (!isRecord2(
|
|
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 =
|
|
474
|
-
const 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 !==
|
|
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:
|
|
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
|
|
515
|
-
const decoded = profile(current.value,
|
|
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)) ||
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
};
|
package/dist/index-runtime.js
CHANGED
|
@@ -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
|
}
|
package/dist/model-runtime.js
CHANGED
|
@@ -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
|
}
|