@warlock.js/cascade 1.0.5 → 1.0.7

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 (280) hide show
  1. package/cjs/aggregate/DeselectPipeline.d.ts +10 -0
  2. package/cjs/aggregate/DeselectPipeline.d.ts.map +1 -0
  3. package/cjs/aggregate/DeselectPipeline.js +17 -0
  4. package/cjs/aggregate/DeselectPipeline.js.map +1 -0
  5. package/cjs/aggregate/GeoNearPipeline.d.ts +34 -0
  6. package/cjs/aggregate/GeoNearPipeline.d.ts.map +1 -0
  7. package/cjs/aggregate/GeoNearPipeline.js +44 -0
  8. package/cjs/aggregate/GeoNearPipeline.js.map +1 -0
  9. package/cjs/aggregate/GroupByPipeline.d.ts +12 -0
  10. package/cjs/aggregate/GroupByPipeline.d.ts.map +1 -0
  11. package/cjs/aggregate/GroupByPipeline.js +28 -0
  12. package/cjs/aggregate/GroupByPipeline.js.map +1 -0
  13. package/cjs/aggregate/LimitPipeline.d.ts +10 -0
  14. package/cjs/aggregate/LimitPipeline.d.ts.map +1 -0
  15. package/cjs/aggregate/LimitPipeline.js +14 -0
  16. package/cjs/aggregate/LimitPipeline.js.map +1 -0
  17. package/cjs/aggregate/LookupPipeline.d.ts +19 -0
  18. package/cjs/aggregate/LookupPipeline.d.ts.map +1 -0
  19. package/cjs/aggregate/LookupPipeline.js +19 -0
  20. package/cjs/aggregate/LookupPipeline.js.map +1 -0
  21. package/cjs/aggregate/OrWherePipeline.d.ts +23 -0
  22. package/cjs/aggregate/OrWherePipeline.d.ts.map +1 -0
  23. package/cjs/aggregate/OrWherePipeline.js +42 -0
  24. package/cjs/aggregate/OrWherePipeline.js.map +1 -0
  25. package/cjs/aggregate/SelectPipeline.d.ts +10 -0
  26. package/cjs/aggregate/SelectPipeline.d.ts.map +1 -0
  27. package/cjs/aggregate/SelectPipeline.js +26 -0
  28. package/cjs/aggregate/SelectPipeline.js.map +1 -0
  29. package/cjs/aggregate/SkipPipeline.d.ts +10 -0
  30. package/cjs/aggregate/SkipPipeline.d.ts.map +1 -0
  31. package/cjs/aggregate/SkipPipeline.js +14 -0
  32. package/cjs/aggregate/SkipPipeline.js.map +1 -0
  33. package/cjs/aggregate/SortByPipeline.d.ts +10 -0
  34. package/cjs/aggregate/SortByPipeline.d.ts.map +1 -0
  35. package/cjs/aggregate/SortByPipeline.js +18 -0
  36. package/cjs/aggregate/SortByPipeline.js.map +1 -0
  37. package/cjs/aggregate/SortPipeline.d.ts +11 -0
  38. package/cjs/aggregate/SortPipeline.d.ts.map +1 -0
  39. package/cjs/aggregate/SortPipeline.js +18 -0
  40. package/cjs/aggregate/SortPipeline.js.map +1 -0
  41. package/cjs/aggregate/SortRandomPipeline.d.ts +10 -0
  42. package/cjs/aggregate/SortRandomPipeline.d.ts.map +1 -0
  43. package/cjs/aggregate/SortRandomPipeline.js +16 -0
  44. package/cjs/aggregate/SortRandomPipeline.js.map +1 -0
  45. package/cjs/aggregate/UnwindPipeline.d.ts +14 -0
  46. package/cjs/aggregate/UnwindPipeline.d.ts.map +1 -0
  47. package/cjs/aggregate/UnwindPipeline.js +19 -0
  48. package/cjs/aggregate/UnwindPipeline.js.map +1 -0
  49. package/cjs/aggregate/WhereExpression.d.ts +17 -0
  50. package/cjs/aggregate/WhereExpression.d.ts.map +1 -0
  51. package/cjs/aggregate/WhereExpression.js +149 -0
  52. package/cjs/aggregate/WhereExpression.js.map +1 -0
  53. package/cjs/aggregate/WhereExpressionPipeline.d.ts +10 -0
  54. package/cjs/aggregate/WhereExpressionPipeline.d.ts.map +1 -0
  55. package/cjs/aggregate/WhereExpressionPipeline.js +15 -0
  56. package/cjs/aggregate/WhereExpressionPipeline.js.map +1 -0
  57. package/cjs/aggregate/WherePipeline.d.ts +13 -0
  58. package/cjs/aggregate/WherePipeline.d.ts.map +1 -0
  59. package/cjs/aggregate/WherePipeline.js +12 -0
  60. package/cjs/aggregate/WherePipeline.js.map +1 -0
  61. package/cjs/aggregate/aggregate.d.ts +358 -0
  62. package/cjs/aggregate/aggregate.d.ts.map +1 -0
  63. package/cjs/aggregate/aggregate.js +680 -0
  64. package/cjs/aggregate/aggregate.js.map +1 -0
  65. package/cjs/aggregate/expressions.d.ts +361 -0
  66. package/cjs/aggregate/expressions.d.ts.map +1 -0
  67. package/cjs/aggregate/expressions.js +536 -0
  68. package/cjs/aggregate/expressions.js.map +1 -0
  69. package/cjs/aggregate/index.d.ts +21 -0
  70. package/cjs/aggregate/index.d.ts.map +1 -0
  71. package/cjs/aggregate/parsePipelines.d.ts +5 -0
  72. package/cjs/aggregate/parsePipelines.d.ts.map +1 -0
  73. package/cjs/aggregate/parsePipelines.js +6 -0
  74. package/cjs/aggregate/parsePipelines.js.map +1 -0
  75. package/cjs/aggregate/pipeline.d.ts +31 -0
  76. package/cjs/aggregate/pipeline.d.ts.map +1 -0
  77. package/cjs/aggregate/pipeline.js +42 -0
  78. package/cjs/aggregate/pipeline.js.map +1 -0
  79. package/cjs/aggregate/types.d.ts +8 -0
  80. package/cjs/aggregate/types.d.ts.map +1 -0
  81. package/cjs/aggregate/types.js +31 -0
  82. package/cjs/aggregate/types.js.map +1 -0
  83. package/cjs/blueprint/blueprint-column.d.ts +82 -0
  84. package/cjs/blueprint/blueprint-column.d.ts.map +1 -0
  85. package/cjs/blueprint/blueprint.d.ts +162 -0
  86. package/cjs/blueprint/blueprint.d.ts.map +1 -0
  87. package/cjs/blueprint/blueprint.js +340 -0
  88. package/cjs/blueprint/blueprint.js.map +1 -0
  89. package/cjs/blueprint/index.d.ts +3 -0
  90. package/cjs/blueprint/index.d.ts.map +1 -0
  91. package/cjs/blueprint/model-blueprint.d.ts +15 -0
  92. package/cjs/blueprint/model-blueprint.d.ts.map +1 -0
  93. package/cjs/blueprint/model-blueprint.js +16 -0
  94. package/cjs/blueprint/model-blueprint.js.map +1 -0
  95. package/cjs/casts/arrayOf.d.ts +5 -0
  96. package/cjs/casts/arrayOf.d.ts.map +1 -0
  97. package/cjs/casts/arrayOf.js +18 -0
  98. package/cjs/casts/arrayOf.js.map +1 -0
  99. package/cjs/casts/cast-email.d.ts +2 -0
  100. package/cjs/casts/cast-email.d.ts.map +1 -0
  101. package/cjs/casts/cast-email.js +5 -0
  102. package/cjs/casts/cast-email.js.map +1 -0
  103. package/cjs/casts/castModel.d.ts +3 -0
  104. package/cjs/casts/castModel.d.ts.map +1 -0
  105. package/cjs/casts/castModel.js +49 -0
  106. package/cjs/casts/castModel.js.map +1 -0
  107. package/cjs/casts/expiresAfter.d.ts +3 -0
  108. package/cjs/casts/expiresAfter.d.ts.map +1 -0
  109. package/cjs/casts/expiresAfter.js +5 -0
  110. package/cjs/casts/expiresAfter.js.map +1 -0
  111. package/cjs/casts/index.d.ts +9 -0
  112. package/cjs/casts/index.d.ts.map +1 -0
  113. package/cjs/casts/oneOf.d.ts +3 -0
  114. package/cjs/casts/oneOf.d.ts.map +1 -0
  115. package/cjs/casts/oneOf.js +22 -0
  116. package/cjs/casts/oneOf.js.map +1 -0
  117. package/cjs/casts/random-string.d.ts +2 -0
  118. package/cjs/casts/random-string.d.ts.map +1 -0
  119. package/cjs/casts/random-string.js +5 -0
  120. package/cjs/casts/random-string.js.map +1 -0
  121. package/cjs/casts/randomInteger.d.ts +2 -0
  122. package/cjs/casts/randomInteger.d.ts.map +1 -0
  123. package/cjs/casts/randomInteger.js +7 -0
  124. package/cjs/casts/randomInteger.js.map +1 -0
  125. package/cjs/casts/shapedArray.d.ts +26 -0
  126. package/cjs/casts/shapedArray.d.ts.map +1 -0
  127. package/cjs/casts/shapedArray.js +100 -0
  128. package/cjs/casts/shapedArray.js.map +1 -0
  129. package/cjs/config.d.ts +4 -0
  130. package/cjs/config.d.ts.map +1 -0
  131. package/cjs/config.js +10 -0
  132. package/cjs/config.js.map +1 -0
  133. package/cjs/connection.d.ts +45 -0
  134. package/cjs/connection.d.ts.map +1 -0
  135. package/cjs/connection.js +98 -0
  136. package/cjs/connection.js.map +1 -0
  137. package/cjs/database.d.ts +49 -0
  138. package/cjs/database.d.ts.map +1 -0
  139. package/cjs/database.js +85 -0
  140. package/cjs/database.js.map +1 -0
  141. package/cjs/index.d.ts +11 -1
  142. package/cjs/index.d.ts.map +1 -1
  143. package/cjs/index.js +1 -5
  144. package/cjs/index.js.map +1 -1
  145. package/cjs/migration/index.d.ts +4 -0
  146. package/cjs/migration/index.d.ts.map +1 -0
  147. package/cjs/migration/migrate.d.ts +13 -0
  148. package/cjs/migration/migrate.d.ts.map +1 -0
  149. package/cjs/migration/migrate.js +72 -0
  150. package/cjs/migration/migrate.js.map +1 -0
  151. package/cjs/migration/migration-office.d.ts +21 -0
  152. package/cjs/migration/migration-office.d.ts.map +1 -0
  153. package/cjs/migration/migration-office.js +40 -0
  154. package/cjs/migration/migration-office.js.map +1 -0
  155. package/cjs/migration/migration-officer.d.ts +33 -0
  156. package/cjs/migration/migration-officer.d.ts.map +1 -0
  157. package/cjs/migration/migration-officer.js +55 -0
  158. package/cjs/migration/migration-officer.js.map +1 -0
  159. package/cjs/migration/types.d.ts +34 -0
  160. package/cjs/migration/types.d.ts.map +1 -0
  161. package/cjs/model/ModelAggregate.d.ts +84 -0
  162. package/cjs/model/ModelAggregate.d.ts.map +1 -0
  163. package/cjs/model/ModelAggregate.js +164 -0
  164. package/cjs/model/ModelAggregate.js.map +1 -0
  165. package/cjs/model/ModelSync.d.ts +74 -0
  166. package/cjs/model/ModelSync.d.ts.map +1 -0
  167. package/cjs/model/ModelSync.js +215 -0
  168. package/cjs/model/ModelSync.js.map +1 -0
  169. package/cjs/model/RelationshipWithMany.d.ts +24 -0
  170. package/cjs/model/RelationshipWithMany.d.ts.map +1 -0
  171. package/cjs/model/RelationshipWithMany.js +42 -0
  172. package/cjs/model/RelationshipWithMany.js.map +1 -0
  173. package/cjs/model/base-model.d.ts +155 -0
  174. package/cjs/model/base-model.d.ts.map +1 -0
  175. package/cjs/model/base-model.js +230 -0
  176. package/cjs/model/base-model.js.map +1 -0
  177. package/cjs/model/crud-model.d.ts +117 -0
  178. package/cjs/model/crud-model.d.ts.map +1 -0
  179. package/cjs/model/crud-model.js +352 -0
  180. package/cjs/model/crud-model.js.map +1 -0
  181. package/cjs/model/index.d.ts +10 -0
  182. package/cjs/model/index.d.ts.map +1 -0
  183. package/cjs/model/joinable.d.ts +87 -0
  184. package/cjs/model/joinable.d.ts.map +1 -0
  185. package/cjs/model/joinable.js +155 -0
  186. package/cjs/model/joinable.js.map +1 -0
  187. package/cjs/model/master-mind.d.ts +44 -0
  188. package/cjs/model/master-mind.d.ts.map +1 -0
  189. package/cjs/model/master-mind.js +129 -0
  190. package/cjs/model/master-mind.js.map +1 -0
  191. package/cjs/model/model-events.d.ts +57 -0
  192. package/cjs/model/model-events.d.ts.map +1 -0
  193. package/cjs/model/model-events.js +102 -0
  194. package/cjs/model/model-events.js.map +1 -0
  195. package/cjs/model/model.d.ts +401 -0
  196. package/cjs/model/model.d.ts.map +1 -0
  197. package/cjs/model/model.js +1028 -0
  198. package/cjs/model/model.js.map +1 -0
  199. package/cjs/model/types.d.ts +113 -0
  200. package/cjs/model/types.d.ts.map +1 -0
  201. package/cjs/model/types.js +11 -0
  202. package/cjs/model/types.js.map +1 -0
  203. package/cjs/query/index.d.ts +2 -0
  204. package/cjs/query/index.d.ts.map +1 -0
  205. package/cjs/query/query.d.ts +228 -0
  206. package/cjs/query/query.d.ts.map +1 -0
  207. package/cjs/query/query.js +675 -0
  208. package/cjs/query/query.js.map +1 -0
  209. package/cjs/query/types.d.ts +56 -0
  210. package/cjs/query/types.d.ts.map +1 -0
  211. package/cjs/types.d.ts +62 -0
  212. package/cjs/types.d.ts.map +1 -0
  213. package/cjs/utils/connectToDatabase.d.ts +3 -0
  214. package/cjs/utils/connectToDatabase.d.ts.map +1 -0
  215. package/cjs/utils/connectToDatabase.js +3 -0
  216. package/cjs/utils/connectToDatabase.js.map +1 -0
  217. package/cjs/utils/deep-diff.d.ts +9 -0
  218. package/cjs/utils/deep-diff.d.ts.map +1 -0
  219. package/cjs/utils/deep-diff.js +44 -0
  220. package/cjs/utils/deep-diff.js.map +1 -0
  221. package/cjs/utils/dropAllDatabaseIndexes.d.ts +2 -0
  222. package/cjs/utils/dropAllDatabaseIndexes.d.ts.map +1 -0
  223. package/cjs/utils/dropAllDatabaseIndexes.js +10 -0
  224. package/cjs/utils/dropAllDatabaseIndexes.js.map +1 -0
  225. package/cjs/utils/index.d.ts +5 -0
  226. package/cjs/utils/index.d.ts.map +1 -0
  227. package/cjs/utils/joinable-proxy.d.ts +3 -0
  228. package/cjs/utils/joinable-proxy.d.ts.map +1 -0
  229. package/cjs/utils/joinable-proxy.js +14 -0
  230. package/cjs/utils/joinable-proxy.js.map +1 -0
  231. package/cjs/utils/listDatabaseIndexes.d.ts +4 -0
  232. package/cjs/utils/listDatabaseIndexes.d.ts.map +1 -0
  233. package/cjs/utils/listDatabaseIndexes.js +101 -0
  234. package/cjs/utils/listDatabaseIndexes.js.map +1 -0
  235. package/cjs/utils/onceConnected.d.ts +2 -0
  236. package/cjs/utils/onceConnected.d.ts.map +1 -0
  237. package/cjs/utils/onceConnected.js +8 -0
  238. package/cjs/utils/onceConnected.js.map +1 -0
  239. package/esm/connection.js +1 -1
  240. package/esm/connection.js.map +1 -1
  241. package/esm/utils/deep-diff.d.ts.map +1 -1
  242. package/esm/utils/deep-diff.js +5 -3
  243. package/esm/utils/deep-diff.js.map +1 -1
  244. package/package.json +1 -1
  245. package/cjs/commands/create-new-app/get-app-path.d.ts +0 -2
  246. package/cjs/commands/create-new-app/get-app-path.d.ts.map +0 -1
  247. package/cjs/commands/create-new-app/get-app-path.js +0 -8
  248. package/cjs/commands/create-new-app/get-app-path.js.map +0 -1
  249. package/cjs/commands/create-new-app/index.d.ts +0 -2
  250. package/cjs/commands/create-new-app/index.d.ts.map +0 -1
  251. package/cjs/commands/create-new-app/index.js +0 -44
  252. package/cjs/commands/create-new-app/index.js.map +0 -1
  253. package/cjs/commands/create-new-app/select-app-type.d.ts +0 -2
  254. package/cjs/commands/create-new-app/select-app-type.d.ts.map +0 -1
  255. package/cjs/commands/create-new-app/types.d.ts +0 -9
  256. package/cjs/commands/create-new-app/types.d.ts.map +0 -1
  257. package/cjs/commands/create-warlock-app/index.d.ts +0 -3
  258. package/cjs/commands/create-warlock-app/index.d.ts.map +0 -1
  259. package/cjs/commands/create-warlock-app/index.js +0 -18
  260. package/cjs/commands/create-warlock-app/index.js.map +0 -1
  261. package/cjs/helpers/app.d.ts +0 -51
  262. package/cjs/helpers/app.d.ts.map +0 -1
  263. package/cjs/helpers/app.js +0 -127
  264. package/cjs/helpers/app.js.map +0 -1
  265. package/cjs/helpers/exec.d.ts +0 -10
  266. package/cjs/helpers/exec.d.ts.map +0 -1
  267. package/cjs/helpers/exec.js +0 -69
  268. package/cjs/helpers/exec.js.map +0 -1
  269. package/cjs/helpers/package-manager.d.ts +0 -6
  270. package/cjs/helpers/package-manager.d.ts.map +0 -1
  271. package/cjs/helpers/package-manager.js +0 -22
  272. package/cjs/helpers/package-manager.js.map +0 -1
  273. package/cjs/helpers/paths.d.ts +0 -4
  274. package/cjs/helpers/paths.d.ts.map +0 -1
  275. package/cjs/helpers/paths.js +0 -8
  276. package/cjs/helpers/paths.js.map +0 -1
  277. package/cjs/helpers/project-builder-helpers.d.ts +0 -7
  278. package/cjs/helpers/project-builder-helpers.d.ts.map +0 -1
  279. package/cjs/helpers/project-builder-helpers.js +0 -44
  280. package/cjs/helpers/project-builder-helpers.js.map +0 -1
