gdc-common-utils-ts 2.0.18 → 2.2.2

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.
Files changed (185) hide show
  1. package/README.md +18 -1
  2. package/dist/claims/claims-helpers-allergy-intolerance.d.ts +8 -0
  3. package/dist/claims/claims-helpers-allergy-intolerance.js +30 -12
  4. package/dist/claims/claims-helpers-condition.d.ts +8 -0
  5. package/dist/claims/claims-helpers-condition.js +30 -12
  6. package/dist/claims/claims-helpers-consent.d.ts +4 -0
  7. package/dist/claims/claims-helpers-consent.js +15 -1
  8. package/dist/claims/claims-helpers-diagnostic-report.d.ts +4 -0
  9. package/dist/claims/claims-helpers-diagnostic-report.js +17 -2
  10. package/dist/claims/claims-helpers-medication-statement.d.ts +10 -2
  11. package/dist/claims/claims-helpers-medication-statement.js +32 -14
  12. package/dist/constants/didcomm.d.ts +22 -0
  13. package/dist/constants/didcomm.js +22 -0
  14. package/dist/constants/fhir-resource-types.d.ts +2 -0
  15. package/dist/constants/fhir-resource-types.js +1 -0
  16. package/dist/constants/index.d.ts +1 -0
  17. package/dist/constants/index.js +1 -0
  18. package/dist/constants/lifecycle.d.ts +2 -0
  19. package/dist/constants/lifecycle.js +2 -0
  20. package/dist/constants/verifiable-credentials.d.ts +9 -0
  21. package/dist/constants/verifiable-credentials.js +9 -0
  22. package/dist/examples/bundle-didcomm-payload.d.ts +11 -0
  23. package/dist/examples/bundle-didcomm-payload.js +15 -0
  24. package/dist/examples/communication-attached-bundle-session.js +28 -27
  25. package/dist/examples/communication-didcomm-payload.d.ts +39 -0
  26. package/dist/examples/communication-didcomm-payload.js +44 -0
  27. package/dist/examples/consent-access.js +2 -1
  28. package/dist/examples/employee.d.ts +21 -0
  29. package/dist/examples/employee.js +21 -0
  30. package/dist/examples/index.d.ts +4 -0
  31. package/dist/examples/index.js +4 -0
  32. package/dist/examples/individual-controller.d.ts +27 -0
  33. package/dist/examples/individual-controller.js +28 -1
  34. package/dist/examples/inter-tenant-access-contract.js +3 -2
  35. package/dist/examples/ips-bundle.js +17 -16
  36. package/dist/examples/lifecycle.js +13 -11
  37. package/dist/examples/profile-manager-mem.d.ts +45 -0
  38. package/dist/examples/profile-manager-mem.js +30 -0
  39. package/dist/examples/related-person.d.ts +14 -0
  40. package/dist/examples/related-person.js +18 -4
  41. package/dist/examples/shared.d.ts +13 -3
  42. package/dist/examples/shared.js +14 -4
  43. package/dist/examples/vital-signs.js +1 -1
  44. package/dist/examples/wallet-mem.d.ts +38 -0
  45. package/dist/examples/wallet-mem.js +42 -0
  46. package/dist/index.d.ts +1 -0
  47. package/dist/index.js +1 -0
  48. package/dist/interfaces/IProfileOutboxRepository.d.ts +36 -0
  49. package/dist/interfaces/IProfileOutboxRepository.js +2 -0
  50. package/dist/interfaces/IWallet.d.ts +74 -0
  51. package/dist/interfaces/IWallet.js +2 -0
  52. package/dist/interfaces/IWalletQueue.d.ts +30 -0
  53. package/dist/interfaces/IWalletQueue.js +2 -0
  54. package/dist/interfaces/index.d.ts +8 -0
  55. package/dist/interfaces/index.js +8 -0
  56. package/dist/models/authority-resolution.d.ts +56 -0
  57. package/dist/models/authority-resolution.js +2 -0
  58. package/dist/models/bundle-editor-types.d.ts +89 -0
  59. package/dist/models/bundle-editor-types.js +45 -0
  60. package/dist/models/bundle.d.ts +5 -0
  61. package/dist/models/communication-attached-bundle-session.d.ts +195 -0
  62. package/dist/models/communication-attached-bundle-session.js +36 -0
  63. package/dist/models/confidential-storage.d.ts +2 -1
  64. package/dist/models/consent-rule.d.ts +11 -1
  65. package/dist/models/consent-rule.js +9 -1
  66. package/dist/models/index.d.ts +5 -0
  67. package/dist/models/index.js +5 -0
  68. package/dist/models/individual-onboarding.d.ts +18 -0
  69. package/dist/models/interoperable-claims/allergy-intolerance-claims.d.ts +12 -1
  70. package/dist/models/interoperable-claims/allergy-intolerance-claims.js +12 -1
  71. package/dist/models/interoperable-claims/condition-claims.d.ts +12 -1
  72. package/dist/models/interoperable-claims/condition-claims.js +12 -1
  73. package/dist/models/interoperable-claims/diagnostic-report-claims.d.ts +14 -4
  74. package/dist/models/interoperable-claims/diagnostic-report-claims.js +13 -3
  75. package/dist/models/interoperable-claims/document-reference-claims.d.ts +1 -0
  76. package/dist/models/interoperable-claims/document-reference-claims.js +3 -0
  77. package/dist/models/interoperable-claims/medication-statement-claims.d.ts +17 -0
  78. package/dist/models/interoperable-claims/medication-statement-claims.js +17 -0
  79. package/dist/models/profile-manager.d.ts +85 -0
  80. package/dist/models/profile-manager.js +2 -0
  81. package/dist/models/wallet.d.ts +59 -0
  82. package/dist/models/wallet.js +22 -0
  83. package/dist/utils/allergy-intolerance-entry-editor.d.ts +51 -0
  84. package/dist/utils/allergy-intolerance-entry-editor.js +55 -0
  85. package/dist/utils/authority-resolution.d.ts +37 -0
  86. package/dist/utils/authority-resolution.js +112 -0
  87. package/dist/utils/backend-message-manager-mem.d.ts +78 -0
  88. package/dist/utils/backend-message-manager-mem.js +238 -0
  89. package/dist/utils/bundle-didcomm-payload.d.ts +29 -0
  90. package/dist/utils/bundle-didcomm-payload.js +49 -0
  91. package/dist/utils/bundle-document-builder.d.ts +1 -0
  92. package/dist/utils/bundle-document-builder.js +134 -14
  93. package/dist/utils/bundle-editor-core.d.ts +181 -0
  94. package/dist/utils/bundle-editor-core.js +467 -0
  95. package/dist/utils/bundle-editor-helpers.d.ts +53 -0
  96. package/dist/utils/bundle-editor-helpers.js +146 -0
  97. package/dist/utils/bundle-editor-registry.d.ts +6 -0
  98. package/dist/utils/bundle-editor-registry.js +14 -0
  99. package/dist/utils/bundle-editor.d.ts +21 -722
  100. package/dist/utils/bundle-editor.js +21 -1601
  101. package/dist/utils/bundle-entry-editor.d.ts +96 -0
  102. package/dist/utils/bundle-entry-editor.js +305 -0
  103. package/dist/utils/bundle-query.d.ts +1 -0
  104. package/dist/utils/bundle-query.js +12 -3
  105. package/dist/utils/bundle-reader.d.ts +48 -0
  106. package/dist/utils/bundle-reader.js +175 -1
  107. package/dist/utils/care-plan-entry-editor.d.ts +43 -0
  108. package/dist/utils/care-plan-entry-editor.js +47 -0
  109. package/dist/utils/client-assertion.d.ts +38 -0
  110. package/dist/utils/client-assertion.js +113 -0
  111. package/dist/utils/clinical-impression-entry-editor.d.ts +43 -0
  112. package/dist/utils/clinical-impression-entry-editor.js +47 -0
  113. package/dist/utils/clinical-resource-entry-editor.d.ts +123 -0
  114. package/dist/utils/clinical-resource-entry-editor.js +296 -0
  115. package/dist/utils/communication-attached-bundle-session-helpers.d.ts +54 -0
  116. package/dist/utils/communication-attached-bundle-session-helpers.js +519 -0
  117. package/dist/utils/communication-attached-bundle-session.d.ts +87 -304
  118. package/dist/utils/communication-attached-bundle-session.js +175 -841
  119. package/dist/utils/communication-consent-access-editor.d.ts +85 -0
  120. package/dist/utils/communication-consent-access-editor.js +244 -0
  121. package/dist/utils/communication-didcomm-payload.d.ts +38 -0
  122. package/dist/utils/communication-didcomm-payload.js +85 -0
  123. package/dist/utils/communication-document-reference.d.ts +23 -0
  124. package/dist/utils/communication-document-reference.js +89 -0
  125. package/dist/utils/communication-editor.d.ts +53 -0
  126. package/dist/utils/communication-editor.js +97 -0
  127. package/dist/utils/condition-entry-editor.d.ts +30 -0
  128. package/dist/utils/condition-entry-editor.js +34 -0
  129. package/dist/utils/consent-claim-helpers.d.ts +4 -0
  130. package/dist/utils/consent-claim-helpers.js +15 -1
  131. package/dist/utils/coverage-entry-editor.d.ts +51 -0
  132. package/dist/utils/coverage-entry-editor.js +55 -0
  133. package/dist/utils/device-entry-editor.d.ts +59 -0
  134. package/dist/utils/device-entry-editor.js +63 -0
  135. package/dist/utils/device-use-statement-entry-editor.d.ts +43 -0
  136. package/dist/utils/device-use-statement-entry-editor.js +47 -0
  137. package/dist/utils/diagnostic-report-entry-editor.d.ts +74 -0
  138. package/dist/utils/diagnostic-report-entry-editor.js +136 -0
  139. package/dist/utils/did.d.ts +8 -0
  140. package/dist/utils/did.js +22 -0
  141. package/dist/utils/document-reference-entry-editor.d.ts +62 -0
  142. package/dist/utils/document-reference-entry-editor.js +66 -0
  143. package/dist/utils/employee-entry-editor.d.ts +36 -0
  144. package/dist/utils/employee-entry-editor.js +88 -0
  145. package/dist/utils/employee.d.ts +1 -0
  146. package/dist/utils/employee.js +2 -1
  147. package/dist/utils/encounter-entry-editor.d.ts +51 -0
  148. package/dist/utils/encounter-entry-editor.js +55 -0
  149. package/dist/utils/flag-entry-editor.d.ts +47 -0
  150. package/dist/utils/flag-entry-editor.js +51 -0
  151. package/dist/utils/immunization-entry-editor.d.ts +87 -0
  152. package/dist/utils/immunization-entry-editor.js +169 -0
  153. package/dist/utils/index.d.ts +15 -0
  154. package/dist/utils/index.js +15 -0
  155. package/dist/utils/individual-onboarding-acceptance-credential.d.ts +35 -0
  156. package/dist/utils/individual-onboarding-acceptance-credential.js +55 -0
  157. package/dist/utils/individual-smart.d.ts +59 -0
  158. package/dist/utils/individual-smart.js +135 -0
  159. package/dist/utils/medication-statement-entry-editor.d.ts +90 -0
  160. package/dist/utils/medication-statement-entry-editor.js +94 -0
  161. package/dist/utils/observation-component-entry-editor.d.ts +57 -0
  162. package/dist/utils/observation-component-entry-editor.js +105 -0
  163. package/dist/utils/observation-entry-editor.d.ts +29 -0
  164. package/dist/utils/observation-entry-editor.js +68 -0
  165. package/dist/utils/procedure-entry-editor.d.ts +71 -0
  166. package/dist/utils/procedure-entry-editor.js +75 -0
  167. package/dist/utils/professional-smart.d.ts +87 -0
  168. package/dist/utils/professional-smart.js +118 -4
  169. package/dist/utils/profile-manager-mem.d.ts +69 -0
  170. package/dist/utils/profile-manager-mem.js +79 -0
  171. package/dist/utils/profile-outbox-memory-repository.d.ts +34 -0
  172. package/dist/utils/profile-outbox-memory-repository.js +57 -0
  173. package/dist/utils/same-as.d.ts +40 -0
  174. package/dist/utils/same-as.js +72 -0
  175. package/dist/utils/unified-health-id.d.ts +51 -0
  176. package/dist/utils/unified-health-id.js +92 -0
  177. package/dist/utils/vital-sign-day-batch.d.ts +25 -0
  178. package/dist/utils/vital-sign-day-batch.js +115 -0
  179. package/dist/utils/vital-sign-entry-editor.d.ts +61 -0
  180. package/dist/utils/vital-sign-entry-editor.js +152 -0
  181. package/dist/utils/wallet-mem.d.ts +93 -0
  182. package/dist/utils/wallet-mem.js +277 -0
  183. package/dist/utils/wallet-memory-queue.d.ts +32 -0
  184. package/dist/utils/wallet-memory-queue.js +82 -0
  185. package/package.json +2 -1
