@snowtop/ent 0.1.0-alpha1 → 0.1.0-alpha100

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 (172) hide show
  1. package/action/action.d.ts +38 -30
  2. package/action/action.js +22 -7
  3. package/action/executor.d.ts +4 -4
  4. package/action/executor.js +8 -3
  5. package/action/experimental_action.d.ts +32 -22
  6. package/action/experimental_action.js +35 -9
  7. package/action/index.d.ts +2 -0
  8. package/action/index.js +7 -1
  9. package/action/orchestrator.d.ts +48 -16
  10. package/action/orchestrator.js +343 -81
  11. package/action/privacy.d.ts +2 -2
  12. package/action/relative_value.d.ts +47 -0
  13. package/action/relative_value.js +125 -0
  14. package/action/transaction.d.ts +10 -0
  15. package/action/transaction.js +23 -0
  16. package/auth/auth.d.ts +1 -1
  17. package/core/base.d.ts +54 -27
  18. package/core/base.js +23 -1
  19. package/core/clause.d.ts +105 -3
  20. package/core/clause.js +563 -30
  21. package/core/config.d.ts +30 -1
  22. package/core/config.js +24 -1
  23. package/core/context.d.ts +5 -3
  24. package/core/context.js +20 -2
  25. package/core/convert.d.ts +1 -1
  26. package/core/date.js +1 -5
  27. package/core/db.d.ts +14 -11
  28. package/core/db.js +22 -8
  29. package/core/ent.d.ts +82 -28
  30. package/core/ent.js +692 -202
  31. package/core/loaders/assoc_count_loader.d.ts +3 -2
  32. package/core/loaders/assoc_count_loader.js +10 -2
  33. package/core/loaders/assoc_edge_loader.d.ts +3 -3
  34. package/core/loaders/assoc_edge_loader.js +13 -15
  35. package/core/loaders/index.d.ts +1 -1
  36. package/core/loaders/index.js +1 -3
  37. package/core/loaders/index_loader.d.ts +2 -2
  38. package/core/loaders/index_loader.js +1 -0
  39. package/core/loaders/loader.js +5 -5
  40. package/core/loaders/object_loader.d.ts +13 -7
  41. package/core/loaders/object_loader.js +95 -32
  42. package/core/loaders/query_loader.d.ts +6 -12
  43. package/core/loaders/query_loader.js +52 -11
  44. package/core/loaders/raw_count_loader.d.ts +2 -2
  45. package/core/loaders/raw_count_loader.js +5 -1
  46. package/core/logger.d.ts +1 -1
  47. package/core/logger.js +1 -0
  48. package/core/privacy.d.ts +26 -25
  49. package/core/privacy.js +23 -24
  50. package/core/query/assoc_query.d.ts +7 -6
  51. package/core/query/assoc_query.js +9 -1
  52. package/core/query/custom_clause_query.d.ts +26 -0
  53. package/core/query/custom_clause_query.js +78 -0
  54. package/core/query/custom_query.d.ts +20 -5
  55. package/core/query/custom_query.js +87 -12
  56. package/core/query/index.d.ts +1 -0
  57. package/core/query/index.js +3 -1
  58. package/core/query/query.d.ts +8 -4
  59. package/core/query/query.js +101 -53
  60. package/core/query/shared_assoc_test.d.ts +2 -1
  61. package/core/query/shared_assoc_test.js +35 -45
  62. package/core/query/shared_test.d.ts +8 -1
  63. package/core/query/shared_test.js +469 -236
  64. package/core/viewer.d.ts +4 -3
  65. package/core/viewer.js +5 -1
  66. package/graphql/builtins/connection.js +3 -3
  67. package/graphql/builtins/edge.js +2 -2
  68. package/graphql/builtins/node.js +1 -1
  69. package/graphql/graphql.d.ts +17 -9
  70. package/graphql/graphql.js +47 -30
  71. package/graphql/index.d.ts +1 -1
  72. package/graphql/index.js +3 -4
  73. package/graphql/mutations/union.d.ts +2 -0
  74. package/graphql/mutations/union.js +35 -0
  75. package/graphql/node_resolver.d.ts +0 -1
  76. package/graphql/query/connection_type.d.ts +9 -9
  77. package/graphql/query/connection_type.js +6 -6
  78. package/graphql/query/edge_connection.d.ts +9 -9
  79. package/graphql/query/page_info.d.ts +1 -1
  80. package/graphql/query/page_info.js +4 -4
  81. package/graphql/query/shared_assoc_test.js +3 -3
  82. package/graphql/query/shared_edge_connection.js +1 -19
  83. package/graphql/scalars/time.d.ts +1 -1
  84. package/imports/index.d.ts +6 -1
  85. package/imports/index.js +19 -4
  86. package/index.d.ts +23 -1
  87. package/index.js +32 -6
  88. package/package.json +18 -17
  89. package/parse_schema/parse.d.ts +45 -8
  90. package/parse_schema/parse.js +193 -15
  91. package/schema/base_schema.d.ts +38 -1
  92. package/schema/base_schema.js +53 -2
  93. package/schema/field.d.ts +75 -21
  94. package/schema/field.js +185 -72
  95. package/schema/index.d.ts +4 -2
  96. package/schema/index.js +15 -2
  97. package/schema/json_field.d.ts +13 -1
  98. package/schema/json_field.js +28 -1
  99. package/schema/schema.d.ts +125 -10
  100. package/schema/schema.js +133 -5
  101. package/schema/struct_field.d.ts +27 -0
  102. package/schema/struct_field.js +138 -0
  103. package/schema/union_field.d.ts +23 -0
  104. package/schema/union_field.js +79 -0
  105. package/scripts/custom_compiler.js +10 -6
  106. package/scripts/custom_graphql.js +224 -36
  107. package/scripts/{transform_schema.d.ts → migrate_v0.1.d.ts} +0 -0
  108. package/scripts/migrate_v0.1.js +36 -0
  109. package/scripts/move_types.d.ts +1 -0
  110. package/scripts/move_types.js +117 -0
  111. package/scripts/read_schema.js +35 -6
  112. package/testutils/action/complex_schemas.d.ts +69 -0
  113. package/testutils/action/complex_schemas.js +398 -0
  114. package/testutils/builder.d.ts +52 -49
  115. package/testutils/builder.js +143 -44
  116. package/testutils/context/test_context.d.ts +2 -2
  117. package/testutils/context/test_context.js +7 -1
  118. package/testutils/db/fixture.d.ts +10 -0
  119. package/testutils/db/fixture.js +26 -0
  120. package/testutils/db/{test_db.d.ts → temp_db.d.ts} +26 -9
  121. package/testutils/db/{test_db.js → temp_db.js} +190 -46
  122. package/testutils/db/value.d.ts +7 -0
  123. package/testutils/db/value.js +251 -0
  124. package/testutils/db_mock.d.ts +16 -4
  125. package/testutils/db_mock.js +51 -6
  126. package/testutils/db_time_zone.d.ts +4 -0
  127. package/testutils/db_time_zone.js +41 -0
  128. package/testutils/ent-graphql-tests/index.d.ts +9 -1
  129. package/testutils/ent-graphql-tests/index.js +53 -25
  130. package/testutils/fake_data/const.d.ts +2 -1
  131. package/testutils/fake_data/const.js +3 -0
  132. package/testutils/fake_data/fake_contact.d.ts +10 -10
  133. package/testutils/fake_data/fake_contact.js +23 -21
  134. package/testutils/fake_data/fake_event.d.ts +8 -9
  135. package/testutils/fake_data/fake_event.js +25 -28
  136. package/testutils/fake_data/fake_tag.d.ts +36 -0
  137. package/testutils/fake_data/fake_tag.js +89 -0
  138. package/testutils/fake_data/fake_user.d.ts +10 -11
  139. package/testutils/fake_data/fake_user.js +20 -23
  140. package/testutils/fake_data/index.js +5 -1
  141. package/testutils/fake_data/internal.d.ts +2 -0
  142. package/testutils/fake_data/internal.js +7 -1
  143. package/testutils/fake_data/tag_query.d.ts +13 -0
  144. package/testutils/fake_data/tag_query.js +43 -0
  145. package/testutils/fake_data/test_helpers.d.ts +11 -4
  146. package/testutils/fake_data/test_helpers.js +29 -13
  147. package/testutils/fake_data/user_query.d.ts +13 -6
  148. package/testutils/fake_data/user_query.js +54 -22
  149. package/testutils/fake_log.d.ts +3 -3
  150. package/testutils/parse_sql.d.ts +6 -0
  151. package/testutils/parse_sql.js +16 -2
  152. package/testutils/test_edge_global_schema.d.ts +15 -0
  153. package/testutils/test_edge_global_schema.js +62 -0
  154. package/testutils/write.d.ts +2 -2
  155. package/testutils/write.js +33 -7
  156. package/tsc/ast.d.ts +44 -0
  157. package/tsc/ast.js +277 -0
  158. package/tsc/compilerOptions.d.ts +6 -0
  159. package/tsc/compilerOptions.js +45 -2
  160. package/tsc/move_generated.d.ts +1 -0
  161. package/tsc/move_generated.js +164 -0
  162. package/tsc/transform.d.ts +22 -0
  163. package/tsc/transform.js +181 -0
  164. package/tsc/transform_action.d.ts +22 -0
  165. package/tsc/transform_action.js +183 -0
  166. package/tsc/transform_ent.d.ts +17 -0
  167. package/tsc/transform_ent.js +59 -0
  168. package/tsc/transform_schema.d.ts +27 -0
  169. package/tsc/transform_schema.js +383 -0
  170. package/graphql/enums.d.ts +0 -3
  171. package/graphql/enums.js +0 -25
  172. package/scripts/transform_schema.js +0 -288
