@contember/engine-content-api 1.2.0-alpha.8 → 1.2.0-beta.1
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.
- package/dist/src/acl/EvaluatedPredicateReplacer.d.ts +2 -3
- package/dist/src/acl/EvaluatedPredicateReplacer.d.ts.map +1 -1
- package/dist/src/acl/EvaluatedPredicateReplacer.js +5 -14
- package/dist/src/acl/EvaluatedPredicateReplacer.js.map +1 -1
- package/dist/src/acl/PermissionFactory.d.ts.map +1 -1
- package/dist/src/acl/PermissionFactory.js +15 -11
- package/dist/src/acl/PermissionFactory.js.map +1 -1
- package/dist/src/acl/PredicateFactory.d.ts +9 -3
- package/dist/src/acl/PredicateFactory.d.ts.map +1 -1
- package/dist/src/acl/PredicateFactory.js +47 -36
- package/dist/src/acl/PredicateFactory.js.map +1 -1
- package/dist/src/acl/PredicatesInjector.d.ts +1 -1
- package/dist/src/acl/PredicatesInjector.d.ts.map +1 -1
- package/dist/src/acl/PredicatesInjector.js +13 -18
- package/dist/src/acl/PredicatesInjector.js.map +1 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.d.ts +0 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.d.ts.map +1 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.js +26 -23
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.js.map +1 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts +1 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts.map +1 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js +1 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.d.ts +5 -4
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.d.ts.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js +11 -14
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.d.ts.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.js +18 -14
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.js.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts +3 -3
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js +3 -3
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.d.ts +5 -4
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.d.ts.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js +11 -15
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js.map +1 -1
- package/dist/src/input-validation/ColumnValueResolver.d.ts +4 -3
- package/dist/src/input-validation/ColumnValueResolver.d.ts.map +1 -1
- package/dist/src/input-validation/ColumnValueResolver.js.map +1 -1
- package/dist/src/input-validation/EntityRulesResolver.js +4 -4
- package/dist/src/input-validation/EntityRulesResolver.js.map +1 -1
- package/dist/src/input-validation/QueryAstFactory.js +1 -1
- package/dist/src/input-validation/QueryAstFactory.js.map +1 -1
- package/dist/src/input-validation/ValidationDataSelector.js +1 -1
- package/dist/src/input-validation/ValidationDataSelector.js.map +1 -1
- package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.d.ts +7 -8
- package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.d.ts.map +1 -1
- package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.js.map +1 -1
- package/dist/src/input-validation/preValidation/InputPreValidator.js +4 -4
- package/dist/src/input-validation/preValidation/InputPreValidator.js.map +1 -1
- package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.d.ts +7 -8
- package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.d.ts.map +1 -1
- package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.js.map +1 -1
- package/dist/src/inputProcessing/CreateInputProcessor.d.ts +8 -9
- package/dist/src/inputProcessing/CreateInputProcessor.d.ts.map +1 -1
- package/dist/src/inputProcessing/CreateInputVisitor.d.ts +7 -7
- package/dist/src/inputProcessing/CreateInputVisitor.d.ts.map +1 -1
- package/dist/src/inputProcessing/CreateInputVisitor.js +15 -46
- package/dist/src/inputProcessing/CreateInputVisitor.js.map +1 -1
- package/dist/src/inputProcessing/UpdateInputProcessor.d.ts +8 -9
- package/dist/src/inputProcessing/UpdateInputProcessor.d.ts.map +1 -1
- package/dist/src/inputProcessing/UpdateInputVisitor.d.ts +7 -7
- package/dist/src/inputProcessing/UpdateInputVisitor.d.ts.map +1 -1
- package/dist/src/inputProcessing/UpdateInputVisitor.js +13 -28
- package/dist/src/inputProcessing/UpdateInputVisitor.js.map +1 -1
- package/dist/src/inputProcessing/index.d.ts +0 -1
- package/dist/src/inputProcessing/index.d.ts.map +1 -1
- package/dist/src/inputProcessing/index.js +0 -1
- package/dist/src/inputProcessing/index.js.map +1 -1
- package/dist/src/introspection/IntrospectionSchemaFactory.js +7 -7
- package/dist/src/introspection/IntrospectionSchemaFactory.js.map +1 -1
- package/dist/src/mapper/ErrorUtils.d.ts.map +1 -1
- package/dist/src/mapper/ErrorUtils.js +2 -2
- package/dist/src/mapper/ErrorUtils.js.map +1 -1
- package/dist/src/mapper/JunctionTableManager.js.map +1 -1
- package/dist/src/mapper/Mapper.d.ts +6 -6
- package/dist/src/mapper/Mapper.d.ts.map +1 -1
- package/dist/src/mapper/Mapper.js +26 -21
- package/dist/src/mapper/Mapper.js.map +1 -1
- package/dist/src/mapper/MapperContainer.d.ts.map +1 -1
- package/dist/src/mapper/MapperContainer.js +4 -4
- package/dist/src/mapper/MapperContainer.js.map +1 -1
- package/dist/src/mapper/Result.d.ts.map +1 -1
- package/dist/src/mapper/Result.js +2 -4
- package/dist/src/mapper/Result.js.map +1 -1
- package/dist/src/mapper/delete/DeleteExecutor.js +6 -6
- package/dist/src/mapper/delete/DeleteExecutor.js.map +1 -1
- package/dist/src/mapper/insert/InsertBuilder.d.ts +1 -1
- package/dist/src/mapper/insert/InsertBuilder.d.ts.map +1 -1
- package/dist/src/mapper/insert/InsertBuilder.js.map +1 -1
- package/dist/src/mapper/insert/SqlCreateInputProcessor.d.ts +4 -2
- package/dist/src/mapper/insert/SqlCreateInputProcessor.d.ts.map +1 -1
- package/dist/src/mapper/insert/SqlCreateInputProcessor.js.map +1 -1
- package/dist/src/mapper/select/JoinVisitor.d.ts +6 -6
- package/dist/src/mapper/select/JoinVisitor.d.ts.map +1 -1
- package/dist/src/mapper/select/JoinVisitor.js +6 -6
- package/dist/src/mapper/select/JoinVisitor.js.map +1 -1
- package/dist/src/mapper/select/Path.d.ts +1 -0
- package/dist/src/mapper/select/Path.d.ts.map +1 -1
- package/dist/src/mapper/select/Path.js +4 -1
- package/dist/src/mapper/select/Path.js.map +1 -1
- package/dist/src/mapper/select/RelationFetcher.d.ts +11 -19
- package/dist/src/mapper/select/RelationFetcher.d.ts.map +1 -1
- package/dist/src/mapper/select/RelationFetcher.js +34 -25
- package/dist/src/mapper/select/RelationFetcher.js.map +1 -1
- package/dist/src/mapper/select/SelectBuilder.d.ts +4 -1
- package/dist/src/mapper/select/SelectBuilder.d.ts.map +1 -1
- package/dist/src/mapper/select/SelectBuilder.js +52 -12
- package/dist/src/mapper/select/SelectBuilder.js.map +1 -1
- package/dist/src/mapper/select/SelectBuilderFactory.d.ts +2 -1
- package/dist/src/mapper/select/SelectBuilderFactory.d.ts.map +1 -1
- package/dist/src/mapper/select/SelectExecutionHandler.d.ts +16 -4
- package/dist/src/mapper/select/SelectExecutionHandler.d.ts.map +1 -1
- package/dist/src/mapper/select/SelectHydrator.d.ts +3 -2
- package/dist/src/mapper/select/SelectHydrator.d.ts.map +1 -1
- package/dist/src/mapper/select/SelectHydrator.js +6 -9
- package/dist/src/mapper/select/SelectHydrator.js.map +1 -1
- package/dist/src/mapper/select/WhereBuilder.d.ts +8 -4
- package/dist/src/mapper/select/WhereBuilder.d.ts.map +1 -1
- package/dist/src/mapper/select/WhereBuilder.js +137 -35
- package/dist/src/mapper/select/WhereBuilder.js.map +1 -1
- package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts +10 -8
- package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts.map +1 -1
- package/dist/src/mapper/select/handlers/FieldsVisitor.js +129 -94
- package/dist/src/mapper/select/handlers/FieldsVisitor.js.map +1 -1
- package/dist/src/mapper/select/handlers/FieldsVisitorFactory.d.ts.map +1 -1
- package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js +1 -1
- package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js.map +1 -1
- package/dist/src/mapper/select/handlers/MetaHandler.d.ts.map +1 -1
- package/dist/src/mapper/select/handlers/MetaHandler.js +6 -11
- package/dist/src/mapper/select/handlers/MetaHandler.js.map +1 -1
- package/dist/src/mapper/select/optimizer/ConditionOptimizer.d.ts.map +1 -1
- package/dist/src/mapper/select/optimizer/ConditionOptimizer.js +6 -0
- package/dist/src/mapper/select/optimizer/ConditionOptimizer.js.map +1 -1
- package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts +9 -1
- package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts.map +1 -1
- package/dist/src/mapper/select/optimizer/WhereOptimizer.js +127 -13
- package/dist/src/mapper/select/optimizer/WhereOptimizer.js.map +1 -1
- package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts +3 -0
- package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts.map +1 -0
- package/dist/src/mapper/select/optimizer/WhereReplacer.js +46 -0
- package/dist/src/mapper/select/optimizer/WhereReplacer.js.map +1 -0
- package/dist/src/mapper/select/optimizer/helpers.d.ts +1 -1
- package/dist/src/mapper/select/optimizer/helpers.d.ts.map +1 -1
- package/dist/src/mapper/select/optimizer/helpers.js +8 -1
- package/dist/src/mapper/select/optimizer/helpers.js.map +1 -1
- package/dist/src/mapper/update/SqlUpdateInputProcessor.d.ts +2 -3
- package/dist/src/mapper/update/SqlUpdateInputProcessor.d.ts.map +1 -1
- package/dist/src/mapper/update/SqlUpdateInputProcessor.js +3 -4
- package/dist/src/mapper/update/SqlUpdateInputProcessor.js.map +1 -1
- package/dist/src/mapper/update/UpdateBuilder.js +3 -3
- package/dist/src/mapper/update/UpdateBuilder.js.map +1 -1
- package/dist/src/resolvers/ExecutionContainerFactory.d.ts +1 -1
- package/dist/src/resolvers/ExecutionContainerFactory.d.ts.map +1 -1
- package/dist/src/resolvers/GraphQlQueryAstFactory.d.ts +1 -2
- package/dist/src/resolvers/GraphQlQueryAstFactory.d.ts.map +1 -1
- package/dist/src/resolvers/GraphQlQueryAstFactory.js +2 -2
- package/dist/src/resolvers/GraphQlQueryAstFactory.js.map +1 -1
- package/dist/src/resolvers/MutationResolver.d.ts.map +1 -1
- package/dist/src/resolvers/MutationResolver.js +13 -2
- package/dist/src/resolvers/MutationResolver.js.map +1 -1
- package/dist/src/resolvers/ReadHelpers.js +3 -3
- package/dist/src/resolvers/ReadHelpers.js.map +1 -1
- package/dist/src/resolvers/ReadResolver.js +2 -2
- package/dist/src/resolvers/ReadResolver.js.map +1 -1
- package/dist/src/schema/EnumsProvider.d.ts.map +1 -1
- package/dist/src/schema/EnumsProvider.js +1 -2
- package/dist/src/schema/EnumsProvider.js.map +1 -1
- package/dist/src/schema/FieldAccessVisitor.d.ts +2 -2
- package/dist/src/schema/FieldAccessVisitor.d.ts.map +1 -1
- package/dist/src/schema/FieldAccessVisitor.js +2 -2
- package/dist/src/schema/FieldAccessVisitor.js.map +1 -1
- package/dist/src/schema/OrderByTypeProvider.d.ts +1 -1
- package/dist/src/schema/OrderByTypeProvider.d.ts.map +1 -1
- package/dist/src/schema/OrderByTypeProvider.js +2 -2
- package/dist/src/schema/OrderByTypeProvider.js.map +1 -1
- package/dist/src/schema/WhereTypeProvider.d.ts +1 -2
- package/dist/src/schema/WhereTypeProvider.d.ts.map +1 -1
- package/dist/src/schema/WhereTypeProvider.js +4 -4
- package/dist/src/schema/WhereTypeProvider.js.map +1 -1
- package/dist/src/schema/entities/FieldArgsVisitor.d.ts +4 -5
- package/dist/src/schema/entities/FieldArgsVisitor.d.ts.map +1 -1
- package/dist/src/schema/entities/FieldArgsVisitor.js +3 -3
- package/dist/src/schema/entities/FieldArgsVisitor.js.map +1 -1
- package/dist/src/schema/entities/FieldTypeVisitor.d.ts +3 -3
- package/dist/src/schema/entities/FieldTypeVisitor.d.ts.map +1 -1
- package/dist/src/schema/entities/FieldTypeVisitor.js +3 -3
- package/dist/src/schema/entities/FieldTypeVisitor.js.map +1 -1
- package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.d.ts +3 -3
- package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.d.ts.map +1 -1
- package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.js +3 -3
- package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.js.map +1 -1
- package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.d.ts +6 -6
- package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.d.ts.map +1 -1
- package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.js +6 -6
- package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.js.map +1 -1
- package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.d.ts +3 -3
- package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.d.ts.map +1 -1
- package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.js +5 -5
- package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.js.map +1 -1
- package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.d.ts +10 -4
- package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.d.ts.map +1 -1
- package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.js +3 -3
- package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.js.map +1 -1
- package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.d.ts +6 -6
- package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.d.ts.map +1 -1
- package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.js +6 -6
- package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.js.map +1 -1
- package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.d.ts +2 -2
- package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.d.ts.map +1 -1
- package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js +2 -2
- package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js.map +1 -1
- package/dist/src/schema/utils.d.ts +1 -1
- package/dist/src/schema/utils.d.ts.map +1 -1
- package/dist/src/tsconfig.tsbuildinfo +1 -1
- package/dist/src/utils/object.d.ts.map +1 -1
- package/dist/src/utils/object.js +3 -4
- package/dist/src/utils/object.js.map +1 -1
- package/dist/src/utils/uniqueWhereFields.js +3 -3
- package/dist/src/utils/uniqueWhereFields.js.map +1 -1
- package/dist/tests/cases/bugs/bug102.test.js +6 -6
- package/dist/tests/cases/bugs/bug102.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js +5 -5
- package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/delete/additionalDeleteFilter.test.js +5 -5
- package/dist/tests/cases/integration/graphQlRequests/delete/additionalDeleteFilter.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/delete/cascadeDelete.test.js +5 -5
- package/dist/tests/cases/integration/graphQlRequests/delete/cascadeDelete.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/delete/deleteById.test.js +5 -5
- package/dist/tests/cases/integration/graphQlRequests/delete/deleteById.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/delete/orphanRemoval.test.js +5 -5
- package/dist/tests/cases/integration/graphQlRequests/delete/orphanRemoval.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/delete/setNullOnDelete.test.js +5 -5
- package/dist/tests/cases/integration/graphQlRequests/delete/setNullOnDelete.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/query/acl/differentRowAndFieldPredicate.test.js +51 -4
- package/dist/tests/cases/integration/graphQlRequests/query/acl/differentRowAndFieldPredicate.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js +26 -25
- package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js +9 -6
- package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.d.ts +2 -0
- package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.js +109 -0
- package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.js.map +1 -0
- package/dist/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.js +17 -15
- package/dist/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.js +4 -5
- package/dist/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/query/graphqlFeatures/alias.test.js +9 -13
- package/dist/tests/cases/integration/graphQlRequests/query/graphqlFeatures/alias.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/query/unique/oneHasManyUnique.test.js +5 -3
- package/dist/tests/cases/integration/graphQlRequests/query/unique/oneHasManyUnique.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/delete.test.js +5 -5
- package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/delete.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/delete.test.js +5 -5
- package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/delete.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/delete.test.js +10 -10
- package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/delete.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/combination.test.js +5 -5
- package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/combination.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/delete.test.js +5 -5
- package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/delete.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/delete.test.js +5 -5
- package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/delete.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js +4 -4
- package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlSchema/model.js.map +1 -1
- package/dist/tests/cases/unit/conditionOptimizer.test.js +5 -0
- package/dist/tests/cases/unit/conditionOptimizer.test.js.map +1 -1
- package/dist/tests/cases/unit/permissionMerger.test.js +2 -0
- package/dist/tests/cases/unit/permissionMerger.test.js.map +1 -1
- package/dist/tests/cases/unit/predicatesFactory.test.js +7 -1
- package/dist/tests/cases/unit/predicatesFactory.test.js.map +1 -1
- package/dist/tests/cases/unit/predicatesInjector.test.js +105 -0
- package/dist/tests/cases/unit/predicatesInjector.test.js.map +1 -1
- package/dist/tests/cases/unit/whereBuilder.test.d.ts +2 -0
- package/dist/tests/cases/unit/whereBuilder.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/whereBuilder.test.js +131 -0
- package/dist/tests/cases/unit/whereBuilder.test.js.map +1 -0
- package/dist/tests/cases/unit/whereOptimizer.test.js +187 -0
- package/dist/tests/cases/unit/whereOptimizer.test.js.map +1 -1
- package/dist/tests/src/test.js +2 -2
- package/dist/tests/src/test.js.map +1 -1
- package/dist/tests/src/testGraphql.d.ts.map +1 -1
- package/dist/tests/src/testGraphql.js +9 -5
- package/dist/tests/src/testGraphql.js.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -11
- package/src/acl/EvaluatedPredicateReplacer.ts +9 -15
- package/src/acl/PermissionFactory.ts +18 -13
- package/src/acl/PredicateFactory.ts +64 -40
- package/src/acl/PredicatesInjector.ts +18 -17
- package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.ts +21 -28
- package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.ts +1 -6
- package/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.ts +10 -28
- package/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.ts +11 -8
- package/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.ts +4 -22
- package/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.ts +10 -29
- package/src/input-validation/ColumnValueResolver.ts +2 -3
- package/src/input-validation/EntityRulesResolver.ts +4 -4
- package/src/input-validation/QueryAstFactory.ts +1 -1
- package/src/input-validation/ValidationDataSelector.ts +1 -1
- package/src/input-validation/preValidation/CreateInputPreValidationProcessor.ts +7 -8
- package/src/input-validation/preValidation/InputPreValidator.ts +4 -4
- package/src/input-validation/preValidation/UpdateInputPreValidationProcessor.ts +7 -8
- package/src/inputProcessing/CreateInputProcessor.ts +8 -9
- package/src/inputProcessing/CreateInputVisitor.ts +27 -89
- package/src/inputProcessing/UpdateInputProcessor.ts +8 -9
- package/src/inputProcessing/UpdateInputVisitor.ts +25 -71
- package/src/inputProcessing/index.ts +0 -1
- package/src/introspection/IntrospectionSchemaFactory.ts +7 -7
- package/src/mapper/ErrorUtils.ts +2 -2
- package/src/mapper/JunctionTableManager.ts +3 -3
- package/src/mapper/Mapper.ts +34 -31
- package/src/mapper/MapperContainer.ts +7 -5
- package/src/mapper/Result.ts +2 -4
- package/src/mapper/delete/DeleteExecutor.ts +6 -6
- package/src/mapper/insert/InsertBuilder.ts +2 -2
- package/src/mapper/insert/SqlCreateInputProcessor.ts +3 -3
- package/src/mapper/select/JoinVisitor.ts +6 -33
- package/src/mapper/select/Path.ts +4 -1
- package/src/mapper/select/RelationFetcher.ts +49 -50
- package/src/mapper/select/SelectBuilder.ts +71 -13
- package/src/mapper/select/SelectBuilderFactory.ts +2 -1
- package/src/mapper/select/SelectExecutionHandler.ts +16 -8
- package/src/mapper/select/SelectHydrator.ts +15 -11
- package/src/mapper/select/WhereBuilder.ts +168 -61
- package/src/mapper/select/handlers/FieldsVisitor.ts +80 -111
- package/src/mapper/select/handlers/FieldsVisitorFactory.ts +1 -0
- package/src/mapper/select/handlers/MetaHandler.ts +6 -17
- package/src/mapper/select/optimizer/ConditionOptimizer.ts +6 -0
- package/src/mapper/select/optimizer/WhereOptimizer.ts +148 -21
- package/src/mapper/select/optimizer/WhereReplacer.ts +39 -0
- package/src/mapper/select/optimizer/helpers.ts +7 -3
- package/src/mapper/update/SqlUpdateInputProcessor.ts +4 -10
- package/src/mapper/update/UpdateBuilder.ts +3 -3
- package/src/resolvers/ExecutionContainerFactory.ts +1 -1
- package/src/resolvers/GraphQlQueryAstFactory.ts +5 -4
- package/src/resolvers/MutationResolver.ts +14 -4
- package/src/resolvers/ReadHelpers.ts +3 -3
- package/src/resolvers/ReadResolver.ts +2 -2
- package/src/schema/EnumsProvider.ts +2 -4
- package/src/schema/FieldAccessVisitor.ts +2 -2
- package/src/schema/OrderByTypeProvider.ts +10 -3
- package/src/schema/WhereTypeProvider.ts +5 -6
- package/src/schema/entities/FieldArgsVisitor.ts +4 -5
- package/src/schema/entities/FieldTypeVisitor.ts +3 -3
- package/src/schema/mutations/CreateEntityInputFieldVisitor.ts +3 -6
- package/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.ts +6 -20
- package/src/schema/mutations/CreateEntityRelationInputFieldVisitor.ts +6 -20
- package/src/schema/mutations/UpdateEntityInputFieldVisitor.ts +3 -6
- package/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.ts +6 -20
- package/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.ts +9 -14
- package/src/schema/utils.ts +1 -1
- package/src/tsconfig.json +6 -6
- package/src/utils/object.ts +6 -6
- package/src/utils/uniqueWhereFields.ts +3 -3
- package/tests/cases/bugs/bug102.test.ts +6 -6
- package/tests/cases/integration/graphQlRequests/delete/aclDelete.test.ts +5 -5
- package/tests/cases/integration/graphQlRequests/delete/additionalDeleteFilter.test.ts +5 -5
- package/tests/cases/integration/graphQlRequests/delete/cascadeDelete.test.ts +5 -5
- package/tests/cases/integration/graphQlRequests/delete/deleteById.test.ts +5 -5
- package/tests/cases/integration/graphQlRequests/delete/orphanRemoval.test.ts +5 -5
- package/tests/cases/integration/graphQlRequests/delete/setNullOnDelete.test.ts +5 -5
- package/tests/cases/integration/graphQlRequests/query/acl/differentRowAndFieldPredicate.test.ts +54 -4
- package/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.ts +26 -25
- package/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.ts +9 -6
- package/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.ts +104 -0
- package/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.ts +17 -15
- package/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.ts +4 -5
- package/tests/cases/integration/graphQlRequests/query/graphqlFeatures/alias.test.ts +9 -13
- package/tests/cases/integration/graphQlRequests/query/unique/oneHasManyUnique.test.ts +5 -3
- package/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/delete.test.ts +5 -5
- package/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/delete.test.ts +5 -5
- package/tests/cases/integration/graphQlRequests/update/manyHasOne/delete.test.ts +10 -10
- package/tests/cases/integration/graphQlRequests/update/oneHasMany/combination.test.ts +5 -5
- package/tests/cases/integration/graphQlRequests/update/oneHasMany/delete.test.ts +5 -5
- package/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/delete.test.ts +5 -5
- package/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.ts +2 -3
- package/tests/cases/unit/conditionOptimizer.test.ts +6 -0
- package/tests/cases/unit/permissionMerger.test.ts +2 -0
- package/tests/cases/unit/predicatesFactory.test.ts +8 -2
- package/tests/cases/unit/predicatesInjector.test.ts +97 -2
- package/tests/cases/unit/whereBuilder.test.ts +148 -0
- package/tests/cases/unit/whereOptimizer.test.ts +215 -0
- package/tests/src/test.ts +2 -2
- package/tests/src/testGraphql.ts +9 -5
- package/dist/src/inputProcessing/InputContext.d.ts +0 -43
- package/dist/src/inputProcessing/InputContext.d.ts.map +0 -1
- package/dist/src/inputProcessing/InputContext.js +0 -3
- package/dist/src/inputProcessing/InputContext.js.map +0 -1
- package/src/inputProcessing/InputContext.ts +0 -49
|
@@ -2,48 +2,160 @@ import { Input, Model } from '@contember/schema'
|
|
|
2
2
|
import { ConditionOptimizer } from './ConditionOptimizer'
|
|
3
3
|
import { acceptFieldVisitor } from '@contember/schema-utils'
|
|
4
4
|
import { optimizeAnd, optimizeNot, optimizeOr } from './helpers'
|
|
5
|
+
import { replaceWhere } from './WhereReplacer'
|
|
6
|
+
|
|
7
|
+
type ExtendedRelationContext =
|
|
8
|
+
& {
|
|
9
|
+
context: Model.AnyRelationContext
|
|
10
|
+
canEliminate: boolean
|
|
11
|
+
isLast: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface WhereOptimizationHints {
|
|
15
|
+
relationPath?: Model.AnyRelationContext[]
|
|
16
|
+
evaluatedPredicates?: Input.OptionalWhere[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type OptimizedOperand = Input.OptionalWhere | undefined | boolean
|
|
5
20
|
|
|
6
21
|
export class WhereOptimizer {
|
|
22
|
+
private static eliminableRelations = new Set<Model.AnyRelationContext['type']>(['oneHasMany', 'oneHasOneInverse', 'oneHasOneOwning'])
|
|
23
|
+
|
|
7
24
|
constructor(
|
|
8
25
|
private readonly model: Model.Schema,
|
|
9
26
|
private readonly conditionOptimizer: ConditionOptimizer,
|
|
10
27
|
) {
|
|
11
28
|
}
|
|
12
29
|
|
|
13
|
-
public optimize(where: Input.OptionalWhere, entity: Model.Entity): Input.
|
|
14
|
-
|
|
30
|
+
public optimize(where: Input.OptionalWhere, entity: Model.Entity, { relationPath = [], evaluatedPredicates = [] }: WhereOptimizationHints = {}): Input.OptionalWhere {
|
|
31
|
+
let processedRelationPath: ExtendedRelationContext[] = []
|
|
32
|
+
for (const i in relationPath) {
|
|
33
|
+
const el = relationPath[i]
|
|
34
|
+
if (!WhereOptimizer.eliminableRelations.has(el.type)) {
|
|
35
|
+
processedRelationPath = []
|
|
36
|
+
} else {
|
|
37
|
+
processedRelationPath.push({ context: el, canEliminate: true, isLast: Number(i) === relationPath.length })
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
let result = this.optimizeWhere(where, entity, processedRelationPath)
|
|
15
41
|
|
|
16
42
|
if (typeof result === 'boolean') {
|
|
17
43
|
return { [entity.primary]: { [result ? 'always' : 'never']: true } }
|
|
18
44
|
}
|
|
45
|
+
let changed = false
|
|
46
|
+
for (const evaluated of evaluatedPredicates) {
|
|
47
|
+
const evaluatedPredicate = this.optimize(evaluated, entity)
|
|
48
|
+
const newResult = replaceWhere(result, evaluatedPredicate, { [entity.primary]: { always: true } })
|
|
49
|
+
if (newResult !== result) {
|
|
50
|
+
result = newResult
|
|
51
|
+
changed = true
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (changed) {
|
|
55
|
+
return this.optimize(result, entity)
|
|
56
|
+
}
|
|
19
57
|
|
|
20
58
|
return result
|
|
21
59
|
}
|
|
22
60
|
|
|
23
|
-
private optimizeWhere(where: Input.OptionalWhere, entity: Model.Entity): Input.
|
|
24
|
-
|
|
25
|
-
Object.entries(where).map(([key, value]) => {
|
|
26
|
-
if (value === undefined || value === null) {
|
|
27
|
-
return undefined
|
|
61
|
+
private optimizeWhere(where: Input.OptionalWhere, entity: Model.Entity, relationPath: ExtendedRelationContext[]): Input.OptionalWhere | boolean {
|
|
62
|
+
const operands: OptimizedOperand[] = []
|
|
28
63
|
|
|
29
|
-
|
|
30
|
-
|
|
64
|
+
for (const key in where) {
|
|
65
|
+
const value = where[key]
|
|
66
|
+
let operand: OptimizedOperand = undefined
|
|
67
|
+
if (value === undefined || value === null) {
|
|
68
|
+
continue
|
|
69
|
+
} else if (key === 'and') {
|
|
70
|
+
const innerOperands: (Input.OptionalWhere | boolean)[] = []
|
|
71
|
+
for (const innerValue of value as readonly Input.OptionalWhere[]) {
|
|
72
|
+
const innerOperand = this.optimizeWhere(innerValue, entity, relationPath)
|
|
73
|
+
if (innerOperand === false) {
|
|
74
|
+
return false
|
|
75
|
+
}
|
|
76
|
+
innerOperands.push(innerOperand)
|
|
77
|
+
}
|
|
78
|
+
operand = this.optimizeAnd(innerOperands, entity, relationPath)
|
|
79
|
+
} else if (key === 'or') {
|
|
80
|
+
const innerOperands: (Input.OptionalWhere | boolean)[] = []
|
|
81
|
+
for (const innerValue of value as readonly Input.OptionalWhere[]) {
|
|
82
|
+
const innerOperand = this.optimizeWhere(innerValue, entity, relationPath)
|
|
83
|
+
if (innerOperand === true) {
|
|
84
|
+
operand = true
|
|
85
|
+
break
|
|
86
|
+
}
|
|
87
|
+
innerOperands.push(innerOperand)
|
|
88
|
+
}
|
|
89
|
+
if (operand !== true) {
|
|
90
|
+
operand = this.optimizeOr(innerOperands, entity, relationPath)
|
|
91
|
+
}
|
|
31
92
|
|
|
32
|
-
|
|
33
|
-
|
|
93
|
+
} else if (key === 'not') {
|
|
94
|
+
operand = optimizeNot(this.optimizeWhere(value as Input.OptionalWhere, entity, relationPath))
|
|
34
95
|
|
|
35
|
-
|
|
36
|
-
|
|
96
|
+
} else {
|
|
97
|
+
operand = this.resolveFieldValue(entity, key, value, relationPath)
|
|
98
|
+
}
|
|
37
99
|
|
|
38
|
-
|
|
39
|
-
|
|
100
|
+
if (operand === false) {
|
|
101
|
+
return false
|
|
102
|
+
|
|
103
|
+
} else if (operand !== undefined) {
|
|
104
|
+
operands.push(operand)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return this.optimizeAnd(operands, entity, relationPath)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private optimizeOr(operands: readonly OptimizedOperand[], entity: Model.Entity, relationPath: ExtendedRelationContext[]): Input.OptionalWhere | boolean {
|
|
111
|
+
const optimized = optimizeOr(operands)
|
|
112
|
+
if (typeof optimized === 'boolean' || !Array.isArray(optimized.or)) {
|
|
113
|
+
return optimized
|
|
114
|
+
}
|
|
115
|
+
const result = this.crossOptimize(optimized.or, entity, { never: true }, relationPath)
|
|
116
|
+
if (result === optimized.or) {
|
|
117
|
+
return optimized
|
|
118
|
+
}
|
|
119
|
+
return optimizeOr(result)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private optimizeAnd(operands: readonly OptimizedOperand[], entity: Model.Entity, relationPath: ExtendedRelationContext[]): Input.OptionalWhere | boolean {
|
|
123
|
+
const optimized = optimizeAnd(operands)
|
|
124
|
+
if (typeof optimized === 'boolean' || !Array.isArray(optimized.and)) {
|
|
125
|
+
return optimized
|
|
126
|
+
}
|
|
127
|
+
const result = this.crossOptimize(optimized.and, entity, { always: true }, relationPath)
|
|
128
|
+
if (result === optimized.and) {
|
|
129
|
+
return optimized
|
|
130
|
+
}
|
|
131
|
+
return optimizeAnd(result)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private crossOptimize(operands: Input.OptionalWhere[], entity: Model.Entity, replacement: Input.Condition, relationPath: ExtendedRelationContext[]): (Input.OptionalWhere | boolean)[] {
|
|
135
|
+
let result: (Input.OptionalWhere | boolean)[] = operands
|
|
136
|
+
let copied = false
|
|
137
|
+
const count = result.length
|
|
138
|
+
for (let i = 0; i < count; i++) {
|
|
139
|
+
for (let j = 0; j < count; j++) {
|
|
140
|
+
const a = result[j]
|
|
141
|
+
const b = result[i]
|
|
142
|
+
if (i !== j && typeof a !== 'boolean' && typeof b !== 'boolean') {
|
|
143
|
+
const elResult = replaceWhere(a, b, { [entity.primary]: replacement })
|
|
144
|
+
if (elResult !== a) {
|
|
145
|
+
if (!copied) {
|
|
146
|
+
result = [...result]
|
|
147
|
+
copied = true
|
|
148
|
+
}
|
|
149
|
+
result[j] = this.optimizeWhere(elResult, entity, relationPath)
|
|
150
|
+
}
|
|
40
151
|
}
|
|
41
|
-
}
|
|
42
|
-
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return result
|
|
43
155
|
}
|
|
44
156
|
|
|
45
|
-
private resolveFieldValue(entity: Model.Entity, key: string, value: Input.OptionalWhere[string]) {
|
|
46
|
-
return acceptFieldVisitor<Input.
|
|
157
|
+
private resolveFieldValue(entity: Model.Entity, key: string, value: Input.OptionalWhere[string], relationPath: ExtendedRelationContext[]) {
|
|
158
|
+
return acceptFieldVisitor<Input.OptionalWhere | boolean>(this.model, entity, key, {
|
|
47
159
|
visitColumn: () => {
|
|
48
160
|
const optimizedCondition = this.conditionOptimizer.optimize(value as Input.Condition)
|
|
49
161
|
|
|
@@ -53,8 +165,23 @@ export class WhereOptimizer {
|
|
|
53
165
|
|
|
54
166
|
return { [key]: optimizedCondition }
|
|
55
167
|
},
|
|
56
|
-
visitRelation:
|
|
57
|
-
|
|
168
|
+
visitRelation: context => {
|
|
169
|
+
let where = value as Input.OptionalWhere
|
|
170
|
+
const newRelationPath: ExtendedRelationContext[] = [...relationPath]
|
|
171
|
+
const length = relationPath.length
|
|
172
|
+
if (length > 0 && relationPath[length - 1].context.targetRelation?.name === context.relation.name) {
|
|
173
|
+
const item = newRelationPath.pop()
|
|
174
|
+
const type = item!.context.type
|
|
175
|
+
if (item?.canEliminate && (type === 'oneHasMany' || type === 'oneHasOneOwning' || type === 'oneHasOneInverse')) {
|
|
176
|
+
where = replaceWhere(where, { [context.targetEntity.primary]: { isNull: true } }, { [context.targetEntity.primary]: { never: true } })
|
|
177
|
+
where = replaceWhere(where, { [context.targetEntity.primary]: { isNull: false } }, { [context.targetEntity.primary]: { always: true } })
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
// first level relation - we are sure root exists
|
|
181
|
+
const canEliminate = length === 0 || relationPath[length - 1].isLast
|
|
182
|
+
newRelationPath.push({ context, isLast: false, canEliminate })
|
|
183
|
+
}
|
|
184
|
+
const optimizedWhere = this.optimizeWhere(where, context.targetEntity, newRelationPath)
|
|
58
185
|
|
|
59
186
|
if (typeof optimizedWhere === 'boolean') {
|
|
60
187
|
return optimizedWhere
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Input, Writable } from '@contember/schema'
|
|
2
|
+
import deepEqual from 'fast-deep-equal'
|
|
3
|
+
|
|
4
|
+
export const replaceWhere = (subject: Input.OptionalWhere, find: Input.OptionalWhere, replace: Input.OptionalWhere): Input.OptionalWhere => {
|
|
5
|
+
if (deepEqual(subject, find)) {
|
|
6
|
+
return replace
|
|
7
|
+
}
|
|
8
|
+
let result: Writable<Input.OptionalWhere> = subject
|
|
9
|
+
let copied = false
|
|
10
|
+
for (const key in subject) {
|
|
11
|
+
const value = subject[key]
|
|
12
|
+
if (key === 'not') {
|
|
13
|
+
const newNot = replaceWhere(value as Input.OptionalWhere, find, replace)
|
|
14
|
+
if (newNot !== value) {
|
|
15
|
+
if (!copied) {
|
|
16
|
+
result = { ...result }
|
|
17
|
+
}
|
|
18
|
+
result['not'] = newNot
|
|
19
|
+
}
|
|
20
|
+
} else if (key === 'and' || key === 'or') {
|
|
21
|
+
const items: Input.OptionalWhere[] = []
|
|
22
|
+
let itemChanged = false
|
|
23
|
+
for (const el of value as Input.OptionalWhere[]) {
|
|
24
|
+
const newEl = replaceWhere(el, find, replace)
|
|
25
|
+
if (newEl !== el) {
|
|
26
|
+
itemChanged = true
|
|
27
|
+
}
|
|
28
|
+
items.push(newEl)
|
|
29
|
+
}
|
|
30
|
+
if (itemChanged) {
|
|
31
|
+
if (!copied) {
|
|
32
|
+
result = { ...result }
|
|
33
|
+
}
|
|
34
|
+
result[key] = items
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return result
|
|
39
|
+
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
export const optimizeOr = <P extends Record<string, unknown>>(operands: readonly (P | boolean)[]): P | { or?: P[] } | boolean => {
|
|
1
|
+
export const optimizeOr = <P extends Record<string, unknown>>(operands: readonly (P | boolean | undefined)[]): P | { or?: P[] } | boolean => {
|
|
2
2
|
const normalized: P[] = []
|
|
3
|
-
|
|
3
|
+
let hasNever = false
|
|
4
4
|
for (const operand of operands) {
|
|
5
5
|
if (operand === true) {
|
|
6
6
|
return true
|
|
7
|
-
} else if (operand
|
|
7
|
+
} else if (operand === false) {
|
|
8
|
+
hasNever = true
|
|
9
|
+
} else if (operand !== undefined) {
|
|
8
10
|
normalized.push(...Array.isArray(operand.or) ? operand.or : [operand])
|
|
9
11
|
}
|
|
10
12
|
}
|
|
@@ -13,6 +15,8 @@ export const optimizeOr = <P extends Record<string, unknown>>(operands: readonly
|
|
|
13
15
|
return { or: normalized }
|
|
14
16
|
} else if (normalized.length === 1) {
|
|
15
17
|
return normalized[0]
|
|
18
|
+
} else if (hasNever) {
|
|
19
|
+
return false
|
|
16
20
|
} else {
|
|
17
21
|
return {}
|
|
18
22
|
}
|
|
@@ -2,7 +2,6 @@ import { Input, Model, Value } from '@contember/schema'
|
|
|
2
2
|
import { Mapper } from '../Mapper'
|
|
3
3
|
import { UpdateBuilder } from './UpdateBuilder'
|
|
4
4
|
import { UpdateInputProcessor } from '../../inputProcessing'
|
|
5
|
-
import * as Context from '../../inputProcessing'
|
|
6
5
|
import {
|
|
7
6
|
ConstraintType,
|
|
8
7
|
getInsertPrimary,
|
|
@@ -17,6 +16,7 @@ import { hasManyProcessor, hasOneProcessor } from '../MutationProcessorHelper'
|
|
|
17
16
|
import { AbortUpdate } from './Updater'
|
|
18
17
|
import { ImplementationException } from '../../exception'
|
|
19
18
|
import { CheckedPrimary } from '../CheckedPrimary'
|
|
19
|
+
import { logger } from '@contember/logger'
|
|
20
20
|
|
|
21
21
|
export class SqlUpdateInputProcessor implements UpdateInputProcessor<MutationResultList> {
|
|
22
22
|
constructor(
|
|
@@ -26,7 +26,7 @@ export class SqlUpdateInputProcessor implements UpdateInputProcessor<MutationRes
|
|
|
26
26
|
private readonly mapper: Mapper,
|
|
27
27
|
) {}
|
|
28
28
|
|
|
29
|
-
public column({ entity, column }:
|
|
29
|
+
public column({ entity, column }: Model.ColumnContext) {
|
|
30
30
|
if (this.data[column.name] !== undefined) {
|
|
31
31
|
this.updateBuilder.addFieldValue(column.name, this.data[column.name] as Value.AtomicValue)
|
|
32
32
|
}
|
|
@@ -228,10 +228,7 @@ export class SqlUpdateInputProcessor implements UpdateInputProcessor<MutationRes
|
|
|
228
228
|
return [new MutationConstraintViolationError([], ConstraintType.notNull)]
|
|
229
229
|
}
|
|
230
230
|
if (relation.joiningColumn.onDelete === Model.OnDelete.restrict) {
|
|
231
|
-
|
|
232
|
-
console.error(
|
|
233
|
-
'[DEPRECATED] You are deleting an entity over the relation where onDelete behaviour is set to restrict. This will fail in next version.',
|
|
234
|
-
)
|
|
231
|
+
logger.warn('You are deleting an entity over the relation where onDelete behaviour is set to restrict. This will fail in next version.', { loc: 'SqlUpdateInputProcessor' })
|
|
235
232
|
this.updateBuilder.addFieldValue(relation.name, null)
|
|
236
233
|
}
|
|
237
234
|
const inversePrimary = await this.mapper.selectField(
|
|
@@ -490,10 +487,7 @@ export class SqlUpdateInputProcessor implements UpdateInputProcessor<MutationRes
|
|
|
490
487
|
return [new MutationConstraintViolationError([], ConstraintType.notNull)]
|
|
491
488
|
}
|
|
492
489
|
if (relation.joiningColumn.onDelete === Model.OnDelete.restrict) {
|
|
493
|
-
|
|
494
|
-
console.error(
|
|
495
|
-
'[DEPRECATED] You are deleting an entity over the relation where onDelete behaviour is set to restrict. This will fail in next version.',
|
|
496
|
-
)
|
|
490
|
+
logger.warn('You are deleting an entity over the relation where onDelete behaviour is set to restrict. This will fail in next version.', { loc: 'SqlUpdateInputProcessor' })
|
|
497
491
|
this.updateBuilder.addFieldValue(relation.name, null)
|
|
498
492
|
}
|
|
499
493
|
const targetPrimary = await this.mapper.selectField(
|
|
@@ -74,9 +74,9 @@ export class UpdateBuilder {
|
|
|
74
74
|
const columns = new Set(resolvedData.map(it => it.columnName))
|
|
75
75
|
const allColumns: string[] = Object.values(
|
|
76
76
|
acceptEveryFieldVisitor(this.schema, this.entity, {
|
|
77
|
-
visitColumn: (
|
|
78
|
-
visitManyHasOne: (
|
|
79
|
-
visitOneHasOneOwning: (
|
|
77
|
+
visitColumn: ({ column }) => column.columnName,
|
|
78
|
+
visitManyHasOne: ({ relation }) => relation.joiningColumn.columnName,
|
|
79
|
+
visitOneHasOneOwning: ({ relation }) => relation.joiningColumn.columnName,
|
|
80
80
|
visitManyHasManyInverse: () => null,
|
|
81
81
|
visitManyHasManyOwning: () => null,
|
|
82
82
|
visitOneHasOneInverse: () => null,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
import { ValidationResolver } from './ValidationResolver'
|
|
16
16
|
import { Providers } from '@contember/schema-utils'
|
|
17
17
|
import { GraphQlQueryAstFactory } from './GraphQlQueryAstFactory'
|
|
18
|
-
import { getArgumentValues } from 'graphql
|
|
18
|
+
import { getArgumentValues } from 'graphql'
|
|
19
19
|
import { createMapperContainer } from '../mapper'
|
|
20
20
|
|
|
21
21
|
export interface ExecutionContainer {
|
|
@@ -2,17 +2,18 @@ import { isIt, ResolveInfoUtils } from '../utils'
|
|
|
2
2
|
import {
|
|
3
3
|
FieldNode as GraphQlFieldNode,
|
|
4
4
|
FragmentSpreadNode,
|
|
5
|
+
getArgumentValues,
|
|
5
6
|
GraphQLObjectType,
|
|
6
7
|
GraphQLOutputType,
|
|
7
8
|
GraphQLResolveInfo,
|
|
8
9
|
isListType,
|
|
9
10
|
isNonNullType,
|
|
10
|
-
isObjectType,
|
|
11
|
+
isObjectType,
|
|
12
|
+
Kind,
|
|
13
|
+
SelectionSetNode,
|
|
11
14
|
} from 'graphql'
|
|
12
|
-
import { SelectionSetNode } from 'graphql/language/ast'
|
|
13
|
-
import { getArgumentValues } from 'graphql/execution/values'
|
|
14
15
|
import { FieldNode, ObjectNode } from '../inputProcessing'
|
|
15
|
-
import { isDeepStrictEqual } from 'util'
|
|
16
|
+
import { isDeepStrictEqual } from 'node:util'
|
|
16
17
|
|
|
17
18
|
type NodeFilter = (node: GraphQlFieldNode, path: string[]) => boolean
|
|
18
19
|
type AnyNode = ObjectNode | FieldNode
|
|
@@ -2,13 +2,13 @@ import { Input, Model, Result, Value } from '@contember/schema'
|
|
|
2
2
|
import {
|
|
3
3
|
ConstraintType,
|
|
4
4
|
getInsertPrimary,
|
|
5
|
-
getUpdatePrimary,
|
|
6
5
|
InputErrorKind,
|
|
7
6
|
Mapper,
|
|
8
7
|
MapperFactory,
|
|
9
8
|
MutationResultHint,
|
|
10
9
|
MutationResultList,
|
|
11
|
-
MutationResultType,
|
|
10
|
+
MutationResultType,
|
|
11
|
+
tryMutation,
|
|
12
12
|
} from '../mapper'
|
|
13
13
|
import { ValidationResolver } from './ValidationResolver'
|
|
14
14
|
import { GraphQLResolveInfo } from 'graphql'
|
|
@@ -20,6 +20,7 @@ import { assertNever } from '../utils'
|
|
|
20
20
|
import { InputPreValidator } from '../input-validation'
|
|
21
21
|
import { ObjectNode } from '../inputProcessing'
|
|
22
22
|
import { executeReadOperations } from './ReadHelpers'
|
|
23
|
+
import { logger } from '@contember/logger'
|
|
23
24
|
|
|
24
25
|
type WithoutNode<T extends { node: any }> = Pick<T, Exclude<keyof T, 'node'>>
|
|
25
26
|
|
|
@@ -61,6 +62,7 @@ export class MutationResolver {
|
|
|
61
62
|
|
|
62
63
|
return this.transaction(async (mapper, trx) => {
|
|
63
64
|
if (options?.deferForeignKeyConstraints) {
|
|
65
|
+
logger.debug('MutationResolver: deferring foreign constraints')
|
|
64
66
|
await mapper.constraintHelper.setFkConstraintsDeferred()
|
|
65
67
|
}
|
|
66
68
|
const validationResult: Record<string, Result.MutationFieldResult> = {}
|
|
@@ -144,7 +146,7 @@ export class MutationResolver {
|
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
const meta = readOperationMeta(fieldConfig.extensions)
|
|
147
|
-
|
|
149
|
+
logger.debug('MutationResolver: Resolving a field', { field: field.alias })
|
|
148
150
|
const result: {
|
|
149
151
|
ok: boolean
|
|
150
152
|
validation?: Result.ValidationResult
|
|
@@ -168,6 +170,7 @@ export class MutationResolver {
|
|
|
168
170
|
})()
|
|
169
171
|
|
|
170
172
|
if (!result.ok) {
|
|
173
|
+
logger.debug('MutationResolver: Field evaluation failed', { result, field: field.alias })
|
|
171
174
|
const validationErrors = result.validation ? prefixErrors(result.validation.errors, field.alias) : []
|
|
172
175
|
const executionErrors = prefixErrors(result.errors, field.alias)
|
|
173
176
|
return {
|
|
@@ -192,12 +195,14 @@ export class MutationResolver {
|
|
|
192
195
|
trxResult[field.alias] = result
|
|
193
196
|
}
|
|
194
197
|
if (options?.deferForeignKeyConstraints) {
|
|
198
|
+
logger.debug('MutationResolver: validating fk constraints')
|
|
195
199
|
const constraintsResult = await tryMutation(this.schema, async () => {
|
|
196
200
|
await mapper.constraintHelper.setFkConstraintsImmediate()
|
|
197
201
|
return []
|
|
198
202
|
})
|
|
199
203
|
const errorResponse = this.createErrorResponse(constraintsResult)
|
|
200
204
|
if (errorResponse) {
|
|
205
|
+
logger.debug('MutationResolver: deferred fk validation failed', { errorResponse })
|
|
201
206
|
return { ...errorResponse, ...validationResult }
|
|
202
207
|
}
|
|
203
208
|
}
|
|
@@ -457,7 +462,7 @@ export class MutationResolver {
|
|
|
457
462
|
throw new Error('MutationResolver: expected ObjectNode')
|
|
458
463
|
}
|
|
459
464
|
const objectWithArgs = singleNodeQuery.withArgs({ by: where })
|
|
460
|
-
nodes[singleNodeQuery.alias] = await mapper.selectUnique(entity, objectWithArgs,
|
|
465
|
+
nodes[singleNodeQuery.alias] = await mapper.selectUnique(entity, objectWithArgs, [])
|
|
461
466
|
}
|
|
462
467
|
return nodes
|
|
463
468
|
}
|
|
@@ -468,17 +473,22 @@ export class MutationResolver {
|
|
|
468
473
|
return await retryTransaction(
|
|
469
474
|
async () => {
|
|
470
475
|
return await this.db.transaction(async trx => {
|
|
476
|
+
logger.debug('MutationResolver: Starting mutation transaction')
|
|
471
477
|
await trx.connection.query(Connection.REPEATABLE_READ)
|
|
472
478
|
await this.systemVariablesSetup(trx)
|
|
473
479
|
const mapper = this.mapperFactory(trx)
|
|
474
480
|
|
|
475
481
|
const result = await cb(mapper, trx)
|
|
476
482
|
if (!result.ok) {
|
|
483
|
+
logger.debug('MutationResolver: Transaction failed, rolling back', { result })
|
|
477
484
|
await trx.connection.rollback()
|
|
485
|
+
} else {
|
|
486
|
+
logger.debug('MutationResolver: Transaction ok, committing')
|
|
478
487
|
}
|
|
479
488
|
return result
|
|
480
489
|
})
|
|
481
490
|
},
|
|
491
|
+
message => logger.warn(message),
|
|
482
492
|
{
|
|
483
493
|
maxAttempts: 15,
|
|
484
494
|
minTimeout: 10,
|
|
@@ -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,
|
|
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,
|
|
40
|
+
return mapper.selectUnique(meta.entity, field, [])
|
|
41
41
|
case Operation.list:
|
|
42
|
-
return mapper.select(meta.entity, field,
|
|
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,
|
|
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,
|
|
41
|
+
return await this.mapperFactory(this.db).selectUnique(entity, queryAst, [])
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
public async resolvePaginationQuery(entity: Model.Entity, info: GraphQLResolveInfo) {
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { GraphQLEnumType } from 'graphql'
|
|
2
|
-
import { GraphQLEnumValueConfigMap } from 'graphql/type/definition'
|
|
1
|
+
import { GraphQLEnumType, GraphQLEnumValueConfigMap } from 'graphql'
|
|
3
2
|
import { Model } from '@contember/schema'
|
|
4
|
-
import { singletonFactory } from '../utils'
|
|
5
|
-
import { capitalizeFirstLetter } from '../utils'
|
|
3
|
+
import { capitalizeFirstLetter, singletonFactory } from '../utils'
|
|
6
4
|
|
|
7
5
|
export class EnumsProvider {
|
|
8
6
|
private schema: Model.Schema
|
|
@@ -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(
|
|
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({
|
|
14
|
+
visitRelation({ targetEntity }: Model.AnyRelationContext) {
|
|
15
15
|
return this.authorizator.getEntityPermission(this.operation, targetEntity.name) !== 'no'
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
GraphQLBoolean,
|
|
3
|
+
GraphQLEnumType,
|
|
4
|
+
GraphQLInputFieldConfig,
|
|
5
|
+
GraphQLInputFieldConfigMap,
|
|
6
|
+
GraphQLInputObjectType,
|
|
7
|
+
GraphQLInputType,
|
|
8
|
+
GraphQLInt,
|
|
9
|
+
} from 'graphql'
|
|
2
10
|
import { Acl, Model } from '@contember/schema'
|
|
3
11
|
import { acceptFieldVisitor } from '@contember/schema-utils'
|
|
4
12
|
import { singletonFactory } from '../utils'
|
|
5
13
|
import { GqlTypeName } from './utils'
|
|
6
14
|
import { Authorizator } from '../acl'
|
|
7
15
|
import { FieldAccessVisitor } from './FieldAccessVisitor'
|
|
8
|
-
import { GraphQLBoolean, GraphQLEnumType, GraphQLInputObjectType, GraphQLInt } from 'graphql'
|
|
9
16
|
|
|
10
17
|
export class OrderByTypeProvider {
|
|
11
18
|
private orderBySingleton = singletonFactory(name => this.createEntityOrderByType(name))
|
|
@@ -51,7 +58,7 @@ export class OrderByTypeProvider {
|
|
|
51
58
|
|
|
52
59
|
const field = acceptFieldVisitor(this.schema, name, fieldName, {
|
|
53
60
|
visitColumn: () => ({ type: this.orderDirectionEnum }),
|
|
54
|
-
visitHasOne: (
|
|
61
|
+
visitHasOne: ({ relation }) => ({ type: this.getEntityOrderByType(relation.target) }),
|
|
55
62
|
visitHasMany: () => undefined,
|
|
56
63
|
} as Model.FieldVisitor<GraphQLInputFieldConfig | undefined>)
|
|
57
64
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Acl, Model } from '@contember/schema'
|
|
2
2
|
import { acceptFieldVisitor, getEntity } from '@contember/schema-utils'
|
|
3
|
-
import { GraphQLInputObjectType, GraphQLList } from 'graphql'
|
|
4
|
-
import { GraphQLInputFieldConfig, GraphQLInputFieldConfigMap } from 'graphql/type/definition'
|
|
3
|
+
import { GraphQLInputFieldConfig, GraphQLInputFieldConfigMap, GraphQLInputObjectType, GraphQLList } from 'graphql'
|
|
5
4
|
import { capitalizeFirstLetter, getFieldsForUniqueWhere, singletonFactory } from '../utils'
|
|
6
5
|
import { ColumnTypeResolver } from './ColumnTypeResolver'
|
|
7
6
|
import { ConditionTypeProvider } from './ConditionTypeProvider'
|
|
@@ -74,7 +73,7 @@ export class WhereTypeProvider {
|
|
|
74
73
|
continue
|
|
75
74
|
}
|
|
76
75
|
fields[field] = acceptFieldVisitor<GraphQLInputFieldConfig>(this.schema, entity, field, {
|
|
77
|
-
visitRelation: (
|
|
76
|
+
visitRelation: ({ targetEntity }) => {
|
|
78
77
|
// if (!isIt<Model.JoiningColumnRelation>(relation, 'joiningColumn')) {
|
|
79
78
|
// throw new Error('Only column or owning relation can be a part of unique key')
|
|
80
79
|
// }
|
|
@@ -84,7 +83,7 @@ export class WhereTypeProvider {
|
|
|
84
83
|
}
|
|
85
84
|
return { type: uniqueWhere }
|
|
86
85
|
},
|
|
87
|
-
visitColumn: (
|
|
86
|
+
visitColumn: ({ column }) => ({ type: this.columnTypeResolver.getType(column) }),
|
|
88
87
|
})
|
|
89
88
|
}
|
|
90
89
|
}
|
|
@@ -104,8 +103,8 @@ export class WhereTypeProvider {
|
|
|
104
103
|
continue
|
|
105
104
|
}
|
|
106
105
|
fields[fieldName] = acceptFieldVisitor(this.schema, name, fieldName, {
|
|
107
|
-
visitColumn: (
|
|
108
|
-
visitRelation: (
|
|
106
|
+
visitColumn: ({ column }) => ({ type: this.conditionTypeProvider.getCondition(column) }),
|
|
107
|
+
visitRelation: ({ relation }) => ({ type: this.getEntityWhereType(relation.target) }),
|
|
109
108
|
} as Model.FieldVisitor<GraphQLInputFieldConfig>)
|
|
110
109
|
}
|
|
111
110
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Model } from '@contember/schema'
|
|
2
2
|
import { WhereTypeProvider } from '../WhereTypeProvider'
|
|
3
|
-
import { GraphQLFieldConfigArgumentMap } from 'graphql
|
|
3
|
+
import { GraphQLFieldConfigArgumentMap, GraphQLInt, GraphQLList, GraphQLNonNull } from 'graphql'
|
|
4
4
|
import { OrderByTypeProvider } from '../OrderByTypeProvider'
|
|
5
|
-
import { GraphQLInt, GraphQLList, GraphQLNonNull } from 'graphql'
|
|
6
5
|
|
|
7
6
|
export class FieldArgsVisitor implements
|
|
8
7
|
Model.ColumnVisitor<GraphQLFieldConfigArgumentMap | undefined>,
|
|
@@ -15,11 +14,11 @@ export class FieldArgsVisitor implements
|
|
|
15
14
|
this.whereTypeProvider = whereTypeProvider
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
public visitColumn(
|
|
17
|
+
public visitColumn() {
|
|
19
18
|
return undefined
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
public visitHasMany(
|
|
21
|
+
public visitHasMany({ relation }: Model.AnyHasManyRelationContext) {
|
|
23
22
|
const filter = this.getWhereArg(relation)
|
|
24
23
|
const orderBy = this.getOrderByArgs(relation)
|
|
25
24
|
return {
|
|
@@ -30,7 +29,7 @@ export class FieldArgsVisitor implements
|
|
|
30
29
|
}
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
public visitHasOne(
|
|
32
|
+
public visitHasOne({ relation }: Model.ManyHasOneContext) {
|
|
34
33
|
const filter = this.getWhereArg(relation)
|
|
35
34
|
return { filter }
|
|
36
35
|
}
|
|
@@ -13,7 +13,7 @@ export class FieldTypeVisitor implements Model.ColumnVisitor<GraphQLOutputType>,
|
|
|
13
13
|
) {
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
public visitColumn(
|
|
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(
|
|
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(
|
|
34
|
+
public visitHasOne({ relation }: Model.AnyHasOneRelationContext): GraphQLOutputType {
|
|
35
35
|
return this.entityTypeProvider.getEntity(relation.target)
|
|
36
36
|
}
|
|
37
37
|
}
|