@contember/engine-content-api 1.3.6 → 1.4.0-alpha.2

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 (122) 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 +2 -0
  24. package/dist/src/introspection/IntrospectionSchemaDefinitionFactory.d.ts.map +1 -1
  25. package/dist/src/introspection/IntrospectionSchemaDefinitionFactory.js +18 -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/handlers/FieldsVisitor.d.ts +3 -5
  51. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts.map +1 -1
  52. package/dist/src/mapper/select/handlers/FieldsVisitor.js +8 -4
  53. package/dist/src/mapper/select/handlers/FieldsVisitor.js.map +1 -1
  54. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.d.ts +3 -5
  55. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.d.ts.map +1 -1
  56. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js +3 -4
  57. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js.map +1 -1
  58. package/dist/src/mapper/update/Updater.d.ts +2 -2
  59. package/dist/src/mapper/update/Updater.d.ts.map +1 -1
  60. package/dist/src/mapper/update/Updater.js.map +1 -1
  61. package/dist/src/resolvers/MutationResolver.d.ts +3 -2
  62. package/dist/src/resolvers/MutationResolver.d.ts.map +1 -1
  63. package/dist/src/resolvers/MutationResolver.js +20 -18
  64. package/dist/src/resolvers/MutationResolver.js.map +1 -1
  65. package/dist/src/schema/EntityTypeProvider.d.ts.map +1 -1
  66. package/dist/src/schema/EntityTypeProvider.js +23 -26
  67. package/dist/src/schema/EntityTypeProvider.js.map +1 -1
  68. package/dist/src/schema/GraphQlSchemaBuilder.d.ts.map +1 -1
  69. package/dist/src/schema/GraphQlSchemaBuilder.js +3 -1
  70. package/dist/src/schema/GraphQlSchemaBuilder.js.map +1 -1
  71. package/dist/src/tsconfig.tsbuildinfo +1 -1
  72. package/dist/tests/cases/integration/graphQlDb/update/deferedConstraints.test.js +1 -1
  73. package/dist/tests/cases/integration/graphQlDb/update/deferedConstraints.test.js.map +1 -1
  74. package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.d.ts +2 -0
  75. package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.d.ts.map +1 -0
  76. package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.js +170 -0
  77. package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.js.map +1 -0
  78. package/dist/tests/src/test.js +1 -1
  79. package/dist/tests/src/test.js.map +1 -1
  80. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  81. package/graphql.codegen.yml +1 -1
  82. package/package.json +12 -13
  83. package/src/ExecutionContainer.ts +13 -6
  84. package/src/extensions/EntityFieldsProvider.ts +1 -1
  85. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducer.ts +12 -5
  86. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.ts +33 -24
  87. package/src/extensions/paginatedHasMany/PaginatedHasManyFieldProvider.ts +8 -5
  88. package/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.ts +28 -17
  89. package/src/introspection/IntrospectionSchemaDefinitionFactory.ts +22 -14
  90. package/src/introspection/index.ts +1 -2
  91. package/src/mapper/ErrorUtils.ts +8 -7
  92. package/src/mapper/Mapper.ts +4 -4
  93. package/src/mapper/MapperFactory.ts +3 -3
  94. package/src/mapper/Result.ts +2 -3
  95. package/src/mapper/delete/DeleteExecutor.ts +1 -1
  96. package/src/mapper/insert/Inserter.ts +3 -2
  97. package/src/mapper/select/handlers/FieldsVisitor.ts +9 -5
  98. package/src/mapper/select/handlers/FieldsVisitorFactory.ts +3 -6
  99. package/src/mapper/update/Updater.ts +3 -2
  100. package/src/resolvers/MutationResolver.ts +29 -22
  101. package/src/schema/EntityTypeProvider.ts +32 -41
  102. package/src/schema/GraphQlSchemaBuilder.ts +3 -1
  103. package/tests/cases/integration/graphQlDb/update/deferedConstraints.test.ts +1 -1
  104. package/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.ts +169 -0
  105. package/tests/cases/integration/graphQlSchema/schema-acl-allowed.gql +1 -0
  106. package/tests/cases/integration/graphQlSchema/schema-acl-create-only.gql +1 -0
  107. package/tests/cases/integration/graphQlSchema/schema-acl-restricted-create.gql +1 -0
  108. package/tests/cases/integration/graphQlSchema/schema-acl-restricted-delete.gql +1 -0
  109. package/tests/cases/integration/graphQlSchema/schema-acl-restricted-update.gql +1 -0
  110. package/tests/cases/integration/graphQlSchema/schema-acl.gql +1 -0
  111. package/tests/cases/integration/graphQlSchema/schema-aliased-type.gql +1 -0
  112. package/tests/cases/integration/graphQlSchema/schema-basic.gql +1 -0
  113. package/tests/cases/integration/graphQlSchema/schema-bug-66.gql +1 -0
  114. package/tests/cases/integration/graphQlSchema/schema-custom-primary.gql +1 -0
  115. package/tests/cases/integration/graphQlSchema/schema-has-many-reduction.gql +1 -0
  116. package/tests/cases/integration/graphQlSchema/schema-new-builder.gql +1 -0
  117. package/tests/src/test.ts +3 -3
  118. package/dist/src/introspection/content-schema.graphql.d.ts +0 -4
  119. package/dist/src/introspection/content-schema.graphql.d.ts.map +0 -1
  120. package/dist/src/introspection/content-schema.graphql.js +0 -113
  121. package/dist/src/introspection/content-schema.graphql.js.map +0 -1
  122. 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.6",
