Merge pull request #1 from Redocly/master

pull from original
This commit is contained in:
Sergey Dubovyk 2019-10-01 11:58:26 +03:00 committed by GitHub
commit 20298bf560
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 149 additions and 58 deletions

View File

@ -1,3 +1,36 @@
# [2.0.0-rc.16](https://github.com/Redocly/redoc/compare/v2.0.0-rc.15...v2.0.0-rc.16) (2019-09-30)
### Bug Fixes
* fix scrollYOffset when SSR ([d09c1c1](https://github.com/Redocly/redoc/commit/d09c1c1))
# [2.0.0-rc.15](https://github.com/Redocly/redoc/compare/v2.0.0-rc.14...v2.0.0-rc.15) (2019-09-30)
### Bug Fixes
* auth section appears twice ([5aa7784](https://github.com/Redocly/redoc/commit/5aa7784)), closes [#818](https://github.com/Redocly/redoc/issues/818)
* clicking on group title breaks first tag ([4649683](https://github.com/Redocly/redoc/commit/4649683)), closes [#1034](https://github.com/Redocly/redoc/issues/1034)
* do not crash on empty scopes ([e787d9e](https://github.com/Redocly/redoc/commit/e787d9e)), closes [#1044](https://github.com/Redocly/redoc/issues/1044)
* false-positive recursive detection with allOf at the same level ([faa74d6](https://github.com/Redocly/redoc/commit/faa74d6))
* fix scrollYOffset when SSR ([21258a5](https://github.com/Redocly/redoc/commit/21258a5))
* left menu item before group is not highligted ([67e2a8f](https://github.com/Redocly/redoc/commit/67e2a8f)), closes [#1033](https://github.com/Redocly/redoc/issues/1033)
* remove excessive whitespace between md sections on small screens ([e318fb3](https://github.com/Redocly/redoc/commit/e318fb3)), closes [#874](https://github.com/Redocly/redoc/issues/874)
* use url-template dependency ([#1008](https://github.com/Redocly/redoc/issues/1008)) ([32a464a](https://github.com/Redocly/redoc/commit/32a464a)), closes [#1007](https://github.com/Redocly/redoc/issues/1007)
### Features
* **cli:** added support for JSON string value for --options CLI argument ([#1047](https://github.com/Redocly/redoc/issues/1047)) ([2a28130](https://github.com/Redocly/redoc/commit/2a28130)), closes [#797](https://github.com/Redocly/redoc/issues/797)
* **cli:** add `disableGoogleFont` parameter to cli ([#1045](https://github.com/Redocly/redoc/issues/1045)) ([aceb343](https://github.com/Redocly/redoc/commit/aceb343))
* new option expandDefaultServerVariables ([#1014](https://github.com/Redocly/redoc/issues/1014)) ([0360dce](https://github.com/Redocly/redoc/commit/0360dce))
# [2.0.0-rc.14](https://github.com/Redocly/redoc/compare/v2.0.0-rc.13...v2.0.0-rc.14) (2019-08-07)

View File

@ -245,6 +245,7 @@ You can use all of the following options with standalone version on <redoc> tag
* `onlyRequiredInSamples` - shows only required fields in request samples.
* `jsonSampleExpandLevel` - set the default expand level for JSON payload samples (responses and request body). Special value 'all' expands all levels. The default value is `2`.
* `menuToggle` - if true clicking second time on expanded menu item will collapse it, default `false`
* `expandDefaultServerVariables` - enable expanding default server variables, default `false`
* `theme` - ReDoc theme. Not documented yet. For details check source code: [theme.ts](https://github.com/Redocly/redoc/blob/master/src/theme.ts)
## Advanced usage of standalone version

View File

@ -69,9 +69,11 @@ YargsParser.command(
watch: argv.watch as boolean,
templateFileName: argv.template as string,
templateOptions: argv.templateOptions || {},
redocOptions: argv.options || {},
redocOptions: getObjectOrJSON(argv.options),
};
console.log(config);
try {
await serve(argv.port as number, argv.spec as string, config);
} catch (e) {
@ -124,7 +126,7 @@ YargsParser.command(
disableGoogleFont: argv.disableGoogleFont as boolean,
templateFileName: argv.template as string,
templateOptions: argv.templateOptions || {},
redocOptions: argv.options || {},
redocOptions: getObjectOrJSON(argv.options),
};
try {
@ -353,3 +355,15 @@ function handleError(error: Error) {
console.error(error.stack);
process.exit(1);
}
function getObjectOrJSON(options) {
try {
return options && typeof options === 'string'
? JSON.parse(options) : options
? options
: {};
} catch (e) {
console.log(`Encountered error:\n${options}\nis not a valid JSON.`);
handleError(e);
}
}

View File

@ -1,6 +1,6 @@
{
"name": "redoc-cli",
"version": "0.8.6",
"version": "0.9.2",
"description": "ReDoc's Command Line Interface",
"main": "index.js",
"bin": "index.js",
@ -19,7 +19,7 @@
"node-libs-browser": "^2.2.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"redoc": "2.0.0-rc.13",
"redoc": "2.0.0-rc.16",
"styled-components": "^4.3.2",
"tslib": "^1.10.0",
"yargs": "^13.3.0"

View File

@ -629,10 +629,10 @@ domain-browser@^1.1.1:
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
dompurify@^1.0.11:
version "1.0.11"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-1.0.11.tgz#fe0f4a40d147f7cebbe31a50a1357539cfc1eb4d"
integrity sha512-XywCTXZtc/qCX3iprD1pIklRVk/uhl8BKpkTxr+ZyMVUzSUg7wkQXRBp/euJ5J5moa1QvfpvaPQVP71z1O59dQ==
dompurify@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.0.3.tgz#5cc4965a487d54aedba6ba9634b137cfbd7eb50d"
integrity sha512-q006uOkD2JGSJgF0qBt7rVhUvUPBWCxpGayALmHvXx2iNlMfNVz7PDGeXEUjNGgIDjADz59VZCv6UE3U8XRWVw==
elliptic@^6.0.0:
version "6.5.0"
@ -1092,7 +1092,7 @@ mem@^4.0.0:
mimic-fn "^2.0.0"
p-is-promise "^2.0.0"
memoize-one@^5.0.0, memoize-one@^5.0.5:
memoize-one@^5.0.0, memoize-one@~5.0.5:
version "5.0.5"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.5.tgz#8cd3809555723a07684afafcd6f756072ac75d7e"
integrity sha512-ey6EpYv0tEaIbM/nTDOpHciXUvd+ackQrJgEzBwemhZZIWZjcyodqEcrmqDy2BKRTM3a65kKBV4WtLXJDt26SQ==
@ -1161,10 +1161,10 @@ mobx-react-lite@1.4.0:
resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-1.4.0.tgz#193beb5fdddf17ae61542f65ff951d84db402351"
integrity sha512-5xCuus+QITQpzKOjAOIQ/YxNhOl/En+PlNJF+5QU4Qxn9gnNMJBbweAdEW3HnuVQbfqDYEUnkGs5hmkIIStehg==
mobx-react@^6.1.1:
version "6.1.1"
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.1.1.tgz#24a2c8a3393890fa732b4efd34cc6dcccf6e0e7a"
integrity sha512-hjACWCTpxZf9Sv1YgWF/r6HS6Nsly1SYF22qBJeUE3j+FMfoptgjf8Zmcx2d6uzA07Cezwap5Cobq9QYa0MKUw==
mobx-react@^6.1.3:
version "6.1.3"
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.1.3.tgz#ad07880ea60cdcdb2a7e2a0d54e01379710cf00a"
integrity sha512-eT/jO9dYIoB1AlZwI2VC3iX0gPOeOIqZsiwg7tDJV1B7Z69h+TZZL3dgOE0UeS2zoHhGeKbP+K+OLeLMnnkGnA==
dependencies:
mobx-react-lite "1.4.0"
@ -1540,10 +1540,10 @@ react-dropdown@^1.6.4:
dependencies:
classnames "^2.2.3"
react-hot-loader@^4.12.10:
version "4.12.10"
resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.12.10.tgz#b3457c0f733423c4827c6d2672e50c9f8bedaf6b"
integrity sha512-dX+ZUigxQijWLsKPnxc0khuCt2sYiZ1W59LgSBMOLeGSG3+HkknrTlnJu6BCNdhYxbEQkGvBsr7zXlNWYUIhAQ==
react-hot-loader@^4.12.14:
version "4.12.14"
resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.12.14.tgz#81ca06ffda0b90aad15d6069339f73ed6428340a"
integrity sha512-ecxH4eBvEaJ9onT8vkEmK1FAAJUh1PqzGqds9S3k+GeihSp7nKAp4fOxytO+Ghr491LiBD38jaKyDXYnnpI9pQ==
dependencies:
fast-levenshtein "^2.0.6"
global "^4.3.0"
@ -1602,35 +1602,35 @@ readdirp@^3.1.1:
dependencies:
picomatch "^2.0.4"
redoc@2.0.0-rc.13:
version "2.0.0-rc.13"
resolved "https://registry.yarnpkg.com/redoc/-/redoc-2.0.0-rc.13.tgz#243e4d003ca9bd45006c215d8856a3b1229ca8bb"
integrity sha512-t0vlss1TIUknYXTI9RIZ1nRMyIW/pjo4KMMDFOMdRq5/8jopkNyf37q25BwBuAJfDxQV+tIUoy6o+rAAffeDkQ==
redoc@2.0.0-rc.16:
version "2.0.0-rc.16"
resolved "https://registry.yarnpkg.com/redoc/-/redoc-2.0.0-rc.16.tgz#01d5dafba6ae266a5934dc9904b87bc8a175b222"
integrity sha512-5YWk7NBebYZ8xMbKXA1sD++QsSh7NbnB2sStJRKLeP/rU4oX586SIqHXl+MW1OhIZW44mYFMHpYzxpZKCllk9w==
dependencies:
classnames "^2.2.6"
decko "^1.2.0"
dompurify "^1.0.11"
dompurify "^2.0.3"
eventemitter3 "^4.0.0"
json-pointer "^0.6.0"
json-schema-ref-parser "^6.1.0"
lunr "2.3.6"
mark.js "^8.11.1"
marked "^0.7.0"
memoize-one "^5.0.5"
mobx-react "^6.1.1"
memoize-one "~5.0.5"
mobx-react "^6.1.3"
openapi-sampler "1.0.0-beta.15"
perfect-scrollbar "^1.4.0"
polished "^3.4.1"
prismjs "^1.17.1"
prop-types "^15.7.2"
react-dropdown "^1.6.4"
react-hot-loader "^4.12.10"
react-hot-loader "^4.12.14"
react-tabs "^3.0.0"
slugify "^1.3.4"
slugify "^1.3.5"
stickyfill "^1.1.1"
swagger2openapi "^5.3.1"
tslib "^1.10.0"
uri-template-lite "^19.4.0"
url-template "^2.0.8"
reftools@^1.0.8:
version "1.0.8"
@ -1782,10 +1782,10 @@ signal-exit@^3.0.0:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
slugify@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.3.4.tgz#78d2792d7222b55cd9fc81fa018df99af779efeb"
integrity sha512-KP0ZYk5hJNBS8/eIjGkFDCzGQIoZ1mnfQRYS5WM3273z+fxGWXeN0fkwf2ebEweydv9tioZIHGZKoF21U07/nw==
slugify@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.3.5.tgz#90210678818b6d533cb060083aed0e8238133508"
integrity sha512-5VCnH7aS13b0UqWOs7Ef3E5rkhFe8Od+cp7wybFv5mv/sYSRkucZlJX0bamAJky7b2TTtGvrJBWVdpdEicsSrA==
source-map@^0.5.0:
version "0.5.7"
@ -2002,10 +2002,10 @@ uglify-js@^3.1.4:
commander "~2.20.0"
source-map "~0.6.1"
uri-template-lite@^19.4.0:
version "19.4.0"
resolved "https://registry.yarnpkg.com/uri-template-lite/-/uri-template-lite-19.4.0.tgz#cbc2c072cf4931428a2f9d3aea36b8254a33cce5"
integrity sha512-VY8dgwyMwnCztkzhq0cA/YhNmO+YZqow//5FdmgE2fZU/JPi+U0rPL7MRDi0F+Ch4vJ7nYidWzeWAeY7uywe9g==
url-template@^2.0.8:
version "2.0.8"
resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21"
integrity sha1-/FZaPMy/93MMd19WQflVV5FDnyE=
url@^0.11.0:
version "0.11.0"

View File

@ -1,6 +1,6 @@
{
"name": "redoc",
"version": "2.0.0-rc.14",
"version": "2.0.0-rc.16",
"description": "ReDoc",
"repository": {
"type": "git",

View File

@ -1,14 +1,16 @@
import { SECTION_ATTR } from '../services/MenuStore';
import styled, { media } from '../styled-components';
export const MiddlePanel = styled.div`
export const MiddlePanel = styled.div<{ compact?: boolean }>`
width: calc(100% - ${props => props.theme.rightPanel.width});
padding: 0 ${props => props.theme.spacing.sectionHorizontal}px;
${media.lessThan('medium', true)`
${({ compact, theme }) =>
media.lessThan('medium', true)`
width: 100%;
padding: ${props =>
`${props.theme.spacing.sectionVertical}px ${props.theme.spacing.sectionHorizontal}px`};
padding: ${`${compact ? 0 : theme.spacing.sectionVertical}px ${
theme.spacing.sectionHorizontal
}px`};
`};
`;

View File

@ -60,7 +60,7 @@ export class ContentItem extends React.Component<ContentItemProps> {
}
}
const middlePanelWrap = component => <MiddlePanel>{component}</MiddlePanel>;
const middlePanelWrap = component => <MiddlePanel compact={true}>{component}</MiddlePanel>;
@observer
export class SectionItem extends React.Component<ContentItemProps> {
@ -71,7 +71,7 @@ export class SectionItem extends React.Component<ContentItemProps> {
return (
<>
<Row>
<MiddlePanel>
<MiddlePanel compact={level !== 1}>
<Header>
<ShareLink to={this.props.item.id} />
{name}

View File

@ -49,7 +49,7 @@ export class OAuthFlow extends React.PureComponent<OAuthFlowProps> {
<strong> Scopes: </strong>
</div>
<ul>
{Object.keys(flow!.scopes).map(scope => (
{Object.keys(flow!.scopes || {}).map(scope => (
<li key={scope}>
<code>{scope}</code> - <Markdown inline={true} source={flow!.scopes[scope] || ''} />
</li>

View File

@ -87,7 +87,7 @@ export class StickyResponsiveSidebar extends React.Component<
> {
static contextType = OptionsContext;
context!: React.ContextType<typeof OptionsContext>;
state: StickySidebarState = {};
state: StickySidebarState = { offsetTop: '0px' };
stickyElement: Element;
@ -122,7 +122,7 @@ export class StickyResponsiveSidebar extends React.Component<
render() {
const open = this.props.menu.sideBarOpened;
const top = this.state.offsetTop || this.getScrollYOffset(this.context);
const top = this.state.offsetTop;
return (
<>

View File

@ -116,7 +116,7 @@ export class MenuStore {
}
if (isScrolledDown) {
const el = this.getElementAt(itemIdx + 1);
const el = this.getElementAtOrFirstChild(itemIdx + 1);
if (this.scroll.isElementBellow(el)) {
break;
}
@ -163,6 +163,18 @@ export class MenuStore {
return (item && querySelector(`[${SECTION_ATTR}="${item.id}"]`)) || null;
}
/**
* get section/operation DOM Node related to the item or if it is group item, returns first item of the group
* @param idx item absolute index
*/
getElementAtOrFirstChild(idx: number): Element | null {
let item = this.flatItems[idx];
if (item && item.type === 'group') {
item = item.items[0];
}
return (item && querySelector(`[${SECTION_ATTR}="${item.id}"]`)) || null;
}
/**
* current active item
*/
@ -189,6 +201,11 @@ export class MenuStore {
if ((this.activeItem && this.activeItem.id) === (item && item.id)) {
return;
}
if (item && item.type === 'group') {
return;
}
this.deactivate(this.activeItem);
if (!item) {
this.history.replace('', rewriteHistory);

View File

@ -4,7 +4,11 @@ import { OpenAPIRef, OpenAPISchema, OpenAPISpec, Referenced } from '../types';
import { appendToMdHeading, IS_BROWSER } from '../utils/';
import { JsonPointer } from '../utils/JsonPointer';
import { isNamedDefinition, SECURITY_DEFINITIONS_COMPONENT_NAME } from '../utils/openapi';
import {
isNamedDefinition,
SECURITY_DEFINITIONS_COMPONENT_NAME,
SECURITY_DEFINITIONS_JSX_NAME,
} from '../utils/openapi';
import { buildComponentComment, MarkdownRenderer } from './MarkdownRenderer';
import { RedocNormalizedOptions } from './RedocNormalizedOptions';
@ -40,6 +44,7 @@ class RefCounter {
export class OpenAPIParser {
specUrl?: string;
spec: OpenAPISpec;
mergeRefs: Set<string>;
private _refCounter: RefCounter = new RefCounter();
@ -53,6 +58,8 @@ export class OpenAPIParser {
this.spec = spec;
this.mergeRefs = new Set();
const href = IS_BROWSER ? window.location.href : '';
if (typeof specUrl === 'string') {
this.specUrl = urlResolve(href, specUrl);
@ -74,7 +81,10 @@ export class OpenAPIParser {
) {
// Automatically inject Authentication section with SecurityDefinitions component
const description = spec.info.description || '';
if (!MarkdownRenderer.containsComponent(description, SECURITY_DEFINITIONS_COMPONENT_NAME)) {
if (
!MarkdownRenderer.containsComponent(description, SECURITY_DEFINITIONS_COMPONENT_NAME) &&
!MarkdownRenderer.containsComponent(description, SECURITY_DEFINITIONS_JSX_NAME)
) {
const comment = buildComponentComment(SECURITY_DEFINITIONS_COMPONENT_NAME);
spec.info.description = appendToMdHeading(description, 'Authentication', comment);
}
@ -176,7 +186,12 @@ export class OpenAPIParser {
schema: OpenAPISchema,
$ref?: string,
forceCircular: boolean = false,
used$Refs = new Set<string>(),
): MergedOpenAPISchema {
if ($ref) {
used$Refs.add($ref);
}
schema = this.hoistOneOfs(schema);
if (schema.allOf === undefined) {
@ -198,16 +213,25 @@ export class OpenAPIParser {
receiver.items = { ...receiver.items };
}
const allOfSchemas = schema.allOf.map(subSchema => {
const allOfSchemas = schema.allOf
.map(subSchema => {
if (subSchema && subSchema.$ref && used$Refs.has(subSchema.$ref)) {
return undefined;
}
const resolved = this.deref(subSchema, forceCircular);
const subRef = subSchema.$ref || undefined;
const subMerged = this.mergeAllOf(resolved, subRef, forceCircular);
const subMerged = this.mergeAllOf(resolved, subRef, forceCircular, used$Refs);
receiver.parentRefs!.push(...(subMerged.parentRefs || []));
return {
$ref: subRef,
schema: subMerged,
};
});
})
.filter(child => child !== undefined) as Array<{
$ref: string | undefined;
schema: MergedOpenAPISchema;
}>;
for (const { $ref: subSchemaRef, schema: subSchema } of allOfSchemas) {
if (