@subsquid/openreader 4.4.2 → 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.
- package/lib/context.d.ts +6 -3
- package/lib/context.d.ts.map +1 -1
- package/lib/db.d.ts +11 -13
- package/lib/db.d.ts.map +1 -1
- package/lib/db.js +51 -29
- package/lib/db.js.map +1 -1
- package/lib/server.d.ts.map +1 -1
- package/lib/server.js +8 -23
- package/lib/server.js.map +1 -1
- package/lib/test/limits.test.js +1 -1
- package/lib/test/limits.test.js.map +1 -1
- package/lib/test/setup.d.ts.map +1 -1
- package/lib/test/setup.js +1 -0
- package/lib/test/setup.js.map +1 -1
- package/lib/util/error-handling.d.ts +8 -9
- package/lib/util/error-handling.d.ts.map +1 -1
- package/lib/util/error-handling.js +32 -32
- package/lib/util/error-handling.js.map +1 -1
- package/lib/util/execute.d.ts +7 -2
- package/lib/util/execute.d.ts.map +1 -1
- package/lib/util/execute.js +74 -14
- package/lib/util/execute.js.map +1 -1
- package/lib/util/limit.js +2 -2
- package/lib/util/limit.js.map +1 -1
- package/package.json +1 -1
- package/src/context.ts +6 -3
- package/src/db.ts +68 -37
- package/src/server.ts +18 -24
- package/src/test/limits.test.ts +1 -1
- package/src/test/setup.ts +2 -0
- package/src/util/error-handling.ts +40 -30
- package/src/util/execute.ts +96 -14
- package/src/util/limit.ts +2 -2
package/lib/context.d.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { Logger } from '@subsquid/logger';
|
|
2
|
+
import type { Dialect } from './dialect';
|
|
3
|
+
import type { Query } from './sql/query';
|
|
4
|
+
import type { Limit } from './util/limit';
|
|
4
5
|
export interface Context {
|
|
5
6
|
openreader: OpenreaderContext;
|
|
6
7
|
}
|
|
7
8
|
export interface OpenreaderContext {
|
|
9
|
+
id: number;
|
|
8
10
|
dialect: Dialect;
|
|
9
11
|
executeQuery<T>(query: Query<T>): Promise<T>;
|
|
10
12
|
subscription<T>(query: Query<T>): AsyncIterable<T>;
|
|
11
13
|
responseSizeLimit?: Limit;
|
|
12
14
|
subscriptionResponseSizeLimit?: Limit;
|
|
15
|
+
log?: Logger;
|
|
13
16
|
}
|
|
14
17
|
//# sourceMappingURL=context.d.ts.map
|
package/lib/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAA;AAC5C,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AACtC,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,cAAc,CAAA;AAGvC,MAAM,WAAW,OAAO;IACpB,UAAU,EAAE,iBAAiB,CAAA;CAChC;AAGD,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IAC5C,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;IAClD,iBAAiB,CAAC,EAAE,KAAK,CAAA;IACzB,6BAA6B,CAAC,EAAE,KAAK,CAAA;IACrC,GAAG,CAAC,EAAE,MAAM,CAAA;CACf"}
|
package/lib/db.d.ts
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
query(sql: string, parameters?: any[]): Promise<any[][]>;
|
|
7
|
-
}
|
|
8
|
-
export declare class PgDatabase implements Database {
|
|
9
|
-
private client;
|
|
10
|
-
constructor(client: ClientBase);
|
|
11
|
-
query(sql: string, parameters?: any[]): Promise<any[][]>;
|
|
12
|
-
}
|
|
1
|
+
import type { Logger } from '@subsquid/logger';
|
|
2
|
+
import type { Pool } from 'pg';
|
|
3
|
+
import { OpenreaderContext } from './context';
|
|
4
|
+
import { Dialect } from './dialect';
|
|
5
|
+
import { Query } from './sql/query';
|
|
13
6
|
export declare class PoolOpenreaderContext implements OpenreaderContext {
|
|
14
7
|
readonly dialect: Dialect;
|
|
15
8
|
private subscriptionPollInterval;
|
|
9
|
+
id: number;
|
|
10
|
+
log?: Logger;
|
|
16
11
|
private tx;
|
|
17
12
|
private subscriptionPool;
|
|
18
|
-
|
|
13
|
+
private queryCounter;
|
|
14
|
+
constructor(dialect: Dialect, pool: Pool, subscriptionPool?: Pool, subscriptionPollInterval?: number, log?: Logger);
|
|
19
15
|
close(): Promise<void>;
|
|
20
16
|
executeQuery<T>(query: Query<T>): Promise<T>;
|
|
21
17
|
subscription<T>(query: Query<T>): AsyncIterable<T>;
|
|
18
|
+
private transact;
|
|
19
|
+
private query;
|
|
22
20
|
}
|
|
23
21
|
//# sourceMappingURL=db.d.ts.map
|
package/lib/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAA;AAE5C,OAAO,KAAK,EAAa,IAAI,EAAC,MAAM,IAAI,CAAA;AAExC,OAAO,EAAC,iBAAiB,EAAC,MAAM,WAAW,CAAA;AAC3C,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AAQjC,qBAAa,qBAAsB,YAAW,iBAAiB;aAQvC,OAAO,EAAE,OAAO;IAGhC,OAAO,CAAC,wBAAwB;IAV7B,EAAE,SAA8D;IAChE,GAAG,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,CAA2B;IACrC,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,YAAY,CAAI;gBAGJ,OAAO,EAAE,OAAO,EAChC,IAAI,EAAE,IAAI,EACV,gBAAgB,CAAC,EAAE,IAAI,EACf,wBAAwB,GAAE,MAAa,EAC/C,GAAG,CAAC,EAAE,MAAM;IAOhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAMlD,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;YAOpC,QAAQ;YAiBR,KAAK;CA8BtB"}
|
package/lib/db.js
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PoolOpenreaderContext =
|
|
3
|
+
exports.PoolOpenreaderContext = void 0;
|
|
4
|
+
const util_internal_1 = require("@subsquid/util-internal");
|
|
4
5
|
const subscription_1 = require("./subscription");
|
|
5
|
-
const error_handling_1 = require("./util/error-handling");
|
|
6
6
|
const lazy_transaction_1 = require("./util/lazy-transaction");
|
|
7
|
-
|
|
8
|
-
constructor(client) {
|
|
9
|
-
this.client = client;
|
|
10
|
-
}
|
|
11
|
-
query(sql, parameters) {
|
|
12
|
-
return this.client.query({ text: sql, rowMode: 'array' }, parameters)
|
|
13
|
-
.then(result => result.rows)
|
|
14
|
-
.catch((0, error_handling_1.withErrorContext)({ sql, parameters }));
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
exports.PgDatabase = PgDatabase;
|
|
7
|
+
let CTX_COUNTER = 0;
|
|
18
8
|
class PoolOpenreaderContext {
|
|
19
|
-
constructor(dialect, pool, subscriptionPool, subscriptionPollInterval = 1000) {
|
|
9
|
+
constructor(dialect, pool, subscriptionPool, subscriptionPollInterval = 1000, log) {
|
|
20
10
|
this.dialect = dialect;
|
|
21
11
|
this.subscriptionPollInterval = subscriptionPollInterval;
|
|
22
|
-
this.
|
|
12
|
+
this.id = (CTX_COUNTER = (CTX_COUNTER + 1) % Number.MAX_SAFE_INTEGER);
|
|
13
|
+
this.queryCounter = 0;
|
|
14
|
+
this.log = log?.child({ graphqlCtx: this.id });
|
|
15
|
+
this.tx = new lazy_transaction_1.LazyTransaction(cb => this.transact(pool, cb));
|
|
23
16
|
this.subscriptionPool = subscriptionPool || pool;
|
|
24
17
|
}
|
|
25
18
|
close() {
|
|
@@ -27,31 +20,60 @@ class PoolOpenreaderContext {
|
|
|
27
20
|
}
|
|
28
21
|
async executeQuery(query) {
|
|
29
22
|
let db = await this.tx.get();
|
|
30
|
-
let result = await db
|
|
23
|
+
let result = await db(query.sql, query.params);
|
|
31
24
|
return query.map(result);
|
|
32
25
|
}
|
|
33
26
|
subscription(query) {
|
|
34
|
-
return new subscription_1.Subscription(this.subscriptionPollInterval, () => transact(this.subscriptionPool, async (db) => {
|
|
35
|
-
let result = await db
|
|
27
|
+
return new subscription_1.Subscription(this.subscriptionPollInterval, () => this.transact(this.subscriptionPool, async (db) => {
|
|
28
|
+
let result = await db(query.sql, query.params);
|
|
36
29
|
return query.map(result);
|
|
37
30
|
}));
|
|
38
31
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
async function transact(pool, cb) {
|
|
42
|
-
let client = await pool.connect();
|
|
43
|
-
try {
|
|
44
|
-
await client.query('START TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY');
|
|
32
|
+
async transact(pool, cb) {
|
|
33
|
+
let client = await pool.connect();
|
|
45
34
|
try {
|
|
46
|
-
|
|
47
|
-
|
|
35
|
+
await this.query(client, 'START TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY');
|
|
36
|
+
try {
|
|
37
|
+
return await cb(async (sql, parameters) => {
|
|
38
|
+
let result = await this.query(client, sql, parameters);
|
|
39
|
+
return result.rows;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
await this.query(client, 'COMMIT').catch(() => { });
|
|
44
|
+
}
|
|
48
45
|
}
|
|
49
46
|
finally {
|
|
50
|
-
|
|
47
|
+
client.release();
|
|
51
48
|
}
|
|
52
49
|
}
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
async query(client, sql, parameters) {
|
|
51
|
+
let queryId = this.queryCounter = (this.queryCounter + 1) % Number.MAX_SAFE_INTEGER;
|
|
52
|
+
let ctx = {
|
|
53
|
+
graphqlCtx: this.id,
|
|
54
|
+
graphqlSqlQuery: queryId,
|
|
55
|
+
};
|
|
56
|
+
let log = this.log?.child('sql', ctx);
|
|
57
|
+
log?.debug({
|
|
58
|
+
sql,
|
|
59
|
+
parameters
|
|
60
|
+
}, 'sql query');
|
|
61
|
+
try {
|
|
62
|
+
let result = await client.query({ text: sql, rowMode: 'array' }, parameters);
|
|
63
|
+
log?.debug({
|
|
64
|
+
rowCount: result.rowCount || 0,
|
|
65
|
+
rows: log.isTrace() ? result.rows : undefined
|
|
66
|
+
}, 'sql result');
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
throw (0, util_internal_1.addErrorContext)(err, {
|
|
71
|
+
...ctx,
|
|
72
|
+
sql,
|
|
73
|
+
parameters
|
|
74
|
+
});
|
|
75
|
+
}
|
|
55
76
|
}
|
|
56
77
|
}
|
|
78
|
+
exports.PoolOpenreaderContext = PoolOpenreaderContext;
|
|
57
79
|
//# sourceMappingURL=db.js.map
|
package/lib/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
package/lib/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAS,eAAe,EAAC,MAAM,qCAAqC,CAAA;AAC3E,OAAO,EAAC,aAAa,EAAE,gBAAgB,EAAC,MAAM,oBAAoB,CAAA;AAElE,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,OAAO,EAAgB,aAAa,EAAC,MAAM,SAAS,CAAA;AAIpD,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,IAAI,CAAA;AAE5B,OAAO,EAAC,OAAO,EAAoB,MAAM,WAAW,CAAA;AAEpD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAS,eAAe,EAAC,MAAM,qCAAqC,CAAA;AAC3E,OAAO,EAAC,aAAa,EAAE,gBAAgB,EAAC,MAAM,oBAAoB,CAAA;AAElE,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,OAAO,EAAgB,aAAa,EAAC,MAAM,SAAS,CAAA;AAIpD,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,IAAI,CAAA;AAE5B,OAAO,EAAC,OAAO,EAAoB,MAAM,WAAW,CAAA;AAEpD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,SAAS,CAAA;AAMlC,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB,KAAK,EAAE,KAAK,CAAA;IACZ,UAAU,EAAE,IAAI,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,sBAAsB,CAAC,EAAE,IAAI,CAAA;IAC7B,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,KAAK,CAAC,EAAE,aAAa,CAAA;CACxB;AAED,wBAAsB,KAAK,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAmD5E;AAGD,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;AAGzC,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB,SAAS,EAAE,OAAO,EAAE,CAAA;IACpB,OAAO,EAAE,MAAM,OAAO,CAAA;IACtB,MAAM,EAAE,aAAa,CAAA;IACrB,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,aAAa,CAAA;CACxB;AAGD,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CA+EhF;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAmB/H;AAGD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,WAAW,GAAG,IAAI,CAsBnE"}
|
package/lib/server.js
CHANGED
|
@@ -14,15 +14,14 @@ const path_1 = __importDefault(require("path"));
|
|
|
14
14
|
const ws_2 = require("ws");
|
|
15
15
|
const db_1 = require("./db");
|
|
16
16
|
const schema_1 = require("./opencrud/schema");
|
|
17
|
-
const error_handling_1 = require("./util/error-handling");
|
|
18
17
|
const execute_1 = require("./util/execute");
|
|
19
18
|
const limit_1 = require("./util/limit");
|
|
20
19
|
async function serve(options) {
|
|
21
|
-
let { connection, subscriptionConnection, subscriptionPollInterval, maxResponseNodes, subscriptionMaxResponseNodes } = options;
|
|
20
|
+
let { connection, subscriptionConnection, subscriptionPollInterval, maxResponseNodes, subscriptionMaxResponseNodes, log } = options;
|
|
22
21
|
let dialect = options.dialect ?? 'postgres';
|
|
23
22
|
let schema = new schema_1.SchemaBuilder(options).build();
|
|
24
23
|
let context = () => {
|
|
25
|
-
let openreader = new db_1.PoolOpenreaderContext(dialect, connection, subscriptionConnection, subscriptionPollInterval);
|
|
24
|
+
let openreader = new db_1.PoolOpenreaderContext(dialect, connection, subscriptionConnection, subscriptionPollInterval, log);
|
|
26
25
|
if (maxResponseNodes) {
|
|
27
26
|
openreader.responseSizeLimit = new limit_1.ResponseSizeLimit(maxResponseNodes);
|
|
28
27
|
openreader.subscriptionResponseSizeLimit = new limit_1.ResponseSizeLimit(maxResponseNodes);
|
|
@@ -54,9 +53,9 @@ async function runApollo(options) {
|
|
|
54
53
|
let maxRequestSizeBytes = options.maxRequestSizeBytes ?? 256 * 1024;
|
|
55
54
|
let app = (0, express_1.default)();
|
|
56
55
|
let server = http_1.default.createServer(app);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
let execute = (args) => (0, execute_1.openreaderExecute)(args, {
|
|
57
|
+
maxRootFields: maxRootFields
|
|
58
|
+
});
|
|
60
59
|
if (options.subscriptions) {
|
|
61
60
|
let wsServer = new ws_2.WebSocketServer({
|
|
62
61
|
server,
|
|
@@ -67,14 +66,7 @@ async function runApollo(options) {
|
|
|
67
66
|
schema,
|
|
68
67
|
context,
|
|
69
68
|
execute,
|
|
70
|
-
|
|
71
|
-
if (log) {
|
|
72
|
-
// FIXME: we don't want to log client errors
|
|
73
|
-
for (let err of errors) {
|
|
74
|
-
(0, error_handling_1.logGraphQLError)(log, err);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
},
|
|
69
|
+
subscribe: execute_1.openreaderSubscribe,
|
|
78
70
|
onNext(_ctx, _message, args, result) {
|
|
79
71
|
args.contextValue.openreader.close();
|
|
80
72
|
return result;
|
|
@@ -88,7 +80,7 @@ async function runApollo(options) {
|
|
|
88
80
|
cache: options.cache,
|
|
89
81
|
stopOnTerminationSignals: false,
|
|
90
82
|
allowBatchedHttpRequests: false,
|
|
91
|
-
executor:
|
|
83
|
+
executor: async (req) => {
|
|
92
84
|
return execute({
|
|
93
85
|
schema,
|
|
94
86
|
document: req.document,
|
|
@@ -97,7 +89,7 @@ async function runApollo(options) {
|
|
|
97
89
|
variableValues: req.request.variables,
|
|
98
90
|
operationName: req.operationName
|
|
99
91
|
});
|
|
100
|
-
}
|
|
92
|
+
},
|
|
101
93
|
plugins: [
|
|
102
94
|
...options.plugins || [],
|
|
103
95
|
{
|
|
@@ -105,13 +97,6 @@ async function runApollo(options) {
|
|
|
105
97
|
return {
|
|
106
98
|
willSendResponse(req) {
|
|
107
99
|
return req.context.openreader.close();
|
|
108
|
-
},
|
|
109
|
-
async didEncounterErrors(req) {
|
|
110
|
-
if (req.operation && log) {
|
|
111
|
-
for (let err of req.errors) {
|
|
112
|
-
(0, error_handling_1.logGraphQLError)(log, err);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
100
|
}
|
|
116
101
|
};
|
|
117
102
|
}
|
package/lib/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;;AACA,mFAA2E;AAE3E,iEAAkD;AAClD,sDAA6B;AAC7B,4CAAmB;AAEnB,8CAA8D;AAC9D,gDAAuB;AACvB,gDAAuB;AAEvB,2BAAkC;AAElC,6BAA0C;AAG1C,8CAA+C;AAC/C,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/lib/test/limits.test.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"limits.test.js","sourceRoot":"","sources":["../../src/test/limits.test.ts"],"names":[],"mappings":";;;;;AAAA,oDAA2B;AAC3B,mCAA8C;AAG9C,QAAQ,CAAC,sBAAsB,EAAE;IAC7B,IAAA,mBAAW,EAAC;QACR,6CAA6C;QAC7C,oEAAoE;QACpE,6CAA6C;QAC7C,oEAAoE;QACpE,6CAA6C;QAC7C,oEAAoE;KACvE,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,IAAA,iBAAS,EAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiCxB,EAAE;QACC,gBAAgB,EAAE,EAAE;QACpB,aAAa,EAAE,CAAC;KACnB,CAAC,CAAA;IAEF,EAAE,CAAC,yBAAyB,EAAE,KAAK;QAC/B,IAAI,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;;;;;;SAM/B,CAAC,CAAA;QACF,IAAA,gBAAM,EAAC,MAAM,CAAC,CAAC,aAAa,CAAC;YACzB,IAAI,EAAE,IAAI;YACV,MAAM,EAAE;gBACJ,gBAAM,CAAC,gBAAgB,CAAC,EAAC,OAAO,EAAE,sCAAsC,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAC,CAAC;aAChG;SACJ,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uBAAuB,EAAE;QACxB,OAAO,MAAM,CAAC,IAAI,CAAC;;;;;;;;SAQlB,EAAE;YACC,OAAO,EAAE,EAAE;SACd,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE;QAC3C,OAAO,MAAM,CAAC,IAAI,CAAC;;;;;;SAMlB,EAAE;YACC,OAAO,EAAE,EAAE;SACd,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE;QACnC,OAAO,MAAM,CAAC,IAAI,CAAC;;;;;;SAMlB,EAAE;YACC,OAAO,EAAE,EAAE;SACd,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uCAAuC,EAAE,KAAK;QAC7C,IAAI,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;;;;;;SAM/B,CAAC,CAAA;QACF,IAAA,gBAAM,EAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACnB,IAAI,EAAE,IAAI;YACV,MAAM,EAAE;gBACJ,gBAAM,CAAC,gBAAgB,CAAC;oBACpB,OAAO,EAAE,sCAAsC;oBAC/C,IAAI,EAAE,CAAC,SAAS,CAAC;iBACpB,CAAC;aACL;SACJ,CAAC,CAAA;QACF,MAAM,MAAM,CAAC,IAAI,CAAC;;;;;;SAMjB,EAAE;YACC,OAAO,EAAE,EAAE;SACd,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iCAAiC,EAAE;QAClC,OAAO,MAAM,CAAC,IAAI,CAAC;;;;;;SAMlB,EAAE;YACC,OAAO,EAAE,EAAE;SACd,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yBAAyB,EAAE,KAAK;QAC/B,OAAO,MAAM,CAAC,aAAa,CAAC;;;;;;;SAO3B,EAAE;YACC,MAAM,EAAE;gBACJ,gBAAM,CAAC,gBAAgB,CAAC;oBACpB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"limits.test.js","sourceRoot":"","sources":["../../src/test/limits.test.ts"],"names":[],"mappings":";;;;;AAAA,oDAA2B;AAC3B,mCAA8C;AAG9C,QAAQ,CAAC,sBAAsB,EAAE;IAC7B,IAAA,mBAAW,EAAC;QACR,6CAA6C;QAC7C,oEAAoE;QACpE,6CAA6C;QAC7C,oEAAoE;QACpE,6CAA6C;QAC7C,oEAAoE;KACvE,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,IAAA,iBAAS,EAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiCxB,EAAE;QACC,gBAAgB,EAAE,EAAE;QACpB,aAAa,EAAE,CAAC;KACnB,CAAC,CAAA;IAEF,EAAE,CAAC,yBAAyB,EAAE,KAAK;QAC/B,IAAI,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;;;;;;SAM/B,CAAC,CAAA;QACF,IAAA,gBAAM,EAAC,MAAM,CAAC,CAAC,aAAa,CAAC;YACzB,IAAI,EAAE,IAAI;YACV,MAAM,EAAE;gBACJ,gBAAM,CAAC,gBAAgB,CAAC,EAAC,OAAO,EAAE,sCAAsC,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAC,CAAC;aAChG;SACJ,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uBAAuB,EAAE;QACxB,OAAO,MAAM,CAAC,IAAI,CAAC;;;;;;;;SAQlB,EAAE;YACC,OAAO,EAAE,EAAE;SACd,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE;QAC3C,OAAO,MAAM,CAAC,IAAI,CAAC;;;;;;SAMlB,EAAE;YACC,OAAO,EAAE,EAAE;SACd,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE;QACnC,OAAO,MAAM,CAAC,IAAI,CAAC;;;;;;SAMlB,EAAE;YACC,OAAO,EAAE,EAAE;SACd,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uCAAuC,EAAE,KAAK;QAC7C,IAAI,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;;;;;;SAM/B,CAAC,CAAA;QACF,IAAA,gBAAM,EAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACnB,IAAI,EAAE,IAAI;YACV,MAAM,EAAE;gBACJ,gBAAM,CAAC,gBAAgB,CAAC;oBACpB,OAAO,EAAE,sCAAsC;oBAC/C,IAAI,EAAE,CAAC,SAAS,CAAC;iBACpB,CAAC;aACL;SACJ,CAAC,CAAA;QACF,MAAM,MAAM,CAAC,IAAI,CAAC;;;;;;SAMjB,EAAE;YACC,OAAO,EAAE,EAAE;SACd,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iCAAiC,EAAE;QAClC,OAAO,MAAM,CAAC,IAAI,CAAC;;;;;;SAMlB,EAAE;YACC,OAAO,EAAE,EAAE;SACd,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yBAAyB,EAAE,KAAK;QAC/B,OAAO,MAAM,CAAC,aAAa,CAAC;;;;;;;SAO3B,EAAE;YACC,MAAM,EAAE;gBACJ,gBAAM,CAAC,gBAAgB,CAAC;oBACpB,OAAO,EAAE,uCAAuC;iBACnD,CAAC;aACL;SACJ,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
|
package/lib/test/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,MAAM,EAAC,MAAM,iBAAiB,CAAA;AAEtC,OAAO,EAAqB,UAAU,EAAO,MAAM,IAAI,CAAA;AAEvD,OAAO,EAAQ,aAAa,EAAC,MAAM,WAAW,CAAA;AAG9C,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAGD,eAAO,MAAM,SAAS;;;;;;CAQrB,CAAA;AAGD,wBAAsB,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ9F;AAGD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAM5D;AAGD,wBAAgB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAK9C;AAGD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAK/C;AAGD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,MAAM,CAqBlF"}
|
package/lib/test/setup.js
CHANGED
package/lib/test/setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { Logger
|
|
2
|
-
import { GraphQLError } from
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export declare class NonErrorThrown extends Error {
|
|
8
|
-
readonly value: unknown;
|
|
9
|
-
constructor(value: unknown);
|
|
1
|
+
import { Logger } from '@subsquid/logger';
|
|
2
|
+
import { ExecutionArgs, GraphQLError } from 'graphql';
|
|
3
|
+
export interface DocumentCtx {
|
|
4
|
+
graphqlOperationName?: string;
|
|
5
|
+
graphqlDocument: string;
|
|
6
|
+
graphqlVariables: any;
|
|
10
7
|
}
|
|
8
|
+
export declare const getDocumentCtx: (obj: ExecutionArgs) => DocumentCtx;
|
|
9
|
+
export declare function logGraphQLErrors(log: Logger, args: ExecutionArgs, errors: readonly GraphQLError[] | undefined): void;
|
|
11
10
|
//# sourceMappingURL=error-handling.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../src/util/error-handling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../src/util/error-handling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAW,MAAM,kBAAkB,CAAA;AAEjD,OAAO,EAAC,aAAa,EAAE,YAAY,EAAQ,MAAM,SAAS,CAAA;AAG1D,MAAM,WAAW,WAAW;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,GAAG,CAAA;CACxB;AAGD,eAAO,MAAM,cAAc,qCAMzB,CAAA;AAGF,wBAAgB,gBAAgB,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,GAC5C,IAAI,CAiBN"}
|
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.logGraphQLErrors = exports.getDocumentCtx = void 0;
|
|
4
4
|
const logger_1 = require("@subsquid/logger");
|
|
5
|
+
const util_internal_1 = require("@subsquid/util-internal");
|
|
5
6
|
const graphql_1 = require("graphql");
|
|
6
|
-
|
|
7
|
+
exports.getDocumentCtx = (0, util_internal_1.weakMemo)((args) => {
|
|
8
|
+
return {
|
|
9
|
+
graphqlOperationName: args.operationName || undefined,
|
|
10
|
+
graphqlDocument: (0, graphql_1.print)(args.document),
|
|
11
|
+
graphqlVariables: args.variableValues
|
|
12
|
+
};
|
|
13
|
+
});
|
|
14
|
+
function logGraphQLErrors(log, args, errors) {
|
|
15
|
+
if (!errors?.length)
|
|
16
|
+
return;
|
|
17
|
+
let level = 0;
|
|
18
|
+
let graphqlErrors = errors.map(err => {
|
|
19
|
+
level = Math.max(level, getErrorLevel(err));
|
|
20
|
+
return {
|
|
21
|
+
message: err.message,
|
|
22
|
+
path: err.path?.join('.'),
|
|
23
|
+
extensions: err.extensions,
|
|
24
|
+
originalError: err.originalError
|
|
25
|
+
};
|
|
26
|
+
});
|
|
7
27
|
if (log.level > level)
|
|
8
28
|
return;
|
|
9
|
-
let msg = (0, graphql_1.printError)(err) + '\n';
|
|
10
29
|
log.write(level, {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}, msg);
|
|
15
|
-
}
|
|
16
|
-
exports.logGraphQLError = logGraphQLError;
|
|
17
|
-
function withErrorContext(ctx) {
|
|
18
|
-
return function (err) {
|
|
19
|
-
throw addErrorContext(err, ctx);
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
exports.withErrorContext = withErrorContext;
|
|
23
|
-
function addErrorContext(error, ctx) {
|
|
24
|
-
let e = ensureError(error);
|
|
25
|
-
Object.assign(e, ctx);
|
|
26
|
-
return e;
|
|
27
|
-
}
|
|
28
|
-
exports.addErrorContext = addErrorContext;
|
|
29
|
-
function ensureError(err) {
|
|
30
|
-
if (err instanceof Error)
|
|
31
|
-
return err;
|
|
32
|
-
return new NonErrorThrown(err);
|
|
30
|
+
graphqlErrors,
|
|
31
|
+
...(0, exports.getDocumentCtx)(args)
|
|
32
|
+
}, 'graphql query ended with errors');
|
|
33
33
|
}
|
|
34
|
-
exports.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
exports.logGraphQLErrors = logGraphQLErrors;
|
|
35
|
+
function getErrorLevel(err) {
|
|
36
|
+
if (err.__openreaderLogLevel)
|
|
37
|
+
return err.__openreaderLogLevel;
|
|
38
|
+
if (err.extensions?.code === 'BAD_USER_INPUT')
|
|
39
|
+
return logger_1.LogLevel.WARN;
|
|
40
|
+
return logger_1.LogLevel.ERROR;
|
|
40
41
|
}
|
|
41
|
-
exports.NonErrorThrown = NonErrorThrown;
|
|
42
42
|
//# sourceMappingURL=error-handling.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handling.js","sourceRoot":"","sources":["../../src/util/error-handling.ts"],"names":[],"mappings":";;;AAAA,6CAAiD;AACjD,
|
|
1
|
+
{"version":3,"file":"error-handling.js","sourceRoot":"","sources":["../../src/util/error-handling.ts"],"names":[],"mappings":";;;AAAA,6CAAiD;AACjD,2DAAgD;AAChD,qCAA0D;AAU7C,QAAA,cAAc,GAAG,IAAA,wBAAQ,EAAC,CAAC,IAAmB,EAAe,EAAE;IACxE,OAAO;QACH,oBAAoB,EAAE,IAAI,CAAC,aAAa,IAAI,SAAS;QACrD,eAAe,EAAE,IAAA,eAAK,EAAC,IAAI,CAAC,QAAQ,CAAC;QACrC,gBAAgB,EAAE,IAAI,CAAC,cAAc;KACxC,CAAA;AACL,CAAC,CAAC,CAAA;AAGF,SAAgB,gBAAgB,CAC5B,GAAW,EACX,IAAmB,EACnB,MAA2C;IAE3C,IAAI,CAAC,MAAM,EAAE,MAAM;QAAE,OAAM;IAC3B,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACjC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAA;QAC3C,OAAO;YACH,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;YACzB,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,aAAa,EAAE,GAAG,CAAC,aAAa;SACnC,CAAA;IACL,CAAC,CAAC,CAAA;IACF,IAAI,GAAG,CAAC,KAAK,GAAG,KAAK;QAAE,OAAM;IAC7B,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE;QACb,aAAa;QACb,GAAG,IAAA,sBAAc,EAAC,IAAI,CAAC;KAC1B,EAAE,iCAAiC,CAAC,CAAA;AACzC,CAAC;AArBD,4CAqBC;AAGD,SAAS,aAAa,CAAC,GAAiB;IACpC,IAAK,GAAW,CAAC,oBAAoB;QAAE,OAAQ,GAAW,CAAC,oBAAoB,CAAA;IAC/E,IAAI,GAAG,CAAC,UAAU,EAAE,IAAI,KAAK,gBAAgB;QAAE,OAAO,iBAAQ,CAAC,IAAI,CAAA;IACnE,OAAO,iBAAQ,CAAC,KAAK,CAAA;AACzB,CAAC"}
|
package/lib/util/execute.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { ExecutionResult } from 'graphql-ws';
|
|
2
2
|
import { ExecutionArgs } from 'graphql/execution/execute';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
export interface ExecuteOptions {
|
|
4
|
+
maxRootFields?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function openreaderExecute(args: ExecutionArgs, options: ExecuteOptions): Promise<ExecutionResult>;
|
|
7
|
+
type SubscriptionResult = AsyncIterableIterator<ExecutionResult> | ExecutionResult;
|
|
8
|
+
export declare function openreaderSubscribe(args: ExecutionArgs): Promise<SubscriptionResult>;
|
|
9
|
+
export {};
|
|
5
10
|
//# sourceMappingURL=execute.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/util/execute.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/util/execute.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,eAAe,EAAC,MAAM,YAAY,CAAA;AAC1C,OAAO,EAKH,aAAa,EAEhB,MAAM,2BAA2B,CAAA;AAIlC,MAAM,WAAW,cAAc;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAA;CACzB;AAGD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAiB9G;AAGD,KAAK,kBAAkB,GAAG,qBAAqB,CAAC,eAAe,CAAC,GAAG,eAAe,CAAA;AAGlF,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0B1F"}
|
package/lib/util/execute.js
CHANGED
|
@@ -1,28 +1,88 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.openreaderSubscribe = exports.openreaderExecute = void 0;
|
|
4
|
+
const logger_1 = require("@subsquid/logger");
|
|
5
|
+
const util_internal_1 = require("@subsquid/util-internal");
|
|
6
|
+
const apollo_server_core_1 = require("apollo-server-core");
|
|
4
7
|
const graphql_1 = require("graphql");
|
|
5
8
|
const execute_1 = require("graphql/execution/execute");
|
|
6
|
-
|
|
9
|
+
const error_handling_1 = require("./error-handling");
|
|
10
|
+
async function openreaderExecute(args, options) {
|
|
11
|
+
let log = args.contextValue.openreader.log?.child('gql');
|
|
12
|
+
if (log?.isDebug()) {
|
|
13
|
+
log.debug((0, error_handling_1.getDocumentCtx)(args), 'graphql query');
|
|
14
|
+
}
|
|
15
|
+
let result;
|
|
16
|
+
let errors = validate(args, options);
|
|
17
|
+
if (errors.length > 0) {
|
|
18
|
+
result = { errors };
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
result = await (0, execute_1.execute)(args);
|
|
22
|
+
}
|
|
23
|
+
logResult('graphql result', log, args, result);
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
exports.openreaderExecute = openreaderExecute;
|
|
27
|
+
async function openreaderSubscribe(args) {
|
|
28
|
+
let log = args.contextValue.openreader.log?.child('gql');
|
|
29
|
+
if (log?.isDebug()) {
|
|
30
|
+
log.debug((0, error_handling_1.getDocumentCtx)(args), 'graphql subscription');
|
|
31
|
+
}
|
|
32
|
+
let result;
|
|
33
|
+
let errors = validate(args, {});
|
|
34
|
+
if (errors.length > 0) {
|
|
35
|
+
result = { errors };
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
result = await (0, graphql_1.subscribe)(args);
|
|
39
|
+
}
|
|
40
|
+
if (result[Symbol.asyncIterator]) {
|
|
41
|
+
log?.debug('graphql subscription initiated');
|
|
42
|
+
if (log)
|
|
43
|
+
return logSubscriptionResults(log, args, result);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
logResult('graphql subscription result', log, args, result);
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
exports.openreaderSubscribe = openreaderSubscribe;
|
|
51
|
+
async function* logSubscriptionResults(log, args, results) {
|
|
52
|
+
for await (let result of results) {
|
|
53
|
+
logResult('graphql subscription result', log, args, result);
|
|
54
|
+
yield result;
|
|
55
|
+
}
|
|
56
|
+
log.debug('graphql subscription ended');
|
|
57
|
+
}
|
|
58
|
+
function logResult(msg, log, args, result) {
|
|
59
|
+
if (log == null)
|
|
60
|
+
return;
|
|
61
|
+
if (log.isDebug()) {
|
|
62
|
+
log.debug({
|
|
63
|
+
graphqlResult: log.isTrace() ? result : undefined
|
|
64
|
+
}, msg);
|
|
65
|
+
}
|
|
66
|
+
(0, error_handling_1.logGraphQLErrors)(log, args, result.errors);
|
|
67
|
+
}
|
|
68
|
+
function validate(args, { maxRootFields }) {
|
|
7
69
|
(0, execute_1.assertValidExecutionArguments)(args.schema, args.document, args.variableValues);
|
|
8
70
|
let xtx = (0, execute_1.buildExecutionContext)(args.schema, args.document, args.rootValue, args.contextValue, args.variableValues, args.operationName, args.fieldResolver, args.typeResolver);
|
|
9
|
-
if (Array.isArray(xtx))
|
|
10
|
-
return
|
|
11
|
-
|
|
71
|
+
if (Array.isArray(xtx))
|
|
72
|
+
return xtx.map(err => (0, util_internal_1.addErrorContext)(err, {
|
|
73
|
+
__openreaderLogLevel: logger_1.LogLevel.WARN
|
|
74
|
+
}));
|
|
12
75
|
let etx = xtx;
|
|
13
|
-
if (etx.operation.operation == 'query') {
|
|
76
|
+
if (maxRootFields && etx.operation.operation == 'query') {
|
|
14
77
|
let query = (0, graphql_1.getOperationRootType)(etx.schema, etx.operation);
|
|
15
78
|
let fields = (0, execute_1.collectFields)(etx, query, etx.operation.selectionSet, Object.create(null), Object.create(null));
|
|
16
79
|
let fieldsCount = Object.keys(fields).length;
|
|
17
|
-
if (fieldsCount >
|
|
18
|
-
return
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
]
|
|
22
|
-
};
|
|
80
|
+
if (fieldsCount > maxRootFields) {
|
|
81
|
+
return [
|
|
82
|
+
new apollo_server_core_1.UserInputError(`only ${maxRootFields} root fields allowed, but got ${fieldsCount}`)
|
|
83
|
+
];
|
|
23
84
|
}
|
|
24
85
|
}
|
|
25
|
-
return
|
|
86
|
+
return [];
|
|
26
87
|
}
|
|
27
|
-
exports.executeWithLimit = executeWithLimit;
|
|
28
88
|
//# sourceMappingURL=execute.js.map
|
package/lib/util/execute.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/util/execute.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/util/execute.ts"],"names":[],"mappings":";;;AAAA,6CAAiD;AACjD,2DAAuD;AACvD,2DAAiD;AACjD,qCAAyF;AAEzF,uDAOkC;AAClC,qDAAiE;AAQ1D,KAAK,UAAU,iBAAiB,CAAC,IAAmB,EAAE,OAAuB;IAChF,IAAI,GAAG,GAAuB,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC5E,IAAI,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC;QACjB,GAAG,CAAC,KAAK,CAAC,IAAA,+BAAc,EAAC,IAAI,CAAC,EAAE,eAAe,CAAC,CAAA;IACpD,CAAC;IAED,IAAI,MAAuB,CAAA;IAC3B,IAAI,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACpC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,GAAG,EAAC,MAAM,EAAC,CAAA;IACrB,CAAC;SAAM,CAAC;QACJ,MAAM,GAAG,MAAM,IAAA,iBAAc,EAAC,IAAI,CAAC,CAAA;IACvC,CAAC;IAED,SAAS,CAAC,gBAAgB,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IAE9C,OAAO,MAAM,CAAA;AACjB,CAAC;AAjBD,8CAiBC;AAMM,KAAK,UAAU,mBAAmB,CAAC,IAAmB;IACzD,IAAI,GAAG,GAAuB,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IAC5E,IAAI,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC;QACjB,GAAG,CAAC,KAAK,CAAC,IAAA,+BAAc,EAAC,IAAI,CAAC,EAAE,sBAAsB,CAAC,CAAA;IAC3D,CAAC;IAED,IAAI,MAA0B,CAAA;IAC9B,IAAI,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IAC/B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,GAAG,EAAC,MAAM,EAAC,CAAA;IACrB,CAAC;SAAM,CAAC;QACJ,MAAM,GAAG,MAAM,IAAA,mBAAgB,EAAC,IAAI,CAAC,CAAA;IACzC,CAAC;IAED,IAAK,MAAc,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;QACxC,GAAG,EAAE,KAAK,CAAC,gCAAgC,CAAC,CAAA;QAC5C,IAAI,GAAG;YAAE,OAAO,sBAAsB,CAClC,GAAG,EACH,IAAI,EACJ,MAAgD,CACnD,CAAA;IACL,CAAC;SAAM,CAAC;QACJ,SAAS,CAAC,6BAA6B,EAAE,GAAG,EAAE,IAAI,EAAE,MAAyB,CAAC,CAAA;IAClF,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC;AA1BD,kDA0BC;AAGD,KAAK,SAAU,CAAC,CAAA,sBAAsB,CAClC,GAAW,EACX,IAAmB,EACnB,OAA+C;IAE/C,IAAI,KAAK,EAAE,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;QAC/B,SAAS,CAAC,6BAA6B,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;QAC3D,MAAM,MAAM,CAAA;IAChB,CAAC;IACD,GAAG,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAA;AAC3C,CAAC;AAGD,SAAS,SAAS,CAAC,GAAW,EAAE,GAAuB,EAAE,IAAmB,EAAE,MAAuB;IACjG,IAAI,GAAG,IAAI,IAAI;QAAE,OAAM;IACvB,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;QAChB,GAAG,CAAC,KAAK,CAAC;YACN,aAAa,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;SACpD,EAAE,GAAG,CAAC,CAAA;IACX,CAAC;IACD,IAAA,iCAAgB,EAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;AAC9C,CAAC;AAGD,SAAS,QAAQ,CAAC,IAAmB,EAAE,EAAC,aAAa,EAAiB;IAClE,IAAA,uCAA6B,EAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;IAE9E,IAAI,GAAG,GAAG,IAAA,+BAAqB,EAC3B,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,YAAY,CACpB,CAAA;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,+BAAe,EAAC,GAAG,EAAE;YAC/D,oBAAoB,EAAE,iBAAQ,CAAC,IAAI;SACtC,CAAC,CAAC,CAAA;IAEH,IAAI,GAAG,GAAG,GAAuB,CAAA;IACjC,IAAI,aAAa,IAAI,GAAG,CAAC,SAAS,CAAC,SAAS,IAAI,OAAO,EAAE,CAAC;QACtD,IAAI,KAAK,GAAG,IAAA,8BAAoB,EAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,CAAC,CAAA;QAC3D,IAAI,MAAM,GAAG,IAAA,uBAAa,EACtB,GAAG,EACH,KAAK,EACL,GAAG,CAAC,SAAS,CAAC,YAAY,EAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EACnB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CACtB,CAAA;QACD,IAAI,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAA;QAC5C,IAAI,WAAW,GAAG,aAAa,EAAE,CAAC;YAC9B,OAAQ;gBACJ,IAAI,mCAAc,CAAC,QAAQ,aAAa,iCAAiC,WAAW,EAAE,CAAC;aAC1F,CAAA;QACL,CAAC;IACL,CAAC;IAED,OAAO,EAAE,CAAA;AACb,CAAC"}
|
package/lib/util/limit.js
CHANGED
|
@@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ResponseSizeLimit = exports.Limit = void 0;
|
|
7
|
+
const apollo_server_core_1 = require("apollo-server-core");
|
|
7
8
|
const assert_1 = __importDefault(require("assert"));
|
|
8
|
-
const graphql_1 = require("graphql");
|
|
9
9
|
class Limit {
|
|
10
10
|
constructor(error, value) {
|
|
11
11
|
this.error = error;
|
|
@@ -28,7 +28,7 @@ class Limit {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
exports.Limit = Limit;
|
|
31
|
-
const SIZE_LIMIT = new
|
|
31
|
+
const SIZE_LIMIT = new apollo_server_core_1.UserInputError('response might exceed the size limit');
|
|
32
32
|
SIZE_LIMIT.stack = undefined;
|
|
33
33
|
class ResponseSizeLimit extends Limit {
|
|
34
34
|
constructor(maxNodes) {
|
package/lib/util/limit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"limit.js","sourceRoot":"","sources":["../../src/util/limit.ts"],"names":[],"mappings":";;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"limit.js","sourceRoot":"","sources":["../../src/util/limit.ts"],"names":[],"mappings":";;;;;;AAAA,2DAAiD;AACjD,oDAA2B;AAG3B,MAAa,KAAK;IACd,YAAoB,KAAY,EAAU,KAAa;QAAnC,UAAK,GAAL,KAAK,CAAO;QAAU,UAAK,GAAL,KAAK,CAAQ;QACnD,IAAA,gBAAM,EAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;IAC1B,CAAC;IAED,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAClC,CAAC;IAED,KAAK,CAAC,EAA4B;QAC9B,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC;YAAE,MAAM,IAAI,CAAC,KAAK,CAAA;QACpC,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACtC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,CAAC,KAAK,CAAA;QACpB,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACrB,CAAC;IACL,CAAC;CACJ;AAlBD,sBAkBC;AAGD,MAAM,UAAU,GAAG,IAAI,mCAAc,CAAC,sCAAsC,CAAC,CAAA;AAC7E,UAAU,CAAC,KAAK,GAAG,SAAS,CAAA;AAG5B,MAAa,iBAAkB,SAAQ,KAAK;IACxC,YAAY,QAAgB;QACxB,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;IAC/B,CAAC;CACJ;AAJD,8CAIC"}
|
package/package.json
CHANGED
package/src/context.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type {Logger} from '@subsquid/logger'
|
|
2
|
+
import type {Dialect} from './dialect'
|
|
3
|
+
import type {Query} from './sql/query'
|
|
4
|
+
import type {Limit} from './util/limit'
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
export interface Context {
|
|
@@ -9,9 +10,11 @@ export interface Context {
|
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
export interface OpenreaderContext {
|
|
13
|
+
id: number
|
|
12
14
|
dialect: Dialect
|
|
13
15
|
executeQuery<T>(query: Query<T>): Promise<T>
|
|
14
16
|
subscription<T>(query: Query<T>): AsyncIterable<T>
|
|
15
17
|
responseSizeLimit?: Limit
|
|
16
18
|
subscriptionResponseSizeLimit?: Limit
|
|
19
|
+
log?: Logger
|
|
17
20
|
}
|
package/src/db.ts
CHANGED
|
@@ -1,39 +1,33 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
import type {Logger} from '@subsquid/logger'
|
|
2
|
+
import {addErrorContext} from '@subsquid/util-internal'
|
|
3
|
+
import type {ClientBase, Pool} from 'pg'
|
|
4
|
+
import {QueryResult} from 'pg'
|
|
5
|
+
import {OpenreaderContext} from './context'
|
|
6
|
+
import {Dialect} from './dialect'
|
|
7
|
+
import {Query} from './sql/query'
|
|
8
|
+
import {Subscription} from './subscription'
|
|
9
|
+
import {LazyTransaction} from './util/lazy-transaction'
|
|
8
10
|
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
query(sql: string, parameters?: any[]): Promise<any[][]>
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export class PgDatabase implements Database {
|
|
16
|
-
constructor(private client: ClientBase) {}
|
|
17
|
-
|
|
18
|
-
query(sql: string, parameters?: any[]): Promise<any[][]> {
|
|
19
|
-
return this.client.query({text: sql, rowMode: 'array'}, parameters)
|
|
20
|
-
.then(result => result.rows)
|
|
21
|
-
.catch(withErrorContext({sql, parameters}))
|
|
22
|
-
}
|
|
23
|
-
}
|
|
12
|
+
let CTX_COUNTER = 0
|
|
24
13
|
|
|
25
14
|
|
|
26
15
|
export class PoolOpenreaderContext implements OpenreaderContext {
|
|
16
|
+
public id = (CTX_COUNTER = (CTX_COUNTER + 1) % Number.MAX_SAFE_INTEGER)
|
|
17
|
+
public log?: Logger
|
|
27
18
|
private tx: LazyTransaction<Database>
|
|
28
19
|
private subscriptionPool: Pool
|
|
20
|
+
private queryCounter = 0
|
|
29
21
|
|
|
30
22
|
constructor(
|
|
31
23
|
public readonly dialect: Dialect,
|
|
32
24
|
pool: Pool,
|
|
33
25
|
subscriptionPool?: Pool,
|
|
34
|
-
private subscriptionPollInterval: number = 1000
|
|
26
|
+
private subscriptionPollInterval: number = 1000,
|
|
27
|
+
log?: Logger
|
|
35
28
|
) {
|
|
36
|
-
this.
|
|
29
|
+
this.log = log?.child({graphqlCtx: this.id})
|
|
30
|
+
this.tx = new LazyTransaction(cb => this.transact(pool, cb))
|
|
37
31
|
this.subscriptionPool = subscriptionPool || pool
|
|
38
32
|
}
|
|
39
33
|
|
|
@@ -43,30 +37,67 @@ export class PoolOpenreaderContext implements OpenreaderContext {
|
|
|
43
37
|
|
|
44
38
|
async executeQuery<T>(query: Query<T>): Promise<T> {
|
|
45
39
|
let db = await this.tx.get()
|
|
46
|
-
let result = await db
|
|
40
|
+
let result = await db(query.sql, query.params)
|
|
47
41
|
return query.map(result)
|
|
48
42
|
}
|
|
49
43
|
|
|
50
44
|
subscription<T>(query: Query<T>): AsyncIterable<T> {
|
|
51
|
-
return new Subscription(this.subscriptionPollInterval, () => transact(this.subscriptionPool, async db => {
|
|
52
|
-
let result = await db
|
|
45
|
+
return new Subscription(this.subscriptionPollInterval, () => this.transact(this.subscriptionPool, async db => {
|
|
46
|
+
let result = await db(query.sql, query.params)
|
|
53
47
|
return query.map(result)
|
|
54
48
|
}))
|
|
55
49
|
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
50
|
|
|
59
|
-
async
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
await client.query('START TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY')
|
|
51
|
+
private async transact<T>(pool: Pool, cb: (db: Database) => Promise<T>): Promise<T> {
|
|
52
|
+
let client = await pool.connect()
|
|
63
53
|
try {
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
await this.query(client, 'START TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY')
|
|
55
|
+
try {
|
|
56
|
+
return await cb(async (sql, parameters) => {
|
|
57
|
+
let result = await this.query(client, sql, parameters)
|
|
58
|
+
return result.rows
|
|
59
|
+
})
|
|
60
|
+
} finally {
|
|
61
|
+
await this.query(client, 'COMMIT').catch(() => {})
|
|
62
|
+
}
|
|
66
63
|
} finally {
|
|
67
|
-
|
|
64
|
+
client.release()
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private async query(client: ClientBase, sql: string, parameters?: any[]): Promise<QueryResult> {
|
|
69
|
+
let queryId = this.queryCounter = (this.queryCounter + 1) % Number.MAX_SAFE_INTEGER
|
|
70
|
+
|
|
71
|
+
let ctx = {
|
|
72
|
+
graphqlCtx: this.id,
|
|
73
|
+
graphqlSqlQuery: queryId,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let log = this.log?.child('sql', ctx)
|
|
77
|
+
|
|
78
|
+
log?.debug({
|
|
79
|
+
sql,
|
|
80
|
+
parameters
|
|
81
|
+
}, 'sql query')
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
let result = await client.query({text: sql, rowMode: 'array'}, parameters)
|
|
85
|
+
log?.debug({
|
|
86
|
+
rowCount: result.rowCount || 0,
|
|
87
|
+
rows: log.isTrace() ? result.rows : undefined
|
|
88
|
+
}, 'sql result')
|
|
89
|
+
return result
|
|
90
|
+
} catch(err: any) {
|
|
91
|
+
throw addErrorContext(err, {
|
|
92
|
+
...ctx,
|
|
93
|
+
sql,
|
|
94
|
+
parameters
|
|
95
|
+
})
|
|
68
96
|
}
|
|
69
|
-
} finally {
|
|
70
|
-
client.release()
|
|
71
97
|
}
|
|
72
98
|
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
interface Database {
|
|
102
|
+
(sql: string, parameters?: any[]): Promise<any[][]>
|
|
103
|
+
}
|
package/src/server.ts
CHANGED
|
@@ -15,8 +15,7 @@ import {PoolOpenreaderContext} from './db'
|
|
|
15
15
|
import type {Dialect} from './dialect'
|
|
16
16
|
import type {Model} from './model'
|
|
17
17
|
import {SchemaBuilder} from './opencrud/schema'
|
|
18
|
-
import {
|
|
19
|
-
import {executeWithLimit} from './util/execute'
|
|
18
|
+
import {openreaderExecute, openreaderSubscribe} from './util/execute'
|
|
20
19
|
import {ResponseSizeLimit} from './util/limit'
|
|
21
20
|
|
|
22
21
|
|
|
@@ -38,7 +37,15 @@ export interface ServerOptions {
|
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
export async function serve(options: ServerOptions): Promise<ListeningServer> {
|
|
41
|
-
let {
|
|
40
|
+
let {
|
|
41
|
+
connection,
|
|
42
|
+
subscriptionConnection,
|
|
43
|
+
subscriptionPollInterval,
|
|
44
|
+
maxResponseNodes,
|
|
45
|
+
subscriptionMaxResponseNodes,
|
|
46
|
+
log
|
|
47
|
+
} = options
|
|
48
|
+
|
|
42
49
|
let dialect = options.dialect ?? 'postgres'
|
|
43
50
|
|
|
44
51
|
let schema = new SchemaBuilder(options).build()
|
|
@@ -48,7 +55,8 @@ export async function serve(options: ServerOptions): Promise<ListeningServer> {
|
|
|
48
55
|
dialect,
|
|
49
56
|
connection,
|
|
50
57
|
subscriptionConnection,
|
|
51
|
-
subscriptionPollInterval
|
|
58
|
+
subscriptionPollInterval,
|
|
59
|
+
log
|
|
52
60
|
)
|
|
53
61
|
|
|
54
62
|
if (maxResponseNodes) {
|
|
@@ -107,9 +115,9 @@ export async function runApollo(options: ApolloOptions): Promise<ListeningServer
|
|
|
107
115
|
let app = express()
|
|
108
116
|
let server = http.createServer(app)
|
|
109
117
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
118
|
+
let execute = (args: ExecutionArgs) => openreaderExecute(args, {
|
|
119
|
+
maxRootFields: maxRootFields
|
|
120
|
+
})
|
|
113
121
|
|
|
114
122
|
if (options.subscriptions) {
|
|
115
123
|
let wsServer = new WebSocketServer({
|
|
@@ -122,14 +130,7 @@ export async function runApollo(options: ApolloOptions): Promise<ListeningServer
|
|
|
122
130
|
schema,
|
|
123
131
|
context,
|
|
124
132
|
execute,
|
|
125
|
-
|
|
126
|
-
if (log) {
|
|
127
|
-
// FIXME: we don't want to log client errors
|
|
128
|
-
for (let err of errors) {
|
|
129
|
-
logGraphQLError(log, err)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
+
subscribe: openreaderSubscribe,
|
|
133
134
|
onNext(_ctx, _message, args, result) {
|
|
134
135
|
args.contextValue.openreader.close()
|
|
135
136
|
return result
|
|
@@ -147,7 +148,7 @@ export async function runApollo(options: ApolloOptions): Promise<ListeningServer
|
|
|
147
148
|
cache: options.cache,
|
|
148
149
|
stopOnTerminationSignals: false,
|
|
149
150
|
allowBatchedHttpRequests: false,
|
|
150
|
-
executor:
|
|
151
|
+
executor: async req => {
|
|
151
152
|
return execute({
|
|
152
153
|
schema,
|
|
153
154
|
document: req.document,
|
|
@@ -156,7 +157,7 @@ export async function runApollo(options: ApolloOptions): Promise<ListeningServer
|
|
|
156
157
|
variableValues: req.request.variables,
|
|
157
158
|
operationName: req.operationName
|
|
158
159
|
})
|
|
159
|
-
}
|
|
160
|
+
},
|
|
160
161
|
plugins: [
|
|
161
162
|
...options.plugins || [],
|
|
162
163
|
{
|
|
@@ -164,13 +165,6 @@ export async function runApollo(options: ApolloOptions): Promise<ListeningServer
|
|
|
164
165
|
return {
|
|
165
166
|
willSendResponse(req: any) {
|
|
166
167
|
return req.context.openreader.close()
|
|
167
|
-
},
|
|
168
|
-
async didEncounterErrors(req) {
|
|
169
|
-
if (req.operation && log) {
|
|
170
|
-
for (let err of req.errors) {
|
|
171
|
-
logGraphQLError(log, err)
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
168
|
}
|
|
175
169
|
}
|
|
176
170
|
}
|
package/src/test/limits.test.ts
CHANGED
package/src/test/setup.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {createLogger} from '@subsquid/logger'
|
|
1
2
|
import {assertNotNull} from "@subsquid/util-internal"
|
|
2
3
|
import {ListeningServer} from "@subsquid/util-internal-http-server"
|
|
3
4
|
import {Client} from "gql-test-client"
|
|
@@ -72,6 +73,7 @@ export function useServer(schema: string, options?: Partial<ServerOptions>): Cli
|
|
|
72
73
|
subscriptions: true,
|
|
73
74
|
subscriptionPollInterval: 500,
|
|
74
75
|
maxRootFields: 10,
|
|
76
|
+
// log: createLogger('sqd:openreader'),
|
|
75
77
|
...options
|
|
76
78
|
})
|
|
77
79
|
client.endpoint = `http://localhost:${info.port}/graphql`
|
|
@@ -1,40 +1,50 @@
|
|
|
1
|
-
import {Logger, LogLevel} from
|
|
2
|
-
import {
|
|
1
|
+
import {Logger, LogLevel} from '@subsquid/logger'
|
|
2
|
+
import {weakMemo} from '@subsquid/util-internal'
|
|
3
|
+
import {ExecutionArgs, GraphQLError, print} from 'graphql'
|
|
3
4
|
|
|
4
5
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
graphqlOriginalError: err.originalError,
|
|
10
|
-
graphqlPath: err.path?.join('.'),
|
|
11
|
-
graphqlQuery: err.source?.body,
|
|
12
|
-
}, msg)
|
|
6
|
+
export interface DocumentCtx {
|
|
7
|
+
graphqlOperationName?: string
|
|
8
|
+
graphqlDocument: string
|
|
9
|
+
graphqlVariables: any
|
|
13
10
|
}
|
|
14
11
|
|
|
15
12
|
|
|
16
|
-
export
|
|
17
|
-
return
|
|
18
|
-
|
|
13
|
+
export const getDocumentCtx = weakMemo((args: ExecutionArgs): DocumentCtx => {
|
|
14
|
+
return {
|
|
15
|
+
graphqlOperationName: args.operationName || undefined,
|
|
16
|
+
graphqlDocument: print(args.document),
|
|
17
|
+
graphqlVariables: args.variableValues
|
|
19
18
|
}
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
export function logGraphQLErrors(
|
|
23
|
+
log: Logger,
|
|
24
|
+
args: ExecutionArgs,
|
|
25
|
+
errors: readonly GraphQLError[] | undefined,
|
|
26
|
+
): void {
|
|
27
|
+
if (!errors?.length) return
|
|
28
|
+
let level = 0
|
|
29
|
+
let graphqlErrors = errors.map(err => {
|
|
30
|
+
level = Math.max(level, getErrorLevel(err))
|
|
31
|
+
return {
|
|
32
|
+
message: err.message,
|
|
33
|
+
path: err.path?.join('.'),
|
|
34
|
+
extensions: err.extensions,
|
|
35
|
+
originalError: err.originalError
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
if (log.level > level) return
|
|
39
|
+
log.write(level, {
|
|
40
|
+
graphqlErrors,
|
|
41
|
+
...getDocumentCtx(args)
|
|
42
|
+
}, 'graphql query ended with errors')
|
|
20
43
|
}
|
|
21
44
|
|
|
22
45
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export function ensureError(err: unknown): Error {
|
|
31
|
-
if (err instanceof Error) return err
|
|
32
|
-
return new NonErrorThrown(err)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
export class NonErrorThrown extends Error {
|
|
37
|
-
constructor(public readonly value: unknown) {
|
|
38
|
-
super('Non error object thrown')
|
|
39
|
-
}
|
|
46
|
+
function getErrorLevel(err: GraphQLError): LogLevel {
|
|
47
|
+
if ((err as any).__openreaderLogLevel) return (err as any).__openreaderLogLevel
|
|
48
|
+
if (err.extensions?.code === 'BAD_USER_INPUT') return LogLevel.WARN
|
|
49
|
+
return LogLevel.ERROR
|
|
40
50
|
}
|
package/src/util/execute.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
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 {
|
|
14
|
+
import {getDocumentCtx, logGraphQLErrors} from './error-handling'
|
|
12
15
|
|
|
13
16
|
|
|
14
|
-
export
|
|
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
|
-
|
|
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 >
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
|
|
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
|
|
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
|
|
26
|
+
const SIZE_LIMIT = new UserInputError('response might exceed the size limit')
|
|
27
27
|
SIZE_LIMIT.stack = undefined
|
|
28
28
|
|
|
29
29
|
|