Exemple #1
0
        public override void ResolveReferences(OpenApiComponents components)
        {
            base.ResolveReferences(components);

            Schema = Schema?.Resolve(components);
        }
 public override void Visit(OpenApiSchema schema)
 {
     Locations.Add(this.PathString);
 }
 public static bool IsOneOf(this OpenApiSchema schema)
 {
     return(schema?.OneOf?.Any() ?? false);
 }
Exemple #4
0
 public bool CanValidate(OpenApiSchema schema) => schema.AllOf != null && schema.AllOf.Any();
Exemple #5
0
        private static OpenApiSchema CreateStructuredTypeSchema(this ODataContext context, IEdmStructuredType structuredType, bool processBase, bool processExample)
        {
            Debug.Assert(context != null);
            Debug.Assert(structuredType != null);

            if (processBase && structuredType.BaseType != null)
            {
                // A structured type with a base type is represented as a Schema Object
                // that contains the keyword allOf whose value is an array with two items:
                return(new OpenApiSchema
                {
                    AllOf = new List <OpenApiSchema>
                    {
                        // 1. a JSON Reference to the Schema Object of the base type
                        new OpenApiSchema
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.Schema,
                                Id = structuredType.BaseType.FullTypeName()
                            }
                        },

                        // 2. a Schema Object describing the derived type
                        context.CreateStructuredTypeSchema(structuredType, false, false)
                    },

                    AnyOf = null,
                    OneOf = null,
                    Properties = null,
                    Example = CreateStructuredTypePropertiesExample(structuredType)
                });
            }
            else
            {
                // A structured type without a base type is represented as a Schema Object of type object
                OpenApiSchema schema = new OpenApiSchema
                {
                    Title = (structuredType as IEdmSchemaElement)?.Name,

                    Type = "object",

                    // Each structural property and navigation property is represented
                    // as a name/value pair of the standard OpenAPI properties object.
                    Properties = context.CreateStructuredTypePropertiesSchema(structuredType),

                    // make others null
                    AllOf = null,
                    OneOf = null,
                    AnyOf = null
                };

                // It optionally can contain the field description,
                // whose value is the value of the unqualified annotation Core.Description of the structured type.
                if (structuredType.TypeKind == EdmTypeKind.Complex)
                {
                    IEdmComplexType complex = (IEdmComplexType)structuredType;
                    schema.Description = context.Model.GetDescriptionAnnotation(complex);
                }
                else if (structuredType.TypeKind == EdmTypeKind.Entity)
                {
                    IEdmEntityType entity = (IEdmEntityType)structuredType;
                    schema.Description = context.Model.GetDescriptionAnnotation(entity);
                }

                if (processExample)
                {
                    schema.Example = CreateStructuredTypePropertiesExample(structuredType);
                }

                return(schema);
            }
        }
        private OpenApiSchema GenerateObjectSchema(DataContract dataContract, SchemaRepository schemaRepository)
        {
            var schema = new OpenApiSchema
            {
                Type       = "object",
                Properties = new Dictionary <string, OpenApiSchema>(),
                Required   = new SortedSet <string>(),
                AdditionalPropertiesAllowed = false
            };

            // If it's a baseType with known subTypes, add the discriminator property
            if (_generatorOptions.GeneratePolymorphicSchemas && _generatorOptions.SubTypesResolver(dataContract.UnderlyingType).Any())
            {
                var discriminatorName = _generatorOptions.DiscriminatorSelector(dataContract.UnderlyingType);

                if (!schema.Properties.ContainsKey(discriminatorName))
                {
                    schema.Properties.Add(discriminatorName, new OpenApiSchema {
                        Type = "string"
                    });
                }

                schema.Required.Add(discriminatorName);
                schema.Discriminator = new OpenApiDiscriminator {
                    PropertyName = discriminatorName
                };
            }

            foreach (var dataProperty in dataContract.Properties ?? Enumerable.Empty <DataProperty>())
            {
                var customAttributes = dataProperty.MemberInfo?.GetInlineOrMetadataTypeAttributes() ?? Enumerable.Empty <object>();

                if (_generatorOptions.IgnoreObsoleteProperties && customAttributes.OfType <ObsoleteAttribute>().Any())
                {
                    continue;
                }

                schema.Properties[dataProperty.Name] = GeneratePropertySchema(dataProperty, schemaRepository);

                if (dataProperty.IsRequired || customAttributes.OfType <RequiredAttribute>().Any())
                {
                    schema.Required.Add(dataProperty.Name);
                }
            }

            if (dataContract.AdditionalPropertiesType != null)
            {
                schema.AdditionalPropertiesAllowed = true;
                schema.AdditionalProperties        = GenerateSchema(dataContract.AdditionalPropertiesType, schemaRepository);
            }

            // If it's a known subType, reference the baseType for inheritied properties
            if (
                _generatorOptions.GeneratePolymorphicSchemas &&
                (dataContract.UnderlyingType.BaseType != null) &&
                _generatorOptions.SubTypesResolver(dataContract.UnderlyingType.BaseType).Contains(dataContract.UnderlyingType))
            {
                var basedataContract    = _dataContractResolver.GetDataContractForType(dataContract.UnderlyingType.BaseType);
                var baseSchemaReference = GenerateReferencedSchema(basedataContract, schemaRepository);

                var baseSchema = schemaRepository.Schemas[baseSchemaReference.Reference.Id];
                foreach (var basePropertyName in baseSchema.Properties.Keys)
                {
                    schema.Properties.Remove(basePropertyName);
                }

                return(new OpenApiSchema
                {
                    AllOf = new List <OpenApiSchema> {
                        baseSchemaReference, schema
                    }
                });
            }

            return(schema);
        }
    public static void AppendVarDataModelOrListOfModel(
        int indentSpaces,
        StringBuilder sb,
        EndpointMethodMetadata endpointMethodMetadata,
        OpenApiSchema schema,
        HttpStatusCode httpStatusCode,
        SchemaMapLocatedAreaType locatedAreaType,
        KeyValuePair <string, OpenApiSchema>?badPropertySchema = null,
        bool asJsonBody       = false,
        int maxItemsForList   = 3,
        int depthHierarchy    = 0,
        int maxDepthHierarchy = 2)
    {
        ArgumentNullException.ThrowIfNull(endpointMethodMetadata);

        var trailingChar = TrailingCharType.SemiColon;

        if (asJsonBody)
        {
            trailingChar = TrailingCharType.None;
        }

        switch (locatedAreaType)
        {
        case SchemaMapLocatedAreaType.Parameter:
            break;

        case SchemaMapLocatedAreaType.RequestBody:
            if (schema.IsTypeArray())
            {
                var indentSpacesForData = indentSpaces;
                if (asJsonBody)
                {
                    sb.AppendLine(indentSpaces, "var sb = new StringBuilder();");
                    indentSpacesForData -= 4;
                }

                if (schema.HasItemsWithFormatTypeBinary())
                {
                    if (asJsonBody)
                    {
                        throw new NotSupportedException("JSON not supported when RequestBody is type Array and format type is Binary.");
                    }

                    sb.AppendLine(indentSpaces, "var data = GetTestFiles();");
                }
                else
                {
                    AppendVarDataEqualNewListOfModel(
                        indentSpacesForData,
                        sb,
                        endpointMethodMetadata,
                        new KeyValuePair <string, OpenApiSchema>("data", schema),
                        trailingChar,
                        maxItemsForList,
                        depthHierarchy,
                        maxDepthHierarchy,
                        badPropertySchema,
                        asJsonBody);
                }

                if (asJsonBody)
                {
                    sb.AppendLine(indentSpaces, "var data = sb.ToString();");
                }
            }
            else
            {
                if (asJsonBody)
                {
                    sb.AppendLine(indentSpaces, "var sb = new StringBuilder();");
                }
                else
                {
                    GenerateXunitTestPartsHelper.AppendPartVarDataEqualNew(12, sb);
                }

                var modelName = schema.GetModelName();
                AppendModel(
                    indentSpaces,
                    sb,
                    endpointMethodMetadata,
                    modelName,
                    schema,
                    trailingChar,
                    0,
                    maxItemsForList,
                    depthHierarchy,
                    maxDepthHierarchy,
                    badPropertySchema,
                    asJsonBody);

                if (asJsonBody)
                {
                    sb.AppendLine(indentSpaces, "var data = sb.ToString();");
                }
            }

            break;

        case SchemaMapLocatedAreaType.Response:
            var contractReturnTypeName = endpointMethodMetadata.ContractReturnTypeNames.First(x => x.StatusCode == httpStatusCode);
            if (GenerateXunitTestPartsHelper.IsListKind(contractReturnTypeName.FullModelName))
            {
                AppendVarDataEqualNewListOfModel(
                    indentSpaces,
                    sb,
                    endpointMethodMetadata,
                    new KeyValuePair <string, OpenApiSchema>("data", contractReturnTypeName.Schema !),
                    trailingChar,
                    maxItemsForList,
                    depthHierarchy,
                    maxDepthHierarchy,
                    badPropertySchema,
                    asJsonBody);
            }
            else
            {
                GenerateXunitTestPartsHelper.AppendPartVarDataEqualNew(12, sb);
                AppendModel(
                    indentSpaces,
                    sb,
                    endpointMethodMetadata,
                    contractReturnTypeName.FullModelName,
                    contractReturnTypeName.Schema !,
                    trailingChar,
                    0,
                    maxItemsForList,
                    depthHierarchy,
                    maxDepthHierarchy,
                    badPropertySchema,
                    asJsonBody);
            }

            break;

        default:
            throw new ArgumentOutOfRangeException(nameof(locatedAreaType), locatedAreaType, message: null);
        }
    }
        /// <inheritdoc/>
        protected override void SetResponses(OpenApiOperation operation)
        {
            OpenApiSchema schema = new OpenApiSchema
            {
                // $ref returns string for the Uri?
                Type = "string"
            };

            if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                var properties = new Dictionary <string, OpenApiSchema>
                {
                    {
                        "value",
                        new OpenApiSchema
                        {
                            Type  = "array",
                            Items = schema
                        }
                    }
                };

                if (Context.Settings.EnablePagination)
                {
                    properties.Add(
                        "@odata.nextLink",
                        new OpenApiSchema
                    {
                        Type = "string"
                    });
                }

                operation.Responses = new OpenApiResponses
                {
                    {
                        Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            Description = "Retrieved navigation property links",
                            Content     = new Dictionary <string, OpenApiMediaType>
                            {
                                {
                                    Constants.ApplicationJsonMediaType,
                                    new OpenApiMediaType
                                    {
                                        Schema = new OpenApiSchema
                                        {
                                            Title      = "Collection of links of " + NavigationProperty.ToEntityType().Name,
                                            Type       = "object",
                                            Properties = properties
                                        }
                                    }
                                }
                            }
                        }
                    }
                };
            }
            else
            {
                IDictionary <string, OpenApiLink> links = null;
                if (Context.Settings.ShowLinks)
                {
                    string operationId = GetOperationId();

                    links = Context.CreateLinks(entityType: NavigationProperty.ToEntityType(), entityName: NavigationProperty.Name,
                                                entityKind: NavigationProperty.PropertyKind.ToString(), parameters: operation.Parameters,
                                                navPropOperationId: operationId);
                }

                operation.Responses = new OpenApiResponses
                {
                    {
                        Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            Description = "Retrieved navigation property link",
                            Content     = new Dictionary <string, OpenApiMediaType>
                            {
                                {
                                    Constants.ApplicationJsonMediaType,
                                    new OpenApiMediaType
                                    {
                                        Schema = schema
                                    }
                                }
                            },
                            Links = links
                        }
                    }
                };
            }

            operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse());

            base.SetResponses(operation);
        }
