docs(core): fix 500 error when directing from framework specific pages to intro page (#6492)
This commit is contained in:
parent
0bacdf3181
commit
59fa59fddc
@ -8,6 +8,10 @@ import {
|
||||
VersionMetadata,
|
||||
} from './documents.models';
|
||||
|
||||
export interface StaticDocumentPaths {
|
||||
params: { segments: string[] };
|
||||
}
|
||||
|
||||
export const flavorList: {
|
||||
label: string;
|
||||
value: string;
|
||||
@ -26,10 +30,16 @@ export class DocumentsApi {
|
||||
versions: VersionMetadata[];
|
||||
documentsMap: Map<string, DocumentMetadata[]>;
|
||||
}
|
||||
) {}
|
||||
) {
|
||||
if (!options.archiveRoot || !options.previewRoot) {
|
||||
throw new Error('archive and preview roots cannot be undefined');
|
||||
}
|
||||
}
|
||||
|
||||
getDefaultVersion(): VersionMetadata {
|
||||
return this.options.versions.find((v) => v.default);
|
||||
const found = this.options.versions.find((v) => v.default);
|
||||
if (found) return found;
|
||||
throw new Error('Cannot find default version');
|
||||
}
|
||||
|
||||
getVersions(): VersionMetadata[] {
|
||||
@ -72,8 +82,8 @@ export class DocumentsApi {
|
||||
}
|
||||
}
|
||||
|
||||
getStaticDocumentPaths(version: string) {
|
||||
const paths = [];
|
||||
getStaticDocumentPaths(version: string): StaticDocumentPaths[] {
|
||||
const paths: StaticDocumentPaths[] = [];
|
||||
const defaultVersion = this.getDefaultVersion();
|
||||
|
||||
function recur(curr, acc) {
|
||||
@ -111,11 +121,12 @@ export class DocumentsApi {
|
||||
return this.options.previewRoot;
|
||||
}
|
||||
|
||||
if (version === 'latest' || version === 'previous') {
|
||||
return join(
|
||||
this.options.archiveRoot,
|
||||
this.options.versions.find((x) => x.id === version).path
|
||||
);
|
||||
const versionPath = this.options.versions.find(
|
||||
(x) => x.id === version
|
||||
)?.path;
|
||||
|
||||
if (versionPath) {
|
||||
return join(this.options.archiveRoot, versionPath);
|
||||
}
|
||||
|
||||
throw new Error(`Cannot find root for ${version}`);
|
||||
@ -132,7 +143,7 @@ export class DocumentsApi {
|
||||
|
||||
let found;
|
||||
for (const part of path) {
|
||||
found = items.find((item) => item.id === part);
|
||||
found = items?.find((item) => item.id === part);
|
||||
if (found) {
|
||||
items = found.itemList;
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
export function extractTitle(markdownContent: string): string | null {
|
||||
return (
|
||||
/^\s*#\s+(?<title>.+)[\n.]+/.exec(markdownContent)?.groups.title ?? null
|
||||
/^\s*#\s+(?<title>.+)[\n.]+/.exec(markdownContent)?.groups?.title ?? null
|
||||
);
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ describe('MenuApi', () => {
|
||||
|
||||
// first basic section item should have prefix by version and flavor
|
||||
// e.g. "latest/react/getting-started/intro"
|
||||
expect(menu.sections[0].itemList[0].itemList[0].path).toMatch(
|
||||
expect(menu?.sections?.[0]?.itemList?.[0]?.itemList?.[0].path).toMatch(
|
||||
/latest\/react/
|
||||
);
|
||||
});
|
||||
|
||||
@ -23,12 +23,14 @@ export function createMenuItems(
|
||||
return pathData;
|
||||
};
|
||||
|
||||
return items.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
itemList: item.itemList?.map((ii) => createPathMetadata(ii, item.id)),
|
||||
};
|
||||
});
|
||||
return (
|
||||
items?.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
itemList: item.itemList?.map((ii) => createPathMetadata(ii, item.id)),
|
||||
};
|
||||
}) ?? []
|
||||
);
|
||||
}
|
||||
|
||||
export function getBasicSection(items: MenuItem[]): MenuSection {
|
||||
@ -73,7 +75,7 @@ export function getDeepDiveSection(items: MenuItem[]): MenuSection {
|
||||
.map((m) => ({
|
||||
...m,
|
||||
disableCollapsible: true,
|
||||
itemList: m.itemList.map((item) => ({
|
||||
itemList: m.itemList?.map((item) => ({
|
||||
...item,
|
||||
disableCollapsible: true,
|
||||
})),
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"strictNullChecks": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"strictNullChecks": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"files": [],
|
||||
|
||||
@ -7,6 +7,8 @@ describe('Content', () => {
|
||||
it('should render successfully', () => {
|
||||
const { baseElement } = render(
|
||||
<Content
|
||||
versionList={[]}
|
||||
flavorList={[]}
|
||||
version="1.0.0"
|
||||
flavor="react"
|
||||
document={{
|
||||
|
||||
@ -17,7 +17,7 @@ export interface DocumentationFeatureDocViewerProps {
|
||||
menu: Menu;
|
||||
document: DocumentData;
|
||||
toc: any;
|
||||
navIsOpen: boolean;
|
||||
navIsOpen?: boolean;
|
||||
}
|
||||
|
||||
export function DocViewer({
|
||||
|
||||
@ -16,7 +16,7 @@ export interface SidebarProps {
|
||||
versionList: VersionMetadata[];
|
||||
flavorList: any[];
|
||||
flavor: any;
|
||||
navIsOpen: boolean;
|
||||
navIsOpen?: boolean;
|
||||
}
|
||||
|
||||
// Exported for testing
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"jsx": "react",
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"strictNullChecks": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"files": [],
|
||||
|
||||
@ -26,7 +26,7 @@ export function AlgoliaSearch({ flavorId, versionId }: AlgoliaSearchProps) {
|
||||
|
||||
const router = useRouter();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const searchButtonRef = useRef();
|
||||
const searchButtonRef = useRef<HTMLButtonElement>(null);
|
||||
const [initialQuery, setInitialQuery] = useState(null);
|
||||
const [browserDetected, setBrowserDetected] = useState(false);
|
||||
const [actionKey, setActionKey] = useState(ACTION_KEY_DEFAULT);
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"strictNullChecks": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"files": [],
|
||||
|
||||
@ -5,7 +5,7 @@ const isServer = typeof window === 'undefined';
|
||||
export function useStorage(key: string) {
|
||||
const initialValue = isServer ? undefined : window.localStorage.getItem(key);
|
||||
|
||||
const [value, _setValue] = useState<string>(initialValue);
|
||||
const [value, _setValue] = useState<string>(initialValue ?? '');
|
||||
|
||||
const setValue = (newValue: string) => {
|
||||
if (newValue !== value && !isServer) {
|
||||
|
||||
@ -17,8 +17,11 @@ import { documentsApi, menuApi } from '../lib/api';
|
||||
import { useStorage } from '../lib/use-storage';
|
||||
|
||||
const versionList = documentsApi.getVersions();
|
||||
const defaultVersion = versionList.find((v) => v.default);
|
||||
const defaultFlavor = flavorList.find((f) => f.default);
|
||||
const defaultVersion = versionList.find((v) => v.default) as VersionMetadata;
|
||||
const defaultFlavor = flavorList.find((f) => f.default) as {
|
||||
value: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
interface DocumentationPageProps {
|
||||
version: VersionMetadata;
|
||||
@ -277,12 +280,16 @@ function findDocumentAndMenu(
|
||||
version: VersionMetadata,
|
||||
flavor: { label: string; value: string },
|
||||
segments: string[]
|
||||
): { menu?: Menu; document?: DocumentData; isFallback?: boolean } {
|
||||
): {
|
||||
menu: undefined | Menu;
|
||||
document: undefined | DocumentData;
|
||||
isFallback?: boolean;
|
||||
} {
|
||||
const isFallback = segments[0] !== version.id;
|
||||
const path = isFallback ? segments : segments.slice(2);
|
||||
|
||||
let menu: Menu;
|
||||
let document: DocumentData;
|
||||
let menu: undefined | Menu = undefined;
|
||||
let document: undefined | DocumentData = undefined;
|
||||
|
||||
try {
|
||||
menu = menuApi.getMenu(version.id, flavor.value);
|
||||
|
||||
@ -9,7 +9,8 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true
|
||||
"isolatedModules": true,
|
||||
"strictNullChecks": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
|
||||
@ -2,7 +2,7 @@ import cx from 'classnames';
|
||||
import Link from 'next/link';
|
||||
|
||||
export interface FooterProps {
|
||||
useDarkBackground: boolean;
|
||||
useDarkBackground?: boolean;
|
||||
}
|
||||
export function Footer({ useDarkBackground }: FooterProps) {
|
||||
return (
|
||||
|
||||
@ -4,12 +4,12 @@ import { AlgoliaSearch } from '@nrwl/nx-dev/feature-search';
|
||||
|
||||
interface HeaderPropsWithoutFlavorAndVersion {
|
||||
showSearch: false;
|
||||
useDarkBackground: boolean;
|
||||
useDarkBackground?: boolean;
|
||||
}
|
||||
|
||||
interface HeaderPropsWithFlavorAndVersion {
|
||||
showSearch: boolean;
|
||||
useDarkBackground: boolean;
|
||||
useDarkBackground?: boolean;
|
||||
flavor: { name: string; value: string };
|
||||
version: { name: string; value: string };
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"strictNullChecks": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"files": [],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user