@contember/engine-content-api 1.3.4 → 1.4.0-alpha.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.
Files changed (139) hide show
  1. package/dist/src/ExecutionContainer.d.ts +4 -4
  2. package/dist/src/ExecutionContainer.d.ts.map +1 -1
  3. package/dist/src/ExecutionContainer.js +5 -2
  4. package/dist/src/ExecutionContainer.js.map +1 -1
  5. package/dist/src/extensions/EntityFieldsProvider.d.ts +1 -1
  6. package/dist/src/extensions/EntityFieldsProvider.d.ts.map +1 -1
  7. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducer.d.ts +1 -1
  8. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducer.d.ts.map +1 -1
  9. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducer.js +12 -2
  10. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducer.js.map +1 -1
  11. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts +16 -9
  12. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts.map +1 -1
  13. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js +21 -13
  14. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js.map +1 -1
  15. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProvider.d.ts +1 -1
  16. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProvider.d.ts.map +1 -1
  17. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProvider.js +8 -2
  18. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProvider.js.map +1 -1
  19. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts +16 -9
  20. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts.map +1 -1
  21. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js +17 -12
  22. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js.map +1 -1
  23. package/dist/src/introspection/IntrospectionSchemaDefinitionFactory.d.ts +5 -2
  24. package/dist/src/introspection/IntrospectionSchemaDefinitionFactory.d.ts.map +1 -1
  25. package/dist/src/introspection/IntrospectionSchemaDefinitionFactory.js +164 -14
  26. package/dist/src/introspection/IntrospectionSchemaDefinitionFactory.js.map +1 -1
  27. package/dist/src/introspection/index.d.ts +1 -2
  28. package/dist/src/introspection/index.d.ts.map +1 -1
  29. package/dist/src/introspection/index.js +4 -4
  30. package/dist/src/introspection/index.js.map +1 -1
  31. package/dist/src/mapper/ErrorUtils.d.ts +3 -3
  32. package/dist/src/mapper/ErrorUtils.d.ts.map +1 -1
  33. package/dist/src/mapper/ErrorUtils.js +2 -2
  34. package/dist/src/mapper/ErrorUtils.js.map +1 -1
  35. package/dist/src/mapper/Mapper.d.ts +2 -3
  36. package/dist/src/mapper/Mapper.d.ts.map +1 -1
  37. package/dist/src/mapper/Mapper.js +1 -1
  38. package/dist/src/mapper/Mapper.js.map +1 -1
  39. package/dist/src/mapper/MapperFactory.d.ts +3 -3
  40. package/dist/src/mapper/MapperFactory.d.ts.map +1 -1
  41. package/dist/src/mapper/MapperFactory.js.map +1 -1
  42. package/dist/src/mapper/Result.d.ts +2 -2
  43. package/dist/src/mapper/Result.d.ts.map +1 -1
  44. package/dist/src/mapper/Result.js.map +1 -1
  45. package/dist/src/mapper/delete/DeleteExecutor.js +1 -1
  46. package/dist/src/mapper/delete/DeleteExecutor.js.map +1 -1
  47. package/dist/src/mapper/insert/Inserter.d.ts +3 -2
  48. package/dist/src/mapper/insert/Inserter.d.ts.map +1 -1
  49. package/dist/src/mapper/insert/Inserter.js.map +1 -1
  50. package/dist/src/mapper/select/RelationFetcher.d.ts.map +1 -1
  51. package/dist/src/mapper/select/RelationFetcher.js +8 -7
  52. package/dist/src/mapper/select/RelationFetcher.js.map +1 -1
  53. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts +3 -5
  54. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts.map +1 -1
  55. package/dist/src/mapper/select/handlers/FieldsVisitor.js +8 -4
  56. package/dist/src/mapper/select/handlers/FieldsVisitor.js.map +1 -1
  57. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.d.ts +3 -5
  58. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.d.ts.map +1 -1
  59. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js +3 -4
  60. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js.map +1 -1
  61. package/dist/src/mapper/update/Updater.d.ts +2 -2
  62. package/dist/src/mapper/update/Updater.d.ts.map +1 -1
  63. package/dist/src/mapper/update/Updater.js.map +1 -1
  64. package/dist/src/resolvers/MutationResolver.d.ts +3 -2
  65. package/dist/src/resolvers/MutationResolver.d.ts.map +1 -1
  66. package/dist/src/resolvers/MutationResolver.js +20 -18
  67. package/dist/src/resolvers/MutationResolver.js.map +1 -1
  68. package/dist/src/schema/EntityTypeProvider.d.ts.map +1 -1
  69. package/dist/src/schema/EntityTypeProvider.js +23 -26
  70. package/dist/src/schema/EntityTypeProvider.js.map +1 -1
  71. package/dist/src/schema/GraphQlSchemaBuilder.d.ts +10 -2
  72. package/dist/src/schema/GraphQlSchemaBuilder.d.ts.map +1 -1
  73. package/dist/src/schema/GraphQlSchemaBuilder.js +47 -37
  74. package/dist/src/schema/GraphQlSchemaBuilder.js.map +1 -1
  75. package/dist/src/schema/ResultSchemaTypeProvider.d.ts +4 -0
  76. package/dist/src/schema/ResultSchemaTypeProvider.d.ts.map +1 -1
  77. package/dist/src/schema/ResultSchemaTypeProvider.js +27 -23
  78. package/dist/src/schema/ResultSchemaTypeProvider.js.map +1 -1
  79. package/dist/src/tsconfig.tsbuildinfo +1 -1
  80. package/dist/tests/cases/integration/graphQlDb/update/deferedConstraints.test.js +1 -1
  81. package/dist/tests/cases/integration/graphQlDb/update/deferedConstraints.test.js.map +1 -1
  82. package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.d.ts +2 -0
  83. package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.d.ts.map +1 -0
  84. package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.js +170 -0
  85. package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.js.map +1 -0
  86. package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.js +44 -0
  87. package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.js.map +1 -1
  88. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js +20 -0
  89. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js.map +1 -1
  90. package/dist/tests/src/test.js +1 -1
  91. package/dist/tests/src/test.js.map +1 -1
  92. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  93. package/graphql.codegen.yml +1 -1
  94. package/package.json +12 -14
  95. package/src/ExecutionContainer.ts +13 -6
  96. package/src/extensions/EntityFieldsProvider.ts +1 -1
  97. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducer.ts +12 -5
  98. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.ts +33 -24
  99. package/src/extensions/paginatedHasMany/PaginatedHasManyFieldProvider.ts +8 -5
  100. package/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.ts +28 -17
  101. package/src/introspection/IntrospectionSchemaDefinitionFactory.ts +202 -13
  102. package/src/introspection/index.ts +1 -2
  103. package/src/mapper/ErrorUtils.ts +8 -7
  104. package/src/mapper/Mapper.ts +4 -4
  105. package/src/mapper/MapperFactory.ts +3 -3
  106. package/src/mapper/Result.ts +2 -3
  107. package/src/mapper/delete/DeleteExecutor.ts +1 -1
  108. package/src/mapper/insert/Inserter.ts +3 -2
  109. package/src/mapper/select/RelationFetcher.ts +8 -4
  110. package/src/mapper/select/handlers/FieldsVisitor.ts +9 -5
  111. package/src/mapper/select/handlers/FieldsVisitorFactory.ts +3 -6
  112. package/src/mapper/update/Updater.ts +3 -2
  113. package/src/resolvers/MutationResolver.ts +29 -22
  114. package/src/schema/EntityTypeProvider.ts +32 -41
  115. package/src/schema/GraphQlSchemaBuilder.ts +61 -40
  116. package/src/schema/ResultSchemaTypeProvider.ts +29 -27
  117. package/tests/cases/integration/graphQlDb/update/deferedConstraints.test.ts +1 -1
  118. package/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.ts +169 -0
  119. package/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.ts +45 -0
  120. package/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.ts +24 -0
  121. package/tests/cases/integration/graphQlSchema/schema-acl-allowed.gql +1 -0
  122. package/tests/cases/integration/graphQlSchema/schema-acl-create-only.gql +1 -0
  123. package/tests/cases/integration/graphQlSchema/schema-acl-restricted-create.gql +1 -0
  124. package/tests/cases/integration/graphQlSchema/schema-acl-restricted-delete.gql +1 -0
  125. package/tests/cases/integration/graphQlSchema/schema-acl-restricted-update.gql +1 -0
  126. package/tests/cases/integration/graphQlSchema/schema-acl.gql +1 -0
  127. package/tests/cases/integration/graphQlSchema/schema-aliased-type.gql +1 -0
  128. package/tests/cases/integration/graphQlSchema/schema-basic.gql +1 -0
  129. package/tests/cases/integration/graphQlSchema/schema-bug-66.gql +1 -0
  130. package/tests/cases/integration/graphQlSchema/schema-custom-primary.gql +1 -0
  131. package/tests/cases/integration/graphQlSchema/schema-has-many-reduction.gql +1 -0
  132. package/tests/cases/integration/graphQlSchema/schema-new-builder.gql +1 -0
  133. package/tests/cases/integration/graphQlSchema/schema-read-only.gql +116 -0
  134. package/tests/src/test.ts +3 -3
  135. package/dist/src/introspection/content-schema.graphql.d.ts +0 -4
  136. package/dist/src/introspection/content-schema.graphql.d.ts.map +0 -1
  137. package/dist/src/introspection/content-schema.graphql.js +0 -113
  138. package/dist/src/introspection/content-schema.graphql.js.map +0 -1
  139. package/src/introspection/content-schema.graphql.ts +0 -113
