@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
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Format detection utilities for diagram source code.
3
+ * Detects diagram format based on file extension and content analysis.
4
+ */
5
+ export class FormatDetector {
6
+ /**
7
+ * Detect diagram format from file path and content.
8
+ *
9
+ * @param filePath - Path to the diagram file
10
+ * @param content - Content of the diagram file
11
+ * @returns Detected format, or null if format cannot be determined
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const format = FormatDetector.detect('diagram.puml', content);
16
+ * if (format === 'plantuml') {
17
+ * // Process as PlantUML
18
+ * }
19
+ * ```
20
+ */
21
+ static detect(filePath, content) {
22
+ // Try extension-based detection first
23
+ const extensionFormat = this.detectByExtension(filePath);
24
+ if (extensionFormat) {
25
+ return extensionFormat;
26
+ }
27
+ // Fall back to content-based detection
28
+ return this.detectByContent(content);
29
+ }
30
+ /**
31
+ * Detect format based on file extension.
32
+ *
33
+ * @param filePath - Path to the diagram file
34
+ * @returns Detected format, or null if extension is not recognized
35
+ */
36
+ static detectByExtension(filePath) {
37
+ const ext = filePath.toLowerCase().match(/\.[^.]+$/)?.[0];
38
+ if (!ext) {
39
+ return null;
40
+ }
41
+ return this.EXTENSION_MAP[ext] || null;
42
+ }
43
+ /**
44
+ * Detect format based on content patterns.
45
+ *
46
+ * @param content - Content of the diagram file
47
+ * @returns Detected format, or null if no pattern matches
48
+ */
49
+ static detectByContent(content) {
50
+ for (const { pattern, format } of this.CONTENT_PATTERNS) {
51
+ if (pattern.test(content)) {
52
+ return format;
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+ /**
58
+ * Get file extension for a given format.
59
+ *
60
+ * @param format - Diagram format
61
+ * @returns Default file extension for the format
62
+ */
63
+ static getDefaultExtension(format) {
64
+ switch (format) {
65
+ case 'plantuml':
66
+ return '.puml';
67
+ case 'mermaid':
68
+ return '.mmd';
69
+ }
70
+ }
71
+ }
72
+ /**
73
+ * File extensions mapped to their diagram formats
74
+ */
75
+ Object.defineProperty(FormatDetector, "EXTENSION_MAP", {
76
+ enumerable: true,
77
+ configurable: true,
78
+ writable: true,
79
+ value: {
80
+ '.puml': 'plantuml',
81
+ '.plantuml': 'plantuml',
82
+ '.pu': 'plantuml',
83
+ '.mmd': 'mermaid',
84
+ '.mermaid': 'mermaid',
85
+ }
86
+ });
87
+ /**
88
+ * Content patterns for format detection
89
+ */
90
+ Object.defineProperty(FormatDetector, "CONTENT_PATTERNS", {
91
+ enumerable: true,
92
+ configurable: true,
93
+ writable: true,
94
+ value: [
95
+ { pattern: /^\s*@startuml/m, format: 'plantuml' },
96
+ { pattern: /^\s*sequenceDiagram/m, format: 'mermaid' },
97
+ ]
98
+ });
@@ -8,3 +8,4 @@ export declare class ParserFactory {
8
8
  static register(language: string, parser: DiagramParser): void;
9
9
  static getParser(language: string): DiagramParser;
10
10
  }
11
+ export { FormatDetector, type DiagramFormat } from './format-detector';
@@ -1,5 +1,6 @@
1
1
  var _a;
2
2
  import { mermaidParser } from './languages/mermaid';
3
+ import { plantumlParser } from './languages/plantuml';
3
4
  /**
4
5
  * Parser Factory
5
6
  * Centralizes retrieval of parser strategies.
@@ -26,4 +27,7 @@ Object.defineProperty(ParserFactory, "parsers", {
26
27
  (() => {
27
28
  // Register built-in parsers
28
29
  _a.register('mermaid', mermaidParser);
30
+ _a.register('plantuml', plantumlParser);
29
31
  })();
32
+ // Re-export format detector
33
+ export { FormatDetector } from './format-detector';
@@ -1,6 +1,6 @@
1
1
  import { BaseLexer } from '../../base/lexer';
2
2
  import { Token } from './tokens';
3
- export declare class Lexer extends BaseLexer {
3
+ export declare class Lexer extends BaseLexer<Token> {
4
4
  constructor(input: string);
5
5
  nextToken(): Token;
6
6
  private newToken;
@@ -1,7 +1,8 @@
1
1
  import { PolagramRoot } from '../../../ast';
2
2
  import { BaseParser } from '../../base/parser';
3
3
  import { Lexer } from './lexer';
4
- export declare class Parser extends BaseParser {
4
+ import { Token } from './tokens';
5
+ export declare class Parser extends BaseParser<Token> {
5
6
  private currentGroup;
6
7
  private idCounters;
7
8
  constructor(lexer: Lexer);
@@ -0,0 +1,4 @@
1
+ import { DiagramParser } from '../../interface';
2
+ export declare const plantumlParser: DiagramParser;
3
+ export { Lexer } from './lexer';
4
+ export { Parser } from './parser';
@@ -0,0 +1,11 @@
1
+ import { Lexer } from './lexer';
2
+ import { Parser } from './parser';
3
+ export const plantumlParser = {
4
+ parse: (code) => {
5
+ const lexer = new Lexer(code);
6
+ const parser = new Parser(lexer);
7
+ return parser.parse();
8
+ }
9
+ };
10
+ export { Lexer } from './lexer';
11
+ export { Parser } from './parser';
@@ -0,0 +1,15 @@
1
+ import { BaseLexer } from '../../base/lexer';
2
+ import { Token } from './tokens';
3
+ export declare class Lexer extends BaseLexer<Token> {
4
+ constructor(input: string);
5
+ nextToken(): Token;
6
+ private newToken;
7
+ private readIdentifier;
8
+ private readString;
9
+ private lookupIdent;
10
+ private readArrow;
11
+ private peekExact;
12
+ private peekString;
13
+ readRestOfLine(): string;
14
+ private readMulti;
15
+ }
@@ -0,0 +1,143 @@
1
+ import { BaseLexer } from '../../base/lexer';
2
+ export class Lexer extends BaseLexer {
3
+ constructor(input) {
4
+ super(input);
5
+ }
6
+ nextToken() {
7
+ this.skipWhitespace();
8
+ const start = this.position;
9
+ const startColumn = this.column;
10
+ let tok;
11
+ switch (this.ch) {
12
+ case '\n':
13
+ tok = this.newToken('NEWLINE', this.ch, start, startColumn);
14
+ break;
15
+ case '@':
16
+ if (this.peekString('startuml')) {
17
+ this.readMulti(9);
18
+ tok = this.newToken('START_UML', '@startuml', start, startColumn);
19
+ }
20
+ else if (this.peekString('enduml')) {
21
+ this.readMulti(7);
22
+ tok = this.newToken('END_UML', '@enduml', start, startColumn);
23
+ }
24
+ else {
25
+ tok = this.newToken('UNKNOWN', this.ch, start, startColumn);
26
+ }
27
+ break;
28
+ case ',':
29
+ tok = this.newToken('COMMA', ',', start, startColumn);
30
+ break;
31
+ case '"':
32
+ const str = this.readString();
33
+ return this.newToken('STRING', str, start, startColumn);
34
+ case ':':
35
+ tok = this.newToken('COLON', ':', start, startColumn);
36
+ break;
37
+ case '-':
38
+ const arrow = this.readArrow();
39
+ if (arrow) {
40
+ tok = this.newToken('ARROW', arrow, start, startColumn);
41
+ }
42
+ else {
43
+ tok = this.newToken('UNKNOWN', this.ch, start, startColumn);
44
+ }
45
+ break;
46
+ case '':
47
+ tok = this.newToken('EOF', '', start, startColumn);
48
+ break;
49
+ default:
50
+ if (this.isLetter(this.ch)) {
51
+ const literal = this.readIdentifier();
52
+ const type = this.lookupIdent(literal);
53
+ return this.newToken(type, literal, start, startColumn);
54
+ }
55
+ else {
56
+ tok = this.newToken('UNKNOWN', this.ch, start, startColumn);
57
+ }
58
+ }
59
+ this.readChar();
60
+ return tok;
61
+ }
62
+ newToken(type, literal, start, startColumn) {
63
+ const end = (this.position === start) ? start + literal.length : this.position;
64
+ return { type, literal, line: this.line, column: startColumn, start, end };
65
+ }
66
+ readIdentifier() {
67
+ const position = this.position;
68
+ while (this.isLetter(this.ch) || this.isDigit(this.ch)) {
69
+ this.readChar();
70
+ }
71
+ return this.input.slice(position, this.position);
72
+ }
73
+ readString() {
74
+ const position = this.position + 1;
75
+ this.readChar();
76
+ while (this.ch !== '"' && this.ch !== '' && this.ch !== '\n') {
77
+ this.readChar();
78
+ }
79
+ const str = this.input.slice(position, this.position);
80
+ this.readChar();
81
+ return str;
82
+ }
83
+ lookupIdent(ident) {
84
+ const keywords = {
85
+ 'title': 'TITLE',
86
+ 'participant': 'PARTICIPANT',
87
+ 'actor': 'ACTOR',
88
+ 'database': 'DATABASE',
89
+ 'as': 'AS',
90
+ 'activate': 'ACTIVATE',
91
+ 'deactivate': 'DEACTIVATE',
92
+ 'note': 'NOTE',
93
+ 'left': 'LEFT',
94
+ 'right': 'RIGHT',
95
+ 'over': 'OVER',
96
+ 'of': 'OF',
97
+ 'alt': 'ALT',
98
+ 'opt': 'OPT',
99
+ 'loop': 'LOOP',
100
+ 'else': 'ELSE',
101
+ 'end': 'END',
102
+ 'box': 'BOX',
103
+ '@startuml': 'START_UML',
104
+ '@enduml': 'END_UML'
105
+ };
106
+ return keywords[ident] || 'IDENTIFIER';
107
+ }
108
+ readArrow() {
109
+ // We are at '-'
110
+ // Check for -->
111
+ if (this.peekString('->')) {
112
+ this.readMulti(2);
113
+ return '-->';
114
+ }
115
+ // Check for ->
116
+ if (this.peekExact('>')) {
117
+ this.readMulti(1);
118
+ return '->';
119
+ }
120
+ return null;
121
+ }
122
+ peekExact(char) {
123
+ return this.input[this.position + 1] === char;
124
+ }
125
+ peekString(str) {
126
+ for (let i = 0; i < str.length; i++) {
127
+ if (this.input[this.position + 1 + i] !== str[i])
128
+ return false;
129
+ }
130
+ return true;
131
+ }
132
+ readRestOfLine() {
133
+ const start = this.position;
134
+ while (this.input[this.position] !== '\n' && this.input[this.position] !== '' && this.position < this.input.length) {
135
+ this.readChar();
136
+ }
137
+ return this.input.slice(start, this.position).trim();
138
+ }
139
+ readMulti(count) {
140
+ for (let i = 0; i < count; i++)
141
+ this.readChar();
142
+ }
143
+ }
@@ -0,0 +1,23 @@
1
+ import { PolagramRoot } from '../../../ast';
2
+ import { BaseParser } from '../../base/parser';
3
+ import { Lexer } from './lexer';
4
+ import { Token } from './tokens';
5
+ export declare class Parser extends BaseParser<Token> {
6
+ constructor(lexer: Lexer);
7
+ /**
8
+ * Type-safe token type checker.
9
+ * Helps TypeScript understand token type after advance() calls.
10
+ */
11
+ private isTokenType;
12
+ parse(): PolagramRoot;
13
+ private parseGroup;
14
+ private parseFragment;
15
+ private parseStatement;
16
+ private parseNote;
17
+ private parseActivation;
18
+ private isParticipantToken;
19
+ private parseMessage;
20
+ private ensureParticipant;
21
+ private parseParticipant;
22
+ private readRestOfLine;
23
+ }