rawsql-ts 0.11.42-beta → 0.11.44-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +12 -13
  2. package/dist/esm/index.js +18 -0
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/index.min.js +23 -18
  5. package/dist/esm/index.min.js.map +4 -4
  6. package/dist/esm/src/index.d.ts +18 -0
  7. package/dist/esm/src/index.js +18 -0
  8. package/dist/esm/src/index.js.map +1 -1
  9. package/dist/esm/src/models/BinarySelectQuery.d.ts +25 -1
  10. package/dist/esm/src/models/BinarySelectQuery.js +28 -0
  11. package/dist/esm/src/models/BinarySelectQuery.js.map +1 -1
  12. package/dist/esm/src/models/Clause.d.ts +14 -2
  13. package/dist/esm/src/models/Clause.js +26 -1
  14. package/dist/esm/src/models/Clause.js.map +1 -1
  15. package/dist/esm/src/models/CreateTableQuery.d.ts +99 -5
  16. package/dist/esm/src/models/CreateTableQuery.js +85 -10
  17. package/dist/esm/src/models/CreateTableQuery.js.map +1 -1
  18. package/dist/esm/src/models/DDLStatements.d.ts +157 -0
  19. package/dist/esm/src/models/DDLStatements.js +141 -0
  20. package/dist/esm/src/models/DDLStatements.js.map +1 -0
  21. package/dist/esm/src/models/DeleteQuery.d.ts +17 -0
  22. package/dist/esm/src/models/DeleteQuery.js +16 -0
  23. package/dist/esm/src/models/DeleteQuery.js.map +1 -0
  24. package/dist/esm/src/models/InsertQuery.d.ts +7 -1
  25. package/dist/esm/src/models/InsertQuery.js +6 -2
  26. package/dist/esm/src/models/InsertQuery.js.map +1 -1
  27. package/dist/esm/src/models/MergeQuery.d.ts +63 -0
  28. package/dist/esm/src/models/MergeQuery.js +94 -0
  29. package/dist/esm/src/models/MergeQuery.js.map +1 -0
  30. package/dist/esm/src/models/SelectQuery.d.ts +37 -1
  31. package/dist/esm/src/models/SelectQuery.js +4 -1
  32. package/dist/esm/src/models/SelectQuery.js.map +1 -1
  33. package/dist/esm/src/models/SimpleSelectQuery.d.ts +29 -1
  34. package/dist/esm/src/models/SimpleSelectQuery.js +32 -0
  35. package/dist/esm/src/models/SimpleSelectQuery.js.map +1 -1
  36. package/dist/esm/src/models/SqlComponent.d.ts +2 -1
  37. package/dist/esm/src/models/SqlComponent.js +1 -1
  38. package/dist/esm/src/models/SqlComponent.js.map +1 -1
  39. package/dist/esm/src/models/SqlPrintToken.d.ts +33 -0
  40. package/dist/esm/src/models/SqlPrintToken.js +32 -0
  41. package/dist/esm/src/models/SqlPrintToken.js.map +1 -1
  42. package/dist/esm/src/models/ValuesQuery.d.ts +25 -1
  43. package/dist/esm/src/models/ValuesQuery.js +28 -0
  44. package/dist/esm/src/models/ValuesQuery.js.map +1 -1
  45. package/dist/esm/src/parsers/AlterTableParser.d.ts +25 -0
  46. package/dist/esm/src/parsers/AlterTableParser.js +428 -0
  47. package/dist/esm/src/parsers/AlterTableParser.js.map +1 -0
  48. package/dist/esm/src/parsers/CreateIndexParser.d.ts +16 -0
  49. package/dist/esm/src/parsers/CreateIndexParser.js +237 -0
  50. package/dist/esm/src/parsers/CreateIndexParser.js.map +1 -0
  51. package/dist/esm/src/parsers/CreateTableParser.d.ts +41 -0
  52. package/dist/esm/src/parsers/CreateTableParser.js +734 -0
  53. package/dist/esm/src/parsers/CreateTableParser.js.map +1 -0
  54. package/dist/esm/src/parsers/DeleteClauseParser.d.ts +11 -0
  55. package/dist/esm/src/parsers/DeleteClauseParser.js +33 -0
  56. package/dist/esm/src/parsers/DeleteClauseParser.js.map +1 -0
  57. package/dist/esm/src/parsers/DeleteQueryParser.d.ts +16 -0
  58. package/dist/esm/src/parsers/DeleteQueryParser.js +73 -0
  59. package/dist/esm/src/parsers/DeleteQueryParser.js.map +1 -0
  60. package/dist/esm/src/parsers/DropConstraintParser.d.ts +12 -0
  61. package/dist/esm/src/parsers/DropConstraintParser.js +47 -0
  62. package/dist/esm/src/parsers/DropConstraintParser.js.map +1 -0
  63. package/dist/esm/src/parsers/DropIndexParser.d.ts +12 -0
  64. package/dist/esm/src/parsers/DropIndexParser.js +69 -0
  65. package/dist/esm/src/parsers/DropIndexParser.js.map +1 -0
  66. package/dist/esm/src/parsers/DropTableParser.d.ts +12 -0
  67. package/dist/esm/src/parsers/DropTableParser.js +59 -0
  68. package/dist/esm/src/parsers/DropTableParser.js.map +1 -0
  69. package/dist/esm/src/parsers/FunctionExpressionParser.d.ts +4 -0
  70. package/dist/esm/src/parsers/FunctionExpressionParser.js +25 -8
  71. package/dist/esm/src/parsers/FunctionExpressionParser.js.map +1 -1
  72. package/dist/esm/src/parsers/InsertQueryParser.js +103 -31
  73. package/dist/esm/src/parsers/InsertQueryParser.js.map +1 -1
  74. package/dist/esm/src/parsers/MergeQueryParser.d.ts +26 -0
  75. package/dist/esm/src/parsers/MergeQueryParser.js +479 -0
  76. package/dist/esm/src/parsers/MergeQueryParser.js.map +1 -0
  77. package/dist/esm/src/parsers/ReturningClauseParser.js +50 -7
  78. package/dist/esm/src/parsers/ReturningClauseParser.js.map +1 -1
  79. package/dist/esm/src/parsers/SelectClauseParser.js +3 -3
  80. package/dist/esm/src/parsers/SelectClauseParser.js.map +1 -1
  81. package/dist/esm/src/parsers/SelectQueryParser.d.ts +4 -0
  82. package/dist/esm/src/parsers/SelectQueryParser.js +4 -0
  83. package/dist/esm/src/parsers/SelectQueryParser.js.map +1 -1
  84. package/dist/esm/src/parsers/SetClauseParser.js +97 -15
  85. package/dist/esm/src/parsers/SetClauseParser.js.map +1 -1
  86. package/dist/esm/src/parsers/SqlParser.d.ts +38 -0
  87. package/dist/esm/src/parsers/SqlParser.js +344 -0
  88. package/dist/esm/src/parsers/SqlParser.js.map +1 -0
  89. package/dist/esm/src/parsers/SqlPrintTokenParser.d.ts +68 -21
  90. package/dist/esm/src/parsers/SqlPrintTokenParser.js +1145 -254
  91. package/dist/esm/src/parsers/SqlPrintTokenParser.js.map +1 -1
  92. package/dist/esm/src/parsers/SqlTokenizer.d.ts +24 -2
  93. package/dist/esm/src/parsers/SqlTokenizer.js +135 -74
  94. package/dist/esm/src/parsers/SqlTokenizer.js.map +1 -1
  95. package/dist/esm/src/parsers/UpdateQueryParser.js +11 -1
  96. package/dist/esm/src/parsers/UpdateQueryParser.js.map +1 -1
  97. package/dist/esm/src/parsers/UsingClauseParser.d.ts +11 -0
  98. package/dist/esm/src/parsers/UsingClauseParser.js +29 -0
  99. package/dist/esm/src/parsers/UsingClauseParser.js.map +1 -0
  100. package/dist/esm/src/parsers/ValueParser.js +5 -1
  101. package/dist/esm/src/parsers/ValueParser.js.map +1 -1
  102. package/dist/esm/src/parsers/ValuesQueryParser.d.ts +0 -2
  103. package/dist/esm/src/parsers/ValuesQueryParser.js +5 -45
  104. package/dist/esm/src/parsers/ValuesQueryParser.js.map +1 -1
  105. package/dist/esm/src/parsers/utils/LexemeCommentUtils.d.ts +6 -0
  106. package/dist/esm/src/parsers/utils/LexemeCommentUtils.js +26 -0
  107. package/dist/esm/src/parsers/utils/LexemeCommentUtils.js.map +1 -0
  108. package/dist/esm/src/tokenReaders/CommandTokenReader.js +49 -2
  109. package/dist/esm/src/tokenReaders/CommandTokenReader.js.map +1 -1
  110. package/dist/esm/src/tokenReaders/LiteralTokenReader.js +8 -5
  111. package/dist/esm/src/tokenReaders/LiteralTokenReader.js.map +1 -1
  112. package/dist/esm/src/tokenReaders/OperatorTokenReader.js +10 -1
  113. package/dist/esm/src/tokenReaders/OperatorTokenReader.js.map +1 -1
  114. package/dist/esm/src/tokenReaders/TypeTokenReader.js +11 -1
  115. package/dist/esm/src/tokenReaders/TypeTokenReader.js.map +1 -1
  116. package/dist/esm/src/transformers/InsertQuerySelectValuesConverter.d.ts +18 -0
  117. package/dist/esm/src/transformers/InsertQuerySelectValuesConverter.js +118 -0
  118. package/dist/esm/src/transformers/InsertQuerySelectValuesConverter.js.map +1 -0
  119. package/dist/esm/src/transformers/LinePrinter.d.ts +2 -0
  120. package/dist/esm/src/transformers/LinePrinter.js +34 -1
  121. package/dist/esm/src/transformers/LinePrinter.js.map +1 -1
  122. package/dist/esm/src/transformers/OnelineFormattingHelper.d.ts +29 -0
  123. package/dist/esm/src/transformers/OnelineFormattingHelper.js +88 -0
  124. package/dist/esm/src/transformers/OnelineFormattingHelper.js.map +1 -0
  125. package/dist/esm/src/transformers/QueryBuilder.d.ts +47 -13
  126. package/dist/esm/src/transformers/QueryBuilder.js +424 -62
  127. package/dist/esm/src/transformers/QueryBuilder.js.map +1 -1
  128. package/dist/esm/src/transformers/SqlFormatter.d.ts +13 -3
  129. package/dist/esm/src/transformers/SqlFormatter.js +13 -4
  130. package/dist/esm/src/transformers/SqlFormatter.js.map +1 -1
  131. package/dist/esm/src/transformers/SqlPrinter.d.ts +63 -10
  132. package/dist/esm/src/transformers/SqlPrinter.js +954 -64
  133. package/dist/esm/src/transformers/SqlPrinter.js.map +1 -1
  134. package/dist/esm/src/types/Formatting.d.ts +8 -0
  135. package/dist/esm/src/types/Formatting.js +2 -0
  136. package/dist/esm/src/types/Formatting.js.map +1 -0
  137. package/dist/esm/src/utils/ParserStringUtils.d.ts +6 -0
  138. package/dist/esm/src/utils/ParserStringUtils.js +28 -0
  139. package/dist/esm/src/utils/ParserStringUtils.js.map +1 -0
  140. package/dist/esm/tsconfig.browser.tsbuildinfo +1 -1
  141. package/dist/index.min.js +22 -17
  142. package/dist/index.min.js.map +4 -4
  143. package/dist/src/index.d.ts +18 -0
  144. package/dist/src/index.js +18 -0
  145. package/dist/src/index.js.map +1 -1
  146. package/dist/src/models/BinarySelectQuery.d.ts +25 -1
  147. package/dist/src/models/BinarySelectQuery.js +28 -0
  148. package/dist/src/models/BinarySelectQuery.js.map +1 -1
  149. package/dist/src/models/Clause.d.ts +14 -2
  150. package/dist/src/models/Clause.js +29 -2
  151. package/dist/src/models/Clause.js.map +1 -1
  152. package/dist/src/models/CreateTableQuery.d.ts +99 -5
  153. package/dist/src/models/CreateTableQuery.js +90 -11
  154. package/dist/src/models/CreateTableQuery.js.map +1 -1
  155. package/dist/src/models/DDLStatements.d.ts +157 -0
  156. package/dist/src/models/DDLStatements.js +153 -0
  157. package/dist/src/models/DDLStatements.js.map +1 -0
  158. package/dist/src/models/DeleteQuery.d.ts +17 -0
  159. package/dist/src/models/DeleteQuery.js +20 -0
  160. package/dist/src/models/DeleteQuery.js.map +1 -0
  161. package/dist/src/models/InsertQuery.d.ts +7 -1
  162. package/dist/src/models/InsertQuery.js +6 -2
  163. package/dist/src/models/InsertQuery.js.map +1 -1
  164. package/dist/src/models/MergeQuery.d.ts +63 -0
  165. package/dist/src/models/MergeQuery.js +104 -0
  166. package/dist/src/models/MergeQuery.js.map +1 -0
  167. package/dist/src/models/SelectQuery.d.ts +37 -1
  168. package/dist/src/models/SelectQuery.js +7 -1
  169. package/dist/src/models/SelectQuery.js.map +1 -1
  170. package/dist/src/models/SimpleSelectQuery.d.ts +29 -1
  171. package/dist/src/models/SimpleSelectQuery.js +32 -0
  172. package/dist/src/models/SimpleSelectQuery.js.map +1 -1
  173. package/dist/src/models/SqlComponent.d.ts +2 -1
  174. package/dist/src/models/SqlComponent.js +1 -1
  175. package/dist/src/models/SqlComponent.js.map +1 -1
  176. package/dist/src/models/SqlPrintToken.d.ts +33 -0
  177. package/dist/src/models/SqlPrintToken.js +32 -0
  178. package/dist/src/models/SqlPrintToken.js.map +1 -1
  179. package/dist/src/models/ValuesQuery.d.ts +25 -1
  180. package/dist/src/models/ValuesQuery.js +28 -0
  181. package/dist/src/models/ValuesQuery.js.map +1 -1
  182. package/dist/src/parsers/AlterTableParser.d.ts +25 -0
  183. package/dist/src/parsers/AlterTableParser.js +432 -0
  184. package/dist/src/parsers/AlterTableParser.js.map +1 -0
  185. package/dist/src/parsers/CreateIndexParser.d.ts +16 -0
  186. package/dist/src/parsers/CreateIndexParser.js +241 -0
  187. package/dist/src/parsers/CreateIndexParser.js.map +1 -0
  188. package/dist/src/parsers/CreateTableParser.d.ts +41 -0
  189. package/dist/src/parsers/CreateTableParser.js +738 -0
  190. package/dist/src/parsers/CreateTableParser.js.map +1 -0
  191. package/dist/src/parsers/DeleteClauseParser.d.ts +11 -0
  192. package/dist/src/parsers/DeleteClauseParser.js +37 -0
  193. package/dist/src/parsers/DeleteClauseParser.js.map +1 -0
  194. package/dist/src/parsers/DeleteQueryParser.d.ts +16 -0
  195. package/dist/src/parsers/DeleteQueryParser.js +77 -0
  196. package/dist/src/parsers/DeleteQueryParser.js.map +1 -0
  197. package/dist/src/parsers/DropConstraintParser.d.ts +12 -0
  198. package/dist/src/parsers/DropConstraintParser.js +51 -0
  199. package/dist/src/parsers/DropConstraintParser.js.map +1 -0
  200. package/dist/src/parsers/DropIndexParser.d.ts +12 -0
  201. package/dist/src/parsers/DropIndexParser.js +73 -0
  202. package/dist/src/parsers/DropIndexParser.js.map +1 -0
  203. package/dist/src/parsers/DropTableParser.d.ts +12 -0
  204. package/dist/src/parsers/DropTableParser.js +63 -0
  205. package/dist/src/parsers/DropTableParser.js.map +1 -0
  206. package/dist/src/parsers/FunctionExpressionParser.d.ts +4 -0
  207. package/dist/src/parsers/FunctionExpressionParser.js +25 -8
  208. package/dist/src/parsers/FunctionExpressionParser.js.map +1 -1
  209. package/dist/src/parsers/InsertQueryParser.js +103 -31
  210. package/dist/src/parsers/InsertQueryParser.js.map +1 -1
  211. package/dist/src/parsers/MergeQueryParser.d.ts +26 -0
  212. package/dist/src/parsers/MergeQueryParser.js +483 -0
  213. package/dist/src/parsers/MergeQueryParser.js.map +1 -0
  214. package/dist/src/parsers/ReturningClauseParser.js +50 -7
  215. package/dist/src/parsers/ReturningClauseParser.js.map +1 -1
  216. package/dist/src/parsers/SelectClauseParser.js +2 -2
  217. package/dist/src/parsers/SelectClauseParser.js.map +1 -1
  218. package/dist/src/parsers/SelectQueryParser.d.ts +4 -0
  219. package/dist/src/parsers/SelectQueryParser.js +4 -0
  220. package/dist/src/parsers/SelectQueryParser.js.map +1 -1
  221. package/dist/src/parsers/SetClauseParser.js +97 -15
  222. package/dist/src/parsers/SetClauseParser.js.map +1 -1
  223. package/dist/src/parsers/SqlParser.d.ts +38 -0
  224. package/dist/src/parsers/SqlParser.js +353 -0
  225. package/dist/src/parsers/SqlParser.js.map +1 -0
  226. package/dist/src/parsers/SqlPrintTokenParser.d.ts +68 -21
  227. package/dist/src/parsers/SqlPrintTokenParser.js +1143 -252
  228. package/dist/src/parsers/SqlPrintTokenParser.js.map +1 -1
  229. package/dist/src/parsers/SqlTokenizer.d.ts +24 -2
  230. package/dist/src/parsers/SqlTokenizer.js +139 -74
  231. package/dist/src/parsers/SqlTokenizer.js.map +1 -1
  232. package/dist/src/parsers/UpdateQueryParser.js +11 -1
  233. package/dist/src/parsers/UpdateQueryParser.js.map +1 -1
  234. package/dist/src/parsers/UsingClauseParser.d.ts +11 -0
  235. package/dist/src/parsers/UsingClauseParser.js +33 -0
  236. package/dist/src/parsers/UsingClauseParser.js.map +1 -0
  237. package/dist/src/parsers/ValueParser.js +5 -1
  238. package/dist/src/parsers/ValueParser.js.map +1 -1
  239. package/dist/src/parsers/ValuesQueryParser.d.ts +0 -2
  240. package/dist/src/parsers/ValuesQueryParser.js +5 -45
  241. package/dist/src/parsers/ValuesQueryParser.js.map +1 -1
  242. package/dist/src/parsers/utils/LexemeCommentUtils.d.ts +6 -0
  243. package/dist/src/parsers/utils/LexemeCommentUtils.js +29 -0
  244. package/dist/src/parsers/utils/LexemeCommentUtils.js.map +1 -0
  245. package/dist/src/tokenReaders/CommandTokenReader.js +49 -2
  246. package/dist/src/tokenReaders/CommandTokenReader.js.map +1 -1
  247. package/dist/src/tokenReaders/LiteralTokenReader.js +8 -5
  248. package/dist/src/tokenReaders/LiteralTokenReader.js.map +1 -1
  249. package/dist/src/tokenReaders/OperatorTokenReader.js +10 -1
  250. package/dist/src/tokenReaders/OperatorTokenReader.js.map +1 -1
  251. package/dist/src/tokenReaders/TypeTokenReader.js +11 -1
  252. package/dist/src/tokenReaders/TypeTokenReader.js.map +1 -1
  253. package/dist/src/transformers/InsertQuerySelectValuesConverter.d.ts +18 -0
  254. package/dist/src/transformers/InsertQuerySelectValuesConverter.js +122 -0
  255. package/dist/src/transformers/InsertQuerySelectValuesConverter.js.map +1 -0
  256. package/dist/src/transformers/LinePrinter.d.ts +2 -0
  257. package/dist/src/transformers/LinePrinter.js +34 -1
  258. package/dist/src/transformers/LinePrinter.js.map +1 -1
  259. package/dist/src/transformers/OnelineFormattingHelper.d.ts +29 -0
  260. package/dist/src/transformers/OnelineFormattingHelper.js +92 -0
  261. package/dist/src/transformers/OnelineFormattingHelper.js.map +1 -0
  262. package/dist/src/transformers/QueryBuilder.d.ts +47 -13
  263. package/dist/src/transformers/QueryBuilder.js +433 -60
  264. package/dist/src/transformers/QueryBuilder.js.map +1 -1
  265. package/dist/src/transformers/SqlFormatter.d.ts +13 -3
  266. package/dist/src/transformers/SqlFormatter.js +20 -6
  267. package/dist/src/transformers/SqlFormatter.js.map +1 -1
  268. package/dist/src/transformers/SqlPrinter.d.ts +63 -10
  269. package/dist/src/transformers/SqlPrinter.js +954 -64
  270. package/dist/src/transformers/SqlPrinter.js.map +1 -1
  271. package/dist/src/types/Formatting.d.ts +8 -0
  272. package/dist/src/types/Formatting.js +3 -0
  273. package/dist/src/types/Formatting.js.map +1 -0
  274. package/dist/src/utils/ParserStringUtils.d.ts +6 -0
  275. package/dist/src/utils/ParserStringUtils.js +31 -0
  276. package/dist/src/utils/ParserStringUtils.js.map +1 -0
  277. package/dist/tsconfig.tsbuildinfo +1 -1
  278. package/package.json +1 -1
