@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,74 @@
1
+ /**
2
+ *
3
+ * Reldens - DrizzleModulesValidator
4
+ *
5
+ */
6
+
7
+ const { Logger, sc } = require('@reldens/utils');
8
+
9
+ let requiredOrmFunctions = [
10
+ 'eq', 'ne', 'gt', 'gte', 'lt', 'lte', 'inArray', 'like', 'isNull', 'and', 'or', 'not', 'asc', 'desc', 'count'
11
+ ];
12
+
13
+ class DrizzleModulesValidator
14
+ {
15
+
16
+ static validate(drizzleModules)
17
+ {
18
+ if(!sc.isObject(drizzleModules)){
19
+ Logger.critical('Missing "drizzleModules" object.');
20
+ return false;
21
+ }
22
+ if(!DrizzleModulesValidator.validateOrm(drizzleModules.orm)){
23
+ return false;
24
+ }
25
+ if(drizzleModules.db){
26
+ return DrizzleModulesValidator.validateDbInstance(drizzleModules.db);
27
+ }
28
+ if(!sc.isFunction(drizzleModules.drizzle)){
29
+ Logger.critical('Invalid "drizzleModules.drizzle".');
30
+ return false;
31
+ }
32
+ return true;
33
+ }
34
+
35
+ static validateOrm(orm)
36
+ {
37
+ if(!sc.isObject(orm)){
38
+ Logger.critical('Missing "drizzleModules.orm" namespace.');
39
+ return false;
40
+ }
41
+ let missingFunctions = requiredOrmFunctions.filter(ormFunction => !sc.isFunction(orm[ormFunction]));
42
+ if(0 < missingFunctions.length){
43
+ Logger.critical('Invalid "drizzleModules.orm", missing: '+missingFunctions.join(', '));
44
+ return false;
45
+ }
46
+ if(!sc.isFunction(orm.sql)){
47
+ Logger.critical('Invalid "drizzleModules.orm", "sql" not found.');
48
+ return false;
49
+ }
50
+ if(!sc.isFunction(orm.sql.raw)){
51
+ Logger.critical('Invalid "drizzleModules.orm", "sql.raw" not found.');
52
+ return false;
53
+ }
54
+ return true;
55
+ }
56
+
57
+ static validateDbInstance(db)
58
+ {
59
+ let requiredMethods = ['select', 'insert', 'update', 'delete', 'execute'];
60
+ let missingMethods = requiredMethods.filter(method => !sc.isFunction(db[method]));
61
+ if(0 < missingMethods.length){
62
+ Logger.critical('Invalid Drizzle instance, missing: '+missingMethods.join(', '));
63
+ return false;
64
+ }
65
+ if(!sc.isObjectFunction(db.$client, 'end')){
66
+ Logger.critical('Invalid Drizzle instance, "$client.end" not found.');
67
+ return false;
68
+ }
69
+ return true;
70
+ }
71
+
72
+ }
73
+
74
+ module.exports.DrizzleModulesValidator = DrizzleModulesValidator;
@@ -9,6 +9,9 @@ const { Logger, sc } = require('@reldens/utils');
9
9
  const { ObjectionJsDataServer } = require('./objection-js/objection-js-data-server');
10
10
  const { MikroOrmDataServer } = require('./mikro-orm/mikro-orm-data-server');
11
11
  const { PrismaDataServer } = require('./prisma/prisma-data-server');
12
+ const { KnexDataServer } = require('./knex/knex-data-server');
13
+ const { KyselyDataServer } = require('./kysely/kysely-data-server');
14
+ const { DrizzleDataServer } = require('./drizzle/drizzle-data-server');
12
15
  const { PrismaRelationsMetadataExtractor } = require('./prisma/prisma-relations-metadata-extractor');
13
16
  const { EntitiesGeneration } = require('./generators/entities-generation');
14
17
  const { ModelsGeneration } = require('./generators/models-generation');