@@ -1,5 +1,5 @@
1
1
  schema:
2
- - "./src/introspection/content-schema.graphql.ts"
2
+ - "./src/introspection/IntrospectionSchemaDefinitionFactory.ts"
3
3
  documents: []
4
4
  config:
5
5
  immutableTypes: "1"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/engine-content-api",
3
- "version": "1.3.4",
3
+ "version": "1.4.0-alpha.1",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/src/index.js",
6
6
  "typings": "dist/src/index.d.ts",
@@ -13,21 +13,19 @@
13
13
  "test": "vitest --dir ./tests/cases --no-threads"
14
14
  },
15
15
  "dependencies": {
16
- "@contember/database": "1.3.4",
17
- "@contember/dic": "1.3.4",
18
- "@contember/graphql-utils": "1.3.4",
19
- "@contember/logger": "1.3.4",
20
- "@contember/schema": "1.3.4",
21
- "@contember/schema-definition": "1.3.4",
22
- "@contember/schema-utils": "1.3.4",
23
- "@graphql-tools/schema": "^8.3.5",
24
- "fast-deep-equal": "^3.1.3",
25
- "graphql-tag": "^2.12.5"
16
+ "@contember/database": "1.4.0-alpha.1",
17
+ "@contember/dic": "1.4.0-alpha.1",
18
+ "@contember/graphql-utils": "1.4.0-alpha.1",
19
+ "@contember/logger": "1.4.0-alpha.1",
20
+ "@contember/schema": "1.4.0-alpha.1",
21
+ "@contember/schema-definition": "1.4.0-alpha.1",
22
+ "@contember/schema-utils": "1.4.0-alpha.1",
23
+ "fast-deep-equal": "^3.1.3"
26
24
  },
