@subsquid/openreader 4.6.0 → 5.0.0-beta.79fbfe

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/lib/context.d.ts +2 -2
  2. package/lib/context.d.ts.map +1 -1
  3. package/lib/db.d.ts +3 -3
  4. package/lib/db.d.ts.map +1 -1
  5. package/lib/db.js +2 -2
  6. package/lib/db.js.map +1 -1
  7. package/lib/dialect/common.d.ts +19 -0
  8. package/lib/dialect/common.d.ts.map +1 -0
  9. package/lib/dialect/common.js +42 -0
  10. package/lib/dialect/common.js.map +1 -0
  11. package/lib/dialect/index.d.ts +6 -0
  12. package/lib/dialect/index.d.ts.map +1 -0
  13. package/lib/dialect/index.js +49 -0
  14. package/lib/dialect/index.js.map +1 -0
  15. package/lib/{opencrud → dialect/opencrud}/orderBy.d.ts +2 -3
  16. package/lib/dialect/opencrud/orderBy.d.ts.map +1 -0
  17. package/lib/{opencrud → dialect/opencrud}/orderBy.js +4 -21
  18. package/lib/dialect/opencrud/orderBy.js.map +1 -0
  19. package/lib/{opencrud → dialect/opencrud}/schema.d.ts +2 -6
  20. package/lib/dialect/opencrud/schema.d.ts.map +1 -0
  21. package/lib/{opencrud → dialect/opencrud}/schema.js +21 -34
  22. package/lib/dialect/opencrud/schema.js.map +1 -0
  23. package/lib/{opencrud → dialect/opencrud}/tree.d.ts +3 -3
  24. package/lib/dialect/opencrud/tree.d.ts.map +1 -0
  25. package/lib/{opencrud → dialect/opencrud}/tree.js +3 -3
  26. package/lib/dialect/opencrud/tree.js.map +1 -0
  27. package/lib/{opencrud → dialect/opencrud}/where.d.ts +1 -1
  28. package/lib/dialect/opencrud/where.d.ts.map +1 -0
  29. package/lib/{opencrud → dialect/opencrud}/where.js +4 -13
  30. package/lib/dialect/opencrud/where.js.map +1 -0
  31. package/lib/dialect/thegraph/locale.d.ts +2 -0
  32. package/lib/dialect/thegraph/locale.d.ts.map +1 -0
  33. package/lib/dialect/thegraph/locale.js +49 -0
  34. package/lib/dialect/thegraph/locale.js.map +1 -0
  35. package/lib/dialect/thegraph/orderBy.d.ts +11 -0
  36. package/lib/dialect/thegraph/orderBy.d.ts.map +1 -0
  37. package/lib/dialect/thegraph/orderBy.js +71 -0
  38. package/lib/dialect/thegraph/orderBy.js.map +1 -0
  39. package/lib/dialect/thegraph/schema.d.ts +25 -0
  40. package/lib/dialect/thegraph/schema.d.ts.map +1 -0
  41. package/lib/dialect/thegraph/schema.js +429 -0
  42. package/lib/dialect/thegraph/schema.js.map +1 -0
  43. package/lib/dialect/thegraph/tree.d.ts +10 -0
  44. package/lib/dialect/thegraph/tree.d.ts.map +1 -0
  45. package/lib/dialect/thegraph/tree.js +148 -0
  46. package/lib/dialect/thegraph/tree.js.map +1 -0
  47. package/lib/dialect/thegraph/where.d.ts +9 -0
  48. package/lib/dialect/thegraph/where.d.ts.map +1 -0
  49. package/lib/dialect/thegraph/where.js +188 -0
  50. package/lib/dialect/thegraph/where.js.map +1 -0
  51. package/lib/ir/args.d.ts +1 -1
  52. package/lib/ir/args.d.ts.map +1 -1
  53. package/lib/main.js +1 -1
  54. package/lib/main.js.map +1 -1
  55. package/lib/model.d.ts +2 -0
  56. package/lib/model.d.ts.map +1 -1
  57. package/lib/model.schema.d.ts.map +1 -1
  58. package/lib/model.schema.js +31 -2
  59. package/lib/model.schema.js.map +1 -1
  60. package/lib/server.d.ts +3 -1
  61. package/lib/server.d.ts.map +1 -1
  62. package/lib/server.js +7 -6
  63. package/lib/server.js.map +1 -1
  64. package/lib/sql/cursor.d.ts +2 -2
  65. package/lib/sql/cursor.d.ts.map +1 -1
  66. package/lib/sql/cursor.js +2 -2
  67. package/lib/sql/cursor.js.map +1 -1
  68. package/lib/sql/printer.d.ts +3 -3
  69. package/lib/sql/printer.d.ts.map +1 -1
  70. package/lib/sql/printer.js +17 -15
  71. package/lib/sql/printer.js.map +1 -1
  72. package/lib/sql/query.d.ts +5 -5
  73. package/lib/sql/query.d.ts.map +1 -1
  74. package/lib/sql/query.js.map +1 -1
  75. package/lib/sql/util.d.ts +2 -2
  76. package/lib/sql/util.d.ts.map +1 -1
  77. package/lib/sql/util.js.map +1 -1
  78. package/lib/test/basic.test.js +471 -229
  79. package/lib/test/basic.test.js.map +1 -1
  80. package/lib/test/isNull.test.js +87 -36
  81. package/lib/test/isNull.test.js.map +1 -1
  82. package/lib/test/limits.test.js +206 -94
  83. package/lib/test/limits.test.js.map +1 -1
  84. package/lib/test/lookup.test.js +184 -81
  85. package/lib/test/lookup.test.js.map +1 -1
  86. package/lib/test/setup.js +2 -2
  87. package/lib/test/setup.js.map +1 -1
  88. package/lib/test/where.test.js +216 -99
  89. package/lib/test/where.test.js.map +1 -1
  90. package/package.json +5 -3
  91. package/src/context.ts +2 -2
  92. package/src/db.ts +4 -2
  93. package/src/dialect/common.ts +49 -0
  94. package/src/dialect/index.ts +20 -0
  95. package/src/{opencrud → dialect/opencrud}/orderBy.ts +4 -21
  96. package/src/{opencrud → dialect/opencrud}/schema.ts +30 -55
  97. package/src/{opencrud → dialect/opencrud}/tree.ts +6 -7
  98. package/src/{opencrud → dialect/opencrud}/where.ts +4 -16
  99. package/src/dialect/thegraph/locale.ts +284 -0
  100. package/src/dialect/thegraph/orderBy.ts +75 -0
  101. package/src/dialect/thegraph/schema.ts +484 -0
  102. package/src/dialect/thegraph/tree.ts +162 -0
  103. package/src/dialect/thegraph/where.ts +184 -0
  104. package/src/ir/args.ts +2 -0
  105. package/src/main.ts +3 -3
  106. package/src/model.schema.ts +37 -4
  107. package/src/model.ts +2 -0
  108. package/src/server.ts +21 -19
  109. package/src/sql/cursor.ts +4 -4
  110. package/src/sql/printer.ts +22 -18
  111. package/src/sql/query.ts +5 -5
  112. package/src/sql/util.ts +2 -2
  113. package/src/test/basic.test.ts +570 -282
  114. package/src/test/isNull.test.ts +95 -38
  115. package/src/test/limits.test.ts +212 -91
  116. package/src/test/lookup.test.ts +190 -83
  117. package/src/test/setup.ts +2 -2
  118. package/src/test/where.test.ts +235 -108
  119. package/lib/dialect.d.ts +0 -2
  120. package/lib/dialect.d.ts.map +0 -1
  121. package/lib/dialect.js +0 -3
  122. package/lib/dialect.js.map +0 -1
  123. package/lib/opencrud/orderBy.d.ts.map +0 -1
  124. package/lib/opencrud/orderBy.js.map +0 -1
  125. package/lib/opencrud/schema.d.ts.map +0 -1
  126. package/lib/opencrud/schema.js.map +0 -1
  127. package/lib/opencrud/tree.d.ts.map +0 -1
  128. package/lib/opencrud/tree.js.map +0 -1
  129. package/lib/opencrud/where.d.ts.map +0 -1
  130. package/lib/opencrud/where.js.map +0 -1
  131. package/src/dialect.ts +0 -2
