Esempio n. 1
0
 private OpenApiSchema GenerateArraySchema(SerializerContract serializerContract, SchemaRepository schemaRepository)
 {
     return(new OpenApiSchema
     {
         Type = "array",
         Items = GenerateSchema(serializerContract.ArrayItemType, schemaRepository),
         UniqueItems = serializerContract.Type.IsSet() ? (bool?)true : null
     });
 }
Esempio n. 2
0
 private OpenApiSchema GenerateReferencedSchema(SerializerContract serializerContract, SchemaRepository schemaRepository)
 {
     return(schemaRepository.GetOrAdd(
                serializerContract.Type,
                _generatorOptions.SchemaIdSelector(serializerContract.Type),
                () =>
     {
         var schema = GenerateInlineSchema(serializerContract, schemaRepository);
         ApplyFilters(schema, serializerContract.Type, schemaRepository);
         return schema;
     }));
 }
Esempio n. 3
0
        private OpenApiSchema GeneratePrimitiveSchema(SerializerContract serializerContract)
        {
            var schema = new OpenApiSchema
            {
                Type   = serializerContract.DataType,
                Format = serializerContract.DataFormat
            };

            if (serializerContract.EnumValues != null)
            {
                schema.Enum = serializerContract.EnumValues
                              .Select(value => OpenApiAnyFactory.CreateFor(schema, value))
                              .ToList();
            }

            return(schema);
        }
Esempio n. 4
0
        private OpenApiSchema GenerateDictionarySchema(SerializerContract serializerContract, SchemaRepository schemaRepository)
        {
            if (serializerContract.DictionaryKeyType.IsEnum)
            {
                // This is a special case where we can include named properties based on the enum values
                return(new OpenApiSchema
                {
                    Type = "object",
                    Properties = serializerContract.DictionaryKeyType.GetEnumNames()
                                 .ToDictionary(
                        name => name,
                        name => GenerateSchema(serializerContract.DictionaryValueType, schemaRepository)
                        )
                });
            }

            return(new OpenApiSchema
            {
                Type = "object",
                AdditionalPropertiesAllowed = true,
                AdditionalProperties = GenerateSchema(serializerContract.DictionaryValueType, schemaRepository)
            });
        }
        public SerializerContract GetSerializerContractForType(Type type)
        {
            var underlyingType = type.IsNullable(out Type innerType) ? innerType : type;

            if (PrimitiveTypesAndFormats.ContainsKey(underlyingType))
            {
                var primitiveTypeAndFormat = PrimitiveTypesAndFormats[underlyingType];
                return(SerializerContract.ForPrimitive(underlyingType, primitiveTypeAndFormat.Item1, primitiveTypeAndFormat.Item2));
            }

            if (underlyingType.IsEnum)
            {
                var enumValues = GetSerializeEnumValuesFor(underlyingType);

                var primitiveTypeAndFormat = (enumValues.Any(value => value.GetType() == typeof(string)))
                    ? PrimitiveTypesAndFormats[typeof(string)]
                    : PrimitiveTypesAndFormats[underlyingType.GetEnumUnderlyingType()];

                return(SerializerContract.ForPrimitive(underlyingType, primitiveTypeAndFormat.Item1, primitiveTypeAndFormat.Item2, enumValues));
            }

            if (underlyingType.IsDictionary(out Type keyType, out Type valueType))
            {
                return(SerializerContract.ForDictionary(underlyingType, keyType, valueType));
            }

            if (underlyingType.IsEnumerable(out Type itemType))
            {
                return(SerializerContract.ForArray(underlyingType, itemType));
            }

            return(SerializerContract.ForObject(
                       underlyingType,
                       GetSerializerPropertiesFor(underlyingType, out Type extensionDataValueType),
                       extensionDataValueType));
        }
Esempio n. 6
0
        private OpenApiSchema GenerateInlineSchema(SerializerContract serializerContract, SchemaRepository schemaRepository)
        {
            if (serializerContract.IsPrimitive)
            {
                return(GeneratePrimitiveSchema(serializerContract));
            }

            if (serializerContract.IsDictionary)
            {
                return(GenerateDictionarySchema(serializerContract, schemaRepository));
            }

            if (serializerContract.IsArray)
            {
                return(GenerateArraySchema(serializerContract, schemaRepository));
            }

            if (serializerContract.IsObject)
            {
                return(GenerateObjectSchema(serializerContract, schemaRepository));
            }

            return(new OpenApiSchema());
        }
Esempio n. 7
0
        private OpenApiSchema GenerateObjectSchema(SerializerContract serializerContract, SchemaRepository schemaRepository)
        {
            if (serializerContract.Members == null)
            {
                return(new OpenApiSchema {
                    Type = "object"
                });
            }

            var schema = new OpenApiSchema
            {
                Type       = "object",
                Properties = new Dictionary <string, OpenApiSchema>(),
                Required   = new SortedSet <string>()
            };

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

                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 serializerMember in serializerContract.Members)
            {
                var customAttributes = serializerMember.MemberInfo?.GetInlineOrMetadataTypeAttributes() ?? Enumerable.Empty <object>();

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

                var propertySchema = GenerateSchema(serializerMember.MemberType, schemaRepository, memberInfo: serializerMember.MemberInfo);

                schema.Properties.Add(serializerMember.Name, propertySchema);

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

                if (propertySchema.Reference == null)
                {
                    propertySchema.Nullable  = serializerMember.IsNullable && propertySchema.Nullable;
                    propertySchema.ReadOnly  = serializerMember.IsReadOnly;
                    propertySchema.WriteOnly = serializerMember.IsWriteOnly;
                }
            }

            if (serializerContract.ExtensionDataValueType != null)
            {
                schema.AdditionalProperties = GenerateSchema(serializerContract.ExtensionDataValueType, schemaRepository);
            }

            // If it's a known subType, reference the baseType for inheritied properties
            if (_generatorOptions.GeneratePolymorphicSchemas &&
                (serializerContract.Type.BaseType != null) &&
                _generatorOptions.SubTypesResolver(serializerContract.Type.BaseType).Contains(serializerContract.Type))
            {
                var baseSerializerContract = _serializerContractResolver.GetSerializerContractForType(serializerContract.Type.BaseType);
                var baseSchemaReference    = GenerateReferencedSchema(baseSerializerContract, 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);
        }