@snowtop/ent 0.1.0-alpha13 → 0.1.0-alpha131

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 (173) hide show
  1. package/action/action.d.ts +33 -29
  2. package/action/action.js +22 -7
  3. package/action/executor.d.ts +3 -3
  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 +32 -15
  10. package/action/orchestrator.js +249 -53
  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 +61 -37
  18. package/core/base.js +7 -1
  19. package/core/clause.d.ts +85 -40
  20. package/core/clause.js +375 -64
  21. package/core/config.d.ts +12 -1
  22. package/core/config.js +7 -1
  23. package/core/const.d.ts +3 -0
  24. package/core/const.js +6 -0
  25. package/core/context.d.ts +6 -4
  26. package/core/context.js +20 -2
  27. package/core/convert.d.ts +1 -1
  28. package/core/date.js +1 -5
  29. package/core/db.d.ts +11 -8
  30. package/core/db.js +20 -8
  31. package/core/ent.d.ts +86 -30
  32. package/core/ent.js +626 -197
  33. package/core/global_schema.d.ts +7 -0
  34. package/core/global_schema.js +51 -0
  35. package/core/loaders/assoc_count_loader.d.ts +3 -2
  36. package/core/loaders/assoc_count_loader.js +10 -2
  37. package/core/loaders/assoc_edge_loader.d.ts +2 -2
  38. package/core/loaders/assoc_edge_loader.js +8 -11
  39. package/core/loaders/index.d.ts +1 -1
  40. package/core/loaders/index.js +1 -3
  41. package/core/loaders/index_loader.d.ts +3 -3
  42. package/core/loaders/loader.d.ts +2 -2
  43. package/core/loaders/loader.js +5 -5
  44. package/core/loaders/object_loader.d.ts +32 -11
  45. package/core/loaders/object_loader.js +225 -78
  46. package/core/loaders/query_loader.d.ts +7 -13
  47. package/core/loaders/query_loader.js +52 -11
  48. package/core/loaders/raw_count_loader.d.ts +2 -2
  49. package/core/loaders/raw_count_loader.js +5 -1
  50. package/core/logger.d.ts +1 -1
  51. package/core/logger.js +1 -0
  52. package/core/privacy.d.ts +25 -24
  53. package/core/privacy.js +21 -25
  54. package/core/query/assoc_query.d.ts +7 -6
  55. package/core/query/assoc_query.js +9 -1
  56. package/core/query/custom_clause_query.d.ts +27 -0
  57. package/core/query/custom_clause_query.js +84 -0
  58. package/core/query/custom_query.d.ts +20 -5
  59. package/core/query/custom_query.js +87 -12
  60. package/core/query/index.d.ts +1 -0
  61. package/core/query/index.js +3 -1
  62. package/core/query/query.d.ts +8 -4
  63. package/core/query/query.js +101 -53
  64. package/core/query/shared_assoc_test.d.ts +2 -1
  65. package/core/query/shared_assoc_test.js +35 -45
  66. package/core/query/shared_test.d.ts +8 -1
  67. package/core/query/shared_test.js +470 -236
  68. package/core/viewer.d.ts +3 -3
  69. package/core/viewer.js +1 -1
  70. package/graphql/graphql.d.ts +51 -19
  71. package/graphql/graphql.js +160 -136
  72. package/graphql/graphql_field_helpers.d.ts +7 -1
  73. package/graphql/graphql_field_helpers.js +21 -1
  74. package/graphql/index.d.ts +2 -2
  75. package/graphql/index.js +3 -5
  76. package/graphql/query/connection_type.d.ts +9 -9
  77. package/graphql/query/edge_connection.d.ts +9 -9
  78. package/graphql/query/page_info.d.ts +1 -1
  79. package/graphql/query/shared_assoc_test.js +1 -1
  80. package/graphql/query/shared_edge_connection.js +1 -19
  81. package/graphql/scalars/orderby_direction.d.ts +2 -0
  82. package/graphql/scalars/orderby_direction.js +15 -0
  83. package/imports/dataz/example1/_auth.js +128 -47
  84. package/imports/dataz/example1/_viewer.js +87 -39
  85. package/imports/index.d.ts +6 -1
  86. package/imports/index.js +19 -4
  87. package/index.d.ts +13 -5
  88. package/index.js +21 -7
  89. package/package.json +17 -17
  90. package/parse_schema/parse.d.ts +31 -9
  91. package/parse_schema/parse.js +155 -13
  92. package/schema/base_schema.d.ts +7 -3
  93. package/schema/base_schema.js +10 -0
  94. package/schema/field.d.ts +78 -21
  95. package/schema/field.js +231 -71
  96. package/schema/index.d.ts +2 -2
  97. package/schema/index.js +5 -1
  98. package/schema/json_field.d.ts +16 -4
  99. package/schema/json_field.js +32 -2
  100. package/schema/schema.d.ts +89 -19
  101. package/schema/schema.js +11 -13
  102. package/schema/struct_field.d.ts +15 -3
  103. package/schema/struct_field.js +117 -22
  104. package/schema/union_field.d.ts +1 -1
  105. package/scripts/custom_compiler.js +10 -6
  106. package/scripts/custom_graphql.js +128 -31
  107. package/scripts/migrate_v0.1.js +36 -0
  108. package/scripts/move_types.js +120 -0
  109. package/scripts/read_schema.js +20 -5
  110. package/testutils/action/complex_schemas.d.ts +69 -0
  111. package/testutils/action/complex_schemas.js +398 -0
  112. package/testutils/builder.d.ts +41 -47
  113. package/testutils/builder.js +76 -49
  114. package/testutils/db/fixture.d.ts +10 -0
  115. package/testutils/db/fixture.js +26 -0
  116. package/testutils/db/{test_db.d.ts → temp_db.d.ts} +24 -8
  117. package/testutils/db/{test_db.js → temp_db.js} +182 -45
  118. package/testutils/db/value.d.ts +7 -0
  119. package/testutils/db/value.js +251 -0
  120. package/testutils/db_mock.d.ts +16 -4
  121. package/testutils/db_mock.js +52 -7
  122. package/testutils/db_time_zone.d.ts +4 -0
  123. package/testutils/db_time_zone.js +41 -0
  124. package/testutils/ent-graphql-tests/index.d.ts +7 -1
  125. package/testutils/ent-graphql-tests/index.js +52 -23
  126. package/testutils/fake_comms.js +1 -1
  127. package/testutils/fake_data/const.d.ts +2 -1
  128. package/testutils/fake_data/const.js +3 -0
  129. package/testutils/fake_data/fake_contact.d.ts +7 -3
  130. package/testutils/fake_data/fake_contact.js +13 -7
  131. package/testutils/fake_data/fake_event.d.ts +4 -1
  132. package/testutils/fake_data/fake_event.js +7 -6
  133. package/testutils/fake_data/fake_tag.d.ts +36 -0
  134. package/testutils/fake_data/fake_tag.js +89 -0
  135. package/testutils/fake_data/fake_user.d.ts +8 -5
  136. package/testutils/fake_data/fake_user.js +16 -15
  137. package/testutils/fake_data/index.js +5 -1
  138. package/testutils/fake_data/internal.d.ts +2 -0
  139. package/testutils/fake_data/internal.js +7 -1
  140. package/testutils/fake_data/tag_query.d.ts +13 -0
  141. package/testutils/fake_data/tag_query.js +43 -0
  142. package/testutils/fake_data/test_helpers.d.ts +11 -4
  143. package/testutils/fake_data/test_helpers.js +28 -12
  144. package/testutils/fake_data/user_query.d.ts +13 -6
  145. package/testutils/fake_data/user_query.js +54 -22
  146. package/testutils/fake_log.d.ts +3 -3
  147. package/testutils/fake_log.js +1 -1
  148. package/testutils/parse_sql.d.ts +6 -0
  149. package/testutils/parse_sql.js +16 -2
  150. package/testutils/test_edge_global_schema.d.ts +15 -0
  151. package/testutils/test_edge_global_schema.js +62 -0
  152. package/testutils/write.d.ts +2 -2
  153. package/testutils/write.js +33 -7
  154. package/tsc/ast.d.ts +25 -2
  155. package/tsc/ast.js +141 -17
  156. package/tsc/compilerOptions.js +5 -1
  157. package/tsc/move_generated.d.ts +1 -0
  158. package/tsc/move_generated.js +164 -0
  159. package/tsc/transform.d.ts +22 -0
  160. package/tsc/transform.js +181 -0
  161. package/tsc/transform_action.d.ts +22 -0
  162. package/tsc/transform_action.js +183 -0
  163. package/tsc/transform_ent.d.ts +17 -0
  164. package/tsc/transform_ent.js +60 -0
  165. package/tsc/transform_schema.d.ts +27 -0
  166. package/{scripts → tsc}/transform_schema.js +146 -117
  167. package/graphql/enums.d.ts +0 -3
  168. package/graphql/enums.js +0 -25
  169. package/scripts/move_generated.js +0 -142
  170. package/scripts/transform_code.js +0 -113
  171. package/scripts/transform_schema.d.ts +0 -1
  172. /package/scripts/{move_generated.d.ts → migrate_v0.1.d.ts} +0 -0
  173. /package/scripts/{transform_code.d.ts → move_types.d.ts} +0 -0
