@subsquid/openreader 1.0.1 → 2.0.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 (279) hide show
  1. package/bin/main.js +2 -1
  2. package/lib/context.d.ts +11 -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 +3 -0
  27. package/lib/limit.size.d.ts.map +1 -0
  28. package/lib/limit.size.js +44 -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 +53 -0
  33. package/lib/main.js.map +1 -0
  34. package/{dist → lib}/model.d.ts +10 -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} +44 -7
  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 +522 -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 +38 -0
  83. package/lib/server.d.ts.map +1 -0
  84. package/lib/server.js +146 -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/{dist → lib}/test/lists.test.d.ts +0 -0
  127. package/{dist → lib}/test/lists.test.d.ts.map +0 -0
  128. package/{dist → lib}/test/lists.test.js +0 -0
  129. package/{dist → lib}/test/lists.test.js.map +0 -0
  130. package/{dist → lib}/test/lookup.test.d.ts +0 -0
  131. package/{dist → lib}/test/lookup.test.d.ts.map +0 -0
  132. package/{dist → lib}/test/lookup.test.js +0 -0
  133. package/{dist → lib}/test/lookup.test.js.map +0 -0
  134. package/{dist → lib}/test/regressions.test.d.ts +0 -0
  135. package/{dist → lib}/test/regressions.test.d.ts.map +0 -0
  136. package/{dist → lib}/test/regressions.test.js +0 -0
  137. package/{dist → lib}/test/regressions.test.js.map +0 -0
  138. package/{dist → lib}/test/scalars.test.d.ts +0 -0
  139. package/{dist → lib}/test/scalars.test.d.ts.map +0 -0
  140. package/{dist → lib}/test/scalars.test.js +0 -0
  141. package/{dist → lib}/test/scalars.test.js.map +0 -0
  142. package/{dist → lib}/test/setup.d.ts +3 -1
  143. package/lib/test/setup.d.ts.map +1 -0
  144. package/{dist → lib}/test/setup.js +14 -12
  145. package/lib/test/setup.js.map +1 -0
  146. package/lib/test/subscription.test.d.ts +2 -0
  147. package/lib/test/subscription.test.d.ts.map +1 -0
  148. package/lib/test/subscription.test.js +99 -0
  149. package/lib/test/subscription.test.js.map +1 -0
  150. package/{dist → lib}/test/tools.test.d.ts +0 -0
  151. package/{dist → lib}/test/tools.test.d.ts.map +0 -0
  152. package/{dist → lib}/test/tools.test.js +0 -0
  153. package/{dist → lib}/test/tools.test.js.map +0 -0
  154. package/{dist → lib}/test/typed-json.test.d.ts +0 -0
  155. package/{dist → lib}/test/typed-json.test.d.ts.map +0 -0
  156. package/{dist → lib}/test/typed-json.test.js +0 -0
  157. package/{dist → lib}/test/typed-json.test.js.map +0 -0
  158. package/{dist → lib}/test/unions.test.d.ts +0 -0
  159. package/{dist → lib}/test/unions.test.d.ts.map +0 -0
  160. package/{dist → lib}/test/unions.test.js +0 -0
  161. package/{dist → lib}/test/unions.test.js.map +0 -0
  162. package/{dist → lib}/test/where.test.d.ts +0 -0
  163. package/{dist → lib}/test/where.test.d.ts.map +0 -0
  164. package/{dist → lib}/test/where.test.js +0 -0
  165. package/{dist → lib}/test/where.test.js.map +0 -0
  166. package/{dist → lib}/tools.d.ts +0 -0
  167. package/{dist → lib}/tools.d.ts.map +0 -0
  168. package/{dist → lib}/tools.js +3 -3
  169. package/{dist → lib}/tools.js.map +1 -1
  170. package/lib/util/error-handling.d.ts +11 -0
  171. package/lib/util/error-handling.d.ts.map +1 -0
  172. package/lib/util/error-handling.js +42 -0
  173. package/lib/util/error-handling.js.map +1 -0
  174. package/lib/util/lazy-transaction.d.ts +10 -0
  175. package/lib/util/lazy-transaction.d.ts.map +1 -0
  176. package/lib/util/lazy-transaction.js +43 -0
  177. package/lib/util/lazy-transaction.js.map +1 -0
  178. package/lib/util/resolve-tree.d.ts +14 -0
  179. package/lib/util/resolve-tree.d.ts.map +1 -0
  180. package/lib/util/resolve-tree.js +52 -0
  181. package/lib/util/resolve-tree.js.map +1 -0
  182. package/{dist → lib/util}/util.d.ts +2 -3
  183. package/lib/util/util.d.ts.map +1 -0
  184. package/{dist → lib/util}/util.js +9 -13
  185. package/lib/util/util.js.map +1 -0
  186. package/package.json +17 -9
  187. package/src/context.ts +14 -0
  188. package/src/db.ts +46 -57
  189. package/src/ir/args.ts +85 -0
  190. package/src/ir/connection.ts +48 -0
  191. package/src/ir/fields.ts +40 -0
  192. package/src/limit.size.ts +46 -0
  193. package/src/main.ts +62 -37
  194. package/src/{gql/schema.ts → model.schema.ts} +51 -8
  195. package/src/model.ts +12 -1
  196. package/src/{orderBy.ts → opencrud/orderBy.ts} +3 -10
  197. package/src/opencrud/schema.ts +632 -0
  198. package/src/opencrud/tree.ts +144 -0
  199. package/src/opencrud/where.ts +141 -0
  200. package/src/{gql/scalars → scalars}/BigInt.ts +1 -1
  201. package/src/{gql/scalars → scalars}/Bytes.ts +4 -4
  202. package/src/{gql/scalars → scalars}/DateTime.ts +1 -1
  203. package/src/{gql/scalars → scalars}/JSON.ts +0 -0
  204. package/src/{gql/scalars → scalars}/index.ts +0 -0
  205. package/src/server.ts +128 -48
  206. package/src/sql/cursor.ts +291 -0
  207. package/src/sql/mapping.ts +66 -0
  208. package/src/sql/printer.ts +328 -0
  209. package/src/sql/query.ts +194 -0
  210. package/src/sql/util.ts +89 -0
  211. package/src/subscription.ts +46 -0
  212. package/src/test/fts.test.ts +1 -1
  213. package/src/test/setup.ts +12 -10
  214. package/src/test/subscription.test.ts +98 -0
  215. package/src/tools.ts +1 -1
  216. package/src/util/error-handling.ts +40 -0
  217. package/src/util/lazy-transaction.ts +49 -0
  218. package/src/util/resolve-tree.ts +65 -0
  219. package/src/{util.ts → util/util.ts} +9 -14
  220. package/dist/db.d.ts +0 -28
  221. package/dist/db.d.ts.map +0 -1
  222. package/dist/db.js +0 -69
  223. package/dist/db.js.map +0 -1
  224. package/dist/gql/opencrud.d.ts +0 -6
  225. package/dist/gql/opencrud.d.ts.map +0 -1
  226. package/dist/gql/opencrud.js +0 -326
  227. package/dist/gql/opencrud.js.map +0 -1
  228. package/dist/gql/scalars/BigInt.d.ts.map +0 -1
  229. package/dist/gql/scalars/BigInt.js.map +0 -1
  230. package/dist/gql/scalars/Bytes.d.ts.map +0 -1
  231. package/dist/gql/scalars/Bytes.js.map +0 -1
  232. package/dist/gql/scalars/DateTime.d.ts.map +0 -1
  233. package/dist/gql/scalars/DateTime.js.map +0 -1
  234. package/dist/gql/scalars/JSON.d.ts.map +0 -1
  235. package/dist/gql/scalars/JSON.js.map +0 -1
  236. package/dist/gql/scalars/index.d.ts.map +0 -1
  237. package/dist/gql/scalars/index.js.map +0 -1
  238. package/dist/gql/schema.d.ts.map +0 -1
  239. package/dist/gql/schema.js.map +0 -1
  240. package/dist/main.js +0 -43
  241. package/dist/main.js.map +0 -1
  242. package/dist/model.d.ts.map +0 -1
  243. package/dist/orderBy.d.ts.map +0 -1
  244. package/dist/orderBy.js.map +0 -1
  245. package/dist/queryBuilder.d.ts +0 -56
  246. package/dist/queryBuilder.d.ts.map +0 -1
  247. package/dist/queryBuilder.js +0 -733
  248. package/dist/queryBuilder.js.map +0 -1
  249. package/dist/relayConnection.d.ts +0 -37
  250. package/dist/relayConnection.d.ts.map +0 -1
  251. package/dist/relayConnection.js +0 -43
  252. package/dist/relayConnection.js.map +0 -1
  253. package/dist/requestedFields.d.ts +0 -33
  254. package/dist/requestedFields.d.ts.map +0 -1
  255. package/dist/requestedFields.js +0 -179
  256. package/dist/requestedFields.js.map +0 -1
  257. package/dist/resolver.d.ts +0 -9
  258. package/dist/resolver.d.ts.map +0 -1
  259. package/dist/resolver.js +0 -158
  260. package/dist/resolver.js.map +0 -1
  261. package/dist/server.d.ts +0 -22
  262. package/dist/server.d.ts.map +0 -1
  263. package/dist/server.js +0 -96
  264. package/dist/server.js.map +0 -1
  265. package/dist/test/fts.test.js.map +0 -1
  266. package/dist/test/setup.d.ts.map +0 -1
  267. package/dist/test/setup.js.map +0 -1
  268. package/dist/util.d.ts.map +0 -1
  269. package/dist/util.js.map +0 -1
  270. package/dist/where.d.ts +0 -9
  271. package/dist/where.d.ts.map +0 -1
  272. package/dist/where.js +0 -101
  273. package/dist/where.js.map +0 -1
  274. package/src/gql/opencrud.ts +0 -350
  275. package/src/queryBuilder.ts +0 -891
  276. package/src/relayConnection.ts +0 -80
  277. package/src/requestedFields.ts +0 -246
  278. package/src/resolver.ts +0 -201
  279. package/src/where.ts +0 -119
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.hasTreeRequest = exports.getTreeRequest = exports.getResolveTree = exports.simplifyResolveTree = void 0;
7
+ const apollo_server_core_1 = require("apollo-server-core");
8
+ const assert_1 = __importDefault(require("assert"));
9
+ const graphql_parse_resolve_info_1 = require("graphql-parse-resolve-info");
10
+ function simplifyResolveTree(schema, tree, typeName) {
11
+ let type = schema.getType(typeName);
12
+ (0, assert_1.default)(type != null);
13
+ return (0, graphql_parse_resolve_info_1.simplifyParsedResolveInfoFragmentWithType)(tree, type);
14
+ }
15
+ exports.simplifyResolveTree = simplifyResolveTree;
16
+ function getResolveTree(info, typeName) {
17
+ let tree = (0, graphql_parse_resolve_info_1.parseResolveInfo)(info);
18
+ (0, assert_1.default)(isResolveTree(tree));
19
+ if (typeName) {
20
+ return simplifyResolveTree(info.schema, tree, typeName);
21
+ }
22
+ else {
23
+ return tree;
24
+ }
25
+ }
26
+ exports.getResolveTree = getResolveTree;
27
+ function isResolveTree(resolveInfo) {
28
+ return resolveInfo != null && resolveInfo.fieldsByTypeName != null;
29
+ }
30
+ function getTreeRequest(treeFields, fieldName) {
31
+ let req;
32
+ for (let alias in treeFields) {
33
+ let e = treeFields[alias];
34
+ if (e.name != fieldName)
35
+ continue;
36
+ if (req != null)
37
+ throw new apollo_server_core_1.UserInputError(`multiple aliases for field '${fieldName}' are not supported`);
38
+ req = e;
39
+ }
40
+ return req;
41
+ }
42
+ exports.getTreeRequest = getTreeRequest;
43
+ function hasTreeRequest(treeFields, fieldName) {
44
+ for (let alias in treeFields) {
45
+ let e = treeFields[alias];
46
+ if (e.name == fieldName)
47
+ return true;
48
+ }
49
+ return false;
50
+ }
51
+ exports.hasTreeRequest = hasTreeRequest;
52
+ //# sourceMappingURL=resolve-tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-tree.js","sourceRoot":"","sources":["../../src/util/resolve-tree.ts"],"names":[],"mappings":";;;;;;AAAA,2DAAiD;AACjD,oDAA2B;AAE3B,2EAKmC;AAanC,SAAgB,mBAAmB,CAAC,MAAqB,EAAE,IAAiB,EAAE,QAAgB;IAC1F,IAAI,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACnC,IAAA,gBAAM,EAAC,IAAI,IAAI,IAAI,CAAC,CAAA;IACpB,OAAO,IAAA,sEAAyC,EAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AAChE,CAAC;AAJD,kDAIC;AAKD,SAAgB,cAAc,CAAC,IAAwB,EAAE,QAAiB;IACtE,IAAI,IAAI,GAAG,IAAA,6CAAgB,EAAC,IAAI,CAAC,CAAA;IACjC,IAAA,gBAAM,EAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3B,IAAI,QAAQ,EAAE;QACV,OAAO,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;KAC1D;SAAM;QACH,OAAO,IAAI,CAAA;KACd;AACL,CAAC;AARD,wCAQC;AAGD,SAAS,aAAa,CAAC,WAA8D;IACjF,OAAO,WAAW,IAAI,IAAI,IAAI,WAAW,CAAC,gBAAgB,IAAI,IAAI,CAAA;AACtE,CAAC;AAGD,SAAgB,cAAc,CAAC,UAA6B,EAAE,SAAiB;IAC3E,IAAI,GAA4B,CAAA;IAChC,KAAK,IAAI,KAAK,IAAI,UAAU,EAAE;QAC1B,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QACzB,IAAI,CAAC,CAAC,IAAI,IAAI,SAAS;YAAE,SAAQ;QACjC,IAAI,GAAG,IAAI,IAAI;YAAE,MAAM,IAAI,mCAAc,CAAC,+BAA+B,SAAS,qBAAqB,CAAC,CAAA;QACxG,GAAG,GAAG,CAAC,CAAA;KACV;IACD,OAAO,GAAG,CAAA;AACd,CAAC;AATD,wCASC;AAGD,SAAgB,cAAc,CAAC,UAA6B,EAAE,SAAiB;IAC3E,KAAK,IAAI,KAAK,IAAI,UAAU,EAAE;QAC1B,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QACzB,IAAI,CAAC,CAAC,IAAI,IAAI,SAAS;YAAE,OAAO,IAAI,CAAA;KACvC;IACD,OAAO,KAAK,CAAA;AAChB,CAAC;AAND,wCAMC"}
@@ -1,9 +1,8 @@
1
- export declare function toQueryListField(entityName: string): string;
2
1
  export declare function toColumn(gqlFieldName: string): string;
