From 59fa59fddc4b05df40b076f5beb412df288f3af5 Mon Sep 17 00:00:00 2001 From: Jack Hsu Date: Fri, 23 Jul 2021 10:49:20 -0400 Subject: [PATCH] docs(core): fix 500 error when directing from framework specific pages to intro page (#6492) --- .../src/lib/documents.api.ts | 31 +++++++++++++------ .../src/lib/documents.utils.ts | 2 +- .../src/lib/menu.api.spec.ts | 2 +- .../src/lib/menu.utils.ts | 16 +++++----- nx-dev/data-access-documents/tsconfig.json | 3 ++ nx-dev/feature-analytics/tsconfig.json | 1 + .../src/lib/content.spec.tsx | 2 ++ .../feature-doc-viewer/src/lib/doc-viewer.tsx | 2 +- nx-dev/feature-doc-viewer/src/lib/sidebar.tsx | 2 +- nx-dev/feature-doc-viewer/tsconfig.json | 1 + .../feature-search/src/lib/algolia-search.tsx | 2 +- nx-dev/feature-search/tsconfig.json | 1 + nx-dev/nx-dev/lib/use-storage.ts | 2 +- nx-dev/nx-dev/pages/[...segments].tsx | 17 +++++++--- nx-dev/nx-dev/tsconfig.json | 3 +- nx-dev/ui/common/src/lib/footer.tsx | 2 +- nx-dev/ui/common/src/lib/header.tsx | 4 +-- nx-dev/ui/common/tsconfig.json | 1 + 18 files changed, 62 insertions(+), 32 deletions(-) diff --git a/nx-dev/data-access-documents/src/lib/documents.api.ts b/nx-dev/data-access-documents/src/lib/documents.api.ts index fb6ae509f7..31c5381c69 100644 --- a/nx-dev/data-access-documents/src/lib/documents.api.ts +++ b/nx-dev/data-access-documents/src/lib/documents.api.ts @@ -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; } - ) {} + ) { + 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 { diff --git a/nx-dev/data-access-documents/src/lib/documents.utils.ts b/nx-dev/data-access-documents/src/lib/documents.utils.ts index 6118470b3a..621f2dd134 100644 --- a/nx-dev/data-access-documents/src/lib/documents.utils.ts +++ b/nx-dev/data-access-documents/src/lib/documents.utils.ts @@ -1,5 +1,5 @@ export function extractTitle(markdownContent: string): string | null { return ( - /^\s*#\s+(?.+)[\n.]+/.exec(markdownContent)?.groups.title ?? null + /^\s*#\s+(?<title>.+)[\n.]+/.exec(markdownContent)?.groups?.title ?? null ); } diff --git a/nx-dev/data-access-documents/src/lib/menu.api.spec.ts b/nx-dev/data-access-documents/src/lib/menu.api.spec.ts index f195653901..52451e1eec 100644 --- a/nx-dev/data-access-documents/src/lib/menu.api.spec.ts +++ b/nx-dev/data-access-documents/src/lib/menu.api.spec.ts @@ -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/ ); }); diff --git a/nx-dev/data-access-documents/src/lib/menu.utils.ts b/nx-dev/data-access-documents/src/lib/menu.utils.ts index 542f8ed164..56398211fa 100644 --- a/nx-dev/data-access-documents/src/lib/menu.utils.ts +++ b/nx-dev/data-access-documents/src/lib/menu.utils.ts @@ -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, })), diff --git a/nx-dev/data-access-documents/tsconfig.json b/nx-dev/data-access-documents/tsconfig.json index 62ebbd9464..ecd9872c40 100644 --- a/nx-dev/data-access-documents/tsconfig.json +++ b/nx-dev/data-access-documents/tsconfig.json @@ -1,5 +1,8 @@ { "extends": "../../tsconfig.base.json", + "compilerOptions": { + "strictNullChecks": true + }, "files": [], "include": [], "references": [ diff --git a/nx-dev/feature-analytics/tsconfig.json b/nx-dev/feature-analytics/tsconfig.json index 37ab84bcdb..59b9f4cfe0 100644 --- a/nx-dev/feature-analytics/tsconfig.json +++ b/nx-dev/feature-analytics/tsconfig.json @@ -4,6 +4,7 @@ "jsx": "react-jsx", "allowJs": true, "esModuleInterop": true, + "strictNullChecks": true, "allowSyntheticDefaultImports": true }, "files": [], diff --git a/nx-dev/feature-doc-viewer/src/lib/content.spec.tsx b/nx-dev/feature-doc-viewer/src/lib/content.spec.tsx index bd6babe7bc..7661cdb7a5 100644 --- a/nx-dev/feature-doc-viewer/src/lib/content.spec.tsx +++ b/nx-dev/feature-doc-viewer/src/lib/content.spec.tsx @@ -7,6 +7,8 @@ describe('Content', () => { it('should render successfully', () => { const { baseElement } = render( <Content + versionList={[]} + flavorList={[]} version="1.0.0" flavor="react" document={{ diff --git a/nx-dev/feature-doc-viewer/src/lib/doc-viewer.tsx b/nx-dev/feature-doc-viewer/src/lib/doc-viewer.tsx index 2910c01860..0aeca12466 100644 --- a/nx-dev/feature-doc-viewer/src/lib/doc-viewer.tsx +++ b/nx-dev/feature-doc-viewer/src/lib/doc-viewer.tsx @@ -17,7 +17,7 @@ export interface DocumentationFeatureDocViewerProps { menu: Menu; document: DocumentData; toc: any; - navIsOpen: boolean; + navIsOpen?: boolean; } export function DocViewer({ diff --git a/nx-dev/feature-doc-viewer/src/lib/sidebar.tsx b/nx-dev/feature-doc-viewer/src/lib/sidebar.tsx index b252a5a054..103c2a0f7d 100644 --- a/nx-dev/feature-doc-viewer/src/lib/sidebar.tsx +++ b/nx-dev/feature-doc-viewer/src/lib/sidebar.tsx @@ -16,7 +16,7 @@ export interface SidebarProps { versionList: VersionMetadata[]; flavorList: any[]; flavor: any; - navIsOpen: boolean; + navIsOpen?: boolean; } // Exported for testing diff --git a/nx-dev/feature-doc-viewer/tsconfig.json b/nx-dev/feature-doc-viewer/tsconfig.json index d8eb687121..d5d05866f8 100644 --- a/nx-dev/feature-doc-viewer/tsconfig.json +++ b/nx-dev/feature-doc-viewer/tsconfig.json @@ -4,6 +4,7 @@ "jsx": "react", "allowJs": true, "esModuleInterop": true, + "strictNullChecks": true, "allowSyntheticDefaultImports": true }, "files": [], diff --git a/nx-dev/feature-search/src/lib/algolia-search.tsx b/nx-dev/feature-search/src/lib/algolia-search.tsx index 07864660ff..e714c3c0f6 100644 --- a/nx-dev/feature-search/src/lib/algolia-search.tsx +++ b/nx-dev/feature-search/src/lib/algolia-search.tsx @@ -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); diff --git a/nx-dev/feature-search/tsconfig.json b/nx-dev/feature-search/tsconfig.json index 37ab84bcdb..59b9f4cfe0 100644 --- a/nx-dev/feature-search/tsconfig.json +++ b/nx-dev/feature-search/tsconfig.json @@ -4,6 +4,7 @@ "jsx": "react-jsx", "allowJs": true, "esModuleInterop": true, + "strictNullChecks": true, "allowSyntheticDefaultImports": true }, "files": [], diff --git a/nx-dev/nx-dev/lib/use-storage.ts b/nx-dev/nx-dev/lib/use-storage.ts index bb9ce95c59..e2e89622bd 100644 --- a/nx-dev/nx-dev/lib/use-storage.ts +++ b/nx-dev/nx-dev/lib/use-storage.ts @@ -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) { diff --git a/nx-dev/nx-dev/pages/[...segments].tsx b/nx-dev/nx-dev/pages/[...segments].tsx index 0b67dd7378..115ad9d0e6 100644 --- a/nx-dev/nx-dev/pages/[...segments].tsx +++ b/nx-dev/nx-dev/pages/[...segments].tsx @@ -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); diff --git a/nx-dev/nx-dev/tsconfig.json b/nx-dev/nx-dev/tsconfig.json index bc1511f9a7..ca01cf500e 100644 --- a/nx-dev/nx-dev/tsconfig.json +++ b/nx-dev/nx-dev/tsconfig.json @@ -9,7 +9,8 @@ "forceConsistentCasingInFileNames": true, "noEmit": true, "resolveJsonModule": true, - "isolatedModules": true + "isolatedModules": true, + "strictNullChecks": true }, "files": [], "include": [], diff --git a/nx-dev/ui/common/src/lib/footer.tsx b/nx-dev/ui/common/src/lib/footer.tsx index b7ca77e01e..1c1c34df3b 100644 --- a/nx-dev/ui/common/src/lib/footer.tsx +++ b/nx-dev/ui/common/src/lib/footer.tsx @@ -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 ( diff --git a/nx-dev/ui/common/src/lib/header.tsx b/nx-dev/ui/common/src/lib/header.tsx index 801b6cbb80..4d160dae05 100644 --- a/nx-dev/ui/common/src/lib/header.tsx +++ b/nx-dev/ui/common/src/lib/header.tsx @@ -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 }; } diff --git a/nx-dev/ui/common/tsconfig.json b/nx-dev/ui/common/tsconfig.json index 4f13c3264d..42100283ec 100644 --- a/nx-dev/ui/common/tsconfig.json +++ b/nx-dev/ui/common/tsconfig.json @@ -4,6 +4,7 @@ "jsx": "react-jsx", "allowJs": true, "esModuleInterop": true, + "strictNullChecks": true, "allowSyntheticDefaultImports": true }, "files": [],