@@ -25,6 +28,9 @@ class EntitiesGenerator
25
28
  'objection-js': FileHandler.joinPaths(this.templatesFolderPath, 'objection-js-model.template'),
26
29
  'mikro-orm': FileHandler.joinPaths(this.templatesFolderPath, 'mikro-orm-model.template'),
27
30
  'prisma': FileHandler.joinPaths(this.templatesFolderPath, 'prisma-model.template'),
31
+ 'knex': FileHandler.joinPaths(this.templatesFolderPath, 'query-builder-model.template'),
32
+ 'kysely': FileHandler.joinPaths(this.templatesFolderPath, 'query-builder-model.template'),
33
+ 'drizzle': FileHandler.joinPaths(this.templatesFolderPath, 'drizzle-model.template'),
28
34
  'entity': FileHandler.joinPaths(this.templatesFolderPath, 'entity.template'),
29
35
  'entities-config': FileHandler.joinPaths(this.templatesFolderPath, 'entities-config.template'),
30
36
  'entities-translations': FileHandler.joinPaths(this.templatesFolderPath, 'entities-translations.template'),
@@ -39,17 +45,36 @@ class EntitiesGenerator
39
45
  this.driverMap = {
40
46
  'objection-js': ObjectionJsDataServer,
41
47
  'mikro-orm': MikroOrmDataServer,
42
- 'prisma': PrismaDataServer
48
+ 'prisma': PrismaDataServer,
49
+ 'knex': KnexDataServer,
50
+ 'kysely': KyselyDataServer,
51
+ 'drizzle': DrizzleDataServer
43
52
  };
44
53
  this.driversClassMap = {
45
54
  'ObjectionJsDataServer': 'objection-js',
46
55
  'MikroOrmDataServer': 'mikro-orm',
47
- 'PrismaDataServer': 'prisma'
56
+ 'PrismaDataServer': 'prisma',
57
+ 'KnexDataServer': 'knex',
58
+ 'KyselyDataServer': 'kysely',
59
+ 'DrizzleDataServer': 'drizzle'
48
60
  };
49
61
  this.server = sc.get(props, 'server', false);
50
62
  this.connectionData = sc.get(props, 'connectionData', false);
51
63
  this.isOverride = sc.get(props, 'isOverride', false);
64
+ this.driverModulesProps = {
65
+ 'objection-js': 'objectionModules',
66
+ 'mikro-orm': 'mikroOrmModules',
67
+ 'prisma': 'prismaModules',
68
+ 'knex': 'knexModules',
69
+ 'kysely': 'kyselyModules',
70
+ 'drizzle': 'drizzleModules'
71
+ };
52
72
  this.prismaModules = sc.get(props, 'prismaModules', false);
73
+ this.kyselyModules = sc.get(props, 'kyselyModules', false);
74
+ this.drizzleModules = sc.get(props, 'drizzleModules', false);
75
+ this.objectionModules = sc.get(props, 'objectionModules', false);
76
+ this.knexModules = sc.get(props, 'knexModules', false);
77
+ this.mikroOrmModules = sc.get(props, 'mikroOrmModules', false);
53
78
  this.generatedEntities = {};
54
79
  this.existingEntities = {};
55
80
  this.existingEntityFields = {};
@@ -64,7 +89,10 @@ class EntitiesGenerator
64
89
  templates: {
65
90
  'objection-js': this.templates['objection-js'],
66
91
  'mikro-orm': this.templates['mikro-orm'],
67
- 'prisma': this.templates['prisma']
92
+ 'prisma': this.templates['prisma'],
93
+ 'knex': this.templates['knex'],
94
+ 'kysely': this.templates['kysely'],
95
+ 'drizzle': this.templates['drizzle']
68
96
  }
69
97
  });
