@subsquid/openreader 0.2.1 → 0.4.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.
Files changed (131) hide show
  1. package/README.md +2 -15
  2. package/bin/main.js +2 -0
  3. package/dist/db.d.ts +28 -0
  4. package/dist/db.d.ts.map +1 -0
  5. package/dist/db.js +69 -0
  6. package/dist/db.js.map +1 -0
  7. package/dist/gql/opencrud.d.ts +1 -0
  8. package/dist/gql/opencrud.d.ts.map +1 -0
  9. package/dist/gql/opencrud.js +10 -9
  10. package/dist/gql/opencrud.js.map +1 -1
  11. package/dist/gql/schema.d.ts +1 -0
  12. package/dist/gql/schema.d.ts.map +1 -0
  13. package/dist/gql/schema.js +116 -17
  14. package/dist/gql/schema.js.map +1 -1
  15. package/dist/main.d.ts +2 -3
  16. package/dist/main.d.ts.map +1 -0
  17. package/dist/main.js +6 -30
  18. package/dist/main.js.map +1 -1
  19. package/dist/model.d.ts +9 -0
  20. package/dist/model.d.ts.map +1 -0
  21. package/dist/model.tools.d.ts +2 -0
  22. package/dist/model.tools.d.ts.map +1 -0
  23. package/dist/model.tools.js +27 -1
  24. package/dist/model.tools.js.map +1 -1
  25. package/dist/orderBy.d.ts +1 -0
  26. package/dist/orderBy.d.ts.map +1 -0
  27. package/dist/queryBuilder.d.ts +3 -2
  28. package/dist/queryBuilder.d.ts.map +1 -0
  29. package/dist/queryBuilder.js +28 -27
  30. package/dist/queryBuilder.js.map +1 -1
  31. package/dist/relayConnection.d.ts +1 -0
  32. package/dist/relayConnection.d.ts.map +1 -0
  33. package/dist/requestedFields.d.ts +1 -0
  34. package/dist/requestedFields.d.ts.map +1 -0
  35. package/dist/requestedFields.js +3 -3
  36. package/dist/requestedFields.js.map +1 -1
  37. package/dist/resolver.d.ts +3 -2
  38. package/dist/resolver.d.ts.map +1 -0
  39. package/dist/resolver.js +12 -11
  40. package/dist/resolver.js.map +1 -1
  41. package/dist/scalars.d.ts +2 -2
  42. package/dist/scalars.d.ts.map +1 -0
  43. package/dist/scalars.js.map +1 -1
  44. package/dist/server.d.ts +5 -11
  45. package/dist/server.d.ts.map +1 -0
  46. package/dist/server.js +13 -31
  47. package/dist/server.js.map +1 -1
  48. package/dist/test/basic.test.d.ts +2 -0
  49. package/dist/test/basic.test.d.ts.map +1 -0
  50. package/dist/test/basic.test.js +286 -0
  51. package/dist/test/basic.test.js.map +1 -0
  52. package/dist/test/connection.test.d.ts +2 -0
  53. package/dist/test/connection.test.d.ts.map +1 -0
  54. package/dist/test/connection.test.js +193 -0
  55. package/dist/test/connection.test.js.map +1 -0
  56. package/dist/test/fts.test.d.ts +2 -0
  57. package/dist/test/fts.test.d.ts.map +1 -0
  58. package/dist/test/fts.test.js +110 -0
  59. package/dist/test/fts.test.js.map +1 -0
  60. package/dist/test/lists.test.d.ts +2 -0
  61. package/dist/test/lists.test.d.ts.map +1 -0
  62. package/dist/test/lists.test.js +266 -0
  63. package/dist/test/lists.test.js.map +1 -0
  64. package/dist/test/lookup.test.d.ts +2 -0
  65. package/dist/test/lookup.test.d.ts.map +1 -0
  66. package/dist/test/lookup.test.js +109 -0
  67. package/dist/test/lookup.test.js.map +1 -0
  68. package/dist/test/scalars.test.d.ts +2 -0
  69. package/dist/test/scalars.test.d.ts.map +1 -0
  70. package/dist/test/scalars.test.js +303 -0
  71. package/dist/test/scalars.test.js.map +1 -0
  72. package/dist/test/tools.test.d.ts +2 -0
  73. package/dist/test/tools.test.d.ts.map +1 -0
  74. package/dist/test/tools.test.js +49 -0
  75. package/dist/test/tools.test.js.map +1 -0
  76. package/dist/test/typed-json.test.d.ts +2 -0
  77. package/dist/test/typed-json.test.d.ts.map +1 -0
  78. package/dist/test/typed-json.test.js +75 -0
  79. package/dist/test/typed-json.test.js.map +1 -0
  80. package/dist/test/unions.test.d.ts +2 -0
  81. package/dist/test/unions.test.d.ts.map +1 -0
  82. package/dist/test/unions.test.js +84 -0
  83. package/dist/test/unions.test.js.map +1 -0
  84. package/dist/test/util/setup.d.ts +7 -0
  85. package/dist/test/util/setup.d.ts.map +1 -0
  86. package/dist/test/util/setup.js +60 -0
  87. package/dist/test/util/setup.js.map +1 -0
  88. package/dist/test/where.test.d.ts +2 -0
  89. package/dist/test/where.test.d.ts.map +1 -0
  90. package/dist/test/where.test.js +127 -0
  91. package/dist/test/where.test.js.map +1 -0
  92. package/dist/tools.d.ts +1 -0
  93. package/dist/tools.d.ts.map +1 -0
  94. package/dist/util.d.ts +1 -13
  95. package/dist/util.d.ts.map +1 -0
  96. package/dist/util.js +6 -79
  97. package/dist/util.js.map +1 -1
  98. package/dist/where.d.ts +1 -0
  99. package/dist/where.d.ts.map +1 -0
  100. package/package.json +26 -20
  101. package/src/db.ts +83 -0
  102. package/src/gql/opencrud.ts +328 -0
  103. package/src/gql/schema.ts +463 -0
  104. package/src/main.ts +51 -0
  105. package/src/model.tools.ts +201 -0
  106. package/src/model.ts +137 -0
  107. package/src/orderBy.ts +105 -0
  108. package/src/queryBuilder.ts +785 -0
  109. package/src/relayConnection.ts +80 -0
  110. package/src/requestedFields.ts +246 -0
  111. package/src/resolver.ts +199 -0
  112. package/src/scalars.ts +247 -0
  113. package/src/server.ts +115 -0
  114. package/src/test/basic.test.ts +339 -0
  115. package/src/test/connection.test.ts +195 -0
  116. package/src/test/fts.test.ts +114 -0
  117. package/src/test/lists.test.ts +278 -0
  118. package/src/test/lookup.test.ts +111 -0
  119. package/src/test/scalars.test.ts +316 -0
  120. package/src/test/tools.test.ts +27 -0
  121. package/src/test/typed-json.test.ts +76 -0
  122. package/src/test/unions.test.ts +85 -0
  123. package/src/test/util/setup.ts +63 -0
  124. package/src/test/where.test.ts +135 -0
  125. package/src/tools.ts +33 -0
  126. package/src/util.ts +39 -0
  127. package/src/where.ts +110 -0
  128. package/CHANGELOG.md +0 -20
  129. package/dist/transaction.d.ts +0 -10
  130. package/dist/transaction.js +0 -47
  131. package/dist/transaction.js.map +0 -1