3
+ "version": "1.4.0-alpha.2",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/src/index.js",
6
6
  "typings": "dist/src/index.d.ts",
@@ -13,20 +13,19 @@
13
13
  "test": "vitest --dir ./tests/cases --no-threads"
14
14
  },
15
15
  "dependencies": {
16
- "@contember/database": "1.3.6",
17
- "@contember/dic": "1.3.6",
18
- "@contember/graphql-utils": "1.3.6",
19
- "@contember/logger": "1.3.6",
20
- "@contember/schema": "1.3.6",
21
- "@contember/schema-definition": "1.3.6",
22
- "@contember/schema-utils": "1.3.6",
23
- "fast-deep-equal": "^3.1.3",
24
- "graphql-tag": "^2.12.5"
16
+ "@contember/database": "1.4.0-alpha.2",
17
+ "@contember/dic": "1.4.0-alpha.2",
18
+ "@contember/graphql-utils": "1.4.0-alpha.2",
19
+ "@contember/logger": "1.4.0-alpha.2",
20
+ "@contember/schema": "1.4.0-alpha.2",
21
+ "@contember/schema-definition": "1.4.0-alpha.2",
22
+ "@contember/schema-utils": "1.4.0-alpha.2",
23
+ "fast-deep-equal": "^3.1.3"
25
24
  },
26
25
  "devDependencies": {
27
- "@contember/database-tester": "1.3.6",
28
- "@contember/engine-api-tester": "1.3.6",
29
- "@contember/schema-definition": "1.3.6",
26
+ "@contember/database-tester": "1.4.0-alpha.2",
27
+ "@contember/engine-api-tester": "1.4.0-alpha.2",
28
+ "@contember/schema-definition": "1.4.0-alpha.2",
30
29
  "@graphql-codegen/cli": "^2.6.2",
31
30
  "@graphql-codegen/typescript": "^2.5.1",
32
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
  }
