graphile-build-pg 4.13.0 → 4.14.1

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 (106) hide show
  1. package/README.md +4 -13
  2. package/node8plus/GraphQLJSON.js +0 -11
  3. package/node8plus/GraphQLJSON.js.map +1 -1
  4. package/node8plus/PgLiveProvider.js +4 -11
  5. package/node8plus/PgLiveProvider.js.map +1 -1
  6. package/node8plus/QueryBuilder.js +42 -176
  7. package/node8plus/QueryBuilder.js.map +1 -1
  8. package/node8plus/index.js +8 -47
  9. package/node8plus/index.js.map +1 -1
  10. package/node8plus/inflections.js +9 -61
  11. package/node8plus/inflections.js.map +1 -1
  12. package/node8plus/omit.js +7 -22
  13. package/node8plus/omit.js.map +1 -1
  14. package/node8plus/parseIdentifier.js +0 -1
  15. package/node8plus/parseIdentifier.js.map +1 -1
  16. package/node8plus/pgPrepareAndRun.js +2 -14
  17. package/node8plus/pgPrepareAndRun.js.map +1 -1
  18. package/node8plus/plugins/PageInfoStartEndCursor.js +0 -4
  19. package/node8plus/plugins/PageInfoStartEndCursor.js.map +1 -1
  20. package/node8plus/plugins/PgAllRows.js +0 -29
  21. package/node8plus/plugins/PgAllRows.js.map +1 -1
  22. package/node8plus/plugins/PgBackwardRelationPlugin.js +2 -41
  23. package/node8plus/plugins/PgBackwardRelationPlugin.js.map +1 -1
  24. package/node8plus/plugins/PgBasicsPlugin.js +20 -147
  25. package/node8plus/plugins/PgBasicsPlugin.js.map +1 -1
  26. package/node8plus/plugins/PgColumnDeprecationPlugin.js +2 -5
  27. package/node8plus/plugins/PgColumnDeprecationPlugin.js.map +1 -1
  28. package/node8plus/plugins/PgColumnsPlugin.js +4 -17
  29. package/node8plus/plugins/PgColumnsPlugin.js.map +1 -1
  30. package/node8plus/plugins/PgComputedColumnsPlugin.js +4 -19
  31. package/node8plus/plugins/PgComputedColumnsPlugin.js.map +1 -1
  32. package/node8plus/plugins/PgConditionComputedColumnPlugin.js +12 -23
  33. package/node8plus/plugins/PgConditionComputedColumnPlugin.js.map +1 -1
  34. package/node8plus/plugins/PgConnectionArgCondition.js +1 -9
  35. package/node8plus/plugins/PgConnectionArgCondition.js.map +1 -1
  36. package/node8plus/plugins/PgConnectionArgFirstLastBeforeAfter.js +0 -12
  37. package/node8plus/plugins/PgConnectionArgFirstLastBeforeAfter.js.map +1 -1
  38. package/node8plus/plugins/PgConnectionArgOrderBy.js +2 -19
  39. package/node8plus/plugins/PgConnectionArgOrderBy.js.map +1 -1
  40. package/node8plus/plugins/PgConnectionArgOrderByDefaultValue.js +0 -6
  41. package/node8plus/plugins/PgConnectionArgOrderByDefaultValue.js.map +1 -1
  42. package/node8plus/plugins/PgConnectionTotalCount.js +0 -8
  43. package/node8plus/plugins/PgConnectionTotalCount.js.map +1 -1
  44. package/node8plus/plugins/PgForwardRelationPlugin.js +2 -25
  45. package/node8plus/plugins/PgForwardRelationPlugin.js.map +1 -1
  46. package/node8plus/plugins/PgIntrospectionPlugin.js +91 -180
  47. package/node8plus/plugins/PgIntrospectionPlugin.js.flow +30 -2
  48. package/node8plus/plugins/PgIntrospectionPlugin.js.map +1 -1
  49. package/node8plus/plugins/PgJWTPlugin.js +2 -18
  50. package/node8plus/plugins/PgJWTPlugin.js.map +1 -1
  51. package/node8plus/plugins/PgMutationCreatePlugin.js +0 -18
  52. package/node8plus/plugins/PgMutationCreatePlugin.js.map +1 -1
  53. package/node8plus/plugins/PgMutationPayloadEdgePlugin.js +4 -25
  54. package/node8plus/plugins/PgMutationPayloadEdgePlugin.js.map +1 -1
  55. package/node8plus/plugins/PgMutationProceduresPlugin.js +0 -6
  56. package/node8plus/plugins/PgMutationProceduresPlugin.js.map +1 -1
  57. package/node8plus/plugins/PgMutationUpdateDeletePlugin.js +14 -49
  58. package/node8plus/plugins/PgMutationUpdateDeletePlugin.js.flow +5 -2
  59. package/node8plus/plugins/PgMutationUpdateDeletePlugin.js.map +1 -1
  60. package/node8plus/plugins/PgNodeAliasPostGraphile.js +0 -6
  61. package/node8plus/plugins/PgNodeAliasPostGraphile.js.map +1 -1
  62. package/node8plus/plugins/PgOrderAllColumnsPlugin.js +0 -4
  63. package/node8plus/plugins/PgOrderAllColumnsPlugin.js.map +1 -1
  64. package/node8plus/plugins/PgOrderByPrimaryKeyPlugin.js +0 -6
  65. package/node8plus/plugins/PgOrderByPrimaryKeyPlugin.js.map +1 -1
  66. package/node8plus/plugins/PgOrderComputedColumnsPlugin.js +10 -14
  67. package/node8plus/plugins/PgOrderComputedColumnsPlugin.js.map +1 -1
  68. package/node8plus/plugins/PgQueryProceduresPlugin.js +4 -16
  69. package/node8plus/plugins/PgQueryProceduresPlugin.js.map +1 -1
  70. package/node8plus/plugins/PgRecordFunctionConnectionPlugin.js +3 -20
  71. package/node8plus/plugins/PgRecordFunctionConnectionPlugin.js.map +1 -1
  72. package/node8plus/plugins/PgRecordReturnTypesPlugin.js +11 -16
  73. package/node8plus/plugins/PgRecordReturnTypesPlugin.js.map +1 -1
  74. package/node8plus/plugins/PgRowByUniqueConstraint.js +4 -25
  75. package/node8plus/plugins/PgRowByUniqueConstraint.js.map +1 -1
  76. package/node8plus/plugins/PgRowNode.js +0 -32
  77. package/node8plus/plugins/PgRowNode.js.map +1 -1
  78. package/node8plus/plugins/PgScalarFunctionConnectionPlugin.js +3 -17
  79. package/node8plus/plugins/PgScalarFunctionConnectionPlugin.js.map +1 -1
  80. package/node8plus/plugins/PgTablesPlugin.js +7 -59
  81. package/node8plus/plugins/PgTablesPlugin.js.map +1 -1
  82. package/node8plus/plugins/PgTypesPlugin.js +140 -240
  83. package/node8plus/plugins/PgTypesPlugin.js.flow +76 -23
  84. package/node8plus/plugins/PgTypesPlugin.js.map +1 -1
  85. package/node8plus/plugins/addStartEndCursor.js +2 -5
  86. package/node8plus/plugins/addStartEndCursor.js.map +1 -1
  87. package/node8plus/plugins/debugSql.js +1 -16
  88. package/node8plus/plugins/debugSql.js.map +1 -1
  89. package/node8plus/plugins/introspectionQuery.js +3 -4
  90. package/node8plus/plugins/introspectionQuery.js.flow +11 -3
  91. package/node8plus/plugins/introspectionQuery.js.map +1 -1
  92. package/node8plus/plugins/makeProcField.js +40 -90
  93. package/node8plus/plugins/makeProcField.js.map +1 -1
  94. package/node8plus/plugins/pgField.js +2 -7
  95. package/node8plus/plugins/pgField.js.map +1 -1
  96. package/node8plus/plugins/viaTemporaryTable.js +6 -12
  97. package/node8plus/plugins/viaTemporaryTable.js.map +1 -1
  98. package/node8plus/postgresInterval.js +4 -4
  99. package/node8plus/postgresInterval.js.map +1 -1
  100. package/node8plus/queryFromResolveDataFactory.js +33 -77
  101. package/node8plus/queryFromResolveDataFactory.js.map +1 -1
  102. package/node8plus/utils.js +8 -9
  103. package/node8plus/utils.js.map +1 -1
  104. package/node8plus/withPgClient.js +4 -26
  105. package/node8plus/withPgClient.js.map +1 -1
  106. package/package.json +4 -4
@@ -4,35 +4,24 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _QueryBuilder = _interopRequireDefault(require("./QueryBuilder"));
9
-
10
8
  var sql = _interopRequireWildcard(require("pg-sql2"));
11
-
12
9
  var _isSafeInteger = _interopRequireDefault(require("lodash/isSafeInteger"));
13
-
14
10
  var _assert = _interopRequireDefault(require("assert"));
15
-
16
11
  var _util = require("util");
17
-
18
12
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
19
-
20
13
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
21
-
22
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
-
15
+ // eslint-disable-next-line flowtype/no-weak-types
24
16
  const identity = _ => _ !== null && _ !== undefined;
25
-
26
17
  function assertSafeName(name) {
27
18
  if (typeof name !== "string") {
28
19
  throw new Error(`Expected name to be a string; instead received '${(0, _util.inspect)(name)}'`);
29
20
  }
30
-
31
21
  if (!/^[@a-zA-Z0-9_]{1,63}$/.test(name)) {
32
22
  throw new Error(`Name '${name}' is not safe - either it is too long, too short, or has invalid characters`);
33
23
  }
34
24
  }
