ts-graphviz 1.0.1 → 1.2.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/lib/ast/index.cjs CHANGED
@@ -59,7 +59,7 @@ const endOfLine = (eol) => {
59
59
  }
60
60
  };
61
61
 
62
- const AttributeListPrintPlugin$1 = {
62
+ const AttributeListPrintPlugin = {
63
63
  match(ast) {
64
64
  return ast.type === 'AttributeList';
65
65
  },
@@ -253,8 +253,8 @@ const SubgraphPrintPlugin = {
253
253
  },
254
254
  };
255
255
 
256
- const defaultPlugins$1 = [
257
- AttributeListPrintPlugin$1,
256
+ const defaultPlugins$2 = [
257
+ AttributeListPrintPlugin,
258
258
  AttributePrintPlugin,
259
259
  CommentPrintPlugin,
260
260
  DotPrintPlugin,
@@ -273,7 +273,7 @@ const defaultPlugins$1 = [
273
273
  class Printer {
274
274
  options;
275
275
  /** @internal */
276
- #plugins = [...defaultPlugins$1];
276
+ #plugins = [...defaultPlugins$2];
277
277
  constructor(options = {}) {
278
278
  this.options = options;
279
279
  }
@@ -5342,7 +5342,7 @@ function convertClusterChildren(context, model) {
5342
5342
  );
5343
5343
  }
5344
5344
 
5345
- const AttributeListPrintPlugin = {
5345
+ const AttributeListPlugin = {
5346
5346
  match(model) {
5347
5347
  return model.$$type === 'AttributeList';
5348
5348
  },
@@ -5357,7 +5357,7 @@ const AttributeListPrintPlugin = {
5357
5357
  },
5358
5358
  };
5359
5359
 
5360
- const EdgeConvertPlugin = {
5360
+ const EdgePlugin$1 = {
5361
5361
  match(model) {
5362
5362
  return model.$$type === 'Edge';
5363
5363
  },
@@ -5427,7 +5427,7 @@ const EdgeConvertPlugin = {
5427
5427
  },
5428
5428
  };
5429
5429
 
5430
- const GraphConvertPlugin = {
5430
+ const GraphPlugin$1 = {
5431
5431
  match(model) {
5432
5432
  return model.$$type === 'Graph';
5433
5433
  },
@@ -5456,7 +5456,7 @@ const GraphConvertPlugin = {
5456
5456
  },
5457
5457
  };
5458
5458
 
5459
- const NodeConvertPlugin = {
5459
+ const NodePlugin$1 = {
5460
5460
  match(model) {
5461
5461
  return model.$$type === 'Node';
5462
5462
  },
@@ -5481,7 +5481,7 @@ const NodeConvertPlugin = {
5481
5481
  },
5482
5482
  };
5483
5483
 
5484
- const SubgraphConvertPlugin = {
5484
+ const SubgraphPlugin$1 = {
5485
5485
  match(model) {
5486
5486
  return model.$$type === 'Subgraph';
5487
5487
  },
@@ -5505,13 +5505,7 @@ const SubgraphConvertPlugin = {
5505
5505
  },
5506
5506
  };
5507
5507
 
5508
- const defaultPlugins = [
5509
- AttributeListPrintPlugin,
5510
- EdgeConvertPlugin,
5511
- NodeConvertPlugin,
5512
- GraphConvertPlugin,
5513
- SubgraphConvertPlugin,
5514
- ];
5508
+ const defaultPlugins$1 = [AttributeListPlugin, EdgePlugin$1, NodePlugin$1, GraphPlugin$1, SubgraphPlugin$1];
5515
5509
 
5516
5510
  /**
5517
5511
  * @group Convert Model to AST
@@ -5519,7 +5513,7 @@ const defaultPlugins = [
5519
5513
  class FromModelConverter {
5520
5514
  options;
5521
5515
  /** @hidden */
5522
- #plugins = [...defaultPlugins];
5516
+ #plugins = [...defaultPlugins$1];
5523
5517
  constructor(options = {}) {
5524
5518
  this.options = options;
5525
5519
  }
@@ -5530,7 +5524,6 @@ class FromModelConverter {
5530
5524
  commentKind,
5531
5525
  convert(m) {
5532
5526
  for (const plugin of plugins) {
5533
- /* */
5534
5527
  if (plugin.match(m)) {
5535
5528
  return plugin.convert(context, m);
5536
5529
  }
@@ -5549,11 +5542,226 @@ function fromModel(model, options) {
5549
5542
  return new FromModelConverter(options).convert(model);
5550
5543
  }
5551
5544
 
5545
+ class CommentHolder {
5546
+ comment = null;
5547
+ set(comment) {
5548
+ this.comment = comment;
5549
+ }
5550
+ reset() {
5551
+ this.comment = null;
5552
+ }
5553
+ apply(model, location) {
5554
+ if (location && this.comment?.location) {
5555
+ if (this.comment?.kind === 'Block') {
5556
+ if (this.comment.location.end.line === location.start.line - 1) {
5557
+ model.comment = this.comment.value;
5558
+ }
5559
+ } else {
5560
+ if (this.comment.location.end.line === location.start.line) {
5561
+ model.comment = this.comment.value;
5562
+ }
5563
+ }
5564
+ } else {
5565
+ model.comment = this.comment?.value;
5566
+ }
5567
+ this.reset();
5568
+ }
5569
+ }
5570
+
5571
+ const DotPlugin = {
5572
+ match(ast) {
5573
+ return ast.type === 'Dot';
5574
+ },
5575
+ convert(context, ast) {
5576
+ const commentHolder = new CommentHolder();
5577
+ for (const stmt of ast.children) {
5578
+ switch (stmt.type) {
5579
+ case 'Comment':
5580
+ commentHolder.set(stmt);
5581
+ break;
5582
+ case 'Graph':
5583
+ const graph = context.convert(stmt);
5584
+ commentHolder.apply(graph, stmt.location);
5585
+ return graph;
5586
+ }
5587
+ }
5588
+ throw Error();
5589
+ },
5590
+ };
5591
+
5592
+ function convertToEdgeTargetTuple(edge) {
5593
+ return edge.targets.map((t) => {
5594
+ switch (t.type) {
5595
+ case 'NodeRef':
5596
+ return { id: t.id.value, port: t.port?.value, compass: t.compass?.value };
5597
+ case 'NodeRefGroup':
5598
+ return t.children.map((t) => ({ id: t.id.value, port: t.port?.value, compass: t.compass?.value }));
5599
+ }
5600
+ });
5601
+ }
5602
+
5603
+ const EdgePlugin = {
5604
+ match(ast) {
5605
+ return ast.type === 'Edge';
5606
+ },
5607
+ convert(context, ast) {
5608
+ const edge = new context.models.Edge(
5609
+ convertToEdgeTargetTuple(ast),
5610
+ ast.children
5611
+ .filter((v) => v.type === 'Attribute')
5612
+ .reduce((prev, curr) => ({ ...prev, [curr.key.value]: curr.value.value }), {}),
5613
+ );
5614
+ return edge;
5615
+ },
5616
+ };
5617
+
5618
+ function applyStatements(graph, statements) {
5619
+ const commentHolder = new CommentHolder();
5620
+ for (const stmt of statements) {
5621
+ switch (stmt.type) {
5622
+ case 'Subgraph':
5623
+ const subgraph = stmt.id ? graph.subgraph(stmt.id.value) : graph.subgraph();
5624
+ applyStatements(subgraph, stmt.children);
5625
+ commentHolder.apply(subgraph, stmt.location);
5626
+ break;
5627
+ case 'Attribute':
5628
+ graph.set(stmt.key.value, stmt.value.value);
5629
+ commentHolder.reset();
5630
+ break;
5631
+ case 'Node':
5632
+ commentHolder.apply(
5633
+ graph.node(
5634
+ stmt.id.value,
5635
+ stmt.children
5636
+ .filter((v) => v.type === 'Attribute')
5637
+ .reduce((prev, curr) => ({ ...prev, [curr.key.value]: curr.value.value }), {}),
5638
+ ),
5639
+ stmt.location,
5640
+ );
5641
+ break;
5642
+ case 'Edge':
5643
+ commentHolder.apply(
5644
+ graph.edge(
5645
+ convertToEdgeTargetTuple(stmt),
5646
+ stmt.children
5647
+ .filter((v) => v.type === 'Attribute')
5648
+ .reduce((prev, curr) => ({ ...prev, [curr.key.value]: curr.value.value }), {}),
5649
+ ),
5650
+ stmt.location,
5651
+ );
5652
+ break;
5653
+ case 'AttributeList':
5654
+ const attrs = stmt.children
5655
+ .filter((v) => v.type === 'Attribute')
5656
+ .reduce((prev, curr) => ({ ...prev, [curr.key.value]: curr.value.value }), {});
5657
+ switch (stmt.kind) {
5658
+ case 'Edge':
5659
+ graph.edge(attrs);
5660
+ break;
5661
+ case 'Node':
5662
+ graph.node(attrs);
5663
+ break;
5664
+ case 'Graph':
5665
+ graph.graph(attrs);
5666
+ break;
5667
+ }
5668
+ commentHolder.reset();
5669
+ break;
5670
+ case 'Comment':
5671
+ commentHolder.set(stmt);
5672
+ }
5673
+ }
5674
+ }
5675
+
5676
+ const GraphPlugin = {
5677
+ match(ast) {
5678
+ return ast.type === 'Graph';
5679
+ },
5680
+ convert(context, ast) {
5681
+ const G = ast.directed ? context.models.Digraph : context.models.Graph;
5682
+ const graph = new G(ast.id?.value, ast.strict);
5683
+ applyStatements(graph, ast.children);
5684
+ return graph;
5685
+ },
5686
+ };
5687
+
5688
+ const SubgraphPlugin = {
5689
+ match(ast) {
5690
+ return ast.type === 'Subgraph';
5691
+ },
5692
+ convert(context, ast) {
5693
+ const subgraph = new context.models.Subgraph(ast.id?.value);
5694
+ applyStatements(subgraph, ast.children);
5695
+ return subgraph;
5696
+ },
5697
+ };
5698
+
5699
+ const NodePlugin = {
5700
+ match(ast) {
5701
+ return ast.type === 'Node';
5702
+ },
5703
+ convert(context, ast) {
5704
+ const node = new context.models.Node(
5705
+ ast.id.value,
5706
+ ast.children
5707
+ .filter((v) => v.type === 'Attribute')
5708
+ .reduce((prev, curr) => ({ ...prev, [curr.key.value]: curr.value.value }), {}),
5709
+ );
5710
+ return node;
5711
+ },
5712
+ };
5713
+
5714
+ const defaultPlugins = [NodePlugin, EdgePlugin, SubgraphPlugin, GraphPlugin, DotPlugin];
5715
+
5716
+ /**
5717
+ * @group Convert AST to Model
5718
+ * @alpha
5719
+ */
5720
+ class ToModelConverter {
5721
+ options;
5722
+ /** @hidden */
5723
+ plugins = [...defaultPlugins];
5724
+ constructor(options = {}) {
5725
+ this.options = options;
5726
+ }
5727
+ /**
5728
+ * Convert AST to Model.
5729
+ *
5730
+ * @param ast AST node.
5731
+ * @alpha
5732
+ */
5733
+ convert(ast) {
5734
+ const plugins = [...this.plugins];
5735
+ const context = {
5736
+ models: common.createModelsContext(this.options.models ?? {}),
5737
+ convert(m) {
5738
+ for (const plugin of plugins) {
5739
+ if (plugin.match(m)) {
5740
+ return plugin.convert(context, m);
5741
+ }
5742
+ }
5743
+ throw Error();
5744
+ },
5745
+ };
5746
+ return context.convert(ast);
5747
+ }
5748
+ }
5749
+
5750
+ /**
5751
+ * @group Convert AST to Model
5752
+ * @beta
5753
+ */
5754
+ function toModel(ast, options) {
5755
+ return new ToModelConverter(options).convert(ast);
5756
+ }
5757
+
5552
5758
  exports.Builder = Builder;
5553
5759
  exports.FromModelConverter = FromModelConverter;
5554
5760
  exports.Printer = Printer;
5555
5761
  exports.SyntaxError = SyntaxError;
5762
+ exports.ToModelConverter = ToModelConverter;
5556
5763
  exports.createElement = createElement;
5557
5764
  exports.fromModel = fromModel;
5558
5765
  exports.parse = parse;
5559
5766
  exports.stringify = stringify;
5767
+ exports.toModel = toModel;
@@ -1,4 +1,14 @@
1
- import { Compass, AttributeKey, ASTType, DotObjectType, DotObjectModel } from '#lib/common';
1
+ import {
2
+ Compass,
3
+ AttributeKey,
4
+ ASTType,
5
+ DotObjectModel,
6
+ RootGraphModel,
7
+ EdgeModel,
8
+ NodeModel,
9
+ SubgraphModel,
10
+ ModelsContext,
11
+ } from '#lib/common';
2
12
 
3
13
  /**
4
14
  * @group AST
@@ -432,6 +442,7 @@ declare function parse(input: string, options?: ParseOptions<'AttributeList'>):
432
442
  declare function parse(input: string, options?: ParseOptions<'Attribute'>): AttributeASTNode;
433
443
  declare function parse(input: string, options?: ParseOptions<'Subgraph'>): SubgraphASTNode;
434
444
  declare function parse(input: string, options?: ParseOptions<'ClusterStatements'>): ClusterStatementASTNode[];
445
+ declare function parse(input: string, options?: ParseOptions<Rule>): ASTNode | ClusterStatementASTNode[];
435
446
  /**
436
447
  * @group Convert DOT to AST
437
448
  */
@@ -440,9 +451,7 @@ declare const SyntaxError: typeof SyntaxError$1;
440
451
  /**
441
452
  * @group AST
442
453
  */
443
- declare type ModelToAST<T> = T extends {
444
- $$type: infer U extends DotObjectType;
445
- }
454
+ declare type ModelToAST<T> = T extends DotObjectModel<infer U>
446
455
  ? U extends 'Graph'
447
456
  ? GraphASTNode | DotASTNode
448
457
  : U extends 'AttributeList'
@@ -493,6 +502,79 @@ declare class FromModelConverter {
493
502
  */
494
503
  declare function fromModel<T extends DotObjectModel>(model: T, options?: ConvertFromModelOptions): ModelToAST<T>;
495
504
 
505
+ /**
506
+ * @group AST
507
+ */
508
+ declare type ModelOf<T> = T extends 'Dot' | 'Graph'
509
+ ? RootGraphModel
510
+ : T extends 'Edge'
511
+ ? EdgeModel
512
+ : T extends 'Node'
513
+ ? NodeModel
514
+ : T extends 'Subgraph'
515
+ ? SubgraphModel
516
+ : never;
517
+ /**
518
+ * @group AST
519
+ */
520
+ declare type ASTToModel<T> = T extends {
521
+ type: infer U;
522
+ }
523
+ ? ModelOf<U>
524
+ : never;
525
+ /**
526
+ * @group Convert AST to Model
527
+ * @beta
528
+ */
529
+ declare type ToModelConvertableASTNode = DotASTNode | GraphASTNode | SubgraphASTNode | NodeASTNode | EdgeASTNode;
530
+ /**
531
+ * @group Convert AST to Model
532
+ * @alpha
533
+ */
534
+ interface ConvertToModelOptions {
535
+ models?: Partial<ModelsContext>;
536
+ }
537
+ /**
538
+ * @group Convert AST to Model
539
+ * @alpha
540
+ */
541
+ interface ConvertToModelContext {
542
+ models: ModelsContext;
543
+ convert<T extends ToModelConvertableASTNode>(ast: T): ASTToModel<T>;
544
+ }
545
+ /**
546
+ * @group Convert AST to Model
547
+ * @alpha
548
+ */
549
+ interface ConvertToModelPlugin<T extends ToModelConvertableASTNode = ToModelConvertableASTNode> {
550
+ match(ast: T): boolean;
551
+ convert(context: ConvertToModelContext, ast: T): ASTToModel<T>;
552
+ }
553
+
554
+ /**
555
+ * @group Convert AST to Model
556
+ * @alpha
557
+ */
558
+ declare class ToModelConverter {
559
+ private options;
560
+ /** @hidden */
561
+ protected plugins: ConvertToModelPlugin<ToModelConvertableASTNode>[];
562
+ constructor(options?: ConvertToModelOptions);
563
+ /**
564
+ * Convert AST to Model.
565
+ *
566
+ * @param ast AST node.
567
+ * @alpha
568
+ */
569
+ convert<T extends ToModelConvertableASTNode>(ast: T): ASTToModel<T>;
570
+ }
571
+
572
+ /**
573
+ * @group Convert AST to Model
574
+ * @beta
575
+ */
576
+ declare function toModel<T extends ToModelConvertableASTNode>(ast: T, options?: ConvertToModelOptions): ASTToModel<T>;
577
+
496
578
  export {
497
579
  ASTBaseNode,
498
580
  ASTBaseParentNode,
@@ -500,6 +582,7 @@ export {
500
582
  ASTChildNode,
501
583
  ASTCommonPropaties,
502
584
  ASTNode,
585
+ ASTToModel,
503
586
  AttributeASTNode,
504
587
  AttributeASTPropaties,
505
588
  AttributeListASTNode,
@@ -514,6 +597,9 @@ export {
514
597
  ConvertFromModelContext,
515
598
  ConvertFromModelOptions,
516
599
  ConvertFromModelPlugin,
600
+ ConvertToModelContext,
601
+ ConvertToModelOptions,
602
+ ConvertToModelPlugin,
517
603
  CreateElement,
518
604
  DotASTNode,
519
605
  DotASTPropaties,
@@ -529,6 +615,7 @@ export {
529
615
  IndentStyle,
530
616
  LiteralASTNode,
531
617
  LiteralASTPropaties,
618
+ ModelOf,
532
619
  ModelToAST,
533
620
  NodeASTNode,
534
621
  NodeASTPropaties,
@@ -546,8 +633,11 @@ export {
546
633
  SubgraphASTNode,
547
634
  SubgraphASTPropaties,
548
635
  SyntaxError,
636
+ ToModelConvertableASTNode,
637
+ ToModelConverter,
549
638
  createElement,
550
639
  fromModel,
551
640
  parse,
552
641
  stringify,
642
+ toModel,
553
643
  };