Exemple #9
0
 public bool CanValidate(OpenApiSchema schema) => schema.Type == "null";
        private void ParseDefinitions(IDictionary <string, OpenApiSchema> schemas, Type schemaType, string route, string verb)
        {
            if (IsSwaggerScalarType(schemaType) || schemaType.ExcludesFeature(Feature.Metadata))
            {
                return;
            }

            var schemaId = GetSchemaTypeName(schemaType);

            if (schemas.ContainsKey(schemaId))
            {
                return;
            }

            var schema = GetDictionarySchema(schemas, schemaType, route, verb)
                         ?? GetKeyValuePairSchema(schemas, schemaType, route, verb)
                         ?? GetListSchema(schemas, schemaType, route, verb);

            bool parseProperties = false;

            if (schema == null)
            {
                schema = new OpenApiSchema
                {
                    Type        = OpenApiType.Object,
                    Description = schemaType.GetDescription() ?? GetSchemaTypeName(schemaType),
                    Properties  = new OrderedDictionary <string, OpenApiProperty>()
                };
                parseProperties = schemaType.IsUserType();
            }
            schemas[schemaId] = schema;

            var properties = schemaType.GetProperties();

            // Order schema properties by DataMember.Order if [DataContract] and [DataMember](s) defined
            // Ordering defined by: http://msdn.microsoft.com/en-us/library/ms729813.aspx
            var dataContractAttr = schemaType.FirstAttribute <DataContractAttribute>();

            if (dataContractAttr != null && properties.Any(prop => prop.IsDefined(typeof(DataMemberAttribute), true)))
            {
                var typeOrder = new List <Type> {
                    schemaType
                };
                var baseType = schemaType.BaseType();
                while (baseType != null)
                {
                    typeOrder.Add(baseType);
                    baseType = baseType.BaseType();
                }

                var propsWithDataMember = properties.Where(prop => prop.IsDefined(typeof(DataMemberAttribute), true));
                var propDataMemberAttrs = properties.ToDictionary(prop => prop, prop => prop.FirstAttribute <DataMemberAttribute>());

                properties = propsWithDataMember
                             .OrderBy(prop => propDataMemberAttrs[prop].Order)                // Order by DataMember.Order
                             .ThenByDescending(prop => typeOrder.IndexOf(prop.DeclaringType)) // Then by BaseTypes First
                             .ThenBy(prop =>                                                  // Then by [DataMember].Name / prop.Name
                {
                    var name = propDataMemberAttrs[prop].Name;
                    return(name.IsNullOrEmpty() ? prop.Name : name);
                }).ToArray();
            }

            if (parseProperties)
            {
                foreach (var prop in properties)
                {
                    if (prop.HasAttribute <IgnoreDataMemberAttribute>())
                    {
                        continue;
                    }

                    var apiMembers = prop
                                     .AllAttributes <ApiMemberAttribute>()
                                     .OrderByDescending(attr => attr.Route)
                                     .ToList();
                    var apiDoc = apiMembers
                                 .Where(attr => string.IsNullOrEmpty(verb) || string.IsNullOrEmpty(attr.Verb) || (verb ?? "").Equals(attr.Verb))
                                 .Where(attr => string.IsNullOrEmpty(route) || string.IsNullOrEmpty(attr.Route) || (route ?? "").StartsWith(attr.Route))
                                 .FirstOrDefault(attr => attr.ParameterType == "body" || attr.ParameterType == "model");

                    if (apiMembers.Any(x => x.ExcludeInSchema))
                    {
                        continue;
                    }
                    var schemaProp = GetOpenApiProperty(schemas, prop.PropertyType, route, verb);

                    schemaProp.Description = prop.GetDescription() ?? apiDoc?.Description;

                    var propAttr = prop.FirstAttribute <ApiMemberAttribute>();
                    if (propAttr != null)
                    {
                        if (propAttr.DataType != null)
                        {
                            schemaProp.Type = propAttr.DataType;
                        }

                        if (propAttr.Format != null)
                        {
                            schemaProp.Format = propAttr.Format;
                        }
                    }

                    var allowableValues = prop.FirstAttribute <ApiAllowableValuesAttribute>();
                    if (allowableValues != null)
                    {
                        schemaProp.Enum = GetEnumValues(allowableValues);
                    }

                    SchemaPropertyFilter?.Invoke(schemaProp);

                    schema.Properties[GetSchemaPropertyName(prop)] = schemaProp;
                }
            }
        }
