@contember/engine-content-api 1.3.0-alpha.1 → 1.3.0-alpha.13

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 (328) hide show
  1. package/dist/src/ExecutionContainer.d.ts +144 -0
  2. package/dist/src/ExecutionContainer.d.ts.map +1 -0
  3. package/dist/src/ExecutionContainer.js +85 -0
  4. package/dist/src/ExecutionContainer.js.map +1 -0
  5. package/dist/src/acl/PermissionFactory.d.ts +5 -4
  6. package/dist/src/acl/PermissionFactory.d.ts.map +1 -1
  7. package/dist/src/acl/PermissionFactory.js +10 -13
  8. package/dist/src/acl/PermissionFactory.js.map +1 -1
  9. package/dist/src/acl/index.d.ts +0 -1
  10. package/dist/src/acl/index.d.ts.map +1 -1
  11. package/dist/src/acl/index.js +0 -1
  12. package/dist/src/acl/index.js.map +1 -1
  13. package/dist/src/index.d.ts +2 -1
  14. package/dist/src/index.d.ts.map +1 -1
  15. package/dist/src/index.js +18 -2
  16. package/dist/src/index.js.map +1 -1
  17. package/dist/src/mapper/ColumnValue.d.ts +2 -2
  18. package/dist/src/mapper/ColumnValue.d.ts.map +1 -1
  19. package/dist/src/mapper/ErrorUtils.d.ts +3 -2
  20. package/dist/src/mapper/ErrorUtils.d.ts.map +1 -1
  21. package/dist/src/mapper/ErrorUtils.js +55 -35
  22. package/dist/src/mapper/ErrorUtils.js.map +1 -1
  23. package/dist/src/mapper/EventManager.d.ts +86 -0
  24. package/dist/src/mapper/EventManager.d.ts.map +1 -0
  25. package/dist/src/mapper/EventManager.js +118 -0
  26. package/dist/src/mapper/EventManager.js.map +1 -0
  27. package/dist/src/mapper/JunctionTableManager.d.ts +12 -11
  28. package/dist/src/mapper/JunctionTableManager.d.ts.map +1 -1
  29. package/dist/src/mapper/JunctionTableManager.js +20 -8
  30. package/dist/src/mapper/JunctionTableManager.js.map +1 -1
  31. package/dist/src/mapper/Mapper.d.ts +13 -6
  32. package/dist/src/mapper/Mapper.d.ts.map +1 -1
  33. package/dist/src/mapper/Mapper.js +41 -21
  34. package/dist/src/mapper/Mapper.js.map +1 -1
  35. package/dist/src/mapper/MapperFactory.d.ts +34 -0
  36. package/dist/src/mapper/MapperFactory.d.ts.map +1 -0
  37. package/dist/src/mapper/MapperFactory.js +41 -0
  38. package/dist/src/mapper/MapperFactory.js.map +1 -0
  39. package/dist/src/mapper/Result.d.ts +5 -3
  40. package/dist/src/mapper/Result.d.ts.map +1 -1
  41. package/dist/src/mapper/Result.js +4 -3
  42. package/dist/src/mapper/Result.js.map +1 -1
  43. package/dist/src/mapper/delete/DeleteExecutor.d.ts.map +1 -1
  44. package/dist/src/mapper/delete/DeleteExecutor.js +41 -1
  45. package/dist/src/mapper/delete/DeleteExecutor.js.map +1 -1
  46. package/dist/src/mapper/index.d.ts +3 -1
  47. package/dist/src/mapper/index.d.ts.map +1 -1
  48. package/dist/src/mapper/index.js +3 -1
  49. package/dist/src/mapper/index.js.map +1 -1
  50. package/dist/src/mapper/insert/InsertBuilder.d.ts +2 -2
  51. package/dist/src/mapper/insert/InsertBuilder.d.ts.map +1 -1
  52. package/dist/src/mapper/insert/InsertBuilder.js +8 -2
  53. package/dist/src/mapper/insert/InsertBuilder.js.map +1 -1
  54. package/dist/src/mapper/insert/Inserter.d.ts +3 -2
  55. package/dist/src/mapper/insert/Inserter.d.ts.map +1 -1
  56. package/dist/src/mapper/insert/Inserter.js +7 -6
  57. package/dist/src/mapper/insert/Inserter.js.map +1 -1
  58. package/dist/src/mapper/select/OrderByHelper.d.ts +1 -1
  59. package/dist/src/mapper/select/OrderByHelper.d.ts.map +1 -1
  60. package/dist/src/mapper/select/OrderByHelper.js +3 -1
  61. package/dist/src/mapper/select/OrderByHelper.js.map +1 -1
  62. package/dist/src/mapper/select/RelationFetcher.js +2 -2
  63. package/dist/src/mapper/select/RelationFetcher.js.map +1 -1
  64. package/dist/src/mapper/update/UpdateBuilder.d.ts +4 -4
  65. package/dist/src/mapper/update/UpdateBuilder.d.ts.map +1 -1
  66. package/dist/src/mapper/update/UpdateBuilder.js +26 -8
  67. package/dist/src/mapper/update/UpdateBuilder.js.map +1 -1
  68. package/dist/src/mapper/update/UpdateBuilderFactory.d.ts +1 -1
  69. package/dist/src/mapper/update/UpdateBuilderFactory.d.ts.map +1 -1
  70. package/dist/src/mapper/update/UpdateBuilderFactory.js +2 -2
  71. package/dist/src/mapper/update/UpdateBuilderFactory.js.map +1 -1
  72. package/dist/src/mapper/update/Updater.d.ts +3 -1
  73. package/dist/src/mapper/update/Updater.d.ts.map +1 -1
  74. package/dist/src/mapper/update/Updater.js +9 -12
  75. package/dist/src/mapper/update/Updater.js.map +1 -1
  76. package/dist/src/resolvers/GraphQlQueryAstFactory.d.ts +1 -3
  77. package/dist/src/resolvers/GraphQlQueryAstFactory.d.ts.map +1 -1
  78. package/dist/src/resolvers/GraphQlQueryAstFactory.js +1 -4
  79. package/dist/src/resolvers/GraphQlQueryAstFactory.js.map +1 -1
  80. package/dist/src/resolvers/MutationResolver.d.ts +3 -4
  81. package/dist/src/resolvers/MutationResolver.d.ts.map +1 -1
  82. package/dist/src/resolvers/MutationResolver.js +11 -12
  83. package/dist/src/resolvers/MutationResolver.js.map +1 -1
  84. package/dist/src/resolvers/ReadResolver.d.ts +1 -3
  85. package/dist/src/resolvers/ReadResolver.d.ts.map +1 -1
  86. package/dist/src/resolvers/ReadResolver.js +6 -10
  87. package/dist/src/resolvers/ReadResolver.js.map +1 -1
  88. package/dist/src/resolvers/ValidationResolver.d.ts +1 -3
  89. package/dist/src/resolvers/ValidationResolver.d.ts.map +1 -1
  90. package/dist/src/resolvers/ValidationResolver.js +3 -4
  91. package/dist/src/resolvers/ValidationResolver.js.map +1 -1
  92. package/dist/src/resolvers/index.d.ts +0 -1
  93. package/dist/src/resolvers/index.d.ts.map +1 -1
  94. package/dist/src/resolvers/index.js +0 -1
  95. package/dist/src/resolvers/index.js.map +1 -1
  96. package/dist/src/schema/CustomTypesProvider.d.ts.map +1 -1
  97. package/dist/src/schema/CustomTypesProvider.js +1 -23
  98. package/dist/src/schema/CustomTypesProvider.js.map +1 -1
  99. package/dist/src/schema/MutationProvider.js +4 -4
  100. package/dist/src/schema/MutationProvider.js.map +1 -1
  101. package/dist/src/schema/QueryProvider.js +3 -3
  102. package/dist/src/schema/QueryProvider.js.map +1 -1
  103. package/dist/src/tsconfig.tsbuildinfo +1 -1
  104. package/dist/src/types.d.ts +3 -4
  105. package/dist/src/types.d.ts.map +1 -1
  106. package/dist/src/utils/index.d.ts +0 -1
  107. package/dist/src/utils/index.d.ts.map +1 -1
  108. package/dist/src/utils/index.js +0 -1
  109. package/dist/src/utils/index.js.map +1 -1
  110. package/dist/src/utils/uniqueWhereFields.js +1 -1
  111. package/dist/src/utils/uniqueWhereFields.js.map +1 -1
  112. package/dist/tests/cases/bugs/bug-update-by-nested-unique.test.js +3 -5
  113. package/dist/tests/cases/bugs/bug-update-by-nested-unique.test.js.map +1 -1
  114. package/dist/tests/cases/integration/graphQlDb/insert/insertSequence.test.js +2 -2
  115. package/dist/tests/cases/integration/graphQlDb/insert/insertSequence.test.js.map +1 -1
  116. package/dist/tests/cases/integration/graphQlDb/update/bug-freeze-connect-missing-one.test.js +1 -1
  117. package/dist/tests/cases/integration/graphQlDb/update/bug-freeze-connect-missing-one.test.js.map +1 -1
  118. package/dist/tests/cases/integration/graphQlDb/update/deferedConstraints.test.js +45 -45
  119. package/dist/tests/cases/integration/graphQlDb/update/deferedConstraints.test.js.map +1 -1
  120. package/dist/tests/cases/integration/graphQlDb/update/failedDelete.test.js +5 -5
  121. package/dist/tests/cases/integration/graphQlDb/update/failedDelete.test.js.map +1 -1
  122. package/dist/tests/cases/integration/graphQlDb/update/invalidInput.test.js +2 -2
  123. package/dist/tests/cases/integration/graphQlDb/update/invalidInput.test.js.map +1 -1
  124. package/dist/tests/cases/integration/graphQlDb/update/nullChecksNotNull.test.js +7 -7
  125. package/dist/tests/cases/integration/graphQlDb/update/nullChecksNotNull.test.js.map +1 -1
  126. package/dist/tests/cases/integration/graphQlDb/update/nullChecksNullable.test.js +7 -7
  127. package/dist/tests/cases/integration/graphQlDb/update/nullChecksNullable.test.js.map +1 -1
  128. package/dist/tests/cases/integration/graphQlDb/update/uniqueConstraint.test.js +2 -2
  129. package/dist/tests/cases/integration/graphQlDb/update/uniqueConstraint.test.js.map +1 -1
  130. package/dist/tests/cases/integration/graphQlRequests/insert/oneHasMany/connect.test.js +3 -3
  131. package/dist/tests/cases/integration/graphQlRequests/insert/oneHasMany/connect.test.js.map +1 -1
  132. package/dist/tests/cases/integration/graphQlRequests/query/acl/isNullAcl.test.d.ts +2 -0
  133. package/dist/tests/cases/integration/graphQlRequests/query/acl/isNullAcl.test.d.ts.map +1 -0
  134. package/dist/tests/cases/integration/graphQlRequests/query/acl/isNullAcl.test.js +91 -0
  135. package/dist/tests/cases/integration/graphQlRequests/query/acl/isNullAcl.test.js.map +1 -0
  136. package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.js +1 -1
  137. package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.js.map +1 -1
  138. package/dist/tests/cases/integration/graphQlRequests/query/sorting/orderBy.test.d.ts +2 -0
  139. package/dist/tests/cases/integration/graphQlRequests/query/sorting/orderBy.test.d.ts.map +1 -0
  140. package/dist/tests/cases/integration/graphQlRequests/query/sorting/orderBy.test.js +67 -0
  141. package/dist/tests/cases/integration/graphQlRequests/query/sorting/orderBy.test.js.map +1 -0
  142. package/dist/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.js +6 -18
  143. package/dist/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.js.map +1 -1
  144. package/dist/tests/cases/integration/graphQlRequests/update/additionalFilter.test.js +3 -4
  145. package/dist/tests/cases/integration/graphQlRequests/update/additionalFilter.test.js.map +1 -1
  146. package/dist/tests/cases/integration/graphQlRequests/update/basic/columnUpdate.test.js +3 -8
  147. package/dist/tests/cases/integration/graphQlRequests/update/basic/columnUpdate.test.js.map +1 -1
  148. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/update.test.js +3 -9
  149. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/update.test.js.map +1 -1
  150. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/upsert.test.js +3 -9
  151. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/upsert.test.js.map +1 -1
  152. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/update.test.js +3 -9
  153. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/update.test.js.map +1 -1
  154. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/upsert.test.js +3 -9
  155. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/upsert.test.js.map +1 -1
  156. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/connect.test.js +3 -10
  157. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/connect.test.js.map +1 -1
  158. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/create.test.js +3 -10
  159. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/create.test.js.map +1 -1
  160. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/disconnect.test.js +3 -9
  161. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/disconnect.test.js.map +1 -1
  162. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/update.test.js +3 -9
  163. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/update.test.js.map +1 -1
  164. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/upsert.test.js +6 -18
  165. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/upsert.test.js.map +1 -1
  166. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/connect.test.js +3 -11
  167. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/connect.test.js.map +1 -1
  168. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/disconnect.test.js +3 -8
  169. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/disconnect.test.js.map +1 -1
  170. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/update.test.js +3 -6
  171. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/update.test.js.map +1 -1
  172. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/upsert.test.js +3 -6
  173. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/upsert.test.js.map +1 -1
  174. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/connect.test.js +15 -50
  175. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/connect.test.js.map +1 -1
  176. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/create.test.js +3 -10
  177. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/create.test.js.map +1 -1
  178. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/disconnect.test.js +3 -10
  179. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/disconnect.test.js.map +1 -1
  180. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/update.test.js +3 -6
  181. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/update.test.js.map +1 -1
  182. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/upsert.test.js +3 -7
  183. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/upsert.test.js.map +1 -1
  184. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/connect.test.js +12 -32
  185. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/connect.test.js.map +1 -1
  186. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/connectOrCreate.test.js +3 -3
  187. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/connectOrCreate.test.js.map +1 -1
  188. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/create.test.js +6 -20
  189. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/create.test.js.map +1 -1
  190. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/disconnect.test.js +3 -10
  191. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/disconnect.test.js.map +1 -1
  192. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/update.test.js +3 -9
  193. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/update.test.js.map +1 -1
  194. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/upsert.test.js +6 -19
  195. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/upsert.test.js.map +1 -1
  196. package/dist/tests/cases/integration/graphQlRequests/update/queryPortal.test.js +6 -8
  197. package/dist/tests/cases/integration/graphQlRequests/update/queryPortal.test.js.map +1 -1
  198. package/dist/tests/cases/integration/graphQlRequests/update/transaction.test.js +9 -24
  199. package/dist/tests/cases/integration/graphQlRequests/update/transaction.test.js.map +1 -1
  200. package/dist/tests/cases/integration/graphQlRequests/upsert/basicUpsert.test.js +3 -7
  201. package/dist/tests/cases/integration/graphQlRequests/upsert/basicUpsert.test.js.map +1 -1
  202. package/dist/tests/cases/unit/orderbyHelper.test.js +13 -2
  203. package/dist/tests/cases/unit/orderbyHelper.test.js.map +1 -1
  204. package/dist/tests/cases/unit/permissionMerger.test.js +8 -3
  205. package/dist/tests/cases/unit/permissionMerger.test.js.map +1 -1
  206. package/dist/tests/cases/unit/predicatesInjector.test.js +1 -1
  207. package/dist/tests/cases/unit/predicatesInjector.test.js.map +1 -1
  208. package/dist/tests/src/test.d.ts +1 -0
  209. package/dist/tests/src/test.d.ts.map +1 -1
  210. package/dist/tests/src/test.js +35 -6
  211. package/dist/tests/src/test.js.map +1 -1
  212. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  213. package/package.json +16 -13
  214. package/src/ExecutionContainer.ts +208 -0
  215. package/src/acl/PermissionFactory.ts +15 -13
  216. package/src/acl/index.ts +0 -1
  217. package/src/index.ts +24 -1
  218. package/src/mapper/ColumnValue.ts +2 -2
  219. package/src/mapper/ErrorUtils.ts +66 -41
  220. package/src/mapper/EventManager.ts +158 -0
  221. package/src/mapper/JunctionTableManager.ts +50 -32
  222. package/src/mapper/Mapper.ts +48 -27
  223. package/src/mapper/MapperFactory.ts +69 -0
  224. package/src/mapper/Result.ts +5 -2
  225. package/src/mapper/delete/DeleteExecutor.ts +42 -1
  226. package/src/mapper/index.ts +3 -1
  227. package/src/mapper/insert/InsertBuilder.ts +12 -2
  228. package/src/mapper/insert/Inserter.ts +7 -7
  229. package/src/mapper/select/OrderByHelper.ts +2 -1
  230. package/src/mapper/select/RelationFetcher.ts +2 -2
  231. package/src/mapper/update/UpdateBuilder.ts +30 -7
  232. package/src/mapper/update/UpdateBuilderFactory.ts +2 -2
  233. package/src/mapper/update/Updater.ts +9 -13
  234. package/src/resolvers/GraphQlQueryAstFactory.ts +1 -2
  235. package/src/resolvers/MutationResolver.ts +15 -14
  236. package/src/resolvers/ReadResolver.ts +5 -9
  237. package/src/resolvers/ValidationResolver.ts +2 -4
  238. package/src/resolvers/index.ts +0 -1
  239. package/src/schema/CustomTypesProvider.ts +2 -27
  240. package/src/schema/MutationProvider.ts +4 -4
  241. package/src/schema/QueryProvider.ts +3 -3
  242. package/src/tsconfig.json +7 -21
  243. package/src/types.ts +3 -4
  244. package/src/utils/index.ts +0 -1
  245. package/src/utils/uniqueWhereFields.ts +1 -1
  246. package/tests/cases/bugs/bug-update-by-nested-unique.test.ts +3 -5
  247. package/tests/cases/integration/graphQlDb/insert/insertSequence.test.ts +2 -2
  248. package/tests/cases/integration/graphQlDb/update/bug-freeze-connect-missing-one.test.ts +1 -1
  249. package/tests/cases/integration/graphQlDb/update/deferedConstraints.test.ts +9 -9
  250. package/tests/cases/integration/graphQlDb/update/failedDelete.test.ts +3 -3
  251. package/tests/cases/integration/graphQlDb/update/invalidInput.test.ts +2 -2
  252. package/tests/cases/integration/graphQlDb/update/nullChecksNotNull.test.ts +7 -7
  253. package/tests/cases/integration/graphQlDb/update/nullChecksNullable.test.ts +7 -7
  254. package/tests/cases/integration/graphQlDb/update/uniqueConstraint.test.ts +2 -2
  255. package/tests/cases/integration/graphQlRequests/insert/oneHasMany/connect.test.ts +3 -3
  256. package/tests/cases/integration/graphQlRequests/query/acl/isNullAcl.test.ts +77 -0
  257. package/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.ts +1 -1
  258. package/tests/cases/integration/graphQlRequests/query/sorting/orderBy.test.ts +67 -0
  259. package/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.ts +6 -18
  260. package/tests/cases/integration/graphQlRequests/update/additionalFilter.test.ts +3 -4
  261. package/tests/cases/integration/graphQlRequests/update/basic/columnUpdate.test.ts +3 -8
  262. package/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/update.test.ts +3 -9
  263. package/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/upsert.test.ts +3 -9
  264. package/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/update.test.ts +3 -9
  265. package/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/upsert.test.ts +3 -9
  266. package/tests/cases/integration/graphQlRequests/update/manyHasOne/connect.test.ts +3 -10
  267. package/tests/cases/integration/graphQlRequests/update/manyHasOne/create.test.ts +3 -10
  268. package/tests/cases/integration/graphQlRequests/update/manyHasOne/disconnect.test.ts +3 -9
  269. package/tests/cases/integration/graphQlRequests/update/manyHasOne/update.test.ts +3 -9
  270. package/tests/cases/integration/graphQlRequests/update/manyHasOne/upsert.test.ts +6 -18
  271. package/tests/cases/integration/graphQlRequests/update/oneHasMany/connect.test.ts +3 -11
  272. package/tests/cases/integration/graphQlRequests/update/oneHasMany/disconnect.test.ts +3 -8
  273. package/tests/cases/integration/graphQlRequests/update/oneHasMany/update.test.ts +3 -6
  274. package/tests/cases/integration/graphQlRequests/update/oneHasMany/upsert.test.ts +3 -6
  275. package/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/connect.test.ts +15 -50
  276. package/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/create.test.ts +3 -10
  277. package/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/disconnect.test.ts +3 -10
  278. package/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/update.test.ts +3 -6
  279. package/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/upsert.test.ts +3 -7
  280. package/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/connect.test.ts +12 -32
  281. package/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/connectOrCreate.test.ts +3 -3
  282. package/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/create.test.ts +6 -20
  283. package/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/disconnect.test.ts +3 -10
  284. package/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/update.test.ts +3 -9
  285. package/tests/cases/integration/graphQlRequests/update/oneHasOneOwning/upsert.test.ts +6 -19
  286. package/tests/cases/integration/graphQlRequests/update/queryPortal.test.ts +6 -8
  287. package/tests/cases/integration/graphQlRequests/update/transaction.test.ts +9 -24
  288. package/tests/cases/integration/graphQlRequests/upsert/basicUpsert.test.ts +3 -7
  289. package/tests/cases/unit/orderbyHelper.test.ts +15 -2
  290. package/tests/cases/unit/permissionMerger.test.ts +9 -4
  291. package/tests/cases/unit/predicatesInjector.test.ts +1 -1
  292. package/tests/src/test.ts +40 -16
  293. package/tests/tsconfig.json +3 -9
  294. package/dist/src/acl/PermissionsByIdentityFactory.d.ts +0 -12
  295. package/dist/src/acl/PermissionsByIdentityFactory.d.ts.map +0 -1
  296. package/dist/src/acl/PermissionsByIdentityFactory.js +0 -15
  297. package/dist/src/acl/PermissionsByIdentityFactory.js.map +0 -1
  298. package/dist/src/mapper/MapperContainer.d.ts +0 -18
  299. package/dist/src/mapper/MapperContainer.d.ts.map +0 -1
  300. package/dist/src/mapper/MapperContainer.js +0 -55
  301. package/dist/src/mapper/MapperContainer.js.map +0 -1
  302. package/dist/src/resolvers/ExecutionContainerFactory.d.ts +0 -24
  303. package/dist/src/resolvers/ExecutionContainerFactory.d.ts.map +0 -1
  304. package/dist/src/resolvers/ExecutionContainerFactory.js +0 -45
  305. package/dist/src/resolvers/ExecutionContainerFactory.js.map +0 -1
  306. package/dist/src/utils/arrays.d.ts +0 -3
  307. package/dist/src/utils/arrays.d.ts.map +0 -1
  308. package/dist/src/utils/arrays.js +0 -22
  309. package/dist/src/utils/arrays.js.map +0 -1
  310. package/dist/tests/cases/integration/graphQlSchema/schema-acl-allowed.gql +0 -420
  311. package/dist/tests/cases/integration/graphQlSchema/schema-acl-create-only.gql +0 -229
  312. package/dist/tests/cases/integration/graphQlSchema/schema-acl-predicate.gql +0 -112
  313. package/dist/tests/cases/integration/graphQlSchema/schema-acl-predicate2.gql +0 -112
  314. package/dist/tests/cases/integration/graphQlSchema/schema-acl-restricted-create.gql +0 -309
  315. package/dist/tests/cases/integration/graphQlSchema/schema-acl-restricted-delete.gql +0 -402
  316. package/dist/tests/cases/integration/graphQlSchema/schema-acl-restricted-update.gql +0 -338
  317. package/dist/tests/cases/integration/graphQlSchema/schema-acl.gql +0 -221
  318. package/dist/tests/cases/integration/graphQlSchema/schema-aliased-type.gql +0 -226
  319. package/dist/tests/cases/integration/graphQlSchema/schema-basic.gql +0 -841
  320. package/dist/tests/cases/integration/graphQlSchema/schema-bug-66.gql +0 -540
  321. package/dist/tests/cases/integration/graphQlSchema/schema-custom-primary.gql +0 -851
  322. package/dist/tests/cases/integration/graphQlSchema/schema-has-many-reduction.gql +0 -453
  323. package/dist/tests/cases/integration/graphQlSchema/schema-new-builder.gql +0 -912
  324. package/dist/tests/cases/integration/graphQlSchema/schema-view-entity.gql +0 -112
  325. package/src/acl/PermissionsByIdentityFactory.ts +0 -21
  326. package/src/mapper/MapperContainer.ts +0 -142
  327. package/src/resolvers/ExecutionContainerFactory.ts +0 -74
  328. package/src/utils/arrays.ts +0 -19
