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,27 @@
1
+ import { ProtectedDataAES } from './models/aes';
2
+ /**
3
+ * Manages AES-GCM encryption and decryption using Node's native crypto module.
4
+ * This class handles the core cryptography and the base64url serialization required for JWE.
5
+ */
6
+ export declare class AesManager {
7
+ private readonly ALGORITHM;
8
+ private readonly KEY_SIZE;
9
+ private readonly IV_GENERATION_SIZE;
10
+ private readonly TAG_SIZE_BYTES;
11
+ /**
12
+ * Encrypts a plaintext string and returns the components as base64url strings.
13
+ * @param plaintext The stringified data to encrypt (e.g. a stringified object or ASCII string from raw bytes)
14
+ * @param cekBytes The 32-byte Content Encryption Key.
15
+ * @param aad The Additional Authenticated Data string for integrity protection.
16
+ * @returns A promise resolving to the JWE-compatible encrypted components.
17
+ */
18
+ encrypt(plaintext: string, cekBytes: Uint8Array, aad: string): Promise<ProtectedDataAES>;
19
+ /**
20
+ * Decrypts JWE-compatible encrypted components back to a plaintext string.
21
+ * @param encryptedData The object containing the base64url-encoded ciphertext, iv, and tag.
22
+ * @param cekBytes The 32-byte Content Encryption Key.
23
+ * @param aad The Additional Authenticated Data for integrity verification.
24
+ * @returns A promise resolving to the decrypted plaintext string.
25
+ */
26
+ decrypt(encryptedData: ProtectedDataAES, cekBytes: Uint8Array, aad: string): Promise<string>;
27
+ }
@@ -0,0 +1,62 @@
1
+ // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ // File: crypto-ts/AesManager.ts
3
+ import { createCipheriv, createDecipheriv, randomBytes } from 'crypto';
4
+ import { Content } from './utils/content.js';
5
+ /**
6
+ * Manages AES-GCM encryption and decryption using Node's native crypto module.
7
+ * This class handles the core cryptography and the base64url serialization required for JWE.
8
+ */
9
+ export class AesManager {
10
+ ALGORITHM = 'aes-256-gcm';
11
+ KEY_SIZE = 32; // 256-bit key
12
+ IV_GENERATION_SIZE = 12; // 96-bit IV, recommended by NIST for GCM
13
+ TAG_SIZE_BYTES = 16; // 128-bit authentication tag
14
+ /**
15
+ * Encrypts a plaintext string and returns the components as base64url strings.
16
+ * @param plaintext The stringified data to encrypt (e.g. a stringified object or ASCII string from raw bytes)
17
+ * @param cekBytes The 32-byte Content Encryption Key.
18
+ * @param aad The Additional Authenticated Data string for integrity protection.
19
+ * @returns A promise resolving to the JWE-compatible encrypted components.
20
+ */
21
+ async encrypt(plaintext, cekBytes, aad) {
22
+ if (cekBytes.length !== this.KEY_SIZE) {
23
+ throw new Error(`Invalid key length: a ${this.KEY_SIZE}-byte key is required.`);
24
+ }
25
+ const iv = randomBytes(this.IV_GENERATION_SIZE);
26
+ const aadBytes = Content.stringToBytesUTF8(aad);
27
+ const cipher = createCipheriv(this.ALGORITHM, cekBytes, iv, {
28
+ authTagLength: this.TAG_SIZE_BYTES
29
+ });
30
+ cipher.setAAD(aadBytes);
31
+ const ciphertext = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
32
+ const tag = cipher.getAuthTag();
33
+ return {
34
+ ciphertext: Content.bytesToRawBase64UrlSafe(ciphertext),
35
+ iv: Content.bytesToRawBase64UrlSafe(iv),
36
+ tag: Content.bytesToRawBase64UrlSafe(tag),
37
+ };
38
+ }
39
+ /**
40
+ * Decrypts JWE-compatible encrypted components back to a plaintext string.
41
+ * @param encryptedData The object containing the base64url-encoded ciphertext, iv, and tag.
42
+ * @param cekBytes The 32-byte Content Encryption Key.
43
+ * @param aad The Additional Authenticated Data for integrity verification.
44
+ * @returns A promise resolving to the decrypted plaintext string.
45
+ */
46
+ async decrypt(encryptedData, cekBytes, aad) {
47
+ if (cekBytes.length !== this.KEY_SIZE) {
48
+ throw new Error(`Invalid key length: a ${this.KEY_SIZE}-byte key is required.`);
49
+ }
50
+ const ciphertextBytes = Content.base64ToBytes(encryptedData.ciphertext);
51
+ const tagBytes = Content.base64ToBytes(encryptedData.tag);
52
+ const ivBytes = Content.base64ToBytes(encryptedData.iv);
53
+ const aadBytes = Content.stringToBytesUTF8(aad);
54
+ const decipher = createDecipheriv(this.ALGORITHM, cekBytes, ivBytes, {
55
+ authTagLength: this.TAG_SIZE_BYTES
56
+ });
57
+ decipher.setAuthTag(tagBytes);
58
+ decipher.setAAD(aadBytes);
59
+ const decryptedBytes = Buffer.concat([decipher.update(ciphertextBytes), decipher.final()]);
60
+ return Content.bytesToStringUTF8(decryptedBytes);
61
+ }
62
+ }
@@ -0,0 +1,76 @@
1
+ import { ICryptoHelper } from './interfaces/ICryptoHelper';
2
+ import { ICryptography } from './interfaces/ICryptography';
3
+ import { DataCompactJWT, JwtCompactParts } from './models/jwt';
4
+ import { JweObject } from './models/jwe';
5
+ import { MlkemPublicJwk, MldsaPublicJwk, PublicJwk, MlkemPrivateJwk, MldsaAlg, MlkemCurve } from './interfaces/Cryptography.types';
6
+ import { ProtectedDataAES } from './models/aes';
7
+ /**
8
+ * Implements the ICryptography interface, providing a complete suite of low-level,
9
+ * stateless cryptographic functions. This service is the "engine" of the security layer,
10
+ * orchestrating Post-Quantum and AES primitives.
11
+ */
12
+ export declare class CryptographyService implements ICryptography {
13
+ private aesManager;
14
+ private cryptoHelper;
15
+ private mlDsaModule;
16
+ private mlKemModule;
17
+ private readonly ML_KEM_SEED_SIZE;
18
+ private readonly ML_DSA_SEED_SIZE;
19
+ constructor(cryptoHelper: ICryptoHelper);
20
+ private loadMlDsa;
21
+ private loadMlKem;
22
+ digestString(data: string, algorithm: string): Promise<string>;
23
+ generateKeyPairMlKem(seedBytes?: Uint8Array, crv?: MlkemCurve): Promise<{
24
+ publicJWKey: MlkemPublicJwk & {
25
+ kid: string;
26
+ };
27
+ secretKeyBytes: Uint8Array;
28
+ }>;
29
+ generateKeyPairMlDsa(seedBytes?: Uint8Array, alg?: MldsaAlg): Promise<{
30
+ publicJWKey: MldsaPublicJwk & {
31
+ kid: string;
32
+ };
33
+ secretKeyBytes: Uint8Array;
34
+ }>;
35
+ encryptJwe(payload: object, protectedHeader: object, secretJWKey: MlkemPrivateJwk, recipientsJWKeys: MlkemPublicJwk[]): Promise<JweObject>;
36
+ encryptJweToCompact(payload: object | string, protectedHeader: object, secretJWKey: MlkemPrivateJwk, recipientJWKey: MlkemPublicJwk): Promise<string>;
37
+ decryptJwe(jwe: JweObject | string, secretKeyJwk: MlkemPrivateJwk): Promise<{
38
+ decryptedBytes: Uint8Array;
39
+ protectedHeader: object;
40
+ }>;
41
+ getRecipientKidsFromJwe(jwe: JweObject | string): string[];
42
+ signDataJws(payload: object, protectedHeader: object, secretKeyBytes: Uint8Array): Promise<JwtCompactParts>;
43
+ verifyJws(jws: JwtCompactParts | string, publicJwk: PublicJwk): Promise<boolean>;
44
+ verifyDetachedJws(payloadBytes: Uint8Array, detachedJws: string, publicJWKey: PublicJwk): Promise<boolean>;
45
+ encrypt(plaintext: string, cekBytes: Uint8Array, aad: string): Promise<ProtectedDataAES>;
46
+ decrypt(encryptedData: ProtectedDataAES, cekBytes: Uint8Array, aad: string): Promise<string>;
47
+ encapsulate(cekSeedBytes: Uint8Array, secretKeyBytes: Uint8Array, recipientPublicKeyBytes: Uint8Array): Promise<{
48
+ encapsulatedCekBytes: Uint8Array;
49
+ derivedCekBytes: Uint8Array;
50
+ }>;
51
+ decapsulate(encapsulatedBytes: Uint8Array, secretKeyBytes: Uint8Array): Promise<Uint8Array>;
52
+ signBytes(payloadBytes: Uint8Array, secretKeyBytes: Uint8Array, alg: MldsaAlg): Promise<Uint8Array>;
53
+ verifyBytes(signatureBytes: Uint8Array, dataBytes: Uint8Array, publicKey: PublicJwk): Promise<boolean>;
54
+ jwsToCompact(jws: DataCompactJWT): string;
55
+ parseCompactJws(jwsString: string): DataCompactJWT;
56
+ parseCompactJwe(jweString: string): JweObject;
57
+ /**
58
+ * Computes a JWK thumbprint using a specified hash algorithm.
59
+ * This implementation is platform-agnostic by using the injected ICryptoHelper.
60
+ */
61
+ private _computeJwkThumbprint;
62
+ /**
63
+ * Creates a canonical string from a simple, flat JSON object as required by
64
+ * RFC 7638 for JWK thumbprints.
65
+ */
66
+ private _canonicalizeForJwkThumbprint;
67
+ /**
68
+ * Extracts the Base JWK for thumbprint calculation per RFC 7638.
69
+ * This handles both Post-Quantum (OKP, AKP) and legacy (EC) key types.
70
+ */
71
+ private _toBaseJwk;
72
+ /**
73
+ * Utility to convert a hex string to a Uint8Array.
74
+ */
75
+ private _hexToBytes;
76
+ }
@@ -0,0 +1,403 @@
1
+ // Copyright 2025 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ // File: crypto-ts/CryptographyService.ts
3
+ import * as pako from 'pako';
4
+ import * as jwtUtils from './utils/jwt.js';
5
+ import { AesManager } from './AesManager.js';
6
+ import { Content } from './utils/content.js';
7
+ /**
8
+ * Implements the ICryptography interface, providing a complete suite of low-level,
9
+ * stateless cryptographic functions. This service is the "engine" of the security layer,
10
+ * orchestrating Post-Quantum and AES primitives.
11
+ */
12
+ export class CryptographyService {
13
+ aesManager;
14
+ cryptoHelper;
15
+ mlDsaModule = null;
16
+ mlKemModule = null;
17
+ // Constants for seed sizes, as per @noble library requirements.
18
+ ML_KEM_SEED_SIZE = 64;
19
+ ML_DSA_SEED_SIZE = 32;
20
+ constructor(cryptoHelper) {
21
+ this.aesManager = new AesManager();
22
+ this.cryptoHelper = cryptoHelper;
23
+ }
24
+ async loadMlDsa() {
25
+ if (this.mlDsaModule)
26
+ return this.mlDsaModule;
27
+ try {
28
+ // Use explicit .js subpath to satisfy package exports in Metro/Node ESM.
29
+ const module = await import('@noble/post-quantum/ml-dsa.js');
30
+ this.mlDsaModule = module;
31
+ return module;
32
+ }
33
+ catch (error) {
34
+ throw new Error('[CryptographyService] Missing dependency "@noble/post-quantum/ml-dsa.js". Install it for ML-DSA operations.');
35
+ }
36
+ }
37
+ async loadMlKem() {
38
+ if (this.mlKemModule)
39
+ return this.mlKemModule;
40
+ try {
41
+ // Use explicit .js subpath to satisfy package exports in Metro/Node ESM.
42
+ const module = await import('@noble/post-quantum/ml-kem.js');
43
+ this.mlKemModule = module;
44
+ return module;
45
+ }
46
+ catch (error) {
47
+ throw new Error('[CryptographyService] Missing dependency "@noble/post-quantum/ml-kem.js". Install it for ML-KEM operations.');
48
+ }
49
+ }
50
+ digestString(data, algorithm) {
51
+ return this.cryptoHelper.digestString(data, algorithm);
52
+ }
53
+ // --- Key Generation ---
54
+ async generateKeyPairMlKem(seedBytes, crv = 'ML-KEM-768') {
55
+ const mlKem = await this.loadMlKem();
56
+ let seed;
57
+ if (seedBytes && seedBytes.length === this.ML_KEM_SEED_SIZE) {
58
+ seed = seedBytes;
59
+ }
60
+ else {
61
+ seed = await this.cryptoHelper.getRandomBytes(this.ML_KEM_SEED_SIZE);
62
+ }
63
+ let keygenFn;
64
+ switch (crv) {
65
+ case 'ML-KEM-512':
66
+ keygenFn = mlKem.ml_kem512.keygen;
67
+ break;
68
+ case 'ML-KEM-1024':
69
+ keygenFn = mlKem.ml_kem1024.keygen;
70
+ break;
71
+ case 'ML-KEM-768':
72
+ default:
73
+ keygenFn = mlKem.ml_kem768.keygen;
74
+ break;
75
+ }
76
+ const { secretKey, publicKey: publicKeyBytes } = keygenFn(seed);
77
+ const pubJwkWithoutKid = {
78
+ kty: 'OKP', crv: crv, x: Content.bytesToRawBase64UrlSafe(publicKeyBytes),
79
+ };
80
+ const kid = await this._computeJwkThumbprint(pubJwkWithoutKid);
81
+ const publicKey = { ...pubJwkWithoutKid, kid };
82
+ return { publicJWKey: publicKey, secretKeyBytes: secretKey };
83
+ }
84
+ async generateKeyPairMlDsa(seedBytes, alg = 'ML-DSA-44') {
85
+ const mlDsa = await this.loadMlDsa();
86
+ let seed;
87
+ if (seedBytes && seedBytes.length === this.ML_DSA_SEED_SIZE) {
88
+ seed = seedBytes;
89
+ }
90
+ else {
91
+ seed = await this.cryptoHelper.getRandomBytes(this.ML_DSA_SEED_SIZE);
92
+ }
93
+ let keygenFn;
94
+ switch (alg) {
95
+ case 'ML-DSA-65':
96
+ keygenFn = mlDsa.ml_dsa65.keygen;
97
+ break;
98
+ case 'ML-DSA-87':
99
+ keygenFn = mlDsa.ml_dsa87.keygen;
100
+ break;
101
+ case 'ML-DSA-44':
102
+ default:
103
+ keygenFn = mlDsa.ml_dsa44.keygen;
104
+ break;
105
+ }
106
+ const { secretKey, publicKey: publicKeyBytes } = keygenFn(seed);
107
+ const pubJwkWithoutKid = {
108
+ kty: 'AKP', alg: alg, pub: Content.bytesToRawBase64UrlSafe(publicKeyBytes),
109
+ };
110
+ const kid = await this._computeJwkThumbprint(pubJwkWithoutKid);
111
+ const publicKey = { ...pubJwkWithoutKid, kid };
112
+ return { publicJWKey: publicKey, secretKeyBytes: secretKey };
113
+ }
114
+ // --- High-Level Workflows ---
115
+ async encryptJwe(payload, protectedHeader, secretJWKey, recipientsJWKeys) {
116
+ // ARCHITECTURAL NOTE: This implementation is currently only suitable for a single recipient.
117
+ // A Key Encapsulation Mechanism (KEM) derives a *different* shared secret for each recipient's public key.
118
+ // A true multi-recipient JWE requires a single Content Encryption Key (CEK) that is then
119
+ // encrypted (wrapped) for each recipient. This code uses the KEM-derived shared secret as the CEK.
120
+ // This must be refactored to a key-wrapping approach to support multiple recipients correctly.
121
+ if (recipientsJWKeys.length !== 1) {
122
+ // Temporarily throw until the architecture is fixed for multi-recipient.
123
+ throw new Error("CryptographyService.encryptJwe currently only supports a single recipient.");
124
+ }
125
+ const recipient = recipientsJWKeys[0];
126
+ const publicKeyBytes = Content.base64ToBytes(recipient.x);
127
+ // Per RFC 9278, we generate a random seed for the KEM. The KEM then derives both the
128
+ // final Content Encryption Key (CEK) and the encapsulated key from this seed.
129
+ const cekSeedBytes = await this.cryptoHelper.getRandomBytes(32);
130
+ const { derivedCekBytes, // This is the actual Content Encryption Key
131
+ encapsulatedCekBytes // This is the encrypted key for the recipient
132
+ } = await this.encapsulate(cekSeedBytes, secretJWKey.dBytes, publicKeyBytes);
133
+ // 2. Now, use the *derived* CEK to encrypt the payload with AES.
134
+ const protectedHeaderB64Url = Content.objectToRawBase64UrlSafe(protectedHeader);
135
+ let payloadBytes = Content.objectToBytes(payload);
136
+ let payloadString;
137
+ if (protectedHeader.zip === 'DEF') {
138
+ payloadBytes = pako.deflate(payloadBytes);
139
+ payloadString = Content.bytesToRawBase64UrlSafe(payloadBytes);
140
+ }
141
+ else {
142
+ payloadString = Content.bytesToStringASCII(payloadBytes);
143
+ }
144
+ const encrypted = await this.encrypt(payloadString, derivedCekBytes, protectedHeaderB64Url);
145
+ // 3. Assemble the JWE. The `encrypted_key` is the result of the KEM encapsulation.
146
+ const recipientData = [{
147
+ header: { alg: recipient.crv, kid: recipient.kid },
148
+ encrypted_key: Content.bytesToRawBase64UrlSafe(encapsulatedCekBytes),
149
+ }];
150
+ return {
151
+ protected: protectedHeaderB64Url,
152
+ recipients: recipientData,
153
+ iv: encrypted.iv,
154
+ ciphertext: encrypted.ciphertext,
155
+ tag: encrypted.tag,
156
+ };
157
+ }
158
+ async encryptJweToCompact(payload, protectedHeader, secretJWKey, recipientJWKey) {
159
+ // 1. Construct the complete, final protected header by merging the main and recipient headers.
160
+ const recipientHeader = { alg: recipientJWKey.crv, kid: recipientJWKey.kid };
161
+ const finalProtectedHeader = { ...protectedHeader, ...recipientHeader };
162
+ const protectedHeaderB64Url = Content.objectToRawBase64UrlSafe(finalProtectedHeader);
163
+ // 2. Perform KEM to derive the Content Encryption Key (CEK).
164
+ const publicKeyBytes = Content.base64ToBytes(recipientJWKey.x);
165
+ const cekSeedBytes = await this.cryptoHelper.getRandomBytes(32);
166
+ const { derivedCekBytes, encapsulatedCekBytes } = await this.encapsulate(cekSeedBytes, secretJWKey.dBytes, publicKeyBytes);
167
+ const encapsulatedKeyB64Url = Content.bytesToRawBase64UrlSafe(encapsulatedCekBytes);
168
+ // 3. Encrypt the payload using the derived CEK and the *final* protected header as AAD.
169
+ const payloadBytes = typeof payload === 'string'
170
+ ? Content.stringToBytesUTF8(payload)
171
+ : Content.objectToBytes(payload);
172
+ if (finalProtectedHeader.zip === 'DEF') {
173
+ // Note: Compressing a compact JWS string is often inefficient, but supported.
174
+ const compressedPayload = pako.deflate(payloadBytes);
175
+ const payloadString = Content.bytesToRawBase64UrlSafe(compressedPayload);
176
+ const encrypted = await this.encrypt(payloadString, derivedCekBytes, protectedHeaderB64Url);
177
+ return `${protectedHeaderB64Url}.${encapsulatedKeyB64Url}.${encrypted.iv}.${encrypted.ciphertext}.${encrypted.tag}`;
178
+ }
179
+ const payloadString = Content.bytesToStringASCII(payloadBytes);
180
+ const encrypted = await this.encrypt(payloadString, derivedCekBytes, protectedHeaderB64Url);
181
+ // 4. Assemble the 5 parts of the compact JWE.
182
+ return `${protectedHeaderB64Url}.${encapsulatedKeyB64Url}.${encrypted.iv}.${encrypted.ciphertext}.${encrypted.tag}`;
183
+ }
184
+ async decryptJwe(jwe, secretKeyJwk) {
185
+ const jweObject = typeof jwe === 'string' ? this.parseCompactJwe(jwe) : jwe;
186
+ const recipient = jweObject.recipients.find(r => r.header?.kid === secretKeyJwk.kid);
187
+ if (!recipient || !recipient.encrypted_key) {
188
+ throw new Error(`JWE does not contain a recipient with kid=${secretKeyJwk.kid}`);
189
+ }
190
+ // Decapsulate to get the CEK
191
+ const encapsulatedKeyBytes = Content.base64ToBytes(recipient.encrypted_key);
192
+ const cekBytes = await this.decapsulate(encapsulatedKeyBytes, secretKeyJwk.dBytes);
193
+ // Decrypt the payload
194
+ const encryptedData = { ciphertext: jweObject.ciphertext, iv: jweObject.iv, tag: jweObject.tag };
195
+ const decryptedPayloadString = await this.decrypt(encryptedData, cekBytes, jweObject.protected);
196
+ // Handle decompression
197
+ const protectedHeader = Content.base64UrlSafeToJSON(jweObject.protected);
198
+ let decryptedBytes;
199
+ if (protectedHeader.zip === 'DEF') {
200
+ const compressedBytes = Content.base64ToBytes(decryptedPayloadString);
201
+ decryptedBytes = pako.inflate(compressedBytes);
202
+ }
203
+ else {
204
+ decryptedBytes = Content.stringToBytesUTF8(decryptedPayloadString);
205
+ }
206
+ return { decryptedBytes, protectedHeader };
207
+ }
208
+ getRecipientKidsFromJwe(jwe) {
209
+ const jweObject = typeof jwe === 'string' ? this.parseCompactJwe(jwe) : jwe;
210
+ if (!jweObject.recipients) {
211
+ return [];
212
+ }
213
+ return jweObject.recipients
214
+ .map(recipient => recipient.header?.kid)
215
+ .filter((kid) => !!kid);
216
+ }
217
+ async signDataJws(payload, protectedHeader, secretKeyBytes) {
218
+ const protectedHeaderB64Url = Content.objectToRawBase64UrlSafe(protectedHeader);
219
+ const payloadB64Url = await jwtUtils.encodePayload(payload);
220
+ const signingInput = `${protectedHeaderB64Url}.${payloadB64Url}`;
221
+ const signingInputBytes = Content.stringToBytesUTF8(signingInput);
222
+ // Infer algorithm from protected header
223
+ const alg = protectedHeader.alg;
224
+ if (!alg)
225
+ throw new Error("Protected header must contain 'alg' property for signing.");
226
+ const signatureBytes = await this.signBytes(signingInputBytes, secretKeyBytes, alg);
227
+ const jwsParts = {
228
+ protected: protectedHeaderB64Url,
229
+ payload: payloadB64Url,
230
+ signature: Content.bytesToRawBase64UrlSafe(signatureBytes),
231
+ };
232
+ return jwsParts;
233
+ }
234
+ async verifyJws(jws, publicJwk) {
235
+ const parts = typeof jws === 'string' ? jwtUtils.getPartsJWT(jws) : jws;
236
+ if (!parts)
237
+ throw new Error('Invalid Compact JWS format');
238
+ const signingInput = `${parts.protected}.${parts.payload}`;
239
+ const signingInputBytes = Content.stringToBytesUTF8(signingInput);
240
+ const signatureBytes = Content.base64ToBytes(parts.signature);
241
+ return this.verifyBytes(signatureBytes, signingInputBytes, publicJwk);
242
+ }
243
+ async verifyDetachedJws(payloadBytes, detachedJws, publicJWKey) {
244
+ const parts = detachedJws.split('..');
245
+ if (parts.length !== 2)
246
+ throw new Error("Invalid Detached JWS format");
247
+ const protectedHeaderB64Url = parts[0];
248
+ const signatureB64Url = parts[1];
249
+ const payloadB64Url = Content.bytesToRawBase64UrlSafe(payloadBytes);
250
+ const signingInput = `${protectedHeaderB64Url}.${payloadB64Url}`;
251
+ const signingInputBytes = Content.stringToBytesUTF8(signingInput);
252
+ const signatureBytes = Content.base64ToBytes(signatureB64Url);
253
+ return this.verifyBytes(signatureBytes, signingInputBytes, publicJWKey);
254
+ }
255
+ // --- Low-Level Primitives ---
256
+ encrypt(plaintext, cekBytes, aad) {
257
+ return this.aesManager.encrypt(plaintext, cekBytes, aad);
258
+ }
259
+ decrypt(encryptedData, cekBytes, aad) {
260
+ return this.aesManager.decrypt(encryptedData, cekBytes, aad);
261
+ }
262
+ async encapsulate(cekSeedBytes, secretKeyBytes, recipientPublicKeyBytes) {
263
+ // According to RFC 9278 (JWE with ML-KEM), a seed is used for the KEM encapsulation.
264
+ // The KEM then derives a shared secret from this seed. It is this *derived* shared secret
265
+ // that is used to encrypt the content, NOT the original seed.
266
+ // The `encapsulate` function from the noble library handles this correctly by accepting the
267
+ // seed as the second argument. It returns both the encapsulated key (`cipherText`)
268
+ // and the derived shared secret, which we must use as the actual AES key.
269
+ const mlKem = await this.loadMlKem();
270
+ const { sharedSecret, cipherText } = await mlKem.ml_kem768.encapsulate(recipientPublicKeyBytes, cekSeedBytes);
271
+ return { derivedCekBytes: sharedSecret, encapsulatedCekBytes: cipherText };
272
+ }
273
+ async decapsulate(encapsulatedBytes, secretKeyBytes) {
274
+ const mlKem = await this.loadMlKem();
275
+ return mlKem.ml_kem768.decapsulate(encapsulatedBytes, secretKeyBytes);
276
+ }
277
+ async signBytes(payloadBytes, secretKeyBytes, alg) {
278
+ const mlDsa = await this.loadMlDsa();
279
+ switch (alg) {
280
+ case 'ML-DSA-44': return mlDsa.ml_dsa44.sign(payloadBytes, secretKeyBytes);
281
+ case 'ML-DSA-65': return mlDsa.ml_dsa65.sign(payloadBytes, secretKeyBytes);
282
+ case 'ML-DSA-87': return mlDsa.ml_dsa87.sign(payloadBytes, secretKeyBytes);
283
+ default: throw new Error(`Unsupported ML-DSA algorithm: ${alg}`);
284
+ }
285
+ }
286
+ async verifyBytes(signatureBytes, dataBytes, publicKey) {
287
+ const mlDsa = await this.loadMlDsa();
288
+ const publicKeyBytes = Content.base64ToBytes(publicKey.pub || publicKey.x);
289
+ const alg = publicKey.alg;
290
+ if (!alg)
291
+ throw new Error("Public key must contain 'alg' property for verification.");
292
+ switch (alg) {
293
+ case 'ML-DSA-44': return mlDsa.ml_dsa44.verify(signatureBytes, dataBytes, publicKeyBytes);
294
+ case 'ML-DSA-65': return mlDsa.ml_dsa65.verify(signatureBytes, dataBytes, publicKeyBytes);
295
+ case 'ML-DSA-87': return mlDsa.ml_dsa87.verify(signatureBytes, dataBytes, publicKeyBytes);
296
+ default: throw new Error(`Unsupported ML-DSA algorithm: ${alg}`);
297
+ }
298
+ }
299
+ // --- Formatting & Parsing Utilities ---
300
+ jwsToCompact(jws) {
301
+ return `${jws.protected}.${jws.payload}.${jws.signature}`;
302
+ }
303
+ parseCompactJws(jwsString) {
304
+ if (jwsString.trim().startsWith('{')) {
305
+ const parsed = JSON.parse(jwsString);
306
+ if (!parsed.payload || !parsed.signatures || !parsed.signatures[0]) {
307
+ throw new Error("Invalid JWS JSON format");
308
+ }
309
+ return {
310
+ payload: parsed.payload,
311
+ protected: parsed.signatures[0].protected,
312
+ signature: parsed.signatures[0].signature,
313
+ };
314
+ }
315
+ const parts = jwtUtils.getPartsJWT(jwsString);
316
+ if (!parts)
317
+ throw new Error("Invalid Compact JWS format");
318
+ const result = {
319
+ payload: Content.base64UrlSafeToJSON(parts.payload),
320
+ protected: Content.base64UrlSafeToJSON(parts.protected),
321
+ signature: Content.base64ToBytes(parts.signature),
322
+ };
323
+ return result;
324
+ }
325
+ parseCompactJwe(jweString) {
326
+ if (jweString.trim().startsWith('{')) {
327
+ return JSON.parse(jweString);
328
+ }
329
+ const parts = jweString.split('.');
330
+ if (parts.length !== 5)
331
+ throw new Error("Invalid Compact JWE format");
332
+ const protectedHeader = Content.base64UrlSafeToJSON(parts[0]);
333
+ // Compact JWE has no per-recipient header, but our model requires one.
334
+ // The 'kid' should be in the main protected header for decryption to work.
335
+ return {
336
+ protected: parts[0],
337
+ recipients: [{
338
+ header: { alg: protectedHeader.alg || '', kid: protectedHeader.kid || '' },
339
+ encrypted_key: parts[1]
340
+ }],
341
+ iv: parts[2],
342
+ ciphertext: parts[3],
343
+ tag: parts[4],
344
+ };
345
+ }
346
+ // --- JWK Thumbprint Calculation (RFC 7638) ---
347
+ /**
348
+ * Computes a JWK thumbprint using a specified hash algorithm.
349
+ * This implementation is platform-agnostic by using the injected ICryptoHelper.
350
+ */
351
+ async _computeJwkThumbprint(jwk, hash = "SHA-256") {
352
+ const baseJwk = this._toBaseJwk(jwk);
353
+ const canonical = this._canonicalizeForJwkThumbprint(baseJwk);
354
+ // Use the platform-agnostic digest method
355
+ const digestHex = await this.cryptoHelper.digestString(canonical, hash);
356
+ // The digestString returns a hex string, but thumbprints are Base64UrlSafe.
357
+ // We need to convert from hex to bytes, then bytes to Base64UrlSafe.
358
+ const digestBytes = this._hexToBytes(digestHex);
359
+ return Content.bytesToRawBase64UrlSafe(digestBytes);
360
+ }
361
+ /**
362
+ * Creates a canonical string from a simple, flat JSON object as required by
363
+ * RFC 7638 for JWK thumbprints.
364
+ */
365
+ _canonicalizeForJwkThumbprint(obj) {
366
+ const keys = Object.keys(obj).sort();
367
+ const parts = keys.map(k => `"${k}":${JSON.stringify(obj[k])}`);
368
+ return `{${parts.join(",")}}`;
369
+ }
370
+ /**
371
+ * Extracts the Base JWK for thumbprint calculation per RFC 7638.
372
+ * This handles both Post-Quantum (OKP, AKP) and legacy (EC) key types.
373
+ */
374
+ _toBaseJwk(jwk) {
375
+ if (jwk.kty === "OKP") {
376
+ const { crv, x } = jwk;
377
+ return { kty: "OKP", crv, x };
378
+ }
379
+ else if (jwk.kty === "AKP") {
380
+ const { alg, pub } = jwk;
381
+ return { kty: "AKP", alg, pub };
382
+ }
383
+ else if (jwk.kty === "EC") {
384
+ const { crv, x, y } = jwk;
385
+ const baseJwk = { kty: "EC", crv, x, y };
386
+ return baseJwk;
387
+ }
388
+ else {
389
+ const exhaustiveCheck = jwk;
390
+ throw new Error(`Unsupported key type for JWK thumbprint: ${exhaustiveCheck.kty}`);
391
+ }
392
+ }
393
+ /**
394
+ * Utility to convert a hex string to a Uint8Array.
395
+ */
396
+ _hexToBytes(hex) {
397
+ const bytes = new Uint8Array(hex.length / 2);
398
+ for (let i = 0; i < hex.length; i += 2) {
399
+ bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
400
+ }
401
+ return bytes;
402
+ }
403
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Defines the types of form requests that can be sent in a batch.
3
+ */
4
+ export declare const FormRequestType: {
5
+ readonly IndividualTerms: "IndividualTerms";
6
+ readonly PersonalIdentity: "PersonalIdentity";
7
+ };
8
+ export declare const Sector: {
9
+ readonly EMERGENCY: "emergency";
10
+ readonly HEALTH_CARE: "health-care";
11
+ readonly HEALTH_INSURANCE: "health-insurance";
12
+ readonly RESEARCH: "research";
13
+ };
14
+ export type Sector = typeof Sector[keyof typeof Sector];
15
+ export declare const Section: {
16
+ readonly REGISTRY: "registry";
17
+ readonly ENTITY: "entity";
18
+ readonly INDIVIDUAL: "individual";
19
+ readonly NETWORK: "network";
20
+ };
21
+ export type Section = typeof Section[keyof typeof Section];
22
+ export declare const Format: {
23
+ readonly SCHEMA: "org.schema";
24
+ readonly FHIR_API: "org.hl7.fhir.api";
25
+ };
26
+ export type Format = typeof Format[keyof typeof Format];
27
+ export declare const Resource: {
28
+ readonly PERSON: "Person";
29
+ readonly RELATED_PERSON: "RelatedPerson";
30
+ readonly EMPLOYEE: "Employee";
31
+ readonly EMPLOYEE_ROLE: "EmployeeRole";
32
+ readonly PRACTITIONER: "Practitioner";
33
+ readonly PRACTITIONER_ROLE: "PractitionerRole";
34
+ readonly ORGANIZATION: "Organization";
35
+ readonly LOCATION: "Location";
36
+ readonly GROUP: "Group";
37
+ };
38
+ export type Resource = typeof Resource[keyof typeof Resource];
39
+ export declare const JobAction: {
40
+ readonly BATCH: "_batch";
41
+ readonly CREATE: "_create";
42
+ readonly DISCOVERY: "_discovery";
43
+ };
44
+ export type JobAction = typeof JobAction[keyof typeof JobAction];
45
+ export declare const knownDomainsReversed: readonly ["org.schema", "org.hl7.fhir", "org.ilo.isco", "net.openid"];
@@ -0,0 +1,48 @@
1
+ // constants/Schemas.ts
2
+ // Based on the backend's src/models/schemaorg.ts
3
+ /**
4
+ * Defines the types of form requests that can be sent in a batch.
5
+ */
6
+ export const FormRequestType = {
7
+ IndividualTerms: 'IndividualTerms',
8
+ PersonalIdentity: 'PersonalIdentity',
9
+ };
10
+ // --- Enums for URL construction and validation ---
11
+ export const Sector = {
12
+ EMERGENCY: 'emergency',
13
+ HEALTH_CARE: 'health-care',
14
+ HEALTH_INSURANCE: 'health-insurance',
15
+ RESEARCH: 'research',
16
+ };
17
+ export const Section = {
18
+ REGISTRY: 'registry',
19
+ ENTITY: 'entity',
20
+ INDIVIDUAL: 'individual',
21
+ NETWORK: 'network',
22
+ };
23
+ export const Format = {
24
+ SCHEMA: 'org.schema',
25
+ FHIR_API: 'org.hl7.fhir.api',
26
+ };
27
+ export const Resource = {
28
+ PERSON: 'Person',
29
+ RELATED_PERSON: 'RelatedPerson',
30
+ EMPLOYEE: 'Employee',
31
+ EMPLOYEE_ROLE: 'EmployeeRole',
32
+ PRACTITIONER: 'Practitioner',
33
+ PRACTITIONER_ROLE: 'PractitionerRole',
34
+ ORGANIZATION: 'Organization',
35
+ LOCATION: 'Location',
36
+ GROUP: 'Group',
37
+ };
38
+ export const JobAction = {
39
+ BATCH: '_batch',
40
+ CREATE: '_create',
41
+ DISCOVERY: '_discovery',
42
+ };
43
+ export const knownDomainsReversed = [
44
+ 'org.schema',
45
+ 'org.hl7.fhir',
46
+ 'org.ilo.isco',
47
+ 'net.openid',
48
+ ];
@@ -0,0 +1 @@
1
+ export * from './schemaorg.js';