@graph-ir/core 0.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.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -0
  3. package/dist/generation/id-generator.d.ts +81 -0
  4. package/dist/generation/id-generator.d.ts.map +1 -0
  5. package/dist/generation/id-generator.js +193 -0
  6. package/dist/generation/id-generator.js.map +1 -0
  7. package/dist/generation/index.d.ts +7 -0
  8. package/dist/generation/index.d.ts.map +1 -0
  9. package/dist/generation/index.js +7 -0
  10. package/dist/generation/index.js.map +1 -0
  11. package/dist/index.d.ts +12 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +26 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/output/ci.d.ts +36 -0
  16. package/dist/output/ci.d.ts.map +1 -0
  17. package/dist/output/ci.js +145 -0
  18. package/dist/output/ci.js.map +1 -0
  19. package/dist/output/index.d.ts +20 -0
  20. package/dist/output/index.d.ts.map +1 -0
  21. package/dist/output/index.js +40 -0
  22. package/dist/output/index.js.map +1 -0
  23. package/dist/output/json.d.ts +24 -0
  24. package/dist/output/json.d.ts.map +1 -0
  25. package/dist/output/json.js +49 -0
  26. package/dist/output/json.js.map +1 -0
  27. package/dist/output/pretty.d.ts +44 -0
  28. package/dist/output/pretty.d.ts.map +1 -0
  29. package/dist/output/pretty.js +227 -0
  30. package/dist/output/pretty.js.map +1 -0
  31. package/dist/output/types.d.ts +63 -0
  32. package/dist/output/types.d.ts.map +1 -0
  33. package/dist/output/types.js +5 -0
  34. package/dist/output/types.js.map +1 -0
  35. package/dist/schemas/graph-ir.schema.json +360 -0
  36. package/dist/skills/diff.d.ts +73 -0
  37. package/dist/skills/diff.d.ts.map +1 -0
  38. package/dist/skills/diff.js +315 -0
  39. package/dist/skills/diff.js.map +1 -0
  40. package/dist/skills/migrate.d.ts +40 -0
  41. package/dist/skills/migrate.d.ts.map +1 -0
  42. package/dist/skills/migrate.js +288 -0
  43. package/dist/skills/migrate.js.map +1 -0
  44. package/dist/skills/visualize.d.ts +30 -0
  45. package/dist/skills/visualize.d.ts.map +1 -0
  46. package/dist/skills/visualize.js +254 -0
  47. package/dist/skills/visualize.js.map +1 -0
  48. package/dist/symbols/index.d.ts +12 -0
  49. package/dist/symbols/index.d.ts.map +1 -0
  50. package/dist/symbols/index.js +12 -0
  51. package/dist/symbols/index.js.map +1 -0
  52. package/dist/symbols/notation-registry.d.ts +61 -0
  53. package/dist/symbols/notation-registry.d.ts.map +1 -0
  54. package/dist/symbols/notation-registry.js +114 -0
  55. package/dist/symbols/notation-registry.js.map +1 -0
  56. package/dist/symbols/symbol-registry.d.ts +58 -0
  57. package/dist/symbols/symbol-registry.d.ts.map +1 -0
  58. package/dist/symbols/symbol-registry.js +88 -0
  59. package/dist/symbols/symbol-registry.js.map +1 -0
  60. package/dist/symbols/types.d.ts +166 -0
  61. package/dist/symbols/types.d.ts.map +1 -0
  62. package/dist/symbols/types.js +13 -0
  63. package/dist/symbols/types.js.map +1 -0
  64. package/dist/testing/diff.d.ts +46 -0
  65. package/dist/testing/diff.d.ts.map +1 -0
  66. package/dist/testing/diff.js +400 -0
  67. package/dist/testing/diff.js.map +1 -0
  68. package/dist/testing/index.d.ts +10 -0
  69. package/dist/testing/index.d.ts.map +1 -0
  70. package/dist/testing/index.js +10 -0
  71. package/dist/testing/index.js.map +1 -0
  72. package/dist/testing/snapshot.d.ts +95 -0
  73. package/dist/testing/snapshot.d.ts.map +1 -0
  74. package/dist/testing/snapshot.js +172 -0
  75. package/dist/testing/snapshot.js.map +1 -0
  76. package/dist/types.d.ts +240 -0
  77. package/dist/types.d.ts.map +1 -0
  78. package/dist/types.js +7 -0
  79. package/dist/types.js.map +1 -0
  80. package/dist/validation/index.d.ts +9 -0
  81. package/dist/validation/index.d.ts.map +1 -0
  82. package/dist/validation/index.js +8 -0
  83. package/dist/validation/index.js.map +1 -0
  84. package/dist/validation/ir-validator.d.ts +51 -0
  85. package/dist/validation/ir-validator.d.ts.map +1 -0
  86. package/dist/validation/ir-validator.js +349 -0
  87. package/dist/validation/ir-validator.js.map +1 -0
  88. package/dist/validation/validator.d.ts +13 -0
  89. package/dist/validation/validator.d.ts.map +1 -0
  90. package/dist/validation/validator.js +19 -0
  91. package/dist/validation/validator.js.map +1 -0
  92. package/package.json +73 -0
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Snapshot Testing Utilities for Graph-IR
3
+ *
4
+ * Provides snapshot management for comparing Graph-IR structures
5
+ * across test runs.
6
+ */
7
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, readdirSync } from 'fs';
8
+ import { join, basename } from 'path';
9
+ // ============================================================================
10
+ // Snapshot Manager
11
+ // ============================================================================
12
+ /**
13
+ * Manages snapshots for testing
14
+ */
15
+ export class SnapshotManager {
16
+ snapshotDir;
17
+ constructor(snapshotDir) {
18
+ this.snapshotDir = snapshotDir;
19
+ // Ensure directory exists
20
+ if (!existsSync(snapshotDir)) {
21
+ mkdirSync(snapshotDir, { recursive: true });
22
+ }
23
+ }
24
+ /**
25
+ * Match data against a snapshot
26
+ *
27
+ * If snapshot doesn't exist, creates it.
28
+ * If snapshot exists, compares and returns result.
29
+ */
30
+ match(name, data) {
31
+ const filePath = this.getSnapshotPath(name);
32
+ if (!existsSync(filePath)) {
33
+ // Create new snapshot
34
+ const snapshot = wrapSnapshot(data, name);
35
+ this.writeSnapshot(name, snapshot);
36
+ return {
37
+ status: 'new',
38
+ name,
39
+ };
40
+ }
41
+ // Compare with existing snapshot
42
+ const existing = this.read(name);
43
+ if (!existing) {
44
+ // Shouldn't happen, but handle gracefully
45
+ const snapshot = wrapSnapshot(data, name);
46
+ this.writeSnapshot(name, snapshot);
47
+ return { status: 'new', name };
48
+ }
49
+ // Deep compare
50
+ const isEqual = this.deepEqual(existing.data, data);
51
+ if (isEqual) {
52
+ return { status: 'pass', name };
53
+ }
54
+ return {
55
+ status: 'fail',
56
+ name,
57
+ expected: existing.data,
58
+ actual: data,
59
+ diff: this.formatDiff(existing.data, data),
60
+ };
61
+ }
62
+ /**
63
+ * Update a snapshot with new data
64
+ */
65
+ update(name, data) {
66
+ const existing = this.read(name);
67
+ const snapshot = {
68
+ name,
69
+ data,
70
+ createdAt: existing?.createdAt ?? new Date().toISOString(),
71
+ updatedAt: new Date().toISOString(),
72
+ version: (existing?.version ?? 0) + 1,
73
+ };
74
+ this.writeSnapshot(name, snapshot);
75
+ }
76
+ /**
77
+ * Read a snapshot by name
78
+ */
79
+ read(name) {
80
+ const filePath = this.getSnapshotPath(name);
81
+ if (!existsSync(filePath)) {
82
+ return undefined;
83
+ }
84
+ try {
85
+ const content = readFileSync(filePath, 'utf-8');
86
+ return JSON.parse(content);
87
+ }
88
+ catch {
89
+ return undefined;
90
+ }
91
+ }
92
+ /**
93
+ * Check if a snapshot exists
94
+ */
95
+ exists(name) {
96
+ return existsSync(this.getSnapshotPath(name));
97
+ }
98
+ /**
99
+ * Delete a snapshot
100
+ */
101
+ delete(name) {
102
+ const filePath = this.getSnapshotPath(name);
103
+ if (existsSync(filePath)) {
104
+ unlinkSync(filePath);
105
+ }
106
+ }
107
+ /**
108
+ * List all snapshot names
109
+ */
110
+ list() {
111
+ if (!existsSync(this.snapshotDir)) {
112
+ return [];
113
+ }
114
+ return readdirSync(this.snapshotDir)
115
+ .filter((f) => f.endsWith('.snap.json'))
116
+ .map((f) => basename(f, '.snap.json'));
117
+ }
118
+ /**
119
+ * Get the file path for a snapshot
120
+ */
121
+ getSnapshotPath(name) {
122
+ return join(this.snapshotDir, `${name}.snap.json`);
123
+ }
124
+ /**
125
+ * Write a snapshot to disk
126
+ */
127
+ writeSnapshot(name, snapshot) {
128
+ const filePath = this.getSnapshotPath(name);
129
+ writeFileSync(filePath, JSON.stringify(snapshot, null, 2), 'utf-8');
130
+ }
131
+ /**
132
+ * Deep equality check
133
+ */
134
+ deepEqual(a, b) {
135
+ return JSON.stringify(a) === JSON.stringify(b);
136
+ }
137
+ /**
138
+ * Format a simple diff for display
139
+ */
140
+ formatDiff(expected, actual) {
141
+ const lines = [];
142
+ lines.push('Snapshot mismatch:');
143
+ lines.push('');
144
+ lines.push('Expected:');
145
+ lines.push(JSON.stringify(expected, null, 2));
146
+ lines.push('');
147
+ lines.push('Actual:');
148
+ lines.push(JSON.stringify(actual, null, 2));
149
+ return lines.join('\n');
150
+ }
151
+ }
152
+ // ============================================================================
153
+ // Helper Functions
154
+ // ============================================================================
155
+ /**
156
+ * Wrap data in a snapshot envelope
157
+ */
158
+ export function wrapSnapshot(data, name) {
159
+ return {
160
+ name,
161
+ data,
162
+ createdAt: new Date().toISOString(),
163
+ version: 1,
164
+ };
165
+ }
166
+ /**
167
+ * Extract data from a snapshot envelope
168
+ */
169
+ export function unwrapSnapshot(snapshot) {
170
+ return snapshot.data;
171
+ }
172
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/testing/snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Graph-IR Type Definitions
3
+ *
4
+ * Based on docs/schema-specification.md
5
+ */
6
+ export interface GraphIR {
7
+ /** Schema version for migration support */
8
+ version: string;
9
+ /** Unique identifier for this graph */
10
+ id: string;
11
+ /** Human-readable name */
12
+ name?: string;
13
+ /** Top-level nodes (may contain children for hierarchy) */
14
+ nodes: GraphNode[];
15
+ /** Connections between nodes */
16
+ edges: GraphEdge[];
17
+ /** Graph-level metadata */
18
+ metadata?: GraphMetadata;
19
+ /** Default layout options for the entire graph */
20
+ layoutOptions?: LayoutOptions;
21
+ }
22
+ export interface GraphNode {
23
+ /** Unique identifier within the graph */
24
+ id: string;
25
+ /** Node type (e.g., 'service', 'database', 'user') */
26
+ type: string;
27
+ /** Display label */
28
+ label?: string;
29
+ /** Optional description or documentation */
30
+ description?: string;
31
+ /**
32
+ * Symbol for visual representation (e.g., 'decision', 'cylinder', 'actor').
33
+ * References a symbol definition in a symbol registry.
34
+ * If omitted, renderers use a default shape based on `type` or a rectangle.
35
+ */
36
+ symbol?: string;
37
+ /**
38
+ * Variant of the symbol (e.g., 'start' vs 'end' for terminal symbols).
39
+ * Interpretation depends on the symbol definition.
40
+ */
41
+ variant?: string;
42
+ /** Custom properties for this node type */
43
+ properties?: Record<string, unknown>;
44
+ /** Child nodes for compound/nested graphs */
45
+ children?: GraphNode[];
46
+ /** Reference to parent node ID */
47
+ parent?: string;
48
+ /** Connection points on this node */
49
+ ports?: Port[];
50
+ /** Visual dimensions (width x height) */
51
+ dimensions?: Dimensions;
52
+ /** Position if manually placed or computed */
53
+ position?: Position;
54
+ /** Whether position should be preserved during layout */
55
+ pinned?: boolean;
56
+ /** Node-specific layout options */
57
+ layoutOptions?: NodeLayoutOptions;
58
+ /** Source location for round-tripping */
59
+ sourceInfo?: SourceInfo;
60
+ }
61
+ export interface Port {
62
+ /** Unique identifier within the parent node */
63
+ id: string;
64
+ /** Which side of the node this port appears on */
65
+ side: PortSide;
66
+ /** Optional label */
67
+ label?: string;
68
+ /** Position along the side (0.0 to 1.0) */
69
+ position?: number;
70
+ /** Port-specific properties */
71
+ properties?: Record<string, unknown>;
72
+ }
73
+ export type PortSide = 'NORTH' | 'SOUTH' | 'EAST' | 'WEST';
74
+ export interface Dimensions {
75
+ width: number;
76
+ height: number;
77
+ }
78
+ export interface Position {
79
+ x: number;
80
+ y: number;
81
+ }
82
+ export interface GraphEdge {
83
+ /** Unique identifier within the graph */
84
+ id: string;
85
+ /** Source node ID */
86
+ source: string;
87
+ /** Target node ID */
88
+ target: string;
89
+ /** Optional source port ID */
90
+ sourcePort?: string;
91
+ /** Optional target port ID */
92
+ targetPort?: string;
93
+ /** Edge type (e.g., 'dependency', 'dataflow', 'http') */
94
+ type?: string;
95
+ /** Display label */
96
+ label?: string;
97
+ /** Custom properties */
98
+ properties?: Record<string, unknown>;
99
+ /** Intermediate points for edge routing */
100
+ routingPoints?: Position[];
101
+ /** Visual style hints */
102
+ style?: EdgeStyle;
103
+ /** Source location for round-tripping */
104
+ sourceInfo?: SourceInfo;
105
+ }
106
+ export interface EdgeStyle {
107
+ /** Line pattern */
108
+ lineStyle?: 'solid' | 'dashed' | 'dotted';
109
+ /** Arrow at target */
110
+ targetArrow?: 'arrow' | 'diamond' | 'circle' | 'none';
111
+ /** Arrow at source */
112
+ sourceArrow?: 'arrow' | 'diamond' | 'circle' | 'none';
113
+ /** Routing algorithm hint */
114
+ routing?: 'orthogonal' | 'polyline' | 'spline';
115
+ }
116
+ export interface LayoutOptions {
117
+ /** Layout algorithm to use */
118
+ algorithm?: 'layered' | 'force' | 'radial' | 'tree' | 'fixed';
119
+ /** Primary direction for hierarchical layouts */
120
+ direction?: 'DOWN' | 'UP' | 'LEFT' | 'RIGHT';
121
+ /** Spacing configuration */
122
+ spacing?: SpacingOptions;
123
+ /** Edge routing style */
124
+ edgeRouting?: 'orthogonal' | 'polyline' | 'spline';
125
+ /** How to handle compound nodes */
126
+ hierarchyHandling?: 'INCLUDE_CHILDREN' | 'SEPARATE_CHILDREN';
127
+ /** Additional algorithm-specific options */
128
+ algorithmOptions?: Record<string, string | number | boolean>;
129
+ }
130
+ export interface SpacingOptions {
131
+ /** Minimum space between nodes */
132
+ nodeNode?: number;
133
+ /** Minimum space between node and edge */
134
+ nodeEdge?: number;
135
+ /** Minimum space between edges */
136
+ edgeEdge?: number;
137
+ /** Space between layers (for layered algorithm) */
138
+ layerSpacing?: number;
139
+ }
140
+ export interface NodeLayoutOptions {
141
+ /** Port constraint level */
142
+ portConstraints?: 'FREE' | 'FIXED_SIDE' | 'FIXED_ORDER' | 'FIXED_POS';
143
+ /** How to order ports on each side */
144
+ portAlignment?: 'BEGIN' | 'CENTER' | 'END' | 'JUSTIFIED';
145
+ /** Node size constraints */
146
+ sizeConstraints?: ('MINIMUM_SIZE' | 'NODE_LABELS' | 'PORTS')[];
147
+ /** Minimum dimensions */
148
+ minimumSize?: Dimensions;
149
+ /** Padding inside compound nodes */
150
+ padding?: {
151
+ top?: number;
152
+ right?: number;
153
+ bottom?: number;
154
+ left?: number;
155
+ };
156
+ }
157
+ export interface SourceInfo {
158
+ /** Byte range in the original source file */
159
+ range: SourceRange;
160
+ /** Comments associated with this element */
161
+ leadingComments?: Comment[];
162
+ trailingComment?: Comment;
163
+ /** Whitespace before this element */
164
+ leadingWhitespace?: string;
165
+ /** Has this element been modified since parsing? */
166
+ modified?: boolean;
167
+ /** Original raw text (for fallback) */
168
+ originalText?: string;
169
+ }
170
+ export interface SourceRange {
171
+ /** Start byte offset (0-indexed) */
172
+ start: number;
173
+ /** End byte offset (exclusive) */
174
+ end: number;
175
+ /** Start line and column (for error messages) */
176
+ startPosition?: {
177
+ line: number;
178
+ column: number;
179
+ };
180
+ /** End line and column */
181
+ endPosition?: {
182
+ line: number;
183
+ column: number;
184
+ };
185
+ }
186
+ export interface Comment {
187
+ /** Comment text (without delimiters) */
188
+ text: string;
189
+ /** Comment style */
190
+ style: 'line' | 'block';
191
+ /** Position relative to associated element */
192
+ range?: SourceRange;
193
+ }
194
+ export interface GraphMetadata {
195
+ /** Author or owner */
196
+ author?: string;
197
+ /** Creation timestamp (ISO 8601) */
198
+ created?: string;
199
+ /** Last modification timestamp (ISO 8601) */
200
+ modified?: string;
201
+ /** Human-readable description */
202
+ description?: string;
203
+ /** Tags for categorization */
204
+ tags?: string[];
205
+ /**
206
+ * Notation this graph follows (e.g., 'flowchart', 'erd', 'bpmn').
207
+ * Used for validation and to select appropriate symbol libraries.
208
+ * If omitted, no notation-specific validation is applied.
209
+ */
210
+ notation?: string;
211
+ /** Custom domain-specific data */
212
+ custom?: Record<string, unknown>;
213
+ }
214
+ export interface ValidationResult {
215
+ valid: boolean;
216
+ errors: ValidationError[];
217
+ warnings: ValidationError[];
218
+ stats?: {
219
+ nodes: number;
220
+ edges: number;
221
+ };
222
+ }
223
+ export interface ValidationError {
224
+ code: ErrorCode | WarningCode;
225
+ message: string;
226
+ path: string;
227
+ severity: 'error' | 'warning';
228
+ suggestion?: string;
229
+ }
230
+ export type ErrorCode = 'INVALID_JSON' | 'SCHEMA_VIOLATION' | 'DUPLICATE_NODE_ID' | 'DUPLICATE_EDGE_ID' | 'INVALID_EDGE_SOURCE' | 'INVALID_EDGE_TARGET' | 'INVALID_PORT_REFERENCE' | 'CYCLIC_HIERARCHY' | 'INVALID_SOURCE_RANGE';
231
+ export type WarningCode = 'SELF_LOOP_EDGE' | 'ORPHAN_NODE' | 'ORPHAN_PORT' | 'STALE_SOURCE_INFO';
232
+ export interface ValidationOptions {
233
+ /** Treat warnings as errors */
234
+ strict?: boolean;
235
+ /** Skip schema validation (faster, less thorough) */
236
+ skipSchema?: boolean;
237
+ /** Skip semantic checks (cycles, orphans) */
238
+ skipSemantic?: boolean;
239
+ }
240
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Graph-IR Type Definitions
3
+ *
4
+ * Based on docs/schema-specification.md
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Graph-IR Validation Module
3
+ *
4
+ * Validates Graph-IR JSON against schema and semantic rules.
5
+ */
6
+ export { validateIR, validateIRFromString } from './validator.js';
7
+ export { IRValidator } from './ir-validator.js';
8
+ export type { ValidationOptions } from '../types.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validation/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Graph-IR Validation Module
3
+ *
4
+ * Validates Graph-IR JSON against schema and semantic rules.
5
+ */
6
+ export { validateIR, validateIRFromString } from './validator.js';
7
+ export { IRValidator } from './ir-validator.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validation/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Graph-IR Validator
3
+ *
4
+ * Validates Graph-IR against schema and semantic rules:
5
+ * 1. JSON Schema validation (structure)
6
+ * 2. ID uniqueness
7
+ * 3. Reference validity (edges -> nodes, ports)
8
+ * 4. Cycle detection in hierarchy
9
+ * 5. Semantic warnings (orphans, self-loops)
10
+ */
11
+ import type { ValidationResult, ValidationOptions } from '../types.js';
12
+ export declare class IRValidator {
13
+ private options;
14
+ private ajv;
15
+ private schemaValidator;
16
+ constructor(options?: ValidationOptions);
17
+ private addDateTimeFormat;
18
+ /**
19
+ * Validate from JSON string
20
+ */
21
+ validateFromString(jsonString: string): ValidationResult;
22
+ /**
23
+ * Validate a Graph-IR object
24
+ */
25
+ validate(ir: unknown): ValidationResult;
26
+ /**
27
+ * Validate against JSON Schema
28
+ */
29
+ private validateSchema;
30
+ /**
31
+ * Collect all nodes including nested children
32
+ */
33
+ private collectAllNodes;
34
+ /**
35
+ * Check if a node has a port with the given ID
36
+ */
37
+ private hasPort;
38
+ /**
39
+ * Check for cycles in the node hierarchy
40
+ */
41
+ private checkHierarchyCycles;
42
+ /**
43
+ * Find a similar ID for suggestions
44
+ */
45
+ private findSimilarId;
46
+ /**
47
+ * Calculate Levenshtein distance for similarity
48
+ */
49
+ private levenshteinDistance;
50
+ }
51
+ //# sourceMappingURL=ir-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ir-validator.d.ts","sourceRoot":"","sources":["../../src/validation/ir-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAIV,gBAAgB,EAEhB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AASrB,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,eAAe,CAAmB;gBAE9B,OAAO,GAAE,iBAAsB;IAQ3C,OAAO,CAAC,iBAAiB;IAWzB;;OAEG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;IAwBxD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,OAAO,GAAG,gBAAgB;IAsLvC;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAkBvB;;OAEG;IACH,OAAO,CAAC,OAAO;IAIf;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA2C5B;;OAEG;IACH,OAAO,CAAC,aAAa;IAgBrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CA0B5B"}