@subsquid/openreader 1.0.2 → 2.1.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/bin/main.js +1 -1
- package/lib/context.d.ts +14 -0
- package/lib/context.d.ts.map +1 -0
- package/lib/context.js +3 -0
- package/lib/context.js.map +1 -0
- package/lib/db.d.ts +23 -0
- package/lib/db.d.ts.map +1 -0
- package/lib/db.js +57 -0
- package/lib/db.js.map +1 -0
- package/{dist → lib}/dialect.d.ts +0 -0
- package/{dist → lib}/dialect.d.ts.map +0 -0
- package/{dist → lib}/dialect.js +0 -0
- package/{dist → lib}/dialect.js.map +0 -0
- package/lib/ir/args.d.ts +47 -0
- package/lib/ir/args.d.ts.map +1 -0
- package/lib/ir/args.js +3 -0
- package/lib/ir/args.js.map +1 -0
- package/lib/ir/connection.d.ts +30 -0
- package/lib/ir/connection.d.ts.map +1 -0
- package/lib/ir/connection.js +17 -0
- package/lib/ir/connection.js.map +1 -0
- package/lib/ir/fields.d.ts +22 -0
- package/lib/ir/fields.d.ts.map +1 -0
- package/lib/ir/fields.js +3 -0
- package/lib/ir/fields.js.map +1 -0
- package/lib/limit.size.d.ts +8 -0
- package/lib/limit.size.d.ts.map +1 -0
- package/lib/limit.size.js +107 -0
- package/lib/limit.size.js.map +1 -0
- package/{dist → lib}/main.d.ts +0 -0
- package/{dist → lib}/main.d.ts.map +0 -0
- package/lib/main.js +59 -0
- package/lib/main.js.map +1 -0
- package/{dist → lib}/model.d.ts +11 -1
- package/lib/model.d.ts.map +1 -0
- package/{dist → lib}/model.js +0 -0
- package/{dist → lib}/model.js.map +0 -0
- package/{dist/gql/schema.d.ts → lib/model.schema.d.ts} +2 -2
- package/lib/model.schema.d.ts.map +1 -0
- package/{dist/gql/schema.js → lib/model.schema.js} +62 -8
- package/lib/model.schema.js.map +1 -0
- package/{dist → lib}/model.tools.d.ts +0 -0
- package/{dist → lib}/model.tools.d.ts.map +0 -0
- package/{dist → lib}/model.tools.js +0 -0
- package/{dist → lib}/model.tools.js.map +0 -0
- package/{dist → lib/opencrud}/orderBy.d.ts +2 -5
- package/lib/opencrud/orderBy.d.ts.map +1 -0
- package/{dist → lib/opencrud}/orderBy.js +1 -1
- package/lib/opencrud/orderBy.js.map +1 -0
- package/lib/opencrud/schema.d.ts +31 -0
- package/lib/opencrud/schema.d.ts.map +1 -0
- package/lib/opencrud/schema.js +527 -0
- package/lib/opencrud/schema.js.map +1 -0
- package/lib/opencrud/tree.d.ts +8 -0
- package/lib/opencrud/tree.d.ts.map +1 -0
- package/lib/opencrud/tree.js +131 -0
- package/lib/opencrud/tree.js.map +1 -0
- package/lib/opencrud/where.d.ts +7 -0
- package/lib/opencrud/where.d.ts.map +1 -0
- package/lib/opencrud/where.js +141 -0
- package/lib/opencrud/where.js.map +1 -0
- package/{dist/gql → lib}/scalars/BigInt.d.ts +0 -0
- package/lib/scalars/BigInt.d.ts.map +1 -0
- package/{dist/gql → lib}/scalars/BigInt.js +1 -1
- package/lib/scalars/BigInt.js.map +1 -0
- package/{dist/gql → lib}/scalars/Bytes.d.ts +0 -0
- package/lib/scalars/Bytes.d.ts.map +1 -0
- package/{dist/gql → lib}/scalars/Bytes.js +2 -2
- package/lib/scalars/Bytes.js.map +1 -0
- package/{dist/gql → lib}/scalars/DateTime.d.ts +0 -0
- package/lib/scalars/DateTime.d.ts.map +1 -0
- package/{dist/gql → lib}/scalars/DateTime.js +1 -1
- package/lib/scalars/DateTime.js.map +1 -0
- package/{dist/gql → lib}/scalars/JSON.d.ts +0 -0
- package/lib/scalars/JSON.d.ts.map +1 -0
- package/{dist/gql → lib}/scalars/JSON.js +0 -0
- package/lib/scalars/JSON.js.map +1 -0
- package/{dist/gql → lib}/scalars/index.d.ts +0 -0
- package/lib/scalars/index.d.ts.map +1 -0
- package/{dist/gql → lib}/scalars/index.js +0 -0
- package/lib/scalars/index.js.map +1 -0
- package/lib/server.d.ts +42 -0
- package/lib/server.d.ts.map +1 -0
- package/lib/server.js +171 -0
- package/lib/server.js.map +1 -0
- package/lib/sql/cursor.d.ts +52 -0
- package/lib/sql/cursor.d.ts.map +1 -0
- package/lib/sql/cursor.js +234 -0
- package/lib/sql/cursor.js.map +1 -0
- package/lib/sql/mapping.d.ts +4 -0
- package/lib/sql/mapping.d.ts.map +1 -0
- package/lib/sql/mapping.js +71 -0
- package/lib/sql/mapping.js.map +1 -0
- package/lib/sql/printer.d.ts +37 -0
- package/lib/sql/printer.d.ts.map +1 -0
- package/lib/sql/printer.js +311 -0
- package/lib/sql/printer.js.map +1 -0
- package/lib/sql/query.d.ts +46 -0
- package/lib/sql/query.d.ts.map +1 -0
- package/lib/sql/query.js +134 -0
- package/lib/sql/query.js.map +1 -0
- package/lib/sql/util.d.ts +30 -0
- package/lib/sql/util.d.ts.map +1 -0
- package/lib/sql/util.js +75 -0
- package/lib/sql/util.js.map +1 -0
- package/lib/subscription.d.ts +18 -0
- package/lib/subscription.d.ts.map +1 -0
- package/lib/subscription.js +47 -0
- package/lib/subscription.js.map +1 -0
- package/{dist → lib}/test/basic.test.d.ts +0 -0
- package/{dist → lib}/test/basic.test.d.ts.map +0 -0
- package/{dist → lib}/test/basic.test.js +0 -0
- package/{dist → lib}/test/basic.test.js.map +0 -0
- package/{dist → lib}/test/connection.test.d.ts +0 -0
- package/{dist → lib}/test/connection.test.d.ts.map +0 -0
- package/{dist → lib}/test/connection.test.js +0 -0
- package/{dist → lib}/test/connection.test.js.map +0 -0
- package/{dist → lib}/test/fts.test.d.ts +0 -0
- package/{dist → lib}/test/fts.test.d.ts.map +0 -0
- package/{dist → lib}/test/fts.test.js +1 -1
- package/lib/test/fts.test.js.map +1 -0
- package/{dist → lib}/test/isNull.test.d.ts +0 -0
- package/{dist → lib}/test/isNull.test.d.ts.map +0 -0
- package/{dist → lib}/test/isNull.test.js +0 -0
- package/{dist → lib}/test/isNull.test.js.map +0 -0
- package/lib/test/limits.test.d.ts +2 -0
- package/lib/test/limits.test.d.ts.map +1 -0
- package/lib/test/limits.test.js +159 -0
- package/lib/test/limits.test.js.map +1 -0
- package/{dist → lib}/test/lists.test.d.ts +0 -0
- package/{dist → lib}/test/lists.test.d.ts.map +0 -0
- package/{dist → lib}/test/lists.test.js +0 -0
- package/{dist → lib}/test/lists.test.js.map +0 -0
- package/{dist → lib}/test/lookup.test.d.ts +0 -0
- package/{dist → lib}/test/lookup.test.d.ts.map +0 -0
- package/{dist → lib}/test/lookup.test.js +0 -0
- package/{dist → lib}/test/lookup.test.js.map +0 -0
- package/{dist → lib}/test/regressions.test.d.ts +0 -0
- package/{dist → lib}/test/regressions.test.d.ts.map +0 -0
- package/{dist → lib}/test/regressions.test.js +0 -0
- package/{dist → lib}/test/regressions.test.js.map +0 -0
- package/{dist → lib}/test/scalars.test.d.ts +0 -0
- package/{dist → lib}/test/scalars.test.d.ts.map +0 -0
- package/{dist → lib}/test/scalars.test.js +0 -0
- package/{dist → lib}/test/scalars.test.js.map +0 -0
- package/lib/test/setup.d.ts +17 -0
- package/lib/test/setup.d.ts.map +1 -0
- package/{dist → lib}/test/setup.js +18 -13
- package/lib/test/setup.js.map +1 -0
- package/lib/test/subscription.test.d.ts +2 -0
- package/lib/test/subscription.test.d.ts.map +1 -0
- package/lib/test/subscription.test.js +99 -0
- package/lib/test/subscription.test.js.map +1 -0
- package/{dist → lib}/test/tools.test.d.ts +0 -0
- package/{dist → lib}/test/tools.test.d.ts.map +0 -0
- package/{dist → lib}/test/tools.test.js +0 -0
- package/{dist → lib}/test/tools.test.js.map +0 -0
- package/{dist → lib}/test/typed-json.test.d.ts +0 -0
- package/{dist → lib}/test/typed-json.test.d.ts.map +0 -0
- package/{dist → lib}/test/typed-json.test.js +0 -0
- package/{dist → lib}/test/typed-json.test.js.map +0 -0
- package/{dist → lib}/test/unions.test.d.ts +0 -0
- package/{dist → lib}/test/unions.test.d.ts.map +0 -0
- package/{dist → lib}/test/unions.test.js +0 -0
- package/{dist → lib}/test/unions.test.js.map +0 -0
- package/{dist → lib}/test/where.test.d.ts +0 -0
- package/{dist → lib}/test/where.test.d.ts.map +0 -0
- package/{dist → lib}/test/where.test.js +0 -0
- package/{dist → lib}/test/where.test.js.map +0 -0
- package/{dist → lib}/tools.d.ts +0 -0
- package/{dist → lib}/tools.d.ts.map +0 -0
- package/{dist → lib}/tools.js +3 -3
- package/{dist → lib}/tools.js.map +1 -1
- package/lib/util/error-handling.d.ts +11 -0
- package/lib/util/error-handling.d.ts.map +1 -0
- package/lib/util/error-handling.js +42 -0
- package/lib/util/error-handling.js.map +1 -0
- package/lib/util/execute.d.ts +5 -0
- package/lib/util/execute.d.ts.map +1 -0
- package/lib/util/execute.js +28 -0
- package/lib/util/execute.js.map +1 -0
- package/lib/util/lazy-transaction.d.ts +10 -0
- package/lib/util/lazy-transaction.d.ts.map +1 -0
- package/lib/util/lazy-transaction.js +43 -0
- package/lib/util/lazy-transaction.js.map +1 -0
- package/lib/util/limit.d.ts +11 -0
- package/lib/util/limit.d.ts.map +1 -0
- package/lib/util/limit.js +39 -0
- package/lib/util/limit.js.map +1 -0
- package/lib/util/resolve-tree.d.ts +14 -0
- package/lib/util/resolve-tree.d.ts.map +1 -0
- package/lib/util/resolve-tree.js +52 -0
- package/lib/util/resolve-tree.js.map +1 -0
- package/{dist → lib/util}/util.d.ts +2 -3
- package/lib/util/util.d.ts.map +1 -0
- package/{dist → lib/util}/util.js +9 -13
- package/lib/util/util.js.map +1 -0
- package/package.json +18 -10
- package/src/context.ts +17 -0
- package/src/db.ts +46 -57
- package/src/ir/args.ts +85 -0
- package/src/ir/connection.ts +48 -0
- package/src/ir/fields.ts +40 -0
- package/src/limit.size.ts +130 -0
- package/src/main.ts +74 -42
- package/src/{gql/schema.ts → model.schema.ts} +72 -9
- package/src/model.ts +13 -1
- package/src/{orderBy.ts → opencrud/orderBy.ts} +3 -10
- package/src/opencrud/schema.ts +639 -0
- package/src/opencrud/tree.ts +144 -0
- package/src/opencrud/where.ts +141 -0
- package/src/{gql/scalars → scalars}/BigInt.ts +1 -1
- package/src/{gql/scalars → scalars}/Bytes.ts +4 -4
- package/src/{gql/scalars → scalars}/DateTime.ts +1 -1
- package/src/{gql/scalars → scalars}/JSON.ts +0 -0
- package/src/{gql/scalars → scalars}/index.ts +0 -0
- package/src/server.ts +175 -55
- package/src/sql/cursor.ts +291 -0
- package/src/sql/mapping.ts +66 -0
- package/src/sql/printer.ts +328 -0
- package/src/sql/query.ts +194 -0
- package/src/sql/util.ts +89 -0
- package/src/subscription.ts +46 -0
- package/src/test/fts.test.ts +1 -1
- package/src/test/limits.test.ts +163 -0
- package/src/test/setup.ts +16 -11
- package/src/test/subscription.test.ts +98 -0
- package/src/tools.ts +1 -1
- package/src/util/error-handling.ts +40 -0
- package/src/util/execute.ts +53 -0
- package/src/util/lazy-transaction.ts +49 -0
- package/src/util/limit.ts +34 -0
- package/src/util/resolve-tree.ts +65 -0
- package/src/{util.ts → util/util.ts} +9 -14
- package/dist/db.d.ts +0 -28
- package/dist/db.d.ts.map +0 -1
- package/dist/db.js +0 -69
- package/dist/db.js.map +0 -1
- package/dist/gql/opencrud.d.ts +0 -6
- package/dist/gql/opencrud.d.ts.map +0 -1
- package/dist/gql/opencrud.js +0 -326
- package/dist/gql/opencrud.js.map +0 -1
- package/dist/gql/scalars/BigInt.d.ts.map +0 -1
- package/dist/gql/scalars/BigInt.js.map +0 -1
- package/dist/gql/scalars/Bytes.d.ts.map +0 -1
- package/dist/gql/scalars/Bytes.js.map +0 -1
- package/dist/gql/scalars/DateTime.d.ts.map +0 -1
- package/dist/gql/scalars/DateTime.js.map +0 -1
- package/dist/gql/scalars/JSON.d.ts.map +0 -1
- package/dist/gql/scalars/JSON.js.map +0 -1
- package/dist/gql/scalars/index.d.ts.map +0 -1
- package/dist/gql/scalars/index.js.map +0 -1
- package/dist/gql/schema.d.ts.map +0 -1
- package/dist/gql/schema.js.map +0 -1
- package/dist/main.js +0 -44
- package/dist/main.js.map +0 -1
- package/dist/model.d.ts.map +0 -1
- package/dist/orderBy.d.ts.map +0 -1
- package/dist/orderBy.js.map +0 -1
- package/dist/queryBuilder.d.ts +0 -56
- package/dist/queryBuilder.d.ts.map +0 -1
- package/dist/queryBuilder.js +0 -733
- package/dist/queryBuilder.js.map +0 -1
- package/dist/relayConnection.d.ts +0 -37
- package/dist/relayConnection.d.ts.map +0 -1
- package/dist/relayConnection.js +0 -43
- package/dist/relayConnection.js.map +0 -1
- package/dist/requestedFields.d.ts +0 -33
- package/dist/requestedFields.d.ts.map +0 -1
- package/dist/requestedFields.js +0 -179
- package/dist/requestedFields.js.map +0 -1
- package/dist/resolver.d.ts +0 -9
- package/dist/resolver.d.ts.map +0 -1
- package/dist/resolver.js +0 -158
- package/dist/resolver.js.map +0 -1
- package/dist/server.d.ts +0 -22
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -96
- package/dist/server.js.map +0 -1
- package/dist/test/fts.test.js.map +0 -1
- package/dist/test/setup.d.ts +0 -14
- package/dist/test/setup.d.ts.map +0 -1
- package/dist/test/setup.js.map +0 -1
- package/dist/util.d.ts.map +0 -1
- package/dist/util.js.map +0 -1
- package/dist/where.d.ts +0 -9
- package/dist/where.d.ts.map +0 -1
- package/dist/where.js +0 -101
- package/dist/where.js.map +0 -1
- package/src/gql/opencrud.ts +0 -350
- package/src/queryBuilder.ts +0 -891
- package/src/relayConnection.ts +0 -80
- package/src/requestedFields.ts +0 -246
- package/src/resolver.ts +0 -201
- package/src/where.ts +0 -119
package/src/relayConnection.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import {UserInputError} from "apollo-server-core"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export interface PageInfo {
|
|
5
|
-
hasNextPage: boolean
|
|
6
|
-
hasPreviousPage: boolean
|
|
7
|
-
startCursor: string
|
|
8
|
-
endCursor: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export interface ConnectionEdge<T> {
|
|
13
|
-
node?: T
|
|
14
|
-
cursor?: string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
export interface ConnectionResponse<T> {
|
|
19
|
-
edges?: ConnectionEdge<T>[]
|
|
20
|
-
pageInfo?: PageInfo
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Offset value for SQL query
|
|
26
|
-
*/
|
|
27
|
-
export type Cursor = number
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export function encodeCursor(cursor: Cursor): string {
|
|
31
|
-
return ''+cursor
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
export function decodeCursor(value: string): Cursor {
|
|
36
|
-
let cursor = parseInt(value)
|
|
37
|
-
if (isFinite(cursor) && cursor >= 0) {
|
|
38
|
-
return cursor
|
|
39
|
-
} else {
|
|
40
|
-
throw new InvalidCursorValue(value)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
export class InvalidCursorValue extends UserInputError {
|
|
46
|
-
constructor(value: string) {
|
|
47
|
-
super(`invalid cursor value: ${value}`)
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
export interface ConnectionArgs {
|
|
53
|
-
first?: number
|
|
54
|
-
after?: string
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
export interface ConnectionParams {
|
|
59
|
-
offset: number
|
|
60
|
-
limit: number
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* https://relay.dev/assets/files/connections-932f4f2cdffd79724ac76373deb30dc8.htm#sec-Pagination-algorithm
|
|
66
|
-
*/
|
|
67
|
-
export function decodeConnectionArgs(args: ConnectionArgs): ConnectionParams {
|
|
68
|
-
let offset = 0
|
|
69
|
-
let limit = 100
|
|
70
|
-
if (args.after) {
|
|
71
|
-
offset = decodeCursor(args.after)
|
|
72
|
-
}
|
|
73
|
-
if (args.first != null) {
|
|
74
|
-
if (args.first < 0) {
|
|
75
|
-
throw new UserInputError("'first' argument of connection can't be less than 0")
|
|
76
|
-
}
|
|
77
|
-
limit = args.first
|
|
78
|
-
}
|
|
79
|
-
return {offset, limit}
|
|
80
|
-
}
|
package/src/requestedFields.ts
DELETED
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
import {toPlural} from "@subsquid/util-naming"
|
|
2
|
-
import {UserInputError} from "apollo-server-core"
|
|
3
|
-
import assert from "assert"
|
|
4
|
-
import {GraphQLResolveInfo, GraphQLSchema} from "graphql"
|
|
5
|
-
import {
|
|
6
|
-
FieldsByTypeName,
|
|
7
|
-
parseResolveInfo,
|
|
8
|
-
ResolveTree,
|
|
9
|
-
simplifyParsedResolveInfoFragmentWithType
|
|
10
|
-
} from "graphql-parse-resolve-info"
|
|
11
|
-
import {Model, PropType} from "./model"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export interface RequestedFields {
|
|
15
|
-
[name: string]: RequestedField
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export interface RequestedField {
|
|
20
|
-
propType: PropType
|
|
21
|
-
requests: FieldRequest[]
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
export interface FieldRequest {
|
|
26
|
-
alias: string
|
|
27
|
-
children?: RequestedFields
|
|
28
|
-
args?: any
|
|
29
|
-
ifType?: string
|
|
30
|
-
index: number
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export function requestedFields(model: Model, entityName: string, info: GraphQLResolveInfo): RequestedFields {
|
|
35
|
-
let tree = getResolveTree(info)
|
|
36
|
-
return collectRequestedFields(model, entityName, info.schema, tree)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
function collectRequestedFields(model: Model, objectName: string, schema: GraphQLSchema, tree: ResolveTree): RequestedFields {
|
|
41
|
-
let requested: RequestedFields = {}
|
|
42
|
-
let object = model[objectName]
|
|
43
|
-
assert(object.kind == 'entity' || object.kind == 'object')
|
|
44
|
-
|
|
45
|
-
let fields = simplifyResolveTree(schema, tree, objectName).fields
|
|
46
|
-
for (let alias in fields) {
|
|
47
|
-
let f = fields[alias]
|
|
48
|
-
let prop = object.properties[f.name]
|
|
49
|
-
let propType = prop.type
|
|
50
|
-
switch(propType.kind) {
|
|
51
|
-
case 'scalar':
|
|
52
|
-
case 'enum':
|
|
53
|
-
case 'list':
|
|
54
|
-
requested[f.name] = {
|
|
55
|
-
propType,
|
|
56
|
-
requests: [{alias: f.name, index: 0}]
|
|
57
|
-
}
|
|
58
|
-
break
|
|
59
|
-
case 'object':
|
|
60
|
-
addRequest(requested, f.name, propType, {
|
|
61
|
-
alias,
|
|
62
|
-
children: collectRequestedFields(model, propType.name, schema, f),
|
|
63
|
-
index: 0
|
|
64
|
-
})
|
|
65
|
-
break
|
|
66
|
-
case 'fk':
|
|
67
|
-
addRequest(requested, f.name, propType, {
|
|
68
|
-
alias,
|
|
69
|
-
children: collectRequestedFields(model, propType.foreignEntity, schema, f),
|
|
70
|
-
index: 0
|
|
71
|
-
})
|
|
72
|
-
break
|
|
73
|
-
case 'lookup':
|
|
74
|
-
addRequest(requested, f.name, propType, {
|
|
75
|
-
alias,
|
|
76
|
-
children: collectRequestedFields(model, propType.entity, schema, f),
|
|
77
|
-
index: 0
|
|
78
|
-
})
|
|
79
|
-
break
|
|
80
|
-
case 'list-lookup':
|
|
81
|
-
addRequest(requested, f.name, propType, {
|
|
82
|
-
alias,
|
|
83
|
-
args: f.args,
|
|
84
|
-
children: collectRequestedFields(model, propType.entity, schema, f),
|
|
85
|
-
index: 0
|
|
86
|
-
})
|
|
87
|
-
break
|
|
88
|
-
case 'union':{
|
|
89
|
-
let union = model[propType.name]
|
|
90
|
-
assert(union.kind == 'union')
|
|
91
|
-
let children: RequestedFields = {}
|
|
92
|
-
union.variants.forEach(name => {
|
|
93
|
-
let variantFields = collectRequestedFields(model, name, schema, f)
|
|
94
|
-
for (let key in variantFields) {
|
|
95
|
-
let field = variantFields[key]
|
|
96
|
-
field.requests.forEach(req => {
|
|
97
|
-
addRequest(children, key, field.propType, {...req, ifType: name})
|
|
98
|
-
})
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
addRequest(requested, f.name, propType, {
|
|
102
|
-
alias,
|
|
103
|
-
children,
|
|
104
|
-
index: 0
|
|
105
|
-
})
|
|
106
|
-
break
|
|
107
|
-
}
|
|
108
|
-
default:
|
|
109
|
-
throw new Error(`Field ${objectName}.${f.name} has unsupported type and can't be requested`)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return requested
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
function addRequest(requested: RequestedFields, name: string, propType: PropType, req: FieldRequest): void {
|
|
118
|
-
let field = requested[name]
|
|
119
|
-
if (field == null) {
|
|
120
|
-
requested[name] = {
|
|
121
|
-
propType,
|
|
122
|
-
requests: [req]
|
|
123
|
-
}
|
|
124
|
-
} else {
|
|
125
|
-
field.requests.push(req)
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
export interface ConnectionRequestedFields {
|
|
131
|
-
totalCount?: boolean
|
|
132
|
-
pageInfo?: boolean
|
|
133
|
-
edges?: {
|
|
134
|
-
node?: RequestedFields
|
|
135
|
-
cursor?: boolean
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
export function connectionRequestedFields(model: Model, entityName: string, info: GraphQLResolveInfo): ConnectionRequestedFields {
|
|
141
|
-
let requested: ConnectionRequestedFields = {}
|
|
142
|
-
let tree = getResolveTree(info, toPlural(entityName) + 'Connection')
|
|
143
|
-
requested.totalCount = hasTreeRequest(tree.fields, 'totalCount')
|
|
144
|
-
requested.pageInfo = hasTreeRequest(tree.fields, 'pageInfo')
|
|
145
|
-
let edgesTree = getTreeRequest(tree.fields, 'edges')
|
|
146
|
-
if (edgesTree) {
|
|
147
|
-
let edgeFields = simplifyResolveTree(info.schema, edgesTree, entityName + 'Edge').fields
|
|
148
|
-
requested.edges = {}
|
|
149
|
-
requested.edges.cursor = hasTreeRequest(edgeFields, 'cursor')
|
|
150
|
-
let nodeTree = getTreeRequest(edgeFields, 'node')
|
|
151
|
-
if (nodeTree) {
|
|
152
|
-
requested.edges.node = collectRequestedFields(model, entityName, info.schema, nodeTree)
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return requested
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
export interface FtsRequestedFields {
|
|
160
|
-
item?: Record<string, RequestedFields>
|
|
161
|
-
highlight?: boolean
|
|
162
|
-
rank?: boolean
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
export function ftsRequestedFields(model: Model, queryName: string, info: GraphQLResolveInfo): FtsRequestedFields {
|
|
167
|
-
let query = model[queryName]
|
|
168
|
-
assert(query.kind == 'fts')
|
|
169
|
-
|
|
170
|
-
let requested: FtsRequestedFields = {}
|
|
171
|
-
let tree = getResolveTree(info, queryName + '_Output')
|
|
172
|
-
|
|
173
|
-
requested.rank = hasTreeRequest(tree.fields, 'rank')
|
|
174
|
-
requested.highlight = hasTreeRequest(tree.fields, 'highlight')
|
|
175
|
-
|
|
176
|
-
let itemTree = getTreeRequest(tree.fields, 'item')
|
|
177
|
-
if (itemTree) {
|
|
178
|
-
requested.item = {}
|
|
179
|
-
for (let i = 0; i < query.sources.length; i++) {
|
|
180
|
-
let entity = query.sources[i].entity
|
|
181
|
-
let fields = collectRequestedFields(model, entity, info.schema, itemTree)
|
|
182
|
-
for (let key in fields) {
|
|
183
|
-
requested.item[entity] = fields
|
|
184
|
-
break
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return requested
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
function getTreeRequest(treeFields: ResolveTreeFields, fieldName: string): ResolveTree | undefined {
|
|
194
|
-
let req: ResolveTree | undefined
|
|
195
|
-
for (let alias in treeFields) {
|
|
196
|
-
let e = treeFields[alias]
|
|
197
|
-
if (e.name != fieldName) continue
|
|
198
|
-
if (req != null) throw new UserInputError(`multiple aliases for field '${fieldName}' are not supported`)
|
|
199
|
-
req = e
|
|
200
|
-
}
|
|
201
|
-
return req
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
function hasTreeRequest(treeFields: ResolveTreeFields, fieldName: string): boolean {
|
|
206
|
-
for (let alias in treeFields) {
|
|
207
|
-
let e = treeFields[alias]
|
|
208
|
-
if (e.name == fieldName) return true
|
|
209
|
-
}
|
|
210
|
-
return false
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
type ResolveTreeFields = {
|
|
215
|
-
[alias: string]: ResolveTree
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
interface ResolveTreeWithFields extends ResolveTree {
|
|
220
|
-
fields: ResolveTreeFields
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
function getResolveTree(info: GraphQLResolveInfo): ResolveTree
|
|
225
|
-
function getResolveTree(info: GraphQLResolveInfo, typeName: string): ResolveTreeWithFields
|
|
226
|
-
function getResolveTree(info: GraphQLResolveInfo, typeName?: string): ResolveTree {
|
|
227
|
-
let tree = parseResolveInfo(info)
|
|
228
|
-
assert(isResolveTree(tree))
|
|
229
|
-
if (typeName) {
|
|
230
|
-
return simplifyResolveTree(info.schema, tree, typeName)
|
|
231
|
-
} else {
|
|
232
|
-
return tree
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
function simplifyResolveTree(schema: GraphQLSchema, tree: ResolveTree, typeName: string): ResolveTreeWithFields {
|
|
238
|
-
let type = schema.getType(typeName)
|
|
239
|
-
assert(type != null)
|
|
240
|
-
return simplifyParsedResolveInfoFragmentWithType(tree, type)
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
function isResolveTree(resolveInfo: ResolveTree | FieldsByTypeName | null | undefined): resolveInfo is ResolveTree {
|
|
245
|
-
return resolveInfo != null && resolveInfo.fieldsByTypeName != null
|
|
246
|
-
}
|
package/src/resolver.ts
DELETED
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import type {IFieldResolver, IResolvers} from "@graphql-tools/utils"
|
|
2
|
-
import {toCamelCase} from "@subsquid/util-naming"
|
|
3
|
-
import {UserInputError} from "apollo-server-core"
|
|
4
|
-
import assert from "assert"
|
|
5
|
-
import type {GraphQLResolveInfo} from "graphql"
|
|
6
|
-
import type {Database, Transaction} from "./db"
|
|
7
|
-
import type {Dialect} from "./dialect"
|
|
8
|
-
import {customScalars} from "./gql/scalars"
|
|
9
|
-
import type {Entity, JsonObject, Model} from "./model"
|
|
10
|
-
import {QueryBuilder} from "./queryBuilder"
|
|
11
|
-
import {
|
|
12
|
-
ConnectionArgs as RelayConnectionArgs,
|
|
13
|
-
ConnectionEdge,
|
|
14
|
-
ConnectionResponse as RelayConnectionResponse,
|
|
15
|
-
decodeConnectionArgs,
|
|
16
|
-
encodeCursor,
|
|
17
|
-
PageInfo
|
|
18
|
-
} from "./relayConnection"
|
|
19
|
-
import {connectionRequestedFields, ftsRequestedFields, requestedFields} from "./requestedFields"
|
|
20
|
-
import {ensureArray, toQueryListField, unsupportedCase} from "./util"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export interface ResolverContext {
|
|
24
|
-
openReaderTransaction: Transaction
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export function buildResolvers(model: Model, dialect: Dialect): IResolvers<unknown, ResolverContext> {
|
|
29
|
-
let Query: Record<string, IFieldResolver<unknown, ResolverContext>> = {}
|
|
30
|
-
let resolvers: IResolvers = {Query, ...customScalars}
|
|
31
|
-
|
|
32
|
-
for (let name in model) {
|
|
33
|
-
let item = model[name]
|
|
34
|
-
switch(item.kind) {
|
|
35
|
-
case 'entity':
|
|
36
|
-
Query[toQueryListField(name)] = async (source, args, context, info) => {
|
|
37
|
-
let fields = requestedFields(model, name, info)
|
|
38
|
-
let db = await context.openReaderTransaction.get()
|
|
39
|
-
return new QueryBuilder(model, dialect, db).executeSelect(name, args, fields)
|
|
40
|
-
}
|
|
41
|
-
Query[toQueryListField(name) + 'Connection'] = async (source, args, context, info) => {
|
|
42
|
-
let db = await context.openReaderTransaction.get()
|
|
43
|
-
return resolveEntityConnection(model, dialect, name, args, info, db)
|
|
44
|
-
}
|
|
45
|
-
Query[`${toCamelCase(name)}ById`] = async (source, args, context, info) => {
|
|
46
|
-
let fields = requestedFields(model, name, info)
|
|
47
|
-
let db = await context.openReaderTransaction.get()
|
|
48
|
-
let result = await new QueryBuilder(model, dialect, db)
|
|
49
|
-
.executeSelect(name, {where: {id_eq: args.id}}, fields)
|
|
50
|
-
assert(result.length < 2)
|
|
51
|
-
return result[0]
|
|
52
|
-
}
|
|
53
|
-
Query[`${toCamelCase(name)}ByUniqueInput`] = async (source, args, context, info) => {
|
|
54
|
-
let fields = requestedFields(model, name, info)
|
|
55
|
-
let db = await context.openReaderTransaction.get()
|
|
56
|
-
let result = await new QueryBuilder(model, dialect, db)
|
|
57
|
-
.executeSelect(name, {where: {id_eq: args.where.id}}, fields)
|
|
58
|
-
assert(result.length < 2)
|
|
59
|
-
return result[0]
|
|
60
|
-
}
|
|
61
|
-
installFieldResolvers(name, item)
|
|
62
|
-
break
|
|
63
|
-
case 'object':
|
|
64
|
-
installFieldResolvers(name, item)
|
|
65
|
-
break
|
|
66
|
-
case 'union':
|
|
67
|
-
resolvers[name] = {
|
|
68
|
-
__resolveType: resolveUnionType
|
|
69
|
-
}
|
|
70
|
-
break
|
|
71
|
-
case 'fts':
|
|
72
|
-
Query[name] = async (source, args, context, info) => {
|
|
73
|
-
let fields = ftsRequestedFields(model, name, info)
|
|
74
|
-
let db = await context.openReaderTransaction.get()
|
|
75
|
-
return new QueryBuilder(model, dialect, db).executeFulltextSearch(name, args, fields)
|
|
76
|
-
}
|
|
77
|
-
resolvers[`${name}_Item`] = {
|
|
78
|
-
__resolveType: resolveUnionType
|
|
79
|
-
}
|
|
80
|
-
break
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function installFieldResolvers(name: string, object: Entity | JsonObject): void {
|
|
85
|
-
let fields: Record<string, IFieldResolver<any, any>> = {}
|
|
86
|
-
for (let key in object.properties) {
|
|
87
|
-
let kind = object.properties[key].type.kind
|
|
88
|
-
switch(kind) {
|
|
89
|
-
case 'object':
|
|
90
|
-
case 'union':
|
|
91
|
-
case 'fk':
|
|
92
|
-
case 'lookup':
|
|
93
|
-
case 'list-lookup':
|
|
94
|
-
fields[key] = aliasResolver
|
|
95
|
-
break
|
|
96
|
-
case 'scalar':
|
|
97
|
-
case 'enum':
|
|
98
|
-
case 'list':
|
|
99
|
-
break
|
|
100
|
-
default:
|
|
101
|
-
throw unsupportedCase(kind)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
resolvers[name] = fields
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return resolvers
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
function resolveUnionType(source: any): string {
|
|
112
|
-
return source.isTypeOf
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
function aliasResolver(source: any, args: unknown, ctx: unknown, info: GraphQLResolveInfo): any {
|
|
117
|
-
return source[info.path.key]
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
interface ConnectionArgs extends RelayConnectionArgs {
|
|
122
|
-
orderBy?: string[]
|
|
123
|
-
where?: any
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
interface ConnectionResponse extends RelayConnectionResponse<any> {
|
|
128
|
-
totalCount?: number
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
async function resolveEntityConnection(
|
|
133
|
-
model: Model,
|
|
134
|
-
dialect: Dialect,
|
|
135
|
-
entityName: string,
|
|
136
|
-
args: ConnectionArgs,
|
|
137
|
-
info: GraphQLResolveInfo,
|
|
138
|
-
db: Database
|
|
139
|
-
): Promise<ConnectionResponse> {
|
|
140
|
-
let response: ConnectionResponse = {}
|
|
141
|
-
|
|
142
|
-
let orderBy = args.orderBy && ensureArray(args.orderBy)
|
|
143
|
-
if (!orderBy?.length) {
|
|
144
|
-
throw new UserInputError('orderBy argument is required for connection')
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
let {offset, limit} = decodeConnectionArgs(args)
|
|
148
|
-
let listArgs = {
|
|
149
|
-
where: args.where,
|
|
150
|
-
orderBy,
|
|
151
|
-
offset,
|
|
152
|
-
limit: limit + 1
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// https://relay.dev/assets/files/connections-932f4f2cdffd79724ac76373deb30dc8.htm#sec-undefined.PageInfo.Fields
|
|
156
|
-
function pageInfo(listLength: number): PageInfo {
|
|
157
|
-
return {
|
|
158
|
-
hasNextPage: listLength > limit,
|
|
159
|
-
hasPreviousPage: listLength > 0 && offset > 0,
|
|
160
|
-
startCursor: listLength > 0 ? encodeCursor(offset + 1) : '',
|
|
161
|
-
endCursor: listLength > 0 ? encodeCursor(offset + Math.min(limit, listLength)) : ''
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
let fields = connectionRequestedFields(model, entityName, info)
|
|
166
|
-
if (fields.edges?.node) {
|
|
167
|
-
let nodes = await new QueryBuilder(model, dialect, db).executeSelect(entityName, listArgs, fields.edges.node)
|
|
168
|
-
let edges: ConnectionEdge<any>[] = new Array(Math.min(limit, nodes.length))
|
|
169
|
-
for (let i = 0; i < edges.length; i++) {
|
|
170
|
-
edges[i] = {
|
|
171
|
-
node: nodes[i],
|
|
172
|
-
cursor: encodeCursor(offset + i + 1)
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
response.edges = edges
|
|
176
|
-
response.pageInfo = pageInfo(nodes.length)
|
|
177
|
-
if (nodes.length > 0 && nodes.length <= limit) {
|
|
178
|
-
response.totalCount = offset + nodes.length
|
|
179
|
-
}
|
|
180
|
-
} else if (fields.edges?.cursor || fields.pageInfo) {
|
|
181
|
-
let listLength = await new QueryBuilder(model, dialect, db).executeListCount(entityName, listArgs)
|
|
182
|
-
response.pageInfo = pageInfo(listLength)
|
|
183
|
-
if (fields.edges?.cursor) {
|
|
184
|
-
response.edges = []
|
|
185
|
-
for (let i = 0; i < Math.min(limit, listLength); i++) {
|
|
186
|
-
response.edges.push({
|
|
187
|
-
cursor: encodeCursor(offset + i + 1)
|
|
188
|
-
})
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
if (listLength > 0 && listLength <= limit) {
|
|
192
|
-
response.totalCount = offset + listLength
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (fields.totalCount && response.totalCount == null) {
|
|
197
|
-
response.totalCount = await new QueryBuilder(model, dialect, db).executeSelectCount(entityName, listArgs.where)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return response
|
|
201
|
-
}
|
package/src/where.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
export type WhereOp =
|
|
3
|
-
'-' | // no operator
|
|
4
|
-
'isNull' |
|
|
5
|
-
'eq' | 'not_eq' |
|
|
6
|
-
'gt' |
|
|
7
|
-
'gte' |
|
|
8
|
-
'lt' |
|
|
9
|
-
'lte' |
|
|
10
|
-
'in' | 'not_in' |
|
|
11
|
-
'contains' | 'not_contains' |
|
|
12
|
-
'containsInsensitive' | 'not_containsInsensitive' |
|
|
13
|
-
'startsWith' | 'not_startsWith' |
|
|
14
|
-
'endsWith' | 'not_endsWith' |
|
|
15
|
-
'containsAll' |
|
|
16
|
-
'containsAny' |
|
|
17
|
-
'containsNone' |
|
|
18
|
-
'some' |
|
|
19
|
-
'every' |
|
|
20
|
-
'none' |
|
|
21
|
-
'jsonContains' |
|
|
22
|
-
'jsonHasKey'
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const ENDINGS = [
|
|
26
|
-
'isNull',
|
|
27
|
-
'eq',
|
|
28
|
-
'not_eq',
|
|
29
|
-
'gt',
|
|
30
|
-
'gte',
|
|
31
|
-
'lt',
|
|
32
|
-
'lte',
|
|
33
|
-
'in',
|
|
34
|
-
'not_in',
|
|
35
|
-
'contains',
|
|
36
|
-
'not_contains',
|
|
37
|
-
'containsInsensitive',
|
|
38
|
-
'not_containsInsensitive',
|
|
39
|
-
'startsWith',
|
|
40
|
-
'not_startsWith',
|
|
41
|
-
'endsWith',
|
|
42
|
-
'not_endsWith',
|
|
43
|
-
'containsAll',
|
|
44
|
-
'containsAny',
|
|
45
|
-
'containsNone',
|
|
46
|
-
'some',
|
|
47
|
-
'every',
|
|
48
|
-
'none',
|
|
49
|
-
'jsonContains',
|
|
50
|
-
'jsonHasKey',
|
|
51
|
-
].sort((a, b) => b.length - a.length).map(e => '_' + e)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
function parseEnding(field: string): string {
|
|
55
|
-
for (let i = 0; i < ENDINGS.length; i++) {
|
|
56
|
-
if (field.endsWith(ENDINGS[i])) return ENDINGS[i].slice(1)
|
|
57
|
-
}
|
|
58
|
-
return ''
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
export function parseWhereField(field: string): {op: WhereOp, field: string} {
|
|
63
|
-
let ending = parseEnding(field)
|
|
64
|
-
if (!ending) return {op: '-', field}
|
|
65
|
-
let fieldName = field.slice(0, -(ending.length + 1))
|
|
66
|
-
return {
|
|
67
|
-
op: ending as WhereOp,
|
|
68
|
-
field: fieldName
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
export function hasConditions(where?: any): where is any {
|
|
74
|
-
if (where == null) return false
|
|
75
|
-
for (let key in where) {
|
|
76
|
-
switch(key) {
|
|
77
|
-
case 'AND':
|
|
78
|
-
case 'OR':
|
|
79
|
-
break
|
|
80
|
-
default:
|
|
81
|
-
return true
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
if (Array.isArray(where.AND)) {
|
|
85
|
-
if (where.AND.some(hasConditions)) return true
|
|
86
|
-
} else if (where.AND && hasConditions(where.AND)) {
|
|
87
|
-
return true
|
|
88
|
-
}
|
|
89
|
-
if (Array.isArray(where.OR)) {
|
|
90
|
-
if (where.OR.some(hasConditions)) return true
|
|
91
|
-
} else if (where.OR && hasConditions(where.OR)) {
|
|
92
|
-
return true
|
|
93
|
-
}
|
|
94
|
-
return false
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
export function whereOpToSqlOperator(op: WhereOp): string {
|
|
99
|
-
switch(op) {
|
|
100
|
-
case 'eq':
|
|
101
|
-
return '='
|
|
102
|
-
case 'not_eq':
|
|
103
|
-
return '!='
|
|
104
|
-
case 'gt':
|
|
105
|
-
return '>'
|
|
106
|
-
case 'gte':
|
|
107
|
-
return '>='
|
|
108
|
-
case 'lt':
|
|
109
|
-
return '<'
|
|
110
|
-
case 'lte':
|
|
111
|
-
return '<='
|
|
112
|
-
case 'in':
|
|
113
|
-
return 'IN'
|
|
114
|
-
case 'not_in':
|
|
115
|
-
return 'NOT IN'
|
|
116
|
-
default:
|
|
117
|
-
throw new Error(`Operator ${op} doesn't have SQL analog`)
|
|
118
|
-
}
|
|
119
|
-
}
|