@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,168 @@
|
|
|
1
|
+
import { FabricContractAdapter } from "../ContractAdapter";
|
|
2
|
+
import { Context, Contract, Context as Ctx } from "fabric-contract-api";
|
|
3
|
+
import { Constructor, Model } from "@decaf-ts/decorator-validation";
|
|
4
|
+
import { FabricContractRepository } from "../FabricContractRepository";
|
|
5
|
+
import { DeterministicSerializer } from "../../shared/DeterministicSerializer";
|
|
6
|
+
import { MangoQuery } from "@decaf-ts/for-couchdb";
|
|
7
|
+
import { Checkable, healthcheck } from "../../shared/interfaces/Checkable";
|
|
8
|
+
import { ContractLogger } from "../logging";
|
|
9
|
+
/**
|
|
10
|
+
* @description Base contract class for CRUD operations in Fabric chaincode
|
|
11
|
+
* @summary Provides standard create, read, update, and delete operations for models in Fabric chaincode
|
|
12
|
+
* @template M - Type extending Model
|
|
13
|
+
* @class FabricCrudContract
|
|
14
|
+
* @extends {Contract}
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // Define a model
|
|
18
|
+
* @table('assets')
|
|
19
|
+
* class Asset extends Model {
|
|
20
|
+
* @id()
|
|
21
|
+
* id: string;
|
|
22
|
+
*
|
|
23
|
+
* @property()
|
|
24
|
+
* data: string;
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* // Create a contract that extends FabricCrudContract
|
|
28
|
+
* export class AssetContract extends FabricCrudContract<Asset> {
|
|
29
|
+
* constructor() {
|
|
30
|
+
* super('AssetContract', Asset);
|
|
31
|
+
* }
|
|
32
|
+
*
|
|
33
|
+
* // Add custom methods as needed
|
|
34
|
+
* async getAssetHistory(ctx: Context, id: string): Promise<any[]> {
|
|
35
|
+
* // Custom implementation
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
* @mermaid
|
|
40
|
+
* sequenceDiagram
|
|
41
|
+
* participant Client
|
|
42
|
+
* participant Contract
|
|
43
|
+
* participant Repository
|
|
44
|
+
* participant Adapter
|
|
45
|
+
* participant StateDB
|
|
46
|
+
*
|
|
47
|
+
* Client->>Contract: create(ctx, model)
|
|
48
|
+
* Contract->>Repository: repository(ctx)
|
|
49
|
+
* Contract->>Repository: create(model, ctx)
|
|
50
|
+
* Repository->>Adapter: create(tableName, id, record, transient, ctx)
|
|
51
|
+
* Adapter->>StateDB: putState(id, serializedData)
|
|
52
|
+
* StateDB-->>Adapter: Success
|
|
53
|
+
* Adapter-->>Repository: record
|
|
54
|
+
* Repository-->>Contract: model
|
|
55
|
+
* Contract-->>Client: model
|
|
56
|
+
*/
|
|
57
|
+
export declare abstract class FabricCrudContract<M extends Model> extends Contract implements Checkable {
|
|
58
|
+
protected readonly clazz: Constructor<M>;
|
|
59
|
+
/**
|
|
60
|
+
* @description Shared adapter instance for all contract instances
|
|
61
|
+
*/
|
|
62
|
+
protected static adapter: FabricContractAdapter;
|
|
63
|
+
protected readonly repo: FabricContractRepository<M>;
|
|
64
|
+
protected static readonly serializer: DeterministicSerializer<Model<false>>;
|
|
65
|
+
protected initialized: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* @description Creates a new FabricCrudContract instance
|
|
68
|
+
* @summary Initializes a contract with a name and model class
|
|
69
|
+
* @param {string} name - The name of the contract
|
|
70
|
+
* @param {Constructor<M>} clazz - The model constructor
|
|
71
|
+
*/
|
|
72
|
+
protected constructor(name: string, clazz: Constructor<M>);
|
|
73
|
+
protected getAdapter(clazz: Constructor<M>): FabricContractAdapter;
|
|
74
|
+
/**
|
|
75
|
+
* @description Creates a logger for a specific chaincode context
|
|
76
|
+
* @summary Returns a ContractLogger instance configured for the current context
|
|
77
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
78
|
+
* @return {ContractLogger} The logger instance
|
|
79
|
+
*/
|
|
80
|
+
logFor(ctx: Context): ContractLogger;
|
|
81
|
+
/**
|
|
82
|
+
* @description Creates a single model in the state database
|
|
83
|
+
* @summary Delegates to the repository's create method
|
|
84
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
85
|
+
* @param {M} model - The model to create
|
|
86
|
+
* @param {...any[]} args - Additional arguments
|
|
87
|
+
* @return {Promise<M>} Promise resolving to the created model
|
|
88
|
+
*/
|
|
89
|
+
create(ctx: Ctx, model: string | M, ...args: any[]): Promise<string | M>;
|
|
90
|
+
/**
|
|
91
|
+
* @description Reads a single model from the state database
|
|
92
|
+
* @summary Delegates to the repository's read method
|
|
93
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
94
|
+
* @param {string | number} key - The key of the model to read
|
|
95
|
+
* @param {...any[]} args - Additional arguments
|
|
96
|
+
* @return {Promise<M>} Promise resolving to the retrieved model
|
|
97
|
+
*/
|
|
98
|
+
read(ctx: Ctx, key: string | number, ...args: any[]): Promise<M | string>;
|
|
99
|
+
protected getTransientData(ctx: Ctx): any;
|
|
100
|
+
/**
|
|
101
|
+
* @description Updates a single model in the state database
|
|
102
|
+
* @summary Delegates to the repository's update method
|
|
103
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
104
|
+
* @param {M} model - The model to update
|
|
105
|
+
* @param {...any[]} args - Additional arguments
|
|
106
|
+
* @return {Promise<M>} Promise resolving to the updated model
|
|
107
|
+
*/
|
|
108
|
+
update(ctx: Ctx, model: string | M, ...args: any[]): Promise<string | M>;
|
|
109
|
+
/**
|
|
110
|
+
* @description Deletes a single model from the state database
|
|
111
|
+
* @summary Delegates to the repository's delete method
|
|
112
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
113
|
+
* @param {string | number} key - The key of the model to delete
|
|
114
|
+
* @param {...any[]} args - Additional arguments
|
|
115
|
+
* @return {Promise<M>} Promise resolving to the deleted model
|
|
116
|
+
*/
|
|
117
|
+
delete(ctx: Ctx, key: string | number, ...args: any[]): Promise<M | string>;
|
|
118
|
+
/**
|
|
119
|
+
* @description Deletes multiple models from the state database
|
|
120
|
+
* @summary Delegates to the repository's deleteAll method
|
|
121
|
+
* @param {string[] | number[]} keys - The keys of the models to delete
|
|
122
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
123
|
+
* @param {...any[]} args - Additional arguments
|
|
124
|
+
* @return {Promise<M[]>} Promise resolving to the deleted models
|
|
125
|
+
*/
|
|
126
|
+
deleteAll(ctx: Ctx, keys: string | string[] | number[], ...args: any[]): Promise<M[] | string>;
|
|
127
|
+
/**
|
|
128
|
+
* @description Reads multiple models from the state database
|
|
129
|
+
* @summary Delegates to the repository's readAll method
|
|
130
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
131
|
+
* @param {string[] | number[]} keys - The keys of the models to read
|
|
132
|
+
* @param {...any[]} args - Additional arguments
|
|
133
|
+
* @return {Promise<M[]>} Promise resolving to the retrieved models
|
|
134
|
+
*/
|
|
135
|
+
readAll(ctx: Ctx, keys: string | string[] | number[], ...args: any[]): Promise<M[] | string>;
|
|
136
|
+
/**
|
|
137
|
+
* @description Updates multiple models in the state database
|
|
138
|
+
* @summary Delegates to the repository's updateAll method
|
|
139
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
140
|
+
* @param {M[]} models - The models to update
|
|
141
|
+
* @param {...any[]} args - Additional arguments
|
|
142
|
+
* @return {Promise<M[]>} Promise resolving to the updated models
|
|
143
|
+
*/
|
|
144
|
+
updateAll(ctx: Ctx, models: string | M[], ...args: any[]): Promise<string | M[]>;
|
|
145
|
+
/**
|
|
146
|
+
* @description Executes a raw query against the state database
|
|
147
|
+
* @summary Delegates to the repository's raw method
|
|
148
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
149
|
+
* @param {any} rawInput - The query to execute
|
|
150
|
+
* @param {boolean} docsOnly - Whether to return only documents
|
|
151
|
+
* @param {...any[]} args - Additional arguments
|
|
152
|
+
* @return {Promise<any>} Promise resolving to the query results
|
|
153
|
+
*/
|
|
154
|
+
raw(ctx: Ctx, rawInput: MangoQuery | string, docsOnly: boolean, ...args: any[]): Promise<any | string>;
|
|
155
|
+
protected serialize(model: M): string;
|
|
156
|
+
protected deserialize<M extends Model>(str: string): M;
|
|
157
|
+
protected init(ctx: Ctx): Promise<void>;
|
|
158
|
+
healthcheck(ctx: Ctx): Promise<string | healthcheck>;
|
|
159
|
+
/**
|
|
160
|
+
* @description Creates multiple models in the state database
|
|
161
|
+
* @summary Delegates to the repository's createAll method
|
|
162
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
163
|
+
* @param {M[]} models - The models to create
|
|
164
|
+
* @param {...any[]} args - Additional arguments
|
|
165
|
+
* @return {Promise<M[]>} Promise resolving to the created models
|
|
166
|
+
*/
|
|
167
|
+
createAll(ctx: Ctx, models: string | M[], ...args: any[]): Promise<string | M[]>;
|
|
168
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { FabricContractAdapter } from "./../ContractAdapter.js";
|
|
2
|
+
import { Contract } from "fabric-contract-api";
|
|
3
|
+
import { Repository } from "@decaf-ts/core";
|
|
4
|
+
import { DeterministicSerializer } from "./../../shared/DeterministicSerializer.js";
|
|
5
|
+
import { Logging } from "@decaf-ts/logging";
|
|
6
|
+
import { isModelPrivate, modelToPrivate } from "./../private-data.js";
|
|
7
|
+
import { FabricContractPrivateDataAdapter } from "./../ContractPrivateDataAdapter.js";
|
|
8
|
+
/**
|
|
9
|
+
* @description Base contract class for CRUD operations in Fabric chaincode
|
|
10
|
+
* @summary Provides standard create, read, update, and delete operations for models in Fabric chaincode
|
|
11
|
+
* @template M - Type extending Model
|
|
12
|
+
* @class FabricCrudContract
|
|
13
|
+
* @extends {Contract}
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Define a model
|
|
17
|
+
* @table('assets')
|
|
18
|
+
* class Asset extends Model {
|
|
19
|
+
* @id()
|
|
20
|
+
* id: string;
|
|
21
|
+
*
|
|
22
|
+
* @property()
|
|
23
|
+
* data: string;
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* // Create a contract that extends FabricCrudContract
|
|
27
|
+
* export class AssetContract extends FabricCrudContract<Asset> {
|
|
28
|
+
* constructor() {
|
|
29
|
+
* super('AssetContract', Asset);
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* // Add custom methods as needed
|
|
33
|
+
* async getAssetHistory(ctx: Context, id: string): Promise<any[]> {
|
|
34
|
+
* // Custom implementation
|
|
35
|
+
* }
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
* @mermaid
|
|
39
|
+
* sequenceDiagram
|
|
40
|
+
* participant Client
|
|
41
|
+
* participant Contract
|
|
42
|
+
* participant Repository
|
|
43
|
+
* participant Adapter
|
|
44
|
+
* participant StateDB
|
|
45
|
+
*
|
|
46
|
+
* Client->>Contract: create(ctx, model)
|
|
47
|
+
* Contract->>Repository: repository(ctx)
|
|
48
|
+
* Contract->>Repository: create(model, ctx)
|
|
49
|
+
* Repository->>Adapter: create(tableName, id, record, transient, ctx)
|
|
50
|
+
* Adapter->>StateDB: putState(id, serializedData)
|
|
51
|
+
* StateDB-->>Adapter: Success
|
|
52
|
+
* Adapter-->>Repository: record
|
|
53
|
+
* Repository-->>Contract: model
|
|
54
|
+
* Contract-->>Client: model
|
|
55
|
+
*/
|
|
56
|
+
export class FabricCrudContract extends Contract {
|
|
57
|
+
static { this.serializer = new DeterministicSerializer(); }
|
|
58
|
+
/**
|
|
59
|
+
* @description Creates a new FabricCrudContract instance
|
|
60
|
+
* @summary Initializes a contract with a name and model class
|
|
61
|
+
* @param {string} name - The name of the contract
|
|
62
|
+
* @param {Constructor<M>} clazz - The model constructor
|
|
63
|
+
*/
|
|
64
|
+
constructor(name, clazz) {
|
|
65
|
+
super(name);
|
|
66
|
+
this.clazz = clazz;
|
|
67
|
+
this.initialized = false;
|
|
68
|
+
FabricCrudContract.adapter = this.getAdapter(clazz);
|
|
69
|
+
this.repo = Repository.forModel(clazz, FabricCrudContract.adapter.alias);
|
|
70
|
+
}
|
|
71
|
+
getAdapter(clazz) {
|
|
72
|
+
const instance = new clazz();
|
|
73
|
+
if (isModelPrivate(instance)) {
|
|
74
|
+
const pvt = modelToPrivate(instance);
|
|
75
|
+
const collections = Object.keys(pvt.private);
|
|
76
|
+
return new FabricContractPrivateDataAdapter(undefined, "fabric-private-data-adapter", collections);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
return new FabricContractAdapter(undefined, "fabric-public-data-adapter");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @description Creates a logger for a specific chaincode context
|
|
84
|
+
* @summary Returns a ContractLogger instance configured for the current context
|
|
85
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
86
|
+
* @return {ContractLogger} The logger instance
|
|
87
|
+
*/
|
|
88
|
+
logFor(ctx) {
|
|
89
|
+
return Logging.for(FabricCrudContract.name, {}, ctx);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* @description Creates a single model in the state database
|
|
93
|
+
* @summary Delegates to the repository's create method
|
|
94
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
95
|
+
* @param {M} model - The model to create
|
|
96
|
+
* @param {...any[]} args - Additional arguments
|
|
97
|
+
* @return {Promise<M>} Promise resolving to the created model
|
|
98
|
+
*/
|
|
99
|
+
async create(ctx, model, ...args) {
|
|
100
|
+
const log = this.logFor(ctx).for(this.create);
|
|
101
|
+
if (typeof model === "string")
|
|
102
|
+
model = this.deserialize(model);
|
|
103
|
+
log.info(`Creating model: ${JSON.stringify(model)}`);
|
|
104
|
+
const transient = this.getTransientData(ctx);
|
|
105
|
+
log.info(`Merging transient data...`);
|
|
106
|
+
model = this.repo.merge(model, transient);
|
|
107
|
+
return this.repo.create(model, ctx, ...args);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* @description Reads a single model from the state database
|
|
111
|
+
* @summary Delegates to the repository's read method
|
|
112
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
113
|
+
* @param {string | number} key - The key of the model to read
|
|
114
|
+
* @param {...any[]} args - Additional arguments
|
|
115
|
+
* @return {Promise<M>} Promise resolving to the retrieved model
|
|
116
|
+
*/
|
|
117
|
+
async read(ctx, key, ...args) {
|
|
118
|
+
const log = this.logFor(ctx).for(this.read);
|
|
119
|
+
log.info(`reading entry with pk ${key} `);
|
|
120
|
+
return this.repo.read(key, ctx, ...args);
|
|
121
|
+
}
|
|
122
|
+
getTransientData(ctx) {
|
|
123
|
+
const transientMap = ctx.stub.getTransient();
|
|
124
|
+
let transient = {};
|
|
125
|
+
if (transientMap.has(this.repo.tableName)) {
|
|
126
|
+
transient = JSON.parse(transientMap.get(this.repo.tableName)?.toString("utf8"));
|
|
127
|
+
}
|
|
128
|
+
return transient;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* @description Updates a single model in the state database
|
|
132
|
+
* @summary Delegates to the repository's update method
|
|
133
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
134
|
+
* @param {M} model - The model to update
|
|
135
|
+
* @param {...any[]} args - Additional arguments
|
|
136
|
+
* @return {Promise<M>} Promise resolving to the updated model
|
|
137
|
+
*/
|
|
138
|
+
async update(ctx, model, ...args) {
|
|
139
|
+
const log = this.logFor(ctx).for(this.update);
|
|
140
|
+
if (typeof model === "string")
|
|
141
|
+
model = this.deserialize(model);
|
|
142
|
+
log.info(`Updating model: ${JSON.stringify(model)}`);
|
|
143
|
+
const transient = this.getTransientData(ctx);
|
|
144
|
+
log.info(`Merging transient data...`);
|
|
145
|
+
model = this.repo.merge(model, transient);
|
|
146
|
+
return this.repo.update(model, ctx, ...args);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @description Deletes a single model from the state database
|
|
150
|
+
* @summary Delegates to the repository's delete method
|
|
151
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
152
|
+
* @param {string | number} key - The key of the model to delete
|
|
153
|
+
* @param {...any[]} args - Additional arguments
|
|
154
|
+
* @return {Promise<M>} Promise resolving to the deleted model
|
|
155
|
+
*/
|
|
156
|
+
async delete(ctx, key, ...args) {
|
|
157
|
+
const log = this.logFor(ctx).for(this.delete);
|
|
158
|
+
log.info(`deleting entry with pk ${key} `);
|
|
159
|
+
return this.repo.delete(String(key), ctx, ...args);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* @description Deletes multiple models from the state database
|
|
163
|
+
* @summary Delegates to the repository's deleteAll method
|
|
164
|
+
* @param {string[] | number[]} keys - The keys of the models to delete
|
|
165
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
166
|
+
* @param {...any[]} args - Additional arguments
|
|
167
|
+
* @return {Promise<M[]>} Promise resolving to the deleted models
|
|
168
|
+
*/
|
|
169
|
+
async deleteAll(ctx, keys, ...args) {
|
|
170
|
+
if (typeof keys === "string")
|
|
171
|
+
keys = JSON.parse(keys);
|
|
172
|
+
return this.repo.deleteAll(keys, ctx, ...args);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* @description Reads multiple models from the state database
|
|
176
|
+
* @summary Delegates to the repository's readAll method
|
|
177
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
178
|
+
* @param {string[] | number[]} keys - The keys of the models to read
|
|
179
|
+
* @param {...any[]} args - Additional arguments
|
|
180
|
+
* @return {Promise<M[]>} Promise resolving to the retrieved models
|
|
181
|
+
*/
|
|
182
|
+
async readAll(ctx, keys, ...args) {
|
|
183
|
+
if (typeof keys === "string")
|
|
184
|
+
keys = JSON.parse(keys);
|
|
185
|
+
return this.repo.readAll(keys, ctx, ...args);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* @description Updates multiple models in the state database
|
|
189
|
+
* @summary Delegates to the repository's updateAll method
|
|
190
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
191
|
+
* @param {M[]} models - The models to update
|
|
192
|
+
* @param {...any[]} args - Additional arguments
|
|
193
|
+
* @return {Promise<M[]>} Promise resolving to the updated models
|
|
194
|
+
*/
|
|
195
|
+
async updateAll(ctx, models, ...args) {
|
|
196
|
+
const log = this.logFor(ctx).for(this.updateAll);
|
|
197
|
+
if (typeof models === "string")
|
|
198
|
+
models = JSON.parse(models)
|
|
199
|
+
.map((m) => this.deserialize(m))
|
|
200
|
+
.map((m) => new this.clazz(m));
|
|
201
|
+
log.info(`updating ${models.length} entries to the table`);
|
|
202
|
+
return this.repo.updateAll(models, ctx, ...args);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* @description Executes a raw query against the state database
|
|
206
|
+
* @summary Delegates to the repository's raw method
|
|
207
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
208
|
+
* @param {any} rawInput - The query to execute
|
|
209
|
+
* @param {boolean} docsOnly - Whether to return only documents
|
|
210
|
+
* @param {...any[]} args - Additional arguments
|
|
211
|
+
* @return {Promise<any>} Promise resolving to the query results
|
|
212
|
+
*/
|
|
213
|
+
async raw(ctx, rawInput, docsOnly, ...args) {
|
|
214
|
+
if (typeof rawInput === "string")
|
|
215
|
+
rawInput = JSON.parse(rawInput);
|
|
216
|
+
return this.repo.raw(rawInput, docsOnly, ctx, ...args);
|
|
217
|
+
}
|
|
218
|
+
serialize(model) {
|
|
219
|
+
return FabricCrudContract.serializer.serialize(model);
|
|
220
|
+
}
|
|
221
|
+
deserialize(str) {
|
|
222
|
+
return FabricCrudContract.serializer.deserialize(str);
|
|
223
|
+
}
|
|
224
|
+
async init(ctx) {
|
|
225
|
+
const log = this.logFor(ctx).for(this.init);
|
|
226
|
+
log.info(`Running contract initialization...`);
|
|
227
|
+
this.initialized = true;
|
|
228
|
+
log.info(`Contract initialization completed.`);
|
|
229
|
+
}
|
|
230
|
+
async healthcheck(ctx) {
|
|
231
|
+
const log = this.logFor(ctx).for(this.healthcheck);
|
|
232
|
+
log.info(`Running Healthcheck: ${this.initialized}...`);
|
|
233
|
+
return { healthcheck: this.initialized };
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* @description Creates multiple models in the state database
|
|
237
|
+
* @summary Delegates to the repository's createAll method
|
|
238
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
239
|
+
* @param {M[]} models - The models to create
|
|
240
|
+
* @param {...any[]} args - Additional arguments
|
|
241
|
+
* @return {Promise<M[]>} Promise resolving to the created models
|
|
242
|
+
*/
|
|
243
|
+
async createAll(ctx, models, ...args) {
|
|
244
|
+
const log = this.logFor(ctx).for(this.createAll);
|
|
245
|
+
if (typeof models === "string")
|
|
246
|
+
models = JSON.parse(models)
|
|
247
|
+
.map((m) => this.deserialize(m))
|
|
248
|
+
.map((m) => new this.clazz(m));
|
|
249
|
+
log.info(`adding ${models.length} entries to the table`);
|
|
250
|
+
return this.repo.createAll(models, ctx, ...args);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3J1ZC1jb250cmFjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb250cmFjdHMvY3J1ZC9jcnVkLWNvbnRyYWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxnQ0FBMkI7QUFDM0QsT0FBTyxFQUFXLFFBQVEsRUFBa0IsTUFBTSxxQkFBcUIsQ0FBQztBQUV4RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFNUMsT0FBTyxFQUFFLHVCQUF1QixFQUFFLGtEQUE2QztBQUkvRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDNUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsNkJBQXdCO0FBQ2pFLE9BQU8sRUFBRSxnQ0FBZ0MsRUFBRSwyQ0FBc0M7QUFFakY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBK0NHO0FBQ0gsTUFBTSxPQUFnQixrQkFDcEIsU0FBUSxRQUFRO2FBVVUsZUFBVSxHQUFHLElBQUksdUJBQXVCLEVBQUUsQUFBaEMsQ0FBaUM7SUFJckU7Ozs7O09BS0c7SUFDSCxZQUNFLElBQVksRUFDTyxLQUFxQjtRQUV4QyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFGTyxVQUFLLEdBQUwsS0FBSyxDQUFnQjtRQVZoQyxnQkFBVyxHQUFZLEtBQUssQ0FBQztRQWFyQyxrQkFBa0IsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRVMsVUFBVSxDQUFDLEtBQXFCO1FBQ3hDLE1BQU0sUUFBUSxHQUFHLElBQUksS0FBSyxFQUFF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LElBQUksQ0FBQyxXQUFXLEtBQUssQ0FBQyxDQUFDO1FBQ3hELE9BQU8sRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLFNBQVMsQ0FDYixHQUFRLEVBQ1IsTUFBb0IsRUFDcEIsR0FBRyxJQUFXO1FBRWQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRWpELElBQUksT0FBTyxNQUFNLEtBQUssUUFBUTtZQUM1QixNQUFNLEdBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQVE7aUJBQ2hDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDL0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQVEsQ0FBQztRQUUxQyxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLENBQUMsQ0FBQztRQUN6RCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQXdCLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7SUFDckUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEZhYnJpY0NvbnRyYWN0QWRhcHRlciB9IGZyb20gXCIuLi9Db250cmFjdEFkYXB0ZXJcIjtcbmltcG9ydCB7IENvbnRleHQsIENvbnRyYWN0LCBDb250ZXh0IGFzIEN0eCB9IGZyb20gXCJmYWJyaWMtY29udHJhY3QtYXBpXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwsIFNlcmlhbGl6ZXIgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5IH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBGYWJyaWNDb250cmFjdFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vRmFicmljQ29udHJhY3RSZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBEZXRlcm1pbmlzdGljU2VyaWFsaXplciB9IGZyb20gXCIuLi8uLi9zaGFyZWQvRGV0ZXJtaW5pc3RpY1NlcmlhbGl6ZXJcIjtcbmltcG9ydCB7IE1hbmdvUXVlcnkgfSBmcm9tIFwiQGRlY2FmLXRzL2Zvci1jb3VjaGRiXCI7XG5pbXBvcnQgeyBDaGVja2FibGUsIGhlYWx0aGNoZWNrIH0gZnJvbSBcIi4uLy4uL3NoYXJlZC9pbnRlcmZhY2VzL0NoZWNrYWJsZVwiO1xuaW1wb3J0IHsgQ29udHJhY3RMb2dnZXIgfSBmcm9tIFwiLi4vbG9nZ2luZ1wiO1xuaW1wb3J0IHsgTG9nZ2luZyB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuaW1wb3J0IHsgaXNNb2RlbFByaXZhdGUsIG1vZGVsVG9Qcml2YXRlIH0gZnJvbSBcIi4uL3ByaXZhdGUtZGF0YVwiO1xuaW1wb3J0IHsgRmFicmljQ29udHJhY3RQcml2YXRlRGF0YUFkYXB0ZXIgfSBmcm9tIFwiLi4vQ29udHJhY3RQcml2YXRlRGF0YUFkYXB0ZXJcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQmFzZSBjb250cmFjdCBjbGFzcyBmb3IgQ1JVRCBvcGVyYXRpb25zIGluIEZhYnJpYyBjaGFpbmNvZGVcbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIHN0YW5kYXJkIGNyZWF0ZSwgcmVhZCwgdXBkYXRlLCBhbmQgZGVsZXRlIG9wZXJhdGlvbnMgZm9yIG1vZGVscyBpbiBGYWJyaWMgY2hhaW5jb2RlXG4gKiBAdGVtcGxhdGUgTSAtIFR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAY2xhc3MgRmFicmljQ3J1ZENvbnRyYWN0XG4gKiBAZXh0ZW5kcyB7Q29udHJhY3R9XG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gRGVmaW5lIGEgbW9kZWxcbiAqIEB0YWJsZSgnYXNzZXRzJylcbiAqIGNsYXNzIEFzc2V0IGV4dGVuZHMgTW9kZWwge1xuICogICBAaWQoKVxuICogICBpZDogc3RyaW5nO1xuICpcbiAqICAgQHByb3BlcnR5KClcbiAqICAgZGF0YTogc3RyaW5nO1xuICogfVxuICpcbiAqIC8vIENyZWF0ZSBhIGNvbnRyYWN0IHRoYXQgZXh0ZW5kcyBGYWJyaWNDcnVkQ29udHJhY3RcbiAqIGV4cG9ydCBjbGFzcyBBc3NldENvbnRyYWN0IGV4dGVuZHMgRmFicmljQ3J1ZENvbnRyYWN0PEFzc2V0PiB7XG4gKiAgIGNvbnN0cnVjdG9yKCkge1xuICogICAgIHN1cGVyKCdBc3NldENvbnRyYWN0JywgQXNzZXQpO1xuICogICB9XG4gKlxuICogICAvLyBBZGQgY3VzdG9tIG1ldGhvZHMgYXMgbmVlZGVkXG4gKiAgIGFzeW5jIGdldEFzc2V0SGlzdG9yeShjdHg6IENvbnRleHQsIGlkOiBzdHJpbmcpOiBQcm9taXNlPGFueVtdPiB7XG4gKiAgICAgLy8gQ3VzdG9tIGltcGxlbWVudGF0aW9uXG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgQ29udHJhY3RcbiAqICAgcGFydGljaXBhbnQgUmVwb3NpdG9yeVxuICogICBwYXJ0aWNpcGFudCBBZGFwdGVyXG4gKiAgIHBhcnRpY2lwYW50IFN0YXRlREJcbiAqXG4gKiAgIENsaWVudC0+PkNvbnRyYWN0OiBjcmVhdGUoY3R4LCBtb2RlbClcbiAqICAgQ29udHJhY3QtPj5SZXBvc2l0b3J5OiByZXBvc2l0b3J5KGN0eClcbiAqICAgQ29udHJhY3QtPj5SZXBvc2l0b3J5OiBjcmVhdGUobW9kZWwsIGN0eClcbiAqICAgUmVwb3NpdG9yeS0+PkFkYXB0ZXI6IGNyZWF0ZSh0YWJsZU5hbWUsIGlkLCByZWNvcmQsIHRyYW5zaWVudCwgY3R4KVxuICogICBBZGFwdGVyLT4+U3RhdGVEQjogcHV0U3RhdGUoaWQsIHNlcmlhbGl6ZWREYXRhKVxuICogICBTdGF0ZURCLS0+PkFkYXB0ZXI6IFN1Y2Nlc3NcbiAqICAgQWRhcHRlci0tPj5SZXBvc2l0b3J5OiByZWNvcmRcbiAqICAgUmVwb3NpdG9yeS0tPj5Db250cmFjdDogbW9kZWxcbiAqICAgQ29udHJhY3QtLT4+Q2xpZW50OiBtb2RlbFxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRmFicmljQ3J1ZENvbnRyYWN0PE0gZXh0ZW5kcyBNb2RlbD5cbiAgZXh0ZW5kcyBDb250cmFjdFxuICBpbXBsZW1lbnRzIENoZWNrYWJsZVxue1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNoYXJlZCBhZGFwdGVyIGluc3RhbmNlIGZvciBhbGwgY29udHJhY3QgaW5zdGFuY2VzXG4gICAqL1xuICBwcm90ZWN0ZWQgc3RhdGljIGFkYXB0ZXI6IEZhYnJpY0NvbnRyYWN0QWRhcHRlcjtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVwbzogRmFicmljQ29udHJhY3RSZXBvc2l0b3J5PE0+O1xuXG4gIHByb3RlY3RlZCBzdGF0aWMgcmVhZG9ubHkgc2VyaWFsaXplciA9IG5ldyBEZXRlcm1pbmlzdGljU2VyaWFsaXplcigpO1xuXG4gIHByb3RlY3RlZCBpbml0aWFsaXplZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyBGYWJyaWNDcnVkQ29udHJhY3QgaW5zdGFuY2VcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBjb250cmFjdCB3aXRoIGEgbmFtZSBhbmQgbW9kZWwgY2xhc3NcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgY29udHJhY3RcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gY2xhenogLSBUaGUgbW9kZWwgY29uc3RydWN0b3JcbiAgICovXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGNsYXp6OiBDb25zdHJ1Y3RvcjxNPlxuICApIHtcbiAgICBzdXBlcihuYW1lKTtcbiAgICBGYWJyaWNDcnVkQ29udHJhY3QuYWRhcHRlciA9IHRoaXMuZ2V0QWRhcHRlcihjbGF6eik7XG4gICAgdGhpcy5yZXBvID0gUmVwb3NpdG9yeS5mb3JNb2RlbChjbGF6eiwgRmFicmljQ3J1ZENvbnRyYWN0LmFkYXB0ZXIuYWxpYXMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldEFkYXB0ZXIoY2xheno6IENvbnN0cnVjdG9yPE0+KTogRmFicmljQ29udHJhY3RBZGFwdGVyIHtcbiAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyBjbGF6eigpO1xuXG4gICAgaWYgKGlzTW9kZWxQcml2YXRlKGluc3RhbmNlKSkge1xuICAgICAgY29uc3QgcHZ0ID0gbW9kZWxUb1ByaXZhdGUoaW5zdGFuY2UpO1xuICAgICAgY29uc3QgY29sbGVjdGlvbnMgPSBPYmplY3Qua2V5cyhwdnQucHJpdmF0ZSEpO1xuXG4gICAgICByZXR1cm4gbmV3IEZhYnJpY0NvbnRyYWN0UHJpdmF0ZURhdGFBZGFwdGVyKFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIFwiZmFicmljLXByaXZhdGUtZGF0YS1hZGFwdGVyXCIsXG4gICAgICAgIGNvbGxlY3Rpb25zXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV3IEZhYnJpY0NvbnRyYWN0QWRhcHRlcih1bmRlZmluZWQsIFwiZmFicmljLXB1YmxpYy1kYXRhLWFkYXB0ZXJcIik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbG9nZ2VyIGZvciBhIHNwZWNpZmljIGNoYWluY29kZSBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IFJldHVybnMgYSBDb250cmFjdExvZ2dlciBpbnN0YW5jZSBjb25maWd1cmVkIGZvciB0aGUgY3VycmVudCBjb250ZXh0XG4gICAqIEBwYXJhbSB7Q3R4fSBjdHggLSBUaGUgRmFicmljIGNoYWluY29kZSBjb250ZXh0XG4gICAqIEByZXR1cm4ge0NvbnRyYWN0TG9nZ2VyfSBUaGUgbG9nZ2VyIGluc3RhbmNlXG4gICAqL1xuICBwdWJsaWMgbG9nRm9yKGN0eDogQ29udGV4dCk6IENvbnRyYWN0TG9nZ2VyIHtcbiAgICByZXR1cm4gTG9nZ2luZy5mb3IoRmFicmljQ3J1ZENvbnRyYWN0Lm5hbWUsIHt9LCBjdHgpIGFzIENvbnRyYWN0TG9nZ2VyO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgc2luZ2xlIG1vZGVsIGluIHRoZSBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdG8gdGhlIHJlcG9zaXRvcnkncyBjcmVhdGUgbWV0aG9kXG4gICAqIEBwYXJhbSB7Q3R4fSBjdHggLSBUaGUgRmFicmljIGNoYWluY29kZSBjb250ZXh0XG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgdG8gY3JlYXRlXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50c1xuICAgKiBAcmV0dXJuIHtQcm9taXNlPE0+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgY3JlYXRlZCBtb2RlbFxuICAgKi9cbiAgYXN5bmMgY3JlYXRlKFxuICAgIGN0eDogQ3R4LFxuICAgIG1vZGVsOiBzdHJpbmcgfCBNLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8c3RyaW5nIHwgTT4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nRm9yKGN0eCkuZm9yKHRoaXMuY3JlYXRlKTtcblxuICAgIGlmICh0eXBlb2YgbW9kZWwgPT09IFwic3RyaW5nXCIpIG1vZGVsID0gdGhpcy5kZXNlcmlhbGl6ZTxNPihtb2RlbCkgYXMgYW55O1xuXG4gICAgbG9nLmluZm8oYENyZWF0aW5nIG1vZGVsOiAke0pTT04uc3RyaW5naWZ5KG1vZGVsKX1gKTtcblxuICAgIGNvbnN0IHRyYW5zaWVudCA9IHRoaXMuZ2V0VHJhbnNpZW50RGF0YShjdHgpO1xuXG4gICAgbG9nLmluZm8oYE1lcmdpbmcgdHJhbnNpZW50IGRhdGEuLi5gKTtcbiAgICBtb2RlbCA9ICh0aGlzLnJlcG8gYXMgYW55KS5tZXJnZShtb2RlbCBhcyBNLCB0cmFuc2llbnQpO1xuXG4gICAgcmV0dXJuIHRoaXMucmVwby5jcmVhdGUobW9kZWwgYXMgdW5rbm93biBhcyBNLCBjdHgsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWFkcyBhIHNpbmdsZSBtb2RlbCBmcm9tIHRoZSBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdG8gdGhlIHJlcG9zaXRvcnkncyByZWFkIG1ldGhvZFxuICAgKiBAcGFyYW0ge0N0eH0gY3R4IC0gVGhlIEZhYnJpYyBjaGFpbmNvZGUgY29udGV4dFxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlcn0ga2V5IC0gVGhlIGtleSBvZiB0aGUgbW9kZWwgdG8gcmVhZFxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICogQHJldHVybiB7UHJvbWlzZTxNPn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIHJldHJpZXZlZCBtb2RlbFxuICAgKi9cbiAgYXN5bmMgcmVhZChcbiAgICBjdHg6IEN0eCxcbiAgICBrZXk6IHN0cmluZyB8IG51bWJlcixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPE0gfCBzdHJpbmc+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZ0ZvcihjdHgpLmZvcih0aGlzLnJlYWQpO1xuXG4gICAgbG9nLmluZm8oYHJlYWRpbmcgZW50cnkgd2l0aCBwayAke2tleX0gYCk7XG5cbiAgICByZXR1cm4gdGhpcy5yZXBvLnJlYWQoa2V5LCBjdHgsIC4uLmFyZ3MpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldFRyYW5zaWVudERhdGEoY3R4OiBDdHgpOiBhbnkge1xuICAgIGNvbnN0IHRyYW5zaWVudE1hcCA9IGN0eC5zdHViLmdldFRyYW5zaWVudCgpO1xuICAgIGxldCB0cmFuc2llbnQ6IGFueSA9IHt9O1xuXG4gICAgaWYgKHRyYW5zaWVudE1hcC5oYXMoKHRoaXMucmVwbyBhcyBhbnkpLnRhYmxlTmFtZSkpIHtcbiAgICAgIHRyYW5zaWVudCA9IEpTT04ucGFyc2UoXG4gICAgICAgICh0cmFuc2llbnRNYXAuZ2V0KCh0aGlzLnJlcG8gYXMgYW55KS50YWJsZU5hbWUpIGFzIEJ1ZmZlcik/LnRvU3RyaW5nKFxuICAgICAgICAgIFwidXRmOFwiXG4gICAgICAgICkgYXMgc3RyaW5nXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0cmFuc2llbnQ7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgYSBzaW5nbGUgbW9kZWwgaW4gdGhlIHN0YXRlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0byB0aGUgcmVwb3NpdG9yeSdzIHVwZGF0ZSBtZXRob2RcbiAgICogQHBhcmFtIHtDdHh9IGN0eCAtIFRoZSBGYWJyaWMgY2hhaW5jb2RlIGNvbnRleHRcbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCB0byB1cGRhdGVcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TT59IFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSB1cGRhdGVkIG1vZGVsXG4gICAqL1xuICBhc3luYyB1cGRhdGUoXG4gICAgY3R4OiBDdHgsXG4gICAgbW9kZWw6IHN0cmluZyB8IE0sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxzdHJpbmcgfCBNPiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2dGb3IoY3R4KS5mb3IodGhpcy51cGRhdGUpO1xuXG4gICAgaWYgKHR5cGVvZiBtb2RlbCA9PT0gXCJzdHJpbmdcIikgbW9kZWwgPSB0aGlzLmRlc2VyaWFsaXplPE0+KG1vZGVsKSBhcyBhbnk7XG5cbiAgICBsb2cuaW5mbyhgVXBkYXRpbmcgbW9kZWw6ICR7SlNPTi5zdHJpbmdpZnkobW9kZWwpfWApO1xuXG4gICAgY29uc3QgdHJhbnNpZW50ID0gdGhpcy5nZXRUcmFuc2llbnREYXRhKGN0eCk7XG5cbiAgICBsb2cuaW5mbyhgTWVyZ2luZyB0cmFuc2llbnQgZGF0YS4uLmApO1xuICAgIG1vZGVsID0gKHRoaXMucmVwbyBhcyBhbnkpLm1lcmdlKG1vZGVsIGFzIE0sIHRyYW5zaWVudCk7XG5cbiAgICByZXR1cm4gdGhpcy5yZXBvLnVwZGF0ZShtb2RlbCBhcyB1bmtub3duIGFzIE0sIGN0eCwgLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgYSBzaW5nbGUgbW9kZWwgZnJvbSB0aGUgc3RhdGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgRGVsZWdhdGVzIHRvIHRoZSByZXBvc2l0b3J5J3MgZGVsZXRlIG1ldGhvZFxuICAgKiBAcGFyYW0ge0N0eH0gY3R4IC0gVGhlIEZhYnJpYyBjaGFpbmNvZGUgY29udGV4dFxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlcn0ga2V5IC0gVGhlIGtleSBvZiB0aGUgbW9kZWwgdG8gZGVsZXRlXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50c1xuICAgKiBAcmV0dXJuIHtQcm9taXNlPE0+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgZGVsZXRlZCBtb2RlbFxuICAgKi9cbiAgYXN5bmMgZGVsZXRlKFxuICAgIGN0eDogQ3R4LFxuICAgIGtleTogc3RyaW5nIHwgbnVtYmVyLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8TSB8IHN0cmluZz4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nRm9yKGN0eCkuZm9yKHRoaXMuZGVsZXRlKTtcbiAgICBsb2cuaW5mbyhgZGVsZXRpbmcgZW50cnkgd2l0aCBwayAke2tleX0gYCk7XG4gICAgcmV0dXJuIHRoaXMucmVwby5kZWxldGUoU3RyaW5nKGtleSksIGN0eCwgLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgbXVsdGlwbGUgbW9kZWxzIGZyb20gdGhlIHN0YXRlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0byB0aGUgcmVwb3NpdG9yeSdzIGRlbGV0ZUFsbCBtZXRob2RcbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IG51bWJlcltdfSBrZXlzIC0gVGhlIGtleXMgb2YgdGhlIG1vZGVscyB0byBkZWxldGVcbiAgICogQHBhcmFtIHtDdHh9IGN0eCAtIFRoZSBGYWJyaWMgY2hhaW5jb2RlIGNvbnRleHRcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TVtdPn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIGRlbGV0ZWQgbW9kZWxzXG4gICAqL1xuICBhc3luYyBkZWxldGVBbGwoXG4gICAgY3R4OiBDdHgsXG4gICAga2V5czogc3RyaW5nIHwgc3RyaW5nW10gfCBudW1iZXJbXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPE1bXSB8IHN0cmluZz4ge1xuICAgIGlmICh0eXBlb2Yga2V5cyA9PT0gXCJzdHJpbmdcIikga2V5cyA9IEpTT04ucGFyc2Uoa2V5cykgYXMgc3RyaW5nW107XG4gICAgcmV0dXJuIHRoaXMucmVwby5kZWxldGVBbGwoa2V5cywgY3R4LCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVhZHMgbXVsdGlwbGUgbW9kZWxzIGZyb20gdGhlIHN0YXRlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0byB0aGUgcmVwb3NpdG9yeSdzIHJlYWRBbGwgbWV0aG9kXG4gICAqIEBwYXJhbSB7Q3R4fSBjdHggLSBUaGUgRmFicmljIGNoYWluY29kZSBjb250ZXh0XG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBudW1iZXJbXX0ga2V5cyAtIFRoZSBrZXlzIG9mIHRoZSBtb2RlbHMgdG8gcmVhZFxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICogQHJldHVybiB7UHJvbWlzZTxNW10+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgcmV0cmlldmVkIG1vZGVsc1xuICAgKi9cbiAgYXN5bmMgcmVhZEFsbChcbiAgICBjdHg6IEN0eCxcbiAgICBrZXlzOiBzdHJpbmcgfCBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8TVtdIHwgc3RyaW5nPiB7XG4gICAgaWYgKHR5cGVvZiBrZXlzID09PSBcInN0cmluZ1wiKSBrZXlzID0gSlNPTi5wYXJzZShrZXlzKSBhcyBzdHJpbmdbXTtcbiAgICByZXR1cm4gdGhpcy5yZXBvLnJlYWRBbGwoa2V5cywgY3R4LCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyBtdWx0aXBsZSBtb2RlbHMgaW4gdGhlIHN0YXRlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IERlbGVnYXRlcyB0byB0aGUgcmVwb3NpdG9yeSdzIHVwZGF0ZUFsbCBtZXRob2RcbiAgICogQHBhcmFtIHtDdHh9IGN0eCAtIFRoZSBGYWJyaWMgY2hhaW5jb2RlIGNvbnRleHRcbiAgICogQHBhcmFtIHtNW119IG1vZGVscyAtIFRoZSBtb2RlbHMgdG8gdXBkYXRlXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50c1xuICAgKiBAcmV0dXJuIHtQcm9taXNlPE1bXT59IFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSB1cGRhdGVkIG1vZGVsc1xuICAgKi9cbiAgYXN5bmMgdXBkYXRlQWxsKFxuICAgIGN0eDogQ3R4LFxuICAgIG1vZGVsczogc3RyaW5nIHwgTVtdLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8c3RyaW5nIHwgTVtdPiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2dGb3IoY3R4KS5mb3IodGhpcy51cGRhdGVBbGwpO1xuICAgIGlmICh0eXBlb2YgbW9kZWxzID09PSBcInN0cmluZ1wiKVxuICAgICAgbW9kZWxzID0gKEpTT04ucGFyc2UobW9kZWxzKSBhcyBbXSlcbiAgICAgICAgLm1hcCgobSkgPT4gdGhpcy5kZXNlcmlhbGl6ZShtKSlcbiAgICAgICAgLm1hcCgobSkgPT4gbmV3IHRoaXMuY2xhenoobSkpIGFzIGFueTtcblxuICAgIGxvZy5pbmZvKGB1cGRhdGluZyAke21vZGVscy5sZW5ndGh9IGVudHJpZXMgdG8gdGhlIHRhYmxlYCk7XG4gICAgcmV0dXJuIHRoaXMucmVwby51cGRhdGVBbGwobW9kZWxzIGFzIHVua25vd24gYXMgTVtdLCBjdHgsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeGVjdXRlcyBhIHJhdyBxdWVyeSBhZ2FpbnN0IHRoZSBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdG8gdGhlIHJlcG9zaXRvcnkncyByYXcgbWV0aG9kXG4gICAqIEBwYXJhbSB7Q3R4fSBjdHggLSBUaGUgRmFicmljIGNoYWluY29kZSBjb250ZXh0XG4gICAqIEBwYXJhbSB7YW55fSByYXdJbnB1dCAtIFRoZSBxdWVyeSB0byBleGVjdXRlXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gZG9jc09ubHkgLSBXaGV0aGVyIHRvIHJldHVybiBvbmx5IGRvY3VtZW50c1xuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICogQHJldHVybiB7UHJvbWlzZTxhbnk+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgcXVlcnkgcmVzdWx0c1xuICAgKi9cbiAgYXN5bmMgcmF3KFxuICAgIGN0eDogQ3R4LFxuICAgIHJhd0lucHV0OiBNYW5nb1F1ZXJ5IHwgc3RyaW5nLFxuICAgIGRvY3NPbmx5OiBib29sZWFuLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8YW55IHwgc3RyaW5nPiB7XG4gICAgaWYgKHR5cGVvZiByYXdJbnB1dCA9PT0gXCJzdHJpbmdcIilcbiAgICAgIHJhd0lucHV0ID0gSlNPTi5wYXJzZShyYXdJbnB1dCkgYXMgTWFuZ29RdWVyeTtcbiAgICByZXR1cm4gdGhpcy5yZXBvLnJhdyhyYXdJbnB1dCwgZG9jc09ubHksIGN0eCwgLi4uYXJncyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2VyaWFsaXplKG1vZGVsOiBNKTogc3RyaW5nIHtcbiAgICByZXR1cm4gRmFicmljQ3J1ZENvbnRyYWN0LnNlcmlhbGl6ZXIuc2VyaWFsaXplKG1vZGVsKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBkZXNlcmlhbGl6ZTxNIGV4dGVuZHMgTW9kZWw+KHN0cjogc3RyaW5nKTogTSB7XG4gICAgcmV0dXJuIChcbiAgICAgIEZhYnJpY0NydWRDb250cmFjdC5zZXJpYWxpemVyIGFzIHVua25vd24gYXMgU2VyaWFsaXplcjxNPlxuICAgICkuZGVzZXJpYWxpemUoc3RyKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBpbml0KGN0eDogQ3R4KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2dGb3IoY3R4KS5mb3IodGhpcy5pbml0KTtcbiAgICBsb2cuaW5mbyhgUnVubmluZyBjb250cmFjdCBpbml0aWFsaXphdGlvbi4uLmApO1xuICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIGxvZy5pbmZvKGBDb250cmFjdCBpbml0aWFsaXphdGlvbiBjb21wbGV0ZWQuYCk7XG4gIH1cblxuICBhc3luYyBoZWFsdGhjaGVjayhjdHg6IEN0eCk6IFByb21pc2U8c3RyaW5nIHwgaGVhbHRoY2hlY2s+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZ0ZvcihjdHgpLmZvcih0aGlzLmhlYWx0aGNoZWNrKTtcbiAgICBsb2cuaW5mbyhgUnVubmluZyBIZWFsdGhjaGVjazogJHt0aGlzLmluaXRpYWxpemVkfS4uLmApO1xuICAgIHJldHVybiB7IGhlYWx0aGNoZWNrOiB0aGlzLmluaXRpYWxpemVkIH07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgbXVsdGlwbGUgbW9kZWxzIGluIHRoZSBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgdG8gdGhlIHJlcG9zaXRvcnkncyBjcmVhdGVBbGwgbWV0aG9kXG4gICAqIEBwYXJhbSB7Q3R4fSBjdHggLSBUaGUgRmFicmljIGNoYWluY29kZSBjb250ZXh0XG4gICAqIEBwYXJhbSB7TVtdfSBtb2RlbHMgLSBUaGUgbW9kZWxzIHRvIGNyZWF0ZVxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICogQHJldHVybiB7UHJvbWlzZTxNW10+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgY3JlYXRlZCBtb2RlbHNcbiAgICovXG4gIGFzeW5jIGNyZWF0ZUFsbChcbiAgICBjdHg6IEN0eCxcbiAgICBtb2RlbHM6IHN0cmluZyB8IE1bXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPHN0cmluZyB8IE1bXT4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nRm9yKGN0eCkuZm9yKHRoaXMuY3JlYXRlQWxsKTtcblxuICAgIGlmICh0eXBlb2YgbW9kZWxzID09PSBcInN0cmluZ1wiKVxuICAgICAgbW9kZWxzID0gKEpTT04ucGFyc2UobW9kZWxzKSBhcyBbXSlcbiAgICAgICAgLm1hcCgobSkgPT4gdGhpcy5kZXNlcmlhbGl6ZShtKSlcbiAgICAgICAgLm1hcCgobSkgPT4gbmV3IHRoaXMuY2xhenoobSkpIGFzIGFueTtcblxuICAgIGxvZy5pbmZvKGBhZGRpbmcgJHttb2RlbHMubGVuZ3RofSBlbnRyaWVzIHRvIHRoZSB0YWJsZWApO1xuICAgIHJldHVybiB0aGlzLnJlcG8uY3JlYXRlQWxsKG1vZGVscyBhcyB1bmtub3duIGFzIE1bXSwgY3R4LCAuLi5hcmdzKTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export * from "./crud-contract.js";
|
|
2
|
+
export * from "./serialized-crud-contract.js";
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29udHJhY3RzL2NydWQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsbUNBQWdDO0FBQ2hDLDhDQUEyQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gXCIuL2NydWQtY29udHJhY3RcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3NlcmlhbGl6ZWQtY3J1ZC1jb250cmFjdFwiO1xuIl19
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { FabricCrudContract } from "./crud-contract";
|
|
2
|
+
import { Constructor, Model } from "@decaf-ts/decorator-validation";
|
|
3
|
+
import { Context, Context as Ctx } from "fabric-contract-api";
|
|
4
|
+
import { ContractLogger } from "../logging";
|
|
5
|
+
/**
|
|
6
|
+
* @description CRUD contract variant that serializes/deserializes payloads
|
|
7
|
+
* @summary Exposes the same CRUD operations as FabricCrudContract but takes and returns JSON strings to facilitate simple client interactions.
|
|
8
|
+
* @template M - Model type handled by this contract
|
|
9
|
+
* @param {string} name - The contract name
|
|
10
|
+
* @param {Constructor<M>} clazz - The model constructor used to instantiate models from JSON
|
|
11
|
+
* @return {void}
|
|
12
|
+
* @class SerializedCrudContract
|
|
13
|
+
* @example
|
|
14
|
+
* const contract = new SerializedCrudContract<MyModel>('MyModelContract', MyModel);
|
|
15
|
+
* // Client submits JSON string payloads and receives JSON string responses
|
|
16
|
+
*/
|
|
17
|
+
export declare class SerializedCrudContract<M extends Model> extends FabricCrudContract<M> {
|
|
18
|
+
constructor(name: string, clazz: Constructor<M>);
|
|
19
|
+
/**
|
|
20
|
+
* @description Creates a logger for a specific chaincode context
|
|
21
|
+
* @summary Returns a ContractLogger instance configured for the current context
|
|
22
|
+
* @param {Ctx} ctx - The Fabric chaincode context
|
|
23
|
+
* @return {ContractLogger} The logger instance
|
|
24
|
+
*/
|
|
25
|
+
logFor(ctx: Context): ContractLogger;
|
|
26
|
+
create(ctx: Ctx, model: string): Promise<string>;
|
|
27
|
+
read(ctx: Ctx, key: string): Promise<string>;
|
|
28
|
+
update(ctx: Ctx, model: string): Promise<string>;
|
|
29
|
+
delete(ctx: Ctx, key: string): Promise<string>;
|
|
30
|
+
deleteAll(ctx: Ctx, keys: string): Promise<string>;
|
|
31
|
+
readAll(ctx: Ctx, keys: string): Promise<string>;
|
|
32
|
+
updateAll(ctx: Ctx, models: string): Promise<string>;
|
|
33
|
+
raw(ctx: Ctx, rawInput: string, docsOnly: boolean): Promise<any>;
|
|
34
|
+
init(ctx: Ctx): Promise<void>;
|
|
35
|
+
healthcheck(ctx: Ctx): Promise<string>;
|
|
36
|
+
createAll(ctx: Ctx, models: string): Promise<string>;
|
|
37
|
+
}
|