27
25
  "devDependencies": {
28
- "@contember/database-tester": "1.3.4",
29
- "@contember/engine-api-tester": "1.3.4",
30
- "@contember/schema-definition": "1.3.4",
26
+ "@contember/database-tester": "1.4.0-alpha.1",
27
+ "@contember/engine-api-tester": "1.4.0-alpha.1",
28
+ "@contember/schema-definition": "1.4.0-alpha.1",
31
29
  "@graphql-codegen/cli": "^2.6.2",
32
30
  "@graphql-codegen/typescript": "^2.5.1",
33
31
  "@graphql-codegen/typescript-operations": "^2.4.2",
@@ -27,8 +27,8 @@ import {
27
27
  } from './mapper'
28
28
  import { Builder } from '@contember/dic'
29
29
  import { Acl, Model, Schema } from '@contember/schema'
30
- import { Client, SelectBuilder as DbSelectBuilder } from '@contember/database'
31
- import { Providers, SchemaDatabaseMetadata } from '@contember/schema-utils'
30
+ import { Client, DatabaseMetadata, SelectBuilder as DbSelectBuilder } from '@contember/database'
31
+ import { Providers } from '@contember/schema-utils'
32
32
  import { PaginatedHasManyExecutionHandler } from './extensions/paginatedHasMany/PaginatedHasManyExecutionHandler'
33
33
  import { PaginatedHasManyFieldProvider } from './extensions/paginatedHasMany/PaginatedHasManyFieldProvider'
34
34
  import { WhereOptimizer } from './mapper/select/optimizer/WhereOptimizer'
@@ -44,7 +44,7 @@ import {
44
44
 
45
45
  export type ExecutionContainerArgs = {
46
46
  schema: Schema & { id: number }
47
- schemaDatabaseMetadata: SchemaDatabaseMetadata
47
+ schemaDatabaseMetadata: DatabaseMetadata
48
48
  db: Client
49
49
  identityId: string
50
50
  identityVariables: Acl.VariablesMap
@@ -107,13 +107,20 @@ export class ExecutionContainerFactory {
107
107
  .addService('whereOptimized', ({ schema }) =>
108
108
  new WhereOptimizer(schema.model, new ConditionOptimizer()))
109
109
  .addService('whereBuilder', ({ joinBuilder, conditionBuilder, pathFactory, whereOptimized, schema }) =>
110
- new WhereBuilder(schema.model, joinBuilder, conditionBuilder, pathFactory, whereOptimized, schema.settings.useExistsInHasManyFilter === true))
110
+ new WhereBuilder(
111
+ schema.model,
112
+ joinBuilder,
113
+ conditionBuilder,
114
+ pathFactory,
115
+ whereOptimized,
116
+ (schema.settings.content?.useExistsInHasManyFilter ?? schema.settings.useExistsInHasManyFilter) === true,
117
+ ))
111
118
  .addService('orderByBuilder', ({ joinBuilder, schema }) =>
112
119
  new OrderByBuilder(schema.model, joinBuilder))
113
120
  .addService('relationFetcher', ({ whereBuilder, orderByBuilder, predicatesInjector, pathFactory }) =>
114
121
  new RelationFetcher(whereBuilder, orderByBuilder, predicatesInjector, pathFactory))
115
- .addService('fieldsVisitorFactory', ({ relationFetcher, predicateFactory, whereBuilder, schema }) =>
116
- new FieldsVisitorFactory(schema.model, relationFetcher, predicateFactory, whereBuilder))
122
+ .addService('fieldsVisitorFactory', ({ relationFetcher, predicateFactory, schema }) =>
123
+ new FieldsVisitorFactory(relationFetcher, predicateFactory, schema.settings.content ?? {}))
117
124
  .addService('metaHandler', ({ whereBuilder, predicateFactory }) =>
118
125
  new MetaHandler(whereBuilder, predicateFactory))
119
126
  .addService('uniqueWhereExpander', ({ schema }) =>
@@ -2,7 +2,7 @@ import { GraphQLFieldConfig } from 'graphql'
2
2
  import { Model } from '@contember/schema'
3
3
 
4
4
  export interface EntityFieldsProvider<ExtensionArg extends object = {}> {
5
- getFields(entity: Model.Entity, accessibleFields: string[]): FieldMap<ExtensionArg>
5
+ getFields(entity: Model.Entity, accessibleFields: Model.AnyField[]): FieldMap<ExtensionArg>
6
6
  }
7
7
 
8
8
  export type FieldMap<ExtensionArg extends object> = {
@@ -11,11 +11,18 @@ export class HasManyToHasOneReducer implements EntityFieldsProvider<HasManyToHas
11
11
  private readonly visitor: HasManyToHasOneRelationReducerFieldVisitor,
12
12
  ) {}
13
13
 
14
- getFields(entity: Model.Entity, fields: string[]): FieldMap<HasManyToHasOneReducerExtension> {
15
- return fields.reduce(
16
- (result, field) => ({ ...result, ...acceptFieldVisitor(this.schema, entity, field, this.visitor) }),
17
- {},
18
- )
14
+ getFields(entity: Model.Entity, accessibleFields: Model.AnyField[]): FieldMap<HasManyToHasOneReducerExtension> {
15
+ const fieldMap: FieldMap<HasManyToHasOneReducerExtension> = {}
16
+ for (const field of accessibleFields) {
17
+ if (field.type !== Model.RelationType.OneHasMany) {
18
+ continue
19
+ }
20
+
21
+ for (const [name, resultField] of acceptFieldVisitor(this.schema, entity, field, this.visitor)) {
22
+ fieldMap[name] = resultField
23
+ }
24
+ }
25
+ return fieldMap
19
26
  }
20
27
  }
21
28
 
@@ -1,21 +1,22 @@
1
1
  import { GraphQLInputObjectType, GraphQLNonNull } from 'graphql'
2
2
  import { Acl, Model } from '@contember/schema'
3
- import {
4
- aliasAwareResolver,
5
- EntityTypeProvider,
6
- FieldAccessVisitor,
7
- GqlTypeName,
8
- WhereTypeProvider,
9
- } from '../../schema'
3
+ import { aliasAwareResolver, EntityTypeProvider, FieldAccessVisitor, GqlTypeName, WhereTypeProvider } from '../../schema'
10
4
  import { acceptFieldVisitor } from '@contember/schema-utils'
11
5
  import { Authorizator } from '../../acl'
12
6
  import { getFieldsForUniqueWhere } from '../../utils'
13
- import { HasManyToHasOneReducerExtension } from './HasManyToHasOneReducer'
14
- import { FieldMap } from '../EntityFieldsProvider'
7
+ import { HasManyToHasOneReducer, HasManyToHasOneReducerExtension } from './HasManyToHasOneReducer'
8
+ import { GraphQLFieldConfig } from 'graphql'
9
+
10
+ type Result = [
11
+ string,
12
+ GraphQLFieldConfig<any, any> & {
13
+ extensions: HasManyToHasOneReducerExtension
14
+ }
15
+ ]
15
16
 
16
17
  export class HasManyToHasOneRelationReducerFieldVisitor implements
17
- Model.ColumnVisitor<FieldMap<HasManyToHasOneReducerExtension>>,
18
- Model.RelationByTypeVisitor<FieldMap<HasManyToHasOneReducerExtension>> {
18
+ Model.ColumnVisitor<Result[]>,
19
+ Model.RelationByTypeVisitor<Result[]> {
19
20
 
20
21
  constructor(
21
22
  private readonly schema: Model.Schema,
@@ -25,32 +26,32 @@ export class HasManyToHasOneRelationReducerFieldVisitor implements
25
26
  ) {}
26
27
 
27
28
  public visitColumn() {
28
- return {}
29
+ return []
29
30
  }
30
31
 
31
32
  public visitOneHasOneOwning() {
32
- return {}
33
+ return []
33
34
  }
34
35
 
35
36
  public visitOneHasOneInverse() {
36
- return {}
37
+ return []
37
38
  }
38
39
 
39
40
  public visitManyHasOne() {
40
- return {}
41
+ return []
41
42
  }
42
43
 
43
44
  public visitManyHasManyInverse() {
44
- return {}
45
+ return []
45
46
  }
46
47
 
47
48
  public visitManyHasManyOwning() {
48
- return {}
49
+ return []
49
50
  }
50
51
 
51
52
  public visitOneHasMany({ entity, targetEntity, targetRelation, relation }: Model.OneHasManyContext) {
52
53
  if (!targetRelation) {
53
- return {}
54
+ return []
54
55
  }
55
56
  const uniqueConstraints = getFieldsForUniqueWhere(this.schema, targetEntity)
56
57
  const composedUnique = uniqueConstraints
@@ -63,6 +64,8 @@ export class HasManyToHasOneRelationReducerFieldVisitor implements
63
64
  .map(fields => fields[0])
64
65
  .filter(it => it !== targetRelation.name)
65
66
 
67
+
68
+ const existing = new Set<string>()
66
69
  return [...composedUnique, ...singleUnique]
67
70
  .filter(field =>
68
71
  acceptFieldVisitor(
@@ -72,7 +75,11 @@ export class HasManyToHasOneRelationReducerFieldVisitor implements
72
75
  new FieldAccessVisitor(Acl.Operation.read, this.authorizator),
73
76
  ),
74
77
  )
75
- .reduce<FieldMap<HasManyToHasOneReducerExtension>>((fields, fieldName) => {
78
+ .map<Result | null>(fieldName => {
79
+ if (existing.has(fieldName)) {
80
+ return null
81
+ }
82
+ existing.add(fieldName)
76
83
  const graphQlName = relation.name + GqlTypeName`By${fieldName}`
77
84
  const uniqueWhere: GraphQLInputObjectType = new GraphQLInputObjectType({
78
85
  //todo this can be simplified to ${targetEntity.name}By${fieldName}, but singleton must be used
@@ -84,12 +91,13 @@ export class HasManyToHasOneRelationReducerFieldVisitor implements
84
91
 
85
92
  const entityType = this.entityTypeProvider.getEntity(targetEntity.name)
86
93
 
87
- return {
88
- ...fields,
89
- [graphQlName]: {
94
+ return [
95
+ graphQlName,
96
+ {
90
97
  type: entityType,
91
98
  extensions: {
92
99
  relationName: relation.name,
100
+ extensionKey: HasManyToHasOneReducer.extensionName,
93
101
  },
94
102
  args: {
95
103
  by: { type: new GraphQLNonNull(uniqueWhere) },
@@ -97,7 +105,8 @@ export class HasManyToHasOneRelationReducerFieldVisitor implements
97
105
  },
98
106
  resolve: aliasAwareResolver,
99
107
  },
100
- }
101
- }, {})
108
+ ]
109
+ })
110
+ .filter((it): it is Result => it !== null)
102
111
  }
103
112
  }
@@ -8,11 +8,14 @@ export class PaginatedHasManyFieldProvider implements EntityFieldsProvider<Pagin
8
8
 
9
9
  constructor(private readonly schema: Model.Schema, private readonly visitor: PaginatedHasManyFieldProviderVisitor) {}
10
10
 
11
- getFields(entity: Model.Entity, fields: string[]): FieldMap<PaginatedHasManyFieldProviderExtension> {
12
- return fields.reduce(
13
- (result, field) => ({ ...result, ...acceptFieldVisitor(this.schema, entity, field, this.visitor) }),
14
- {},
15
- )
11
+ getFields(entity: Model.Entity, accessibleFields: Model.AnyField[]): FieldMap<PaginatedHasManyFieldProviderExtension> {
12
+ const fields: FieldMap<PaginatedHasManyFieldProviderExtension> = {}
13
+ for (const field of accessibleFields) {
14
+ for (const [name, fieldConfig] of acceptFieldVisitor(this.schema, entity, field, this.visitor)) {
15
+ fields[name] = fieldConfig
16
+ }
17
+ }
18
+ return fields
16
19
  }
17
20
  }
18
21
 
@@ -1,13 +1,20 @@
1
1
  import { Model } from '@contember/schema'
2
- import { FieldMap } from '../EntityFieldsProvider'
3
- import { PaginatedHasManyFieldProviderExtension } from './PaginatedHasManyFieldProvider'
2
+ import { PaginatedHasManyFieldProvider, PaginatedHasManyFieldProviderExtension } from './PaginatedHasManyFieldProvider'
4
3
  import { capitalizeFirstLetter } from '../../utils'
5
4
  import { PaginatedFieldConfigFactory } from '../../schema/PaginatedFieldConfigFactory'
6
5
  import { aliasAwareResolver } from '../../schema'
6
+ import { GraphQLFieldConfig } from 'graphql'
7
+
8
+ type Result = [
9
+ string,
10
+ GraphQLFieldConfig<any, any> & {
11
+ extensions: PaginatedHasManyFieldProviderExtension
12
+ }
13
+ ]
7
14
 
8
15
  export class PaginatedHasManyFieldProviderVisitor implements
9
- Model.ColumnVisitor<FieldMap<PaginatedHasManyFieldProviderExtension>>,
10
- Model.RelationByTypeVisitor<FieldMap<PaginatedHasManyFieldProviderExtension>> {
16
+ Model.ColumnVisitor<Result[]>,
17
+ Model.RelationByTypeVisitor<Result[]> {
11
18
 
12
19
  constructor(private readonly paginatedFieldFactory: PaginatedFieldConfigFactory) {}
13
20
 
@@ -23,31 +30,35 @@ export class PaginatedHasManyFieldProviderVisitor implements
23
30
  return this.createField(targetEntity, relation)
24
31
  }
25
32
 
26
- private createField(entity: Model.Entity, relation: Model.Relation): FieldMap<PaginatedHasManyFieldProviderExtension> {
27
- return {
28
- [`paginate${capitalizeFirstLetter(relation.name)}`]: {
29
- ...this.paginatedFieldFactory.createFieldConfig(entity),
30
- extensions: {
31
- relationName: relation.name,
33
+ private createField(entity: Model.Entity, relation: Model.Relation): Result[] {
34
+ return [
35
+ [
36
+ `paginate${capitalizeFirstLetter(relation.name)}`,
37
+ {
38
+ ...this.paginatedFieldFactory.createFieldConfig(entity),
39
+ extensions: {
40
+ relationName: relation.name,
41
+ extensionKey: PaginatedHasManyFieldProvider.extensionName,
42
+ },
43
+ resolve: aliasAwareResolver,
32
44
  },
33
- resolve: aliasAwareResolver,
34
- },
35
- }
45
+ ],
46
+ ]
36
47
  }
37
48
 
38
49
  visitColumn() {
39
- return {}
50
+ return []
40
51
  }
41
52
 
42
53
  visitManyHasOne() {
43
- return {}
54
+ return []
44
55
  }
45
56
 
46
57
  visitOneHasOneInverse() {
47
- return {}
58
+ return []
48
59
  }
49
60
 
50
61
  visitOneHasOneOwning() {
51
- return {}
62
+ return []
52
63
  }
53
64
  }
@@ -1,21 +1,210 @@
1
- import { IExecutableSchemaDefinition } from '@graphql-tools/schema'
2
- import schema from './content-schema.graphql'
3
1
  import * as ContentSchema from './content-schema.types'
4
2
  import { IntrospectionSchemaFactory } from './IntrospectionSchemaFactory'
3
+ import { JSONType } from '@contember/graphql-utils'
5
4
 
6
- export class IntrospectionSchemaDefinitionFactory {
7
- constructor(private readonly introspectionSchemaFactory: IntrospectionSchemaFactory) {}
5
+ import {
6
+ GraphQLBoolean,
7
+ GraphQLEnumType,
8
+ GraphQLFieldResolver,
9
+ GraphQLInt,
10
+ GraphQLInterfaceType,
11
+ GraphQLList,
12
+ GraphQLNonNull,
13
+ GraphQLObjectType,
14
+ GraphQLSchema,
15
+ GraphQLSchemaConfig,
16
+ GraphQLString,
17
+ GraphQLUnionType,
18
+ } from 'graphql'
19
+
20
+ const _RuleMessage = new GraphQLObjectType({
21
+ name: '_RuleMessage',
22
+ fields: {
23
+ text: { type: GraphQLString },
24
+ },
25
+ })
26
+
27
+ const _ValidatorArgument = new GraphQLObjectType({
28
+ name: '_ValidatorArgument',
29
+ fields: {
30
+ validator: { type: new GraphQLNonNull(GraphQLInt) },
31
+ },
32
+ })
33
+
34
+ const _PathArgument = new GraphQLObjectType({
35
+ name: '_PathArgument',
36
+ fields: {
37
+ path: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))) },
38
+ },
39
+ })
40
+
41
+ const _LiteralArgument = new GraphQLObjectType({
42
+ name: '_LiteralArgument',
43
+ fields: {
44
+ value: { type: JSONType },
45
+ },
46
+ })
47
+
48
+ const _Argument = new GraphQLUnionType({
49
+ name: '_Argument',
50
+ types: [_ValidatorArgument, _PathArgument, _LiteralArgument],
51
+ })
52
+
53
+ const _Validator = new GraphQLObjectType({
54
+ name: '_Validator',
55
+ fields: {
56
+ operation: { type: new GraphQLNonNull(GraphQLString) },
57
+ arguments: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Argument))) },
58
+ },
59
+ })
60
+
61
+ const _Rule = new GraphQLObjectType({
62
+ name: '_Rule',
63
+ fields: {
64
+ message: { type: _RuleMessage },
65
+ validator: { type: new GraphQLNonNull(GraphQLInt) },
66
+ },
67
+ })
68
+
69
+ const _FieldInterface = new GraphQLInterfaceType({
70
+ name: '_Field',
71
+ fields: {
72
+ name: { type: new GraphQLNonNull(GraphQLString) },
73
+ type: { type: new GraphQLNonNull(GraphQLString) },
74
+ nullable: { type: GraphQLBoolean },
75
+ rules: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Rule))) },
76
+ validators: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Validator))) },
77
+ },
78
+ })
79
+
80
+ const _OrderByDirection = new GraphQLEnumType({
81
+ name: '_OrderByDirection',
82
+ values: {
83
+ asc: {},
84
+ desc: {},
85
+ },
86
+ })
87
+
88
+ const _OrderBy = new GraphQLObjectType({
89
+ name: '_OrderBy',
90
+ fields: {
91
+ path: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))) },
92
+ direction: { type: new GraphQLNonNull(_OrderByDirection) },
93
+ },
94
+ })
95
+
96
+ const _OnDeleteBehaviour = new GraphQLEnumType({
97
+ name: '_OnDeleteBehaviour',
98
+ values: {
99
+ restrict: {},
100
+ cascade: {},
101
+ setNull: {},
102
+ },
103
+ })
104
+
105
+ const _RelationSide = new GraphQLEnumType({
106
+ name: '_RelationSide',
107
+ values: {
108
+ owning: {},
109
+ inverse: {},
110
+ },
111
+ })
112
+
113
+ const _Relation = new GraphQLObjectType({
114
+ name: '_Relation',
115
+ interfaces: [_FieldInterface],
116
+ fields: {
117
+ name: { type: new GraphQLNonNull(GraphQLString) },
118
+ type: { type: new GraphQLNonNull(GraphQLString) },
119
+ side: { type: new GraphQLNonNull(_RelationSide) },
120
+ targetEntity: { type: new GraphQLNonNull(GraphQLString) },
121
+ ownedBy: { type: GraphQLString },
122
+ inversedBy: { type: GraphQLString },
123
+ nullable: { type: GraphQLBoolean },
124
+ onDelete: { type: _OnDeleteBehaviour },
125
+ orphanRemoval: { type: GraphQLBoolean },
126
+ orderBy: { type: new GraphQLList(new GraphQLNonNull(_OrderBy)) },
127
+ rules: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Rule))) },
128
+ validators: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Validator))) },
129
+ },
130
+ })
131
+
132
+ const _Column = new GraphQLObjectType({
133
+ name: '_Column',
134
+ interfaces: [_FieldInterface],
135
+ fields: {
136
+ name: { type: new GraphQLNonNull(GraphQLString) },
137
+ type: { type: new GraphQLNonNull(GraphQLString) },
138
+ enumName: { type: GraphQLString },
139
+ defaultValue: { type: JSONType },
140
+ nullable: { type: new GraphQLNonNull(GraphQLBoolean) },
141
+ rules: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Rule))) },
142
+ validators: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Validator))) },
143
+ },
144
+ })
8
145
 
