Skip to content

Commit

Permalink
feat: add more swagger fields
Browse files Browse the repository at this point in the history
  • Loading branch information
plantain-00 committed Nov 26, 2018
1 parent 125b208 commit 08f8e52
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 55 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ boolean[]:

+ `@method get`: set api method
+ `@path /pet/{id}`: set api url
+ `@in query`: a parameter in a `query`, `body`, `header` or `path`
+ `@in query`: a parameter in a `query`, `body`, `header`, `formData` or `path`

## number type alias

Expand Down
6 changes: 5 additions & 1 deletion demo/cases.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@
"name": "id",
"required": true,
"in": "path",
"type": "number"
"type": "integer",
"minimum": 1,
"description": "pet id"
}
],
"summary": "get pet by id.",
"description": "get pet by id",
"responses": {
"200": {
"schema": {
Expand Down
11 changes: 10 additions & 1 deletion demo/cases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,5 +409,14 @@ interface Pet {
/**
* @method get
* @path /pet/{id}
* @summary get pet by id.
* @description get pet by id
*/
export declare function getPetById(/** @in path */id: number): Promise<Pet>
export declare function getPetById(
/**
* @in path
* @description pet id
* @minimum 1
*/
id: integer
): Promise<Pet>
18 changes: 11 additions & 7 deletions demo/debug.json
Original file line number Diff line number Diff line change
Expand Up @@ -3155,8 +3155,8 @@
"name": "Pet",
"position": {
"file": "demo/cases.ts",
"line": 412,
"character": 71
"line": 421,
"character": 11
}
},
"optional": false,
Expand All @@ -3165,19 +3165,23 @@
"name": "id",
"type": {
"kind": "number",
"type": "number",
"type": "integer",
"position": {
"file": "demo/cases.ts",
"line": 412,
"character": 54
}
"line": 420,
"character": 6
},
"description": "pet id",
"minimum": 1
},
"optional": false,
"in": "path"
}
],
"method": "get",
"path": "/pet/{id}"
"path": "/pet/{id}",
"summary": "get pet by id.",
"description": "get pet by id"
},
{
"kind": "object",
Expand Down
11 changes: 10 additions & 1 deletion online/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,17 @@ interface Pet {
/**
* @method get
* @path /pet/{id}
* @summary get pet by id.
* @description get pet by id
*/
export declare function getPetById(/** @in path */id: number): Promise<Pet>
export declare function getPetById(
/**
* @in path
* @description pet id
* @minimum 1
*/
id: integer
): Promise<Pet>
`
// @ts-ignore
export function indexTemplateHtml(this: App) {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"app"},[_c('textarea',{directives:[{name:"model",rawName:"v-model",value:(_vm.source),expression:"source"}],staticClass:"source",domProps:{"value":(_vm.source)},on:{"input":function($event){if($event.target.composing){ return; }_vm.source=$event.target.value}}}),_vm._v(" "),_c('div',{staticClass:"result"},[_c('button',{on:{"click":function($event){_vm.generate()}}},[_vm._v("generate")]),_vm._v(" "),_c('div',{staticClass:"options"},[_c('select',{directives:[{name:"model",rawName:"v-model",value:(_vm.selectedOption),expression:"selectedOption"}],on:{"change":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return val}); _vm.selectedOption=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},_vm._l((_vm.options),function(option){return _c('option',{key:option,domProps:{"value":option}},[_vm._v(_vm._s(option))])}))]),_vm._v(" "),(_vm.selectedOption === 'protobuf')?_c('pre',{staticClass:"protobuf"},[_vm._v(_vm._s(_vm.protobuf))]):_vm._e(),_vm._v(" "),(_vm.jsonSchema)?_c('pre',{staticClass:"json-schema"},[_vm._v(_vm._s(_vm.jsonSchema))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'graphql schema')?_c('pre',{staticClass:"graphql-schema"},[_vm._v(_vm._s(_vm.graphqlSchema))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'reason types')?_c('pre',{staticClass:"reason-types"},[_vm._v(_vm._s(_vm.reasonTypes))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'ocaml types')?_c('pre',{staticClass:"ocaml-types"},[_vm._v(_vm._s(_vm.ocamlTypes))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'rust types')?_c('pre',{staticClass:"rust-types"},[_vm._v(_vm._s(_vm.rustTypes))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'mongoose schema')?_c('pre',{staticClass:"mongoose-schema"},[_vm._v(_vm._s(_vm.mongooseSchema))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'graphql root type')?_c('pre',{staticClass:"graphql-root-type"},[_vm._v(_vm._s(_vm.graphqlRootType))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'swagger doc')?_c('pre',{staticClass:"swagger-doc"},[_vm._v(_vm._s(_vm.swaggerDoc))]):_vm._e()])])}
Expand Down
2 changes: 1 addition & 1 deletion src/json-schema-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function getTypeNameOfEnumOrConst(type: string): any {
return 'integer'
}

function getJsonSchemaProperty(memberType: Type): Definition {
export function getJsonSchemaProperty(memberType: Type): Definition {
if (memberType.kind === 'number') {
return getNumberType(memberType)
} else if (memberType.kind === 'boolean') {
Expand Down
66 changes: 40 additions & 26 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,29 +135,36 @@ export class Parser {
name: declaration.name ? declaration.name.text : '',
type,
optional: !!declaration.questionToken,
parameters: declaration.parameters.map((parameter) => {
const parameterDoc = this.getParameter(parameter, sourceFile)
const jsDocs = this.getJsDocs(parameter, sourceFile)
for (const jsDoc of jsDocs) {
if (jsDoc.comment && jsDoc.name === 'in') {
parameterDoc.in = jsDoc.comment
}
}
return parameterDoc
})
parameters: declaration.parameters.map((parameter) => this.handleFunctionParameter(parameter, sourceFile))
}
for (const jsDoc of jsDocs) {
if (jsDoc.comment) {
if (jsDoc.name === 'method') {
functionDeclaration.method = jsDoc.comment
} else if (jsDoc.name === 'path') {
functionDeclaration.path = jsDoc.comment
} else if (jsDoc.name === 'description') {
functionDeclaration.description = jsDoc.comment
} else if (jsDoc.name === 'summary') {
functionDeclaration.summary = jsDoc.comment
}
}
}
this.declarations.push(functionDeclaration)
}

private handleFunctionParameter(parameter: ts.ParameterDeclaration, sourceFile: ts.SourceFile) {
const parameterDoc = this.getParameter(parameter, sourceFile)
const jsDocs = this.getJsDocs(parameter, sourceFile)
for (const jsDoc of jsDocs) {
if (jsDoc.comment && jsDoc.name === 'in') {
parameterDoc.in = jsDoc.comment
}
}
this.setJsDoc(jsDocs, parameterDoc.type, sourceFile)
return parameterDoc
}

private handleInterfaceOrClassDeclaration(
declaration: ts.InterfaceDeclaration | ts.ClassDeclaration,
jsDocs: JsDoc[],
Expand Down Expand Up @@ -1038,6 +1045,28 @@ export class Parser {
} as FunctionParameter
}

private setJsDoc(jsDocs: JsDoc[], type: Type, sourceFile: ts.SourceFile) {
for (const jsDoc of jsDocs) {
if (jsDoc.name === 'mapValueType') {
this.setJsDocMapValue(jsDoc, type)
} else if (jsDoc.name === 'type') {
this.overrideType(type, jsDoc)
} else if (type.kind === 'array') {
this.setJsDocArray(jsDoc, type, sourceFile)
} else if (type.kind === 'number') {
this.setJsDocNumber(jsDoc, type)
} else if (type.kind === 'string') {
this.setJsDocString(jsDoc, type)
} else if (type.kind === 'boolean') {
this.setJsDocBoolean(jsDoc, type)
} else if (type.kind === 'object') {
this.setJsDocObject(jsDoc, type)
} else if (type.kind === 'reference') {
this.setJsDocReference(jsDoc, type)
}
}
}

private setPropertyJsDoc(
property: ts.PropertySignature | ts.PropertyDeclaration,
member: Member,
Expand All @@ -1047,26 +1076,11 @@ export class Parser {
for (const propertyJsDoc of propertyJsDocs) {
if (propertyJsDoc.name === 'tag') {
this.setJsDocTag(propertyJsDoc, member)
} else if (propertyJsDoc.name === 'mapValueType') {
this.setJsDocMapValue(propertyJsDoc, member.type)
} else if (propertyJsDoc.name === 'type') {
this.overrideType(member.type, propertyJsDoc)
} else if (propertyJsDoc.name === 'param') {
this.setJsDocParam(propertyJsDoc, member)
} else if (member.type.kind === 'array') {
this.setJsDocArray(propertyJsDoc, member.type, sourceFile)
} else if (member.type.kind === 'number') {
this.setJsDocNumber(propertyJsDoc, member.type)
} else if (member.type.kind === 'string') {
this.setJsDocString(propertyJsDoc, member.type)
} else if (member.type.kind === 'boolean') {
this.setJsDocBoolean(propertyJsDoc, member.type)
} else if (member.type.kind === 'object') {
this.setJsDocObject(propertyJsDoc, member.type)
} else if (member.type.kind === 'reference') {
this.setJsDocReference(propertyJsDoc, member.type)
}
}
this.setJsDoc(propertyJsDocs, member.type, sourceFile)
}

private setJsDocReference(propertyJsDoc: JsDoc, type: ReferenceType) {
Expand Down
25 changes: 8 additions & 17 deletions src/swagger-doc-generator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TypeDeclaration, Type } from './utils'
import { getAllDefinitions, getReferencedDefinitions, Definition } from './json-schema-generator'
import { TypeDeclaration } from './utils'
import { getAllDefinitions, getReferencedDefinitions, Definition, getJsonSchemaProperty } from './json-schema-generator'

export function generateSwaggerDoc(typeDeclarations: TypeDeclaration[]) {
const paths: { [path: string]: { [method: string]: any } } = {}
Expand All @@ -24,12 +24,16 @@ export function generateSwaggerDoc(typeDeclarations: TypeDeclaration[]) {
name: parameter.name,
required: !parameter.optional,
in: parameter.in,
...getType(parameter.type)
...getJsonSchemaProperty(parameter.type)
}
}),
summary: typeDeclaration.summary,
description: typeDeclaration.description,
responses: {
200: {
...getType(typeDeclaration.type)
schema: {
...getJsonSchemaProperty(typeDeclaration.type)
}
}
}
}
Expand All @@ -48,16 +52,3 @@ export function generateSwaggerDoc(typeDeclarations: TypeDeclaration[]) {
}
return JSON.stringify(result, null, 2)
}

function getType(type: Type) {
if (type.kind === 'reference') {
return {
schema: {
$ref: `#/definitions/${type.name}`
}
}
}
return {
type: type.kind
}
}
2 changes: 2 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ export type FunctionDeclaration = {
parameters: FunctionParameter[];
method?: string;
path?: string;
description?: string
summary?: string
}

export type FunctionParameter = Parameter & {
Expand Down

0 comments on commit 08f8e52

Please sign in to comment.