@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.
- package/action/action.d.ts +38 -30
- package/action/action.js +22 -7
- package/action/executor.d.ts +4 -4
- package/action/executor.js +8 -3
- package/action/experimental_action.d.ts +32 -22
- package/action/experimental_action.js +35 -9
- package/action/index.d.ts +2 -0
- package/action/index.js +7 -1
- package/action/orchestrator.d.ts +48 -16
- package/action/orchestrator.js +343 -81
- package/action/privacy.d.ts +2 -2
- package/action/relative_value.d.ts +47 -0
- package/action/relative_value.js +125 -0
- package/action/transaction.d.ts +10 -0
- package/action/transaction.js +23 -0
- package/auth/auth.d.ts +1 -1
- package/core/base.d.ts +54 -27
- package/core/base.js +23 -1
- package/core/clause.d.ts +105 -3
- package/core/clause.js +563 -30
- package/core/config.d.ts +30 -1
- package/core/config.js +24 -1
- package/core/context.d.ts +5 -3
- package/core/context.js +20 -2
- package/core/convert.d.ts +1 -1
- package/core/date.js +1 -5
- package/core/db.d.ts +14 -11
- package/core/db.js +22 -8
- package/core/ent.d.ts +82 -28
- package/core/ent.js +692 -202
- package/core/loaders/assoc_count_loader.d.ts +3 -2
- package/core/loaders/assoc_count_loader.js +10 -2
- package/core/loaders/assoc_edge_loader.d.ts +3 -3
- package/core/loaders/assoc_edge_loader.js +13 -15
- package/core/loaders/index.d.ts +1 -1
- package/core/loaders/index.js +1 -3
- package/core/loaders/index_loader.d.ts +2 -2
- package/core/loaders/index_loader.js +1 -0
- package/core/loaders/loader.js +5 -5
- package/core/loaders/object_loader.d.ts +13 -7
- package/core/loaders/object_loader.js +95 -32
- package/core/loaders/query_loader.d.ts +6 -12
- package/core/loaders/query_loader.js +52 -11
- package/core/loaders/raw_count_loader.d.ts +2 -2
- package/core/loaders/raw_count_loader.js +5 -1
- package/core/logger.d.ts +1 -1
- package/core/logger.js +1 -0
- package/core/privacy.d.ts +26 -25
- package/core/privacy.js +23 -24
- package/core/query/assoc_query.d.ts +7 -6
- package/core/query/assoc_query.js +9 -1
- package/core/query/custom_clause_query.d.ts +26 -0
- package/core/query/custom_clause_query.js +78 -0
- package/core/query/custom_query.d.ts +20 -5
- package/core/query/custom_query.js +87 -12
- package/core/query/index.d.ts +1 -0
- package/core/query/index.js +3 -1
- package/core/query/query.d.ts +8 -4
- package/core/query/query.js +101 -53
- package/core/query/shared_assoc_test.d.ts +2 -1
- package/core/query/shared_assoc_test.js +35 -45
- package/core/query/shared_test.d.ts +8 -1
- package/core/query/shared_test.js +469 -236
- package/core/viewer.d.ts +4 -3
- package/core/viewer.js +5 -1
- package/graphql/builtins/connection.js +3 -3
- package/graphql/builtins/edge.js +2 -2
- package/graphql/builtins/node.js +1 -1
- package/graphql/graphql.d.ts +17 -9
- package/graphql/graphql.js +47 -30
- package/graphql/index.d.ts +1 -1
- package/graphql/index.js +3 -4
- package/graphql/mutations/union.d.ts +2 -0
- package/graphql/mutations/union.js +35 -0
- package/graphql/node_resolver.d.ts +0 -1
- package/graphql/query/connection_type.d.ts +9 -9
- package/graphql/query/connection_type.js +6 -6
- package/graphql/query/edge_connection.d.ts +9 -9
- package/graphql/query/page_info.d.ts +1 -1
- package/graphql/query/page_info.js +4 -4
- package/graphql/query/shared_assoc_test.js +3 -3
- package/graphql/query/shared_edge_connection.js +1 -19
- package/graphql/scalars/time.d.ts +1 -1
- package/imports/index.d.ts +6 -1
- package/imports/index.js +19 -4
- package/index.d.ts +23 -1
- package/index.js +32 -6
- package/package.json +18 -17
- package/parse_schema/parse.d.ts +45 -8
- package/parse_schema/parse.js +193 -15
- package/schema/base_schema.d.ts +38 -1
- package/schema/base_schema.js +53 -2
- package/schema/field.d.ts +75 -21
- package/schema/field.js +185 -72
- package/schema/index.d.ts +4 -2
- package/schema/index.js +15 -2
- package/schema/json_field.d.ts +13 -1
- package/schema/json_field.js +28 -1
- package/schema/schema.d.ts +125 -10
- package/schema/schema.js +133 -5
- package/schema/struct_field.d.ts +27 -0
- package/schema/struct_field.js +138 -0
- package/schema/union_field.d.ts +23 -0
- package/schema/union_field.js +79 -0
- package/scripts/custom_compiler.js +10 -6
- package/scripts/custom_graphql.js +224 -36
- package/scripts/{transform_schema.d.ts → migrate_v0.1.d.ts} +0 -0
- package/scripts/migrate_v0.1.js +36 -0
- package/scripts/move_types.d.ts +1 -0
- package/scripts/move_types.js +117 -0
- package/scripts/read_schema.js +35 -6
- package/testutils/action/complex_schemas.d.ts +69 -0
- package/testutils/action/complex_schemas.js +398 -0
- package/testutils/builder.d.ts +52 -49
- package/testutils/builder.js +143 -44
- package/testutils/context/test_context.d.ts +2 -2
- package/testutils/context/test_context.js +7 -1
- package/testutils/db/fixture.d.ts +10 -0
- package/testutils/db/fixture.js +26 -0
- package/testutils/db/{test_db.d.ts → temp_db.d.ts} +26 -9
- package/testutils/db/{test_db.js → temp_db.js} +190 -46
- package/testutils/db/value.d.ts +7 -0
- package/testutils/db/value.js +251 -0
- package/testutils/db_mock.d.ts +16 -4
- package/testutils/db_mock.js +51 -6
- package/testutils/db_time_zone.d.ts +4 -0
- package/testutils/db_time_zone.js +41 -0
- package/testutils/ent-graphql-tests/index.d.ts +9 -1
- package/testutils/ent-graphql-tests/index.js +53 -25
- package/testutils/fake_data/const.d.ts +2 -1
- package/testutils/fake_data/const.js +3 -0
- package/testutils/fake_data/fake_contact.d.ts +10 -10
- package/testutils/fake_data/fake_contact.js +23 -21
- package/testutils/fake_data/fake_event.d.ts +8 -9
- package/testutils/fake_data/fake_event.js +25 -28
- package/testutils/fake_data/fake_tag.d.ts +36 -0
- package/testutils/fake_data/fake_tag.js +89 -0
- package/testutils/fake_data/fake_user.d.ts +10 -11
- package/testutils/fake_data/fake_user.js +20 -23
- package/testutils/fake_data/index.js +5 -1
- package/testutils/fake_data/internal.d.ts +2 -0
- package/testutils/fake_data/internal.js +7 -1
- package/testutils/fake_data/tag_query.d.ts +13 -0
- package/testutils/fake_data/tag_query.js +43 -0
- package/testutils/fake_data/test_helpers.d.ts +11 -4
- package/testutils/fake_data/test_helpers.js +29 -13
- package/testutils/fake_data/user_query.d.ts +13 -6
- package/testutils/fake_data/user_query.js +54 -22
- package/testutils/fake_log.d.ts +3 -3
- package/testutils/parse_sql.d.ts +6 -0
- package/testutils/parse_sql.js +16 -2
- package/testutils/test_edge_global_schema.d.ts +15 -0
- package/testutils/test_edge_global_schema.js +62 -0
- package/testutils/write.d.ts +2 -2
- package/testutils/write.js +33 -7
- package/tsc/ast.d.ts +44 -0
- package/tsc/ast.js +277 -0
- package/tsc/compilerOptions.d.ts +6 -0
- package/tsc/compilerOptions.js +45 -2
- package/tsc/move_generated.d.ts +1 -0
- package/tsc/move_generated.js +164 -0
- package/tsc/transform.d.ts +22 -0
- package/tsc/transform.js +181 -0
- package/tsc/transform_action.d.ts +22 -0
- package/tsc/transform_action.js +183 -0
- package/tsc/transform_ent.d.ts +17 -0
- package/tsc/transform_ent.js +59 -0
- package/tsc/transform_schema.d.ts +27 -0
- package/tsc/transform_schema.js +383 -0
- package/graphql/enums.d.ts +0 -3
- package/graphql/enums.js +0 -25
- 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.
|
|
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.
|
|
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
|
|
58
|
+
function check(name, condition) {
|
|
54
59
|
return {
|
|
55
|
-
name
|
|
60
|
+
name,
|
|
56
61
|
generate() {
|
|
57
|
-
return `
|
|
62
|
+
return `CONSTRAINT ${name} CHECK(${condition})`;
|
|
58
63
|
},
|
|
59
64
|
};
|
|
60
65
|
}
|
|
61
|
-
exports.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
321
|
-
|
|
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
|
-
|
|
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 (
|
|
352
|
-
process.env.DB_CONNECTION_STRING
|
|
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
|
-
|
|
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
|
-
|
|
373
|
-
|
|
374
|
-
|
|
425
|
+
if (this.setTables) {
|
|
426
|
+
let tables = [];
|
|
427
|
+
if (typeof this.setTables === "function") {
|
|
428
|
+
tables = this.setTables();
|
|
375
429
|
}
|
|
376
430
|
else {
|
|
377
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
443
|
-
|
|
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.
|
|
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
|
|
600
|
+
const items = [];
|
|
482
601
|
for (const [fieldName, field] of fields) {
|
|
483
|
-
|
|
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), ...
|
|
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,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
|
+
}
|
package/testutils/db_mock.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
50
|
-
|
|
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 {};
|