@contember/engine-content-api 2.0.0-alpha.15 → 2.0.0-alpha.17

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 (70) hide show
  1. package/dist/development/index.cjs +2 -1
  2. package/dist/development/index.cjs.map +1 -1
  3. package/dist/development/index.js +2 -1
  4. package/dist/development/index.js.map +1 -1
  5. package/dist/development/src/inputProcessing/UpdateInputVisitor.cjs +3 -0
  6. package/dist/development/src/inputProcessing/UpdateInputVisitor.cjs.map +1 -1
  7. package/dist/development/src/inputProcessing/UpdateInputVisitor.js +3 -0
  8. package/dist/development/src/inputProcessing/UpdateInputVisitor.js.map +1 -1
  9. package/dist/development/src/introspection/IntrospectionSchemaDefinitionFactory.cjs +6 -163
  10. package/dist/development/src/introspection/IntrospectionSchemaDefinitionFactory.cjs.map +1 -1
  11. package/dist/development/src/introspection/IntrospectionSchemaDefinitionFactory.js +5 -162
  12. package/dist/development/src/introspection/IntrospectionSchemaDefinitionFactory.js.map +1 -1
  13. package/dist/development/src/introspection/introspection.schema.cjs +163 -0
  14. package/dist/development/src/introspection/introspection.schema.cjs.map +1 -0
  15. package/dist/development/src/introspection/introspection.schema.js +163 -0
  16. package/dist/development/src/introspection/introspection.schema.js.map +1 -0
  17. package/dist/development/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.cjs +2 -0
  18. package/dist/development/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.cjs.map +1 -1
  19. package/dist/development/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js +2 -0
  20. package/dist/development/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js.map +1 -1
  21. package/dist/production/index.cjs +2 -1
  22. package/dist/production/index.cjs.map +1 -1
  23. package/dist/production/index.js +2 -1
  24. package/dist/production/index.js.map +1 -1
  25. package/dist/production/src/inputProcessing/UpdateInputVisitor.cjs +3 -0
  26. package/dist/production/src/inputProcessing/UpdateInputVisitor.cjs.map +1 -1
  27. package/dist/production/src/inputProcessing/UpdateInputVisitor.js +3 -0
  28. package/dist/production/src/inputProcessing/UpdateInputVisitor.js.map +1 -1
  29. package/dist/production/src/introspection/IntrospectionSchemaDefinitionFactory.cjs +6 -163
  30. package/dist/production/src/introspection/IntrospectionSchemaDefinitionFactory.cjs.map +1 -1
  31. package/dist/production/src/introspection/IntrospectionSchemaDefinitionFactory.js +5 -162
  32. package/dist/production/src/introspection/IntrospectionSchemaDefinitionFactory.js.map +1 -1
  33. package/dist/production/src/introspection/introspection.schema.cjs +163 -0
  34. package/dist/production/src/introspection/introspection.schema.cjs.map +1 -0
  35. package/dist/production/src/introspection/introspection.schema.js +163 -0
  36. package/dist/production/src/introspection/introspection.schema.js.map +1 -0
  37. package/dist/production/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.cjs +2 -0
  38. package/dist/production/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.cjs.map +1 -1
  39. package/dist/production/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js +2 -0
  40. package/dist/production/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js.map +1 -1
  41. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/connectOrCreate.test.d.ts +2 -0
  42. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/connectOrCreate.test.d.ts.map +1 -0
  43. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/connectOrCreate.test.d.ts +2 -0
  44. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/connectOrCreate.test.d.ts.map +1 -0
  45. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  46. package/dist/types/inputProcessing/UpdateInputVisitor.d.ts.map +1 -1
  47. package/dist/types/introspection/IntrospectionSchemaDefinitionFactory.d.ts +1 -3
  48. package/dist/types/introspection/IntrospectionSchemaDefinitionFactory.d.ts.map +1 -1
  49. package/dist/types/introspection/index.d.ts +2 -1
  50. package/dist/types/introspection/index.d.ts.map +1 -1
  51. package/dist/types/introspection/introspection.schema.d.ts +5 -0
  52. package/dist/types/introspection/introspection.schema.d.ts.map +1 -0
  53. package/dist/types/schema/mutations/UpdateEntityRelationInputFieldVisitor.d.ts.map +1 -1
  54. package/dist/types/tsconfig.tsbuildinfo +1 -1
  55. package/graphql.codegen.yml +2 -2
  56. package/package.json +13 -17
  57. package/src/inputProcessing/UpdateInputVisitor.ts +3 -0
  58. package/src/introspection/IntrospectionSchemaDefinitionFactory.ts +2 -194
  59. package/src/introspection/index.ts +2 -1
  60. package/src/introspection/introspection.schema.ts +194 -0
  61. package/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.ts +5 -0
  62. package/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/connectOrCreate.test.ts +100 -0
  63. package/tests/cases/integration/graphQlRequests/update/oneHasMany/connectOrCreate.test.ts +90 -0
  64. package/tests/cases/integration/graphQlSchema/schema-acl-allowed.gql +1 -0
  65. package/tests/cases/integration/graphQlSchema/schema-acl-restricted-delete.gql +1 -0
  66. package/tests/cases/integration/graphQlSchema/schema-basic.gql +4 -0
  67. package/tests/cases/integration/graphQlSchema/schema-bug-66.gql +1 -0
  68. package/tests/cases/integration/graphQlSchema/schema-custom-primary.gql +4 -0
  69. package/tests/cases/integration/graphQlSchema/schema-has-many-reduction.gql +1 -0
  70. package/tests/cases/integration/graphQlSchema/schema-new-builder.gql +4 -0
