@coral-viz/language 0.2.3
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/LICENSE +4 -0
- package/README.md +5 -0
- package/dist/diagnostics.d.ts +81 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +59 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/formats/dot.d.ts +23 -0
- package/dist/formats/dot.d.ts.map +1 -0
- package/dist/formats/dot.js +541 -0
- package/dist/formats/dot.js.map +1 -0
- package/dist/formats/index.d.ts +6 -0
- package/dist/formats/index.d.ts.map +1 -0
- package/dist/formats/index.js +6 -0
- package/dist/formats/index.js.map +1 -0
- package/dist/formats/mermaid.d.ts +29 -0
- package/dist/formats/mermaid.d.ts.map +1 -0
- package/dist/formats/mermaid.js +1051 -0
- package/dist/formats/mermaid.js.map +1 -0
- package/dist/formats/plantuml.d.ts +20 -0
- package/dist/formats/plantuml.d.ts.map +1 -0
- package/dist/formats/plantuml.js +271 -0
- package/dist/formats/plantuml.js.map +1 -0
- package/dist/ids.d.ts +36 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/ids.js +69 -0
- package/dist/ids.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/index.d.ts +13 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +415 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/printer/index.d.ts +47 -0
- package/dist/printer/index.d.ts.map +1 -0
- package/dist/printer/index.js +392 -0
- package/dist/printer/index.js.map +1 -0
- package/dist/strings.d.ts +17 -0
- package/dist/strings.d.ts.map +1 -0
- package/dist/strings.js +48 -0
- package/dist/strings.js.map +1 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coral DSL Printer
|
|
3
|
+
*
|
|
4
|
+
* Converts Graph-IR back to Coral DSL text.
|
|
5
|
+
* Enables roundtrip: DSL → IR → DSL
|
|
6
|
+
*/
|
|
7
|
+
import { printDiagnostic } from '../diagnostics.js';
|
|
8
|
+
import { escapeString, quoteIfNeeded } from '../strings.js';
|
|
9
|
+
import { IdAllocator } from '../ids.js';
|
|
10
|
+
/** Discards everything, so `print` allocates nothing per node or edge. */
|
|
11
|
+
const NULL_SINK = { push() { } };
|
|
12
|
+
/** Node fields with no Coral spelling, reported rather than dropped in silence. */
|
|
13
|
+
/** Coordinates print to at most two decimal places, so the loop settles. */
|
|
14
|
+
function formatCoord(value) {
|
|
15
|
+
return String(Number(value.toFixed(2)));
|
|
16
|
+
}
|
|
17
|
+
/** True when a property value has a Coral spelling. */
|
|
18
|
+
export function isPrintableScalar(value) {
|
|
19
|
+
if (typeof value === 'string' || typeof value === 'boolean')
|
|
20
|
+
return true;
|
|
21
|
+
if (typeof value === 'number')
|
|
22
|
+
return Number.isFinite(value);
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const UNPRINTABLE_NODE_FIELDS = [
|
|
26
|
+
'dimensions', 'description', 'layoutOptions',
|
|
27
|
+
'symbol', 'variant', 'ports',
|
|
28
|
+
];
|
|
29
|
+
/** Edge fields with no Coral spelling. */
|
|
30
|
+
const UNPRINTABLE_EDGE_FIELDS = [
|
|
31
|
+
['sourcePort', 'source-port'],
|
|
32
|
+
['targetPort', 'target-port'],
|
|
33
|
+
['description', 'description'],
|
|
34
|
+
];
|
|
35
|
+
/** Report the node's own unprintable fields. Called by printNode, which owns the walk. */
|
|
36
|
+
function reportNodeFieldLoss(node, out) {
|
|
37
|
+
const bag = node;
|
|
38
|
+
for (const field of UNPRINTABLE_NODE_FIELDS) {
|
|
39
|
+
if (bag[field] !== undefined) {
|
|
40
|
+
out.push(printDiagnostic({
|
|
41
|
+
severity: 'warning',
|
|
42
|
+
code: `coral.node.${field.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase())}.dropped`,
|
|
43
|
+
message: `Node "${node.id}" carries ${field}, which the Coral surface cannot express`,
|
|
44
|
+
subject: { kind: 'node', id: node.id },
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
for (const [key, value] of Object.entries(node.properties ?? {})) {
|
|
49
|
+
collectPropertyLoss('node', node.id, key, value, out);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function collectPropertyLoss(kind, id, key, value, out) {
|
|
53
|
+
if (key.startsWith('_')) {
|
|
54
|
+
out.push(printDiagnostic({
|
|
55
|
+
severity: 'info',
|
|
56
|
+
code: `coral.${kind}.reserved-property.dropped`,
|
|
57
|
+
message: `Property "${key}" on ${kind} "${id}" is reserved for internal use and is not emitted`,
|
|
58
|
+
subject: { kind, id },
|
|
59
|
+
}));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (value == null)
|
|
63
|
+
return;
|
|
64
|
+
if (typeof value === 'number' && !Number.isFinite(value)) {
|
|
65
|
+
out.push(printDiagnostic({
|
|
66
|
+
severity: 'warning',
|
|
67
|
+
code: `coral.${kind}.property.dropped`,
|
|
68
|
+
message: `Property "${key}" on ${kind} "${id}" is not a finite number and is not emitted`,
|
|
69
|
+
subject: { kind, id },
|
|
70
|
+
}));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!['string', 'number', 'boolean'].includes(typeof value)) {
|
|
74
|
+
out.push(printDiagnostic({
|
|
75
|
+
severity: 'warning',
|
|
76
|
+
code: `coral.${kind}.property.dropped`,
|
|
77
|
+
message: `Property "${key}" on ${kind} "${id}" is not a scalar and is not emitted`,
|
|
78
|
+
subject: { kind, id },
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Report the edge's unprintable fields. Called by printEdge. */
|
|
83
|
+
function reportEdgeFieldLoss(edge, out) {
|
|
84
|
+
const bag = edge;
|
|
85
|
+
// Edge ids are re-derived from endpoints on parse and cannot survive (R-010).
|
|
86
|
+
out.push(printDiagnostic({
|
|
87
|
+
severity: 'info',
|
|
88
|
+
code: 'coral.edge.id.dropped',
|
|
89
|
+
message: `Edge id "${edge.id}" is not emitted; it is re-derived from its endpoints on parse`,
|
|
90
|
+
subject: { kind: 'edge', id: edge.id },
|
|
91
|
+
}));
|
|
92
|
+
for (const [field, slug] of UNPRINTABLE_EDGE_FIELDS) {
|
|
93
|
+
if (bag[field] !== undefined) {
|
|
94
|
+
out.push(printDiagnostic({
|
|
95
|
+
severity: 'warning',
|
|
96
|
+
code: `coral.edge.${slug}.dropped`,
|
|
97
|
+
message: `Edge "${edge.id}" carries ${field}, which the Coral surface cannot express`,
|
|
98
|
+
subject: { kind: 'edge', id: edge.id },
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Only lineStyle has a Coral spelling; the rest of EdgeStyle does not.
|
|
103
|
+
for (const key of ['sourceArrow', 'targetArrow', 'routing']) {
|
|
104
|
+
if (edge.style?.[key] !== undefined) {
|
|
105
|
+
out.push(printDiagnostic({
|
|
106
|
+
severity: 'warning',
|
|
107
|
+
code: `coral.edge.style-${key.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase())}.dropped`,
|
|
108
|
+
message: `Edge "${edge.id}" carries style.${key}, which the Coral surface cannot express`,
|
|
109
|
+
subject: { kind: 'edge', id: edge.id },
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
for (const [key, value] of Object.entries(edge.properties ?? {})) {
|
|
114
|
+
collectPropertyLoss('edge', edge.id, key, value, out);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function reportGraphFieldLoss(graph, out) {
|
|
118
|
+
const bag = graph;
|
|
119
|
+
for (const field of ['id', 'name', 'metadata', 'layoutOptions']) {
|
|
120
|
+
if (bag[field] !== undefined) {
|
|
121
|
+
out.push(printDiagnostic({
|
|
122
|
+
severity: 'info',
|
|
123
|
+
code: `coral.graph.${field.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase())}.dropped`,
|
|
124
|
+
message: `Graph ${field} is not emitted; the Coral surface has no spelling for it`,
|
|
125
|
+
subject: { kind: 'graph', id: graph.id },
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Print Graph-IR to Coral DSL text, reporting everything the surface cannot
|
|
132
|
+
* carry.
|
|
133
|
+
*
|
|
134
|
+
* `print` keeps its bare-string signature for existing consumers; this is the
|
|
135
|
+
* variant the editor uses.
|
|
136
|
+
*/
|
|
137
|
+
export function printWithDiagnostics(graph, options = {}) {
|
|
138
|
+
const diagnostics = [];
|
|
139
|
+
const text = renderGraph(graph, options, diagnostics);
|
|
140
|
+
return { text, diagnostics };
|
|
141
|
+
}
|
|
142
|
+
/** The single traversal that both emits text and records what it declined to emit. */
|
|
143
|
+
function renderGraph(graph, options, diagnostics) {
|
|
144
|
+
const { indent = ' ' } = options;
|
|
145
|
+
const lines = [];
|
|
146
|
+
reportGraphFieldLoss(graph, diagnostics);
|
|
147
|
+
// Make the input safe for the replay: unique, non-empty ids, with edges
|
|
148
|
+
// rewritten to follow (R-010 AC-2, AC-3).
|
|
149
|
+
const safe = normaliseIds(graph, diagnostics);
|
|
150
|
+
graph = safe;
|
|
151
|
+
// Decide which nodes need an explicit `as` clause.
|
|
152
|
+
const explicit = markExplicitIds(graph);
|
|
153
|
+
// Top-level nodes only; printNode recurses into children and reports as it goes.
|
|
154
|
+
for (const node of graph.nodes) {
|
|
155
|
+
printNode(node, lines, 0, indent, diagnostics, explicit);
|
|
156
|
+
}
|
|
157
|
+
if (graph.nodes.length > 0 && graph.edges.length > 0) {
|
|
158
|
+
lines.push('');
|
|
159
|
+
}
|
|
160
|
+
for (const edge of graph.edges) {
|
|
161
|
+
lines.push(printEdge(edge, diagnostics));
|
|
162
|
+
}
|
|
163
|
+
return lines.join('\n');
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Print Graph-IR to Coral DSL text
|
|
167
|
+
*/
|
|
168
|
+
export function print(graph, options = {}) {
|
|
169
|
+
return renderGraph(graph, options, NULL_SINK);
|
|
170
|
+
}
|
|
171
|
+
/** The label text the printer will actually emit for a node. */
|
|
172
|
+
function emittedLabel(node) {
|
|
173
|
+
return node.label !== undefined ? node.label : node.id;
|
|
174
|
+
}
|
|
175
|
+
/** Every node, in declaration order, children included. */
|
|
176
|
+
function inDeclarationOrder(nodes) {
|
|
177
|
+
const out = [];
|
|
178
|
+
const walk = (list) => {
|
|
179
|
+
for (const n of list) {
|
|
180
|
+
out.push(n);
|
|
181
|
+
if (n.children)
|
|
182
|
+
walk(n.children);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
walk(nodes);
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Give every node a unique, non-empty id before the replay runs, rewriting the
|
|
190
|
+
* edges that referenced a substituted id (R-010 AC-2, AC-3).
|
|
191
|
+
*
|
|
192
|
+
* Returns the original graph untouched when nothing needed changing, so the
|
|
193
|
+
* common path allocates nothing.
|
|
194
|
+
*/
|
|
195
|
+
function normaliseIds(graph, out) {
|
|
196
|
+
const seen = new Set();
|
|
197
|
+
const substitutions = new Map();
|
|
198
|
+
const pool = new IdAllocator();
|
|
199
|
+
// Seed with every id that is already unique and usable, so the pre-pass does
|
|
200
|
+
// not hand a later node an id an untouched node is holding.
|
|
201
|
+
for (const node of inDeclarationOrder(graph.nodes)) {
|
|
202
|
+
if (node.id !== '' && !seen.has(node.id)) {
|
|
203
|
+
seen.add(node.id);
|
|
204
|
+
pool.reserve(node.id);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const taken = new Set();
|
|
208
|
+
const rewrite = new Map();
|
|
209
|
+
for (const node of inDeclarationOrder(graph.nodes)) {
|
|
210
|
+
if (node.id !== '' && !taken.has(node.id)) {
|
|
211
|
+
taken.add(node.id);
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
const replacement = pool.allocateFromLabel(emittedLabel(node));
|
|
215
|
+
rewrite.set(node, replacement);
|
|
216
|
+
taken.add(replacement);
|
|
217
|
+
// Only an empty id is orphaned. A duplicate id is still held by the
|
|
218
|
+
// earlier node, which keeps it, so edges must continue to resolve there
|
|
219
|
+
// (R-010 AC-3) and must not be rewritten to the renamed occurrence.
|
|
220
|
+
if (node.id === '' && !substitutions.has(''))
|
|
221
|
+
substitutions.set('', replacement);
|
|
222
|
+
out.push(printDiagnostic({
|
|
223
|
+
severity: 'warning',
|
|
224
|
+
code: 'coral.node.id.degraded',
|
|
225
|
+
message: node.id === ''
|
|
226
|
+
? `A node had an empty id, which Coral cannot express; it was given "${replacement}"`
|
|
227
|
+
: `Node id "${node.id}" was used more than once; one occurrence was given "${replacement}"`,
|
|
228
|
+
subject: { kind: 'node', id: replacement },
|
|
229
|
+
}));
|
|
230
|
+
}
|
|
231
|
+
if (rewrite.size === 0)
|
|
232
|
+
return graph;
|
|
233
|
+
const cloneNode = (node) => ({
|
|
234
|
+
...node,
|
|
235
|
+
id: rewrite.get(node) ?? node.id,
|
|
236
|
+
...(node.children ? { children: node.children.map(cloneNode) } : {}),
|
|
237
|
+
});
|
|
238
|
+
return {
|
|
239
|
+
...graph,
|
|
240
|
+
nodes: graph.nodes.map(cloneNode),
|
|
241
|
+
edges: graph.edges.map((edge) => ({
|
|
242
|
+
...edge,
|
|
243
|
+
source: substitutions.get(edge.source) ?? edge.source,
|
|
244
|
+
target: substitutions.get(edge.target) ?? edge.target,
|
|
245
|
+
})),
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Decide which nodes need an explicit `as` clause.
|
|
250
|
+
*
|
|
251
|
+
* One forward pass in declaration order, applying each decision immediately: a
|
|
252
|
+
* node whose allocated id matches keeps it, otherwise the speculative id is
|
|
253
|
+
* released so a later node may still receive it, and `node.id` is reserved.
|
|
254
|
+
* Deciding every node before applying any of them over-annotates, because
|
|
255
|
+
* marking one node explicit changes what a later node is allocated.
|
|
256
|
+
*/
|
|
257
|
+
function markExplicitIds(graph) {
|
|
258
|
+
const allocator = new IdAllocator();
|
|
259
|
+
const explicit = new Set();
|
|
260
|
+
for (const node of inDeclarationOrder(graph.nodes)) {
|
|
261
|
+
const allocated = allocator.allocateFromLabel(emittedLabel(node));
|
|
262
|
+
if (allocated === node.id)
|
|
263
|
+
continue;
|
|
264
|
+
allocator.release(allocated);
|
|
265
|
+
allocator.reserve(node.id);
|
|
266
|
+
explicit.add(node.id);
|
|
267
|
+
}
|
|
268
|
+
return explicit;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Print a single node and its children
|
|
272
|
+
*/
|
|
273
|
+
function printNode(node, lines, depth, indent, out, explicit) {
|
|
274
|
+
reportNodeFieldLoss(node, out);
|
|
275
|
+
const prefix = indent.repeat(depth);
|
|
276
|
+
const nodeType = node.type || 'service';
|
|
277
|
+
const emitted = emittedLabel(node);
|
|
278
|
+
const label = escapeString(emitted);
|
|
279
|
+
const idClause = explicit.has(node.id) ? ` as ${quoteIfNeeded(node.id)}` : '';
|
|
280
|
+
const geometry = node.position
|
|
281
|
+
? ` @ (${formatCoord(node.position.x)}, ${formatCoord(node.position.y)})`
|
|
282
|
+
: '';
|
|
283
|
+
const pinned = node.pinned ? ' pinned' : '';
|
|
284
|
+
// Check if node has body content (children or printable properties)
|
|
285
|
+
const hasChildren = node.children && node.children.length > 0;
|
|
286
|
+
const hasProperties = node.properties && Object.entries(node.properties).some(([key, value]) => !key.startsWith('_') && value != null && isPrintableScalar(value));
|
|
287
|
+
const hasBody = hasChildren || hasProperties;
|
|
288
|
+
if (hasBody) {
|
|
289
|
+
lines.push(`${prefix}${nodeType} "${label}"${idClause}${geometry}${pinned} {`);
|
|
290
|
+
// Print properties first
|
|
291
|
+
if (hasProperties) {
|
|
292
|
+
for (const [key, value] of Object.entries(node.properties)) {
|
|
293
|
+
// Skip internal properties
|
|
294
|
+
if (key.startsWith('_'))
|
|
295
|
+
continue;
|
|
296
|
+
// Skip null/undefined
|
|
297
|
+
if (value == null)
|
|
298
|
+
continue;
|
|
299
|
+
if (!isPrintableScalar(value))
|
|
300
|
+
continue;
|
|
301
|
+
if (typeof value === 'string') {
|
|
302
|
+
lines.push(`${prefix}${indent}${quoteIfNeeded(key)}: "${escapeString(value)}"`);
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
lines.push(`${prefix}${indent}${quoteIfNeeded(key)}: ${value}`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// Print children
|
|
310
|
+
if (hasChildren) {
|
|
311
|
+
for (const child of node.children) {
|
|
312
|
+
printNode(child, lines, depth + 1, indent, out, explicit);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
lines.push(`${prefix}}`);
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
lines.push(`${prefix}${nodeType} "${label}"${idClause}${geometry}${pinned}`);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Print a single edge
|
|
323
|
+
*/
|
|
324
|
+
function printEdge(edge, out) {
|
|
325
|
+
reportEdgeFieldLoss(edge, out);
|
|
326
|
+
const parts = [`${quoteIfNeeded(edge.source)} -> ${quoteIfNeeded(edge.target)}`];
|
|
327
|
+
// Build attributes
|
|
328
|
+
const attrs = [];
|
|
329
|
+
if (edge.type) {
|
|
330
|
+
// A bare leading token that spells a line style would be misread as one,
|
|
331
|
+
// so it is quoted; a quoted leading token is always the relation type.
|
|
332
|
+
const ambiguous = ['solid', 'dashed', 'dotted'].includes(edge.type);
|
|
333
|
+
attrs.push(ambiguous || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(edge.type)
|
|
334
|
+
? `"${escapeString(edge.type)}"`
|
|
335
|
+
: edge.type);
|
|
336
|
+
}
|
|
337
|
+
// `solid` is emitted like any other style so it survives the round-trip.
|
|
338
|
+
if (edge.style?.lineStyle) {
|
|
339
|
+
attrs.push(edge.style.lineStyle);
|
|
340
|
+
}
|
|
341
|
+
if (edge.label !== undefined) {
|
|
342
|
+
attrs.push(`label: "${escapeString(edge.label)}"`);
|
|
343
|
+
}
|
|
344
|
+
// Add other properties as attributes (sorted for deterministic output)
|
|
345
|
+
if (edge.properties) {
|
|
346
|
+
const sortedKeys = Object.keys(edge.properties).sort();
|
|
347
|
+
for (const key of sortedKeys) {
|
|
348
|
+
const value = edge.properties[key];
|
|
349
|
+
if (key === 'label')
|
|
350
|
+
continue; // Already handled
|
|
351
|
+
// Reserved for internal use; omitted on both sides (R-009 AC-7).
|
|
352
|
+
if (key.startsWith('_'))
|
|
353
|
+
continue;
|
|
354
|
+
if (value == null)
|
|
355
|
+
continue;
|
|
356
|
+
if (!isPrintableScalar(value))
|
|
357
|
+
continue;
|
|
358
|
+
if (typeof value === 'string') {
|
|
359
|
+
attrs.push(`${quoteIfNeeded(key)}: "${escapeString(value)}"`);
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
attrs.push(`${quoteIfNeeded(key)}: ${value}`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (attrs.length > 0) {
|
|
367
|
+
parts.push(`[${attrs.join(', ')}]`);
|
|
368
|
+
}
|
|
369
|
+
if (edge.routingPoints && edge.routingPoints.length > 0) {
|
|
370
|
+
parts.push(`via ${edge.routingPoints
|
|
371
|
+
.map((p) => `(${formatCoord(p.x)}, ${formatCoord(p.y)})`)
|
|
372
|
+
.join(' ')}`);
|
|
373
|
+
}
|
|
374
|
+
return parts.join(' ');
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Pretty print with additional formatting options
|
|
378
|
+
*/
|
|
379
|
+
export function prettyPrint(graph, options = {}) {
|
|
380
|
+
const { sortByType = false, ...printOptions } = options;
|
|
381
|
+
let nodes = [...graph.nodes];
|
|
382
|
+
if (sortByType) {
|
|
383
|
+
const typeOrder = ['actor', 'service', 'module', 'database', 'external_api', 'group'];
|
|
384
|
+
nodes.sort((a, b) => {
|
|
385
|
+
const aIndex = typeOrder.indexOf(a.type || 'service');
|
|
386
|
+
const bIndex = typeOrder.indexOf(b.type || 'service');
|
|
387
|
+
return aIndex - bIndex;
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
return print({ ...graph, nodes }, printOptions);
|
|
391
|
+
}
|
|
392
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/printer/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quoting (R-009).
|
|
3
|
+
*
|
|
4
|
+
* One escaper and one unescaper, inverse over the characters Coral quotes.
|
|
5
|
+
* Every quoted position — node label, property value, edge attribute and the
|
|
6
|
+
* id spellings — is written by the first and read by the second, so a string
|
|
7
|
+
* survives any number of round-trips rather than growing a backslash on each.
|
|
8
|
+
*/
|
|
9
|
+
/** Escape the characters that cannot appear raw inside a Coral quoted string. */
|
|
10
|
+
export declare function escapeString(str: string): string;
|
|
11
|
+
/** Reverse {@link escapeString}. */
|
|
12
|
+
export declare function unescapeString(str: string): string;
|
|
13
|
+
/** A bare identifier needs no quoting; anything else does. */
|
|
14
|
+
export declare const BARE_IDENTIFIER: RegExp;
|
|
15
|
+
/** Emit an id or key bare when it can be, quoted when it cannot. */
|
|
16
|
+
export declare function quoteIfNeeded(value: string): string;
|
|
17
|
+
//# sourceMappingURL=strings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOhD;AAED,oCAAoC;AACpC,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgBlD;AAED,8DAA8D;AAC9D,eAAO,MAAM,eAAe,QAA6B,CAAC;AAE1D,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
package/dist/strings.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quoting (R-009).
|
|
3
|
+
*
|
|
4
|
+
* One escaper and one unescaper, inverse over the characters Coral quotes.
|
|
5
|
+
* Every quoted position — node label, property value, edge attribute and the
|
|
6
|
+
* id spellings — is written by the first and read by the second, so a string
|
|
7
|
+
* survives any number of round-trips rather than growing a backslash on each.
|
|
8
|
+
*/
|
|
9
|
+
/** Escape the characters that cannot appear raw inside a Coral quoted string. */
|
|
10
|
+
export function escapeString(str) {
|
|
11
|
+
return str
|
|
12
|
+
.replace(/\\/g, '\\\\')
|
|
13
|
+
.replace(/"/g, '\\"')
|
|
14
|
+
.replace(/\n/g, '\\n')
|
|
15
|
+
.replace(/\r/g, '\\r')
|
|
16
|
+
.replace(/\t/g, '\\t');
|
|
17
|
+
}
|
|
18
|
+
/** Reverse {@link escapeString}. */
|
|
19
|
+
export function unescapeString(str) {
|
|
20
|
+
let out = '';
|
|
21
|
+
for (let i = 0; i < str.length; i++) {
|
|
22
|
+
if (str[i] !== '\\' || i + 1 >= str.length) {
|
|
23
|
+
out += str[i];
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const next = str[++i];
|
|
27
|
+
if (next === 'n')
|
|
28
|
+
out += '\n';
|
|
29
|
+
else if (next === 'r')
|
|
30
|
+
out += '\r';
|
|
31
|
+
else if (next === 't')
|
|
32
|
+
out += '\t';
|
|
33
|
+
else if (next === '"')
|
|
34
|
+
out += '"';
|
|
35
|
+
else if (next === '\\')
|
|
36
|
+
out += '\\';
|
|
37
|
+
else
|
|
38
|
+
out += next;
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
/** A bare identifier needs no quoting; anything else does. */
|
|
43
|
+
export const BARE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
44
|
+
/** Emit an id or key bare when it can be, quoted when it cannot. */
|
|
45
|
+
export function quoteIfNeeded(value) {
|
|
46
|
+
return BARE_IDENTIFIER.test(value) ? value : `"${escapeString(value)}"`;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=strings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strings.js","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,iFAAiF;AACjF,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,GAAG;SACP,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAC3C,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YACd,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,KAAK,GAAG;YAAE,GAAG,IAAI,IAAI,CAAC;aACzB,IAAI,IAAI,KAAK,GAAG;YAAE,GAAG,IAAI,IAAI,CAAC;aAC9B,IAAI,IAAI,KAAK,GAAG;YAAE,GAAG,IAAI,IAAI,CAAC;aAC9B,IAAI,IAAI,KAAK,GAAG;YAAE,GAAG,IAAI,GAAG,CAAC;aAC7B,IAAI,IAAI,KAAK,IAAI;YAAE,GAAG,IAAI,IAAI,CAAC;;YAC/B,GAAG,IAAI,IAAI,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8DAA8D;AAC9D,MAAM,CAAC,MAAM,eAAe,GAAG,0BAA0B,CAAC;AAE1D,oEAAoE;AACpE,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC;AAC1E,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Canonical Graph-IR types are owned by @graph-ir/core. */
|
|
2
|
+
import type { GraphIR } from '@graph-ir/core';
|
|
3
|
+
import type { ParseDiagnostic } from './diagnostics.js';
|
|
4
|
+
export type { GraphIR, GraphNode, GraphEdge, Port, PortSide, Dimensions, Position, EdgeStyle, LayoutOptions, SpacingOptions, NodeLayoutOptions, GraphMetadata, SourceInfo, SourceRange, Comment, } from '@graph-ir/core';
|
|
5
|
+
/**
|
|
6
|
+
* Parser options
|
|
7
|
+
*/
|
|
8
|
+
export interface ParseOptions {
|
|
9
|
+
/** Include source info for roundtripping */
|
|
10
|
+
includeSourceInfo?: boolean;
|
|
11
|
+
/** Graph ID (defaults to 'coral-graph') */
|
|
12
|
+
graphId?: string;
|
|
13
|
+
/** Graph name */
|
|
14
|
+
graphName?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Parse result
|
|
18
|
+
*/
|
|
19
|
+
export interface ParseResult {
|
|
20
|
+
success: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Best-effort graph. Populated even when `success` is false, so one bad line
|
|
23
|
+
* does not discard everything that parsed (R-009 AC-8).
|
|
24
|
+
*/
|
|
25
|
+
graph?: GraphIR;
|
|
26
|
+
/**
|
|
27
|
+
* The error-severity view of `diagnostics`: element-identical, same order,
|
|
28
|
+
* frozen. Derived by the builder, never accumulated in parallel (R-011 AC-2).
|
|
29
|
+
*/
|
|
30
|
+
errors: ParseError[];
|
|
31
|
+
/** Every diagnostic, at every severity (R-011). */
|
|
32
|
+
diagnostics: ParseDiagnostic[];
|
|
33
|
+
}
|
|
34
|
+
export interface ParseError {
|
|
35
|
+
message: string;
|
|
36
|
+
line: number;
|
|
37
|
+
column: number;
|
|
38
|
+
offset: number;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,YAAY,EACV,OAAO,EACP,SAAS,EACT,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,SAAS,EACT,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,UAAU,EACV,WAAW,EACX,OAAO,GACR,MAAM,gBAAgB,CAAC;AAExB;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,mDAAmD;IACnD,WAAW,EAAE,eAAe,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@coral-viz/language",
|
|
3
|
+
"version": "0.2.3",
|
|
4
|
+
"description": "Coral DSL parser and printer",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/coreyt/coral.git",
|
|
9
|
+
"directory": "packages/language"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"types": "dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./parser": {
|
|
20
|
+
"types": "./dist/parser/index.d.ts",
|
|
21
|
+
"import": "./dist/parser/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./printer": {
|
|
24
|
+
"types": "./dist/printer/index.d.ts",
|
|
25
|
+
"import": "./dist/printer/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./formats": {
|
|
28
|
+
"types": "./dist/formats/index.d.ts",
|
|
29
|
+
"import": "./dist/formats/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "node ../../scripts/clean.mjs dist && tsc",
|
|
39
|
+
"prepack": "npm run build",
|
|
40
|
+
"test": "vitest",
|
|
41
|
+
"test:run": "vitest run",
|
|
42
|
+
"test:coverage": "vitest run --coverage",
|
|
43
|
+
"lint": "eslint src test",
|
|
44
|
+
"typecheck": "tsc --noEmit"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@graph-ir/core": "0.2.0"
|
|
48
|
+
},
|
|
49
|
+
"optionalDependencies": {
|
|
50
|
+
"tree-sitter": "0.25.1"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "24.13.3",
|
|
54
|
+
"@vitest/coverage-v8": "5.0.0",
|
|
55
|
+
"typescript": "6.0.3",
|
|
56
|
+
"vitest": "5.0.0"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=24.19.0"
|
|
60
|
+
},
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public"
|
|
63
|
+
}
|
|
64
|
+
}
|