Merge branch 'master' of https://github.com/nutanix/ReDoc into add-validation

This commit is contained in:
Harjeet Singh 2018-06-19 15:37:35 -07:00
commit 4f0bb8c57b
21 changed files with 165 additions and 56 deletions

View File

@ -1,6 +1,6 @@
* *
!bundles/* !bundles/*
!typings/* !typings/**/*
!package.json !package.json
!README.md !README.md
!LICENSE !LICENSE

View File

@ -15,7 +15,7 @@ env:
addons: addons:
chrome: stable chrome: stable
before_script: npm run bundle before_script: npm run bundle
script: npm test && npm run e2e-ci script: npm test && [ "${TRAVIS_PULL_REQUEST}" = "false" ] && npm run e2e-ci || npm run e2e
after_script: cat ./coverage/lcov.info | coveralls after_script: cat ./coverage/lcov.info | coveralls
before_deploy: npm run compile:cli && npm run declarations before_deploy: npm run compile:cli && npm run declarations
deploy: deploy:

View File

@ -1,3 +1,26 @@
<a name="2.0.0-alpha.24"></a>
# [2.0.0-alpha.24](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.23...v2.0.0-alpha.24) (2018-06-01)
### Bug Fixes
* temporary downgrade marked as it introduced breaking changes and a few bugs ([902f97a](https://github.com/Rebilly/ReDoc/commit/902f97a))
<a name="2.0.0-alpha.23"></a>
# [2.0.0-alpha.23](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.22...v2.0.0-alpha.23) (2018-05-31)
### Bug Fixes
* **cli:** make positional arguments required and handle errors in serve and bundle manually ([#518](https://github.com/Rebilly/ReDoc/issues/518)) ([370d08a](https://github.com/Rebilly/ReDoc/commit/370d08a))
* fix typings on npm ([d957ad7](https://github.com/Rebilly/ReDoc/commit/d957ad7))
* fix vertical line misaligned in firefox ([bde08f1](https://github.com/Rebilly/ReDoc/commit/bde08f1)), closes [#503](https://github.com/Rebilly/ReDoc/issues/503)
* mergeAllOf takes items into account ([#511](https://github.com/Rebilly/ReDoc/issues/511)) ([47b2177](https://github.com/Rebilly/ReDoc/commit/47b2177))
<a name="2.0.0-alpha.22"></a> <a name="2.0.0-alpha.22"></a>
# [2.0.0-alpha.22](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.21...v2.0.0-alpha.22) (2018-05-29) # [2.0.0-alpha.22](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.21...v2.0.0-alpha.22) (2018-05-29)

View File

@ -212,12 +212,13 @@ You can use all of the following options with standalone version on <redoc> tag
## Advanced usage of standalone version ## Advanced usage of standalone version
Instead of adding `spec-url` attribute to the `<redoc>` element you can initialize ReDoc via globally exposed `Redoc` object: Instead of adding `spec-url` attribute to the `<redoc>` element you can initialize ReDoc via globally exposed `Redoc` object:
```js ```js
Redoc.init(specOrSpecUrl, options, element) Redoc.init(specOrSpecUrl, options, element, callback?)
``` ```
- `specOrSpecUrl` is either JSON object with specification or an URL to the spec in `JSON` or `YAML` format - `specOrSpecUrl` is either JSON object with specification or an URL to the spec in `JSON` or `YAML` format
- `options` [options object](#redoc-options-object) - `options` [options object](#redoc-options-object)
- `element` DOM element to put ReDoc into - `element` DOM element to put ReDoc into
- `callback` (optional) - callback to be called after Redoc has been fully rendered
```js ```js
Redoc.init('http://petstore.swagger.io/v2/swagger.json', { Redoc.init('http://petstore.swagger.io/v2/swagger.json', {

View File

@ -32,7 +32,7 @@ const BUNDLES_DIR = dirname(require.resolve('redoc'));
/* tslint:disable-next-line */ /* tslint:disable-next-line */
YargsParser.command( YargsParser.command(
'serve [spec]', 'serve <spec>',
'start the server', 'start the server',
yargs => { yargs => {
yargs.positional('spec', { yargs.positional('spec', {
@ -60,16 +60,22 @@ YargsParser.command(
return yargs; return yargs;
}, },
async argv => { async argv => {
await serve(argv.port, argv.spec, { const config = {
ssr: argv.ssr, ssr: argv.ssr,
watch: argv.watch, watch: argv.watch,
templateFileName: argv.template, templateFileName: argv.template,
redocOptions: argv.options || {}, redocOptions: argv.options || {},
}); };
try {
await serve(argv.port, argv.spec, config);
} catch (e) {
handleError(e);
}
}, },
) )
.command( .command(
'bundle [spec]', 'bundle <spec>',
'bundle spec into zero-dependency HTML-file', 'bundle spec into zero-dependency HTML-file',
yargs => { yargs => {
yargs.positional('spec', { yargs.positional('spec', {
@ -99,16 +105,22 @@ YargsParser.command(
return yargs; return yargs;
}, },
async argv => { async argv => {
await bundle(argv.spec, { const config = {
ssr: true, ssr: true,
output: argv.o, output: argv.o,
cdn: argv.cdn, cdn: argv.cdn,
title: argv.title, title: argv.title,
templateFileName: argv.template, templateFileName: argv.template,
redocOptions: argv.options || {}, redocOptions: argv.options || {},
}); };
try {
await bundle(argv.spec, config);
} catch (e) {
handleError(e);
}
}, },
) )
.demandCommand() .demandCommand()
.options('t', { .options('t', {
alias: 'template', alias: 'template',
@ -117,10 +129,6 @@ YargsParser.command(
}) })
.options('options', { .options('options', {
describe: 'ReDoc options, use dot notation, e.g. options.nativeScrollbars', describe: 'ReDoc options, use dot notation, e.g. options.nativeScrollbars',
})
.fail((message, error) => {
console.log(error.stack);
process.exit(1);
}).argv; }).argv;
async function serve(port: number, pathToSpec: string, options: Options = {}) { async function serve(port: number, pathToSpec: string, options: Options = {}) {
@ -229,13 +237,13 @@ async function getPageHTML(
ssr ssr
? 'hydrate(__redoc_state, container);' ? 'hydrate(__redoc_state, container);'
: `init("spec.json", ${JSON.stringify(redocOptions)}, container)` : `init("spec.json", ${JSON.stringify(redocOptions)}, container)`
}; };
</script>`, </script>`,
redocHead: ssr redocHead: ssr
? (cdn ? (cdn
? '<script src="https://unpkg.com/redoc@next/bundles/redoc.standalone.js"></script>' ? '<script src="https://unpkg.com/redoc@next/bundles/redoc.standalone.js"></script>'
: `<script>${redocStandaloneSrc}</script>`) + css : `<script>${redocStandaloneSrc}</script>`) + css
: '<script src="redoc.standalone.js"></script>', : '<script src="redoc.standalone.js"></script>',
title, title,
}); });
@ -296,3 +304,8 @@ function isURL(str: string): boolean {
function escapeUnicode(str) { function escapeUnicode(str) {
return str.replace(/\u2028|\u2029/g, m => '\\u202' + (m === '\u2028' ? '8' : '9')); return str.replace(/\u2028|\u2029/g, m => '\\u202' + (m === '\u2028' ? '8' : '9'));
} }
function handleError(error: Error) {
console.error(error.stack);
process.exit(1);
}

4
custom.d.ts vendored
View File

@ -18,10 +18,6 @@ declare module '*.css' {
declare var __REDOC_VERSION__: string; declare var __REDOC_VERSION__: string;
declare var __REDOC_REVISION__: string; declare var __REDOC_REVISION__: string;
declare type Dict<T> = {
[key: string]: T;
};
interface Element { interface Element {
scrollIntoViewIfNeeded(centerIfNeeded?: boolean): void; scrollIntoViewIfNeeded(centerIfNeeded?: boolean): void;
} }

View File

@ -11,7 +11,7 @@ const demos = [
value: 'https://api.apis.guru/v2/specs/googleapis.com/calendar/v3/swagger.yaml', value: 'https://api.apis.guru/v2/specs/googleapis.com/calendar/v3/swagger.yaml',
label: 'Google Calendar', label: 'Google Calendar',
}, },
{ value: 'https://api.apis.guru/v2/specs/slack.com/1.0.3/swagger.yaml', label: 'Slack' }, { value: 'https://api.apis.guru/v2/specs/slack.com/1.0.6/swagger.yaml', label: 'Slack' },
{ value: 'https://api.apis.guru/v2/specs/zoom.us/2.0.0/swagger.yaml', label: 'Zoom.us' }, { value: 'https://api.apis.guru/v2/specs/zoom.us/2.0.0/swagger.yaml', label: 'Zoom.us' },
{ {
value: 'https://api.apis.guru/v2/specs/graphhopper.com/1.0/swagger.yaml', value: 'https://api.apis.guru/v2/specs/graphhopper.com/1.0/swagger.yaml',

View File

@ -200,6 +200,16 @@ Extends OpenAPI [Parameter Object](http://swagger.io/specification/#parameterObj
###### Usage in ReDoc ###### Usage in ReDoc
`x-examples` are rendered in the JSON tab on the right panel of ReDoc. `x-examples` are rendered in the JSON tab on the right panel of ReDoc.
### Response Object vendor extensions
Extneds OpeanAPI [Response Object](https://swagger.io/specification/#responseObject)
#### x-summary
| Field Name | Type | Description |
| :------------- | :------: | :---------- |
| x-summary | string | a short summary of the response |
###### Usage in ReDoc
If specified, `x-summary` is used as the response button text. Description is rendered under the button.
### Schema Object vendor extensions ### Schema Object vendor extensions
Extends OpenAPI [Schema Object](http://swagger.io/specification/#schemaObject) Extends OpenAPI [Schema Object](http://swagger.io/specification/#schemaObject)

View File

@ -1,6 +1,6 @@
{ {
"name": "redoc", "name": "redoc",
"version": "2.0.0-alpha.22", "version": "2.0.0-alpha.24",
"description": "ReDoc", "description": "ReDoc",
"repository": { "repository": {
"type": "git", "type": "git",
@ -51,10 +51,10 @@
"license-check": "license-checker --production --onlyAllow 'MIT;ISC;Apache-2.0;BSD-2-Clause;BSD-3-Clause' --summary" "license-check": "license-checker --production --onlyAllow 'MIT;ISC;Apache-2.0;BSD-2-Clause;BSD-3-Clause' --summary"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.0.0-beta.40", "@babel/core": "7.0.0-beta.47",
"@babel/plugin-syntax-decorators": "^7.0.0-beta.42", "@babel/plugin-syntax-decorators": "7.0.0-beta.47",
"@babel/plugin-syntax-jsx": "^7.0.0-beta.42", "@babel/plugin-syntax-jsx": "7.0.0-beta.47",
"@babel/plugin-syntax-typescript": "^7.0.0-beta.42", "@babel/plugin-syntax-typescript": "7.0.0-beta.47",
"@cypress/webpack-preprocessor": "2.0.1", "@cypress/webpack-preprocessor": "2.0.1",
"@types/dompurify": "^0.0.31", "@types/dompurify": "^0.0.31",
"@types/enzyme": "^3.1.8", "@types/enzyme": "^3.1.8",
@ -138,7 +138,7 @@
"json-schema-ref-parser": "^5.0.0", "json-schema-ref-parser": "^5.0.0",
"lunr": "^2.2.1", "lunr": "^2.2.1",
"mark.js": "^8.11.1", "mark.js": "^8.11.1",
"marked": "^0.4.0", "marked": "0.3.18",
"mobx": "^4.3.0", "mobx": "^4.3.0",
"mobx-react": "^5.0.0", "mobx-react": "^5.0.0",
"openapi-sampler": "1.0.0-beta.12", "openapi-sampler": "1.0.0-beta.12",

View File

@ -117,7 +117,7 @@ export const InnerPropertiesWrap = styled.div`
`; `;
export const PropertiesTable = styled.table` export const PropertiesTable = styled.table`
border-collapse: collapse; border-collapse: separate;
border-radius: 3px; border-radius: 3px;
font-size: ${props => props.theme.baseFont.size}; font-size: ${props => props.theme.baseFont.size};

View File

@ -28,12 +28,7 @@ export class FieldDetails extends React.PureComponent<FieldProps> {
<div> <div>
<TypePrefix>{schema.typePrefix}</TypePrefix> <TypePrefix>{schema.typePrefix}</TypePrefix>
<TypeName>{schema.displayType}</TypeName> <TypeName>{schema.displayType}</TypeName>
{schema.format && ( {schema.format && <TypeFormat> &lt;{schema.format}&gt; </TypeFormat>}
<TypeFormat>
{' <'}
{schema.format}>
</TypeFormat>
)}
{schema.title && <TypeTitle> ({schema.title}) </TypeTitle>} {schema.title && <TypeTitle> ({schema.title}) </TypeTitle>}
<ConstraintsView constraints={schema.constraints} /> <ConstraintsView constraints={schema.constraints} />
{schema.nullable && <NullableLabel> Nullable </NullableLabel>} {schema.nullable && <NullableLabel> Nullable </NullableLabel>}

View File

@ -21,9 +21,10 @@ export class MediaTypeSamples extends React.Component<PayloadSamplesProps> {
const sampleView = isJsonLike(mimeType) const sampleView = isJsonLike(mimeType)
? sample => <JsonViewer data={sample} /> ? sample => <JsonViewer data={sample} />
: sample => : sample =>
(sample && <SourceCodeWithCopy lang={langFromMime(mimeType)} source={sample} />) || { (sample !== undefined && (
noSample, <SourceCodeWithCopy lang={langFromMime(mimeType)} source={sample} />
}; )) ||
noSample;
const examplesNames = Object.keys(examples); const examplesNames = Object.keys(examples);
if (examplesNames.length === 0) { if (examplesNames.length === 0) {

View File

@ -8,6 +8,7 @@ import { DropdownOrLabel } from '../DropdownOrLabel/DropdownOrLabel';
import { MediaTypesSwitch } from '../MediaTypeSwitch/MediaTypesSwitch'; import { MediaTypesSwitch } from '../MediaTypeSwitch/MediaTypesSwitch';
import { Schema } from '../Schema'; import { Schema } from '../Schema';
import { Markdown } from '../Markdown/Markdown';
import { ResponseHeaders } from './ResponseHeaders'; import { ResponseHeaders } from './ResponseHeaders';
import { ResponseDetailsWrap, StyledResponseTitle } from './styled.elements'; import { ResponseDetailsWrap, StyledResponseTitle } from './styled.elements';
@ -18,11 +19,11 @@ export class ResponseView extends React.Component<{ response: ResponseModel }> {
}; };
render() { render() {
const { headers, type, description, code, expanded, content } = this.props.response; const { headers, type, summary, description, code, expanded, content } = this.props.response;
const mimes = const mimes =
content === undefined ? [] : content.mediaTypes.filter(mime => mime.schema !== undefined); content === undefined ? [] : content.mediaTypes.filter(mime => mime.schema !== undefined);
const empty = headers.length === 0 && mimes.length === 0; const empty = headers.length === 0 && mimes.length === 0 && !description;
return ( return (
<div> <div>
@ -30,13 +31,14 @@ export class ResponseView extends React.Component<{ response: ResponseModel }> {
onClick={this.toggle} onClick={this.toggle}
type={type} type={type}
empty={empty} empty={empty}
title={description || ''} title={summary || ''}
code={code} code={code}
opened={expanded} opened={expanded}
/> />
{expanded && {expanded &&
!empty && ( !empty && (
<ResponseDetailsWrap> <ResponseDetailsWrap>
{description && <Markdown source={description} />}
<ResponseHeaders headers={headers} /> <ResponseHeaders headers={headers} />
<MediaTypesSwitch content={content} renderDropdown={this.renderDropdown}> <MediaTypesSwitch content={content} renderDropdown={this.renderDropdown}>
{({ schema }) => { {({ schema }) => {

View File

@ -6,6 +6,7 @@ import { IMenuItem, MenuStore } from '../../services/MenuStore';
import { MenuItems } from './MenuItems'; import { MenuItems } from './MenuItems';
import { PerfectScrollbar } from '../../common-elements/perfect-scrollbar'; import { PerfectScrollbar } from '../../common-elements/perfect-scrollbar';
import { RedocAttribution } from './styled.elements';
@observer @observer
export class SideMenu extends React.Component<{ menu: MenuStore }> { export class SideMenu extends React.Component<{ menu: MenuStore }> {
@ -29,6 +30,11 @@ export class SideMenu extends React.Component<{ menu: MenuStore }> {
) : ( ) : (
<PerfectScrollbar updateFn={this.saveScrollUpdate}> <PerfectScrollbar updateFn={this.saveScrollUpdate}>
<MenuItems items={store.items} onActivate={this.activate} root={true} /> <MenuItems items={store.items} onActivate={this.activate} root={true} />
<RedocAttribution>
<a target="_blank" href="https://github.com/Rebilly/ReDoc">
Documentation Powered by ReDoc
</a>
</RedocAttribution>
</PerfectScrollbar> </PerfectScrollbar>
) )
} }

View File

@ -160,3 +160,21 @@ export const MenuItemTitle = withProps<{ width?: string }>(styled.span)`
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
`; `;
export const RedocAttribution = styled.div`
font-size: 0.8em;
margin-top: ${({ theme }) => `${theme.spacingUnit / 2}px`};
padding: ${({ theme }) => `0 ${theme.spacingUnit}px`};
text-align: left;
opacity: 0.7;
a,
a:visited,
a:hover {
color: ${({ theme }) => theme.colors.text} !important;
border-top: 1px solid #e1e1e1;
padding-top: 10px;
display: block;
}
`;

View File

@ -233,6 +233,15 @@ export class OpenAPIParser {
} }
} }
if (subSchema.items !== undefined) {
receiver.items = receiver.items || {};
// merge inner properties
receiver.items = this.mergeAllOf(
{ allOf: [receiver.items, subSchema.items] },
$ref + '/items',
);
}
if (subSchema.required !== undefined) { if (subSchema.required !== undefined) {
receiver.required = (receiver.required || []).concat(subSchema.required); receiver.required = (receiver.required || []).concat(subSchema.required);
} }

View File

@ -10,7 +10,9 @@ import { OpenAPIExternalDocumentation, OpenAPIServer } from '../../types';
import { import {
getOperationSummary, getOperationSummary,
getStatusCodeType,
isAbsolutePath, isAbsolutePath,
isStatusCode,
JsonPointer, JsonPointer,
mergeParams, mergeParams,
sortByRequired, sortByRequired,
@ -99,10 +101,15 @@ export class OperationModel implements IMenuItem {
let hasSuccessResponses = false; let hasSuccessResponses = false;
this.responses = Object.keys(operationSpec.responses || []) this.responses = Object.keys(operationSpec.responses || [])
.filter(code => { .filter(code => {
if (parseInt(code, 10) >= 100 && parseInt(code, 10) <= 399) { if (code === 'default') {
return true;
}
if (getStatusCodeType(code) === 'success') {
hasSuccessResponses = true; hasSuccessResponses = true;
} }
return isNumeric(code) || code === 'default';
return isStatusCode(code);
}) // filter out other props (e.g. x-props) }) // filter out other props (e.g. x-props)
.map(code => { .map(code => {
return new ResponseModel( return new ResponseModel(

View File

@ -13,6 +13,7 @@ export class ResponseModel {
content?: MediaContentModel; content?: MediaContentModel;
code: string; code: string;
summary: string;
description: string; description: string;
type: string; type: string;
headers: FieldModel[] = []; headers: FieldModel[] = [];
@ -32,7 +33,15 @@ export class ResponseModel {
if (info.content !== undefined) { if (info.content !== undefined) {
this.content = new MediaContentModel(parser, info.content, false, options); this.content = new MediaContentModel(parser, info.content, false, options);
} }
this.description = info.description || '';
if (info['x-summary'] !== undefined) {
this.summary = info['x-summary'];
this.description = info.description || '';
} else {
this.summary = info.description || '';
this.description = '';
}
this.type = getStatusCodeType(code, defaultAsError); this.type = getStatusCodeType(code, defaultAsError);
const headers = info.headers; const headers = info.headers;

View File

@ -1,3 +1,8 @@
export * from './open-api'; export * from './open-api';
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
declare global {
type Dict<T> = {
[key: string]: T;
};
}

View File

@ -6,21 +6,35 @@ import {
OpenAPISchema, OpenAPISchema,
Referenced, Referenced,
} from '../types'; } from '../types';
import { isNumeric } from './helpers';
export function getStatusCodeType(statusCode: string | number, defaultAsError = false): string { function isWildcardStatusCode(statusCode: string | number): statusCode is string {
return typeof statusCode === 'string' && /\dxx/i.test(statusCode);
}
export function isStatusCode(statusCode: string) {
return statusCode === 'default' || isNumeric(statusCode) || isWildcardStatusCode(statusCode);
}
export function getStatusCodeType(statusCode: string, defaultAsError = false): string {
if (statusCode === 'default') { if (statusCode === 'default') {
return defaultAsError ? 'error' : 'success'; return defaultAsError ? 'error' : 'success';
} }
if (statusCode < 100 || statusCode > 599) { let code = parseInt(statusCode, 10);
if (isWildcardStatusCode(statusCode)) {
code *= 100; // parseInt('2xx') parses to 2
}
if (code < 100 || code > 599) {
throw new Error('invalid HTTP code'); throw new Error('invalid HTTP code');
} }
let res = 'success'; let res = 'success';
if (statusCode >= 300 && statusCode < 400) { if (code >= 300 && code < 400) {
res = 'redirect'; res = 'redirect';
} else if (statusCode >= 400) { } else if (code >= 400) {
res = 'error'; res = 'error';
} else if (statusCode < 200) { } else if (code < 200) {
res = 'info'; res = 'info';
} }
return res; return res;

View File

@ -14,7 +14,7 @@
dependencies: dependencies:
"@babel/highlight" "7.0.0-beta.46" "@babel/highlight" "7.0.0-beta.46"
"@babel/core@^7.0.0-beta.40": "@babel/core@7.0.0-beta.47":
version "7.0.0-beta.47" version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.47.tgz#b9c164fb9a1e1083f067c236a9da1d7a7d759271" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.47.tgz#b9c164fb9a1e1083f067c236a9da1d7a7d759271"
dependencies: dependencies:
@ -98,19 +98,19 @@
esutils "^2.0.2" esutils "^2.0.2"
js-tokens "^3.0.0" js-tokens "^3.0.0"
"@babel/plugin-syntax-decorators@^7.0.0-beta.42": "@babel/plugin-syntax-decorators@7.0.0-beta.47":
version "7.0.0-beta.47" version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.0.0-beta.47.tgz#a42f10fcd651940bc475d93b3ac23432b4a8a293" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.0.0-beta.47.tgz#a42f10fcd651940bc475d93b3ac23432b4a8a293"
dependencies: dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47" "@babel/helper-plugin-utils" "7.0.0-beta.47"
"@babel/plugin-syntax-jsx@^7.0.0-beta.42": "@babel/plugin-syntax-jsx@7.0.0-beta.47":
version "7.0.0-beta.47" version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.47.tgz#f3849d94288695d724bd205b4f6c3c99e4ec24a4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.47.tgz#f3849d94288695d724bd205b4f6c3c99e4ec24a4"
dependencies: dependencies:
"@babel/helper-plugin-utils" "7.0.0-beta.47" "@babel/helper-plugin-utils" "7.0.0-beta.47"
"@babel/plugin-syntax-typescript@^7.0.0-beta.42": "@babel/plugin-syntax-typescript@7.0.0-beta.47":
version "7.0.0-beta.47" version "7.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.0.0-beta.47.tgz#108d4c83ff48ddcb8f0532252a9892e805ddc64c" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.0.0-beta.47.tgz#108d4c83ff48ddcb8f0532252a9892e805ddc64c"
dependencies: dependencies:
@ -6542,9 +6542,9 @@ mark.js@^8.11.1:
version "8.11.1" version "8.11.1"
resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5" resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5"
marked@^0.4.0: marked@0.3.18:
version "0.4.0" version "0.3.18"
resolved "https://registry.yarnpkg.com/marked/-/marked-0.4.0.tgz#9ad2c2a7a1791f10a852e0112f77b571dce10c66" resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.18.tgz#3ef058cd926101849b92a7a7c15db18c7fc76b2f"
math-expression-evaluator@^1.2.14: math-expression-evaluator@^1.2.14:
version "1.2.17" version "1.2.17"