@@ -0,0 +1,1028 @@
1
+ 'use strict';var reinforcements=require('@mongez/reinforcements'),supportiveIs=require('@mongez/supportive-is'),timeWizard=require('@mongez/time-wizard'),dayjs=require('dayjs'),mongodb=require('mongodb'),castModel=require('../casts/castModel.js'),oneOf=require('../casts/oneOf.js'),deepDiff=require('../utils/deep-diff.js'),joinableProxy=require('../utils/joinable-proxy.js'),ModelAggregate=require('./ModelAggregate.js'),ModelSync=require('./ModelSync.js'),RelationshipWithMany=require('./RelationshipWithMany.js'),crudModel=require('./crud-model.js'),joinable=require('./joinable.js'),types=require('./types.js');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var dayjs__default=/*#__PURE__*/_interopDefault(dayjs);class Model
2
+ // <
3
+ // ModelDocument extends Document = any,
4
+ // ModelSchema extends Schema<ModelDocument> = any,
5
+ // >
6
+ extends crudModel.CrudModel {
7
+ /**
8
+ * Model Initial Document data
9
+ */
10
+ initialData = {};
11
+ /**
12
+ * Relations list
13
+ */
14
+ static relations = {};
15
+ /**
16
+ * Model Document data
17
+ */
18
+ data;
19
+ /**
20
+ * Define Default value data that will be merged with the models' data
21
+ * on the create process
22
+ */
23
+ defaultValue = {};
24
+ /**
25
+ * A flag to determine if the model is being restored
26
+ */
27
+ isRestored = false;
28
+ /**
29
+ * Model casts types
30
+ */
31
+ casts = {};
32
+ /**
33
+ * Sync with list
34
+ */
35
+ syncWith = [];
36
+ /**
37
+ * Set custom casts that will be used to cast the model's data are not related to the current value of the collection's column
38
+ *
39
+ * For example: `name` is not a column in the given data, but it will be concatenation of `firstName` and `lastName`
40
+ */
41
+ customCasts = {};
42
+ /**
43
+ * Guarded fields
44
+ */
45
+ guarded = [];
46
+ /**
47
+ * Fillable fields
48
+ */
49
+ filled = [];
50
+ /**
51
+ * Embedded columns
52
+ */
53
+ embedded = [];
54
+ /**
55
+ * Embed all columns except the given columns
56
+ */
57
+ embedAllExcept = [];
58
+ /**
59
+ * Embed all columns except timestamps and created|updated|deleted by columns
60
+ */
61
+ embedAllExceptTimestampsAndUserColumns = false;
62
+ /**
63
+ * Created at column
64
+ */
65
+ createdAtColumn = "createdAt";
66
+ /**
67
+ * Updated at column
68
+ */
69
+ updatedAtColumn = "updatedAt";
70
+ /**
71
+ * Deleted at column
72
+ */
73
+ deletedAtColumn = "deletedAt";
74
+ /**
75
+ * Created by column
76
+ */
77
+ createdByColumn = "createdBy";
78
+ /**
79
+ * Updated by column
80
+ */
81
+ updatedByColumn = "updatedBy";
82
+ /**
83
+ * Deleted by column
84
+ */
85
+ deletedByColumn = "deletedBy";
86
+ /**
87
+ * Date format
88
+ */
89
+ dateFormat = "DD-MM-YYYY";
90
+ /**
91
+ * A flag to determine if the id is auto generated not added manually
92
+ */
93
+ autoGeneratedId = false;
94
+ /**
95
+ * Is active column
96
+ */
97
+ isActiveColumn = "isActive";
98
+ /**
99
+ * Original data
100
+ */
101
+ originalData = {};
102
+ /**
103
+ * List of dirty columns
104
+ */
105
+ dirtyColumns = {};
106
+ /**
107
+ * Constructor
108
+ */
109
+ constructor(originalData = {}) {
110
+ super();
111
+ if (originalData instanceof Model) {
112
+ this.originalData = reinforcements.clone(originalData.data);
113
+ }
114
+ else {
115
+ this.originalData = reinforcements.clone(originalData);
116
+ }
117
+ if (typeof originalData?._id === "string") {
118
+ try {
119
+ originalData._id = new mongodb.ObjectId(originalData._id);
120
+ }
121
+ catch (error) {
122
+ originalData._id = new mongodb.ObjectId();
123
+ }
124
+ }
125
+ this.data = reinforcements.clone(this.originalData);
126
+ this.initialData = reinforcements.clone(this.originalData);
127
+ // this is necessary as clone() will generate a new _id for the data
128
+ // so we need to keep the original _id
129
+ if (originalData?._id) {
130
+ this.originalData._id = new mongodb.ObjectId(originalData._id);
131
+ this.data._id = new mongodb.ObjectId(originalData._id);
132
+ this.initialData._id = new mongodb.ObjectId(originalData._id);
133
+ }
134
+ }
135
+ /**
136
+ * Get save columns which are the casts keys
137
+ */
138
+ get castColumns() {
139
+ return Object.keys(this.casts);
140
+ }
141
+ /**
142
+ * Get value from original data
143
+ */
144
+ original(key, defaultValue) {
145
+ return reinforcements.get(this.originalData, key, defaultValue);
146
+ }
147
+ /**
148
+ * Get all data except the guarded fields
149
+ */
150
+ get publicData() {
151
+ return reinforcements.except(this.data, this.guarded);
152
+ }
153
+ /**
154
+ * Get guarded data
155
+ */
156
+ get guardedData() {
157
+ return reinforcements.only(this.data, this.guarded);
158
+ }
159
+ /**
160
+ * Get the model's id
161
+ */
162
+ get id() {
163
+ return this.get("id");
164
+ }
165
+ /**
166
+ * Check if current user is active
167
+ */
168
+ get isActive() {
169
+ return Boolean(this.get(this.isActiveColumn));
170
+ }
171
+ /**
172
+ * Get mongodb id
173
+ */
174
+ get _id() {
175
+ return this.get("_id");
176
+ }
177
+ /**
178
+ * Mark the current model as being restored
179
+ */
180
+ markAsRestored() {
181
+ this.isRestored = true;
182
+ }
183
+ /**
184
+ * Set a column in the model data
185
+ */
186
+ set(column, value) {
187
+ const currentValue = this.get(column);
188
+ this.data = reinforcements.set(this.data, column, value);
189
+ if (currentValue !== value) {
190
+ reinforcements.set(this.dirtyColumns, column, {
191
+ oldValue: currentValue,
192
+ newValue: value,
193
+ });
194
+ }
195
+ return this;
196
+ }
197
+ /**
198
+ * Increment the given column by the given value
199
+ */
200
+ increment(column, value = 1) {
201
+ return this.set(column, this.get(column, 0) + value);
202
+ }
203
+ /**
204
+ * Decrement the given column by the given value
205
+ */
206
+ decrement(column, value = 1) {
207
+ return this.set(column, this.get(column, 0) - value);
208
+ }
209
+ /**
210
+ * Get initial value of the given column
211
+ */
212
+ getInitial(column, defaultValue) {
213
+ return reinforcements.get(this.initialData, column, defaultValue);
214
+ }
215
+ /**
216
+ * Get value of the given column
217
+ */
218
+ get(column, defaultValue) {
219
+ return reinforcements.get(this.data, column, defaultValue);
220
+ }
221
+ /**
222
+ * Return the value of the given column as a string
223
+ */
224
+ string(column, defaultValue) {
225
+ return String(this.get(column, defaultValue));
226
+ }
227
+ /**
228
+ * Return the value of the given column as an integer
229
+ */
230
+ int(column, defaultValue) {
231
+ return parseInt(this.get(column, defaultValue));
232
+ }
233
+ /**
234
+ * Return the value of the given column as a float
235
+ */
236
+ float(column, defaultValue) {
237
+ return parseFloat(this.get(column, defaultValue));
238
+ }
239
+ /**
240
+ * Return the value of the given column as a number
241
+ */
242
+ number(column, defaultValue) {
243
+ return Number(this.get(column, defaultValue));
244
+ }
245
+ /**
246
+ * Return the value of the given column as a boolean
247
+ */
248
+ bool(column, defaultValue) {
249
+ return Boolean(this.get(column, defaultValue));
250
+ }
251
+ /**
252
+ * Determine whether the given column exists in the document
253
+ */
254
+ has(column) {
255
+ return reinforcements.get(this.data, column) !== undefined;
256
+ }
257
+ /**
258
+ * Get all columns except the given ones
259
+ */
260
+ except(columns) {
261
+ return reinforcements.except(this.data, columns);
262
+ }
263
+ /**
264
+ * Get only the given columns
265
+ */
266
+ only(columns) {
267
+ return reinforcements.only(this.data, columns);
268
+ }
269
+ /**
270
+ * Get only id
271
+ */
272
+ get onlyId() {
273
+ return this.only(["id"]);
274
+ }
275
+ /**
276
+ * Unset or remove the given columns from the data
277
+ */
278
+ unset(...columns) {
279
+ const currentValues = this.only(columns);
280
+ this.data = reinforcements.except(this.data, columns);
281
+ for (const column in currentValues) {
282
+ reinforcements.set(this.dirtyColumns, column, {
283
+ oldValue: currentValues[column],
284
+ newValue: undefined,
285
+ });
286
+ }
287
+ return this;
288
+ }
289
+ /**
290
+ * Replace the entire document data with the given new data
291
+ */
292
+ replaceWith(data) {
293
+ if (!data.id && this.data.id) {
294
+ data.id = this.data.id;
295
+ }
296
+ if (!data._id && this.data._id) {
297
+ data._id = this.data._id;
298
+ }
299
+ const currentData = reinforcements.clone(this.data);
300
+ this.data = data;
301
+ const dirtyValues = deepDiff.deepDiff(currentData, this.data);
302
+ reinforcements.merge(this.dirtyColumns, dirtyValues);
303
+ return this;
304
+ }
305
+ /**
306
+ * Merge the given documents to current document
307
+ */
308
+ merge(data) {
309
+ const currentData = reinforcements.clone(this.data);
310
+ this.data = reinforcements.merge(this.data, data);
311
+ const dirtyValues = deepDiff.deepDiff(currentData, this.data);
312
+ reinforcements.merge(this.dirtyColumns, dirtyValues);
313
+ for (const column in this.data) {
314
+ if (this.data[column] !== currentData[column]) {
315
+ reinforcements.set(this.dirtyColumns, column, {
316
+ oldValue: currentData[column],
317
+ newValue: this.data[column],
318
+ });
319
+ }
320
+ }
321
+ return this;
322
+ }
323
+ /**
324
+ * Push the given values to the given column
325
+ * If the given column does not exists, it will be created
326
+ * If the given value exists but not an array it will be ignored
327
+ */
328
+ push(column, ...values) {
329
+ const currentValue = this.get(column);
330
+ if (Array.isArray(currentValue)) {
331
+ this.set(column, [...currentValue, ...values]);
332
+ }
333
+ else if (!currentValue) {
334
+ this.set(column, values);
335
+ }
336
+ return this;
337
+ }
338
+ /**
339
+ * Push the given values to the given column only if not exists
340
+ */
341
+ pushOnce(column, ...values) {
342
+ const currentValue = this.get(column);
343
+ if (Array.isArray(currentValue)) {
344
+ const newValues = Array.from(new Set([...currentValue, ...values]));
345
+ this.set(column, newValues);
346
+ }
347
+ else if (!currentValue) {
348
+ this.set(column, values);
349
+ }
350
+ return this;
351
+ }
352
+ /**
353
+ * Add the given values to the beginning of the given column
354
+ * If the given column does not exists, it will be created
355
+ * If the given value exists but not an array it will be ignored
356
+ */
357
+ unshift(column, ...values) {
358
+ const currentValue = this.get(column);
359
+ if (Array.isArray(currentValue)) {
360
+ this.set(column, [...values, ...currentValue]);
361
+ }
362
+ else if (!currentValue) {
363
+ this.set(column, values);
364
+ }
365
+ return this;
366
+ }
367
+ /**
368
+ * Add the given values to the beginning of the given column only if not exists
369
+ */
370
+ unshiftOnce(column, ...values) {
371
+ const currentValue = this.get(column);
372
+ if (Array.isArray(currentValue)) {
373
+ const newValues = Array.from(new Set([...values, ...currentValue]));
374
+ this.set(column, newValues);
375
+ }
376
+ else if (!currentValue) {
377
+ this.set(column, values);
378
+ }
379
+ return this;
380
+ }
381
+ /**
382
+ * Perform saving operation either by updating or creating a new record in database
383
+ */
384
+ async save(mergedData, { triggerEvents = true, cast = true, forceUpdate = false, } = {}) {
385
+ const saveEvents = [];
386
+ try {
387
+ if (mergedData) {
388
+ this.merge(mergedData);
389
+ }
390
+ let mode = "create";
391
+ let currentModel;
392
+ // check if the data contains the primary id column
393
+ if (!this.isNewModel()) {
394
+ // perform an update operation
395
+ // check if the data has changed
396
+ // if not changed, then do not do anything
397
+ if (cast) {
398
+ await this.castData(forceUpdate);
399
+ }
400
+ if (this.shouldUpdate(this.originalData, this.data) === false) {
401
+ return this;
402
+ }
403
+ currentModel = new this.constructor(this.originalData);
404
+ mode = "update";
405
+ const updatedAtColumn = this.updatedAtColumn;
406
+ if (updatedAtColumn) {
407
+ // updateAtColumn is supposed to be part of the Schema
408
+ this.data[updatedAtColumn] = new Date();
409
+ }
410
+ if (triggerEvents) {
411
+ const selfModelEvents = this.getModelEvents();
412
+ const ModelEvents = this.getBaseModelEvents();
413
+ await this.onSaving();
414
+ await this.onUpdating();
415
+ await selfModelEvents.trigger("updating", this, currentModel);
416
+ await selfModelEvents.trigger("saving", this, currentModel);
417
+ await ModelEvents.trigger("updating", this, currentModel);
418
+ await ModelEvents.trigger("saving", this, currentModel);
419
+ }
420
+ await this.getQuery().replace(this.getCollection(), {
421
+ _id: this.data._id,
422
+ }, this.data);
423
+ if (triggerEvents) {
424
+ const selfModelEvents = this.getModelEvents();
425
+ const ModelEvents = this.getBaseModelEvents();
426
+ saveEvents.push(this.onSaved(), this.onUpdated(), selfModelEvents.trigger("updated", this, currentModel), selfModelEvents.trigger("saved", this, currentModel), ModelEvents.trigger("updated", this, currentModel), ModelEvents.trigger("saved", this, currentModel));
427
+ }
428
+ }
429
+ else {
430
+ let tries = 3;
431
+ while (tries > 0) {
432
+ try {
433
+ // await this.getDatabase().startSessionContext(async ({ session }) => {
434
+ // check for default values and merge it with the data
435
+ await this.checkDefaultValues();
436
+ // if the column does not exist, then create it
437
+ if ((!this.data.id || !this.autoGeneratedId) &&
438
+ this.getStaticProperty("autoGenerateId")) {
439
+ this.autoGeneratedId = true;
440
+ await this.generateNextId();
441
+ }
442
+ const now = new Date();
443
+ const createdAtColumn = this.createdAtColumn;
444
+ // if the column does not exist, then create it
445
+ if (this.data[createdAtColumn]) {
446
+ this.data[createdAtColumn] = new Date(this.data[createdAtColumn]);
447
+ }
448
+ else if (createdAtColumn) {
449
+ this.data[createdAtColumn] = now;
450
+ }
451
+ // if the column does not exist, then create it
452
+ const updatedAtColumn = this.updatedAtColumn;
453
+ if (updatedAtColumn) {
454
+ this.data[updatedAtColumn] = now;
455
+ }
456
+ if (cast) {
457
+ await this.castData();
458
+ }
459
+ if (triggerEvents) {
460
+ const selfModelEvents = this.getModelEvents();
461
+ const ModelEvents = this.getBaseModelEvents();
462
+ await this.onSaving();
463
+ await this.onCreating();
464
+ await selfModelEvents.trigger("creating", this);
465
+ await selfModelEvents.trigger("saving", this);
466
+ await ModelEvents.trigger("creating", this);
467
+ await ModelEvents.trigger("saving", this);
468
+ }
469
+ this.data = (await this.getQuery().create(this.getCollection(), this.data));
470
+ if (triggerEvents) {
471
+ const selfModelEvents = this.getModelEvents();
472
+ const ModelEvents = this.getBaseModelEvents();
473
+ saveEvents.push(this.onSaved(), this.onCreated(), selfModelEvents.trigger("created", this), selfModelEvents.trigger("saved", this), ModelEvents.trigger("created", this), ModelEvents.trigger("saved", this));
474
+ }
475
+ break;
476
+ }
477
+ catch (error) {
478
+ console.log(error.message);
479
+ console.log(error.trace);
480
+ // Handle duplicate key error
481
+ if (error instanceof mongodb.MongoServerError && error.code === 11000) {
482
+ if (tries < 2) {
483
+ const duplicateField = error.keyValue;
484
+ const fieldName = Object.keys(duplicateField)[0];
485
+ const errorMessage = `A record with the same ${fieldName} already exists.`;
486
+ if (this.autoGeneratedId) {
487
+ this.unset("id");
488
+ }
489
+ throw new Error(errorMessage);
490
+ }
491
+ else {
492
+ tries--;
493
+ }
494
+ }
495
+ throw error;
496
+ }
497
+ }
498
+ }
499
+ if (!this.data.id)
500
+ return this;
501
+ this.originalData = reinforcements.clone(this.data);
502
+ // @see constructor
503
+ this.originalData._id = this.data._id;
504
+ if (triggerEvents) {
505
+ await Promise.all(saveEvents);
506
+ this.startSyncing(mode, currentModel);
507
+ }
508
+ return this;
509
+ }
510
+ catch (error) {
511
+ console.log("Error in " + this.constructor.name + ".save()");
512
+ console.log(error);
513
+ throw error;
514
+ }
515
+ }
516
+ /**
517
+ * Generate and return next id
518
+ */
519
+ async generateNextId() {
520
+ this.set("id", await this.getStaticProperty("genNextId").bind(this.constructor)());
521
+ return this.id;
522
+ }
523
+ /**
524
+ * Perform saving but without any events triggers
525
+ */
526
+ async silentSaving(mergedData, options) {
527
+ return await this.save(mergedData, {
528
+ triggerEvents: false,
529
+ ...(options || {}),
530
+ });
531
+ }
532
+ /**
533
+ * Determine whether the model should be updated or not
534
+ */
535
+ shouldUpdate(originalData, data) {
536
+ return reinforcements.areEqual(originalData, data) === false;
537
+ }
538
+ /**
539
+ * Triggered before saving the model either by creating or updating
540
+ */
541
+ async onSaving() {
542
+ //
543
+ }
544
+ /**
545
+ * Triggered after saving the model either by creating or updating
546
+ */
547
+ async onSaved() {
548
+ //
549
+ }
550
+ /**
551
+ * Triggered before creating the model
552
+ */
553
+ async onCreating() {
554
+ //
555
+ }
556
+ /**
557
+ * Triggered after creating the model
558
+ */
559
+ async onCreated() {
560
+ //
561
+ }
562
+ /**
563
+ * Triggered before updating the model
564
+ */
565
+ async onUpdating() {
566
+ //
567
+ }
568
+ /**
569
+ * Triggered after updating the model
570
+ */
571
+ async onUpdated() {
572
+ //
573
+ }
574
+ /**
575
+ * Triggered before deleting the model
576
+ */
577
+ async onDeleting() {
578
+ //
579
+ }
580
+ /**
581
+ * Triggered after deleting the model
582
+ */
583
+ async onDeleted() {
584
+ //
585
+ }
586
+ /**
587
+ * Cast data before saving
588
+ */
589
+ async castData(forceUpdate = false) {
590
+ for (const column in this.casts) {
591
+ if (!forceUpdate && !this.isDirty(column)) {
592
+ continue;
593
+ }
594
+ let value = this.get(column);
595
+ if (value === undefined)
596
+ continue;
597
+ const castType = this.casts[column];
598
+ const castValue = async (value) => {
599
+ if (castType.prototype instanceof Model) {
600
+ // if cast type is passed as model class, then get its embedded data
601
+ value = await castModel.castModel(castType)(value);
602
+ }
603
+ else if (castType?.model) {
604
+ // it means the user is passing a custom model embedding i.e Model.embed('embedToProduct') => Product to embed from the getter property
605
+ // embedToProduct
606
+ // @see EmbeddedModel
607
+ value = await castModel.castModel(castType.model, castType.embeddedKey)(value);
608
+ }
609
+ else if (typeof castType === "object") {
610
+ // it means the user is passing an enum object
611
+ value = await oneOf.castEnum(castType)(value);
612
+ }
613
+ else if (value instanceof Model) {
614
+ value = value.embeddedData;
615
+ }
616
+ else if (typeof castType === "function") {
617
+ value = await castType(value, column, this);
618
+ }
619
+ else {
620
+ value = this.castValue(value, castType);
621
+ }
622
+ return value;
623
+ };
624
+ // if the cast type is passed in array
625
+ // it means we just need to pass the value to the first function
626
+ // second argument will be the column name
627
+ // and the third argument will be the model instance
628
+ if (Array.isArray(castType)) {
629
+ value = await castType[0](value, column, this);
630
+ }
631
+ else if (Array.isArray(value) && castType !== "localized") {
632
+ // if cast type is array, then we'll keep the value as it is
633
+ // now we want to add a new validation rule that to check
634
+ // if the value is an array of localized objects
635
+ // if so, then each value in the array should have `localeCode` and `value` keys
636
+ // if so, then it will be cast only to the value key inside each object
637
+ // so the final output will be localeCode and `castValue` of the value key
638
+ if (castType === "array") ;
639
+ else if (value[0]?.localeCode && value[0]?.value) {
640
+ value = await Promise.all(value.map(async (item) => {
641
+ return {
642
+ localeCode: item.localeCode,
643
+ value: await castValue(item.value),
644
+ };
645
+ }));
646
+ }
647
+ else {
648
+ value = await Promise.all(value.map(async (item) => {
649
+ return await castValue(item);
650
+ }));
651
+ }
652
+ }
653
+ else {
654
+ value = await castValue(value);
655
+ }
656
+ if (Array.isArray(value)) {
657
+ value = value.filter(value => value !== null && value !== undefined);
658
+ }
659
+ if (value !== undefined) {
660
+ this.set(column, value);
661
+ }
662
+ else {
663
+ this.unset(column);
664
+ }
665
+ }
666
+ for (const column in this.customCasts) {
667
+ const castType = this.customCasts[column];
668
+ const value = await castType(this, column);
669
+ if (value !== undefined) {
670
+ this.set(column, value);
671
+ }
672
+ else {
673
+ this.unset(column);
674
+ }
675
+ }
676
+ }
677
+ /**
678
+ * Return only the given columns to be used in output
679
+ */
680
+ outputOnly(columns) {
681
+ return this.clone(this.only(columns));
682
+ }
683
+ /**
684
+ * Return all columns except the given columns to be used in output
685
+ */
686
+ outputExcept(columns) {
687
+ return this.clone(this.except(columns));
688
+ }
689
+ /**
690
+ * Cast the given value based on the given cast type
691
+ */
692
+ castValue(value, castType) {
693
+ const isEmptyValue = supportiveIs.isEmpty(value);
694
+ if (typeof value === "object") {
695
+ if (value === null)
696
+ return undefined;
697
+ }
698
+ else if (isEmptyValue)
699
+ return undefined;
700
+ switch (castType) {
701
+ case "string":
702
+ return isEmptyValue ? "" : String(value).trim();
703
+ case "localized":
704
+ // if (isEmptyValue) return [];
705
+ // if (!Array.isArray(value)) return [];
706
+ if (!Array.isArray(value))
707
+ return undefined;
708
+ return value
709
+ .filter(value => !supportiveIs.isEmpty(value) && supportiveIs.isPlainObject(value))
710
+ .map(item => {
711
+ return {
712
+ localeCode: item.localeCode,
713
+ value: item.value,
714
+ };
715
+ });
716
+ case "number":
717
+ // return isEmptyValue ? 0 : Number(value);
718
+ return Number(value);
719
+ case "int":
720
+ case "integer":
721
+ // return isEmptyValue ? 0 : parseInt(value);
722
+ return parseInt(value);
723
+ case "float":
724
+ // return isEmptyValue ? 0 : parseFloat(value);
725
+ return parseFloat(value);
726
+ case "bool":
727
+ case "boolean": {
728
+ // if (isEmptyValue) return false;
729
+ if (value === "true")
730
+ return true;
731
+ if (value === "false" || value === "0" || value === 0)
732
+ return false;
733
+ return Boolean(value);
734
+ }
735
+ case "date": {
736
+ if (dayjs__default.default.isDayjs(value)) {
737
+ value = value.toDate();
738
+ }
739
+ if (value instanceof Date) {
740
+ return timeWizard.toUTC(value);
741
+ }
742
+ return timeWizard.toUTC(new Date(value));
743
+ }
744
+ case "location": {
745
+ // if (isEmptyValue) return null;
746
+ const lat = value?.[0] || value?.lat;
747
+ const lng = value?.[1] || value?.lng;
748
+ const address = value?.address || value?.formattedAddress;
749
+ return {
750
+ type: "Point",
751
+ coordinates: [Number(lat), Number(lng)],
752
+ address,
753
+ };
754
+ }
755
+ case "object": {
756
+ // if (isEmptyValue) return {};
757
+ if (typeof value === "string") {
758
+ try {
759
+ return JSON.parse(value);
760
+ }
761
+ catch (error) {
762
+ return undefined;
763
+ }
764
+ }
765
+ return value;
766
+ }
767
+ case "array": {
768
+ // if (isEmptyValue) return [];
769
+ if (typeof value === "string") {
770
+ return JSON.parse(value);
771
+ }
772
+ return value;
773
+ }
774
+ case "mixed":
775
+ case "any":
776
+ default:
777
+ return value;
778
+ }
779
+ }
780
+ /**
781
+ * Check for default values
782
+ */
783
+ checkDefaultValues() {
784
+ // if default value is empty, then do nothing
785
+ if (supportiveIs.isEmpty(this.defaultValue))
786
+ return;
787
+ const defaultValue = { ...this.defaultValue };
788
+ for (const key in defaultValue) {
789
+ const value = defaultValue[key];
790
+ if (typeof value === "function") {
791
+ defaultValue[key] = value(this);
792
+ }
793
+ }
794
+ // merge the data with default value
795
+ this.data = reinforcements.merge(defaultValue, this.data);
796
+ }
797
+ /**
798
+ * Destroy the model and delete it from database collection
799
+ */
800
+ async destroy() {
801
+ if (!this.data._id)
802
+ return;
803
+ if (this.deletedAtColumn) {
804
+ this.set(this.deletedAtColumn, new Date());
805
+ }
806
+ const deleteStrategy = this.getStaticProperty("deleteStrategy");
807
+ if (deleteStrategy === types.ModelDeleteStrategy.moveToTrash) {
808
+ const collectionName = this.getCollection();
809
+ class Trash extends Model {
810
+ static collection = collectionName + "Trash";
811
+ }
812
+ // we need to wrap the trash collection inside a model class so it get a generated timestamps and id
813
+ Trash.create({
814
+ document: this.data,
815
+ });
816
+ }
817
+ const selfModelEvents = this.getModelEvents();
818
+ const ModelEvents = this.getBaseModelEvents();
819
+ await this.onDeleting();
820
+ await selfModelEvents.trigger("deleting", this);
821
+ await ModelEvents.trigger("deleting", this);
822
+ // the document will be deleted from database collection if the delete strategy is not soft delete
823
+ if (deleteStrategy !== types.ModelDeleteStrategy.softDelete) {
824
+ await this.getQuery().deleteOne(this.getCollection(), {
825
+ _id: this.data._id,
826
+ });
827
+ }
828
+ else if (deleteStrategy === types.ModelDeleteStrategy.softDelete) {
829
+ await this.getQuery().updateOne(this.getCollection(), {
830
+ _id: this.data._id,
831
+ }, this.data);
832
+ }
833
+ this.onDeleted();
834
+ selfModelEvents.trigger("deleted", this);
835
+ ModelEvents.trigger("deleted", this);
836
+ this.syncDestruction();
837
+ }
838
+ /**
839
+ * Determine if the given column is dirty column
840
+ *
841
+ * Dirty columns are columns that their values have been changed from the original data
842
+ */
843
+ isDirty(column) {
844
+ if (!column) {
845
+ return reinforcements.areEqual(reinforcements.clone(this.data), reinforcements.clone(this.originalData)) === false;
846
+ }
847
+ if (this.isNewModel())
848
+ return true;
849
+ const currentValue = reinforcements.get(this.data, column);
850
+ const originalValue = reinforcements.get(this.originalData, column);
851
+ return reinforcements.areEqual(reinforcements.clone(currentValue), reinforcements.clone(originalValue)) === false;
852
+ }
853
+ /**
854
+ * Check if current model is a new model
855
+ */
856
+ isNewModel() {
857
+ return !this.data._id || (this.data._id && this.isRestored);
858
+ }
859
+ /**
860
+ * Get embedded data
861
+ */
862
+ get embeddedData() {
863
+ if (this.embedAllExcept.length > 0) {
864
+ return reinforcements.except(this.data, this.embedAllExcept);
865
+ }
866
+ if (this.embedAllExceptTimestampsAndUserColumns) {
867
+ return reinforcements.except(this.data, [
868
+ this.createdAtColumn,
869
+ this.updatedAtColumn,
870
+ this.deletedAtColumn,
871
+ this.createdByColumn,
872
+ this.updatedByColumn,
873
+ this.deletedByColumn,
874
+ ]);
875
+ }
876
+ return this.embedded.length > 0 ? this.only(this.embedded) : this.data;
877
+ }
878
+ /**
879
+ * Clone the model
880
+ */
881
+ clone(data = this.data) {
882
+ return new this.constructor(reinforcements.clone(data));
883
+ }
884
+ /**
885
+ * Get relationship with the given model class
886
+ */
887
+ hasMany(modelClass, column) {
888
+ return new RelationshipWithMany.RelationshipWithMany(this, modelClass, column);
889
+ }
890
+ /**
891
+ * Get new aggregate for current model
892
+ */
893
+ static aggregate() {
894
+ return new ModelAggregate.ModelAggregate(this);
895
+ }
896
+ /**
897
+ * @alias aggregate
898
+ */
899
+ static $() {
900
+ return this.aggregate();
901
+ }
902
+ /**
903
+ * Get query builder
904
+ * @alias aggregate
905
+ */
906
+ static queryBuilder() {
907
+ return new ModelAggregate.ModelAggregate(this);
908
+ }
909
+ /**
910
+ * Sync with the given model
911
+ */
912
+ static sync(columns, embedMethod = "embedData") {
913
+ return new ModelSync.ModelSync(this, columns, embedMethod);
914
+ }
915
+ /**
916
+ * Sync data on saving
917
+ */
918
+ startSyncing(saveMode, oldModel) {
919
+ for (const modelSync of this.syncWith) {
920
+ modelSync.sync(this, saveMode, oldModel);
921
+ }
922
+ }
923
+ /**
924
+ * Sync destruction
925
+ * Called when destroy method is called
926
+ */
927
+ syncDestruction() {
928
+ for (const modelSync of this.syncWith) {
929
+ modelSync.syncDestruction(this);
930
+ }
931
+ }
932
+ /**
933
+ * The syncing model (That calls startSyncing) is being embedded in multiple documents of current model
934
+ * I.e Country.syncMany('cities') while current model is City
935
+ */
936
+ static syncMany(columns, embedMethod = "embedData") {
937
+ return new ModelSync.ModelSync(this, columns, embedMethod).syncMany();
938
+ }
939
+ /**
940
+ * Reassociate a model/object/document with the current model
941
+ * If the model is already associated, it will be updated
942
+ * If not, it will be associated
943
+ * the model/document must have an id
944
+ *
945
+ * If it is a model, you can set the embed method to use
946
+ */
947
+ reassociate(column, model, embedWith) {
948
+ const columnValue = model instanceof Model
949
+ ? embedWith
950
+ ? model[embedWith]()
951
+ : model.embeddedData
952
+ : model;
953
+ if (columnValue === undefined)
954
+ return this;
955
+ // make a deep copy so when changing the data, it won't affect the original data
956
+ const documentsList = reinforcements.clone(this.get(column, []));
957
+ const index = documentsList.findIndex((doc) => (doc?.id || doc) === (columnValue?.id || columnValue));
958
+ if (index === -1) {
959
+ documentsList.push(columnValue);
960
+ }
961
+ else {
962
+ documentsList[index] = columnValue;
963
+ }
964
+ this.set(column, [...documentsList]);
965
+ return this;
966
+ }
967
+ /**
968
+ * Associate a model with the current model
969
+ */
970
+ associate(column, model, embedWith) {
971
+ const columnValue = model instanceof Model
972
+ ? embedWith
973
+ ? model[embedWith]()
974
+ : model.embeddedData
975
+ : model;
976
+ if (columnValue === undefined)
977
+ return this;
978
+ const documentsList = this.get(column, []);
979
+ documentsList.push(columnValue);
980
+ this.set(column, documentsList);
981
+ return this;
982
+ }
983
+ /**
984
+ * Disassociate a model with the current model
985
+ */
986
+ disassociate(column, model) {
987
+ const columnValue = model instanceof Model ? model.embeddedData : model;
988
+ if (columnValue === undefined)
989
+ return this;
990
+ const documentsList = this.get(column, []);
991
+ if (!Array.isArray(documentsList))
992
+ return this;
993
+ const index = documentsList.findIndex((doc) => (doc?.id || doc) === (columnValue?.id || columnValue));
994
+ if (index !== -1) {
995
+ documentsList.splice(index, 1);
996
+ }
997
+ this.set(column, documentsList);
998
+ return this;
999
+ }
1000
+ /**
1001
+ * Make a wrapper to list when models should be updated when only one of the given columns is updated
1002
+ */
1003
+ syncUpdateWhenChange(columns, syncModels) {
1004
+ return syncModels.map(syncModel => {
1005
+ syncModel.updateWhenChange(columns);
1006
+ return syncModel;
1007
+ });
1008
+ }
1009
+ /**
1010
+ * Get a Joinable instance for current model
1011
+ */
1012
+ static joinable(localField, foreignField, single, as) {
1013
+ const joinable$1 = new joinable.Joinable(this);
1014
+ if (localField) {
1015
+ joinable$1.localField(localField);
1016
+ }
1017
+ if (foreignField) {
1018
+ joinable$1.foreignField(foreignField);
1019
+ }
1020
+ if (single) {
1021
+ joinable$1.single(single);
1022
+ }
1023
+ if (as) {
1024
+ joinable$1.as(as);
1025
+ }
1026
+ return joinableProxy.joinableProxy(joinable$1);
1027
+ }
1028
+ }exports.Model=Model;//# sourceMappingURL=model.js.map