rawsql-ts 0.10.9-beta → 0.11.1-beta

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 (104) hide show
  1. package/README.md +175 -47
  2. package/dist/esm/index.js +6 -0
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/index.min.js +16 -14
  5. package/dist/esm/index.min.js.map +4 -4
  6. package/dist/esm/src/index.js +6 -0
  7. package/dist/esm/src/index.js.map +1 -1
  8. package/dist/esm/src/tokenReaders/OperatorTokenReader.js +4 -0
  9. package/dist/esm/src/tokenReaders/OperatorTokenReader.js.map +1 -1
  10. package/dist/esm/src/transformers/CTEDependencyTracer.js +249 -0
  11. package/dist/esm/src/transformers/CTEDependencyTracer.js.map +1 -0
  12. package/dist/esm/src/transformers/DynamicQueryBuilder.js +155 -0
  13. package/dist/esm/src/transformers/DynamicQueryBuilder.js.map +1 -0
  14. package/dist/esm/src/transformers/JsonMappingUnifier.js +217 -0
  15. package/dist/esm/src/transformers/JsonMappingUnifier.js.map +1 -0
  16. package/dist/esm/src/transformers/ModelDrivenJsonMapping.js +103 -0
  17. package/dist/esm/src/transformers/ModelDrivenJsonMapping.js.map +1 -0
  18. package/dist/esm/src/transformers/PostgresArrayEntityCteBuilder.js +204 -16
  19. package/dist/esm/src/transformers/PostgresArrayEntityCteBuilder.js.map +1 -1
  20. package/dist/esm/src/transformers/PostgresJsonQueryBuilder.js +26 -21
  21. package/dist/esm/src/transformers/PostgresJsonQueryBuilder.js.map +1 -1
  22. package/dist/esm/src/transformers/PostgresObjectEntityCteBuilder.js +8 -5
  23. package/dist/esm/src/transformers/PostgresObjectEntityCteBuilder.js.map +1 -1
  24. package/dist/esm/src/transformers/SelectableColumnCollector.js +17 -5
  25. package/dist/esm/src/transformers/SelectableColumnCollector.js.map +1 -1
  26. package/dist/esm/src/transformers/SqlFormatter.js +1 -2
  27. package/dist/esm/src/transformers/SqlFormatter.js.map +1 -1
  28. package/dist/esm/src/transformers/TypeTransformationPostProcessor.js +342 -0
  29. package/dist/esm/src/transformers/TypeTransformationPostProcessor.js.map +1 -0
  30. package/dist/esm/src/transformers/UnifiedJsonMapping.js +57 -0
  31. package/dist/esm/src/transformers/UnifiedJsonMapping.js.map +1 -0
  32. package/dist/esm/src/transformers/UpstreamSelectQueryFinder.js +8 -1
  33. package/dist/esm/src/transformers/UpstreamSelectQueryFinder.js.map +1 -1
  34. package/dist/esm/src/utils/JsonSchemaValidator.js +211 -0
  35. package/dist/esm/src/utils/JsonSchemaValidator.js.map +1 -0
  36. package/dist/esm/src/utils/OperatorPrecedence.js +3 -1
  37. package/dist/esm/src/utils/OperatorPrecedence.js.map +1 -1
  38. package/dist/esm/src/utils/SchemaManager.js +0 -1
  39. package/dist/esm/src/utils/SchemaManager.js.map +1 -1
  40. package/dist/esm/tsconfig.browser.tsbuildinfo +1 -1
  41. package/dist/esm/types/src/index.d.ts +6 -0
  42. package/dist/esm/types/src/transformers/CTEDependencyTracer.d.ts +58 -0
  43. package/dist/esm/types/src/transformers/DynamicQueryBuilder.d.ts +108 -0
  44. package/dist/esm/types/src/transformers/JsonMappingUnifier.d.ts +95 -0
  45. package/dist/esm/types/src/transformers/ModelDrivenJsonMapping.d.ts +62 -0
  46. package/dist/esm/types/src/transformers/PostgresArrayEntityCteBuilder.d.ts +80 -1
  47. package/dist/esm/types/src/transformers/PostgresJsonQueryBuilder.d.ts +3 -2
  48. package/dist/esm/types/src/transformers/SelectableColumnCollector.d.ts +14 -3
  49. package/dist/esm/types/src/transformers/SqlFormatter.d.ts +2 -3
  50. package/dist/esm/types/src/transformers/TypeTransformationPostProcessor.d.ts +108 -0
  51. package/dist/esm/types/src/transformers/UnifiedJsonMapping.d.ts +53 -0
  52. package/dist/esm/types/src/transformers/UpstreamSelectQueryFinder.d.ts +5 -1
  53. package/dist/esm/types/src/utils/JsonSchemaValidator.d.ts +81 -0
  54. package/dist/index.min.js +16 -14
  55. package/dist/index.min.js.map +4 -4
  56. package/dist/src/index.d.ts +6 -0
  57. package/dist/src/index.js +14 -0
  58. package/dist/src/index.js.map +1 -1
  59. package/dist/src/tokenReaders/OperatorTokenReader.js +4 -0
  60. package/dist/src/tokenReaders/OperatorTokenReader.js.map +1 -1
  61. package/dist/src/transformers/CTEDependencyTracer.d.ts +58 -0
  62. package/dist/src/transformers/CTEDependencyTracer.js +253 -0
  63. package/dist/src/transformers/CTEDependencyTracer.js.map +1 -0
  64. package/dist/src/transformers/DynamicQueryBuilder.d.ts +108 -0
  65. package/dist/src/transformers/DynamicQueryBuilder.js +159 -0
  66. package/dist/src/transformers/DynamicQueryBuilder.js.map +1 -0
  67. package/dist/src/transformers/JsonMappingUnifier.d.ts +95 -0
  68. package/dist/src/transformers/JsonMappingUnifier.js +226 -0
  69. package/dist/src/transformers/JsonMappingUnifier.js.map +1 -0
  70. package/dist/src/transformers/ModelDrivenJsonMapping.d.ts +62 -0
  71. package/dist/src/transformers/ModelDrivenJsonMapping.js +110 -0
  72. package/dist/src/transformers/ModelDrivenJsonMapping.js.map +1 -0
  73. package/dist/src/transformers/PostgresArrayEntityCteBuilder.d.ts +80 -1
  74. package/dist/src/transformers/PostgresArrayEntityCteBuilder.js +204 -16
  75. package/dist/src/transformers/PostgresArrayEntityCteBuilder.js.map +1 -1
  76. package/dist/src/transformers/PostgresJsonQueryBuilder.d.ts +3 -2
  77. package/dist/src/transformers/PostgresJsonQueryBuilder.js +26 -21
  78. package/dist/src/transformers/PostgresJsonQueryBuilder.js.map +1 -1
  79. package/dist/src/transformers/PostgresObjectEntityCteBuilder.js +8 -5
  80. package/dist/src/transformers/PostgresObjectEntityCteBuilder.js.map +1 -1
  81. package/dist/src/transformers/SelectableColumnCollector.d.ts +14 -3
  82. package/dist/src/transformers/SelectableColumnCollector.js +17 -5
  83. package/dist/src/transformers/SelectableColumnCollector.js.map +1 -1
  84. package/dist/src/transformers/SqlFormatter.d.ts +2 -3
  85. package/dist/src/transformers/SqlFormatter.js +1 -2
  86. package/dist/src/transformers/SqlFormatter.js.map +1 -1
  87. package/dist/src/transformers/TypeTransformationPostProcessor.d.ts +108 -0
  88. package/dist/src/transformers/TypeTransformationPostProcessor.js +351 -0
  89. package/dist/src/transformers/TypeTransformationPostProcessor.js.map +1 -0
  90. package/dist/src/transformers/UnifiedJsonMapping.d.ts +53 -0
  91. package/dist/src/transformers/UnifiedJsonMapping.js +60 -0
  92. package/dist/src/transformers/UnifiedJsonMapping.js.map +1 -0
  93. package/dist/src/transformers/UpstreamSelectQueryFinder.d.ts +5 -1
  94. package/dist/src/transformers/UpstreamSelectQueryFinder.js +8 -1
  95. package/dist/src/transformers/UpstreamSelectQueryFinder.js.map +1 -1
  96. package/dist/src/utils/JsonSchemaValidator.d.ts +81 -0
  97. package/dist/src/utils/JsonSchemaValidator.js +215 -0
  98. package/dist/src/utils/JsonSchemaValidator.js.map +1 -0
  99. package/dist/src/utils/OperatorPrecedence.js +3 -1
  100. package/dist/src/utils/OperatorPrecedence.js.map +1 -1
  101. package/dist/src/utils/SchemaManager.js +0 -1
  102. package/dist/src/utils/SchemaManager.js.map +1 -1
  103. package/dist/tsconfig.tsbuildinfo +1 -1
  104. package/package.json +8 -5
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DynamicQueryBuilder = void 0;
4
+ const SelectQueryParser_1 = require("../parsers/SelectQueryParser");
5
+ const SqlParamInjector_1 = require("./SqlParamInjector");
6
+ const SqlSortInjector_1 = require("./SqlSortInjector");
7
+ const SqlPaginationInjector_1 = require("./SqlPaginationInjector");
8
+ const PostgresJsonQueryBuilder_1 = require("./PostgresJsonQueryBuilder");
9
+ const QueryBuilder_1 = require("./QueryBuilder");
10
+ /**
11
+ * DynamicQueryBuilder provides pure JavaScript SQL query building capabilities.
12
+ * It combines SQL parsing with dynamic condition injection (filtering, sorting, pagination, serialization).
13
+ *
14
+ * This class is framework-agnostic and does not perform any file I/O operations.
15
+ * It only works with SQL content provided as strings.
16
+ *
17
+ * Key features:
18
+ * - Pure JavaScript/TypeScript - no file system dependencies
19
+ * - Framework-agnostic - can be used with any database framework
20
+ * - Composable - combines multiple injectors in the correct order
21
+ * - Type-safe - provides TypeScript types for all options
22
+ * - Testable - easy to unit test without mocking file system
23
+ */
24
+ class DynamicQueryBuilder {
25
+ /**
26
+ * Creates a new DynamicQueryBuilder instance
27
+ * @param tableColumnResolver Optional function to resolve table columns for wildcard queries
28
+ */
29
+ constructor(tableColumnResolver) {
30
+ this.tableColumnResolver = tableColumnResolver;
31
+ }
32
+ /**
33
+ * Builds a SelectQuery from SQL content with dynamic conditions.
34
+ * This is a pure function that does not perform any I/O operations.
35
+ * * @param sqlContent Raw SQL string to parse and modify
36
+ * @param options Dynamic conditions to apply (filter, sort, paging, serialize)
37
+ * @returns Modified SelectQuery with all dynamic conditions applied
38
+ * * @example
39
+ * ```typescript
40
+ * const builder = new DynamicQueryBuilder();
41
+ * const query = builder.buildQuery(
42
+ * 'SELECT id, name FROM users WHERE active = true',
43
+ * {
44
+ * filter: { status: 'premium' },
45
+ * sort: { created_at: { desc: true } },
46
+ * paging: { page: 2, pageSize: 10 },
47
+ * serialize: { rootName: 'user', rootEntity: { id: 'user', name: 'User', columns: { id: 'id', name: 'name' } }, nestedEntities: [] }
48
+ * }
49
+ * );
50
+ * ```
51
+ */
52
+ buildQuery(sqlContent, options = {}) {
53
+ // Parse the base SQL
54
+ let parsedQuery;
55
+ try {
56
+ parsedQuery = SelectQueryParser_1.SelectQueryParser.parse(sqlContent);
57
+ }
58
+ catch (error) {
59
+ throw new Error(`Failed to parse SQL: ${error instanceof Error ? error.message : 'Unknown error'}`);
60
+ }
61
+ // Apply dynamic modifications in the correct order
62
+ let modifiedQuery = parsedQuery;
63
+ // 1. Apply filtering first (most selective, should reduce data early)
64
+ if (options.filter && Object.keys(options.filter).length > 0) {
65
+ const paramInjector = new SqlParamInjector_1.SqlParamInjector(this.tableColumnResolver);
66
+ // Ensure we have a SimpleSelectQuery for the injector
67
+ const simpleQuery = QueryBuilder_1.QueryBuilder.buildSimpleQuery(modifiedQuery);
68
+ modifiedQuery = paramInjector.inject(simpleQuery, options.filter);
69
+ }
70
+ // 2. Apply sorting second (after filtering to sort smaller dataset)
71
+ if (options.sort && Object.keys(options.sort).length > 0) {
72
+ const sortInjector = new SqlSortInjector_1.SqlSortInjector(this.tableColumnResolver);
73
+ // Ensure we have a SimpleSelectQuery for the injector
74
+ const simpleQuery = QueryBuilder_1.QueryBuilder.buildSimpleQuery(modifiedQuery);
75
+ modifiedQuery = sortInjector.inject(simpleQuery, options.sort);
76
+ } // 3. Apply pagination third (after filtering and sorting)
77
+ if (options.paging) {
78
+ const { page = 1, pageSize } = options.paging;
79
+ if (pageSize !== undefined) {
80
+ const paginationInjector = new SqlPaginationInjector_1.SqlPaginationInjector();
81
+ const paginationOptions = { page, pageSize };
82
+ // Ensure we have a SimpleSelectQuery for the injector
83
+ const simpleQuery = QueryBuilder_1.QueryBuilder.buildSimpleQuery(modifiedQuery);
84
+ modifiedQuery = paginationInjector.inject(simpleQuery, paginationOptions);
85
+ }
86
+ }
87
+ // 4. Apply serialization last (transform the final query structure to JSON)
88
+ // Note: boolean values are handled at RawSqlClient level for auto-loading
89
+ if (options.serialize && typeof options.serialize === 'object') {
90
+ const jsonBuilder = new PostgresJsonQueryBuilder_1.PostgresJsonQueryBuilder();
91
+ // Ensure we have a SimpleSelectQuery for the JSON builder
92
+ const simpleQuery = QueryBuilder_1.QueryBuilder.buildSimpleQuery(modifiedQuery);
93
+ modifiedQuery = jsonBuilder.buildJsonQuery(simpleQuery, options.serialize);
94
+ }
95
+ return modifiedQuery;
96
+ }
97
+ /**
98
+ * Builds a SelectQuery with only filtering applied.
99
+ * Convenience method for when you only need dynamic WHERE conditions.
100
+ *
101
+ * @param sqlContent Raw SQL string to parse and modify
102
+ * @param filter Filter conditions to apply
103
+ * @returns Modified SelectQuery with filter conditions applied
104
+ */
105
+ buildFilteredQuery(sqlContent, filter) {
106
+ return this.buildQuery(sqlContent, { filter });
107
+ }
108
+ /**
109
+ * Builds a SelectQuery with only sorting applied.
110
+ * Convenience method for when you only need dynamic ORDER BY clauses.
111
+ *
112
+ * @param sqlContent Raw SQL string to parse and modify
113
+ * @param sort Sort conditions to apply
114
+ * @returns Modified SelectQuery with sort conditions applied
115
+ */
116
+ buildSortedQuery(sqlContent, sort) {
117
+ return this.buildQuery(sqlContent, { sort });
118
+ } /**
119
+ * Builds a SelectQuery with only pagination applied.
120
+ * Convenience method for when you only need LIMIT/OFFSET clauses.
121
+ *
122
+ * @param sqlContent Raw SQL string to parse and modify
123
+ * @param paging Pagination options to apply
124
+ * @returns Modified SelectQuery with pagination applied
125
+ */
126
+ buildPaginatedQuery(sqlContent, paging) {
127
+ return this.buildQuery(sqlContent, { paging });
128
+ }
129
+ /**
130
+ * Builds a SelectQuery with only JSON serialization applied.
131
+ * Convenience method for when you only need hierarchical JSON transformation.
132
+ *
133
+ * @param sqlContent Raw SQL string to parse and modify
134
+ * @param serialize JSON mapping configuration to apply
135
+ * @returns Modified SelectQuery with JSON serialization applied
136
+ */
137
+ buildSerializedQuery(sqlContent, serialize) {
138
+ return this.buildQuery(sqlContent, { serialize });
139
+ }
140
+ /**
141
+ * Validates SQL content by attempting to parse it.
142
+ * Useful for testing SQL validity without applying any modifications.
143
+ *
144
+ * @param sqlContent Raw SQL string to validate
145
+ * @returns true if SQL is valid, throws error if invalid
146
+ * @throws Error if SQL cannot be parsed
147
+ */
148
+ validateSql(sqlContent) {
149
+ try {
150
+ SelectQueryParser_1.SelectQueryParser.parse(sqlContent);
151
+ return true;
152
+ }
153
+ catch (error) {
154
+ throw new Error(`Invalid SQL: ${error instanceof Error ? error.message : 'Unknown error'}`);
155
+ }
156
+ }
157
+ }
158
+ exports.DynamicQueryBuilder = DynamicQueryBuilder;
159
+ //# sourceMappingURL=DynamicQueryBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DynamicQueryBuilder.js","sourceRoot":"","sources":["../../../src/transformers/DynamicQueryBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Unified JSON Mapping processor that supports both legacy and model-driven formats.
3
+ *
4
+ * This module provides backward compatibility while encouraging migration to the model-driven format.
5
+ * It automatically detects the input format and normalizes to a consistent internal representation.
6
+ */
7
+ import { JsonMapping } from './PostgresJsonQueryBuilder';
8
+ import { ModelDrivenJsonMapping } from './ModelDrivenJsonMapping';
9
+ /**
10
+ * Unified mapping format that can handle both legacy and model-driven inputs.
11
+ */
12
+ export interface UnifiedMappingInput {
13
+ typeInfo?: {
14
+ interface: string;
15
+ importPath: string;
16
+ };
17
+ structure?: any;
18
+ protectedStringFields?: string[];
19
+ rootName?: string;
20
+ rootEntity?: any;
21
+ nestedEntities?: any[];
22
+ columns?: any;
23
+ relationships?: any;
24
+ }
25
+ /**
26
+ * Result of mapping format detection and conversion.
27
+ */
28
+ export interface MappingProcessResult {
29
+ format: 'model-driven' | 'unified' | 'legacy';
30
+ jsonMapping: JsonMapping;
31
+ originalInput: UnifiedMappingInput;
32
+ metadata?: {
33
+ typeInfo?: {
34
+ interface: string;
35
+ importPath: string;
36
+ };
37
+ protectedStringFields?: string[];
38
+ typeProtection?: any;
39
+ };
40
+ }
41
+ /**
42
+ * Detects the format of a JSON mapping configuration.
43
+ *
44
+ * @param input - The mapping configuration to analyze
45
+ * @returns The detected format type
46
+ */
47
+ export declare function detectMappingFormat(input: UnifiedMappingInput): 'model-driven' | 'unified' | 'legacy';
48
+ /**
49
+ * Main processor that unifies all JSON mapping formats into a consistent JsonMapping.
50
+ *
51
+ * Features:
52
+ * - Automatic format detection
53
+ * - Backward compatibility with all existing formats
54
+ * - Metadata preservation for advanced features
55
+ * - Zero external dependencies
56
+ *
57
+ * @param input - Any supported JSON mapping format
58
+ * @returns Unified processing result with JsonMapping and metadata
59
+ */
60
+ export declare function processJsonMapping(input: UnifiedMappingInput): MappingProcessResult;
61
+ /**
62
+ * Convenience function for direct JsonMapping extraction.
63
+ *
64
+ * @param input - Any supported JSON mapping format
65
+ * @returns JsonMapping ready for use with PostgresJsonQueryBuilder
66
+ */
67
+ export declare function unifyJsonMapping(input: UnifiedMappingInput): JsonMapping;
68
+ /**
69
+ * Type guard to check if input uses model-driven format.
70
+ *
71
+ * @param input - Mapping input to check
72
+ * @returns True if input is model-driven format
73
+ */
74
+ export declare function isModelDrivenFormat(input: UnifiedMappingInput): input is ModelDrivenJsonMapping;
75
+ /**
76
+ * Type guard to check if input uses unified format.
77
+ *
78
+ * @param input - Mapping input to check
79
+ * @returns True if input is unified format
80
+ */
81
+ export declare function isUnifiedFormat(input: UnifiedMappingInput): boolean;
82
+ /**
83
+ * Type guard to check if input uses legacy format.
84
+ *
85
+ * @param input - Mapping input to check
86
+ * @returns True if input is legacy format
87
+ */
88
+ export declare function isLegacyFormat(input: UnifiedMappingInput): boolean;
89
+ /**
90
+ * Migration helper that suggests upgrading to model-driven format.
91
+ *
92
+ * @param input - Current mapping configuration
93
+ * @returns Suggestions for migration (if applicable)
94
+ */
95
+ export declare function suggestModelDrivenMigration(input: UnifiedMappingInput): string[];
@@ -0,0 +1,226 @@
1
+ "use strict";
2
+ /**
3
+ * Unified JSON Mapping processor that supports both legacy and model-driven formats.
4
+ *
5
+ * This module provides backward compatibility while encouraging migration to the model-driven format.
6
+ * It automatically detects the input format and normalizes to a consistent internal representation.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.detectMappingFormat = detectMappingFormat;
10
+ exports.processJsonMapping = processJsonMapping;
11
+ exports.unifyJsonMapping = unifyJsonMapping;
12
+ exports.isModelDrivenFormat = isModelDrivenFormat;
13
+ exports.isUnifiedFormat = isUnifiedFormat;
14
+ exports.isLegacyFormat = isLegacyFormat;
15
+ exports.suggestModelDrivenMigration = suggestModelDrivenMigration;
16
+ const ModelDrivenJsonMapping_1 = require("./ModelDrivenJsonMapping");
17
+ /**
18
+ * Detects the format of a JSON mapping configuration.
19
+ *
20
+ * @param input - The mapping configuration to analyze
21
+ * @returns The detected format type
22
+ */
23
+ function detectMappingFormat(input) {
24
+ // Model-driven format: has typeInfo and structure
25
+ if (input.typeInfo && input.structure) {
26
+ return 'model-driven';
27
+ }
28
+ // Unified format: has rootName and rootEntity
29
+ if (input.rootName && input.rootEntity) {
30
+ return 'unified';
31
+ }
32
+ // Legacy format: direct JsonMapping structure
33
+ if (input.columns || input.relationships) {
34
+ return 'legacy';
35
+ }
36
+ // Default fallback
37
+ return 'legacy';
38
+ }
39
+ /**
40
+ * Converts legacy unified format to JsonMapping.
41
+ *
42
+ * @param input - Unified format mapping configuration
43
+ * @returns Converted JsonMapping
44
+ */
45
+ function convertUnifiedFormat(input) {
46
+ if (!input.rootEntity) {
47
+ throw new Error('Unified format requires rootEntity');
48
+ }
49
+ const result = {
50
+ rootName: input.rootName || 'root',
51
+ rootEntity: {
52
+ id: input.rootEntity.id || 'root',
53
+ name: input.rootEntity.name || 'Root',
54
+ columns: input.rootEntity.columns || {}
55
+ },
56
+ nestedEntities: []
57
+ };
58
+ // Convert nestedEntities
59
+ if (input.nestedEntities && Array.isArray(input.nestedEntities)) {
60
+ result.nestedEntities = input.nestedEntities.map(entity => ({
61
+ id: entity.id || entity.propertyName || 'nested',
62
+ name: entity.name || entity.propertyName || 'Nested',
63
+ parentId: entity.parentId || result.rootEntity.id,
64
+ propertyName: entity.propertyName || 'nested',
65
+ relationshipType: entity.relationshipType || 'object',
66
+ columns: entity.columns || {}
67
+ }));
68
+ }
69
+ return result;
70
+ }
71
+ /**
72
+ * Converts legacy format directly to JsonMapping.
73
+ *
74
+ * @param input - Legacy format mapping configuration
75
+ * @returns JsonMapping
76
+ */
77
+ function convertLegacyFormat(input) {
78
+ const result = {
79
+ rootName: input.rootName || 'root',
80
+ rootEntity: {
81
+ id: 'root',
82
+ name: input.rootName || 'Root',
83
+ columns: input.columns || {}
84
+ },
85
+ nestedEntities: []
86
+ };
87
+ // Convert relationships to nestedEntities
88
+ if (input.relationships && typeof input.relationships === 'object') {
89
+ for (const [propertyName, relationship] of Object.entries(input.relationships)) {
90
+ // Type assertion for legacy relationship format
91
+ const rel = relationship;
92
+ result.nestedEntities.push({
93
+ id: propertyName,
94
+ name: propertyName.charAt(0).toUpperCase() + propertyName.slice(1),
95
+ parentId: 'root',
96
+ propertyName,
97
+ relationshipType: rel.type === 'hasMany' ? 'array' : 'object',
98
+ columns: rel.columns || {}
99
+ });
100
+ }
101
+ }
102
+ return result;
103
+ }
104
+ /**
105
+ * Main processor that unifies all JSON mapping formats into a consistent JsonMapping.
106
+ *
107
+ * Features:
108
+ * - Automatic format detection
109
+ * - Backward compatibility with all existing formats
110
+ * - Metadata preservation for advanced features
111
+ * - Zero external dependencies
112
+ *
113
+ * @param input - Any supported JSON mapping format
114
+ * @returns Unified processing result with JsonMapping and metadata
115
+ */
116
+ function processJsonMapping(input) {
117
+ const format = detectMappingFormat(input);
118
+ let jsonMapping;
119
+ let metadata = {};
120
+ try {
121
+ switch (format) {
122
+ case 'model-driven':
123
+ // Validate model-driven input
124
+ if (!input.typeInfo || !input.structure) {
125
+ throw new Error('Model-driven format requires typeInfo and structure fields');
126
+ }
127
+ // Convert model-driven to JsonMapping
128
+ const modelDrivenInput = {
129
+ typeInfo: input.typeInfo,
130
+ structure: input.structure
131
+ };
132
+ const converted = (0, ModelDrivenJsonMapping_1.convertModelDrivenMapping)(modelDrivenInput);
133
+ jsonMapping = converted.jsonMapping;
134
+ // Preserve metadata
135
+ metadata = {
136
+ typeInfo: input.typeInfo,
137
+ typeProtection: converted.typeProtection
138
+ };
139
+ break;
140
+ case 'unified':
141
+ // Validate unified input
142
+ if (!input.rootEntity) {
143
+ throw new Error('Unified format requires rootEntity field');
144
+ }
145
+ jsonMapping = convertUnifiedFormat(input);
146
+ break;
147
+ case 'legacy':
148
+ // Validate legacy input
149
+ if (!input.columns && !input.relationships) {
150
+ throw new Error('Legacy format requires at least columns or relationships field');
151
+ }
152
+ jsonMapping = convertLegacyFormat(input);
153
+ break;
154
+ default:
155
+ throw new Error(`Unsupported mapping format: ${format}`);
156
+ }
157
+ return {
158
+ format,
159
+ jsonMapping,
160
+ originalInput: input,
161
+ metadata
162
+ };
163
+ }
164
+ catch (error) {
165
+ throw new Error(`Failed to process JSON mapping (format: ${format}): ${error instanceof Error ? error.message : String(error)}`);
166
+ }
167
+ }
168
+ /**
169
+ * Convenience function for direct JsonMapping extraction.
170
+ *
171
+ * @param input - Any supported JSON mapping format
172
+ * @returns JsonMapping ready for use with PostgresJsonQueryBuilder
173
+ */
174
+ function unifyJsonMapping(input) {
175
+ return processJsonMapping(input).jsonMapping;
176
+ }
177
+ /**
178
+ * Type guard to check if input uses model-driven format.
179
+ *
180
+ * @param input - Mapping input to check
181
+ * @returns True if input is model-driven format
182
+ */
183
+ function isModelDrivenFormat(input) {
184
+ return detectMappingFormat(input) === 'model-driven';
185
+ }
186
+ /**
187
+ * Type guard to check if input uses unified format.
188
+ *
189
+ * @param input - Mapping input to check
190
+ * @returns True if input is unified format
191
+ */
192
+ function isUnifiedFormat(input) {
193
+ return detectMappingFormat(input) === 'unified';
194
+ }
195
+ /**
196
+ * Type guard to check if input uses legacy format.
197
+ *
198
+ * @param input - Mapping input to check
199
+ * @returns True if input is legacy format
200
+ */
201
+ function isLegacyFormat(input) {
202
+ return detectMappingFormat(input) === 'legacy';
203
+ }
204
+ /**
205
+ * Migration helper that suggests upgrading to model-driven format.
206
+ *
207
+ * @param input - Current mapping configuration
208
+ * @returns Suggestions for migration (if applicable)
209
+ */
210
+ function suggestModelDrivenMigration(input) {
211
+ const format = detectMappingFormat(input);
212
+ const suggestions = [];
213
+ if (format !== 'model-driven') {
214
+ suggestions.push('Consider migrating to model-driven JSON mapping format');
215
+ suggestions.push('Benefits: Better type safety, IDE support, and future-proof design');
216
+ suggestions.push('See: Model-Driven JSON Mapping Guide for migration instructions');
217
+ if (format === 'unified') {
218
+ suggestions.push('Your current unified format can be automatically converted');
219
+ }
220
+ if (format === 'legacy') {
221
+ suggestions.push('Legacy format support will be maintained but new features target model-driven format');
222
+ }
223
+ }
224
+ return suggestions;
225
+ }
226
+ //# sourceMappingURL=JsonMappingUnifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonMappingUnifier.js","sourceRoot":"","sources":["../../../src/transformers/JsonMappingUnifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Model-driven JSON mapping structure that mirrors TypeScript model definitions.
3
+ * This approach provides intuitive, hierarchical mapping that closely resembles the target data structure.
4
+ */
5
+ import { JsonMapping } from './PostgresJsonQueryBuilder';
6
+ /**
7
+ * Supported field types for database column mapping.
8
+ */
9
+ export type FieldType = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'auto';
10
+ /**
11
+ * Field mapping configuration that can be either a simple column name or enhanced mapping with type control.
12
+ */
13
+ export type FieldMapping = string | {
14
+ column: string;
15
+ type?: FieldType;
16
+ } | {
17
+ from: string;
18
+ type?: FieldType;
19
+ };
20
+ /**
21
+ * Nested object or array structure definition.
22
+ */
23
+ export interface NestedStructure {
24
+ type: 'object' | 'array';
25
+ from: string;
26
+ structure: StructureFields;
27
+ }
28
+ /**
29
+ * Structure fields can contain either field mappings or nested structures.
30
+ */
31
+ export type StructureFields = {
32
+ [key: string]: FieldMapping | NestedStructure;
33
+ };
34
+ /**
35
+ * Model-driven JSON mapping that mirrors TypeScript interface structure.
36
+ * This design makes it easy to understand the relationship between models and database columns.
37
+ */
38
+ export interface ModelDrivenJsonMapping {
39
+ typeInfo: {
40
+ interface: string;
41
+ importPath: string;
42
+ };
43
+ structure: StructureFields;
44
+ }
45
+ /**
46
+ * Type protection configuration extracted from the model-driven mapping.
47
+ */
48
+ export interface TypeProtectionConfig {
49
+ protectedStringFields: string[];
50
+ }
51
+ /**
52
+ * Convert a model-driven JSON mapping to the traditional JsonMapping format.
53
+ * This enables backward compatibility with existing PostgresJsonQueryBuilder.
54
+ */
55
+ export declare function convertModelDrivenMapping(modelMapping: ModelDrivenJsonMapping): {
56
+ jsonMapping: JsonMapping;
57
+ typeProtection: TypeProtectionConfig;
58
+ };
59
+ /**
60
+ * Validate that a model-driven mapping structure is well-formed.
61
+ */
62
+ export declare function validateModelDrivenMapping(mapping: ModelDrivenJsonMapping): string[];
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ /**
3
+ * Model-driven JSON mapping structure that mirrors TypeScript model definitions.
4
+ * This approach provides intuitive, hierarchical mapping that closely resembles the target data structure.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.convertModelDrivenMapping = convertModelDrivenMapping;
8
+ exports.validateModelDrivenMapping = validateModelDrivenMapping;
9
+ /**
10
+ * Convert a model-driven JSON mapping to the traditional JsonMapping format.
11
+ * This enables backward compatibility with existing PostgresJsonQueryBuilder.
12
+ */
13
+ function convertModelDrivenMapping(modelMapping) {
14
+ const protectedStringFields = [];
15
+ let entityIdCounter = 0;
16
+ // Generate unique entity IDs
17
+ const generateEntityId = () => `entity_${++entityIdCounter}`;
18
+ // Helper function to process structure fields and extract entities
19
+ const processStructure = (structure, parentId = null) => {
20
+ const columns = {};
21
+ const nestedEntities = [];
22
+ for (const [fieldName, config] of Object.entries(structure)) {
23
+ if (typeof config === 'string') {
24
+ // Simple field mapping: "fieldName": "column_name"
25
+ columns[fieldName] = config;
26
+ }
27
+ else if ('column' in config && typeof config.column === 'string' && !('type' in config && (config.type === 'object' || config.type === 'array'))) {
28
+ // Enhanced field mapping: "fieldName": { "column": "column_name", "type": "string" }
29
+ const fieldConfig = config;
30
+ if (typeof fieldConfig === 'object' && 'column' in fieldConfig) {
31
+ columns[fieldName] = fieldConfig.column;
32
+ if (fieldConfig.type === 'string') {
33
+ protectedStringFields.push(fieldConfig.column);
34
+ }
35
+ }
36
+ }
37
+ else if ('from' in config && typeof config.from === 'string' && !('type' in config && (config.type === 'object' || config.type === 'array'))) {
38
+ // Legacy field mapping: "fieldName": { "from": "column_name", "type": "string" }
39
+ const fieldConfig = config;
40
+ if (typeof fieldConfig === 'object' && 'from' in fieldConfig) {
41
+ columns[fieldName] = fieldConfig.from;
42
+ if (fieldConfig.type === 'string') {
43
+ protectedStringFields.push(fieldConfig.from);
44
+ }
45
+ }
46
+ }
47
+ else if ('type' in config && (config.type === 'object' || config.type === 'array')) {
48
+ // Nested structure: object or array
49
+ const nestedStructure = config;
50
+ const entityId = generateEntityId();
51
+ const processedNested = processStructure(nestedStructure.structure, entityId);
52
+ nestedEntities.push({
53
+ id: entityId,
54
+ name: fieldName.charAt(0).toUpperCase() + fieldName.slice(1), // Capitalize first letter
55
+ parentId: parentId || 'root',
56
+ propertyName: fieldName,
57
+ relationshipType: nestedStructure.type,
58
+ columns: processedNested.columns
59
+ });
60
+ // Add nested entities from deeper levels
61
+ nestedEntities.push(...processedNested.nestedEntities.map(entity => ({
62
+ ...entity,
63
+ parentId: entity.parentId === 'root' ? entityId : entity.parentId
64
+ })));
65
+ }
66
+ }
67
+ return { columns, nestedEntities };
68
+ };
69
+ // Process the root structure
70
+ const processed = processStructure(modelMapping.structure); // Build the traditional JsonMapping
71
+ const jsonMapping = {
72
+ rootName: 'root', // Default root name
73
+ rootEntity: {
74
+ id: 'root',
75
+ name: 'Root',
76
+ columns: processed.columns
77
+ },
78
+ nestedEntities: processed.nestedEntities
79
+ };
80
+ // Add typeInfo for backward compatibility
81
+ jsonMapping.typeInfo = modelMapping.typeInfo;
82
+ return {
83
+ jsonMapping,
84
+ typeProtection: { protectedStringFields }
85
+ };
86
+ }
87
+ /**
88
+ * Validate that a model-driven mapping structure is well-formed.
89
+ */
90
+ function validateModelDrivenMapping(mapping) {
91
+ const errors = [];
92
+ // Validate typeInfo
93
+ if (!mapping.typeInfo) {
94
+ errors.push('typeInfo is required');
95
+ }
96
+ else {
97
+ if (!mapping.typeInfo.interface) {
98
+ errors.push('typeInfo.interface is required');
99
+ }
100
+ if (!mapping.typeInfo.importPath) {
101
+ errors.push('typeInfo.importPath is required');
102
+ }
103
+ }
104
+ // Validate structure
105
+ if (!mapping.structure || typeof mapping.structure !== 'object') {
106
+ errors.push('structure is required and must be an object');
107
+ }
108
+ return errors;
109
+ }
110
+ //# sourceMappingURL=ModelDrivenJsonMapping.js.map