@contember/engine-content-api 1.2.0-alpha.9 → 1.2.0-beta.2

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 (378) hide show
  1. package/dist/src/acl/EvaluatedPredicateReplacer.d.ts +2 -3
  2. package/dist/src/acl/EvaluatedPredicateReplacer.d.ts.map +1 -1
  3. package/dist/src/acl/EvaluatedPredicateReplacer.js +5 -14
  4. package/dist/src/acl/EvaluatedPredicateReplacer.js.map +1 -1
  5. package/dist/src/acl/PredicateFactory.d.ts +9 -3
  6. package/dist/src/acl/PredicateFactory.d.ts.map +1 -1
  7. package/dist/src/acl/PredicateFactory.js +47 -36
  8. package/dist/src/acl/PredicateFactory.js.map +1 -1
  9. package/dist/src/acl/PredicatesInjector.d.ts +1 -1
  10. package/dist/src/acl/PredicatesInjector.d.ts.map +1 -1
  11. package/dist/src/acl/PredicatesInjector.js +13 -18
  12. package/dist/src/acl/PredicatesInjector.js.map +1 -1
  13. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.d.ts +0 -1
  14. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.d.ts.map +1 -1
  15. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.js +26 -23
  16. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.js.map +1 -1
  17. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts +1 -1
  18. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts.map +1 -1
  19. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js +1 -1
  20. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js.map +1 -1
  21. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.d.ts +5 -4
  22. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.d.ts.map +1 -1
  23. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js +11 -14
  24. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js.map +1 -1
  25. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.d.ts.map +1 -1
  26. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.js +18 -14
  27. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.js.map +1 -1
  28. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts +3 -3
  29. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts.map +1 -1
  30. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js +3 -3
  31. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js.map +1 -1
  32. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.d.ts +5 -4
  33. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.d.ts.map +1 -1
  34. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js +11 -15
  35. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js.map +1 -1
  36. package/dist/src/input-validation/ColumnValueResolver.d.ts +4 -3
  37. package/dist/src/input-validation/ColumnValueResolver.d.ts.map +1 -1
  38. package/dist/src/input-validation/ColumnValueResolver.js.map +1 -1
  39. package/dist/src/input-validation/EntityRulesResolver.js +4 -4
  40. package/dist/src/input-validation/EntityRulesResolver.js.map +1 -1
  41. package/dist/src/input-validation/QueryAstFactory.js +1 -1
  42. package/dist/src/input-validation/QueryAstFactory.js.map +1 -1
  43. package/dist/src/input-validation/ValidationDataSelector.js +1 -1
  44. package/dist/src/input-validation/ValidationDataSelector.js.map +1 -1
  45. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.d.ts +7 -8
  46. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.d.ts.map +1 -1
  47. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.js.map +1 -1
  48. package/dist/src/input-validation/preValidation/InputPreValidator.js +4 -4
  49. package/dist/src/input-validation/preValidation/InputPreValidator.js.map +1 -1
  50. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.d.ts +7 -8
  51. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.d.ts.map +1 -1
  52. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.js.map +1 -1
  53. package/dist/src/inputProcessing/CreateInputProcessor.d.ts +8 -9
  54. package/dist/src/inputProcessing/CreateInputProcessor.d.ts.map +1 -1
  55. package/dist/src/inputProcessing/CreateInputVisitor.d.ts +7 -7
  56. package/dist/src/inputProcessing/CreateInputVisitor.d.ts.map +1 -1
  57. package/dist/src/inputProcessing/CreateInputVisitor.js +15 -46
  58. package/dist/src/inputProcessing/CreateInputVisitor.js.map +1 -1
  59. package/dist/src/inputProcessing/UpdateInputProcessor.d.ts +8 -9
  60. package/dist/src/inputProcessing/UpdateInputProcessor.d.ts.map +1 -1
  61. package/dist/src/inputProcessing/UpdateInputVisitor.d.ts +7 -7
  62. package/dist/src/inputProcessing/UpdateInputVisitor.d.ts.map +1 -1
  63. package/dist/src/inputProcessing/UpdateInputVisitor.js +13 -28
  64. package/dist/src/inputProcessing/UpdateInputVisitor.js.map +1 -1
  65. package/dist/src/inputProcessing/index.d.ts +0 -1
  66. package/dist/src/inputProcessing/index.d.ts.map +1 -1
  67. package/dist/src/inputProcessing/index.js +0 -1
  68. package/dist/src/inputProcessing/index.js.map +1 -1
  69. package/dist/src/introspection/IntrospectionSchemaFactory.js +7 -7
  70. package/dist/src/introspection/IntrospectionSchemaFactory.js.map +1 -1
  71. package/dist/src/mapper/ErrorUtils.d.ts.map +1 -1
  72. package/dist/src/mapper/ErrorUtils.js +2 -2
  73. package/dist/src/mapper/ErrorUtils.js.map +1 -1
  74. package/dist/src/mapper/JunctionTableManager.js.map +1 -1
  75. package/dist/src/mapper/Mapper.d.ts +6 -6
  76. package/dist/src/mapper/Mapper.d.ts.map +1 -1
  77. package/dist/src/mapper/Mapper.js +26 -21
  78. package/dist/src/mapper/Mapper.js.map +1 -1
  79. package/dist/src/mapper/MapperContainer.d.ts.map +1 -1
  80. package/dist/src/mapper/MapperContainer.js +4 -4
  81. package/dist/src/mapper/MapperContainer.js.map +1 -1
  82. package/dist/src/mapper/Result.d.ts.map +1 -1
  83. package/dist/src/mapper/Result.js +2 -4
  84. package/dist/src/mapper/Result.js.map +1 -1
  85. package/dist/src/mapper/delete/DeleteExecutor.js +6 -6
  86. package/dist/src/mapper/delete/DeleteExecutor.js.map +1 -1
  87. package/dist/src/mapper/insert/InsertBuilder.d.ts +1 -1
  88. package/dist/src/mapper/insert/InsertBuilder.d.ts.map +1 -1
  89. package/dist/src/mapper/insert/InsertBuilder.js.map +1 -1
  90. package/dist/src/mapper/insert/SqlCreateInputProcessor.d.ts +4 -2
  91. package/dist/src/mapper/insert/SqlCreateInputProcessor.d.ts.map +1 -1
  92. package/dist/src/mapper/insert/SqlCreateInputProcessor.js.map +1 -1
  93. package/dist/src/mapper/select/JoinVisitor.d.ts +6 -6
  94. package/dist/src/mapper/select/JoinVisitor.d.ts.map +1 -1
  95. package/dist/src/mapper/select/JoinVisitor.js +6 -6
  96. package/dist/src/mapper/select/JoinVisitor.js.map +1 -1
  97. package/dist/src/mapper/select/Path.d.ts +1 -0
  98. package/dist/src/mapper/select/Path.d.ts.map +1 -1
  99. package/dist/src/mapper/select/Path.js +4 -1
  100. package/dist/src/mapper/select/Path.js.map +1 -1
  101. package/dist/src/mapper/select/RelationFetcher.d.ts +11 -19
  102. package/dist/src/mapper/select/RelationFetcher.d.ts.map +1 -1
  103. package/dist/src/mapper/select/RelationFetcher.js +34 -25
  104. package/dist/src/mapper/select/RelationFetcher.js.map +1 -1
  105. package/dist/src/mapper/select/SelectBuilder.d.ts +4 -1
  106. package/dist/src/mapper/select/SelectBuilder.d.ts.map +1 -1
  107. package/dist/src/mapper/select/SelectBuilder.js +52 -12
  108. package/dist/src/mapper/select/SelectBuilder.js.map +1 -1
  109. package/dist/src/mapper/select/SelectBuilderFactory.d.ts +2 -1
  110. package/dist/src/mapper/select/SelectBuilderFactory.d.ts.map +1 -1
  111. package/dist/src/mapper/select/SelectExecutionHandler.d.ts +16 -4
  112. package/dist/src/mapper/select/SelectExecutionHandler.d.ts.map +1 -1
  113. package/dist/src/mapper/select/SelectHydrator.d.ts +3 -2
  114. package/dist/src/mapper/select/SelectHydrator.d.ts.map +1 -1
  115. package/dist/src/mapper/select/SelectHydrator.js +6 -9
  116. package/dist/src/mapper/select/SelectHydrator.js.map +1 -1
  117. package/dist/src/mapper/select/WhereBuilder.d.ts +8 -4
  118. package/dist/src/mapper/select/WhereBuilder.d.ts.map +1 -1
  119. package/dist/src/mapper/select/WhereBuilder.js +137 -35
  120. package/dist/src/mapper/select/WhereBuilder.js.map +1 -1
  121. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts +10 -8
  122. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts.map +1 -1
  123. package/dist/src/mapper/select/handlers/FieldsVisitor.js +129 -94
  124. package/dist/src/mapper/select/handlers/FieldsVisitor.js.map +1 -1
  125. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.d.ts.map +1 -1
  126. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js +1 -1
  127. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js.map +1 -1
  128. package/dist/src/mapper/select/handlers/MetaHandler.d.ts.map +1 -1
  129. package/dist/src/mapper/select/handlers/MetaHandler.js +6 -11
  130. package/dist/src/mapper/select/handlers/MetaHandler.js.map +1 -1
  131. package/dist/src/mapper/select/optimizer/ConditionOptimizer.d.ts.map +1 -1
  132. package/dist/src/mapper/select/optimizer/ConditionOptimizer.js +6 -0
  133. package/dist/src/mapper/select/optimizer/ConditionOptimizer.js.map +1 -1
  134. package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts +9 -1
  135. package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts.map +1 -1
  136. package/dist/src/mapper/select/optimizer/WhereOptimizer.js +127 -13
  137. package/dist/src/mapper/select/optimizer/WhereOptimizer.js.map +1 -1
  138. package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts +3 -0
  139. package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts.map +1 -0
  140. package/dist/src/mapper/select/optimizer/WhereReplacer.js +46 -0
  141. package/dist/src/mapper/select/optimizer/WhereReplacer.js.map +1 -0
  142. package/dist/src/mapper/select/optimizer/helpers.d.ts +1 -1
  143. package/dist/src/mapper/select/optimizer/helpers.js +1 -1
  144. package/dist/src/mapper/select/optimizer/helpers.js.map +1 -1
  145. package/dist/src/mapper/update/SqlUpdateInputProcessor.d.ts +2 -3
  146. package/dist/src/mapper/update/SqlUpdateInputProcessor.d.ts.map +1 -1
  147. package/dist/src/mapper/update/SqlUpdateInputProcessor.js +3 -4
  148. package/dist/src/mapper/update/SqlUpdateInputProcessor.js.map +1 -1
  149. package/dist/src/mapper/update/UpdateBuilder.js +3 -3
  150. package/dist/src/mapper/update/UpdateBuilder.js.map +1 -1
  151. package/dist/src/resolvers/ExecutionContainerFactory.d.ts +1 -1
  152. package/dist/src/resolvers/ExecutionContainerFactory.d.ts.map +1 -1
  153. package/dist/src/resolvers/GraphQlQueryAstFactory.d.ts +1 -2
  154. package/dist/src/resolvers/GraphQlQueryAstFactory.d.ts.map +1 -1
  155. package/dist/src/resolvers/GraphQlQueryAstFactory.js +2 -2
  156. package/dist/src/resolvers/GraphQlQueryAstFactory.js.map +1 -1
  157. package/dist/src/resolvers/MutationResolver.d.ts.map +1 -1
  158. package/dist/src/resolvers/MutationResolver.js +13 -2
  159. package/dist/src/resolvers/MutationResolver.js.map +1 -1
  160. package/dist/src/resolvers/ReadHelpers.js +3 -3
  161. package/dist/src/resolvers/ReadHelpers.js.map +1 -1
  162. package/dist/src/resolvers/ReadResolver.js +2 -2
  163. package/dist/src/resolvers/ReadResolver.js.map +1 -1
  164. package/dist/src/schema/EnumsProvider.d.ts.map +1 -1
  165. package/dist/src/schema/EnumsProvider.js +1 -2
  166. package/dist/src/schema/EnumsProvider.js.map +1 -1
  167. package/dist/src/schema/FieldAccessVisitor.d.ts +2 -2
  168. package/dist/src/schema/FieldAccessVisitor.d.ts.map +1 -1
  169. package/dist/src/schema/FieldAccessVisitor.js +2 -2
  170. package/dist/src/schema/FieldAccessVisitor.js.map +1 -1
  171. package/dist/src/schema/OrderByTypeProvider.d.ts +1 -1
  172. package/dist/src/schema/OrderByTypeProvider.d.ts.map +1 -1
  173. package/dist/src/schema/OrderByTypeProvider.js +2 -2
  174. package/dist/src/schema/OrderByTypeProvider.js.map +1 -1
  175. package/dist/src/schema/WhereTypeProvider.d.ts +1 -2
  176. package/dist/src/schema/WhereTypeProvider.d.ts.map +1 -1
  177. package/dist/src/schema/WhereTypeProvider.js +4 -4
  178. package/dist/src/schema/WhereTypeProvider.js.map +1 -1
  179. package/dist/src/schema/entities/FieldArgsVisitor.d.ts +4 -5
  180. package/dist/src/schema/entities/FieldArgsVisitor.d.ts.map +1 -1
  181. package/dist/src/schema/entities/FieldArgsVisitor.js +3 -3
  182. package/dist/src/schema/entities/FieldArgsVisitor.js.map +1 -1
  183. package/dist/src/schema/entities/FieldTypeVisitor.d.ts +3 -3
  184. package/dist/src/schema/entities/FieldTypeVisitor.d.ts.map +1 -1
  185. package/dist/src/schema/entities/FieldTypeVisitor.js +3 -3
  186. package/dist/src/schema/entities/FieldTypeVisitor.js.map +1 -1
  187. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.d.ts +3 -3
  188. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.d.ts.map +1 -1
  189. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.js +3 -3
  190. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.js.map +1 -1
  191. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.d.ts +6 -6
  192. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.d.ts.map +1 -1
  193. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.js +6 -6
  194. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.js.map +1 -1
  195. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.d.ts +3 -3
  196. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.d.ts.map +1 -1
  197. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.js +5 -5
  198. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.js.map +1 -1
  199. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.d.ts +10 -4
  200. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.d.ts.map +1 -1
  201. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.js +3 -3
  202. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.js.map +1 -1
  203. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.d.ts +6 -6
  204. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.d.ts.map +1 -1
  205. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.js +6 -6
  206. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.js.map +1 -1
  207. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.d.ts +2 -2
  208. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.d.ts.map +1 -1
  209. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js +2 -2
  210. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js.map +1 -1
  211. package/dist/src/schema/utils.d.ts +1 -1
  212. package/dist/src/schema/utils.d.ts.map +1 -1
  213. package/dist/src/tsconfig.tsbuildinfo +1 -1
  214. package/dist/src/utils/uniqueWhereFields.js +3 -3
  215. package/dist/src/utils/uniqueWhereFields.js.map +1 -1
  216. package/dist/tests/cases/bugs/bug102.test.js +6 -6
  217. package/dist/tests/cases/bugs/bug102.test.js.map +1 -1
  218. package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js +5 -5
  219. package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js.map +1 -1
  220. package/dist/tests/cases/integration/graphQlRequests/delete/additionalDeleteFilter.test.js +5 -5
  221. package/dist/tests/cases/integration/graphQlRequests/delete/additionalDeleteFilter.test.js.map +1 -1
  222. package/dist/tests/cases/integration/graphQlRequests/delete/cascadeDelete.test.js +5 -5
  223. package/dist/tests/cases/integration/graphQlRequests/delete/cascadeDelete.test.js.map +1 -1
  224. package/dist/tests/cases/integration/graphQlRequests/delete/deleteById.test.js +5 -5
  225. package/dist/tests/cases/integration/graphQlRequests/delete/deleteById.test.js.map +1 -1
  226. package/dist/tests/cases/integration/graphQlRequests/delete/orphanRemoval.test.js +5 -5
  227. package/dist/tests/cases/integration/graphQlRequests/delete/orphanRemoval.test.js.map +1 -1
  228. package/dist/tests/cases/integration/graphQlRequests/delete/setNullOnDelete.test.js +5 -5
  229. package/dist/tests/cases/integration/graphQlRequests/delete/setNullOnDelete.test.js.map +1 -1
  230. package/dist/tests/cases/integration/graphQlRequests/query/acl/differentRowAndFieldPredicate.test.js +51 -4
  231. package/dist/tests/cases/integration/graphQlRequests/query/acl/differentRowAndFieldPredicate.test.js.map +1 -1
  232. package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js +26 -25
  233. package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js.map +1 -1
  234. package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js +9 -6
  235. package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js.map +1 -1
  236. package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.d.ts +2 -0
  237. package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.d.ts.map +1 -0
  238. package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.js +109 -0
  239. package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.js.map +1 -0
  240. package/dist/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.js +17 -15
  241. package/dist/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.js.map +1 -1
  242. package/dist/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.js +4 -5
  243. package/dist/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.js.map +1 -1
  244. package/dist/tests/cases/integration/graphQlRequests/query/graphqlFeatures/alias.test.js +9 -13
  245. package/dist/tests/cases/integration/graphQlRequests/query/graphqlFeatures/alias.test.js.map +1 -1
  246. package/dist/tests/cases/integration/graphQlRequests/query/unique/oneHasManyUnique.test.js +5 -3
  247. package/dist/tests/cases/integration/graphQlRequests/query/unique/oneHasManyUnique.test.js.map +1 -1
  248. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/delete.test.js +5 -5
  249. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/delete.test.js.map +1 -1
  250. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/delete.test.js +5 -5
  251. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/delete.test.js.map +1 -1
  252. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/delete.test.js +10 -10
  253. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/delete.test.js.map +1 -1
  254. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/combination.test.js +5 -5
  255. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/combination.test.js.map +1 -1
  256. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/delete.test.js +5 -5
  257. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/delete.test.js.map +1 -1
  258. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/delete.test.js +5 -5
  259. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/delete.test.js.map +1 -1
  260. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js +4 -4
  261. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js.map +1 -1
  262. package/dist/tests/cases/unit/predicatesFactory.test.js +7 -1
  263. package/dist/tests/cases/unit/predicatesFactory.test.js.map +1 -1
  264. package/dist/tests/cases/unit/predicatesInjector.test.js +105 -0
  265. package/dist/tests/cases/unit/predicatesInjector.test.js.map +1 -1
  266. package/dist/tests/cases/unit/whereBuilder.test.d.ts +2 -0
  267. package/dist/tests/cases/unit/whereBuilder.test.d.ts.map +1 -0
  268. package/dist/tests/cases/unit/whereBuilder.test.js +131 -0
  269. package/dist/tests/cases/unit/whereBuilder.test.js.map +1 -0
  270. package/dist/tests/cases/unit/whereOptimizer.test.js +173 -0
  271. package/dist/tests/cases/unit/whereOptimizer.test.js.map +1 -1
  272. package/dist/tests/src/test.js +2 -2
  273. package/dist/tests/src/test.js.map +1 -1
  274. package/dist/tests/src/testGraphql.d.ts.map +1 -1
  275. package/dist/tests/src/testGraphql.js +9 -5
  276. package/dist/tests/src/testGraphql.js.map +1 -1
  277. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  278. package/package.json +12 -10
  279. package/src/acl/EvaluatedPredicateReplacer.ts +9 -15
  280. package/src/acl/PredicateFactory.ts +64 -40
  281. package/src/acl/PredicatesInjector.ts +18 -17
  282. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.ts +21 -28
  283. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.ts +1 -6
  284. package/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.ts +10 -28
  285. package/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.ts +11 -8
  286. package/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.ts +4 -22
  287. package/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.ts +10 -29
  288. package/src/input-validation/ColumnValueResolver.ts +2 -3
  289. package/src/input-validation/EntityRulesResolver.ts +4 -4
  290. package/src/input-validation/QueryAstFactory.ts +1 -1
  291. package/src/input-validation/ValidationDataSelector.ts +1 -1
  292. package/src/input-validation/preValidation/CreateInputPreValidationProcessor.ts +7 -8
  293. package/src/input-validation/preValidation/InputPreValidator.ts +4 -4
  294. package/src/input-validation/preValidation/UpdateInputPreValidationProcessor.ts +7 -8
  295. package/src/inputProcessing/CreateInputProcessor.ts +8 -9
  296. package/src/inputProcessing/CreateInputVisitor.ts +27 -89
  297. package/src/inputProcessing/UpdateInputProcessor.ts +8 -9
  298. package/src/inputProcessing/UpdateInputVisitor.ts +25 -71
  299. package/src/inputProcessing/index.ts +0 -1
  300. package/src/introspection/IntrospectionSchemaFactory.ts +7 -7
  301. package/src/mapper/ErrorUtils.ts +2 -2
  302. package/src/mapper/JunctionTableManager.ts +3 -3
  303. package/src/mapper/Mapper.ts +34 -31
  304. package/src/mapper/MapperContainer.ts +7 -5
  305. package/src/mapper/Result.ts +2 -4
  306. package/src/mapper/delete/DeleteExecutor.ts +6 -6
  307. package/src/mapper/insert/InsertBuilder.ts +2 -2
  308. package/src/mapper/insert/SqlCreateInputProcessor.ts +3 -3
  309. package/src/mapper/select/JoinVisitor.ts +6 -33
  310. package/src/mapper/select/Path.ts +4 -1
  311. package/src/mapper/select/RelationFetcher.ts +49 -50
  312. package/src/mapper/select/SelectBuilder.ts +71 -13
  313. package/src/mapper/select/SelectBuilderFactory.ts +2 -1
  314. package/src/mapper/select/SelectExecutionHandler.ts +16 -8
  315. package/src/mapper/select/SelectHydrator.ts +15 -11
  316. package/src/mapper/select/WhereBuilder.ts +168 -61
  317. package/src/mapper/select/handlers/FieldsVisitor.ts +80 -111
  318. package/src/mapper/select/handlers/FieldsVisitorFactory.ts +1 -0
  319. package/src/mapper/select/handlers/MetaHandler.ts +6 -17
  320. package/src/mapper/select/optimizer/ConditionOptimizer.ts +6 -0
  321. package/src/mapper/select/optimizer/WhereOptimizer.ts +148 -21
  322. package/src/mapper/select/optimizer/WhereReplacer.ts +39 -0
  323. package/src/mapper/select/optimizer/helpers.ts +2 -2
  324. package/src/mapper/update/SqlUpdateInputProcessor.ts +4 -10
  325. package/src/mapper/update/UpdateBuilder.ts +3 -3
  326. package/src/resolvers/ExecutionContainerFactory.ts +1 -1
  327. package/src/resolvers/GraphQlQueryAstFactory.ts +5 -4
  328. package/src/resolvers/MutationResolver.ts +14 -4
  329. package/src/resolvers/ReadHelpers.ts +3 -3
  330. package/src/resolvers/ReadResolver.ts +2 -2
  331. package/src/schema/EnumsProvider.ts +2 -4
  332. package/src/schema/FieldAccessVisitor.ts +2 -2
  333. package/src/schema/OrderByTypeProvider.ts +10 -3
  334. package/src/schema/WhereTypeProvider.ts +5 -6
  335. package/src/schema/entities/FieldArgsVisitor.ts +4 -5
  336. package/src/schema/entities/FieldTypeVisitor.ts +3 -3
  337. package/src/schema/mutations/CreateEntityInputFieldVisitor.ts +3 -6
  338. package/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.ts +6 -20
  339. package/src/schema/mutations/CreateEntityRelationInputFieldVisitor.ts +6 -20
  340. package/src/schema/mutations/UpdateEntityInputFieldVisitor.ts +3 -6
  341. package/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.ts +6 -20
  342. package/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.ts +9 -14
  343. package/src/schema/utils.ts +1 -1
  344. package/src/tsconfig.json +6 -6
  345. package/src/utils/uniqueWhereFields.ts +3 -3
  346. package/tests/cases/bugs/bug102.test.ts +6 -6
  347. package/tests/cases/integration/graphQlRequests/delete/aclDelete.test.ts +5 -5
  348. package/tests/cases/integration/graphQlRequests/delete/additionalDeleteFilter.test.ts +5 -5
  349. package/tests/cases/integration/graphQlRequests/delete/cascadeDelete.test.ts +5 -5
  350. package/tests/cases/integration/graphQlRequests/delete/deleteById.test.ts +5 -5
  351. package/tests/cases/integration/graphQlRequests/delete/orphanRemoval.test.ts +5 -5
  352. package/tests/cases/integration/graphQlRequests/delete/setNullOnDelete.test.ts +5 -5
  353. package/tests/cases/integration/graphQlRequests/query/acl/differentRowAndFieldPredicate.test.ts +54 -4
  354. package/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.ts +26 -25
  355. package/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.ts +9 -6
  356. package/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.ts +104 -0
  357. package/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.ts +17 -15
  358. package/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.ts +4 -5
  359. package/tests/cases/integration/graphQlRequests/query/graphqlFeatures/alias.test.ts +9 -13
  360. package/tests/cases/integration/graphQlRequests/query/unique/oneHasManyUnique.test.ts +5 -3
  361. package/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/delete.test.ts +5 -5
  362. package/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/delete.test.ts +5 -5
  363. package/tests/cases/integration/graphQlRequests/update/manyHasOne/delete.test.ts +10 -10
  364. package/tests/cases/integration/graphQlRequests/update/oneHasMany/combination.test.ts +5 -5
  365. package/tests/cases/integration/graphQlRequests/update/oneHasMany/delete.test.ts +5 -5
  366. package/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/delete.test.ts +5 -5
  367. package/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.ts +2 -3
  368. package/tests/cases/unit/predicatesFactory.test.ts +8 -2
  369. package/tests/cases/unit/predicatesInjector.test.ts +97 -2
  370. package/tests/cases/unit/whereBuilder.test.ts +148 -0
  371. package/tests/cases/unit/whereOptimizer.test.ts +199 -0
  372. package/tests/src/test.ts +2 -2
  373. package/tests/src/testGraphql.ts +9 -5
  374. package/dist/src/inputProcessing/InputContext.d.ts +0 -43
  375. package/dist/src/inputProcessing/InputContext.d.ts.map +0 -1
  376. package/dist/src/inputProcessing/InputContext.js +0 -3
  377. package/dist/src/inputProcessing/InputContext.js.map +0 -1
  378. package/src/inputProcessing/InputContext.ts +0 -49
