From 5602309936c1dbfefcb0512aa589de38723286a4 Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Tue, 9 Apr 2024 20:21:55 +0900 Subject: [PATCH] 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. --- packages/cli/README.md | 2 +- packages/cli/src/commander.test.ts | 18 ++++++++----- packages/cli/src/frontmatter.ts | 27 +++++++++++++++++-- packages/cli/src/methods.ts | 16 ++++++++--- .../cli/test/fixtures/connected-diagram.mmd | 2 +- .../cli/test/fixtures/linked-markdown-file.md | 4 +-- .../partially-linked-markdown-file.md | 2 +- 7 files changed, 53 insertions(+), 18 deletions(-) diff --git a/packages/cli/README.md b/packages/cli/README.md index 45b18d6..fcbf514 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -57,7 +57,7 @@ which points to the diagram on MermaidChart.com: ```mermaid --- title: My diagram -id: xxxx-xxxxx-xxxxx # this field is created by @mermaidchart/cli +id: https://www.mermaidchart.com/d/xxxx-xxxxx-xxxxx # this field is created by @mermaidchart/cli --- flowchart x[My Diagram] diff --git a/packages/cli/src/commander.test.ts b/packages/cli/src/commander.test.ts index 33a2f1d..c1b9fba 100644 --- a/packages/cli/src/commander.test.ts +++ b/packages/cli/src/commander.test.ts @@ -226,7 +226,7 @@ describe('link', () => { ); await expect(readFile(diagram, { encoding: 'utf8' })).resolves.toContain( - `id: ${mockedEmptyDiagram.documentID}`, + `id: https://test.mermaidchart.invalid/d/${mockedEmptyDiagram.documentID}`, ); }); @@ -271,7 +271,7 @@ describe('link', () => { await Promise.all( [diagram, diagram2, diagram3].map(async (file) => { await expect(readFile(file, { encoding: 'utf8' })).resolves.toContain( - `id: ${mockedEmptyDiagram.documentID}`, + `id: https://test.mermaidchart.invalid/d/${mockedEmptyDiagram.documentID}`, ); }), ); @@ -298,8 +298,10 @@ describe('link', () => { const file = await readFile(unlinkedMarkdownFile, { encoding: 'utf8' }); - expect(file).toMatch(`id: ${mockedEmptyDiagram.documentID}\n`); - expect(file).toMatch(`id: second-id\n`); + expect(file).toMatch( + `id: https://test.mermaidchart.invalid/d/${mockedEmptyDiagram.documentID}\n`, + ); + expect(file).toMatch(`id: https://test.mermaidchart.invalid/d/second-id\n`); }); it('should link diagrams in partially linked markdown file', async () => { @@ -323,7 +325,7 @@ describe('link', () => { const file = await readFile(partiallyLinkedMarkdownFile, { encoding: 'utf8' }); - expect(file).toMatch(`id: second-id\n`); + expect(file).toMatch(`id: https://test.mermaidchart.invalid/d/second-id\n`); }); it('should handle unusual markdown formatting', async () => { @@ -347,7 +349,7 @@ describe('link', () => { const file = await readFile(unusualMarkdownFile, { encoding: 'utf8' }); - const idLineRegex = /^.*id: my-mocked-diagram-id\n/gm; + const idLineRegex = /^.*id: https:\/\/test.mermaidchart.invalid\/d\/my-mocked-diagram-id\n/gm; expect(file).toMatch(idLineRegex); // other than the added `id: xxxx` field, everything else should be identical, @@ -412,7 +414,9 @@ title: My cool flowchart for (const file of [diagram, diagram2]) { const diagramContents = await readFile(file, { encoding: 'utf8' }); - expect(diagramContents).toContain(`id: ${mockedDiagram.documentID}`); + expect(diagramContents).toContain( + `id: https://test.mermaidchart.invalid/d/${mockedDiagram.documentID}`, + ); expect(diagramContents).toContain("flowchart TD\n A[I've been updated!]"); } }); diff --git a/packages/cli/src/frontmatter.ts b/packages/cli/src/frontmatter.ts index 967bfdf..6cb6f02 100644 --- a/packages/cli/src/frontmatter.ts +++ b/packages/cli/src/frontmatter.ts @@ -6,14 +6,37 @@ import * as yaml from 'js-yaml'; const frontMatterRegex = /^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s; +const urlIDRegex = /(?.*)\/d\/(?[\w-]+)/; + +type UrlID = `${string}/d/${string}`; + +export function getDocumentID(urlID: UrlID, expectedbaseURL: string) { + const match = urlID.match(urlIDRegex); + if (match === null) { + throw new Error( + `Invalid document ID: ${urlID}. Please report this issue to the @mermaidchart/cli maintainers.`, + ); + } + // we know that this regex will always return groups on a match + const { baseURL, documentID } = match.groups as { baseURL: string; documentID: string }; + if (baseURL !== expectedbaseURL) { + throw new Error( + `Your @mermaidchart/cli is configured to use ${expectedbaseURL}, but your diagram is using ${baseURL}`, + ); + } + return documentID; +} +export function createUrlID(baseURL: string, documentID: string): UrlID { + return `${baseURL}/d/${documentID}`; +} interface FrontMatterMetadata { title?: string; // Allows custom display modes. Currently used for compact mode in gantt charts. displayMode?: string; config?: Record; // eslint-disable-line @typescript-eslint/no-explicit-any - /** Unique ID for the diagram on MermaidChart.com */ - id?: string; + /** Unique ID for the diagram, e.g. `https://www.mermaidchart.com/d/xxxxxx-xxxx-xxxxx` */ + id?: UrlID; } export interface FrontMatterResult { diff --git a/packages/cli/src/methods.ts b/packages/cli/src/methods.ts index 5d86b9c..e0aeea0 100644 --- a/packages/cli/src/methods.ts +++ b/packages/cli/src/methods.ts @@ -1,7 +1,13 @@ import type { MermaidChart } from '@mermaidchart/sdk'; import { CommanderError } from '@commander-js/extra-typings'; -import { extractFrontMatter, injectFrontMatter, removeFrontMatterKeys } from './frontmatter.js'; +import { + createUrlID, + extractFrontMatter, + getDocumentID, + injectFrontMatter, + removeFrontMatterKeys, +} from './frontmatter.js'; /** * Cached data to use when pulling/pushing/linking multiple files at once. @@ -81,7 +87,9 @@ export async function link( code: diagram, }); - const diagramWithId = injectFrontMatter(diagram, { id: createdDocument.documentID }); + const diagramWithId = injectFrontMatter(diagram, { + id: createUrlID(client.baseURL, createdDocument.documentID), + }); return diagramWithId; } @@ -103,7 +111,7 @@ export async function pull(diagram: string, client: MermaidChart, { title }: Pul } const uploadedFile = await client.getDocument({ - documentID: frontmatter.metadata.id, + documentID: getDocumentID(frontmatter.metadata.id, client.baseURL), }); if (uploadedFile.code === undefined) { @@ -129,7 +137,7 @@ export async function push(diagram: string, client: MermaidChart, { title }: Pus // TODO: check if file has changed since last push and print a warning const existingDiagram = await client.getDocument({ - documentID: frontmatter.metadata.id, + documentID: getDocumentID(frontmatter.metadata.id, client.baseURL), }); // due to MC-1056, try to remove YAML frontmatter if we can diff --git a/packages/cli/test/fixtures/connected-diagram.mmd b/packages/cli/test/fixtures/connected-diagram.mmd index cf32b98..266c594 100644 --- a/packages/cli/test/fixtures/connected-diagram.mmd +++ b/packages/cli/test/fixtures/connected-diagram.mmd @@ -1,6 +1,6 @@ --- title: My cool flowchart -id: my-test-document-id +id: https://test.mermaidchart.invalid/d/my-test-document-id --- flowchart TD A[Needs Update] diff --git a/packages/cli/test/fixtures/linked-markdown-file.md b/packages/cli/test/fixtures/linked-markdown-file.md index e777905..0433854 100644 --- a/packages/cli/test/fixtures/linked-markdown-file.md +++ b/packages/cli/test/fixtures/linked-markdown-file.md @@ -6,7 +6,7 @@ This is a flowchart diagram ```mermaid --- -id: xxxxxxx-flowchart +id: https://test.mermaidchart.invalid/d/xxxxxxx-flowchart --- flowchart A[Hello World] @@ -16,7 +16,7 @@ While this is a pie diagram ```mermaid --- -id: xxxxxxx-pie +id: https://test.mermaidchart.invalid/d/xxxxxxx-pie --- pie "Flowchart" : 1 diff --git a/packages/cli/test/fixtures/partially-linked-markdown-file.md b/packages/cli/test/fixtures/partially-linked-markdown-file.md index 51ea585..60e3383 100644 --- a/packages/cli/test/fixtures/partially-linked-markdown-file.md +++ b/packages/cli/test/fixtures/partially-linked-markdown-file.md @@ -6,7 +6,7 @@ This is a journey diagram that is already linked. ```mermaid --- -id: xxxxxxx-journey +id: https://test.mermaidchart.invalid/d/xxxxxxx-journey --- journey title This is a linked journey diagram.