@polagram/core 0.0.3 → 0.0.4

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.
Files changed (40) hide show
  1. package/dist/index.d.ts +104 -6
  2. package/dist/polagram-core.js +2689 -2157
  3. package/dist/polagram-core.umd.cjs +20 -14
  4. package/dist/src/api.d.ts +12 -3
  5. package/dist/src/api.js +26 -3
  6. package/dist/src/config/schema.d.ts +16 -0
  7. package/dist/src/config/schema.js +5 -1
  8. package/dist/src/generator/generators/plantuml.d.ts +17 -0
  9. package/dist/src/generator/generators/plantuml.js +131 -0
  10. package/dist/src/generator/generators/plantuml.test.d.ts +1 -0
  11. package/dist/src/generator/generators/plantuml.test.js +143 -0
  12. package/dist/src/index.d.ts +4 -0
  13. package/dist/src/index.js +4 -0
  14. package/dist/src/parser/base/lexer.d.ts +3 -3
  15. package/dist/src/parser/base/parser.d.ts +9 -9
  16. package/dist/src/parser/base/token.d.ts +18 -0
  17. package/dist/src/parser/base/token.js +1 -0
  18. package/dist/src/parser/base/tokens.d.ts +8 -0
  19. package/dist/src/parser/base/tokens.js +1 -0
  20. package/dist/src/parser/format-detector.d.ts +55 -0
  21. package/dist/src/parser/format-detector.js +98 -0
  22. package/dist/src/parser/index.d.ts +1 -0
  23. package/dist/src/parser/index.js +4 -0
  24. package/dist/src/parser/languages/mermaid/lexer.d.ts +1 -1
  25. package/dist/src/parser/languages/mermaid/parser.d.ts +2 -1
  26. package/dist/src/parser/languages/plantuml/index.d.ts +4 -0
  27. package/dist/src/parser/languages/plantuml/index.js +11 -0
  28. package/dist/src/parser/languages/plantuml/lexer.d.ts +15 -0
  29. package/dist/src/parser/languages/plantuml/lexer.js +143 -0
  30. package/dist/src/parser/languages/plantuml/parser.d.ts +23 -0
  31. package/dist/src/parser/languages/plantuml/parser.js +481 -0
  32. package/dist/src/parser/languages/plantuml/parser.test.d.ts +1 -0
  33. package/dist/src/parser/languages/plantuml/parser.test.js +236 -0
  34. package/dist/src/parser/languages/plantuml/tokens.d.ts +9 -0
  35. package/dist/src/parser/languages/plantuml/tokens.js +1 -0
  36. package/dist/src/transformer/orchestration/engine.test.js +12 -1
  37. package/dist/src/transformer/selector/matcher.test.js +17 -0
  38. package/dist/src/transformer/traverse/walker.test.js +67 -4
  39. package/dist/tsconfig.tsbuildinfo +1 -1
  40. package/package.json +10 -9
package/dist/src/api.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { MermaidGeneratorVisitor } from './generator/generators/mermaid';
2
+ import { PlantUMLGeneratorVisitor } from './generator/generators/plantuml';
2
3
  import { ParserFactory } from './parser';
3
4
  import { TransformationEngine } from './transformer/orchestration/engine';
4
5
  /**
@@ -17,19 +18,19 @@ export class Polagram {
17
18
  /**
18
19
  * Initialize a new Polagram transformation pipeline.
19
20
  * @param code Source diagram code
20
- * @param format Input format (currently only 'mermaid' is supported)
21
+ * @param format Input format ('mermaid' or 'plantuml')
21
22
  */
22
23
  static init(code, format = 'mermaid') {
23
24
  const parser = ParserFactory.getParser(format);
24
25
  const ast = parser.parse(code);
25
- return new PolagramBuilder(ast);
26
+ return new PolagramBuilder(ast, format);
26
27
  }
27
28
  }
28
29
  /**
29
30
  * Builder class for chaining transformations.
30
31
  */
