@platformatic/sql-graphql 0.31.0 → 0.32.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/README.md +1 -1
- package/lib/entity-to-type.js +31 -14
- package/package.json +3 -3
- package/test/array.test.js +216 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @platformatic/sql-graphql
|
|
2
2
|
|
|
3
|
-
Check out the full documentation on [our website](https://
|
|
3
|
+
Check out the full documentation on [our website](https://docs.platformatic.dev/docs/reference/sql-graphql/queries).
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
package/lib/entity-to-type.js
CHANGED
|
@@ -47,8 +47,12 @@ function constructGraph (app, entity, opts, ignore) {
|
|
|
47
47
|
const meta = { field }
|
|
48
48
|
|
|
49
49
|
// sqlite doesn't support enums
|
|
50
|
+
// PG does support Arrays as columns
|
|
50
51
|
/* istanbul ignore next */
|
|
51
|
-
if (field.
|
|
52
|
+
if (field.isArray) {
|
|
53
|
+
const listType = sqlTypeToGraphQL(field.sqlType)
|
|
54
|
+
meta.type = new graphql.GraphQLList(listType)
|
|
55
|
+
} else if (field.enum) {
|
|
52
56
|
const enumValues = field.enum.reduce((acc, enumValue, index) => {
|
|
53
57
|
let key = enumValue.replace(/[^\w\s]/g, '_')
|
|
54
58
|
|
|
@@ -100,20 +104,30 @@ function constructGraph (app, entity, opts, ignore) {
|
|
|
100
104
|
}).flat())].join('_'))
|
|
101
105
|
|
|
102
106
|
const whereFields = Object.keys(fields).reduce((acc, field) => {
|
|
107
|
+
let graphqlFields
|
|
108
|
+
/* istanbul ignore else */
|
|
109
|
+
if (!fields[field].field.isArray) {
|
|
110
|
+
graphqlFields = {
|
|
111
|
+
eq: { type: fields[field].type },
|
|
112
|
+
neq: { type: fields[field].type },
|
|
113
|
+
gt: { type: fields[field].type },
|
|
114
|
+
gte: { type: fields[field].type },
|
|
115
|
+
lt: { type: fields[field].type },
|
|
116
|
+
lte: { type: fields[field].type },
|
|
117
|
+
like: { type: fields[field].type },
|
|
118
|
+
in: { type: new graphql.GraphQLList(fields[field].type) },
|
|
119
|
+
nin: { type: new graphql.GraphQLList(fields[field].type) }
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
graphqlFields = {
|
|
123
|
+
any: { type: fields[field].type.ofType },
|
|
124
|
+
all: { type: fields[field].type.ofType }
|
|
125
|
+
}
|
|
126
|
+
}
|
|
103
127
|
acc[field] = {
|
|
104
128
|
type: new graphql.GraphQLInputObjectType({
|
|
105
129
|
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
|
-
}
|
|
130
|
+
fields: graphqlFields
|
|
117
131
|
})
|
|
118
132
|
}
|
|
119
133
|
return acc
|
|
@@ -163,8 +177,11 @@ function constructGraph (app, entity, opts, ignore) {
|
|
|
163
177
|
const orderByFields = new graphql.GraphQLEnumType({
|
|
164
178
|
name: `${entityName}OrderByField`,
|
|
165
179
|
values: Object.keys(fields).reduce((acc, field) => {
|
|
166
|
-
|
|
167
|
-
|
|
180
|
+
/* istanbul ignore else */
|
|
181
|
+
if (!fields[field].isArray) {
|
|
182
|
+
acc[field] = {
|
|
183
|
+
value: field
|
|
184
|
+
}
|
|
168
185
|
}
|
|
169
186
|
return acc
|
|
170
187
|
}, {})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/sql-graphql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.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.28.1",
|
|
24
24
|
"ws": "^8.13.0",
|
|
25
|
-
"@platformatic/sql-events": "0.
|
|
26
|
-
"@platformatic/sql-mapper": "0.
|
|
25
|
+
"@platformatic/sql-events": "0.32.0",
|
|
26
|
+
"@platformatic/sql-mapper": "0.32.0"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@mercuriusjs/federation": "^2.0.0",
|
|
@@ -0,0 +1,216 @@
|
|
|
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: { any: "baz" } }) {
|
|
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
|
+
}
|
|
134
|
+
}, 'pages response')
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
{
|
|
138
|
+
const res = await app.inject({
|
|
139
|
+
method: 'POST',
|
|
140
|
+
url: '/graphql',
|
|
141
|
+
body: {
|
|
142
|
+
query: `
|
|
143
|
+
query {
|
|
144
|
+
pages(where: { tags: { all: "foo" } }) {
|
|
145
|
+
id
|
|
146
|
+
title,
|
|
147
|
+
tags
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
`
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
equal(res.statusCode, 200, 'pages status code')
|
|
154
|
+
same(res.json(), {
|
|
155
|
+
data: {
|
|
156
|
+
pages: []
|
|
157
|
+
}
|
|
158
|
+
}, 'pages response')
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
{
|
|
162
|
+
const res = await app.inject({
|
|
163
|
+
method: 'POST',
|
|
164
|
+
url: '/graphql',
|
|
165
|
+
body: {
|
|
166
|
+
query: `
|
|
167
|
+
mutation {
|
|
168
|
+
savePage(input: { id: 1, title: "Hello World", tags: ["foo", "bar", "baz"] }) {
|
|
169
|
+
id
|
|
170
|
+
title
|
|
171
|
+
tags
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
`
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
equal(res.statusCode, 200, 'savePage status code')
|
|
178
|
+
same(res.json(), {
|
|
179
|
+
data: {
|
|
180
|
+
savePage: {
|
|
181
|
+
id: 1,
|
|
182
|
+
title: 'Hello World',
|
|
183
|
+
tags: ['foo', 'bar', 'baz']
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}, 'savePage response')
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
{
|
|
190
|
+
const res = await app.inject({
|
|
191
|
+
method: 'POST',
|
|
192
|
+
url: '/graphql',
|
|
193
|
+
body: {
|
|
194
|
+
query: `
|
|
195
|
+
query {
|
|
196
|
+
getPageById(id: 1) {
|
|
197
|
+
id
|
|
198
|
+
title
|
|
199
|
+
tags
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
`
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
equal(res.statusCode, 200, 'pages status code')
|
|
206
|
+
same(res.json(), {
|
|
207
|
+
data: {
|
|
208
|
+
getPageById: {
|
|
209
|
+
id: 1,
|
|
210
|
+
title: 'Hello World',
|
|
211
|
+
tags: ['foo', 'bar', 'baz']
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}, 'pages response')
|
|
215
|
+
}
|
|
216
|
+
})
|