@@ -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,29 +364,18 @@ 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
381
  async beforeAll(setupConnString = true) {
@@ -349,12 +391,17 @@ class TempDB {
349
391
  this.db = randomDB();
350
392
  await this.client.query(`CREATE DATABASE ${this.db}`);
351
393
  if (setupConnString) {
394
+ delete process.env.DB_CONNECTION_STRING;
395
+ let connStr = "";
352
396
  if (user && password) {
353
- process.env.DB_CONNECTION_STRING = `postgres://${user}:${password}@localhost:5432/${this.db}`;
397
+ connStr = `postgres://${user}:${password}@localhost:5432/${this.db}`;
354
398
  }
355
399
  else {
356
- process.env.DB_CONNECTION_STRING = `postgres://localhost/${this.db}?`;
400
+ connStr = `postgres://localhost/${this.db}?`;
357
401
  }
402
+ db_1.default.initDB({
403
+ connectionString: connStr,
404
+ });
358
405
  }
359
406
  else {
360
407
  // will probably be setup via loadConfig
@@ -375,12 +422,35 @@ class TempDB {
375
422
  const filePath = process.env.DB_CONNECTION_STRING.substr(10);
376
423
  this.sqlite = (0, better_sqlite3_1.default)(filePath);
377
424
  }
378
- for (const [_, table] of this.tables) {
379
- if (this.dialect == db_1.Dialect.Postgres) {
380
- await this.dbClient.query(table.create());
425
+ if (this.setTables) {
426
+ let tables = [];
427
+ if (typeof this.setTables === "function") {
428
+ tables = this.setTables();
381
429
  }
382
430
  else {
383
- 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
+ }
384
454
  }
385
455
  }
386
456
  }
@@ -393,6 +463,9 @@ class TempDB {
393
463
  async afterAll() {
394
464
  if (this.dialect === db_1.Dialect.SQLite) {
395
465
  this.sqlite.close();
466
+ if (!this.sqlite.memory) {
467
+ fs.rmSync(this.getSqliteClient().name);
468
+ }
396
469
  return;
397
470
  }
398
471
  // end our connection to db
@@ -431,12 +504,7 @@ class TempDB {
431
504
  if (this.tables.has(table.name)) {
432
505
  throw new Error(`table with name ${table.name} already exists`);
433
506
  }
434
- if (this.dialect === db_1.Dialect.Postgres) {
435
- await this.dbClient.query(table.create());
436
- }
437
- else {
438
- this.sqlite.exec(table.create());
439
- }
507
+ await this.createImpl(table);
440
508
  this.tables.set(table.name, table);
441
509
  }
442
510
  }
@@ -448,18 +516,26 @@ function assoc_edge_config_table() {
448
516
  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"));
449
517
  }
450
518
  exports.assoc_edge_config_table = assoc_edge_config_table;
451
- function assoc_edge_table(name) {
452
- return table(name, uuid("id1"), text("id1_type"),
519
+ // if global flag is true, add any column from testEdgeGlobalSchema
520
+ // up to caller to set/clear that as needed
521
+ function assoc_edge_table(name, global) {
522
+ const t = table(name, uuid("id1"), text("id1_type"),
453
523
  // same as in assoc_edge_config_table
454
524
  text("edge_type"), uuid("id2"), text("id2_type"), timestamptz("time"), text("data", { nullable: true }), primaryKey(`${name}_pkey`, ["id1", "id2", "edge_type"]));
525
+ if (global) {
526
+ for (const k in test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields) {
527
+ const col = getColumnFromField(k, test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields[k], db_1.Dialect.Postgres);
528
+ t.columns.push(col);
529
+ }
530
+ }
531
+ return t;
455
532
  }
456
533
  exports.assoc_edge_table = assoc_edge_table;
457
534
  function setupSqlite(connString, tables, opts) {
458
- let tdb;
535
+ let tdb = new TempDB(db_1.Dialect.SQLite, tables);
459
536
  beforeAll(async () => {
460
537
  process.env.DB_CONNECTION_STRING = connString;
461
538
  (0, config_1.loadConfig)();
462
- tdb = new TempDB(db_1.Dialect.SQLite, tables());
463
539
  await tdb.beforeAll();
464
540
  const conn = db_1.default.getInstance().getConnection();
465
541
  expect(conn.db.memory).toBe(false);
@@ -467,7 +543,7 @@ function setupSqlite(connString, tables, opts) {
467
543
  if (!opts?.disableDeleteAfterEachTest) {
468
544
  afterEach(async () => {
469
545
  const client = await db_1.default.getInstance().getNewClient();
470
- for (const [key, _] of tdb.getTables()) {
546
+ for (const [key, _] of tdb.__getTables()) {
471
547
  const query = `delete from ${key}`;
472
548
  if (isSyncClient(client))
473
549
  if (client.execSync) {
@@ -481,17 +557,77 @@ function setupSqlite(connString, tables, opts) {
481
557
  }
482
558
  afterAll(async () => {
483
559
  await tdb.afterAll();
484
- fs.rmSync(tdb.getSqliteClient().name);
560
+ delete process.env.DB_CONNECTION_STRING;
485
561
  });
562
+ return tdb;
486
563
  }
487
564
  exports.setupSqlite = setupSqlite;
565
+ function setupPostgres(tables, opts) {
566
+ let tdb;
567
+ beforeAll(async () => {
568
+ tdb = new TempDB(db_1.Dialect.Postgres, tables());
569
+ await tdb.beforeAll();
570
+ });
571
+ // TODO need to fix this implementation...
572
+ if (!opts?.disableDeleteAfterEachTest) {
573
+ afterEach(async () => {
574
+ const client = await db_1.default.getInstance().getNewClient();
575
+ for (const [key, _] of tdb.__getTables()) {
576
+ const query = `delete from ${key}`;
577
+ await client.exec(query);
578
+ }
579
+ client.release();
580
+ });
581
+ }
582
+ afterAll(async () => {
583
+ await tdb.afterAll();
584
+ });
585
+ }
586
+ exports.setupPostgres = setupPostgres;
587
+ async function doSQLiteTestFromSchemas(schemas, doTest, db) {
588
+ const connString = `sqlite:///${db || randomDB()}.db`;
589
+ const tables = schemas.map((schema) => getSchemaTable(schema, db_1.Dialect.SQLite));
590
+ let tdb = new TempDB(db_1.Dialect.SQLite, tables);
591
+ process.env.DB_CONNECTION_STRING = connString;
592
+ (0, config_1.loadConfig)();
593
+ await tdb.beforeAll();
594
+ await doTest();
595
+ await tdb.afterAll();
596
+ delete process.env.DB_CONNECTION_STRING;
597
+ return tdb;
598
+ }
599
+ exports.doSQLiteTestFromSchemas = doSQLiteTestFromSchemas;
488
600
  function getSchemaTable(schema, dialect) {
489
601
  const fields = (0, schema_1.getFields)(schema);
490
- const columns = [];
602
+ const items = [];
491
603
  for (const [fieldName, field] of fields) {
492
- columns.push(getColumnFromField(fieldName, field, dialect));
604
+ items.push(getColumnFromField(fieldName, field, dialect));
605
+ }
606
+ if (schema.constraints) {
607
+ for (const constraint of schema.constraints) {
608
+ switch (constraint.type) {
609
+ case schema_1.ConstraintType.PrimaryKey:
610
+ items.push(primaryKey(constraint.name, constraint.columns));
611
+ break;
612
+ case schema_1.ConstraintType.ForeignKey:
613
+ if (!constraint.fkey) {
614
+ throw new Error(`need 'fkey' field for foreign key constraint`);
615
+ }
616
+ items.push(foreignKey(constraint.name, constraint.columns, {
617
+ table: constraint.fkey.tableName,
618
+ cols: constraint.fkey.columns,
619
+ }));
620
+ break;
621
+ case schema_1.ConstraintType.Check:
622
+ if (!constraint.condition) {
623
+ throw new Error(`need 'condition' field for check constraint`);
624
+ }
625
+ items.push(check(constraint.name, constraint.condition));
626
+ break;
627
+ }
628
+ }
493
629
  }
494
- return table((0, builder_1.getTableName)(schema), ...columns);
630
+ return table((0, builder_1.getTableName)(schema), ...items);
495
631
  }
496
632
  exports.getSchemaTable = getSchemaTable;
497
633
  function getColumnForDbType(t, dialect) {
@@ -549,6 +685,7 @@ function getColumnFromField(fieldName, f, dialect) {
549
685
  return getColumn(fieldName, f, fn);
550
686
  }
551
687
  }
688
+ exports.getColumnFromField = getColumnFromField;
552
689
  function getColumn(fieldName, f, col) {
553
690
  return col(storageKey(fieldName, f), buildOpts(f));
554
691
  }
@@ -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 {};