mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-09 22:54:51 +03:00
mediatype is properly picked and stuff like uuid in uri is also properly handlled,
This commit is contained in:
parent
07ad2ccecf
commit
b1dc621212
|
@ -22,13 +22,16 @@ const big = window.location.search.indexOf('big') > -1;
|
||||||
const swagger = window.location.search.indexOf('swagger') > -1; // compatibility mode ?
|
const swagger = window.location.search.indexOf('swagger') > -1; // compatibility mode ?
|
||||||
|
|
||||||
let specUrl = swagger ? 'swagger.yaml' : big ? 'big-openapi.json' : 'openapi.yaml';
|
let specUrl = swagger ? 'swagger.yaml' : big ? 'big-openapi.json' : 'openapi.yaml';
|
||||||
// specUrl = 'intent.json';
|
specUrl = 'intent.json';
|
||||||
|
|
||||||
// specUrl = 'swagger.yaml';
|
// specUrl = 'swagger.yaml';
|
||||||
specUrl = 'petstore.json';
|
// specUrl = 'petstore.json';
|
||||||
|
|
||||||
let store;
|
let store;
|
||||||
const options: RedocRawOptions = { nativeScrollbars: false, enableConsole: true, providedByName: 'Intent ApiDocs by Nutanix', providedByUri: 'http://www.nutanix.com' };
|
const headers = {
|
||||||
|
'x-nutanix-client': 'ui',
|
||||||
|
};
|
||||||
|
const options: RedocRawOptions = { nativeScrollbars: false, enableConsole: true, providedByName: 'Intent ApiDocs by Nutanix', providedByUri: 'http://www.nutanix.com', additionalHeaders: headers };
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
const spec = await loadAndBundleSpec(specUrl);
|
const spec = await loadAndBundleSpec(specUrl);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { observer } from 'mobx-react';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { SendButton } from '../../common-elements/buttons';
|
import { SendButton } from '../../common-elements/buttons';
|
||||||
import { ConsoleActionsRow } from '../../common-elements/panels';
|
import { ConsoleActionsRow } from '../../common-elements/panels';
|
||||||
import { OperationModel } from '../../services/models';
|
import { FieldModel, OperationModel } from '../../services/models';
|
||||||
import { OpenAPISchema } from '../../types';
|
import { OpenAPISchema } from '../../types';
|
||||||
import { PayloadSamples } from '../PayloadSamples/PayloadSamples';
|
import { PayloadSamples } from '../PayloadSamples/PayloadSamples';
|
||||||
import { SourceCodeWithCopy } from '../SourceCode/SourceCode';
|
import { SourceCodeWithCopy } from '../SourceCode/SourceCode';
|
||||||
|
@ -12,6 +12,9 @@ const qs = require('qs');
|
||||||
|
|
||||||
export interface ConsoleViewerProps {
|
export interface ConsoleViewerProps {
|
||||||
operation: OperationModel;
|
operation: OperationModel;
|
||||||
|
additionalHeaders?: object;
|
||||||
|
queryParamPrefix?: string;
|
||||||
|
queryParamSuffix?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConsoleViewerState {
|
export interface ConsoleViewerState {
|
||||||
|
@ -26,6 +29,7 @@ export interface Schema {
|
||||||
@observer
|
@observer
|
||||||
export class ConsoleViewer extends React.Component<ConsoleViewerProps, ConsoleViewerState> {
|
export class ConsoleViewer extends React.Component<ConsoleViewerProps, ConsoleViewerState> {
|
||||||
operation: OperationModel;
|
operation: OperationModel;
|
||||||
|
additionalHeaders: object;
|
||||||
visited = new Set();
|
visited = new Set();
|
||||||
private consoleEditor: ConsoleEditor;
|
private consoleEditor: ConsoleEditor;
|
||||||
|
|
||||||
|
@ -39,46 +43,77 @@ export class ConsoleViewer extends React.Component<ConsoleViewerProps, ConsoleVi
|
||||||
const ace = this.consoleEditor && this.consoleEditor.editor;
|
const ace = this.consoleEditor && this.consoleEditor.editor;
|
||||||
// const value = ace && ace.editor &&
|
// const value = ace && ace.editor &&
|
||||||
const schema = this.getSchema();
|
const schema = this.getSchema();
|
||||||
const { operation } = this.props;
|
const { operation, additionalHeaders = {} } = this.props;
|
||||||
|
|
||||||
// console.log('Schema: ' + JSON.stringify(schema, null, 2));
|
// console.log('Schema: ' + JSON.stringify(schema, null, 2));
|
||||||
let value = ace && ace.editor.getValue();
|
let value = ace && ace.editor.getValue();
|
||||||
|
|
||||||
const ref = schema && schema._$ref;
|
const ref = schema && schema._$ref;
|
||||||
|
|
||||||
// var valid = window && window.ajv.validate({ $ref: `specs.json${ref}` }, value);
|
// var valid = window && window.ajv.validate({ $ref: `specs.json${ref}` }, value);
|
||||||
// console.log(JSON.stringify(window.ajv.errors));
|
// console.log(JSON.stringify(window.ajv.errors));
|
||||||
// if (!valid) {
|
// if (!valid) {
|
||||||
// console.warn('INVALID REQUEST!');
|
// console.warn('INVALID REQUEST!');
|
||||||
// }
|
// }
|
||||||
|
const content = operation.requestBody && operation.requestBody.content;
|
||||||
|
const mediaType = content && content.mediaTypes[content.activeMimeIdx];
|
||||||
const endpoint = {
|
const endpoint = {
|
||||||
method: operation.httpVerb,
|
method: operation.httpVerb,
|
||||||
path: operation.servers[0].url + operation.path,
|
path: operation.servers[0].url + operation.path,
|
||||||
};
|
};
|
||||||
console.log('Value: ' + value);
|
// console.log('Value: ' + value);
|
||||||
if (value) {
|
if (value) {
|
||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
}
|
}
|
||||||
|
const contentType = mediaType && mediaType.name || 'application/json';
|
||||||
const result = await this.invoke(endpoint, value);
|
const contentTypeHeader = { 'Content-Type': contentType };
|
||||||
console.log('Result: ' + JSON.stringify(result));
|
const headers = { ...additionalHeaders, ...contentTypeHeader };
|
||||||
|
let result;
|
||||||
|
try {
|
||||||
|
result = await this.invoke(endpoint, value, headers);
|
||||||
this.setState({
|
this.setState({
|
||||||
result,
|
result,
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
this.setState({
|
||||||
|
result: error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we have a url like foo/bar/{uuid} uuid will be replaced with what user has typed in.
|
||||||
|
*/
|
||||||
|
addParamsToUrl(url: string, params: Array<FieldModel>) {
|
||||||
|
const queryParamPrefix = '{';
|
||||||
|
const queryParamSuffix = '}';
|
||||||
|
|
||||||
|
for (const fieldModel of params) {
|
||||||
|
console.log(fieldModel.name + ' ' + url);
|
||||||
|
console.log(fieldModel.$value);
|
||||||
|
if (url.indexOf(`${queryParamPrefix}${fieldModel.name}${queryParamSuffix}`) > -1 && fieldModel.$value.length > 0) {
|
||||||
|
url = url.replace(`${queryParamPrefix}${fieldModel.name}${queryParamSuffix}`, fieldModel.$value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.split(queryParamPrefix).length > 1) {
|
||||||
|
console.error('** we have missing query params ** ', url);
|
||||||
|
throw Error(`** we have missing query params ** ${url}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
async invoke(endpoint, body) {
|
async invoke(endpoint, body, headers = {}) {
|
||||||
const headers = { 'Content-Type': 'application/json' };
|
|
||||||
try {
|
try {
|
||||||
let url = endpoint.path;
|
const { operation } = this.props;
|
||||||
|
let url = this.addParamsToUrl(endpoint.path, operation.parameters || []);
|
||||||
if (endpoint.method.toLocaleLowerCase() === 'get') {
|
if (endpoint.method.toLocaleLowerCase() === 'get') {
|
||||||
url = url + '?' + qs.stringify(body || '');
|
url = url + '?' + qs.stringify(body || '');
|
||||||
}
|
}
|
||||||
|
|
||||||
const myHeaders = new Headers();
|
const myHeaders = new Headers();
|
||||||
myHeaders.append('Content-Type', 'application/json');
|
for (const [key, value] of Object.entries(headers)) {
|
||||||
|
myHeaders.append(key, `${value}`);
|
||||||
|
}
|
||||||
|
|
||||||
const request = new Request(url, {
|
const request = new Request(url, {
|
||||||
method: endpoint.method,
|
method: endpoint.method,
|
||||||
|
|
|
@ -41,6 +41,9 @@ export class Endpoint extends React.Component<EndpointProps, EndpointState> {
|
||||||
const { operation, inverted, hideHostname } = this.props;
|
const { operation, inverted, hideHostname } = this.props;
|
||||||
const { expanded } = this.state;
|
const { expanded } = this.state;
|
||||||
|
|
||||||
|
if (operation && operation.parameters && operation.parameters.length > 0) {
|
||||||
|
console.log('USER INPUT VALUE:: ' + operation.parameters[0]['$value']);
|
||||||
|
}
|
||||||
// TODO: highlight server variables, e.g. https://{user}.test.com
|
// TODO: highlight server variables, e.g. https://{user}.test.com
|
||||||
return (
|
return (
|
||||||
<OptionsContext.Consumer>
|
<OptionsContext.Consumer>
|
||||||
|
|
|
@ -30,6 +30,12 @@ export class Field extends React.PureComponent<FieldProps> {
|
||||||
toggle = () => {
|
toggle = () => {
|
||||||
this.props.field.toggle();
|
this.props.field.toggle();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onFieldChange = (e) => {
|
||||||
|
console.log('Textfield value is ' + e.target.placeholder + ' - ' + e.target.value);
|
||||||
|
this.props.field.setValue(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { className, field, isLast } = this.props;
|
const { className, field, isLast } = this.props;
|
||||||
const { name, expanded, deprecated, required, kind } = field;
|
const { name, expanded, deprecated, required, kind } = field;
|
||||||
|
@ -63,7 +69,7 @@ export class Field extends React.PureComponent<FieldProps> {
|
||||||
<FieldDetails {...this.props} />
|
<FieldDetails {...this.props} />
|
||||||
</PropertyDetailsCell>
|
</PropertyDetailsCell>
|
||||||
{field && field.in === 'path' &&
|
{field && field.in === 'path' &&
|
||||||
<td><TextField placeholder="foo" /></td>
|
<td><TextField placeholder={field.name} onChange={this.onFieldChange} /></td>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
{field.expanded &&
|
{field.expanded &&
|
||||||
|
|
|
@ -100,7 +100,7 @@ export class Operation extends React.Component<OperationProps, OperationState> {
|
||||||
{!options.pathInMiddlePanel && <Endpoint operation={operation} />}
|
{!options.pathInMiddlePanel && <Endpoint operation={operation} />}
|
||||||
{executeMode &&
|
{executeMode &&
|
||||||
<div>
|
<div>
|
||||||
<ConsoleViewer operation={operation} />
|
<ConsoleViewer operation={operation} additionalHeaders={options.additionalHeaders} queryParamPrefix={options.queryParamPrefix} queryParamSuffix={options.queryParamSuffix} />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{!executeMode &&
|
{!executeMode &&
|
||||||
|
|
|
@ -7,6 +7,7 @@ export interface RedocRawOptions {
|
||||||
scrollYOffset?: number | string | (() => number);
|
scrollYOffset?: number | string | (() => number);
|
||||||
hideHostname?: boolean | string;
|
hideHostname?: boolean | string;
|
||||||
enableConsole?: boolean;
|
enableConsole?: boolean;
|
||||||
|
additionalHeaders?: object;
|
||||||
expandResponses?: string | 'all';
|
expandResponses?: string | 'all';
|
||||||
requiredPropsFirst?: boolean | string;
|
requiredPropsFirst?: boolean | string;
|
||||||
noAutoAuth?: boolean | string;
|
noAutoAuth?: boolean | string;
|
||||||
|
@ -18,6 +19,8 @@ export interface RedocRawOptions {
|
||||||
|
|
||||||
providedByName?: string;
|
providedByName?: string;
|
||||||
providedByUri?: string;
|
providedByUri?: string;
|
||||||
|
queryParamPrefix?: string;
|
||||||
|
queryParamSuffix?: string;
|
||||||
|
|
||||||
unstable_ignoreMimeParameters?: boolean;
|
unstable_ignoreMimeParameters?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -98,8 +101,11 @@ export class RedocNormalizedOptions {
|
||||||
untrustedSpec: boolean;
|
untrustedSpec: boolean;
|
||||||
hideDownloadButton: boolean;
|
hideDownloadButton: boolean;
|
||||||
enableConsole: boolean;
|
enableConsole: boolean;
|
||||||
|
additionalHeaders: object;
|
||||||
providedByName: string;
|
providedByName: string;
|
||||||
providedByUri: string;
|
providedByUri: string;
|
||||||
|
queryParamPrefix: string;
|
||||||
|
queryParamSuffix: string;
|
||||||
|
|
||||||
/* tslint:disable-next-line */
|
/* tslint:disable-next-line */
|
||||||
unstable_ignoreMimeParameters: boolean;
|
unstable_ignoreMimeParameters: boolean;
|
||||||
|
@ -116,8 +122,11 @@ export class RedocNormalizedOptions {
|
||||||
this.untrustedSpec = argValueToBoolean(raw.untrustedSpec);
|
this.untrustedSpec = argValueToBoolean(raw.untrustedSpec);
|
||||||
this.hideDownloadButton = argValueToBoolean(raw.hideDownloadButton);
|
this.hideDownloadButton = argValueToBoolean(raw.hideDownloadButton);
|
||||||
this.enableConsole = argValueToBoolean(raw.enableConsole);
|
this.enableConsole = argValueToBoolean(raw.enableConsole);
|
||||||
|
this.additionalHeaders = raw.additionalHeaders || {};
|
||||||
this.providedByName = raw.providedByName || 'Documentation Powered by ReDoc';
|
this.providedByName = raw.providedByName || 'Documentation Powered by ReDoc';
|
||||||
this.providedByUri = raw.providedByUri || 'https://github.com/Rebilly/ReDoc';
|
this.providedByUri = raw.providedByUri || 'https://github.com/Rebilly/ReDoc';
|
||||||
|
this.queryParamPrefix = raw.queryParamPrefix || '{';
|
||||||
|
this.queryParamSuffix = raw.queryParamSuffix || '}';
|
||||||
|
|
||||||
this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters);
|
this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { SchemaModel } from './Schema';
|
||||||
*/
|
*/
|
||||||
export class FieldModel {
|
export class FieldModel {
|
||||||
@observable expanded: boolean = false;
|
@observable expanded: boolean = false;
|
||||||
|
@observable $value: string = '';
|
||||||
schema: SchemaModel;
|
schema: SchemaModel;
|
||||||
name: string;
|
name: string;
|
||||||
required: boolean;
|
required: boolean;
|
||||||
|
@ -46,4 +46,9 @@ export class FieldModel {
|
||||||
toggle() {
|
toggle() {
|
||||||
this.expanded = !this.expanded;
|
this.expanded = !this.expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
setValue(value: string) {
|
||||||
|
this.$value = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
parseparseFetchFetch
|
//parseparseFetchFetch
|
Loading…
Reference in New Issue
Block a user