@contember/engine-content-api 1.1.2 → 1.2.0-alpha.11

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 (352) hide show
  1. package/dist/src/acl/EvaluatedPredicateReplacer.d.ts +9 -0
  2. package/dist/src/acl/EvaluatedPredicateReplacer.d.ts.map +1 -0
  3. package/dist/src/acl/EvaluatedPredicateReplacer.js +31 -0
  4. package/dist/src/acl/EvaluatedPredicateReplacer.js.map +1 -0
  5. package/dist/src/acl/PermissionFactory.d.ts.map +1 -1
  6. package/dist/src/acl/PermissionFactory.js +15 -11
  7. package/dist/src/acl/PermissionFactory.js.map +1 -1
  8. package/dist/src/acl/PredicateFactory.d.ts +4 -2
  9. package/dist/src/acl/PredicateFactory.d.ts.map +1 -1
  10. package/dist/src/acl/PredicateFactory.js +17 -6
  11. package/dist/src/acl/PredicateFactory.js.map +1 -1
  12. package/dist/src/acl/PredicatesInjector.d.ts +1 -1
  13. package/dist/src/acl/PredicatesInjector.d.ts.map +1 -1
  14. package/dist/src/acl/PredicatesInjector.js +16 -19
  15. package/dist/src/acl/PredicatesInjector.js.map +1 -1
  16. package/dist/src/acl/VariableInjector.d.ts +0 -1
  17. package/dist/src/acl/VariableInjector.d.ts.map +1 -1
  18. package/dist/src/acl/VariableInjector.js +4 -14
  19. package/dist/src/acl/VariableInjector.js.map +1 -1
  20. package/dist/src/acl/VariableUtils.d.ts +2 -13
  21. package/dist/src/acl/VariableUtils.d.ts.map +1 -1
  22. package/dist/src/acl/VariableUtils.js +5 -16
  23. package/dist/src/acl/VariableUtils.js.map +1 -1
  24. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.d.ts +0 -1
  25. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.d.ts.map +1 -1
  26. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.js +14 -15
  27. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.js.map +1 -1
  28. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts +1 -1
  29. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts.map +1 -1
  30. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js +1 -1
  31. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js.map +1 -1
  32. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.d.ts +5 -4
  33. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.d.ts.map +1 -1
  34. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js +29 -20
  35. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js.map +1 -1
  36. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.d.ts.map +1 -1
  37. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.js +2 -2
  38. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.js.map +1 -1
  39. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts +3 -3
  40. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts.map +1 -1
  41. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js +3 -3
  42. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js.map +1 -1
  43. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.d.ts +5 -4
  44. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.d.ts.map +1 -1
  45. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js +29 -20
  46. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js.map +1 -1
  47. package/dist/src/input-validation/ColumnValueResolver.d.ts +4 -3
  48. package/dist/src/input-validation/ColumnValueResolver.d.ts.map +1 -1
  49. package/dist/src/input-validation/ColumnValueResolver.js.map +1 -1
  50. package/dist/src/input-validation/EntityRulesResolver.js +4 -4
  51. package/dist/src/input-validation/EntityRulesResolver.js.map +1 -1
  52. package/dist/src/input-validation/QueryAstFactory.js +1 -1
  53. package/dist/src/input-validation/QueryAstFactory.js.map +1 -1
  54. package/dist/src/input-validation/ValidationContext.d.ts +2 -2
  55. package/dist/src/input-validation/ValidationContext.d.ts.map +1 -1
  56. package/dist/src/input-validation/ValidationContext.js.map +1 -1
  57. package/dist/src/input-validation/ValidationDataSelector.d.ts.map +1 -1
  58. package/dist/src/input-validation/ValidationDataSelector.js +1 -1
  59. package/dist/src/input-validation/ValidationDataSelector.js.map +1 -1
  60. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.d.ts +7 -8
  61. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.d.ts.map +1 -1
  62. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.js.map +1 -1
  63. package/dist/src/input-validation/preValidation/InputPreValidator.js +4 -4
  64. package/dist/src/input-validation/preValidation/InputPreValidator.js.map +1 -1
  65. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.d.ts +7 -8
  66. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.d.ts.map +1 -1
  67. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.js.map +1 -1
  68. package/dist/src/inputProcessing/CreateInputProcessor.d.ts +8 -9
  69. package/dist/src/inputProcessing/CreateInputProcessor.d.ts.map +1 -1
  70. package/dist/src/inputProcessing/CreateInputVisitor.d.ts +7 -7
  71. package/dist/src/inputProcessing/CreateInputVisitor.d.ts.map +1 -1
  72. package/dist/src/inputProcessing/CreateInputVisitor.js +15 -46
  73. package/dist/src/inputProcessing/CreateInputVisitor.js.map +1 -1
  74. package/dist/src/inputProcessing/UpdateInputProcessor.d.ts +8 -9
  75. package/dist/src/inputProcessing/UpdateInputProcessor.d.ts.map +1 -1
  76. package/dist/src/inputProcessing/UpdateInputVisitor.d.ts +7 -7
  77. package/dist/src/inputProcessing/UpdateInputVisitor.d.ts.map +1 -1
  78. package/dist/src/inputProcessing/UpdateInputVisitor.js +13 -28
  79. package/dist/src/inputProcessing/UpdateInputVisitor.js.map +1 -1
  80. package/dist/src/inputProcessing/index.d.ts +0 -1
  81. package/dist/src/inputProcessing/index.d.ts.map +1 -1
  82. package/dist/src/inputProcessing/index.js +0 -1
  83. package/dist/src/inputProcessing/index.js.map +1 -1
  84. package/dist/src/introspection/IntrospectionSchemaFactory.js +7 -7
  85. package/dist/src/introspection/IntrospectionSchemaFactory.js.map +1 -1
  86. package/dist/src/introspection/content-schema.types.d.ts +19 -223
  87. package/dist/src/introspection/content-schema.types.d.ts.map +1 -1
  88. package/dist/src/introspection/content-schema.types.js +2 -2
  89. package/dist/src/introspection/content-schema.types.js.map +1 -1
  90. package/dist/src/mapper/Mapper.d.ts +6 -6
  91. package/dist/src/mapper/Mapper.d.ts.map +1 -1
  92. package/dist/src/mapper/Mapper.js +28 -23
  93. package/dist/src/mapper/Mapper.js.map +1 -1
  94. package/dist/src/mapper/MapperContainer.d.ts.map +1 -1
  95. package/dist/src/mapper/MapperContainer.js +7 -4
  96. package/dist/src/mapper/MapperContainer.js.map +1 -1
  97. package/dist/src/mapper/delete/DeleteExecutor.js +3 -3
  98. package/dist/src/mapper/delete/DeleteExecutor.js.map +1 -1
  99. package/dist/src/mapper/insert/SqlCreateInputProcessor.d.ts +4 -2
  100. package/dist/src/mapper/insert/SqlCreateInputProcessor.d.ts.map +1 -1
  101. package/dist/src/mapper/insert/SqlCreateInputProcessor.js.map +1 -1
  102. package/dist/src/mapper/select/JoinVisitor.d.ts +6 -6
  103. package/dist/src/mapper/select/JoinVisitor.d.ts.map +1 -1
  104. package/dist/src/mapper/select/JoinVisitor.js +6 -6
  105. package/dist/src/mapper/select/JoinVisitor.js.map +1 -1
  106. package/dist/src/mapper/select/RelationFetcher.d.ts +32 -5
  107. package/dist/src/mapper/select/RelationFetcher.d.ts.map +1 -1
  108. package/dist/src/mapper/select/RelationFetcher.js +37 -15
  109. package/dist/src/mapper/select/RelationFetcher.js.map +1 -1
  110. package/dist/src/mapper/select/SelectBuilder.d.ts +2 -1
  111. package/dist/src/mapper/select/SelectBuilder.d.ts.map +1 -1
  112. package/dist/src/mapper/select/SelectBuilder.js +4 -2
  113. package/dist/src/mapper/select/SelectBuilder.js.map +1 -1
  114. package/dist/src/mapper/select/SelectBuilderFactory.d.ts +2 -1
  115. package/dist/src/mapper/select/SelectBuilderFactory.d.ts.map +1 -1
  116. package/dist/src/mapper/select/SelectExecutionHandler.d.ts +1 -0
  117. package/dist/src/mapper/select/SelectExecutionHandler.d.ts.map +1 -1
  118. package/dist/src/mapper/select/WhereBuilder.d.ts +6 -3
  119. package/dist/src/mapper/select/WhereBuilder.d.ts.map +1 -1
  120. package/dist/src/mapper/select/WhereBuilder.js +31 -24
  121. package/dist/src/mapper/select/WhereBuilder.js.map +1 -1
  122. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts +9 -8
  123. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts.map +1 -1
  124. package/dist/src/mapper/select/handlers/FieldsVisitor.js +45 -24
  125. package/dist/src/mapper/select/handlers/FieldsVisitor.js.map +1 -1
  126. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.d.ts.map +1 -1
  127. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js +1 -1
  128. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js.map +1 -1
  129. package/dist/src/mapper/select/optimizer/ConditionOptimizer.d.ts +5 -0
  130. package/dist/src/mapper/select/optimizer/ConditionOptimizer.d.ts.map +1 -0
  131. package/dist/src/mapper/select/optimizer/ConditionOptimizer.js +39 -0
  132. package/dist/src/mapper/select/optimizer/ConditionOptimizer.js.map +1 -0
  133. package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts +15 -0
  134. package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts.map +1 -0
  135. package/dist/src/mapper/select/optimizer/WhereOptimizer.js +118 -0
  136. package/dist/src/mapper/select/optimizer/WhereOptimizer.js.map +1 -0
  137. package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts +6 -0
  138. package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts.map +1 -0
  139. package/dist/src/mapper/select/optimizer/WhereReplacer.js +28 -0
  140. package/dist/src/mapper/select/optimizer/WhereReplacer.js.map +1 -0
  141. package/dist/src/mapper/select/optimizer/helpers.d.ts +10 -0
  142. package/dist/src/mapper/select/optimizer/helpers.d.ts.map +1 -0
  143. package/dist/src/mapper/select/optimizer/helpers.js +72 -0
  144. package/dist/src/mapper/select/optimizer/helpers.js.map +1 -0
  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.map +1 -1
  148. package/dist/src/mapper/update/UpdateBuilder.js +3 -3
  149. package/dist/src/mapper/update/UpdateBuilder.js.map +1 -1
  150. package/dist/src/resolvers/GraphQlQueryAstFactory.js +2 -2
  151. package/dist/src/resolvers/GraphQlQueryAstFactory.js.map +1 -1
  152. package/dist/src/resolvers/MutationResolver.js +15 -15
  153. package/dist/src/resolvers/MutationResolver.js.map +1 -1
  154. package/dist/src/resolvers/ReadHelpers.js +10 -10
  155. package/dist/src/resolvers/ReadHelpers.js.map +1 -1
  156. package/dist/src/resolvers/ReadResolver.js +2 -2
  157. package/dist/src/resolvers/ReadResolver.js.map +1 -1
  158. package/dist/src/schema/FieldAccessVisitor.d.ts +2 -2
  159. package/dist/src/schema/FieldAccessVisitor.d.ts.map +1 -1
  160. package/dist/src/schema/FieldAccessVisitor.js +2 -2
  161. package/dist/src/schema/FieldAccessVisitor.js.map +1 -1
  162. package/dist/src/schema/MutationProvider.js +4 -4
  163. package/dist/src/schema/MutationProvider.js.map +1 -1
  164. package/dist/src/schema/OrderByTypeProvider.js +1 -1
  165. package/dist/src/schema/OrderByTypeProvider.js.map +1 -1
  166. package/dist/src/schema/QueryProvider.js +3 -3
  167. package/dist/src/schema/QueryProvider.js.map +1 -1
  168. package/dist/src/schema/ResultSchemaTypeProvider.d.ts +2 -2
  169. package/dist/src/schema/ResultSchemaTypeProvider.d.ts.map +1 -1
  170. package/dist/src/schema/WhereTypeProvider.js +4 -4
  171. package/dist/src/schema/WhereTypeProvider.js.map +1 -1
  172. package/dist/src/schema/entities/FieldArgsVisitor.d.ts +7 -7
  173. package/dist/src/schema/entities/FieldArgsVisitor.d.ts.map +1 -1
  174. package/dist/src/schema/entities/FieldArgsVisitor.js +3 -3
  175. package/dist/src/schema/entities/FieldArgsVisitor.js.map +1 -1
  176. package/dist/src/schema/entities/FieldTypeVisitor.d.ts +3 -3
  177. package/dist/src/schema/entities/FieldTypeVisitor.d.ts.map +1 -1
  178. package/dist/src/schema/entities/FieldTypeVisitor.js +3 -3
  179. package/dist/src/schema/entities/FieldTypeVisitor.js.map +1 -1
  180. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.d.ts +3 -3
  181. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.d.ts.map +1 -1
  182. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.js +3 -3
  183. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.js.map +1 -1
  184. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.d.ts +6 -6
  185. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.d.ts.map +1 -1
  186. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.js +6 -6
  187. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.js.map +1 -1
  188. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.d.ts +3 -3
  189. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.d.ts.map +1 -1
  190. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.js +5 -5
  191. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.js.map +1 -1
  192. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.d.ts +10 -4
  193. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.d.ts.map +1 -1
  194. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.js +3 -3
  195. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.js.map +1 -1
  196. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.d.ts +6 -6
  197. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.d.ts.map +1 -1
  198. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.js +6 -6
  199. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.js.map +1 -1
  200. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.d.ts +2 -2
  201. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.d.ts.map +1 -1
  202. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js +2 -2
  203. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js.map +1 -1
  204. package/dist/src/tsconfig.tsbuildinfo +1 -1
  205. package/dist/src/utils/object.d.ts.map +1 -1
  206. package/dist/src/utils/object.js +3 -4
  207. package/dist/src/utils/object.js.map +1 -1
  208. package/dist/src/utils/uniqueWhereFields.js +3 -3
  209. package/dist/src/utils/uniqueWhereFields.js.map +1 -1
  210. package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js +1 -1
  211. package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js.map +1 -1
  212. package/dist/tests/cases/integration/graphQlRequests/insert/acl/setField.test.js +2 -2
  213. package/dist/tests/cases/integration/graphQlRequests/insert/acl/setField.test.js.map +1 -1
  214. package/dist/tests/cases/integration/graphQlRequests/insert/aclInsert.test.js +1 -1
  215. package/dist/tests/cases/integration/graphQlRequests/insert/aclInsert.test.js.map +1 -1
  216. package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js +7 -6
  217. package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js.map +1 -1
  218. package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js +1 -1
  219. package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js.map +1 -1
  220. package/dist/tests/cases/integration/graphQlRequests/query/acl/predicateElimination.test.d.ts +2 -0
  221. package/dist/tests/cases/integration/graphQlRequests/query/acl/predicateElimination.test.d.ts.map +1 -0
  222. package/dist/tests/cases/integration/graphQlRequests/query/acl/predicateElimination.test.js +137 -0
  223. package/dist/tests/cases/integration/graphQlRequests/query/acl/predicateElimination.test.js.map +1 -0
  224. package/dist/tests/cases/integration/graphQlRequests/query/filter/complexCondition.test.js +1 -1
  225. package/dist/tests/cases/integration/graphQlRequests/query/filter/composedFilter.test.js +1 -1
  226. package/dist/tests/cases/integration/graphQlRequests/query/filter/composedFilter.test.js.map +1 -1
  227. package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyInverse.test.js +73 -0
  228. package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyInverse.test.js.map +1 -1
  229. package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.js +73 -0
  230. package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.js.map +1 -1
  231. package/dist/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.js +6 -6
  232. package/dist/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.js.map +1 -1
  233. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js +6 -3
  234. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js.map +1 -1
  235. package/dist/tests/cases/integration/graphQlSchema/model.js.map +1 -1
  236. package/dist/tests/cases/unit/aclVariablesFactory.test.js +7 -33
  237. package/dist/tests/cases/unit/aclVariablesFactory.test.js.map +1 -1
  238. package/dist/tests/cases/unit/conditionOptimizer.test.d.ts +2 -0
  239. package/dist/tests/cases/unit/conditionOptimizer.test.d.ts.map +1 -0
  240. package/dist/tests/cases/unit/conditionOptimizer.test.js +118 -0
  241. package/dist/tests/cases/unit/conditionOptimizer.test.js.map +1 -0
  242. package/dist/tests/cases/unit/orderbyHelper.test.js +1 -0
  243. package/dist/tests/cases/unit/orderbyHelper.test.js.map +1 -1
  244. package/dist/tests/cases/unit/permissionMerger.test.js +2 -0
  245. package/dist/tests/cases/unit/permissionMerger.test.js.map +1 -1
  246. package/dist/tests/cases/unit/predicatesFactory.test.d.ts +2 -0
  247. package/dist/tests/cases/unit/predicatesFactory.test.d.ts.map +1 -0
  248. package/dist/tests/cases/unit/predicatesFactory.test.js +109 -0
  249. package/dist/tests/cases/unit/predicatesFactory.test.js.map +1 -0
  250. package/dist/tests/cases/unit/predicatesInjector.test.js +88 -14
  251. package/dist/tests/cases/unit/predicatesInjector.test.js.map +1 -1
  252. package/dist/tests/cases/unit/variableInjector.test.js +4 -3
  253. package/dist/tests/cases/unit/variableInjector.test.js.map +1 -1
  254. package/dist/tests/cases/unit/whereOptimizer.test.d.ts +2 -0
  255. package/dist/tests/cases/unit/whereOptimizer.test.d.ts.map +1 -0
  256. package/dist/tests/cases/unit/whereOptimizer.test.js +265 -0
  257. package/dist/tests/cases/unit/whereOptimizer.test.js.map +1 -0
  258. package/dist/tests/src/testGraphql.d.ts.map +1 -1
  259. package/dist/tests/src/testGraphql.js +10 -2
  260. package/dist/tests/src/testGraphql.js.map +1 -1
  261. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  262. package/graphql.codegen.yml +0 -3
  263. package/package.json +16 -16
  264. package/src/acl/EvaluatedPredicateReplacer.ts +32 -0
  265. package/src/acl/PermissionFactory.ts +18 -13
  266. package/src/acl/PredicateFactory.ts +32 -8
  267. package/src/acl/PredicatesInjector.ts +25 -17
  268. package/src/acl/VariableInjector.ts +2 -15
  269. package/src/acl/VariableUtils.ts +7 -23
  270. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.ts +17 -24
  271. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.ts +1 -6
  272. package/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.ts +26 -46
  273. package/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.ts +6 -3
  274. package/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.ts +4 -22
  275. package/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.ts +26 -49
  276. package/src/input-validation/ColumnValueResolver.ts +2 -3
  277. package/src/input-validation/EntityRulesResolver.ts +4 -4
  278. package/src/input-validation/QueryAstFactory.ts +1 -1
  279. package/src/input-validation/ValidationContext.ts +2 -2
  280. package/src/input-validation/ValidationDataSelector.ts +2 -2
  281. package/src/input-validation/preValidation/CreateInputPreValidationProcessor.ts +7 -8
  282. package/src/input-validation/preValidation/InputPreValidator.ts +4 -4
  283. package/src/input-validation/preValidation/UpdateInputPreValidationProcessor.ts +7 -8
  284. package/src/inputProcessing/CreateInputProcessor.ts +8 -9
  285. package/src/inputProcessing/CreateInputVisitor.ts +27 -89
  286. package/src/inputProcessing/UpdateInputProcessor.ts +8 -9
  287. package/src/inputProcessing/UpdateInputVisitor.ts +25 -71
  288. package/src/inputProcessing/index.ts +0 -1
  289. package/src/introspection/IntrospectionSchemaFactory.ts +7 -7
  290. package/src/introspection/content-schema.types.ts +19 -286
  291. package/src/mapper/Mapper.ts +37 -30
  292. package/src/mapper/MapperContainer.ts +10 -5
  293. package/src/mapper/delete/DeleteExecutor.ts +3 -3
  294. package/src/mapper/insert/SqlCreateInputProcessor.ts +3 -3
  295. package/src/mapper/select/JoinVisitor.ts +6 -33
  296. package/src/mapper/select/RelationFetcher.ts +101 -41
  297. package/src/mapper/select/SelectBuilder.ts +3 -1
  298. package/src/mapper/select/SelectBuilderFactory.ts +2 -1
  299. package/src/mapper/select/SelectExecutionHandler.ts +1 -0
  300. package/src/mapper/select/WhereBuilder.ts +46 -32
  301. package/src/mapper/select/handlers/FieldsVisitor.ts +47 -57
  302. package/src/mapper/select/handlers/FieldsVisitorFactory.ts +1 -0
  303. package/src/mapper/select/optimizer/ConditionOptimizer.ts +41 -0
  304. package/src/mapper/select/optimizer/WhereOptimizer.ts +138 -0
  305. package/src/mapper/select/optimizer/WhereReplacer.ts +27 -0
  306. package/src/mapper/select/optimizer/helpers.ts +58 -0
  307. package/src/mapper/update/SqlUpdateInputProcessor.ts +1 -1
  308. package/src/mapper/update/UpdateBuilder.ts +3 -3
  309. package/src/resolvers/GraphQlQueryAstFactory.ts +3 -3
  310. package/src/resolvers/MutationResolver.ts +1 -1
  311. package/src/resolvers/ReadHelpers.ts +3 -3
  312. package/src/resolvers/ReadResolver.ts +2 -2
  313. package/src/schema/FieldAccessVisitor.ts +2 -2
  314. package/src/schema/OrderByTypeProvider.ts +1 -1
  315. package/src/schema/WhereTypeProvider.ts +4 -4
  316. package/src/schema/entities/FieldArgsVisitor.ts +3 -3
  317. package/src/schema/entities/FieldTypeVisitor.ts +3 -3
  318. package/src/schema/mutations/CreateEntityInputFieldVisitor.ts +3 -6
  319. package/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.ts +6 -20
  320. package/src/schema/mutations/CreateEntityRelationInputFieldVisitor.ts +5 -18
  321. package/src/schema/mutations/UpdateEntityInputFieldVisitor.ts +3 -6
  322. package/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.ts +6 -20
  323. package/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.ts +2 -12
  324. package/src/utils/object.ts +6 -6
  325. package/src/utils/uniqueWhereFields.ts +3 -3
  326. package/tests/cases/integration/graphQlRequests/delete/aclDelete.test.ts +2 -2
  327. package/tests/cases/integration/graphQlRequests/insert/acl/setField.test.ts +3 -3
  328. package/tests/cases/integration/graphQlRequests/insert/aclInsert.test.ts +2 -2
  329. package/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.ts +7 -6
  330. package/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.ts +1 -1
  331. package/tests/cases/integration/graphQlRequests/query/acl/predicateElimination.test.ts +130 -0
  332. package/tests/cases/integration/graphQlRequests/query/filter/complexCondition.test.ts +1 -1
  333. package/tests/cases/integration/graphQlRequests/query/filter/composedFilter.test.ts +1 -1
  334. package/tests/cases/integration/graphQlRequests/query/relations/manyHasManyInverse.test.ts +74 -0
  335. package/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.ts +77 -0
  336. package/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.ts +7 -7
  337. package/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.ts +5 -5
  338. package/tests/cases/unit/aclVariablesFactory.test.ts +8 -35
  339. package/tests/cases/unit/conditionOptimizer.test.ts +135 -0
  340. package/tests/cases/unit/orderbyHelper.test.ts +1 -0
  341. package/tests/cases/unit/permissionMerger.test.ts +2 -0
  342. package/tests/cases/unit/predicatesFactory.test.ts +103 -0
  343. package/tests/cases/unit/predicatesInjector.test.ts +78 -16
  344. package/tests/cases/unit/variableInjector.test.ts +6 -5
  345. package/tests/cases/unit/whereOptimizer.test.ts +289 -0
  346. package/tests/src/testGraphql.ts +9 -2
  347. package/dist/src/inputProcessing/InputContext.d.ts +0 -43
  348. package/dist/src/inputProcessing/InputContext.d.ts.map +0 -1
  349. package/dist/src/inputProcessing/InputContext.js +0 -3
  350. package/dist/src/inputProcessing/InputContext.js.map +0 -1
  351. package/jasmine.json +0 -7
  352. package/src/inputProcessing/InputContext.ts +0 -49
