Skip to content

Commit 6e63ab7

Browse files
authored
Support accept Header & Use RequestBody (#1541)
1 parent 677b4c2 commit 6e63ab7

File tree

2 files changed

+250
-150
lines changed

2 files changed

+250
-150
lines changed

operationv3.go

Lines changed: 152 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"strconv"
1010
"strings"
1111

12+
"github.com/pkg/errors"
1213
"github.com/sv-tools/openapi/spec"
1314
"gopkg.in/yaml.v2"
1415
)
@@ -145,16 +146,49 @@ func (o *OperationV3) ParseTagsComment(commentLine string) {
145146
func (o *OperationV3) ParseAcceptComment(commentLine string) error {
146147
const errMessage = "could not parse accept comment"
147148

148-
// TODO this must be moved into another comment
149-
// return parseMimeTypeList(commentLine, &o.RequestBody.Spec.Spec.Content, )
150-
// result, err := parseMimeTypeListV3(commentLine, "%v accept type can't be accepted")
151-
// if err != nil {
152-
// return errors.Wrap(err, errMessage)
153-
// }
149+
validTypes, err := parseMimeTypeListV3(commentLine, "%v accept type can't be accepted")
150+
if err != nil {
151+
return errors.Wrap(err, errMessage)
152+
}
154153

155-
// for _, value := range result {
156-
// o.RequestBody.Spec.Spec.Content[value] = spec.NewMediaType()
157-
// }
154+
if o.RequestBody == nil {
155+
o.RequestBody = spec.NewRequestBodySpec()
156+
}
157+
158+
if o.RequestBody.Spec.Spec.Content == nil {
159+
o.RequestBody.Spec.Spec.Content = make(map[string]*spec.Extendable[spec.MediaType], len(validTypes))
160+
}
161+
162+
for _, value := range validTypes {
163+
// skip correctly setup types like application/json
164+
if o.RequestBody.Spec.Spec.Content[value] != nil {
165+
continue
166+
}
167+
168+
mediaType := spec.NewMediaType()
169+
schema := spec.NewSchemaSpec()
170+
171+
switch value {
172+
case "application/json", "multipart/form-data", "text/xml":
173+
schema.Spec.Type = spec.NewSingleOrArray(OBJECT)
174+
case "image/png",
175+
"image/jpeg",
176+
"image/gif",
177+
"application/octet-stream",
178+
"application/pdf",
179+
"application/msexcel",
180+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
181+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
182+
"application/vnd.openxmlformats-officedocument.presentationml.presentation":
183+
schema.Spec.Type = spec.NewSingleOrArray(STRING)
184+
schema.Spec.Format = "binary"
185+
default:
186+
schema.Spec.Type = spec.NewSingleOrArray(STRING)
187+
}
188+
189+
mediaType.Spec.Schema = schema
190+
o.RequestBody.Spec.Spec.Content[value] = mediaType
191+
}
158192

159193
return nil
160194
}
@@ -316,15 +350,33 @@ func (o *OperationV3) ParseParamComment(commentLine string, astFile *ast.File) e
316350
}
317351
case "body":
318352
if objectType == PRIMITIVE {
319-
param.Schema = PrimitiveSchemaV3(refType)
320-
} else {
321-
schema, err := o.parseAPIObjectSchema(commentLine, objectType, refType, astFile)
353+
schema := PrimitiveSchemaV3(refType)
354+
355+
err := o.parseParamAttributeForBody(commentLine, objectType, refType, schema.Spec)
322356
if err != nil {
323357
return err
324358
}
325359

326-
param.Schema = schema
360+
o.fillRequestBody(schema, required, description, true)
361+
362+
return nil
363+
364+
}
365+
366+
schema, err := o.parseAPIObjectSchema(commentLine, objectType, refType, astFile)
367+
if err != nil {
368+
return err
327369
}
370+
371+
err = o.parseParamAttributeForBody(commentLine, objectType, refType, schema.Spec)
372+
if err != nil {
373+
return err
374+
}
375+
376+
o.fillRequestBody(schema, required, description, false)
377+
378+
return nil
379+
328380
default:
329381
return fmt.Errorf("%s is not supported paramType", paramType)
330382
}
@@ -343,7 +395,74 @@ func (o *OperationV3) ParseParamComment(commentLine string, astFile *ast.File) e
343395
return nil
344396
}
345397

