@subsquid/openreader 2.1.0 → 3.0.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/lib/ir/args.d.ts +1 -1
- package/lib/ir/args.d.ts.map +1 -1
- package/lib/ir/connection.d.ts +3 -4
- package/lib/ir/connection.d.ts.map +1 -1
- package/lib/ir/connection.js.map +1 -1
- package/lib/ir/fields.d.ts +6 -2
- package/lib/ir/fields.d.ts.map +1 -1
- package/lib/ir/fields.js +15 -0
- package/lib/ir/fields.js.map +1 -1
- package/lib/limit.size.d.ts +4 -4
- package/lib/limit.size.d.ts.map +1 -1
- package/lib/limit.size.js +51 -20
- package/lib/limit.size.js.map +1 -1
- package/lib/main.js +0 -9
- package/lib/main.js.map +1 -1
- package/lib/model.d.ts +2 -1
- package/lib/model.d.ts.map +1 -1
- package/lib/model.schema.d.ts +2 -2
- package/lib/model.schema.d.ts.map +1 -1
- package/lib/model.schema.js +8 -3
- package/lib/model.schema.js.map +1 -1
- package/lib/model.tools.d.ts +6 -1
- package/lib/model.tools.d.ts.map +1 -1
- package/lib/model.tools.js +111 -8
- package/lib/model.tools.js.map +1 -1
- package/lib/opencrud/orderBy.d.ts +2 -2
- package/lib/opencrud/orderBy.d.ts.map +1 -1
- package/lib/opencrud/orderBy.js +13 -17
- package/lib/opencrud/orderBy.js.map +1 -1
- package/lib/opencrud/schema.d.ts +4 -4
- package/lib/opencrud/schema.d.ts.map +1 -1
- package/lib/opencrud/schema.js +53 -62
- package/lib/opencrud/schema.js.map +1 -1
- package/lib/opencrud/tree.d.ts +9 -7
- package/lib/opencrud/tree.d.ts.map +1 -1
- package/lib/opencrud/tree.js +32 -14
- package/lib/opencrud/tree.js.map +1 -1
- package/lib/sql/cursor.js +2 -2
- package/lib/sql/cursor.js.map +1 -1
- package/lib/sql/mapping.d.ts +3 -1
- package/lib/sql/mapping.d.ts.map +1 -1
- package/lib/sql/mapping.js +16 -1
- package/lib/sql/mapping.js.map +1 -1
- package/lib/sql/printer.d.ts +29 -11
- package/lib/sql/printer.d.ts.map +1 -1
- package/lib/sql/printer.js +106 -10
- package/lib/sql/printer.js.map +1 -1
- package/lib/sql/query.d.ts +11 -11
- package/lib/sql/query.d.ts.map +1 -1
- package/lib/sql/query.js +41 -19
- package/lib/sql/query.js.map +1 -1
- package/lib/test/queryable.test.d.ts +2 -0
- package/lib/test/queryable.test.d.ts.map +1 -0
- package/lib/test/queryable.test.js +255 -0
- package/lib/test/queryable.test.js.map +1 -0
- package/package.json +2 -2
- package/src/ir/args.ts +1 -1
- package/src/ir/connection.ts +3 -4
- package/src/ir/fields.ts +22 -2
- package/src/limit.size.ts +55 -30
- package/src/main.ts +0 -11
- package/src/model.schema.ts +16 -9
- package/src/model.tools.ts +121 -8
- package/src/model.ts +2 -1
- package/src/opencrud/orderBy.ts +13 -17
- package/src/opencrud/schema.ts +78 -84
- package/src/opencrud/tree.ts +55 -26
- package/src/sql/cursor.ts +2 -2
- package/src/sql/mapping.ts +18 -1
- package/src/sql/printer.ts +137 -21
- package/src/sql/query.ts +50 -30
- package/src/test/queryable.test.ts +258 -0
package/src/opencrud/schema.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {def, unexpectedCase} from
|
|
2
|
-
import {toCamelCase, toPlural} from
|
|
3
|
-
import {UserInputError} from
|
|
4
|
-
import assert from
|
|
1
|
+
import {def, unexpectedCase} from '@subsquid/util-internal'
|
|
2
|
+
import {toCamelCase, toPlural} from '@subsquid/util-naming'
|
|
3
|
+
import {UserInputError} from 'apollo-server-core'
|
|
4
|
+
import assert from 'assert'
|
|
5
5
|
import {
|
|
6
6
|
GraphQLBoolean,
|
|
7
7
|
GraphQLEnumType,
|
|
@@ -20,27 +20,28 @@ import {
|
|
|
20
20
|
GraphQLSchema,
|
|
21
21
|
GraphQLString,
|
|
22
22
|
GraphQLUnionType
|
|
23
|
-
} from
|
|
23
|
+
} from 'graphql'
|
|
24
24
|
import {
|
|
25
25
|
GraphQLEnumValueConfigMap,
|
|
26
26
|
GraphQLFieldConfigArgumentMap,
|
|
27
27
|
GraphQLFieldConfigMap,
|
|
28
28
|
GraphQLInputFieldConfigMap
|
|
29
|
-
} from
|
|
30
|
-
import {Context} from
|
|
31
|
-
import {decodeRelayConnectionCursor, RelayConnectionRequest} from
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
29
|
+
} from 'graphql/type/definition'
|
|
30
|
+
import {Context} from '../context'
|
|
31
|
+
import {decodeRelayConnectionCursor, RelayConnectionRequest} from '../ir/connection'
|
|
32
|
+
import {AnyFields} from '../ir/fields'
|
|
33
|
+
import {getConnectionSize, getListSize, getObjectSize} from '../limit.size'
|
|
34
|
+
import {Entity, Interface, JsonObject, Model, Prop} from '../model'
|
|
35
|
+
import {getObject, getUniversalProperties} from '../model.tools'
|
|
36
|
+
import {customScalars} from '../scalars'
|
|
37
|
+
import {ConnectionQuery, CountQuery, EntityByIdQuery, ListQuery, Query} from '../sql/query'
|
|
38
|
+
import {Subscription} from '../subscription'
|
|
38
39
|
import {Limit} from '../util/limit'
|
|
39
|
-
import {getResolveTree, getTreeRequest, hasTreeRequest, simplifyResolveTree} from
|
|
40
|
-
import {ensureArray, identity} from
|
|
41
|
-
import {getOrderByMapping, parseOrderBy} from
|
|
42
|
-
import {
|
|
43
|
-
import {parseWhere} from
|
|
40
|
+
import {getResolveTree, getTreeRequest, hasTreeRequest, simplifyResolveTree} from '../util/resolve-tree'
|
|
41
|
+
import {ensureArray, identity} from '../util/util'
|
|
42
|
+
import {getOrderByMapping, parseOrderBy} from './orderBy'
|
|
43
|
+
import {parseAnyTree, parseObjectTree, parseSqlArguments} from './tree'
|
|
44
|
+
import {parseWhere} from './where'
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
type GqlFieldMap = GraphQLFieldConfigMap<unknown, Context>
|
|
@@ -111,7 +112,8 @@ export class SchemaBuilder {
|
|
|
111
112
|
return new GraphQLInterfaceType({
|
|
112
113
|
name,
|
|
113
114
|
description: item.description,
|
|
114
|
-
fields: () => this.buildObjectFields(item)
|
|
115
|
+
fields: () => this.buildObjectFields(item),
|
|
116
|
+
resolveType: item.queryable ? (value: any) => value._isTypeOf : undefined
|
|
115
117
|
})
|
|
116
118
|
case "enum":
|
|
117
119
|
return new GraphQLEnumType({
|
|
@@ -145,7 +147,7 @@ export class SchemaBuilder {
|
|
|
145
147
|
type: this.getPropType(prop)
|
|
146
148
|
}
|
|
147
149
|
if (prop.type.kind == 'list-lookup') {
|
|
148
|
-
field.args = this.
|
|
150
|
+
field.args = this.listArguments(prop.type.entity)
|
|
149
151
|
}
|
|
150
152
|
if (object.kind == 'entity' || object.kind == 'object') {
|
|
151
153
|
switch(prop.type.kind) {
|
|
@@ -170,7 +172,7 @@ export class SchemaBuilder {
|
|
|
170
172
|
type = new GraphQLList(this.getPropType(prop.type.item))
|
|
171
173
|
break
|
|
172
174
|
case "fk":
|
|
173
|
-
type = this.get(prop.type.
|
|
175
|
+
type = this.get(prop.type.entity)
|
|
174
176
|
break
|
|
175
177
|
case "lookup":
|
|
176
178
|
return this.get(prop.type.entity)
|
|
@@ -191,46 +193,33 @@ export class SchemaBuilder {
|
|
|
191
193
|
return type
|
|
192
194
|
}
|
|
193
195
|
|
|
194
|
-
private
|
|
196
|
+
private listArguments(typeName: string): GraphQLFieldConfigArgumentMap {
|
|
195
197
|
return {
|
|
196
|
-
where: {type: this.getWhere(
|
|
197
|
-
orderBy: {type: this.getOrderBy(
|
|
198
|
+
where: {type: this.getWhere(typeName)},
|
|
199
|
+
orderBy: {type: this.getOrderBy(typeName)},
|
|
198
200
|
offset: {type: GraphQLInt},
|
|
199
201
|
limit: {type: GraphQLInt}
|
|
200
202
|
}
|
|
201
203
|
}
|
|
202
204
|
|
|
203
|
-
private getWhere(
|
|
204
|
-
let where = this.where.get(
|
|
205
|
+
private getWhere(typeName: string): GraphQLInputType {
|
|
206
|
+
let where = this.where.get(typeName)
|
|
205
207
|
if (where) return where
|
|
206
208
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
case "entity":
|
|
210
|
-
case "object":
|
|
211
|
-
case "union":
|
|
212
|
-
break
|
|
213
|
-
default:
|
|
214
|
-
throw unexpectedCase(object.kind)
|
|
215
|
-
}
|
|
209
|
+
let object = this.model[typeName]
|
|
210
|
+
let properties = getUniversalProperties(this.model, typeName)
|
|
216
211
|
|
|
217
212
|
where = new GraphQLInputObjectType({
|
|
218
|
-
name: `${
|
|
213
|
+
name: `${typeName}WhereInput`,
|
|
219
214
|
fields: () => {
|
|
220
215
|
let fields: GraphQLInputFieldConfigMap = {}
|
|
221
|
-
let properties
|
|
222
|
-
if (object.kind == 'union') {
|
|
223
|
-
properties = getUnionProps(this.model, name).properties
|
|
224
|
-
} else {
|
|
225
|
-
properties = object.properties
|
|
226
|
-
}
|
|
227
216
|
|
|
228
217
|
for (let key in properties) {
|
|
229
218
|
this.buildPropWhereFilters(key, properties[key], fields)
|
|
230
219
|
}
|
|
231
220
|
|
|
232
|
-
if (object.kind == 'entity') {
|
|
233
|
-
let whereList = new GraphQLList(new GraphQLNonNull(this.getWhere(
|
|
221
|
+
if (object.kind == 'entity' || object.kind == 'interface') {
|
|
222
|
+
let whereList = new GraphQLList(new GraphQLNonNull(this.getWhere(typeName)))
|
|
234
223
|
fields['AND'] = {
|
|
235
224
|
type: whereList
|
|
236
225
|
}
|
|
@@ -242,7 +231,8 @@ export class SchemaBuilder {
|
|
|
242
231
|
return fields
|
|
243
232
|
}
|
|
244
233
|
})
|
|
245
|
-
|
|
234
|
+
|
|
235
|
+
this.where.set(typeName, where)
|
|
246
236
|
return where
|
|
247
237
|
}
|
|
248
238
|
|
|
@@ -320,10 +310,8 @@ export class SchemaBuilder {
|
|
|
320
310
|
fields[key] = {type: this.getWhere(prop.type.name)}
|
|
321
311
|
break
|
|
322
312
|
case "fk":
|
|
323
|
-
fields[`${key}_isNull`] = {type: GraphQLBoolean}
|
|
324
|
-
fields[key] = {type: this.getWhere(prop.type.foreignEntity)}
|
|
325
|
-
break
|
|
326
313
|
case "lookup":
|
|
314
|
+
fields[`${key}_isNull`] = {type: GraphQLBoolean}
|
|
327
315
|
fields[key] = {type: this.getWhere(prop.type.entity)}
|
|
328
316
|
break
|
|
329
317
|
case "list-lookup": {
|
|
@@ -355,24 +343,24 @@ export class SchemaBuilder {
|
|
|
355
343
|
return false
|
|
356
344
|
}
|
|
357
345
|
|
|
358
|
-
private getOrderBy(
|
|
359
|
-
let orderBy = this.orderBy.get(
|
|
346
|
+
private getOrderBy(typeName: string): GraphQLInputType {
|
|
347
|
+
let orderBy = this.orderBy.get(typeName)
|
|
360
348
|
if (orderBy) return orderBy
|
|
361
349
|
|
|
362
350
|
let values: GraphQLEnumValueConfigMap = {}
|
|
363
|
-
for (let variant of getOrderByMapping(this.model,
|
|
351
|
+
for (let variant of getOrderByMapping(this.model, typeName).keys()) {
|
|
364
352
|
values[variant] = {}
|
|
365
353
|
}
|
|
366
354
|
|
|
367
355
|
orderBy = new GraphQLList(
|
|
368
356
|
new GraphQLNonNull(
|
|
369
357
|
new GraphQLEnumType({
|
|
370
|
-
name: `${
|
|
358
|
+
name: `${typeName}OrderByInput`,
|
|
371
359
|
values
|
|
372
360
|
})
|
|
373
361
|
)
|
|
374
362
|
)
|
|
375
|
-
this.orderBy.set(
|
|
363
|
+
this.orderBy.set(typeName, orderBy)
|
|
376
364
|
return orderBy
|
|
377
365
|
}
|
|
378
366
|
|
|
@@ -385,11 +373,17 @@ export class SchemaBuilder {
|
|
|
385
373
|
let item = this.model[name]
|
|
386
374
|
switch(item.kind) {
|
|
387
375
|
case "entity":
|
|
388
|
-
this.
|
|
376
|
+
this.installListQuery(name, query, subscription)
|
|
389
377
|
this.installEntityById(name, query, subscription)
|
|
390
378
|
this.installEntityByUniqueInput(name, query)
|
|
391
379
|
this.installRelayConnection(name, query)
|
|
392
380
|
break
|
|
381
|
+
case 'interface':
|
|
382
|
+
if (item.queryable) {
|
|
383
|
+
this.installListQuery(name, query, subscription)
|
|
384
|
+
this.installRelayConnection(name, query)
|
|
385
|
+
}
|
|
386
|
+
break
|
|
393
387
|
}
|
|
394
388
|
}
|
|
395
389
|
|
|
@@ -405,21 +399,21 @@ export class SchemaBuilder {
|
|
|
405
399
|
})
|
|
406
400
|
}
|
|
407
401
|
|
|
408
|
-
private
|
|
402
|
+
private installListQuery(typeName: string, query: GqlFieldMap, subscription: GqlFieldMap): void {
|
|
409
403
|
let model = this.model
|
|
410
|
-
let queryName = toPlural(toCamelCase(
|
|
411
|
-
let outputType = new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(this.get(
|
|
412
|
-
let argsType = this.
|
|
404
|
+
let queryName = toPlural(toCamelCase(typeName))
|
|
405
|
+
let outputType = new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(this.get(typeName))))
|
|
406
|
+
let argsType = this.listArguments(typeName)
|
|
413
407
|
|
|
414
408
|
function createQuery(context: Context, info: GraphQLResolveInfo, limit?: Limit) {
|
|
415
409
|
let tree = getResolveTree(info)
|
|
416
|
-
let
|
|
417
|
-
let
|
|
418
|
-
limit?.check(() =>
|
|
419
|
-
return new
|
|
410
|
+
let args = parseSqlArguments(model, typeName, tree.args)
|
|
411
|
+
let fields = parseAnyTree(model, typeName, info.schema, tree)
|
|
412
|
+
limit?.check(() => getListSize(model, typeName, fields, args.limit, args.where) + 1)
|
|
413
|
+
return new ListQuery(
|
|
420
414
|
model,
|
|
421
415
|
context.openreader.dialect,
|
|
422
|
-
|
|
416
|
+
typeName,
|
|
423
417
|
fields,
|
|
424
418
|
args
|
|
425
419
|
)
|
|
@@ -454,8 +448,8 @@ export class SchemaBuilder {
|
|
|
454
448
|
|
|
455
449
|
function createQuery(context: Context, info: GraphQLResolveInfo, limit?: Limit) {
|
|
456
450
|
let tree = getResolveTree(info)
|
|
457
|
-
let fields =
|
|
458
|
-
limit?.check(() =>
|
|
451
|
+
let fields = parseObjectTree(model, entityName, info.schema, tree)
|
|
452
|
+
limit?.check(() => getObjectSize(model, fields) + 1)
|
|
459
453
|
return new EntityByIdQuery(
|
|
460
454
|
model,
|
|
461
455
|
context.openreader.dialect,
|
|
@@ -496,9 +490,9 @@ export class SchemaBuilder {
|
|
|
496
490
|
},
|
|
497
491
|
async resolve(source, args, context, info) {
|
|
498
492
|
let tree = getResolveTree(info)
|
|
499
|
-
let fields =
|
|
500
|
-
context.openreader.responseSizeLimit?.check(() =>
|
|
501
|
-
let query = new
|
|
493
|
+
let fields = parseObjectTree(model, entityName, info.schema, tree)
|
|
494
|
+
context.openreader.responseSizeLimit?.check(() => getObjectSize(model, fields) + 1)
|
|
495
|
+
let query = new ListQuery(
|
|
502
496
|
model,
|
|
503
497
|
context.openreader.dialect,
|
|
504
498
|
entityName,
|
|
@@ -512,12 +506,12 @@ export class SchemaBuilder {
|
|
|
512
506
|
}
|
|
513
507
|
}
|
|
514
508
|
|
|
515
|
-
private installRelayConnection(
|
|
509
|
+
private installRelayConnection(typeName: string, query: GqlFieldMap): void {
|
|
516
510
|
let model = this.model
|
|
517
|
-
let outputType = toPlural(
|
|
518
|
-
let edgeType = `${
|
|
511
|
+
let outputType = toPlural(typeName) + 'Connection'
|
|
512
|
+
let edgeType = `${typeName}Edge`
|
|
519
513
|
|
|
520
|
-
query[`${toPlural(toCamelCase(
|
|
514
|
+
query[`${toPlural(toCamelCase(typeName))}Connection`] = {
|
|
521
515
|
type: new GraphQLNonNull(new GraphQLObjectType({
|
|
522
516
|
name: outputType,
|
|
523
517
|
fields: {
|
|
@@ -525,7 +519,7 @@ export class SchemaBuilder {
|
|
|
525
519
|
type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(new GraphQLObjectType({
|
|
526
520
|
name: edgeType,
|
|
527
521
|
fields: {
|
|
528
|
-
node: {type: new GraphQLNonNull(this.get(
|
|
522
|
+
node: {type: new GraphQLNonNull(this.get(typeName))},
|
|
529
523
|
cursor: {type: new GraphQLNonNull(GraphQLString)}
|
|
530
524
|
}
|
|
531
525
|
}))))
|
|
@@ -535,10 +529,10 @@ export class SchemaBuilder {
|
|
|
535
529
|
}
|
|
536
530
|
})),
|
|
537
531
|
args: {
|
|
538
|
-
orderBy: {type: new GraphQLNonNull(this.getOrderBy(
|
|
532
|
+
orderBy: {type: new GraphQLNonNull(this.getOrderBy(typeName))},
|
|
539
533
|
after: {type: GraphQLString},
|
|
540
534
|
first: {type: GraphQLInt},
|
|
541
|
-
where: {type: this.getWhere(
|
|
535
|
+
where: {type: this.getWhere(typeName)}
|
|
542
536
|
},
|
|
543
537
|
async resolve(source, args, context, info) {
|
|
544
538
|
let orderByArg = ensureArray(args.orderBy)
|
|
@@ -546,8 +540,8 @@ export class SchemaBuilder {
|
|
|
546
540
|
throw new UserInputError('orderBy argument is required for connection')
|
|
547
541
|
}
|
|
548
542
|
|
|
549
|
-
let req: RelayConnectionRequest = {
|
|
550
|
-
orderBy: parseOrderBy(model,
|
|
543
|
+
let req: RelayConnectionRequest<AnyFields> = {
|
|
544
|
+
orderBy: parseOrderBy(model, typeName, orderByArg),
|
|
551
545
|
where: parseWhere(args.where)
|
|
552
546
|
}
|
|
553
547
|
|
|
@@ -578,24 +572,24 @@ export class SchemaBuilder {
|
|
|
578
572
|
req.edgeCursor = hasTreeRequest(edgeFields, 'cursor')
|
|
579
573
|
let nodeTree = getTreeRequest(edgeFields, 'node')
|
|
580
574
|
if (nodeTree) {
|
|
581
|
-
req.edgeNode =
|
|
575
|
+
req.edgeNode = parseAnyTree(model, typeName, info.schema, nodeTree)
|
|
582
576
|
}
|
|
583
577
|
}
|
|
584
578
|
|
|
585
|
-
context.openreader.responseSizeLimit?.check(() =>
|
|
579
|
+
context.openreader.responseSizeLimit?.check(() => getConnectionSize(model, typeName, req) + 1)
|
|
586
580
|
|
|
587
|
-
let result = await context.openreader.executeQuery(new
|
|
581
|
+
let result = await context.openreader.executeQuery(new ConnectionQuery(
|
|
588
582
|
model,
|
|
589
583
|
context.openreader.dialect,
|
|
590
|
-
|
|
584
|
+
typeName,
|
|
591
585
|
req
|
|
592
586
|
))
|
|
593
587
|
|
|
594
588
|
if (req.totalCount && result.totalCount == null) {
|
|
595
|
-
result.totalCount = await context.openreader.executeQuery(new
|
|
589
|
+
result.totalCount = await context.openreader.executeQuery(new CountQuery(
|
|
596
590
|
model,
|
|
597
591
|
context.openreader.dialect,
|
|
598
|
-
|
|
592
|
+
typeName,
|
|
599
593
|
req.where
|
|
600
594
|
))
|
|
601
595
|
}
|
package/src/opencrud/tree.ts
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
|
-
import {unexpectedCase} from
|
|
2
|
-
import assert from
|
|
3
|
-
import {GraphQLSchema} from
|
|
4
|
-
import {ResolveTree} from
|
|
5
|
-
import {
|
|
6
|
-
import {FieldRequest, OpaqueRequest} from
|
|
7
|
-
import {Model} from
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import {unexpectedCase} from '@subsquid/util-internal'
|
|
2
|
+
import assert from 'assert'
|
|
3
|
+
import {GraphQLSchema} from 'graphql'
|
|
4
|
+
import {ResolveTree} from 'graphql-parse-resolve-info'
|
|
5
|
+
import {SqlArguments} from '../ir/args'
|
|
6
|
+
import {AnyFields, FieldRequest, FieldsByEntity, OpaqueRequest} from '../ir/fields'
|
|
7
|
+
import {Model} from '../model'
|
|
8
|
+
import {getQueryableEntities} from '../model.tools'
|
|
9
|
+
import {simplifyResolveTree} from '../util/resolve-tree'
|
|
10
|
+
import {ensureArray} from '../util/util'
|
|
11
|
+
import {parseOrderBy} from './orderBy'
|
|
12
|
+
import {parseWhere} from './where'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export function parseObjectTree(
|
|
15
16
|
model: Model,
|
|
16
|
-
|
|
17
|
+
typeName: string,
|
|
17
18
|
schema: GraphQLSchema,
|
|
18
19
|
tree: ResolveTree
|
|
19
20
|
): FieldRequest[] {
|
|
20
21
|
|
|
21
22
|
let requests: FieldRequest[] = []
|
|
22
23
|
let requestedScalars: Record<string, true> = {}
|
|
23
|
-
let object = model[
|
|
24
|
+
let object = model[typeName]
|
|
24
25
|
assert(object.kind == "entity" || object.kind == "object")
|
|
25
26
|
|
|
26
|
-
let fields = simplifyResolveTree(schema, tree,
|
|
27
|
+
let fields = simplifyResolveTree(schema, tree, typeName).fields
|
|
27
28
|
for (let alias in fields) {
|
|
28
29
|
let f = fields[alias]
|
|
29
30
|
let prop = object.properties[f.name]
|
|
@@ -51,7 +52,7 @@ export function parseResolveTree(
|
|
|
51
52
|
type: prop.type,
|
|
52
53
|
prop,
|
|
53
54
|
index: 0,
|
|
54
|
-
children:
|
|
55
|
+
children: parseObjectTree(model, prop.type.name, schema, f)
|
|
55
56
|
})
|
|
56
57
|
break
|
|
57
58
|
case "union": {
|
|
@@ -59,7 +60,7 @@ export function parseResolveTree(
|
|
|
59
60
|
assert(union.kind == "union")
|
|
60
61
|
let children: FieldRequest[] = []
|
|
61
62
|
for (let variant of union.variants) {
|
|
62
|
-
for (let req of
|
|
63
|
+
for (let req of parseObjectTree(model, variant, schema, f)) {
|
|
63
64
|
req.ifType = variant
|
|
64
65
|
children.push(req)
|
|
65
66
|
}
|
|
@@ -83,7 +84,7 @@ export function parseResolveTree(
|
|
|
83
84
|
type: prop.type,
|
|
84
85
|
prop,
|
|
85
86
|
index: 0,
|
|
86
|
-
children:
|
|
87
|
+
children: parseObjectTree(model, prop.type.entity, schema, f)
|
|
87
88
|
})
|
|
88
89
|
break
|
|
89
90
|
case "lookup":
|
|
@@ -94,7 +95,7 @@ export function parseResolveTree(
|
|
|
94
95
|
type: prop.type,
|
|
95
96
|
prop,
|
|
96
97
|
index: 0,
|
|
97
|
-
children:
|
|
98
|
+
children: parseObjectTree(model, prop.type.entity, schema, f)
|
|
98
99
|
})
|
|
99
100
|
break
|
|
100
101
|
case "list-lookup":
|
|
@@ -105,8 +106,8 @@ export function parseResolveTree(
|
|
|
105
106
|
type: prop.type,
|
|
106
107
|
prop,
|
|
107
108
|
index: 0,
|
|
108
|
-
args:
|
|
109
|
-
children:
|
|
109
|
+
args: parseSqlArguments(model, prop.type.entity, f.args),
|
|
110
|
+
children: parseObjectTree(model, prop.type.entity, schema, f)
|
|
110
111
|
})
|
|
111
112
|
break
|
|
112
113
|
default:
|
|
@@ -118,8 +119,8 @@ export function parseResolveTree(
|
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
|
|
121
|
-
export function
|
|
122
|
-
let args:
|
|
122
|
+
export function parseSqlArguments(model: Model, typeName: string, gqlArgs: any): SqlArguments {
|
|
123
|
+
let args: SqlArguments = {}
|
|
123
124
|
|
|
124
125
|
let where = parseWhere(gqlArgs.where)
|
|
125
126
|
if (where) {
|
|
@@ -127,7 +128,7 @@ export function parseEntityListArguments(model: Model, entityName: string, gqlAr
|
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
if (gqlArgs.orderBy) {
|
|
130
|
-
args.orderBy = parseOrderBy(model,
|
|
131
|
+
args.orderBy = parseOrderBy(model, typeName, ensureArray(gqlArgs.orderBy))
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
if (gqlArgs.offset) {
|
|
@@ -142,3 +143,31 @@ export function parseEntityListArguments(model: Model, entityName: string, gqlAr
|
|
|
142
143
|
|
|
143
144
|
return args
|
|
144
145
|
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
export function parseQueryableTree(
|
|
149
|
+
model: Model,
|
|
150
|
+
queryableName: string,
|
|
151
|
+
schema: GraphQLSchema,
|
|
152
|
+
tree: ResolveTree
|
|
153
|
+
): FieldsByEntity {
|
|
154
|
+
let fields: FieldsByEntity = {}
|
|
155
|
+
for (let entity of getQueryableEntities(model, queryableName)) {
|
|
156
|
+
fields[entity] = parseObjectTree(model, entity, schema, tree)
|
|
157
|
+
}
|
|
158
|
+
return fields
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
export function parseAnyTree(
|
|
163
|
+
model: Model,
|
|
164
|
+
typeName: string,
|
|
165
|
+
schema: GraphQLSchema,
|
|
166
|
+
tree: ResolveTree
|
|
167
|
+
): AnyFields {
|
|
168
|
+
if (model[typeName].kind == 'interface') {
|
|
169
|
+
return parseQueryableTree(model, typeName, schema, tree)
|
|
170
|
+
} else {
|
|
171
|
+
return parseObjectTree(model, typeName, schema, tree)
|
|
172
|
+
}
|
|
173
|
+
}
|
package/src/sql/cursor.ts
CHANGED
|
@@ -154,7 +154,7 @@ export class EntityCursor implements Cursor {
|
|
|
154
154
|
case "fk":
|
|
155
155
|
return new EntityCursor(
|
|
156
156
|
this.ctx,
|
|
157
|
-
prop.type.
|
|
157
|
+
prop.type.entity,
|
|
158
158
|
{on: 'id', rhs: this.native(field)}
|
|
159
159
|
)
|
|
160
160
|
case "lookup":
|
|
@@ -281,7 +281,7 @@ export class ObjectCursor implements Cursor {
|
|
|
281
281
|
case "fk":
|
|
282
282
|
return new EntityCursor(
|
|
283
283
|
this.ctx,
|
|
284
|
-
prop.type.
|
|
284
|
+
prop.type.entity,
|
|
285
285
|
{on: 'id', rhs: this.string(field)}
|
|
286
286
|
)
|
|
287
287
|
default:
|
package/src/sql/mapping.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {unexpectedCase} from "@subsquid/util-internal"
|
|
2
|
-
import {FieldRequest} from
|
|
2
|
+
import {FieldRequest, FieldsByEntity} from '../ir/fields'
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
export function mapRows(rows: any[][], fields: FieldRequest[]): any[] {
|
|
@@ -64,3 +64,20 @@ export function mapRow(row: any[], fields: FieldRequest[], ifType?: string): any
|
|
|
64
64
|
}
|
|
65
65
|
return rec
|
|
66
66
|
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
export function mapQueryableRows(rows: any[][], fields: FieldsByEntity): any[] {
|
|
70
|
+
let result = new Array(rows.length)
|
|
71
|
+
for (let i = 0; i < rows.length; i++) {
|
|
72
|
+
result[i] = mapQueryableRow(rows[i], fields)
|
|
73
|
+
}
|
|
74
|
+
return result
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
export function mapQueryableRow(row: any[], fields: FieldsByEntity): any {
|
|
79
|
+
let entity = row[0]
|
|
80
|
+
let rec = mapRow(row[1], fields[entity])
|
|
81
|
+
rec._isTypeOf = entity
|
|
82
|
+
return rec
|
|
83
|
+
}
|