@reldens/storage 0.117.0 → 0.119.0

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 (78) hide show
  1. package/.claude/test-architecture.md +27 -17
  2. package/CLAUDE.md +67 -11
  3. package/README.md +204 -22
  4. package/bin/reldens-storage.js +43 -10
  5. package/index.js +53 -12
  6. package/lib/drizzle/drizzle-data-server.js +123 -0
  7. package/lib/drizzle/drizzle-driver.js +228 -0
  8. package/lib/drizzle/drizzle-models-generation.js +49 -0
  9. package/lib/drizzle/drizzle-modules-loader.js +32 -0
  10. package/lib/drizzle/drizzle-modules-validator.js +74 -0
  11. package/lib/entities-generator.js +36 -7
  12. package/lib/entity-templates/drizzle-model.template +28 -0
  13. package/lib/entity-templates/query-builder-model.template +17 -0
  14. package/lib/generators/base-generator.js +13 -0
  15. package/lib/generators/entities-generation.js +0 -13
  16. package/lib/generators/models-generation.js +179 -680
  17. package/lib/generators/relations-detection.js +171 -0
  18. package/lib/knex/knex-data-server.js +128 -0
  19. package/lib/knex/knex-driver.js +157 -0
  20. package/lib/knex/knex-modules-loader.js +28 -0
  21. package/lib/knex/knex-modules-validator.js +45 -0
  22. package/lib/kysely/kysely-data-server.js +128 -0
  23. package/lib/kysely/kysely-driver.js +176 -0
  24. package/lib/kysely/kysely-modules-loader.js +28 -0
  25. package/lib/kysely/kysely-modules-validator.js +53 -0
  26. package/lib/mikro-orm/mikro-orm-data-server.js +48 -29
  27. package/lib/mikro-orm/mikro-orm-driver.js +317 -108
  28. package/lib/mikro-orm/mikro-orm-models-generation.js +178 -0
  29. package/lib/mikro-orm/mikro-orm-modules-loader.js +50 -0
  30. package/lib/mikro-orm/mikro-orm-modules-validator.js +46 -0
  31. package/lib/mysql2-connection-config.js +38 -0
  32. package/lib/objection-js/objection-js-data-server.js +71 -125
  33. package/lib/objection-js/objection-js-driver.js +4 -1
  34. package/lib/objection-js/objection-js-models-generation.js +98 -0
  35. package/lib/objection-js/objection-modules-loader.js +28 -0
  36. package/lib/objection-js/objection-modules-validator.js +31 -0
  37. package/lib/package-resolver.js +45 -0
  38. package/lib/prisma/prisma-client-loader.js +11 -1
  39. package/lib/prisma/prisma-driver.js +16 -2
  40. package/lib/prisma/prisma-filter-processor.js +5 -6
  41. package/lib/prisma/prisma-models-generation.js +236 -0
  42. package/lib/prisma/prisma-schema-generator.js +5 -1
  43. package/lib/prisma/prisma-type-caster.js +14 -0
  44. package/lib/query-builder-driver.js +210 -0
  45. package/lib/query-builder-models-generation.js +80 -0
  46. package/lib/relations-loader.js +192 -0
  47. package/lib/type-mapper.js +38 -0
  48. package/package.json +8 -8
  49. package/tests/.env.test.example +6 -0
  50. package/tests/fixtures/categories-fixtures.js +8 -0
  51. package/tests/fixtures/expected-entities/entities/test-product-details-entity.js +10 -1
  52. package/tests/fixtures/expected-entities/entities-translations.js +2 -0
  53. package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-categories-model.js +13 -8
  54. package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-product-details-model.js +30 -10
  55. package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-products-model.js +15 -14
  56. package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-reviews-model.js +13 -12
  57. package/tests/fixtures/expected-entities-prisma/models/prisma/test-product-details-model.js +3 -1
  58. package/tests/fixtures/product-details-fixtures.js +4 -1
  59. package/tests/fixtures/reviews-fixtures.js +2 -1
  60. package/tests/fixtures/sql/test-schema.sql +11 -2
  61. package/tests/fixtures/table-columns-fixtures.js +97 -0
  62. package/tests/integration/test-cross-driver-equivalence.js +286 -0
  63. package/tests/integration/test-nested-filters.js +265 -408
  64. package/tests/integration/test-relations.js +135 -0
  65. package/tests/integration/test-reldens-sample-data.js +255 -0
  66. package/tests/integration/test-reldens-shape-relations.js +292 -0
  67. package/tests/run-tests.js +111 -65
  68. package/tests/unit/test-drivers.js +7 -1
  69. package/tests/unit/test-models-generation.js +28 -18
  70. package/tests/utils/column-value-assert.js +139 -0
  71. package/tests/utils/entity-projection.js +111 -0
  72. package/tests/utils/observed-value.js +41 -0
  73. package/tests/utils/projection-difference.js +151 -0
  74. package/tests/utils/relations-shape-support.js +104 -0
  75. package/tests/utils/reldens-schema-loader.js +274 -0
  76. package/tests/utils/test-helpers.js +143 -13
  77. package/tests/utils/test-runner.js +26 -5
  78. package/tests/utils/whole-result-assert.js +243 -0