3
2
  export declare function toFkColumn(gqlFieldName: string): string;
4
3
  export declare function toTable(entityName: string): string;
5
4
  export declare function ensureArray<T>(item: T | T[]): T[];
6
- export declare function unsupportedCase(value: string): Error;
7
- export declare function toInt(val: number | string): number;
5
+ export declare function toSafeInteger(s: number | string): number;
8
6
  export declare function invalidFormat(type: string, value: string): Error;
7
+ export declare function identity<T>(x: T): T;
9
8
  //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util/util.ts"],"names":[],"mappings":"AAIA,wBAAgB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAErD;AAGD,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEvD;AAGD,wBAAgB,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAElD;AAGD,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,CAEjD;AAGD,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAIxD;AAGD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAEhE;AAGD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAEnC"}
@@ -3,13 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.invalidFormat = exports.toInt = exports.unsupportedCase = exports.ensureArray = exports.toTable = exports.toFkColumn = exports.toColumn = exports.toQueryListField = void 0;
6
+ exports.identity = exports.invalidFormat = exports.toSafeInteger = exports.ensureArray = exports.toTable = exports.toFkColumn = exports.toColumn = void 0;
7
7
  const util_naming_1 = require("@subsquid/util-naming");
8
8
  const assert_1 = __importDefault(require("assert"));
