-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support externalValue for examples
- Loading branch information
1 parent
309901b
commit 2cdfcd2
Showing
9 changed files
with
179 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import * as React from 'react'; | ||
|
||
import { StyledPre } from '../../common-elements/samples'; | ||
import { ExampleModel } from '../../services/models'; | ||
import { isJsonLike, langFromMime } from '../../utils'; | ||
import { JsonViewer } from '../JsonViewer/JsonViewer'; | ||
import { SourceCodeWithCopy } from '../SourceCode/SourceCode'; | ||
import { ExampleValue } from './ExampleValue'; | ||
import { useExternalExample } from './exernalExampleHook'; | ||
|
||
export interface ExampleProps { | ||
example: ExampleModel; | ||
mimeType: string; | ||
} | ||
|
||
export function Example({ example, mimeType }: ExampleProps) { | ||
if (example.value === undefined && example.externalValueUrl) { | ||
return <ExternalExample example={example} mimeType={mimeType} />; | ||
} else { | ||
return <ExampleValue value={example.value} mimeType={mimeType} />; | ||
} | ||
} | ||
|
||
export function ExternalExample({ example, mimeType }: ExampleProps) { | ||
let value = useExternalExample(example, mimeType); | ||
|
||
if (value === undefined) { | ||
return <span>Loading...</span>; | ||
} | ||
|
||
if (value instanceof Error) { | ||
console.log(value); | ||
return ( | ||
<StyledPre> | ||
Error loading external example: <br /> | ||
<a className={'token string'} href={example.externalValueUrl} target="_blank"> | ||
{example.externalValueUrl} | ||
</a> | ||
</StyledPre> | ||
); | ||
} | ||
|
||
if (isJsonLike(mimeType)) { | ||
return <JsonViewer data={value} />; | ||
} else { | ||
if (typeof value === 'object') { | ||
// just in case example was cached as json but used as non-json | ||
value = JSON.stringify(value, null, 2); | ||
} | ||
return <SourceCodeWithCopy lang={langFromMime(mimeType)} source={value} />; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import * as React from 'react'; | ||
|
||
import { isJsonLike, langFromMime } from '../../utils/openapi'; | ||
import { JsonViewer } from '../JsonViewer/JsonViewer'; | ||
import { SourceCodeWithCopy } from '../SourceCode/SourceCode'; | ||
|
||
export interface ExampleValueProps { | ||
value: any; | ||
mimeType: string; | ||
} | ||
|
||
export function ExampleValue({ value, mimeType }: ExampleValueProps) { | ||
if (isJsonLike(mimeType)) { | ||
return <JsonViewer data={value} />; | ||
} else { | ||
return <SourceCodeWithCopy lang={langFromMime(mimeType)} source={value} />; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { useEffect, useRef, useState } from 'react'; | ||
import { ExampleModel } from '../../services/models/Example'; | ||
|
||
export function useExternalExample(example: ExampleModel, mimeType: string) { | ||
const [, setIsLoading] = useState(true); // to trigger component reload | ||
|
||
const value = useRef<any>(undefined); | ||
const prevRef = useRef<ExampleModel | undefined>(undefined); | ||
|
||
if (prevRef.current !== example) { | ||
value.current = undefined; | ||
} | ||
|
||
prevRef.current = example; | ||
|
||
useEffect( | ||
() => { | ||
const load = async () => { | ||
setIsLoading(true); | ||
try { | ||
value.current = await example.getExternalValue(mimeType); | ||
} catch (e) { | ||
value.current = e; | ||
} | ||
setIsLoading(false); | ||
}; | ||
|
||
load(); | ||
}, | ||
[example, mimeType], | ||
); | ||
|
||
return value.current; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,55 @@ | ||
import { resolve as urlResolve } from 'url'; | ||
|
||
import { OpenAPIExample, Referenced } from '../../types'; | ||
import { isJsonLike } from '../../utils/openapi'; | ||
import { OpenAPIParser } from '../OpenAPIParser'; | ||
|
||
const externalExamplesCache: { [url: string]: Promise<any> } = {}; | ||
|
||
export class ExampleModel { | ||
value: any; | ||
summary?: string; | ||
description?: string; | ||
externalValue?: string; | ||
externalValueUrl?: string; | ||
|
||
constructor(parser: OpenAPIParser, infoOrRef: Referenced<OpenAPIExample>) { | ||
Object.assign(this, parser.deref(infoOrRef)); | ||
const example = parser.deref(infoOrRef); | ||
this.value = example.value; | ||
this.summary = example.summary; | ||
this.description = example.description; | ||
if (example.externalValue) { | ||
this.externalValueUrl = urlResolve(parser.specUrl || '', example.externalValue); | ||
} | ||
parser.exitRef(infoOrRef); | ||
} | ||
|
||
getExternalValue(mimeType: string): Promise<any> { | ||
if (!this.externalValueUrl) { | ||
return Promise.resolve(undefined); | ||
} | ||
|
||
if (externalExamplesCache[this.externalValueUrl]) { | ||
return externalExamplesCache[this.externalValueUrl]; | ||
} | ||
|
||
externalExamplesCache[this.externalValueUrl] = fetch(this.externalValueUrl).then(res => { | ||
return res.text().then(txt => { | ||
if (!res.ok) { | ||
return Promise.reject(new Error(txt)); | ||
} | ||
|
||
if (isJsonLike(mimeType)) { | ||
try { | ||
return JSON.parse(txt); | ||
} catch (e) { | ||
return txt; | ||
} | ||
} else { | ||
return txt; | ||
} | ||
}); | ||
}); | ||
|
||
return externalExamplesCache[this.externalValueUrl]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters