From 49f04d321f79a35049679dff4538c5dd4d09ce36 Mon Sep 17 00:00:00 2001 From: Till Kolter Date: Sun, 23 Aug 2020 22:44:18 +0200 Subject: [PATCH] feat: Add MDX Slate style --- .vscode/settings.json | 7 +- demo/playground/hmr-playground.tsx | 8 +- package-lock.json | 34 ++++--- package.json | 2 + src/common-elements/flex.ts | 15 +++ src/components/ContentItems/ContentItems.tsx | 10 +- src/components/Redoc/Redoc.tsx | 48 +++++---- src/components/SideMenu/MenuItems.tsx | 14 ++- src/components/SideMenu/SideMenu.tsx | 15 ++- src/components/SideMenu/styled.elements.ts | 10 +- src/markdown/TryOutWidget.tsx | 21 ++++ src/markdown/auth.mdx | 55 ++++++++++ src/markdown/code/Highlighter/index.tsx | 37 +++++++ src/markdown/index.tsx | 100 +++++++++++++++++++ src/markdown/plugins/export-toc.ts | 38 +++++++ src/markdown/welcome.mdx | 11 ++ src/services/AppStore.ts | 2 +- src/services/MenuStore.ts | 30 ++++-- src/services/models/ExtraContent.ts | 58 +++++++++++ src/services/models/index.ts | 14 +-- src/types/mdx.d.ts | 1 + 21 files changed, 461 insertions(+), 69 deletions(-) create mode 100644 src/common-elements/flex.ts create mode 100644 src/markdown/TryOutWidget.tsx create mode 100644 src/markdown/auth.mdx create mode 100644 src/markdown/code/Highlighter/index.tsx create mode 100644 src/markdown/index.tsx create mode 100644 src/markdown/plugins/export-toc.ts create mode 100644 src/markdown/welcome.mdx create mode 100644 src/services/models/ExtraContent.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 3a19d2f7..f878daed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,9 @@ { "editor.formatOnSave": true, - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "[typescript]": { + "editor.codeActionsOnSave": { + "source.organizeImports": false + } + }, } diff --git a/demo/playground/hmr-playground.tsx b/demo/playground/hmr-playground.tsx index 39ddfa51..03222e4f 100644 --- a/demo/playground/hmr-playground.tsx +++ b/demo/playground/hmr-playground.tsx @@ -27,15 +27,13 @@ const specUrl = let store; const options: RedocRawOptions = { - nativeScrollbars: false, - maxDisplayedEnumValues: 3, expandAllSchemaFields: true, + hideHttpVerbs: true, hideShelfIcon: true, - hideHttpVerbs: true + maxDisplayedEnumValues: 3, + nativeScrollbars: false, }; -console.log('options', options) - async function init() { const spec = await loadAndBundleSpec(specUrl); store = new AppStore(spec, specUrl, options); diff --git a/package-lock.json b/package-lock.json index cbe4e52a..e51d7eb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1973,8 +1973,7 @@ "@mdx-js/react": { "version": "1.6.16", "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.16.tgz", - "integrity": "sha512-+FhuSVOPo7+4fZaRwWuCSRUcZkJOkZu0rfAbBKvoCg1LWb1Td8Vzi0DTLORdSvgWNbU6+EL40HIgwTOs00x2Jw==", - "dev": true + "integrity": "sha512-+FhuSVOPo7+4fZaRwWuCSRUcZkJOkZu0rfAbBKvoCg1LWb1Td8Vzi0DTLORdSvgWNbU6+EL40HIgwTOs00x2Jw==" }, "@mdx-js/util": { "version": "1.6.16", @@ -9098,6 +9097,20 @@ "property-information": "^5.0.0", "vfile": "^4.0.0", "web-namespaces": "^1.0.0" + }, + "dependencies": { + "hastscript": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.1.2.tgz", + "integrity": "sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ==", + "dev": true, + "requires": { + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + } + } } }, "hast-util-is-element": { @@ -9175,18 +9188,6 @@ "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==", "dev": true }, - "hastscript": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.1.2.tgz", - "integrity": "sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ==", - "dev": true, - "requires": { - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" - } - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -15192,6 +15193,11 @@ } } }, + "prism-react-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.1.1.tgz", + "integrity": "sha512-MgMhSdHuHymNRqD6KM3eGS0PNqgK9q4QF5P0yoQQvpB6jNjeSAi3jcSAz0Sua/t9fa4xDOMar9HJbLa08gl9ug==" + }, "prismjs": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.20.0.tgz", diff --git a/package.json b/package.json index 4ce7c5d4..bdb04e13 100644 --- a/package.json +++ b/package.json @@ -140,6 +140,7 @@ "styled-components": "^4.1.1" }, "dependencies": { + "@mdx-js/react": "^1.6.16", "@types/node": "^13.11.1", "classnames": "^2.2.6", "decko": "^1.2.0", @@ -155,6 +156,7 @@ "openapi-sampler": "^1.0.0-beta.16", "perfect-scrollbar": "^1.4.0", "polished": "^3.6.5", + "prism-react-renderer": "^1.1.1", "prismjs": "^1.20.0", "prop-types": "^15.7.2", "react-dropdown-aria": "^2.0.7", diff --git a/src/common-elements/flex.ts b/src/common-elements/flex.ts new file mode 100644 index 00000000..1eae0a5d --- /dev/null +++ b/src/common-elements/flex.ts @@ -0,0 +1,15 @@ +import styled from 'styled-components' + +export const Flex = styled.div` + display: flex; + justify-content: ${(props) => props.justifyContent}; + width: 100%; +`; + +export const HFlex = styled(Flex)` + flex-direction: row; +`; + +export const VFlex = styled(Flex)` + flex-direction: column; +`; diff --git a/src/components/ContentItems/ContentItems.tsx b/src/components/ContentItems/ContentItems.tsx index 2766887a..71fb7de9 100644 --- a/src/components/ContentItems/ContentItems.tsx +++ b/src/components/ContentItems/ContentItems.tsx @@ -17,9 +17,11 @@ export class ContentItems extends React.Component<{ if (items.length === 0) { return null; } - return items.map(item => { - return ; - }); + return items + .filter((item) => item.type !== 'extra') + .map((item) => { + return ; + }); } } @@ -61,7 +63,7 @@ export class ContentItem extends React.Component { } } -const middlePanelWrap = component => {component}; +const middlePanelWrap = (component) => {component}; @observer export class SectionItem extends React.Component { diff --git a/src/components/Redoc/Redoc.tsx b/src/components/Redoc/Redoc.tsx index 2b43e77d..9d51e662 100644 --- a/src/components/Redoc/Redoc.tsx +++ b/src/components/Redoc/Redoc.tsx @@ -1,5 +1,6 @@ import * as PropTypes from 'prop-types'; import * as React from 'react'; +import { MDXProvider } from '@mdx-js/react'; import { ThemeProvider } from '../../styled-components'; import { OptionsProvider } from '../OptionsProvider'; @@ -15,6 +16,8 @@ import { ApiContentWrap, BackgroundStub, RedocWrap } from './styled.elements'; import { SearchBox } from '../SearchBox/SearchBox'; import { StoreProvider } from '../StoreBuilder'; +import { sections, components } from '../../markdown'; + export interface RedocProps { store: AppStore; } @@ -41,26 +44,31 @@ export class Redoc extends React.Component { - - - - {(!options.disableSearch && ( - - )) || - null} - - - - - - - - + + + + + {(!options.disableSearch && ( + + )) || + null} + + + + + {sections.map((MDXComponent, idx) => { + return ; + })} + + + + + diff --git a/src/components/SideMenu/MenuItems.tsx b/src/components/SideMenu/MenuItems.tsx index f8791343..480ed4c7 100644 --- a/src/components/SideMenu/MenuItems.tsx +++ b/src/components/SideMenu/MenuItems.tsx @@ -2,6 +2,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { IMenuItem } from '../../services'; +import { ExtraContent } from '../../services/models/ExtraContent'; import { MenuItem } from './MenuItem'; import { MenuItemUl } from './styled.elements'; @@ -12,6 +13,7 @@ export interface MenuItemsProps { onActivate?: (item: IMenuItem) => void; style?: React.CSSProperties; root?: boolean; + extra?: any; className?: string; } @@ -19,7 +21,7 @@ export interface MenuItemsProps { @observer export class MenuItems extends React.Component { render() { - const { items, root, className } = this.props; + const { items, root, className, extra } = this.props; const expanded = this.props.expanded == null ? true : this.props.expanded; return ( { expanded={expanded} {...(root ? { role: 'navigation' } : {})} > + {extra && + extra.map((headline, ids) => ( + + ))} {items.map((item, idx) => ( ))} diff --git a/src/components/SideMenu/SideMenu.tsx b/src/components/SideMenu/SideMenu.tsx index 386fed07..9ba395df 100644 --- a/src/components/SideMenu/SideMenu.tsx +++ b/src/components/SideMenu/SideMenu.tsx @@ -9,7 +9,11 @@ import { PerfectScrollbarWrap } from '../../common-elements/perfect-scrollbar'; import { RedocAttribution } from './styled.elements'; @observer -export class SideMenu extends React.Component<{ menu: MenuStore; className?: string }> { +export class SideMenu extends React.Component<{ + menu: MenuStore; + className?: string; + extra?: any; +}> { static contextType = OptionsContext; private _updateScroll?: () => void; @@ -23,7 +27,12 @@ export class SideMenu extends React.Component<{ menu: MenuStore; className?: str wheelPropagation: false, }} > - + Documentation Powered by ReDoc @@ -46,7 +55,7 @@ export class SideMenu extends React.Component<{ menu: MenuStore; className?: str }); }; - private saveScrollUpdate = upd => { + private saveScrollUpdate = (upd) => { this._updateScroll = upd; }; } diff --git a/src/components/SideMenu/styled.elements.ts b/src/components/SideMenu/styled.elements.ts index 1b14fcb8..1ef8bfc4 100644 --- a/src/components/SideMenu/styled.elements.ts +++ b/src/components/SideMenu/styled.elements.ts @@ -1,6 +1,5 @@ import * as classnames from 'classnames'; import { darken } from 'polished'; - import { deprecatedCss, ShelfIcon } from '../../common-elements'; import styled, { css, ResolvedThemeInterface } from '../../styled-components'; @@ -107,12 +106,17 @@ export const menuItemDepth = { 1: css` font-size: 0.929em; text-transform: ${({ theme }) => theme.sidebar.level1Items.textTransform}; + font-weight: ${({ theme }) => theme.sidebar.level1Items.fw}; + font-size: ${({ theme }) => theme.sidebar.level1Items.fontSize}; + color: ${({theme}) => theme.sidebar.level1Items.color}; + &:hover { color: ${props => props.theme.sidebar.activeTextColor}; } `, 2: css` - color: ${props => props.theme.sidebar.textColor}; + color: ${({ theme }) => theme.sidebar.level1Items.color}; + font-size: ${({ theme }) => theme.sidebar.level2Items.fontSize}; `, }; @@ -133,7 +137,7 @@ export const MenuItemLabel = styled.label.attrs((props: MenuItemLabelType) => ({ color: ${props => props.active ? props.theme.sidebar.activeTextColor : props.theme.sidebar.textColor}; margin: 0; - padding: 12.5px ${props => props.theme.spacing.unit * 4}px; + padding: 12.5px ${props => !props.depth || props.depth === 0 ? `${props.theme.spacing.unit * 2}px` : `${props.depth}rem`}; ${({ depth, type, theme }) => (type === 'section' && depth > 1 && 'padding-left: ' + theme.spacing.unit * 8 + 'px;') || ''} display: flex; diff --git a/src/markdown/TryOutWidget.tsx b/src/markdown/TryOutWidget.tsx new file mode 100644 index 00000000..f4f4c933 --- /dev/null +++ b/src/markdown/TryOutWidget.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; +import { HFlex } from '../common-elements/flex'; +import styled from 'styled-components'; + +const Button = styled.button` + margin-left: auto; +`; + +const TryOutWidget: React.FC = () => { + const onClick = (e) => { + e.preventDefault(); + window.location.href = 'https://en.wikipedia.org/wiki/Register'; + }; + return ( + + + + ); +}; + +export default TryOutWidget; diff --git a/src/markdown/auth.mdx b/src/markdown/auth.mdx new file mode 100644 index 00000000..e99efb6b --- /dev/null +++ b/src/markdown/auth.mdx @@ -0,0 +1,55 @@ + +# Authentication + +```bash +#!/bin/bash + +BSDEX_API_KEY=put-your-api-key-here +BSDEX_API_SECRET=put-your-api-secret-here +DATE="`date -u '+%a, %d %b %Y %T %Z'`" +# The signature is in fact HMAC signature of a few fields, currently only "date", using your API secret. +AUTHORIZATION="hmac username=\"$BSDEX_API_KEY\", algorithm=\"hmac-sha1\", headers=\"date\", signature=\"`/bin/echo -n "date: ${DATE}" | openssl sha1 -binary -hmac "${BSDEX_API_SECRET}" | base64 `\"" + +curl -v \ + -H "Date: $DATE" \ + -H "ApiKey: $BSDEX_API_KEY" \ + -H "Authorization: $AUTHORIZATION" \ + -X GET "https://api-public.prelive.cex.tribe.sh/api/v1/balance" +``` + +> And you'll receive a response such as: + +```json +[ + { + "asset_id": "btc", + "available": "0", + "locked": "0" + }, + { + "asset_id": "eur", + "available": "34163", + "locked": "123" + } +] +``` + +The requests are secured via Keyed-Hashing for Message Authentication (HMAC). + +In order to authenticate, you need to add the following headers in your HTTP requests in addition to the `Authentication` header: + +| Header | Description | Example | +| ------ | ----------- | ------- | +|`Date`| Current date in RFC7231 format | Wed, 12 Aug 2020 12:49:26 UTC | +|`ApiKey`| Your API key | put-your-api-key-here | + +The `Authentication` header's value has the pattern +`hmac username=, algorithm="hmac-sha1", headers="date", signature=""` +where `signed_date` is the base64-encoded HMAC-SHA1 signature for the expression `date: `. + +Have a look at the code example to understand the HMAC signing process better. + + + diff --git a/src/markdown/code/Highlighter/index.tsx b/src/markdown/code/Highlighter/index.tsx new file mode 100644 index 00000000..0e93185f --- /dev/null +++ b/src/markdown/code/Highlighter/index.tsx @@ -0,0 +1,37 @@ +import * as React from 'react'; +import Highlight, { defaultProps, Language } from 'prism-react-renderer'; +import styled from 'styled-components'; + +type Props = { + className: string; +}; + +const OverflowHighlighter = styled.pre` + overflow-x: scroll; +`; + +const Highligher: React.FC = ({ children, className }) => { + const language = className.replace(/language-/, ''); + + if (!children) { + return null; + } + + return ( + + {({ className, style, tokens, getLineProps, getTokenProps }) => ( + + {tokens.map((line, i) => ( +
+ {line.map((token, key) => ( + + ))} +
+ ))} +
+ )} +
+ ); +}; + +export default Highligher; diff --git a/src/markdown/index.tsx b/src/markdown/index.tsx new file mode 100644 index 00000000..9be2dd34 --- /dev/null +++ b/src/markdown/index.tsx @@ -0,0 +1,100 @@ +import * as React from 'react'; +import { + DarkRightPanel, + H1, + H2, + MiddlePanel, + PropertiesTable, + Row, + Section, + ShareLink, +} from '../common-elements'; +import Highlighter from './code/Highlighter'; + +const INCLUDES = ['auth', 'welcome']; + +const H1Comp = ({ children, ...props }) => { + return ( +

+ + {children} +

+ ); +}; + +const H2Comp = ({ children, ...props }) => ( +

+ + {children} +

+); + +const Wrapper = ({ children }) => { + const getSections = (children) => { + let currentSection: any[] = []; + let currentId: number | null = null; + let currentCodeBlocks: any[] = []; + const result: any[] = []; + + children.forEach((child) => { + const type = child.props.mdxType; + if (['h1', 'h2', 'h3', 'h4', 'h5'].includes(type)) { + if (currentSection.length > 0) { + result.push({ + id: currentId, + middle: currentSection, + right: currentCodeBlocks, + }); + } + currentId = child.props.id; + currentSection = []; + currentCodeBlocks = []; + } + if (['code', 'pre', 'blockquote'].includes(type)) { + currentCodeBlocks.push(child); + } else { + currentSection.push(child); + } + }); + + if (currentSection.length > 0) { + result.push({ id: currentId, middle: currentSection, right: currentCodeBlocks }); + } + + return result; + }; + + const sections = getSections(children); + + return ( + <> + {sections.map((section) => ( +
+ + {section.middle && {section.middle}} + {section.right && {section.right}} + +
+ ))} + + ); +}; + +const includedSections = INCLUDES.map((include) => require(`./${include}.mdx`)); + +export const sections = includedSections.map((sect) => sect.default); + +export const headings = includedSections.reduce( + (acc, section) => [...acc, ...section.headings], + [], +); + +export const components = { + code: Highlighter, + h1: H1Comp, + h2: H2Comp, + table: PropertiesTable, + wrapper: Wrapper, +}; + +export default sections; diff --git a/src/markdown/plugins/export-toc.ts b/src/markdown/plugins/export-toc.ts new file mode 100644 index 00000000..67e3bb62 --- /dev/null +++ b/src/markdown/plugins/export-toc.ts @@ -0,0 +1,38 @@ +'use strict'; + +const visit = require('unist-util-visit'); + +module.exports = slug; + +function slug() { + return transformer; +} + +// Patch slugs on heading nodes. +function transformer(ast) { + const headlines: any[] = []; + visit(ast, 'heading', visitor); + + function visitor(node) { + const data = node.data || (node.data = {}); + const props = data.hProperties || (data.hProperties = {}); + + const sectionId = `section/${data.id}`; + data.id = sectionId; + props.id = sectionId; + + visit(node, 'text', (textNode) => { + headlines.push({ depth: node.depth, id: data.id, text: textNode.value }); + }); + } + + const value = `export const headings = ${JSON.stringify(headlines)};`; + + const meta = { + default: false, + type: 'export', + value, + }; + + ast.children.splice(0, 0, meta); +} diff --git a/src/markdown/welcome.mdx b/src/markdown/welcome.mdx new file mode 100644 index 00000000..2fbaf659 --- /dev/null +++ b/src/markdown/welcome.mdx @@ -0,0 +1,11 @@ +# Hello, world! + +First intro + +## Hello subline + +Some text + +import TryOutWidget from './TryOutWidget'; + + diff --git a/src/services/AppStore.ts b/src/services/AppStore.ts index 9387c521..1e75e3a6 100644 --- a/src/services/AppStore.ts +++ b/src/services/AppStore.ts @@ -89,7 +89,7 @@ export class AppStore { this.search.indexItems(this.menu.items); } - this.disposer = observe(this.menu, 'activeItemIdx', change => { + this.disposer = observe(this.menu, 'activeItemIdx', (change) => { this.updateMarkOnMenu(change.newValue as number); }); } diff --git a/src/services/MenuStore.ts b/src/services/MenuStore.ts index 2a619af6..cbf7b75e 100644 --- a/src/services/MenuStore.ts +++ b/src/services/MenuStore.ts @@ -1,14 +1,14 @@ import { action, observable } from 'mobx'; -import { querySelector } from '../utils/dom'; -import { SpecStore } from './models'; - -import { history as historyInst, HistoryService } from './HistoryService'; -import { ScrollService } from './ScrollService'; - import { flattenByProp, SECURITY_SCHEMES_SECTION_PREFIX } from '../utils'; +import { querySelector } from '../utils/dom'; +import { history as historyInst, HistoryService } from './HistoryService'; import { GROUP_DEPTH } from './MenuBuilder'; +import { SpecStore } from './models'; +import { ScrollService } from './ScrollService'; +import { ExtraContent } from './models/ExtraContent'; +import { headings } from '../markdown'; -export type MenuItemGroupType = 'group' | 'tag' | 'section'; +export type MenuItemGroupType = 'group' | 'tag' | 'section' | 'extra'; export type MenuItemType = MenuItemGroupType | 'operation'; /** Generic interface for MenuItems */ @@ -76,7 +76,15 @@ export class MenuStore { * @param scroll scroll service instance used by this menu */ constructor(spec: SpecStore, public scroll: ScrollService, public history: HistoryService) { - this.items = spec.contentItems; + const extraItems = headings.map( + ({ id, text, depth }) => + new ExtraContent({ + id, + name: text, + depth, + }), + ); + this.items = [...extraItems, ...spec.contentItems]; this.flatItems = flattenByProp(this.items || [], 'items'); this.flatItems.forEach((item, idx) => (item.absoluteIdx = idx)); @@ -142,12 +150,12 @@ export class MenuStore { } let item: IMenuItem | undefined; - item = this.flatItems.find(i => i.id === id); + item = this.flatItems.find((i) => i.id === id); if (item) { this.activateAndScroll(item, false); } else { if (id.startsWith(SECURITY_SCHEMES_SECTION_PREFIX)) { - item = this.flatItems.find(i => SECURITY_SCHEMES_SECTION_PREFIX.startsWith(i.id)); + item = this.flatItems.find((i) => SECURITY_SCHEMES_SECTION_PREFIX.startsWith(i.id)); this.activate(item); } this.scroll.scrollIntoViewBySelector(`[${SECTION_ATTR}="${id}"]`); @@ -183,7 +191,7 @@ export class MenuStore { } getItemById = (id: string) => { - return this.flatItems.find(item => item.id === id); + return this.flatItems.find((item) => item.id === id); }; /** diff --git a/src/services/models/ExtraContent.ts b/src/services/models/ExtraContent.ts new file mode 100644 index 00000000..5a325f19 --- /dev/null +++ b/src/services/models/ExtraContent.ts @@ -0,0 +1,58 @@ +import { action, observable } from 'mobx'; +import { ContentItemModel } from '..'; +import { OpenAPIExternalDocumentation } from '../../types'; +import { IMenuItem } from '../MenuStore'; + +export class ExtraContent implements IMenuItem { + //#region IMenuItem fields + id: string; + absoluteIdx?: number; + name: string; + description?: string; + type = 'extra' as const; + content: JSX.Element + + items: ContentItemModel[] = []; + parent?: ExtraContent; + externalDocs?: OpenAPIExternalDocumentation; + + @observable + active: boolean = false; + @observable + expanded: boolean = false; + + depth: number; + level: number; + + constructor({ id, name, depth }) { + this.id = id + this.name = name + this.depth = depth + } + + /** + * set operation as active (used by side menu) + */ + @action + activate() { + this.active = true; + } + + /** + * set operation as inactive (used by side menu) + */ + @action + deactivate() { + this.active = false; + } + + expand() { + if (this.parent) { + this.parent.expand(); + } + } + + collapse() { + /* do nothing */ + } +} diff --git a/src/services/models/index.ts b/src/services/models/index.ts index a3569c5a..37928e0d 100644 --- a/src/services/models/index.ts +++ b/src/services/models/index.ts @@ -1,13 +1,15 @@ export * from '../SpecStore'; -export * from './Group.model'; -export * from './Operation'; -export * from './RequestBody'; +export * from './ApiInfo'; +export * from './Callback'; export * from './Example'; +export * from './ExtraContent'; +export * from './Field'; +export * from './Group.model'; export * from './MediaContent'; export * from './MediaType'; +export * from './Operation'; +export * from './RequestBody'; export * from './Response'; export * from './Schema'; -export * from './Field'; -export * from './ApiInfo'; export * from './SecuritySchemes'; -export * from './Callback'; + diff --git a/src/types/mdx.d.ts b/src/types/mdx.d.ts index 8df3b385..74f97abd 100644 --- a/src/types/mdx.d.ts +++ b/src/types/mdx.d.ts @@ -1,4 +1,5 @@ declare module '*.mdx' { let MDXComponent: (props: any) => JSX.Element; + export const headings: any; export default MDXComponent; }