package/core/clause.js CHANGED
@@ -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];
@@ -19,10 +23,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
19
23
  return result;
20
24
  };
21
25
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.sensitiveValue = exports.In = exports.Or = exports.And = exports.LessEq = exports.GreaterEq = exports.Less = exports.Greater = exports.NotEq = exports.Eq = void 0;
26
+ exports.Modulo = exports.Divide = exports.Multiply = exports.Subtract = exports.Add = exports.PaginationMultipleColsSubQuery = exports.JSONPathValuePredicate = exports.JSONObjectFieldKeyAsText = exports.JSONObjectFieldKeyASJSON = exports.sensitiveValue = exports.TsVectorWebsearchToTsQuery = exports.TsVectorPhraseToTsQuery = exports.TsVectorPlainToTsQuery = exports.TsVectorColTsQuery = exports.WebsearchToTsQuery = exports.PhraseToTsQuery = exports.PlainToTsQuery = exports.TsQuery = exports.In = exports.OrOptional = exports.Or = exports.AndOptional = exports.And = exports.LessEq = exports.GreaterEq = exports.Less = exports.Greater = exports.NotEq = exports.Eq = exports.ArrayNotEq = exports.ArrayEq = exports.PostgresArrayNotOverlaps = exports.PostgresArrayOverlaps = exports.PostgresArrayNotContains = exports.PostgresArrayNotContainsValue = exports.PostgresArrayContains = exports.PostgresArrayContainsValue = exports.inClause = void 0;
23
27
  const db_1 = __importStar(require("./db"));
