@contember/engine-content-api 1.1.1 → 1.2.0-alpha.10

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 (198) 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 +24 -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 +18 -14
  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.js +1 -1
  25. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.js.map +1 -1
  26. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.d.ts.map +1 -1
  27. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js +25 -13
  28. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js.map +1 -1
  29. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.d.ts.map +1 -1
  30. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js +26 -13
  31. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js.map +1 -1
  32. package/dist/src/input-validation/ValidationContext.d.ts +2 -2
  33. package/dist/src/input-validation/ValidationContext.d.ts.map +1 -1
  34. package/dist/src/input-validation/ValidationContext.js.map +1 -1
  35. package/dist/src/input-validation/ValidationDataSelector.d.ts.map +1 -1
  36. package/dist/src/input-validation/ValidationDataSelector.js +1 -1
  37. package/dist/src/input-validation/ValidationDataSelector.js.map +1 -1
  38. package/dist/src/introspection/content-schema.types.d.ts +19 -223
  39. package/dist/src/introspection/content-schema.types.d.ts.map +1 -1
  40. package/dist/src/introspection/content-schema.types.js +2 -2
  41. package/dist/src/introspection/content-schema.types.js.map +1 -1
  42. package/dist/src/mapper/Mapper.d.ts +4 -4
  43. package/dist/src/mapper/Mapper.d.ts.map +1 -1
  44. package/dist/src/mapper/Mapper.js +7 -7
  45. package/dist/src/mapper/Mapper.js.map +1 -1
  46. package/dist/src/mapper/MapperContainer.d.ts.map +1 -1
  47. package/dist/src/mapper/MapperContainer.js +5 -2
  48. package/dist/src/mapper/MapperContainer.js.map +1 -1
  49. package/dist/src/mapper/select/RelationFetcher.d.ts +40 -5
  50. package/dist/src/mapper/select/RelationFetcher.d.ts.map +1 -1
  51. package/dist/src/mapper/select/RelationFetcher.js +19 -6
  52. package/dist/src/mapper/select/RelationFetcher.js.map +1 -1
  53. package/dist/src/mapper/select/WhereBuilder.d.ts +3 -1
  54. package/dist/src/mapper/select/WhereBuilder.d.ts.map +1 -1
  55. package/dist/src/mapper/select/WhereBuilder.js +4 -2
  56. package/dist/src/mapper/select/WhereBuilder.js.map +1 -1
  57. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts +2 -2
  58. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts.map +1 -1
  59. package/dist/src/mapper/select/handlers/FieldsVisitor.js +31 -18
  60. package/dist/src/mapper/select/handlers/FieldsVisitor.js.map +1 -1
  61. package/dist/src/mapper/select/optimizer/ConditionOptimizer.d.ts +5 -0
  62. package/dist/src/mapper/select/optimizer/ConditionOptimizer.d.ts.map +1 -0
  63. package/dist/src/mapper/select/optimizer/ConditionOptimizer.js +33 -0
  64. package/dist/src/mapper/select/optimizer/ConditionOptimizer.js.map +1 -0
  65. package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts +14 -0
  66. package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts.map +1 -0
  67. package/dist/src/mapper/select/optimizer/WhereOptimizer.js +86 -0
  68. package/dist/src/mapper/select/optimizer/WhereOptimizer.js.map +1 -0
  69. package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts +3 -0
  70. package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts.map +1 -0
  71. package/dist/src/mapper/select/optimizer/WhereReplacer.js +27 -0
  72. package/dist/src/mapper/select/optimizer/WhereReplacer.js.map +1 -0
  73. package/dist/src/mapper/select/optimizer/helpers.d.ts +10 -0
  74. package/dist/src/mapper/select/optimizer/helpers.d.ts.map +1 -0
  75. package/dist/src/mapper/select/optimizer/helpers.js +72 -0
  76. package/dist/src/mapper/select/optimizer/helpers.js.map +1 -0
  77. package/dist/src/resolvers/GraphQlQueryAstFactory.js +2 -2
  78. package/dist/src/resolvers/GraphQlQueryAstFactory.js.map +1 -1
  79. package/dist/src/resolvers/MutationResolver.js +15 -15
  80. package/dist/src/resolvers/MutationResolver.js.map +1 -1
  81. package/dist/src/resolvers/ReadHelpers.js +10 -10
  82. package/dist/src/resolvers/ReadHelpers.js.map +1 -1
  83. package/dist/src/resolvers/ReadResolver.js +2 -2
  84. package/dist/src/resolvers/ReadResolver.js.map +1 -1
  85. package/dist/src/schema/MutationProvider.js +4 -4
  86. package/dist/src/schema/MutationProvider.js.map +1 -1
  87. package/dist/src/schema/QueryProvider.js +3 -3
  88. package/dist/src/schema/QueryProvider.js.map +1 -1
  89. package/dist/src/schema/ResultSchemaTypeProvider.d.ts +2 -2
  90. package/dist/src/schema/ResultSchemaTypeProvider.d.ts.map +1 -1
  91. package/dist/src/schema/entities/FieldArgsVisitor.d.ts +4 -4
  92. package/dist/src/schema/entities/FieldArgsVisitor.d.ts.map +1 -1
  93. package/dist/src/tsconfig.tsbuildinfo +1 -1
  94. package/dist/src/utils/object.d.ts.map +1 -1
  95. package/dist/src/utils/object.js +3 -4
  96. package/dist/src/utils/object.js.map +1 -1
  97. package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js +1 -1
  98. package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js.map +1 -1
  99. package/dist/tests/cases/integration/graphQlRequests/insert/acl/setField.test.js +2 -2
  100. package/dist/tests/cases/integration/graphQlRequests/insert/acl/setField.test.js.map +1 -1
  101. package/dist/tests/cases/integration/graphQlRequests/insert/aclInsert.test.js +1 -1
  102. package/dist/tests/cases/integration/graphQlRequests/insert/aclInsert.test.js.map +1 -1
  103. package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js +7 -6
  104. package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js.map +1 -1
  105. package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js +1 -1
  106. package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js.map +1 -1
  107. package/dist/tests/cases/integration/graphQlRequests/query/acl/predicateElimination.test.d.ts +2 -0
  108. package/dist/tests/cases/integration/graphQlRequests/query/acl/predicateElimination.test.d.ts.map +1 -0
  109. package/dist/tests/cases/integration/graphQlRequests/query/acl/predicateElimination.test.js +137 -0
  110. package/dist/tests/cases/integration/graphQlRequests/query/acl/predicateElimination.test.js.map +1 -0
  111. package/dist/tests/cases/integration/graphQlRequests/query/filter/complexCondition.test.js +1 -1
  112. package/dist/tests/cases/integration/graphQlRequests/query/filter/composedFilter.test.js +1 -1
  113. package/dist/tests/cases/integration/graphQlRequests/query/filter/composedFilter.test.js.map +1 -1
  114. package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyInverse.test.js +73 -0
  115. package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyInverse.test.js.map +1 -1
  116. package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.js +73 -0
  117. package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.js.map +1 -1
  118. package/dist/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.js +6 -6
  119. package/dist/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.js.map +1 -1
  120. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js +6 -3
  121. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js.map +1 -1
  122. package/dist/tests/cases/integration/graphQlSchema/model.js.map +1 -1
  123. package/dist/tests/cases/unit/aclVariablesFactory.test.js +7 -33
  124. package/dist/tests/cases/unit/aclVariablesFactory.test.js.map +1 -1
  125. package/dist/tests/cases/unit/conditionOptimizer.test.d.ts +2 -0
  126. package/dist/tests/cases/unit/conditionOptimizer.test.d.ts.map +1 -0
  127. package/dist/tests/cases/unit/conditionOptimizer.test.js +118 -0
  128. package/dist/tests/cases/unit/conditionOptimizer.test.js.map +1 -0
  129. package/dist/tests/cases/unit/orderbyHelper.test.js +1 -0
  130. package/dist/tests/cases/unit/orderbyHelper.test.js.map +1 -1
  131. package/dist/tests/cases/unit/permissionMerger.test.js +2 -0
  132. package/dist/tests/cases/unit/permissionMerger.test.js.map +1 -1
  133. package/dist/tests/cases/unit/predicatesFactory.test.d.ts +2 -0
  134. package/dist/tests/cases/unit/predicatesFactory.test.d.ts.map +1 -0
  135. package/dist/tests/cases/unit/predicatesFactory.test.js +103 -0
  136. package/dist/tests/cases/unit/predicatesFactory.test.js.map +1 -0
  137. package/dist/tests/cases/unit/predicatesInjector.test.js +88 -14
  138. package/dist/tests/cases/unit/predicatesInjector.test.js.map +1 -1
  139. package/dist/tests/cases/unit/variableInjector.test.js +4 -3
  140. package/dist/tests/cases/unit/variableInjector.test.js.map +1 -1
  141. package/dist/tests/cases/unit/whereOptimizer.test.d.ts +2 -0
  142. package/dist/tests/cases/unit/whereOptimizer.test.d.ts.map +1 -0
  143. package/dist/tests/cases/unit/whereOptimizer.test.js +183 -0
  144. package/dist/tests/cases/unit/whereOptimizer.test.js.map +1 -0
  145. package/dist/tests/src/testGraphql.d.ts.map +1 -1
  146. package/dist/tests/src/testGraphql.js +10 -2
  147. package/dist/tests/src/testGraphql.js.map +1 -1
  148. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  149. package/graphql.codegen.yml +0 -3
  150. package/package.json +16 -16
  151. package/src/acl/EvaluatedPredicateReplacer.ts +32 -0
  152. package/src/acl/PermissionFactory.ts +18 -13
  153. package/src/acl/PredicateFactory.ts +39 -8
  154. package/src/acl/PredicatesInjector.ts +26 -13
  155. package/src/acl/VariableInjector.ts +2 -15
  156. package/src/acl/VariableUtils.ts +7 -23
  157. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.ts +3 -3
  158. package/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.ts +26 -28
  159. package/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.ts +27 -31
  160. package/src/input-validation/ValidationContext.ts +2 -2
  161. package/src/input-validation/ValidationDataSelector.ts +2 -2
  162. package/src/introspection/content-schema.types.ts +19 -286
  163. package/src/mapper/Mapper.ts +10 -6
  164. package/src/mapper/MapperContainer.ts +7 -3
  165. package/src/mapper/select/RelationFetcher.ts +95 -34
  166. package/src/mapper/select/WhereBuilder.ts +5 -2
  167. package/src/mapper/select/handlers/FieldsVisitor.ts +31 -24
  168. package/src/mapper/select/optimizer/ConditionOptimizer.ts +35 -0
  169. package/src/mapper/select/optimizer/WhereOptimizer.ts +100 -0
  170. package/src/mapper/select/optimizer/WhereReplacer.ts +22 -0
  171. package/src/mapper/select/optimizer/helpers.ts +58 -0
  172. package/src/resolvers/GraphQlQueryAstFactory.ts +3 -3
  173. package/src/resolvers/MutationResolver.ts +1 -1
  174. package/src/resolvers/ReadHelpers.ts +3 -3
  175. package/src/resolvers/ReadResolver.ts +2 -2
  176. package/src/utils/object.ts +6 -6
  177. package/tests/cases/integration/graphQlRequests/delete/aclDelete.test.ts +2 -2
  178. package/tests/cases/integration/graphQlRequests/insert/acl/setField.test.ts +3 -3
  179. package/tests/cases/integration/graphQlRequests/insert/aclInsert.test.ts +2 -2
  180. package/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.ts +7 -6
  181. package/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.ts +1 -1
  182. package/tests/cases/integration/graphQlRequests/query/acl/predicateElimination.test.ts +130 -0
  183. package/tests/cases/integration/graphQlRequests/query/filter/complexCondition.test.ts +1 -1
  184. package/tests/cases/integration/graphQlRequests/query/filter/composedFilter.test.ts +1 -1
  185. package/tests/cases/integration/graphQlRequests/query/relations/manyHasManyInverse.test.ts +74 -0
  186. package/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.ts +77 -0
  187. package/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.ts +7 -7
  188. package/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.ts +5 -5
  189. package/tests/cases/unit/aclVariablesFactory.test.ts +8 -35
  190. package/tests/cases/unit/conditionOptimizer.test.ts +135 -0
  191. package/tests/cases/unit/orderbyHelper.test.ts +1 -0
  192. package/tests/cases/unit/permissionMerger.test.ts +2 -0
  193. package/tests/cases/unit/predicatesFactory.test.ts +97 -0
  194. package/tests/cases/unit/predicatesInjector.test.ts +78 -16
  195. package/tests/cases/unit/variableInjector.test.ts +6 -5
  196. package/tests/cases/unit/whereOptimizer.test.ts +195 -0
  197. package/tests/src/testGraphql.ts +9 -2
  198. package/jasmine.json +0 -7
