@decaf-ts/core 0.8.29 → 0.8.31

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 (66) hide show
  1. package/README.md +1 -1
  2. package/dist/core.cjs +1 -1
  3. package/dist/core.cjs.map +1 -1
  4. package/dist/core.js +1 -1
  5. package/dist/core.js.map +1 -1
  6. package/lib/esm/identity/decorators.js +1 -1
  7. package/lib/esm/identity/decorators.js.map +1 -1
  8. package/lib/esm/index.d.ts +1 -1
  9. package/lib/esm/index.js +1 -1
  10. package/lib/esm/model/SequenceModel.js +2 -1
  11. package/lib/esm/model/SequenceModel.js.map +1 -1
  12. package/lib/esm/model/construction.d.ts +13 -0
  13. package/lib/esm/model/construction.js +286 -1
  14. package/lib/esm/model/construction.js.map +1 -1
  15. package/lib/esm/model/decorators.d.ts +1 -20
  16. package/lib/esm/model/decorators.js +9 -41
  17. package/lib/esm/model/decorators.js.map +1 -1
  18. package/lib/esm/model/index.d.ts +1 -0
  19. package/lib/esm/model/index.js +1 -0
  20. package/lib/esm/model/index.js.map +1 -1
  21. package/lib/esm/model/indexing.d.ts +20 -0
  22. package/lib/esm/model/indexing.js +37 -0
  23. package/lib/esm/model/indexing.js.map +1 -0
  24. package/lib/esm/persistence/Adapter.js +4 -2
  25. package/lib/esm/persistence/Adapter.js.map +1 -1
  26. package/lib/esm/repository/decorators.js +2 -1
  27. package/lib/esm/repository/decorators.js.map +1 -1
  28. package/lib/esm/tasks/TaskEngine.js +13 -6
  29. package/lib/esm/tasks/TaskEngine.js.map +1 -1
  30. package/lib/esm/tasks/TaskTracker.d.ts +2 -0
  31. package/lib/esm/tasks/TaskTracker.js +26 -3
  32. package/lib/esm/tasks/TaskTracker.js.map +1 -1
  33. package/lib/esm/tasks/models/TaskIOSerializer.d.ts +8 -2
  34. package/lib/esm/tasks/models/TaskIOSerializer.js +70 -30
  35. package/lib/esm/tasks/models/TaskIOSerializer.js.map +1 -1
  36. package/lib/identity/decorators.cjs +2 -2
  37. package/lib/identity/decorators.js.map +1 -1
  38. package/lib/index.cjs +1 -1
  39. package/lib/index.d.ts +1 -1
  40. package/lib/model/SequenceModel.cjs +2 -1
  41. package/lib/model/SequenceModel.js.map +1 -1
  42. package/lib/model/construction.cjs +293 -0
  43. package/lib/model/construction.d.ts +13 -0
  44. package/lib/model/construction.js.map +1 -1
  45. package/lib/model/decorators.cjs +7 -40
  46. package/lib/model/decorators.d.ts +1 -20
  47. package/lib/model/decorators.js.map +1 -1
  48. package/lib/model/index.cjs +1 -0
  49. package/lib/model/index.d.ts +1 -0
  50. package/lib/model/index.js.map +1 -1
  51. package/lib/model/indexing.cjs +40 -0
  52. package/lib/model/indexing.d.ts +20 -0
  53. package/lib/model/indexing.js.map +1 -0
  54. package/lib/persistence/Adapter.cjs +4 -2
  55. package/lib/persistence/Adapter.js.map +1 -1
  56. package/lib/repository/decorators.cjs +4 -3
  57. package/lib/repository/decorators.js.map +1 -1
  58. package/lib/tasks/TaskEngine.cjs +13 -6
  59. package/lib/tasks/TaskEngine.js.map +1 -1
  60. package/lib/tasks/TaskTracker.cjs +26 -3
  61. package/lib/tasks/TaskTracker.d.ts +2 -0
  62. package/lib/tasks/TaskTracker.js.map +1 -1
  63. package/lib/tasks/models/TaskIOSerializer.cjs +70 -30
  64. package/lib/tasks/models/TaskIOSerializer.d.ts +8 -2
  65. package/lib/tasks/models/TaskIOSerializer.js.map +1 -1
  66. package/package.json +1 -1