@@ -5,6 +5,7 @@ import { JSONType } from '@contember/graphql-utils'
5
5
  import {
6
6
  GraphQLBoolean,
7
7
  GraphQLEnumType,
8
+ GraphQLFieldResolver,
8
9
  GraphQLInt,
9
10
  GraphQLInterfaceType,
10
11
  GraphQLList,
@@ -176,6 +177,24 @@ const _Schema = new GraphQLObjectType({
176
177
  })
177
178
 
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,
188
+ },
189
+ },
190
+ }),
191
+ types: [_Column, _Relation],
192
+ }
193
+ }
194
+
195
+
196
+ export default new GraphQLSchema(createSchemaConfig())
197
+
179
198
  export class IntrospectionSchemaDefinitionFactory {
180
199
  constructor(private readonly introspectionSchemaFactory: IntrospectionSchemaFactory) {}
181
200
 
@@ -184,19 +203,8 @@ export class IntrospectionSchemaDefinitionFactory {
184
203
  }
185
204
 
186
205
  public createConfig(): GraphQLSchemaConfig {
187
- return {
188
- query: new GraphQLObjectType({
189
- name: 'Query',
190
- fields: {
191
- schema: {
192
- type: _Schema,
193
- resolve: (): ContentSchema._Schema => {
194
- return this.introspectionSchemaFactory.create()
195
- },
196
- },
197
- },
198
- }),
199
- types: [_Column, _Relation],
200
- }
206
+ return createSchemaConfig((): ContentSchema._Schema => {
207
+ return this.introspectionSchemaFactory.create()
208
+ })
201
209
  }
202
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
 
@@ -6,9 +6,9 @@ import { DeleteExecutor } from './delete'
6
6
  import { Updater } from './update'
7
7
  import { Inserter } from './insert'
8
8
  import { Model } from '@contember/schema'
9
- import { Client, Connection } from '@contember/database'
9
+ import { Client, Connection, DatabaseMetadata } from '@contember/database'
10
10
  import { Mapper } from './Mapper'
11
- import { Providers, SchemaDatabaseMetadata } from '@contember/schema-utils'
11
+ import { Providers } from '@contember/schema-utils'
12
12
 
13
13
  export type MapperFactoryHook = (mapper: Mapper) => void
14
14
 
@@ -20,7 +20,7 @@ export class MapperFactory {
20
20
  private readonly db: Client,
21
21
  private readonly identityId: string,
22
22
  private readonly schema: Model.Schema,
23
- private readonly schemaDatabaseMetadata: SchemaDatabaseMetadata,
23
+ private readonly schemaDatabaseMetadata: DatabaseMetadata,
24
24
  private readonly predicatesInjector: PredicatesInjector,
25
25
  private readonly selectBuilderFactory: SelectBuilderFactory,
26
26
  private readonly uniqueWhereExpander: UniqueWhereExpander,
@@ -1,9 +1,8 @@
1
1
  import { Input, Model, Value } from '@contember/schema'
2
2
  import { convertError } from './ErrorUtils'
3
3
  import { getFulfilledValues, getRejections } from '../utils'
4
- import { SerializationFailureError } from '@contember/database'
4
+ import { DatabaseMetadata, SerializationFailureError } from '@contember/database'
5
5
  import { logger } from '@contember/logger'
6
- import { SchemaDatabaseMetadata } from '@contember/schema-utils'
7
6
 
8
7
  export enum MutationResultType {
9
8
  ok = 'ok',
@@ -213,7 +212,7 @@ export type ResultListNotFlatten = MutationResultList | MutationResultList[]
213
212
 
214
213
  export const collectResults = async (
215
214
  schema: Model.Schema,
216
- schemaDatabaseMetadata: SchemaDatabaseMetadata,
215
+ schemaDatabaseMetadata: DatabaseMetadata,
217
216
  mainPromise: Promise<ResultListNotFlatten | undefined> | undefined,
218
217
  otherPromises: (Promise<ResultListNotFlatten | undefined> | undefined)[],
219
218
  ): Promise<MutationResultList> => {
@@ -252,7 +252,7 @@ export class DeleteExecutor {
252
252
  relation: Model.ManyHasOneRelation | Model.OneHasOneOwningRelation,
253
253
  values: Input.PrimaryValue[],
254
254
  ): Promise<void> {
255
- if (mapper.constraintHelper.areFkConstraintsDeferred()) {
255
+ if (mapper.constraintHelper.areConstraintsDeferred('foreignKey')) {
256
256
  return
257
257
  }
258
258
  const qb = this.createFetchByIdQueryBuilder(entity, relation, values)
@@ -11,16 +11,17 @@ import { CreateInputVisitor } from '../../inputProcessing'
11
11
  import { SqlCreateInputProcessor } from './SqlCreateInputProcessor'
12
12
  import { Mapper } from '../Mapper'
13
13
  import { Input, Model, Value } from '@contember/schema'
14
- import { acceptEveryFieldVisitor, Providers, SchemaDatabaseMetadata } from '@contember/schema-utils'
14
+ import { acceptEveryFieldVisitor, Providers } from '@contember/schema-utils'
15
15
  import { InsertBuilderFactory } from './InsertBuilderFactory'
16
16
  import { InsertBuilder } from './InsertBuilder'
17
17
  import { tryMutation } from '../ErrorUtils'
18
18
  import { rowDataToFieldValues } from '../ColumnValue'
19
+ import { DatabaseMetadata } from '@contember/database'
19
20
 
20
21
  export class Inserter {
21
22
  constructor(
22
23
  private readonly schema: Model.Schema,
23
- private readonly schemaDatabaseMetadata: SchemaDatabaseMetadata,
24
+ private readonly schemaDatabaseMetadata: DatabaseMetadata,
24
25
  private readonly insertBuilderFactory: InsertBuilderFactory,
25
26
  private readonly providers: Providers,
26
27
  ) {}
@@ -1,19 +1,18 @@
1
- import { Acl, Input, Model } from '@contember/schema'
1
+ import { Acl, Input, Model, Settings } from '@contember/schema'
2
2
  import { Mapper } from '../../Mapper'
3
3
  import { RelationFetcher } from '../RelationFetcher'
4
4
  import { SelectExecutionHandlerContext } from '../SelectExecutionHandler'
5
5
  import { PredicateFactory } from '../../../acl'
6
- import { WhereBuilder } from '../WhereBuilder'
6
+ import { Literal, wrapIdentifier } from '@contember/database'
7
7
 
8
8
  export class FieldsVisitor implements Model.RelationByTypeVisitor<void>, Model.ColumnVisitor<void> {
9
9
  constructor(
10
- private readonly schema: Model.Schema,
11
10
  private readonly relationFetcher: RelationFetcher,
12
11
  private readonly predicateFactory: PredicateFactory,
13
- private readonly whereBuilder: WhereBuilder,
14
12
  private readonly mapper: Mapper,
15
13
  private readonly executionContext: SelectExecutionHandlerContext,
16
14
  private readonly relationPath: Model.AnyRelationContext[],
15
+ private readonly settings: Settings.ContentSettings,
17
16
  ) {}
18
17
 
19
18
  visitColumn({ entity, column }: Model.ColumnContext): void {
@@ -21,8 +20,13 @@ export class FieldsVisitor implements Model.RelationByTypeVisitor<void>, Model.C
21
20
  const tableAlias = columnPath.back().alias
22
21
  const columnAlias = columnPath.alias
23
22
 
23
+ let selectFrom = wrapIdentifier(tableAlias) + '.' + wrapIdentifier(column.columnName)
24
+ if (column.type === Model.ColumnType.Date && this.settings.shortDateResponse) {
25
+ selectFrom += '::text'
26
+ }
27
+
24
28
  this.executionContext.addColumn({
25
- query: qb => qb.select([tableAlias, column.columnName], columnAlias),
29
+ query: qb => qb.select(new Literal(selectFrom), columnAlias),
26
30
  predicate: this.getRequiredPredicate(entity, column),
27
31
  })
28
32
  }
@@ -1,28 +1,25 @@
1
1
  import { FieldsVisitor } from './FieldsVisitor'
2
2
  import { RelationFetcher } from '../RelationFetcher'
3
- import { Model } from '@contember/schema'
4
3
  import { Mapper } from '../../Mapper'
5
4
  import { SelectExecutionHandlerContext } from '../SelectExecutionHandler'
6
5
  import { PredicateFactory } from '../../../acl'
7
- import { WhereBuilder } from '../WhereBuilder'
6
+ import { Settings } from '@contember/schema'
8
7
 
9
8
  export class FieldsVisitorFactory {
10
9
  constructor(
11
- private readonly schema: Model.Schema,
12
10
  private readonly relationFetcher: RelationFetcher,
13
11
  private readonly predicateFactory: PredicateFactory,
14
- private readonly whereBuilder: WhereBuilder,
12
+ private readonly settings: Settings.ContentSettings,
15
13
  ) {}
16
14
 
17
15
  create(mapper: Mapper, context: SelectExecutionHandlerContext): FieldsVisitor {
18
16
  return new FieldsVisitor(
19
- this.schema,
20
17
  this.relationFetcher,
21
18
  this.predicateFactory,
22
- this.whereBuilder,
23
19
  mapper,
24
20
  context,
25
21
  context.relationPath,
22
+ this.settings,
26
23
  )
27
24
  }
28
25
  }
@@ -4,7 +4,7 @@ import { Input, Model } from '@contember/schema'
4
4
  import { PredicateFactory } from '../../acl'
5
5
  import { UpdateBuilderFactory } from './UpdateBuilderFactory'
6
6
  import { Mapper } from '../Mapper'
7
- import { acceptEveryFieldVisitor, SchemaDatabaseMetadata } from '@contember/schema-utils'
7
+ import { acceptEveryFieldVisitor } from '@contember/schema-utils'
8
8
  import {
9
9
  collectResults,
10
10
  MutationNoResultError,
@@ -17,11 +17,12 @@ import {
17
17
  } from '../Result'
18
18
  import { UpdateBuilder } from './UpdateBuilder'
19
19
  import { rowDataToFieldValues } from '../ColumnValue'
20
+ import { DatabaseMetadata } from '@contember/database'
20
21
 
21
22
  export class Updater {
22
23
  constructor(
23
24
  private readonly schema: Model.Schema,
24
- private readonly schemaDatabaseMetadata: SchemaDatabaseMetadata,
25
+ private readonly schemaDatabaseMetadata: DatabaseMetadata,
25
26
  private readonly predicateFactory: PredicateFactory,
26
27
  private readonly updateBuilderFactory: UpdateBuilderFactory,
27
28
  ) {}