35
-
36
25
  var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOptions, withBuilder, context = {}, rootValue) => {
37
26
  const {
38
27
  pgQuery,
@@ -45,8 +34,8 @@ var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOp
45
34
  calculateHasNextPage,
46
35
  calculateHasPreviousPage,
47
36
  usesCursor: explicitlyUsesCursor
48
- } = resolveData; // Push a query container for aggregates
49
-
37
+ } = resolveData;
38
+ // Push a query container for aggregates
50
39
  if (pgAggregateQuery && pgAggregateQuery.length || pgNamedQuery.length) {
51
40
  pgNamedQueryContainer.push({
52
41
  name: "aggregates",
@@ -63,9 +52,8 @@ var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOp
63
52
  where ${queryBuilder.buildWhereClause(false, false, options)}
64
53
  )`
65
54
  });
66
- } // Convert pgAggregateQuery to pgNamedQueryContainer/pgNamedQuery combo
67
-
68
-
55
+ }
56
+ // Convert pgAggregateQuery to pgNamedQueryContainer/pgNamedQuery combo
69
57
  if (pgAggregateQuery && pgAggregateQuery.length) {
70
58
  // And a query for each previous query
71
59
  pgAggregateQuery.forEach(query => {
@@ -75,9 +63,9 @@ var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOp
75
63
  });
76
64
  });
77
65
  }
78
-
79
66
  const preventAsterisk = pgDontUseAsterisk ? pgDontUseAsterisk.length > 0 : false;
80
- const options = { ...inOptions,
67
+ const options = {
68
+ ...inOptions,
81
69
  // Allow pgDontUseAsterisk to override useAsterisk
82
70
  useAsterisk: inOptions.useAsterisk && !preventAsterisk
83
71
  };
@@ -85,17 +73,14 @@ var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOp
85
73
  const rawCursorPrefix = reallyRawCursorPrefix && reallyRawCursorPrefix.filter(identity);
86
74
  const queryBuilder = new _QueryBuilder.default(queryBuilderOptions, context, rootValue);
87
75
  queryBuilder.from(from, fromAlias ? fromAlias : undefined);
88
-
89
76
  if (withBuilder) {
90
77
  withBuilder(queryBuilder);
91
78
  }
92
-
93
79
  if (pgQuery) {
94
80
  for (let i = 0, l = pgQuery.length; i < l; i++) {
95
81
  pgQuery[i](queryBuilder, resolveData);
96
82
  }
97
83
  }
98
-
99
84
  function generateNextPrevPageSql(sqlQueryAlias, canHaveCursorInWhere, queryHasBefore, queryHasFirst, offset = 0, invert = false) {
100
85
  /*
101
86
  * Strap in, 'coz this function gets hairy!
@@ -164,6 +149,7 @@ var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOp
164
149
  * hasNextPage we always pretend we're determining `hasNextPage`, and we
165
150
  * just invert everything.
166
151
  */
152
+
167
153
  const sqlCommonUnbounded = sql.fragment`\
168
154
  select 1
169
155
  from ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}`;
@@ -182,29 +168,26 @@ from ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}`;
182
168
  * upper bound. In hasPreviousPage mode (invert === true), it represents
183
169
  * everything from `(before || END)` backwards, with no lower bound.
184
170
  */
185
-
186
171
  const sqlCommon = sql.fragment`\
187
172
  ${sqlCommonUnbounded}
188
173
  where ${queryBuilder.buildWhereClause(!invert, invert, options)}`;
174
+
189
175
  /*
190
176
  * Since the offset makes the diagram asymmetric, if offset === 0
191
177
  * then the diagram is symmetric and things are simplified a little.
192
178
  */
193
-
194
179
  const isForwardOrSymmetric = !invert || offset === 0;
195
-
196
180
  if (!isForwardOrSymmetric) {
197
181
  (0, _assert.default)(invert);
198
- (0, _assert.default)(offset > 0); // We're looking for a previous page, and there's an offset, so lets just
182
+ (0, _assert.default)(offset > 0);
183
+ // We're looking for a previous page, and there's an offset, so lets just
199
184
  // assume there's a previous page where offset is smaller.
200
-
201
185
  return sql.literal(true);
202
186
  } else if (canHaveCursorInWhere) {
203
187
  (0, _assert.default)(isForwardOrSymmetric);
204
-
205
188
  if (!queryHasBefore && !queryHasFirst) {
206
- (0, _assert.default)(isForwardOrSymmetric); // There can be no next page since there's no upper bound
207
-
189
+ (0, _assert.default)(isForwardOrSymmetric);
190
+ // There can be no next page since there's no upper bound
208
191
  return sql.literal(false);
209
192
  } else if (queryHasBefore && !queryHasFirst) {
210
193
  /*
@@ -224,8 +207,8 @@ exists(
224
207
  and not (${queryBuilder.buildWhereBoundClause(invert)})
225
208
  )`;
226
209
  } else {
227
- (0, _assert.default)(queryHasFirst); // queryHasBefore could be true or false.
228
-
210
+ (0, _assert.default)(queryHasFirst);
211
+ // queryHasBefore could be true or false.
229
212
  /*
230
213
  * There's a few ways that we could determine if there's a next page.
231
214
  *
@@ -245,7 +228,6 @@ exists(
245
228
  */
246
229
  // Drop the `first` limit, see if there are any records that aren't
247
230
  // already in the list we've fetched.
248
-
249
231
  return sql.fragment`\
250
232
  exists(
251
233
  ${sqlCommon}
@@ -255,22 +237,20 @@ exists(
255
237
  }
256
238
  } else {
257
239
  (0, _assert.default)(!invert || offset === 0); // isForwardOrSymmetric
258
-
259
- (0, _assert.default)(!canHaveCursorInWhere); // We're dealing with LIMIT/OFFSET pagination here, which means `natural`
240
+ (0, _assert.default)(!canHaveCursorInWhere);
241
+ // We're dealing with LIMIT/OFFSET pagination here, which means `natural`
260
242
  // cursors, so the `queryBuilder` factors the before/after, first/last
261
243
  // into the limit / offset.
262
-
263
244
  const {
264
245
  limit
265
246
  } = queryBuilder.getFinalLimitAndOffset();
266
-
267
247
  if (limit == null) {
268
248
  // If paginating backwards, then offset > 0 has already been dealt
269
249
  // with. Unbounded, so there's no next page.
270
250
  return sql.fragment`false`;
271
251
  } else if (invert) {
272
- (0, _assert.default)(offset === 0); // Paginating backwards and there's no offset (which factors in before/after), so there's no previous page.
273
-
252
+ (0, _assert.default)(offset === 0);
253
+ // Paginating backwards and there's no offset (which factors in before/after), so there's no previous page.
274
254
  return sql.fragment`false`;
275
255
  } else {
276
256
  (0, _assert.default)(!invert);
@@ -280,7 +260,6 @@ exists(
280
260
  *
281
261
  * We want to see if there's more than limit+offset records in sqlCommon.
282
262
  */
283
-
284
263
  return sql.fragment`\
285
264
  exists(
286
265
  ${sqlCommon}
@@ -289,15 +268,12 @@ exists(
289
268
  }
290
269
  }
291
270
  }
292
-
293
271
  const getPgCursorPrefix = () => rawCursorPrefix && rawCursorPrefix.length > 0 ? rawCursorPrefix : queryBuilder.data.cursorPrefix.map(val => sql.literal(val));
294
-
295
272
  if (options.withPagination || options.withPaginationAsFields || options.withCursor) {
296
273
  // Sometimes we need a __cursor even if it's not a collection; e.g. to get the edge field on a mutation
297
274
  if (usesCursor) {
298
275
  queryBuilder.selectCursor(() => {
299
276
  const orderBy = queryBuilder.getOrderByExpressionsAndDirections().map(([expr]) => expr);
300
-
301
277
  if (queryBuilder.isOrderUnique() && orderBy.length > 0) {
302
278
  return sql.fragment`json_build_array(${sql.join([...getPgCursorPrefix(), sql.fragment`json_build_array(${sql.join(orderBy, ", ")})`], ", ")})`;
303
279
  } else {
@@ -307,46 +283,37 @@ exists(
307
283
  * query with limit offset is in a subquery, so our row_number()
308
284
  * call doesn't know about it. Here we add the offset back in
309
285
  * again. See matching NOTE in QueryBuilder.js.
310
- */
311
- options.useAsterisk ? sql.fragment`${sql.literal(queryBuilder.getFinalOffset() || 0)} + ` : sql.fragment``}(row_number() over (partition by 1)))`;
286
+ */options.useAsterisk ? sql.fragment`${sql.literal(queryBuilder.getFinalOffset() || 0)} + ` : sql.fragment``}(row_number() over (partition by 1)))`;
312
287
  }
313
288
  });
314
289
  }
315
290
  }
316
-
317
291
  if (options.withPagination || options.withPaginationAsFields) {
318
292
  queryBuilder.setCursorComparator((cursorValue, isAfter) => {
319
293
  function badCursor() {
320
294
  queryBuilder.whereBound(sql.fragment`false`, isAfter);
321
295
  }
322
-
323
296
  const orderByExpressionsAndDirections = queryBuilder.getOrderByExpressionsAndDirections();
324
-
325
297
  if (orderByExpressionsAndDirections.length > 0) {
326
298
  if (!queryBuilder.isOrderUnique()) {
327
299
  throw new Error("The order supplied is not unique, so before/after cursors cannot be used. Please ensure the supplied order includes all the columns from the primary key or a unique constraint.");
328
300
  }
329
-
330
301
  const rawPrefixes = cursorValue.slice(0, cursorValue.length - 1);
331
302
  const rawCursors = cursorValue[cursorValue.length - 1];
332
-
333
303
  if (rawPrefixes.length !== getPgCursorPrefix().length) {
334
304
  badCursor();
335
305
  return;
336
306
  }
337
-
338
307
  if (!Array.isArray(rawCursors)) {
339
308
  badCursor();
340
309
  return;
341
310
  }
342
-
343
311
  let sqlFilter = sql.fragment`false`;
344
312
  const sqlCursors = rawCursors.map(val => sql.value(val));
345
-
346
313
  for (let i = orderByExpressionsAndDirections.length - 1; i >= 0; i--) {
347
- const [sqlExpression, ascending] = orderByExpressionsAndDirections[i]; // If ascending and isAfter then >
314
+ const [sqlExpression, ascending] = orderByExpressionsAndDirections[i];
315
+ // If ascending and isAfter then >
348
316
  // If ascending and isBefore then <
349
-
350
317
  const comparison = Number(ascending) ^ Number(!isAfter) ? sql.fragment`>` : sql.fragment`<`;
351
318
  const sqlOldFilter = sqlFilter;
352
319
  sqlFilter = sql.fragment`\
@@ -359,17 +326,17 @@ OR\
359
326
  ${sqlOldFilter}\
360
327
  )\
361
328
  )`;
362
- } // Check the cursor prefixes apply
363
- // TODO:v5: we should be able to do this in JS-land rather than SQL-land
364
-
329
+ }
365
330
 
331
+ // Check the cursor prefixes apply
332
+ // TODO:v5: we should be able to do this in JS-land rather than SQL-land
366
333
  sqlFilter = sql.fragment`(((${sql.join(getPgCursorPrefix(), ", ")}) = (${sql.join(rawPrefixes.map(val => sql.value(val)), ", ")})) AND (${sqlFilter}))`;
367
334
  queryBuilder.whereBound(sqlFilter, isAfter);
368
- } else if (cursorValue[0] === "natural" && (0, _isSafeInteger.default)(cursorValue[1]) && // $FlowFixMe: we know this is a number
335
+ } else if (cursorValue[0] === "natural" && (0, _isSafeInteger.default)(cursorValue[1]) &&
336
+ // $FlowFixMe: we know this is a number
369
337
  cursorValue[1] >= 0) {
370
338
  // $FlowFixMe: we know this is a number
371
339
  const cursorValue1 = cursorValue[1];
372
-
373
340
  if (isAfter) {
374
341
  queryBuilder.offset(() => cursorValue1);
375
342
  } else {
@@ -385,7 +352,8 @@ OR\
385
352
  const query = queryBuilder.build(options);
386
353
  const haveFields = queryBuilder.getSelectFieldsCount() > 0;
387
354
  const sqlQueryAlias = sql.identifier(Symbol());
388
- const sqlSummaryAlias = sql.identifier(Symbol()); //
355
+ const sqlSummaryAlias = sql.identifier(Symbol());
356
+ //
389
357
  // Tables should ALWAYS push their PK onto the order stack, if this isn't
390
358
  // present then we're either dealing with a view or a table without a PK.
391
359
  // Either way, we don't have anything to guarantee uniqueness so we need to
@@ -394,7 +362,6 @@ OR\
394
362
  // TODO: support unique keys in PgAllRows etc
395
363
  // TODO: add a warning for cursor-based pagination when using the fallback
396
364
  // TODO: if it is a view maybe add a warning encouraging pgViewUniqueKey
397
-
398
365
  const canHaveCursorInWhere = queryBuilder.getOrderByExpressionsAndDirections().length > 0 && queryBuilder.isOrderUnique();
399
366
  const queryHasBefore = queryBuilder.compiledData.whereBound.upper.length > 0;
400
367
  const queryHasAfter = queryBuilder.compiledData.whereBound.lower.length > 0;
@@ -406,19 +373,15 @@ OR\
406
373
  const sqlWith = haveFields ? sql.fragment`with ${sqlQueryAlias} as (${query}), ${sqlSummaryAlias} as (select json_agg(to_json(${sqlQueryAlias})) as data from ${sqlQueryAlias})` : sql.fragment``;
407
374
  const sqlFrom = sql.fragment``;
408
375
  const fields = [];
409
-
410
376
  if (haveFields) {
411
377
  fields.push([sql.fragment`coalesce((select ${sqlSummaryAlias}.data from ${sqlSummaryAlias}), '[]'::json)`, "data"]);
412
-
413
378
  if (calculateHasNextPage) {
414
379
  fields.push([hasNextPage, "hasNextPage"]);
415
380
  }
416
-
417
381
  if (calculateHasPreviousPage) {
418
382
  fields.push([hasPreviousPage, "hasPreviousPage"]);
419
383
  }
420
384
  }
421
-
422
385
  if (pgNamedQuery && pgNamedQuery.length) {
423
386
  const groups = {};
424
387
  pgNamedQuery.forEach(({
@@ -426,35 +389,30 @@ OR\
426
389
  query
427
390
  }) => {
428
391
  assertSafeName(name);
429
-
430
392
  if (!groups[name]) {
431
393
  groups[name] = [];
432
394
  }
433
-
434
395
  groups[name].push(query);
435
396
  });
436
397
  Object.keys(groups).forEach(groupName => {
437
- const queryCallbacks = groups[groupName]; // Get container
398
+ const queryCallbacks = groups[groupName];
438
399
 
400
+ // Get container
439
401
  const containers = pgNamedQueryContainer.filter(c => c.name === groupName);
440
-
441
402
  if (containers.length === 0) {
442
403
  throw new Error(`${queryCallbacks.length} pgNamedQuery entries with name: '${groupName}' existed, but there was no matching pgNamedQueryContainer.`);
443
404
  }
444
-
445
405
  if (containers.length > 1) {
446
406
  throw new Error(`${containers.length} pgNamedQueryContainer entries with name: '${groupName}' existed, but there should be exactly one.`);
447
407
  }
448
-
449
408
  const container = containers[0];
450
409
  const innerQueryBuilder = new _QueryBuilder.default(queryBuilderOptions, context, rootValue);
451
410
  innerQueryBuilder.from(queryBuilder.getTableExpression(), queryBuilder.getTableAlias());
452
-
453
411
  for (let i = 0, l = queryCallbacks.length; i < l; i++) {
454
412
  queryCallbacks[i](innerQueryBuilder);
455
- } // Generate the SQL statement (e.g. `select ${innerQueryBuilder.build({onlyJsonField: true})} from ${queryBuilder.getTableExpression()} as ...`)
456
-
413
+ }
457
414
 
415
+ // Generate the SQL statement (e.g. `select ${innerQueryBuilder.build({onlyJsonField: true})} from ${queryBuilder.getTableExpression()} as ...`)
458
416
  const aggregatesSql = container.query({
459
417
  queryBuilder,
460
418
  innerQueryBuilder,
@@ -463,7 +421,6 @@ OR\
463
421
  fields.push([aggregatesSql, groupName]);
464
422
  });
465
423
  }
466
-
467
424
  if (options.withPaginationAsFields) {
468
425
  return sql.fragment`${sqlWith} select ${sql.join(fields.map(([expr, alias]) => sql.fragment`${expr} as ${sql.identifier(alias)}`), ", ")} ${sqlFrom}`;
469
426
  } else {
@@ -474,6 +431,5 @@ OR\
474
431
  return query;
475
432
  }
476
433
  };
477
-
478
434
  exports.default = _default;
479
435
  //# sourceMappingURL=queryFromResolveDataFactory.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/queryFromResolveDataFactory.js"],"names":["identity","_","undefined","assertSafeName","name","Error","test","queryBuilderOptions","from","fromAlias","resolveData","inOptions","withBuilder","context","rootValue","pgQuery","pgAggregateQuery","pgNamedQueryContainer","pgNamedQuery","pgCursorPrefix","reallyRawCursorPrefix","pgDontUseAsterisk","calculateHasNextPage","calculateHasPreviousPage","usesCursor","explicitlyUsesCursor","length","push","query","queryBuilder","options","innerQueryBuilder","sql","fragment","build","onlyJsonField","getTableExpression","getTableAlias","buildWhereClause","forEach","preventAsterisk","useAsterisk","rawCursorPrefix","filter","QueryBuilder","i","l","generateNextPrevPageSql","sqlQueryAlias","canHaveCursorInWhere","queryHasBefore","queryHasFirst","offset","invert","sqlCommonUnbounded","sqlCommon","isForwardOrSymmetric","literal","buildWhereBoundClause","getSelectCursor","blank","value","limit","getFinalLimitAndOffset","getPgCursorPrefix","data","cursorPrefix","map","val","withPagination","withPaginationAsFields","withCursor","selectCursor","orderBy","getOrderByExpressionsAndDirections","expr","isOrderUnique","join","getFinalOffset","setCursorComparator","cursorValue","isAfter","badCursor","whereBound","orderByExpressionsAndDirections","rawPrefixes","slice","rawCursors","Array","isArray","sqlFilter","sqlCursors","sqlExpression","ascending","comparison","Number","sqlOldFilter","null","cursorValue1","getOffset","Math","max","haveFields","getSelectFieldsCount","identifier","Symbol","sqlSummaryAlias","compiledData","upper","queryHasAfter","lower","queryHasZeroLimit","getFinalLimit","first","queryHasLast","last","hasNextPage","hasPreviousPage","sqlWith","sqlFrom","fields","groups","Object","keys","groupName","queryCallbacks","containers","c","container","aggregatesSql","alias","jsonbBuildObject"],"mappings":"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,EAKEC,MAAM,GAAG,CALX,EAMEC,MAAM,GAAG,KANX,EAOE;AACA;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEM,UAAMC,kBAAkB,GAAGtB,GAAG,CAACC,QAAS;AAC9C;AACA,OAAOJ,YAAY,CAACO,kBAAb,EAAkC,OAAMP,YAAY,CAACQ,aAAb,EAA6B,EAFtE;AAGA;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACM,UAAMkB,SAAS,GAAGvB,GAAG,CAACC,QAAS;AACrC,EAAEqB,kBAAmB;AACrB,QAAQzB,YAAY,CAACS,gBAAb,CAA8B,CAACe,MAA/B,EAAuCA,MAAvC,EAA+CvB,OAA/C,CAAwD,EAF1D;AAIA;AACN;AACA;AACA;;AACM,UAAM0B,oBAAoB,GAAG,CAACH,MAAD,IAAWD,MAAM,KAAK,CAAnD;;AAEA,QAAI,CAACI,oBAAL,EAA2B;AACzB,2BAAOH,MAAP;AACA,2BAAOD,MAAM,GAAG,CAAhB,EAFyB,CAGzB;AACA;;AACA,aAAOpB,GAAG,CAACyB,OAAJ,CAAY,IAAZ,CAAP;AACD,KAND,MAMO,IAAIR,oBAAJ,EAA0B;AAC/B,2BAAOO,oBAAP;;AACA,UAAI,CAACN,cAAD,IAAmB,CAACC,aAAxB,EAAuC;AACrC,6BAAOK,oBAAP,EADqC,CAErC;;AACA,eAAOxB,GAAG,CAACyB,OAAJ,CAAY,KAAZ,CAAP;AACD,OAJD,MAIO,IAAIP,cAAc,IAAI,CAACC,aAAvB,EAAsC;AAC3C;AACV;AACA;AACA;AACA;AACA;AACA;AACA;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","sourcesContent":["// @flow\nimport QueryBuilder from \"./QueryBuilder\";\nimport type { QueryBuilderOptions } from \"./QueryBuilder\";\nimport type { RawAlias } from \"./QueryBuilder\";\nimport * as sql from \"pg-sql2\";\nimport type { SQL } from \"pg-sql2\";\nimport type { DataForType } from \"graphile-build\";\nimport isSafeInteger from \"lodash/isSafeInteger\";\nimport assert from \"assert\";\nimport { inspect } from \"util\";\n\n// eslint-disable-next-line flowtype/no-weak-types\ntype GraphQLContext = any;\n\nconst identity = _ => _ !== null && _ !== undefined;\n\nfunction assertSafeName(name: mixed) {\n if (typeof name !== \"string\") {\n throw new Error(\n `Expected name to be a string; instead received '${inspect(name)}'`\n );\n }\n if (!/^[@a-zA-Z0-9_]{1,63}$/.test(name)) {\n throw new Error(\n `Name '${name}' is not safe - either it is too long, too short, or has invalid characters`\n );\n }\n}\n\nexport default (queryBuilderOptions: QueryBuilderOptions = {}) =>\n (\n from: SQL,\n fromAlias: ?SQL,\n resolveData: DataForType,\n inOptions: {\n withPagination?: boolean,\n withPaginationAsFields?: boolean,\n asJson?: boolean,\n asJsonAggregate?: boolean,\n addNullCase?: boolean,\n addNotDistinctFromNullCase?: boolean,\n onlyJsonField?: boolean,\n useAsterisk?: boolean,\n withCursor?: boolean,\n },\n // TODO:v5: context is not optional\n withBuilder?: ((builder: QueryBuilder) => void) | null | void,\n context?: GraphQLContext = {},\n rootValue?: any // eslint-disable-line flowtype/no-weak-types\n ) => {\n const {\n pgQuery,\n pgAggregateQuery, // Shorthand for using pgNamedQueryContainer/pgNamedQuery combo\n pgNamedQueryContainer = [],\n pgNamedQuery = [],\n pgCursorPrefix: reallyRawCursorPrefix,\n pgDontUseAsterisk,\n calculateHasNextPage,\n calculateHasPreviousPage,\n usesCursor: explicitlyUsesCursor,\n } = resolveData;\n // Push a query container for aggregates\n if ((pgAggregateQuery && pgAggregateQuery.length) || pgNamedQuery.length) {\n pgNamedQueryContainer.push({\n name: \"aggregates\",\n query: ({ queryBuilder, options, innerQueryBuilder }) => sql.fragment`\\\n(\n select ${innerQueryBuilder.build({ onlyJsonField: true })}\n from ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}\n where ${queryBuilder.buildWhereClause(false, false, options)}\n)`,\n });\n }\n // Convert pgAggregateQuery to pgNamedQueryContainer/pgNamedQuery combo\n if (pgAggregateQuery && pgAggregateQuery.length) {\n // And a query for each previous query\n pgAggregateQuery.forEach(query => {\n pgNamedQuery.push({ name: \"aggregates\", query });\n });\n }\n\n const preventAsterisk = pgDontUseAsterisk\n ? pgDontUseAsterisk.length > 0\n : false;\n const options = {\n ...inOptions,\n // Allow pgDontUseAsterisk to override useAsterisk\n useAsterisk: inOptions.useAsterisk && !preventAsterisk,\n };\n\n const usesCursor: boolean =\n (explicitlyUsesCursor && explicitlyUsesCursor.length > 0) ||\n (calculateHasNextPage && calculateHasNextPage.length > 0) ||\n (calculateHasPreviousPage && calculateHasPreviousPage.length > 0) ||\n false;\n const rawCursorPrefix =\n reallyRawCursorPrefix && reallyRawCursorPrefix.filter(identity);\n\n const queryBuilder = new QueryBuilder(\n queryBuilderOptions,\n context,\n rootValue\n );\n queryBuilder.from(from, fromAlias ? fromAlias : undefined);\n\n if (withBuilder) {\n withBuilder(queryBuilder);\n }\n if (pgQuery) {\n for (let i = 0, l = pgQuery.length; i < l; i++) {\n pgQuery[i](queryBuilder, resolveData);\n }\n }\n\n function generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasBefore,\n queryHasFirst,\n offset = 0,\n invert = false\n ) {\n /*\n * Strap in, 'coz this function gets hairy!\n *\n * The point of this function is to return SQL which will resolve to a\n * boolean true/false depending on whether or not there is a (invert ?\n * \"previous\" : \"next\") page.\n *\n * Connections have before, after, first, last and offset.\n * - Users are forbidden from setting both first and last.\n * - Users are forbidden from setting both offset and last.\n *\n * Further there are two main modes of paginating, one works by adding a\n * where clause (this is preferred, but is not always possible, and is\n * indicated by `canHaveCursorInWhere === true`) and the other works using\n * standard LIMIT/OFFSET SQL pagination (and is indicated by\n * `canHaveCursorInWhere === false`).\n *\n * The following diagram shows a full collection of records, #, starting at\n * START and ending at END. The key after, before, offset, first and last\n * variables are shown. One thing not show is that it's possible to have\n * fewer records between before and after than requested by first or last.\n * Another detail not clearly show is that if there is no `after` then\n * `START` is used, similarly if there is no `before` then `END` is used.\n *\n * #################################################### < collection\n * ^ ^<-offset->^<-first->^ ^<-last->^ ^\n * | | | | | | |\n * | | +---------+ +--------+ |\n * | | | DATA1 DATA2 | |\n * | | | | |\n * | | | | |\n * | | +-------------------------+ |\n * | | DATA3 | |\n * | after before |\n * | |\n * START END\n *\n * We want one of the three DATA blocks:\n *\n * - If `first` is set, then we want DATA1.\n * - If `last` is set then we want DATA2.\n * - If neither is set then we want DATA3.\n *\n * (Remember: you cannot set both `first` and `last` at the same time.)\n *\n * When invert === false:\n *\n * Note that both DATA2 and DATA3 end at the same point, and we only care\n * if there's data *after* the relevant DATA block, so really we only\n * care if the query specified `first` (`queryHasFirst`) which makes\n * things complex (ending at the end of DATA1), otherwise we can use\n * `before` as the bound (end of DATA2/DATA3).\n *\n * When invert === true:\n *\n * Similarly, DATA1 and DATA3 start at the same point, and we're going\n * backwards so we only care if there's data *before* the DATA block, so\n * really we just need to know if the query set `last` or not, but since\n * this is inverted we call it `queryHasFirst`.\n *\n * When `invert` is false we're calculating `hasNextPage`, when true we're\n * calculating `hasPreviousPage`.\n *\n * Because of the near-symmetry of requesting hasPreviousPage vs\n * hasNextPage we always pretend we're determining `hasNextPage`, and we\n * just invert everything.\n */\n\n const sqlCommonUnbounded = sql.fragment`\\\nselect 1\nfrom ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}`;\n /*\n * This variable is a fragment to go into an `EXISTS(...)` call (after some tweaks).\n *\n * The buildWhereClause takes three arguments:\n *\n * - includeLowerBound (we want this for hasNextPage but not hasPreviousPage)\n * - includeUpperBound (we want this for hasPreviousPage but not hasNextPage)\n * - options (specifically `{addNullCase, addNotDistinctFromNullCase}`) -\n * we just pass this through.\n *\n * So in hasNextPage mode (invert === false), this common SQL ends up\n * representing the collection from `(after || START)` onwards with no\n * upper bound. In hasPreviousPage mode (invert === true), it represents\n * everything from `(before || END)` backwards, with no lower bound.\n */\n const sqlCommon = sql.fragment`\\\n${sqlCommonUnbounded}\nwhere ${queryBuilder.buildWhereClause(!invert, invert, options)}`;\n\n /*\n * Since the offset makes the diagram asymmetric, if offset === 0\n * then the diagram is symmetric and things are simplified a little.\n */\n const isForwardOrSymmetric = !invert || offset === 0;\n\n if (!isForwardOrSymmetric) {\n assert(invert);\n assert(offset > 0);\n // We're looking for a previous page, and there's an offset, so lets just\n // assume there's a previous page where offset is smaller.\n return sql.literal(true);\n } else if (canHaveCursorInWhere) {\n assert(isForwardOrSymmetric);\n if (!queryHasBefore && !queryHasFirst) {\n assert(isForwardOrSymmetric);\n // There can be no next page since there's no upper bound\n return sql.literal(false);\n } else if (queryHasBefore && !queryHasFirst) {\n /*\n * We invert the upper buildWhereBoundClause to only represent the data\n * after `before`, then check if there's at least one record in that set.\n *\n * This only works if the `before` cursor can be represented in the\n * SQL WHERE clause, otherwise we're doing limit/offset pagination\n * which requires different logic. It also only works if there's no\n * `first` clause, otherwise there could be a next page before the\n * `before` clause.\n */\n return sql.fragment`\\\nexists(\n ${sqlCommonUnbounded}\n where ${queryBuilder.buildWhereClause(false, false, options)}\n and not (${queryBuilder.buildWhereBoundClause(invert)})\n)`;\n } else {\n assert(queryHasFirst);\n // queryHasBefore could be true or false.\n /*\n * There's a few ways that we could determine if there's a next page.\n *\n * If !queryHasBefore, we could COUNT(*) the number of rows in\n * `sqlCommon` and see if it's larger than `first`:\n * `(select count(*) > ${first} from (${sqlCommon}) __random_table_alias__)`\n *\n * If !queryHasBefore, we could build a subquery table of offsetData\n * from sqlCommon and see if it contains any rows:\n * `EXISTS(select 1 from (${sqlCommon} OFFSET ${first}) __random_table_alias__)`.\n *\n * We could see if there's at least one row in sqlCommon that's not\n * already in our chosen result set.\n *\n * We've chosen the latter approach here because it doesn't place a limit\n * on queryHasBefore.\n */\n // Drop the `first` limit, see if there are any records that aren't\n // already in the list we've fetched.\n return sql.fragment`\\\nexists(\n ${sqlCommon}\n and (${queryBuilder.getSelectCursor()})::text not in (select __cursor::text from ${sqlQueryAlias})\n ${offset === 0 ? sql.blank : sql.fragment`offset ${sql.value(offset)}`}\n)`;\n }\n } else {\n assert(!invert || offset === 0); // isForwardOrSymmetric\n assert(!canHaveCursorInWhere);\n // We're dealing with LIMIT/OFFSET pagination here, which means `natural`\n // cursors, so the `queryBuilder` factors the before/after, first/last\n // into the limit / offset.\n const { limit } = queryBuilder.getFinalLimitAndOffset();\n\n if (limit == null) {\n // If paginating backwards, then offset > 0 has already been dealt\n // with. Unbounded, so there's no next page.\n return sql.fragment`false`;\n } else if (invert) {\n assert(offset === 0);\n // Paginating backwards and there's no offset (which factors in before/after), so there's no previous page.\n return sql.fragment`false`;\n } else {\n assert(!invert);\n /*\n * We're paginating forwards; either there's a before, there's a first,\n * or both.\n *\n * We want to see if there's more than limit+offset records in sqlCommon.\n */\n return sql.fragment`\\\nexists(\n ${sqlCommon}\n offset ${sql.literal(limit + offset)}\n)`;\n }\n }\n }\n const getPgCursorPrefix = () =>\n rawCursorPrefix && rawCursorPrefix.length > 0\n ? rawCursorPrefix\n : queryBuilder.data.cursorPrefix.map(val => sql.literal(val));\n if (\n options.withPagination ||\n options.withPaginationAsFields ||\n options.withCursor\n ) {\n // Sometimes we need a __cursor even if it's not a collection; e.g. to get the edge field on a mutation\n if (usesCursor) {\n queryBuilder.selectCursor((): SQL => {\n const orderBy = queryBuilder\n .getOrderByExpressionsAndDirections()\n .map(([expr]) => expr);\n if (queryBuilder.isOrderUnique() && orderBy.length > 0) {\n return sql.fragment`json_build_array(${sql.join(\n [\n ...getPgCursorPrefix(),\n sql.fragment`json_build_array(${sql.join(orderBy, \", \")})`,\n ],\n \", \"\n )})`;\n } else {\n return sql.fragment`json_build_array(${sql.join(\n getPgCursorPrefix(),\n \", \"\n )}, ${\n /*\n * NOTE[useAsterisk/row_number]: If we have useAsterisk then the\n * query with limit offset is in a subquery, so our row_number()\n * call doesn't know about it. Here we add the offset back in\n * again. See matching NOTE in QueryBuilder.js.\n */\n options.useAsterisk\n ? sql.fragment`${sql.literal(\n queryBuilder.getFinalOffset() || 0\n )} + `\n : sql.fragment``\n }(row_number() over (partition by 1)))`;\n }\n });\n }\n }\n if (options.withPagination || options.withPaginationAsFields) {\n queryBuilder.setCursorComparator((cursorValue, isAfter) => {\n function badCursor() {\n queryBuilder.whereBound(sql.fragment`false`, isAfter);\n }\n const orderByExpressionsAndDirections =\n queryBuilder.getOrderByExpressionsAndDirections();\n if (orderByExpressionsAndDirections.length > 0) {\n if (!queryBuilder.isOrderUnique()) {\n throw new Error(\n \"The order supplied is not unique, so before/after cursors cannot be used. Please ensure the supplied order includes all the columns from the primary key or a unique constraint.\"\n );\n }\n const rawPrefixes = cursorValue.slice(0, cursorValue.length - 1);\n const rawCursors = cursorValue[cursorValue.length - 1];\n if (rawPrefixes.length !== getPgCursorPrefix().length) {\n badCursor();\n return;\n }\n if (!Array.isArray(rawCursors)) {\n badCursor();\n return;\n }\n let sqlFilter = sql.fragment`false`;\n const sqlCursors = rawCursors.map(val => sql.value(val));\n for (\n let i = orderByExpressionsAndDirections.length - 1;\n i >= 0;\n i--\n ) {\n const [sqlExpression, ascending] =\n orderByExpressionsAndDirections[i];\n // If ascending and isAfter then >\n // If ascending and isBefore then <\n const comparison =\n Number(ascending) ^ Number(!isAfter)\n ? sql.fragment`>`\n : sql.fragment`<`;\n\n const sqlOldFilter = sqlFilter;\n sqlFilter = sql.fragment`\\\n(\\\n (${sqlExpression} ${comparison} ${sqlCursors[i] || sql.null})\nOR\\\n (\\\n ${sqlExpression} = ${sqlCursors[i] || sql.null}\\\n AND\\\n ${sqlOldFilter}\\\n )\\\n)`;\n }\n\n // Check the cursor prefixes apply\n // TODO:v5: we should be able to do this in JS-land rather than SQL-land\n sqlFilter = sql.fragment`(((${sql.join(\n getPgCursorPrefix(),\n \", \"\n )}) = (${sql.join(\n rawPrefixes.map(val => sql.value(val)),\n \", \"\n )})) AND (${sqlFilter}))`;\n queryBuilder.whereBound(sqlFilter, isAfter);\n } else if (\n cursorValue[0] === \"natural\" &&\n isSafeInteger(cursorValue[1]) &&\n // $FlowFixMe: we know this is a number\n cursorValue[1] >= 0\n ) {\n // $FlowFixMe: we know this is a number\n const cursorValue1: number = cursorValue[1];\n if (isAfter) {\n queryBuilder.offset(() => cursorValue1);\n } else {\n queryBuilder.limit(() => {\n const offset = queryBuilder.getOffset();\n return Math.max(0, cursorValue1 - offset - 1);\n });\n }\n } else {\n throw new Error(\n \"Cannot use 'before'/'after' without unique 'orderBy'\"\n );\n }\n });\n\n const query = queryBuilder.build(options);\n const haveFields = queryBuilder.getSelectFieldsCount() > 0;\n const sqlQueryAlias = sql.identifier(Symbol());\n const sqlSummaryAlias = sql.identifier(Symbol());\n //\n // Tables should ALWAYS push their PK onto the order stack, if this isn't\n // present then we're either dealing with a view or a table without a PK.\n // Either way, we don't have anything to guarantee uniqueness so we need to\n // fall back to limit/offset.\n //\n // TODO: support unique keys in PgAllRows etc\n // TODO: add a warning for cursor-based pagination when using the fallback\n // TODO: if it is a view maybe add a warning encouraging pgViewUniqueKey\n const canHaveCursorInWhere =\n queryBuilder.getOrderByExpressionsAndDirections().length > 0 &&\n queryBuilder.isOrderUnique();\n const queryHasBefore =\n queryBuilder.compiledData.whereBound.upper.length > 0;\n const queryHasAfter =\n queryBuilder.compiledData.whereBound.lower.length > 0;\n const queryHasZeroLimit = queryBuilder.getFinalLimit() === 0;\n const queryHasFirst = isSafeInteger(queryBuilder.compiledData.first);\n const queryHasLast = isSafeInteger(queryBuilder.compiledData.last);\n const hasNextPage = queryHasZeroLimit\n ? sql.literal(false)\n : generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasBefore,\n queryHasFirst,\n queryBuilder.getFinalOffset() || 0\n );\n const hasPreviousPage = queryHasZeroLimit\n ? sql.literal(false)\n : generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasAfter,\n queryHasLast,\n queryBuilder.getFinalOffset() || 0,\n true\n );\n\n const sqlWith = haveFields\n ? sql.fragment`with ${sqlQueryAlias} as (${query}), ${sqlSummaryAlias} as (select json_agg(to_json(${sqlQueryAlias})) as data from ${sqlQueryAlias})`\n : sql.fragment``;\n const sqlFrom = sql.fragment``;\n const fields: Array<[SQL, RawAlias]> = [];\n if (haveFields) {\n fields.push([\n sql.fragment`coalesce((select ${sqlSummaryAlias}.data from ${sqlSummaryAlias}), '[]'::json)`,\n \"data\",\n ]);\n if (calculateHasNextPage) {\n fields.push([hasNextPage, \"hasNextPage\"]);\n }\n if (calculateHasPreviousPage) {\n fields.push([hasPreviousPage, \"hasPreviousPage\"]);\n }\n }\n if (pgNamedQuery && pgNamedQuery.length) {\n const groups = {};\n pgNamedQuery.forEach(({ name, query }) => {\n assertSafeName(name);\n if (!groups[name]) {\n groups[name] = [];\n }\n groups[name].push(query);\n });\n Object.keys(groups).forEach(groupName => {\n const queryCallbacks = groups[groupName];\n\n // Get container\n const containers = pgNamedQueryContainer.filter(\n c => c.name === groupName\n );\n if (containers.length === 0) {\n throw new Error(\n `${queryCallbacks.length} pgNamedQuery entries with name: '${groupName}' existed, but there was no matching pgNamedQueryContainer.`\n );\n }\n if (containers.length > 1) {\n throw new Error(\n `${containers.length} pgNamedQueryContainer entries with name: '${groupName}' existed, but there should be exactly one.`\n );\n }\n const container = containers[0];\n\n const innerQueryBuilder = new QueryBuilder(\n queryBuilderOptions,\n context,\n rootValue\n );\n innerQueryBuilder.from(\n queryBuilder.getTableExpression(),\n queryBuilder.getTableAlias()\n );\n\n for (let i = 0, l = queryCallbacks.length; i < l; i++) {\n queryCallbacks[i](innerQueryBuilder);\n }\n\n // Generate the SQL statement (e.g. `select ${innerQueryBuilder.build({onlyJsonField: true})} from ${queryBuilder.getTableExpression()} as ...`)\n const aggregatesSql = container.query({\n queryBuilder,\n innerQueryBuilder,\n options,\n });\n\n fields.push([aggregatesSql, groupName]);\n });\n }\n if (options.withPaginationAsFields) {\n return sql.fragment`${sqlWith} select ${sql.join(\n fields.map(\n ([expr, alias]) => sql.fragment`${expr} as ${sql.identifier(alias)}`\n ),\n \", \"\n )} ${sqlFrom}`;\n } else {\n return sql.fragment`${sqlWith} select ${queryBuilder.jsonbBuildObject(\n fields\n )} ${sqlFrom}`;\n }\n } else {\n const query = queryBuilder.build(options);\n return query;\n }\n };\n"],"file":"queryFromResolveDataFactory.js"}
1
+ {"version":3,"file":"queryFromResolveDataFactory.js","names":["_QueryBuilder","_interopRequireDefault","require","sql","_interopRequireWildcard","_isSafeInteger","_assert","_util","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","identity","_","undefined","assertSafeName","name","Error","inspect","test","_default","queryBuilderOptions","from","fromAlias","resolveData","inOptions","withBuilder","context","rootValue","pgQuery","pgAggregateQuery","pgNamedQueryContainer","pgNamedQuery","pgCursorPrefix","reallyRawCursorPrefix","pgDontUseAsterisk","calculateHasNextPage","calculateHasPreviousPage","usesCursor","explicitlyUsesCursor","length","push","query","queryBuilder","options","innerQueryBuilder","fragment","build","onlyJsonField","getTableExpression","getTableAlias","buildWhereClause","forEach","preventAsterisk","useAsterisk","rawCursorPrefix","filter","QueryBuilder","i","l","generateNextPrevPageSql","sqlQueryAlias","canHaveCursorInWhere","queryHasBefore","queryHasFirst","offset","invert","sqlCommonUnbounded","sqlCommon","isForwardOrSymmetric","assert","literal","buildWhereBoundClause","getSelectCursor","blank","value","limit","getFinalLimitAndOffset","getPgCursorPrefix","data","cursorPrefix","map","val","withPagination","withPaginationAsFields","withCursor","selectCursor","orderBy","getOrderByExpressionsAndDirections","expr","isOrderUnique","join","getFinalOffset","setCursorComparator","cursorValue","isAfter","badCursor","whereBound","orderByExpressionsAndDirections","rawPrefixes","slice","rawCursors","Array","isArray","sqlFilter","sqlCursors","sqlExpression","ascending","comparison","Number","sqlOldFilter","null","isSafeInteger","cursorValue1","getOffset","Math","max","haveFields","getSelectFieldsCount","identifier","Symbol","sqlSummaryAlias","compiledData","upper","queryHasAfter","lower","queryHasZeroLimit","getFinalLimit","first","queryHasLast","last","hasNextPage","hasPreviousPage","sqlWith","sqlFrom","fields","groups","keys","groupName","queryCallbacks","containers","c","container","aggregatesSql","alias","jsonbBuildObject","exports"],"sources":["../src/queryFromResolveDataFactory.js"],"sourcesContent":["// @flow\nimport QueryBuilder from \"./QueryBuilder\";\nimport type { QueryBuilderOptions } from \"./QueryBuilder\";\nimport type { RawAlias } from \"./QueryBuilder\";\nimport * as sql from \"pg-sql2\";\nimport type { SQL } from \"pg-sql2\";\nimport type { DataForType } from \"graphile-build\";\nimport isSafeInteger from \"lodash/isSafeInteger\";\nimport assert from \"assert\";\nimport { inspect } from \"util\";\n\n// eslint-disable-next-line flowtype/no-weak-types\ntype GraphQLContext = any;\n\nconst identity = _ => _ !== null && _ !== undefined;\n\nfunction assertSafeName(name: mixed) {\n if (typeof name !== \"string\") {\n throw new Error(\n `Expected name to be a string; instead received '${inspect(name)}'`\n );\n }\n if (!/^[@a-zA-Z0-9_]{1,63}$/.test(name)) {\n throw new Error(\n `Name '${name}' is not safe - either it is too long, too short, or has invalid characters`\n );\n }\n}\n\nexport default (queryBuilderOptions: QueryBuilderOptions = {}) =>\n (\n from: SQL,\n fromAlias: ?SQL,\n resolveData: DataForType,\n inOptions: {\n withPagination?: boolean,\n withPaginationAsFields?: boolean,\n asJson?: boolean,\n asJsonAggregate?: boolean,\n addNullCase?: boolean,\n addNotDistinctFromNullCase?: boolean,\n onlyJsonField?: boolean,\n useAsterisk?: boolean,\n withCursor?: boolean,\n },\n // TODO:v5: context is not optional\n withBuilder?: ((builder: QueryBuilder) => void) | null | void,\n context?: GraphQLContext = {},\n rootValue?: any // eslint-disable-line flowtype/no-weak-types\n ) => {\n const {\n pgQuery,\n pgAggregateQuery, // Shorthand for using pgNamedQueryContainer/pgNamedQuery combo\n pgNamedQueryContainer = [],\n pgNamedQuery = [],\n pgCursorPrefix: reallyRawCursorPrefix,\n pgDontUseAsterisk,\n calculateHasNextPage,\n calculateHasPreviousPage,\n usesCursor: explicitlyUsesCursor,\n } = resolveData;\n // Push a query container for aggregates\n if ((pgAggregateQuery && pgAggregateQuery.length) || pgNamedQuery.length) {\n pgNamedQueryContainer.push({\n name: \"aggregates\",\n query: ({ queryBuilder, options, innerQueryBuilder }) => sql.fragment`\\\n(\n select ${innerQueryBuilder.build({ onlyJsonField: true })}\n from ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}\n where ${queryBuilder.buildWhereClause(false, false, options)}\n)`,\n });\n }\n // Convert pgAggregateQuery to pgNamedQueryContainer/pgNamedQuery combo\n if (pgAggregateQuery && pgAggregateQuery.length) {\n // And a query for each previous query\n pgAggregateQuery.forEach(query => {\n pgNamedQuery.push({ name: \"aggregates\", query });\n });\n }\n\n const preventAsterisk = pgDontUseAsterisk\n ? pgDontUseAsterisk.length > 0\n : false;\n const options = {\n ...inOptions,\n // Allow pgDontUseAsterisk to override useAsterisk\n useAsterisk: inOptions.useAsterisk && !preventAsterisk,\n };\n\n const usesCursor: boolean =\n (explicitlyUsesCursor && explicitlyUsesCursor.length > 0) ||\n (calculateHasNextPage && calculateHasNextPage.length > 0) ||\n (calculateHasPreviousPage && calculateHasPreviousPage.length > 0) ||\n false;\n const rawCursorPrefix =\n reallyRawCursorPrefix && reallyRawCursorPrefix.filter(identity);\n\n const queryBuilder = new QueryBuilder(\n queryBuilderOptions,\n context,\n rootValue\n );\n queryBuilder.from(from, fromAlias ? fromAlias : undefined);\n\n if (withBuilder) {\n withBuilder(queryBuilder);\n }\n if (pgQuery) {\n for (let i = 0, l = pgQuery.length; i < l; i++) {\n pgQuery[i](queryBuilder, resolveData);\n }\n }\n\n function generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasBefore,\n queryHasFirst,\n offset = 0,\n invert = false\n ) {\n /*\n * Strap in, 'coz this function gets hairy!\n *\n * The point of this function is to return SQL which will resolve to a\n * boolean true/false depending on whether or not there is a (invert ?\n * \"previous\" : \"next\") page.\n *\n * Connections have before, after, first, last and offset.\n * - Users are forbidden from setting both first and last.\n * - Users are forbidden from setting both offset and last.\n *\n * Further there are two main modes of paginating, one works by adding a\n * where clause (this is preferred, but is not always possible, and is\n * indicated by `canHaveCursorInWhere === true`) and the other works using\n * standard LIMIT/OFFSET SQL pagination (and is indicated by\n * `canHaveCursorInWhere === false`).\n *\n * The following diagram shows a full collection of records, #, starting at\n * START and ending at END. The key after, before, offset, first and last\n * variables are shown. One thing not show is that it's possible to have\n * fewer records between before and after than requested by first or last.\n * Another detail not clearly show is that if there is no `after` then\n * `START` is used, similarly if there is no `before` then `END` is used.\n *\n * #################################################### < collection\n * ^ ^<-offset->^<-first->^ ^<-last->^ ^\n * | | | | | | |\n * | | +---------+ +--------+ |\n * | | | DATA1 DATA2 | |\n * | | | | |\n * | | | | |\n * | | +-------------------------+ |\n * | | DATA3 | |\n * | after before |\n * | |\n * START END\n *\n * We want one of the three DATA blocks:\n *\n * - If `first` is set, then we want DATA1.\n * - If `last` is set then we want DATA2.\n * - If neither is set then we want DATA3.\n *\n * (Remember: you cannot set both `first` and `last` at the same time.)\n *\n * When invert === false:\n *\n * Note that both DATA2 and DATA3 end at the same point, and we only care\n * if there's data *after* the relevant DATA block, so really we only\n * care if the query specified `first` (`queryHasFirst`) which makes\n * things complex (ending at the end of DATA1), otherwise we can use\n * `before` as the bound (end of DATA2/DATA3).\n *\n * When invert === true:\n *\n * Similarly, DATA1 and DATA3 start at the same point, and we're going\n * backwards so we only care if there's data *before* the DATA block, so\n * really we just need to know if the query set `last` or not, but since\n * this is inverted we call it `queryHasFirst`.\n *\n * When `invert` is false we're calculating `hasNextPage`, when true we're\n * calculating `hasPreviousPage`.\n *\n * Because of the near-symmetry of requesting hasPreviousPage vs\n * hasNextPage we always pretend we're determining `hasNextPage`, and we\n * just invert everything.\n */\n\n const sqlCommonUnbounded = sql.fragment`\\\nselect 1\nfrom ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}`;\n /*\n * This variable is a fragment to go into an `EXISTS(...)` call (after some tweaks).\n *\n * The buildWhereClause takes three arguments:\n *\n * - includeLowerBound (we want this for hasNextPage but not hasPreviousPage)\n * - includeUpperBound (we want this for hasPreviousPage but not hasNextPage)\n * - options (specifically `{addNullCase, addNotDistinctFromNullCase}`) -\n * we just pass this through.\n *\n * So in hasNextPage mode (invert === false), this common SQL ends up\n * representing the collection from `(after || START)` onwards with no\n * upper bound. In hasPreviousPage mode (invert === true), it represents\n * everything from `(before || END)` backwards, with no lower bound.\n */\n const sqlCommon = sql.fragment`\\\n${sqlCommonUnbounded}\nwhere ${queryBuilder.buildWhereClause(!invert, invert, options)}`;\n\n /*\n * Since the offset makes the diagram asymmetric, if offset === 0\n * then the diagram is symmetric and things are simplified a little.\n */\n const isForwardOrSymmetric = !invert || offset === 0;\n\n if (!isForwardOrSymmetric) {\n assert(invert);\n assert(offset > 0);\n // We're looking for a previous page, and there's an offset, so lets just\n // assume there's a previous page where offset is smaller.\n return sql.literal(true);\n } else if (canHaveCursorInWhere) {\n assert(isForwardOrSymmetric);\n if (!queryHasBefore && !queryHasFirst) {\n assert(isForwardOrSymmetric);\n // There can be no next page since there's no upper bound\n return sql.literal(false);\n } else if (queryHasBefore && !queryHasFirst) {\n /*\n * We invert the upper buildWhereBoundClause to only represent the data\n * after `before`, then check if there's at least one record in that set.\n *\n * This only works if the `before` cursor can be represented in the\n * SQL WHERE clause, otherwise we're doing limit/offset pagination\n * which requires different logic. It also only works if there's no\n * `first` clause, otherwise there could be a next page before the\n * `before` clause.\n */\n return sql.fragment`\\\nexists(\n ${sqlCommonUnbounded}\n where ${queryBuilder.buildWhereClause(false, false, options)}\n and not (${queryBuilder.buildWhereBoundClause(invert)})\n)`;\n } else {\n assert(queryHasFirst);\n // queryHasBefore could be true or false.\n /*\n * There's a few ways that we could determine if there's a next page.\n *\n * If !queryHasBefore, we could COUNT(*) the number of rows in\n * `sqlCommon` and see if it's larger than `first`:\n * `(select count(*) > ${first} from (${sqlCommon}) __random_table_alias__)`\n *\n * If !queryHasBefore, we could build a subquery table of offsetData\n * from sqlCommon and see if it contains any rows:\n * `EXISTS(select 1 from (${sqlCommon} OFFSET ${first}) __random_table_alias__)`.\n *\n * We could see if there's at least one row in sqlCommon that's not\n * already in our chosen result set.\n *\n * We've chosen the latter approach here because it doesn't place a limit\n * on queryHasBefore.\n */\n // Drop the `first` limit, see if there are any records that aren't\n // already in the list we've fetched.\n return sql.fragment`\\\nexists(\n ${sqlCommon}\n and (${queryBuilder.getSelectCursor()})::text not in (select __cursor::text from ${sqlQueryAlias})\n ${offset === 0 ? sql.blank : sql.fragment`offset ${sql.value(offset)}`}\n)`;\n }\n } else {\n assert(!invert || offset === 0); // isForwardOrSymmetric\n assert(!canHaveCursorInWhere);\n // We're dealing with LIMIT/OFFSET pagination here, which means `natural`\n // cursors, so the `queryBuilder` factors the before/after, first/last\n // into the limit / offset.\n const { limit } = queryBuilder.getFinalLimitAndOffset();\n\n if (limit == null) {\n // If paginating backwards, then offset > 0 has already been dealt\n // with. Unbounded, so there's no next page.\n return sql.fragment`false`;\n } else if (invert) {\n assert(offset === 0);\n // Paginating backwards and there's no offset (which factors in before/after), so there's no previous page.\n return sql.fragment`false`;\n } else {\n assert(!invert);\n /*\n * We're paginating forwards; either there's a before, there's a first,\n * or both.\n *\n * We want to see if there's more than limit+offset records in sqlCommon.\n */\n return sql.fragment`\\\nexists(\n ${sqlCommon}\n offset ${sql.literal(limit + offset)}\n)`;\n }\n }\n }\n const getPgCursorPrefix = () =>\n rawCursorPrefix && rawCursorPrefix.length > 0\n ? rawCursorPrefix\n : queryBuilder.data.cursorPrefix.map(val => sql.literal(val));\n if (\n options.withPagination ||\n options.withPaginationAsFields ||\n options.withCursor\n ) {\n // Sometimes we need a __cursor even if it's not a collection; e.g. to get the edge field on a mutation\n if (usesCursor) {\n queryBuilder.selectCursor((): SQL => {\n const orderBy = queryBuilder\n .getOrderByExpressionsAndDirections()\n .map(([expr]) => expr);\n if (queryBuilder.isOrderUnique() && orderBy.length > 0) {\n return sql.fragment`json_build_array(${sql.join(\n [\n ...getPgCursorPrefix(),\n sql.fragment`json_build_array(${sql.join(orderBy, \", \")})`,\n ],\n \", \"\n )})`;\n } else {\n return sql.fragment`json_build_array(${sql.join(\n getPgCursorPrefix(),\n \", \"\n )}, ${\n /*\n * NOTE[useAsterisk/row_number]: If we have useAsterisk then the\n * query with limit offset is in a subquery, so our row_number()\n * call doesn't know about it. Here we add the offset back in\n * again. See matching NOTE in QueryBuilder.js.\n */\n options.useAsterisk\n ? sql.fragment`${sql.literal(\n queryBuilder.getFinalOffset() || 0\n )} + `\n : sql.fragment``\n }(row_number() over (partition by 1)))`;\n }\n });\n }\n }\n if (options.withPagination || options.withPaginationAsFields) {\n queryBuilder.setCursorComparator((cursorValue, isAfter) => {\n function badCursor() {\n queryBuilder.whereBound(sql.fragment`false`, isAfter);\n }\n const orderByExpressionsAndDirections =\n queryBuilder.getOrderByExpressionsAndDirections();\n if (orderByExpressionsAndDirections.length > 0) {\n if (!queryBuilder.isOrderUnique()) {\n throw new Error(\n \"The order supplied is not unique, so before/after cursors cannot be used. Please ensure the supplied order includes all the columns from the primary key or a unique constraint.\"\n );\n }\n const rawPrefixes = cursorValue.slice(0, cursorValue.length - 1);\n const rawCursors = cursorValue[cursorValue.length - 1];\n if (rawPrefixes.length !== getPgCursorPrefix().length) {\n badCursor();\n return;\n }\n if (!Array.isArray(rawCursors)) {\n badCursor();\n return;\n }\n let sqlFilter = sql.fragment`false`;\n const sqlCursors = rawCursors.map(val => sql.value(val));\n for (\n let i = orderByExpressionsAndDirections.length - 1;\n i >= 0;\n i--\n ) {\n const [sqlExpression, ascending] =\n orderByExpressionsAndDirections[i];\n // If ascending and isAfter then >\n // If ascending and isBefore then <\n const comparison =\n Number(ascending) ^ Number(!isAfter)\n ? sql.fragment`>`\n : sql.fragment`<`;\n\n const sqlOldFilter = sqlFilter;\n sqlFilter = sql.fragment`\\\n(\\\n (${sqlExpression} ${comparison} ${sqlCursors[i] || sql.null})\nOR\\\n (\\\n ${sqlExpression} = ${sqlCursors[i] || sql.null}\\\n AND\\\n ${sqlOldFilter}\\\n )\\\n)`;\n }\n\n // Check the cursor prefixes apply\n // TODO:v5: we should be able to do this in JS-land rather than SQL-land\n sqlFilter = sql.fragment`(((${sql.join(\n getPgCursorPrefix(),\n \", \"\n )}) = (${sql.join(\n rawPrefixes.map(val => sql.value(val)),\n \", \"\n )})) AND (${sqlFilter}))`;\n queryBuilder.whereBound(sqlFilter, isAfter);\n } else if (\n cursorValue[0] === \"natural\" &&\n isSafeInteger(cursorValue[1]) &&\n // $FlowFixMe: we know this is a number\n cursorValue[1] >= 0\n ) {\n // $FlowFixMe: we know this is a number\n const cursorValue1: number = cursorValue[1];\n if (isAfter) {\n queryBuilder.offset(() => cursorValue1);\n } else {\n queryBuilder.limit(() => {\n const offset = queryBuilder.getOffset();\n return Math.max(0, cursorValue1 - offset - 1);\n });\n }\n } else {\n throw new Error(\n \"Cannot use 'before'/'after' without unique 'orderBy'\"\n );\n }\n });\n\n const query = queryBuilder.build(options);\n const haveFields = queryBuilder.getSelectFieldsCount() > 0;\n const sqlQueryAlias = sql.identifier(Symbol());\n const sqlSummaryAlias = sql.identifier(Symbol());\n //\n // Tables should ALWAYS push their PK onto the order stack, if this isn't\n // present then we're either dealing with a view or a table without a PK.\n // Either way, we don't have anything to guarantee uniqueness so we need to\n // fall back to limit/offset.\n //\n // TODO: support unique keys in PgAllRows etc\n // TODO: add a warning for cursor-based pagination when using the fallback\n // TODO: if it is a view maybe add a warning encouraging pgViewUniqueKey\n const canHaveCursorInWhere =\n queryBuilder.getOrderByExpressionsAndDirections().length > 0 &&\n queryBuilder.isOrderUnique();\n const queryHasBefore =\n queryBuilder.compiledData.whereBound.upper.length > 0;\n const queryHasAfter =\n queryBuilder.compiledData.whereBound.lower.length > 0;\n const queryHasZeroLimit = queryBuilder.getFinalLimit() === 0;\n const queryHasFirst = isSafeInteger(queryBuilder.compiledData.first);\n const queryHasLast = isSafeInteger(queryBuilder.compiledData.last);\n const hasNextPage = queryHasZeroLimit\n ? sql.literal(false)\n : generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasBefore,\n queryHasFirst,\n queryBuilder.getFinalOffset() || 0\n );\n const hasPreviousPage = queryHasZeroLimit\n ? sql.literal(false)\n : generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasAfter,\n queryHasLast,\n queryBuilder.getFinalOffset() || 0,\n true\n );\n\n const sqlWith = haveFields\n ? sql.fragment`with ${sqlQueryAlias} as (${query}), ${sqlSummaryAlias} as (select json_agg(to_json(${sqlQueryAlias})) as data from ${sqlQueryAlias})`\n : sql.fragment``;\n const sqlFrom = sql.fragment``;\n const fields: Array<[SQL, RawAlias]> = [];\n if (haveFields) {\n fields.push([\n sql.fragment`coalesce((select ${sqlSummaryAlias}.data from ${sqlSummaryAlias}), '[]'::json)`,\n \"data\",\n ]);\n if (calculateHasNextPage) {\n fields.push([hasNextPage, \"hasNextPage\"]);\n }\n if (calculateHasPreviousPage) {\n fields.push([hasPreviousPage, \"hasPreviousPage\"]);\n }\n }\n if (pgNamedQuery && pgNamedQuery.length) {\n const groups = {};\n pgNamedQuery.forEach(({ name, query }) => {\n assertSafeName(name);\n if (!groups[name]) {\n groups[name] = [];\n }\n groups[name].push(query);\n });\n Object.keys(groups).forEach(groupName => {\n const queryCallbacks = groups[groupName];\n\n // Get container\n const containers = pgNamedQueryContainer.filter(\n c => c.name === groupName\n );\n if (containers.length === 0) {\n throw new Error(\n `${queryCallbacks.length} pgNamedQuery entries with name: '${groupName}' existed, but there was no matching pgNamedQueryContainer.`\n );\n }\n if (containers.length > 1) {\n throw new Error(\n `${containers.length} pgNamedQueryContainer entries with name: '${groupName}' existed, but there should be exactly one.`\n );\n }\n const container = containers[0];\n\n const innerQueryBuilder = new QueryBuilder(\n queryBuilderOptions,\n context,\n rootValue\n );\n innerQueryBuilder.from(\n queryBuilder.getTableExpression(),\n queryBuilder.getTableAlias()\n );\n\n for (let i = 0, l = queryCallbacks.length; i < l; i++) {\n queryCallbacks[i](innerQueryBuilder);\n }\n\n // Generate the SQL statement (e.g. `select ${innerQueryBuilder.build({onlyJsonField: true})} from ${queryBuilder.getTableExpression()} as ...`)\n const aggregatesSql = container.query({\n queryBuilder,\n innerQueryBuilder,\n options,\n });\n\n fields.push([aggregatesSql, groupName]);\n });\n }\n if (options.withPaginationAsFields) {\n return sql.fragment`${sqlWith} select ${sql.join(\n fields.map(\n ([expr, alias]) => sql.fragment`${expr} as ${sql.identifier(alias)}`\n ),\n \", \"\n )} ${sqlFrom}`;\n } else {\n return sql.fragment`${sqlWith} select ${queryBuilder.jsonbBuildObject(\n fields\n )} ${sqlFrom}`;\n }\n } else {\n const query = queryBuilder.build(options);\n return query;\n }\n };\n"],"mappings":"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"}
@@ -4,27 +4,27 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.parseTags = void 0;
7
-
8
7
  const parseTags = str => {
9
8
  return str.split(/\r?\n/).reduce((prev, curr) => {
10
9
  if (prev.text !== "") {
11
- return { ...prev,
10
+ return {
11
+ ...prev,
12
12
  text: `${prev.text}\n${curr}`
13
13
  };
14
14
  }
15
-
16
15
  const match = curr.match(/^@[a-zA-Z][a-zA-Z0-9_]*($|\s)/);
17
-
18
16
  if (!match) {
19
- return { ...prev,
17
+ return {
18
+ ...prev,
20
19
  text: curr
21
20
  };
22
21
  }
23
-
24
22
  const key = match[0].slice(1).trim();
25
23
  const value = match[0] === curr ? true : curr.replace(match[0], "");
26
- return { ...prev,
27
- tags: { ...prev.tags,
24
+ return {
25
+ ...prev,
26
+ tags: {
27
+ ...prev.tags,
28
28
  [key]: !Object.prototype.hasOwnProperty.call(prev.tags, key) ? value : Array.isArray(prev.tags[key]) ? [...prev.tags[key], value] : [prev.tags[key], value]
29
29
  }
30
30
  };
@@ -33,6 +33,5 @@ const parseTags = str => {
33
33
  text: ""
34
34
  });
35
35
  };
36
-
37
36
  exports.parseTags = parseTags;
38
37
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.js"],"names":["parseTags","str","split","reduce","prev","curr","text","match","key","slice","trim","value","replace","tags","Object","prototype","hasOwnProperty","call","Array","isArray"],"mappings":";;;;;;;AACO,MAAMA,SAAS,GAAIC,GAAD,IAAiB;AACxC,SAAOA,GAAG,CAACC,KAAJ,CAAU,OAAV,EAAmBC,MAAnB,CACL,CAACC,IAAD,EAAOC,IAAP,KAAgB;AACd,QAAID,IAAI,CAACE,IAAL,KAAc,EAAlB,EAAsB;AACpB,aAAO,EAAE,GAAGF,IAAL;AAAWE,QAAAA,IAAI,EAAG,GAAEF,IAAI,CAACE,IAAK,KAAID,IAAK;AAAvC,OAAP;AACD;;AACD,UAAME,KAAK,GAAGF,IAAI,CAACE,KAAL,CAAW,+BAAX,CAAd;;AACA,QAAI,CAACA,KAAL,EAAY;AACV,aAAO,EAAE,GAAGH,IAAL;AAAWE,QAAAA,IAAI,EAAED;AAAjB,OAAP;AACD;;AACD,UAAMG,GAAG,GAAGD,KAAK,CAAC,CAAD,CAAL,CAASE,KAAT,CAAe,CAAf,EAAkBC,IAAlB,EAAZ;AACA,UAAMC,KAAK,GAAGJ,KAAK,CAAC,CAAD,CAAL,KAAaF,IAAb,GAAoB,IAApB,GAA2BA,IAAI,CAACO,OAAL,CAAaL,KAAK,CAAC,CAAD,CAAlB,EAAuB,EAAvB,CAAzC;AACA,WAAO,EACL,GAAGH,IADE;AAELS,MAAAA,IAAI,EAAE,EACJ,GAAGT,IAAI,CAACS,IADJ;AAEJ,SAACL,GAAD,GAAO,CAACM,MAAM,CAACC,SAAP,CAAiBC,cAAjB,CAAgCC,IAAhC,CAAqCb,IAAI,CAACS,IAA1C,EAAgDL,GAAhD,CAAD,GACHG,KADG,GAEHO,KAAK,CAACC,OAAN,CAAcf,IAAI,CAACS,IAAL,CAAUL,GAAV,CAAd,IACA,CAAC,GAAGJ,IAAI,CAACS,IAAL,CAAUL,GAAV,CAAJ,EAAoBG,KAApB,CADA,GAEA,CAACP,IAAI,CAACS,IAAL,CAAUL,GAAV,CAAD,EAAiBG,KAAjB;AANA;AAFD,KAAP;AAWD,GAtBI,EAuBL;AACEE,IAAAA,IAAI,EAAE,EADR;AAEEP,IAAAA,IAAI,EAAE;AAFR,GAvBK,CAAP;AA4BD,CA7BM","sourcesContent":["// @flow\nexport const parseTags = (str: string) => {\n return str.split(/\\r?\\n/).reduce(\n (prev, curr) => {\n if (prev.text !== \"\") {\n return { ...prev, text: `${prev.text}\\n${curr}` };\n }\n const match = curr.match(/^@[a-zA-Z][a-zA-Z0-9_]*($|\\s)/);\n if (!match) {\n return { ...prev, text: curr };\n }\n const key = match[0].slice(1).trim();\n const value = match[0] === curr ? true : curr.replace(match[0], \"\");\n return {\n ...prev,\n tags: {\n ...prev.tags,\n [key]: !Object.prototype.hasOwnProperty.call(prev.tags, key)\n ? value\n : Array.isArray(prev.tags[key])\n ? [...prev.tags[key], value]\n : [prev.tags[key], value],\n },\n };\n },\n {\n tags: {},\n text: \"\",\n }\n );\n};\n"],"file":"utils.js"}
1
+ {"version":3,"file":"utils.js","names":["parseTags","str","split","reduce","prev","curr","text","match","key","slice","trim","value","replace","tags","Object","prototype","hasOwnProperty","call","Array","isArray","exports"],"sources":["../src/utils.js"],"sourcesContent":["// @flow\nexport const parseTags = (str: string) => {\n return str.split(/\\r?\\n/).reduce(\n (prev, curr) => {\n if (prev.text !== \"\") {\n return { ...prev, text: `${prev.text}\\n${curr}` };\n }\n const match = curr.match(/^@[a-zA-Z][a-zA-Z0-9_]*($|\\s)/);\n if (!match) {\n return { ...prev, text: curr };\n }\n const key = match[0].slice(1).trim();\n const value = match[0] === curr ? true : curr.replace(match[0], \"\");\n return {\n ...prev,\n tags: {\n ...prev.tags,\n [key]: !Object.prototype.hasOwnProperty.call(prev.tags, key)\n ? value\n : Array.isArray(prev.tags[key])\n ? [...prev.tags[key], value]\n : [prev.tags[key], value],\n },\n };\n },\n {\n tags: {},\n text: \"\",\n }\n );\n};\n"],"mappings":";;;;;;AACO,MAAMA,SAAS,GAAIC,GAAW,IAAK;EACxC,OAAOA,GAAG,CAACC,KAAK,CAAC,OAAO,CAAC,CAACC,MAAM,CAC9B,CAACC,IAAI,EAAEC,IAAI,KAAK;IACd,IAAID,IAAI,CAACE,IAAI,KAAK,EAAE,EAAE;MACpB,OAAO;QAAE,GAAGF,IAAI;QAAEE,IAAI,EAAG,GAAEF,IAAI,CAACE,IAAK,KAAID,IAAK;MAAE,CAAC;IACnD;IACA,MAAME,KAAK,GAAGF,IAAI,CAACE,KAAK,CAAC,+BAA+B,CAAC;IACzD,IAAI,CAACA,KAAK,EAAE;MACV,OAAO;QAAE,GAAGH,IAAI;QAAEE,IAAI,EAAED;MAAK,CAAC;IAChC;IACA,MAAMG,GAAG,GAAGD,KAAK,CAAC,CAAC,CAAC,CAACE,KAAK,CAAC,CAAC,CAAC,CAACC,IAAI,CAAC,CAAC;IACpC,MAAMC,KAAK,GAAGJ,KAAK,CAAC,CAAC,CAAC,KAAKF,IAAI,GAAG,IAAI,GAAGA,IAAI,CAACO,OAAO,CAACL,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACnE,OAAO;MACL,GAAGH,IAAI;MACPS,IAAI,EAAE;QACJ,GAAGT,IAAI,CAACS,IAAI;QACZ,CAACL,GAAG,GAAG,CAACM,MAAM,CAACC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACb,IAAI,CAACS,IAAI,EAAEL,GAAG,CAAC,GACxDG,KAAK,GACLO,KAAK,CAACC,OAAO,CAACf,IAAI,CAACS,IAAI,CAACL,GAAG,CAAC,CAAC,GAC7B,CAAC,GAAGJ,IAAI,CAACS,IAAI,CAACL,GAAG,CAAC,EAAEG,KAAK,CAAC,GAC1B,CAACP,IAAI,CAACS,IAAI,CAACL,GAAG,CAAC,EAAEG,KAAK;MAC5B;IACF,CAAC;EACH,CAAC,EACD;IACEE,IAAI,EAAE,CAAC,CAAC;IACRP,IAAI,EAAE;EACR,CACF,CAAC;AACH,CAAC;AAACc,OAAA,CAAApB,SAAA,GAAAA,SAAA"}