@reldens/storage 0.116.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.
Files changed (86) 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 -693
  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 +385 -121
  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 +7 -7
  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 +72 -0
  52. package/tests/fixtures/expected-entities/entities-config.js +6 -4
  53. package/tests/fixtures/expected-entities/entities-translations.js +25 -14
  54. package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/registered-models-mikro-orm.js +2 -0
  55. package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-categories-model.js +13 -8
  56. package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-product-details-model.js +80 -0
  57. package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-products-model.js +20 -14
  58. package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-reviews-model.js +13 -12
  59. package/tests/fixtures/expected-entities-objection-js/models/objection-js/registered-models-objection-js.js +2 -0
  60. package/tests/fixtures/expected-entities-objection-js/models/objection-js/test-product-details-model.js +33 -0
  61. package/tests/fixtures/expected-entities-objection-js/models/objection-js/test-products-model.js +9 -0
  62. package/tests/fixtures/expected-entities-prisma/models/prisma/registered-models-prisma.js +2 -0
  63. package/tests/fixtures/expected-entities-prisma/models/prisma/test-product-details-model.js +43 -0
  64. package/tests/fixtures/expected-entities-prisma/models/prisma/test-products-model.js +2 -0
  65. package/tests/fixtures/product-details-fixtures.js +22 -0
  66. package/tests/fixtures/reviews-fixtures.js +2 -1
  67. package/tests/fixtures/sql/test-schema.sql +23 -1
  68. package/tests/fixtures/table-columns-fixtures.js +97 -0
  69. package/tests/integration/test-cross-driver-equivalence.js +286 -0
  70. package/tests/integration/test-nested-filters.js +265 -408
  71. package/tests/integration/test-relations.js +199 -0
  72. package/tests/integration/test-reldens-sample-data.js +255 -0
  73. package/tests/integration/test-reldens-shape-relations.js +292 -0
  74. package/tests/run-tests.js +112 -60
  75. package/tests/unit/test-drivers.js +7 -1
  76. package/tests/unit/test-models-generation.js +174 -0
  77. package/tests/utils/column-value-assert.js +139 -0
  78. package/tests/utils/driver-registry.js +1 -1
  79. package/tests/utils/entity-projection.js +111 -0
  80. package/tests/utils/observed-value.js +41 -0
  81. package/tests/utils/projection-difference.js +151 -0
  82. package/tests/utils/relations-shape-support.js +104 -0
  83. package/tests/utils/reldens-schema-loader.js +274 -0
  84. package/tests/utils/test-helpers.js +152 -19
  85. package/tests/utils/test-runner.js +26 -5
  86. package/tests/utils/whole-result-assert.js +243 -0