@@ -13,132 +13,87 @@ export class FieldsVisitor implements Model.RelationByTypeVisitor<void>, Model.C
13
13
  private readonly whereBuilder: WhereBuilder,
14
14
  private readonly mapper: Mapper,
15
15
  private readonly executionContext: SelectExecutionHandlerContext,
16
+ private readonly relationPath: Model.AnyRelationContext[],
16
17
  ) {}
17
18
 
18
- visitColumn(entity: Model.Entity, column: Model.AnyColumn): void {
19
+ visitColumn({ entity, column }: Model.ColumnContext): void {
19
20
  const columnPath = this.executionContext.path
20
- this.executionContext.addColumn(qb => {
21
- const tableAlias = columnPath.back().alias
22
- const columnAlias = columnPath.alias
21
+ const tableAlias = columnPath.back().alias
22
+ const columnAlias = columnPath.alias
23
23
 
24
- const fieldPredicate = this.predicateFactory.shouldApplyCellLevelPredicate(
25
- entity,
26
- Acl.Operation.read,
27
- column.name,
28
- )
29
- ? this.predicateFactory.create(entity, Acl.Operation.read, [column.name])
30
- : undefined
31
-
32
- if (!fieldPredicate || Object.keys(fieldPredicate).length === 0) {
33
- return qb.select([tableAlias, column.columnName], columnAlias)
34
- }
35
- return this.whereBuilder.buildAdvanced(entity, columnPath.back(), fieldPredicate, cb =>
36
- qb.select(
37
- expr =>
38
- expr.case(caseExpr =>
39
- caseExpr
40
- .when(
41
- whenExpr => whenExpr.selectCondition(cb),
42
- thenExpr => thenExpr.select([tableAlias, column.columnName]),
43
- )
44
- .else(elseExpr => elseExpr.raw('null')),
45
- ),
46
- columnAlias,
47
- ),
48
- )
24
+ this.executionContext.addColumn({
25
+ query: qb => qb.select([tableAlias, column.columnName], columnAlias),
26
+ predicate: this.getRequiredPredicate(entity, column),
49
27
  })
50
28
  }
51
29
 
52
- public visitManyHasManyInverse(
53
- entity: Model.Entity,
54
- relation: Model.ManyHasManyInverseRelation,
55
- targetEntity: Model.Entity,
56
- targetRelation: Model.ManyHasManyOwningRelation,
57
- ): void {
30
+ public visitManyHasManyInverse(relationContext: Model.ManyHasManyInverseContext): void {
58
31
  const field = this.executionContext.objectNode
59
32
  if (!field) {
60
33
  throw new Error()
61
34
  }
62
- this.executionContext.addData(
63
- entity.primary,
64
- async ids =>
65
- this.relationFetcher.fetchManyHasManyGroups(
66
- {
67
- mapper: this.mapper,
68
- field: field,
69
- targetEntity: targetEntity,
70
- sourceRelation: relation,
71
- targetRelation,
72
- directionFrom: 'inverse',
73
- ids: ids,
74
- },
75
- ),
76
- [],
77
- )
35
+ this.executionContext.addData({
36
+ field: relationContext.entity.primary,
37
+ dataProvider: async ids =>
38
+ this.relationFetcher.fetchManyHasManyGroups({
39
+ mapper: this.mapper,
40
+ field: field,
41
+ relationContext,
42
+ relationPath: this.relationPath,
43
+ ids: ids,
44
+ }),
45
+ defaultValue: [],
46
+ predicate: this.getRequiredPredicate(relationContext.entity, relationContext.relation),
47
+ })
78
48
  }
79
49
 
80
- public visitManyHasManyOwning(
81
- entity: Model.Entity,
82
- relation: Model.ManyHasManyOwningRelation,
83
- targetEntity: Model.Entity,
84
- targetRelation: Model.ManyHasManyInverseRelation | null,
85
- ): void {
50
+ public visitManyHasManyOwning(relationContext: Model.ManyHasManyOwningContext): void {
86
51
  const field = this.executionContext.objectNode
87
52
  if (!field) {
88
53
  throw new Error()
89
54
  }
90
55
 
91
- this.executionContext.addData(
92
- entity.primary,
93
- async ids =>
56
+ this.executionContext.addData({
57
+ field: relationContext.entity.primary,
58
+ dataProvider: async ids =>
94
59
  this.relationFetcher.fetchManyHasManyGroups({
95
60
  mapper: this.mapper,
96
61
  field: field,
97
- targetEntity: targetEntity,
98
- sourceRelation: relation,
99
- targetRelation,
100
- directionFrom: 'owning',
62
+ relationContext,
63
+ relationPath: this.relationPath,
101
64
  ids: ids,
102
65
  }),
103
- [],
104
- )
66
+ defaultValue: [],
67
+ predicate: this.getRequiredPredicate(relationContext.entity, relationContext.relation),
68
+ })
105
69
  }
106
70
 
107
- public visitOneHasMany(
108
- entity: Model.Entity,
109
- relation: Model.OneHasManyRelation,
110
- targetEntity: Model.Entity,
111
- targetRelation: Model.ManyHasOneRelation,
112
- ): void {
71
+ public visitOneHasMany(relationContext: Model.OneHasManyContext): void {
113
72
  const field = this.executionContext.objectNode
114
73
  if (!field) {
115
74
  throw new Error()
116
75
  }
117
76
 
118
- this.executionContext.addData(
119
- entity.primary,
120
- async ids =>
77
+ this.executionContext.addData({
78
+ field: relationContext.entity.primary,
79
+ dataProvider: async ids =>
121
80
  this.relationFetcher.fetchOneHasManyGroups({
122
81
  mapper: this.mapper,
123
82
  objectNode: field,
124
- targetEntity: targetEntity,
125
- relation: relation,
126
- targetRelation: targetRelation,
83
+ relationContext,
84
+ relationPath: this.relationPath,
127
85
  ids: ids,
128
86
  }),
129
- [],
130
- )
87
+ defaultValue: [],
88
+ predicate: this.getRequiredPredicate(relationContext.entity, relationContext.relation),
89
+ })
131
90
  }
132
91
 
133
- public visitOneHasOneInverse(
134
- entity: Model.Entity,
135
- relation: Model.OneHasOneInverseRelation,
136
- targetEntity: Model.Entity,
137
- targetRelation: Model.OneHasOneOwningRelation,
138
- ): void {
139
- this.executionContext.addData(
140
- entity.primary,
141
- async ids => {
92
+ public visitOneHasOneInverse(relationContext: Model.OneHasOneInverseContext): void {
93
+ const { entity, targetRelation, targetEntity } = relationContext
94
+ this.executionContext.addData({
95
+ field: entity.primary,
96
+ dataProvider: async ids => {
142
97
  const idsWhere: Input.Where = {
143
98
  [targetRelation.name]: {
144
99
  [entity.primary]: {
@@ -155,21 +110,21 @@ export class FieldsVisitor implements Model.RelationByTypeVisitor<void>, Model.C
155
110
  }
156
111
  const objectWithWhere = field.withArg('filter', where)
157
112
 
158
- return this.mapper.select(targetEntity, objectWithWhere, targetRelation, targetRelation.name)
113
+ return this.mapper.selectAssoc(targetEntity, objectWithWhere, [
114
+ ...this.relationPath,
115
+ relationContext,
116
+ ], targetRelation.name)
159
117
  },
160
- null,
161
- )
118
+ defaultValue: null,
119
+ predicate: this.getRequiredPredicate(relationContext.entity, relationContext.relation),
120
+ })
162
121
  }
163
122
 
164
- public visitOneHasOneOwning(
165
- entity: Model.Entity,
166
- relation: Model.OneHasOneOwningRelation,
167
- targetEntity: Model.Entity,
168
- targetRelation: Model.OneHasOneInverseRelation | null,
169
- ): void {
170
- this.executionContext.addData(
171
- relation.name,
172
- async ids => {
123
+ public visitOneHasOneOwning(relationContext: Model.OneHasOneOwningContext): void {
124
+ const { relation, targetEntity } = relationContext
125
+ this.executionContext.addData({
126
+ field: relation.name,
127
+ dataProvider: async ids => {
173
128
  const idsWhere: Input.Where = {
174
129
  [targetEntity.primary]: {
175
130
  in: ids,
@@ -184,16 +139,21 @@ export class FieldsVisitor implements Model.RelationByTypeVisitor<void>, Model.C
184
139
  }
185
140
  const objectWithWhere = objectNode.withArg('filter', where)
186
141
 
187
- return this.mapper.select(targetEntity, objectWithWhere, targetRelation, targetEntity.primary)
142
+ return this.mapper.selectAssoc(targetEntity, objectWithWhere, [
143
+ ...this.relationPath,
144
+ relationContext,
145
+ ], targetEntity.primary)
188
146
  },
189
- null,
190
- )
147
+ defaultValue: null,
148
+ predicate: this.getRequiredPredicate(relationContext.entity, relationContext.relation),
149
+ })
191
150
  }
192
151
 
193
- public visitManyHasOne(entity: Model.Entity, relation: Model.ManyHasOneRelation, targetEntity: Model.Entity, targetRelation: Model.OneHasManyRelation | null): void {
194
- this.executionContext.addData(
195
- relation.name,
196
- async ids => {
152
+ public visitManyHasOne(relationContext: Model.ManyHasOneContext): void {
153
+ const { relation, targetEntity } = relationContext
154
+ this.executionContext.addData({
155
+ field: relation.name,
156
+ dataProvider: async ids => {
197
157
  const idsWhere: Input.Where = {
198
158
  [targetEntity.primary]: {
199
159
  in: ids,
@@ -208,9 +168,18 @@ export class FieldsVisitor implements Model.RelationByTypeVisitor<void>, Model.C
208
168
  }
209
169
  const objectWithWhere = objectNode.withArg('filter', where)
210
170
 
211
- return this.mapper.select(targetEntity, objectWithWhere, targetRelation, targetEntity.primary)
171
+ return this.mapper.selectAssoc(targetEntity, objectWithWhere, [
172
+ ...this.relationPath,
173
+ relationContext,
174
+ ], targetEntity.primary)
212
175
  },
213
- null,
214
- )
176
+ defaultValue: null,
177
+ predicate: this.getRequiredPredicate(relationContext.entity, relationContext.relation),
178
+ })
179
+ }
180
+
181
+ private getRequiredPredicate(entity: Model.Entity, field: Model.AnyField): Acl.Predicate | undefined {
182
+ const fieldPredicate = this.predicateFactory.getFieldPredicate(entity, Acl.Operation.read, field.name)
183
+ return fieldPredicate.isSameAsPrimary ? undefined : fieldPredicate.predicate
215
184
  }
216
185
  }
@@ -22,6 +22,7 @@ export class FieldsVisitorFactory {
22
22
  this.whereBuilder,
23
23
  mapper,
24
24
  context,
25
+ context.relationPath,
25
26
  )
26
27
  }
27
28
  }
@@ -32,25 +32,14 @@ export class MetaHandler implements SelectExecutionHandler<{}> {
32
32
  metaPath: Path,
33
33
  operation: Acl.Operation.read | Acl.Operation.update,
34
34
  ): void {
35
- const { entity, path } = context
35
+ const { entity } = context
36
36
  if (entity.primary === fieldName) {
37
37
  return
38
38
  }
39
- const fieldPredicate = this.predicateFactory.create(entity, operation, [fieldName])
40
- context.addColumn(qb => {
41
- return this.whereBuilder.buildAdvanced(entity, path.back(), fieldPredicate, cb =>
42
- qb.select(
43
- expr =>
44
- expr.selectCondition(condition => {
45
- condition = cb(condition)
46
- if (condition.isEmpty()) {
47
- return condition.raw('true')
48
- }
49
- return condition
50
- }),
51
- metaPath.alias,
52
- ),
53
- )
54
- }, metaPath)
39
+ const fieldPredicate = this.predicateFactory.getFieldPredicate(entity, operation, fieldName)
40
+ context.addColumn({
41
+ path: metaPath,
42
+ valueGetter: context.addPredicate(fieldPredicate.predicate),
43
+ })
55
44
  }
56
45
  }
@@ -23,6 +23,12 @@ export class ConditionOptimizer {
23
23
  } else if (key === 'or') {
24
24
  return optimizeOr(value.map(it => this.optimize(it)))
25
25
 
26
+ } else if (key === 'in' && value.length === 0) {
27
+ return false
28
+
29
+ } else if (key === 'notIn' && value.length === 0) {
30
+ return true
31
+
26
32
  } else if (key === 'not') {
27
33
  return optimizeNot(this.optimize(value))
28
34
 
@@ -2,48 +2,160 @@ import { Input, Model } from '@contember/schema'
2
2
  import { ConditionOptimizer } from './ConditionOptimizer'
3
3
  import { acceptFieldVisitor } from '@contember/schema-utils'
4
4
  import { optimizeAnd, optimizeNot, optimizeOr } from './helpers'
5
+ import { replaceWhere } from './WhereReplacer'
6
+
7
+ type ExtendedRelationContext =
8
+ & {
9
+ context: Model.AnyRelationContext
10
+ canEliminate: boolean
11
+ isLast: boolean
12
+ }
13
+
14
+ export interface WhereOptimizationHints {
15
+ relationPath?: Model.AnyRelationContext[]
16
+ evaluatedPredicates?: Input.OptionalWhere[]
17
+ }
18
+
19
+ type OptimizedOperand = Input.OptionalWhere | undefined | boolean
5
20
 
6
21
  export class WhereOptimizer {
22
+ private static eliminableRelations = new Set<Model.AnyRelationContext['type']>(['oneHasMany', 'oneHasOneInverse', 'oneHasOneOwning'])
23
+
7
24
  constructor(
8
25
  private readonly model: Model.Schema,
9
26
  private readonly conditionOptimizer: ConditionOptimizer,
10
27
  ) {
11
28
  }
12
29
 
13
- public optimize(where: Input.OptionalWhere, entity: Model.Entity): Input.Where {
14
- const result = this.optimizeWhere(where, entity)
30
+ public optimize(where: Input.OptionalWhere, entity: Model.Entity, { relationPath = [], evaluatedPredicates = [] }: WhereOptimizationHints = {}): Input.OptionalWhere {
31
+ let processedRelationPath: ExtendedRelationContext[] = []
32
+ for (const i in relationPath) {
33
+ const el = relationPath[i]
34
+ if (!WhereOptimizer.eliminableRelations.has(el.type)) {
35
+ processedRelationPath = []
36
+ } else {
37
+ processedRelationPath.push({ context: el, canEliminate: true, isLast: Number(i) === relationPath.length })
38
+ }
39
+ }
40
+ let result = this.optimizeWhere(where, entity, processedRelationPath)
15
41
 
16
42
  if (typeof result === 'boolean') {
17
43
  return { [entity.primary]: { [result ? 'always' : 'never']: true } }
18
44
  }
45
+ let changed = false
46
+ for (const evaluated of evaluatedPredicates) {
47
+ const evaluatedPredicate = this.optimize(evaluated, entity)
48
+ const newResult = replaceWhere(result, evaluatedPredicate, { [entity.primary]: { always: true } })
49
+ if (newResult !== result) {
50
+ result = newResult
51
+ changed = true
52
+ }
53
+ }
54
+ if (changed) {
55
+ return this.optimize(result, entity)
56
+ }
19
57
 
20
58
  return result
21
59
  }
22
60
 
23
- private optimizeWhere(where: Input.OptionalWhere, entity: Model.Entity): Input.Where | boolean {
24
- return optimizeAnd(
25
- Object.entries(where).map(([key, value]) => {
26
- if (value === undefined || value === null) {
27
- return undefined
61
+ private optimizeWhere(where: Input.OptionalWhere, entity: Model.Entity, relationPath: ExtendedRelationContext[]): Input.OptionalWhere | boolean {
62
+ const operands: OptimizedOperand[] = []
28
63
 
29
- } else if (key === 'and') {
30
- return optimizeAnd((value as readonly Input.Where[]).map(it => this.optimizeWhere(it, entity)))
64
+ for (const key in where) {
65
+ const value = where[key]
66
+ let operand: OptimizedOperand = undefined
67
+ if (value === undefined || value === null) {
68
+ continue
69
+ } else if (key === 'and') {
70
+ const innerOperands: (Input.OptionalWhere | boolean)[] = []
71
+ for (const innerValue of value as readonly Input.OptionalWhere[]) {
72
+ const innerOperand = this.optimizeWhere(innerValue, entity, relationPath)
73
+ if (innerOperand === false) {
74
+ return false
75
+ }
76
+ innerOperands.push(innerOperand)
77
+ }
78
+ operand = this.optimizeAnd(innerOperands, entity, relationPath)
79
+ } else if (key === 'or') {
80
+ const innerOperands: (Input.OptionalWhere | boolean)[] = []
81
+ for (const innerValue of value as readonly Input.OptionalWhere[]) {
82
+ const innerOperand = this.optimizeWhere(innerValue, entity, relationPath)
83
+ if (innerOperand === true) {
84
+ operand = true
85
+ break
86
+ }
87
+ innerOperands.push(innerOperand)
88
+ }
89
+ if (operand !== true) {
90
+ operand = this.optimizeOr(innerOperands, entity, relationPath)
91
+ }
31
92
 
32
- } else if (key === 'or') {
33
- return optimizeOr((value as readonly Input.Where[]).map(it => this.optimizeWhere(it, entity)))
93
+ } else if (key === 'not') {
94
+ operand = optimizeNot(this.optimizeWhere(value as Input.OptionalWhere, entity, relationPath))
34
95
 
35
- } else if (key === 'not') {
36
- return optimizeNot(this.optimizeWhere(value as Input.Where, entity))
96
+ } else {
97
+ operand = this.resolveFieldValue(entity, key, value, relationPath)
98
+ }
37
99
 
38
- } else {
39
- return this.resolveFieldValue(entity, key, value)
100
+ if (operand === false) {
101
+ return false
102
+
103
+ } else if (operand !== undefined) {
104
+ operands.push(operand)
105
+ }
106
+ }
107
+ return this.optimizeAnd(operands, entity, relationPath)
108
+ }
109
+
110
+ private optimizeOr(operands: readonly OptimizedOperand[], entity: Model.Entity, relationPath: ExtendedRelationContext[]): Input.OptionalWhere | boolean {
111
+ const optimized = optimizeOr(operands)
112
+ if (typeof optimized === 'boolean' || !Array.isArray(optimized.or)) {
113
+ return optimized
114
+ }
115
+ const result = this.crossOptimize(optimized.or, entity, { never: true }, relationPath)
116
+ if (result === optimized.or) {
117
+ return optimized
118
+ }
119
+ return optimizeOr(result)
120
+ }
121
+
122
+ private optimizeAnd(operands: readonly OptimizedOperand[], entity: Model.Entity, relationPath: ExtendedRelationContext[]): Input.OptionalWhere | boolean {
123
+ const optimized = optimizeAnd(operands)
124
+ if (typeof optimized === 'boolean' || !Array.isArray(optimized.and)) {
125
+ return optimized
126
+ }
127
+ const result = this.crossOptimize(optimized.and, entity, { always: true }, relationPath)
128
+ if (result === optimized.and) {
129
+ return optimized
130
+ }
131
+ return optimizeAnd(result)
132
+ }
133
+
134
+ private crossOptimize(operands: Input.OptionalWhere[], entity: Model.Entity, replacement: Input.Condition, relationPath: ExtendedRelationContext[]): (Input.OptionalWhere | boolean)[] {
135
+ let result: (Input.OptionalWhere | boolean)[] = operands
136
+ let copied = false
137
+ const count = result.length
138
+ for (let i = 0; i < count; i++) {
139
+ for (let j = 0; j < count; j++) {
140
+ const a = result[j]
141
+ const b = result[i]
142
+ if (i !== j && typeof a !== 'boolean' && typeof b !== 'boolean') {
143
+ const elResult = replaceWhere(a, b, { [entity.primary]: replacement })
144
+ if (elResult !== a) {
145
+ if (!copied) {
146
+ result = [...result]
147
+ copied = true
148
+ }
149
+ result[j] = this.optimizeWhere(elResult, entity, relationPath)
150
+ }
40
151
  }
41
- }),
42
- )
152
+ }
153
+ }
154
+ return result
43
155
  }
44
156
 
45
- private resolveFieldValue(entity: Model.Entity, key: string, value: Input.OptionalWhere[string]) {
46
- return acceptFieldVisitor<Input.Where | boolean>(this.model, entity, key, {
157
+ private resolveFieldValue(entity: Model.Entity, key: string, value: Input.OptionalWhere[string], relationPath: ExtendedRelationContext[]) {
158
+ return acceptFieldVisitor<Input.OptionalWhere | boolean>(this.model, entity, key, {
47
159
  visitColumn: () => {
48
160
  const optimizedCondition = this.conditionOptimizer.optimize(value as Input.Condition)
49
161
 
@@ -53,8 +165,23 @@ export class WhereOptimizer {
53
165
 
54
166
  return { [key]: optimizedCondition }
55
167
  },
56
- visitRelation: (entity, relation, targetEntity) => {
57
- const optimizedWhere = this.optimizeWhere(value as Input.Where, targetEntity)
168
+ visitRelation: context => {
169
+ let where = value as Input.OptionalWhere
170
+ const newRelationPath: ExtendedRelationContext[] = [...relationPath]
171
+ const length = relationPath.length
172
+ if (length > 0 && relationPath[length - 1].context.targetRelation?.name === context.relation.name) {
173
+ const item = newRelationPath.pop()
174
+ const type = item!.context.type
175
+ if (item?.canEliminate && (type === 'oneHasMany' || type === 'oneHasOneOwning' || type === 'oneHasOneInverse')) {
176
+ where = replaceWhere(where, { [context.targetEntity.primary]: { isNull: true } }, { [context.targetEntity.primary]: { never: true } })
177
+ where = replaceWhere(where, { [context.targetEntity.primary]: { isNull: false } }, { [context.targetEntity.primary]: { always: true } })
178
+ }
179
+ } else {
180
+ // first level relation - we are sure root exists
181
+ const canEliminate = length === 0 || relationPath[length - 1].isLast
182
+ newRelationPath.push({ context, isLast: false, canEliminate })
183
+ }
184
+ const optimizedWhere = this.optimizeWhere(where, context.targetEntity, newRelationPath)
58
185
 
59
186
  if (typeof optimizedWhere === 'boolean') {
60
187
  return optimizedWhere
@@ -0,0 +1,39 @@
1
+ import { Input, Writable } from '@contember/schema'
2
+ import deepEqual from 'fast-deep-equal'
3
+
4
+ export const replaceWhere = (subject: Input.OptionalWhere, find: Input.OptionalWhere, replace: Input.OptionalWhere): Input.OptionalWhere => {
5
+ if (deepEqual(subject, find)) {
6
+ return replace
7
+ }
8
+ let result: Writable<Input.OptionalWhere> = subject
9
+ let copied = false
10
+ for (const key in subject) {
11
+ const value = subject[key]
12
+ if (key === 'not') {
13
+ const newNot = replaceWhere(value as Input.OptionalWhere, find, replace)
14
+ if (newNot !== value) {
15
+ if (!copied) {
16
+ result = { ...result }
17
+ }
18
+ result['not'] = newNot
19
+ }
20
+ } else if (key === 'and' || key === 'or') {
21
+ const items: Input.OptionalWhere[] = []
22
+ let itemChanged = false
23
+ for (const el of value as Input.OptionalWhere[]) {
24
+ const newEl = replaceWhere(el, find, replace)
25
+ if (newEl !== el) {
26
+ itemChanged = true
27
+ }
28
+ items.push(newEl)
29
+ }
30
+ if (itemChanged) {
31
+ if (!copied) {
32
+ result = { ...result }
33
+ }
34
+ result[key] = items
35
+ }
36
+ }
37
+ }
38
+ return result
39
+ }
@@ -1,4 +1,4 @@
1
- export const optimizeOr = <P extends Record<string, unknown>>(operands: readonly (P | boolean)[]): P | { or?: P[] } | boolean => {
1
+ export const optimizeOr = <P extends Record<string, unknown>>(operands: readonly (P | boolean | undefined)[]): P | { or?: P[] } | boolean => {
2
2
  const normalized: P[] = []
3
3
  let hasNever = false
4
4
  for (const operand of operands) {
@@ -6,7 +6,7 @@ export const optimizeOr = <P extends Record<string, unknown>>(operands: readonly
6
6
  return true
7
7
  } else if (operand === false) {
8
8
  hasNever = true
9
- } else {
9
+ } else if (operand !== undefined) {
10
10
  normalized.push(...Array.isArray(operand.or) ? operand.or : [operand])
11
11
  }
12
12
  }
@@ -2,7 +2,6 @@ import { Input, Model, Value } from '@contember/schema'
2
2
  import { Mapper } from '../Mapper'
3
3
  import { UpdateBuilder } from './UpdateBuilder'
4
4
  import { UpdateInputProcessor } from '../../inputProcessing'
5
- import * as Context from '../../inputProcessing'
6
5
  import {
7
6
  ConstraintType,
8
7
  getInsertPrimary,
@@ -17,6 +16,7 @@ import { hasManyProcessor, hasOneProcessor } from '../MutationProcessorHelper'
17
16
  import { AbortUpdate } from './Updater'
18
17
  import { ImplementationException } from '../../exception'
19
18
  import { CheckedPrimary } from '../CheckedPrimary'
19
+ import { logger } from '@contember/logger'
20
20
 
21
21
  export class SqlUpdateInputProcessor implements UpdateInputProcessor<MutationResultList> {
22
22
  constructor(
@@ -26,7 +26,7 @@ export class SqlUpdateInputProcessor implements UpdateInputProcessor<MutationRes
26
26
  private readonly mapper: Mapper,
27
27
  ) {}
28
28
 
29
- public column({ entity, column }: Context.ColumnContext) {
29
+ public column({ entity, column }: Model.ColumnContext) {
30
30
  if (this.data[column.name] !== undefined) {
31
31
  this.updateBuilder.addFieldValue(column.name, this.data[column.name] as Value.AtomicValue)
32
32
  }
@@ -228,10 +228,7 @@ export class SqlUpdateInputProcessor implements UpdateInputProcessor<MutationRes
228
228
  return [new MutationConstraintViolationError([], ConstraintType.notNull)]
229
229
  }
230
230
  if (relation.joiningColumn.onDelete === Model.OnDelete.restrict) {
231
- // eslint-disable-next-line no-console
232
- console.error(
233
- '[DEPRECATED] You are deleting an entity over the relation where onDelete behaviour is set to restrict. This will fail in next version.',
234
- )
231
+ logger.warn('You are deleting an entity over the relation where onDelete behaviour is set to restrict. This will fail in next version.', { loc: 'SqlUpdateInputProcessor' })
235
232
  this.updateBuilder.addFieldValue(relation.name, null)
236
233
  }
237
234
  const inversePrimary = await this.mapper.selectField(
@@ -490,10 +487,7 @@ export class SqlUpdateInputProcessor implements UpdateInputProcessor<MutationRes
490
487
  return [new MutationConstraintViolationError([], ConstraintType.notNull)]
491
488
  }
492
489
  if (relation.joiningColumn.onDelete === Model.OnDelete.restrict) {
493
- // eslint-disable-next-line no-console
494
- console.error(
495
- '[DEPRECATED] You are deleting an entity over the relation where onDelete behaviour is set to restrict. This will fail in next version.',
496
- )
490
+ logger.warn('You are deleting an entity over the relation where onDelete behaviour is set to restrict. This will fail in next version.', { loc: 'SqlUpdateInputProcessor' })
497
491
  this.updateBuilder.addFieldValue(relation.name, null)
498
492
  }
499
493
  const targetPrimary = await this.mapper.selectField(
@@ -74,9 +74,9 @@ export class UpdateBuilder {
74
74
  const columns = new Set(resolvedData.map(it => it.columnName))
75
75
  const allColumns: string[] = Object.values(
76
76
  acceptEveryFieldVisitor(this.schema, this.entity, {
77
- visitColumn: (entity, column) => column.columnName,
78
- visitManyHasOne: (entity, relation) => relation.joiningColumn.columnName,
79
- visitOneHasOneOwning: (entity, relation) => relation.joiningColumn.columnName,
77
+ visitColumn: ({ column }) => column.columnName,
78
+ visitManyHasOne: ({ relation }) => relation.joiningColumn.columnName,
79
+ visitOneHasOneOwning: ({ relation }) => relation.joiningColumn.columnName,
80
80
  visitManyHasManyInverse: () => null,
81
81
  visitManyHasManyOwning: () => null,
82
82
  visitOneHasOneInverse: () => null,
@@ -15,7 +15,7 @@ import {
15
15
  import { ValidationResolver } from './ValidationResolver'
16
16
  import { Providers } from '@contember/schema-utils'
17
17
  import { GraphQlQueryAstFactory } from './GraphQlQueryAstFactory'
18
- import { getArgumentValues } from 'graphql/execution/values'
18
+ import { getArgumentValues } from 'graphql'
19
19
  import { createMapperContainer } from '../mapper'
20
20
 
21
21
  export interface ExecutionContainer {
@@ -2,17 +2,18 @@ import { isIt, ResolveInfoUtils } from '../utils'
2
2
  import {
3
3
  FieldNode as GraphQlFieldNode,
4
4
  FragmentSpreadNode,
5
+ getArgumentValues,
5
6
  GraphQLObjectType,
6
7
  GraphQLOutputType,
7
8
  GraphQLResolveInfo,
8
9
  isListType,
9
10
  isNonNullType,
10
- isObjectType, Kind,
11
+ isObjectType,
12
+ Kind,
13
+ SelectionSetNode,
11
14
  } from 'graphql'
12
- import { SelectionSetNode } from 'graphql/language/ast'
13
- import { getArgumentValues } from 'graphql/execution/values'
14
15
  import { FieldNode, ObjectNode } from '../inputProcessing'
15
- import { isDeepStrictEqual } from 'util'
16
+ import { isDeepStrictEqual } from 'node:util'
16
17
 
17
18
  type NodeFilter = (node: GraphQlFieldNode, path: string[]) => boolean
18
19
  type AnyNode = ObjectNode | FieldNode