@platformatic/sql-graphql 0.20.1 → 0.21.0
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/lib/entity-to-type.js +28 -16
- package/lib/utils.js +2 -2
- package/package.json +3 -3
- package/test/datatypes.test.js +8 -8
- package/test/or.test.js +302 -0
package/lib/entity-to-type.js
CHANGED
|
@@ -99,27 +99,39 @@ function constructGraph (app, entity, opts, ignore) {
|
|
|
99
99
|
return ['and', key]
|
|
100
100
|
}).flat())].join('_'))
|
|
101
101
|
|
|
102
|
+
const whereFields = Object.keys(fields).reduce((acc, field) => {
|
|
103
|
+
acc[field] = {
|
|
104
|
+
type: new graphql.GraphQLInputObjectType({
|
|
105
|
+
name: `${entityName}WhereArguments${field}`,
|
|
106
|
+
fields: {
|
|
107
|
+
eq: { type: fields[field].type },
|
|
108
|
+
neq: { type: fields[field].type },
|
|
109
|
+
gt: { type: fields[field].type },
|
|
110
|
+
gte: { type: fields[field].type },
|
|
111
|
+
lt: { type: fields[field].type },
|
|
112
|
+
lte: { type: fields[field].type },
|
|
113
|
+
like: { type: fields[field].type },
|
|
114
|
+
in: { type: new graphql.GraphQLList(fields[field].type) },
|
|
115
|
+
nin: { type: new graphql.GraphQLList(fields[field].type) }
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
return acc
|
|
120
|
+
}, {})
|
|
121
|
+
|
|
102
122
|
const whereArgType = new graphql.GraphQLInputObjectType({
|
|
103
123
|
name: `${entityName}WhereArguments`,
|
|
104
|
-
fields:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
124
|
+
fields: {
|
|
125
|
+
...whereFields,
|
|
126
|
+
or: {
|
|
127
|
+
type: new graphql.GraphQLList(new graphql.GraphQLInputObjectType({
|
|
128
|
+
name: `${entityName}WhereArgumentsOr`,
|
|
108
129
|
fields: {
|
|
109
|
-
|
|
110
|
-
neq: { type: fields[field].type },
|
|
111
|
-
gt: { type: fields[field].type },
|
|
112
|
-
gte: { type: fields[field].type },
|
|
113
|
-
lt: { type: fields[field].type },
|
|
114
|
-
lte: { type: fields[field].type },
|
|
115
|
-
like: { type: fields[field].type },
|
|
116
|
-
in: { type: new graphql.GraphQLList(fields[field].type) },
|
|
117
|
-
nin: { type: new graphql.GraphQLList(fields[field].type) }
|
|
130
|
+
...whereFields
|
|
118
131
|
}
|
|
119
|
-
})
|
|
132
|
+
}))
|
|
120
133
|
}
|
|
121
|
-
|
|
122
|
-
}, {})
|
|
134
|
+
}
|
|
123
135
|
})
|
|
124
136
|
|
|
125
137
|
queryTopFields[getBy] = {
|
package/lib/utils.js
CHANGED
|
@@ -19,7 +19,7 @@ function sqlTypeToGraphQL (sqlType) {
|
|
|
19
19
|
case 'smallint':
|
|
20
20
|
return graphql.GraphQLInt
|
|
21
21
|
case 'decimal':
|
|
22
|
-
return graphql.
|
|
22
|
+
return graphql.GraphQLString
|
|
23
23
|
case 'bigint':
|
|
24
24
|
return graphql.GraphQLString
|
|
25
25
|
case 'int2':
|
|
@@ -43,7 +43,7 @@ function sqlTypeToGraphQL (sqlType) {
|
|
|
43
43
|
case 'double precision':
|
|
44
44
|
return graphql.GraphQLFloat
|
|
45
45
|
case 'numeric':
|
|
46
|
-
return graphql.
|
|
46
|
+
return graphql.GraphQLString
|
|
47
47
|
case 'float4':
|
|
48
48
|
return graphql.GraphQLFloat
|
|
49
49
|
case 'date':
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/sql-graphql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Map SQL dbs to GraphQL",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"tap": "^16.3.4",
|
|
22
22
|
"tsd": "^0.28.0",
|
|
23
23
|
"ws": "^8.12.1",
|
|
24
|
-
"@platformatic/sql-events": "0.
|
|
25
|
-
"@platformatic/sql-mapper": "0.
|
|
24
|
+
"@platformatic/sql-events": "0.21.0",
|
|
25
|
+
"@platformatic/sql-mapper": "0.21.0"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@mercuriusjs/federation": "^1.0.1",
|
package/test/datatypes.test.js
CHANGED
|
@@ -58,7 +58,7 @@ test('[PG] simple db simple graphql schema', { skip: !isPg }, async ({ pass, tea
|
|
|
58
58
|
uuid: "12345678-1234-1234-1234-123456789012",
|
|
59
59
|
aReal: 1.2,
|
|
60
60
|
aSmallint: 42,
|
|
61
|
-
aDecimal: 42,
|
|
61
|
+
aDecimal: "42",
|
|
62
62
|
anEnum: value1
|
|
63
63
|
}) {
|
|
64
64
|
id
|
|
@@ -92,7 +92,7 @@ test('[PG] simple db simple graphql schema', { skip: !isPg }, async ({ pass, tea
|
|
|
92
92
|
uuid: '12345678-1234-1234-1234-123456789012',
|
|
93
93
|
aReal: 1.2,
|
|
94
94
|
aSmallint: 42,
|
|
95
|
-
aDecimal: 42,
|
|
95
|
+
aDecimal: '42',
|
|
96
96
|
anEnum: 'value1'
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -303,7 +303,7 @@ test('[MySQL] simple db simple graphql schema', { skip: !isMysql }, async ({ pas
|
|
|
303
303
|
uuid: "12345678-1234-1234-1234-123456789012",
|
|
304
304
|
aReal: 1.2,
|
|
305
305
|
aSmallint: 42,
|
|
306
|
-
aDecimal: 42,
|
|
306
|
+
aDecimal: "42",
|
|
307
307
|
anEnum: value1
|
|
308
308
|
}) {
|
|
309
309
|
id
|
|
@@ -337,7 +337,7 @@ test('[MySQL] simple db simple graphql schema', { skip: !isMysql }, async ({ pas
|
|
|
337
337
|
uuid: '12345678-1234-1234-1234-123456789012',
|
|
338
338
|
aReal: 1.2,
|
|
339
339
|
aSmallint: 42,
|
|
340
|
-
aDecimal: 42,
|
|
340
|
+
aDecimal: '42',
|
|
341
341
|
anEnum: 'value1'
|
|
342
342
|
}
|
|
343
343
|
}
|
|
@@ -383,7 +383,7 @@ test('[MySQL] simple db simple graphql schema', { skip: !isMysql }, async ({ pas
|
|
|
383
383
|
uuid: '12345678-1234-1234-1234-123456789012',
|
|
384
384
|
aReal: 1.2,
|
|
385
385
|
aSmallint: 42,
|
|
386
|
-
aDecimal: 42,
|
|
386
|
+
aDecimal: '42',
|
|
387
387
|
anEnum: 'value1'
|
|
388
388
|
}
|
|
389
389
|
}
|
|
@@ -546,7 +546,7 @@ test('[SQLite] simple db simple graphql schema', { skip: !isSQLite }, async ({ p
|
|
|
546
546
|
uuid: "12345678-1234-1234-1234-123456789012",
|
|
547
547
|
aReal: 1.2,
|
|
548
548
|
aSmallint: 42,
|
|
549
|
-
aDecimal: 42 }) {
|
|
549
|
+
aDecimal: "42" }) {
|
|
550
550
|
id
|
|
551
551
|
published
|
|
552
552
|
current
|
|
@@ -573,7 +573,7 @@ test('[SQLite] simple db simple graphql schema', { skip: !isSQLite }, async ({ p
|
|
|
573
573
|
uuid: '12345678-1234-1234-1234-123456789012',
|
|
574
574
|
aReal: 1.2,
|
|
575
575
|
aSmallint: 42,
|
|
576
|
-
aDecimal: 42
|
|
576
|
+
aDecimal: '42'
|
|
577
577
|
}
|
|
578
578
|
}
|
|
579
579
|
}, 'saveSimpleType response')
|
|
@@ -613,7 +613,7 @@ test('[SQLite] simple db simple graphql schema', { skip: !isSQLite }, async ({ p
|
|
|
613
613
|
uuid: '12345678-1234-1234-1234-123456789012',
|
|
614
614
|
aReal: 1.2,
|
|
615
615
|
aSmallint: 42,
|
|
616
|
-
aDecimal: 42
|
|
616
|
+
aDecimal: '42'
|
|
617
617
|
}
|
|
618
618
|
}
|
|
619
619
|
}, 'getSimpleTypeById response')
|
package/test/or.test.js
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const sqlGraphQL = require('..')
|
|
5
|
+
const sqlMapper = require('@platformatic/sql-mapper')
|
|
6
|
+
const fastify = require('fastify')
|
|
7
|
+
const { clear, connInfo, isSQLite } = require('./helper')
|
|
8
|
+
|
|
9
|
+
test('list', async ({ pass, teardown, same, equal }) => {
|
|
10
|
+
const app = fastify()
|
|
11
|
+
app.register(sqlMapper, {
|
|
12
|
+
...connInfo,
|
|
13
|
+
async onDatabaseLoad (db, sql) {
|
|
14
|
+
pass('onDatabaseLoad called')
|
|
15
|
+
|
|
16
|
+
await clear(db, sql)
|
|
17
|
+
|
|
18
|
+
if (isSQLite) {
|
|
19
|
+
await db.query(sql`CREATE TABLE posts (
|
|
20
|
+
id INTEGER PRIMARY KEY,
|
|
21
|
+
title VARCHAR(42),
|
|
22
|
+
long_text TEXT,
|
|
23
|
+
counter INTEGER
|
|
24
|
+
);`)
|
|
25
|
+
} else {
|
|
26
|
+
await db.query(sql`CREATE TABLE posts (
|
|
27
|
+
id SERIAL PRIMARY KEY,
|
|
28
|
+
title VARCHAR(42),
|
|
29
|
+
long_text TEXT,
|
|
30
|
+
counter INTEGER
|
|
31
|
+
);`)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
app.register(sqlGraphQL)
|
|
36
|
+
teardown(app.close.bind(app))
|
|
37
|
+
|
|
38
|
+
await app.ready()
|
|
39
|
+
|
|
40
|
+
const posts = [{
|
|
41
|
+
title: 'Dog',
|
|
42
|
+
longText: 'Foo',
|
|
43
|
+
counter: 10
|
|
44
|
+
}, {
|
|
45
|
+
title: 'Cat',
|
|
46
|
+
longText: 'Bar',
|
|
47
|
+
counter: 20
|
|
48
|
+
}, {
|
|
49
|
+
title: 'Mouse',
|
|
50
|
+
longText: 'Baz',
|
|
51
|
+
counter: 30
|
|
52
|
+
}, {
|
|
53
|
+
title: 'Duck',
|
|
54
|
+
longText: 'A duck tale',
|
|
55
|
+
counter: 40
|
|
56
|
+
}]
|
|
57
|
+
|
|
58
|
+
{
|
|
59
|
+
const res = await app.inject({
|
|
60
|
+
method: 'POST',
|
|
61
|
+
url: '/graphql',
|
|
62
|
+
body: {
|
|
63
|
+
query: `
|
|
64
|
+
mutation batch($inputs : [PostInput]!) {
|
|
65
|
+
insertPosts(inputs: $inputs) {
|
|
66
|
+
id
|
|
67
|
+
title
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
`,
|
|
71
|
+
variables: {
|
|
72
|
+
inputs: posts
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
equal(res.statusCode, 200, 'posts status code')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
{
|
|
80
|
+
const res = await app.inject({
|
|
81
|
+
method: 'POST',
|
|
82
|
+
url: '/graphql',
|
|
83
|
+
body: {
|
|
84
|
+
query: `
|
|
85
|
+
query {
|
|
86
|
+
posts(where: { or: [ { title: { eq: "Dog" } }, { title: { eq: "Cat" } } ] }) {
|
|
87
|
+
id
|
|
88
|
+
title
|
|
89
|
+
longText
|
|
90
|
+
counter
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
`
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
equal(res.statusCode, 200, 'posts status code')
|
|
97
|
+
same(res.json(), {
|
|
98
|
+
data: {
|
|
99
|
+
posts: [
|
|
100
|
+
{ id: '1', title: 'Dog', longText: 'Foo', counter: 10 },
|
|
101
|
+
{ id: '2', title: 'Cat', longText: 'Bar', counter: 20 }
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
}, 'posts response')
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
{
|
|
108
|
+
const res = await app.inject({
|
|
109
|
+
method: 'POST',
|
|
110
|
+
url: '/graphql',
|
|
111
|
+
body: {
|
|
112
|
+
query: `
|
|
113
|
+
query {
|
|
114
|
+
posts(where: { id: { eq: 1 }, or: [ { title: { eq: "Dog" } }, { title: { eq: "Cat" } } ] }) {
|
|
115
|
+
id
|
|
116
|
+
title
|
|
117
|
+
longText
|
|
118
|
+
counter
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
`
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
equal(res.statusCode, 200, 'posts status code')
|
|
125
|
+
same(res.json(), {
|
|
126
|
+
data: {
|
|
127
|
+
posts: [
|
|
128
|
+
{ id: '1', title: 'Dog', longText: 'Foo', counter: 10 }
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
}, 'posts response')
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
{
|
|
135
|
+
const res = await app.inject({
|
|
136
|
+
method: 'POST',
|
|
137
|
+
url: '/graphql',
|
|
138
|
+
body: {
|
|
139
|
+
query: `
|
|
140
|
+
query {
|
|
141
|
+
posts(where: { or: [ { counter: { eq: 10 } }, { counter: { eq: 20 } } ] }) {
|
|
142
|
+
id
|
|
143
|
+
title
|
|
144
|
+
longText
|
|
145
|
+
counter
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
`
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
equal(res.statusCode, 200, 'posts status code')
|
|
152
|
+
same(res.json(), {
|
|
153
|
+
data: {
|
|
154
|
+
posts: [
|
|
155
|
+
{ id: '1', title: 'Dog', longText: 'Foo', counter: 10 },
|
|
156
|
+
{ id: '2', title: 'Cat', longText: 'Bar', counter: 20 }
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
}, 'posts response')
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
{
|
|
163
|
+
const res = await app.inject({
|
|
164
|
+
method: 'POST',
|
|
165
|
+
url: '/graphql',
|
|
166
|
+
body: {
|
|
167
|
+
query: `
|
|
168
|
+
query {
|
|
169
|
+
posts(where: { or: [ { counter: { eq: 10 } }, { counter: { gte: 30 } } ] }) {
|
|
170
|
+
id
|
|
171
|
+
title
|
|
172
|
+
longText
|
|
173
|
+
counter
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
`
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
equal(res.statusCode, 200, 'posts status code')
|
|
180
|
+
same(res.json(), {
|
|
181
|
+
data: {
|
|
182
|
+
posts: [
|
|
183
|
+
{ id: '1', title: 'Dog', longText: 'Foo', counter: 10 },
|
|
184
|
+
{ id: '3', title: 'Mouse', longText: 'Baz', counter: 30 },
|
|
185
|
+
{ id: '4', title: 'Duck', longText: 'A duck tale', counter: 40 }
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
}, 'posts response')
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
{
|
|
192
|
+
const res = await app.inject({
|
|
193
|
+
method: 'POST',
|
|
194
|
+
url: '/graphql',
|
|
195
|
+
body: {
|
|
196
|
+
query: `
|
|
197
|
+
query {
|
|
198
|
+
posts(where: { or: [ { title: { eq: "Dog" } }, { title: { eq: "Duck" } } ] }) {
|
|
199
|
+
id
|
|
200
|
+
title
|
|
201
|
+
longText
|
|
202
|
+
counter
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
`
|
|
206
|
+
}
|
|
207
|
+
})
|
|
208
|
+
equal(res.statusCode, 200, 'posts status code')
|
|
209
|
+
same(res.json(), {
|
|
210
|
+
data: {
|
|
211
|
+
posts: [
|
|
212
|
+
{ id: '1', title: 'Dog', longText: 'Foo', counter: 10 },
|
|
213
|
+
{ id: '4', title: 'Duck', longText: 'A duck tale', counter: 40 }
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
}, 'posts response')
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
{
|
|
220
|
+
const res = await app.inject({
|
|
221
|
+
method: 'POST',
|
|
222
|
+
url: '/graphql',
|
|
223
|
+
body: {
|
|
224
|
+
query: `
|
|
225
|
+
query {
|
|
226
|
+
posts(where: { or: [ { title: { eq: "Dog" } }, { longText: { eq: "Baz" } } ] }) {
|
|
227
|
+
id
|
|
228
|
+
title
|
|
229
|
+
longText
|
|
230
|
+
counter
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
`
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
equal(res.statusCode, 200, 'posts status code')
|
|
237
|
+
same(res.json(), {
|
|
238
|
+
data: {
|
|
239
|
+
posts: [
|
|
240
|
+
{ id: '1', title: 'Dog', longText: 'Foo', counter: 10 },
|
|
241
|
+
{ id: '3', title: 'Mouse', longText: 'Baz', counter: 30 }
|
|
242
|
+
]
|
|
243
|
+
}
|
|
244
|
+
}, 'posts response')
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
{
|
|
248
|
+
const res = await app.inject({
|
|
249
|
+
method: 'POST',
|
|
250
|
+
url: '/graphql',
|
|
251
|
+
body: {
|
|
252
|
+
query: `
|
|
253
|
+
query {
|
|
254
|
+
posts(where: { counter: { in: [10, 20] }, or: [ { title: { eq: "Dog" } }, { longText: { eq: "Baz" } } ] }) {
|
|
255
|
+
id
|
|
256
|
+
title
|
|
257
|
+
longText
|
|
258
|
+
counter
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
`
|
|
262
|
+
}
|
|
263
|
+
})
|
|
264
|
+
equal(res.statusCode, 200, 'posts status code')
|
|
265
|
+
same(res.json(), {
|
|
266
|
+
data: {
|
|
267
|
+
posts: [
|
|
268
|
+
{ id: '1', title: 'Dog', longText: 'Foo', counter: 10 }
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
}, 'posts response')
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
{
|
|
275
|
+
const res = await app.inject({
|
|
276
|
+
method: 'POST',
|
|
277
|
+
url: '/graphql',
|
|
278
|
+
body: {
|
|
279
|
+
query: `
|
|
280
|
+
query {
|
|
281
|
+
posts(where: { or: [ { counter: { in: [10, 20] } }, { counter: { in: [20, 30] } } ] }) {
|
|
282
|
+
id
|
|
283
|
+
title
|
|
284
|
+
longText
|
|
285
|
+
counter
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
`
|
|
289
|
+
}
|
|
290
|
+
})
|
|
291
|
+
equal(res.statusCode, 200, 'posts status code')
|
|
292
|
+
same(res.json(), {
|
|
293
|
+
data: {
|
|
294
|
+
posts: [
|
|
295
|
+
{ id: '1', title: 'Dog', longText: 'Foo', counter: 10 },
|
|
296
|
+
{ id: '2', title: 'Cat', longText: 'Bar', counter: 20 },
|
|
297
|
+
{ id: '3', title: 'Mouse', longText: 'Baz', counter: 30 }
|
|
298
|
+
]
|
|
299
|
+
}
|
|
300
|
+
}, 'posts response')
|
|
301
|
+
}
|
|
302
|
+
})
|