@snowtop/ent 0.1.0-alpha10 → 0.1.0-alpha101

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 (158) hide show
  1. package/action/action.d.ts +37 -31
  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 +40 -16
  10. package/action/orchestrator.js +230 -62
  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 +49 -26
  18. package/core/base.js +7 -1
  19. package/core/clause.d.ts +88 -7
  20. package/core/clause.js +355 -63
  21. package/core/config.d.ts +12 -1
  22. package/core/config.js +7 -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 +11 -8
  28. package/core/db.js +20 -8
  29. package/core/ent.d.ts +81 -25
  30. package/core/ent.js +636 -193
  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 +2 -2
  34. package/core/loaders/assoc_edge_loader.js +8 -11
  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/loader.js +5 -5
  39. package/core/loaders/object_loader.d.ts +6 -5
  40. package/core/loaders/object_loader.js +67 -59
  41. package/core/loaders/query_loader.d.ts +6 -12
  42. package/core/loaders/query_loader.js +52 -11
  43. package/core/loaders/raw_count_loader.d.ts +2 -2
  44. package/core/loaders/raw_count_loader.js +5 -1
  45. package/core/logger.d.ts +1 -1
  46. package/core/logger.js +1 -0
  47. package/core/privacy.d.ts +25 -24
  48. package/core/privacy.js +21 -25
  49. package/core/query/assoc_query.d.ts +7 -6
  50. package/core/query/assoc_query.js +9 -1
  51. package/core/query/custom_clause_query.d.ts +26 -0
  52. package/core/query/custom_clause_query.js +78 -0
  53. package/core/query/custom_query.d.ts +20 -5
  54. package/core/query/custom_query.js +87 -12
  55. package/core/query/index.d.ts +1 -0
  56. package/core/query/index.js +3 -1
  57. package/core/query/query.d.ts +8 -4
  58. package/core/query/query.js +101 -53
  59. package/core/query/shared_assoc_test.d.ts +2 -1
  60. package/core/query/shared_assoc_test.js +35 -45
  61. package/core/query/shared_test.d.ts +8 -1
  62. package/core/query/shared_test.js +469 -236
  63. package/core/viewer.d.ts +3 -3
  64. package/core/viewer.js +1 -1
  65. package/graphql/graphql.d.ts +14 -7
  66. package/graphql/graphql.js +23 -7
  67. package/graphql/index.d.ts +0 -1
  68. package/graphql/index.js +1 -4
  69. package/graphql/query/connection_type.d.ts +9 -9
  70. package/graphql/query/edge_connection.d.ts +9 -9
  71. package/graphql/query/page_info.d.ts +1 -1
  72. package/graphql/query/shared_assoc_test.js +1 -1
  73. package/graphql/query/shared_edge_connection.js +1 -19
  74. package/imports/index.d.ts +6 -1
  75. package/imports/index.js +19 -4
  76. package/index.d.ts +12 -5
  77. package/index.js +20 -7
  78. package/package.json +17 -16
  79. package/parse_schema/parse.d.ts +29 -9
  80. package/parse_schema/parse.js +118 -11
  81. package/schema/base_schema.d.ts +5 -3
  82. package/schema/base_schema.js +5 -0
  83. package/schema/field.d.ts +74 -20
  84. package/schema/field.js +174 -69
  85. package/schema/index.d.ts +2 -2
  86. package/schema/index.js +5 -1
  87. package/schema/json_field.d.ts +13 -1
  88. package/schema/json_field.js +28 -1
  89. package/schema/schema.d.ts +81 -18
  90. package/schema/schema.js +24 -17
  91. package/schema/struct_field.d.ts +11 -1
  92. package/schema/struct_field.js +57 -21
  93. package/scripts/custom_compiler.js +10 -6
  94. package/scripts/custom_graphql.js +117 -30
  95. package/scripts/{transform_code.d.ts → migrate_v0.1.d.ts} +0 -0
  96. package/scripts/migrate_v0.1.js +36 -0
  97. package/scripts/{transform_schema.d.ts → move_types.d.ts} +0 -0
  98. package/scripts/move_types.js +117 -0
  99. package/scripts/read_schema.js +20 -5
  100. package/testutils/action/complex_schemas.d.ts +69 -0
  101. package/testutils/action/complex_schemas.js +398 -0
  102. package/testutils/builder.d.ts +46 -47
  103. package/testutils/builder.js +108 -65
  104. package/testutils/db/fixture.d.ts +10 -0
  105. package/testutils/db/fixture.js +26 -0
  106. package/testutils/db/{test_db.d.ts → temp_db.d.ts} +24 -8
  107. package/testutils/db/{test_db.js → temp_db.js} +179 -44
  108. package/testutils/db/value.d.ts +7 -0
  109. package/testutils/db/value.js +251 -0
  110. package/testutils/db_mock.d.ts +16 -4
  111. package/testutils/db_mock.js +51 -6
  112. package/testutils/db_time_zone.d.ts +4 -0
  113. package/testutils/db_time_zone.js +41 -0
  114. package/testutils/ent-graphql-tests/index.d.ts +7 -1
  115. package/testutils/ent-graphql-tests/index.js +27 -8
  116. package/testutils/fake_data/const.d.ts +2 -1
  117. package/testutils/fake_data/const.js +3 -0
  118. package/testutils/fake_data/fake_contact.d.ts +7 -3
  119. package/testutils/fake_data/fake_contact.js +15 -8
  120. package/testutils/fake_data/fake_event.d.ts +5 -2
  121. package/testutils/fake_data/fake_event.js +9 -7
  122. package/testutils/fake_data/fake_tag.d.ts +36 -0
  123. package/testutils/fake_data/fake_tag.js +89 -0
  124. package/testutils/fake_data/fake_user.d.ts +7 -4
  125. package/testutils/fake_data/fake_user.js +18 -16
  126. package/testutils/fake_data/index.js +5 -1
  127. package/testutils/fake_data/internal.d.ts +2 -0
  128. package/testutils/fake_data/internal.js +7 -1
  129. package/testutils/fake_data/tag_query.d.ts +13 -0
  130. package/testutils/fake_data/tag_query.js +43 -0
  131. package/testutils/fake_data/test_helpers.d.ts +11 -4
  132. package/testutils/fake_data/test_helpers.js +28 -12
  133. package/testutils/fake_data/user_query.d.ts +13 -6
  134. package/testutils/fake_data/user_query.js +54 -22
  135. package/testutils/fake_log.d.ts +3 -3
  136. package/testutils/parse_sql.d.ts +6 -0
  137. package/testutils/parse_sql.js +16 -2
  138. package/testutils/test_edge_global_schema.d.ts +15 -0
  139. package/testutils/test_edge_global_schema.js +62 -0
  140. package/testutils/write.d.ts +2 -2
  141. package/testutils/write.js +33 -7
  142. package/tsc/ast.d.ts +26 -2
  143. package/tsc/ast.js +163 -17
  144. package/tsc/compilerOptions.d.ts +2 -1
  145. package/tsc/compilerOptions.js +11 -2
  146. package/tsc/move_generated.d.ts +1 -0
  147. package/tsc/move_generated.js +164 -0
  148. package/tsc/transform.d.ts +22 -0
  149. package/tsc/transform.js +181 -0
  150. package/tsc/transform_action.d.ts +22 -0
  151. package/tsc/transform_action.js +183 -0
  152. package/tsc/transform_ent.d.ts +17 -0
  153. package/tsc/transform_ent.js +59 -0
  154. package/tsc/transform_schema.d.ts +27 -0
  155. package/{scripts → tsc}/transform_schema.js +145 -119
  156. package/graphql/enums.d.ts +0 -3
  157. package/graphql/enums.js +0 -25
  158. package/scripts/transform_code.js +0 -114
