Skip to content

Commit 5602309

Browse files
committedApr 9, 2024
feat(cli)!: use a URL id in the frontmatter
Currently, we're using just an UUID for the id in the frontmatter of a link mermaid diagram, e.g.: ```mermaid --- id: 00000000-0000-0000-0000-000000000000 --- info ``` Instead, we can use a URL for an ID, e.g.: ```mermaid --- id: https://test.mermaidchart.invalid/d/00000000-0000-0000-0000-000000000000 --- info ``` This has the benefits of: 1. The MermaidChart server is part of the URL, which improves cases where users are using different instances of the MermaidChart app. 2. Users can click on the URL to instantly see their diagram on the Mermaid Chart app. BREAKING-CHANGE: Frontmatter `id`s are now URLs instead of just UUIDs.
1 parent 1ee1ab1 commit 5602309

7 files changed

+53
-18
lines changed
 

‎packages/cli/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ which points to the diagram on MermaidChart.com:
5757
```mermaid
5858
---
5959
title: My diagram
60-
id: xxxx-xxxxx-xxxxx # this field is created by @mermaidchart/cli
60+
id: https://www.mermaidchart.com/d/xxxx-xxxxx-xxxxx # this field is created by @mermaidchart/cli
6161
---
6262
flowchart
6363
x[My Diagram]

‎packages/cli/src/commander.test.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ describe('link', () => {
226226
);
227227

228228
await expect(readFile(diagram, { encoding: 'utf8' })).resolves.toContain(
229-
`id: ${mockedEmptyDiagram.documentID}`,
229+
`id: https://test.mermaidchart.invalid/d/${mockedEmptyDiagram.documentID}`,
230230
);
231231
});
232232

