@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.
Files changed (72) hide show
  1. package/lib/ir/args.d.ts +1 -1
  2. package/lib/ir/args.d.ts.map +1 -1
  3. package/lib/ir/connection.d.ts +3 -4
  4. package/lib/ir/connection.d.ts.map +1 -1
  5. package/lib/ir/connection.js.map +1 -1
  6. package/lib/ir/fields.d.ts +6 -2
  7. package/lib/ir/fields.d.ts.map +1 -1
  8. package/lib/ir/fields.js +15 -0
  9. package/lib/ir/fields.js.map +1 -1
  10. package/lib/limit.size.d.ts +4 -4
  11. package/lib/limit.size.d.ts.map +1 -1
  12. package/lib/limit.size.js +51 -20
  13. package/lib/limit.size.js.map +1 -1
  14. package/lib/main.js +0 -9
  15. package/lib/main.js.map +1 -1
  16. package/lib/model.d.ts +2 -1
  17. package/lib/model.d.ts.map +1 -1
  18. package/lib/model.schema.d.ts +2 -2
  19. package/lib/model.schema.d.ts.map +1 -1
  20. package/lib/model.schema.js +8 -3
  21. package/lib/model.schema.js.map +1 -1
  22. package/lib/model.tools.d.ts +6 -1
  23. package/lib/model.tools.d.ts.map +1 -1
  24. package/lib/model.tools.js +111 -8
  25. package/lib/model.tools.js.map +1 -1
  26. package/lib/opencrud/orderBy.d.ts +2 -2
  27. package/lib/opencrud/orderBy.d.ts.map +1 -1
  28. package/lib/opencrud/orderBy.js +13 -17
  29. package/lib/opencrud/orderBy.js.map +1 -1
  30. package/lib/opencrud/schema.d.ts +4 -4
  31. package/lib/opencrud/schema.d.ts.map +1 -1
  32. package/lib/opencrud/schema.js +53 -62
  33. package/lib/opencrud/schema.js.map +1 -1
  34. package/lib/opencrud/tree.d.ts +9 -7
  35. package/lib/opencrud/tree.d.ts.map +1 -1
  36. package/lib/opencrud/tree.js +32 -14
  37. package/lib/opencrud/tree.js.map +1 -1
  38. package/lib/sql/cursor.js +2 -2
  39. package/lib/sql/cursor.js.map +1 -1
  40. package/lib/sql/mapping.d.ts +3 -1
  41. package/lib/sql/mapping.d.ts.map +1 -1
  42. package/lib/sql/mapping.js +16 -1
  43. package/lib/sql/mapping.js.map +1 -1
  44. package/lib/sql/printer.d.ts +29 -11
  45. package/lib/sql/printer.d.ts.map +1 -1
  46. package/lib/sql/printer.js +106 -10
  47. package/lib/sql/printer.js.map +1 -1
  48. package/lib/sql/query.d.ts +11 -11
  49. package/lib/sql/query.d.ts.map +1 -1
  50. package/lib/sql/query.js +41 -19
  51. package/lib/sql/query.js.map +1 -1
  52. package/lib/test/queryable.test.d.ts +2 -0
  53. package/lib/test/queryable.test.d.ts.map +1 -0
  54. package/lib/test/queryable.test.js +255 -0
  55. package/lib/test/queryable.test.js.map +1 -0
  56. package/package.json +2 -2
  57. package/src/ir/args.ts +1 -1
  58. package/src/ir/connection.ts +3 -4
  59. package/src/ir/fields.ts +22 -2
  60. package/src/limit.size.ts +55 -30
  61. package/src/main.ts +0 -11
  62. package/src/model.schema.ts +16 -9
  63. package/src/model.tools.ts +121 -8
  64. package/src/model.ts +2 -1
  65. package/src/opencrud/orderBy.ts +13 -17
  66. package/src/opencrud/schema.ts +78 -84
  67. package/src/opencrud/tree.ts +55 -26
  68. package/src/sql/cursor.ts +2 -2
  69. package/src/sql/mapping.ts +18 -1
  70. package/src/sql/printer.ts +137 -21
  71. package/src/sql/query.ts +50 -30
  72. package/src/test/queryable.test.ts +258 -0
@@ -1,7 +1,7 @@
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"
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 "graphql"
23
+ } from 'graphql'
24
24
  import {
25
25
  GraphQLEnumValueConfigMap,
26
26
  GraphQLFieldConfigArgumentMap,
27
27
  GraphQLFieldConfigMap,
28
28
  GraphQLInputFieldConfigMap
29
- } from "graphql/type/definition"
30
- import {Context} from "../context"
31
- import {decodeRelayConnectionCursor, RelayConnectionRequest} from "../ir/connection"
32
- import {getEntityListSize, getRelaySize, getSize} from '../limit.size'
33
- import {Entity, Interface, JsonObject, Model, Prop} from "../model"
34
- import {getObject, getUnionProps} from "../model.tools"
35
- import {customScalars} from "../scalars"
36
- import {EntityByIdQuery, EntityConnectionQuery, EntityCountQuery, EntityListQuery, Query} from "../sql/query"
37
- import {Subscription} from "../subscription"
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 "../util/resolve-tree"
40
- import {ensureArray, identity} from "../util/util"
41
- import {getOrderByMapping, parseOrderBy} from "./orderBy"
42
- import {parseEntityListArguments, parseResolveTree} from "./tree"
43
- import {parseWhere} from "./where"
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.entityListArguments(prop.type.entity)
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.foreignEntity)
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 entityListArguments(entityName: string): GraphQLFieldConfigArgumentMap {
196
+ private listArguments(typeName: string): GraphQLFieldConfigArgumentMap {
195
197
  return {
196
- where: {type: this.getWhere(entityName)},
197
- orderBy: {type: this.getOrderBy(entityName)},
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(name: string): GraphQLInputType {
204
- let where = this.where.get(name)
205
+ private getWhere(typeName: string): GraphQLInputType {
206
+ let where = this.where.get(typeName)
205
207
  if (where) return where
206
208
 
207
- const object = this.model[name]
208
- switch(object.kind) {
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: `${name}WhereInput`,
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(name)))
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
- this.where.set(name, where)
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(entityName: string): GraphQLInputType {
359
- let orderBy = this.orderBy.get(entityName)
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, entityName).keys()) {
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: `${entityName}OrderByInput`,
358
+ name: `${typeName}OrderByInput`,
371
359
  values
372
360
  })
373
361
  )
374
362
  )
