@platformatic/sql-graphql 0.31.1 → 0.33.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @platformatic/sql-graphql
2
2
 
3
- Check out the full documentation on [our website](https://oss.platformatic.dev/docs/reference/sql-graphql/queries).
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
 
@@ -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.enum) {
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
- acc[field] = {
167
- value: field
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.31.1",
3
+ "version": "0.33.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.31.1",
26
- "@platformatic/sql-mapper": "0.31.1"
25
+ "@platformatic/sql-events": "0.33.0",
26
+ "@platformatic/sql-mapper": "0.33.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
+ })