@@ -0,0 +1,274 @@
1
+ /**
2
+ *
3
+ * Reldens - ReldensSchemaLoader
4
+ *
5
+ */
6
+
7
+ const { TestHelpers } = require('./test-helpers');
8
+ const { Logger, sc } = require('@reldens/utils');
9
+ const { FileHandler } = require('@reldens/server-utils');
10
+
11
+ class ReldensSchemaLoader
12
+ {
13
+
14
+ static migrationsPath()
15
+ {
16
+ return process.env.RELDENS_TEST_MIGRATIONS_PATH || '';
17
+ }
18
+
19
+ static sqlFileNames()
20
+ {
21
+ return ['reldens-install-v4.0.0.sql', 'reldens-basic-config-v4.0.0.sql', 'reldens-sample-data-v4.0.0.sql'];
22
+ }
23
+
24
+ static isAvailable()
25
+ {
26
+ let migrationsPath = this.migrationsPath();
27
+ if('' === migrationsPath){
28
+ return false;
29
+ }
30
+ for(let fileName of this.sqlFileNames()){
31
+ if(!FileHandler.exists(FileHandler.joinPaths(migrationsPath, fileName))){
32
+ Logger.warning('Reldens schema file not found: '+fileName);
33
+ return false;
34
+ }
35
+ }
36
+ return true;
37
+ }
38
+
39
+ static databaseName()
40
+ {
41
+ return process.env.RELDENS_TEST_RELDENS_DB_NAME || 'reldens_storage_test_full';
42
+ }
43
+
44
+ static generationPath()
45
+ {
46
+ return FileHandler.joinPaths(process.cwd(), 'tests', 'generated-reldens-schema');
47
+ }
48
+
49
+ static async ensureDatabase()
50
+ {
51
+ let BootstrapServerClass = TestHelpers.getDataServerClass('knex');
52
+ if(!BootstrapServerClass){
53
+ Logger.critical('Reldens schema bootstrap data server class not found.');
54
+ return false;
55
+ }
56
+ let bootstrapServer = new BootstrapServerClass({
57
+ client: TestHelpers.driverClient('knex'),
58
+ config: {...TestHelpers.getTestDbConfig(), multipleStatements: true},
59
+ rawEntities: {},
60
+ multipleStatements: true,
61
+ poolConfig: {min: 0, max: 2}
62
+ });
63
+ await bootstrapServer.connect();
64
+ if(!bootstrapServer.initialized){
65
+ Logger.critical('Reldens schema bootstrap connection failed.');
66
+ return false;
67
+ }
68
+ await TestHelpers.executeRawSQL(bootstrapServer, 'DROP DATABASE IF EXISTS '+this.databaseName()+';');
69
+ await TestHelpers.executeRawSQL(bootstrapServer, 'CREATE DATABASE '+this.databaseName()+';');
70
+ await bootstrapServer.disconnect();
71
+ Logger.info('Reldens schema database is ready: '+this.databaseName());
72
+ return true;
73
+ }
74
+
75
+ static async regeneratedPrismaModules(config)
76
+ {
77
+ let prismaConfig = Object.assign({}, config, {client: 'mysql'});
78
+ if(!await TestHelpers.generatePrismaSchema(prismaConfig)){
79
+ Logger.critical('Reldens schema Prisma schema generation failed.');
80
+ return false;
81
+ }
82
+ if(!await TestHelpers.generatePrismaClient()){
83
+ Logger.critical('Reldens schema Prisma client generation failed.');
84
+ return false;
85
+ }
86
+ delete require.cache[require.resolve(FileHandler.joinPaths(process.cwd(), 'prisma', 'client'))];
87
+ return await TestHelpers.loadPrismaModules(process.cwd(), config);
88
+ }
89
+
90
+ static async refreshPrismaClient(dataServer, driverName)
91
+ {
92
+ if('prisma' !== driverName){
93
+ return true;
94
+ }
95
+ let config = TestHelpers.getTestDbConfig();
96
+ config.database = this.databaseName();
97
+ let prismaModules = await this.regeneratedPrismaModules(config);
98
+ if(!prismaModules){
99
+ return false;
100
+ }
101
+ await dataServer.disconnect();
102
+ dataServer.prismaModules = prismaModules;
103
+ dataServer.prisma = prismaModules.client;
104
+ dataServer.initialized = Date.now();
105
+ return true;
106
+ }
107
+
108
+ static async setupDataServer(driverName)
109
+ {
110
+ let DataServerClass = TestHelpers.getDataServerClass(driverName);
111
+ if(!DataServerClass){
112
+ Logger.critical('Reldens schema data server class not found for '+driverName);
113
+ return false;
114
+ }
115
+ let config = TestHelpers.getTestDbConfig();
116
+ config.database = this.databaseName();
117
+ let serverConfig = {
118
+ client: TestHelpers.driverClient(driverName),
119
+ config: {...config, multipleStatements: true},
120
+ rawEntities: {},
121
+ multipleStatements: true,
122
+ poolConfig: {min: 0, max: 2}
123
+ };
124
+ TestHelpers.appendDriverModules(serverConfig, driverName);
125
+ if('prisma' === driverName){
126
+ serverConfig.prismaModules = await TestHelpers.loadPrismaModules(process.cwd(), config);
127
+ if(!serverConfig.prismaModules){
128
+ return false;
129
+ }
130
+ }
131
+ let dataServer = new DataServerClass(serverConfig);
132
+ await dataServer.connect();
133
+ if(!dataServer.initialized){
134
+ Logger.critical('Reldens schema data server failed to initialize for '+driverName);
135
+ return false;
136
+ }
137
+ return dataServer;
138
+ }
139
+
140
+ static async loadSchemaAndData(dataServer)
141
+ {
142
+ for(let fileName of this.sqlFileNames()){
143
+ let sql = FileHandler.readFile(FileHandler.joinPaths(this.migrationsPath(), fileName));
144
+ if(!sql){
145
+ Logger.critical('Could not read reldens schema file: '+fileName);
146
+ return false;
147
+ }
148
+ await TestHelpers.executeRawSQL(dataServer, sql);
149
+ Logger.info('Loaded reldens schema file: '+fileName);
150
+ }
151
+ return true;
152
+ }
153
+
154
+ static async generateEntities(dataServer, driverName)
155
+ {
156
+ let { EntitiesGenerator } = require('../../lib/entities-generator');
157
+ let config = TestHelpers.getTestDbConfig();
158
+ let generator = new EntitiesGenerator({
159
+ connectionData: {
160
+ driver: driverName,
161
+ client: TestHelpers.driverClient(driverName),
162
+ user: config.user,
163
+ password: config.password,
164
+ host: config.host,
165
+ database: this.databaseName(),
166
+ port: config.port
167
+ },
168
+ projectPath: this.generationPath(),
169
+ isOverride: true,
170
+ server: dataServer
171
+ });
172
+ if(!await generator.generate()){
173
+ Logger.critical('Reldens schema entities generation failed for '+driverName);
174
+ return false;
175
+ }
176
+ return this.fixGeneratedRequirePaths(driverName);
177
+ }
178
+
179
+ static modelsFolderDepth = 5;
180
+
181
+ static entitiesFolderDepth = 4;
182
+
183
+ static packageRequirePath(folderDepth)
184
+ {
185
+ return '..'+'/..'.repeat(folderDepth - 1)+'/index';
186
+ }
187
+
188
+ static fixGeneratedRequirePaths(driverName)
189
+ {
190
+ let modelsFolder = FileHandler.joinPaths(this.generationPath(), 'generated-entities', 'models', driverName);
191
+ if(!this.replacePackageRequire(modelsFolder, this.packageRequirePath(this.modelsFolderDepth))){
192
+ return false;
193
+ }
194
+ return this.replacePackageRequire(
195
+ FileHandler.joinPaths(this.generationPath(), 'generated-entities', 'entities'),
196
+ this.packageRequirePath(this.entitiesFolderDepth)
197
+ );
198
+ }
199
+
200
+ static replacePackageRequire(folderPath, packagePath)
201
+ {
202
+ let fileNames = FileHandler.getFilesInFolder(folderPath, ['.js']);
203
+ if(!sc.isArray(fileNames) || 0 === fileNames.length){
204
+ Logger.critical('No reldens schema files were generated at: '+folderPath);
205
+ return false;
206
+ }
207
+ for(let fileName of fileNames){
208
+ let filePath = FileHandler.joinPaths(folderPath, fileName);
209
+ let content = FileHandler.readFile(filePath);
210
+ FileHandler.writeFile(
211
+ filePath,
212
+ content.replace("require('@reldens/storage')", "require('"+packagePath+"')")
213
+ );
214
+ }
215
+ Logger.info('Fixed the require paths on '+fileNames.length+' reldens schema files at: '+folderPath);
216
+ return true;
217
+ }
218
+
219
+ static async loadEntities(dataServer, driverName)
220
+ {
221
+ let modelsFolder = FileHandler.joinPaths(this.generationPath(), 'generated-entities', 'models', driverName);
222
+ let modelsPath = FileHandler.joinPaths(modelsFolder, 'registered-models-'+driverName+'.js');
223
+ if(!FileHandler.exists(modelsPath)){
224
+ Logger.critical('Reldens schema registered models not found: '+modelsPath);
225
+ return false;
226
+ }
227
+ dataServer.rawEntities = require(modelsPath).rawRegisteredEntities;
228
+ if('mikro-orm' === driverName){
229
+ await dataServer.disconnect();
230
+ await dataServer.connect();
231
+ }
232
+ dataServer.generateEntities();
233
+ if(0 === Object.keys(dataServer.entities).length){
234
+ Logger.critical('No reldens schema entities generated for '+driverName);
235
+ return false;
236
+ }
237
+ Logger.info('Loaded '+Object.keys(dataServer.entities).length+' reldens schema entities for '+driverName);
238
+ return true;
239
+ }
240
+
241
+ static async setup(driverName)
242
+ {
243
+ if(!await this.ensureDatabase()){
244
+ return false;
245
+ }
246
+ let dataServer = await this.setupDataServer(driverName);
247
+ if(!dataServer){
248
+ return false;
249
+ }
250
+ if(!await this.loadSchemaAndData(dataServer)){
251
+ return false;
252
+ }
253
+ if(!await this.refreshPrismaClient(dataServer, driverName)){
254
+ return false;
255
+ }
256
+ if(!await this.generateEntities(dataServer, driverName)){
257
+ return false;
258
+ }
259
+ if(!await this.loadEntities(dataServer, driverName)){
260
+ return false;
261
+ }
262
+ return dataServer;
263
+ }
264
+
265
+ static async teardown(dataServer)
266
+ {
267
+ await TestHelpers.teardownDriver(dataServer);
268
+ FileHandler.remove(this.generationPath());
269
+ return true;
270
+ }
271
+
272
+ }
273
+
274
+ module.exports.ReldensSchemaLoader = ReldensSchemaLoader;
@@ -5,6 +5,11 @@
5
5
  */
