docs(core): fix 500 error when directing from framework specific pages to intro page (#6492)

This commit is contained in:
Jack Hsu 2021-07-23 10:49:20 -04:00 committed by GitHub
parent 0bacdf3181
commit 59fa59fddc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 62 additions and 32 deletions

View File

@ -8,6 +8,10 @@ import {
VersionMetadata, VersionMetadata,
} from './documents.models'; } from './documents.models';
export interface StaticDocumentPaths {
params: { segments: string[] };
}
export const flavorList: { export const flavorList: {
label: string; label: string;
value: string; value: string;
@ -26,10 +30,16 @@ export class DocumentsApi {
versions: VersionMetadata[]; versions: VersionMetadata[];
documentsMap: Map<string, DocumentMetadata[]>; documentsMap: Map<string, DocumentMetadata[]>;
} }
) {} ) {
if (!options.archiveRoot || !options.previewRoot) {
throw new Error('archive and preview roots cannot be undefined');
}
}
getDefaultVersion(): VersionMetadata { 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[] { getVersions(): VersionMetadata[] {
@ -72,8 +82,8 @@ export class DocumentsApi {
} }
} }
getStaticDocumentPaths(version: string) { getStaticDocumentPaths(version: string): StaticDocumentPaths[] {
const paths = []; const paths: StaticDocumentPaths[] = [];
const defaultVersion = this.getDefaultVersion(); const defaultVersion = this.getDefaultVersion();
function recur(curr, acc) { function recur(curr, acc) {
@ -111,11 +121,12 @@ export class DocumentsApi {
return this.options.previewRoot; return this.options.previewRoot;
} }
if (version === 'latest' || version === 'previous') { const versionPath = this.options.versions.find(
return join( (x) => x.id === version
this.options.archiveRoot, )?.path;
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}`); throw new Error(`Cannot find root for ${version}`);
@ -132,7 +143,7 @@ export class DocumentsApi {
let found; let found;
for (const part of path) { for (const part of path) {
found = items.find((item) => item.id === part); found = items?.find((item) => item.id === part);
if (found) { if (found) {
items = found.itemList; items = found.itemList;
} else { } else {

View File

@ -1,5 +1,5 @@
export function extractTitle(markdownContent: string): string | null { export function extractTitle(markdownContent: string): string | null {
return ( return (
/^\s*#\s+(?<title>.+)[\n.]+/.exec(markdownContent)?.groups.title ?? null /^\s*#\s+(?<title>.+)[\n.]+/.exec(markdownContent)?.groups?.title ?? null
); );
} }

View File

@ -29,7 +29,7 @@ describe('MenuApi', () => {
// first basic section item should have prefix by version and flavor // first basic section item should have prefix by version and flavor
// e.g. "latest/react/getting-started/intro" // 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/ /latest\/react/
); );
}); });

View File

@ -23,12 +23,14 @@ export function createMenuItems(
return pathData; return pathData;
}; };
return items.map((item) => { return (
return { items?.map((item) => {
...item, return {
itemList: item.itemList?.map((ii) => createPathMetadata(ii, item.id)), ...item,
}; itemList: item.itemList?.map((ii) => createPathMetadata(ii, item.id)),
}); };
}) ?? []
);
} }
export function getBasicSection(items: MenuItem[]): MenuSection { export function getBasicSection(items: MenuItem[]): MenuSection {
@ -73,7 +75,7 @@ export function getDeepDiveSection(items: MenuItem[]): MenuSection {
.map((m) => ({ .map((m) => ({
...m, ...m,
disableCollapsible: true, disableCollapsible: true,
itemList: m.itemList.map((item) => ({ itemList: m.itemList?.map((item) => ({
...item, ...item,
disableCollapsible: true, disableCollapsible: true,
})), })),

View File

@ -1,5 +1,8 @@
{ {
"extends": "../../tsconfig.base.json", "extends": "../../tsconfig.base.json",
"compilerOptions": {
"strictNullChecks": true
},
"files": [], "files": [],
"include": [], "include": [],
"references": [ "references": [

View File

@ -4,6 +4,7 @@
"jsx": "react-jsx", "jsx": "react-jsx",
"allowJs": true, "allowJs": true,
"esModuleInterop": true, "esModuleInterop": true,
"strictNullChecks": true,
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true
}, },
"files": [], "files": [],

View File

@ -7,6 +7,8 @@ describe('Content', () => {
it('should render successfully', () => { it('should render successfully', () => {
const { baseElement } = render( const { baseElement } = render(
<Content <Content
versionList={[]}
flavorList={[]}
version="1.0.0" version="1.0.0"
flavor="react" flavor="react"
document={{ document={{

View File

@ -17,7 +17,7 @@ export interface DocumentationFeatureDocViewerProps {
menu: Menu; menu: Menu;
document: DocumentData; document: DocumentData;
toc: any; toc: any;
navIsOpen: boolean; navIsOpen?: boolean;
} }
export function DocViewer({ export function DocViewer({

View File

@ -16,7 +16,7 @@ export interface SidebarProps {
versionList: VersionMetadata[]; versionList: VersionMetadata[];
flavorList: any[]; flavorList: any[];
flavor: any; flavor: any;
navIsOpen: boolean; navIsOpen?: boolean;
} }
// Exported for testing // Exported for testing

View File

@ -4,6 +4,7 @@
"jsx": "react", "jsx": "react",
"allowJs": true, "allowJs": true,
"esModuleInterop": true, "esModuleInterop": true,
"strictNullChecks": true,
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true
}, },
"files": [], "files": [],

View File

@ -26,7 +26,7 @@ export function AlgoliaSearch({ flavorId, versionId }: AlgoliaSearchProps) {
const router = useRouter(); const router = useRouter();
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const searchButtonRef = useRef(); const searchButtonRef = useRef<HTMLButtonElement>(null);
const [initialQuery, setInitialQuery] = useState(null); const [initialQuery, setInitialQuery] = useState(null);
const [browserDetected, setBrowserDetected] = useState(false); const [browserDetected, setBrowserDetected] = useState(false);
const [actionKey, setActionKey] = useState(ACTION_KEY_DEFAULT); const [actionKey, setActionKey] = useState(ACTION_KEY_DEFAULT);

View File

@ -4,6 +4,7 @@
"jsx": "react-jsx", "jsx": "react-jsx",
"allowJs": true, "allowJs": true,
"esModuleInterop": true, "esModuleInterop": true,
"strictNullChecks": true,
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true
}, },
"files": [], "files": [],

View File

@ -5,7 +5,7 @@ const isServer = typeof window === 'undefined';
export function useStorage(key: string) { export function useStorage(key: string) {
const initialValue = isServer ? undefined : window.localStorage.getItem(key); const initialValue = isServer ? undefined : window.localStorage.getItem(key);
const [value, _setValue] = useState<string>(initialValue); const [value, _setValue] = useState<string>(initialValue ?? '');
const setValue = (newValue: string) => { const setValue = (newValue: string) => {
if (newValue !== value && !isServer) { if (newValue !== value && !isServer) {

View File

@ -17,8 +17,11 @@ import { documentsApi, menuApi } from '../lib/api';
import { useStorage } from '../lib/use-storage'; import { useStorage } from '../lib/use-storage';
const versionList = documentsApi.getVersions(); const versionList = documentsApi.getVersions();
const defaultVersion = versionList.find((v) => v.default); const defaultVersion = versionList.find((v) => v.default) as VersionMetadata;
const defaultFlavor = flavorList.find((f) => f.default); const defaultFlavor = flavorList.find((f) => f.default) as {
value: string;
label: string;
};
interface DocumentationPageProps { interface DocumentationPageProps {
version: VersionMetadata; version: VersionMetadata;
@ -277,12 +280,16 @@ function findDocumentAndMenu(
version: VersionMetadata, version: VersionMetadata,
flavor: { label: string; value: string }, flavor: { label: string; value: string },
segments: string[] segments: string[]
): { menu?: Menu; document?: DocumentData; isFallback?: boolean } { ): {
menu: undefined | Menu;
document: undefined | DocumentData;
isFallback?: boolean;
} {
const isFallback = segments[0] !== version.id; const isFallback = segments[0] !== version.id;
const path = isFallback ? segments : segments.slice(2); const path = isFallback ? segments : segments.slice(2);
let menu: Menu; let menu: undefined | Menu = undefined;
let document: DocumentData; let document: undefined | DocumentData = undefined;
try { try {
menu = menuApi.getMenu(version.id, flavor.value); menu = menuApi.getMenu(version.id, flavor.value);

View File

@ -9,7 +9,8 @@
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"noEmit": true, "noEmit": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true "isolatedModules": true,
"strictNullChecks": true
}, },
"files": [], "files": [],
"include": [], "include": [],

View File

@ -2,7 +2,7 @@ import cx from 'classnames';
import Link from 'next/link'; import Link from 'next/link';
export interface FooterProps { export interface FooterProps {
useDarkBackground: boolean; useDarkBackground?: boolean;
} }
export function Footer({ useDarkBackground }: FooterProps) { export function Footer({ useDarkBackground }: FooterProps) {
return ( return (

View File

@ -4,12 +4,12 @@ import { AlgoliaSearch } from '@nrwl/nx-dev/feature-search';
interface HeaderPropsWithoutFlavorAndVersion { interface HeaderPropsWithoutFlavorAndVersion {
showSearch: false; showSearch: false;
useDarkBackground: boolean; useDarkBackground?: boolean;
} }
interface HeaderPropsWithFlavorAndVersion { interface HeaderPropsWithFlavorAndVersion {
showSearch: boolean; showSearch: boolean;
useDarkBackground: boolean; useDarkBackground?: boolean;
flavor: { name: string; value: string }; flavor: { name: string; value: string };
version: { name: string; value: string }; version: { name: string; value: string };
} }

View File

@ -4,6 +4,7 @@
"jsx": "react-jsx", "jsx": "react-jsx",
"allowJs": true, "allowJs": true,
"esModuleInterop": true, "esModuleInterop": true,
"strictNullChecks": true,
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true
}, },
"files": [], "files": [],