398+
func (o *OperationV3) fillRequestBody(schema *spec.RefOrSpec[spec.Schema], required bool, description string, primitive bool) {
399+
if o.RequestBody == nil {
400+
o.RequestBody = spec.NewRequestBodySpec()
401+
o.RequestBody.Spec.Spec.Content = make(map[string]*spec.Extendable[spec.MediaType])
402+
403+
if primitive {
404+
o.RequestBody.Spec.Spec.Content["text/plain"] = spec.NewMediaType()
405+
} else {
406+
o.RequestBody.Spec.Spec.Content["application/json"] = spec.NewMediaType()
407+
}
408+
}
409+
410+
o.RequestBody.Spec.Spec.Description = description
411+
o.RequestBody.Spec.Spec.Required = required
412+
413+
for _, value := range o.RequestBody.Spec.Spec.Content {
414+
value.Spec.Schema = schema
415+
}
416+
}
417+
346418
func (o *OperationV3) parseParamAttribute(comment, objectType, schemaType string, param *spec.Parameter) error {
419+
if param == nil {
420+
return fmt.Errorf("cannot parse empty parameter for comment: %s", comment)
421+
}
422+
423+
schemaType = TransToValidSchemeType(schemaType)
424+
425+
for attrKey, re := range regexAttributes {
426+
attr, err := findAttr(re, comment)
427+
if err != nil {
428+
continue
429+
}
430+
431+
switch attrKey {
432+
case enumsTag:
433+
err = setEnumParamV3(param.Schema.Spec, attr, objectType, schemaType)
434+
case minimumTag, maximumTag:
435+
err = setNumberParamV3(param.Schema.Spec, attrKey, schemaType, attr, comment)
436+
case defaultTag:
437+
err = setDefaultV3(param.Schema.Spec, schemaType, attr)
438+
case minLengthTag, maxLengthTag:
439+
err = setStringParamV3(param.Schema.Spec, attrKey, schemaType, attr, comment)
440+
case formatTag:
441+
param.Schema.Spec.Format = attr
442+
case exampleTag:
443+
val, err := defineType(schemaType, attr)
444+
if err != nil {
445+
continue // Don't set a example value if it's not valid
446+
}
447+
448+
param.Example = val
449+
case schemaExampleTag:
450+
err = setSchemaExampleV3(param.Schema.Spec, schemaType, attr)
451+
case extensionsTag:
452+
param.Schema.Spec.Extensions = setExtensionParam(attr)
453+
case collectionFormatTag:
454+
err = setCollectionFormatParamV3(param, attrKey, objectType, attr, comment)
455+
}
456+
457+
if err != nil {
458+
return err
459+
}
460+
}
461+
462+
return nil
463+
}
464+
465+
func (o *OperationV3) parseParamAttributeForBody(comment, objectType, schemaType string, param *spec.Schema) error {
347466
schemaType = TransToValidSchemeType(schemaType)
348467

349468
for attrKey, re := range regexAttributes {
@@ -362,15 +481,13 @@ func (o *OperationV3) parseParamAttribute(comment, objectType, schemaType string
362481
case minLengthTag, maxLengthTag:
363482
err = setStringParamV3(param, attrKey, schemaType, attr, comment)
364483
case formatTag:
365-
param.Schema.Spec.Format = attr
484+
param.Format = attr
366485
case exampleTag:
367-
err = setExampleV3(param, schemaType, attr)
486+
err = setSchemaExampleV3(param, schemaType, attr)
368487
case schemaExampleTag:
369488
err = setSchemaExampleV3(param, schemaType, attr)
370489
case extensionsTag:
371-
param.Schema.Spec.Extensions = setExtensionParam(attr)
372-
case collectionFormatTag:
373-
err = setCollectionFormatParamV3(param, attrKey, objectType, attr, comment)
490+
param.Extensions = setExtensionParam(attr)
374491
}
375492

376493
if err != nil {
@@ -390,28 +507,29 @@ func setCollectionFormatParamV3(param *spec.Parameter, name, schemaType, attr, c
390507
return fmt.Errorf("%s is attribute to set to an array. comment=%s got=%s", name, commentLine, schemaType)
391508
}
392509

393-
func setSchemaExampleV3(param *spec.Parameter, schemaType string, value string) error {
510+
func setSchemaExampleV3(param *spec.Schema, schemaType string, value string) error {
394511
val, err := defineType(schemaType, value)
395512
if err != nil {
396513
return nil // Don't set a example value if it's not valid
397514
}
515+
398516
// skip schema
399-
if param.Schema == nil {
517+
if param == nil {
400518
return nil
401519
}
402520

403521
switch v := val.(type) {
404522
case string:
405523
// replaces \r \n \t in example string values.
406-
param.Schema.Spec.Example = strings.NewReplacer(`\r`, "\r", `\n`, "\n", `\t`, "\t").Replace(v)
524+
param.Example = strings.NewReplacer(`\r`, "\r", `\n`, "\n", `\t`, "\t").Replace(v)
407525
default:
408-
param.Schema.Spec.Example = val
526+
param.Example = val
409527
}
410528

411529
return nil
412530
}
413531

414-
func setExampleV3(param *spec.Parameter, schemaType string, value string) error {
532+
func setExampleParameterV3(param *spec.Parameter, schemaType string, value string) error {
415533
val, err := defineType(schemaType, value)
416534
if err != nil {
417535
return nil // Don't set a example value if it's not valid
@@ -422,7 +540,7 @@ func setExampleV3(param *spec.Parameter, schemaType string, value string) error
422540
return nil
423541
}
424542

425-
func setStringParamV3(param *spec.Parameter, name, schemaType, attr, commentLine string) error {
543+
func setStringParamV3(param *spec.Schema, name, schemaType, attr, commentLine string) error {
426544
if schemaType != STRING {
427545
return fmt.Errorf("%s is attribute to set to a number. comment=%s got=%s", name, commentLine, schemaType)
428546
}
@@ -434,26 +552,26 @@ func setStringParamV3(param *spec.Parameter, name, schemaType, attr, commentLine
434552

435553
switch name {
436554
case minLengthTag:
437-
param.Schema.Spec.MinLength = &n
555+
param.MinLength = &n
438556
case maxLengthTag:
439-
param.Schema.Spec.MaxLength = &n
557+
param.MaxLength = &n
440558
}
441559

442560
return nil
443561
}
444562

445-
func setDefaultV3(param *spec.Parameter, schemaType string, value string) error {
563+
func setDefaultV3(param *spec.Schema, schemaType string, value string) error {
446564
val, err := defineType(schemaType, value)
447565
if err != nil {
448566
return nil // Don't set a default value if it's not valid
449567
}
450568

451-
param.Schema.Spec.Default = val
569+
param.Default = val
452570

453571
return nil
454572
}
455573

456-
func setEnumParamV3(param *spec.Parameter, attr, objectType, schemaType string) error {
574+
func setEnumParamV3(param *spec.Schema, attr, objectType, schemaType string) error {
457575
for _, e := range strings.Split(attr, ",") {
458576
e = strings.TrimSpace(e)
459577

@@ -464,16 +582,16 @@ func setEnumParamV3(param *spec.Parameter, attr, objectType, schemaType string)
464582

465583
switch objectType {
466584
case ARRAY:
467-
param.Schema.Spec.Items.Schema.Spec.Enum = append(param.Schema.Spec.Items.Schema.Spec.Enum, value)
585+
param.Items.Schema.Spec.Enum = append(param.Items.Schema.Spec.Enum, value)
468586
default:
469-
param.Schema.Spec.Enum = append(param.Schema.Spec.Enum, value)
587+
param.Enum = append(param.Enum, value)
470588
}
471589
}
472590

473591
return nil
474592
}
475593

476-
func setNumberParamV3(param *spec.Parameter, name, schemaType, attr, commentLine string) error {
594+
func setNumberParamV3(param *spec.Schema, name, schemaType, attr, commentLine string) error {
477595
switch schemaType {
478596
case INTEGER, NUMBER:
479597
n, err := strconv.Atoi(attr)
@@ -483,9 +601,9 @@ func setNumberParamV3(param *spec.Parameter, name, schemaType, attr, commentLine
483601

484602
switch name {
485603
case minimumTag:
486-
param.Schema.Spec.Minimum = &n
604+
param.Minimum = &n
487605
case maximumTag:
488-
param.Schema.Spec.Maximum = &n
606+
param.Maximum = &n
489607
}
490608

491609
return nil

0 commit comments

Comments
 (0)