24
28
  function isSensitive(val) {
25
- return (typeof val === "object" && val.logValue !== undefined);
29
+ return (val !== null &&
30
+ typeof val === "object" &&
31
+ val.logValue !== undefined);
26
32
  }
27
33
  function rawValue(val) {
28
34
  if (isSensitive(val)) {
@@ -31,17 +37,114 @@ function rawValue(val) {
31
37
  return val;
32
38
  }
33
39
  class simpleClause {
34
- constructor(col, value, op) {
40
+ constructor(col, value, op, handleNull) {
35
41
  this.col = col;
36
42
  this.value = value;
37
43
  this.op = op;
44
+ this.handleNull = handleNull;
38
45
  }
39
46
  clause(idx) {
47
+ const nullClause = this.nullClause();
48
+ if (nullClause) {
49
+ return nullClause.clause(idx);
50
+ }
40
51
  if (db_1.default.getDialect() === db_1.Dialect.Postgres) {
41
52
  return `${this.col} ${this.op} $${idx}`;
42
53
  }
43
54
  return `${this.col} ${this.op} ?`;
44
55
  }
56
+ nullClause() {
57
+ if (!this.handleNull || this.value !== null) {
58
+ return;
59
+ }
60
+ return this.handleNull;
61
+ }
62
+ columns() {
63
+ return [this.col];
64
+ }
65
+ values() {
66
+ const nullClause = this.nullClause();
67
+ if (nullClause) {
68
+ return nullClause.values();
69
+ }
70
+ if (isSensitive(this.value)) {
71
+ return [this.value.value()];
72
+ }
73
+ return [this.value];
74
+ }
75
+ logValues() {
76
+ const nullClause = this.nullClause();
77
+ if (nullClause) {
78
+ return nullClause.logValues();
79
+ }
80
+ if (isSensitive(this.value)) {
81
+ return [this.value.logValue()];
82
+ }
83
+ return [this.value];
84
+ }
85
+ instanceKey() {
86
+ const nullClause = this.nullClause();
87
+ if (nullClause) {
88
+ return nullClause.instanceKey();
89
+ }
90
+ return `${this.col}${this.op}${rawValue(this.value)}`;
91
+ }
92
+ }
93
+ class isNullClause {
94
+ constructor(col) {
95
+ this.col = col;
96
+ }
97
+ clause(idx) {
98
+ return `${this.col} IS NULL`;
99
+ }
100
+ columns() {
101
+ return [];
102
+ }
103
+ values() {
104
+ return [];
105
+ }
106
+ logValues() {
107
+ return [];
108
+ }
109
+ instanceKey() {
110
+ return `${this.col} IS NULL`;
111
+ }
112
+ }
113
+ class isNotNullClause {
114
+ constructor(col) {
115
+ this.col = col;
116
+ }
117
+ clause(idx) {
118
+ return `${this.col} IS NOT NULL`;
119
+ }
120
+ columns() {
121
+ return [];
122
+ }
123
+ values() {
124
+ return [];
125
+ }
126
+ logValues() {
127
+ return [];
128
+ }
129
+ instanceKey() {
130
+ return `${this.col} IS NOT NULL`;
131
+ }
132
+ }
133
+ class arraySimpleClause {
134
+ constructor(col, value, op) {
135
+ this.col = col;
136
+ this.value = value;
137
+ this.op = op;
138
+ }
139
+ clause(idx) {
140
+ if (db_1.default.getDialect() === db_1.Dialect.Postgres) {
141
+ return `$${idx} ${this.op} ANY(${this.col})`;
142
+ }
143
+ return `${this.col} ${this.op} ?`;
144
+ }
145
+ columns() {
146
+ return [this.col];
147
+ }
45
148
  values() {
46
149
  if (isSensitive(this.value)) {
47
150
  return [this.value.value()];
@@ -58,18 +161,105 @@ class simpleClause {
58
161
  return `${this.col}${this.op}${rawValue(this.value)}`;
59
162
  }
60
163
  }
164
+ class postgresArrayOperator {
165
+ constructor(col, value, op, not) {
166
+ this.col = col;
167
+ this.value = value;
168
+ this.op = op;
169
+ this.not = not;
170
+ }
171
+ clause(idx) {
172
+ if (db_1.default.getDialect() === db_1.Dialect.Postgres) {
173
+ if (this.not) {
174
+ return `NOT ${this.col} ${this.op} $${idx}`;
175
+ }
176
+ return `${this.col} ${this.op} $${idx}`;
177
+ }
178
+ throw new Error(`not supported`);
179
+ }
180
+ columns() {
181
+ return [this.col];
182
+ }
183
+ values() {
184
+ if (isSensitive(this.value)) {
185
+ return [`{${this.value.value()}}`];
186
+ }
187
+ return [`{${this.value}}`];
188
+ }
189
+ logValues() {
190
+ if (isSensitive(this.value)) {
191
+ return [`{${this.value.logValue()}}`];
192
+ }
193
+ return [`{${this.value}}`];
194
+ }
195
+ instanceKey() {
196
+ if (this.not) {
197
+ return `NOT:${this.col}${this.op}${rawValue(this.value)}`;
198
+ }
199
+ return `${this.col}${this.op}${rawValue(this.value)}`;
200
+ }
201
+ }
202
+ class postgresArrayOperatorList extends postgresArrayOperator {
203
+ constructor(col, value, op, not) {
204
+ super(col, value, op, not);
205
+ }
206
+ values() {
207
+ return [
208
+ `{${this.value
209
+ .map((v) => {
210
+ if (isSensitive(v)) {
211
+ return v.value();
212
+ }
213
+ return v;
214
+ })
215
+ .join(", ")}}`,
216
+ ];
217
+ }
218
+ logValues() {
219
+ return [
220
+ `{${this.value
221
+ .map((v) => {
222
+ if (isSensitive(v)) {
223
+ return v.logValue();
224
+ }
225
+ return v;
226
+ })
227
+ .join(", ")}}`,
228
+ ];
229
+ }
230
+ }
61
231
  class inClause {
62
- constructor(col, value) {
232
+ static getPostgresInClauseValuesThreshold() {
233
+ return 70;
234
+ }
235
+ constructor(col, value, type = "uuid") {
63
236
  this.col = col;
64
237
  this.value = value;
238
+ this.type = type;
65
239
  }
66
240
  clause(idx) {
67
- const dialect = db_1.default.getDialect();
241
+ // do a simple = when only one item
242
+ if (this.value.length === 1) {
243
+ return new simpleClause(this.col, this.value[0], "=").clause(idx);
244
+ }
245
+ const postgres = db_1.default.getDialect() === db_1.Dialect.Postgres;
246
+ const postgresValuesList = postgres &&
247
+ this.value.length >= inClause.getPostgresInClauseValuesThreshold();
68
248
  let indices;
69
- if (dialect === db_1.Dialect.Postgres) {
249
+ if (postgres) {
70
250
  indices = [];
71
251
  for (let i = 0; i < this.value.length; i++) {
72
- indices.push(`$${idx}`);
252
+ if (postgresValuesList) {
253
+ if (i === 0) {
254
+ indices.push(`($${idx}::${this.type})`);
255
+ }
256
+ else {
257
+ indices.push(`($${idx})`);
258
+ }
259
+ }
260
+ else {
261
+ indices.push(`$${idx}`);
262
+ }
73
263
  idx++;
74
264
  }
75
265
  }
@@ -77,34 +267,31 @@ class inClause {
77
267
  indices = new Array(this.value.length);
78
268
  indices.fill("?", 0);
79
269
  }
80
- const inValue = indices.join(", ");
270
+ let inValue = indices.join(", ");
271
+ // wrap in VALUES list for postgres...
272
+ if (postgresValuesList) {
273
+ inValue = `VALUES${inValue}`;
274
+ }
81
275
  return `${this.col} IN (${inValue})`;
82
276
  // TODO we need to return idx at end to query builder...
83
277
  // or anything that's doing a composite query so next clause knows where to start
84
278
  // or change to a sqlx.Rebind format
85
279
  // here's what sqlx does: https://play.golang.org/p/vPzvYqeAcP0
86
280
  }
281
+ columns() {
282
+ return [this.col];
283
+ }
87
284
  values() {
88
285
  const result = [];
89
- for (const value of this.value) {
90
- if (isSensitive(value)) {
91
- result.push(value.value());
92
- }
93
- else {
94
- result.push(value);
95
- }
286
+ for (let value of this.value) {
287
+ result.push(rawValue(value));
96
288
  }
97
289
  return result;
98
290
  }
99
291
  logValues() {
100
292
  const result = [];
101
- for (const value of this.value) {
102
- if (isSensitive(value)) {
103
- result.push(value.logValue());
104
- }
105
- else {
106
- result.push(value);
107
- }
293
+ for (let value of this.value) {
294
+ result.push(isSensitive(value) ? value.logValue() : value);
108
295
  }
109
296
  return result;
110
297
  }
@@ -112,19 +299,33 @@ class inClause {
112
299
  return `in:${this.col}:${this.values().join(",")}`;
113
300
  }
114
301
  }
302
+ exports.inClause = inClause;
115
303
  class compositeClause {
116
304
  constructor(clauses, sep) {
117
305
  this.clauses = clauses;
118
306
  this.sep = sep;
307
+ this.compositeOp = this.sep;
119
308
  }
120
309
  clause(idx) {
121
310
  let clauses = [];
122
311
  for (const clause of this.clauses) {
123
- clauses.push(clause.clause(idx));
312
+ let cls = clause.clause(idx);
313
+ // if composite clause and a different op, add parens so that we enforce order of precedence
314
+ if (clause.compositeOp && clause.compositeOp !== this.sep) {
315
+ cls = `(${cls})`;
316
+ }
317
+ clauses.push(cls);
124
318
  idx = idx + clause.values().length;
125
319
  }
126
320
  return clauses.join(this.sep);
127
321
  }
322
+ columns() {
323
+ const ret = [];
324
+ for (const cls of this.clauses) {
325
+ ret.push(...cls.columns());
326
+ }
327
+ return ret;
328
+ }
128
329
  values() {
129
330
  let result = [];
130
331
  for (const clause of this.clauses) {
@@ -141,16 +342,159 @@ class compositeClause {
141
342
  }
142
343
  instanceKey() {
143
344
  let keys = [];
144
- this.clauses.forEach((clause) => keys.push(clause.instanceKey()));
345
+ this.clauses.forEach((clause) => {
346
+ if (clause.compositeOp && clause.compositeOp != this.sep) {
347
+ keys.push(`(${clause.instanceKey()})`);
348
+ }
349
+ else {
350
+ keys.push(clause.instanceKey());
351
+ }
352
+ });
145
353
  return keys.join(this.sep);
146
354
  }
147
355
  }
356
+ class tsQueryClause {
357
+ constructor(col, val, tsVectorCol) {
358
+ this.col = col;
359
+ this.val = val;
360
+ this.tsVectorCol = tsVectorCol;
361
+ }
362
+ isTsQuery(val) {
363
+ return typeof val !== "string";
364
+ }
365
+ getInfo() {
366
+ if (this.isTsQuery(this.val)) {
367
+ return { value: this.val.value, language: this.val.language };
368
+ }
369
+ return {
370
+ language: "english",
371
+ value: this.val,
372
+ };
373
+ }
374
+ clause(idx) {
375
+ const { language } = this.getInfo();
376
+ if (db_1.Dialect.Postgres === db_1.default.getDialect()) {
377
+ if (this.tsVectorCol) {
378
+ return `to_tsvector(${this.col}) @@ ${this.getFunction()}('${language}', $${idx})`;
379
+ }
380
+ return `${this.col} @@ ${this.getFunction()}('${language}', $${idx})`;
381
+ }
382
+ // FYI this doesn't actually work for sqlite since different
383
+ return `${this.col} @@ ${this.getFunction()}('${language}', ?)`;
384
+ }
385
+ columns() {
386
+ return [this.col];
387
+ }
388
+ values() {
389
+ const { value } = this.getInfo();
390
+ return [value];
391
+ }
392
+ logValues() {
393
+ const { value } = this.getInfo();
394
+ return [value];
395
+ }
396
+ getFunction() {
397
+ return "to_tsquery";
398
+ }
399
+ instanceKey() {
400
+ const { language, value } = this.getInfo();
401
+ if (this.tsVectorCol) {
402
+ return `to_tsvector(${this.col})@@${this.getFunction()}:${language}:${value}`;
403
+ }
404
+ return `${this.col}@@${this.getFunction()}:${language}:${value}`;
405
+ }
406
+ }
407
+ class plainToTsQueryClause extends tsQueryClause {
408
+ getFunction() {
409
+ return "plainto_tsquery";
410
+ }
411
+ }
412
+ class phraseToTsQueryClause extends tsQueryClause {
413
+ getFunction() {
414
+ return "phraseto_tsquery";
415
+ }
416
+ }
417
+ class websearchTosQueryClause extends tsQueryClause {
418
+ getFunction() {
419
+ return "websearch_to_tsquery";
420
+ }
421
+ }
422
+ // postgres array operators
423
+ // https://www.postgresql.org/docs/current/functions-array.html
424
+ /**
425
+ * creates a clause to determine if the given value is contained in the array stored in the column in the db
426
+ * only works with postgres gin indexes
427
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
428
+ */
429
+ function PostgresArrayContainsValue(col, value) {
430
+ return new postgresArrayOperator(col, value, "@>");
431
+ }
432
+ exports.PostgresArrayContainsValue = PostgresArrayContainsValue;
433
+ /**
434
+ * creates a clause to determine if every item in the list is stored in the array stored in the column in the db
435
+ * only works with postgres gin indexes
436
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
437
+ */
438
+ function PostgresArrayContains(col, value) {
439
+ return new postgresArrayOperatorList(col, value, "@>");
440
+ }
441
+ exports.PostgresArrayContains = PostgresArrayContains;
442
+ /**
443
+ * creates a clause to determine if the given value is NOT contained in the array stored in the column in the db
444
+ * only works with postgres gin indexes
445
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
446
+ */
447
+ function PostgresArrayNotContainsValue(col, value) {
448
+ return new postgresArrayOperator(col, value, "@>", true);
449
+ }
450
+ exports.PostgresArrayNotContainsValue = PostgresArrayNotContainsValue;
451
+ /**
452
+ * creates a clause to determine if every item in the list is NOT stored in the array stored in the column in the db
453
+ * only works with postgres gin indexes
454
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
455
+ */
456
+ function PostgresArrayNotContains(col, value) {
457
+ return new postgresArrayOperatorList(col, value, "@>", true);
458
+ }
459
+ exports.PostgresArrayNotContains = PostgresArrayNotContains;
460
+ /**
461
+ * creates a clause to determine if the arrays overlap, that is, do they have any elements in common
462
+ * only works with postgres gin indexes
463
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
464
+ */
465
+ function PostgresArrayOverlaps(col, value) {
466
+ return new postgresArrayOperatorList(col, value, "&&");
467
+ }
468
+ exports.PostgresArrayOverlaps = PostgresArrayOverlaps;
469
+ /**
470
+ * creates a clause to determine if the arrays do not overlap, that is, do they have any elements in common
471
+ * only works with postgres gin indexes
472
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
473
+ */
474
+ function PostgresArrayNotOverlaps(col, value) {
475
+ return new postgresArrayOperatorList(col, value, "&&", true);
476
+ }
477
+ exports.PostgresArrayNotOverlaps = PostgresArrayNotOverlaps;
478
+ /**
479
+ * @deprecated use PostgresArrayContainsValue
480
+ */
481
+ function ArrayEq(col, value) {
482
+ return new arraySimpleClause(col, value, "=");
483
+ }
484
+ exports.ArrayEq = ArrayEq;
485
+ /**
486
+ * @deprecated use PostgresNotArrayContains
487
+ */
488
+ function ArrayNotEq(col, value) {
489
+ return new arraySimpleClause(col, value, "!=");
490
+ }
491
+ exports.ArrayNotEq = ArrayNotEq;
148
492
  function Eq(col, value) {
149
- return new simpleClause(col, value, "=");
493
+ return new simpleClause(col, value, "=", new isNullClause(col));
150
494
  }
151
495
  exports.Eq = Eq;
152
496
  function NotEq(col, value) {
153
- return new simpleClause(col, value, "!=");
497
+ return new simpleClause(col, value, "!=", new isNotNullClause(col));
154
498
  }
155
499
  exports.NotEq = NotEq;
156
500
  function Greater(col, value) {
@@ -173,15 +517,93 @@ function And(...args) {
173
517
  return new compositeClause(args, " AND ");
174
518
  }
175
519
  exports.And = And;
520
+ function AndOptional(...args) {
521
+ // @ts-ignore
522
+ let filtered = args.filter((v) => v !== undefined);
523
+ if (filtered.length === 1) {
524
+ return filtered[0];
525
+ }
526
+ return And(...filtered);
527
+ }
528
+ exports.AndOptional = AndOptional;
176
529
  function Or(...args) {
177
530
  return new compositeClause(args, " OR ");
178
531
  }
179
532
  exports.Or = Or;
180
- // TODO this breaks if values.length ===1 and array. todo fix
181
- function In(col, ...values) {
182
- return new inClause(col, values);
533
+ function OrOptional(...args) {
534
+ // @ts-ignore
535
+ let filtered = args.filter((v) => v !== undefined);
536
+ if (filtered.length === 1) {
537
+ return filtered[0];
538
+ }
539
+ return Or(...filtered);
540
+ }
541
+ exports.OrOptional = OrOptional;
542
+ function In(...args) {
543
+ if (args.length < 2) {
544
+ throw new Error(`invalid args passed to In`);
545
+ }
546
+ // 2nd overload
547
+ if (Array.isArray(args[1])) {
548
+ return new inClause(args[0], args[1], args[2]);
549
+ }
550
+ return new inClause(args[0], args.slice(1));
183
551
  }
184
552
  exports.In = In;
553
+ // if string defaults to english
554
+ // https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES
555
+ // to_tsquery
556
+ // plainto_tsquery
557
+ // phraseto_tsquery;
558
+ // websearch_to_tsquery
559
+ function TsQuery(col, val) {
560
+ return new tsQueryClause(col, val);
561
+ }
562
+ exports.TsQuery = TsQuery;
563
+ function PlainToTsQuery(col, val) {
564
+ return new plainToTsQueryClause(col, val);
565
+ }
566
+ exports.PlainToTsQuery = PlainToTsQuery;
567
+ function PhraseToTsQuery(col, val) {
568
+ return new phraseToTsQueryClause(col, val);
569
+ }
570
+ exports.PhraseToTsQuery = PhraseToTsQuery;
571
+ function WebsearchToTsQuery(col, val) {
572
+ return new websearchTosQueryClause(col, val);
573
+ }
574
+ exports.WebsearchToTsQuery = WebsearchToTsQuery;
575
+ // TsVectorColTsQuery is used when the column is not a tsvector field e.g.
576
+ // when there's an index just on the field and is not a combination of multiple fields
577
+ function TsVectorColTsQuery(col, val) {
578
+ return new tsQueryClause(col, val, true);
579
+ }
580
+ exports.TsVectorColTsQuery = TsVectorColTsQuery;
581
+ // TsVectorPlainToTsQuery is used when the column is not a tsvector field e.g.
582
+ // when there's an index just on the field and is not a combination of multiple fields
583
+ // TODO do these 4 need TsQuery because would be nice to have language?
584
+ // it seems to default to the config of the column
585
+ function TsVectorPlainToTsQuery(col, val) {
586
+ return new plainToTsQueryClause(col, val, true);
587
+ }
588
+ exports.TsVectorPlainToTsQuery = TsVectorPlainToTsQuery;
589
+ // TsVectorPhraseToTsQuery is used when the column is not a tsvector field e.g.
590
+ // when there's an index just on the field and is not a combination of multiple fields
591
+ function TsVectorPhraseToTsQuery(col, val) {
592
+ return new phraseToTsQueryClause(col, val, true);
593
+ }
594
+ exports.TsVectorPhraseToTsQuery = TsVectorPhraseToTsQuery;
595
+ // TsVectorWebsearchToTsQuery is used when the column is not a tsvector field e.g.
596
+ // when there's an index just on the field and is not a combination of multiple fields
597
+ function TsVectorWebsearchToTsQuery(col, val) {
598
+ return new websearchTosQueryClause(col, val, true);
599
+ }
600
+ exports.TsVectorWebsearchToTsQuery = TsVectorWebsearchToTsQuery;
601
+ // TODO would be nice to support this with building blocks but not supporting for now
602
+ // AND: foo & bar,
603
+ // OR: foo | bar
604
+ // followed by: foo <-> bar
605
+ // NOT: !foo
606
+ // starts_with: theo:*
185
607
  // wrap a query in the db with this to ensure that it doesn't show up in the logs
186
608
  // e.g. if querying for password, SSN, etc
187
609
  // we'll pass the right fields to query and log something along the lines of `****`
@@ -196,3 +618,114 @@ function sensitiveValue(val) {
196
618
  };
197
619
  }
198
620
  exports.sensitiveValue = sensitiveValue;
621
+ // These don't return Clauses but return helpful things that can be passed to clauses
622
+ // https://www.postgresql.org/docs/12/functions-json.html#FUNCTIONS-JSON-OP-TABLE
623
+ // see test in db_clause.test.ts
624
+ // unclear best time to use this...
625
+ function JSONObjectFieldKeyASJSON(col, field) {
626
+ return `${col}->'${field}'`;
627
+ }
628
+ exports.JSONObjectFieldKeyASJSON = JSONObjectFieldKeyASJSON;
629
+ function JSONObjectFieldKeyAsText(col, field) {
630
+ return `${col}->>'${field}'`;
631
+ }
632
+ exports.JSONObjectFieldKeyAsText = JSONObjectFieldKeyAsText;
633
+ class jSONPathValuePredicateClause {
634
+ constructor(col, path, value, pred) {
635
+ this.col = col;
636
+ this.path = path;
637
+ this.value = value;
638
+ this.pred = pred;
639
+ }
640
+ clause(idx) {
641
+ if (db_1.default.getDialect() !== db_1.Dialect.Postgres) {
642
+ throw new Error(`not supported`);
643
+ }
644
+ return `${this.col} @@ $${idx}`;
645
+ }
646
+ columns() {
647
+ return [this.col];
648
+ }
649
+ wrap(val) {
650
+ return `${this.path} ${this.pred} ${JSON.stringify(val)}`;
651
+ }
652
+ values() {
653
+ if (isSensitive(this.value)) {
654
+ return [this.wrap(this.value.value())];
655
+ }
656
+ return [this.wrap(this.value)];
657
+ }
658
+ logValues() {
659
+ if (isSensitive(this.value)) {
660
+ return [this.wrap(this.value.logValue())];
661
+ }
662
+ return [this.wrap(this.value)];
663
+ }
664
+ instanceKey() {
665
+ return `${this.col}${this.path}${rawValue(this.value)}${this.pred}`;
666
+ }
667
+ }
668
+ // https://www.postgresql.org/docs/12/functions-json.html#FUNCTIONS-JSON-OP-TABLE
669
+ function JSONPathValuePredicate(dbCol, path, val, pred) {
670
+ return new jSONPathValuePredicateClause(dbCol, path, val, pred);
671
+ }
672
+ exports.JSONPathValuePredicate = JSONPathValuePredicate;
673
+ // TODO need a better name for this lol
674
+ // this assumes we're doing the same direction twice which isn't necessarily accurate in the future...
675
+ class paginationMultipleColumnsSubQueryClause {
676
+ constructor(col, op, tableName, uniqueCol, val) {
677
+ this.col = col;
678
+ this.op = op;
679
+ this.tableName = tableName;
680
+ this.uniqueCol = uniqueCol;
681
+ this.val = val;
682
+ }
683
+ buildSimpleQuery(clause, idx) {
684
+ return `SELECT ${this.col} FROM ${this.tableName} WHERE ${clause.clause(idx)}`;
685
+ }
686
+ clause(idx) {
687
+ const eq1 = this.buildSimpleQuery(Eq(this.uniqueCol, this.val), idx);
688
+ const eq2 = this.buildSimpleQuery(Eq(this.uniqueCol, this.val), idx + 1);
689
+ const op = new simpleClause(this.uniqueCol, this.val, this.op).clause(idx + 2);
690
+ // nest in () to make sure it's scoped correctly
691
+ return `(${this.col} ${this.op} (${eq1}) OR (${this.col} = (${eq2}) AND ${op}))`;
692
+ }
693
+ columns() {
694
+ return [this.col];
695
+ }
696
+ values() {
697
+ return [this.val, this.val, this.val];
698
+ }
699
+ logValues() {
700
+ const log = isSensitive(this.val) ? this.val.logValue() : this.val;
701
+ return [log, log, log];
702
+ }
703
+ instanceKey() {
704
+ return `${this.col}-${this.op}-${this.tableName}-${this.uniqueCol}-${this.val}`;
705
+ }
706
+ }
707
+ function PaginationMultipleColsSubQuery(col, op, tableName, uniqueCol, val) {
708
+ return new paginationMultipleColumnsSubQueryClause(col, op, tableName, uniqueCol, val);
709
+ }
710
+ exports.PaginationMultipleColsSubQuery = PaginationMultipleColsSubQuery;
711
+ // These 5 are used on the RHS of an expression
712
+ function Add(col, value) {
713
+ return new simpleClause(col, value, "+", new isNullClause(col));
714
+ }
715
+ exports.Add = Add;
716
+ function Subtract(col, value) {
717
+ return new simpleClause(col, value, "-", new isNullClause(col));
718
+ }
719
+ exports.Subtract = Subtract;
720
+ function Multiply(col, value) {
721
+ return new simpleClause(col, value, "*", new isNullClause(col));
722
+ }
723
+ exports.Multiply = Multiply;
724
+ function Divide(col, value) {
725
+ return new simpleClause(col, value, "/", new isNullClause(col));
726
+ }
727
+ exports.Divide = Divide;
728
+ function Modulo(col, value) {
729
+ return new simpleClause(col, value, "%", new isNullClause(col));
730
+ }
731
+ exports.Modulo = Modulo;