rawsql-ts 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (537) hide show
  1. package/LICENSE +21 -0
  2. package/dist/esm/index.js +11 -0
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/index.min.js +16 -16
  5. package/dist/esm/index.min.js.map +3 -3
  6. package/dist/esm/src/index.d.ts +12 -0
  7. package/dist/esm/src/index.js +11 -0
  8. package/dist/esm/src/index.js.map +1 -1
  9. package/dist/esm/src/models/Clause.d.ts +7 -3
  10. package/dist/esm/src/models/Clause.js +17 -4
  11. package/dist/esm/src/models/Clause.js.map +1 -1
  12. package/dist/esm/src/models/DDLStatements.d.ts +14 -2
  13. package/dist/esm/src/models/DDLStatements.js +12 -0
  14. package/dist/esm/src/models/DDLStatements.js.map +1 -1
  15. package/dist/esm/src/models/InsertQuery.d.ts +1 -4
  16. package/dist/esm/src/models/InsertQuery.js +3 -5
  17. package/dist/esm/src/models/InsertQuery.js.map +1 -1
  18. package/dist/esm/src/models/SqlPrintToken.d.ts +1 -0
  19. package/dist/esm/src/models/SqlPrintToken.js +1 -0
  20. package/dist/esm/src/models/SqlPrintToken.js.map +1 -1
  21. package/dist/esm/src/models/TableDefinitionModel.d.ts +39 -0
  22. package/dist/esm/src/models/TableDefinitionModel.js +77 -0
  23. package/dist/esm/src/models/TableDefinitionModel.js.map +1 -0
  24. package/dist/esm/src/models/ValuesQuery.d.ts +2 -0
  25. package/dist/esm/src/models/ValuesQuery.js +1 -0
  26. package/dist/esm/src/models/ValuesQuery.js.map +1 -1
  27. package/dist/esm/src/parsers/AlterTableParser.js +1 -1
  28. package/dist/esm/src/parsers/AlterTableParser.js.map +1 -1
  29. package/dist/esm/src/parsers/InsertQueryParser.js +4 -1
  30. package/dist/esm/src/parsers/InsertQueryParser.js.map +1 -1
  31. package/dist/esm/src/parsers/ReturningClauseParser.js +33 -47
  32. package/dist/esm/src/parsers/ReturningClauseParser.js.map +1 -1
  33. package/dist/esm/src/parsers/SqlParser.d.ts +0 -1
  34. package/dist/esm/src/parsers/SqlParser.js +44 -58
  35. package/dist/esm/src/parsers/SqlParser.js.map +1 -1
  36. package/dist/esm/src/parsers/SqlPrintTokenParser.d.ts +1 -0
  37. package/dist/esm/src/parsers/SqlPrintTokenParser.js +23 -5
  38. package/dist/esm/src/parsers/SqlPrintTokenParser.js.map +1 -1
  39. package/dist/esm/src/tokenReaders/LiteralTokenReader.js +7 -0
  40. package/dist/esm/src/tokenReaders/LiteralTokenReader.js.map +1 -1
  41. package/dist/esm/src/transformers/DDLDiffGenerator.d.ts +14 -0
  42. package/dist/esm/src/transformers/DDLDiffGenerator.js +197 -0
  43. package/dist/esm/src/transformers/DDLDiffGenerator.js.map +1 -0
  44. package/dist/esm/src/transformers/DDLGeneralizer.d.ts +13 -0
  45. package/dist/esm/src/transformers/DDLGeneralizer.js +98 -0
  46. package/dist/esm/src/transformers/DDLGeneralizer.js.map +1 -0
  47. package/dist/esm/src/transformers/DDLToFixtureConverter.d.ts +19 -0
  48. package/dist/esm/src/transformers/DDLToFixtureConverter.js +202 -0
  49. package/dist/esm/src/transformers/DDLToFixtureConverter.js.map +1 -0
  50. package/dist/esm/src/transformers/DeleteResultSelectConverter.d.ts +53 -0
  51. package/dist/esm/src/transformers/DeleteResultSelectConverter.js +394 -0
  52. package/dist/esm/src/transformers/DeleteResultSelectConverter.js.map +1 -0
  53. package/dist/esm/src/transformers/FixtureCteBuilder.d.ts +60 -0
  54. package/dist/esm/src/transformers/FixtureCteBuilder.js +147 -0
  55. package/dist/esm/src/transformers/FixtureCteBuilder.js.map +1 -0
  56. package/dist/esm/src/transformers/InsertQuerySelectValuesConverter.js +5 -2
  57. package/dist/esm/src/transformers/InsertQuerySelectValuesConverter.js.map +1 -1
  58. package/dist/esm/src/transformers/InsertResultSelectConverter.d.ts +64 -0
  59. package/dist/esm/src/transformers/InsertResultSelectConverter.js +495 -0
  60. package/dist/esm/src/transformers/InsertResultSelectConverter.js.map +1 -0
  61. package/dist/esm/src/transformers/MergeResultSelectConverter.d.ts +38 -0
  62. package/dist/esm/src/transformers/MergeResultSelectConverter.js +306 -0
  63. package/dist/esm/src/transformers/MergeResultSelectConverter.js.map +1 -0
  64. package/dist/esm/src/transformers/QueryBuilder.d.ts +11 -0
  65. package/dist/esm/src/transformers/QueryBuilder.js +19 -3
  66. package/dist/esm/src/transformers/QueryBuilder.js.map +1 -1
  67. package/dist/esm/src/transformers/SelectResultSelectConverter.d.ts +10 -0
  68. package/dist/esm/src/transformers/SelectResultSelectConverter.js +32 -0
  69. package/dist/esm/src/transformers/SelectResultSelectConverter.js.map +1 -0
  70. package/dist/esm/src/transformers/SimulatedSelectConverter.d.ts +23 -0
  71. package/dist/esm/src/transformers/SimulatedSelectConverter.js +61 -0
  72. package/dist/esm/src/transformers/SimulatedSelectConverter.js.map +1 -0
  73. package/dist/esm/src/transformers/UpdateResultSelectConverter.d.ts +51 -0
  74. package/dist/esm/src/transformers/UpdateResultSelectConverter.js +340 -0
  75. package/dist/esm/src/transformers/UpdateResultSelectConverter.js.map +1 -0
  76. package/dist/esm/src/utils/SelectQueryWithClauseHelper.d.ts +12 -0
  77. package/dist/esm/src/utils/SelectQueryWithClauseHelper.js +43 -0
  78. package/dist/esm/src/utils/SelectQueryWithClauseHelper.js.map +1 -0
  79. package/dist/esm/src/utils/ValueComponentRewriter.d.ts +3 -0
  80. package/dist/esm/src/utils/ValueComponentRewriter.js +180 -0
  81. package/dist/esm/src/utils/ValueComponentRewriter.js.map +1 -0
  82. package/dist/esm/tsconfig.browser.tsbuildinfo +1 -1
  83. package/dist/formatters/OriginalFormatRestorer.js +139 -0
  84. package/dist/formatters/OriginalFormatRestorer.js.map +1 -0
  85. package/dist/index.js +144 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/index.min.js +17 -17
  88. package/dist/index.min.js.map +3 -3
  89. package/dist/models/BinarySelectQuery.js +198 -0
  90. package/dist/models/BinarySelectQuery.js.map +1 -0
  91. package/dist/models/CTEError.js +37 -0
  92. package/dist/models/CTEError.js.map +1 -0
  93. package/dist/models/Clause.js +535 -0
  94. package/dist/models/Clause.js.map +1 -0
  95. package/dist/models/CreateTableQuery.js +135 -0
  96. package/dist/models/CreateTableQuery.js.map +1 -0
  97. package/dist/models/DDLStatements.js +275 -0
  98. package/dist/models/DDLStatements.js.map +1 -0
  99. package/dist/models/DeleteQuery.js +20 -0
  100. package/dist/models/DeleteQuery.js.map +1 -0
  101. package/dist/models/FormattingLexeme.js +3 -0
  102. package/dist/models/FormattingLexeme.js.map +1 -0
  103. package/dist/models/HintClause.js +41 -0
  104. package/dist/models/HintClause.js.map +1 -0
  105. package/dist/models/InsertQuery.js +23 -0
  106. package/dist/models/InsertQuery.js.map +1 -0
  107. package/dist/models/KeywordTrie.js +54 -0
  108. package/dist/models/KeywordTrie.js.map +1 -0
  109. package/dist/models/Lexeme.js +22 -0
  110. package/dist/models/Lexeme.js.map +1 -0
  111. package/dist/models/MergeQuery.js +104 -0
  112. package/dist/models/MergeQuery.js.map +1 -0
  113. package/dist/models/SelectQuery.js +22 -0
  114. package/dist/models/SelectQuery.js.map +1 -0
  115. package/dist/models/SimpleSelectQuery.js +648 -0
  116. package/dist/models/SimpleSelectQuery.js.map +1 -0
  117. package/dist/models/SqlComponent.js +73 -0
  118. package/dist/models/SqlComponent.js.map +1 -0
  119. package/dist/models/SqlPrintToken.js +143 -0
  120. package/dist/models/SqlPrintToken.js.map +1 -0
  121. package/dist/models/TableDefinitionModel.js +86 -0
  122. package/dist/models/TableDefinitionModel.js.map +1 -0
  123. package/dist/models/UpdateQuery.js +29 -0
  124. package/dist/models/UpdateQuery.js.map +1 -0
  125. package/dist/models/ValueComponent.js +380 -0
  126. package/dist/models/ValueComponent.js.map +1 -0
  127. package/dist/models/ValuesQuery.js +62 -0
  128. package/dist/models/ValuesQuery.js.map +1 -0
  129. package/dist/parsers/AlterTableParser.js +490 -0
  130. package/dist/parsers/AlterTableParser.js.map +1 -0
  131. package/dist/parsers/AnalyzeStatementParser.js +94 -0
  132. package/dist/parsers/AnalyzeStatementParser.js.map +1 -0
  133. package/dist/parsers/CommandExpressionParser.js +213 -0
  134. package/dist/parsers/CommandExpressionParser.js.map +1 -0
  135. package/dist/parsers/CommonTableParser.js +177 -0
  136. package/dist/parsers/CommonTableParser.js.map +1 -0
  137. package/dist/parsers/CreateIndexParser.js +241 -0
  138. package/dist/parsers/CreateIndexParser.js.map +1 -0
  139. package/dist/parsers/CreateTableParser.js +738 -0
  140. package/dist/parsers/CreateTableParser.js.map +1 -0
  141. package/dist/parsers/DeleteClauseParser.js +37 -0
  142. package/dist/parsers/DeleteClauseParser.js.map +1 -0
  143. package/dist/parsers/DeleteQueryParser.js +77 -0
  144. package/dist/parsers/DeleteQueryParser.js.map +1 -0
  145. package/dist/parsers/DropConstraintParser.js +51 -0
  146. package/dist/parsers/DropConstraintParser.js.map +1 -0
  147. package/dist/parsers/DropIndexParser.js +73 -0
  148. package/dist/parsers/DropIndexParser.js.map +1 -0
  149. package/dist/parsers/DropTableParser.js +63 -0
  150. package/dist/parsers/DropTableParser.js.map +1 -0
  151. package/dist/parsers/ExplainStatementParser.js +189 -0
  152. package/dist/parsers/ExplainStatementParser.js.map +1 -0
  153. package/dist/parsers/FetchClauseParser.js +89 -0
  154. package/dist/parsers/FetchClauseParser.js.map +1 -0
  155. package/dist/parsers/ForClauseParser.js +58 -0
  156. package/dist/parsers/ForClauseParser.js.map +1 -0
  157. package/dist/parsers/FromClauseParser.js +54 -0
  158. package/dist/parsers/FromClauseParser.js.map +1 -0
  159. package/dist/parsers/FullNameParser.js +110 -0
  160. package/dist/parsers/FullNameParser.js.map +1 -0
  161. package/dist/parsers/FunctionExpressionParser.js +524 -0
  162. package/dist/parsers/FunctionExpressionParser.js.map +1 -0
  163. package/dist/parsers/GroupByParser.js +58 -0
  164. package/dist/parsers/GroupByParser.js.map +1 -0
  165. package/dist/parsers/HavingParser.js +36 -0
  166. package/dist/parsers/HavingParser.js.map +1 -0
  167. package/dist/parsers/IdentifierDecorator.js +17 -0
  168. package/dist/parsers/IdentifierDecorator.js.map +1 -0
  169. package/dist/parsers/IdentifierParser.js +15 -0
  170. package/dist/parsers/IdentifierParser.js.map +1 -0
  171. package/dist/parsers/InsertQueryParser.js +162 -0
  172. package/dist/parsers/InsertQueryParser.js.map +1 -0
  173. package/dist/parsers/JoinClauseParser.js +117 -0
  174. package/dist/parsers/JoinClauseParser.js.map +1 -0
  175. package/dist/parsers/JoinOnClauseParser.js +21 -0
  176. package/dist/parsers/JoinOnClauseParser.js.map +1 -0
  177. package/dist/parsers/JoinUsingClauseParser.js +23 -0
  178. package/dist/parsers/JoinUsingClauseParser.js.map +1 -0
  179. package/dist/parsers/KeywordParser.js +99 -0
  180. package/dist/parsers/KeywordParser.js.map +1 -0
  181. package/dist/parsers/LimitClauseParser.js +38 -0
  182. package/dist/parsers/LimitClauseParser.js.map +1 -0
  183. package/dist/parsers/LiteralParser.js +48 -0
  184. package/dist/parsers/LiteralParser.js.map +1 -0
  185. package/dist/parsers/MergeQueryParser.js +483 -0
  186. package/dist/parsers/MergeQueryParser.js.map +1 -0
  187. package/dist/parsers/OffsetClauseParser.js +42 -0
  188. package/dist/parsers/OffsetClauseParser.js.map +1 -0
  189. package/dist/parsers/OrderByClauseParser.js +108 -0
  190. package/dist/parsers/OrderByClauseParser.js.map +1 -0
  191. package/dist/parsers/OverExpressionParser.js +44 -0
  192. package/dist/parsers/OverExpressionParser.js.map +1 -0
  193. package/dist/parsers/ParameterDecorator.js +40 -0
  194. package/dist/parsers/ParameterDecorator.js.map +1 -0
  195. package/dist/parsers/ParameterExpressionParser.js +24 -0
  196. package/dist/parsers/ParameterExpressionParser.js.map +1 -0
  197. package/dist/parsers/ParenExpressionParser.js +109 -0
  198. package/dist/parsers/ParenExpressionParser.js.map +1 -0
  199. package/dist/parsers/ParseError.js +25 -0
  200. package/dist/parsers/ParseError.js.map +1 -0
  201. package/dist/parsers/PartitionByParser.js +53 -0
  202. package/dist/parsers/PartitionByParser.js.map +1 -0
  203. package/dist/parsers/ReturningClauseParser.js +64 -0
  204. package/dist/parsers/ReturningClauseParser.js.map +1 -0
  205. package/dist/parsers/SelectClauseParser.js +244 -0
  206. package/dist/parsers/SelectClauseParser.js.map +1 -0
  207. package/dist/parsers/SelectQueryParser.js +564 -0
  208. package/dist/parsers/SelectQueryParser.js.map +1 -0
  209. package/dist/parsers/SequenceParser.js +245 -0
  210. package/dist/parsers/SequenceParser.js.map +1 -0
  211. package/dist/parsers/SetClauseParser.js +125 -0
  212. package/dist/parsers/SetClauseParser.js.map +1 -0
  213. package/dist/parsers/SourceAliasExpressionParser.js +60 -0
  214. package/dist/parsers/SourceAliasExpressionParser.js.map +1 -0
  215. package/dist/parsers/SourceExpressionParser.js +69 -0
  216. package/dist/parsers/SourceExpressionParser.js.map +1 -0
  217. package/dist/parsers/SourceParser.js +144 -0
  218. package/dist/parsers/SourceParser.js.map +1 -0
  219. package/dist/parsers/SqlParser.js +431 -0
  220. package/dist/parsers/SqlParser.js.map +1 -0
  221. package/dist/parsers/SqlPrintTokenParser.js +3289 -0
  222. package/dist/parsers/SqlPrintTokenParser.js.map +1 -0
  223. package/dist/parsers/SqlTokenizer.js +553 -0
  224. package/dist/parsers/SqlTokenizer.js.map +1 -0
  225. package/dist/parsers/StringSpecifierExpressionParser.js +22 -0
  226. package/dist/parsers/StringSpecifierExpressionParser.js.map +1 -0
  227. package/dist/parsers/UnaryExpressionParser.js +39 -0
  228. package/dist/parsers/UnaryExpressionParser.js.map +1 -0
  229. package/dist/parsers/UpdateClauseParser.js +21 -0
  230. package/dist/parsers/UpdateClauseParser.js.map +1 -0
  231. package/dist/parsers/UpdateQueryParser.js +98 -0
  232. package/dist/parsers/UpdateQueryParser.js.map +1 -0
  233. package/dist/parsers/UsingClauseParser.js +33 -0
  234. package/dist/parsers/UsingClauseParser.js.map +1 -0
  235. package/dist/parsers/ValueParser.js +562 -0
  236. package/dist/parsers/ValueParser.js.map +1 -0
  237. package/dist/parsers/ValuesQueryParser.js +112 -0
  238. package/dist/parsers/ValuesQueryParser.js.map +1 -0
  239. package/dist/parsers/WhereClauseParser.js +51 -0
  240. package/dist/parsers/WhereClauseParser.js.map +1 -0
  241. package/dist/parsers/WindowClauseParser.js +57 -0
  242. package/dist/parsers/WindowClauseParser.js.map +1 -0
  243. package/dist/parsers/WindowExpressionParser.js +163 -0
  244. package/dist/parsers/WindowExpressionParser.js.map +1 -0
  245. package/dist/parsers/WithClauseParser.js +165 -0
  246. package/dist/parsers/WithClauseParser.js.map +1 -0
  247. package/dist/parsers/utils/LexemeCommentUtils.js +29 -0
  248. package/dist/parsers/utils/LexemeCommentUtils.js.map +1 -0
  249. package/dist/reporting/models/DataFlowEdge.js +58 -0
  250. package/dist/reporting/models/DataFlowEdge.js.map +1 -0
  251. package/dist/reporting/models/DataFlowGraph.js +138 -0
  252. package/dist/reporting/models/DataFlowGraph.js.map +1 -0
  253. package/dist/reporting/models/DataFlowNode.js +148 -0
  254. package/dist/reporting/models/DataFlowNode.js.map +1 -0
  255. package/dist/reporting/services/CTEHandler.js +58 -0
  256. package/dist/reporting/services/CTEHandler.js.map +1 -0
  257. package/dist/reporting/services/DataSourceHandler.js +95 -0
  258. package/dist/reporting/services/DataSourceHandler.js.map +1 -0
  259. package/dist/reporting/services/JoinHandler.js +84 -0
  260. package/dist/reporting/services/JoinHandler.js.map +1 -0
  261. package/dist/reporting/services/ProcessHandler.js +26 -0
  262. package/dist/reporting/services/ProcessHandler.js.map +1 -0
  263. package/dist/src/index.d.ts +15 -0
  264. package/dist/src/index.js +13 -1
  265. package/dist/src/index.js.map +1 -1
  266. package/dist/src/models/Clause.d.ts +7 -3
  267. package/dist/src/models/Clause.js +16 -3
  268. package/dist/src/models/Clause.js.map +1 -1
  269. package/dist/src/models/DDLStatements.d.ts +97 -2
  270. package/dist/src/models/DDLStatements.js +14 -1
  271. package/dist/src/models/DDLStatements.js.map +1 -1
  272. package/dist/src/models/InsertQuery.d.ts +1 -4
  273. package/dist/src/models/InsertQuery.js +3 -5
  274. package/dist/src/models/InsertQuery.js.map +1 -1
  275. package/dist/src/models/SqlPrintToken.d.ts +6 -0
  276. package/dist/src/models/SqlPrintToken.js +1 -0
  277. package/dist/src/models/SqlPrintToken.js.map +1 -1
  278. package/dist/src/models/TableDefinitionModel.d.ts +41 -0
  279. package/dist/src/models/TableDefinitionModel.js +85 -0
  280. package/dist/src/models/TableDefinitionModel.js.map +1 -0
  281. package/dist/src/models/ValueComponent.d.ts +2 -1
  282. package/dist/src/models/ValuesQuery.d.ts +2 -0
  283. package/dist/src/models/ValuesQuery.js +1 -0
  284. package/dist/src/models/ValuesQuery.js.map +1 -1
  285. package/dist/src/parsers/AlterTableParser.d.ts +1 -0
  286. package/dist/src/parsers/AlterTableParser.js +26 -5
  287. package/dist/src/parsers/AlterTableParser.js.map +1 -1
  288. package/dist/src/parsers/FunctionExpressionParser.d.ts +1 -0
  289. package/dist/src/parsers/InsertQueryParser.js +4 -1
  290. package/dist/src/parsers/InsertQueryParser.js.map +1 -1
  291. package/dist/src/parsers/ReturningClauseParser.js +33 -47
  292. package/dist/src/parsers/ReturningClauseParser.js.map +1 -1
  293. package/dist/src/parsers/SequenceParser.d.ts +16 -0
  294. package/dist/src/parsers/SqlParser.d.ts +4 -3
  295. package/dist/src/parsers/SqlParser.js +44 -63
  296. package/dist/src/parsers/SqlParser.js.map +1 -1
  297. package/dist/src/parsers/SqlPrintTokenParser.d.ts +9 -0
  298. package/dist/src/parsers/SqlPrintTokenParser.js +22 -4
  299. package/dist/src/parsers/SqlPrintTokenParser.js.map +1 -1
  300. package/dist/src/parsers/SqlTokenizer.d.ts +1 -0
  301. package/dist/src/tokenReaders/LiteralTokenReader.js +7 -0
  302. package/dist/src/tokenReaders/LiteralTokenReader.js.map +1 -1
  303. package/dist/src/transformers/DDLDiffGenerator.d.ts +18 -0
  304. package/dist/src/transformers/DDLDiffGenerator.js +313 -0
  305. package/dist/src/transformers/DDLDiffGenerator.js.map +1 -0
  306. package/dist/src/transformers/DDLGeneralizer.d.ts +13 -0
  307. package/dist/src/transformers/DDLGeneralizer.js +119 -0
  308. package/dist/src/transformers/DDLGeneralizer.js.map +1 -0
  309. package/dist/src/transformers/DDLToFixtureConverter.d.ts +19 -0
  310. package/dist/src/transformers/DDLToFixtureConverter.js +206 -0
  311. package/dist/src/transformers/DDLToFixtureConverter.js.map +1 -0
  312. package/dist/src/transformers/DeleteResultSelectConverter.d.ts +53 -0
  313. package/dist/src/transformers/DeleteResultSelectConverter.js +398 -0
  314. package/dist/src/transformers/DeleteResultSelectConverter.js.map +1 -0
  315. package/dist/src/transformers/FixtureCteBuilder.d.ts +60 -0
  316. package/dist/src/transformers/FixtureCteBuilder.js +151 -0
  317. package/dist/src/transformers/FixtureCteBuilder.js.map +1 -0
  318. package/dist/src/transformers/InsertQuerySelectValuesConverter.js +5 -2
  319. package/dist/src/transformers/InsertQuerySelectValuesConverter.js.map +1 -1
  320. package/dist/src/transformers/InsertResultSelectConverter.d.ts +67 -0
  321. package/dist/src/transformers/InsertResultSelectConverter.js +499 -0
  322. package/dist/src/transformers/InsertResultSelectConverter.js.map +1 -0
  323. package/dist/src/transformers/MergeResultSelectConverter.d.ts +38 -0
  324. package/dist/src/transformers/MergeResultSelectConverter.js +310 -0
  325. package/dist/src/transformers/MergeResultSelectConverter.js.map +1 -0
  326. package/dist/src/transformers/QueryBuilder.d.ts +11 -0
  327. package/dist/src/transformers/QueryBuilder.js +19 -3
  328. package/dist/src/transformers/QueryBuilder.js.map +1 -1
  329. package/dist/src/transformers/SelectResultSelectConverter.d.ts +10 -0
  330. package/dist/src/transformers/SelectResultSelectConverter.js +36 -0
  331. package/dist/src/transformers/SelectResultSelectConverter.js.map +1 -0
  332. package/dist/src/transformers/SimulatedSelectConverter.d.ts +23 -0
  333. package/dist/src/transformers/SimulatedSelectConverter.js +65 -0
  334. package/dist/src/transformers/SimulatedSelectConverter.js.map +1 -0
  335. package/dist/src/transformers/UpdateResultSelectConverter.d.ts +51 -0
  336. package/dist/src/transformers/UpdateResultSelectConverter.js +344 -0
  337. package/dist/src/transformers/UpdateResultSelectConverter.js.map +1 -0
  338. package/dist/src/types/GenericFixture.d.ts +17 -0
  339. package/dist/src/utils/SelectQueryWithClauseHelper.d.ts +12 -0
  340. package/dist/src/utils/SelectQueryWithClauseHelper.js +47 -0
  341. package/dist/src/utils/SelectQueryWithClauseHelper.js.map +1 -0
  342. package/dist/src/utils/TableNameUtils.d.ts +10 -0
  343. package/dist/src/utils/ValueComponentRewriter.d.ts +3 -0
  344. package/dist/src/utils/ValueComponentRewriter.js +183 -0
  345. package/dist/src/utils/ValueComponentRewriter.js.map +1 -0
  346. package/dist/tokenReaders/BaseTokenReader.js +86 -0
  347. package/dist/tokenReaders/BaseTokenReader.js.map +1 -0
  348. package/dist/tokenReaders/CommandTokenReader.js +221 -0
  349. package/dist/tokenReaders/CommandTokenReader.js.map +1 -0
  350. package/dist/tokenReaders/EscapedIdentifierTokenReader.js +99 -0
  351. package/dist/tokenReaders/EscapedIdentifierTokenReader.js.map +1 -0
  352. package/dist/tokenReaders/FunctionTokenReader.js +47 -0
  353. package/dist/tokenReaders/FunctionTokenReader.js.map +1 -0
  354. package/dist/tokenReaders/IdentifierTokenReader.js +34 -0
  355. package/dist/tokenReaders/IdentifierTokenReader.js.map +1 -0
  356. package/dist/tokenReaders/LiteralTokenReader.js +329 -0
  357. package/dist/tokenReaders/LiteralTokenReader.js.map +1 -0
  358. package/dist/tokenReaders/OperatorTokenReader.js +152 -0
  359. package/dist/tokenReaders/OperatorTokenReader.js.map +1 -0
  360. package/dist/tokenReaders/ParameterTokenReader.js +190 -0
  361. package/dist/tokenReaders/ParameterTokenReader.js.map +1 -0
  362. package/dist/tokenReaders/StringSpecifierTokenReader.js +31 -0
  363. package/dist/tokenReaders/StringSpecifierTokenReader.js.map +1 -0
  364. package/dist/tokenReaders/SymbolTokenReader.js +35 -0
  365. package/dist/tokenReaders/SymbolTokenReader.js.map +1 -0
  366. package/dist/tokenReaders/TokenReaderManager.js +110 -0
  367. package/dist/tokenReaders/TokenReaderManager.js.map +1 -0
  368. package/dist/tokenReaders/TypeTokenReader.js +69 -0
  369. package/dist/tokenReaders/TypeTokenReader.js.map +1 -0
  370. package/dist/transformers/AliasRenamer.js +600 -0
  371. package/dist/transformers/AliasRenamer.js.map +1 -0
  372. package/dist/transformers/CTEBuilder.js +188 -0
  373. package/dist/transformers/CTEBuilder.js.map +1 -0
  374. package/dist/transformers/CTECollector.js +409 -0
  375. package/dist/transformers/CTECollector.js.map +1 -0
  376. package/dist/transformers/CTEComposer.js +302 -0
  377. package/dist/transformers/CTEComposer.js.map +1 -0
  378. package/dist/transformers/CTEDependencyAnalyzer.js +285 -0
  379. package/dist/transformers/CTEDependencyAnalyzer.js.map +1 -0
  380. package/dist/transformers/CTEDependencyTracer.js +253 -0
  381. package/dist/transformers/CTEDependencyTracer.js.map +1 -0
  382. package/dist/transformers/CTEDisabler.js +355 -0
  383. package/dist/transformers/CTEDisabler.js.map +1 -0
  384. package/dist/transformers/CTEInjector.js +83 -0
  385. package/dist/transformers/CTEInjector.js.map +1 -0
  386. package/dist/transformers/CTENormalizer.js +46 -0
  387. package/dist/transformers/CTENormalizer.js.map +1 -0
  388. package/dist/transformers/CTEQueryDecomposer.js +589 -0
  389. package/dist/transformers/CTEQueryDecomposer.js.map +1 -0
  390. package/dist/transformers/CTERenamer.js +486 -0
  391. package/dist/transformers/CTERenamer.js.map +1 -0
  392. package/dist/transformers/CTETableReferenceCollector.js +358 -0
  393. package/dist/transformers/CTETableReferenceCollector.js.map +1 -0
  394. package/dist/transformers/ColumnReferenceCollector.js +478 -0
  395. package/dist/transformers/ColumnReferenceCollector.js.map +1 -0
  396. package/dist/transformers/DDLDiffGenerator.js +313 -0
  397. package/dist/transformers/DDLDiffGenerator.js.map +1 -0
  398. package/dist/transformers/DDLGeneralizer.js +119 -0
  399. package/dist/transformers/DDLGeneralizer.js.map +1 -0
  400. package/dist/transformers/DDLToFixtureConverter.js +206 -0
  401. package/dist/transformers/DDLToFixtureConverter.js.map +1 -0
  402. package/dist/transformers/DeleteResultSelectConverter.js +414 -0
  403. package/dist/transformers/DeleteResultSelectConverter.js.map +1 -0
  404. package/dist/transformers/DynamicQueryBuilder.js +164 -0
  405. package/dist/transformers/DynamicQueryBuilder.js.map +1 -0
  406. package/dist/transformers/EnhancedJsonMapping.js +223 -0
  407. package/dist/transformers/EnhancedJsonMapping.js.map +1 -0
  408. package/dist/transformers/FilterableItemCollector.js +259 -0
  409. package/dist/transformers/FilterableItemCollector.js.map +1 -0
  410. package/dist/transformers/FixtureCteBuilder.js +151 -0
  411. package/dist/transformers/FixtureCteBuilder.js.map +1 -0
  412. package/dist/transformers/FormatOptionResolver.js +67 -0
  413. package/dist/transformers/FormatOptionResolver.js.map +1 -0
  414. package/dist/transformers/Formatter.js +38 -0
  415. package/dist/transformers/Formatter.js.map +1 -0
  416. package/dist/transformers/InsertQuerySelectValuesConverter.js +125 -0
  417. package/dist/transformers/InsertQuerySelectValuesConverter.js.map +1 -0
  418. package/dist/transformers/InsertResultSelectConverter.js +589 -0
  419. package/dist/transformers/InsertResultSelectConverter.js.map +1 -0
  420. package/dist/transformers/JoinAggregationDecomposer.js +497 -0
  421. package/dist/transformers/JoinAggregationDecomposer.js.map +1 -0
  422. package/dist/transformers/JsonMappingConverter.js +392 -0
  423. package/dist/transformers/JsonMappingConverter.js.map +1 -0
  424. package/dist/transformers/JsonMappingUnifier.js +216 -0
  425. package/dist/transformers/JsonMappingUnifier.js.map +1 -0
  426. package/dist/transformers/LinePrinter.js +148 -0
  427. package/dist/transformers/LinePrinter.js.map +1 -0
  428. package/dist/transformers/MergeResultSelectConverter.js +310 -0
  429. package/dist/transformers/MergeResultSelectConverter.js.map +1 -0
  430. package/dist/transformers/ModelDrivenJsonMapping.js +122 -0
  431. package/dist/transformers/ModelDrivenJsonMapping.js.map +1 -0
  432. package/dist/transformers/OnelineFormattingHelper.js +99 -0
  433. package/dist/transformers/OnelineFormattingHelper.js.map +1 -0
  434. package/dist/transformers/ParameterCollector.js +37 -0
  435. package/dist/transformers/ParameterCollector.js.map +1 -0
  436. package/dist/transformers/PostgresArrayEntityCteBuilder.js +458 -0
  437. package/dist/transformers/PostgresArrayEntityCteBuilder.js.map +1 -0
  438. package/dist/transformers/PostgresJsonQueryBuilder.js +245 -0
  439. package/dist/transformers/PostgresJsonQueryBuilder.js.map +1 -0
  440. package/dist/transformers/PostgresObjectEntityCteBuilder.js +347 -0
  441. package/dist/transformers/PostgresObjectEntityCteBuilder.js.map +1 -0
  442. package/dist/transformers/QueryBuilder.js +649 -0
  443. package/dist/transformers/QueryBuilder.js.map +1 -0
  444. package/dist/transformers/QueryFlowDiagramGenerator.js +157 -0
  445. package/dist/transformers/QueryFlowDiagramGenerator.js.map +1 -0
  446. package/dist/transformers/SchemaCollector.js +523 -0
  447. package/dist/transformers/SchemaCollector.js.map +1 -0
  448. package/dist/transformers/SelectResultSelectConverter.js +36 -0
  449. package/dist/transformers/SelectResultSelectConverter.js.map +1 -0
  450. package/dist/transformers/SelectValueCollector.js +244 -0
  451. package/dist/transformers/SelectValueCollector.js.map +1 -0
  452. package/dist/transformers/SelectableColumnCollector.js +674 -0
  453. package/dist/transformers/SelectableColumnCollector.js.map +1 -0
  454. package/dist/transformers/SimulatedSelectConverter.js +65 -0
  455. package/dist/transformers/SimulatedSelectConverter.js.map +1 -0
  456. package/dist/transformers/SmartRenamer.js +422 -0
  457. package/dist/transformers/SmartRenamer.js.map +1 -0
  458. package/dist/transformers/SqlFormatter.js +77 -0
  459. package/dist/transformers/SqlFormatter.js.map +1 -0
  460. package/dist/transformers/SqlIdentifierRenamer.js +504 -0
  461. package/dist/transformers/SqlIdentifierRenamer.js.map +1 -0
  462. package/dist/transformers/SqlOutputToken.js +13 -0
  463. package/dist/transformers/SqlOutputToken.js.map +1 -0
  464. package/dist/transformers/SqlPaginationInjector.js +108 -0
  465. package/dist/transformers/SqlPaginationInjector.js.map +1 -0
  466. package/dist/transformers/SqlParamInjector.js +802 -0
  467. package/dist/transformers/SqlParamInjector.js.map +1 -0
  468. package/dist/transformers/SqlParameterBinder.js +70 -0
  469. package/dist/transformers/SqlParameterBinder.js.map +1 -0
  470. package/dist/transformers/SqlPrinter.js +1478 -0
  471. package/dist/transformers/SqlPrinter.js.map +1 -0
  472. package/dist/transformers/SqlSortInjector.js +153 -0
  473. package/dist/transformers/SqlSortInjector.js.map +1 -0
  474. package/dist/transformers/TableColumnResolver.js +3 -0
  475. package/dist/transformers/TableColumnResolver.js.map +1 -0
  476. package/dist/transformers/TableSourceCollector.js +439 -0
  477. package/dist/transformers/TableSourceCollector.js.map +1 -0
  478. package/dist/transformers/TypeTransformationPostProcessor.js +363 -0
  479. package/dist/transformers/TypeTransformationPostProcessor.js.map +1 -0
  480. package/dist/transformers/UpdateResultSelectConverter.js +359 -0
  481. package/dist/transformers/UpdateResultSelectConverter.js.map +1 -0
  482. package/dist/transformers/UpstreamSelectQueryFinder.js +184 -0
  483. package/dist/transformers/UpstreamSelectQueryFinder.js.map +1 -0
  484. package/dist/tsconfig.tsbuildinfo +1 -1
  485. package/dist/types/Formatting.js +3 -0
  486. package/dist/types/Formatting.js.map +1 -0
  487. package/dist/types/GenericFixture.js +3 -0
  488. package/dist/types/GenericFixture.js.map +1 -0
  489. package/dist/utils/CTERegionDetector.js +464 -0
  490. package/dist/utils/CTERegionDetector.js.map +1 -0
  491. package/dist/utils/CommentEditor.js +345 -0
  492. package/dist/utils/CommentEditor.js.map +1 -0
  493. package/dist/utils/CommentUtils.js +69 -0
  494. package/dist/utils/CommentUtils.js.map +1 -0
  495. package/dist/utils/CursorContextAnalyzer.js +338 -0
  496. package/dist/utils/CursorContextAnalyzer.js.map +1 -0
  497. package/dist/utils/IntelliSenseApi.js +292 -0
  498. package/dist/utils/IntelliSenseApi.js.map +1 -0
  499. package/dist/utils/JsonSchemaValidator.js +215 -0
  500. package/dist/utils/JsonSchemaValidator.js.map +1 -0
  501. package/dist/utils/KeywordCache.js +206 -0
  502. package/dist/utils/KeywordCache.js.map +1 -0
  503. package/dist/utils/LexemeCursor.js +314 -0
  504. package/dist/utils/LexemeCursor.js.map +1 -0
  505. package/dist/utils/MultiQuerySplitter.js +292 -0
  506. package/dist/utils/MultiQuerySplitter.js.map +1 -0
  507. package/dist/utils/OperatorPrecedence.js +107 -0
  508. package/dist/utils/OperatorPrecedence.js.map +1 -0
  509. package/dist/utils/ParameterDetector.js +53 -0
  510. package/dist/utils/ParameterDetector.js.map +1 -0
  511. package/dist/utils/ParameterHelper.js +31 -0
  512. package/dist/utils/ParameterHelper.js.map +1 -0
  513. package/dist/utils/ParameterRemover.js +783 -0
  514. package/dist/utils/ParameterRemover.js.map +1 -0
  515. package/dist/utils/ParserStringUtils.js +31 -0
  516. package/dist/utils/ParserStringUtils.js.map +1 -0
  517. package/dist/utils/PositionAwareParser.js +363 -0
  518. package/dist/utils/PositionAwareParser.js.map +1 -0
  519. package/dist/utils/SchemaManager.js +217 -0
  520. package/dist/utils/SchemaManager.js.map +1 -0
  521. package/dist/utils/ScopeResolver.js +272 -0
  522. package/dist/utils/ScopeResolver.js.map +1 -0
  523. package/dist/utils/SelectQueryWithClauseHelper.js +47 -0
  524. package/dist/utils/SelectQueryWithClauseHelper.js.map +1 -0
  525. package/dist/utils/SqlSchemaValidator.js +55 -0
  526. package/dist/utils/SqlSchemaValidator.js.map +1 -0
  527. package/dist/utils/TableNameUtils.js +35 -0
  528. package/dist/utils/TableNameUtils.js.map +1 -0
  529. package/dist/utils/TextPositionUtils.js +128 -0
  530. package/dist/utils/TextPositionUtils.js.map +1 -0
  531. package/dist/utils/ValueComponentRewriter.js +187 -0
  532. package/dist/utils/ValueComponentRewriter.js.map +1 -0
  533. package/dist/utils/charLookupTable.js +73 -0
  534. package/dist/utils/charLookupTable.js.map +1 -0
  535. package/dist/utils/stringUtils.js +230 -0
  536. package/dist/utils/stringUtils.js.map +1 -0
  537. package/package.json +62 -62