70
98
  this.entitiesConfigGeneration = new EntitiesConfigGeneration({
@@ -288,7 +316,7 @@ class EntitiesGenerator
288
316
  Logger.critical('Failed to fetch driver key.');
289
317
  return false;
290
318
  }
291
- this.modelsGeneration.setAllTablesData(tables);
319
+ this.modelsGeneration.relationsDetection.allTablesData = tables;
292
320
  let tablesToGenerate = this.filterTablesToGenerate(tables, driverKey);
293
321
  if(0 === Object.keys(tablesToGenerate).length && !this.isOverride){
294
322
  return true;
@@ -340,7 +368,7 @@ class EntitiesGenerator
340
368
  if(this.server){
341
369
  return this.server;
342
370
  }
343
- let driverKey = sc.get(this.connectionData, 'driver', 'objection-js');
371
+ let driverKey = sc.get(this.connectionData, 'driver', 'knex');
344
372
  let driverClassMapped = this.driverMap[driverKey];
345
373
  if(!driverClassMapped){
346
374
  Logger.critical('Unsupported driver: '+driverKey);
@@ -357,8 +385,9 @@ class EntitiesGenerator
357
385
  },
358
386
  projectRoot: this.projectPath
359
387
  };
360
- if('prisma' === driverKey && this.prismaModules){
361
- serverConfig.prismaModules = this.prismaModules;
388
+ let modulesProp = sc.get(this.driverModulesProps, driverKey, false);
389
+ if(modulesProp && this[modulesProp]){
390
+ serverConfig[modulesProp] = this[modulesProp];
362
391
  }
363
392
  this.server = new driverClassMapped(serverConfig);
364
393
  return this.server;
@@ -0,0 +1,28 @@
1
+ /**
2
+ *
3
+ * Reldens - {{modelClassName}}
4
+ *
5
+ */
6
+
7
+ const DrizzleMysqlCore = require('drizzle-orm/mysql-core');
8
+
9
+ let table = DrizzleMysqlCore.mysqlTable('{{tableName}}', {
10
+ {{entityPropertiesDefinition}}
11
+ });
12
+
13
+ class {{modelClassName}}
14
+ {
15
+
16
+ static get tableName()
17
+ {
18
+ return '{{tableName}}';
19
+ }
20
+
21
+ static get table()
22
+ {
23
+ return table;
24
+ }
25
+ {{idColumn}}{{modelRelations}}
26
+ }
27
+
28
+ module.exports.{{modelClassName}} = {{modelClassName}};
@@ -0,0 +1,17 @@
1
+ /**
2
+ *
3
+ * Reldens - {{modelClassName}}
4
+ *
5
+ */
6
+
7
+ class {{modelClassName}}
8
+ {
9
+
10
+ static get tableName()
11
+ {
12
+ return '{{tableName}}';
13
+ }
14
+ {{idColumn}}{{modelRelations}}
15
+ }
16
+
17
+ module.exports.{{modelClassName}} = {{modelClassName}};
@@ -25,6 +25,19 @@ class BaseGenerator
25
25
  props.push('onDelete: \''+deleteRule+'\'');
26
26
  }
27
27
 
28
+ parseEnumValues(columnType)
29
+ {
30
+ if(!columnType){
31
+ return [];
32
+ }
33
+ let match = columnType.match(/^enum\('(.+)'\)$/i);
34
+ if(!match){
35
+ return [];
36
+ }
37
+ let valuesString = match[1];
38
+ return valuesString.split('\',\'');
39
+ }
40
+
28
41
  mapDeleteRule(deleteRule)
29
42
  {
30
43
  if(!deleteRule){
@@ -277,19 +277,6 @@ class EntitiesGeneration extends BaseGenerator
277
277
  );
278
278
  }
279
279
 
280
- parseEnumValues(columnType)
281
- {
282
- if(!columnType){
283
- return [];
284
- }
285
- let match = columnType.match(/^enum\('(.+)'\)$/i);
286
- if(!match){
287
- return [];
288
- }
289
- let valuesString = match[1];
290
- return valuesString.split('\',\'');
291
- }
292
-
293
280
  addRequiredAttribute(props, column)
294
281
  {
295
282
  if(!column.nullable && !column.default){