9
- public create(): IExecutableSchemaDefinition {
10
- return {
11
- typeDefs: schema,
12
- resolvers: {
13
- Query: {
14
- schema: (): ContentSchema._Schema => {
15
- return this.introspectionSchemaFactory.create()
16
- },
146
+ const _UniqueConstraint = new GraphQLObjectType({
147
+ name: '_UniqueConstraint',
148
+ fields: {
149
+ fields: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))) },
150
+ },
151
+ })
152
+
153
+ const _Entity = new GraphQLObjectType({
154
+ name: '_Entity',
155
+ fields: {
156
+ name: { type: new GraphQLNonNull(GraphQLString) },
157
+ customPrimaryAllowed: { type: new GraphQLNonNull(GraphQLBoolean) },
158
+ fields: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_FieldInterface))) },
159
+ unique: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_UniqueConstraint))) },
160
+ },
161
+ })
162
+
163
+ const _Enum = new GraphQLObjectType({
164
+ name: '_Enum',
165
+ fields: {
166
+ name: { type: new GraphQLNonNull(GraphQLString) },
167
+ values: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))) },
168
+ },
169
+ })
170
+
171
+ const _Schema = new GraphQLObjectType({
172
+ name: '_Schema',
173
+ fields: {
174
+ enums: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Enum))) },
175
+ entities: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Entity))) },
176
+ },
177
+ })
178
+
179
+
180
+ const createSchemaConfig = (resolver?: GraphQLFieldResolver<any, any>): GraphQLSchemaConfig => {
181
+ return {
182
+ query: new GraphQLObjectType({
183
+ name: 'Query',
184
+ fields: {
185
+ schema: {
186
+ type: _Schema,
187
+ resolve: resolver,
17
188
  },
18
189
  },
19
- }
190
+ }),
191
+ types: [_Column, _Relation],
192
+ }
193
+ }
194
+
195
+
196
+ export default new GraphQLSchema(createSchemaConfig())
197
+
198
+ export class IntrospectionSchemaDefinitionFactory {
199
+ constructor(private readonly introspectionSchemaFactory: IntrospectionSchemaFactory) {}
200
+
201
+ public create(): GraphQLSchema {
202
+ return new GraphQLSchema(this.createConfig())
203
+ }
204
+
205
+ public createConfig(): GraphQLSchemaConfig {
206
+ return createSchemaConfig((): ContentSchema._Schema => {
207
+ return this.introspectionSchemaFactory.create()
208
+ })
20
209
  }
21
210
  }