@@ -1,6 +1,6 @@
1
1
  import { Input, Model } from '@contember/schema'
2
2
  import { getColumnName } from '@contember/schema-utils'
3
- import { SelectHydrator, SelectIndexedResultObjects, SelectResultObject } from './select'
3
+ import { SelectGroupedObjects, SelectHydrator, SelectIndexedResultObjects, SelectResultObject } from './select'
4
4
  import { PathFactory } from './select'
5
5
  import * as database from '@contember/database'
6
6
  import { Client, SelectBuilder } from '@contember/database'
@@ -14,7 +14,7 @@ import { Updater } from './update'
14
14
  import { Inserter } from './insert'
15
15
  import { tryMutation } from './ErrorUtils'
16
16
  import { OrderByHelper } from './select'
17
- import { ObjectNode, UniqueWhereExpander } from '../inputProcessing'
17
+ import { ObjectNode, UniqueWhereExpander } from '../inputProcessing'
18
18
  import { UpdateBuilder } from './update'
19
19
  import { Mutex } from '../utils'
20
20
  import { CheckedPrimary } from './CheckedPrimary'
@@ -50,59 +50,64 @@ export class Mapper {
50
50
  .from(entity.tableName, 'root_')
51
51
  .select(['root_', columnName])
52
52
  const expandedWhere = this.uniqueWhereExpander.expand(entity, where)
53
- const builtQb = this.whereBuilder.build(qb, entity, this.pathFactory.create([]), expandedWhere)
53
+ const builtQb = this.whereBuilder.build(qb, entity, this.pathFactory.create([]), expandedWhere, [])
54
54
  const result = await builtQb.getResult(this.db)
55
55
 
56
56
  return result[0] !== undefined ? result[0][columnName] : undefined
57
57
  }