375
- this.orderBy.set(entityName, orderBy)
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.installEntityList(name, query, subscription)
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 installEntityList(entityName: string, query: GqlFieldMap, subscription: GqlFieldMap): void {
402
+ private installListQuery(typeName: string, query: GqlFieldMap, subscription: GqlFieldMap): void {
409
403
  let model = this.model
410
- let queryName = toPlural(toCamelCase(entityName))
411
- let outputType = new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(this.get(entityName))))
412
- let argsType = this.entityListArguments(entityName)
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 fields = parseResolveTree(model, entityName, info.schema, tree)
417
- let args = parseEntityListArguments(model, entityName, tree.args)
418
- limit?.check(() => getEntityListSize(model, entityName, fields, args.limit, args.where) + 1)
419
- return new EntityListQuery(
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
- entityName,
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 = parseResolveTree(model, entityName, info.schema, tree)
458
- limit?.check(() => getSize(model, fields) + 1)
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 = parseResolveTree(model, entityName, info.schema, tree)
500
- context.openreader.responseSizeLimit?.check(() => getSize(model, fields) + 1)
501
- let query = new EntityListQuery(
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(entityName: string, query: GqlFieldMap): void {
509
+ private installRelayConnection(typeName: string, query: GqlFieldMap): void {
516
510
  let model = this.model
517
- let outputType = toPlural(entityName) + 'Connection'
518
- let edgeType = `${entityName}Edge`
511
+ let outputType = toPlural(typeName) + 'Connection'
512
+ let edgeType = `${typeName}Edge`
519
513
 
520
- query[`${toPlural(toCamelCase(entityName))}Connection`] = {
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(entityName))},
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(entityName))},
532
+ orderBy: {type: new GraphQLNonNull(this.getOrderBy(typeName))},
539
533
  after: {type: GraphQLString},
540
534
  first: {type: GraphQLInt},
541
- where: {type: this.getWhere(entityName)}
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, entityName, orderByArg),
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 = parseResolveTree(model, entityName, info.schema, nodeTree)
575
+ req.edgeNode = parseAnyTree(model, typeName, info.schema, nodeTree)
582
576
  }
583
577
  }
584
578
 
585
- context.openreader.responseSizeLimit?.check(() => getRelaySize(model, entityName, req) + 1)
579
+ context.openreader.responseSizeLimit?.check(() => getConnectionSize(model, typeName, req) + 1)
586
580
 
587
- let result = await context.openreader.executeQuery(new EntityConnectionQuery(
581
+ let result = await context.openreader.executeQuery(new ConnectionQuery(
588
582
  model,
589
583
  context.openreader.dialect,
590
- entityName,
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 EntityCountQuery(
589
+ result.totalCount = await context.openreader.executeQuery(new CountQuery(
596
590
  model,
597
591
  context.openreader.dialect,
598
- entityName,
592
+ typeName,
599
593
  req.where
600
594
  ))
601
595
  }
@@ -1,29 +1,30 @@
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 {EntityListArguments} from "../ir/args"
6
- import {FieldRequest, OpaqueRequest} from "../ir/fields"
7
- import {Model} from "../model"
8
- import {simplifyResolveTree} from "../util/resolve-tree"
9
- import {ensureArray} from "../util/util"
10
- import {parseOrderBy} from "./orderBy"
11
- import {parseWhere} from "./where"
12
-
13
-
14
- export function parseResolveTree(
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
- objectName: string,
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[objectName]
24
+ let object = model[typeName]
24
25
  assert(object.kind == "entity" || object.kind == "object")
25
26
 
26
- let fields = simplifyResolveTree(schema, tree, objectName).fields
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: parseResolveTree(model, prop.type.name, schema, f)
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 parseResolveTree(model, variant, schema, f)) {
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: parseResolveTree(model, prop.type.foreignEntity, schema, f)
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: parseResolveTree(model, prop.type.entity, schema, f)
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: parseEntityListArguments(model, prop.type.entity, f.args),
109
- children: parseResolveTree(model, prop.type.entity, schema, f)
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 parseEntityListArguments(model: Model, entityName: string, gqlArgs: any): EntityListArguments {
122
- let args: EntityListArguments = {}
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, entityName, ensureArray(gqlArgs.orderBy))
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.foreignEntity,
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.foreignEntity,
284
+ prop.type.entity,
285
285
  {on: 'id', rhs: this.string(field)}
286
286
  )
287
287
  default:
@@ -1,5 +1,5 @@
1
1
  import {unexpectedCase} from "@subsquid/util-internal"
2
- import {FieldRequest} from "../ir/fields"
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
+ }