@@ -27,29 +27,21 @@ import {
27
27
  GraphQLFieldConfigMap,
28
28
  GraphQLInputFieldConfigMap
29
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 {Limit} from '../util/limit'
39
- import {getResolveTree, getTreeRequest, hasTreeRequest, simplifyResolveTree} from '../util/resolve-tree'
40
- import {ensureArray, identity} from '../util/util'
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 {getEntity, getObject, getUniversalProperties} from '../../model.tools'
36
+ import {customScalars} from '../../scalars'
37
+ import {ConnectionQuery, CountQuery, EntityByIdQuery, ListQuery, Query} from '../../sql/query'
38
+ import {Limit} from '../../util/limit'
39
+ import {getResolveTree, getTreeRequest, hasTreeRequest, simplifyResolveTree} from '../../util/resolve-tree'
40
+ import {ensureArray, identity} from '../../util/util'
41
41
  import {getOrderByMapping, parseOrderBy} from './orderBy'
42
42
  import {parseAnyTree, parseObjectTree, parseSqlArguments} from './tree'
43
43
  import {parseWhere} from './where'
44
-
45
-
46
- type GqlFieldMap = GraphQLFieldConfigMap<unknown, Context>
47
-
48
-
49
- export interface SchemaOptions {
50
- model: Model
51
- subscriptions?: boolean
52
- }
44
+ import {GqlFieldMap, SchemaOptions} from '../common'
53
45
 
54
46
 
55
47
  export class SchemaBuilder {
@@ -377,7 +369,6 @@ export class SchemaBuilder {
377
369
  case "entity":
378
370
  this.installListQuery(name, query, subscription)
379
371
  this.installEntityById(name, query, subscription)
380
- this.installEntityByUniqueInput(name, query)
381
372
  this.installRelayConnection(name, query)
382
373
  break
383
374
  case 'interface':
@@ -403,7 +394,9 @@ export class SchemaBuilder {
403
394
 
404
395
  private installListQuery(typeName: string, query: GqlFieldMap, subscription: GqlFieldMap): void {
405
396
  let model = this.model
406
- let queryName = toPlural(toCamelCase(typeName))
397
+
398
+ let entity = model[typeName]
399
+ let queryName = entity.kind === 'entity' && entity.listQueryName || this.normalizeEntityName(typeName).plural
407
400
  let outputType = new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(this.get(typeName))))
408
401
  let argsType = this.listArguments(typeName)
409
402
 
@@ -414,7 +407,7 @@ export class SchemaBuilder {
414
407
  limit?.check(() => getListSize(model, typeName, fields, args.limit, args.where) + 1)
415
408
  return new ListQuery(
416
409
  model,
417
- context.openreader.dialect,
410
+ context.openreader.dbType,
418
411
  typeName,
419
412
  fields,
420
413
  args
@@ -443,7 +436,9 @@ export class SchemaBuilder {
443
436
 
444
437
  private installEntityById(entityName: string, query: GqlFieldMap, subscription: GqlFieldMap): void {
445
438
  let model = this.model
446
- let queryName = `${toCamelCase(entityName)}ById`
439
+
440
+ let entity = model[entityName]
441
+ let queryName = (entity.kind === 'entity' && entity.queryName) || `${this.normalizeEntityName(entityName).singular}ById`
447
442
  let argsType = {
448
443
  id: {type: new GraphQLNonNull(GraphQLString)}
449
444
  }
@@ -454,7 +449,7 @@ export class SchemaBuilder {
454
449
  limit?.check(() => getObjectSize(model, fields) + 1)
455
450
  return new EntityByIdQuery(
456
451
  model,
457
- context.openreader.dialect,
452
+ context.openreader.dbType,
458
453
  entityName,
459
454
  fields,
460
455
  tree.args.id as string
@@ -481,39 +476,12 @@ export class SchemaBuilder {
481
476
  }
482
477
  }
483
478
 
484
- private installEntityByUniqueInput(entityName: string, query: GqlFieldMap): void {
485
- let model = this.model
486
-
487
- query[`${toCamelCase(entityName)}ByUniqueInput`] = {
488
- deprecationReason: `Use ${toCamelCase(entityName)}ById`,
489
- type: this.get(entityName),
490
- args: {
491
- where: {type: this.whereIdInput()}
492
- },
493
- async resolve(source, args, context, info) {
494
- let tree = getResolveTree(info)
495
- let fields = parseObjectTree(model, entityName, info.schema, tree)
496
- context.openreader.responseSizeLimit?.check(() => getObjectSize(model, fields) + 1)
497
- let query = new ListQuery(
498
- model,
499
- context.openreader.dialect,
500
- entityName,
501
- fields,
502
- {where: {op: 'eq', field: 'id', value: args.where.id}}
503
- )
504
- let result = await context.openreader.executeQuery(query)
505
- assert(result.length < 2)
506
- return result[0]
507
- }
508
- }
509
- }
510
-
511
479
  private installRelayConnection(typeName: string, query: GqlFieldMap): void {
512
480
  let model = this.model
513
481
  let outputType = toPlural(typeName) + 'Connection'
514
482
  let edgeType = `${typeName}Edge`
515
483
 
516
- query[`${toPlural(toCamelCase(typeName))}Connection`] = {
484
+ query[`${this.normalizeEntityName(typeName).plural}Connection`] = {
517
485
  type: new GraphQLNonNull(new GraphQLObjectType({
518
486
  name: outputType,
519
487
  fields: {
@@ -582,7 +550,7 @@ export class SchemaBuilder {
582
550
 
583
551
  let result = await context.openreader.executeQuery(new ConnectionQuery(
584
552
  model,
585
- context.openreader.dialect,
553
+ context.openreader.dbType,
586
554
  typeName,
587
555
  req
588
556
  ))
@@ -590,7 +558,7 @@ export class SchemaBuilder {
590
558
  if (req.totalCount && result.totalCount == null) {
591
559
  result.totalCount = await context.openreader.executeQuery(new CountQuery(
592
560
  model,
593
- context.openreader.dialect,
561
+ context.openreader.dbType,
594
562
  typeName,
595
563
  req.where
596
564
  ))
@@ -627,6 +595,13 @@ export class SchemaBuilder {
627
595
  })
628
596
  )
629
597
  }
598
+
599
+ private normalizeEntityName(typeName: string) {
600
+ let singular = toCamelCase(typeName)
601
+ let plural = toPlural(singular)
602
+
603
+ return {singular, plural}
604
+ }
630
605
  }
631
606
 
632
607
 
@@ -2,12 +2,12 @@ import {unexpectedCase} from '@subsquid/util-internal'
2
2
  import assert from 'assert'
3
3
  import {GraphQLSchema} from 'graphql'
4
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'
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
11
  import {parseOrderBy} from './orderBy'
12
12
  import {parseWhere} from './where'
13
13
 
@@ -18,7 +18,6 @@ export function parseObjectTree(
18
18
  schema: GraphQLSchema,
19
19
  tree: ResolveTree
20
20
  ): FieldRequest[] {
21
-
22
21
  let requests: FieldRequest[] = []
23
22
  let requestedScalars: Record<string, true> = {}
24
23
  let object = model[typeName]
@@ -1,7 +1,8 @@
1
1
  import {unexpectedCase} from "@subsquid/util-internal"
2
2
  import assert from "assert"
3
- import {Where} from "../ir/args"
4
- import {ensureArray} from "../util/util"
3
+ import {Where} from "../../ir/args"
4
+ import {ensureArray} from "../../util/util"
5
+ import {toCondition} from '../common'
5
6
 
6
7
 
7
8
  export function parseWhere(whereArg?: any): Where | undefined {
@@ -86,19 +87,6 @@ export function parseWhere(whereArg?: any): Where | undefined {
86
87
  }
87
88
  }
88
89
 
89
-
90
- function toCondition(op: 'AND' | 'OR', operands: Where[]): Where | undefined {
91
- switch(operands.length) {
92
- case 0:
93
- return undefined
94
- case 1:
95
- return operands[0]
96
- default:
97
- return {op, args: operands}
98
- }
99
- }
100
-
101
-
102
90
  export function parseWhereKey(key: string): {op: Where['op'], field: string} {
103
91
  let m = WHERE_KEY_REGEX.exec(key)
104
92
  if (m) {
@@ -138,4 +126,4 @@ const WHERE_KEY_REGEX = (() => {
138
126
  "not_in",
139
127
  ]
140
128
  return new RegExp(`^([^_]*)_(${ops.join('|')})$`)
141
- })()
129
+ })()
@@ -0,0 +1,284 @@
1
+ import {inflections, pluralize} from 'inflected'
2
+
3
+ const THEGRAPH_LOCALE = 'thegraph'
4
+
5
+ // ref https://github.com/whatisinternet/Inflector/blob/master/src/string/pluralize/mod.rs
6
+ inflections(THEGRAPH_LOCALE, (inflector) => {
7
+ inflector.plural(/(\w*)$/, '$1s')
8
+ inflector.plural(/(\w*)s$/, '$1s')
9
+ inflector.plural(/(\w*([^aeiou]ese))$/, '$1')
10
+ inflector.plural(/(\w*(ax|test))is$/, '$1es')
11
+ inflector.plural(/(\w*(alias|[^aou]us|tlas|gas|ris))$/, '$1es')
12
+ inflector.plural(/(\w*(e[mn]u))s?$/, '$1s')
13
+ inflector.plural(/(\w*([^l]ias|[aeiou]las|[emjzr]as|[iu]am))$/, '$1')
14
+ inflector.plural(
15
+ /(\w*(alumn|syllab|octop|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat))(?:us|i)$/,
16
+ '$1i'
17
+ )
18
+ inflector.plural(/(\w*(alumn|alg|vertebr))(?:a|ae)$/, '$1ae')
19
+ inflector.plural(/(\w*(seraph|cherub))(?:im)?$/, '$1im')
20
+ inflector.plural(/(\w*(her|at|gr))o$/, '$1oes')
21
+ inflector.plural(
22
+ /(\w*(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor))(?:a|um)$/,
23
+ '$1a'
24
+ )
25
+ inflector.plural(
26
+ /(\w*(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat))(?:a|on)$/,
27
+ '$1a'
28
+ )
29
+ inflector.plural(/(\w*)sis$/, '$1ses')
30
+ inflector.plural(/(\w*(kni|wi|li))fe$/, '$1ves')
31
+ inflector.plural(/(\w*(ar|l|ea|eo|oa|hoo))f$/, '$1ves')
32
+ inflector.plural(/(\w*([^aeiouy]|qu))y$/, '$1ies')
33
+ inflector.plural(/(\w*([^ch][ieo][ln]))ey$/, '$1ies')
34
+ inflector.plural(/(\w*(x|ch|ss|sh|zz)es)$/, '$1')
35
+ inflector.plural(/(\w*(x|ch|ss|sh|zz))$/, '$1es')
36
+ inflector.plural(/(\w*(matr|cod|mur|sil|vert|ind|append))(?:ix|ex)$/, '$1ices')
37
+ inflector.plural(/(\w*(m|l)(?:ice|ouse))$/, '$1ice')
38
+ inflector.plural(/(\w*(pe)(?:rson|ople))$/, '$1ople')
39
+ inflector.plural(/(\w*(child))(?:ren)?$/, '$1ren')
40
+ inflector.plural(/(\w*eaux)$/, '$1')
41
+
42
+ inflector.irregular('ox', 'oxes')
43
+ inflector.irregular('man', 'men')
44
+ inflector.irregular('woman', 'women')
45
+ inflector.irregular('die', 'dice')
46
+ inflector.irregular('yes', 'yeses')
47
+ inflector.irregular('foot', 'feet')
48
+ inflector.irregular('eave', 'eaves')
49
+ inflector.irregular('goose', 'geese')
50
+ inflector.irregular('tooth', 'teeth')
51
+ inflector.irregular('quiz', 'quizzes')
52
+
53
+ inflector.uncountable(
54
+ 'accommodation',
55
+ 'adulthood',
56
+ 'advertising',
57
+ 'advice',
58
+ 'aggression',
59
+ 'aid',
60
+ 'air',
61
+ 'aircraft',
62
+ 'alcohol',
63
+ 'anger',
64
+ 'applause',
65
+ 'arithmetic',
66
+ 'assistance',
67
+ 'athletics',
68
+
69
+ 'bacon',
70
+ 'baggage',
71
+ 'beef',
72
+ 'biology',
73
+ 'blood',
74
+ 'botany',
75
+ 'bread',
76
+ 'butter',
77
+
78
+ 'carbon',
79
+ 'cardboard',
80
+ 'cash',
81
+ 'chalk',
82
+ 'chaos',
83
+ 'chess',
84
+ 'crossroads',
85
+ 'countryside',
86
+
87
+ 'dancing',
88
+ 'deer',
89
+ 'dignity',
90
+ 'dirt',
91
+ 'dust',
92
+
93
+ 'economics',
94
+ 'education',
95
+ 'electricity',
96
+ 'engineering',
97
+ 'enjoyment',
98
+ 'envy',
99
+ 'equipment',
100
+ 'ethics',
101
+ 'evidence',
102
+ 'evolution',
103
+
104
+ 'fame',
105
+ 'fiction',
106
+ 'flour',
107
+ 'flu',
108
+ 'food',
109
+ 'fuel',
110
+ 'fun',
111
+ 'furniture',
112
+
113
+ 'gallows',
114
+ 'garbage',
115
+ 'garlic',
116
+ 'genetics',
117
+ 'gold',
118
+ 'golf',
119
+ 'gossip',
120
+ 'grammar',
121
+ 'gratitude',
122
+ 'grief',
123
+ 'guilt',
124
+ 'gymnastics',
125
+
126
+ 'happiness',
127
+ 'hardware',
128
+ 'harm',
129
+ 'hate',
130
+ 'hatred',
131
+ 'health',
132
+ 'heat',
133
+ 'help',
134
+ 'homework',
135
+ 'honesty',
136
+ 'honey',
137
+ 'hospitality',
138
+ 'housework',
139
+ 'humour',
140
+ 'hunger',
141
+ 'hydrogen',
142
+
143
+ 'ice',
144
+ 'importance',
145
+ 'inflation',
146
+ 'information',
147
+ 'innocence',
148
+ 'iron',
149
+ 'irony',
150
+
151
+ 'jam',
152
+ 'jewelry',
153
+ 'judo',
154
+
155
+ 'karate',
156
+ 'knowledge',
157
+
158
+ 'lack',
159
+ 'laughter',
160
+ 'lava',
161
+ 'leather',
162
+ 'leisure',
163
+ 'lightning',
164
+ 'linguine',
165
+ 'linguini',
166
+ 'linguistics',
167
+ 'literature',
168
+ 'litter',
169
+ 'livestock',
170
+ 'logic',
171
+ 'loneliness',
172
+ 'luck',
173
+ 'luggage',
174
+
175
+ 'macaroni',
176
+ 'machinery',
177
+ 'magic',
178
+ 'management',
179
+ 'mankind',
180
+ 'marble',
181
+ 'mathematics',
182
+ 'mayonnaise',
183
+ 'measles',
184
+ 'methane',
185
+ 'milk',
186
+ 'money',
187
+ 'mud',
188
+ 'music',
189
+ 'mumps',
190
+
191
+ 'nature',
192
+ 'news',
193
+ 'nitrogen',
194
+ 'nonsense',
195
+ 'nurture',
196
+ 'nutrition',
197
+
198
+ 'obedience',
199
+ 'obesity',
200
+ 'oxygen',
201
+
202
+ 'pasta',
203
+ 'patience',
204
+ 'physics',
205
+ 'poetry',
206
+ 'pollution',
207
+ 'poverty',
208
+ 'pride',
209
+ 'psychology',
210
+ 'publicity',
211
+ 'punctuation',
212
+
213
+ 'quartz',
214
+
215
+ 'racism',
216
+ 'relaxation',
217
+ 'reliability',
218
+ 'research',
219
+ 'respect',
220
+ 'revenge',
221
+ 'rice',
222
+ 'rubbish',
223
+ 'rum',
224
+
225
+ 'safety',
226
+ 'scenery',
227
+ 'seafood',
228
+ 'seaside',
229
+ 'series',
230
+ 'shame',
231
+ 'sheep',
232
+ 'shopping',
233
+ 'sleep',
234
+ 'smoke',
235
+ 'smoking',
236
+ 'snow',
237
+ 'soap',
238
+ 'software',
239
+ 'soil',
240
+ 'spaghetti',
241
+ 'species',
242
+ 'steam',
243
+ 'stuff',
244
+ 'stupidity',
245
+ 'sunshine',
246
+ 'symmetry',
247
+
248
+ 'tennis',
249
+ 'thirst',
250
+ 'thunder',
251
+ 'timber',
252
+ 'traffic',
253
+ 'transportation',
254
+ 'trust',
255
+
256
+ 'underwear',
257
+ 'unemployment',
258
+ 'unity',
259
+
260
+ 'validity',
261
+ 'veal',
262
+ 'vegetation',
263
+ 'vegetarianism',
264
+ 'vengeance',
265
+ 'violence',
266
+ 'vitality',
267
+
268
+ 'warmth',
269
+ 'wealth',
270
+ 'weather',
271
+ 'welfare',
272
+ 'wheat',
273
+ 'wildlife',
274
+ 'wisdom',
275
+ 'yoga',
276
+
277
+ 'zinc',
278
+ 'zoology'
279
+ )
280
+ })
281
+
282
+ export function toPlural(value: string) {
283
+ return pluralize(value, THEGRAPH_LOCALE)
284
+ }
@@ -0,0 +1,75 @@
1
+ import assert from 'assert'
2
+ import type {Model} from '../../model'
3
+ import {getUniversalProperties} from '../../model.tools'
4
+ import {OrderBy, SortOrder} from '../../ir/args'
5
+ import {mergeOrderBy} from '../common'
6
+
7
+ export type TheGraphOrderByValue = string
8
+
9
+ export type TheGraph_OrderBy_List = ReadonlySet<TheGraphOrderByValue>
10
+
11
+ const MAPPING_CACHE = new WeakMap<Model, Record<string, TheGraph_OrderBy_List>>()
12
+
13
+ export function getOrderByList(model: Model, typeName: string): TheGraph_OrderBy_List {
14
+ let cache = MAPPING_CACHE.get(model)
15
+ if (cache == null) {
16
+ cache = {}
17
+ MAPPING_CACHE.set(model, cache)
18
+ }
19
+ if (cache[typeName]) return cache[typeName]
20
+ return (cache[typeName] = buildOrderByList(model, typeName, 2))
21
+ }
22
+
23
+ function buildOrderByList(model: Model, typeName: string, depth: number): TheGraph_OrderBy_List {
24
+ if (depth <= 0) return new Set()
25
+ let properties = getUniversalProperties(model, typeName)
26
+ let m = new Set<TheGraphOrderByValue>()
27
+ for (let key in properties) {
28
+ let propType = properties[key].type
29
+ switch (propType.kind) {
30
+ case 'scalar':
31
+ case 'enum':
32
+ if (propType.name != 'JSON') {
33
+ m.add(key)
34
+ }
35
+ break
36
+ case 'object':
37
+ case 'union':
38
+ for (let name of buildOrderByList(model, propType.name, depth - 1)) {
39
+ m.add(key + '__' + name)
40
+ }
41
+ break
42
+ case 'fk':
43
+ case 'lookup':
44
+ m.add(key)
45
+ for (let name of buildOrderByList(model, propType.entity, depth - 1)) {
46
+ m.add(key + '__' + name)
47
+ }
48
+ break
49
+ }
50
+ }
51
+ return m
52
+ }
53
+
54
+ export const ORDER_DIRECTIONS: Record<string, SortOrder> = {
55
+ asc: 'ASC',
56
+ asc_nulls_first: 'ASC NULLS FIRST',
57
+ asc_nulls_last: 'ASC NULLS LAST',
58
+ desc: 'DESC',
59
+ desc_nulls_first: 'DESC NULLS FIRST',
60
+ desc_nulls_last: 'DESC NULLS LAST',
61
+ }
62
+
63
+ export function parseOrderBy(model: Model, typeName: string, input: {orderBy: string; direction?: string}): OrderBy {
64
+ let list = getOrderByList(model, typeName)
65
+ assert(list.has(input.orderBy))
66
+
67
+ const sortOrder = input.direction ? ORDER_DIRECTIONS[input.direction] : ORDER_DIRECTIONS['asc']
68
+ assert(sortOrder)
69
+
70
+ const keys = input.orderBy.split('__').reverse()
71
+ const res = keys.reduce((res: OrderBy | null, key) => ({[key]: res ?? sortOrder}), null)
72
+ assert(res)
73
+
74
+ return res
75
+ }