@zxsylph/dbml-formatter 1.0.11 → 1.0.13
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/package.json +1 -1
- package/src/formatter/formatter.ts +55 -38
- package/src/repro_alignment.ts +33 -0
package/package.json
CHANGED
|
@@ -185,44 +185,46 @@ export function format(input: string, options: FormatterOptions = {}): string {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
// OPTIONAL: Sort Fields within groups
|
|
189
|
+
// 1. Normalize groups: Detach "Gap" (extra newlines) from content lines.
|
|
190
|
+
{
|
|
191
|
+
const normalized: Token[][] = [];
|
|
192
|
+
|
|
193
|
+
for (const line of otherLinesGroups) {
|
|
194
|
+
const last = line[line.length - 1];
|
|
195
|
+
let hasExtraNewline = false;
|
|
196
|
+
|
|
197
|
+
if (last && last.type === TokenType.Whitespace) {
|
|
198
|
+
const newlineCount = (last.value.match(/\n/g) || []).length;
|
|
199
|
+
if (newlineCount > 1) {
|
|
200
|
+
hasExtraNewline = true;
|
|
201
|
+
|
|
202
|
+
// Create stripped line (1 newline)
|
|
203
|
+
const newLineTokens = [...line];
|
|
204
|
+
newLineTokens[newLineTokens.length - 1] = {
|
|
205
|
+
...last,
|
|
206
|
+
value: '\n'
|
|
207
|
+
};
|
|
208
|
+
normalized.push(newLineTokens);
|
|
209
|
+
|
|
210
|
+
// Add spacer lines
|
|
211
|
+
for(let k=1; k < newlineCount; k++) {
|
|
212
|
+
normalized.push([{ type: TokenType.Whitespace, value: '\n', line: 0, column: 0 }]);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (!hasExtraNewline) {
|
|
218
|
+
normalized.push(line);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Replace otherLinesGroups with normalized version
|
|
223
|
+
otherLinesGroups.splice(0, otherLinesGroups.length, ...normalized);
|
|
224
|
+
}
|
|
225
|
+
|
|
188
226
|
// OPTIONAL: Sort Fields within groups
|
|
189
227
|
if (options.orderField) {
|
|
190
|
-
// 1. Normalize groups: Detach "Gap" (extra newlines) from content lines.
|
|
191
|
-
// If a line ends with > 1 newline, split it into [ContentLine] + [EmptyLine]s.
|
|
192
|
-
|
|
193
|
-
const normalized: Token[][] = [];
|
|
194
|
-
|
|
195
|
-
for (const line of otherLinesGroups) {
|
|
196
|
-
const last = line[line.length - 1];
|
|
197
|
-
let hasExtraNewline = false;
|
|
198
|
-
|
|
199
|
-
if (last && last.type === TokenType.Whitespace) {
|
|
200
|
-
const newlineCount = (last.value.match(/\n/g) || []).length;
|
|
201
|
-
if (newlineCount > 1) {
|
|
202
|
-
hasExtraNewline = true;
|
|
203
|
-
|
|
204
|
-
// Create stripped line (1 newline)
|
|
205
|
-
const newLineTokens = [...line];
|
|
206
|
-
newLineTokens[newLineTokens.length - 1] = {
|
|
207
|
-
...last,
|
|
208
|
-
value: last.value.replace(/\n+/g, '\n')
|
|
209
|
-
};
|
|
210
|
-
normalized.push(newLineTokens);
|
|
211
|
-
|
|
212
|
-
// Add spacer lines
|
|
213
|
-
for(let k=1; k < newlineCount; k++) {
|
|
214
|
-
normalized.push([{ type: TokenType.Whitespace, value: '\n', line: 0, column: 0 }]);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (!hasExtraNewline) {
|
|
220
|
-
normalized.push(line);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Replace otherLinesGroups with normalized version
|
|
225
|
-
otherLinesGroups.splice(0, otherLinesGroups.length, ...normalized);
|
|
226
228
|
|
|
227
229
|
// 2. Group lines by "is content" and Sort
|
|
228
230
|
|
|
@@ -544,8 +546,23 @@ export function format(input: string, options: FormatterOptions = {}): string {
|
|
|
544
546
|
}
|
|
545
547
|
};
|
|
546
548
|
|
|
547
|
-
// Align
|
|
548
|
-
|
|
549
|
+
// Align by grouping (split by empty lines)
|
|
550
|
+
let currentBlock: Token[][] = [];
|
|
551
|
+
for (const line of otherLinesGroups) {
|
|
552
|
+
const isWhitespace = line.every(t => t.type === TokenType.Whitespace);
|
|
553
|
+
// console.log('Line tokens:', line.map(t => t.type + ':' + JSON.stringify(t.value)), 'isWhitespace:', isWhitespace);
|
|
554
|
+
if (isWhitespace) {
|
|
555
|
+
if (currentBlock.length > 0) {
|
|
556
|
+
alignFieldBlock(currentBlock);
|
|
557
|
+
currentBlock = [];
|
|
558
|
+
}
|
|
559
|
+
} else {
|
|
560
|
+
currentBlock.push(line);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
if (currentBlock.length > 0) {
|
|
564
|
+
alignFieldBlock(currentBlock);
|
|
565
|
+
}
|
|
549
566
|
|
|
550
567
|
// 5c. Print Pass
|
|
551
568
|
for (let lgIdx = 0; lgIdx < otherLinesGroups.length; lgIdx++) {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { format } from "./formatter/formatter";
|
|
2
|
+
import * as assert from "assert";
|
|
3
|
+
|
|
4
|
+
const input = `Table users {
|
|
5
|
+
id integer
|
|
6
|
+
username varchar
|
|
7
|
+
|
|
8
|
+
email varchar
|
|
9
|
+
created_at timestamp
|
|
10
|
+
}`;
|
|
11
|
+
|
|
12
|
+
const expected = `Table users {
|
|
13
|
+
id "integer"
|
|
14
|
+
username "varchar"
|
|
15
|
+
|
|
16
|
+
email "varchar"
|
|
17
|
+
created_at "timestamp"
|
|
18
|
+
}
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
const actual = format(input);
|
|
22
|
+
|
|
23
|
+
console.log("Expected:");
|
|
24
|
+
console.log(expected);
|
|
25
|
+
console.log("Actual:");
|
|
26
|
+
console.log(actual);
|
|
27
|
+
|
|
28
|
+
if (actual === expected) {
|
|
29
|
+
console.log("Test Passed");
|
|
30
|
+
} else {
|
|
31
|
+
console.error("Test Failed");
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|