@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.
- package/dist/src/ExecutionContainer.d.ts +4 -4
- package/dist/src/ExecutionContainer.d.ts.map +1 -1
- package/dist/src/ExecutionContainer.js +5 -2
- package/dist/src/ExecutionContainer.js.map +1 -1
- package/dist/src/extensions/EntityFieldsProvider.d.ts +1 -1
- package/dist/src/extensions/EntityFieldsProvider.d.ts.map +1 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducer.d.ts +1 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducer.d.ts.map +1 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducer.js +12 -2
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducer.js.map +1 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts +16 -9
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts.map +1 -1
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js +21 -13
- package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProvider.d.ts +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProvider.d.ts.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProvider.js +8 -2
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProvider.js.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts +16 -9
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts.map +1 -1
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js +17 -12
- package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js.map +1 -1
- package/dist/src/introspection/IntrospectionSchemaDefinitionFactory.d.ts +5 -2
- package/dist/src/introspection/IntrospectionSchemaDefinitionFactory.d.ts.map +1 -1
- package/dist/src/introspection/IntrospectionSchemaDefinitionFactory.js +164 -14
- package/dist/src/introspection/IntrospectionSchemaDefinitionFactory.js.map +1 -1
- package/dist/src/introspection/index.d.ts +1 -2
- package/dist/src/introspection/index.d.ts.map +1 -1
- package/dist/src/introspection/index.js +4 -4
- package/dist/src/introspection/index.js.map +1 -1
- package/dist/src/mapper/ErrorUtils.d.ts +3 -3
- 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/Mapper.d.ts +2 -3
- package/dist/src/mapper/Mapper.d.ts.map +1 -1
- package/dist/src/mapper/Mapper.js +1 -1
- package/dist/src/mapper/Mapper.js.map +1 -1
- package/dist/src/mapper/MapperFactory.d.ts +3 -3
- package/dist/src/mapper/MapperFactory.d.ts.map +1 -1
- package/dist/src/mapper/MapperFactory.js.map +1 -1
- package/dist/src/mapper/Result.d.ts +2 -2
- package/dist/src/mapper/Result.d.ts.map +1 -1
- package/dist/src/mapper/Result.js.map +1 -1
- package/dist/src/mapper/delete/DeleteExecutor.js +1 -1
- package/dist/src/mapper/delete/DeleteExecutor.js.map +1 -1
- package/dist/src/mapper/insert/Inserter.d.ts +3 -2
- package/dist/src/mapper/insert/Inserter.d.ts.map +1 -1
- package/dist/src/mapper/insert/Inserter.js.map +1 -1
- package/dist/src/mapper/select/RelationFetcher.d.ts.map +1 -1
- package/dist/src/mapper/select/RelationFetcher.js +8 -7
- package/dist/src/mapper/select/RelationFetcher.js.map +1 -1
- package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts +3 -5
- package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts.map +1 -1
- package/dist/src/mapper/select/handlers/FieldsVisitor.js +8 -4
- package/dist/src/mapper/select/handlers/FieldsVisitor.js.map +1 -1
- package/dist/src/mapper/select/handlers/FieldsVisitorFactory.d.ts +3 -5
- package/dist/src/mapper/select/handlers/FieldsVisitorFactory.d.ts.map +1 -1
- package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js +3 -4
- package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js.map +1 -1
- package/dist/src/mapper/update/Updater.d.ts +2 -2
- package/dist/src/mapper/update/Updater.d.ts.map +1 -1
- package/dist/src/mapper/update/Updater.js.map +1 -1
- package/dist/src/resolvers/MutationResolver.d.ts +3 -2
- package/dist/src/resolvers/MutationResolver.d.ts.map +1 -1
- package/dist/src/resolvers/MutationResolver.js +20 -18
- package/dist/src/resolvers/MutationResolver.js.map +1 -1
- package/dist/src/schema/EntityTypeProvider.d.ts.map +1 -1
- package/dist/src/schema/EntityTypeProvider.js +23 -26
- package/dist/src/schema/EntityTypeProvider.js.map +1 -1
- package/dist/src/schema/GraphQlSchemaBuilder.d.ts +10 -2
- package/dist/src/schema/GraphQlSchemaBuilder.d.ts.map +1 -1
- package/dist/src/schema/GraphQlSchemaBuilder.js +47 -37
- package/dist/src/schema/GraphQlSchemaBuilder.js.map +1 -1
- package/dist/src/schema/ResultSchemaTypeProvider.d.ts +4 -0
- package/dist/src/schema/ResultSchemaTypeProvider.d.ts.map +1 -1
- package/dist/src/schema/ResultSchemaTypeProvider.js +27 -23
- package/dist/src/schema/ResultSchemaTypeProvider.js.map +1 -1
- package/dist/src/tsconfig.tsbuildinfo +1 -1
- package/dist/tests/cases/integration/graphQlDb/update/deferedConstraints.test.js +1 -1
- package/dist/tests/cases/integration/graphQlDb/update/deferedConstraints.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.d.ts +2 -0
- package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.js +170 -0
- package/dist/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.js.map +1 -0
- package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.js +44 -0
- package/dist/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.js.map +1 -1
- package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js +20 -0
- package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js.map +1 -1
- package/dist/tests/src/test.js +1 -1
- package/dist/tests/src/test.js.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/graphql.codegen.yml +1 -1
- package/package.json +12 -14
- package/src/ExecutionContainer.ts +13 -6
- package/src/extensions/EntityFieldsProvider.ts +1 -1
- package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducer.ts +12 -5
- package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.ts +33 -24
- package/src/extensions/paginatedHasMany/PaginatedHasManyFieldProvider.ts +8 -5
- package/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.ts +28 -17
- package/src/introspection/IntrospectionSchemaDefinitionFactory.ts +202 -13
- package/src/introspection/index.ts +1 -2
- package/src/mapper/ErrorUtils.ts +8 -7
- package/src/mapper/Mapper.ts +4 -4
- package/src/mapper/MapperFactory.ts +3 -3
- package/src/mapper/Result.ts +2 -3
- package/src/mapper/delete/DeleteExecutor.ts +1 -1
- package/src/mapper/insert/Inserter.ts +3 -2
- package/src/mapper/select/RelationFetcher.ts +8 -4
- package/src/mapper/select/handlers/FieldsVisitor.ts +9 -5
- package/src/mapper/select/handlers/FieldsVisitorFactory.ts +3 -6
- package/src/mapper/update/Updater.ts +3 -2
- package/src/resolvers/MutationResolver.ts +29 -22
- package/src/schema/EntityTypeProvider.ts +32 -41
- package/src/schema/GraphQlSchemaBuilder.ts +61 -40
- package/src/schema/ResultSchemaTypeProvider.ts +29 -27
- package/tests/cases/integration/graphQlDb/update/deferedConstraints.test.ts +1 -1
- package/tests/cases/integration/graphQlDb/update/deferredUniqueConstraints.test.ts +169 -0
- package/tests/cases/integration/graphQlRequests/query/relations/manyHasManyOwning.test.ts +45 -0
- package/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.ts +24 -0
- package/tests/cases/integration/graphQlSchema/schema-acl-allowed.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-acl-create-only.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-acl-restricted-create.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-acl-restricted-delete.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-acl-restricted-update.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-acl.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-aliased-type.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-basic.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-bug-66.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-custom-primary.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-has-many-reduction.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-new-builder.gql +1 -0
- package/tests/cases/integration/graphQlSchema/schema-read-only.gql +116 -0
- package/tests/src/test.ts +3 -3
- package/dist/src/introspection/content-schema.graphql.d.ts +0 -4
- package/dist/src/introspection/content-schema.graphql.d.ts.map +0 -1
- package/dist/src/introspection/content-schema.graphql.js +0 -113
- package/dist/src/introspection/content-schema.graphql.js.map +0 -1
- package/src/introspection/content-schema.graphql.ts +0 -113
|
@@ -12,24 +12,33 @@ import {
|
|
|
12
12
|
} from 'graphql'
|
|
13
13
|
|
|
14
14
|
export class ResultSchemaTypeProvider {
|
|
15
|
+
private fieldPathFragmentType = new GraphQLObjectType({
|
|
16
|
+
name: '_FieldPathFragment',
|
|
17
|
+
fields: {
|
|
18
|
+
field: { type: new GraphQLNonNull(GraphQLString) },
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
private indexPathFragmentType = new GraphQLObjectType({
|
|
22
|
+
name: '_IndexPathFragment',
|
|
23
|
+
fields: {
|
|
24
|
+
index: { type: new GraphQLNonNull(GraphQLInt) },
|
|
25
|
+
alias: { type: GraphQLString },
|
|
26
|
+
},
|
|
27
|
+
})
|
|
15
28
|
private pathFragmentType = new GraphQLUnionType({
|
|
16
29
|
name: '_PathFragment',
|
|
17
30
|
types: () => [
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
fields: {
|
|
21
|
-
field: { type: new GraphQLNonNull(GraphQLString) },
|
|
22
|
-
},
|
|
23
|
-
}),
|
|
24
|
-
new GraphQLObjectType({
|
|
25
|
-
name: '_IndexPathFragment',
|
|
26
|
-
fields: {
|
|
27
|
-
index: { type: new GraphQLNonNull(GraphQLInt) },
|
|
28
|
-
alias: { type: GraphQLString },
|
|
29
|
-
},
|
|
30
|
-
}),
|
|
31
|
+
this.fieldPathFragmentType,
|
|
32
|
+
this.indexPathFragmentType,
|
|
31
33
|
],
|
|
32
34
|
})
|
|
35
|
+
|
|
36
|
+
private validationMessageType = new GraphQLObjectType({
|
|
37
|
+
name: '_ValidationMessage',
|
|
38
|
+
fields: {
|
|
39
|
+
text: { type: new GraphQLNonNull(GraphQLString) },
|
|
40
|
+
},
|
|
41
|
+
})
|
|
33
42
|
private validationErrorType = new GraphQLObjectType({
|
|
34
43
|
name: '_ValidationError',
|
|
35
44
|
fields: {
|
|
@@ -37,14 +46,7 @@ export class ResultSchemaTypeProvider {
|
|
|
37
46
|
type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(this.pathFragmentType))),
|
|
38
47
|
},
|
|
39
48
|
message: {
|
|
40
|
-
type: new GraphQLNonNull(
|
|
41
|
-
new GraphQLObjectType({
|
|
42
|
-
name: '_ValidationMessage',
|
|
43
|
-
fields: {
|
|
44
|
-
text: { type: new GraphQLNonNull(GraphQLString) },
|
|
45
|
-
},
|
|
46
|
-
}),
|
|
47
|
-
),
|
|
49
|
+
type: new GraphQLNonNull(this.validationMessageType),
|
|
48
50
|
},
|
|
49
51
|
},
|
|
50
52
|
})
|
|
@@ -58,6 +60,11 @@ export class ResultSchemaTypeProvider {
|
|
|
58
60
|
},
|
|
59
61
|
})
|
|
60
62
|
|
|
63
|
+
private mutationErrorType = new GraphQLEnumType({
|
|
64
|
+
name: '_MutationErrorType',
|
|
65
|
+
values: Object.values(Result.ExecutionErrorType).reduce((acc, type) => ({ ...acc, [type]: {} }), {}),
|
|
66
|
+
})
|
|
67
|
+
|
|
61
68
|
public errorResultType = new GraphQLObjectType({
|
|
62
69
|
name: '_MutationError',
|
|
63
70
|
fields: {
|
|
@@ -71,12 +78,7 @@ export class ResultSchemaTypeProvider {
|
|
|
71
78
|
),
|
|
72
79
|
},
|
|
73
80
|
type: {
|
|
74
|
-
type: new GraphQLNonNull(
|
|
75
|
-
new GraphQLEnumType({
|
|
76
|
-
name: '_MutationErrorType',
|
|
77
|
-
values: Object.values(Result.ExecutionErrorType).reduce((acc, type) => ({ ...acc, [type]: {} }), {}),
|
|
78
|
-
}),
|
|
79
|
-
),
|
|
81
|
+
type: new GraphQLNonNull(this.mutationErrorType),
|
|
80
82
|
},
|
|
81
83
|
message: { type: GraphQLString },
|
|
82
84
|
},
|
|
@@ -196,7 +196,7 @@ test('delete with unsuccessfully deferring constraints', async () => {
|
|
|
196
196
|
ok: false,
|
|
197
197
|
errorMessage: 'Execution has failed:\nunknown field: ForeignKeyConstraintViolation (Cannot delete row 123e4567-e89b-12d3-a456-000000000004 of entity Attachment, because it is still referenced from Reference::attachment. This is possibly caused by ACL denial or by missing "on delete cascade")',
|
|
198
198
|
updatePost: {
|
|
199
|
-
ok:
|
|
199
|
+
ok: true,
|
|
200
200
|
errorMessage: null,
|
|
201
201
|
},
|
|
202
202
|
},
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { test } from 'vitest'
|
|
2
|
+
import { c, createSchema } from '@contember/schema-definition'
|
|
3
|
+
import { GQL } from '../../../../src/tags'
|
|
4
|
+
import { testUuid } from '../../../../src/testUuid'
|
|
5
|
+
import { executeDbTest } from '@contember/engine-api-tester'
|
|
6
|
+
|
|
7
|
+
namespace DeferredUniqueModel {
|
|
8
|
+
export class Post {
|
|
9
|
+
slug = c.stringColumn().unique()
|
|
10
|
+
order = c.intColumn().unique({ timing: 'deferrable' })
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
test('update without deferring unique constraints', async () => {
|
|
15
|
+
await executeDbTest({
|
|
16
|
+
schema: createSchema(DeferredUniqueModel),
|
|
17
|
+
seed: [
|
|
18
|
+
{
|
|
19
|
+
query: `mutation {
|
|
20
|
+
postA: createPost(data: {slug: "a", order: 1}) {
|
|
21
|
+
ok
|
|
22
|
+
node {
|
|
23
|
+
id
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
postB: createPost(data: {slug: "b", order: 2}) {
|
|
27
|
+
ok
|
|
28
|
+
node {
|
|
29
|
+
id
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}`,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
query: GQL`
|
|
36
|
+
mutation {
|
|
37
|
+
transaction {
|
|
38
|
+
ok
|
|
39
|
+
errorMessage
|
|
40
|
+
upA: updatePost(by: {slug: "a"}, data: {order: 2}) {
|
|
41
|
+
ok
|
|
42
|
+
errorMessage
|
|
43
|
+
}
|
|
44
|
+
upB: updatePost(by: {slug: "b"}, data: {order: 1}) {
|
|
45
|
+
ok
|
|
46
|
+
errorMessage
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
`,
|
|
51
|
+
return: {
|
|
52
|
+
transaction: {
|
|
53
|
+
ok: false,
|
|
54
|
+
errorMessage: 'Execution has failed:\nupA.order: UniqueConstraintViolation (Value (2) already exists in unique columns (order) on entity Post)',
|
|
55
|
+
upA: {
|
|
56
|
+
ok: false,
|
|
57
|
+
errorMessage: 'Execution has failed:\norder: UniqueConstraintViolation (Value (2) already exists in unique columns (order) on entity Post)',
|
|
58
|
+
},
|
|
59
|
+
upB: {
|
|
60
|
+
ok: false,
|
|
61
|
+
errorMessage: null,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('update with deferring unique constraints', async () => {
|
|
69
|
+
await executeDbTest({
|
|
70
|
+
schema: createSchema(DeferredUniqueModel),
|
|
71
|
+
seed: [
|
|
72
|
+
{
|
|
73
|
+
query: `mutation {
|
|
74
|
+
|
|
75
|
+
postA: createPost(data: {slug: "a", order: 1}) {
|
|
76
|
+
ok
|
|
77
|
+
node {
|
|
78
|
+
id
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
postB: createPost(data: {slug: "b", order: 2}) {
|
|
82
|
+
ok
|
|
83
|
+
node {
|
|
84
|
+
id
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}`,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
query: GQL`
|
|
91
|
+
mutation {
|
|
92
|
+
transaction(options: {deferUniqueConstraints: true}) {
|
|
93
|
+
ok
|
|
94
|
+
errorMessage
|
|
95
|
+
upA: updatePost(by: {slug: "a"}, data: {order: 2}) {
|
|
96
|
+
ok
|
|
97
|
+
errorMessage
|
|
98
|
+
}
|
|
99
|
+
upB: updatePost(by: {slug: "b"}, data: {order: 1}) {
|
|
100
|
+
ok
|
|
101
|
+
errorMessage
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
`,
|
|
106
|
+
return: {
|
|
107
|
+
transaction: {
|
|
108
|
+
ok: true,
|
|
109
|
+
errorMessage: null,
|
|
110
|
+
upA: {
|
|
111
|
+
ok: true,
|
|
112
|
+
errorMessage: null,
|
|
113
|
+
},
|
|
114
|
+
upB: {
|
|
115
|
+
ok: true,
|
|
116
|
+
errorMessage: null,
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
test('update with failed deferred unique constraints', async () => {
|
|
125
|
+
await executeDbTest({
|
|
126
|
+
schema: createSchema(DeferredUniqueModel),
|
|
127
|
+
seed: [
|
|
128
|
+
{
|
|
129
|
+
query: `mutation {
|
|
130
|
+
|
|
131
|
+
postA: createPost(data: {slug: "a", order: 1}) {
|
|
132
|
+
ok
|
|
133
|
+
node {
|
|
134
|
+
id
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
postB: createPost(data: {slug: "b", order: 2}) {
|
|
138
|
+
ok
|
|
139
|
+
node {
|
|
140
|
+
id
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}`,
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
query: GQL`
|
|
147
|
+
mutation {
|
|
148
|
+
transaction(options: {deferUniqueConstraints: true}) {
|
|
149
|
+
ok
|
|
150
|
+
errorMessage
|
|
151
|
+
upA: updatePost(by: {slug: "a"}, data: {order: 2}) {
|
|
152
|
+
ok
|
|
153
|
+
errorMessage
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
`,
|
|
158
|
+
return: {
|
|
159
|
+
transaction: {
|
|
160
|
+
ok: false,
|
|
161
|
+
errorMessage: 'Execution has failed:\norder: UniqueConstraintViolation (Value (2) already exists in unique columns (order) on entity Post)',
|
|
162
|
+
upA: {
|
|
163
|
+
ok: true,
|
|
164
|
+
errorMessage: null,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
})
|
|
169
|
+
})
|
|
@@ -194,3 +194,48 @@ test('Posts with paginated tags (many has many owning)', async () => {
|
|
|
194
194
|
})
|
|
195
195
|
|
|
196
196
|
|
|
197
|
+
test('large number of posts - use array', async () => {
|
|
198
|
+
const ids = Array.from({ length: 1000 }).map((it, index) => testUuid(index + 1))
|
|
199
|
+
await execute({
|
|
200
|
+
schema: new SchemaBuilder()
|
|
201
|
+
.entity('Post', entity => entity.manyHasMany('tags', relation => relation.target('Tag')))
|
|
202
|
+
.entity('Tag', entity => entity.column('name'))
|
|
203
|
+
.buildSchema(),
|
|
204
|
+
query: GQL`
|
|
205
|
+
query {
|
|
206
|
+
listPost {
|
|
207
|
+
id
|
|
208
|
+
tags {
|
|
209
|
+
name
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
`,
|
|
214
|
+
executes: [
|
|
215
|
+
{
|
|
216
|
+
sql: SQL`select "root_"."id" as "root_id",
|
|
217
|
+
"root_"."id" as "root_id"
|
|
218
|
+
from "public"."post" as "root_"`,
|
|
219
|
+
response: {
|
|
220
|
+
rows: ids.map(id => ({ root_id: id })),
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
sql: SQL`select "junction_"."tag_id", "junction_"."post_id" from "public"."post_tags" as "junction_" where "junction_"."post_id" = any(?::uuid[])`,
|
|
225
|
+
parameters: [ids],
|
|
226
|
+
response: {
|
|
227
|
+
rows: [],
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
return: {
|
|
232
|
+
data: {
|
|
233
|
+
listPost: ids.map(id => ({
|
|
234
|
+
id,
|
|
235
|
+
tags: [],
|
|
236
|
+
})),
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
})
|
|
240
|
+
})
|
|
241
|
+
|
|
@@ -114,6 +114,30 @@ describe('GraphQL schema builder', () => {
|
|
|
114
114
|
})
|
|
115
115
|
})
|
|
116
116
|
|
|
117
|
+
it('read only', async () => {
|
|
118
|
+
await testSchema({
|
|
119
|
+
schema: builder =>
|
|
120
|
+
builder.entity('Test', e =>
|
|
121
|
+
e
|
|
122
|
+
.column('a', c => c.type(Model.ColumnType.String))
|
|
123
|
+
.column('b', c => c.type(Model.ColumnType.String)),
|
|
124
|
+
),
|
|
125
|
+
permissions: () => ({
|
|
126
|
+
Test: {
|
|
127
|
+
predicates: {},
|
|
128
|
+
operations: {
|
|
129
|
+
read: {
|
|
130
|
+
id: true,
|
|
131
|
+
a: true,
|
|
132
|
+
b: true,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
}),
|
|
137
|
+
graphQlSchemaFile: 'schema-read-only.gql',
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
|
|
117
141
|
|
|
118
142
|
it('conditionally restricted read of some fields', async () => {
|
|
119
143
|
await testSchema({
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
type Query {
|
|
2
|
+
getTest(by: TestUniqueWhere!, filter: TestWhere): Test
|
|
3
|
+
listTest(filter: TestWhere, orderBy: [TestOrderBy!], offset: Int, limit: Int): [Test!]!
|
|
4
|
+
paginateTest(filter: TestWhere, orderBy: [TestOrderBy!], skip: Int, first: Int): TestConnection!
|
|
5
|
+
transaction: QueryTransaction
|
|
6
|
+
_info: Info
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type Test {
|
|
10
|
+
_meta: TestMeta
|
|
11
|
+
id: UUID!
|
|
12
|
+
a: String
|
|
13
|
+
b: String
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type TestMeta {
|
|
17
|
+
id: FieldMeta
|
|
18
|
+
a: FieldMeta
|
|
19
|
+
b: FieldMeta
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type FieldMeta {
|
|
23
|
+
readable: Boolean
|
|
24
|
+
updatable: Boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
scalar UUID
|
|
28
|
+
|
|
29
|
+
input TestUniqueWhere {
|
|
30
|
+
id: UUID
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
input TestWhere {
|
|
34
|
+
id: UUIDCondition
|
|
35
|
+
a: StringCondition
|
|
36
|
+
b: StringCondition
|
|
37
|
+
and: [TestWhere]
|
|
38
|
+
or: [TestWhere]
|
|
39
|
+
not: TestWhere
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
input UUIDCondition {
|
|
43
|
+
and: [UUIDCondition!]
|
|
44
|
+
or: [UUIDCondition!]
|
|
45
|
+
not: UUIDCondition
|
|
46
|
+
null: Boolean
|
|
47
|
+
isNull: Boolean
|
|
48
|
+
eq: UUID
|
|
49
|
+
notEq: UUID
|
|
50
|
+
in: [UUID!]
|
|
51
|
+
notIn: [UUID!]
|
|
52
|
+
lt: UUID
|
|
53
|
+
lte: UUID
|
|
54
|
+
gt: UUID
|
|
55
|
+
gte: UUID
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
input StringCondition {
|
|
59
|
+
and: [StringCondition!]
|
|
60
|
+
or: [StringCondition!]
|
|
61
|
+
not: StringCondition
|
|
62
|
+
null: Boolean
|
|
63
|
+
isNull: Boolean
|
|
64
|
+
eq: String
|
|
65
|
+
notEq: String
|
|
66
|
+
in: [String!]
|
|
67
|
+
notIn: [String!]
|
|
68
|
+
lt: String
|
|
69
|
+
lte: String
|
|
70
|
+
gt: String
|
|
71
|
+
gte: String
|
|
72
|
+
contains: String
|
|
73
|
+
startsWith: String
|
|
74
|
+
endsWith: String
|
|
75
|
+
containsCI: String
|
|
76
|
+
startsWithCI: String
|
|
77
|
+
endsWithCI: String
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
input TestOrderBy {
|
|
81
|
+
_random: Boolean
|
|
82
|
+
_randomSeeded: Int
|
|
83
|
+
id: OrderDirection
|
|
84
|
+
a: OrderDirection
|
|
85
|
+
b: OrderDirection
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
enum OrderDirection {
|
|
89
|
+
asc
|
|
90
|
+
desc
|
|
91
|
+
ascNullsFirst
|
|
92
|
+
descNullsLast
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
type TestConnection {
|
|
96
|
+
pageInfo: PageInfo!
|
|
97
|
+
edges: [TestEdge!]!
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
type PageInfo {
|
|
101
|
+
totalCount: Int!
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
type TestEdge {
|
|
105
|
+
node: Test!
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
type QueryTransaction {
|
|
109
|
+
getTest(by: TestUniqueWhere!, filter: TestWhere): Test
|
|
110
|
+
listTest(filter: TestWhere, orderBy: [TestOrderBy!], offset: Int, limit: Int): [Test!]!
|
|
111
|
+
paginateTest(filter: TestWhere, orderBy: [TestOrderBy!], skip: Int, first: Int): TestConnection!
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
type Info {
|
|
115
|
+
description: String
|
|
116
|
+
}
|
package/tests/src/test.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Acl, Model, Schema, Validation } from '@contember/schema'
|
|
2
2
|
import { Authorizator, GraphQlSchemaBuilderFactory, ExecutionContainerFactory } from '../../src'
|
|
3
|
-
import { AllowAllPermissionFactory,
|
|
3
|
+
import { AllowAllPermissionFactory, emptySchema } from '@contember/schema-utils'
|
|
4
4
|
import { executeGraphQlTest } from './testGraphql'
|
|
5
|
-
import { Client } from '@contember/database'
|
|
5
|
+
import { Client, emptyDatabaseMetadata } from '@contember/database'
|
|
6
6
|
import { createConnectionMock } from '@contember/database-tester'
|
|
7
7
|
import { createUuidGenerator } from '@contember/engine-api-tester'
|
|
8
8
|
import { SQL } from './tags'
|
|
@@ -111,7 +111,7 @@ export const execute = async (test: Test) => {
|
|
|
111
111
|
systemSchema: 'system',
|
|
112
112
|
stage: { id: '00000000-0000-0000-0000-000000000000', slug: 'live' },
|
|
113
113
|
project: { slug: 'test' },
|
|
114
|
-
schemaDatabaseMetadata:
|
|
114
|
+
schemaDatabaseMetadata: emptyDatabaseMetadata,
|
|
115
115
|
}),
|
|
116
116
|
timer: (label: any, cb: any) => cb(),
|
|
117
117
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"content-schema.graphql.d.ts","sourceRoot":"","sources":["../../../src/introspection/content-schema.graphql.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,QAAA,MAAM,MAAM,EAAE,YA2Gb,CAAA;AAED,eAAe,MAAM,CAAA"}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const graphql_tag_1 = require("graphql-tag");
|
|
4
|
-
const schema = (0, graphql_tag_1.gql) `
|
|
5
|
-
scalar Json
|
|
6
|
-
|
|
7
|
-
type Query {
|
|
8
|
-
schema: _Schema
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
type _Schema {
|
|
12
|
-
enums: [_Enum!]!
|
|
13
|
-
entities: [_Entity!]!
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
type _Entity {
|
|
17
|
-
name: String!
|
|
18
|
-
customPrimaryAllowed: Boolean!
|
|
19
|
-
fields: [_Field!]!
|
|
20
|
-
unique: [_UniqueConstraint!]!
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
type _UniqueConstraint {
|
|
24
|
-
fields: [String!]!
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface _Field {
|
|
28
|
-
name: String!
|
|
29
|
-
type: String!
|
|
30
|
-
nullable: Boolean
|
|
31
|
-
rules: [_Rule!]!
|
|
32
|
-
validators: [_Validator!]!
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
type _Column implements _Field {
|
|
36
|
-
name: String!
|
|
37
|
-
type: String!
|
|
38
|
-
enumName: String
|
|
39
|
-
defaultValue: Json
|
|
40
|
-
nullable: Boolean!
|
|
41
|
-
rules: [_Rule!]!
|
|
42
|
-
validators: [_Validator!]!
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
enum _OnDeleteBehaviour {
|
|
46
|
-
restrict
|
|
47
|
-
cascade
|
|
48
|
-
setNull
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
enum _RelationSide {
|
|
52
|
-
owning
|
|
53
|
-
inverse
|
|
54
|
-
}
|
|
55
|
-
enum _OrderByDirection {
|
|
56
|
-
asc
|
|
57
|
-
desc
|
|
58
|
-
}
|
|
59
|
-
type _OrderBy {
|
|
60
|
-
path: [String!]!
|
|
61
|
-
direction: _OrderByDirection!
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
type _Relation implements _Field {
|
|
65
|
-
name: String!
|
|
66
|
-
type: String!
|
|
67
|
-
side: _RelationSide!
|
|
68
|
-
targetEntity: String!
|
|
69
|
-
ownedBy: String
|
|
70
|
-
inversedBy: String
|
|
71
|
-
nullable: Boolean
|
|
72
|
-
onDelete: _OnDeleteBehaviour
|
|
73
|
-
orphanRemoval: Boolean
|
|
74
|
-
orderBy: [_OrderBy!]
|
|
75
|
-
rules: [_Rule!]!
|
|
76
|
-
validators: [_Validator!]!
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
type _Rule {
|
|
80
|
-
message: _RuleMessage
|
|
81
|
-
validator: Int!
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
type _Validator {
|
|
85
|
-
operation: String!
|
|
86
|
-
arguments: [_Argument!]!
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
union _Argument = _ValidatorArgument | _PathArgument | _LiteralArgument
|
|
90
|
-
|
|
91
|
-
type _ValidatorArgument {
|
|
92
|
-
validator: Int!
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
type _PathArgument {
|
|
96
|
-
path: [String!]!
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
type _LiteralArgument {
|
|
100
|
-
value: Json
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
type _RuleMessage {
|
|
104
|
-
text: String
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
type _Enum {
|
|
108
|
-
name: String!
|
|
109
|
-
values: [String!]!
|
|
110
|
-
}
|
|
111
|
-
`;
|
|
112
|
-
exports.default = schema;
|
|
113
|
-
//# sourceMappingURL=content-schema.graphql.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"content-schema.graphql.js","sourceRoot":"","sources":["../../../src/introspection/content-schema.graphql.ts"],"names":[],"mappings":";;AAAA,6CAAiC;AAGjC,MAAM,MAAM,GAAiB,IAAA,iBAAG,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2G/B,CAAA;AAED,kBAAe,MAAM,CAAA"}
|