@platformatic/sql-graphql 0.46.1 → 0.47.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/sql-graphql",
3
- "version": "0.46.1",
3
+ "version": "0.47.0",
4
4
  "description": "Map SQL dbs to GraphQL",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -22,8 +22,8 @@
22
22
  "tap": "^16.3.6",
23
23
  "tsd": "^0.29.0",
24
24
  "ws": "^8.13.0",
25
- "@platformatic/sql-events": "0.46.1",
26
- "@platformatic/sql-mapper": "0.46.1"
25
+ "@platformatic/sql-events": "0.47.0",
26
+ "@platformatic/sql-mapper": "0.47.0"
27
27
  },
28
28
  "dependencies": {
29
29
  "@fastify/error": "^3.2.1",
@@ -35,7 +35,7 @@
35
35
  "graphql-type-json": "^0.3.2",
36
36
  "inflected": "^2.1.0",
37
37
  "mercurius": "^13.0.0",
38
- "@platformatic/utils": "0.46.1"
38
+ "@platformatic/utils": "0.47.0"
39
39
  },
40
40
  "tsd": {
41
41
  "directory": "test/types"
@@ -1,372 +0,0 @@
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, isPg } = require('./helper')
8
-
9
- test('array support', { skip: !isPg }, 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
- await db.query(sql`CREATE TABLE pages (
18
- id SERIAL PRIMARY KEY,
19
- title VARCHAR(42) NOT NULL,
20
- tags VARCHAR(42)[] NOT NULL
21
- );`)
22
- }
23
- })
24
- app.register(sqlGraphQL)
25
- teardown(app.close.bind(app))
26
-
27
- await app.ready()
28
-
29
- {
30
- const res = await app.inject({
31
- method: 'POST',
32
- url: '/graphql',
33
- body: {
34
- query: `
35
- mutation {
36
- savePage(input: { title: "Hello", tags: ["foo", "bar"] }) {
37
- id
38
- title
39
- tags
40
- }
41
- }
42
- `
43
- }
44
- })
45
- equal(res.statusCode, 200, 'savePage status code')
46
- same(res.json(), {
47
- data: {
48
- savePage: {
49
- id: 1,
50
- title: 'Hello',
51
- tags: ['foo', 'bar']
52
- }
53
- }
54
- }, 'savePage response')
55
- }
56
-
57
- {
58
- const res = await app.inject({
59
- method: 'POST',
60
- url: '/graphql',
61
- body: {
62
- query: `
63
- query {
64
- getPageById(id: 1) {
65
- id
66
- title,
67
- tags
68
- }
69
- }
70
- `
71
- }
72
- })
73
- equal(res.statusCode, 200, 'pages status code')
74
- same(res.json(), {
75
- data: {
76
- getPageById: {
77
- id: 1,
78
- title: 'Hello',
79
- tags: ['foo', 'bar']
80
- }
81
- }
82
- }, 'pages response')
83
- }
84
-
85
- {
86
- const res = await app.inject({
87
- method: 'POST',
88
- url: '/graphql',
89
- body: {
90
- query: `
91
- query {
92
- pages(where: { tags: { any: "foo" } }) {
93
- id
94
- title
95
- tags
96
- }
97
- }
98
- `
99
- }
100
- })
101
- equal(res.statusCode, 200, 'pages status code')
102
- same(res.json(), {
103
- data: {
104
- pages: [{
105
- id: 1,
106
- title: 'Hello',
107
- tags: ['foo', 'bar']
108
- }]
109
- }
110
- }, 'pages response')
111
- }
112
-
113
- {
114
- const res = await app.inject({
115
- method: 'POST',
116
- url: '/graphql',
117
- body: {
118
- query: `
119
- query {
120
- pages(where: { tags: { contains: ["foo"] } }) {
121
- id
122
- title
123
- tags
124
- }
125
- }
126
- `
127
- }
128
- })
129
- equal(res.statusCode, 200, 'pages status code')
130
- same(res.json(), {
131
- data: {
132
- pages: [{
133
- id: 1,
134
- title: 'Hello',
135
- tags: ['foo', 'bar']
136
- }]
137
- }
138
- }, 'pages response')
139
- }
140
-
141
- {
142
- const res = await app.inject({
143
- method: 'POST',
144
- url: '/graphql',
145
- body: {
146
- query: `
147
- query {
148
- pages(where: { tags: { contained: ["foo", "bar"] } }) {
149
- id
150
- title
151
- tags
152
- }
153
- }
154
- `
155
- }
156
- })
157
- equal(res.statusCode, 200, 'pages status code')
158
- same(res.json(), {
159
- data: {
160
- pages: [{
161
- id: 1,
162
- title: 'Hello',
163
- tags: ['foo', 'bar']
164
- }]
165
- }
166
- }, 'pages response')
167
- }
168
-
169
- {
170
- const res = await app.inject({
171
- method: 'POST',
172
- url: '/graphql',
173
- body: {
174
- query: `
175
- query {
176
- pages(where: { tags: { overlaps: ["foo"] } }) {
177
- id
178
- title
179
- tags
180
- }
181
- }
182
- `
183
- }
184
- })
185
- equal(res.statusCode, 200, 'pages status code')
186
- same(res.json(), {
187
- data: {
188
- pages: [{
189
- id: 1,
190
- title: 'Hello',
191
- tags: ['foo', 'bar']
192
- }]
193
- }
194
- }, 'pages response')
195
- }
196
-
197
- {
198
- const res = await app.inject({
199
- method: 'POST',
200
- url: '/graphql',
201
- body: {
202
- query: `
203
- query {
204
- pages(where: { tags: { any: "baz" } }) {
205
- id
206
- title,
207
- tags
208
- }
209
- }
210
- `
211
- }
212
- })
213
- equal(res.statusCode, 200, 'pages status code')
214
- same(res.json(), {
215
- data: {
216
- pages: []
217
- }
218
- }, 'pages response')
219
- }
220
-
221
- {
222
- const res = await app.inject({
223
- method: 'POST',
224
- url: '/graphql',
225
- body: {
226
- query: `
227
- query {
228
- pages(where: { tags: { contains: ["baz"] } }) {
229
- id
230
- title,
231
- tags
232
- }
233
- }
234
- `
235
- }
236
- })
237
- equal(res.statusCode, 200, 'pages status code')
238
- same(res.json(), {
239
- data: {
240
- pages: []
241
- }
242
- }, 'pages response')
243
- }
244
-
245
- {
246
- const res = await app.inject({
247
- method: 'POST',
248
- url: '/graphql',
249
- body: {
250
- query: `
251
- query {
252
- pages(where: { tags: { contained: ["foo"] } }) {
253
- id
254
- title,
255
- tags
256
- }
257
- }
258
- `
259
- }
260
- })
261
- equal(res.statusCode, 200, 'pages status code')
262
- same(res.json(), {
263
- data: {
264
- pages: []
265
- }
266
- }, 'pages response')
267
- }
268
-
269
- {
270
- const res = await app.inject({
271
- method: 'POST',
272
- url: '/graphql',
273
- body: {
274
- query: `
275
- query {
276
- pages(where: { tags: { overlaps: ["baz"] } }) {
277
- id
278
- title,
279
- tags
280
- }
281
- }
282
- `
283
- }
284
- })
285
- equal(res.statusCode, 200, 'pages status code')
286
- same(res.json(), {
287
- data: {
288
- pages: []
289
- }
290
- }, 'pages response')
291
- }
292
-
293
- {
294
- const res = await app.inject({
295
- method: 'POST',
296
- url: '/graphql',
297
- body: {
298
- query: `
299
- query {
300
- pages(where: { tags: { all: "foo" } }) {
301
- id
302
- title,
303
- tags
304
- }
305
- }
306
- `
307
- }
308
- })
309
- equal(res.statusCode, 200, 'pages status code')
310
- same(res.json(), {
311
- data: {
312
- pages: []
313
- }
314
- }, 'pages response')
315
- }
316
-
317
- {
318
- const res = await app.inject({
319
- method: 'POST',
320
- url: '/graphql',
321
- body: {
322
- query: `
323
- mutation {
324
- savePage(input: { id: 1, title: "Hello World", tags: ["foo", "bar", "baz"] }) {
325
- id
326
- title
327
- tags
328
- }
329
- }
330
- `
331
- }
332
- })
333
- equal(res.statusCode, 200, 'savePage status code')
334
- same(res.json(), {
335
- data: {
336
- savePage: {
337
- id: 1,
338
- title: 'Hello World',
339
- tags: ['foo', 'bar', 'baz']
340
- }
341
- }
342
- }, 'savePage response')
343
- }
344
-
345
- {
346
- const res = await app.inject({
347
- method: 'POST',
348
- url: '/graphql',
349
- body: {
350
- query: `
351
- query {
352
- getPageById(id: 1) {
353
- id
354
- title
355
- tags
356
- }
357
- }
358
- `
359
- }
360
- })
361
- equal(res.statusCode, 200, 'pages status code')
362
- same(res.json(), {
363
- data: {
364
- getPageById: {
365
- id: 1,
366
- title: 'Hello World',
367
- tags: ['foo', 'bar', 'baz']
368
- }
369
- }
370
- }, 'pages response')
371
- }
372
- })
@@ -1,312 +0,0 @@
1
- 'use strict'
2
-
3
- const { test } = require('tap')
4
- const Fastify = require('fastify')
5
- const WebSocket = require('ws')
6
- const { once } = require('events')
7
- const sqlGraphQL = require('..')
8
- const sqlMapper = require('@platformatic/sql-mapper')
9
- const sqlEvents = require('@platformatic/sql-events')
10
- const { clear, connInfo, isSQLite } = require('./helper')
11
- const stream = require('stream')
12
-
13
- async function createBasicPages (db, sql) {
14
- if (isSQLite) {
15
- await db.query(sql`CREATE TABLE pages (
16
- page_id INTEGER PRIMARY KEY,
17
- title VARCHAR(42)
18
- );`)
19
- } else {
20
- await db.query(sql`CREATE TABLE pages (
21
- page_id SERIAL PRIMARY KEY,
22
- title VARCHAR(42)
23
- );`)
24
- }
25
- }
26
-
27
- function createWebSocketClient (t, app) {
28
- const ws = new WebSocket('ws://localhost:' + (app.server.address()).port + '/graphql', 'graphql-ws')
29
- const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8', objectMode: true })
30
- t.teardown(client.destroy.bind(client))
31
- client.setEncoding('utf8')
32
- return { client, ws }
33
- }
34
-
35
- test('subscription - crud when there is a primary key to be camelised', async t => {
36
- const app = Fastify()
37
- t.teardown(() => app.close())
38
-
39
- app.register(sqlMapper, {
40
- ...connInfo,
41
- async onDatabaseLoad (db, sql) {
42
- await clear(db, sql)
43
- await createBasicPages(db, sql)
44
- }
45
- })
46
- app.register(sqlEvents)
47
- app.register(sqlGraphQL)
48
-
49
- await app.listen({ port: 0 })
50
-
51
- const { client } = createWebSocketClient(t, app)
52
-
53
- client.write(JSON.stringify({
54
- type: 'connection_init'
55
- }))
56
-
57
- {
58
- const query = `subscription {
59
- pageSaved {
60
- pageId
61
- title
62
- }
63
- }`
64
- client.write(JSON.stringify({
65
- pageId: 1,
66
- type: 'start',
67
- payload: {
68
- query
69
- }
70
- }))
71
- }
72
-
73
- {
74
- const query = `subscription {
75
- pageDeleted {
76
- pageId
77
- }
78
- }`
79
- client.write(JSON.stringify({
80
- pageId: 1,
81
- type: 'start',
82
- payload: {
83
- query
84
- }
85
- }))
86
- }
87
-
88
- {
89
- const [chunk] = await once(client, 'data')
90
- const data = JSON.parse(chunk)
91
- t.equal(data.type, 'connection_ack')
92
- }
93
-
94
- t.comment('sending mutation')
95
-
96
- await app.inject({
97
- method: 'POST',
98
- url: '/graphql',
99
- body: {
100
- query: `
101
- mutation {
102
- savePage(input: { title: "Hello World" }) {
103
- pageId
104
- }
105
- }
106
- `
107
- }
108
- })
109
-
110
- t.comment('mutation sent')
111
-
112
- {
113
- const [chunk] = await once(client, 'data')
114
- const data = JSON.parse(chunk)
115
- t.same(data, {
116
- type: 'data',
117
- payload: {
118
- data: {
119
- pageSaved: {
120
- pageId: '1',
121
- title: 'Hello World'
122
- }
123
- }
124
- }
125
- })
126
- }
127
-
128
- t.comment('updating entity')
129
-
130
- await app.inject({
131
- method: 'POST',
132
- url: '/graphql',
133
- body: {
134
- query: `
135
- mutation {
136
- savePage(input: { pageId: 1, title: "Il libraccio" }) {
137
- pageId
138
- }
139
- }
140
- `
141
- }
142
- })
143
-
144
- t.comment('entity updated')
145
-
146
- {
147
- const [chunk] = await once(client, 'data')
148
- const data = JSON.parse(chunk)
149
- t.same(data, {
150
- type: 'data',
151
- payload: {
152
- data: {
153
- pageSaved: {
154
- pageId: '1',
155
- title: 'Il libraccio'
156
- }
157
- }
158
- }
159
- })
160
- }
161
-
162
- t.comment('deleting entity')
163
-
164
- await app.inject({
165
- method: 'POST',
166
- url: '/graphql',
167
- body: {
168
- query: `
169
- mutation {
170
- deletePages(where: { pageId: { eq: 1 } }) {
171
- pageId
172
- }
173
- }
174
- `
175
- }
176
- })
177
-
178
- t.comment('entity deleted')
179
-
180
- {
181
- const [chunk] = await once(client, 'data')
182
- const data = JSON.parse(chunk)
183
- t.same(data, {
184
- type: 'data',
185
- payload: {
186
- data: {
187
- pageDeleted: {
188
- pageId: '1'
189
- }
190
- }
191
- }
192
- })
193
- }
194
-
195
- t.comment('sending mutation')
196
-
197
- {
198
- const [
199
- received,
200
- stored
201
- ] = await Promise.all(([
202
- (async function () {
203
- const res = await app.inject({
204
- method: 'POST',
205
- url: '/graphql',
206
- body: {
207
- query: `
208
- mutation batch($inputs : [PageInput]!) {
209
- insertPages (inputs: $inputs) {
210
- pageId
211
- title
212
- }
213
- }
214
- `,
215
- variables: {
216
- inputs: [
217
- { title: 'Page 1' },
218
- { title: 'Page 2' },
219
- { title: 'Page 3' }
220
- ]
221
- }
222
- }
223
- })
224
- t.comment('mutation sent')
225
- const pages = res.json().data.insertPages
226
- t.comment(JSON.stringify(pages, null, 2))
227
- return pages
228
- })(),
229
- (async function () {
230
- const pages = []
231
- const second = new stream.PassThrough({ objectMode: true })
232
- client.pipe(second)
233
- for await (const chunk of second) {
234
- const data = JSON.parse(chunk)
235
- pages.push(data.payload.data.pageSaved)
236
- if (pages.length === 3) {
237
- break
238
- }
239
- }
240
- t.comment('received all pages', JSON.stringify(pages, null, 2))
241
- return pages
242
- })()
243
- ]))
244
-
245
- t.same(received, stored)
246
- }
247
- })
248
-
249
- test('subscription - crud with a primary key to be camelised, two schemas and a ignore', async t => {
250
- const app = Fastify()
251
- t.teardown(() => app.close())
252
-
253
- app.register(sqlMapper, {
254
- ...connInfo,
255
- async onDatabaseLoad (db, sql) {
256
- await clear(db, sql)
257
- await createBasicPages(db, sql)
258
-
259
- if (isSQLite) {
260
- await db.query(sql`CREATE TABLE categories (
261
- category_id INTEGER PRIMARY KEY,
262
- name VARCHAR(42)
263
- );`)
264
- } else {
265
- await db.query(sql`CREATE TABLE categories (
266
- category_id SERIAL PRIMARY KEY,
267
- name VARCHAR(42)
268
- );`)
269
- }
270
- }
271
- })
272
- app.register(sqlEvents)
273
- app.register(sqlGraphQL, {
274
- subscriptionIgnore: ['category']
275
- })
276
-
277
- await app.listen({ port: 0 })
278
-
279
- const { client } = createWebSocketClient(t, app)
280
- t.teardown(() => client.destroy())
281
-
282
- client.write(JSON.stringify({
283
- type: 'connection_init'
284
- }))
285
-
286
- {
287
- const [chunk] = await once(client, 'data')
288
- const data = JSON.parse(chunk)
289
- t.equal(data.type, 'connection_ack')
290
- }
291
-
292
- {
293
- const query = `subscription {
294
- categorySaved {
295
- categoryId
296
- }
297
- }`
298
- client.write(JSON.stringify({
299
- categoryId: 1,
300
- type: 'start',
301
- payload: {
302
- query
303
- }
304
- }))
305
- }
306
-
307
- {
308
- const [chunk] = await once(client, 'data')
309
- const data = JSON.parse(chunk)
310
- t.equal(data.payload, 'The subscription field "categorySaved" is not defined.')
311
- }
312
- })