@@ -1,4 +1,3 @@
1
- export { default as ContentSchema } from './content-schema.graphql'
2
1
  export * as ContentSchemaTypes from './content-schema.types'
3
- export * from './IntrospectionSchemaDefinitionFactory'
2
+ export { IntrospectionSchemaDefinitionFactory, default as ContentSchema } from './IntrospectionSchemaDefinitionFactory'
4
3
  export * from './IntrospectionSchemaFactory'
@@ -11,8 +11,9 @@ import {
11
11
  import * as Database from '@contember/database'
12
12
  import { UniqueWhereError } from '../inputProcessing'
13
13
  import { Model } from '@contember/schema'
14
- import { acceptFieldVisitor, SchemaDatabaseMetadata, tryGetColumnName } from '@contember/schema-utils'
14
+ import { acceptFieldVisitor, tryGetColumnName } from '@contember/schema-utils'
15
15
  import { logger } from '@contember/logger'
16
+ import { DatabaseMetadata } from '@contember/database'
16
17
 
17
18
 
18
19
  type UniqueConstraintResult = {
@@ -22,8 +23,8 @@ type UniqueConstraintResult = {
22
23
 
23
24
  const getEntityByTableName = (model: Model.Schema, tableName: string) => Object.values(model.entities).find(it => it.tableName === tableName)
24
25
 
25
- const findUniqueConstraint = (model: Model.Schema, databaseMetadata: SchemaDatabaseMetadata, tableName: string, constraintName: string): UniqueConstraintResult | null => {
26
- const constraint = databaseMetadata.getUniqueConstraint(tableName, constraintName)
26
+ const findUniqueConstraint = (model: Model.Schema, databaseMetadata: DatabaseMetadata, tableName: string, constraintName: string): UniqueConstraintResult | null => {
27
+ const constraint = databaseMetadata.uniqueConstraints.filter({ tableName, constraintName }).first()
27
28
  if (!constraint) {
28
29
  return null
29
30
  }
@@ -50,8 +51,8 @@ type RelationInfo = {
50
51
  targetEntity: Model.Entity
51
52
  }
52
53
 
53
- const findForeignConstraint = (model: Model.Schema, databaseMetadata: SchemaDatabaseMetadata, tableName: string, constraintName: string): RelationInfo | null => {
54
- const constraint = databaseMetadata.getForeignKeyConstraint(tableName, constraintName)
54
+ const findForeignConstraint = (model: Model.Schema, databaseMetadata: DatabaseMetadata, tableName: string, constraintName: string): RelationInfo | null => {
55
+ const constraint = databaseMetadata.foreignKeys.filter({ fromTable: tableName, constraintName }).first()
55
56
  if (!constraint) {
56
57
  return null
57
58
  }
@@ -88,7 +89,7 @@ const findForeignConstraint = (model: Model.Schema, databaseMetadata: SchemaData
88
89
 
89
90
  export const convertError = (
90
91
  schema: Model.Schema,
91
- databaseMetadata: SchemaDatabaseMetadata,
92
+ databaseMetadata: DatabaseMetadata,
92
93
  e: any,
93
94
  ): MutationResult => {
94
95
 
@@ -140,7 +141,7 @@ export const convertError = (
140
141
  throw e
141
142
  }
142
143
 
143
- export const tryMutation = async (schema: Model.Schema, databaseMetadata: SchemaDatabaseMetadata, cb: () => Promise<MutationResultList>): Promise<MutationResultList> => {
144
+ export const tryMutation = async (schema: Model.Schema, databaseMetadata: DatabaseMetadata, cb: () => Promise<MutationResultList>): Promise<MutationResultList> => {
144
145
  try {
145
146
  return await cb()
146
147
  } catch (e) {
@@ -1,5 +1,5 @@
1
1
  import { Input, Model } from '@contember/schema'
2
- import { acceptFieldVisitor, getColumnName, SchemaDatabaseMetadata } from '@contember/schema-utils'
2
+ import { acceptFieldVisitor, getColumnName } from '@contember/schema-utils'
3
3
  import {
4
4
  OrderByHelper,
5
5
  PathFactory,
@@ -10,7 +10,7 @@ import {
10
10
  SelectResultObject,
11
11
  WhereBuilder,
12
12
  } from './select'
13
- import { Client, Connection, ConstraintHelper, SelectBuilder } from '@contember/database'
13
+ import { Client, Connection, ConstraintHelper, DatabaseMetadata, SelectBuilder } from '@contember/database'
14
14
  import { PredicatesInjector } from '../acl'
15
15
  import { JunctionTableManager } from './JunctionTableManager'
16
16
  import { DeletedEntitiesStorage, DeleteExecutor } from './delete'
@@ -38,7 +38,7 @@ export class Mapper<ConnectionType extends Connection.ConnectionLike = Connectio
38
38
  public readonly identityId: string,
39
39
  public readonly transactionId: string,
40
40
  private readonly schema: Model.Schema,
41
- private readonly schemaDatabaseMetadata: SchemaDatabaseMetadata,
41
+ private readonly schemaDatabaseMetadata: DatabaseMetadata,
42
42
  private readonly predicatesInjector: PredicatesInjector,
43
43
  private readonly selectBuilderFactory: SelectBuilderFactory,
44
44
  private readonly uniqueWhereExpander: UniqueWhereExpander,
@@ -49,7 +49,7 @@ export class Mapper<ConnectionType extends Connection.ConnectionLike = Connectio
49
49
  private readonly inserter: Inserter,
50
50
  private readonly pathFactory: PathFactory,
51
51
  ) {
52
- this.constraintHelper = new ConstraintHelper(db)
52
+ this.constraintHelper = new ConstraintHelper(db, this.schemaDatabaseMetadata)
53
53
  this.eventManager = new EventManager(this)
54
54
  }
55
55