func gatherModels(specDoc *spec.Document, modelNames []string) (map[string]spec.Schema, error) { models, mnc := make(map[string]spec.Schema), len(modelNames) defs := specDoc.Spec().Definitions if mnc > 0 { var unknownModels []string for _, m := range modelNames { _, ok := defs[m] if !ok { unknownModels = append(unknownModels, m) } } if len(unknownModels) != 0 { return nil, fmt.Errorf("unknown models: %s", strings.Join(unknownModels, ", ")) } } for k, v := range defs { if mnc == 0 { models[k] = v } for _, nm := range modelNames { if k == nm { models[k] = v } } } return models, nil }
// New creates a new default runtime for a swagger api client. func New(swaggerSpec *spec.Document) *Runtime { var rt Runtime rt.DefaultMediaType = httpkit.JSONMime // TODO: actually infer this stuff from the spec rt.Consumers = map[string]httpkit.Consumer{ httpkit.JSONMime: httpkit.JSONConsumer(), } rt.Producers = map[string]httpkit.Producer{ httpkit.JSONMime: httpkit.JSONProducer(), } rt.Spec = swaggerSpec rt.Transport = http.DefaultTransport rt.client = http.DefaultClient rt.client.Transport = rt.Transport rt.Host = swaggerSpec.Host() rt.BasePath = swaggerSpec.BasePath() schemes := swaggerSpec.Spec().Schemes if len(schemes) == 0 { schemes = append(schemes, "http") } rt.methodsAndPaths = make(map[string]methodAndPath) for mth, pathItem := range rt.Spec.Operations() { for pth, op := range pathItem { if len(op.Schemes) > 0 { rt.methodsAndPaths[op.ID] = methodAndPath{mth, pth, op.Schemes} } else { rt.methodsAndPaths[op.ID] = methodAndPath{mth, pth, schemes} } } } return &rt }
func makeCodegenModel(name, pkg string, schema spec.Schema, specDoc *spec.Document) *genModel { receiver := "m" props := make(map[string]genModelProperty) for pn, p := range schema.Properties { var required bool for _, v := range schema.Required { if v == pn { required = true break } } props[swag.ToJSONName(pn)] = makeGenModelProperty( "\""+pn+"\"", swag.ToJSONName(pn), swag.ToGoName(pn), receiver, "i", receiver+"."+swag.ToGoName(pn), p, required) } for _, p := range schema.AllOf { if p.Ref.GetURL() != nil { tn := filepath.Base(p.Ref.GetURL().Fragment) p = specDoc.Spec().Definitions[tn] } mod := makeCodegenModel(name, pkg, p, specDoc) if mod != nil { for _, prop := range mod.Properties { props[prop.ParamName] = prop } } } var properties []genModelProperty var hasValidations bool for _, v := range props { if v.HasValidations { hasValidations = v.HasValidations } properties = append(properties, v) } sort.Sort(genModelPropertySlice(properties)) return &genModel{ Package: filepath.Base(pkg), ClassName: swag.ToGoName(name), Name: swag.ToJSONName(name), ReceiverName: receiver, Properties: properties, Description: schema.Description, DocString: modelDocString(swag.ToGoName(name), schema.Description), HumanClassName: swag.ToHumanNameLower(swag.ToGoName(name)), DefaultImports: []string{"github.com/go-swagger/go-swagger/strfmt"}, HasValidations: hasValidations, } }
func gatherModels(specDoc *spec.Document, modelNames []string) map[string]spec.Schema { models, mnc := make(map[string]spec.Schema), len(modelNames) for k, v := range specDoc.Spec().Definitions { for _, nm := range modelNames { if mnc == 0 || k == nm { models[k] = v } } } return models }
// New creates a new default runtime for a swagger api client. func New(swaggerSpec *spec.Document) *Runtime { var rt Runtime rt.DefaultMediaType = httpkit.JSONMime // TODO: actually infer this stuff from the spec rt.Consumers = map[string]httpkit.Consumer{ httpkit.JSONMime: httpkit.JSONConsumer(), } rt.Producers = map[string]httpkit.Producer{ httpkit.JSONMime: httpkit.JSONProducer(), } rt.Spec = swaggerSpec rt.Transport = http.DefaultTransport rt.client = http.DefaultClient rt.client.Transport = rt.Transport rt.Host = swaggerSpec.Host() rt.BasePath = swaggerSpec.BasePath() if !strings.HasPrefix(rt.BasePath, "/") { rt.BasePath = "/" + rt.BasePath } rt.Debug = os.Getenv("DEBUG") == "1" schemes := swaggerSpec.Spec().Schemes if len(schemes) == 0 { schemes = append(schemes, "http") } rt.methodsAndPaths = make(map[string]methodAndPath) for mth, pathItem := range rt.Spec.Operations() { for pth, op := range pathItem { nm := ensureUniqueName(op.ID, mth, pth, rt.methodsAndPaths) op.ID = nm if len(op.Schemes) > 0 { rt.methodsAndPaths[nm] = methodAndPath{mth, pth, op.Schemes} } else { rt.methodsAndPaths[nm] = methodAndPath{mth, pth, schemes} } } } return &rt }
// Validate validates the swagger spec func (s *SpecValidator) Validate(data interface{}) (errs *Result, warnings *Result) { var sd *spec.Document switch v := data.(type) { case *spec.Document: sd = v } if sd == nil { errs = sErr(errors.New(500, "spec validator can only validate spec.Document objects")) return } s.spec = sd errs = new(Result) warnings = new(Result) schv := NewSchemaValidator(s.schema, nil, "", s.KnownFormats) errs.Merge(schv.Validate(sd.Spec())) // error - if errs.HasErrors() { return // no point in continuing } errs.Merge(s.validateReferencesValid()) // error if errs.HasErrors() { return // no point in continuing } errs.Merge(s.validateDuplicatePropertyNames()) // error errs.Merge(s.validateParameters()) // error - errs.Merge(s.validateItems()) // error - errs.Merge(s.validateRequiredDefinitions()) // error - errs.Merge(s.validateDefaultValueValidAgainstSchema()) // error warnings.Merge(s.validateUniqueSecurityScopes()) // warning warnings.Merge(s.validateUniqueScopesSecurityDefinitions()) // warning warnings.Merge(s.validateReferenced()) // warning return }
func gatherModels(specDoc *spec.Document, modelNames []string) (map[string]spec.Schema, error) { models, mnc := make(map[string]spec.Schema), len(modelNames) defs := specDoc.Spec().Definitions if mnc > 0 { for _, m := range modelNames { _, ok := defs[m] if !ok { return nil, errors.New("unknown model") } } } for k, v := range defs { if mnc == 0 { models[k] = v } for _, nm := range modelNames { if k == nm { models[k] = v } } } return models, nil }
func appNameOrDefault(specDoc *spec.Document, name, defaultName string) string { if name == "" { if specDoc.Spec().Info != nil && specDoc.Spec().Info.Title != "" { name = specDoc.Spec().Info.Title } else { name = defaultName } } return strings.TrimSuffix(swag.ToGoName(name), "API") }
func makeGenDefinition(name, pkg string, schema spec.Schema, specDoc *spec.Document) (*GenDefinition, error) { receiver := "m" resolver := &typeResolver{ ModelsPackage: "", ModelName: name, Doc: specDoc, } di := discriminatorInfo(specDoc) pg := schemaGenContext{ Path: "", Name: name, Receiver: receiver, IndexVar: "i", ValueExpr: receiver, Schema: schema, Required: false, TypeResolver: resolver, Named: true, ExtraSchemas: make(map[string]GenSchema), Discrimination: di, } if err := pg.makeGenSchema(); err != nil { return nil, err } dsi, ok := di.Discriminators["#/definitions/"+name] if ok { // when these 2 are true then the schema will render as an interface pg.GenSchema.IsBaseType = true pg.GenSchema.IsExported = true pg.GenSchema.DiscriminatorField = dsi.FieldName // clone schema and turn into IsExported false //tpeImpl := newDiscriminatorImpl(pg.GenSchema) //pg.ExtraSchemas[tpeImpl.Name] = tpeImpl for _, v := range dsi.Children { if pg.GenSchema.Discriminates == nil { pg.GenSchema.Discriminates = make(map[string]string) } pg.GenSchema.Discriminates[v.FieldValue] = v.GoType } } dse, ok := di.Discriminated["#/definitions/"+name] if ok { pg.GenSchema.DiscriminatorField = dse.FieldName pg.GenSchema.DiscriminatorValue = dse.FieldValue pg.GenSchema.IsSubType = true // find the referenced definitions // check if it has a discriminator defined // when it has a discriminator get the schema and run makeGenSchema for it. // replace the ref with this new genschema swsp := specDoc.Spec() for i, ss := range schema.AllOf { ref := ss.Ref for ref.String() != "" { rsch, err := spec.ResolveRef(swsp, &ref) if err != nil { return nil, err } ref = rsch.Ref if rsch != nil && rsch.Ref.String() != "" { ref = rsch.Ref continue } ref = spec.Ref{} if rsch != nil && rsch.Discriminator != "" { gs, err := makeGenDefinition(strings.TrimPrefix(ss.Ref.String(), "#/definitions/"), pkg, *rsch, specDoc) if err != nil { return nil, err } gs.GenSchema.IsBaseType = true gs.GenSchema.IsExported = true pg.GenSchema.AllOf[i] = gs.GenSchema schPtr := &(pg.GenSchema.AllOf[i]) if schPtr.AdditionalItems != nil { schPtr.AdditionalItems.IsBaseType = true } if schPtr.AdditionalProperties != nil { schPtr.AdditionalProperties.IsBaseType = true } for j := range schPtr.Properties { schPtr.Properties[j].IsBaseType = true schPtr.Properties[j].ValueExpression += "()" } } } } } var defaultImports []string if pg.GenSchema.HasValidations { defaultImports = []string{ "github.com/go-swagger/go-swagger/errors", "github.com/go-swagger/go-swagger/strfmt", "github.com/go-swagger/go-swagger/httpkit/validate", } } var extras []GenSchema var extraKeys []string for k := range pg.ExtraSchemas { extraKeys = append(extraKeys, k) } sort.Strings(extraKeys) for _, k := range extraKeys { extras = append(extras, pg.ExtraSchemas[k]) } return &GenDefinition{ Package: mangleName(filepath.Base(pkg), "definitions"), GenSchema: pg.GenSchema, DependsOn: pg.Dependencies, DefaultImports: defaultImports, ExtraSchemas: extras, }, nil }