6
6
 
7
7
  const { FileHandler } = require('@reldens/server-utils');
8
+ const { KyselyModulesLoader } = require('../../lib/kysely/kysely-modules-loader');
9
+ const { DrizzleModulesLoader } = require('../../lib/drizzle/drizzle-modules-loader');
10
+ const { MikroOrmModulesLoader } = require('../../lib/mikro-orm/mikro-orm-modules-loader');
11
+ const { ObjectionModulesLoader } = require('../../lib/objection-js/objection-modules-loader');
12
+ const { KnexModulesLoader } = require('../../lib/knex/knex-modules-loader');
8
13
  const { Logger, sc } = require('@reldens/utils');
9
14
  const { exec, execSync } = require('child_process');
10
15
  const { promisify } = require('util');
@@ -22,7 +27,8 @@ class TestHelpers
22
27
  user: process.env.RELDENS_TEST_DB_USER || 'test_user',
23
28
  password: process.env.RELDENS_TEST_DB_PASSWORD || 'test_password',
24
29
  database: process.env.RELDENS_TEST_DB_NAME || 'reldens_storage_test',
25
- client: process.env.RELDENS_TEST_DB_CLIENT || 'mysql'
30
+ client: process.env.RELDENS_TEST_DB_CLIENT || 'mysql',
31
+ connectionLimit: Number(process.env.RELDENS_TEST_DB_CONNECTION_LIMIT || 2)
26
32
  };
