docs(core): fix relative image paths (#5635)
This commit is contained in:
parent
0bd6deaa65
commit
6db97832e6
@ -1,5 +1,5 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { join, relative } from 'path';
|
||||
import matter from 'gray-matter';
|
||||
import { readJsonFile } from '@nrwl/workspace';
|
||||
import {
|
||||
@ -29,7 +29,10 @@ export function getDocument(
|
||||
}
|
||||
|
||||
return {
|
||||
filePath: docPath,
|
||||
filePath: relative(
|
||||
version === 'preview' ? previewRootPath : archiveRootPath,
|
||||
docPath
|
||||
),
|
||||
data: file.data,
|
||||
content: file.content,
|
||||
excerpt: file.excerpt,
|
||||
|
||||
@ -5,7 +5,18 @@ import Content from './content';
|
||||
|
||||
describe('Content', () => {
|
||||
it('should render successfully', () => {
|
||||
const { baseElement } = render(<Content data="hello" />);
|
||||
const { baseElement } = render(
|
||||
<Content
|
||||
version="1.0.0"
|
||||
flavor="react"
|
||||
document={{
|
||||
content: '',
|
||||
data: {},
|
||||
filePath: 'a/b/test.md',
|
||||
excerpt: '',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(baseElement).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@ -3,6 +3,7 @@ import ReactMarkdown from 'react-markdown';
|
||||
import autolinkHeadings from 'rehype-autolink-headings';
|
||||
import gfm from 'remark-gfm';
|
||||
import slug from 'rehype-slug';
|
||||
import { DocumentData } from '@nrwl/nx-dev/data-access-documents';
|
||||
|
||||
import { transformLinkPath } from './renderers/transform-link-path';
|
||||
import { transformImagePath } from './renderers/transform-image-path';
|
||||
@ -10,7 +11,7 @@ import { renderIframes } from './renderers/render-iframe';
|
||||
import { CodeBlock } from './code-block';
|
||||
|
||||
export interface ContentProps {
|
||||
data: string;
|
||||
document: DocumentData;
|
||||
flavor: string;
|
||||
version: string;
|
||||
}
|
||||
@ -41,12 +42,15 @@ export function Content(props: ContentProps) {
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[gfm]}
|
||||
rehypePlugins={[slug, autolinkHeadings, renderIframes]}
|
||||
children={props.data}
|
||||
children={props.document.content}
|
||||
transformLinkUri={transformLinkPath({
|
||||
flavor: props.flavor,
|
||||
version: props.version,
|
||||
})}
|
||||
transformImageUri={transformImagePath(props.version)}
|
||||
transformImageUri={transformImagePath({
|
||||
version: props.version,
|
||||
document: props.document,
|
||||
})}
|
||||
className="prose max-w-none"
|
||||
components={components}
|
||||
/>
|
||||
|
||||
@ -48,7 +48,7 @@ export function DocViewer({
|
||||
className="min-w-0 w-full flex-auto lg:static lg:max-h-full lg:overflow-visible"
|
||||
>
|
||||
<Content
|
||||
data={document.content}
|
||||
document={document}
|
||||
flavor={flavor.value}
|
||||
version={version.path}
|
||||
/>
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
import { transformImagePath } from './transform-image-path';
|
||||
|
||||
describe('transformImagePath', () => {
|
||||
it('should transform relative paths', () => {
|
||||
const opts = {
|
||||
version: '1.0.0',
|
||||
document: { content: '', excerpt: '', filePath: 'a/b/test.md', data: {} },
|
||||
};
|
||||
const transform = transformImagePath(opts);
|
||||
|
||||
expect(transform('./test.png')).toEqual('/documentation/a/b/test.png');
|
||||
expect(transform('../test.png')).toEqual('/documentation/a/test.png');
|
||||
expect(transform('../../test.png')).toEqual('/documentation/test.png');
|
||||
});
|
||||
|
||||
it('should transform absolute paths', () => {
|
||||
const opts = {
|
||||
version: '1.0.0',
|
||||
document: { content: '', excerpt: '', filePath: 'a/b/test.md', data: {} },
|
||||
};
|
||||
const transform = transformImagePath(opts);
|
||||
|
||||
expect(transform('/shared/test.png')).toEqual(
|
||||
'/documentation/1.0.0/shared/test.png'
|
||||
);
|
||||
});
|
||||
|
||||
it('should support preview links', () => {
|
||||
const opts = {
|
||||
version: 'preview',
|
||||
document: { content: '', excerpt: '', filePath: 'a/b/test.md', data: {} },
|
||||
};
|
||||
const transform = transformImagePath(opts);
|
||||
|
||||
expect(transform('/shared/test.png')).toEqual(
|
||||
'/api/preview-asset?uri=%2Fshared%2Ftest.png&document=a%2Fb%2Ftest.md'
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,12 +1,26 @@
|
||||
import { uriTransformer } from 'react-markdown';
|
||||
import { DocumentData } from '@nrwl/nx-dev/data-access-documents';
|
||||
import { join } from 'path';
|
||||
|
||||
export function transformImagePath(version: string): (src: string) => string {
|
||||
export function transformImagePath({
|
||||
version,
|
||||
document,
|
||||
}: {
|
||||
version: string;
|
||||
document: DocumentData;
|
||||
}): (src: string) => string {
|
||||
return (src) => {
|
||||
if (/\.(gif|jpe?g|tiff?|png|webp|bmp)$/i.test(src)) {
|
||||
if (version === 'preview') {
|
||||
src = `/api/preview-asset?uri=${encodeURIComponent(src)}`;
|
||||
src = `/api/preview-asset?uri=${encodeURIComponent(
|
||||
src
|
||||
)}&document=${encodeURIComponent(document.filePath)}`;
|
||||
} else {
|
||||
src = `/documentation/${version}`.concat(src);
|
||||
if (src.startsWith('.')) {
|
||||
src = join('/documentation', document.filePath, '..', src);
|
||||
} else {
|
||||
src = `/documentation/${version}`.concat(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
return uriTransformer(src);
|
||||
|
||||
@ -8,12 +8,15 @@ import * as send from 'send';
|
||||
const previewRootPath = join(appRootPath, 'docs');
|
||||
|
||||
export default function (req: NextApiRequest, res: NextApiResponse) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
if (Array.isArray(req.query.uri)) {
|
||||
return new Promise<void>((resolve) => {
|
||||
if (Array.isArray(req.query.uri) || Array.isArray(req.query.document)) {
|
||||
res.writeHead(422, { 'Content-Type': 'text/plain' });
|
||||
res.end('Invalid URI');
|
||||
} else {
|
||||
const stream = send(req, decodeURIComponent(req.query.uri), {
|
||||
const uri = decodeURIComponent(req.query.uri);
|
||||
const document = decodeURIComponent(req.query.document);
|
||||
const src = uri.startsWith('.') ? join(document, '..', uri) : uri;
|
||||
const stream = send(req, src, {
|
||||
// Files outside of the root are forbidden and will result in 404.
|
||||
root: previewRootPath,
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user