9
- function toQueryListField(entityName) {
10
- return (0, util_naming_1.toPlural)((0, util_naming_1.toCamelCase)(entityName));
11
- }
12
- exports.toQueryListField = toQueryListField;
13
9
  function toColumn(gqlFieldName) {
14
10
  return (0, util_naming_1.toSnakeCase)(gqlFieldName);
15
11
  }
@@ -26,18 +22,18 @@ function ensureArray(item) {
26
22
  return Array.isArray(item) ? item : [item];
27
23
  }
28
24
  exports.ensureArray = ensureArray;
29
- function unsupportedCase(value) {
30
- return new Error(`Unsupported case: ${value}`);
31
- }
32
- exports.unsupportedCase = unsupportedCase;
33
- function toInt(val) {
34
- let i = parseInt(val);
35
- (0, assert_1.default)(!isNaN(i) && isFinite(i));
25
+ function toSafeInteger(s) {
26
+ let i = parseInt(s, 10);
27
+ (0, assert_1.default)(Number.isSafeInteger(i));
36
28
  return i;
37
29
  }
38
- exports.toInt = toInt;
30
+ exports.toSafeInteger = toSafeInteger;
39
31
  function invalidFormat(type, value) {
40
32
  return new TypeError(`Not a ${type}: ${value}`);
41
33
  }
42
34
  exports.invalidFormat = invalidFormat;
35
+ function identity(x) {
36
+ return x;
37
+ }
38
+ exports.identity = identity;
43
39
  //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util/util.ts"],"names":[],"mappings":";;;;;;AAAA,uDAAiD;AACjD,oDAA2B;AAG3B,SAAgB,QAAQ,CAAC,YAAoB;IACzC,OAAO,IAAA,yBAAW,EAAC,YAAY,CAAC,CAAA;AACpC,CAAC;AAFD,4BAEC;AAGD,SAAgB,UAAU,CAAC,YAAoB;IAC3C,OAAO,IAAA,yBAAW,EAAC,YAAY,CAAC,GAAG,KAAK,CAAA;AAC5C,CAAC;AAFD,gCAEC;AAGD,SAAgB,OAAO,CAAC,UAAkB;IACtC,OAAO,IAAA,yBAAW,EAAC,UAAU,CAAC,CAAA;AAClC,CAAC;AAFD,0BAEC;AAGD,SAAgB,WAAW,CAAI,IAAa;IACxC,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AAC9C,CAAC;AAFD,kCAEC;AAGD,SAAgB,aAAa,CAAC,CAAkB;IAC5C,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAW,EAAE,EAAE,CAAC,CAAA;IACjC,IAAA,gBAAM,EAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IAC/B,OAAO,CAAC,CAAA;AACZ,CAAC;AAJD,sCAIC;AAGD,SAAgB,aAAa,CAAC,IAAY,EAAE,KAAa;IACrD,OAAO,IAAI,SAAS,CAAC,SAAS,IAAI,KAAK,KAAK,EAAE,CAAC,CAAA;AACnD,CAAC;AAFD,sCAEC;AAGD,SAAgB,QAAQ,CAAI,CAAI;IAC5B,OAAO,CAAC,CAAA;AACZ,CAAC;AAFD,4BAEC"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@subsquid/openreader",
3
- "version": "1.0.1",
4
- "description": "GraphQL server for squid framework",
3
+ "version": "2.0.0",
4
+ "description": "GraphQL server for postgres-compatible databases",
5
5
  "keywords": [
6
6
  "graphql",
7
- "opencrud"
7
+ "opencrud",
8
+ "postgres"
8
9
  ],
9
10
  "license": "GPL-3.0-or-later",
10
11
  "repository": "git@github.com:subsquid/squid.git",
@@ -16,29 +17,36 @@
16
17
  },
