@subsquid/openreader 4.6.0 → 5.0.0-beta.79d2fc
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/context.d.ts +2 -2
- package/lib/context.d.ts.map +1 -1
- package/lib/db.d.ts +3 -3
- package/lib/db.d.ts.map +1 -1
- package/lib/db.js +2 -2
- package/lib/db.js.map +1 -1
- package/lib/dialect/common.d.ts +19 -0
- package/lib/dialect/common.d.ts.map +1 -0
- package/lib/dialect/common.js +42 -0
- package/lib/dialect/common.js.map +1 -0
- package/lib/dialect/index.d.ts +6 -0
- package/lib/dialect/index.d.ts.map +1 -0
- package/lib/dialect/index.js +49 -0
- package/lib/dialect/index.js.map +1 -0
- package/lib/{opencrud → dialect/opencrud}/orderBy.d.ts +2 -3
- package/lib/dialect/opencrud/orderBy.d.ts.map +1 -0
- package/lib/{opencrud → dialect/opencrud}/orderBy.js +4 -21
- package/lib/dialect/opencrud/orderBy.js.map +1 -0
- package/lib/{opencrud → dialect/opencrud}/schema.d.ts +2 -6
- package/lib/dialect/opencrud/schema.d.ts.map +1 -0
- package/lib/{opencrud → dialect/opencrud}/schema.js +21 -34
- package/lib/dialect/opencrud/schema.js.map +1 -0
- package/lib/{opencrud → dialect/opencrud}/tree.d.ts +3 -3
- package/lib/dialect/opencrud/tree.d.ts.map +1 -0
- package/lib/{opencrud → dialect/opencrud}/tree.js +3 -3
- package/lib/dialect/opencrud/tree.js.map +1 -0
- package/lib/{opencrud → dialect/opencrud}/where.d.ts +1 -1
- package/lib/dialect/opencrud/where.d.ts.map +1 -0
- package/lib/{opencrud → dialect/opencrud}/where.js +4 -13
- package/lib/dialect/opencrud/where.js.map +1 -0
- package/lib/dialect/thegraph/locale.d.ts +2 -0
- package/lib/dialect/thegraph/locale.d.ts.map +1 -0
- package/lib/dialect/thegraph/locale.js +49 -0
- package/lib/dialect/thegraph/locale.js.map +1 -0
- package/lib/dialect/thegraph/orderBy.d.ts +11 -0
- package/lib/dialect/thegraph/orderBy.d.ts.map +1 -0
- package/lib/dialect/thegraph/orderBy.js +71 -0
- package/lib/dialect/thegraph/orderBy.js.map +1 -0
- package/lib/dialect/thegraph/schema.d.ts +25 -0
- package/lib/dialect/thegraph/schema.d.ts.map +1 -0
- package/lib/dialect/thegraph/schema.js +429 -0
- package/lib/dialect/thegraph/schema.js.map +1 -0
- package/lib/dialect/thegraph/tree.d.ts +10 -0
- package/lib/dialect/thegraph/tree.d.ts.map +1 -0
- package/lib/dialect/thegraph/tree.js +148 -0
- package/lib/dialect/thegraph/tree.js.map +1 -0
- package/lib/dialect/thegraph/where.d.ts +9 -0
- package/lib/dialect/thegraph/where.d.ts.map +1 -0
- package/lib/dialect/thegraph/where.js +198 -0
- package/lib/dialect/thegraph/where.js.map +1 -0
- package/lib/ir/args.d.ts +1 -1
- package/lib/ir/args.d.ts.map +1 -1
- package/lib/main.js +1 -1
- package/lib/main.js.map +1 -1
- package/lib/model.d.ts +2 -0
- package/lib/model.d.ts.map +1 -1
- package/lib/model.schema.d.ts.map +1 -1
- package/lib/model.schema.js +31 -2
- package/lib/model.schema.js.map +1 -1
- package/lib/server.d.ts +3 -1
- package/lib/server.d.ts.map +1 -1
- package/lib/server.js +7 -6
- package/lib/server.js.map +1 -1
- package/lib/sql/cursor.d.ts +2 -2
- package/lib/sql/cursor.d.ts.map +1 -1
- package/lib/sql/cursor.js +2 -2
- package/lib/sql/cursor.js.map +1 -1
- package/lib/sql/printer.d.ts +3 -3
- package/lib/sql/printer.d.ts.map +1 -1
- package/lib/sql/printer.js +17 -15
- package/lib/sql/printer.js.map +1 -1
- package/lib/sql/query.d.ts +5 -5
- package/lib/sql/query.d.ts.map +1 -1
- package/lib/sql/query.js.map +1 -1
- package/lib/sql/util.d.ts +2 -2
- package/lib/sql/util.d.ts.map +1 -1
- package/lib/sql/util.js.map +1 -1
- package/lib/test/basic.test.js +471 -229
- package/lib/test/basic.test.js.map +1 -1
- package/lib/test/isNull.test.js +87 -36
- package/lib/test/isNull.test.js.map +1 -1
- package/lib/test/limits.test.js +206 -94
- package/lib/test/limits.test.js.map +1 -1
- package/lib/test/lookup.test.js +184 -81
- package/lib/test/lookup.test.js.map +1 -1
- package/lib/test/setup.js +2 -2
- package/lib/test/setup.js.map +1 -1
- package/lib/test/where.test.js +216 -99
- package/lib/test/where.test.js.map +1 -1
- package/package.json +5 -3
- package/src/context.ts +2 -2
- package/src/db.ts +4 -2
- package/src/dialect/common.ts +49 -0
- package/src/dialect/index.ts +20 -0
- package/src/{opencrud → dialect/opencrud}/orderBy.ts +4 -21
- package/src/{opencrud → dialect/opencrud}/schema.ts +30 -55
- package/src/{opencrud → dialect/opencrud}/tree.ts +6 -7
- package/src/{opencrud → dialect/opencrud}/where.ts +4 -16
- package/src/dialect/thegraph/locale.ts +284 -0
- package/src/dialect/thegraph/orderBy.ts +75 -0
- package/src/dialect/thegraph/schema.ts +484 -0
- package/src/dialect/thegraph/tree.ts +162 -0
- package/src/dialect/thegraph/where.ts +192 -0
- package/src/ir/args.ts +2 -0
- package/src/main.ts +3 -3
- package/src/model.schema.ts +37 -4
- package/src/model.ts +2 -0
- package/src/server.ts +21 -19
- package/src/sql/cursor.ts +4 -4
- package/src/sql/printer.ts +22 -18
- package/src/sql/query.ts +5 -5
- package/src/sql/util.ts +2 -2
- package/src/test/basic.test.ts +570 -282
- package/src/test/isNull.test.ts +95 -38
- package/src/test/limits.test.ts +212 -91
- package/src/test/lookup.test.ts +190 -83
- package/src/test/setup.ts +2 -2
- package/src/test/where.test.ts +235 -108
- package/lib/dialect.d.ts +0 -2
- package/lib/dialect.d.ts.map +0 -1
- package/lib/dialect.js +0 -3
- package/lib/dialect.js.map +0 -1
- package/lib/opencrud/orderBy.d.ts.map +0 -1
- package/lib/opencrud/orderBy.js.map +0 -1
- package/lib/opencrud/schema.d.ts.map +0 -1
- package/lib/opencrud/schema.js.map +0 -1
- package/lib/opencrud/tree.d.ts.map +0 -1
- package/lib/opencrud/tree.js.map +0 -1
- package/lib/opencrud/where.d.ts.map +0 -1
- package/lib/opencrud/where.js.map +0 -1
- 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 '
|
|
31
|
-
import {decodeRelayConnectionCursor, RelayConnectionRequest} from '
|
|
32
|
-
import {AnyFields} from '
|
|
33
|
-
import {getConnectionSize, getListSize, getObjectSize} from '
|
|
34
|
-
import {Entity, Interface, JsonObject, Model, Prop} from '
|
|
35
|
-
import {getObject, getUniversalProperties} from '
|
|
36
|
-
import {customScalars} from '
|
|
37
|
-
import {ConnectionQuery, CountQuery, EntityByIdQuery, ListQuery, Query} from '
|
|
38
|
-
import {Limit} from '
|
|
39
|
-
import {getResolveTree, getTreeRequest, hasTreeRequest, simplifyResolveTree} from '
|
|
40
|
-
import {ensureArray, identity} from '
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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[`${
|
|
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.
|
|
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.
|
|
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 '
|
|
6
|
-
import {AnyFields, FieldRequest, FieldsByEntity, OpaqueRequest} from '
|
|
7
|
-
import {Model} from '
|
|
8
|
-
import {getQueryableEntities} from '
|
|
9
|
-
import {simplifyResolveTree} from '
|
|
10
|
-
import {ensureArray} from '
|
|
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 "
|
|
4
|
-
import {ensureArray} from "
|
|
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
|
+
}
|