@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.
- package/LICENSE.md +22 -0
- package/README.md +647 -0
- package/dist/for-fabric.cjs +6223 -0
- package/dist/for-fabric.esm.cjs +6180 -0
- package/lib/client/FabricClientAdapter.cjs +760 -0
- package/lib/client/FabricClientAdapter.d.ts +381 -0
- package/lib/client/FabricClientDispatch.cjs +186 -0
- package/lib/client/FabricClientDispatch.d.ts +125 -0
- package/lib/client/FabricClientRepository.cjs +131 -0
- package/lib/client/FabricClientRepository.d.ts +100 -0
- package/lib/client/erc20/erc20ClientRepository.cjs +343 -0
- package/lib/client/erc20/erc20ClientRepository.d.ts +254 -0
- package/lib/client/fabric-fs.cjs +234 -0
- package/lib/client/fabric-fs.d.ts +92 -0
- package/lib/client/index.cjs +30 -0
- package/lib/client/index.d.ts +13 -0
- package/lib/client/logging.cjs +102 -0
- package/lib/client/logging.d.ts +60 -0
- package/lib/client/services/LoggedService.cjs +47 -0
- package/lib/client/services/LoggedService.d.ts +42 -0
- package/lib/client/services/constants.cjs +3 -0
- package/lib/client/services/constants.d.ts +15 -0
- package/lib/client/services/enrollementService.cjs +344 -0
- package/lib/client/services/enrollementService.d.ts +176 -0
- package/lib/client/services/index.cjs +18 -0
- package/lib/client/services/index.d.ts +1 -0
- package/lib/contracts/ContractAdapter.cjs +730 -0
- package/lib/contracts/ContractAdapter.d.ts +296 -0
- package/lib/contracts/ContractContext.cjs +85 -0
- package/lib/contracts/ContractContext.d.ts +64 -0
- package/lib/contracts/ContractPrivateDataAdapter.cjs +281 -0
- package/lib/contracts/ContractPrivateDataAdapter.d.ts +74 -0
- package/lib/contracts/FabricConstruction.cjs +441 -0
- package/lib/contracts/FabricConstruction.d.ts +304 -0
- package/lib/contracts/FabricContractRepository.cjs +306 -0
- package/lib/contracts/FabricContractRepository.d.ts +162 -0
- package/lib/contracts/FabricContractRepositoryObservableHandler.cjs +85 -0
- package/lib/contracts/FabricContractRepositoryObservableHandler.d.ts +62 -0
- package/lib/contracts/FabricContractSequence.cjs +139 -0
- package/lib/contracts/FabricContractSequence.d.ts +61 -0
- package/lib/contracts/FabricContractStatement.cjs +119 -0
- package/lib/contracts/FabricContractStatement.d.ts +34 -0
- package/lib/contracts/PrivateSequence.cjs +36 -0
- package/lib/contracts/PrivateSequence.d.ts +15 -0
- package/lib/contracts/crud/crud-contract.cjs +257 -0
- package/lib/contracts/crud/crud-contract.d.ts +168 -0
- package/lib/contracts/crud/index.cjs +19 -0
- package/lib/contracts/crud/index.d.ts +2 -0
- package/lib/contracts/crud/serialized-crud-contract.cjs +172 -0
- package/lib/contracts/crud/serialized-crud-contract.d.ts +37 -0
- package/lib/contracts/erc20/erc20contract.cjs +569 -0
- package/lib/contracts/erc20/erc20contract.d.ts +151 -0
- package/lib/contracts/erc20/index.cjs +21 -0
- package/lib/contracts/erc20/index.d.ts +2 -0
- package/lib/contracts/erc20/models.cjs +209 -0
- package/lib/contracts/erc20/models.d.ts +114 -0
- package/lib/contracts/index.cjs +32 -0
- package/lib/contracts/index.d.ts +15 -0
- package/lib/contracts/logging.cjs +96 -0
- package/lib/contracts/logging.d.ts +49 -0
- package/lib/contracts/private-data.cjs +121 -0
- package/lib/contracts/private-data.d.ts +16 -0
- package/lib/contracts/types.cjs +3 -0
- package/lib/contracts/types.d.ts +26 -0
- package/lib/esm/client/FabricClientAdapter.d.ts +381 -0
- package/lib/esm/client/FabricClientAdapter.js +723 -0
- package/lib/esm/client/FabricClientDispatch.d.ts +125 -0
- package/lib/esm/client/FabricClientDispatch.js +182 -0
- package/lib/esm/client/FabricClientRepository.d.ts +100 -0
- package/lib/esm/client/FabricClientRepository.js +127 -0
- package/lib/esm/client/erc20/erc20ClientRepository.d.ts +254 -0
- package/lib/esm/client/erc20/erc20ClientRepository.js +339 -0
- package/lib/esm/client/fabric-fs.d.ts +92 -0
- package/lib/esm/client/fabric-fs.js +191 -0
- package/lib/esm/client/index.d.ts +13 -0
- package/lib/esm/client/index.js +14 -0
- package/lib/esm/client/logging.d.ts +60 -0
- package/lib/esm/client/logging.js +98 -0
- package/lib/esm/client/services/LoggedService.d.ts +42 -0
- package/lib/esm/client/services/LoggedService.js +43 -0
- package/lib/esm/client/services/constants.d.ts +15 -0
- package/lib/esm/client/services/constants.js +2 -0
- package/lib/esm/client/services/enrollementService.d.ts +176 -0
- package/lib/esm/client/services/enrollementService.js +337 -0
- package/lib/esm/client/services/index.d.ts +1 -0
- package/lib/esm/client/services/index.js +2 -0
- package/lib/esm/contracts/ContractAdapter.d.ts +296 -0
- package/lib/esm/contracts/ContractAdapter.js +724 -0
- package/lib/esm/contracts/ContractContext.d.ts +64 -0
- package/lib/esm/contracts/ContractContext.js +81 -0
- package/lib/esm/contracts/ContractPrivateDataAdapter.d.ts +74 -0
- package/lib/esm/contracts/ContractPrivateDataAdapter.js +277 -0
- package/lib/esm/contracts/FabricConstruction.d.ts +304 -0
- package/lib/esm/contracts/FabricConstruction.js +433 -0
- package/lib/esm/contracts/FabricContractRepository.d.ts +162 -0
- package/lib/esm/contracts/FabricContractRepository.js +302 -0
- package/lib/esm/contracts/FabricContractRepositoryObservableHandler.d.ts +62 -0
- package/lib/esm/contracts/FabricContractRepositoryObservableHandler.js +81 -0
- package/lib/esm/contracts/FabricContractSequence.d.ts +61 -0
- package/lib/esm/contracts/FabricContractSequence.js +135 -0
- package/lib/esm/contracts/FabricContractStatement.d.ts +34 -0
- package/lib/esm/contracts/FabricContractStatement.js +115 -0
- package/lib/esm/contracts/PrivateSequence.d.ts +15 -0
- package/lib/esm/contracts/PrivateSequence.js +33 -0
- package/lib/esm/contracts/crud/crud-contract.d.ts +168 -0
- package/lib/esm/contracts/crud/crud-contract.js +253 -0
- package/lib/esm/contracts/crud/index.d.ts +2 -0
- package/lib/esm/contracts/crud/index.js +3 -0
- package/lib/esm/contracts/crud/serialized-crud-contract.d.ts +37 -0
- package/lib/esm/contracts/crud/serialized-crud-contract.js +168 -0
- package/lib/esm/contracts/erc20/erc20contract.d.ts +151 -0
- package/lib/esm/contracts/erc20/erc20contract.js +565 -0
- package/lib/esm/contracts/erc20/index.d.ts +2 -0
- package/lib/esm/contracts/erc20/index.js +4 -0
- package/lib/esm/contracts/erc20/models.d.ts +114 -0
- package/lib/esm/contracts/erc20/models.js +206 -0
- package/lib/esm/contracts/index.d.ts +15 -0
- package/lib/esm/contracts/index.js +16 -0
- package/lib/esm/contracts/logging.d.ts +49 -0
- package/lib/esm/contracts/logging.js +92 -0
- package/lib/esm/contracts/private-data.d.ts +16 -0
- package/lib/esm/contracts/private-data.js +113 -0
- package/lib/esm/contracts/types.d.ts +26 -0
- package/lib/esm/contracts/types.js +2 -0
- package/lib/esm/index.d.ts +8 -0
- package/lib/esm/index.js +9 -0
- package/lib/esm/shared/ClientSerializer.d.ts +52 -0
- package/lib/esm/shared/ClientSerializer.js +80 -0
- package/lib/esm/shared/DeterministicSerializer.d.ts +40 -0
- package/lib/esm/shared/DeterministicSerializer.js +50 -0
- package/lib/esm/shared/SimpleDeterministicSerializer.d.ts +7 -0
- package/lib/esm/shared/SimpleDeterministicSerializer.js +42 -0
- package/lib/esm/shared/constants.d.ts +39 -0
- package/lib/esm/shared/constants.js +42 -0
- package/lib/esm/shared/crypto.d.ts +107 -0
- package/lib/esm/shared/crypto.js +331 -0
- package/lib/esm/shared/decorators.d.ts +24 -0
- package/lib/esm/shared/decorators.js +98 -0
- package/lib/esm/shared/erc20/erc20-constants.d.ts +25 -0
- package/lib/esm/shared/erc20/erc20-constants.js +27 -0
- package/lib/esm/shared/errors.d.ts +116 -0
- package/lib/esm/shared/errors.js +132 -0
- package/lib/esm/shared/events.d.ts +39 -0
- package/lib/esm/shared/events.js +47 -0
- package/lib/esm/shared/fabric-types.d.ts +33 -0
- package/lib/esm/shared/fabric-types.js +2 -0
- package/lib/esm/shared/index.d.ts +13 -0
- package/lib/esm/shared/index.js +14 -0
- package/lib/esm/shared/interfaces/Checkable.d.ts +21 -0
- package/lib/esm/shared/interfaces/Checkable.js +2 -0
- package/lib/esm/shared/math.d.ts +34 -0
- package/lib/esm/shared/math.js +61 -0
- package/lib/esm/shared/model/Identity.d.ts +42 -0
- package/lib/esm/shared/model/Identity.js +78 -0
- package/lib/esm/shared/model/IdentityCredentials.d.ts +41 -0
- package/lib/esm/shared/model/IdentityCredentials.js +74 -0
- package/lib/esm/shared/model/index.d.ts +1 -0
- package/lib/esm/shared/model/index.js +2 -0
- package/lib/esm/shared/model/utils.d.ts +60 -0
- package/lib/esm/shared/model/utils.js +108 -0
- package/lib/esm/shared/types.d.ts +79 -0
- package/lib/esm/shared/types.js +2 -0
- package/lib/esm/shared/utils.d.ts +55 -0
- package/lib/esm/shared/utils.js +148 -0
- package/lib/index.cjs +25 -0
- package/lib/index.d.ts +8 -0
- package/lib/shared/ClientSerializer.cjs +84 -0
- package/lib/shared/ClientSerializer.d.ts +52 -0
- package/lib/shared/DeterministicSerializer.cjs +54 -0
- package/lib/shared/DeterministicSerializer.d.ts +40 -0
- package/lib/shared/SimpleDeterministicSerializer.cjs +46 -0
- package/lib/shared/SimpleDeterministicSerializer.d.ts +7 -0
- package/lib/shared/constants.cjs +45 -0
- package/lib/shared/constants.d.ts +39 -0
- package/lib/shared/crypto.cjs +369 -0
- package/lib/shared/crypto.d.ts +107 -0
- package/lib/shared/decorators.cjs +105 -0
- package/lib/shared/decorators.d.ts +24 -0
- package/lib/shared/erc20/erc20-constants.cjs +30 -0
- package/lib/shared/erc20/erc20-constants.d.ts +25 -0
- package/lib/shared/errors.cjs +142 -0
- package/lib/shared/errors.d.ts +116 -0
- package/lib/shared/events.cjs +51 -0
- package/lib/shared/events.d.ts +39 -0
- package/lib/shared/fabric-types.cjs +4 -0
- package/lib/shared/fabric-types.d.ts +33 -0
- package/lib/shared/index.cjs +30 -0
- package/lib/shared/index.d.ts +13 -0
- package/lib/shared/interfaces/Checkable.cjs +3 -0
- package/lib/shared/interfaces/Checkable.d.ts +21 -0
- package/lib/shared/math.cjs +66 -0
- package/lib/shared/math.d.ts +34 -0
- package/lib/shared/model/Identity.cjs +81 -0
- package/lib/shared/model/Identity.d.ts +42 -0
- package/lib/shared/model/IdentityCredentials.cjs +77 -0
- package/lib/shared/model/IdentityCredentials.d.ts +41 -0
- package/lib/shared/model/index.cjs +18 -0
- package/lib/shared/model/index.d.ts +1 -0
- package/lib/shared/model/utils.cjs +114 -0
- package/lib/shared/model/utils.d.ts +60 -0
- package/lib/shared/types.cjs +3 -0
- package/lib/shared/types.d.ts +79 -0
- package/lib/shared/utils.cjs +185 -0
- package/lib/shared/utils.d.ts +55 -0
- package/package.json +166 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { getAllPropertyDecoratorsRecursive, InternalError, modelToTransient, SerializationError, } from "@decaf-ts/db-decorators";
|
|
2
|
+
import { Model } from "@decaf-ts/decorator-validation";
|
|
3
|
+
import { Repository } from "@decaf-ts/core";
|
|
4
|
+
import { getFabricModelKey } from "./../shared/decorators.js";
|
|
5
|
+
import { FabricModelKeys } from "./../shared/constants.js";
|
|
6
|
+
export const MISSING_PRIVATE_DATA_REGEX = /private\s+data\s+matching\s+public\s+hash\s+version\s+is\s+not\s+available/i;
|
|
7
|
+
export const MISSING_PRIVATE_DATA_ERROR_MESSAGE = "private data matching public hash version is not available ...";
|
|
8
|
+
export function processModel(adapter, model) {
|
|
9
|
+
const transient = modelToTransient(model);
|
|
10
|
+
const privateData = modelToPrivate(model);
|
|
11
|
+
const transformModel = (model) => {
|
|
12
|
+
return Object.entries(model).reduce((accum, [key, val]) => {
|
|
13
|
+
if (typeof val === "undefined")
|
|
14
|
+
return accum;
|
|
15
|
+
const mappedProp = Repository.column(model, key);
|
|
16
|
+
if (adapter.isReserved(mappedProp))
|
|
17
|
+
throw new InternalError(`Property name ${mappedProp} is reserved`);
|
|
18
|
+
accum[mappedProp] = val;
|
|
19
|
+
return accum;
|
|
20
|
+
}, {});
|
|
21
|
+
};
|
|
22
|
+
if (privateData.private) {
|
|
23
|
+
const collections = Object.keys(privateData.private);
|
|
24
|
+
for (const collection of collections) {
|
|
25
|
+
privateData.private[collection] = transformModel(privateData.private[collection]);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
model: transient.model,
|
|
30
|
+
transient: transient.transient,
|
|
31
|
+
privateData: privateData.private,
|
|
32
|
+
result: transformModel(transient.model),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export function hasPrivateData(model) {
|
|
36
|
+
const metadata = getClassPrivateDataMetadata(model);
|
|
37
|
+
if (!metadata)
|
|
38
|
+
return false;
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
export function getClassPrivateDataMetadata(model) {
|
|
42
|
+
let metadata = Reflect.getMetadata(getFabricModelKey(FabricModelKeys.PRIVATE), model);
|
|
43
|
+
metadata =
|
|
44
|
+
metadata ||
|
|
45
|
+
Reflect.getMetadata(getFabricModelKey(FabricModelKeys.PRIVATE), model.constructor);
|
|
46
|
+
return metadata;
|
|
47
|
+
}
|
|
48
|
+
export function isModelPrivate(model) {
|
|
49
|
+
const metadata = getClassPrivateDataMetadata(model);
|
|
50
|
+
if (!metadata || metadata.isPrivate === undefined)
|
|
51
|
+
return false;
|
|
52
|
+
return metadata.isPrivate;
|
|
53
|
+
}
|
|
54
|
+
export function modelToPrivate(model) {
|
|
55
|
+
if (!hasPrivateData(model))
|
|
56
|
+
return { model: model };
|
|
57
|
+
const decs = getAllPropertyDecoratorsRecursive(model, undefined, getFabricModelKey(FabricModelKeys.PRIVATE));
|
|
58
|
+
const isPrivate = isModelPrivate(model);
|
|
59
|
+
const modelCollections = getClassPrivateDataMetadata(model);
|
|
60
|
+
let result = {
|
|
61
|
+
model: model,
|
|
62
|
+
private: undefined,
|
|
63
|
+
};
|
|
64
|
+
if (isPrivate) {
|
|
65
|
+
result = Object.keys(model).reduce((accum, k) => {
|
|
66
|
+
const collections = modelCollections.collections;
|
|
67
|
+
accum.private = accum.private || {};
|
|
68
|
+
for (const collection of collections) {
|
|
69
|
+
try {
|
|
70
|
+
accum.private[collection] = accum.private[collection] || {};
|
|
71
|
+
accum.private[collection][k] = model[k];
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
throw new SerializationError(`Failed to serialize private property ${k}: ${e}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return accum;
|
|
78
|
+
}, { model: {} });
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
result = Object.entries(decs).reduce((accum, [k, val]) => {
|
|
82
|
+
const privateData = val.find((el) => el.key === "");
|
|
83
|
+
if (privateData) {
|
|
84
|
+
const collections = privateData.props.collections;
|
|
85
|
+
accum.private = accum.private || {};
|
|
86
|
+
for (const collection of collections) {
|
|
87
|
+
try {
|
|
88
|
+
accum.private[collection] = accum.private[collection] || {};
|
|
89
|
+
accum.private[collection][k] = model[k];
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
throw new SerializationError(`Failed to serialize private property ${k}: ${e}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
accum.model = accum.model || {};
|
|
98
|
+
accum.model[k] = model[k];
|
|
99
|
+
}
|
|
100
|
+
return accum;
|
|
101
|
+
}, {});
|
|
102
|
+
}
|
|
103
|
+
result.model = result.model || {};
|
|
104
|
+
result.model = Model.build(result.model, model.constructor.name);
|
|
105
|
+
if (result.private) {
|
|
106
|
+
const collections = Object.keys(result.private);
|
|
107
|
+
for (const collection of collections) {
|
|
108
|
+
result.private[collection] = Model.build(result.private[collection], model.constructor.name);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmF0ZS1kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbnRyYWN0cy9wcml2YXRlLWRhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGlDQUFpQyxFQUNqQyxhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGtCQUFrQixHQUNuQixNQUFNLHlCQUF5QixDQUFDO0FBQ2pDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN2RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGtDQUE2QjtBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLGlDQUE0QjtBQUV0RCxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FDckMsNkVBQTZFLENBQUM7QUFFaEYsTUFBTSxDQUFDLE1BQU0sa0NBQWtDLEdBQzdDLGdFQUFnRSxDQUFDO0FBRW5FLE1BQU0sVUFBVSxZQUFZLENBQWtCLE9BQVksRUFBRSxLQUFRO0lBQ2xFLE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFDLE1BQU0sV0FBVyxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUUxQyxNQUFNLGNBQWMsR0FBRyxDQUFDLEtBQVUsRUFBRSxFQUFFO1FBQ3BDLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQ2pDLENBQUMsS0FBMEIsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFO1lBQ3pDLElBQUksT0FBTyxHQUFHLEtBQUssV0FBVztnQkFBRSxPQUFPLEtBQUssQ0FBQztZQUM3QyxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNqRCxJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFD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SCxDQUFDO0lBQ0QsT0FBTyxNQUFxRSxDQUFDO0FBQy9FLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUsXG4gIEludGVybmFsRXJyb3IsXG4gIG1vZGVsVG9UcmFuc2llbnQsXG4gIFNlcmlhbGl6YXRpb25FcnJvcixcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IGdldEZhYnJpY01vZGVsS2V5IH0gZnJvbSBcIi4uL3NoYXJlZC9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBGYWJyaWNNb2RlbEtleXMgfSBmcm9tIFwiLi4vc2hhcmVkL2NvbnN0YW50c1wiO1xuXG5leHBvcnQgY29uc3QgTUlTU0lOR19QUklWQVRFX0RBVEFfUkVHRVggPVxuICAvcHJpdmF0ZVxccytkYXRhXFxzK21hdGNoaW5nXFxzK3B1YmxpY1xccytoYXNoXFxzK3ZlcnNpb25cXHMraXNcXHMrbm90XFxzK2F2YWlsYWJsZS9pO1xuXG5leHBvcnQgY29uc3QgTUlTU0lOR19QUklWQVRFX0RBVEFfRVJST1JfTUVTU0FHRSA9XG4gIFwicHJpdmF0ZSBkYXRhIG1hdGNoaW5nIHB1YmxpYyBoYXNoIHZlcnNpb24gaXMgbm90IGF2YWlsYWJsZSAuLi5cIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHByb2Nlc3NNb2RlbDxNIGV4dGVuZHMgTW9kZWw+KGFkYXB0ZXI6IGFueSwgbW9kZWw6IE0pIHtcbiAgY29uc3QgdHJhbnNpZW50ID0gbW9kZWxUb1RyYW5zaWVudChtb2RlbCk7XG4gIGNvbnN0IHByaXZhdGVEYXRhID0gbW9kZWxUb1ByaXZhdGUobW9kZWwpO1xuXG4gIGNvbnN0IHRyYW5zZm9ybU1vZGVsID0gKG1vZGVsOiBhbnkpID0+IHtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMobW9kZWwpLnJlZHVjZShcbiAgICAgIChhY2N1bTogUmVjb3JkPHN0cmluZywgYW55PiwgW2tleSwgdmFsXSkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIGFjY3VtO1xuICAgICAgICBjb25zdCBtYXBwZWRQcm9wID0gUmVwb3NpdG9yeS5jb2x1bW4obW9kZWwsIGtleSk7XG4gICAgICAgIGlmIChhZGFwdGVyLmlzUmVzZXJ2ZWQobWFwcGVkUHJvcCkpXG4gICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYFByb3BlcnR5IG5hbWUgJHttYXBwZWRQcm9wfSBpcyByZXNlcnZlZGApO1xuICAgICAgICBhY2N1bVttYXBwZWRQcm9wXSA9IHZhbDtcbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSxcbiAgICAgIHt9XG4gICAgKTtcbiAgfTtcblxuICBpZiAocHJpdmF0ZURhdGEucHJpdmF0ZSkge1xuICAgIGNvbnN0IGNvbGxlY3Rpb25zID0gT2JqZWN0LmtleXMocHJpdmF0ZURhdGEucHJpdmF0ZSk7XG5cbiAgICBmb3IgKGNvbnN0IGNvbGxlY3Rpb24gb2YgY29sbGVjdGlvbnMpIHtcbiAgICAgIHByaXZhdGVEYXRhLnByaXZhdGUhW2NvbGxlY3Rpb25dID0gdHJhbnNmb3JtTW9kZWwoXG4gICAgICAgIHByaXZhdGVEYXRhLnByaXZhdGUhW2NvbGxlY3Rpb25dXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbW9kZWw6IHRyYW5zaWVudC5tb2RlbCxcbiAgICB0cmFuc2llbnQ6IHRyYW5zaWVudC50cmFuc2llbnQsXG4gICAgcHJpdmF0ZURhdGE6IHByaXZhdGVEYXRhLnByaXZhdGUsXG4gICAgcmVzdWx0OiB0cmFuc2Zvcm1Nb2RlbCh0cmFuc2llbnQubW9kZWwpLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzUHJpdmF0ZURhdGE8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSkge1xuICBjb25zdCBtZXRhZGF0YSA9IGdldENsYXNzUHJpdmF0ZURhdGFNZXRhZGF0YShtb2RlbCk7XG4gIGlmICghbWV0YWRhdGEpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbGFzc1ByaXZhdGVEYXRhTWV0YWRhdGE8TSBleHRlbmRzIE1vZGVsPihcbiAgbW9kZWw6IE1cbik6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICBsZXQgbWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgIGdldEZhYnJpY01vZGVsS2V5KEZhYnJpY01vZGVsS2V5cy5QUklWQVRFKSxcbiAgICBtb2RlbFxuICApO1xuXG4gIG1ldGFkYXRhID1cbiAgICBtZXRhZGF0YSB8fFxuICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBnZXRGYWJyaWNNb2RlbEtleShGYWJyaWNNb2RlbEtleXMuUFJJVkFURSksXG4gICAgICBtb2RlbC5jb25zdHJ1Y3RvclxuICAgICk7XG5cbiAgcmV0dXJuIG1ldGFkYXRhO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNNb2RlbFByaXZhdGU8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSk6IGJvb2xlYW4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGdldENsYXNzUHJpdmF0ZURhdGFNZXRhZGF0YShtb2RlbCk7XG4gIGlmICghbWV0YWRhdGEgfHwgbWV0YWRhdGEuaXNQcml2YXRlID09PSB1bmRlZmluZWQpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIG1ldGFkYXRhLmlzUHJpdmF0ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1vZGVsVG9Qcml2YXRlPE0gZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsOiBNXG4pOiB7IG1vZGVsOiBNOyBwcml2YXRlPzogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgYW55Pj4gfSB7XG4gIGlmICghaGFzUHJpdmF0ZURhdGEobW9kZWwpKSByZXR1cm4geyBtb2RlbDogbW9kZWwgfTtcbiAgY29uc3QgZGVjczogUmVjb3JkPHN0cmluZywgYW55W10+ID0gZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlKFxuICAgIG1vZGVsLFxuICAgIHVuZGVmaW5lZCxcbiAgICBnZXRGYWJyaWNNb2RlbEtleShGYWJyaWNNb2RlbEtleXMuUFJJVkFURSlcbiAgKSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnlbXT47XG5cbiAgY29uc3QgaXNQcml2YXRlID0gaXNNb2RlbFByaXZhdGUobW9kZWwpO1xuICBjb25zdCBtb2RlbENvbGxlY3Rpb25zOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID1cbiAgICBnZXRDbGFzc1ByaXZhdGVEYXRhTWV0YWRhdGEobW9kZWwpO1xuXG4gIGxldCByZXN1bHQ6IHsgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT47IHByaXZhdGU/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+IH0gPSB7XG4gICAgbW9kZWw6IG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgcHJpdmF0ZTogdW5kZWZpbmVkLFxuICB9O1xuXG4gIGlmIChpc1ByaXZhdGUpIHtcbiAgICByZXN1bHQgPSBPYmplY3Qua2V5cyhtb2RlbCkucmVkdWNlKFxuICAgICAgKFxuICAgICAgICBhY2N1bTogeyBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PjsgcHJpdmF0ZT86IFJlY29yZDxzdHJpbmcsIGFueT4gfSxcbiAgICAgICAga1xuICAgICAgKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbGxlY3Rpb25zID0gbW9kZWxDb2xsZWN0aW9ucy5jb2xsZWN0aW9ucztcbiAgICAgICAgYWNjdW0ucHJpdmF0ZSA9IGFjY3VtLnByaXZhdGUgfHwge307XG5cbiAgICAgICAgZm9yIChjb25zdCBjb2xsZWN0aW9uIG9mIGNvbGxlY3Rpb25zKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGFjY3VtLnByaXZhdGVbY29sbGVjdGlvbl0gPSBhY2N1bS5wcml2YXRlW2NvbGxlY3Rpb25dIHx8IHt9O1xuICAgICAgICAgICAgYWNjdW0ucHJpdmF0ZVtjb2xsZWN0aW9uXVtrXSA9IG1vZGVsW2sgYXMga2V5b2YgTV07XG4gICAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICAgICAgICAgYEZhaWxlZCB0byBzZXJpYWxpemUgcHJpdmF0ZSBwcm9wZXJ0eSAke2t9OiAke2V9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LFxuICAgICAgeyBtb2RlbDoge30gfSBhcyB7XG4gICAgICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgICAgICBwcml2YXRlPzogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICAgIH1cbiAgICApO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdCA9IE9iamVjdC5lbnRyaWVzKGRlY3MpLnJlZHVjZShcbiAgICAgIChcbiAgICAgICAgYWNjdW06IHsgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT47IHByaXZhdGU/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+IH0sXG4gICAgICAgIFtrLCB2YWxdXG4gICAgICApID0+IHtcbiAgICAgICAgY29uc3QgcHJpdmF0ZURhdGEgPSB2YWwuZmluZCgoZWwpID0+IGVsLmtleSA9PT0gXCJcIik7XG5cbiAgICAgICAgaWYgKHByaXZhdGVEYXRhKSB7XG4gICAgICAgICAgY29uc3QgY29sbGVjdGlvbnMgPSBwcml2YXRlRGF0YS5wcm9wcy5jb2xsZWN0aW9ucztcblxuICAgICAgICAgIGFjY3VtLnByaXZhdGUgPSBhY2N1bS5wcml2YXRlIHx8IHt9O1xuXG4gICAgICAgICAgZm9yIChjb25zdCBjb2xsZWN0aW9uIG9mIGNvbGxlY3Rpb25zKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBhY2N1bS5wcml2YXRlW2NvbGxlY3Rpb25dID0gYWNjdW0ucHJpdmF0ZVtjb2xsZWN0aW9uXSB8fCB7fTtcbiAgICAgICAgICAgICAgYWNjdW0ucHJpdmF0ZVtjb2xsZWN0aW9uXVtrXSA9IG1vZGVsW2sgYXMga2V5b2YgTV07XG4gICAgICAgICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAgICAgICAgICAgYEZhaWxlZCB0byBzZXJpYWxpemUgcHJpdmF0ZSBwcm9wZXJ0eSAke2t9OiAke2V9YFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhY2N1bS5tb2RlbCA9IGFjY3VtLm1vZGVsIHx8IHt9O1xuICAgICAgICAgIGFjY3VtLm1vZGVsW2tdID0gKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sXG4gICAgICB7fSBhcyB7IG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+OyBwcml2YXRlPzogUmVjb3JkPHN0cmluZywgYW55PiB9XG4gICAgKTtcbiAgfVxuXG4gIHJlc3VsdC5tb2RlbCA9IHJlc3VsdC5tb2RlbCB8fCB7fTtcblxuICByZXN1bHQubW9kZWwgPSBNb2RlbC5idWlsZChyZXN1bHQubW9kZWwsIG1vZGVsLmNvbnN0cnVjdG9yLm5hbWUpO1xuXG4gIGlmIChyZXN1bHQucHJpdmF0ZSkge1xuICAgIGNvbnN0IGNvbGxlY3Rpb25zID0gT2JqZWN0LmtleXMocmVzdWx0LnByaXZhdGUpO1xuXG4gICAgZm9yIChjb25zdCBjb2xsZWN0aW9uIG9mIGNvbGxlY3Rpb25zKSB7XG4gICAgICByZXN1bHQucHJpdmF0ZSFbY29sbGVjdGlvbl0gPSBNb2RlbC5idWlsZChcbiAgICAgICAgcmVzdWx0LnByaXZhdGUhW2NvbGxlY3Rpb25dLFxuICAgICAgICBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lXG4gICAgICApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0IGFzIHsgbW9kZWw6IE07IHByaXZhdGU/OiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBhbnk+PiB9O1xufVxuIl19
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { RepositoryFlags } from "@decaf-ts/db-decorators";
|
|
2
|
+
import { ChaincodeStub, ClientIdentity } from "fabric-shim-api";
|
|
3
|
+
import { Logger } from "@decaf-ts/logging";
|
|
4
|
+
/**
|
|
5
|
+
* @description Flags for Fabric chaincode contract operations
|
|
6
|
+
* @summary Extends repository flags with Fabric-specific context elements available during Fabric chaincode execution, such as the ChaincodeStub, ClientIdentity and a request-scoped Logger.
|
|
7
|
+
* @template T
|
|
8
|
+
* @param {RepositoryFlags} [base] - Base repository flags that these Fabric-specific flags extend
|
|
9
|
+
* @return {void}
|
|
10
|
+
* @interface FabricContractFlags
|
|
11
|
+
* @memberOf module:fabric.contracts
|
|
12
|
+
*/
|
|
13
|
+
export interface FabricContractFlags extends RepositoryFlags {
|
|
14
|
+
/**
|
|
15
|
+
* @description Chaincode stub for interacting with the ledger
|
|
16
|
+
*/
|
|
17
|
+
stub: ChaincodeStub;
|
|
18
|
+
/**
|
|
19
|
+
* @description Client identity for the transaction submitter
|
|
20
|
+
*/
|
|
21
|
+
clientIdentity: ClientIdentity;
|
|
22
|
+
/**
|
|
23
|
+
* @description Logger instance for the contract
|
|
24
|
+
*/
|
|
25
|
+
logger: Logger;
|
|
26
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29udHJhY3RzL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXBvc2l0b3J5RmxhZ3MgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IENoYWluY29kZVN0dWIsIENsaWVudElkZW50aXR5IH0gZnJvbSBcImZhYnJpYy1zaGltLWFwaVwiO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEZsYWdzIGZvciBGYWJyaWMgY2hhaW5jb2RlIGNvbnRyYWN0IG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IEV4dGVuZHMgcmVwb3NpdG9yeSBmbGFncyB3aXRoIEZhYnJpYy1zcGVjaWZpYyBjb250ZXh0IGVsZW1lbnRzIGF2YWlsYWJsZSBkdXJpbmcgRmFicmljIGNoYWluY29kZSBleGVjdXRpb24sIHN1Y2ggYXMgdGhlIENoYWluY29kZVN0dWIsIENsaWVudElkZW50aXR5IGFuZCBhIHJlcXVlc3Qtc2NvcGVkIExvZ2dlci5cbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0ge1JlcG9zaXRvcnlGbGFnc30gW2Jhc2VdIC0gQmFzZSByZXBvc2l0b3J5IGZsYWdzIHRoYXQgdGhlc2UgRmFicmljLXNwZWNpZmljIGZsYWdzIGV4dGVuZFxuICogQHJldHVybiB7dm9pZH1cbiAqIEBpbnRlcmZhY2UgRmFicmljQ29udHJhY3RGbGFnc1xuICogQG1lbWJlck9mIG1vZHVsZTpmYWJyaWMuY29udHJhY3RzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRmFicmljQ29udHJhY3RGbGFncyBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ2hhaW5jb2RlIHN0dWIgZm9yIGludGVyYWN0aW5nIHdpdGggdGhlIGxlZGdlclxuICAgKi9cbiAgc3R1YjogQ2hhaW5jb2RlU3R1YjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENsaWVudCBpZGVudGl0eSBmb3IgdGhlIHRyYW5zYWN0aW9uIHN1Ym1pdHRlclxuICAgKi9cbiAgY2xpZW50SWRlbnRpdHk6IENsaWVudElkZW50aXR5O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgY29udHJhY3RcbiAgICovXG4gIGxvZ2dlcjogTG9nZ2VyO1xufVxuIl19
|
|
@@ -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";
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
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/index.js";
|
|
7
|
+
export * from "./contracts/index.js";
|
|
8
|
+
export * from "./shared/index.js";
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILGtDQUF5QjtBQUN6QixxQ0FBNEI7QUFDNUIsa0NBQXlCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZGVzY3JpcHRpb24gSHlwZXJsZWRnZXIgRmFicmljIE1vZHVsZSBmb3IgRGVjYWYtdHNcbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGNsaWVudC1zaWRlIGFuZCBjaGFpbmNvZGUtc2lkZSB0b29saW5nIGZvciBidWlsZGluZyBIeXBlcmxlZGdlciBGYWJyaWMgYXBwbGljYXRpb25zIHdpdGggRGVjYWYtdHMuIEV4cG9zZXMgY2xpZW50IGFkYXB0ZXJzLCByZXBvc2l0b3JpZXMsIGNvbnRyYWN0IGFkYXB0ZXJzLCBzZXF1ZW5jZXMsIHV0aWxpdGllcywgYW5kIHNoYXJlZCB0eXBlcyB0byBzdHJlYW1saW5lIGRldmVsb3BtZW50IGFuZCBpbnRlcmFjdGlvbiB3aXRoIEZhYnJpYyBuZXR3b3Jrcy4gU2VlIHtAbGluayBtb2R1bGU6ZmFicmljLmNsaWVudH0sIHtAbGluayBtb2R1bGU6ZmFicmljLmNvbnRyYWN0c30sIGFuZCB7QGxpbmsgbW9kdWxlOmZhYnJpYy5zaGFyZWR9IGZvciBncm91cGVkIGV4cG9ydHMuXG4gKiBAbW9kdWxlIGZvci1mYWJyaWNcbiAqL1xuXG5leHBvcnQgKiBmcm9tIFwiLi9jbGllbnRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRyYWN0c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vc2hhcmVkXCI7XG4iXX0=
|
|
@@ -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,80 @@
|
|
|
1
|
+
import { getMetadata, JSONSerializer, Model, ModelKeys, } from "@decaf-ts/decorator-validation";
|
|
2
|
+
import { SerializationError } from "@decaf-ts/db-decorators";
|
|
3
|
+
/**
|
|
4
|
+
* @description Client-side JSON serializer for Decaf models targeting Hyperledger Fabric
|
|
5
|
+
* @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.
|
|
6
|
+
* @template M extends Model - The Decaf model type handled by this serializer
|
|
7
|
+
* @param {void} [constructor] No public constructor arguments; provided for documentation completeness
|
|
8
|
+
* @return {void}
|
|
9
|
+
* @class ClientSerializer
|
|
10
|
+
* @example
|
|
11
|
+
* const serializer = new ClientSerializer<User>();
|
|
12
|
+
* const json = serializer.serialize(new User({ id: "1", name: "Alice" }));
|
|
13
|
+
* const user = serializer.deserialize(json);
|
|
14
|
+
* @mermaid
|
|
15
|
+
* sequenceDiagram
|
|
16
|
+
* participant App
|
|
17
|
+
* participant Serializer as ClientSerializer
|
|
18
|
+
* participant Model
|
|
19
|
+
* App->>Serializer: serialize(model)
|
|
20
|
+
* Serializer->>Serializer: preSerialize(model)
|
|
21
|
+
* Serializer-->>App: JSON string
|
|
22
|
+
* App->>Serializer: deserialize(json)
|
|
23
|
+
* Serializer->>Serializer: JSON.parse(json)
|
|
24
|
+
* Serializer->>Model: Model.build(parsed, anchor)
|
|
25
|
+
* Model-->>App: instance
|
|
26
|
+
*/
|
|
27
|
+
export class ClientSerializer extends JSONSerializer {
|
|
28
|
+
constructor() {
|
|
29
|
+
super();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* @description Prepare a model for JSON serialization embedding class anchor
|
|
33
|
+
* @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.
|
|
34
|
+
* @template M - Model type handled by this serializer
|
|
35
|
+
* @param {M} model - The model instance to serialize
|
|
36
|
+
* @param {string} [table] - Optional table name to use when metadata cannot be derived
|
|
37
|
+
* @return {Record<string, any>} A plain object ready to be JSON.stringify'd
|
|
38
|
+
*/
|
|
39
|
+
preSerialize(model, table) {
|
|
40
|
+
// TODO: nested preserialization (so increase performance when deserializing)
|
|
41
|
+
const toSerialize = Object.assign({}, model);
|
|
42
|
+
let metadata;
|
|
43
|
+
try {
|
|
44
|
+
metadata = getMetadata(model);
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
metadata = table;
|
|
49
|
+
}
|
|
50
|
+
if (!metadata)
|
|
51
|
+
throw new SerializationError(`Could not find metadata for ${model.constructor.name}`);
|
|
52
|
+
toSerialize[ModelKeys.ANCHOR] = metadata;
|
|
53
|
+
return toSerialize;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @description Rebuilds a model from its JSON serialization
|
|
57
|
+
* @summary Parses the JSON string, retrieves the embedded model anchor, and uses Model.build to reconstruct the original instance
|
|
58
|
+
* @param {string} str - The JSON string previously produced by serialize
|
|
59
|
+
* @return {M} The reconstructed model instance
|
|
60
|
+
*/
|
|
61
|
+
deserialize(str) {
|
|
62
|
+
const deserialization = JSON.parse(str);
|
|
63
|
+
const className = deserialization[ModelKeys.ANCHOR];
|
|
64
|
+
if (!className)
|
|
65
|
+
throw new Error("Could not find class reference in serialized model");
|
|
66
|
+
const model = Model.build(deserialization, className);
|
|
67
|
+
return model;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* @description Serializes a model to a JSON string
|
|
71
|
+
* @summary Prepares the model via preSerialize, embedding metadata needed for reconstruction, and returns a JSON string representation
|
|
72
|
+
* @param {M} model - The model instance to serialize
|
|
73
|
+
* @param {string} [table] - Optional table name to include as anchor when metadata is unavailable
|
|
74
|
+
* @return {string} A JSON string containing the serialized model with anchor metadata
|
|
75
|
+
*/
|
|
76
|
+
serialize(model, table) {
|
|
77
|
+
return JSON.stringify(this.preSerialize(model, table));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2xpZW50U2VyaWFsaXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zaGFyZWQvQ2xpZW50U2VyaWFsaXplci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsV0FBVyxFQUNYLGNBQWMsRUFDZCxLQUFLLEVBQ0wsU0FBUyxHQUNWLE1BQU0sZ0NBQWdDLENBQUM7QUFDeEMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFN0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUJHO0FBQ0gsTUFBTSxPQUFPLGdCQUFrQyxTQUFRLGNBQWlCO0lBQ3RFO1FBQ0UsS0FBSyxFQUFFLENBQUM7SUFDVixDQUFDO0lBQ0Q7Ozs7Ozs7T0FPRztJQUNnQixZQUFZLENBQUMsS0FBUSxFQUFFLEtBQWM7UUFDdEQsNkVBQTZFO1FBQzdFLE1BQU0sV0FBVyxHQUF3QixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNsRSxJQUFJLFFBQVEsQ0FBQztRQUNiLElBQUksQ0FBQztZQUNILFFBQVEsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDOUIsNkRBQTZEO1FBQy9ELENBQUM7UUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO1lBQ3BCLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDbkIsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRO1lBQ1gsTUFBTSxJQUFJLGtCQUFrQixDQUMxQiwrQkFBK0IsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FDeEQsQ0FBQztRQUNKLFdBQVcsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDO1FBQ3pDLE9BQU8sV0FBVyxDQUFDO0lBQ3JCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNNLFdBQVcsQ0FBQyxHQUFXO1FBQzlCLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEMsTUFBTSxTQUFTLEdBQUcsZUFBZSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsU0FBUztZQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUN4RSxNQUFNLEtBQUssR0FBTSxLQUFLLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRSxTQUFTLENBQWlCLENBQUM7UUFDekUsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ00sU0FBUyxDQUFDLEtBQVEsRUFBRSxLQUFjO1FBQ3pDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGdldE1ldGFkYXRhLFxuICBKU09OU2VyaWFsaXplcixcbiAgTW9kZWwsXG4gIE1vZGVsS2V5cyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgU2VyaWFsaXphdGlvbkVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENsaWVudC1zaWRlIEpTT04gc2VyaWFsaXplciBmb3IgRGVjYWYgbW9kZWxzIHRhcmdldGluZyBIeXBlcmxlZGdlciBGYWJyaWNcbiAqIEBzdW1tYXJ5IEV4dGVuZHMgdGhlIGJhc2UgSlNPTlNlcmlhbGl6ZXIgdG8gZW1iZWQgbW9kZWwgbWV0YWRhdGEgKGFuY2hvcikgcmVxdWlyZWQgdG8gcmVjb25zdHJ1Y3QgaW5zdGFuY2VzIG9uIHRoZSBjbGllbnQsIGFuZCB0byBzYWZlbHkgc2VyaWFsaXplL2Rlc2VyaWFsaXplIEZhYnJpYy1ib3VuZCBtb2RlbHMuXG4gKiBAdGVtcGxhdGUgTSBleHRlbmRzIE1vZGVsIC0gVGhlIERlY2FmIG1vZGVsIHR5cGUgaGFuZGxlZCBieSB0aGlzIHNlcmlhbGl6ZXJcbiAqIEBwYXJhbSB7dm9pZH0gW2NvbnN0cnVjdG9yXSBObyBwdWJsaWMgY29uc3RydWN0b3IgYXJndW1lbnRzOyBwcm92aWRlZCBmb3IgZG9jdW1lbnRhdGlvbiBjb21wbGV0ZW5lc3NcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKiBAY2xhc3MgQ2xpZW50U2VyaWFsaXplclxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNlcmlhbGl6ZXIgPSBuZXcgQ2xpZW50U2VyaWFsaXplcjxVc2VyPigpO1xuICogY29uc3QganNvbiA9IHNlcmlhbGl6ZXIuc2VyaWFsaXplKG5ldyBVc2VyKHsgaWQ6IFwiMVwiLCBuYW1lOiBcIkFsaWNlXCIgfSkpO1xuICogY29uc3QgdXNlciA9IHNlcmlhbGl6ZXIuZGVzZXJpYWxpemUoanNvbik7XG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEFwcFxuICogICBwYXJ0aWNpcGFudCBTZXJpYWxpemVyIGFzIENsaWVudFNlcmlhbGl6ZXJcbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgQXBwLT4+U2VyaWFsaXplcjogc2VyaWFsaXplKG1vZGVsKVxuICogICBTZXJpYWxpemVyLT4+U2VyaWFsaXplcjogcHJlU2VyaWFsaXplKG1vZGVsKVxuICogICBTZXJpYWxpemVyLS0+PkFwcDogSlNPTiBzdHJpbmdcbiAqICAgQXBwLT4+U2VyaWFsaXplcjogZGVzZXJpYWxpemUoanNvbilcbiAqICAgU2VyaWFsaXplci0+PlNlcmlhbGl6ZXI6IEpTT04ucGFyc2UoanNvbilcbiAqICAgU2VyaWFsaXplci0+Pk1vZGVsOiBNb2RlbC5idWlsZChwYXJzZWQsIGFuY2hvcilcbiAqICAgTW9kZWwtLT4+QXBwOiBpbnN0YW5jZVxuICovXG5leHBvcnQgY2xhc3MgQ2xpZW50U2VyaWFsaXplcjxNIGV4dGVuZHMgTW9kZWw+IGV4dGVuZHMgSlNPTlNlcmlhbGl6ZXI8TT4ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICB9XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJlcGFyZSBhIG1vZGVsIGZvciBKU09OIHNlcmlhbGl6YXRpb24gZW1iZWRkaW5nIGNsYXNzIGFuY2hvclxuICAgKiBAc3VtbWFyeSBDbG9uZXMgdGhlIG1vZGVsIGFuZCBpbmplY3RzIHRoZSBjbGFzcyBtZXRhZGF0YSBhbmNob3Igc28gaXQgY2FuIGJlIHJlY29uc3RydWN0ZWQgZHVyaW5nIGRlc2VyaWFsaXphdGlvbi4gRmFsbHMgYmFjayB0byBwcm92aWRlZCB0YWJsZSBuYW1lIGlmIG1ldGFkYXRhIGlzIG5vdCBhdmFpbGFibGUuXG4gICAqIEB0ZW1wbGF0ZSBNIC0gTW9kZWwgdHlwZSBoYW5kbGVkIGJ5IHRoaXMgc2VyaWFsaXplclxuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIHNlcmlhbGl6ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3RhYmxlXSAtIE9wdGlvbmFsIHRhYmxlIG5hbWUgdG8gdXNlIHdoZW4gbWV0YWRhdGEgY2Fubm90IGJlIGRlcml2ZWRcbiAgICogQHJldHVybiB7UmVjb3JkPHN0cmluZywgYW55Pn0gQSBwbGFpbiBvYmplY3QgcmVhZHkgdG8gYmUgSlNPTi5zdHJpbmdpZnknZFxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIHByZVNlcmlhbGl6ZShtb2RlbDogTSwgdGFibGU/OiBzdHJpbmcpIHtcbiAgICAvLyBUT0RPOiBuZXN0ZWQgcHJlc2VyaWFsaXphdGlvbiAoc28gaW5jcmVhc2UgcGVyZm9ybWFuY2Ugd2hlbiBkZXNlcmlhbGl6aW5nKVxuICAgIGNvbnN0IHRvU2VyaWFsaXplOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gT2JqZWN0LmFzc2lnbih7fSwgbW9kZWwpO1xuICAgIGxldCBtZXRhZGF0YTtcbiAgICB0cnkge1xuICAgICAgbWV0YWRhdGEgPSBnZXRNZXRhZGF0YShtb2RlbCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgbWV0YWRhdGEgPSB0YWJsZTtcbiAgICB9XG4gICAgaWYgKCFtZXRhZGF0YSlcbiAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgZmluZCBtZXRhZGF0YSBmb3IgJHttb2RlbC5jb25zdHJ1Y3Rvci5uYW1lfWBcbiAgICAgICk7XG4gICAgdG9TZXJpYWxpemVbTW9kZWxLZXlzLkFOQ0hPUl0gPSBtZXRhZGF0YTtcbiAgICByZXR1cm4gdG9TZXJpYWxpemU7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlYnVpbGRzIGEgbW9kZWwgZnJvbSBpdHMgSlNPTiBzZXJpYWxpemF0aW9uXG4gICAqIEBzdW1tYXJ5IFBhcnNlcyB0aGUgSlNPTiBzdHJpbmcsIHJldHJpZXZlcyB0aGUgZW1iZWRkZWQgbW9kZWwgYW5jaG9yLCBhbmQgdXNlcyBNb2RlbC5idWlsZCB0byByZWNvbnN0cnVjdCB0aGUgb3JpZ2luYWwgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFRoZSBKU09OIHN0cmluZyBwcmV2aW91c2x5IHByb2R1Y2VkIGJ5IHNlcmlhbGl6ZVxuICAgKiBAcmV0dXJuIHtNfSBUaGUgcmVjb25zdHJ1Y3RlZCBtb2RlbCBpbnN0YW5jZVxuICAgKi9cbiAgb3ZlcnJpZGUgZGVzZXJpYWxpemUoc3RyOiBzdHJpbmcpOiBNIHtcbiAgICBjb25zdCBkZXNlcmlhbGl6YXRpb24gPSBKU09OLnBhcnNlKHN0cik7XG4gICAgY29uc3QgY2xhc3NOYW1lID0gZGVzZXJpYWxpemF0aW9uW01vZGVsS2V5cy5BTkNIT1JdO1xuICAgIGlmICghY2xhc3NOYW1lKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IGZpbmQgY2xhc3MgcmVmZXJlbmNlIGluIHNlcmlhbGl6ZWQgbW9kZWxcIik7XG4gICAgY29uc3QgbW9kZWw6IE0gPSBNb2RlbC5idWlsZChkZXNlcmlhbGl6YXRpb24sIGNsYXNzTmFtZSkgYXMgdW5rbm93biBhcyBNO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2VyaWFsaXplcyBhIG1vZGVsIHRvIGEgSlNPTiBzdHJpbmdcbiAgICogQHN1bW1hcnkgUHJlcGFyZXMgdGhlIG1vZGVsIHZpYSBwcmVTZXJpYWxpemUsIGVtYmVkZGluZyBtZXRhZGF0YSBuZWVkZWQgZm9yIHJlY29uc3RydWN0aW9uLCBhbmQgcmV0dXJucyBhIEpTT04gc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdG8gc2VyaWFsaXplXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbdGFibGVdIC0gT3B0aW9uYWwgdGFibGUgbmFtZSB0byBpbmNsdWRlIGFzIGFuY2hvciB3aGVuIG1ldGFkYXRhIGlzIHVuYXZhaWxhYmxlXG4gICAqIEByZXR1cm4ge3N0cmluZ30gQSBKU09OIHN0cmluZyBjb250YWluaW5nIHRoZSBzZXJpYWxpemVkIG1vZGVsIHdpdGggYW5jaG9yIG1ldGFkYXRhXG4gICAqL1xuICBvdmVycmlkZSBzZXJpYWxpemUobW9kZWw6IE0sIHRhYmxlPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy5wcmVTZXJpYWxpemUobW9kZWwsIHRhYmxlKSk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -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,50 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
2
|
+
import { JSONSerializer } from "@decaf-ts/decorator-validation";
|
|
3
|
+
/**
|
|
4
|
+
* @description Deterministic JSON serializer for Fabric models
|
|
5
|
+
* @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.
|
|
6
|
+
* @template M - The Decaf Model subtype serialized by this instance
|
|
7
|
+
* @param {void} [constructor] No public constructor arguments
|
|
8
|
+
* @class DeterministicSerializer
|
|
9
|
+
* @example
|
|
10
|
+
* const serializer = new DeterministicSerializer<MyModel>();
|
|
11
|
+
* const json = serializer.serialize(model);
|
|
12
|
+
* const rebuilt = serializer.deserialize(json);
|
|
13
|
+
* @mermaid
|
|
14
|
+
* sequenceDiagram
|
|
15
|
+
* participant Caller
|
|
16
|
+
* participant DS as DeterministicSerializer
|
|
17
|
+
* Caller->>DS: serialize(model)
|
|
18
|
+
* DS->>DS: preSerialize(model)
|
|
19
|
+
* DS->>DS: sort-keys-recursive
|
|
20
|
+
* DS->>DS: json-stringify-deterministic
|
|
21
|
+
* DS-->>Caller: string
|
|
22
|
+
* Caller->>DS: deserialize(string)
|
|
23
|
+
* DS-->>Caller: model
|
|
24
|
+
*/
|
|
25
|
+
export class DeterministicSerializer extends JSONSerializer {
|
|
26
|
+
constructor() {
|
|
27
|
+
super();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* @description Deserialize a JSON string into a model instance
|
|
31
|
+
* @summary Delegates to the base JSONSerializer implementation to rebuild the model
|
|
32
|
+
* @param {string} str - The JSON string to deserialize
|
|
33
|
+
* @return {M} The reconstructed model instance
|
|
34
|
+
*/
|
|
35
|
+
deserialize(str) {
|
|
36
|
+
return super.deserialize(str);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @description Serialize a model into a deterministic JSON string
|
|
40
|
+
* @summary Prepares the model with preSerialize, sorts keys recursively, and stringifies deterministically for stable ordering
|
|
41
|
+
* @param {M} model - The model instance to serialize
|
|
42
|
+
* @return {string} Deterministic JSON representation of the model
|
|
43
|
+
*/
|
|
44
|
+
serialize(model) {
|
|
45
|
+
const stringify = require("json-stringify-deterministic");
|
|
46
|
+
const sortKeysRecursive = require("sort-keys-recursive");
|
|
47
|
+
return stringify(sortKeysRecursive(this.preSerialize(model)));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGV0ZXJtaW5pc3RpY1NlcmlhbGl6ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2hhcmVkL0RldGVybWluaXN0aWNTZXJpYWxpemVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBEQUEwRDtBQUMxRCxPQUFPLEVBQUUsY0FBYyxFQUFTLE1BQU0sZ0NBQWdDLENBQUM7QUFFdkU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQU0sT0FBTyx1QkFFWCxTQUFRLGNBQWlCO0lBQ3pCO1FBQ0UsS0FBSyxFQUFFLENBQUM7SUFDVixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTSxXQUFXLENBQUMsR0FBVztRQUM5QixPQUFPLEtBQUssQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ00sU0FBUyxDQUFDLEtBQVE7UUFDekIsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFDMUQsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUN6RCxPQUFPLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoRSxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzICovXG5pbXBvcnQgeyBKU09OU2VyaWFsaXplciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERldGVybWluaXN0aWMgSlNPTiBzZXJpYWxpemVyIGZvciBGYWJyaWMgbW9kZWxzXG4gKiBAc3VtbWFyeSBFbnN1cmVzIHN0YWJsZSwgZGV0ZXJtaW5pc3RpYyBKU09OIG91dHB1dCBieSBzb3J0aW5nIG9iamVjdCBrZXlzIHJlY3Vyc2l2ZWx5IGJlZm9yZSBzdHJpbmdpZmljYXRpb24sIHdoaWNoIGlzIGltcG9ydGFudCBmb3IgRmFicmljIGVuZG9yc2VtZW50IGFuZCBoYXNoaW5nLiBFeHRlbmRzIEpTT05TZXJpYWxpemVyIHRvIHBsdWcgaW50byBleGlzdGluZyBEZWNhZiBtb2RlbCBzZXJpYWxpemF0aW9uIGZsb3cuXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBEZWNhZiBNb2RlbCBzdWJ0eXBlIHNlcmlhbGl6ZWQgYnkgdGhpcyBpbnN0YW5jZVxuICogQHBhcmFtIHt2b2lkfSBbY29uc3RydWN0b3JdIE5vIHB1YmxpYyBjb25zdHJ1Y3RvciBhcmd1bWVudHNcbiAqIEBjbGFzcyBEZXRlcm1pbmlzdGljU2VyaWFsaXplclxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNlcmlhbGl6ZXIgPSBuZXcgRGV0ZXJtaW5pc3RpY1NlcmlhbGl6ZXI8TXlNb2RlbD4oKTtcbiAqIGNvbnN0IGpzb24gPSBzZXJpYWxpemVyLnNlcmlhbGl6ZShtb2RlbCk7XG4gKiBjb25zdCByZWJ1aWx0ID0gc2VyaWFsaXplci5kZXNlcmlhbGl6ZShqc29uKTtcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IERTIGFzIERldGVybWluaXN0aWNTZXJpYWxpemVyXG4gKiAgIENhbGxlci0+PkRTOiBzZXJpYWxpemUobW9kZWwpXG4gKiAgIERTLT4+RFM6IHByZVNlcmlhbGl6ZShtb2RlbClcbiAqICAgRFMtPj5EUzogc29ydC1rZXlzLXJlY3Vyc2l2ZVxuICogICBEUy0+PkRTOiBqc29uLXN0cmluZ2lmeS1kZXRlcm1pbmlzdGljXG4gKiAgIERTLS0+PkNhbGxlcjogc3RyaW5nXG4gKiAgIENhbGxlci0+PkRTOiBkZXNlcmlhbGl6ZShzdHJpbmcpXG4gKiAgIERTLS0+PkNhbGxlcjogbW9kZWxcbiAqL1xuZXhwb3J0IGNsYXNzIERldGVybWluaXN0aWNTZXJpYWxpemVyPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4+IGV4dGVuZHMgSlNPTlNlcmlhbGl6ZXI8TT4ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEZXNlcmlhbGl6ZSBhIEpTT04gc3RyaW5nIGludG8gYSBtb2RlbCBpbnN0YW5jZVxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdG8gdGhlIGJhc2UgSlNPTlNlcmlhbGl6ZXIgaW1wbGVtZW50YXRpb24gdG8gcmVidWlsZCB0aGUgbW9kZWxcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFRoZSBKU09OIHN0cmluZyB0byBkZXNlcmlhbGl6ZVxuICAgKiBAcmV0dXJuIHtNfSBUaGUgcmVjb25zdHJ1Y3RlZCBtb2RlbCBpbnN0YW5jZVxuICAgKi9cbiAgb3ZlcnJpZGUgZGVzZXJpYWxpemUoc3RyOiBzdHJpbmcpOiBNIHtcbiAgICByZXR1cm4gc3VwZXIuZGVzZXJpYWxpemUoc3RyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2VyaWFsaXplIGEgbW9kZWwgaW50byBhIGRldGVybWluaXN0aWMgSlNPTiBzdHJpbmdcbiAgICogQHN1bW1hcnkgUHJlcGFyZXMgdGhlIG1vZGVsIHdpdGggcHJlU2VyaWFsaXplLCBzb3J0cyBrZXlzIHJlY3Vyc2l2ZWx5LCBhbmQgc3RyaW5naWZpZXMgZGV0ZXJtaW5pc3RpY2FsbHkgZm9yIHN0YWJsZSBvcmRlcmluZ1xuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIHNlcmlhbGl6ZVxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IERldGVybWluaXN0aWMgSlNPTiByZXByZXNlbnRhdGlvbiBvZiB0aGUgbW9kZWxcbiAgICovXG4gIG92ZXJyaWRlIHNlcmlhbGl6ZShtb2RlbDogTSk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RyaW5naWZ5ID0gcmVxdWlyZShcImpzb24tc3RyaW5naWZ5LWRldGVybWluaXN0aWNcIik7XG4gICAgY29uc3Qgc29ydEtleXNSZWN1cnNpdmUgPSByZXF1aXJlKFwic29ydC1rZXlzLXJlY3Vyc2l2ZVwiKTtcbiAgICByZXR1cm4gc3RyaW5naWZ5KHNvcnRLZXlzUmVjdXJzaXZlKHRoaXMucHJlU2VyaWFsaXplKG1vZGVsKSkpO1xuICB9XG59XG4iXX0=
|
|
@@ -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,42 @@
|
|
|
1
|
+
import { JSONSerializer } from "@decaf-ts/decorator-validation";
|
|
2
|
+
export class SimpleDeterministicSerializer extends JSONSerializer {
|
|
3
|
+
constructor() {
|
|
4
|
+
super();
|
|
5
|
+
}
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
7
|
+
deserialize(str, tableName) {
|
|
8
|
+
const deserialization = JSON.parse(str);
|
|
9
|
+
// const className = tableName;
|
|
10
|
+
// if (!className)
|
|
11
|
+
// throw new Error("Could not find class reference in serialized model");
|
|
12
|
+
// // this will return undefined values
|
|
13
|
+
// const model: M = Model.build(deserialization, className) as unknown as M;
|
|
14
|
+
// // Populate Model
|
|
15
|
+
// const processedDesealization = Object.keys(model).reduce(
|
|
16
|
+
// (accum: M, key) => {
|
|
17
|
+
// (accum as Record<string, any>)[key] =
|
|
18
|
+
// deserialization[Repository.column(accum, key)];
|
|
19
|
+
// return accum;
|
|
20
|
+
// },
|
|
21
|
+
// model
|
|
22
|
+
// );
|
|
23
|
+
// const result = Model.build(
|
|
24
|
+
// processedDesealization,
|
|
25
|
+
// className
|
|
26
|
+
// ) as unknown as M;
|
|
27
|
+
// return result;
|
|
28
|
+
return deserialization;
|
|
29
|
+
}
|
|
30
|
+
serialize(model) {
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
32
|
+
const stringify = require("json-stringify-deterministic");
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
34
|
+
const sortKeysRecursive = require("sort-keys-recursive");
|
|
35
|
+
return stringify(sortKeysRecursive(this.preSerialize(model)));
|
|
36
|
+
}
|
|
37
|
+
preSerialize(model) {
|
|
38
|
+
const toSerialize = Object.assign({}, model);
|
|
39
|
+
return toSerialize;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2ltcGxlRGV0ZXJtaW5pc3RpY1NlcmlhbGl6ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2hhcmVkL1NpbXBsZURldGVybWluaXN0aWNTZXJpYWxpemVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQVMsTUFBTSxnQ0FBZ0MsQ0FBQztBQUV2RSxNQUFNLE9BQU8sNkJBRVgsU0FBUSxjQUFpQjtJQUN6QjtRQUNFLEtBQUssRUFBRSxDQUFDO0lBQ1YsQ0FBQztJQUVELDZEQUE2RDtJQUNwRCxXQUFXLENBQUMsR0FBVyxFQUFFLFNBQWtCO1FBQ2xELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEMsK0JBQStCO1FBQy9CLGtCQUFrQjtRQUNsQiwyRUFBMkU7UUFFM0UsdUNBQXVDO1FBQ3ZDLDRFQUE0RTtRQUU1RSxvQkFBb0I7UUFDcEIsNERBQTREO1FBQzVELHlCQUF5QjtRQUN6Qiw0Q0FBNEM7UUFDNUMsd0RBQXdEO1FBQ3hELG9CQUFvQjtRQUNwQixPQUFPO1FBQ1AsVUFBVTtRQUNWLEtBQUs7UUFFTCw4QkFBOEI7UUFDOUIsNEJBQTRCO1FBQzVCLGNBQWM7UUFDZCxxQkFBcUI7UUFFckIsaUJBQWlCO1FBQ2pCLE9BQU8sZUFBZSxDQUFDO0lBQ3pCLENBQUM7SUFFUSxTQUFTLENBQUMsS0FBUTtRQUN6QixpRUFBaUU7UUFDakUsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFDMUQsaUVBQWlFO1FBQ2pFLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDekQsT0FBTyxTQUFTLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVRLFlBQVksQ0FBQyxLQUFRO1FBQzVCLE1BQU0sV0FBVyxHQUF3QixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNsRSxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBKU09OU2VyaWFsaXplciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbmV4cG9ydCBjbGFzcyBTaW1wbGVEZXRlcm1pbmlzdGljU2VyaWFsaXplcjxcbiAgTSBleHRlbmRzIE1vZGVsLFxuPiBleHRlbmRzIEpTT05TZXJpYWxpemVyPE0+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgb3ZlcnJpZGUgZGVzZXJpYWxpemUoc3RyOiBzdHJpbmcsIHRhYmxlTmFtZT86IHN0cmluZyk6IE0ge1xuICAgIGNvbnN0IGRlc2VyaWFsaXphdGlvbiA9IEpTT04ucGFyc2Uoc3RyKTtcbiAgICAvLyBjb25zdCBjbGFzc05hbWUgPSB0YWJsZU5hbWU7XG4gICAgLy8gaWYgKCFjbGFzc05hbWUpXG4gICAgLy8gICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZmluZCBjbGFzcyByZWZlcmVuY2UgaW4gc2VyaWFsaXplZCBtb2RlbFwiKTtcblxuICAgIC8vIC8vIHRoaXMgd2lsbCByZXR1cm4gdW5kZWZpbmVkIHZhbHVlc1xuICAgIC8vIGNvbnN0IG1vZGVsOiBNID0gTW9kZWwuYnVpbGQoZGVzZXJpYWxpemF0aW9uLCBjbGFzc05hbWUpIGFzIHVua25vd24gYXMgTTtcblxuICAgIC8vIC8vIFBvcHVsYXRlIE1vZGVsXG4gICAgLy8gY29uc3QgcHJvY2Vzc2VkRGVzZWFsaXphdGlvbiA9IE9iamVjdC5rZXlzKG1vZGVsKS5yZWR1Y2UoXG4gICAgLy8gICAoYWNjdW06IE0sIGtleSkgPT4ge1xuICAgIC8vICAgICAoYWNjdW0gYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XSA9XG4gICAgLy8gICAgICAgZGVzZXJpYWxpemF0aW9uW1JlcG9zaXRvcnkuY29sdW1uKGFjY3VtLCBrZXkpXTtcbiAgICAvLyAgICAgcmV0dXJuIGFjY3VtO1xuICAgIC8vICAgfSxcbiAgICAvLyAgIG1vZGVsXG4gICAgLy8gKTtcblxuICAgIC8vIGNvbnN0IHJlc3VsdCA9IE1vZGVsLmJ1aWxkKFxuICAgIC8vICAgcHJvY2Vzc2VkRGVzZWFsaXphdGlvbixcbiAgICAvLyAgIGNsYXNzTmFtZVxuICAgIC8vICkgYXMgdW5rbm93biBhcyBNO1xuXG4gICAgLy8gcmV0dXJuIHJlc3VsdDtcbiAgICByZXR1cm4gZGVzZXJpYWxpemF0aW9uO1xuICB9XG5cbiAgb3ZlcnJpZGUgc2VyaWFsaXplKG1vZGVsOiBNKTogc3RyaW5nIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgIGNvbnN0IHN0cmluZ2lmeSA9IHJlcXVpcmUoXCJqc29uLXN0cmluZ2lmeS1kZXRlcm1pbmlzdGljXCIpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3Qgc29ydEtleXNSZWN1cnNpdmUgPSByZXF1aXJlKFwic29ydC1rZXlzLXJlY3Vyc2l2ZVwiKTtcbiAgICByZXR1cm4gc3RyaW5naWZ5KHNvcnRLZXlzUmVjdXJzaXZlKHRoaXMucHJlU2VyaWFsaXplKG1vZGVsKSkpO1xuICB9XG5cbiAgb3ZlcnJpZGUgcHJlU2VyaWFsaXplKG1vZGVsOiBNKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgY29uc3QgdG9TZXJpYWxpemU6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBPYmplY3QuYXNzaWduKHt9LCBtb2RlbCk7XG4gICAgcmV0dXJuIHRvU2VyaWFsaXplO1xuICB9XG59XG4iXX0=
|
|
@@ -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";
|
|
@@ -0,0 +1,42 @@
|
|
|
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 var FabricModelKeys;
|
|
9
|
+
(function (FabricModelKeys) {
|
|
10
|
+
/** Private data marker used to tag properties or models for Fabric private collections */
|
|
11
|
+
FabricModelKeys["PRIVATE"] = "private";
|
|
12
|
+
/** Namespace prefix used for Fabric-specific metadata keys */
|
|
13
|
+
FabricModelKeys["FABRIC"] = "fabric.";
|
|
14
|
+
FabricModelKeys["OWNEDBY"] = "owned-by";
|
|
15
|
+
})(FabricModelKeys || (FabricModelKeys = {}));
|
|
16
|
+
/**
|
|
17
|
+
* @description Supported identity types for Fabric credentials
|
|
18
|
+
* @summary Enumeration of identity formats recognized by this library
|
|
19
|
+
* @enum {string}
|
|
20
|
+
* @readonly
|
|
21
|
+
* @memberOf module:for-fabric.shared
|
|
22
|
+
*/
|
|
23
|
+
export var IdentityType;
|
|
24
|
+
(function (IdentityType) {
|
|
25
|
+
/** Standard X.509 identity format used by Hyperledger Fabric */
|
|
26
|
+
IdentityType["X509"] = "X.509";
|
|
27
|
+
})(IdentityType || (IdentityType = {}));
|
|
28
|
+
/**
|
|
29
|
+
* @description String identifier for the Fabric adapter flavour
|
|
30
|
+
* @summary Used to tag adapters/repositories that operate against Hyperledger Fabric
|
|
31
|
+
* @const FabricFlavour
|
|
32
|
+
* @memberOf module:for-fabric.shared
|
|
33
|
+
*/
|
|
34
|
+
export const FabricFlavour = "hlf-fabric";
|
|
35
|
+
/**
|
|
36
|
+
* @description Package version placeholder replaced at build time
|
|
37
|
+
* @summary Constant holding the current package version injected by the build pipeline
|
|
38
|
+
* @const VERSION
|
|
39
|
+
* @memberOf module:for-fabric.shared
|
|
40
|
+
*/
|
|
41
|
+
export const VERSION = "0.0.2";
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NoYXJlZC9jb25zdGFudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFOLElBQVksZUFNWDtBQU5ELFdBQVksZUFBZTtJQUN6QiwwRkFBMEY7SUFDMUYsc0NBQW1CLENBQUE7SUFDbkIsOERBQThEO0lBQzlELHFDQUFrQixDQUFBO0lBQ2xCLHVDQUFvQixDQUFBO0FBQ3RCLENBQUMsRUFOVyxlQUFlLEtBQWYsZUFBZSxRQU0xQjtBQUNEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBTixJQUFZLFlBR1g7QUFIRCxXQUFZLFlBQVk7SUFDdEIsZ0VBQWdFO0lBQ2hFLDhCQUFjLENBQUE7QUFDaEIsQ0FBQyxFQUhXLFlBQVksS0FBWixZQUFZLFFBR3ZCO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsWUFBWSxDQUFDO0FBRTFDOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGRlc2NyaXB0aW9uIEtleXMgdXNlZCB0byBtYXJrIEZhYnJpYy1zcGVjaWZpYyBtb2RlbCBtZXRhZGF0YVxuICogQHN1bW1hcnkgRW51bWVyYXRpb24gb2Ygc3BlY2lhbCBrZXlzIHVzZWQgYnkgdGhlIHNlcmlhbGl6YXRpb24gbGF5ZXIgdG8gcGVyc2lzdCBGYWJyaWMtcmVsYXRlZCBmbGFncyBvbiBtb2RlbHNcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Zm9yLWZhYnJpYy5zaGFyZWRcbiAqL1xuZXhwb3J0IGVudW0gRmFicmljTW9kZWxLZXlzIHtcbiAgLyoqIFByaXZhdGUgZGF0YSBtYXJrZXIgdXNlZCB0byB0YWcgcHJvcGVydGllcyBvciBtb2RlbHMgZm9yIEZhYnJpYyBwcml2YXRlIGNvbGxlY3Rpb25zICovXG4gIFBSSVZBVEUgPSBcInByaXZhdGVcIixcbiAgLyoqIE5hbWVzcGFjZSBwcmVmaXggdXNlZCBmb3IgRmFicmljLXNwZWNpZmljIG1ldGFkYXRhIGtleXMgKi9cbiAgRkFCUklDID0gXCJmYWJyaWMuXCIsXG4gIE9XTkVEQlkgPSBcIm93bmVkLWJ5XCIsXG59XG4vKipcbiAqIEBkZXNjcmlwdGlvbiBTdXBwb3J0ZWQgaWRlbnRpdHkgdHlwZXMgZm9yIEZhYnJpYyBjcmVkZW50aWFsc1xuICogQHN1bW1hcnkgRW51bWVyYXRpb24gb2YgaWRlbnRpdHkgZm9ybWF0cyByZWNvZ25pemVkIGJ5IHRoaXMgbGlicmFyeVxuICogQGVudW0ge3N0cmluZ31cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTpmb3ItZmFicmljLnNoYXJlZFxuICovXG5leHBvcnQgZW51bSBJZGVudGl0eVR5cGUge1xuICAvKiogU3RhbmRhcmQgWC41MDkgaWRlbnRpdHkgZm9ybWF0IHVzZWQgYnkgSHlwZXJsZWRnZXIgRmFicmljICovXG4gIFg1MDkgPSBcIlguNTA5XCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFN0cmluZyBpZGVudGlmaWVyIGZvciB0aGUgRmFicmljIGFkYXB0ZXIgZmxhdm91clxuICogQHN1bW1hcnkgVXNlZCB0byB0YWcgYWRhcHRlcnMvcmVwb3NpdG9yaWVzIHRoYXQgb3BlcmF0ZSBhZ2FpbnN0IEh5cGVybGVkZ2VyIEZhYnJpY1xuICogQGNvbnN0IEZhYnJpY0ZsYXZvdXJcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Zm9yLWZhYnJpYy5zaGFyZWRcbiAqL1xuZXhwb3J0IGNvbnN0IEZhYnJpY0ZsYXZvdXIgPSBcImhsZi1mYWJyaWNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUGFja2FnZSB2ZXJzaW9uIHBsYWNlaG9sZGVyIHJlcGxhY2VkIGF0IGJ1aWxkIHRpbWVcbiAqIEBzdW1tYXJ5IENvbnN0YW50IGhvbGRpbmcgdGhlIGN1cnJlbnQgcGFja2FnZSB2ZXJzaW9uIGluamVjdGVkIGJ5IHRoZSBidWlsZCBwaXBlbGluZVxuICogQGNvbnN0IFZFUlNJT05cbiAqIEBtZW1iZXJPZiBtb2R1bGU6Zm9yLWZhYnJpYy5zaGFyZWRcbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG4iXX0=
|