gdc-common-utils-ts 1.0.4 → 1.0.7

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 (202) hide show
  1. package/dist/AesManager.d.ts +27 -0
  2. package/dist/AesManager.js +62 -0
  3. package/dist/CryptographyService.d.ts +76 -0
  4. package/dist/CryptographyService.js +403 -0
  5. package/dist/constants/Schemas.d.ts +45 -0
  6. package/dist/constants/Schemas.js +48 -0
  7. package/dist/constants/index.js +1 -0
  8. package/{src/constants/schemaorg.ts → dist/constants/schemaorg.d.ts} +24 -116
  9. package/dist/constants/schemaorg.js +185 -0
  10. package/dist/cryptoDecode.d.ts +3 -0
  11. package/dist/cryptoDecode.js +90 -0
  12. package/dist/cryptoEncode.d.ts +1 -0
  13. package/dist/cryptoEncode.js +30 -0
  14. package/dist/cryptography.abstract.d.ts +13 -0
  15. package/{src/cryptography.abstract.ts → dist/cryptography.abstract.js} +6 -14
  16. package/dist/hmac.d.ts +2 -0
  17. package/{src/hmac.ts → dist/hmac.js} +4 -7
  18. package/dist/index.js +3 -0
  19. package/{src/interfaces/Cryptography.types.ts → dist/interfaces/Cryptography.types.d.ts} +71 -71
  20. package/dist/interfaces/Cryptography.types.js +8 -0
  21. package/dist/interfaces/ICryptoHelper.d.ts +28 -0
  22. package/dist/interfaces/ICryptoHelper.js +3 -0
  23. package/dist/interfaces/ICryptography.d.ts +154 -0
  24. package/dist/interfaces/ICryptography.js +3 -0
  25. package/dist/interfaces/IWallet.d.ts +55 -0
  26. package/dist/interfaces/IWallet.js +3 -0
  27. package/dist/interfaces/MlDsa.d.ts +9 -0
  28. package/{src/interfaces/MlDsa.ts → dist/interfaces/MlDsa.js} +1 -5
  29. package/dist/interfaces/MlKem.d.ts +11 -0
  30. package/{src/interfaces/MlKem.ts → dist/interfaces/MlKem.js} +0 -5
  31. package/dist/models/aes.d.ts +85 -0
  32. package/dist/models/aes.js +10 -0
  33. package/dist/models/auth.d.ts +35 -0
  34. package/dist/models/auth.js +3 -0
  35. package/{src/models/bundle.ts → dist/models/bundle.d.ts} +41 -63
  36. package/dist/models/bundle.js +26 -0
  37. package/dist/models/clinical-sections.d.ts +36 -0
  38. package/dist/models/clinical-sections.en.d.ts +75 -0
  39. package/dist/models/clinical-sections.en.js +81 -0
  40. package/dist/models/clinical-sections.js +32 -0
  41. package/dist/models/comm.d.ts +44 -0
  42. package/dist/models/comm.js +4 -0
  43. package/{src/models/confidential-job.ts → dist/models/confidential-job.d.ts} +23 -45
  44. package/dist/models/confidential-job.js +20 -0
  45. package/dist/models/confidential-message.d.ts +97 -0
  46. package/dist/models/confidential-message.js +4 -0
  47. package/{src/models/confidential-storage.ts → dist/models/confidential-storage.d.ts} +35 -56
  48. package/dist/models/confidential-storage.js +3 -0
  49. package/{src/models/consent-rule.ts → dist/models/consent-rule.d.ts} +22 -42
  50. package/dist/models/consent-rule.js +21 -0
  51. package/{src/models/crypto.ts → dist/models/crypto.d.ts} +5 -13
  52. package/dist/models/crypto.js +3 -0
  53. package/dist/models/device-license.d.ts +133 -0
  54. package/dist/models/device-license.js +3 -0
  55. package/{src/models/did.ts → dist/models/did.d.ts} +21 -30
  56. package/dist/models/did.js +3 -0
  57. package/dist/models/index.js +31 -0
  58. package/dist/models/indexing.d.ts +11 -0
  59. package/dist/models/indexing.js +18 -0
  60. package/dist/models/issue.d.ts +57 -0
  61. package/dist/models/issue.js +75 -0
  62. package/dist/models/jsonapi.d.ts +13 -0
  63. package/dist/models/jsonapi.js +3 -0
  64. package/{src/models/jwe.ts → dist/models/jwe.d.ts} +10 -22
  65. package/dist/models/jwe.js +3 -0
  66. package/{src/models/jwk.ts → dist/models/jwk.d.ts} +0 -11
  67. package/dist/models/jwk.js +3 -0
  68. package/{src/models/jws.ts → dist/models/jws.d.ts} +0 -7
  69. package/dist/models/jws.js +3 -0
  70. package/dist/models/jwt.d.ts +9 -0
  71. package/dist/models/jwt.js +3 -0
  72. package/dist/models/multibase58.d.ts +13 -0
  73. package/dist/models/multibase58.js +40 -0
  74. package/dist/models/oidc4ida.common.model.d.ts +33 -0
  75. package/dist/models/oidc4ida.common.model.js +3 -0
  76. package/dist/models/oidc4ida.document.model.d.ts +50 -0
  77. package/dist/models/oidc4ida.document.model.js +3 -0
  78. package/{src/models/oidc4ida.electronicRecord.model.ts → dist/models/oidc4ida.electronicRecord.model.d.ts} +18 -37
  79. package/dist/models/oidc4ida.electronicRecord.model.js +3 -0
  80. package/{src/models/oidc4ida.evidence.model.ts → dist/models/oidc4ida.evidence.model.d.ts} +17 -35
  81. package/dist/models/oidc4ida.evidence.model.js +5 -0
  82. package/dist/models/openid-device.d.ts +119 -0
  83. package/dist/models/openid-device.js +3 -0
  84. package/dist/models/operation-outcome.d.ts +26 -0
  85. package/dist/models/operation-outcome.js +3 -0
  86. package/{src/models/params.ts → dist/models/params.d.ts} +20 -29
  87. package/dist/models/params.js +3 -0
  88. package/dist/models/resource-document.d.ts +14 -0
  89. package/dist/models/resource-document.js +3 -0
  90. package/dist/models/response.d.ts +1 -0
  91. package/dist/models/response.js +3 -0
  92. package/dist/models/urlPath.d.ts +58 -0
  93. package/dist/models/urlPath.js +76 -0
  94. package/dist/models/verifiable-credential.d.ts +45 -0
  95. package/dist/models/verifiable-credential.js +8 -0
  96. package/dist/utils/actor.d.ts +18 -0
  97. package/dist/utils/actor.js +36 -0
  98. package/dist/utils/base-convert.d.ts +20 -0
  99. package/{src/utils/base-convert.ts → dist/utils/base-convert.js} +23 -36
  100. package/dist/utils/baseN.d.ts +35 -0
  101. package/dist/utils/baseN.js +174 -0
  102. package/dist/utils/bundle.d.ts +6 -0
  103. package/dist/utils/bundle.js +32 -0
  104. package/dist/utils/content.d.ts +55 -0
  105. package/{src/utils/content.ts → dist/utils/content.js} +4 -10
  106. package/dist/utils/did.d.ts +67 -0
  107. package/dist/utils/did.js +123 -0
  108. package/dist/utils/format-converter.d.ts +21 -0
  109. package/dist/utils/format-converter.js +109 -0
  110. package/dist/utils/index.js +13 -0
  111. package/dist/utils/jwt.d.ts +52 -0
  112. package/dist/utils/jwt.js +153 -0
  113. package/dist/utils/manager-error.d.ts +15 -0
  114. package/dist/utils/manager-error.js +23 -0
  115. package/dist/utils/multibase58.d.ts +13 -0
  116. package/dist/utils/multibase58.js +40 -0
  117. package/dist/utils/multibasehash.d.ts +8 -0
  118. package/{src/utils/multibasehash.ts → dist/utils/multibasehash.js} +8 -13
  119. package/dist/utils/normalize.d.ts +16 -0
  120. package/{src/utils/normalize.ts → dist/utils/normalize.js} +15 -18
  121. package/dist/utils/object-convert.d.ts +20 -0
  122. package/{src/utils/object-convert.ts → dist/utils/object-convert.js} +10 -16
  123. package/dist/utils/string-convert.d.ts +24 -0
  124. package/{src/utils/string-convert.ts → dist/utils/string-convert.js} +5 -14
  125. package/dist/utils/string-utils.d.ts +25 -0
  126. package/{src/utils/string-utils.ts → dist/utils/string-utils.js} +12 -16
  127. package/dist/utils/url.d.ts +27 -0
  128. package/{src/utils/url.ts → dist/utils/url.js} +6 -7
  129. package/package.json +56 -14
  130. package/PUBLISHING.md +0 -33
  131. package/__tests__/AesManager.test.ts +0 -53
  132. package/__tests__/CryptographyService.test.ts +0 -194
  133. package/__tests__/bundle.test.ts +0 -29
  134. package/__tests__/content.test.ts +0 -72
  135. package/__tests__/crypto-encode-decode.test.ts +0 -52
  136. package/__tests__/crypto-hmac.test.ts +0 -21
  137. package/__tests__/did-generateServiceId.errors.test.ts +0 -8
  138. package/__tests__/did-generateServiceId.test.ts +0 -18
  139. package/__tests__/models-clinical-sections.test.ts +0 -32
  140. package/__tests__/models-multibase58.test.ts +0 -33
  141. package/__tests__/multibase58.errors.test.ts +0 -7
  142. package/__tests__/multibase58.test.ts +0 -28
  143. package/__tests__/multibasehash.test.ts +0 -25
  144. package/__tests__/utils-actor.test.ts +0 -46
  145. package/__tests__/utils-base-convert.test.ts +0 -57
  146. package/__tests__/utils-baseN.test.ts +0 -40
  147. package/__tests__/utils-did-extra.test.ts +0 -33
  148. package/__tests__/utils-format-converter.test.ts +0 -87
  149. package/__tests__/utils-jwt.test.ts +0 -57
  150. package/__tests__/utils-manager-error.test.ts +0 -11
  151. package/__tests__/utils-normalize.test.ts +0 -15
  152. package/__tests__/utils-object-convert.test.ts +0 -38
  153. package/__tests__/utils-string-convert.test.ts +0 -20
  154. package/__tests__/utils-string-utils.test.ts +0 -25
  155. package/__tests__/utils-url.test.ts +0 -21
  156. package/babel.config.cjs +0 -5
  157. package/jest.config.ts +0 -47
  158. package/src/AesManager.ts +0 -82
  159. package/src/CryptographyService.ts +0 -461
  160. package/src/JweManager.ts.txt +0 -365
  161. package/src/KmsService.txt +0 -493
  162. package/src/constants/Schemas.ts +0 -61
  163. package/src/cryptoDecode.ts +0 -104
  164. package/src/cryptoEncode.ts +0 -36
  165. package/src/interfaces/ICryptoHelper.ts +0 -33
  166. package/src/interfaces/ICryptography.ts +0 -177
  167. package/src/interfaces/IWallet.ts +0 -62
  168. package/src/models/aes.ts +0 -93
  169. package/src/models/auth.ts +0 -38
  170. package/src/models/bundle.txt +0 -93
  171. package/src/models/clinical-sections.en.ts +0 -82
  172. package/src/models/clinical-sections.ts +0 -64
  173. package/src/models/comm.ts +0 -63
  174. package/src/models/confidential-message.ts +0 -137
  175. package/src/models/device-license.ts +0 -161
  176. package/src/models/indexing.ts +0 -20
  177. package/src/models/issue.ts +0 -85
  178. package/src/models/jsonapi.ts +0 -19
  179. package/src/models/jwt.ts +0 -15
  180. package/src/models/multibase58.ts +0 -46
  181. package/src/models/oidc4ida.common.model.ts +0 -39
  182. package/src/models/oidc4ida.document.model.ts +0 -61
  183. package/src/models/openid-device.ts +0 -146
  184. package/src/models/operation-outcome.ts +0 -34
  185. package/src/models/resource-document.ts +0 -21
  186. package/src/models/response.ts +0 -5
  187. package/src/models/urlPath.ts +0 -76
  188. package/src/models/verifiable-credential.ts +0 -52
  189. package/src/types/noble-hashes.d.ts +0 -4
  190. package/src/utils/actor.ts +0 -56
  191. package/src/utils/baseN.ts +0 -203
  192. package/src/utils/bundle.ts +0 -30
  193. package/src/utils/did.ts +0 -155
  194. package/src/utils/format-converter.ts +0 -119
  195. package/src/utils/jwt.ts +0 -165
  196. package/src/utils/manager-error.ts +0 -27
  197. package/src/utils/multibase58.ts +0 -46
  198. package/tsconfig.json +0 -15
  199. /package/{src/constants/index.ts → dist/constants/index.d.ts} +0 -0
  200. /package/{src/index.ts → dist/index.d.ts} +0 -0
  201. /package/{src/models/index.ts → dist/models/index.d.ts} +0 -0
  202. /package/{src/utils/index.ts → dist/utils/index.d.ts} +0 -0