@@ -39,23 +39,29 @@ const schema = new EntitySchema({
39
39
  class: TestProductsModel,
40
40
  tableName: 'test_products',
41
41
  properties: {
42
- id: { type: 'number', primary: true },
43
- category_id: { type: 'number', persist: false },
44
- name: { type: 'string' },
45
- sku: { type: 'string' },
46
- description: { type: 'string', nullable: true },
47
- price: { type: 'number' },
48
- stock_quantity: { type: 'number', nullable: true },
49
- is_featured: { type: 'number', nullable: true },
50
- metadata: { type: 'object', nullable: true },
51
- tags: { type: 'string', nullable: true },
52
- status: { type: 'undefined', nullable: true },
53
- created_at: { type: 'Date', nullable: true },
54
- updated_at: { type: 'Date', nullable: true },
42
+ id: { type: 'int', primary: true },
43
+ category_id: { type: 'int' },
44
+ name: { type: 'varchar' },
45
+ sku: { type: 'varchar' },
46
+ description: { type: 'text', nullable: true },
47
+ price: { type: 'decimal' },
48
+ stock_quantity: { type: 'int', nullable: true },
49
+ is_featured: { type: 'tinyint', nullable: true },
50
+ metadata: { type: 'json', nullable: true },
51
+ tags: { type: 'varchar', nullable: true },
52
+ status: { type: 'enum', nullable: true },
53
+ created_at: { type: 'timestamp', nullable: true },
54
+ updated_at: { type: 'timestamp', nullable: true },
55
55
  related_test_categories: {
56
56
  kind: 'm:1',
57
57
  entity: () => require('./test-categories-model').TestCategoriesModel,
58
- joinColumns: ['category_id']
58
+ joinColumns: ['category_id'],
59
+ persist: false
60
+ },
61
+ related_test_product_details: {
62
+ kind: '1:1',
63
+ entity: () => require('./test-product-details-model').TestProductDetailsModel,
64
+ mappedBy: 'related_test_products'
59
65
  },
60
66
  related_test_reviews: {
61
67
  kind: '1:m',
@@ -37,21 +37,22 @@ const schema = new EntitySchema({
37
37
  class: TestReviewsModel,
38
38
  tableName: 'test_reviews',
39
39
  properties: {
40
- id: { type: 'number', primary: true },
41
- product_id: { type: 'number', persist: false },
42
- reviewer_name: { type: 'string' },
43
- reviewer_email: { type: 'string' },
44
- rating: { type: 'number' },
45
- title: { type: 'string', nullable: true },
46
- comment: { type: 'string', nullable: true },
47
- is_verified: { type: 'number', nullable: true },
48
- helpful_count: { type: 'number', nullable: true },
49
- created_at: { type: 'Date', nullable: true },
50
- updated_at: { type: 'Date', nullable: true },
40
+ id: { type: 'int', primary: true },
41
+ product_id: { type: 'int' },
42
+ reviewer_name: { type: 'varchar' },
43
+ reviewer_email: { type: 'varchar' },
44
+ rating: { type: 'tinyint' },
45
+ title: { type: 'varchar', nullable: true },
46
+ comment: { type: 'text', nullable: true },
47
+ is_verified: { type: 'tinyint', nullable: true },
48
+ helpful_count: { type: 'int', nullable: true },
49
+ created_at: { type: 'timestamp', nullable: true },
50
+ updated_at: { type: 'timestamp', nullable: true },
51
51
  related_test_products: {
52
52
  kind: 'm:1',
53
53
  entity: () => require('./test-products-model').TestProductsModel,
54
- joinColumns: ['product_id']
54
+ joinColumns: ['product_id'],
55
+ persist: false
55
56
  }
56
57
  },
57
58
  });
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  const { TestCategoriesModel } = require('./test-categories-model');
8
+ const { TestProductDetailsModel } = require('./test-product-details-model');
8
9
  const { TestProductsModel } = require('./test-products-model');
9
10
  const { TestReviewsModel } = require('./test-reviews-model');
10
11
  const { entitiesConfig } = require('../../entities-config');
@@ -12,6 +13,7 @@ const { entitiesTranslations } = require('../../entities-translations');
12
13
 
13
14
  let rawRegisteredEntities = {
14
15
  testCategories: TestCategoriesModel,
16
+ testProductDetails: TestProductDetailsModel,
15
17
  testProducts: TestProductsModel,
16
18
  testReviews: TestReviewsModel
17
19
  };
@@ -0,0 +1,33 @@
1
+ /**
2
+ *
3
+ * Reldens - TestProductDetailsModel
4
+ *
5
+ */
6
+
7
+ const { ObjectionJsRawModel } = require('../../../index');
8
+
9
+ class TestProductDetailsModel extends ObjectionJsRawModel
10
+ {
11
+
12
+ static get tableName()
13
+ {
14
+ return 'test_product_details';
15
+ }
16
+
17
+ static get relationMappings()
18
+ {
19
+ const { TestProductsModel } = require('./test-products-model');
20
+ return {
21
+ related_test_products: {
22
+ relation: this.BelongsToOneRelation,
23
+ modelClass: TestProductsModel,
24
+ join: {
25
+ from: this.tableName+'.product_id',
26
+ to: TestProductsModel.tableName+'.id'
27
+ }
28
+ }
29
+ };
30
+ }
31
+ }
32
+
33
+ module.exports.TestProductDetailsModel = TestProductDetailsModel;
@@ -17,6 +17,7 @@ class TestProductsModel extends ObjectionJsRawModel
17
17
  static get relationMappings()
18
18
  {
19
19
  const { TestCategoriesModel } = require('./test-categories-model');
20
+ const { TestProductDetailsModel } = require('./test-product-details-model');
20
21
  const { TestReviewsModel } = require('./test-reviews-model');
21
22
  return {
22
23
  related_test_categories: {
@@ -27,6 +28,14 @@ class TestProductsModel extends ObjectionJsRawModel
27
28
  to: TestCategoriesModel.tableName+'.id'
28
29
  }
29
30
  },
31
+ related_test_product_details: {
32
+ relation: this.HasOneRelation,
33
+ modelClass: TestProductDetailsModel,
34
+ join: {
35
+ from: this.tableName+'.id',
36
+ to: TestProductDetailsModel.tableName+'.product_id'
37
+ }
38
+ },
30
39
  related_test_reviews: {
31
40
  relation: this.HasManyRelation,
32
41
  modelClass: TestReviewsModel,
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  const { TestCategoriesModel } = require('./test-categories-model');
8
+ const { TestProductDetailsModel } = require('./test-product-details-model');
8
9
  const { TestProductsModel } = require('./test-products-model');
9
10
  const { TestReviewsModel } = require('./test-reviews-model');
10
11
  const { entitiesConfig } = require('../../entities-config');
@@ -12,6 +13,7 @@ const { entitiesTranslations } = require('../../entities-translations');
12
13
 
13
14
  let rawRegisteredEntities = {
14
15
  testCategories: TestCategoriesModel,
16
+ testProductDetails: TestProductDetailsModel,
15
17
  testProducts: TestProductsModel,
16
18
  testReviews: TestReviewsModel
17
19
  };
@@ -0,0 +1,43 @@
1
+ /**
2
+ *
3
+ * Reldens - TestProductDetailsModel
4
+ *
5
+ */
6
+
7
+ class TestProductDetailsModel
8
+ {
9
+
10
+ constructor(id, product_id, weight, dimensions, customData, useTimeOut, created_at, updated_at)
11
+ {
12
+ this.id = id;
13
+ this.product_id = product_id;
14
+ this.weight = weight;
15
+ this.dimensions = dimensions;
16
+ this.customData = customData;
17
+ this.useTimeOut = useTimeOut;
18
+ this.created_at = created_at;
19
+ this.updated_at = updated_at;
20
+ }
21
+
22
+ static get tableName()
23
+ {
24
+ return 'test_product_details';
25
+ }
26
+
27
+
28
+ static get relationTypes()
29
+ {
30
+ return {
31
+ test_products: 'one'
32
+ };
33
+ }
34
+
35
+ static get relationMappings()
36
+ {
37
+ return {
38
+ 'related_test_products': 'test_products'
39
+ };
40
+ }
41
+ }
42
+
43
+ module.exports.TestProductDetailsModel = TestProductDetailsModel;
@@ -34,6 +34,7 @@ class TestProductsModel
34
34
  {
35
35
  return {
36
36
  test_categories: 'one',
37
+ test_product_details: 'one',
37
38
  test_reviews: 'many'
38
39
  };
39
40
  }
@@ -42,6 +43,7 @@ class TestProductsModel
42
43
  {
43
44
  return {
44
45
  'related_test_categories': 'test_categories',
46
+ 'related_test_product_details': 'test_product_details',
45
47
  'related_test_reviews': 'test_reviews'
46
48
  };
47
49
  }
@@ -0,0 +1,22 @@
1
+ /**
2
+ *
3
+ * Reldens - Test Product Details Fixtures
4
+ * Universal fixtures for all drivers (no driver-specific nesting)
5
+ *
6
+ */
7
+
8
+ module.exports.ProductDetailsFixtures = {
9
+ product_details_relations_1: {
10
+ id: 4600,
11
+ product_id: 2600,
12
+ weight: 1.25,
13
+ dimensions: '10x20x30',
14
+ customData: '{"origin":"fixture"}',
15
+ useTimeOut: 45,
16
+ total_views: 9007199254740991
17
+ },
18
+ product_details_create_nested: {
19
+ weight: 2.5,
20
+ dimensions: '5x5x5'
21
+ }
22
+ };
@@ -26,7 +26,8 @@ module.exports.ReviewsFixtures = {
26
26
  title: 'Good value',
27
27
  comment: 'Works as expected',
28
28
  is_verified: 1,
29
- helpful_count: 5
29
+ helpful_count: 5,
30
+ category_slug: 'relations-test-1'
30
31
  },
31
32
  review_relations_2: {
32
33
  id: 3601,
@@ -1,4 +1,5 @@
1
1
  DROP TABLE IF EXISTS `test_reviews`;
2
+ DROP TABLE IF EXISTS `test_product_details`;
2
3
  DROP TABLE IF EXISTS `test_products`;
3
4
  DROP TABLE IF EXISTS `test_categories`;
4
5
 
@@ -39,6 +40,24 @@ CREATE TABLE `test_products` (
39
40
  CONSTRAINT `fk_products_category` FOREIGN KEY (`category_id`) REFERENCES `test_categories` (`id`) ON DELETE CASCADE
40
41
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
41
42
 
43
+ CREATE TABLE `test_product_details` (
44
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
45
+ `product_id` INT UNSIGNED NOT NULL,
46
+ `weight` DECIMAL(10,2) NULL,
47
+ `dimensions` VARCHAR(100) NULL,
48
+ `customData` TEXT NULL,
49
+ `useTimeOut` INT NULL,
50
+ `total_views` BIGINT NULL,
51
+ `category_id` INT UNSIGNED NULL DEFAULT NULL,
52
+ `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
53
+ `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
54
+ PRIMARY KEY (`id`),
55
+ UNIQUE KEY `product_id` (`product_id`),
56
+ KEY `category_id` (`category_id`),
57
+ CONSTRAINT `fk_product_details_product` FOREIGN KEY (`product_id`) REFERENCES `test_products` (`id`) ON DELETE CASCADE,
58
+ CONSTRAINT `fk_product_details_category` FOREIGN KEY (`category_id`) REFERENCES `test_categories` (`id`) ON DELETE SET NULL
59
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
60
+
42
61
  CREATE TABLE `test_reviews` (
43
62
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
44
63
  `product_id` INT UNSIGNED NOT NULL,
@@ -49,11 +68,14 @@ CREATE TABLE `test_reviews` (
49
68
  `comment` TEXT NULL,
50
69
  `is_verified` TINYINT(1) NOT NULL DEFAULT 0,
51
70
  `helpful_count` INT NOT NULL DEFAULT 0,
71
+ `category_slug` VARCHAR(100) NULL,
52
72
  `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
53
73
  `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
54
74
  PRIMARY KEY (`id`),
55
75
  KEY `product_id` (`product_id`),
56
76
  KEY `rating` (`rating`),
57
77
  KEY `is_verified` (`is_verified`),
58
- CONSTRAINT `fk_reviews_product` FOREIGN KEY (`product_id`) REFERENCES `test_products` (`id`) ON DELETE CASCADE
78
+ KEY `category_slug` (`category_slug`),
79
+ CONSTRAINT `fk_reviews_product` FOREIGN KEY (`product_id`) REFERENCES `test_products` (`id`) ON DELETE CASCADE,
80
+ CONSTRAINT `fk_reviews_category_slug` FOREIGN KEY (`category_slug`) REFERENCES `test_categories` (`slug`) ON DELETE SET NULL
59
81
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -0,0 +1,97 @@
1
+ /**
2
+ *
3
+ * Reldens - Test Table Columns Fixtures
4
+ * Every column of every test table with the JavaScript type it must be returned as and the database default
5
+ * applied when the inserted fixture does not include it, mirroring tests/fixtures/sql/test-schema.sql.
6
+ *
7
+ */
8
+
9
+ module.exports.TableColumnsFixtures = {
10
+ test_categories: {
11
+ columns: {
12
+ id: 'number',
13
+ name: 'string',
14
+ slug: 'string',
15
+ description: 'string',
16
+ is_active: 'number',
17
+ display_order: 'number',
18
+ created_at: 'date',
19
+ updated_at: 'date'
20
+ },
21
+ defaults: {
22
+ description: null,
23
+ is_active: 1,
24
+ display_order: 0
25
+ }
26
+ },
27
+ test_products: {
28
+ columns: {
29
+ id: 'number',
30
+ category_id: 'number',
31
+ name: 'string',
32
+ sku: 'string',
33
+ description: 'string',
34
+ price: 'string',
35
+ stock_quantity: 'number',
36
+ is_featured: 'number',
37
+ metadata: 'json',
38
+ tags: 'string',
39
+ status: 'string',
40
+ created_at: 'date',
41
+ updated_at: 'date'
42
+ },
43
+ defaults: {
44
+ description: null,
45
+ stock_quantity: 0,
46
+ is_featured: 0,
47
+ metadata: null,
48
+ tags: null,
49
+ status: 'draft'
50
+ }
51
+ },
52
+ test_product_details: {
53
+ columns: {
54
+ id: 'number',
55
+ product_id: 'number',
56
+ weight: 'number',
57
+ dimensions: 'string',
58
+ customData: 'string',
59
+ useTimeOut: 'number',
60
+ total_views: 'number',
61
+ category_id: 'number',
62
+ created_at: 'date',
63
+ updated_at: 'date'
64
+ },
65
+ defaults: {
66
+ weight: null,
67
+ dimensions: null,
68
+ customData: null,
69
+ useTimeOut: null,
70
+ total_views: null,
71
+ category_id: null
72
+ }
73
+ },
74
+ test_reviews: {
75
+ columns: {
76
+ id: 'number',
77
+ product_id: 'number',
78
+ reviewer_name: 'string',
79
+ reviewer_email: 'string',
80
+ rating: 'number',
81
+ title: 'string',
82
+ comment: 'string',
83
+ is_verified: 'number',
84
+ helpful_count: 'number',
85
+ category_slug: 'string',
86
+ created_at: 'date',
87
+ updated_at: 'date'
88
+ },
89
+ defaults: {
90
+ title: null,
91
+ comment: null,
92
+ is_verified: 0,
93
+ helpful_count: 0,
94
+ category_slug: null
95
+ }
96
+ }
97
+ };