@subsquid/openreader 4.4.1 → 4.5.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 (54) hide show
  1. package/lib/context.d.ts +6 -3
  2. package/lib/context.d.ts.map +1 -1
  3. package/lib/db.d.ts +11 -13
  4. package/lib/db.d.ts.map +1 -1
  5. package/lib/db.js +51 -29
  6. package/lib/db.js.map +1 -1
  7. package/lib/limit.size.js.map +1 -1
  8. package/lib/model.schema.js.map +1 -1
  9. package/lib/model.tools.js.map +1 -1
  10. package/lib/opencrud/orderBy.js.map +1 -1
  11. package/lib/opencrud/schema.js.map +1 -1
  12. package/lib/opencrud/tree.js.map +1 -1
  13. package/lib/opencrud/where.js.map +1 -1
  14. package/lib/scalars/BigDecimal.js.map +1 -1
  15. package/lib/scalars/BigInt.js.map +1 -1
  16. package/lib/scalars/Bytes.js.map +1 -1
  17. package/lib/scalars/DateTime.js.map +1 -1
  18. package/lib/server.d.ts.map +1 -1
  19. package/lib/server.js +8 -23
  20. package/lib/server.js.map +1 -1
  21. package/lib/sql/cursor.js.map +1 -1
  22. package/lib/sql/mapping.js.map +1 -1
  23. package/lib/sql/printer.js.map +1 -1
  24. package/lib/sql/query.js.map +1 -1
  25. package/lib/sql/util.js.map +1 -1
  26. package/lib/subscription.js.map +1 -1
  27. package/lib/test/limits.test.js +1 -1
  28. package/lib/test/limits.test.js.map +1 -1
  29. package/lib/test/setup.d.ts.map +1 -1
  30. package/lib/test/setup.js +1 -0
  31. package/lib/test/setup.js.map +1 -1
  32. package/lib/tools.js.map +1 -1
  33. package/lib/util/big-decimal.js.map +1 -1
  34. package/lib/util/error-handling.d.ts +8 -9
  35. package/lib/util/error-handling.d.ts.map +1 -1
  36. package/lib/util/error-handling.js +32 -32
  37. package/lib/util/error-handling.js.map +1 -1
  38. package/lib/util/execute.d.ts +7 -2
  39. package/lib/util/execute.d.ts.map +1 -1
  40. package/lib/util/execute.js +74 -14
  41. package/lib/util/execute.js.map +1 -1
  42. package/lib/util/lazy-transaction.js.map +1 -1
  43. package/lib/util/limit.js +2 -2
  44. package/lib/util/limit.js.map +1 -1
  45. package/lib/util/resolve-tree.js.map +1 -1
  46. package/package.json +21 -21
  47. package/src/context.ts +6 -3
  48. package/src/db.ts +68 -37
  49. package/src/server.ts +18 -24
  50. package/src/test/limits.test.ts +1 -1
  51. package/src/test/setup.ts +2 -0
  52. package/src/util/error-handling.ts +40 -30
  53. package/src/util/execute.ts +96 -14
  54. package/src/util/limit.ts +2 -2
@@ -1,4 +1,7 @@
1
- import {getOperationRootType, GraphQLError} from 'graphql'
1
+ import {Logger, LogLevel} from '@subsquid/logger'
2
+ import {addErrorContext} from '@subsquid/util-internal'
3
+ import {UserInputError} from 'apollo-server-core'
4
+ import {getOperationRootType, GraphQLError, subscribe as graphqlSubscribe} from 'graphql'
2
5
  import {ExecutionResult} from 'graphql-ws'
