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