17
18
  "files": [
18
19
  "bin",
19
- "dist",
20
+ "lib",
20
21
  "src"
21
22
  ],
22
23
  "dependencies": {
23
24
  "@graphql-tools/merge": "^8",
24
- "@graphql-tools/utils": "^8",
25
25
  "@subsquid/graphiql-console": "^0.2.0",
26
+ "@subsquid/logger": "^0.1.0",
26
27
  "@subsquid/util-internal": "^0.0.1",
27
- "@subsquid/util-internal-code-printer": "^0.0.1",
28
- "@subsquid/util-naming": "^0.0.1",
28
+ "@subsquid/util-internal-commander": "^0.0.0",
29
29
  "@subsquid/util-internal-hex": "^0.0.1",
30
+ "@subsquid/util-internal-http-server": "^0.1.0",
31
+ "@subsquid/util-naming": "^0.0.1",
30
32
  "apollo-server-core": "^3.9.0",
31
33
  "apollo-server-express": "^3.9.0",
34
+ "commander": "^9.3.0",
35
+ "deep-equal": "^2.0.5",
32
36
  "express": "^4.18.1",
33
37
  "graphql": "^15.8.0",
34
38
  "graphql-parse-resolve-info": "^4.12.3",
35
- "pg": "^8.7.3"
39
+ "graphql-ws": "^5.9.1",
40
+ "pg": "^8.7.3",
41
+ "ws": "^8.8.1"
36
42
  },
