@duckcodeailabs/dql-core 0.10.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/format/diff.d.ts +46 -0
- package/dist/format/diff.d.ts.map +1 -0
- package/dist/format/diff.js +231 -0
- package/dist/format/diff.js.map +1 -0
- package/dist/format/index.d.ts +29 -0
- package/dist/format/index.d.ts.map +1 -0
- package/dist/format/index.js +74 -0
- package/dist/format/index.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ProgramNode } from '../ast/nodes.js';
|
|
2
|
+
export type DiffChange = {
|
|
3
|
+
kind: 'block-added';
|
|
4
|
+
name: string;
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'block-removed';
|
|
7
|
+
name: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'block-changed';
|
|
10
|
+
name: string;
|
|
11
|
+
fields: FieldChange[];
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'dashboard-added';
|
|
14
|
+
title: string;
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'dashboard-removed';
|
|
17
|
+
title: string;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'dashboard-changed';
|
|
20
|
+
title: string;
|
|
21
|
+
fields: FieldChange[];
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'workbook-added';
|
|
24
|
+
title: string;
|
|
25
|
+
} | {
|
|
26
|
+
kind: 'workbook-removed';
|
|
27
|
+
title: string;
|
|
28
|
+
} | {
|
|
29
|
+
kind: 'workbook-changed';
|
|
30
|
+
title: string;
|
|
31
|
+
fields: FieldChange[];
|
|
32
|
+
};
|
|
33
|
+
export interface FieldChange {
|
|
34
|
+
path: string;
|
|
35
|
+
before: string | null;
|
|
36
|
+
after: string | null;
|
|
37
|
+
}
|
|
38
|
+
export interface DiffReport {
|
|
39
|
+
changes: DiffChange[];
|
|
40
|
+
/** True when `before` and `after` are semantically identical at the AST level. */
|
|
41
|
+
identical: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare function diffDQL(beforeSource: string, afterSource: string): DiffReport;
|
|
44
|
+
export declare function diffProgram(before: ProgramNode, after: ProgramNode): DiffReport;
|
|
45
|
+
export declare function renderDiffText(report: DiffReport): string;
|
|
46
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/format/diff.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAOV,WAAW,EAGZ,MAAM,iBAAiB,CAAC;AAGzB,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC;AAEvE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,kFAAkF;IAClF,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,UAAU,CAE7E;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,GAAG,UAAU,CAqC/E;AA2JD,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAsCzD"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
// v0.11 semantic diff for `.dql` files.
|
|
2
|
+
//
|
|
3
|
+
// `diffProgram` compares two parsed programs by top-level identity
|
|
4
|
+
// (block name, dashboard title, workbook title) and returns a structured
|
|
5
|
+
// report of added / removed / changed entities. For changed entities we
|
|
6
|
+
// descend into the properties that actually matter for review: SQL query,
|
|
7
|
+
// parameters, visualization, tests, tags, metadata.
|
|
8
|
+
//
|
|
9
|
+
// The output is intentionally lossy relative to a textual diff — it's
|
|
10
|
+
// meant to answer "what changed *semantically*?", not "which bytes moved".
|
|
11
|
+
import { parse } from '../parser/parser.js';
|
|
12
|
+
import { NodeKind } from '../ast/nodes.js';
|
|
13
|
+
import { formatProgram } from '../formatter/formatter.js';
|
|
14
|
+
export function diffDQL(beforeSource, afterSource) {
|
|
15
|
+
return diffProgram(parse(beforeSource), parse(afterSource));
|
|
16
|
+
}
|
|
17
|
+
export function diffProgram(before, after) {
|
|
18
|
+
const changes = [];
|
|
19
|
+
const beforeBlocks = indexBy(before.statements.filter(isBlock), (b) => b.name);
|
|
20
|
+
const afterBlocks = indexBy(after.statements.filter(isBlock), (b) => b.name);
|
|
21
|
+
diffKeyed(beforeBlocks, afterBlocks, {
|
|
22
|
+
onAdded: (name) => changes.push({ kind: 'block-added', name }),
|
|
23
|
+
onRemoved: (name) => changes.push({ kind: 'block-removed', name }),
|
|
24
|
+
onChanged: (name, a, b) => {
|
|
25
|
+
const fields = diffBlock(a, b);
|
|
26
|
+
if (fields.length > 0)
|
|
27
|
+
changes.push({ kind: 'block-changed', name, fields });
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
const beforeDashboards = indexBy(before.statements.filter(isDashboard), (d) => d.title);
|
|
31
|
+
const afterDashboards = indexBy(after.statements.filter(isDashboard), (d) => d.title);
|
|
32
|
+
diffKeyed(beforeDashboards, afterDashboards, {
|
|
33
|
+
onAdded: (title) => changes.push({ kind: 'dashboard-added', title }),
|
|
34
|
+
onRemoved: (title) => changes.push({ kind: 'dashboard-removed', title }),
|
|
35
|
+
onChanged: (title, a, b) => {
|
|
36
|
+
const fields = diffDashboard(a, b);
|
|
37
|
+
if (fields.length > 0)
|
|
38
|
+
changes.push({ kind: 'dashboard-changed', title, fields });
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
const beforeWorkbooks = indexBy(before.statements.filter(isWorkbook), (w) => w.title);
|
|
42
|
+
const afterWorkbooks = indexBy(after.statements.filter(isWorkbook), (w) => w.title);
|
|
43
|
+
diffKeyed(beforeWorkbooks, afterWorkbooks, {
|
|
44
|
+
onAdded: (title) => changes.push({ kind: 'workbook-added', title }),
|
|
45
|
+
onRemoved: (title) => changes.push({ kind: 'workbook-removed', title }),
|
|
46
|
+
onChanged: (title, a, b) => {
|
|
47
|
+
const fields = diffWorkbook(a, b);
|
|
48
|
+
if (fields.length > 0)
|
|
49
|
+
changes.push({ kind: 'workbook-changed', title, fields });
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
return { changes, identical: changes.length === 0 };
|
|
53
|
+
}
|
|
54
|
+
// ---- Block ----
|
|
55
|
+
function diffBlock(a, b) {
|
|
56
|
+
const out = [];
|
|
57
|
+
scalar(out, 'domain', a.domain, b.domain);
|
|
58
|
+
scalar(out, 'type', a.blockType, b.blockType);
|
|
59
|
+
scalar(out, 'description', a.description, b.description);
|
|
60
|
+
scalar(out, 'owner', a.owner, b.owner);
|
|
61
|
+
scalar(out, 'tags', a.tags?.join(', '), b.tags?.join(', '));
|
|
62
|
+
scalar(out, 'metricRef', a.metricRef, b.metricRef);
|
|
63
|
+
scalar(out, 'metricsRef', a.metricsRef?.join(', '), b.metricsRef?.join(', '));
|
|
64
|
+
scalar(out, 'query', normalizeSQL(a.query?.rawSQL), normalizeSQL(b.query?.rawSQL));
|
|
65
|
+
diffParams(out, a.params?.params ?? [], b.params?.params ?? []);
|
|
66
|
+
diffNamedArgs(out, 'visualization', a.visualization?.properties ?? [], b.visualization?.properties ?? []);
|
|
67
|
+
diffTests(out, a.tests ?? [], b.tests ?? []);
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
function diffParams(out, a, b) {
|
|
71
|
+
const am = new Map(a.map((p) => [p.name, formatExpr(p.initializer)]));
|
|
72
|
+
const bm = new Map(b.map((p) => [p.name, formatExpr(p.initializer)]));
|
|
73
|
+
for (const name of union(am, bm)) {
|
|
74
|
+
scalar(out, `params.${name}`, am.get(name), bm.get(name));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function diffNamedArgs(out, prefix, a, b) {
|
|
78
|
+
const am = new Map(a.map((p) => [p.name, formatExpr(p.value)]));
|
|
79
|
+
const bm = new Map(b.map((p) => [p.name, formatExpr(p.value)]));
|
|
80
|
+
for (const name of union(am, bm)) {
|
|
81
|
+
scalar(out, `${prefix}.${name}`, am.get(name), bm.get(name));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function diffTests(out, a, b) {
|
|
85
|
+
const key = (t) => `${t.field} ${t.operator}`;
|
|
86
|
+
const am = new Map(a.map((t) => [key(t), formatExpr(t.expected)]));
|
|
87
|
+
const bm = new Map(b.map((t) => [key(t), formatExpr(t.expected)]));
|
|
88
|
+
for (const k of union(am, bm)) {
|
|
89
|
+
scalar(out, `tests[${k}]`, am.get(k), bm.get(k));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// ---- Dashboard / Workbook ----
|
|
93
|
+
// For dashboards/workbooks we reduce the body to its formatted text and
|
|
94
|
+
// diff that as a single field; an AST-level diff of charts/filters/layouts
|
|
95
|
+
// is possible but pays off less than block-level diffing.
|
|
96
|
+
function diffDashboard(a, b) {
|
|
97
|
+
const out = [];
|
|
98
|
+
scalar(out, 'body', formatBody(a), formatBody(b));
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
function diffWorkbook(a, b) {
|
|
102
|
+
const out = [];
|
|
103
|
+
scalar(out, 'body', formatBody(a), formatBody(b));
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
function formatBody(node) {
|
|
107
|
+
const program = {
|
|
108
|
+
kind: NodeKind.Program,
|
|
109
|
+
span: node.span,
|
|
110
|
+
statements: [node],
|
|
111
|
+
};
|
|
112
|
+
return formatProgram(program);
|
|
113
|
+
}
|
|
114
|
+
// ---- Helpers ----
|
|
115
|
+
function scalar(out, path, before, after) {
|
|
116
|
+
const b = before ?? null;
|
|
117
|
+
const a = after ?? null;
|
|
118
|
+
if (b !== a)
|
|
119
|
+
out.push({ path, before: b, after: a });
|
|
120
|
+
}
|
|
121
|
+
function normalizeSQL(sql) {
|
|
122
|
+
if (sql == null)
|
|
123
|
+
return undefined;
|
|
124
|
+
return sql.trim().replace(/\s+/g, ' ');
|
|
125
|
+
}
|
|
126
|
+
function formatExpr(node) {
|
|
127
|
+
switch (node.kind) {
|
|
128
|
+
case NodeKind.StringLiteral:
|
|
129
|
+
return JSON.stringify(node.value);
|
|
130
|
+
case NodeKind.NumberLiteral:
|
|
131
|
+
return String(node.value);
|
|
132
|
+
case NodeKind.BooleanLiteral:
|
|
133
|
+
return node.value ? 'true' : 'false';
|
|
134
|
+
case NodeKind.Identifier:
|
|
135
|
+
return node.name;
|
|
136
|
+
case NodeKind.ArrayLiteral:
|
|
137
|
+
return `[${node.elements.map(formatExpr).join(', ')}]`;
|
|
138
|
+
case NodeKind.BinaryExpr:
|
|
139
|
+
return `${formatExpr(node.left)} ${node.operator} ${formatExpr(node.right)}`;
|
|
140
|
+
case NodeKind.IntervalExpr:
|
|
141
|
+
return `INTERVAL ${JSON.stringify(node.value)}`;
|
|
142
|
+
case NodeKind.FunctionCall:
|
|
143
|
+
return `${node.callee}(${node.arguments.map(formatExpr).join(', ')})`;
|
|
144
|
+
case NodeKind.TemplateString:
|
|
145
|
+
return node.parts
|
|
146
|
+
.map((p) => (typeof p === 'string' ? p : `{${formatExpr(p)}}`))
|
|
147
|
+
.join('');
|
|
148
|
+
default:
|
|
149
|
+
return '';
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function isBlock(s) {
|
|
153
|
+
return s.kind === NodeKind.BlockDecl;
|
|
154
|
+
}
|
|
155
|
+
function isDashboard(s) {
|
|
156
|
+
return s.kind === NodeKind.Dashboard;
|
|
157
|
+
}
|
|
158
|
+
function isWorkbook(s) {
|
|
159
|
+
return s.kind === NodeKind.Workbook;
|
|
160
|
+
}
|
|
161
|
+
function indexBy(items, key) {
|
|
162
|
+
const out = new Map();
|
|
163
|
+
for (const item of items)
|
|
164
|
+
out.set(key(item), item);
|
|
165
|
+
return out;
|
|
166
|
+
}
|
|
167
|
+
function diffKeyed(before, after, handlers) {
|
|
168
|
+
for (const key of before.keys()) {
|
|
169
|
+
if (!after.has(key))
|
|
170
|
+
handlers.onRemoved(key);
|
|
171
|
+
}
|
|
172
|
+
for (const [key, a] of after.entries()) {
|
|
173
|
+
const b = before.get(key);
|
|
174
|
+
if (b === undefined)
|
|
175
|
+
handlers.onAdded(key);
|
|
176
|
+
else
|
|
177
|
+
handlers.onChanged(key, b, a);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function union(a, b) {
|
|
181
|
+
return Array.from(new Set([...a.keys(), ...b.keys()]));
|
|
182
|
+
}
|
|
183
|
+
// ---- Text rendering ----
|
|
184
|
+
export function renderDiffText(report) {
|
|
185
|
+
if (report.identical)
|
|
186
|
+
return 'No changes.';
|
|
187
|
+
const lines = [];
|
|
188
|
+
for (const c of report.changes) {
|
|
189
|
+
switch (c.kind) {
|
|
190
|
+
case 'block-added':
|
|
191
|
+
lines.push(`+ block "${c.name}"`);
|
|
192
|
+
break;
|
|
193
|
+
case 'block-removed':
|
|
194
|
+
lines.push(`- block "${c.name}"`);
|
|
195
|
+
break;
|
|
196
|
+
case 'block-changed':
|
|
197
|
+
lines.push(`~ block "${c.name}"`);
|
|
198
|
+
for (const f of c.fields) {
|
|
199
|
+
lines.push(` ${f.path}: ${fmtVal(f.before)} → ${fmtVal(f.after)}`);
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
case 'dashboard-added':
|
|
203
|
+
lines.push(`+ dashboard "${c.title}"`);
|
|
204
|
+
break;
|
|
205
|
+
case 'dashboard-removed':
|
|
206
|
+
lines.push(`- dashboard "${c.title}"`);
|
|
207
|
+
break;
|
|
208
|
+
case 'dashboard-changed':
|
|
209
|
+
lines.push(`~ dashboard "${c.title}" (body changed)`);
|
|
210
|
+
break;
|
|
211
|
+
case 'workbook-added':
|
|
212
|
+
lines.push(`+ workbook "${c.title}"`);
|
|
213
|
+
break;
|
|
214
|
+
case 'workbook-removed':
|
|
215
|
+
lines.push(`- workbook "${c.title}"`);
|
|
216
|
+
break;
|
|
217
|
+
case 'workbook-changed':
|
|
218
|
+
lines.push(`~ workbook "${c.title}" (body changed)`);
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return lines.join('\n');
|
|
223
|
+
}
|
|
224
|
+
function fmtVal(v) {
|
|
225
|
+
if (v === null)
|
|
226
|
+
return '∅';
|
|
227
|
+
if (v.length > 80)
|
|
228
|
+
return `${v.slice(0, 77)}…`;
|
|
229
|
+
return v;
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/format/diff.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,mEAAmE;AACnE,yEAAyE;AACzE,wEAAwE;AACxE,0EAA0E;AAC1E,oDAAoD;AACpD,EAAE;AACF,sEAAsE;AACtE,2EAA2E;AAE3E,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAY3C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAyB1D,MAAM,UAAU,OAAO,CAAC,YAAoB,EAAE,WAAmB;IAC/D,OAAO,WAAW,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAmB,EAAE,KAAkB;IACjE,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC/E,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7E,SAAS,CAAC,YAAY,EAAE,WAAW,EAAE;QACnC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;QAC9D,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;QAClE,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;YACxB,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/E,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACxF,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtF,SAAS,CAAC,gBAAgB,EAAE,eAAe,EAAE;QAC3C,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC;QACpE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC;QACxE,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;YACzB,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACnC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACpF,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtF,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACpF,SAAS,CAAC,eAAe,EAAE,cAAc,EAAE;QACzC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;QACnE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC;QACvE,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;YACzB,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAClC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACnF,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;AACtD,CAAC;AAED,kBAAkB;AAElB,SAAS,SAAS,CAAC,CAAgB,EAAE,CAAgB;IACnD,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IAC9C,MAAM,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;IACzD,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5D,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IACnD,MAAM,CAAC,GAAG,EAAE,YAAY,EAAE,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9E,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnF,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;IAChE,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,CAAC,CAAC,aAAa,EAAE,UAAU,IAAI,EAAE,EAAE,CAAC,CAAC,aAAa,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC;IAC1G,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAC7C,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CAAC,GAAkB,EAAE,CAAoB,EAAE,CAAoB;IAChF,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,EAAE,UAAU,IAAI,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,GAAkB,EAAE,MAAc,EAAE,CAAiB,EAAE,CAAiB;IAC7F,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,EAAE,GAAG,MAAM,IAAI,IAAI,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,GAAkB,EAAE,CAAkB,EAAE,CAAkB;IAC3E,MAAM,GAAG,GAAG,CAAC,CAAgB,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC7D,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,iCAAiC;AACjC,wEAAwE;AACxE,2EAA2E;AAC3E,0DAA0D;AAE1D,SAAS,aAAa,CAAC,CAAgB,EAAE,CAAgB;IACvD,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,YAAY,CAAC,CAAe,EAAE,CAAe;IACpD,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CAAC,IAAkC;IACpD,MAAM,OAAO,GAAgB;QAC3B,IAAI,EAAE,QAAQ,CAAC,OAAO;QACtB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,UAAU,EAAE,CAAC,IAAI,CAAC;KACnB,CAAC;IACF,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,oBAAoB;AAEpB,SAAS,MAAM,CAAC,GAAkB,EAAE,IAAY,EAAE,MAA0B,EAAE,KAAyB;IACrG,MAAM,CAAC,GAAG,MAAM,IAAI,IAAI,CAAC;IACzB,MAAM,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC;IACxB,IAAI,CAAC,KAAK,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,YAAY,CAAC,GAAuB;IAC3C,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,SAAS,CAAC;IAClC,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,UAAU,CAAC,IAAoB;IACtC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,QAAQ,CAAC,aAAa;YACzB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,KAAK,QAAQ,CAAC,aAAa;YACzB,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,KAAK,QAAQ,CAAC,cAAc;YAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QACvC,KAAK,QAAQ,CAAC,UAAU;YACtB,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,KAAK,QAAQ,CAAC,YAAY;YACxB,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QACzD,KAAK,QAAQ,CAAC,UAAU;YACtB,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/E,KAAK,QAAQ,CAAC,YAAY;YACxB,OAAO,YAAY,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,KAAK,QAAQ,CAAC,YAAY;YACxB,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QACxE,KAAK,QAAQ,CAAC,cAAc;YAC1B,OAAO,IAAI,CAAC,KAAK;iBACd,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;iBAC9D,IAAI,CAAC,EAAE,CAAC,CAAC;QACd;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,CAAgB;IAC/B,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,SAAS,CAAC;AACvC,CAAC;AAED,SAAS,WAAW,CAAC,CAAgB;IACnC,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,SAAS,CAAC;AACvC,CAAC;AAED,SAAS,UAAU,CAAC,CAAgB;IAClC,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,QAAQ,CAAC;AACtC,CAAC;AAED,SAAS,OAAO,CAAO,KAAU,EAAE,GAAmB;IACpD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAQ,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IACnD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,SAAS,CAChB,MAAsB,EACtB,KAAqB,EACrB,QAIC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,SAAS;YAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;;YACtC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAO,CAAY,EAAE,CAAY;IAC7C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,2BAA2B;AAE3B,MAAM,UAAU,cAAc,CAAC,MAAkB;IAC/C,IAAI,MAAM,CAAC,SAAS;QAAE,OAAO,aAAa,CAAC;IAC3C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/B,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,aAAa;gBAChB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;gBAClC,MAAM;YACR,KAAK,eAAe;gBAClB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;gBAClC,MAAM;YACR,KAAK,eAAe;gBAClB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;gBAClC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;oBACzB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACxE,CAAC;gBACD,MAAM;YACR,KAAK,iBAAiB;gBACpB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;gBACvC,MAAM;YACR,KAAK,mBAAmB;gBACtB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;gBACvC,MAAM;YACR,KAAK,mBAAmB;gBACtB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,kBAAkB,CAAC,CAAC;gBACtD,MAAM;YACR,KAAK,gBAAgB;gBACnB,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;gBACtC,MAAM;YACR,KAAK,kBAAkB;gBACrB,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;gBACtC,MAAM;YACR,KAAK,kBAAkB;gBACrB,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,KAAK,kBAAkB,CAAC,CAAC;gBACrD,MAAM;QACV,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,MAAM,CAAC,CAAgB;IAC9B,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC3B,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;IAC/C,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type FormatOptions } from '../formatter/index.js';
|
|
2
|
+
export * from './diff.js';
|
|
3
|
+
export declare const FORMAT_VERSION = 1;
|
|
4
|
+
export declare const FORMAT_HEADER_PREFIX = "// dql-format:";
|
|
5
|
+
export interface CanonicalizeOptions extends FormatOptions {
|
|
6
|
+
/** Override the emitted format version. Defaults to FORMAT_VERSION. */
|
|
7
|
+
version?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Return the declared format version of a `.dql` source, or `null` if the
|
|
11
|
+
* header is absent. Only the first non-empty line is inspected.
|
|
12
|
+
*/
|
|
13
|
+
export declare function readFormatVersion(source: string): number | null;
|
|
14
|
+
export declare function hasCanonicalHeader(source: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Produce the canonical on-disk representation of a `.dql` source:
|
|
17
|
+
* 1. Drop any existing format header
|
|
18
|
+
* 2. Reformat via `formatDQL` (deterministic key order, spacing)
|
|
19
|
+
* 3. Prepend the current format header
|
|
20
|
+
*
|
|
21
|
+
* Idempotent: `canonicalize(canonicalize(x)) === canonicalize(x)`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function canonicalize(source: string, options?: CanonicalizeOptions): string;
|
|
24
|
+
/**
|
|
25
|
+
* True when `canonicalize(source) === source` — i.e. the file is already
|
|
26
|
+
* byte-identical to its canonical form and needs no rewrite.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isCanonical(source: string): boolean;
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/format/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtE,cAAc,WAAW,CAAC;AAE1B,eAAO,MAAM,cAAc,IAAI,CAAC;AAChC,eAAO,MAAM,oBAAoB,mBAAmB,CAAC;AAIrD,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO/D;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1D;AAmBD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAKtF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// v0.11 canonical `.dql` serializer.
|
|
2
|
+
//
|
|
3
|
+
// Adds a stable format-version header and routes all writes through the
|
|
4
|
+
// formatter so that files produced by the CLI, notebook, and block studio
|
|
5
|
+
// byte-identical — the precondition for clean git diffs, `dql diff`, and
|
|
6
|
+
// a safe file-format migration path.
|
|
7
|
+
//
|
|
8
|
+
// Format:
|
|
9
|
+
// // dql-format: <N>
|
|
10
|
+
// <formatted body>
|
|
11
|
+
//
|
|
12
|
+
// Readers that don't recognise a header treat it as an ordinary comment.
|
|
13
|
+
// Writers always emit the current version.
|
|
14
|
+
import { formatDQL } from '../formatter/index.js';
|
|
15
|
+
export * from './diff.js';
|
|
16
|
+
export const FORMAT_VERSION = 1;
|
|
17
|
+
export const FORMAT_HEADER_PREFIX = '// dql-format:';
|
|
18
|
+
const HEADER_RE = /^\s*\/\/\s*dql-format:\s*(\d+)\s*$/;
|
|
19
|
+
/**
|
|
20
|
+
* Return the declared format version of a `.dql` source, or `null` if the
|
|
21
|
+
* header is absent. Only the first non-empty line is inspected.
|
|
22
|
+
*/
|
|
23
|
+
export function readFormatVersion(source) {
|
|
24
|
+
for (const line of source.split('\n')) {
|
|
25
|
+
if (line.trim() === '')
|
|
26
|
+
continue;
|
|
27
|
+
const match = HEADER_RE.exec(line);
|
|
28
|
+
return match ? Number(match[1]) : null;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
export function hasCanonicalHeader(source) {
|
|
33
|
+
return readFormatVersion(source) !== null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Strip any leading `// dql-format:` header (plus a single trailing blank
|
|
37
|
+
* line) so the remainder can be re-parsed by the existing formatter, which
|
|
38
|
+
* does not yet preserve comments.
|
|
39
|
+
*/
|
|
40
|
+
function stripHeader(source) {
|
|
41
|
+
const lines = source.split('\n');
|
|
42
|
+
let i = 0;
|
|
43
|
+
while (i < lines.length && lines[i].trim() === '')
|
|
44
|
+
i++;
|
|
45
|
+
if (i < lines.length && HEADER_RE.test(lines[i])) {
|
|
46
|
+
i++;
|
|
47
|
+
if (i < lines.length && lines[i].trim() === '')
|
|
48
|
+
i++;
|
|
49
|
+
return lines.slice(i).join('\n');
|
|
50
|
+
}
|
|
51
|
+
return source;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Produce the canonical on-disk representation of a `.dql` source:
|
|
55
|
+
* 1. Drop any existing format header
|
|
56
|
+
* 2. Reformat via `formatDQL` (deterministic key order, spacing)
|
|
57
|
+
* 3. Prepend the current format header
|
|
58
|
+
*
|
|
59
|
+
* Idempotent: `canonicalize(canonicalize(x)) === canonicalize(x)`.
|
|
60
|
+
*/
|
|
61
|
+
export function canonicalize(source, options = {}) {
|
|
62
|
+
const version = options.version ?? FORMAT_VERSION;
|
|
63
|
+
const body = formatDQL(stripHeader(source), options);
|
|
64
|
+
const header = `${FORMAT_HEADER_PREFIX} ${version}`;
|
|
65
|
+
return `${header}\n\n${body.startsWith('\n') ? body.slice(1) : body}`;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* True when `canonicalize(source) === source` — i.e. the file is already
|
|
69
|
+
* byte-identical to its canonical form and needs no rewrite.
|
|
70
|
+
*/
|
|
71
|
+
export function isCanonical(source) {
|
|
72
|
+
return canonicalize(source) === source;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/format/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,EAAE;AACF,wEAAwE;AACxE,0EAA0E;AAC1E,yEAAyE;AACzE,qCAAqC;AACrC,EAAE;AACF,UAAU;AACV,uBAAuB;AACvB,qBAAqB;AACrB,EAAE;AACF,yEAAyE;AACzE,2CAA2C;AAE3C,OAAO,EAAE,SAAS,EAAsB,MAAM,uBAAuB,CAAC;AAEtE,cAAc,WAAW,CAAC;AAE1B,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAChC,MAAM,CAAC,MAAM,oBAAoB,GAAG,gBAAgB,CAAC;AAErD,MAAM,SAAS,GAAG,oCAAoC,CAAC;AAOvD;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QACjC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,OAAO,iBAAiB,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,MAAc;IACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,CAAC,EAAE,CAAC;IACvD,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,CAAC,EAAE,CAAC;QACJ,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,CAAC,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,UAA+B,EAAE;IAC5E,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC;IAClD,MAAM,IAAI,GAAG,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,GAAG,oBAAoB,IAAI,OAAO,EAAE,CAAC;IACpD,OAAO,GAAG,MAAM,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACxE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,OAAO,YAAY,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC;AACzC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './parser/index.js';
|
|
|
4
4
|
export * from './semantic/index.js';
|
|
5
5
|
export * from './errors/index.js';
|
|
6
6
|
export * from './formatter/index.js';
|
|
7
|
+
export * from './format/index.js';
|
|
7
8
|
export * from './lineage/index.js';
|
|
8
9
|
export * from './manifest/index.js';
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export * from './parser/index.js';
|
|
|
6
6
|
export * from './semantic/index.js';
|
|
7
7
|
export * from './errors/index.js';
|
|
8
8
|
export * from './formatter/index.js';
|
|
9
|
+
export * from './format/index.js';
|
|
9
10
|
export * from './lineage/index.js';
|
|
10
11
|
export * from './manifest/index.js';
|
|
11
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,wCAAwC;AAExC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,wCAAwC;AAExC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
|