@@ -0,0 +1,85 @@
1
+ import { type HealthcareActorRoleDescriptor, type HealthcareSectionDescriptor } from '../constants/healthcare';
2
+ import type { DataspaceSector } from '../constants/sectors';
3
+ import type { CommunicationAttachedBundleSessionOptions, ConsentEditorClassifiedActors, ConsentEditorClassifiedPurpose, ConsentEditorClassifiedRoles, ConsentEditorClassifiedTarget, ConsentViewModel } from '../models/communication-attached-bundle-session';
4
+ import type { ConsentDuplicateRuleConflict } from './consent-duplicate-rules';
5
+ import { CommunicationAttachedBundleSession } from './communication-attached-bundle-session';
6
+ /**
7
+ * High-level consent-access editor alias for onboarding and app-facing code.
8
+ *
9
+ * This keeps the business intent explicit for developers who are editing
10
+ * Consent access rules inside a Communication-carried bundle and should not
11
+ * need to start from the lower-level generic session name.
12
+ */
13
+ export declare class ConsentAccessEditor extends CommunicationAttachedBundleSession {
14
+ /** Returns duplicate atomic consent-rule conflicts across the current bundle. */
15
+ getConsentRuleDuplicateConflicts(): ConsentDuplicateRuleConflict[];
16
+ /** Returns duplicate atomic consent-rule conflicts affecting the active Consent entry. */
17
+ getActiveConsentRuleDuplicateConflicts(): ConsentDuplicateRuleConflict[];
18
+ /** Returns one frontend-facing editable view model for the active Consent entry. */
19
+ getConsentViewModel(): ConsentViewModel;
20
+ /** Applies one frontend-facing editable view model back into the active Consent entry. */
21
+ applyConsentViewModel(viewModel: ConsentViewModel): this;
22
+ /** Returns the canonical permit/deny decision from the active Consent entry. */
23
+ getDecision(): string;
24
+ /** @deprecated Use `getDecision()`. */
25
+ getPermit(): string;
26
+ /** Returns target classification derived from the current consent claim contract. */
27
+ getTargetsClassified(): ConsentEditorClassifiedTarget[];
28
+ getCoreSectionOptions(): readonly ConsentEditorClassifiedTarget[];
29
+ getCoreSectionCatalog(): Readonly<Record<string, HealthcareSectionDescriptor>>;
30
+ getKindOfDocumentOptions(): readonly ConsentEditorClassifiedTarget[];
31
+ getKindOfDocumentCatalog(): Readonly<Record<string, HealthcareSectionDescriptor>>;
32
+ getTypeOfServiceOptions(): readonly ConsentEditorClassifiedTarget[];
33
+ getTypeOfServiceCatalog(): Readonly<Record<string, HealthcareSectionDescriptor>>;
34
+ getSubjectMatterDomainOptions(): readonly ConsentEditorClassifiedTarget[];
35
+ getSubjectMatterDomainCatalog(): Readonly<Record<string, HealthcareSectionDescriptor>>;
36
+ getResourceTypeOptions(): readonly ConsentEditorClassifiedTarget[];
37
+ getResourceTypeCatalog(): readonly string[];
38
+ getAvailableProfessionalRolesBySector(sector: DataspaceSector): Readonly<Record<string, HealthcareActorRoleDescriptor>>;
39
+ getAvailableRelationshipRoles(): Readonly<Record<string, HealthcareActorRoleDescriptor>>;
40
+ getSelectedCoreSections(): string[];
41
+ getSelectedKindOfDocuments(): string[];
42
+ getSelectedTypeOfServices(): string[];
43
+ getSelectedSubjectMatterDomains(): string[];
44
+ getSelectedResourceTypes(): string[];
45
+ setSelectedCoreSections(codes: readonly string[]): this;
46
+ setSelectedKindOfDocuments(codes: readonly string[]): this;
47
+ setSelectedTypeOfServices(codes: readonly string[]): this;
48
+ setSelectedSubjectMatterDomains(codes: readonly string[]): this;
49
+ setSelectedResourceTypes(codes: readonly string[]): this;
50
+ addCoreSections(codes: readonly string[]): this;
51
+ removeCoreSections(codes: readonly string[]): this;
52
+ addKindOfDocuments(codes: readonly string[]): this;
53
+ removeKindOfDocuments(codes: readonly string[]): this;
54
+ addTypeOfServices(codes: readonly string[]): this;
55
+ removeTypeOfServices(codes: readonly string[]): this;
56
+ addSubjectMatterDomains(codes: readonly string[]): this;
57
+ removeSubjectMatterDomains(codes: readonly string[]): this;
58
+ addResourceTypes(codes: readonly string[]): this;
59
+ removeResourceTypes(codes: readonly string[]): this;
60
+ getPurposesClassified(): ConsentEditorClassifiedPurpose[];
61
+ getSelectedPurposes(): string[];
62
+ setSelectedPurposes(codes: readonly string[]): this;
63
+ addPurposes(codes: readonly string[]): this;
64
+ removePurposes(codes: readonly string[]): this;
65
+ getRolesClassified(): ConsentEditorClassifiedRoles;
66
+ getSelectedRoles(): string[];
67
+ setSelectedRoles(codes: readonly string[]): this;
68
+ addRoles(codes: readonly string[]): this;
69
+ removeRoles(codes: readonly string[]): this;
70
+ getActorsClassified(): ConsentEditorClassifiedActors;
71
+ private getSelectedSectionCodesByFamily;
72
+ private setSelectedSectionCodesByFamily;
73
+ private addSectionCodesByFamily;
74
+ private removeSectionCodesByFamily;
75
+ private setActiveEntryClaimList;
76
+ private addActiveEntryClaimList;
77
+ private removeActiveEntryClaimList;
78
+ }
79
+ /**
80
+ * High-level factory for consent-access editing.
81
+ *
82
+ * Prefer this name in onboarding docs when the developer intent is:
83
+ * "edit a Consent access bundle carried by a Communication".
84
+ */
85
+ export declare function createConsentAccessEditor(options?: CommunicationAttachedBundleSessionOptions): ConsentAccessEditor;
@@ -0,0 +1,244 @@
1
+ // Copyright 2026 Conectate Soluciones y Aplicaciones SL under the Apache License, Version 2.0.
2
+ import { ResourceTypesFhirR4 } from '../constants/fhir-resource-types.js';
3
+ import { getHealthcareProfessionalRolesBySector, getHealthcareRolesByFamily, getHealthcareSectionsByFamily, getHealthcareSectionFamilyByCode, HealthcareRoleFamilies, HealthcareCanonicalSectionFamilies, } from '../constants/healthcare.js';
4
+ import { ClaimConsent } from '../models/consent-rule.js';
5
+ import { ConsentEditorScopeCodes, ConsentEditorTargetKinds, } from '../models/communication-attached-bundle-session.js';
6
+ import { detectDuplicateConsentRuleConflicts } from './consent-duplicate-rules.js';
7
+ import { CommunicationAttachedBundleSession } from './communication-attached-bundle-session.js';
8
+ import { asTrimmedString, buildClassifiedConsentTarget, buildConsentViewModel, buildSectionCatalogOptions, classifyConsentActors, classifyConsentPurposes, classifyConsentRoles, classifyConsentTargetsFromClaims, CSV_SEPARATOR, flattenClassifiedActors, flattenClassifiedRoles, flattenClassifiedTargets, normalizeCsvValues, splitCsv, } from './communication-attached-bundle-session-helpers.js';
9
+ /**
10
+ * High-level consent-access editor alias for onboarding and app-facing code.
11
+ *
12
+ * This keeps the business intent explicit for developers who are editing
13
+ * Consent access rules inside a Communication-carried bundle and should not
14
+ * need to start from the lower-level generic session name.
15
+ */
16
+ export class ConsentAccessEditor extends CommunicationAttachedBundleSession {
17
+ /** Returns duplicate atomic consent-rule conflicts across the current bundle. */
18
+ getConsentRuleDuplicateConflicts() {
19
+ return detectDuplicateConsentRuleConflicts(this.getBundleInMemory().data);
20
+ }
21
+ /** Returns duplicate atomic consent-rule conflicts affecting the active Consent entry. */
22
+ getActiveConsentRuleDuplicateConflicts() {
23
+ const activeEntryIndex = this.getActiveEntryIndex();
24
+ if (activeEntryIndex === null) {
25
+ return [];
26
+ }
27
+ return this.getConsentRuleDuplicateConflicts()
28
+ .filter((conflict) => conflict.affectedEntries.some((entry) => entry.entryIndex === activeEntryIndex));
29
+ }
30
+ /** Returns one frontend-facing editable view model for the active Consent entry. */
31
+ getConsentViewModel() {
32
+ return buildConsentViewModel(this.getActiveEntry(), this.getDecision(), this.getActorsClassified(), this.getRolesClassified(), this.getPurposesClassified(), this.getTargetsClassified());
33
+ }
34
+ /** Applies one frontend-facing editable view model back into the active Consent entry. */
35
+ applyConsentViewModel(viewModel) {
36
+ this.setActiveEntryClaim(ClaimConsent.identifier, viewModel.identifier);
37
+ this.setActiveEntryClaim(ClaimConsent.subject, viewModel.subject);
38
+ this.setActiveEntryClaim(ClaimConsent.decision, viewModel.decision);
39
+ this.setActiveEntryClaimList(ClaimConsent.actorIdentifier, flattenClassifiedActors(viewModel.classifiedActors));
40
+ this.setSelectedRoles(flattenClassifiedRoles(viewModel.classifiedRoles));
41
+ this.setSelectedPurposes(viewModel.classifiedPurposes.map((purpose) => purpose.code));
42
+ const flattenedTargets = flattenClassifiedTargets(viewModel.classifiedTargets);
43
+ this.setSelectedCoreSections(flattenedTargets.coreSections);
44
+ this.setSelectedKindOfDocuments(flattenedTargets.kindOfDocuments);
45
+ this.setSelectedTypeOfServices(flattenedTargets.typeOfServices);
46
+ this.setSelectedSubjectMatterDomains(flattenedTargets.subjectMatterDomains);
47
+ this.setSelectedResourceTypes(flattenedTargets.resourceTypes);
48
+ return this;
49
+ }
50
+ /** Returns the canonical permit/deny decision from the active Consent entry. */
51
+ getDecision() {
52
+ return asTrimmedString(this.getActiveEntryClaim(ClaimConsent.decision));
53
+ }
54
+ /** @deprecated Use `getDecision()`. */
55
+ getPermit() {
56
+ return this.getDecision();
57
+ }
58
+ /** Returns target classification derived from the current consent claim contract. */
59
+ getTargetsClassified() {
60
+ return classifyConsentTargetsFromClaims({
61
+ ...(this.getActiveEntry()?.resource?.meta?.claims || {}),
62
+ });
63
+ }
64
+ getCoreSectionOptions() {
65
+ return buildSectionCatalogOptions(HealthcareCanonicalSectionFamilies.CoreSection);
66
+ }
67
+ getCoreSectionCatalog() {
68
+ return getHealthcareSectionsByFamily(HealthcareCanonicalSectionFamilies.CoreSection);
69
+ }
70
+ getKindOfDocumentOptions() {
71
+ return buildSectionCatalogOptions(HealthcareCanonicalSectionFamilies.KindOfDocument);
72
+ }
73
+ getKindOfDocumentCatalog() {
74
+ return getHealthcareSectionsByFamily(HealthcareCanonicalSectionFamilies.KindOfDocument);
75
+ }
76
+ getTypeOfServiceOptions() {
77
+ return buildSectionCatalogOptions(HealthcareCanonicalSectionFamilies.TypeOfService);
78
+ }
79
+ getTypeOfServiceCatalog() {
80
+ return getHealthcareSectionsByFamily(HealthcareCanonicalSectionFamilies.TypeOfService);
81
+ }
82
+ getSubjectMatterDomainOptions() {
83
+ return buildSectionCatalogOptions(HealthcareCanonicalSectionFamilies.SubjectMatterDomain);
84
+ }
85
+ getSubjectMatterDomainCatalog() {
86
+ return getHealthcareSectionsByFamily(HealthcareCanonicalSectionFamilies.SubjectMatterDomain);
87
+ }
88
+ getResourceTypeOptions() {
89
+ return this.getSelectedResourceTypes().map((code) => buildClassifiedConsentTarget(ConsentEditorTargetKinds.ResourceType, code, [ConsentEditorScopeCodes.Read]));
90
+ }
91
+ getResourceTypeCatalog() {
92
+ return Object.values(ResourceTypesFhirR4).filter((resourceType) => resourceType !== ResourceTypesFhirR4.Bundle);
93
+ }
94
+ getAvailableProfessionalRolesBySector(sector) {
95
+ return getHealthcareProfessionalRolesBySector(sector);
96
+ }
97
+ getAvailableRelationshipRoles() {
98
+ return getHealthcareRolesByFamily(HealthcareRoleFamilies.PersonalRelationshipHl7);
99
+ }
100
+ getSelectedCoreSections() {
101
+ return this.getSelectedSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.CoreSection);
102
+ }
103
+ getSelectedKindOfDocuments() {
104
+ return splitCsv(this.getActiveEntryClaim(ClaimConsent.category));
105
+ }
106
+ getSelectedTypeOfServices() {
107
+ return this.getSelectedSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.TypeOfService);
108
+ }
109
+ getSelectedSubjectMatterDomains() {
110
+ return this.getSelectedSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.SubjectMatterDomain);
111
+ }
112
+ getSelectedResourceTypes() {
113
+ return splitCsv(this.getActiveEntryClaim(ClaimConsent.resourceType));
114
+ }
115
+ setSelectedCoreSections(codes) {
116
+ return this.setSelectedSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.CoreSection, codes);
117
+ }
118
+ setSelectedKindOfDocuments(codes) {
119
+ return this.setActiveEntryClaimList(ClaimConsent.category, codes);
120
+ }
121
+ setSelectedTypeOfServices(codes) {
122
+ return this.setSelectedSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.TypeOfService, codes);
123
+ }
124
+ setSelectedSubjectMatterDomains(codes) {
125
+ return this.setSelectedSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.SubjectMatterDomain, codes);
126
+ }
127
+ setSelectedResourceTypes(codes) {
128
+ return this.setActiveEntryClaimList(ClaimConsent.resourceType, codes);
129
+ }
130
+ addCoreSections(codes) {
131
+ return this.addSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.CoreSection, codes);
132
+ }
133
+ removeCoreSections(codes) {
134
+ return this.removeSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.CoreSection, codes);
135
+ }
136
+ addKindOfDocuments(codes) {
137
+ return this.addActiveEntryClaimList(ClaimConsent.category, codes);
138
+ }
139
+ removeKindOfDocuments(codes) {
140
+ return this.removeActiveEntryClaimList(ClaimConsent.category, codes);
141
+ }
142
+ addTypeOfServices(codes) {
143
+ return this.addSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.TypeOfService, codes);
144
+ }
145
+ removeTypeOfServices(codes) {
146
+ return this.removeSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.TypeOfService, codes);
147
+ }
148
+ addSubjectMatterDomains(codes) {
149
+ return this.addSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.SubjectMatterDomain, codes);
150
+ }
151
+ removeSubjectMatterDomains(codes) {
152
+ return this.removeSectionCodesByFamily(ClaimConsent.action, HealthcareCanonicalSectionFamilies.SubjectMatterDomain, codes);
153
+ }
154
+ addResourceTypes(codes) {
155
+ return this.addActiveEntryClaimList(ClaimConsent.resourceType, codes);
156
+ }
157
+ removeResourceTypes(codes) {
158
+ return this.removeActiveEntryClaimList(ClaimConsent.resourceType, codes);
159
+ }
160
+ getPurposesClassified() {
161
+ return classifyConsentPurposes(this.getSelectedPurposes());
162
+ }
163
+ getSelectedPurposes() {
164
+ return splitCsv(this.getActiveEntryClaim(ClaimConsent.purpose));
165
+ }
166
+ setSelectedPurposes(codes) {
167
+ return this.setActiveEntryClaimList(ClaimConsent.purpose, codes);
168
+ }
169
+ addPurposes(codes) {
170
+ return this.addActiveEntryClaimList(ClaimConsent.purpose, codes);
171
+ }
172
+ removePurposes(codes) {
173
+ return this.removeActiveEntryClaimList(ClaimConsent.purpose, codes);
174
+ }
175
+ getRolesClassified() {
176
+ return classifyConsentRoles(this.getSelectedRoles());
177
+ }
178
+ getSelectedRoles() {
179
+ return splitCsv(this.getActiveEntryClaim(ClaimConsent.actorRole));
180
+ }
181
+ setSelectedRoles(codes) {
182
+ return this.setActiveEntryClaimList(ClaimConsent.actorRole, codes);
183
+ }
184
+ addRoles(codes) {
185
+ return this.addActiveEntryClaimList(ClaimConsent.actorRole, codes);
186
+ }
187
+ removeRoles(codes) {
188
+ return this.removeActiveEntryClaimList(ClaimConsent.actorRole, codes);
189
+ }
190
+ getActorsClassified() {
191
+ const claims = {
192
+ ...(this.getActiveEntry()?.resource?.meta?.claims || {}),
193
+ };
194
+ return classifyConsentActors(splitCsv(claims[ClaimConsent.actorIdentifier]), splitCsv(claims[ClaimConsent.actorRole])[0] || '');
195
+ }
196
+ getSelectedSectionCodesByFamily(claimKey, family) {
197
+ return splitCsv(this.getActiveEntryClaim(claimKey))
198
+ .filter((code) => getHealthcareSectionFamilyByCode(code) === family);
199
+ }
200
+ setSelectedSectionCodesByFamily(claimKey, family, codes) {
201
+ const preserved = splitCsv(this.getActiveEntryClaim(claimKey))
202
+ .filter((code) => getHealthcareSectionFamilyByCode(code) !== family);
203
+ return this.setActiveEntryClaimList(claimKey, [...preserved, ...codes]);
204
+ }
205
+ addSectionCodesByFamily(claimKey, family, codes) {
206
+ const next = [...this.getSelectedSectionCodesByFamily(claimKey, family), ...codes];
207
+ return this.setSelectedSectionCodesByFamily(claimKey, family, next);
208
+ }
209
+ removeSectionCodesByFamily(claimKey, family, codes) {
210
+ const codesToRemove = new Set(normalizeCsvValues(codes));
211
+ const next = this.getSelectedSectionCodesByFamily(claimKey, family)
212
+ .filter((code) => !codesToRemove.has(code));
213
+ return this.setSelectedSectionCodesByFamily(claimKey, family, next);
214
+ }
215
+ setActiveEntryClaimList(key, values) {
216
+ const normalized = normalizeCsvValues(values);
217
+ if (normalized.length === 0) {
218
+ return this.removeActiveEntryClaim(key);
219
+ }
220
+ return this.setActiveEntryClaim(key, normalized.join(CSV_SEPARATOR));
221
+ }
222
+ addActiveEntryClaimList(key, values) {
223
+ const next = normalizeCsvValues([
224
+ ...splitCsv(this.getActiveEntryClaim(key)),
225
+ ...values,
226
+ ]);
227
+ return this.setActiveEntryClaimList(key, next);
228
+ }
229
+ removeActiveEntryClaimList(key, values) {
230
+ const valuesToRemove = new Set(normalizeCsvValues(values));
231
+ const next = splitCsv(this.getActiveEntryClaim(key))
232
+ .filter((value) => !valuesToRemove.has(value));
233
+ return this.setActiveEntryClaimList(key, next);
234
+ }
235
+ }
236
+ /**
237
+ * High-level factory for consent-access editing.
238
+ *
239
+ * Prefer this name in onboarding docs when the developer intent is:
240
+ * "edit a Consent access bundle carried by a Communication".
241
+ */
242
+ export function createConsentAccessEditor(options = {}) {
243
+ return new ConsentAccessEditor(options);
244
+ }
@@ -0,0 +1,38 @@
1
+ import type { IDecodedDidcommPayload } from '../models/confidential-message';
2
+ export declare const CommunicationDidcommEntryTypes: Readonly<{
3
+ readonly AttachedBundle: "Communication-attached-bundle-v1.0";
4
+ }>;
5
+ /**
6
+ * Input contract for wrapping canonical Communication claims as one low-level
7
+ * DIDComm-style batch payload.
8
+ */
9
+ export type BuildDidcommPayloadFromCommunicationClaimsInput = Readonly<{
10
+ communicationClaims: Record<string, unknown>;
11
+ iss: string;
12
+ aud: string;
13
+ jti: string;
14
+ thid: string;
15
+ entryType?: string;
16
+ }>;
17
+ /**
18
+ * Builds the low-level DIDComm-style batch payload that carries one FHIR-like
19
+ * `Communication` resource authored from canonical communication claims.
20
+ *
21
+ * This helper intentionally stays below actor-specific SDK facades so frontend,
22
+ * BFF, and GW-like tests can reuse the same wrapping contract.
23
+ */
24
+ export declare function buildDidcommPayloadFromCommunicationClaims(input: BuildDidcommPayloadFromCommunicationClaimsInput): IDecodedDidcommPayload;
25
+ /**
26
+ * Reads canonical communication claims from the first `body.data[]` entry of
27
+ * one DIDComm-style payload.
28
+ */
29
+ export declare function getFirstCommunicationClaimsFromDidcommPayload(payload: IDecodedDidcommPayload): Record<string, unknown>;
30
+ /**
31
+ * Reads canonical communication claims from every `body.data[]` entry of one
32
+ * DIDComm-style payload.
33
+ */
34
+ export declare function getCommunicationClaimsListFromDidcommPayload(payload: IDecodedDidcommPayload): Record<string, unknown>[];
35
+ /**
36
+ * Decodes the attached bundle carried in `Communication.content-attachment-data`.
37
+ */
38
+ export declare function decodeAttachedBundleFromCommunicationClaims(communicationClaims: Record<string, unknown>): Record<string, unknown>;
@@ -0,0 +1,85 @@
1
+ // Copyright 2026 Conectate Soluciones y Aplicaciones SL under the Apache License, Version 2.0.
2
+ import { DidcommMessageTypes } from '../constants/didcomm.js';
3
+ import { CommunicationClaim } from '../models/interoperable-claims/communication-claims.js';
4
+ import { transformCommunicationClaimsToResourceFhirR4 } from './communication-fhir-r4.js';
5
+ export const CommunicationDidcommEntryTypes = Object.freeze({
6
+ AttachedBundle: DidcommMessageTypes.CommunicationAttachedBundle,
7
+ });
8
+ function clone(value) {
9
+ return JSON.parse(JSON.stringify(value));
10
+ }
11
+ /**
12
+ * Builds the low-level DIDComm-style batch payload that carries one FHIR-like
13
+ * `Communication` resource authored from canonical communication claims.
14
+ *
15
+ * This helper intentionally stays below actor-specific SDK facades so frontend,
16
+ * BFF, and GW-like tests can reuse the same wrapping contract.
17
+ */
18
+ export function buildDidcommPayloadFromCommunicationClaims(input) {
19
+ const claims = clone(input.communicationClaims);
20
+ const transformed = transformCommunicationClaimsToResourceFhirR4([claims], {
21
+ mode: 'strict',
22
+ });
23
+ const communicationResource = transformed.resources[0] || {};
24
+ return {
25
+ iss: String(input.iss || '').trim(),
26
+ aud: String(input.aud || '').trim(),
27
+ jti: String(input.jti || '').trim(),
28
+ thid: String(input.thid || '').trim(),
29
+ type: CommunicationDidcommEntryTypes.AttachedBundle,
30
+ body: {
31
+ data: [
32
+ {
33
+ id: String(claims[CommunicationClaim.Identifier] || input.jti || '').trim(),
34
+ type: String(input.entryType || CommunicationDidcommEntryTypes.AttachedBundle).trim(),
35
+ meta: {
36
+ claims,
37
+ },
38
+ resource: communicationResource,
39
+ },
40
+ ],
41
+ },
42
+ };
43
+ }
44
+ /**
45
+ * Reads canonical communication claims from the first `body.data[]` entry of
46
+ * one DIDComm-style payload.
47
+ */
48
+ export function getFirstCommunicationClaimsFromDidcommPayload(payload) {
49
+ return getCommunicationClaimsListFromDidcommPayload(payload)[0] || {};
50
+ }
51
+ /**
52
+ * Reads canonical communication claims from every `body.data[]` entry of one
53
+ * DIDComm-style payload.
54
+ */
55
+ export function getCommunicationClaimsListFromDidcommPayload(payload) {
56
+ const entries = Array.isArray(payload?.body?.data) ? payload.body.data : [];
57
+ return entries.map((first) => {
58
+ const metaClaims = first?.meta && typeof first.meta === 'object'
59
+ ? first.meta['claims']
60
+ : undefined;
61
+ if (metaClaims && typeof metaClaims === 'object') {
62
+ return clone(metaClaims);
63
+ }
64
+ const resource = first?.resource && typeof first.resource === 'object'
65
+ ? first.resource
66
+ : {};
67
+ const meta = resource.meta && typeof resource.meta === 'object'
68
+ ? resource.meta
69
+ : {};
70
+ const claims = meta.claims && typeof meta.claims === 'object'
71
+ ? meta.claims
72
+ : {};
73
+ return clone(claims);
74
+ });
75
+ }
76
+ /**
77
+ * Decodes the attached bundle carried in `Communication.content-attachment-data`.
78
+ */
79
+ export function decodeAttachedBundleFromCommunicationClaims(communicationClaims) {
80
+ const encoded = String(communicationClaims[CommunicationClaim.ContentAttachmentData] || '').trim();
81
+ if (!encoded) {
82
+ throw new Error(`decodeAttachedBundleFromCommunicationClaims requires ${CommunicationClaim.ContentAttachmentData}.`);
83
+ }
84
+ return JSON.parse(Buffer.from(encoded, 'base64').toString('utf8'));
85
+ }
@@ -25,6 +25,18 @@ export type BuildDocumentReferenceResult = {
25
25
  evidence: EvidenceObjectDLT[];
26
26
  warnings: string[];
27
27
  };