37
43
  "devDependencies": {
44
+ "@types/deep-equal": "^1.0.1",
38
45
  "@types/express": "^4.17.13",
39
46
  "@types/mocha": "^9.1.1",
40
47
  "@types/node": "^16.11.41",
41
- "@types/pg": "8.6.5",
48
+ "@types/pg": "^8.6.5",
49
+ "@types/ws": "^8.5.3",
42
50
  "dotenv": "^10.0.0",
43
51
  "expect": "^27.5.1",
44
52
  "gql-test-client": "^0.0.0",
package/src/context.ts ADDED
@@ -0,0 +1,14 @@
1
+ import {Dialect} from "./dialect"
2
+ import {Query} from "./sql/query"
3
+
4
+
5
+ export interface Context {
6
+ openreader: OpenreaderContext
7
+ }
8
+
9
+
10
+ export interface OpenreaderContext {
11
+ dialect: Dialect
12
+ executeQuery<T>(query: Query<T>): Promise<T>
13
+ subscription<T>(query: Query<T>): AsyncIterable<T>
14
+ }
package/src/db.ts CHANGED
@@ -1,83 +1,72 @@
1
- import type {ClientBase, Pool, PoolClient, PoolConfig} from "pg"
1
+ import type {ClientBase, Pool} from "pg"
2
+ import {OpenreaderContext} from "./context"
3
+ import {Dialect} from "./dialect"
4
+ import {Query} from "./sql/query"
5
+ import {Subscription} from "./subscription"
6
+ import {withErrorContext} from "./util/error-handling"
7
+ import {LazyTransaction} from "./util/lazy-transaction"
2
8
 
3
9
 
4
10
  export interface Database {
5
11
  query(sql: string, parameters?: any[]): Promise<any[][]>
6
- escapeIdentifier(name: string): string
7
- }
8
-
9
-
10
- /**
11
- * This is an interface OpenReader uses to interact with underling database.
12
- */
13
- export interface Transaction {
14
- get(): Promise<Database>
15
12
  }
16
13
 
17
14
 
18
15
  export class PgDatabase implements Database {
19
16
  constructor(private client: ClientBase) {}
20
17
 
21
- query(sql: string, parameters?: any[]): Promise<any[]> {
22
- return this.client.query({text: sql, rowMode: 'array'}, parameters).then(result => result.rows)
23
- }
24
-
25
- escapeIdentifier(name: string): string {
26
- return this.client.escapeIdentifier(name)
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}))
27
22
  }