@@ -10,32 +10,11 @@ export class TaskIOSerializer extends JSONSerializer {
10
10
  * @description returns a shallow copy of the object, containing an enumerable {@link ModelKeys#ANCHOR} property
11
11
  * so the object can be recognized upon deserialization
12
12
  *
13
- * @param {T} model
13
+ * @param {any} value
14
14
  * @protected
15
15
  */
16
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
17
- preSerialize(model, ...args) {
18
- if (model === null || typeof model !== "object") {
19
- return model;
20
- }
21
- const toSerialize = Object.assign({}, model);
22
- if (model instanceof Condition) {
23
- toSerialize[ModelKeys.ANCHOR] = "??condition";
24
- return toSerialize;
25
- }
26
- if (Model.isModel(model)) {
27
- let metadata;
28
- try {
29
- metadata = Metadata.modelName(model.constructor);
30
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
31
- }
32
- catch (error) {
33
- metadata = undefined;
34
- }
35
- if (metadata)
36
- toSerialize[ModelKeys.ANCHOR] = metadata;
37
- }
38
- return toSerialize;
16
+ preSerialize(value, ...args) {
17
+ return this.serializeValue(value, ...args);
39
18
  }
40
19
  /**
41
20
  * @summary Rebuilds a model from a serialization
@@ -46,12 +25,73 @@ export class TaskIOSerializer extends JSONSerializer {
46
25
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
47
26
  deserialize(str, ...args) {
48
27
  const deserialization = JSON.parse(str);
49
- const className = deserialization[ModelKeys.ANCHOR];
50
- if (!className)
51
- return deserialization;
52
- if (className === "??condition")
53
- return Condition.from(deserialization);
54
- return Model.build(deserialization, className);
28
+ return this.rebuildValue(deserialization);
29
+ }
30
+ serializeValue(value, ...args) {
31
+ if (value === undefined || value === null)
32
+ return value;
33
+ if (typeof value !== "object")
34
+ return value;
35
+ if (value instanceof Date)
36
+ return value.toISOString();
37
+ if (Array.isArray(value)) {
38
+ return value.map((item) => this.serializeValue(item, ...args));
39
+ }
40
+ if (value instanceof Condition) {
41
+ const condition = this.serializePlain(value, ...args);
42
+ condition[ModelKeys.ANCHOR] = "??condition";
43
+ return condition;
44
+ }
45
+ if (Model.isModel(value)) {
46
+ return this.serializeModel(value, ...args);
47
+ }
48
+ return this.serializePlain(value, ...args);
49
+ }
50
+ serializeModel(value, ...args) {
51
+ const serialized = this.serializePlain(value, ...args);
52
+ const metadata = this.getMetadata(value.constructor) ??
53
+ value.constructor?.name;
54
+ if (metadata)
55
+ serialized[ModelKeys.ANCHOR] = metadata;
56
+ return serialized;
57
+ }
58
+ serializePlain(value, ...args) {
59
+ const result = {};
60
+ for (const [key, child] of Object.entries(value)) {
61
+ result[key] = this.serializeValue(child, ...args);
62
+ }
63
+ return result;
64
+ }
65
+ getMetadata(constructor) {
66
+ try {
67
+ return Metadata.modelName(constructor);
68
+ }
69
+ catch {
70
+ return undefined;
71
+ }
72
+ }
73
+ rebuildValue(value) {
74
+ if (value === null || typeof value !== "object")
75
+ return value;
76
+ if (Array.isArray(value)) {
77
+ return value.map((item) => this.rebuildValue(item));
78
+ }
79
+ const anchor = value[ModelKeys.ANCHOR];
80
+ const rebuilt = this.rebuildObject(value);
81
+ if (!anchor)
82
+ return rebuilt;
83
+ if (anchor === "??condition")
84
+ return Condition.from(rebuilt);
85
+ return Model.build(rebuilt, anchor);
86
+ }
87
+ rebuildObject(value) {
88
+ const result = {};
89
+ for (const [key, child] of Object.entries(value)) {
90
+ if (key === ModelKeys.ANCHOR)
91
+ continue;
92
+ result[key] = this.rebuildValue(child);
93
+ }
94
+ return result;
55
95
  }
56
96
  /**
57
97
  * @summary Serializes a model
@@ -1 +1 @@
1
- {"version":3,"file":"TaskIOSerializer.js","sourceRoot":"","sources":["../../../../src/tasks/models/TaskIOSerializer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,EACL,SAAS,GACV,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAe,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,mCAA8B;AAElD,MAAM,OAAO,gBAAkC,SAAQ,cAAiB;IACtE;QACE,KAAK,EAAE,CAAC;IACV,CAAC;IAED;;;;;;;OAOG;IACH,6DAA6D;IAC1C,YAAY,CAAC,KAAQ,EAAE,GAAG,IAAW;QACtD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAChD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,WAAW,GAAwB,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAClE,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;YAC/B,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC;YAC9C,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,QAAQ,CAAC;YACb,IAAI,CAAC;gBACH,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,WAA0B,CAAC,CAAC;gBAChE,6DAA6D;YAC/D,CAAC;YAAC,OAAO,KAAc,EAAE,CAAC;gBACxB,QAAQ,GAAG,SAAS,CAAC;YACvB,CAAC;YACD,IAAI,QAAQ;gBAAE,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;QACzD,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACH,6DAA6D;IACpD,WAAW,CAAC,GAAW,EAAE,GAAG,IAAW;QAC9C,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,SAAS;YAAE,OAAO,eAAoB,CAAC;QAC5C,IAAI,SAAS,KAAK,aAAa;YAC7B,OAAO,SAAS,CAAC,IAAI,CAAC,eAAe,CAAiB,CAAC;QACzD,OAAO,KAAK,CAAC,KAAK,CAAC,eAAe,EAAE,SAAS,CAAiB,CAAC;IACjE,CAAC;IAED;;;;;OAKG;IACH,6DAA6D;IACpD,SAAS,CAAC,KAAQ,EAAE,GAAG,IAAW;QACzC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IAClD,CAAC;CACF"}
1
+ {"version":3,"file":"TaskIOSerializer.js","sourceRoot":"","sources":["../../../../src/tasks/models/TaskIOSerializer.ts"],"names":[],"mappings":"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"}
@@ -6,9 +6,9 @@ exports.pk = pk;
6
6
  const decorator_validation_1 = require("@decaf-ts/decorator-validation");
7
7
  const SequenceOptions_1 = require("./../interfaces/SequenceOptions.cjs");
8
8
  const db_decorators_1 = require("@decaf-ts/db-decorators");
9
- const decorators_1 = require("./../model/decorators.cjs");
10
9
  const constants_1 = require("./../repository/constants.cjs");
11
10
  const decoration_1 = require("@decaf-ts/decoration");
11
+ const indexing_1 = require("./../model/indexing.cjs");
12
12
  const defaultPkPriority = 60; // Default priority for primary key to run latter than other properties
13
13
  /**
14
14
  * @description Callback function for primary key creation
@@ -111,7 +111,7 @@ function pkDec(options, groupsort) {
111
111
  }
112
112
  const decs = [
113
113
  (0, decoration_1.prop)(),
114
- (0, decorators_1.index)([constants_1.OrderDirection.ASC, constants_1.OrderDirection.DSC]),
114
+ (0, indexing_1.index)([constants_1.OrderDirection.ASC, constants_1.OrderDirection.DSC]),
115
115
  (0, decorator_validation_1.required)(),
116
116
  (0, db_decorators_1.readonly)(),
117
117
  (0, decoration_1.propMetadata)(decoration_1.Metadata.key(db_decorators_1.DBKeys.ID, attr), options),
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/identity/decorators.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/identity/decorators.ts"],"names":[],"mappings":"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"}
package/lib/index.cjs CHANGED
@@ -48,7 +48,7 @@ __exportStar(require("./persistence/index.cjs"), exports);
48
48
  * @const VERSION
49
49
  * @memberOf module:core
50
50
  */
51
- exports.VERSION = "0.8.29";
51
+ exports.VERSION = "0.8.30";
52
52
  /**
53
53
  * @description Stores the current package version
54
54
  * @summary A constant representing the version of the core package
package/lib/index.d.ts CHANGED
@@ -21,7 +21,7 @@ export * from "./persistence";
21
21
  * @const VERSION
22
22
  * @memberOf module:core
23
23
  */
24
- export declare const VERSION = "0.8.29";
24
+ export declare const VERSION = "0.8.30";
25
25
  /**
26
26
  * @description Stores the current package version
27
27
  * @summary A constant representing the version of the core package
@@ -14,6 +14,7 @@ const decorator_validation_1 = require("@decaf-ts/decorator-validation");
14
14
  const BaseModel_1 = require("./BaseModel.cjs");
15
15
  const decorators_1 = require("./decorators.cjs");
16
16
  const decorators_2 = require("./../identity/decorators.cjs");
17
+ const indexing_1 = require("./indexing.cjs");
17
18
  /**
18
19
  * @description RAM sequence model for auto-incrementing values
19
20
  * @summary A model class that represents a sequence in the RAM adapter. It stores the current value
@@ -44,7 +45,7 @@ __decorate([
44
45
  ], SequenceModel.prototype, "id", void 0);
45
46
  __decorate([
46
47
  (0, decorator_validation_1.required)(),
47
- (0, decorators_1.index)(),
48
+ (0, indexing_1.index)(),
48
49
  __metadata("design:type", Object)
49
50
  ], SequenceModel.prototype, "current", void 0);
50
51
  exports.SequenceModel = SequenceModel = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"SequenceModel.js","sourceRoot":"","sources":["../../src/model/SequenceModel.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yEAAiE;AAEjE,+CAAwC;AACxC,iDAA4C;AAC5C,6DAA4C;AAE5C;;;;;;;;;;;;;;;;;GAiBG;AAGI,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,qBAAS;IAe1C,YAAY,GAA6B;QACvC,KAAK,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;CACF,CAAA;AAlBY,sCAAa;AAKxB;IADC,IAAA,eAAE,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;;yCAC3B;AAQZ;IAFC,IAAA,+BAAQ,GAAE;IACV,IAAA,kBAAK,GAAE;;8CACkB;wBAbf,aAAa;IAFzB,IAAA,kBAAK,EAAC,YAAY,CAAC;IACnB,IAAA,4BAAK,GAAE;;GACK,aAAa,CAkBzB"}
1
+ {"version":3,"file":"SequenceModel.js","sourceRoot":"","sources":["../../src/model/SequenceModel.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yEAAiE;AAEjE,+CAAwC;AACxC,iDAAqC;AACrC,6DAA4C;AAC5C,6CAAmC;AACnC;;;;;;;;;;;;;;;;;GAiBG;AAGI,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,qBAAS;IAe1C,YAAY,GAA6B;QACvC,KAAK,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;CACF,CAAA;AAlBY,sCAAa;AAKxB;IADC,IAAA,eAAE,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;;yCAC3B;AAQZ;IAFC,IAAA,+BAAQ,GAAE;IACV,IAAA,gBAAK,GAAE;;8CACkB;wBAbf,aAAa;IAFzB,IAAA,kBAAK,EAAC,YAAY,CAAC;IACnB,IAAA,4BAAK,GAAE;;GACK,aAAa,CAkBzB"}
@@ -7,6 +7,14 @@ exports.oneToOneOnDelete = oneToOneOnDelete;
7
7
  exports.oneToManyOnCreate = oneToManyOnCreate;
8
8
  exports.oneToManyOnUpdate = oneToManyOnUpdate;
9
9
  exports.oneToManyOnDelete = oneToManyOnDelete;
10
+ exports.manyToOneOnCreate = manyToOneOnCreate;
11
+ exports.validBidirectionalRelation = validBidirectionalRelation;
12
+ exports.manyToOneOnUpdate = manyToOneOnUpdate;
13
+ exports.manyToOneOnDelete = manyToOneOnDelete;
14
+ exports.manyToManyOnCreate = manyToManyOnCreate;
15
+ exports.getAndConstructJunctionTable = getAndConstructJunctionTable;
16
+ exports.manyToManyOnUpdate = manyToManyOnUpdate;
17
+ exports.manyToManyOnDelete = manyToManyOnDelete;
10
18
  exports.getPopulateKey = getPopulateKey;
11
19
  exports.getTagForDeleteKey = getTagForDeleteKey;
12
20
  exports.cacheModelForPopulate = cacheModelForPopulate;
@@ -19,6 +27,7 @@ const db_decorators_1 = require("@decaf-ts/db-decorators");
19
27
  const constants_1 = require("./../persistence/constants.cjs");
20
28
  const constants_2 = require("./../repository/constants.cjs");
21
29
  const decoration_1 = require("@decaf-ts/decoration");
30
+ const decorators_1 = require("./../identity/decorators.cjs");
22
31
  /**
23
32
  * @description Creates or updates a model instance
24
33
  * @summary Determines whether to create a new model or update an existing one based on the presence of a primary key
@@ -208,6 +217,8 @@ async function oneToOneOnCreate(context, data, key, model) {
208
217
  const propertyValue = model[key];
209
218
  if (!propertyValue)
210
219
  return;
220
+ if (!validBidirectionalRelation(model, data))
221
+ return;
211
222
  if (typeof propertyValue !== "object") {
212
223
  const innerRepo = repositoryFromTypeMetadata(model, key, this.adapter.alias);
213
224
  const read = await innerRepo.read(propertyValue, context);
@@ -408,6 +419,8 @@ async function oneToManyOnCreate(context, data, key, model) {
408
419
  const propertyValues = model[key];
409
420
  if (!propertyValues || !propertyValues.length)
410
421
  return;
422
+ if (!validBidirectionalRelation(model, data))
423
+ return;
411
424
  const arrayType = typeof propertyValues[0];
412
425
  if (!propertyValues.every((item) => typeof item === arrayType))
413
426
  throw new db_decorators_1.InternalError(`Invalid operation. All elements of property ${key} must match the same type.`);
@@ -576,6 +589,286 @@ async function oneToManyOnDelete(context, data, key, model) {
576
589
  }
577
590
  model[key] = ids;
578
591
  }
592
+ async function manyToOneOnCreate(context, data, key, model) {
593
+ const propertyValue = model[key];
594
+ if (!propertyValue)
595
+ return;
596
+ if (!validBidirectionalRelation(model, data))
597
+ return;
598
+ const log = context.logger.for(manyToOneOnCreate);
599
+ // If it's a primitive value (ID), read the existing record
600
+ if (typeof propertyValue !== "object") {
601
+ const innerRepo = repositoryFromTypeMetadata(model, key, this.adapter.alias);
602
+ const read = await innerRepo.read(propertyValue);
603
+ await cacheModelForPopulate(context, model, key, propertyValue, read);
604
+ model[key] = propertyValue;
605
+ return;
606
+ }
607
+ const constructor = data.class instanceof decorator_validation_1.Model ? data.class.constructor : data.class;
608
+ if (!constructor)
609
+ throw new db_decorators_1.InternalError(`Could not find model ${data.class}`);
610
+ log.info(`Creating or updating many-to-one model: ${JSON.stringify(propertyValue)}`);
611
+ const record = await createOrUpdate(propertyValue, context, this.adapter.alias);
612
+ const pk = decorator_validation_1.Model.pk(record);
613
+ log.info(`caching: ${JSON.stringify(record)} under ${record[pk]}`);
614
+ await cacheModelForPopulate(context, model, key, record[pk], record);
615
+ model[key] = record[pk];
616
+ }
617
+ function validBidirectionalRelation(model, data) {
618
+ let metaReverseRelation;
619
+ const relationConstructor = typeof data.class === "function" && data.class.name
620
+ ? data.class
621
+ : data.class();
622
+ // get the inverse relation metadata
623
+ const metaReverseRelationMeta = decoration_1.Metadata.get(relationConstructor, constants_1.PersistenceKeys.RELATIONS);
624
+ if (metaReverseRelationMeta)
625
+ metaReverseRelation = Object.values(metaReverseRelationMeta)?.find((rel) => {
626
+ const relationConstructor = typeof rel.class === "function" && rel.class.name
627
+ ? rel.class
628
+ : rel.class();
629
+ return model instanceof relationConstructor;
630
+ });
631
+ // If populate is set to true on both sides, we should throw an error.
632
+ if (metaReverseRelation?.populate === true && data?.populate === true) {
633
+ throw new db_decorators_1.InternalError("Bidirectional populate is not allowed. Please set populate to false on one side of the relation.");
634
+ }
635
+ return true;
636
+ }
637
+ async function manyToOneOnUpdate(context, data, key, model) {
638
+ const { cascade } = data;
639
+ if (cascade.update !== constants_2.Cascade.CASCADE)
640
+ return;
641
+ return manyToOneOnCreate.apply(this, [
642
+ context,
643
+ data,
644
+ key,
645
+ model,
646
+ ]);
647
+ }
648
+ async function manyToOneOnDelete(context, data, key, model) {
649
+ if (data.cascade.delete !== constants_2.Cascade.CASCADE)
650
+ return;
651
+ const value = model[key];
652
+ if (!value)
653
+ return;
654
+ const isInstantiated = typeof value === "object";
655
+ const repo = isInstantiated
656
+ ? Repository_1.Repository.forModel(value, this.adapter.alias)
657
+ : repositoryFromTypeMetadata(model, key, this.adapter.alias);
658
+ const repoId = isInstantiated ? value[repo["pk"]] : value;
659
+ const deleted = await repo.delete(repoId);
660
+ await cacheModelForPopulate(context, model, key, repoId, deleted);
661
+ model[key] = repoId;
662
+ }
663
+ async function manyToManyOnCreate(context, data, key, modelA) {
664
+ console.warn("DECORATOR manyToMany UNDER DEVELOPMENT");
665
+ const propertyValues = modelA[key];
666
+ if (!propertyValues || !propertyValues.length)
667
+ return;
668
+ if (!validBidirectionalRelation(modelA, data))
669
+ return;
670
+ const arrayType = typeof propertyValues[0];
671
+ if (!propertyValues.every((item) => typeof item === arrayType))
672
+ throw new db_decorators_1.InternalError(`Invalid operation. All elements of property ${key} must match the same type.`);
673
+ const log = context.logger.for(manyToManyOnCreate);
674
+ const uniqueValues = new Set([...propertyValues]);
675
+ // If it's a primitive value (ID), read the existing record
676
+ if (arrayType !== "object") {
677
+ const repo = repositoryFromTypeMetadata(modelA, key, this.adapter.alias);
678
+ const read = await repo.readAll([...uniqueValues.values()], context);
679
+ for (let i = 0; i < read.length; i++) {
680
+ const model = read[i];
681
+ log.info(`FOUND MANY TO MANY VALUE: ${JSON.stringify(model)}`);
682
+ await cacheModelForPopulate(context, model, key, [...uniqueValues.values()][i], read);
683
+ }
684
+ // Create junction table entries
685
+ await getOrCreateJunctionModel.apply(this, [
686
+ modelA,
687
+ [...propertyValues],
688
+ log,
689
+ context,
690
+ data,
691
+ ]);
692
+ modelA[key] = [...uniqueValues];
693
+ log.info(`SET MANY TO MANY IDS: ${modelA[key]}`);
694
+ return;
695
+ }
696
+ const pkName = decorator_validation_1.Model.pk(propertyValues[0].constructor);
697
+ const result = new Set();
698
+ for (const propertyValue of propertyValues) {
699
+ log.info(`Creating or updating many-to-many model: ${JSON.stringify(propertyValue)}`);
700
+ const record = await createOrUpdate(propertyValue, context, this.adapter.alias);
701
+ log.info(`caching: ${JSON.stringify(record)} under ${record[pkName]}`);
702
+ await cacheModelForPopulate(context, modelA, key, record[pkName], record);
703
+ log.info(`Creating or updating many-to-many model: ${JSON.stringify(propertyValue)}`);
704
+ propertyValue.id = record.id;
705
+ result.add(record[pkName]);
706
+ }
707
+ // Get or generate the ID for modelA before persisting junction records
708
+ const modelPkName = decorator_validation_1.Model.pk(modelA.constructor);
709
+ if (typeof modelA[modelPkName] === "undefined") {
710
+ const nextId = await getNextId(this, modelA, context);
711
+ modelA[modelPkName] = nextId;
712
+ }
713
+ // Create junction table entries
714
+ const JunctionModel = await getOrCreateJunctionModel.apply(this, [modelA, propertyValues, log, context, data]);
715
+ // This will require creating junction repository and storing the relationships
716
+ log.info(`Junction model created: ${JunctionModel.name}`);
717
+ modelA[key] = [...result];
718
+ }
719
+ async function getNextId(repo, modelA, context) {
720
+ // Get the next id for the model before it is persisted so we can put it in the junction table
721
+ const modelPkName = decorator_validation_1.Model.pk(modelA.constructor);
722
+ const modelAId = modelA[modelPkName];
723
+ if (modelAId !== undefined) {
724
+ return modelAId;
725
+ }
726
+ const pkProps = decorator_validation_1.Model.sequenceFor(modelA.constructor);
727
+ if (!pkProps?.name) {
728
+ pkProps.name = decorator_validation_1.Model.sequenceName(modelA, "pk");
729
+ }
730
+ let sequence;
731
+ try {
732
+ // Access adapter through the public property 'db' or use type assertion
733
+ sequence = await repo.adapter.Sequence(pkProps);
734
+ return await sequence.next(context);
735
+ }
736
+ catch (e) {
737
+ throw new db_decorators_1.InternalError(`Failed to instantiate Sequence ${pkProps.name}: ${e}`);
738
+ }
739
+ }
740
+ async function getOrCreateJunctionModel(modelA, modelsB, log, context, metadata) {
741
+ const { JunctionModel, fkA, fkB } = getAndConstructJunctionTable(modelA, modelsB[0], metadata);
742
+ const recordIds = [];
743
+ for (const modelB of modelsB) {
744
+ log.info(`Creating or updating many-to-many junction model: ${JSON.stringify(modelB)}`);
745
+ // If it is a model, find and store fk content, else it is fk value directly
746
+ const junctionRegister = {
747
+ [fkA]: modelA instanceof decorator_validation_1.Model
748
+ ? modelA[decorator_validation_1.Model.pk(modelA.constructor)]
749
+ : modelA,
750
+ [fkB]: modelB instanceof decorator_validation_1.Model
751
+ ? modelB[decorator_validation_1.Model.pk(modelB.constructor)]
752
+ : modelB,
753
+ };
754
+ const record = await createOrUpdate(new JunctionModel(junctionRegister), context, this.adapter.alias);
755
+ if (record?.id)
756
+ recordIds.push(record.id);
757
+ }
758
+ if (recordIds.length === modelsB?.length) {
759
+ console.log(`All junction records created successfully for table ${JunctionModel?.name}`);
760
+ const repository = Repository_1.Repository.forModel(JunctionModel);
761
+ const results = await repository?.readAll(recordIds);
762
+ console.log("results:", results);
763
+ }
764
+ else
765
+ console.error(`Some junction records failed to be created for table ${JunctionModel?.name}`);
766
+ return JunctionModel;
767
+ }
768
+ function getAndConstructJunctionTable(modelA, modelB, metadata) {
769
+ // Get the name of the table and fks
770
+ const modelAName = decorator_validation_1.Model.tableName(modelA);
771
+ let modelBName;
772
+ if (modelB instanceof decorator_validation_1.Model)
773
+ modelBName = decorator_validation_1.Model.tableName(modelB);
774
+ else if (decorator_validation_1.Model.isModel(modelB) &&
775
+ typeof modelB === "function") {
776
+ modelBName = modelB.name ? modelB.name : modelB()?.name;
777
+ }
778
+ else if (metadata?.class) {
779
+ const clazz = typeof metadata.class === "function" && !metadata.class.name
780
+ ? metadata.class()
781
+ : metadata.class;
782
+ modelBName = decorator_validation_1.Model.tableName(clazz);
783
+ }
784
+ if (!modelAName || !modelBName)
785
+ throw new db_decorators_1.InternalError("Missing tablenames to create junction table");
786
+ const junctionTableName = metadata?.joinTable?.name
787
+ ? metadata?.joinTable?.name
788
+ : `${modelAName}_${modelBName}`;
789
+ const fkA = `${modelAName?.toLowerCase()}_fk`;
790
+ const fkB = `${modelBName?.toLowerCase()}_fk`;
791
+ // Anonymous class to be able to change name
792
+ const DynamicJunctionModel = class extends decorator_validation_1.Model {
793
+ constructor(arg) {
794
+ super(arg);
795
+ }
796
+ };
797
+ Object.defineProperty(DynamicJunctionModel, "name", {
798
+ value: junctionTableName,
799
+ writable: false,
800
+ });
801
+ // Apply the decorators
802
+ (0, decorators_1.pk)({ type: Number })(DynamicJunctionModel.prototype, "id");
803
+ (0, decorator_validation_1.required)()(DynamicJunctionModel.prototype, fkA);
804
+ (0, decorator_validation_1.required)()(DynamicJunctionModel.prototype, fkB);
805
+ // Apply @model() decorator to the class
806
+ const DecoratedModel = (0, decorator_validation_1.model)()(DynamicJunctionModel);
807
+ decoration_1.Metadata.set(DynamicJunctionModel, constants_1.PersistenceKeys.TABLE, junctionTableName);
808
+ return {
809
+ fkA,
810
+ fkB,
811
+ JunctionModel: DecoratedModel,
812
+ };
813
+ }
814
+ async function manyToManyOnUpdate(context, data, key, model) {
815
+ console.warn("method not yet implemented");
816
+ const { cascade } = data;
817
+ if (cascade.update !== constants_2.Cascade.CASCADE)
818
+ return;
819
+ return manyToManyOnCreate.apply(this, [
820
+ context,
821
+ data,
822
+ key,
823
+ model,
824
+ ]);
825
+ }
826
+ async function manyToManyOnDelete(context, data, key, model) {
827
+ console.warn("Method under development");
828
+ if (data.cascade.delete !== constants_2.Cascade.CASCADE)
829
+ return;
830
+ const values = model[key];
831
+ if (!values || !values.length)
832
+ return;
833
+ const arrayType = typeof values[0];
834
+ const areAllSameType = values.every((item) => typeof item === arrayType);
835
+ if (!areAllSameType)
836
+ throw new db_decorators_1.InternalError(`Invalid operation. All elements of property ${key} must match the same type.`);
837
+ // Delete the values and the junction table entries
838
+ const clazz = typeof data.class === "function" && !data.class.name
839
+ ? data.class()
840
+ : data.class;
841
+ const isInstantiated = arrayType === "object";
842
+ const repo = isInstantiated
843
+ ? Repository_1.Repository.forModel(clazz, this.adapter.alias)
844
+ : repositoryFromTypeMetadata(model, key, this.adapter.alias);
845
+ const uniqueValues = new Set([
846
+ ...(isInstantiated
847
+ ? values.map((v) => v[repo["pk"]])
848
+ : values),
849
+ ]);
850
+ const ids = [...uniqueValues.values()];
851
+ let deleted;
852
+ try {
853
+ deleted = await repo.deleteAll(ids, context);
854
+ }
855
+ catch (e) {
856
+ context.logger.error(`Failed to delete all records`, e);
857
+ throw e;
858
+ }
859
+ let del;
860
+ for (let i = 0; i < deleted.length; i++) {
861
+ del = deleted[i];
862
+ try {
863
+ await cacheModelForPopulate(context, model, key, ids[i], del);
864
+ }
865
+ catch (e) {
866
+ context.logger.error(`Failed to cache record ${ids[i]} with key ${key} and model ${JSON.stringify(model, undefined, 2)} `, e);
867
+ throw e;
868
+ }
869
+ }
870
+ model[key] = ids;
871
+ }
579
872
  /**
580
873
  * @description Generates a key for caching populated model relationships
581
874
  * @summary Creates a unique key for storing and retrieving populated model relationships in the cache
@@ -1,6 +1,7 @@
1
1
  import { Model } from "@decaf-ts/decorator-validation";
2
2
  import { Repo } from "../repository/Repository";
3
3
  import { RelationsMetadata } from "./types";
4
+ import { Constructor } from "@decaf-ts/decoration";
4
5
  import { AdapterFlags, ContextOf } from "../persistence/types";
5
6
  import { Context } from "../persistence/Context";
6
7
  /**
@@ -323,6 +324,18 @@ export declare function oneToManyOnUpdate<M extends Model, R extends Repo<M>>(th
323
324
  * oneToManyOnDelete-->>Caller: void
324
325
  */
325
326
  export declare function oneToManyOnDelete<M extends Model, R extends Repo<M>>(this: R, context: ContextOf<R>, data: RelationsMetadata, key: keyof M, model: M): Promise<void>;
327
+ export declare function manyToOneOnCreate<M extends Model, R extends Repo<M>>(this: R, context: ContextOf<R>, data: RelationsMetadata, key: keyof M, model: M): Promise<void>;
328
+ export declare function validBidirectionalRelation<M extends Model>(model: M, data: RelationsMetadata): boolean;
329
+ export declare function manyToOneOnUpdate<M extends Model, R extends Repo<M>>(this: R, context: ContextOf<R>, data: RelationsMetadata, key: keyof M, model: M): Promise<void>;
330
+ export declare function manyToOneOnDelete<M extends Model, R extends Repo<M>>(this: R, context: ContextOf<R>, data: RelationsMetadata, key: keyof M, model: M): Promise<void>;
331
+ export declare function manyToManyOnCreate<M extends Model, R extends Repo<M>>(this: R, context: ContextOf<R>, data: RelationsMetadata, key: keyof M, modelA: M): Promise<void>;
332
+ export declare function getAndConstructJunctionTable(modelA: Model, modelB: Model | any, metadata?: RelationsMetadata): {
333
+ fkA: string;
334
+ fkB: string;
335
+ JunctionModel: Constructor<Model<false>>;
336
+ };
337
+ export declare function manyToManyOnUpdate<M extends Model, R extends Repo<M>>(this: R, context: ContextOf<R>, data: RelationsMetadata, key: keyof M, model: M): Promise<void>;
338
+ export declare function manyToManyOnDelete<M extends Model, R extends Repo<M>>(this: R, context: ContextOf<R>, data: RelationsMetadata, key: keyof M, model: M): Promise<void>;
326
339
  /**
327
340
  * @description Generates a key for caching populated model relationships
328
341
  * @summary Creates a unique key for storing and retrieving populated model relationships in the cache