@@ -4,6 +4,10 @@ exports.SqlPrinter = void 0;
4
4
  const SqlPrintToken_1 = require("../models/SqlPrintToken");
5
5
  const LinePrinter_1 = require("./LinePrinter");
6
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']);
7
11
  /**
8
12
  * SqlPrinter formats a SqlPrintToken tree into a SQL string with flexible style options.
9
13
  *
@@ -32,6 +36,12 @@ class SqlPrinter {
32
36
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
33
37
  /** Track whether we are currently inside a WITH clause for full-oneline formatting */
34
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;
35
45
  // Resolve logical options to their control character representations before applying defaults.
36
46
  const resolvedIndentChar = (0, FormatOptionResolver_1.resolveIndentCharOption)(options === null || options === void 0 ? void 0 : options.indentChar);
37
47
  const resolvedNewline = (0, FormatOptionResolver_1.resolveNewlineOption)(options === null || options === void 0 ? void 0 : options.newline);
@@ -46,17 +56,29 @@ class SqlPrinter {
46
56
  this.andBreak = (_e = options === null || options === void 0 ? void 0 : options.andBreak) !== null && _e !== void 0 ? _e : 'none';
47
57
  this.orBreak = (_f = options === null || options === void 0 ? void 0 : options.orBreak) !== null && _f !== void 0 ? _f : 'none';
48
58
  this.keywordCase = (_g = options === null || options === void 0 ? void 0 : options.keywordCase) !== null && _g !== void 0 ? _g : 'none';
49
- this.exportComment = (_h = options === null || options === void 0 ? void 0 : options.exportComment) !== null && _h !== void 0 ? _h : false;
50
- this.strictCommentPlacement = (_j = options === null || options === void 0 ? void 0 : options.strictCommentPlacement) !== null && _j !== void 0 ? _j : false;
51
- this.withClauseStyle = (_k = options === null || options === void 0 ? void 0 : options.withClauseStyle) !== null && _k !== void 0 ? _k : 'standard';
52
- this.commentStyle = (_l = options === null || options === void 0 ? void 0 : options.commentStyle) !== null && _l !== void 0 ? _l : 'block';
53
- this.parenthesesOneLine = (_m = options === null || options === void 0 ? void 0 : options.parenthesesOneLine) !== null && _m !== void 0 ? _m : false;
54
- this.betweenOneLine = (_o = options === null || options === void 0 ? void 0 : options.betweenOneLine) !== null && _o !== void 0 ? _o : false;
55
- this.valuesOneLine = (_p = options === null || options === void 0 ? void 0 : options.valuesOneLine) !== null && _p !== void 0 ? _p : false;
56
- this.joinOneLine = (_q = options === null || options === void 0 ? void 0 : options.joinOneLine) !== null && _q !== void 0 ? _q : false;
57
- this.caseOneLine = (_r = options === null || options === void 0 ? void 0 : options.caseOneLine) !== null && _r !== void 0 ? _r : false;
58
- this.subqueryOneLine = (_s = options === null || options === void 0 ? void 0 : options.subqueryOneLine) !== null && _s !== void 0 ? _s : false;
59
- this.indentNestedParentheses = (_t = options === null || options === void 0 ? void 0 : options.indentNestedParentheses) !== null && _t !== void 0 ? _t : false;
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);
60
82
  this.linePrinter = new LinePrinter_1.LinePrinter(this.indentChar, this.indentSize, this.newline, this.commaBreak);