@@ -1,5 +1,5 @@
1
1
  schema:
2
- - "./src/introspection/IntrospectionSchemaDefinitionFactory.ts"
2
+ - "./src/introspection/introspection.schema.ts"
3
3
  documents: []
4
4
  config:
5
5
  immutableTypes: "1"
@@ -12,4 +12,4 @@ generates:
12
12
  - "typescript-operations"
13
13
  hooks:
14
14
  afterAllFileWrite:
15
- - eslint --fix
15
+ - yarn run -T eslint --fix
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/engine-content-api",
3
- "version": "2.0.0-alpha.15",
3
+ "version": "2.0.0-alpha.17",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/production/index.js",
6
6
  "typings": "./dist/types/index.d.ts",
@@ -26,25 +26,21 @@
26
26
  "generate": "gql-gen --config graphql.codegen.yml"
27
27
  },
28
28
  "dependencies": {
29
- "@contember/database": "2.0.0-alpha.15",
30
- "@contember/dic": "2.0.0-alpha.15",
31
- "@contember/graphql-utils": "2.0.0-alpha.15",
32
- "@contember/logger": "2.0.0-alpha.15",
33
- "@contember/schema": "2.0.0-alpha.15",
34
- "@contember/schema-definition": "2.0.0-alpha.15",
35
- "@contember/schema-utils": "2.0.0-alpha.15",
29
+ "@contember/database": "2.0.0-alpha.17",
30
+ "@contember/dic": "2.0.0-alpha.17",
31
+ "@contember/graphql-utils": "2.0.0-alpha.17",
32
+ "@contember/logger": "2.0.0-alpha.17",
33
+ "@contember/schema": "2.0.0-alpha.17",
34
+ "@contember/schema-definition": "2.0.0-alpha.17",
35
+ "@contember/schema-utils": "2.0.0-alpha.17",
36
36
  "fast-deep-equal": "^3.1.3"
37
37
  },
38
38
  "devDependencies": {
39
- "@contember/database-tester": "2.0.0-alpha.15",
40
- "@contember/schema-definition": "2.0.0-alpha.15",
41
- "@graphql-codegen/cli": "^5.0.0",
42
- "@graphql-codegen/typescript": "^4.0.1",
43
- "@graphql-codegen/typescript-operations": "^4.0.1",
44
- "@graphql-codegen/typescript-resolvers": "^4.0.1",
45
- "@types/node": "^20.9.0",
46
- "graphql": "^16.8.1",
47
- "pg": "^8.11.3"
39
+ "@contember/database-tester": "2.0.0-alpha.17",
40
+ "@contember/schema-definition": "2.0.0-alpha.17",
41
+ "@types/node": "^20.16.5",
42
+ "graphql": "^16.9.0",
43
+ "pg": "^8.12.0"
48
44
  },