27
33
  }
28
34
 
@@ -41,10 +47,11 @@ class TestHelpers
41
47
  }
42
48
  }
43
49
  let serverConfig = {
44
- client: driverName === 'objection-js' ? 'mysql2' : 'mysql',
50
+ client: this.driverClient(driverName),
45
51
  config: {...config, multipleStatements: true},
46
52
  rawEntities: rawEntities,
47
- multipleStatements: true
53
+ multipleStatements: true,
54
+ poolConfig: {min: 0, max: 2}
48
55
  };
49
56
  if('prisma' === driverName){
50
57
  let prismaModules = await this.loadPrismaModules(process.cwd(), config);
@@ -53,6 +60,7 @@ class TestHelpers
53
60
  }
54
61
  serverConfig.prismaModules = prismaModules;
55
62
  }
63
+ this.appendDriverModules(serverConfig, driverName);
56
64
  let DataServerClass = this.getDataServerClass(driverName);
57
65
  let dataServer = new DataServerClass(serverConfig);
58
66
  let connected = await dataServer.connect();
@@ -81,16 +89,67 @@ class TestHelpers
81
89
  let { PrismaDataServer } = require('../../lib/prisma/prisma-data-server');
82
90
  return PrismaDataServer;
83
91
  }
92
+ if('knex' === driverName){
93
+ let { KnexDataServer } = require('../../lib/knex/knex-data-server');
94
+ return KnexDataServer;
95
+ }
96
+ if('kysely' === driverName){
97
+ let { KyselyDataServer } = require('../../lib/kysely/kysely-data-server');
98
+ return KyselyDataServer;
99
+ }
100
+ if('drizzle' === driverName){
101
+ let { DrizzleDataServer } = require('../../lib/drizzle/drizzle-data-server');
102
+ return DrizzleDataServer;
103
+ }
84
104
  Logger.critical('Unknown driver: '+driverName);
