@platformatic/sql-graphql 0.0.23

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 (54) hide show
  1. package/.nyc_output/0681b2b7-587a-40f2-8242-257bc4c72456.json +1 -0
  2. package/.nyc_output/191054d4-6a1e-4a1b-87bb-f801ed78a223.json +1 -0
  3. package/.nyc_output/22ead0f6-e5a6-4647-a2ea-db2f42498081.json +1 -0
  4. package/.nyc_output/4e847e26-05cd-4063-9277-48aff86d6822.json +1 -0
  5. package/.nyc_output/5acfd416-02d1-497b-8dbd-69c0af167c62.json +1 -0
  6. package/.nyc_output/5ec04f76-9bcb-475d-b79e-f9304cc0026c.json +1 -0
  7. package/.nyc_output/5f3bb47a-0d2d-440a-a466-8ffa9ab3efaa.json +1 -0
  8. package/.nyc_output/71c2bd84-9a72-4e86-83c6-d587ce525fe4.json +1 -0
  9. package/.nyc_output/74cc1dab-7479-48e7-80b0-c97351d8856e.json +1 -0
  10. package/.nyc_output/9f5d12ba-bc3d-461c-a0e2-2a95d2020c19.json +1 -0
  11. package/.nyc_output/ac343b71-6f76-421c-a287-46d19bb48f89.json +1 -0
  12. package/.nyc_output/c1c0eecb-63a0-4258-81b6-50e7488bd67c.json +1 -0
  13. package/.nyc_output/c201a1cd-3105-4d18-bbbb-8d7fa674d439.json +1 -0
  14. package/.nyc_output/d6da0270-e9ed-41e2-bbf3-9262d1df683c.json +1 -0
  15. package/.nyc_output/processinfo/0681b2b7-587a-40f2-8242-257bc4c72456.json +1 -0
  16. package/.nyc_output/processinfo/191054d4-6a1e-4a1b-87bb-f801ed78a223.json +1 -0
  17. package/.nyc_output/processinfo/22ead0f6-e5a6-4647-a2ea-db2f42498081.json +1 -0
  18. package/.nyc_output/processinfo/4e847e26-05cd-4063-9277-48aff86d6822.json +1 -0
  19. package/.nyc_output/processinfo/5acfd416-02d1-497b-8dbd-69c0af167c62.json +1 -0
  20. package/.nyc_output/processinfo/5ec04f76-9bcb-475d-b79e-f9304cc0026c.json +1 -0
  21. package/.nyc_output/processinfo/5f3bb47a-0d2d-440a-a466-8ffa9ab3efaa.json +1 -0
  22. package/.nyc_output/processinfo/71c2bd84-9a72-4e86-83c6-d587ce525fe4.json +1 -0
  23. package/.nyc_output/processinfo/74cc1dab-7479-48e7-80b0-c97351d8856e.json +1 -0
  24. package/.nyc_output/processinfo/9f5d12ba-bc3d-461c-a0e2-2a95d2020c19.json +1 -0
  25. package/.nyc_output/processinfo/ac343b71-6f76-421c-a287-46d19bb48f89.json +1 -0
  26. package/.nyc_output/processinfo/c1c0eecb-63a0-4258-81b6-50e7488bd67c.json +1 -0
  27. package/.nyc_output/processinfo/c201a1cd-3105-4d18-bbbb-8d7fa674d439.json +1 -0
  28. package/.nyc_output/processinfo/d6da0270-e9ed-41e2-bbf3-9262d1df683c.json +1 -0
  29. package/.nyc_output/processinfo/index.json +1 -0
  30. package/.taprc +1 -0
  31. package/LICENSE +201 -0
  32. package/NOTICE +13 -0
  33. package/README.md +13 -0
  34. package/index.d.ts +40 -0
  35. package/index.js +117 -0
  36. package/lib/entity-to-type.js +248 -0
  37. package/lib/relationship.js +67 -0
  38. package/lib/utils.js +77 -0
  39. package/package.json +44 -0
  40. package/test/datatypes.test.js +708 -0
  41. package/test/federation.test.js +312 -0
  42. package/test/helper.js +70 -0
  43. package/test/hooks.test.js +660 -0
  44. package/test/ignore.test.js +117 -0
  45. package/test/insert.test.js +181 -0
  46. package/test/inserted_updated_at.test.js +517 -0
  47. package/test/nested.test.js +862 -0
  48. package/test/no-modification-of-entity.test.js +113 -0
  49. package/test/order_by.test.js +397 -0
  50. package/test/relations.test.js +60 -0
  51. package/test/simple.test.js +708 -0
  52. package/test/sqlite.test.js +276 -0
  53. package/test/types/index.test-d.ts +33 -0
  54. package/test/where.test.js +814 -0