28
+ export type BlockchainArtifactDocumentReferenceInput = Readonly<{
29
+ subject: string;
30
+ resource?: Record<string, unknown>;
31
+ contentDataBase64?: string;
32
+ contentType?: string;
33
+ identifier?: string;
34
+ title?: string;
35
+ description?: string;
36
+ date?: string;
37
+ location?: string;
38
+ language?: string;
39
+ }>;
28
40
  /**
29
41
  * Detects the logical attachment kind from a MIME type.
30
42
  *
@@ -39,3 +51,14 @@ export declare function detectAttachmentKind(contentType?: string): AttachmentKi
39
51
  * @param options.mode `strict` throws on invalid input, `normalize` applies best-effort defaults.
40
52
  */
41
53
  export declare function buildDocumentReferenceFromCommunicationPayload(communication: Record<string, any>, options?: BuildDocumentReferenceOptions): BuildDocumentReferenceResult;
54
+ /**
55
+ * Builds a blockchain-ready `DocumentReference` projection from either a FHIR
56
+ * resource or already-encoded attachment bytes.
57
+ *
58
+ * The resulting projection keeps two identifiers distinct:
59
+ * - `contentCid`: canonical content address used for blockchain registration
60
+ * - `documentReference.identifier`: optional business identifier supplied by the caller
61
+ *
62
+ * @param input Source artifact data to wrap.
63
+ */
64
+ export declare function buildBlockchainArtifactDocumentReference(input: BlockchainArtifactDocumentReferenceInput): BuildDocumentReferenceResult;
@@ -38,6 +38,9 @@ function cidFromBytes(bytes) {
38
38
  function decodeBase64(data) {
39
39
  return Uint8Array.from(Buffer.from(data, 'base64'));
40
40
  }
41
+ function encodeBase64Utf8(data) {
42
+ return Buffer.from(data, 'utf8').toString('base64');
43
+ }
41
44
  function toStringOrUndefined(value) {
42
45
  if (value === undefined || value === null)
43
46
  return undefined;
@@ -168,3 +171,89 @@ export function buildDocumentReferenceFromCommunicationPayload(communication, op
168
171
  warnings,
169
172
  };
170
173
  }
174
+ /**
175
+ * Builds a blockchain-ready `DocumentReference` projection from either a FHIR
176
+ * resource or already-encoded attachment bytes.
177
+ *
178
+ * The resulting projection keeps two identifiers distinct:
179
+ * - `contentCid`: canonical content address used for blockchain registration
180
+ * - `documentReference.identifier`: optional business identifier supplied by the caller
181
+ *
182
+ * @param input Source artifact data to wrap.
183
+ */
184
+ export function buildBlockchainArtifactDocumentReference(input) {
185
+ const subject = toStringOrUndefined(input.subject);
186
+ if (!subject) {
187
+ throw new Error('buildBlockchainArtifactDocumentReference requires subject.');
188
+ }
189
+ const resource = input.resource;
190
+ const hasResource = !!resource && typeof resource === 'object' && !Array.isArray(resource);
191
+ const contentType = toStringOrUndefined(input.contentType) || (hasResource ? 'application/fhir+json' : 'application/octet-stream');
192
+ const title = toStringOrUndefined(input.title) || (hasResource
193
+ ? `${String(resource.resourceType || 'resource').toLowerCase()}.json`
194
+ : 'artifact.bin');
195
+ let contentDataBase64 = toStringOrUndefined(input.contentDataBase64);
196
+ let contentCid;
197
+ let communicationLike;
198
+ if (hasResource) {
199
+ const serialized = JSON.stringify(resource);
200
+ contentDataBase64 = encodeBase64Utf8(serialized);
201
+ contentCid = fhirResourceToCid(resource).cid;
202
+ communicationLike = {
203
+ resourceType: 'Communication',
204
+ meta: { claims: { [CommunicationClaim.Subject]: subject } },
205
+ payload: [{ contentAttachment: { contentType, data: contentDataBase64, title } }],
206
+ };
207
+ }
208
+ else {
209
+ if (!contentDataBase64) {
210
+ throw new Error('buildBlockchainArtifactDocumentReference requires contentDataBase64 when resource is absent.');
211
+ }
212
+ contentCid = cidFromBytes(decodeBase64(contentDataBase64));
213
+ communicationLike = {
214
+ resourceType: 'Communication',
215
+ meta: { claims: { [CommunicationClaim.Subject]: subject } },
216
+ payload: [{ contentAttachment: { contentType, data: contentDataBase64, title, url: input.location } }],
217
+ };
218
+ }
219
+ const result = buildDocumentReferenceFromCommunicationPayload(communicationLike, { mode: 'strict' });
220
+ const logicalIdentifier = toStringOrUndefined(input.identifier) || contentCid;
221
+ const documentReference = {
222
+ ...result.documentReference,
223
+ identifier: logicalIdentifier ? [{ value: logicalIdentifier }] : undefined,
224
+ description: toStringOrUndefined(input.description) || result.documentReference.description,
225
+ date: toStringOrUndefined(input.date) || result.documentReference.date,
226
+ content: [{
227
+ attachment: {
228
+ ...(result.documentReference.content?.[0]?.attachment || {}),
229
+ contentType,
230
+ data: contentDataBase64,
231
+ url: toStringOrUndefined(input.location) || result.documentReference.content?.[0]?.attachment?.url,
232
+ title,
233
+ language: toStringOrUndefined(input.language) || result.documentReference.content?.[0]?.attachment?.language,
234
+ hash: contentCid,
235
+ },
236
+ }],
237
+ meta: {
238
+ ...(result.documentReference.meta || {}),
239
+ versionId: contentCid,
240
+ claims: {
241
+ ...((result.documentReference.meta || {}).claims || {}),
242
+ [DocumentReferenceClaim.Identifier]: logicalIdentifier,
243
+ [DocumentReferenceClaim.ContentHash]: contentCid,
244
+ [DocumentReferenceClaim.ContentData]: contentDataBase64,
245
+ [DocumentReferenceClaim.ContentType]: contentType,
246
+ [DocumentReferenceClaim.Subject]: subject,
247
+ ...(toStringOrUndefined(input.description) ? { [DocumentReferenceClaim.Description]: input.description } : {}),
248
+ ...(toStringOrUndefined(input.date) ? { [DocumentReferenceClaim.Date]: input.date } : {}),
249
+ ...(toStringOrUndefined(input.location) ? { [DocumentReferenceClaim.Location]: input.location } : {}),
250
+ ...(toStringOrUndefined(input.language) ? { [DocumentReferenceClaim.Language]: input.language } : {}),
251
+ },
252
+ },
253
+ };
254
+ return {
255
+ ...result,
256
+ contentCid,
257
+ documentReference,
258
+ };
259
+ }
@@ -0,0 +1,53 @@
1
+ import type { BundleEntry, BundleJsonApi } from '../models/bundle';
2
+ import type { BundleResourceIdFilters } from './bundle-query';
3
+ import { type CommunicationAttachedBundleSessionMode } from '../models/communication-attached-bundle-session';
4
+ import { BundleReader } from './bundle-reader';
5
+ import { CommunicationAttachedBundleSession } from './communication-attached-bundle-session';
6
+ import type { IDecodedDidcommPayload } from '../models/confidential-message';
7
+ export type CommunicationEditorOptions = Readonly<{
8
+ initialBundle?: BundleJsonApi<BundleEntry>;
9
+ mode?: CommunicationAttachedBundleSessionMode;
10
+ communicationClaims?: Record<string, unknown>;
11
+ }>;
12
+ /**
13
+ * Public high-level editor for one delivery `Communication`.
14
+ *
15
+ * Teaching contract:
16
+ * - use this name in tutorials when the caller is authoring one outer
17
+ * `Communication`
18
+ * - keep `CommunicationAttachedBundleSession` as the lower-level compatibility
19
+ * implementation detail underneath
20
+ */
21
+ export declare class CommunicationEditor extends CommunicationAttachedBundleSession {
22
+ constructor(options?: CommunicationEditorOptions);
23
+ /** Materializes one immutable snapshot of the current Communication claims. */
24
+ done(): Record<string, unknown>;
25
+ /** Returns one reader over the current Communication snapshot. */
26
+ toReader(): CommunicationReader;
27
+ }
28
+ /**
29
+ * Public high-level reader for one delivery `Communication`.
30
+ */
31
+ export declare class CommunicationReader {
32
+ private readonly session;
33
+ constructor(communicationClaims: Record<string, unknown>);
34
+ /** Reads the first delivery `Communication` carried in one DIDComm/plain payload. */
35
+ static fromDidcommPayload(payload: IDecodedDidcommPayload): CommunicationReader;
36
+ /** Reads every delivery `Communication` carried in one DIDComm/plain payload. */
37
+ static listFromDidcommPayload(payload: IDecodedDidcommPayload): CommunicationReader[];
38
+ getCommunicationClaims(): Record<string, unknown>;
39
+ getCommunicationIdentifier(): string;
40
+ getCommunicationSubject(): string;
41
+ getCommunicationCategoryList(): string[];
42
+ getCommunicationTopic(): string;
43
+ getCommunicationText(): string;
44
+ getAttachmentContentType(): string;
45
+ getAttachmentTitle(): string;
46
+ getAttachmentUrl(): string;
47
+ getAttachmentDataBase64(): string;
48
+ getAttachedBundle(): BundleJsonApi<BundleEntry>;
49
+ getAttachedBundleReader(): BundleReader;
50
+ getAttachedBundleResourceIds(filters?: BundleResourceIdFilters): string[];
51
+ getAttachedBundleEntriesByIds(resourceIds: readonly string[]): BundleEntry[];
52
+ getAttachedBundleEntryUrl(resourceId: string): string | undefined;
53
+ }