@autofleet/sadot 1.1.5-beta → 1.1.5

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 (331) hide show
  1. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.cjs +1 -0
  2. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.js +1 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.cjs +1 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.js +1 -0
  5. package/dist/_virtual/rolldown_runtime.cjs +1 -0
  6. package/dist/api/index.cjs +2 -0
  7. package/dist/api/index.cjs.map +1 -0
  8. package/dist/api/index.js +2 -12
  9. package/dist/api/index.js.map +1 -0
  10. package/dist/api/v1/definition/index.cjs +2 -0
  11. package/dist/api/v1/definition/index.cjs.map +1 -0
  12. package/dist/api/v1/definition/index.js +2 -116
  13. package/dist/api/v1/definition/index.js.map +1 -0
  14. package/dist/api/v1/definition/validations.cjs +2 -0
  15. package/dist/api/v1/definition/validations.cjs.map +1 -0
  16. package/dist/api/v1/definition/validations.js +2 -77
  17. package/dist/api/v1/definition/validations.js.map +1 -0
  18. package/dist/api/v1/errors.cjs +2 -0
  19. package/dist/api/v1/errors.cjs.map +1 -0
  20. package/dist/api/v1/errors.js +2 -12
  21. package/dist/api/v1/errors.js.map +1 -0
  22. package/dist/api/v1/index.cjs +2 -0
  23. package/dist/api/v1/index.cjs.map +1 -0
  24. package/dist/api/v1/index.js +2 -13
  25. package/dist/api/v1/index.js.map +1 -0
  26. package/dist/api/v1/validator/index.cjs +2 -0
  27. package/dist/api/v1/validator/index.cjs.map +1 -0
  28. package/dist/api/v1/validator/index.js +2 -143
  29. package/dist/api/v1/validator/index.js.map +1 -0
  30. package/dist/api/v1/validator/validations.cjs +2 -0
  31. package/dist/api/v1/validator/validations.cjs.map +1 -0
  32. package/dist/api/v1/validator/validations.d.cts +23 -0
  33. package/dist/api/v1/validator/validations.d.ts +23 -6
  34. package/dist/api/v1/validator/validations.js +2 -38
  35. package/dist/api/v1/validator/validations.js.map +1 -0
  36. package/dist/errors/index.cjs +3 -0
  37. package/dist/errors/index.cjs.map +1 -0
  38. package/dist/errors/index.js +3 -66
  39. package/dist/errors/index.js.map +1 -0
  40. package/dist/events/index.cjs +2 -0
  41. package/dist/events/index.cjs.map +1 -0
  42. package/dist/events/index.js +2 -54
  43. package/dist/events/index.js.map +1 -0
  44. package/dist/hooks/enrich.cjs +2 -0
  45. package/dist/hooks/enrich.cjs.map +1 -0
  46. package/dist/hooks/enrich.js +2 -198
  47. package/dist/hooks/enrich.js.map +1 -0
  48. package/dist/hooks/find.cjs +2 -0
  49. package/dist/hooks/find.cjs.map +1 -0
  50. package/dist/hooks/find.js +2 -29
  51. package/dist/hooks/find.js.map +1 -0
  52. package/dist/hooks/hooks.cjs +2 -0
  53. package/dist/hooks/hooks.cjs.map +1 -0
  54. package/dist/hooks/hooks.js +2 -388
  55. package/dist/hooks/hooks.js.map +1 -0
  56. package/dist/hooks/index.cjs +1 -0
  57. package/dist/hooks/index.js +1 -17
  58. package/dist/hooks/utils/updateInstanceValues.cjs +2 -0
  59. package/dist/hooks/utils/updateInstanceValues.cjs.map +1 -0
  60. package/dist/hooks/utils/updateInstanceValues.js +2 -50
  61. package/dist/hooks/utils/updateInstanceValues.js.map +1 -0
  62. package/dist/index.cjs +2 -0
  63. package/dist/index.cjs.map +1 -0
  64. package/dist/index.d.cts +23 -0
  65. package/dist/index.d.ts +22 -12
  66. package/dist/index.js +2 -67
  67. package/dist/index.js.map +1 -0
  68. package/dist/models/CustomFieldDefinition.cjs +2 -0
  69. package/dist/models/CustomFieldDefinition.cjs.map +1 -0
  70. package/dist/models/CustomFieldDefinition.d.cts +31 -0
  71. package/dist/models/CustomFieldDefinition.d.ts +29 -23
  72. package/dist/models/CustomFieldDefinition.js +2 -192
  73. package/dist/models/CustomFieldDefinition.js.map +1 -0
  74. package/dist/models/CustomFieldEntries.cjs +2 -0
  75. package/dist/models/CustomFieldEntries.cjs.map +1 -0
  76. package/dist/models/CustomFieldEntries.d.cts +16 -0
  77. package/dist/models/CustomFieldEntries.d.ts +14 -13
  78. package/dist/models/CustomFieldEntries.js +2 -123
  79. package/dist/models/CustomFieldEntries.js.map +1 -0
  80. package/dist/models/CustomFieldValue.cjs +2 -0
  81. package/dist/models/CustomFieldValue.cjs.map +1 -0
  82. package/dist/models/CustomFieldValue.d.cts +22 -0
  83. package/dist/models/CustomFieldValue.d.ts +20 -14
  84. package/dist/models/CustomFieldValue.js +2 -151
  85. package/dist/models/CustomFieldValue.js.map +1 -0
  86. package/dist/models/CustomValidator.cjs +2 -0
  87. package/dist/models/CustomValidator.cjs.map +1 -0
  88. package/dist/models/CustomValidator.d.cts +19 -0
  89. package/dist/models/CustomValidator.d.ts +17 -15
  90. package/dist/models/CustomValidator.js +2 -98
  91. package/dist/models/CustomValidator.js.map +1 -0
  92. package/dist/models/index.cjs +2 -0
  93. package/dist/models/index.cjs.map +1 -0
  94. package/dist/models/index.d.cts +6 -0
  95. package/dist/models/index.d.ts +6 -18
  96. package/dist/models/index.js +2 -131
  97. package/dist/models/index.js.map +1 -0
  98. package/dist/models/tests/AssociatedTestModel.cjs +2 -0
  99. package/dist/models/tests/AssociatedTestModel.cjs.map +1 -0
  100. package/dist/models/tests/AssociatedTestModel.js +2 -71
  101. package/dist/models/tests/AssociatedTestModel.js.map +1 -0
  102. package/dist/models/tests/TestModel.cjs +2 -0
  103. package/dist/models/tests/TestModel.cjs.map +1 -0
  104. package/dist/models/tests/TestModel.js +2 -69
  105. package/dist/models/tests/TestModel.js.map +1 -0
  106. package/dist/models/tests/contextAwareModels/ContextAwareTestModel.cjs +2 -0
  107. package/dist/models/tests/contextAwareModels/ContextAwareTestModel.cjs.map +1 -0
  108. package/dist/models/tests/contextAwareModels/ContextAwareTestModel.js +2 -53
  109. package/dist/models/tests/contextAwareModels/ContextAwareTestModel.js.map +1 -0
  110. package/dist/models/tests/contextAwareModels/ContextTestModel.cjs +2 -0
  111. package/dist/models/tests/contextAwareModels/ContextTestModel.cjs.map +1 -0
  112. package/dist/models/tests/contextAwareModels/ContextTestModel.js +2 -47
  113. package/dist/models/tests/contextAwareModels/ContextTestModel.js.map +1 -0
  114. package/dist/repository/definition.cjs +2 -0
  115. package/dist/repository/definition.cjs.map +1 -0
  116. package/dist/repository/definition.js +2 -121
  117. package/dist/repository/definition.js.map +1 -0
  118. package/dist/repository/entries.cjs +2 -0
  119. package/dist/repository/entries.cjs.map +1 -0
  120. package/dist/repository/entries.js +2 -92
  121. package/dist/repository/entries.js.map +1 -0
  122. package/dist/repository/utils/formatValues.cjs +2 -0
  123. package/dist/repository/utils/formatValues.cjs.map +1 -0
  124. package/dist/repository/utils/formatValues.js +2 -16
  125. package/dist/repository/utils/formatValues.js.map +1 -0
  126. package/dist/repository/validator.cjs +2 -0
  127. package/dist/repository/validator.cjs.map +1 -0
  128. package/dist/repository/validator.js +2 -69
  129. package/dist/repository/validator.js.map +1 -0
  130. package/dist/repository/value.cjs +2 -0
  131. package/dist/repository/value.cjs.map +1 -0
  132. package/dist/repository/value.js +2 -124
  133. package/dist/repository/value.js.map +1 -0
  134. package/dist/scopes/filter.cjs +2 -0
  135. package/dist/scopes/filter.cjs.map +1 -0
  136. package/dist/scopes/filter.d.cts +23 -0
  137. package/dist/scopes/filter.d.ts +22 -29
  138. package/dist/scopes/filter.js +2 -75
  139. package/dist/scopes/filter.js.map +1 -0
  140. package/dist/scopes/helpers/filter.helpers.cjs +46 -0
  141. package/dist/scopes/helpers/filter.helpers.cjs.map +1 -0
  142. package/dist/scopes/helpers/filter.helpers.d.cts +17 -0
  143. package/dist/scopes/helpers/filter.helpers.d.ts +15 -40
  144. package/dist/scopes/helpers/filter.helpers.js +25 -183
  145. package/dist/scopes/helpers/filter.helpers.js.map +1 -0
  146. package/dist/scopes/index.cjs +1 -0
  147. package/dist/scopes/index.js +1 -6
  148. package/dist/types/index.d.cts +45 -0
  149. package/dist/types/index.d.ts +45 -46
  150. package/dist/utils/constants/index.cjs +2 -0
  151. package/dist/utils/constants/index.cjs.map +1 -0
  152. package/dist/utils/constants/index.d.cts +22 -0
  153. package/dist/utils/constants/index.d.ts +20 -17
  154. package/dist/utils/constants/index.js +2 -22
  155. package/dist/utils/constants/index.js.map +1 -0
  156. package/dist/utils/db/index.cjs +2 -0
  157. package/dist/utils/db/index.cjs.map +1 -0
  158. package/dist/utils/db/index.js +2 -24
  159. package/dist/utils/db/index.js.map +1 -0
  160. package/dist/utils/helpers/index.cjs +2 -0
  161. package/dist/utils/helpers/index.cjs.map +1 -0
  162. package/dist/utils/helpers/index.d.cts +31 -0
  163. package/dist/utils/helpers/index.d.ts +28 -23
  164. package/dist/utils/helpers/index.js +2 -40
  165. package/dist/utils/helpers/index.js.map +1 -0
  166. package/dist/utils/init.cjs +2 -0
  167. package/dist/utils/init.cjs.map +1 -0
  168. package/dist/utils/init.js +2 -112
  169. package/dist/utils/init.js.map +1 -0
  170. package/dist/utils/logger/index.cjs +2 -0
  171. package/dist/utils/logger/index.cjs.map +1 -0
  172. package/dist/utils/logger/index.js +2 -42
  173. package/dist/utils/logger/index.js.map +1 -0
  174. package/dist/utils/scopeAttributes.cjs +2 -0
  175. package/dist/utils/scopeAttributes.cjs.map +1 -0
  176. package/dist/utils/scopeAttributes.js +2 -11
  177. package/dist/utils/scopeAttributes.js.map +1 -0
  178. package/dist/utils/validations/index.cjs +2 -0
  179. package/dist/utils/validations/index.cjs.map +1 -0
  180. package/dist/utils/validations/index.js +2 -41
  181. package/dist/utils/validations/index.js.map +1 -0
  182. package/dist/utils/validations/schema/custom-fields.cjs +2 -0
  183. package/dist/utils/validations/schema/custom-fields.cjs.map +1 -0
  184. package/dist/utils/validations/schema/custom-fields.d.cts +7 -0
  185. package/dist/utils/validations/schema/custom-fields.d.ts +6 -2
  186. package/dist/utils/validations/schema/custom-fields.js +2 -9
  187. package/dist/utils/validations/schema/custom-fields.js.map +1 -0
  188. package/dist/utils/validations/schema/validator-schema.cjs +2 -0
  189. package/dist/utils/validations/schema/validator-schema.cjs.map +1 -0
  190. package/dist/utils/validations/schema/validator-schema.js +2 -95
  191. package/dist/utils/validations/schema/validator-schema.js.map +1 -0
  192. package/dist/utils/validations/validators/index.cjs +2 -0
  193. package/dist/utils/validations/validators/index.cjs.map +1 -0
  194. package/dist/utils/validations/validators/index.js +2 -40
  195. package/dist/utils/validations/validators/index.js.map +1 -0
  196. package/dist/utils/validations/validators/select.validator.cjs +2 -0
  197. package/dist/utils/validations/validators/select.validator.cjs.map +1 -0
  198. package/dist/utils/validations/validators/select.validator.js +2 -12
  199. package/dist/utils/validations/validators/select.validator.js.map +1 -0
  200. package/dist/utils/validations/validators/status.validator.cjs +2 -0
  201. package/dist/utils/validations/validators/status.validator.cjs.map +1 -0
  202. package/dist/utils/validations/validators/status.validator.js +2 -15
  203. package/dist/utils/validations/validators/status.validator.js.map +1 -0
  204. package/package.json +40 -39
  205. package/.nvmrc +0 -1
  206. package/dist/api/index.d.ts +0 -3
  207. package/dist/api/v1/definition/index.d.ts +0 -3
  208. package/dist/api/v1/definition/validations.d.ts +0 -2
  209. package/dist/api/v1/errors.d.ts +0 -4
  210. package/dist/api/v1/index.d.ts +0 -3
  211. package/dist/api/v1/validator/index.d.ts +0 -3
  212. package/dist/errors/index.d.ts +0 -24
  213. package/dist/events/index.d.ts +0 -5
  214. package/dist/hooks/create.d.ts +0 -10
  215. package/dist/hooks/create.js +0 -95
  216. package/dist/hooks/enrich.d.ts +0 -25
  217. package/dist/hooks/find.d.ts +0 -1
  218. package/dist/hooks/hooks.d.ts +0 -17
  219. package/dist/hooks/index.d.ts +0 -5
  220. package/dist/hooks/update.d.ts +0 -10
  221. package/dist/hooks/update.js +0 -49
  222. package/dist/hooks/utils/updateInstanceValues.d.ts +0 -15
  223. package/dist/hooks/workaround.d.ts +0 -10
  224. package/dist/hooks/workaround.js +0 -37
  225. package/dist/models/tests/AssociatedTestModel.d.ts +0 -12
  226. package/dist/models/tests/TestModel.d.ts +0 -12
  227. package/dist/models/tests/contextAwareModels/ContextAwareTestModel.d.ts +0 -10
  228. package/dist/models/tests/contextAwareModels/ContextTestModel.d.ts +0 -13
  229. package/dist/repository/definition.d.ts +0 -36
  230. package/dist/repository/entries.d.ts +0 -13
  231. package/dist/repository/utils/formatValues.d.ts +0 -3
  232. package/dist/repository/validator.d.ts +0 -27
  233. package/dist/repository/value.d.ts +0 -28
  234. package/dist/scopes/index.d.ts +0 -2
  235. package/dist/tests/api/test-api.d.ts +0 -2
  236. package/dist/tests/api/test-api.js +0 -38
  237. package/dist/tests/functional/searching/index.d.ts +0 -8
  238. package/dist/tests/functional/searching/index.js +0 -44
  239. package/dist/tests/helpers/commonHooks.d.ts +0 -6
  240. package/dist/tests/helpers/commonHooks.js +0 -62
  241. package/dist/tests/helpers/database-config.d.ts +0 -16
  242. package/dist/tests/helpers/database-config.js +0 -17
  243. package/dist/tests/helpers/index.d.ts +0 -7
  244. package/dist/tests/helpers/index.js +0 -33
  245. package/dist/tests/mocks/definition.mock.d.ts +0 -48
  246. package/dist/tests/mocks/definition.mock.js +0 -78
  247. package/dist/tests/mocks/events.mock.d.ts +0 -4
  248. package/dist/tests/mocks/events.mock.js +0 -21
  249. package/dist/tests/mocks/testModel.d.ts +0 -12
  250. package/dist/tests/mocks/testModel.js +0 -35
  251. package/dist/types/definition/index.d.ts +0 -25
  252. package/dist/types/definition/index.js +0 -2
  253. package/dist/types/entries/index.d.ts +0 -25
  254. package/dist/types/entries/index.js +0 -2
  255. package/dist/types/index.js +0 -2
  256. package/dist/types/value/index.d.ts +0 -15
  257. package/dist/types/value/index.js +0 -2
  258. package/dist/utils/db/index.d.ts +0 -4
  259. package/dist/utils/init.d.ts +0 -7
  260. package/dist/utils/logger/index.d.ts +0 -3
  261. package/dist/utils/scopeAttributes.d.ts +0 -2
  262. package/dist/utils/validations/index.d.ts +0 -8
  263. package/dist/utils/validations/schema/validator-schema.d.ts +0 -9
  264. package/dist/utils/validations/type.d.ts +0 -15
  265. package/dist/utils/validations/type.js +0 -2
  266. package/dist/utils/validations/validators/index.d.ts +0 -14
  267. package/dist/utils/validations/validators/select.validator.d.ts +0 -5
  268. package/dist/utils/validations/validators/status.validator.d.ts +0 -12
  269. package/src/api/index.ts +0 -10
  270. package/src/api/v1/definition/index.ts +0 -104
  271. package/src/api/v1/definition/validations.ts +0 -75
  272. package/src/api/v1/errors.ts +0 -13
  273. package/src/api/v1/index.ts +0 -11
  274. package/src/api/v1/validator/index.ts +0 -141
  275. package/src/api/v1/validator/validations.ts +0 -38
  276. package/src/errors/index.ts +0 -70
  277. package/src/events/index.ts +0 -63
  278. package/src/hooks/create.ts +0 -81
  279. package/src/hooks/enrich.ts +0 -255
  280. package/src/hooks/find.ts +0 -27
  281. package/src/hooks/hooks.ts +0 -482
  282. package/src/hooks/index.ts +0 -20
  283. package/src/hooks/update.ts +0 -55
  284. package/src/hooks/utils/updateInstanceValues.ts +0 -63
  285. package/src/hooks/workaround.ts +0 -47
  286. package/src/index.ts +0 -52
  287. package/src/models/CustomFieldDefinition.ts +0 -162
  288. package/src/models/CustomFieldEntries.ts +0 -81
  289. package/src/models/CustomFieldValue.ts +0 -118
  290. package/src/models/CustomValidator.ts +0 -78
  291. package/src/models/index.ts +0 -165
  292. package/src/models/tests/AssociatedTestModel.ts +0 -57
  293. package/src/models/tests/TestModel.ts +0 -54
  294. package/src/models/tests/contextAwareModels/ContextAwareTestModel.ts +0 -43
  295. package/src/models/tests/contextAwareModels/ContextTestModel.ts +0 -38
  296. package/src/repository/definition.ts +0 -175
  297. package/src/repository/entries.ts +0 -88
  298. package/src/repository/utils/formatValues.ts +0 -14
  299. package/src/repository/validator.ts +0 -104
  300. package/src/repository/value.ts +0 -116
  301. package/src/scopes/filter.ts +0 -100
  302. package/src/scopes/helpers/filter.helpers.ts +0 -227
  303. package/src/scopes/index.ts +0 -6
  304. package/src/tests/api/test-api.ts +0 -40
  305. package/src/tests/functional/searching/index.ts +0 -39
  306. package/src/tests/helpers/commonHooks.ts +0 -43
  307. package/src/tests/helpers/database-config.ts +0 -15
  308. package/src/tests/helpers/index.ts +0 -35
  309. package/src/tests/mocks/definition.mock.ts +0 -84
  310. package/src/tests/mocks/events.mock.ts +0 -21
  311. package/src/tests/mocks/testModel.ts +0 -37
  312. package/src/types/definition/index.ts +0 -24
  313. package/src/types/entries/index.ts +0 -27
  314. package/src/types/index.ts +0 -52
  315. package/src/types/value/index.ts +0 -14
  316. package/src/utils/constants/index.ts +0 -25
  317. package/src/utils/db/index.ts +0 -21
  318. package/src/utils/helpers/index.ts +0 -66
  319. package/src/utils/init.ts +0 -120
  320. package/src/utils/logger/index.ts +0 -14
  321. package/src/utils/scopeAttributes.ts +0 -12
  322. package/src/utils/validations/index.ts +0 -46
  323. package/src/utils/validations/schema/README.md +0 -93
  324. package/src/utils/validations/schema/custom-fields.ts +0 -8
  325. package/src/utils/validations/schema/validator-schema.ts +0 -106
  326. package/src/utils/validations/type.ts +0 -20
  327. package/src/utils/validations/validators/index.ts +0 -38
  328. package/src/utils/validations/validators/select.validator.ts +0 -12
  329. package/src/utils/validations/validators/status.validator.ts +0 -22
  330. package/tsconfig.build.json +0 -7
  331. package/tsconfig.json +0 -16
