@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
@@ -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];
@@ -22,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
27
  };
24
28
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.getSchemaTable = exports.setupSqlite = exports.assoc_edge_table = exports.assoc_edge_config_table = exports.TempDB = exports.enumType = exports.table = exports.boolList = exports.dateList = exports.timetzList = exports.timeList = exports.timestamptzList = exports.timestampList = exports.uuidList = exports.integerList = exports.textList = exports.jsonb = exports.json = exports.float = exports.integer = exports.bool = exports.date = exports.timetz = exports.time = exports.timestamptz = exports.timestamp = exports.enumCol = exports.text = exports.uuid = exports.uniqueIndex = exports.foreignKey = exports.primaryKey = void 0;
29
+ exports.getColumnFromField = exports.getSchemaTable = exports.doSQLiteTestFromSchemas = exports.setupPostgres = exports.setupSqlite = exports.assoc_edge_table = exports.assoc_edge_config_table = exports.TempDB = exports.enumType = exports.table = exports.boolList = exports.dateList = exports.timetzList = exports.timeList = exports.timestamptzList = exports.timestampList = exports.uuidList = exports.integerList = exports.textList = exports.jsonb = exports.json = exports.float = exports.integer = exports.bool = exports.date = exports.timetz = exports.time = exports.timestamptz = exports.timestamp = exports.enumCol = exports.text = exports.uuid = exports.index = exports.check = exports.foreignKey = exports.primaryKey = void 0;
26
30
  const pg_1 = require("pg");
27
31
  const db_1 = __importStar(require("../../core/db"));
28
32
  // this should only be used in tests so we expect to be able to import without shenanigans
@@ -32,6 +36,7 @@ const fs = __importStar(require("fs"));
32
36
  const schema_1 = require("../../schema");
33
37
  const snake_case_1 = require("snake-case");
34
38
  const builder_1 = require("../builder");
