Skip to content

Commit 0e3299b

Browse files
authored
Merge pull request #20 from Mermaid-Chart/feat/use-a-url-id-for-frontmatter
feat(cli)!: use a URL id in the frontmatter
2 parents aa9fbd7 + 5602309 commit 0e3299b

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)