gdc-common-utils-ts 1.0.1

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 (100) hide show
  1. package/PUBLISHING.md +33 -0
  2. package/__tests__/AesManager.test.ts +53 -0
  3. package/__tests__/CryptographyService.test.ts +194 -0
  4. package/__tests__/bundle.test.ts +29 -0
  5. package/__tests__/content.test.ts +72 -0
  6. package/__tests__/crypto-encode-decode.test.ts +52 -0
  7. package/__tests__/crypto-hmac.test.ts +21 -0
  8. package/__tests__/did-generateServiceId.errors.test.ts +8 -0
  9. package/__tests__/did-generateServiceId.test.ts +18 -0
  10. package/__tests__/models-clinical-sections.test.ts +32 -0
  11. package/__tests__/models-multibase58.test.ts +33 -0
  12. package/__tests__/multibase58.errors.test.ts +7 -0
  13. package/__tests__/multibase58.test.ts +28 -0
  14. package/__tests__/multibasehash.test.ts +25 -0
  15. package/__tests__/utils-actor.test.ts +22 -0
  16. package/__tests__/utils-base-convert.test.ts +57 -0
  17. package/__tests__/utils-baseN.test.ts +40 -0
  18. package/__tests__/utils-did-extra.test.ts +33 -0
  19. package/__tests__/utils-format-converter.test.ts +87 -0
  20. package/__tests__/utils-jwt.test.ts +57 -0
  21. package/__tests__/utils-manager-error.test.ts +11 -0
  22. package/__tests__/utils-normalize.test.ts +15 -0
  23. package/__tests__/utils-object-convert.test.ts +38 -0
  24. package/__tests__/utils-string-convert.test.ts +20 -0
  25. package/__tests__/utils-string-utils.test.ts +25 -0
  26. package/__tests__/utils-url.test.ts +21 -0
  27. package/babel.config.cjs +5 -0
  28. package/jest.config.ts +46 -0
  29. package/package.json +36 -0
  30. package/src/AesManager.ts +82 -0
  31. package/src/CryptographyService.ts +461 -0
  32. package/src/JweManager.ts.txt +365 -0
  33. package/src/KmsService.txt +493 -0
  34. package/src/constants/Schemas.ts +61 -0
  35. package/src/constants/index.ts +1 -0
  36. package/src/constants/schemaorg.ts +193 -0
  37. package/src/cryptoDecode.ts +104 -0
  38. package/src/cryptoEncode.ts +36 -0
  39. package/src/cryptography.abstract.ts +29 -0
  40. package/src/hmac.ts +15 -0
  41. package/src/index.ts +3 -0
  42. package/src/interfaces/Cryptography.types.ts +131 -0
  43. package/src/interfaces/ICryptoHelper.ts +33 -0
  44. package/src/interfaces/ICryptography.ts +177 -0
  45. package/src/interfaces/IWallet.ts +62 -0
  46. package/src/interfaces/MlDsa.ts +25 -0
  47. package/src/interfaces/MlKem.ts +18 -0
  48. package/src/models/aes.ts +93 -0
  49. package/src/models/auth.ts +38 -0
  50. package/src/models/bundle.ts +152 -0
  51. package/src/models/bundle.txt +93 -0
  52. package/src/models/clinical-sections.en.ts +82 -0
  53. package/src/models/clinical-sections.ts +64 -0
  54. package/src/models/comm.ts +63 -0
  55. package/src/models/confidential-job.ts +100 -0
  56. package/src/models/confidential-message.ts +137 -0
  57. package/src/models/confidential-storage.ts +170 -0
  58. package/src/models/consent-rule.ts +141 -0
  59. package/src/models/crypto.ts +43 -0
  60. package/src/models/device-license.ts +161 -0
  61. package/src/models/did.ts +81 -0
  62. package/src/models/index.ts +31 -0
  63. package/src/models/indexing.ts +20 -0
  64. package/src/models/issue.ts +85 -0
  65. package/src/models/jsonapi.ts +19 -0
  66. package/src/models/jwe.ts +132 -0
  67. package/src/models/jwk.ts +50 -0
  68. package/src/models/jws.ts +42 -0
  69. package/src/models/jwt.ts +15 -0
  70. package/src/models/multibase58.ts +46 -0
  71. package/src/models/oidc4ida.common.model.ts +39 -0
  72. package/src/models/oidc4ida.document.model.ts +61 -0
  73. package/src/models/oidc4ida.electronicRecord.model.ts +86 -0
  74. package/src/models/oidc4ida.evidence.model.ts +69 -0
  75. package/src/models/openid-device.ts +146 -0
  76. package/src/models/operation-outcome.ts +34 -0
  77. package/src/models/params.ts +142 -0
  78. package/src/models/resource-document.ts +21 -0
  79. package/src/models/response.ts +5 -0
  80. package/src/models/urlPath.ts +76 -0
  81. package/src/models/verifiable-credential.ts +52 -0
  82. package/src/types/noble-hashes.d.ts +4 -0
  83. package/src/utils/actor.ts +52 -0
  84. package/src/utils/base-convert.ts +77 -0
  85. package/src/utils/baseN.ts +203 -0
  86. package/src/utils/bundle.ts +30 -0
  87. package/src/utils/content.ts +66 -0
  88. package/src/utils/did.ts +155 -0
  89. package/src/utils/format-converter.ts +119 -0
  90. package/src/utils/index.ts +13 -0
  91. package/src/utils/jwt.ts +165 -0
  92. package/src/utils/manager-error.ts +27 -0
  93. package/src/utils/multibase58.ts +46 -0
  94. package/src/utils/multibasehash.ts +28 -0
  95. package/src/utils/normalize.ts +43 -0
  96. package/src/utils/object-convert.ts +57 -0
  97. package/src/utils/string-convert.ts +71 -0
  98. package/src/utils/string-utils.ts +70 -0
  99. package/src/utils/url.ts +46 -0
  100. package/tsconfig.json +13 -0