39
+ const test_edge_global_schema_1 = require("../test_edge_global_schema");
35
40
  function primaryKey(name, cols) {
36
41
  return {
37
42
  name: name,
@@ -50,15 +55,35 @@ function foreignKey(name, cols, fkey) {
50
55
  };
51
56
  }
52
57
  exports.foreignKey = foreignKey;
53
- function uniqueIndex(name) {
58
+ function check(name, condition) {
54
59
  return {
55
- name: "",
60
+ name,
56
61
  generate() {
57
- return `UNIQUE (${name})`;
62
+ return `CONSTRAINT ${name} CHECK(${condition})`;
58
63
  },
59
64
  };
60
65
  }
61
- exports.uniqueIndex = uniqueIndex;
66
+ exports.check = check;
67
+ function isPostCreateIndex(s) {
68
+ return (s.postCreate !== undefined &&
69
+ s.postCreate());
70
+ }
71
+ function index(tableName, cols, opts) {
72
+ const name = `${tableName}_${cols.join("_")}_idx`;
73
+ return {
74
+ name,
75
+ generate() {
76
+ if (opts?.unique && db_1.Dialect.SQLite === db_1.default.getDialect()) {
77
+ return `UNIQUE (${cols.join(",")})`;
78
+ }
79
+ return `CREATE ${opts?.unique ? "UNIQUE " : ""}INDEX ${name} ON ${tableName} USING ${opts?.type || "btree"} (${cols.join(",")});`;
80
+ },
81
+ postCreate() {
82
+ return db_1.Dialect.Postgres === db_1.default.getDialect() && !!opts?.unique;
83
+ },
84
+ };
85
+ }
86
+ exports.index = index;
62
87
  function uuid(name, opts) {
63
88
  return {
64
89
  name,
@@ -248,9 +273,24 @@ exports.boolList = boolList;
248
273
  function table(name, ...items) {
249
274
  let cols = [];
250
275
  let constraints = [];
276
+ let indexes = [];
251
277
  for (const item of items) {
252
278
  if (item.datatype !== undefined) {
253
279
  const col = item;
280
+ if (col.index) {
281
+ let opts = {
282
+ type: "btree",
283
+ };
284
+ if (col.index === true) {
285
+ opts = {
286
+ type: "btree",
287
+ };
288
+ }
289
+ else {
290
+ opts = col.index;
291
+ }
292
+ indexes.push(index(name, [col.name], opts));
293
+ }
254
294
  // add it as a constraint
255
295
  if (col.foreignKey) {
256
296
  constraints.push(foreignKey(`${name}_${col.name}_fkey`, [col.name], {
@@ -261,7 +301,12 @@ function table(name, ...items) {
261
301
  cols.push(item);
262
302
  }
263
303
  else if (item.generate !== undefined) {
264
- constraints.push(item);
304
+ if (isPostCreateIndex(item) && item.postCreate()) {
305
+ indexes.push(item);
306
+ }
307
+ else {
308
+ constraints.push(item);
309
+ }
265
310
  }
266
311
  }
267
312
  return {
@@ -278,7 +323,12 @@ function table(name, ...items) {
278
323
  parts.push("PRIMARY KEY");
279
324
  }
280
325
  if (col.default !== undefined) {
281
- parts.push(`DEFAULT ${col.default}`);
326
+ if (db_1.Dialect.SQLite === db_1.default.getDialect()) {
327
+ parts.push(`DEFAULT "${col.default}"`);
328
+ }
329
+ else {
330
+ parts.push(`DEFAULT ${col.default}`);
331
+ }
282
332
  }
283
333
  if (col.unique) {
284
334
  parts.push("UNIQUE");
@@ -288,6 +338,9 @@ function table(name, ...items) {
288
338
  constraints.forEach((constraint) => schemaStr.push(constraint.generate()));
289
339
  return `CREATE TABLE IF NOT EXISTS ${name} (\n ${schemaStr})`;
290
340
  },
341
+ postCreate() {
342
+ return indexes.map((index) => index.generate());
343
+ },
291
344
  drop() {
292
345
  return `DROP TABLE IF EXISTS ${name}`;
293
346
  },
@@ -311,32 +364,21 @@ function randomDB() {
311
364
  // always ensure it starts with an alpha character
312
365
  return "abcdefghijklmnopqrstuvwxyz"[Math.floor(Math.random() * 26)] + str;
313
366
  }
314
- function isDialect(dialect) {
315
- return !Array.isArray(dialect);
316
- }
317
367
  class TempDB {
318
368
  constructor(dialect, tables) {
319
369
  this.tables = new Map();
320
- let tbles = [];
321
- if (isDialect(dialect)) {
322
- this.dialect = dialect;
323
- if (tables) {
324
- tbles = tables;
325
- }
326
- }
327
- else {
328
- this.dialect = db_1.Dialect.Postgres;
329
- tbles = dialect;
330
- }
331
- tbles.forEach((table) => this.tables.set(table.name, table));
370
+ this.dialect = dialect;
371
+ this.setTables = tables;
332
372
  }
333
373
  getDialect() {
334
374
  return this.dialect;
335
375
  }
336
- getTables() {
376
+ // NB: this won't be set until after beforeAll() is called since it depends on
377
+ // dialect being correctly set
378
+ __getTables() {
337
379
  return this.tables;
338
380
  }
339
- async beforeAll() {
381
+ async beforeAll(setupConnString = true) {
340
382
  if (this.dialect === db_1.Dialect.Postgres) {
341
383
  const user = process.env.POSTGRES_USER || "";
342
384
  const password = process.env.POSTGRES_PASSWORD || "";
@@ -348,11 +390,22 @@ class TempDB {
348
390
  await this.client.connect();
349
391
  this.db = randomDB();
350
392
  await this.client.query(`CREATE DATABASE ${this.db}`);
351
- if (user && password) {
352
- process.env.DB_CONNECTION_STRING = `postgres://${user}:${password}@localhost:5432/${this.db}`;
393
+ if (setupConnString) {
394
+ delete process.env.DB_CONNECTION_STRING;
395
+ let connStr = "";
396
+ if (user && password) {
397
+ connStr = `postgres://${user}:${password}@localhost:5432/${this.db}`;
398
+ }
399
+ else {
400
+ connStr = `postgres://localhost/${this.db}?`;
401
+ }
402
+ db_1.default.initDB({
403
+ connectionString: connStr,
404
+ });
353
405
  }
354
406
  else {
355
- process.env.DB_CONNECTION_STRING = `postgres://localhost/${this.db}?`;
407
+ // will probably be setup via loadConfig
408
+ delete process.env.DB_CONNECTION_STRING;
356
409
  }
357
410
  this.dbClient = new pg_1.Client({
358
411
  host: "localhost",
@@ -369,12 +422,35 @@ class TempDB {
369
422
  const filePath = process.env.DB_CONNECTION_STRING.substr(10);
370
423
  this.sqlite = (0, better_sqlite3_1.default)(filePath);
371
424
  }
372
- for (const [_, table] of this.tables) {
373
- if (this.dialect == db_1.Dialect.Postgres) {
374
- await this.dbClient.query(table.create());
425
+ if (this.setTables) {
426
+ let tables = [];
427
+ if (typeof this.setTables === "function") {
428
+ tables = this.setTables();
375
429
  }
376
430
  else {
377
- this.sqlite.exec(table.create());
431
+ tables = this.setTables;
432
+ }
433
+ tables.forEach((table) => this.tables.set(table.name, table));
434
+ }
435
+ for (const [_, table] of this.tables) {
436
+ await this.createImpl(table);
437
+ }
438
+ }
439
+ async createImpl(table) {
440
+ if (this.dialect == db_1.Dialect.Postgres) {
441
+ await this.dbClient.query(table.create());
442
+ if (table.postCreate) {
443
+ for (const q of table.postCreate()) {
444
+ await this.dbClient.query(q);
445
+ }
446
+ }
447
+ }
448
+ else {
449
+ this.sqlite.exec(table.create());
450
+ if (table.postCreate) {
451
+ for (const q of table.postCreate()) {
452
+ this.sqlite.exec(q);
453
+ }
378
454
  }
379
455
  }
380
456
  }
@@ -397,6 +473,9 @@ class TempDB {
397
473
  await this.client.query(`DROP DATABASE ${this.db}`);
398
474
  await this.client.end();
399
475
  }
476
+ getDB() {
477
+ return this.db;
478
+ }
400
479
  async dropAll() {
401
480
  for (const [t, _] of this.tables) {
402
481
  await this.drop(t);
@@ -422,12 +501,7 @@ class TempDB {
422
501
  if (this.tables.has(table.name)) {
423
502
  throw new Error(`table with name ${table.name} already exists`);
424
503
  }
425
- if (this.dialect === db_1.Dialect.Postgres) {
426
- await this.dbClient.query(table.create());
427
- }
428
- else {
429
- this.sqlite.exec(table.create());
430
- }
504
+ await this.createImpl(table);
431
505
  this.tables.set(table.name, table);
432
506
  }
433
507
  }
@@ -439,18 +513,26 @@ function assoc_edge_config_table() {
439
513
  text("edge_type", { primaryKey: true }), text("edge_name"), bool("symmetric_edge", { default: "FALSE" }), text("inverse_edge_type", { nullable: true }), text("edge_table"), timestamptz("created_at"), timestamptz("updated_at"));
440
514
  }
441
515
  exports.assoc_edge_config_table = assoc_edge_config_table;
442
- function assoc_edge_table(name) {
443
- return table(name, uuid("id1"), text("id1_type"),
516
+ // if global flag is true, add any column from testEdgeGlobalSchema
517
+ // up to caller to set/clear that as needed
518
+ function assoc_edge_table(name, global) {
519
+ const t = table(name, uuid("id1"), text("id1_type"),
444
520
  // same as in assoc_edge_config_table
445
521
  text("edge_type"), uuid("id2"), text("id2_type"), timestamptz("time"), text("data", { nullable: true }), primaryKey(`${name}_pkey`, ["id1", "id2", "edge_type"]));
522
+ if (global) {
523
+ for (const k in test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields) {
524
+ const col = getColumnFromField(k, test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields[k], db_1.Dialect.Postgres);
525
+ t.columns.push(col);
526
+ }
527
+ }
528
+ return t;
446
529
  }
447
530
  exports.assoc_edge_table = assoc_edge_table;
448
531
  function setupSqlite(connString, tables, opts) {
449
- let tdb;
532
+ let tdb = new TempDB(db_1.Dialect.SQLite, tables);
450
533
  beforeAll(async () => {
451
534
  process.env.DB_CONNECTION_STRING = connString;
452
535
  (0, config_1.loadConfig)();
453
- tdb = new TempDB(db_1.Dialect.SQLite, tables());
454
536
  await tdb.beforeAll();
455
537
  const conn = db_1.default.getInstance().getConnection();
456
538
  expect(conn.db.memory).toBe(false);
@@ -458,7 +540,7 @@ function setupSqlite(connString, tables, opts) {
458
540
  if (!opts?.disableDeleteAfterEachTest) {
459
541
  afterEach(async () => {
460
542
  const client = await db_1.default.getInstance().getNewClient();
461
- for (const [key, _] of tdb.getTables()) {
543
+ for (const [key, _] of tdb.__getTables()) {
462
544
  const query = `delete from ${key}`;
463
545
  if (isSyncClient(client))
464
546
  if (client.execSync) {
@@ -473,16 +555,77 @@ function setupSqlite(connString, tables, opts) {
473
555
  afterAll(async () => {
474
556
  await tdb.afterAll();
475
557
  fs.rmSync(tdb.getSqliteClient().name);
558
+ delete process.env.DB_CONNECTION_STRING;
476
559
  });
560
+ return tdb;
477
561
  }
478
562
  exports.setupSqlite = setupSqlite;
563
+ function setupPostgres(tables, opts) {
564
+ let tdb;
565
+ beforeAll(async () => {
566
+ tdb = new TempDB(db_1.Dialect.Postgres, tables());
567
+ await tdb.beforeAll();
568
+ });
569
+ // TODO need to fix this implementation...
570
+ if (!opts?.disableDeleteAfterEachTest) {
571
+ afterEach(async () => {
572
+ const client = await db_1.default.getInstance().getNewClient();
573
+ for (const [key, _] of tdb.__getTables()) {
574
+ const query = `delete from ${key}`;
575
+ await client.exec(query);
576
+ }
577
+ client.release();
578
+ });
579
+ }
580
+ afterAll(async () => {
581
+ await tdb.afterAll();
582
+ });
583
+ }
584
+ exports.setupPostgres = setupPostgres;
585
+ async function doSQLiteTestFromSchemas(schemas, doTest, db) {
586
+ const connString = `sqlite:///${db || randomDB()}.db`;
587
+ const tables = schemas.map((schema) => getSchemaTable(schema, db_1.Dialect.SQLite));
588
+ let tdb = new TempDB(db_1.Dialect.SQLite, tables);
589
+ process.env.DB_CONNECTION_STRING = connString;
590
+ (0, config_1.loadConfig)();
591
+ await tdb.beforeAll();
592
+ await doTest();
593
+ await tdb.afterAll();
594
+ delete process.env.DB_CONNECTION_STRING;
595
+ return tdb;
596
+ }
597
+ exports.doSQLiteTestFromSchemas = doSQLiteTestFromSchemas;
479
598
  function getSchemaTable(schema, dialect) {
480
599
  const fields = (0, schema_1.getFields)(schema);
481
- const columns = [];
600
+ const items = [];
482
601
  for (const [fieldName, field] of fields) {
483
- columns.push(getColumnFromField(fieldName, field, dialect));
602
+ items.push(getColumnFromField(fieldName, field, dialect));
603
+ }
604
+ if (schema.constraints) {
605
+ for (const constraint of schema.constraints) {
606
+ switch (constraint.type) {
607
+ case schema_1.ConstraintType.PrimaryKey:
608
+ items.push(primaryKey(constraint.name, constraint.columns));
609
+ break;
610
+ case schema_1.ConstraintType.ForeignKey:
611
+ if (!constraint.fkey) {
612
+ throw new Error(`need 'fkey' field for foreign key constraint`);
613
+ }
614
+ items.push(foreignKey(constraint.name, constraint.columns, {
615
+ table: constraint.fkey.tableName,
616
+ cols: constraint.fkey.columns,
617
+ }));
618
+ break;
619
+ case schema_1.ConstraintType.Check:
620
+ if (!constraint.condition) {
621
+ throw new Error(`need 'condition' field for check constraint`);
622
+ }
623
+ items.push(check(constraint.name, constraint.condition));
624
+ break;
625
+ }
626
+ }
484
627
  }
485
- return table((0, builder_1.getTableName)(schema), ...columns);
628
+ return table((0, builder_1.getTableName)(schema), ...items);
486
629
  }
487
630
  exports.getSchemaTable = getSchemaTable;
488
631
  function getColumnForDbType(t, dialect) {
@@ -540,6 +683,7 @@ function getColumnFromField(fieldName, f, dialect) {
540
683
  return getColumn(fieldName, f, fn);
541
684
  }
542
685
  }
686
+ exports.getColumnFromField = getColumnFromField;
543
687
  function getColumn(fieldName, f, col) {
544
688
  return col(storageKey(fieldName, f), buildOpts(f));
545
689
  }
@@ -0,0 +1,7 @@
1
+ import { Field, Schema } from "../../schema";
2
+ export declare function randomEmail(domain?: string): string;
3
+ interface Info {
4
+ schema: Schema;
5
+ }
6
+ export declare function getDefaultValue(f: Field, col: string, infos?: Map<string, Info>): any;
7
+ export {};
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDefaultValue = exports.randomEmail = void 0;
4
+ const uuid_1 = require("uuid");
5
+ const schema_1 = require("../../schema");
6
+ const schema_2 = require("../../schema");
7
+ function random() {
8
+ return Math.random().toString(16).substring(2);
9
+ }
10
+ function randomEmail(domain) {
11
+ domain = domain || "email.com";
12
+ return `test+${random()}@${domain}`;
13
+ }
14
+ exports.randomEmail = randomEmail;
15
+ function randomPhoneNumber() {
16
+ return `+1${Math.random().toString(10).substring(2, 11)}`;
17
+ }
18
+ function coinFlip() {
19
+ return Math.floor(Math.random() * 10) >= 5;
20
+ }
21
+ function specialType(typ, col) {
22
+ let list = m.get(typ.dbType);
23
+ if (list?.length) {
24
+ for (const l of list) {
25
+ let regex = [];
26
+ if (Array.isArray(l.regex)) {
27
+ regex = l.regex;
28
+ }
29
+ else {
30
+ regex = [l.regex];
31
+ }
32
+ for (const r of regex) {
33
+ if (r.test(col)) {
34
+ return l.newValue();
35
+ }
36
+ }
37
+ }
38
+ }
39
+ return undefined;
40
+ }
41
+ function getDefaultValue(f, col, infos) {
42
+ if (f.defaultValueOnCreate) {
43
+ // @ts-ignore
44
+ return f.defaultValueOnCreate();
45
+ }
46
+ // half the time, return null for nullable
47
+ if (f.nullable && coinFlip()) {
48
+ return null;
49
+ }
50
+ const specialVal = specialType(f.type, col);
51
+ if (specialVal !== undefined) {
52
+ return specialVal;
53
+ }
54
+ return getValueForType(f.type, f, infos);
55
+ }
56
+ exports.getDefaultValue = getDefaultValue;
57
+ function getValueForType(typ, f, infos) {
58
+ switch (typ.dbType) {
59
+ case schema_1.DBType.UUID:
60
+ return (0, uuid_1.v4)();
61
+ case schema_1.DBType.Boolean:
62
+ return coinFlip();
63
+ case schema_1.DBType.Date:
64
+ return (0, schema_2.DateType)().format(new Date());
65
+ case schema_1.DBType.Time:
66
+ return (0, schema_2.TimeType)().format(new Date());
67
+ case schema_1.DBType.Timetz:
68
+ return (0, schema_2.TimetzType)().format(new Date());
69
+ case schema_1.DBType.Timestamp:
70
+ return (0, schema_2.TimestampType)().format(new Date());
71
+ case schema_1.DBType.Timestamptz:
72
+ return (0, schema_2.TimestamptzType)().format(new Date());
73
+ case schema_1.DBType.String:
74
+ return random();
75
+ case schema_1.DBType.Int:
76
+ return Math.floor(Math.random() * 100000000);
77
+ case schema_1.DBType.Float:
78
+ return Math.random() * 100000000;
79
+ case schema_1.DBType.Enum:
80
+ case schema_1.DBType.StringEnum:
81
+ if (typ.values) {
82
+ const idx = Math.floor(Math.random() * typ.values.length);
83
+ return typ.values[idx];
84
+ }
85
+ if (typ.enumMap) {
86
+ const vals = Object.values(typ.enumMap);
87
+ const idx = Math.floor(Math.random() * vals.length);
88
+ return vals[idx];
89
+ }
90
+ if (f.foreignKey) {
91
+ const schema = f.foreignKey.schema;
92
+ const col = f.foreignKey.column;
93
+ if (!infos) {
94
+ throw new Error(`infos required for enum with foreignKey`);
95
+ }
96
+ const info = infos.get(schema);
97
+ if (!info) {
98
+ throw new Error(`couldn't load data for schema ${schema}`);
99
+ }
100
+ if (!info.schema.dbRows) {
101
+ throw new Error(`no dbRows for schema ${schema}`);
102
+ }
103
+ const idx = Math.floor(Math.random() * info.schema.dbRows.length);
104
+ return info.schema.dbRows[idx][col];
105
+ }
106
+ throw new Error("TODO: enum without values not currently supported");
107
+ case schema_1.DBType.IntEnum:
108
+ const vals = Object.values(typ.intEnumMap);
109
+ const idx = Math.floor(Math.random() * vals.length);
110
+ return vals[idx];
111
+ case schema_1.DBType.BigInt:
112
+ return BigInt(Math.floor(Math.random() * 100000000));
113
+ case schema_1.DBType.JSONB:
114
+ // type as list
115
+ if (typ.listElemType?.dbType === schema_1.DBType.JSONB) {
116
+ const values = [];
117
+ for (let i = 0; i < 10; i++) {
118
+ values.push(getValueForType(typ.listElemType, f, infos));
119
+ }
120
+ if (!f.format) {
121
+ throw new Error("invalid format");
122
+ }
123
+ return f.format(values);
124
+ }
125
+ return (0, schema_2.JSONBType)().format({});
126
+ case schema_1.DBType.JSON:
127
+ return (0, schema_2.JSONType)().format({});
128
+ case schema_1.DBType.List:
129
+ // just do 10
130
+ const values = [];
131
+ for (let i = 0; i < 10; i++) {
132
+ values.push(getValueForType(f.type.listElemType, f.__getElemField(), infos));
133
+ }
134
+ if (!f.format) {
135
+ throw new Error("invalid format");
136
+ }
137
+ return f.format(values);
138
+ default:
139
+ throw new Error(`unsupported type ${typ.dbType}`);
140
+ }
141
+ }
142
+ const emailType = {
143
+ dbType: schema_1.DBType.String,
144
+ newValue: () => {
145
+ return (0, schema_2.StringType)().format(randomEmail().toLowerCase());
146
+ },
147
+ regex: /^email(_address)|_email$/,
148
+ };
149
+ const phoneType = {
150
+ dbType: schema_1.DBType.String,
151
+ newValue: () => {
152
+ return randomPhoneNumber();
153
+ },
154
+ regex: /^phone(_number)?|_phone$|_phone_number$/,
155
+ };
156
+ const passwordType = {
157
+ dbType: schema_1.DBType.String,
158
+ newValue: () => {
159
+ // we don't use password type because when we're generating so many rows, it's too slow...
160
+ return random();
161
+ },
162
+ regex: /^password/,
163
+ };
164
+ const firstNames = [
165
+ "Daenerys",
166
+ "Jon",
167
+ "Arya",
168
+ "Sansa",
169
+ "Eddard",
170
+ "Khal",
171
+ "Robb",
172
+ "Joffrey",
173
+ "Ramsay",
174
+ "Cersei",
175
+ "Bolton",
176
+ "Oberyn",
177
+ "Jojen",
178
+ "Petyr",
179
+ "Brienne",
180
+ "Ygritte",
181
+ "Missandei",
182
+ "Shae",
183
+ "Sandor",
184
+ "Theon",
185
+ "Catelyn",
186
+ "Gilly",
187
+ "Samwell",
188
+ "Jaime",
189
+ "Stannis",
190
+ "Tyene",
191
+ "Obara",
192
+ "Nymeria",
193
+ "Elia",
194
+ "Ellaria",
195
+ "Myrcella",
196
+ "Hodor",
197
+ "Osha",
198
+ "Meera",
199
+ "Davos",
200
+ "Gendry",
201
+ ];
202
+ const lastNames = [
203
+ "Stark",
204
+ "Targaryen",
205
+ "Lannister",
206
+ "Drogo",
207
+ "Baratheon",
208
+ "Reed",
209
+ "Martell",
210
+ "Tyrell",
211
+ "Clegane",
212
+ "Baelish",
213
+ "Greyjoy",
214
+ "Tarly",
215
+ "Sand",
216
+ "Snow",
217
+ "Bolton",
218
+ "Frey",
219
+ "Tarth",
220
+ "Payne",
221
+ "Seaworth",
222
+ ];
223
+ const firstNameType = {
224
+ dbType: schema_1.DBType.String,
225
+ newValue: () => {
226
+ let idx = Math.floor(firstNames.length * Math.random());
227
+ return firstNames[idx];
228
+ },
229
+ regex: /^first_?(name)?/,
230
+ };
231
+ const lastNameType = {
232
+ dbType: schema_1.DBType.String,
233
+ newValue: () => {
234
+ let idx = Math.floor(lastNames.length * Math.random());
235
+ return lastNames[idx];
236
+ },
237
+ regex: /^last_?(name)?/,
238
+ };
239
+ let types = [
240
+ phoneType,
241
+ emailType,
242
+ passwordType,
243
+ firstNameType,
244
+ lastNameType,
245
+ ];
246
+ let m = new Map();
247
+ for (const type of types) {
248
+ let list = m.get(type.dbType) || [];
249
+ list.push(type);
250
+ m.set(type.dbType, list);
251
+ }
@@ -18,7 +18,8 @@ export declare enum queryType {
18
18
  UPDATE = 2,
19
19
  BEGIN = 3,
20
20
  COMMIT = 4,
21
- ROLLBACK = 5
21
+ ROLLBACK = 5,
22
+ DELETE = 6
22
23
  }
23
24
  export interface queryStructure {
24
25
  tableName?: string;
@@ -32,11 +33,14 @@ interface internalQueryStructure extends queryStructure {
32
33
  suffix?: string;
33
34
  setClause?: string;
34
35
  }
36
+ /**
37
+ * @deprecated
38
+ */
35
39
  export declare class QueryRecorder {
36
40
  private static queries;
37
41
  private static ids;
38
42
  private static data;
39
- private static getQueryStructure;
43
+ static getQueryStructure(query: any): internalQueryStructure | null;
40
44
  private static recordQuery;
41
45
  static newID(): ID;
42
46
  static getCurrentIDs(): ID[];
@@ -46,8 +50,16 @@ export declare class QueryRecorder {
46
50
  static clear(): void;
47
51
  static clearQueries(): void;
48
52
  static getCurrentQueries(): queryOptions[];
49
- static validateQueryStructuresFromLogs(ml: MockLogs, expected: queryStructure[], skipSelect?: boolean): void;
50
- private static validateQuryStructuresImpl;
53
+ /**
54
+ * @deprecated will keep this since it's just using ml.logs
55
+ * which we still want around (I think) but we should eventually
56
+ * probably stop using this
57
+ */
58
+ static validateQueryStructuresFromLogs(ml: MockLogs, expected: queryStructure[], opts?: {
59
+ skipSelect?: boolean;
60
+ flagBeginCommit?: boolean;
61
+ }): void;
62
+ private static validateQueryStructuresImpl;
51
63
  static mockPool(pool: typeof Pool): void;
52
64
  }
53
65
  export {};