@@ -0,0 +1,316 @@
1
+ import {useDatabase, useServer} from "./util/setup"
2
+
3
+ describe('scalars', function() {
4
+ useDatabase([
5
+ `create table scalar (id text primary key, "boolean" bool, "bigint" numeric, "string" text, enum text, date_time timestamptz, "bytes" bytea, deep jsonb)`,
6
+ `insert into scalar (id, "boolean") values ('1', true)`,
7
+ `insert into scalar (id, "boolean", deep) values ('2', false, '{"boolean": true}'::jsonb)`,
8
+ `insert into scalar (id, "bigint", deep) values ('3', 1000000000000000000000000000000000000, '{"bigint": "1000000000000000000000000000000000000"}'::jsonb)`,
9
+ `insert into scalar (id, "bigint", deep) values ('4', 2000000000000000000000000000000000000, '{"bigint": "2000000000000000000000000000000000000"}'::jsonb)`,
10
+ `insert into scalar (id, "bigint", deep) values ('5', 5, '{"bigint": "5"}'::jsonb)`,
11
+ `insert into scalar (id, "string") values ('6', 'foo bar baz')`,
12
+ `insert into scalar (id, "string") values ('7', 'bar baz foo')`,
13
+ `insert into scalar (id, "string") values ('8', 'baz foo bar')`,
14
+ `insert into scalar (id, "string") values ('9', 'hello')`,
15
+ `insert into scalar (id, "date_time", deep) values ('10', '2021-09-24T15:43:13.400Z', '{"dateTime": "2021-09-24T00:00:00.120Z"}'::jsonb)`,
16
+ `insert into scalar (id, "date_time", deep) values ('11', '2021-09-24T00:00:00.000Z', '{"dateTime": "2021-09-24T00:00:00Z"}'::jsonb)`,
17
+ `insert into scalar (id, "date_time", deep) values ('12', '2021-09-24 02:00:00.001 +01:00', '{"dateTime": "2021-09-24T00:00:00.1Z"}'::jsonb)`,
18
+ `insert into scalar (id, "bytes", deep) values ('13', decode('aa', 'hex'), '{"bytes": "0xaa"}'::jsonb)`,
19
+ `insert into scalar (id, "bytes", deep) values ('14', decode('bb', 'hex'), '{"bytes": "0xCCDD"}'::jsonb)`,
20
+ `insert into scalar (id, "enum") values ('15', 'A')`,
21
+ `insert into scalar (id, "enum") values ('16', 'B')`,
22
+ `insert into scalar (id, "enum") values ('17', 'C')`,
23
+ ])
24
+
25
+ const client = useServer(`
26
+ type Scalar @entity {
27
+ id: ID!
28
+ boolean: Boolean
29
+ string: String
30
+ enum: Enum
31
+ bigint: BigInt
32
+ dateTime: DateTime
33
+ bytes: Bytes
34
+ deep: DeepScalar
35
+ }
36
+
37
+ type DeepScalar {
38
+ bigint: BigInt
39
+ dateTime: DateTime
40
+ bytes: Bytes
41
+ boolean: Boolean
42
+ }
43
+
44
+ enum Enum {
45
+ A B C
46
+ }
47
+ `)
48
+
49
+ describe('Boolean', function () {
50
+ it('outputs correctly', function () {
51
+ return client.test(`
52
+ query {
53
+ scalars(where: {id_in: ["1", "2"]} orderBy: id_ASC) {
54
+ id
55
+ boolean
56
+ }
57
+ }
58
+ `, {
59
+ scalars: [
60
+ {id: '1', boolean: true},
61
+ {id: '2', boolean: false}
62
+ ]
63
+ })
64
+ })
65
+
66
+ it('output from nested object', function () {
67
+ return client.test(`
68
+ query {
69
+ scalars(where: {id_eq: "2"}) {
70
+ deep {
71
+ boolean
72
+ }
73
+ }
74
+ }
75
+ `, {
76
+ scalars: [
77
+ {deep: {boolean: true}}
78
+ ]
79
+ })
80
+ })
81
+
82
+ it('supports where conditions', function () {
83
+ return client.test(`
84
+ query {
85
+ t: scalars(where: {boolean_eq: true}) { id }
86
+ f: scalars(where: {boolean_eq: false}) { id }
87
+ nt: scalars(where: {boolean_not_eq: true}) { id }
88
+ nf: scalars(where: {boolean_not_eq: false}) { id }
89
+ }
90
+ `, {
91
+ t: [{id: '1'}],
92
+ f: [{id: '2'}],
93
+ nt: [{id: '2'}],
94
+ nf: [{id: '1'}]
95
+ })
96
+ })
97
+ })
98
+
99
+ describe('String', function () {
100
+ it('supports where conditions', function () {
101
+ return client.test(`
102
+ query {
103
+ starts_with: scalars(where: {string_startsWith: "foo"} orderBy: id_ASC) { id }
104
+ not_starts_with: scalars(where: {string_not_startsWith: "foo"} orderBy: id_ASC) { id }
105
+ ends_with: scalars(where: {string_endsWith: "foo"} orderBy: id_ASC) { id }
106
+ not_ends_with: scalars(where: {string_not_endsWith: "foo"} orderBy: id_ASC) { id }
107
+ contains: scalars(where: {string_contains: "foo"} orderBy: id_ASC) { id }
108
+ not_contains: scalars(where: {string_not_contains: "foo"} orderBy: id_ASC) { id }
109
+ case_sensitive: scalars(where: {string_contains: "Foo"} orderBy: id_ASC) { id }
110
+ }
111
+ `, {
112
+ starts_with: [{id: '6'}],
113
+ not_starts_with: [{id: '7'}, {id: '8'}, {id: '9'}],
114
+ ends_with: [{id: '7'}],
115
+ not_ends_with: [{id: '6'}, {id: '8'}, {id: '9'}],
116
+ contains: [{id: '6'}, {id: '7'}, {id: '8'}],
117
+ not_contains: [{id: '9'}],
118
+ case_sensitive: []
119
+ })
120
+ })
121
+ })
122
+
123
+ describe('Enum', function () {
124
+ it('outputs correctly', function () {
125
+ return client.test(`
126
+ query {
127
+ scalars(where: {id_in: ["15", "16", "17"]} orderBy: id_ASC) {
128
+ id
129
+ enum
130
+ }
131
+ }
132
+ `, {
133
+ scalars: [
134
+ {id: '15', enum: 'A'},
135
+ {id: '16', enum: 'B'},
136
+ {id: '17', enum: 'C'},
137
+ ]
138
+ })
139
+ })
140
+
141
+ it('supports where conditions', function () {
142
+ return client.test(`
143
+ query {
144
+ eq: scalars(where: {enum_eq: A} orderBy: id_ASC) { id }
145
+ not_eq: scalars(where: {enum_not_eq: A} orderBy: id_ASC) { id }
146
+ in: scalars(where: {enum_in: [A, B]} orderBy: id_ASC) { id }
147
+ not_in: scalars(where: {enum_not_in: B} orderBy: id_ASC) { id }
148
+ }
149
+ `, {
150
+ eq: [{id: '15'}],
151
+ not_eq: [{id: '16'}, {id: '17'}],
152
+ in: [{id: '15'}, {id: '16'}],
153
+ not_in: [{id: '15'}, {id: '17'}],
154
+ })
155
+ })
156
+ })
157
+
158
+ describe('BigInt', function () {
159
+ it('outputs correctly', function () {
160
+ return client.test(`
161
+ query {
162
+ scalars(where: {id_in: ["3", "4", "5"]} orderBy: id_ASC) {
163
+ id
164
+ bigint
165
+ deep { bigint }
166
+ }
167
+ }
168
+ `, {
169
+ scalars: [
170
+ {
171
+ id: '3',
172
+ bigint: '1000000000000000000000000000000000000',
173
+ deep: {bigint: '1000000000000000000000000000000000000'}
174
+ },
175
+ {
176
+ id: '4',
177
+ bigint: '2000000000000000000000000000000000000',
178
+ deep: {bigint: '2000000000000000000000000000000000000'}
179
+ },
180
+ {
181
+ id: '5',
182
+ bigint: '5',
183
+ deep: {bigint: '5'}
184
+ }
185
+ ]
186
+ })
187
+ })
188
+
189
+ it('supports where conditions', function () {
190
+ return client.test(`
191
+ query {
192
+ eq: scalars(where: {bigint_eq: 2000000000000000000000000000000000000} orderBy: id_ASC) { id }
193
+ not_eq: scalars(where: {bigint_not_eq: 2000000000000000000000000000000000000} orderBy: id_ASC) { id }
194
+ gt: scalars(where: {bigint_gt: 1000000000000000000000000000000000000} orderBy: id_ASC) { id }
195
+ gte: scalars(where: {bigint_gte: 1000000000000000000000000000000000000} orderBy: id_ASC) { id }
196
+ lt: scalars(where: {bigint_lt: 1000000000000000000000000000000000000} orderBy: id_ASC) { id }
197
+ lte: scalars(where: {bigint_lte: 1000000000000000000000000000000000000} orderBy: id_ASC) { id }
198
+ in: scalars(where: {bigint_in: [1000000000000000000000000000000000000, 5]} orderBy: id_ASC) { id }
199
+ not_in: scalars(where: {bigint_not_in: [1000000000000000000000000000000000000, 5]} orderBy: id_ASC) { id }
200
+ }
201
+ `, {
202
+ eq: [{id: '4'}],
203
+ not_eq: [{id: '3'}, {id: '5'}],
204
+ gt: [{id: '4'}],
205
+ gte: [{id: '3'}, {id: '4'}],
206
+ lt: [{id: '5'}],
207
+ lte: [{id: '3'}, {id: '5'}],
208
+ in: [{id: '3'}, {id: '5'}],
209
+ not_in: [{id: '4'}]
210
+ })
211
+ })
212
+
213
+ it('json sort', function () {
214
+ return client.test(`
215
+ query {
216
+ scalars(orderBy: deep_bigint_ASC where: {id_in: ["3", "4", "5"]}) {
217
+ id
218
+ }
219
+ }
220
+ `, {
221
+ scalars: [
222
+ {id: '5'},
223
+ {id: '3'},
224
+ {id: '4'}
225
+ ]
226
+ })
227
+ })
228
+ })
229
+
230
+ describe('DateTime', function () {
231
+ it('outputs correctly', function () {
232
+ return client.test(`
233
+ query {
234
+ scalars(where: {id_in: ["10", "11", "12"]} orderBy: id_ASC) {
235
+ id
236
+ dateTime
237
+ deep { dateTime }
238
+ }
239
+ }
240
+ `, {
241
+ scalars: [
242
+ {id: '10', dateTime: '2021-09-24T15:43:13.400Z', deep: {dateTime: '2021-09-24T00:00:00.120Z'}},
243
+ {id: '11', dateTime: '2021-09-24T00:00:00.000Z', deep: {dateTime: '2021-09-24T00:00:00Z'}},
244
+ {id: '12', dateTime: '2021-09-24T01:00:00.001Z', deep: {dateTime: '2021-09-24T00:00:00.1Z'}}
245
+ ]
246
+ })
247
+ })
248
+
249
+ it('supports where conditions', function () {
250
+ return client.test(`
251
+ query {
252
+ gt: scalars(orderBy: id_ASC, where: {dateTime_gt: "2021-09-24T00:00:00Z"}) { id }
253
+ gte: scalars(orderBy: id_ASC, where: {dateTime_gte: "2021-09-24T00:00:00Z"}) { id }
254
+ lt: scalars(orderBy: id_ASC, where: {dateTime_lt: "2021-09-24T00:00:00Z"}) { id }
255
+ lte: scalars(orderBy: id_ASC, where: {dateTime_lte: "2021-09-24T00:00:00Z"}) { id }
256
+ in: scalars(orderBy: id_ASC, where: {dateTime_in: ["2021-09-24T00:00:00Z", "2021-09-24T15:43:13.400Z"]}) { id }
257
+ not_in: scalars(orderBy: id_ASC, where: {dateTime_not_in: ["2021-09-24T00:00:00Z", "2021-09-24T15:43:13.400Z"]}) { id }
258
+ }
259
+ `, {
260
+ gt: [{id: '10'}, {id: '12'}],
261
+ gte: [{id: '10'}, {id: '11'}, {id: '12'}],
262
+ lt: [],
263
+ lte: [{id: '11'}],
264
+ in: [{id: '10'}, {'id': '11'}],
265
+ not_in: [{'id': '12'}]
266
+ })
267
+ })
268
+
269
+ it('json sort', function () {
270
+ return client.test(`
271
+ query {
272
+ scalars(orderBy: deep_dateTime_ASC where: {id_in: ["10", "11", "12"]}) {
273
+ id
274
+ }
275
+ }
276
+ `, {
277
+ scalars: [
278
+ {id: '11'},
279
+ {id: '12'},
280
+ {id: '10'}
281
+ ]
282
+ })
283
+ })
284
+ })
285
+
286
+ describe('Bytes', function () {
287
+ it('outputs correctly', function () {
288
+ return client.test(`
289
+ query {
290
+ scalars(where: {id_in: ["13", "14"]} orderBy: id_ASC) {
291
+ id
292
+ bytes
293
+ deep { bytes }
294
+ }
295
+ }
296
+ `, {
297
+ scalars: [
298
+ {id: '13', bytes: '0xaa', deep: {bytes: '0xaa'}},
299
+ {id: '14', bytes: '0xbb', deep: {bytes: '0xccdd'}},
300
+ ]
301
+ })
302
+ })
303
+
304
+ it('supports where conditions', function () {
305
+ return client.test(`
306
+ query {
307
+ eq: scalars(where: {bytes_eq: "0xaa"} orderBy: id_ASC) { id }
308
+ deep_eq: scalars(where: {deep: {bytes_eq: "0xccdd"}} orderBy: id_ASC) { id }
309
+ }
310
+ `, {
311
+ eq: [{id: '13'}],
312
+ deep_eq: [{id: '14'}]
313
+ })
314
+ })
315
+ })
316
+ })
@@ -0,0 +1,27 @@
1
+ import * as path from "path"
2
+ import expect from "expect"
3
+ import {loadModel} from "../tools"
4
+
5
+ function fixture(name: string): string {
6
+ return path.join(__dirname, '../../fixtures', name)
7
+ }
8
+
9
+ describe('tools', function () {
10
+ describe('loadModel()', function () {
11
+ it('loads model from a single file', function () {
12
+ let model = loadModel(fixture('schema.graphql'))
13
+ expect(model).toMatchObject({
14
+ Account: {kind: 'entity'},
15
+ HistoricalBalance: {kind: 'entity'}
16
+ })
17
+ })
18
+
19
+ it('loads model from a directory', function () {
20
+ let model = loadModel(fixture('schema'))
21
+ expect(model).toMatchObject({
22
+ Account: {kind: 'entity'},
23
+ HistoricalBalance: {kind: 'entity'}
24
+ })
25
+ })
26
+ })
27
+ })
@@ -0,0 +1,76 @@
1
+ import {useDatabase, useServer} from "./util/setup"
2
+
3
+ describe('typed json fields', function () {
4
+ useDatabase([
5
+ `create table entity (id text primary key, a jsonb)`,
6
+ `insert into entity (id, a) values ('1', '{"a": "a", "b": {"b": "b", "e": "1"}}'::jsonb)`,
7
+ `insert into entity (id, a) values ('2', '{"a": "A", "b": {"b": "B", "e": "1"}}'::jsonb)`,
8
+ `insert into entity (id, a) values ('3', '{}'::jsonb)`,
9
+ `insert into entity (id) values ('4')`,
10
+ ])
11
+
12
+ const client = useServer(`
13
+ type Entity @entity {
14
+ a: A
15
+ }
16
+
17
+ type A {
18
+ a: String
19
+ b: B
20
+ }
21
+
22
+ type B {
23
+ a: A
24
+ b: String
25
+ e: Entity
26
+ }
27
+ `)
28
+
29
+ it('maps nulls correctly', function () {
30
+ return client.test(`
31
+ query {
32
+ entities(orderBy: id_ASC) {
33
+ id
34
+ a { a }
35
+ }
36
+ }
37
+ `, {
38
+ entities: [
39
+ {id: '1', a: {a: 'a'}},
40
+ {id: '2', a: {a: 'A'}},
41
+ {id: '3', a: {a: null}},
42
+ {id: '4', a: null}
43
+ ]
44
+ })
45
+ })
46
+
47
+ it('can fetch deep entities', function () {
48
+ return client.test(`
49
+ query {
50
+ entities(orderBy: id_ASC) {
51
+ id
52
+ a {
53
+ b {
54
+ e {
55
+ id
56
+ a {
57
+ b {
58
+ b
59
+ e { id }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
67
+ `, {
68
+ entities: [
69
+ {id: '1', a: {b: {e: {id: '1', a: {b: {b: 'b', e: {id: '1'}}}}}}},
70
+ {id: '2', a: {b: {e: {id: '1', a: {b: {b: 'b', e: {id: '1'}}}}}}},
71
+ {id: '3', a: {b: null}},
72
+ {id: '4', a: null}
73
+ ]
74
+ })
75
+ })
76
+ })
@@ -0,0 +1,85 @@
1
+ import {useDatabase, useServer} from "./util/setup"
2
+
3
+ describe('unions', function () {
4
+ useDatabase([
5
+ `create table "user" (id text primary key, login text)`,
6
+ `create table equipment (id text primary key, name text, owner jsonb)`,
7
+ `insert into "user" (id, login) values ('1', 'farmer')`,
8
+ `insert into "user" (id, login) values ('2', 'programmer')`,
9
+ `insert into equipment (id, name, owner) values ('1', 'combine', '{"isTypeOf": "Farmer", "user": "1", "crop": 100}'::jsonb)`,
10
+ `insert into equipment (id, name, owner) values ('2', 'computer', '{"isTypeOf": "Programmer", "user": "2", "stack": "Python"}'::jsonb)`
11
+ ])
12
+
13
+ const client = useServer(`
14
+ type User @entity {
15
+ id: ID!
16
+ login: String!
17
+ }
18
+
19
+ type Farmer {
20
+ user: User!
21
+ crop: Int
22
+ }
23
+
24
+ type Programmer {
25
+ user: User!
26
+ stack: String
27
+ }
28
+
29
+ union Owner = Farmer | Programmer
30
+
31
+ type Equipment @entity {
32
+ name: String!
33
+ owner: Owner!
34
+ }
35
+ `)
36
+
37
+ it('output', function () {
38
+ return client.test(`
39
+ query {
40
+ equipment(orderBy: id_ASC) {
41
+ name
42
+ owner {
43
+ ... on Farmer {
44
+ user { login }
45
+ crop
46
+ }
47
+ ... on Programmer {
48
+ user { login }
49
+ stack
50
+ }
51
+ }
52
+ }
53
+ }
54
+ `, {
55
+ equipment: [
56
+ {
57
+ name: 'combine',
58
+ owner: {
59
+ user: {login: 'farmer'},
60
+ crop: 100
61
+ }
62
+ },
63
+ {
64
+ name: 'computer',
65
+ owner: {
66
+ user: {login: 'programmer'},
67
+ stack: 'Python'
68
+ }
69
+ }
70
+ ]
71
+ })
72
+ })
73
+
74
+ it('filtering', function () {
75
+ return client.test(`
76
+ query {
77
+ type_farmer: equipment(where: {owner: {isTypeOf_eq: "Farmer"}}) { id }
78
+ stack_Python: equipment(where: {owner: {stack_eq: "Python"}}) { id }
79
+ }
80
+ `, {
81
+ type_farmer: [{id: '1'}],
82
+ stack_Python: [{id: '2'}]
83
+ })
84
+ })
85
+ })
@@ -0,0 +1,63 @@
1
+ import {Client} from "gql-test-client"
2
+ import {parse} from "graphql"
3
+ import {Client as PgClient, ClientBase, Pool} from "pg"
4
+ import {createPoolConfig} from "../../db"
5
+ import {buildModel, buildSchema} from "../../gql/schema"
6
+ import {ListeningServer, serve} from "../../server"
7
+
8
+
9
+ export const db_config = createPoolConfig()
10
+
11
+
12
+ async function withClient(block: (client: ClientBase) => Promise<void>): Promise<void> {
13
+ let client = new PgClient(db_config)
14
+ await client.connect()
15
+ try {
16
+ await block(client)
17
+ } finally {
18
+ await client.end()
19
+ }
20
+ }
21
+
22
+
23
+ export function databaseInit(sql: string[]): Promise<void> {
24
+ return withClient(async client => {
25
+ for (let i = 0; i < sql.length; i++) {
26
+ await client.query(sql[i])
27
+ }
28
+ })
29
+ }
30
+
31
+
32
+ export function databaseDelete(): Promise<void> {
33
+ return withClient(async client => {
34
+ await client.query(`DROP SCHEMA IF EXISTS public CASCADE`)
35
+ await client.query(`CREATE SCHEMA public`)
36
+ })
37
+ }
38
+
39
+
40
+ export function useDatabase(sql: string[]): void {
41
+ before(async () => {
42
+ await databaseDelete()
43
+ await databaseInit(sql)
44
+ })
45
+ }
46
+
47
+
48
+ export function useServer(schema: string): Client {
49
+ let client = new Client('not defined')
50
+ let db = new Pool(db_config)
51
+ let info: ListeningServer | undefined
52
+ before(async () => {
53
+ info = await serve({
54
+ db,
55
+ model: buildModel(buildSchema(parse(schema))),
56
+ port: 0
57
+ })
58
+ client.endpoint = `http://localhost:${info.port}/graphql`
59
+ })
60
+ after(() => info?.stop())
61
+ after(() => db.end())
62
+ return client
63
+ }