@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.
Files changed (295) hide show
  1. package/bin/main.js +1 -1
  2. package/lib/context.d.ts +14 -0
  3. package/lib/context.d.ts.map +1 -0
  4. package/lib/context.js +3 -0
  5. package/lib/context.js.map +1 -0
  6. package/lib/db.d.ts +23 -0
  7. package/lib/db.d.ts.map +1 -0
  8. package/lib/db.js +57 -0
  9. package/lib/db.js.map +1 -0
  10. package/{dist → lib}/dialect.d.ts +0 -0
  11. package/{dist → lib}/dialect.d.ts.map +0 -0
  12. package/{dist → lib}/dialect.js +0 -0
  13. package/{dist → lib}/dialect.js.map +0 -0
  14. package/lib/ir/args.d.ts +47 -0
  15. package/lib/ir/args.d.ts.map +1 -0
  16. package/lib/ir/args.js +3 -0
  17. package/lib/ir/args.js.map +1 -0
  18. package/lib/ir/connection.d.ts +30 -0
  19. package/lib/ir/connection.d.ts.map +1 -0
  20. package/lib/ir/connection.js +17 -0
  21. package/lib/ir/connection.js.map +1 -0
  22. package/lib/ir/fields.d.ts +22 -0
  23. package/lib/ir/fields.d.ts.map +1 -0
  24. package/lib/ir/fields.js +3 -0
  25. package/lib/ir/fields.js.map +1 -0
  26. package/lib/limit.size.d.ts +8 -0
  27. package/lib/limit.size.d.ts.map +1 -0
  28. package/lib/limit.size.js +107 -0
  29. package/lib/limit.size.js.map +1 -0
  30. package/{dist → lib}/main.d.ts +0 -0
  31. package/{dist → lib}/main.d.ts.map +0 -0
  32. package/lib/main.js +59 -0
  33. package/lib/main.js.map +1 -0
  34. package/{dist → lib}/model.d.ts +11 -1
  35. package/lib/model.d.ts.map +1 -0
  36. package/{dist → lib}/model.js +0 -0
  37. package/{dist → lib}/model.js.map +0 -0
  38. package/{dist/gql/schema.d.ts → lib/model.schema.d.ts} +2 -2
  39. package/lib/model.schema.d.ts.map +1 -0
  40. package/{dist/gql/schema.js → lib/model.schema.js} +62 -8
  41. package/lib/model.schema.js.map +1 -0
  42. package/{dist → lib}/model.tools.d.ts +0 -0
  43. package/{dist → lib}/model.tools.d.ts.map +0 -0
  44. package/{dist → lib}/model.tools.js +0 -0
  45. package/{dist → lib}/model.tools.js.map +0 -0
  46. package/{dist → lib/opencrud}/orderBy.d.ts +2 -5
  47. package/lib/opencrud/orderBy.d.ts.map +1 -0
  48. package/{dist → lib/opencrud}/orderBy.js +1 -1
  49. package/lib/opencrud/orderBy.js.map +1 -0
  50. package/lib/opencrud/schema.d.ts +31 -0
  51. package/lib/opencrud/schema.d.ts.map +1 -0
  52. package/lib/opencrud/schema.js +527 -0
  53. package/lib/opencrud/schema.js.map +1 -0
  54. package/lib/opencrud/tree.d.ts +8 -0
  55. package/lib/opencrud/tree.d.ts.map +1 -0
  56. package/lib/opencrud/tree.js +131 -0
  57. package/lib/opencrud/tree.js.map +1 -0
  58. package/lib/opencrud/where.d.ts +7 -0
  59. package/lib/opencrud/where.d.ts.map +1 -0
  60. package/lib/opencrud/where.js +141 -0
  61. package/lib/opencrud/where.js.map +1 -0
  62. package/{dist/gql → lib}/scalars/BigInt.d.ts +0 -0
  63. package/lib/scalars/BigInt.d.ts.map +1 -0
  64. package/{dist/gql → lib}/scalars/BigInt.js +1 -1
  65. package/lib/scalars/BigInt.js.map +1 -0
  66. package/{dist/gql → lib}/scalars/Bytes.d.ts +0 -0
  67. package/lib/scalars/Bytes.d.ts.map +1 -0
  68. package/{dist/gql → lib}/scalars/Bytes.js +2 -2
  69. package/lib/scalars/Bytes.js.map +1 -0
  70. package/{dist/gql → lib}/scalars/DateTime.d.ts +0 -0
  71. package/lib/scalars/DateTime.d.ts.map +1 -0
  72. package/{dist/gql → lib}/scalars/DateTime.js +1 -1
  73. package/lib/scalars/DateTime.js.map +1 -0
  74. package/{dist/gql → lib}/scalars/JSON.d.ts +0 -0
  75. package/lib/scalars/JSON.d.ts.map +1 -0
  76. package/{dist/gql → lib}/scalars/JSON.js +0 -0
  77. package/lib/scalars/JSON.js.map +1 -0
  78. package/{dist/gql → lib}/scalars/index.d.ts +0 -0
  79. package/lib/scalars/index.d.ts.map +1 -0
  80. package/{dist/gql → lib}/scalars/index.js +0 -0
  81. package/lib/scalars/index.js.map +1 -0
  82. package/lib/server.d.ts +42 -0
  83. package/lib/server.d.ts.map +1 -0
  84. package/lib/server.js +171 -0
  85. package/lib/server.js.map +1 -0
  86. package/lib/sql/cursor.d.ts +52 -0
  87. package/lib/sql/cursor.d.ts.map +1 -0
  88. package/lib/sql/cursor.js +234 -0
  89. package/lib/sql/cursor.js.map +1 -0
  90. package/lib/sql/mapping.d.ts +4 -0
  91. package/lib/sql/mapping.d.ts.map +1 -0
  92. package/lib/sql/mapping.js +71 -0
  93. package/lib/sql/mapping.js.map +1 -0
  94. package/lib/sql/printer.d.ts +37 -0
  95. package/lib/sql/printer.d.ts.map +1 -0
  96. package/lib/sql/printer.js +311 -0
  97. package/lib/sql/printer.js.map +1 -0
  98. package/lib/sql/query.d.ts +46 -0
  99. package/lib/sql/query.d.ts.map +1 -0
  100. package/lib/sql/query.js +134 -0
  101. package/lib/sql/query.js.map +1 -0
  102. package/lib/sql/util.d.ts +30 -0
  103. package/lib/sql/util.d.ts.map +1 -0
  104. package/lib/sql/util.js +75 -0
  105. package/lib/sql/util.js.map +1 -0
  106. package/lib/subscription.d.ts +18 -0
  107. package/lib/subscription.d.ts.map +1 -0
  108. package/lib/subscription.js +47 -0
  109. package/lib/subscription.js.map +1 -0
  110. package/{dist → lib}/test/basic.test.d.ts +0 -0
  111. package/{dist → lib}/test/basic.test.d.ts.map +0 -0
  112. package/{dist → lib}/test/basic.test.js +0 -0
  113. package/{dist → lib}/test/basic.test.js.map +0 -0
  114. package/{dist → lib}/test/connection.test.d.ts +0 -0
  115. package/{dist → lib}/test/connection.test.d.ts.map +0 -0
  116. package/{dist → lib}/test/connection.test.js +0 -0
  117. package/{dist → lib}/test/connection.test.js.map +0 -0
  118. package/{dist → lib}/test/fts.test.d.ts +0 -0
  119. package/{dist → lib}/test/fts.test.d.ts.map +0 -0
  120. package/{dist → lib}/test/fts.test.js +1 -1
  121. package/lib/test/fts.test.js.map +1 -0
  122. package/{dist → lib}/test/isNull.test.d.ts +0 -0
  123. package/{dist → lib}/test/isNull.test.d.ts.map +0 -0
  124. package/{dist → lib}/test/isNull.test.js +0 -0
  125. package/{dist → lib}/test/isNull.test.js.map +0 -0
  126. package/lib/test/limits.test.d.ts +2 -0
  127. package/lib/test/limits.test.d.ts.map +1 -0
  128. package/lib/test/limits.test.js +159 -0
  129. package/lib/test/limits.test.js.map +1 -0
  130. package/{dist → lib}/test/lists.test.d.ts +0 -0
  131. package/{dist → lib}/test/lists.test.d.ts.map +0 -0
  132. package/{dist → lib}/test/lists.test.js +0 -0
  133. package/{dist → lib}/test/lists.test.js.map +0 -0
  134. package/{dist → lib}/test/lookup.test.d.ts +0 -0
  135. package/{dist → lib}/test/lookup.test.d.ts.map +0 -0
  136. package/{dist → lib}/test/lookup.test.js +0 -0
  137. package/{dist → lib}/test/lookup.test.js.map +0 -0
  138. package/{dist → lib}/test/regressions.test.d.ts +0 -0
  139. package/{dist → lib}/test/regressions.test.d.ts.map +0 -0
  140. package/{dist → lib}/test/regressions.test.js +0 -0
  141. package/{dist → lib}/test/regressions.test.js.map +0 -0
  142. package/{dist → lib}/test/scalars.test.d.ts +0 -0
  143. package/{dist → lib}/test/scalars.test.d.ts.map +0 -0
  144. package/{dist → lib}/test/scalars.test.js +0 -0
  145. package/{dist → lib}/test/scalars.test.js.map +0 -0
  146. package/lib/test/setup.d.ts +17 -0
  147. package/lib/test/setup.d.ts.map +1 -0
  148. package/{dist → lib}/test/setup.js +18 -13
  149. package/lib/test/setup.js.map +1 -0
  150. package/lib/test/subscription.test.d.ts +2 -0
  151. package/lib/test/subscription.test.d.ts.map +1 -0
  152. package/lib/test/subscription.test.js +99 -0
  153. package/lib/test/subscription.test.js.map +1 -0
  154. package/{dist → lib}/test/tools.test.d.ts +0 -0
  155. package/{dist → lib}/test/tools.test.d.ts.map +0 -0
  156. package/{dist → lib}/test/tools.test.js +0 -0
  157. package/{dist → lib}/test/tools.test.js.map +0 -0
  158. package/{dist → lib}/test/typed-json.test.d.ts +0 -0
  159. package/{dist → lib}/test/typed-json.test.d.ts.map +0 -0
  160. package/{dist → lib}/test/typed-json.test.js +0 -0
  161. package/{dist → lib}/test/typed-json.test.js.map +0 -0
  162. package/{dist → lib}/test/unions.test.d.ts +0 -0
  163. package/{dist → lib}/test/unions.test.d.ts.map +0 -0
  164. package/{dist → lib}/test/unions.test.js +0 -0
  165. package/{dist → lib}/test/unions.test.js.map +0 -0
  166. package/{dist → lib}/test/where.test.d.ts +0 -0
  167. package/{dist → lib}/test/where.test.d.ts.map +0 -0
  168. package/{dist → lib}/test/where.test.js +0 -0
  169. package/{dist → lib}/test/where.test.js.map +0 -0
  170. package/{dist → lib}/tools.d.ts +0 -0
  171. package/{dist → lib}/tools.d.ts.map +0 -0
  172. package/{dist → lib}/tools.js +3 -3
  173. package/{dist → lib}/tools.js.map +1 -1
  174. package/lib/util/error-handling.d.ts +11 -0
  175. package/lib/util/error-handling.d.ts.map +1 -0
  176. package/lib/util/error-handling.js +42 -0
  177. package/lib/util/error-handling.js.map +1 -0
  178. package/lib/util/execute.d.ts +5 -0
  179. package/lib/util/execute.d.ts.map +1 -0
  180. package/lib/util/execute.js +28 -0
  181. package/lib/util/execute.js.map +1 -0
  182. package/lib/util/lazy-transaction.d.ts +10 -0
  183. package/lib/util/lazy-transaction.d.ts.map +1 -0
  184. package/lib/util/lazy-transaction.js +43 -0
  185. package/lib/util/lazy-transaction.js.map +1 -0
  186. package/lib/util/limit.d.ts +11 -0
  187. package/lib/util/limit.d.ts.map +1 -0
  188. package/lib/util/limit.js +39 -0
  189. package/lib/util/limit.js.map +1 -0
  190. package/lib/util/resolve-tree.d.ts +14 -0
  191. package/lib/util/resolve-tree.d.ts.map +1 -0
  192. package/lib/util/resolve-tree.js +52 -0
  193. package/lib/util/resolve-tree.js.map +1 -0
  194. package/{dist → lib/util}/util.d.ts +2 -3
  195. package/lib/util/util.d.ts.map +1 -0
  196. package/{dist → lib/util}/util.js +9 -13
  197. package/lib/util/util.js.map +1 -0
  198. package/package.json +18 -10
  199. package/src/context.ts +17 -0
  200. package/src/db.ts +46 -57
  201. package/src/ir/args.ts +85 -0
  202. package/src/ir/connection.ts +48 -0
  203. package/src/ir/fields.ts +40 -0
  204. package/src/limit.size.ts +130 -0
  205. package/src/main.ts +74 -42
  206. package/src/{gql/schema.ts → model.schema.ts} +72 -9
  207. package/src/model.ts +13 -1
  208. package/src/{orderBy.ts → opencrud/orderBy.ts} +3 -10
  209. package/src/opencrud/schema.ts +639 -0
  210. package/src/opencrud/tree.ts +144 -0
  211. package/src/opencrud/where.ts +141 -0
  212. package/src/{gql/scalars → scalars}/BigInt.ts +1 -1
  213. package/src/{gql/scalars → scalars}/Bytes.ts +4 -4
  214. package/src/{gql/scalars → scalars}/DateTime.ts +1 -1
  215. package/src/{gql/scalars → scalars}/JSON.ts +0 -0
  216. package/src/{gql/scalars → scalars}/index.ts +0 -0
  217. package/src/server.ts +175 -55
  218. package/src/sql/cursor.ts +291 -0
  219. package/src/sql/mapping.ts +66 -0
  220. package/src/sql/printer.ts +328 -0
  221. package/src/sql/query.ts +194 -0
  222. package/src/sql/util.ts +89 -0
  223. package/src/subscription.ts +46 -0
  224. package/src/test/fts.test.ts +1 -1
  225. package/src/test/limits.test.ts +163 -0
  226. package/src/test/setup.ts +16 -11
  227. package/src/test/subscription.test.ts +98 -0
  228. package/src/tools.ts +1 -1
  229. package/src/util/error-handling.ts +40 -0
  230. package/src/util/execute.ts +53 -0
  231. package/src/util/lazy-transaction.ts +49 -0
  232. package/src/util/limit.ts +34 -0
  233. package/src/util/resolve-tree.ts +65 -0
  234. package/src/{util.ts → util/util.ts} +9 -14
  235. package/dist/db.d.ts +0 -28
  236. package/dist/db.d.ts.map +0 -1
  237. package/dist/db.js +0 -69
  238. package/dist/db.js.map +0 -1
  239. package/dist/gql/opencrud.d.ts +0 -6
  240. package/dist/gql/opencrud.d.ts.map +0 -1
  241. package/dist/gql/opencrud.js +0 -326
  242. package/dist/gql/opencrud.js.map +0 -1
  243. package/dist/gql/scalars/BigInt.d.ts.map +0 -1
  244. package/dist/gql/scalars/BigInt.js.map +0 -1
  245. package/dist/gql/scalars/Bytes.d.ts.map +0 -1
  246. package/dist/gql/scalars/Bytes.js.map +0 -1
  247. package/dist/gql/scalars/DateTime.d.ts.map +0 -1
  248. package/dist/gql/scalars/DateTime.js.map +0 -1
  249. package/dist/gql/scalars/JSON.d.ts.map +0 -1
  250. package/dist/gql/scalars/JSON.js.map +0 -1
  251. package/dist/gql/scalars/index.d.ts.map +0 -1
  252. package/dist/gql/scalars/index.js.map +0 -1
  253. package/dist/gql/schema.d.ts.map +0 -1
  254. package/dist/gql/schema.js.map +0 -1
  255. package/dist/main.js +0 -44
  256. package/dist/main.js.map +0 -1
  257. package/dist/model.d.ts.map +0 -1
  258. package/dist/orderBy.d.ts.map +0 -1
  259. package/dist/orderBy.js.map +0 -1
  260. package/dist/queryBuilder.d.ts +0 -56
  261. package/dist/queryBuilder.d.ts.map +0 -1
  262. package/dist/queryBuilder.js +0 -733
  263. package/dist/queryBuilder.js.map +0 -1
  264. package/dist/relayConnection.d.ts +0 -37
  265. package/dist/relayConnection.d.ts.map +0 -1
  266. package/dist/relayConnection.js +0 -43
  267. package/dist/relayConnection.js.map +0 -1
  268. package/dist/requestedFields.d.ts +0 -33
  269. package/dist/requestedFields.d.ts.map +0 -1
  270. package/dist/requestedFields.js +0 -179
  271. package/dist/requestedFields.js.map +0 -1
  272. package/dist/resolver.d.ts +0 -9
  273. package/dist/resolver.d.ts.map +0 -1
  274. package/dist/resolver.js +0 -158
  275. package/dist/resolver.js.map +0 -1
  276. package/dist/server.d.ts +0 -22
  277. package/dist/server.d.ts.map +0 -1
  278. package/dist/server.js +0 -96
  279. package/dist/server.js.map +0 -1
  280. package/dist/test/fts.test.js.map +0 -1
  281. package/dist/test/setup.d.ts +0 -14
  282. package/dist/test/setup.d.ts.map +0 -1
  283. package/dist/test/setup.js.map +0 -1
  284. package/dist/util.d.ts.map +0 -1
  285. package/dist/util.js.map +0 -1
  286. package/dist/where.d.ts +0 -9
  287. package/dist/where.d.ts.map +0 -1
  288. package/dist/where.js +0 -101
  289. package/dist/where.js.map +0 -1
  290. package/src/gql/opencrud.ts +0 -350
  291. package/src/queryBuilder.ts +0 -891
  292. package/src/relayConnection.ts +0 -80
  293. package/src/requestedFields.ts +0 -246
  294. package/src/resolver.ts +0 -201
  295. package/src/where.ts +0 -119
@@ -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
- }
@@ -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
- }