@decaf-ts/for-fabric 0.1.119 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/for-fabric.cjs +1 -1
  2. package/dist/for-fabric.cjs.map +1 -1
  3. package/dist/for-fabric.js +1 -1
  4. package/dist/for-fabric.js.map +1 -1
  5. package/lib/client/FabricClientAdapter.cjs +4 -7
  6. package/lib/client/FabricClientAdapter.js.map +1 -1
  7. package/lib/client/services/FabricIdentityService.cjs +3 -2
  8. package/lib/client/services/FabricIdentityService.js.map +1 -1
  9. package/lib/contract/OtherMarketContract.cjs +30 -0
  10. package/lib/contract/OtherMarketContract.d.ts +5 -0
  11. package/lib/contract/OtherMarketContract.js.map +1 -0
  12. package/lib/contract/OtherProductStrengthContract.cjs +30 -0
  13. package/lib/contract/OtherProductStrengthContract.d.ts +5 -0
  14. package/lib/contract/OtherProductStrengthContract.js.map +1 -0
  15. package/lib/contract/index.cjs +4 -0
  16. package/lib/contract/index.js.map +1 -1
  17. package/lib/contract/models/Audit.js.map +1 -1
  18. package/lib/contract/models/OtherAudit.cjs +105 -0
  19. package/lib/contract/models/OtherAudit.d.ts +13 -0
  20. package/lib/contract/models/OtherAudit.js.map +1 -0
  21. package/lib/contract/models/OtherMarket.cjs +78 -0
  22. package/lib/contract/models/OtherMarket.d.ts +12 -0
  23. package/lib/contract/models/OtherMarket.js.map +1 -0
  24. package/lib/contract/models/OtherProductShared.cjs +15 -4
  25. package/lib/contract/models/OtherProductShared.d.ts +4 -0
  26. package/lib/contract/models/OtherProductShared.js.map +1 -1
  27. package/lib/contract/models/OtherProductStrength.cjs +81 -0
  28. package/lib/contract/models/OtherProductStrength.d.ts +11 -0
  29. package/lib/contract/models/OtherProductStrength.js.map +1 -0
  30. package/lib/contract/models/Product.cjs +1 -1
  31. package/lib/contract/models/Product.js.map +1 -1
  32. package/lib/contract/models/ProductStrength.js.map +1 -1
  33. package/lib/contract/models/decorators-private.cjs +88 -0
  34. package/lib/contract/models/decorators-private.d.ts +16 -0
  35. package/lib/contract/models/decorators-private.js.map +1 -0
  36. package/lib/contract/models/decorators.cjs +31 -2
  37. package/lib/contract/models/decorators.d.ts +6 -1
  38. package/lib/contract/models/decorators.js.map +1 -1
  39. package/lib/contracts/ContractAdapter.cjs +259 -409
  40. package/lib/contracts/ContractAdapter.d.ts +5 -29
  41. package/lib/contracts/ContractAdapter.js.map +1 -1
  42. package/lib/contracts/ContractContext.cjs +41 -13
  43. package/lib/contracts/ContractContext.d.ts +13 -8
  44. package/lib/contracts/ContractContext.js.map +1 -1
  45. package/lib/contracts/FabricContractRepository.cjs +70 -0
  46. package/lib/contracts/FabricContractRepository.d.ts +6 -0
  47. package/lib/contracts/FabricContractRepository.js.map +1 -1
  48. package/lib/contracts/FabricContractSequence.cjs +7 -23
  49. package/lib/contracts/FabricContractSequence.js.map +1 -1
  50. package/lib/contracts/FabricContractStatement.cjs +136 -1
  51. package/lib/contracts/FabricContractStatement.d.ts +5 -2
  52. package/lib/contracts/FabricContractStatement.js.map +1 -1
  53. package/lib/contracts/crud/crud-contract.cjs +42 -17
  54. package/lib/contracts/crud/crud-contract.d.ts +6 -5
  55. package/lib/contracts/crud/crud-contract.js.map +1 -1
  56. package/lib/contracts/types.d.ts +9 -2
  57. package/lib/esm/client/FabricClientAdapter.js +4 -7
  58. package/lib/esm/client/FabricClientAdapter.js.map +1 -1
  59. package/lib/esm/client/services/FabricIdentityService.js +3 -2
  60. package/lib/esm/client/services/FabricIdentityService.js.map +1 -1
  61. package/lib/esm/contract/OtherMarketContract.d.ts +5 -0
  62. package/lib/esm/contract/OtherMarketContract.js +27 -0
  63. package/lib/esm/contract/OtherMarketContract.js.map +1 -0
  64. package/lib/esm/contract/OtherProductStrengthContract.d.ts +5 -0
  65. package/lib/esm/contract/OtherProductStrengthContract.js +27 -0
  66. package/lib/esm/contract/OtherProductStrengthContract.js.map +1 -0
  67. package/lib/esm/contract/index.js +4 -0
  68. package/lib/esm/contract/index.js.map +1 -1
  69. package/lib/esm/contract/models/Audit.js +1 -1
  70. package/lib/esm/contract/models/Audit.js.map +1 -1
  71. package/lib/esm/contract/models/OtherAudit.d.ts +13 -0
  72. package/lib/esm/contract/models/OtherAudit.js +102 -0
  73. package/lib/esm/contract/models/OtherAudit.js.map +1 -0
  74. package/lib/esm/contract/models/OtherMarket.d.ts +12 -0
  75. package/lib/esm/contract/models/OtherMarket.js +75 -0
  76. package/lib/esm/contract/models/OtherMarket.js.map +1 -0
  77. package/lib/esm/contract/models/OtherProductShared.d.ts +4 -0
  78. package/lib/esm/contract/models/OtherProductShared.js +16 -5
  79. package/lib/esm/contract/models/OtherProductShared.js.map +1 -1
  80. package/lib/esm/contract/models/OtherProductStrength.d.ts +11 -0
  81. package/lib/esm/contract/models/OtherProductStrength.js +78 -0
  82. package/lib/esm/contract/models/OtherProductStrength.js.map +1 -0
  83. package/lib/esm/contract/models/Product.js +1 -1
  84. package/lib/esm/contract/models/Product.js.map +1 -1
  85. package/lib/esm/contract/models/ProductStrength.js +1 -1
  86. package/lib/esm/contract/models/ProductStrength.js.map +1 -1
  87. package/lib/esm/contract/models/decorators-private.d.ts +16 -0
  88. package/lib/esm/contract/models/decorators-private.js +81 -0
  89. package/lib/esm/contract/models/decorators-private.js.map +1 -0
  90. package/lib/esm/contract/models/decorators.d.ts +6 -1
  91. package/lib/esm/contract/models/decorators.js +30 -2
  92. package/lib/esm/contract/models/decorators.js.map +1 -1
  93. package/lib/esm/contracts/ContractAdapter.d.ts +5 -29
  94. package/lib/esm/contracts/ContractAdapter.js +262 -412
  95. package/lib/esm/contracts/ContractAdapter.js.map +1 -1
  96. package/lib/esm/contracts/ContractContext.d.ts +13 -8
  97. package/lib/esm/contracts/ContractContext.js +41 -13
  98. package/lib/esm/contracts/ContractContext.js.map +1 -1
  99. package/lib/esm/contracts/FabricContractRepository.d.ts +6 -0
  100. package/lib/esm/contracts/FabricContractRepository.js +70 -0
  101. package/lib/esm/contracts/FabricContractRepository.js.map +1 -1
  102. package/lib/esm/contracts/FabricContractSequence.js +9 -25
  103. package/lib/esm/contracts/FabricContractSequence.js.map +1 -1
  104. package/lib/esm/contracts/FabricContractStatement.d.ts +5 -2
  105. package/lib/esm/contracts/FabricContractStatement.js +135 -0
  106. package/lib/esm/contracts/FabricContractStatement.js.map +1 -1
  107. package/lib/esm/contracts/crud/crud-contract.d.ts +6 -5
  108. package/lib/esm/contracts/crud/crud-contract.js +42 -17
  109. package/lib/esm/contracts/crud/crud-contract.js.map +1 -1
  110. package/lib/esm/contracts/types.d.ts +9 -2
  111. package/lib/esm/shared/decorators.d.ts +8 -0
  112. package/lib/esm/shared/decorators.js +90 -83
  113. package/lib/esm/shared/decorators.js.map +1 -1
  114. package/lib/esm/shared/overrides/overrides.js +7 -6
  115. package/lib/esm/shared/overrides/overrides.js.map +1 -1
  116. package/lib/esm/shared/types.d.ts +3 -2
  117. package/lib/esm/version.d.ts +1 -1
  118. package/lib/esm/version.js +1 -1
  119. package/lib/shared/decorators.cjs +91 -82
  120. package/lib/shared/decorators.d.ts +8 -0
  121. package/lib/shared/decorators.js.map +1 -1
  122. package/lib/shared/overrides/overrides.cjs +7 -6
  123. package/lib/shared/overrides/overrides.js.map +1 -1
  124. package/lib/shared/types.d.ts +3 -2
  125. package/lib/version.cjs +1 -1
  126. package/lib/version.d.ts +1 -1
  127. package/package.json +3 -3
  128. package/lib/contracts/ContractPrivateDataAdapter.cjs +0 -426
  129. package/lib/contracts/ContractPrivateDataAdapter.d.ts +0 -0
  130. package/lib/contracts/ContractPrivateDataAdapter.js.map +0 -1
  131. package/lib/contracts/FabricConstruction.cjs +0 -441
  132. package/lib/contracts/FabricConstruction.d.ts +0 -305
  133. package/lib/contracts/FabricConstruction.js.map +0 -1
  134. package/lib/contracts/private-data.cjs +0 -204
  135. package/lib/contracts/private-data.d.ts +0 -0
  136. package/lib/contracts/private-data.js.map +0 -1
  137. package/lib/esm/contracts/ContractPrivateDataAdapter.d.ts +0 -0
  138. package/lib/esm/contracts/ContractPrivateDataAdapter.js +0 -426
  139. package/lib/esm/contracts/ContractPrivateDataAdapter.js.map +0 -1
  140. package/lib/esm/contracts/FabricConstruction.d.ts +0 -305
  141. package/lib/esm/contracts/FabricConstruction.js +0 -433
  142. package/lib/esm/contracts/FabricConstruction.js.map +0 -1
  143. package/lib/esm/contracts/private-data.d.ts +0 -0
  144. package/lib/esm/contracts/private-data.js +0 -204
  145. package/lib/esm/contracts/private-data.js.map +0 -1
