@comper/mermaid-parser 1.0.1
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/LICENSE +21 -0
- package/README.md +319 -0
- package/dist/dom-stubs.d.ts +5 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +312 -0
- package/dist/index.js.map +11 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 A24Z
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# @a24z/mermaid-parser
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/@a24z%2Fmermaid-parser)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
> **Lightweight Mermaid diagram validator for server-side environments**
|
|
7
|
+
|
|
8
|
+
A validation-only version of Mermaid that provides syntax checking without the heavy rendering dependencies. Perfect for server-side validation, CI/CD pipelines, API endpoints, and any environment where you need to validate Mermaid diagram syntax without rendering.
|
|
9
|
+
|
|
10
|
+
## âĻ Key Features
|
|
11
|
+
|
|
12
|
+
- **ðŠķ Ultra-lightweight**: ~50KB vs ~2MB (97% smaller than full Mermaid)
|
|
13
|
+
- **⥠Fast**: No rendering overhead, pure syntax validation
|
|
14
|
+
- **ð Universal**: Works in Node.js, Deno, Bun, browsers, and serverless functions
|
|
15
|
+
- **ð Complete**: Supports all Mermaid diagram types
|
|
16
|
+
- **ð Safe**: No DOM dependencies, perfect for server environments
|
|
17
|
+
- **ðĶ Zero config**: Import and use immediately
|
|
18
|
+
|
|
19
|
+
## ð Supported Diagram Types
|
|
20
|
+
|
|
21
|
+
- **Flowcharts** (`graph`, `flowchart`)
|
|
22
|
+
- **Sequence Diagrams** (`sequenceDiagram`)
|
|
23
|
+
- **Class Diagrams** (`classDiagram`)
|
|
24
|
+
- **State Diagrams** (`stateDiagram`, `stateDiagram-v2`)
|
|
25
|
+
- **Entity Relationship** (`erDiagram`)
|
|
26
|
+
- **User Journey** (`journey`)
|
|
27
|
+
- **Gantt Charts** (`gantt`)
|
|
28
|
+
- **Pie Charts** (`pie`)
|
|
29
|
+
- **Git Graphs** (`gitGraph`)
|
|
30
|
+
- **Mindmaps** (`mindmap`)
|
|
31
|
+
- **Timelines** (`timeline`)
|
|
32
|
+
- **Quadrant Charts** (`quadrantChart`)
|
|
33
|
+
- **Requirement Diagrams** (`requirementDiagram`)
|
|
34
|
+
- **C4 Diagrams** (`C4Context`, `C4Container`, etc.)
|
|
35
|
+
- **Sankey Diagrams** (`sankey-beta`)
|
|
36
|
+
- **Block Diagrams** (`block-beta`)
|
|
37
|
+
- **Packet Diagrams** (`packet-beta`)
|
|
38
|
+
- **Architecture Diagrams** (`architecture-beta`)
|
|
39
|
+
- **XY Charts** (`xychart-beta`)
|
|
40
|
+
|
|
41
|
+
## ð Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install @a24z/mermaid-parser
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
yarn add @a24z/mermaid-parser
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pnpm add @a24z/mermaid-parser
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
bun add @a24z/mermaid-parser
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## ðĄ Usage
|
|
60
|
+
|
|
61
|
+
### Basic Validation
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { validate } from '@a24z/mermaid-parser';
|
|
65
|
+
|
|
66
|
+
// Validate a flowchart
|
|
67
|
+
const result = await validate(`
|
|
68
|
+
graph TD
|
|
69
|
+
A[Start] --> B{Decision}
|
|
70
|
+
B -->|Yes| C[Success]
|
|
71
|
+
B -->|No| D[Retry]
|
|
72
|
+
D --> A
|
|
73
|
+
`);
|
|
74
|
+
|
|
75
|
+
if (result) {
|
|
76
|
+
console.log(`â
Valid ${result.diagramType} diagram`);
|
|
77
|
+
console.log('Config:', result.config);
|
|
78
|
+
} else {
|
|
79
|
+
console.log('â Invalid diagram');
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Error Handling
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { validate, parse } from '@a24z/mermaid-parser';
|
|
87
|
+
|
|
88
|
+
// With error suppression
|
|
89
|
+
const result = await validate('invalid syntax', { suppressErrors: true });
|
|
90
|
+
console.log(result); // false
|
|
91
|
+
|
|
92
|
+
// With detailed error information
|
|
93
|
+
const detailed = await parse('invalid syntax');
|
|
94
|
+
console.log(detailed);
|
|
95
|
+
// { type: 'unknown', valid: false, error: 'Unknown diagram type' }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Type Checking
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { isSupported, getSupportedDiagrams, getDiagramType } from '@a24z/mermaid-parser';
|
|
102
|
+
|
|
103
|
+
// Check if a diagram type is supported
|
|
104
|
+
console.log(isSupported('flowchart')); // true
|
|
105
|
+
console.log(isSupported('custom')); // false
|
|
106
|
+
|
|
107
|
+
// Get all supported types
|
|
108
|
+
console.log(getSupportedDiagrams());
|
|
109
|
+
// ['flowchart', 'sequence', 'class', 'state', ...]
|
|
110
|
+
|
|
111
|
+
// Detect diagram type without validation
|
|
112
|
+
const type = getDiagramType('sequenceDiagram\nAlice->Bob: Hi');
|
|
113
|
+
console.log(type); // 'sequence'
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## ð Use Cases
|
|
117
|
+
|
|
118
|
+
### Express.js API Endpoint
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
import express from 'express';
|
|
122
|
+
import { validate } from '@a24z/mermaid-parser';
|
|
123
|
+
|
|
124
|
+
const app = express();
|
|
125
|
+
app.use(express.json());
|
|
126
|
+
|
|
127
|
+
app.post('/api/validate-diagram', async (req, res) => {
|
|
128
|
+
const { diagram } = req.body;
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
const result = await validate(diagram);
|
|
132
|
+
if (result) {
|
|
133
|
+
res.json({
|
|
134
|
+
valid: true,
|
|
135
|
+
type: result.diagramType,
|
|
136
|
+
config: result.config
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
res.status(400).json({
|
|
140
|
+
valid: false,
|
|
141
|
+
error: 'Invalid diagram syntax'
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
} catch (error) {
|
|
145
|
+
res.status(400).json({
|
|
146
|
+
valid: false,
|
|
147
|
+
error: error.message
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### AWS Lambda Function
|
|
154
|
+
|
|
155
|
+
```javascript
|
|
156
|
+
import { validate } from '@a24z/mermaid-parser';
|
|
157
|
+
|
|
158
|
+
export const handler = async (event) => {
|
|
159
|
+
const { diagram } = JSON.parse(event.body);
|
|
160
|
+
|
|
161
|
+
const result = await validate(diagram, { suppressErrors: true });
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
statusCode: result ? 200 : 400,
|
|
165
|
+
body: JSON.stringify({
|
|
166
|
+
valid: !!result,
|
|
167
|
+
diagramType: result?.diagramType,
|
|
168
|
+
}),
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### GitHub Actions CI/CD
|
|
174
|
+
|
|
175
|
+
```yaml
|
|
176
|
+
name: Validate Mermaid Diagrams
|
|
177
|
+
on: [push, pull_request]
|
|
178
|
+
|
|
179
|
+
jobs:
|
|
180
|
+
validate:
|
|
181
|
+
runs-on: ubuntu-latest
|
|
182
|
+
steps:
|
|
183
|
+
- uses: actions/checkout@v3
|
|
184
|
+
- uses: oven-sh/setup-bun@v1
|
|
185
|
+
- run: bun install @a24z/mermaid-parser
|
|
186
|
+
- run: |
|
|
187
|
+
bun -e "
|
|
188
|
+
import { validate } from '@a24z/mermaid-parser';
|
|
189
|
+
import { readFileSync } from 'fs';
|
|
190
|
+
|
|
191
|
+
const diagram = readFileSync('docs/architecture.mmd', 'utf8');
|
|
192
|
+
const result = await validate(diagram);
|
|
193
|
+
|
|
194
|
+
if (!result) {
|
|
195
|
+
console.error('â Invalid diagram in docs/architecture.mmd');
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
console.log(\`â
Valid \${result.diagramType} diagram\`);
|
|
200
|
+
"
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Next.js API Route
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// pages/api/validate.ts
|
|
207
|
+
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
208
|
+
import { validate } from '@a24z/mermaid-parser';
|
|
209
|
+
|
|
210
|
+
export default async function handler(
|
|
211
|
+
req: NextApiRequest,
|
|
212
|
+
res: NextApiResponse
|
|
213
|
+
) {
|
|
214
|
+
if (req.method !== 'POST') {
|
|
215
|
+
return res.status(405).json({ message: 'Method not allowed' });
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const { diagram } = req.body;
|
|
219
|
+
|
|
220
|
+
const result = await validate(diagram, { suppressErrors: true });
|
|
221
|
+
|
|
222
|
+
res.status(result ? 200 : 400).json({
|
|
223
|
+
valid: !!result,
|
|
224
|
+
type: result?.diagramType,
|
|
225
|
+
config: result?.config,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Deno Script
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
import { validate } from 'npm:@a24z/mermaid-parser';
|
|
234
|
+
|
|
235
|
+
const diagram = await Deno.readTextFile('./diagram.mmd');
|
|
236
|
+
const result = await validate(diagram);
|
|
237
|
+
|
|
238
|
+
if (result) {
|
|
239
|
+
console.log(`â
Valid ${result.diagramType} diagram`);
|
|
240
|
+
} else {
|
|
241
|
+
console.log('â Invalid diagram');
|
|
242
|
+
Deno.exit(1);
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## ð Performance Comparison
|
|
247
|
+
|
|
248
|
+
| Package | Size | Load Time | Memory Usage | Use Case |
|
|
249
|
+
|---------|------|-----------|--------------|----------|
|
|
250
|
+
| `mermaid` (full) | ~2MB | ~500ms | ~50MB | Browser rendering |
|
|
251
|
+
| `@a24z/mermaid-parser` | ~50KB | ~10ms | ~5MB | Server validation |
|
|
252
|
+
|
|
253
|
+
## ð§ API Reference
|
|
254
|
+
|
|
255
|
+
### `validate(text: string, options?: ParseOptions): Promise<ParseResult | false>`
|
|
256
|
+
|
|
257
|
+
Validates a Mermaid diagram and returns the result.
|
|
258
|
+
|
|
259
|
+
**Parameters:**
|
|
260
|
+
- `text`: The Mermaid diagram definition
|
|
261
|
+
- `options.suppressErrors`: If true, returns `false` instead of throwing errors
|
|
262
|
+
|
|
263
|
+
**Returns:**
|
|
264
|
+
- `ParseResult` with `diagramType` and `config` if valid
|
|
265
|
+
- `false` if invalid (when `suppressErrors: true`)
|
|
266
|
+
- Throws error if invalid (when `suppressErrors: false`)
|
|
267
|
+
|
|
268
|
+
### `parse(text: string): Promise<DetailedParseResult>`
|
|
269
|
+
|
|
270
|
+
Parses a diagram and returns detailed information including errors.
|
|
271
|
+
|
|
272
|
+
### `isSupported(diagramType: string): boolean`
|
|
273
|
+
|
|
274
|
+
Checks if a diagram type is supported.
|
|
275
|
+
|
|
276
|
+
### `getSupportedDiagrams(): string[]`
|
|
277
|
+
|
|
278
|
+
Returns array of all supported diagram types.
|
|
279
|
+
|
|
280
|
+
### `getDiagramType(text: string): string`
|
|
281
|
+
|
|
282
|
+
Detects diagram type without full validation.
|
|
283
|
+
|
|
284
|
+
## ðïļ Architecture
|
|
285
|
+
|
|
286
|
+
This package provides a lightweight alternative by:
|
|
287
|
+
|
|
288
|
+
1. **Stubbing DOM APIs** - Provides browser globals for Node.js environments
|
|
289
|
+
2. **Pattern-based detection** - Uses regex patterns instead of full parsers
|
|
290
|
+
3. **Syntax validation** - Validates basic syntax rules for each diagram type
|
|
291
|
+
4. **Zero rendering** - No D3.js, no SVG generation, no layout calculation
|
|
292
|
+
5. **Minimal dependencies** - Only `js-yaml` for config parsing
|
|
293
|
+
|
|
294
|
+
## ðĪ Contributing
|
|
295
|
+
|
|
296
|
+
Contributions are welcome! This package aims to be:
|
|
297
|
+
|
|
298
|
+
- **Lightweight**: Keep bundle size minimal
|
|
299
|
+
- **Compatible**: Work in all JavaScript environments
|
|
300
|
+
- **Accurate**: Match Mermaid's diagram type detection
|
|
301
|
+
- **Fast**: Optimize for validation speed
|
|
302
|
+
|
|
303
|
+
## ð License
|
|
304
|
+
|
|
305
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
306
|
+
|
|
307
|
+
## ð Related
|
|
308
|
+
|
|
309
|
+
- [Mermaid](https://mermaid.js.org/) - The original Mermaid library
|
|
310
|
+
- [Mermaid Live Editor](https://mermaid.live/) - Online Mermaid editor
|
|
311
|
+
- [Mermaid CLI](https://github.com/mermaid-js/mermaid-cli) - Command line tool
|
|
312
|
+
|
|
313
|
+
## ð Changelog
|
|
314
|
+
|
|
315
|
+
See [CHANGELOG.md](CHANGELOG.md) for release history.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
**Made with âĪïļ for the Mermaid community**
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @a24z/mermaid-parser - Lightweight Mermaid diagram validator
|
|
3
|
+
*
|
|
4
|
+
* This package provides validation-only functionality for Mermaid diagrams
|
|
5
|
+
* without the heavy rendering dependencies. Perfect for server-side validation,
|
|
6
|
+
* CI/CD pipelines, and API endpoints.
|
|
7
|
+
*/
|
|
8
|
+
import './dom-stubs.js';
|
|
9
|
+
export interface ParseOptions {
|
|
10
|
+
suppressErrors?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface ParseResult {
|
|
13
|
+
diagramType: string;
|
|
14
|
+
config?: any;
|
|
15
|
+
warnings?: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface DetailedParseResult {
|
|
18
|
+
type: string;
|
|
19
|
+
config?: any;
|
|
20
|
+
valid: boolean;
|
|
21
|
+
error?: string;
|
|
22
|
+
warnings?: string[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validate a mermaid diagram without rendering
|
|
26
|
+
* @param text - The mermaid diagram definition
|
|
27
|
+
* @param parseOptions - Options for parsing
|
|
28
|
+
* @returns Validation result with diagram type if valid, false if invalid
|
|
29
|
+
*/
|
|
30
|
+
export declare function validate(text: string, parseOptions?: ParseOptions): Promise<ParseResult | false>;
|
|
31
|
+
/**
|
|
32
|
+
* Parse a diagram and return detailed information
|
|
33
|
+
*/
|
|
34
|
+
export declare function parse(text: string): Promise<DetailedParseResult>;
|
|
35
|
+
/**
|
|
36
|
+
* Check if a diagram type is supported
|
|
37
|
+
*/
|
|
38
|
+
export declare function isSupported(diagramType: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Get list of supported diagram types
|
|
41
|
+
*/
|
|
42
|
+
export declare function getSupportedDiagrams(): string[];
|
|
43
|
+
/**
|
|
44
|
+
* Get diagram type from text without full validation
|
|
45
|
+
*/
|
|
46
|
+
export declare function getDiagramType(text: string): string;
|
|
47
|
+
declare const mermaidValidator: {
|
|
48
|
+
validate: typeof validate;
|
|
49
|
+
parse: typeof parse;
|
|
50
|
+
isSupported: typeof isSupported;
|
|
51
|
+
getSupportedDiagrams: typeof getSupportedDiagrams;
|
|
52
|
+
getDiagramType: typeof getDiagramType;
|
|
53
|
+
};
|
|
54
|
+
export default mermaidValidator;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
// src/dom-stubs.ts
|
|
2
|
+
if (typeof globalThis !== "undefined") {
|
|
3
|
+
if (typeof window === "undefined") {
|
|
4
|
+
globalThis.window = {
|
|
5
|
+
scrollX: 0,
|
|
6
|
+
scrollY: 0,
|
|
7
|
+
location: { href: "" },
|
|
8
|
+
navigator: { userAgent: "mermaid-validator" },
|
|
9
|
+
addEventListener: () => {},
|
|
10
|
+
removeEventListener: () => {},
|
|
11
|
+
getComputedStyle: () => ({
|
|
12
|
+
getPropertyValue: () => ""
|
|
13
|
+
})
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (typeof document === "undefined") {
|
|
17
|
+
globalThis.document = {
|
|
18
|
+
querySelector: () => null,
|
|
19
|
+
querySelectorAll: () => [],
|
|
20
|
+
getElementById: () => null,
|
|
21
|
+
getElementsByClassName: () => [],
|
|
22
|
+
getElementsByTagName: () => [],
|
|
23
|
+
createElement: () => ({
|
|
24
|
+
tagName: "div",
|
|
25
|
+
style: {},
|
|
26
|
+
setAttribute: () => {},
|
|
27
|
+
getAttribute: () => null,
|
|
28
|
+
removeAttribute: () => {},
|
|
29
|
+
addEventListener: () => {},
|
|
30
|
+
removeEventListener: () => {},
|
|
31
|
+
appendChild: () => {},
|
|
32
|
+
removeChild: () => {},
|
|
33
|
+
getBoundingClientRect: () => ({
|
|
34
|
+
top: 0,
|
|
35
|
+
left: 0,
|
|
36
|
+
right: 0,
|
|
37
|
+
bottom: 0,
|
|
38
|
+
width: 100,
|
|
39
|
+
height: 20,
|
|
40
|
+
x: 0,
|
|
41
|
+
y: 0
|
|
42
|
+
}),
|
|
43
|
+
innerHTML: "",
|
|
44
|
+
textContent: "",
|
|
45
|
+
childNodes: [],
|
|
46
|
+
classList: {
|
|
47
|
+
add: () => {},
|
|
48
|
+
remove: () => {},
|
|
49
|
+
contains: () => false
|
|
50
|
+
}
|
|
51
|
+
}),
|
|
52
|
+
createElementNS: () => ({
|
|
53
|
+
setAttribute: () => {},
|
|
54
|
+
getAttribute: () => null,
|
|
55
|
+
getBBox: () => ({ x: 0, y: 0, width: 100, height: 20 })
|
|
56
|
+
}),
|
|
57
|
+
createTextNode: () => ({}),
|
|
58
|
+
body: { appendChild: () => {}, style: {} }
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (typeof Element === "undefined") {
|
|
62
|
+
globalThis.Element = class Element2 {
|
|
63
|
+
setAttribute() {}
|
|
64
|
+
getAttribute() {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
removeAttribute() {}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/index.ts
|
|
73
|
+
import * as yaml from "js-yaml";
|
|
74
|
+
var DIAGRAM_PATTERNS = {
|
|
75
|
+
flowchart: /^\s*(graph|flowchart)(\s+TD|TB|BT|RL|LR)?/i,
|
|
76
|
+
sequence: /^\s*sequenceDiagram/i,
|
|
77
|
+
class: /^\s*classDiagram/i,
|
|
78
|
+
state: /^\s*stateDiagram(-v2)?/i,
|
|
79
|
+
er: /^\s*erDiagram/i,
|
|
80
|
+
journey: /^\s*journey/i,
|
|
81
|
+
gantt: /^\s*gantt/i,
|
|
82
|
+
pie: /^\s*pie(\s+title)?/i,
|
|
83
|
+
gitgraph: /^\s*gitGraph/i,
|
|
84
|
+
mindmap: /^\s*mindmap/i,
|
|
85
|
+
timeline: /^\s*timeline/i,
|
|
86
|
+
quadrant: /^\s*quadrantChart/i,
|
|
87
|
+
requirement: /^\s*requirementDiagram/i,
|
|
88
|
+
c4context: /^\s*C4Context/i,
|
|
89
|
+
c4container: /^\s*C4Container/i,
|
|
90
|
+
c4component: /^\s*C4Component/i,
|
|
91
|
+
c4dynamic: /^\s*C4Dynamic/i,
|
|
92
|
+
c4deployment: /^\s*C4Deployment/i,
|
|
93
|
+
sankey: /^\s*sankey-beta/i,
|
|
94
|
+
block: /^\s*block-beta/i,
|
|
95
|
+
packet: /^\s*packet-beta/i,
|
|
96
|
+
architecture: /^\s*architecture-beta/i,
|
|
97
|
+
xyChart: /^\s*xychart-beta/i
|
|
98
|
+
};
|
|
99
|
+
function preprocessDiagram(text) {
|
|
100
|
+
const lines = text.split(`
|
|
101
|
+
`);
|
|
102
|
+
let config = {};
|
|
103
|
+
let codeLines = [];
|
|
104
|
+
let inDirective = false;
|
|
105
|
+
let directiveText = "";
|
|
106
|
+
for (const line of lines) {
|
|
107
|
+
const trimmed = line.trim();
|
|
108
|
+
if (trimmed.startsWith("%%{")) {
|
|
109
|
+
inDirective = true;
|
|
110
|
+
directiveText = trimmed.slice(3);
|
|
111
|
+
if (trimmed.endsWith("}%%")) {
|
|
112
|
+
directiveText = directiveText.slice(0, -3);
|
|
113
|
+
try {
|
|
114
|
+
const parsed = JSON.parse(directiveText);
|
|
115
|
+
config = { ...config, ...parsed };
|
|
116
|
+
} catch {
|
|
117
|
+
try {
|
|
118
|
+
const yamlParsed = yaml.load(directiveText);
|
|
119
|
+
config = { ...config, ...yamlParsed };
|
|
120
|
+
} catch {}
|
|
121
|
+
}
|
|
122
|
+
inDirective = false;
|
|
123
|
+
directiveText = "";
|
|
124
|
+
}
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (inDirective) {
|
|
128
|
+
directiveText += line;
|
|
129
|
+
if (trimmed.endsWith("}%%")) {
|
|
130
|
+
directiveText = directiveText.slice(0, -3);
|
|
131
|
+
try {
|
|
132
|
+
const parsed = JSON.parse(directiveText);
|
|
133
|
+
config = { ...config, ...parsed };
|
|
134
|
+
} catch {}
|
|
135
|
+
inDirective = false;
|
|
136
|
+
directiveText = "";
|
|
137
|
+
}
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (trimmed.startsWith("%%") || trimmed.startsWith("#")) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
codeLines.push(line);
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
code: codeLines.join(`
|
|
147
|
+
`),
|
|
148
|
+
config: Object.keys(config).length > 0 ? config : undefined
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function detectType(text) {
|
|
152
|
+
const cleaned = text.trim();
|
|
153
|
+
for (const [type, pattern] of Object.entries(DIAGRAM_PATTERNS)) {
|
|
154
|
+
if (pattern.test(cleaned)) {
|
|
155
|
+
return type;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return "unknown";
|
|
159
|
+
}
|
|
160
|
+
function checkNodeLabels(text, diagramType) {
|
|
161
|
+
const warnings = [];
|
|
162
|
+
if (diagramType === "flowchart" || diagramType === "graph") {
|
|
163
|
+
const nodePattern = /\w+\[([^\]]+)\]/g;
|
|
164
|
+
let match;
|
|
165
|
+
while ((match = nodePattern.exec(text)) !== null) {
|
|
166
|
+
const label = match[1];
|
|
167
|
+
if (/^\s*[-*]\s+/m.test(label)) {
|
|
168
|
+
warnings.push(`Node label "${label}" contains markdown list syntax which is not supported in Mermaid nodes`);
|
|
169
|
+
}
|
|
170
|
+
if (/^\s*\d+\.\s+/m.test(label)) {
|
|
171
|
+
warnings.push(`Node label "${label}" contains numbered list syntax which is not supported in Mermaid nodes`);
|
|
172
|
+
}
|
|
173
|
+
if (/^#+\s+/m.test(label)) {
|
|
174
|
+
warnings.push(`Node label "${label}" contains markdown header syntax which may not render correctly`);
|
|
175
|
+
}
|
|
176
|
+
if (/```/.test(label)) {
|
|
177
|
+
warnings.push(`Node label "${label}" contains code block syntax which is not supported in Mermaid nodes`);
|
|
178
|
+
}
|
|
179
|
+
if (/<[^>]+>/.test(label)) {
|
|
180
|
+
warnings.push(`Node label "${label}" contains HTML tags which may not render correctly`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const edgePattern = /\|([^|]+)\|/g;
|
|
184
|
+
while ((match = edgePattern.exec(text)) !== null) {
|
|
185
|
+
const label = match[1];
|
|
186
|
+
if (/^\s*[-*]\s+/m.test(label)) {
|
|
187
|
+
warnings.push(`Edge label "${label}" contains markdown list syntax which may cause rendering issues`);
|
|
188
|
+
}
|
|
189
|
+
if (/^\s*\d+\.\s+/m.test(label)) {
|
|
190
|
+
warnings.push(`Edge label "${label}" contains numbered list which may cause rendering issues`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return warnings;
|
|
195
|
+
}
|
|
196
|
+
var SYNTAX_VALIDATORS = {
|
|
197
|
+
flowchart: (text) => {
|
|
198
|
+
const hasNodes = /\w+\s*(\[|\(|\{)/.test(text);
|
|
199
|
+
const hasArrows = /\w+\s*-+>+\s*\w+/.test(text);
|
|
200
|
+
const hasValidSyntax = !/[<>]{3,}/.test(text);
|
|
201
|
+
return (hasNodes || hasArrows) && hasValidSyntax;
|
|
202
|
+
},
|
|
203
|
+
sequence: (text) => {
|
|
204
|
+
const hasParticipants = /participant\s+\w+|actor\s+\w+|\w+\s*-[->]+\s*\w+/.test(text);
|
|
205
|
+
return hasParticipants;
|
|
206
|
+
},
|
|
207
|
+
class: (text) => {
|
|
208
|
+
const hasClasses = /class\s+\w+|[\w\s]+\s*[<|>-]+\s*[\w\s]+/.test(text);
|
|
209
|
+
return hasClasses;
|
|
210
|
+
},
|
|
211
|
+
state: (text) => {
|
|
212
|
+
const hasStates = /\[\*\]|\w+\s*-->\s*\w+|state\s+\w+/.test(text);
|
|
213
|
+
return hasStates;
|
|
214
|
+
},
|
|
215
|
+
er: (text) => {
|
|
216
|
+
const hasEntities = /\w+\s+\|\|?--[o{]?\{?\s*\w+/.test(text);
|
|
217
|
+
return hasEntities;
|
|
218
|
+
},
|
|
219
|
+
gantt: (text) => {
|
|
220
|
+
const hasGanttElements = /section\s+|title\s+|\w+\s*:\s*[\w,\s-]+/.test(text);
|
|
221
|
+
return hasGanttElements;
|
|
222
|
+
},
|
|
223
|
+
pie: (text) => {
|
|
224
|
+
const hasData = /"[^"]+"\s*:\s*\d+/.test(text);
|
|
225
|
+
return hasData;
|
|
226
|
+
},
|
|
227
|
+
journey: (text) => {
|
|
228
|
+
const hasJourneyElements = /section\s+|\w+:\s*\d+/.test(text);
|
|
229
|
+
return hasJourneyElements;
|
|
230
|
+
},
|
|
231
|
+
default: () => true
|
|
232
|
+
};
|
|
233
|
+
async function validate(text, parseOptions) {
|
|
234
|
+
try {
|
|
235
|
+
if (!text || typeof text !== "string") {
|
|
236
|
+
throw new Error("Invalid input: text must be a non-empty string");
|
|
237
|
+
}
|
|
238
|
+
const processed = preprocessDiagram(text);
|
|
239
|
+
const type = detectType(processed.code);
|
|
240
|
+
if (type === "unknown") {
|
|
241
|
+
throw new Error("Unknown diagram type");
|
|
242
|
+
}
|
|
243
|
+
const validator = SYNTAX_VALIDATORS[type] || SYNTAX_VALIDATORS.default;
|
|
244
|
+
const isValid = validator(processed.code);
|
|
245
|
+
if (!isValid) {
|
|
246
|
+
throw new Error(`Invalid ${type} diagram syntax`);
|
|
247
|
+
}
|
|
248
|
+
const warnings = checkNodeLabels(processed.code, type);
|
|
249
|
+
return {
|
|
250
|
+
diagramType: type,
|
|
251
|
+
config: processed.config,
|
|
252
|
+
warnings: warnings.length > 0 ? warnings : undefined
|
|
253
|
+
};
|
|
254
|
+
} catch (error) {
|
|
255
|
+
if (parseOptions?.suppressErrors) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
throw error;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async function parse(text) {
|
|
262
|
+
try {
|
|
263
|
+
const result = await validate(text, { suppressErrors: false });
|
|
264
|
+
if (result) {
|
|
265
|
+
return {
|
|
266
|
+
type: result.diagramType,
|
|
267
|
+
config: result.config,
|
|
268
|
+
valid: true,
|
|
269
|
+
warnings: result.warnings
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
type: "unknown",
|
|
274
|
+
valid: false
|
|
275
|
+
};
|
|
276
|
+
} catch (error) {
|
|
277
|
+
return {
|
|
278
|
+
type: "unknown",
|
|
279
|
+
valid: false,
|
|
280
|
+
error: error instanceof Error ? error.message : String(error)
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function isSupported(diagramType) {
|
|
285
|
+
return Object.keys(DIAGRAM_PATTERNS).includes(diagramType);
|
|
286
|
+
}
|
|
287
|
+
function getSupportedDiagrams() {
|
|
288
|
+
return Object.keys(DIAGRAM_PATTERNS);
|
|
289
|
+
}
|
|
290
|
+
function getDiagramType(text) {
|
|
291
|
+
const processed = preprocessDiagram(text);
|
|
292
|
+
return detectType(processed.code);
|
|
293
|
+
}
|
|
294
|
+
var mermaidValidator = {
|
|
295
|
+
validate,
|
|
296
|
+
parse,
|
|
297
|
+
isSupported,
|
|
298
|
+
getSupportedDiagrams,
|
|
299
|
+
getDiagramType
|
|
300
|
+
};
|
|
301
|
+
var src_default = mermaidValidator;
|
|
302
|
+
export {
|
|
303
|
+
validate,
|
|
304
|
+
parse,
|
|
305
|
+
isSupported,
|
|
306
|
+
getSupportedDiagrams,
|
|
307
|
+
getDiagramType,
|
|
308
|
+
src_default as default
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
//# debugId=52B77ECA8D89C42664756E2164756E21
|
|
312
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/dom-stubs.ts", "../src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * DOM stubs for non-browser environments\n * Used in the validation-only build to provide browser APIs\n */\n\n// Skip TypeScript global declarations to avoid conflicts\n\n// Only create globals if they don't exist (avoid conflicts in browser)\nif (typeof globalThis !== 'undefined') {\n if (typeof window === 'undefined') {\n (globalThis as any).window = {\n scrollX: 0,\n scrollY: 0,\n location: { href: '' },\n navigator: { userAgent: 'mermaid-validator' },\n addEventListener: () => {},\n removeEventListener: () => {},\n getComputedStyle: () => ({\n getPropertyValue: () => '',\n }),\n };\n }\n\n if (typeof document === 'undefined') {\n (globalThis as any).document = {\n querySelector: () => null,\n querySelectorAll: () => [],\n getElementById: () => null,\n getElementsByClassName: () => [],\n getElementsByTagName: () => [],\n createElement: () => ({\n tagName: 'div',\n style: {},\n setAttribute: () => {},\n getAttribute: () => null,\n removeAttribute: () => {},\n addEventListener: () => {},\n removeEventListener: () => {},\n appendChild: () => {},\n removeChild: () => {},\n getBoundingClientRect: () => ({\n top: 0, left: 0, right: 0, bottom: 0,\n width: 100, height: 20, x: 0, y: 0,\n }),\n innerHTML: '',\n textContent: '',\n childNodes: [],\n classList: {\n add: () => {},\n remove: () => {},\n contains: () => false,\n },\n }),\n createElementNS: () => ({\n setAttribute: () => {},\n getAttribute: () => null,\n getBBox: () => ({ x: 0, y: 0, width: 100, height: 20 }),\n }),\n createTextNode: () => ({}),\n body: { appendChild: () => {}, style: {} },\n };\n }\n\n if (typeof Element === 'undefined') {\n (globalThis as any).Element = class Element {\n setAttribute() {}\n getAttribute() { return null; }\n removeAttribute() {}\n };\n }\n}\n\nexport {};",
|
|
6
|
+
"/**\n * @a24z/mermaid-parser - Lightweight Mermaid diagram validator\n * \n * This package provides validation-only functionality for Mermaid diagrams\n * without the heavy rendering dependencies. Perfect for server-side validation,\n * CI/CD pipelines, and API endpoints.\n */\n\nimport './dom-stubs.js';\nimport * as yaml from 'js-yaml';\n\nexport interface ParseOptions {\n suppressErrors?: boolean;\n}\n\nexport interface ParseResult {\n diagramType: string;\n config?: any;\n warnings?: string[];\n}\n\nexport interface DetailedParseResult {\n type: string;\n config?: any;\n valid: boolean;\n error?: string;\n warnings?: string[];\n}\n\n/**\n * Basic diagram type detection patterns\n */\nconst DIAGRAM_PATTERNS = {\n flowchart: /^\\s*(graph|flowchart)(\\s+TD|TB|BT|RL|LR)?/i,\n sequence: /^\\s*sequenceDiagram/i,\n class: /^\\s*classDiagram/i,\n state: /^\\s*stateDiagram(-v2)?/i,\n er: /^\\s*erDiagram/i,\n journey: /^\\s*journey/i,\n gantt: /^\\s*gantt/i,\n pie: /^\\s*pie(\\s+title)?/i,\n gitgraph: /^\\s*gitGraph/i,\n mindmap: /^\\s*mindmap/i,\n timeline: /^\\s*timeline/i,\n quadrant: /^\\s*quadrantChart/i,\n requirement: /^\\s*requirementDiagram/i,\n c4context: /^\\s*C4Context/i,\n c4container: /^\\s*C4Container/i,\n c4component: /^\\s*C4Component/i,\n c4dynamic: /^\\s*C4Dynamic/i,\n c4deployment: /^\\s*C4Deployment/i,\n sankey: /^\\s*sankey-beta/i,\n block: /^\\s*block-beta/i,\n packet: /^\\s*packet-beta/i,\n architecture: /^\\s*architecture-beta/i,\n xyChart: /^\\s*xychart-beta/i,\n};\n\n/**\n * Simple preprocessing to extract config and clean diagram text\n */\nfunction preprocessDiagram(text: string): { code: string; config?: any } {\n const lines = text.split('\\n');\n let config: any = {};\n let codeLines: string[] = [];\n let inDirective = false;\n let directiveText = '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n \n // Handle directives (%%{...}%%)\n if (trimmed.startsWith('%%{')) {\n inDirective = true;\n directiveText = trimmed.slice(3);\n if (trimmed.endsWith('}%%')) {\n directiveText = directiveText.slice(0, -3);\n try {\n const parsed = JSON.parse(directiveText);\n config = { ...config, ...parsed };\n } catch {\n // Try parsing with js-yaml as fallback\n try {\n const yamlParsed = yaml.load(directiveText) as any;\n config = { ...config, ...yamlParsed };\n } catch {\n // Ignore invalid directives\n }\n }\n inDirective = false;\n directiveText = '';\n }\n continue;\n }\n \n if (inDirective) {\n directiveText += line;\n if (trimmed.endsWith('}%%')) {\n directiveText = directiveText.slice(0, -3);\n try {\n const parsed = JSON.parse(directiveText);\n config = { ...config, ...parsed };\n } catch {\n // Ignore invalid JSON\n }\n inDirective = false;\n directiveText = '';\n }\n continue;\n }\n \n // Skip comments\n if (trimmed.startsWith('%%') || trimmed.startsWith('#')) {\n continue;\n }\n \n codeLines.push(line);\n }\n\n return {\n code: codeLines.join('\\n'),\n config: Object.keys(config).length > 0 ? config : undefined,\n };\n}\n\n/**\n * Detect diagram type from text\n */\nfunction detectType(text: string): string {\n const cleaned = text.trim();\n \n for (const [type, pattern] of Object.entries(DIAGRAM_PATTERNS)) {\n if (pattern.test(cleaned)) {\n return type;\n }\n }\n \n return 'unknown';\n}\n\n/**\n * Check for potential rendering issues in node labels\n */\nfunction checkNodeLabels(text: string, diagramType: string): string[] {\n const warnings: string[] = [];\n \n if (diagramType === 'flowchart' || diagramType === 'graph') {\n // Check for problematic markdown in node labels\n // Mermaid nodes with [] support limited markdown\n \n // Pattern to match node definitions with square brackets\n const nodePattern = /\\w+\\[([^\\]]+)\\]/g;\n let match;\n \n while ((match = nodePattern.exec(text)) !== null) {\n const label = match[1];\n \n // Check for markdown lists (- or * at start of lines)\n if (/^\\s*[-*]\\s+/m.test(label)) {\n warnings.push(`Node label \"${label}\" contains markdown list syntax which is not supported in Mermaid nodes`);\n }\n \n // Check for numbered lists\n if (/^\\s*\\d+\\.\\s+/m.test(label)) {\n warnings.push(`Node label \"${label}\" contains numbered list syntax which is not supported in Mermaid nodes`);\n }\n \n // Check for headers\n if (/^#+\\s+/m.test(label)) {\n warnings.push(`Node label \"${label}\" contains markdown header syntax which may not render correctly`);\n }\n \n // Check for code blocks\n if (/```/.test(label)) {\n warnings.push(`Node label \"${label}\" contains code block syntax which is not supported in Mermaid nodes`);\n }\n \n // Check for HTML tags (common issue)\n if (/<[^>]+>/.test(label)) {\n warnings.push(`Node label \"${label}\" contains HTML tags which may not render correctly`);\n }\n }\n \n // Also check edge labels\n const edgePattern = /\\|([^|]+)\\|/g;\n while ((match = edgePattern.exec(text)) !== null) {\n const label = match[1];\n \n // Check for problematic characters in edge labels\n if (/^\\s*[-*]\\s+/m.test(label)) {\n warnings.push(`Edge label \"${label}\" contains markdown list syntax which may cause rendering issues`);\n }\n \n if (/^\\s*\\d+\\.\\s+/m.test(label)) {\n warnings.push(`Edge label \"${label}\" contains numbered list which may cause rendering issues`);\n }\n }\n }\n \n return warnings;\n}\n\n/**\n * Basic syntax validation for different diagram types\n */\nconst SYNTAX_VALIDATORS = {\n flowchart: (text: string) => {\n // Basic flowchart validation - look for nodes or arrows\n const hasNodes = /\\w+\\s*(\\[|\\(|\\{)/.test(text);\n const hasArrows = /\\w+\\s*-+>+\\s*\\w+/.test(text);\n const hasValidSyntax = !/[<>]{3,}/.test(text); // Avoid invalid arrow syntax\n return (hasNodes || hasArrows) && hasValidSyntax;\n },\n \n sequence: (text: string) => {\n // Check for participant or actor definitions, or direct interactions\n const hasParticipants = /participant\\s+\\w+|actor\\s+\\w+|\\w+\\s*-[->]+\\s*\\w+/.test(text);\n return hasParticipants;\n },\n \n class: (text: string) => {\n // Check for class definitions or relationships\n const hasClasses = /class\\s+\\w+|[\\w\\s]+\\s*[<|>-]+\\s*[\\w\\s]+/.test(text);\n return hasClasses;\n },\n \n state: (text: string) => {\n // Check for state definitions or transitions\n const hasStates = /\\[\\*\\]|\\w+\\s*-->\\s*\\w+|state\\s+\\w+/.test(text);\n return hasStates;\n },\n \n er: (text: string) => {\n // Check for entity relationships\n const hasEntities = /\\w+\\s+\\|\\|?--[o{]?\\{?\\s*\\w+/.test(text);\n return hasEntities;\n },\n \n gantt: (text: string) => {\n // Check for sections and tasks\n const hasGanttElements = /section\\s+|title\\s+|\\w+\\s*:\\s*[\\w,\\s-]+/.test(text);\n return hasGanttElements;\n },\n \n pie: (text: string) => {\n // Check for pie chart data\n const hasData = /\"[^\"]+\"\\s*:\\s*\\d+/.test(text);\n return hasData;\n },\n \n journey: (text: string) => {\n // Check for journey sections\n const hasJourneyElements = /section\\s+|\\w+:\\s*\\d+/.test(text);\n return hasJourneyElements;\n },\n \n default: () => true, // Accept other diagram types without deep validation\n};\n\n/**\n * Validate a mermaid diagram without rendering\n * @param text - The mermaid diagram definition\n * @param parseOptions - Options for parsing\n * @returns Validation result with diagram type if valid, false if invalid\n */\nexport async function validate(\n text: string,\n parseOptions?: ParseOptions\n): Promise<ParseResult | false> {\n try {\n if (!text || typeof text !== 'string') {\n throw new Error('Invalid input: text must be a non-empty string');\n }\n\n const processed = preprocessDiagram(text);\n const type = detectType(processed.code);\n \n if (type === 'unknown') {\n throw new Error('Unknown diagram type');\n }\n\n // Run basic syntax validation\n const validator = SYNTAX_VALIDATORS[type as keyof typeof SYNTAX_VALIDATORS] || SYNTAX_VALIDATORS.default;\n const isValid = validator(processed.code);\n \n if (!isValid) {\n throw new Error(`Invalid ${type} diagram syntax`);\n }\n\n // Check for potential rendering issues\n const warnings = checkNodeLabels(processed.code, type);\n\n return {\n diagramType: type,\n config: processed.config,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n } catch (error) {\n if (parseOptions?.suppressErrors) {\n return false;\n }\n throw error;\n }\n}\n\n/**\n * Parse a diagram and return detailed information\n */\nexport async function parse(text: string): Promise<DetailedParseResult> {\n try {\n const result = await validate(text, { suppressErrors: false });\n if (result) {\n return {\n type: result.diagramType,\n config: result.config,\n valid: true,\n warnings: result.warnings,\n };\n }\n return {\n type: 'unknown',\n valid: false,\n };\n } catch (error) {\n return {\n type: 'unknown',\n valid: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Check if a diagram type is supported\n */\nexport function isSupported(diagramType: string): boolean {\n return Object.keys(DIAGRAM_PATTERNS).includes(diagramType);\n}\n\n/**\n * Get list of supported diagram types\n */\nexport function getSupportedDiagrams(): string[] {\n return Object.keys(DIAGRAM_PATTERNS);\n}\n\n/**\n * Get diagram type from text without full validation\n */\nexport function getDiagramType(text: string): string {\n const processed = preprocessDiagram(text);\n return detectType(processed.code);\n}\n\n// Default export\nconst mermaidValidator = {\n validate,\n parse,\n isSupported,\n getSupportedDiagrams,\n getDiagramType,\n};\n\nexport default mermaidValidator;"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "52B77ECA8D89C42664756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@comper/mermaid-parser",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Lightweight Mermaid diagram validator for server-side environments - validation without rendering",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist/",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"mermaid",
|
|
23
|
+
"validator",
|
|
24
|
+
"parser",
|
|
25
|
+
"diagram",
|
|
26
|
+
"syntax",
|
|
27
|
+
"flowchart",
|
|
28
|
+
"sequence",
|
|
29
|
+
"class",
|
|
30
|
+
"state",
|
|
31
|
+
"serverless",
|
|
32
|
+
"node",
|
|
33
|
+
"validation",
|
|
34
|
+
"lightweight"
|
|
35
|
+
],
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/comper-io/mermaid-parser",
|
|
39
|
+
"directory": "packages/a24z-mermaid-parser"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/comper-io/mermaid-parser/tree/main/packages/a24z-mermaid-parser#readme",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/comper-io/mermaid-parser/issues"
|
|
44
|
+
},
|
|
45
|
+
"author": "A24Z - fork by Comper",
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18.0.0"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "bun run scripts/build.ts",
|
|
52
|
+
"test": "bun test",
|
|
53
|
+
"prepublishOnly": "bun run build",
|
|
54
|
+
"clean": "rm -rf dist",
|
|
55
|
+
"dev": "bun run scripts/build.ts --watch"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"bun": "^1.3.5",
|
|
59
|
+
"js-yaml": "^4.1.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/js-yaml": "^4.0.5",
|
|
63
|
+
"bun-types": "^1.0.0",
|
|
64
|
+
"typescript": "^5.0.0"
|
|
65
|
+
},
|
|
66
|
+
"publishConfig": {
|
|
67
|
+
"access": "public",
|
|
68
|
+
"registry": "https://registry.npmjs.org/"
|
|
69
|
+
}
|
|
70
|
+
}
|