@decaf-ts/for-fabric 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +647 -0
  3. package/dist/for-fabric.cjs +6223 -0
  4. package/dist/for-fabric.esm.cjs +6180 -0
  5. package/lib/client/FabricClientAdapter.cjs +760 -0
  6. package/lib/client/FabricClientAdapter.d.ts +381 -0
  7. package/lib/client/FabricClientDispatch.cjs +186 -0
  8. package/lib/client/FabricClientDispatch.d.ts +125 -0
  9. package/lib/client/FabricClientRepository.cjs +131 -0
  10. package/lib/client/FabricClientRepository.d.ts +100 -0
  11. package/lib/client/erc20/erc20ClientRepository.cjs +343 -0
  12. package/lib/client/erc20/erc20ClientRepository.d.ts +254 -0
  13. package/lib/client/fabric-fs.cjs +234 -0
  14. package/lib/client/fabric-fs.d.ts +92 -0
  15. package/lib/client/index.cjs +30 -0
  16. package/lib/client/index.d.ts +13 -0
  17. package/lib/client/logging.cjs +102 -0
  18. package/lib/client/logging.d.ts +60 -0
  19. package/lib/client/services/LoggedService.cjs +47 -0
  20. package/lib/client/services/LoggedService.d.ts +42 -0
  21. package/lib/client/services/constants.cjs +3 -0
  22. package/lib/client/services/constants.d.ts +15 -0
  23. package/lib/client/services/enrollementService.cjs +344 -0
  24. package/lib/client/services/enrollementService.d.ts +176 -0
  25. package/lib/client/services/index.cjs +18 -0
  26. package/lib/client/services/index.d.ts +1 -0
  27. package/lib/contracts/ContractAdapter.cjs +730 -0
  28. package/lib/contracts/ContractAdapter.d.ts +296 -0
  29. package/lib/contracts/ContractContext.cjs +85 -0
  30. package/lib/contracts/ContractContext.d.ts +64 -0
  31. package/lib/contracts/ContractPrivateDataAdapter.cjs +281 -0
  32. package/lib/contracts/ContractPrivateDataAdapter.d.ts +74 -0
  33. package/lib/contracts/FabricConstruction.cjs +441 -0
  34. package/lib/contracts/FabricConstruction.d.ts +304 -0
  35. package/lib/contracts/FabricContractRepository.cjs +306 -0
  36. package/lib/contracts/FabricContractRepository.d.ts +162 -0
  37. package/lib/contracts/FabricContractRepositoryObservableHandler.cjs +85 -0
  38. package/lib/contracts/FabricContractRepositoryObservableHandler.d.ts +62 -0
  39. package/lib/contracts/FabricContractSequence.cjs +139 -0
  40. package/lib/contracts/FabricContractSequence.d.ts +61 -0
  41. package/lib/contracts/FabricContractStatement.cjs +119 -0
  42. package/lib/contracts/FabricContractStatement.d.ts +34 -0
  43. package/lib/contracts/PrivateSequence.cjs +36 -0
  44. package/lib/contracts/PrivateSequence.d.ts +15 -0
  45. package/lib/contracts/crud/crud-contract.cjs +257 -0
  46. package/lib/contracts/crud/crud-contract.d.ts +168 -0
  47. package/lib/contracts/crud/index.cjs +19 -0
  48. package/lib/contracts/crud/index.d.ts +2 -0
  49. package/lib/contracts/crud/serialized-crud-contract.cjs +172 -0
  50. package/lib/contracts/crud/serialized-crud-contract.d.ts +37 -0
  51. package/lib/contracts/erc20/erc20contract.cjs +569 -0
  52. package/lib/contracts/erc20/erc20contract.d.ts +151 -0
  53. package/lib/contracts/erc20/index.cjs +21 -0
  54. package/lib/contracts/erc20/index.d.ts +2 -0
  55. package/lib/contracts/erc20/models.cjs +209 -0
  56. package/lib/contracts/erc20/models.d.ts +114 -0
  57. package/lib/contracts/index.cjs +32 -0
  58. package/lib/contracts/index.d.ts +15 -0
  59. package/lib/contracts/logging.cjs +96 -0
  60. package/lib/contracts/logging.d.ts +49 -0
  61. package/lib/contracts/private-data.cjs +121 -0
  62. package/lib/contracts/private-data.d.ts +16 -0
  63. package/lib/contracts/types.cjs +3 -0
  64. package/lib/contracts/types.d.ts +26 -0
  65. package/lib/esm/client/FabricClientAdapter.d.ts +381 -0
  66. package/lib/esm/client/FabricClientAdapter.js +723 -0
  67. package/lib/esm/client/FabricClientDispatch.d.ts +125 -0
  68. package/lib/esm/client/FabricClientDispatch.js +182 -0
  69. package/lib/esm/client/FabricClientRepository.d.ts +100 -0
  70. package/lib/esm/client/FabricClientRepository.js +127 -0
  71. package/lib/esm/client/erc20/erc20ClientRepository.d.ts +254 -0
  72. package/lib/esm/client/erc20/erc20ClientRepository.js +339 -0
  73. package/lib/esm/client/fabric-fs.d.ts +92 -0
  74. package/lib/esm/client/fabric-fs.js +191 -0
  75. package/lib/esm/client/index.d.ts +13 -0
  76. package/lib/esm/client/index.js +14 -0
  77. package/lib/esm/client/logging.d.ts +60 -0
  78. package/lib/esm/client/logging.js +98 -0
  79. package/lib/esm/client/services/LoggedService.d.ts +42 -0
  80. package/lib/esm/client/services/LoggedService.js +43 -0
  81. package/lib/esm/client/services/constants.d.ts +15 -0
  82. package/lib/esm/client/services/constants.js +2 -0
  83. package/lib/esm/client/services/enrollementService.d.ts +176 -0
  84. package/lib/esm/client/services/enrollementService.js +337 -0
  85. package/lib/esm/client/services/index.d.ts +1 -0
  86. package/lib/esm/client/services/index.js +2 -0
  87. package/lib/esm/contracts/ContractAdapter.d.ts +296 -0
  88. package/lib/esm/contracts/ContractAdapter.js +724 -0
  89. package/lib/esm/contracts/ContractContext.d.ts +64 -0
  90. package/lib/esm/contracts/ContractContext.js +81 -0
  91. package/lib/esm/contracts/ContractPrivateDataAdapter.d.ts +74 -0
  92. package/lib/esm/contracts/ContractPrivateDataAdapter.js +277 -0
  93. package/lib/esm/contracts/FabricConstruction.d.ts +304 -0
  94. package/lib/esm/contracts/FabricConstruction.js +433 -0
  95. package/lib/esm/contracts/FabricContractRepository.d.ts +162 -0
  96. package/lib/esm/contracts/FabricContractRepository.js +302 -0
  97. package/lib/esm/contracts/FabricContractRepositoryObservableHandler.d.ts +62 -0
  98. package/lib/esm/contracts/FabricContractRepositoryObservableHandler.js +81 -0
  99. package/lib/esm/contracts/FabricContractSequence.d.ts +61 -0
  100. package/lib/esm/contracts/FabricContractSequence.js +135 -0
  101. package/lib/esm/contracts/FabricContractStatement.d.ts +34 -0
  102. package/lib/esm/contracts/FabricContractStatement.js +115 -0
  103. package/lib/esm/contracts/PrivateSequence.d.ts +15 -0
  104. package/lib/esm/contracts/PrivateSequence.js +33 -0
  105. package/lib/esm/contracts/crud/crud-contract.d.ts +168 -0
  106. package/lib/esm/contracts/crud/crud-contract.js +253 -0
  107. package/lib/esm/contracts/crud/index.d.ts +2 -0
  108. package/lib/esm/contracts/crud/index.js +3 -0
  109. package/lib/esm/contracts/crud/serialized-crud-contract.d.ts +37 -0
  110. package/lib/esm/contracts/crud/serialized-crud-contract.js +168 -0
  111. package/lib/esm/contracts/erc20/erc20contract.d.ts +151 -0
  112. package/lib/esm/contracts/erc20/erc20contract.js +565 -0
  113. package/lib/esm/contracts/erc20/index.d.ts +2 -0
  114. package/lib/esm/contracts/erc20/index.js +4 -0
  115. package/lib/esm/contracts/erc20/models.d.ts +114 -0
  116. package/lib/esm/contracts/erc20/models.js +206 -0
  117. package/lib/esm/contracts/index.d.ts +15 -0
  118. package/lib/esm/contracts/index.js +16 -0
  119. package/lib/esm/contracts/logging.d.ts +49 -0
  120. package/lib/esm/contracts/logging.js +92 -0
  121. package/lib/esm/contracts/private-data.d.ts +16 -0
  122. package/lib/esm/contracts/private-data.js +113 -0
  123. package/lib/esm/contracts/types.d.ts +26 -0
  124. package/lib/esm/contracts/types.js +2 -0
  125. package/lib/esm/index.d.ts +8 -0
  126. package/lib/esm/index.js +9 -0
  127. package/lib/esm/shared/ClientSerializer.d.ts +52 -0
  128. package/lib/esm/shared/ClientSerializer.js +80 -0
  129. package/lib/esm/shared/DeterministicSerializer.d.ts +40 -0
  130. package/lib/esm/shared/DeterministicSerializer.js +50 -0
  131. package/lib/esm/shared/SimpleDeterministicSerializer.d.ts +7 -0
  132. package/lib/esm/shared/SimpleDeterministicSerializer.js +42 -0
  133. package/lib/esm/shared/constants.d.ts +39 -0
  134. package/lib/esm/shared/constants.js +42 -0
  135. package/lib/esm/shared/crypto.d.ts +107 -0
  136. package/lib/esm/shared/crypto.js +331 -0
  137. package/lib/esm/shared/decorators.d.ts +24 -0
  138. package/lib/esm/shared/decorators.js +98 -0
  139. package/lib/esm/shared/erc20/erc20-constants.d.ts +25 -0
  140. package/lib/esm/shared/erc20/erc20-constants.js +27 -0
  141. package/lib/esm/shared/errors.d.ts +116 -0
  142. package/lib/esm/shared/errors.js +132 -0
  143. package/lib/esm/shared/events.d.ts +39 -0
  144. package/lib/esm/shared/events.js +47 -0
  145. package/lib/esm/shared/fabric-types.d.ts +33 -0
  146. package/lib/esm/shared/fabric-types.js +2 -0
  147. package/lib/esm/shared/index.d.ts +13 -0
  148. package/lib/esm/shared/index.js +14 -0
  149. package/lib/esm/shared/interfaces/Checkable.d.ts +21 -0
  150. package/lib/esm/shared/interfaces/Checkable.js +2 -0
  151. package/lib/esm/shared/math.d.ts +34 -0
  152. package/lib/esm/shared/math.js +61 -0
  153. package/lib/esm/shared/model/Identity.d.ts +42 -0
  154. package/lib/esm/shared/model/Identity.js +78 -0
  155. package/lib/esm/shared/model/IdentityCredentials.d.ts +41 -0
  156. package/lib/esm/shared/model/IdentityCredentials.js +74 -0
  157. package/lib/esm/shared/model/index.d.ts +1 -0
  158. package/lib/esm/shared/model/index.js +2 -0
  159. package/lib/esm/shared/model/utils.d.ts +60 -0
  160. package/lib/esm/shared/model/utils.js +108 -0
  161. package/lib/esm/shared/types.d.ts +79 -0
  162. package/lib/esm/shared/types.js +2 -0
  163. package/lib/esm/shared/utils.d.ts +55 -0
  164. package/lib/esm/shared/utils.js +148 -0
  165. package/lib/index.cjs +25 -0
  166. package/lib/index.d.ts +8 -0
  167. package/lib/shared/ClientSerializer.cjs +84 -0
  168. package/lib/shared/ClientSerializer.d.ts +52 -0
  169. package/lib/shared/DeterministicSerializer.cjs +54 -0
  170. package/lib/shared/DeterministicSerializer.d.ts +40 -0
  171. package/lib/shared/SimpleDeterministicSerializer.cjs +46 -0
  172. package/lib/shared/SimpleDeterministicSerializer.d.ts +7 -0
  173. package/lib/shared/constants.cjs +45 -0
  174. package/lib/shared/constants.d.ts +39 -0
  175. package/lib/shared/crypto.cjs +369 -0
  176. package/lib/shared/crypto.d.ts +107 -0
  177. package/lib/shared/decorators.cjs +105 -0
  178. package/lib/shared/decorators.d.ts +24 -0
  179. package/lib/shared/erc20/erc20-constants.cjs +30 -0
  180. package/lib/shared/erc20/erc20-constants.d.ts +25 -0
  181. package/lib/shared/errors.cjs +142 -0
  182. package/lib/shared/errors.d.ts +116 -0
  183. package/lib/shared/events.cjs +51 -0
  184. package/lib/shared/events.d.ts +39 -0
  185. package/lib/shared/fabric-types.cjs +4 -0
  186. package/lib/shared/fabric-types.d.ts +33 -0
  187. package/lib/shared/index.cjs +30 -0
  188. package/lib/shared/index.d.ts +13 -0
  189. package/lib/shared/interfaces/Checkable.cjs +3 -0
  190. package/lib/shared/interfaces/Checkable.d.ts +21 -0
  191. package/lib/shared/math.cjs +66 -0
  192. package/lib/shared/math.d.ts +34 -0
  193. package/lib/shared/model/Identity.cjs +81 -0
  194. package/lib/shared/model/Identity.d.ts +42 -0
  195. package/lib/shared/model/IdentityCredentials.cjs +77 -0
  196. package/lib/shared/model/IdentityCredentials.d.ts +41 -0
  197. package/lib/shared/model/index.cjs +18 -0
  198. package/lib/shared/model/index.d.ts +1 -0
  199. package/lib/shared/model/utils.cjs +114 -0
  200. package/lib/shared/model/utils.d.ts +60 -0
  201. package/lib/shared/types.cjs +3 -0
  202. package/lib/shared/types.d.ts +79 -0
  203. package/lib/shared/utils.cjs +185 -0
  204. package/lib/shared/utils.d.ts +55 -0
  205. package/package.json +166 -0
