Skip to content

Commit 171a5be

Browse files
authored
Merge bb84eb5 into a4977bf
2 parents a4977bf + bb84eb5 commit 171a5be

25 files changed

+2146
-236
lines changed

package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,8 @@
7979
"printWidth": 80,
8080
"tabWidth": 2
8181
},
82-
"packageManager": "yarn@4.0.1"
82+
"packageManager": "yarn@4.0.1",
83+
"volta": {
84+
"node": "18.12.0"
85+
}
8386
}

packages/docusaurus-plugin-redoc/src/index.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
PluginDirectUsageOptions,
2525
DEFAULT_OPTIONS,
2626
} from './options';
27-
import type { SpecProps, ApiDocProps } from './types/common';
27+
import type { SpecDataResult, ApiDocProps } from './types/common';
2828
import { loadSpecWithConfig } from './loadSpec';
2929
import { loadRedoclyConfig } from './loadRedoclyConfig';
3030

@@ -33,6 +33,10 @@ const version = require('../package.json').version;
3333

3434
export { PluginOptions, PluginDirectUsageOptions, loadRedoclyConfig };
3535

36+
function getIsExternalUrl(url = '') {
37+
return ['http://', 'https://'].some((protocol) => url.startsWith(protocol));
38+
}
39+
3640
export default function redocPlugin(
3741
context: LoadContext,
3842
opts: PluginOptions,
@@ -45,12 +49,13 @@ export default function redocPlugin(
4549
const { debug, spec, url: downloadUrl, config, themeId } = options;
4650

4751
let url = downloadUrl;
48-
const isSpecFile = fs.existsSync(spec);
52+
const isExternalUrl = getIsExternalUrl(url);
53+
4954
const fileName = path.join(
5055
'redocusaurus',
5156
`${options.id || 'api-spec'}.yaml`,
5257
);
53-
let filesToWatch: string[] = isSpecFile ? [path.resolve(spec)] : [];
58+
let filesToWatch: string[] = !isExternalUrl ? [path.resolve(spec)] : [];
5459

5560
if (debug) {
5661
console.error('[REDOCUSAURUS_PLUGIN] Opts Input:', opts);
@@ -67,7 +72,7 @@ export default function redocPlugin(
6772

6873
let bundledSpec: Document, problems: NormalizedProblem[];
6974

70-
if (!isSpecFile) {
75+
if (isExternalUrl) {
7176
// If spec is a remote url then add it as download url also as a default
7277
url = url || spec;
7378
if (debug) {
@@ -123,10 +128,9 @@ export default function redocPlugin(
123128
throw new Error(`[Redocusaurus] Spec could not be parsed: ${spec}`);
124129
}
125130

126-
const data: SpecProps = {
131+
const data: SpecDataResult = {
127132
url,
128133
themeId,
129-
isSpecFile,
130134
// eslint-disable-next-line @typescript-eslint/no-explicit-any
131135
spec: content.converted as any,
132136
};
@@ -165,7 +169,7 @@ export default function redocPlugin(
165169
}
166170
},
167171
async postBuild({ content }) {
168-
if (!isSpecFile || downloadUrl) {
172+
if (isExternalUrl || downloadUrl) {
169173
return;
170174
}
171175
// Create a static file from bundled spec

packages/docusaurus-theme-redoc/src/theme/ApiDocMdx/ApiDocMdx.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React, { useMemo } from 'react';
22
import Redoc from '@theme/Redoc';
33
import useSpecData from '@theme/useSpecData';
4-
import { MdxProps as Props } from '../../types/common';
4+
import { MdxProps } from '../../types/common';
55
import '../ApiSchema/styles.css';
66

7-
const ApiDocMdx: React.FC<Props> = ({ id }: Props): JSX.Element => {
7+
const ApiDocMdx: React.FC<MdxProps> = ({ id }: MdxProps): JSX.Element => {
88
const specProps = useSpecData(id);
99
const optionsOverrides = useMemo(() => {
1010
return {

packages/docusaurus-theme-redoc/src/theme/ApiSchema/ApiSchema.tsx

+17-11
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,25 @@ import clsx from 'clsx';
33
import { ThemeProvider } from 'styled-components';
44
import '../../global';
55
import { SchemaDefinition } from 'redoc';
6-
import { useSpec } from '../../utils/useSpec';
7-
import { useSpecData } from '../useSpecData';
8-
import { ApiSchemaProps as Props } from '../../types/common';
6+
import useSpec from '@theme/useSpec';
97
import '../Redoc/styles.css';
108
import './styles.css';
119

12-
const ApiSchema: React.FC<Props> = ({
13-
id,
14-
example,
10+
const ApiSchema: React.FC<ApiSchemaProps> = ({
11+
showExample,
1512
pointer,
13+
id,
14+
spec,
15+
optionsOverrides,
1616
...rest
17-
}: Props): JSX.Element => {
18-
const specProps = useSpecData(id);
19-
const { store } = useSpec(specProps);
17+
}: ApiSchemaProps): JSX.Element => {
18+
const { store } = useSpec(
19+
{
20+
id,
21+
spec,
22+
},
23+
optionsOverrides,
24+
);
2025

2126
useEffect(() => {
2227
/**
@@ -31,13 +36,14 @@ const ApiSchema: React.FC<Props> = ({
3136
className={clsx([
3237
'redocusaurus',
3338
'redocusaurus-schema',
34-
example ? null : 'hide-example',
39+
showExample ? null : 'hide-example',
3540
])}
3641
>
3742
<SchemaDefinition
3843
parser={store.spec.parser}
3944
options={store.options}
4045
schemaRef={pointer}
46+
showExample={showExample}
4147
{...rest}
4248
/>
4349
</div>
@@ -46,7 +52,7 @@ const ApiSchema: React.FC<Props> = ({
4652
};
4753

4854
ApiSchema.defaultProps = {
49-
example: false,
55+
showExample: false,
5056
};
5157

5258
export default ApiSchema;
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,34 @@
11
import React from 'react';
22
import clsx from 'clsx';
33
import '../../global';
4-
import { RedocStandalone, RedocRawOptions } from 'redoc';
5-
import { SpecProps } from '../../types/common';
6-
import { useSpecOptions } from '../../utils/useSpecOptions';
4+
import { RedocStandalone } from 'redoc';
5+
import useSpecOptions from '@theme/useSpecOptions';
76
import './styles.css';
87
import ServerRedoc from './ServerRedoc';
98

9+
function getIsExternalUrl(url = '') {
10+
return ['http://', 'https://'].some((protocol) => url.startsWith(protocol));
11+
}
12+
1013
/*!
1114
* Redocusaurus
1215
* https://redocusaurus.vercel.app/
1316
* (c) 2024 Rohit Gohri
1417
* Released under the MIT License
1518
*/
16-
function Redoc(
17-
props: Partial<SpecProps> & {
18-
className?: string;
19-
optionsOverrides?: RedocRawOptions;
20-
},
21-
): JSX.Element {
22-
const { className, optionsOverrides, spec, url, themeId, isSpecFile } = props;
19+
function Redoc(props: RedocProps): JSX.Element {
20+
const { className, optionsOverrides, url, themeId } = props;
2321
const { options } = useSpecOptions(themeId, optionsOverrides);
24-
const isDevMode = process.env.NODE_ENV === 'development';
2522

26-
if ((isDevMode && isSpecFile === false) || !spec) {
23+
if (getIsExternalUrl(url)) {
2724
return (
2825
<div className={clsx(['redocusaurus', className])}>
2926
<RedocStandalone specUrl={url} options={options} />
3027
</div>
3128
);
3229
}
3330

34-
return <ServerRedoc {...props} spec={spec} />;
31+
return <ServerRedoc {...props} />;
3532
}
3633

3734
export default Redoc;

packages/docusaurus-theme-redoc/src/theme/Redoc/ServerRedoc.tsx

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import React from 'react';
22
import clsx from 'clsx';
33
import '../../global';
4-
import { Redoc as RedocComponent, RedocRawOptions } from 'redoc';
5-
import { SpecProps } from '../../types/common';
6-
import { useSpec } from '../../utils/useSpec';
4+
import { Redoc as RedocComponent } from 'redoc';
5+
import useSpec from '@theme/useSpec';
76
import { ServerStyles } from './Styles';
87
import './styles.css';
98

@@ -13,22 +12,22 @@ import './styles.css';
1312
* (c) 2024 Rohit Gohri
1413
* Released under the MIT License
1514
*/
16-
function ServerRedoc(
17-
props: SpecProps & {
18-
className?: string;
19-
optionsOverrides?: RedocRawOptions;
20-
},
21-
): JSX.Element {
22-
const { className, optionsOverrides, ...specProps } = props;
23-
const { store, darkThemeOptions, lightThemeOptions, hasLogo } = useSpec(
24-
specProps,
15+
function ServerRedoc(props: RedocProps): JSX.Element {
16+
const { className, optionsOverrides, url, id, themeId } = props;
17+
const { store, spec, darkThemeOptions, lightThemeOptions, hasLogo } = useSpec(
18+
{
19+
spec: props.spec,
20+
themeId,
21+
id,
22+
},
2523
optionsOverrides,
2624
);
2725

2826
return (
2927
<>
3028
<ServerStyles
31-
specProps={specProps}
29+
spec={spec}
30+
url={url}
3231
lightThemeOptions={lightThemeOptions}
3332
darkThemeOptions={darkThemeOptions}
3433
/>

packages/docusaurus-theme-redoc/src/theme/Redoc/ServerStyles.tsx

+14-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import '../../global';
33
import useBaseUrl from '@docusaurus/useBaseUrl';
44
import { AppStore, Redoc, RedocRawOptions } from 'redoc';
5+
import type { OpenAPISpec } from 'redoc/typings/types';
56
// eslint-disable-next-line import/no-extraneous-dependencies
67
import { renderToString } from 'react-dom/server';
78
import { ServerStyleSheet } from 'styled-components';
@@ -53,22 +54,26 @@ const prefixCssSelectors = function (rules: string, className: string) {
5354
const LIGHT_MODE_PREFIX = "html:not([data-theme='dark'])";
5455
const DARK_MODE_PREFIX = "html([data-theme='dark'])";
5556

57+
export type ServerStylesProps = {
58+
spec: OpenAPISpec;
59+
url?: string;
60+
lightThemeOptions: RedocRawOptions;
61+
darkThemeOptions: RedocRawOptions;
62+
};
63+
5664
export function ServerStyles({
57-
specProps,
65+
spec,
66+
url,
5867
lightThemeOptions,
5968
darkThemeOptions,
60-
}: {
61-
specProps: SpecProps;
62-
lightThemeOptions: RedocRawOptions;
63-
darkThemeOptions: RedocRawOptions;
64-
}) {
65-
const fullUrl = useBaseUrl(specProps.url, { absolute: true });
69+
}: ServerStylesProps) {
70+
const fullUrl = useBaseUrl(url, { absolute: true });
6671
const css = {
6772
light: '',
6873
dark: '',
6974
};
7075
const lightSheet = new ServerStyleSheet();
71-
const lightStore = new AppStore(specProps.spec, fullUrl, lightThemeOptions);
76+
const lightStore = new AppStore(spec, fullUrl, lightThemeOptions);
7277
renderToString(
7378
lightSheet.collectStyles(React.createElement(Redoc, { store: lightStore })),
7479
);
@@ -78,7 +83,7 @@ export function ServerStyles({
7883
css.light = prefixCssSelectors(lightCss, LIGHT_MODE_PREFIX);
7984

8085
const darkSheet = new ServerStyleSheet();
81-
const darkStore = new AppStore(specProps.spec, fullUrl, darkThemeOptions);
86+
const darkStore = new AppStore(spec, fullUrl, darkThemeOptions);
8287
renderToString(
8388
darkSheet.collectStyles(React.createElement(Redoc, { store: darkStore })),
8489
);
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
import React from 'react';
22
import '../../global';
3-
import type { RedocRawOptions } from 'redoc';
3+
import type { ServerStylesProps } from './ServerStyles';
44

55
/**
66
* Don't hydrate/replace server styles
77
* @see https://github.com/facebook/react/issues/10923#issuecomment-338715787
88
*/
9-
export function ServerStyles(_props: {
10-
specProps: SpecProps;
11-
lightThemeOptions: RedocRawOptions;
12-
darkThemeOptions: RedocRawOptions;
13-
}) {
9+
export function ServerStyles(_props: ServerStylesProps) {
1410
return <div className="redocusaurus-styles"></div>;
1511
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { useSpec } from './useSpec';
2+
3+
export default useSpec;

packages/docusaurus-theme-redoc/src/utils/useSpec.ts packages/docusaurus-theme-redoc/src/theme/useSpec/useSpec.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { useMemo, useEffect } from 'react';
22
import useBaseUrl from '@docusaurus/useBaseUrl';
33
import useIsBrowser from '@docusaurus/useIsBrowser';
44
import { useColorMode } from '@docusaurus/theme-common';
5-
import '../global';
5+
import useSpecData from '@theme/useSpecData';
6+
import useSpecOptions from '@theme/useSpecOptions';
7+
import '../../global';
68
import { AppStore, RedocRawOptions } from 'redoc';
7-
import { SpecProps } from '../types/common';
8-
import { useSpecOptions } from './useSpecOptions';
99

1010
// the current store singleton in the app's instance
1111
let currentStore: AppStore | null = null;
@@ -17,9 +17,14 @@ let currentStore: AppStore | null = null;
1717
* Released under the MIT License
1818
*/
1919
export function useSpec(
20-
{ spec, url, themeId }: SpecProps,
20+
specInfo: SpecProps,
2121
optionsOverrides?: RedocRawOptions,
22-
) {
22+
): SpecResult {
23+
const { spec, url, themeId } = useSpecData(
24+
specInfo.id,
25+
specInfo.spec,
26+
specInfo.themeId,
27+
);
2328
const specOptions = useSpecOptions(themeId, optionsOverrides);
2429
const fullUrl = useBaseUrl(url, { absolute: true });
2530
const isBrowser = useIsBrowser();
@@ -36,6 +41,7 @@ export function useSpec(
3641
// @ts-expect-error extra prop
3742
hasLogo: !!spec.info?.['x-logo'],
3843
store: currentStore,
44+
spec,
3945
};
4046
}, [isBrowser, spec, fullUrl, specOptions]);
4147

packages/docusaurus-theme-redoc/src/theme/useSpecData.ts

-18
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { useSpecData } from './useSpecData';
2+
3+
export default useSpecData;

0 commit comments

Comments
 (0)