49
45
  "peerDependencies": {
50
46
  "graphql": ">= 14.6.0",
@@ -124,6 +124,9 @@ export class UpdateInputVisitor<Result> implements
124
124
  if (isIt<Input.CreateRelationInput>(element, 'create')) {
125
125
  result = processor.create({ ...context, input: element.create, index: i, alias })
126
126
  }
127
+ if (isIt<Input.ConnectOrCreateRelationInput>(element, 'connectOrCreate')) {
128
+ result = processor.connectOrCreate({ ...context, input: element.connectOrCreate, index: i, alias })
129
+ }
127
130
  if (isIt<Input.DeleteSpecifiedRelationInput>(element, 'delete')) {
128
131
  result = processor.delete({ ...context, input: element.delete, index: i, alias })
129
132
  }
@@ -1,199 +1,7 @@
1
+ import { GraphQLSchema, GraphQLSchemaConfig } from 'graphql'
1
2
  import * as ContentSchema from './content-schema.types'
2
3
  import { IntrospectionSchemaFactory } from './IntrospectionSchemaFactory'
3
- import { JSONType } from '@contember/graphql-utils'
4
-
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
- })
145
-
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,
188
- },
189
- },
190
- }),
191
- types: [_Column, _Relation],
192
- }
193
- }
194
-
195
-
196
- export default new GraphQLSchema(createSchemaConfig())
4
+ import { createSchemaConfig } from './introspection.schema'
197
5
 
