Skip to content

Commit

Permalink
No more export default + fix typings
Browse files Browse the repository at this point in the history
  • Loading branch information
serut committed Mar 9, 2024
1 parent 1784940 commit 438de62
Show file tree
Hide file tree
Showing 18 changed files with 187 additions and 142 deletions.
4 changes: 2 additions & 2 deletions packages/docusaurus-plugin-redoc/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
PluginDirectUsageOptions,
DEFAULT_OPTIONS,
} from './options';
import type { SpecPropsWithUrl, ApiDocProps } from './types/common';
import type { SpecDataResult, ApiDocProps } from './types/common';
import { loadSpecWithConfig } from './loadSpec';
import { loadRedoclyConfig } from './loadRedoclyConfig';

Expand Down Expand Up @@ -128,7 +128,7 @@ export default function redocPlugin(
throw new Error(`[Redocusaurus] Spec could not be parsed: ${spec}`);
}

const data: SpecPropsWithUrl = {
const data: SpecDataResult = {
url,
themeId,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
18 changes: 13 additions & 5 deletions packages/docusaurus-theme-redoc/src/theme/ApiSchema/ApiSchema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,25 @@ import clsx from 'clsx';
import { ThemeProvider } from 'styled-components';
import '../../global';
import { SchemaDefinition } from 'redoc';
import useSpec from '../../utils/useSpec';
import { ApiSchemaProps as Props } from '../../types/common';
import useSpec from '@theme/useSpec';
import '../Redoc/styles.css';
import './styles.css';

const ApiSchema: React.FC<Props> = ({
const ApiSchema: React.FC<ApiSchemaProps> = ({
showExample,
pointer,
id,
spec,
optionsOverrides,
...rest
}: Props): JSX.Element => {
const { store } = useSpec(rest);
}: ApiSchemaProps): JSX.Element => {
const { store } = useSpec(
{
id,
spec,
},
optionsOverrides,
);

useEffect(() => {
/**
Expand Down
14 changes: 8 additions & 6 deletions packages/docusaurus-theme-redoc/src/theme/Redoc/Redoc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,33 @@ import React from 'react';
import clsx from 'clsx';
import '../../global';
import { RedocStandalone } from 'redoc';
import { RedocProps } from '../../types/common';
import useSpecOptions from '../../utils/useSpecOptions';
import useSpecOptions from '@theme/useSpecOptions';
import './styles.css';
import ServerRedoc from './ServerRedoc';

function getIsExternalUrl(url = '') {
return ['http://', 'https://'].some((protocol) => url.startsWith(protocol));
}

/*!
* Redocusaurus
* https://redocusaurus.vercel.app/
* (c) 2024 Rohit Gohri
* Released under the MIT License
*/
function Redoc(props: RedocProps): JSX.Element {
const { className, optionsOverrides, spec, url, themeId, isSpecFile } = props;
const { className, optionsOverrides, url, themeId } = props;
const { options } = useSpecOptions(themeId, optionsOverrides);
const isDevMode = process.env.NODE_ENV === 'development';

if ((isDevMode && isSpecFile === false) || !spec) {
if (getIsExternalUrl(url)) {
return (
<div className={clsx(['redocusaurus', className])}>
<RedocStandalone specUrl={url} options={options} />
</div>
);
}

return <ServerRedoc {...props} spec={spec} />;
return <ServerRedoc {...props} />;
}

export default Redoc;
25 changes: 12 additions & 13 deletions packages/docusaurus-theme-redoc/src/theme/Redoc/ServerRedoc.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React from 'react';
import clsx from 'clsx';
import '../../global';
import { Redoc as RedocComponent, RedocRawOptions } from 'redoc';
import { SpecProps } from '../../types/common';
import useSpec from '../../utils/useSpec';
import { Redoc as RedocComponent } from 'redoc';
import useSpec from '@theme/useSpec';
import { ServerStyles } from './Styles';
import './styles.css';

Expand All @@ -13,22 +12,22 @@ import './styles.css';
* (c) 2024 Rohit Gohri
* Released under the MIT License
*/
function ServerRedoc(
props: SpecProps & {
className?: string;
optionsOverrides?: RedocRawOptions;
},
): JSX.Element {
const { className, optionsOverrides, ...specProps } = props;
const { store, darkThemeOptions, lightThemeOptions, hasLogo } = useSpec(
specProps,
function ServerRedoc(props: RedocProps): JSX.Element {
const { className, optionsOverrides, url, id, themeId } = props;
const { store, spec, darkThemeOptions, lightThemeOptions, hasLogo } = useSpec(
{
spec: props.spec,
themeId,
id,
},
optionsOverrides,
);

return (
<>
<ServerStyles
specProps={specProps}
spec={spec}
url={url}
lightThemeOptions={lightThemeOptions}
darkThemeOptions={darkThemeOptions}
/>
Expand Down
23 changes: 14 additions & 9 deletions packages/docusaurus-theme-redoc/src/theme/Redoc/ServerStyles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import '../../global';
import useBaseUrl from '@docusaurus/useBaseUrl';
import { AppStore, Redoc, RedocRawOptions } from 'redoc';
import type { OpenAPISpec } from 'redoc/typings/types';
// eslint-disable-next-line import/no-extraneous-dependencies
import { renderToString } from 'react-dom/server';
import { ServerStyleSheet } from 'styled-components';
Expand Down Expand Up @@ -53,22 +54,26 @@ const prefixCssSelectors = function (rules: string, className: string) {
const LIGHT_MODE_PREFIX = "html:not([data-theme='dark'])";
const DARK_MODE_PREFIX = "html([data-theme='dark'])";

export type ServerStylesProps = {
spec: OpenAPISpec;
url?: string;
lightThemeOptions: RedocRawOptions;
darkThemeOptions: RedocRawOptions;
};

export function ServerStyles({
specProps,
spec,
url,
lightThemeOptions,
darkThemeOptions,
}: {
specProps: SpecProps;
lightThemeOptions: RedocRawOptions;
darkThemeOptions: RedocRawOptions;
}) {
const fullUrl = useBaseUrl(specProps.url, { absolute: true });
}: ServerStylesProps) {
const fullUrl = useBaseUrl(url, { absolute: true });
const css = {
light: '',
dark: '',
};
const lightSheet = new ServerStyleSheet();
const lightStore = new AppStore(specProps.spec, fullUrl, lightThemeOptions);
const lightStore = new AppStore(spec, fullUrl, lightThemeOptions);
renderToString(
lightSheet.collectStyles(React.createElement(Redoc, { store: lightStore })),
);
Expand All @@ -78,7 +83,7 @@ export function ServerStyles({
css.light = prefixCssSelectors(lightCss, LIGHT_MODE_PREFIX);

const darkSheet = new ServerStyleSheet();
const darkStore = new AppStore(specProps.spec, fullUrl, darkThemeOptions);
const darkStore = new AppStore(spec, fullUrl, darkThemeOptions);
renderToString(
darkSheet.collectStyles(React.createElement(Redoc, { store: darkStore })),
);
Expand Down
8 changes: 2 additions & 6 deletions packages/docusaurus-theme-redoc/src/theme/Redoc/Styles.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import React from 'react';
import '../../global';
import type { RedocRawOptions } from 'redoc';
import type { ServerStylesProps } from './ServerStyles';

/**
* Don't hydrate/replace server styles
* @see https://github.com/facebook/react/issues/10923#issuecomment-338715787
*/
export function ServerStyles(_props: {
specProps: SpecProps;
lightThemeOptions: RedocRawOptions;
darkThemeOptions: RedocRawOptions;
}) {
export function ServerStyles(_props: ServerStylesProps) {
return <div className="redocusaurus-styles"></div>;
}
3 changes: 3 additions & 0 deletions packages/docusaurus-theme-redoc/src/theme/useSpec/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { useSpec } from './useSpec';

export default useSpec;
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import { useMemo, useEffect } from 'react';
import useBaseUrl from '@docusaurus/useBaseUrl';
import useIsBrowser from '@docusaurus/useIsBrowser';
import { useColorMode } from '@docusaurus/theme-common';
import '../global';
import useSpecData from '@theme/useSpecData';
import useSpecOptions from '@theme/useSpecOptions';
import '../../global';
import { AppStore, RedocRawOptions } from 'redoc';
import { SpecProps } from '../types/common';
import useSpecOptions from './useSpecOptions';
import useSpecData from './useSpecData';

// the current store singleton in the app's instance
let currentStore: AppStore | null = null;
Expand All @@ -17,11 +16,15 @@ let currentStore: AppStore | null = null;
* (c) 2024 Rohit Gohri
* Released under the MIT License
*/
export default function useSpec(
export function useSpec(
specInfo: SpecProps,
optionsOverrides?: RedocRawOptions,
) {
const { spec, url, themeId } = useSpecData(specInfo);
): SpecResult {
const { spec, url, themeId } = useSpecData(
specInfo.id,
specInfo.spec,
specInfo.themeId,
);
const specOptions = useSpecOptions(themeId, optionsOverrides);
const fullUrl = useBaseUrl(url, { absolute: true });
const isBrowser = useIsBrowser();
Expand All @@ -38,6 +41,7 @@ export default function useSpec(
// @ts-expect-error extra prop
hasLogo: !!spec.info?.['x-logo'],
store: currentStore,
spec,
};
}, [isBrowser, spec, fullUrl, specOptions]);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { useSpecData } from './useSpecData';

export default useSpecData;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useAllPluginInstancesData } from '@docusaurus/useGlobalData';
import type { OpenAPISpec } from 'redoc/typings/types';
import { SpecProps, SpecPropsWithUrl } from '../types/common';
import { SpecDataResult } from '../../types/common';

export type ParsedSpec = OpenAPISpec;

Expand All @@ -13,17 +13,23 @@ export type ParsedSpec = OpenAPISpec;
* @param providedSpec spec data
* @returns Spec Data of ID or first one if ID is not provided
*/
export default function useSpecData(providedSpec: SpecProps): SpecPropsWithUrl {
export function useSpecData(
id?: string,
spec?: OpenAPISpec,
themeId?: string,
): SpecDataResult {
const allData = useAllPluginInstancesData('docusaurus-plugin-redoc');
if (providedSpec.spec) {
if (spec) {
// return provided spec when already defined
return providedSpec as SpecPropsWithUrl;
return {
spec,
themeId,
};
} else {
// retrieve spec from docusaurus conf
const id = providedSpec.id;
const apiData = id
? allData?.[id as string]
: Object.values(allData ?? {})?.[0];
return apiData as SpecPropsWithUrl;
return apiData as SpecDataResult;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { useSpecOptions } from './useSpecOptions';

export default useSpecOptions;
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import {
} from '@docusaurus/useGlobalData';
import { useColorMode } from '@docusaurus/theme-common';
import merge from 'lodash/merge';
import '../global';
import '../../global';
import { RedocRawOptions } from 'redoc';
import { SpecProps } from '../types/common';
import { GlobalData } from '../types/options';
import { SpecProps } from '../../types/common';
import { GlobalData } from '../../types/options';

/**
* Redocusaurus
* https://redocusaurus.vercel.app/
* (c) 2024 Rohit Gohri
* Released under the MIT License
*/
export default function useSpecOptions(
export function useSpecOptions(
themeId: SpecProps['themeId'] = 'theme-redoc',
optionsOverrides?: RedocRawOptions,
) {
Expand Down
36 changes: 4 additions & 32 deletions packages/docusaurus-theme-redoc/src/types/common.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import type { Props as LayoutProps } from '@theme/Layout';
import type { ObjectDescriptionProps, RedocRawOptions } from 'redoc';
import type { OpenAPISpec } from 'redoc/typings/types';

export type ParsedSpec = OpenAPISpec;
import type { ObjectDescriptionProps } from 'redoc';

export interface SpecProps {
/**
* Spec to use, already loaded previously
*/
spec: ParsedSpec;
spec: import('redoc/typings/types').OpenAPISpec;
/**
* When spec not provided, load the spec from docusaurus config
* fallback to first configuration if not provided
Expand All @@ -20,23 +17,9 @@ export interface SpecProps {
themeId?: string;
}

export type SpecPropsWithUrl = Omit<SpecProps, 'id'> & {
/**
* Absolute path to the spec file used
*/
url?: string;
};

export type RedocProps = SpecProps & {
/**
* FIXME - incorrect name - should be isExternalUrl
*/
isSpecFile?: boolean;
className?: string;
optionsOverrides?: RedocRawOptions;
export type SpecDataResult = Omit<SpecProps, 'id'> & {
/**
* External URL to load spec file from
* FIXME - incorrect name - should be externalUrl
* Public path to the spec file used, used by Redoc as download url
*/
url?: string;
};
Expand All @@ -48,17 +31,6 @@ export interface MdxProps {
*/
id?: string;
}
export type ApiSchemaProps = Omit<
ObjectDescriptionProps,
'parser' | 'options' | 'schemaRef'
> &
MdxProps & {
/**
* Ref to the schema
*/
pointer: ObjectDescriptionProps['schemaRef'];
spec: ParsedSpec;
};

export type ApiDocProps = {
specProps: SpecProps;
Expand Down
Loading

0 comments on commit 438de62

Please sign in to comment.