@technicity/data-service-generator 0.4.3 → 0.4.7

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.
@@ -27,7 +27,7 @@ function getOrderBy(args, primaryKey) {
27
27
  out = out.concat(orderByPrimaryKey);
28
28
  }
29
29
  }
30
- flip = getFlip(args, out, primaryKey);
30
+ flip = getFlip(args);
31
31
  if (flip) {
32
32
  out = flipOrderByDirection(out);
33
33
  }
@@ -35,16 +35,8 @@ function getOrderBy(args, primaryKey) {
35
35
  return { orderBy: out, flip };
36
36
  }
37
37
  exports.getOrderBy = getOrderBy;
38
- function getFlip(args, orderBy, primaryKey) {
39
- if (args?.$paginate?.after != null &&
40
- orderBy?.find((x) => x.column === primaryKey)?.direction === "desc") {
41
- return true;
42
- }
43
- if (args?.$paginate?.before != null &&
44
- orderBy?.find((x) => x.column === primaryKey)?.direction === "asc") {
45
- return true;
46
- }
47
- return false;
38
+ function getFlip(args) {
39
+ return args?.$paginate?.last != null;
48
40
  }
49
41
  function flipOrderByDirection(orderBy) {
50
42
  return orderBy.map((x) => ({ ...x, direction: flipDirection(x.direction) }));
package/dist/getSqlAst.js CHANGED
@@ -10,7 +10,7 @@ const _ = require("lodash/fp");
10
10
  const getOrderBy_1 = require("./getOrderBy");
11
11
  const namespace = new alias_namespace_1.default(true);
12
12
  function getSqlAst(input) {
13
- const { table, fieldName, fields, args, grabMany, sqlJoin, sqlBatch, junction, getWhere, artifacts, rowWithCursorId, dialect, } = input;
13
+ const { table, fieldName, fields, args, grabMany, sqlJoin, sqlBatch, junction, getWhere, artifacts, rowWithMatchingCursor, dialect, } = input;
14
14
  const tableArtifacts = artifacts[table];
15
15
  const primaryKey = tableArtifacts.primaryKey;
16
16
  const format = dialect === "mysql"
@@ -25,7 +25,9 @@ function getSqlAst(input) {
25
25
  argsMapped = _.cloneDeep(argsMapped);
26
26
  argsMapped.$where = argsMapped.$where[0];
27
27
  }
28
- const whereResult = getWhere(table, argsMapped, dialect, orderBy, rowWithCursorId);
28
+ const whereResult = getWhere(
29
+ // table is escaped already
30
+ table, argsMapped, dialect, orderBy, rowWithMatchingCursor);
29
31
  if (whereResult == null) {
30
32
  return undefined;
31
33
  }
@@ -112,7 +114,9 @@ function getSqlAst(input) {
112
114
  }
113
115
  const argsMapped = _.cloneDeep(args);
114
116
  argsMapped.$where = argsMapped.$where[1];
115
- const whereResult = getWhere(table, argsMapped, dialect, orderBy, rowWithCursorId);
117
+ const whereResult = getWhere(
118
+ // table is escaped already
119
+ table, argsMapped, dialect, orderBy, rowWithMatchingCursor);
116
120
  if (whereResult == null) {
117
121
  return undefined;
118
122
  }
@@ -1,2 +1,2 @@
1
1
  import type { IOrderBy, IDialect } from "./types";
2
- export declare function getWhere(table: string, args: any, dialect: IDialect, orderBy?: IOrderBy | undefined, rowWithCursorId?: any): string | null;
2
+ export declare function getWhere(table: string, args: any, dialect: IDialect, orderBy?: IOrderBy | undefined, rowWithMatchingCursor?: any): string | null;
package/dist/getWhere.js CHANGED
@@ -2,7 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getWhere = void 0;
4
4
  const stringifyWhere_1 = require("./stringifyWhere");
5
- function getWhere(table, args, dialect, orderBy, rowWithCursorId) {
5
+ function getWhere(
6
+ // Note: `table` is not escaped in getWhere, so it should be escaped beforehand.
7
+ table, args, dialect, orderBy, rowWithMatchingCursor) {
6
8
  if (args?.$where == null && args?.$paginate == null) {
7
9
  return null;
8
10
  }
@@ -13,7 +15,7 @@ function getWhere(table, args, dialect, orderBy, rowWithCursorId) {
13
15
  dialect,
14
16
  args,
15
17
  orderBy,
16
- rowWithCursorId,
18
+ rowWithMatchingCursor,
17
19
  }) || null);
18
20
  }
19
21
  exports.getWhere = getWhere;
@@ -74,7 +74,7 @@ class RuntimeKSQL {
74
74
  delete input.args.$where[k];
75
75
  }
76
76
  }
77
- const where = getWhere_1.getWhere(tableKSQL, input.args, "mysql");
77
+ const where = getWhere_1.getWhere(SqlString.escapeId(tableKSQL), input.args, "mysql");
78
78
  if (!where) {
79
79
  throw new Error("Invalid $where");
80
80
  }
@@ -23,7 +23,7 @@ async function resolve(input, dbCall, formatQuery, options) {
23
23
  const context = {};
24
24
  const kind = input.kind;
25
25
  const primaryKey = input.artifacts[input.table].primaryKey;
26
- let rowWithCursorId = undefined;
26
+ let rowWithMatchingCursor = undefined;
27
27
  if (kind === "listPaginated") {
28
28
  if (input.args?.$paginate == null) {
29
29
  throw new Error("$paginate required but not supplied");
@@ -33,7 +33,7 @@ async function resolve(input, dbCall, formatQuery, options) {
33
33
  const cursor = input.args.$paginate.after != null
34
34
  ? input.args.$paginate.after
35
35
  : input.args.$paginate.before;
36
- rowWithCursorId = await dbCall(formatQuery("SELECT * FROM ?? WHERE ?? = ?", [
36
+ rowWithMatchingCursor = await dbCall(formatQuery("SELECT * FROM ?? WHERE ?? = ?", [
37
37
  input.table,
38
38
  primaryKey,
39
39
  cursor_1.decodeCursor(cursor),
@@ -49,7 +49,7 @@ async function resolve(input, dbCall, formatQuery, options) {
49
49
  fields,
50
50
  getWhere: getWhere_1.getWhere,
51
51
  orderBy: orderByListPaginatedRootResult?.orderBy,
52
- rowWithCursorId,
52
+ rowWithMatchingCursor,
53
53
  dialect: options.dialect,
54
54
  });
55
55
  let { sql, shapeDefinition } = await util_1.compileSqlAST(sqlAST, context, options);
@@ -113,9 +113,31 @@ async function resolve(input, dbCall, formatQuery, options) {
113
113
  // return true;
114
114
  // });
115
115
  if (kind === "listPaginated") {
116
+ const argsTotalCount = input.args && _.cloneDeep(input.args);
117
+ if (argsTotalCount != null) {
118
+ if (argsTotalCount.$paginate != null) {
119
+ // We don't want the where clause to include cursor-related stuff
120
+ delete argsTotalCount.$paginate.after;
121
+ delete argsTotalCount.$paginate.before;
122
+ }
123
+ }
124
+ const sqlASTTotalCount = getSqlAst_1.getSqlAst({
125
+ ...input,
126
+ args: argsTotalCount,
127
+ // Because we're going to manually set children anyway
128
+ fields: [],
129
+ getWhere: getWhere_1.getWhere,
130
+ // We don't want the where clause to include cursor-related stuff
131
+ rowWithMatchingCursor: null,
132
+ dialect: options.dialect,
133
+ });
134
+ // Because orderBy doesn't matter for total count.
135
+ // getOrderBy adds an element if paginating, so deleting args.$orderBy
136
+ // isn't sufficient.
137
+ delete sqlASTTotalCount.orderBy;
116
138
  data = await wrapListPaginated(data, input.args, orderByListPaginatedRootResult.flip, (xs) => {
117
139
  postProcess(xs, fields, shouldRemoveExtraKeys);
118
- }, sqlAST, dbCall, input.artifacts[input.table].primaryKey, context, options);
140
+ }, sqlASTTotalCount, dbCall, input.artifacts[input.table].primaryKey, context, options);
119
141
  }
120
142
  return data;
121
143
  }
@@ -128,11 +150,8 @@ exports.resolve = resolve;
128
150
  // Not recursive at the moment; only supported at the root.
129
151
  // TODO - remove if support for pagination for mysql dialect
130
152
  // is added (I doubt it)
131
- async function wrapListPaginated(data, args, flip, cb, sqlAST, dbCall, primaryKey, context, options) {
132
- const isPaginatingBackward = args.$paginate.last != null;
133
- const limit = isPaginatingBackward
134
- ? args.$paginate.last
135
- : args.$paginate.first;
153
+ async function wrapListPaginated(data, args, flip, cb, sqlASTTotalCount, dbCall, primaryKey, context, options) {
154
+ const limit = flip ? args.$paginate.last : args.$paginate.first;
136
155
  const hasMoreResults = data.length === limit + 1;
137
156
  if (hasMoreResults) {
138
157
  // because we peeked
@@ -141,15 +160,14 @@ async function wrapListPaginated(data, args, flip, cb, sqlAST, dbCall, primaryKe
141
160
  if (flip) {
142
161
  data = data.reverse();
143
162
  }
144
- const hasPreviousPage = isPaginatingBackward ? hasMoreResults : false;
145
- const hasNextPage = isPaginatingBackward ? false : hasMoreResults;
163
+ const hasPreviousPage = flip ? hasMoreResults : false;
164
+ const hasNextPage = flip ? false : hasMoreResults;
146
165
  const startKey = data?.[0]?.[primaryKey];
147
166
  const endKey = data?.[data.length - 1]?.[primaryKey];
148
167
  const startCursor = startKey == null ? null : cursor_1.encodeCursor(startKey);
149
168
  const endCursor = endKey == null ? null : cursor_1.encodeCursor(endKey);
150
169
  // Replace field selection with `COUNT(*)`
151
170
  const fieldNameTotalCount = "totalCount";
152
- const sqlASTTotalCount = { ...sqlAST };
153
171
  sqlASTTotalCount.children = [
154
172
  {
155
173
  type: "expression",
@@ -158,9 +176,6 @@ async function wrapListPaginated(data, args, flip, cb, sqlAST, dbCall, primaryKe
158
176
  as: fieldNameTotalCount,
159
177
  },
160
178
  ];
161
- // Remove ORDER BY to avoid the error:
162
- // Column "X" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.
163
- delete sqlASTTotalCount.orderBy;
164
179
  const { sql: sqlTotalCount } = await util_1.compileSqlAST(sqlASTTotalCount, context, options);
165
180
  const totalCount = await dbCall(sqlTotalCount).then((xs) => xs[0][fieldNameTotalCount]);
166
181
  cb(data);
@@ -225,9 +240,10 @@ async function post(input) {
225
240
  exports.post = post;
226
241
  async function patch(input) {
227
242
  async function _patch() {
228
- const { dbCall, formatQuery } = input;
243
+ const { dbCall, formatQuery, dialect } = input;
244
+ const escapeId = stringifyWhere_1.getEscapeId(dialect);
229
245
  const tableArtifacts = input.artifacts[input.table];
230
- const where = getWhere_1.getWhere(input.table, input.args, input.dialect);
246
+ const where = getWhere_1.getWhere(escapeId(input.table), input.args, input.dialect);
231
247
  if (where == null) {
232
248
  throw new Error("Null where");
233
249
  }
@@ -322,9 +338,10 @@ function getUpdateQuery(table, data, where, dialect, formatQuery) {
322
338
  }
323
339
  async function patchList(input) {
324
340
  async function _patchList() {
325
- const { dbCall, formatQuery } = input;
341
+ const { dbCall, formatQuery, dialect } = input;
342
+ const escapeId = stringifyWhere_1.getEscapeId(dialect);
326
343
  const tableArtifacts = input.artifacts[input.table];
327
- const where = getWhere_1.getWhere(input.table, input.args, input.dialect);
344
+ const where = getWhere_1.getWhere(escapeId(input.table), input.args, input.dialect);
328
345
  if (where == null) {
329
346
  throw new Error("Null where");
330
347
  }
@@ -386,8 +403,9 @@ async function del(input) {
386
403
  }
387
404
  exports.del = del;
388
405
  async function deleteList(input) {
389
- const { dbCall, formatQuery } = input;
390
- const where = getWhere_1.getWhere(input.table, input.args, input.dialect);
406
+ const { dbCall, formatQuery, dialect } = input;
407
+ const escapeId = stringifyWhere_1.getEscapeId(dialect);
408
+ const where = getWhere_1.getWhere(escapeId(input.table), input.args, input.dialect);
391
409
  if (where == null) {
392
410
  throw new Error("Null where");
393
411
  }
@@ -11,7 +11,7 @@ export declare function stringifyWhere(input: {
11
11
  dialect: IDialect;
12
12
  args: IArgs;
13
13
  orderBy?: IOrderBy | undefined;
14
- rowWithCursorId?: any;
14
+ rowWithMatchingCursor?: any;
15
15
  }): string;
16
16
  export declare function getEscapeId(dialect: IDialect): any;
17
17
  export declare function getEscape(dialect: IDialect): any;
@@ -6,7 +6,7 @@ const MySqlString = require("sqlstring");
6
6
  // @ts-ignore
7
7
  const TSqlString = require("tsqlstring");
8
8
  function stringifyWhere(input) {
9
- const { where, table, dialect, args, orderBy, rowWithCursorId } = input;
9
+ const { where, table, dialect, args, orderBy, rowWithMatchingCursor } = input;
10
10
  const escapeId = getEscapeId(dialect);
11
11
  const escape = getEscape(dialect);
12
12
  let result = _stringifyWhere(where, table, escapeId, escape, "");
@@ -16,7 +16,7 @@ function stringifyWhere(input) {
16
16
  orderBy,
17
17
  escapeId,
18
18
  escape,
19
- rowWithCursorId,
19
+ rowWithMatchingCursor,
20
20
  });
21
21
  if (paginationWhere) {
22
22
  result = result + " AND " + paginationWhere;
@@ -159,11 +159,11 @@ function getOperatorNeq(value) {
159
159
  // return { k, v };
160
160
  // }
161
161
  function stringifyPaginationWhere(input) {
162
- const { table, args, orderBy, escapeId, escape, rowWithCursorId } = input;
162
+ const { table, args, orderBy, escapeId, escape, rowWithMatchingCursor, } = input;
163
163
  if (args?.$paginate?.after == null && args?.$paginate?.before == null) {
164
164
  return "";
165
165
  }
166
- if (rowWithCursorId == null) {
166
+ if (rowWithMatchingCursor == null) {
167
167
  return "";
168
168
  }
169
169
  // orderBy should never be null because of getOrderBy, but add a check.
@@ -188,12 +188,12 @@ function stringifyPaginationWhere(input) {
188
188
  let a = orderBy.slice(0, i).map(({ column: col2 }) => {
189
189
  const field = `${table}.${escapeId(col2)}`;
190
190
  const op = "=";
191
- const v = printValue(rowWithCursorId[col2]);
191
+ const v = printValue(rowWithMatchingCursor[col2]);
192
192
  return `${field} ${op} ${v}`;
193
193
  });
194
194
  const field = `${table}.${escapeId(column)}`;
195
195
  const op = getCompOp(direction);
196
- const v = printValue(rowWithCursorId[column]);
196
+ const v = printValue(rowWithMatchingCursor[column]);
197
197
  a.push(`${field} ${op} ${v}`);
198
198
  return "(" + a.join(" AND ") + ")";
199
199
  })
package/dist/types.d.ts CHANGED
@@ -65,7 +65,7 @@ export declare type IGetSQLASTInput = {
65
65
  grabMany: boolean;
66
66
  getWhere: typeof getWhere;
67
67
  orderBy?: IOrderBy | undefined;
68
- rowWithCursorId?: any;
68
+ rowWithMatchingCursor?: any;
69
69
  artifacts: IArtifacts;
70
70
  dialect: IDialect;
71
71
  firstChild?: IASTChildColumn | IASTChildComposite;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@technicity/data-service-generator",
3
- "version": "0.4.3",
3
+ "version": "0.4.7",
4
4
  "main": "./dist/index.js",
5
5
  "files": [
6
6
  "dist"