@@ -0,0 +1,82 @@
1
+ /**
2
+ * English display labels for supported clinical document section codes.
3
+ *
4
+ * Notes:
5
+ * - This file is intentionally separate from the section registry so apps can:
6
+ * - use these labels as a default (e.g., server-side rendering), and/or
7
+ * - override them via i18n resources keyed by `org.loinc.<CODE>`.
8
+ * - Sources: HL7 FHIR doc-section-codes + project-specific additions.
9
+ */
10
+ export const clinicalSectionTitleEn = {
11
+ // ---------------------------------------------------------------------------
12
+ // HL7 FHIR doc-section-codes (LOINC) — subset used by the platform/docs
13
+ // ---------------------------------------------------------------------------
14
+ '10154-3': 'Chief complaint Narrative - Reported',
15
+ '10157-6': 'History of family member diseases Narrative',
16
+ '10160-0': 'History of Medication use Narrative',
17
+ '10164-2': 'History of Present illness Narrative',
18
+ '10183-2': 'Hospital discharge medications Narrative',
19
+ '10184-0': 'Hospital discharge physical findings Narrative',
20
+ '10187-3': 'Review of systems Narrative - Reported',
21
+ '10210-3': 'Physical findings of General status Narrative',
22
+ '10216-0': 'Surgical operation note fluids Narrative',
23
+ '10218-6': 'Surgical operation note postoperative diagnosis Narrative',
24
+ '10222-8': 'Surgical operation note surgical complications [Interpretation] Narrative',
25
+ '10223-6': 'Surgical operation note surgical procedure Narrative',
26
+ '11329-0': 'History general Narrative - Reported',
27
+ '11348-0': 'History of Past illness Narrative',
28
+ '11369-6': 'History of Immunization Narrative',
29
+ '11493-4': 'Hospital discharge studies summary Narrative',
30
+ '11535-2': 'Hospital discharge Dx Narrative',
31
+ '11537-8': 'Surgical drains Narrative',
32
+ '18776-5': 'Plan of care note',
33
+ '18841-7': 'Hospital consultations Document',
34
+ '29299-5': 'Reason for visit Narrative',
35
+ '29545-1': 'Physical findings Narrative',
36
+ '29549-3': 'Medication administered Narrative',
37
+ '29554-3': 'Procedure Narrative',
38
+ '29762-2': 'Social history Narrative',
39
+ '30954-2': 'Relevant diagnostic tests/laboratory data Narrative',
40
+ '42344-2': 'Discharge diet (narrative)',
41
+ '42346-7': 'Medications on admission (narrative)',
42
+ '42348-3': 'Advance directives',
43
+ '42349-1': 'Reason for referral (narrative)',
44
+ '46240-8': 'History of Hospitalizations+Outpatient visits Narrative',
45
+ '46241-6': 'Hospital admission diagnosis Narrative - Reported',
46
+ '46264-8': 'History of medical device use',
47
+ '47420-5': 'Functional status assessment note',
48
+ '47519-4': 'History of Procedures Document',
49
+ '48765-2': 'Allergies and adverse reactions Document',
50
+ '48768-6': 'Payment sources Document',
51
+ '51848-0': 'Evaluation note',
52
+ '55109-3': 'Complications Document',
53
+ '55122-6': 'Surgical operation note implants Narrative',
54
+ '57852-6': 'Problem list Narrative - Reported',
55
+ '59768-2': 'Procedure indications [Interpretation] Narrative',
56
+ '59769-0': 'Postprocedure diagnosis Narrative',
57
+ '59770-8': 'Procedure estimated blood loss Narrative',
58
+ '59771-6': 'Procedure implants Narrative',
59
+ '59772-4': 'Planned procedure Narrative',
60
+ '59773-2': 'Procedure specimens taken Narrative',
61
+ '59775-7': 'Procedure disposition Narrative',
62
+ '59776-5': 'Procedure findings Narrative',
63
+ '61149-1': 'Objective Narrative',
64
+ '61150-9': 'Subjective Narrative',
65
+ '69730-0': 'Instructions',
66
+ '8648-8': 'Hospital course Narrative',
67
+ '8653-8': 'Hospital Discharge instructions',
68
+ '8716-3': 'Vital signs',
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // Project additions (not part of doc-section-codes, but used by clients)
72
+ // ---------------------------------------------------------------------------
73
+ '60591-5': 'Patient summary',
74
+ '11450-4': 'Problem list',
75
+ '61144-2': 'Diet',
76
+ '82810-3': 'History of pregnancy',
77
+ '87520-3': 'Health insurance coverage',
78
+ '10190-7': 'Mental status',
79
+ '18726-0': 'Radiology studies',
80
+ '11503-0': 'Medical records (generic)',
81
+ '56796-6': 'Healthcare (general)',
82
+ } as const;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Canonical registry of supported clinical document sections (e.g., IPS Composition sections).
3
+ *
4
+ * Design goals:
5
+ * - Use stable codes (LOINC) for interoperability.
6
+ * - Provide a reverse-DNS i18n key for consistent UI translations across apps.
7
+ * - Keep this in `gdc-common-utils-ts` so both backend and frontend can share it.
8
+ */
9
+
10
+ import { clinicalSectionTitleEn } from './clinical-sections.en';
11
+
12
+ export const LOINC_SYSTEM_URL = 'http://loinc.org' as const;
13
+ export const LOINC_SYSTEM_REVERSE_DNS = 'org.loinc' as const;
14
+
15
+ export type ClinicalSectionDescriptor = {
16
+ /** Canonical coding system URL (FHIR-style). */
17
+ system: string;
18
+ /** Code within the coding system (e.g., a LOINC code). */
19
+ code: string;
20
+ /**
21
+ * Reverse-DNS translation key, intended for i18n resources.
22
+ * Example: `org.loinc.48765-2`.
23
+ */
24
+ i18nKey: string;
25
+ /**
26
+ * English fallback label (documentation/UI fallback).
27
+ *
28
+ * Prefer rendering a UI label via `i18nKey` (e.g., `org.loinc.<CODE>`) rather than relying on this.
29
+ */
30
+ titleEn?: string;
31
+ /** True when this is an IPS-aligned section code. */
32
+ ips?: boolean;
33
+ };
34
+
35
+ export function loincI18nKey(code: string): string {
36
+ return `${LOINC_SYSTEM_REVERSE_DNS}.${code}`;
37
+ }
38
+
39
+ export type SupportedClinicalSectionCode = keyof typeof clinicalSectionTitleEn;
40
+
41
+ export const supportedClinicalSectionCodes = Object.freeze(
42
+ Object.keys(clinicalSectionTitleEn) as SupportedClinicalSectionCode[]
43
+ );
44
+
45
+ export const clinicalSectionRegistry: Readonly<Record<string, ClinicalSectionDescriptor>> = (() => {
46
+ const entries = Object.entries(clinicalSectionTitleEn).map(([code, titleEn]) => {
47
+ const descriptor: ClinicalSectionDescriptor = {
48
+ system: LOINC_SYSTEM_URL,
49
+ code,
50
+ i18nKey: loincI18nKey(code),
51
+ titleEn,
52
+ ips: true,
53
+ };
54
+ return [code, descriptor] as const;
55
+ });
56
+
57
+ return Object.freeze(Object.fromEntries(entries));
58
+ })();
59
+
60
+ export { clinicalSectionTitleEn };
61
+
62
+ export function getClinicalSectionByCode(code: string): ClinicalSectionDescriptor | undefined {
63
+ return clinicalSectionRegistry[code];
64
+ }
@@ -0,0 +1,63 @@
1
+ // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ // File: src/models/comm.ts
3
+ // Description: Defines the core communication and data structures based on DIDComm and FHIR.
4
+
5
+ /**
6
+ * Represents the standard payload of a DIDComm v2 message.
7
+ * @see https://identity.foundation/didcomm-messaging/spec/v2.0/#plaintext-message-structure
8
+ */
9
+ export interface DidCommPayload {
10
+ id: string; // Message ID, required.
11
+ type: string; // Message Type URI, required.
12
+ from?: string; // Sender DID
13
+ to?: string[]; // Recipient DIDs
14
+ thid?: string; // Thread ID
15
+ pthid?: string; // Parent Thread ID
16
+ created_time?: number;
17
+ expires_time?: number;
18
+ body: { [key: string]: any };
19
+ }
20
+
21
+ /**
22
+ * Represents a data entry in the `body` of a CommMsgExtended,
23
+ * following a hybrid JSON:API and FHIR structure.
24
+ */
25
+ export interface DataEntry {
26
+ id: string;
27
+ type: 'Annotation' | 'Reference' | 'Attachment' | 'CodeableConcept' | string;
28
+ resource: { [key: string]: any };
29
+ meta?: {
30
+ claims: any;
31
+ }
32
+ }
33
+
34
+ /**
35
+ * The canonical, internal representation of a secure message, extending
36
+ * the standard DIDComm payload with FHIR-specific, flattened metadata.
37
+ */
38
+ export interface CommMsgExtended extends DidCommPayload {
39
+ // Overriding body for a more specific structure
40
+ body: {
41
+ data: DataEntry[];
42
+ };
43
+
44
+ // FHIR Communication resource fields, flattened for use as metadata or search parameters.
45
+ // These are derived from the source FHIR resource during conversion.
46
+
47
+ // 'status'?: string; // e.g., 'completed', 'in-progress'
48
+ // 'statusReason'?: string; // Flattened from CodeableConcept
49
+ // 'partOf'?: string; // Comma-separated list of URNs/URLs
50
+ // 'basedOn'?: string; // Comma-separated list of URNs/URLs
51
+ // 'inResponseTo'?: string; // Comma-separated list of URNs/URLs
52
+ // 'priority'?: string; // e.g., 'routine', 'urgent'
53
+ // 'topic'?: string; // Flattened from CodeableConcept
54
+ // 'medium'?: string; // Flattened from CodeableConcept
55
+ // 'about'?: string; // Comma-separated list of URNs/URLs
56
+ // 'encounter'?: string; // URN or URL
57
+ }
58
+
59
+ /**
60
+ * A type placeholder for a FHIR Communication resource.
61
+ */
62
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
+ export type FhirCommunication = any;
@@ -0,0 +1,100 @@
1
+ // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ // File: crypto-ts/models/confidential-job.ts
3
+
4
+ /**
5
+ * @file This file contains the core data models for the job processing system.
6
+ * These models are platform-agnostic and are part of the core SDK.
7
+ * @sdk
8
+ */
9
+
10
+ import { IDecodedDidcommPayload as DecodedDidcommPayload } from "./confidential-message";
11
+ import { ConfidentialStorageDoc, IndexedData } from "./confidential-storage";
12
+ import { ServiceEndpointSelector } from "./did";
13
+
14
+ /** When the organization has its own domain for the connector do not appear in the path:
15
+ * - the tenantId and jurisdiction, and
16
+ * - the apiVersion and sector;
17
+ */
18
+ export interface JobRequestInfo extends ServiceEndpointSelector {
19
+ /** When the organization has its own domain for the connector the tenantId and jurisdiction do not appear in the path */
20
+ tenantId?: string;
21
+ jurisdiction?: string;
22
+ /** The Unix epoch timestamp (in milliseconds) of when the job record was created. */
23
+ createdAtTimestamp: number;
24
+ requestUrl?: string;
25
+ httpMethod?: string;
26
+ contentType?: string;
27
+ language?: string;
28
+ }
29
+
30
+ /**
31
+ * Defines the possible statuses of a job throughout its lifecycle.
32
+ */
33
+ export enum JobStatus {
34
+ /** The job has been created locally but not yet submitted. */
35
+ DRAFT = 'DRAFT',
36
+ /** The job is in the process of being submitted to the server. */
37
+ SUBMITTING = 'SUBMITTING',
38
+ /** The job was successfully submitted and is awaiting asynchronous processing. */
39
+ SENT = 'SENT',
40
+ /** The server has finished processing the job and returned a final result. This is a terminal state. */
41
+ COMPLETED = 'COMPLETED',
42
+ /** The job failed due to a transport-level error and will not be retried. This is a terminal state. */
43
+ FAILED = 'FAILED',
44
+ /** The job failed due to a transient error and may be retried. */
45
+ ERROR_RETRYABLE = 'ERROR_RETRYABLE',
46
+ }
47
+
48
+ /**
49
+ * Represents the entire data package for a single job ready for processing.
50
+ * It combines the HTTP request context with the unprotected message and its security context.
51
+ * The hosted URL has this structure: `https://<host-domain>/:tenantId/cds-:jurisdiction/v1/:sector/:section/:format/:resourceType/:action`
52
+ * The external URL has this structure: `https://<organization-domain>/:section/:format/:resourceType/:action`
53
+ */
54
+ export interface JobRequest extends ConfidentialStorageDoc, JobRequestInfo {
55
+ // 'id' serves as the primary key in the vault.
56
+ id: string;
57
+ /**
58
+ * DIDComm thread ID for correlating async jobs.
59
+ * Stored outside encrypted `content` so UIs can query jobs by thread without decrypting.
60
+ */
61
+ thid?: string;
62
+ status: JobStatus;
63
+ versionId?: string;
64
+ vaultId?: string;
65
+ chunks?: number;
66
+
67
+ // From ConfidentialStorageDoc
68
+
69
+ /** A number that MUST be incremented each time the document is updated. */
70
+ sequence: number;
71
+
72
+ /** Previous sequence being replaced by the update */
73
+ previousSequence?: number;
74
+
75
+ /** Contains an array of indexed attributes protected with HMAC for blind queries. */
76
+ indexed?: IndexedData;
77
+
78
+ /** The decoded DIDComm message. Present when the job is unprotected. */
79
+ content?: DecodedDidcommPayload;
80
+
81
+ /** The JWE representation of the encrypted content. Present when the job is protected. */
82
+ jwe?: Record<string, any>;
83
+
84
+ // Additional information for job processing
85
+
86
+ /** Addtional information from HTTP header */
87
+ onBehalfOf?: string;
88
+
89
+ /** The URL provided by the server to poll for the job's status. */
90
+ locationUrl?: string;
91
+
92
+ /** A counter for the number of retry attempts. */
93
+ retryCount?: number;
94
+
95
+ /** The ID of the corresponding response message stored in the vault, once the job is COMPLETED. */
96
+ responseMessageId?: string;
97
+
98
+ /** CAUTION: Only for debugging purposes. It is the last error message, o*/
99
+ errorMessage?: string;
100
+ }
@@ -0,0 +1,137 @@
1
+ // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ // File: crypto-ts/models/confidential-message.ts
3
+ // Description: Defines the core communication and data structures based on DIDComm and FHIR.
4
+
5
+ import { ProtectedHeadersJWE } from "./jwe";
6
+ import { JwsHeader } from "./jws";
7
+
8
+ export type { DataEntry } from "./comm";
9
+
10
+ /**
11
+ * Defines the structure of the cryptographic metadata associated with a job request.
12
+ */
13
+ export interface DidCommDecodedMetadata {
14
+ jws?: {
15
+ protected?: JwsHeader;
16
+ /** Detached signature of the request JWS (when available). */
17
+ signature?: string;
18
+ };
19
+ jwe?: {
20
+ header?: ProtectedHeadersJWE;
21
+ };
22
+ bearer?: {
23
+ compact?: string,
24
+ jwt: {
25
+ header?: JwsHeader;
26
+ payload?: Record<string, any>;
27
+ };
28
+ };
29
+ }
30
+
31
+ /**
32
+ * Represents the standard payload of a DIDComm v2 message.
33
+ * @see https://identity.foundation/didcomm-messaging/spec/v2.0/#plaintext-message-structure
34
+ */
35
+ /**
36
+ * Represents the plaintext of a decoded DIDComm message.
37
+ * This is the core business-level "input" for a job.
38
+ * For FAPI compliance, this entire object is typically the payload of a signed JWS.
39
+ */
40
+ export interface IDecodedDidcommPayload {
41
+
42
+ /** Relevant information available through the decryption and verification process */
43
+ meta?: DidCommDecodedMetadata;
44
+
45
+ // --- FAPI & JWT Core Claims ---
46
+
47
+ /**
48
+ * (Issuer) The DID of the entity that issued the message.
49
+ * REQUIRED for FAPI. MUST match the signer of the enclosing JWS.
50
+ */
51
+ iss: string;
52
+
53
+ /**
54
+ * (Audience) The URL of the backend endpoint that will process this message.
55
+ * REQUIRED for FAPI. The backend MUST validate that this value matches its own URL.
56
+ */
57
+ aud: string;
58
+
59
+ /** (Expiration Time) Timestamp after which the message is considered invalid. REQUIRED for FAPI (instead of expires_time). */
60
+ exp?: number;
61
+
62
+ /** (Not Before) Timestamp before which the message must not be processed. REQUIRED for FAPI (instead of created_time). */
63
+ nbf?: number;
64
+
65
+ /** (Issued At) Timestamp when the message was issued. REQUIRED for FAPI. */
66
+ iat?: number;
67
+
68
+ /**
69
+ * (JWT ID) A unique identifier for this message/token. Can be used to prevent replay attacks.
70
+ * In our architecture, this can also serve as the version hash of the data content.
71
+ */
72
+ jti: string;
73
+
74
+ // --- DIDComm Core Fields ---
75
+
76
+ /** Optional. The `jti` identifies both the message and job for processing */
77
+ id?: string;
78
+
79
+ /** The Transaction ID / Thread ID for message correlation across an interaction. */
80
+ thid: string;
81
+
82
+ /** Parent Thread ID */
83
+ pthid?: string;
84
+
85
+ /** The DID of the intended recipient. Used for P2P messaging, informational in client-server requests. */
86
+ to?: string[];
87
+
88
+ /** The DID of the sender. Used for P2P messaging, but `iss` is the authoritative value for FAPI. */
89
+ from?: string;
90
+
91
+ /**
92
+ * The Message Type URI, identifying the type of data in the body or protocol used.
93
+ * (e.g. 'application/json')
94
+ */
95
+ type: string;
96
+
97
+ /** The main business payload of the message. The structure is defined by the 'type' protocol. */
98
+ body: any;
99
+ }
100
+
101
+ /**
102
+ * Represents a data entry in the `body` of a CommMsgExtended,
103
+ * following a hybrid JSON:API and FHIR structure.
104
+ */
105
+ export interface CommDataEntry {
106
+ id: string;
107
+ type: 'Annotation' | 'Reference' | 'Attachment' | 'CodeableConcept' | string;
108
+ resource: { [key: string]: any };
109
+ meta?: {
110
+ claims: any;
111
+ }
112
+ }
113
+
114
+ /**
115
+ * The canonical, internal representation of a secure message, extending
116
+ * the standard DIDComm payload with FHIR-specific, flattened metadata.
117
+ */
118
+ export interface ICommPayloadExtended extends IDecodedDidcommPayload {
119
+ // Overriding body for a more specific structure
120
+ body: {
121
+ data: CommDataEntry[];
122
+ };
123
+
124
+ // FHIR Communication resource fields, flattened for use as metadata or search parameters.
125
+ // These are derived from the source FHIR resource during conversion.
126
+
127
+ // 'status'?: string; // e.g., 'completed', 'in-progress'
128
+ // 'statusReason'?: string; // Flattened from CodeableConcept
129
+ // 'partOf'?: string; // Comma-separated list of URNs/URLs
130
+ // 'basedOn'?: string; // Comma-separated list of URNs/URLs
131
+ // 'inResponseTo'?: string; // Comma-separated list of URNs/URLs
132
+ // 'priority'?: string; // e.g., 'routine', 'urgent'
133
+ // 'topic'?: string; // Flattened from CodeableConcept
134
+ // 'medium'?: string; // Flattened from CodeableConcept
135
+ // 'about'?: string; // Comma-separated list of URNs/URLs
136
+ // 'encounter'?: string; // URN or URL
137
+ }
@@ -0,0 +1,170 @@
1
+ // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ // File: gdc-common-utils-ts/src/models/confidential-storage.ts
3
+
4
+ import { ParameterType } from './params';
5
+
6
+ /**
7
+ * FHIR `Coding`-like tag used for research/analytics metadata.
8
+ * Keep values coarse and coded; avoid free text in `display` unless explicitly policy-approved.
9
+ */
10
+ export interface MetaTagCoding {
11
+ system?: string;
12
+ code?: string;
13
+ version?: string;
14
+ display?: string;
15
+ userSelected?: boolean;
16
+ }
17
+
18
+ /**
19
+ * Research/analytics metadata kept outside encrypted `content`.
20
+ * Policy-dependent: treat these fields as potentially sensitive.
21
+ */
22
+ export interface ResearchInfo {
23
+ /** Coarse jurisdiction identifier (e.g., "cds-es" or "ES"). */
24
+ jurisdiction?: string;
25
+ /** Year of birth (YYYY). */
26
+ yearOfBirth?: string;
27
+ /** Gender identity (user-identified). Keep coded and coarse. */
28
+ gender?: string;
29
+ /** Sex assigned at birth (if collected). Keep coded and coarse. */
30
+ sexAtBirth?: string;
31
+ }
32
+
33
+ /**
34
+ * Audit metadata for traceability.
35
+ *
36
+ * Values are set by the software (off-ledger) and/or by an external attestation layer (on-ledger).
37
+ * This object is intentionally separate from:
38
+ * - `research` (analytics metadata)
39
+ * - any `meta` object inside encrypted `content` (e.g., entry `meta.claims`)
40
+ */
41
+ export interface AuditInfo {
42
+ /** When the document was first created off-ledger (ISO 8601). */
43
+ created?: string;
44
+ /** When the document was last updated off-ledger (ISO 8601). */
45
+ updated?: string;
46
+ /** True if removed/deactivated (deactivation time is typically `updated`). */
47
+ deactivated?: boolean;
48
+ /** Name of the channel/network where the data is audited/anchored. */
49
+ channel?: string;
50
+ /** Base58/Base64Url transaction identifier, depending on the attestation layer. */
51
+ txId?: string;
52
+ /** Transaction timestamp (ISO 8601). */
53
+ txTime?: string;
54
+ }
55
+
56
+ /**
57
+ * Defines the structure of an attribute to be indexed for blind, searchable queries.
58
+ * @see https://identity.foundation/confidential-storage/#indexed-attributes
59
+ */
60
+ export interface IndexedAttribute {
61
+ name: string;
62
+ value: string;
63
+ unique?: boolean;
64
+ /**
65
+ * The original data type of the `value` before it was converted to a string
66
+ * for HMAC protection. This is essential for performing type-aware queries
67
+ * (e.g., numerical range queries) on the indexed data.
68
+ * If not present, the type is assumed to be 'string'.
69
+ */
70
+ type?: ParameterType | string;
71
+ }
72
+
73
+ /**
74
+ * Defines an indexed portion of a confidential document, allowing specific attributes to be searchable.
75
+ */
76
+ export interface IndexedData {
77
+ attributes: IndexedAttribute[];
78
+ hmac?: {
79
+ id: string;
80
+ type: string;
81
+ };
82
+ sequence?: number;
83
+ }
84
+
85
+ /**
86
+ * Represents a complete Structured Document as defined by the Confidential Storage specification.
87
+ * This is the canonical format for all documents persisted in a vault.
88
+ * @see https://identity.foundation/confidential-storage/#structureddocument
89
+ */
90
+ export interface ConfidentialStorageDoc {
91
+ // 'id' is inherited from RecordBase
92
+ id: string;
93
+ status: string;
94
+ /**
95
+ * Optional content-derived version identifier.
96
+ *
97
+ * Recommended usage:
98
+ * - set to a deterministic content hash of the canonicalized artifact/claims (e.g., multihash over JCS bytes),
99
+ * so each semantic update yields a new `versionId`.
100
+ * - do NOT use this for blockchain transaction identifiers (use `audit.txId` / `audit.txTime` instead).
101
+ */
102
+ versionId?: string;
103
+ vaultId?: string;
104
+ chunks?: number;
105
+
106
+ /** A number that MUST be incremented each time the document is updated. */
107
+ sequence: number;
108
+
109
+ /** Contains an array of indexed attributes protected with HMAC for blind queries. */
110
+ indexed?: IndexedData;
111
+
112
+ /** The main, potentially encrypted, content of the document. */
113
+ content?: Record<string, any>;
114
+
115
+ /** The JWE representation of the encrypted content. It could be a URL in case of a bucket is used to store the JWE or chunks */
116
+ jwe?: Record<string, any>;
117
+
118
+ /**
119
+ * Document-level created timestamp (outside encrypted `content`).
120
+ * This is distinct from any `meta` objects inside `content` (e.g., entry meta.claims).
121
+ */
122
+ audit?: AuditInfo;
123
+
124
+ /**
125
+ * @deprecated Use `audit.created` instead.
126
+ */
127
+ created?: string;
128
+
129
+ /**
130
+ * Document-level content type label (outside encrypted `content`).
131
+ * This is distinct from any `contentType` claims inside `content`.
132
+ */
133
+ contentType?: string;
134
+
135
+ /**
136
+ * Optional research/routing tags kept outside encrypted `content`.
137
+ * These tags are intended for analytics/routing and may be mirrored back to API responses.
138
+ * Avoid free text in `display` unless explicitly policy-approved.
139
+ */
140
+ tag?: MetaTagCoding[];
141
+
142
+ /** Policy-dependent research/analytics metadata, kept outside encrypted `content`. */
143
+ research?: ResearchInfo;
144
+
145
+ /**
146
+ * @deprecated Use `created`, `contentType`, and `research` instead.
147
+ * This legacy field is kept for backwards compatibility with older stored documents.
148
+ */
149
+ meta?: {
150
+ created?: string;
151
+ contentType?: string;
152
+ chunks?: number;
153
+ jurisdiction?: string;
154
+ yearOfBirth?: string;
155
+ gender?: string;
156
+ sexAtBirth?: string;
157
+ /** @deprecated Use `tag` instead. */
158
+ tags?: string;
159
+ };
160
+ }
161
+
162
+ /**
163
+ * Represents a document whose sensitive content has been decrypted and is held
164
+ * in memory. The `jwe` property is removed, and the `content` is guaranteed to exist.
165
+ * This type should ONLY be used for in-memory processing and NEVER for persistence.
166
+ * @template T The expected type of the decrypted `content`.
167
+ */
168
+ export type UnprotectedStorageDoc<T> = Omit<ConfidentialStorageDoc, 'jwe' | 'content'> & {
169
+ content: T;
170
+ };