@snowtop/ent 0.1.0-alpha7 → 0.1.0-alpha75

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 (116) hide show
  1. package/action/action.d.ts +28 -24
  2. package/action/executor.d.ts +4 -4
  3. package/action/executor.js +2 -2
  4. package/action/experimental_action.d.ts +29 -22
  5. package/action/experimental_action.js +29 -6
  6. package/action/orchestrator.d.ts +44 -16
  7. package/action/orchestrator.js +287 -73
  8. package/action/privacy.d.ts +2 -2
  9. package/core/base.d.ts +43 -23
  10. package/core/base.js +16 -0
  11. package/core/clause.d.ts +82 -3
  12. package/core/clause.js +463 -27
  13. package/core/config.d.ts +26 -0
  14. package/core/config.js +17 -0
  15. package/core/context.d.ts +5 -3
  16. package/core/context.js +7 -2
  17. package/core/convert.d.ts +1 -1
  18. package/core/db.d.ts +3 -4
  19. package/core/db.js +2 -0
  20. package/core/ent.d.ts +71 -27
  21. package/core/ent.js +458 -97
  22. package/core/loaders/assoc_count_loader.d.ts +2 -2
  23. package/core/loaders/assoc_count_loader.js +6 -1
  24. package/core/loaders/assoc_edge_loader.d.ts +3 -3
  25. package/core/loaders/assoc_edge_loader.js +5 -4
  26. package/core/loaders/index_loader.js +1 -0
  27. package/core/loaders/loader.js +5 -5
  28. package/core/loaders/object_loader.d.ts +11 -5
  29. package/core/loaders/object_loader.js +70 -4
  30. package/core/loaders/query_loader.d.ts +2 -2
  31. package/core/loaders/raw_count_loader.d.ts +2 -2
  32. package/core/logger.d.ts +1 -1
  33. package/core/logger.js +1 -0
  34. package/core/privacy.d.ts +26 -25
  35. package/core/privacy.js +23 -24
  36. package/core/query/assoc_query.d.ts +6 -6
  37. package/core/query/custom_query.d.ts +5 -5
  38. package/core/query/query.d.ts +1 -1
  39. package/core/query/shared_assoc_test.d.ts +1 -1
  40. package/core/query/shared_assoc_test.js +17 -5
  41. package/core/query/shared_test.d.ts +3 -0
  42. package/core/query/shared_test.js +95 -17
  43. package/core/viewer.d.ts +4 -3
  44. package/core/viewer.js +5 -1
  45. package/graphql/builtins/connection.js +3 -3
  46. package/graphql/builtins/edge.js +2 -2
  47. package/graphql/builtins/node.js +1 -1
  48. package/graphql/graphql.d.ts +3 -2
  49. package/graphql/graphql.js +30 -23
  50. package/graphql/node_resolver.d.ts +0 -1
  51. package/graphql/query/connection_type.js +6 -6
  52. package/graphql/query/edge_connection.d.ts +9 -9
  53. package/graphql/query/page_info.d.ts +1 -1
  54. package/graphql/query/page_info.js +4 -4
  55. package/graphql/query/shared_assoc_test.js +2 -2
  56. package/graphql/scalars/time.d.ts +1 -1
  57. package/index.d.ts +21 -1
  58. package/index.js +24 -5
  59. package/package.json +3 -3
  60. package/parse_schema/parse.d.ts +24 -5
  61. package/parse_schema/parse.js +90 -8
  62. package/schema/base_schema.d.ts +36 -1
  63. package/schema/base_schema.js +51 -2
  64. package/schema/field.d.ts +34 -6
  65. package/schema/field.js +67 -2
  66. package/schema/index.d.ts +2 -2
  67. package/schema/index.js +8 -1
  68. package/schema/json_field.d.ts +13 -1
  69. package/schema/json_field.js +28 -1
  70. package/schema/schema.d.ts +101 -2
  71. package/schema/schema.js +127 -5
  72. package/schema/struct_field.d.ts +11 -1
  73. package/schema/struct_field.js +43 -4
  74. package/scripts/custom_graphql.js +127 -16
  75. package/scripts/{transform_schema.d.ts → migrate_v0.1.d.ts} +0 -0
  76. package/scripts/migrate_v0.1.js +36 -0
  77. package/scripts/read_schema.js +25 -2
  78. package/testutils/builder.d.ts +36 -22
  79. package/testutils/builder.js +110 -13
  80. package/testutils/context/test_context.d.ts +2 -2
  81. package/testutils/context/test_context.js +7 -1
  82. package/testutils/db/{test_db.d.ts → temp_db.d.ts} +17 -4
  83. package/testutils/db/{test_db.js → temp_db.js} +76 -19
  84. package/testutils/ent-graphql-tests/index.d.ts +2 -0
  85. package/testutils/ent-graphql-tests/index.js +26 -17
  86. package/testutils/fake_data/fake_contact.d.ts +5 -9
  87. package/testutils/fake_data/fake_contact.js +17 -21
  88. package/testutils/fake_data/fake_event.d.ts +5 -9
  89. package/testutils/fake_data/fake_event.js +24 -28
  90. package/testutils/fake_data/fake_user.d.ts +6 -10
  91. package/testutils/fake_data/fake_user.js +25 -29
  92. package/testutils/fake_data/test_helpers.d.ts +2 -2
  93. package/testutils/fake_data/test_helpers.js +6 -6
  94. package/testutils/fake_data/user_query.d.ts +2 -2
  95. package/testutils/fake_log.d.ts +3 -3
  96. package/testutils/parse_sql.d.ts +6 -0
  97. package/testutils/parse_sql.js +16 -2
  98. package/testutils/test_edge_global_schema.d.ts +15 -0
  99. package/testutils/test_edge_global_schema.js +58 -0
  100. package/testutils/write.d.ts +2 -2
  101. package/testutils/write.js +3 -3
  102. package/tsc/ast.d.ts +44 -0
  103. package/tsc/ast.js +267 -0
  104. package/tsc/compilerOptions.d.ts +6 -0
  105. package/tsc/compilerOptions.js +40 -1
  106. package/tsc/move_generated.d.ts +1 -0
  107. package/tsc/move_generated.js +160 -0
  108. package/tsc/transform.d.ts +21 -0
  109. package/tsc/transform.js +167 -0
  110. package/tsc/transform_action.d.ts +22 -0
  111. package/tsc/transform_action.js +179 -0
  112. package/tsc/transform_ent.d.ts +17 -0
  113. package/tsc/transform_ent.js +59 -0
  114. package/tsc/transform_schema.d.ts +27 -0
  115. package/tsc/transform_schema.js +379 -0
  116. package/scripts/transform_schema.js +0 -288
