@reldens/storage 0.117.0 → 0.118.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.
- package/.claude/test-architecture.md +27 -17
- package/CLAUDE.md +67 -11
- package/README.md +204 -22
- package/bin/reldens-storage.js +43 -10
- package/index.js +53 -12
- package/lib/drizzle/drizzle-data-server.js +123 -0
- package/lib/drizzle/drizzle-driver.js +228 -0
- package/lib/drizzle/drizzle-models-generation.js +49 -0
- package/lib/drizzle/drizzle-modules-loader.js +32 -0
- package/lib/drizzle/drizzle-modules-validator.js +74 -0
- package/lib/entities-generator.js +36 -7
- package/lib/entity-templates/drizzle-model.template +28 -0
- package/lib/entity-templates/query-builder-model.template +17 -0
- package/lib/generators/base-generator.js +13 -0
- package/lib/generators/entities-generation.js +0 -13
- package/lib/generators/models-generation.js +179 -680
- package/lib/generators/relations-detection.js +171 -0
- package/lib/knex/knex-data-server.js +128 -0
- package/lib/knex/knex-driver.js +157 -0
- package/lib/knex/knex-modules-loader.js +28 -0
- package/lib/knex/knex-modules-validator.js +45 -0
- package/lib/kysely/kysely-data-server.js +128 -0
- package/lib/kysely/kysely-driver.js +176 -0
- package/lib/kysely/kysely-modules-loader.js +28 -0
- package/lib/kysely/kysely-modules-validator.js +53 -0
- package/lib/mikro-orm/mikro-orm-data-server.js +48 -29
- package/lib/mikro-orm/mikro-orm-driver.js +317 -108
- package/lib/mikro-orm/mikro-orm-models-generation.js +178 -0
- package/lib/mikro-orm/mikro-orm-modules-loader.js +50 -0
- package/lib/mikro-orm/mikro-orm-modules-validator.js +46 -0
- package/lib/mysql2-connection-config.js +38 -0
- package/lib/objection-js/objection-js-data-server.js +71 -125
- package/lib/objection-js/objection-js-driver.js +4 -1
- package/lib/objection-js/objection-js-models-generation.js +98 -0
- package/lib/objection-js/objection-modules-loader.js +28 -0
- package/lib/objection-js/objection-modules-validator.js +31 -0
- package/lib/package-resolver.js +45 -0
- package/lib/prisma/prisma-client-loader.js +11 -1
- package/lib/prisma/prisma-driver.js +16 -2
- package/lib/prisma/prisma-filter-processor.js +5 -6
- package/lib/prisma/prisma-models-generation.js +236 -0
- package/lib/prisma/prisma-schema-generator.js +5 -1
- package/lib/prisma/prisma-type-caster.js +14 -0
- package/lib/query-builder-driver.js +210 -0
- package/lib/query-builder-models-generation.js +80 -0
- package/lib/relations-loader.js +192 -0
- package/lib/type-mapper.js +38 -0
- package/package.json +7 -7
- package/tests/.env.test.example +6 -0
- package/tests/fixtures/categories-fixtures.js +8 -0
- package/tests/fixtures/expected-entities/entities/test-product-details-entity.js +10 -1
- package/tests/fixtures/expected-entities/entities-translations.js +2 -0
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-categories-model.js +13 -8
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-product-details-model.js +30 -10
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-products-model.js +15 -14
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-reviews-model.js +13 -12
- package/tests/fixtures/expected-entities-prisma/models/prisma/test-product-details-model.js +3 -1
- package/tests/fixtures/product-details-fixtures.js +4 -1
- package/tests/fixtures/reviews-fixtures.js +2 -1
- package/tests/fixtures/sql/test-schema.sql +11 -2
- package/tests/fixtures/table-columns-fixtures.js +97 -0
- package/tests/integration/test-cross-driver-equivalence.js +286 -0
- package/tests/integration/test-nested-filters.js +265 -408
- package/tests/integration/test-relations.js +135 -0
- package/tests/integration/test-reldens-sample-data.js +255 -0
- package/tests/integration/test-reldens-shape-relations.js +292 -0
- package/tests/run-tests.js +111 -65
- package/tests/unit/test-drivers.js +7 -1
- package/tests/unit/test-models-generation.js +28 -18
- package/tests/utils/column-value-assert.js +139 -0
- package/tests/utils/entity-projection.js +111 -0
- package/tests/utils/observed-value.js +41 -0
- package/tests/utils/projection-difference.js +151 -0
- package/tests/utils/relations-shape-support.js +104 -0
- package/tests/utils/reldens-schema-loader.js +274 -0
- package/tests/utils/test-helpers.js +143 -13
- package/tests/utils/test-runner.js +26 -5
- 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
|
|
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: '
|
|
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 = [
|
|
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 = ['
|
|
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
|
-
? {
|
|
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('
|
|
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
|
-
|
|
42
|
-
Logger.info(' ✔ '+name+' ('+duration+'ms)');
|
|
42
|
+
this.logTestResult(name, startTime, false);
|
|
43
43
|
} catch(error) {
|
|
44
44
|
this.failedCount++;
|
|
45
|
-
|
|
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
|
|