31
32
  export class PolagramBuilder {
32
- constructor(ast) {
33
+ constructor(ast, sourceFormat = 'mermaid') {
33
34
  Object.defineProperty(this, "ast", {
34
35
  enumerable: true,
35
36
  configurable: true,
@@ -42,7 +43,14 @@ export class PolagramBuilder {
42
43
  writable: true,
43
44
  value: []
44
45
  });
46
+ Object.defineProperty(this, "sourceFormat", {
47
+ enumerable: true,
48
+ configurable: true,
49
+ writable: true,
50
+ value: void 0
51
+ });
45
52
  this.ast = ast;
53
+ this.sourceFormat = sourceFormat;
46
54
  }
47
55
  // -- Entity Filtering --
48
56
  /**
@@ -122,6 +130,15 @@ export class PolagramBuilder {
122
130
  const generator = new MermaidGeneratorVisitor();
123
131
  return generator.generate(transformedAst);
124
132
  }
133
+ /**
134
+ * Generate PlantUML code from the transformed AST.
135
+ */
136
+ toPlantUML() {
137
+ const engine = new TransformationEngine();
138
+ const transformedAst = engine.transform(this.ast, this.layers);
139
+ const generator = new PlantUMLGeneratorVisitor();
140
+ return generator.generate(transformedAst);
141
+ }
125
142
  /**
126
143
  * Get the transformed AST (for advanced use cases).
127
144
  */
@@ -129,6 +146,12 @@ export class PolagramBuilder {
129
146
  const engine = new TransformationEngine();
130
147
  return engine.transform(this.ast, this.layers);
131
148
  }
149
+ /**
150
+ * Get the source format detected/specified during init.
151
+ */
152
+ getSourceFormat() {
153
+ return this.sourceFormat;
154
+ }
132
155
  // -- Helper Methods --
133
156
  normalizeParticipantSelector(selector) {
134
157
  if (this.isTextMatcher(selector)) {
@@ -109,6 +109,14 @@ declare const TargetConfigSchema: z.ZodObject<{
109
109
  }, z.core.$strip>], "kind">;
110
110
  }, z.core.$strip>>;
111
111
  }, z.core.$strip>>;
112
+ format: z.ZodOptional<z.ZodEnum<{
113
+ mermaid: "mermaid";
114
+ plantuml: "plantuml";
115
+ }>>;
116
+ outputFormat: z.ZodOptional<z.ZodEnum<{
117
+ mermaid: "mermaid";
118
+ plantuml: "plantuml";
119
+ }>>;
112
120
  }, z.core.$strip>;
113
121
  export declare const PolagramConfigSchema: z.ZodObject<{
114
122
  version: z.ZodNumber;
@@ -169,6 +177,14 @@ export declare const PolagramConfigSchema: z.ZodObject<{
169
177
  }, z.core.$strip>], "kind">;
170
178
  }, z.core.$strip>>;
171
179
  }, z.core.$strip>>;
180
+ format: z.ZodOptional<z.ZodEnum<{
181
+ mermaid: "mermaid";
182
+ plantuml: "plantuml";
183
+ }>>;
184
+ outputFormat: z.ZodOptional<z.ZodEnum<{
185
+ mermaid: "mermaid";
186
+ plantuml: "plantuml";
187
+ }>>;
172
188
  }, z.core.$strip>>;
173
189
  }, z.core.$strip>;
174
190
  export type PolagramConfig = z.infer<typeof PolagramConfigSchema>;
@@ -50,12 +50,16 @@ const LensSchema = z.object({
50
50
  suffix: z.string().optional(), // Defaults to .name in logic
51
51
  layers: z.array(LayerSchema)
52
52
  });
53
+ // -- Format --
54
+ const DiagramFormatSchema = z.enum(['mermaid', 'plantuml']);
53
55
  // -- Config --