@@ -17,7 +17,6 @@ const SimpleDeterministicSerializer_1 = require("./../shared/SimpleDeterministic
17
17
  const decoration_1 = require("@decaf-ts/decoration");
18
18
  const FabricContractPaginator_1 = require("./FabricContractPaginator.cjs");
19
19
  const errors_1 = require("./../shared/errors.cjs");
20
- const MIRROR_SKIP_FLAG_PREFIX = "mirror:skip:";
21
20
  /**
22
21
  * @description Sets the creator or updater field in a model based on the user in the context
23
22
  * @summary Callback function used in decorators to automatically set the created_by or updated_by fields
@@ -100,12 +99,6 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
100
99
  */
101
100
  static { this.textDecoder = new TextDecoder("utf8"); }
102
101
  static { this.serializer = new SimpleDeterministicSerializer_1.SimpleDeterministicSerializer(); }
103
- setSequenceSegregation(seqName, fullySegregated, collections) {
104
- this._sequenceSegregation.set(seqName, { fullySegregated, collections });
105
- }
106
- getSequenceSegregation(seqName) {
107
- return this._sequenceSegregation.get(seqName);
108
- }
109
102
  /**
110
103
  * @description Context constructor for this adapter
111
104
  * @summary Overrides the base Context constructor with FabricContractContext
@@ -136,17 +129,18 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
136
129
  */
137
130
  constructor(scope, alias) {
138
131
  super(scope, constants_1.FabricFlavour, alias);
139
- /**
140
- * @description Stores segregation metadata per sequence name
141
- * @summary Needed because the Sequence creates its own context (via logCtx),
142
- * losing flags set by extractSegregatedCollections on the handler context.
143
- * The adapter persists across operations, making it a reliable store.
144
- */
145
- this._sequenceSegregation = new Map();
146
132
  }
147
133
  for(config, ...args) {
148
134
  return super.for(config, ...args);
149
135
  }
136
+ getModelDefaults(clazz) {
137
+ const m = new clazz();
138
+ return (decoration_1.Metadata.properties(clazz) || []).reduce((acc, p) => {
139
+ if (typeof m[p] !== "undefined")
140
+ acc[p] = m[p];
141
+ return acc;
142
+ }, {});
143
+ }
150
144
  /**
151
145
  * @description Creates a record in the state database
152
146
  * @summary Serializes a model and stores it in the Fabric state database
@@ -164,6 +158,10 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
164
158
  const tableName = decorator_validation_1.Model.tableName(clazz);
165
159
  const composedKey = ctx.stub.createCompositeKey(tableName, [String(id)]);
166
160
  const isMirror = ctx.getOrUndefined("mirror");
161
+ const segregated = isMirror
162
+ ? ctx.getOrUndefined("segregated")
163
+ : undefined;
164
+ const fullySegregated = ctx.isFullySegregated && !segregated;
167
165
  if (!isMirror) {
168
166
  let existing;
169
167
  try {
@@ -179,30 +177,45 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
179
177
  throw new db_decorators_1.ConflictError(`record with id ${id} in table ${tableName} already exists`);
180
178
  }
181
179
  try {
182
- const sanitizedModel = this.normalizeForPublic(clazz, model, ctx);
183
180
  log.info(`adding entry to ${tableName} table with pk ${id}`);
184
- if (ctx.isFullySegregated) {
185
- await this.flushSegregatedWrites(ctx, composedKey);
186
- return sanitizedModel;
181
+ if (segregated) {
182
+ // Mirror write: route the full model to the mirror collection via forPrivate
183
+ model = await this.forPrivate(segregated).putState(composedKey, model, ctx);
184
+ }
185
+ else {
186
+ const defaults = this.getModelDefaults(clazz);
187
+ // handle public data if not fully segregated
188
+ if (!fullySegregated) {
189
+ if (Object.keys(model).filter((k) => {
190
+ if (k === for_couchdb_1.CouchDBKeys.TABLE)
191
+ return false;
192
+ return !(defaults &&
193
+ k in defaults &&
194
+ defaults[k] === model[k]);
195
+ }).length)
196
+ model = await this.putState(composedKey, model, ctx);
197
+ }
198
+ // handle segregated writes
199
+ const data = ctx.getFromChildren("segregatedData");
200
+ if (data) {
201
+ for (const collection in data) {
202
+ Object.assign(model, await this.forPrivate(collection).putState(composedKey, data[collection][id], ctx));
203
+ }
204
+ }
187
205
  }
188
- model = await this.putState(composedKey, sanitizedModel, ctx);
189
206
  }
190
207
  catch (e) {
191
208
  throw this.parseError(e);
192
209
  }
193
210
  return model;
194
211
  }
195
- normalizeForPublic(clazz, model, ctx) {
196
- if (model &&
197
- typeof model === "object" &&
198
- Object.prototype.hasOwnProperty.call(model, for_couchdb_1.CouchDBKeys.TABLE)) {
199
- return model;
200
- }
201
- const instance = decorator_validation_1.Model.isModel(model)
202
- ? model
203
- : decorator_validation_1.Model.build(model, clazz.name);
204
- const prepared = this.prepare(instance, ctx);
205
- return prepared.record;
212
+ async createAll(tableName, id, model, ...args) {
213
+ if (id.length !== model.length)
214
+ throw new db_decorators_1.InternalError("Ids and models must have the same length");
215
+ const { log, ctxArgs } = this.logCtx(args, this.createAll);
216
+ const tableLabel = decorator_validation_1.Model.tableName(tableName);
217
+ log.debug(`Creating ${id.length} entries ${tableLabel} table`);
218
+ return Promise.all(id.map((i, count) => this.create(tableName, i, model[count], ...ctxArgs)));
206
219
  }
207
220
  /**
208
221
  * @description Reads a record from the state database
@@ -219,22 +232,18 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
219
232
  const composedKey = ctx.stub.createCompositeKey(tableName, [String(id)]);
220
233
  let model;
221
234
  try {
222
- model = await this.readState(composedKey, ctx);
235
+ model = ctx.isFullySegregated
236
+ ? {}
237
+ : await this.readState(composedKey, ctx);
223
238
  }
224
239
  catch (e) {
225
- const fabricCtx = ctx;
226
- if (e instanceof db_decorators_1.NotFoundError &&
227
- (fabricCtx.isFullySegregated ||
228
- fabricCtx.getReadCollections().length ||
229
- !!ctx.getOrUndefined("segregated") ||
230
- !!ctx.getOrUndefined("mirror"))) {
231
- model = {};
232
- }
233
- else {
234
- throw this.parseError(e);
235
- }
240
+ throw this.parseError(e);
241
+ }
242
+ const collections = ctx.getReadCollections();
243
+ if (collections && collections.length) {
244
+ for (const col of collections)
245
+ Object.assign(model, await this.forPrivate(col).readState(composedKey, ctx));
236
246
  }
237
- model = await this.mergeSegregatedReads(ctx, composedKey, model);
238
247
  return model;
239
248
  }
240
249
  /**
@@ -250,16 +259,38 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
250
259
  async update(clazz, id, model, ...args) {
251
260
  const { ctx, log } = this.logCtx(args, this.update);
252
261
  this.enforceMirrorAuthorization(clazz, ctx);
262
+ log.info(`in ADAPTER update with args ${args}`);
253
263
  const tableName = decorator_validation_1.Model.tableName(clazz);
254
264
  const composedKey = ctx.stub.createCompositeKey(tableName, [String(id)]);
265
+ const isMirror = ctx.getOrUndefined("mirror");
266
+ const segregated = isMirror
267
+ ? ctx.getOrUndefined("segregated")
268
+ : undefined;
255
269
  try {
256
- log.verbose(`updating entry to ${tableName} table with pk ${id}`);
257
- const sanitizedModel = this.normalizeForPublic(clazz, model, ctx);
258
- if (ctx.isFullySegregated) {
259
- await this.flushSegregatedWrites(ctx, composedKey);
260
- return sanitizedModel;
270
+ log.info(`updating entry in ${tableName} table with pk ${id}`);
271
+ if (segregated) {
272
+ // Mirror/segregated write: route the full model to the private collection
273
+ model = await this.forPrivate(segregated).putState(composedKey, model, ctx);
274
+ }
275
+ else {
276
+ const defaults = this.getModelDefaults(clazz);
277
+ // handle public data
278
+ if (Object.keys(model).filter((k) => {
279
+ if (k === for_couchdb_1.CouchDBKeys.TABLE)
280
+ return false;
281
+ return !(defaults &&
282
+ k in defaults &&
283
+ defaults[k] === model[k]);
284
+ }).length)
285
+ model = await this.putState(composedKey, model, ctx);
286
+ // handle segregated writes
287
+ const data = ctx.getFromChildren("segregatedData");
288
+ if (data) {
289
+ for (const collection in data) {
290
+ Object.assign(model, await this.forPrivate(collection).putState(composedKey, data[collection][id], ctx));
291
+ }
292
+ }
261
293
  }
262
- model = await this.putState(composedKey, sanitizedModel, ctx);
263
294
  }
264
295
  catch (e) {
265
296
  throw this.parseError(e);
@@ -275,40 +306,48 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
275
306
  * @return {Promise<Record<string, any>>} Promise resolving to the deleted record
276
307
  */
277
308
  async delete(clazz, id, ...args) {
278
- const { ctx, log, ctxArgs } = this.logCtx(args, this.delete);
309
+ const { ctx } = this.logCtx(args, this.delete);
279
310
  this.enforceMirrorAuthorization(clazz, ctx);
280
311
  const tableName = decorator_validation_1.Model.tableName(clazz);
281
- const pkProp = decorator_validation_1.Model.pk(clazz);
312
+ const composedKey = ctx.stub.createCompositeKey(tableName, [String(id)]);
282
313
  const isMirror = ctx.getOrUndefined("mirror");
314
+ const segregated = isMirror
315
+ ? ctx.getOrUndefined("segregated")
316
+ : undefined;
283
317
  let model;
284
- let shouldDeletePublicState = false;
285
- try {
286
- const composedKey = ctx.stub.createCompositeKey(tableName, [String(id)]);
287
- if (!isMirror) {
288
- model = await this.read(clazz, id, ...ctxArgs);
289
- shouldDeletePublicState = this.hasPublicState(model, clazz);
290
- }
291
- else {
292
- model = { [pkProp]: id };
318
+ if (segregated) {
319
+ // Mirror/segregated delete: route through forPrivate
320
+ try {
321
+ model = await this.forPrivate(segregated).readState(composedKey, ctx);
322
+ await this.forPrivate(segregated).deleteState(composedKey, ctx);
293
323
  }
294
- log.verbose(`deleting entry with pk ${id} from ${tableName} table`);
295
- if (shouldDeletePublicState) {
296
- await this.deleteState(composedKey, ctx);
324
+ catch (e) {
325
+ throw this.parseError(e);
297
326
  }
298
- await this.deleteSegregatedCollections(ctx, composedKey);
299
327
  }
300
- catch (e) {
301
- throw this.parseError(e);
328
+ else {
329
+ try {
330
+ model = ctx.isFullySegregated
331
+ ? {}
332
+ : await this.readState(composedKey, ctx);
333
+ if (!ctx.isFullySegregated)
334
+ await this.deleteState(composedKey, ctx);
335
+ }
336
+ catch (e) {
337
+ throw this.parseError(e);
338
+ }
339
+ const collections = ctx.getReadCollections();
340
+ if (collections && collections.length) {
341
+ for (const col of collections) {
342
+ Object.assign(model, await this.forPrivate(col).readState(composedKey, ctx));
343
+ await this.forPrivate(col).deleteState(composedKey, ctx);
344
+ }
345
+ }
302
346
  }
303
347
  return model;
304
348
  }
305
349
  async deleteState(id, context) {
306
- const { ctx } = this.logCtx([context], this.deleteState);
307
- const collection = ctx.getOrUndefined("segregated");
308
- if (collection)
309
- await ctx.stub.deletePrivateData(collection, id);
310
- else
311
- await ctx.stub.deleteState(id);
350
+ await context.stub.deleteState(id);
312
351
  }
313
352
  forPrivate(collection) {
314
353
  const toOverride = [
@@ -353,55 +392,62 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
353
392
  }
354
393
  case "queryResult": {
355
394
  const [stub, rawInput] = argsList;
356
- return stub.getPrivateDataQueryResult(collection, rawInput);
395
+ return stub.getPrivateDataQueryResult(collection, JSON.stringify(rawInput));
357
396
  }
358
397
  case "queryResultPaginated": {
359
- const [stub, rawInput, limit, skip] = argsList;
360
- const iterator = await stub.getPrivateDataQueryResult(collection, rawInput);
398
+ const [stub, rawInput, limit, skip, bookmark] = argsList;
399
+ const iterator = await stub.getPrivateDataQueryResult(collection, JSON.stringify(rawInput));
361
400
  const results = [];
362
401
  let count = 0;
363
- let reachedBookmark = skip ? false : true;
402
+ const skipKey = bookmark || skip;
403
+ let reachedBookmark = skipKey ? false : true;
364
404
  let lastKey = null;
365
405
  while (true) {
366
406
  const res = await iterator.next();
367
407
  if (res.value && res.value.value.toString()) {
368
408
  const recordKey = res.value.key;
369
409
  const recordValue = res.value.value.toString("utf8");
370
- // If we have a skip, skip until we reach it
410
+ // If we have a bookmark/skip, skip until we pass it
371
411
  if (!reachedBookmark) {
372
- if (recordKey === skip?.toString()) {
412
+ if (recordKey === skipKey?.toString()) {
373
413
  reachedBookmark = true;
374
414
  }
375
415
  continue;
376
416
  }
377
417
  results.push({
378
- Key: recordKey,
379
- Record: JSON.parse(recordValue),
418
+ key: recordKey,
419
+ value: Buffer.from(recordValue),
380
420
  });
381
421
  lastKey = recordKey;
382
422
  count++;
383
423
  if (count >= limit) {
384
424
  await iterator.close();
385
- return {
386
- iterator: results,
387
- metadata: {
388
- fetchedRecordsCount: results.length,
389
- bookmark: lastKey,
390
- },
391
- };
425
+ break;
392
426
  }
393
427
  }
394
428
  if (res.done) {
395
429
  await iterator.close();
396
- return {
397
- iterator: results,
398
- metadata: {
399
- fetchedRecordsCount: results.length,
400
- bookmark: "",
401
- },
402
- };
430
+ break;
403
431
  }
404
432
  }
433
+ // Wrap results in an async iterator compatible with resultIterator()
434
+ let idx = 0;
435
+ const arrayIterator = {
436
+ async next() {
437
+ if (idx < results.length) {
438
+ return { value: results[idx++], done: false };
439
+ }
440
+ return { value: undefined, done: true };
441
+ },
442
+ async close() { },
443
+ };
444
+ return {
445
+ iterator: arrayIterator,
446
+ metadata: {
447
+ fetchedRecordsCount: results.length,
448
+ bookmark: count >= limit ? lastKey || "" : "",
449
+ },
450
+ };
405
451
  }
406
452
  default:
407
453
  throw new db_decorators_1.InternalError(`Unsupported method override ${String(prop)}`);
@@ -413,156 +459,22 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
413
459
  }
414
460
  async putState(id, model, ctx) {
415
461
  let data;
416
- const { log } = this.logCtx([ctx], this.putState);
417
462
  try {
418
463
  data = Buffer.from(FabricContractAdapter.serializer.serialize(model, false));
419
464
  }
420
465
  catch (e) {
421
466
  throw new db_decorators_1.SerializationError(`Failed to serialize record with id ${id}: ${e}`);
422
467
  }
423
- const collection = ctx.getOrUndefined("segregated");
424
- if (collection) {
425
- if (ctx.getOrUndefined("mirror")) {
426
- const cacheKey = `segregatedRecord:${collection}:${id.toString()}`;
427
- let existingRecord = ctx.cache.get(cacheKey);
428
- ctx.cache.remove(cacheKey);
429
- if (!existingRecord) {
430
- const existing = await ctx.stub.getPrivateData(collection, id.toString());
431
- if (existing) {
432
- try {
433
- existingRecord = FabricContractAdapter.serializer.deserialize(existing.toString());
434
- }
435
- catch {
436
- existingRecord = undefined;
437
- }
438
- }
439
- }
440
- if (existingRecord) {
441
- const merged = Object.assign({}, existingRecord, model);
442
- data = Buffer.from(FabricContractAdapter.serializer.serialize(merged, false));
443
- }
444
- }
445
- await ctx.stub.putPrivateData(collection, id.toString(), data);
446
- }
447
- else {
448
- await ctx.stub.putState(id.toString(), data);
449
- await this.flushSegregatedWrites(ctx, id);
450
- }
451
- log.silly(`state stored${collection ? ` in ${collection} collection` : ""} under id ${id}`);
452
- return model;
453
- }
454
- async flushSegregatedWrites(ctx, compositeKey) {
455
- const writeCollections = ctx.getWriteCollections();
456
- if (!writeCollections.length)
457
- return;
458
- const writes = ctx._segregateWrite;
459
- if (!writes)
460
- return;
461
- for (const collection of writeCollections) {
462
- const entries = writes[collection];
463
- if (!entries || !entries.length)
464
- continue;
465
- const record = this.buildSegregatedRecord(entries, collection);
466
- if (!record || !Object.keys(record).length)
467
- continue;
468
- const cacheKey = `segregatedRecord:${collection}:${compositeKey}`;
469
- ctx.cache.put(cacheKey, record);
470
- const privateCtx = ctx.override({
471
- segregated: collection,
472
- });
473
- await this.putState(compositeKey, record, privateCtx);
474
- }
475
- ctx.cache.remove("segregateWrite");
476
- }
477
- buildSegregatedRecord(entries, collection) {
478
- if (!entries || !entries.length)
479
- return undefined;
480
- const firstModel = entries.find((entry) => !!entry.model)?.model;
481
- if (!firstModel)
482
- return undefined;
483
- const clazz = firstModel.constructor;
484
- const pkProp = decorator_validation_1.Model.pk(clazz);
485
- const keys = new Set();
486
- entries.forEach((entry) => entry.keys.forEach((key) => keys.add(key)));
487
- const metadataFields = this.getFieldsForCollection(firstModel, collection);
488
- metadataFields.forEach((key) => keys.add(key));
489
- if (pkProp)
490
- keys.add(pkProp);
491
- const record = {};
492
- keys.forEach((key) => {
493
- const value = entries
494
- .map((entry) => entry.model[key])
495
- .find((val) => typeof val !== "undefined");
496
- if (typeof value === "undefined")
497
- return;
498
- const mappedProp = decorator_validation_1.Model.columnName(clazz, key);
499
- if (this.isReserved(mappedProp))
500
- throw new db_decorators_1.InternalError(`Property name ${mappedProp} is reserved`);
501
- record[mappedProp] =
502
- value instanceof Date ? new Date(value) : value;
503
- });
504
- return record;
505
- }
506
- async mergeSegregatedReads(ctx, id, model) {
507
- // Use getReadCollections which reads from the private _segregateRead property
508
- const reads = ctx.getReadCollections();
509
- if (!reads?.length)
510
- return model;
511
- for (const collection of reads) {
512
- const skipFlagKey = `${MIRROR_SKIP_FLAG_PREFIX}${collection}`;
513
- if (ctx.getOrUndefined(skipFlagKey))
514
- continue;
515
- const privateRecord = await this.readPrivateRecord(ctx, collection, id);
516
- if (!privateRecord)
517
- continue;
518
- Object.entries(privateRecord).forEach(([key, value]) => {
519
- if (typeof value === "undefined")
520
- return;
521
- model[key] = value;
522
- });
523
- }
468
+ await ctx.stub.putState(id.toString(), data);
524
469
  return model;
525
470
  }
526
- async readPrivateRecord(ctx, collection, id) {
527
- const data = await ctx.stub.getPrivateData(collection, id);
528
- if (!data)
529
- return undefined;
530
- const text = data.toString();
531
- if (!text)
532
- return undefined;
533
- try {
534
- return FabricContractAdapter.serializer.deserialize(text);
535
- }
536
- catch {
537
- return undefined;
538
- }
539
- }
540
- async deleteSegregatedCollections(ctx, id) {
541
- // Use getReadCollections which reads from the private _segregateRead property
542
- const reads = ctx.getReadCollections();
543
- if (!reads?.length)
544
- return;
545
- for (const collection of reads) {
546
- try {
547
- await ctx.stub.deletePrivateData(collection, id);
548
- }
549
- catch {
550
- // ignore missing private data
551
- }
552
- }
553
- }
554
471
  async readState(id, ctx) {
555
472
  let result;
556
473
  const { log } = this.logCtx([ctx], this.readState);
557
- let res;
558
- const collection = ctx.get("segregated");
559
- if (collection)
560
- res = (await ctx.stub.getPrivateData(collection, id.toString())).toString();
561
- else
562
- res = (await ctx.stub.getState(id.toString())).toString();
474
+ const res = (await ctx.stub.getState(id.toString())).toString();
563
475
  if (!res)
564
- throw new db_decorators_1.NotFoundError(`Record with id ${id}${collection ? ` in ${collection} collection` : ""} not found`);
565
- log.silly(`state retrieved from${collection ? ` ${collection} collection` : ""} under id ${id}`);
476
+ throw new db_decorators_1.NotFoundError(`Record with id ${id} not found`);
477
+ log.silly(`state retrieved under id ${id}`);
566
478
  try {
567
479
  result = FabricContractAdapter.serializer.deserialize(res.toString());
568
480
  }
@@ -571,84 +483,15 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
571
483
  }
572
484
  return result;
573
485
  }
574
- async queryResult(stub, rawInput, ...args) {
575
- const { ctx } = this.logCtx(args, this.queryResult);
576
- let res;
577
- const collection = ctx.get("segregated");
578
- if (collection)
579
- res = await ctx.stub.getPrivateDataQueryResult(collection, JSON.stringify(rawInput));
580
- else
581
- res = await stub.getQueryResult(JSON.stringify(rawInput));
582
- return res;
583
- }
584
- createRowsIterator(rows) {
585
- let index = 0;
586
- return {
587
- // @ts-expect-error typeing of iterator?
588
- async next() {
589
- if (index < rows.length) {
590
- const row = rows[index++];
591
- return {
592
- value: { key: row.key, value: row.value },
593
- done: false,
594
- };
595
- }
596
- return { done: true };
597
- },
598
- async close() {
599
- // noop
600
- },
601
- };
602
- }
603
- async queryResultPaginated(stub, rawInput, limit = 250, page, bookmark, ...args) {
604
- const { ctx } = this.logCtx(args, this.readState);
605
- let res;
606
- const collection = ctx.get("segregated");
607
- if (collection) {
608
- const clonedInput = JSON.parse(JSON.stringify(rawInput));
609
- clonedInput.selector = clonedInput.selector || {};
610
- if (bookmark)
611
- clonedInput.selector._id = { $gt: bookmark.toString() };
612
- const limitValue = typeof limit === "number" && limit > 0 ? limit : Number.MAX_VALUE;
613
- const iterator = await stub.getPrivateDataQueryResult(collection, JSON.stringify(clonedInput));
614
- const rows = [];
615
- let lastKey = "";
616
- while (rows.length < limitValue) {
617
- const resRow = await iterator.next();
618
- if (resRow.done)
619
- break;
620
- if (resRow.value && resRow.value.value) {
621
- rows.push({
622
- key: resRow.value.key,
623
- value: resRow.value.value,
624
- });
625
- lastKey = resRow.value.key;
626
- }
627
- }
628
- await iterator.close();
629
- res = {
630
- iterator: this.createRowsIterator(rows),
631
- metadata: {
632
- fetchedRecordsCount: rows.length,
633
- bookmark: rows.length ? lastKey : "",
634
- },
635
- };
636
- }
637
- else
638
- res = await stub.getQueryResultWithPagination(JSON.stringify(rawInput), limit, bookmark?.toString());
639
- return res;
486
+ async queryResult(stub, rawInput,
487
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
488
+ ...args) {
489
+ return stub.getQueryResult(JSON.stringify(rawInput));
640
490
  }
641
- mergeModels(results) {
642
- const extract = (model) => Object.entries(model).reduce((accum, [key, val]) => {
643
- if (typeof val !== "undefined")
644
- accum[key] = val;
645
- return accum;
646
- }, {});
647
- let finalModel = results.pop();
648
- for (const res of results) {
649
- finalModel = Object.assign({}, extract(finalModel), extract(res));
650
- }
651
- return finalModel;
491
+ async queryResultPaginated(stub, rawInput, limit = 250, page, bookmark,
492
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
493
+ ...args) {
494
+ return stub.getQueryResultWithPagination(JSON.stringify(rawInput), limit, bookmark?.toString());
652
495
  }
653
496
  /**
654
497
  * @description Decodes binary data to string
@@ -673,6 +516,7 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
673
516
  let baseFlags = Object.assign({
674
517
  segregated: false,
675
518
  rebuildWithTransient: false,
519
+ fullySegregated: false,
676
520
  }, flags);
677
521
  const stubFromFlags = flags.stub || flags.stub;
678
522
  const identityFromFlags = flags.identity ||
@@ -797,15 +641,16 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
797
641
  * FabricContractAdapter-->>Caller: results
798
642
  */
799
643
  async raw(rawInput, docsOnly = true, ...args) {
800
- const { log, ctx } = this.logCtx(args, this.raw);
644
+ const { log, ctx, ctxArgs } = this.logCtx(args, this.raw);
645
+ const enableSegregates = !args.length || args[0] !== true;
801
646
  const { skip, limit } = rawInput;
802
647
  let iterator;
803
- const resp = { docs: [], bookmark: undefined };
648
+ let resp = { docs: [], bookmark: undefined };
804
649
  if (limit || skip) {
805
650
  delete rawInput["limit"];
806
651
  delete rawInput["skip"];
807
652
  log.debug(`Retrieving paginated iterator: limit: ${limit}/ skip: ${skip}`);
808
- const response = (await this.queryResultPaginated(ctx.stub, rawInput, limit || Number.MAX_VALUE, skip?.toString(), rawInput["bookmark"], ctx));
653
+ const response = (await this.queryResultPaginated(ctx.stub, rawInput, limit || Number.MAX_VALUE, skip?.toString(), rawInput["bookmark"], ...[ctx]));
809
654
  resp.bookmark = response.metadata.bookmark;
810
655
  iterator = response.iterator;
811
656
  }
@@ -816,8 +661,30 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
816
661
  log.debug("Iterator acquired");
817
662
  resp.docs = (await this.resultIterator(log, iterator));
818
663
  log.debug(`returning ${Array.isArray(resp.docs) ? resp.docs.length : 1} results`);
819
- if (docsOnly)
664
+ const collections = enableSegregates ? ctx.getReadCollections() : undefined;
665
+ const segregated = [];
666
+ if (collections && collections.length) {
667
+ // Restore limit/skip for segregated queries (they were removed above)
668
+ const segregatedInput = { ...rawInput };
669
+ if (limit)
670
+ segregatedInput.limit = limit;
671
+ if (skip)
672
+ segregatedInput.skip = skip;
673
+ for (const collection of collections) {
674
+ segregated.push(await this.forPrivate(collection).raw(segregatedInput, false, true, ...ctxArgs));
675
+ }
676
+ // choose the response with the most results
677
+ resp = segregated.reduce((acc, curr) => {
678
+ if (!acc)
679
+ return curr;
680
+ if (curr.docs && curr.docs.length >= acc?.docs.length)
681
+ return curr;
682
+ return acc;
683
+ }, resp);
684
+ }
685
+ if (docsOnly) {
820
686
  return resp.docs;
687
+ }
821
688
  return resp;
822
689
  }
823
690
  async view(
@@ -834,14 +701,6 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
834
701
  Statement() {
835
702
  return new FabricContractStatement_1.FabricStatement(this);
836
703
  }
837
- async createAll(tableName, id, model, ...args) {
838
- if (id.length !== model.length)
839
- throw new db_decorators_1.InternalError("Ids and models must have the same length");
840
- const { log, ctxArgs } = this.logCtx(args, this.createAll);
841
- const tableLabel = decorator_validation_1.Model.tableName(tableName);
842
- log.debug(`Creating ${id.length} entries ${tableLabel} table`);
843
- return Promise.all(id.map((i, count) => this.create(tableName, i, model[count], ...ctxArgs)));
844
- }
845
704
  async updateAll(tableName, id, model, ...args) {
846
705
  if (id.length !== model.length)
847
706
  throw new db_decorators_1.InternalError("Ids and models must have the same length");
@@ -858,115 +717,98 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
858
717
  */
859
718
  prepare(model, ...args) {
860
719
  const { log, ctx } = this.logCtx(args, this.prepare);
720
+ const split = decorator_validation_1.Model.segregate(model);
861
721
  const tableName = decorator_validation_1.Model.tableName(model.constructor);
862
722
  const pk = decorator_validation_1.Model.pk(model.constructor);
863
- const collection = ctx.getOrUndefined("segregated");
723
+ const id = model[pk];
864
724
  const isMirror = ctx.getOrUndefined("mirror");
865
- let entries;
866
- if (collection && isMirror) {
867
- // MIRROR mode: keep ALL properties (full model copy)
868
- entries = Object.keys(model)
869
- .map((key) => [key, model[key]])
870
- .filter(([, val]) => typeof val !== "undefined");
871
- }
872
- else if (collection) {
873
- // SEGREGATED mode: keep only properties decorated for this collection + pk
874
- const collectionFields = this.getFieldsForCollection(model, collection);
875
- entries = [...new Set([pk, ...collectionFields])]
876
- .map((key) => [key, model[key]])
877
- .filter(([, val]) => typeof val !== "undefined");
878
- }
879
- else {
880
- // NORMAL mode: strip transient (current behavior)
881
- const split = decorator_validation_1.Model.segregate(model);
882
- entries = Object.entries(split.model).filter(([, val]) => typeof val !== "undefined");
883
- }
884
- const record = entries.reduce((accum, [key, val]) => {
885
- const mappedProp = decorator_validation_1.Model.columnName(model, key);
886
- if (this.isReserved(mappedProp))
887
- throw new db_decorators_1.InternalError(`Property name ${mappedProp} is reserved`);
888
- val = val instanceof Date ? new Date(val) : val;
889
- accum[mappedProp] = val;
890
- return accum;
891
- }, {});
892
- // Add table identifier
893
- record[for_couchdb_1.CouchDBKeys.TABLE] = tableName;
725
+ const mapToRecord = function (obj, keysOverride) {
726
+ if (keysOverride)
727
+ keysOverride = [...new Set([...keysOverride, pk])];
728
+ const result = Object.entries(obj).reduce((accum, [key, val]) => {
729
+ if (typeof val === "undefined")
730
+ return accum;
731
+ if (keysOverride && !keysOverride.includes(key))
732
+ return accum;
733
+ const mappedProp = decorator_validation_1.Model.columnName(model, key);
734
+ if (this.isReserved(mappedProp))
735
+ throw new db_decorators_1.InternalError(`Property name ${mappedProp} is reserved`);
736
+ val = val instanceof Date ? new Date(val) : val;
737
+ accum[mappedProp] = val;
738
+ return accum;
739
+ }, {});
740
+ if (Object.keys(result).filter((k) => Boolean(result[k])).length) {
741
+ // Add table identifier
742
+ result[for_couchdb_1.CouchDBKeys.TABLE] = tableName;
743
+ }
744
+ return result;
745
+ }.bind(this);
894
746
  log.silly(`Preparing record for ${tableName} table with pk ${model[pk]}`);
747
+ const segregatedWriteKeys = ctx.getSegregatedWrites();
748
+ const segregatedWrites = {};
749
+ if (segregatedWriteKeys) {
750
+ for (const collection in segregatedWriteKeys) {
751
+ segregatedWrites[collection] = segregatedWrites[collection] || {};
752
+ segregatedWrites[collection][id] = mapToRecord(ctx.getOrUndefined("forceSegregateWrite")
753
+ ? split.model
754
+ : split.transient, segregatedWriteKeys[collection]);
755
+ }
756
+ }
757
+ // In mirror mode, the record should contain ALL model properties (full copy)
758
+ const record = isMirror ? mapToRecord(model) : mapToRecord(split.model);
895
759
  return {
896
760
  record,
897
761
  id: model[pk],
898
- transient: collection ? undefined : decorator_validation_1.Model.segregate(model).transient,
762
+ transient: !isMirror && split.transient && Object.keys(split.transient).length
763
+ ? mapToRecord(split.transient)
764
+ : undefined,
765
+ segregated: isMirror ? undefined : segregatedWrites,
899
766
  };
900
767
  }
901
- /**
902
- * @description Gets the property names that belong to a specific private/shared collection
903
- * @summary Looks up per-property metadata set by @privateData/@sharedData decorators
904
- * to determine which properties are decorated for the given collection name.
905
- */
906
- getFieldsForCollection(model, collection) {
907
- const constr = model.constructor;
908
- const properties = decoration_1.Metadata.validatableProperties(constr);
909
- if (!properties)
910
- return [];
911
- return properties.filter((prop) => {
912
- const privateKey = decoration_1.Metadata.key(constants_1.FabricModelKeys.PRIVATE, prop);
913
- const privateMeta = decoration_1.Metadata.get(constr, privateKey);
914
- if (privateMeta?.collections?.includes(collection))
915
- return true;
916
- const sharedKey = decoration_1.Metadata.key(constants_1.FabricModelKeys.SHARED, prop);
917
- const sharedMeta = decoration_1.Metadata.get(constr, sharedKey);
918
- if (sharedMeta?.collections?.includes(collection))
919
- return true;
920
- return false;
921
- });
922
- }
923
768
  revert(obj, clazz, id, transient, ...args) {
924
769
  const { log, ctx } = this.logCtx(args, this.revert);
925
770
  const ob = {};
926
771
  const pk = decorator_validation_1.Model.pk(clazz);
772
+ const pkProps = decorator_validation_1.Model.pkProps(clazz);
773
+ if (pkProps?.type === Number && typeof id === "string") {
774
+ id = Number(id);
775
+ }
927
776
  ob[pk] = id;
928
- const m = (typeof clazz === "string" ? decorator_validation_1.Model.build(ob, clazz) : new clazz(ob));
929
- log.silly(`Rebuilding model ${m.constructor.name} id ${id}`);
930
- const result = Object.keys(m).reduce((accum, key) => {
931
- accum[key] =
932
- obj[decorator_validation_1.Model.columnName(accum, key)];
933
- return accum;
934
- }, m);
935
- if (transient &&
936
- this.shouldRebuildWithTransient(ctx, ctx.getOrUndefined("operation"))) {
937
- log.debug(`re-adding transient properties: ${Object.keys(transient).join(", ")}`);
938
- Object.entries(transient).forEach(([key, val]) => {
939
- if (key in result && result[key] !== undefined)
940
- log.warn(`overwriting existing ${key}. if this is not a default value, this may pose a problem`);
941
- result[key] = val;
942
- });
777
+ log.silly(`Rebuilding model ${clazz.name} id ${id}`);
778
+ function mapToModel(r) {
779
+ const m = (typeof clazz === "string" ? decorator_validation_1.Model.build(ob, clazz) : new clazz(ob));
780
+ const attributes = decorator_validation_1.Model.getAttributes(clazz);
781
+ const keys = attributes.length ? attributes : Object.keys(m);
782
+ return keys
783
+ .filter((k) => k !== pk)
784
+ .reduce((accum, key) => {
785
+ accum[key] =
786
+ r[decorator_validation_1.Model.columnName(accum, key)];
787
+ return accum;
788
+ }, m);
789
+ }
790
+ let result = mapToModel(obj);
791
+ if (transient && !this.shouldRebuildWithTransient(ctx)) {
792
+ log.debug(`filtering transient properties: ${Object.keys(transient).join(", ")}`);
793
+ result = Object.entries(result).reduce((acc, [key, v]) => {
794
+ if (key === pk || !(key in transient)) {
795
+ acc[key] = v;
796
+ }
797
+ return acc;
798
+ }, new clazz());
943
799
  }
944
800
  return result;
945
801
  }
946
- shouldRebuildWithTransient(ctx, operation) {
802
+ shouldRebuildWithTransient(ctx) {
947
803
  if (!ctx)
948
804
  return false;
949
805
  if (ctx.getOrUndefined("rebuildWithTransient"))
950
806
  return true;
807
+ const operation = ctx.getOrUndefined("operation");
951
808
  if (!operation)
952
- return false;
809
+ return true;
953
810
  const op = operation.toString().toLowerCase();
954
- return (op.includes("read") ||
955
- op.includes("find") ||
956
- op.includes("query") ||
957
- op.includes("statement") ||
958
- op.includes("page"));
959
- }
960
- hasPublicState(model, clazz) {
961
- if (!model)
962
- return false;
963
- const instance = decorator_validation_1.Model.isModel(model)
964
- ? model
965
- : decorator_validation_1.Model.build(model, clazz.name);
966
- const split = decorator_validation_1.Model.segregate(instance);
967
- const pkProp = decorator_validation_1.Model.pk(clazz);
968
- return Object.keys(split.model).some((key) => key !== pkProp &&
969
- typeof split.model[key] !== "undefined");
811
+ return !core_1.TransactionOperationKeys.map((k) => k.toLowerCase()).includes(op);
970
812
  }
971
813
  getContextMsp(context) {
972
814
  const identity = context.get("identity");
@@ -1099,11 +941,19 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
1099
941
  super.decoration();
1100
942
  decoration_1.Decoration.flavouredAs(constants_1.FabricFlavour)
1101
943
  .for(core_1.PersistenceKeys.CREATED_BY)
1102
- .define((0, db_decorators_1.onCreate)(createdByOnFabricCreateUpdate), (0, decoration_1.propMetadata)(core_1.PersistenceKeys.CREATED_BY, {}))
944
+ .define({
945
+ decorator: function createdBy() {
946
+ return (0, decoration_1.apply)((0, db_decorators_1.onCreate)(createdByOnFabricCreateUpdate), (0, decoration_1.propMetadata)(core_1.PersistenceKeys.CREATED_BY, {}));
947
+ },
948
+ })
1103
949
  .apply();
1104
950
  decoration_1.Decoration.flavouredAs(constants_1.FabricFlavour)
1105
951
  .for(core_1.PersistenceKeys.UPDATED_BY)
1106
- .define((0, db_decorators_1.onCreateUpdate)(createdByOnFabricCreateUpdate), (0, decoration_1.propMetadata)(core_1.PersistenceKeys.UPDATED_BY, {}))
952
+ .define({
953
+ decorator: function createdBy() {
954
+ return (0, decoration_1.apply)((0, db_decorators_1.onCreateUpdate)(createdByOnFabricCreateUpdate), (0, decoration_1.propMetadata)(core_1.PersistenceKeys.UPDATED_BY, {}));
955
+ },
956
+ })
1107
957
  .apply();
1108
958
  decoration_1.Decoration.flavouredAs(constants_1.FabricFlavour)
1109
959
  .for(core_1.PersistenceKeys.COLUMN)