Skip to content

Commit

Permalink
refactor: fix mermaid in production (#6149)
Browse files Browse the repository at this point in the history
Use dynamic CDN import to use Mermaid as Parcel has issues on handling the
static import in production.
  • Loading branch information
gao-sun authored Jul 1, 2024
1 parent 88dd7d2 commit dd69c1c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 20 deletions.
34 changes: 20 additions & 14 deletions packages/console/src/mdx-components/Mermaid/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { Theme } from '@logto/schemas';
import mermaid from 'mermaid';
import { type Mermaid as MermaidType } from 'mermaid';
import { useEffect } from 'react';

import useTheme from '@/hooks/use-theme';

mermaid.initialize({
startOnLoad: true,
theme: 'default',
securityLevel: 'loose',
fontFamily: 'Fira Code',
});
const loadMermaid = async () => {
// Define this variable to "outsmart" the detection of the dynamic import by Parcel:
// https://github.com/parcel-bundler/parcel/issues/7064#issuecomment-942441649
const uri = 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const imported: { default: MermaidType } = await import(uri);
return imported.default;
};

const mermaidPromise = loadMermaid();

type Props = {
readonly children: string;
Expand All @@ -24,14 +28,16 @@ export default function Mermaid({ children }: Props) {
const theme = useTheme();

useEffect(() => {
mermaid.initialize({
theme: themeToMermaidTheme[theme],
});
(async () => {
const mermaid = await mermaidPromise;
mermaid.initialize({
startOnLoad: false,
theme: themeToMermaidTheme[theme],
securityLevel: 'loose',
});
await mermaid.run();
})();
}, [theme]);

useEffect(() => {
mermaid.contentLoaded();
}, []);

return <div className="mermaid">{children}</div>;
}
15 changes: 9 additions & 6 deletions packages/core/src/middleware/koa-security-headers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@ export default function koaSecurityHeaders<StateT, ContextT, ResponseBodyT>(
/** Google Sign-In (GSI) origin for Google One Tap. */
const gsiOrigin = 'https://accounts.google.com/gsi/';

// We use react-monaco-editor for code editing in the admin console. It loads the monaco editor asynchronously from a CDN.
// We have the following use cases:
//
// 1. We use `react-monaco-editor` for code editing in the admin console. It loads the monaco
// editor asynchronously from jsDelivr.
// 2. We use `mermaid` for rendering diagrams in the admin console. It loads the mermaid library
// asynchronously from jsDelivr since Parcel has issues with loading it directly in production.
//
// Allow the CDN src in the CSP.
// Allow blob: for monaco editor to load worker scripts
const monacoEditorCDNSource = [
'https://cdn.jsdelivr.net/npm/[email protected]/min/vs/',
'blob:',
];
const cdnSources = ['https://cdn.jsdelivr.net/', 'blob:'];

/**
* Default Applied rules:
Expand Down Expand Up @@ -122,7 +125,7 @@ export default function koaSecurityHeaders<StateT, ContextT, ResponseBodyT>(
scriptSrc: [
"'self'",
...conditionalArray(!isProduction && ["'unsafe-eval'", "'unsafe-inline'"]),
...monacoEditorCDNSource,
...cdnSources,
],
connectSrc: ["'self'", logtoOrigin, ...adminOrigins, ...coreOrigins, ...developmentOrigins],
// Allow Main Flow origin loaded in preview iframe
Expand Down

0 comments on commit dd69c1c

Please sign in to comment.