@@ -0,0 +1,158 @@
1
+ import { Input, Model, Value } from '@contember/schema'
2
+ import { ResolvedColumnValue } from './ColumnValue'
3
+ import { Mapper } from './Mapper'
4
+ import { logger } from '@contember/logger'
5
+
6
+ export class BeforeInsertEvent {
7
+ public type = 'BeforeInsertEvent' as const
8
+
9
+ public afterEvent: AfterInsertEvent | undefined = undefined
10
+
11
+ constructor(
12
+ public readonly entity: Model.Entity,
13
+ public readonly data: ResolvedColumnValue[],
14
+ ) {
15
+ }
16
+ }
17
+
18
+ export class AfterInsertEvent {
19
+ public type = 'AfterInsertEvent' as const
20
+
21
+ constructor(
22
+ public readonly entity: Model.Entity,
23
+ public readonly data: ResolvedColumnValue[],
24
+ public readonly id: Input.PrimaryValue,
25
+ ) {
26
+ }
27
+ }
28
+
29
+
30
+ export class BeforeUpdateEvent {
31
+ public type = 'BeforeUpdateEvent' as const
32
+
33
+ public afterEvent: AfterUpdateEvent | undefined = undefined
34
+
35
+ constructor(
36
+ public readonly entity: Model.Entity,
37
+ public readonly data: ResolvedColumnValue[],
38
+ public readonly id: Input.PrimaryValue,
39
+ ) {
40
+ }
41
+ }
42
+
43
+ export class AfterUpdateEvent {
44
+ public type = 'AfterUpdateEvent' as const
45
+
46
+ private _hasChanges: boolean | undefined
47
+
48
+ constructor(
49
+ public readonly entity: Model.Entity,
50
+ public readonly data: (ResolvedColumnValue & { old: Value.FieldValue })[],
51
+ public readonly id: Input.PrimaryValue,
52
+ ) {
53
+ }
54
+ get hasChanges() {
55
+ // todo: deep equals
56
+ return this._hasChanges = this.data.some(it => it.resolvedValue !== it.old)
57
+ }
58
+ }
59
+
60
+ export class BeforeDeleteEvent {
61
+ public type = 'BeforeDeleteEvent' as const
62
+
63
+ constructor(
64
+ public readonly entity: Model.Entity,
65
+ public readonly id: Input.PrimaryValue,
66
+ ) {
67
+ }
68
+ }
69
+
70
+ export class BeforeJunctionUpdateEvent {
71
+ public type = 'BeforeJunctionUpdateEvent' as const
72
+
73
+ public afterEvent: AfterJunctionUpdateEvent | undefined = undefined
74
+
75
+ constructor(
76
+ public readonly owningEntity: Model.Entity,
77
+ public readonly owningRelation: Model.ManyHasManyOwningRelation,
78
+ public readonly owningId: Input.PrimaryValue,
79
+ public readonly inverseId: Input.PrimaryValue,
80
+ public readonly operation: 'connect' | 'disconnect',
81
+ ) {
82
+ }
83
+ }
84
+
85
+
86
+ export class AfterJunctionUpdateEvent {
87
+ public type = 'AfterJunctionUpdateEvent' as const
88
+
89
+ constructor(
90
+ public readonly owningEntity: Model.Entity,
91
+ public readonly owningRelation: Model.ManyHasManyOwningRelation,
92
+ public readonly owningId: Input.PrimaryValue,
93
+ public readonly inverseId: Input.PrimaryValue,
94
+ public readonly operation: 'connect' | 'disconnect',
95
+ public readonly hasChanges: boolean,
96
+ ) {
97
+ }
98
+ }
99
+
100
+ export class BeforeCommitEvent {
101
+ public type = 'BeforeCommitEvent' as const
102
+ }
103
+
104
+ export class AfterCommitEvent {
105
+ public type = 'AfterCommitEvent' as const
106
+ }
107
+
108
+ export type DataModificationEvent =
109
+ | BeforeInsertEvent
110
+ | AfterInsertEvent
111
+ | BeforeUpdateEvent
112
+ | AfterUpdateEvent
113
+ | BeforeJunctionUpdateEvent
114
+ | AfterJunctionUpdateEvent
115
+ | BeforeDeleteEvent
116
+
117
+ export type AnyEvent =
118
+ | DataModificationEvent
119
+ | BeforeCommitEvent
120
+ | AfterCommitEvent
121
+
122
+ export type EventMap<E extends AnyEvent = AnyEvent> = {
123
+ [K in E['type']]: E extends { type: K } ? E : never
124
+ }
125
+
126
+ export type EventListener<K extends keyof EventMap> = (event: EventMap[K], mapper: Mapper) => Promise<void>
127
+
128
+ export class EventManager {
129
+ private listeners: { [K in keyof EventMap]: EventListener<K>[] } = {
130
+ BeforeInsertEvent: [],
131
+ AfterInsertEvent: [],
132
+ BeforeUpdateEvent: [],
133
+ AfterUpdateEvent: [],
134
+ BeforeDeleteEvent: [],
135
+ BeforeCommitEvent: [],
136
+ AfterCommitEvent: [],
137
+ BeforeJunctionUpdateEvent: [],
138
+ AfterJunctionUpdateEvent: [],
139
+ }
140
+
141
+ constructor(
142
+ private readonly mapper: Mapper,
143
+ ) {
144
+ }
145
+
146
+ public listen<K extends keyof EventMap>(type: K, cb: EventListener<K>) {
147
+ this.listeners[type].push(cb)
148
+ }
149
+
150
+ public async fire<K extends keyof EventMap>(event: EventMap[K]) {
151
+ (await Promise.allSettled(this.listeners[event.type].map(it => (it as EventListener<K>)(event, this.mapper))))
152
+ .map(it => {
153
+ if (it.status === 'rejected') {
154
+ logger.error(it.reason)
155
+ }
156
+ })
157
+ }
158
+ }
@@ -1,6 +1,5 @@
1
1
  import { getEntity } from '@contember/schema-utils'