@@ -0,0 +1,2 @@
1
+ const e=require(`../_virtual/rolldown_runtime.cjs`),t=require(`../utils/logger/index.cjs`),n=require(`../utils/constants/index.cjs`),r=require(`../errors/index.cjs`),i=require(`../repository/definition.cjs`),a=require(`../repository/validator.cjs`),o=require(`../utils/scopeAttributes.cjs`),s=require(`./utils/updateInstanceValues.cjs`);let c=require(`joi`);c=e.__toESM(c);let l=require(`@autofleet/errors`),u=require(`ajv`);u=e.__toESM(u);let d=require(`ajv-formats`);d=e.__toESM(d);let f=require(`ajv-errors`);f=e.__toESM(f);const p=[`id`,`schema`,`modelType`,`entityId`,`disabled`],m=new u.default({allErrors:!0,strict:!1,strictTypes:!1,$data:!0});(0,d.default)(m),(0,f.default)(m);const h=(e,t)=>({__proto__:null,...e,...t}),g=async(e,n)=>{if(!e.id||!e.customFields||Object.keys(e.customFields).length===0)return e.customFields||{};try{let r=await e.constructor.findOne({where:{id:e.id},attributes:[`customFields`],transaction:n.transaction,raw:!0});if(r?.customFields){let n=h(r.customFields,e.customFields);return t.default.debug(`sadot - fetched complete custom fields for validation`,{fieldsCount:Object.keys(n).length,updateFieldsCount:Object.keys(e.customFields).length}),n}}catch(e){t.default.error(`sadot - error fetching complete model for validation`,{error:e})}return e.customFields||{}},_=e=>{let t={...e.dataValues};(e.changed?.()||[]).forEach(n=>{let r=e.previous?.(n);r!==void 0&&(t[n]=r)});let n=e.previous?.(`customFields`);return n!==void 0&&(t.customFields=n),t},v=e=>e.reduce((e,t)=>{let n=((t.instancePath||``).split(`/`).filter(Boolean).join(`.`).replace(/^after\./,``)+(t.keyword===`required`?`.${t.params?.missingProperty}`:``)).replace(/^\./,``)||`root`;return e[n]=t.message||`Invalid value`,e},{}),y=async(e,n,r,i={},s=!1)=>{let c=e.constructor.name;t.default.debug(`sadot - validating model`,{isCreate:s,modelType:c});let u=o.default(e,r);if(t.default.debug(`sadot - identifiers`,{identifiers:u}),!u||Object.keys(u).length===0){t.default.debug(`sadot - skipping validation: no identifiers`);return}let d=Object.values(u)[0];if(t.default.debug(`sadot - entityId`,{entityId:d}),!d){t.default.debug(`sadot - skipping validation: no entityId`);return}let f,y;n.transaction&&(n.transaction.validationsCache??=new Map,y=`${c}-${d}`,f=n.transaction.validationsCache.get(y)),f||(f=a.findAllByModelType(c,d,{transaction:n.transaction,attributes:p,modelOptions:i}),n.transaction&&n?.transaction?.validationsCache.set(y,f));let b=await f;if(t.default.debug(`sadot - validators found`,{count:b.length}),!b.length){t.default.debug(`sadot - skipping validation: no validators found`);return}let x=null;s||(x=_(e));let S=s?e.customFields||{}:await g(e,n);for(let n of b){let{schema:r}=n,i=r;if(t.default.debug(`sadot - validating with schema`,{schema:r,hasAfterProps:!!i.properties?.after,hasBeforeProps:!!i.properties?.before}),s){if(i.properties?.after){let t=m.compile({...r,properties:{after:i.properties.after}});if(!t(JSON.parse(JSON.stringify({after:{...e.dataValues,customFields:S}})))){let e=t.errors?.map(e=>`${e.instancePath||``} ${e.message||`Invalid value`}`).join(`, `),n=v(t.errors);throw new l.BadRequest([Error(`Validation failed for ${c}: ${e}`)],void 0,{customError:n})}}}else{let n=m.compile(i),r=h(e.dataValues);r.customFields=S;let a={before:x,after:r},o=n(JSON.parse(JSON.stringify(a)));if(t.default.debug(`sadot - validation result`,{isValid:o,test:{before:x,after:r}}),!o){let e=n.errors?.map(e=>`${e.instancePath||``} ${e.message||`Invalid value`}`).join(`, `),t=v(n.errors);throw new l.BadRequest([Error(`Validation failed for ${c}: ${e}`)],void 0,{customError:t})}}}},b=async({modelType:e,modelOptions:t,identifiers:n,options:r})=>{let{include:a,useEntityIdFromInclude:o}=t,s={modelType:e,disabled:!1,...!o&&{entityId:n}};return await i.findAll(s,{withDisabled:!1,transaction:r.transaction,include:a?.(n)})},x=(e,t)=>{(e||[]).forEach(e=>{let{fieldType:i,name:a}=e;if([n.CustomFieldDefinitionType.DATE,n.CustomFieldDefinitionType.DATETIME].includes(i)){let e=t.customFields?.[a];if(e){let{value:n,error:i}=c.default.date().validate(e);if(i)throw new r.InvalidValueError(e,a,i);t.customFields[a]=n.toISOString()}}})},S=(e,n={},i={useCustomFieldsEntries:!1})=>async(a,c)=>{t.default.debug(`sadot - before create hook`);let{fields:l}=c,u=a.constructor.name,d=o.default(a,e),f=await b({modelType:u,modelOptions:n,identifiers:d,options:c}),p=f.filter(e=>![null,void 0].includes(e.defaultValue));p.length&&(a.customFields||={},p.filter(e=>a.customFields?.[e.name]===void 0).forEach(({name:e,defaultValue:t})=>{a.customFields[e]=t}));let m=Array.from(new Set(f.filter(({required:e})=>e).map(({name:e})=>e))),{customFields:h}=a,g=Object.keys(h??{}),_=m.filter(e=>!g.includes(e));if(_?.length)throw new r.MissingRequiredCustomFieldError(_);await y(a,c,e,n,!0),x(f,a);let v=l.indexOf(`customFields`);v===-1||!h||!Object.keys(h).length||(await s.default({modelId:a.id,modelType:u,identifiers:d,customFields:h,options:{useCustomFieldsEntries:i.useCustomFieldsEntries,transaction:c.transaction,modelOptions:n}}),l.splice(v,1))},C=(e,n={},r={useCustomFieldsEntries:!1})=>async(i,a)=>{t.default.debug(`sadot - before update hook`);let{fields:c}=a,l=i.constructor.name,u=o.default(i,e),d=await b({modelType:l,modelOptions:n,identifiers:u,options:a});await y(i,a,e,n,!1),x(d,i);let f=c.indexOf(`customFields`);if(f>-1){let{customFields:e}=i;if(!Object.keys(e).length)return;await s.default({modelId:i.id,modelType:l,identifiers:u,customFields:e,options:{useCustomFieldsEntries:r.useCustomFieldsEntries,transaction:a.transaction,modelOptions:n}}),c.splice(f,1)}},w=e=>{e.individualHooks=!0},T=e=>{e.individualHooks=!0};exports.beforeBulkCreate=w,exports.beforeBulkUpdate=T,exports.beforeCreate=S,exports.beforeUpdate=C;
2
+ //# sourceMappingURL=hooks.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.cjs","names":["ajv","Ajv","beforeFull: any","applyScopeToInstance","cacheKey: string | undefined","BadRequest","where: WhereOptions","CustomFieldDefinitionType","Joi","InvalidValueError","MissingRequiredCustomFieldError","updateInstanceValues"],"sources":["../../src/hooks/hooks.ts"],"sourcesContent":["import type {\n BulkCreateOptions, CreateOptions, Transactionable, UpdateOptions, WhereOptions,\n} from 'sequelize';\nimport Ajv from 'ajv';\nimport Joi from 'joi';\nimport addFormats from 'ajv-formats';\nimport { BadRequest } from '@autofleet/errors';\nimport ajvErrors from 'ajv-errors';\nimport logger from '../utils/logger';\nimport * as ValidatorRepo from '../repository/validator';\nimport * as DefinitionRepo from '../repository/definition';\nimport { InvalidValueError, MissingRequiredCustomFieldError } from '../errors';\nimport type { CustomFieldOptions, ModelOptions, TransactionOptions } from '../types';\nimport applyScopeToInstance from '../utils/scopeAttributes';\nimport updateInstanceValues from './utils/updateInstanceValues';\nimport { CustomFieldDefinitionType } from '../utils/constants';\nimport type { CustomFieldDefinition } from '../models';\n\n// Include all required fields for proper validation\nconst CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL = ['id', 'schema', 'modelType', 'entityId', 'disabled'];\n\n// Initialize Ajv with relaxed settings to avoid warnings\nconst ajv = new Ajv({\n allErrors: true,\n strict: false, // Disable strict mode to avoid warnings\n strictTypes: false, // Disable strict type checking\n $data: true, // Enable $data references\n});\n\naddFormats(ajv);\najvErrors(ajv);\n\n/**\n * Helper function to manually copy object properties\n * This is more efficient for large objects and avoids excessive object creation\n */\nconst manualObjectCopy = (sourceObj: Record<string, any>, additionalProps?: Record<string, any>): Record<string, any> =>\n ({ __proto__: null, ...sourceObj, ...additionalProps });\n\n/**\n * Fetches complete custom fields for an instance by merging DB values with update values\n * This is needed for partial updates to ensure all related fields are available for validation\n */\nconst getCompleteCustomFields = async (instance: any, options: Transactionable): Promise<Record<string, any>> => {\n // If we don't have an instance id or no custom fields being updated, return original fields\n if (!instance.id || !instance.customFields || Object.keys(instance.customFields).length === 0) {\n return instance.customFields || {};\n }\n\n try {\n const ModelClass = instance.constructor;\n // Only select the customFields column to minimize data transfer\n const currentCustomFields = await ModelClass.findOne({\n where: { id: instance.id },\n attributes: ['customFields'],\n transaction: options.transaction,\n raw: true, // Get plain object instead of model instance for better performance\n });\n\n if (currentCustomFields?.customFields) {\n // Merge existing fields with update fields using our helper function\n const completeFields = manualObjectCopy(\n currentCustomFields.customFields,\n instance.customFields,\n );\n\n logger.debug('sadot - fetched complete custom fields for validation', {\n fieldsCount: Object.keys(completeFields).length,\n updateFieldsCount: Object.keys(instance.customFields).length,\n });\n\n return completeFields;\n }\n } catch (error) {\n logger.error('sadot - error fetching complete model for validation', { error });\n // Continue with partial data if we can't fetch the complete model\n }\n\n return instance.customFields || {};\n};\n\nconst buildPreChangeState = (instance: any) => {\n const beforeFull: any = { ...instance.dataValues };\n\n const changedKeys: string[] = instance.changed?.() || [];\n changedKeys.forEach((key) => {\n const prevVal = instance.previous?.(key);\n if (prevVal !== undefined) {\n beforeFull[key] = prevVal;\n }\n });\n\n const prevCF = instance.previous?.('customFields');\n if (prevCF !== undefined) {\n beforeFull.customFields = prevCF;\n }\n\n return beforeFull;\n};\n\nconst formatAjvErrors = (\n errors: {\n instancePath?: string;\n keyword: string;\n message?: string;\n params?: Record<string, any>;\n }[],\n): Record<string, string> => errors.reduce((acc, err) => {\n const basePath = (err.instancePath || '')\n .split('/')\n .filter(Boolean)\n .join('.')\n .replace(/^after\\./, '');\n\n const missingProp = err.keyword === 'required' ? `.${err.params?.missingProperty}` : '';\n const key = (basePath + missingProp).replace(/^\\./, '') || 'root';\n\n const message = err.message || 'Invalid value';\n acc[key] = message;\n\n return acc;\n}, {} as Record<string, string>);\n\n/**\n * Validates the model using custom validators\n */\nconst validateModel = async (\n instance: any,\n options: TransactionOptions,\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n isCreate = false,\n): Promise<void> => {\n const modelType = instance.constructor.name;\n\n logger.debug('sadot - validating model', { isCreate, modelType });\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n logger.debug('sadot - identifiers', { identifiers });\n\n // Skip if no identifiers\n if (!identifiers || Object.keys(identifiers).length === 0) {\n logger.debug('sadot - skipping validation: no identifiers');\n return;\n }\n\n // Find the entityId from identifiers (fleetId, businessModelId, etc.)\n const entityId = Object.values(identifiers)[0]; // Get the first value as entityId\n\n logger.debug('sadot - entityId', { entityId });\n\n if (!entityId) {\n logger.debug('sadot - skipping validation: no entityId');\n return;\n }\n\n let validatorsPromise;\n let cacheKey: string | undefined;\n if (options.transaction) {\n options.transaction.validationsCache ??= new Map();\n cacheKey = `${modelType}-${entityId}`;\n validatorsPromise = options.transaction.validationsCache.get(cacheKey);\n }\n\n if (!validatorsPromise) {\n validatorsPromise = ValidatorRepo.findAllByModelType(\n modelType,\n entityId,\n {\n transaction: options.transaction,\n attributes: CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL,\n modelOptions,\n },\n );\n if (options.transaction) {\n options?.transaction?.validationsCache!.set(cacheKey!, validatorsPromise);\n }\n }\n const validators = await validatorsPromise;\n\n logger.debug('sadot - validators found', { count: validators.length });\n\n if (!validators.length) {\n logger.debug('sadot - skipping validation: no validators found');\n return;\n }\n\n // For updates, get the previous values\n let originalValues = null;\n if (!isCreate) {\n originalValues = buildPreChangeState(instance);\n }\n\n // Get complete custom fields by merging DB values with update values\n // This is especially important for partial updates to ensure all related fields are available\n const completeCustomFields = !isCreate\n ? await getCompleteCustomFields(instance, options)\n : instance.customFields || {};\n\n for (const validator of validators) {\n const { schema } = validator;\n const typedSchema = schema as Record<string, any>;\n\n logger.debug('sadot - validating with schema', {\n schema,\n hasAfterProps: !!typedSchema.properties?.after,\n hasBeforeProps: !!typedSchema.properties?.before,\n });\n\n if (isCreate) {\n // For create operations, we only need the 'after' state\n if (typedSchema.properties?.after) {\n const validateSchema = ajv.compile({\n ...schema,\n // Focus only on the 'after' validation part for create\n properties: {\n after: typedSchema.properties.after,\n },\n });\n\n const isValid = validateSchema(JSON.parse(JSON.stringify({\n after: {\n ...instance.dataValues,\n customFields: completeCustomFields,\n },\n })));\n\n if (!isValid) {\n const errorDetails = validateSchema.errors?.map(err =>\n `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n } else {\n // For update operations, we need both before and after\n const validateSchema = ajv.compile(typedSchema);\n\n // Create after object with our helper function\n const afterObj = manualObjectCopy(instance.dataValues);\n\n // Add complete custom fields\n afterObj.customFields = completeCustomFields;\n\n // Create validation payload\n const payload = {\n before: originalValues,\n after: afterObj,\n };\n\n // Validate\n const isValid = validateSchema(JSON.parse(JSON.stringify(payload)));\n\n logger.debug('sadot - validation result', {\n isValid,\n test: {\n before: originalValues,\n after: afterObj,\n },\n });\n\n if (!isValid) {\n const errorDetails = validateSchema\n .errors\n ?.map(err => `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n }\n};\n\nconst getFieldDefinitions = async ({\n modelType,\n modelOptions,\n identifiers,\n options,\n}: {\n modelType: any;\n modelOptions: ModelOptions;\n identifiers: any[];\n options: any;\n}) => {\n const { include, useEntityIdFromInclude } = modelOptions;\n const where: WhereOptions = {\n modelType,\n disabled: false,\n ...(!useEntityIdFromInclude && { entityId: identifiers }),\n };\n\n const fieldDefinitions = await DefinitionRepo.findAll(where, {\n withDisabled: false,\n transaction: options.transaction,\n include: include?.(identifiers),\n });\n return fieldDefinitions;\n};\n\nconst formatDates = (fieldDefinitions: CustomFieldDefinition[], instance: any) => {\n (fieldDefinitions || []).forEach((fieldDefinition) => {\n const { fieldType, name } = fieldDefinition;\n if ([CustomFieldDefinitionType.DATE, CustomFieldDefinitionType.DATETIME].includes(fieldType)) {\n const value = instance.customFields?.[name];\n if (value) {\n const { value: joiValue, error: validationError } = Joi.date().validate(value);\n if (validationError) {\n throw new InvalidValueError(value, name, validationError);\n }\n instance.customFields[name] = joiValue.toISOString();\n }\n }\n });\n};\n\n/**\n * Hook to handle validation and custom fields during creation\n */\nexport const beforeCreate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries'> = { useCustomFieldsEntries: false },\n) => async (\n instance: any,\n options: CreateOptions,\n): Promise<void> => {\n logger.debug('sadot - before create hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n // Step 1: Handle custom fields default values and required fields\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options,\n });\n\n // Apply default values\n const fieldsWithDefaultValue = fieldDefinitions.filter(def => ![null, undefined].includes(def.defaultValue));\n if (fieldsWithDefaultValue.length) {\n instance.customFields ||= {};\n fieldsWithDefaultValue\n .filter(def => (instance.customFields?.[def.name] === undefined))\n .forEach(({ name, defaultValue }) => {\n instance.customFields[name] = defaultValue;\n });\n }\n\n // Check for required fields\n const requiredFieldsNames = Array.from(\n new Set(fieldDefinitions.filter(({ required }) => required).map(({ name }) => name)),\n );\n const { customFields } = instance;\n const fieldsNames = Object.keys(customFields ?? {});\n const missingFields = requiredFieldsNames.filter(name => !fieldsNames.includes(name));\n if (missingFields?.length) {\n throw new MissingRequiredCustomFieldError(missingFields);\n }\n\n // Step 2: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, true);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 3: Save custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx === -1 || !customFields || !Object.keys(customFields).length) {\n // No custom fields to update\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n};\n\n/**\n * Hook to handle validation and custom fields during update\n */\nexport const beforeUpdate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries'> = { useCustomFieldsEntries: false },\n) => async (\n instance: any,\n options: UpdateOptions,\n): Promise<void> => {\n logger.debug('sadot - before update hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options,\n });\n\n // Step 1: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, false);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 2: Update custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx > -1) {\n const { customFields } = instance;\n\n if (!Object.keys(customFields).length) {\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n }\n};\n\n/**\n * Hook to enable individual hooks for bulk create operations\n */\nexport const beforeBulkCreate = (options: BulkCreateOptions): void => {\n // This will activate the beforeCreate hook on each instance\n options.individualHooks = true;\n};\n\n/**\n * Hook to enable individual hooks for bulk update operations\n */\nexport const beforeBulkUpdate = (options: UpdateOptions): void => {\n // This will activate the beforeUpdate hook on each instance\n options.individualHooks = true;\n};\n"],"mappings":"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"}
@@ -1,388 +1,2 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.beforeBulkUpdate = exports.beforeBulkCreate = exports.beforeUpdate = exports.beforeCreate = void 0;
30
- const ajv_1 = __importDefault(require("ajv"));
31
- const joi_1 = __importDefault(require("joi"));
32
- const ajv_formats_1 = __importDefault(require("ajv-formats"));
33
- const errors_1 = require("@autofleet/errors");
34
- const ajv_errors_1 = __importDefault(require("ajv-errors"));
35
- const logger_1 = __importDefault(require("../utils/logger"));
36
- const ValidatorRepo = __importStar(require("../repository/validator"));
37
- const DefinitionRepo = __importStar(require("../repository/definition"));
38
- const errors_2 = require("../errors");
39
- const scopeAttributes_1 = __importDefault(require("../utils/scopeAttributes"));
40
- const updateInstanceValues_1 = __importDefault(require("./utils/updateInstanceValues"));
41
- const constants_1 = require("../utils/constants");
42
- // Include all required fields for proper validation
43
- const CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL = ['id', 'schema', 'modelType', 'entityId', 'disabled'];
44
- // Initialize Ajv with relaxed settings to avoid warnings
45
- const ajv = new ajv_1.default({
46
- allErrors: true,
47
- strict: false, // Disable strict mode to avoid warnings
48
- strictTypes: false, // Disable strict type checking
49
- $data: true, // Enable $data references
50
- });
51
- (0, ajv_formats_1.default)(ajv);
52
- (0, ajv_errors_1.default)(ajv);
53
- /**
54
- * Helper function to manually copy object properties
55
- * This is more efficient for large objects and avoids excessive object creation
56
- */
57
- // eslint-disable-next-line prefer-object-spread
58
- const manualObjectCopy = (sourceObj, additionalProps) => ({ __proto__: null, ...sourceObj, ...additionalProps });
59
- /**
60
- * Fetches complete custom fields for an instance by merging DB values with update values
61
- * This is needed for partial updates to ensure all related fields are available for validation
62
- */
63
- const getCompleteCustomFields = async (instance, options) => {
64
- // If we don't have an instance id or no custom fields being updated, return original fields
65
- if (!instance.id || !instance.customFields || Object.keys(instance.customFields).length === 0) {
66
- return instance.customFields || {};
67
- }
68
- try {
69
- const ModelClass = instance.constructor;
70
- // Only select the customFields column to minimize data transfer
71
- const currentCustomFields = await ModelClass.findOne({
72
- where: { id: instance.id },
73
- attributes: ['customFields'],
74
- transaction: options.transaction,
75
- raw: true, // Get plain object instead of model instance for better performance
76
- });
77
- if (currentCustomFields?.customFields) {
78
- // Merge existing fields with update fields using our helper function
79
- const completeFields = manualObjectCopy(currentCustomFields.customFields, instance.customFields);
80
- logger_1.default.debug('sadot - fetched complete custom fields for validation', {
81
- fieldsCount: Object.keys(completeFields).length,
82
- updateFieldsCount: Object.keys(instance.customFields).length,
83
- });
84
- return completeFields;
85
- }
86
- }
87
- catch (error) {
88
- logger_1.default.error('sadot - error fetching complete model for validation', { error });
89
- // Continue with partial data if we can't fetch the complete model
90
- }
91
- return instance.customFields || {};
92
- };
93
- const buildPreChangeState = (instance) => {
94
- const beforeFull = { ...instance.dataValues };
95
- const changedKeys = instance.changed?.() || [];
96
- changedKeys.forEach((key) => {
97
- const prevVal = instance.previous?.(key);
98
- if (prevVal !== undefined) {
99
- beforeFull[key] = prevVal;
100
- }
101
- });
102
- const prevCF = instance.previous?.('customFields');
103
- if (prevCF !== undefined) {
104
- beforeFull.customFields = prevCF;
105
- }
106
- return beforeFull;
107
- };
108
- const formatAjvErrors = (errors) => errors.reduce((acc, err) => {
109
- const basePath = (err.instancePath || '')
110
- .split('/')
111
- .filter(Boolean)
112
- .join('.')
113
- .replace(/^after\./, '');
114
- const missingProp = err.keyword === 'required' ? `.${err.params?.missingProperty}` : '';
115
- const key = (basePath + missingProp).replace(/^\./, '') || 'root';
116
- const message = err.message || 'Invalid value';
117
- acc[key] = message;
118
- return acc;
119
- }, {});
120
- /**
121
- * Validates the model using custom validators
122
- */
123
- const validateModel = async (instance, options, scopeAttributes, modelOptions = {}, isCreate = false) => {
124
- var _a;
125
- const modelType = instance.constructor.name;
126
- logger_1.default.debug('sadot - validating model', { isCreate, modelType });
127
- const identifiers = (0, scopeAttributes_1.default)(instance, scopeAttributes);
128
- logger_1.default.debug('sadot - identifiers', { identifiers });
129
- // Skip if no identifiers
130
- if (!identifiers || Object.keys(identifiers).length === 0) {
131
- logger_1.default.debug('sadot - skipping validation: no identifiers');
132
- return;
133
- }
134
- // Find the entityId from identifiers (fleetId, businessModelId, etc.)
135
- const entityId = Object.values(identifiers)[0]; // Get the first value as entityId
136
- logger_1.default.debug('sadot - entityId', { entityId });
137
- if (!entityId) {
138
- logger_1.default.debug('sadot - skipping validation: no entityId');
139
- return;
140
- }
141
- let validatorsPromise;
142
- let cacheKey;
143
- if (options.transaction) {
144
- // eslint-disable-next-line no-param-reassign
145
- (_a = options.transaction).validationsCache || (_a.validationsCache = new Map());
146
- cacheKey = `${modelType}-${entityId}`;
147
- validatorsPromise = options.transaction.validationsCache.get(cacheKey);
148
- }
149
- if (!validatorsPromise) {
150
- validatorsPromise = ValidatorRepo.findAllByModelType(modelType, entityId, {
151
- transaction: options.transaction,
152
- attributes: CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL,
153
- modelOptions,
154
- });
155
- if (options.transaction) {
156
- options?.transaction?.validationsCache.set(cacheKey, validatorsPromise);
157
- }
158
- }
159
- const validators = await validatorsPromise;
160
- logger_1.default.debug('sadot - validators found', { count: validators.length });
161
- if (!validators.length) {
162
- logger_1.default.debug('sadot - skipping validation: no validators found');
163
- return;
164
- }
165
- // For updates, get the previous values
166
- let originalValues = null;
167
- if (!isCreate) {
168
- originalValues = buildPreChangeState(instance);
169
- }
170
- // Get complete custom fields by merging DB values with update values
171
- // This is especially important for partial updates to ensure all related fields are available
172
- const completeCustomFields = !isCreate
173
- ? await getCompleteCustomFields(instance, options)
174
- : instance.customFields || {};
175
- // eslint-disable-next-line no-restricted-syntax
176
- for (const validator of validators) {
177
- const { schema } = validator;
178
- const typedSchema = schema;
179
- logger_1.default.debug('sadot - validating with schema', {
180
- schema,
181
- hasAfterProps: !!typedSchema.properties?.after,
182
- hasBeforeProps: !!typedSchema.properties?.before,
183
- });
184
- if (isCreate) {
185
- // For create operations, we only need the 'after' state
186
- if (typedSchema.properties?.after) {
187
- const validateSchema = ajv.compile({
188
- ...schema,
189
- // Focus only on the 'after' validation part for create
190
- properties: {
191
- after: typedSchema.properties.after,
192
- },
193
- });
194
- const isValid = validateSchema(JSON.parse(JSON.stringify({
195
- after: {
196
- ...instance.dataValues,
197
- customFields: completeCustomFields,
198
- },
199
- })));
200
- if (!isValid) {
201
- const errorDetails = validateSchema.errors?.map((err) => `${err.instancePath || ''} ${err.message || 'Invalid value'}`).join(', ');
202
- const formattedErrors = formatAjvErrors(validateSchema.errors);
203
- throw new errors_1.BadRequest([new Error(`Validation failed for ${modelType}: ${errorDetails}`)], undefined, {
204
- customError: formattedErrors,
205
- });
206
- }
207
- }
208
- }
209
- else {
210
- // For update operations, we need both before and after
211
- const validateSchema = ajv.compile(typedSchema);
212
- // Create after object with our helper function
213
- const afterObj = manualObjectCopy(instance.dataValues);
214
- // Add complete custom fields
215
- afterObj.customFields = completeCustomFields;
216
- // Create validation payload
217
- const payload = {
218
- before: originalValues,
219
- after: afterObj,
220
- };
221
- // Validate
222
- const isValid = validateSchema(JSON.parse(JSON.stringify(payload)));
223
- logger_1.default.debug('sadot - validation result', {
224
- isValid,
225
- test: {
226
- before: originalValues,
227
- after: afterObj,
228
- },
229
- });
230
- if (!isValid) {
231
- const errorDetails = validateSchema
232
- .errors
233
- ?.map((err) => `${err.instancePath || ''} ${err.message || 'Invalid value'}`).join(', ');
234
- const formattedErrors = formatAjvErrors(validateSchema.errors);
235
- throw new errors_1.BadRequest([new Error(`Validation failed for ${modelType}: ${errorDetails}`)], undefined, {
236
- customError: formattedErrors,
237
- });
238
- }
239
- }
240
- }
241
- };
242
- const getFieldDefinitions = async ({ modelType, modelOptions, identifiers, options, }) => {
243
- const { include, useEntityIdFromInclude } = modelOptions;
244
- const where = {
245
- modelType,
246
- disabled: false,
247
- ...(!useEntityIdFromInclude && { entityId: identifiers }),
248
- };
249
- const fieldDefinitions = await DefinitionRepo.findAll(where, {
250
- withDisabled: false,
251
- transaction: options.transaction,
252
- include: include?.(identifiers),
253
- });
254
- return fieldDefinitions;
255
- };
256
- const formatDates = (fieldDefinitions, instance) => {
257
- (fieldDefinitions || []).forEach((fieldDefinition) => {
258
- const { fieldType, name } = fieldDefinition;
259
- if ([constants_1.CustomFieldDefinitionType.DATE, constants_1.CustomFieldDefinitionType.DATETIME].includes(fieldType)) {
260
- const value = instance.customFields?.[name];
261
- if (value) {
262
- const { value: joiValue, error: validationError } = joi_1.default.date().validate(value);
263
- if (validationError) {
264
- throw new errors_2.InvalidValueError(value, name, validationError);
265
- }
266
- // eslint-disable-next-line no-param-reassign
267
- instance.customFields[name] = joiValue.toISOString();
268
- }
269
- }
270
- });
271
- };
272
- /**
273
- * Hook to handle validation and custom fields during creation
274
- */
275
- const beforeCreate = (scopeAttributes, modelOptions = {}, sadotOptions = { useCustomFieldsEntries: false }) => async (instance, options) => {
276
- logger_1.default.debug('sadot - before create hook');
277
- const { fields } = options;
278
- const modelType = instance.constructor.name;
279
- const identifiers = (0, scopeAttributes_1.default)(instance, scopeAttributes);
280
- // Step 1: Handle custom fields default values and required fields
281
- const fieldDefinitions = await getFieldDefinitions({
282
- modelType, modelOptions, identifiers, options,
283
- });
284
- // Apply default values
285
- const fieldsWithDefaultValue = fieldDefinitions.filter((def) => ![null, undefined].includes(def.defaultValue));
286
- if (fieldsWithDefaultValue.length) {
287
- // eslint-disable-next-line no-param-reassign
288
- instance.customFields || (instance.customFields = {});
289
- fieldsWithDefaultValue
290
- .filter((def) => (instance.customFields?.[def.name] === undefined))
291
- .forEach(({ name, defaultValue }) => {
292
- // eslint-disable-next-line no-param-reassign
293
- instance.customFields[name] = defaultValue;
294
- });
295
- }
296
- // Check for required fields
297
- const requiredFieldsNames = Array.from(new Set(fieldDefinitions.filter(({ required }) => required).map(({ name }) => name)));
298
- const { customFields } = instance;
299
- const fieldsNames = Object.keys(customFields ?? {});
300
- const missingFields = requiredFieldsNames.filter((name) => !fieldsNames.includes(name));
301
- if (missingFields?.length) {
302
- throw new errors_2.MissingRequiredCustomFieldError(missingFields);
303
- }
304
- // Step 2: Validate the model data (including custom fields)
305
- await validateModel(instance, options, scopeAttributes, modelOptions, true);
306
- // format date and datetime fields
307
- formatDates(fieldDefinitions, instance);
308
- // Step 3: Save custom field values if they exist
309
- const customFieldsIdx = fields.indexOf('customFields');
310
- if (customFieldsIdx === -1 || !customFields || !Object.keys(customFields).length) {
311
- // No custom fields to update
312
- return;
313
- }
314
- // Save custom field values
315
- await (0, updateInstanceValues_1.default)({
316
- modelId: instance.id,
317
- modelType,
318
- identifiers,
319
- customFields,
320
- options: {
321
- useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,
322
- transaction: options.transaction,
323
- modelOptions,
324
- },
325
- });
326
- // Remove customFields from fields array after handling
327
- // eslint-disable-next-line no-param-reassign
328
- fields.splice(customFieldsIdx, 1);
329
- };
330
- exports.beforeCreate = beforeCreate;
331
- /**
332
- * Hook to handle validation and custom fields during update
333
- */
334
- const beforeUpdate = (scopeAttributes, modelOptions = {}, sadotOptions = { useCustomFieldsEntries: false }) => async (instance, options) => {
335
- logger_1.default.debug('sadot - before update hook');
336
- const { fields } = options;
337
- const modelType = instance.constructor.name;
338
- const identifiers = (0, scopeAttributes_1.default)(instance, scopeAttributes);
339
- const fieldDefinitions = await getFieldDefinitions({
340
- modelType, modelOptions, identifiers, options,
341
- });
342
- // Step 1: Validate the model data (including custom fields)
343
- await validateModel(instance, options, scopeAttributes, modelOptions, false);
344
- // format date and datetime fields
345
- formatDates(fieldDefinitions, instance);
346
- // Step 2: Update custom field values if they exist
347
- const customFieldsIdx = fields.indexOf('customFields');
348
- if (customFieldsIdx > -1) {
349
- const { customFields } = instance;
350
- if (!Object.keys(customFields).length) {
351
- return;
352
- }
353
- // Save custom field values
354
- await (0, updateInstanceValues_1.default)({
355
- modelId: instance.id,
356
- modelType,
357
- identifiers,
358
- customFields,
359
- options: {
360
- useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,
361
- transaction: options.transaction,
362
- modelOptions,
363
- },
364
- });
365
- // Remove customFields from fields array after handling
366
- // eslint-disable-next-line no-param-reassign
367
- fields.splice(customFieldsIdx, 1);
368
- }
369
- };
370
- exports.beforeUpdate = beforeUpdate;
371
- /**
372
- * Hook to enable individual hooks for bulk create operations
373
- */
374
- const beforeBulkCreate = (options) => {
375
- // This will activate the beforeCreate hook on each instance
376
- // eslint-disable-next-line no-param-reassign
377
- options.individualHooks = true;
378
- };
379
- exports.beforeBulkCreate = beforeBulkCreate;
380
- /**
381
- * Hook to enable individual hooks for bulk update operations
382
- */
383
- const beforeBulkUpdate = (options) => {
384
- // This will activate the beforeUpdate hook on each instance
385
- // eslint-disable-next-line no-param-reassign
386
- options.individualHooks = true;
387
- };
388
- exports.beforeBulkUpdate = beforeBulkUpdate;
1
+ import e from"../utils/logger/index.js";import{CustomFieldDefinitionType as t}from"../utils/constants/index.js";import{InvalidValueError as n,MissingRequiredCustomFieldError as r}from"../errors/index.js";import{findAll as i}from"../repository/definition.js";import{findAllByModelType as a}from"../repository/validator.js";import o from"../utils/scopeAttributes.js";import s from"./utils/updateInstanceValues.js";import c from"joi";import{BadRequest as l}from"@autofleet/errors";import u from"ajv";import d from"ajv-formats";import f from"ajv-errors";const p=[`id`,`schema`,`modelType`,`entityId`,`disabled`],m=new u({allErrors:!0,strict:!1,strictTypes:!1,$data:!0});d(m),f(m);const h=(e,t)=>({__proto__:null,...e,...t}),g=async(t,n)=>{if(!t.id||!t.customFields||Object.keys(t.customFields).length===0)return t.customFields||{};try{let r=await t.constructor.findOne({where:{id:t.id},attributes:[`customFields`],transaction:n.transaction,raw:!0});if(r?.customFields){let n=h(r.customFields,t.customFields);return e.debug(`sadot - fetched complete custom fields for validation`,{fieldsCount:Object.keys(n).length,updateFieldsCount:Object.keys(t.customFields).length}),n}}catch(t){e.error(`sadot - error fetching complete model for validation`,{error:t})}return t.customFields||{}},_=e=>{let t={...e.dataValues};(e.changed?.()||[]).forEach(n=>{let r=e.previous?.(n);r!==void 0&&(t[n]=r)});let n=e.previous?.(`customFields`);return n!==void 0&&(t.customFields=n),t},v=e=>e.reduce((e,t)=>{let n=((t.instancePath||``).split(`/`).filter(Boolean).join(`.`).replace(/^after\./,``)+(t.keyword===`required`?`.${t.params?.missingProperty}`:``)).replace(/^\./,``)||`root`;return e[n]=t.message||`Invalid value`,e},{}),y=async(t,n,r,i={},s=!1)=>{let c=t.constructor.name;e.debug(`sadot - validating model`,{isCreate:s,modelType:c});let u=o(t,r);if(e.debug(`sadot - identifiers`,{identifiers:u}),!u||Object.keys(u).length===0){e.debug(`sadot - skipping validation: no identifiers`);return}let d=Object.values(u)[0];if(e.debug(`sadot - entityId`,{entityId:d}),!d){e.debug(`sadot - skipping validation: no entityId`);return}let f,y;n.transaction&&(n.transaction.validationsCache??=new Map,y=`${c}-${d}`,f=n.transaction.validationsCache.get(y)),f||(f=a(c,d,{transaction:n.transaction,attributes:p,modelOptions:i}),n.transaction&&n?.transaction?.validationsCache.set(y,f));let b=await f;if(e.debug(`sadot - validators found`,{count:b.length}),!b.length){e.debug(`sadot - skipping validation: no validators found`);return}let x=null;s||(x=_(t));let S=s?t.customFields||{}:await g(t,n);for(let n of b){let{schema:r}=n,i=r;if(e.debug(`sadot - validating with schema`,{schema:r,hasAfterProps:!!i.properties?.after,hasBeforeProps:!!i.properties?.before}),s){if(i.properties?.after){let e=m.compile({...r,properties:{after:i.properties.after}});if(!e(JSON.parse(JSON.stringify({after:{...t.dataValues,customFields:S}})))){let t=e.errors?.map(e=>`${e.instancePath||``} ${e.message||`Invalid value`}`).join(`, `),n=v(e.errors);throw new l([Error(`Validation failed for ${c}: ${t}`)],void 0,{customError:n})}}}else{let n=m.compile(i),r=h(t.dataValues);r.customFields=S;let a={before:x,after:r},o=n(JSON.parse(JSON.stringify(a)));if(e.debug(`sadot - validation result`,{isValid:o,test:{before:x,after:r}}),!o){let e=n.errors?.map(e=>`${e.instancePath||``} ${e.message||`Invalid value`}`).join(`, `),t=v(n.errors);throw new l([Error(`Validation failed for ${c}: ${e}`)],void 0,{customError:t})}}}},b=async({modelType:e,modelOptions:t,identifiers:n,options:r})=>{let{include:a,useEntityIdFromInclude:o}=t;return await i({modelType:e,disabled:!1,...!o&&{entityId:n}},{withDisabled:!1,transaction:r.transaction,include:a?.(n)})},x=(e,r)=>{(e||[]).forEach(e=>{let{fieldType:i,name:a}=e;if([t.DATE,t.DATETIME].includes(i)){let e=r.customFields?.[a];if(e){let{value:t,error:i}=c.date().validate(e);if(i)throw new n(e,a,i);r.customFields[a]=t.toISOString()}}})},S=(t,n={},i={useCustomFieldsEntries:!1})=>async(a,c)=>{e.debug(`sadot - before create hook`);let{fields:l}=c,u=a.constructor.name,d=o(a,t),f=await b({modelType:u,modelOptions:n,identifiers:d,options:c}),p=f.filter(e=>![null,void 0].includes(e.defaultValue));p.length&&(a.customFields||={},p.filter(e=>a.customFields?.[e.name]===void 0).forEach(({name:e,defaultValue:t})=>{a.customFields[e]=t}));let m=Array.from(new Set(f.filter(({required:e})=>e).map(({name:e})=>e))),{customFields:h}=a,g=Object.keys(h??{}),_=m.filter(e=>!g.includes(e));if(_?.length)throw new r(_);await y(a,c,t,n,!0),x(f,a);let v=l.indexOf(`customFields`);v===-1||!h||!Object.keys(h).length||(await s({modelId:a.id,modelType:u,identifiers:d,customFields:h,options:{useCustomFieldsEntries:i.useCustomFieldsEntries,transaction:c.transaction,modelOptions:n}}),l.splice(v,1))},C=(t,n={},r={useCustomFieldsEntries:!1})=>async(i,a)=>{e.debug(`sadot - before update hook`);let{fields:c}=a,l=i.constructor.name,u=o(i,t),d=await b({modelType:l,modelOptions:n,identifiers:u,options:a});await y(i,a,t,n,!1),x(d,i);let f=c.indexOf(`customFields`);if(f>-1){let{customFields:e}=i;if(!Object.keys(e).length)return;await s({modelId:i.id,modelType:l,identifiers:u,customFields:e,options:{useCustomFieldsEntries:r.useCustomFieldsEntries,transaction:a.transaction,modelOptions:n}}),c.splice(f,1)}},w=e=>{e.individualHooks=!0},T=e=>{e.individualHooks=!0};export{w as beforeBulkCreate,T as beforeBulkUpdate,S as beforeCreate,C as beforeUpdate};
2
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","names":["beforeFull: any","applyScopeToInstance","cacheKey: string | undefined","ValidatorRepo.findAllByModelType","where: WhereOptions","DefinitionRepo.findAll","updateInstanceValues"],"sources":["../../src/hooks/hooks.ts"],"sourcesContent":["import type {\n BulkCreateOptions, CreateOptions, Transactionable, UpdateOptions, WhereOptions,\n} from 'sequelize';\nimport Ajv from 'ajv';\nimport Joi from 'joi';\nimport addFormats from 'ajv-formats';\nimport { BadRequest } from '@autofleet/errors';\nimport ajvErrors from 'ajv-errors';\nimport logger from '../utils/logger';\nimport * as ValidatorRepo from '../repository/validator';\nimport * as DefinitionRepo from '../repository/definition';\nimport { InvalidValueError, MissingRequiredCustomFieldError } from '../errors';\nimport type { CustomFieldOptions, ModelOptions, TransactionOptions } from '../types';\nimport applyScopeToInstance from '../utils/scopeAttributes';\nimport updateInstanceValues from './utils/updateInstanceValues';\nimport { CustomFieldDefinitionType } from '../utils/constants';\nimport type { CustomFieldDefinition } from '../models';\n\n// Include all required fields for proper validation\nconst CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL = ['id', 'schema', 'modelType', 'entityId', 'disabled'];\n\n// Initialize Ajv with relaxed settings to avoid warnings\nconst ajv = new Ajv({\n allErrors: true,\n strict: false, // Disable strict mode to avoid warnings\n strictTypes: false, // Disable strict type checking\n $data: true, // Enable $data references\n});\n\naddFormats(ajv);\najvErrors(ajv);\n\n/**\n * Helper function to manually copy object properties\n * This is more efficient for large objects and avoids excessive object creation\n */\nconst manualObjectCopy = (sourceObj: Record<string, any>, additionalProps?: Record<string, any>): Record<string, any> =>\n ({ __proto__: null, ...sourceObj, ...additionalProps });\n\n/**\n * Fetches complete custom fields for an instance by merging DB values with update values\n * This is needed for partial updates to ensure all related fields are available for validation\n */\nconst getCompleteCustomFields = async (instance: any, options: Transactionable): Promise<Record<string, any>> => {\n // If we don't have an instance id or no custom fields being updated, return original fields\n if (!instance.id || !instance.customFields || Object.keys(instance.customFields).length === 0) {\n return instance.customFields || {};\n }\n\n try {\n const ModelClass = instance.constructor;\n // Only select the customFields column to minimize data transfer\n const currentCustomFields = await ModelClass.findOne({\n where: { id: instance.id },\n attributes: ['customFields'],\n transaction: options.transaction,\n raw: true, // Get plain object instead of model instance for better performance\n });\n\n if (currentCustomFields?.customFields) {\n // Merge existing fields with update fields using our helper function\n const completeFields = manualObjectCopy(\n currentCustomFields.customFields,\n instance.customFields,\n );\n\n logger.debug('sadot - fetched complete custom fields for validation', {\n fieldsCount: Object.keys(completeFields).length,\n updateFieldsCount: Object.keys(instance.customFields).length,\n });\n\n return completeFields;\n }\n } catch (error) {\n logger.error('sadot - error fetching complete model for validation', { error });\n // Continue with partial data if we can't fetch the complete model\n }\n\n return instance.customFields || {};\n};\n\nconst buildPreChangeState = (instance: any) => {\n const beforeFull: any = { ...instance.dataValues };\n\n const changedKeys: string[] = instance.changed?.() || [];\n changedKeys.forEach((key) => {\n const prevVal = instance.previous?.(key);\n if (prevVal !== undefined) {\n beforeFull[key] = prevVal;\n }\n });\n\n const prevCF = instance.previous?.('customFields');\n if (prevCF !== undefined) {\n beforeFull.customFields = prevCF;\n }\n\n return beforeFull;\n};\n\nconst formatAjvErrors = (\n errors: {\n instancePath?: string;\n keyword: string;\n message?: string;\n params?: Record<string, any>;\n }[],\n): Record<string, string> => errors.reduce((acc, err) => {\n const basePath = (err.instancePath || '')\n .split('/')\n .filter(Boolean)\n .join('.')\n .replace(/^after\\./, '');\n\n const missingProp = err.keyword === 'required' ? `.${err.params?.missingProperty}` : '';\n const key = (basePath + missingProp).replace(/^\\./, '') || 'root';\n\n const message = err.message || 'Invalid value';\n acc[key] = message;\n\n return acc;\n}, {} as Record<string, string>);\n\n/**\n * Validates the model using custom validators\n */\nconst validateModel = async (\n instance: any,\n options: TransactionOptions,\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n isCreate = false,\n): Promise<void> => {\n const modelType = instance.constructor.name;\n\n logger.debug('sadot - validating model', { isCreate, modelType });\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n logger.debug('sadot - identifiers', { identifiers });\n\n // Skip if no identifiers\n if (!identifiers || Object.keys(identifiers).length === 0) {\n logger.debug('sadot - skipping validation: no identifiers');\n return;\n }\n\n // Find the entityId from identifiers (fleetId, businessModelId, etc.)\n const entityId = Object.values(identifiers)[0]; // Get the first value as entityId\n\n logger.debug('sadot - entityId', { entityId });\n\n if (!entityId) {\n logger.debug('sadot - skipping validation: no entityId');\n return;\n }\n\n let validatorsPromise;\n let cacheKey: string | undefined;\n if (options.transaction) {\n options.transaction.validationsCache ??= new Map();\n cacheKey = `${modelType}-${entityId}`;\n validatorsPromise = options.transaction.validationsCache.get(cacheKey);\n }\n\n if (!validatorsPromise) {\n validatorsPromise = ValidatorRepo.findAllByModelType(\n modelType,\n entityId,\n {\n transaction: options.transaction,\n attributes: CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL,\n modelOptions,\n },\n );\n if (options.transaction) {\n options?.transaction?.validationsCache!.set(cacheKey!, validatorsPromise);\n }\n }\n const validators = await validatorsPromise;\n\n logger.debug('sadot - validators found', { count: validators.length });\n\n if (!validators.length) {\n logger.debug('sadot - skipping validation: no validators found');\n return;\n }\n\n // For updates, get the previous values\n let originalValues = null;\n if (!isCreate) {\n originalValues = buildPreChangeState(instance);\n }\n\n // Get complete custom fields by merging DB values with update values\n // This is especially important for partial updates to ensure all related fields are available\n const completeCustomFields = !isCreate\n ? await getCompleteCustomFields(instance, options)\n : instance.customFields || {};\n\n for (const validator of validators) {\n const { schema } = validator;\n const typedSchema = schema as Record<string, any>;\n\n logger.debug('sadot - validating with schema', {\n schema,\n hasAfterProps: !!typedSchema.properties?.after,\n hasBeforeProps: !!typedSchema.properties?.before,\n });\n\n if (isCreate) {\n // For create operations, we only need the 'after' state\n if (typedSchema.properties?.after) {\n const validateSchema = ajv.compile({\n ...schema,\n // Focus only on the 'after' validation part for create\n properties: {\n after: typedSchema.properties.after,\n },\n });\n\n const isValid = validateSchema(JSON.parse(JSON.stringify({\n after: {\n ...instance.dataValues,\n customFields: completeCustomFields,\n },\n })));\n\n if (!isValid) {\n const errorDetails = validateSchema.errors?.map(err =>\n `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n } else {\n // For update operations, we need both before and after\n const validateSchema = ajv.compile(typedSchema);\n\n // Create after object with our helper function\n const afterObj = manualObjectCopy(instance.dataValues);\n\n // Add complete custom fields\n afterObj.customFields = completeCustomFields;\n\n // Create validation payload\n const payload = {\n before: originalValues,\n after: afterObj,\n };\n\n // Validate\n const isValid = validateSchema(JSON.parse(JSON.stringify(payload)));\n\n logger.debug('sadot - validation result', {\n isValid,\n test: {\n before: originalValues,\n after: afterObj,\n },\n });\n\n if (!isValid) {\n const errorDetails = validateSchema\n .errors\n ?.map(err => `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n }\n};\n\nconst getFieldDefinitions = async ({\n modelType,\n modelOptions,\n identifiers,\n options,\n}: {\n modelType: any;\n modelOptions: ModelOptions;\n identifiers: any[];\n options: any;\n}) => {\n const { include, useEntityIdFromInclude } = modelOptions;\n const where: WhereOptions = {\n modelType,\n disabled: false,\n ...(!useEntityIdFromInclude && { entityId: identifiers }),\n };\n\n const fieldDefinitions = await DefinitionRepo.findAll(where, {\n withDisabled: false,\n transaction: options.transaction,\n include: include?.(identifiers),\n });\n return fieldDefinitions;\n};\n\nconst formatDates = (fieldDefinitions: CustomFieldDefinition[], instance: any) => {\n (fieldDefinitions || []).forEach((fieldDefinition) => {\n const { fieldType, name } = fieldDefinition;\n if ([CustomFieldDefinitionType.DATE, CustomFieldDefinitionType.DATETIME].includes(fieldType)) {\n const value = instance.customFields?.[name];\n if (value) {\n const { value: joiValue, error: validationError } = Joi.date().validate(value);\n if (validationError) {\n throw new InvalidValueError(value, name, validationError);\n }\n instance.customFields[name] = joiValue.toISOString();\n }\n }\n });\n};\n\n/**\n * Hook to handle validation and custom fields during creation\n */\nexport const beforeCreate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries'> = { useCustomFieldsEntries: false },\n) => async (\n instance: any,\n options: CreateOptions,\n): Promise<void> => {\n logger.debug('sadot - before create hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n // Step 1: Handle custom fields default values and required fields\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options,\n });\n\n // Apply default values\n const fieldsWithDefaultValue = fieldDefinitions.filter(def => ![null, undefined].includes(def.defaultValue));\n if (fieldsWithDefaultValue.length) {\n instance.customFields ||= {};\n fieldsWithDefaultValue\n .filter(def => (instance.customFields?.[def.name] === undefined))\n .forEach(({ name, defaultValue }) => {\n instance.customFields[name] = defaultValue;\n });\n }\n\n // Check for required fields\n const requiredFieldsNames = Array.from(\n new Set(fieldDefinitions.filter(({ required }) => required).map(({ name }) => name)),\n );\n const { customFields } = instance;\n const fieldsNames = Object.keys(customFields ?? {});\n const missingFields = requiredFieldsNames.filter(name => !fieldsNames.includes(name));\n if (missingFields?.length) {\n throw new MissingRequiredCustomFieldError(missingFields);\n }\n\n // Step 2: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, true);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 3: Save custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx === -1 || !customFields || !Object.keys(customFields).length) {\n // No custom fields to update\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n};\n\n/**\n * Hook to handle validation and custom fields during update\n */\nexport const beforeUpdate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries'> = { useCustomFieldsEntries: false },\n) => async (\n instance: any,\n options: UpdateOptions,\n): Promise<void> => {\n logger.debug('sadot - before update hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options,\n });\n\n // Step 1: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, false);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 2: Update custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx > -1) {\n const { customFields } = instance;\n\n if (!Object.keys(customFields).length) {\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n }\n};\n\n/**\n * Hook to enable individual hooks for bulk create operations\n */\nexport const beforeBulkCreate = (options: BulkCreateOptions): void => {\n // This will activate the beforeCreate hook on each instance\n options.individualHooks = true;\n};\n\n/**\n * Hook to enable individual hooks for bulk update operations\n */\nexport const beforeBulkUpdate = (options: UpdateOptions): void => {\n // This will activate the beforeUpdate hook on each instance\n options.individualHooks = true;\n};\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ const e=require(`./enrich.cjs`),t=require(`./find.cjs`),n=require(`./hooks.cjs`);
@@ -1,17 +1 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.beforeBulkUpdate = exports.beforeBulkCreate = exports.beforeUpdate = exports.beforeCreate = exports.workaround = exports.beforeFind = exports.enrichResults = void 0;
7
- const enrich_1 = __importDefault(require("./enrich"));
8
- exports.enrichResults = enrich_1.default;
9
- const find_1 = require("./find");
10
- Object.defineProperty(exports, "beforeFind", { enumerable: true, get: function () { return find_1.beforeFind; } });
11
- const workaround_1 = __importDefault(require("./workaround"));
12
- exports.workaround = workaround_1.default;
13
- const hooks_1 = require("./hooks");
14
- Object.defineProperty(exports, "beforeCreate", { enumerable: true, get: function () { return hooks_1.beforeCreate; } });
15
- Object.defineProperty(exports, "beforeUpdate", { enumerable: true, get: function () { return hooks_1.beforeUpdate; } });
16
- Object.defineProperty(exports, "beforeBulkCreate", { enumerable: true, get: function () { return hooks_1.beforeBulkCreate; } });
17
- Object.defineProperty(exports, "beforeBulkUpdate", { enumerable: true, get: function () { return hooks_1.beforeBulkUpdate; } });
1
+ import e from"./enrich.js";import{beforeFind as t}from"./find.js";import{beforeBulkCreate as n,beforeBulkUpdate as r,beforeCreate as i,beforeUpdate as a}from"./hooks.js";export{};
@@ -0,0 +1,2 @@
1
+ const e=require(`../../repository/value.cjs`),t=require(`../../repository/entries.cjs`),n=async({modelId:n,modelType:r,identifiers:i,customFields:a,options:o={modelOptions:{},useCustomFieldsEntries:!1}})=>{if(await e.updateValues(r,n,i,a,{...o,modelOptions:o.modelOptions??{}}),!o?.useCustomFieldsEntries)return;let{dataValues:{customFields:s}}=await t.findEntriesByModelId(n,o)??{dataValues:{}},c={...s,...a};await t.updateEntries(n,r,c,i,{...o,modelOptions:o.modelOptions??{}})};var r=n;exports.default=r;
2
+ //# sourceMappingURL=updateInstanceValues.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateInstanceValues.cjs","names":[],"sources":["../../../src/hooks/utils/updateInstanceValues.ts"],"sourcesContent":["import type { Transaction } from 'sequelize';\nimport * as ValueRepo from '../../repository/value';\nimport * as EntriesRepo from '../../repository/entries';\nimport type { ModelOptions } from '../../types';\n\ninterface UpdateInstanceValuesParams {\n modelId: string;\n modelType: string;\n identifiers: string[];\n customFields: Record<string, any>;\n options?: {\n transaction?: Transaction | null;\n modelOptions?: ModelOptions;\n useCustomFieldsEntries?: boolean;\n };\n}\n\nconst updateInstanceValues = async ({\n modelId,\n modelType,\n identifiers,\n customFields,\n options = {\n modelOptions: {},\n useCustomFieldsEntries: false,\n },\n}: UpdateInstanceValuesParams): Promise<void> => {\n await ValueRepo.updateValues(\n modelType,\n modelId,\n identifiers,\n customFields,\n {\n ...options,\n modelOptions: options.modelOptions ?? {},\n },\n );\n\n /*\n T.Y TODO - Once we're ready to switch from custom_field_values to custom_field_entries, we should remove the ValueRepo.updateValues call.\n Currently, We're updating both tables to keep the data in sync, but not all microservices are using the new table yet.\n */\n\n if (!options?.useCustomFieldsEntries) {\n return;\n }\n\n const { dataValues: { customFields: oldCustomFields } } = await EntriesRepo.findEntriesByModelId(modelId, options) ?? { dataValues: {} };\n const newCustomFields = { ...oldCustomFields, ...customFields };\n\n await EntriesRepo.updateEntries(\n modelId,\n modelType,\n newCustomFields,\n identifiers,\n {\n ...options,\n modelOptions: options.modelOptions ?? {},\n },\n );\n};\n\nexport default updateInstanceValues;\n"],"mappings":"wFAiBM,EAAuB,MAAO,CAClC,UACA,YACA,cACA,eACA,UAAU,CACR,aAAc,EAAE,CAChB,uBAAwB,GACzB,IAC8C,CAiB/C,GAhBA,MAAA,EAAA,aACE,EACA,EACA,EACA,EACA,CACE,GAAG,EACH,aAAc,EAAQ,cAAgB,EAAE,CACzC,CACF,CAOG,CAAC,GAAS,uBACZ,OAGF,GAAM,CAAE,WAAY,CAAE,aAAc,IAAsB,MAAA,EAAA,qBAAuC,EAAS,EAAQ,EAAI,CAAE,WAAY,EAAE,CAAE,CAClI,EAAkB,CAAE,GAAG,EAAiB,GAAG,EAAc,CAE/D,MAAA,EAAA,cACE,EACA,EACA,EACA,EACA,CACE,GAAG,EACH,aAAc,EAAQ,cAAgB,EAAE,CACzC,CACF,EAGH,IAAA,EAAe"}
@@ -1,50 +1,2 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- Object.defineProperty(exports, "__esModule", { value: true });
26
- const ValueRepo = __importStar(require("../../repository/value"));
27
- const EntriesRepo = __importStar(require("../../repository/entries"));
28
- const updateInstanceValues = async ({ modelId, modelType, identifiers, customFields, options = {
29
- modelOptions: {},
30
- useCustomFieldsEntries: false,
31
- }, }) => {
32
- await ValueRepo.updateValues(modelType, modelId, identifiers, customFields, {
33
- ...options,
34
- modelOptions: options.modelOptions ?? {},
35
- });
36
- /*
37
- T.Y TODO - Once we're ready to switch from custom_field_values to custom_field_entries, we should remove the ValueRepo.updateValues call.
38
- Currently, We're updating both tables to keep the data in sync, but not all microservices are using the new table yet.
39
- */
40
- if (!options?.useCustomFieldsEntries) {
41
- return;
42
- }
43
- const { dataValues: { customFields: oldCustomFields } } = await EntriesRepo.findEntriesByModelId(modelId, options) ?? { dataValues: {} };
44
- const newCustomFields = { ...oldCustomFields, ...customFields };
45
- await EntriesRepo.updateEntries(modelId, modelType, newCustomFields, identifiers, {
46
- ...options,
47
- modelOptions: options.modelOptions ?? {},
48
- });
49
- };
50
- exports.default = updateInstanceValues;
1
+ import{updateValues as e}from"../../repository/value.js";import{findEntriesByModelId as t,updateEntries as n}from"../../repository/entries.js";var r=async({modelId:r,modelType:i,identifiers:a,customFields:o,options:s={modelOptions:{},useCustomFieldsEntries:!1}})=>{if(await e(i,r,a,o,{...s,modelOptions:s.modelOptions??{}}),!s?.useCustomFieldsEntries)return;let{dataValues:{customFields:c}}=await t(r,s)??{dataValues:{}};await n(r,i,{...c,...o},a,{...s,modelOptions:s.modelOptions??{}})};export{r as default};
2
+ //# sourceMappingURL=updateInstanceValues.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateInstanceValues.js","names":["ValueRepo.updateValues","EntriesRepo.findEntriesByModelId","EntriesRepo.updateEntries"],"sources":["../../../src/hooks/utils/updateInstanceValues.ts"],"sourcesContent":["import type { Transaction } from 'sequelize';\nimport * as ValueRepo from '../../repository/value';\nimport * as EntriesRepo from '../../repository/entries';\nimport type { ModelOptions } from '../../types';\n\ninterface UpdateInstanceValuesParams {\n modelId: string;\n modelType: string;\n identifiers: string[];\n customFields: Record<string, any>;\n options?: {\n transaction?: Transaction | null;\n modelOptions?: ModelOptions;\n useCustomFieldsEntries?: boolean;\n };\n}\n\nconst updateInstanceValues = async ({\n modelId,\n modelType,\n identifiers,\n customFields,\n options = {\n modelOptions: {},\n useCustomFieldsEntries: false,\n },\n}: UpdateInstanceValuesParams): Promise<void> => {\n await ValueRepo.updateValues(\n modelType,\n modelId,\n identifiers,\n customFields,\n {\n ...options,\n modelOptions: options.modelOptions ?? {},\n },\n );\n\n /*\n T.Y TODO - Once we're ready to switch from custom_field_values to custom_field_entries, we should remove the ValueRepo.updateValues call.\n Currently, We're updating both tables to keep the data in sync, but not all microservices are using the new table yet.\n */\n\n if (!options?.useCustomFieldsEntries) {\n return;\n }\n\n const { dataValues: { customFields: oldCustomFields } } = await EntriesRepo.findEntriesByModelId(modelId, options) ?? { dataValues: {} };\n const newCustomFields = { ...oldCustomFields, ...customFields };\n\n await EntriesRepo.updateEntries(\n modelId,\n modelType,\n newCustomFields,\n identifiers,\n {\n ...options,\n modelOptions: options.modelOptions ?? {},\n },\n );\n};\n\nexport default updateInstanceValues;\n"],"mappings":"+IA8DA,IAAA,EA7C6B,MAAO,CAClC,UACA,YACA,cACA,eACA,UAAU,CACR,aAAc,EAAE,CAChB,uBAAwB,GACzB,IAC8C,CAiB/C,GAhBA,MAAMA,EACJ,EACA,EACA,EACA,EACA,CACE,GAAG,EACH,aAAc,EAAQ,cAAgB,EAAE,CACzC,CACF,CAOG,CAAC,GAAS,uBACZ,OAGF,GAAM,CAAE,WAAY,CAAE,aAAc,IAAsB,MAAMC,EAAiC,EAAS,EAAQ,EAAI,CAAE,WAAY,EAAE,CAAE,CAGxI,MAAMC,EACJ,EACA,EAJsB,CAAE,GAAG,EAAiB,GAAG,EAAc,CAM7D,EACA,CACE,GAAG,EACH,aAAc,EAAQ,cAAgB,EAAE,CACzC,CACF"}
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,`__esModule`,{value:!0});const e=require(`./utils/logger/index.cjs`),t=require(`./utils/constants/index.cjs`),n=require(`./models/CustomFieldDefinition.cjs`),r=require(`./models/CustomFieldValue.cjs`),i=require(`./models/CustomFieldEntries.cjs`),a=require(`./models/CustomValidator.cjs`),o=require(`./models/index.cjs`),s=require(`./api/index.cjs`),c=require(`./utils/db/index.cjs`),l=require(`./utils/helpers/index.cjs`),u=require(`./scopes/filter.cjs`),d=require(`./utils/init.cjs`),f=require(`./utils/validations/schema/custom-fields.cjs`),p=async(t,n,r)=>{e.tryAddingTraceIdMiddleware();let{models:i,useCustomFieldsEntries:a}=r;t&&t.use(`/api`,s.default);let l=r.sequelize??c.default(r.databaseConfig);return process.env.NODE_ENV===`test`&&await o.initTestModels(l),d.addHooks(i,n,{useCustomFieldsEntries:a}),await o.initTables(l,r.getUser,{useCustomFieldsEntries:a}),d.addScopes(i,n,{useCustomFieldsEntries:a}),d.applyCustomAssociation(i),e.default.debug(`sadot - custom fields finished initializing with models`,i),l};var m=p;const h=(e,t)=>{d.removeHooks(e,t)};exports.CUSTOM_FIELDS_FILTER_SCOPE=t.CUSTOM_FIELDS_FILTER_SCOPE,exports.CustomFieldDefinition=n,exports.CustomFieldDefinitionType=t.CustomFieldDefinitionType,exports.CustomFieldEntries=i,exports.CustomFieldValue=r,exports.CustomFieldsSchema=f.CustomFieldsSchema,exports.CustomValidator=a,exports.customFieldsSortScope=u.customFieldsSortScope,exports.default=m,exports.disableCustomFields=h,exports.generateCustomFieldSearchQueryPayload=l.generateCustomFieldSearchQueryPayload,exports.generateRandomString=l.generateRandomString,exports.supportedEntities=t.supportedEntities;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["api","initDB","initTestModels","initTables"],"sources":["../src/index.ts"],"sourcesContent":["import type { Application } from 'express';\nimport type { Sequelize } from 'sequelize-typescript';\nimport {\n initTables, initTestModels,\n} from './models';\nimport api from './api';\nimport initDB from './utils/db';\nimport logger, { tryAddingTraceIdMiddleware } from './utils/logger';\nimport type { CustomFieldOptions, ModelFetcher, Models } from './types';\nimport {\n addHooks, addScopes, applyCustomAssociation, removeHooks,\n} from './utils/init';\n\nexport * from './utils/validations/schema/custom-fields';\n\nexport * from './utils/constants';\n\nexport * from './utils/helpers';\n\nexport { customFieldsSortScope } from './scopes/filter';\nexport {\n CustomFieldDefinition,\n CustomFieldEntries,\n CustomFieldValue,\n CustomValidator,\n} from './models';\n\n/**\n * Adding custom fields enrichment to the models inside the MODELS_FILE_NAME json file\n * @see {@link 'custom-fields/config'} for configurations\n */\nconst useCustomFields = async (\n app: Pick<Application, 'use'> | null,\n getModel: ModelFetcher,\n options: CustomFieldOptions,\n): Promise<Sequelize> => {\n tryAddingTraceIdMiddleware();\n const { models, useCustomFieldsEntries } = options;\n if (app) {\n app.use('/api', api);\n }\n const sequelize = options.sequelize ?? initDB(options.databaseConfig);\n if (process.env.NODE_ENV === 'test') {\n await initTestModels(sequelize);\n }\n // The order is important\n addHooks(models, getModel, { useCustomFieldsEntries });\n await initTables(sequelize, options.getUser, { useCustomFieldsEntries });\n addScopes(models, getModel, { useCustomFieldsEntries });\n applyCustomAssociation(models);\n\n logger.debug('sadot - custom fields finished initializing with models', models);\n return sequelize;\n};\n\nexport default useCustomFields;\n\nexport const disableCustomFields = (models: Models[], getModel: ModelFetcher): void => {\n removeHooks(models, getModel);\n};\n"],"mappings":"6jBA+BM,EAAkB,MACtB,EACA,EACA,IACuB,CACvB,EAAA,4BAA4B,CAC5B,GAAM,CAAE,SAAQ,0BAA2B,EACvC,GACF,EAAI,IAAI,OAAQA,EAAAA,QAAI,CAEtB,IAAM,EAAY,EAAQ,WAAaC,EAAAA,QAAO,EAAQ,eAAe,CAWrE,OAVI,QAAQ,IAAI,WAAa,QAC3B,MAAMC,EAAAA,eAAe,EAAU,CAGjC,EAAA,SAAS,EAAQ,EAAU,CAAE,yBAAwB,CAAC,CACtD,MAAMC,EAAAA,WAAW,EAAW,EAAQ,QAAS,CAAE,yBAAwB,CAAC,CACxE,EAAA,UAAU,EAAQ,EAAU,CAAE,yBAAwB,CAAC,CACvD,EAAA,uBAAuB,EAAO,CAE9B,EAAA,QAAO,MAAM,0DAA2D,EAAO,CACxE,GAGT,IAAA,EAAe,EAEf,MAAa,GAAuB,EAAkB,IAAiC,CACrF,EAAA,YAAY,EAAQ,EAAS"}