@snowtop/ent 0.1.0-alpha90 → 0.1.0-alpha91

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 (63) hide show
  1. package/action/orchestrator.js +5 -1
  2. package/core/clause.d.ts +15 -0
  3. package/core/clause.js +44 -2
  4. package/core/config.js +5 -1
  5. package/core/db.js +5 -1
  6. package/core/ent.js +7 -8
  7. package/core/loaders/assoc_count_loader.d.ts +1 -0
  8. package/core/loaders/assoc_count_loader.js +8 -1
  9. package/core/loaders/assoc_edge_loader.js +5 -1
  10. package/core/loaders/object_loader.js +5 -1
  11. package/core/loaders/query_loader.js +5 -1
  12. package/core/loaders/raw_count_loader.js +5 -1
  13. package/core/privacy.d.ts +6 -6
  14. package/core/query/assoc_query.d.ts +1 -0
  15. package/core/query/assoc_query.js +9 -1
  16. package/core/query/custom_clause_query.d.ts +2 -0
  17. package/core/query/custom_clause_query.js +9 -3
  18. package/core/query/custom_query.d.ts +2 -2
  19. package/core/query/custom_query.js +29 -21
  20. package/core/query/query.d.ts +7 -3
  21. package/core/query/query.js +101 -60
  22. package/core/query/shared_assoc_test.d.ts +2 -1
  23. package/core/query/shared_assoc_test.js +24 -45
  24. package/core/query/shared_test.d.ts +5 -1
  25. package/core/query/shared_test.js +354 -301
  26. package/graphql/graphql.js +10 -6
  27. package/graphql/query/shared_edge_connection.js +1 -15
  28. package/imports/index.js +5 -1
  29. package/index.js +5 -1
  30. package/package.json +1 -1
  31. package/schema/field.js +11 -1
  32. package/schema/index.js +5 -1
  33. package/schema/schema.d.ts +1 -0
  34. package/scripts/custom_compiler.js +10 -6
  35. package/scripts/custom_graphql.js +5 -1
  36. package/scripts/read_schema.js +5 -1
  37. package/testutils/db/temp_db.d.ts +6 -5
  38. package/testutils/db/temp_db.js +40 -28
  39. package/testutils/db_mock.js +3 -1
  40. package/testutils/ent-graphql-tests/index.js +8 -1
  41. package/testutils/fake_data/const.d.ts +2 -1
  42. package/testutils/fake_data/const.js +3 -0
  43. package/testutils/fake_data/fake_contact.d.ts +2 -0
  44. package/testutils/fake_data/fake_tag.d.ts +35 -0
  45. package/testutils/fake_data/fake_tag.js +88 -0
  46. package/testutils/fake_data/fake_user.d.ts +2 -0
  47. package/testutils/fake_data/index.js +5 -1
  48. package/testutils/fake_data/internal.d.ts +2 -0
  49. package/testutils/fake_data/internal.js +7 -1
  50. package/testutils/fake_data/tag_query.d.ts +13 -0
  51. package/testutils/fake_data/tag_query.js +43 -0
  52. package/testutils/fake_data/test_helpers.d.ts +8 -2
  53. package/testutils/fake_data/test_helpers.js +21 -7
  54. package/testutils/fake_data/user_query.d.ts +5 -0
  55. package/testutils/fake_data/user_query.js +28 -3
  56. package/testutils/test_edge_global_schema.js +5 -1
  57. package/testutils/write.js +5 -1
  58. package/tsc/ast.js +5 -1
  59. package/tsc/compilerOptions.js +5 -1
  60. package/tsc/move_generated.js +5 -1
  61. package/tsc/transform.js +5 -1
  62. package/tsc/transform_action.js +5 -1
  63. package/tsc/transform_schema.js +5 -1
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -27,6 +31,8 @@ const ent_1 = require("../ent");
27
31
  const clause = __importStar(require("../clause"));
28
32
  const memoizee_1 = __importDefault(require("memoizee"));
29
33
  const privacy_1 = require("../privacy");
34
+ const uuid_1 = require("uuid");
35
+ const util_1 = require("util");
30
36
  // TODO can we generalize EdgeQuery to support any clause
