1
1
/**
2
2
* Copied from https://github.com/mermaid-js/mermaid/blob/4a4e614b646bdb5f91f02d0483a7704b315d09fd/packages/mermaid/src/diagram-api/regexes.ts
3
3
*/
4
-
5
- // The "* as yaml" part is necessary for tree-shaking
6
- import * as yaml from 'js-yaml' ;
4
+ import { parseDocument , type Document , YAMLMap , isMap } from 'yaml' ;
7
5
8
6
const frontMatterRegex = / ^ - { 3 } \s * [ \n \r ] ( .* ?) [ \n \r ] - { 3 } \s * [ \n \r ] + / s;
9
7
const urlIDRegex = / (?< baseURL > .* ) \/ d \/ (?< documentID > [ \w - ] + ) / ;
@@ -59,20 +57,13 @@ function splitFrontMatter(text: string) {
59
57
}
60
58
}
61
59
62
- function parseFrontMatterYAML ( frontMatterYaml : string ) {
63
- let parsed : FrontMatterMetadata =
64
- // TODO: replace with https://www.npmjs.com/package/yaml so that we can
65
- // read/write comments too
66
- yaml . load ( frontMatterYaml , {
67
- // To support config, we need JSON schema.
68
- // https://www.yaml.org/spec/1.2/spec.html#id2803231
69
- schema : yaml . JSON_SCHEMA ,
70
- } ) ?? { } ;
71
-
72
- // To handle runtime data type changes
73
- parsed = typeof parsed === 'object' && ! Array . isArray ( parsed ) ? parsed : { } ;
60
+ function parseFrontMatterYAML ( frontMatterYaml : string ) : Document < YAMLMap , false > {
61
+ const document : Document = parseDocument ( frontMatterYaml ) ;
62
+ if ( ! isMap ( document . contents ) ) {
63
+ document . contents = new YAMLMap ( ) ;
64
+ }
74
65
75
- return parsed ;
66
+ return document as unknown as Document < YAMLMap , false > ;
76
67
}
77
68
78
69
/**
@@ -85,7 +76,7 @@ function parseFrontMatterYAML(frontMatterYaml: string) {
85
76
export function extractFrontMatter ( text : string ) : FrontMatterResult {
86
77
const { diagramText, frontMatter } = splitFrontMatter ( text ) ;
87
78
88
- const parsed = parseFrontMatterYAML ( frontMatter ) ;
79
+ const parsed = parseFrontMatterYAML ( frontMatter ) . toJSON ( ) ;
89
80
90
81
const metadata : FrontMatterMetadata = { } ;
91
82
@@ -116,16 +107,16 @@ export function extractFrontMatter(text: string): FrontMatterResult {
116
107
* @param newMetadata - The metadata fields to update.
117
108
* @returns The text with the updated YAML frontmatter.
118
109
*/
119
- export function injectFrontMatter ( text : string , newMetadata : Partial < FrontMatterMetadata > ) {
110
+ export function injectFrontMatter ( text : string , newMetadata : Pick < FrontMatterMetadata , 'id' > ) {
120
111
const { diagramText, frontMatter } = splitFrontMatter ( text ) ;
121
112
122
- const parsed = parseFrontMatterYAML ( frontMatter ) ;
113
+ const document = parseFrontMatterYAML ( frontMatter ) ;
123
114
124
- const mergedFrontmatter = { ...parsed , ...newMetadata } ;
115
+ for ( const [ key , value ] of Object . entries ( newMetadata ) ) {
116
+ document . contents . set ( key , value ) ;
117
+ }
125
118
126
- return `---\n${ yaml . dump ( mergedFrontmatter , {
127
- schema : yaml . JSON_SCHEMA ,
128
- } ) } ---\n${ diagramText } `;
119
+ return `---\n${ document . toString ( ) } ---\n${ diagramText } ` ;
129
120
}
130
121
131
122
/**
@@ -138,24 +129,16 @@ export function injectFrontMatter(text: string, newMetadata: Partial<FrontMatter
138
129
export function removeFrontMatterKeys ( text : string , keysToRemove : Set < keyof FrontMatterMetadata > ) {
139
130
const { diagramText, frontMatter } = splitFrontMatter ( text ) ;
140
131
141
- const parsedFrontMatter = parseFrontMatterYAML ( frontMatter ) ;
132
+ const document = parseFrontMatterYAML ( frontMatter ) ;
142
133
143
- const entries = Object . entries ( parsedFrontMatter )
144
- . map ( ( val ) => {
145
- if ( keysToRemove . has ( val [ 0 ] as keyof FrontMatterMetadata ) ) {
146
- return null ;
147
- } else {
148
- return val ;
149
- }
150
- } )
151
- . filter ( ( val ) => val ) as [ string , any ] [ ] ; // eslint-disable-line @typescript-eslint/no-explicit-any
134
+ for ( const key of keysToRemove ) {
135
+ document . contents . delete ( key ) ;
136
+ }
152
137
153
- if ( entries . length === 0 ) {
138
+ if ( document . contents . items . length === 0 ) {
154
139
// skip creating frontmatter if there is no frontmatter
155
140
return diagramText ;
156
141
} else {
157
- return `---\n${ yaml . dump ( Object . fromEntries ( entries ) , {
158
- schema : yaml . JSON_SCHEMA ,
159
- } ) } ---\n${ diagramText } `;
142
+ return `---\n${ document . toString ( ) } ---\n${ diagramText } ` ;
160
143
}
161
144
}
0 commit comments