85
105
  return false;
86
106
  }
87
107
 
108
+ static driverClient(driverName)
109
+ {
110
+ if('objection-js' === driverName){
111
+ return 'mysql2';
112
+ }
113
+ if('knex' === driverName){
114
+ return 'mysql2';
115
+ }
116
+ return 'mysql';
117
+ }
118
+
119
+ static appendDriverModules(serverConfig, driverName)
120
+ {
121
+ this.registerNpmGlobalPaths();
122
+ if('kysely' === driverName){
123
+ serverConfig.kyselyModules = KyselyModulesLoader.load(false);
124
+ return serverConfig;
125
+ }
126
+ if('drizzle' === driverName){
127
+ serverConfig.drizzleModules = DrizzleModulesLoader.load(false);
128
+ return serverConfig;
129
+ }
130
+ if('mikro-orm' === driverName){
131
+ serverConfig.mikroOrmModules = MikroOrmModulesLoader.load(false, serverConfig.client);
132
+ return serverConfig;
133
+ }
134
+ if('objection-js' === driverName){
135
+ serverConfig.objectionModules = ObjectionModulesLoader.load(false);
136
+ return serverConfig;
137
+ }
138
+ if('knex' === driverName){
139
+ serverConfig.knexModules = KnexModulesLoader.load(false);
140
+ }
141
+ return serverConfig;
142
+ }
143
+
88
144
  static async teardownDriver(dataServer)
