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.
- package/README.md +175 -47
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +16 -14
- package/dist/esm/index.min.js.map +4 -4
- package/dist/esm/src/index.js +6 -0
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/tokenReaders/OperatorTokenReader.js +4 -0
- package/dist/esm/src/tokenReaders/OperatorTokenReader.js.map +1 -1
- package/dist/esm/src/transformers/CTEDependencyTracer.js +249 -0
- package/dist/esm/src/transformers/CTEDependencyTracer.js.map +1 -0
- package/dist/esm/src/transformers/DynamicQueryBuilder.js +155 -0
- package/dist/esm/src/transformers/DynamicQueryBuilder.js.map +1 -0
- package/dist/esm/src/transformers/JsonMappingUnifier.js +217 -0
- package/dist/esm/src/transformers/JsonMappingUnifier.js.map +1 -0
- package/dist/esm/src/transformers/ModelDrivenJsonMapping.js +103 -0
- package/dist/esm/src/transformers/ModelDrivenJsonMapping.js.map +1 -0
- package/dist/esm/src/transformers/PostgresArrayEntityCteBuilder.js +204 -16
- package/dist/esm/src/transformers/PostgresArrayEntityCteBuilder.js.map +1 -1
- package/dist/esm/src/transformers/PostgresJsonQueryBuilder.js +26 -21
- package/dist/esm/src/transformers/PostgresJsonQueryBuilder.js.map +1 -1
- package/dist/esm/src/transformers/PostgresObjectEntityCteBuilder.js +8 -5
- package/dist/esm/src/transformers/PostgresObjectEntityCteBuilder.js.map +1 -1
- package/dist/esm/src/transformers/SelectableColumnCollector.js +17 -5
- package/dist/esm/src/transformers/SelectableColumnCollector.js.map +1 -1
- package/dist/esm/src/transformers/SqlFormatter.js +1 -2
- package/dist/esm/src/transformers/SqlFormatter.js.map +1 -1
- package/dist/esm/src/transformers/TypeTransformationPostProcessor.js +342 -0
- package/dist/esm/src/transformers/TypeTransformationPostProcessor.js.map +1 -0
- package/dist/esm/src/transformers/UnifiedJsonMapping.js +57 -0
- package/dist/esm/src/transformers/UnifiedJsonMapping.js.map +1 -0
- package/dist/esm/src/transformers/UpstreamSelectQueryFinder.js +8 -1
- package/dist/esm/src/transformers/UpstreamSelectQueryFinder.js.map +1 -1
- package/dist/esm/src/utils/JsonSchemaValidator.js +211 -0
- package/dist/esm/src/utils/JsonSchemaValidator.js.map +1 -0
- package/dist/esm/src/utils/OperatorPrecedence.js +3 -1
- package/dist/esm/src/utils/OperatorPrecedence.js.map +1 -1
- package/dist/esm/src/utils/SchemaManager.js +0 -1
- package/dist/esm/src/utils/SchemaManager.js.map +1 -1
- package/dist/esm/tsconfig.browser.tsbuildinfo +1 -1
- package/dist/esm/types/src/index.d.ts +6 -0
- package/dist/esm/types/src/transformers/CTEDependencyTracer.d.ts +58 -0
- package/dist/esm/types/src/transformers/DynamicQueryBuilder.d.ts +108 -0
- package/dist/esm/types/src/transformers/JsonMappingUnifier.d.ts +95 -0
- package/dist/esm/types/src/transformers/ModelDrivenJsonMapping.d.ts +62 -0
- package/dist/esm/types/src/transformers/PostgresArrayEntityCteBuilder.d.ts +80 -1
- package/dist/esm/types/src/transformers/PostgresJsonQueryBuilder.d.ts +3 -2
- package/dist/esm/types/src/transformers/SelectableColumnCollector.d.ts +14 -3
- package/dist/esm/types/src/transformers/SqlFormatter.d.ts +2 -3
- package/dist/esm/types/src/transformers/TypeTransformationPostProcessor.d.ts +108 -0
- package/dist/esm/types/src/transformers/UnifiedJsonMapping.d.ts +53 -0
- package/dist/esm/types/src/transformers/UpstreamSelectQueryFinder.d.ts +5 -1
- package/dist/esm/types/src/utils/JsonSchemaValidator.d.ts +81 -0
- package/dist/index.min.js +16 -14
- package/dist/index.min.js.map +4 -4
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +14 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/tokenReaders/OperatorTokenReader.js +4 -0
- package/dist/src/tokenReaders/OperatorTokenReader.js.map +1 -1
- package/dist/src/transformers/CTEDependencyTracer.d.ts +58 -0
- package/dist/src/transformers/CTEDependencyTracer.js +253 -0
- package/dist/src/transformers/CTEDependencyTracer.js.map +1 -0
- package/dist/src/transformers/DynamicQueryBuilder.d.ts +108 -0
- package/dist/src/transformers/DynamicQueryBuilder.js +159 -0
- package/dist/src/transformers/DynamicQueryBuilder.js.map +1 -0
- package/dist/src/transformers/JsonMappingUnifier.d.ts +95 -0
- package/dist/src/transformers/JsonMappingUnifier.js +226 -0
- package/dist/src/transformers/JsonMappingUnifier.js.map +1 -0
- package/dist/src/transformers/ModelDrivenJsonMapping.d.ts +62 -0
- package/dist/src/transformers/ModelDrivenJsonMapping.js +110 -0
- package/dist/src/transformers/ModelDrivenJsonMapping.js.map +1 -0
- package/dist/src/transformers/PostgresArrayEntityCteBuilder.d.ts +80 -1
- package/dist/src/transformers/PostgresArrayEntityCteBuilder.js +204 -16
- package/dist/src/transformers/PostgresArrayEntityCteBuilder.js.map +1 -1
- package/dist/src/transformers/PostgresJsonQueryBuilder.d.ts +3 -2
- package/dist/src/transformers/PostgresJsonQueryBuilder.js +26 -21
- package/dist/src/transformers/PostgresJsonQueryBuilder.js.map +1 -1
- package/dist/src/transformers/PostgresObjectEntityCteBuilder.js +8 -5
- package/dist/src/transformers/PostgresObjectEntityCteBuilder.js.map +1 -1
- package/dist/src/transformers/SelectableColumnCollector.d.ts +14 -3
- package/dist/src/transformers/SelectableColumnCollector.js +17 -5
- package/dist/src/transformers/SelectableColumnCollector.js.map +1 -1
- package/dist/src/transformers/SqlFormatter.d.ts +2 -3
- package/dist/src/transformers/SqlFormatter.js +1 -2
- package/dist/src/transformers/SqlFormatter.js.map +1 -1
- package/dist/src/transformers/TypeTransformationPostProcessor.d.ts +108 -0
- package/dist/src/transformers/TypeTransformationPostProcessor.js +351 -0
- package/dist/src/transformers/TypeTransformationPostProcessor.js.map +1 -0
- package/dist/src/transformers/UnifiedJsonMapping.d.ts +53 -0
- package/dist/src/transformers/UnifiedJsonMapping.js +60 -0
- package/dist/src/transformers/UnifiedJsonMapping.js.map +1 -0
- package/dist/src/transformers/UpstreamSelectQueryFinder.d.ts +5 -1
- package/dist/src/transformers/UpstreamSelectQueryFinder.js +8 -1
- package/dist/src/transformers/UpstreamSelectQueryFinder.js.map +1 -1
- package/dist/src/utils/JsonSchemaValidator.d.ts +81 -0
- package/dist/src/utils/JsonSchemaValidator.js +215 -0
- package/dist/src/utils/JsonSchemaValidator.js.map +1 -0
- package/dist/src/utils/OperatorPrecedence.js +3 -1
- package/dist/src/utils/OperatorPrecedence.js.map +1 -1
- package/dist/src/utils/SchemaManager.js +0 -1
- package/dist/src/utils/SchemaManager.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -5
|
@@ -14,10 +14,16 @@ export * from './transformers/SelectValueCollector';
|
|
|
14
14
|
export * from './transformers/SelectableColumnCollector';
|
|
15
15
|
export * from './transformers/TableColumnResolver';
|
|
16
16
|
export * from './transformers/TableSourceCollector';
|
|
17
|
+
export * from './transformers/UnifiedJsonMapping';
|
|
18
|
+
export { ModelDrivenJsonMapping, convertModelDrivenMapping, validateModelDrivenMapping, FieldMapping, NestedStructure, StructureFields, FieldType } from './transformers/ModelDrivenJsonMapping';
|
|
19
|
+
export { processJsonMapping, unifyJsonMapping, isModelDrivenFormat, isUnifiedFormat, isLegacyFormat } from './transformers/JsonMappingUnifier';
|
|
17
20
|
export * from './transformers/UpstreamSelectQueryFinder';
|
|
21
|
+
export * from './transformers/TypeTransformationPostProcessor';
|
|
18
22
|
export * from './transformers/SchemaCollector';
|
|
19
23
|
export * from './transformers/SqlParamInjector';
|
|
20
24
|
export * from './transformers/SqlSortInjector';
|
|
21
25
|
export * from './transformers/SqlPaginationInjector';
|
|
26
|
+
export * from './transformers/DynamicQueryBuilder';
|
|
22
27
|
export * from './utils/SqlSchemaValidator';
|
|
28
|
+
export * from './utils/JsonSchemaValidator';
|
|
23
29
|
export * from './utils/SchemaManager';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { SelectQuery } from "../models/SelectQuery";
|
|
2
|
+
/**
|
|
3
|
+
* CTE dependency tree node for visualization
|
|
4
|
+
*/
|
|
5
|
+
export interface CTENode {
|
|
6
|
+
name: string;
|
|
7
|
+
columns: string[];
|
|
8
|
+
dependencies: string[];
|
|
9
|
+
dependents: string[];
|
|
10
|
+
query: SelectQuery;
|
|
11
|
+
level: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* CTE dependency graph for debugging complex queries
|
|
15
|
+
*/
|
|
16
|
+
export interface CTEGraph {
|
|
17
|
+
nodes: Map<string, CTENode>;
|
|
18
|
+
rootNodes: string[];
|
|
19
|
+
leafNodes: string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Debug utility for visualizing CTE dependencies and column search paths
|
|
23
|
+
*/
|
|
24
|
+
export declare class CTEDependencyTracer {
|
|
25
|
+
private columnCollector;
|
|
26
|
+
private silent;
|
|
27
|
+
constructor(options?: {
|
|
28
|
+
silent?: boolean;
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Build complete CTE dependency graph
|
|
32
|
+
*/
|
|
33
|
+
buildGraph(query: SelectQuery): CTEGraph;
|
|
34
|
+
/**
|
|
35
|
+
* Trace column search path through CTE dependencies
|
|
36
|
+
*/
|
|
37
|
+
traceColumnSearch(query: SelectQuery, columnName: string): {
|
|
38
|
+
searchPath: string[];
|
|
39
|
+
foundIn: string[];
|
|
40
|
+
notFoundIn: string[];
|
|
41
|
+
graph: CTEGraph;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Print visual representation of CTE dependency graph
|
|
45
|
+
*/
|
|
46
|
+
printGraph(graph: CTEGraph): void;
|
|
47
|
+
/**
|
|
48
|
+
* Print column search trace
|
|
49
|
+
*/
|
|
50
|
+
printColumnTrace(columnName: string, trace: ReturnType<typeof this.traceColumnSearch>): void;
|
|
51
|
+
/**
|
|
52
|
+
* Find CTEs that are actually referenced in the given query.
|
|
53
|
+
* Uses TableSourceCollector to properly identify table references from the AST.
|
|
54
|
+
*/
|
|
55
|
+
private findReferencedCTEs;
|
|
56
|
+
private calculateLevels;
|
|
57
|
+
private getSearchOrder;
|
|
58
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { SelectQuery } from "../models/SelectQuery";
|
|
2
|
+
import { SortConditions } from "./SqlSortInjector";
|
|
3
|
+
import { PaginationOptions } from "./SqlPaginationInjector";
|
|
4
|
+
import { JsonMapping } from "./PostgresJsonQueryBuilder";
|
|
5
|
+
/**
|
|
6
|
+
* Options for dynamic query building
|
|
7
|
+
*/
|
|
8
|
+
export interface QueryBuildOptions {
|
|
9
|
+
/** Filter conditions to inject into WHERE clause */
|
|
10
|
+
filter?: Record<string, any>;
|
|
11
|
+
/** Sort conditions to inject into ORDER BY clause */
|
|
12
|
+
sort?: SortConditions;
|
|
13
|
+
/** Pagination options to inject LIMIT/OFFSET clauses */
|
|
14
|
+
paging?: PaginationOptions;
|
|
15
|
+
/** JSON serialization mapping to transform results into hierarchical JSON
|
|
16
|
+
* - JsonMapping object: explicit mapping configuration
|
|
17
|
+
* - true: auto-load mapping from corresponding .json file
|
|
18
|
+
* - false/undefined: no serialization
|
|
19
|
+
*/
|
|
20
|
+
serialize?: JsonMapping | boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* DynamicQueryBuilder provides pure JavaScript SQL query building capabilities.
|
|
24
|
+
* It combines SQL parsing with dynamic condition injection (filtering, sorting, pagination, serialization).
|
|
25
|
+
*
|
|
26
|
+
* This class is framework-agnostic and does not perform any file I/O operations.
|
|
27
|
+
* It only works with SQL content provided as strings.
|
|
28
|
+
*
|
|
29
|
+
* Key features:
|
|
30
|
+
* - Pure JavaScript/TypeScript - no file system dependencies
|
|
31
|
+
* - Framework-agnostic - can be used with any database framework
|
|
32
|
+
* - Composable - combines multiple injectors in the correct order
|
|
33
|
+
* - Type-safe - provides TypeScript types for all options
|
|
34
|
+
* - Testable - easy to unit test without mocking file system
|
|
35
|
+
*/
|
|
36
|
+
export declare class DynamicQueryBuilder {
|
|
37
|
+
private tableColumnResolver?;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a new DynamicQueryBuilder instance
|
|
40
|
+
* @param tableColumnResolver Optional function to resolve table columns for wildcard queries
|
|
41
|
+
*/
|
|
42
|
+
constructor(tableColumnResolver?: (tableName: string) => string[]);
|
|
43
|
+
/**
|
|
44
|
+
* Builds a SelectQuery from SQL content with dynamic conditions.
|
|
45
|
+
* This is a pure function that does not perform any I/O operations.
|
|
46
|
+
* * @param sqlContent Raw SQL string to parse and modify
|
|
47
|
+
* @param options Dynamic conditions to apply (filter, sort, paging, serialize)
|
|
48
|
+
* @returns Modified SelectQuery with all dynamic conditions applied
|
|
49
|
+
* * @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const builder = new DynamicQueryBuilder();
|
|
52
|
+
* const query = builder.buildQuery(
|
|
53
|
+
* 'SELECT id, name FROM users WHERE active = true',
|
|
54
|
+
* {
|
|
55
|
+
* filter: { status: 'premium' },
|
|
56
|
+
* sort: { created_at: { desc: true } },
|
|
57
|
+
* paging: { page: 2, pageSize: 10 },
|
|
58
|
+
* serialize: { rootName: 'user', rootEntity: { id: 'user', name: 'User', columns: { id: 'id', name: 'name' } }, nestedEntities: [] }
|
|
59
|
+
* }
|
|
60
|
+
* );
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
buildQuery(sqlContent: string, options?: QueryBuildOptions): SelectQuery;
|
|
64
|
+
/**
|
|
65
|
+
* Builds a SelectQuery with only filtering applied.
|
|
66
|
+
* Convenience method for when you only need dynamic WHERE conditions.
|
|
67
|
+
*
|
|
68
|
+
* @param sqlContent Raw SQL string to parse and modify
|
|
69
|
+
* @param filter Filter conditions to apply
|
|
70
|
+
* @returns Modified SelectQuery with filter conditions applied
|
|
71
|
+
*/
|
|
72
|
+
buildFilteredQuery(sqlContent: string, filter: Record<string, any>): SelectQuery;
|
|
73
|
+
/**
|
|
74
|
+
* Builds a SelectQuery with only sorting applied.
|
|
75
|
+
* Convenience method for when you only need dynamic ORDER BY clauses.
|
|
76
|
+
*
|
|
77
|
+
* @param sqlContent Raw SQL string to parse and modify
|
|
78
|
+
* @param sort Sort conditions to apply
|
|
79
|
+
* @returns Modified SelectQuery with sort conditions applied
|
|
80
|
+
*/
|
|
81
|
+
buildSortedQuery(sqlContent: string, sort: SortConditions): SelectQuery; /**
|
|
82
|
+
* Builds a SelectQuery with only pagination applied.
|
|
83
|
+
* Convenience method for when you only need LIMIT/OFFSET clauses.
|
|
84
|
+
*
|
|
85
|
+
* @param sqlContent Raw SQL string to parse and modify
|
|
86
|
+
* @param paging Pagination options to apply
|
|
87
|
+
* @returns Modified SelectQuery with pagination applied
|
|
88
|
+
*/
|
|
89
|
+
buildPaginatedQuery(sqlContent: string, paging: PaginationOptions): SelectQuery;
|
|
90
|
+
/**
|
|
91
|
+
* Builds a SelectQuery with only JSON serialization applied.
|
|
92
|
+
* Convenience method for when you only need hierarchical JSON transformation.
|
|
93
|
+
*
|
|
94
|
+
* @param sqlContent Raw SQL string to parse and modify
|
|
95
|
+
* @param serialize JSON mapping configuration to apply
|
|
96
|
+
* @returns Modified SelectQuery with JSON serialization applied
|
|
97
|
+
*/
|
|
98
|
+
buildSerializedQuery(sqlContent: string, serialize: JsonMapping): SelectQuery;
|
|
99
|
+
/**
|
|
100
|
+
* Validates SQL content by attempting to parse it.
|
|
101
|
+
* Useful for testing SQL validity without applying any modifications.
|
|
102
|
+
*
|
|
103
|
+
* @param sqlContent Raw SQL string to validate
|
|
104
|
+
* @returns true if SQL is valid, throws error if invalid
|
|
105
|
+
* @throws Error if SQL cannot be parsed
|
|
106
|
+
*/
|
|
107
|
+
validateSql(sqlContent: string): boolean;
|
|
108
|
+
}
|
|
@@ -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,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[];
|
|
@@ -90,8 +90,87 @@ export declare class PostgresArrayEntityCteBuilder {
|
|
|
90
90
|
* @param entity The array entity being processed
|
|
91
91
|
* @param nestedEntities All nested entities from the mapping
|
|
92
92
|
* @param allEntities Map of all entities (not used in current implementation)
|
|
93
|
-
* @param useJsonb Whether to use JSONB functions
|
|
94
93
|
* @returns Object containing the JSON aggregation function
|
|
95
94
|
*/
|
|
96
95
|
private buildAggregationDetailsForArrayEntity;
|
|
96
|
+
/**
|
|
97
|
+
* Collects array entity columns organized by depth for the GROUP BY exclusion strategy.
|
|
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.
|
|
102
|
+
*
|
|
103
|
+
* @param mapping The JSON mapping configuration containing all entities
|
|
104
|
+
* @param currentDepth The current aggregation depth being processed
|
|
105
|
+
* @returns A map where keys are depth levels and values are sets of column names
|
|
106
|
+
*/
|
|
107
|
+
private collectArrayEntityColumnsByDepth;
|
|
108
|
+
/**
|
|
109
|
+
* Calculates the depth of an entity in the hierarchy by traversing up to the root.
|
|
110
|
+
*
|
|
111
|
+
* @param entity The entity to calculate depth for
|
|
112
|
+
* @param mapping The JSON mapping containing all entities
|
|
113
|
+
* @returns The depth level (0 for root level, 1 for first level, etc.)
|
|
114
|
+
*/
|
|
115
|
+
private calculateEntityDepth;
|
|
116
|
+
/**
|
|
117
|
+
* Adds all columns from an entity to the specified depth set.
|
|
118
|
+
*
|
|
119
|
+
* @param entity The entity whose columns should be added
|
|
120
|
+
* @param depth The depth level to add columns to
|
|
121
|
+
* @param arrayEntitiesByDepth The map to update
|
|
122
|
+
*/
|
|
123
|
+
private addEntityColumnsToDepthSet;
|
|
124
|
+
/**
|
|
125
|
+
* Recursively collects columns from all descendant entities under a parent entity.
|
|
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.
|
|
129
|
+
*
|
|
130
|
+
* @param parentEntityId The ID of the parent entity
|
|
131
|
+
* @param targetDepth The depth level to assign collected columns to
|
|
132
|
+
* @param mapping The JSON mapping containing all entities
|
|
133
|
+
* @param arrayEntitiesByDepth The map to update with collected columns
|
|
134
|
+
*/
|
|
135
|
+
private collectDescendantColumns;
|
|
136
|
+
/**
|
|
137
|
+
* Processes SELECT variables to determine which should be included in GROUP BY clauses.
|
|
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.
|
|
142
|
+
*
|
|
143
|
+
* @param prevSelects SELECT variables from the previous CTE
|
|
144
|
+
* @param arrayColumns Columns that are being aggregated (should be excluded from GROUP BY)
|
|
145
|
+
* @param arrayEntitiesByDepth Map of depth levels to their column sets
|
|
146
|
+
* @param currentDepth The current aggregation depth being processed
|
|
147
|
+
* @param selectItems Output array for SELECT items
|
|
148
|
+
* @param groupByItems Output array for GROUP BY items
|
|
149
|
+
*/
|
|
150
|
+
private processSelectVariablesForGroupBy;
|
|
151
|
+
/**
|
|
152
|
+
* Determines whether a column should be included in the GROUP BY clause.
|
|
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.
|
|
157
|
+
*
|
|
158
|
+
* @param columnName The name of the column to evaluate
|
|
159
|
+
* @param arrayEntitiesByDepth Map of depth levels to their column sets
|
|
160
|
+
* @param currentDepth The current aggregation depth
|
|
161
|
+
* @returns True if the column should be included in GROUP BY, false otherwise
|
|
162
|
+
*/
|
|
163
|
+
private shouldIncludeColumnInGroupBy;
|
|
164
|
+
/**
|
|
165
|
+
* Applies heuristics to determine if an entity JSON column should be included in GROUP BY.
|
|
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.
|
|
170
|
+
*
|
|
171
|
+
* @param columnName The JSON column name (expected format: entity_N_json)
|
|
172
|
+
* @param currentDepth The current aggregation depth
|
|
173
|
+
* @returns True if the JSON column should be included, false otherwise
|
|
174
|
+
*/
|
|
175
|
+
private shouldIncludeJsonColumn;
|
|
97
176
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SimpleSelectQuery } from '../models/SimpleSelectQuery';
|
|
2
|
+
import { SelectQuery } from '../models/SelectQuery';
|
|
2
3
|
/**
|
|
3
4
|
* Universal JSON mapping definition for creating any level of JSON structures.
|
|
4
5
|
* Supports flat arrays, nested objects, and unlimited hierarchical structures.
|
|
@@ -22,7 +23,6 @@ export interface JsonMapping {
|
|
|
22
23
|
[jsonKey: string]: string;
|
|
23
24
|
};
|
|
24
25
|
}>;
|
|
25
|
-
useJsonb?: boolean;
|
|
26
26
|
resultFormat?: "array" | "single";
|
|
27
27
|
emptyResult?: string;
|
|
28
28
|
}
|
|
@@ -43,10 +43,11 @@ export declare class PostgresJsonQueryBuilder {
|
|
|
43
43
|
private validateMapping;
|
|
44
44
|
/**
|
|
45
45
|
* Build JSON query from original query and mapping configuration.
|
|
46
|
-
* @param originalQuery Original query to transform
|
|
46
|
+
* @param originalQuery Original query to transform (can be any SelectQuery type)
|
|
47
47
|
* @param mapping JSON mapping configuration
|
|
48
48
|
* @returns Transformed query with JSON aggregation
|
|
49
49
|
*/
|
|
50
|
+
buildJsonQuery(originalQuery: SelectQuery, mapping: JsonMapping): SimpleSelectQuery;
|
|
50
51
|
buildJsonQuery(originalQuery: SimpleSelectQuery, mapping: JsonMapping): SimpleSelectQuery;
|
|
51
52
|
/**
|
|
52
53
|
* Build JSON query from original query and mapping configuration.
|
|
@@ -20,12 +20,23 @@ import { SqlComponent, SqlComponentVisitor } from "../models/SqlComponent";
|
|
|
20
20
|
import { ValueComponent } from "../models/ValueComponent";
|
|
21
21
|
import { TableColumnResolver } from "./TableColumnResolver";
|
|
22
22
|
/**
|
|
23
|
-
* A visitor that collects all ColumnReference instances from
|
|
23
|
+
* A visitor that collects all ColumnReference instances from SimpleSelectQuery structures.
|
|
24
24
|
* This visitor scans through all clauses and collects all unique ColumnReference objects.
|
|
25
25
|
* It does not scan Common Table Expressions (CTEs) or subqueries.
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* IMPORTANT: This collector only supports SimpleSelectQuery. BinarySelectQuery
|
|
28
|
+
* (UNION/INTERSECT/EXCEPT) will throw an error and should be decomposed into
|
|
29
|
+
* individual SimpleSelectQuery branches before using this collector.
|
|
30
|
+
*
|
|
31
|
+
* Behavioral notes:
|
|
32
|
+
* - Only collects column references to tables defined in the root FROM/JOIN clauses
|
|
33
|
+
* - For aliased columns (e.g., 'title as name'), collects both the original column
|
|
34
|
+
* reference ('title') AND the alias ('name') to enable complete dependency tracking
|
|
35
|
+
*
|
|
36
|
+
* Use cases:
|
|
37
|
+
* - Dependency analysis and schema migration tools
|
|
38
|
+
* - Column usage tracking within individual SELECT branches
|
|
39
|
+
* - Security analysis for column-level access control
|
|
29
40
|
*/
|
|
30
41
|
export declare class SelectableColumnCollector implements SqlComponentVisitor<void> {
|
|
31
42
|
private handlers;
|
|
@@ -26,8 +26,7 @@ export declare class SqlFormatter {
|
|
|
26
26
|
keywordCase?: 'none' | 'upper' | 'lower';
|
|
27
27
|
commaBreak?: CommaBreakStyle;
|
|
28
28
|
andBreak?: AndBreakStyle;
|
|
29
|
-
});
|
|
30
|
-
/**
|
|
29
|
+
}); /**
|
|
31
30
|
* Formats a SQL query string with the given parameters.
|
|
32
31
|
* @param sqlText The SQL query string to format.
|
|
33
32
|
* @param parameters A dictionary of parameters to replace in the query.
|
|
@@ -35,6 +34,6 @@ export declare class SqlFormatter {
|
|
|
35
34
|
*/
|
|
36
35
|
format(sql: SqlComponent): {
|
|
37
36
|
formattedSql: string;
|
|
38
|
-
params: Record<string, any>;
|
|
37
|
+
params: any[] | Record<string, any>;
|
|
39
38
|
};
|
|
40
39
|
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-processor for transforming database values to appropriate TypeScript types
|
|
3
|
+
* after JSON serialization from PostgreSQL
|
|
4
|
+
*/
|
|
5
|
+
export interface TypeTransformationConfig {
|
|
6
|
+
/** Column transformations mapping - takes precedence over value-based detection */
|
|
7
|
+
columnTransformations?: {
|
|
8
|
+
[columnName: string]: TypeTransformation;
|
|
9
|
+
};
|
|
10
|
+
/** Global transformation rules by SQL data type */
|
|
11
|
+
globalTransformations?: {
|
|
12
|
+
[sqlType: string]: TypeTransformation;
|
|
13
|
+
};
|
|
14
|
+
/** Custom transformation functions */
|
|
15
|
+
customTransformers?: {
|
|
16
|
+
[transformerName: string]: (value: any) => any;
|
|
17
|
+
};
|
|
18
|
+
/** Enable value-based type detection when column mapping is not provided (default: true) */
|
|
19
|
+
enableValueBasedDetection?: boolean;
|
|
20
|
+
/** Strict date detection - only convert ISO 8601 with 'T' separator (default: false) */
|
|
21
|
+
strictDateDetection?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface TypeTransformation {
|
|
24
|
+
/** Source SQL data type */
|
|
25
|
+
sourceType: 'DATE' | 'TIMESTAMP' | 'BIGINT' | 'NUMERIC' | 'JSONB' | 'custom';
|
|
26
|
+
/** Target TypeScript type representation */
|
|
27
|
+
targetType: 'Date' | 'bigint' | 'string' | 'number' | 'object' | 'custom';
|
|
28
|
+
/** Custom transformer function name (for custom type) */
|
|
29
|
+
customTransformer?: string;
|
|
30
|
+
/** Whether to handle null values (default: true) */
|
|
31
|
+
handleNull?: boolean;
|
|
32
|
+
/** Validation function for the value */
|
|
33
|
+
validator?: (value: any) => boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Applies type transformations to JSON results from PostgreSQL
|
|
37
|
+
*/
|
|
38
|
+
export declare class TypeTransformationPostProcessor {
|
|
39
|
+
private config;
|
|
40
|
+
constructor(config?: TypeTransformationConfig);
|
|
41
|
+
/**
|
|
42
|
+
* Transform a single result object
|
|
43
|
+
* @param result The result object from PostgreSQL JSON query
|
|
44
|
+
* @returns Transformed result with proper TypeScript types
|
|
45
|
+
*/
|
|
46
|
+
transformResult<T = any>(result: any): T;
|
|
47
|
+
/**
|
|
48
|
+
* Transform a single object recursively
|
|
49
|
+
*/
|
|
50
|
+
private transformSingleObject;
|
|
51
|
+
/**
|
|
52
|
+
* Detect value type and create appropriate transformation based on value characteristics
|
|
53
|
+
* This is the core value-based detection logic
|
|
54
|
+
*/
|
|
55
|
+
private detectValueBasedTransformation;
|
|
56
|
+
/**
|
|
57
|
+
* Get global transformation for a specific value (if any match)
|
|
58
|
+
* This is separate from value-based detection and relies on configured global rules
|
|
59
|
+
*/
|
|
60
|
+
private getGlobalTransformationForValue;
|
|
61
|
+
/**
|
|
62
|
+
* @deprecated Use detectValueBasedTransformation instead
|
|
63
|
+
* Detect value type and get appropriate global transformation
|
|
64
|
+
*/
|
|
65
|
+
private detectAndGetGlobalTransformation;
|
|
66
|
+
/**
|
|
67
|
+
* Check if string is a valid date string
|
|
68
|
+
* Supports both strict (ISO 8601 with T separator) and loose detection
|
|
69
|
+
*/
|
|
70
|
+
private isDateString;
|
|
71
|
+
/**
|
|
72
|
+
* Apply a specific transformation to a value
|
|
73
|
+
*/
|
|
74
|
+
private applyTransformation;
|
|
75
|
+
/**
|
|
76
|
+
* Create a default configuration for common PostgreSQL types
|
|
77
|
+
* Enables value-based detection with loose date detection by default
|
|
78
|
+
*/
|
|
79
|
+
static createDefaultConfig(): TypeTransformationConfig;
|
|
80
|
+
/**
|
|
81
|
+
* Create a safe configuration for handling user input
|
|
82
|
+
* Disables value-based detection and uses strict date detection
|
|
83
|
+
*/
|
|
84
|
+
static createSafeConfig(columnMappings?: {
|
|
85
|
+
[columnName: string]: TypeTransformation;
|
|
86
|
+
}): TypeTransformationConfig;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Convenience function to create and apply transformations
|
|
90
|
+
*/
|
|
91
|
+
export declare function transformDatabaseResult<T = any>(result: any, config?: TypeTransformationConfig): T;
|
|
92
|
+
/**
|
|
93
|
+
* Type-safe transformation helpers
|
|
94
|
+
*/
|
|
95
|
+
export declare const TypeTransformers: {
|
|
96
|
+
/**
|
|
97
|
+
* Transform date string to Date object
|
|
98
|
+
*/
|
|
99
|
+
toDate: (value: string | null) => Date | null;
|
|
100
|
+
/**
|
|
101
|
+
* Transform numeric string to BigInt
|
|
102
|
+
*/
|
|
103
|
+
toBigInt: (value: string | number | null) => bigint | null;
|
|
104
|
+
/**
|
|
105
|
+
* Transform JSON string to object
|
|
106
|
+
*/
|
|
107
|
+
toObject: <T = any>(value: string | null) => T | null;
|
|
108
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced JSON mapping structure that integrates column mapping and type protection configuration.
|
|
3
|
+
* This unified approach eliminates the need for separate .types.json files.
|
|
4
|
+
*/
|
|
5
|
+
import { JsonMapping } from './PostgresJsonQueryBuilder';
|
|
6
|
+
/**
|
|
7
|
+
* Supported column type enforcement options.
|
|
8
|
+
*/
|
|
9
|
+
export type ColumnType = 'string' | 'auto';
|
|
10
|
+
/**
|
|
11
|
+
* Column configuration that can either be a simple string mapping or an enhanced mapping with type control.
|
|
12
|
+
*/
|
|
13
|
+
export type ColumnMappingConfig = string | {
|
|
14
|
+
column: string;
|
|
15
|
+
type?: ColumnType;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Enhanced JSON mapping configuration with integrated type protection.
|
|
19
|
+
*/
|
|
20
|
+
export interface UnifiedJsonMapping {
|
|
21
|
+
rootName: string;
|
|
22
|
+
typeInfo?: {
|
|
23
|
+
interface: string;
|
|
24
|
+
importPath: string;
|
|
25
|
+
};
|
|
26
|
+
rootEntity: {
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
columns: Record<string, ColumnMappingConfig>;
|
|
30
|
+
};
|
|
31
|
+
nestedEntities?: Array<{
|
|
32
|
+
id: string;
|
|
33
|
+
name: string;
|
|
34
|
+
parentId: string;
|
|
35
|
+
propertyName: string;
|
|
36
|
+
relationshipType: 'object' | 'array';
|
|
37
|
+
columns: Record<string, ColumnMappingConfig>;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Type protection configuration extracted from the unified mapping.
|
|
42
|
+
*/
|
|
43
|
+
export interface TypeProtectionConfig {
|
|
44
|
+
protectedStringFields: string[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Convert a unified JSON mapping to separate JsonMapping and TypeProtectionConfig.
|
|
48
|
+
* This enables backward compatibility with existing code while supporting the new unified structure.
|
|
49
|
+
*/
|
|
50
|
+
export declare function convertUnifiedMapping(unified: UnifiedJsonMapping): {
|
|
51
|
+
jsonMapping: JsonMapping;
|
|
52
|
+
typeProtection: TypeProtectionConfig;
|
|
53
|
+
};
|
|
@@ -3,7 +3,11 @@ import { SelectQuery, SimpleSelectQuery } from "../models/SelectQuery";
|
|
|
3
3
|
* UpstreamSelectQueryFinder searches upstream queries for the specified columns.
|
|
4
4
|
* If a query (including its upstream CTEs or subqueries) contains all columns,
|
|
5
5
|
* it returns the highest such SelectQuery. Otherwise, it searches downstream.
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
|
+
* For BinarySelectQuery (UNION/INTERSECT/EXCEPT), this finder processes each branch
|
|
8
|
+
* independently, as SelectableColumnCollector is designed for SimpleSelectQuery only.
|
|
9
|
+
* This approach ensures accurate column detection within individual SELECT branches
|
|
10
|
+
* while maintaining compatibility with compound query structures.
|
|
7
11
|
*/
|
|
8
12
|
export declare class UpstreamSelectQueryFinder {
|
|
9
13
|
private options;
|