58
58
 
59
- public async select(entity: Model.Entity, input: ObjectNode<Input.ListQueryInput>): Promise<SelectResultObject[]>
60
- public async select(
59
+ public async selectAssoc(
61
60
  entity: Model.Entity,
62
61
  input: ObjectNode<Input.ListQueryInput>,
62
+ relationPath: Model.AnyRelationContext[],
63
63
  indexBy: string,
64
- ): Promise<SelectIndexedResultObjects>
65
- public async select(
66
- entity: Model.Entity,
67
- input: ObjectNode<Input.ListQueryInput>,
68
- indexBy?: string,
69
- ): Promise<SelectResultObject[] | SelectIndexedResultObjects> {
64
+ ): Promise<SelectIndexedResultObjects> {
70
65
  const hydrator = new SelectHydrator()
71
- let qb: SelectBuilder<SelectBuilder.Result> = SelectBuilder.create()
72
- let indexByAlias: string | null = null
73
- if (indexBy) {
74
- const path = this.pathFactory.create([])
75
- indexByAlias = path.for(indexBy).alias
76
- qb = qb.select([path.alias, getColumnName(this.schema, entity, indexBy)], indexByAlias)
77
- }
78
- const rows = await this.selectRows(hydrator, qb, entity, input)
66
+ const path = this.pathFactory.create([])
67
+ const indexByAlias: string = path.for(indexBy).alias
68
+ const qb: SelectBuilder = SelectBuilder.create()
69
+ .select([path.alias, getColumnName(this.schema, entity, indexBy)], indexByAlias)
70
+ const rows = await this.selectRows(hydrator, qb, entity, input, relationPath)
71
+ return await hydrator.hydrateAll(rows, indexByAlias)
72
+ }
73
+
74
+ public async select(entity: Model.Entity, input: ObjectNode<Input.ListQueryInput>, relationPath: Model.AnyRelationContext[]): Promise<SelectResultObject[]> {
75
+ const hydrator = new SelectHydrator()
76
+ const qb: SelectBuilder<SelectBuilder.Result> = SelectBuilder.create()
77
+
78
+ const rows = await this.selectRows(hydrator, qb, entity, input, relationPath)
79
79
 
80
- return await (indexByAlias !== null ? hydrator.hydrateAll(rows, indexByAlias) : hydrator.hydrateAll(rows))
80
+ return await hydrator.hydrateAll(rows)
81
81
  }
82
82
 
83
83
  public async selectUnique(
84
84
  entity: Model.Entity,
85
85
  query: ObjectNode<Input.UniqueQueryInput>,
86
+ relationPath: Model.AnyRelationContext[],
86
87
  ): Promise<SelectResultObject | null> {
87
88
  const uniqueWhere = this.uniqueWhereExpander.expand(entity, query.args.by)
88
89
  const where = query.args.filter ? { and: [uniqueWhere, query.args.filter] } : uniqueWhere
89
90
  const queryExpanded = query.withArg<Input.ListQueryInput>('filter', where)
90
91
 
91
- return (await this.select(entity, queryExpanded))[0] || null
92
+ const rows = await this.select(entity, queryExpanded, relationPath)
93
+
94
+ return rows[0] ?? null
92
95
  }
93
96
 
94
97
  public async selectGrouped(
95
98
  entity: Model.Entity,
96
99
  input: ObjectNode<Input.ListQueryInput>,
97
- relation: Model.JoiningColumnRelation & Model.Relation,
98
- ) {
100
+ relation: Model.JoiningColumnRelation & Model.AnyRelation,
101
+ relationPath: Model.AnyRelationContext[],
102
+ ): Promise<SelectGroupedObjects> {
99
103
  const hydrator = new SelectHydrator()
100
- let qb: SelectBuilder<SelectBuilder.Result> = SelectBuilder.create()
101
104
  const path = this.pathFactory.create([])
102
105
  const groupingKey = '__grouping_key'
103
- qb = qb.select([path.alias, relation.joiningColumn.columnName], groupingKey)
106
+ const qb: SelectBuilder = SelectBuilder.create()
107
+ .select([path.alias, relation.joiningColumn.columnName], groupingKey)
108
+
109
+ const rows = await this.selectRows(hydrator, qb, entity, input, relationPath, relation.name)
104
110
 
105
- const rows = await this.selectRows(hydrator, qb, entity, input, relation.name)
106
111
  return await hydrator.hydrateGroups(rows, groupingKey)
107
112
  }
108
113
 
@@ -111,14 +116,15 @@ export class Mapper {
111
116
  qb: SelectBuilder<SelectBuilder.Result>,
112
117
  entity: Model.Entity,
113
118
  input: ObjectNode<Input.ListQueryInput>,
119
+ relationPath: Model.AnyRelationContext[],
114
120
  groupBy?: string,
115
121
  ) {
116
122
  const inputWithOrder = OrderByHelper.appendDefaultOrderBy(entity, input, [])
117
123
  const path = this.pathFactory.create([])
118
124
  const augmentedBuilder = qb.from(entity.tableName, path.alias).meta('path', [...input.path, input.alias])
119
125
 
120
- const selector = this.selectBuilderFactory.create(augmentedBuilder, hydrator)
121
- const filterWithPredicates = this.predicatesInjector.inject(entity, inputWithOrder.args.filter || {})
126
+ const selector = this.selectBuilderFactory.create(augmentedBuilder, hydrator, relationPath)
127
+ const filterWithPredicates = this.predicatesInjector.inject(entity, inputWithOrder.args.filter || {}, relationPath[relationPath.length - 1])
122
128
  const inputWithPredicates = inputWithOrder.withArg('filter', filterWithPredicates)
123
129
  selector.select(this, entity, inputWithPredicates, path, groupBy)
124
130
  return await selector.execute(this.db)
@@ -130,7 +136,7 @@ export class Mapper {
130
136
  .from(entity.tableName, path.alias)
131
137
  .select(expr => expr.raw('count(*)'), 'row_count')
132
138
  const withPredicates = this.predicatesInjector.inject(entity, filter)
133
- const qbWithWhere = this.whereBuilder.build(qb, entity, path, withPredicates)
139
+ const qbWithWhere = this.whereBuilder.build(qb, entity, path, withPredicates, [])
134
140
  const result = await qbWithWhere.getResult(this.db)
135
141
  return result[0].row_count
136
142
  }
@@ -139,6 +145,7 @@ export class Mapper {
139
145
  entity: Model.Entity,
140
146
  filter: Input.OptionalWhere,
141
147
  relation: Model.JoiningColumnRelation & Model.Relation,
148
+ relationPath: Model.AnyRelationContext[],
142
149
  ): Promise<Record<string, number>> {
143
150
  const path = this.pathFactory.create([])
144
151
  const qb = SelectBuilder.create()
@@ -147,7 +154,7 @@ export class Mapper {
147
154
  .select([path.alias, relation.joiningColumn.columnName])
148
155
  .groupBy([path.alias, relation.joiningColumn.columnName])
149
156
  const withPredicates = this.predicatesInjector.inject(entity, filter)
150
- const qbWithWhere = this.whereBuilder.build(qb, entity, path, withPredicates)
157
+ const qbWithWhere = this.whereBuilder.build(qb, entity, path, withPredicates, relationPath)
151
158
  const rows = await qbWithWhere.getResult(this.db)
152
159
  const result = new Map<string, number>()
153
160
  for (const row of rows) {
@@ -27,11 +27,13 @@ import {
27
27
  Updater,
28
28
  } from '../mapper'
29
29
  import { Builder } from '@contember/dic'
30
- import { Acl, Schema } from '@contember/schema'
30
+ import { Acl, Model, Schema } from '@contember/schema'
31
31
  import { Client, SelectBuilder as DbSelectBuilder } from '@contember/database'
32
32
  import { Providers } from '@contember/schema-utils'
33
33
  import { PaginatedHasManyExecutionHandler } from '../extensions/paginatedHasMany/PaginatedHasManyExecutionHandler'
34
34
  import { PaginatedHasManyFieldProvider } from '../extensions/paginatedHasMany/PaginatedHasManyFieldProvider'
35
+ import { WhereOptimizer } from './select/optimizer/WhereOptimizer'
36
+ import { ConditionOptimizer } from './select/optimizer/ConditionOptimizer'
35
37
 
36
38
  type MapperContainerArgs = {
37
39
  schema: Schema
@@ -51,7 +53,7 @@ export const createMapperContainer = ({ permissions, schema, identityVariables,
51
53
  .addService('variableInjector', () =>
52
54
  new VariableInjector(schema.model, identityVariables))
53
55
  .addService('predicateFactory', ({ variableInjector }) =>
54
- new PredicateFactory(permissions, variableInjector))
56
+ new PredicateFactory(permissions, schema.model, variableInjector))
55
57
  .addService('predicatesInjector', ({ predicateFactory }) =>
56
58
  new PredicatesInjector(schema.model, predicateFactory))
57
59
  .addService('joinBuilder', () =>
@@ -60,8 +62,10 @@ export const createMapperContainer = ({ permissions, schema, identityVariables,
60
62
  new ConditionBuilder())
61
63
  .addService('pathFactory', () =>
62
64
  new PathFactory())
63
- .addService('whereBuilder', ({ joinBuilder, conditionBuilder, pathFactory }) =>
64
- new WhereBuilder(schema.model, joinBuilder, conditionBuilder, pathFactory))
65
+ .addService('whereOptimized', () =>
66
+ new WhereOptimizer(schema.model, new ConditionOptimizer()))
67
+ .addService('whereBuilder', ({ joinBuilder, conditionBuilder, pathFactory, whereOptimized }) =>
68
+ new WhereBuilder(schema.model, joinBuilder, conditionBuilder, pathFactory, whereOptimized))
65
69
  .addService('orderByBuilder', ({ joinBuilder }) =>
66
70
  new OrderByBuilder(schema.model, joinBuilder))
67
71
  .addService('relationFetcher', ({ whereBuilder, orderByBuilder, predicatesInjector, pathFactory }) =>
@@ -82,7 +86,7 @@ export const createMapperContainer = ({ permissions, schema, identityVariables,
82
86
  }))
83
87
  .addService('selectBuilderFactory', ({ whereBuilder, orderByBuilder, fieldsVisitorFactory, metaHandler, selectHandlers, pathFactory }) =>
84
88
  new (class implements SelectBuilderFactory {
85
- create(qb: DbSelectBuilder, hydrator: SelectHydrator): SelectBuilder {
89
+ create(qb: DbSelectBuilder, hydrator: SelectHydrator, relationPath: Model.AnyRelationContext[]): SelectBuilder {
86
90
  return new SelectBuilder(
87
91
  schema.model,
88
92
  whereBuilder,
@@ -93,6 +97,7 @@ export const createMapperContainer = ({ permissions, schema, identityVariables,
93
97
  fieldsVisitorFactory,
94
98
  selectHandlers,
95
99
  pathFactory,
100
+ relationPath,
96
101
  )
97
102
  }
98
103
  })())
@@ -131,8 +131,8 @@ export class DeleteExecutor {
131
131
  visitManyHasManyOwning: () => null,
132
132
  visitOneHasOneInverse: () => null,
133
133
  visitOneHasMany: () => null,
134
- visitOneHasOneOwning: ({}, relation): EntityOwningRelationTuple => [entity, relation],
135
- visitManyHasOne: ({}, relation): EntityOwningRelationTuple => [entity, relation],
134
+ visitOneHasOneOwning: ({ relation }): EntityOwningRelationTuple => [entity, relation],
135
+ visitManyHasOne: ({ relation }): EntityOwningRelationTuple => [entity, relation],
136
136
  }),
137
137
  )
138
138
  .reduce<EntityOwningRelationTuple[]>(
@@ -155,7 +155,7 @@ export class DeleteExecutor {
155
155
  visitManyHasManyOwning: () => null,
156
156
  visitOneHasOneInverse: () => null,
157
157
  visitOneHasMany: () => null,
158
- visitOneHasOneOwning: ({}, relation, targetEntity) =>
158
+ visitOneHasOneOwning: ({ relation, targetEntity }) =>
159
159
  relation.orphanRemoval ? [targetEntity, relation] : null,
160
160
  visitManyHasOne: () => null,
161
161
  }),
@@ -1,4 +1,4 @@
1
- import { Input, Value } from '@contember/schema'
1
+ import { Input, Model, Value } from '@contember/schema'
2
2
  import { Mapper } from '../Mapper'
3
3
  import { InsertBuilder } from './InsertBuilder'
4
4
  import { Providers, resolveColumnValue } from '@contember/schema-utils'
@@ -15,7 +15,7 @@ export class SqlCreateInputProcessor implements CreateInputProcessor<MutationRes
15
15
  private readonly providers: Providers,
16
16
  ) {}
17
17
 
18
- public async column(context: Context.ColumnContext): Promise<MutationResultList> {
18
+ public async column(context: Model.ColumnContext & { input: Input.ColumnValue | undefined }): Promise<MutationResultList> {
19
19
  this.insertBuilder.addFieldValue(
20
20
  context.column.name,
21
21
  ((): Value.GenericValueLike<Value.AtomicValue | undefined> => {
@@ -159,7 +159,7 @@ export class SqlCreateInputProcessor implements CreateInputProcessor<MutationRes
159
159
  return []
160
160
  },
161
161
  connect: hasOneProcessor(
162
- async (context: Context.OneHasOneOwningContext & { input: Input.UniqueWhere }): Promise<MutationResultList> => {
162
+ async (context: Model.OneHasOneOwningContext & { input: Input.UniqueWhere }): Promise<MutationResultList> => {
163
163
  const primaryValue = this.mapper.getPrimaryValue(context.targetEntity, context.input)
164
164
  this.insertBuilder.addFieldValue(context.relation.name, async () => {
165
165
  const value = await primaryValue
@@ -4,11 +4,7 @@ import { Path } from './Path'
4
4
  export class JoinVisitor implements Model.RelationByTypeVisitor<JoinDefinition[]> {
5
5
  constructor(private readonly path: Path) {}
6
6
 
7
- visitOneHasOneOwning(
8
- entity: Model.Entity,
9
- relation: Model.OneHasOneOwningRelation,
10
- targetEntity: Model.Entity,
11
- ): JoinDefinition[] {
7
+ visitOneHasOneOwning({ targetEntity, relation }: Model.OneHasOneOwningContext): JoinDefinition[] {
12
8
  return [
13
9
  {
14
10
  tableName: targetEntity.tableName,
@@ -18,12 +14,7 @@ export class JoinVisitor implements Model.RelationByTypeVisitor<JoinDefinition[]
18
14
  ]
19
15
  }
20
16
 
21
- visitOneHasOneInverse(
22
- entity: Model.Entity,
23
- relation: Model.OneHasOneInverseRelation,
24
- targetEntity: Model.Entity,
25
- targetRelation: Model.OneHasOneOwningRelation,
26
- ): JoinDefinition[] {
17
+ visitOneHasOneInverse({ targetEntity, entity, targetRelation }: Model.OneHasOneInverseContext): JoinDefinition[] {
27
18
  return [
28
19
  {
29
20
  tableName: targetEntity.tableName,
@@ -33,11 +24,7 @@ export class JoinVisitor implements Model.RelationByTypeVisitor<JoinDefinition[]
33
24
  ]
34
25
  }
35
26
 
36
- visitManyHasOne(
37
- entity: Model.Entity,
38
- relation: Model.ManyHasOneRelation,
39
- targetEntity: Model.Entity,
40
- ): JoinDefinition[] {
27
+ visitManyHasOne({ targetEntity, relation }: Model.ManyHasOneContext): JoinDefinition[] {
41
28
  return [
42
29
  {
43
30
  tableName: targetEntity.tableName,
@@ -47,12 +34,7 @@ export class JoinVisitor implements Model.RelationByTypeVisitor<JoinDefinition[]
47
34
  ]
48
35
  }
49
36
 
50
- visitOneHasMany(
51
- entity: Model.Entity,
52
- relation: Model.OneHasManyRelation,
53
- targetEntity: Model.Entity,
54
- targetRelation: Model.ManyHasOneRelation,
55
- ): JoinDefinition[] {
37
+ visitOneHasMany({ targetEntity, targetRelation, entity }: Model.OneHasManyContext): JoinDefinition[] {
56
38
  return [
57
39
  {
58
40
  tableName: targetEntity.tableName,
@@ -63,11 +45,7 @@ export class JoinVisitor implements Model.RelationByTypeVisitor<JoinDefinition[]
63
45
  ]
64
46
  }
65
47
 
66
- visitManyHasManyOwning(
67
- entity: Model.Entity,
68
- relation: Model.ManyHasManyOwningRelation,
69
- targetEntity: Model.Entity,
70
- ): JoinDefinition[] {
48
+ visitManyHasManyOwning({ relation, entity, targetEntity }: Model.ManyHasManyOwningContext): JoinDefinition[] {
71
49
  const sourceAlias = this.path.back().alias
72
50
  const targetAlias = this.path.alias
73
51
  const joiningAlias = this.path.back().for('x_' + this.path.alias).alias
@@ -90,12 +68,7 @@ export class JoinVisitor implements Model.RelationByTypeVisitor<JoinDefinition[]
90
68
  ]
91
69
  }
92
70
 
93
- visitManyHasManyInverse(
94
- entity: Model.Entity,
95
- relation: Model.ManyHasManyInverseRelation,
96
- targetEntity: Model.Entity,
97
- targetRelation: Model.ManyHasManyOwningRelation,
98
- ): JoinDefinition[] {
71
+ visitManyHasManyInverse({ targetRelation, entity, targetEntity }: Model.ManyHasManyInverseContext): JoinDefinition[] {
99
72
  const sourceAlias = this.path.back().alias
100
73
  const targetAlias = this.path.alias
101
74
  const joiningAlias = this.path.back().for('x_' + this.path.alias).alias
@@ -12,6 +12,41 @@ import { Mapper } from '../Mapper'
12
12
 
13
13
  export type GroupedCounts = Record<Input.PrimaryValue, number>
14
14
 
15
+ type CountOneHasManyGroupsArgs = {
16
+ mapper: Mapper
17
+ filter: Input.OptionalWhere | undefined
18
+ relationPath: Model.AnyRelationContext[]
19
+ relationContext: Model.OneHasManyContext
20
+ ids: Input.PrimaryValue[]
21
+ }
22
+
23
+ type FetchOneHasManyGroupsArgs = {
24
+ mapper: Mapper
25
+ objectNode: ObjectNode<Input.ListQueryInput>
26
+ relationPath: Model.AnyRelationContext[]
27
+ relationContext: Model.OneHasManyContext
28
+ ids: Input.PrimaryValue[]
29
+ }
30
+
31
+ type ManyHasManyBaseArgs =
32
+ & {
33
+ mapper: Mapper
34
+ ids: Input.PrimaryValue[]
35
+ relationPath: Model.AnyRelationContext[]
36
+ relationContext: Model.ManyHasManyInverseContext | Model.ManyHasManyOwningContext
37
+ }
38
+ type CountManyHasManyGroupArgs =
39
+ & ManyHasManyBaseArgs
40
+ & {
41
+ filter: Input.OptionalWhere | undefined
42
+ }
43
+
44
+ type FetchManyHasManyGroupsArgs =
45
+ & ManyHasManyBaseArgs
46
+ & {
47
+ field: ObjectNode<Input.ListQueryInput>
48
+ }
49
+
15
50
  export class RelationFetcher {
16
51
  constructor(
17
52
  private readonly whereBuilder: WhereBuilder,
@@ -20,25 +55,29 @@ export class RelationFetcher {
20
55
  private readonly pathFactory: PathFactory,
21
56
  ) {}
22
57
 
23
- public async countOneHasManyGroups(
24
- mapper: Mapper,
25
- filter: Input.OptionalWhere | undefined,
26
- targetEntity: Model.Entity,
27
- targetRelation: Model.ManyHasOneRelation,
28
- ids: Input.PrimaryValue[],
29
- ): Promise<GroupedCounts> {
58
+ public async countOneHasManyGroups({
59
+ mapper,
60
+ filter,
61
+ relationContext,
62
+ relationPath,
63
+ ids,
64
+ }: CountOneHasManyGroupsArgs): Promise<GroupedCounts> {
65
+ const { targetRelation, targetEntity } = relationContext
30
66
  const filterWithParent = this.createOneHasManyFilter(targetEntity, targetRelation, ids, filter)
31
- return mapper.countGrouped(targetEntity, filterWithParent, targetRelation)
67
+ return mapper.countGrouped(targetEntity, filterWithParent, targetRelation, [
68
+ ...relationPath,
69
+ relationContext,
70
+ ])
32
71
  }
33
72
 
34
- public async fetchOneHasManyGroups(
35
- mapper: Mapper,
36
- objectNode: ObjectNode<Input.ListQueryInput>,
37
- targetEntity: Model.Entity,
38
- relation: Model.OneHasManyRelation,
39
- targetRelation: Model.ManyHasOneRelation,
40
- ids: Input.PrimaryValue[],
41
- ): Promise<SelectGroupedObjects> {
73
+ public async fetchOneHasManyGroups({
74
+ mapper,
75
+ objectNode,
76
+ relationContext,
77
+ relationPath,
78
+ ids,
79
+ }: FetchOneHasManyGroupsArgs): Promise<SelectGroupedObjects> {
80
+ const { relation, targetEntity, targetRelation } = relationContext
42
81
  const filter = this.createOneHasManyFilter(targetEntity, targetRelation, ids, objectNode.args.filter)
43
82
  const objectNodeWithWhere = objectNode.withArg<Input.ListQueryInput>('filter', filter)
44
83
  const objectNodeWithOrder = OrderByHelper.appendDefaultOrderBy(
@@ -47,7 +86,10 @@ export class RelationFetcher {
47
86
  relation.orderBy || [],
48
87
  )
49
88
 
50
- return mapper.selectGrouped(targetEntity, objectNodeWithOrder, targetRelation)
89
+ return mapper.selectGrouped(targetEntity, objectNodeWithOrder, targetRelation, [
90
+ ...relationPath,
91
+ relationContext,
92
+ ])
51
93
  }
52
94
 
53
95
  private createOneHasManyFilter(
@@ -65,38 +107,43 @@ export class RelationFetcher {
65
107
  }
66
108
  }
67
109
 
68
- public async countManyHasManyGroups(
69
- mapper: Mapper,
70
- filter: Input.OptionalWhere | undefined,
71
- targetEntity: Model.Entity,
72
- owningRelation: Model.ManyHasManyOwningRelation,
73
- ids: Input.PrimaryValue[],
74
- joiningColumns: JoiningColumns,
75
- ): Promise<GroupedCounts> {
76
- const qb = this.buildJunctionQb(owningRelation, ids, joiningColumns, targetEntity, { filter })
110
+ public async countManyHasManyGroups({
111
+ mapper,
112
+ filter,
113
+ relationContext,
114
+ relationPath,
115
+ ids,
116
+ }: CountManyHasManyGroupArgs): Promise<GroupedCounts> {
117
+ const owningRelation = relationContext.type === 'manyHasManyInverse' ? relationContext.targetRelation : relationContext.relation
118
+
119
+ const joiningColumns = this.resolveJoiningColumns({ relationType: relationContext.type, joiningTable: owningRelation.joiningTable })
120
+
121
+ const qb = this.buildJunctionQb(owningRelation, ids, joiningColumns, relationContext.targetEntity, { filter }, relationPath)
77
122
  .select(['junction_', joiningColumns.sourceColumn.columnName])
78
123
  .select(expr => expr.raw('count(*)'), 'row_count')
79
124
  .groupBy(['junction_', joiningColumns.sourceColumn.columnName])
125
+
80
126
  const result = new Map<string, number>()
81
127
  const rows = await qb.getResult(mapper.db)
82
128
  for (const row of rows) {
83
129
  result.set(String(row[joiningColumns.sourceColumn.columnName]), Number(row.row_count))
84
130
  }
131
+
85
132
  return Object.fromEntries(result)
86
133
  }
87
134
 
88
- public async fetchManyHasManyGroups(
89
- mapper: Mapper,
90
- field: ObjectNode<Input.ListQueryInput>,
91
- targetEntity: Model.Entity,
92
- fromRelation: Model.ManyHasManyOwningRelation | Model.ManyHasManyInverseRelation,
93
- owningRelation: Model.ManyHasManyOwningRelation,
94
- joiningColumns: JoiningColumns,
95
- ids: Input.PrimaryValue[],
96
- ): Promise<SelectGroupedObjects> {
97
- const defaultOrderBy = fromRelation.orderBy || []
98
- const objectNode = OrderByHelper.appendDefaultOrderBy(targetEntity, field, defaultOrderBy)
99
-
135
+ public async fetchManyHasManyGroups({
136
+ mapper,
137
+ field,
138
+ relationContext,
139
+ relationPath,
140
+ ids,
141
+ }: FetchManyHasManyGroupsArgs): Promise<SelectGroupedObjects> {
142
+ const owningRelation = relationContext.type === 'manyHasManyInverse' ? relationContext.targetRelation : relationContext.relation
143
+ const joiningColumns = this.resolveJoiningColumns({ relationType: relationContext.type, joiningTable: owningRelation.joiningTable })
144
+ const defaultOrderBy = relationContext.relation.orderBy || []
145
+ const objectNode = OrderByHelper.appendDefaultOrderBy(relationContext.targetEntity, field, defaultOrderBy)
146
+ const { targetEntity } = relationContext
100
147
  const junctionValues = await this.fetchJunction(
101
148
  mapper.db,
102
149
  owningRelation,
@@ -104,6 +151,7 @@ export class RelationFetcher {
104
151
  joiningColumns,
105
152
  targetEntity,
106
153
  objectNode,
154
+ relationPath,
107
155
  )
108
156
  if (junctionValues.length === 0) {
109
157
  return {}
@@ -122,11 +170,21 @@ export class RelationFetcher {
122
170
  },
123
171
  })
124
172
  .withField(primaryField)
125
- const result = await mapper.select(targetEntity, queryWithWhere)
173
+ const result = await mapper.select(targetEntity, queryWithWhere, [...relationPath, relationContext])
126
174
 
127
175
  return this.buildManyHasManyGroups(targetEntity, joiningColumns, result, junctionValues)
128
176
  }
129
177
 
178
+ private resolveJoiningColumns({ relationType, joiningTable }: { joiningTable: Model.JoiningTable; relationType: 'manyHasManyOwning' | 'manyHasManyInverse' }): JoiningColumns {
179
+ return relationType === 'manyHasManyOwning' ? {
180
+ sourceColumn: joiningTable.joiningColumn,
181
+ targetColumn: joiningTable.inverseJoiningColumn,
182
+ } : {
183
+ sourceColumn: joiningTable.inverseJoiningColumn,
184
+ targetColumn: joiningTable.joiningColumn,
185
+ }
186
+ }
187
+
130
188
  private buildManyHasManyGroups(
131
189
  entity: Model.Entity,
132
190
  joiningColumns: JoiningColumns,
@@ -159,9 +217,10 @@ export class RelationFetcher {
159
217
  column: JoiningColumns,
160
218
  targetEntity: Model.Entity,
161
219
  object: ObjectNode<Input.ListQueryInput>,
220
+ relationPath: Model.AnyRelationContext[],
162
221
  ): Promise<Record<string, Value.AtomicValue>[]> {
163
222
  const joiningTable = relation.joiningTable
164
- const qb = this.buildJunctionQb(relation, values, column, targetEntity, object.args)
223
+ const qb = this.buildJunctionQb(relation, values, column, targetEntity, object.args, relationPath)
165
224
  .select(['junction_', joiningTable.inverseJoiningColumn.columnName])
166
225
  .select(['junction_', joiningTable.joiningColumn.columnName])
167
226
  const wrapper = new LimitByGroupWrapper(
@@ -191,6 +250,7 @@ export class RelationFetcher {
191
250
  column: JoiningColumns,
192
251
  targetEntity: Model.Entity,
193
252
  objectArgs: Input.ListQueryInput,
253
+ relationPath: Model.AnyRelationContext[],
194
254
  ): SelectBuilder {
195
255
  const joiningTable = relation.joiningTable
196
256
 
@@ -218,7 +278,7 @@ export class RelationFetcher {
218
278
  }
219
279
 
220
280
  if (where && hasWhere) {
221
- qb = this.whereBuilder.build(qb, targetEntity, this.pathFactory.create([]), where)
281
+ qb = this.whereBuilder.build(qb, targetEntity, this.pathFactory.create([]), where, relationPath)
222
282
  }
223
283
  return qb
224
284
  }
@@ -30,6 +30,7 @@ export class SelectBuilder {
30
30
  private readonly fieldsVisitorFactory: FieldsVisitorFactory,
31
31
  private readonly selectHandlers: { [key: string]: SelectExecutionHandler<any> },
32
32
  private readonly pathFactory: PathFactory,
33
+ private readonly relationPath: Model.AnyRelationContext[],
33
34
  ) {}
34
35
 
35
36
  public async execute(db: Client): Promise<SelectRow[]> {
@@ -53,7 +54,7 @@ export class SelectBuilder {
53
54
  this.selectInternal(mapper, entity, path, input)
54
55
  const where = input.args.filter
55
56
  if (where) {
56
- this.qb = this.whereBuilder.build(this.qb, entity, path, where)
57
+ this.qb = this.whereBuilder.build(this.qb, entity, path, where, this.relationPath)
57
58
  }
58
59
  const orderBy = input.args.orderBy || []
59
60
 
@@ -96,6 +97,7 @@ export class SelectBuilder {
96
97
  })()
97
98
  const executionContext: SelectExecutionHandlerContext = {
98
99
  mapper,
100
+ relationPath: this.relationPath,
99
101
  addData: async (fieldName, cb, defaultValue = null) => {
100
102
  const columnName = getColumnName(this.schema, entity, fieldName)
101
103
  const ids = (await this.getColumnValues(path.for(fieldName), columnName)).filter(it => it !== null)
@@ -1,7 +1,8 @@
1
1
  import { SelectBuilder } from './SelectBuilder'
2
2
  import { SelectHydrator } from './SelectHydrator'
3
3
  import { SelectBuilder as DbSelectBuilder } from '@contember/database'
4
+ import { Model } from '@contember/schema'
4
5
 
5
6
  export interface SelectBuilderFactory {
6
- create(qb: DbSelectBuilder<DbSelectBuilder.Result>, hydrator: SelectHydrator): SelectBuilder
7
+ create(qb: DbSelectBuilder<DbSelectBuilder.Result>, hydrator: SelectHydrator, relationPath: Model.AnyRelationContext[]): SelectBuilder
7
8
  }
@@ -21,6 +21,7 @@ export type SelectExecutionHandlerContext<
21
21
  mapper: Mapper
22
22
  path: Path
23
23
  entity: Model.Entity
24
+ relationPath: Model.AnyRelationContext[]
24
25
 
25
26
  addColumn: (
26
27
  queryCallback: (qb: SelectBuilder<SelectBuilder.Result>) => SelectBuilder<SelectBuilder.Result>,