chore: refactor path servers and pointers

This commit is contained in:
Roman Hotsiy 2020-04-07 13:09:32 +03:00
parent a306068aaa
commit a4cee05d67
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
8 changed files with 48 additions and 43 deletions

View File

@ -522,7 +522,7 @@ paths:
description: Subscription added description: Subscription added
content: content:
application/json: application/json:
schema: schema:
type: object type: object
properties: properties:
subscriptionId: subscriptionId:
@ -620,13 +620,13 @@ paths:
description: Order in Progress (Only Description) description: Order in Progress (Only Description)
servers: servers:
- url: //callback-url.operation-level/v1 - url: //callback-url.operation-level/v1
description: Operation level server 1 (Path override) description: Operation level server 1 (Operation override)
- url: //callback-url.operation-level/v2 - url: //callback-url.operation-level/v2
description: Operation level server 2 (Path override) description: Operation level server 2 (Operation override)
requestBody: requestBody:
content: content:
application/json: application/json:
schema: schema:
type: object type: object
properties: properties:
orderId: orderId:
@ -667,18 +667,18 @@ paths:
orderShipped: orderShipped:
'{$request.body#/callbackUrl}?event={$request.body#/eventName}': '{$request.body#/callbackUrl}?event={$request.body#/eventName}':
post: post:
description: | description: |
Very long description Very long description
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum. culpa qui officia deserunt mollit anim id est laborum.
requestBody: requestBody:
content: content:
application/json: application/json:
schema: schema:
type: object type: object
properties: properties:
orderId: orderId:

View File

@ -19,6 +19,7 @@ describe('Components', () => {
parser, parser,
'Test.Callback', 'Test.Callback',
{ $ref: '#/components/callbacks/Test' }, { $ref: '#/components/callbacks/Test' },
'',
options, options,
); );
// There should be 1 operation defined in simple-callback.json, just get it manually for readability. // There should be 1 operation defined in simple-callback.json, just get it manually for readability.
@ -53,6 +54,7 @@ describe('Components', () => {
parser, parser,
'Test.Callback', 'Test.Callback',
{ $ref: '#/components/callbacks/Test' }, { $ref: '#/components/callbacks/Test' },
'',
options, options,
); );
const callbacksListViewElement = shallow( const callbacksListViewElement = shallow(

View File

@ -1,8 +1,16 @@
import { OpenAPIOperation, OpenAPIParameter, OpenAPISpec, OpenAPITag, Referenced } from '../types'; import {
OpenAPIOperation,
OpenAPIParameter,
OpenAPISpec,
OpenAPITag,
Referenced,
OpenAPIServer,
} from '../types';
import { import {
isOperationName, isOperationName,
SECURITY_DEFINITIONS_COMPONENT_NAME, SECURITY_DEFINITIONS_COMPONENT_NAME,
setSecuritySchemePrefix, setSecuritySchemePrefix,
JsonPointer,
} from '../utils'; } from '../utils';
import { MarkdownRenderer } from './MarkdownRenderer'; import { MarkdownRenderer } from './MarkdownRenderer';
import { GroupModel, OperationModel } from './models'; import { GroupModel, OperationModel } from './models';
@ -15,9 +23,11 @@ export type TagInfo = OpenAPITag & {
}; };
export type ExtendedOpenAPIOperation = { export type ExtendedOpenAPIOperation = {
pointer: string;
pathName: string; pathName: string;
httpVerb: string; httpVerb: string;
pathParameters: Array<Referenced<OpenAPIParameter>>; pathParameters: Array<Referenced<OpenAPIParameter>>;
pathServers: Array<OpenAPIServer>;
} & OpenAPIOperation; } & OpenAPIOperation;
export type TagsInfoMap = Dict<TagInfo>; export type TagsInfoMap = Dict<TagInfo>;
@ -237,8 +247,10 @@ export class MenuBuilder {
tag.operations.push({ tag.operations.push({
...operationInfo, ...operationInfo,
pathName, pathName,
pointer: JsonPointer.compile(['paths', pathName, operationName]),
httpVerb: operationName, httpVerb: operationName,
pathParameters: path.parameters || [], pathParameters: path.parameters || [],
pathServers: path.servers || [],
}); });
} }
} }

View File

@ -15,11 +15,11 @@ describe('Models', () => {
parser, parser,
'Test.Callback', 'Test.Callback',
{ $ref: '#/components/callbacks/Test' }, { $ref: '#/components/callbacks/Test' },
'',
opts, opts,
); );
expect(callback.name).toEqual('Test.Callback'); expect(callback.name).toEqual('Test.Callback');
expect(callback.operations.length).toEqual(0); expect(callback.operations.length).toEqual(0);
expect(callback.paths).toBeDefined();
expect(callback.expanded).toBeUndefined(); expect(callback.expanded).toBeUndefined();
}); });
}); });

View File