89
145
  {
90
146
  if(!dataServer){
91
147
  return;
92
148
  }
93
149
  try {
150
+ if(dataServer.db){
151
+ await dataServer.disconnect();
152
+ }
94
153
  if(dataServer.knex){
95
154
  await dataServer.knex.destroy();
96
155
  }
@@ -294,14 +353,16 @@ class TestHelpers
294
353
  static verifyAllPackages()
295
354
  {
296
355
  let required = [
297
- {name: '@mikro-orm/core', version: '7.2.0'},
298
- {name: '@mikro-orm/mongodb', version: '7.2.0'},
299
- {name: '@mikro-orm/mysql', version: '7.2.0'},
300
356
  {name: 'knex', version: '3.3.0'},
301
- {name: 'mysql', version: '2.18.1'},
302
- {name: 'mysql2', version: '3.24.3'},
303
- {name: 'objection', version: '3.1.5'}
357
+ {name: 'mysql2', version: '3.24.4'}
304
358
  ];
359
+ if(this.isObjectionFlagEnabled()){
360
+ required.push({name: 'objection', version: '3.1.5', optional: true});
361
+ }
362
+ if(this.isMikroOrmFlagEnabled()){
363
+ required.push({name: '@mikro-orm/core', version: '7.2.0', optional: true});
364
+ required.push({name: '@mikro-orm/mysql', version: '7.2.0', optional: true});
365
+ }
305
366
  if(this.isPrismaFlagEnabled()){
306
367
  required.push({name: 'prisma', version: '7.9.1', optional: true});
307
368
  required.push({name: '@prisma/client', version: '7.9.1', optional: true});
@@ -361,7 +422,11 @@ class TestHelpers
361
422
  Logger.warning('Could not resolve the npm global root: '+error.message);
362
423
  return '';
363
424
  }
364
- let extraPaths = [globalRoot, FileHandler.joinPaths(globalRoot, '@prisma', 'client', 'node_modules')];
425
+ let extraPaths = [
426
+ globalRoot,
427
+ FileHandler.joinPaths(globalRoot, '@prisma', 'client', 'node_modules'),
428
+ FileHandler.joinPaths(process.cwd(), 'node_modules')
429
+ ];
365
430
  let currentPaths = process.env.NODE_PATH ? process.env.NODE_PATH.split(delimiter) : [];
366
431
  process.env.NODE_PATH = [...currentPaths, ...extraPaths].join(delimiter);
367
432
  NodeModule._initPaths();
@@ -383,12 +448,66 @@ class TestHelpers
383
448
  return this.isPrismaAvailable();
384
449
  }
385
450
 
451
+ static isObjectionFlagEnabled()
452
+ {
453
+ return '1' === String(process.env.RELDENS_TEST_OBJECTION_ENABLED);
454
+ }
455
+
456
+ static isObjectionEnabled()
457
+ {
458
+ if(!this.isObjectionFlagEnabled()){
459
+ return false;
460
+ }
461
+ return this.canResolvePackage('objection');
462
+ }
463
+
464
+ static isMikroOrmFlagEnabled()
465
+ {
466
+ return '1' === String(process.env.RELDENS_TEST_MIKRO_ORM_ENABLED);
467
+ }
468
+
469
+ static isMikroOrmEnabled()
470
+ {
471
+ if(!this.isMikroOrmFlagEnabled()){
472
+ return false;
473
+ }
474
+ return this.canResolvePackage('@mikro-orm/core') && this.canResolvePackage('@mikro-orm/mysql');
475
+ }
476
+
477
+ static isKyselyEnabled()
478
+ {
479
+ if('1' !== String(process.env.RELDENS_TEST_KYSELY_ENABLED)){
480
+ return false;
481
+ }
482
+ return this.canResolvePackage('kysely');
483
+ }
484
+
485
+ static isDrizzleEnabled()
486
+ {
487
+ if('1' !== String(process.env.RELDENS_TEST_DRIZZLE_ENABLED)){
488
+ return false;
489
+ }
490
+ return this.canResolvePackage('drizzle-orm');
491
+ }
492
+
386
493
  static activeDriverNames()
387
494
  {
388
- let driverNames = ['objection-js', 'mikro-orm'];
495
+ let driverNames = ['knex'];
496
+ if(this.isObjectionEnabled()){
497
+ driverNames.push('objection-js');
498
+ }
499
+ if(this.isMikroOrmEnabled()){
500
+ driverNames.push('mikro-orm');
501
+ }
389
502
  if(this.isPrismaEnabled()){
390
503
  driverNames.push('prisma');
391
504
  }
505
+ if(this.isKyselyEnabled()){
506
+ driverNames.push('kysely');
507
+ }
508
+ if(this.isDrizzleEnabled()){
509
+ driverNames.push('drizzle');
510
+ }
392
511
  return driverNames;
393
512
  }
394
513
 
@@ -481,7 +600,14 @@ class TestHelpers
481
600
  }
482
601
  let adapterModule = require('@prisma/adapter-mariadb');
483
602
  let adapterConfig = config
484
- ? { host: config.host, port: config.port, user: config.user, password: config.password, database: config.database }
603
+ ? {
604
+ host: config.host,
605
+ port: config.port,
606
+ user: config.user,
607
+ password: config.password,
608
+ database: config.database,
609
+ connectionLimit: sc.get(config, 'connectionLimit', 2)
610
+ }
485
611
  : process.env.RELDENS_DB_URL;
486
612
  let client = new prismaModule.PrismaClient({ adapter: new adapterModule.PrismaMariaDb(adapterConfig) });
487
613
  await client.$connect();
@@ -509,6 +635,10 @@ class TestHelpers
509
635
  Logger.info('Cleaning up Prisma config file: '+prismaConfigPath);
510
636
  FileHandler.remove(prismaConfigPath);
511
637
  }