@@ -271,7 +271,7 @@ describe('link', () => {
271271
await Promise.all(
272272
[diagram, diagram2, diagram3].map(async (file) => {
273273
await expect(readFile(file, { encoding: 'utf8' })).resolves.toContain(
274-
`id: ${mockedEmptyDiagram.documentID}`,
274+
`id: https://test.mermaidchart.invalid/d/${mockedEmptyDiagram.documentID}`,
275275
);
276276
}),
277277
);
@@ -298,8 +298,10 @@ describe('link', () => {
298298

299299
const file = await readFile(unlinkedMarkdownFile, { encoding: 'utf8' });
300300

301-
expect(file).toMatch(`id: ${mockedEmptyDiagram.documentID}\n`);
302-
expect(file).toMatch(`id: second-id\n`);
301+
expect(file).toMatch(
302+
`id: https://test.mermaidchart.invalid/d/${mockedEmptyDiagram.documentID}\n`,
303+
);
304+
expect(file).toMatch(`id: https://test.mermaidchart.invalid/d/second-id\n`);
303305
});
304306

305307
it('should link diagrams in partially linked markdown file', async () => {
@@ -323,7 +325,7 @@ describe('link', () => {
323325

324326
const file = await readFile(partiallyLinkedMarkdownFile, { encoding: 'utf8' });
325327

326-
expect(file).toMatch(`id: second-id\n`);
328+
expect(file).toMatch(`id: https://test.mermaidchart.invalid/d/second-id\n`);
327329
});
328330

329331
it('should handle unusual markdown formatting', async () => {
@@ -347,7 +349,7 @@ describe('link', () => {
347349

348350
const file = await readFile(unusualMarkdownFile, { encoding: 'utf8' });
349351

350-
const idLineRegex = /^.*id: my-mocked-diagram-id\n/gm;
352+
const idLineRegex = /^.*id: https:\/\/test.mermaidchart.invalid\/d\/my-mocked-diagram-id\n/gm;
351353

352354
expect(file).toMatch(idLineRegex);
353355
// other than the added `id: xxxx` field, everything else should be identical,
@@ -412,7 +414,9 @@ title: My cool flowchart
412414
for (const file of [diagram, diagram2]) {
413415
const diagramContents = await readFile(file, { encoding: 'utf8' });
414416

415-
expect(diagramContents).toContain(`id: ${mockedDiagram.documentID}`);
417+
expect(diagramContents).toContain(
418+
`id: https://test.mermaidchart.invalid/d/${mockedDiagram.documentID}`,
419+
);
416420
expect(diagramContents).toContain("flowchart TD\n A[I've been updated!]");
417421
}
418422
});

‎packages/cli/src/frontmatter.ts

+25-2
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,37 @@
66
import * as yaml from 'js-yaml';
77

88
const frontMatterRegex = /^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s;
9+
const urlIDRegex = /(?<baseURL>.*)\/d\/(?<documentID>[\w-]+)/;
10+
11+
type UrlID = `${string}/d/${string}`;
12+
13+
export function getDocumentID(urlID: UrlID, expectedbaseURL: string) {
14+
const match = urlID.match(urlIDRegex);
15+
if (match === null) {
16+
throw new Error(
17+
`Invalid document ID: ${urlID}. Please report this issue to the @mermaidchart/cli maintainers.`,
18+
);
19+
}
20+
// we know that this regex will always return groups on a match
21+
const { baseURL, documentID } = match.groups as { baseURL: string; documentID: string };
22+
if (baseURL !== expectedbaseURL) {
23+
throw new Error(
24+
`Your @mermaidchart/cli is configured to use ${expectedbaseURL}, but your diagram is using ${baseURL}`,
25+
);
26+
}
27+
return documentID;
28+
}
29+
export function createUrlID(baseURL: string, documentID: string): UrlID {
30+
return `${baseURL}/d/${documentID}`;
31+
}
932

1033
interface FrontMatterMetadata {
1134
title?: string;
1235
// Allows custom display modes. Currently used for compact mode in gantt charts.
1336
displayMode?: string;
1437
config?: Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
15-
/** Unique ID for the diagram on MermaidChart.com */
16-
id?: string;
38+
/** Unique ID for the diagram, e.g. `https://www.mermaidchart.com/d/xxxxxx-xxxx-xxxxx` */
39+
id?: UrlID;
1740
}
1841

1942
export interface FrontMatterResult {

‎packages/cli/src/methods.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import type { MermaidChart } from '@mermaidchart/sdk';
22

33
import { CommanderError } from '@commander-js/extra-typings';
4-
import { extractFrontMatter, injectFrontMatter, removeFrontMatterKeys } from './frontmatter.js';
4+
import {
5+
createUrlID,
6+
extractFrontMatter,
7+
getDocumentID,
8+
injectFrontMatter,
9+
removeFrontMatterKeys,
10+
} from './frontmatter.js';
511

612
/**
713
* Cached data to use when pulling/pushing/linking multiple files at once.
@@ -81,7 +87,9 @@ export async function link(
8187
code: diagram,
8288
});
8389

84-
const diagramWithId = injectFrontMatter(diagram, { id: createdDocument.documentID });
90+
const diagramWithId = injectFrontMatter(diagram, {
91+
id: createUrlID(client.baseURL, createdDocument.documentID),
92+
});
8593

8694
return diagramWithId;
8795
}
@@ -103,7 +111,7 @@ export async function pull(diagram: string, client: MermaidChart, { title }: Pul
103111
}
104112

105113
const uploadedFile = await client.getDocument({
106-
documentID: frontmatter.metadata.id,
114+
documentID: getDocumentID(frontmatter.metadata.id, client.baseURL),
107115
});
108116

109117
if (uploadedFile.code === undefined) {
@@ -129,7 +137,7 @@ export async function push(diagram: string, client: MermaidChart, { title }: Pus
129137

130138
// TODO: check if file has changed since last push and print a warning
131139
const existingDiagram = await client.getDocument({
132-
documentID: frontmatter.metadata.id,
140+
documentID: getDocumentID(frontmatter.metadata.id, client.baseURL),
133141
});
134142

135143
// due to MC-1056, try to remove YAML frontmatter if we can
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: My cool flowchart
3-
id: my-test-document-id
3+
id: https://test.mermaidchart.invalid/d/my-test-document-id
44
---
55
flowchart TD
66
A[Needs Update]

‎packages/cli/test/fixtures/linked-markdown-file.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This is a flowchart diagram
66

77
```mermaid
88
---
9-
id: xxxxxxx-flowchart
9+
id: https://test.mermaidchart.invalid/d/xxxxxxx-flowchart
1010
---
1111
flowchart
1212
A[Hello World]
@@ -16,7 +16,7 @@ While this is a pie diagram
1616

1717
```mermaid
1818
---
19-
id: xxxxxxx-pie
19+
id: https://test.mermaidchart.invalid/d/xxxxxxx-pie
2020
---
2121
pie
2222
"Flowchart" : 1

‎packages/cli/test/fixtures/partially-linked-markdown-file.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This is a journey diagram that is already linked.
66

77
```mermaid
88
---
9-
id: xxxxxxx-journey
9+
id: https://test.mermaidchart.invalid/d/xxxxxxx-journey
1010
---
1111
journey
1212
title This is a linked journey diagram.

0 commit comments

Comments
 (0)
Failed to load comments.