@@ -1,9 +1,8 @@
1
- import { GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig } from 'graphql'
2
1
  export type Maybe<T> = T | null
2
+ export type InputMaybe<T> = Maybe<T>
3
3
  export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] }
4
4
  export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> }
5
5
  export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> }
6
- export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
7
6
  /** All built-in and custom scalars, mapped to their actual values */
8
7
  export type Scalars = {
9
8
  ID: string
@@ -14,30 +13,29 @@ export type Scalars = {
14
13
  Json: any
15
14
  }
16
15
 
17
-
18
16
  export type Query = {
19
17
  readonly __typename?: 'Query'
20
18
  readonly schema?: Maybe<_Schema>
21
19
  }
22
20
 
23
- export type _Argument = _ValidatorArgument | _PathArgument | _LiteralArgument
21
+ export type _Argument = _LiteralArgument | _PathArgument | _ValidatorArgument
24
22
 
25
23
  export type _Column = _Field & {
26
24
  readonly __typename?: '_Column'
27
- readonly name: Scalars['String']
28
- readonly type: Scalars['String']
29
- readonly enumName?: Maybe<Scalars['String']>
30
25
  readonly defaultValue?: Maybe<Scalars['Json']>
26
+ readonly enumName?: Maybe<Scalars['String']>
27
+ readonly name: Scalars['String']
31
28
  readonly nullable: Scalars['Boolean']
32
29
  readonly rules: ReadonlyArray<_Rule>
30
+ readonly type: Scalars['String']
33
31
  readonly validators: ReadonlyArray<_Validator>
34
32
  }
35
33
 
36
34
  export type _Entity = {
37
35
  readonly __typename?: '_Entity'
38
- readonly name: Scalars['String']
39
36
  readonly customPrimaryAllowed: Scalars['Boolean']
40
37
  readonly fields: ReadonlyArray<_Field>
38
+ readonly name: Scalars['String']
41
39
  readonly unique: ReadonlyArray<_UniqueConstraint>
42
40
  }
43
41
 
@@ -49,9 +47,9 @@ export type _Enum = {
49
47
 
50
48
  export type _Field = {
51
49
  readonly name: Scalars['String']
52
- readonly type: Scalars['String']
53
50
  readonly nullable?: Maybe<Scalars['Boolean']>
54
51
  readonly rules: ReadonlyArray<_Rule>
52
+ readonly type: Scalars['String']
55
53
  readonly validators: ReadonlyArray<_Validator>
56
54
  }
57
55
 
@@ -61,15 +59,15 @@ export type _LiteralArgument = {
61
59
  }
62
60
 
63
61
  export enum _OnDeleteBehaviour {
64
- Restrict = 'restrict',
65
62
  Cascade = 'cascade',
63
+ Restrict = 'restrict',
66
64
  SetNull = 'setNull'
67
65
  }
68
66
 
69
67
  export type _OrderBy = {
70
68
  readonly __typename?: '_OrderBy'
71
- readonly path: ReadonlyArray<Scalars['String']>
72
69
  readonly direction: _OrderByDirection
70
+ readonly path: ReadonlyArray<Scalars['String']>
73
71
  }
74
72
 
75
73
  export enum _OrderByDirection {
@@ -84,23 +82,23 @@ export type _PathArgument = {
84
82
 
85
83
  export type _Relation = _Field & {
86
84
  readonly __typename?: '_Relation'
87
- readonly name: Scalars['String']
88
- readonly type: Scalars['String']
89
- readonly side: _RelationSide
90
- readonly targetEntity: Scalars['String']
91
- readonly ownedBy?: Maybe<Scalars['String']>
92
85
  readonly inversedBy?: Maybe<Scalars['String']>
86
+ readonly name: Scalars['String']
93
87
  readonly nullable?: Maybe<Scalars['Boolean']>
94
88
  readonly onDelete?: Maybe<_OnDeleteBehaviour>
95
- readonly orphanRemoval?: Maybe<Scalars['Boolean']>
96
89
  readonly orderBy?: Maybe<ReadonlyArray<_OrderBy>>
90
+ readonly orphanRemoval?: Maybe<Scalars['Boolean']>
91
+ readonly ownedBy?: Maybe<Scalars['String']>
97
92
  readonly rules: ReadonlyArray<_Rule>
93
+ readonly side: _RelationSide
94
+ readonly targetEntity: Scalars['String']
95
+ readonly type: Scalars['String']
98
96
  readonly validators: ReadonlyArray<_Validator>
99
97
  }
100
98
 
101
99
  export enum _RelationSide {
102
- Owning = 'owning',
103
- Inverse = 'inverse'
100
+ Inverse = 'inverse',
101
+ Owning = 'owning'
104
102
  }
105
103
 
106
104
  export type _Rule = {
@@ -116,8 +114,8 @@ export type _RuleMessage = {
116
114
 
117
115
  export type _Schema = {
118
116
  readonly __typename?: '_Schema'
119
- readonly enums: ReadonlyArray<_Enum>
120
117
  readonly entities: ReadonlyArray<_Entity>
118
+ readonly enums: ReadonlyArray<_Enum>
121
119
  }
122
120
 
123
121
  export type _UniqueConstraint = {
@@ -127,276 +125,11 @@ export type _UniqueConstraint = {
127
125
 
128
126
  export type _Validator = {
129
127
  readonly __typename?: '_Validator'
130
- readonly operation: Scalars['String']
131
128
  readonly arguments: ReadonlyArray<_Argument>
129
+ readonly operation: Scalars['String']
132
130
  }
133
131
 
134
132
  export type _ValidatorArgument = {
135
133
  readonly __typename?: '_ValidatorArgument'
136
134
  readonly validator: Scalars['Int']
137
135
  }
138
-
139
-
140
-
141
- export type ResolverTypeWrapper<T> = Promise<T> | T
142
-
143
-
144
- export type LegacyStitchingResolver<TResult, TParent, TContext, TArgs> = {
145
- fragment: string
146
- resolve: ResolverFn<TResult, TParent, TContext, TArgs>
147
- }
148
-
149
- export type NewStitchingResolver<TResult, TParent, TContext, TArgs> = {
150
- selectionSet: string
151
- resolve: ResolverFn<TResult, TParent, TContext, TArgs>
152
- }
153
- export type StitchingResolver<TResult, TParent, TContext, TArgs> = LegacyStitchingResolver<TResult, TParent, TContext, TArgs> | NewStitchingResolver<TResult, TParent, TContext, TArgs>
154
- export type Resolver<TResult, TParent = {}, TContext = {}, TArgs = {}> =
155
- | ResolverFn<TResult, TParent, TContext, TArgs>
156
- | StitchingResolver<TResult, TParent, TContext, TArgs>
157
-
158
- export type ResolverFn<TResult, TParent, TContext, TArgs> = (
159
- parent: TParent,
160
- args: TArgs,
161
- context: TContext,
162
- info: GraphQLResolveInfo
163
- ) => Promise<TResult> | TResult
164
-
165
- export type SubscriptionSubscribeFn<TResult, TParent, TContext, TArgs> = (
166
- parent: TParent,
167
- args: TArgs,
168
- context: TContext,
169
- info: GraphQLResolveInfo
170
- ) => AsyncIterator<TResult> | Promise<AsyncIterator<TResult>>
171
-
172
- export type SubscriptionResolveFn<TResult, TParent, TContext, TArgs> = (
173
- parent: TParent,
174
- args: TArgs,
175
- context: TContext,
176
- info: GraphQLResolveInfo
177
- ) => TResult | Promise<TResult>
178
-
179
- export interface SubscriptionSubscriberObject<TResult, TKey extends string, TParent, TContext, TArgs> {
180
- subscribe: SubscriptionSubscribeFn<{ [key in TKey]: TResult }, TParent, TContext, TArgs>
181
- resolve?: SubscriptionResolveFn<TResult, { [key in TKey]: TResult }, TContext, TArgs>
182
- }
183
-
184
- export interface SubscriptionResolverObject<TResult, TParent, TContext, TArgs> {
185
- subscribe: SubscriptionSubscribeFn<any, TParent, TContext, TArgs>
186
- resolve: SubscriptionResolveFn<TResult, any, TContext, TArgs>
187
- }
188
-
189
- export type SubscriptionObject<TResult, TKey extends string, TParent, TContext, TArgs> =
190
- | SubscriptionSubscriberObject<TResult, TKey, TParent, TContext, TArgs>
191
- | SubscriptionResolverObject<TResult, TParent, TContext, TArgs>
192
-
193
- export type SubscriptionResolver<TResult, TKey extends string, TParent = {}, TContext = {}, TArgs = {}> =
194
- | ((...args: any[]) => SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>)
195
- | SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>
196
-
197
- export type TypeResolveFn<TTypes, TParent = {}, TContext = {}> = (
198
- parent: TParent,
199
- context: TContext,
200
- info: GraphQLResolveInfo
201
- ) => Maybe<TTypes> | Promise<Maybe<TTypes>>
202
-
203
- export type IsTypeOfResolverFn<T = {}, TContext = {}> = (obj: T, context: TContext, info: GraphQLResolveInfo) => boolean | Promise<boolean>
204
-
205
- export type NextResolverFn<T> = () => Promise<T>
206
-
207
- export type DirectiveResolverFn<TResult = {}, TParent = {}, TContext = {}, TArgs = {}> = (
208
- next: NextResolverFn<TResult>,
209
- parent: TParent,
210
- args: TArgs,
211
- context: TContext,
212
- info: GraphQLResolveInfo
213
- ) => TResult | Promise<TResult>
214
-
215
- /** Mapping between all available schema types and the resolvers types */
216
- export type ResolversTypes = {
217
- Json: ResolverTypeWrapper<Scalars['Json']>
218
- Query: ResolverTypeWrapper<{}>
219
- _Argument: ResolversTypes['_ValidatorArgument'] | ResolversTypes['_PathArgument'] | ResolversTypes['_LiteralArgument']
220
- _Column: ResolverTypeWrapper<_Column>
221
- String: ResolverTypeWrapper<Scalars['String']>
222
- Boolean: ResolverTypeWrapper<Scalars['Boolean']>
223
- _Entity: ResolverTypeWrapper<_Entity>
224
- _Enum: ResolverTypeWrapper<_Enum>
225
- _Field: ResolversTypes['_Column'] | ResolversTypes['_Relation']
226
- _LiteralArgument: ResolverTypeWrapper<_LiteralArgument>
227
- _OnDeleteBehaviour: _OnDeleteBehaviour
228
- _OrderBy: ResolverTypeWrapper<_OrderBy>
229
- _OrderByDirection: _OrderByDirection
230
- _PathArgument: ResolverTypeWrapper<_PathArgument>
231
- _Relation: ResolverTypeWrapper<_Relation>
232
- _RelationSide: _RelationSide
233
- _Rule: ResolverTypeWrapper<_Rule>
234
- Int: ResolverTypeWrapper<Scalars['Int']>
235
- _RuleMessage: ResolverTypeWrapper<_RuleMessage>
236
- _Schema: ResolverTypeWrapper<_Schema>
237
- _UniqueConstraint: ResolverTypeWrapper<_UniqueConstraint>
238
- _Validator: ResolverTypeWrapper<Omit<_Validator, 'arguments'> & { arguments: ReadonlyArray<ResolversTypes['_Argument']> }>
239
- _ValidatorArgument: ResolverTypeWrapper<_ValidatorArgument>
240
- }
241
-
242
- /** Mapping between all available schema types and the resolvers parents */
243
- export type ResolversParentTypes = {
244
- Json: Scalars['Json']
245
- Query: {}
246
- _Argument: ResolversParentTypes['_ValidatorArgument'] | ResolversParentTypes['_PathArgument'] | ResolversParentTypes['_LiteralArgument']
247
- _Column: _Column
248
- String: Scalars['String']
249
- Boolean: Scalars['Boolean']
250
- _Entity: _Entity
251
- _Enum: _Enum
252
- _Field: ResolversParentTypes['_Column'] | ResolversParentTypes['_Relation']
253
- _LiteralArgument: _LiteralArgument
254
- _OrderBy: _OrderBy
255
- _PathArgument: _PathArgument
256
- _Relation: _Relation
257
- _Rule: _Rule
258
- Int: Scalars['Int']
259
- _RuleMessage: _RuleMessage
260
- _Schema: _Schema
261
- _UniqueConstraint: _UniqueConstraint
262
- _Validator: Omit<_Validator, 'arguments'> & { arguments: ReadonlyArray<ResolversParentTypes['_Argument']> }
263
- _ValidatorArgument: _ValidatorArgument
264
- }
265
-
266
- export interface JsonScalarConfig extends GraphQLScalarTypeConfig<ResolversTypes['Json'], any> {
267
- name: 'Json'
268
- }
269
-
270
- export type QueryResolvers<ContextType = any, ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']> = {
271
- schema?: Resolver<Maybe<ResolversTypes['_Schema']>, ParentType, ContextType>
272
- }
273
-
274
- export type _ArgumentResolvers<ContextType = any, ParentType extends ResolversParentTypes['_Argument'] = ResolversParentTypes['_Argument']> = {
275
- __resolveType: TypeResolveFn<'_ValidatorArgument' | '_PathArgument' | '_LiteralArgument', ParentType, ContextType>
276
- }
277
-
278
- export type _ColumnResolvers<ContextType = any, ParentType extends ResolversParentTypes['_Column'] = ResolversParentTypes['_Column']> = {
279
- name?: Resolver<ResolversTypes['String'], ParentType, ContextType>
280
- type?: Resolver<ResolversTypes['String'], ParentType, ContextType>
281
- enumName?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>
282
- defaultValue?: Resolver<Maybe<ResolversTypes['Json']>, ParentType, ContextType>
283
- nullable?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>
284
- rules?: Resolver<ReadonlyArray<ResolversTypes['_Rule']>, ParentType, ContextType>
285
- validators?: Resolver<ReadonlyArray<ResolversTypes['_Validator']>, ParentType, ContextType>
286
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
287
- }
288
-
289
- export type _EntityResolvers<ContextType = any, ParentType extends ResolversParentTypes['_Entity'] = ResolversParentTypes['_Entity']> = {
290
- name?: Resolver<ResolversTypes['String'], ParentType, ContextType>
291
- customPrimaryAllowed?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>
292
- fields?: Resolver<ReadonlyArray<ResolversTypes['_Field']>, ParentType, ContextType>
293
- unique?: Resolver<ReadonlyArray<ResolversTypes['_UniqueConstraint']>, ParentType, ContextType>
294
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
295
- }
296
-
297
- export type _EnumResolvers<ContextType = any, ParentType extends ResolversParentTypes['_Enum'] = ResolversParentTypes['_Enum']> = {
298
- name?: Resolver<ResolversTypes['String'], ParentType, ContextType>
299
- values?: Resolver<ReadonlyArray<ResolversTypes['String']>, ParentType, ContextType>
300
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
301
- }
302
-
303
- export type _FieldResolvers<ContextType = any, ParentType extends ResolversParentTypes['_Field'] = ResolversParentTypes['_Field']> = {
304
- __resolveType: TypeResolveFn<'_Column' | '_Relation', ParentType, ContextType>
305
- name?: Resolver<ResolversTypes['String'], ParentType, ContextType>
306
- type?: Resolver<ResolversTypes['String'], ParentType, ContextType>
307
- nullable?: Resolver<Maybe<ResolversTypes['Boolean']>, ParentType, ContextType>
308
- rules?: Resolver<ReadonlyArray<ResolversTypes['_Rule']>, ParentType, ContextType>
309
- validators?: Resolver<ReadonlyArray<ResolversTypes['_Validator']>, ParentType, ContextType>
310
- }
311
-
312
- export type _LiteralArgumentResolvers<ContextType = any, ParentType extends ResolversParentTypes['_LiteralArgument'] = ResolversParentTypes['_LiteralArgument']> = {
313
- value?: Resolver<Maybe<ResolversTypes['Json']>, ParentType, ContextType>
314
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
315
- }
316
-
317
- export type _OrderByResolvers<ContextType = any, ParentType extends ResolversParentTypes['_OrderBy'] = ResolversParentTypes['_OrderBy']> = {
318
- path?: Resolver<ReadonlyArray<ResolversTypes['String']>, ParentType, ContextType>
319
- direction?: Resolver<ResolversTypes['_OrderByDirection'], ParentType, ContextType>
320
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
321
- }
322
-
323
- export type _PathArgumentResolvers<ContextType = any, ParentType extends ResolversParentTypes['_PathArgument'] = ResolversParentTypes['_PathArgument']> = {
324
- path?: Resolver<ReadonlyArray<ResolversTypes['String']>, ParentType, ContextType>
325
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
326
- }
327
-
328
- export type _RelationResolvers<ContextType = any, ParentType extends ResolversParentTypes['_Relation'] = ResolversParentTypes['_Relation']> = {
329
- name?: Resolver<ResolversTypes['String'], ParentType, ContextType>
330
- type?: Resolver<ResolversTypes['String'], ParentType, ContextType>
331
- side?: Resolver<ResolversTypes['_RelationSide'], ParentType, ContextType>
332
- targetEntity?: Resolver<ResolversTypes['String'], ParentType, ContextType>
333
- ownedBy?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>
334
- inversedBy?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>
335
- nullable?: Resolver<Maybe<ResolversTypes['Boolean']>, ParentType, ContextType>
336
- onDelete?: Resolver<Maybe<ResolversTypes['_OnDeleteBehaviour']>, ParentType, ContextType>
337
- orphanRemoval?: Resolver<Maybe<ResolversTypes['Boolean']>, ParentType, ContextType>
338
- orderBy?: Resolver<Maybe<ReadonlyArray<ResolversTypes['_OrderBy']>>, ParentType, ContextType>
339
- rules?: Resolver<ReadonlyArray<ResolversTypes['_Rule']>, ParentType, ContextType>
340
- validators?: Resolver<ReadonlyArray<ResolversTypes['_Validator']>, ParentType, ContextType>
341
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
342
- }
343
-
344
- export type _RuleResolvers<ContextType = any, ParentType extends ResolversParentTypes['_Rule'] = ResolversParentTypes['_Rule']> = {
345
- message?: Resolver<Maybe<ResolversTypes['_RuleMessage']>, ParentType, ContextType>
346
- validator?: Resolver<ResolversTypes['Int'], ParentType, ContextType>
347
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
348
- }
349
-
350
- export type _RuleMessageResolvers<ContextType = any, ParentType extends ResolversParentTypes['_RuleMessage'] = ResolversParentTypes['_RuleMessage']> = {
351
- text?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>
352
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
353
- }
354
-
355
- export type _SchemaResolvers<ContextType = any, ParentType extends ResolversParentTypes['_Schema'] = ResolversParentTypes['_Schema']> = {
356
- enums?: Resolver<ReadonlyArray<ResolversTypes['_Enum']>, ParentType, ContextType>
357
- entities?: Resolver<ReadonlyArray<ResolversTypes['_Entity']>, ParentType, ContextType>
358
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
359
- }
360
-
361
- export type _UniqueConstraintResolvers<ContextType = any, ParentType extends ResolversParentTypes['_UniqueConstraint'] = ResolversParentTypes['_UniqueConstraint']> = {
362
- fields?: Resolver<ReadonlyArray<ResolversTypes['String']>, ParentType, ContextType>
363
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
364
- }
365
-
366
- export type _ValidatorResolvers<ContextType = any, ParentType extends ResolversParentTypes['_Validator'] = ResolversParentTypes['_Validator']> = {
367
- operation?: Resolver<ResolversTypes['String'], ParentType, ContextType>
368
- arguments?: Resolver<ReadonlyArray<ResolversTypes['_Argument']>, ParentType, ContextType>
369
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
370
- }
371
-
372
- export type _ValidatorArgumentResolvers<ContextType = any, ParentType extends ResolversParentTypes['_ValidatorArgument'] = ResolversParentTypes['_ValidatorArgument']> = {
373
- validator?: Resolver<ResolversTypes['Int'], ParentType, ContextType>
374
- __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>
375
- }
376
-
377
- export type Resolvers<ContextType = any> = {
378
- Json?: GraphQLScalarType
379
- Query?: QueryResolvers<ContextType>
380
- _Argument?: _ArgumentResolvers<ContextType>
381
- _Column?: _ColumnResolvers<ContextType>
382
- _Entity?: _EntityResolvers<ContextType>
383
- _Enum?: _EnumResolvers<ContextType>
384
- _Field?: _FieldResolvers<ContextType>
385
- _LiteralArgument?: _LiteralArgumentResolvers<ContextType>
386
- _OrderBy?: _OrderByResolvers<ContextType>
387
- _PathArgument?: _PathArgumentResolvers<ContextType>
388
- _Relation?: _RelationResolvers<ContextType>
389
- _Rule?: _RuleResolvers<ContextType>
390
- _RuleMessage?: _RuleMessageResolvers<ContextType>
391
- _Schema?: _SchemaResolvers<ContextType>
392
- _UniqueConstraint?: _UniqueConstraintResolvers<ContextType>
393
- _Validator?: _ValidatorResolvers<ContextType>
394
- _ValidatorArgument?: _ValidatorArgumentResolvers<ContextType>
395
- }
396
-
397
-
398
- /**
399
- * @deprecated
400
- * Use "Resolvers" root object instead. If you wish to get "IResolvers", add "typesPrefix: I" to your config.
401
- */
402
- export type IResolvers<ContextType = any> = Resolvers<ContextType>
@@ -56,15 +56,17 @@ export class Mapper {
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[]>
59
+ public async select(entity: Model.Entity, input: ObjectNode<Input.ListQueryInput>, overRelation: Model.AnyRelation | null): Promise<SelectResultObject[]>
60
60
  public async select(
61
61
  entity: Model.Entity,
62
62
  input: ObjectNode<Input.ListQueryInput>,
63
+ overRelation: Model.AnyRelation | null,
63
64
  indexBy: string,
64
65
  ): Promise<SelectIndexedResultObjects>
65
66
  public async select(
66
67
  entity: Model.Entity,
67
68
  input: ObjectNode<Input.ListQueryInput>,
69
+ overRelation: Model.AnyRelation | null,
68
70
  indexBy?: string,
69
71
  ): Promise<SelectResultObject[] | SelectIndexedResultObjects> {
70
72
  const hydrator = new SelectHydrator()
@@ -75,7 +77,7 @@ export class Mapper {
75
77
  indexByAlias = path.for(indexBy).alias
76
78
  qb = qb.select([path.alias, getColumnName(this.schema, entity, indexBy)], indexByAlias)
77
79
  }
78
- const rows = await this.selectRows(hydrator, qb, entity, input)
80
+ const rows = await this.selectRows(hydrator, qb, entity, input, overRelation)
79
81
 
80
82
  return await (indexByAlias !== null ? hydrator.hydrateAll(rows, indexByAlias) : hydrator.hydrateAll(rows))
81
83
  }
@@ -83,18 +85,19 @@ export class Mapper {
83
85
  public async selectUnique(
84
86
  entity: Model.Entity,
85
87
  query: ObjectNode<Input.UniqueQueryInput>,
88
+ overRelation: Model.AnyRelation | null,
86
89
  ): Promise<SelectResultObject | null> {
87
90
  const uniqueWhere = this.uniqueWhereExpander.expand(entity, query.args.by)
88
91
  const where = query.args.filter ? { and: [uniqueWhere, query.args.filter] } : uniqueWhere
89
92
  const queryExpanded = query.withArg<Input.ListQueryInput>('filter', where)
90
93
 
91
- return (await this.select(entity, queryExpanded))[0] || null
94
+ return (await this.select(entity, queryExpanded, overRelation))[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,
100
+ relation: Model.JoiningColumnRelation & Model.AnyRelation,
98
101
  ) {
99
102
  const hydrator = new SelectHydrator()
100
103
  let qb: SelectBuilder<SelectBuilder.Result> = SelectBuilder.create()
@@ -102,7 +105,7 @@ export class Mapper {
102
105
  const groupingKey = '__grouping_key'
103
106
  qb = qb.select([path.alias, relation.joiningColumn.columnName], groupingKey)
104
107
 
105
- const rows = await this.selectRows(hydrator, qb, entity, input, relation.name)
108
+ const rows = await this.selectRows(hydrator, qb, entity, input, relation, relation.name)
106
109
  return await hydrator.hydrateGroups(rows, groupingKey)
107
110
  }
108
111
 
@@ -111,6 +114,7 @@ export class Mapper {
111
114
  qb: SelectBuilder<SelectBuilder.Result>,
112
115
  entity: Model.Entity,
113
116
  input: ObjectNode<Input.ListQueryInput>,
117
+ overRelation: Model.AnyRelation | null,
114
118
  groupBy?: string,
115
119
  ) {
116
120
  const inputWithOrder = OrderByHelper.appendDefaultOrderBy(entity, input, [])
@@ -118,7 +122,7 @@ export class Mapper {
118
122
  const augmentedBuilder = qb.from(entity.tableName, path.alias).meta('path', [...input.path, input.alias])
119
123
 
120
124
  const selector = this.selectBuilderFactory.create(augmentedBuilder, hydrator)
121
- const filterWithPredicates = this.predicatesInjector.inject(entity, inputWithOrder.args.filter || {})
125
+ const filterWithPredicates = this.predicatesInjector.inject(entity, inputWithOrder.args.filter || {}, overRelation ?? undefined)
122
126
  const inputWithPredicates = inputWithOrder.withArg('filter', filterWithPredicates)
123
127
  selector.select(this, entity, inputWithPredicates, path, groupBy)
124
128
  return await selector.execute(this.db)
@@ -32,6 +32,8 @@ 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 }) =>
@@ -12,6 +12,52 @@ 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
+ targetEntity: Model.Entity
19
+ targetRelation: Model.ManyHasOneRelation
20
+ ids: Input.PrimaryValue[]
21
+ }
22
+
23
+ type FetchOneHasManyGroupsArgs = {
24
+ mapper: Mapper
25
+ objectNode: ObjectNode<Input.ListQueryInput>
26
+ targetEntity: Model.Entity
27
+ relation: Model.OneHasManyRelation
28
+ targetRelation: Model.ManyHasOneRelation
29
+ ids: Input.PrimaryValue[]
30
+ }
31
+
32
+ type ManyHasManyBaseArgs =
33
+ & {
34
+ mapper: Mapper
35
+ targetEntity: Model.Entity
36
+ ids: Input.PrimaryValue[]
37
+ } & (
38
+ | {
39
+ directionFrom: 'owning'
40
+ sourceRelation: Model.ManyHasManyOwningRelation
41
+ targetRelation: Model.ManyHasManyInverseRelation | null
42
+ }
43
+ | {
44
+ directionFrom: 'inverse'
45
+ sourceRelation: Model.ManyHasManyInverseRelation
46
+ targetRelation: Model.ManyHasManyOwningRelation
47
+ }
48
+ )
49
+ type CountManyHasManyGroupArgs =
50
+ & ManyHasManyBaseArgs
51
+ & {
52
+ filter: Input.OptionalWhere | undefined
53
+ }
54
+
55
+ type FetchManyHasManyGroupsArgs =
56
+ & ManyHasManyBaseArgs
57
+ & {
58
+ field: ObjectNode<Input.ListQueryInput>
59
+ }
60
+
15
61
  export class RelationFetcher {
16
62
  constructor(
17
63
  private readonly whereBuilder: WhereBuilder,
@@ -20,25 +66,25 @@ export class RelationFetcher {
20
66
  private readonly pathFactory: PathFactory,
21
67
  ) {}
22
68
 
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> {
69
+ public async countOneHasManyGroups({
70
+ mapper,
71
+ filter,
72
+ targetEntity,
73
+ targetRelation,
74
+ ids,
75
+ }: CountOneHasManyGroupsArgs): Promise<GroupedCounts> {
30
76
  const filterWithParent = this.createOneHasManyFilter(targetEntity, targetRelation, ids, filter)
31
77
  return mapper.countGrouped(targetEntity, filterWithParent, targetRelation)
32
78
  }
33
79
 
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> {
80
+ public async fetchOneHasManyGroups({
81
+ mapper,
82
+ objectNode,
83
+ targetEntity,
84
+ relation,
85
+ targetRelation,
86
+ ids,
87
+ }: FetchOneHasManyGroupsArgs): Promise<SelectGroupedObjects> {
42
88
  const filter = this.createOneHasManyFilter(targetEntity, targetRelation, ids, objectNode.args.filter)
43
89
  const objectNodeWithWhere = objectNode.withArg<Input.ListQueryInput>('filter', filter)
44
90
  const objectNodeWithOrder = OrderByHelper.appendDefaultOrderBy(
@@ -65,14 +111,17 @@ export class RelationFetcher {
65
111
  }
66
112
  }
67
113
 
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> {
114
+ public async countManyHasManyGroups({
115
+ mapper,
116
+ filter,
117
+ targetEntity,
118
+ directionFrom,
119
+ sourceRelation,
120
+ targetRelation,
121
+ ids,
122
+ }: CountManyHasManyGroupArgs): Promise<GroupedCounts> {
123
+ const owningRelation = directionFrom === 'owning' ? sourceRelation : targetRelation
124
+ const joiningColumns = this.resolveJoiningColumns({ directionFrom, owningRelation })
76
125
  const qb = this.buildJunctionQb(owningRelation, ids, joiningColumns, targetEntity, { filter })
77
126
  .select(['junction_', joiningColumns.sourceColumn.columnName])
78
127
  .select(expr => expr.raw('count(*)'), 'row_count')
@@ -85,16 +134,18 @@ export class RelationFetcher {
85
134
  return Object.fromEntries(result)
86
135
  }
87
136
 
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 || []
137
+ public async fetchManyHasManyGroups({
138
+ mapper,
139
+ field,
140
+ sourceRelation,
141
+ targetEntity,
142
+ targetRelation,
143
+ directionFrom,
144
+ ids,
145
+ }: FetchManyHasManyGroupsArgs): Promise<SelectGroupedObjects> {
146
+ const owningRelation = directionFrom === 'owning' ? sourceRelation : targetRelation
147
+ const joiningColumns = this.resolveJoiningColumns({ directionFrom, owningRelation })
148
+ const defaultOrderBy = sourceRelation.orderBy || []
98
149
  const objectNode = OrderByHelper.appendDefaultOrderBy(targetEntity, field, defaultOrderBy)
99
150
 
100
151
  const junctionValues = await this.fetchJunction(
@@ -122,11 +173,21 @@ export class RelationFetcher {
122
173
  },
123
174
  })
124
175
  .withField(primaryField)
125
- const result = await mapper.select(targetEntity, queryWithWhere)
176
+ const result = await mapper.select(targetEntity, queryWithWhere, targetRelation)
126
177
 
127
178
  return this.buildManyHasManyGroups(targetEntity, joiningColumns, result, junctionValues)
128
179
  }
129
180
 
181
+ private resolveJoiningColumns({ directionFrom, owningRelation }: { owningRelation: Model.ManyHasManyOwningRelation; directionFrom: 'owning' | 'inverse' }): JoiningColumns {
182
+ return directionFrom === 'owning' ? {
183
+ sourceColumn: owningRelation.joiningTable.joiningColumn,
184
+ targetColumn: owningRelation.joiningTable.inverseJoiningColumn,
185
+ } : {
186
+ sourceColumn: owningRelation.joiningTable.inverseJoiningColumn,
187
+ targetColumn: owningRelation.joiningTable.joiningColumn,
188
+ }
189
+ }
190
+
130
191
  private buildManyHasManyGroups(
131
192
  entity: Model.Entity,
132
193
  joiningColumns: JoiningColumns,