@@ -0,0 +1,1478 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SqlPrinter = void 0;
4
+ const SqlPrintToken_1 = require("../models/SqlPrintToken");
5
+ const LinePrinter_1 = require("./LinePrinter");
6
+ const FormatOptionResolver_1 = require("./FormatOptionResolver");
7
+ const OnelineFormattingHelper_1 = require("./OnelineFormattingHelper");
8
+ const CREATE_TABLE_SINGLE_PAREN_KEYWORDS = new Set(['unique', 'check', 'key', 'index']);
9
+ const CREATE_TABLE_MULTI_PAREN_KEYWORDS = new Set(['primary key', 'foreign key', 'unique key']);
10
+ const CREATE_TABLE_PAREN_KEYWORDS_WITH_IDENTIFIER = new Set(['references']);
11
+ /**
12
+ * SqlPrinter formats a SqlPrintToken tree into a SQL string with flexible style options.
13
+ *
14
+ * This class provides various formatting options including:
15
+ * - Indentation control (character and size)
16
+ * - Line break styles for commas and AND operators
17
+ * - Keyword case transformation
18
+ * - Comment handling
19
+ * - WITH clause formatting styles
20
+ *
21
+ * @example
22
+ * const printer = new SqlPrinter({
23
+ * indentChar: ' ',
24
+ * indentSize: 1,
25
+ * keywordCase: 'upper',
26
+ * commaBreak: 'after',
27
+ * withClauseStyle: 'cte-oneline'
28
+ * });
29
+ * const formatted = printer.print(sqlToken);
30
+ */
31
+ class SqlPrinter {
32
+ /**
33
+ * @param options Optional style settings for pretty printing
34
+ */
35
+ constructor(options) {
36
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
37
+ /** Track whether we are currently inside a WITH clause for full-oneline formatting */
38
+ this.insideWithClause = false;
39
+ /** Tracks nesting depth while formatting MERGE WHEN predicate segments */
40
+ this.mergeWhenPredicateDepth = 0;
41
+ /** Pending line comment that needs a forced newline before next token */
42
+ this.pendingLineCommentBreak = null;
43
+ /** Accumulates lines when reconstructing multi-line block comments inside CommentBlocks */
44
+ this.smartCommentBlockBuilder = null;
45
+ // Resolve logical options to their control character representations before applying defaults.
46
+ const resolvedIndentChar = (0, FormatOptionResolver_1.resolveIndentCharOption)(options === null || options === void 0 ? void 0 : options.indentChar);
47
+ const resolvedNewline = (0, FormatOptionResolver_1.resolveNewlineOption)(options === null || options === void 0 ? void 0 : options.newline);
48
+ this.indentChar = resolvedIndentChar !== null && resolvedIndentChar !== void 0 ? resolvedIndentChar : '';
49
+ this.indentSize = (_a = options === null || options === void 0 ? void 0 : options.indentSize) !== null && _a !== void 0 ? _a : 0;
50
+ // The default newline character is set to a blank space (' ') to enable one-liner formatting.
51
+ // This is intentional and differs from the LinePrinter default of '\r\n'.
52
+ this.newline = resolvedNewline !== null && resolvedNewline !== void 0 ? resolvedNewline : ' ';
53
+ this.commaBreak = (_b = options === null || options === void 0 ? void 0 : options.commaBreak) !== null && _b !== void 0 ? _b : 'none';
54
+ this.cteCommaBreak = (_c = options === null || options === void 0 ? void 0 : options.cteCommaBreak) !== null && _c !== void 0 ? _c : this.commaBreak;
55
+ this.valuesCommaBreak = (_d = options === null || options === void 0 ? void 0 : options.valuesCommaBreak) !== null && _d !== void 0 ? _d : this.commaBreak;
56
+ this.andBreak = (_e = options === null || options === void 0 ? void 0 : options.andBreak) !== null && _e !== void 0 ? _e : 'none';
57
+ this.orBreak = (_f = options === null || options === void 0 ? void 0 : options.orBreak) !== null && _f !== void 0 ? _f : 'none';
58
+ this.keywordCase = (_g = options === null || options === void 0 ? void 0 : options.keywordCase) !== null && _g !== void 0 ? _g : 'none';
59
+ this.commentExportMode = this.resolveCommentExportMode(options === null || options === void 0 ? void 0 : options.exportComment);
60
+ this.withClauseStyle = (_h = options === null || options === void 0 ? void 0 : options.withClauseStyle) !== null && _h !== void 0 ? _h : 'standard';
61
+ this.commentStyle = (_j = options === null || options === void 0 ? void 0 : options.commentStyle) !== null && _j !== void 0 ? _j : 'block';
62
+ this.parenthesesOneLine = (_k = options === null || options === void 0 ? void 0 : options.parenthesesOneLine) !== null && _k !== void 0 ? _k : false;
63
+ this.betweenOneLine = (_l = options === null || options === void 0 ? void 0 : options.betweenOneLine) !== null && _l !== void 0 ? _l : false;
64
+ this.valuesOneLine = (_m = options === null || options === void 0 ? void 0 : options.valuesOneLine) !== null && _m !== void 0 ? _m : false;
65
+ this.joinOneLine = (_o = options === null || options === void 0 ? void 0 : options.joinOneLine) !== null && _o !== void 0 ? _o : false;
66
+ this.caseOneLine = (_p = options === null || options === void 0 ? void 0 : options.caseOneLine) !== null && _p !== void 0 ? _p : false;
67
+ this.subqueryOneLine = (_q = options === null || options === void 0 ? void 0 : options.subqueryOneLine) !== null && _q !== void 0 ? _q : false;
68
+ this.indentNestedParentheses = (_r = options === null || options === void 0 ? void 0 : options.indentNestedParentheses) !== null && _r !== void 0 ? _r : false;
69
+ this.insertColumnsOneLine = (_s = options === null || options === void 0 ? void 0 : options.insertColumnsOneLine) !== null && _s !== void 0 ? _s : false;
70
+ this.whenOneLine = (_t = options === null || options === void 0 ? void 0 : options.whenOneLine) !== null && _t !== void 0 ? _t : false;
71
+ const onelineOptions = {
72
+ parenthesesOneLine: this.parenthesesOneLine,
73
+ betweenOneLine: this.betweenOneLine,
74
+ valuesOneLine: this.valuesOneLine,
75
+ joinOneLine: this.joinOneLine,
76
+ caseOneLine: this.caseOneLine,
77
+ subqueryOneLine: this.subqueryOneLine,
78
+ insertColumnsOneLine: this.insertColumnsOneLine,
79
+ withClauseStyle: this.withClauseStyle,
80
+ };
81
+ this.onelineHelper = new OnelineFormattingHelper_1.OnelineFormattingHelper(onelineOptions);
82
+ this.linePrinter = new LinePrinter_1.LinePrinter(this.indentChar, this.indentSize, this.newline, this.commaBreak);
83
+ // Initialize
84
+ this.indentIncrementContainers = new Set((_u = options === null || options === void 0 ? void 0 : options.indentIncrementContainerTypes) !== null && _u !== void 0 ? _u : [
85
+ SqlPrintToken_1.SqlPrintTokenContainerType.SelectClause,
86
+ SqlPrintToken_1.SqlPrintTokenContainerType.FromClause,
87
+ SqlPrintToken_1.SqlPrintTokenContainerType.WhereClause,
88
+ SqlPrintToken_1.SqlPrintTokenContainerType.GroupByClause,
89
+ SqlPrintToken_1.SqlPrintTokenContainerType.HavingClause,
90
+ SqlPrintToken_1.SqlPrintTokenContainerType.WindowFrameExpression,
91
+ SqlPrintToken_1.SqlPrintTokenContainerType.PartitionByClause,
92
+ SqlPrintToken_1.SqlPrintTokenContainerType.OrderByClause,
93
+ SqlPrintToken_1.SqlPrintTokenContainerType.WindowClause,
94
+ SqlPrintToken_1.SqlPrintTokenContainerType.LimitClause,
95
+ SqlPrintToken_1.SqlPrintTokenContainerType.OffsetClause,
96
+ SqlPrintToken_1.SqlPrintTokenContainerType.SubQuerySource,
97
+ SqlPrintToken_1.SqlPrintTokenContainerType.BinarySelectQueryOperator, SqlPrintToken_1.SqlPrintTokenContainerType.Values,
98
+ SqlPrintToken_1.SqlPrintTokenContainerType.WithClause,
99
+ SqlPrintToken_1.SqlPrintTokenContainerType.SwitchCaseArgument,
100
+ SqlPrintToken_1.SqlPrintTokenContainerType.CaseKeyValuePair,
101
+ SqlPrintToken_1.SqlPrintTokenContainerType.CaseThenValue,
102
+ SqlPrintToken_1.SqlPrintTokenContainerType.ElseClause,
103
+ SqlPrintToken_1.SqlPrintTokenContainerType.CaseElseValue,
104
+ SqlPrintToken_1.SqlPrintTokenContainerType.SimpleSelectQuery,
105
+ SqlPrintToken_1.SqlPrintTokenContainerType.CreateTableDefinition,
106
+ SqlPrintToken_1.SqlPrintTokenContainerType.AlterTableStatement,
107
+ SqlPrintToken_1.SqlPrintTokenContainerType.IndexColumnList,
108
+ SqlPrintToken_1.SqlPrintTokenContainerType.SetClause
109
+ // Note: CommentBlock is intentionally excluded from indentIncrementContainers
110
+ // because it serves as a grouping mechanism without affecting indentation.
111
+ // CaseExpression, SwitchCaseArgument, CaseKeyValuePair, and ElseClause
112
+ // are not included by default to maintain backward compatibility with tests.
113
+ // SqlPrintTokenContainerType.CommonTable is also excluded by default.
114
+ ]);
115
+ }
116
+ /**
117
+ * Converts a SqlPrintToken tree to a formatted SQL string.
118
+ * @param token The root SqlPrintToken to format
119
+ * @param level Initial indentation level (default: 0)
120
+ * @returns Formatted SQL string
121
+ * @example
122
+ * const printer = new SqlPrinter({ indentChar: ' ', keywordCase: 'upper' });
123
+ * const formatted = printer.print(sqlToken);
124
+ */
125
+ print(token, level = 0) {
126
+ // initialize
127
+ this.linePrinter = new LinePrinter_1.LinePrinter(this.indentChar, this.indentSize, this.newline, this.commaBreak);
128
+ this.insideWithClause = false; // Reset WITH clause context
129
+ this.pendingLineCommentBreak = null;
130
+ this.smartCommentBlockBuilder = null;
131
+ if (this.linePrinter.lines.length > 0 && level !== this.linePrinter.lines[0].level) {
132
+ this.linePrinter.lines[0].level = level;
133
+ }
134
+ this.appendToken(token, level, undefined, 0, false, undefined, false);
135
+ return this.linePrinter.print();
136
+ }
137
+ // Resolve legacy boolean values into explicit comment export modes.
138
+ resolveCommentExportMode(option) {
139
+ if (option === undefined) {
140
+ return 'none';
141
+ }
142
+ if (option === true) {
143
+ return 'full';
144
+ }
145
+ if (option === false) {
146
+ return 'none';
147
+ }
148
+ return option;
149
+ }
150
+ // Determine whether the current mode allows emitting inline comments.
151
+ rendersInlineComments() {
152
+ return this.commentExportMode === 'full';
153
+ }
154
+ // Decide if a comment block or token should be rendered given its context.
155
+ shouldRenderComment(token, context) {
156
+ if (context === null || context === void 0 ? void 0 : context.forceRender) {
157
+ return this.commentExportMode !== 'none';
158
+ }
159
+ switch (this.commentExportMode) {
160
+ case 'full':
161
+ return true;
162
+ case 'none':
163
+ return false;
164
+ case 'header-only':
165
+ return token.isHeaderComment === true;
166
+ case 'top-header-only':
167
+ return token.isHeaderComment === true && Boolean(context === null || context === void 0 ? void 0 : context.isTopLevelContainer);
168
+ default:
169
+ return false;
170
+ }
171
+ }
172
+ appendToken(token, level, parentContainerType, caseContextDepth = 0, indentParentActive = false, commentContext, previousSiblingWasOpenParen = false) {
173
+ // Track WITH clause context for full-oneline formatting
174
+ const wasInsideWithClause = this.insideWithClause;
175
+ if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.WithClause && this.withClauseStyle === 'full-oneline') {
176
+ this.insideWithClause = true;
177
+ }
178
+ if (this.shouldSkipToken(token)) {
179
+ return;
180
+ }
181
+ const containerIsTopLevel = parentContainerType === undefined;
182
+ let leadingCommentCount = 0;
183
+ // Collect leading comment blocks with context so we can respect the export mode.
184
+ const leadingCommentContexts = [];
185
+ if (token.innerTokens && token.innerTokens.length > 0) {
186
+ while (leadingCommentCount < token.innerTokens.length) {
187
+ const leadingCandidate = token.innerTokens[leadingCommentCount];
188
+ if (leadingCandidate.containerType !== SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock) {
189
+ break;
190
+ }
191
+ const context = {
192
+ position: 'leading',
193
+ isTopLevelContainer: containerIsTopLevel,
194
+ };
195
+ const shouldRender = this.shouldRenderComment(leadingCandidate, context);
196
+ leadingCommentContexts.push({ token: leadingCandidate, context, shouldRender });
197
+ leadingCommentCount++;
198
+ }
199
+ }
200
+ const hasRenderableLeadingComment = leadingCommentContexts.some(item => item.shouldRender);
201
+ const leadingCommentIndentLevel = hasRenderableLeadingComment
202
+ ? this.getLeadingCommentIndentLevel(parentContainerType, level)
203
+ : null;
204
+ if (hasRenderableLeadingComment
205
+ && !this.isOnelineMode()
206
+ && this.shouldAddNewlineBeforeLeadingComments(parentContainerType)) {
207
+ const currentLine = this.linePrinter.getCurrentLine();
208
+ if (currentLine.text.trim().length > 0) {
209
+ // Align the newline before leading comments with the intended comment indentation.
210
+ this.linePrinter.appendNewline(leadingCommentIndentLevel !== null && leadingCommentIndentLevel !== void 0 ? leadingCommentIndentLevel : level);
211
+ }
212
+ }
213
+ for (const leading of leadingCommentContexts) {
214
+ if (!leading.shouldRender) {
215
+ continue;
216
+ }
217
+ // Keep leading comment processing aligned with its computed indentation level.
218
+ this.appendToken(leading.token, leadingCommentIndentLevel !== null && leadingCommentIndentLevel !== void 0 ? leadingCommentIndentLevel : level, token.containerType, caseContextDepth, indentParentActive, leading.context, false);
219
+ }
220
+ if (this.smartCommentBlockBuilder && token.containerType !== SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock && token.type !== SqlPrintToken_1.SqlPrintTokenType.commentNewline) {
221
+ this.flushSmartCommentBlockBuilder();
222
+ }
223
+ if (this.pendingLineCommentBreak !== null) {
224
+ if (!this.isOnelineMode()) {
225
+ this.linePrinter.appendNewline(this.pendingLineCommentBreak);
226
+ }
227
+ const shouldSkipToken = token.type === SqlPrintToken_1.SqlPrintTokenType.commentNewline;
228
+ this.pendingLineCommentBreak = null;
229
+ if (shouldSkipToken) {
230
+ return;
231
+ }
232
+ }
233
+ // Fallback context applies when the caller did not provide comment metadata.
234
+ const effectiveCommentContext = commentContext !== null && commentContext !== void 0 ? commentContext : {
235
+ position: 'inline',
236
+ isTopLevelContainer: containerIsTopLevel,
237
+ };
238
+ if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock) {
239
+ if (!this.shouldRenderComment(token, effectiveCommentContext)) {
240
+ return;
241
+ }
242
+ const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
243
+ this.handleCommentBlockContainer(token, commentLevel, effectiveCommentContext);
244
+ return;
245
+ }
246
+ const current = this.linePrinter.getCurrentLine();
247
+ const isCaseContext = this.isCaseContext(token.containerType);
248
+ const nextCaseContextDepth = isCaseContext ? caseContextDepth + 1 : caseContextDepth;
249
+ const shouldIndentNested = this.shouldIndentNestedParentheses(token, previousSiblingWasOpenParen);
250
+ // Handle different token types
251
+ if (token.type === SqlPrintToken_1.SqlPrintTokenType.keyword) {
252
+ this.handleKeywordToken(token, level, parentContainerType, caseContextDepth);
253
+ }
254
+ else if (token.type === SqlPrintToken_1.SqlPrintTokenType.comma) {
255
+ this.handleCommaToken(token, level, parentContainerType);
256
+ }
257
+ else if (token.type === SqlPrintToken_1.SqlPrintTokenType.parenthesis) {
258
+ this.handleParenthesisToken(token, level, indentParentActive, parentContainerType);
259
+ }
260
+ else if (token.type === SqlPrintToken_1.SqlPrintTokenType.operator && token.text.toLowerCase() === 'and') {
261
+ this.handleAndOperatorToken(token, level, parentContainerType, caseContextDepth);
262
+ }
263
+ else if (token.type === SqlPrintToken_1.SqlPrintTokenType.operator && token.text.toLowerCase() === 'or') {
264
+ this.handleOrOperatorToken(token, level, parentContainerType, caseContextDepth);
265
+ }
266
+ else if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.JoinClause) {
267
+ this.handleJoinClauseToken(token, level);
268
+ }
269
+ else if (token.type === SqlPrintToken_1.SqlPrintTokenType.comment) {
270
+ if (this.shouldRenderComment(token, effectiveCommentContext)) {
271
+ const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
272
+ this.printCommentToken(token.text, commentLevel, parentContainerType);
273
+ }
274
+ }
275
+ else if (token.type === SqlPrintToken_1.SqlPrintTokenType.space) {
276
+ this.handleSpaceToken(token, parentContainerType);
277
+ }
278
+ else if (token.type === SqlPrintToken_1.SqlPrintTokenType.commentNewline) {
279
+ if (this.whenOneLine && parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause) {
280
+ return;
281
+ }
282
+ const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
283
+ this.handleCommentNewlineToken(token, commentLevel);
284
+ }
285
+ else if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommonTable && this.withClauseStyle === 'cte-oneline') {
286
+ this.handleCteOnelineToken(token, level);
287
+ return; // Return early to avoid processing innerTokens
288
+ }
289
+ else if (this.shouldFormatContainerAsOneline(token, shouldIndentNested)) {
290
+ this.handleOnelineToken(token, level);
291
+ return; // Return early to avoid processing innerTokens
292
+ }
293
+ else if (!this.tryAppendInsertClauseTokenText(token.text, parentContainerType)) {
294
+ this.linePrinter.appendText(token.text);
295
+ }
296
+ // append keyword tokens(not indented)
297
+ if (token.keywordTokens && token.keywordTokens.length > 0) {
298
+ for (let i = 0; i < token.keywordTokens.length; i++) {
299
+ const keywordToken = token.keywordTokens[i];
300
+ this.appendToken(keywordToken, level, token.containerType, nextCaseContextDepth, indentParentActive, undefined, false);
301
+ }
302
+ }
303
+ let innerLevel = level;
304
+ let increasedIndent = false;
305
+ const shouldIncreaseIndent = this.indentIncrementContainers.has(token.containerType) || shouldIndentNested;
306
+ const delayIndentNewline = shouldIndentNested && token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression;
307
+ const isAlterTableStatement = token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.AlterTableStatement;
308
+ let deferAlterTableIndent = false;
309
+ const alignExplainChild = this.shouldAlignExplainStatementChild(parentContainerType, token.containerType);
310
+ if (alignExplainChild) {
311
+ // Keep EXPLAIN target statements flush left so they render like standalone statements.
312
+ if (!this.isOnelineMode() && current.text !== '') {
313
+ this.linePrinter.appendNewline(level);
314
+ }
315
+ innerLevel = level;
316
+ increasedIndent = false;
317
+ }
318
+ else if (!this.isOnelineMode() && shouldIncreaseIndent) {
319
+ if (this.insideWithClause && this.withClauseStyle === 'full-oneline') {
320
+ // Keep everything on one line for full-oneline WITH clauses.
321
+ }
322
+ else if (delayIndentNewline) {
323
+ innerLevel = level + 1;
324
+ increasedIndent = true;
325
+ }
326
+ else if (current.text !== '') {
327
+ if (isAlterTableStatement) {
328
+ // Delay the first line break so ALTER TABLE keeps the table name on the opening line.
329
+ innerLevel = level + 1;
330
+ increasedIndent = true;
331
+ deferAlterTableIndent = true;
332
+ }
333
+ else {
334
+ let targetIndentLevel = level + 1;
335
+ if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.SetClause &&
336
+ parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction) {
337
+ targetIndentLevel = level + 2;
338
+ }
339
+ if (this.shouldAlignCreateTableSelect(token.containerType, parentContainerType)) {
340
+ innerLevel = level;
341
+ increasedIndent = false;
342
+ this.linePrinter.appendNewline(level);
343
+ }
344
+ else {
345
+ innerLevel = targetIndentLevel;
346
+ increasedIndent = true;
347
+ this.linePrinter.appendNewline(innerLevel);
348
+ }
349
+ }
350
+ }
351
+ else if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.SetClause) {
352
+ innerLevel = parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction ? level + 2 : level + 1;
353
+ increasedIndent = true;
354
+ current.level = innerLevel;
355
+ }
356
+ }
357
+ const isMergeWhenClause = this.whenOneLine && token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause;
358
+ let mergePredicateActive = isMergeWhenClause;
359
+ let alterTableTableRendered = false;
360
+ let alterTableIndentInserted = false;
361
+ for (let i = leadingCommentCount; i < token.innerTokens.length; i++) {
362
+ const child = token.innerTokens[i];
363
+ const nextChild = token.innerTokens[i + 1];
364
+ const previousEntry = this.findPreviousSignificantToken(token.innerTokens, i);
365
+ const previousChild = previousEntry === null || previousEntry === void 0 ? void 0 : previousEntry.token;
366
+ const priorEntry = previousEntry ? this.findPreviousSignificantToken(token.innerTokens, previousEntry.index) : undefined;
367
+ const priorChild = priorEntry === null || priorEntry === void 0 ? void 0 : priorEntry.token;
368
+ const childIsAction = this.isMergeActionContainer(child);
369
+ const nextIsAction = this.isMergeActionContainer(nextChild);
370
+ const inMergePredicate = mergePredicateActive && !childIsAction;
371
+ if (isAlterTableStatement) {
372
+ if (child.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.QualifiedName) {
373
+ // Track when the table name has been printed so we can defer indentation until after it.
374
+ alterTableTableRendered = true;
375
+ }
376
+ else if (deferAlterTableIndent && alterTableTableRendered && !alterTableIndentInserted) {
377
+ if (!this.isOnelineMode()) {
378
+ this.linePrinter.appendNewline(innerLevel);
379
+ }
380
+ alterTableIndentInserted = true;
381
+ deferAlterTableIndent = false;
382
+ if (!this.isOnelineMode() && child.type === SqlPrintToken_1.SqlPrintTokenType.space) {
383
+ // Drop the space token because we already emitted a newline.
384
+ continue;
385
+ }
386
+ }
387
+ }
388
+ if (child.type === SqlPrintToken_1.SqlPrintTokenType.space) {
389
+ if (this.shouldConvertSpaceToClauseBreak(token.containerType, nextChild)) {
390
+ if (!this.isOnelineMode()) {
391
+ // Use a dedicated indent resolver so clause breaks can shift indentation for nested blocks.
392
+ const clauseBreakIndent = this.getClauseBreakIndentLevel(token.containerType, innerLevel);
393
+ this.linePrinter.appendNewline(clauseBreakIndent);
394
+ }
395
+ if (isMergeWhenClause && nextIsAction) {
396
+ mergePredicateActive = false;
397
+ }
398
+ continue;
399
+ }
400
+ this.handleSpaceToken(child, token.containerType, nextChild, previousChild, priorChild);
401
+ continue;
402
+ }
403
+ const previousChildWasOpenParen = (previousChild === null || previousChild === void 0 ? void 0 : previousChild.type) === SqlPrintToken_1.SqlPrintTokenType.parenthesis && previousChild.text.trim() === '(';
404
+ const childIndentParentActive = token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression ? shouldIndentNested : indentParentActive;
405
+ if (inMergePredicate) {
406
+ this.mergeWhenPredicateDepth++;
407
+ }
408
+ const childCommentContext = child.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock
409
+ ? { position: 'inline', isTopLevelContainer: containerIsTopLevel }
410
+ : undefined;
411
+ this.appendToken(child, innerLevel, token.containerType, nextCaseContextDepth, childIndentParentActive, childCommentContext, previousChildWasOpenParen);
412
+ if (inMergePredicate) {
413
+ this.mergeWhenPredicateDepth--;
414
+ }
415
+ if (childIsAction && isMergeWhenClause) {
416
+ mergePredicateActive = false;
417
+ }
418
+ }
419
+ if (this.smartCommentBlockBuilder && this.smartCommentBlockBuilder.mode === 'line') {
420
+ this.flushSmartCommentBlockBuilder();
421
+ }
422
+ // Exit WITH clause context when we finish processing WithClause container
423
+ if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.WithClause && this.withClauseStyle === 'full-oneline') {
424
+ this.insideWithClause = false;
425
+ // Add newline after WITH clause to separate it from main SELECT
426
+ this.linePrinter.appendNewline(level);
427
+ return; // Return early to avoid additional newline below
428
+ }
429
+ // indent level down
430
+ if (increasedIndent && shouldIncreaseIndent && !(this.insideWithClause && this.withClauseStyle === 'full-oneline') && !delayIndentNewline) {
431
+ this.linePrinter.appendNewline(level);
432
+ }
433
+ }
434
+ shouldAlignExplainStatementChild(parentType, childType) {
435
+ if (parentType !== SqlPrintToken_1.SqlPrintTokenContainerType.ExplainStatement) {
436
+ return false;
437
+ }
438
+ switch (childType) {
439
+ case SqlPrintToken_1.SqlPrintTokenContainerType.SimpleSelectQuery:
440
+ case SqlPrintToken_1.SqlPrintTokenContainerType.InsertQuery:
441
+ case SqlPrintToken_1.SqlPrintTokenContainerType.UpdateQuery:
442
+ case SqlPrintToken_1.SqlPrintTokenContainerType.DeleteQuery:
443
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeQuery:
444
+ return true;
445
+ default:
446
+ return false;
447
+ }
448
+ }
449
+ isCaseContext(containerType) {
450
+ switch (containerType) {
451
+ case SqlPrintToken_1.SqlPrintTokenContainerType.CaseExpression:
452
+ case SqlPrintToken_1.SqlPrintTokenContainerType.CaseKeyValuePair:
453
+ case SqlPrintToken_1.SqlPrintTokenContainerType.CaseThenValue:
454
+ case SqlPrintToken_1.SqlPrintTokenContainerType.CaseElseValue:
455
+ case SqlPrintToken_1.SqlPrintTokenContainerType.SwitchCaseArgument:
456
+ return true;
457
+ default:
458
+ return false;
459
+ }
460
+ }
461
+ /**
462
+ * Determines if a token should be skipped during printing.
463
+ * Tokens are skipped if they have no content and no inner tokens,
464
+ * except for special token types that have semantic meaning despite empty text.
465
+ */
466
+ shouldSkipToken(token) {
467
+ // Special tokens with semantic meaning should never be skipped
468
+ if (token.type === SqlPrintToken_1.SqlPrintTokenType.commentNewline) {
469
+ return false;
470
+ }
471
+ // Skip tokens that have no content and no children
472
+ return (!token.innerTokens || token.innerTokens.length === 0) && token.text === '';
473
+ }
474
+ applyKeywordCase(text) {
475
+ if (this.keywordCase === 'upper') {
476
+ return text.toUpperCase();
477
+ }
478
+ else if (this.keywordCase === 'lower') {
479
+ return text.toLowerCase();
480
+ }
481
+ return text;
482
+ }
483
+ handleKeywordToken(token, level, parentContainerType, caseContextDepth = 0) {
484
+ const lower = token.text.toLowerCase();
485
+ if (lower === 'and' &&
486
+ (this.andBreak !== 'none' || (this.whenOneLine && parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause))) {
487
+ this.handleAndOperatorToken(token, level, parentContainerType, caseContextDepth);
488
+ return;
489
+ }
490
+ else if (lower === 'or' &&
491
+ (this.orBreak !== 'none' || (this.whenOneLine && parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause))) {
492
+ this.handleOrOperatorToken(token, level, parentContainerType, caseContextDepth);
493
+ return;
494
+ }
495
+ const text = this.applyKeywordCase(token.text);
496
+ if (caseContextDepth > 0) {
497
+ this.linePrinter.appendText(text);
498
+ return;
499
+ }
500
+ this.ensureSpaceBeforeKeyword();
501
+ this.linePrinter.appendText(text);
502
+ }
503
+ ensureSpaceBeforeKeyword() {
504
+ const currentLine = this.linePrinter.getCurrentLine();
505
+ if (currentLine.text === '') {
506
+ return;
507
+ }
508
+ const lastChar = currentLine.text[currentLine.text.length - 1];
509
+ if (lastChar === '(') {
510
+ return;
511
+ }
512
+ this.ensureTrailingSpace();
513
+ }
514
+ ensureTrailingSpace() {
515
+ const currentLine = this.linePrinter.getCurrentLine();
516
+ if (currentLine.text === '') {
517
+ return;
518
+ }
519
+ if (!currentLine.text.endsWith(' ')) {
520
+ currentLine.text += ' ';
521
+ }
522
+ currentLine.text = currentLine.text.replace(/\s+$/, ' ');
523
+ }
524
+ /**
525
+ * Normalizes INSERT column list token text when one-line formatting is active.
526
+ */
527
+ tryAppendInsertClauseTokenText(text, parentContainerType) {
528
+ const currentLineText = this.linePrinter.getCurrentLine().text;
529
+ const result = this.onelineHelper.formatInsertClauseToken(text, parentContainerType, currentLineText, () => this.ensureTrailingSpace());
530
+ if (!result.handled) {
531
+ return false;
532
+ }
533
+ if (result.text) {
534
+ this.linePrinter.appendText(result.text);
535
+ }
536
+ return true;
537
+ }
538
+ handleCommaToken(token, level, parentContainerType) {
539
+ const text = token.text;
540
+ const isWithinWithClause = parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.WithClause;
541
+ let effectiveCommaBreak = this.onelineHelper.resolveCommaBreak(parentContainerType, this.commaBreak, this.cteCommaBreak, this.valuesCommaBreak);
542
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.SetClause) {
543
+ effectiveCommaBreak = 'before';
544
+ }
545
+ // Skip comma newlines when inside WITH clause with full-oneline style
546
+ if (this.insideWithClause && this.withClauseStyle === 'full-oneline') {
547
+ this.linePrinter.appendText(text);
548
+ }
549
+ // Special handling for commas in WithClause when withClauseStyle is 'cte-oneline'
550
+ else if (this.withClauseStyle === 'cte-oneline' && isWithinWithClause) {
551
+ this.linePrinter.appendText(text);
552
+ this.linePrinter.appendNewline(level);
553
+ }
554
+ else if (effectiveCommaBreak === 'before') {
555
+ const previousCommaBreak = this.linePrinter.commaBreak;
556
+ if (previousCommaBreak !== 'before') {
557
+ this.linePrinter.commaBreak = 'before';
558
+ }
559
+ if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
560
+ this.linePrinter.appendNewline(level);
561
+ if (this.newline === ' ') {
562
+ // Remove the spacer introduced by space newlines so commas attach directly to the preceding token.
563
+ this.linePrinter.trimTrailingWhitespaceFromPreviousLine();
564
+ }
565
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause) {
566
+ // Align comma-prefixed column entries under the INSERT column indentation.
567
+ this.linePrinter.getCurrentLine().level = level + 1;
568
+ }
569
+ }
570
+ this.linePrinter.appendText(text);
571
+ if (previousCommaBreak !== 'before') {
572
+ this.linePrinter.commaBreak = previousCommaBreak;
573
+ }
574
+ }
575
+ else if (effectiveCommaBreak === 'after') {
576
+ const previousCommaBreak = this.linePrinter.commaBreak;
577
+ if (previousCommaBreak !== 'after') {
578
+ this.linePrinter.commaBreak = 'after';
579
+ }
580
+ if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
581
+ this.linePrinter.appendNewline(level);
582
+ }
583
+ this.linePrinter.appendText(text);
584
+ if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
585
+ this.linePrinter.appendNewline(level);
586
+ }
587
+ if (previousCommaBreak !== 'after') {
588
+ this.linePrinter.commaBreak = previousCommaBreak;
589
+ }
590
+ }
591
+ else if (effectiveCommaBreak === 'none') {
592
+ const previousCommaBreak = this.linePrinter.commaBreak;
593
+ if (previousCommaBreak !== 'none') {
594
+ this.linePrinter.commaBreak = 'none';
595
+ }
596
+ this.linePrinter.appendText(text);
597
+ if (this.onelineHelper.isInsertClauseOneline(parentContainerType)) {
598
+ this.ensureTrailingSpace();
599
+ }
600
+ if (previousCommaBreak !== 'none') {
601
+ this.linePrinter.commaBreak = previousCommaBreak;
602
+ }
603
+ }
604
+ else {
605
+ this.linePrinter.appendText(text);
606
+ }
607
+ }
608
+ handleAndOperatorToken(token, level, parentContainerType, caseContextDepth = 0) {
609
+ const text = this.applyKeywordCase(token.text);
610
+ if (caseContextDepth > 0) {
611
+ this.linePrinter.appendText(text);
612
+ return;
613
+ }
614
+ if (this.whenOneLine &&
615
+ (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause || this.mergeWhenPredicateDepth > 0)) {
616
+ this.linePrinter.appendText(text);
617
+ return;
618
+ }
619
+ if (this.andBreak === 'before') {
620
+ // Skip newline when inside WITH clause with full-oneline style
621
+ if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
622
+ this.linePrinter.appendNewline(level);
623
+ }
624
+ this.linePrinter.appendText(text);
625
+ }
626
+ else if (this.andBreak === 'after') {
627
+ this.linePrinter.appendText(text);
628
+ // Skip newline when inside WITH clause with full-oneline style
629
+ if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
630
+ this.linePrinter.appendNewline(level);
631
+ }
632
+ }
633
+ else {
634
+ this.linePrinter.appendText(text);
635
+ }
636
+ }
637
+ handleParenthesisToken(token, level, indentParentActive, parentContainerType) {
638
+ if (token.text === '(') {
639
+ this.linePrinter.appendText(token.text);
640
+ if ((parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause ||
641
+ parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction) &&
642
+ this.insertColumnsOneLine) {
643
+ return;
644
+ }
645
+ if (!this.isOnelineMode()) {
646
+ if (this.shouldBreakAfterOpeningParen(parentContainerType)) {
647
+ this.linePrinter.appendNewline(level + 1);
648
+ }
649
+ else if (indentParentActive && !(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
650
+ this.linePrinter.appendNewline(level);
651
+ }
652
+ }
653
+ return;
654
+ }
655
+ if (token.text === ')' && !this.isOnelineMode()) {
656
+ if (this.shouldBreakBeforeClosingParen(parentContainerType)) {
657
+ this.linePrinter.appendNewline(Math.max(level, 0));
658
+ this.linePrinter.appendText(token.text);
659
+ return;
660
+ }
661
+ if (indentParentActive && !(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
662
+ const closingLevel = Math.max(level - 1, 0);
663
+ this.linePrinter.appendNewline(closingLevel);
664
+ }
665
+ }
666
+ this.linePrinter.appendText(token.text);
667
+ }
668
+ handleOrOperatorToken(token, level, parentContainerType, caseContextDepth = 0) {
669
+ const text = this.applyKeywordCase(token.text);
670
+ // Leave OR untouched inside CASE branches to preserve inline evaluation order.
671
+ if (caseContextDepth > 0) {
672
+ this.linePrinter.appendText(text);
673
+ return;
674
+ }
675
+ if (this.whenOneLine &&
676
+ (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause || this.mergeWhenPredicateDepth > 0)) {
677
+ this.linePrinter.appendText(text);
678
+ return;
679
+ }
680
+ if (this.orBreak === 'before') {
681
+ // Insert a newline before OR unless WITH full-oneline mode suppresses breaks.
682
+ if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
683
+ this.linePrinter.appendNewline(level);
684
+ }
685
+ this.linePrinter.appendText(text);
686
+ }
687
+ else if (this.orBreak === 'after') {
688
+ this.linePrinter.appendText(text);
689
+ // Break after OR when multi-line formatting is active.
690
+ if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
691
+ this.linePrinter.appendNewline(level);
692
+ }
693
+ }
694
+ else {
695
+ this.linePrinter.appendText(text);
696
+ }
697
+ }
698
+ /**
699
+ * Decide whether a parentheses group should increase indentation when inside nested structures.
700
+ * We only expand groups that contain further parentheses so simple comparisons stay compact.
701
+ */
702
+ shouldIndentNestedParentheses(token, previousSiblingWasOpenParen = false) {
703
+ if (!this.indentNestedParentheses) {
704
+ return false;
705
+ }
706
+ if (token.containerType !== SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression) {
707
+ return false;
708
+ }
709
+ // Look for nested parentheses containers. If present, indent to highlight grouping.
710
+ return previousSiblingWasOpenParen || token.innerTokens.some((child) => this.containsParenExpression(child));
711
+ }
712
+ /**
713
+ * Recursively inspect descendants to find additional parentheses groups.
714
+ * Helps detect complex boolean groups like ((A) OR (B) OR (C)).
715
+ */
716
+ containsParenExpression(token) {
717
+ if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression) {
718
+ return true;
719
+ }
720
+ for (const child of token.innerTokens) {
721
+ if (this.containsParenExpression(child)) {
722
+ return true;
723
+ }
724
+ }
725
+ return false;
726
+ }
727
+ handleJoinClauseToken(token, level) {
728
+ const text = this.applyKeywordCase(token.text);
729
+ // before join clause, add newline when multiline formatting is allowed
730
+ if (this.onelineHelper.shouldInsertJoinNewline(this.insideWithClause)) {
731
+ this.linePrinter.appendNewline(level);
732
+ }
733
+ this.linePrinter.appendText(text);
734
+ }
735
+ /**
736
+ * Decides whether the current container should collapse into a single line.
737
+ */
738
+ shouldFormatContainerAsOneline(token, shouldIndentNested) {
739
+ return this.onelineHelper.shouldFormatContainer(token, shouldIndentNested);
740
+ }
741
+ /**
742
+ * Detects an INSERT column list that must stay on a single line.
743
+ */
744
+ isInsertClauseOneline(parentContainerType) {
745
+ return this.onelineHelper.isInsertClauseOneline(parentContainerType);
746
+ }
747
+ /**
748
+ * Handles space tokens with context-aware filtering.
749
+ * Skips spaces in CommentBlocks when in specific CTE modes to prevent duplication.
750
+ */
751
+ handleSpaceToken(token, parentContainerType, nextToken, previousToken, priorToken) {
752
+ if (this.smartCommentBlockBuilder && this.smartCommentBlockBuilder.mode === 'line') {
753
+ this.flushSmartCommentBlockBuilder();
754
+ }
755
+ const currentLineText = this.linePrinter.getCurrentLine().text;
756
+ if (this.onelineHelper.shouldSkipInsertClauseSpace(parentContainerType, nextToken, currentLineText)) {
757
+ return;
758
+ }
759
+ if (this.onelineHelper.shouldSkipCommentBlockSpace(parentContainerType, this.insideWithClause)) {
760
+ const currentLine = this.linePrinter.getCurrentLine();
761
+ if (currentLine.text !== '' && !currentLine.text.endsWith(' ')) {
762
+ this.linePrinter.appendText(' ');
763
+ }
764
+ return;
765
+ }
766
+ // Skip redundant spaces before structural parentheses in CREATE TABLE DDL.
767
+ if (this.shouldSkipSpaceBeforeParenthesis(parentContainerType, nextToken, previousToken, priorToken)) {
768
+ return;
769
+ }
770
+ this.linePrinter.appendText(token.text);
771
+ }
772
+ findPreviousSignificantToken(tokens, index) {
773
+ for (let i = index - 1; i >= 0; i--) {
774
+ const candidate = tokens[i];
775
+ if (candidate.type === SqlPrintToken_1.SqlPrintTokenType.space || candidate.type === SqlPrintToken_1.SqlPrintTokenType.commentNewline) {
776
+ continue;
777
+ }
778
+ if (candidate.type === SqlPrintToken_1.SqlPrintTokenType.comment && !this.rendersInlineComments()) {
779
+ continue;
780
+ }
781
+ return { token: candidate, index: i };
782
+ }
783
+ return undefined;
784
+ }
785
+ shouldSkipSpaceBeforeParenthesis(parentContainerType, nextToken, previousToken, priorToken) {
786
+ if (!nextToken || nextToken.type !== SqlPrintToken_1.SqlPrintTokenType.parenthesis || nextToken.text !== '(') {
787
+ return false;
788
+ }
789
+ if (!parentContainerType || !this.isCreateTableSpacingContext(parentContainerType)) {
790
+ return false;
791
+ }
792
+ if (!previousToken) {
793
+ return false;
794
+ }
795
+ if (this.isCreateTableNameToken(previousToken, parentContainerType)) {
796
+ return true;
797
+ }
798
+ if (this.isCreateTableConstraintKeyword(previousToken, parentContainerType)) {
799
+ return true;
800
+ }
801
+ if (priorToken && this.isCreateTableConstraintKeyword(priorToken, parentContainerType)) {
802
+ if (this.isIdentifierAttachedToConstraint(previousToken, priorToken, parentContainerType)) {
803
+ return true;
804
+ }
805
+ }
806
+ return false;
807
+ }
808
+ shouldAlignCreateTableSelect(containerType, parentContainerType) {
809
+ return containerType === SqlPrintToken_1.SqlPrintTokenContainerType.SimpleSelectQuery &&
810
+ parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.CreateTableQuery;
811
+ }
812
+ isCreateTableSpacingContext(parentContainerType) {
813
+ switch (parentContainerType) {
814
+ case SqlPrintToken_1.SqlPrintTokenContainerType.CreateTableQuery:
815
+ case SqlPrintToken_1.SqlPrintTokenContainerType.CreateTableDefinition:
816
+ case SqlPrintToken_1.SqlPrintTokenContainerType.TableConstraintDefinition:
817
+ case SqlPrintToken_1.SqlPrintTokenContainerType.ColumnConstraintDefinition:
818
+ case SqlPrintToken_1.SqlPrintTokenContainerType.ReferenceDefinition:
819
+ return true;
820
+ default:
821
+ return false;
822
+ }
823
+ }
824
+ isCreateTableNameToken(previousToken, parentContainerType) {
825
+ if (parentContainerType !== SqlPrintToken_1.SqlPrintTokenContainerType.CreateTableQuery) {
826
+ return false;
827
+ }
828
+ return previousToken.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.QualifiedName;
829
+ }
830
+ isCreateTableConstraintKeyword(token, parentContainerType) {
831
+ if (token.type !== SqlPrintToken_1.SqlPrintTokenType.keyword) {
832
+ return false;
833
+ }
834
+ const text = token.text.toLowerCase();
835
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ReferenceDefinition) {
836
+ return CREATE_TABLE_PAREN_KEYWORDS_WITH_IDENTIFIER.has(text);
837
+ }
838
+ if (CREATE_TABLE_SINGLE_PAREN_KEYWORDS.has(text)) {
839
+ return true;
840
+ }
841
+ if (CREATE_TABLE_MULTI_PAREN_KEYWORDS.has(text)) {
842
+ return true;
843
+ }
844
+ return false;
845
+ }
846
+ isIdentifierAttachedToConstraint(token, keywordToken, parentContainerType) {
847
+ if (!token) {
848
+ return false;
849
+ }
850
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ReferenceDefinition) {
851
+ return token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.QualifiedName &&
852
+ CREATE_TABLE_PAREN_KEYWORDS_WITH_IDENTIFIER.has(keywordToken.text.toLowerCase());
853
+ }
854
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.TableConstraintDefinition ||
855
+ parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ColumnConstraintDefinition) {
856
+ const normalized = keywordToken.text.toLowerCase();
857
+ if (CREATE_TABLE_SINGLE_PAREN_KEYWORDS.has(normalized) ||
858
+ CREATE_TABLE_MULTI_PAREN_KEYWORDS.has(normalized)) {
859
+ return token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.IdentifierString;
860
+ }
861
+ }
862
+ return false;
863
+ }
864
+ printCommentToken(text, level, parentContainerType) {
865
+ const trimmed = text.trim();
866
+ if (!trimmed) {
867
+ return;
868
+ }
869
+ if (this.commentStyle === 'smart' && parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock) {
870
+ if (this.handleSmartCommentBlockToken(text, trimmed, level)) {
871
+ return;
872
+ }
873
+ }
874
+ if (this.commentStyle === 'smart') {
875
+ const normalized = this.normalizeCommentForSmart(trimmed);
876
+ if (normalized.lines.length > 1 || normalized.forceBlock) {
877
+ const blockText = this.buildBlockComment(normalized.lines, level);
878
+ this.linePrinter.appendText(blockText);
879
+ }
880
+ else {
881
+ const content = normalized.lines[0];
882
+ const lineText = content ? `-- ${content}` : '--';
883
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock) {
884
+ this.linePrinter.appendText(lineText);
885
+ this.pendingLineCommentBreak = this.resolveCommentIndentLevel(level, parentContainerType);
886
+ }
887
+ else {
888
+ this.linePrinter.appendText(lineText);
889
+ const effectiveLevel = this.resolveCommentIndentLevel(level, parentContainerType);
890
+ this.linePrinter.appendNewline(effectiveLevel);
891
+ }
892
+ }
893
+ }
894
+ else {
895
+ if (trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
896
+ if (/\r?\n/.test(trimmed)) {
897
+ // Keep multi-line block comments intact by normalizing line endings once.
898
+ const newlineReplacement = this.isOnelineMode() ? ' ' : (typeof this.newline === 'string' ? this.newline : '\n');
899
+ const normalized = trimmed.replace(/\r?\n/g, newlineReplacement);
900
+ this.linePrinter.appendText(normalized);
901
+ }
902
+ else {
903
+ this.linePrinter.appendText(trimmed);
904
+ }
905
+ }
906
+ else {
907
+ this.linePrinter.appendText(trimmed);
908
+ }
909
+ if (trimmed.startsWith('--')) {
910
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock) {
911
+ this.pendingLineCommentBreak = this.resolveCommentIndentLevel(level, parentContainerType);
912
+ }
913
+ else {
914
+ const effectiveLevel = this.resolveCommentIndentLevel(level, parentContainerType);
915
+ this.linePrinter.appendNewline(effectiveLevel);
916
+ }
917
+ }
918
+ }
919
+ }
920
+ handleSmartCommentBlockToken(raw, trimmed, level) {
921
+ if (!this.smartCommentBlockBuilder) {
922
+ if (trimmed === '/*') {
923
+ // Begin assembling a multi-line block comment that is emitted as split tokens
924
+ this.smartCommentBlockBuilder = { lines: [], level, mode: 'block' };
925
+ return true;
926
+ }
927
+ const lineContent = this.extractLineCommentContent(trimmed);
928
+ if (lineContent !== null) {
929
+ this.smartCommentBlockBuilder = {
930
+ lines: [lineContent],
931
+ level,
932
+ mode: 'line',
933
+ };
934
+ return true;
935
+ }
936
+ return false;
937
+ }
938
+ if (this.smartCommentBlockBuilder.mode === 'block') {
939
+ if (trimmed === '*/') {
940
+ const { lines, level: blockLevel } = this.smartCommentBlockBuilder;
941
+ const blockText = this.buildBlockComment(lines, blockLevel);
942
+ this.linePrinter.appendText(blockText);
943
+ this.pendingLineCommentBreak = blockLevel;
944
+ this.smartCommentBlockBuilder = null;
945
+ return true;
946
+ }
947
+ this.smartCommentBlockBuilder.lines.push(this.normalizeSmartBlockLine(raw));
948
+ return true;
949
+ }
950
+ const content = this.extractLineCommentContent(trimmed);
951
+ if (content !== null) {
952
+ this.smartCommentBlockBuilder.lines.push(content);
953
+ return true;
954
+ }
955
+ this.flushSmartCommentBlockBuilder();
956
+ return false;
957
+ }
958
+ handleCommentBlockContainer(token, level, context) {
959
+ var _a;
960
+ if (this.commentStyle !== 'smart') {
961
+ const rawLines = this.extractRawCommentBlockLines(token);
962
+ if (rawLines.length > 0) {
963
+ const normalizedBlocks = rawLines.map(line => `/* ${line} */`).join(' ');
964
+ const hasTrailingSpace = (_a = token.innerTokens) === null || _a === void 0 ? void 0 : _a.some(child => child.type === SqlPrintToken_1.SqlPrintTokenType.space && child.text.includes(' '));
965
+ this.linePrinter.appendText(hasTrailingSpace ? `${normalizedBlocks} ` : normalizedBlocks);
966
+ return;
967
+ }
968
+ for (const child of token.innerTokens) {
969
+ // Force inner comment tokens to render once the block is approved.
970
+ const childContext = {
971
+ position: context.position,
972
+ isTopLevelContainer: context.isTopLevelContainer,
973
+ forceRender: true,
974
+ };
975
+ this.appendToken(child, level, token.containerType, 0, false, childContext, false);
976
+ }
977
+ return;
978
+ }
979
+ const lines = this.collectCommentBlockLines(token);
980
+ if (lines.length === 0 && !this.smartCommentBlockBuilder) {
981
+ // No meaningful content; treat as empty line comment to preserve spacing
982
+ this.smartCommentBlockBuilder = {
983
+ lines: [''],
984
+ level,
985
+ mode: 'line',
986
+ };
987
+ return;
988
+ }
989
+ if (!this.smartCommentBlockBuilder || this.smartCommentBlockBuilder.mode !== 'line') {
990
+ this.smartCommentBlockBuilder = {
991
+ lines: [...lines],
992
+ level,
993
+ mode: 'line',
994
+ };
995
+ }
996
+ else {
997
+ this.smartCommentBlockBuilder.lines.push(...lines);
998
+ }
999
+ }
1000
+ normalizeSmartBlockLine(raw) {
1001
+ // Remove trailing whitespace that only carries formatting artifacts
1002
+ let line = raw.replace(/\s+$/g, '');
1003
+ if (!line) {
1004
+ return '';
1005
+ }
1006
+ if (line.startsWith(' ')) {
1007
+ line = line.slice(2);
1008
+ }
1009
+ if (line.startsWith('* ')) {
1010
+ return line.slice(2);
1011
+ }
1012
+ if (line === '*') {
1013
+ return '';
1014
+ }
1015
+ if (line.startsWith('*')) {
1016
+ return line.slice(1);
1017
+ }
1018
+ return line;
1019
+ }
1020
+ extractLineCommentContent(trimmed) {
1021
+ if (trimmed.startsWith('--')) {
1022
+ return trimmed.slice(2).trimStart();
1023
+ }
1024
+ if (trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
1025
+ const inner = trimmed.slice(2, -2).trim();
1026
+ return inner;
1027
+ }
1028
+ return null;
1029
+ }
1030
+ flushSmartCommentBlockBuilder() {
1031
+ var _a;
1032
+ if (!this.smartCommentBlockBuilder) {
1033
+ return;
1034
+ }
1035
+ const { lines, level, mode } = this.smartCommentBlockBuilder;
1036
+ if (mode === 'line') {
1037
+ const meaningfulLineCount = lines.filter(line => line.trim() !== '').length;
1038
+ if (meaningfulLineCount > 1) {
1039
+ const blockText = this.buildBlockComment(lines, level);
1040
+ this.linePrinter.appendText(blockText);
1041
+ }
1042
+ else {
1043
+ const content = (_a = lines[0]) !== null && _a !== void 0 ? _a : '';
1044
+ const lineText = content ? `-- ${content}` : '--';
1045
+ this.linePrinter.appendText(lineText);
1046
+ }
1047
+ if (!this.isOnelineMode()) {
1048
+ this.linePrinter.appendNewline(level);
1049
+ }
1050
+ this.pendingLineCommentBreak = null;
1051
+ }
1052
+ this.smartCommentBlockBuilder = null;
1053
+ }
1054
+ collectCommentBlockLines(token) {
1055
+ var _a;
1056
+ const lines = [];
1057
+ let collectingBlock = false;
1058
+ for (const child of (_a = token.innerTokens) !== null && _a !== void 0 ? _a : []) {
1059
+ if (child.type === SqlPrintToken_1.SqlPrintTokenType.comment) {
1060
+ const trimmed = child.text.trim();
1061
+ if (trimmed === '/*') {
1062
+ collectingBlock = true;
1063
+ continue;
1064
+ }
1065
+ if (trimmed === '*/') {
1066
+ collectingBlock = false;
1067
+ continue;
1068
+ }
1069
+ if (collectingBlock) {
1070
+ lines.push(this.normalizeSmartBlockLine(child.text));
1071
+ continue;
1072
+ }
1073
+ const content = this.extractLineCommentContent(trimmed);
1074
+ if (content !== null) {
1075
+ lines.push(content);
1076
+ }
1077
+ }
1078
+ }
1079
+ return lines;
1080
+ }
1081
+ extractRawCommentBlockLines(token) {
1082
+ var _a;
1083
+ const lines = [];
1084
+ let collectingBlock = false;
1085
+ for (const child of (_a = token.innerTokens) !== null && _a !== void 0 ? _a : []) {
1086
+ if (child.type === SqlPrintToken_1.SqlPrintTokenType.comment) {
1087
+ const text = child.text;
1088
+ const trimmed = text.trim();
1089
+ if (trimmed === '/*') {
1090
+ collectingBlock = true;
1091
+ continue;
1092
+ }
1093
+ if (trimmed === '*/') {
1094
+ collectingBlock = false;
1095
+ continue;
1096
+ }
1097
+ if (collectingBlock) {
1098
+ if (trimmed.length > 0) {
1099
+ lines.push(trimmed);
1100
+ }
1101
+ continue;
1102
+ }
1103
+ }
1104
+ }
1105
+ return lines;
1106
+ }
1107
+ normalizeCommentForSmart(text) {
1108
+ const trimmed = text.trim();
1109
+ let source = trimmed;
1110
+ let forceBlock = false;
1111
+ if (trimmed.startsWith('--')) {
1112
+ source = trimmed.slice(2);
1113
+ }
1114
+ else if (trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
1115
+ const inner = trimmed.slice(2, -2);
1116
+ const normalizedInner = inner.replace(/\r?\n/g, '\n');
1117
+ if (normalizedInner.includes('\n')) {
1118
+ forceBlock = true;
1119
+ source = inner;
1120
+ }
1121
+ else {
1122
+ source = inner;
1123
+ if (!source.trim()) {
1124
+ source = trimmed;
1125
+ }
1126
+ }
1127
+ }
1128
+ const escaped = this.escapeCommentDelimiters(source);
1129
+ const normalized = escaped.replace(/\r?\n/g, '\n');
1130
+ const rawSegments = normalized.split('\n');
1131
+ const processedLines = [];
1132
+ const processedRaw = [];
1133
+ for (const segment of rawSegments) {
1134
+ const rawTrimmed = segment.trim();
1135
+ const sanitized = this.sanitizeCommentLine(segment);
1136
+ if (sanitized.length > 0) {
1137
+ processedLines.push(sanitized);
1138
+ processedRaw.push(rawTrimmed);
1139
+ }
1140
+ }
1141
+ let lines = processedLines;
1142
+ if (lines.length === 0) {
1143
+ lines = [''];
1144
+ }
1145
+ if (!forceBlock && lines.length === 1 && !lines[0] && trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
1146
+ const escapedFull = this.escapeCommentDelimiters(trimmed);
1147
+ lines = [this.sanitizeCommentLine(escapedFull)];
1148
+ }
1149
+ if (!forceBlock && lines.length > 1) {
1150
+ forceBlock = true;
1151
+ }
1152
+ lines = lines.map((line, index) => {
1153
+ var _a;
1154
+ if (/^[-=_+*#]+$/.test(line)) {
1155
+ const rawLine = (_a = processedRaw[index]) !== null && _a !== void 0 ? _a : line;
1156
+ const normalizedRaw = rawLine.replace(/\s+/g, '');
1157
+ if (normalizedRaw.length >= line.length) {
1158
+ return normalizedRaw;
1159
+ }
1160
+ }
1161
+ return line;
1162
+ });
1163
+ return { lines, forceBlock };
1164
+ }
1165
+ buildBlockComment(lines, level) {
1166
+ var _a, _b, _c;
1167
+ if (lines.length <= 1) {
1168
+ const content = (_a = lines[0]) !== null && _a !== void 0 ? _a : '';
1169
+ return content ? `/* ${content} */` : '/* */';
1170
+ }
1171
+ const newline = this.newline === ' ' ? '\n' : this.newline;
1172
+ const currentLevel = (_c = (_b = this.linePrinter.getCurrentLine()) === null || _b === void 0 ? void 0 : _b.level) !== null && _c !== void 0 ? _c : level;
1173
+ const baseIndent = this.getIndentString(currentLevel);
1174
+ const unitIndent = ' ';
1175
+ const innerIndent = baseIndent + unitIndent;
1176
+ const body = lines.map(line => `${innerIndent}${line}`).join(newline);
1177
+ const closing = `${baseIndent}*/`;
1178
+ return `/*${newline}${body}${newline}${closing}`;
1179
+ }
1180
+ getIndentString(level) {
1181
+ if (level <= 0) {
1182
+ return '';
1183
+ }
1184
+ if (this.indentSize <= 0) {
1185
+ return ' '.repeat(level);
1186
+ }
1187
+ const unit = typeof this.indentChar === 'string' ? this.indentChar : '';
1188
+ return unit.repeat(this.indentSize * level);
1189
+ }
1190
+ sanitizeCommentLine(content) {
1191
+ let sanitized = content;
1192
+ sanitized = sanitized.replace(/\u2028|\u2029/g, ' ');
1193
+ sanitized = sanitized.replace(/\s+/g, ' ').trim();
1194
+ return sanitized;
1195
+ }
1196
+ escapeCommentDelimiters(content) {
1197
+ return content
1198
+ .replace(/\/\*/g, '\\/\\*')
1199
+ .replace(/\*\//g, '*\\/');
1200
+ }
1201
+ getCommentBaseIndentLevel(level, parentContainerType) {
1202
+ if (!parentContainerType) {
1203
+ return level;
1204
+ }
1205
+ const clauseAlignedLevel = this.getClauseBreakIndentLevel(parentContainerType, level);
1206
+ return Math.max(level, clauseAlignedLevel);
1207
+ }
1208
+ resolveCommentIndentLevel(level, parentContainerType) {
1209
+ var _a;
1210
+ const baseLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
1211
+ const currentLevel = (_a = this.linePrinter.getCurrentLine().level) !== null && _a !== void 0 ? _a : baseLevel;
1212
+ return Math.max(baseLevel, currentLevel);
1213
+ }
1214
+ /**
1215
+ * Handles commentNewline tokens with conditional newline behavior.
1216
+ * In multiline mode (newline !== ' '), adds a newline after comments.
1217
+ * In oneliner mode (newline === ' '), does nothing to keep comments on same line.
1218
+ * Skips newlines in CTE modes (full-oneline, cte-oneline) to maintain one-line format.
1219
+ */
1220
+ handleCommentNewlineToken(token, level) {
1221
+ if (this.smartCommentBlockBuilder) {
1222
+ return;
1223
+ }
1224
+ if (this.pendingLineCommentBreak !== null) {
1225
+ this.linePrinter.appendNewline(this.pendingLineCommentBreak);
1226
+ this.pendingLineCommentBreak = null;
1227
+ return;
1228
+ }
1229
+ if (this.shouldSkipCommentNewline()) {
1230
+ return;
1231
+ }
1232
+ if (!this.isOnelineMode()) {
1233
+ this.linePrinter.appendNewline(level);
1234
+ }
1235
+ }
1236
+ /**
1237
+ * Determines whether to skip commentNewline tokens.
1238
+ * Skips in CTE modes to maintain one-line formatting.
1239
+ */
1240
+ shouldSkipCommentNewline() {
1241
+ return (this.insideWithClause && this.withClauseStyle === 'full-oneline') ||
1242
+ this.withClauseStyle === 'cte-oneline';
1243
+ }
1244
+ shouldAddNewlineBeforeLeadingComments(parentType) {
1245
+ if (!parentType) {
1246
+ return false;
1247
+ }
1248
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.TupleExpression) {
1249
+ return true;
1250
+ }
1251
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause ||
1252
+ parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction) {
1253
+ return !this.insertColumnsOneLine;
1254
+ }
1255
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.SetClause) {
1256
+ return true;
1257
+ }
1258
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.SelectClause) {
1259
+ return true;
1260
+ }
1261
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.ExplainStatement) {
1262
+ // Ensure EXPLAIN targets print header comments on a dedicated line.
1263
+ return true;
1264
+ }
1265
+ return false;
1266
+ }
1267
+ getLeadingCommentIndentLevel(parentType, currentLevel) {
1268
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.TupleExpression) {
1269
+ return currentLevel + 1;
1270
+ }
1271
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause ||
1272
+ parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction ||
1273
+ parentType === SqlPrintToken_1.SqlPrintTokenContainerType.SelectClause) {
1274
+ return currentLevel + 1;
1275
+ }
1276
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.SetClause) {
1277
+ return currentLevel + 1;
1278
+ }
1279
+ return currentLevel;
1280
+ }
1281
+ /**
1282
+ * Determines if the printer is in oneliner mode.
1283
+ * Oneliner mode uses single spaces instead of actual newlines.
1284
+ */
1285
+ isOnelineMode() {
1286
+ return this.newline === ' ';
1287
+ }
1288
+ /**
1289
+ * Handles CTE tokens with one-liner formatting.
1290
+ * Creates a nested SqlPrinter instance for proper CTE oneline formatting.
1291
+ */
1292
+ handleCteOnelineToken(token, level) {
1293
+ const onelinePrinter = this.createCteOnelinePrinter();
1294
+ const onelineResult = onelinePrinter.print(token, level);
1295
+ let cleanedResult = this.cleanDuplicateSpaces(onelineResult);
1296
+ cleanedResult = cleanedResult.replace(/\(\s+/g, '(').replace(/\s+\)/g, ' )');
1297
+ this.linePrinter.appendText(cleanedResult.trim());
1298
+ }
1299
+ /**
1300
+ * Creates a SqlPrinter instance configured for CTE oneline formatting.
1301
+ */
1302
+ createCteOnelinePrinter() {
1303
+ return new SqlPrinter({
1304
+ indentChar: '',
1305
+ indentSize: 0,
1306
+ newline: ' ',
1307
+ commaBreak: this.commaBreak,
1308
+ cteCommaBreak: this.cteCommaBreak,
1309
+ valuesCommaBreak: this.valuesCommaBreak,
1310
+ andBreak: this.andBreak,
1311
+ orBreak: this.orBreak,
1312
+ keywordCase: this.keywordCase,
1313
+ exportComment: 'none',
1314
+ withClauseStyle: 'standard', // Prevent recursive processing
1315
+ indentNestedParentheses: false,
1316
+ insertColumnsOneLine: this.insertColumnsOneLine,
1317
+ });
1318
+ }
1319
+ /**
1320
+ * Handles tokens with oneline formatting (parentheses, BETWEEN, VALUES, JOIN, CASE, subqueries).
1321
+ * Creates a unified oneline printer that formats everything as one line regardless of content type.
1322
+ */
1323
+ handleOnelineToken(token, level) {
1324
+ const onelinePrinter = this.createOnelinePrinter();
1325
+ const onelineResult = onelinePrinter.print(token, level);
1326
+ const cleanedResult = this.cleanDuplicateSpaces(onelineResult);
1327
+ this.linePrinter.appendText(cleanedResult);
1328
+ }
1329
+ getClauseBreakIndentLevel(parentType, level) {
1330
+ if (!parentType) {
1331
+ return level;
1332
+ }
1333
+ switch (parentType) {
1334
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause:
1335
+ // Actions under WHEN clauses should be indented one level deeper than the WHEN line.
1336
+ return level + 1;
1337
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction:
1338
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeDeleteAction:
1339
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction:
1340
+ // Keep MERGE actions and their follow-up keywords (e.g., VALUES, WHERE) aligned with the action keyword.
1341
+ return level + 1;
1342
+ default:
1343
+ return level;
1344
+ }
1345
+ }
1346
+ isMergeActionContainer(token) {
1347
+ if (!token) {
1348
+ return false;
1349
+ }
1350
+ switch (token.containerType) {
1351
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction:
1352
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeDeleteAction:
1353
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction:
1354
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeDoNothingAction:
1355
+ return true;
1356
+ default:
1357
+ return false;
1358
+ }
1359
+ }
1360
+ shouldBreakAfterOpeningParen(parentType) {
1361
+ if (!parentType) {
1362
+ return false;
1363
+ }
1364
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause ||
1365
+ parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction) {
1366
+ return !this.isInsertClauseOneline(parentType);
1367
+ }
1368
+ return false;
1369
+ }
1370
+ shouldBreakBeforeClosingParen(parentType) {
1371
+ if (!parentType) {
1372
+ return false;
1373
+ }
1374
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause ||
1375
+ parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction) {
1376
+ return !this.isInsertClauseOneline(parentType);
1377
+ }
1378
+ return false;
1379
+ }
1380
+ shouldConvertSpaceToClauseBreak(parentType, nextToken) {
1381
+ if (!parentType || !nextToken) {
1382
+ return false;
1383
+ }
1384
+ const nextKeyword = nextToken.type === SqlPrintToken_1.SqlPrintTokenType.keyword ? nextToken.text.toLowerCase() : null;
1385
+ const nextContainer = nextToken.containerType;
1386
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeQuery) {
1387
+ // Break before USING blocks and before each WHEN clause to mirror statement structure.
1388
+ if (nextKeyword === 'using') {
1389
+ return true;
1390
+ }
1391
+ if (nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause) {
1392
+ return true;
1393
+ }
1394
+ }
1395
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause) {
1396
+ // Force the action to start on the next line with additional indentation.
1397
+ if (nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction ||
1398
+ nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.MergeDeleteAction ||
1399
+ nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction ||
1400
+ nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.MergeDoNothingAction) {
1401
+ return true;
1402
+ }
1403
+ }
1404
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.UpdateQuery) {
1405
+ if (nextKeyword === 'set' || nextKeyword === 'from' || nextKeyword === 'where' || nextKeyword === 'returning') {
1406
+ return true;
1407
+ }
1408
+ }
1409
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertQuery) {
1410
+ if (nextKeyword === 'returning') {
1411
+ return true;
1412
+ }
1413
+ if (nextKeyword && (nextKeyword.startsWith('select') || nextKeyword.startsWith('values'))) {
1414
+ return true;
1415
+ }
1416
+ if (nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.ValuesQuery || nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.SimpleSelectQuery) {
1417
+ return true;
1418
+ }
1419
+ if (nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause) {
1420
+ return true;
1421
+ }
1422
+ }
1423
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.DeleteQuery) {
1424
+ if (nextKeyword === 'using' || nextKeyword === 'where' || nextKeyword === 'returning') {
1425
+ return true;
1426
+ }
1427
+ }
1428
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction || parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeDeleteAction) {
1429
+ if (nextKeyword === 'where') {
1430
+ return true;
1431
+ }
1432
+ }
1433
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction) {
1434
+ if (nextKeyword && (nextKeyword.startsWith('values') || nextKeyword === 'default values')) {
1435
+ return true;
1436
+ }
1437
+ }
1438
+ return false;
1439
+ }
1440
+ /**
1441
+ * Creates a unified SqlPrinter instance configured for oneline formatting.
1442
+ * Works for all oneline options: parentheses, BETWEEN, VALUES, JOIN, CASE, subqueries.
1443
+ * Sets all oneline options to false to prevent recursion and uses newline=' ' for actual oneline effect.
1444
+ */
1445
+ createOnelinePrinter() {
1446
+ return new SqlPrinter({
1447
+ indentChar: '',
1448
+ indentSize: 0,
1449
+ newline: ' ', // KEY: Replace all newlines with spaces - this makes everything oneline!
1450
+ commaBreak: 'none', // Disable comma-based line breaks
1451
+ cteCommaBreak: this.cteCommaBreak,
1452
+ valuesCommaBreak: 'none',
1453
+ andBreak: 'none', // Disable AND-based line breaks
1454
+ orBreak: 'none', // Disable OR-based line breaks
1455
+ keywordCase: this.keywordCase,
1456
+ exportComment: this.commentExportMode,
1457
+ commentStyle: this.commentStyle,
1458
+ withClauseStyle: 'standard',
1459
+ parenthesesOneLine: false, // Prevent recursive processing (avoid infinite loops)
1460
+ betweenOneLine: false, // Prevent recursive processing (avoid infinite loops)
1461
+ valuesOneLine: false, // Prevent recursive processing (avoid infinite loops)
1462
+ joinOneLine: false, // Prevent recursive processing (avoid infinite loops)
1463
+ caseOneLine: false, // Prevent recursive processing (avoid infinite loops)
1464
+ subqueryOneLine: false, // Prevent recursive processing (avoid infinite loops)
1465
+ indentNestedParentheses: false,
1466
+ insertColumnsOneLine: this.insertColumnsOneLine,
1467
+ });
1468
+ }
1469
+ /**
1470
+ * Removes duplicate consecutive spaces while preserving single spaces.
1471
+ * Simple and safe space normalization for CTE oneline mode.
1472
+ */
1473
+ cleanDuplicateSpaces(text) {
1474
+ return text.replace(/\s{2,}/g, ' ');
1475
+ }
1476
+ }
1477
+ exports.SqlPrinter = SqlPrinter;
1478
+ //# sourceMappingURL=SqlPrinter.js.map