31
37
  function assertPositive(n) {
32
38
  if (n < 0) {
@@ -36,31 +42,32 @@ function assertPositive(n) {
36
42
  function assertValidCursor(cursor, col) {
37
43
  let decoded = Buffer.from(cursor, "base64").toString("ascii");
38
44
  let parts = decoded.split(":");
45
+ // uuid, don't parse int since it tries to validate just first part
46
+ if ((0, uuid_1.validate)(parts[1])) {
47
+ return parts[1];
48
+ }
39
49
  // invalid or unknown cursor. nothing to do here.
40
50
  if (parts.length !== 2 || parts[0] !== col) {
41
51
  throw new Error(`invalid cursor ${cursor} passed`);
42
52
  }
43
- // TODO check if numeric or not but for now we're only doing numbers
53
+ // TODO handle both cases... (time vs not) better
54
+ // TODO change this to only do the parseInt part if time...
55
+ // pass flag indicating if time?
44
56
  const time = parseInt(parts[1], 10);
45
57
  if (isNaN(time)) {
46
- throw new Error(`invalid cursor ${cursor} passed`);
58
+ return parts[1];
47
59
  }
48
60
  return time;
49
61
  }
62
+ const orderbyRegex = new RegExp(/([0-9a-z_]+)[ ]?([0-9a-z_]+)?/i);
50
63
  class FirstFilter {
51
64
  constructor(options) {
52
65
  this.options = options;
53
66
  this.pageMap = new Map();
54
67
  assertPositive(options.limit);
55
- if (options.before) {
56
- throw new Error(`cannot specify before with a first filter`);
57
- }
58
- this.sortCol = options.sortCol || "time";
68
+ this.sortCol = options.sortCol;
59
69
  if (options.after) {
60
- this.offset = assertValidCursor(options.after, this.sortCol);
61
- }
62
- if (this.options.sortColNotTime && !this.options.sortCol) {
63
- throw new Error(`cannot specify sortColNotTime without specifying a sortCol`);
70
+ this.offset = assertValidCursor(options.after, options.cursorCol);
64
71
  }
65
72
  this.edgeQuery = options.query;
66
73
  }
@@ -69,6 +76,8 @@ class FirstFilter {
69
76
  const ret = edges.slice(0, this.options.limit);
70
77
  this.pageMap.set(id, {
71
78
  hasNextPage: true,
79
+ // hasPreviousPage always false even if there's a previous page because
80
+ // we shouldn't be querying in both directions at the same
72
81
  hasPreviousPage: false,
73
82
  startCursor: this.edgeQuery.getCursor(ret[0]),
74
83
  endCursor: this.edgeQuery.getCursor(ret[ret.length - 1]),
@@ -82,31 +91,34 @@ class FirstFilter {
82
91
  // so we'd need a way to indicate whether this is done in sql or not
83
92
  return edges;
84
93
  }
85
- query(options) {
94
+ async query(options) {
86
95
  // we fetch an extra one to see if we're at the end
87
96
  const limit = this.options.limit + 1;
88
97
  options.limit = limit;
89
- // todo may not be desc
90
- // and if asc
91
- // clause below should switch to greater...
92
- const sortCol = this.sortCol.toLowerCase();
93
- if (sortCol.endsWith("desc") || sortCol.endsWith("asc")) {
94
- options.orderby = `${this.sortCol}`;
95
- }
96
- else {
97
- options.orderby = `${this.sortCol} DESC`;
98
- }
98
+ let orderby = this.options.defaultDirection || "DESC";
99
99
  // we sort by most recent first
100
100
  // so when paging, we fetch afterCursor X
101
- if (this.offset) {
102
- if (this.options.sortColNotTime) {
103
- options.clause = clause.Less(this.sortCol, this.offset);
101
+ const less = orderby === "DESC";
102
+ if (this.options.cursorCol !== this.sortCol) {
103
+ // we also sort unique col in same direction since it doesn't matter...
104
+ options.orderby = `${this.sortCol} ${orderby}, ${this.options.cursorCol} ${orderby}`;
105
+ if (this.offset) {
106
+ const res = this.edgeQuery.getTableName();
107
+ const tableName = util_1.types.isPromise(res) ? await res : res;
108
+ // inner col time
109
+ options.clause = clause.PaginationMultipleColsSubQuery(this.sortCol, less ? "<" : ">", tableName, this.options.cursorCol, this.offset);
104
110
  }
105
- else {
106
- options.clause = clause.Less(this.sortCol, new Date(this.offset).toISOString());
111
+ }
112
+ else {
113
+ options.orderby = `${this.sortCol} ${orderby}`;
114
+ if (this.offset) {
115
+ let clauseFn = less ? clause.Less : clause.Greater;
116
+ let val = this.options.sortColTime
117
+ ? new Date(this.offset).toISOString()
118
+ : this.offset;
119
+ options.clause = clauseFn(this.sortCol, val);
107
120
  }
108
121
  }
109
- // console.debug("filter opts", options, this.options);
110
122
  return options;
111
123
  }
112
124
  // TODO?
@@ -119,15 +131,9 @@ class LastFilter {
119
131
  this.options = options;
120
132
  this.pageMap = new Map();
121
133
  assertPositive(options.limit);
122
- if (options.after) {
123
- throw new Error(`cannot specify after with a last filter`);
124
- }
125
- this.sortCol = options.sortCol || "time";
134
+ this.sortCol = options.sortCol;
126
135
  if (options.before) {
127
- this.offset = assertValidCursor(options.before, this.sortCol);
128
- }
129
- if (this.options.sortColNotTime && !this.options.sortCol) {
130
- throw new Error(`cannot specify sortColNotTime without specifying a sortCol`);
136
+ this.offset = assertValidCursor(options.before, options.cursorCol);
131
137
  }
132
138
  this.edgeQuery = options.query;
133
139
  }
@@ -144,11 +150,13 @@ class LastFilter {
144
150
  }
145
151
  }
146
152
  else {
147
- ret = edges.slice(edges.length - this.options.limit, edges.length);
153
+ ret = edges.slice(0, this.options.limit);
148
154
  }
149
155
  if (edges.length > this.options.limit) {
150
156
  this.pageMap.set(id, {
151
157
  hasPreviousPage: true,
158
+ // hasNextPage always false even if there's a next page because
159
+ // we shouldn't be querying in both directions at the same
152
160
  hasNextPage: false,
153
161
  startCursor: this.edgeQuery.getCursor(ret[0]),
154
162
  endCursor: this.edgeQuery.getCursor(ret[ret.length - 1]),
@@ -156,17 +164,39 @@ class LastFilter {
156
164
  }
157
165
  return ret;
158
166
  }
159
- query(options) {
160
- if (!this.offset) {
161
- return options;
167
+ async query(options) {
168
+ // assume desc by default
169
+ // so last is reverse
170
+ let orderby = "ASC";
171
+ if (this.options.defaultDirection) {
172
+ // reverse sort col shown...
173
+ if (this.options.defaultDirection === "DESC") {
174
+ orderby = "ASC";
175
+ }
176
+ else {
177
+ orderby = "DESC";
178
+ }
162
179
  }
163
- options.orderby = `${this.sortCol} ASC`;
180
+ const greater = orderby === "ASC";
164
181
  options.limit = this.options.limit + 1; // fetch an extra so we know if previous pag
165
- if (this.options.sortColNotTime) {
166
- options.clause = clause.Greater(this.sortCol, this.offset);
182
+ if (this.options.cursorCol !== this.sortCol) {
183
+ const res = this.edgeQuery.getTableName();
184
+ const tableName = util_1.types.isPromise(res) ? await res : res;
185
+ if (this.offset) {
186
+ // inner col time
187
+ options.clause = clause.PaginationMultipleColsSubQuery(this.sortCol, greater ? ">" : "<", tableName, this.options.cursorCol, this.offset);
188
+ }
189
+ options.orderby = `${this.sortCol} ${orderby}, ${this.options.cursorCol} ${orderby}`;
167
190
  }
168
191
  else {
169
- options.clause = clause.Greater(this.sortCol, new Date(this.offset).toISOString());
192
+ options.orderby = `${this.sortCol} ${orderby}`;
193
+ if (this.offset) {
194
+ let clauseFn = greater ? clause.Greater : clause.Less;
195
+ let val = this.options.sortColTime
196
+ ? new Date(this.offset).toISOString()
197
+ : this.offset;
198
+ options.clause = clauseFn(this.sortCol, val);
199
+ }
170
200
  }
171
201
  return options;
172
202
  }
@@ -175,9 +205,8 @@ class LastFilter {
175
205
  }
176
206
  }
177
207
  class BaseEdgeQuery {
178
- constructor(viewer, sortCol) {
208
+ constructor(viewer, sortCol, cursorCol) {
179
209
  this.viewer = viewer;
180
- this.sortCol = sortCol;
181
210
  this.filters = [];
182
211
  this.edges = new Map();
183
212
  this.pagination = new Map();
@@ -233,9 +262,26 @@ class BaseEdgeQuery {
233
262
  await Promise.all(promises);
234
263
  return results;
235
264
  };
265
+ let m = orderbyRegex.exec(sortCol);
266
+ if (!m) {
267
+ throw new Error(`invalid sort column ${sortCol}`);
268
+ }
269
+ this.sortCol = m[1];
270
+ if (m[2]) {
271
+ // @ts-ignore
272
+ this.defaultDirection = m[2].toUpperCase();
273
+ }
274
+ let m2 = orderbyRegex.exec(cursorCol);
275
+ if (!m2) {
276
+ throw new Error(`invalid sort column ${cursorCol}`);
277
+ }
278
+ this.cursorCol = m2[1];
236
279
  this.memoizedloadEdges = (0, memoizee_1.default)(this.loadEdges.bind(this));
237
280
  this.genIDInfosToFetch = (0, memoizee_1.default)(this.genIDInfosToFetchImpl.bind(this));
238
281
  }
282
+ getSortCol() {
283
+ return this.sortCol;
284
+ }
239
285
  getPrivacyPolicy() {
240
286
  // default PrivacyPolicy is always allow. nothing to do here
241
287
  return privacy_1.AlwaysAllowPrivacyPolicy;
@@ -246,6 +292,8 @@ class BaseEdgeQuery {
246
292
  limit: n,
247
293
  after,
248
294
  sortCol: this.sortCol,
295
+ cursorCol: this.cursorCol,
296
+ defaultDirection: this.defaultDirection,
249
297
  query: this,
250
298
  }));
251
299
  return this;
@@ -256,6 +304,8 @@ class BaseEdgeQuery {
256
304
  limit: n,
257
305
  before,
258
306
  sortCol: this.sortCol,
307
+ cursorCol: this.cursorCol,
308
+ defaultDirection: this.defaultDirection,
259
309
  query: this,
260
310
  }));
261
311
  return this;
@@ -307,11 +357,12 @@ class BaseEdgeQuery {
307
357
  // TODO once we add a lot of complex filters, this needs to be more complicated
308
358
  // e.g. commutative filters. what can be done in sql or combined together etc
309
359
  // may need to bring sql mode or something back
310
- this.filters.forEach((filter) => {
360
+ for (const filter of this.filters) {
311
361
  if (filter.query) {
312
- options = filter.query(options);
362
+ let res = filter.query(options);
363
+ options = util_1.types.isPromise(res) ? await res : res;
313
364
  }
314
- });
365
+ }
315
366
  await this.loadRawData(idsInfo, options);
316
367
  // no filters. nothing to do here.
317
368
  if (!this.filters.length) {
@@ -338,17 +389,7 @@ class BaseEdgeQuery {
338
389
  getCursor(row) {
339
390
  return (0, ent_1.getCursor)({
340
391
  row,
341
- col: this.sortCol,
342
- conv: (datum) => {
343
- if (datum instanceof Date) {
344
- return datum.getTime();
345
- }
346
- // sqlite stores it as string and doesn't convert back
347
- if (typeof datum === "string") {
348
- return Date.parse(datum);
349
- }
350
- return datum;
351
- },
392
+ col: this.cursorCol,
352
393
  });
353
394
  }
354
395
  }
@@ -1 +1,2 @@
1
- export declare function assocTests(global?: boolean): void;
1
+ import { MockLogs } from "../../testutils/mock_log";
2
+ export declare function assocTests(ml: MockLogs, global?: boolean): void;
@@ -1,33 +1,14 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
- Object.defineProperty(o, "default", { enumerable: true, value: v });
11
- }) : function(o, v) {
12
- o["default"] = v;
13
- });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
20
- };
21
2
  Object.defineProperty(exports, "__esModule", { value: true });
22
3
  exports.assocTests = void 0;
23
- const db_mock_1 = require("../../testutils/db_mock");
24
4
  const ent_1 = require("../ent");
25
5
  const viewer_1 = require("../viewer");
26
6
  const jest_date_mock_1 = require("jest-date-mock");
27
7
  const index_1 = require("../../testutils/fake_data/index");
28
8
  const test_helpers_1 = require("../../testutils/fake_data/test_helpers");
29
- const db_1 = __importStar(require("../db"));
30
- function assocTests(global = false) {
9
+ const clause_1 = require("../clause");
10
+ function assocTests(ml, global = false) {
11
+ ml.mock();
31
12
  describe("custom edge", () => {
32
13
  let user1, user2;
33
14
  beforeEach(async () => {
@@ -67,40 +48,36 @@ function assocTests(global = false) {
67
48
  function firstNEntsFilter(contacts) {
68
49
  return contacts.reverse().slice(0, N);
69
50
  }
51
+ function getWhereClause(query) {
52
+ let execArray = /^SELECT (.+) FROM (.+) WHERE (.+)?/.exec(query.query);
53
+ return execArray?.[3];
54
+ }
70
55
  function verifyQuery({ length = 1, numQueries = 1, limit = ent_1.DefaultLimit, disablePaginationBump = false, }) {
71
- if (db_1.default.getDialect() === db_1.Dialect.SQLite) {
72
- return;
73
- }
74
- const queries = db_mock_1.QueryRecorder.getCurrentQueries();
75
- expect(queries.length).toBe(length);
56
+ expect(ml.logs.length).toBe(length);
76
57
  for (let i = 0; i < numQueries; i++) {
77
- const query = queries[i];
58
+ const whereClause = getWhereClause(ml.logs[i]);
78
59
  let expLimit = disablePaginationBump ? limit : limit + 1;
79
60
  if (global) {
80
- expect(query.qs?.whereClause, `${i}`).toBe(
61
+ expect(whereClause, `${i}`).toBe(
81
62
  // default limit
82
- `id1 = $1 AND edge_type = $2 AND deleted_at IS NULL ORDER BY time DESC LIMIT ${expLimit}`);
63
+ `${(0, clause_1.And)((0, clause_1.Eq)("id1", ""), (0, clause_1.Eq)("edge_type", ""), (0, clause_1.Eq)("deleted_at", null)).clause(1)} ORDER BY time DESC, id2 DESC LIMIT ${expLimit}`);
83
64
  }
84
65
  else {
85
- expect(query.qs?.whereClause, `${i}`).toBe(
66
+ expect(whereClause, `${i}`).toBe(
86
67
  // default limit
87
- `id1 = $1 AND edge_type = $2 ORDER BY time DESC LIMIT ${expLimit}`);
68
+ `${(0, clause_1.And)((0, clause_1.Eq)("id1", ""), (0, clause_1.Eq)("edge_type", "")).clause(1)} ORDER BY time DESC, id2 DESC LIMIT ${expLimit}`);
88
69
  }
89
70
  }
90
71
  }
91
72
  function verifyCountQuery({ length = 1, numQueries = 1 }) {
92
- if (db_1.default.getDialect() === db_1.Dialect.SQLite) {
93
- return;
94
- }
95
- const queries = db_mock_1.QueryRecorder.getCurrentQueries();
96
- expect(queries.length).toBe(length);
73
+ expect(ml.logs.length).toBe(length);
97
74
  for (let i = 0; i < numQueries; i++) {
98
- const query = queries[i];
75
+ const whereClause = getWhereClause(ml.logs[i]);
99
76
  if (global) {
100
- expect(query.qs?.whereClause).toBe(`id1 = $1 AND edge_type = $2 AND deleted_at IS NULL`);
77
+ expect(whereClause).toBe(`${(0, clause_1.And)((0, clause_1.Eq)("id1", ""), (0, clause_1.Eq)("edge_type", ""), (0, clause_1.Eq)("deleted_at", null)).clause(1)}`);
101
78
  }
102
79
  else {
103
- expect(query.qs?.whereClause).toBe(`id1 = $1 AND edge_type = $2`);
80
+ expect(whereClause).toBe(`${(0, clause_1.And)((0, clause_1.Eq)("id1", ""), (0, clause_1.Eq)("edge_type", "")).clause(1)}`);
104
81
  }
105
82
  }
106
83
  }
@@ -115,16 +92,18 @@ function assocTests(global = false) {
115
92
  }
116
93
  async beforeEach() {
117
94
  let [user1, user2, user3] = await Promise.all([
118
- (0, test_helpers_1.createAllContacts)({ firstName: "Jon", lastName: "Snow" }),
119
- (0, test_helpers_1.createAllContacts)({ firstName: "Aegon", lastName: "Targaryen" }),
120
- (0, test_helpers_1.createAllContacts)({ firstName: "Ned", lastName: "Stark" }),
95
+ (0, test_helpers_1.createAllContacts)({ input: { firstName: "Jon", lastName: "Snow" } }),
96
+ (0, test_helpers_1.createAllContacts)({
97
+ input: { firstName: "Aegon", lastName: "Targaryen" },
98
+ }),
99
+ (0, test_helpers_1.createAllContacts)({ input: { firstName: "Ned", lastName: "Stark" } }),
121
100
  ]);
122
101
  // modify contacts as needed
123
102
  user1[1] = this.ents(user1[1]);
124
103
  user2[1] = this.ents(user2[1]);
125
104
  user3[1] = this.ents(user3[1]);
126
105
  this.dataz = [user1, user2, user3];
127
- db_mock_1.QueryRecorder.clearQueries();
106
+ ml.clear();
128
107
  }
129
108
  getQuery(viewer) {
130
109
  return this.filter(index_1.UserToContactsQuery.query(viewer || new viewer_1.LoggedOutViewer(), this.dataz.map((data) => data[0])));
@@ -469,7 +448,7 @@ function assocTests(global = false) {
469
448
  }
470
449
  //order is users, then events
471
450
  this.expCount = this.ents([...this.users, ...this.events]).length;
472
- db_mock_1.QueryRecorder.clearQueries();
451
+ ml.clear();
473
452
  }
474
453
  getQuery(viewer) {
475
454
  return this.filter(index_1.UserToFollowingQuery.query(viewer || new viewer_1.IDViewer(this.user.id), this.user));
@@ -1,16 +1,20 @@
1
1
  import { Data, Viewer } from "../base";
2
2
  import { FakeUser, FakeContact } from "../../testutils/fake_data/index";
3
3
  import { EdgeQuery } from "./query";
4
+ import { MockLogs } from "../../testutils/mock_log";
5
+ import { Clause } from "../clause";
4
6
  interface options<TData extends Data> {
5
7
  newQuery: (v: Viewer, user: FakeUser) => EdgeQuery<FakeUser, FakeContact, TData>;
6
8
  tableName: string;
7
9
  uniqKey: string;
10
+ ml: MockLogs;
8
11
  entsLength?: number;
9
- where: string;
12
+ clause: Clause;
10
13
  sortCol: string;
11
14
  livePostgresDB?: boolean;
12
15
  sqlite?: boolean;
13
16
  globalSchema?: boolean;
17
+ orderby: "DESC" | "ASC";
14
18
  rawDataVerify?(user: FakeUser): Promise<void>;
15
19
  }
16
20
  export declare const commonTests: <TData extends Data>(opts: options<TData>) => void;