638
+ if('1' === process.env.RELDENS_TEST_KEEP_GENERATED){
639
+ Logger.info('Keeping generated entities folder, RELDENS_TEST_KEEP_GENERATED is active.');
640
+ return;
641
+ }
512
642
  let entitiesPath = FileHandler.joinPaths(process.cwd(), 'generated-entities');
513
643
  if(FileHandler.exists(entitiesPath)){
514
644
  Logger.info('Cleaning up generated entities folder: '+entitiesPath);
@@ -798,7 +928,7 @@ class TestHelpers
798
928
  this.fixGeneratedRequirePaths();
799
929
  this.compareGeneratedWithExpected(driverName, 'entities');
800
930
  this.compareGeneratedWithExpected(driverName, 'models/'+driverName);
801
- if('objection-js' === driverName){
931
+ if('knex' === driverName){
802
932
  this.compareGeneratedWithExpected(driverName, 'entities-config.js');
803
933
  this.compareGeneratedWithExpected(driverName, 'entities-translations.js');
804
934
  }
@@ -17,6 +17,7 @@ class TestRunner
17
17
  this.failedCount = 0;
18
18
  this.currentSuite = '';
19
19
  this.currentGroup = '';
20
+ this.totalDuration = 0;
20
21
  }
21
22
 
22
23
  suite(name)
@@ -38,22 +39,42 @@ class TestRunner
38
39
  try {
39
40
  await testFn();
40
41
  this.passedCount++;
41
- let duration = Date.now() - startTime;
42
- Logger.info(' ✔ '+name+' ('+duration+'ms)');
42
+ this.logTestResult(name, startTime, false);
43
43
  } catch(error) {
44
44
  this.failedCount++;
45
- let duration = Date.now() - startTime;
46
- Logger.error(' ✖ '+name+' ('+duration+'ms)');
45
+ this.logTestResult(name, startTime, true);
47
46
  Logger.error(' Error: '+error.message);
48
47
  }
49
48
  }
50
49
 
50
+ fail(name, message)
51
+ {
52
+ this.testCount++;
53
+ this.failedCount++;
54
+ Logger.error(' ✖ '+name);
55
+ Logger.error(' Error: '+message);
56
+ return this.getResults();
57
+ }
58
+
59
+ logTestResult(name, startTime, hasFailed)
60
+ {
61
+ let duration = Date.now() - startTime;
62
+ this.totalDuration += duration;
63
+ if(hasFailed){
64
+ Logger.error(' ✖ '+name+' ('+duration+'ms)');
65
+ return duration;
66
+ }
67
+ Logger.info(' ✔ '+name+' ('+duration+'ms)');
68
+ return duration;
69
+ }
70
+
51
71
  getResults()
52
72
  {
53
73
  return {
54
74
  total: this.testCount,
55
75
  passed: this.passedCount,
56
- failed: this.failedCount
76
+ failed: this.failedCount,
77
+ duration: this.totalDuration
57
78
  };
58
79
  }
59
80