rawsql-ts 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +4 -4
- package/dist/esm/index.min.js.map +4 -4
- package/dist/esm/transformers/DynamicQueryBuilder.d.ts +9 -13
- package/dist/esm/transformers/DynamicQueryBuilder.js +8 -108
- package/dist/esm/transformers/DynamicQueryBuilder.js.map +1 -1
- package/dist/esm/transformers/PruneOptionalConditionBranches.d.ts +14 -2
- package/dist/esm/transformers/PruneOptionalConditionBranches.js +105 -37
- package/dist/esm/transformers/PruneOptionalConditionBranches.js.map +1 -1
- package/dist/esm/transformers/SSSQLFilterBuilder.d.ts +30 -0
- package/dist/esm/transformers/SSSQLFilterBuilder.js +253 -0
- package/dist/esm/transformers/SSSQLFilterBuilder.js.map +1 -0
- package/dist/esm/utils/RelationGraph.d.ts +43 -0
- package/dist/esm/utils/RelationGraph.js +117 -0
- package/dist/esm/utils/RelationGraph.js.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +4 -4
- package/dist/index.min.js.map +4 -4
- package/dist/src/index.d.ts +4 -0
- package/dist/src/transformers/DynamicQueryBuilder.d.ts +9 -13
- package/dist/src/transformers/PruneOptionalConditionBranches.d.ts +14 -2
- package/dist/src/transformers/SSSQLFilterBuilder.d.ts +30 -0
- package/dist/src/utils/RelationGraph.d.ts +43 -0
- package/dist/transformers/DynamicQueryBuilder.js +8 -97
- package/dist/transformers/DynamicQueryBuilder.js.map +1 -1
- package/dist/transformers/PruneOptionalConditionBranches.js +106 -37
- package/dist/transformers/PruneOptionalConditionBranches.js.map +1 -1
- package/dist/transformers/SSSQLFilterBuilder.js +259 -0
- package/dist/transformers/SSSQLFilterBuilder.js.map +1 -0
- package/dist/tsconfig.browser.tsbuildinfo +1 -1
- package/dist/utils/RelationGraph.js +123 -0
- package/dist/utils/RelationGraph.js.map +1 -0
- package/package.json +64 -65
package/dist/esm/index.min.js
CHANGED
|
@@ -80,15 +80,15 @@ ${query}`}addRestorationComments(sql,targetNode,warnings){let comments=[];return
|
|
|
80
80
|
\u{1F527} Check:
|
|
81
81
|
1. Model-driven mapping conversion generates consistent entity IDs
|
|
82
82
|
2. PostgresObjectEntityCteBuilder processes all entities correctly
|
|
83
|
-
3. Entity hierarchy and parentId relationships are correct`)}args.push(new ColumnReference(null,new IdentifierString(mapping.generatedColumnName)))}else childEntity.relationshipType==="array"&&args.push(new ColumnReference(null,new IdentifierString(childEntity.propertyName)))});let jsonObject=new FunctionCall(null,new RawString(jsonBuildFunction),new ValueList(args),null),jsonAggFunction=_PostgresArrayEntityCteBuilder.JSON_FUNCTIONS.AGGREGATE,primaryColumn=Object.values(entity.columns)[0];return{jsonAgg:new FunctionCall(null,new RawString(jsonAggFunction),new ValueList([jsonObject]),null)}}collectArrayEntityColumnsByDepth(mapping,currentDepth){let arrayEntitiesByDepth=new Map,maxDepth=Math.max(currentDepth+3,5);for(let d=currentDepth;d<=maxDepth;d++)arrayEntitiesByDepth.set(d,new Set);return mapping.nestedEntities.filter(entity=>entity.relationshipType==="array").forEach(entity=>{let entityDepth=this.calculateEntityDepth(entity,mapping);arrayEntitiesByDepth.has(entityDepth)||arrayEntitiesByDepth.set(entityDepth,new Set),this.addEntityColumnsToDepthSet(entity,entityDepth,arrayEntitiesByDepth),this.collectDescendantColumns(entity.id,entityDepth,mapping,arrayEntitiesByDepth)}),arrayEntitiesByDepth}calculateEntityDepth(entity,mapping){let entityDepth=0,currentEntity=entity;for(;currentEntity.parentId&¤tEntity.parentId!==mapping.rootEntity.id;)entityDepth++,currentEntity=mapping.nestedEntities.find(e=>e.id===currentEntity.parentId)||currentEntity;return entityDepth}addEntityColumnsToDepthSet(entity,depth,arrayEntitiesByDepth){Object.values(entity.columns).forEach(column=>{let columnName=typeof column=="string"?column:column.column;arrayEntitiesByDepth.get(depth).add(columnName)})}collectDescendantColumns(parentEntityId,targetDepth,mapping,arrayEntitiesByDepth){mapping.nestedEntities.filter(nestedEntity=>nestedEntity.parentId===parentEntityId).forEach(nestedEntity=>{this.addEntityColumnsToDepthSet(nestedEntity,targetDepth,arrayEntitiesByDepth),this.collectDescendantColumns(nestedEntity.id,targetDepth,mapping,arrayEntitiesByDepth)})}processSelectVariablesForGroupBy(prevSelects,arrayColumns,arrayEntitiesByDepth,currentDepth,selectItems,groupByItems,arrayInternalObjectColumns){prevSelects.forEach(sv=>{if(!arrayColumns.has(sv.name)){if(arrayInternalObjectColumns&&arrayInternalObjectColumns.has(sv.name))return;this.shouldIncludeColumnInGroupBy(sv.name,arrayEntitiesByDepth,currentDepth)&&(selectItems.push(new SelectItem(new ColumnReference(null,new IdentifierString(sv.name)),sv.name)),sv.name.endsWith("_json")||groupByItems.push(new ColumnReference(null,new IdentifierString(sv.name))))}})}shouldIncludeColumnInGroupBy(columnName,arrayEntitiesByDepth,currentDepth){let isJsonColumn=columnName.endsWith("_json"),shouldInclude=!0;for(let[entityDepth,columns]of arrayEntitiesByDepth.entries())if(entityDepth>=currentDepth&&columns.has(columnName)){shouldInclude=!1;break}return isJsonColumn&&columnName.startsWith("entity_")&&(shouldInclude=this.shouldIncludeJsonColumn(columnName,currentDepth)),shouldInclude}shouldIncludeJsonColumn(columnName,currentDepth){let entityMatch=columnName.match(/entity_(\d+)_json/);return entityMatch&¤tDepth>0?parseInt(entityMatch[1])<=2:!0}};var PostgresJsonQueryBuilder=class{constructor(){this.selectValueCollector=new SelectValueCollector(null),this.objectEntityCteBuilder=new PostgresObjectEntityCteBuilder,this.arrayEntityCteBuilder=new PostgresArrayEntityCteBuilder}validateMapping(query,mapping){let selectedValues=new SelectValueCollector().collect(query),availableColumns=new Set(selectedValues.map(sv=>sv.name));for(let jsonKey in mapping.rootEntity.columns){let columnDef=mapping.rootEntity.columns[jsonKey],sourceColumn=typeof columnDef=="string"?columnDef:columnDef.column;if(!availableColumns.has(sourceColumn))throw new Error(`Validation Error: Column "${sourceColumn}" for JSON key "${jsonKey}" in root entity "${mapping.rootEntity.name}" not found in the query's select list.`)}let entityIds=new Set([mapping.rootEntity.id]),parentToChildrenMap=new Map;mapping.nestedEntities.forEach(ne=>{entityIds.add(ne.id),parentToChildrenMap.has(ne.parentId)||parentToChildrenMap.set(ne.parentId,[]),parentToChildrenMap.get(ne.parentId).push(ne.id)});for(let entity of mapping.nestedEntities){if(!entityIds.has(entity.parentId))throw new Error(`Validation Error: Parent entity with ID "${entity.parentId}" for nested entity "${entity.name}" (ID: ${entity.id}) not found.`);for(let jsonKey in entity.columns){let columnDef=entity.columns[jsonKey],sourceColumn=typeof columnDef=="string"?columnDef:columnDef.column;if(!availableColumns.has(sourceColumn))throw new Error(`Validation Error: Column "${sourceColumn}" for JSON key "${jsonKey}" in nested entity "${entity.name}" (ID: ${entity.id}) not found in the query's select list.`)}}let allParentIds=new Set([mapping.rootEntity.id,...mapping.nestedEntities.map(ne=>ne.parentId)]);for(let parentId of allParentIds){let directChildren=mapping.nestedEntities.filter(ne=>ne.parentId===parentId);if(directChildren.filter(c=>c.relationshipType==="array").length>1){let parentName=parentId===mapping.rootEntity.id?mapping.rootEntity.name:mapping.nestedEntities.find(ne=>ne.id===parentId)?.name;throw new Error(`Validation Error: Parent entity "${parentName}" (ID: ${parentId}) has multiple direct array children. This is not supported.`)}let propertyNames=new Set;for(let child of directChildren){if(propertyNames.has(child.propertyName)){let parentName=parentId===mapping.rootEntity.id?mapping.rootEntity.name:mapping.nestedEntities.find(ne=>ne.id===parentId)?.name;throw new Error(`Validation Error: Parent entity "${parentName}" (ID: ${parentId}) has duplicate property name "${child.propertyName}" for its children.`)}propertyNames.add(child.propertyName)}}}buildJsonQuery(originalQuery,mapping,options){if(options?.jsonb===!1)throw new Error("JSONB must be enabled for PostgreSQL GROUP BY compatibility. JSON type cannot be used in GROUP BY clauses. Please set jsonb: true or omit the jsonb option (defaults to true).");let simpleQuery=originalQuery instanceof SimpleSelectQuery?originalQuery:QueryBuilder.buildSimpleQuery(originalQuery);return this.buildJsonWithCteStrategy(simpleQuery,mapping)}buildJson(originalQuery,mapping){return console.warn("buildJson is deprecated. Use buildJsonQuery instead."),this.buildJsonQuery(originalQuery,mapping)}buildJsonWithCteStrategy(originalQuery,mapping){this.validateMapping(originalQuery,mapping);let{initialCte,initialCteAlias}=this.createInitialCte(originalQuery),ctesForProcessing=[initialCte],currentAliasToBuildUpon=initialCteAlias,allEntities=new Map;allEntities.set(mapping.rootEntity.id,{...mapping.rootEntity,isRoot:!0,propertyName:mapping.rootName}),mapping.nestedEntities.forEach(ne=>allEntities.set(ne.id,{...ne,isRoot:!1,propertyName:ne.propertyName}));let objectEntityResult=this.objectEntityCteBuilder.buildObjectEntityCtes(initialCte,allEntities,mapping);ctesForProcessing=objectEntityResult.ctes,currentAliasToBuildUpon=objectEntityResult.lastCteAlias;let columnMappings=objectEntityResult.columnMappings,arrayCteBuildResult=this.arrayEntityCteBuilder.buildArrayEntityCtes(ctesForProcessing,currentAliasToBuildUpon,allEntities,mapping,columnMappings);return ctesForProcessing=arrayCteBuildResult.updatedCtes,currentAliasToBuildUpon=arrayCteBuildResult.lastCteAlias,this.buildFinalSelectQuery(ctesForProcessing,currentAliasToBuildUpon,allEntities,mapping,columnMappings)}createInitialCte(originalQuery){let originCteAlias="origin_query";return{initialCte:new CommonTable(originalQuery,new SourceAliasExpression(originCteAlias,null),null),initialCteAlias:originCteAlias}}buildFinalSelectQuery(finalCtesList,lastCteAliasForFromClause,allEntities,mapping,columnMappings){let currentCtes=[...finalCtesList],rootObjectCteAlias=`cte_root_${mapping.rootName.toLowerCase().replace(/[^a-z0-9_]/g,"_")}`,rootEntity=allEntities.get(mapping.rootEntity.id);if(!rootEntity)throw new Error(`Root entity ${mapping.rootEntity.id} not found`);if(mapping.resultFormat==="array"||!mapping.resultFormat){let rootObjectBuilderExpression=this.buildEntityJsonObject(rootEntity,null,mapping.nestedEntities,allEntities,columnMappings),rootObjectSelectItem=new SelectItem(rootObjectBuilderExpression,mapping.rootName),rootObjectCte=new CommonTable(new SimpleSelectQuery({selectClause:new SelectClause([rootObjectSelectItem]),fromClause:new FromClause(new SourceExpression(new TableSource(null,new IdentifierString(lastCteAliasForFromClause)),null),null)}),new SourceAliasExpression(rootObjectCteAlias,null),null);currentCtes.push(rootObjectCte);let aggregationFunc="jsonb_agg",aggregateExpression=new FunctionCall(null,new RawString(aggregationFunc),new ValueList([new ColumnReference(null,new IdentifierString(mapping.rootName))]),null);return new SimpleSelectQuery({withClause:new WithClause(!1,currentCtes),selectClause:new SelectClause([new SelectItem(aggregateExpression,`${mapping.rootName}_array`)]),fromClause:new FromClause(new SourceExpression(new TableSource(null,new IdentifierString(rootObjectCteAlias)),null),null)})}else{let rootObjectBuilderExpression=this.buildEntityJsonObject(rootEntity,null,mapping.nestedEntities,allEntities,columnMappings),rootObjectSelectItem=new SelectItem(rootObjectBuilderExpression,mapping.rootName),rootObjectCte=new CommonTable(new SimpleSelectQuery({selectClause:new SelectClause([rootObjectSelectItem]),fromClause:new FromClause(new SourceExpression(new TableSource(null,new IdentifierString(lastCteAliasForFromClause)),null),null)}),new SourceAliasExpression(rootObjectCteAlias,null),null);return currentCtes.push(rootObjectCte),new SimpleSelectQuery({withClause:new WithClause(!1,currentCtes),selectClause:new SelectClause([new SelectItem(new ColumnReference(null,new IdentifierString(mapping.rootName)),mapping.rootName)]),fromClause:new FromClause(new SourceExpression(new TableSource(null,new IdentifierString(rootObjectCteAlias)),null),null),limitClause:new LimitClause(new LiteralValue(1))})}}buildEntityJsonObject(entity,sourceAlias,nestedEntities,allEntities,columnMappings){let jsonBuildFunction="jsonb_build_object",args=[];return Object.entries(entity.columns).forEach(([jsonKey,columnDef])=>{let sqlColumn=typeof columnDef=="string"?columnDef:columnDef.column;args.push(new LiteralValue(jsonKey,void 0,!0)),args.push(new ColumnReference(null,new IdentifierString(sqlColumn)))}),nestedEntities.filter(ne=>ne.parentId===entity.id).forEach(childEntity=>{let child=allEntities.get(childEntity.id);if(child)if(args.push(new LiteralValue(childEntity.propertyName,void 0,!0)),childEntity.relationshipType==="object"){let mapping=columnMappings.find(m=>m.entityId===child.id);if(!mapping)throw new Error(`Column mapping not found for entity: ${child.id}`);args.push(new ColumnReference(null,new IdentifierString(mapping.generatedColumnName)))}else childEntity.relationshipType==="array"&&args.push(new ColumnReference(null,new IdentifierString(childEntity.propertyName)))}),new FunctionCall(null,new RawString(jsonBuildFunction),new ValueList(args),null)}};var SelectResultSelectConverter=class{static toSelectQuery(query,options){let fixtureTables=options?.fixtureTables??[];if(fixtureTables.length===0)return query;let sources=new TableSourceCollector(!1).collect(query),referencedTables=new Set;sources.forEach(s=>referencedTables.add(s.getSourceName().toLowerCase()));let neededFixtures=fixtureTables.filter(f=>referencedTables.has(f.tableName.toLowerCase()));if(neededFixtures.length===0)return query;let fixtureCtes=FixtureCteBuilder.buildFixtures(neededFixtures);return query instanceof SimpleSelectQuery&&(query.withClause?query.withClause.tables=[...fixtureCtes,...query.withClause.tables]:query.appendWith(fixtureCtes)),query}};var SimulatedSelectConverter=class{static convert(ast,options){if(ast instanceof InsertQuery)return InsertResultSelectConverter.toSelectQuery(ast,options);if(ast instanceof UpdateQuery)return UpdateResultSelectConverter.toSelectQuery(ast,options);if(ast instanceof DeleteQuery)return DeleteResultSelectConverter.toSelectQuery(ast,options);if(ast instanceof MergeQuery)return MergeResultSelectConverter.toSelectQuery(ast,options);if(ast instanceof SimpleSelectQuery||ast instanceof BinarySelectQuery||ast instanceof ValuesQuery)return SelectResultSelectConverter.toSelectQuery(ast,options);if(ast instanceof CreateTableQuery){if(ast.isTemporary&&ast.asSelectQuery){let processedSelect=SelectResultSelectConverter.toSelectQuery(ast.asSelectQuery,options);return ast.asSelectQuery=processedSelect,ast}return null}return null}};var DDLGeneralizer=class{static generalize(ast){let result=[];for(let component of ast)if(component instanceof CreateTableQuery){let{createTable,alterTables}=this.splitCreateTable(component);result.push(createTable),result.push(...alterTables)}else result.push(component);return result}static splitCreateTable(query){let newColumns=[],alterTables=[],tableQualifiedName=new QualifiedName(query.namespaces||[],query.tableName.name);for(let col of query.columns){let newConstraints=[];for(let constraint of col.constraints)if(["primary-key","unique","references","check"].includes(constraint.kind)){let tableConstraint=this.columnToTableConstraint(col.name,constraint);alterTables.push(new AlterTableStatement({table:tableQualifiedName,actions:[new AlterTableAddConstraint({constraint:tableConstraint})]}))}else newConstraints.push(constraint);newColumns.push(new TableColumnDefinition({name:col.name,dataType:col.dataType,constraints:newConstraints}))}if(query.tableConstraints)for(let constraint of query.tableConstraints)alterTables.push(new AlterTableStatement({table:tableQualifiedName,actions:[new AlterTableAddConstraint({constraint})]}));return{createTable:new CreateTableQuery({tableName:query.tableName.name,namespaces:query.namespaces,columns:newColumns,ifNotExists:query.ifNotExists,isTemporary:query.isTemporary,tableOptions:query.tableOptions,asSelectQuery:query.asSelectQuery,withDataOption:query.withDataOption,tableConstraints:[]}),alterTables}}static columnToTableConstraint(columnName,constraint){let baseParams={constraintName:constraint.constraintName,deferrable:constraint.reference?.deferrable,initially:constraint.reference?.initially};switch(constraint.kind){case"primary-key":return new TableConstraintDefinition({kind:"primary-key",columns:[columnName],...baseParams});case"unique":return new TableConstraintDefinition({kind:"unique",columns:[columnName],...baseParams});case"references":return new TableConstraintDefinition({kind:"foreign-key",columns:[columnName],reference:constraint.reference,...baseParams});case"check":return new TableConstraintDefinition({kind:"check",checkExpression:constraint.checkExpression,...baseParams});default:throw new Error(`Unsupported constraint kind for generalization: ${constraint.kind}`)}}};var DDLDiffGenerator=class{static generateDiff(currentSql,expectedSql,options={}){let currentAst=this.parseAndGeneralize(currentSql),expectedAst=this.parseAndGeneralize(expectedSql),currentSchema=this.buildSchema(currentAst),expectedSchema=this.buildSchema(expectedAst),diffAsts=[];for(let[tableName,expectedTable]of expectedSchema.tables){let currentTable=currentSchema.tables.get(tableName);if(currentTable)this.compareColumns(currentTable,expectedTable,diffAsts,options),this.compareConstraints(currentTable,expectedTable,diffAsts,options),this.compareIndexes(currentTable,expectedTable,diffAsts,options);else{let columns=Array.from(expectedTable.columns.values()).map(c=>c.definition),tableNameStr=expectedTable.qualifiedName.name instanceof RawString?expectedTable.qualifiedName.name.value:expectedTable.qualifiedName.name.name,namespaces=expectedTable.qualifiedName.namespaces?expectedTable.qualifiedName.namespaces.map(ns=>ns.name):null,createTable=new CreateTableQuery({tableName:tableNameStr,namespaces,columns});diffAsts.push(createTable);for(let constraint of expectedTable.constraints)diffAsts.push(new AlterTableStatement({table:expectedTable.qualifiedName,actions:[new AlterTableAddConstraint({constraint:constraint.definition})]}));for(let index of expectedTable.indexes)diffAsts.push(index.definition)}}if(options.dropTables)for(let[tableName,currentTable]of currentSchema.tables)expectedSchema.tables.has(tableName)||diffAsts.push(new DropTableStatement({tables:[currentTable.qualifiedName],ifExists:!1}));let formatter=new SqlFormatter(options.formatOptions||{keywordCase:"upper"});return diffAsts.map(ast=>formatter.format(ast).formattedSql+";")}static parseAndGeneralize(sql){let split=MultiQuerySplitter.split(sql),asts=[];for(let q of split.queries)if(!q.isEmpty)try{let ast=SqlParser.parse(q.sql);asts.push(ast)}catch(e){console.warn("Failed to parse SQL for diff:",q.sql,e)}return DDLGeneralizer.generalize(asts)}static buildSchema(asts){let tables=new Map,formatter=new SqlFormatter({keywordCase:"none"});for(let ast of asts)if(ast instanceof CreateTableQuery){let qName=new QualifiedName(ast.namespaces||[],ast.tableName),key=this.getQualifiedNameKey(qName),tableModel={name:key,qualifiedName:qName,columns:new Map,constraints:[],indexes:[]};for(let col of ast.columns)tableModel.columns.set(col.name.name,{name:col.name.name,definition:col});tables.set(key,tableModel)}else if(ast instanceof AlterTableStatement){let key=this.getQualifiedNameKey(ast.table),tableModel=tables.get(key);if(tableModel)for(let action of ast.actions)if(action instanceof AlterTableAddConstraint){let formatted=formatter.format(action.constraint).formattedSql;tableModel.constraints.push({name:action.constraint.constraintName?.name,kind:action.constraint.kind,definition:action.constraint,formatted})}else action instanceof AlterTableAddColumn&&tableModel.columns.set(action.column.name.name,{name:action.column.name.name,definition:action.column})}else if(ast instanceof CreateIndexStatement){let key=this.getQualifiedNameKey(ast.tableName),tableModel=tables.get(key);if(tableModel){let formatted=formatter.format(ast).formattedSql;tableModel.indexes.push({name:ast.indexName.toString(),definition:ast,formatted})}}return{tables}}static compareColumns(current,expected,diffs,options){for(let[name,col]of expected.columns)current.columns.has(name)||diffs.push(new AlterTableStatement({table:expected.qualifiedName,actions:[new AlterTableAddColumn({column:col.definition})]}));if(options.dropColumns)for(let[name,col]of current.columns)expected.columns.has(name)||diffs.push(new AlterTableStatement({table:expected.qualifiedName,actions:[new AlterTableDropColumn({columnName:col.definition.name})]}))}static compareConstraints(current,expected,diffs,options){let formatter=new SqlFormatter({keywordCase:"none"}),getConstraintSignature=c=>options.checkConstraintNames?c.kind==="primary-key"?c.formatted.replace(/^constraint\s+("[^"]+"|[^\s]+)\s+/i,"").trim():c.name||c.formatted:c.formatted.replace(/^constraint\s+("[^"]+"|[^\s]+)\s+/i,"").trim(),currentSignatures=new Set(current.constraints.map(getConstraintSignature));for(let expectedC of expected.constraints){let sig=getConstraintSignature(expectedC);currentSignatures.has(sig)||diffs.push(new AlterTableStatement({table:expected.qualifiedName,actions:[new AlterTableAddConstraint({constraint:expectedC.definition})]}))}if(options.dropConstraints){let expectedSignatures=new Set(expected.constraints.map(getConstraintSignature));for(let currentC of current.constraints){let sig=getConstraintSignature(currentC);expectedSignatures.has(sig)||(currentC.name?diffs.push(new AlterTableStatement({table:expected.qualifiedName,actions:[new AlterTableDropConstraint({constraintName:new IdentifierString(currentC.name)})]})):console.warn("Cannot drop unnamed constraint:",currentC.formatted))}}}static compareIndexes(current,expected,diffs,options){let getIndexSignature=idx=>{if(options.checkConstraintNames)return idx.name;let def=idx.definition,parts=[];parts.push(def.tableName.toString()),def.unique&&parts.push("UNIQUE"),def.usingMethod&&parts.push(`USING:${def.usingMethod.toString()}`);let columnSigs=def.columns.map(col=>{let expr=col.expression.toString(),sort=col.sortOrder||"",nulls=col.nullsOrder||"";return`${expr}${sort}${nulls}`});return parts.push(`COLS:${columnSigs.join(",")}`),def.include&&def.include.length>0&&parts.push(`INCLUDE:${def.include.map(i=>i.toString()).join(",")}`),def.where&&parts.push(`WHERE:${def.where.toString()}`),parts.join("|")},currentSignatures=new Set(current.indexes.map(getIndexSignature));for(let expectedIdx of expected.indexes){let sig=getIndexSignature(expectedIdx);currentSignatures.has(sig)||diffs.push(expectedIdx.definition)}if(options.checkConstraintNames||options.dropIndexes){let expectedSignatures=new Set(expected.indexes.map(getIndexSignature));for(let currentIdx of current.indexes){let sig=getIndexSignature(currentIdx);expectedSignatures.has(sig)||diffs.push(new DropIndexStatement({indexNames:[currentIdx.definition.indexName],ifExists:!1}))}}}static getQualifiedNameKey(qName){return qName.toString()}};var ParameterDetector=class{static extractParameterNames(query){return ParameterCollector.collect(query).map(p=>p.name.value)}static hasParameter(query,parameterName){return this.extractParameterNames(query).includes(parameterName)}static separateFilters(query,filter){let hardcodedParamNames=this.extractParameterNames(query),hardcodedParams={},dynamicFilters={};for(let[key,value]of Object.entries(filter))hardcodedParamNames.includes(key)?hardcodedParams[key]=value:dynamicFilters[key]=value;return{hardcodedParams,dynamicFilters}}};var FilterableItem=class{constructor(name,type,tableName){this.name=name;this.type=type;this.tableName=tableName}},FilterableItemCollector=class{constructor(tableColumnResolver,options){this.tableColumnResolver=tableColumnResolver,this.options={qualified:!1,upstream:!0,...options}}collect(query){let items=[],columnItems=this.collectColumns(query);items.push(...columnItems);let parameterItems=this.collectParameters(query);return items.push(...parameterItems),this.removeDuplicates(items)}collectColumns(query){let items=[];try{let columns=new SelectableColumnCollector(this.tableColumnResolver,!1,"fullName",{upstream:this.options.upstream}).collect(query);for(let column of columns){let tableName,realTableName;if(column.value&&typeof column.value.getNamespace=="function"){let namespace=column.value.getNamespace();namespace&&namespace.trim()!==""&&(tableName=namespace,this.options.qualified&&(realTableName=this.getRealTableName(query,namespace)))}tableName||(tableName=this.inferTableNameFromQuery(query),tableName&&this.options.qualified&&(realTableName=tableName));let columnName=column.name;this.options.qualified&&(realTableName||tableName)&&(columnName=`${realTableName||tableName}.${column.name}`),items.push(new FilterableItem(columnName,"column",tableName))}}catch(error){console.warn("Failed to collect columns with SelectableColumnCollector, using fallback:",error);try{let schemas=new SchemaCollector(this.tableColumnResolver,!0).collect(query);for(let schema of schemas)for(let columnName of schema.columns){let finalColumnName=columnName;this.options.qualified&&(finalColumnName=`${schema.name}.${columnName}`),items.push(new FilterableItem(finalColumnName,"column",schema.name))}}catch(fallbackError){console.warn("Failed to collect columns with both approaches:",error,fallbackError)}}return items}inferTableNameFromQuery(query){if(query instanceof SimpleSelectQuery&&query.fromClause&&query.fromClause.source){let datasource=query.fromClause.source.datasource;if(datasource&&typeof datasource.table=="object"){let table=datasource.table;if(table&&typeof table.name=="string")return table.name}}}getRealTableName(query,aliasOrName){try{let simpleQuery=query.type==="WITH"?query.toSimpleQuery():query;if(simpleQuery instanceof SimpleSelectQuery&&simpleQuery.fromClause){if(simpleQuery.fromClause.source?.datasource){let mainSource=simpleQuery.fromClause.source,realName=this.extractRealTableName(mainSource,aliasOrName);if(realName)return realName}let fromClause=simpleQuery.fromClause;if(fromClause.joinClauses&&Array.isArray(fromClause.joinClauses)){for(let joinClause of fromClause.joinClauses)if(joinClause.source?.datasource){let realName=this.extractRealTableName(joinClause.source,aliasOrName);if(realName)return realName}}}}catch(error){console.warn("Error resolving real table name:",error)}return aliasOrName}extractRealTableName(source,aliasOrName){try{let datasource=source.datasource;if(!datasource)return;let alias=source.alias||source.aliasExpression?.table?.name,realTableName=datasource.table?.name;if(alias===aliasOrName&&realTableName||!alias&&realTableName===aliasOrName)return realTableName}catch{}}collectParameters(query){let items=[];try{let parameterNames=ParameterDetector.extractParameterNames(query);for(let paramName of parameterNames)items.push(new FilterableItem(paramName,"parameter"))}catch(error){console.warn("Failed to collect parameters:",error)}return items}removeDuplicates(items){let seen=new Set,result=[];for(let item of items){let key=`${item.type}:${item.name}:${item.tableName||"none"}`;seen.has(key)||(seen.add(key),result.push(item))}return result.sort((a,b)=>{if(a.type!==b.type)return a.type==="column"?-1:1;if(a.type==="column"){let tableA=a.tableName||"",tableB=b.tableName||"";if(tableA!==tableB)return tableA.localeCompare(tableB)}return a.name.localeCompare(b.name)})}};var SqlParamInjector=class{constructor(optionsOrResolver,options){typeof optionsOrResolver=="function"?(this.tableColumnResolver=optionsOrResolver,this.options=options||{}):(this.tableColumnResolver=void 0,this.options=optionsOrResolver||{})}inject(query,state){typeof query=="string"&&(query=SelectQueryParser.parse(query));let finder=new UpstreamSelectQueryFinder(this.tableColumnResolver,this.options),collector=new SelectableColumnCollector(this.tableColumnResolver,!1,"fullName",{upstream:!0}),normalize=s=>this.options.ignoreCaseAndUnderscore?s.toLowerCase().replace(/_/g,""):s,allowedOps=["min","max","like","ilike","in","any","=","<",">","!=","<>","<=",">=","or","and","column"],stateValues=Object.values(state);if(stateValues.length>0&&stateValues.every(value=>value===void 0)&&!this.options.allowAllUndefined)throw new Error("All parameters are undefined. This would result in fetching all records. Use allowAllUndefined: true option to explicitly allow this behavior.");let qualifiedParams=[],unqualifiedParams=[];for(let[name,stateValue]of Object.entries(state))stateValue!==void 0&&(this.isQualifiedColumnName(name)?qualifiedParams.push([name,stateValue]):unqualifiedParams.push([name,stateValue]));for(let[name,stateValue]of qualifiedParams)this.processStateParameter(name,stateValue,query,finder,collector,normalize,allowedOps,injectOrConditions,injectAndConditions,injectSimpleCondition,injectComplexConditions,validateOperators);let processedQualifiedColumns=new Set;for(let[qualifiedName,_]of qualifiedParams){let parsed=this.parseQualifiedColumnName(qualifiedName);parsed&&processedQualifiedColumns.add(`${parsed.table.toLowerCase()}.${parsed.column.toLowerCase()}`)}for(let[name,stateValue]of unqualifiedParams)this.processUnqualifiedParameter(name,stateValue,query,finder,collector,normalize,allowedOps,injectOrConditions,injectAndConditions,injectSimpleCondition,injectComplexConditions,validateOperators,processedQualifiedColumns);function injectAndConditions(q,baseName,andConditions,normalize2,availableColumns){for(let i=0;i<andConditions.length;i++){let andCondition=andConditions[i],columnName=andCondition.column||baseName,entry=availableColumns.find(item=>normalize2(item.name)===normalize2(columnName));if(!entry)throw new Error(`Column '${columnName}' not found in query for AND condition`);let columnRef=entry.value;if("="in andCondition&&andCondition["="]!==void 0){let paramName=`${baseName}_and_${i}_eq`,paramExpr=new ParameterExpression(paramName,andCondition["="]);q.appendWhere(new BinaryExpression(columnRef,"=",paramExpr))}if("min"in andCondition&&andCondition.min!==void 0){let paramName=`${baseName}_and_${i}_min`,paramExpr=new ParameterExpression(paramName,andCondition.min);q.appendWhere(new BinaryExpression(columnRef,">=",paramExpr))}if("max"in andCondition&&andCondition.max!==void 0){let paramName=`${baseName}_and_${i}_max`,paramExpr=new ParameterExpression(paramName,andCondition.max);q.appendWhere(new BinaryExpression(columnRef,"<=",paramExpr))}if("like"in andCondition&&andCondition.like!==void 0){let paramName=`${baseName}_and_${i}_like`,paramExpr=new ParameterExpression(paramName,andCondition.like);q.appendWhere(new BinaryExpression(columnRef,"like",paramExpr))}if("ilike"in andCondition&&andCondition.ilike!==void 0){let paramName=`${baseName}_and_${i}_ilike`,paramExpr=new ParameterExpression(paramName,andCondition.ilike);q.appendWhere(new BinaryExpression(columnRef,"ilike",paramExpr))}if("in"in andCondition&&andCondition.in!==void 0){let prms=andCondition.in.map((v,j)=>new ParameterExpression(`${baseName}_and_${i}_in_${j}`,v));q.appendWhere(new BinaryExpression(columnRef,"in",new ParenExpression(new ValueList(prms))))}if("any"in andCondition&&andCondition.any!==void 0){let paramName=`${baseName}_and_${i}_any`,paramExpr=new ParameterExpression(paramName,andCondition.any);q.appendWhere(new BinaryExpression(columnRef,"=",new FunctionCall(null,"any",paramExpr,null)))}if("<"in andCondition&&andCondition["<"]!==void 0){let paramName=`${baseName}_and_${i}_lt`,paramExpr=new ParameterExpression(paramName,andCondition["<"]);q.appendWhere(new BinaryExpression(columnRef,"<",paramExpr))}if(">"in andCondition&&andCondition[">"]!==void 0){let paramName=`${baseName}_and_${i}_gt`,paramExpr=new ParameterExpression(paramName,andCondition[">"]);q.appendWhere(new BinaryExpression(columnRef,">",paramExpr))}if("!="in andCondition&&andCondition["!="]!==void 0){let paramName=`${baseName}_and_${i}_neq`,paramExpr=new ParameterExpression(paramName,andCondition["!="]);q.appendWhere(new BinaryExpression(columnRef,"!=",paramExpr))}if("<>"in andCondition&&andCondition["<>"]!==void 0){let paramName=`${baseName}_and_${i}_ne`,paramExpr=new ParameterExpression(paramName,andCondition["<>"]);q.appendWhere(new BinaryExpression(columnRef,"<>",paramExpr))}if("<="in andCondition&&andCondition["<="]!==void 0){let paramName=`${baseName}_and_${i}_le`,paramExpr=new ParameterExpression(paramName,andCondition["<="]);q.appendWhere(new BinaryExpression(columnRef,"<=",paramExpr))}if(">="in andCondition&&andCondition[">="]!==void 0){let paramName=`${baseName}_and_${i}_ge`,paramExpr=new ParameterExpression(paramName,andCondition[">="]);q.appendWhere(new BinaryExpression(columnRef,">=",paramExpr))}}}function injectOrConditions(q,baseName,orConditions,normalize2,availableColumns){let orExpressions=[];for(let i=0;i<orConditions.length;i++){let orCondition=orConditions[i],columnName=orCondition.column||baseName,entry=availableColumns.find(item=>normalize2(item.name)===normalize2(columnName));if(!entry)throw new Error(`Column '${columnName}' not found in query for OR condition`);let columnRef=entry.value,branchConditions=[];if("="in orCondition&&orCondition["="]!==void 0){let paramName=`${baseName}_or_${i}_eq`,paramExpr=new ParameterExpression(paramName,orCondition["="]);branchConditions.push(new BinaryExpression(columnRef,"=",paramExpr))}if("min"in orCondition&&orCondition.min!==void 0){let paramName=`${baseName}_or_${i}_min`,paramExpr=new ParameterExpression(paramName,orCondition.min);branchConditions.push(new BinaryExpression(columnRef,">=",paramExpr))}if("max"in orCondition&&orCondition.max!==void 0){let paramName=`${baseName}_or_${i}_max`,paramExpr=new ParameterExpression(paramName,orCondition.max);branchConditions.push(new BinaryExpression(columnRef,"<=",paramExpr))}if("like"in orCondition&&orCondition.like!==void 0){let paramName=`${baseName}_or_${i}_like`,paramExpr=new ParameterExpression(paramName,orCondition.like);branchConditions.push(new BinaryExpression(columnRef,"like",paramExpr))}if("ilike"in orCondition&&orCondition.ilike!==void 0){let paramName=`${baseName}_or_${i}_ilike`,paramExpr=new ParameterExpression(paramName,orCondition.ilike);branchConditions.push(new BinaryExpression(columnRef,"ilike",paramExpr))}if("in"in orCondition&&orCondition.in!==void 0){let prms=orCondition.in.map((v,j)=>new ParameterExpression(`${baseName}_or_${i}_in_${j}`,v));branchConditions.push(new BinaryExpression(columnRef,"in",new ParenExpression(new ValueList(prms))))}if("any"in orCondition&&orCondition.any!==void 0){let paramName=`${baseName}_or_${i}_any`,paramExpr=new ParameterExpression(paramName,orCondition.any);branchConditions.push(new BinaryExpression(columnRef,"=",new FunctionCall(null,"any",paramExpr,null)))}if("<"in orCondition&&orCondition["<"]!==void 0){let paramName=`${baseName}_or_${i}_lt`,paramExpr=new ParameterExpression(paramName,orCondition["<"]);branchConditions.push(new BinaryExpression(columnRef,"<",paramExpr))}if(">"in orCondition&&orCondition[">"]!==void 0){let paramName=`${baseName}_or_${i}_gt`,paramExpr=new ParameterExpression(paramName,orCondition[">"]);branchConditions.push(new BinaryExpression(columnRef,">",paramExpr))}if("!="in orCondition&&orCondition["!="]!==void 0){let paramName=`${baseName}_or_${i}_neq`,paramExpr=new ParameterExpression(paramName,orCondition["!="]);branchConditions.push(new BinaryExpression(columnRef,"!=",paramExpr))}if("<>"in orCondition&&orCondition["<>"]!==void 0){let paramName=`${baseName}_or_${i}_ne`,paramExpr=new ParameterExpression(paramName,orCondition["<>"]);branchConditions.push(new BinaryExpression(columnRef,"<>",paramExpr))}if("<="in orCondition&&orCondition["<="]!==void 0){let paramName=`${baseName}_or_${i}_le`,paramExpr=new ParameterExpression(paramName,orCondition["<="]);branchConditions.push(new BinaryExpression(columnRef,"<=",paramExpr))}if(">="in orCondition&&orCondition[">="]!==void 0){let paramName=`${baseName}_or_${i}_ge`,paramExpr=new ParameterExpression(paramName,orCondition[">="]);branchConditions.push(new BinaryExpression(columnRef,">=",paramExpr))}if(branchConditions.length>0){let branchExpr=branchConditions[0];for(let j=1;j<branchConditions.length;j++)branchExpr=new BinaryExpression(branchExpr,"and",branchConditions[j]);branchConditions.length>1?orExpressions.push(new ParenExpression(branchExpr)):orExpressions.push(branchExpr)}}if(orExpressions.length>0){let finalOrExpr=orExpressions[0];for(let i=1;i<orExpressions.length;i++)finalOrExpr=new BinaryExpression(finalOrExpr,"or",orExpressions[i]);q.appendWhere(new ParenExpression(finalOrExpr))}}function validateOperators(stateValue,allowedOps2,name){Object.keys(stateValue).forEach(op=>{if(!allowedOps2.includes(op))throw new Error(`Unsupported operator '${op}' for state key '${name}'`)})}function injectSimpleCondition(q,columnRef,name,stateValue){let paramExpr=new ParameterExpression(name,stateValue);q.appendWhere(new BinaryExpression(columnRef,"=",paramExpr))}function injectComplexConditions(q,columnRef,name,stateValue){let conditions=[];if("="in stateValue){let paramEq=new ParameterExpression(name,stateValue["="]);conditions.push(new BinaryExpression(columnRef,"=",paramEq))}if("min"in stateValue){let paramMin=new ParameterExpression(name+"_min",stateValue.min);conditions.push(new BinaryExpression(columnRef,">=",paramMin))}if("max"in stateValue){let paramMax=new ParameterExpression(name+"_max",stateValue.max);conditions.push(new BinaryExpression(columnRef,"<=",paramMax))}if("like"in stateValue){let paramLike=new ParameterExpression(name+"_like",stateValue.like);conditions.push(new BinaryExpression(columnRef,"like",paramLike))}if("ilike"in stateValue){let paramIlike=new ParameterExpression(name+"_ilike",stateValue.ilike);conditions.push(new BinaryExpression(columnRef,"ilike",paramIlike))}if("in"in stateValue){let prms=stateValue.in.map((v,i)=>new ParameterExpression(`${name}_in_${i}`,v));conditions.push(new BinaryExpression(columnRef,"in",new ParenExpression(new ValueList(prms))))}if("any"in stateValue){let paramAny=new ParameterExpression(name+"_any",stateValue.any);conditions.push(new BinaryExpression(columnRef,"=",new FunctionCall(null,"any",paramAny,null)))}if("<"in stateValue){let paramLT=new ParameterExpression(name+"_lt",stateValue["<"]);conditions.push(new BinaryExpression(columnRef,"<",paramLT))}if(">"in stateValue){let paramGT=new ParameterExpression(name+"_gt",stateValue[">"]);conditions.push(new BinaryExpression(columnRef,">",paramGT))}if("!="in stateValue){let paramNEQ=new ParameterExpression(name+"_neq",stateValue["!="]);conditions.push(new BinaryExpression(columnRef,"!=",paramNEQ))}if("<>"in stateValue){let paramNE=new ParameterExpression(name+"_ne",stateValue["<>"]);conditions.push(new BinaryExpression(columnRef,"<>",paramNE))}if("<="in stateValue){let paramLE=new ParameterExpression(name+"_le",stateValue["<="]);conditions.push(new BinaryExpression(columnRef,"<=",paramLE))}if(">="in stateValue){let paramGE=new ParameterExpression(name+"_ge",stateValue[">="]);conditions.push(new BinaryExpression(columnRef,">=",paramGE))}if(conditions.length===1)q.appendWhere(conditions[0]);else if(conditions.length>1){let combinedExpr=conditions[0];for(let i=1;i<conditions.length;i++)combinedExpr=new BinaryExpression(combinedExpr,"and",conditions[i]);q.appendWhere(new ParenExpression(combinedExpr))}}return query}isOrCondition(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&"or"in value}isAndCondition(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&"and"in value}isExplicitColumnMapping(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&"column"in value&&!("or"in value)}isValidatableObject(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&Object.getPrototypeOf(value)===Object.prototype}parseQualifiedColumnName(qualifiedName){let parts=qualifiedName.split(".");return parts.length===2&&parts[0].trim()&&parts[1].trim()?{table:parts[0].trim(),column:parts[1].trim()}:null}isQualifiedColumnName(name){return name.includes(".")&&this.parseQualifiedColumnName(name)!==null}sanitizeParameterName(name){return name.replace(/\./g,"_")}hasColumnMapping(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&"column"in value}isSimpleValue(value){return value===null||typeof value!="object"||Array.isArray(value)||value instanceof Date}processStateParameter(name,stateValue,query,finder,collector,normalize,allowedOps,injectOrConditions,injectAndConditions,injectSimpleCondition,injectComplexConditions,validateOperators){if(this.isOrCondition(stateValue)){let orConditions=stateValue.or;if(orConditions&&orConditions.length>0){let targetQuery=this.findTargetQueryForLogicalCondition(finder,query,name,orConditions),allColumns=this.getAllAvailableColumns(targetQuery,collector);injectOrConditions(targetQuery,name,orConditions,normalize,allColumns);return}}if(this.isAndCondition(stateValue)){let andConditions=stateValue.and;if(andConditions&&andConditions.length>0){let targetQuery=this.findTargetQueryForLogicalCondition(finder,query,name,andConditions),allColumns=this.getAllAvailableColumns(targetQuery,collector);injectAndConditions(targetQuery,name,andConditions,normalize,allColumns);return}}if(this.isExplicitColumnMapping(stateValue)){let explicitColumnName=stateValue.column;if(explicitColumnName){let queries=finder.find(query,explicitColumnName);if(queries.length===0)throw new Error(`Explicit column '${explicitColumnName}' not found in query`);for(let q of queries){let entry=this.getAllAvailableColumns(q,collector).find(item=>normalize(item.name)===normalize(explicitColumnName));if(!entry)throw new Error(`Explicit column '${explicitColumnName}' not found in query`);this.isValidatableObject(stateValue)&&validateOperators(stateValue,allowedOps,name),injectComplexConditions(q,entry.value,name,stateValue)}return}}this.processRegularColumnCondition(name,stateValue,query,finder,collector,normalize,allowedOps,injectSimpleCondition,injectComplexConditions,validateOperators)}processUnqualifiedParameter(name,stateValue,query,finder,collector,normalize,allowedOps,injectOrConditions,injectAndConditions,injectSimpleCondition,injectComplexConditions,validateOperators,processedQualifiedColumns){if(this.isOrCondition(stateValue)){let orConditions=stateValue.or;if(orConditions&&orConditions.length>0){let targetQuery=this.findTargetQueryForLogicalCondition(finder,query,name,orConditions),allColumns=this.getAllAvailableColumns(targetQuery,collector);injectOrConditions(targetQuery,name,orConditions,normalize,allColumns);return}}if(this.isAndCondition(stateValue)){let andConditions=stateValue.and;if(andConditions&&andConditions.length>0){let targetQuery=this.findTargetQueryForLogicalCondition(finder,query,name,andConditions),allColumns=this.getAllAvailableColumns(targetQuery,collector);injectAndConditions(targetQuery,name,andConditions,normalize,allColumns);return}}if(this.isExplicitColumnMapping(stateValue)){let explicitColumnName=stateValue.column;if(explicitColumnName){let queries2=finder.find(query,explicitColumnName);if(queries2.length===0)throw new Error(`Explicit column '${explicitColumnName}' not found in query`);for(let q of queries2){let entry=this.getAllAvailableColumns(q,collector).find(item=>normalize(item.name)===normalize(explicitColumnName));if(!entry)throw new Error(`Explicit column '${explicitColumnName}' not found in query`);this.isValidatableObject(stateValue)&&validateOperators(stateValue,allowedOps,name),injectComplexConditions(q,entry.value,name,stateValue)}return}}let queries=finder.find(query,name);if(queries.length===0){if(this.options.ignoreNonExistentColumns)return;throw new Error(`Column '${name}' not found in query`)}for(let q of queries){let allColumns=this.getAllAvailableColumns(q,collector),tableMapping=this.buildTableMapping(q),matchingColumns=allColumns.filter(item=>normalize(item.name)===normalize(name));for(let entry of matchingColumns){let skipColumn=!1;if(entry.value&&typeof entry.value.getNamespace=="function"){let namespace=entry.value.getNamespace();if(namespace){let realTableName=tableMapping.aliasToRealTable.get(namespace.toLowerCase());if(realTableName){let qualifiedKey=`${realTableName.toLowerCase()}.${name.toLowerCase()}`;processedQualifiedColumns.has(qualifiedKey)&&(skipColumn=!0)}}}if(skipColumn)continue;let columnRef=entry.value;this.isValidatableObject(stateValue)&&validateOperators(stateValue,allowedOps,name);let targetColumn=columnRef;if(this.hasColumnMapping(stateValue)){let explicitColumnName=stateValue.column;if(explicitColumnName){let explicitEntry=allColumns.find(item=>normalize(item.name)===normalize(explicitColumnName));explicitEntry&&(targetColumn=explicitEntry.value)}}this.isSimpleValue(stateValue)?injectSimpleCondition(q,targetColumn,name,stateValue):injectComplexConditions(q,targetColumn,name,stateValue)}}}processRegularColumnCondition(name,stateValue,query,finder,collector,normalize,allowedOps,injectSimpleCondition,injectComplexConditions,validateOperators){let searchColumnName=name,targetTableName;if(this.isQualifiedColumnName(name)){let parsed=this.parseQualifiedColumnName(name);parsed&&(searchColumnName=parsed.column,targetTableName=parsed.table)}let queries=finder.find(query,searchColumnName);if(queries.length===0){if(this.options.ignoreNonExistentColumns)return;throw new Error(`Column '${searchColumnName}' not found in query`)}for(let q of queries){let allColumns=this.getAllAvailableColumns(q,collector),entry;if(targetTableName){let tableMapping=this.buildTableMapping(q);if(entry=allColumns.find(item=>{if(!(normalize(item.name)===normalize(searchColumnName)))return!1;if(item.value&&typeof item.value.getNamespace=="function"){let namespace=item.value.getNamespace();if(namespace){let normalizedNamespace=normalize(namespace),normalizedTargetTable=normalize(targetTableName),realTableName=tableMapping.aliasToRealTable.get(normalizedNamespace);if(realTableName&&normalize(realTableName)===normalizedTargetTable)return!0}}return!1}),!entry){if(this.options.ignoreNonExistentColumns)continue;let tableMapping2=this.buildTableMapping(q),hasRealTable=Array.from(tableMapping2.realTableToAlias.keys()).some(realTable=>normalize(realTable)===normalize(targetTableName)),hasAliasTable=Array.from(tableMapping2.aliasToRealTable.keys()).some(alias=>normalize(alias)===normalize(targetTableName));throw!hasRealTable&&!hasAliasTable?new Error(`Column '${name}' (qualified as ${name}) not found in query`):hasAliasTable&&!hasRealTable?new Error(`Column '${name}' not found. Only real table names are allowed in qualified column references (e.g., 'users.name'), not aliases (e.g., 'u.name').`):new Error(`Column '${name}' (qualified as ${name}) not found in query`)}}else if(entry=allColumns.find(item=>normalize(item.name)===normalize(searchColumnName)),!entry)throw new Error(`Column '${searchColumnName}' not found in query`);let columnRef=entry.value;this.isValidatableObject(stateValue)&&validateOperators(stateValue,allowedOps,name);let targetColumn=columnRef;if(this.hasColumnMapping(stateValue)){let explicitColumnName=stateValue.column;if(explicitColumnName){let explicitEntry=allColumns.find(item=>normalize(item.name)===normalize(explicitColumnName));explicitEntry&&(targetColumn=explicitEntry.value)}}let parameterName=this.sanitizeParameterName(name);this.isSimpleValue(stateValue)?injectSimpleCondition(q,targetColumn,parameterName,stateValue):injectComplexConditions(q,targetColumn,parameterName,stateValue)}}findTargetQueryForLogicalCondition(finder,query,baseName,conditions){let referencedColumns=conditions.map(cond=>cond.column||baseName).filter((col,index,arr)=>arr.indexOf(col)===index);for(let colName of referencedColumns){let queries=finder.find(query,colName);if(queries.length>0)return queries[0]}let conditionType=conditions===conditions.or?"OR":"AND";throw new Error(`None of the ${conditionType} condition columns [${referencedColumns.join(", ")}] found in query`)}getAllAvailableColumns(query,collector){let columns=collector.collect(query),cteColumns=this.collectCTEColumns(query);return[...columns,...cteColumns]}collectCTEColumns(query){let cteColumns=[];if(query.withClause)for(let cte of query.withClause.tables)try{let columns=this.collectColumnsFromCteQuery(cte.query);cteColumns.push(...columns)}catch{}return cteColumns}collectColumnsFromCteQuery(query){return this.isSelectQuery(query)?this.collectColumnsFromSelectQuery(query):this.collectColumnsFromReturning(query)}collectColumnsFromSelectQuery(query){return query instanceof SimpleSelectQuery?new SelectableColumnCollector(this.tableColumnResolver,!1,"fullName",{upstream:!0}).collect(query):query instanceof BinarySelectQuery?this.collectColumnsFromSelectQuery(query.left):[]}collectColumnsFromReturning(query){if(query instanceof InsertQuery||query instanceof UpdateQuery||query instanceof DeleteQuery){if(!query.returningClause)return[];let columns=[];for(let item of query.returningClause.items){let columnName=item.identifier?.name??this.extractColumnName(item);columnName&&columns.push({name:columnName,value:item.value})}return columns}return[]}extractColumnName(item){return item.identifier?item.identifier.name:item.value instanceof ColumnReference?item.value.column.name:null}isSelectQuery(query){return"__selectQueryType"in query&&query.__selectQueryType==="SelectQuery"}buildTableMapping(query){let aliasToRealTable=new Map,realTableToAlias=new Map;try{if(query.fromClause&&(this.processSourceForMapping(query.fromClause.source,aliasToRealTable,realTableToAlias),query.fromClause.joins))for(let join of query.fromClause.joins)this.processSourceForMapping(join.source,aliasToRealTable,realTableToAlias);if(query.withClause)for(let cte of query.withClause.tables){let cteAlias=cte.getSourceAliasName();cteAlias&&(aliasToRealTable.set(cteAlias.toLowerCase(),cteAlias),realTableToAlias.set(cteAlias.toLowerCase(),cteAlias))}}catch{}return{aliasToRealTable,realTableToAlias}}processSourceForMapping(source,aliasToRealTable,realTableToAlias){try{if(source.datasource instanceof TableSource){let realTableName=source.datasource.getSourceName(),aliasName=source.aliasExpression?.table?.name||realTableName;realTableName&&aliasName&&(aliasToRealTable.set(aliasName.toLowerCase(),realTableName),realTableToAlias.set(realTableName.toLowerCase(),aliasName),aliasName===realTableName&&aliasToRealTable.set(realTableName.toLowerCase(),realTableName))}}catch{}}};var SqlSortInjector=class{constructor(tableColumnResolver){this.tableColumnResolver=tableColumnResolver}static removeOrderBy(query){if(typeof query=="string"&&(query=SelectQueryParser.parse(query)),!(query instanceof SimpleSelectQuery))throw new Error("Complex queries are not supported for ORDER BY removal");return new SimpleSelectQuery({withClause:query.withClause,selectClause:query.selectClause,fromClause:query.fromClause,whereClause:query.whereClause,groupByClause:query.groupByClause,havingClause:query.havingClause,orderByClause:null,windowClause:query.windowClause,limitClause:query.limitClause,offsetClause:query.offsetClause,fetchClause:query.fetchClause,forClause:query.forClause})}inject(query,sortConditions){if(typeof query=="string"&&(query=SelectQueryParser.parse(query)),!(query instanceof SimpleSelectQuery))throw new Error("Complex queries are not supported for sorting");let availableColumns=new SelectableColumnCollector(this.tableColumnResolver,!1,"fullName",{upstream:!0}).collect(query);for(let columnName of Object.keys(sortConditions))if(!availableColumns.find(item=>item.name===columnName))throw new Error(`Column or alias '${columnName}' not found in current query`);let newOrderByItems=[];for(let[columnName,condition]of Object.entries(sortConditions)){let columnEntry=availableColumns.find(item=>item.name===columnName);if(!columnEntry)continue;let columnRef=columnEntry.value;this.validateSortCondition(columnName,condition);let sortDirection;condition.desc?sortDirection="desc":sortDirection="asc";let nullsPosition=null;condition.nullsFirst?nullsPosition="first":condition.nullsLast&&(nullsPosition="last");let orderByItem=new OrderByItem(columnRef,sortDirection,nullsPosition);newOrderByItems.push(orderByItem)}let finalOrderByItems=[];query.orderByClause?finalOrderByItems=[...query.orderByClause.order,...newOrderByItems]:finalOrderByItems=newOrderByItems;let newOrderByClause=finalOrderByItems.length>0?new OrderByClause(finalOrderByItems):null;return new SimpleSelectQuery({withClause:query.withClause,selectClause:query.selectClause,fromClause:query.fromClause,whereClause:query.whereClause,groupByClause:query.groupByClause,havingClause:query.havingClause,orderByClause:newOrderByClause,windowClause:query.windowClause,limitClause:query.limitClause,offsetClause:query.offsetClause,fetchClause:query.fetchClause,forClause:query.forClause})}validateSortCondition(columnName,condition){if(condition.asc&&condition.desc)throw new Error(`Conflicting sort directions for column '${columnName}': both asc and desc specified`);if(condition.nullsFirst&&condition.nullsLast)throw new Error(`Conflicting nulls positions for column '${columnName}': both nullsFirst and nullsLast specified`);if(!condition.asc&&!condition.desc&&!condition.nullsFirst&&!condition.nullsLast)throw new Error(`Empty sort condition for column '${columnName}': at least one sort option must be specified`)}};var SqlPaginationInjector=class{inject(query,pagination){if(this.validatePaginationOptions(pagination),typeof query=="string"&&(query=SelectQueryParser.parse(query)),!(query instanceof SimpleSelectQuery))throw new Error("Complex queries are not supported for pagination");if(query.limitClause||query.offsetClause)throw new Error("Query already contains LIMIT or OFFSET clause. Use removePagination() first if you want to override existing pagination.");let offset=(pagination.page-1)*pagination.pageSize,limitClause=new LimitClause(new ParameterExpression("paging_limit",pagination.pageSize)),offsetClause=new OffsetClause(new ParameterExpression("paging_offset",offset));return new SimpleSelectQuery({withClause:query.withClause,selectClause:query.selectClause,fromClause:query.fromClause,whereClause:query.whereClause,groupByClause:query.groupByClause,havingClause:query.havingClause,orderByClause:query.orderByClause,windowClause:query.windowClause,limitClause,offsetClause,fetchClause:query.fetchClause,forClause:query.forClause})}static removePagination(query){if(typeof query=="string"&&(query=SelectQueryParser.parse(query)),!(query instanceof SimpleSelectQuery))throw new Error("Complex queries are not supported for pagination removal");return new SimpleSelectQuery({withClause:query.withClause,selectClause:query.selectClause,fromClause:query.fromClause,whereClause:query.whereClause,groupByClause:query.groupByClause,havingClause:query.havingClause,orderByClause:query.orderByClause,windowClause:query.windowClause,limitClause:null,offsetClause:null,fetchClause:query.fetchClause,forClause:query.forClause})}validatePaginationOptions(pagination){if(!pagination)throw new Error("Pagination options are required");if(typeof pagination.page!="number"||pagination.page<1)throw new Error("Page number must be a positive integer (1 or greater)");if(typeof pagination.pageSize!="number"||pagination.pageSize<1)throw new Error("Page size must be a positive integer (1 or greater)");if(pagination.pageSize>1e3)throw new Error("Page size cannot exceed 1000 items")}};var SqlParameterBinder=class{constructor(options={}){this.options={requireAllParameters:!0,...options}}bind(query,parameterValues){let modifiedQuery=query,existingParams=ParameterDetector.extractParameterNames(modifiedQuery);if(this.options.requireAllParameters){let missingParams=existingParams.filter(paramName=>!(paramName in parameterValues)||parameterValues[paramName]===void 0);if(missingParams.length>0)throw new Error(`Missing values for required parameters: ${missingParams.join(", ")}`)}for(let[paramName,value]of Object.entries(parameterValues))if(existingParams.includes(paramName))try{ParameterHelper.set(modifiedQuery,paramName,value)}catch(error){throw new Error(`Failed to bind parameter '${paramName}': ${error instanceof Error?error.message:"Unknown error"}`)}return modifiedQuery}bindToSimpleQuery(query,parameterValues){return this.bind(query,parameterValues)}};function injectExistsPredicates(query,instructions,options={}){if(instructions.length===0)return query;let simpleQuery=QueryBuilder.buildSimpleQuery(query),resolver=new ColumnReferenceResolver(options.tableColumnResolver),formatter=new SqlFormatter,strictMode=!!options.strict;for(let instruction of instructions)try{applyInstruction(simpleQuery,instruction,resolver,formatter)}catch(error){if(strictMode)throw error}return simpleQuery}function applyInstruction(query,instruction,resolver,formatter){if(instruction.anchorColumns.length===0)throw new Error("EXISTS instruction requires at least one anchor column.");let formattedColumns=instruction.anchorColumns.map(column=>{let columnRef=resolver.resolve(query,column);if(!columnRef)throw new Error(`Unable to resolve anchor column '${column}'.`);return columnRef}).map(component=>formatter.format(component).formattedSql),normalizedSql=substitutePlaceholders(instruction.sql,formattedColumns).trim();enforceSqlConstraints(normalizedSql);let subquery=SelectQueryParser.parse(normalizedSql);instruction.params&&bindSubqueryParameters(subquery,instruction.params);let existsExpression=new UnaryExpression("exists",new InlineQuery(subquery)),predicate=instruction.mode==="exists"?existsExpression:new UnaryExpression("not",existsExpression);query.appendWhere(predicate)}function substitutePlaceholders(sql,formattedColumns){let usedIndexes=new Set,replaced=sql.replace(/\$c(\d+)/g,(_,indexDigits)=>{let index=Number(indexDigits);if(!Number.isInteger(index))throw new Error(`Invalid placeholder '$c${indexDigits}' in EXISTS SQL.`);if(index<0||index>=formattedColumns.length)throw new Error(`Placeholder '$c${index}' references a missing anchor column.`);return usedIndexes.add(index),formattedColumns[index]});for(let i=0;i<formattedColumns.length;i++)if(!usedIndexes.has(i))throw new Error(`Missing placeholder '$c${i}' for anchor column.`);return replaced}function enforceSqlConstraints(sql){if(!sql)throw new Error("EXISTS SQL must not be empty.");if(sql.includes(";"))throw new Error("EXISTS SQL must not contain semicolons or multiple statements.");if(/\blateral\b/i.test(sql))throw new Error("LATERAL is not supported in column-anchored EXISTS filters.")}function bindSubqueryParameters(query,params){for(let[name,value]of Object.entries(params))query.setParameter(name,value)}var ColumnReferenceResolver=class{constructor(tableColumnResolver){this.tableColumnResolver=tableColumnResolver;this.finder=new UpstreamSelectQueryFinder(this.tableColumnResolver),this.collector=new SelectableColumnCollector(this.tableColumnResolver,!1,"fullName",{upstream:!0})}resolve(query,columnName){let parsed=this.parseQualifiedColumnName(columnName),searchColumn=parsed?.column??columnName,targetTable=parsed?.table,candidateQueries=this.finder.find(query,searchColumn);for(let candidate of candidateQueries){let columns=this.collectColumns(candidate),match=this.findMatchingColumn(columns,searchColumn,targetTable,candidate);if(match)return match.value}return null}collectColumns(query){let columnEntries=this.collector.collect(query),cteColumns=this.collectCTEColumns(query);return[...columnEntries,...cteColumns]}findMatchingColumn(columns,searchColumn,targetTable,query){let normalizedSearch=this.normalizeColumnName(searchColumn);for(let entry of columns)if(this.normalizeColumnName(entry.name)===normalizedSearch){if(targetTable){if(this.matchesTable(entry.value,targetTable,query))return entry;continue}return entry}return null}matchesTable(value,targetTable,query){if(!(value instanceof ColumnReference))return!1;let namespace=value.getNamespace();if(!namespace)return!1;let normalizedTarget=this.normalizeString(targetTable),mapping=this.buildTableMapping(query),aliasKey=namespace.toLowerCase(),mappedRealTable=mapping.aliasToRealTable.get(aliasKey);if(mappedRealTable&&this.normalizeString(mappedRealTable)===normalizedTarget||this.normalizeString(namespace)===normalizedTarget)return!0;let aliasFromTarget=mapping.realTableToAlias.get(normalizedTarget);return!!(aliasFromTarget&&aliasFromTarget.toLowerCase()===aliasKey)}collectCTEColumns(query){let results=[];if(!query.withClause)return results;for(let cte of query.withClause.tables)try{let nestedColumns=this.collectColumnsFromCteQuery(cte.query);results.push(...nestedColumns)}catch{}return results}collectColumnsFromCteQuery(query){return this.isSelectQuery(query)?this.collectColumnsFromSelectQuery(query):this.collectColumnsFromReturning(query)}collectColumnsFromSelectQuery(query){return query instanceof SimpleSelectQuery?this.collector.collect(query):query instanceof BinarySelectQuery?this.collectColumnsFromSelectQuery(query.left):[]}collectColumnsFromReturning(query){return query instanceof InsertQuery||query instanceof UpdateQuery||query instanceof DeleteQuery?this.extractReturningColumns(query.returningClause):[]}extractReturningColumns(returningClause){if(!returningClause)return[];let columns=[];for(let item of returningClause.items){let columnName=item.identifier?.name??this.extractColumnName(item);columnName&&columns.push({name:columnName,value:item.value})}return columns}extractColumnName(item){return item.identifier?item.identifier.name:item.value instanceof ColumnReference?item.value.column.name:null}buildTableMapping(query){let aliasToRealMap=new Map,realToAliasMap=new Map;if((fromClause=>{if(fromClause&&(this.processSourceForMapping(fromClause.source,aliasToRealMap,realToAliasMap),fromClause.joins))for(let join of fromClause.joins)this.processSourceForMapping(join.source,aliasToRealMap,realToAliasMap)})(query.fromClause??void 0),query.withClause)for(let cte of query.withClause.tables){let alias=cte.getSourceAliasName()?.toLowerCase();alias&&(aliasToRealMap.set(alias,alias),realToAliasMap.set(alias,alias))}return{aliasToRealTable:aliasToRealMap,realTableToAlias:realToAliasMap}}processSourceForMapping(source,aliasToReal,realToAlias){try{if(source.datasource instanceof TableSource){let realName=source.datasource.getSourceName(),aliasName=source.aliasExpression?.table?.name||realName;realName&&aliasName&&(aliasToReal.set(aliasName.toLowerCase(),realName),realToAlias.set(realName.toLowerCase(),aliasName),aliasName.toLowerCase()===realName.toLowerCase()&&aliasToReal.set(realName.toLowerCase(),realName))}}catch{}}parseQualifiedColumnName(columnName){let parts=columnName.split(".");return parts.length===2&&parts[0].trim()&&parts[1].trim()?{table:parts[0].trim(),column:parts[1].trim()}:null}normalizeColumnName(name){let columnPart=name.includes(".")?name.split(".").pop()??name:name;return this.normalizeString(columnPart)}normalizeString(value){return value.toLowerCase()}isSelectQuery(query){return"__selectQueryType"in query&&query.__selectQueryType==="SelectQuery"}};var NAMESPACE_SEPARATOR="|",normalizeIdentifier=input=>{let value=input?.trim()??"";return value===""?"":value.toLowerCase()},normalizeColumnSetKey=columns=>columns.map(column=>normalizeIdentifier(column)).filter(Boolean).sort().join(NAMESPACE_SEPARATOR),buildSchemaMap=schemaInfo=>{let map=new Map;for(let table of schemaInfo){let normalizedName=normalizeIdentifier(table.name);if(!normalizedName)continue;let columnSet=new Set(table.columns.map(normalizeIdentifier).filter(Boolean)),uniqueSetKeys=new Set;for(let uniqueKey of table.uniqueKeys){let normalizedKey=normalizeColumnSetKey(uniqueKey);normalizedKey&&uniqueSetKeys.add(normalizedKey)}columnSet.size===0&&uniqueSetKeys.size===0||map.set(normalizedName,{columnSet,uniqueSetKeys})}return map},collectReferenceMetadata=query=>{let collector=new ColumnReferenceCollector,namespaceCounts=new Map,unqualifiedColumns=new Set;for(let ref of collector.collect(query)){let namespace=normalizeIdentifier(ref.getNamespace());if(namespace)namespaceCounts.set(namespace,(namespaceCounts.get(namespace)??0)+1);else{let column=normalizeIdentifier(ref.column.name);column&&unqualifiedColumns.add(column)}}let joinConditionCounts=new Map;if(query.fromClause?.joins)for(let join of query.fromClause.joins){let counts=new Map;if(join.condition&&join.condition instanceof JoinOnClause){let joinCollector=new ColumnReferenceCollector;for(let ref of joinCollector.collect(join.condition.condition)){let namespace=normalizeIdentifier(ref.getNamespace());namespace&&counts.set(namespace,(counts.get(namespace)??0)+1)}}joinConditionCounts.set(join,counts)}return{namespaceCounts,unqualifiedColumns,joinConditionCounts}},isLeftJoin=join=>join.joinType.value.toLowerCase().includes("left"),getJoinIdentifiers=join=>{let identifiers=new Set,alias=normalizeIdentifier(join.source.getAliasName());if(alias&&identifiers.add(alias),join.source.datasource instanceof TableSource){let rawName=join.source.datasource.getSourceName();rawName&&identifiers.add(normalizeIdentifier(rawName));let shortName=normalizeIdentifier(join.source.datasource.table.name);shortName&&identifiers.add(shortName)}return[...identifiers]},hasExternalReferences=(identifiers,metadata,join)=>{let local=metadata.joinConditionCounts.get(join)??new Map;for(let identifier of identifiers){let total=metadata.namespaceCounts.get(identifier)??0,localCount=local.get(identifier)??0;if(total-localCount>0)return!0}return!1},getJoinColumnInfo=(join,identifiers)=>{if(!(join.condition instanceof JoinOnClause))return null;let expression=join.condition.condition;if(!(expression instanceof BinaryExpression)||expression.operator.value.trim().toLowerCase()!=="=")return null;let resolveColumn=component=>component instanceof ColumnReference?component:null,leftRef=resolveColumn(expression.left),rightRef=resolveColumn(expression.right);if(!leftRef||!rightRef)return null;let normalizedLeftNamespace=normalizeIdentifier(leftRef.getNamespace()),normalizedRightNamespace=normalizeIdentifier(rightRef.getNamespace());return identifiers.has(normalizedLeftNamespace)?normalizeIdentifier(leftRef.column.name):identifiers.has(normalizedRightNamespace)?normalizeIdentifier(rightRef.column.name):null},shouldRemoveJoin=(join,schemaMap,metadata)=>{if(!isLeftJoin(join)||join.lateral||!(join.source.datasource instanceof TableSource))return!1;let candidates=[normalizeIdentifier(join.source.datasource.getSourceName()),normalizeIdentifier(join.source.datasource.table.name)].filter(Boolean),tableInfo;for(let candidate of candidates){let info=schemaMap.get(candidate);if(info){tableInfo=info;break}}if(!tableInfo)return!1;let identifiers=new Set(getJoinIdentifiers(join));if(identifiers.size===0||hasExternalReferences([...identifiers],metadata,join))return!1;let joinColumn=getJoinColumnInfo(join,identifiers);if(!joinColumn||metadata.unqualifiedColumns.has(joinColumn)||tableInfo.columnSet.size>0&&!tableInfo.columnSet.has(joinColumn))return!1;let uniqueKey=normalizeColumnSetKey([joinColumn]);return!!tableInfo.uniqueSetKeys.has(uniqueKey)},optimizeSimpleQuery=(query,schemaMap)=>{if(!query.fromClause?.joins?.length)return!1;let metadata=collectReferenceMetadata(query),retainedJoins=[],removed=!1;for(let join of query.fromClause.joins){if(shouldRemoveJoin(join,schemaMap,metadata)){removed=!0;continue}retainedJoins.push(join)}return query.fromClause.joins=retainedJoins.length>0?retainedJoins:null,removed},traverseSelectQuery=(query,schemaMap)=>{if(query instanceof SimpleSelectQuery)return optimizeSimpleQuery(query,schemaMap);if(query instanceof BinarySelectQuery){let leftChanged=traverseSelectQuery(query.left,schemaMap),rightChanged=traverseSelectQuery(query.right,schemaMap);return leftChanged||rightChanged}return!1},optimizeUnusedLeftJoinsOnce=(query,schemaMap)=>schemaMap.size===0?!1:traverseSelectQuery(query,schemaMap),optimizeUnusedLeftJoins=(query,schemaInfo)=>(optimizeUnusedLeftJoinsOnce(query,buildSchemaMap(schemaInfo)),query),optimizeUnusedLeftJoinsToFixedPoint=(query,schemaInfo)=>{let schemaMap=buildSchemaMap(schemaInfo),changed=!0;for(;changed;)changed=optimizeUnusedLeftJoinsOnce(query,schemaMap);return query},collectTableSourceNames=component=>{let collector=new CTETableReferenceCollector,names=new Set;for(let source of collector.collect(component)){let normalizedName=normalizeIdentifier(source.table.name);normalizedName&&names.add(normalizedName)}return names},isReferencedByOthers=(cteName,mainReferences,cteReferenceMap)=>{if(mainReferences.has(cteName))return!0;for(let[otherName,references]of cteReferenceMap)if(otherName!==cteName&&references.has(cteName))return!0;return!1},optimizeSimpleQueryCtes=query=>{let withClause=query.withClause;if(!withClause||withClause.recursive||withClause.tables.length===0)return!1;let mainReferences=collectTableSourceNames(query),cteReferenceMap=new Map;for(let table of withClause.tables){let normalizedName=normalizeIdentifier(table.aliasExpression.table.name);normalizedName&&cteReferenceMap.set(normalizedName,collectTableSourceNames(table.query))}let removableNames=[];for(let table of withClause.tables){let normalizedName=normalizeIdentifier(table.aliasExpression.table.name);if(!normalizedName)continue;let body=table.query;!(body instanceof SimpleSelectQuery)&&!(body instanceof BinarySelectQuery)||isReferencedByOthers(normalizedName,mainReferences,cteReferenceMap)||removableNames.push(normalizedName)}if(removableNames.length===0)return!1;for(let name of removableNames)query.removeCTE(name);return!0},optimizeCtesInSelectQuery=query=>{if(query instanceof SimpleSelectQuery)return optimizeSimpleQueryCtes(query);if(query instanceof BinarySelectQuery){let leftChanged=optimizeCtesInSelectQuery(query.left),rightChanged=optimizeCtesInSelectQuery(query.right);return leftChanged||rightChanged}return!1},optimizeUnusedCtesOnce=query=>optimizeCtesInSelectQuery(query),optimizeUnusedCtes=query=>(optimizeUnusedCtesOnce(query),query),optimizeUnusedCtesToFixedPoint=query=>{let changed=!0;for(;changed;)changed=optimizeUnusedCtesOnce(query);return query};var SUPPORTED_COMPARISON_OPERATORS=new Set(["=","<>","!=",">",">=","<","<="]),isBinaryOperator=(expression,operator)=>expression instanceof BinaryExpression&&expression.operator.value.trim().toLowerCase()===operator,unwrapSingleOuterParen=expression=>{let candidate=expression;for(;candidate instanceof ParenExpression;)candidate=candidate.expression;return candidate},collectTopLevelAndTerms=expression=>{let candidate=unwrapSingleOuterParen(expression);return isBinaryOperator(candidate,"and")?[...collectTopLevelAndTerms(candidate.left),...collectTopLevelAndTerms(candidate.right)]:[expression]},isNullLiteral=expression=>expression instanceof LiteralValue&&expression.value===null||expression instanceof RawString&&expression.value.trim().toLowerCase()==="null",isTrueSentinel=expression=>{let candidate=unwrapSingleOuterParen(expression);return candidate instanceof LiteralValue?candidate.value===!0:isBinaryOperator(candidate,"=")?candidate.left instanceof LiteralValue&&candidate.right instanceof LiteralValue&&candidate.left.value===1&&candidate.right.value===1:!1},getGuardedParameterName=expression=>{let candidate=unwrapSingleOuterParen(expression);return!isBinaryOperator(candidate,"is")||!(candidate.left instanceof ParameterExpression)||!isNullLiteral(candidate.right)?null:candidate.left.name.value},getUniqueParameterNames=expression=>new Set(ParameterCollector.collect(expression).map(parameter=>parameter.name.value)),isSupportedScalarPredicate=(expression,parameterName)=>{let candidate=unwrapSingleOuterParen(expression);if(!(candidate instanceof BinaryExpression))return!1;let operator=candidate.operator.value.trim().toLowerCase();if(!SUPPORTED_COMPARISON_OPERATORS.has(operator))return!1;let leftIsTargetParameter=candidate.left instanceof ParameterExpression&&candidate.left.name.value===parameterName,rightIsTargetParameter=candidate.right instanceof ParameterExpression&&candidate.right.name.value===parameterName;return leftIsTargetParameter===rightIsTargetParameter?!1:getUniqueParameterNames(candidate).size===1},isSupportedExistsPredicate=(expression,parameterName)=>{let candidate=unwrapSingleOuterParen(expression);if(!(candidate instanceof UnaryExpression)||candidate.operator.value.trim().toLowerCase()!=="exists"||!(candidate.expression instanceof InlineQuery))return!1;let parameterNames=getUniqueParameterNames(candidate.expression);return parameterNames.size===1&¶meterNames.has(parameterName)},isExplicitPruningTarget=(pruningParameters,parameterName)=>Object.prototype.hasOwnProperty.call(pruningParameters,parameterName),isKnownAbsentTarget=(pruningParameters,parameterName)=>{if(!isExplicitPruningTarget(pruningParameters,parameterName))return!1;let parameterValue=pruningParameters[parameterName];return parameterValue==null},shouldPruneOptionalBranch=(expression,pruningParameters)=>{let candidate=unwrapSingleOuterParen(expression);if(!isBinaryOperator(candidate,"or"))return!1;let parameterName=getGuardedParameterName(candidate.left);return!parameterName||!(isSupportedScalarPredicate(candidate.right,parameterName)||isSupportedExistsPredicate(candidate.right,parameterName))?!1:isKnownAbsentTarget(pruningParameters,parameterName)},rebuildAndCondition=terms=>{if(terms.length===0)return null;let condition=terms[0];for(let index=1;index<terms.length;index+=1)condition=new BinaryExpression(condition,"and",terms[index]);return condition},pruneSimpleQueryWhereClause=(query,pruningParameters)=>{if(!query.whereClause)return!1;let topLevelTerms=collectTopLevelAndTerms(query.whereClause.condition),retainedTerms=[],prunedAnyBranch=!1;for(let term of topLevelTerms){if(shouldPruneOptionalBranch(term,pruningParameters)){prunedAnyBranch=!0;continue}retainedTerms.push(term)}if(!prunedAnyBranch)return!1;let cleanedTerms=retainedTerms.filter(term=>!isTrueSentinel(term)),rebuiltCondition=rebuildAndCondition(cleanedTerms);return query.whereClause=rebuiltCondition?new WhereClause(rebuiltCondition):null,!0},isSelectQueryNode=value=>value instanceof SimpleSelectQuery||value instanceof BinarySelectQuery,traverseNestedSelectQueries=(root,pruningParameters)=>{let changed=!1,visited=new WeakSet,walk=value=>{if(!(!value||typeof value!="object")&&!visited.has(value)){if(visited.add(value),value!==root&&isSelectQueryNode(value)){changed=traverseSelectQuery2(value,pruningParameters)||changed;return}if(Array.isArray(value)){value.forEach(walk);return}for(let child of Object.values(value))walk(child)}};return walk(root),changed},traverseSelectQuery2=(query,pruningParameters)=>{if(query instanceof SimpleSelectQuery){let selfChanged=pruneSimpleQueryWhereClause(query,pruningParameters),nestedChanged=traverseNestedSelectQueries(query,pruningParameters);return selfChanged||nestedChanged}if(query instanceof BinarySelectQuery){let leftChanged=traverseSelectQuery2(query.left,pruningParameters),rightChanged=traverseSelectQuery2(query.right,pruningParameters);return leftChanged||rightChanged}return!1},pruneOptionalConditionBranches=(query,pruningParameters)=>(Object.keys(pruningParameters).length===0||traverseSelectQuery2(query,pruningParameters),query);var DynamicQueryBuilder=class{constructor(resolverOrOptions){typeof resolverOrOptions=="function"?this.tableColumnResolver=resolverOrOptions:resolverOrOptions&&(this.tableColumnResolver=resolverOrOptions.tableColumnResolver,this.defaultSchemaInfo=resolverOrOptions.schemaInfo)}buildQuery(sqlContent,options={}){let parsedQuery;try{parsedQuery=SelectQueryParser.parse(sqlContent)}catch(error){throw new Error(`Failed to parse SQL: ${error instanceof Error?error.message:"Unknown error"}`)}let modifiedQuery=parsedQuery;if(options.filter&&Object.keys(options.filter).length>0){let{hardcodedParams,dynamicFilters}=ParameterDetector.separateFilters(modifiedQuery,options.filter);Object.keys(hardcodedParams).length>0&&(modifiedQuery=new SqlParameterBinder({requireAllParameters:!1}).bind(modifiedQuery,hardcodedParams));let{filters:cleanedFilters,instructions:existsInstructions}=this.extractExistsInstructions(dynamicFilters);if(Object.keys(cleanedFilters).length>0){let paramInjector=new SqlParamInjector(this.tableColumnResolver),simpleQuery=QueryBuilder.buildSimpleQuery(modifiedQuery);modifiedQuery=paramInjector.inject(simpleQuery,cleanedFilters)}existsInstructions.length>0&&(modifiedQuery=injectExistsPredicates(modifiedQuery,existsInstructions,{tableColumnResolver:this.tableColumnResolver,strict:!!options.existsStrict}))}if(options.sort&&Object.keys(options.sort).length>0){let sortInjector=new SqlSortInjector(this.tableColumnResolver),simpleQuery=QueryBuilder.buildSimpleQuery(modifiedQuery);modifiedQuery=sortInjector.inject(simpleQuery,options.sort)}if(options.paging){let{page=1,pageSize}=options.paging;if(pageSize!==void 0){let paginationInjector=new SqlPaginationInjector,paginationOptions={page,pageSize},simpleQuery=QueryBuilder.buildSimpleQuery(modifiedQuery);modifiedQuery=paginationInjector.inject(simpleQuery,paginationOptions)}}modifiedQuery=this.applyColumnFilters(modifiedQuery,options);let optionalConditionParameters=this.resolveOptionalConditionPruningParameters(options);Object.keys(optionalConditionParameters).length>0&&(modifiedQuery=pruneOptionalConditionBranches(modifiedQuery,optionalConditionParameters));let effectiveSchemaInfo=options.schemaInfo??this.defaultSchemaInfo;if(options.removeUnusedLeftJoins&&effectiveSchemaInfo?.length&&(modifiedQuery=optimizeUnusedLeftJoinsToFixedPoint(modifiedQuery,effectiveSchemaInfo)),options.removeUnusedCtes&&(modifiedQuery=optimizeUnusedCtesToFixedPoint(modifiedQuery)),options.serialize&&typeof options.serialize=="object"){let jsonBuilder=new PostgresJsonQueryBuilder,simpleQuery=QueryBuilder.buildSimpleQuery(modifiedQuery);modifiedQuery=jsonBuilder.buildJsonQuery(simpleQuery,options.serialize)}return modifiedQuery}resolveOptionalConditionPruningParameters(options){if(options.optionalConditionParameters)return options.optionalConditionParameters;if(!options.optionalConditionParameterStates)return{};let legacyParameters={};for(let[parameterName,state]of Object.entries(options.optionalConditionParameterStates))legacyParameters[parameterName]=state==="absent"?null:"__RAWSQL_OPTIONAL_CONDITION_PRESENT__";return legacyParameters}extractExistsInstructions(filters){let cleanedFilters={},instructions=[];for(let[key,value]of Object.entries(filters)){if(key==="$exists"||key==="$notExists"){if(!this.isMultiColumnDefinitionArray(value))throw new Error(`'${key}' must be an array of EXISTS definitions.`);this.handleMultiAnchorDefinitions(key,value,instructions);continue}if(this.isFilterConditionObject(value)){let{leftover,exists,notExists}=this.splitExistsProperties(value);exists&&instructions.push(this.createExistsInstruction([key],exists,"exists")),notExists&&instructions.push(this.createExistsInstruction([key],notExists,"notExists")),leftover&&(cleanedFilters[key]=leftover);continue}this.isMultiColumnDefinitionArray(value)||(cleanedFilters[key]=value)}return{filters:cleanedFilters,instructions}}handleMultiAnchorDefinitions(key,definitions,instructions){for(let definition of definitions){if(!definition.on||definition.on.length===0)throw new Error(`Every ${key} instruction must specify an "on" array.`);instructions.push(this.createExistsInstruction(definition.on,definition,key==="$notExists"?"notExists":"exists"))}}splitExistsProperties(value){let{exists,notExists,...rest}=value;return{leftover:Object.keys(rest).length>0?rest:void 0,exists,notExists}}isFilterConditionObject(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}isMultiColumnDefinitionArray(value){return Array.isArray(value)&&value.every(entry=>this.isMultiColumnDefinition(entry))}isMultiColumnDefinition(value){if(!value||typeof value!="object")return!1;let candidate=value;return Array.isArray(candidate.on)&&candidate.on.length>0&&candidate.on.every(column=>typeof column=="string")&&typeof candidate.sql=="string"}createExistsInstruction(anchors,definition,mode){if(!definition.sql||typeof definition.sql!="string")throw new Error("EXISTS definition must include a SQL string.");return{mode,anchorColumns:anchors,sql:definition.sql,params:definition.params}}applyColumnFilters(query,options){let hasIncludeFilters=Array.isArray(options.includeColumns)&&options.includeColumns.length>0,hasExcludeFilters=Array.isArray(options.excludeColumns)&&options.excludeColumns.length>0;if(!hasIncludeFilters&&!hasExcludeFilters)return query;if(hasIncludeFilters&&hasExcludeFilters)throw new Error("includeColumns and excludeColumns cannot be used together.");let simpleQuery=QueryBuilder.buildSimpleQuery(query),metadata=simpleQuery.selectClause.items.map(item=>{let name=this.getSelectItemName(item);return{item,normalized:name?this.normalizeColumnIdentifier(name):null}}),availableColumns=new Set(metadata.map(entry=>entry.normalized).filter(name=>name!==null)),includeFilters=hasIncludeFilters?this.normalizeColumnList(options.includeColumns):null,excludeFilters=hasExcludeFilters?this.normalizeColumnList(options.excludeColumns):null,includeSet=includeFilters?new Set(includeFilters.map(entry=>entry.normalized)):null,excludeSet=excludeFilters?new Set(excludeFilters.map(entry=>entry.normalized)):null;if(includeFilters){let missing=includeFilters.filter(entry=>!availableColumns.has(entry.normalized));if(missing.length>0)throw new Error(`Column${missing.length===1?"":"s"} not found in SELECT clause: ${missing.map(entry=>`'${entry.original}'`).join(", ")}.`)}if(excludeFilters){let missing=excludeFilters.filter(entry=>!availableColumns.has(entry.normalized));if(missing.length>0)throw new Error(`Column${missing.length===1?"":"s"} not found in SELECT clause: ${missing.map(entry=>`'${entry.original}'`).join(", ")}.`)}let filteredItems=metadata.filter(entry=>entry.normalized?includeSet?includeSet.has(entry.normalized):excludeSet?!excludeSet.has(entry.normalized):!0:!0).map(entry=>entry.item);if(filteredItems.length===0)throw new Error("Column filtering removed every SELECT item.");return simpleQuery.selectClause.items=filteredItems,simpleQuery}normalizeColumnList(columns){return columns.map(column=>{if(typeof column!="string")throw new Error("Column filters must be strings.");let trimmed=column.trim();if(trimmed==="")throw new Error("Column filters must not be empty.");return{normalized:this.normalizeColumnIdentifier(trimmed),original:trimmed}})}normalizeColumnIdentifier(value){return value.trim().toLowerCase()}getSelectItemName(item){return item.identifier?item.identifier.name:item.value instanceof ColumnReference?item.value.column.name:null}buildFilteredQuery(sqlContent,filter){return this.buildQuery(sqlContent,{filter})}buildSortedQuery(sqlContent,sort){return this.buildQuery(sqlContent,{sort})}buildPaginatedQuery(sqlContent,paging){return this.buildQuery(sqlContent,{paging})}buildSerializedQuery(sqlContent,serialize){return this.buildQuery(sqlContent,{serialize})}validateSql(sqlContent){try{return SelectQueryParser.parse(sqlContent),!0}catch(error){throw new Error(`Invalid SQL: ${error instanceof Error?error.message:"Unknown error"}`)}}};function convertModelDrivenMapping(modelMapping){let protectedStringFields=[],entityIdCounter=0,propertyNameCounters={},generateEntityId=()=>`entity_${++entityIdCounter}`,generateUniquePropertyName=baseName=>(propertyNameCounters[baseName]||(propertyNameCounters[baseName]=0),propertyNameCounters[baseName]++,propertyNameCounters[baseName]===1?baseName:`${baseName}_${propertyNameCounters[baseName]}`),processStructure=(structure,parentId=null)=>{let columns={},nestedEntities=[];for(let[fieldName,config]of Object.entries(structure))if(typeof config=="string")columns[fieldName]=config;else if("column"in config&&typeof config.column=="string"&&!("type"in config&&(config.type==="object"||config.type==="array"))){let fieldConfig=config;typeof fieldConfig=="object"&&"column"in fieldConfig&&(columns[fieldName]=fieldConfig.column,fieldConfig.type==="string"&&protectedStringFields.push(fieldConfig.column))}else if("from"in config&&typeof config.from=="string"&&!("type"in config&&(config.type==="object"||config.type==="array"))){let fieldConfig=config;typeof fieldConfig=="object"&&"from"in fieldConfig&&(columns[fieldName]=fieldConfig.from,fieldConfig.type==="string"&&protectedStringFields.push(fieldConfig.from))}else if("type"in config&&(config.type==="object"||config.type==="array")){let nestedStructure=config,uniquePropertyName=generateUniquePropertyName(fieldName),entityId=generateEntityId(),processedNested=processStructure(nestedStructure.structure,entityId);nestedEntities.push({id:entityId,name:fieldName.charAt(0).toUpperCase()+fieldName.slice(1),parentId:parentId||"root",propertyName:uniquePropertyName,originalPropertyName:fieldName,relationshipType:nestedStructure.type,columns:processedNested.columns}),nestedEntities.push(...processedNested.nestedEntities.map(entity=>({...entity,parentId:entity.parentId==="root"?entityId:entity.parentId})))}return{columns,nestedEntities}},processed=processStructure(modelMapping.structure),jsonMapping={rootName:"root",rootEntity:{id:"root",name:"Root",columns:processed.columns},nestedEntities:processed.nestedEntities};return jsonMapping.typeInfo=modelMapping.typeInfo,{jsonMapping,typeProtection:{protectedStringFields}}}function validateModelDrivenMapping(mapping){let errors=[];return mapping.typeInfo?(mapping.typeInfo.interface||errors.push("typeInfo.interface is required"),mapping.typeInfo.importPath||errors.push("typeInfo.importPath is required")):errors.push("typeInfo is required"),(!mapping.structure||typeof mapping.structure!="object")&&errors.push("structure is required and must be an object"),errors}function convertColumnsToLegacy(columns){let result={};for(let[key,config]of Object.entries(columns))typeof config=="string"?result[key]=config:config&&typeof config=="object"?"column"in config?result[key]=config.column:"from"in config?result[key]=config.from:result[key]=key:result[key]=key;return result}function convertToLegacyJsonMapping(input){if(!input)throw new Error("Input mapping is required");if(input.rootName&&input.rootEntity&&typeof input.rootEntity.columns=="object"&&!input.typeInfo&&!input.typeProtection&&!input.metadata&&Object.values(input.rootEntity.columns).every(col=>typeof col=="string"))return input;if(input.rootName&&input.rootEntity)return{rootName:input.rootName,rootEntity:{id:input.rootEntity.id||"root",name:input.rootEntity.name||input.rootName,columns:convertColumnsToLegacy(input.rootEntity.columns||{})},nestedEntities:(input.nestedEntities||[]).map(entity=>({id:entity.id,name:entity.name,parentId:entity.parentId,propertyName:entity.propertyName,relationshipType:entity.relationshipType,columns:convertColumnsToLegacy(entity.columns||{})})),resultFormat:input.resultFormat,emptyResult:input.emptyResult};throw new Error("Unsupported mapping format")}function toLegacyMapping(enhanced){return{rootName:enhanced.rootName,rootEntity:{id:enhanced.rootEntity.id,name:enhanced.rootEntity.name,columns:convertColumnsToLegacy(enhanced.rootEntity.columns)},nestedEntities:enhanced.nestedEntities.map(entity=>({id:entity.id,name:entity.name,parentId:entity.parentId,propertyName:entity.propertyName,relationshipType:entity.relationshipType,columns:convertColumnsToLegacy(entity.columns)})),resultFormat:enhanced.resultFormat,emptyResult:enhanced.emptyResult}}function extractTypeProtection(enhanced){let protectedStringFields=[],dateFields=[],numberFields=[];if(enhanced.typeProtection)return{protectedStringFields:enhanced.typeProtection.protectedStringFields||[],dateFields:enhanced.typeProtection.dateFields,numberFields:enhanced.typeProtection.numberFields,customTransforms:enhanced.typeProtection.customTransforms};for(let[key,config]of Object.entries(enhanced.rootEntity.columns))if(typeof config=="object"&&config.type){let columnName=config.column;switch(config.type){case"string":protectedStringFields.push(columnName);break;case"date":dateFields.push(columnName);break;case"number":numberFields.push(columnName);break}}for(let entity of enhanced.nestedEntities)for(let[key,config]of Object.entries(entity.columns))if(typeof config=="object"&&config.type){let columnName=config.column;switch(config.type){case"string":protectedStringFields.push(columnName);break;case"date":dateFields.push(columnName);break;case"number":numberFields.push(columnName);break}}return{protectedStringFields,dateFields:dateFields.length>0?dateFields:void 0,numberFields:numberFields.length>0?numberFields:void 0,customTransforms:void 0}}function isValidMappingInput(input){return input!=null&&typeof input=="object"}var EnhancedFormatStrategy=class{detect(input){if(!isValidMappingInput(input))return!1;let candidate=input;if(!candidate||typeof candidate.rootName!="string"||!candidate.rootEntity||!Array.isArray(candidate.nestedEntities))return!1;if(candidate.typeInfo||candidate.typeProtection||candidate.metadata)return!0;let hasEnhancedColumns=columns=>!columns||typeof columns!="object"?!1:Object.values(columns).some(col=>typeof col=="object"&&col!==null&&"column"in col);return hasEnhancedColumns(candidate.rootEntity.columns)?!0:candidate.nestedEntities.some(entity=>entity&&typeof entity=="object"&&hasEnhancedColumns(entity.columns))}convert(input){return{format:"enhanced",mapping:toLegacyMapping(input),typeProtection:extractTypeProtection(input),originalInput:input,metadata:{typeInfo:input.typeInfo,version:input.metadata?.version,description:input.metadata?.description}}}},ModelDrivenFormatStrategy=class{detect(input){if(!isValidMappingInput(input))return!1;let candidate=input;return candidate&&candidate.typeInfo&&candidate.structure&&typeof candidate.typeInfo.interface=="string"}convert(input){let converted=convertModelDrivenMapping(input);return{format:"model-driven",mapping:converted.jsonMapping,typeProtection:converted.typeProtection,originalInput:input,metadata:{typeInfo:input.typeInfo}}}},LegacyFormatStrategy=class{detect(input){if(!isValidMappingInput(input))return!1;let candidate=input;if(!candidate||typeof candidate.rootName!="string"||!candidate.rootEntity||typeof candidate.rootEntity.columns!="object"||candidate.typeInfo||candidate.typeProtection||candidate.metadata)return!1;let hasEnhancedColumns=columns=>!columns||typeof columns!="object"?!1:Object.values(columns).some(col=>typeof col=="object"&&col!==null&&"column"in col);return!(hasEnhancedColumns(candidate.rootEntity.columns)||candidate.nestedEntities&&Array.isArray(candidate.nestedEntities)&&candidate.nestedEntities.some(entity=>entity&&typeof entity=="object"&&hasEnhancedColumns(entity.columns)))}convert(input){return{format:"legacy",mapping:input,typeProtection:{protectedStringFields:[]},originalInput:input}}},JsonMappingConverter=class{constructor(){this.strategies=[new EnhancedFormatStrategy,new ModelDrivenFormatStrategy,new LegacyFormatStrategy]}detectFormat(input){for(let strategy of this.strategies)if(strategy.detect(input))return strategy.convert(input).format;throw new Error("Unsupported JSON mapping format")}convert(input){for(let strategy of this.strategies)if(strategy.detect(input))return strategy.convert(input);throw new Error("Unsupported JSON mapping format: Unable to detect a compatible strategy for the provided input")}toLegacyMapping(input){return this.convert(input).mapping}getTypeProtection(input){return this.convert(input).typeProtection}validate(input){let errors=[];if(!input||typeof input!="object")return errors.push("Input must be an object"),errors;(!("rootName"in input)||!input.rootName)&&errors.push("rootName is required");try{let result=this.convert(input);if(result.mapping.rootName||errors.push("rootName is required"),result.mapping.rootEntity?(result.mapping.rootEntity.id||errors.push("rootEntity.id is required"),result.mapping.rootEntity.columns||errors.push("rootEntity.columns is required")):errors.push("rootEntity is required"),result.mapping.nestedEntities)for(let entity of result.mapping.nestedEntities)entity.id||errors.push(`Nested entity missing id: ${entity.propertyName}`),entity.parentId||errors.push(`Nested entity missing parentId: ${entity.id}`),entity.propertyName||errors.push(`Nested entity missing propertyName: ${entity.id}`)}catch(error){errors.length===0&&errors.push(`Conversion failed: ${error instanceof Error?error.message:String(error)}`)}return errors}upgradeToEnhanced(legacy,typeInfo){return{rootName:legacy.rootName,rootEntity:{id:legacy.rootEntity.id,name:legacy.rootEntity.name,columns:legacy.rootEntity.columns},nestedEntities:legacy.nestedEntities.map(entity=>({id:entity.id,name:entity.name,parentId:entity.parentId,propertyName:entity.propertyName,relationshipType:entity.relationshipType||"object",columns:entity.columns})),resultFormat:legacy.resultFormat,emptyResult:legacy.emptyResult,typeInfo,metadata:{version:"1.0",description:"Upgraded from legacy format"}}}};function detectMappingFormat(input){return input.typeInfo&&input.structure?"model-driven":input.rootName&&input.rootEntity?"unified":(input.columns||input.relationships,"legacy")}function convertLegacyFormat(input){let result={rootName:input.rootName||"root",rootEntity:{id:"root",name:input.rootName||"Root",columns:input.columns||{}},nestedEntities:[]};if(input.relationships&&typeof input.relationships=="object")for(let[propertyName,relationship]of Object.entries(input.relationships)){let rel=relationship;result.nestedEntities.push({id:propertyName,name:propertyName.charAt(0).toUpperCase()+propertyName.slice(1),parentId:"root",propertyName,relationshipType:rel.type==="hasMany"?"array":"object",columns:rel.columns||{}})}return result}function processJsonMapping(input){if(console.warn("\u26A0\uFE0F DEPRECATED: processJsonMapping() is deprecated. Use JsonMappingConverter.convert() instead."),console.warn("Migration guide: https://github.com/mk3008/rawsql-ts/blob/main/docs/migration-guide.md"),(input.columns||input.relationships)&&!input.rootName&&!input.rootEntity)return{format:"legacy",jsonMapping:convertLegacyFormat(input),originalInput:input,metadata:{}};let result=new JsonMappingConverter().convert(input),format=result.format;return result.format==="legacy"&&input.rootName&&input.rootEntity&&(format="unified"),{format,jsonMapping:result.mapping,originalInput:input,metadata:{typeInfo:result.metadata?.typeInfo,typeProtection:result.typeProtection}}}function unifyJsonMapping(input){return console.warn("\u26A0\uFE0F DEPRECATED: unifyJsonMapping() is deprecated. Use JsonMappingConverter.toLegacyMapping() instead."),console.warn("Migration guide: https://github.com/mk3008/rawsql-ts/blob/main/docs/migration-guide.md"),new JsonMappingConverter().toLegacyMapping(input)}function isModelDrivenFormat(input){return detectMappingFormat(input)==="model-driven"}function isUnifiedFormat(input){return detectMappingFormat(input)==="unified"}function isLegacyFormat(input){return detectMappingFormat(input)==="legacy"}var TypeTransformationPostProcessor=class{constructor(config={}){this.config={enableValueBasedDetection:!0,strictDateDetection:!1,...config}}transformResult(result){return result==null?result:Array.isArray(result)?result.map(item=>this.transformSingleObject(item)):this.transformSingleObject(result)}transformSingleObject(obj){if(obj==null||typeof obj!="object")return obj;if(Array.isArray(obj))return obj.map(item=>this.transformSingleObject(item));let transformed={};for(let[key,value]of Object.entries(obj)){if(value==null){transformed[key]=value;continue}let columnTransform=this.config.columnTransformations?.[key];if(columnTransform){transformed[key]=this.applyTransformation(value,columnTransform);continue}if(this.config.enableValueBasedDetection){let detectedTransform=this.detectValueBasedTransformation(value);if(detectedTransform){transformed[key]=this.applyTransformation(value,detectedTransform);continue}}let globalTransform=this.config.globalTransformations&&this.getGlobalTransformationForValue(value);if(globalTransform){transformed[key]=this.applyTransformation(value,globalTransform);continue}if(typeof value=="object"&&!Array.isArray(value)){transformed[key]=this.transformSingleObject(value);continue}if(Array.isArray(value)){transformed[key]=value.map(item=>typeof item=="object"?this.transformSingleObject(item):item);continue}transformed[key]=value}return transformed}detectValueBasedTransformation(value){return typeof value=="string"&&this.isDateString(value)?{sourceType:"TIMESTAMP",targetType:"Date",handleNull:!0,validator:v=>typeof v=="string"&&!isNaN(Date.parse(v))}:typeof value=="number"&&!Number.isSafeInteger(value)?{sourceType:"BIGINT",targetType:"bigint",handleNull:!0,validator:v=>{try{return typeof v=="string"||typeof v=="number"||typeof v=="bigint"||typeof v=="boolean"?(BigInt(v),!0):!1}catch{return!1}}}:typeof value=="string"&&/^\d{16,}$/.test(value)?{sourceType:"BIGINT",targetType:"bigint",handleNull:!0,validator:v=>{try{return typeof v=="string"||typeof v=="number"||typeof v=="bigint"||typeof v=="boolean"?(BigInt(v),!0):!1}catch{return!1}}}:null}getGlobalTransformationForValue(value){return this.config.globalTransformations,null}detectAndGetGlobalTransformation(value){return this.detectValueBasedTransformation(value)}isDateString(value){if(this.config.strictDateDetection){if(!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})?$/.test(value))return!1}else if(!/^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})?)?$/.test(value))return!1;let date=new Date(value);return!isNaN(date.getTime())}applyTransformation(value,transformation){if(value==null)return transformation.handleNull!==!1?value:null;if(transformation.validator&&!transformation.validator(value))return console.warn(`TypeTransformationPostProcessor: Value validation failed for ${value}`),value;try{switch(transformation.targetType){case"Date":return new Date(value);case"bigint":if(typeof value=="number"){let integerValue=Math.trunc(value);return BigInt(integerValue.toString())}return BigInt(value);case"string":return value.toString();case"number":return typeof value=="string"?parseFloat(value):Number(value);case"object":return typeof value=="string"?JSON.parse(value):value;case"custom":if(transformation.customTransformer&&this.config.customTransformers?.[transformation.customTransformer])return this.config.customTransformers[transformation.customTransformer](value);break;default:return value}}catch(error){return console.warn(`TypeTransformationPostProcessor: Transformation failed for ${value}:`,error),value}return value}static createDefaultConfig(){return{enableValueBasedDetection:!0,strictDateDetection:!1,globalTransformations:{DATE:{sourceType:"DATE",targetType:"Date",handleNull:!0,validator:value=>typeof value=="string"&&!isNaN(Date.parse(value))},TIMESTAMP:{sourceType:"TIMESTAMP",targetType:"Date",handleNull:!0,validator:value=>typeof value=="string"&&!isNaN(Date.parse(value))},BIGINT:{sourceType:"BIGINT",targetType:"bigint",handleNull:!0,validator:value=>{try{return typeof value=="string"||typeof value=="number"||typeof value=="bigint"||typeof value=="boolean"?(BigInt(value),!0):!1}catch{return!1}}}}}}static createSafeConfig(columnMappings){return{enableValueBasedDetection:!1,strictDateDetection:!0,columnTransformations:columnMappings||{},globalTransformations:{DATE:{sourceType:"DATE",targetType:"Date",handleNull:!0,validator:value=>typeof value=="string"&&!isNaN(Date.parse(value))},TIMESTAMP:{sourceType:"TIMESTAMP",targetType:"Date",handleNull:!0,validator:value=>typeof value=="string"&&!isNaN(Date.parse(value))},BIGINT:{sourceType:"BIGINT",targetType:"bigint",handleNull:!0,validator:value=>{try{return typeof value=="string"||typeof value=="number"||typeof value=="bigint"||typeof value=="boolean"?(BigInt(value),!0):!1}catch{return!1}}}}}}};function transformDatabaseResult(result,config){return new TypeTransformationPostProcessor(config||TypeTransformationPostProcessor.createDefaultConfig()).transformResult(result)}var TypeTransformers={toDate:value=>{if(value==null)return null;let date=new Date(value);return isNaN(date.getTime())?null:date},toBigInt:value=>{if(value==null)return null;try{return BigInt(value)}catch{return null}},toObject:value=>{if(value==null)return null;try{return JSON.parse(value)}catch{return null}}};var BaseDataFlowNode=class{constructor(id,label,type,shape,details){this.id=id;this.label=label;this.type=type;this.shape=shape;this.details=details}},DataSourceNode=class _DataSourceNode extends BaseDataFlowNode{constructor(id,label,type){super(id,label,type,type==="subquery"?"hexagon":"cylinder");this.annotations=new Set}addAnnotation(annotation){this.annotations.add(annotation)}hasAnnotation(annotation){return this.annotations.has(annotation)}getMermaidRepresentation(){return this.shape==="hexagon"?`${this.id}{{${this.label}}}`:`${this.id}[(${this.label})]`}static createTable(tableName){return new _DataSourceNode(`table_${tableName}`,tableName,"table")}static createCTE(cteName){return new _DataSourceNode(`cte_${cteName}`,`CTE:${cteName}`,"cte")}static createSubquery(alias){return new _DataSourceNode(`subquery_${alias}`,`SubQuery:${alias}`,"subquery")}},ProcessNode=class _ProcessNode extends BaseDataFlowNode{constructor(id,operation,context=""){let nodeId=context?`${context}_${operation.toLowerCase().replace(/\s+/g,"_")}`:operation.toLowerCase().replace(/\s+/g,"_");super(nodeId,operation,"process","hexagon")}getMermaidRepresentation(){return`${this.id}{{${this.label}}}`}static createWhere(context){return new _ProcessNode(`${context}_where`,"WHERE",context)}static createGroupBy(context){return new _ProcessNode(`${context}_group_by`,"GROUP BY",context)}static createHaving(context){return new _ProcessNode(`${context}_having`,"HAVING",context)}static createSelect(context){return new _ProcessNode(`${context}_select`,"SELECT",context)}static createOrderBy(context){return new _ProcessNode(`${context}_order_by`,"ORDER BY",context)}static createLimit(context,hasOffset=!1){let label=hasOffset?"LIMIT/OFFSET":"LIMIT";return new _ProcessNode(`${context}_limit`,label,context)}},OperationNode=class _OperationNode extends BaseDataFlowNode{constructor(id,operation,shape="diamond"){super(id,operation,"operation",shape)}getMermaidRepresentation(){switch(this.shape){case"rounded":return`${this.id}(${this.label})`;case"rectangle":return`${this.id}[${this.label}]`;case"hexagon":return`${this.id}{{${this.label}}}`;case"stadium":return`${this.id}([${this.label}])`;case"diamond":default:return`${this.id}{${this.label}}`}}static createJoin(joinId,joinType){let label,normalizedType=joinType.trim().toLowerCase();return normalizedType==="join"?label="INNER JOIN":normalizedType.endsWith(" join")?label=normalizedType.toUpperCase():label=normalizedType.toUpperCase()+" JOIN",new _OperationNode(`join_${joinId}`,label,"rectangle")}static createUnion(unionId,unionType="UNION ALL"){return new _OperationNode(`${unionType.toLowerCase().replace(/\s+/g,"_")}_${unionId}`,unionType.toUpperCase(),"rectangle")}static createSetOperation(operationId,operation){let normalizedOp=operation.toUpperCase(),id=`${normalizedOp.toLowerCase().replace(/\s+/g,"_")}_${operationId}`;return new _OperationNode(id,normalizedOp,"rectangle")}},OutputNode=class extends BaseDataFlowNode{constructor(context="main"){let label=context==="main"?"Final Result":`${context} Result`;super(`${context}_output`,label,"output","stadium")}getMermaidRepresentation(){return`${this.id}([${this.label}])`}};var DataFlowConnection=class _DataFlowConnection{constructor(from,to,label){this.from=from;this.to=to;this.label=label}getMermaidRepresentation(){let arrow=this.label?` -->|${this.label}| `:" --> ";return`${this.from}${arrow}${this.to}`}static create(from,to,label){return new _DataFlowConnection(from,to,label)}static createWithNullability(from,to,isNullable){let label=isNullable?"NULLABLE":"NOT NULL";return new _DataFlowConnection(from,to,label)}},DataFlowEdgeCollection=class{constructor(){this.edges=[];this.connectionSet=new Set}add(edge){let key=`${edge.from}->${edge.to}`;this.connectionSet.has(key)||(this.edges.push(edge),this.connectionSet.add(key))}addConnection(from,to,label){this.add(DataFlowConnection.create(from,to,label))}addJoinConnection(from,to,isNullable){this.add(DataFlowConnection.createWithNullability(from,to,isNullable))}hasConnection(from,to){return this.connectionSet.has(`${from}->${to}`)}getAll(){return[...this.edges]}getMermaidRepresentation(){return this.edges.map(edge=>edge.getMermaidRepresentation()).join(`
|
|
83
|
+
3. Entity hierarchy and parentId relationships are correct`)}args.push(new ColumnReference(null,new IdentifierString(mapping.generatedColumnName)))}else childEntity.relationshipType==="array"&&args.push(new ColumnReference(null,new IdentifierString(childEntity.propertyName)))});let jsonObject=new FunctionCall(null,new RawString(jsonBuildFunction),new ValueList(args),null),jsonAggFunction=_PostgresArrayEntityCteBuilder.JSON_FUNCTIONS.AGGREGATE,primaryColumn=Object.values(entity.columns)[0];return{jsonAgg:new FunctionCall(null,new RawString(jsonAggFunction),new ValueList([jsonObject]),null)}}collectArrayEntityColumnsByDepth(mapping,currentDepth){let arrayEntitiesByDepth=new Map,maxDepth=Math.max(currentDepth+3,5);for(let d=currentDepth;d<=maxDepth;d++)arrayEntitiesByDepth.set(d,new Set);return mapping.nestedEntities.filter(entity=>entity.relationshipType==="array").forEach(entity=>{let entityDepth=this.calculateEntityDepth(entity,mapping);arrayEntitiesByDepth.has(entityDepth)||arrayEntitiesByDepth.set(entityDepth,new Set),this.addEntityColumnsToDepthSet(entity,entityDepth,arrayEntitiesByDepth),this.collectDescendantColumns(entity.id,entityDepth,mapping,arrayEntitiesByDepth)}),arrayEntitiesByDepth}calculateEntityDepth(entity,mapping){let entityDepth=0,currentEntity=entity;for(;currentEntity.parentId&¤tEntity.parentId!==mapping.rootEntity.id;)entityDepth++,currentEntity=mapping.nestedEntities.find(e=>e.id===currentEntity.parentId)||currentEntity;return entityDepth}addEntityColumnsToDepthSet(entity,depth,arrayEntitiesByDepth){Object.values(entity.columns).forEach(column=>{let columnName=typeof column=="string"?column:column.column;arrayEntitiesByDepth.get(depth).add(columnName)})}collectDescendantColumns(parentEntityId,targetDepth,mapping,arrayEntitiesByDepth){mapping.nestedEntities.filter(nestedEntity=>nestedEntity.parentId===parentEntityId).forEach(nestedEntity=>{this.addEntityColumnsToDepthSet(nestedEntity,targetDepth,arrayEntitiesByDepth),this.collectDescendantColumns(nestedEntity.id,targetDepth,mapping,arrayEntitiesByDepth)})}processSelectVariablesForGroupBy(prevSelects,arrayColumns,arrayEntitiesByDepth,currentDepth,selectItems,groupByItems,arrayInternalObjectColumns){prevSelects.forEach(sv=>{if(!arrayColumns.has(sv.name)){if(arrayInternalObjectColumns&&arrayInternalObjectColumns.has(sv.name))return;this.shouldIncludeColumnInGroupBy(sv.name,arrayEntitiesByDepth,currentDepth)&&(selectItems.push(new SelectItem(new ColumnReference(null,new IdentifierString(sv.name)),sv.name)),sv.name.endsWith("_json")||groupByItems.push(new ColumnReference(null,new IdentifierString(sv.name))))}})}shouldIncludeColumnInGroupBy(columnName,arrayEntitiesByDepth,currentDepth){let isJsonColumn=columnName.endsWith("_json"),shouldInclude=!0;for(let[entityDepth,columns]of arrayEntitiesByDepth.entries())if(entityDepth>=currentDepth&&columns.has(columnName)){shouldInclude=!1;break}return isJsonColumn&&columnName.startsWith("entity_")&&(shouldInclude=this.shouldIncludeJsonColumn(columnName,currentDepth)),shouldInclude}shouldIncludeJsonColumn(columnName,currentDepth){let entityMatch=columnName.match(/entity_(\d+)_json/);return entityMatch&¤tDepth>0?parseInt(entityMatch[1])<=2:!0}};var PostgresJsonQueryBuilder=class{constructor(){this.selectValueCollector=new SelectValueCollector(null),this.objectEntityCteBuilder=new PostgresObjectEntityCteBuilder,this.arrayEntityCteBuilder=new PostgresArrayEntityCteBuilder}validateMapping(query,mapping){let selectedValues=new SelectValueCollector().collect(query),availableColumns=new Set(selectedValues.map(sv=>sv.name));for(let jsonKey in mapping.rootEntity.columns){let columnDef=mapping.rootEntity.columns[jsonKey],sourceColumn=typeof columnDef=="string"?columnDef:columnDef.column;if(!availableColumns.has(sourceColumn))throw new Error(`Validation Error: Column "${sourceColumn}" for JSON key "${jsonKey}" in root entity "${mapping.rootEntity.name}" not found in the query's select list.`)}let entityIds=new Set([mapping.rootEntity.id]),parentToChildrenMap=new Map;mapping.nestedEntities.forEach(ne=>{entityIds.add(ne.id),parentToChildrenMap.has(ne.parentId)||parentToChildrenMap.set(ne.parentId,[]),parentToChildrenMap.get(ne.parentId).push(ne.id)});for(let entity of mapping.nestedEntities){if(!entityIds.has(entity.parentId))throw new Error(`Validation Error: Parent entity with ID "${entity.parentId}" for nested entity "${entity.name}" (ID: ${entity.id}) not found.`);for(let jsonKey in entity.columns){let columnDef=entity.columns[jsonKey],sourceColumn=typeof columnDef=="string"?columnDef:columnDef.column;if(!availableColumns.has(sourceColumn))throw new Error(`Validation Error: Column "${sourceColumn}" for JSON key "${jsonKey}" in nested entity "${entity.name}" (ID: ${entity.id}) not found in the query's select list.`)}}let allParentIds=new Set([mapping.rootEntity.id,...mapping.nestedEntities.map(ne=>ne.parentId)]);for(let parentId of allParentIds){let directChildren=mapping.nestedEntities.filter(ne=>ne.parentId===parentId);if(directChildren.filter(c=>c.relationshipType==="array").length>1){let parentName=parentId===mapping.rootEntity.id?mapping.rootEntity.name:mapping.nestedEntities.find(ne=>ne.id===parentId)?.name;throw new Error(`Validation Error: Parent entity "${parentName}" (ID: ${parentId}) has multiple direct array children. This is not supported.`)}let propertyNames=new Set;for(let child of directChildren){if(propertyNames.has(child.propertyName)){let parentName=parentId===mapping.rootEntity.id?mapping.rootEntity.name:mapping.nestedEntities.find(ne=>ne.id===parentId)?.name;throw new Error(`Validation Error: Parent entity "${parentName}" (ID: ${parentId}) has duplicate property name "${child.propertyName}" for its children.`)}propertyNames.add(child.propertyName)}}}buildJsonQuery(originalQuery,mapping,options){if(options?.jsonb===!1)throw new Error("JSONB must be enabled for PostgreSQL GROUP BY compatibility. JSON type cannot be used in GROUP BY clauses. Please set jsonb: true or omit the jsonb option (defaults to true).");let simpleQuery=originalQuery instanceof SimpleSelectQuery?originalQuery:QueryBuilder.buildSimpleQuery(originalQuery);return this.buildJsonWithCteStrategy(simpleQuery,mapping)}buildJson(originalQuery,mapping){return console.warn("buildJson is deprecated. Use buildJsonQuery instead."),this.buildJsonQuery(originalQuery,mapping)}buildJsonWithCteStrategy(originalQuery,mapping){this.validateMapping(originalQuery,mapping);let{initialCte,initialCteAlias}=this.createInitialCte(originalQuery),ctesForProcessing=[initialCte],currentAliasToBuildUpon=initialCteAlias,allEntities=new Map;allEntities.set(mapping.rootEntity.id,{...mapping.rootEntity,isRoot:!0,propertyName:mapping.rootName}),mapping.nestedEntities.forEach(ne=>allEntities.set(ne.id,{...ne,isRoot:!1,propertyName:ne.propertyName}));let objectEntityResult=this.objectEntityCteBuilder.buildObjectEntityCtes(initialCte,allEntities,mapping);ctesForProcessing=objectEntityResult.ctes,currentAliasToBuildUpon=objectEntityResult.lastCteAlias;let columnMappings=objectEntityResult.columnMappings,arrayCteBuildResult=this.arrayEntityCteBuilder.buildArrayEntityCtes(ctesForProcessing,currentAliasToBuildUpon,allEntities,mapping,columnMappings);return ctesForProcessing=arrayCteBuildResult.updatedCtes,currentAliasToBuildUpon=arrayCteBuildResult.lastCteAlias,this.buildFinalSelectQuery(ctesForProcessing,currentAliasToBuildUpon,allEntities,mapping,columnMappings)}createInitialCte(originalQuery){let originCteAlias="origin_query";return{initialCte:new CommonTable(originalQuery,new SourceAliasExpression(originCteAlias,null),null),initialCteAlias:originCteAlias}}buildFinalSelectQuery(finalCtesList,lastCteAliasForFromClause,allEntities,mapping,columnMappings){let currentCtes=[...finalCtesList],rootObjectCteAlias=`cte_root_${mapping.rootName.toLowerCase().replace(/[^a-z0-9_]/g,"_")}`,rootEntity=allEntities.get(mapping.rootEntity.id);if(!rootEntity)throw new Error(`Root entity ${mapping.rootEntity.id} not found`);if(mapping.resultFormat==="array"||!mapping.resultFormat){let rootObjectBuilderExpression=this.buildEntityJsonObject(rootEntity,null,mapping.nestedEntities,allEntities,columnMappings),rootObjectSelectItem=new SelectItem(rootObjectBuilderExpression,mapping.rootName),rootObjectCte=new CommonTable(new SimpleSelectQuery({selectClause:new SelectClause([rootObjectSelectItem]),fromClause:new FromClause(new SourceExpression(new TableSource(null,new IdentifierString(lastCteAliasForFromClause)),null),null)}),new SourceAliasExpression(rootObjectCteAlias,null),null);currentCtes.push(rootObjectCte);let aggregationFunc="jsonb_agg",aggregateExpression=new FunctionCall(null,new RawString(aggregationFunc),new ValueList([new ColumnReference(null,new IdentifierString(mapping.rootName))]),null);return new SimpleSelectQuery({withClause:new WithClause(!1,currentCtes),selectClause:new SelectClause([new SelectItem(aggregateExpression,`${mapping.rootName}_array`)]),fromClause:new FromClause(new SourceExpression(new TableSource(null,new IdentifierString(rootObjectCteAlias)),null),null)})}else{let rootObjectBuilderExpression=this.buildEntityJsonObject(rootEntity,null,mapping.nestedEntities,allEntities,columnMappings),rootObjectSelectItem=new SelectItem(rootObjectBuilderExpression,mapping.rootName),rootObjectCte=new CommonTable(new SimpleSelectQuery({selectClause:new SelectClause([rootObjectSelectItem]),fromClause:new FromClause(new SourceExpression(new TableSource(null,new IdentifierString(lastCteAliasForFromClause)),null),null)}),new SourceAliasExpression(rootObjectCteAlias,null),null);return currentCtes.push(rootObjectCte),new SimpleSelectQuery({withClause:new WithClause(!1,currentCtes),selectClause:new SelectClause([new SelectItem(new ColumnReference(null,new IdentifierString(mapping.rootName)),mapping.rootName)]),fromClause:new FromClause(new SourceExpression(new TableSource(null,new IdentifierString(rootObjectCteAlias)),null),null),limitClause:new LimitClause(new LiteralValue(1))})}}buildEntityJsonObject(entity,sourceAlias,nestedEntities,allEntities,columnMappings){let jsonBuildFunction="jsonb_build_object",args=[];return Object.entries(entity.columns).forEach(([jsonKey,columnDef])=>{let sqlColumn=typeof columnDef=="string"?columnDef:columnDef.column;args.push(new LiteralValue(jsonKey,void 0,!0)),args.push(new ColumnReference(null,new IdentifierString(sqlColumn)))}),nestedEntities.filter(ne=>ne.parentId===entity.id).forEach(childEntity=>{let child=allEntities.get(childEntity.id);if(child)if(args.push(new LiteralValue(childEntity.propertyName,void 0,!0)),childEntity.relationshipType==="object"){let mapping=columnMappings.find(m=>m.entityId===child.id);if(!mapping)throw new Error(`Column mapping not found for entity: ${child.id}`);args.push(new ColumnReference(null,new IdentifierString(mapping.generatedColumnName)))}else childEntity.relationshipType==="array"&&args.push(new ColumnReference(null,new IdentifierString(childEntity.propertyName)))}),new FunctionCall(null,new RawString(jsonBuildFunction),new ValueList(args),null)}};var SelectResultSelectConverter=class{static toSelectQuery(query,options){let fixtureTables=options?.fixtureTables??[];if(fixtureTables.length===0)return query;let sources=new TableSourceCollector(!1).collect(query),referencedTables=new Set;sources.forEach(s=>referencedTables.add(s.getSourceName().toLowerCase()));let neededFixtures=fixtureTables.filter(f=>referencedTables.has(f.tableName.toLowerCase()));if(neededFixtures.length===0)return query;let fixtureCtes=FixtureCteBuilder.buildFixtures(neededFixtures);return query instanceof SimpleSelectQuery&&(query.withClause?query.withClause.tables=[...fixtureCtes,...query.withClause.tables]:query.appendWith(fixtureCtes)),query}};var SimulatedSelectConverter=class{static convert(ast,options){if(ast instanceof InsertQuery)return InsertResultSelectConverter.toSelectQuery(ast,options);if(ast instanceof UpdateQuery)return UpdateResultSelectConverter.toSelectQuery(ast,options);if(ast instanceof DeleteQuery)return DeleteResultSelectConverter.toSelectQuery(ast,options);if(ast instanceof MergeQuery)return MergeResultSelectConverter.toSelectQuery(ast,options);if(ast instanceof SimpleSelectQuery||ast instanceof BinarySelectQuery||ast instanceof ValuesQuery)return SelectResultSelectConverter.toSelectQuery(ast,options);if(ast instanceof CreateTableQuery){if(ast.isTemporary&&ast.asSelectQuery){let processedSelect=SelectResultSelectConverter.toSelectQuery(ast.asSelectQuery,options);return ast.asSelectQuery=processedSelect,ast}return null}return null}};var DDLGeneralizer=class{static generalize(ast){let result=[];for(let component of ast)if(component instanceof CreateTableQuery){let{createTable,alterTables}=this.splitCreateTable(component);result.push(createTable),result.push(...alterTables)}else result.push(component);return result}static splitCreateTable(query){let newColumns=[],alterTables=[],tableQualifiedName=new QualifiedName(query.namespaces||[],query.tableName.name);for(let col of query.columns){let newConstraints=[];for(let constraint of col.constraints)if(["primary-key","unique","references","check"].includes(constraint.kind)){let tableConstraint=this.columnToTableConstraint(col.name,constraint);alterTables.push(new AlterTableStatement({table:tableQualifiedName,actions:[new AlterTableAddConstraint({constraint:tableConstraint})]}))}else newConstraints.push(constraint);newColumns.push(new TableColumnDefinition({name:col.name,dataType:col.dataType,constraints:newConstraints}))}if(query.tableConstraints)for(let constraint of query.tableConstraints)alterTables.push(new AlterTableStatement({table:tableQualifiedName,actions:[new AlterTableAddConstraint({constraint})]}));return{createTable:new CreateTableQuery({tableName:query.tableName.name,namespaces:query.namespaces,columns:newColumns,ifNotExists:query.ifNotExists,isTemporary:query.isTemporary,tableOptions:query.tableOptions,asSelectQuery:query.asSelectQuery,withDataOption:query.withDataOption,tableConstraints:[]}),alterTables}}static columnToTableConstraint(columnName,constraint){let baseParams={constraintName:constraint.constraintName,deferrable:constraint.reference?.deferrable,initially:constraint.reference?.initially};switch(constraint.kind){case"primary-key":return new TableConstraintDefinition({kind:"primary-key",columns:[columnName],...baseParams});case"unique":return new TableConstraintDefinition({kind:"unique",columns:[columnName],...baseParams});case"references":return new TableConstraintDefinition({kind:"foreign-key",columns:[columnName],reference:constraint.reference,...baseParams});case"check":return new TableConstraintDefinition({kind:"check",checkExpression:constraint.checkExpression,...baseParams});default:throw new Error(`Unsupported constraint kind for generalization: ${constraint.kind}`)}}};var DDLDiffGenerator=class{static generateDiff(currentSql,expectedSql,options={}){let currentAst=this.parseAndGeneralize(currentSql),expectedAst=this.parseAndGeneralize(expectedSql),currentSchema=this.buildSchema(currentAst),expectedSchema=this.buildSchema(expectedAst),diffAsts=[];for(let[tableName,expectedTable]of expectedSchema.tables){let currentTable=currentSchema.tables.get(tableName);if(currentTable)this.compareColumns(currentTable,expectedTable,diffAsts,options),this.compareConstraints(currentTable,expectedTable,diffAsts,options),this.compareIndexes(currentTable,expectedTable,diffAsts,options);else{let columns=Array.from(expectedTable.columns.values()).map(c=>c.definition),tableNameStr=expectedTable.qualifiedName.name instanceof RawString?expectedTable.qualifiedName.name.value:expectedTable.qualifiedName.name.name,namespaces=expectedTable.qualifiedName.namespaces?expectedTable.qualifiedName.namespaces.map(ns=>ns.name):null,createTable=new CreateTableQuery({tableName:tableNameStr,namespaces,columns});diffAsts.push(createTable);for(let constraint of expectedTable.constraints)diffAsts.push(new AlterTableStatement({table:expectedTable.qualifiedName,actions:[new AlterTableAddConstraint({constraint:constraint.definition})]}));for(let index of expectedTable.indexes)diffAsts.push(index.definition)}}if(options.dropTables)for(let[tableName,currentTable]of currentSchema.tables)expectedSchema.tables.has(tableName)||diffAsts.push(new DropTableStatement({tables:[currentTable.qualifiedName],ifExists:!1}));let formatter=new SqlFormatter(options.formatOptions||{keywordCase:"upper"});return diffAsts.map(ast=>formatter.format(ast).formattedSql+";")}static parseAndGeneralize(sql){let split=MultiQuerySplitter.split(sql),asts=[];for(let q of split.queries)if(!q.isEmpty)try{let ast=SqlParser.parse(q.sql);asts.push(ast)}catch(e){console.warn("Failed to parse SQL for diff:",q.sql,e)}return DDLGeneralizer.generalize(asts)}static buildSchema(asts){let tables=new Map,formatter=new SqlFormatter({keywordCase:"none"});for(let ast of asts)if(ast instanceof CreateTableQuery){let qName=new QualifiedName(ast.namespaces||[],ast.tableName),key=this.getQualifiedNameKey(qName),tableModel={name:key,qualifiedName:qName,columns:new Map,constraints:[],indexes:[]};for(let col of ast.columns)tableModel.columns.set(col.name.name,{name:col.name.name,definition:col});tables.set(key,tableModel)}else if(ast instanceof AlterTableStatement){let key=this.getQualifiedNameKey(ast.table),tableModel=tables.get(key);if(tableModel)for(let action of ast.actions)if(action instanceof AlterTableAddConstraint){let formatted=formatter.format(action.constraint).formattedSql;tableModel.constraints.push({name:action.constraint.constraintName?.name,kind:action.constraint.kind,definition:action.constraint,formatted})}else action instanceof AlterTableAddColumn&&tableModel.columns.set(action.column.name.name,{name:action.column.name.name,definition:action.column})}else if(ast instanceof CreateIndexStatement){let key=this.getQualifiedNameKey(ast.tableName),tableModel=tables.get(key);if(tableModel){let formatted=formatter.format(ast).formattedSql;tableModel.indexes.push({name:ast.indexName.toString(),definition:ast,formatted})}}return{tables}}static compareColumns(current,expected,diffs,options){for(let[name,col]of expected.columns)current.columns.has(name)||diffs.push(new AlterTableStatement({table:expected.qualifiedName,actions:[new AlterTableAddColumn({column:col.definition})]}));if(options.dropColumns)for(let[name,col]of current.columns)expected.columns.has(name)||diffs.push(new AlterTableStatement({table:expected.qualifiedName,actions:[new AlterTableDropColumn({columnName:col.definition.name})]}))}static compareConstraints(current,expected,diffs,options){let formatter=new SqlFormatter({keywordCase:"none"}),getConstraintSignature=c=>options.checkConstraintNames?c.kind==="primary-key"?c.formatted.replace(/^constraint\s+("[^"]+"|[^\s]+)\s+/i,"").trim():c.name||c.formatted:c.formatted.replace(/^constraint\s+("[^"]+"|[^\s]+)\s+/i,"").trim(),currentSignatures=new Set(current.constraints.map(getConstraintSignature));for(let expectedC of expected.constraints){let sig=getConstraintSignature(expectedC);currentSignatures.has(sig)||diffs.push(new AlterTableStatement({table:expected.qualifiedName,actions:[new AlterTableAddConstraint({constraint:expectedC.definition})]}))}if(options.dropConstraints){let expectedSignatures=new Set(expected.constraints.map(getConstraintSignature));for(let currentC of current.constraints){let sig=getConstraintSignature(currentC);expectedSignatures.has(sig)||(currentC.name?diffs.push(new AlterTableStatement({table:expected.qualifiedName,actions:[new AlterTableDropConstraint({constraintName:new IdentifierString(currentC.name)})]})):console.warn("Cannot drop unnamed constraint:",currentC.formatted))}}}static compareIndexes(current,expected,diffs,options){let getIndexSignature=idx=>{if(options.checkConstraintNames)return idx.name;let def=idx.definition,parts=[];parts.push(def.tableName.toString()),def.unique&&parts.push("UNIQUE"),def.usingMethod&&parts.push(`USING:${def.usingMethod.toString()}`);let columnSigs=def.columns.map(col=>{let expr=col.expression.toString(),sort=col.sortOrder||"",nulls=col.nullsOrder||"";return`${expr}${sort}${nulls}`});return parts.push(`COLS:${columnSigs.join(",")}`),def.include&&def.include.length>0&&parts.push(`INCLUDE:${def.include.map(i=>i.toString()).join(",")}`),def.where&&parts.push(`WHERE:${def.where.toString()}`),parts.join("|")},currentSignatures=new Set(current.indexes.map(getIndexSignature));for(let expectedIdx of expected.indexes){let sig=getIndexSignature(expectedIdx);currentSignatures.has(sig)||diffs.push(expectedIdx.definition)}if(options.checkConstraintNames||options.dropIndexes){let expectedSignatures=new Set(expected.indexes.map(getIndexSignature));for(let currentIdx of current.indexes){let sig=getIndexSignature(currentIdx);expectedSignatures.has(sig)||diffs.push(new DropIndexStatement({indexNames:[currentIdx.definition.indexName],ifExists:!1}))}}}static getQualifiedNameKey(qName){return qName.toString()}};var ParameterDetector=class{static extractParameterNames(query){return ParameterCollector.collect(query).map(p=>p.name.value)}static hasParameter(query,parameterName){return this.extractParameterNames(query).includes(parameterName)}static separateFilters(query,filter){let hardcodedParamNames=this.extractParameterNames(query),hardcodedParams={},dynamicFilters={};for(let[key,value]of Object.entries(filter))hardcodedParamNames.includes(key)?hardcodedParams[key]=value:dynamicFilters[key]=value;return{hardcodedParams,dynamicFilters}}};var FilterableItem=class{constructor(name,type,tableName){this.name=name;this.type=type;this.tableName=tableName}},FilterableItemCollector=class{constructor(tableColumnResolver,options){this.tableColumnResolver=tableColumnResolver,this.options={qualified:!1,upstream:!0,...options}}collect(query){let items=[],columnItems=this.collectColumns(query);items.push(...columnItems);let parameterItems=this.collectParameters(query);return items.push(...parameterItems),this.removeDuplicates(items)}collectColumns(query){let items=[];try{let columns=new SelectableColumnCollector(this.tableColumnResolver,!1,"fullName",{upstream:this.options.upstream}).collect(query);for(let column of columns){let tableName,realTableName;if(column.value&&typeof column.value.getNamespace=="function"){let namespace=column.value.getNamespace();namespace&&namespace.trim()!==""&&(tableName=namespace,this.options.qualified&&(realTableName=this.getRealTableName(query,namespace)))}tableName||(tableName=this.inferTableNameFromQuery(query),tableName&&this.options.qualified&&(realTableName=tableName));let columnName=column.name;this.options.qualified&&(realTableName||tableName)&&(columnName=`${realTableName||tableName}.${column.name}`),items.push(new FilterableItem(columnName,"column",tableName))}}catch(error){console.warn("Failed to collect columns with SelectableColumnCollector, using fallback:",error);try{let schemas=new SchemaCollector(this.tableColumnResolver,!0).collect(query);for(let schema of schemas)for(let columnName of schema.columns){let finalColumnName=columnName;this.options.qualified&&(finalColumnName=`${schema.name}.${columnName}`),items.push(new FilterableItem(finalColumnName,"column",schema.name))}}catch(fallbackError){console.warn("Failed to collect columns with both approaches:",error,fallbackError)}}return items}inferTableNameFromQuery(query){if(query instanceof SimpleSelectQuery&&query.fromClause&&query.fromClause.source){let datasource=query.fromClause.source.datasource;if(datasource&&typeof datasource.table=="object"){let table=datasource.table;if(table&&typeof table.name=="string")return table.name}}}getRealTableName(query,aliasOrName){try{let simpleQuery=query.type==="WITH"?query.toSimpleQuery():query;if(simpleQuery instanceof SimpleSelectQuery&&simpleQuery.fromClause){if(simpleQuery.fromClause.source?.datasource){let mainSource=simpleQuery.fromClause.source,realName=this.extractRealTableName(mainSource,aliasOrName);if(realName)return realName}let fromClause=simpleQuery.fromClause;if(fromClause.joinClauses&&Array.isArray(fromClause.joinClauses)){for(let joinClause of fromClause.joinClauses)if(joinClause.source?.datasource){let realName=this.extractRealTableName(joinClause.source,aliasOrName);if(realName)return realName}}}}catch(error){console.warn("Error resolving real table name:",error)}return aliasOrName}extractRealTableName(source,aliasOrName){try{let datasource=source.datasource;if(!datasource)return;let alias=source.alias||source.aliasExpression?.table?.name,realTableName=datasource.table?.name;if(alias===aliasOrName&&realTableName||!alias&&realTableName===aliasOrName)return realTableName}catch{}}collectParameters(query){let items=[];try{let parameterNames=ParameterDetector.extractParameterNames(query);for(let paramName of parameterNames)items.push(new FilterableItem(paramName,"parameter"))}catch(error){console.warn("Failed to collect parameters:",error)}return items}removeDuplicates(items){let seen=new Set,result=[];for(let item of items){let key=`${item.type}:${item.name}:${item.tableName||"none"}`;seen.has(key)||(seen.add(key),result.push(item))}return result.sort((a,b)=>{if(a.type!==b.type)return a.type==="column"?-1:1;if(a.type==="column"){let tableA=a.tableName||"",tableB=b.tableName||"";if(tableA!==tableB)return tableA.localeCompare(tableB)}return a.name.localeCompare(b.name)})}};var SqlSortInjector=class{constructor(tableColumnResolver){this.tableColumnResolver=tableColumnResolver}static removeOrderBy(query){if(typeof query=="string"&&(query=SelectQueryParser.parse(query)),!(query instanceof SimpleSelectQuery))throw new Error("Complex queries are not supported for ORDER BY removal");return new SimpleSelectQuery({withClause:query.withClause,selectClause:query.selectClause,fromClause:query.fromClause,whereClause:query.whereClause,groupByClause:query.groupByClause,havingClause:query.havingClause,orderByClause:null,windowClause:query.windowClause,limitClause:query.limitClause,offsetClause:query.offsetClause,fetchClause:query.fetchClause,forClause:query.forClause})}inject(query,sortConditions){if(typeof query=="string"&&(query=SelectQueryParser.parse(query)),!(query instanceof SimpleSelectQuery))throw new Error("Complex queries are not supported for sorting");let availableColumns=new SelectableColumnCollector(this.tableColumnResolver,!1,"fullName",{upstream:!0}).collect(query);for(let columnName of Object.keys(sortConditions))if(!availableColumns.find(item=>item.name===columnName))throw new Error(`Column or alias '${columnName}' not found in current query`);let newOrderByItems=[];for(let[columnName,condition]of Object.entries(sortConditions)){let columnEntry=availableColumns.find(item=>item.name===columnName);if(!columnEntry)continue;let columnRef=columnEntry.value;this.validateSortCondition(columnName,condition);let sortDirection;condition.desc?sortDirection="desc":sortDirection="asc";let nullsPosition=null;condition.nullsFirst?nullsPosition="first":condition.nullsLast&&(nullsPosition="last");let orderByItem=new OrderByItem(columnRef,sortDirection,nullsPosition);newOrderByItems.push(orderByItem)}let finalOrderByItems=[];query.orderByClause?finalOrderByItems=[...query.orderByClause.order,...newOrderByItems]:finalOrderByItems=newOrderByItems;let newOrderByClause=finalOrderByItems.length>0?new OrderByClause(finalOrderByItems):null;return new SimpleSelectQuery({withClause:query.withClause,selectClause:query.selectClause,fromClause:query.fromClause,whereClause:query.whereClause,groupByClause:query.groupByClause,havingClause:query.havingClause,orderByClause:newOrderByClause,windowClause:query.windowClause,limitClause:query.limitClause,offsetClause:query.offsetClause,fetchClause:query.fetchClause,forClause:query.forClause})}validateSortCondition(columnName,condition){if(condition.asc&&condition.desc)throw new Error(`Conflicting sort directions for column '${columnName}': both asc and desc specified`);if(condition.nullsFirst&&condition.nullsLast)throw new Error(`Conflicting nulls positions for column '${columnName}': both nullsFirst and nullsLast specified`);if(!condition.asc&&!condition.desc&&!condition.nullsFirst&&!condition.nullsLast)throw new Error(`Empty sort condition for column '${columnName}': at least one sort option must be specified`)}};var SqlPaginationInjector=class{inject(query,pagination){if(this.validatePaginationOptions(pagination),typeof query=="string"&&(query=SelectQueryParser.parse(query)),!(query instanceof SimpleSelectQuery))throw new Error("Complex queries are not supported for pagination");if(query.limitClause||query.offsetClause)throw new Error("Query already contains LIMIT or OFFSET clause. Use removePagination() first if you want to override existing pagination.");let offset=(pagination.page-1)*pagination.pageSize,limitClause=new LimitClause(new ParameterExpression("paging_limit",pagination.pageSize)),offsetClause=new OffsetClause(new ParameterExpression("paging_offset",offset));return new SimpleSelectQuery({withClause:query.withClause,selectClause:query.selectClause,fromClause:query.fromClause,whereClause:query.whereClause,groupByClause:query.groupByClause,havingClause:query.havingClause,orderByClause:query.orderByClause,windowClause:query.windowClause,limitClause,offsetClause,fetchClause:query.fetchClause,forClause:query.forClause})}static removePagination(query){if(typeof query=="string"&&(query=SelectQueryParser.parse(query)),!(query instanceof SimpleSelectQuery))throw new Error("Complex queries are not supported for pagination removal");return new SimpleSelectQuery({withClause:query.withClause,selectClause:query.selectClause,fromClause:query.fromClause,whereClause:query.whereClause,groupByClause:query.groupByClause,havingClause:query.havingClause,orderByClause:query.orderByClause,windowClause:query.windowClause,limitClause:null,offsetClause:null,fetchClause:query.fetchClause,forClause:query.forClause})}validatePaginationOptions(pagination){if(!pagination)throw new Error("Pagination options are required");if(typeof pagination.page!="number"||pagination.page<1)throw new Error("Page number must be a positive integer (1 or greater)");if(typeof pagination.pageSize!="number"||pagination.pageSize<1)throw new Error("Page size must be a positive integer (1 or greater)");if(pagination.pageSize>1e3)throw new Error("Page size cannot exceed 1000 items")}};var SqlParameterBinder=class{constructor(options={}){this.options={requireAllParameters:!0,...options}}bind(query,parameterValues){let modifiedQuery=query,existingParams=ParameterDetector.extractParameterNames(modifiedQuery);if(this.options.requireAllParameters){let missingParams=existingParams.filter(paramName=>!(paramName in parameterValues)||parameterValues[paramName]===void 0);if(missingParams.length>0)throw new Error(`Missing values for required parameters: ${missingParams.join(", ")}`)}for(let[paramName,value]of Object.entries(parameterValues))if(existingParams.includes(paramName))try{ParameterHelper.set(modifiedQuery,paramName,value)}catch(error){throw new Error(`Failed to bind parameter '${paramName}': ${error instanceof Error?error.message:"Unknown error"}`)}return modifiedQuery}bindToSimpleQuery(query,parameterValues){return this.bind(query,parameterValues)}};var NAMESPACE_SEPARATOR="|",normalizeIdentifier=input=>{let value=input?.trim()??"";return value===""?"":value.toLowerCase()},normalizeColumnSetKey=columns=>columns.map(column=>normalizeIdentifier(column)).filter(Boolean).sort().join(NAMESPACE_SEPARATOR),buildSchemaMap=schemaInfo=>{let map=new Map;for(let table of schemaInfo){let normalizedName=normalizeIdentifier(table.name);if(!normalizedName)continue;let columnSet=new Set(table.columns.map(normalizeIdentifier).filter(Boolean)),uniqueSetKeys=new Set;for(let uniqueKey of table.uniqueKeys){let normalizedKey=normalizeColumnSetKey(uniqueKey);normalizedKey&&uniqueSetKeys.add(normalizedKey)}columnSet.size===0&&uniqueSetKeys.size===0||map.set(normalizedName,{columnSet,uniqueSetKeys})}return map},collectReferenceMetadata=query=>{let collector=new ColumnReferenceCollector,namespaceCounts=new Map,unqualifiedColumns=new Set;for(let ref of collector.collect(query)){let namespace=normalizeIdentifier(ref.getNamespace());if(namespace)namespaceCounts.set(namespace,(namespaceCounts.get(namespace)??0)+1);else{let column=normalizeIdentifier(ref.column.name);column&&unqualifiedColumns.add(column)}}let joinConditionCounts=new Map;if(query.fromClause?.joins)for(let join of query.fromClause.joins){let counts=new Map;if(join.condition&&join.condition instanceof JoinOnClause){let joinCollector=new ColumnReferenceCollector;for(let ref of joinCollector.collect(join.condition.condition)){let namespace=normalizeIdentifier(ref.getNamespace());namespace&&counts.set(namespace,(counts.get(namespace)??0)+1)}}joinConditionCounts.set(join,counts)}return{namespaceCounts,unqualifiedColumns,joinConditionCounts}},isLeftJoin=join=>join.joinType.value.toLowerCase().includes("left"),getJoinIdentifiers=join=>{let identifiers=new Set,alias=normalizeIdentifier(join.source.getAliasName());if(alias&&identifiers.add(alias),join.source.datasource instanceof TableSource){let rawName=join.source.datasource.getSourceName();rawName&&identifiers.add(normalizeIdentifier(rawName));let shortName=normalizeIdentifier(join.source.datasource.table.name);shortName&&identifiers.add(shortName)}return[...identifiers]},hasExternalReferences=(identifiers,metadata,join)=>{let local=metadata.joinConditionCounts.get(join)??new Map;for(let identifier of identifiers){let total=metadata.namespaceCounts.get(identifier)??0,localCount=local.get(identifier)??0;if(total-localCount>0)return!0}return!1},getJoinColumnInfo=(join,identifiers)=>{if(!(join.condition instanceof JoinOnClause))return null;let expression=join.condition.condition;if(!(expression instanceof BinaryExpression)||expression.operator.value.trim().toLowerCase()!=="=")return null;let resolveColumn=component=>component instanceof ColumnReference?component:null,leftRef=resolveColumn(expression.left),rightRef=resolveColumn(expression.right);if(!leftRef||!rightRef)return null;let normalizedLeftNamespace=normalizeIdentifier(leftRef.getNamespace()),normalizedRightNamespace=normalizeIdentifier(rightRef.getNamespace());return identifiers.has(normalizedLeftNamespace)?normalizeIdentifier(leftRef.column.name):identifiers.has(normalizedRightNamespace)?normalizeIdentifier(rightRef.column.name):null},shouldRemoveJoin=(join,schemaMap,metadata)=>{if(!isLeftJoin(join)||join.lateral||!(join.source.datasource instanceof TableSource))return!1;let candidates=[normalizeIdentifier(join.source.datasource.getSourceName()),normalizeIdentifier(join.source.datasource.table.name)].filter(Boolean),tableInfo;for(let candidate of candidates){let info=schemaMap.get(candidate);if(info){tableInfo=info;break}}if(!tableInfo)return!1;let identifiers=new Set(getJoinIdentifiers(join));if(identifiers.size===0||hasExternalReferences([...identifiers],metadata,join))return!1;let joinColumn=getJoinColumnInfo(join,identifiers);if(!joinColumn||metadata.unqualifiedColumns.has(joinColumn)||tableInfo.columnSet.size>0&&!tableInfo.columnSet.has(joinColumn))return!1;let uniqueKey=normalizeColumnSetKey([joinColumn]);return!!tableInfo.uniqueSetKeys.has(uniqueKey)},optimizeSimpleQuery=(query,schemaMap)=>{if(!query.fromClause?.joins?.length)return!1;let metadata=collectReferenceMetadata(query),retainedJoins=[],removed=!1;for(let join of query.fromClause.joins){if(shouldRemoveJoin(join,schemaMap,metadata)){removed=!0;continue}retainedJoins.push(join)}return query.fromClause.joins=retainedJoins.length>0?retainedJoins:null,removed},traverseSelectQuery=(query,schemaMap)=>{if(query instanceof SimpleSelectQuery)return optimizeSimpleQuery(query,schemaMap);if(query instanceof BinarySelectQuery){let leftChanged=traverseSelectQuery(query.left,schemaMap),rightChanged=traverseSelectQuery(query.right,schemaMap);return leftChanged||rightChanged}return!1},optimizeUnusedLeftJoinsOnce=(query,schemaMap)=>schemaMap.size===0?!1:traverseSelectQuery(query,schemaMap),optimizeUnusedLeftJoins=(query,schemaInfo)=>(optimizeUnusedLeftJoinsOnce(query,buildSchemaMap(schemaInfo)),query),optimizeUnusedLeftJoinsToFixedPoint=(query,schemaInfo)=>{let schemaMap=buildSchemaMap(schemaInfo),changed=!0;for(;changed;)changed=optimizeUnusedLeftJoinsOnce(query,schemaMap);return query},collectTableSourceNames=component=>{let collector=new CTETableReferenceCollector,names=new Set;for(let source of collector.collect(component)){let normalizedName=normalizeIdentifier(source.table.name);normalizedName&&names.add(normalizedName)}return names},isReferencedByOthers=(cteName,mainReferences,cteReferenceMap)=>{if(mainReferences.has(cteName))return!0;for(let[otherName,references]of cteReferenceMap)if(otherName!==cteName&&references.has(cteName))return!0;return!1},optimizeSimpleQueryCtes=query=>{let withClause=query.withClause;if(!withClause||withClause.recursive||withClause.tables.length===0)return!1;let mainReferences=collectTableSourceNames(query),cteReferenceMap=new Map;for(let table of withClause.tables){let normalizedName=normalizeIdentifier(table.aliasExpression.table.name);normalizedName&&cteReferenceMap.set(normalizedName,collectTableSourceNames(table.query))}let removableNames=[];for(let table of withClause.tables){let normalizedName=normalizeIdentifier(table.aliasExpression.table.name);if(!normalizedName)continue;let body=table.query;!(body instanceof SimpleSelectQuery)&&!(body instanceof BinarySelectQuery)||isReferencedByOthers(normalizedName,mainReferences,cteReferenceMap)||removableNames.push(normalizedName)}if(removableNames.length===0)return!1;for(let name of removableNames)query.removeCTE(name);return!0},optimizeCtesInSelectQuery=query=>{if(query instanceof SimpleSelectQuery)return optimizeSimpleQueryCtes(query);if(query instanceof BinarySelectQuery){let leftChanged=optimizeCtesInSelectQuery(query.left),rightChanged=optimizeCtesInSelectQuery(query.right);return leftChanged||rightChanged}return!1},optimizeUnusedCtesOnce=query=>optimizeCtesInSelectQuery(query),optimizeUnusedCtes=query=>(optimizeUnusedCtesOnce(query),query),optimizeUnusedCtesToFixedPoint=query=>{let changed=!0;for(;changed;)changed=optimizeUnusedCtesOnce(query);return query};var isBinaryOperator=(expression,operator)=>expression instanceof BinaryExpression&&expression.operator.value.trim().toLowerCase()===operator,unwrapSingleOuterParen=expression=>{let candidate=expression;for(;candidate instanceof ParenExpression;)candidate=candidate.expression;return candidate},collectTopLevelAndTerms=expression=>{let candidate=unwrapSingleOuterParen(expression);return isBinaryOperator(candidate,"and")?[...collectTopLevelAndTerms(candidate.left),...collectTopLevelAndTerms(candidate.right)]:[expression]},collectTopLevelOrTerms=expression=>{let candidate=unwrapSingleOuterParen(expression);return isBinaryOperator(candidate,"or")?[...collectTopLevelOrTerms(candidate.left),...collectTopLevelOrTerms(candidate.right)]:[expression]},isNullLiteral=expression=>expression instanceof LiteralValue&&expression.value===null||expression instanceof RawString&&expression.value.trim().toLowerCase()==="null",isTrueSentinel=expression=>{let candidate=unwrapSingleOuterParen(expression);return candidate instanceof LiteralValue?candidate.value===!0:isBinaryOperator(candidate,"=")?candidate.left instanceof LiteralValue&&candidate.right instanceof LiteralValue&&candidate.left.value===1&&candidate.right.value===1:!1},getGuardedParameterName=expression=>{let candidate=unwrapSingleOuterParen(expression);return!isBinaryOperator(candidate,"is")||!(candidate.left instanceof ParameterExpression)||!isNullLiteral(candidate.right)?null:candidate.left.name.value},getUniqueParameterNames=expression=>new Set(ParameterCollector.collect(expression).map(parameter=>parameter.name.value)),isSupportedMeaningfulBranch=(expression,parameterName)=>{let candidate=unwrapSingleOuterParen(expression);if(candidate instanceof ParameterExpression)return!1;let parameterNames=getUniqueParameterNames(candidate);return parameterNames.size!==1||!parameterNames.has(parameterName)?!1:!(candidate instanceof LiteralValue||candidate instanceof RawString)},isExplicitPruningTarget=(pruningParameters,parameterName)=>Object.prototype.hasOwnProperty.call(pruningParameters,parameterName),isKnownAbsentTarget=(pruningParameters,parameterName)=>{if(!isExplicitPruningTarget(pruningParameters,parameterName))return!1;let parameterValue=pruningParameters[parameterName];return parameterValue==null},shouldPruneOptionalBranch=(expression,pruningParameters)=>{let branch=getSupportedOptionalConditionBranch(expression);return branch!==null&&isKnownAbsentTarget(pruningParameters,branch.parameterName)},rebuildAndCondition=terms=>{if(terms.length===0)return null;let condition=terms[0];for(let index=1;index<terms.length;index+=1)condition=new BinaryExpression(condition,"and",terms[index]);return condition},pruneSimpleQueryWhereClause=(query,pruningParameters)=>{if(!query.whereClause)return!1;let topLevelTerms=collectTopLevelAndTerms(query.whereClause.condition),retainedTerms=[],prunedAnyBranch=!1;for(let term of topLevelTerms){if(shouldPruneOptionalBranch(term,pruningParameters)){prunedAnyBranch=!0;continue}retainedTerms.push(term)}if(!prunedAnyBranch)return!1;let cleanedTerms=retainedTerms.filter(term=>!isTrueSentinel(term)),rebuiltCondition=rebuildAndCondition(cleanedTerms);return query.whereClause=rebuiltCondition?new WhereClause(rebuiltCondition):null,!0},isSelectQueryNode=value=>value instanceof SimpleSelectQuery||value instanceof BinarySelectQuery,traverseNestedSelectQueries=(root,pruningParameters)=>{let changed=!1,visited=new WeakSet,walk=value=>{if(!(!value||typeof value!="object")&&!visited.has(value)){if(visited.add(value),value!==root&&isSelectQueryNode(value)){changed=traverseSelectQuery2(value,pruningParameters)||changed;return}if(Array.isArray(value)){value.forEach(walk);return}for(let child of Object.values(value))walk(child)}};return walk(root),changed},traverseSelectQuery2=(query,pruningParameters)=>{if(query instanceof SimpleSelectQuery){let selfChanged=pruneSimpleQueryWhereClause(query,pruningParameters),nestedChanged=traverseNestedSelectQueries(query,pruningParameters);return selfChanged||nestedChanged}if(query instanceof BinarySelectQuery){let leftChanged=traverseSelectQuery2(query.left,pruningParameters),rightChanged=traverseSelectQuery2(query.right,pruningParameters);return leftChanged||rightChanged}return!1},getSupportedOptionalConditionBranch=expression=>{let orTerms=collectTopLevelOrTerms(expression);if(orTerms.length<2)return null;let guardTerms=orTerms.map(term=>({term,parameterName:getGuardedParameterName(term)})).filter(candidate=>candidate.parameterName!==null);if(guardTerms.length!==1)return null;let[{term:guardTerm,parameterName}]=guardTerms,meaningfulTerms=orTerms.filter(term=>term!==guardTerm);return meaningfulTerms.length===0||!meaningfulTerms.every(term=>isSupportedMeaningfulBranch(term,parameterName))?null:{parameterName,kind:"expression"}},collectSupportedBranchesFromSimpleQuery=(query,branches)=>{if(!query.whereClause)return;let topLevelTerms=collectTopLevelAndTerms(query.whereClause.condition);for(let term of topLevelTerms){let branch=getSupportedOptionalConditionBranch(term);branch&&branches.push({query,parameterName:branch.parameterName,expression:term,kind:branch.kind})}},collectSupportedBranchesFromSelectQuery=(query,branches)=>{if(query instanceof SimpleSelectQuery){collectSupportedBranchesFromSimpleQuery(query,branches),traverseNestedSelectQueriesForCollection(query,branches);return}query instanceof BinarySelectQuery&&(collectSupportedBranchesFromSelectQuery(query.left,branches),collectSupportedBranchesFromSelectQuery(query.right,branches))},traverseNestedSelectQueriesForCollection=(root,branches)=>{let visited=new WeakSet,walk=value=>{if(!(!value||typeof value!="object")&&!visited.has(value)){if(visited.add(value),value!==root&&isSelectQueryNode(value)){collectSupportedBranchesFromSelectQuery(value,branches);return}if(Array.isArray(value)){value.forEach(walk);return}for(let child of Object.values(value))walk(child)}};walk(root)},pruneOptionalConditionBranches=(query,pruningParameters)=>(Object.keys(pruningParameters).length===0||traverseSelectQuery2(query,pruningParameters),query),collectSupportedOptionalConditionBranches=query=>{let branches=[];return collectSupportedBranchesFromSelectQuery(query,branches),branches};var DynamicQueryBuilder=class{constructor(resolverOrOptions){typeof resolverOrOptions=="function"?this.tableColumnResolver=resolverOrOptions:resolverOrOptions&&(this.tableColumnResolver=resolverOrOptions.tableColumnResolver,this.defaultSchemaInfo=resolverOrOptions.schemaInfo)}buildQuery(sqlContent,options={}){let parsedQuery;try{parsedQuery=SelectQueryParser.parse(sqlContent)}catch(error){throw new Error(`Failed to parse SQL: ${error instanceof Error?error.message:"Unknown error"}`)}let modifiedQuery=parsedQuery;if(options.filter&&Object.keys(options.filter).length>0){let{hardcodedParams,dynamicFilters}=ParameterDetector.separateFilters(modifiedQuery,options.filter);if(Object.keys(hardcodedParams).length>0&&(modifiedQuery=new SqlParameterBinder({requireAllParameters:!1}).bind(modifiedQuery,hardcodedParams)),Object.keys(dynamicFilters).length>0)throw new Error("DynamicQueryBuilder no longer injects runtime filter predicates. Use `ztd query sssql scaffold` to author optional filters, `ztd query sssql refresh` to refresh them, and `optionalConditionParameters` at runtime for pruning only.")}if(options.sort&&Object.keys(options.sort).length>0){let sortInjector=new SqlSortInjector(this.tableColumnResolver),simpleQuery=QueryBuilder.buildSimpleQuery(modifiedQuery);modifiedQuery=sortInjector.inject(simpleQuery,options.sort)}if(options.paging){let{page=1,pageSize}=options.paging;if(pageSize!==void 0){let paginationInjector=new SqlPaginationInjector,paginationOptions={page,pageSize},simpleQuery=QueryBuilder.buildSimpleQuery(modifiedQuery);modifiedQuery=paginationInjector.inject(simpleQuery,paginationOptions)}}modifiedQuery=this.applyColumnFilters(modifiedQuery,options);let optionalConditionParameters=this.resolveOptionalConditionPruningParameters(options);Object.keys(optionalConditionParameters).length>0&&(modifiedQuery=pruneOptionalConditionBranches(modifiedQuery,optionalConditionParameters));let effectiveSchemaInfo=options.schemaInfo??this.defaultSchemaInfo;if(options.removeUnusedLeftJoins&&effectiveSchemaInfo?.length&&(modifiedQuery=optimizeUnusedLeftJoinsToFixedPoint(modifiedQuery,effectiveSchemaInfo)),options.removeUnusedCtes&&(modifiedQuery=optimizeUnusedCtesToFixedPoint(modifiedQuery)),options.serialize&&typeof options.serialize=="object"){let jsonBuilder=new PostgresJsonQueryBuilder,simpleQuery=QueryBuilder.buildSimpleQuery(modifiedQuery);modifiedQuery=jsonBuilder.buildJsonQuery(simpleQuery,options.serialize)}return modifiedQuery}resolveOptionalConditionPruningParameters(options){if(options.optionalConditionParameters)return options.optionalConditionParameters;if(!options.optionalConditionParameterStates)return{};let legacyParameters={};for(let[parameterName,state]of Object.entries(options.optionalConditionParameterStates))legacyParameters[parameterName]=state==="absent"?null:"__RAWSQL_OPTIONAL_CONDITION_PRESENT__";return legacyParameters}applyColumnFilters(query,options){let hasIncludeFilters=Array.isArray(options.includeColumns)&&options.includeColumns.length>0,hasExcludeFilters=Array.isArray(options.excludeColumns)&&options.excludeColumns.length>0;if(!hasIncludeFilters&&!hasExcludeFilters)return query;if(hasIncludeFilters&&hasExcludeFilters)throw new Error("includeColumns and excludeColumns cannot be used together.");let simpleQuery=QueryBuilder.buildSimpleQuery(query),metadata=simpleQuery.selectClause.items.map(item=>{let name=this.getSelectItemName(item);return{item,normalized:name?this.normalizeColumnIdentifier(name):null}}),availableColumns=new Set(metadata.map(entry=>entry.normalized).filter(name=>name!==null)),includeFilters=hasIncludeFilters?this.normalizeColumnList(options.includeColumns):null,excludeFilters=hasExcludeFilters?this.normalizeColumnList(options.excludeColumns):null,includeSet=includeFilters?new Set(includeFilters.map(entry=>entry.normalized)):null,excludeSet=excludeFilters?new Set(excludeFilters.map(entry=>entry.normalized)):null;if(includeFilters){let missing=includeFilters.filter(entry=>!availableColumns.has(entry.normalized));if(missing.length>0)throw new Error(`Column${missing.length===1?"":"s"} not found in SELECT clause: ${missing.map(entry=>`'${entry.original}'`).join(", ")}.`)}if(excludeFilters){let missing=excludeFilters.filter(entry=>!availableColumns.has(entry.normalized));if(missing.length>0)throw new Error(`Column${missing.length===1?"":"s"} not found in SELECT clause: ${missing.map(entry=>`'${entry.original}'`).join(", ")}.`)}let filteredItems=metadata.filter(entry=>entry.normalized?includeSet?includeSet.has(entry.normalized):excludeSet?!excludeSet.has(entry.normalized):!0:!0).map(entry=>entry.item);if(filteredItems.length===0)throw new Error("Column filtering removed every SELECT item.");return simpleQuery.selectClause.items=filteredItems,simpleQuery}normalizeColumnList(columns){return columns.map(column=>{if(typeof column!="string")throw new Error("Column filters must be strings.");let trimmed=column.trim();if(trimmed==="")throw new Error("Column filters must not be empty.");return{normalized:this.normalizeColumnIdentifier(trimmed),original:trimmed}})}normalizeColumnIdentifier(value){return value.trim().toLowerCase()}getSelectItemName(item){return item.identifier?item.identifier.name:item.value instanceof ColumnReference?item.value.column.name:null}buildFilteredQuery(sqlContent,filter){return this.buildQuery(sqlContent,{filter})}buildSortedQuery(sqlContent,sort){return this.buildQuery(sqlContent,{sort})}buildPaginatedQuery(sqlContent,paging){return this.buildQuery(sqlContent,{paging})}buildSerializedQuery(sqlContent,serialize){return this.buildQuery(sqlContent,{serialize})}validateSql(sqlContent){try{return SelectQueryParser.parse(sqlContent),!0}catch(error){throw new Error(`Invalid SQL: ${error instanceof Error?error.message:"Unknown error"}`)}}};var normalizeIdentifier2=value=>value.trim().toLowerCase(),normalizeColumnReferenceKey=reference=>`${normalizeIdentifier2(reference.getNamespace())}.${normalizeIdentifier2(reference.column.name)}`,isExplicitEqualityScaffoldValue=value=>{if(value==null)return!0;if(Array.isArray(value))return!1;if(typeof value!="object")return!0;let entries=Object.entries(value).filter(([,entry])=>entry!==void 0);return entries.length===1&&entries[0]?.[0]==="="},parseQualifiedFilterName=filterName=>{let segments=filterName.split(".");if(segments.length!==2)return null;let[table,column]=segments.map(segment=>segment.trim());return!table||!column?null:{table,column}},makeParameterName=filterName=>filterName.trim().replace(/\./g,"_").replace(/[^a-zA-Z0-9_]/g,"_"),buildOptionalEqualityBranch=(column,parameterName)=>{let parameter=new ParameterExpression(parameterName),guard=new BinaryExpression(new ParameterExpression(parameterName),"is",new LiteralValue(null)),equality=new BinaryExpression(new ColumnReference(column.getNamespace()||null,column.column.name),"=",parameter);return new ParenExpression(new BinaryExpression(guard,"or",equality))},rebuildWhereWithoutTerm=(query,termToRemove)=>{if(!query.whereClause)return;let collectTopLevelAndTerms2=expression=>expression instanceof BinaryExpression&&expression.operator.value.trim().toLowerCase()==="and"?[...collectTopLevelAndTerms2(expression.left),...collectTopLevelAndTerms2(expression.right)]:[expression],terms=collectTopLevelAndTerms2(query.whereClause.condition).filter(term=>term!==termToRemove);if(terms.length===0){query.whereClause=null;return}let rebuilt=terms[0];for(let index=1;index<terms.length;index+=1)rebuilt=new BinaryExpression(rebuilt,"and",terms[index]);query.whereClause=new WhereClause(rebuilt)},SSSQLFilterBuilder=class{constructor(tableColumnResolver){this.tableColumnResolver=tableColumnResolver;this.finder=new UpstreamSelectQueryFinder(this.tableColumnResolver)}scaffold(query,filters){let parsed=this.parseQuery(query);for(let[filterName,filterValue]of Object.entries(filters)){if(!isExplicitEqualityScaffoldValue(filterValue))throw new Error(`SSSQL scaffold only supports equality filters in v1. Use refresh for pre-authored branches: '${filterName}'.`);let target=this.resolveTarget(parsed,filterName);target.query.appendWhere(buildOptionalEqualityBranch(target.column,target.parameterName))}return parsed}refresh(query,filters){let parsed=this.parseQuery(query);for(let[filterName,filterValue]of Object.entries(filters)){let target=this.resolveTarget(parsed,filterName),matches=collectSupportedOptionalConditionBranches(parsed).filter(branch=>branch.parameterName===target.parameterName);if(matches.length===0){if(!isExplicitEqualityScaffoldValue(filterValue))throw new Error(`No existing SSSQL branch was found for '${filterName}', and v1 scaffold only supports equality filters.`);target.query.appendWhere(buildOptionalEqualityBranch(target.column,target.parameterName));continue}if(matches.length>1)throw new Error(`Multiple SSSQL branches matched parameter ':${target.parameterName}'. Refresh is ambiguous.`);let[match]=matches;match&&match.query!==target.query&&(this.rebaseMovedBranch(match.expression,match.query,target.column),rebuildWhereWithoutTerm(match.query,match.expression),target.query.appendWhere(match.expression))}return parsed}parseQuery(query){return typeof query=="string"?SelectQueryParser.parse(query):query}resolveTarget(root,filterName){let qualified=parseQualifiedFilterName(filterName),lookupColumn=qualified?.column??filterName.trim(),matches=[...new Set(this.finder.find(root,lookupColumn))].map(query=>this.resolveTargetInQuery(query,filterName,qualified)).filter(target=>target!==null);if(matches.length===0)throw new Error(`Could not resolve SSSQL filter target '${filterName}' in the current query graph.`);if(matches.length>1)throw new Error(`SSSQL filter target '${filterName}' is ambiguous across multiple query scopes.`);return matches[0]}resolveTargetInQuery(query,filterName,qualified){return qualified?this.resolveQualifiedTarget(query,qualified):this.resolveUnqualifiedTarget(query,filterName)}resolveQualifiedTarget(query,filterName){let alias=this.findAliasForTable(query,filterName.table);if(!alias)return null;let matches=new SelectableColumnCollector(this.tableColumnResolver,!1,"fullName",{upstream:!0}).collect(query).filter(entry=>entry.value instanceof ColumnReference).filter(entry=>normalizeColumnReferenceKey(entry.value)===`${normalizeIdentifier2(alias)}.${normalizeIdentifier2(filterName.column)}`);if(matches.length===0)return null;if(matches.length>1)throw new Error(`SSSQL scaffold target '${filterName.table}.${filterName.column}' resolved to multiple columns.`);return{query,column:matches[0].value,parameterName:makeParameterName(`${filterName.table}.${filterName.column}`)}}resolveUnqualifiedTarget(query,filterName){let matches=new SelectableColumnCollector(this.tableColumnResolver,!1,"fullName",{upstream:!0}).collect(query).filter(entry=>entry.value instanceof ColumnReference).filter(entry=>normalizeIdentifier2(entry.name)===normalizeIdentifier2(filterName));if(matches.length===0)return null;if(matches.length>1)throw new Error(`SSSQL scaffold target '${filterName}' is ambiguous. Use a qualified table.column reference.`);return{query,column:matches[0].value,parameterName:makeParameterName(filterName)}}findAliasForTable(query,tableName){let normalizedTable=normalizeIdentifier2(tableName),matchingAliases=(query.fromClause?.getSources()??[]).map(source=>this.resolveAliasForSource(source,normalizedTable)).filter(alias=>alias!==null);if(matchingAliases.length===0)return null;if(matchingAliases.length>1)throw new Error(`SSSQL scaffold target table '${tableName}' is ambiguous in the selected query scope.`);return matchingAliases[0]}resolveAliasForSource(source,normalizedTable){if(!(source.datasource instanceof TableSource))return null;let sourceName=normalizeIdentifier2(source.datasource.getSourceName()),shortName=normalizeIdentifier2(source.datasource.table.name);return sourceName!==normalizedTable&&shortName!==normalizedTable?null:source.getAliasName()??source.datasource.table.name}rebaseMovedBranch(expression,sourceQuery,targetColumn){let targetNamespace=targetColumn.qualifiedName.namespaces?targetColumn.qualifiedName.namespaces.map(namespace=>namespace.name):null,targetColumnName=normalizeIdentifier2(targetColumn.column.name),sourceAliases=new Set(new ColumnReferenceCollector().collect(expression).filter(reference=>normalizeIdentifier2(reference.column.name)===targetColumnName).map(reference=>normalizeIdentifier2(reference.getNamespace())).filter(namespace=>namespace.length>0));if(sourceAliases.size===0)return;if(sourceAliases.size>1){let aliases=[...sourceAliases].join(", ");throw new Error(`SSSQL refresh cannot safely rebase '${targetColumn.column.name}' across multiple aliases (${aliases}).`)}let[sourceAlias]=[...sourceAliases];if(new Set((sourceQuery.fromClause?.getSources()??[]).map(source=>source.getAliasName()).filter(alias=>typeof alias=="string").map(alias=>normalizeIdentifier2(alias))).has(sourceAlias))for(let reference of new ColumnReferenceCollector().collect(expression))normalizeIdentifier2(reference.getNamespace())===sourceAlias&&(reference.qualifiedName.namespaces=targetNamespace?.map(namespace=>new IdentifierString(namespace))??null)}},scaffoldSssqlQuery=(sqlContent,filters)=>({query:new SSSQLFilterBuilder().scaffold(sqlContent,filters)}),refreshSssqlQuery=(sqlContent,filters)=>({query:new SSSQLFilterBuilder().refresh(sqlContent,filters)});function convertModelDrivenMapping(modelMapping){let protectedStringFields=[],entityIdCounter=0,propertyNameCounters={},generateEntityId=()=>`entity_${++entityIdCounter}`,generateUniquePropertyName=baseName=>(propertyNameCounters[baseName]||(propertyNameCounters[baseName]=0),propertyNameCounters[baseName]++,propertyNameCounters[baseName]===1?baseName:`${baseName}_${propertyNameCounters[baseName]}`),processStructure=(structure,parentId=null)=>{let columns={},nestedEntities=[];for(let[fieldName,config]of Object.entries(structure))if(typeof config=="string")columns[fieldName]=config;else if("column"in config&&typeof config.column=="string"&&!("type"in config&&(config.type==="object"||config.type==="array"))){let fieldConfig=config;typeof fieldConfig=="object"&&"column"in fieldConfig&&(columns[fieldName]=fieldConfig.column,fieldConfig.type==="string"&&protectedStringFields.push(fieldConfig.column))}else if("from"in config&&typeof config.from=="string"&&!("type"in config&&(config.type==="object"||config.type==="array"))){let fieldConfig=config;typeof fieldConfig=="object"&&"from"in fieldConfig&&(columns[fieldName]=fieldConfig.from,fieldConfig.type==="string"&&protectedStringFields.push(fieldConfig.from))}else if("type"in config&&(config.type==="object"||config.type==="array")){let nestedStructure=config,uniquePropertyName=generateUniquePropertyName(fieldName),entityId=generateEntityId(),processedNested=processStructure(nestedStructure.structure,entityId);nestedEntities.push({id:entityId,name:fieldName.charAt(0).toUpperCase()+fieldName.slice(1),parentId:parentId||"root",propertyName:uniquePropertyName,originalPropertyName:fieldName,relationshipType:nestedStructure.type,columns:processedNested.columns}),nestedEntities.push(...processedNested.nestedEntities.map(entity=>({...entity,parentId:entity.parentId==="root"?entityId:entity.parentId})))}return{columns,nestedEntities}},processed=processStructure(modelMapping.structure),jsonMapping={rootName:"root",rootEntity:{id:"root",name:"Root",columns:processed.columns},nestedEntities:processed.nestedEntities};return jsonMapping.typeInfo=modelMapping.typeInfo,{jsonMapping,typeProtection:{protectedStringFields}}}function validateModelDrivenMapping(mapping){let errors=[];return mapping.typeInfo?(mapping.typeInfo.interface||errors.push("typeInfo.interface is required"),mapping.typeInfo.importPath||errors.push("typeInfo.importPath is required")):errors.push("typeInfo is required"),(!mapping.structure||typeof mapping.structure!="object")&&errors.push("structure is required and must be an object"),errors}function convertColumnsToLegacy(columns){let result={};for(let[key,config]of Object.entries(columns))typeof config=="string"?result[key]=config:config&&typeof config=="object"?"column"in config?result[key]=config.column:"from"in config?result[key]=config.from:result[key]=key:result[key]=key;return result}function convertToLegacyJsonMapping(input){if(!input)throw new Error("Input mapping is required");if(input.rootName&&input.rootEntity&&typeof input.rootEntity.columns=="object"&&!input.typeInfo&&!input.typeProtection&&!input.metadata&&Object.values(input.rootEntity.columns).every(col=>typeof col=="string"))return input;if(input.rootName&&input.rootEntity)return{rootName:input.rootName,rootEntity:{id:input.rootEntity.id||"root",name:input.rootEntity.name||input.rootName,columns:convertColumnsToLegacy(input.rootEntity.columns||{})},nestedEntities:(input.nestedEntities||[]).map(entity=>({id:entity.id,name:entity.name,parentId:entity.parentId,propertyName:entity.propertyName,relationshipType:entity.relationshipType,columns:convertColumnsToLegacy(entity.columns||{})})),resultFormat:input.resultFormat,emptyResult:input.emptyResult};throw new Error("Unsupported mapping format")}function toLegacyMapping(enhanced){return{rootName:enhanced.rootName,rootEntity:{id:enhanced.rootEntity.id,name:enhanced.rootEntity.name,columns:convertColumnsToLegacy(enhanced.rootEntity.columns)},nestedEntities:enhanced.nestedEntities.map(entity=>({id:entity.id,name:entity.name,parentId:entity.parentId,propertyName:entity.propertyName,relationshipType:entity.relationshipType,columns:convertColumnsToLegacy(entity.columns)})),resultFormat:enhanced.resultFormat,emptyResult:enhanced.emptyResult}}function extractTypeProtection(enhanced){let protectedStringFields=[],dateFields=[],numberFields=[];if(enhanced.typeProtection)return{protectedStringFields:enhanced.typeProtection.protectedStringFields||[],dateFields:enhanced.typeProtection.dateFields,numberFields:enhanced.typeProtection.numberFields,customTransforms:enhanced.typeProtection.customTransforms};for(let[key,config]of Object.entries(enhanced.rootEntity.columns))if(typeof config=="object"&&config.type){let columnName=config.column;switch(config.type){case"string":protectedStringFields.push(columnName);break;case"date":dateFields.push(columnName);break;case"number":numberFields.push(columnName);break}}for(let entity of enhanced.nestedEntities)for(let[key,config]of Object.entries(entity.columns))if(typeof config=="object"&&config.type){let columnName=config.column;switch(config.type){case"string":protectedStringFields.push(columnName);break;case"date":dateFields.push(columnName);break;case"number":numberFields.push(columnName);break}}return{protectedStringFields,dateFields:dateFields.length>0?dateFields:void 0,numberFields:numberFields.length>0?numberFields:void 0,customTransforms:void 0}}function isValidMappingInput(input){return input!=null&&typeof input=="object"}var EnhancedFormatStrategy=class{detect(input){if(!isValidMappingInput(input))return!1;let candidate=input;if(!candidate||typeof candidate.rootName!="string"||!candidate.rootEntity||!Array.isArray(candidate.nestedEntities))return!1;if(candidate.typeInfo||candidate.typeProtection||candidate.metadata)return!0;let hasEnhancedColumns=columns=>!columns||typeof columns!="object"?!1:Object.values(columns).some(col=>typeof col=="object"&&col!==null&&"column"in col);return hasEnhancedColumns(candidate.rootEntity.columns)?!0:candidate.nestedEntities.some(entity=>entity&&typeof entity=="object"&&hasEnhancedColumns(entity.columns))}convert(input){return{format:"enhanced",mapping:toLegacyMapping(input),typeProtection:extractTypeProtection(input),originalInput:input,metadata:{typeInfo:input.typeInfo,version:input.metadata?.version,description:input.metadata?.description}}}},ModelDrivenFormatStrategy=class{detect(input){if(!isValidMappingInput(input))return!1;let candidate=input;return candidate&&candidate.typeInfo&&candidate.structure&&typeof candidate.typeInfo.interface=="string"}convert(input){let converted=convertModelDrivenMapping(input);return{format:"model-driven",mapping:converted.jsonMapping,typeProtection:converted.typeProtection,originalInput:input,metadata:{typeInfo:input.typeInfo}}}},LegacyFormatStrategy=class{detect(input){if(!isValidMappingInput(input))return!1;let candidate=input;if(!candidate||typeof candidate.rootName!="string"||!candidate.rootEntity||typeof candidate.rootEntity.columns!="object"||candidate.typeInfo||candidate.typeProtection||candidate.metadata)return!1;let hasEnhancedColumns=columns=>!columns||typeof columns!="object"?!1:Object.values(columns).some(col=>typeof col=="object"&&col!==null&&"column"in col);return!(hasEnhancedColumns(candidate.rootEntity.columns)||candidate.nestedEntities&&Array.isArray(candidate.nestedEntities)&&candidate.nestedEntities.some(entity=>entity&&typeof entity=="object"&&hasEnhancedColumns(entity.columns)))}convert(input){return{format:"legacy",mapping:input,typeProtection:{protectedStringFields:[]},originalInput:input}}},JsonMappingConverter=class{constructor(){this.strategies=[new EnhancedFormatStrategy,new ModelDrivenFormatStrategy,new LegacyFormatStrategy]}detectFormat(input){for(let strategy of this.strategies)if(strategy.detect(input))return strategy.convert(input).format;throw new Error("Unsupported JSON mapping format")}convert(input){for(let strategy of this.strategies)if(strategy.detect(input))return strategy.convert(input);throw new Error("Unsupported JSON mapping format: Unable to detect a compatible strategy for the provided input")}toLegacyMapping(input){return this.convert(input).mapping}getTypeProtection(input){return this.convert(input).typeProtection}validate(input){let errors=[];if(!input||typeof input!="object")return errors.push("Input must be an object"),errors;(!("rootName"in input)||!input.rootName)&&errors.push("rootName is required");try{let result=this.convert(input);if(result.mapping.rootName||errors.push("rootName is required"),result.mapping.rootEntity?(result.mapping.rootEntity.id||errors.push("rootEntity.id is required"),result.mapping.rootEntity.columns||errors.push("rootEntity.columns is required")):errors.push("rootEntity is required"),result.mapping.nestedEntities)for(let entity of result.mapping.nestedEntities)entity.id||errors.push(`Nested entity missing id: ${entity.propertyName}`),entity.parentId||errors.push(`Nested entity missing parentId: ${entity.id}`),entity.propertyName||errors.push(`Nested entity missing propertyName: ${entity.id}`)}catch(error){errors.length===0&&errors.push(`Conversion failed: ${error instanceof Error?error.message:String(error)}`)}return errors}upgradeToEnhanced(legacy,typeInfo){return{rootName:legacy.rootName,rootEntity:{id:legacy.rootEntity.id,name:legacy.rootEntity.name,columns:legacy.rootEntity.columns},nestedEntities:legacy.nestedEntities.map(entity=>({id:entity.id,name:entity.name,parentId:entity.parentId,propertyName:entity.propertyName,relationshipType:entity.relationshipType||"object",columns:entity.columns})),resultFormat:legacy.resultFormat,emptyResult:legacy.emptyResult,typeInfo,metadata:{version:"1.0",description:"Upgraded from legacy format"}}}};function detectMappingFormat(input){return input.typeInfo&&input.structure?"model-driven":input.rootName&&input.rootEntity?"unified":(input.columns||input.relationships,"legacy")}function convertLegacyFormat(input){let result={rootName:input.rootName||"root",rootEntity:{id:"root",name:input.rootName||"Root",columns:input.columns||{}},nestedEntities:[]};if(input.relationships&&typeof input.relationships=="object")for(let[propertyName,relationship]of Object.entries(input.relationships)){let rel=relationship;result.nestedEntities.push({id:propertyName,name:propertyName.charAt(0).toUpperCase()+propertyName.slice(1),parentId:"root",propertyName,relationshipType:rel.type==="hasMany"?"array":"object",columns:rel.columns||{}})}return result}function processJsonMapping(input){if(console.warn("\u26A0\uFE0F DEPRECATED: processJsonMapping() is deprecated. Use JsonMappingConverter.convert() instead."),console.warn("Migration guide: https://github.com/mk3008/rawsql-ts/blob/main/docs/migration-guide.md"),(input.columns||input.relationships)&&!input.rootName&&!input.rootEntity)return{format:"legacy",jsonMapping:convertLegacyFormat(input),originalInput:input,metadata:{}};let result=new JsonMappingConverter().convert(input),format=result.format;return result.format==="legacy"&&input.rootName&&input.rootEntity&&(format="unified"),{format,jsonMapping:result.mapping,originalInput:input,metadata:{typeInfo:result.metadata?.typeInfo,typeProtection:result.typeProtection}}}function unifyJsonMapping(input){return console.warn("\u26A0\uFE0F DEPRECATED: unifyJsonMapping() is deprecated. Use JsonMappingConverter.toLegacyMapping() instead."),console.warn("Migration guide: https://github.com/mk3008/rawsql-ts/blob/main/docs/migration-guide.md"),new JsonMappingConverter().toLegacyMapping(input)}function isModelDrivenFormat(input){return detectMappingFormat(input)==="model-driven"}function isUnifiedFormat(input){return detectMappingFormat(input)==="unified"}function isLegacyFormat(input){return detectMappingFormat(input)==="legacy"}var TypeTransformationPostProcessor=class{constructor(config={}){this.config={enableValueBasedDetection:!0,strictDateDetection:!1,...config}}transformResult(result){return result==null?result:Array.isArray(result)?result.map(item=>this.transformSingleObject(item)):this.transformSingleObject(result)}transformSingleObject(obj){if(obj==null||typeof obj!="object")return obj;if(Array.isArray(obj))return obj.map(item=>this.transformSingleObject(item));let transformed={};for(let[key,value]of Object.entries(obj)){if(value==null){transformed[key]=value;continue}let columnTransform=this.config.columnTransformations?.[key];if(columnTransform){transformed[key]=this.applyTransformation(value,columnTransform);continue}if(this.config.enableValueBasedDetection){let detectedTransform=this.detectValueBasedTransformation(value);if(detectedTransform){transformed[key]=this.applyTransformation(value,detectedTransform);continue}}let globalTransform=this.config.globalTransformations&&this.getGlobalTransformationForValue(value);if(globalTransform){transformed[key]=this.applyTransformation(value,globalTransform);continue}if(typeof value=="object"&&!Array.isArray(value)){transformed[key]=this.transformSingleObject(value);continue}if(Array.isArray(value)){transformed[key]=value.map(item=>typeof item=="object"?this.transformSingleObject(item):item);continue}transformed[key]=value}return transformed}detectValueBasedTransformation(value){return typeof value=="string"&&this.isDateString(value)?{sourceType:"TIMESTAMP",targetType:"Date",handleNull:!0,validator:v=>typeof v=="string"&&!isNaN(Date.parse(v))}:typeof value=="number"&&!Number.isSafeInteger(value)?{sourceType:"BIGINT",targetType:"bigint",handleNull:!0,validator:v=>{try{return typeof v=="string"||typeof v=="number"||typeof v=="bigint"||typeof v=="boolean"?(BigInt(v),!0):!1}catch{return!1}}}:typeof value=="string"&&/^\d{16,}$/.test(value)?{sourceType:"BIGINT",targetType:"bigint",handleNull:!0,validator:v=>{try{return typeof v=="string"||typeof v=="number"||typeof v=="bigint"||typeof v=="boolean"?(BigInt(v),!0):!1}catch{return!1}}}:null}getGlobalTransformationForValue(value){return this.config.globalTransformations,null}detectAndGetGlobalTransformation(value){return this.detectValueBasedTransformation(value)}isDateString(value){if(this.config.strictDateDetection){if(!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})?$/.test(value))return!1}else if(!/^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})?)?$/.test(value))return!1;let date=new Date(value);return!isNaN(date.getTime())}applyTransformation(value,transformation){if(value==null)return transformation.handleNull!==!1?value:null;if(transformation.validator&&!transformation.validator(value))return console.warn(`TypeTransformationPostProcessor: Value validation failed for ${value}`),value;try{switch(transformation.targetType){case"Date":return new Date(value);case"bigint":if(typeof value=="number"){let integerValue=Math.trunc(value);return BigInt(integerValue.toString())}return BigInt(value);case"string":return value.toString();case"number":return typeof value=="string"?parseFloat(value):Number(value);case"object":return typeof value=="string"?JSON.parse(value):value;case"custom":if(transformation.customTransformer&&this.config.customTransformers?.[transformation.customTransformer])return this.config.customTransformers[transformation.customTransformer](value);break;default:return value}}catch(error){return console.warn(`TypeTransformationPostProcessor: Transformation failed for ${value}:`,error),value}return value}static createDefaultConfig(){return{enableValueBasedDetection:!0,strictDateDetection:!1,globalTransformations:{DATE:{sourceType:"DATE",targetType:"Date",handleNull:!0,validator:value=>typeof value=="string"&&!isNaN(Date.parse(value))},TIMESTAMP:{sourceType:"TIMESTAMP",targetType:"Date",handleNull:!0,validator:value=>typeof value=="string"&&!isNaN(Date.parse(value))},BIGINT:{sourceType:"BIGINT",targetType:"bigint",handleNull:!0,validator:value=>{try{return typeof value=="string"||typeof value=="number"||typeof value=="bigint"||typeof value=="boolean"?(BigInt(value),!0):!1}catch{return!1}}}}}}static createSafeConfig(columnMappings){return{enableValueBasedDetection:!1,strictDateDetection:!0,columnTransformations:columnMappings||{},globalTransformations:{DATE:{sourceType:"DATE",targetType:"Date",handleNull:!0,validator:value=>typeof value=="string"&&!isNaN(Date.parse(value))},TIMESTAMP:{sourceType:"TIMESTAMP",targetType:"Date",handleNull:!0,validator:value=>typeof value=="string"&&!isNaN(Date.parse(value))},BIGINT:{sourceType:"BIGINT",targetType:"bigint",handleNull:!0,validator:value=>{try{return typeof value=="string"||typeof value=="number"||typeof value=="bigint"||typeof value=="boolean"?(BigInt(value),!0):!1}catch{return!1}}}}}}};function transformDatabaseResult(result,config){return new TypeTransformationPostProcessor(config||TypeTransformationPostProcessor.createDefaultConfig()).transformResult(result)}var TypeTransformers={toDate:value=>{if(value==null)return null;let date=new Date(value);return isNaN(date.getTime())?null:date},toBigInt:value=>{if(value==null)return null;try{return BigInt(value)}catch{return null}},toObject:value=>{if(value==null)return null;try{return JSON.parse(value)}catch{return null}}};var BaseDataFlowNode=class{constructor(id,label,type,shape,details){this.id=id;this.label=label;this.type=type;this.shape=shape;this.details=details}},DataSourceNode=class _DataSourceNode extends BaseDataFlowNode{constructor(id,label,type){super(id,label,type,type==="subquery"?"hexagon":"cylinder");this.annotations=new Set}addAnnotation(annotation){this.annotations.add(annotation)}hasAnnotation(annotation){return this.annotations.has(annotation)}getMermaidRepresentation(){return this.shape==="hexagon"?`${this.id}{{${this.label}}}`:`${this.id}[(${this.label})]`}static createTable(tableName){return new _DataSourceNode(`table_${tableName}`,tableName,"table")}static createCTE(cteName){return new _DataSourceNode(`cte_${cteName}`,`CTE:${cteName}`,"cte")}static createSubquery(alias){return new _DataSourceNode(`subquery_${alias}`,`SubQuery:${alias}`,"subquery")}},ProcessNode=class _ProcessNode extends BaseDataFlowNode{constructor(id,operation,context=""){let nodeId=context?`${context}_${operation.toLowerCase().replace(/\s+/g,"_")}`:operation.toLowerCase().replace(/\s+/g,"_");super(nodeId,operation,"process","hexagon")}getMermaidRepresentation(){return`${this.id}{{${this.label}}}`}static createWhere(context){return new _ProcessNode(`${context}_where`,"WHERE",context)}static createGroupBy(context){return new _ProcessNode(`${context}_group_by`,"GROUP BY",context)}static createHaving(context){return new _ProcessNode(`${context}_having`,"HAVING",context)}static createSelect(context){return new _ProcessNode(`${context}_select`,"SELECT",context)}static createOrderBy(context){return new _ProcessNode(`${context}_order_by`,"ORDER BY",context)}static createLimit(context,hasOffset=!1){let label=hasOffset?"LIMIT/OFFSET":"LIMIT";return new _ProcessNode(`${context}_limit`,label,context)}},OperationNode=class _OperationNode extends BaseDataFlowNode{constructor(id,operation,shape="diamond"){super(id,operation,"operation",shape)}getMermaidRepresentation(){switch(this.shape){case"rounded":return`${this.id}(${this.label})`;case"rectangle":return`${this.id}[${this.label}]`;case"hexagon":return`${this.id}{{${this.label}}}`;case"stadium":return`${this.id}([${this.label}])`;case"diamond":default:return`${this.id}{${this.label}}`}}static createJoin(joinId,joinType){let label,normalizedType=joinType.trim().toLowerCase();return normalizedType==="join"?label="INNER JOIN":normalizedType.endsWith(" join")?label=normalizedType.toUpperCase():label=normalizedType.toUpperCase()+" JOIN",new _OperationNode(`join_${joinId}`,label,"rectangle")}static createUnion(unionId,unionType="UNION ALL"){return new _OperationNode(`${unionType.toLowerCase().replace(/\s+/g,"_")}_${unionId}`,unionType.toUpperCase(),"rectangle")}static createSetOperation(operationId,operation){let normalizedOp=operation.toUpperCase(),id=`${normalizedOp.toLowerCase().replace(/\s+/g,"_")}_${operationId}`;return new _OperationNode(id,normalizedOp,"rectangle")}},OutputNode=class extends BaseDataFlowNode{constructor(context="main"){let label=context==="main"?"Final Result":`${context} Result`;super(`${context}_output`,label,"output","stadium")}getMermaidRepresentation(){return`${this.id}([${this.label}])`}};var DataFlowConnection=class _DataFlowConnection{constructor(from,to,label){this.from=from;this.to=to;this.label=label}getMermaidRepresentation(){let arrow=this.label?` -->|${this.label}| `:" --> ";return`${this.from}${arrow}${this.to}`}static create(from,to,label){return new _DataFlowConnection(from,to,label)}static createWithNullability(from,to,isNullable){let label=isNullable?"NULLABLE":"NOT NULL";return new _DataFlowConnection(from,to,label)}},DataFlowEdgeCollection=class{constructor(){this.edges=[];this.connectionSet=new Set}add(edge){let key=`${edge.from}->${edge.to}`;this.connectionSet.has(key)||(this.edges.push(edge),this.connectionSet.add(key))}addConnection(from,to,label){this.add(DataFlowConnection.create(from,to,label))}addJoinConnection(from,to,isNullable){this.add(DataFlowConnection.createWithNullability(from,to,isNullable))}hasConnection(from,to){return this.connectionSet.has(`${from}->${to}`)}getAll(){return[...this.edges]}getMermaidRepresentation(){return this.edges.map(edge=>edge.getMermaidRepresentation()).join(`
|
|
84
84
|
`)}};var DataFlowGraph=class{constructor(){this.nodes=new Map;this.edges=new DataFlowEdgeCollection}addNode(node){this.nodes.set(node.id,node)}addEdge(edge){this.edges.add(edge)}addConnection(from,to,label){this.edges.addConnection(from,to,label)}hasNode(nodeId){return this.nodes.has(nodeId)}hasConnection(from,to){return this.edges.hasConnection(from,to)}getNode(nodeId){return this.nodes.get(nodeId)}getAllNodes(){return Array.from(this.nodes.values())}getAllEdges(){return this.edges.getAll()}generateMermaid(direction="TD",title){let mermaid=`flowchart ${direction}
|
|
85
85
|
`;title&&(mermaid+=` %% ${title}
|
|
86
86
|
`);let nodeLines=Array.from(this.nodes.values()).map(node=>` ${node.getMermaidRepresentation()}`).join(`
|
|
87
87
|
`);nodeLines&&(mermaid+=nodeLines+`
|
|
88
88
|
`),this.nodes.size>0&&this.edges.getAll().length>0&&(mermaid+=`
|
|
89
89
|
`);let edgeRepresentation=this.edges.getMermaidRepresentation();return edgeRepresentation&&(mermaid+=` ${edgeRepresentation}
|
|
90
|
-
`),mermaid}getOrCreateTable(tableName){let nodeId=`table_${tableName}`,node=this.nodes.get(nodeId);return node||(node=DataSourceNode.createTable(tableName),this.addNode(node)),node}getOrCreateCTE(cteName){let nodeId=`cte_${cteName}`,node=this.nodes.get(nodeId);return node||(node=DataSourceNode.createCTE(cteName),this.addNode(node)),node}getOrCreateSubquery(alias){let nodeId=`subquery_${alias}`,node=this.nodes.get(nodeId);return node||(node=DataSourceNode.createSubquery(alias),this.addNode(node)),node}createProcessNode(type,context){let node=new ProcessNode(context,type);return this.addNode(node),node}createJoinNode(joinId,joinType){let node=OperationNode.createJoin(joinId,joinType);return this.addNode(node),node}createSetOperationNode(operationId,operation){let node=OperationNode.createSetOperation(operationId,operation);return this.addNode(node),node}createOutputNode(context="main"){let node=new OutputNode(context);return this.addNode(node),node}};var DataSourceHandler=class{constructor(graph){this.graph=graph}processSource(sourceExpr,cteNames,queryProcessor){if(sourceExpr.datasource instanceof TableSource)return this.processTableSource(sourceExpr.datasource,cteNames);if(sourceExpr.datasource instanceof SubQuerySource)return this.processSubquerySource(sourceExpr,cteNames,queryProcessor);throw new Error("Unsupported source type")}processTableSource(tableSource,cteNames){let tableName=tableSource.getSourceName();return cteNames.has(tableName)?this.graph.getOrCreateCTE(tableName).id:this.graph.getOrCreateTable(tableName).id}processSubquerySource(sourceExpr,cteNames,queryProcessor){let alias=sourceExpr.aliasExpression?.table.name||"subquery",subqueryNode=this.graph.getOrCreateSubquery(alias),subqueryResultId=queryProcessor(sourceExpr.datasource.query,`subquery_${alias}_internal`,cteNames);return subqueryResultId&&!this.graph.hasConnection(subqueryResultId,subqueryNode.id)&&this.graph.addConnection(subqueryResultId,subqueryNode.id),subqueryNode.id}extractTableNodeIds(fromClause,cteNames){let tableNodeIds=[],sourceExpr=fromClause.source;if(sourceExpr.datasource instanceof TableSource){let tableName=sourceExpr.datasource.getSourceName();if(cteNames.has(tableName)){let cteNode=this.graph.getOrCreateCTE(tableName);tableNodeIds.push(cteNode.id)}else{let tableNode=this.graph.getOrCreateTable(tableName);tableNodeIds.push(tableNode.id)}}if(fromClause.joins&&fromClause.joins.length>0)for(let join of fromClause.joins){let joinSourceExpr=join.source;if(joinSourceExpr.datasource instanceof TableSource){let tableName=joinSourceExpr.datasource.getSourceName();if(cteNames.has(tableName)){let cteNode=this.graph.getOrCreateCTE(tableName);tableNodeIds.push(cteNode.id)}else{let tableNode=this.graph.getOrCreateTable(tableName);tableNodeIds.push(tableNode.id)}}}return tableNodeIds}};var JoinHandler=class{constructor(graph,dataSourceHandler){this.graph=graph;this.dataSourceHandler=dataSourceHandler;this.joinIdCounter=0}resetJoinCounter(){this.joinIdCounter=0}getNextJoinId(){return String(++this.joinIdCounter)}processFromClause(fromClause,cteNames,queryProcessor){let mainSourceId=this.dataSourceHandler.processSource(fromClause.source,cteNames,queryProcessor);return fromClause.joins&&fromClause.joins.length>0?this.processJoins(fromClause.joins,mainSourceId,cteNames,queryProcessor):mainSourceId}processJoins(joins,currentNodeId,cteNames,queryProcessor){let resultNodeId=currentNodeId;for(let join of joins){let joinNodeId=this.dataSourceHandler.processSource(join.source,cteNames,queryProcessor),joinOpId=this.getNextJoinId(),joinNode=this.graph.createJoinNode(joinOpId,join.joinType.value),{leftLabel,rightLabel}=this.getJoinNullabilityLabels(join.joinType.value);resultNodeId&&!this.graph.hasConnection(resultNodeId,joinNode.id)&&this.graph.addConnection(resultNodeId,joinNode.id,leftLabel),joinNodeId&&!this.graph.hasConnection(joinNodeId,joinNode.id)&&this.graph.addConnection(joinNodeId,joinNode.id,rightLabel),resultNodeId=joinNode.id}return resultNodeId}getJoinNullabilityLabels(joinType){switch(joinType.toLowerCase()){case"left join":return{leftLabel:"NOT NULL",rightLabel:"NULLABLE"};case"right join":return{leftLabel:"NULLABLE",rightLabel:"NOT NULL"};case"inner join":case"join":return{leftLabel:"NOT NULL",rightLabel:"NOT NULL"};case"full join":case"full outer join":return{leftLabel:"NULLABLE",rightLabel:"NULLABLE"};case"cross join":return{leftLabel:"NOT NULL",rightLabel:"NOT NULL"};default:return{leftLabel:"",rightLabel:""}}}};var ProcessHandler=class{constructor(graph,dataSourceHandler){this.graph=graph;this.dataSourceHandler=dataSourceHandler}processQueryClauses(query,context,currentNodeId,cteNames,queryProcessor){return currentNodeId}};var CTEHandler=class{constructor(graph){this.graph=graph}processCTEs(withClause,cteNames,queryProcessor){for(let i=0;i<withClause.tables.length;i++){let cteName=withClause.tables[i].getSourceAliasName(),cteNode=this.graph.getOrCreateCTE(cteName);cteNames.add(cteName),withClause.recursive&&i===0&&cteNode.addAnnotation("recursive")}for(let i=0;i<withClause.tables.length;i++){let cte=withClause.tables[i],cteName=cte.getSourceAliasName(),cteNode=this.graph.getOrCreateCTE(cteName),cteResultId=queryProcessor(cte.query,`cte_${cteName}`,cteNames);if(cteResultId&&!this.graph.hasConnection(cteResultId,cteNode.id)){let label=withClause.recursive&&i===0?"RECURSIVE":void 0;this.graph.addConnection(cteResultId,cteNode.id,label)}}}detectRecursiveReference(query,cteName){return query.toString().toLowerCase().includes(cteName.toLowerCase())}};var QueryFlowDiagramGenerator=class _QueryFlowDiagramGenerator{constructor(){this.graph=new DataFlowGraph,this.dataSourceHandler=new DataSourceHandler(this.graph),this.joinHandler=new JoinHandler(this.graph,this.dataSourceHandler),this.processHandler=new ProcessHandler(this.graph,this.dataSourceHandler),this.cteHandler=new CTEHandler(this.graph)}generateMermaidFlow(query,options){this.graph=new DataFlowGraph,this.dataSourceHandler=new DataSourceHandler(this.graph),this.joinHandler=new JoinHandler(this.graph,this.dataSourceHandler),this.processHandler=new ProcessHandler(this.graph,this.dataSourceHandler),this.cteHandler=new CTEHandler(this.graph),this.joinHandler.resetJoinCounter();let parsedQuery=typeof query=="string"?SelectQueryParser.parse(query):query,cteNames=new Set;return this.processQuery(parsedQuery,"main",cteNames),this.graph.generateMermaid(options?.direction||"TD",options?.title)}static generate(sql){return new _QueryFlowDiagramGenerator().generateMermaidFlow(sql)}processQuery(query,context,cteNames){if(query instanceof SimpleSelectQuery)return this.processSimpleQuery(query,context,cteNames);if(query instanceof BinarySelectQuery)return this.processBinaryQuery(query,context,cteNames);throw new Error("Unsupported query type")}processSimpleQuery(query,context,cteNames){query.withClause&&this.cteHandler.processCTEs(query.withClause,cteNames,this.processQuery.bind(this));let currentNodeId="";return query.fromClause&&(query.fromClause.joins&&query.fromClause.joins.length>0?currentNodeId=this.joinHandler.processFromClause(query.fromClause,cteNames,this.processQuery.bind(this)):currentNodeId=this.dataSourceHandler.processSource(query.fromClause.source,cteNames,this.processQuery.bind(this))),currentNodeId&&(currentNodeId=this.processHandler.processQueryClauses(query,context,currentNodeId,cteNames,this.processQuery.bind(this))),this.handleOutputNode(currentNodeId,context)}processBinaryQuery(query,context,cteNames){let parts=this.flattenBinaryChain(query,query.operator.value);return parts.length>2?this.processMultiPartOperation(parts,query.operator.value,context,cteNames):this.processSimpleBinaryOperation(query,context,cteNames)}processSimpleBinaryOperation(query,context,cteNames){let leftNodeId=this.processQuery(query.left,`${context}_left`,cteNames),rightNodeId=this.processQuery(query.right,`${context}_right`,cteNames),operationId=context==="main"?"main":context.replace(/^cte_/,""),operationNode=this.graph.createSetOperationNode(operationId,query.operator.value);return leftNodeId&&!this.graph.hasConnection(leftNodeId,operationNode.id)&&this.graph.addConnection(leftNodeId,operationNode.id),rightNodeId&&!this.graph.hasConnection(rightNodeId,operationNode.id)&&this.graph.addConnection(rightNodeId,operationNode.id),operationNode.id}processMultiPartOperation(parts,operator,context,cteNames){let partNodes=[],operationId=context==="main"?"main":context.replace(/^cte_/,""),operationNode=this.graph.createSetOperationNode(operationId,operator);for(let i=0;i<parts.length;i++){let partContext=`${context}_part${i+1}`,partNodeId=this.processQuery(parts[i],partContext,cteNames);partNodes.push(partNodeId)}for(let partNodeId of partNodes)partNodeId&&!this.graph.hasConnection(partNodeId,operationNode.id)&&this.graph.addConnection(partNodeId,operationNode.id);return operationNode.id}handleOutputNode(currentNodeId,context){if(context==="main"){let outputNode=this.graph.createOutputNode(context);return currentNodeId&&this.graph.addConnection(currentNodeId,outputNode.id),outputNode.id}return currentNodeId}flattenBinaryChain(query,operator){let parts=[],collectParts=q=>{q instanceof BinarySelectQuery&&q.operator.value===operator?(collectParts(q.left),collectParts(q.right)):parts.push(q)};return collectParts(query),parts}};var JsonSchemaValidator=class{static validate(jsonMapping,expectedStructure){let extractedStructure=this.extractStructureFromJsonMapping(jsonMapping);return this.compareStructures(extractedStructure,expectedStructure)}static validateStrict(jsonMapping,expectedStructure){let result=this.validate(jsonMapping,expectedStructure);if(!result.isValid){let errorMessage=["JsonMapping validation failed:",...result.errors].join(`
|
|
90
|
+
`),mermaid}getOrCreateTable(tableName){let nodeId=`table_${tableName}`,node=this.nodes.get(nodeId);return node||(node=DataSourceNode.createTable(tableName),this.addNode(node)),node}getOrCreateCTE(cteName){let nodeId=`cte_${cteName}`,node=this.nodes.get(nodeId);return node||(node=DataSourceNode.createCTE(cteName),this.addNode(node)),node}getOrCreateSubquery(alias){let nodeId=`subquery_${alias}`,node=this.nodes.get(nodeId);return node||(node=DataSourceNode.createSubquery(alias),this.addNode(node)),node}createProcessNode(type,context){let node=new ProcessNode(context,type);return this.addNode(node),node}createJoinNode(joinId,joinType){let node=OperationNode.createJoin(joinId,joinType);return this.addNode(node),node}createSetOperationNode(operationId,operation){let node=OperationNode.createSetOperation(operationId,operation);return this.addNode(node),node}createOutputNode(context="main"){let node=new OutputNode(context);return this.addNode(node),node}};var DataSourceHandler=class{constructor(graph){this.graph=graph}processSource(sourceExpr,cteNames,queryProcessor){if(sourceExpr.datasource instanceof TableSource)return this.processTableSource(sourceExpr.datasource,cteNames);if(sourceExpr.datasource instanceof SubQuerySource)return this.processSubquerySource(sourceExpr,cteNames,queryProcessor);throw new Error("Unsupported source type")}processTableSource(tableSource,cteNames){let tableName=tableSource.getSourceName();return cteNames.has(tableName)?this.graph.getOrCreateCTE(tableName).id:this.graph.getOrCreateTable(tableName).id}processSubquerySource(sourceExpr,cteNames,queryProcessor){let alias=sourceExpr.aliasExpression?.table.name||"subquery",subqueryNode=this.graph.getOrCreateSubquery(alias),subqueryResultId=queryProcessor(sourceExpr.datasource.query,`subquery_${alias}_internal`,cteNames);return subqueryResultId&&!this.graph.hasConnection(subqueryResultId,subqueryNode.id)&&this.graph.addConnection(subqueryResultId,subqueryNode.id),subqueryNode.id}extractTableNodeIds(fromClause,cteNames){let tableNodeIds=[],sourceExpr=fromClause.source;if(sourceExpr.datasource instanceof TableSource){let tableName=sourceExpr.datasource.getSourceName();if(cteNames.has(tableName)){let cteNode=this.graph.getOrCreateCTE(tableName);tableNodeIds.push(cteNode.id)}else{let tableNode=this.graph.getOrCreateTable(tableName);tableNodeIds.push(tableNode.id)}}if(fromClause.joins&&fromClause.joins.length>0)for(let join of fromClause.joins){let joinSourceExpr=join.source;if(joinSourceExpr.datasource instanceof TableSource){let tableName=joinSourceExpr.datasource.getSourceName();if(cteNames.has(tableName)){let cteNode=this.graph.getOrCreateCTE(tableName);tableNodeIds.push(cteNode.id)}else{let tableNode=this.graph.getOrCreateTable(tableName);tableNodeIds.push(tableNode.id)}}}return tableNodeIds}};var JoinHandler=class{constructor(graph,dataSourceHandler){this.graph=graph;this.dataSourceHandler=dataSourceHandler;this.joinIdCounter=0}resetJoinCounter(){this.joinIdCounter=0}getNextJoinId(){return String(++this.joinIdCounter)}processFromClause(fromClause,cteNames,queryProcessor){let mainSourceId=this.dataSourceHandler.processSource(fromClause.source,cteNames,queryProcessor);return fromClause.joins&&fromClause.joins.length>0?this.processJoins(fromClause.joins,mainSourceId,cteNames,queryProcessor):mainSourceId}processJoins(joins,currentNodeId,cteNames,queryProcessor){let resultNodeId=currentNodeId;for(let join of joins){let joinNodeId=this.dataSourceHandler.processSource(join.source,cteNames,queryProcessor),joinOpId=this.getNextJoinId(),joinNode=this.graph.createJoinNode(joinOpId,join.joinType.value),{leftLabel,rightLabel}=this.getJoinNullabilityLabels(join.joinType.value);resultNodeId&&!this.graph.hasConnection(resultNodeId,joinNode.id)&&this.graph.addConnection(resultNodeId,joinNode.id,leftLabel),joinNodeId&&!this.graph.hasConnection(joinNodeId,joinNode.id)&&this.graph.addConnection(joinNodeId,joinNode.id,rightLabel),resultNodeId=joinNode.id}return resultNodeId}getJoinNullabilityLabels(joinType){switch(joinType.toLowerCase()){case"left join":return{leftLabel:"NOT NULL",rightLabel:"NULLABLE"};case"right join":return{leftLabel:"NULLABLE",rightLabel:"NOT NULL"};case"inner join":case"join":return{leftLabel:"NOT NULL",rightLabel:"NOT NULL"};case"full join":case"full outer join":return{leftLabel:"NULLABLE",rightLabel:"NULLABLE"};case"cross join":return{leftLabel:"NOT NULL",rightLabel:"NOT NULL"};default:return{leftLabel:"",rightLabel:""}}}};var ProcessHandler=class{constructor(graph,dataSourceHandler){this.graph=graph;this.dataSourceHandler=dataSourceHandler}processQueryClauses(query,context,currentNodeId,cteNames,queryProcessor){return currentNodeId}};var CTEHandler=class{constructor(graph){this.graph=graph}processCTEs(withClause,cteNames,queryProcessor){for(let i=0;i<withClause.tables.length;i++){let cteName=withClause.tables[i].getSourceAliasName(),cteNode=this.graph.getOrCreateCTE(cteName);cteNames.add(cteName),withClause.recursive&&i===0&&cteNode.addAnnotation("recursive")}for(let i=0;i<withClause.tables.length;i++){let cte=withClause.tables[i],cteName=cte.getSourceAliasName(),cteNode=this.graph.getOrCreateCTE(cteName),cteResultId=queryProcessor(cte.query,`cte_${cteName}`,cteNames);if(cteResultId&&!this.graph.hasConnection(cteResultId,cteNode.id)){let label=withClause.recursive&&i===0?"RECURSIVE":void 0;this.graph.addConnection(cteResultId,cteNode.id,label)}}}detectRecursiveReference(query,cteName){return query.toString().toLowerCase().includes(cteName.toLowerCase())}};var QueryFlowDiagramGenerator=class _QueryFlowDiagramGenerator{constructor(){this.graph=new DataFlowGraph,this.dataSourceHandler=new DataSourceHandler(this.graph),this.joinHandler=new JoinHandler(this.graph,this.dataSourceHandler),this.processHandler=new ProcessHandler(this.graph,this.dataSourceHandler),this.cteHandler=new CTEHandler(this.graph)}generateMermaidFlow(query,options){this.graph=new DataFlowGraph,this.dataSourceHandler=new DataSourceHandler(this.graph),this.joinHandler=new JoinHandler(this.graph,this.dataSourceHandler),this.processHandler=new ProcessHandler(this.graph,this.dataSourceHandler),this.cteHandler=new CTEHandler(this.graph),this.joinHandler.resetJoinCounter();let parsedQuery=typeof query=="string"?SelectQueryParser.parse(query):query,cteNames=new Set;return this.processQuery(parsedQuery,"main",cteNames),this.graph.generateMermaid(options?.direction||"TD",options?.title)}static generate(sql){return new _QueryFlowDiagramGenerator().generateMermaidFlow(sql)}processQuery(query,context,cteNames){if(query instanceof SimpleSelectQuery)return this.processSimpleQuery(query,context,cteNames);if(query instanceof BinarySelectQuery)return this.processBinaryQuery(query,context,cteNames);throw new Error("Unsupported query type")}processSimpleQuery(query,context,cteNames){query.withClause&&this.cteHandler.processCTEs(query.withClause,cteNames,this.processQuery.bind(this));let currentNodeId="";return query.fromClause&&(query.fromClause.joins&&query.fromClause.joins.length>0?currentNodeId=this.joinHandler.processFromClause(query.fromClause,cteNames,this.processQuery.bind(this)):currentNodeId=this.dataSourceHandler.processSource(query.fromClause.source,cteNames,this.processQuery.bind(this))),currentNodeId&&(currentNodeId=this.processHandler.processQueryClauses(query,context,currentNodeId,cteNames,this.processQuery.bind(this))),this.handleOutputNode(currentNodeId,context)}processBinaryQuery(query,context,cteNames){let parts=this.flattenBinaryChain(query,query.operator.value);return parts.length>2?this.processMultiPartOperation(parts,query.operator.value,context,cteNames):this.processSimpleBinaryOperation(query,context,cteNames)}processSimpleBinaryOperation(query,context,cteNames){let leftNodeId=this.processQuery(query.left,`${context}_left`,cteNames),rightNodeId=this.processQuery(query.right,`${context}_right`,cteNames),operationId=context==="main"?"main":context.replace(/^cte_/,""),operationNode=this.graph.createSetOperationNode(operationId,query.operator.value);return leftNodeId&&!this.graph.hasConnection(leftNodeId,operationNode.id)&&this.graph.addConnection(leftNodeId,operationNode.id),rightNodeId&&!this.graph.hasConnection(rightNodeId,operationNode.id)&&this.graph.addConnection(rightNodeId,operationNode.id),operationNode.id}processMultiPartOperation(parts,operator,context,cteNames){let partNodes=[],operationId=context==="main"?"main":context.replace(/^cte_/,""),operationNode=this.graph.createSetOperationNode(operationId,operator);for(let i=0;i<parts.length;i++){let partContext=`${context}_part${i+1}`,partNodeId=this.processQuery(parts[i],partContext,cteNames);partNodes.push(partNodeId)}for(let partNodeId of partNodes)partNodeId&&!this.graph.hasConnection(partNodeId,operationNode.id)&&this.graph.addConnection(partNodeId,operationNode.id);return operationNode.id}handleOutputNode(currentNodeId,context){if(context==="main"){let outputNode=this.graph.createOutputNode(context);return currentNodeId&&this.graph.addConnection(currentNodeId,outputNode.id),outputNode.id}return currentNodeId}flattenBinaryChain(query,operator){let parts=[],collectParts=q=>{q instanceof BinarySelectQuery&&q.operator.value===operator?(collectParts(q.left),collectParts(q.right)):parts.push(q)};return collectParts(query),parts}};var SqlParamInjector=class{constructor(optionsOrResolver,options){typeof optionsOrResolver=="function"?(this.tableColumnResolver=optionsOrResolver,this.options=options||{}):(this.tableColumnResolver=void 0,this.options=optionsOrResolver||{})}inject(query,state){typeof query=="string"&&(query=SelectQueryParser.parse(query));let finder=new UpstreamSelectQueryFinder(this.tableColumnResolver,this.options),collector=new SelectableColumnCollector(this.tableColumnResolver,!1,"fullName",{upstream:!0}),normalize=s=>this.options.ignoreCaseAndUnderscore?s.toLowerCase().replace(/_/g,""):s,allowedOps=["min","max","like","ilike","in","any","=","<",">","!=","<>","<=",">=","or","and","column"],stateValues=Object.values(state);if(stateValues.length>0&&stateValues.every(value=>value===void 0)&&!this.options.allowAllUndefined)throw new Error("All parameters are undefined. This would result in fetching all records. Use allowAllUndefined: true option to explicitly allow this behavior.");let qualifiedParams=[],unqualifiedParams=[];for(let[name,stateValue]of Object.entries(state))stateValue!==void 0&&(this.isQualifiedColumnName(name)?qualifiedParams.push([name,stateValue]):unqualifiedParams.push([name,stateValue]));for(let[name,stateValue]of qualifiedParams)this.processStateParameter(name,stateValue,query,finder,collector,normalize,allowedOps,injectOrConditions,injectAndConditions,injectSimpleCondition,injectComplexConditions,validateOperators);let processedQualifiedColumns=new Set;for(let[qualifiedName,_]of qualifiedParams){let parsed=this.parseQualifiedColumnName(qualifiedName);parsed&&processedQualifiedColumns.add(`${parsed.table.toLowerCase()}.${parsed.column.toLowerCase()}`)}for(let[name,stateValue]of unqualifiedParams)this.processUnqualifiedParameter(name,stateValue,query,finder,collector,normalize,allowedOps,injectOrConditions,injectAndConditions,injectSimpleCondition,injectComplexConditions,validateOperators,processedQualifiedColumns);function injectAndConditions(q,baseName,andConditions,normalize2,availableColumns){for(let i=0;i<andConditions.length;i++){let andCondition=andConditions[i],columnName=andCondition.column||baseName,entry=availableColumns.find(item=>normalize2(item.name)===normalize2(columnName));if(!entry)throw new Error(`Column '${columnName}' not found in query for AND condition`);let columnRef=entry.value;if("="in andCondition&&andCondition["="]!==void 0){let paramName=`${baseName}_and_${i}_eq`,paramExpr=new ParameterExpression(paramName,andCondition["="]);q.appendWhere(new BinaryExpression(columnRef,"=",paramExpr))}if("min"in andCondition&&andCondition.min!==void 0){let paramName=`${baseName}_and_${i}_min`,paramExpr=new ParameterExpression(paramName,andCondition.min);q.appendWhere(new BinaryExpression(columnRef,">=",paramExpr))}if("max"in andCondition&&andCondition.max!==void 0){let paramName=`${baseName}_and_${i}_max`,paramExpr=new ParameterExpression(paramName,andCondition.max);q.appendWhere(new BinaryExpression(columnRef,"<=",paramExpr))}if("like"in andCondition&&andCondition.like!==void 0){let paramName=`${baseName}_and_${i}_like`,paramExpr=new ParameterExpression(paramName,andCondition.like);q.appendWhere(new BinaryExpression(columnRef,"like",paramExpr))}if("ilike"in andCondition&&andCondition.ilike!==void 0){let paramName=`${baseName}_and_${i}_ilike`,paramExpr=new ParameterExpression(paramName,andCondition.ilike);q.appendWhere(new BinaryExpression(columnRef,"ilike",paramExpr))}if("in"in andCondition&&andCondition.in!==void 0){let prms=andCondition.in.map((v,j)=>new ParameterExpression(`${baseName}_and_${i}_in_${j}`,v));q.appendWhere(new BinaryExpression(columnRef,"in",new ParenExpression(new ValueList(prms))))}if("any"in andCondition&&andCondition.any!==void 0){let paramName=`${baseName}_and_${i}_any`,paramExpr=new ParameterExpression(paramName,andCondition.any);q.appendWhere(new BinaryExpression(columnRef,"=",new FunctionCall(null,"any",paramExpr,null)))}if("<"in andCondition&&andCondition["<"]!==void 0){let paramName=`${baseName}_and_${i}_lt`,paramExpr=new ParameterExpression(paramName,andCondition["<"]);q.appendWhere(new BinaryExpression(columnRef,"<",paramExpr))}if(">"in andCondition&&andCondition[">"]!==void 0){let paramName=`${baseName}_and_${i}_gt`,paramExpr=new ParameterExpression(paramName,andCondition[">"]);q.appendWhere(new BinaryExpression(columnRef,">",paramExpr))}if("!="in andCondition&&andCondition["!="]!==void 0){let paramName=`${baseName}_and_${i}_neq`,paramExpr=new ParameterExpression(paramName,andCondition["!="]);q.appendWhere(new BinaryExpression(columnRef,"!=",paramExpr))}if("<>"in andCondition&&andCondition["<>"]!==void 0){let paramName=`${baseName}_and_${i}_ne`,paramExpr=new ParameterExpression(paramName,andCondition["<>"]);q.appendWhere(new BinaryExpression(columnRef,"<>",paramExpr))}if("<="in andCondition&&andCondition["<="]!==void 0){let paramName=`${baseName}_and_${i}_le`,paramExpr=new ParameterExpression(paramName,andCondition["<="]);q.appendWhere(new BinaryExpression(columnRef,"<=",paramExpr))}if(">="in andCondition&&andCondition[">="]!==void 0){let paramName=`${baseName}_and_${i}_ge`,paramExpr=new ParameterExpression(paramName,andCondition[">="]);q.appendWhere(new BinaryExpression(columnRef,">=",paramExpr))}}}function injectOrConditions(q,baseName,orConditions,normalize2,availableColumns){let orExpressions=[];for(let i=0;i<orConditions.length;i++){let orCondition=orConditions[i],columnName=orCondition.column||baseName,entry=availableColumns.find(item=>normalize2(item.name)===normalize2(columnName));if(!entry)throw new Error(`Column '${columnName}' not found in query for OR condition`);let columnRef=entry.value,branchConditions=[];if("="in orCondition&&orCondition["="]!==void 0){let paramName=`${baseName}_or_${i}_eq`,paramExpr=new ParameterExpression(paramName,orCondition["="]);branchConditions.push(new BinaryExpression(columnRef,"=",paramExpr))}if("min"in orCondition&&orCondition.min!==void 0){let paramName=`${baseName}_or_${i}_min`,paramExpr=new ParameterExpression(paramName,orCondition.min);branchConditions.push(new BinaryExpression(columnRef,">=",paramExpr))}if("max"in orCondition&&orCondition.max!==void 0){let paramName=`${baseName}_or_${i}_max`,paramExpr=new ParameterExpression(paramName,orCondition.max);branchConditions.push(new BinaryExpression(columnRef,"<=",paramExpr))}if("like"in orCondition&&orCondition.like!==void 0){let paramName=`${baseName}_or_${i}_like`,paramExpr=new ParameterExpression(paramName,orCondition.like);branchConditions.push(new BinaryExpression(columnRef,"like",paramExpr))}if("ilike"in orCondition&&orCondition.ilike!==void 0){let paramName=`${baseName}_or_${i}_ilike`,paramExpr=new ParameterExpression(paramName,orCondition.ilike);branchConditions.push(new BinaryExpression(columnRef,"ilike",paramExpr))}if("in"in orCondition&&orCondition.in!==void 0){let prms=orCondition.in.map((v,j)=>new ParameterExpression(`${baseName}_or_${i}_in_${j}`,v));branchConditions.push(new BinaryExpression(columnRef,"in",new ParenExpression(new ValueList(prms))))}if("any"in orCondition&&orCondition.any!==void 0){let paramName=`${baseName}_or_${i}_any`,paramExpr=new ParameterExpression(paramName,orCondition.any);branchConditions.push(new BinaryExpression(columnRef,"=",new FunctionCall(null,"any",paramExpr,null)))}if("<"in orCondition&&orCondition["<"]!==void 0){let paramName=`${baseName}_or_${i}_lt`,paramExpr=new ParameterExpression(paramName,orCondition["<"]);branchConditions.push(new BinaryExpression(columnRef,"<",paramExpr))}if(">"in orCondition&&orCondition[">"]!==void 0){let paramName=`${baseName}_or_${i}_gt`,paramExpr=new ParameterExpression(paramName,orCondition[">"]);branchConditions.push(new BinaryExpression(columnRef,">",paramExpr))}if("!="in orCondition&&orCondition["!="]!==void 0){let paramName=`${baseName}_or_${i}_neq`,paramExpr=new ParameterExpression(paramName,orCondition["!="]);branchConditions.push(new BinaryExpression(columnRef,"!=",paramExpr))}if("<>"in orCondition&&orCondition["<>"]!==void 0){let paramName=`${baseName}_or_${i}_ne`,paramExpr=new ParameterExpression(paramName,orCondition["<>"]);branchConditions.push(new BinaryExpression(columnRef,"<>",paramExpr))}if("<="in orCondition&&orCondition["<="]!==void 0){let paramName=`${baseName}_or_${i}_le`,paramExpr=new ParameterExpression(paramName,orCondition["<="]);branchConditions.push(new BinaryExpression(columnRef,"<=",paramExpr))}if(">="in orCondition&&orCondition[">="]!==void 0){let paramName=`${baseName}_or_${i}_ge`,paramExpr=new ParameterExpression(paramName,orCondition[">="]);branchConditions.push(new BinaryExpression(columnRef,">=",paramExpr))}if(branchConditions.length>0){let branchExpr=branchConditions[0];for(let j=1;j<branchConditions.length;j++)branchExpr=new BinaryExpression(branchExpr,"and",branchConditions[j]);branchConditions.length>1?orExpressions.push(new ParenExpression(branchExpr)):orExpressions.push(branchExpr)}}if(orExpressions.length>0){let finalOrExpr=orExpressions[0];for(let i=1;i<orExpressions.length;i++)finalOrExpr=new BinaryExpression(finalOrExpr,"or",orExpressions[i]);q.appendWhere(new ParenExpression(finalOrExpr))}}function validateOperators(stateValue,allowedOps2,name){Object.keys(stateValue).forEach(op=>{if(!allowedOps2.includes(op))throw new Error(`Unsupported operator '${op}' for state key '${name}'`)})}function injectSimpleCondition(q,columnRef,name,stateValue){let paramExpr=new ParameterExpression(name,stateValue);q.appendWhere(new BinaryExpression(columnRef,"=",paramExpr))}function injectComplexConditions(q,columnRef,name,stateValue){let conditions=[];if("="in stateValue){let paramEq=new ParameterExpression(name,stateValue["="]);conditions.push(new BinaryExpression(columnRef,"=",paramEq))}if("min"in stateValue){let paramMin=new ParameterExpression(name+"_min",stateValue.min);conditions.push(new BinaryExpression(columnRef,">=",paramMin))}if("max"in stateValue){let paramMax=new ParameterExpression(name+"_max",stateValue.max);conditions.push(new BinaryExpression(columnRef,"<=",paramMax))}if("like"in stateValue){let paramLike=new ParameterExpression(name+"_like",stateValue.like);conditions.push(new BinaryExpression(columnRef,"like",paramLike))}if("ilike"in stateValue){let paramIlike=new ParameterExpression(name+"_ilike",stateValue.ilike);conditions.push(new BinaryExpression(columnRef,"ilike",paramIlike))}if("in"in stateValue){let prms=stateValue.in.map((v,i)=>new ParameterExpression(`${name}_in_${i}`,v));conditions.push(new BinaryExpression(columnRef,"in",new ParenExpression(new ValueList(prms))))}if("any"in stateValue){let paramAny=new ParameterExpression(name+"_any",stateValue.any);conditions.push(new BinaryExpression(columnRef,"=",new FunctionCall(null,"any",paramAny,null)))}if("<"in stateValue){let paramLT=new ParameterExpression(name+"_lt",stateValue["<"]);conditions.push(new BinaryExpression(columnRef,"<",paramLT))}if(">"in stateValue){let paramGT=new ParameterExpression(name+"_gt",stateValue[">"]);conditions.push(new BinaryExpression(columnRef,">",paramGT))}if("!="in stateValue){let paramNEQ=new ParameterExpression(name+"_neq",stateValue["!="]);conditions.push(new BinaryExpression(columnRef,"!=",paramNEQ))}if("<>"in stateValue){let paramNE=new ParameterExpression(name+"_ne",stateValue["<>"]);conditions.push(new BinaryExpression(columnRef,"<>",paramNE))}if("<="in stateValue){let paramLE=new ParameterExpression(name+"_le",stateValue["<="]);conditions.push(new BinaryExpression(columnRef,"<=",paramLE))}if(">="in stateValue){let paramGE=new ParameterExpression(name+"_ge",stateValue[">="]);conditions.push(new BinaryExpression(columnRef,">=",paramGE))}if(conditions.length===1)q.appendWhere(conditions[0]);else if(conditions.length>1){let combinedExpr=conditions[0];for(let i=1;i<conditions.length;i++)combinedExpr=new BinaryExpression(combinedExpr,"and",conditions[i]);q.appendWhere(new ParenExpression(combinedExpr))}}return query}isOrCondition(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&"or"in value}isAndCondition(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&"and"in value}isExplicitColumnMapping(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&"column"in value&&!("or"in value)}isValidatableObject(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&Object.getPrototypeOf(value)===Object.prototype}parseQualifiedColumnName(qualifiedName){let parts=qualifiedName.split(".");return parts.length===2&&parts[0].trim()&&parts[1].trim()?{table:parts[0].trim(),column:parts[1].trim()}:null}isQualifiedColumnName(name){return name.includes(".")&&this.parseQualifiedColumnName(name)!==null}sanitizeParameterName(name){return name.replace(/\./g,"_")}hasColumnMapping(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&"column"in value}isSimpleValue(value){return value===null||typeof value!="object"||Array.isArray(value)||value instanceof Date}processStateParameter(name,stateValue,query,finder,collector,normalize,allowedOps,injectOrConditions,injectAndConditions,injectSimpleCondition,injectComplexConditions,validateOperators){if(this.isOrCondition(stateValue)){let orConditions=stateValue.or;if(orConditions&&orConditions.length>0){let targetQuery=this.findTargetQueryForLogicalCondition(finder,query,name,orConditions),allColumns=this.getAllAvailableColumns(targetQuery,collector);injectOrConditions(targetQuery,name,orConditions,normalize,allColumns);return}}if(this.isAndCondition(stateValue)){let andConditions=stateValue.and;if(andConditions&&andConditions.length>0){let targetQuery=this.findTargetQueryForLogicalCondition(finder,query,name,andConditions),allColumns=this.getAllAvailableColumns(targetQuery,collector);injectAndConditions(targetQuery,name,andConditions,normalize,allColumns);return}}if(this.isExplicitColumnMapping(stateValue)){let explicitColumnName=stateValue.column;if(explicitColumnName){let queries=finder.find(query,explicitColumnName);if(queries.length===0)throw new Error(`Explicit column '${explicitColumnName}' not found in query`);for(let q of queries){let entry=this.getAllAvailableColumns(q,collector).find(item=>normalize(item.name)===normalize(explicitColumnName));if(!entry)throw new Error(`Explicit column '${explicitColumnName}' not found in query`);this.isValidatableObject(stateValue)&&validateOperators(stateValue,allowedOps,name),injectComplexConditions(q,entry.value,name,stateValue)}return}}this.processRegularColumnCondition(name,stateValue,query,finder,collector,normalize,allowedOps,injectSimpleCondition,injectComplexConditions,validateOperators)}processUnqualifiedParameter(name,stateValue,query,finder,collector,normalize,allowedOps,injectOrConditions,injectAndConditions,injectSimpleCondition,injectComplexConditions,validateOperators,processedQualifiedColumns){if(this.isOrCondition(stateValue)){let orConditions=stateValue.or;if(orConditions&&orConditions.length>0){let targetQuery=this.findTargetQueryForLogicalCondition(finder,query,name,orConditions),allColumns=this.getAllAvailableColumns(targetQuery,collector);injectOrConditions(targetQuery,name,orConditions,normalize,allColumns);return}}if(this.isAndCondition(stateValue)){let andConditions=stateValue.and;if(andConditions&&andConditions.length>0){let targetQuery=this.findTargetQueryForLogicalCondition(finder,query,name,andConditions),allColumns=this.getAllAvailableColumns(targetQuery,collector);injectAndConditions(targetQuery,name,andConditions,normalize,allColumns);return}}if(this.isExplicitColumnMapping(stateValue)){let explicitColumnName=stateValue.column;if(explicitColumnName){let queries2=finder.find(query,explicitColumnName);if(queries2.length===0)throw new Error(`Explicit column '${explicitColumnName}' not found in query`);for(let q of queries2){let entry=this.getAllAvailableColumns(q,collector).find(item=>normalize(item.name)===normalize(explicitColumnName));if(!entry)throw new Error(`Explicit column '${explicitColumnName}' not found in query`);this.isValidatableObject(stateValue)&&validateOperators(stateValue,allowedOps,name),injectComplexConditions(q,entry.value,name,stateValue)}return}}let queries=finder.find(query,name);if(queries.length===0){if(this.options.ignoreNonExistentColumns)return;throw new Error(`Column '${name}' not found in query`)}for(let q of queries){let allColumns=this.getAllAvailableColumns(q,collector),tableMapping=this.buildTableMapping(q),matchingColumns=allColumns.filter(item=>normalize(item.name)===normalize(name));for(let entry of matchingColumns){let skipColumn=!1;if(entry.value&&typeof entry.value.getNamespace=="function"){let namespace=entry.value.getNamespace();if(namespace){let realTableName=tableMapping.aliasToRealTable.get(namespace.toLowerCase());if(realTableName){let qualifiedKey=`${realTableName.toLowerCase()}.${name.toLowerCase()}`;processedQualifiedColumns.has(qualifiedKey)&&(skipColumn=!0)}}}if(skipColumn)continue;let columnRef=entry.value;this.isValidatableObject(stateValue)&&validateOperators(stateValue,allowedOps,name);let targetColumn=columnRef;if(this.hasColumnMapping(stateValue)){let explicitColumnName=stateValue.column;if(explicitColumnName){let explicitEntry=allColumns.find(item=>normalize(item.name)===normalize(explicitColumnName));explicitEntry&&(targetColumn=explicitEntry.value)}}this.isSimpleValue(stateValue)?injectSimpleCondition(q,targetColumn,name,stateValue):injectComplexConditions(q,targetColumn,name,stateValue)}}}processRegularColumnCondition(name,stateValue,query,finder,collector,normalize,allowedOps,injectSimpleCondition,injectComplexConditions,validateOperators){let searchColumnName=name,targetTableName;if(this.isQualifiedColumnName(name)){let parsed=this.parseQualifiedColumnName(name);parsed&&(searchColumnName=parsed.column,targetTableName=parsed.table)}let queries=finder.find(query,searchColumnName);if(queries.length===0){if(this.options.ignoreNonExistentColumns)return;throw new Error(`Column '${searchColumnName}' not found in query`)}for(let q of queries){let allColumns=this.getAllAvailableColumns(q,collector),entry;if(targetTableName){let tableMapping=this.buildTableMapping(q);if(entry=allColumns.find(item=>{if(!(normalize(item.name)===normalize(searchColumnName)))return!1;if(item.value&&typeof item.value.getNamespace=="function"){let namespace=item.value.getNamespace();if(namespace){let normalizedNamespace=normalize(namespace),normalizedTargetTable=normalize(targetTableName),realTableName=tableMapping.aliasToRealTable.get(normalizedNamespace);if(realTableName&&normalize(realTableName)===normalizedTargetTable)return!0}}return!1}),!entry){if(this.options.ignoreNonExistentColumns)continue;let tableMapping2=this.buildTableMapping(q),hasRealTable=Array.from(tableMapping2.realTableToAlias.keys()).some(realTable=>normalize(realTable)===normalize(targetTableName)),hasAliasTable=Array.from(tableMapping2.aliasToRealTable.keys()).some(alias=>normalize(alias)===normalize(targetTableName));throw!hasRealTable&&!hasAliasTable?new Error(`Column '${name}' (qualified as ${name}) not found in query`):hasAliasTable&&!hasRealTable?new Error(`Column '${name}' not found. Only real table names are allowed in qualified column references (e.g., 'users.name'), not aliases (e.g., 'u.name').`):new Error(`Column '${name}' (qualified as ${name}) not found in query`)}}else if(entry=allColumns.find(item=>normalize(item.name)===normalize(searchColumnName)),!entry)throw new Error(`Column '${searchColumnName}' not found in query`);let columnRef=entry.value;this.isValidatableObject(stateValue)&&validateOperators(stateValue,allowedOps,name);let targetColumn=columnRef;if(this.hasColumnMapping(stateValue)){let explicitColumnName=stateValue.column;if(explicitColumnName){let explicitEntry=allColumns.find(item=>normalize(item.name)===normalize(explicitColumnName));explicitEntry&&(targetColumn=explicitEntry.value)}}let parameterName=this.sanitizeParameterName(name);this.isSimpleValue(stateValue)?injectSimpleCondition(q,targetColumn,parameterName,stateValue):injectComplexConditions(q,targetColumn,parameterName,stateValue)}}findTargetQueryForLogicalCondition(finder,query,baseName,conditions){let referencedColumns=conditions.map(cond=>cond.column||baseName).filter((col,index,arr)=>arr.indexOf(col)===index);for(let colName of referencedColumns){let queries=finder.find(query,colName);if(queries.length>0)return queries[0]}let conditionType=conditions===conditions.or?"OR":"AND";throw new Error(`None of the ${conditionType} condition columns [${referencedColumns.join(", ")}] found in query`)}getAllAvailableColumns(query,collector){let columns=collector.collect(query),cteColumns=this.collectCTEColumns(query);return[...columns,...cteColumns]}collectCTEColumns(query){let cteColumns=[];if(query.withClause)for(let cte of query.withClause.tables)try{let columns=this.collectColumnsFromCteQuery(cte.query);cteColumns.push(...columns)}catch{}return cteColumns}collectColumnsFromCteQuery(query){return this.isSelectQuery(query)?this.collectColumnsFromSelectQuery(query):this.collectColumnsFromReturning(query)}collectColumnsFromSelectQuery(query){return query instanceof SimpleSelectQuery?new SelectableColumnCollector(this.tableColumnResolver,!1,"fullName",{upstream:!0}).collect(query):query instanceof BinarySelectQuery?this.collectColumnsFromSelectQuery(query.left):[]}collectColumnsFromReturning(query){if(query instanceof InsertQuery||query instanceof UpdateQuery||query instanceof DeleteQuery){if(!query.returningClause)return[];let columns=[];for(let item of query.returningClause.items){let columnName=item.identifier?.name??this.extractColumnName(item);columnName&&columns.push({name:columnName,value:item.value})}return columns}return[]}extractColumnName(item){return item.identifier?item.identifier.name:item.value instanceof ColumnReference?item.value.column.name:null}isSelectQuery(query){return"__selectQueryType"in query&&query.__selectQueryType==="SelectQuery"}buildTableMapping(query){let aliasToRealTable=new Map,realTableToAlias=new Map;try{if(query.fromClause&&(this.processSourceForMapping(query.fromClause.source,aliasToRealTable,realTableToAlias),query.fromClause.joins))for(let join of query.fromClause.joins)this.processSourceForMapping(join.source,aliasToRealTable,realTableToAlias);if(query.withClause)for(let cte of query.withClause.tables){let cteAlias=cte.getSourceAliasName();cteAlias&&(aliasToRealTable.set(cteAlias.toLowerCase(),cteAlias),realTableToAlias.set(cteAlias.toLowerCase(),cteAlias))}}catch{}return{aliasToRealTable,realTableToAlias}}processSourceForMapping(source,aliasToRealTable,realTableToAlias){try{if(source.datasource instanceof TableSource){let realTableName=source.datasource.getSourceName(),aliasName=source.aliasExpression?.table?.name||realTableName;realTableName&&aliasName&&(aliasToRealTable.set(aliasName.toLowerCase(),realTableName),realTableToAlias.set(realTableName.toLowerCase(),aliasName),aliasName===realTableName&&aliasToRealTable.set(realTableName.toLowerCase(),realTableName))}}catch{}}};var JsonSchemaValidator=class{static validate(jsonMapping,expectedStructure){let extractedStructure=this.extractStructureFromJsonMapping(jsonMapping);return this.compareStructures(extractedStructure,expectedStructure)}static validateStrict(jsonMapping,expectedStructure){let result=this.validate(jsonMapping,expectedStructure);if(!result.isValid){let errorMessage=["JsonMapping validation failed:",...result.errors].join(`
|
|
91
91
|
`);throw new Error(errorMessage)}}static extractStructureFromJsonMapping(jsonMapping){let structure={};return jsonMapping.rootEntity&&jsonMapping.rootEntity.columns&&Object.keys(jsonMapping.rootEntity.columns).forEach(propertyName=>{structure[propertyName]="primitive"}),jsonMapping.nestedEntities&&jsonMapping.nestedEntities.filter(entity=>entity.parentId===jsonMapping.rootEntity.id).forEach(entity=>{entity.propertyName&&entity.columns&&(entity.relationshipType==="object"?structure[entity.propertyName]=this.extractNestedEntityStructure(entity,jsonMapping):entity.relationshipType==="array"&&(structure[entity.propertyName]=[this.extractNestedEntityStructure(entity,jsonMapping)]))}),structure}static extractNestedEntityStructure(entity,jsonMapping){let entityStructure={};return entity.columns&&Object.keys(entity.columns).forEach(propName=>{entityStructure[propName]="primitive"}),jsonMapping.nestedEntities&&jsonMapping.nestedEntities.filter(childEntity=>childEntity.parentId===entity.id).forEach(childEntity=>{childEntity.propertyName&&childEntity.columns&&(childEntity.relationshipType==="object"?entityStructure[childEntity.propertyName]=this.extractNestedEntityStructure(childEntity,jsonMapping):childEntity.relationshipType==="array"&&(entityStructure[childEntity.propertyName]=[this.extractNestedEntityStructure(childEntity,jsonMapping)]))}),entityStructure}static compareStructures(extracted,expected,path=""){let errors=[],missingProperties=[],extraProperties=[];if(extracted==="primitive"&&expected==="primitive")return{isValid:!0,errors:[],missingProperties:[],extraProperties:[]};if(Array.isArray(expected)&&Array.isArray(extracted)){if(expected.length>0&&extracted.length>0){let nestedResult=this.compareStructures(extracted[0],expected[0],`${path}[]`);errors.push(...nestedResult.errors),missingProperties.push(...nestedResult.missingProperties),extraProperties.push(...nestedResult.extraProperties)}return{isValid:errors.length===0,errors,missingProperties,extraProperties}}if(typeof extracted!="object"||typeof expected!="object"||Array.isArray(extracted)||Array.isArray(expected)||extracted===null||expected===null)return{isValid:!0,errors:[],missingProperties:[],extraProperties:[]};let extractedObj=extracted,expectedObj=expected;return Object.keys(expectedObj).forEach(key=>{let currentPath=path?`${path}.${key}`:key;if(!(key in extractedObj)){missingProperties.push(currentPath),errors.push(`Missing property: ${currentPath}`);return}let extractedValue=extractedObj[key],expectedValue=expectedObj[key],nestedResult=this.compareStructures(extractedValue,expectedValue,currentPath);errors.push(...nestedResult.errors),missingProperties.push(...nestedResult.missingProperties),extraProperties.push(...nestedResult.extraProperties)}),Object.keys(extractedObj).forEach(key=>{let currentPath=path?`${path}.${key}`:key;key in expectedObj||extraProperties.push(currentPath)}),{isValid:errors.length===0,errors,missingProperties,extraProperties}}static validateAgainstSample(jsonMapping,sampleObject){let expectedStructure=this.extractStructureFromSample(sampleObject);return this.validate(jsonMapping,expectedStructure)}static validateAgainstSampleStrict(jsonMapping,sampleObject){let result=this.validateAgainstSample(jsonMapping,sampleObject);if(!result.isValid){let errorMessage=["JsonMapping validation against sample object failed:",...result.errors].join(`
|
|
92
|
-
`);throw new Error(errorMessage)}}static extractStructureFromSample(sampleObject){if(sampleObject==null)return"primitive";if(Array.isArray(sampleObject))return sampleObject.length===0?[]:[this.extractStructureFromSample(sampleObject[0])];if(typeof sampleObject=="object"){let structure={};return Object.keys(sampleObject).forEach(key=>{structure[key]=this.extractStructureFromSample(sampleObject[key])}),structure}return"primitive"}};var SchemaManager=class{constructor(schemas){this.schemas=schemas,this.validateSchemas()}validateSchemas(){let tableNames=Object.keys(this.schemas),errors=[];if(Object.entries(this.schemas).forEach(([tableName,table])=>{Object.entries(table.columns).filter(([_,col])=>col.isPrimaryKey).map(([name,_])=>name).length===0&&errors.push(`Table '${tableName}' has no primary key defined`),table.relationships?.forEach(rel=>{tableNames.includes(rel.table)||errors.push(`Table '${tableName}' references unknown table '${rel.table}' in relationship`)})}),errors.length>0)throw new Error(`Schema validation failed:\\n${errors.join("\\n")}`)}getTableColumns(tableName){let table=this.schemas[tableName];return table?Object.keys(table.columns):[]}createTableColumnResolver(){return tableName=>this.getTableColumns(tableName)}createJsonMapping(rootTableName){let rootTable=this.schemas[rootTableName];if(!rootTable)throw new Error(`Table '${rootTableName}' not found in schema registry`);let rootColumns={};Object.entries(rootTable.columns).forEach(([columnName,column])=>{rootColumns[columnName]=column.jsonAlias||column.name});let nestedEntities=[];return rootTable.relationships?.forEach(rel=>{let relatedTable=this.schemas[rel.table];if(!relatedTable)throw new Error(`Related table '${rel.table}' not found in schema registry`);let relatedColumns={};Object.entries(relatedTable.columns).forEach(([columnName,column])=>{relatedColumns[columnName]=column.jsonAlias||column.name});let relationshipType=rel.type;nestedEntities.push({id:rel.propertyName,name:relatedTable.displayName||rel.table,parentId:rootTableName,propertyName:rel.propertyName,relationshipType,columns:relatedColumns})}),{rootName:rootTableName,rootEntity:{id:rootTableName,name:rootTable.displayName||rootTableName,columns:rootColumns},nestedEntities,resultFormat:"single"}}getTableNames(){return Object.keys(this.schemas)}getTable(tableName){return this.schemas[tableName]}getPrimaryKey(tableName){let table=this.schemas[tableName];if(!table)return;let primaryKeyEntry=Object.entries(table.columns).find(([_,col])=>col.isPrimaryKey);return primaryKeyEntry?primaryKeyEntry[0]:void 0}getForeignKeys(tableName){let table=this.schemas[tableName];if(!table)return[];let foreignKeys=[];return Object.entries(table.columns).forEach(([columnName,column])=>{column.foreignKey&&foreignKeys.push({column:columnName,referencedTable:column.foreignKey.table,referencedColumn:column.foreignKey.column})}),foreignKeys}};function createSchemaManager(schemas){return new SchemaManager(schemas)}function createTableColumnResolver(schemas){return new SchemaManager(schemas).createTableColumnResolver()}function createJsonMappingFromSchema(schemas,rootTableName){return new SchemaManager(schemas).createJsonMapping(rootTableName)}var KeywordCache=class{static{this.joinSuggestionCache=new Map}static{this.commandSuggestionCache=new Map}static{this.initialized=!1}static initialize(){if(this.initialized)return;let joinPatterns=[["join"],["inner","join"],["cross","join"],["left","join"],["left","outer","join"],["right","join"],["right","outer","join"],["full","join"],["full","outer","join"],["natural","join"],["natural","inner","join"],["natural","left","join"],["natural","left","outer","join"],["natural","right","join"],["natural","right","outer","join"],["natural","full","join"],["natural","full","outer","join"],["lateral","join"],["lateral","inner","join"],["lateral","left","join"],["lateral","left","outer","join"]],suggestionMap=new Map,completePhrases=new Set;joinPatterns.forEach(pattern=>{pattern.length>1&&completePhrases.add(pattern.slice(1).join(" ").toUpperCase())}),joinPatterns.forEach(pattern=>{for(let i=0;i<pattern.length-1;i++){let prefix=pattern[i];suggestionMap.has(prefix)||suggestionMap.set(prefix,new Set),joinPatterns.forEach(candidatePattern=>{if(candidatePattern.length>i+1&&candidatePattern[i]===prefix){let completePhrase=candidatePattern.slice(i+1).join(" ").toUpperCase();suggestionMap.get(prefix).add(completePhrase)}})}}),suggestionMap.forEach((suggestions,keyword)=>{this.joinSuggestionCache.set(keyword.toLowerCase(),Array.from(suggestions))}),this.initializeCommandKeywords(),this.initialized=!0}static getJoinSuggestions(keyword){return this.initialize(),this.joinSuggestionCache.get(keyword.toLowerCase())||[]}static isValidJoinKeyword(keyword){return joinkeywordParser.parse(keyword,0)!==null}static getPartialSuggestions(partialKeyword){this.initialize();let partial=partialKeyword.toLowerCase(),suggestions=[];return this.joinSuggestionCache.forEach((values,key)=>{key.startsWith(partial)&&(suggestions.push(key),values.forEach(value=>{suggestions.includes(value)||suggestions.push(value)}))}),suggestions}static getAllJoinKeywords(){this.initialize();let allKeywords=new Set;return this.joinSuggestionCache.forEach((values,key)=>{allKeywords.add(key),values.forEach(value=>allKeywords.add(value))}),Array.from(allKeywords)}static initializeCommandKeywords(){let commandPatterns=this.extractCommandPatternsFromTrie(),suggestionMap=new Map;commandPatterns.forEach(pattern=>{for(let i=0;i<pattern.length-1;i++){let prefix=pattern[i],nextWord=pattern[i+1];suggestionMap.has(prefix)||suggestionMap.set(prefix,new Set),suggestionMap.get(prefix).add(nextWord)}}),suggestionMap.forEach((suggestions,keyword)=>{this.commandSuggestionCache.set(keyword.toLowerCase(),Array.from(suggestions))})}static extractCommandPatternsFromTrie(){return[["group","by"],["order","by"],["distinct","on"],["not","materialized"],["row","only"],["rows","only"],["percent","with","ties"],["key","share"],["no","key","update"],["union","all"],["intersect","all"],["except","all"],["partition","by"],["within","group"],["with","ordinality"]]}static getCommandSuggestions(keyword){return this.initialize(),this.commandSuggestionCache.get(keyword.toLowerCase())||[]}static reset(){this.joinSuggestionCache.clear(),this.commandSuggestionCache.clear(),this.initialized=!1}};var CursorContextAnalyzer=class{static{this.patternCache=null}static getKeywordPatterns(){if(this.patternCache!==null)return this.patternCache;let requiresKeywords=new Map,suggestsTables=new Set,suggestsColumns=new Set;return this.extractKeywordPatterns(requiresKeywords,suggestsTables,suggestsColumns),this.patternCache={requiresKeywords,suggestsTables,suggestsColumns},this.patternCache}static extractKeywordPatterns(requiresKeywords,suggestsTables,suggestsColumns){let tableContexts=["from","join"],columnContexts=["select","where","on","having","by"];for(let keyword of tableContexts)this.isKeywordInDictionary(keyword)&&suggestsTables.add(keyword);for(let keyword of columnContexts)this.isKeywordInDictionary(keyword)&&suggestsColumns.add(keyword);this.extractRequiresKeywordPatterns(requiresKeywords)}static isKeywordInDictionary(keyword){return KeywordCache.isValidJoinKeyword(keyword)?!0:["from","join","select","where","on","having","by","group","order"].includes(keyword)}static extractRequiresKeywordPatterns(requiresKeywords){let potentialFirstWords=["inner","left","right","full","cross","natural","outer","group","order"];for(let word of potentialFirstWords){let possibleFollowups=this.findPossibleFollowups(word);possibleFollowups.length>0&&requiresKeywords.set(word,possibleFollowups)}}static findPossibleFollowups(word){let followups=new Set;return KeywordCache.getJoinSuggestions(word.toLowerCase()).forEach(s=>followups.add(s.toUpperCase())),KeywordCache.getCommandSuggestions(word.toLowerCase()).forEach(s=>followups.add(s.toUpperCase())),Array.from(followups)}static requiresSpecificKeywords(tokenValue){let requiredKeywords=this.getKeywordPatterns().requiresKeywords.get(tokenValue);return requiredKeywords?{suggestKeywords:!0,requiredKeywords}:null}static analyzeIntelliSense(sql,cursorPosition){try{let allLexemes=LexemeCursor.getAllLexemesWithPosition(sql),actualTokenIndex=-1,actualCurrentToken;for(let i=0;i<allLexemes.length;i++){let lexeme=allLexemes[i];if(lexeme.position){if(cursorPosition>=lexeme.position.startPosition&&cursorPosition<=lexeme.position.endPosition){actualCurrentToken=lexeme,actualTokenIndex=i;break}else if(lexeme.position.startPosition>cursorPosition){actualTokenIndex=Math.max(0,i-1),actualCurrentToken=actualTokenIndex>=0?allLexemes[actualTokenIndex]:void 0;break}}}actualTokenIndex===-1&&allLexemes.length>0&&(actualTokenIndex=allLexemes.length-1,actualCurrentToken=allLexemes[actualTokenIndex]);let previousToken=actualTokenIndex>0?allLexemes[actualTokenIndex-1]:void 0;if(this.isAfterDot(sql,cursorPosition,previousToken))return{suggestTables:!1,suggestColumns:!0,suggestKeywords:!1,tableScope:this.findPrecedingIdentifier(sql,cursorPosition,allLexemes),currentToken:actualCurrentToken,previousToken};if(actualCurrentToken){let currentValue=actualCurrentToken.value.toLowerCase(),keywordRequirement=this.requiresSpecificKeywords(currentValue);if(keywordRequirement)return{suggestTables:!1,suggestColumns:!1,...keywordRequirement,currentToken:actualCurrentToken,previousToken}}let tokenValue=actualCurrentToken?.value.toLowerCase(),prevValue=previousToken?.value.toLowerCase();if(tokenValue){let patterns=this.getKeywordPatterns();if(patterns.suggestsTables.has(tokenValue))return{suggestTables:!0,suggestColumns:!1,suggestKeywords:!1,currentToken:actualCurrentToken,previousToken};if(patterns.suggestsColumns.has(tokenValue))return{suggestTables:!1,suggestColumns:!0,suggestKeywords:!1,currentToken:actualCurrentToken,previousToken}}if(prevValue){let patterns=this.getKeywordPatterns(),keywordRequirement=this.requiresSpecificKeywords(prevValue);if(keywordRequirement&&tokenValue!=="join"&&tokenValue!=="outer"&&tokenValue!=="by")return{suggestTables:!1,suggestColumns:!1,...keywordRequirement,currentToken:actualCurrentToken,previousToken};if(patterns.suggestsTables.has(prevValue))return{suggestTables:!0,suggestColumns:!1,suggestKeywords:!1,currentToken:actualCurrentToken,previousToken};if(patterns.suggestsColumns.has(prevValue))return{suggestTables:!1,suggestColumns:!0,suggestKeywords:!1,currentToken:actualCurrentToken,previousToken}}return{suggestTables:!1,suggestColumns:!1,suggestKeywords:!0,currentToken:actualCurrentToken,previousToken}}catch{return{suggestTables:!1,suggestColumns:!1,suggestKeywords:!1}}}static analyzeIntelliSenseAt(sql,position){let charOffset=TextPositionUtils.lineColumnToCharOffset(sql,position);return charOffset===-1?{suggestTables:!1,suggestColumns:!1,suggestKeywords:!1}:this.analyzeIntelliSense(sql,charOffset)}static isAfterDot(sql,cursorPosition,previousToken){if(cursorPosition>0&&sql[cursorPosition-1]==="."||previousToken&&previousToken.value===".")return!0;let pos=cursorPosition-1;for(;pos>=0&&/\s/.test(sql[pos]);)pos--;return pos>=0&&sql[pos]==="."}static findPrecedingIdentifier(sql,cursorPosition,lexemes){if(this.isAfterDot(sql,cursorPosition)){let pos=cursorPosition-1;for(;pos>=0&&/\s/.test(sql[pos]);)pos--;if(pos>=0&&sql[pos]==="."){let identifierEnd=pos;for(;pos>=0&&/\s/.test(sql[pos]);)pos--;for(;pos>=0&&/[a-zA-Z0-9_]/.test(sql[pos]);)pos--;let identifierStart=pos+1;if(identifierStart<identifierEnd)return sql.substring(identifierStart,identifierEnd)}for(let i=lexemes.length-1;i>=0;i--)if(lexemes[i].value==="."&&lexemes[i].position&&lexemes[i].position.startPosition<cursorPosition){if(i>0&&this.isIdentifier(lexemes[i-1]))return lexemes[i-1].value;break}}}static isIdentifier(lexeme){return/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(lexeme.value)}};var ScopeResolver=class{static resolve(sql,cursorPosition){return this.createEmptyScope()}static resolveAt(sql,position){let charOffset=TextPositionUtils.lineColumnToCharOffset(sql,position);return charOffset===-1?this.createEmptyScope():this.resolve(sql,charOffset)}static getColumnsForTable(sql,cursorPosition,tableOrAlias){let scope=this.resolve(sql,cursorPosition),table=scope.availableTables.find(t=>t.name===tableOrAlias||t.alias===tableOrAlias);return table?scope.visibleColumns.filter(col=>col.tableName===table.name||table.alias&&col.tableAlias===table.alias):[]}static analyzeScopeFromQuery(query){let scope={availableTables:[],availableCTEs:[],subqueryLevel:0,visibleColumns:[],currentQuery:query,parentQueries:[]};if(query instanceof SimpleSelectQuery)scope.availableCTEs=this.collectCTEs(query),scope.availableTables=this.collectTablesFromQuery(query),scope.visibleColumns=this.collectVisibleColumns(scope.availableTables,scope.availableCTEs);else if(query instanceof BinarySelectQuery){let leftScope=this.analyzeScopeFromQuery(query.left),rightScope=this.analyzeScopeFromQuery(query.right);scope.availableTables=[...leftScope.availableTables,...rightScope.availableTables],scope.availableCTEs=[...leftScope.availableCTEs,...rightScope.availableCTEs],scope.visibleColumns=[...leftScope.visibleColumns,...rightScope.visibleColumns]}return scope}static collectCTEs(query){let ctes=[];if(query.withClause){let collectedCTEs=new CTECollector().collect(query);for(let cte of collectedCTEs)ctes.push({name:cte.getSourceAliasName(),query:cte.query,columns:this.extractCTEColumns(cte.query),materialized:cte.materialized||!1})}return ctes}static collectTablesFromQuery(query){let tables=[];if(query.fromClause){let fromTables=this.extractTablesFromFromClause(query.fromClause);tables.push(...fromTables)}return tables}static extractTablesFromFromClause(fromClause){let tables=[];if(fromClause.source.datasource instanceof TableSource){let table={name:this.extractTableName(fromClause.source.datasource.qualifiedName),alias:fromClause.source.aliasExpression?.table.name,schema:this.extractSchemaName(fromClause.source.datasource.qualifiedName),fullName:this.getQualifiedNameString(fromClause.source.datasource.qualifiedName),sourceType:"table"};tables.push(table)}else if(fromClause.source.datasource instanceof SubQuerySource){let table={name:fromClause.source.aliasExpression?.table.name||"subquery",alias:fromClause.source.aliasExpression?.table.name,fullName:fromClause.source.aliasExpression?.table.name||"subquery",sourceType:"subquery",originalQuery:fromClause.source.datasource.query};tables.push(table)}if(fromClause.joins)for(let join of fromClause.joins){let joinTables=this.extractTablesFromJoin(join);tables.push(...joinTables)}return tables}static extractTablesFromJoin(join){let tables=[];if(join.source.datasource instanceof TableSource){let table={name:this.extractTableName(join.source.datasource.qualifiedName),alias:join.source.aliasExpression?.table.name,schema:this.extractSchemaName(join.source.datasource.qualifiedName),fullName:this.getQualifiedNameString(join.source.datasource.qualifiedName),sourceType:"table"};tables.push(table)}else if(join.source.datasource instanceof SubQuerySource){let table={name:join.source.aliasExpression?.table.name||"subquery",alias:join.source.aliasExpression?.table.name,fullName:join.source.aliasExpression?.table.name||"subquery",sourceType:"subquery",originalQuery:join.source.datasource.query};tables.push(table)}return tables}static getQualifiedNameString(qualifiedName){return qualifiedName.toString()}static extractTableName(qualifiedName){let parts=this.getQualifiedNameString(qualifiedName).split(".");return parts[parts.length-1]}static extractSchemaName(qualifiedName){let parts=this.getQualifiedNameString(qualifiedName).split(".");return parts.length>1?parts[parts.length-2]:void 0}static extractCTEColumns(query){try{if(this.isSelectQuery(query))return query instanceof SimpleSelectQuery&&query.selectClause?this.extractColumnsFromItems(query.selectClause.items):void 0;if((query instanceof InsertQuery||query instanceof UpdateQuery||query instanceof DeleteQuery)&&query.returningClause)return this.extractColumnsFromItems(query.returningClause.items)}catch{}}static extractColumnsFromItems(items){let columns=[];for(let item of items){if(item.identifier){columns.push(item.identifier.name);continue}let columnName=this.extractColumnNameFromExpression(item.value);columnName&&columns.push(columnName)}return columns.length>0?columns:void 0}static extractColumnNameFromExpression(expression){if(expression instanceof ColumnReference)return expression.column.name;if(expression&&typeof expression=="object"&&"value"in expression)return expression.value}static isSelectQuery(query){return"__selectQueryType"in query&&query.__selectQueryType==="SelectQuery"}static collectVisibleColumns(tables,ctes){let columns=[];for(let cte of ctes)if(cte.columns)for(let columnName of cte.columns)columns.push({name:columnName,tableName:cte.name,fullReference:`${cte.name}.${columnName}`});for(let table of tables)table.sourceType==="table"&&columns.push({name:"*",tableName:table.name,tableAlias:table.alias,fullReference:`${table.alias||table.name}.*`});return columns}static createEmptyScope(){return{availableTables:[],availableCTEs:[],subqueryLevel:0,visibleColumns:[],parentQueries:[]}}};var PositionAwareParser=class{static parseToPosition(sql,cursorPosition,options={}){let charPosition=typeof cursorPosition=="number"?cursorPosition:TextPositionUtils.lineColumnToCharOffset(sql,cursorPosition);if(charPosition===-1)return{success:!1,error:"Invalid cursor position",stoppedAtCursor:!1};try{let normalResult=this.tryNormalParse(sql,charPosition,options);return normalResult.success?normalResult:options.errorRecovery?this.tryErrorRecovery(sql,charPosition,options):normalResult}catch(error){return{success:!1,error:error instanceof Error?error.message:String(error),stoppedAtCursor:!1}}}static parseCurrentQuery(sql,cursorPosition,options={}){let charPosition=typeof cursorPosition=="number"?cursorPosition:TextPositionUtils.lineColumnToCharOffset(sql,cursorPosition);if(charPosition===-1)return{success:!1,error:"Invalid cursor position",stoppedAtCursor:!1};let queryBoundaries=this.findQueryBoundaries(sql),currentQuery=this.findQueryAtPosition(queryBoundaries,charPosition);if(!currentQuery)return{success:!1,error:"No query found at cursor position",stoppedAtCursor:!1};let relativePosition=charPosition-currentQuery.start,querySQL=sql.substring(currentQuery.start,currentQuery.end);return this.parseToPosition(querySQL,relativePosition,options)}static tryNormalParse(sql,cursorPosition,options){if(cursorPosition<0||cursorPosition>sql.length)return{success:!1,error:"Invalid cursor position",stoppedAtCursor:!1};let trimmedSql=sql.trim(),appearsIncomplete=[".",",","SELECT","FROM","WHERE","JOIN","ON","GROUP BY","ORDER BY"].some(pattern=>trimmedSql.toLowerCase().endsWith(pattern.toLowerCase())),analysisResult=SelectQueryParser.analyze(sql);if(!analysisResult.success||appearsIncomplete)return{...analysisResult,success:!1};let allTokens=this.getAllTokens(sql),cursorToken=this.findTokenAtPosition(allTokens,cursorPosition),beforeCursor=this.findTokenBeforePosition(allTokens,cursorPosition);return{...analysisResult,parsedTokens:allTokens,tokenBeforeCursor:beforeCursor,stoppedAtCursor:cursorPosition<sql.length,recoveryAttempts:0}}static tryErrorRecovery(sql,cursorPosition,options){let maxAttempts=options.maxRecoveryAttempts||5,attempts=0,strategies=[()=>this.recoverWithTokenInsertion(sql,cursorPosition,options),()=>this.recoverWithTruncation(sql,cursorPosition,options),()=>this.recoverWithCompletion(sql,cursorPosition,options),()=>this.recoverWithMinimalSQL(sql,cursorPosition,options)];for(let strategy of strategies){if(attempts>=maxAttempts)break;attempts++;try{let result=strategy();if(result.success)return result.recoveryAttempts=attempts,result}catch{continue}}return{success:!1,error:"All error recovery attempts failed",recoveryAttempts:attempts,stoppedAtCursor:!1}}static recoverWithTokenInsertion(sql,cursorPosition,options){if(!options.insertMissingTokens)throw new Error("Token insertion disabled");let fixes=[{pattern:/SELECT\s*$/i,replacement:"SELECT 1 "},{pattern:/FROM\s*$/i,replacement:"FROM dual "},{pattern:/WHERE\s*$/i,replacement:"WHERE 1=1 "},{pattern:/JOIN\s*$/i,replacement:"JOIN dual ON 1=1 "},{pattern:/ON\s*$/i,replacement:"ON 1=1 "},{pattern:/GROUP\s+BY\s*$/i,replacement:"GROUP BY 1 "},{pattern:/ORDER\s+BY\s*$/i,replacement:"ORDER BY 1 "}],fixedSQL=sql;for(let fix of fixes)if(fix.pattern.test(sql)){fixedSQL=sql.replace(fix.pattern,fix.replacement);break}if(fixedSQL===sql)throw new Error("No applicable token insertion found");let result=SelectQueryParser.analyze(fixedSQL),tokens=this.getAllTokens(sql);return{...result,parsedTokens:tokens,tokenBeforeCursor:this.findTokenBeforePosition(tokens,cursorPosition),stoppedAtCursor:!0,recoveryAttempts:1}}static recoverWithTruncation(sql,cursorPosition,options){let truncated=sql.substring(0,cursorPosition),completions=[""," 1"," FROM dual"," WHERE 1=1"];for(let completion of completions)try{let testSQL=truncated+completion,result=SelectQueryParser.analyze(testSQL);if(result.success){let tokens=this.getAllTokens(sql);return{...result,parsedTokens:tokens.filter(t=>t.position&&t.position.startPosition<=cursorPosition),tokenBeforeCursor:this.findTokenBeforePosition(tokens,cursorPosition),stoppedAtCursor:!0,recoveryAttempts:1}}}catch{continue}throw new Error("Truncation recovery failed")}static recoverWithCompletion(sql,cursorPosition,options){let beforeCursor=sql.substring(0,cursorPosition),afterCursor=sql.substring(cursorPosition),completions=[{pattern:/\.\s*$/,completion:"id"},{pattern:/\w+\s*$/,completion:""},{pattern:/,\s*$/,completion:"1"},{pattern:/\(\s*$/,completion:"1)"}];for(let comp of completions)if(comp.pattern.test(beforeCursor)){let testSQL=beforeCursor+comp.completion+afterCursor;try{let result=SelectQueryParser.analyze(testSQL);if(result.success){let tokens=this.getAllTokens(sql);return{...result,parsedTokens:tokens,tokenBeforeCursor:this.findTokenBeforePosition(tokens,cursorPosition),stoppedAtCursor:!0,recoveryAttempts:1}}}catch{continue}}throw new Error("Completion recovery failed")}static recoverWithMinimalSQL(sql,cursorPosition,options){let minimalSQL="SELECT 1 FROM dual WHERE 1=1";try{let result=SelectQueryParser.analyze(minimalSQL),tokens=this.getAllTokens(sql);return{success:!0,query:result.query,parsedTokens:tokens.filter(t=>t.position&&t.position.startPosition<=cursorPosition),tokenBeforeCursor:this.findTokenBeforePosition(tokens,cursorPosition),stoppedAtCursor:!0,partialAST:result.query,recoveryAttempts:1}}catch{throw new Error("Minimal SQL recovery failed")}}static getAllTokens(sql){try{return LexemeCursor.getAllLexemesWithPosition(sql)}catch{return[]}}static findTokenAtPosition(tokens,position){return tokens.find(token=>token.position&&position>=token.position.startPosition&&position<token.position.endPosition)}static findTokenBeforePosition(tokens,position){let beforeToken;for(let token of tokens)if(token.position)if(token.position.endPosition<=position)beforeToken=token;else{if(token.position.startPosition<position)break;break}return beforeToken}static findQueryBoundaries(sql){let boundaries=[],currentStart=0,inString=!1,stringChar="",inComment=!1;for(let i=0;i<sql.length;i++){let char=sql[i],nextChar=i<sql.length-1?sql[i+1]:"";if(!inComment&&(char==="'"||char==='"')){inString?char===stringChar&&(inString=!1,stringChar=""):(inString=!0,stringChar=char);continue}if(!inString&&char==="-"&&nextChar==="-"){inComment=!0,i++;continue}if(inComment&&char===`
|
|
93
|
-
`){inComment=!1;continue}!inString&&!inComment&&char===";"&&(boundaries.push({start:currentStart,end:i}),currentStart=i+1)}return currentStart<sql.length&&boundaries.push({start:currentStart,end:sql.length}),boundaries}static findQueryAtPosition(boundaries,position){return boundaries.find(boundary=>position>=boundary.start&&position<=boundary.end)}};function parseToPosition(sql,cursorPosition,options={}){return PositionAwareParser.parseToPosition(sql,cursorPosition,options)}function getCursorContext(sql,cursorPosition){return typeof cursorPosition=="number"?CursorContextAnalyzer.analyzeIntelliSense(sql,cursorPosition):CursorContextAnalyzer.analyzeIntelliSenseAt(sql,cursorPosition)}function resolveScope(sql,cursorPosition){return typeof cursorPosition=="number"?ScopeResolver.resolve(sql,cursorPosition):ScopeResolver.resolveAt(sql,cursorPosition)}function splitQueries(sql){return MultiQuerySplitter.split(sql)}function getIntelliSenseInfo(sql,cursorPosition,options={}){let charPos=typeof cursorPosition=="number"?cursorPosition:TextPositionUtils.lineColumnToCharOffset(sql,cursorPosition);if(charPos===-1)return;let activeQuery=splitQueries(sql).getActive(charPos);if(!activeQuery)return;let relativePosition=charPos-activeQuery.start,querySQL=activeQuery.sql,context=getCursorContext(querySQL,relativePosition),scope=resolveScope(querySQL,relativePosition),parseResult=parseToPosition(querySQL,relativePosition,options);return{context,scope,parseResult,currentQuery:querySQL,relativePosition}}function getCompletionSuggestions(sql,cursorPosition){let charPos=typeof cursorPosition=="number"?cursorPosition:TextPositionUtils.lineColumnToCharOffset(sql,cursorPosition);if(charPos===-1)return[];let intelliSenseContext=CursorContextAnalyzer.analyzeIntelliSense(sql,charPos),scope=resolveScope(sql,cursorPosition),suggestions=[];return intelliSenseContext.suggestKeywords&&(intelliSenseContext.requiredKeywords?intelliSenseContext.requiredKeywords.forEach(keyword=>{suggestions.push({type:"keyword",value:keyword,detail:`Required keyword: ${keyword}`})}):getGeneralKeywords(intelliSenseContext).forEach(keyword=>{suggestions.push({type:"keyword",value:keyword.value,detail:keyword.detail})})),intelliSenseContext.suggestTables&&(scope.availableTables.forEach(table=>{suggestions.push({type:"table",value:table.alias||table.name,detail:`Table: ${table.fullName}`,documentation:`Available table${table.alias?` (alias: ${table.alias})`:""}`})}),scope.availableCTEs.forEach(cte=>{suggestions.push({type:"cte",value:cte.name,detail:`CTE: ${cte.name}`,documentation:`Common Table Expression${cte.columns?` with columns: ${cte.columns.join(", ")}`:""}`})})),intelliSenseContext.suggestColumns&&(intelliSenseContext.tableScope?scope.visibleColumns.filter(col=>col.tableName===intelliSenseContext.tableScope||col.tableAlias===intelliSenseContext.tableScope).forEach(col=>{suggestions.push({type:"column",value:col.name,detail:`Column: ${col.fullReference}`,documentation:`Column from ${col.tableName}${col.type?` (${col.type})`:""}`})}):scope.visibleColumns.forEach(col=>{suggestions.push({type:"column",value:col.name==="*"?"*":`${col.tableAlias||col.tableName}.${col.name}`,detail:`Column: ${col.fullReference}`,documentation:`Column from ${col.tableName}`})})),suggestions}function getGeneralKeywords(context){let prevToken=context.previousToken?.value?.toLowerCase(),currentToken=context.currentToken?.value?.toLowerCase();return prevToken==="select"||currentToken==="select"?[{value:"DISTINCT",detail:"Remove duplicate rows"},{value:"COUNT",detail:"Aggregate function"},{value:"SUM",detail:"Aggregate function"},{value:"AVG",detail:"Aggregate function"},{value:"MAX",detail:"Aggregate function"},{value:"MIN",detail:"Aggregate function"}]:prevToken==="from"||currentToken==="from"?[{value:"JOIN",detail:"Inner join tables"},{value:"LEFT JOIN",detail:"Left outer join"},{value:"RIGHT JOIN",detail:"Right outer join"},{value:"FULL JOIN",detail:"Full outer join"},{value:"WHERE",detail:"Filter conditions"},{value:"GROUP BY",detail:"Group results"},{value:"ORDER BY",detail:"Sort results"}]:["where","having","on"].includes(prevToken||"")||["where","having","on"].includes(currentToken||"")?[{value:"AND",detail:"Logical AND operator"},{value:"OR",detail:"Logical OR operator"},{value:"NOT",detail:"Logical NOT operator"},{value:"IN",detail:"Match any value in list"},{value:"LIKE",detail:"Pattern matching"},{value:"BETWEEN",detail:"Range comparison"}]:[{value:"SELECT",detail:"Query data"},{value:"FROM",detail:"Specify table"},{value:"WHERE",detail:"Filter conditions"},{value:"JOIN",detail:"Join tables"},{value:"GROUP BY",detail:"Group results"},{value:"ORDER BY",detail:"Sort results"},{value:"LIMIT",detail:"Limit results"}]}export{AliasRenamer,AlterSequenceStatement,AlterTableAddColumn,AlterTableAddConstraint,AlterTableAlterColumnDefault,AlterTableDropColumn,AlterTableDropConstraint,AlterTableParser,AlterTableStatement,AnalyzeStatement,ArrayExpression,ArrayIndexExpression,ArrayQueryExpression,ArraySliceExpression,BetweenExpression,BinaryExpression,BinarySelectQuery,CTECollector,CTEComposer,CTEDependencyAnalyzer,CTEDisabler,CTENormalizer,CTENotFoundError,CTEQueryDecomposer,CTERegionDetector,CTERenamer,CTETableReferenceCollector,CaseExpression,CaseKeyValuePair,CastExpression,CheckpointStatement,CheckpointStatementParser,ClusterStatement,ClusterStatementParser,ColumnConstraintDefinition,ColumnReference,ColumnReferenceCollector,CommentEditor,CommentOnParser,CommentOnStatement,CommonTable,CreateIndexParser,CreateIndexStatement,CreateSchemaStatement,CreateSequenceStatement,CreateTableParser,CreateTableQuery,CursorContextAnalyzer,DDLDiffGenerator,DDLGeneralizer,DDLToFixtureConverter,DeleteClause,DeleteQuery,DeleteQueryParser,DeleteResultSelectConverter,Distinct,DistinctOn,DropConstraintParser,DropConstraintStatement,DropIndexParser,DropIndexStatement,DropSchemaStatement,DropTableParser,DropTableStatement,DuplicateCTEError,DuplicateDetectionMode,DynamicQueryBuilder,ExplainOption,ExplainStatement,FetchClause,FetchExpression,FetchType,FetchUnit,FilterableItem,FilterableItemCollector,FixtureCteBuilder,ForClause,Formatter,FromClause,FunctionCall,FunctionSource,GroupByClause,HavingClause,IdentifierString,IndexColumnDefinition,InlineQuery,InsertClause,InsertQuery,InsertQueryParser,InsertQuerySelectValuesConverter,InsertResultSelectConverter,InvalidCTENameError,JoinClause,JoinOnClause,JoinUsingClause,JsonMappingConverter,JsonSchemaValidator,LexemeCursor,LimitClause,LiteralValue,LockMode,MergeAction,MergeDeleteAction,MergeDoNothingAction,MergeInsertAction,MergeQuery,MergeQueryParser,MergeResultSelectConverter,MergeUpdateAction,MergeWhenClause,MultiQuerySplitter,MultiQueryUtils,NullsSortDirection,OffsetClause,OrderByClause,OrderByItem,OriginalFormatRestorer,ParameterExpression,ParenExpression,ParenSource,PartitionByClause,PositionAwareParser,PostgresJsonQueryBuilder,QualifiedName,QueryBuilder,QueryFlowDiagramGenerator,RawString,ReferenceDefinition,ReindexStatement,ReindexStatementParser,ReturningClause,SchemaCollector,SchemaManager,ScopeResolver,SelectClause,SelectItem,SelectQueryParser,SelectResultSelectConverter,SelectValueCollector,SelectableColumnCollector,SetClause,SetClauseItem,SimpleSelectQuery,SimulatedSelectConverter,SmartRenamer,SortDirection,SourceAliasExpression,SourceExpression,SqlComponent,SqlDialectConfiguration,SqlFormatter,SqlIdentifierRenamer,SqlPaginationInjector,SqlParamInjector,SqlParser,SqlSchemaValidator,SqlSortInjector,StringSpecifierExpression,SubQuerySource,SwitchCaseArgument,TableColumnDefinition,TableConstraintDefinition,TableSchema,TableSource,TableSourceCollector,TokenType,TupleExpression,TypeTransformationPostProcessor,TypeTransformers,TypeValue,UnaryExpression,UpdateClause,UpdateQuery,UpdateQueryParser,UpdateResultSelectConverter,UpstreamSelectQueryFinder,UsingClause,VALID_PRESETS,VacuumStatement,VacuumStatementParser,ValueList,ValuesQuery,WhereClause,WindowFrameBound,WindowFrameBoundStatic,WindowFrameBoundaryValue,WindowFrameClause,WindowFrameExpression,WindowFrameSpec,WindowFrameType,WindowsClause,WithClause,WithClauseParser,convertColumnsToLegacy,convertModelDrivenMapping,convertToLegacyJsonMapping,createJsonMappingFromSchema,createSchemaManager,createTableColumnResolver,createTableDefinitionFromCreateTableQuery,createTableDefinitionRegistryFromCreateTableQueries,createTableDefinitionRegistryFromSchema,extractTypeProtection,getCompletionSuggestions,getCursorContext,getIntelliSenseInfo,isLegacyFormat,isModelDrivenFormat,isUnifiedFormat,normalizeTableName,optimizeUnusedCtes,optimizeUnusedCtesToFixedPoint,optimizeUnusedLeftJoins,optimizeUnusedLeftJoinsToFixedPoint,parseToPosition,processJsonMapping,pruneOptionalConditionBranches,resolveScope,splitQueries,tableNameVariants,toLegacyMapping,transformDatabaseResult,unifyJsonMapping,validateModelDrivenMapping};
|
|
92
|
+
`);throw new Error(errorMessage)}}static extractStructureFromSample(sampleObject){if(sampleObject==null)return"primitive";if(Array.isArray(sampleObject))return sampleObject.length===0?[]:[this.extractStructureFromSample(sampleObject[0])];if(typeof sampleObject=="object"){let structure={};return Object.keys(sampleObject).forEach(key=>{structure[key]=this.extractStructureFromSample(sampleObject[key])}),structure}return"primitive"}};var SchemaManager=class{constructor(schemas){this.schemas=schemas,this.validateSchemas()}validateSchemas(){let tableNames=Object.keys(this.schemas),errors=[];if(Object.entries(this.schemas).forEach(([tableName,table])=>{Object.entries(table.columns).filter(([_,col])=>col.isPrimaryKey).map(([name,_])=>name).length===0&&errors.push(`Table '${tableName}' has no primary key defined`),table.relationships?.forEach(rel=>{tableNames.includes(rel.table)||errors.push(`Table '${tableName}' references unknown table '${rel.table}' in relationship`)})}),errors.length>0)throw new Error(`Schema validation failed:\\n${errors.join("\\n")}`)}getTableColumns(tableName){let table=this.schemas[tableName];return table?Object.keys(table.columns):[]}createTableColumnResolver(){return tableName=>this.getTableColumns(tableName)}createJsonMapping(rootTableName){let rootTable=this.schemas[rootTableName];if(!rootTable)throw new Error(`Table '${rootTableName}' not found in schema registry`);let rootColumns={};Object.entries(rootTable.columns).forEach(([columnName,column])=>{rootColumns[columnName]=column.jsonAlias||column.name});let nestedEntities=[];return rootTable.relationships?.forEach(rel=>{let relatedTable=this.schemas[rel.table];if(!relatedTable)throw new Error(`Related table '${rel.table}' not found in schema registry`);let relatedColumns={};Object.entries(relatedTable.columns).forEach(([columnName,column])=>{relatedColumns[columnName]=column.jsonAlias||column.name});let relationshipType=rel.type;nestedEntities.push({id:rel.propertyName,name:relatedTable.displayName||rel.table,parentId:rootTableName,propertyName:rel.propertyName,relationshipType,columns:relatedColumns})}),{rootName:rootTableName,rootEntity:{id:rootTableName,name:rootTable.displayName||rootTableName,columns:rootColumns},nestedEntities,resultFormat:"single"}}getTableNames(){return Object.keys(this.schemas)}getTable(tableName){return this.schemas[tableName]}getPrimaryKey(tableName){let table=this.schemas[tableName];if(!table)return;let primaryKeyEntry=Object.entries(table.columns).find(([_,col])=>col.isPrimaryKey);return primaryKeyEntry?primaryKeyEntry[0]:void 0}getForeignKeys(tableName){let table=this.schemas[tableName];if(!table)return[];let foreignKeys=[];return Object.entries(table.columns).forEach(([columnName,column])=>{column.foreignKey&&foreignKeys.push({column:columnName,referencedTable:column.foreignKey.table,referencedColumn:column.foreignKey.column})}),foreignKeys}};function createSchemaManager(schemas){return new SchemaManager(schemas)}function createTableColumnResolver(schemas){return new SchemaManager(schemas).createTableColumnResolver()}function createJsonMappingFromSchema(schemas,rootTableName){return new SchemaManager(schemas).createJsonMapping(rootTableName)}function buildRelationGraphFromCreateTableQueries(queries){let relations=[],byChildTable=new Map,byParentTable=new Map,tableNames=new Set,seen=new Set;for(let query of queries){let childTable=normalizeRelationTableName(buildQualifiedName(query.namespaces,query.tableName.name));tableNames.add(childTable);for(let column of query.columns)for(let constraint of column.constraints){if(constraint.kind!=="references"||!constraint.reference)continue;let edge=createEdge({childTable,parentTable:normalizeRelationTableName(constraint.reference.targetTable.toString()),childColumns:[column.name.name],parentColumns:constraint.reference.columns?.map(item=>item.name)??[],constraintKind:"column-reference",constraintName:constraint.constraintName?.name??null,evidenceKind:"column-reference",confidence:"confirmed"});addEdge(relations,byChildTable,byParentTable,seen,tableNames,edge)}for(let constraint of query.tableConstraints){if(constraint.kind!=="foreign-key"||!constraint.reference)continue;let edge=createEdge({childTable,parentTable:normalizeRelationTableName(constraint.reference.targetTable.toString()),childColumns:constraint.columns?.map(item=>item.name)??[],parentColumns:constraint.reference.columns?.map(item=>item.name)??[],constraintKind:"table-foreign-key",constraintName:constraint.constraintName?.name??null,evidenceKind:"table-foreign-key",confidence:"confirmed"});addEdge(relations,byChildTable,byParentTable,seen,tableNames,edge)}}return{relations,byChildTable,byParentTable,tableNames}}function getOutgoingRelations(graph,childTable){return[...graph.byChildTable.get(normalizeRelationTableName(childTable))??[]]}function getIncomingRelations(graph,parentTable){return[...graph.byParentTable.get(normalizeRelationTableName(parentTable))??[]]}function addEdge(relations,byChildTable,byParentTable,seen,tableNames,edge){tableNames.add(edge.childTable),tableNames.add(edge.parentTable);let signature=[edge.childTable,edge.parentTable,edge.childColumns.join(","),edge.parentColumns.join(","),edge.constraintKind].join("|");seen.has(signature)||(seen.add(signature),relations.push(edge),pushIndexedEdge(byChildTable,edge.childTable,edge),pushIndexedEdge(byParentTable,edge.parentTable,edge))}function pushIndexedEdge(index,key,edge){let bucket=index.get(key)??[];bucket.push(edge),index.set(key,bucket)}function createEdge(params){return{childTable:params.childTable,parentTable:params.parentTable,childColumns:[...params.childColumns],parentColumns:[...params.parentColumns],constraintKind:params.constraintKind,constraintName:params.constraintName,evidenceKind:params.evidenceKind,confidence:params.confidence,isSelfReference:params.childTable===params.parentTable}}function buildQualifiedName(namespaces,name){return[...namespaces??[],name].join(".")}function normalizeRelationTableName(tableName){return normalizeTableName(tableName)}function getQualifiedNameText(value){return normalizeRelationTableName(value.toString())}var KeywordCache=class{static{this.joinSuggestionCache=new Map}static{this.commandSuggestionCache=new Map}static{this.initialized=!1}static initialize(){if(this.initialized)return;let joinPatterns=[["join"],["inner","join"],["cross","join"],["left","join"],["left","outer","join"],["right","join"],["right","outer","join"],["full","join"],["full","outer","join"],["natural","join"],["natural","inner","join"],["natural","left","join"],["natural","left","outer","join"],["natural","right","join"],["natural","right","outer","join"],["natural","full","join"],["natural","full","outer","join"],["lateral","join"],["lateral","inner","join"],["lateral","left","join"],["lateral","left","outer","join"]],suggestionMap=new Map,completePhrases=new Set;joinPatterns.forEach(pattern=>{pattern.length>1&&completePhrases.add(pattern.slice(1).join(" ").toUpperCase())}),joinPatterns.forEach(pattern=>{for(let i=0;i<pattern.length-1;i++){let prefix=pattern[i];suggestionMap.has(prefix)||suggestionMap.set(prefix,new Set),joinPatterns.forEach(candidatePattern=>{if(candidatePattern.length>i+1&&candidatePattern[i]===prefix){let completePhrase=candidatePattern.slice(i+1).join(" ").toUpperCase();suggestionMap.get(prefix).add(completePhrase)}})}}),suggestionMap.forEach((suggestions,keyword)=>{this.joinSuggestionCache.set(keyword.toLowerCase(),Array.from(suggestions))}),this.initializeCommandKeywords(),this.initialized=!0}static getJoinSuggestions(keyword){return this.initialize(),this.joinSuggestionCache.get(keyword.toLowerCase())||[]}static isValidJoinKeyword(keyword){return joinkeywordParser.parse(keyword,0)!==null}static getPartialSuggestions(partialKeyword){this.initialize();let partial=partialKeyword.toLowerCase(),suggestions=[];return this.joinSuggestionCache.forEach((values,key)=>{key.startsWith(partial)&&(suggestions.push(key),values.forEach(value=>{suggestions.includes(value)||suggestions.push(value)}))}),suggestions}static getAllJoinKeywords(){this.initialize();let allKeywords=new Set;return this.joinSuggestionCache.forEach((values,key)=>{allKeywords.add(key),values.forEach(value=>allKeywords.add(value))}),Array.from(allKeywords)}static initializeCommandKeywords(){let commandPatterns=this.extractCommandPatternsFromTrie(),suggestionMap=new Map;commandPatterns.forEach(pattern=>{for(let i=0;i<pattern.length-1;i++){let prefix=pattern[i],nextWord=pattern[i+1];suggestionMap.has(prefix)||suggestionMap.set(prefix,new Set),suggestionMap.get(prefix).add(nextWord)}}),suggestionMap.forEach((suggestions,keyword)=>{this.commandSuggestionCache.set(keyword.toLowerCase(),Array.from(suggestions))})}static extractCommandPatternsFromTrie(){return[["group","by"],["order","by"],["distinct","on"],["not","materialized"],["row","only"],["rows","only"],["percent","with","ties"],["key","share"],["no","key","update"],["union","all"],["intersect","all"],["except","all"],["partition","by"],["within","group"],["with","ordinality"]]}static getCommandSuggestions(keyword){return this.initialize(),this.commandSuggestionCache.get(keyword.toLowerCase())||[]}static reset(){this.joinSuggestionCache.clear(),this.commandSuggestionCache.clear(),this.initialized=!1}};var CursorContextAnalyzer=class{static{this.patternCache=null}static getKeywordPatterns(){if(this.patternCache!==null)return this.patternCache;let requiresKeywords=new Map,suggestsTables=new Set,suggestsColumns=new Set;return this.extractKeywordPatterns(requiresKeywords,suggestsTables,suggestsColumns),this.patternCache={requiresKeywords,suggestsTables,suggestsColumns},this.patternCache}static extractKeywordPatterns(requiresKeywords,suggestsTables,suggestsColumns){let tableContexts=["from","join"],columnContexts=["select","where","on","having","by"];for(let keyword of tableContexts)this.isKeywordInDictionary(keyword)&&suggestsTables.add(keyword);for(let keyword of columnContexts)this.isKeywordInDictionary(keyword)&&suggestsColumns.add(keyword);this.extractRequiresKeywordPatterns(requiresKeywords)}static isKeywordInDictionary(keyword){return KeywordCache.isValidJoinKeyword(keyword)?!0:["from","join","select","where","on","having","by","group","order"].includes(keyword)}static extractRequiresKeywordPatterns(requiresKeywords){let potentialFirstWords=["inner","left","right","full","cross","natural","outer","group","order"];for(let word of potentialFirstWords){let possibleFollowups=this.findPossibleFollowups(word);possibleFollowups.length>0&&requiresKeywords.set(word,possibleFollowups)}}static findPossibleFollowups(word){let followups=new Set;return KeywordCache.getJoinSuggestions(word.toLowerCase()).forEach(s=>followups.add(s.toUpperCase())),KeywordCache.getCommandSuggestions(word.toLowerCase()).forEach(s=>followups.add(s.toUpperCase())),Array.from(followups)}static requiresSpecificKeywords(tokenValue){let requiredKeywords=this.getKeywordPatterns().requiresKeywords.get(tokenValue);return requiredKeywords?{suggestKeywords:!0,requiredKeywords}:null}static analyzeIntelliSense(sql,cursorPosition){try{let allLexemes=LexemeCursor.getAllLexemesWithPosition(sql),actualTokenIndex=-1,actualCurrentToken;for(let i=0;i<allLexemes.length;i++){let lexeme=allLexemes[i];if(lexeme.position){if(cursorPosition>=lexeme.position.startPosition&&cursorPosition<=lexeme.position.endPosition){actualCurrentToken=lexeme,actualTokenIndex=i;break}else if(lexeme.position.startPosition>cursorPosition){actualTokenIndex=Math.max(0,i-1),actualCurrentToken=actualTokenIndex>=0?allLexemes[actualTokenIndex]:void 0;break}}}actualTokenIndex===-1&&allLexemes.length>0&&(actualTokenIndex=allLexemes.length-1,actualCurrentToken=allLexemes[actualTokenIndex]);let previousToken=actualTokenIndex>0?allLexemes[actualTokenIndex-1]:void 0;if(this.isAfterDot(sql,cursorPosition,previousToken))return{suggestTables:!1,suggestColumns:!0,suggestKeywords:!1,tableScope:this.findPrecedingIdentifier(sql,cursorPosition,allLexemes),currentToken:actualCurrentToken,previousToken};if(actualCurrentToken){let currentValue=actualCurrentToken.value.toLowerCase(),keywordRequirement=this.requiresSpecificKeywords(currentValue);if(keywordRequirement)return{suggestTables:!1,suggestColumns:!1,...keywordRequirement,currentToken:actualCurrentToken,previousToken}}let tokenValue=actualCurrentToken?.value.toLowerCase(),prevValue=previousToken?.value.toLowerCase();if(tokenValue){let patterns=this.getKeywordPatterns();if(patterns.suggestsTables.has(tokenValue))return{suggestTables:!0,suggestColumns:!1,suggestKeywords:!1,currentToken:actualCurrentToken,previousToken};if(patterns.suggestsColumns.has(tokenValue))return{suggestTables:!1,suggestColumns:!0,suggestKeywords:!1,currentToken:actualCurrentToken,previousToken}}if(prevValue){let patterns=this.getKeywordPatterns(),keywordRequirement=this.requiresSpecificKeywords(prevValue);if(keywordRequirement&&tokenValue!=="join"&&tokenValue!=="outer"&&tokenValue!=="by")return{suggestTables:!1,suggestColumns:!1,...keywordRequirement,currentToken:actualCurrentToken,previousToken};if(patterns.suggestsTables.has(prevValue))return{suggestTables:!0,suggestColumns:!1,suggestKeywords:!1,currentToken:actualCurrentToken,previousToken};if(patterns.suggestsColumns.has(prevValue))return{suggestTables:!1,suggestColumns:!0,suggestKeywords:!1,currentToken:actualCurrentToken,previousToken}}return{suggestTables:!1,suggestColumns:!1,suggestKeywords:!0,currentToken:actualCurrentToken,previousToken}}catch{return{suggestTables:!1,suggestColumns:!1,suggestKeywords:!1}}}static analyzeIntelliSenseAt(sql,position){let charOffset=TextPositionUtils.lineColumnToCharOffset(sql,position);return charOffset===-1?{suggestTables:!1,suggestColumns:!1,suggestKeywords:!1}:this.analyzeIntelliSense(sql,charOffset)}static isAfterDot(sql,cursorPosition,previousToken){if(cursorPosition>0&&sql[cursorPosition-1]==="."||previousToken&&previousToken.value===".")return!0;let pos=cursorPosition-1;for(;pos>=0&&/\s/.test(sql[pos]);)pos--;return pos>=0&&sql[pos]==="."}static findPrecedingIdentifier(sql,cursorPosition,lexemes){if(this.isAfterDot(sql,cursorPosition)){let pos=cursorPosition-1;for(;pos>=0&&/\s/.test(sql[pos]);)pos--;if(pos>=0&&sql[pos]==="."){let identifierEnd=pos;for(;pos>=0&&/\s/.test(sql[pos]);)pos--;for(;pos>=0&&/[a-zA-Z0-9_]/.test(sql[pos]);)pos--;let identifierStart=pos+1;if(identifierStart<identifierEnd)return sql.substring(identifierStart,identifierEnd)}for(let i=lexemes.length-1;i>=0;i--)if(lexemes[i].value==="."&&lexemes[i].position&&lexemes[i].position.startPosition<cursorPosition){if(i>0&&this.isIdentifier(lexemes[i-1]))return lexemes[i-1].value;break}}}static isIdentifier(lexeme){return/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(lexeme.value)}};var ScopeResolver=class{static resolve(sql,cursorPosition){return this.createEmptyScope()}static resolveAt(sql,position){let charOffset=TextPositionUtils.lineColumnToCharOffset(sql,position);return charOffset===-1?this.createEmptyScope():this.resolve(sql,charOffset)}static getColumnsForTable(sql,cursorPosition,tableOrAlias){let scope=this.resolve(sql,cursorPosition),table=scope.availableTables.find(t=>t.name===tableOrAlias||t.alias===tableOrAlias);return table?scope.visibleColumns.filter(col=>col.tableName===table.name||table.alias&&col.tableAlias===table.alias):[]}static analyzeScopeFromQuery(query){let scope={availableTables:[],availableCTEs:[],subqueryLevel:0,visibleColumns:[],currentQuery:query,parentQueries:[]};if(query instanceof SimpleSelectQuery)scope.availableCTEs=this.collectCTEs(query),scope.availableTables=this.collectTablesFromQuery(query),scope.visibleColumns=this.collectVisibleColumns(scope.availableTables,scope.availableCTEs);else if(query instanceof BinarySelectQuery){let leftScope=this.analyzeScopeFromQuery(query.left),rightScope=this.analyzeScopeFromQuery(query.right);scope.availableTables=[...leftScope.availableTables,...rightScope.availableTables],scope.availableCTEs=[...leftScope.availableCTEs,...rightScope.availableCTEs],scope.visibleColumns=[...leftScope.visibleColumns,...rightScope.visibleColumns]}return scope}static collectCTEs(query){let ctes=[];if(query.withClause){let collectedCTEs=new CTECollector().collect(query);for(let cte of collectedCTEs)ctes.push({name:cte.getSourceAliasName(),query:cte.query,columns:this.extractCTEColumns(cte.query),materialized:cte.materialized||!1})}return ctes}static collectTablesFromQuery(query){let tables=[];if(query.fromClause){let fromTables=this.extractTablesFromFromClause(query.fromClause);tables.push(...fromTables)}return tables}static extractTablesFromFromClause(fromClause){let tables=[];if(fromClause.source.datasource instanceof TableSource){let table={name:this.extractTableName(fromClause.source.datasource.qualifiedName),alias:fromClause.source.aliasExpression?.table.name,schema:this.extractSchemaName(fromClause.source.datasource.qualifiedName),fullName:this.getQualifiedNameString(fromClause.source.datasource.qualifiedName),sourceType:"table"};tables.push(table)}else if(fromClause.source.datasource instanceof SubQuerySource){let table={name:fromClause.source.aliasExpression?.table.name||"subquery",alias:fromClause.source.aliasExpression?.table.name,fullName:fromClause.source.aliasExpression?.table.name||"subquery",sourceType:"subquery",originalQuery:fromClause.source.datasource.query};tables.push(table)}if(fromClause.joins)for(let join of fromClause.joins){let joinTables=this.extractTablesFromJoin(join);tables.push(...joinTables)}return tables}static extractTablesFromJoin(join){let tables=[];if(join.source.datasource instanceof TableSource){let table={name:this.extractTableName(join.source.datasource.qualifiedName),alias:join.source.aliasExpression?.table.name,schema:this.extractSchemaName(join.source.datasource.qualifiedName),fullName:this.getQualifiedNameString(join.source.datasource.qualifiedName),sourceType:"table"};tables.push(table)}else if(join.source.datasource instanceof SubQuerySource){let table={name:join.source.aliasExpression?.table.name||"subquery",alias:join.source.aliasExpression?.table.name,fullName:join.source.aliasExpression?.table.name||"subquery",sourceType:"subquery",originalQuery:join.source.datasource.query};tables.push(table)}return tables}static getQualifiedNameString(qualifiedName){return qualifiedName.toString()}static extractTableName(qualifiedName){let parts=this.getQualifiedNameString(qualifiedName).split(".");return parts[parts.length-1]}static extractSchemaName(qualifiedName){let parts=this.getQualifiedNameString(qualifiedName).split(".");return parts.length>1?parts[parts.length-2]:void 0}static extractCTEColumns(query){try{if(this.isSelectQuery(query))return query instanceof SimpleSelectQuery&&query.selectClause?this.extractColumnsFromItems(query.selectClause.items):void 0;if((query instanceof InsertQuery||query instanceof UpdateQuery||query instanceof DeleteQuery)&&query.returningClause)return this.extractColumnsFromItems(query.returningClause.items)}catch{}}static extractColumnsFromItems(items){let columns=[];for(let item of items){if(item.identifier){columns.push(item.identifier.name);continue}let columnName=this.extractColumnNameFromExpression(item.value);columnName&&columns.push(columnName)}return columns.length>0?columns:void 0}static extractColumnNameFromExpression(expression){if(expression instanceof ColumnReference)return expression.column.name;if(expression&&typeof expression=="object"&&"value"in expression)return expression.value}static isSelectQuery(query){return"__selectQueryType"in query&&query.__selectQueryType==="SelectQuery"}static collectVisibleColumns(tables,ctes){let columns=[];for(let cte of ctes)if(cte.columns)for(let columnName of cte.columns)columns.push({name:columnName,tableName:cte.name,fullReference:`${cte.name}.${columnName}`});for(let table of tables)table.sourceType==="table"&&columns.push({name:"*",tableName:table.name,tableAlias:table.alias,fullReference:`${table.alias||table.name}.*`});return columns}static createEmptyScope(){return{availableTables:[],availableCTEs:[],subqueryLevel:0,visibleColumns:[],parentQueries:[]}}};var PositionAwareParser=class{static parseToPosition(sql,cursorPosition,options={}){let charPosition=typeof cursorPosition=="number"?cursorPosition:TextPositionUtils.lineColumnToCharOffset(sql,cursorPosition);if(charPosition===-1)return{success:!1,error:"Invalid cursor position",stoppedAtCursor:!1};try{let normalResult=this.tryNormalParse(sql,charPosition,options);return normalResult.success?normalResult:options.errorRecovery?this.tryErrorRecovery(sql,charPosition,options):normalResult}catch(error){return{success:!1,error:error instanceof Error?error.message:String(error),stoppedAtCursor:!1}}}static parseCurrentQuery(sql,cursorPosition,options={}){let charPosition=typeof cursorPosition=="number"?cursorPosition:TextPositionUtils.lineColumnToCharOffset(sql,cursorPosition);if(charPosition===-1)return{success:!1,error:"Invalid cursor position",stoppedAtCursor:!1};let queryBoundaries=this.findQueryBoundaries(sql),currentQuery=this.findQueryAtPosition(queryBoundaries,charPosition);if(!currentQuery)return{success:!1,error:"No query found at cursor position",stoppedAtCursor:!1};let relativePosition=charPosition-currentQuery.start,querySQL=sql.substring(currentQuery.start,currentQuery.end);return this.parseToPosition(querySQL,relativePosition,options)}static tryNormalParse(sql,cursorPosition,options){if(cursorPosition<0||cursorPosition>sql.length)return{success:!1,error:"Invalid cursor position",stoppedAtCursor:!1};let trimmedSql=sql.trim(),appearsIncomplete=[".",",","SELECT","FROM","WHERE","JOIN","ON","GROUP BY","ORDER BY"].some(pattern=>trimmedSql.toLowerCase().endsWith(pattern.toLowerCase())),analysisResult=SelectQueryParser.analyze(sql);if(!analysisResult.success||appearsIncomplete)return{...analysisResult,success:!1};let allTokens=this.getAllTokens(sql),cursorToken=this.findTokenAtPosition(allTokens,cursorPosition),beforeCursor=this.findTokenBeforePosition(allTokens,cursorPosition);return{...analysisResult,parsedTokens:allTokens,tokenBeforeCursor:beforeCursor,stoppedAtCursor:cursorPosition<sql.length,recoveryAttempts:0}}static tryErrorRecovery(sql,cursorPosition,options){let maxAttempts=options.maxRecoveryAttempts||5,attempts=0,strategies=[()=>this.recoverWithTokenInsertion(sql,cursorPosition,options),()=>this.recoverWithTruncation(sql,cursorPosition,options),()=>this.recoverWithCompletion(sql,cursorPosition,options),()=>this.recoverWithMinimalSQL(sql,cursorPosition,options)];for(let strategy of strategies){if(attempts>=maxAttempts)break;attempts++;try{let result=strategy();if(result.success)return result.recoveryAttempts=attempts,result}catch{continue}}return{success:!1,error:"All error recovery attempts failed",recoveryAttempts:attempts,stoppedAtCursor:!1}}static recoverWithTokenInsertion(sql,cursorPosition,options){if(!options.insertMissingTokens)throw new Error("Token insertion disabled");let fixes=[{pattern:/SELECT\s*$/i,replacement:"SELECT 1 "},{pattern:/FROM\s*$/i,replacement:"FROM dual "},{pattern:/WHERE\s*$/i,replacement:"WHERE 1=1 "},{pattern:/JOIN\s*$/i,replacement:"JOIN dual ON 1=1 "},{pattern:/ON\s*$/i,replacement:"ON 1=1 "},{pattern:/GROUP\s+BY\s*$/i,replacement:"GROUP BY 1 "},{pattern:/ORDER\s+BY\s*$/i,replacement:"ORDER BY 1 "}],fixedSQL=sql;for(let fix of fixes)if(fix.pattern.test(sql)){fixedSQL=sql.replace(fix.pattern,fix.replacement);break}if(fixedSQL===sql)throw new Error("No applicable token insertion found");let result=SelectQueryParser.analyze(fixedSQL),tokens=this.getAllTokens(sql);return{...result,parsedTokens:tokens,tokenBeforeCursor:this.findTokenBeforePosition(tokens,cursorPosition),stoppedAtCursor:!0,recoveryAttempts:1}}static recoverWithTruncation(sql,cursorPosition,options){let truncated=sql.substring(0,cursorPosition),completions=[""," 1"," FROM dual"," WHERE 1=1"];for(let completion of completions)try{let testSQL=truncated+completion,result=SelectQueryParser.analyze(testSQL);if(result.success){let tokens=this.getAllTokens(sql);return{...result,parsedTokens:tokens.filter(t=>t.position&&t.position.startPosition<=cursorPosition),tokenBeforeCursor:this.findTokenBeforePosition(tokens,cursorPosition),stoppedAtCursor:!0,recoveryAttempts:1}}}catch{continue}throw new Error("Truncation recovery failed")}static recoverWithCompletion(sql,cursorPosition,options){let beforeCursor=sql.substring(0,cursorPosition),afterCursor=sql.substring(cursorPosition),completions=[{pattern:/\.\s*$/,completion:"id"},{pattern:/\w+\s*$/,completion:""},{pattern:/,\s*$/,completion:"1"},{pattern:/\(\s*$/,completion:"1)"}];for(let comp of completions)if(comp.pattern.test(beforeCursor)){let testSQL=beforeCursor+comp.completion+afterCursor;try{let result=SelectQueryParser.analyze(testSQL);if(result.success){let tokens=this.getAllTokens(sql);return{...result,parsedTokens:tokens,tokenBeforeCursor:this.findTokenBeforePosition(tokens,cursorPosition),stoppedAtCursor:!0,recoveryAttempts:1}}}catch{continue}}throw new Error("Completion recovery failed")}static recoverWithMinimalSQL(sql,cursorPosition,options){let minimalSQL="SELECT 1 FROM dual WHERE 1=1";try{let result=SelectQueryParser.analyze(minimalSQL),tokens=this.getAllTokens(sql);return{success:!0,query:result.query,parsedTokens:tokens.filter(t=>t.position&&t.position.startPosition<=cursorPosition),tokenBeforeCursor:this.findTokenBeforePosition(tokens,cursorPosition),stoppedAtCursor:!0,partialAST:result.query,recoveryAttempts:1}}catch{throw new Error("Minimal SQL recovery failed")}}static getAllTokens(sql){try{return LexemeCursor.getAllLexemesWithPosition(sql)}catch{return[]}}static findTokenAtPosition(tokens,position){return tokens.find(token=>token.position&&position>=token.position.startPosition&&position<token.position.endPosition)}static findTokenBeforePosition(tokens,position){let beforeToken;for(let token of tokens)if(token.position)if(token.position.endPosition<=position)beforeToken=token;else{if(token.position.startPosition<position)break;break}return beforeToken}static findQueryBoundaries(sql){let boundaries=[],currentStart=0,inString=!1,stringChar="",inComment=!1;for(let i=0;i<sql.length;i++){let char=sql[i],nextChar=i<sql.length-1?sql[i+1]:"";if(!inComment&&(char==="'"||char==='"')){inString?char===stringChar&&(inString=!1,stringChar=""):(inString=!0,stringChar=char);continue}if(!inString&&char==="-"&&nextChar==="-"){inComment=!0,i++;continue}if(inComment&&char===`
|
|
93
|
+
`){inComment=!1;continue}!inString&&!inComment&&char===";"&&(boundaries.push({start:currentStart,end:i}),currentStart=i+1)}return currentStart<sql.length&&boundaries.push({start:currentStart,end:sql.length}),boundaries}static findQueryAtPosition(boundaries,position){return boundaries.find(boundary=>position>=boundary.start&&position<=boundary.end)}};function parseToPosition(sql,cursorPosition,options={}){return PositionAwareParser.parseToPosition(sql,cursorPosition,options)}function getCursorContext(sql,cursorPosition){return typeof cursorPosition=="number"?CursorContextAnalyzer.analyzeIntelliSense(sql,cursorPosition):CursorContextAnalyzer.analyzeIntelliSenseAt(sql,cursorPosition)}function resolveScope(sql,cursorPosition){return typeof cursorPosition=="number"?ScopeResolver.resolve(sql,cursorPosition):ScopeResolver.resolveAt(sql,cursorPosition)}function splitQueries(sql){return MultiQuerySplitter.split(sql)}function getIntelliSenseInfo(sql,cursorPosition,options={}){let charPos=typeof cursorPosition=="number"?cursorPosition:TextPositionUtils.lineColumnToCharOffset(sql,cursorPosition);if(charPos===-1)return;let activeQuery=splitQueries(sql).getActive(charPos);if(!activeQuery)return;let relativePosition=charPos-activeQuery.start,querySQL=activeQuery.sql,context=getCursorContext(querySQL,relativePosition),scope=resolveScope(querySQL,relativePosition),parseResult=parseToPosition(querySQL,relativePosition,options);return{context,scope,parseResult,currentQuery:querySQL,relativePosition}}function getCompletionSuggestions(sql,cursorPosition){let charPos=typeof cursorPosition=="number"?cursorPosition:TextPositionUtils.lineColumnToCharOffset(sql,cursorPosition);if(charPos===-1)return[];let intelliSenseContext=CursorContextAnalyzer.analyzeIntelliSense(sql,charPos),scope=resolveScope(sql,cursorPosition),suggestions=[];return intelliSenseContext.suggestKeywords&&(intelliSenseContext.requiredKeywords?intelliSenseContext.requiredKeywords.forEach(keyword=>{suggestions.push({type:"keyword",value:keyword,detail:`Required keyword: ${keyword}`})}):getGeneralKeywords(intelliSenseContext).forEach(keyword=>{suggestions.push({type:"keyword",value:keyword.value,detail:keyword.detail})})),intelliSenseContext.suggestTables&&(scope.availableTables.forEach(table=>{suggestions.push({type:"table",value:table.alias||table.name,detail:`Table: ${table.fullName}`,documentation:`Available table${table.alias?` (alias: ${table.alias})`:""}`})}),scope.availableCTEs.forEach(cte=>{suggestions.push({type:"cte",value:cte.name,detail:`CTE: ${cte.name}`,documentation:`Common Table Expression${cte.columns?` with columns: ${cte.columns.join(", ")}`:""}`})})),intelliSenseContext.suggestColumns&&(intelliSenseContext.tableScope?scope.visibleColumns.filter(col=>col.tableName===intelliSenseContext.tableScope||col.tableAlias===intelliSenseContext.tableScope).forEach(col=>{suggestions.push({type:"column",value:col.name,detail:`Column: ${col.fullReference}`,documentation:`Column from ${col.tableName}${col.type?` (${col.type})`:""}`})}):scope.visibleColumns.forEach(col=>{suggestions.push({type:"column",value:col.name==="*"?"*":`${col.tableAlias||col.tableName}.${col.name}`,detail:`Column: ${col.fullReference}`,documentation:`Column from ${col.tableName}`})})),suggestions}function getGeneralKeywords(context){let prevToken=context.previousToken?.value?.toLowerCase(),currentToken=context.currentToken?.value?.toLowerCase();return prevToken==="select"||currentToken==="select"?[{value:"DISTINCT",detail:"Remove duplicate rows"},{value:"COUNT",detail:"Aggregate function"},{value:"SUM",detail:"Aggregate function"},{value:"AVG",detail:"Aggregate function"},{value:"MAX",detail:"Aggregate function"},{value:"MIN",detail:"Aggregate function"}]:prevToken==="from"||currentToken==="from"?[{value:"JOIN",detail:"Inner join tables"},{value:"LEFT JOIN",detail:"Left outer join"},{value:"RIGHT JOIN",detail:"Right outer join"},{value:"FULL JOIN",detail:"Full outer join"},{value:"WHERE",detail:"Filter conditions"},{value:"GROUP BY",detail:"Group results"},{value:"ORDER BY",detail:"Sort results"}]:["where","having","on"].includes(prevToken||"")||["where","having","on"].includes(currentToken||"")?[{value:"AND",detail:"Logical AND operator"},{value:"OR",detail:"Logical OR operator"},{value:"NOT",detail:"Logical NOT operator"},{value:"IN",detail:"Match any value in list"},{value:"LIKE",detail:"Pattern matching"},{value:"BETWEEN",detail:"Range comparison"}]:[{value:"SELECT",detail:"Query data"},{value:"FROM",detail:"Specify table"},{value:"WHERE",detail:"Filter conditions"},{value:"JOIN",detail:"Join tables"},{value:"GROUP BY",detail:"Group results"},{value:"ORDER BY",detail:"Sort results"},{value:"LIMIT",detail:"Limit results"}]}export{AliasRenamer,AlterSequenceStatement,AlterTableAddColumn,AlterTableAddConstraint,AlterTableAlterColumnDefault,AlterTableDropColumn,AlterTableDropConstraint,AlterTableParser,AlterTableStatement,AnalyzeStatement,ArrayExpression,ArrayIndexExpression,ArrayQueryExpression,ArraySliceExpression,BetweenExpression,BinaryExpression,BinarySelectQuery,CTECollector,CTEComposer,CTEDependencyAnalyzer,CTEDisabler,CTENormalizer,CTENotFoundError,CTEQueryDecomposer,CTERegionDetector,CTERenamer,CTETableReferenceCollector,CaseExpression,CaseKeyValuePair,CastExpression,CheckpointStatement,CheckpointStatementParser,ClusterStatement,ClusterStatementParser,ColumnConstraintDefinition,ColumnReference,ColumnReferenceCollector,CommentEditor,CommentOnParser,CommentOnStatement,CommonTable,CreateIndexParser,CreateIndexStatement,CreateSchemaStatement,CreateSequenceStatement,CreateTableParser,CreateTableQuery,CursorContextAnalyzer,DDLDiffGenerator,DDLGeneralizer,DDLToFixtureConverter,DeleteClause,DeleteQuery,DeleteQueryParser,DeleteResultSelectConverter,Distinct,DistinctOn,DropConstraintParser,DropConstraintStatement,DropIndexParser,DropIndexStatement,DropSchemaStatement,DropTableParser,DropTableStatement,DuplicateCTEError,DuplicateDetectionMode,DynamicQueryBuilder,ExplainOption,ExplainStatement,FetchClause,FetchExpression,FetchType,FetchUnit,FilterableItem,FilterableItemCollector,FixtureCteBuilder,ForClause,Formatter,FromClause,FunctionCall,FunctionSource,GroupByClause,HavingClause,IdentifierString,IndexColumnDefinition,InlineQuery,InsertClause,InsertQuery,InsertQueryParser,InsertQuerySelectValuesConverter,InsertResultSelectConverter,InvalidCTENameError,JoinClause,JoinOnClause,JoinUsingClause,JsonMappingConverter,JsonSchemaValidator,LexemeCursor,LimitClause,LiteralValue,LockMode,MergeAction,MergeDeleteAction,MergeDoNothingAction,MergeInsertAction,MergeQuery,MergeQueryParser,MergeResultSelectConverter,MergeUpdateAction,MergeWhenClause,MultiQuerySplitter,MultiQueryUtils,NullsSortDirection,OffsetClause,OrderByClause,OrderByItem,OriginalFormatRestorer,ParameterExpression,ParameterHelper,ParenExpression,ParenSource,PartitionByClause,PositionAwareParser,PostgresJsonQueryBuilder,QualifiedName,QueryBuilder,QueryFlowDiagramGenerator,RawString,ReferenceDefinition,ReindexStatement,ReindexStatementParser,ReturningClause,SSSQLFilterBuilder,SchemaCollector,SchemaManager,ScopeResolver,SelectClause,SelectItem,SelectQueryParser,SelectResultSelectConverter,SelectValueCollector,SelectableColumnCollector,SetClause,SetClauseItem,SimpleSelectQuery,SimulatedSelectConverter,SmartRenamer,SortDirection,SourceAliasExpression,SourceExpression,SqlComponent,SqlDialectConfiguration,SqlFormatter,SqlIdentifierRenamer,SqlPaginationInjector,SqlParamInjector,SqlParameterBinder,SqlParser,SqlSchemaValidator,SqlSortInjector,StringSpecifierExpression,SubQuerySource,SwitchCaseArgument,TableColumnDefinition,TableConstraintDefinition,TableSchema,TableSource,TableSourceCollector,TokenType,TupleExpression,TypeTransformationPostProcessor,TypeTransformers,TypeValue,UnaryExpression,UpdateClause,UpdateQuery,UpdateQueryParser,UpdateResultSelectConverter,UpstreamSelectQueryFinder,UsingClause,VALID_PRESETS,VacuumStatement,VacuumStatementParser,ValueList,ValuesQuery,WhereClause,WindowFrameBound,WindowFrameBoundStatic,WindowFrameBoundaryValue,WindowFrameClause,WindowFrameExpression,WindowFrameSpec,WindowFrameType,WindowsClause,WithClause,WithClauseParser,buildRelationGraphFromCreateTableQueries,collectSupportedOptionalConditionBranches,convertColumnsToLegacy,convertModelDrivenMapping,convertToLegacyJsonMapping,createJsonMappingFromSchema,createSchemaManager,createTableColumnResolver,createTableDefinitionFromCreateTableQuery,createTableDefinitionRegistryFromCreateTableQueries,createTableDefinitionRegistryFromSchema,extractTypeProtection,getCompletionSuggestions,getCursorContext,getIncomingRelations,getIntelliSenseInfo,getOutgoingRelations,getQualifiedNameText,isLegacyFormat,isModelDrivenFormat,isUnifiedFormat,normalizeTableName,optimizeUnusedCtes,optimizeUnusedCtesToFixedPoint,optimizeUnusedLeftJoins,optimizeUnusedLeftJoinsToFixedPoint,parseToPosition,processJsonMapping,pruneOptionalConditionBranches,refreshSssqlQuery,resolveScope,scaffoldSssqlQuery,splitQueries,tableNameVariants,toLegacyMapping,transformDatabaseResult,unifyJsonMapping,validateModelDrivenMapping};
|
|
94
94
|
//# sourceMappingURL=index.min.js.map
|