61
83
  // Initialize
62
84
  this.indentIncrementContainers = new Set((_u = options === null || options === void 0 ? void 0 : options.indentIncrementContainerTypes) !== null && _u !== void 0 ? _u : [
@@ -79,7 +101,11 @@ class SqlPrinter {
79
101
  SqlPrintToken_1.SqlPrintTokenContainerType.CaseThenValue,
80
102
  SqlPrintToken_1.SqlPrintTokenContainerType.ElseClause,
81
103
  SqlPrintToken_1.SqlPrintTokenContainerType.CaseElseValue,
82
- SqlPrintToken_1.SqlPrintTokenContainerType.SimpleSelectQuery
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
83
109
  // Note: CommentBlock is intentionally excluded from indentIncrementContainers
84
110
  // because it serves as a grouping mechanism without affecting indentation.
85
111
  // CaseExpression, SwitchCaseArgument, CaseKeyValuePair, and ElseClause
@@ -100,13 +126,50 @@ class SqlPrinter {
100
126
  // initialize
101
127
  this.linePrinter = new LinePrinter_1.LinePrinter(this.indentChar, this.indentSize, this.newline, this.commaBreak);
102
128
  this.insideWithClause = false; // Reset WITH clause context
129
+ this.pendingLineCommentBreak = null;
130
+ this.smartCommentBlockBuilder = null;
103
131
  if (this.linePrinter.lines.length > 0 && level !== this.linePrinter.lines[0].level) {
104
132
  this.linePrinter.lines[0].level = level;
105
133
  }
106
134
  this.appendToken(token, level, undefined, 0, false);
107
135
  return this.linePrinter.print();
108
136
  }
109
- appendToken(token, level, parentContainerType, caseContextDepth = 0, indentParentActive = false) {
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) {
110
173
  // Track WITH clause context for full-oneline formatting
111
174
  const wasInsideWithClause = this.insideWithClause;
112
175
  if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.WithClause && this.withClauseStyle === 'full-oneline') {
@@ -115,6 +178,71 @@ class SqlPrinter {
115
178
  if (this.shouldSkipToken(token)) {
116
179
  return;
117
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);
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
+ }
118
246
  const current = this.linePrinter.getCurrentLine();
119
247
  const isCaseContext = this.isCaseContext(token.containerType);
120
248
  const nextCaseContextDepth = isCaseContext ? caseContextDepth + 1 : caseContextDepth;
@@ -127,7 +255,7 @@ class SqlPrinter {
127
255
  this.handleCommaToken(token, level, parentContainerType);
128
256
  }
129
257
  else if (token.type === SqlPrintToken_1.SqlPrintTokenType.parenthesis) {
130
- this.handleParenthesisToken(token, level, indentParentActive);
258
+ this.handleParenthesisToken(token, level, indentParentActive, parentContainerType);
131
259
  }
132
260
  else if (token.type === SqlPrintToken_1.SqlPrintTokenType.operator && token.text.toLowerCase() === 'and') {
133
261
  this.handleAndOperatorToken(token, level, parentContainerType, caseContextDepth);
@@ -135,37 +263,34 @@ class SqlPrinter {
135
263
  else if (token.type === SqlPrintToken_1.SqlPrintTokenType.operator && token.text.toLowerCase() === 'or') {
136
264
  this.handleOrOperatorToken(token, level, parentContainerType, caseContextDepth);
137
265
  }
138
- else if (token.containerType === "JoinClause") {
266
+ else if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.JoinClause) {
139
267
  this.handleJoinClauseToken(token, level);
140
268
  }
141
269
  else if (token.type === SqlPrintToken_1.SqlPrintTokenType.comment) {
142
- // Handle comments as regular tokens - let the standard processing handle everything
143
- if (this.exportComment) {
144
- // Note: Smart comment processing is handled at SqlPrintTokenParser level
145
- // via positioned comments system, so we don't need additional processing here
146
- this.linePrinter.appendText(token.text);
270
+ if (this.shouldRenderComment(token, effectiveCommentContext)) {
271
+ const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
272
+ this.printCommentToken(token.text, commentLevel, parentContainerType);
147
273
  }
148
274
  }
149
275
  else if (token.type === SqlPrintToken_1.SqlPrintTokenType.space) {
150
276
  this.handleSpaceToken(token, parentContainerType);
151
277
  }
152
278
  else if (token.type === SqlPrintToken_1.SqlPrintTokenType.commentNewline) {
153
- this.handleCommentNewlineToken(token, level);
279
+ if (this.whenOneLine && parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause) {
280
+ return;
281
+ }
282
+ const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
283
+ this.handleCommentNewlineToken(token, commentLevel);
154
284
  }
155
285
  else if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommonTable && this.withClauseStyle === 'cte-oneline') {
156
286
  this.handleCteOnelineToken(token, level);
157
287
  return; // Return early to avoid processing innerTokens
158
288
  }
159
- else if ((token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression && this.parenthesesOneLine && !shouldIndentNested) ||
160
- (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.BetweenExpression && this.betweenOneLine) ||
161
- (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.Values && this.valuesOneLine) ||
162
- (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.JoinOnClause && this.joinOneLine) ||
163
- (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.CaseExpression && this.caseOneLine) ||
164
- (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.InlineQuery && this.subqueryOneLine)) {
289
+ else if (this.shouldFormatContainerAsOneline(token, shouldIndentNested)) {
165
290
  this.handleOnelineToken(token, level);
166
291
  return; // Return early to avoid processing innerTokens
167
292
  }
168
- else {
293
+ else if (!this.tryAppendInsertClauseTokenText(token.text, parentContainerType)) {
169
294
  this.linePrinter.appendText(token.text);
170
295
  }
171
296
  // append keyword tokens(not indented)
@@ -179,6 +304,8 @@ class SqlPrinter {
179
304
  let increasedIndent = false;
180
305
  const shouldIncreaseIndent = this.indentIncrementContainers.has(token.containerType) || shouldIndentNested;
181
306
  const delayIndentNewline = shouldIndentNested && token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression;
307
+ const isAlterTableStatement = token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.AlterTableStatement;
308
+ let deferAlterTableIndent = false;
182
309
  if (!this.isOnelineMode() && shouldIncreaseIndent) {
183
310
  if (this.insideWithClause && this.withClauseStyle === 'full-oneline') {
184
311
  // Keep everything on one line for full-oneline WITH clauses.
@@ -188,15 +315,99 @@ class SqlPrinter {
188
315
  increasedIndent = true;
189
316
  }
190
317
  else if (current.text !== '') {
191
- innerLevel = level + 1;
318
+ if (isAlterTableStatement) {
319
+ // Delay the first line break so ALTER TABLE keeps the table name on the opening line.
320
+ innerLevel = level + 1;
321
+ increasedIndent = true;
322
+ deferAlterTableIndent = true;
323
+ }
324
+ else {
325
+ let targetIndentLevel = level + 1;
326
+ if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.SetClause &&
327
+ parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction) {
328
+ targetIndentLevel = level + 2;
329
+ }
330
+ if (this.shouldAlignCreateTableSelect(token.containerType, parentContainerType)) {
331
+ innerLevel = level;
332
+ increasedIndent = false;
333
+ this.linePrinter.appendNewline(level);
334
+ }
335
+ else {
336
+ innerLevel = targetIndentLevel;
337
+ increasedIndent = true;
338
+ this.linePrinter.appendNewline(innerLevel);
339
+ }
340
+ }
341
+ }
342
+ else if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.SetClause) {
343
+ innerLevel = parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction ? level + 2 : level + 1;
192
344
  increasedIndent = true;
193
- this.linePrinter.appendNewline(innerLevel);
345
+ current.level = innerLevel;
194
346
  }
195
347
  }
196
- for (let i = 0; i < token.innerTokens.length; i++) {
348
+ const isMergeWhenClause = this.whenOneLine && token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause;
349
+ let mergePredicateActive = isMergeWhenClause;
350
+ let alterTableTableRendered = false;
351
+ let alterTableIndentInserted = false;
352
+ for (let i = leadingCommentCount; i < token.innerTokens.length; i++) {
197
353
  const child = token.innerTokens[i];
354
+ const nextChild = token.innerTokens[i + 1];
355
+ const previousEntry = this.findPreviousSignificantToken(token.innerTokens, i);
356
+ const previousChild = previousEntry === null || previousEntry === void 0 ? void 0 : previousEntry.token;
357
+ const priorEntry = previousEntry ? this.findPreviousSignificantToken(token.innerTokens, previousEntry.index) : undefined;
358
+ const priorChild = priorEntry === null || priorEntry === void 0 ? void 0 : priorEntry.token;
359
+ const childIsAction = this.isMergeActionContainer(child);
360
+ const nextIsAction = this.isMergeActionContainer(nextChild);
361
+ const inMergePredicate = mergePredicateActive && !childIsAction;
362
+ if (isAlterTableStatement) {
363
+ if (child.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.QualifiedName) {
364
+ // Track when the table name has been printed so we can defer indentation until after it.
365
+ alterTableTableRendered = true;
366
+ }
367
+ else if (deferAlterTableIndent && alterTableTableRendered && !alterTableIndentInserted) {
368
+ if (!this.isOnelineMode()) {
369
+ this.linePrinter.appendNewline(innerLevel);
370
+ }
371
+ alterTableIndentInserted = true;
372
+ deferAlterTableIndent = false;
373
+ if (!this.isOnelineMode() && child.type === SqlPrintToken_1.SqlPrintTokenType.space) {
374
+ // Drop the space token because we already emitted a newline.
375
+ continue;
376
+ }
377
+ }
378
+ }
379
+ if (child.type === SqlPrintToken_1.SqlPrintTokenType.space) {
380
+ if (this.shouldConvertSpaceToClauseBreak(token.containerType, nextChild)) {
381
+ if (!this.isOnelineMode()) {
382
+ // Use a dedicated indent resolver so clause breaks can shift indentation for nested blocks.
383
+ const clauseBreakIndent = this.getClauseBreakIndentLevel(token.containerType, innerLevel);
384
+ this.linePrinter.appendNewline(clauseBreakIndent);
385
+ }
386
+ if (isMergeWhenClause && nextIsAction) {
387
+ mergePredicateActive = false;
388
+ }
389
+ continue;
390
+ }
391
+ this.handleSpaceToken(child, token.containerType, nextChild, previousChild, priorChild);
392
+ continue;
393
+ }
198
394
  const childIndentParentActive = token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression ? shouldIndentNested : indentParentActive;
199
- this.appendToken(child, innerLevel, token.containerType, nextCaseContextDepth, childIndentParentActive);
395
+ if (inMergePredicate) {
396
+ this.mergeWhenPredicateDepth++;
397
+ }
398
+ const childCommentContext = child.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock
399
+ ? { position: 'inline', isTopLevelContainer: containerIsTopLevel }
400
+ : undefined;
401
+ this.appendToken(child, innerLevel, token.containerType, nextCaseContextDepth, childIndentParentActive, childCommentContext);
402
+ if (inMergePredicate) {
403
+ this.mergeWhenPredicateDepth--;
404
+ }
405
+ if (childIsAction && isMergeWhenClause) {
406
+ mergePredicateActive = false;
407
+ }
408
+ }
409
+ if (this.smartCommentBlockBuilder && this.smartCommentBlockBuilder.mode === 'line') {
410
+ this.flushSmartCommentBlockBuilder();
200
411
  }
201
412
  // Exit WITH clause context when we finish processing WithClause container
202
413
  if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.WithClause && this.withClauseStyle === 'full-oneline') {
@@ -246,11 +457,13 @@ class SqlPrinter {
246
457
  }
247
458
  handleKeywordToken(token, level, parentContainerType, caseContextDepth = 0) {
248
459
  const lower = token.text.toLowerCase();
249
- if (lower === 'and' && this.andBreak !== 'none') {
460
+ if (lower === 'and' &&
461
+ (this.andBreak !== 'none' || (this.whenOneLine && parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause))) {
250
462
  this.handleAndOperatorToken(token, level, parentContainerType, caseContextDepth);
251
463
  return;
252
464
  }
253
- else if (lower === 'or' && this.orBreak !== 'none') {
465
+ else if (lower === 'or' &&
466
+ (this.orBreak !== 'none' || (this.whenOneLine && parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause))) {
254
467
  this.handleOrOperatorToken(token, level, parentContainerType, caseContextDepth);
255
468
  return;
256
469
  }
@@ -259,18 +472,50 @@ class SqlPrinter {
259
472
  this.linePrinter.appendText(text);
260
473
  return;
261
474
  }
475
+ this.ensureSpaceBeforeKeyword();
262
476
  this.linePrinter.appendText(text);
263
477
  }
478
+ ensureSpaceBeforeKeyword() {
479
+ const currentLine = this.linePrinter.getCurrentLine();
480
+ if (currentLine.text === '') {
481
+ return;
482
+ }
483
+ const lastChar = currentLine.text[currentLine.text.length - 1];
484
+ if (lastChar === '(') {
485
+ return;
486
+ }
487
+ this.ensureTrailingSpace();
488
+ }
489
+ ensureTrailingSpace() {
490
+ const currentLine = this.linePrinter.getCurrentLine();
491
+ if (currentLine.text === '') {
492
+ return;
493
+ }
494
+ if (!currentLine.text.endsWith(' ')) {
495
+ currentLine.text += ' ';
496
+ }
497
+ currentLine.text = currentLine.text.replace(/\s+$/, ' ');
498
+ }
499
+ /**
500
+ * Normalizes INSERT column list token text when one-line formatting is active.
501
+ */
502
+ tryAppendInsertClauseTokenText(text, parentContainerType) {
503
+ const currentLineText = this.linePrinter.getCurrentLine().text;
504
+ const result = this.onelineHelper.formatInsertClauseToken(text, parentContainerType, currentLineText, () => this.ensureTrailingSpace());
505
+ if (!result.handled) {
506
+ return false;
507
+ }
508
+ if (result.text) {
509
+ this.linePrinter.appendText(result.text);
510
+ }
511
+ return true;
512
+ }
264
513
  handleCommaToken(token, level, parentContainerType) {
265
514
  const text = token.text;
266
515
  const isWithinWithClause = parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.WithClause;
267
- const isWithinValuesClause = parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.Values;
268
- let effectiveCommaBreak = this.commaBreak;
269
- if (isWithinWithClause) {
270
- effectiveCommaBreak = this.cteCommaBreak;
271
- }
272
- else if (isWithinValuesClause) {
273
- effectiveCommaBreak = this.valuesCommaBreak;
516
+ let effectiveCommaBreak = this.onelineHelper.resolveCommaBreak(parentContainerType, this.commaBreak, this.cteCommaBreak, this.valuesCommaBreak);
517
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.SetClause) {
518
+ effectiveCommaBreak = 'before';
274
519
  }
275
520
  // Skip comma newlines when inside WITH clause with full-oneline style
276
521
  if (this.insideWithClause && this.withClauseStyle === 'full-oneline') {
@@ -288,6 +533,14 @@ class SqlPrinter {
288
533
  }
289
534
  if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
290
535
  this.linePrinter.appendNewline(level);
536
+ if (this.newline === ' ') {
537
+ // Remove the spacer introduced by space newlines so commas attach directly to the preceding token.
538
+ this.linePrinter.trimTrailingWhitespaceFromPreviousLine();
539
+ }
540
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause) {
541
+ // Align comma-prefixed column entries under the INSERT column indentation.
542
+ this.linePrinter.getCurrentLine().level = level + 1;
543
+ }
291
544
  }
292
545
  this.linePrinter.appendText(text);
293
546
  if (previousCommaBreak !== 'before') {
@@ -299,6 +552,9 @@ class SqlPrinter {
299
552
  if (previousCommaBreak !== 'after') {
300
553
  this.linePrinter.commaBreak = 'after';
301
554
  }
555
+ if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
556
+ this.linePrinter.appendNewline(level);
557
+ }
302
558
  this.linePrinter.appendText(text);
303
559
  if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
304
560
  this.linePrinter.appendNewline(level);
@@ -313,6 +569,9 @@ class SqlPrinter {
313
569
  this.linePrinter.commaBreak = 'none';
314
570
  }
315
571
  this.linePrinter.appendText(text);
572
+ if (this.onelineHelper.isInsertClauseOneline(parentContainerType)) {
573
+ this.ensureTrailingSpace();
574
+ }
316
575
  if (previousCommaBreak !== 'none') {
317
576
  this.linePrinter.commaBreak = previousCommaBreak;
318
577
  }
@@ -327,6 +586,11 @@ class SqlPrinter {
327
586
  this.linePrinter.appendText(text);
328
587
  return;
329
588
  }
589
+ if (this.whenOneLine &&
590
+ (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause || this.mergeWhenPredicateDepth > 0)) {
591
+ this.linePrinter.appendText(text);
592
+ return;
593
+ }
330
594
  if (this.andBreak === 'before') {
331
595
  // Skip newline when inside WITH clause with full-oneline style
332
596
  if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
@@ -345,20 +609,32 @@ class SqlPrinter {
345
609
  this.linePrinter.appendText(text);
346
610
  }
347
611
  }
348
- handleParenthesisToken(token, level, indentParentActive) {
612
+ handleParenthesisToken(token, level, indentParentActive, parentContainerType) {
349
613
  if (token.text === '(') {
350
614
  this.linePrinter.appendText(token.text);
351
- if (indentParentActive && !this.isOnelineMode()) {
352
- if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
615
+ if ((parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause ||
616
+ parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction) &&
617
+ this.insertColumnsOneLine) {
618
+ return;
619
+ }
620
+ if (!this.isOnelineMode()) {
621
+ if (this.shouldBreakAfterOpeningParen(parentContainerType)) {
622
+ this.linePrinter.appendNewline(level + 1);
623
+ }
624
+ else if (indentParentActive && !(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
353
625
  this.linePrinter.appendNewline(level);
354
626
  }
355
627
  }
356
628
  return;
357
629
  }
358
- if (token.text === ')' && indentParentActive && !this.isOnelineMode()) {
359
- // Align closing parenthesis with the outer indentation level when nested groups expand.
360
- const closingLevel = Math.max(level - 1, 0);
361
- if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
630
+ if (token.text === ')' && !this.isOnelineMode()) {
631
+ if (this.shouldBreakBeforeClosingParen(parentContainerType)) {
632
+ this.linePrinter.appendNewline(Math.max(level, 0));
633
+ this.linePrinter.appendText(token.text);
634
+ return;
635
+ }
636
+ if (indentParentActive && !(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
637
+ const closingLevel = Math.max(level - 1, 0);
362
638
  this.linePrinter.appendNewline(closingLevel);
363
639
  }
364
640
  }
@@ -371,6 +647,11 @@ class SqlPrinter {
371
647
  this.linePrinter.appendText(text);
372
648
  return;
373
649
  }
650
+ if (this.whenOneLine &&
651
+ (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause || this.mergeWhenPredicateDepth > 0)) {
652
+ this.linePrinter.appendText(text);
653
+ return;
654
+ }
374
655
  if (this.orBreak === 'before') {
375
656
  // Insert a newline before OR unless WITH full-oneline mode suppresses breaks.
376
657
  if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
@@ -420,34 +701,490 @@ class SqlPrinter {
420
701
  }
421
702
  handleJoinClauseToken(token, level) {
422
703
  const text = this.applyKeywordCase(token.text);
423
- // before join clause, add newline (skip when inside WITH clause with full-oneline style)
424
- if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
704
+ // before join clause, add newline when multiline formatting is allowed
705
+ if (this.onelineHelper.shouldInsertJoinNewline(this.insideWithClause)) {
425
706
  this.linePrinter.appendNewline(level);
426
707
  }
427
708
  this.linePrinter.appendText(text);
428
709
  }
710
+ /**
711
+ * Decides whether the current container should collapse into a single line.
712
+ */
713
+ shouldFormatContainerAsOneline(token, shouldIndentNested) {
714
+ return this.onelineHelper.shouldFormatContainer(token, shouldIndentNested);
715
+ }
716
+ /**
717
+ * Detects an INSERT column list that must stay on a single line.
718
+ */
719
+ isInsertClauseOneline(parentContainerType) {
720
+ return this.onelineHelper.isInsertClauseOneline(parentContainerType);
721
+ }
429
722
  /**
430
723
  * Handles space tokens with context-aware filtering.
431
724
  * Skips spaces in CommentBlocks when in specific CTE modes to prevent duplication.
432
725
  */
433
- handleSpaceToken(token, parentContainerType) {
434
- if (this.shouldSkipCommentBlockSpace(parentContainerType)) {
726
+ handleSpaceToken(token, parentContainerType, nextToken, previousToken, priorToken) {
727
+ if (this.smartCommentBlockBuilder && this.smartCommentBlockBuilder.mode === 'line') {
728
+ this.flushSmartCommentBlockBuilder();
729
+ }
730
+ const currentLineText = this.linePrinter.getCurrentLine().text;
731
+ if (this.onelineHelper.shouldSkipInsertClauseSpace(parentContainerType, nextToken, currentLineText)) {
732
+ return;
733
+ }
734
+ if (this.onelineHelper.shouldSkipCommentBlockSpace(parentContainerType, this.insideWithClause)) {
435
735
  const currentLine = this.linePrinter.getCurrentLine();
436
736
  if (currentLine.text !== '' && !currentLine.text.endsWith(' ')) {
437
737
  this.linePrinter.appendText(' ');
438
738
  }
439
739
  return;
440
740
  }
741
+ // Skip redundant spaces before structural parentheses in CREATE TABLE DDL.
742
+ if (this.shouldSkipSpaceBeforeParenthesis(parentContainerType, nextToken, previousToken, priorToken)) {
743
+ return;
744
+ }
441
745
  this.linePrinter.appendText(token.text);
442
746
  }
443
- /**
444
- * Determines whether to skip space tokens in CommentBlocks.
445
- * Prevents duplicate spacing in CTE full-oneline mode only.
446
- */
447
- shouldSkipCommentBlockSpace(parentContainerType) {
448
- return parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock &&
449
- this.insideWithClause &&
450
- this.withClauseStyle === 'full-oneline';
747
+ findPreviousSignificantToken(tokens, index) {
748
+ for (let i = index - 1; i >= 0; i--) {
749
+ const candidate = tokens[i];
750
+ if (candidate.type === SqlPrintToken_1.SqlPrintTokenType.space || candidate.type === SqlPrintToken_1.SqlPrintTokenType.commentNewline) {
751
+ continue;
752
+ }
753
+ if (candidate.type === SqlPrintToken_1.SqlPrintTokenType.comment && !this.rendersInlineComments()) {
754
+ continue;
755
+ }
756
+ return { token: candidate, index: i };
757
+ }
758
+ return undefined;
759
+ }
760
+ shouldSkipSpaceBeforeParenthesis(parentContainerType, nextToken, previousToken, priorToken) {
761
+ if (!nextToken || nextToken.type !== SqlPrintToken_1.SqlPrintTokenType.parenthesis || nextToken.text !== '(') {
762
+ return false;
763
+ }
764
+ if (!parentContainerType || !this.isCreateTableSpacingContext(parentContainerType)) {
765
+ return false;
766
+ }
767
+ if (!previousToken) {
768
+ return false;
769
+ }
770
+ if (this.isCreateTableNameToken(previousToken, parentContainerType)) {
771
+ return true;
772
+ }
773
+ if (this.isCreateTableConstraintKeyword(previousToken, parentContainerType)) {
774
+ return true;
775
+ }
776
+ if (priorToken && this.isCreateTableConstraintKeyword(priorToken, parentContainerType)) {
777
+ if (this.isIdentifierAttachedToConstraint(previousToken, priorToken, parentContainerType)) {
778
+ return true;
779
+ }
780
+ }
781
+ return false;
782
+ }
783
+ shouldAlignCreateTableSelect(containerType, parentContainerType) {
784
+ return containerType === SqlPrintToken_1.SqlPrintTokenContainerType.SimpleSelectQuery &&
785
+ parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.CreateTableQuery;
786
+ }
787
+ isCreateTableSpacingContext(parentContainerType) {
788
+ switch (parentContainerType) {
789
+ case SqlPrintToken_1.SqlPrintTokenContainerType.CreateTableQuery:
790
+ case SqlPrintToken_1.SqlPrintTokenContainerType.CreateTableDefinition:
791
+ case SqlPrintToken_1.SqlPrintTokenContainerType.TableConstraintDefinition:
792
+ case SqlPrintToken_1.SqlPrintTokenContainerType.ColumnConstraintDefinition:
793
+ case SqlPrintToken_1.SqlPrintTokenContainerType.ReferenceDefinition:
794
+ return true;
795
+ default:
796
+ return false;
797
+ }
798
+ }
799
+ isCreateTableNameToken(previousToken, parentContainerType) {
800
+ if (parentContainerType !== SqlPrintToken_1.SqlPrintTokenContainerType.CreateTableQuery) {
801
+ return false;
802
+ }
803
+ return previousToken.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.QualifiedName;
804
+ }
805
+ isCreateTableConstraintKeyword(token, parentContainerType) {
806
+ if (token.type !== SqlPrintToken_1.SqlPrintTokenType.keyword) {
807
+ return false;
808
+ }
809
+ const text = token.text.toLowerCase();
810
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ReferenceDefinition) {
811
+ return CREATE_TABLE_PAREN_KEYWORDS_WITH_IDENTIFIER.has(text);
812
+ }
813
+ if (CREATE_TABLE_SINGLE_PAREN_KEYWORDS.has(text)) {
814
+ return true;
815
+ }
816
+ if (CREATE_TABLE_MULTI_PAREN_KEYWORDS.has(text)) {
817
+ return true;
818
+ }
819
+ return false;
820
+ }
821
+ isIdentifierAttachedToConstraint(token, keywordToken, parentContainerType) {
822
+ if (!token) {
823
+ return false;
824
+ }
825
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ReferenceDefinition) {
826
+ return token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.QualifiedName &&
827
+ CREATE_TABLE_PAREN_KEYWORDS_WITH_IDENTIFIER.has(keywordToken.text.toLowerCase());
828
+ }
829
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.TableConstraintDefinition ||
830
+ parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ColumnConstraintDefinition) {
831
+ const normalized = keywordToken.text.toLowerCase();
832
+ if (CREATE_TABLE_SINGLE_PAREN_KEYWORDS.has(normalized) ||
833
+ CREATE_TABLE_MULTI_PAREN_KEYWORDS.has(normalized)) {
834
+ return token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.IdentifierString;
835
+ }
836
+ }
837
+ return false;
838
+ }
839
+ printCommentToken(text, level, parentContainerType) {
840
+ const trimmed = text.trim();
841
+ if (!trimmed) {
842
+ return;
843
+ }
844
+ if (this.commentStyle === 'smart' && parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock) {
845
+ if (this.handleSmartCommentBlockToken(text, trimmed, level)) {
846
+ return;
847
+ }
848
+ }
849
+ if (this.commentStyle === 'smart') {
850
+ const normalized = this.normalizeCommentForSmart(trimmed);
851
+ if (normalized.lines.length > 1 || normalized.forceBlock) {
852
+ const blockText = this.buildBlockComment(normalized.lines, level);
853
+ this.linePrinter.appendText(blockText);
854
+ }
855
+ else {
856
+ const content = normalized.lines[0];
857
+ const lineText = content ? `-- ${content}` : '--';
858
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock) {
859
+ this.linePrinter.appendText(lineText);
860
+ this.pendingLineCommentBreak = this.resolveCommentIndentLevel(level, parentContainerType);
861
+ }
862
+ else {
863
+ this.linePrinter.appendText(lineText);
864
+ const effectiveLevel = this.resolveCommentIndentLevel(level, parentContainerType);
865
+ this.linePrinter.appendNewline(effectiveLevel);
866
+ }
867
+ }
868
+ }
869
+ else {
870
+ if (trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
871
+ if (/\r?\n/.test(trimmed)) {
872
+ // Keep multi-line block comments intact by normalizing line endings once.
873
+ const newlineReplacement = this.isOnelineMode() ? ' ' : (typeof this.newline === 'string' ? this.newline : '\n');
874
+ const normalized = trimmed.replace(/\r?\n/g, newlineReplacement);
875
+ this.linePrinter.appendText(normalized);
876
+ }
877
+ else {
878
+ this.linePrinter.appendText(trimmed);
879
+ }
880
+ }
881
+ else {
882
+ this.linePrinter.appendText(trimmed);
883
+ }
884
+ if (trimmed.startsWith('--')) {
885
+ if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock) {
886
+ this.pendingLineCommentBreak = this.resolveCommentIndentLevel(level, parentContainerType);
887
+ }
888
+ else {
889
+ const effectiveLevel = this.resolveCommentIndentLevel(level, parentContainerType);
890
+ this.linePrinter.appendNewline(effectiveLevel);
891
+ }
892
+ }
893
+ }
894
+ }
895
+ handleSmartCommentBlockToken(raw, trimmed, level) {
896
+ if (!this.smartCommentBlockBuilder) {
897
+ if (trimmed === '/*') {
898
+ // Begin assembling a multi-line block comment that is emitted as split tokens
899
+ this.smartCommentBlockBuilder = { lines: [], level, mode: 'block' };
900
+ return true;
901
+ }
902
+ const lineContent = this.extractLineCommentContent(trimmed);
903
+ if (lineContent !== null) {
904
+ this.smartCommentBlockBuilder = {
905
+ lines: [lineContent],
906
+ level,
907
+ mode: 'line',
908
+ };
909
+ return true;
910
+ }
911
+ return false;
912
+ }
913
+ if (this.smartCommentBlockBuilder.mode === 'block') {
914
+ if (trimmed === '*/') {
915
+ const { lines, level: blockLevel } = this.smartCommentBlockBuilder;
916
+ const blockText = this.buildBlockComment(lines, blockLevel);
917
+ this.linePrinter.appendText(blockText);
918
+ this.pendingLineCommentBreak = blockLevel;
919
+ this.smartCommentBlockBuilder = null;
920
+ return true;
921
+ }
922
+ this.smartCommentBlockBuilder.lines.push(this.normalizeSmartBlockLine(raw));
923
+ return true;
924
+ }
925
+ const content = this.extractLineCommentContent(trimmed);
926
+ if (content !== null) {
927
+ this.smartCommentBlockBuilder.lines.push(content);
928
+ return true;
929
+ }
930
+ this.flushSmartCommentBlockBuilder();
931
+ return false;
932
+ }
933
+ handleCommentBlockContainer(token, level, context) {
934
+ var _a;
935
+ if (this.commentStyle !== 'smart') {
936
+ const rawLines = this.extractRawCommentBlockLines(token);
937
+ if (rawLines.length > 0) {
938
+ const normalizedBlocks = rawLines.map(line => `/* ${line} */`).join(' ');
939
+ const hasTrailingSpace = (_a = token.innerTokens) === null || _a === void 0 ? void 0 : _a.some(child => child.type === SqlPrintToken_1.SqlPrintTokenType.space && child.text.includes(' '));
940
+ this.linePrinter.appendText(hasTrailingSpace ? `${normalizedBlocks} ` : normalizedBlocks);
941
+ return;
942
+ }
943
+ for (const child of token.innerTokens) {
944
+ // Force inner comment tokens to render once the block is approved.
945
+ const childContext = {
946
+ position: context.position,
947
+ isTopLevelContainer: context.isTopLevelContainer,
948
+ forceRender: true,
949
+ };
950
+ this.appendToken(child, level, token.containerType, 0, false, childContext);
951
+ }
952
+ return;
953
+ }
954
+ const lines = this.collectCommentBlockLines(token);
955
+ if (lines.length === 0 && !this.smartCommentBlockBuilder) {
956
+ // No meaningful content; treat as empty line comment to preserve spacing
957
+ this.smartCommentBlockBuilder = {
958
+ lines: [''],
959
+ level,
960
+ mode: 'line',
961
+ };
962
+ return;
963
+ }
964
+ if (!this.smartCommentBlockBuilder || this.smartCommentBlockBuilder.mode !== 'line') {
965
+ this.smartCommentBlockBuilder = {
966
+ lines: [...lines],
967
+ level,
968
+ mode: 'line',
969
+ };
970
+ }
971
+ else {
972
+ this.smartCommentBlockBuilder.lines.push(...lines);
973
+ }
974
+ }
975
+ normalizeSmartBlockLine(raw) {
976
+ // Remove trailing whitespace that only carries formatting artifacts
977
+ let line = raw.replace(/\s+$/g, '');
978
+ if (!line) {
979
+ return '';
980
+ }
981
+ if (line.startsWith(' ')) {
982
+ line = line.slice(2);
983
+ }
984
+ if (line.startsWith('* ')) {
985
+ return line.slice(2);
986
+ }
987
+ if (line === '*') {
988
+ return '';
989
+ }
990
+ if (line.startsWith('*')) {
991
+ return line.slice(1);
992
+ }
993
+ return line;
994
+ }
995
+ extractLineCommentContent(trimmed) {
996
+ if (trimmed.startsWith('--')) {
997
+ return trimmed.slice(2).trimStart();
998
+ }
999
+ if (trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
1000
+ const inner = trimmed.slice(2, -2).trim();
1001
+ return inner;
1002
+ }
1003
+ return null;
1004
+ }
1005
+ flushSmartCommentBlockBuilder() {
1006
+ var _a;
1007
+ if (!this.smartCommentBlockBuilder) {
1008
+ return;
1009
+ }
1010
+ const { lines, level, mode } = this.smartCommentBlockBuilder;
1011
+ if (mode === 'line') {
1012
+ const meaningfulLineCount = lines.filter(line => line.trim() !== '').length;
1013
+ if (meaningfulLineCount > 1) {
1014
+ const blockText = this.buildBlockComment(lines, level);
1015
+ this.linePrinter.appendText(blockText);
1016
+ }
1017
+ else {
1018
+ const content = (_a = lines[0]) !== null && _a !== void 0 ? _a : '';
1019
+ const lineText = content ? `-- ${content}` : '--';
1020
+ this.linePrinter.appendText(lineText);
1021
+ }
1022
+ if (!this.isOnelineMode()) {
1023
+ this.linePrinter.appendNewline(level);
1024
+ }
1025
+ this.pendingLineCommentBreak = null;
1026
+ }
1027
+ this.smartCommentBlockBuilder = null;
1028
+ }
1029
+ collectCommentBlockLines(token) {
1030
+ var _a;
1031
+ const lines = [];
1032
+ let collectingBlock = false;
1033
+ for (const child of (_a = token.innerTokens) !== null && _a !== void 0 ? _a : []) {
1034
+ if (child.type === SqlPrintToken_1.SqlPrintTokenType.comment) {
1035
+ const trimmed = child.text.trim();
1036
+ if (trimmed === '/*') {
1037
+ collectingBlock = true;
1038
+ continue;
1039
+ }
1040
+ if (trimmed === '*/') {
1041
+ collectingBlock = false;
1042
+ continue;
1043
+ }
1044
+ if (collectingBlock) {
1045
+ lines.push(this.normalizeSmartBlockLine(child.text));
1046
+ continue;
1047
+ }
1048
+ const content = this.extractLineCommentContent(trimmed);
1049
+ if (content !== null) {
1050
+ lines.push(content);
1051
+ }
1052
+ }
1053
+ }
1054
+ return lines;
1055
+ }
1056
+ extractRawCommentBlockLines(token) {
1057
+ var _a;
1058
+ const lines = [];
1059
+ let collectingBlock = false;
1060
+ for (const child of (_a = token.innerTokens) !== null && _a !== void 0 ? _a : []) {
1061
+ if (child.type === SqlPrintToken_1.SqlPrintTokenType.comment) {
1062
+ const text = child.text;
1063
+ const trimmed = text.trim();
1064
+ if (trimmed === '/*') {
1065
+ collectingBlock = true;
1066
+ continue;
1067
+ }
1068
+ if (trimmed === '*/') {
1069
+ collectingBlock = false;
1070
+ continue;
1071
+ }
1072
+ if (collectingBlock) {
1073
+ if (trimmed.length > 0) {
1074
+ lines.push(trimmed);
1075
+ }
1076
+ continue;
1077
+ }
1078
+ }
1079
+ }
1080
+ return lines;
1081
+ }
1082
+ normalizeCommentForSmart(text) {
1083
+ const trimmed = text.trim();
1084
+ let source = trimmed;
1085
+ let forceBlock = false;
1086
+ if (trimmed.startsWith('--')) {
1087
+ source = trimmed.slice(2);
1088
+ }
1089
+ else if (trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
1090
+ const inner = trimmed.slice(2, -2);
1091
+ const normalizedInner = inner.replace(/\r?\n/g, '\n');
1092
+ if (normalizedInner.includes('\n')) {
1093
+ forceBlock = true;
1094
+ source = inner;
1095
+ }
1096
+ else {
1097
+ source = inner;
1098
+ if (!source.trim()) {
1099
+ source = trimmed;
1100
+ }
1101
+ }
1102
+ }
1103
+ const escaped = this.escapeCommentDelimiters(source);
1104
+ const normalized = escaped.replace(/\r?\n/g, '\n');
1105
+ const rawSegments = normalized.split('\n');
1106
+ const processedLines = [];
1107
+ const processedRaw = [];
1108
+ for (const segment of rawSegments) {
1109
+ const rawTrimmed = segment.trim();
1110
+ const sanitized = this.sanitizeCommentLine(segment);
1111
+ if (sanitized.length > 0) {
1112
+ processedLines.push(sanitized);
1113
+ processedRaw.push(rawTrimmed);
1114
+ }
1115
+ }
1116
+ let lines = processedLines;
1117
+ if (lines.length === 0) {
1118
+ lines = [''];
1119
+ }
1120
+ if (!forceBlock && lines.length === 1 && !lines[0] && trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
1121
+ const escapedFull = this.escapeCommentDelimiters(trimmed);
1122
+ lines = [this.sanitizeCommentLine(escapedFull)];
1123
+ }
1124
+ if (!forceBlock && lines.length > 1) {
1125
+ forceBlock = true;
1126
+ }
1127
+ lines = lines.map((line, index) => {
1128
+ var _a;
1129
+ if (/^[-=_+*#]+$/.test(line)) {
1130
+ const rawLine = (_a = processedRaw[index]) !== null && _a !== void 0 ? _a : line;
1131
+ const normalizedRaw = rawLine.replace(/\s+/g, '');
1132
+ if (normalizedRaw.length >= line.length) {
1133
+ return normalizedRaw;
1134
+ }
1135
+ }
1136
+ return line;
1137
+ });
1138
+ return { lines, forceBlock };
1139
+ }
1140
+ buildBlockComment(lines, level) {
1141
+ var _a, _b, _c;
1142
+ if (lines.length <= 1) {
1143
+ const content = (_a = lines[0]) !== null && _a !== void 0 ? _a : '';
1144
+ return content ? `/* ${content} */` : '/* */';
1145
+ }
1146
+ const newline = this.newline === ' ' ? '\n' : this.newline;
1147
+ const currentLevel = (_c = (_b = this.linePrinter.getCurrentLine()) === null || _b === void 0 ? void 0 : _b.level) !== null && _c !== void 0 ? _c : level;
1148
+ const baseIndent = this.getIndentString(currentLevel);
1149
+ const unitIndent = ' ';
1150
+ const innerIndent = baseIndent + unitIndent;
1151
+ const body = lines.map(line => `${innerIndent}${line}`).join(newline);
1152
+ const closing = `${baseIndent}*/`;
1153
+ return `/*${newline}${body}${newline}${closing}`;
1154
+ }
1155
+ getIndentString(level) {
1156
+ if (level <= 0) {
1157
+ return '';
1158
+ }
1159
+ if (this.indentSize <= 0) {
1160
+ return ' '.repeat(level);
1161
+ }
1162
+ const unit = typeof this.indentChar === 'string' ? this.indentChar : '';
1163
+ return unit.repeat(this.indentSize * level);
1164
+ }
1165
+ sanitizeCommentLine(content) {
1166
+ let sanitized = content;
1167
+ sanitized = sanitized.replace(/\u2028|\u2029/g, ' ');
1168
+ sanitized = sanitized.replace(/\s+/g, ' ').trim();
1169
+ return sanitized;
1170
+ }
1171
+ escapeCommentDelimiters(content) {
1172
+ return content
1173
+ .replace(/\/\*/g, '\\/\\*')
1174
+ .replace(/\*\//g, '*\\/');
1175
+ }
1176
+ getCommentBaseIndentLevel(level, parentContainerType) {
1177
+ if (!parentContainerType) {
1178
+ return level;
1179
+ }
1180
+ const clauseAlignedLevel = this.getClauseBreakIndentLevel(parentContainerType, level);
1181
+ return Math.max(level, clauseAlignedLevel);
1182
+ }
1183
+ resolveCommentIndentLevel(level, parentContainerType) {
1184
+ var _a;
1185
+ const baseLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
1186
+ const currentLevel = (_a = this.linePrinter.getCurrentLine().level) !== null && _a !== void 0 ? _a : baseLevel;
1187
+ return Math.max(baseLevel, currentLevel);
451
1188
  }
452
1189
  /**
453
1190
  * Handles commentNewline tokens with conditional newline behavior.
@@ -456,6 +1193,14 @@ class SqlPrinter {
456
1193
  * Skips newlines in CTE modes (full-oneline, cte-oneline) to maintain one-line format.
457
1194
  */
458
1195
  handleCommentNewlineToken(token, level) {
1196
+ if (this.smartCommentBlockBuilder) {
1197
+ return;
1198
+ }
1199
+ if (this.pendingLineCommentBreak !== null) {
1200
+ this.linePrinter.appendNewline(this.pendingLineCommentBreak);
1201
+ this.pendingLineCommentBreak = null;
1202
+ return;
1203
+ }
459
1204
  if (this.shouldSkipCommentNewline()) {
460
1205
  return;
461
1206
  }
@@ -471,6 +1216,39 @@ class SqlPrinter {
471
1216
  return (this.insideWithClause && this.withClauseStyle === 'full-oneline') ||
472
1217
  this.withClauseStyle === 'cte-oneline';
473
1218
  }
1219
+ shouldAddNewlineBeforeLeadingComments(parentType) {
1220
+ if (!parentType) {
1221
+ return false;
1222
+ }
1223
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.TupleExpression) {
1224
+ return true;
1225
+ }
1226
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause ||
1227
+ parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction) {
1228
+ return !this.insertColumnsOneLine;
1229
+ }
1230
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.SetClause) {
1231
+ return true;
1232
+ }
1233
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.SelectClause) {
1234
+ return true;
1235
+ }
1236
+ return false;
1237
+ }
1238
+ getLeadingCommentIndentLevel(parentType, currentLevel) {
1239
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.TupleExpression) {
1240
+ return currentLevel + 1;
1241
+ }
1242
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause ||
1243
+ parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction ||
1244
+ parentType === SqlPrintToken_1.SqlPrintTokenContainerType.SelectClause) {
1245
+ return currentLevel + 1;
1246
+ }
1247
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.SetClause) {
1248
+ return currentLevel + 1;
1249
+ }
1250
+ return currentLevel;
1251
+ }
474
1252
  /**
475
1253
  * Determines if the printer is in oneliner mode.
476
1254
  * Oneliner mode uses single spaces instead of actual newlines.
@@ -503,10 +1281,10 @@ class SqlPrinter {
503
1281
  andBreak: this.andBreak,
504
1282
  orBreak: this.orBreak,
505
1283
  keywordCase: this.keywordCase,
506
- exportComment: false,
507
- strictCommentPlacement: this.strictCommentPlacement,
1284
+ exportComment: 'none',
508
1285
  withClauseStyle: 'standard', // Prevent recursive processing
509
1286
  indentNestedParentheses: false,
1287
+ insertColumnsOneLine: this.insertColumnsOneLine,
510
1288
  });
511
1289
  }
512
1290
  /**
@@ -519,6 +1297,117 @@ class SqlPrinter {
519
1297
  const cleanedResult = this.cleanDuplicateSpaces(onelineResult);
520
1298
  this.linePrinter.appendText(cleanedResult);
521
1299
  }
1300
+ getClauseBreakIndentLevel(parentType, level) {
1301
+ if (!parentType) {
1302
+ return level;
1303
+ }
1304
+ switch (parentType) {
1305
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause:
1306
+ // Actions under WHEN clauses should be indented one level deeper than the WHEN line.
1307
+ return level + 1;
1308
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction:
1309
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeDeleteAction:
1310
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction:
1311
+ // Keep MERGE actions and their follow-up keywords (e.g., VALUES, WHERE) aligned with the action keyword.
1312
+ return level + 1;
1313
+ default:
1314
+ return level;
1315
+ }
1316
+ }
1317
+ isMergeActionContainer(token) {
1318
+ if (!token) {
1319
+ return false;
1320
+ }
1321
+ switch (token.containerType) {
1322
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction:
1323
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeDeleteAction:
1324
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction:
1325
+ case SqlPrintToken_1.SqlPrintTokenContainerType.MergeDoNothingAction:
1326
+ return true;
1327
+ default:
1328
+ return false;
1329
+ }
1330
+ }
1331
+ shouldBreakAfterOpeningParen(parentType) {
1332
+ if (!parentType) {
1333
+ return false;
1334
+ }
1335
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause ||
1336
+ parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction) {
1337
+ return !this.isInsertClauseOneline(parentType);
1338
+ }
1339
+ return false;
1340
+ }
1341
+ shouldBreakBeforeClosingParen(parentType) {
1342
+ if (!parentType) {
1343
+ return false;
1344
+ }
1345
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause ||
1346
+ parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction) {
1347
+ return !this.isInsertClauseOneline(parentType);
1348
+ }
1349
+ return false;
1350
+ }
1351
+ shouldConvertSpaceToClauseBreak(parentType, nextToken) {
1352
+ if (!parentType || !nextToken) {
1353
+ return false;
1354
+ }
1355
+ const nextKeyword = nextToken.type === SqlPrintToken_1.SqlPrintTokenType.keyword ? nextToken.text.toLowerCase() : null;
1356
+ const nextContainer = nextToken.containerType;
1357
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeQuery) {
1358
+ // Break before USING blocks and before each WHEN clause to mirror statement structure.
1359
+ if (nextKeyword === 'using') {
1360
+ return true;
1361
+ }
1362
+ if (nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause) {
1363
+ return true;
1364
+ }
1365
+ }
1366
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeWhenClause) {
1367
+ // Force the action to start on the next line with additional indentation.
1368
+ if (nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction ||
1369
+ nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.MergeDeleteAction ||
1370
+ nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction ||
1371
+ nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.MergeDoNothingAction) {
1372
+ return true;
1373
+ }
1374
+ }
1375
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.UpdateQuery) {
1376
+ if (nextKeyword === 'set' || nextKeyword === 'from' || nextKeyword === 'where' || nextKeyword === 'returning') {
1377
+ return true;
1378
+ }
1379
+ }
1380
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertQuery) {
1381
+ if (nextKeyword === 'returning') {
1382
+ return true;
1383
+ }
1384
+ if (nextKeyword && (nextKeyword.startsWith('select') || nextKeyword.startsWith('values'))) {
1385
+ return true;
1386
+ }
1387
+ if (nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.ValuesQuery || nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.SimpleSelectQuery) {
1388
+ return true;
1389
+ }
1390
+ if (nextContainer === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause) {
1391
+ return true;
1392
+ }
1393
+ }
1394
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.DeleteQuery) {
1395
+ if (nextKeyword === 'using' || nextKeyword === 'where' || nextKeyword === 'returning') {
1396
+ return true;
1397
+ }
1398
+ }
1399
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeUpdateAction || parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeDeleteAction) {
1400
+ if (nextKeyword === 'where') {
1401
+ return true;
1402
+ }
1403
+ }
1404
+ if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction) {
1405
+ if (nextKeyword && (nextKeyword.startsWith('values') || nextKeyword === 'default values')) {
1406
+ return true;
1407
+ }
1408
+ }
1409
+ return false;
1410
+ }
522
1411
  /**
523
1412
  * Creates a unified SqlPrinter instance configured for oneline formatting.
524
1413
  * Works for all oneline options: parentheses, BETWEEN, VALUES, JOIN, CASE, subqueries.
@@ -535,8 +1424,8 @@ class SqlPrinter {
535
1424
  andBreak: 'none', // Disable AND-based line breaks
536
1425
  orBreak: 'none', // Disable OR-based line breaks
537
1426
  keywordCase: this.keywordCase,
538
- exportComment: this.exportComment,
539
- strictCommentPlacement: this.strictCommentPlacement,
1427
+ exportComment: this.commentExportMode,
1428
+ commentStyle: this.commentStyle,
540
1429
  withClauseStyle: 'standard',
541
1430
  parenthesesOneLine: false, // Prevent recursive processing (avoid infinite loops)
542
1431
  betweenOneLine: false, // Prevent recursive processing (avoid infinite loops)
@@ -545,6 +1434,7 @@ class SqlPrinter {
545
1434
  caseOneLine: false, // Prevent recursive processing (avoid infinite loops)
546
1435
  subqueryOneLine: false, // Prevent recursive processing (avoid infinite loops)
547
1436
  indentNestedParentheses: false,
1437
+ insertColumnsOneLine: this.insertColumnsOneLine,
548
1438
  });
549
1439
  }
550
1440
  /**