Exemple #11
0
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            var typeName = context.Type.Name;

            schema.Example = !Schemas.ContainsKey(typeName) ? null : Schemas[typeName];
        }
        public static IOpenApiAny Resolve(IOpenApiAny any, OpenApiSchema schema = null)
        {
            if (any is OpenApiArray arrayAny)
            {
                var newArray = new OpenApiArray();
                foreach (var element in arrayAny)
                {
                    newArray.Add(Resolve(element, schema?.Items));
                }
                return(newArray);
            }
            if (any is OpenApiObject objectAny)
            {
                var newObject = new OpenApiObject();
                foreach (var propertyName in objectAny.Keys.ToList())
                {
                    if (schema?.Properties != null && schema.Properties.ContainsKey(propertyName))
                    {
                        newObject[propertyName] = Resolve(objectAny[propertyName], schema.Properties[propertyName]);
                    }
                    else if (schema?.AdditionalProperties != null && schema.AdditionalProperties is OpenApiSchema ss)
                    {
                        newObject[propertyName] = Resolve(objectAny[propertyName], ss);
                    }
                }
                return(newObject);
            }

            if (!(any is OpenApiString))
            {
                return(any); // already a non-string OpenApiAny
            }
            var value = ((OpenApiString)any).Value;

            if (((OpenApiString)any).Quoted) // quoted string
            {
                if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTimeValue))
                {
                    return(new OpenApiDateTime(dateTimeValue));
                }

                return(any); // actual type is OpenApiString
            }
            if (value == null)
            {
                return(new OpenApiNull());
            }
            if (schema?.Type == null)
            {
                if (value == "true")
                {
                    return(new OpenApiBoolean(true));
                }
                if (value == "false")
                {
                    return(new OpenApiBoolean(false));
                }
                if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue))
                {
                    return(new OpenApiInt32(intValue));
                }

                if (long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var longValue))
                {
                    return(new OpenApiInt64(longValue));
                }

                if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var doubleValue))
                {
                    return(new OpenApiDouble(doubleValue));
                }

                if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTimeValue))
                {
                    return(new OpenApiDateTime(dateTimeValue));
                }
            }
            else
            {
                if (schema.Type == "integer")
                {
                    if (schema.Format != null && schema.Format == "int64")
                    {
                        if (long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var longValue))
                        {
                            return(new OpenApiInt64(longValue));
                        }
                    }
                    else
                    {
                        if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue))
                        {
                            return(new OpenApiInt32(intValue));
                        }
                    }
                }
                if (schema.Type == "number")
                {
                    if (schema.Format != null && schema.Format == "float")
                    {
                        if (float.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var floatValue))
                        {
                            return(new OpenApiFloat(floatValue));
                        }
                    }
                    else
                    {
                        if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var doubleValue))
                        {
                            return(new OpenApiDouble(doubleValue));
                        }
                    }
                }
                if (schema.Type == "string")
                {
                    if (schema.Format != null && schema.Format == "byte")
                    {
                        try
                        {
                            return(new OpenApiByte(Convert.FromBase64String(value)));
                        }
                        catch (FormatException)
                        { }
                    }
                    else if (schema.Format != null && schema.Format == "binary")
                    {
                        try
                        {
                            return(new OpenApiBinary(Encoding.UTF8.GetBytes(value)));
                        }
                        catch (EncoderFallbackException)
                        { }
                    }
                    else if (schema.Format != null && (schema.Format == "date" || schema.Format == "date-time"))
                    {
                        if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateValue))
                        {
                            return(new OpenApiDate(dateValue.Date));
                        }
                    }
                    else if (schema.Format != null && schema.Format == "password")
                    {
                        return(new OpenApiPassword(value));
                    }
                    else
                    {
                        return(new OpenApiString(value));
                    }
                }
                if (schema.Type == "boolean")
                {
                    if (bool.TryParse(value, out var booleanValue))
                    {
                        return(new OpenApiBoolean(booleanValue));
                    }
                }
            }
            return(any);
        }
        /// <summary>
        /// Create a <see cref="OpenApiSchema"/> for a <see cref="IEdmPrimitiveType"/>.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="primitiveType">The Edm primitive type.</param>
        /// <returns>The created <see cref="OpenApiSchema"/>.</returns>
        public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiveType primitiveType)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(primitiveType, nameof(primitiveType));

            // Spec has different configure for double, AnyOf or OneOf?
            OpenApiSchema schema = new OpenApiSchema
            {
                AllOf = null,
                OneOf = null,
                AnyOf = null
            };

            switch (primitiveType.PrimitiveKind)
            {
            case EdmPrimitiveTypeKind.Binary:     // binary
                schema.Type   = "string";
                schema.Format = "base64url";
                break;

            case EdmPrimitiveTypeKind.Boolean:     // boolean
                schema.Type    = "boolean";
                schema.Default = new OpenApiBoolean(false);
                break;

            case EdmPrimitiveTypeKind.Byte:     // byte
                schema.Type   = "integer";
                schema.Format = "uint8";
                break;

            case EdmPrimitiveTypeKind.DateTimeOffset:     // datetime offset
                schema.Type    = "string";
                schema.Format  = "date-time";
                schema.Pattern = "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$";
                break;

            case EdmPrimitiveTypeKind.Decimal:     // decimal
                if (context.Settings.IEEE754Compatible)
                {
                    schema.AnyOf = new List <OpenApiSchema>
                    {
                        new OpenApiSchema {
                            Type = "number"
                        },
                        new OpenApiSchema {
                            Type = "string"
                        },
                    };
                }
                else
                {
                    schema.Type = "number";
                }
                schema.Format = "decimal";
                break;

            case EdmPrimitiveTypeKind.Double:     // double
                if (context.Settings.IEEE754Compatible)
                {
                    schema.AnyOf = new List <OpenApiSchema>
                    {
                        new OpenApiSchema {
                            Type = "number"
                        },
                        new OpenApiSchema {
                            Type = "string"
                        },
                        new OpenApiSchema
                        {
                            Enum = new List <IOpenApiAny>
                            {
                                new OpenApiString("-INF"),
                                new OpenApiString("INF"),
                                new OpenApiString("NaN")
                            }
                        }
                    };
                }
                else
                {
                    schema.Type = "number";
                }
                schema.Format = "double";
                break;

            case EdmPrimitiveTypeKind.Single:     // single
                if (context.Settings.IEEE754Compatible)
                {
                    schema.AnyOf = new List <OpenApiSchema>
                    {
                        new OpenApiSchema {
                            Type = "number"
                        },
                        new OpenApiSchema {
                            Type = "string"
                        },
                        new OpenApiSchema
                        {
                            Enum = new List <IOpenApiAny>
                            {
                                new OpenApiString("-INF"),
                                new OpenApiString("INF"),
                                new OpenApiString("NaN")
                            }
                        }
                    };
                }
                else
                {
                    schema.Type = "number";
                }
                schema.Format = "float";
                break;

            case EdmPrimitiveTypeKind.Guid:     // guid
                schema.Type    = "string";
                schema.Format  = "uuid";
                schema.Pattern = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$";
                break;

            case EdmPrimitiveTypeKind.Int16:
                schema.Type    = "integer";
                schema.Format  = "int16";
                schema.Minimum = Int16.MinValue;     // -32768
                schema.Maximum = Int16.MaxValue;     // 32767
                break;

            case EdmPrimitiveTypeKind.Int32:
                schema.Type    = "integer";
                schema.Format  = "int32";
                schema.Minimum = Int32.MinValue;     // -2147483648
                schema.Maximum = Int32.MaxValue;     // 2147483647
                break;

            case EdmPrimitiveTypeKind.Int64:
                if (context.Settings.IEEE754Compatible)
                {
                    schema.AnyOf = new List <OpenApiSchema>
                    {
                        new OpenApiSchema {
                            Type = "integer"
                        },
                        new OpenApiSchema {
                            Type = "string"
                        }
                    };
                }
                else
                {
                    schema.Type = "integer";
                }

                schema.Format = "int64";
                break;

            case EdmPrimitiveTypeKind.SByte:
                schema.Type    = "integer";
                schema.Format  = "int8";
                schema.Minimum = SByte.MinValue;     // -128
                schema.Maximum = SByte.MaxValue;     // 127
                break;

            case EdmPrimitiveTypeKind.String:     // string
                schema.Type = "string";
                break;

            case EdmPrimitiveTypeKind.Stream:     // stream
                schema.Type   = "string";
                schema.Format = "base64url";
                break;

            case EdmPrimitiveTypeKind.Duration:     // duration
                schema.Type    = "string";
                schema.Format  = "duration";
                schema.Pattern = "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$";
                break;

            case EdmPrimitiveTypeKind.Date:
                schema.Type    = "string";
                schema.Format  = "date";
                schema.Pattern = "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$";
                break;

            case EdmPrimitiveTypeKind.TimeOfDay:
                schema.Type    = "string";
                schema.Format  = "time";
                schema.Pattern = "^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?$";
                break;

            case EdmPrimitiveTypeKind.Geography:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.Geography"
                };
                break;

            case EdmPrimitiveTypeKind.GeographyPoint:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeographyPoint"
                };
                break;

            case EdmPrimitiveTypeKind.GeographyLineString:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeographyLineString"
                };
                break;

            case EdmPrimitiveTypeKind.GeographyPolygon:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeographyPolygon"
                };
                break;

            case EdmPrimitiveTypeKind.GeographyCollection:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeographyCollection"
                };
                break;

            case EdmPrimitiveTypeKind.GeographyMultiPolygon:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeographyMultiPolygon"
                };
                break;

            case EdmPrimitiveTypeKind.GeographyMultiLineString:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeographyMultiLineString"
                };
                break;

            case EdmPrimitiveTypeKind.GeographyMultiPoint:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeographyMultiPoint"
                };
                break;

            case EdmPrimitiveTypeKind.Geometry:     // Geometry
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.Geometry"
                };
                break;

            case EdmPrimitiveTypeKind.GeometryPoint:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeometryPoint"
                };
                break;

            case EdmPrimitiveTypeKind.GeometryLineString:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeometryLineString"
                };
                break;

            case EdmPrimitiveTypeKind.GeometryPolygon:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeometryPolygon"
                };
                break;

            case EdmPrimitiveTypeKind.GeometryCollection:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeometryCollection"
                };
                break;

            case EdmPrimitiveTypeKind.GeometryMultiPolygon:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeometryMultiPolygon"
                };
                break;

            case EdmPrimitiveTypeKind.GeometryMultiLineString:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeometryMultiLineString"
                };
                break;

            case EdmPrimitiveTypeKind.GeometryMultiPoint:
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = "Edm.GeometryMultiPoint"
                };
                break;

            case EdmPrimitiveTypeKind.None:
            default:
                throw new OpenApiException(String.Format(SRResource.NotSupportedEdmTypeKind, primitiveType.PrimitiveKind));
            }

            return(schema);
        }
