Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
322 changes: 135 additions & 187 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,19 @@
"@docusaurus/tsconfig": "^3.10.0",
"@docusaurus/types": "^3.10.0",
"@eslint/js": "~9.39.4",
"dotenv": "^17.3.1",
"@types/lodash": "^4.17.24",
"dotenv": "^17.4.1",
"eslint": "~9.39.4",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
"globals": "^17.4.0",
"lodash": "^4.17.23",
"lodash": "^4.18.1",
"prettier": "^3.8.1",
"raw-loader": "^4.0.2",
"remark": "^15.0.1",
"serve-handler": "^6.1.7",
"typescript": "^5.9.3",
"typescript-eslint": "^8.57.1",
"typescript": "^6.0.2",
"typescript-eslint": "^8.58.0",
"unist-util-visit": "^5.1.0"
},
"overrides": {
Expand Down
9 changes: 7 additions & 2 deletions sidebarsAdEngine.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
import type { SidebarItem, SidebarItemCategory, SidebarItemConfig, SidebarItemDoc } from '@docusaurus/plugin-content-docs/lib/sidebars/types.d.ts';
import type {
SidebarItem,
SidebarItemCategoryConfig,
SidebarItemConfig,
SidebarItemDoc,
} from '@docusaurus/plugin-content-docs/lib/sidebars/types.d.ts';
import apiSidebar from './adengine/reference/sidebar';

function isCategory(item: SidebarItemConfig): item is SidebarItemCategory {
function isCategory(item: SidebarItemConfig): item is SidebarItemCategoryConfig {
return (item as SidebarItem).type === 'category';
}

Expand Down
77 changes: 43 additions & 34 deletions sidebarsMillicast.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
import type { SidebarItem, SidebarItemCategory, SidebarItemConfig, SidebarItemDoc } from '@docusaurus/plugin-content-docs/lib/sidebars/types.d.ts';
import type {
SidebarItem,
SidebarItemCategoryConfig,
SidebarItemConfig,
SidebarItemDoc,
} from '@docusaurus/plugin-content-docs/lib/sidebars/types.d.ts';
import rawMillicastApiSidebar from './millicast/api/sidebar';
import rawMillicastAdvancedReportingApiSidebar from './millicast/api/reporting/sidebar';
import rawMillicastDirectorApiSidebar from './millicast/api/director/sidebar';

function isCategory(item: SidebarItemConfig): item is SidebarItemCategory {
function isCategory(item: SidebarItemConfig): item is SidebarItemCategoryConfig {
return (item as SidebarItem).type === 'category';
}

Expand All @@ -17,7 +22,7 @@ function removeHiddenItems(data: SidebarItemConfig[], hiddenIds: string[]): Side
return data
.map((category) => {
// filter out items from other categories that match the hidden IDs
if (isCategory(category)) {
if (isCategory(category) && Array.isArray(category.items)) {
// filter out the items that match any of the hidden IDs
const filteredItems = category.items.filter((item) => !(isDoc(item) && hiddenIdsSet.has(item.id)));

Expand All @@ -40,55 +45,59 @@ function removeHiddenItems(data: SidebarItemConfig[], hiddenIds: string[]): Side

function fixLabels(items: SidebarItemConfig[], replacements: Record<string, string> = {}): SidebarItemConfig[] {
return items.map((item) => {
if (!(isCategory(item) || isDoc(item))) {
return item;
}
let label = item.label;
if (label) {
if ((isCategory(item) || isDoc(item)) && item.label) {
let label = item.label;
if (replacements[label]) {
// Replace label
label = replacements[label];
item = { ...item, label };
} else if (isCategory(item)) {
// Add spaces between capitalized words
label = item.label.replace(/([a-z])([A-Z])/g, '$1 $2');
item = { ...item, label };
}
}
if (isCategory(item)) {
return { ...item, label, items: fixLabels(item.items, replacements) };
} else {
return { ...item, label };
if (isCategory(item) && Array.isArray(item.items)) {
const items = fixLabels(item.items, replacements);
item = { ...item, items };
}
return item;
});
}

function mergeCategories(items: SidebarItemConfig[]): SidebarItemConfig[] {
for (let index = 0; index < items.length; index++) {
const item = items[index];
if (isCategory(item)) {
// Merge categories with same label
const otherIndex = items.findIndex((other, otherIndex) => {
return otherIndex > index && isCategory(other) && other.label === item.label;
if (!isCategory(item) || !Array.isArray(item.items)) {
continue;
}
// Merge categories with same label
const otherIndex = items.findIndex((other, otherIndex) => {
return otherIndex > index && isCategory(other) && other.label === item.label;
});
if (otherIndex < 0) {
continue;
}
const otherItem = items[otherIndex] as SidebarItemCategoryConfig;
if (!Array.isArray(otherItem.items)) {
continue;
}
const mergedItems = [...otherItem.items];
for (const otherChild of item.items) {
// Insert before existing child with same label (if any).
// Otherwise, insert at the end.
const existingChildIndex = mergedItems.findIndex((existingChild) => {
return isDoc(otherChild) && isDoc(existingChild) && existingChild.label === otherChild.label;
});
if (otherIndex > 0) {
const otherItem = items[otherIndex] as SidebarItemCategory;
const mergedItems = [...otherItem.items];
for (const otherChild of item.items) {
// Insert before existing child with same label (if any).
// Otherwise, insert at the end.
const existingChildIndex = mergedItems.findIndex((existingChild) => {
return isDoc(otherChild) && isDoc(existingChild) && existingChild.label === otherChild.label;
});
if (existingChildIndex >= 0) {
mergedItems.splice(existingChildIndex, 0, otherChild);
} else {
mergedItems.push(otherChild);
}
}
items[index] = { ...item, items: mergedItems };
items.splice(otherIndex, 1);
index--;
if (existingChildIndex >= 0) {
mergedItems.splice(existingChildIndex, 0, otherChild);
} else {
mergedItems.push(otherChild);
}
}
items[index] = { ...item, items: mergedItems };
items.splice(otherIndex, 1);
index--;
}
return items;
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/PlatformSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function PlatformSelect({ docsPluginId, version, className, ...pr
// selectedItem is always null during SSR, so look up the initial platform manually
platforms.find((desc) => desc.platform === lastPlatformName) ??
// last platform does not exist in the active doc version, fall back to default platform
platforms.find((desc) => desc.platform === defaultPlatformName);
platforms.find((desc) => desc.platform === defaultPlatformName)!;
return (
<span className={clsx(styles.platformValue)}>
<Icon className={styles.platformIcon} icon={icon} defaultIcon="" />
Expand All @@ -48,8 +48,8 @@ export default function PlatformSelect({ docsPluginId, version, className, ...pr
>
{(desc) => {
const { platform, label, description, icon } = desc;
const sidebar = findSidebarInVersions(platform, versionCandidates);
const sidebarLink = (activeDoc && getPlatformDoc(docsPluginId, activeVersion, activeDoc, platform)?.path) ?? sidebar.link.path;
const sidebar = findSidebarInVersions(platform, versionCandidates)!;
const sidebarLink = (activeDoc && getPlatformDoc(docsPluginId, activeVersion!, activeDoc, platform)?.path) ?? sidebar.link!.path;
return (
<Item
id={platform}
Expand Down
2 changes: 1 addition & 1 deletion src/components/SidebarCategoryDocCardList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function isCategory(item: PropSidebarItem): item is PropSidebarItemCategory {

export default function SidebarCategoryDocCardList({ headingLevel, ...props }: Props) {
const sidebar = useDocsSidebar();
const categories = sidebar.items.filter(isCategory);
const categories = sidebar?.items.filter(isCategory) ?? [];
return categories.map((category) => (
<Fragment key={category.label}>
<Heading as={headingLevel ?? 'h2'}>{category.label}</Heading>
Expand Down
2 changes: 1 addition & 1 deletion src/components/SidebarDocCardList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function isCategory(item: PropSidebarItem): item is PropSidebarItemCategory {
export default function SidebarDocCardList({ headingLevel, ...props }: Props) {
const doc = useDoc();
const sidebar = useDocsSidebar();
const items = sidebar.items
const items = (sidebar?.items ?? [])
// Hide the current doc page from list
.filter((item) => !(item.type === 'link' && item.docId === doc.metadata.id));
if (headingLevel) {
Expand Down
7 changes: 6 additions & 1 deletion src/components/ThreeCardList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import React from 'react';
import clsx from 'clsx';
import type { Props } from '@theme/DocCardList';
import type { Props as DocCardProps } from '@theme/DocCardList';
import type { PropSidebarItem } from '@docusaurus/plugin-content-docs';
import DocCard from '@theme/DocCard';

export interface Props extends DocCardProps {
readonly items: PropSidebarItem[];
}

export default function ThreeCardList(props: Props) {
const { items, className } = props;
return (
Expand Down
10 changes: 5 additions & 5 deletions src/contexts/lastPlatform.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import { defaultPlatformName } from '@site/src/util/platform';

const isDocsPluginEnabled: boolean = !!useAllDocsData;

type LastPlatformName = PlatformName | null;
type LastPlatformName = PlatformName;

/** State for a single docs plugin instance */
type DocsLastPlatformPluginState = {
lastPlatformName: LastPlatformName;
lastPlatformName: LastPlatformName | null;
};

/**
Expand Down Expand Up @@ -75,7 +75,7 @@ function LastPlatformContextProviderUnsafe({ children }: { children: ReactNode }
const lastPlatformName = state[pluginId].lastPlatformName;
if (activeDoc && (!lastPlatformName || lastPlatformName !== docSidebarName)) {
if (isDocSharedWithPlatform(pluginId, activeDoc, lastPlatformName || defaultPlatformName)) {
if (lastPlatformName && activeVersion.sidebars[lastPlatformName]) {
if (lastPlatformName && activeVersion?.sidebars?.[lastPlatformName]) {
// Prefer last platform for cross-platform docs
} else {
// No last platform yet or platform not in this version, so update to default platform
Expand Down Expand Up @@ -113,7 +113,7 @@ export function useLastPlatform(): {
lastPlatformName: LastPlatformName;
saveLastPlatform: (lastPlatform: LastPlatformName) => void;
} {
const { pluginId } = useActivePlugin({ failfast: true });
const { pluginId } = useActivePlugin({ failfast: true })!;
return useLastPlatformByPluginId(pluginId);
}

Expand Down Expand Up @@ -154,5 +154,5 @@ export function useLastPlatformMainLink(pluginId: string): string | null {
}

const sidebar = findSidebarInVersions(platformName, versionCandidates);
return sidebar.link.path;
return sidebar?.link?.path ?? null;
}
10 changes: 6 additions & 4 deletions src/theme/DocBreadcrumbs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,24 @@ function getMainDocTitle(docPluginId: string): string | null {
return 'Live Streaming';
case 'millicast':
return 'Real-time Streaming';
default:
return null;
}
}

function useSidebarBreadcrumbsWithMainDoc(): PropSidebarBreadcrumbsItem[] | null {
const breadcrumbs = useSidebarBreadcrumbs();
const { pluginId } = useActivePlugin({ failfast: true })!;
const { activeVersion, activeDoc } = useActiveDocContext(pluginId);
const versionMainDoc = activeVersion.docs.find((doc) => doc.id === activeVersion.mainDocId)!;
const mainDocUrl = useBaseUrl(versionMainDoc.path);
const versionMainDoc = activeVersion?.docs.find((doc) => doc.id === activeVersion.mainDocId);
const mainDocUrl = useBaseUrl(versionMainDoc?.path);
const mainDocTitle = getMainDocTitle(pluginId);
if (!breadcrumbs || !mainDocTitle) {
if (!breadcrumbs || !versionMainDoc || !mainDocTitle) {
return breadcrumbs;
}
const mainDocItem: PropSidebarItemLink = {
type: 'link',
href: activeDoc.id === activeVersion.mainDocId ? undefined : mainDocUrl,
href: activeDoc?.id === activeVersion?.mainDocId ? '' : mainDocUrl,
label: mainDocTitle,
docId: versionMainDoc.id,
};
Expand Down
4 changes: 2 additions & 2 deletions src/theme/DocRoot/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import { isDocSharedWithPlatform } from '@site/src/util/platform';
type Props = WrapperProps<typeof LayoutType>;

function PlatformSidebarProvider({ children }: { children: ReactNode }) {
const { pluginId } = useActivePlugin({ failfast: true });
const { pluginId } = useActivePlugin({ failfast: true })!;
const { activeDoc } = useActiveDocContext(pluginId);
const versionMetadata = useDocsVersion();
const { lastPlatformName } = useLastPlatform();

// Override sidebar for certain docs that are shared across platforms
if (isDocSharedWithPlatform(pluginId, activeDoc, lastPlatformName)) {
if (isDocSharedWithPlatform(pluginId, activeDoc!, lastPlatformName)) {
return (
<DocsSidebarProvider name={lastPlatformName} items={versionMetadata.docsSidebars[lastPlatformName]}>
{children}
Expand Down
2 changes: 1 addition & 1 deletion src/theme/DocSidebarItem/Link/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function BackLink({ item, ...props }: Props): JSX.Element {
// Replace back link with last platform's main sidebar link (if available)
const {
activePlugin: { pluginId },
} = useActivePluginAndVersion({ failfast: true });
} = useActivePluginAndVersion({ failfast: true })!;
const href = useLastPlatformMainLink(pluginId) || item.href;
return <Link item={{ ...item, href }} {...props} />;
}
Expand Down
5 changes: 3 additions & 2 deletions src/theme/DocSidebarItems/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ type Props = WrapperProps<typeof DocSidebarItemsType>;
function DocSidebarHeader(): JSX.Element | null {
const {
activePlugin: { pluginId },
activeVersion: { name: versionName },
} = useActivePluginAndVersion({ failfast: true });
activeVersion,
} = useActivePluginAndVersion({ failfast: true })!;
const versionName = activeVersion!.name;
const platforms = getPlatformsByVersion(pluginId, versionName);
if (!platforms.length) {
return null;
Expand Down
2 changes: 1 addition & 1 deletion src/theme/DocVersionBanner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function getProductNameByPluginId(pluginId: string): string {

export default function DocVersionBannerWrapper(props: Props) {
const originalContext: DocusaurusContext = useDocusaurusContext();
const { pluginId } = useActivePlugin({ failfast: true });
const { pluginId } = useActivePlugin({ failfast: true })!;
// <DocVersionBanner> uses siteConfig.title from the DocusaurusContext in its message,
// but we want to show the product name instead (derived from the current doc plugin ID).
// HACK: create a new context and replace the title with the product name.
Expand Down
4 changes: 2 additions & 2 deletions src/theme/FaqList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ export default function FaqList(props: Props): ReactNode {
const filteredItems = filterDocCardListItems(items).filter(isValidItem);
const grouped = Object.groupBy(filteredItems, ({ customProps }) => (customProps?.faqCategory as string) ?? 'Questions');

return Object.keys(grouped).map((key) => (
return Object.entries(grouped).map(([key, group]) => (
<>
<Heading as="h2" className={clsx('text--truncate', styles.faqTitle)} title={key}>
{key}
</Heading>

<ul className={clsx(styles.faqList, className)}>
{grouped[key].map((item, index) => (
{group!.map((item, index) => (
<FaqListItem key={index} item={item as PropSidebarItemLink} />
))}
</ul>
Expand Down
2 changes: 1 addition & 1 deletion src/util/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ export function getPlatformsByVersion(docsPluginId: string, version?: string): r
}

export function usePlatforms(): readonly PlatformDescriptionWithUrl[] {
const { activePlugin, activeVersion } = useActivePluginAndVersion({ failfast: true });
const { activePlugin, activeVersion } = useActivePluginAndVersion({ failfast: true })!;
const { withBaseUrl } = useBaseUrlUtils();
if (!activeVersion) return [];
return getPlatformsByVersion(activePlugin.pluginId, activeVersion.name).map((desc) => ({
Expand Down
4 changes: 2 additions & 2 deletions src/util/sidebar.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { GlobalSidebar, GlobalVersion } from '@docusaurus/plugin-content-docs/client';

export function findSidebarInVersions(sidebarName: string, versionCandidates: GlobalVersion[]): GlobalSidebar {
export function findSidebarInVersions(sidebarName: string, versionCandidates: GlobalVersion[]): GlobalSidebar | undefined {
for (const version of versionCandidates) {
const sidebar = version.sidebars[sidebarName];
const sidebar = version.sidebars?.[sidebarName];
if (sidebar) {
return sidebar;
}
Expand Down
7 changes: 5 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
// This file is not used in compilation. It is here just for a nice editor experience.
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
"target": "es2021",
"target": "es2022",
"lib": ["es2024", "dom"],
"types": ["@docusaurus/module-type-aliases", "@docusaurus/theme-classic"],
"baseUrl": "."
"baseUrl": null,
"paths": {
"@site/*": ["./*"]
}
},
"include": ["sidebars*.ts", "src/", "theoplayer/", "ads/", "adengine/", "open-video-ui/", "contributing/", "theolive/", "millicast/"],
"exclude": ["theoplayer/external/", "open-video-ui/external/", "theoplayer_versioned_docs/"]
Expand Down
Loading