2
- import { PathFactory } from './select'
3
- import { WhereBuilder } from './select'
2
+ import { PathFactory, WhereBuilder } from './select'
4
3
  import { PredicateFactory } from '../acl'
5
4
  import {
6
5
  Client,
@@ -16,14 +15,21 @@ import {
16
15
  MutationJunctionUpdateOk,
17
16
  MutationNoResultError,
18
17
  MutationNothingToDo,
19
- MutationResult,
20
18
  MutationResultList,
19
+ MutationResultType,
21
20
  NothingToDoReason,
22
21
  } from './Result'
23
22
  import { ImplementationException } from '../exception'
23
+ import { AfterJunctionUpdateEvent, BeforeJunctionUpdateEvent } from './EventManager'
24
+ import { Mapper } from './Mapper'
24
25
 
25
26
  type OkResultFactory = () => MutationJunctionUpdateOk
26
27
 
28
+ type JunctionMutationResult =
29
+ | MutationJunctionUpdateOk
30
+ | MutationNothingToDo
31
+ | MutationNoResultError
32
+
27
33
  export class JunctionTableManager {
28
34
  constructor(
29
35
  private readonly schema: Model.Schema,
@@ -35,43 +41,55 @@ export class JunctionTableManager {
35
41
  ) {}
36
42
 
37
43
  public async connectJunction(
38
- db: Client,
44
+ mapper: Mapper,
39
45
  owningEntity: Model.Entity,
40
46
  relation: Model.ManyHasManyOwningRelation,
41
47
  owningUnique: Input.PrimaryValue,
42
48
  inverseUnique: Input.PrimaryValue,
43
49
  ): Promise<MutationResultList> {
44
- return [
45
- await this.executeJunctionModification(
46
- db,
47
- owningEntity,
48
- relation,
49
- owningUnique,
50
- inverseUnique,
51
- this.connectJunctionHandler,
52
- ),
53
- ]
50
+ const beforeEvent = new BeforeJunctionUpdateEvent(owningEntity, relation, owningUnique, inverseUnique, 'connect')
51
+ await mapper.eventManager.fire(beforeEvent)
52
+ const result = await this.executeJunctionModification(
53
+ mapper.db,
54
+ owningEntity,
55
+ relation,
56
+ owningUnique,
57
+ inverseUnique,
58
+ this.connectJunctionHandler,
59
+ )
60
+ if (result.result !== MutationResultType.noResultError) {
61
+ const afterEvent = new AfterJunctionUpdateEvent(owningEntity, relation, owningUnique, inverseUnique, 'connect', result.result === MutationResultType.ok)
62
+ await mapper.eventManager.fire(afterEvent)
63
+ }
64
+ return [result]
54
65
  }
55
66
 
56
67
  public async disconnectJunction(
57
- db: Client,
68
+ mapper: Mapper,
58
69
  owningEntity: Model.Entity,
59
70
  relation: Model.ManyHasManyOwningRelation,
60
71
  owningUnique: Input.PrimaryValue,
61
72
  inverseUnique: Input.PrimaryValue,
62
73
  ): Promise<MutationResultList> {
63
- return [
64
- await this.executeJunctionModification(
65
- db,
66
- owningEntity,
67
- relation,
68
- owningUnique,
69
- inverseUnique,
70
- this.disconnectJunctionHandler,
71
- ),
72
- ]
74
+ const beforeEvent = new BeforeJunctionUpdateEvent(owningEntity, relation, owningUnique, inverseUnique, 'connect')
75
+ await mapper.eventManager.fire(beforeEvent)
76
+ const result = await this.executeJunctionModification(
77
+ mapper.db,
78
+ owningEntity,
79
+ relation,
80
+ owningUnique,
81
+ inverseUnique,
82
+ this.disconnectJunctionHandler,
83
+ )
84
+ if (result.result !== MutationResultType.noResultError) {
85
+ const afterEvent = new AfterJunctionUpdateEvent(owningEntity, relation, owningUnique, inverseUnique, 'disconnect', result.result === MutationResultType.ok)
86
+ beforeEvent.afterEvent = afterEvent
87
+ await mapper.eventManager.fire(afterEvent)
88
+ }
89
+ return [result]
73
90
  }
74
91
 
92
+
75
93
  private async executeJunctionModification(
76
94
  db: Client,
77
95
  owningEntity: Model.Entity,
@@ -79,7 +97,7 @@ export class JunctionTableManager {
79
97
  owningPrimary: Input.PrimaryValue,
80
98
  inversePrimary: Input.PrimaryValue,
81
99
  handler: JunctionHandler,
82
- ): Promise<MutationResult> {
100
+ ): Promise<JunctionMutationResult> {
83
101
  const joiningTable = relation.joiningTable
84
102
  const inverseEntity = getEntity(this.schema, relation.target)
85
103
  if (inverseEntity.view || owningEntity.view) {
@@ -145,9 +163,9 @@ interface JunctionComplexExecutionArgs {
145
163
  }
146
164
 
147
165
  interface JunctionHandler {
148
- executeSimple(args: JunctionSimpleExecutionArgs): Promise<MutationResult>
166
+ executeSimple(args: JunctionSimpleExecutionArgs): Promise<JunctionMutationResult>
149
167
 
150
- executeComplex(args: JunctionComplexExecutionArgs): Promise<MutationResult>
168
+ executeComplex(args: JunctionComplexExecutionArgs): Promise<JunctionMutationResult>
151
169
  }
152
170
 
153
171
  export class JunctionConnectHandler implements JunctionHandler {
@@ -157,7 +175,7 @@ export class JunctionConnectHandler implements JunctionHandler {
157
175
  owningPrimary,
158
176
  inversePrimary,
159
177
  okResultFactory,
160
- }: JunctionSimpleExecutionArgs): Promise<MutationResult> {
178
+ }: JunctionSimpleExecutionArgs): Promise<JunctionMutationResult> {
161
179
  const result = await InsertBuilder.create()
162
180
  .into(joiningTable.tableName)
163
181
  .values({
@@ -177,7 +195,7 @@ export class JunctionConnectHandler implements JunctionHandler {
177
195
  joiningTable,
178
196
  dataCallback,
179
197
  okResultFactory,
180
- }: JunctionComplexExecutionArgs): Promise<MutationResult> {
198
+ }: JunctionComplexExecutionArgs): Promise<JunctionMutationResult> {
181
199
  const insert = InsertBuilder.create()
182
200
  .into(joiningTable.tableName)
183
201
  .values({
@@ -216,7 +234,7 @@ export class JunctionDisconnectHandler implements JunctionHandler {
216
234
  owningPrimary,
217
235
  inversePrimary,
218
236
  okResultFactory,
219
- }: JunctionSimpleExecutionArgs): Promise<MutationResult> {
237
+ }: JunctionSimpleExecutionArgs): Promise<JunctionMutationResult> {
220
238
  const qb = DeleteBuilder.create()
221
239
  .from(joiningTable.tableName)
222
240
  .where(cond => cond.compare(joiningTable.joiningColumn.columnName, Operator.eq, owningPrimary))
@@ -234,7 +252,7 @@ export class JunctionDisconnectHandler implements JunctionHandler {
234
252
  joiningTable,
235
253
  dataCallback,
236
254
  okResultFactory,
237
- }: JunctionComplexExecutionArgs): Promise<MutationResult> {
255
+ }: JunctionComplexExecutionArgs): Promise<JunctionMutationResult> {
238
256
  const deleteQb = DeleteBuilder.create()
239
257
  .from(joiningTable.tableName)
240
258
  .using('data')
@@ -1,5 +1,5 @@
1
1
  import { Input, Model } from '@contember/schema'
2
- import { acceptFieldVisitor, getColumnName } from '@contember/schema-utils'
2
+ import { acceptFieldVisitor, getColumnName, SchemaDatabaseMetadata } from '@contember/schema-utils'
3
3
  import {
4
4
  OrderByHelper,
5
5
  PathFactory,
@@ -10,8 +10,7 @@ import {
10
10
  SelectResultObject,
11
11
  WhereBuilder,
12
12
  } from './select'
13
- import * as database from '@contember/database'
14
- import { Client, ConstraintHelper, SelectBuilder } from '@contember/database'
13
+ import { Client, Connection, ConstraintHelper, SelectBuilder } from '@contember/database'
15
14
  import { PredicatesInjector } from '../acl'
16
15
  import { JunctionTableManager } from './JunctionTableManager'
17
16
  import { DeletedEntitiesStorage, DeleteExecutor } from './delete'
@@ -23,16 +22,23 @@ import { ObjectNode, UniqueWhereExpander } from '../inputProcessing'
23
22
  import { Mutex } from '../utils'
24
23
  import { CheckedPrimary } from './CheckedPrimary'
25
24
  import { ImplementationException } from '../exception'
25
+ import { EventManager } from './EventManager'
26
26
 
27
- export class Mapper {
27
+ export class Mapper<ConnectionType extends Connection.ConnectionLike = Connection.ConnectionLike> {
28
28
  private primaryKeyCache: Record<string, Promise<string> | string> = {}
29
+ private systemVariablesSetupDone: Promise<void> | undefined
29
30
  public readonly deletedEntities = new DeletedEntitiesStorage()
30
31
  public readonly mutex = new Mutex()
31
32
  public readonly constraintHelper: ConstraintHelper
32
33
 
34
+ public readonly eventManager: EventManager
35
+
33
36
  constructor(
37
+ public readonly db: Client<ConnectionType>,
38
+ public readonly identityId: string,
39
+ public readonly transactionId: string,
34
40
  private readonly schema: Model.Schema,
35
- public readonly db: database.Client,
41
+ private readonly schemaDatabaseMetadata: SchemaDatabaseMetadata,
36
42
  private readonly predicatesInjector: PredicatesInjector,
37
43
  private readonly selectBuilderFactory: SelectBuilderFactory,
38
44
  private readonly uniqueWhereExpander: UniqueWhereExpander,
@@ -44,6 +50,7 @@ export class Mapper {
44
50
  private readonly pathFactory: PathFactory,
45
51
  ) {
46
52
  this.constraintHelper = new ConstraintHelper(db)
53
+ this.eventManager = new EventManager(this)
47
54
  }
48
55
 
49
56
  public async selectField(entity: Model.Entity, where: Input.UniqueWhere | CheckedPrimary, fieldName: string) {
@@ -122,7 +129,7 @@ export class Mapper {
122
129
  relationPath: Model.AnyRelationContext[],
123
130
  groupBy?: string,
124
131
  ) {
125
- const inputWithOrder = OrderByHelper.appendDefaultOrderBy(entity, input, [])
132
+ const inputWithOrder = OrderByHelper.appendDefaultOrderBy(entity, input, undefined)
126
133
  const path = this.pathFactory.create([])
127
134
  const augmentedBuilder = qb.from(entity.tableName, path.alias).meta('path', [...input.path, input.alias])
128
135
 
@@ -174,12 +181,9 @@ export class Mapper {
174
181
  if (entity.view) {
175
182
  throw new ImplementationException()
176
183
  }
177
- const pushId = (id: string) => {
178
- const where = { [entity.primary]: id }
179
- this.primaryKeyCache[this.hashWhere(entity.name, where)] = id
180
- }
181
- return tryMutation(this.schema, () =>
182
- this.inserter.insert(this, entity, data, pushId, builderCb),
184
+ await this.setupSystemVariables()
185
+ return tryMutation(this.schema, this.schemaDatabaseMetadata, () =>
186
+ this.insertInternal(entity, data, builderCb),
183
187
  )
184
188
  }
185
189
 
@@ -192,7 +196,8 @@ export class Mapper {
192
196
  if (entity.view) {
193
197
  throw new ImplementationException()
194
198
  }
195
- return tryMutation(this.schema, async () => {
199
+ await this.setupSystemVariables()
200
+ return tryMutation(this.schema, this.schemaDatabaseMetadata, async () => {
196
201
  const primaryValue = await this.getPrimaryValue(entity, by)
197
202
  if (primaryValue === undefined) {
198
203
  return [new MutationEntryNotFoundError([], by)]
@@ -209,7 +214,8 @@ export class Mapper {
209
214
  if (entity.view) {
210
215
  throw new ImplementationException()
211
216
  }
212
- return tryMutation(this.schema, async () => {
217
+ await this.setupSystemVariables()
218
+ return tryMutation(this.schema, this.schemaDatabaseMetadata, async () => {
213
219
  const primaryValue = await this.getPrimaryValue(entity, by)
214
220
  if (primaryValue === undefined) {
215
221
  return [new MutationEntryNotFoundError([], by as Input.UniqueWhere)]
@@ -227,19 +233,23 @@ export class Mapper {
227
233
  if (entity.view) {
228
234
  throw new ImplementationException()
229
235
  }
230
- return tryMutation(this.schema, async () => {
236
+ await this.setupSystemVariables()
237
+ return tryMutation(this.schema, this.schemaDatabaseMetadata, async () => {
231
238
  const primaryValue = await this.getPrimaryValue(entity, by)
232
239
  if (primaryValue === undefined) {
233
- const pushIdCallback = (id: string) => {
234
- const where = { [entity.primary]: id }
235
- this.primaryKeyCache[this.hashWhere(entity.name, where)] = id
236
- }
237
- return await this.inserter.insert(this, entity, create, pushIdCallback, () => {})
240
+ return await this.insertInternal(entity, create)
238
241
  }
239
242
  return await this.updater.update(this, entity, primaryValue, update, filter)
240
243
  })
241
244
  }
242
245
 
246
+ private insertInternal(entity: Model.Entity, data: Input.CreateDataInput, builderCb: (builder: InsertBuilder) => void = () => {}) {
247
+ return this.inserter.insert(this, entity, data, id => {
248
+ const where = { [entity.primary]: id }
249
+ this.primaryKeyCache[this.hashWhere(entity.name, where)] = id
250
+ }, builderCb)
251
+ }
252
+
243
253
  public async delete(
244
254
  entity: Model.Entity,
245
255
  by: Input.UniqueWhere | CheckedPrimary,
@@ -248,7 +258,10 @@ export class Mapper {
248
258
  if (entity.view) {
249
259
  throw new ImplementationException()
250
260
  }
251
- return tryMutation(this.schema, () => this.deleteExecutor.execute(this, entity, by, filter))
261
+ await this.setupSystemVariables()
262
+ return tryMutation(this.schema, this.schemaDatabaseMetadata, () => {
263
+ return this.deleteExecutor.execute(this, entity, by, filter)
264
+ })
252
265
  }
253
266
 
254
267
  public async connectJunction(
@@ -257,15 +270,16 @@ export class Mapper {
257
270
  thisPrimary: Input.PrimaryValue,
258
271
  otherPrimary: Input.PrimaryValue,
259
272
  ): Promise<MutationResultList> {
273
+ await this.setupSystemVariables()
260
274
  const err = () => {
261
275
  throw new ImplementationException()
262
276
  }
263
277
  return await acceptFieldVisitor(this.schema, entity, relation, {
264
278
  visitManyHasManyOwning: ({ entity, relation }) => {
265
- return this.junctionTableManager.connectJunction(this.db, entity, relation, thisPrimary, otherPrimary)
279
+ return this.junctionTableManager.connectJunction(this, entity, relation, thisPrimary, otherPrimary)
266
280
  },
267
281
  visitManyHasManyInverse: ({ targetEntity, targetRelation }) => {
268
- return this.junctionTableManager.connectJunction(this.db, targetEntity, targetRelation, otherPrimary, thisPrimary)
282
+ return this.junctionTableManager.connectJunction(this, targetEntity, targetRelation, otherPrimary, thisPrimary)
269
283
  },
270
284
  visitColumn: err,
271
285
  visitOneHasMany: err,
@@ -281,15 +295,16 @@ export class Mapper {
281
295
  thisPrimary: Input.PrimaryValue,
282
296
  otherPrimary: Input.PrimaryValue,
283
297
  ): Promise<MutationResultList> {
298
+ await this.setupSystemVariables()
284
299
  const err = () => {
285
300
  throw new ImplementationException()
286
301
  }
287
302
  return await acceptFieldVisitor(this.schema, entity, relation, {
288
303
  visitManyHasManyOwning: ({ entity, relation }) => {
289
- return this.junctionTableManager.disconnectJunction(this.db, entity, relation, thisPrimary, otherPrimary)
304
+ return this.junctionTableManager.disconnectJunction(this, entity, relation, thisPrimary, otherPrimary)
290
305
  },
291
306
  visitManyHasManyInverse: ({ targetEntity, targetRelation }) => {
292
- return this.junctionTableManager.disconnectJunction(this.db, targetEntity, targetRelation, otherPrimary, thisPrimary)
307
+ return this.junctionTableManager.disconnectJunction(this, targetEntity, targetRelation, otherPrimary, thisPrimary)
293
308
  },
294
309
  visitColumn: err,
295
310
  visitOneHasMany: err,
@@ -323,6 +338,12 @@ export class Mapper {
323
338
  private hashWhere(entityName: string, where: Input.UniqueWhere): string {
324
339
  return JSON.stringify([entityName, where])
325
340
  }
326
- }
327
341
 
328
- export type MapperFactory = (db: Client) => Mapper
342
+ private async setupSystemVariables() {
343
+ this.systemVariablesSetupDone ??= (async () => {
344
+ await this.db.query('SELECT set_config(?, ?, false)', ['tenant.identity_id', this.identityId]) // todo rename to system.identity_id
345
+ await this.db.query('SELECT set_config(?, ?, false)', ['system.transaction_id', this.transactionId])
346
+ })()
347
+ await this.systemVariablesSetupDone
348
+ }
349
+ }
@@ -0,0 +1,69 @@
1
+ import { PredicatesInjector } from '../acl'
2
+ import { PathFactory, SelectBuilderFactory, WhereBuilder } from './select'
3
+ import { UniqueWhereExpander } from '../inputProcessing'
4
+ import { JunctionTableManager } from './JunctionTableManager'
5
+ import { DeleteExecutor } from './delete'
6
+ import { Updater } from './update'
7
+ import { Inserter } from './insert'
8
+ import { Model } from '@contember/schema'
9
+ import { Client, Connection } from '@contember/database'
10
+ import { Mapper } from './Mapper'
11
+ import { Providers, SchemaDatabaseMetadata } from '@contember/schema-utils'
12
+
13
+ export type MapperFactoryHook = (mapper: Mapper) => void
14
+
15
+ export class MapperFactory {
16
+
17
+ public readonly hooks: MapperFactoryHook[] = []
18
+
19
+ constructor(
20
+ private readonly db: Client,
21
+ private readonly identityId: string,
22
+ private readonly schema: Model.Schema,
23
+ private readonly schemaDatabaseMetadata: SchemaDatabaseMetadata,
24
+ private readonly predicatesInjector: PredicatesInjector,
25
+ private readonly selectBuilderFactory: SelectBuilderFactory,
26
+ private readonly uniqueWhereExpander: UniqueWhereExpander,
27
+ private readonly whereBuilder: WhereBuilder,
28
+ private readonly junctionTableManager: JunctionTableManager,
29
+ private readonly deleteExecutor: DeleteExecutor,
30
+ private readonly updater: Updater,
31
+ private readonly inserter: Inserter,
32
+ private readonly pathFactory: PathFactory,
33
+ private readonly providers: Providers,
34
+ ) {
35
+ }
36
+
37
+ public create() {
38
+ return this.createInternal(this.db)
39
+ }
40
+
41
+ public transaction<T>(cb: (mapper: Mapper<Connection.TransactionLike>) => Promise<T>): Promise<T> {
42
+ return this.db.transaction(async trx => {
43
+ await trx.connection.query(Connection.REPEATABLE_READ)
44
+ const mapper = this.createInternal(trx)
45
+ return await cb(mapper)
46
+ })
47
+ }
48
+
49
+ private createInternal<T extends Connection.ConnectionLike>(db: Client<T>) {
50
+ const mapper = new Mapper<T>(
51
+ db,
52
+ this.identityId,
53
+ this.providers.uuid(),
54
+ this.schema,
55
+ this.schemaDatabaseMetadata,
56
+ this.predicatesInjector,
57
+ this.selectBuilderFactory,
58
+ this.uniqueWhereExpander,
59
+ this.whereBuilder,
60
+ this.junctionTableManager,
61
+ this.deleteExecutor,
62
+ this.updater,
63
+ this.inserter,
64
+ this.pathFactory,
65
+ )
66
+ this.hooks.forEach(it => it(mapper))
67
+ return mapper
68
+ }
69
+ }
@@ -3,6 +3,7 @@ import { convertError } from './ErrorUtils'
3
3
  import { getFulfilledValues, getRejections } from '../utils'
4
4
  import { SerializationFailureError } from '@contember/database'
5
5
  import { logger } from '@contember/logger'
6
+ import { SchemaDatabaseMetadata } from '@contember/schema-utils'
6
7
 
7
8
  export enum MutationResultType {
8
9
  ok = 'ok',
@@ -50,7 +51,7 @@ interface MutationResultInterface {
50
51
  hints: MutationResultHint[]
51
52
  }
52
53
 
53
- export type RowValues = { [fieldName: string]: Value.AtomicValue }
54
+ export type RowValues = { [fieldName: string]: Value.FieldValue }
54
55
 
55
56
  export class MutationUpdateOk implements MutationResultInterface {
56
57
  result = MutationResultType.ok as const
@@ -63,6 +64,7 @@ export class MutationUpdateOk implements MutationResultInterface {
63
64
  public readonly primary: Value.PrimaryValue,
64
65
  public readonly input: Input.UpdateDataInput,
65
66
  public readonly values: RowValues,
67
+ public readonly oldValues?: RowValues,
66
68
  ) {}
67
69
  }
68
70
 
@@ -211,6 +213,7 @@ export type ResultListNotFlatten = MutationResultList | MutationResultList[]
211
213
 
212
214
  export const collectResults = async (
213
215
  schema: Model.Schema,
216
+ schemaDatabaseMetadata: SchemaDatabaseMetadata,
214
217
  mainPromise: Promise<ResultListNotFlatten | undefined> | undefined,
215
218
  otherPromises: (Promise<ResultListNotFlatten | undefined> | undefined)[],
216
219
  ): Promise<MutationResultList> => {
@@ -219,7 +222,7 @@ export const collectResults = async (
219
222
  .filter((it): it is Promise<ResultListNotFlatten> => !!it)
220
223
  .map(it =>
221
224
  it //
222
- .catch(e => [convertError(schema, e)])
225
+ .catch(e => [convertError(schema, schemaDatabaseMetadata, e)])
223
226
  .then(value => ({ value, index: index++ })),
224
227
  )
225
228
  const results = await Promise.allSettled(allPromises)
@@ -26,6 +26,8 @@ import {
26
26
  OneHasOneOwningRelationTuple,
27
27
  } from './helpers'
28
28
  import { getEntity } from '@contember/schema-utils'
29
+ import { AfterUpdateEvent, BeforeDeleteEvent, BeforeUpdateEvent, EventManager } from '../EventManager'
30
+ import { ImplementationException } from '../../exception'
29
31
 
30
32
  type DeleteQueue = [entity: Model.Entity, ids: Input.PrimaryValue[]][]
31
33
 
@@ -67,7 +69,46 @@ export class DeleteExecutor {
67
69
  if (!state.isOk()) {
68
70
  return state.getResult()
69
71
  }
72
+ const result = state.getResult()
73
+ const entryToEventMap = new Map<MutationUpdateOk, BeforeUpdateEvent>()
74
+ for (const entry of result) {
75
+ if (entry instanceof MutationDeleteOk) {
76
+ await mapper.eventManager.fire(new BeforeDeleteEvent(entry.entity, entry.primary))
77
+ } else if (entry instanceof MutationUpdateOk) {
78
+ const beforeUpdateEvent = new BeforeUpdateEvent(entry.entity, [{
79
+ columnName: Object.keys(entry.values)[0],
80
+ fieldName: Object.keys(entry.input)[0],
81
+ columnType: 'text',
82
+ resolvedValue: null,
83
+ value: Promise.resolve(null),
84
+ }], entry.primary)
85
+ entryToEventMap.set(entry, beforeUpdateEvent)
86
+ await mapper.eventManager.fire(beforeUpdateEvent)
87
+ }
88
+ }
89
+
70
90
  await this.executeDeletes(deleteQueue, mapper.db)
91
+
92
+ for (const entry of result) {
93
+ if (entry instanceof MutationUpdateOk) {
94
+ const beforeEvent = entryToEventMap.get(entry)
95
+ if (!beforeEvent) {
96
+ throw new ImplementationException()
97
+ }
98
+ const data = [{
99
+ columnName: Object.keys(entry.values)[0],
100
+ fieldName: Object.keys(entry.input)[0],
101
+ columnType: 'text',
102
+ resolvedValue: null,
103
+ value: Promise.resolve(null),
104
+ old: Object.values(entry.oldValues ?? {})[0],
105
+ }]
106
+ const afterEvent = new AfterUpdateEvent(entry.entity, data, entry.primary)
107
+ beforeEvent.afterEvent = afterEvent
108
+ await mapper.eventManager.fire(afterEvent)
109
+ }
110
+ }
111
+
71
112
  state.confirmDeleted()
72
113
 
73
114
  return state.getResult()
@@ -190,7 +231,7 @@ export class DeleteExecutor {
190
231
  const input = { [relation.name]: { disconnect: true } }
191
232
  const values = { [relation.joiningColumn.columnName]: null }
192
233
 
193
- state.pushOkResult(result.map(it => it.id).map(id => new MutationUpdateOk([], entity, id, input, values)))
234
+ state.pushOkResult(result.map(it => new MutationUpdateOk([], entity, it.id, input, values, { [relation.joiningColumn.columnName]: it.ref })))
194
235
  return
195
236
  }
196
237