@@ -0,0 +1,148 @@
1
+ import { stringFormat } from "@decaf-ts/decorator-validation";
2
+ import { Logging } from "@decaf-ts/logging";
3
+ import { normalizeImport } from "@decaf-ts/utils";
4
+ import { signers } from "@hyperledger/fabric-gateway";
5
+ import { User } from "fabric-common";
6
+ /**
7
+ * @description Core utilities for interacting with files, crypto identities, and Fabric SDK helpers
8
+ * @summary Provides static helper methods to read credentials and keys from disk or raw content, construct Fabric gateway Identities and Signers, and perform common filesystem operations used by the Fabric client tooling.
9
+ * @class CoreUtils
10
+ * @example
11
+ * // Read an identity and signer from directories
12
+ * const identity = await CoreUtils.getIdentity('Org1MSP', '/msp/signcerts');
13
+ * const signer = await CoreUtils.getSigner('/msp/keystore');
14
+ * // Build a CA user
15
+ * const user = await CoreUtils.getCAUser('appUser', pemKey, pemCert, 'Org1MSP');
16
+ */
17
+ export class CoreUtils {
18
+ static { this.logger = Logging.for(CoreUtils.name); }
19
+ constructor() { }
20
+ /**
21
+ * @description Resolve file content from a path or return provided raw content
22
+ * @summary If the input is a Uint8Array or PEM content, returns it as-is; otherwise uses a provided async fileReader to load the content from disk.
23
+ * @param {string|Uint8Array} contentOrPath - Either a raw content buffer/string or a filesystem path
24
+ * @param {function(string): Promise<string|Uint8Array|Buffer>} fileReader - Async function to read file content when a path is provided
25
+ * @return {Promise<string|Uint8Array|Buffer>} The content to be used downstream
26
+ */
27
+ static async contentOfLoadFile(contentOrPath, fileReader) {
28
+ if (contentOrPath instanceof Uint8Array)
29
+ return contentOrPath;
30
+ if (contentOrPath.match(/-----BEGIN (CERTIFICATE|KEY|PRIVATE KEY)-----.+?-----END \1-----$/gms))
31
+ return contentOrPath;
32
+ return await fileReader(contentOrPath);
33
+ }
34
+ /**
35
+ * @description Read file content from a path or return provided Buffer
36
+ * @summary Convenience wrapper that loads a file using fs.promises when a path string is provided; otherwise returns the given Buffer directly.
37
+ * @param {string|Buffer} contentOrPath - Path to a file on disk or an already-loaded Buffer
38
+ * @return {Promise<string|Uint8Array|Buffer>} The file content as a Buffer/string depending on reader
39
+ */
40
+ static async readFile(contentOrPath) {
41
+ if (typeof contentOrPath !== "string")
42
+ return contentOrPath;
43
+ const fileReader = async (path) => {
44
+ const { promises } = await normalizeImport(import("fs"));
45
+ return await promises.readFile(path);
46
+ };
47
+ return await fileReader(contentOrPath);
48
+ }
49
+ /**
50
+ * @description Create a Fabric CA User object with enrollment
51
+ * @summary Constructs a fabric-common User, sets a crypto suite, imports the provided private key, and sets enrollment with certificate and MSP ID.
52
+ * @param {string} userName - The user name for the CA user
53
+ * @param {string} privateKey - PEM-encoded private key
54
+ * @param {string} certificate - PEM-encoded X.509 certificate
55
+ * @param {string} mspId - Membership Service Provider identifier
56
+ * @return {Promise<User>} The enrolled Fabric User instance
57
+ */
58
+ static async getCAUser(userName, privateKey, certificate, mspId) {
59
+ this.logger.debug(stringFormat("Creating CA {0} user {1} with certificate {2}", mspId, userName, certificate));
60
+ const user = new User(userName);
61
+ const cryptoSuite = User.newCryptoSuite();
62
+ user.setCryptoSuite(cryptoSuite);
63
+ const importedKey = cryptoSuite.createKeyFromRaw(privateKey);
64
+ await user.setEnrollment(importedKey, certificate, mspId);
65
+ return user;
66
+ }
67
+ /**
68
+ * @description Build a Fabric Gateway Identity from an MSP ID and certificate
69
+ * @summary Reads a certificate from a directory path or accepts raw content and returns an Identity object suitable for the Fabric Gateway.
70
+ * @param {string} mspId - Membership Service Provider ID
71
+ * @param {string} certDirectoryPath - Path to a directory containing the certificate file, or PEM content
72
+ * @return {Promise<Identity>} The identity containing mspId and certificate credentials
73
+ */
74
+ static async getIdentity(mspId, certDirectoryPath) {
75
+ const identityFileReader = async (path) => {
76
+ const { promises } = await normalizeImport(import("fs"));
77
+ const certPath = await this.getFirstDirFileName(path);
78
+ const credentials = await promises.readFile(certPath);
79
+ return credentials;
80
+ };
81
+ const credentials = (await this.contentOfLoadFile(certDirectoryPath, identityFileReader));
82
+ return { mspId, credentials };
83
+ }
84
+ static async getFirstDirFileName(dirPath) {
85
+ const { promises } = await normalizeImport(import("fs"));
86
+ const { join } = await normalizeImport(import("path"));
87
+ const files = await promises.readdir(dirPath);
88
+ return join(dirPath, files[0]);
89
+ }
90
+ static async getFirstDirFileNameContent(dirPath) {
91
+ const { promises } = await normalizeImport(import("fs"));
92
+ const { join } = await normalizeImport(import("path"));
93
+ const files = await promises.readdir(dirPath);
94
+ return (await promises.readFile(join(dirPath, files[0]))).toString();
95
+ }
96
+ static async getFileContent(filePath) {
97
+ const { promises } = await normalizeImport(import("fs"));
98
+ return (await promises.readFile(filePath)).toString();
99
+ }
100
+ static async getSigner(keyDirectoryPath) {
101
+ const signerFileReader = async (path) => {
102
+ const { promises } = await normalizeImport(import("fs"));
103
+ const keyPath = await this.getFirstDirFileName(path);
104
+ return await promises.readFile(keyPath);
105
+ };
106
+ const privateKeyPem = (await this.contentOfLoadFile(keyDirectoryPath, signerFileReader));
107
+ const privateKey = await this.extractPrivateKey(privateKeyPem);
108
+ const keys = Object.getOwnPropertySymbols(privateKey);
109
+ const k = privateKey[keys[0]];
110
+ // --
111
+ return signers.newPrivateKeySigner(k);
112
+ }
113
+ static async extractPrivateKey(pem) {
114
+ const libName = "crypto";
115
+ let subtle;
116
+ if (globalThis.window &&
117
+ globalThis.window.Crypto) {
118
+ subtle = globalThis.Crypto.subtle;
119
+ }
120
+ else {
121
+ const lib = (await normalizeImport(import(libName)));
122
+ subtle = lib.subtle || lib.webcrypto.subtle;
123
+ }
124
+ if (!subtle)
125
+ throw new Error("Could not load SubtleCrypto module");
126
+ function str2ab(str) {
127
+ const buf = new ArrayBuffer(str.length);
128
+ const bufView = new Uint8Array(buf);
129
+ for (let i = 0, strLen = str.length; i < strLen; i++) {
130
+ bufView[i] = str.charCodeAt(i);
131
+ }
132
+ return buf;
133
+ }
134
+ const str = pem
135
+ .toString("utf8")
136
+ .replace("-----BEGIN PRIVATE KEY-----", "")
137
+ .replaceAll("\n", "")
138
+ .replace("-----END PRIVATE KEY-----", "");
139
+ const decoded = Buffer.from(str, "base64").toString("binary");
140
+ const binaryDer = str2ab(decoded);
141
+ const key = await subtle.importKey("pkcs8", binaryDer, {
142
+ name: "ECDSA",
143
+ namedCurve: "P-256",
144
+ }, true, ["sign"]);
145
+ return key;
146
+ }
147
+ }
148
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2hhcmVkL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM5RCxPQUFPLEVBQVUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2xELE9BQU8sRUFBb0IsT0FBTyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDeEUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVyQzs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLFNBQVM7YUFDTCxXQUFNLEdBQVcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFNUQsZ0JBQXVCLENBQUM7SUFFeEI7Ozs7OztPQU1HO0lBQ0ssTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FDcEMsYUFBa0MsRUFDbEMsVUFBbUU7UUFFbkUsSUFBSSxhQUFhLFlBQVksVUFBVTtZQUFFLE9BQU8sYUFBYSxDQUFDO1FBQzlELElBQ0UsYUFBYSxDQUFDLEtBQUssQ0FDakIsc0VBQXNFLENBQ3ZFO1lBRUQsT0FBTyxhQUFhLENBQUM7UUFDdkIsT0FBTyxNQUFNLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxhQUE4QjtRQUNsRCxJQUFJLE9BQU8sYUFBYSxLQUFLLFFBQVE7WUFBRSxPQUFPLGFBQWEsQ0FBQztRQUU1RCxNQUFNLFVBQVUsR0FBRyxLQUFLLEVBQUUsSUFBWSxFQUFFLEVBQUU7WUFDeEMsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLE1BQU0sZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FB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RSxFQUFFLENBQUMsQ0FBQztRQUM1QyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDOUQsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sR0FBRyxHQUFHLE1BQU0sTUFBTSxDQUFDLFNBQVMsQ0FDaEMsT0FBTyxFQUNQLFNBQVMsRUFDVDtZQUNFLElBQUksRUFBRSxPQUFPO1lBQ2IsVUFBVSxFQUFFLE9BQU87U0FDcEIsRUFDRCxJQUFJLEVBQ0osQ0FBQyxNQUFNLENBQUMsQ0FDVCxDQUFDO1FBRUYsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgc3RyaW5nRm9ybWF0IH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBub3JtYWxpemVJbXBvcnQgfSBmcm9tIFwiQGRlY2FmLXRzL3V0aWxzXCI7XG5pbXBvcnQgeyBJZGVudGl0eSwgU2lnbmVyLCBzaWduZXJzIH0gZnJvbSBcIkBoeXBlcmxlZGdlci9mYWJyaWMtZ2F0ZXdheVwiO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gXCJmYWJyaWMtY29tbW9uXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvcmUgdXRpbGl0aWVzIGZvciBpbnRlcmFjdGluZyB3aXRoIGZpbGVzLCBjcnlwdG8gaWRlbnRpdGllcywgYW5kIEZhYnJpYyBTREsgaGVscGVyc1xuICogQHN1bW1hcnkgUHJvdmlkZXMgc3RhdGljIGhlbHBlciBtZXRob2RzIHRvIHJlYWQgY3JlZGVudGlhbHMgYW5kIGtleXMgZnJvbSBkaXNrIG9yIHJhdyBjb250ZW50LCBjb25zdHJ1Y3QgRmFicmljIGdhdGV3YXkgSWRlbnRpdGllcyBhbmQgU2lnbmVycywgYW5kIHBlcmZvcm0gY29tbW9uIGZpbGVzeXN0ZW0gb3BlcmF0aW9ucyB1c2VkIGJ5IHRoZSBGYWJyaWMgY2xpZW50IHRvb2xpbmcuXG4gKiBAY2xhc3MgQ29yZVV0aWxzXG4gKiBAZXhhbXBsZVxuICogLy8gUmVhZCBhbiBpZGVudGl0eSBhbmQgc2lnbmVyIGZyb20gZGlyZWN0b3JpZXNcbiAqIGNvbnN0IGlkZW50aXR5ID0gYXdhaXQgQ29yZVV0aWxzLmdldElkZW50aXR5KCdPcmcxTVNQJywgJy9tc3Avc2lnbmNlcnRzJyk7XG4gKiBjb25zdCBzaWduZXIgPSBhd2FpdCBDb3JlVXRpbHMuZ2V0U2lnbmVyKCcvbXNwL2tleXN0b3JlJyk7XG4gKiAvLyBCdWlsZCBhIENBIHVzZXJcbiAqIGNvbnN0IHVzZXIgPSBhd2FpdCBDb3JlVXRpbHMuZ2V0Q0FVc2VyKCdhcHBVc2VyJywgcGVtS2V5LCBwZW1DZXJ0LCAnT3JnMU1TUCcpO1xuICovXG5leHBvcnQgY2xhc3MgQ29yZVV0aWxzIHtcbiAgcHJpdmF0ZSBzdGF0aWMgbG9nZ2VyOiBMb2dnZXIgPSBMb2dnaW5nLmZvcihDb3JlVXRpbHMubmFtZSk7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXNvbHZlIGZpbGUgY29udGVudCBmcm9tIGEgcGF0aCBvciByZXR1cm4gcHJvdmlkZWQgcmF3IGNvbnRlbnRcbiAgICogQHN1bW1hcnkgSWYgdGhlIGlucHV0IGlzIGEgVWludDhBcnJheSBvciBQRU0gY29udGVudCwgcmV0dXJucyBpdCBhcy1pczsgb3RoZXJ3aXNlIHVzZXMgYSBwcm92aWRlZCBhc3luYyBmaWxlUmVhZGVyIHRvIGxvYWQgdGhlIGNvbnRlbnQgZnJvbSBkaXNrLlxuICAgKiBAcGFyYW0ge3N0cmluZ3xVaW50OEFycmF5fSBjb250ZW50T3JQYXRoIC0gRWl0aGVyIGEgcmF3IGNvbnRlbnQgYnVmZmVyL3N0cmluZyBvciBhIGZpbGVzeXN0ZW0gcGF0aFxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKHN0cmluZyk6IFByb21pc2U8c3RyaW5nfFVpbnQ4QXJyYXl8QnVmZmVyPn0gZmlsZVJlYWRlciAtIEFzeW5jIGZ1bmN0aW9uIHRvIHJlYWQgZmlsZSBjb250ZW50IHdoZW4gYSBwYXRoIGlzIHByb3ZpZGVkXG4gICAqIEByZXR1cm4ge1Byb21pc2U8c3RyaW5nfFVpbnQ4QXJyYXl8QnVmZmVyPn0gVGhlIGNvbnRlbnQgdG8gYmUgdXNlZCBkb3duc3RyZWFtXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBhc3luYyBjb250ZW50T2ZMb2FkRmlsZShcbiAgICBjb250ZW50T3JQYXRoOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIGZpbGVSZWFkZXI6IChwYXRoOiBzdHJpbmcpID0+IFByb21pc2U8c3RyaW5nIHwgVWludDhBcnJheSB8IEJ1ZmZlcj5cbiAgKSB7XG4gICAgaWYgKGNvbnRlbnRPclBhdGggaW5zdGFuY2VvZiBVaW50OEFycmF5KSByZXR1cm4gY29udGVudE9yUGF0aDtcbiAgICBpZiAoXG4gICAgICBjb250ZW50T3JQYXRoLm1hdGNoKFxuICAgICAgICAvLS0tLS1CRUdJTiAoQ0VSVElGSUNBVEV8S0VZfFBSSVZBVEUgS0VZKS0tLS0tLis/LS0tLS1FTkQgXFwxLS0tLS0kL2dtc1xuICAgICAgKVxuICAgIClcbiAgICAgIHJldHVybiBjb250ZW50T3JQYXRoO1xuICAgIHJldHVybiBhd2FpdCBmaWxlUmVhZGVyKGNvbnRlbnRPclBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWFkIGZpbGUgY29udGVudCBmcm9tIGEgcGF0aCBvciByZXR1cm4gcHJvdmlkZWQgQnVmZmVyXG4gICAqIEBzdW1tYXJ5IENvbnZlbmllbmNlIHdyYXBwZXIgdGhhdCBsb2FkcyBhIGZpbGUgdXNpbmcgZnMucHJvbWlzZXMgd2hlbiBhIHBhdGggc3RyaW5nIGlzIHByb3ZpZGVkOyBvdGhlcndpc2UgcmV0dXJucyB0aGUgZ2l2ZW4gQnVmZmVyIGRpcmVjdGx5LlxuICAgKiBAcGFyYW0ge3N0cmluZ3xCdWZmZXJ9IGNvbnRlbnRPclBhdGggLSBQYXRoIHRvIGEgZmlsZSBvbiBkaXNrIG9yIGFuIGFscmVhZHktbG9hZGVkIEJ1ZmZlclxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHN0cmluZ3xVaW50OEFycmF5fEJ1ZmZlcj59IFRoZSBmaWxlIGNvbnRlbnQgYXMgYSBCdWZmZXIvc3RyaW5nIGRlcGVuZGluZyBvbiByZWFkZXJcbiAgICovXG4gIHN0YXRpYyBhc3luYyByZWFkRmlsZShjb250ZW50T3JQYXRoOiBzdHJpbmcgfCBCdWZmZXIpIHtcbiAgICBpZiAodHlwZW9mIGNvbnRlbnRPclBhdGggIT09IFwic3RyaW5nXCIpIHJldHVybiBjb250ZW50T3JQYXRoO1xuXG4gICAgY29uc3QgZmlsZVJlYWRlciA9IGFzeW5jIChwYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHsgcHJvbWlzZXMgfSA9IGF3YWl0IG5vcm1hbGl6ZUltcG9ydChpbXBvcnQoXCJmc1wiKSk7XG4gICAgICByZXR1cm4gYXdhaXQgcHJvbWlzZXMucmVhZEZpbGUocGF0aCk7XG4gICAgfTtcblxuICAgIHJldHVybiBhd2FpdCBmaWxlUmVhZGVyKGNvbnRlbnRPclBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGUgYSBGYWJyaWMgQ0EgVXNlciBvYmplY3Qgd2l0aCBlbnJvbGxtZW50XG4gICAqIEBzdW1tYXJ5IENvbnN0cnVjdHMgYSBmYWJyaWMtY29tbW9uIFVzZXIsIHNldHMgYSBjcnlwdG8gc3VpdGUsIGltcG9ydHMgdGhlIHByb3ZpZGVkIHByaXZhdGUga2V5LCBhbmQgc2V0cyBlbnJvbGxtZW50IHdpdGggY2VydGlmaWNhdGUgYW5kIE1TUCBJRC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJOYW1lIC0gVGhlIHVzZXIgbmFtZSBmb3IgdGhlIENBIHVzZXJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHByaXZhdGVLZXkgLSBQRU0tZW5jb2RlZCBwcml2YXRlIGtleVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2VydGlmaWNhdGUgLSBQRU0tZW5jb2RlZCBYLjUwOSBjZXJ0aWZpY2F0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gbXNwSWQgLSBNZW1iZXJzaGlwIFNlcnZpY2UgUHJvdmlkZXIgaWRlbnRpZmllclxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFVzZXI+fSBUaGUgZW5yb2xsZWQgRmFicmljIFVzZXIgaW5zdGFuY2VcbiAgICovXG4gIHN0YXRpYyBhc3luYyBnZXRDQVVzZXIoXG4gICAgdXNlck5hbWU6IHN0cmluZyxcbiAgICBwcml2YXRlS2V5OiBzdHJpbmcsXG4gICAgY2VydGlmaWNhdGU6IHN0cmluZyxcbiAgICBtc3BJZDogc3RyaW5nXG4gICk6IFByb21pc2U8VXNlcj4ge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgc3RyaW5nRm9ybWF0KFxuICAgICAgICBcIkNyZWF0aW5nIENBIHswfSB1c2VyIHsxfSB3aXRoIGNlcnRpZmljYXRlIHsyfVwiLFxuICAgICAgICBtc3BJZCxcbiAgICAgICAgdXNlck5hbWUsXG4gICAgICAgIGNlcnRpZmljYXRlXG4gICAgICApXG4gICAgKTtcbiAgICBjb25zdCB1c2VyID0gbmV3IFVzZXIodXNlck5hbWUpO1xuICAgIGNvbnN0IGNyeXB0b1N1aXRlID0gVXNlci5uZXdDcnlwdG9TdWl0ZSgpO1xuICAgIHVzZXIuc2V0Q3J5cHRvU3VpdGUoY3J5cHRvU3VpdGUpO1xuICAgIGNvbnN0IGltcG9ydGVkS2V5ID0gY3J5cHRvU3VpdGUuY3JlYXRlS2V5RnJvbVJhdyhwcml2YXRlS2V5KTtcbiAgICBhd2FpdCB1c2VyLnNldEVucm9sbG1lbnQoaW1wb3J0ZWRLZXksIGNlcnRpZmljYXRlLCBtc3BJZCk7XG4gICAgcmV0dXJuIHVzZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEJ1aWxkIGEgRmFicmljIEdhdGV3YXkgSWRlbnRpdHkgZnJvbSBhbiBNU1AgSUQgYW5kIGNlcnRpZmljYXRlXG4gICAqIEBzdW1tYXJ5IFJlYWRzIGEgY2VydGlmaWNhdGUgZnJvbSBhIGRpcmVjdG9yeSBwYXRoIG9yIGFjY2VwdHMgcmF3IGNvbnRlbnQgYW5kIHJldHVybnMgYW4gSWRlbnRpdHkgb2JqZWN0IHN1aXRhYmxlIGZvciB0aGUgRmFicmljIEdhdGV3YXkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtc3BJZCAtIE1lbWJlcnNoaXAgU2VydmljZSBQcm92aWRlciBJRFxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2VydERpcmVjdG9yeVBhdGggLSBQYXRoIHRvIGEgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhlIGNlcnRpZmljYXRlIGZpbGUsIG9yIFBFTSBjb250ZW50XG4gICAqIEByZXR1cm4ge1Byb21pc2U8SWRlbnRpdHk+fSBUaGUgaWRlbnRpdHkgY29udGFpbmluZyBtc3BJZCBhbmQgY2VydGlmaWNhdGUgY3JlZGVudGlhbHNcbiAgICovXG4gIHN0YXRpYyBhc3luYyBnZXRJZGVudGl0eShcbiAgICBtc3BJZDogc3RyaW5nLFxuICAgIGNlcnREaXJlY3RvcnlQYXRoOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxJZGVudGl0eT4ge1xuICAgIGNvbnN0IGlkZW50aXR5RmlsZVJlYWRlciA9IGFzeW5jIChwYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHsgcHJvbWlzZXMgfSA9IGF3YWl0IG5vcm1hbGl6ZUltcG9ydChpbXBvcnQoXCJmc1wiKSk7XG4gICAgICBjb25zdCBjZXJ0UGF0aCA9IGF3YWl0IHRoaXMuZ2V0Rmlyc3REaXJGaWxlTmFtZShwYXRoKTtcbiAgICAgIGNvbnN0IGNyZWRlbnRpYWxzID0gYXdhaXQgcHJvbWlzZXMucmVhZEZpbGUoY2VydFBhdGgpO1xuICAgICAgcmV0dXJuIGNyZWRlbnRpYWxzO1xuICAgIH07XG5cbiAgICBjb25zdCBjcmVkZW50aWFsczogVWludDhBcnJheSA9IChhd2FpdCB0aGlzLmNvbnRlbnRPZkxvYWRGaWxlKFxuICAgICAgY2VydERpcmVjdG9yeVBhdGgsXG4gICAgICBpZGVudGl0eUZpbGVSZWFkZXJcbiAgICApKSBhcyBVaW50OEFycmF5O1xuXG4gICAgcmV0dXJuIHsgbXNwSWQsIGNyZWRlbnRpYWxzIH07XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgZ2V0Rmlyc3REaXJGaWxlTmFtZShkaXJQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHsgcHJvbWlzZXMgfSA9IGF3YWl0IG5vcm1hbGl6ZUltcG9ydChpbXBvcnQoXCJmc1wiKSk7XG4gICAgY29uc3QgeyBqb2luIH0gPSBhd2FpdCBub3JtYWxpemVJbXBvcnQoaW1wb3J0KFwicGF0aFwiKSk7XG4gICAgY29uc3QgZmlsZXMgPSBhd2FpdCBwcm9taXNlcy5yZWFkZGlyKGRpclBhdGgpO1xuICAgIHJldHVybiBqb2luKGRpclBhdGgsIGZpbGVzWzBdKTtcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBnZXRGaXJzdERpckZpbGVOYW1lQ29udGVudChkaXJQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHsgcHJvbWlzZXMgfSA9IGF3YWl0IG5vcm1hbGl6ZUltcG9ydChpbXBvcnQoXCJmc1wiKSk7XG4gICAgY29uc3QgeyBqb2luIH0gPSBhd2FpdCBub3JtYWxpemVJbXBvcnQoaW1wb3J0KFwicGF0aFwiKSk7XG4gICAgY29uc3QgZmlsZXMgPSBhd2FpdCBwcm9taXNlcy5yZWFkZGlyKGRpclBhdGgpO1xuICAgIHJldHVybiAoYXdhaXQgcHJvbWlzZXMucmVhZEZpbGUoam9pbihkaXJQYXRoLCBmaWxlc1swXSkpKS50b1N0cmluZygpO1xuICB9XG5cbiAgc3RhdGljIGFzeW5jIGdldEZpbGVDb250ZW50KGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHsgcHJvbWlzZXMgfSA9IGF3YWl0IG5vcm1hbGl6ZUltcG9ydChpbXBvcnQoXCJmc1wiKSk7XG4gICAgcmV0dXJuIChhd2FpdCBwcm9taXNlcy5yZWFkRmlsZShmaWxlUGF0aCkpLnRvU3RyaW5nKCk7XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgZ2V0U2lnbmVyKGtleURpcmVjdG9yeVBhdGg6IHN0cmluZyk6IFByb21pc2U8U2lnbmVyPiB7XG4gICAgY29uc3Qgc2lnbmVyRmlsZVJlYWRlciA9IGFzeW5jIChwYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHsgcHJvbWlzZXMgfSA9IGF3YWl0IG5vcm1hbGl6ZUltcG9ydChpbXBvcnQoXCJmc1wiKSk7XG4gICAgICBjb25zdCBrZXlQYXRoID0gYXdhaXQgdGhpcy5nZXRGaXJzdERpckZpbGVOYW1lKHBhdGgpO1xuICAgICAgcmV0dXJuIGF3YWl0IHByb21pc2VzLnJlYWRGaWxlKGtleVBhdGgpO1xuICAgIH07XG5cbiAgICBjb25zdCBwcml2YXRlS2V5UGVtID0gKGF3YWl0IHRoaXMuY29udGVudE9mTG9hZEZpbGUoXG4gICAgICBrZXlEaXJlY3RvcnlQYXRoLFxuICAgICAgc2lnbmVyRmlsZVJlYWRlclxuICAgICkpIGFzIEJ1ZmZlcjtcbiAgICBjb25zdCBwcml2YXRlS2V5ID0gYXdhaXQgdGhpcy5leHRyYWN0UHJpdmF0ZUtleShwcml2YXRlS2V5UGVtKTtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhwcml2YXRlS2V5KTtcbiAgICBjb25zdCBrID0gKHByaXZhdGVLZXkgYXMgYW55KVtrZXlzWzBdXTtcbiAgICAvLyAtLVxuXG4gICAgcmV0dXJuIHNpZ25lcnMubmV3UHJpdmF0ZUtleVNpZ25lcihrIGFzIGFueSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBhc3luYyBleHRyYWN0UHJpdmF0ZUtleShwZW06IEJ1ZmZlcikge1xuICAgIGNvbnN0IGxpYk5hbWUgPSBcImNyeXB0b1wiO1xuICAgIGxldCBzdWJ0bGU6IGFueTtcbiAgICBpZiAoXG4gICAgICAoZ2xvYmFsVGhpcyBhcyBhbnkpLndpbmRvdyAmJlxuICAgICAgKChnbG9iYWxUaGlzIGFzIGFueSkud2luZG93IGFzIHsgQ3J5cHRvOiBhbnkgfSkuQ3J5cHRvXG4gICAgKSB7XG4gICAgICBzdWJ0bGUgPSAoKGdsb2JhbFRoaXMgYXMgYW55KS5DcnlwdG8gYXMgYW55KS5zdWJ0bGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGxpYiA9IChhd2FpdCBub3JtYWxpemVJbXBvcnQoaW1wb3J0KGxpYk5hbWUpKSkgYXMgYW55O1xuICAgICAgc3VidGxlID0gbGliLnN1YnRsZSB8fCBsaWIud2ViY3J5cHRvLnN1YnRsZTtcbiAgICB9XG5cbiAgICBpZiAoIXN1YnRsZSkgdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IGxvYWQgU3VidGxlQ3J5cHRvIG1vZHVsZVwiKTtcblxuICAgIGZ1bmN0aW9uIHN0cjJhYihzdHI6IHN0cmluZykge1xuICAgICAgY29uc3QgYnVmID0gbmV3IEFycmF5QnVmZmVyKHN0ci5sZW5ndGgpO1xuICAgICAgY29uc3QgYnVmVmlldyA9IG5ldyBVaW50OEFycmF5KGJ1Zik7XG4gICAgICBmb3IgKGxldCBpID0gMCwgc3RyTGVuID0gc3RyLmxlbmd0aDsgaSA8IHN0ckxlbjsgaSsrKSB7XG4gICAgICAgIGJ1ZlZpZXdbaV0gPSBzdHIuY2hhckNvZGVBdChpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWY7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RyID0gcGVtXG4gICAgICAudG9TdHJpbmcoXCJ1dGY4XCIpXG4gICAgICAucmVwbGFjZShcIi0tLS0tQkVHSU4gUFJJVkFURSBLRVktLS0tLVwiLCBcIlwiKVxuICAgICAgLnJlcGxhY2VBbGwoXCJcXG5cIiwgXCJcIilcbiAgICAgIC5yZXBsYWNlKFwiLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLVwiLCBcIlwiKTtcbiAgICBjb25zdCBkZWNvZGVkID0gQnVmZmVyLmZyb20oc3RyLCBcImJhc2U2NFwiKS50b1N0cmluZyhcImJpbmFyeVwiKTtcbiAgICBjb25zdCBiaW5hcnlEZXIgPSBzdHIyYWIoZGVjb2RlZCk7XG4gICAgY29uc3Qga2V5ID0gYXdhaXQgc3VidGxlLmltcG9ydEtleShcbiAgICAgIFwicGtjczhcIixcbiAgICAgIGJpbmFyeURlcixcbiAgICAgIHtcbiAgICAgICAgbmFtZTogXCJFQ0RTQVwiLFxuICAgICAgICBuYW1lZEN1cnZlOiBcIlAtMjU2XCIsXG4gICAgICB9LFxuICAgICAgdHJ1ZSxcbiAgICAgIFtcInNpZ25cIl1cbiAgICApO1xuXG4gICAgcmV0dXJuIGtleTtcbiAgfVxufVxuIl19
package/lib/index.cjs ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ /**
3
+ * @description Hyperledger Fabric Module for Decaf-ts
4
+ * @summary Provides client-side and chaincode-side tooling for building Hyperledger Fabric applications with Decaf-ts. Exposes client adapters, repositories, contract adapters, sequences, utilities, and shared types to streamline development and interaction with Fabric networks. See {@link module:fabric.client}, {@link module:fabric.contracts}, and {@link module:fabric.shared} for grouped exports.
5
+ * @module for-fabric
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
19
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ __exportStar(require("./client/index.cjs"), exports);
23
+ __exportStar(require("./contracts/index.cjs"), exports);
24
+ __exportStar(require("./shared/index.cjs"), exports);
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0dBSUc7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFSCxxREFBeUI7QUFDekIsd0RBQTRCO0FBQzVCLHFEQUF5QiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGRlc2NyaXB0aW9uIEh5cGVybGVkZ2VyIEZhYnJpYyBNb2R1bGUgZm9yIERlY2FmLXRzXG4gKiBAc3VtbWFyeSBQcm92aWRlcyBjbGllbnQtc2lkZSBhbmQgY2hhaW5jb2RlLXNpZGUgdG9vbGluZyBmb3IgYnVpbGRpbmcgSHlwZXJsZWRnZXIgRmFicmljIGFwcGxpY2F0aW9ucyB3aXRoIERlY2FmLXRzLiBFeHBvc2VzIGNsaWVudCBhZGFwdGVycywgcmVwb3NpdG9yaWVzLCBjb250cmFjdCBhZGFwdGVycywgc2VxdWVuY2VzLCB1dGlsaXRpZXMsIGFuZCBzaGFyZWQgdHlwZXMgdG8gc3RyZWFtbGluZSBkZXZlbG9wbWVudCBhbmQgaW50ZXJhY3Rpb24gd2l0aCBGYWJyaWMgbmV0d29ya3MuIFNlZSB7QGxpbmsgbW9kdWxlOmZhYnJpYy5jbGllbnR9LCB7QGxpbmsgbW9kdWxlOmZhYnJpYy5jb250cmFjdHN9LCBhbmQge0BsaW5rIG1vZHVsZTpmYWJyaWMuc2hhcmVkfSBmb3IgZ3JvdXBlZCBleHBvcnRzLlxuICogQG1vZHVsZSBmb3ItZmFicmljXG4gKi9cblxuZXhwb3J0ICogZnJvbSBcIi4vY2xpZW50XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250cmFjdHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3NoYXJlZFwiO1xuIl19
package/lib/index.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @description Hyperledger Fabric Module for Decaf-ts
3
+ * @summary Provides client-side and chaincode-side tooling for building Hyperledger Fabric applications with Decaf-ts. Exposes client adapters, repositories, contract adapters, sequences, utilities, and shared types to streamline development and interaction with Fabric networks. See {@link module:fabric.client}, {@link module:fabric.contracts}, and {@link module:fabric.shared} for grouped exports.
4
+ * @module for-fabric
5
+ */
6
+ export * from "./client";
7
+ export * from "./contracts";
8
+ export * from "./shared";
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClientSerializer = void 0;
4
+ const decorator_validation_1 = require("@decaf-ts/decorator-validation");
5
+ const db_decorators_1 = require("@decaf-ts/db-decorators");
6
+ /**
7
+ * @description Client-side JSON serializer for Decaf models targeting Hyperledger Fabric
8
+ * @summary Extends the base JSONSerializer to embed model metadata (anchor) required to reconstruct instances on the client, and to safely serialize/deserialize Fabric-bound models.
9
+ * @template M extends Model - The Decaf model type handled by this serializer
10
+ * @param {void} [constructor] No public constructor arguments; provided for documentation completeness
11
+ * @return {void}
12
+ * @class ClientSerializer
13
+ * @example
14
+ * const serializer = new ClientSerializer<User>();
15
+ * const json = serializer.serialize(new User({ id: "1", name: "Alice" }));
16
+ * const user = serializer.deserialize(json);
17
+ * @mermaid
18
+ * sequenceDiagram
19
+ * participant App
20
+ * participant Serializer as ClientSerializer
21
+ * participant Model
22
+ * App->>Serializer: serialize(model)
23
+ * Serializer->>Serializer: preSerialize(model)
24
+ * Serializer-->>App: JSON string
25
+ * App->>Serializer: deserialize(json)
26
+ * Serializer->>Serializer: JSON.parse(json)
27
+ * Serializer->>Model: Model.build(parsed, anchor)
28
+ * Model-->>App: instance
29
+ */
30
+ class ClientSerializer extends decorator_validation_1.JSONSerializer {
31
+ constructor() {
32
+ super();
33
+ }
34
+ /**
35
+ * @description Prepare a model for JSON serialization embedding class anchor
36
+ * @summary Clones the model and injects the class metadata anchor so it can be reconstructed during deserialization. Falls back to provided table name if metadata is not available.
37
+ * @template M - Model type handled by this serializer
38
+ * @param {M} model - The model instance to serialize
39
+ * @param {string} [table] - Optional table name to use when metadata cannot be derived
40
+ * @return {Record<string, any>} A plain object ready to be JSON.stringify'd
41
+ */
42
+ preSerialize(model, table) {
43
+ // TODO: nested preserialization (so increase performance when deserializing)
44
+ const toSerialize = Object.assign({}, model);
45
+ let metadata;
46
+ try {
47
+ metadata = (0, decorator_validation_1.getMetadata)(model);
48
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
49
+ }
50
+ catch (e) {
51
+ metadata = table;
52
+ }
53
+ if (!metadata)
54
+ throw new db_decorators_1.SerializationError(`Could not find metadata for ${model.constructor.name}`);
55
+ toSerialize[decorator_validation_1.ModelKeys.ANCHOR] = metadata;
56
+ return toSerialize;
57
+ }
58
+ /**
59
+ * @description Rebuilds a model from its JSON serialization
60
+ * @summary Parses the JSON string, retrieves the embedded model anchor, and uses Model.build to reconstruct the original instance
61
+ * @param {string} str - The JSON string previously produced by serialize
62
+ * @return {M} The reconstructed model instance
63
+ */
64
+ deserialize(str) {
65
+ const deserialization = JSON.parse(str);
66
+ const className = deserialization[decorator_validation_1.ModelKeys.ANCHOR];
67
+ if (!className)
68
+ throw new Error("Could not find class reference in serialized model");
69
+ const model = decorator_validation_1.Model.build(deserialization, className);
70
+ return model;
71
+ }
72
+ /**
73
+ * @description Serializes a model to a JSON string
74
+ * @summary Prepares the model via preSerialize, embedding metadata needed for reconstruction, and returns a JSON string representation
75
+ * @param {M} model - The model instance to serialize
76
+ * @param {string} [table] - Optional table name to include as anchor when metadata is unavailable
77
+ * @return {string} A JSON string containing the serialized model with anchor metadata
78
+ */
79
+ serialize(model, table) {
80
+ return JSON.stringify(this.preSerialize(model, table));
81
+ }
82
+ }
83
+ exports.ClientSerializer = ClientSerializer;
84
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2xpZW50U2VyaWFsaXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zaGFyZWQvQ2xpZW50U2VyaWFsaXplci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5RUFLd0M7QUFDeEMsMkRBQTZEO0FBRTdEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXVCRztBQUNILE1BQWEsZ0JBQWtDLFNBQVEscUNBQWlCO0lBQ3RFO1FBQ0UsS0FBSyxFQUFFLENBQUM7SUFDVixDQUFDO0lBQ0Q7Ozs7Ozs7T0FPRztJQUNnQixZQUFZLENBQUMsS0FBUSxFQUFFLEtBQWM7UUFDdEQsNkVBQTZFO1FBQzdFLE1BQU0sV0FBVyxHQUF3QixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNsRSxJQUFJLFFBQVEsQ0FBQztRQUNiLElBQUksQ0FBQztZQUNILFFBQVEsR0FBRyxJQUFBLGtDQUFXLEVBQUMsS0FBSyxDQUFDLENBQUM7WUFDOUIsNkRBQTZEO1FBQy9ELENBQUM7UUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO1lBQ3BCLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDbkIsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRO1lBQ1gsTUFBTSxJQUFJLGtDQUFrQixDQUMxQiwrQkFBK0IsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FDeEQsQ0FBQztRQUNKLFdBQVcsQ0FBQyxnQ0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQztRQUN6QyxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTSxXQUFXLENBQUMsR0FBVztRQUM5QixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxnQ0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxTQUFTO1lBQ1osTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQ3hFLE1BQU0sS0FBSyxHQUFNLDRCQUFLLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRSxTQUFTLENBQWlCLENBQUM7UUFDekUsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ00sU0FBUyxDQUFDLEtBQVEsRUFBRSxLQUFjO1FBQ3pDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7Q0FDRjtBQXZERCw0Q0F1REMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBnZXRNZXRhZGF0YSxcbiAgSlNPTlNlcmlhbGl6ZXIsXG4gIE1vZGVsLFxuICBNb2RlbEtleXMsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFNlcmlhbGl6YXRpb25FcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDbGllbnQtc2lkZSBKU09OIHNlcmlhbGl6ZXIgZm9yIERlY2FmIG1vZGVscyB0YXJnZXRpbmcgSHlwZXJsZWRnZXIgRmFicmljXG4gKiBAc3VtbWFyeSBFeHRlbmRzIHRoZSBiYXNlIEpTT05TZXJpYWxpemVyIHRvIGVtYmVkIG1vZGVsIG1ldGFkYXRhIChhbmNob3IpIHJlcXVpcmVkIHRvIHJlY29uc3RydWN0IGluc3RhbmNlcyBvbiB0aGUgY2xpZW50LCBhbmQgdG8gc2FmZWx5IHNlcmlhbGl6ZS9kZXNlcmlhbGl6ZSBGYWJyaWMtYm91bmQgbW9kZWxzLlxuICogQHRlbXBsYXRlIE0gZXh0ZW5kcyBNb2RlbCAtIFRoZSBEZWNhZiBtb2RlbCB0eXBlIGhhbmRsZWQgYnkgdGhpcyBzZXJpYWxpemVyXG4gKiBAcGFyYW0ge3ZvaWR9IFtjb25zdHJ1Y3Rvcl0gTm8gcHVibGljIGNvbnN0cnVjdG9yIGFyZ3VtZW50czsgcHJvdmlkZWQgZm9yIGRvY3VtZW50YXRpb24gY29tcGxldGVuZXNzXG4gKiBAcmV0dXJuIHt2b2lkfVxuICogQGNsYXNzIENsaWVudFNlcmlhbGl6ZXJcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzZXJpYWxpemVyID0gbmV3IENsaWVudFNlcmlhbGl6ZXI8VXNlcj4oKTtcbiAqIGNvbnN0IGpzb24gPSBzZXJpYWxpemVyLnNlcmlhbGl6ZShuZXcgVXNlcih7IGlkOiBcIjFcIiwgbmFtZTogXCJBbGljZVwiIH0pKTtcbiAqIGNvbnN0IHVzZXIgPSBzZXJpYWxpemVyLmRlc2VyaWFsaXplKGpzb24pO1xuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBBcHBcbiAqICAgcGFydGljaXBhbnQgU2VyaWFsaXplciBhcyBDbGllbnRTZXJpYWxpemVyXG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKiAgIEFwcC0+PlNlcmlhbGl6ZXI6IHNlcmlhbGl6ZShtb2RlbClcbiAqICAgU2VyaWFsaXplci0+PlNlcmlhbGl6ZXI6IHByZVNlcmlhbGl6ZShtb2RlbClcbiAqICAgU2VyaWFsaXplci0tPj5BcHA6IEpTT04gc3RyaW5nXG4gKiAgIEFwcC0+PlNlcmlhbGl6ZXI6IGRlc2VyaWFsaXplKGpzb24pXG4gKiAgIFNlcmlhbGl6ZXItPj5TZXJpYWxpemVyOiBKU09OLnBhcnNlKGpzb24pXG4gKiAgIFNlcmlhbGl6ZXItPj5Nb2RlbDogTW9kZWwuYnVpbGQocGFyc2VkLCBhbmNob3IpXG4gKiAgIE1vZGVsLS0+PkFwcDogaW5zdGFuY2VcbiAqL1xuZXhwb3J0IGNsYXNzIENsaWVudFNlcmlhbGl6ZXI8TSBleHRlbmRzIE1vZGVsPiBleHRlbmRzIEpTT05TZXJpYWxpemVyPE0+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmUgYSBtb2RlbCBmb3IgSlNPTiBzZXJpYWxpemF0aW9uIGVtYmVkZGluZyBjbGFzcyBhbmNob3JcbiAgICogQHN1bW1hcnkgQ2xvbmVzIHRoZSBtb2RlbCBhbmQgaW5qZWN0cyB0aGUgY2xhc3MgbWV0YWRhdGEgYW5jaG9yIHNvIGl0IGNhbiBiZSByZWNvbnN0cnVjdGVkIGR1cmluZyBkZXNlcmlhbGl6YXRpb24uIEZhbGxzIGJhY2sgdG8gcHJvdmlkZWQgdGFibGUgbmFtZSBpZiBtZXRhZGF0YSBpcyBub3QgYXZhaWxhYmxlLlxuICAgKiBAdGVtcGxhdGUgTSAtIE1vZGVsIHR5cGUgaGFuZGxlZCBieSB0aGlzIHNlcmlhbGl6ZXJcbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZSB0byBzZXJpYWxpemVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFt0YWJsZV0gLSBPcHRpb25hbCB0YWJsZSBuYW1lIHRvIHVzZSB3aGVuIG1ldGFkYXRhIGNhbm5vdCBiZSBkZXJpdmVkXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIGFueT59IEEgcGxhaW4gb2JqZWN0IHJlYWR5IHRvIGJlIEpTT04uc3RyaW5naWZ5J2RcbiAgICovXG4gIHByb3RlY3RlZCBvdmVycmlkZSBwcmVTZXJpYWxpemUobW9kZWw6IE0sIHRhYmxlPzogc3RyaW5nKSB7XG4gICAgLy8gVE9ETzogbmVzdGVkIHByZXNlcmlhbGl6YXRpb24gKHNvIGluY3JlYXNlIHBlcmZvcm1hbmNlIHdoZW4gZGVzZXJpYWxpemluZylcbiAgICBjb25zdCB0b1NlcmlhbGl6ZTogUmVjb3JkPHN0cmluZywgYW55PiA9IE9iamVjdC5hc3NpZ24oe30sIG1vZGVsKTtcbiAgICBsZXQgbWV0YWRhdGE7XG4gICAgdHJ5IHtcbiAgICAgIG1ldGFkYXRhID0gZ2V0TWV0YWRhdGEobW9kZWwpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIG1ldGFkYXRhID0gdGFibGU7XG4gICAgfVxuICAgIGlmICghbWV0YWRhdGEpXG4gICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICBgQ291bGQgbm90IGZpbmQgbWV0YWRhdGEgZm9yICR7bW9kZWwuY29uc3RydWN0b3IubmFtZX1gXG4gICAgICApO1xuICAgIHRvU2VyaWFsaXplW01vZGVsS2V5cy5BTkNIT1JdID0gbWV0YWRhdGE7XG4gICAgcmV0dXJuIHRvU2VyaWFsaXplO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWJ1aWxkcyBhIG1vZGVsIGZyb20gaXRzIEpTT04gc2VyaWFsaXphdGlvblxuICAgKiBAc3VtbWFyeSBQYXJzZXMgdGhlIEpTT04gc3RyaW5nLCByZXRyaWV2ZXMgdGhlIGVtYmVkZGVkIG1vZGVsIGFuY2hvciwgYW5kIHVzZXMgTW9kZWwuYnVpbGQgdG8gcmVjb25zdHJ1Y3QgdGhlIG9yaWdpbmFsIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBUaGUgSlNPTiBzdHJpbmcgcHJldmlvdXNseSBwcm9kdWNlZCBieSBzZXJpYWxpemVcbiAgICogQHJldHVybiB7TX0gVGhlIHJlY29uc3RydWN0ZWQgbW9kZWwgaW5zdGFuY2VcbiAgICovXG4gIG92ZXJyaWRlIGRlc2VyaWFsaXplKHN0cjogc3RyaW5nKTogTSB7XG4gICAgY29uc3QgZGVzZXJpYWxpemF0aW9uID0gSlNPTi5wYXJzZShzdHIpO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGRlc2VyaWFsaXphdGlvbltNb2RlbEtleXMuQU5DSE9SXTtcbiAgICBpZiAoIWNsYXNzTmFtZSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBmaW5kIGNsYXNzIHJlZmVyZW5jZSBpbiBzZXJpYWxpemVkIG1vZGVsXCIpO1xuICAgIGNvbnN0IG1vZGVsOiBNID0gTW9kZWwuYnVpbGQoZGVzZXJpYWxpemF0aW9uLCBjbGFzc05hbWUpIGFzIHVua25vd24gYXMgTTtcbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNlcmlhbGl6ZXMgYSBtb2RlbCB0byBhIEpTT04gc3RyaW5nXG4gICAqIEBzdW1tYXJ5IFByZXBhcmVzIHRoZSBtb2RlbCB2aWEgcHJlU2VyaWFsaXplLCBlbWJlZGRpbmcgbWV0YWRhdGEgbmVlZGVkIGZvciByZWNvbnN0cnVjdGlvbiwgYW5kIHJldHVybnMgYSBKU09OIHN0cmluZyByZXByZXNlbnRhdGlvblxuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIHNlcmlhbGl6ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3RhYmxlXSAtIE9wdGlvbmFsIHRhYmxlIG5hbWUgdG8gaW5jbHVkZSBhcyBhbmNob3Igd2hlbiBtZXRhZGF0YSBpcyB1bmF2YWlsYWJsZVxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IEEgSlNPTiBzdHJpbmcgY29udGFpbmluZyB0aGUgc2VyaWFsaXplZCBtb2RlbCB3aXRoIGFuY2hvciBtZXRhZGF0YVxuICAgKi9cbiAgb3ZlcnJpZGUgc2VyaWFsaXplKG1vZGVsOiBNLCB0YWJsZT86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMucHJlU2VyaWFsaXplKG1vZGVsLCB0YWJsZSkpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,52 @@
1
+ import { JSONSerializer, Model } from "@decaf-ts/decorator-validation";
2
+ /**
3
+ * @description Client-side JSON serializer for Decaf models targeting Hyperledger Fabric
4
+ * @summary Extends the base JSONSerializer to embed model metadata (anchor) required to reconstruct instances on the client, and to safely serialize/deserialize Fabric-bound models.
5
+ * @template M extends Model - The Decaf model type handled by this serializer
6
+ * @param {void} [constructor] No public constructor arguments; provided for documentation completeness
7
+ * @return {void}
8
+ * @class ClientSerializer
9
+ * @example
10
+ * const serializer = new ClientSerializer<User>();
11
+ * const json = serializer.serialize(new User({ id: "1", name: "Alice" }));
12
+ * const user = serializer.deserialize(json);
13
+ * @mermaid
14
+ * sequenceDiagram
15
+ * participant App
16
+ * participant Serializer as ClientSerializer
17
+ * participant Model
18
+ * App->>Serializer: serialize(model)
19
+ * Serializer->>Serializer: preSerialize(model)
20
+ * Serializer-->>App: JSON string
21
+ * App->>Serializer: deserialize(json)
22
+ * Serializer->>Serializer: JSON.parse(json)
23
+ * Serializer->>Model: Model.build(parsed, anchor)
24
+ * Model-->>App: instance
25
+ */
26
+ export declare class ClientSerializer<M extends Model> extends JSONSerializer<M> {
27
+ constructor();
28
+ /**
29
+ * @description Prepare a model for JSON serialization embedding class anchor
30
+ * @summary Clones the model and injects the class metadata anchor so it can be reconstructed during deserialization. Falls back to provided table name if metadata is not available.
31
+ * @template M - Model type handled by this serializer
32
+ * @param {M} model - The model instance to serialize
33
+ * @param {string} [table] - Optional table name to use when metadata cannot be derived
34
+ * @return {Record<string, any>} A plain object ready to be JSON.stringify'd
35
+ */
36
+ protected preSerialize(model: M, table?: string): Record<string, any>;
37
+ /**
38
+ * @description Rebuilds a model from its JSON serialization
39
+ * @summary Parses the JSON string, retrieves the embedded model anchor, and uses Model.build to reconstruct the original instance
40
+ * @param {string} str - The JSON string previously produced by serialize
41
+ * @return {M} The reconstructed model instance
42
+ */
43
+ deserialize(str: string): M;
44
+ /**
45
+ * @description Serializes a model to a JSON string
46
+ * @summary Prepares the model via preSerialize, embedding metadata needed for reconstruction, and returns a JSON string representation
47
+ * @param {M} model - The model instance to serialize
48
+ * @param {string} [table] - Optional table name to include as anchor when metadata is unavailable
49
+ * @return {string} A JSON string containing the serialized model with anchor metadata
50
+ */
51
+ serialize(model: M, table?: string): string;
52
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeterministicSerializer = void 0;
4
+ /* eslint-disable @typescript-eslint/no-require-imports */
5
+ const decorator_validation_1 = require("@decaf-ts/decorator-validation");
6
+ /**
7
+ * @description Deterministic JSON serializer for Fabric models
8
+ * @summary Ensures stable, deterministic JSON output by sorting object keys recursively before stringification, which is important for Fabric endorsement and hashing. Extends JSONSerializer to plug into existing Decaf model serialization flow.
9
+ * @template M - The Decaf Model subtype serialized by this instance
10
+ * @param {void} [constructor] No public constructor arguments
11
+ * @class DeterministicSerializer
12
+ * @example
13
+ * const serializer = new DeterministicSerializer<MyModel>();
14
+ * const json = serializer.serialize(model);
15
+ * const rebuilt = serializer.deserialize(json);
16
+ * @mermaid
17
+ * sequenceDiagram
18
+ * participant Caller
19
+ * participant DS as DeterministicSerializer
20
+ * Caller->>DS: serialize(model)
21
+ * DS->>DS: preSerialize(model)
22
+ * DS->>DS: sort-keys-recursive
23
+ * DS->>DS: json-stringify-deterministic
24
+ * DS-->>Caller: string
25
+ * Caller->>DS: deserialize(string)
26
+ * DS-->>Caller: model
27
+ */
28
+ class DeterministicSerializer extends decorator_validation_1.JSONSerializer {
29
+ constructor() {
30
+ super();
31
+ }
32
+ /**
33
+ * @description Deserialize a JSON string into a model instance
34
+ * @summary Delegates to the base JSONSerializer implementation to rebuild the model
35
+ * @param {string} str - The JSON string to deserialize
36
+ * @return {M} The reconstructed model instance
37
+ */
38
+ deserialize(str) {
39
+ return super.deserialize(str);
40
+ }
41
+ /**
42
+ * @description Serialize a model into a deterministic JSON string
43
+ * @summary Prepares the model with preSerialize, sorts keys recursively, and stringifies deterministically for stable ordering
44
+ * @param {M} model - The model instance to serialize
45
+ * @return {string} Deterministic JSON representation of the model
46
+ */
47
+ serialize(model) {
48
+ const stringify = require("json-stringify-deterministic");
49
+ const sortKeysRecursive = require("sort-keys-recursive");
50
+ return stringify(sortKeysRecursive(this.preSerialize(model)));
51
+ }
52
+ }
53
+ exports.DeterministicSerializer = DeterministicSerializer;
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGV0ZXJtaW5pc3RpY1NlcmlhbGl6ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2hhcmVkL0RldGVybWluaXN0aWNTZXJpYWxpemVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDBEQUEwRDtBQUMxRCx5RUFBdUU7QUFFdkU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQWEsdUJBRVgsU0FBUSxxQ0FBaUI7SUFDekI7UUFDRSxLQUFLLEVBQUUsQ0FBQztJQUNWLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNNLFdBQVcsQ0FBQyxHQUFXO1FBQzlCLE9BQU8sS0FBSyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTSxTQUFTLENBQUMsS0FBUTtRQUN6QixNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUMxRCxNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ3pELE9BQU8sU0FBUyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7Q0FDRjtBQTVCRCwwREE0QkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzICovXG5pbXBvcnQgeyBKU09OU2VyaWFsaXplciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERldGVybWluaXN0aWMgSlNPTiBzZXJpYWxpemVyIGZvciBGYWJyaWMgbW9kZWxzXG4gKiBAc3VtbWFyeSBFbnN1cmVzIHN0YWJsZSwgZGV0ZXJtaW5pc3RpYyBKU09OIG91dHB1dCBieSBzb3J0aW5nIG9iamVjdCBrZXlzIHJlY3Vyc2l2ZWx5IGJlZm9yZSBzdHJpbmdpZmljYXRpb24sIHdoaWNoIGlzIGltcG9ydGFudCBmb3IgRmFicmljIGVuZG9yc2VtZW50IGFuZCBoYXNoaW5nLiBFeHRlbmRzIEpTT05TZXJpYWxpemVyIHRvIHBsdWcgaW50byBleGlzdGluZyBEZWNhZiBtb2RlbCBzZXJpYWxpemF0aW9uIGZsb3cuXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBEZWNhZiBNb2RlbCBzdWJ0eXBlIHNlcmlhbGl6ZWQgYnkgdGhpcyBpbnN0YW5jZVxuICogQHBhcmFtIHt2b2lkfSBbY29uc3RydWN0b3JdIE5vIHB1YmxpYyBjb25zdHJ1Y3RvciBhcmd1bWVudHNcbiAqIEBjbGFzcyBEZXRlcm1pbmlzdGljU2VyaWFsaXplclxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNlcmlhbGl6ZXIgPSBuZXcgRGV0ZXJtaW5pc3RpY1NlcmlhbGl6ZXI8TXlNb2RlbD4oKTtcbiAqIGNvbnN0IGpzb24gPSBzZXJpYWxpemVyLnNlcmlhbGl6ZShtb2RlbCk7XG4gKiBjb25zdCByZWJ1aWx0ID0gc2VyaWFsaXplci5kZXNlcmlhbGl6ZShqc29uKTtcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IERTIGFzIERldGVybWluaXN0aWNTZXJpYWxpemVyXG4gKiAgIENhbGxlci0+PkRTOiBzZXJpYWxpemUobW9kZWwpXG4gKiAgIERTLT4+RFM6IHByZVNlcmlhbGl6ZShtb2RlbClcbiAqICAgRFMtPj5EUzogc29ydC1rZXlzLXJlY3Vyc2l2ZVxuICogICBEUy0+PkRTOiBqc29uLXN0cmluZ2lmeS1kZXRlcm1pbmlzdGljXG4gKiAgIERTLS0+PkNhbGxlcjogc3RyaW5nXG4gKiAgIENhbGxlci0+PkRTOiBkZXNlcmlhbGl6ZShzdHJpbmcpXG4gKiAgIERTLS0+PkNhbGxlcjogbW9kZWxcbiAqL1xuZXhwb3J0IGNsYXNzIERldGVybWluaXN0aWNTZXJpYWxpemVyPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4+IGV4dGVuZHMgSlNPTlNlcmlhbGl6ZXI8TT4ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEZXNlcmlhbGl6ZSBhIEpTT04gc3RyaW5nIGludG8gYSBtb2RlbCBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdG8gdGhlIGJhc2UgSlNPTlNlcmlhbGl6ZXIgaW1wbGVtZW50YXRpb24gdG8gcmVidWlsZCB0aGUgbW9kZWxcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFRoZSBKU09OIHN0cmluZyB0byBkZXNlcmlhbGl6ZVxuICAgKiBAcmV0dXJuIHtNfSBUaGUgcmVjb25zdHJ1Y3RlZCBtb2RlbCBpbnN0YW5jZVxuICAgKi9cbiAgb3ZlcnJpZGUgZGVzZXJpYWxpemUoc3RyOiBzdHJpbmcpOiBNIHtcbiAgICByZXR1cm4gc3VwZXIuZGVzZXJpYWxpemUoc3RyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2VyaWFsaXplIGEgbW9kZWwgaW50byBhIGRldGVybWluaXN0aWMgSlNPTiBzdHJpbmdcbiAgICogQHN1bW1hcnkgUHJlcGFyZXMgdGhlIG1vZGVsIHdpdGggcHJlU2VyaWFsaXplLCBzb3J0cyBrZXlzIHJlY3Vyc2l2ZWx5LCBhbmQgc3RyaW5naWZpZXMgZGV0ZXJtaW5pc3RpY2FsbHkgZm9yIHN0YWJsZSBvcmRlcmluZ1xuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIHNlcmlhbGl6ZVxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IERldGVybWluaXN0aWMgSlNPTiByZXByZXNlbnRhdGlvbiBvZiB0aGUgbW9kZWxcbiAgICovXG4gIG92ZXJyaWRlIHNlcmlhbGl6ZShtb2RlbDogTSk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RyaW5naWZ5ID0gcmVxdWlyZShcImpzb24tc3RyaW5naWZ5LWRldGVybWluaXN0aWNcIik7XG4gICAgY29uc3Qgc29ydEtleXNSZWN1cnNpdmUgPSByZXF1aXJlKFwic29ydC1rZXlzLXJlY3Vyc2l2ZVwiKTtcbiAgICByZXR1cm4gc3RyaW5naWZ5KHNvcnRLZXlzUmVjdXJzaXZlKHRoaXMucHJlU2VyaWFsaXplKG1vZGVsKSkpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,40 @@
1
+ import { JSONSerializer, Model } from "@decaf-ts/decorator-validation";
2
+ /**
3
+ * @description Deterministic JSON serializer for Fabric models
4
+ * @summary Ensures stable, deterministic JSON output by sorting object keys recursively before stringification, which is important for Fabric endorsement and hashing. Extends JSONSerializer to plug into existing Decaf model serialization flow.
5
+ * @template M - The Decaf Model subtype serialized by this instance
6
+ * @param {void} [constructor] No public constructor arguments
7
+ * @class DeterministicSerializer
8
+ * @example
9
+ * const serializer = new DeterministicSerializer<MyModel>();
10
+ * const json = serializer.serialize(model);
11
+ * const rebuilt = serializer.deserialize(json);
12
+ * @mermaid
13
+ * sequenceDiagram
14
+ * participant Caller
15
+ * participant DS as DeterministicSerializer
16
+ * Caller->>DS: serialize(model)
17
+ * DS->>DS: preSerialize(model)
18
+ * DS->>DS: sort-keys-recursive
19
+ * DS->>DS: json-stringify-deterministic
20
+ * DS-->>Caller: string
21
+ * Caller->>DS: deserialize(string)
22
+ * DS-->>Caller: model
23
+ */
24
+ export declare class DeterministicSerializer<M extends Model> extends JSONSerializer<M> {
25
+ constructor();
26
+ /**
27
+ * @description Deserialize a JSON string into a model instance
28
+ * @summary Delegates to the base JSONSerializer implementation to rebuild the model
29
+ * @param {string} str - The JSON string to deserialize
30
+ * @return {M} The reconstructed model instance
31
+ */
32
+ deserialize(str: string): M;
33
+ /**
34
+ * @description Serialize a model into a deterministic JSON string
35
+ * @summary Prepares the model with preSerialize, sorts keys recursively, and stringifies deterministically for stable ordering
36
+ * @param {M} model - The model instance to serialize
37
+ * @return {string} Deterministic JSON representation of the model
38
+ */
39
+ serialize(model: M): string;
40
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SimpleDeterministicSerializer = void 0;
4
+ const decorator_validation_1 = require("@decaf-ts/decorator-validation");
5
+ class SimpleDeterministicSerializer extends decorator_validation_1.JSONSerializer {
6
+ constructor() {
7
+ super();
8
+ }
9
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
10
+ deserialize(str, tableName) {
11
+ const deserialization = JSON.parse(str);
12
+ // const className = tableName;
13
+ // if (!className)
14
+ // throw new Error("Could not find class reference in serialized model");
15
+ // // this will return undefined values
16
+ // const model: M = Model.build(deserialization, className) as unknown as M;
17
+ // // Populate Model
18
+ // const processedDesealization = Object.keys(model).reduce(
19
+ // (accum: M, key) => {
20
+ // (accum as Record<string, any>)[key] =
21
+ // deserialization[Repository.column(accum, key)];
22
+ // return accum;
23
+ // },
24
+ // model
25
+ // );
26
+ // const result = Model.build(
27
+ // processedDesealization,
28
+ // className
29
+ // ) as unknown as M;
30
+ // return result;
31
+ return deserialization;
32
+ }
33
+ serialize(model) {
34
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
35
+ const stringify = require("json-stringify-deterministic");
36
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
37
+ const sortKeysRecursive = require("sort-keys-recursive");
38
+ return stringify(sortKeysRecursive(this.preSerialize(model)));
39
+ }
40
+ preSerialize(model) {
41
+ const toSerialize = Object.assign({}, model);
42
+ return toSerialize;
43
+ }
44
+ }
45
+ exports.SimpleDeterministicSerializer = SimpleDeterministicSerializer;
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2ltcGxlRGV0ZXJtaW5pc3RpY1NlcmlhbGl6ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2hhcmVkL1NpbXBsZURldGVybWluaXN0aWNTZXJpYWxpemVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlFQUF1RTtBQUV2RSxNQUFhLDZCQUVYLFNBQVEscUNBQWlCO0lBQ3pCO1FBQ0UsS0FBSyxFQUFFLENBQUM7SUFDVixDQUFDO0lBRUQsNkRBQTZEO0lBQ3BELFdBQVcsQ0FBQyxHQUFXLEVBQUUsU0FBa0I7UUFDbEQsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN4QywrQkFBK0I7UUFDL0Isa0JBQWtCO1FBQ2xCLDJFQUEyRTtRQUUzRSx1Q0FBdUM7UUFDdkMsNEVBQTRFO1FBRTVFLG9CQUFvQjtRQUNwQiw0REFBNEQ7UUFDNUQseUJBQXlCO1FBQ3pCLDRDQUE0QztRQUM1Qyx3REFBd0Q7UUFDeEQsb0JBQW9CO1FBQ3BCLE9BQU87UUFDUCxVQUFVO1FBQ1YsS0FBSztRQUVMLDhCQUE4QjtRQUM5Qiw0QkFBNEI7UUFDNUIsY0FBYztRQUNkLHFCQUFxQjtRQUVyQixpQkFBaUI7UUFDakIsT0FBTyxlQUFlLENBQUM7SUFDekIsQ0FBQztJQUVRLFNBQVMsQ0FBQyxLQUFRO1FBQ3pCLGlFQUFpRTtRQUNqRSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUMxRCxpRUFBaUU7UUFDakUsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUN6RCxPQUFPLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRVEsWUFBWSxDQUFDLEtBQVE7UUFDNUIsTUFBTSxXQUFXLEdBQXdCLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2xFLE9BQU8sV0FBVyxDQUFDO0lBQ3JCLENBQUM7Q0FDRjtBQWhERCxzRUFnREMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBKU09OU2VyaWFsaXplciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbmV4cG9ydCBjbGFzcyBTaW1wbGVEZXRlcm1pbmlzdGljU2VyaWFsaXplcjxcbiAgTSBleHRlbmRzIE1vZGVsLFxuPiBleHRlbmRzIEpTT05TZXJpYWxpemVyPE0+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgb3ZlcnJpZGUgZGVzZXJpYWxpemUoc3RyOiBzdHJpbmcsIHRhYmxlTmFtZT86IHN0cmluZyk6IE0ge1xuICAgIGNvbnN0IGRlc2VyaWFsaXphdGlvbiA9IEpTT04ucGFyc2Uoc3RyKTtcbiAgICAvLyBjb25zdCBjbGFzc05hbWUgPSB0YWJsZU5hbWU7XG4gICAgLy8gaWYgKCFjbGFzc05hbWUpXG4gICAgLy8gICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZmluZCBjbGFzcyByZWZlcmVuY2UgaW4gc2VyaWFsaXplZCBtb2RlbFwiKTtcblxuICAgIC8vIC8vIHRoaXMgd2lsbCByZXR1cm4gdW5kZWZpbmVkIHZhbHVlc1xuICAgIC8vIGNvbnN0IG1vZGVsOiBNID0gTW9kZWwuYnVpbGQoZGVzZXJpYWxpemF0aW9uLCBjbGFzc05hbWUpIGFzIHVua25vd24gYXMgTTtcblxuICAgIC8vIC8vIFBvcHVsYXRlIE1vZGVsXG4gICAgLy8gY29uc3QgcHJvY2Vzc2VkRGVzZWFsaXphdGlvbiA9IE9iamVjdC5rZXlzKG1vZGVsKS5yZWR1Y2UoXG4gICAgLy8gICAoYWNjdW06IE0sIGtleSkgPT4ge1xuICAgIC8vICAgICAoYWNjdW0gYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XSA9XG4gICAgLy8gICAgICAgZGVzZXJpYWxpemF0aW9uW1JlcG9zaXRvcnkuY29sdW1uKGFjY3VtLCBrZXkpXTtcbiAgICAvLyAgICAgcmV0dXJuIGFjY3VtO1xuICAgIC8vICAgfSxcbiAgICAvLyAgIG1vZGVsXG4gICAgLy8gKTtcblxuICAgIC8vIGNvbnN0IHJlc3VsdCA9IE1vZGVsLmJ1aWxkKFxuICAgIC8vICAgcHJvY2Vzc2VkRGVzZWFsaXphdGlvbixcbiAgICAvLyAgIGNsYXNzTmFtZVxuICAgIC8vICkgYXMgdW5rbm93biBhcyBNO1xuXG4gICAgLy8gcmV0dXJuIHJlc3VsdDtcbiAgICByZXR1cm4gZGVzZXJpYWxpemF0aW9uO1xuICB9XG5cbiAgb3ZlcnJpZGUgc2VyaWFsaXplKG1vZGVsOiBNKTogc3RyaW5nIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgIGNvbnN0IHN0cmluZ2lmeSA9IHJlcXVpcmUoXCJqc29uLXN0cmluZ2lmeS1kZXRlcm1pbmlzdGljXCIpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3Qgc29ydEtleXNSZWN1cnNpdmUgPSByZXF1aXJlKFwic29ydC1rZXlzLXJlY3Vyc2l2ZVwiKTtcbiAgICByZXR1cm4gc3RyaW5naWZ5KHNvcnRLZXlzUmVjdXJzaXZlKHRoaXMucHJlU2VyaWFsaXplKG1vZGVsKSkpO1xuICB9XG5cbiAgb3ZlcnJpZGUgcHJlU2VyaWFsaXplKG1vZGVsOiBNKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgY29uc3QgdG9TZXJpYWxpemU6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBPYmplY3QuYXNzaWduKHt9LCBtb2RlbCk7XG4gICAgcmV0dXJuIHRvU2VyaWFsaXplO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,7 @@
1
+ import { JSONSerializer, Model } from "@decaf-ts/decorator-validation";
2
+ export declare class SimpleDeterministicSerializer<M extends Model> extends JSONSerializer<M> {
3
+ constructor();
4
+ deserialize(str: string, tableName?: string): M;
5
+ serialize(model: M): string;
6
+ preSerialize(model: M): Record<string, any>;
7
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VERSION = exports.FabricFlavour = exports.IdentityType = exports.FabricModelKeys = void 0;
4
+ /**
5
+ * @description Keys used to mark Fabric-specific model metadata
6
+ * @summary Enumeration of special keys used by the serialization layer to persist Fabric-related flags on models
7
+ * @enum {string}
8
+ * @readonly
9
+ * @memberOf module:for-fabric.shared
10
+ */
11
+ var FabricModelKeys;
12
+ (function (FabricModelKeys) {
13
+ /** Private data marker used to tag properties or models for Fabric private collections */
14
+ FabricModelKeys["PRIVATE"] = "private";
15
+ /** Namespace prefix used for Fabric-specific metadata keys */
16
+ FabricModelKeys["FABRIC"] = "fabric.";
17
+ FabricModelKeys["OWNEDBY"] = "owned-by";
18
+ })(FabricModelKeys || (exports.FabricModelKeys = FabricModelKeys = {}));
19
+ /**
20
+ * @description Supported identity types for Fabric credentials
21
+ * @summary Enumeration of identity formats recognized by this library
22
+ * @enum {string}
23
+ * @readonly
24
+ * @memberOf module:for-fabric.shared
25
+ */
26
+ var IdentityType;
27
+ (function (IdentityType) {
28
+ /** Standard X.509 identity format used by Hyperledger Fabric */
29
+ IdentityType["X509"] = "X.509";
30
+ })(IdentityType || (exports.IdentityType = IdentityType = {}));
31
+ /**
32
+ * @description String identifier for the Fabric adapter flavour
33
+ * @summary Used to tag adapters/repositories that operate against Hyperledger Fabric
34
+ * @const FabricFlavour
35
+ * @memberOf module:for-fabric.shared
36
+ */
37
+ exports.FabricFlavour = "hlf-fabric";
38
+ /**
39
+ * @description Package version placeholder replaced at build time
40
+ * @summary Constant holding the current package version injected by the build pipeline
41
+ * @const VERSION
42
+ * @memberOf module:for-fabric.shared
43
+ */
44
+ exports.VERSION = "0.0.2";
45
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NoYXJlZC9jb25zdGFudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUE7Ozs7OztHQU1HO0FBQ0gsSUFBWSxlQU1YO0FBTkQsV0FBWSxlQUFlO0lBQ3pCLDBGQUEwRjtJQUMxRixzQ0FBbUIsQ0FBQTtJQUNuQiw4REFBOEQ7SUFDOUQscUNBQWtCLENBQUE7SUFDbEIsdUNBQW9CLENBQUE7QUFDdEIsQ0FBQyxFQU5XLGVBQWUsK0JBQWYsZUFBZSxRQU0xQjtBQUNEOzs7Ozs7R0FNRztBQUNILElBQVksWUFHWDtBQUhELFdBQVksWUFBWTtJQUN0QixnRUFBZ0U7SUFDaEUsOEJBQWMsQ0FBQTtBQUNoQixDQUFDLEVBSFcsWUFBWSw0QkFBWixZQUFZLFFBR3ZCO0FBRUQ7Ozs7O0dBS0c7QUFDVSxRQUFBLGFBQWEsR0FBRyxZQUFZLENBQUM7QUFFMUM7Ozs7O0dBS0c7QUFDVSxRQUFBLE9BQU8sR0FBRyxhQUFhLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBkZXNjcmlwdGlvbiBLZXlzIHVzZWQgdG8gbWFyayBGYWJyaWMtc3BlY2lmaWMgbW9kZWwgbWV0YWRhdGFcbiAqIEBzdW1tYXJ5IEVudW1lcmF0aW9uIG9mIHNwZWNpYWwga2V5cyB1c2VkIGJ5IHRoZSBzZXJpYWxpemF0aW9uIGxheWVyIHRvIHBlcnNpc3QgRmFicmljLXJlbGF0ZWQgZmxhZ3Mgb24gbW9kZWxzXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQHJlYWRvbmx5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZvci1mYWJyaWMuc2hhcmVkXG4gKi9cbmV4cG9ydCBlbnVtIEZhYnJpY01vZGVsS2V5cyB7XG4gIC8qKiBQcml2YXRlIGRhdGEgbWFya2VyIHVzZWQgdG8gdGFnIHByb3BlcnRpZXMgb3IgbW9kZWxzIGZvciBGYWJyaWMgcHJpdmF0ZSBjb2xsZWN0aW9ucyAqL1xuICBQUklWQVRFID0gXCJwcml2YXRlXCIsXG4gIC8qKiBOYW1lc3BhY2UgcHJlZml4IHVzZWQgZm9yIEZhYnJpYy1zcGVjaWZpYyBtZXRhZGF0YSBrZXlzICovXG4gIEZBQlJJQyA9IFwiZmFicmljLlwiLFxuICBPV05FREJZID0gXCJvd25lZC1ieVwiLFxufVxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU3VwcG9ydGVkIGlkZW50aXR5IHR5cGVzIGZvciBGYWJyaWMgY3JlZGVudGlhbHNcbiAqIEBzdW1tYXJ5IEVudW1lcmF0aW9uIG9mIGlkZW50aXR5IGZvcm1hdHMgcmVjb2duaXplZCBieSB0aGlzIGxpYnJhcnlcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Zm9yLWZhYnJpYy5zaGFyZWRcbiAqL1xuZXhwb3J0IGVudW0gSWRlbnRpdHlUeXBlIHtcbiAgLyoqIFN0YW5kYXJkIFguNTA5IGlkZW50aXR5IGZvcm1hdCB1c2VkIGJ5IEh5cGVybGVkZ2VyIEZhYnJpYyAqL1xuICBYNTA5ID0gXCJYLjUwOVwiLFxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBTdHJpbmcgaWRlbnRpZmllciBmb3IgdGhlIEZhYnJpYyBhZGFwdGVyIGZsYXZvdXJcbiAqIEBzdW1tYXJ5IFVzZWQgdG8gdGFnIGFkYXB0ZXJzL3JlcG9zaXRvcmllcyB0aGF0IG9wZXJhdGUgYWdhaW5zdCBIeXBlcmxlZGdlciBGYWJyaWNcbiAqIEBjb25zdCBGYWJyaWNGbGF2b3VyXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZvci1mYWJyaWMuc2hhcmVkXG4gKi9cbmV4cG9ydCBjb25zdCBGYWJyaWNGbGF2b3VyID0gXCJobGYtZmFicmljXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFBhY2thZ2UgdmVyc2lvbiBwbGFjZWhvbGRlciByZXBsYWNlZCBhdCBidWlsZCB0aW1lXG4gKiBAc3VtbWFyeSBDb25zdGFudCBob2xkaW5nIHRoZSBjdXJyZW50IHBhY2thZ2UgdmVyc2lvbiBpbmplY3RlZCBieSB0aGUgYnVpbGQgcGlwZWxpbmVcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZvci1mYWJyaWMuc2hhcmVkXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuIl19
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @description Keys used to mark Fabric-specific model metadata
3
+ * @summary Enumeration of special keys used by the serialization layer to persist Fabric-related flags on models
4
+ * @enum {string}
5
+ * @readonly
6
+ * @memberOf module:for-fabric.shared
7
+ */
8
+ export declare enum FabricModelKeys {
9
+ /** Private data marker used to tag properties or models for Fabric private collections */
10
+ PRIVATE = "private",
11
+ /** Namespace prefix used for Fabric-specific metadata keys */
12
+ FABRIC = "fabric.",
13
+ OWNEDBY = "owned-by"
14
+ }
15
+ /**
16
+ * @description Supported identity types for Fabric credentials
17
+ * @summary Enumeration of identity formats recognized by this library
18
+ * @enum {string}
19
+ * @readonly
20
+ * @memberOf module:for-fabric.shared
21
+ */
22
+ export declare enum IdentityType {
23
+ /** Standard X.509 identity format used by Hyperledger Fabric */
24
+ X509 = "X.509"
25
+ }
26
+ /**
27
+ * @description String identifier for the Fabric adapter flavour
28
+ * @summary Used to tag adapters/repositories that operate against Hyperledger Fabric
29
+ * @const FabricFlavour
30
+ * @memberOf module:for-fabric.shared
31
+ */
32
+ export declare const FabricFlavour = "hlf-fabric";
33
+ /**
34
+ * @description Package version placeholder replaced at build time
35
+ * @summary Constant holding the current package version injected by the build pipeline
36
+ * @const VERSION
37
+ * @memberOf module:for-fabric.shared
38
+ */
39
+ export declare const VERSION = "0.0.2";