28
23
  }
29
24
 
30
25
 
31
- export class PoolTransaction implements Transaction {
32
- private tx: Promise<{client: PoolClient, db: Database}> | undefined
33
- private closed = false
26
+ export class PoolOpenreaderContext implements OpenreaderContext {
27
+ private tx: LazyTransaction<Database>
28
+ private subscriptionPool: Pool
34
29
 
35
- constructor(private pool: Pool) {}
30
+ constructor(
31
+ public readonly dialect: Dialect,
32
+ pool: Pool,
33
+ subscriptionPool?: Pool,
34
+ private subscriptionPollInterval: number = 1000
35
+ ) {
36
+ this.tx = new LazyTransaction(cb => transact(pool, cb))
37
+ this.subscriptionPool = subscriptionPool || pool
38
+ }
36
39
 
37
- async get(): Promise<Database> {
38
- if (this.closed) {
39
- throw new Error('Too late to request transaction')
40
- }
41
- this.tx = this.tx || this.startTransaction()
42
- let {db} = await this.tx
43
- return db
40
+ close(): Promise<void> {
41
+ return this.tx.close()
44
42
  }
45
43
 
46
- private async startTransaction(): Promise<{client: PoolClient, db: Database}> {
47
- let client = await this.pool.connect()
48
- try {
49
- await client.query('START TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY')
50
- return {
51
- client,
52
- db: new PgDatabase(client)
53
- }
54
- } catch(e: any) {
55
- client.release()
56
- throw e
57
- }
44
+ async executeQuery<T>(query: Query<T>): Promise<T> {
45
+ let db = await this.tx.get()
46
+ let result = await db.query(query.sql, query.params)
47
+ return query.map(result)
58
48
  }
59
49
 
60
- close(): Promise<void> {
61
- this.closed = true
62
- return this.tx?.then(async ({client}) => {
63
- try {
64
- await client.query('COMMIT')
65
- } catch(e: any) {
66
- // ignore
67
- } finally {
68
- client.release()
69
- }
70
- }) || Promise.resolve()
50
+ subscription<T>(query: Query<T>): AsyncIterable<T> {
51
+ return new Subscription(this.subscriptionPollInterval, () => transact(this.subscriptionPool, async db => {
52
+ let result = await db.query(query.sql, query.params)
53
+ return query.map(result)
54
+ }))
71
55
  }
72
56
  }
73
57
 
74
58
 
75
- export function createPoolConfig(): PoolConfig {
76
- return {
77
- host: process.env.DB_HOST || 'localhost',
78
- port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 5432,
79
- database: process.env.DB_NAME || 'postgres',
80
- user: process.env.DB_USER || 'postgres',
81
- password: process.env.DB_PASS || 'postgres'
59
+ async function transact<T>(pool: Pool, cb: (db: Database) => Promise<T>): Promise<T> {
60
+ let client = await pool.connect()
61
+ try {
62
+ await client.query('START TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY')
63
+ try {
64
+ let db = new PgDatabase(client)
65
+ return await cb(db)
66
+ } finally {
67
+ await client.query('COMMIT').catch(() => {})
68
+ }
69
+ } finally {
70
+ client.release()
82
71
  }
83
72
  }
package/src/ir/args.ts ADDED
@@ -0,0 +1,85 @@
1
+ export interface EntityListArguments {
2
+ offset?: number
3
+ limit?: number
4
+ orderBy?: OrderBy
5
+ where?: Where
6
+ }
7
+
8
+
9
+ export type Where = AndCondition | OrCondition | InCondition | SetCondition | RefCondition | BinaryCondition | UnaryCondition
10
+
11
+
12
+ export interface AndCondition {
13
+ op: 'AND'
14
+ args: Where[]
15
+ }
16
+
17
+
18
+ export interface OrCondition {
19
+ op: 'OR'
20
+ args: Where[]
21
+ }
22
+
23
+
24
+ export interface SetCondition {
25
+ op: 'some' | 'every' | 'none'
26
+ field: string
27
+ where?: Where
28
+ }
29
+
30
+
31
+ export interface RefCondition {
32
+ op: 'REF'
33
+ field: string
34
+ where: Where
35
+ }
36
+
37
+
38
+ export interface InCondition {
39
+ op: 'in' | 'not_in'
40
+ field: string
41
+ values: unknown[]
42
+ }
43
+
44
+
45
+ export interface BinaryCondition {
46
+ op: BinaryOp
47
+ field: string
48
+ value: unknown
49
+ }
50
+
51
+
52
+ export interface UnaryCondition {
53
+ op: UnaryOp
54
+ field: string
55
+ yes: boolean
56
+ }
57
+
58
+
59
+ export type BinaryOp =
60
+ 'eq' |
61
+ 'not_eq' |
62
+ 'gt' |
63
+ 'gte' |
64
+ 'lt' |
65
+ 'lte' |
66
+ 'contains' | 'not_contains' |
67
+ 'containsInsensitive' | 'not_containsInsensitive' |
68
+ 'startsWith' | 'not_startsWith' |
69
+ 'endsWith' | 'not_endsWith' |
70
+ 'containsAll' |
71
+ 'containsAny' |
72
+ 'containsNone' |
73
+ 'jsonContains' |
74
+ 'jsonHasKey'
75
+
76
+
77
+ export type UnaryOp = 'isNull'
78
+
79
+
80
+ export interface OrderBy {
81
+ [field: string]: SortOrder | OrderBy
82
+ }
83
+
84
+
85
+ export type SortOrder = "ASC" | "DESC"
@@ -0,0 +1,48 @@
1
+ import {OrderBy, Where} from "./args"
2
+ import {FieldRequest} from "./fields"
3
+
4
+
5
+ export interface RelayConnectionRequest {
6
+ orderBy: OrderBy
7
+ where?: Where
8
+ first?: number
9
+ after?: string
10
+ edgeNode?: FieldRequest[]
11
+ edgeCursor?: boolean
12
+ pageInfo?: boolean
13
+ totalCount?: boolean
14
+ }
15
+
16
+
17
+ export interface RelayConnectionResponse {
18
+ edges?: RelayConnectionEdge[]
19
+ pageInfo?: Partial<RelayConnectionPageInfo>
20
+ totalCount?: number
21
+ }
22
+
23
+
24
+ export interface RelayConnectionEdge {
25
+ node?: unknown
26
+ cursor?: string
27
+ }
28
+
29
+
30
+ export interface RelayConnectionPageInfo {
31
+ hasNextPage: boolean
32
+ hasPreviousPage: boolean
33
+ startCursor: string
34
+ endCursor: string
35
+ }
36
+
37
+
38
+ export function decodeRelayConnectionCursor(cursor: string): number | undefined {
39
+ if (!/^\d+$/.test(cursor)) return undefined
40
+ let val = parseInt(cursor, 10)
41
+ if (Number.isSafeInteger(val) && val > 0) return val
42
+ return undefined
43
+ }
44
+
45
+
46
+ export function encodeRelayConnectionCursor(val: number): string {
47
+ return '' + val
48
+ }
@@ -0,0 +1,40 @@
1
+ import {
2
+ EnumPropType,
3
+ FkPropType,
4
+ ListLookupPropType,
5
+ ListPropType,
6
+ LookupPropType,
7
+ ObjectPropType, Prop,
8
+ PropType,
9
+ ScalarPropType,
10
+ UnionPropType
11
+ } from "../model"
12
+ import {EntityListArguments} from "./args"
13
+
14
+
15
+ export type FieldRequest = EntityListRequest | ObjectRequest | OpaqueRequest
16
+
17
+
18
+ type Base<T> = T extends PropType ? {
19
+ field: string
20
+ kind: T['kind']
21
+ type: T
22
+ prop: Prop
23
+ aliases: string[]
24
+ ifType?: string
25
+ index: number
26
+ } : never
27
+
28
+
29
+ export type EntityListRequest = Base<ListLookupPropType> & {
30
+ children: FieldRequest[]
31
+ args?: EntityListArguments
32
+ }
33
+
34
+
35
+ export type ObjectRequest = Base<FkPropType | LookupPropType | ObjectPropType | UnionPropType> & {
36
+ children: FieldRequest[]
37
+ }
38
+
39
+
40
+ export type OpaqueRequest = Base<ScalarPropType | EnumPropType | ListPropType>
@@ -0,0 +1,46 @@
1
+ import {unexpectedCase} from "@subsquid/util-internal"
2
+ import {FieldRequest} from "./ir/fields"
3
+
4
+
5
+ export function getSize(fields: FieldRequest[]): number {
6
+ let total = 0
7
+ for (let req of fields) {
8
+ let size = getFieldSize(req)
9
+ if (Number.isFinite(size)) {
10
+ total += size * req.aliases.length
11
+ } else {
12
+ return Infinity
13
+ }
14
+ }
15
+ return total
16
+ }
17
+
18
+
19
+ function getFieldSize(req: FieldRequest): number {
20
+ switch(req.kind) {
21
+ case "scalar":
22
+ case "list":
23
+ return req.prop.byteWeight || 1
24
+ case "enum":
25
+ return 1
26
+ case "object":
27
+ case "fk":
28
+ case "lookup":
29
+ case "union":
30
+ return getSize(req.children) + 1
31
+ case "list-lookup": {
32
+ let limit = Math.min(req.args?.limit ?? Infinity, req.prop.cardinality ?? Infinity)
33
+ if (Number.isFinite(limit)) {
34
+ return limit * Math.max(getSize(req.children), 1)
35
+ } else {
36
+ return Infinity
37
+ }
38
+ }
39
+ default:
40
+ throw unexpectedCase()
41
+ }
42
+ }
43
+
44
+
45
+
46
+
package/src/main.ts CHANGED
@@ -1,51 +1,76 @@
1
+ import {createLogger} from "@subsquid/logger"
2
+ import {runProgram} from "@subsquid/util-internal"
3
+ import {nat, Url} from "@subsquid/util-internal-commander"
4
+ import {waitForInterruption} from "@subsquid/util-internal-http-server"
5
+ import {Command, Option} from "commander"
1
6
  import {Pool} from "pg"
2
- import {createPoolConfig} from "./db"
7
+ import {Dialect} from "./dialect"
3
8
  import {serve} from "./server"
4
9
  import {loadModel} from "./tools"
5
10
 
6
11
 
7
- module.exports = function main() {
8
- let args = process.argv.slice(2)
12
+ const LOG = createLogger('sqd:openreader')
9
13
 
10
- if (args.indexOf('--help') >= 0) {
11
- help()
12
- process.exit(1)
13
- }
14
14
 
15
- if (args.length != 1) {
16
- help()
17
- process.exit(1)
18
- }
15
+ runProgram(async () => {
16
+ let program = new Command()
19
17
 
20
- let model = loadModel(args[0])
21
- let db = new Pool(createPoolConfig())
22
- let port = process.env.GRAPHQL_SERVER_PORT || 3000
23
-
24
- serve({model, db, port}).then(
25
- () => {
26
- console.log('OpenReader is listening on port ' + port)
27
- },
28
- err => {
29
- console.error(err)
30
- process.exit(1)
31
- }
18
+ program.description(`
19
+ GraphQL server for postgres-compatible databases
20
+ `.trim())
21
+
22
+ program.requiredOption('-s, --schema <file>', 'a path to a file or folder with database description')
23
+ program.requiredOption('-d, --db-url <url>', 'database connection string', Url(['postgres:']))
24
+ program.addOption(
25
+ new Option('-t, --db-type <type>', 'database type').choices(['postgres', 'cockroach']).default('postgres')
32
26
  )
33
- }
27
+ program.option('-p, --port <number>', 'port to listen on', nat, 3000)
28
+ program.option('--max-request-size <kb>', 'max request size in kilobytes', nat, 256)
29
+ program.option('--sql-statement-timeout <ms>', 'sql statement timeout in ms', nat)
30
+ program.option('--subscriptions', 'enable gql subscriptions')
31
+ program.option('--subscription-poll-interval <ms>', 'subscription poll interval in ms', nat, 1000)
32
+ program.option('--subscription-sql-statement-timeout <ms>', 'sql statement timeout for polling queries', nat)
34
33
 
34
+ let opts = program.parse().opts() as {
35
+ schema: string
36
+ dbUrl: string
37
+ dbType: Dialect
38
+ port: number
39
+ maxRequestSize: number
40
+ sqlStatementTimeout?: number
41
+ subscriptions?: boolean
42
+ subscriptionPollInterval: number
43
+ subscriptionSqlStatementTimeout?: number
44
+ }
35
45
 
36
- function help() {
37
- console.error(`
38
- Usage: openreader SCHEMA
46
+ let model = loadModel(opts.schema)
47
+
48
+ let connection = new Pool({
49
+ connectionString: opts.dbUrl,
50
+ statement_timeout: opts.sqlStatementTimeout || undefined
51
+ })
52
+
53
+ let subscriptionConnection: Pool | undefined
54
+ if (opts.subscriptions) {
55
+ subscriptionConnection = new Pool({
56
+ connectionString: opts.dbUrl,
57
+ statement_timeout: opts.subscriptionSqlStatementTimeout || opts.sqlStatementTimeout || undefined
58
+ })
59
+ }
39
60
 
40
- OpenCRUD GraphQL server.
61
+ let server = await serve({
62
+ model,
63
+ dialect: opts.dbType,
64
+ connection,
65
+ port: opts.port,
66
+ log: LOG,
67
+ maxRequestSizeBytes: opts.maxRequestSize * 1024,
68
+ subscriptions: opts.subscriptions,
69
+ subscriptionPollInterval: opts.subscriptionPollInterval,
70
+ subscriptionConnection
71
+ })
41
72
 
42
- Can be configured using the following environment variables:
73
+ LOG.info(`listening on port ${server.port}`)
43
74
 
44
- DB_NAME
45
- DB_USER
46
- DB_PASS
47
- DB_HOST
48
- DB_PORT
49
- GRAPHQL_SERVER_PORT
50
- `)
51
- }
75
+ return waitForInterruption(server)
76
+ }, err => LOG.fatal(err))