@polagram/core 0.0.2

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 (100) hide show
  1. package/README.md +124 -0
  2. package/dist/index.d.ts +625 -0
  3. package/dist/polagram-core.js +3653 -0
  4. package/dist/polagram-core.umd.cjs +28 -0
  5. package/dist/src/api.d.ts +75 -0
  6. package/dist/src/api.js +160 -0
  7. package/dist/src/ast/ast.test.d.ts +1 -0
  8. package/dist/src/ast/ast.test.js +146 -0
  9. package/dist/src/ast/index.d.ts +119 -0
  10. package/dist/src/ast/index.js +2 -0
  11. package/dist/src/config/index.d.ts +1 -0
  12. package/dist/src/config/index.js +1 -0
  13. package/dist/src/config/schema.d.ts +182 -0
  14. package/dist/src/config/schema.js +78 -0
  15. package/dist/src/config/schema.test.d.ts +1 -0
  16. package/dist/src/config/schema.test.js +94 -0
  17. package/dist/src/generator/base/walker.d.ts +19 -0
  18. package/dist/src/generator/base/walker.js +56 -0
  19. package/dist/src/generator/base/walker.test.d.ts +1 -0
  20. package/dist/src/generator/base/walker.test.js +49 -0
  21. package/dist/src/generator/generators/mermaid.d.ts +24 -0
  22. package/dist/src/generator/generators/mermaid.js +140 -0
  23. package/dist/src/generator/generators/mermaid.test.d.ts +1 -0
  24. package/dist/src/generator/generators/mermaid.test.js +70 -0
  25. package/dist/src/generator/interface.d.ts +17 -0
  26. package/dist/src/generator/interface.js +1 -0
  27. package/dist/src/index.d.ts +9 -0
  28. package/dist/src/index.js +17 -0
  29. package/dist/src/parser/base/lexer.d.ts +18 -0
  30. package/dist/src/parser/base/lexer.js +95 -0
  31. package/dist/src/parser/base/lexer.test.d.ts +1 -0
  32. package/dist/src/parser/base/lexer.test.js +53 -0
  33. package/dist/src/parser/base/parser.d.ts +14 -0
  34. package/dist/src/parser/base/parser.js +43 -0
  35. package/dist/src/parser/base/parser.test.d.ts +1 -0
  36. package/dist/src/parser/base/parser.test.js +90 -0
  37. package/dist/src/parser/index.d.ts +10 -0
  38. package/dist/src/parser/index.js +29 -0
  39. package/dist/src/parser/index.test.d.ts +1 -0
  40. package/dist/src/parser/index.test.js +23 -0
  41. package/dist/src/parser/interface.d.ts +8 -0
  42. package/dist/src/parser/interface.js +1 -0
  43. package/dist/src/parser/languages/mermaid/constants.d.ts +7 -0
  44. package/dist/src/parser/languages/mermaid/constants.js +20 -0
  45. package/dist/src/parser/languages/mermaid/index.d.ts +4 -0
  46. package/dist/src/parser/languages/mermaid/index.js +11 -0
  47. package/dist/src/parser/languages/mermaid/lexer.d.ts +14 -0
  48. package/dist/src/parser/languages/mermaid/lexer.js +152 -0
  49. package/dist/src/parser/languages/mermaid/lexer.test.d.ts +1 -0
  50. package/dist/src/parser/languages/mermaid/lexer.test.js +58 -0
  51. package/dist/src/parser/languages/mermaid/parser.d.ts +21 -0
  52. package/dist/src/parser/languages/mermaid/parser.js +340 -0
  53. package/dist/src/parser/languages/mermaid/parser.test.d.ts +1 -0
  54. package/dist/src/parser/languages/mermaid/parser.test.js +252 -0
  55. package/dist/src/parser/languages/mermaid/tokens.d.ts +9 -0
  56. package/dist/src/parser/languages/mermaid/tokens.js +1 -0
  57. package/dist/src/transformer/cleaners/prune-empty.d.ts +9 -0
  58. package/dist/src/transformer/cleaners/prune-empty.js +27 -0
  59. package/dist/src/transformer/cleaners/prune-empty.test.d.ts +1 -0
  60. package/dist/src/transformer/cleaners/prune-empty.test.js +69 -0
  61. package/dist/src/transformer/cleaners/prune-unused.d.ts +5 -0
  62. package/dist/src/transformer/cleaners/prune-unused.js +48 -0
  63. package/dist/src/transformer/cleaners/prune-unused.test.d.ts +1 -0
  64. package/dist/src/transformer/cleaners/prune-unused.test.js +71 -0
  65. package/dist/src/transformer/filters/focus.d.ts +13 -0
  66. package/dist/src/transformer/filters/focus.js +71 -0
  67. package/dist/src/transformer/filters/focus.test.d.ts +1 -0
  68. package/dist/src/transformer/filters/focus.test.js +50 -0
  69. package/dist/src/transformer/filters/remove.d.ts +12 -0
  70. package/dist/src/transformer/filters/remove.js +82 -0
  71. package/dist/src/transformer/filters/remove.test.d.ts +1 -0
  72. package/dist/src/transformer/filters/remove.test.js +38 -0
  73. package/dist/src/transformer/filters/resolve.d.ts +9 -0
  74. package/dist/src/transformer/filters/resolve.js +32 -0
  75. package/dist/src/transformer/filters/resolve.test.d.ts +1 -0
  76. package/dist/src/transformer/filters/resolve.test.js +48 -0
  77. package/dist/src/transformer/index.d.ts +10 -0
  78. package/dist/src/transformer/index.js +10 -0
  79. package/dist/src/transformer/lens.d.ts +12 -0
  80. package/dist/src/transformer/lens.js +58 -0
  81. package/dist/src/transformer/lens.test.d.ts +1 -0
  82. package/dist/src/transformer/lens.test.js +60 -0
  83. package/dist/src/transformer/orchestration/engine.d.ts +5 -0
  84. package/dist/src/transformer/orchestration/engine.js +24 -0
  85. package/dist/src/transformer/orchestration/engine.test.d.ts +1 -0
  86. package/dist/src/transformer/orchestration/engine.test.js +41 -0
  87. package/dist/src/transformer/orchestration/registry.d.ts +10 -0
  88. package/dist/src/transformer/orchestration/registry.js +27 -0
  89. package/dist/src/transformer/selector/matcher.d.ts +9 -0
  90. package/dist/src/transformer/selector/matcher.js +62 -0
  91. package/dist/src/transformer/selector/matcher.test.d.ts +1 -0
  92. package/dist/src/transformer/selector/matcher.test.js +53 -0
  93. package/dist/src/transformer/traverse/walker.d.ts +14 -0
  94. package/dist/src/transformer/traverse/walker.js +67 -0
  95. package/dist/src/transformer/traverse/walker.test.d.ts +1 -0
  96. package/dist/src/transformer/traverse/walker.test.js +48 -0
  97. package/dist/src/transformer/types.d.ts +47 -0
  98. package/dist/src/transformer/types.js +1 -0
  99. package/dist/tsconfig.tsbuildinfo +1 -0
  100. package/package.json +45 -0
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Polagram Abstract Syntax Tree (AST) Definitions
3
+ *
4
+ * Designed to be a lossless representation of Sequence Diagrams from:
5
+ * - Mermaid
6
+ * - PlantUML
7
+ *
8
+ * It captures structure, semantics (lifecycle, grouping), and necessary visual hints.
9
+ */
10
+ export interface PolagramRoot {
11
+ kind: 'root';
12
+ meta: MetaData;
13
+ participants: Participant[];
14
+ groups: ParticipantGroup[];
15
+ events: EventNode[];
16
+ }
17
+ export interface MetaData {
18
+ version: string;
19
+ source: 'mermaid' | 'plantuml' | 'unknown';
20
+ title?: string;
21
+ theme?: Record<string, string>;
22
+ }
23
+ export interface Participant {
24
+ id: string;
25
+ name: string;
26
+ alias?: string;
27
+ type: ParticipantType;
28
+ stereotype?: string;
29
+ style?: StyleProps;
30
+ }
31
+ export type ParticipantType = 'participant' | 'actor' | 'boundary' | 'control' | 'entity' | 'database' | 'collections' | 'queue';
32
+ export interface ParticipantGroup {
33
+ kind: 'group';
34
+ id: string;
35
+ name?: string;
36
+ type?: string;
37
+ participantIds: string[];
38
+ style?: StyleProps;
39
+ }
40
+ export type EventNode = MessageNode | FragmentNode | NoteNode | DividerNode | ActivationNode | ReferenceNode | SpacerNode;
41
+ export type MessageEndpoint = string | null;
42
+ /**
43
+ * Represents a directional interaction.
44
+ * Includes standard sync/async calls, returns, and object creation/deletion.
45
+ */
46
+ export interface MessageNode {
47
+ kind: 'message';
48
+ id: string;
49
+ from: MessageEndpoint;
50
+ to: MessageEndpoint;
51
+ text: string;
52
+ type: 'sync' | 'async' | 'reply' | 'create' | 'destroy';
53
+ style: {
54
+ line: 'solid' | 'dotted';
55
+ head: 'arrow' | 'async' | 'open' | 'cross';
56
+ color?: string;
57
+ };
58
+ lifecycle?: {
59
+ activateTarget?: boolean;
60
+ deactivateSource?: boolean;
61
+ };
62
+ }
63
+ export interface FragmentNode {
64
+ kind: 'fragment';
65
+ id: string;
66
+ operator: FragmentOperator;
67
+ branches: FragmentBranch[];
68
+ }
69
+ export type FragmentOperator = 'alt' | 'opt' | 'loop' | 'par' | 'break' | 'critical' | 'rect' | 'group';
70
+ export interface FragmentBranch {
71
+ id: string;
72
+ condition?: string;
73
+ events: EventNode[];
74
+ }
75
+ export interface NoteNode {
76
+ kind: 'note';
77
+ id: string;
78
+ text: string;
79
+ position: 'left' | 'right' | 'over';
80
+ participantIds: string[];
81
+ style?: StyleProps;
82
+ }
83
+ /**
84
+ * Independent activation/deactivation not tied to a specific message line.
85
+ * e.g., Mermaid "activate A", PlantUML "activate A"
86
+ */
87
+ export interface ActivationNode {
88
+ kind: 'activation';
89
+ participantId: string;
90
+ action: 'activate' | 'deactivate';
91
+ style?: StyleProps;
92
+ }
93
+ /**
94
+ * Refers to another sequence diagram or a frame covering participants.
95
+ * e.g., PlantUML "ref over A, B : Init"
96
+ */
97
+ export interface ReferenceNode {
98
+ kind: 'ref';
99
+ id: string;
100
+ text: string;
101
+ participantIds: string[];
102
+ link?: string;
103
+ }
104
+ export interface DividerNode {
105
+ kind: 'divider';
106
+ id: string;
107
+ text?: string;
108
+ }
109
+ export interface SpacerNode {
110
+ kind: 'spacer';
111
+ id: string;
112
+ height?: number;
113
+ text?: string;
114
+ }
115
+ export interface StyleProps {
116
+ color?: string;
117
+ backgroundColor?: string;
118
+ shape?: string;
119
+ }
@@ -0,0 +1,2 @@
1
+ // packages/core/src/ast.ts
2
+ export {};
@@ -0,0 +1 @@
1
+ export * from './schema';
@@ -0,0 +1 @@
1
+ export * from './schema';
@@ -0,0 +1,182 @@
1
+ import { z } from 'zod';
2
+ declare const LensSchema: z.ZodObject<{
3
+ name: z.ZodString;
4
+ suffix: z.ZodOptional<z.ZodString>;
5
+ layers: z.ZodArray<z.ZodObject<{
6
+ action: z.ZodEnum<{
7
+ resolve: "resolve";
8
+ focus: "focus";
9
+ remove: "remove";
10
+ }>;
11
+ selector: z.ZodDiscriminatedUnion<[z.ZodObject<{
12
+ kind: z.ZodLiteral<"fragment">;
13
+ condition: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
14
+ pattern: z.ZodString;
15
+ flags: z.ZodOptional<z.ZodString>;
16
+ }, z.core.$strip>]>>;
17
+ operator: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
18
+ }, z.core.$strip>, z.ZodObject<{
19
+ kind: z.ZodLiteral<"participant">;
20
+ name: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
21
+ pattern: z.ZodString;
22
+ flags: z.ZodOptional<z.ZodString>;
23
+ }, z.core.$strip>]>>;
24
+ id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
25
+ pattern: z.ZodString;
26
+ flags: z.ZodOptional<z.ZodString>;
27
+ }, z.core.$strip>]>>;
28
+ stereotype: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
29
+ pattern: z.ZodString;
30
+ flags: z.ZodOptional<z.ZodString>;
31
+ }, z.core.$strip>]>>;
32
+ }, z.core.$strip>, z.ZodObject<{
33
+ kind: z.ZodLiteral<"message">;
34
+ text: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
35
+ pattern: z.ZodString;
36
+ flags: z.ZodOptional<z.ZodString>;
37
+ }, z.core.$strip>]>>;
38
+ from: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
39
+ pattern: z.ZodString;
40
+ flags: z.ZodOptional<z.ZodString>;
41
+ }, z.core.$strip>]>>;
42
+ to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
43
+ pattern: z.ZodString;
44
+ flags: z.ZodOptional<z.ZodString>;
45
+ }, z.core.$strip>]>>;
46
+ }, z.core.$strip>, z.ZodObject<{
47
+ kind: z.ZodLiteral<"group">;
48
+ name: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
49
+ pattern: z.ZodString;
50
+ flags: z.ZodOptional<z.ZodString>;
51
+ }, z.core.$strip>]>>;
52
+ }, z.core.$strip>], "kind">;
53
+ }, z.core.$strip>>;
54
+ }, z.core.$strip>;
55
+ declare const TargetConfigSchema: z.ZodObject<{
56
+ input: z.ZodArray<z.ZodString>;
57
+ outputDir: z.ZodString;
58
+ ignore: z.ZodOptional<z.ZodArray<z.ZodString>>;
59
+ lenses: z.ZodArray<z.ZodObject<{
60
+ name: z.ZodString;
61
+ suffix: z.ZodOptional<z.ZodString>;
62
+ layers: z.ZodArray<z.ZodObject<{
63
+ action: z.ZodEnum<{
64
+ resolve: "resolve";
65
+ focus: "focus";
66
+ remove: "remove";
67
+ }>;
68
+ selector: z.ZodDiscriminatedUnion<[z.ZodObject<{
69
+ kind: z.ZodLiteral<"fragment">;
70
+ condition: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
71
+ pattern: z.ZodString;
72
+ flags: z.ZodOptional<z.ZodString>;
73
+ }, z.core.$strip>]>>;
74
+ operator: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
75
+ }, z.core.$strip>, z.ZodObject<{
76
+ kind: z.ZodLiteral<"participant">;
77
+ name: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
78
+ pattern: z.ZodString;
79
+ flags: z.ZodOptional<z.ZodString>;
80
+ }, z.core.$strip>]>>;
81
+ id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
82
+ pattern: z.ZodString;
83
+ flags: z.ZodOptional<z.ZodString>;
84
+ }, z.core.$strip>]>>;
85
+ stereotype: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
86
+ pattern: z.ZodString;
87
+ flags: z.ZodOptional<z.ZodString>;
88
+ }, z.core.$strip>]>>;
89
+ }, z.core.$strip>, z.ZodObject<{
90
+ kind: z.ZodLiteral<"message">;
91
+ text: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
92
+ pattern: z.ZodString;
93
+ flags: z.ZodOptional<z.ZodString>;
94
+ }, z.core.$strip>]>>;
95
+ from: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
96
+ pattern: z.ZodString;
97
+ flags: z.ZodOptional<z.ZodString>;
98
+ }, z.core.$strip>]>>;
99
+ to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
100
+ pattern: z.ZodString;
101
+ flags: z.ZodOptional<z.ZodString>;
102
+ }, z.core.$strip>]>>;
103
+ }, z.core.$strip>, z.ZodObject<{
104
+ kind: z.ZodLiteral<"group">;
105
+ name: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
106
+ pattern: z.ZodString;
107
+ flags: z.ZodOptional<z.ZodString>;
108
+ }, z.core.$strip>]>>;
109
+ }, z.core.$strip>], "kind">;
110
+ }, z.core.$strip>>;
111
+ }, z.core.$strip>>;
112
+ }, z.core.$strip>;
113
+ export declare const PolagramConfigSchema: z.ZodObject<{
114
+ version: z.ZodNumber;
115
+ targets: z.ZodArray<z.ZodObject<{
116
+ input: z.ZodArray<z.ZodString>;
117
+ outputDir: z.ZodString;
118
+ ignore: z.ZodOptional<z.ZodArray<z.ZodString>>;
119
+ lenses: z.ZodArray<z.ZodObject<{
120
+ name: z.ZodString;
121
+ suffix: z.ZodOptional<z.ZodString>;
122
+ layers: z.ZodArray<z.ZodObject<{
123
+ action: z.ZodEnum<{
124
+ resolve: "resolve";
125
+ focus: "focus";
126
+ remove: "remove";
127
+ }>;
128
+ selector: z.ZodDiscriminatedUnion<[z.ZodObject<{
129
+ kind: z.ZodLiteral<"fragment">;
130
+ condition: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
131
+ pattern: z.ZodString;
132
+ flags: z.ZodOptional<z.ZodString>;
133
+ }, z.core.$strip>]>>;
134
+ operator: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
135
+ }, z.core.$strip>, z.ZodObject<{
136
+ kind: z.ZodLiteral<"participant">;
137
+ name: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
138
+ pattern: z.ZodString;
139
+ flags: z.ZodOptional<z.ZodString>;
140
+ }, z.core.$strip>]>>;
141
+ id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
142
+ pattern: z.ZodString;
143
+ flags: z.ZodOptional<z.ZodString>;
144
+ }, z.core.$strip>]>>;
145
+ stereotype: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
146
+ pattern: z.ZodString;
147
+ flags: z.ZodOptional<z.ZodString>;
148
+ }, z.core.$strip>]>>;
149
+ }, z.core.$strip>, z.ZodObject<{
150
+ kind: z.ZodLiteral<"message">;
151
+ text: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
152
+ pattern: z.ZodString;
153
+ flags: z.ZodOptional<z.ZodString>;
154
+ }, z.core.$strip>]>>;
155
+ from: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
156
+ pattern: z.ZodString;
157
+ flags: z.ZodOptional<z.ZodString>;
158
+ }, z.core.$strip>]>>;
159
+ to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
160
+ pattern: z.ZodString;
161
+ flags: z.ZodOptional<z.ZodString>;
162
+ }, z.core.$strip>]>>;
163
+ }, z.core.$strip>, z.ZodObject<{
164
+ kind: z.ZodLiteral<"group">;
165
+ name: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
166
+ pattern: z.ZodString;
167
+ flags: z.ZodOptional<z.ZodString>;
168
+ }, z.core.$strip>]>>;
169
+ }, z.core.$strip>], "kind">;
170
+ }, z.core.$strip>>;
171
+ }, z.core.$strip>>;
172
+ }, z.core.$strip>>;
173
+ }, z.core.$strip>;
174
+ export type PolagramConfig = z.infer<typeof PolagramConfigSchema>;
175
+ export type TargetConfig = z.infer<typeof TargetConfigSchema>;
176
+ export type LensConfig = z.infer<typeof LensSchema>;
177
+ /**
178
+ * Validates the input object against the Polagram Config Schema.
179
+ * Throws a formatted error message if validation fails.
180
+ */
181
+ export declare function validateConfig(input: unknown): PolagramConfig;
182
+ export {};
@@ -0,0 +1,78 @@
1
+ import { z } from 'zod';
2
+ // -- Text Matcher --
3
+ const TextMatcherSchema = z.union([
4
+ z.string(),
5
+ z.object({
6
+ pattern: z.string(),
7
+ flags: z.string().optional()
8
+ })
9
+ ]);
10
+ // -- Selectors --
11
+ // Explicitly requiring 'kind' for all selectors
12
+ const FragmentSelectorSchema = z.object({
13
+ kind: z.literal('fragment'),
14
+ condition: TextMatcherSchema.optional(),
15
+ operator: z.union([z.string(), z.array(z.string())]).optional()
16
+ // Note: Operator types might need to be refined if we want strict enum validation,
17
+ // but string is flexible for now.
18
+ });
19
+ const ParticipantSelectorSchema = z.object({
20
+ kind: z.literal('participant'),
21
+ name: TextMatcherSchema.optional(),
22
+ id: TextMatcherSchema.optional(),
23
+ stereotype: TextMatcherSchema.optional()
24
+ });
25
+ const MessageSelectorSchema = z.object({
26
+ kind: z.literal('message'),
27
+ text: TextMatcherSchema.optional(),
28
+ from: TextMatcherSchema.optional(),
29
+ to: TextMatcherSchema.optional()
30
+ });
31
+ const GroupSelectorSchema = z.object({
32
+ kind: z.literal('group'),
33
+ name: TextMatcherSchema.optional()
34
+ });
35
+ const SelectorSchema = z.discriminatedUnion('kind', [
36
+ FragmentSelectorSchema,
37
+ ParticipantSelectorSchema,
38
+ MessageSelectorSchema,
39
+ GroupSelectorSchema
40
+ ]);
41
+ // -- Layers --
42
+ const ActionSchema = z.enum(['focus', 'remove', 'resolve']);
43
+ const LayerSchema = z.object({
44
+ action: ActionSchema,
45
+ selector: SelectorSchema
46
+ });
47
+ // -- Lens --
48
+ const LensSchema = z.object({
49
+ name: z.string(),
50
+ suffix: z.string().optional(), // Defaults to .name in logic
51
+ layers: z.array(LayerSchema)
52
+ });
53
+ // -- Config --
54
+ const TargetConfigSchema = z.object({
55
+ input: z.array(z.string()),
56
+ outputDir: z.string(),
57
+ ignore: z.array(z.string()).optional(),
58
+ lenses: z.array(LensSchema)
59
+ });
60
+ export const PolagramConfigSchema = z.object({
61
+ version: z.number(),
62
+ targets: z.array(TargetConfigSchema)
63
+ });
64
+ /**
65
+ * Validates the input object against the Polagram Config Schema.
66
+ * Throws a formatted error message if validation fails.
67
+ */
68
+ export function validateConfig(input) {
69
+ const result = PolagramConfigSchema.safeParse(input);
70
+ if (!result.success) {
71
+ const errorMessages = result.error.issues.map(issue => {
72
+ const path = issue.path.join('.');
73
+ return `[${path}]: ${issue.message}`;
74
+ }).join('\n');
75
+ throw new Error(`Invalid Polagram Configuration:\n${errorMessages}`);
76
+ }
77
+ return result.data;
78
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,94 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { validateConfig } from './schema';
3
+ describe('Config Schema Validation', () => {
4
+ it('should validate a correct configuration', () => {
5
+ const input = {
6
+ version: 1,
7
+ targets: [
8
+ {
9
+ input: ['src/*.mmd'],
10
+ outputDir: 'dist',
11
+ lenses: [
12
+ {
13
+ name: 'Success',
14
+ layers: [
15
+ {
16
+ action: 'resolve',
17
+ selector: { kind: 'fragment', condition: 'Success' }
18
+ }
19
+ ]
20
+ }
21
+ ]
22
+ }
23
+ ]
24
+ };
25
+ const config = validateConfig(input);
26
+ expect(config.version).toBe(1);
27
+ expect(config.targets[0].lenses[0].name).toBe('Success');
28
+ });
29
+ it('should throw error for missing required fields', () => {
30
+ const input = {
31
+ // missing version
32
+ targets: []
33
+ };
34
+ expect(() => validateConfig(input)).toThrow('Invalid Polagram Configuration');
35
+ // Zod message might vary, just checking it fails is often enough,
36
+ // but let's check for the path at least.
37
+ expect(() => validateConfig(input)).toThrow('[version]:');
38
+ });
39
+ it('should validate fragment selector correctly', () => {
40
+ const input = {
41
+ version: 1,
42
+ targets: [{
43
+ input: ['src/*.mmd'],
44
+ outputDir: 'dist',
45
+ lenses: [{
46
+ name: 'Test',
47
+ layers: [{
48
+ action: 'focus',
49
+ selector: { kind: 'fragment', condition: 'Success' }
50
+ }]
51
+ }]
52
+ }]
53
+ };
54
+ expect(() => validateConfig(input)).not.toThrow();
55
+ });
56
+ it('should fail if selector kind is missing', () => {
57
+ const input = {
58
+ version: 1,
59
+ targets: [{
60
+ input: ['src/*.mmd'],
61
+ outputDir: 'dist',
62
+ lenses: [{
63
+ name: 'Test',
64
+ layers: [{
65
+ action: 'focus',
66
+ selector: { condition: 'Success' } // Missing kind: 'fragment'
67
+ }]
68
+ }]
69
+ }]
70
+ };
71
+ // Expect failure because checking against union requires discrimination
72
+ expect(() => validateConfig(input)).toThrow();
73
+ });
74
+ it('should validate participant selector with complex matcher', () => {
75
+ const input = {
76
+ version: 1,
77
+ targets: [{
78
+ input: ['src/*.mmd'],
79
+ outputDir: 'dist',
80
+ lenses: [{
81
+ name: 'Test',
82
+ layers: [{
83
+ action: 'focus',
84
+ selector: {
85
+ kind: 'participant',
86
+ name: { pattern: 'User.*', flags: 'i' }
87
+ }
88
+ }]
89
+ }]
90
+ }]
91
+ };
92
+ expect(() => validateConfig(input)).not.toThrow();
93
+ });
94
+ });
@@ -0,0 +1,19 @@
1
+ import { EventNode, PolagramRoot } from '../../ast';
2
+ import { PolagramVisitor } from '../interface';
3
+ /**
4
+ * Helper class to traverse AST nodes and dispatch to the visitor.
5
+ */
6
+ export declare class Traverser {
7
+ private visitor;
8
+ constructor(visitor: PolagramVisitor);
9
+ traverse(root: PolagramRoot): void;
10
+ /**
11
+ * Dispatches a single event node to the appropriate visitor method.
12
+ * This is public so Visitors can call it recursively (e.g. inside Fragments/Groups).
13
+ */
14
+ dispatchEvent(node: EventNode): void;
15
+ /**
16
+ * Helper to iterate over a list of events.
17
+ */
18
+ dispatchEvents(events: EventNode[]): void;
19
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Helper class to traverse AST nodes and dispatch to the visitor.
3
+ */
4
+ export class Traverser {
5
+ constructor(visitor) {
6
+ Object.defineProperty(this, "visitor", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: visitor
11
+ });
12
+ }
13
+ traverse(root) {
14
+ this.visitor.visitRoot(root);
15
+ }
16
+ /**
17
+ * Dispatches a single event node to the appropriate visitor method.
18
+ * This is public so Visitors can call it recursively (e.g. inside Fragments/Groups).
19
+ */
20
+ dispatchEvent(node) {
21
+ switch (node.kind) {
22
+ case 'message':
23
+ this.visitor.visitMessage(node);
24
+ break;
25
+ case 'fragment':
26
+ this.visitor.visitFragment(node);
27
+ break;
28
+ case 'note':
29
+ this.visitor.visitNote(node);
30
+ break;
31
+ case 'activation':
32
+ this.visitor.visitActivation(node);
33
+ break;
34
+ case 'divider':
35
+ this.visitor.visitDivider(node);
36
+ break;
37
+ case 'spacer':
38
+ this.visitor.visitSpacer(node);
39
+ break;
40
+ case 'ref':
41
+ this.visitor.visitReference(node);
42
+ break;
43
+ default:
44
+ // Unknown node type
45
+ break;
46
+ }
47
+ }
48
+ /**
49
+ * Helper to iterate over a list of events.
50
+ */
51
+ dispatchEvents(events) {
52
+ for (const event of events) {
53
+ this.dispatchEvent(event);
54
+ }
55
+ }
56
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,49 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { Traverser } from './walker';
3
+ describe('Traverser', () => {
4
+ it('should dispatch visitRoot', () => {
5
+ const mockVisitor = {
6
+ visitRoot: vi.fn(),
7
+ visitParticipant: vi.fn(),
8
+ visitParticipantGroup: vi.fn(),
9
+ visitMessage: vi.fn(),
10
+ visitFragment: vi.fn(),
11
+ visitNote: vi.fn(),
12
+ visitActivation: vi.fn(),
13
+ visitDivider: vi.fn(),
14
+ visitSpacer: vi.fn(),
15
+ visitReference: vi.fn()
16
+ };
17
+ const traverser = new Traverser(mockVisitor);
18
+ const root = { kind: 'root', meta: { version: '1.0.0', source: 'unknown' }, participants: [], groups: [], events: [] };
19
+ traverser.traverse(root);
20
+ expect(mockVisitor.visitRoot).toHaveBeenCalledWith(root);
21
+ });
22
+ it('should dispatch events based on kind', () => {
23
+ const mockVisitor = {
24
+ visitRoot: vi.fn(), // Root visitor might internally call dispatchEvents
25
+ visitParticipant: vi.fn(),
26
+ visitParticipantGroup: vi.fn(),
27
+ visitMessage: vi.fn(),
28
+ visitFragment: vi.fn(),
29
+ visitNote: vi.fn(),
30
+ visitActivation: vi.fn(),
31
+ visitDivider: vi.fn(),
32
+ visitSpacer: vi.fn(),
33
+ visitReference: vi.fn()
34
+ };
35
+ const traverser = new Traverser(mockVisitor);
36
+ const msg = {
37
+ kind: 'message',
38
+ id: '1',
39
+ from: 'A',
40
+ to: 'B',
41
+ text: 'hi',
42
+ type: 'sync',
43
+ style: { line: 'solid', head: 'arrow' }
44
+ };
45
+ // Directly call dispatchEvents (as if called from visitRoot implementation)
46
+ traverser.dispatchEvents([msg]);
47
+ expect(mockVisitor.visitMessage).toHaveBeenCalledWith(msg);
48
+ });
49
+ });
@@ -0,0 +1,24 @@
1
+ import { ActivationNode, DividerNode, FragmentNode, MessageNode, NoteNode, Participant, ParticipantGroup, PolagramRoot, ReferenceNode, SpacerNode } from '../../ast';
2
+ import { PolagramVisitor } from '../interface';
3
+ /**
4
+ * Visitor implementation that generates Mermaid code.
5
+ */
6
+ export declare class MermaidGeneratorVisitor implements PolagramVisitor {
7
+ private lines;
8
+ private indentLevel;
9
+ private traverser;
10
+ constructor();
11
+ generate(ast: PolagramRoot): string;
12
+ visitRoot(node: PolagramRoot): void;
13
+ visitParticipant(node: Participant): void;
14
+ visitParticipantGroup(node: ParticipantGroup): void;
15
+ visitMessage(node: MessageNode): void;
16
+ visitFragment(node: FragmentNode): void;
17
+ visitNote(node: NoteNode): void;
18
+ visitActivation(node: ActivationNode): void;
19
+ visitDivider(node: DividerNode): void;
20
+ visitSpacer(node: SpacerNode): void;
21
+ visitReference(node: ReferenceNode): void;
22
+ private add;
23
+ private indent;
24
+ }