rawsql-ts 0.24.1 → 0.24.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.min.js +2 -2
- package/dist/esm/index.min.js.map +2 -2
- package/dist/esm/transformers/SqlFormatter.d.ts +7 -1
- package/dist/esm/transformers/SqlFormatter.js.map +1 -1
- package/dist/esm/transformers/SqlPrinter.d.ts +23 -2
- package/dist/esm/transformers/SqlPrinter.js +112 -28
- package/dist/esm/transformers/SqlPrinter.js.map +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +2 -2
- package/dist/src/transformers/SqlFormatter.d.ts +7 -1
- package/dist/src/transformers/SqlPrinter.d.ts +23 -2
- package/dist/transformers/SqlFormatter.js.map +1 -1
- package/dist/transformers/SqlPrinter.js +112 -28
- package/dist/transformers/SqlPrinter.js.map +1 -1
- package/dist/tsconfig.browser.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CastStyle, ConstraintStyle, SourceAliasStyle, OrderByDefaultDirectionStyle } from '../parsers/SqlPrintTokenParser';
|
|
2
|
-
import { CommaBreakStyle, AndBreakStyle, OrBreakStyle } from './SqlPrinter';
|
|
2
|
+
import { CommaBreakStyle, AndBreakStyle, OrBreakStyle, JoinOnBreakStyle } from './SqlPrinter';
|
|
3
3
|
import { CommentExportMode } from '../types/Formatting';
|
|
4
4
|
import { IndentCharOption, NewlineOption } from './LinePrinter';
|
|
5
5
|
import { IdentifierEscapeOption, IdentifierEscapeTarget } from './FormatOptionResolver';
|
|
@@ -49,6 +49,8 @@ export interface BaseFormattingOptions {
|
|
|
49
49
|
andBreak?: AndBreakStyle;
|
|
50
50
|
/** Style for OR line breaks */
|
|
51
51
|
orBreak?: OrBreakStyle;
|
|
52
|
+
/** Style for JOIN ON line breaks */
|
|
53
|
+
joinOnBreak?: JoinOnBreakStyle;
|
|
52
54
|
/** Whether to export comments in formatted output */
|
|
53
55
|
exportComment?: boolean | CommentExportMode;
|
|
54
56
|
/** Comment formatting style */
|
|
@@ -73,6 +75,10 @@ export interface BaseFormattingOptions {
|
|
|
73
75
|
insertColumnsOneLine?: boolean;
|
|
74
76
|
/** Keep MERGE WHEN clause predicates on one line regardless of AND break settings */
|
|
75
77
|
whenOneLine?: boolean;
|
|
78
|
+
/** Maximum rendered width for opt-in one-line constructs. Omit to keep legacy unlimited one-line behavior. */
|
|
79
|
+
oneLineMaxLength?: number;
|
|
80
|
+
/** Indent AND/OR continuation lines inside JOIN ON predicates */
|
|
81
|
+
joinConditionContinuationIndent?: boolean;
|
|
76
82
|
/** Reorder JOIN ON column comparisons to follow table declaration order */
|
|
77
83
|
joinConditionOrderByDeclaration?: boolean;
|
|
78
84
|
}
|
|
@@ -24,6 +24,12 @@ export type AndBreakStyle = 'none' | 'before' | 'after';
|
|
|
24
24
|
* - 'after': Line break after OR
|
|
25
25
|
*/
|
|
26
26
|
export type OrBreakStyle = 'none' | 'before' | 'after';
|
|
27
|
+
/**
|
|
28
|
+
* JoinOnBreakStyle determines whether JOIN ON starts on the JOIN line or its own indented line.
|
|
29
|
+
* - 'none': Keep ON inline with the JOIN target
|
|
30
|
+
* - 'before': Break before ON and indent the join condition
|
|
31
|
+
*/
|
|
32
|
+
export type JoinOnBreakStyle = 'none' | 'before';
|
|
27
33
|
/**
|
|
28
34
|
* Options for configuring SqlPrinter formatting behavior
|
|
29
35
|
*/
|
|
@@ -68,6 +74,8 @@ export declare class SqlPrinter {
|
|
|
68
74
|
andBreak: AndBreakStyle;
|
|
69
75
|
/** OR break style: 'none', 'before', or 'after' */
|
|
70
76
|
orBreak: OrBreakStyle;
|
|
77
|
+
/** JOIN ON break style: 'none' or 'before' */
|
|
78
|
+
joinOnBreak: JoinOnBreakStyle;
|
|
71
79
|
/** Keyword case style: 'none', 'upper' | 'lower' */
|
|
72
80
|
keywordCase: 'none' | 'upper' | 'lower';
|
|
73
81
|
/** Comment export mode controlling how comments are emitted */
|
|
@@ -98,10 +106,18 @@ export declare class SqlPrinter {
|
|
|
98
106
|
private insertColumnsOneLine;
|
|
99
107
|
/** Whether to keep MERGE WHEN predicates on a single line */
|
|
100
108
|
private whenOneLine;
|
|
109
|
+
/** Optional maximum width for opt-in one-line constructs */
|
|
110
|
+
private oneLineMaxLength?;
|
|
111
|
+
/** Whether to indent AND/OR continuation lines inside JOIN ON predicates */
|
|
112
|
+
private joinConditionContinuationIndent;
|
|
101
113
|
/** Tracks nesting depth while formatting MERGE WHEN predicate segments */
|
|
102
114
|
private mergeWhenPredicateDepth;
|
|
115
|
+
/** Tracks nesting depth while formatting JOIN ON condition segments */
|
|
116
|
+
private joinOnClauseDepth;
|
|
103
117
|
/** Shared helper for oneline-specific formatting decisions */
|
|
104
118
|
private onelineHelper;
|
|
119
|
+
/** Containers whose one-line rendering was rejected by oneLineMaxLength */
|
|
120
|
+
private expandedOneLineFallbackTokens;
|
|
105
121
|
/** Pending line comment that needs a forced newline before next token */
|
|
106
122
|
private pendingLineCommentBreak;
|
|
107
123
|
/** Accumulates lines when reconstructing multi-line block comments inside CommentBlocks */
|
|
@@ -144,6 +160,7 @@ export declare class SqlPrinter {
|
|
|
144
160
|
private handleAndOperatorToken;
|
|
145
161
|
private handleParenthesisToken;
|
|
146
162
|
private handleOrOperatorToken;
|
|
163
|
+
private getJoinConditionContinuationLevel;
|
|
147
164
|
/**
|
|
148
165
|
* Decide whether a parentheses group should increase indentation when inside nested structures.
|
|
149
166
|
* We only expand groups that contain further parentheses so simple comparisons stay compact.
|
|
@@ -209,11 +226,13 @@ export declare class SqlPrinter {
|
|
|
209
226
|
* Oneliner mode uses single spaces instead of actual newlines.
|
|
210
227
|
*/
|
|
211
228
|
private isOnelineMode;
|
|
229
|
+
private normalizeOneLineMaxLength;
|
|
230
|
+
private fitsOneLineMaxLength;
|
|
212
231
|
/**
|
|
213
232
|
* Handles CTE tokens with one-liner formatting.
|
|
214
233
|
* Creates a nested SqlPrinter instance for proper CTE oneline formatting.
|
|
215
234
|
*/
|
|
216
|
-
private
|
|
235
|
+
private tryHandleCteOnelineToken;
|
|
217
236
|
/**
|
|
218
237
|
* Creates a SqlPrinter instance configured for CTE oneline formatting.
|
|
219
238
|
*/
|
|
@@ -222,7 +241,9 @@ export declare class SqlPrinter {
|
|
|
222
241
|
* Handles tokens with oneline formatting (parentheses, BETWEEN, VALUES, JOIN, CASE, subqueries).
|
|
223
242
|
* Creates a unified oneline printer that formats everything as one line regardless of content type.
|
|
224
243
|
*/
|
|
225
|
-
private
|
|
244
|
+
private tryHandleOnelineToken;
|
|
245
|
+
private isBooleanParenExpression;
|
|
246
|
+
private containsLogicalOperator;
|
|
226
247
|
private getClauseBreakIndentLevel;
|
|
227
248
|
private isMergeActionContainer;
|
|
228
249
|
private shouldBreakAfterOpeningParen;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlFormatter.js","sourceRoot":"","sources":["../../src/transformers/SqlFormatter.ts"],"names":[],"mappings":";;;AAAA,wEAA2K;AAC3K,
|
|
1
|
+
{"version":3,"file":"SqlFormatter.js","sourceRoot":"","sources":["../../src/transformers/SqlFormatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,11 +33,15 @@ class SqlPrinter {
|
|
|
33
33
|
* @param options Optional style settings for pretty printing
|
|
34
34
|
*/
|
|
35
35
|
constructor(options) {
|
|
36
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
36
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
37
37
|
/** Track whether we are currently inside a WITH clause for full-oneline formatting */
|
|
38
38
|
this.insideWithClause = false;
|
|
39
39
|
/** Tracks nesting depth while formatting MERGE WHEN predicate segments */
|
|
40
40
|
this.mergeWhenPredicateDepth = 0;
|
|
41
|
+
/** Tracks nesting depth while formatting JOIN ON condition segments */
|
|
42
|
+
this.joinOnClauseDepth = 0;
|
|
43
|
+
/** Containers whose one-line rendering was rejected by oneLineMaxLength */
|
|
44
|
+
this.expandedOneLineFallbackTokens = new WeakSet();
|
|
41
45
|
/** Pending line comment that needs a forced newline before next token */
|
|
42
46
|
this.pendingLineCommentBreak = null;
|
|
43
47
|
/** Accumulates lines when reconstructing multi-line block comments inside CommentBlocks */
|
|
@@ -55,19 +59,22 @@ class SqlPrinter {
|
|
|
55
59
|
this.valuesCommaBreak = (_d = options === null || options === void 0 ? void 0 : options.valuesCommaBreak) !== null && _d !== void 0 ? _d : this.commaBreak;
|
|
56
60
|
this.andBreak = (_e = options === null || options === void 0 ? void 0 : options.andBreak) !== null && _e !== void 0 ? _e : 'none';
|
|
57
61
|
this.orBreak = (_f = options === null || options === void 0 ? void 0 : options.orBreak) !== null && _f !== void 0 ? _f : 'none';
|
|
58
|
-
this.
|
|
62
|
+
this.joinOnBreak = (_g = options === null || options === void 0 ? void 0 : options.joinOnBreak) !== null && _g !== void 0 ? _g : 'none';
|
|
63
|
+
this.keywordCase = (_h = options === null || options === void 0 ? void 0 : options.keywordCase) !== null && _h !== void 0 ? _h : 'none';
|
|
59
64
|
this.commentExportMode = this.resolveCommentExportMode(options === null || options === void 0 ? void 0 : options.exportComment);
|
|
60
|
-
this.withClauseStyle = (
|
|
61
|
-
this.commentStyle = (
|
|
62
|
-
this.parenthesesOneLine = (
|
|
63
|
-
this.betweenOneLine = (
|
|
64
|
-
this.valuesOneLine = (
|
|
65
|
-
this.joinOneLine = (
|
|
66
|
-
this.caseOneLine = (
|
|
67
|
-
this.subqueryOneLine = (
|
|
68
|
-
this.indentNestedParentheses = (
|
|
69
|
-
this.insertColumnsOneLine = (
|
|
70
|
-
this.whenOneLine = (
|
|
65
|
+
this.withClauseStyle = (_j = options === null || options === void 0 ? void 0 : options.withClauseStyle) !== null && _j !== void 0 ? _j : 'standard';
|
|
66
|
+
this.commentStyle = (_k = options === null || options === void 0 ? void 0 : options.commentStyle) !== null && _k !== void 0 ? _k : 'block';
|
|
67
|
+
this.parenthesesOneLine = (_l = options === null || options === void 0 ? void 0 : options.parenthesesOneLine) !== null && _l !== void 0 ? _l : false;
|
|
68
|
+
this.betweenOneLine = (_m = options === null || options === void 0 ? void 0 : options.betweenOneLine) !== null && _m !== void 0 ? _m : false;
|
|
69
|
+
this.valuesOneLine = (_o = options === null || options === void 0 ? void 0 : options.valuesOneLine) !== null && _o !== void 0 ? _o : false;
|
|
70
|
+
this.joinOneLine = (_p = options === null || options === void 0 ? void 0 : options.joinOneLine) !== null && _p !== void 0 ? _p : false;
|
|
71
|
+
this.caseOneLine = (_q = options === null || options === void 0 ? void 0 : options.caseOneLine) !== null && _q !== void 0 ? _q : false;
|
|
72
|
+
this.subqueryOneLine = (_r = options === null || options === void 0 ? void 0 : options.subqueryOneLine) !== null && _r !== void 0 ? _r : false;
|
|
73
|
+
this.indentNestedParentheses = (_s = options === null || options === void 0 ? void 0 : options.indentNestedParentheses) !== null && _s !== void 0 ? _s : false;
|
|
74
|
+
this.insertColumnsOneLine = (_t = options === null || options === void 0 ? void 0 : options.insertColumnsOneLine) !== null && _t !== void 0 ? _t : false;
|
|
75
|
+
this.whenOneLine = (_u = options === null || options === void 0 ? void 0 : options.whenOneLine) !== null && _u !== void 0 ? _u : false;
|
|
76
|
+
this.oneLineMaxLength = this.normalizeOneLineMaxLength(options === null || options === void 0 ? void 0 : options.oneLineMaxLength);
|
|
77
|
+
this.joinConditionContinuationIndent = (_v = options === null || options === void 0 ? void 0 : options.joinConditionContinuationIndent) !== null && _v !== void 0 ? _v : false;
|
|
71
78
|
const onelineOptions = {
|
|
72
79
|
parenthesesOneLine: this.parenthesesOneLine,
|
|
73
80
|
betweenOneLine: this.betweenOneLine,
|
|
@@ -81,7 +88,7 @@ class SqlPrinter {
|
|
|
81
88
|
this.onelineHelper = new OnelineFormattingHelper_1.OnelineFormattingHelper(onelineOptions);
|
|
82
89
|
this.linePrinter = new LinePrinter_1.LinePrinter(this.indentChar, this.indentSize, this.newline, this.commaBreak);
|
|
83
90
|
// Initialize
|
|
84
|
-
this.indentIncrementContainers = new Set((
|
|
91
|
+
this.indentIncrementContainers = new Set((_w = options === null || options === void 0 ? void 0 : options.indentIncrementContainerTypes) !== null && _w !== void 0 ? _w : [
|
|
85
92
|
SqlPrintToken_1.SqlPrintTokenContainerType.SelectClause,
|
|
86
93
|
SqlPrintToken_1.SqlPrintTokenContainerType.ReturningClause,
|
|
87
94
|
SqlPrintToken_1.SqlPrintTokenContainerType.FromClause,
|
|
@@ -127,8 +134,10 @@ class SqlPrinter {
|
|
|
127
134
|
// initialize
|
|
128
135
|
this.linePrinter = new LinePrinter_1.LinePrinter(this.indentChar, this.indentSize, this.newline, this.commaBreak);
|
|
129
136
|
this.insideWithClause = false; // Reset WITH clause context
|
|
137
|
+
this.joinOnClauseDepth = 0;
|
|
130
138
|
this.pendingLineCommentBreak = null;
|
|
131
139
|
this.smartCommentBlockBuilder = null;
|
|
140
|
+
this.expandedOneLineFallbackTokens = new WeakSet();
|
|
132
141
|
if (this.linePrinter.lines.length > 0 && level !== this.linePrinter.lines[0].level) {
|
|
133
142
|
this.linePrinter.lines[0].level = level;
|
|
134
143
|
}
|
|
@@ -247,7 +256,7 @@ class SqlPrinter {
|
|
|
247
256
|
const current = this.linePrinter.getCurrentLine();
|
|
248
257
|
const isCaseContext = this.isCaseContext(token.containerType);
|
|
249
258
|
const nextCaseContextDepth = isCaseContext ? caseContextDepth + 1 : caseContextDepth;
|
|
250
|
-
|
|
259
|
+
let shouldIndentNested = this.shouldIndentNestedParentheses(token, previousSiblingWasOpenParen);
|
|
251
260
|
// Handle different token types
|
|
252
261
|
if (token.type === SqlPrintToken_1.SqlPrintTokenType.keyword) {
|
|
253
262
|
this.handleKeywordToken(token, level, parentContainerType, caseContextDepth);
|
|
@@ -284,16 +293,25 @@ class SqlPrinter {
|
|
|
284
293
|
this.handleCommentNewlineToken(token, commentLevel);
|
|
285
294
|
}
|
|
286
295
|
else if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommonTable && this.withClauseStyle === 'cte-oneline') {
|
|
287
|
-
this.
|
|
288
|
-
|
|
296
|
+
if (this.tryHandleCteOnelineToken(token, level)) {
|
|
297
|
+
return; // Return early to avoid processing innerTokens
|
|
298
|
+
}
|
|
289
299
|
}
|
|
290
|
-
else if (this.shouldFormatContainerAsOneline(token, shouldIndentNested)) {
|
|
291
|
-
this.handleOnelineToken(token, level);
|
|
300
|
+
else if (this.shouldFormatContainerAsOneline(token, shouldIndentNested) && this.tryHandleOnelineToken(token, level)) {
|
|
292
301
|
return; // Return early to avoid processing innerTokens
|
|
293
302
|
}
|
|
294
303
|
else if (!this.tryAppendInsertClauseTokenText(token.text, parentContainerType)) {
|
|
295
304
|
this.linePrinter.appendText(token.text);
|
|
296
305
|
}
|
|
306
|
+
if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.JoinOnClause &&
|
|
307
|
+
this.joinOnBreak === 'before' &&
|
|
308
|
+
!this.isOnelineMode() &&
|
|
309
|
+
this.linePrinter.getCurrentLine().text.trim().length > 0) {
|
|
310
|
+
this.linePrinter.appendNewline(level + 1);
|
|
311
|
+
}
|
|
312
|
+
if (this.expandedOneLineFallbackTokens.has(token)) {
|
|
313
|
+
shouldIndentNested = true;
|
|
314
|
+
}
|
|
297
315
|
// append keyword tokens(not indented)
|
|
298
316
|
if (token.keywordTokens && token.keywordTokens.length > 0) {
|
|
299
317
|
for (let i = 0; i < token.keywordTokens.length; i++) {
|
|
@@ -307,6 +325,9 @@ class SqlPrinter {
|
|
|
307
325
|
const delayIndentNewline = shouldIndentNested && token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression;
|
|
308
326
|
const isAlterTableStatement = token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.AlterTableStatement;
|
|
309
327
|
let deferAlterTableIndent = false;
|
|
328
|
+
if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.JoinOnClause && this.joinOnBreak === 'before' && !this.isOnelineMode()) {
|
|
329
|
+
innerLevel = level + 1;
|
|
330
|
+
}
|
|
310
331
|
const alignExplainChild = this.shouldAlignExplainStatementChild(parentContainerType, token.containerType);
|
|
311
332
|
if (alignExplainChild) {
|
|
312
333
|
// Keep EXPLAIN target statements flush left so they render like standalone statements.
|
|
@@ -359,6 +380,10 @@ class SqlPrinter {
|
|
|
359
380
|
let mergePredicateActive = isMergeWhenClause;
|
|
360
381
|
let alterTableTableRendered = false;
|
|
361
382
|
let alterTableIndentInserted = false;
|
|
383
|
+
const enteredJoinOnClause = token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.JoinOnClause;
|
|
384
|
+
if (enteredJoinOnClause) {
|
|
385
|
+
this.joinOnClauseDepth++;
|
|
386
|
+
}
|
|
362
387
|
for (let i = leadingCommentCount; i < token.innerTokens.length; i++) {
|
|
363
388
|
const child = token.innerTokens[i];
|
|
364
389
|
const nextChild = token.innerTokens[i + 1];
|
|
@@ -420,6 +445,9 @@ class SqlPrinter {
|
|
|
420
445
|
if (this.smartCommentBlockBuilder && this.smartCommentBlockBuilder.mode === 'line') {
|
|
421
446
|
this.flushSmartCommentBlockBuilder();
|
|
422
447
|
}
|
|
448
|
+
if (enteredJoinOnClause) {
|
|
449
|
+
this.joinOnClauseDepth--;
|
|
450
|
+
}
|
|
423
451
|
// Exit WITH clause context when we finish processing WithClause container
|
|
424
452
|
if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.WithClause && this.withClauseStyle === 'full-oneline') {
|
|
425
453
|
this.insideWithClause = false;
|
|
@@ -620,7 +648,7 @@ class SqlPrinter {
|
|
|
620
648
|
if (this.andBreak === 'before') {
|
|
621
649
|
// Skip newline when inside WITH clause with full-oneline style
|
|
622
650
|
if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
623
|
-
this.linePrinter.appendNewline(level);
|
|
651
|
+
this.linePrinter.appendNewline(this.getJoinConditionContinuationLevel(level));
|
|
624
652
|
}
|
|
625
653
|
this.linePrinter.appendText(text);
|
|
626
654
|
}
|
|
@@ -628,7 +656,7 @@ class SqlPrinter {
|
|
|
628
656
|
this.linePrinter.appendText(text);
|
|
629
657
|
// Skip newline when inside WITH clause with full-oneline style
|
|
630
658
|
if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
631
|
-
this.linePrinter.appendNewline(level);
|
|
659
|
+
this.linePrinter.appendNewline(this.getJoinConditionContinuationLevel(level));
|
|
632
660
|
}
|
|
633
661
|
}
|
|
634
662
|
else {
|
|
@@ -647,7 +675,9 @@ class SqlPrinter {
|
|
|
647
675
|
if (this.shouldBreakAfterOpeningParen(parentContainerType)) {
|
|
648
676
|
this.linePrinter.appendNewline(level + 1);
|
|
649
677
|
}
|
|
650
|
-
else if (indentParentActive &&
|
|
678
|
+
else if (indentParentActive &&
|
|
679
|
+
parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression &&
|
|
680
|
+
!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
651
681
|
this.linePrinter.appendNewline(level);
|
|
652
682
|
}
|
|
653
683
|
}
|
|
@@ -659,7 +689,9 @@ class SqlPrinter {
|
|
|
659
689
|
this.linePrinter.appendText(token.text);
|
|
660
690
|
return;
|
|
661
691
|
}
|
|
662
|
-
if (indentParentActive &&
|
|
692
|
+
if (indentParentActive &&
|
|
693
|
+
parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression &&
|
|
694
|
+
!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
663
695
|
const closingLevel = Math.max(level - 1, 0);
|
|
664
696
|
this.linePrinter.appendNewline(closingLevel);
|
|
665
697
|
}
|
|
@@ -681,7 +713,7 @@ class SqlPrinter {
|
|
|
681
713
|
if (this.orBreak === 'before') {
|
|
682
714
|
// Insert a newline before OR unless WITH full-oneline mode suppresses breaks.
|
|
683
715
|
if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
684
|
-
this.linePrinter.appendNewline(level);
|
|
716
|
+
this.linePrinter.appendNewline(this.getJoinConditionContinuationLevel(level));
|
|
685
717
|
}
|
|
686
718
|
this.linePrinter.appendText(text);
|
|
687
719
|
}
|
|
@@ -689,13 +721,22 @@ class SqlPrinter {
|
|
|
689
721
|
this.linePrinter.appendText(text);
|
|
690
722
|
// Break after OR when multi-line formatting is active.
|
|
691
723
|
if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
692
|
-
this.linePrinter.appendNewline(level);
|
|
724
|
+
this.linePrinter.appendNewline(this.getJoinConditionContinuationLevel(level));
|
|
693
725
|
}
|
|
694
726
|
}
|
|
695
727
|
else {
|
|
696
728
|
this.linePrinter.appendText(text);
|
|
697
729
|
}
|
|
698
730
|
}
|
|
731
|
+
getJoinConditionContinuationLevel(level) {
|
|
732
|
+
if (this.joinOnClauseDepth === 0) {
|
|
733
|
+
return level;
|
|
734
|
+
}
|
|
735
|
+
if (this.joinOnBreak === 'before') {
|
|
736
|
+
return level;
|
|
737
|
+
}
|
|
738
|
+
return this.joinConditionContinuationIndent ? level + 1 : level;
|
|
739
|
+
}
|
|
699
740
|
/**
|
|
700
741
|
* Decide whether a parentheses group should increase indentation when inside nested structures.
|
|
701
742
|
* We only expand groups that contain further parentheses so simple comparisons stay compact.
|
|
@@ -707,6 +748,9 @@ class SqlPrinter {
|
|
|
707
748
|
if (token.containerType !== SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression) {
|
|
708
749
|
return false;
|
|
709
750
|
}
|
|
751
|
+
if (this.expandedOneLineFallbackTokens.has(token)) {
|
|
752
|
+
return true;
|
|
753
|
+
}
|
|
710
754
|
// Look for nested parentheses containers. If present, indent to highlight grouping.
|
|
711
755
|
return previousSiblingWasOpenParen || token.innerTokens.some((child) => this.containsParenExpression(child));
|
|
712
756
|
}
|
|
@@ -1290,16 +1334,36 @@ class SqlPrinter {
|
|
|
1290
1334
|
isOnelineMode() {
|
|
1291
1335
|
return this.newline === ' ';
|
|
1292
1336
|
}
|
|
1337
|
+
normalizeOneLineMaxLength(value) {
|
|
1338
|
+
if (value === undefined || !Number.isFinite(value) || value <= 0) {
|
|
1339
|
+
return undefined;
|
|
1340
|
+
}
|
|
1341
|
+
const normalized = Math.floor(value);
|
|
1342
|
+
return normalized > 0 ? normalized : undefined;
|
|
1343
|
+
}
|
|
1344
|
+
fitsOneLineMaxLength(text) {
|
|
1345
|
+
if (this.oneLineMaxLength === undefined) {
|
|
1346
|
+
return true;
|
|
1347
|
+
}
|
|
1348
|
+
const currentLine = this.linePrinter.getCurrentLine();
|
|
1349
|
+
const indentWidth = currentLine.level * this.indentSize * String(this.indentChar).length;
|
|
1350
|
+
return indentWidth + currentLine.text.length + text.length <= this.oneLineMaxLength;
|
|
1351
|
+
}
|
|
1293
1352
|
/**
|
|
1294
1353
|
* Handles CTE tokens with one-liner formatting.
|
|
1295
1354
|
* Creates a nested SqlPrinter instance for proper CTE oneline formatting.
|
|
1296
1355
|
*/
|
|
1297
|
-
|
|
1356
|
+
tryHandleCteOnelineToken(token, level) {
|
|
1298
1357
|
const onelinePrinter = this.createCteOnelinePrinter();
|
|
1299
1358
|
const onelineResult = onelinePrinter.print(token, level);
|
|
1300
1359
|
let cleanedResult = this.cleanDuplicateSpaces(onelineResult);
|
|
1301
1360
|
cleanedResult = cleanedResult.replace(/\(\s+/g, '(').replace(/\s+\)/g, ' )');
|
|
1302
|
-
|
|
1361
|
+
const trimmedResult = cleanedResult.trim();
|
|
1362
|
+
if (!this.fitsOneLineMaxLength(trimmedResult)) {
|
|
1363
|
+
return false;
|
|
1364
|
+
}
|
|
1365
|
+
this.linePrinter.appendText(trimmedResult);
|
|
1366
|
+
return true;
|
|
1303
1367
|
}
|
|
1304
1368
|
/**
|
|
1305
1369
|
* Creates a SqlPrinter instance configured for CTE oneline formatting.
|
|
@@ -1325,11 +1389,31 @@ class SqlPrinter {
|
|
|
1325
1389
|
* Handles tokens with oneline formatting (parentheses, BETWEEN, VALUES, JOIN, CASE, subqueries).
|
|
1326
1390
|
* Creates a unified oneline printer that formats everything as one line regardless of content type.
|
|
1327
1391
|
*/
|
|
1328
|
-
|
|
1392
|
+
tryHandleOnelineToken(token, level) {
|
|
1329
1393
|
const onelinePrinter = this.createOnelinePrinter();
|
|
1330
1394
|
const onelineResult = onelinePrinter.print(token, level);
|
|
1331
1395
|
const cleanedResult = this.cleanDuplicateSpaces(onelineResult);
|
|
1396
|
+
if (!this.fitsOneLineMaxLength(cleanedResult)) {
|
|
1397
|
+
if (this.isBooleanParenExpression(token)) {
|
|
1398
|
+
this.expandedOneLineFallbackTokens.add(token);
|
|
1399
|
+
}
|
|
1400
|
+
return false;
|
|
1401
|
+
}
|
|
1332
1402
|
this.linePrinter.appendText(cleanedResult);
|
|
1403
|
+
return true;
|
|
1404
|
+
}
|
|
1405
|
+
isBooleanParenExpression(token) {
|
|
1406
|
+
if (token.containerType !== SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression) {
|
|
1407
|
+
return false;
|
|
1408
|
+
}
|
|
1409
|
+
return this.containsLogicalOperator(token);
|
|
1410
|
+
}
|
|
1411
|
+
containsLogicalOperator(token) {
|
|
1412
|
+
if ((token.type === SqlPrintToken_1.SqlPrintTokenType.operator || token.type === SqlPrintToken_1.SqlPrintTokenType.keyword) &&
|
|
1413
|
+
['and', 'or'].includes(token.text.toLowerCase())) {
|
|
1414
|
+
return true;
|
|
1415
|
+
}
|
|
1416
|
+
return token.innerTokens.some((child) => this.containsLogicalOperator(child));
|
|
1333
1417
|
}
|
|
1334
1418
|
getClauseBreakIndentLevel(parentType, level) {
|
|
1335
1419
|
if (!parentType) {
|