@@ -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
  }
@@ -431,12 +501,7 @@ class TempDB {
431
501
  if (this.tables.has(table.name)) {
432
502
  throw new Error(`table with name ${table.name} already exists`);
433
503
  }
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
- }
504
+ await this.createImpl(table);
440
505
  this.tables.set(table.name, table);
441
506
  }
442
507
  }
@@ -448,18 +513,26 @@ function assoc_edge_config_table() {
448
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"));
449
514
  }
450
515
  exports.assoc_edge_config_table = assoc_edge_config_table;
451
- function assoc_edge_table(name) {
452
- 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"),
453
520
  // same as in assoc_edge_config_table
454
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;
455
529
  }
456
530
  exports.assoc_edge_table = assoc_edge_table;
457
531
  function setupSqlite(connString, tables, opts) {
458
- let tdb;
532
+ let tdb = new TempDB(db_1.Dialect.SQLite, tables);
459
533
  beforeAll(async () => {
460
534
  process.env.DB_CONNECTION_STRING = connString;
461
535
  (0, config_1.loadConfig)();
462
- tdb = new TempDB(db_1.Dialect.SQLite, tables());
463
536
  await tdb.beforeAll();
464
537
  const conn = db_1.default.getInstance().getConnection();
465
538
  expect(conn.db.memory).toBe(false);
@@ -467,7 +540,7 @@ function setupSqlite(connString, tables, opts) {
467
540
  if (!opts?.disableDeleteAfterEachTest) {
468
541
  afterEach(async () => {
469
542
  const client = await db_1.default.getInstance().getNewClient();
470
- for (const [key, _] of tdb.getTables()) {
543
+ for (const [key, _] of tdb.__getTables()) {
471
544
  const query = `delete from ${key}`;
472
545
  if (isSyncClient(client))
473
546
  if (client.execSync) {
@@ -482,16 +555,77 @@ function setupSqlite(connString, tables, opts) {
482
555
  afterAll(async () => {
483
556
  await tdb.afterAll();
484
557
  fs.rmSync(tdb.getSqliteClient().name);
558
+ delete process.env.DB_CONNECTION_STRING;
485
559
  });
560
+ return tdb;
486
561
  }
487
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;
488
598
  function getSchemaTable(schema, dialect) {
489
599
  const fields = (0, schema_1.getFields)(schema);
490
- const columns = [];
600
+ const items = [];
491
601
  for (const [fieldName, field] of fields) {
492
- 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
+ }
493
627
  }
494
- return table((0, builder_1.getTableName)(schema), ...columns);
628
+ return table((0, builder_1.getTableName)(schema), ...items);
495
629
  }
496
630
  exports.getSchemaTable = getSchemaTable;
497
631
  function getColumnForDbType(t, dialect) {
@@ -549,6 +683,7 @@ function getColumnFromField(fieldName, f, dialect) {
549
683
  return getColumn(fieldName, f, fn);
550
684
  }
551
685
  }
686
+ exports.getColumnFromField = getColumnFromField;
552
687
  function getColumn(fieldName, f, col) {
553
688
  return col(storageKey(fieldName, f), buildOpts(f));
554
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 {};