@@ -0,0 +1,517 @@
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, isMysql } = require('./helper')
8
+ const { setTimeout } = require('timers/promises')
9
+
10
+ async function createBasicPages (db, sql) {
11
+ if (isSQLite) {
12
+ await db.query(sql`CREATE TABLE pages (
13
+ id INTEGER PRIMARY KEY,
14
+ title VARCHAR(42),
15
+ inserted_at TIMESTAMP,
16
+ updated_at TIMESTAMP
17
+ );`)
18
+ } else if (isMysql) {
19
+ await db.query(sql`CREATE TABLE pages (
20
+ id SERIAL PRIMARY KEY,
21
+ title VARCHAR(42),
22
+ inserted_at TIMESTAMP NULL DEFAULT NULL,
23
+ updated_at TIMESTAMP NULL DEFAULT NULL
24
+ );`)
25
+ } else {
26
+ await db.query(sql`CREATE TABLE pages (
27
+ id SERIAL PRIMARY KEY,
28
+ title VARCHAR(42),
29
+ inserted_at TIMESTAMP,
30
+ updated_at TIMESTAMP
31
+ );`)
32
+ }
33
+ }
34
+
35
+ test('inserted_at updated_at happy path', async ({ pass, teardown, same, equal, not, comment }) => {
36
+ const app = fastify()
37
+ app.register(sqlMapper, {
38
+ ...connInfo,
39
+ async onDatabaseLoad (db, sql) {
40
+ pass('onDatabaseLoad called')
41
+
42
+ await clear(db, sql)
43
+ await createBasicPages(db, sql)
44
+ }
45
+ })
46
+ app.register(sqlGraphQL)
47
+ teardown(app.close.bind(app))
48
+
49
+ await app.ready()
50
+
51
+ let original
52
+
53
+ {
54
+ const res = await app.inject({
55
+ method: 'POST',
56
+ url: '/graphql',
57
+ body: {
58
+ query: `
59
+ mutation {
60
+ savePage(input: { title: "Hello" }) {
61
+ id
62
+ title
63
+ insertedAt
64
+ updatedAt
65
+ }
66
+ }
67
+ `
68
+ }
69
+ })
70
+ equal(res.statusCode, 200, 'savePage status code')
71
+ const data = res.json().data
72
+ not(data.savePage.insertedAt, null, 'insertedAt')
73
+ not(data.savePage.updatedAt, null, 'updatedAt')
74
+ comment(`insertedAt: ${data.savePage.insertedAt}`)
75
+ comment(`updatedAt: ${data.savePage.updatedAt}`)
76
+ original = data.savePage
77
+ }
78
+
79
+ {
80
+ const res = await app.inject({
81
+ method: 'POST',
82
+ url: '/graphql',
83
+ body: {
84
+ query: `
85
+ query {
86
+ getPageById(id: 1) {
87
+ id
88
+ title
89
+ insertedAt
90
+ updatedAt
91
+ }
92
+ }
93
+ `
94
+ }
95
+ })
96
+ equal(res.statusCode, 200, 'pages status code')
97
+ const data = res.json().data
98
+ equal(data.getPageById.insertedAt, original.insertedAt, 'insertedAt')
99
+ equal(data.getPageById.updatedAt, original.updatedAt, 'updatedAt')
100
+ comment(`insertedAt: ${data.getPageById.insertedAt}`)
101
+ comment(`updatedAt: ${data.getPageById.updatedAt}`)
102
+ }
103
+
104
+ await setTimeout(1000) // await 1s
105
+
106
+ let updated
107
+ {
108
+ const res = await app.inject({
109
+ method: 'POST',
110
+ url: '/graphql',
111
+ body: {
112
+ query: `
113
+ mutation {
114
+ savePage(input: { id: 1, title: "Hello World" }) {
115
+ id
116
+ title
117
+ insertedAt
118
+ updatedAt
119
+ }
120
+ }
121
+ `
122
+ }
123
+ })
124
+ const data = res.json().data
125
+ equal(data.savePage.insertedAt, original.insertedAt, 'insertedAt')
126
+ not(data.savePage.updatedAt, original.updatedAt, 'updatedAt')
127
+ updated = data.savePage
128
+ comment(`insertedAt: ${data.savePage.insertedAt}`)
129
+ comment(`updatedAt: ${data.savePage.updatedAt}`)
130
+ }
131
+
132
+ {
133
+ const res = await app.inject({
134
+ method: 'POST',
135
+ url: '/graphql',
136
+ body: {
137
+ query: `
138
+ query {
139
+ getPageById(id: 1) {
140
+ id
141
+ title
142
+ insertedAt
143
+ updatedAt
144
+ }
145
+ }
146
+ `
147
+ }
148
+ })
149
+ equal(res.statusCode, 200, 'pages status code')
150
+ const data = res.json().data
151
+ equal(data.getPageById.insertedAt, updated.insertedAt, 'insertedAt')
152
+ equal(data.getPageById.updatedAt, updated.updatedAt, 'updatedAt')
153
+ comment(`insertedAt: ${data.getPageById.insertedAt}`)
154
+ comment(`updatedAt: ${data.getPageById.updatedAt}`)
155
+ }
156
+ })
157
+
158
+ test('cannot set inserted_at', async ({ pass, teardown, same, equal, not, comment }) => {
159
+ const app = fastify()
160
+ app.register(sqlMapper, {
161
+ ...connInfo,
162
+ async onDatabaseLoad (db, sql) {
163
+ pass('onDatabaseLoad called')
164
+
165
+ await clear(db, sql)
166
+ await createBasicPages(db, sql)
167
+ }
168
+ })
169
+ app.register(sqlGraphQL)
170
+ teardown(app.close.bind(app))
171
+
172
+ await app.ready()
173
+
174
+ {
175
+ const res = await app.inject({
176
+ method: 'POST',
177
+ url: '/graphql',
178
+ body: {
179
+ query: `
180
+ mutation {
181
+ savePage(input: { title: "Hello", insertedAt: "${new Date().toISOString()}" }) {
182
+ id
183
+ title
184
+ insertedAt
185
+ updatedAt
186
+ }
187
+ }
188
+ `
189
+ }
190
+ })
191
+ equal(res.statusCode, 400, 'savePage status code')
192
+ const data = res.json()
193
+ equal(data.errors[0].message, 'Field "insertedAt" is not defined by type "PageInput".')
194
+ }
195
+ })
196
+
197
+ test('cannot set updated_at', async ({ pass, teardown, same, equal, not, comment }) => {
198
+ const app = fastify()
199
+ app.register(sqlMapper, {
200
+ ...connInfo,
201
+ async onDatabaseLoad (db, sql) {
202
+ pass('onDatabaseLoad called')
203
+
204
+ await clear(db, sql)
205
+ await createBasicPages(db, sql)
206
+ }
207
+ })
208
+ app.register(sqlGraphQL)
209
+ teardown(app.close.bind(app))
210
+
211
+ await app.ready()
212
+
213
+ {
214
+ const res = await app.inject({
215
+ method: 'POST',
216
+ url: '/graphql',
217
+ body: {
218
+ query: `
219
+ mutation {
220
+ savePage(input: { title: "Hello" }) {
221
+ id
222
+ title
223
+ insertedAt
224
+ updatedAt
225
+ }
226
+ }
227
+ `
228
+ }
229
+ })
230
+ equal(res.statusCode, 200, 'savePage status code')
231
+ const data = res.json().data
232
+ not(data.savePage.insertedAt, null, 'insertedAt')
233
+ not(data.savePage.updatedAt, null, 'updatedAt')
234
+ comment(`insertedAt: ${data.savePage.insertedAt}`)
235
+ comment(`updatedAt: ${data.savePage.updatedAt}`)
236
+ }
237
+
238
+ {
239
+ const res = await app.inject({
240
+ method: 'POST',
241
+ url: '/graphql',
242
+ body: {
243
+ query: `
244
+ mutation {
245
+ savePage(input: { id: 1, title: "Hello World", updatedAt: "${new Date().toISOString()}" }) {
246
+ id
247
+ title
248
+ insertedAt
249
+ updatedAt
250
+ }
251
+ }
252
+ `
253
+ }
254
+ })
255
+ equal(res.statusCode, 400, 'savePage status code')
256
+ const data = res.json()
257
+ equal(data.errors[0].message, 'Field "updatedAt" is not defined by type "PageInput".')
258
+ }
259
+ })
260
+
261
+ test('do not assign inserted_at updated_at', async ({ pass, teardown, same, equal, not, comment }) => {
262
+ const app = fastify()
263
+ app.register(sqlMapper, {
264
+ ...connInfo,
265
+ autoTimestamp: false,
266
+ async onDatabaseLoad (db, sql) {
267
+ pass('onDatabaseLoad called')
268
+
269
+ await clear(db, sql)
270
+ await createBasicPages(db, sql)
271
+ }
272
+ })
273
+ app.register(sqlGraphQL)
274
+ teardown(app.close.bind(app))
275
+
276
+ await app.ready()
277
+
278
+ {
279
+ const res = await app.inject({
280
+ method: 'POST',
281
+ url: '/graphql',
282
+ body: {
283
+ query: `
284
+ mutation {
285
+ savePage(input: { title: "Hello" }) {
286
+ id
287
+ title
288
+ insertedAt
289
+ updatedAt
290
+ }
291
+ }
292
+ `
293
+ }
294
+ })
295
+ equal(res.statusCode, 200, 'savePage status code')
296
+ const data = res.json().data
297
+ equal(data.savePage.insertedAt, null, 'insertedAt')
298
+ equal(data.savePage.updatedAt, null, 'updatedAt')
299
+ }
300
+
301
+ {
302
+ const res = await app.inject({
303
+ method: 'POST',
304
+ url: '/graphql',
305
+ body: {
306
+ query: `
307
+ query {
308
+ getPageById(id: 1) {
309
+ id
310
+ title
311
+ insertedAt
312
+ updatedAt
313
+ }
314
+ }
315
+ `
316
+ }
317
+ })
318
+ equal(res.statusCode, 200, 'pages status code')
319
+ const data = res.json().data
320
+ equal(data.getPageById.insertedAt, null, 'insertedAt')
321
+ equal(data.getPageById.updatedAt, null, 'updatedAt')
322
+ }
323
+
324
+ {
325
+ const res = await app.inject({
326
+ method: 'POST',
327
+ url: '/graphql',
328
+ body: {
329
+ query: `
330
+ mutation {
331
+ savePage(input: { id: 1, title: "Hello World" }) {
332
+ id
333
+ title
334
+ insertedAt
335
+ updatedAt
336
+ }
337
+ }
338
+ `
339
+ }
340
+ })
341
+ const data = res.json().data
342
+ equal(data.savePage.insertedAt, null, 'insertedAt')
343
+ equal(data.savePage.updatedAt, null, 'updatedAt')
344
+ }
345
+
346
+ {
347
+ const res = await app.inject({
348
+ method: 'POST',
349
+ url: '/graphql',
350
+ body: {
351
+ query: `
352
+ query {
353
+ getPageById(id: 1) {
354
+ id
355
+ title
356
+ insertedAt
357
+ updatedAt
358
+ }
359
+ }
360
+ `
361
+ }
362
+ })
363
+ equal(res.statusCode, 200, 'pages status code')
364
+ const data = res.json().data
365
+ equal(data.getPageById.insertedAt, null, 'insertedAt')
366
+ equal(data.getPageById.updatedAt, null, 'updatedAt')
367
+ }
368
+ })
369
+
370
+ test('bulk insert adds inserted_at updated_at', async ({ pass, teardown, same, equal, not, comment }) => {
371
+ const app = fastify()
372
+ app.register(sqlMapper, {
373
+ ...connInfo,
374
+ async onDatabaseLoad (db, sql) {
375
+ pass('onDatabaseLoad called')
376
+
377
+ await clear(db, sql)
378
+ await createBasicPages(db, sql)
379
+ }
380
+ })
381
+ app.register(sqlGraphQL)
382
+ teardown(app.close.bind(app))
383
+
384
+ await app.ready()
385
+
386
+ {
387
+ const res = await app.inject({
388
+ method: 'POST',
389
+ url: '/graphql',
390
+ body: {
391
+ query: `
392
+ mutation {
393
+ savePage(input: { title: "Hello" }) {
394
+ id
395
+ title
396
+ insertedAt
397
+ updatedAt
398
+ }
399
+ }
400
+ `
401
+ }
402
+ })
403
+ equal(res.statusCode, 200, 'savePage status code')
404
+ const data = res.json().data
405
+ not(data.savePage.insertedAt, null, 'insertedAt')
406
+ not(data.savePage.updatedAt, null, 'updatedAt')
407
+ }
408
+
409
+ {
410
+ const res = await app.inject({
411
+ method: 'POST',
412
+ url: '/graphql',
413
+ body: {
414
+ query: `
415
+ mutation batch($inputs : [PageInput]!) {
416
+ insertPages (inputs: $inputs) {
417
+ id
418
+ title
419
+ insertedAt
420
+ updatedAt
421
+ }
422
+ }
423
+ `,
424
+ variables: {
425
+ inputs: [
426
+ { title: 'Page 1' },
427
+ { title: 'Page 2' },
428
+ { title: 'Page 3' }
429
+ ]
430
+ }
431
+ }
432
+ })
433
+ equal(res.statusCode, 200, 'savePage status code')
434
+ const pages = res.json().data.insertPages
435
+ for (const page of pages) {
436
+ not(page.insertedAt, null, 'insertedAt')
437
+ not(page.updatedAt, null, 'updatedAt')
438
+ equal(page.insertedAt, page.updatedAt, 'insertedAt === updatedAt')
439
+ }
440
+ }
441
+
442
+ {
443
+ const res = await app.inject({
444
+ method: 'POST',
445
+ url: '/graphql',
446
+ body: {
447
+ query: `
448
+ query {
449
+ pages {
450
+ id
451
+ title
452
+ insertedAt
453
+ updatedAt
454
+ }
455
+ }
456
+ `
457
+ }
458
+ })
459
+ equal(res.statusCode, 200, 'pages status code')
460
+ const pages = res.json().data.pages
461
+ for (const page of pages) {
462
+ not(page.insertedAt, null, 'insertedAt')
463
+ not(page.updatedAt, null, 'updatedAt')
464
+ equal(page.insertedAt, page.updatedAt, 'insertedAt === updatedAt')
465
+ }
466
+ }
467
+ })
468
+
469
+ test('bulk insert with autoTimestamp=false do not hadd inserted_at updated_at', async ({ pass, teardown, same, equal, not, comment }) => {
470
+ const app = fastify()
471
+ app.register(sqlMapper, {
472
+ ...connInfo,
473
+ autoTimestamp: false,
474
+ async onDatabaseLoad (db, sql) {
475
+ pass('onDatabaseLoad called')
476
+
477
+ await clear(db, sql)
478
+ await createBasicPages(db, sql)
479
+ }
480
+ })
481
+ app.register(sqlGraphQL)
482
+ teardown(app.close.bind(app))
483
+
484
+ await app.ready()
485
+
486
+ {
487
+ const res = await app.inject({
488
+ method: 'POST',
489
+ url: '/graphql',
490
+ body: {
491
+ query: `
492
+ mutation batch($inputs : [PageInput]!) {
493
+ insertPages (inputs: $inputs) {
494
+ id
495
+ title
496
+ insertedAt
497
+ updatedAt
498
+ }
499
+ }
500
+ `,
501
+ variables: {
502
+ inputs: [
503
+ { title: 'Page 1' },
504
+ { title: 'Page 2' },
505
+ { title: 'Page 3' }
506
+ ]
507
+ }
508
+ }
509
+ })
510
+ equal(res.statusCode, 200, 'savePage status code')
511
+ const pages = res.json().data.insertPages
512
+ for (const page of pages) {
513
+ equal(page.insertedAt, null, 'insertedAt')
514
+ equal(page.updatedAt, null, 'updatedAt')
515
+ }
516
+ }
517
+ })