3
6
  import {
4
7
  assertValidExecutionArguments,
@@ -8,10 +11,91 @@ import {
8
11
  ExecutionArgs,
9
12
  ExecutionContext
10
13
  } from 'graphql/execution/execute'
11
- import {PromiseOrValue} from 'graphql/jsutils/PromiseOrValue'
14
+ import {getDocumentCtx, logGraphQLErrors} from './error-handling'
12
15
 
13
16
 
14
- export function executeWithLimit(maxQueries: number, args: ExecutionArgs): PromiseOrValue<ExecutionResult> {
17
+ export interface ExecuteOptions {
18
+ maxRootFields?: number
19
+ }
20
+
21
+
22
+ export async function openreaderExecute(args: ExecutionArgs, options: ExecuteOptions): Promise<ExecutionResult> {
23
+ let log: Logger | undefined = args.contextValue.openreader.log?.child('gql')
24
+ if (log?.isDebug()) {
25
+ log.debug(getDocumentCtx(args), 'graphql query')
26
+ }
27
+
28
+ let result: ExecutionResult
29
+ let errors = validate(args, options)
30
+ if (errors.length > 0) {
31
+ result = {errors}
32
+ } else {
33
+ result = await graphqlExecute(args)
34
+ }
35
+
36
+ logResult('graphql result', log, args, result)
37
+
38
+ return result
39
+ }
40
+
41
+
42
+ type SubscriptionResult = AsyncIterableIterator<ExecutionResult> | ExecutionResult
43
+
44
+
45
+ export async function openreaderSubscribe(args: ExecutionArgs): Promise<SubscriptionResult> {
46
+ let log: Logger | undefined = args.contextValue.openreader.log?.child('gql')
47
+ if (log?.isDebug()) {
48
+ log.debug(getDocumentCtx(args), 'graphql subscription')
49
+ }
50
+
51
+ let result: SubscriptionResult
52
+ let errors = validate(args, {})
53
+ if (errors.length > 0) {
54
+ result = {errors}
55
+ } else {
56
+ result = await graphqlSubscribe(args)
57
+ }
58
+
59
+ if ((result as any)[Symbol.asyncIterator]) {
60
+ log?.debug('graphql subscription initiated')
61
+ if (log) return logSubscriptionResults(
62
+ log,
63
+ args,
64
+ result as AsyncIterableIterator<ExecutionResult>
65
+ )
66
+ } else {
67
+ logResult('graphql subscription result', log, args, result as ExecutionResult)
68
+ }
69
+
70
+ return result
71
+ }
72
+
73
+
74
+ async function *logSubscriptionResults(
75
+ log: Logger,
76
+ args: ExecutionArgs,
77
+ results: AsyncIterableIterator<ExecutionResult>
78
+ ): AsyncIterableIterator<ExecutionResult> {
79
+ for await (let result of results) {
80
+ logResult('graphql subscription result', log, args, result)
81
+ yield result
82
+ }
83
+ log.debug('graphql subscription ended')
84
+ }
85
+
86
+
87
+ function logResult(msg: string, log: Logger | undefined, args: ExecutionArgs, result: ExecutionResult): void {
88
+ if (log == null) return
89
+ if (log.isDebug()) {
90
+ log.debug({
91
+ graphqlResult: log.isTrace() ? result : undefined
92
+ }, msg)
93
+ }
94
+ logGraphQLErrors(log, args, result.errors)
95
+ }
96
+
97
+
98
+ function validate(args: ExecutionArgs, {maxRootFields}: ExecuteOptions): GraphQLError[] {
15
99
  assertValidExecutionArguments(args.schema, args.document, args.variableValues)
16
100
 
17
101
  let xtx = buildExecutionContext(
@@ -25,12 +109,12 @@ export function executeWithLimit(maxQueries: number, args: ExecutionArgs): Promi
25
109
  args.typeResolver
26
110
  )
27
111
 
28
- if (Array.isArray(xtx)) {
29
- return {errors: xtx}
30
- }
112
+ if (Array.isArray(xtx)) return xtx.map(err => addErrorContext(err, {
113
+ __openreaderLogLevel: LogLevel.WARN
114
+ }))
31
115
 
32
116
  let etx = xtx as ExecutionContext
33
- if (etx.operation.operation == 'query') {
117
+ if (maxRootFields && etx.operation.operation == 'query') {
34
118
  let query = getOperationRootType(etx.schema, etx.operation)
35
119
  let fields = collectFields(
36
120
  etx,
@@ -40,14 +124,12 @@ export function executeWithLimit(maxQueries: number, args: ExecutionArgs): Promi
40
124
  Object.create(null)
41
125
  )
42
126
  let fieldsCount = Object.keys(fields).length
43
- if (fieldsCount > maxQueries) {
44
- return {
45
- errors: [
46
- new GraphQLError(`only ${maxQueries} root query fields allowed, but got ${fieldsCount}`)
47
- ]
48
- }
127
+ if (fieldsCount > maxRootFields) {
128
+ return [
129
+ new UserInputError(`only ${maxRootFields} root fields allowed, but got ${fieldsCount}`)
130
+ ]
49
131
  }
50
132
  }
51
133
 
52
- return graphqlExecute(args)
134
+ return []
53
135
  }
package/src/util/limit.ts CHANGED
@@ -1,5 +1,5 @@
1
+ import {UserInputError} from 'apollo-server-core'
1
2
  import assert from 'assert'
2
- import {GraphQLError} from 'graphql'
3
3
 
4
4
 
5
5
  export class Limit {
@@ -23,7 +23,7 @@ export class Limit {
23
23
  }
24
24
 
25
25
 
26
- const SIZE_LIMIT = new GraphQLError('response might exceed the size limit')
26
+ const SIZE_LIMIT = new UserInputError('response might exceed the size limit')
27
27
  SIZE_LIMIT.stack = undefined
28
28
 
29
29