@platformatic/sql-graphql 0.45.1 → 0.46.2
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/index.js +18 -2
- package/lib/entity-to-type.js +14 -0
- package/package.json +5 -4
- package/test/array.test.js +0 -372
- package/test/camelcase.test.js +0 -312
- package/test/composite.test.js +0 -474
- package/test/count.test.js +0 -126
- package/test/created_updated_at.test.js +0 -517
- package/test/datatypes.test.js +0 -803
- package/test/enum.test.js +0 -225
- package/test/federation.test.js +0 -312
- package/test/fix-428.test.js +0 -172
- package/test/helper.js +0 -169
- package/test/hooks.test.js +0 -660
- package/test/ignore.test.js +0 -207
- package/test/insert.test.js +0 -181
- package/test/inserted_updated_at.test.js +0 -533
- package/test/nested.test.js +0 -1269
- package/test/no-modification-of-entity.test.js +0 -113
- package/test/or.test.js +0 -302
- package/test/order_by.test.js +0 -397
- package/test/relations.test.js +0 -785
- package/test/schema.test.js +0 -277
- package/test/simple.test.js +0 -959
- package/test/special-chars.test.js +0 -47
- package/test/sqlite.test.js +0 -274
- package/test/subscription.test.js +0 -336
- package/test/types/errors.test-d.ts +0 -15
- package/test/types/index.test-d.ts +0 -32
- package/test/where.test.js +0 -1102
package/index.js
CHANGED
|
@@ -5,6 +5,7 @@ const constructGraph = require('./lib/entity-to-type')
|
|
|
5
5
|
const mercurius = require('mercurius')
|
|
6
6
|
const graphql = require('graphql')
|
|
7
7
|
const { mercuriusFederationPlugin } = require('@mercuriusjs/federation')
|
|
8
|
+
const { findNearestString } = require('@platformatic/utils')
|
|
8
9
|
const establishRelations = require('./lib/relationship')
|
|
9
10
|
const setupSubscriptions = require('./lib/subscriptions')
|
|
10
11
|
const scalars = require('graphql-scalars')
|
|
@@ -37,12 +38,27 @@ async function mapperToGraphql (app, opts) {
|
|
|
37
38
|
hello: () => 'Hello Platformatic!'
|
|
38
39
|
}
|
|
39
40
|
} else {
|
|
41
|
+
const entitiesNames = Object.values(mapper.entities)
|
|
42
|
+
.map(entity => entity.singularName)
|
|
43
|
+
|
|
44
|
+
for (const ignoredEntity of Object.keys(ignore)) {
|
|
45
|
+
if (!entitiesNames.includes(ignoredEntity)) {
|
|
46
|
+
const nearestEntity = findNearestString(entitiesNames, ignoredEntity)
|
|
47
|
+
let warningMessage = `Ignored graphql entity "${ignoredEntity}" not found.`
|
|
48
|
+
/* istanbul ignore next */
|
|
49
|
+
if (nearestEntity) {
|
|
50
|
+
warningMessage += ` Did you mean "${nearestEntity}"?`
|
|
51
|
+
}
|
|
52
|
+
app.log.warn(warningMessage)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
40
56
|
for (const entity of Object.values(mapper.entities)) {
|
|
41
|
-
if (ignore[entity.
|
|
57
|
+
if (ignore[entity.singularName] === true) {
|
|
42
58
|
continue
|
|
43
59
|
}
|
|
44
60
|
relations.push(...entity.relations)
|
|
45
|
-
const meta = constructGraph(app, entity, graphOpts, ignore[entity.
|
|
61
|
+
const meta = constructGraph(app, entity, graphOpts, ignore[entity.singularName] || {})
|
|
46
62
|
metaMap.set(entity, meta)
|
|
47
63
|
}
|
|
48
64
|
|
package/lib/entity-to-type.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const graphql = require('graphql')
|
|
4
4
|
const camelcase = require('camelcase')
|
|
5
|
+
const { findNearestString } = require('@platformatic/utils')
|
|
5
6
|
const {
|
|
6
7
|
sqlTypeToGraphQL,
|
|
7
8
|
fromSelectionSet
|
|
@@ -37,6 +38,19 @@ function constructGraph (app, entity, opts, ignore) {
|
|
|
37
38
|
loaders
|
|
38
39
|
} = opts
|
|
39
40
|
|
|
41
|
+
const entityFieldsNames = Object.values(entity.fields)
|
|
42
|
+
.map(field => field.camelcase)
|
|
43
|
+
|
|
44
|
+
for (const ignoredField of Object.keys(ignore)) {
|
|
45
|
+
if (!entityFieldsNames.includes(ignoredField)) {
|
|
46
|
+
const nearestField = findNearestString(entityFieldsNames, ignoredField)
|
|
47
|
+
app.log.warn(
|
|
48
|
+
`Ignored graphql field "${ignoredField}" not found in entity "${entity.singularName}".` +
|
|
49
|
+
` Did you mean "${nearestField}"?`
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
40
54
|
const fields = {}
|
|
41
55
|
|
|
42
56
|
for (const key of Object.keys(entity.fields)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/sql-graphql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.2",
|
|
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.
|
|
26
|
-
"@platformatic/sql-mapper": "0.
|
|
25
|
+
"@platformatic/sql-events": "0.46.2",
|
|
26
|
+
"@platformatic/sql-mapper": "0.46.2"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@fastify/error": "^3.2.1",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"graphql-scalars": "^1.22.2",
|
|
35
35
|
"graphql-type-json": "^0.3.2",
|
|
36
36
|
"inflected": "^2.1.0",
|
|
37
|
-
"mercurius": "^13.0.0"
|
|
37
|
+
"mercurius": "^13.0.0",
|
|
38
|
+
"@platformatic/utils": "0.46.2"
|
|
38
39
|
},
|
|
39
40
|
"tsd": {
|
|
40
41
|
"directory": "test/types"
|
package/test/array.test.js
DELETED
|
@@ -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
|
-
})
|