@platformatic/sql-graphql 0.20.1 → 0.21.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.
@@ -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: Object.keys(fields).reduce((acc, field) => {
105
- acc[field] = {
106
- type: new graphql.GraphQLInputObjectType({
107
- name: `${entityName}WhereArguments${field}`,
124
+ fields: {
125
+ ...whereFields,
126
+ or: {
127
+ type: new graphql.GraphQLList(new graphql.GraphQLInputObjectType({
128
+ name: `${entityName}WhereArgumentsOr`,
108
129
  fields: {
109
- eq: { type: fields[field].type },
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
- return acc
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.GraphQLInt
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.GraphQLFloat
46
+ return graphql.GraphQLString
47
47
  case 'float4':
48
48
  return graphql.GraphQLFloat
49
49
  case 'date':
@@ -53,7 +53,7 @@ function sqlTypeToGraphQL (sqlType) {
53
53
  case 'timestamp':
54
54
  return scalars.GraphQLDateTime
55
55
  case 'uuid':
56
- return graphql.GraphQLString
56
+ return graphql.GraphQLID
57
57
  case 'json':
58
58
  return GraphQLJSONObject
59
59
  case 'jsonb':
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/sql-graphql",
3
- "version": "0.20.1",
3
+ "version": "0.21.1",
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.20.1",
25
- "@platformatic/sql-mapper": "0.20.1"
24
+ "@platformatic/sql-events": "0.21.1",
25
+ "@platformatic/sql-mapper": "0.21.1"
26
26
  },
27
27
  "dependencies": {
28
28
  "@mercuriusjs/federation": "^1.0.1",
@@ -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')
@@ -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
+ })