198
6
  export class IntrospectionSchemaDefinitionFactory {
199
7
  constructor(private readonly introspectionSchemaFactory: IntrospectionSchemaFactory) {}
@@ -1,3 +1,4 @@
1
1
  export * as ContentSchemaTypes from './content-schema.types'
2
- export { IntrospectionSchemaDefinitionFactory, default as ContentSchema } from './IntrospectionSchemaDefinitionFactory'
2
+ export { IntrospectionSchemaDefinitionFactory } from './IntrospectionSchemaDefinitionFactory'
3
+ export { default as ContentSchema } from './introspection.schema'
3
4
  export * from './IntrospectionSchemaFactory'
@@ -0,0 +1,194 @@
1
+ import { JSONType } from '@contember/graphql-utils'
2
+
3
+ import {
4
+ GraphQLBoolean,
5
+ GraphQLEnumType,
6
+ GraphQLFieldResolver,
7
+ GraphQLInt,
8
+ GraphQLInterfaceType,
9
+ GraphQLList,
10
+ GraphQLNonNull,
11
+ GraphQLObjectType,
12
+ GraphQLSchema,
13
+ GraphQLSchemaConfig,
14
+ GraphQLString,
15
+ GraphQLUnionType,
16
+ } from 'graphql'
17
+
18
+ const _RuleMessage = new GraphQLObjectType({
19
+ name: '_RuleMessage',
20
+ fields: {
21
+ text: { type: GraphQLString },
22
+ },
23
+ })
24
+
25
+ const _ValidatorArgument = new GraphQLObjectType({
26
+ name: '_ValidatorArgument',
27
+ fields: {
28
+ validator: { type: new GraphQLNonNull(GraphQLInt) },
29
+ },
30
+ })
31
+
32
+ const _PathArgument = new GraphQLObjectType({
33
+ name: '_PathArgument',
34
+ fields: {
35
+ path: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))) },
36
+ },
37
+ })
38
+
39
+ const _LiteralArgument = new GraphQLObjectType({
40
+ name: '_LiteralArgument',
41
+ fields: {
42
+ value: { type: JSONType },
43
+ },
44
+ })
45
+
46
+ const _Argument = new GraphQLUnionType({
47
+ name: '_Argument',
48
+ types: [_ValidatorArgument, _PathArgument, _LiteralArgument],
49
+ })
50
+
51
+ const _Validator = new GraphQLObjectType({
52
+ name: '_Validator',
53
+ fields: {
54
+ operation: { type: new GraphQLNonNull(GraphQLString) },
55
+ arguments: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Argument))) },
56
+ },
57
+ })
58
+
59
+ const _Rule = new GraphQLObjectType({
60
+ name: '_Rule',
61
+ fields: {
62
+ message: { type: _RuleMessage },
63
+ validator: { type: new GraphQLNonNull(GraphQLInt) },
64
+ },
65
+ })
66
+
67
+ const _FieldInterface = new GraphQLInterfaceType({
68
+ name: '_Field',
69
+ fields: {
70
+ name: { type: new GraphQLNonNull(GraphQLString) },
71
+ type: { type: new GraphQLNonNull(GraphQLString) },
72
+ nullable: { type: GraphQLBoolean },
73
+ rules: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Rule))) },
74
+ validators: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Validator))) },
75
+ },
76
+ })
77
+
78
+ const _OrderByDirection = new GraphQLEnumType({
79
+ name: '_OrderByDirection',
80
+ values: {
81
+ asc: {},
82
+ desc: {},
83
+ },
84
+ })
85
+
86
+ const _OrderBy = new GraphQLObjectType({
87
+ name: '_OrderBy',
88
+ fields: {
89
+ path: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))) },
90
+ direction: { type: new GraphQLNonNull(_OrderByDirection) },
91
+ },
92
+ })
93
+
94
+ const _OnDeleteBehaviour = new GraphQLEnumType({
95
+ name: '_OnDeleteBehaviour',
96
+ values: {
97
+ restrict: {},
98
+ cascade: {},
99
+ setNull: {},
100
+ },
101
+ })
102
+
103
+ const _RelationSide = new GraphQLEnumType({
104
+ name: '_RelationSide',
105
+ values: {
106
+ owning: {},
107
+ inverse: {},
108
+ },
109
+ })
110
+
111
+ const _Relation = new GraphQLObjectType({
112
+ name: '_Relation',
113
+ interfaces: [_FieldInterface],
114
+ fields: {
115
+ name: { type: new GraphQLNonNull(GraphQLString) },
116
+ type: { type: new GraphQLNonNull(GraphQLString) },
117
+ side: { type: new GraphQLNonNull(_RelationSide) },
118
+ targetEntity: { type: new GraphQLNonNull(GraphQLString) },
119
+ ownedBy: { type: GraphQLString },
120
+ inversedBy: { type: GraphQLString },
121
+ nullable: { type: GraphQLBoolean },
122
+ onDelete: { type: _OnDeleteBehaviour },
123
+ orphanRemoval: { type: GraphQLBoolean },
124
+ orderBy: { type: new GraphQLList(new GraphQLNonNull(_OrderBy)) },
125
+ rules: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Rule))) },
126
+ validators: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Validator))) },
127
+ },
128
+ })
129
+
130
+ const _Column = new GraphQLObjectType({
131
+ name: '_Column',
132
+ interfaces: [_FieldInterface],
133
+ fields: {
134
+ name: { type: new GraphQLNonNull(GraphQLString) },
135
+ type: { type: new GraphQLNonNull(GraphQLString) },
136
+ enumName: { type: GraphQLString },
137
+ defaultValue: { type: JSONType },
138
+ nullable: { type: new GraphQLNonNull(GraphQLBoolean) },
139
+ rules: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Rule))) },
140
+ validators: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Validator))) },
141
+ },
142
+ })
143
+
144
+ const _UniqueConstraint = new GraphQLObjectType({
145
+ name: '_UniqueConstraint',
146
+ fields: {
147
+ fields: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))) },
148
+ },
149
+ })
150
+
151
+ const _Entity = new GraphQLObjectType({
152
+ name: '_Entity',
153
+ fields: {
154
+ name: { type: new GraphQLNonNull(GraphQLString) },
155
+ customPrimaryAllowed: { type: new GraphQLNonNull(GraphQLBoolean) },
156
+ fields: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_FieldInterface))) },
157
+ unique: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_UniqueConstraint))) },
158
+ },
159
+ })
160
+
161
+ const _Enum = new GraphQLObjectType({
162
+ name: '_Enum',
163
+ fields: {
164
+ name: { type: new GraphQLNonNull(GraphQLString) },
165
+ values: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))) },
166
+ },
167
+ })
168
+
169
+ const _Schema = new GraphQLObjectType({
170
+ name: '_Schema',
171
+ fields: {
172
+ enums: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Enum))) },
173
+ entities: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(_Entity))) },
174
+ },
175
+ })
176
+
177
+
178
+ export const createSchemaConfig = (resolver?: GraphQLFieldResolver<any, any>): GraphQLSchemaConfig => {
179
+ return {
180
+ query: new GraphQLObjectType({
181
+ name: 'Query',
182
+ fields: {
183
+ schema: {
184
+ type: _Schema,
185
+ resolve: resolver,
186
+ },
187
+ },
188
+ }),
189
+ types: [_Column, _Relation],
190
+ }
191
+ }
192
+
193
+
194
+ export default new GraphQLSchema(createSchemaConfig())
@@ -123,11 +123,16 @@ export class UpdateEntityRelationInputFieldVisitor implements Model.ColumnVisito
123
123
  }
124
124
  : undefined
125
125
 