@@ -0,0 +1,123 @@
1
+ // crypto-ts/utils/did.ts
2
+ // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
3
+ /**
4
+ * Generates a DID Service ID fragment from a selector object.
5
+ * The format is always `#<section>:<format>:<resourceType>:<action>`.
6
+ *
7
+ * This utility's only job is to correctly assemble the string. It contains no
8
+ * conditional logic about DID types, as that is handled by the data layer.
9
+ *
10
+ * @param selector The structured object containing the endpoint parts.
11
+ * @returns The formatted service ID fragment string.
12
+ */
13
+ export function generateServiceId(selector) {
14
+ // Canonical casing:
15
+ // - `section`, `format`, `resourceType` are matched case-insensitively by the backend router,
16
+ // and lowercasing them makes DID Document lookup deterministic across SDKs.
17
+ // - `action` is kept as-is (future actions may be case-sensitive identifiers).
18
+ const parts = [
19
+ selector.section?.toLowerCase(),
20
+ selector.format?.toLowerCase(),
21
+ selector.resourceType?.toLowerCase(),
22
+ selector.action,
23
+ ];
24
+ return `#${parts.filter(p => p).join(':')}`;
25
+ }
26
+ /**
27
+ * Normalizes a did:web string to a canonical format to prevent resolution errors
28
+ * due to case sensitivity in the path component of the underlying URL.
29
+ *
30
+ * The rule is:
31
+ * - All segments are lowercased, EXCEPT the final segment.
32
+ * - If the final segment represents a `system|code` pair (e.g., for a role),
33
+ * the `system` part is lowercased, but the `code` is preserved as-is.
34
+ * - If the final segment is a unique identifier (like a Tax ID), it is preserved as-is.
35
+ *
36
+ * @param did The did:web string to normalize.
37
+ * @returns The canonicalized did:web string.
38
+ */
39
+ export function normalizeDidWeb(did) {
40
+ const parts = did.split(':');
41
+ if (parts[0] !== 'did' || parts[1] !== 'web' || parts.length < 3) {
42
+ // Not a valid did:web, return as is.
43
+ return did;
44
+ }
45
+ // Lowercase all parts except the very last one.
46
+ const lowercasedParts = parts.slice(0, -1).map(part => part.toLowerCase());
47
+ let lastPart = parts[parts.length - 1];
48
+ // Special handling for the last part if it contains a role descriptor.
49
+ if (lastPart.includes('|')) {
50
+ const [system, ...codeParts] = lastPart.split('|');
51
+ const code = codeParts.join('|'); // Re-join in case the code itself has a pipe.
52
+ lastPart = `${system.toLowerCase()}|${code}`;
53
+ }
54
+ return [...lowercasedParts, lastPart].join(':');
55
+ }
56
+ /**
57
+ * Encodes a hostname according to did:web spec (percent-encodes port colons).
58
+ * @param apiUrl The full base URL of the API.
59
+ * @returns The percent-encoded hostname.
60
+ */
61
+ function getEncodedHost(apiUrl) {
62
+ try {
63
+ const parsedUrl = new URL(apiUrl);
64
+ return parsedUrl.host.replace(':', '%3A');
65
+ }
66
+ catch (e) {
67
+ console.error(`[getEncodedHost] Invalid apiUrl provided: ${apiUrl}`);
68
+ return 'localhost'; // Fallback
69
+ }
70
+ }
71
+ /**
72
+ * Creates the deterministic "hosted" did:web for a tenant (Organization).
73
+ *
74
+ * @param hostDidWeb The DID of the host (e.g., 'did:web:host.example.com').
75
+ * @param tenantAlternateName The alternate name of the tenant (e.g., 'acme').
76
+ * @param context An object containing jurisdiction, version, and sector.
77
+ * @returns The tenant's full, correctly formatted hosted did:web.
78
+ * Example: 'did:web:host.example.com:acme:cds-es:v1:health-care'
79
+ */
80
+ export function createHostedDidWeb(hostDidWeb, tenantAlternateName, context) {
81
+ const hostPart = hostDidWeb.replace(/^did:web:/, '');
82
+ // The path in a did:web uses colons as separators.
83
+ const didPath = `cds-${context.jurisdiction}:${context.version}:${context.sector}`;
84
+ return `did:web:${hostPart}:${tenantAlternateName}:${didPath}`;
85
+ }
86
+ /**
87
+ * Builds the canonical details (URL and did:web URN) for a hosted DID.
88
+ * This is the single source of truth for constructing hosted identifiers in the app.
89
+ *
90
+ * @param options An object with the components of the DID.
91
+ * @param options.host The provider's domain (e.g., 'provider.com').
92
+ * @param options.alternateName The tenant's identifier (e.g., 'acme').
93
+ * @param options.jurisdiction The legal jurisdiction (defaults to 'ES').
94
+ * @param options.sector The business sector (defaults to 'health-care').
95
+ * @returns An object with the full URL (with trailing /) and the canonical did:web.
96
+ */
97
+ export function buildHostedDidDetails({ host, alternateName, jurisdiction = 'ES', sector = 'health-care', }) {
98
+ // 1. Build the path part of the DID/URL.
99
+ const pathPart = `${alternateName}/cds-${jurisdiction}/v1/${sector}`;
100
+ // 2. Build the full URL, ensuring a trailing slash.
101
+ const url = `https://${host}/${pathPart}/`;
102
+ // 3. Build the canonical did:web, replacing / with :.
103
+ const hostAndPath = `${host}/${pathPart}`;
104
+ const did = `did:web:${hostAndPath.replace(/\//g, ':')}`;
105
+ return { did, url };
106
+ }
107
+ /**
108
+ * Converts a did:web identifier into a full HTTPS or HTTP base URL with a trailing slash.
109
+ * It correctly decodes percent-encoded ports for local development.
110
+ * @param did The did:web string (e.g., 'did:web:example.com' or 'did:web:localhost%3A3000:acme:cds-es:v1:health-care').
111
+ * @returns The full base URL (e.g., 'https://example.com/acme/cds-es/v1/health-care/').
112
+ */
113
+ export function getBaseUrlFromDidWeb(did) {
114
+ const didParts = did.replace(/^did:web:/, '').split(':');
115
+ const domainPart = didParts[0];
116
+ const pathParts = didParts.slice(1);
117
+ const decodedDomain = decodeURIComponent(domainPart);
118
+ const protocol = decodedDomain.startsWith('localhost') ? 'http' : 'https';
119
+ const path = pathParts.join('/').replace(/cds-(es|us|gb)/, (match, p1) => `cds-${p1.toUpperCase()}`);
120
+ // Ensure a trailing slash for the base URL, without double slashes when no path is present.
121
+ const normalizedPath = path ? `${path}/` : '';
122
+ return `${protocol}://${decodedDomain}/${normalizedPath}`;
123
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Normalizes a FHIR resource or Bundle into an array of entries.
3
+ */
4
+ export declare const convertResourceDataToArrayOfDataEntries: (inputData: any, requestPath: string, webDomain: string) => any[];
5
+ /**
6
+ * Converts a resource or a FHIR Bundle to a JSON:API Primary Document.
7
+ */
8
+ export declare const convertResourceOrBundleToPrimaryDoc: (resourceData: any, specification: string, webDomain: string, requestPath: string) => any;
9
+ /**
10
+ * Converts a JSON:API Primary Document back to a FHIR Bundle.
11
+ */
12
+ export declare const convertPrimaryDocToBundleFHIR: (primaryDocument: any, bundleType: string) => any;
13
+ /**
14
+ * Converts a FHIR Bundle containing one or more OperationOutcome entries into a
15
+ * compliant JSON:API Error Document. Each error entry in the bundle is mapped
16
+ * to a corresponding error object in the JSON:API `errors` array.
17
+ *
18
+ * @param errorBundle The FHIR Bundle representing the error(s).
19
+ * @returns A JSON:API document with a top-level `errors` array.
20
+ */
21
+ export declare const convertFhirErrorBundleToJsonApiError: (errorBundle: any) => any;
@@ -0,0 +1,109 @@
1
+ // crypto-ts/utils/format-converter.ts
2
+ // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
3
+ import { safelyJoinUrl } from "./url.js";
4
+ /**
5
+ * Normalizes a FHIR resource or Bundle into an array of entries.
6
+ */
7
+ export const convertResourceDataToArrayOfDataEntries = (inputData, requestPath, webDomain) => {
8
+ if (inputData.resourceType) { // It is FHIR data
9
+ if (inputData.resourceType === 'Bundle') {
10
+ return inputData.entry || [];
11
+ }
12
+ else {
13
+ const resourceIdentifier = inputData.id || (inputData.identifier && inputData.identifier[0]?.value) || "";
14
+ const fullUrl = safelyJoinUrl(webDomain, safelyJoinUrl(requestPath, resourceIdentifier));
15
+ return [{ fullUrl, resource: inputData }];
16
+ }
17
+ }
18
+ else { // Assume it's already a JSON:API-like object
19
+ const resourceIdentifier = inputData.id || "";
20
+ // const fullUrl = safelyJoinUrl(webDomain, safelyJoinUrl(requestPath, resourceIdentifier));
21
+ return [inputData];
22
+ }
23
+ };
24
+ /**
25
+ * Converts a resource or a FHIR Bundle to a JSON:API Primary Document.
26
+ */
27
+ export const convertResourceOrBundleToPrimaryDoc = (resourceData, specification, webDomain, requestPath) => {
28
+ const entries = convertResourceDataToArrayOfDataEntries(resourceData, requestPath, webDomain);
29
+ // Handle FHIR entry structure vs. JSON:API data structure
30
+ const data = entries.map(entry => {
31
+ if (entry.resource) { // It's a FHIR entry
32
+ return {
33
+ type: `${specification}.${entry.resource.resourceType}`,
34
+ id: entry.resource.id,
35
+ attributes: { ...entry.resource }
36
+ };
37
+ }
38
+ return entry; // Assumes it's already a JSON:API resource object
39
+ });
40
+ return { data };
41
+ };
42
+ /**
43
+ * Converts a JSON:API Primary Document back to a FHIR Bundle.
44
+ */
45
+ export const convertPrimaryDocToBundleFHIR = (primaryDocument, bundleType) => {
46
+ const entries = [];
47
+ if (primaryDocument.data) {
48
+ entries.push(...primaryDocument.data.map((jsonApiResourceObject) => ({
49
+ // fullUrl might need to be reconstructed based on context
50
+ resource: jsonApiResourceObject.attributes || jsonApiResourceObject
51
+ })));
52
+ }
53
+ if (primaryDocument.errors) {
54
+ entries.push(...primaryDocument.errors.map((errorObject) => ({
55
+ resource: {
56
+ resourceType: 'OperationOutcome',
57
+ id: errorObject.id,
58
+ issue: [{
59
+ code: errorObject.status,
60
+ severity: 'error',
61
+ details: { text: errorObject.detail },
62
+ }]
63
+ }
64
+ })));
65
+ }
66
+ return {
67
+ entry: entries,
68
+ resourceType: 'Bundle',
69
+ total: primaryDocument.data ? primaryDocument.data.length : 0,
70
+ type: bundleType
71
+ };
72
+ };
73
+ /**
74
+ * Converts a FHIR Bundle containing one or more OperationOutcome entries into a
75
+ * compliant JSON:API Error Document. Each error entry in the bundle is mapped
76
+ * to a corresponding error object in the JSON:API `errors` array.
77
+ *
78
+ * @param errorBundle The FHIR Bundle representing the error(s).
79
+ * @returns A JSON:API document with a top-level `errors` array.
80
+ */
81
+ export const convertFhirErrorBundleToJsonApiError = (errorBundle) => {
82
+ if (!errorBundle.entry || errorBundle.entry.length === 0) {
83
+ return {
84
+ errors: [{
85
+ status: '500',
86
+ title: 'Unknown Error',
87
+ detail: 'An unspecified error occurred and the error bundle was malformed or empty.'
88
+ }]
89
+ };
90
+ }
91
+ const errorObjects = errorBundle.entry.map((entry) => {
92
+ const resource = entry.resource || {};
93
+ const issue = resource.issue ? resource.issue[0] : {};
94
+ const title = issue.details?.text || 'Processing Error';
95
+ return {
96
+ id: resource.id,
97
+ status: entry.response?.status?.toString() || '500',
98
+ code: issue.code || 'processing-error',
99
+ title: title,
100
+ detail: issue.diagnostics || 'An error occurred while processing the request.',
101
+ meta: {
102
+ severity: issue.severity || 'error'
103
+ }
104
+ };
105
+ });
106
+ return {
107
+ errors: errorObjects
108
+ };
109
+ };
@@ -0,0 +1,13 @@
1
+ export * from './actor.js';
2
+ export * from './base-convert.js';
3
+ export * from './baseN.js';
4
+ export * from './bundle.js';
5
+ export * from './content.js';
6
+ export * from './did.js';
7
+ export * from './format-converter.js';
8
+ export * from './jwt.js';
9
+ export * from './manager-error.js';
10
+ export * from './multibase58.js';
11
+ export * from './multibasehash.js';
12
+ export * from './normalize.js';
13
+ export * from './object-convert.js';
@@ -0,0 +1,52 @@
1
+ import { DataCompactJWT, JwtCompactParts } from '../models/jwt';
2
+ /**
3
+ * Splits a compact JWT string into its three parts.
4
+ * @param compactToken The compact JWT string.
5
+ * @returns A PartsJWT object or undefined if the format is invalid.
6
+ */
7
+ export declare function getPartsJWT(compactToken: string | undefined): JwtCompactParts | undefined;
8
+ /**
9
+ * Decodes the Base64Url header of a JWT into a JSON object.
10
+ * @param headerB64Url The Base64Url-encoded header string.
11
+ * @returns A JSON object representing the header claims.
12
+ */
13
+ export declare function decodeHeader(headerB64Url: string): any;
14
+ /**
15
+ * Decodes the payload of a JWT, decompressing it if necessary.
16
+ * @param payloadB64Url The Base64Url-encoded payload string.
17
+ * @param isDeflated True if the payload is compressed with DEFLATE.
18
+ * @returns The decoded payload as a JSON object.
19
+ */
20
+ export declare function decodePayload(payloadB64Url: string, isDeflated?: boolean): Promise<object>;
21
+ /**
22
+ * Fully decodes a compact JWT into a `DataCompactJWT` object with JSON headers and payload.
23
+ * @returns A (compact) JWT object or undefined if parsing fails.
24
+ */
25
+ export declare function getDataJWT(compactJWT: string | undefined): Promise<DataCompactJWT | undefined>;
26
+ /**
27
+ * Encodes a JSON object into a Base64Url string.
28
+ * @param header The header object.
29
+ * @returns The encoded string.
30
+ */
31
+ export declare function encodeHeader(header: object): string;
32
+ /**
33
+ * Encodes a JSON object into a Base64Url payload, compressing it if required.
34
+ * @param payload The payload object.
35
+ * @param deflate True to compress the payload with DEFLATE.
36
+ * @returns The encoded string.
37
+ */
38
+ export declare function encodePayload(payload: object, deflate?: boolean): Promise<string>;
39
+ /**
40
+ * Encodes a signature byte array into a Base64Url string.
41
+ * @param signatureBytes The signature bytes.
42
+ * @returns The encoded string, or an empty string if no signature is provided.
43
+ */
44
+ export declare function encodeSignature(signatureBytes?: Uint8Array): string;
45
+ /**
46
+ * Assembles a header, payload, and signature into a compact JWT string.
47
+ * @param header The header object.
48
+ * @param payload The payload object.
49
+ * @param signatureBytes The optional signature.
50
+ * @returns A compact JWT string.
51
+ */
52
+ export declare function compactJWT(header: object, payload: object, signatureBytes?: Uint8Array): Promise<string>;
@@ -0,0 +1,153 @@
1
+ // crypto-ts/utils/jwt.ts
2
+ // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
3
+ // Use `import * as pako` to ensure compatibility with CommonJS/ESM module resolution.
4
+ // This resolves a stubborn TypeScript error (`esModuleInterop`) during testing.
5
+ import * as pako from 'pako';
6
+ import { Content } from './content.js';
7
+ // --- JWT Parsing and Decoding ---
8
+ /**
9
+ * Splits a compact JWT string into its three parts.
10
+ * @param compactToken The compact JWT string.
11
+ * @returns A PartsJWT object or undefined if the format is invalid.
12
+ */
13
+ export function getPartsJWT(compactToken) {
14
+ if (!compactToken) {
15
+ return undefined;
16
+ }
17
+ const parts = compactToken.split('.');
18
+ if (parts.length !== 3) {
19
+ return undefined;
20
+ }
21
+ return {
22
+ protected: parts[0],
23
+ payload: parts[1],
24
+ signature: parts[2],
25
+ };
26
+ }
27
+ /**
28
+ * Decodes the Base64Url header of a JWT into a JSON object.
29
+ * @param headerB64Url The Base64Url-encoded header string.
30
+ * @returns A JSON object representing the header claims.
31
+ */
32
+ export function decodeHeader(headerB64Url) {
33
+ try {
34
+ const headerBytes = Content.base64ToBytes(headerB64Url);
35
+ const headerString = Content.bytesToStringASCII(headerBytes);
36
+ return JSON.parse(headerString);
37
+ }
38
+ catch (e) {
39
+ console.error(`Cannot decode JWT header: ${e}`);
40
+ return {};
41
+ }
42
+ }
43
+ /**
44
+ * Decodes the payload of a JWT, decompressing it if necessary.
45
+ * @param payloadB64Url The Base64Url-encoded payload string.
46
+ * @param isDeflated True if the payload is compressed with DEFLATE.
47
+ * @returns The decoded payload as a JSON object.
48
+ */
49
+ export async function decodePayload(payloadB64Url, isDeflated) {
50
+ try {
51
+ let payloadBytes = Content.base64ToBytes(payloadB64Url);
52
+ if (isDeflated) {
53
+ payloadBytes = pako.inflate(payloadBytes);
54
+ }
55
+ // CRITICAL: The output of a decompression library like pako is a raw binary
56
+ // stream. It is NOT guaranteed to be valid UTF-8. Using the strict
57
+ // `bytesToStringUTF8` can fail. `bytesToStringASCII` is a more permissive
58
+ // decoder that is robust enough to handle this binary data and convert it
59
+ // to a string that can be safely parsed by `JSON.parse()`.
60
+ const payloadString = Content.bytesToStringASCII(payloadBytes);
61
+ return JSON.parse(payloadString);
62
+ }
63
+ catch (e) {
64
+ console.error(`Cannot decode JWT payload: ${e}`);
65
+ return {};
66
+ }
67
+ }
68
+ /**
69
+ * Fully decodes a compact JWT into a `DataCompactJWT` object with JSON headers and payload.
70
+ * @returns A (compact) JWT object or undefined if parsing fails.
71
+ */
72
+ export async function getDataJWT(compactJWT) {
73
+ const parts = getPartsJWT(compactJWT);
74
+ if (!parts) {
75
+ return undefined;
76
+ }
77
+ const header = decodeHeader(parts.protected);
78
+ const isDeflated = header.zip === 'DEF';
79
+ const payload = await decodePayload(parts.payload, isDeflated);
80
+ return {
81
+ protected: header,
82
+ payload,
83
+ signature: parts.signature ? Content.base64ToBytes(parts.signature) : undefined,
84
+ };
85
+ }
86
+ // --- JWT Creation and Encoding ---
87
+ /**
88
+ * Encodes a JSON object into a Base64Url string.
89
+ * @param header The header object.
90
+ * @returns The encoded string.
91
+ */
92
+ export function encodeHeader(header) {
93
+ try {
94
+ return Content.objectToRawBase64UrlSafe(header);
95
+ }
96
+ catch (e) {
97
+ console.warn('Cannot encode JWT header', e);
98
+ return '';
99
+ }
100
+ }
101
+ /**
102
+ * Encodes a JSON object into a Base64Url payload, compressing it if required.
103
+ * @param payload The payload object.
104
+ * @param deflate True to compress the payload with DEFLATE.
105
+ * @returns The encoded string.
106
+ */
107
+ export async function encodePayload(payload, deflate) {
108
+ try {
109
+ // CRITICAL: When creating a payload, we start with a JSON string, which IS
110
+ // valid UTF-8. We must use the strict `stringToBytesUTF8` encoder to ensure
111
+ // standards compliance.
112
+ let payloadBytes = Content.stringToBytesUTF8(JSON.stringify(payload));
113
+ if (deflate) {
114
+ payloadBytes = pako.deflate(payloadBytes);
115
+ }
116
+ return Content.bytesToRawBase64UrlSafe(payloadBytes);
117
+ }
118
+ catch (e) {
119
+ console.warn('Cannot encode JWT payload', e);
120
+ return '';
121
+ }
122
+ }
123
+ /**
124
+ * Encodes a signature byte array into a Base64Url string.
125
+ * @param signatureBytes The signature bytes.
126
+ * @returns The encoded string, or an empty string if no signature is provided.
127
+ */
128
+ export function encodeSignature(signatureBytes) {
129
+ if (!signatureBytes || signatureBytes.length < 1) {
130
+ return '';
131
+ }
132
+ try {
133
+ return Content.bytesToRawBase64UrlSafe(signatureBytes);
134
+ }
135
+ catch (e) {
136
+ console.warn('Cannot encode JWT signature', e);
137
+ return '';
138
+ }
139
+ }
140
+ /**
141
+ * Assembles a header, payload, and signature into a compact JWT string.
142
+ * @param header The header object.
143
+ * @param payload The payload object.
144
+ * @param signatureBytes The optional signature.
145
+ * @returns A compact JWT string.
146
+ */
147
+ export async function compactJWT(header, payload, signatureBytes) {
148
+ const encodedHeader = encodeHeader(header);
149
+ const isDeflated = header.zip === 'DEF';
150
+ const encodedPayload = await encodePayload(payload, isDeflated);
151
+ const encodedSignature = encodeSignature(signatureBytes);
152
+ return `${encodedHeader}.${encodedPayload}.${encodedSignature}`;
153
+ }
@@ -0,0 +1,15 @@
1
+ import { IssueTypeCode } from "../models/issue";
2
+ /**
3
+ * A custom error class used to propagate specific operational failures from deep
4
+ * within the manager's logic to the central error handler.
5
+ * It carries the necessary information to build a well-formed ErrorEntry.
6
+ */
7
+ export declare class ManagerError extends Error {
8
+ readonly code: IssueTypeCode;
9
+ readonly status: string;
10
+ /**
11
+ * @param message The diagnostic message for the error.
12
+ * @param code The classification of the error, from which the HTTP status will be derived.
13
+ */
14
+ constructor(message: string, code: IssueTypeCode);
15
+ }
@@ -0,0 +1,23 @@
1
+ // src/utils/manager-error.ts
2
+ // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
3
+ import { IssueTypeToHttpStatus } from "../models/issue.js";
4
+ /**
5
+ * A custom error class used to propagate specific operational failures from deep
6
+ * within the manager's logic to the central error handler.
7
+ * It carries the necessary information to build a well-formed ErrorEntry.
8
+ */
9
+ export class ManagerError extends Error {
10
+ code;
11
+ status; // This is a string
12
+ /**
13
+ * @param message The diagnostic message for the error.
14
+ * @param code The classification of the error, from which the HTTP status will be derived.
15
+ */
16
+ constructor(message, code) {
17
+ super(message);
18
+ this.name = 'ManagerError';
19
+ this.code = code;
20
+ // Automatically derive the HTTP status string from the issue code.
21
+ this.status = IssueTypeToHttpStatus[code] || '500';
22
+ }
23
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Encode bytes into multibase base58btc string (prefixed with 'z').
3
+ * Equivalent to multiformats base58btc.encode.
4
+ */
5
+ export declare function encodeMultibase58btc(data: Uint8Array): string;
6
+ /**
7
+ * Decode a multibase base58btc string (must start with 'z').
8
+ * Equivalent to multiformats base58btc.decode.
9
+ */
10
+ export declare function decodeMultibase58btc(multibaseStr: string): Uint8Array;
11
+ export declare function encodeHexToMultibase58btc(hexStr: string): string;
12
+ export declare function decodeMultibase58btcToHex(b58str: string): string;
13
+ export declare function decodeMultibase58btcToUUID(b58str: string): string;
@@ -0,0 +1,40 @@
1
+ // crypto-ts/crypto-ts/utils/multibase58.ts
2
+ // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
3
+ import baseX from "base-x";
4
+ const BASE58_BTC_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
5
+ const base58btc = baseX(BASE58_BTC_ALPHABET);
6
+ /**
7
+ * Encode bytes into multibase base58btc string (prefixed with 'z').
8
+ * Equivalent to multiformats base58btc.encode.
9
+ */
10
+ export function encodeMultibase58btc(data) {
11
+ return "z" + base58btc.encode(Buffer.from(data));
12
+ }
13
+ /**
14
+ * Decode a multibase base58btc string (must start with 'z').
15
+ * Equivalent to multiformats base58btc.decode.
16
+ */
17
+ export function decodeMultibase58btc(multibaseStr) {
18
+ if (!multibaseStr.startsWith("z")) {
19
+ throw new Error("Invalid multibase58btc string: missing 'z' prefix");
20
+ }
21
+ return new Uint8Array(base58btc.decode(multibaseStr.slice(1)));
22
+ }
23
+ // HEX ➜ multibase base58btc (quita guiones si los hay)
24
+ export function encodeHexToMultibase58btc(hexStr) {
25
+ const hexClean = hexStr.replace(/-/g, "").toLowerCase();
26
+ if (!/^[0-9a-f]{32}$/i.test(hexClean))
27
+ throw new Error("Invalid 16-byte hex string");
28
+ const bytes = new Uint8Array(hexClean.match(/.{1,2}/g).map(b => parseInt(b, 16)));
29
+ return encodeMultibase58btc(bytes);
30
+ }
31
+ // multibase base58btc ➜ hex (no hyppens)
32
+ export function decodeMultibase58btcToHex(b58str) {
33
+ const bytes = decodeMultibase58btc(b58str);
34
+ return Array.from(bytes).map(b => b.toString(16).padStart(2, "0")).join("");
35
+ }
36
+ // multibase base58btc ➜ UUID (with hyppens)
37
+ export function decodeMultibase58btcToUUID(b58str) {
38
+ const hex = decodeMultibase58btcToHex(b58str);
39
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
40
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Encodes input into multibase(base58btc(multihash(sha384))).
3
+ * - Multihash prefix: 0x15 0x30
4
+ * - 0x15: code for SHA-384
5
+ * - 0x30: length of SHA-384 = 48 bytes
6
+ * - Multibase prefix: 'z'
7
+ */
8
+ export declare function encodeMultibaseSha384(input: string | Uint8Array): string;
@@ -1,13 +1,10 @@
1
1
  // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
2
-
3
2
  // Use explicit .js subpaths to satisfy package exports in Metro/Node ESM.
4
3
  import { sha384 } from '@noble/hashes/sha2.js';
5
4
  import { utf8ToBytes } from '@noble/hashes/utils.js';
6
5
  import baseX from 'base-x';
7
-
8
6
  const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
9
7
  const base58btc = baseX(BASE58_ALPHABET);
10
-
11
8
  /**
12
9
  * Encodes input into multibase(base58btc(multihash(sha384))).
13
10
  * - Multihash prefix: 0x15 0x30
@@ -15,14 +12,12 @@ const base58btc = baseX(BASE58_ALPHABET);
15
12
  * - 0x30: length of SHA-384 = 48 bytes
16
13
  * - Multibase prefix: 'z'
17
14
  */
18
- export function encodeMultibaseSha384(input: string | Uint8Array): string {
19
- const bytes = typeof input === 'string' ? utf8ToBytes(input) : input;
20
- const hashBytes = sha384(bytes);
21
-
22
- const multihashBytes = new Uint8Array(2 + hashBytes.length);
23
- multihashBytes[0] = 0x15; // SHA-384 code
24
- multihashBytes[1] = 0x30; // length = 48
25
- multihashBytes.set(hashBytes, 2);
26
-
27
- return 'z' + base58btc.encode(multihashBytes);
15
+ export function encodeMultibaseSha384(input) {
16
+ const bytes = typeof input === 'string' ? utf8ToBytes(input) : input;
17
+ const hashBytes = sha384(bytes);
18
+ const multihashBytes = new Uint8Array(2 + hashBytes.length);
19
+ multihashBytes[0] = 0x15; // SHA-384 code
20
+ multihashBytes[1] = 0x30; // length = 48
21
+ multihashBytes.set(hashBytes, 2);
22
+ return 'z' + base58btc.encode(multihashBytes);
28
23
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Normalizes an object for hashing by excluding a standard set of volatile properties.
3
+ * This function is based on the original `normalizeAndSerializeObject` from the backend utils.
4
+ *
5
+ * @param obj The object to normalize.
6
+ * @returns A stable, canonical JSON string of the object's core properties.
7
+ */
8
+ export declare function normalizeObject(obj: object): string;
9
+ /**
10
+ * Normalizes a DIDComm payload specifically for generating the `payload.id` (version hash).
11
+ * According to the defined architecture, this specifically excludes `id` and `meta`.
12
+ *
13
+ * @param payload The DIDComm payload object.
14
+ * @returns A stable JSON string representation of the payload's core content.
15
+ */
16
+ export declare function normalizeDidcommPayloadForId(payload: object): string;