@ -1,29 +1,30 @@
import { action, observable } from 'mobx'; import { action, observable } from 'mobx';
import { OpenAPICallback, Referenced } from '../../types'; import { OpenAPICallback, Referenced } from '../../types';
import { isOperationName } from '../../utils'; import { isOperationName, JsonPointer } from '../../utils';
import { OpenAPIParser } from '../OpenAPIParser'; import { OpenAPIParser } from '../OpenAPIParser';
import { OperationModel } from './Operation'; import { OperationModel } from './Operation';
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
export class CallbackModel { export class CallbackModel {
@observable @observable
expanded: boolean; expanded: boolean;
name: string; name: string;
paths: Referenced<OpenAPICallback>;
operations: OperationModel[] = []; operations: OperationModel[] = [];
constructor( constructor(
parser: OpenAPIParser, parser: OpenAPIParser,
name: string, name: string,
infoOrRef: Referenced<OpenAPICallback>, infoOrRef: Referenced<OpenAPICallback>,
options, pointer: string,
options: RedocNormalizedOptions,
) { ) {
this.name = name; this.name = name;
this.paths = parser.deref(infoOrRef); const paths = parser.deref<OpenAPICallback>(infoOrRef);
parser.exitRef(infoOrRef); parser.exitRef(infoOrRef);
for (const pathName of Object.keys(this.paths)) { for (const pathName of Object.keys(paths)) {
const path = this.paths[pathName]; const path = paths[pathName];
const operations = Object.keys(path).filter(isOperationName); const operations = Object.keys(path).filter(isOperationName);
for (const operationName of operations) { for (const operationName of operations) {
const operationInfo = path[operationName]; const operationInfo = path[operationName];
@ -33,8 +34,10 @@ export class CallbackModel {
{ {
...operationInfo, ...operationInfo,
pathName, pathName,
pointer: JsonPointer.compile([pointer, name, pathName, operationName]),
httpVerb: operationName, httpVerb: operationName,
pathParameters: path.parameters || [], pathParameters: path.parameters || [],
pathServers: path.servers || [],
}, },
undefined, undefined,
options, options,

View File

@ -4,19 +4,13 @@ import { IMenuItem } from '../MenuStore';
import { GroupModel } from './Group.model'; import { GroupModel } from './Group.model';
import { SecurityRequirementModel } from './SecurityRequirement'; import { SecurityRequirementModel } from './SecurityRequirement';
import { import { OpenAPIExternalDocumentation, OpenAPIServer, OpenAPIXCodeSample } from '../../types';
OpenAPIExternalDocumentation,
OpenAPIPath,
OpenAPIServer,
OpenAPIXCodeSample,
} from '../../types';
import { import {
extractExtensions, extractExtensions,
getOperationSummary, getOperationSummary,
getStatusCodeType, getStatusCodeType,
isStatusCode, isStatusCode,
JsonPointer,
memoize, memoize,
mergeParams, mergeParams,
normalizeServers, normalizeServers,
@ -87,14 +81,7 @@ export class OperationModel implements IMenuItem {
private options: RedocNormalizedOptions, private options: RedocNormalizedOptions,
isCallback: boolean = false, isCallback: boolean = false,
) { ) {
this.pointer = JsonPointer.compile(['paths', operationSpec.pathName, operationSpec.httpVerb]); this.pointer = operationSpec.pointer;
this.id =
operationSpec.operationId !== undefined
? 'operation/' + operationSpec.operationId
: parent !== undefined
? parent.id + this.pointer
: this.pointer;
this.description = operationSpec.description; this.description = operationSpec.description;
this.parent = parent; this.parent = parent;
@ -107,10 +94,6 @@ export class OperationModel implements IMenuItem {
this.path = operationSpec.pathName; this.path = operationSpec.pathName;
this.isCallback = isCallback; this.isCallback = isCallback;
const pathInfo = parser.byRef<OpenAPIPath>(
JsonPointer.compile(['paths', operationSpec.pathName]),
);
this.name = getOperationSummary(operationSpec); this.name = getOperationSummary(operationSpec);
if (this.isCallback) { if (this.isCallback) {
@ -121,18 +104,22 @@ export class OperationModel implements IMenuItem {
); );
// TODO: update getting pathInfo for overriding servers on path level // TODO: update getting pathInfo for overriding servers on path level
this.servers = normalizeServers( this.servers = normalizeServers('', operationSpec.servers || operationSpec.pathServers || []);
'',
operationSpec.servers || (pathInfo && pathInfo.servers) || [],
);
} else { } else {
this.id =
operationSpec.operationId !== undefined
? 'operation/' + operationSpec.operationId
: parent !== undefined
? parent.id + this.pointer
: this.pointer;
this.security = (operationSpec.security || parser.spec.security || []).map( this.security = (operationSpec.security || parser.spec.security || []).map(
security => new SecurityRequirementModel(security, parser), security => new SecurityRequirementModel(security, parser),
); );
this.servers = normalizeServers( this.servers = normalizeServers(
parser.specUrl, parser.specUrl,
operationSpec.servers || (pathInfo && pathInfo.servers) || parser.spec.servers || [], operationSpec.servers || operationSpec.pathServers || parser.spec.servers || [],
); );
} }
@ -259,6 +246,7 @@ export class OperationModel implements IMenuItem {
this.parser, this.parser,
callbackEventName, callbackEventName,
this.operationSpec.callbacks![callbackEventName], this.operationSpec.callbacks![callbackEventName],
this.pointer,
this.options, this.options,
); );
}); });

View File

@ -1,4 +1,3 @@
export * from './Callback';
export * from '../SpecStore'; export * from '../SpecStore';
export * from './Group.model'; export * from './Group.model';
export * from './Operation'; export * from './Operation';
@ -11,3 +10,4 @@ export * from './Schema';
export * from './Field'; export * from './Field';
export * from './ApiInfo'; export * from './ApiInfo';
export * from './SecuritySchemes'; export * from './SecuritySchemes';
export * from './Callback';

View File

@ -196,7 +196,7 @@ export interface OpenAPILink {
export type OpenAPIHeader = Omit<OpenAPIParameter, 'in' | 'name'>; export type OpenAPIHeader = Omit<OpenAPIParameter, 'in' | 'name'>;
export interface OpenAPICallback { export interface OpenAPICallback {
$ref?: string; [name: string]: OpenAPIPath;
} }
export interface OpenAPIComponents { export interface OpenAPIComponents {