Exemple #14
0
        public void Given_Type_When_ParameterVisit_Invoked_Then_It_Should_Return_Result(Type objectType, string dataType, string dataFormat, OpenApiSchema expected)
        {
            var result = this._visitor.ParameterVisit(objectType, this._strategy);

            result.Should().Be(expected);
        }
        /// <summary>
        /// Fetches the value of "param" tags from xml documentation with in valus of "body"
        /// and populates operation's request body.
        /// </summary>
        /// <param name="operation">The operation to be updated.</param>
        /// <param name="element">The xml element representing an operation in the annotation xml.</param>
        /// <param name="settings">The operation filter settings.</param>
        /// <returns>The list of generation errors, if any produced when processing the filter.</returns>
        /// <remarks>
        /// Care should be taken to not overwrite the existing value in Operation if already present.
        /// This guarantees the predictable behavior that the first tag in the XML will be respected.
        /// It also guarantees that common annotations in the config file do not overwrite the
        /// annotations in the main documentation.
        /// </remarks>
        public IList <GenerationError> Apply(
            OpenApiOperation operation,
            XElement element,
            OperationFilterSettings settings)
        {
            var generationErrors = new List <GenerationError>();

            try
            {
                var bodyElements = element.Elements()
                                   .Where(
                    p => p.Name == KnownXmlStrings.Param &&
                    p.Attribute(KnownXmlStrings.In)?.Value == KnownXmlStrings.Body)
                                   .ToList();

                var generationContext = settings.GenerationContext;

                foreach (var bodyElement in bodyElements)
                {
                    var name      = bodyElement.Attribute(KnownXmlStrings.Name)?.Value.Trim();
                    var mediaType = bodyElement.Attribute(KnownXmlStrings.Type)?.Value ?? "application/json";

                    var description = bodyElement.GetDescriptionTextFromLastTextNode();

                    var allListedTypes = bodyElement.GetListedTypes();

                    if (!allListedTypes.Any())
                    {
                        throw new InvalidRequestBodyException(
                                  string.Format(SpecificationGenerationMessages.MissingSeeCrefTag, name));
                    }

                    var crefKey = allListedTypes.ToCrefKey();

                    OpenApiSchema schema = new OpenApiSchema();
                    if (generationContext.CrefToSchemaMap.ContainsKey(crefKey))
                    {
                        var schemaInfo = generationContext.CrefToSchemaMap[crefKey];

                        if (schemaInfo.Error != null)
                        {
                            generationErrors.Add(schemaInfo.Error);

                            return(generationErrors);
                        }

                        schemaInfo.Schema.CopyInto(schema);
                    }

                    var examples = bodyElement.ToOpenApiExamples(
                        generationContext.CrefToFieldValueMap,
                        generationErrors);

                    var schemaReferenceDefaultVariant = generationContext
                                                        .VariantSchemaReferenceMap[DocumentVariantInfo.Default];

                    if (examples.Count > 0)
                    {
                        var firstExample = examples.First().Value?.Value;

                        if (firstExample != null)
                        {
                            // In case a schema is a reference, find that schema object in schema registry
                            // and update the example.
                            if (schema.Reference != null)
                            {
                                if (schemaReferenceDefaultVariant.ContainsKey(schema.Reference.Id))
                                {
                                    schemaReferenceDefaultVariant[schema.Reference.Id].Example = firstExample;
                                }
                            }
                            else
                            {
                                schema.Example = firstExample;
                            }
                        }
                    }

                    if (operation.RequestBody == null)
                    {
                        operation.RequestBody = new OpenApiRequestBody
                        {
                            Description = description.RemoveBlankLines(),
                            Content     =
                            {
                                [mediaType] = new OpenApiMediaType {
                                    Schema = schema
                                }
                            },
                            Required = true
                        };
                    }
                    else
                    {
                        if (string.IsNullOrWhiteSpace(operation.RequestBody.Description))
                        {
                            operation.RequestBody.Description = description.RemoveBlankLines();
                        }

                        if (!operation.RequestBody.Content.ContainsKey(mediaType))
                        {
                            operation.RequestBody.Content[mediaType] = new OpenApiMediaType
                            {
                                Schema = schema
                            };
                        }
                        else
                        {
                            if (!operation.RequestBody.Content[mediaType].Schema.AnyOf.Any())
                            {
                                var existingSchema = operation.RequestBody.Content[mediaType].Schema;
                                var newSchema      = new OpenApiSchema();
                                newSchema.AnyOf.Add(existingSchema);

                                operation.RequestBody.Content[mediaType].Schema = newSchema;
                            }

                            operation.RequestBody.Content[mediaType].Schema.AnyOf.Add(schema);
                        }
                    }

                    if (examples.Count > 0)
                    {
                        if (operation.RequestBody.Content[mediaType].Examples.Any())
                        {
                            examples.CopyInto(operation.RequestBody.Content[mediaType].Examples);
                        }
                        else
                        {
                            operation.RequestBody.Content[mediaType].Examples = examples;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                generationErrors.Add(
                    new GenerationError
                {
                    Message       = ex.Message,
                    ExceptionType = ex.GetType().Name
                });
            }

            return(generationErrors);
        }
        private static OpenApiResponse GetResponse(string returnDescStr)
        {
            if (string.IsNullOrEmpty(returnDescStr) || !returnDescStr.StartsWith('{'))
            {
                var resp = new OpenApiResponse
                {
                    Description = "Success",
                    Content     = new Dictionary <string, OpenApiMediaType>()
                };
                resp.Content.Add("application/json", new OpenApiMediaType
                {
                    Schema = new OpenApiSchema
                    {
                        Type    = "object",
                        Default = new OpenApiString(returnDescStr)
                    }
                });
                return(resp);
            }
            var returnDesc = JsonConvert.DeserializeObject <JimuServiceReturnDesc>(TypeHelper.ReplaceTypeToJsType(returnDescStr));
            var response   = new OpenApiResponse
            {
                Description = string.IsNullOrEmpty(returnDesc.Comment) ? "Success" : returnDesc.Comment,
                Content     = new Dictionary <string, OpenApiMediaType>()
            };

            var isVoid = returnDesc.ReturnType == "System.Void";

            if (isVoid)
            {
                return(response);
            }

            var isObject = TypeHelper.CheckIsObject(returnDesc.ReturnType);
            var isArray  = TypeHelper.CheckIsArray(returnDesc.ReturnType);
            var schema   = new OpenApiSchema
            {
                Type = returnDesc.ReturnType
            };

            if ((isObject || isArray) && returnDesc.Properties != null && returnDesc.Properties.Any())
            {
                if (isArray)
                {
                    schema = new OpenApiSchema
                    {
                        Type        = "array",
                        Title       = returnDesc.Comment,
                        Description = returnDesc.Comment,
                        Items       = new OpenApiSchema {
                            Properties = _schemaFactory.GetProperties(returnDesc.Properties)
                        }
                    };
                }
                else
                {
                    schema = new OpenApiSchema
                    {
                        Type        = "object",
                        Title       = returnDesc.Comment,
                        Description = returnDesc.Comment,
                        Properties  = _schemaFactory.GetProperties(returnDesc.Properties)
                    };
                }
            }
            response.Content.Add("application/json", new OpenApiMediaType
            {
                Schema = schema
            });
            return(response);
        }
Exemple #17
0
 public void Apply(OpenApiSchema schema, SchemaFilterContext context)
 {
     throw new System.NotImplementedException();
 }
        private OpenApiSchema CreateObjectSchema(DataContract dataContract, SchemaRepository schemaRepository)
        {
            var schema = new OpenApiSchema
            {
                Type       = "object",
                Properties = new Dictionary <string, OpenApiSchema>(),
                Required   = new SortedSet <string>(),
                AdditionalPropertiesAllowed = false
            };

            var applicableDataProperties = dataContract.ObjectProperties;

            if (_generatorOptions.UseAllOfForInheritance || _generatorOptions.UseOneOfForPolymorphism)
            {
                if (IsKnownSubType(dataContract, out var baseTypeDataContract))
                {
                    var baseTypeSchema = GenerateConcreteSchema(baseTypeDataContract, schemaRepository);

                    schema.AllOf.Add(baseTypeSchema);

                    applicableDataProperties = applicableDataProperties
                                               .Where(dataProperty => !dataProperty.MemberInfo.DeclaringType.IsAssignableFrom(baseTypeDataContract.UnderlyingType));
                }

                if (IsBaseTypeWithKnownTypesDefined(dataContract, out var knownTypesDataContracts))
                {
                    foreach (var knownTypeDataContract in knownTypesDataContracts)
                    {
                        // Ensure schema is generated for all known types
                        GenerateConcreteSchema(knownTypeDataContract, schemaRepository);
                    }

                    if (TryGetDiscriminatorFor(dataContract, schemaRepository, knownTypesDataContracts, out var discriminator))
                    {
                        schema.Properties.Add(discriminator.PropertyName, new OpenApiSchema {
                            Type = "string"
                        });
                        schema.Required.Add(discriminator.PropertyName);
                        schema.Discriminator = discriminator;
                    }
                }
            }

            foreach (var dataProperty in applicableDataProperties)
            {
                var customAttributes = dataProperty.MemberInfo?.GetInlineAndMetadataAttributes() ?? Enumerable.Empty <object>();

                if (_generatorOptions.IgnoreObsoleteProperties && customAttributes.OfType <ObsoleteAttribute>().Any())
                {
                    continue;
                }

                schema.Properties[dataProperty.Name] = (dataProperty.MemberInfo != null)
                    ? GenerateSchemaForMember(dataProperty.MemberType, schemaRepository, dataProperty.MemberInfo, dataProperty)
                    : GenerateSchemaForType(dataProperty.MemberType, schemaRepository);

                if ((dataProperty.IsRequired || customAttributes.OfType <RequiredAttribute>().Any()) &&
                    !schema.Required.Contains(dataProperty.Name))
                {
                    schema.Required.Add(dataProperty.Name);
                }
            }

            if (dataContract.ObjectExtensionDataType != null)
            {
                schema.AdditionalPropertiesAllowed = true;
                schema.AdditionalProperties        = GenerateSchema(dataContract.ObjectExtensionDataType, schemaRepository);
            }

            return(schema);
        }
    public static void AppendModel(
        int indentSpaces,
        StringBuilder sb,
        EndpointMethodMetadata endpointMethodMetadata,
        string modelName,
        OpenApiSchema schema,
        TrailingCharType trailingChar,
        int itemNumber,
        int maxItemsForList,
        int depthHierarchy,
        int maxDepthHierarchy,
        KeyValuePair <string, OpenApiSchema>?badPropertySchema,
        bool asJsonBody,
        string?parentModelNameToJsonBody = null)
    {
        ArgumentNullException.ThrowIfNull(sb);
        ArgumentNullException.ThrowIfNull(schema);

        var countString     = 1;
        var renderModelName = OpenApiDocumentSchemaModelNameHelper.EnsureModelNameWithNamespaceIfNeeded(endpointMethodMetadata, modelName);
        var jsonSpaces      = string.Empty.PadLeft(depthHierarchy * 2);

        if (asJsonBody)
        {
            sb.AppendLine(
                indentSpaces,
                string.IsNullOrEmpty(parentModelNameToJsonBody)
                    ? GenerateXunitTestPartsHelper.WrapInStringBuilderAppendLine($"{jsonSpaces}{{")
                    : GenerateXunitTestPartsHelper.WrapInStringBuilderAppendLine($"{jsonSpaces}\\\"{parentModelNameToJsonBody}\\\": {{"));
        }
        else
        {
            sb.AppendLine(renderModelName);
            sb.AppendLine(indentSpaces, "{");
        }

        foreach (var schemaProperty in schema.Properties)
        {
            var trailingCharForProperty = GenerateXunitTestPartsHelper.GetTrailingCharForProperty(asJsonBody, schemaProperty, schema.Properties);
            var useForBadRequest        = badPropertySchema is not null &&
                                          schemaProperty.Key.Equals(badPropertySchema.Value.Key, StringComparison.Ordinal);

            var dataType = schemaProperty.Value.GetDataType();

            var propertyValueGenerated = GenerateXunitTestPartsHelper.PropertyValueGenerator(
                schemaProperty,
                endpointMethodMetadata.ComponentsSchemas,
                useForBadRequest,
                itemNumber,
                customValue: null);

            if ("NEW-INSTANCE-LIST".Equals(propertyValueGenerated, StringComparison.Ordinal))
            {
                AppendDataEqualNewListOfModel(
                    indentSpaces + 4,
                    sb,
                    endpointMethodMetadata,
                    schemaProperty,
                    trailingCharForProperty,
                    maxItemsForList,
                    depthHierarchy + 1,
                    maxDepthHierarchy,
                    badPropertySchema,
                    asJsonBody);
            }
            else if ("NEW-INSTANCE".Equals(propertyValueGenerated, StringComparison.Ordinal))
            {
                AppendModelComplexProperty(
                    indentSpaces,
                    sb,
                    endpointMethodMetadata,
                    schemaProperty,
                    dataType,
                    trailingCharForProperty,
                    itemNumber,
                    maxItemsForList,
                    depthHierarchy + 1,
                    maxDepthHierarchy,
                    badPropertySchema,
                    asJsonBody);
            }
            else
            {
                var countResult = GenerateXunitTestPartsHelper.AppendModelSimpleProperty(
                    indentSpaces,
                    sb,
                    endpointMethodMetadata,
                    schemaProperty,
                    dataType,
                    schema.Required.Contains(schemaProperty.Key),
                    propertyValueGenerated,
                    countString,
                    asJsonBody,
                    depthHierarchy,
                    trailingCharForProperty);

                if (countResult > 1)
                {
                    countString += 1;
                }
            }
        }

        sb.AppendLine(
            indentSpaces,
            asJsonBody
                ? GenerateXunitTestPartsHelper.WrapInStringBuilderAppendLine($"{jsonSpaces}}}{GenerateCodeHelper.GetTrailingChar(trailingChar)}")
                : $"}}{GenerateCodeHelper.GetTrailingChar(trailingChar)}");
    }
Exemple #20
0
 private static void CompareOpenApiSchema(List <Change> changes, OpenApiSchema before, OpenApiSchema after, ChangeType changeType)
 {
     // TODO: Flesh out and check for nulls (both nulls)
 }
        private OpenApiSchema GenerateObjectSchema(DataContract dataContract, SchemaRepository schemaRepository)
        {
            var schema = new OpenApiSchema
            {
                Type       = "object",
                Properties = new Dictionary <string, OpenApiSchema>(),
                Required   = new SortedSet <string>(),
                AdditionalPropertiesAllowed = false
            };

            // By default, all properties will be defined in this schema
            // However, if "Inheritance" behavior is enabled (see below), this set will be reduced to declared properties only
            var applicableDataProperties = dataContract.ObjectProperties;

            if (_generatorOptions.UseOneOfForPolymorphism || _generatorOptions.UseAllOfForInheritance)
            {
                if (IsBaseTypeWithKnownSubTypes(dataContract.UnderlyingType, out IEnumerable <Type> subTypes))
                {
                    if (_generatorOptions.UseAllOfForInheritance)
                    {
                        // Ensure a schema for all known sub types is generated and added to the repository
                        foreach (var subType in subTypes)
                        {
                            var subTypeContract = _serializerBehavior.GetDataContractForType(subType);
                            GenerateReferencedSchema(subType, schemaRepository, () => GenerateObjectSchema(subTypeContract, schemaRepository));
                        }
                    }

                    if (_generatorOptions.UseOneOfForPolymorphism &&
                        TryGetDiscriminatorName(dataContract, out string discriminatorName))
                    {
                        schema.Properties.Add(discriminatorName, new OpenApiSchema {
                            Type = "string"
                        });
                        schema.Required.Add(discriminatorName);
                    }
                }

                if (IsKnownSubType(dataContract.UnderlyingType, out Type baseType))
                {
                    var baseTypeContract = _serializerBehavior.GetDataContractForType(baseType);

                    if (_generatorOptions.UseAllOfForInheritance)
                    {
                        schema.AllOf = new List <OpenApiSchema>
                        {
                            GenerateReferencedSchema(baseType, schemaRepository, () => GenerateObjectSchema(baseTypeContract, schemaRepository))
                        };

                        // Reduce the set of properties to be defined in this schema to declared properties only
                        applicableDataProperties = applicableDataProperties
                                                   .Where(dataProperty => dataProperty.MemberInfo?.DeclaringType == dataContract.UnderlyingType);
                    }

                    if (_generatorOptions.UseOneOfForPolymorphism && !_generatorOptions.UseAllOfForInheritance &&
                        TryGetDiscriminatorName(baseTypeContract, out string discriminatorName))
                    {
                        schema.Properties.Add(discriminatorName, new OpenApiSchema {
                            Type = "string"
                        });
                        schema.Required.Add(discriminatorName);
                    }
                }
            }

            foreach (var dataProperty in applicableDataProperties)
            {
                var customAttributes = dataProperty.MemberInfo?.GetInlineAndMetadataAttributes() ?? Enumerable.Empty <object>();

                if (_generatorOptions.IgnoreObsoleteProperties && customAttributes.OfType <ObsoleteAttribute>().Any())
                {
                    continue;
                }

                schema.Properties[dataProperty.Name] = GeneratePropertySchema(dataProperty, schemaRepository);

                if (dataProperty.IsRequired || customAttributes.OfType <RequiredAttribute>().Any() &&
                    !schema.Required.Contains(dataProperty.Name))
                {
                    schema.Required.Add(dataProperty.Name);
                }
            }

            if (dataContract.ObjectExtensionDataType != null)
            {
                schema.AdditionalPropertiesAllowed = true;
                schema.AdditionalProperties        = GenerateSchema(dataContract.ObjectExtensionDataType, schemaRepository);
            }

            return(schema);
        }
 /// <summary>
 /// Visits <see cref="OpenApiSchema"/>
 /// </summary>
 public virtual void Visit(OpenApiSchema schema)
 {
 }
        public void Given_Type_When_PayloadVisit_Invoked_Then_It_Should_Return_Null(Type type, OpenApiSchema expected)
        {
            var result = this._visitor.PayloadVisit(type, this._strategy);

            result.Should().Be(expected);
        }
 /*
  * static void FixProperty (JsonSchema4 item , string name)
  * {
  *  if (item.Properties.Keys.Contains(name))
  *  {
  *      item.Properties.Remove(name);
  *
  *      JsonProperty jsonProperty = new JsonProperty();
  *      jsonProperty.Type = JsonObjectType.String;
  *      jsonProperty.IsNullableRaw = true;
  *      KeyValuePair<string, JsonProperty> keyValuePair = new KeyValuePair<string, JsonProperty>(name, jsonProperty);
  *
  *      item.Properties.Add(keyValuePair);
  *
  *  }
  * }
  */
 static void CheckProperties(OpenApiDocument swaggerDocument, List <string> itemsToKeep, OpenApiSchema item)
 {
     if (item.Reference != null)
     {
         string title = item.Reference.Id;
         if (title != null && !itemsToKeep.Contains(title))
         {
             // recursive call.
             AddSubItems(swaggerDocument, itemsToKeep, title);
         }
     }
     else
     {
         if (item.Type != null && (item.Type == "object" || item.Type == "array") &&
             item.Items?.Reference?.Id != null)
         {
             string title = item.Items.Reference.Id;
             if (title != null && !itemsToKeep.Contains(title))
             {
                 // recursive call.
                 AddSubItems(swaggerDocument, itemsToKeep, title);
             }
         }
     }
     if (item.Properties != null)
     {
         foreach (var property in item.Properties)
         {
             if (property.Value.Reference != null)
             {
                 string title = property.Value.Reference.Id;
                 if (title != null && !itemsToKeep.Contains(title))
                 {
                     // recursive call.
                     AddSubItems(swaggerDocument, itemsToKeep, title);
                 }
             }
             else
             {
                 if ((property.Value.Type == "object" || property.Value.Type == "array") &&
                     property.Value.Items?.Reference?.Id != null)
                 {
                     string id = property.Value.Items.Reference.Id;
                     if (id != null && !itemsToKeep.Contains(id))
                     {
                         // recursive call.
                         AddSubItems(swaggerDocument, itemsToKeep, id);
                     }
                 }
             }
         }
     }
 }
Exemple #25
0
 public void Apply(OpenApiSchema schema, SchemaFilterContext context)
 {
     schema.Extensions.Add("X-foo", new OpenApiString("bar"));
 }
        public Dictionary <string, OpenApiSchema> SchemaFromObject()
        {
            Dictionary <string, OpenApiSchema> Lista = new Dictionary <string, OpenApiSchema>();

            foreach (Ac4yClass ac4yClass in Parameter.ClassList)
            {
                Dictionary <string, OpenApiSchema> PropertyLista          = new Dictionary <string, OpenApiSchema>();
                Dictionary <string, OpenApiSchema> PropertyListaWithoutID = new Dictionary <string, OpenApiSchema>();

                foreach (Ac4yProperty property in ac4yClass.PropertyList)
                {
                    if (property.Cardinality.Equals("COLLECTION"))
                    {
                        PropertyLista.Add(property.Name, new OpenApiSchema()
                        {
                            Type  = "array",
                            Items = new OpenApiSchema()
                            {
                                Type  = "object",
                                Title = property.TypeName
                            },
                            Nullable    = true,
                            Description = property.Description
                        });
                    }
                    else if (property.NavigationProperty == true)
                    {
                        PropertyLista.Add(property.Name, new OpenApiSchema()
                        {
                            Type        = "object",
                            Description = property.Description,
                            Title       = property.Name,
                            Nullable    = true
                        });
                    }
                    else
                    {
                        PropertyLista.Add(property.Name, new OpenApiSchema()
                        {
                            Type        = GetConvertedType(property.TypeName, TipusKonverziok),
                            Format      = GetConvertedType(property.TypeName, FormaKonverziok),
                            Description = property.Description
                        });


                        if (!property.Name.Equals("Id"))
                        {
                            PropertyListaWithoutID.Add(property.Name, new OpenApiSchema()
                            {
                                Type        = GetConvertedType(property.TypeName, TipusKonverziok),
                                Format      = GetConvertedType(property.TypeName, FormaKonverziok),
                                Description = property.Description
                            });
                        }
                    }
                }
                ;

                OpenApiSchema Schema = new OpenApiSchema()
                {
                    Properties = PropertyLista
                };
                OpenApiSchema SchemaWithoutID = new OpenApiSchema()
                {
                    Properties = PropertyListaWithoutID
                };
                Lista.Add(ac4yClass.Name, Schema);
                Lista.Add(ac4yClass.Name + "WithoutID", SchemaWithoutID);
            }

            return(Lista);
        }
        private static object MapSchemaToObject(OpenApiSchema schema, string name = null)
        {
            if (schema == null)
            {
                return(null);
            }

            switch (schema.GetSchemaType())
            {
            case SchemaType.Array:
                var jArray = new JArray();
                for (int i = 0; i < ArrayItems; i++)
                {
                    if (schema.Items.Properties.Count > 0)
                    {
                        var arrayItem = new JObject();
                        foreach (var property in schema.Items.Properties)
                        {
                            var objectValue = MapSchemaToObject(property.Value, property.Key);
                            if (objectValue is JProperty jp)
                            {
                                arrayItem.Add(jp);
                            }
                            else
                            {
                                arrayItem.Add(new JProperty(property.Key, objectValue));
                            }
                        }

                        jArray.Add(arrayItem);
                    }
                    else
                    {
                        jArray.Add(MapSchemaToObject(schema.Items, name));
                    }
                }

                return(jArray);

            case SchemaType.Boolean:
            case SchemaType.Integer:
            case SchemaType.Number:
            case SchemaType.String:
                return(ExampleValueGenerator.GetExampleValue(schema));

            case SchemaType.Object:
                var propertyAsJObject = new JObject();
                foreach (var schemaProperty in schema.Properties)
                {
                    string propertyName  = schemaProperty.Key;
                    var    openApiSchema = schemaProperty.Value;
                    if (openApiSchema.GetSchemaType() == SchemaType.Object)
                    {
                        var mapped = MapSchemaToObject(schemaProperty.Value, schemaProperty.Key);
                        if (mapped is JProperty jp)
                        {
                            propertyAsJObject.Add(jp);
                        }
                    }
                    else
                    {
                        bool propertyIsNullable = openApiSchema.Nullable || (openApiSchema.TryGetXNullable(out bool x) && x);

                        propertyAsJObject.Add(new JProperty(propertyName, ExampleValueGenerator.GetExampleValue(openApiSchema)));
                    }
                }

                return(name != null ? new JProperty(name, propertyAsJObject) : (JToken)propertyAsJObject);

            default:
                return(null);
            }
        }
        public static Dictionary <string, OpenApiSchema> ToOpenApiSchemas(this Type type, NamingStrategy namingStrategy, OpenApiSchemaVisibilityAttribute attribute = null, bool returnSingleSchema = false, int depth = 0)
        {
            type.ThrowIfNullOrDefault();

            var schema     = (OpenApiSchema)null;
            var schemeName = type.GetOpenApiTypeName(namingStrategy);

            if (depth == 8)
            {
                schema = new OpenApiSchema()
                {
                    Type   = type.ToDataType(),
                    Format = type.ToDataFormat()
                };

                return(new Dictionary <string, OpenApiSchema>()
                {
                    { schemeName, schema }
                });
            }

            depth++;

            if (type.IsJObjectType())
            {
                schema = typeof(object).ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value;

                return(new Dictionary <string, OpenApiSchema>()
                {
                    { schemeName, schema }
                });
            }

            if (type.IsOpenApiNullable(out var unwrappedValueType))
            {
                schema          = unwrappedValueType.ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value;
                schema.Nullable = true;

                return(new Dictionary <string, OpenApiSchema>()
                {
                    { schemeName, schema }
                });
            }

            schema = new OpenApiSchema()
            {
                Type   = type.ToDataType(),
                Format = type.ToDataFormat()
            };

            if (!attribute.IsNullOrDefault())
            {
                var visibility = new OpenApiString(attribute.Visibility.ToDisplayName());

                schema.Extensions.Add("x-ms-visibility", visibility);
            }

            if (type.IsUnflaggedEnumType())
            {
                var converterAttribute = type.GetCustomAttribute <JsonConverterAttribute>();
                if (!converterAttribute.IsNullOrDefault() &&
                    typeof(StringEnumConverter).IsAssignableFrom(converterAttribute.ConverterType))
                {
                    var enums = type.ToOpenApiStringCollection(namingStrategy);

                    schema.Type    = "string";
                    schema.Format  = null;
                    schema.Enum    = enums;
                    schema.Default = enums.First();
                }
                else
                {
                    var enums = type.ToOpenApiIntegerCollection();

                    schema.Enum    = enums;
                    schema.Default = enums.First();
                }
            }

            if (type.IsSimpleType())
            {
                return(new Dictionary <string, OpenApiSchema>()
                {
                    { schemeName, schema }
                });
            }

            if (type.IsOpenApiDictionary())
            {
                schema.AdditionalProperties = type.GetGenericArguments()[1].ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value;

                return(new Dictionary <string, OpenApiSchema>()
                {
                    { schemeName, schema }
                });
            }

            if (type.IsOpenApiArray())
            {
                schema.Type  = "array";
                schema.Items = (type.GetElementType() ?? type.GetGenericArguments()[0]).ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value;

                return(new Dictionary <string, OpenApiSchema>()
                {
                    { schemeName, schema }
                });
            }

            var allProperties = type.IsInterface
                                    ? new[] { type }.Concat(type.GetInterfaces()).SelectMany(i => i.GetProperties())
                                    : type.GetProperties();
            var properties = allProperties.Where(p => !p.ExistsCustomAttribute <JsonIgnoreAttribute>());

            var retVal = new Dictionary <string, OpenApiSchema>();

            foreach (var property in properties)
            {
                var visiblity    = property.GetCustomAttribute <OpenApiSchemaVisibilityAttribute>(inherit: false);
                var propertyName = property.GetJsonPropertyName(namingStrategy);

                var ts = property.DeclaringType.GetGenericArguments();
                if (!ts.Any())
                {
                    if (property.PropertyType.IsUnflaggedEnumType() && !returnSingleSchema)
                    {
                        var recur1 = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, false, depth);
                        retVal.AddRange(recur1);

                        var enumReference = new OpenApiReference()
                        {
                            Type = ReferenceType.Schema,
                            Id   = property.PropertyType.GetOpenApiReferenceId(false, false)
                        };

                        var schema1 = new OpenApiSchema()
                        {
                            Reference = enumReference
                        };
                        schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = schema1;
                    }
                    else if (property.PropertyType.IsSimpleType() || Nullable.GetUnderlyingType(property.PropertyType) != null || returnSingleSchema)
                    {
                        schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, true, depth).Single().Value;
                    }
                    else if (property.PropertyType.IsOpenApiDictionary())
                    {
                        var elementType = property.PropertyType.GetGenericArguments()[1];
                        if (elementType.IsSimpleType() || elementType.IsOpenApiDictionary() || elementType.IsOpenApiArray())
                        {
                            schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, true, depth).Single().Value;
                        }
                        else
                        {
                            var recur1 = elementType.ToOpenApiSchemas(namingStrategy, visiblity, false, depth);
                            retVal.AddRange(recur1);

                            var elementReference = new OpenApiReference()
                            {
                                Type = ReferenceType.Schema,
                                Id   = elementType.GetOpenApiReferenceId(false, false)
                            };

                            var dictionarySchema = new OpenApiSchema()
                            {
                                Type = "object",
                                AdditionalProperties = new OpenApiSchema()
                                {
                                    Reference = elementReference
                                }
                            };

                            schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = dictionarySchema;
                        }
                    }
                    else if (property.PropertyType.IsOpenApiArray())
                    {
                        var elementType = property.PropertyType.GetElementType() ?? property.PropertyType.GetGenericArguments()[0];
                        if (elementType.IsSimpleType() || elementType.IsOpenApiDictionary() || elementType.IsOpenApiArray())
                        {
                            schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, true, depth).Single().Value;
                        }
                        else
                        {
                            var elementReference = elementType.ToOpenApiSchemas(namingStrategy, visiblity, false, depth);
                            retVal.AddRange(elementReference);

                            var reference1 = new OpenApiReference()
                            {
                                Type = ReferenceType.Schema,
                                Id   = elementType.GetOpenApiReferenceId(false, false)
                            };
                            var arraySchema = new OpenApiSchema()
                            {
                                Type  = "array",
                                Items = new OpenApiSchema()
                                {
                                    Reference = reference1
                                }
                            };

                            schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = arraySchema;
                        }
                    }
                    else
                    {
                        var recur1 = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, false, depth);
                        retVal.AddRange(recur1);

                        var reference1 = new OpenApiReference()
                        {
                            Type = ReferenceType.Schema,
                            Id   = property.PropertyType.GetOpenApiReferenceId(false, false)
                        };

                        var schema1 = new OpenApiSchema()
                        {
                            Reference = reference1
                        };

                        schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = schema1;
                    }

                    continue;
                }

                var reference = new OpenApiReference()
                {
                    Type = ReferenceType.Schema,
                    Id   = property.PropertyType.GetOpenApiRootReferenceId()
                };

                var referenceSchema = new OpenApiSchema()
                {
                    Reference = reference
                };

                if (!ts.Contains(property.PropertyType))
                {
                    if (property.PropertyType.IsOpenApiDictionary())
                    {
                        reference.Id = property.PropertyType.GetOpenApiReferenceId(true, false);
                        var dictionarySchema = new OpenApiSchema()
                        {
                            Type = "object",
                            AdditionalProperties = referenceSchema
                        };

                        schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = dictionarySchema;

                        continue;
                    }

                    if (property.PropertyType.IsOpenApiArray())
                    {
                        reference.Id = property.PropertyType.GetOpenApiReferenceId(false, true);
                        var arraySchema = new OpenApiSchema()
                        {
                            Type  = "array",
                            Items = referenceSchema
                        };

                        schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = arraySchema;

                        continue;
                    }

                    schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visiblity, true, depth).Single().Value;

                    continue;
                }

                schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = referenceSchema;
            }

            retVal[schemeName] = schema;

            return(retVal);
        }
 public static string GetSchemaTitle(this OpenApiSchema schema)
 {
     return(schema.GetSchemaTitles().LastOrDefault()?.TrimStart('$'));// OData $ref
 }
Exemple #30
0
        public override void Parse(OpenApiObject data, IEndpointsParser parser)
        {
            base.Parse(data, parser);

            Schema = data.GetSchema("schema");
        }