package/core/clause.js CHANGED
@@ -19,10 +19,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
19
19
  return result;
20
20
  };
21
21
  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;
22
+ 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.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
23
  const db_1 = __importStar(require("./db"));
24
24
  function isSensitive(val) {
25
- return (typeof val === "object" && val.logValue !== undefined);
25
+ return (val !== null &&
26
+ typeof val === "object" &&
27
+ val.logValue !== undefined);
26
28
  }
27
29
  function rawValue(val) {
28
30
  if (isSensitive(val)) {
@@ -31,23 +33,155 @@ function rawValue(val) {
31
33
  return val;
32
34
  }
33
35
  class simpleClause {
34
- constructor(col, value, op) {
36
+ constructor(col, value, op, handleNull) {
35
37
  this.col = col;
36
38
  this.value = value;
37
39
  this.op = op;
40
+ this.handleNull = handleNull;
38
41
  }
39
42
  clause(idx) {
43
+ const nullClause = this.nullClause();
44
+ if (nullClause) {
45
+ return nullClause.clause(idx);
46
+ }
40
47
  if (db_1.default.getDialect() === db_1.Dialect.Postgres) {
41
48
  return `${this.col} ${this.op} $${idx}`;
42
49
  }
43
50
  return `${this.col} ${this.op} ?`;
44
51
  }
52
+ nullClause() {
53
+ if (!this.handleNull || this.value !== null) {
54
+ return;
55
+ }
56
+ return this.handleNull;
57
+ }
58
+ columns() {
59
+ return [this.col];
60
+ }
45
61
  values() {
62
+ const sqliteClause = this.nullClause();
63
+ if (sqliteClause) {
64
+ return sqliteClause.values();
65
+ }
46
66
  if (isSensitive(this.value)) {
47
67
  return [this.value.value()];
48
68
  }
49
69
  return [this.value];
50
70
  }
71
+ logValues() {
72
+ const sqliteClause = this.nullClause();
73
+ if (sqliteClause) {
74
+ return sqliteClause.logValues();
75
+ }
76
+ if (isSensitive(this.value)) {
77
+ return [this.value.logValue()];
78
+ }
79
+ return [this.value];
80
+ }
81
+ instanceKey() {
82
+ const sqliteClause = this.nullClause();
83
+ if (sqliteClause) {
84
+ return sqliteClause.instanceKey();
85
+ }
86
+ return `${this.col}${this.op}${rawValue(this.value)}`;
87
+ }
88
+ }
89
+ class isNullClause {
90
+ constructor(col) {
91
+ this.col = col;
92
+ }
93
+ clause(idx) {
94
+ return `${this.col} IS NULL`;
95
+ }
96
+ columns() {
97
+ return [];
98
+ }
99
+ values() {
100
+ return [];
101
+ }
102
+ logValues() {
103
+ return [];
104
+ }
105
+ instanceKey() {
106
+ return `${this.col} IS NULL`;
107
+ }
108
+ }
109
+ class isNotNullClause {
110
+ constructor(col) {
111
+ this.col = col;
112
+ }
113
+ clause(idx) {
114
+ return `${this.col} IS NOT NULL`;
115
+ }
116
+ columns() {
117
+ return [];
118
+ }
119
+ values() {
120
+ return [];
121
+ }
122
+ logValues() {
123
+ return [];
124
+ }
125
+ instanceKey() {
126
+ return `${this.col} IS NOT NULL`;
127
+ }
128
+ }
129
+ class arraySimpleClause {
130
+ constructor(col, value, op) {
131
+ this.col = col;
132
+ this.value = value;
133
+ this.op = op;
134
+ }
135
+ clause(idx) {
136
+ if (db_1.default.getDialect() === db_1.Dialect.Postgres) {
137
+ return `$${idx} ${this.op} ANY(${this.col})`;
138
+ }
139
+ return `${this.col} ${this.op} ?`;
140
+ }
141
+ columns() {
142
+ return [this.col];
143
+ }
144
+ values() {
145
+ if (isSensitive(this.value)) {
146
+ return [this.value.value()];
147
+ }
148
+ return [this.value];
149
+ }
150
+ logValues() {
151
+ if (isSensitive(this.value)) {
152
+ return [this.value.logValue()];
153
+ }
154
+ return [this.value];
155
+ }
156
+ instanceKey() {
157
+ return `${this.col}${this.op}${rawValue(this.value)}`;
158
+ }
159
+ }
160
+ class postgresArrayOperator {
161
+ constructor(col, value, op, not) {
162
+ this.col = col;
163
+ this.value = value;
164
+ this.op = op;
165
+ this.not = not;
166
+ }
167
+ clause(idx) {
168
+ if (db_1.default.getDialect() === db_1.Dialect.Postgres) {
169
+ if (this.not) {
170
+ return `NOT ${this.col} ${this.op} $${idx}`;
171
+ }
172
+ return `${this.col} ${this.op} $${idx}`;
173
+ }
174
+ throw new Error(`not supported`);
175
+ }
176
+ columns() {
177
+ return [this.col];
178
+ }
179
+ values() {
180
+ if (isSensitive(this.value)) {
181
+ return [`{${this.value.value()}}`];
182
+ }
183
+ return [`{${this.value}}`];
184
+ }
51
185
  logValues() {
52
186
  if (isSensitive(this.value)) {
53
187
  return [this.value.logValue()];
@@ -55,21 +189,61 @@ class simpleClause {
55
189
  return [this.value];
56
190
  }
57
191
  instanceKey() {
192
+ if (this.not) {
193
+ return `NOT:${this.col}${this.op}${rawValue(this.value)}`;
194
+ }
58
195
  return `${this.col}${this.op}${rawValue(this.value)}`;
59
196
  }
60
197
  }
198
+ class postgresArrayOperatorList extends postgresArrayOperator {
199
+ constructor(col, value, op, not) {
200
+ super(col, value, op, not);
201
+ }
202
+ values() {
203
+ return [
204
+ `{${this.value
205
+ .map((v) => {
206
+ if (isSensitive(v)) {
207
+ return v.value();
208
+ }
209
+ return v;
210
+ })
211
+ .join(", ")}}`,
212
+ ];
213
+ }
214
+ }
61
215
  class inClause {
62
- constructor(col, value) {
216
+ constructor(col, value, type = "uuid") {
63
217
  this.col = col;
64
218
  this.value = value;
219
+ this.type = type;
220
+ }
221
+ static getPostgresInClauseValuesThreshold() {
222
+ return 70;
65
223
  }
66
224
  clause(idx) {
67
- const dialect = db_1.default.getDialect();
225
+ // do a simple = when only one item
226
+ if (this.value.length === 1) {
227
+ return new simpleClause(this.col, this.value[0], "=").clause(idx);
228
+ }
229
+ const postgres = db_1.default.getDialect() === db_1.Dialect.Postgres;
230
+ const postgresValuesList = postgres &&
231
+ this.value.length >= inClause.getPostgresInClauseValuesThreshold();
68
232
  let indices;
69
- if (dialect === db_1.Dialect.Postgres) {
233
+ if (postgres) {
70
234
  indices = [];
71
235
  for (let i = 0; i < this.value.length; i++) {
72
- indices.push(`$${idx}`);
236
+ if (postgresValuesList) {
237
+ if (i === 0) {
238
+ indices.push(`($${idx}::${this.type})`);
239
+ }
240
+ else {
241
+ indices.push(`($${idx})`);
242
+ }
243
+ }
244
+ else {
245
+ indices.push(`$${idx}`);
246
+ }
73
247
  idx++;
74
248
  }
75
249
  }
@@ -77,34 +251,31 @@ class inClause {
77
251
  indices = new Array(this.value.length);
78
252
  indices.fill("?", 0);
79
253
  }
80
- const inValue = indices.join(", ");
254
+ let inValue = indices.join(", ");
255
+ // wrap in VALUES list for postgres...
256
+ if (postgresValuesList) {
257
+ inValue = `VALUES${inValue}`;
258
+ }
81
259
  return `${this.col} IN (${inValue})`;
82
260
  // TODO we need to return idx at end to query builder...
83
261
  // or anything that's doing a composite query so next clause knows where to start
84
262
  // or change to a sqlx.Rebind format
85
263
  // here's what sqlx does: https://play.golang.org/p/vPzvYqeAcP0
86
264
  }
265
+ columns() {
266
+ return [this.col];
267
+ }
87
268
  values() {
88
269
  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
- }
270
+ for (let value of this.value) {
271
+ result.push(rawValue(value));
96
272
  }
97
273
  return result;
98
274
  }
99
275
  logValues() {
100
276
  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
- }
277
+ for (let value of this.value) {
278
+ result.push(isSensitive(value) ? value.logValue() : value);
108
279
  }
109
280
  return result;
110
281
  }
@@ -112,6 +283,7 @@ class inClause {
112
283
  return `in:${this.col}:${this.values().join(",")}`;
113
284
  }
114
285
  }
286
+ exports.inClause = inClause;
115
287
  class compositeClause {
116
288
  constructor(clauses, sep) {
117
289
  this.clauses = clauses;
@@ -125,6 +297,13 @@ class compositeClause {
125
297
  }
126
298
  return clauses.join(this.sep);
127
299
  }
300
+ columns() {
301
+ const ret = [];
302
+ for (const cls of this.clauses) {
303
+ ret.push(...cls.columns());
304
+ }
305
+ return ret;
306
+ }
128
307
  values() {
129
308
  let result = [];
130
309
  for (const clause of this.clauses) {
@@ -145,12 +324,148 @@ class compositeClause {
145
324
  return keys.join(this.sep);
146
325
  }
147
326
  }
327
+ class tsQueryClause {
328
+ constructor(col, val, tsVectorCol) {
329
+ this.col = col;
330
+ this.val = val;
331
+ this.tsVectorCol = tsVectorCol;
332
+ }
333
+ isTsQuery(val) {
334
+ return typeof val !== "string";
335
+ }
336
+ getInfo() {
337
+ if (this.isTsQuery(this.val)) {
338
+ return { value: this.val.value, language: this.val.language };
339
+ }
340
+ return {
341
+ language: "english",
342
+ value: this.val,
343
+ };
344
+ }
345
+ clause(idx) {
346
+ const { language } = this.getInfo();
347
+ if (db_1.Dialect.Postgres === db_1.default.getDialect()) {
348
+ if (this.tsVectorCol) {
349
+ return `to_tsvector(${this.col}) @@ ${this.getFunction()}('${language}', $${idx})`;
350
+ }
351
+ return `${this.col} @@ ${this.getFunction()}('${language}', $${idx})`;
352
+ }
353
+ // FYI this doesn't actually work for sqlite since different
354
+ return `${this.col} @@ ${this.getFunction()}('${language}', ?)`;
355
+ }
356
+ columns() {
357
+ return [this.col];
358
+ }
359
+ values() {
360
+ const { value } = this.getInfo();
361
+ return [value];
362
+ }
363
+ logValues() {
364
+ const { value } = this.getInfo();
365
+ return [value];
366
+ }
367
+ getFunction() {
368
+ return "to_tsquery";
369
+ }
370
+ instanceKey() {
371
+ const { language, value } = this.getInfo();
372
+ if (this.tsVectorCol) {
373
+ return `to_tsvector(${this.col})@@${this.getFunction()}:${language}:${value}`;
374
+ }
375
+ return `${this.col}@@${this.getFunction()}:${language}:${value}`;
376
+ }
377
+ }
378
+ class plainToTsQueryClause extends tsQueryClause {
379
+ getFunction() {
380
+ return "plainto_tsquery";
381
+ }
382
+ }
383
+ class phraseToTsQueryClause extends tsQueryClause {
384
+ getFunction() {
385
+ return "phraseto_tsquery";
386
+ }
387
+ }
388
+ class websearchTosQueryClause extends tsQueryClause {
389
+ getFunction() {
390
+ return "websearch_to_tsquery";
391
+ }
392
+ }
393
+ // postgres array operators
394
+ // https://www.postgresql.org/docs/current/functions-array.html
395
+ /**
396
+ * creates a clause to determine if the given value is contained in the array stored in the column in the db
397
+ * only works with postgres gin indexes
398
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
399
+ */
400
+ function PostgresArrayContainsValue(col, value) {
401
+ return new postgresArrayOperator(col, value, "@>");
402
+ }
403
+ exports.PostgresArrayContainsValue = PostgresArrayContainsValue;
404
+ /**
405
+ * creates a clause to determine if every item in the list is stored in the array stored in the column in the db
406
+ * only works with postgres gin indexes
407
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
408
+ */
409
+ function PostgresArrayContains(col, value) {
410
+ return new postgresArrayOperatorList(col, value, "@>");
411
+ }
412
+ exports.PostgresArrayContains = PostgresArrayContains;
413
+ /**
414
+ * creates a clause to determine if the given value is NOT contained in the array stored in the column in the db
415
+ * only works with postgres gin indexes
416
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
417
+ */
418
+ function PostgresArrayNotContainsValue(col, value) {
419
+ return new postgresArrayOperator(col, value, "@>", true);
420
+ }
421
+ exports.PostgresArrayNotContainsValue = PostgresArrayNotContainsValue;
422
+ /**
423
+ * creates a clause to determine if every item in the list is NOT stored in the array stored in the column in the db
424
+ * only works with postgres gin indexes
425
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
426
+ */
427
+ function PostgresArrayNotContains(col, value) {
428
+ return new postgresArrayOperatorList(col, value, "@>", true);
429
+ }
430
+ exports.PostgresArrayNotContains = PostgresArrayNotContains;
431
+ /**
432
+ * creates a clause to determine if the arrays overlap, that is, do they have any elements in common
433
+ * only works with postgres gin indexes
434
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
435
+ */
436
+ function PostgresArrayOverlaps(col, value) {
437
+ return new postgresArrayOperatorList(col, value, "&&");
438
+ }
439
+ exports.PostgresArrayOverlaps = PostgresArrayOverlaps;
440
+ /**
441
+ * creates a clause to determine if the arrays do not overlap, that is, do they have any elements in common
442
+ * only works with postgres gin indexes
443
+ * https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
444
+ */
445
+ function PostgresArrayNotOverlaps(col, value) {
446
+ return new postgresArrayOperatorList(col, value, "&&", true);
447
+ }
448
+ exports.PostgresArrayNotOverlaps = PostgresArrayNotOverlaps;
449
+ /**
450
+ * @deprecated use PostgresArrayContainsValue
451
+ */
452
+ function ArrayEq(col, value) {
453
+ return new arraySimpleClause(col, value, "=");
454
+ }
455
+ exports.ArrayEq = ArrayEq;
456
+ /**
457
+ * @deprecated use PostgresNotArrayContains
458
+ */
459
+ function ArrayNotEq(col, value) {
460
+ return new arraySimpleClause(col, value, "!=");
461
+ }
462
+ exports.ArrayNotEq = ArrayNotEq;
148
463
  function Eq(col, value) {
149
- return new simpleClause(col, value, "=");
464
+ return new simpleClause(col, value, "=", new isNullClause(col));
150
465
  }
151
466
  exports.Eq = Eq;
152
467
  function NotEq(col, value) {
153
- return new simpleClause(col, value, "!=");
468
+ return new simpleClause(col, value, "!=", new isNotNullClause(col));
154
469
  }
155
470
  exports.NotEq = NotEq;
156
471
  function Greater(col, value) {
@@ -173,15 +488,84 @@ function And(...args) {
173
488
  return new compositeClause(args, " AND ");
174
489
  }
175
490
  exports.And = And;
491
+ function AndOptional(...args) {
492
+ // @ts-ignore
493
+ let filtered = args.filter((v) => v !== undefined);
494
+ if (filtered.length === 1) {
495
+ return filtered[0];
496
+ }
497
+ return And(...filtered);
498
+ }
499
+ exports.AndOptional = AndOptional;
176
500
  function Or(...args) {
177
501
  return new compositeClause(args, " OR ");
178
502
  }
179
503
  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);
504
+ function In(...args) {
505
+ if (args.length < 2) {
506
+ throw new Error(`invalid args passed to In`);
507
+ }
508
+ // 2nd overload
509
+ if (Array.isArray(args[1])) {
510
+ return new inClause(args[0], args[1], args[2]);
511
+ }
512
+ return new inClause(args[0], args.slice(1));
183
513
  }
184
514
  exports.In = In;
515
+ // if string defaults to english
516
+ // https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES
517
+ // to_tsquery
518
+ // plainto_tsquery
519
+ // phraseto_tsquery;
520
+ // websearch_to_tsquery
521
+ function TsQuery(col, val) {
522
+ return new tsQueryClause(col, val);
523
+ }
524
+ exports.TsQuery = TsQuery;
525
+ function PlainToTsQuery(col, val) {
526
+ return new plainToTsQueryClause(col, val);
527
+ }
528
+ exports.PlainToTsQuery = PlainToTsQuery;
529
+ function PhraseToTsQuery(col, val) {
530
+ return new phraseToTsQueryClause(col, val);
531
+ }
532
+ exports.PhraseToTsQuery = PhraseToTsQuery;
533
+ function WebsearchToTsQuery(col, val) {
534
+ return new websearchTosQueryClause(col, val);
535
+ }
536
+ exports.WebsearchToTsQuery = WebsearchToTsQuery;
537
+ // TsVectorColTsQuery is used when the column is not a tsvector field e.g.
538
+ // when there's an index just on the field and is not a combination of multiple fields
539
+ function TsVectorColTsQuery(col, val) {
540
+ return new tsQueryClause(col, val, true);
541
+ }
542
+ exports.TsVectorColTsQuery = TsVectorColTsQuery;
543
+ // TsVectorPlainToTsQuery is used when the column is not a tsvector field e.g.
544
+ // when there's an index just on the field and is not a combination of multiple fields
545
+ // TODO do these 4 need TsQuery because would be nice to have language?
546
+ // it seems to default to the config of the column
547
+ function TsVectorPlainToTsQuery(col, val) {
548
+ return new plainToTsQueryClause(col, val, true);
549
+ }
550
+ exports.TsVectorPlainToTsQuery = TsVectorPlainToTsQuery;
551
+ // TsVectorPhraseToTsQuery is used when the column is not a tsvector field e.g.
552
+ // when there's an index just on the field and is not a combination of multiple fields
553
+ function TsVectorPhraseToTsQuery(col, val) {
554
+ return new phraseToTsQueryClause(col, val, true);
555
+ }
556
+ exports.TsVectorPhraseToTsQuery = TsVectorPhraseToTsQuery;
557
+ // TsVectorWebsearchToTsQuery is used when the column is not a tsvector field e.g.
558
+ // when there's an index just on the field and is not a combination of multiple fields
559
+ function TsVectorWebsearchToTsQuery(col, val) {
560
+ return new websearchTosQueryClause(col, val, true);
561
+ }
562
+ exports.TsVectorWebsearchToTsQuery = TsVectorWebsearchToTsQuery;
563
+ // TODO would be nice to support this with building blocks but not supporting for now
564
+ // AND: foo & bar,
565
+ // OR: foo | bar
566
+ // followed by: foo <-> bar
567
+ // NOT: !foo
568
+ // starts_with: theo:*
185
569
  // wrap a query in the db with this to ensure that it doesn't show up in the logs
186
570
  // e.g. if querying for password, SSN, etc
187
571
  // we'll pass the right fields to query and log something along the lines of `****`
@@ -196,3 +580,55 @@ function sensitiveValue(val) {
196
580
  };
197
581
  }
198
582
  exports.sensitiveValue = sensitiveValue;
583
+ // These don't return Clauses but return helpful things that can be passed to clauses
584
+ // https://www.postgresql.org/docs/12/functions-json.html#FUNCTIONS-JSON-OP-TABLE
585
+ // see test in db_clause.test.ts
586
+ // unclear best time to use this...
587
+ function JSONObjectFieldKeyASJSON(col, field) {
588
+ return `${col}->'${field}'`;
589
+ }
590
+ exports.JSONObjectFieldKeyASJSON = JSONObjectFieldKeyASJSON;
591
+ function JSONObjectFieldKeyAsText(col, field) {
592
+ return `${col}->>'${field}'`;
593
+ }
594
+ exports.JSONObjectFieldKeyAsText = JSONObjectFieldKeyAsText;
595
+ class jSONPathValuePredicateClause {
596
+ constructor(col, path, value, pred) {
597
+ this.col = col;
598
+ this.path = path;
599
+ this.value = value;
600
+ this.pred = pred;
601
+ }
602
+ clause(idx) {
603
+ if (db_1.default.getDialect() !== db_1.Dialect.Postgres) {
604
+ throw new Error(`not supported`);
605
+ }
606
+ return `${this.col} @@ $${idx}`;
607
+ }
608
+ columns() {
609
+ return [this.col];
610
+ }
611
+ wrap(val) {
612
+ return `${this.path} ${this.pred} ${JSON.stringify(val)}`;
613
+ }
614
+ values() {
615
+ if (isSensitive(this.value)) {
616
+ return [this.wrap(this.value.value())];
617
+ }
618
+ return [this.wrap(this.value)];
619
+ }
620
+ logValues() {
621
+ if (isSensitive(this.value)) {
622
+ return [this.wrap(this.value.logValue())];
623
+ }
624
+ return [this.wrap(this.value)];
625
+ }
626
+ instanceKey() {
627
+ return `${this.col}${this.path}${rawValue(this.value)}${this.pred}`;
628
+ }
629
+ }
630
+ // https://www.postgresql.org/docs/12/functions-json.html#FUNCTIONS-JSON-OP-TABLE
631
+ function JSONPathValuePredicate(dbCol, path, val, pred) {
632
+ return new jSONPathValuePredicateClause(dbCol, path, val, pred);
633
+ }
634
+ exports.JSONPathValuePredicate = JSONPathValuePredicate;
package/core/config.d.ts CHANGED
@@ -1,12 +1,26 @@
1
1
  /// <reference types="node" />
2
2
  import { Database, DBDict } from "./db";
3
3
  declare type logType = "query" | "warn" | "info" | "error" | "debug";
4
+ declare enum graphqlMutationName {
5
+ NOUN_VERB = "NounVerb",
6
+ VERB_NOUN = "VerbNoun"
7
+ }
8
+ declare enum graphQLFieldFormat {
9
+ LOWER_CAMEL = "lowerCamel",
10
+ SNAKE_CASE = "snake_case"
11
+ }
12
+ declare enum fieldPrivacyEvaluated {
13
+ AT_ENT_LOAD = "at_ent_load",
14
+ ON_DEMAND = "on_demand"
15
+ }
4
16
  export interface Config {
5
17
  dbConnectionString?: string;
6
18
  dbFile?: string;
7
19
  db?: Database | DBDict;
8
20
  log?: logType | logType[];
9
21
  codegen?: CodegenConfig;
22
+ customGraphQLJSONPath?: string;
23
+ globalSchemaPath?: string;
10
24
  }
11
25
  interface CodegenConfig {
12
26
  defaultEntPolicy?: PrivacyConfig;
@@ -17,6 +31,13 @@ interface CodegenConfig {
17
31
  generatedHeader?: string;
18
32
  disableBase64Encoding?: boolean;
19
33
  generateRootResolvers?: boolean;
34
+ defaultGraphQLMutationName?: graphqlMutationName;
35
+ defaultGraphQLFieldFormat?: graphQLFieldFormat;
36
+ schemaSQLFilePath?: boolean;
37
+ databaseToCompareTo?: string;
38
+ fieldPrivacyEvaluated?: fieldPrivacyEvaluated;
39
+ templatizedViewer?: importedObject;
40
+ customAssocEdgePath?: importedObject;
20
41
  }
21
42
  interface PrettierConfig {
22
43
  custom?: boolean;
@@ -27,5 +48,10 @@ interface PrivacyConfig {
27
48
  policyName: string;
28
49
  class?: boolean;
29
50
  }
51
+ interface importedObject {
52
+ path: string;
53
+ name: string;
54
+ alias?: string;
55
+ }
30
56
  export declare function loadConfig(file?: string | Buffer | Config): void;
31
57
  export {};
package/core/config.js CHANGED
@@ -28,6 +28,23 @@ const js_yaml_1 = require("js-yaml");
28
28
  const db_1 = __importDefault(require("./db"));
29
29
  const path = __importStar(require("path"));
30
30
  const logger_1 = require("./logger");
31
+ // ent.config.ts eventually. for now ent.yml
32
+ // or ent.yml?
33
+ var graphqlMutationName;
34
+ (function (graphqlMutationName) {
35
+ graphqlMutationName["NOUN_VERB"] = "NounVerb";
36
+ graphqlMutationName["VERB_NOUN"] = "VerbNoun";
37
+ })(graphqlMutationName || (graphqlMutationName = {}));
38
+ var graphQLFieldFormat;
39
+ (function (graphQLFieldFormat) {
40
+ graphQLFieldFormat["LOWER_CAMEL"] = "lowerCamel";
41
+ graphQLFieldFormat["SNAKE_CASE"] = "snake_case";
42
+ })(graphQLFieldFormat || (graphQLFieldFormat = {}));
43
+ var fieldPrivacyEvaluated;
44
+ (function (fieldPrivacyEvaluated) {
45
+ fieldPrivacyEvaluated["AT_ENT_LOAD"] = "at_ent_load";
46
+ fieldPrivacyEvaluated["ON_DEMAND"] = "on_demand";
47
+ })(fieldPrivacyEvaluated || (fieldPrivacyEvaluated = {}));
31
48
  function setConfig(cfg) {
32
49
  if (cfg.log) {
33
50
  (0, logger_1.setLogLevels)(cfg.log);
package/core/context.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  /// <reference types="node" />
2
- import { Viewer, Data, Loader } from "./base";
2
+ import { Viewer, Data, Loader, Ent } from "./base";
3
3
  import { IncomingMessage, ServerResponse } from "http";
4
4
  import * as clause from "./clause";
5
5
  import { Context } from "./base";
6
- export interface RequestContext extends Context {
7
- authViewer(viewer: Viewer): Promise<void>;
6
+ export interface RequestContext<TViewer extends Viewer = Viewer> extends Context<TViewer> {
7
+ authViewer(viewer: TViewer): Promise<void>;
8
8
  logout(): Promise<void>;
9
9
  request: IncomingMessage;
10
10
  response: ServerResponse;
@@ -14,12 +14,14 @@ export declare class ContextCache {
14
14
  getLoader<T, V>(name: string, create: () => Loader<T, V>): Loader<T, V>;
15
15
  private itemMap;
16
16
  private listMap;
17
+ private entCache;
17
18
  private getkey;
18
19
  getCachedRows(options: queryOptions): Data[] | null;
19
20
  getCachedRow(options: queryOptions): Data | null;
20
21
  primeCache(options: queryOptions, rows: Data[]): void;
21
22
  primeCache(options: queryOptions, rows: Data): void;
22
23
  clearCache(): void;
24
+ getEntCache(): Map<string, Error | Ent<any> | null>;
23
25
  }
24
26
  interface queryOptions {
25
27
  fields: string[];