@contember/engine-content-api 1.2.0-alpha.10 → 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 (236) hide show
  1. package/dist/src/acl/PredicateFactory.d.ts +1 -1
  2. package/dist/src/acl/PredicateFactory.d.ts.map +1 -1
  3. package/dist/src/acl/PredicateFactory.js +6 -13
  4. package/dist/src/acl/PredicateFactory.js.map +1 -1
  5. package/dist/src/acl/PredicatesInjector.d.ts +1 -1
  6. package/dist/src/acl/PredicatesInjector.d.ts.map +1 -1
  7. package/dist/src/acl/PredicatesInjector.js +13 -20
  8. package/dist/src/acl/PredicatesInjector.js.map +1 -1
  9. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.d.ts +0 -1
  10. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.d.ts.map +1 -1
  11. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.js +14 -15
  12. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.js.map +1 -1
  13. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts +1 -1
  14. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts.map +1 -1
  15. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js +1 -1
  16. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js.map +1 -1
  17. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.d.ts +5 -4
  18. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.d.ts.map +1 -1
  19. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js +11 -14
  20. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js.map +1 -1
  21. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.d.ts.map +1 -1
  22. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.js +2 -2
  23. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.js.map +1 -1
  24. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts +3 -3
  25. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts.map +1 -1
  26. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js +3 -3
  27. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js.map +1 -1
  28. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.d.ts +5 -4
  29. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.d.ts.map +1 -1
  30. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js +11 -15
  31. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js.map +1 -1
  32. package/dist/src/input-validation/ColumnValueResolver.d.ts +4 -3
  33. package/dist/src/input-validation/ColumnValueResolver.d.ts.map +1 -1
  34. package/dist/src/input-validation/ColumnValueResolver.js.map +1 -1
  35. package/dist/src/input-validation/EntityRulesResolver.js +4 -4
  36. package/dist/src/input-validation/EntityRulesResolver.js.map +1 -1
  37. package/dist/src/input-validation/QueryAstFactory.js +1 -1
  38. package/dist/src/input-validation/QueryAstFactory.js.map +1 -1
  39. package/dist/src/input-validation/ValidationDataSelector.js +1 -1
  40. package/dist/src/input-validation/ValidationDataSelector.js.map +1 -1
  41. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.d.ts +7 -8
  42. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.d.ts.map +1 -1
  43. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.js.map +1 -1
  44. package/dist/src/input-validation/preValidation/InputPreValidator.js +4 -4
  45. package/dist/src/input-validation/preValidation/InputPreValidator.js.map +1 -1
  46. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.d.ts +7 -8
  47. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.d.ts.map +1 -1
  48. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.js.map +1 -1
  49. package/dist/src/inputProcessing/CreateInputProcessor.d.ts +8 -9
  50. package/dist/src/inputProcessing/CreateInputProcessor.d.ts.map +1 -1
  51. package/dist/src/inputProcessing/CreateInputVisitor.d.ts +7 -7
  52. package/dist/src/inputProcessing/CreateInputVisitor.d.ts.map +1 -1
  53. package/dist/src/inputProcessing/CreateInputVisitor.js +15 -46
  54. package/dist/src/inputProcessing/CreateInputVisitor.js.map +1 -1
  55. package/dist/src/inputProcessing/UpdateInputProcessor.d.ts +8 -9
  56. package/dist/src/inputProcessing/UpdateInputProcessor.d.ts.map +1 -1
  57. package/dist/src/inputProcessing/UpdateInputVisitor.d.ts +7 -7
  58. package/dist/src/inputProcessing/UpdateInputVisitor.d.ts.map +1 -1
  59. package/dist/src/inputProcessing/UpdateInputVisitor.js +13 -28
  60. package/dist/src/inputProcessing/UpdateInputVisitor.js.map +1 -1
  61. package/dist/src/inputProcessing/index.d.ts +0 -1
  62. package/dist/src/inputProcessing/index.d.ts.map +1 -1
  63. package/dist/src/inputProcessing/index.js +0 -1
  64. package/dist/src/inputProcessing/index.js.map +1 -1
  65. package/dist/src/introspection/IntrospectionSchemaFactory.js +7 -7
  66. package/dist/src/introspection/IntrospectionSchemaFactory.js.map +1 -1
  67. package/dist/src/mapper/Mapper.d.ts +6 -6
  68. package/dist/src/mapper/Mapper.d.ts.map +1 -1
  69. package/dist/src/mapper/Mapper.js +28 -23
  70. package/dist/src/mapper/Mapper.js.map +1 -1
  71. package/dist/src/mapper/MapperContainer.d.ts.map +1 -1
  72. package/dist/src/mapper/MapperContainer.js +2 -2
  73. package/dist/src/mapper/MapperContainer.js.map +1 -1
  74. package/dist/src/mapper/delete/DeleteExecutor.js +3 -3
  75. package/dist/src/mapper/delete/DeleteExecutor.js.map +1 -1
  76. package/dist/src/mapper/insert/SqlCreateInputProcessor.d.ts +4 -2
  77. package/dist/src/mapper/insert/SqlCreateInputProcessor.d.ts.map +1 -1
  78. package/dist/src/mapper/insert/SqlCreateInputProcessor.js.map +1 -1
  79. package/dist/src/mapper/select/JoinVisitor.d.ts +6 -6
  80. package/dist/src/mapper/select/JoinVisitor.d.ts.map +1 -1
  81. package/dist/src/mapper/select/JoinVisitor.js +6 -6
  82. package/dist/src/mapper/select/JoinVisitor.js.map +1 -1
  83. package/dist/src/mapper/select/RelationFetcher.d.ts +11 -19
  84. package/dist/src/mapper/select/RelationFetcher.d.ts.map +1 -1
  85. package/dist/src/mapper/select/RelationFetcher.js +34 -25
  86. package/dist/src/mapper/select/RelationFetcher.js.map +1 -1
  87. package/dist/src/mapper/select/SelectBuilder.d.ts +2 -1
  88. package/dist/src/mapper/select/SelectBuilder.d.ts.map +1 -1
  89. package/dist/src/mapper/select/SelectBuilder.js +4 -2
  90. package/dist/src/mapper/select/SelectBuilder.js.map +1 -1
  91. package/dist/src/mapper/select/SelectBuilderFactory.d.ts +2 -1
  92. package/dist/src/mapper/select/SelectBuilderFactory.d.ts.map +1 -1
  93. package/dist/src/mapper/select/SelectExecutionHandler.d.ts +1 -0
  94. package/dist/src/mapper/select/SelectExecutionHandler.d.ts.map +1 -1
  95. package/dist/src/mapper/select/WhereBuilder.d.ts +3 -2
  96. package/dist/src/mapper/select/WhereBuilder.d.ts.map +1 -1
  97. package/dist/src/mapper/select/WhereBuilder.js +29 -24
  98. package/dist/src/mapper/select/WhereBuilder.js.map +1 -1
  99. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts +9 -8
  100. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts.map +1 -1
  101. package/dist/src/mapper/select/handlers/FieldsVisitor.js +33 -25
  102. package/dist/src/mapper/select/handlers/FieldsVisitor.js.map +1 -1
  103. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.d.ts.map +1 -1
  104. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js +1 -1
  105. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js.map +1 -1
  106. package/dist/src/mapper/select/optimizer/ConditionOptimizer.d.ts.map +1 -1
  107. package/dist/src/mapper/select/optimizer/ConditionOptimizer.js +6 -0
  108. package/dist/src/mapper/select/optimizer/ConditionOptimizer.js.map +1 -1
  109. package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts +2 -1
  110. package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts.map +1 -1
  111. package/dist/src/mapper/select/optimizer/WhereOptimizer.js +52 -20
  112. package/dist/src/mapper/select/optimizer/WhereOptimizer.js.map +1 -1
  113. package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts +4 -1
  114. package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts.map +1 -1
  115. package/dist/src/mapper/select/optimizer/WhereReplacer.js +4 -3
  116. package/dist/src/mapper/select/optimizer/WhereReplacer.js.map +1 -1
  117. package/dist/src/mapper/update/SqlUpdateInputProcessor.d.ts +2 -3
  118. package/dist/src/mapper/update/SqlUpdateInputProcessor.d.ts.map +1 -1
  119. package/dist/src/mapper/update/SqlUpdateInputProcessor.js.map +1 -1
  120. package/dist/src/mapper/update/UpdateBuilder.js +3 -3
  121. package/dist/src/mapper/update/UpdateBuilder.js.map +1 -1
  122. package/dist/src/resolvers/MutationResolver.js +1 -1
  123. package/dist/src/resolvers/MutationResolver.js.map +1 -1
  124. package/dist/src/resolvers/ReadHelpers.js +3 -3
  125. package/dist/src/resolvers/ReadHelpers.js.map +1 -1
  126. package/dist/src/resolvers/ReadResolver.js +2 -2
  127. package/dist/src/resolvers/ReadResolver.js.map +1 -1
  128. package/dist/src/schema/FieldAccessVisitor.d.ts +2 -2
  129. package/dist/src/schema/FieldAccessVisitor.d.ts.map +1 -1
  130. package/dist/src/schema/FieldAccessVisitor.js +2 -2
  131. package/dist/src/schema/FieldAccessVisitor.js.map +1 -1
  132. package/dist/src/schema/OrderByTypeProvider.js +1 -1
  133. package/dist/src/schema/OrderByTypeProvider.js.map +1 -1
  134. package/dist/src/schema/WhereTypeProvider.js +4 -4
  135. package/dist/src/schema/WhereTypeProvider.js.map +1 -1
  136. package/dist/src/schema/entities/FieldArgsVisitor.d.ts +3 -3
  137. package/dist/src/schema/entities/FieldArgsVisitor.d.ts.map +1 -1
  138. package/dist/src/schema/entities/FieldArgsVisitor.js +3 -3
  139. package/dist/src/schema/entities/FieldArgsVisitor.js.map +1 -1
  140. package/dist/src/schema/entities/FieldTypeVisitor.d.ts +3 -3
  141. package/dist/src/schema/entities/FieldTypeVisitor.d.ts.map +1 -1
  142. package/dist/src/schema/entities/FieldTypeVisitor.js +3 -3
  143. package/dist/src/schema/entities/FieldTypeVisitor.js.map +1 -1
  144. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.d.ts +3 -3
  145. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.d.ts.map +1 -1
  146. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.js +3 -3
  147. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.js.map +1 -1
  148. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.d.ts +6 -6
  149. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.d.ts.map +1 -1
  150. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.js +6 -6
  151. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.js.map +1 -1
  152. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.d.ts +3 -3
  153. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.d.ts.map +1 -1
  154. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.js +5 -5
  155. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.js.map +1 -1
  156. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.d.ts +10 -4
  157. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.d.ts.map +1 -1
  158. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.js +3 -3
  159. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.js.map +1 -1
  160. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.d.ts +6 -6
  161. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.d.ts.map +1 -1
  162. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.js +6 -6
  163. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.js.map +1 -1
  164. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.d.ts +2 -2
  165. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.d.ts.map +1 -1
  166. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js +2 -2
  167. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js.map +1 -1
  168. package/dist/src/tsconfig.tsbuildinfo +1 -1
  169. package/dist/src/utils/uniqueWhereFields.js +3 -3
  170. package/dist/src/utils/uniqueWhereFields.js.map +1 -1
  171. package/dist/tests/cases/unit/predicatesFactory.test.js +7 -1
  172. package/dist/tests/cases/unit/predicatesFactory.test.js.map +1 -1
  173. package/dist/tests/cases/unit/whereOptimizer.test.js +82 -0
  174. package/dist/tests/cases/unit/whereOptimizer.test.js.map +1 -1
  175. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  176. package/package.json +10 -10
  177. package/src/acl/PredicateFactory.ts +7 -14
  178. package/src/acl/PredicatesInjector.ts +13 -18
  179. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.ts +17 -24
  180. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.ts +1 -6
  181. package/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.ts +10 -28
  182. package/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.ts +6 -3
  183. package/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.ts +4 -22
  184. package/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.ts +10 -29
  185. package/src/input-validation/ColumnValueResolver.ts +2 -3
  186. package/src/input-validation/EntityRulesResolver.ts +4 -4
  187. package/src/input-validation/QueryAstFactory.ts +1 -1
  188. package/src/input-validation/ValidationDataSelector.ts +1 -1
  189. package/src/input-validation/preValidation/CreateInputPreValidationProcessor.ts +7 -8
  190. package/src/input-validation/preValidation/InputPreValidator.ts +4 -4
  191. package/src/input-validation/preValidation/UpdateInputPreValidationProcessor.ts +7 -8
  192. package/src/inputProcessing/CreateInputProcessor.ts +8 -9
  193. package/src/inputProcessing/CreateInputVisitor.ts +27 -89
  194. package/src/inputProcessing/UpdateInputProcessor.ts +8 -9
  195. package/src/inputProcessing/UpdateInputVisitor.ts +25 -71
  196. package/src/inputProcessing/index.ts +0 -1
  197. package/src/introspection/IntrospectionSchemaFactory.ts +7 -7
  198. package/src/mapper/Mapper.ts +36 -33
  199. package/src/mapper/MapperContainer.ts +3 -2
  200. package/src/mapper/delete/DeleteExecutor.ts +3 -3
  201. package/src/mapper/insert/SqlCreateInputProcessor.ts +3 -3
  202. package/src/mapper/select/JoinVisitor.ts +6 -33
  203. package/src/mapper/select/RelationFetcher.ts +49 -50
  204. package/src/mapper/select/SelectBuilder.ts +3 -1
  205. package/src/mapper/select/SelectBuilderFactory.ts +2 -1
  206. package/src/mapper/select/SelectExecutionHandler.ts +1 -0
  207. package/src/mapper/select/WhereBuilder.ts +45 -34
  208. package/src/mapper/select/handlers/FieldsVisitor.ts +32 -49
  209. package/src/mapper/select/handlers/FieldsVisitorFactory.ts +1 -0
  210. package/src/mapper/select/optimizer/ConditionOptimizer.ts +6 -0
  211. package/src/mapper/select/optimizer/WhereOptimizer.ts +58 -20
  212. package/src/mapper/select/optimizer/WhereReplacer.ts +8 -3
  213. package/src/mapper/update/SqlUpdateInputProcessor.ts +1 -1
  214. package/src/mapper/update/UpdateBuilder.ts +3 -3
  215. package/src/resolvers/MutationResolver.ts +1 -1
  216. package/src/resolvers/ReadHelpers.ts +3 -3
  217. package/src/resolvers/ReadResolver.ts +2 -2
  218. package/src/schema/FieldAccessVisitor.ts +2 -2
  219. package/src/schema/OrderByTypeProvider.ts +1 -1
  220. package/src/schema/WhereTypeProvider.ts +4 -4
  221. package/src/schema/entities/FieldArgsVisitor.ts +3 -3
  222. package/src/schema/entities/FieldTypeVisitor.ts +3 -3
  223. package/src/schema/mutations/CreateEntityInputFieldVisitor.ts +3 -6
  224. package/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.ts +6 -20
  225. package/src/schema/mutations/CreateEntityRelationInputFieldVisitor.ts +5 -18
  226. package/src/schema/mutations/UpdateEntityInputFieldVisitor.ts +3 -6
  227. package/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.ts +6 -20
  228. package/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.ts +2 -12
  229. package/src/utils/uniqueWhereFields.ts +3 -3
  230. package/tests/cases/unit/predicatesFactory.test.ts +8 -2
  231. package/tests/cases/unit/whereOptimizer.test.ts +94 -0
  232. package/dist/src/inputProcessing/InputContext.d.ts +0 -43
  233. package/dist/src/inputProcessing/InputContext.d.ts.map +0 -1
  234. package/dist/src/inputProcessing/InputContext.js +0 -3
  235. package/dist/src/inputProcessing/InputContext.js.map +0 -1
  236. package/src/inputProcessing/InputContext.ts +0 -49