126
+ const connectOrCreateInput = createInput && whereInputType
127
+ ? { type: this.connectOrCreateRelationInputProvider.getInput(entity.name, relation.name) }
128
+ : undefined
129
+
126
130
  const fields = {
127
131
  [Input.UpdateRelationOperation.create]: createInput,
128
132
  [Input.UpdateRelationOperation.update]: updateSpecifiedInput,
129
133
  [Input.UpdateRelationOperation.upsert]: upsertInput,
130
134
  [Input.UpdateRelationOperation.connect]: whereInput,
135
+ [Input.UpdateRelationOperation.connectOrCreate]: connectOrCreateInput,
131
136
  [Input.UpdateRelationOperation.disconnect]: whereInput,
132
137
  [Input.UpdateRelationOperation.delete]: whereInput,
133
138
  }
@@ -0,0 +1,100 @@
1
+ import { test } from 'vitest'
2
+ import { execute, sqlTransaction } from '../../../../../src/test'
3
+ import { GQL, SQL } from '../../../../../src/tags'
4
+ import { testUuid } from '../../../../../src/testUuid'
5
+ import { postWithCategories } from './schema'
6
+
7
+ test('connectOrCreate - exists', async () => {
8
+ await execute({
9
+ schema: postWithCategories,
10
+ query: GQL`mutation {
11
+ updatePost(
12
+ by: {id: "${testUuid(2)}"},
13
+ data: {categories: [{connectOrCreate: {connect: {id: "${testUuid(1)}"}, create: {name: "Ipsum"}}}]}
14
+ ) {
15
+ ok
16
+ }
17
+ }`,
18
+ executes: [
19
+ ...sqlTransaction([
20
+ {
21
+ sql: SQL`select "root_"."id" from "public"."post" as "root_" where "root_"."id" = ?`,
22
+ parameters: [testUuid(2)],
23
+ response: { rows: [{ id: testUuid(2) }] },
24
+ },
25
+ {
26
+ sql: SQL`select "root_"."id" from "public"."category" as "root_" where "root_"."id" = ?`,
27
+ parameters: [testUuid(1)],
28
+ response: { rows: [{ id: testUuid(1) }] },
29
+ },
30
+ {
31
+ sql: SQL`insert into "public"."post_categories" ("post_id", "category_id")
32
+ values (?, ?)
33
+ on conflict do nothing`,
34
+ parameters: [testUuid(2), testUuid(1)],
35
+ response: { rowCount: 1 },
36
+ },
37
+ ]),
38
+ ],
39
+ return: {
40
+ data: {
41
+ updatePost: {
42
+ ok: true,
43
+ },
44
+ },
45
+ },
46
+ })
47
+ })
48
+ test('connectOrCreate - not exists', async () => {
49
+ await execute({
50
+ schema: postWithCategories,
51
+ query: GQL`mutation {
52
+ updatePost(
53
+ by: {id: "${testUuid(2)}"},
54
+ data: {categories: [{connectOrCreate: {connect: {id: "${testUuid(1)}"}, create: {name: "Ipsum"}}}]}
55
+ ) {
56
+ ok
57
+ }
58
+ }`,
59
+ executes: [
60
+ ...sqlTransaction([
61
+ {
62
+ sql: SQL`select "root_"."id" from "public"."post" as "root_" where "root_"."id" = ?`,
63
+ parameters: [testUuid(2)],
64
+ response: { rows: [{ id: testUuid(2) }] },
65
+ },
66
+ {
67
+ sql: SQL`select "root_"."id" from "public"."category" as "root_" where "root_"."id" = ?`,
68
+ parameters: [testUuid(1)],
69
+ response: { rows: [] },
70
+ },
71
+ {
72
+ sql: SQL`with "root_" as
73
+ (select ? :: uuid as "id", ? :: text as "name")
74
+ insert into "public"."category" ("id", "name")
75
+ select "root_"."id", "root_"."name"
76
+ from "root_"
77
+ returning "id"`,
78
+ parameters: [testUuid(1), 'Ipsum'],
79
+ response: { rows: [{ id: testUuid(1) }] },
80
+ },
81
+ {
82
+ sql: SQL`insert into "public"."post_categories" ("post_id", "category_id")
83
+ values (?, ?)
84
+ on conflict do nothing`,
85
+ parameters: [testUuid(2), testUuid(1)],
86
+ response: { rowCount: 1 },
87
+ },
88
+ ]),
89
+ ],
90
+ return: {
91
+ data: {
92
+ updatePost: {
93
+ ok: true,
94
+ },
95
+ },
96
+ },
97
+ })
98
+ })
99
+
100
+
@@ -0,0 +1,90 @@
1
+ import { test } from 'vitest'
2
+ import { execute, sqlTransaction } from '../../../../../src/test'
3
+ import { GQL, SQL } from '../../../../../src/tags'
4
+ import { testUuid } from '../../../../../src/testUuid'
5
+ import { postWithLocale } from './schema'
6
+
7
+ test('connectOrCreate - exists', async () => {
8
+ await execute({
9
+ schema: postWithLocale,
10
+ query: GQL`mutation {
11
+ updatePost(
12
+ by: {id: "${testUuid(2)}"},
13
+ data: {locales: [{connectOrCreate: {connect: {id: "${testUuid(10)}"}, create: {title: "World"}}}]}
14
+ ) {
15
+ ok
16
+ }
17
+ }`,
18
+ executes: [
19
+ ...sqlTransaction([
20
+ {
21
+ sql: SQL`select "root_"."id" from "public"."post" as "root_" where "root_"."id" = ?`,
22
+ parameters: [testUuid(2)],
23
+ response: { rows: [{ id: testUuid(2) }] },
24
+ },
25
+ {
26
+ sql: SQL`select "root_"."id" from "public"."post_locale" as "root_" where "root_"."id" = ?`,
27
+ parameters: [testUuid(10)],
28
+ response: { rows: [{ id: testUuid(10) }] },
29
+ },
30
+ {
31
+ sql: SQL`with "newData_" as (select ? :: uuid as "post_id", "root_"."post_id" as "post_id_old__", "root_"."id", "root_"."title", "root_"."locale" from "public"."post_locale" as "root_" where "root_"."id" = ?) update "public"."post_locale" set "post_id" = "newData_"."post_id" from "newData_" where "post_locale"."id" = "newData_"."id" returning "post_id_old__"`,
32
+ parameters: [testUuid(2), testUuid(10)],
33
+ response: { rows: [{ post_id_old__: testUuid(1) }] },
34
+ },
35
+ ]),
36
+ ],
37
+ return: {
38
+ data: {
39
+ updatePost: {
40
+ ok: true,
41
+ },
42
+ },
43
+ },
44
+ })
45
+ })
46
+ test('upsert - not exists (composed unique)', async () => {
47
+ await execute({
48
+ schema: postWithLocale,
49
+ query: GQL`mutation {
50
+ updatePost(
51
+ by: {id: "${testUuid(2)}"},
52
+ data: {locales: [{connectOrCreate: {connect: {id: "${testUuid(10)}"}, create: {title: "World"}}}]}
53
+ ) {
54
+ ok
55
+ }
56
+ }`,
57
+ executes: [
58
+ ...sqlTransaction([
59
+ {
60
+ sql: SQL`select "root_"."id" from "public"."post" as "root_" where "root_"."id" = ?`,
61
+ parameters: [testUuid(2)],
62
+ response: { rows: [{ id: testUuid(2) }] },
63
+ },
64
+ {
65
+ sql: SQL`select "root_"."id" from "public"."post_locale" as "root_" where "root_"."id" = ?`,
66
+ parameters: [testUuid(10)],
67
+ response: { rows: [] },
68
+ },
69
+ {
70
+ sql: SQL`with "root_" as
71
+ (select ? :: uuid as "id", ? :: text as "title", ? :: text as "locale", ? :: uuid as "post_id")
72
+ insert into "public"."post_locale" ("id", "title", "locale", "post_id")
73
+ select "root_"."id", "root_"."title", "root_"."locale", "root_"."post_id"
74
+ from "root_"
75
+ returning "id"`,
76
+ parameters: [testUuid(1), 'World', null, testUuid(2)],
77
+ response: { rows: [{ id: testUuid(1) }] },
78
+ },
79
+ ]),
80
+ ],
81
+ return: {
82
+ data: {
83
+ updatePost: {
84
+ ok: true,
85
+ },
86
+ },
87
+ },
88
+ })
89
+ })
90
+
@@ -263,6 +263,7 @@ input RootUpdateREntityRelationInput {
263
263
  update: RootUpdateRRelationInput
264
264
  upsert: RootUpsertRRelationInput
265
265
  connect: OneHasManyEntityUniqueWhere
266
+ connectOrCreate: RootConnectOrCreateRRelationInput
266
267
  disconnect: OneHasManyEntityUniqueWhere
267
268
  delete: OneHasManyEntityUniqueWhere
268
269
  alias: String