rawsql-ts 0.11.1-beta → 0.11.3-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.
- package/README.md +735 -682
- package/dist/esm/index.js +8 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +46 -12
- package/dist/esm/index.min.js.map +4 -4
- package/dist/esm/src/index.js +8 -2
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/models/BinarySelectQuery.js +9 -0
- package/dist/esm/src/models/BinarySelectQuery.js.map +1 -1
- package/dist/esm/src/models/CTEError.js +31 -0
- package/dist/esm/src/models/CTEError.js.map +1 -0
- package/dist/esm/src/models/SelectQuery.js +1 -0
- package/dist/esm/src/models/SelectQuery.js.map +1 -1
- package/dist/esm/src/models/SimpleSelectQuery.js +229 -0
- package/dist/esm/src/models/SimpleSelectQuery.js.map +1 -1
- package/dist/esm/src/models/ValuesQuery.js +1 -1
- package/dist/esm/src/models/ValuesQuery.js.map +1 -1
- package/dist/esm/src/parsers/ValueParser.js +86 -4
- package/dist/esm/src/parsers/ValueParser.js.map +1 -1
- package/dist/esm/src/transformers/DynamicQueryBuilder.js.map +1 -1
- package/dist/esm/src/transformers/EnhancedJsonMapping.js +217 -0
- package/dist/esm/src/transformers/EnhancedJsonMapping.js.map +1 -0
- package/dist/esm/src/transformers/JsonMappingConverter.js +388 -0
- package/dist/esm/src/transformers/JsonMappingConverter.js.map +1 -0
- package/dist/esm/src/transformers/JsonMappingUnifier.js +36 -46
- package/dist/esm/src/transformers/JsonMappingUnifier.js.map +1 -1
- package/dist/esm/src/transformers/ModelDrivenJsonMapping.js +14 -2
- package/dist/esm/src/transformers/ModelDrivenJsonMapping.js.map +1 -1
- package/dist/esm/src/transformers/PostgresArrayEntityCteBuilder.js +132 -97
- package/dist/esm/src/transformers/PostgresArrayEntityCteBuilder.js.map +1 -1
- package/dist/esm/src/transformers/PostgresJsonQueryBuilder.js +21 -11
- package/dist/esm/src/transformers/PostgresJsonQueryBuilder.js.map +1 -1
- package/dist/esm/src/transformers/PostgresObjectEntityCteBuilder.js +71 -14
- package/dist/esm/src/transformers/PostgresObjectEntityCteBuilder.js.map +1 -1
- package/dist/esm/src/transformers/QueryBuilder.js +2 -0
- package/dist/esm/src/transformers/QueryBuilder.js.map +1 -1
- package/dist/esm/src/transformers/SqlParamInjector.js +189 -108
- package/dist/esm/src/transformers/SqlParamInjector.js.map +1 -1
- package/dist/esm/src/transformers/UpstreamSelectQueryFinder.js +43 -2
- package/dist/esm/src/transformers/UpstreamSelectQueryFinder.js.map +1 -1
- package/dist/esm/tsconfig.browser.tsbuildinfo +1 -1
- package/dist/esm/types/src/index.d.ts +8 -2
- package/dist/esm/types/src/models/BinarySelectQuery.d.ts +7 -0
- package/dist/esm/types/src/models/CTEError.d.ts +21 -0
- package/dist/esm/types/src/models/SelectQuery.d.ts +12 -0
- package/dist/esm/types/src/models/SimpleSelectQuery.d.ts +166 -2
- package/dist/esm/types/src/models/ValuesQuery.d.ts +1 -1
- package/dist/esm/types/src/parsers/ValueParser.d.ts +8 -0
- package/dist/esm/types/src/transformers/DynamicQueryBuilder.d.ts +6 -0
- package/dist/esm/types/src/transformers/EnhancedJsonMapping.d.ts +194 -0
- package/dist/esm/types/src/transformers/JsonMappingConverter.d.ts +200 -0
- package/dist/esm/types/src/transformers/JsonMappingUnifier.d.ts +5 -0
- package/dist/esm/types/src/transformers/PostgresArrayEntityCteBuilder.d.ts +39 -77
- package/dist/esm/types/src/transformers/PostgresJsonQueryBuilder.d.ts +3 -2
- package/dist/esm/types/src/transformers/PostgresObjectEntityCteBuilder.d.ts +31 -6
- package/dist/esm/types/src/transformers/SqlParamInjector.d.ts +48 -0
- package/dist/esm/types/src/transformers/UpstreamSelectQueryFinder.d.ts +8 -0
- package/dist/index.min.js +46 -12
- package/dist/index.min.js.map +4 -4
- package/dist/src/index.d.ts +8 -2
- package/dist/src/index.js +8 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/models/BinarySelectQuery.d.ts +7 -0
- package/dist/src/models/BinarySelectQuery.js +9 -0
- package/dist/src/models/BinarySelectQuery.js.map +1 -1
- package/dist/src/models/CTEError.d.ts +21 -0
- package/dist/src/models/CTEError.js +37 -0
- package/dist/src/models/CTEError.js.map +1 -0
- package/dist/src/models/SelectQuery.d.ts +12 -0
- package/dist/src/models/SelectQuery.js +5 -1
- package/dist/src/models/SelectQuery.js.map +1 -1
- package/dist/src/models/SimpleSelectQuery.d.ts +166 -2
- package/dist/src/models/SimpleSelectQuery.js +229 -0
- package/dist/src/models/SimpleSelectQuery.js.map +1 -1
- package/dist/src/models/ValuesQuery.d.ts +1 -1
- package/dist/src/models/ValuesQuery.js +1 -1
- package/dist/src/models/ValuesQuery.js.map +1 -1
- package/dist/src/parsers/ValueParser.d.ts +8 -0
- package/dist/src/parsers/ValueParser.js +86 -4
- package/dist/src/parsers/ValueParser.js.map +1 -1
- package/dist/src/transformers/DynamicQueryBuilder.d.ts +6 -0
- package/dist/src/transformers/DynamicQueryBuilder.js.map +1 -1
- package/dist/src/transformers/EnhancedJsonMapping.d.ts +194 -0
- package/dist/src/transformers/EnhancedJsonMapping.js +223 -0
- package/dist/src/transformers/EnhancedJsonMapping.js.map +1 -0
- package/dist/src/transformers/JsonMappingConverter.d.ts +200 -0
- package/dist/src/transformers/JsonMappingConverter.js +392 -0
- package/dist/src/transformers/JsonMappingConverter.js.map +1 -0
- package/dist/src/transformers/JsonMappingUnifier.d.ts +5 -0
- package/dist/src/transformers/JsonMappingUnifier.js +36 -46
- package/dist/src/transformers/JsonMappingUnifier.js.map +1 -1
- package/dist/src/transformers/ModelDrivenJsonMapping.js +14 -2
- package/dist/src/transformers/ModelDrivenJsonMapping.js.map +1 -1
- package/dist/src/transformers/PostgresArrayEntityCteBuilder.d.ts +39 -77
- package/dist/src/transformers/PostgresArrayEntityCteBuilder.js +132 -97
- package/dist/src/transformers/PostgresArrayEntityCteBuilder.js.map +1 -1
- package/dist/src/transformers/PostgresJsonQueryBuilder.d.ts +3 -2
- package/dist/src/transformers/PostgresJsonQueryBuilder.js +21 -11
- package/dist/src/transformers/PostgresJsonQueryBuilder.js.map +1 -1
- package/dist/src/transformers/PostgresObjectEntityCteBuilder.d.ts +31 -6
- package/dist/src/transformers/PostgresObjectEntityCteBuilder.js +71 -14
- package/dist/src/transformers/PostgresObjectEntityCteBuilder.js.map +1 -1
- package/dist/src/transformers/QueryBuilder.js +2 -0
- package/dist/src/transformers/QueryBuilder.js.map +1 -1
- package/dist/src/transformers/SqlParamInjector.d.ts +48 -0
- package/dist/src/transformers/SqlParamInjector.js +189 -108
- package/dist/src/transformers/SqlParamInjector.js.map +1 -1
- package/dist/src/transformers/UpstreamSelectQueryFinder.d.ts +8 -0
- package/dist/src/transformers/UpstreamSelectQueryFinder.js +43 -2
- package/dist/src/transformers/UpstreamSelectQueryFinder.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -19,4 +19,12 @@ export declare class ValueParser {
|
|
|
19
19
|
value: ValueComponent;
|
|
20
20
|
newIndex: number;
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Determines if a type token followed by parentheses is a type constructor or function call
|
|
24
|
+
* @param lexemes Array of lexemes
|
|
25
|
+
* @param openParenIndex Index of the opening parenthesis
|
|
26
|
+
* @param typeName Name of the type/function
|
|
27
|
+
* @returns True if this is a type constructor, false if it's a function call
|
|
28
|
+
*/
|
|
29
|
+
private static isTypeConstructor;
|
|
22
30
|
}
|
|
@@ -18,6 +18,12 @@ export interface QueryBuildOptions {
|
|
|
18
18
|
* - false/undefined: no serialization
|
|
19
19
|
*/
|
|
20
20
|
serialize?: JsonMapping | boolean;
|
|
21
|
+
/**
|
|
22
|
+
* JSONB usage setting. Must be true (default) for PostgreSQL GROUP BY compatibility.
|
|
23
|
+
* Setting to false will throw an error as JSON type cannot be used in GROUP BY clauses.
|
|
24
|
+
* @default true
|
|
25
|
+
*/
|
|
26
|
+
jsonb?: boolean;
|
|
21
27
|
}
|
|
22
28
|
/**
|
|
23
29
|
* DynamicQueryBuilder provides pure JavaScript SQL query building capabilities.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced JSON mapping structure that extends the base JsonMapping interface
|
|
3
|
+
* with additional metadata and type safety features.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Supported column types for enhanced mapping.
|
|
7
|
+
*/
|
|
8
|
+
export type ColumnType = 'string' | 'number' | 'boolean' | 'date' | 'auto';
|
|
9
|
+
/**
|
|
10
|
+
* Enhanced column configuration that supports both simple and complex mappings.
|
|
11
|
+
*/
|
|
12
|
+
export interface ColumnConfig {
|
|
13
|
+
/** Source column name */
|
|
14
|
+
column: string;
|
|
15
|
+
/** Type enforcement for this column */
|
|
16
|
+
type?: ColumnType;
|
|
17
|
+
/** Whether this field is nullable */
|
|
18
|
+
nullable?: boolean;
|
|
19
|
+
/** Custom transformation function */
|
|
20
|
+
transform?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Column mapping can be either a simple string or enhanced configuration.
|
|
24
|
+
*/
|
|
25
|
+
export type ColumnMapping = string | ColumnConfig;
|
|
26
|
+
/**
|
|
27
|
+
* Enhanced entity definition with additional metadata.
|
|
28
|
+
*/
|
|
29
|
+
export interface EnhancedEntity {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
columns: Record<string, ColumnMapping>;
|
|
33
|
+
/** Entity description for documentation */
|
|
34
|
+
description?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Enhanced nested entity with relationship metadata.
|
|
38
|
+
*/
|
|
39
|
+
export interface EnhancedNestedEntity extends EnhancedEntity {
|
|
40
|
+
parentId: string;
|
|
41
|
+
propertyName: string;
|
|
42
|
+
relationshipType: 'object' | 'array';
|
|
43
|
+
/** Join condition for complex relationships */
|
|
44
|
+
joinCondition?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Type protection configuration.
|
|
48
|
+
*/
|
|
49
|
+
export interface TypeProtectionConfig {
|
|
50
|
+
/** Columns that should be treated as strings */
|
|
51
|
+
protectedStringFields: string[];
|
|
52
|
+
/** Columns that should be parsed as dates */
|
|
53
|
+
dateFields?: string[];
|
|
54
|
+
/** Columns that should be parsed as numbers */
|
|
55
|
+
numberFields?: string[];
|
|
56
|
+
/** Custom type transformations */
|
|
57
|
+
customTransforms?: Record<string, string>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Enhanced JSON mapping with type safety and metadata support.
|
|
61
|
+
*/
|
|
62
|
+
export interface EnhancedJsonMapping {
|
|
63
|
+
/** Root entity name */
|
|
64
|
+
rootName: string;
|
|
65
|
+
/** Root entity definition */
|
|
66
|
+
rootEntity: EnhancedEntity;
|
|
67
|
+
/** Nested entities */
|
|
68
|
+
nestedEntities: EnhancedNestedEntity[];
|
|
69
|
+
/** Result format */
|
|
70
|
+
resultFormat?: 'array' | 'single';
|
|
71
|
+
/** Empty result fallback */
|
|
72
|
+
emptyResult?: string;
|
|
73
|
+
/** Type information */
|
|
74
|
+
typeInfo?: {
|
|
75
|
+
interface: string;
|
|
76
|
+
importPath: string;
|
|
77
|
+
generics?: string[];
|
|
78
|
+
};
|
|
79
|
+
/** Type protection configuration */
|
|
80
|
+
typeProtection?: TypeProtectionConfig;
|
|
81
|
+
/** Mapping metadata */
|
|
82
|
+
metadata?: {
|
|
83
|
+
version: string;
|
|
84
|
+
description?: string;
|
|
85
|
+
author?: string;
|
|
86
|
+
createdAt?: string;
|
|
87
|
+
updatedAt?: string;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Legacy JSON mapping interface (from PostgresJsonQueryBuilder).
|
|
92
|
+
*/
|
|
93
|
+
export interface LegacyJsonMapping {
|
|
94
|
+
rootName: string;
|
|
95
|
+
rootEntity: {
|
|
96
|
+
id: string;
|
|
97
|
+
name: string;
|
|
98
|
+
columns: {
|
|
99
|
+
[jsonKey: string]: string;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
nestedEntities: Array<{
|
|
103
|
+
id: string;
|
|
104
|
+
name: string;
|
|
105
|
+
parentId: string;
|
|
106
|
+
propertyName: string;
|
|
107
|
+
relationshipType?: "object" | "array";
|
|
108
|
+
columns: {
|
|
109
|
+
[jsonKey: string]: string;
|
|
110
|
+
};
|
|
111
|
+
}>;
|
|
112
|
+
resultFormat?: "array" | "single";
|
|
113
|
+
emptyResult?: string;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Converts enhanced column configurations to simple string mappings for legacy compatibility.
|
|
117
|
+
*
|
|
118
|
+
* This function transforms complex column configurations (with type info, nullable flags, etc.)
|
|
119
|
+
* into simple string mappings that can be used with PostgresJsonQueryBuilder.
|
|
120
|
+
*
|
|
121
|
+
* **Supported Input Formats:**
|
|
122
|
+
* - Simple strings: `"user_name"` → `"user_name"`
|
|
123
|
+
* - Column config: `{ column: "u.name", type: "string" }` → `"u.name"`
|
|
124
|
+
* - From config: `{ from: "user_name", nullable: true }` → `"user_name"`
|
|
125
|
+
*
|
|
126
|
+
* @param columns - Record of field names to column configurations
|
|
127
|
+
* @returns Record of field names to column source strings
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* const enhanced = {
|
|
132
|
+
* id: { column: "u.user_id", type: "number" },
|
|
133
|
+
* name: { from: "user_name", type: "string" },
|
|
134
|
+
* email: "email_address"
|
|
135
|
+
* };
|
|
136
|
+
*
|
|
137
|
+
* const legacy = convertColumnsToLegacy(enhanced);
|
|
138
|
+
* // Result: { id: "u.user_id", name: "user_name", email: "email_address" }
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export declare function convertColumnsToLegacy(columns: Record<string, any>): Record<string, string>;
|
|
142
|
+
/**
|
|
143
|
+
* Converts any unified JSON mapping format to legacy JsonMapping format.
|
|
144
|
+
*
|
|
145
|
+
* This universal converter handles Enhanced, Unified, and Legacy formats, providing
|
|
146
|
+
* a single interface for converting complex mapping configurations to the simple
|
|
147
|
+
* format expected by PostgresJsonQueryBuilder.
|
|
148
|
+
*
|
|
149
|
+
* **Supported Input Formats:**
|
|
150
|
+
* - **Enhanced**: With metadata, type protection, and advanced column configs
|
|
151
|
+
* - **Unified**: Standard format with rootName and rootEntity
|
|
152
|
+
* - **Legacy**: Already compatible format (returned as-is)
|
|
153
|
+
*
|
|
154
|
+
* **Features:**
|
|
155
|
+
* - Automatic format detection
|
|
156
|
+
* - Column configuration simplification
|
|
157
|
+
* - Nested entity handling
|
|
158
|
+
* - Type protection extraction
|
|
159
|
+
*
|
|
160
|
+
* @param input - JSON mapping in any supported format
|
|
161
|
+
* @returns Legacy JsonMapping compatible with PostgresJsonQueryBuilder
|
|
162
|
+
*
|
|
163
|
+
* @throws {Error} When input is null, undefined, or malformed
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* // Enhanced format input
|
|
168
|
+
* const enhanced = {
|
|
169
|
+
* rootName: "User",
|
|
170
|
+
* rootEntity: {
|
|
171
|
+
* columns: {
|
|
172
|
+
* id: { column: "u.user_id", type: "number" },
|
|
173
|
+
* name: { column: "u.user_name", type: "string" }
|
|
174
|
+
* }
|
|
175
|
+
* },
|
|
176
|
+
* metadata: { version: "2.0" }
|
|
177
|
+
* };
|
|
178
|
+
*
|
|
179
|
+
* const legacy = convertToLegacyJsonMapping(enhanced);
|
|
180
|
+
* // Result: Compatible with PostgresJsonQueryBuilder
|
|
181
|
+
* ```
|
|
182
|
+
*
|
|
183
|
+
* @see {@link convertColumnsToLegacy} For column-specific conversion
|
|
184
|
+
* @see {@link extractTypeProtection} For type safety features
|
|
185
|
+
*/
|
|
186
|
+
export declare function convertToLegacyJsonMapping(input: any): LegacyJsonMapping;
|
|
187
|
+
/**
|
|
188
|
+
* Converts enhanced mapping to legacy format for backward compatibility.
|
|
189
|
+
*/
|
|
190
|
+
export declare function toLegacyMapping(enhanced: EnhancedJsonMapping): LegacyJsonMapping;
|
|
191
|
+
/**
|
|
192
|
+
* Extracts type protection configuration from enhanced mapping.
|
|
193
|
+
*/
|
|
194
|
+
export declare function extractTypeProtection(enhanced: EnhancedJsonMapping): TypeProtectionConfig;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified JSON mapping converter that handles all supported formats
|
|
3
|
+
* and provides a single interface for mapping transformations.
|
|
4
|
+
*/
|
|
5
|
+
import { JsonMapping } from './PostgresJsonQueryBuilder';
|
|
6
|
+
import { ModelDrivenJsonMapping } from './ModelDrivenJsonMapping';
|
|
7
|
+
import { EnhancedJsonMapping, LegacyJsonMapping, TypeProtectionConfig } from './EnhancedJsonMapping';
|
|
8
|
+
/**
|
|
9
|
+
* Input format types that the converter can handle.
|
|
10
|
+
*/
|
|
11
|
+
export type JsonMappingInput = EnhancedJsonMapping | ModelDrivenJsonMapping | LegacyJsonMapping;
|
|
12
|
+
/**
|
|
13
|
+
* Format detection result.
|
|
14
|
+
*/
|
|
15
|
+
export type MappingFormat = 'enhanced' | 'model-driven' | 'legacy';
|
|
16
|
+
/**
|
|
17
|
+
* Conversion result with metadata.
|
|
18
|
+
*/
|
|
19
|
+
export interface ConversionResult {
|
|
20
|
+
/** Detected input format */
|
|
21
|
+
format: MappingFormat;
|
|
22
|
+
/** Converted legacy mapping for PostgresJsonQueryBuilder */
|
|
23
|
+
mapping: JsonMapping;
|
|
24
|
+
/** Type protection configuration */
|
|
25
|
+
typeProtection: TypeProtectionConfig;
|
|
26
|
+
/** Original input for reference */
|
|
27
|
+
originalInput: JsonMappingInput;
|
|
28
|
+
/** Additional metadata */
|
|
29
|
+
metadata?: {
|
|
30
|
+
typeInfo?: {
|
|
31
|
+
interface: string;
|
|
32
|
+
importPath: string;
|
|
33
|
+
generics?: string[];
|
|
34
|
+
};
|
|
35
|
+
version?: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Unified JSON mapping converter that handles all supported formats using the Strategy pattern.
|
|
41
|
+
*
|
|
42
|
+
* This converter automatically detects the input format and applies the appropriate conversion
|
|
43
|
+
* strategy to transform any supported JSON mapping format into a standardized result.
|
|
44
|
+
*
|
|
45
|
+
* **Supported Formats:**
|
|
46
|
+
* - **Enhanced**: Rich format with metadata, type protection, and advanced column configurations
|
|
47
|
+
* - **Model-Driven**: TypeScript interface-based mapping with structured field definitions
|
|
48
|
+
* - **Legacy**: Simple format compatible with PostgresJsonQueryBuilder
|
|
49
|
+
*
|
|
50
|
+
* **Usage:**
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const converter = new JsonMappingConverter();
|
|
53
|
+
* const result = converter.convert(someMapping);
|
|
54
|
+
* const legacyMapping = converter.toLegacyMapping(someMapping);
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
export declare class JsonMappingConverter {
|
|
60
|
+
/** Ordered list of conversion strategies, checked in priority order */
|
|
61
|
+
private strategies;
|
|
62
|
+
/**
|
|
63
|
+
* Creates a new JsonMappingConverter with all supported strategies.
|
|
64
|
+
*
|
|
65
|
+
* Strategies are checked in order of specificity:
|
|
66
|
+
* 1. Enhanced format (most feature-rich)
|
|
67
|
+
* 2. Model-driven format (TypeScript-based)
|
|
68
|
+
* 3. Legacy format (fallback)
|
|
69
|
+
*/
|
|
70
|
+
constructor();
|
|
71
|
+
/**
|
|
72
|
+
* Detects the format of the input mapping without performing conversion.
|
|
73
|
+
*
|
|
74
|
+
* This method uses the same strategy pattern as conversion but only returns
|
|
75
|
+
* the detected format type for inspection purposes.
|
|
76
|
+
*
|
|
77
|
+
* @param input - The JSON mapping to analyze
|
|
78
|
+
* @returns The detected mapping format type
|
|
79
|
+
*
|
|
80
|
+
* @throws {Error} When input format is not supported by any strategy
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const format = converter.detectFormat(myMapping);
|
|
85
|
+
* console.log(`Detected format: ${format}`); // "enhanced", "model-driven", or "legacy"
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
detectFormat(input: JsonMappingInput): MappingFormat;
|
|
89
|
+
/**
|
|
90
|
+
* Converts any supported JSON mapping format to a comprehensive result with metadata.
|
|
91
|
+
*
|
|
92
|
+
* This is the primary conversion method that performs format detection and transformation
|
|
93
|
+
* in a single operation. The result includes the legacy mapping, type protection configuration,
|
|
94
|
+
* and metadata about the conversion process.
|
|
95
|
+
*
|
|
96
|
+
* @param input - The JSON mapping in any supported format (Enhanced, Model-Driven, or Legacy)
|
|
97
|
+
* @returns Complete conversion result with mapping, metadata, and type protection
|
|
98
|
+
*
|
|
99
|
+
* @throws {Error} When the input format is not recognized by any strategy
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* const result = converter.convert(enhancedMapping);
|
|
104
|
+
* console.log(`Format: ${result.format}`);
|
|
105
|
+
* console.log(`Type protection: ${result.typeProtection.protectedStringFields.length} fields`);
|
|
106
|
+
*
|
|
107
|
+
* // Use the converted mapping
|
|
108
|
+
* const queryBuilder = new PostgresJsonQueryBuilder(result.mapping);
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* @see {@link toLegacyMapping} For simple mapping extraction
|
|
112
|
+
* @see {@link getTypeProtection} For type protection only
|
|
113
|
+
*/
|
|
114
|
+
convert(input: JsonMappingInput): ConversionResult;
|
|
115
|
+
/**
|
|
116
|
+
* Extracts only the legacy JsonMapping for direct use with PostgresJsonQueryBuilder.
|
|
117
|
+
*
|
|
118
|
+
* This convenience method performs the full conversion but returns only the mapping portion,
|
|
119
|
+
* discarding metadata and type protection information. Use this when you only need
|
|
120
|
+
* the mapping for query building and don't require additional metadata.
|
|
121
|
+
*
|
|
122
|
+
* @param input - The JSON mapping in any supported format
|
|
123
|
+
* @returns Legacy-format JsonMapping ready for PostgresJsonQueryBuilder
|
|
124
|
+
*
|
|
125
|
+
* @throws {Error} When the input format is not supported
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const legacyMapping = converter.toLegacyMapping(modelDrivenMapping);
|
|
130
|
+
* const queryBuilder = new PostgresJsonQueryBuilder(legacyMapping);
|
|
131
|
+
* const query = queryBuilder.build(selectQuery);
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @see {@link convert} For full conversion with metadata
|
|
135
|
+
*/
|
|
136
|
+
toLegacyMapping(input: JsonMappingInput): JsonMapping;
|
|
137
|
+
/**
|
|
138
|
+
* Extracts type protection configuration for runtime type checking.
|
|
139
|
+
*
|
|
140
|
+
* Type protection helps identify fields that should be treated as strings
|
|
141
|
+
* to prevent injection attacks or type coercion issues. This is particularly
|
|
142
|
+
* useful when working with user input or external data sources.
|
|
143
|
+
*
|
|
144
|
+
* @param input - The JSON mapping in any supported format
|
|
145
|
+
* @returns Type protection configuration with protected field definitions
|
|
146
|
+
*
|
|
147
|
+
* @throws {Error} When the input format is not supported
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const typeProtection = converter.getTypeProtection(enhancedMapping);
|
|
152
|
+
*
|
|
153
|
+
* // Apply type protection during data processing
|
|
154
|
+
* for (const field of typeProtection.protectedStringFields) {
|
|
155
|
+
* if (typeof data[field] !== 'string') {
|
|
156
|
+
* data[field] = String(data[field]);
|
|
157
|
+
* }
|
|
158
|
+
* }
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
getTypeProtection(input: JsonMappingInput): TypeProtectionConfig;
|
|
162
|
+
/**
|
|
163
|
+
* Validates that the input mapping is well-formed and can be successfully converted.
|
|
164
|
+
*
|
|
165
|
+
* This method performs comprehensive validation without attempting conversion,
|
|
166
|
+
* returning an array of error messages for any issues found. An empty array
|
|
167
|
+
* indicates the mapping is valid and ready for conversion.
|
|
168
|
+
*
|
|
169
|
+
* **Validation Checks:**
|
|
170
|
+
* - Basic structure validation (object type, required fields)
|
|
171
|
+
* - Format-specific validation (Enhanced, Model-Driven, Legacy)
|
|
172
|
+
* - Column configuration validation
|
|
173
|
+
* - Type protection configuration validation
|
|
174
|
+
*
|
|
175
|
+
* @param input - The JSON mapping to validate
|
|
176
|
+
* @returns Array of validation error messages (empty if valid)
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* const errors = converter.validate(suspiciousMapping);
|
|
181
|
+
* if (errors.length > 0) {
|
|
182
|
+
* console.error('Validation failed:', errors);
|
|
183
|
+
* throw new Error(`Invalid mapping: ${errors.join(', ')}`);
|
|
184
|
+
* }
|
|
185
|
+
*
|
|
186
|
+
* // Safe to convert
|
|
187
|
+
* const result = converter.convert(suspiciousMapping);
|
|
188
|
+
* ```
|
|
189
|
+
*
|
|
190
|
+
* @see {@link convert} Performs conversion after implicit validation
|
|
191
|
+
*/
|
|
192
|
+
validate(input: JsonMappingInput): string[];
|
|
193
|
+
/**
|
|
194
|
+
* Creates a new enhanced mapping from legacy mapping.
|
|
195
|
+
*/
|
|
196
|
+
upgradeToEnhanced(legacy: LegacyJsonMapping, typeInfo?: {
|
|
197
|
+
interface: string;
|
|
198
|
+
importPath: string;
|
|
199
|
+
}): EnhancedJsonMapping;
|
|
200
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Unified JSON Mapping processor that supports both legacy and model-driven formats.
|
|
3
3
|
*
|
|
4
|
+
* @deprecated Use JsonMappingConverter instead. This module is kept for backward compatibility.
|
|
4
5
|
* This module provides backward compatibility while encouraging migration to the model-driven format.
|
|
5
6
|
* It automatically detects the input format and normalizes to a consistent internal representation.
|
|
6
7
|
*/
|
|
@@ -48,6 +49,8 @@ export declare function detectMappingFormat(input: UnifiedMappingInput): 'model-
|
|
|
48
49
|
/**
|
|
49
50
|
* Main processor that unifies all JSON mapping formats into a consistent JsonMapping.
|
|
50
51
|
*
|
|
52
|
+
* @deprecated Use JsonMappingConverter.convert() instead.
|
|
53
|
+
*
|
|
51
54
|
* Features:
|
|
52
55
|
* - Automatic format detection
|
|
53
56
|
* - Backward compatibility with all existing formats
|
|
@@ -61,6 +64,8 @@ export declare function processJsonMapping(input: UnifiedMappingInput): MappingP
|
|
|
61
64
|
/**
|
|
62
65
|
* Convenience function for direct JsonMapping extraction.
|
|
63
66
|
*
|
|
67
|
+
* @deprecated Use JsonMappingConverter.toLegacyMapping() instead.
|
|
68
|
+
*
|
|
64
69
|
* @param input - Any supported JSON mapping format
|
|
65
70
|
* @returns JsonMapping ready for use with PostgresJsonQueryBuilder
|
|
66
71
|
*/
|
|
@@ -1,104 +1,77 @@
|
|
|
1
1
|
import { CommonTable } from '../models/Clause';
|
|
2
2
|
import { JsonMapping } from './PostgresJsonQueryBuilder';
|
|
3
|
-
import { ProcessableEntity } from './PostgresObjectEntityCteBuilder';
|
|
3
|
+
import { ProcessableEntity, JsonColumnMapping } from './PostgresObjectEntityCteBuilder';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* This class handles the creation of CTEs that build JSON/JSONB arrays for child entities,
|
|
7
|
-
* processing them from the deepest level up to ensure proper dependency ordering.
|
|
5
|
+
* Builds CTEs for array entities using depth-first processing and row compression.
|
|
8
6
|
*
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
* - Row
|
|
12
|
-
* -
|
|
13
|
-
* -
|
|
14
|
-
* - Column exclusion to avoid duplication
|
|
15
|
-
*
|
|
16
|
-
* Why depth calculation is critical:
|
|
17
|
-
* 1. Array entities can be nested at multiple levels. We must process the deepest
|
|
18
|
-
* (most distant) arrays first to ensure their JSON representations are available
|
|
19
|
-
* when building their parent arrays.
|
|
20
|
-
* 2. Array entity processing is essentially a row compression operation using GROUP BY.
|
|
21
|
-
* Unlike parent entities which use column compression, arrays require grouping
|
|
22
|
-
* to aggregate multiple rows into JSON arrays.
|
|
23
|
-
*
|
|
24
|
-
* Example hierarchy:
|
|
25
|
-
* Order (root, depth 0)
|
|
26
|
-
* └─ Items (array, depth 1)
|
|
27
|
-
* └─ Details (array, depth 2)
|
|
28
|
-
*
|
|
29
|
-
* Processing order: depth 2 → depth 1 → depth 0
|
|
7
|
+
* Core concepts:
|
|
8
|
+
* - Column Compression: OBJECT relationships (user_id, user_name → user_json)
|
|
9
|
+
* - Row Compression: ARRAY relationships (multiple rows → JSON array via GROUP BY)
|
|
10
|
+
* - Depth-First: Process deepest arrays first for dependency ordering
|
|
11
|
+
* - GROUP BY Exclusion: Exclude array-internal columns to prevent over-grouping
|
|
30
12
|
*/
|
|
31
13
|
export declare class PostgresArrayEntityCteBuilder {
|
|
32
14
|
private static readonly CTE_ARRAY_PREFIX;
|
|
15
|
+
private static readonly JSON_FUNCTIONS;
|
|
33
16
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
17
|
+
* Builds CTEs for all array entities using depth-first processing.
|
|
18
|
+
* Collects arrays by depth, processes deepest first, chains CTEs.
|
|
19
|
+
*
|
|
20
|
+
* @param ctesSoFar Array of CTEs built so far
|
|
21
|
+
* @param aliasOfCteToBuildUpon Alias of the CTE to build upon
|
|
37
22
|
* @param allEntities Map of all entities in the mapping
|
|
38
23
|
* @param mapping The JSON mapping configuration
|
|
39
|
-
* @
|
|
24
|
+
* @param columnMappings Optional mappings from object entity IDs to generated JSON column names
|
|
25
|
+
* @returns Object containing updated CTEs and last CTE alias
|
|
40
26
|
*/
|
|
41
|
-
buildArrayEntityCtes(ctesSoFar: CommonTable[], aliasOfCteToBuildUpon: string, allEntities: Map<string, ProcessableEntity>, mapping: JsonMapping): {
|
|
27
|
+
buildArrayEntityCtes(ctesSoFar: CommonTable[], aliasOfCteToBuildUpon: string, allEntities: Map<string, ProcessableEntity>, mapping: JsonMapping, columnMappings?: JsonColumnMapping[]): {
|
|
42
28
|
updatedCtes: CommonTable[];
|
|
43
29
|
lastCteAlias: string;
|
|
44
30
|
};
|
|
45
31
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* Depth calculation ensures proper processing order where deeper nested
|
|
49
|
-
* arrays are processed first, making their aggregated data available
|
|
50
|
-
* for parent array processing.
|
|
32
|
+
* Collects array entities and calculates depth for dependency ordering.
|
|
33
|
+
* Depth = distance from root. Deeper arrays processed first.
|
|
51
34
|
*
|
|
52
35
|
* @param mapping The JSON mapping configuration
|
|
53
36
|
* @param allEntities Map of all entities in the mapping
|
|
54
|
-
* @returns Array of array entity information with
|
|
37
|
+
* @returns Array of array entity information with depths, sorted deepest first
|
|
55
38
|
*/
|
|
56
39
|
private collectAndSortArrayEntities;
|
|
57
40
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* Grouping by depth allows us to:
|
|
61
|
-
* - Process all entities at the same level in a single CTE
|
|
62
|
-
* - Optimize query performance by reducing the number of CTEs
|
|
63
|
-
* - Maintain clear dependency ordering
|
|
41
|
+
* Groups array entities by depth level for batch processing.
|
|
64
42
|
*
|
|
65
43
|
* @param arrayInfos Array of array entity information with depths
|
|
66
44
|
* @returns Map of depth level to entities at that depth
|
|
67
45
|
*/
|
|
68
46
|
private groupEntitiesByDepth;
|
|
69
47
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* at the same depth, using GROUP BY to compress rows into JSON arrays.
|
|
48
|
+
* Builds CTE for specific depth level using row compression.
|
|
49
|
+
* Uses GROUP BY to aggregate multiple rows into JSON arrays.
|
|
50
|
+
* Excludes array-internal columns from GROUP BY to prevent over-grouping.
|
|
74
51
|
*
|
|
75
52
|
* @param infos Array entities at this depth level
|
|
76
53
|
* @param currentCteAlias Alias of the CTE to build upon
|
|
77
54
|
* @param currentCtes All CTEs built so far
|
|
78
55
|
* @param depth Current depth level being processed
|
|
79
56
|
* @param mapping JSON mapping configuration
|
|
57
|
+
* @param columnMappings Optional mappings from object entity IDs to generated JSON column names
|
|
80
58
|
* @returns The new CTE and its alias
|
|
81
59
|
*/
|
|
82
60
|
private buildDepthCte;
|
|
83
61
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* the entity's columns into a JSON array. It also handles nested relationships
|
|
88
|
-
* by including child entity properties in the JSON object.
|
|
62
|
+
* Creates jsonb_agg function for array entity.
|
|
63
|
+
* Handles entity columns and nested child relationships.
|
|
64
|
+
* Uses originalPropertyName to avoid sequential numbering.
|
|
89
65
|
*
|
|
90
66
|
* @param entity The array entity being processed
|
|
91
67
|
* @param nestedEntities All nested entities from the mapping
|
|
92
68
|
* @param allEntities Map of all entities (not used in current implementation)
|
|
69
|
+
* @param columnMappings Mappings from object entity IDs to generated JSON column names
|
|
93
70
|
* @returns Object containing the JSON aggregation function
|
|
94
71
|
*/
|
|
95
72
|
private buildAggregationDetailsForArrayEntity;
|
|
96
73
|
/**
|
|
97
|
-
* Collects array entity columns
|
|
98
|
-
*
|
|
99
|
-
* This method creates a mapping from depth levels to sets of column names that belong to
|
|
100
|
-
* array entities at each depth. This is used to determine which columns should be excluded
|
|
101
|
-
* from GROUP BY clauses when performing array aggregation at specific depths.
|
|
74
|
+
* Collects array entity columns by depth for GROUP BY exclusion strategy.
|
|
102
75
|
*
|
|
103
76
|
* @param mapping The JSON mapping configuration containing all entities
|
|
104
77
|
* @param currentDepth The current aggregation depth being processed
|
|
@@ -106,7 +79,7 @@ export declare class PostgresArrayEntityCteBuilder {
|
|
|
106
79
|
*/
|
|
107
80
|
private collectArrayEntityColumnsByDepth;
|
|
108
81
|
/**
|
|
109
|
-
* Calculates
|
|
82
|
+
* Calculates entity depth by traversing up to root.
|
|
110
83
|
*
|
|
111
84
|
* @param entity The entity to calculate depth for
|
|
112
85
|
* @param mapping The JSON mapping containing all entities
|
|
@@ -114,7 +87,7 @@ export declare class PostgresArrayEntityCteBuilder {
|
|
|
114
87
|
*/
|
|
115
88
|
private calculateEntityDepth;
|
|
116
89
|
/**
|
|
117
|
-
* Adds
|
|
90
|
+
* Adds entity columns to depth set.
|
|
118
91
|
*
|
|
119
92
|
* @param entity The entity whose columns should be added
|
|
120
93
|
* @param depth The depth level to add columns to
|
|
@@ -122,10 +95,7 @@ export declare class PostgresArrayEntityCteBuilder {
|
|
|
122
95
|
*/
|
|
123
96
|
private addEntityColumnsToDepthSet;
|
|
124
97
|
/**
|
|
125
|
-
* Recursively collects columns from
|
|
126
|
-
*
|
|
127
|
-
* This method ensures that all nested entities (at any depth) under an array entity
|
|
128
|
-
* have their columns properly categorized by the array entity's depth level.
|
|
98
|
+
* Recursively collects columns from descendant entities.
|
|
129
99
|
*
|
|
130
100
|
* @param parentEntityId The ID of the parent entity
|
|
131
101
|
* @param targetDepth The depth level to assign collected columns to
|
|
@@ -134,11 +104,8 @@ export declare class PostgresArrayEntityCteBuilder {
|
|
|
134
104
|
*/
|
|
135
105
|
private collectDescendantColumns;
|
|
136
106
|
/**
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* This method implements the core logic for deciding which columns from previous CTEs
|
|
140
|
-
* should be included in the GROUP BY clause when performing array aggregation. It handles
|
|
141
|
-
* special cases for JSON columns and applies depth-based filtering to prevent over-grouping.
|
|
107
|
+
* Implements GROUP BY exclusion strategy for array aggregation.
|
|
108
|
+
* Excludes current array columns and array-internal object JSON columns.
|
|
142
109
|
*
|
|
143
110
|
* @param prevSelects SELECT variables from the previous CTE
|
|
144
111
|
* @param arrayColumns Columns that are being aggregated (should be excluded from GROUP BY)
|
|
@@ -146,14 +113,12 @@ export declare class PostgresArrayEntityCteBuilder {
|
|
|
146
113
|
* @param currentDepth The current aggregation depth being processed
|
|
147
114
|
* @param selectItems Output array for SELECT items
|
|
148
115
|
* @param groupByItems Output array for GROUP BY items
|
|
116
|
+
* @param arrayInternalObjectColumns JSON columns from objects within arrays being processed
|
|
149
117
|
*/
|
|
150
118
|
private processSelectVariablesForGroupBy;
|
|
151
119
|
/**
|
|
152
|
-
* Determines
|
|
153
|
-
*
|
|
154
|
-
* This method applies depth-based filtering and special handling for JSON columns
|
|
155
|
-
* to prevent over-grouping during array aggregation. It implements heuristics for
|
|
156
|
-
* excluding columns that belong to nested entities within array contexts.
|
|
120
|
+
* Determines if column should be included in GROUP BY clause.
|
|
121
|
+
* Applies depth-based filtering and special handling for JSON columns.
|
|
157
122
|
*
|
|
158
123
|
* @param columnName The name of the column to evaluate
|
|
159
124
|
* @param arrayEntitiesByDepth Map of depth levels to their column sets
|
|
@@ -162,11 +127,8 @@ export declare class PostgresArrayEntityCteBuilder {
|
|
|
162
127
|
*/
|
|
163
128
|
private shouldIncludeColumnInGroupBy;
|
|
164
129
|
/**
|
|
165
|
-
* Applies heuristics
|
|
166
|
-
*
|
|
167
|
-
* This method uses entity numbering patterns to identify deeply nested entities
|
|
168
|
-
* that should be excluded from GROUP BY when processing array aggregations.
|
|
169
|
-
* This is a simplified heuristic approach that works for current use cases.
|
|
130
|
+
* Applies heuristics for entity JSON column inclusion in GROUP BY.
|
|
131
|
+
* Uses entity numbering patterns to identify deeply nested entities.
|
|
170
132
|
*
|
|
171
133
|
* @param columnName The JSON column name (expected format: entity_N_json)
|
|
172
134
|
* @param currentDepth The current aggregation depth
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SimpleSelectQuery } from '../models/SimpleSelectQuery';
|
|
2
2
|
import { SelectQuery } from '../models/SelectQuery';
|
|
3
|
+
import { QueryBuildOptions } from './DynamicQueryBuilder';
|
|
3
4
|
/**
|
|
4
5
|
* Universal JSON mapping definition for creating any level of JSON structures.
|
|
5
6
|
* Supports flat arrays, nested objects, and unlimited hierarchical structures.
|
|
@@ -47,8 +48,8 @@ export declare class PostgresJsonQueryBuilder {
|
|
|
47
48
|
* @param mapping JSON mapping configuration
|
|
48
49
|
* @returns Transformed query with JSON aggregation
|
|
49
50
|
*/
|
|
50
|
-
buildJsonQuery(originalQuery: SelectQuery, mapping: JsonMapping): SimpleSelectQuery;
|
|
51
|
-
buildJsonQuery(originalQuery: SimpleSelectQuery, mapping: JsonMapping): SimpleSelectQuery;
|
|
51
|
+
buildJsonQuery(originalQuery: SelectQuery, mapping: JsonMapping, options?: QueryBuildOptions): SimpleSelectQuery;
|
|
52
|
+
buildJsonQuery(originalQuery: SimpleSelectQuery, mapping: JsonMapping, options?: QueryBuildOptions): SimpleSelectQuery;
|
|
52
53
|
/**
|
|
53
54
|
* Build JSON query from original query and mapping configuration.
|
|
54
55
|
* @deprecated Use buildJsonQuery instead. This method will be removed in a future version.
|