54
56
  const TargetConfigSchema = z.object({
55
57
  input: z.array(z.string()),
56
58
  outputDir: z.string(),
57
59
  ignore: z.array(z.string()).optional(),
58
- lenses: z.array(LensSchema)
60
+ lenses: z.array(LensSchema),
61
+ format: DiagramFormatSchema.optional(), // Input format (auto-detected if omitted)
62
+ outputFormat: DiagramFormatSchema.optional() // Output format (same as input if omitted)
59
63
  });
60
64
  export const PolagramConfigSchema = z.object({
61
65
  version: z.number(),
@@ -0,0 +1,17 @@
1
+ import { ActivationNode, DividerNode, FragmentNode, MessageNode, NoteNode, Participant, ParticipantGroup, PolagramRoot, ReferenceNode, SpacerNode } from '../../ast';
2
+ import { PolagramVisitor } from '../interface';
3
+ export declare class PlantUMLGeneratorVisitor implements PolagramVisitor {
4
+ generate(root: PolagramRoot): string;
5
+ visitRoot(node: PolagramRoot): string;
6
+ visitParticipant(node: Participant): string;
7
+ visitGroup(node: ParticipantGroup, context?: Map<string, Participant>): string;
8
+ visitMessage(node: MessageNode): string;
9
+ visitFragment(node: FragmentNode): string;
10
+ private visitEvent;
11
+ visitNote(node: NoteNode): string;
12
+ visitActivation(node: ActivationNode): string;
13
+ visitParticipantGroup(_node: ParticipantGroup): string;
14
+ visitDivider(_node: DividerNode): string;
15
+ visitSpacer(_node: SpacerNode): string;
16
+ visitReference(_node: ReferenceNode): string;
17
+ }
@@ -0,0 +1,131 @@
1
+ export class PlantUMLGeneratorVisitor {
2
+ generate(root) {
3
+ return this.visitRoot(root);
4
+ }
5
+ visitRoot(node) {
6
+ const lines = ['@startuml'];
7
+ if (node.meta.title) {
8
+ lines.push(`title ${node.meta.title}`);
9
+ }
10
+ const participantsMap = new Map(node.participants.map(p => [p.id, p]));
11
+ const groupedParticipantIds = new Set();
12
+ // Groups
13
+ for (const group of node.groups) {
14
+ lines.push(this.visitGroup(group, participantsMap));
15
+ group.participantIds.forEach(id => groupedParticipantIds.add(id));
16
+ }
17
+ // Ungrouped Participants
18
+ for (const participant of node.participants) {
19
+ if (!groupedParticipantIds.has(participant.id)) {
20
+ lines.push(this.visitParticipant(participant));
21
+ }
22
+ }
23
+ // Events
24
+ for (const event of node.events) {
25
+ lines.push(this.visitEvent(event));
26
+ }
27
+ lines.push('@enduml');
28
+ return lines.join('\n');
29
+ }
30
+ visitParticipant(node) {
31
+ // If Name == ID, use concise format: "type ID"
32
+ // Otherwise use explicit format: "type "Name" as ID"
33
+ if (node.name === node.id) {
34
+ return `${node.type} ${node.id}`;
35
+ }
36
+ return `${node.type} "${node.name}" as ${node.id}`;
37
+ }
38
+ // Adjusted signature to pass context
39
+ visitGroup(node, context) {
40
+ const parts = [];
41
+ const color = node.style?.backgroundColor ? ` ${node.style.backgroundColor}` : '';
42
+ const title = node.name ? ` "${node.name}"` : '';
43
+ parts.push(`box${title}${color}`);
44
+ if (context) {
45
+ for (const pid of node.participantIds) {
46
+ const p = context.get(pid);
47
+ if (p) {
48
+ parts.push(this.visitParticipant(p));
49
+ }
50
+ }
51
+ }
52
+ parts.push('end box');
53
+ return parts.join('\n');
54
+ }
55
+ visitMessage(node) {
56
+ const from = node.from || '[*]'; // Handle lost/found if needed
57
+ const to = node.to || '[*]';
58
+ let arrow = '->';
59
+ if (node.type === 'reply')
60
+ arrow = '-->';
61
+ else if (node.type === 'async')
62
+ arrow = '->>'; // PlantUML doesn't strictly distinguish async arrow head generally, but ->> is fine
63
+ // style override
64
+ if (node.style.line === 'dotted') {
65
+ // If reply, already --> (dotted). If sync but dotted: A -[dotted]-> B ?
66
+ // PlantUML: A ..> B
67
+ // But --> is usually standard reply.
68
+ }
69
+ return `${from} ${arrow} ${to}: ${node.text}`;
70
+ }
71
+ visitFragment(node) {
72
+ const lines = [];
73
+ const op = node.operator;
74
+ node.branches.forEach((branch, index) => {
75
+ if (index === 0) {
76
+ lines.push(`${op} ${branch.condition || ''}`.trim());
77
+ }
78
+ else {
79
+ lines.push(`else ${branch.condition || ''}`.trim());
80
+ }
81
+ for (const event of branch.events) {
82
+ // We need to recursively visit events (messages, nested fragments, etc.)
83
+ // But we can't easily call visitX because we don't know the type statically here or need a centralized dispatcher that returns string.
84
+ // But wait, visitRoot has a dispatcher. We should extract it to `visitEvent`.
85
+ // For now, let's duplicate the relevant dispatch logic or creating a helper.
86
+ lines.push(this.visitEvent(event));
87
+ }
88
+ });
89
+ lines.push('end');
90
+ return lines.join('\n');
91
+ }
92
+ visitEvent(event) {
93
+ switch (event.kind) {
94
+ case 'message': return this.visitMessage(event);
95
+ case 'fragment': return this.visitFragment(event);
96
+ case 'note': return this.visitNote(event);
97
+ case 'activation': return this.visitActivation(event);
98
+ case 'divider': return this.visitDivider(event);
99
+ case 'spacer': return this.visitSpacer(event);
100
+ case 'ref': return this.visitReference(event);
101
+ default: return '';
102
+ }
103
+ }
104
+ visitNote(node) {
105
+ const position = node.position || 'over';
106
+ const participants = node.participantIds.join(', ');
107
+ // note left of A: Text
108
+ // note over A, B: Text
109
+ // For 'over', we don't say 'of' in standard examples? "note over Alice", "note over Alice, Bob"
110
+ // But 'left of', 'right of' use 'of'.
111
+ const positionStr = (position === 'left' || position === 'right') ? `${position} of` : position;
112
+ return `note ${positionStr} ${participants}: ${node.text}`;
113
+ }
114
+ visitActivation(node) {
115
+ // activate A
116
+ // deactivate A
117
+ return `${node.action} ${node.participantId}`;
118
+ }
119
+ visitParticipantGroup(_node) {
120
+ return '';
121
+ }
122
+ visitDivider(_node) {
123
+ return '';
124
+ }
125
+ visitSpacer(_node) {
126
+ return '';
127
+ }
128
+ visitReference(_node) {
129
+ return '';
130
+ }
131
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,143 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { PlantUMLGeneratorVisitor } from './plantuml';
3
+ describe('PlantUML Generator', () => {
4
+ const generator = new PlantUMLGeneratorVisitor();
5
+ it('should generate basic document structure', () => {
6
+ const ast = {
7
+ kind: 'root',
8
+ meta: { version: '1.0.0', source: 'plantuml', title: 'My Diagram' },
9
+ participants: [],
10
+ groups: [],
11
+ events: []
12
+ };
13
+ const code = generator.generate(ast);
14
+ expect(code).toContain('@startuml');
15
+ expect(code).toContain('title My Diagram');
16
+ expect(code).toContain('@enduml');
17
+ });
18
+ it('should generate participants', () => {
19
+ const ast = {
20
+ kind: 'root',
21
+ meta: { version: '1.0.0', source: 'plantuml' },
22
+ participants: [
23
+ { id: 'User', name: 'User', type: 'actor' },
24
+ { id: 'DB', name: 'DB', type: 'database' },
25
+ { id: 'Svc', name: 'Service', type: 'participant' }
26
+ ],
27
+ groups: [],
28
+ events: []
29
+ };
30
+ const code = generator.generate(ast);
31
+ expect(code).toContain('actor User');
32
+ expect(code).toContain('database DB');
33
+ expect(code).toContain('participant "Service" as Svc');
34
+ });
35
+ it('should generate messages', () => {
36
+ const ast = {
37
+ kind: 'root',
38
+ meta: { version: '1.0.0', source: 'plantuml' },
39
+ participants: [
40
+ { id: 'A', name: 'A', type: 'participant' },
41
+ { id: 'B', name: 'B', type: 'participant' }
42
+ ],
43
+ groups: [],
44
+ events: [
45
+ { kind: 'message', id: 'm1', from: 'A', to: 'B', text: 'Sync', type: 'sync', style: { line: 'solid', head: 'arrow' } },
46
+ { kind: 'message', id: 'm2', from: 'B', to: 'A', text: 'Reply', type: 'reply', style: { line: 'dotted', head: 'arrow' } },
47
+ { kind: 'message', id: 'm3', from: 'A', to: 'A', text: 'Self', type: 'sync', style: { line: 'solid', head: 'arrow' } }
48
+ ]
49
+ };
50
+ const code = generator.generate(ast);
51
+ expect(code).toContain('A -> B: Sync');
52
+ expect(code).toContain('B --> A: Reply');
53
+ expect(code).toContain('A -> A: Self');
54
+ });
55
+ it('should generate fragments', () => {
56
+ const ast = {
57
+ kind: 'root',
58
+ meta: { version: '1.0.0', source: 'plantuml' },
59
+ participants: [],
60
+ groups: [],
61
+ events: [
62
+ {
63
+ kind: 'fragment',
64
+ id: 'f1',
65
+ operator: 'alt',
66
+ branches: [
67
+ { id: 'b1', condition: 'success', events: [
68
+ { kind: 'message', id: 'm1', from: 'A', to: 'B', text: 'OK', type: 'sync', style: { line: 'solid', head: 'arrow' } }
69
+ ] },
70
+ { id: 'b2', condition: 'failure', events: [
71
+ { kind: 'message', id: 'm2', from: 'A', to: 'B', text: 'Fail', type: 'sync', style: { line: 'solid', head: 'arrow' } }
72
+ ] }
73
+ ]
74
+ }
75
+ ]
76
+ };
77
+ const code = generator.generate(ast);
78
+ expect(code).toContain('alt success');
79
+ expect(code).toContain('A -> B: OK');
80
+ expect(code).toContain('else failure');
81
+ expect(code).toContain('A -> B: Fail');
82
+ expect(code).toContain('end');
83
+ });
84
+ it('should generate notes', () => {
85
+ const ast = {
86
+ kind: 'root',
87
+ meta: { version: '1.0.0', source: 'plantuml' },
88
+ participants: [
89
+ { id: 'A', name: 'A', type: 'participant' }
90
+ ],
91
+ groups: [],
92
+ events: [
93
+ { kind: 'note', id: 'n1', text: 'My Note', position: 'right', participantIds: ['A'] },
94
+ { kind: 'note', id: 'n2', text: 'Over Note', position: 'over', participantIds: ['A'] }
95
+ ]
96
+ };
97
+ const code = generator.generate(ast);
98
+ expect(code).toContain('note right of A: My Note');
99
+ expect(code).toContain('note over A: Over Note');
100
+ });
101
+ it('should generate lifecycle events', () => {
102
+ const ast = {
103
+ kind: 'root',
104
+ meta: { version: '1.0.0', source: 'plantuml' },
105
+ participants: [
106
+ { id: 'A', name: 'A', type: 'participant' }
107
+ ],
108
+ groups: [],
109
+ events: [
110
+ { kind: 'activation', participantId: 'A', action: 'activate' },
111
+ // Some message presumably
112
+ { kind: 'activation', participantId: 'A', action: 'deactivate' }
113
+ ]
114
+ };
115
+ const code = generator.generate(ast);
116
+ expect(code).toContain('activate A');
117
+ expect(code).toContain('deactivate A');
118
+ });
119
+ it('should generate groups', () => {
120
+ const ast = {
121
+ kind: 'root',
122
+ meta: { version: '1.0.0', source: 'plantuml' },
123
+ participants: [
124
+ { id: 'A', name: 'A', type: 'participant' },
125
+ { id: 'B', name: 'B', type: 'participant' },
126
+ { id: 'C', name: 'C', type: 'participant' }
127
+ ],
128
+ groups: [
129
+ { kind: 'group', id: 'g1', name: 'Box1', type: 'box', participantIds: ['A', 'B'], style: { backgroundColor: '#LightBlue' } }
130
+ ],
131
+ events: []
132
+ };
133
+ const code = generator.generate(ast);
134
+ // Expect Box1 to contain A and B
135
+ // C should be outside
136
+ // Exact order depends on implementation, but box should be there
137
+ expect(code).toContain('box "Box1" #LightBlue');
138
+ expect(code).toContain('participant A');
139
+ expect(code).toContain('participant B');
140
+ expect(code).toContain('end box');
141
+ expect(code).toContain('participant C');
142
+ });
143
+ });
@@ -1,9 +1,13 @@
1
1
  export * from './ast';
2
2
  export { ParserFactory } from './parser';
3
+ export { FormatDetector } from './parser/format-detector';
4
+ export type { DiagramFormat } from './parser/format-detector';
3
5
  export type { DiagramParser } from './parser/interface';
4
6
  export { Traverser } from './generator/base/walker';
5
7
  export type { PolagramVisitor } from './generator/interface';
8
+ export * from './config/schema';
6
9
  export { MermaidGeneratorVisitor } from './generator/generators/mermaid';
10
+ export { PlantUMLGeneratorVisitor } from './generator/generators/plantuml';
7
11
  export * from './transformer';
8
12
  export { Polagram, PolagramBuilder } from './api';
9
13
  export * from './config';
package/dist/src/index.js CHANGED
@@ -3,11 +3,15 @@
3
3
  export * from './ast';
4
4
  // Parsers (Factory & Strategy)
5
5
  export { ParserFactory } from './parser';
6
+ export { FormatDetector } from './parser/format-detector';
6
7
  // Generators
7
8
  export { Traverser } from './generator/base/walker';
8
9
  // Default Implementations (Optional, or force users to use Factory)
9
10
  // We export Mermaid Generator specifically as it might be used directly or via a future Factory
11
+ // Config & Validation
12
+ export * from './config/schema';
10
13
  export { MermaidGeneratorVisitor } from './generator/generators/mermaid';
14
+ export { PlantUMLGeneratorVisitor } from './generator/generators/plantuml';
11
15
  // Transformation Engine
12
16
  export * from './transformer';
13
17
  // Fluent API (Recommended for most users)
@@ -1,5 +1,5 @@
1
- import { Token } from '../languages/mermaid/tokens';
2
- export declare abstract class BaseLexer {
1
+ import { BaseToken } from './token';
2
+ export declare abstract class BaseLexer<T extends BaseToken = BaseToken> {
3
3
  protected input: string;
4
4
  protected position: number;
5
5
  protected readPosition: number;
@@ -8,7 +8,7 @@ export declare abstract class BaseLexer {
8
8
  protected column: number;
9
9
  constructor(input: string);
10
10
  getInput(): string;
11
- abstract nextToken(): Token;
11
+ abstract nextToken(): T;
12
12
  protected readChar(): void;
13
13
  protected peekChar(): string;
14
14
  protected skipWhitespace(): void;
@@ -1,14 +1,14 @@
1
1
  import { PolagramRoot } from '../../ast';
2
- import { Token, TokenType } from '../languages/mermaid/tokens';
3
2
  import { BaseLexer } from './lexer';
4
- export declare abstract class BaseParser {
5
- protected lexer: BaseLexer;
6
- protected currToken: Token;
7
- protected peekToken: Token;
8
- constructor(lexer: BaseLexer);
3
+ import { BaseToken } from './token';
4
+ export declare abstract class BaseParser<T extends BaseToken = BaseToken> {
5
+ protected lexer: BaseLexer<T>;
6
+ protected currToken: T;
7
+ protected peekToken: T;
8
+ constructor(lexer: BaseLexer<T>);
9
9
  protected advance(): void;
10
10
  abstract parse(): PolagramRoot;
11
- protected curTokenIs(t: TokenType): boolean;
12
- protected peekTokenIs(t: TokenType): boolean;
13
- protected expectPeek(t: TokenType): boolean;
11
+ protected curTokenIs(t: string): boolean;
12
+ protected peekTokenIs(t: string): boolean;
13
+ protected expectPeek(t: string): boolean;
14
14
  }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Base token interface that all token types should extend.
3
+ * Represents a lexical token with position information.
4
+ */
5
+ export interface BaseToken {
6
+ /** Token type identifier */
7
+ type: string;
8
+ /** Literal string value of the token */
9
+ literal: string;
10
+ /** Line number (1-indexed) */
11
+ line: number;
12
+ /** Column number (0-indexed) */
13
+ column: number;
14
+ /** Start position in source (0-indexed) */
15
+ start: number;
16
+ /** End position in source (0-indexed) */
17
+ end: number;
18
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ export interface BaseToken {
2
+ type: string;
3
+ literal: string;
4
+ line: number;
5
+ column: number;
6
+ start: number;
7
+ end: number;
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Supported diagram formats
3
+ */
4
+ export type DiagramFormat = 'mermaid' | 'plantuml';
5
+ /**
6
+ * Format detection utilities for diagram source code.
7
+ * Detects diagram format based on file extension and content analysis.
8
+ */
9
+ export declare class FormatDetector {
10
+ /**
11
+ * File extensions mapped to their diagram formats
12
+ */
13
+ private static readonly EXTENSION_MAP;
14
+ /**
15
+ * Content patterns for format detection
16
+ */
17
+ private static readonly CONTENT_PATTERNS;
18
+ /**
19
+ * Detect diagram format from file path and content.
20
+ *
21
+ * @param filePath - Path to the diagram file
22
+ * @param content - Content of the diagram file
23
+ * @returns Detected format, or null if format cannot be determined
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const format = FormatDetector.detect('diagram.puml', content);
28
+ * if (format === 'plantuml') {
29
+ * // Process as PlantUML
30
+ * }
31
+ * ```
32
+ */
33
+ static detect(filePath: string, content: string): DiagramFormat | null;
34
+ /**
35
+ * Detect format based on file extension.
36
+ *
37
+ * @param filePath - Path to the diagram file
38
+ * @returns Detected format, or null if extension is not recognized
39
+ */
40
+ static detectByExtension(filePath: string): DiagramFormat | null;
41
+ /**
42
+ * Detect format based on content patterns.
43
+ *
44
+ * @param content - Content of the diagram file
45
+ * @returns Detected format, or null if no pattern matches
46
+ */
47
+ static detectByContent(content: string): DiagramFormat | null;
48
+ /**
49
+ * Get file extension for a given format.
50
+ *
51
+ * @param format - Diagram format
52
+ * @returns Default file extension for the format
53
+ */
54
+ static getDefaultExtension(format: DiagramFormat): string;
55
+ }