@@ -13,9 +13,10 @@ 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
21
  this.executionContext.addColumn(qb => {
21
22
  const tableAlias = columnPath.back().alias
@@ -49,27 +50,20 @@ export class FieldsVisitor implements Model.RelationByTypeVisitor<void>, Model.C
49
50
  })
50
51
  }
51
52
 
52
- public visitManyHasManyInverse(
53
- entity: Model.Entity,
54
- relation: Model.ManyHasManyInverseRelation,
55
- targetEntity: Model.Entity,
56
- targetRelation: Model.ManyHasManyOwningRelation,
57
- ): void {
53
+ public visitManyHasManyInverse(relationContext: Model.ManyHasManyInverseContext): void {
58
54
  const field = this.executionContext.objectNode
59
55
  if (!field) {
60
56
  throw new Error()
61
57
  }
62
58
  this.executionContext.addData(
63
- entity.primary,
59
+ relationContext.entity.primary,
64
60
  async ids =>
65
61
  this.relationFetcher.fetchManyHasManyGroups(
66
62
  {
67
63
  mapper: this.mapper,
68
64
  field: field,
69
- targetEntity: targetEntity,
70
- sourceRelation: relation,
71
- targetRelation,
72
- directionFrom: 'inverse',
65
+ relationContext,
66
+ relationPath: this.relationPath,
73
67
  ids: ids,
74
68
  },
75
69
  ),
@@ -77,65 +71,48 @@ export class FieldsVisitor implements Model.RelationByTypeVisitor<void>, Model.C
77
71
  )
78
72
  }
79
73
 
80
- public visitManyHasManyOwning(
81
- entity: Model.Entity,
82
- relation: Model.ManyHasManyOwningRelation,
83
- targetEntity: Model.Entity,
84
- targetRelation: Model.ManyHasManyInverseRelation | null,
85
- ): void {
74
+ public visitManyHasManyOwning(relationContext: Model.ManyHasManyOwningContext): void {
86
75
  const field = this.executionContext.objectNode
87
76
  if (!field) {
88
77
  throw new Error()
89
78
  }
90
79
 
91
80
  this.executionContext.addData(
92
- entity.primary,
81
+ relationContext.entity.primary,
93
82
  async ids =>
94
83
  this.relationFetcher.fetchManyHasManyGroups({
95
84
  mapper: this.mapper,
96
85
  field: field,
97
- targetEntity: targetEntity,
98
- sourceRelation: relation,
99
- targetRelation,
100
- directionFrom: 'owning',
86
+ relationContext,
87
+ relationPath: this.relationPath,
101
88
  ids: ids,
102
89
  }),
103
90
  [],
104
91
  )
105
92
  }
106
93
 
107
- public visitOneHasMany(
108
- entity: Model.Entity,
109
- relation: Model.OneHasManyRelation,
110
- targetEntity: Model.Entity,
111
- targetRelation: Model.ManyHasOneRelation,
112
- ): void {
94
+ public visitOneHasMany(relationContext: Model.OneHasManyContext): void {
113
95
  const field = this.executionContext.objectNode
114
96
  if (!field) {
115
97
  throw new Error()
116
98
  }
117
99
 
118
100
  this.executionContext.addData(
119
- entity.primary,
101
+ relationContext.entity.primary,
120
102
  async ids =>
121
103
  this.relationFetcher.fetchOneHasManyGroups({
122
104
  mapper: this.mapper,
123
105
  objectNode: field,
124
- targetEntity: targetEntity,
125
- relation: relation,
126
- targetRelation: targetRelation,
106
+ relationContext,
107
+ relationPath: this.relationPath,
127
108
  ids: ids,
128
109
  }),
129
110
  [],
130
111
  )
131
112
  }
132
113
 
133
- public visitOneHasOneInverse(
134
- entity: Model.Entity,
135
- relation: Model.OneHasOneInverseRelation,
136
- targetEntity: Model.Entity,
137
- targetRelation: Model.OneHasOneOwningRelation,
138
- ): void {
114
+ public visitOneHasOneInverse(relationContext: Model.OneHasOneInverseContext): void {
115
+ const { entity, targetRelation, targetEntity } = relationContext
139
116
  this.executionContext.addData(
140
117
  entity.primary,
141
118
  async ids => {
@@ -155,18 +132,17 @@ export class FieldsVisitor implements Model.RelationByTypeVisitor<void>, Model.C
155
132
  }
156
133
  const objectWithWhere = field.withArg('filter', where)
157
134
 
158
- return this.mapper.select(targetEntity, objectWithWhere, targetRelation, targetRelation.name)
135
+ return this.mapper.selectAssoc(targetEntity, objectWithWhere, [
136
+ ...this.relationPath,
137
+ relationContext,
138
+ ], targetRelation.name)
159
139
  },
160
140
  null,
161
141
  )
162
142
  }
163
143
 
164
- public visitOneHasOneOwning(
165
- entity: Model.Entity,
166
- relation: Model.OneHasOneOwningRelation,
167
- targetEntity: Model.Entity,
168
- targetRelation: Model.OneHasOneInverseRelation | null,
169
- ): void {
144
+ public visitOneHasOneOwning(relationContext: Model.OneHasOneOwningContext): void {
145
+ const { relation, targetEntity } = relationContext
170
146
  this.executionContext.addData(
171
147
  relation.name,
172
148
  async ids => {
@@ -184,13 +160,17 @@ export class FieldsVisitor implements Model.RelationByTypeVisitor<void>, Model.C
184
160
  }
185
161
  const objectWithWhere = objectNode.withArg('filter', where)
186
162
 
187
- return this.mapper.select(targetEntity, objectWithWhere, targetRelation, targetEntity.primary)
163
+ return this.mapper.selectAssoc(targetEntity, objectWithWhere, [
164
+ ...this.relationPath,
165
+ relationContext,
166
+ ], targetEntity.primary)
188
167
  },
189
168
  null,
190
169
  )
191
170
  }
192
171
 
193
- public visitManyHasOne(entity: Model.Entity, relation: Model.ManyHasOneRelation, targetEntity: Model.Entity, targetRelation: Model.OneHasManyRelation | null): void {
172
+ public visitManyHasOne(relationContext: Model.ManyHasOneContext): void {
173
+ const { relation, targetEntity } = relationContext
194
174
  this.executionContext.addData(
195
175
  relation.name,
196
176
  async ids => {
@@ -208,7 +188,10 @@ export class FieldsVisitor implements Model.RelationByTypeVisitor<void>, Model.C
208
188
  }
209
189
  const objectWithWhere = objectNode.withArg('filter', where)
210
190
 
211
- return this.mapper.select(targetEntity, objectWithWhere, targetRelation, targetEntity.primary)
191
+ return this.mapper.selectAssoc(targetEntity, objectWithWhere, [
192
+ ...this.relationPath,
193
+ relationContext,
194
+ ], targetEntity.primary)
212
195
  },
213
196
  null,
214
197
  )
@@ -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
  }
@@ -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
 
@@ -4,15 +4,34 @@ import { acceptFieldVisitor } from '@contember/schema-utils'
4
4
  import { optimizeAnd, optimizeNot, optimizeOr } from './helpers'
5
5
  import { replaceWhere } from './WhereReplacer'
6
6
 
7
+ type ExtendedRelationContext =
8
+ & Model.AnyRelationContext
9
+ & {
10
+ canEliminate: boolean
11
+ isLast: boolean
12
+ }
13
+
7
14
  export class WhereOptimizer {
15
+ private static eliminableRelations = new Set<Model.AnyRelationContext['type']>(['oneHasMany', 'oneHasOneInverse', 'oneHasOneOwning'])
16
+
8
17
  constructor(
9
18
  private readonly model: Model.Schema,
10
19
  private readonly conditionOptimizer: ConditionOptimizer,
11
20
  ) {
12
21
  }
13
22
 
14
- public optimize(where: Input.OptionalWhere, entity: Model.Entity): Input.Where {
15
- const result = this.optimizeWhere(where, entity)
23
+ public optimize(where: Input.OptionalWhere, entity: Model.Entity, relationPath: Model.AnyRelationContext[] = []): Input.Where {
24
+ let processedRelationPath: ExtendedRelationContext[] = []
25
+ for (const i in relationPath) {
26
+ const el = relationPath[i]
27
+ if (!WhereOptimizer.eliminableRelations.has(el.type)) {
28
+ processedRelationPath = []
29
+ } else {
30
+ processedRelationPath.push({ ...el, canEliminate: true, isLast: Number(i) === relationPath.length })
31
+ }
32
+ processedRelationPath.push({ ...el, canEliminate: true, isLast: Number(i) === relationPath.length })
33
+ }
34
+ const result = this.optimizeWhere(where, entity, processedRelationPath)
16
35
 
17
36
  if (typeof result === 'boolean') {
18
37
  return { [entity.primary]: { [result ? 'always' : 'never']: true } }
@@ -21,61 +40,66 @@ export class WhereOptimizer {
21
40
  return result
22
41
  }
23
42
 
24
- private optimizeWhere(where: Input.OptionalWhere, entity: Model.Entity): Input.Where | boolean {
43
+ private optimizeWhere(where: Input.OptionalWhere, entity: Model.Entity, relationPath: ExtendedRelationContext[]): Input.Where | boolean {
25
44
  return this.optimizeAnd(
26
45
  Object.entries(where).map(([key, value]) => {
27
46
  if (value === undefined || value === null) {
28
47
  return undefined
29
48
 
30
49
  } else if (key === 'and') {
31
- return this.optimizeAnd((value as readonly Input.Where[]).map(it => this.optimizeWhere(it, entity)), entity)
50
+ return this.optimizeAnd((value as readonly Input.Where[]).map(it => this.optimizeWhere(it, entity, relationPath)), entity, relationPath)
32
51
 
33
52
  } else if (key === 'or') {
34
- return this.optimizeOr((value as readonly Input.Where[]).map(it => this.optimizeWhere(it, entity)), entity)
53
+ return this.optimizeOr((value as readonly Input.Where[]).map(it => this.optimizeWhere(it, entity, relationPath)), entity, relationPath)
35
54
 
36
55
  } else if (key === 'not') {
37
- return optimizeNot(this.optimizeWhere(value as Input.Where, entity))
56
+ return optimizeNot(this.optimizeWhere(value as Input.Where, entity, relationPath))
38
57
 
39
58
  } else {
40
- return this.resolveFieldValue(entity, key, value)
59
+ return this.resolveFieldValue(entity, key, value, relationPath)
41
60
  }
42
61
  }),
43
62
  entity,
63
+ relationPath,
44
64
  )
45
65
  }
46
66
 
47
- private optimizeOr(operands: readonly (Input.Where | undefined | boolean)[], entity: Model.Entity): Input.Where | boolean {
67
+ private optimizeOr(operands: readonly (Input.Where | undefined | boolean)[], entity: Model.Entity, relationPath: ExtendedRelationContext[]): Input.Where | boolean {
48
68
  const optimized = optimizeOr(operands)
49
69
  if (typeof optimized === 'boolean' || !Array.isArray(optimized.or)) {
50
70
  return optimized
51
71
  }
52
- const result = this.crossOptimize(optimized.or, entity, { never: true })
53
- return optimizeOr(result.map(it => this.optimizeWhere(it, entity)))
72
+ const result = this.crossOptimize(optimized.or, entity, { never: true }, relationPath)
73
+ return optimizeOr(result)
54
74
  }
55
75
 
56
- private optimizeAnd(operands: readonly (Input.Where | undefined | boolean)[], entity: Model.Entity): Input.Where | boolean {
76
+ private optimizeAnd(operands: readonly (Input.Where | undefined | boolean)[], entity: Model.Entity, relationPath: ExtendedRelationContext[]): Input.Where | boolean {
57
77
  const optimized = optimizeAnd(operands)
58
78
  if (typeof optimized === 'boolean' || !Array.isArray(optimized.and)) {
59
79
  return optimized
60
80
  }
61
- const result = this.crossOptimize(optimized.and, entity, { always: true })
62
- return optimizeAnd(result.map(it => this.optimizeWhere(it, entity)))
81
+ const result = this.crossOptimize(optimized.and, entity, { always: true }, relationPath)
82
+ return optimizeAnd(result)
63
83
  }
64
84
 
65
- private crossOptimize(operands: Input.Where[], entity: Model.Entity, replacement: Input.Condition): Input.Where[] {
66
- const result = [...operands]
85
+ private crossOptimize(operands: Input.Where[], entity: Model.Entity, replacement: Input.Condition, relationPath: ExtendedRelationContext[]): (Input.Where | boolean)[] {
86
+ const result: (Input.Where | boolean)[] = [...operands]
67
87
  const count = result.length
68
88
  for (let i = 0; i < count; i++) {
69
89
  for (let j = 0; j < count; j++) {
70
- if (i !== j) {
71
- result[j] = replaceWhere(result[j], result[i], { [entity.primary]: replacement })
90
+ const a = result[j]
91
+ const b = result[i]
92
+ if (i !== j && typeof a !== 'boolean' && typeof b !== 'boolean') {
93
+ const tracker = { count: 0 }
94
+ const elResult = replaceWhere(a, b, { [entity.primary]: replacement }, tracker)
95
+ result[j] = tracker.count > 0 ? this.optimizeWhere(elResult, entity, relationPath) : elResult
72
96
  }
73
97
  }
74
98
  }
75
99
  return result
76
100
  }
77
101
 
78
- private resolveFieldValue(entity: Model.Entity, key: string, value: Input.OptionalWhere[string]) {
102
+ private resolveFieldValue(entity: Model.Entity, key: string, value: Input.OptionalWhere[string], relationPath: ExtendedRelationContext[]) {
79
103
  return acceptFieldVisitor<Input.Where | boolean>(this.model, entity, key, {
80
104
  visitColumn: () => {
81
105
  const optimizedCondition = this.conditionOptimizer.optimize(value as Input.Condition)
@@ -86,8 +110,22 @@ export class WhereOptimizer {
86
110
 
87
111
  return { [key]: optimizedCondition }
88
112
  },
89
- visitRelation: (entity, relation, targetEntity) => {
90
- const optimizedWhere = this.optimizeWhere(value as Input.Where, targetEntity)
113
+ visitRelation: context => {
114
+ const { targetEntity, relation } = context
115
+ let where = value as Input.Where
116
+ const newRelationPath: ExtendedRelationContext[] = [...relationPath]
117
+ if (relationPath.length && relationPath[relationPath.length - 1].targetRelation?.name === relation.name) {
118
+ const item = newRelationPath.pop()
119
+ if (item?.canEliminate && (item.type === 'oneHasMany' || item.type === 'oneHasOneOwning' || item.type === 'oneHasOneInverse')) {
120
+ where = replaceWhere(where, { [targetEntity.primary]: { isNull: true } }, { [targetEntity.primary]: { never: true } })
121
+ where = replaceWhere(where, { [targetEntity.primary]: { isNull: false } }, { [targetEntity.primary]: { always: true } })
122
+ }
123
+ } else {
124
+ // first level relation - we are sure root exists
125
+ const canEliminate = relationPath.length === 0 || relationPath[relationPath.length - 1].isLast
126
+ newRelationPath.push({ ...context, isLast: false, canEliminate })
127
+ }
128
+ const optimizedWhere = this.optimizeWhere(where, targetEntity, newRelationPath)
91
129
 
92
130
  if (typeof optimizedWhere === 'boolean') {
93
131
  return optimizedWhere
@@ -1,17 +1,22 @@
1
1
  import { Input, Writable } from '@contember/schema'
2
2
  import deepEqual from 'fast-deep-equal'
3
3
 
4
- export const replaceWhere = (subject: Input.Where, find: Input.Where, replace: Input.Where): Input.Where => {
4
+ export interface ReplaceWhereResult {
5
+ count: number
6
+ }
7
+
8
+ export const replaceWhere = (subject: Input.Where, find: Input.Where, replace: Input.Where, resultTracker: ReplaceWhereResult = { count: 0 }): Input.Where => {
5
9
  if (deepEqual(subject, find)) {
10
+ resultTracker.count++
6
11
  return replace
7
12
  }
8
13
  const result: Writable<Input.Where> = {}
9
14
  for (const [key, value] of Object.entries(subject)) {
10
15
  if (key === 'not') {
11
- result['not'] = replaceWhere(value as Input.Where, find, replace)
16
+ result['not'] = replaceWhere(value as Input.Where, find, replace, resultTracker)
12
17
 
13
18
  } else if (key === 'and' || key === 'or') {
14
- result[key] = (value as Input.Where[]).map(it => replaceWhere(it, find, replace))
19
+ result[key] = (value as Input.Where[]).map(it => replaceWhere(it, find, replace, resultTracker))
15
20
 
16
21
  } else {
17
22
  result[key] = value
@@ -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
  }
@@ -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,
@@ -457,7 +457,7 @@ export class MutationResolver {
457
457
  throw new Error('MutationResolver: expected ObjectNode')
458
458
  }
459
459
  const objectWithArgs = singleNodeQuery.withArgs({ by: where })
460
- nodes[singleNodeQuery.alias] = await mapper.selectUnique(entity, objectWithArgs, null)
460
+ nodes[singleNodeQuery.alias] = await mapper.selectUnique(entity, objectWithArgs, [])
461
461
  }
462
462
  return nodes
463
463
  }
@@ -15,7 +15,7 @@ export const paginate = async (
15
15
  const totalCount = paginationHelper.requiresTotalCount
16
16
  ? await mapper.count(entity, queryAst.args.filter || {})
17
17
  : undefined
18
- const nodes = paginationHelper.nodeField ? await mapper.select(entity, paginationHelper.nodeField, null) : undefined
18
+ const nodes = paginationHelper.nodeField ? await mapper.select(entity, paginationHelper.nodeField, []) : undefined
19
19
 
20
20
  return paginationHelper.createResponse(totalCount, nodes)
21
21
  }
@@ -37,9 +37,9 @@ export const executeReadOperations = async (
37
37
  trxResult[field.alias] = await (() => {
38
38
  switch (meta.operation) {
39
39
  case Operation.get:
40
- return mapper.selectUnique(meta.entity, field, null)
40
+ return mapper.selectUnique(meta.entity, field, [])
41
41
  case Operation.list:
42
- return mapper.select(meta.entity, field, null)
42
+ return mapper.select(meta.entity, field, [])
43
43
  case Operation.paginate:
44
44
  return paginate(mapper, meta.entity, field)
45
45
  case Operation.create:
@@ -33,12 +33,12 @@ export class ReadResolver {
33
33
 
34
34
  public async resolveListQuery(entity: Model.Entity, info: GraphQLResolveInfo) {
35
35
  const queryAst: ObjectNode<Input.ListQueryInput> = this.queryAstFactory.create(info)
36
- return await this.mapperFactory(this.db).select(entity, queryAst, null)
36
+ return await this.mapperFactory(this.db).select(entity, queryAst, [])
37
37
  }
38
38
 
39
39
  public async resolveGetQuery(entity: Model.Entity, info: GraphQLResolveInfo) {
40
40
  const queryAst: ObjectNode<Input.UniqueQueryInput> = this.queryAstFactory.create(info)
41
- return await this.mapperFactory(this.db).selectUnique(entity, queryAst, null)
41
+ return await this.mapperFactory(this.db).selectUnique(entity, queryAst, [])
42
42
  }
43
43
 
44
44
  public async resolvePaginationQuery(entity: Model.Entity, info: GraphQLResolveInfo) {
@@ -7,11 +7,11 @@ export class FieldAccessVisitor implements Model.ColumnVisitor<boolean>, Model.R
7
7
  private readonly authorizator: Authorizator,
8
8
  ) {}
9
9
 
10
- visitColumn(entity: Model.Entity, column: Model.AnyColumn) {
10
+ visitColumn({ column, entity }: Model.ColumnContext) {
11
11
  return this.authorizator.getFieldPermissions(this.operation, entity.name, column.name) !== 'no'
12
12
  }
13
13
 
14
- visitRelation({}, {}, targetEntity: Model.Entity) {
14
+ visitRelation({ targetEntity }: Model.AnyRelationContext) {
15
15
  return this.authorizator.getEntityPermission(this.operation, targetEntity.name) !== 'no'
16
16
  }
17
17
  }
@@ -51,7 +51,7 @@ export class OrderByTypeProvider {
51
51
 
52
52
  const field = acceptFieldVisitor(this.schema, name, fieldName, {
53
53
  visitColumn: () => ({ type: this.orderDirectionEnum }),
54
- visitHasOne: (entity, relation) => ({ type: this.getEntityOrderByType(relation.target) }),
54
+ visitHasOne: ({ relation }) => ({ type: this.getEntityOrderByType(relation.target) }),
55
55
  visitHasMany: () => undefined,
56
56
  } as Model.FieldVisitor<GraphQLInputFieldConfig | undefined>)
57
57
 
@@ -74,7 +74,7 @@ export class WhereTypeProvider {
74
74
  continue
75
75
  }
76
76
  fields[field] = acceptFieldVisitor<GraphQLInputFieldConfig>(this.schema, entity, field, {
77
- visitRelation: (entity, relation, targetEntity) => {
77
+ visitRelation: ({ targetEntity }) => {
78
78
  // if (!isIt<Model.JoiningColumnRelation>(relation, 'joiningColumn')) {
79
79
  // throw new Error('Only column or owning relation can be a part of unique key')
80
80
  // }
@@ -84,7 +84,7 @@ export class WhereTypeProvider {
84
84
  }
85
85
  return { type: uniqueWhere }
86
86
  },
87
- visitColumn: (entity, column) => ({ type: this.columnTypeResolver.getType(column) }),
87
+ visitColumn: ({ column }) => ({ type: this.columnTypeResolver.getType(column) }),
88
88
  })
89
89
  }
90
90
  }
@@ -104,8 +104,8 @@ export class WhereTypeProvider {
104
104
  continue
105
105
  }
106
106
  fields[fieldName] = acceptFieldVisitor(this.schema, name, fieldName, {
107
- visitColumn: (entity, column) => ({ type: this.conditionTypeProvider.getCondition(column) }),
108
- visitRelation: (entity, relation) => ({ type: this.getEntityWhereType(relation.target) }),
107
+ visitColumn: ({ column }) => ({ type: this.conditionTypeProvider.getCondition(column) }),
108
+ visitRelation: ({ relation }) => ({ type: this.getEntityWhereType(relation.target) }),
109
109
  } as Model.FieldVisitor<GraphQLInputFieldConfig>)
110
110
  }
111
111
 
@@ -15,11 +15,11 @@ export class FieldArgsVisitor implements
15
15
  this.whereTypeProvider = whereTypeProvider
16
16
  }
17
17
 
18
- public visitColumn(entity: Model.Entity, column: Model.AnyColumn) {
18
+ public visitColumn() {
19
19
  return undefined
20
20
  }
21
21
 
22
- public visitHasMany(entity: Model.Entity, relation: Model.Relation) {
22
+ public visitHasMany({ relation }: Model.AnyHasManyRelationContext) {
23
23
  const filter = this.getWhereArg(relation)
24
24
  const orderBy = this.getOrderByArgs(relation)
25
25
  return {
@@ -30,7 +30,7 @@ export class FieldArgsVisitor implements
30
30
  }
31
31
  }
32
32
 
33
- public visitHasOne(entity: Model.Entity, relation: Model.Relation) {
33
+ public visitHasOne({ relation }: Model.ManyHasOneContext) {
34
34
  const filter = this.getWhereArg(relation)
35
35
  return { filter }
36
36
  }
@@ -13,7 +13,7 @@ export class FieldTypeVisitor implements Model.ColumnVisitor<GraphQLOutputType>,
13
13
  ) {
14
14
  }
15
15
 
16
- public visitColumn(entity: Model.Entity, column: Model.AnyColumn): GraphQLOutputType {
16
+ public visitColumn({ column, entity }: Model.ColumnContext): GraphQLOutputType {
17
17
  const basicType = this.columnTypeResolver.getType(column)
18
18
  const fieldPredicate = this.authorizator.getFieldPredicate(Acl.Operation.read, entity.name, column.name)
19
19
  const idPredicate = this.authorizator.getFieldPredicate(Acl.Operation.read, entity.name, entity.primary)
@@ -26,12 +26,12 @@ export class FieldTypeVisitor implements Model.ColumnVisitor<GraphQLOutputType>,
26
26
  return basicType
27
27
  }
28
28
 
29
- public visitHasMany(entity: Model.Entity, relation: Model.Relation): GraphQLOutputType {
29
+ public visitHasMany({ relation }: Model.AnyHasManyRelationContext): GraphQLOutputType {
30
30
  const entityType = this.entityTypeProvider.getEntity(relation.target)
31
31
  return new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(entityType)))
32
32
  }
33
33
 
34
- public visitHasOne(entity: Model.Entity, relation: Model.Relation & Model.NullableRelation): GraphQLOutputType {
34
+ public visitHasOne({ relation }: Model.AnyHasOneRelationContext): GraphQLOutputType {
35
35
  return this.entityTypeProvider.getEntity(relation.target)
36
36
  }
37
37
  }
@@ -15,7 +15,7 @@ export class CreateEntityInputFieldVisitor implements
15
15
  private readonly createEntityRelationInputProvider: CreateEntityRelationInputProvider,
16
16
  ) {}
17
17
 
18
- public visitColumn(entity: Model.Entity, column: Model.AnyColumn): GraphQLInputFieldConfig | undefined {
18
+ public visitColumn({ entity, column }: Model.ColumnContext): GraphQLInputFieldConfig | undefined {
19
19
  if (entity.primary === column.name && !this.authorizator.isCustomPrimaryAllowed(entity.name)) {
20
20
  return undefined
21
21
  }
@@ -28,10 +28,7 @@ export class CreateEntityInputFieldVisitor implements
28
28
  }
29
29
  }
30
30
 
31
- public visitHasOne(
32
- entity: Model.Entity,
33
- relation: Model.Relation & Model.NullableRelation,
34
- ): GraphQLInputFieldConfig | undefined {
31
+ public visitHasOne({ entity, relation }: Model.AnyHasOneRelationContext): GraphQLInputFieldConfig | undefined {
35
32
  const type = this.createEntityRelationInputProvider.getCreateEntityRelationInput(entity.name, relation.name)
36
33
  if (type === undefined) {
37
34
  return undefined
@@ -41,7 +38,7 @@ export class CreateEntityInputFieldVisitor implements
41
38
  }
42
39
  }
43
40
 
44
- public visitHasMany(entity: Model.Entity, relation: Model.Relation): GraphQLInputFieldConfig | undefined {
41
+ public visitHasMany({ entity, relation }: Model.AnyHasManyRelationContext): GraphQLInputFieldConfig | undefined {
45
42
  const type = this.createEntityRelationInputProvider.getCreateEntityRelationInput(entity.name, relation.name)
46
43
  if (type === undefined) {
47
44
  return undefined
@@ -12,32 +12,23 @@ export class CreateEntityRelationAllowedOperationsVisitor implements
12
12
  throw new ImplementationException('CreateEntityRelationAllowedOperationsVisitor: Not applicable for a column')
13
13
  }
14
14
 
15
- public visitManyHasManyInverse({}, {}, targetEntity: Model.Entity, targetRelation: Model.ManyHasManyOwningRelation) {
15
+ public visitManyHasManyInverse({ targetEntity, targetRelation }: Model.ManyHasManyInverseContext) {
16
16
  return this.getAllowedOperations(targetEntity, targetEntity, targetRelation)
17
17
  }
18
18
 
19
- public visitManyHasManyOwning(
20
- entity: Model.Entity,
21
- relation: Model.ManyHasManyOwningRelation,
22
- targetEntity: Model.Entity,
23
- ) {
19
+ public visitManyHasManyOwning({ entity, targetEntity, relation }: Model.ManyHasManyOwningContext) {
24
20
  return this.getAllowedOperations(targetEntity, entity, relation)
25
21
  }
26
22
 
27
- public visitOneHasMany({}, {}, targetEntity: Model.Entity, targetRelation: Model.ManyHasOneRelation) {
23
+ public visitOneHasMany({ targetEntity, targetRelation }: Model.OneHasManyContext) {
28
24
  return this.getAllowedOperations(targetEntity, targetEntity, targetRelation)
29
25
  }
30
26
 
31
- public visitManyHasOne(entity: Model.Entity, relation: Model.ManyHasOneRelation, targetEntity: Model.Entity) {
27
+ public visitManyHasOne({ targetEntity, entity, relation }: Model.ManyHasOneContext) {
32
28
  return this.getAllowedOperations(targetEntity, entity, relation)
33
29
  }
34
30
 
35
- public visitOneHasOneInverse(
36
- {},
37
- relation: Model.OneHasOneInverseRelation,
38
- targetEntity: Model.Entity,
39
- targetRelation: Model.OneHasOneOwningRelation,
40
- ) {
31
+ public visitOneHasOneInverse({ targetEntity, targetRelation, relation }: Model.OneHasOneInverseContext) {
41
32
  const operations = this.getAllowedOperations(targetEntity, targetEntity, targetRelation)
42
33
  if (relation.nullable || targetRelation.nullable) {
43
34
  return operations
@@ -45,12 +36,7 @@ export class CreateEntityRelationAllowedOperationsVisitor implements
45
36
  return operations.filter(it => it === Input.CreateRelationOperation.create)
46
37
  }
47
38
 
48
- public visitOneHasOneOwning(
49
- entity: Model.Entity,
50
- relation: Model.OneHasOneOwningRelation,
51
- targetEntity: Model.Entity,
52
- targetRelation: Model.OneHasOneInverseRelation | null,
53
- ) {
39
+ public visitOneHasOneOwning({ targetEntity, entity, relation, targetRelation }: Model.OneHasOneOwningContext) {
54
40
  const operations = this.getAllowedOperations(targetEntity, entity, relation)
55
41
  if (!targetRelation || targetRelation.nullable || relation.nullable) {
56
42
  return operations