diff --git a/docs/SwaggerClientProvider.md b/docs/SwaggerClientProvider.md
deleted file mode 100644
index 0c5c0e33..00000000
--- a/docs/SwaggerClientProvider.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# Swagger Client Provider
-
-
-
-The SwaggerClientProvider is outdated. There are no plans to improve the custom Swagger 2.0 schema parser or bring new features to this type provider. We hope to remove it from the source code when users migrate to [OpenApiClientProvider](/OpenApiClientProvider) and OpenApi 3.0 schemas.
-
-
-
-SwaggerClientProvider is a generative F# Type Provider, built on top of a custom Swagger schema parser that supports **only** 2.0 schema format.
-
-```fsharp
-open SwaggerProvider
-
-let []schema = "http://petstore.swagger.io/v2/swagger.json"
-type PetStore = SwaggerClientProvider
-let petStore = PetStore.Client()
-```
-
-## Parameters
-
-When you use TP you can specify the following parameters
-
-| Parameter | Description |
-|-----------|-------------|
-| `Schema` | Url or Path to Swagger schema file. |
-| `Headers` | HTTP Headers required to access the schema. |
-| `IgnoreOperationId` | Do not use `operationsId` and generate method names using `path` only. Default value `false`. |
-| `IgnoreControllerPrefix` | Do not parse `operationsId` as `_` and generate one client class for all operations. Default value `true`. |
-| `PreferNullable` | Provide `Nullable<_>` for not required properties, instead of `Option<_>`. Defaults value `false`. |
-| `PreferAsync` | Generate async actions of type `Async<'T>` instead of `Task<'T>`. Defaults value `false`. |
-| `SsrfProtection` | Enable SSRF protection (blocks HTTP and localhost). Set to `false` for development/testing. Default value `true`. |
-
-More configuration scenarios are described in [Customization section](/Customization)
-
-## Security (SSRF Protection)
-
-By default, SwaggerProvider blocks HTTP URLs and localhost/private IP addresses to prevent [SSRF attacks](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery).
-
-For **development and testing** with local servers, disable SSRF protection:
-
-```fsharp
-// Development: Allow HTTP and localhost
-type LocalApi = SwaggerClientProvider<"http://localhost:5000/swagger.json", SsrfProtection=false>
-
-// Production: HTTPS with SSRF protection (default)
-type ProdApi = SwaggerClientProvider<"https://api.example.com/swagger.json">
-```
-
-**Warning:** Never set `SsrfProtection=false` in production code.
-
-## Sample
-
-The usage is very similar to [OpenApiClientProvider](/OpenApiClientProvider#sample)
-
-```fsharp
-open SwaggerProvider
-
-let [] Schema = "https://petstore.swagger.io/v2/swagger.json"
-// Explicitly request Async<'a> methods instead of Task<'a>
-type PetStore = SwaggerClientProvider
-
-[]
-let main argv =
- // Type Provider creates HttpClient for you under the hood
- let client = PetStore.Client()
- async {
- // Create a new instance of the provided type and add it to the store
- let pet = PetStore.Pet(Id = Some(24L), Name = "Shani")
- do! client.AddPet(pet)
-
- // Request data back and deserialize to provided type
- let! myPet = client.GetPetById(24L)
- printfn "Waw, my name is %A" myPet.Name
- }
- |> Async.RunSynchronously
- 0
-```
diff --git a/docs/index.html b/docs/index.html
index 87e4a57f..c8906883 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -48,10 +48,6 @@
{
title: 'OpenApiClientProvider',
link: '/OpenApiClientProvider'
- },
- {
- title: 'SwaggerClientProvider',
- link: '/SwaggerClientProvider',
}
]
},
diff --git a/paket.lock b/paket.lock
index 55820538..b28f5d42 100644
--- a/paket.lock
+++ b/paket.lock
@@ -45,11 +45,11 @@ NUGET
YamlDotNet (16.3)
GITHUB
remote: fsprojects/FSharp.TypeProviders.SDK
- src/ProvidedTypes.fs (41c316752bea3e6ed52859144270a5ff47ba7446)
- src/ProvidedTypes.fsi (41c316752bea3e6ed52859144270a5ff47ba7446)
+ src/ProvidedTypes.fs (75ac6119896431f6573bfcfb663bac2fe3d3df63)
+ src/ProvidedTypes.fsi (75ac6119896431f6573bfcfb663bac2fe3d3df63)
remote: fsprojects/FSharp.Data
- src/FSharp.Data.Runtime.Utilities/NameUtils.fs (7fca47a17aed46f69ad6cb326b3ac5d644bd624f)
- src/FSharp.Data.Runtime.Utilities/Pluralizer.fs (7fca47a17aed46f69ad6cb326b3ac5d644bd624f)
+ src/FSharp.Data.Runtime.Utilities/NameUtils.fs (a1ee1414cacb3d2e6fa26b2726a164f563502728)
+ src/FSharp.Data.Runtime.Utilities/Pluralizer.fs (a1ee1414cacb3d2e6fa26b2726a164f563502728)
GROUP Server
RESTRICTION: == net10.0
NUGET
diff --git a/src/SwaggerProvider.DesignTime/v3/DefinitionCompiler.fs b/src/SwaggerProvider.DesignTime/DefinitionCompiler.fs
similarity index 99%
rename from src/SwaggerProvider.DesignTime/v3/DefinitionCompiler.fs
rename to src/SwaggerProvider.DesignTime/DefinitionCompiler.fs
index a8407842..e343f701 100644
--- a/src/SwaggerProvider.DesignTime/v3/DefinitionCompiler.fs
+++ b/src/SwaggerProvider.DesignTime/DefinitionCompiler.fs
@@ -1,4 +1,4 @@
-namespace SwaggerProvider.Internal.v3.Compilers
+namespace SwaggerProvider.Internal.Compilers
open System
open System.Reflection
diff --git a/src/SwaggerProvider.DesignTime/v3/OperationCompiler.fs b/src/SwaggerProvider.DesignTime/OperationCompiler.fs
similarity index 99%
rename from src/SwaggerProvider.DesignTime/v3/OperationCompiler.fs
rename to src/SwaggerProvider.DesignTime/OperationCompiler.fs
index e075687f..ef9a345b 100644
--- a/src/SwaggerProvider.DesignTime/v3/OperationCompiler.fs
+++ b/src/SwaggerProvider.DesignTime/OperationCompiler.fs
@@ -1,4 +1,4 @@
-namespace SwaggerProvider.Internal.v3.Compilers
+namespace SwaggerProvider.Internal.Compilers
open System
open System.Collections.Generic
diff --git a/src/SwaggerProvider.DesignTime/Provider.OpenApiClient.fs b/src/SwaggerProvider.DesignTime/Provider.OpenApiClient.fs
index 59e8783c..43b23c4a 100644
--- a/src/SwaggerProvider.DesignTime/Provider.OpenApiClient.fs
+++ b/src/SwaggerProvider.DesignTime/Provider.OpenApiClient.fs
@@ -9,7 +9,7 @@ open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Reflection
open Swagger
open SwaggerProvider.Internal
-open SwaggerProvider.Internal.v3.Compilers
+open SwaggerProvider.Internal.Compilers
module OpenApiCache =
let providedTypes = Caching.createInMemoryCache(TimeSpan.FromMinutes 5.0)
diff --git a/src/SwaggerProvider.DesignTime/Provider.SwaggerClient.fs b/src/SwaggerProvider.DesignTime/Provider.SwaggerClient.fs
deleted file mode 100644
index cb5099de..00000000
--- a/src/SwaggerProvider.DesignTime/Provider.SwaggerClient.fs
+++ /dev/null
@@ -1,115 +0,0 @@
-namespace SwaggerProvider
-
-open System
-open System.Reflection
-open ProviderImplementation.ProvidedTypes
-open Microsoft.FSharp.Core.CompilerServices
-open Swagger
-open SwaggerProvider.Internal
-open SwaggerProvider.Internal.v2.Parser
-open SwaggerProvider.Internal.v2.Compilers
-
-module SwaggerCache =
- let providedTypes = Caching.createInMemoryCache(TimeSpan.FromMinutes 5.0)
-
-/// The Swagger Type Provider.
-[]
-type public SwaggerTypeProvider(cfg: TypeProviderConfig) as this =
- inherit
- TypeProviderForNamespaces(
- cfg,
- assemblyReplacementMap = [ ("SwaggerProvider.DesignTime", "SwaggerProvider.Runtime") ],
- addDefaultProbingLocation = true
- )
-
- let ns = "SwaggerProvider"
- let asm = Assembly.GetExecutingAssembly()
-
- // check we contain a copy of runtime files, and are not referencing the runtime DLL
- do assert (typeof.Assembly.GetName().Name = asm.GetName().Name)
-
- let myParamType =
- let t =
- ProvidedTypeDefinition(asm, ns, "SwaggerClientProvider", Some typeof, isErased = false)
-
- let staticParams =
- [ ProvidedStaticParameter("Schema", typeof)
- ProvidedStaticParameter("Headers", typeof, "")
- ProvidedStaticParameter("IgnoreOperationId", typeof, false)
- ProvidedStaticParameter("IgnoreControllerPrefix", typeof, true)
- ProvidedStaticParameter("PreferNullable", typeof, false)
- ProvidedStaticParameter("PreferAsync", typeof, false)
- ProvidedStaticParameter("SsrfProtection", typeof, true) ]
-
- t.AddXmlDoc
- """Statically typed Swagger provider.
- Url or Path to Swagger schema file.
- HTTP Headers requiried to access the schema.
- Do not use `operationsId` and generate method names using `path` only. Default value `false`.
- Do not parse `operationsId` as `_` and generate one client class for all operations. Default value `true`.
- Provide `Nullable<_>` for not required properties, instead of `Option<_>`. Defaults value `false`.
- Generate async actions of type `Async<'T>` instead of `Task<'T>`. Defaults value `false`.
- Enable SSRF protection (blocks HTTP and localhost). Set to false for development/testing. Default value `true`."""
-
- t.DefineStaticParameters(
- staticParams,
- fun typeName args ->
- let schemaPathRaw = unbox args.[0]
- let headersStr = unbox args.[1]
- let ignoreOperationId = unbox args.[2]
- let ignoreControllerPrefix = unbox args.[3]
- let preferNullable = unbox args.[4]
- let preferAsync = unbox args.[5]
- let ssrfProtection = unbox args.[6]
-
- // Cache key includes cfg.RuntimeAssembly, cfg.ResolutionFolder, and cfg.SystemRuntimeAssemblyVersion
- // to differentiate between different TFM builds (same approach as FSharp.Data)
- // See: https://github.com/fsprojects/FSharp.Data/blob/main/src/FSharp.Data.DesignTime/CommonProviderImplementation/Helpers.fs
- let cacheKey =
- (schemaPathRaw,
- headersStr,
- ignoreOperationId,
- ignoreControllerPrefix,
- preferNullable,
- preferAsync,
- ssrfProtection,
- cfg.RuntimeAssembly,
- cfg.ResolutionFolder,
- cfg.SystemRuntimeAssemblyVersion)
- |> sprintf "%A"
-
- let addCache() =
- lazy
- let schemaData =
- SchemaReader.readSchemaPath (not ssrfProtection) headersStr cfg.ResolutionFolder schemaPathRaw
- |> Async.RunSynchronously
-
- let schema = SwaggerParser.parseSchema schemaData
-
- let useDateOnly = cfg.SystemRuntimeAssemblyVersion.Major >= 6
- let defCompiler = DefinitionCompiler(schema, preferNullable, useDateOnly)
-
- let opCompiler =
- OperationCompiler(schema, defCompiler, ignoreControllerPrefix, ignoreOperationId, preferAsync)
-
- opCompiler.CompileProvidedClients(defCompiler.Namespace)
- let tys = defCompiler.Namespace.GetProvidedTypes()
-
- let tempAsm = ProvidedAssembly()
-
- let ty =
- ProvidedTypeDefinition(tempAsm, ns, typeName, Some typeof, isErased = false, hideObjectMethods = true)
-
- ty.AddXmlDoc("Swagger Provider for " + schemaPathRaw)
- ty.AddMembers tys
- tempAsm.AddTypes [ ty ]
-
- ty
-
- SwaggerCache.providedTypes.GetOrAdd(cacheKey, addCache).Value
- )
-
- t
-
- do this.AddNamespace(ns, [ myParamType ])
diff --git a/src/SwaggerProvider.DesignTime/SwaggerProvider.DesignTime.fsproj b/src/SwaggerProvider.DesignTime/SwaggerProvider.DesignTime.fsproj
index a5501dbb..9453d8f5 100644
--- a/src/SwaggerProvider.DesignTime/SwaggerProvider.DesignTime.fsproj
+++ b/src/SwaggerProvider.DesignTime/SwaggerProvider.DesignTime.fsproj
@@ -40,17 +40,10 @@
AssemblyInfo.fs
-
-
-
-
-
-
-
-
+
+
-
diff --git a/src/SwaggerProvider.DesignTime/v2/DefinitionCompiler.fs b/src/SwaggerProvider.DesignTime/v2/DefinitionCompiler.fs
deleted file mode 100644
index 7d145000..00000000
--- a/src/SwaggerProvider.DesignTime/v2/DefinitionCompiler.fs
+++ /dev/null
@@ -1,387 +0,0 @@
-namespace SwaggerProvider.Internal.v2.Compilers
-
-open System
-open System.Reflection
-open ProviderImplementation.ProvidedTypes
-open UncheckedQuotations
-open FSharp.Data.Runtime.NameUtils
-open SwaggerProvider.Internal.v2.Parser.Schema
-open Swagger.Internal
-open SwaggerProvider.Internal
-open Microsoft.FSharp.Quotations
-
-type DefinitionPath =
- { Namespace: string list
- RequestedTypeName: string
- ProvidedTypeNameCandidate: string }
-
- static member Parse(definition: string) =
- let definitionPrefix, nsSeparator = "#/definitions/", '.'
-
- if (not <| definition.StartsWith(definitionPrefix)) then
- failwithf $"Definition path does not start with %s{definitionPrefix}"
-
- let definitionPath = definition.Substring(definitionPrefix.Length)
-
- let rec getCharInTypeName ind =
- if ind = definitionPath.Length then
- ind - 1
- elif
- Char.IsLetterOrDigit definitionPath[ind]
- || definitionPath[ind] = nsSeparator
- then
- getCharInTypeName(ind + 1)
- else
- ind
-
- let lastDot = definitionPath.LastIndexOf(nsSeparator, getCharInTypeName 0)
-
- if lastDot < 0 then
- { Namespace = []
- RequestedTypeName = definitionPath
- ProvidedTypeNameCandidate = nicePascalName definitionPath }
- else
- let nsPath =
- definitionPath.Substring(0, lastDot).Split([| nsSeparator |], StringSplitOptions.RemoveEmptyEntries)
- |> List.ofArray
-
- let tyName = definitionPath.Substring(lastDot + 1)
-
- { Namespace = nsPath
- RequestedTypeName = tyName
- ProvidedTypeNameCandidate = nicePascalName tyName }
-
-type NamespaceEntry =
- | Reservation
- | NameAlias
- | ProvidedType of ProvidedTypeDefinition
- | Namespace of NamespaceAbstraction
- | NestedType of ProvidedTypeDefinition * NamespaceAbstraction
-
-and NamespaceAbstraction(name: string) =
- let providedTys = Collections.Generic.Dictionary()
-
- let updateReservation opName tyName updateFunc =
- match providedTys.TryGetValue tyName with
- | true, Reservation -> updateFunc()
- | false, _ -> failwithf $"Cannot %s{opName} '%s{tyName}' because name was not reserved"
- | _, value -> failwithf $"Cannot %s{opName} '%s{tyName}' because the slot is used by %A{value}"
-
- /// Namespace name
- member _.Name = name
-
- /// Generate unique name and reserve it for the type
- member _.ReserveUniqueName namePref nameSuffix = // TODO: Strange signature - think more
- let rec findUniq prefix i =
- let newName = sprintf "%s%s" prefix (if i = 0 then "" else i.ToString())
-
- if not <| providedTys.ContainsKey newName then
- newName
- else
- findUniq prefix (i + 1)
-
- let newName = findUniq (namePref + nameSuffix) 0
- providedTys.Add(newName, Reservation)
- newName
-
- /// Release previously reserved name
- member _.ReleaseNameReservation tyName =
- updateReservation "release the name" tyName (fun () -> providedTys.Remove(tyName) |> ignore)
-
- /// Mark type name as named alias for basic type
- member _.MarkTypeAsNameAlias tyName =
- updateReservation "mark as Alias type" tyName (fun () -> providedTys[tyName] <- NameAlias)
-
- /// Associate ProvidedType with reserved type name
- member _.RegisterType(tyName, ty) =
- match providedTys.TryGetValue tyName with
- | true, Reservation -> providedTys[tyName] <- ProvidedType ty
- | true, Namespace ns -> providedTys[tyName] <- NestedType(ty, ns)
- | false, _ -> failwithf $"Cannot register the type '%s{tyName}' because name was not reserved"
- | _, value -> failwithf $"Cannot register the type '%s{tyName}' because the slot is used by %A{value}"
-
- /// Get or create sub-namespace
- member _.GetOrCreateNamespace name =
- match providedTys.TryGetValue name with
- | true, Namespace ns -> ns
- | true, NestedType(_, ns) -> ns
- | true, ProvidedType ty ->
- let ns = NamespaceAbstraction(name)
- providedTys[name] <- NestedType(ty, ns)
- ns
- | false, _
- | true, Reservation ->
- let ns = NamespaceAbstraction(name)
- providedTys[name] <- Namespace ns
- ns
- | true, value -> failwithf $"Name collision, cannot create namespace '%s{name}' because it used by '%A{value}'"
-
- /// Resolve DefinitionPath according to current namespace
- member this.Resolve(dPath: DefinitionPath) =
- match dPath.Namespace with
- | [] -> this, this.ReserveUniqueName dPath.RequestedTypeName ""
- | name :: tail ->
- let ns = this.GetOrCreateNamespace name
- ns.Resolve { dPath with Namespace = tail }
-
- /// Create Provided representation of Namespace
- member _.GetProvidedTypes() =
- List.ofSeq providedTys
- |> List.choose(fun kv ->
- match kv.Value with
- | Reservation -> failwithf $"Reservation without type found '%s{kv.Key}'. This is a bug in DefinitionCompiler"
- | NameAlias -> None
- | ProvidedType ty -> Some ty
- | Namespace ns ->
- let types = ns.GetProvidedTypes()
-
- if types.Length = 0 then
- None
- else
- let nsTy = ProvidedTypeDefinition(ns.Name, Some typeof, isErased = false)
-
- nsTy.AddMember
- <| ProvidedConstructor([], invokeCode = (fun _ -> <@@ () @@>)) // hack
-
- nsTy.AddMembers <| types
- Some nsTy
- | NestedType(ty, ns) ->
- ty.AddMembers <| ns.GetProvidedTypes()
- Some ty)
-
-/// Object for compiling definitions.
-type DefinitionCompiler(schema: SwaggerObject, provideNullable, useDateOnly: bool) as this =
- let definitionToSchemaObject =
- let dict = Collections.Generic.Dictionary()
-
- for name, schemaObj in schema.Definitions do
- dict.Add(name, schemaObj)
-
- dict
-
- let definitionToType = Collections.Generic.Dictionary<_, _>()
- let nsRoot = NamespaceAbstraction("Root")
- let nsOps = nsRoot.GetOrCreateNamespace "OperationTypes"
-
- let generateProperty (scope: UniqueNameGenerator) propName ty =
- let propertyName = scope.MakeUnique <| nicePascalName propName
-
- let providedField =
- let fieldName = $"_%c{Char.ToLower propertyName[0]}%s{propertyName.Substring(1)}"
-
- ProvidedField(fieldName, ty)
-
- let providedProperty =
- ProvidedProperty(
- propertyName,
- ty,
- getterCode =
- (function
- | [ this ] -> Expr.FieldGetUnchecked(this, providedField)
- | _ -> failwith "invalid property getter params"),
- setterCode =
- (function
- | [ this; v ] -> Expr.FieldSetUnchecked(this, providedField, v)
- | _ -> failwith "invalid property setter params")
- )
-
- if propName <> propertyName then
- providedProperty.AddCustomAttribute
- <| RuntimeHelpers.getPropertyNameAttribute propName
-
- providedField, providedProperty
-
- let registerInNsAndInDef tyDefName (ns: NamespaceAbstraction) (name, ty: ProvidedTypeDefinition) =
- if definitionToType.ContainsKey tyDefName then
- failwithf $"Second time compilation of type definition '%s{tyDefName}'. This is a bug in DefinitionCompiler"
- else
- definitionToType.Add(tyDefName, ty)
-
- ns.RegisterType(name, ty)
-
- let rec compileDefinition(tyDefName: string) : Type =
- match definitionToType.TryGetValue tyDefName with
- | true, ty -> ty :> Type
- | false, _ ->
- match definitionToSchemaObject.TryGetValue tyDefName with
- | true, def ->
- let ns, tyName = tyDefName |> DefinitionPath.Parse |> nsRoot.Resolve
- let ty = compileSchemaObject ns tyName def true (registerInNsAndInDef tyDefName ns)
- ty :> Type
- | false, _ when tyDefName.StartsWith("#/definitions/") ->
- failwithf $"Cannot find definition '%s{tyDefName}' in schema definitions %A{definitionToType.Keys |> Seq.toArray}"
- | _ -> failwithf $"Cannot find definition '%s{tyDefName}' (references to relative documents are not supported yet)"
-
- and compileSchemaObject (ns: NamespaceAbstraction) tyName (schemaObj: SchemaObject) isRequired registerNew =
- let compileNewObject(properties: DefinitionProperty[]) =
- if properties.Length = 0 then
- if not <| isNull tyName then
- ns.MarkTypeAsNameAlias tyName
-
- typeof
- else if isNull tyName then
- failwithf $"Swagger provider does not support anonymous types: %A{schemaObj}"
- else
- // Register every ProvidedTypeDefinition
- let ty = ProvidedTypeDefinition(tyName, Some typeof, isErased = false)
- registerNew(tyName, ty)
-
- // Generate fields and properties
- let members =
- let generateProperty = generateProperty(UniqueNameGenerator())
-
- List.ofArray properties
- |> List.map(fun p ->
- if String.IsNullOrEmpty(p.Name) then
- failwithf $"Property cannot be created with empty name. TypeName:%A{tyName}; SchemaObj:%A{schemaObj}"
-
- let pTy =
- compileSchemaObject ns (ns.ReserveUniqueName tyName (nicePascalName p.Name)) p.Type p.IsRequired ns.RegisterType
-
- let pField, pProp = generateProperty p.Name pTy
-
- if not <| String.IsNullOrWhiteSpace p.Description then
- pProp.AddXmlDoc p.Description
-
- pField, pProp)
-
- // Add fields and properties to type
- ty.AddMembers
- <| (members
- |> List.collect(fun (f, p) -> [ f :> MemberInfo; p :> MemberInfo ]))
-
- // Add default constructor
- ty.AddMember
- <| ProvidedConstructor([], invokeCode = (fun _ -> <@@ () @@>))
- // Add full-init constructor
- let ctorParams, fields =
- let required, optional =
- List.zip (List.ofArray properties) members
- |> List.partition(fun (x, _) -> x.IsRequired)
-
- (required @ optional)
- |> List.map(fun (x, (f, p)) ->
- let paramName = niceCamelName p.Name
-
- let prParam =
- if x.IsRequired then
- ProvidedParameter(paramName, f.FieldType)
- else
- let paramDefaultValue = this.GetDefaultValue f.FieldType
- ProvidedParameter(paramName, f.FieldType, false, paramDefaultValue)
-
- prParam, f)
- |> List.unzip
-
- ty.AddMember
- <| ProvidedConstructor(
- ctorParams,
- invokeCode =
- fun args ->
- let this, args =
- match args with
- | x :: xs -> (x, xs)
- | _ -> failwith "Wrong constructor arguments"
-
- List.zip args fields
- |> List.map(fun (arg, f) -> Expr.FieldSetUnchecked(this, f, arg))
- |> List.rev
- |> List.fold (fun a b -> Expr.Sequential(a, b)) <@@ () @@>
- )
-
- // Override `.ToString()`
- // Delegates to the shared RuntimeHelpers.formatObject helper so that
- // each generated type's method body is a single static call (O(1) IL).
- let toStr =
- ProvidedMethod(
- "ToString",
- [],
- typeof,
- isStatic = false,
- invokeCode =
- fun args ->
- let this = args[0]
- let thisObj = Expr.Coerce(this, typeof)
- <@@ RuntimeHelpers.formatObject(%%thisObj: obj) @@>
- )
-
- toStr.SetMethodAttrs(MethodAttributes.Public ||| MethodAttributes.Virtual)
-
- let objToStr = typeof.GetMethod("ToString", [||])
- ty.DefineMethodOverride(toStr, objToStr)
- ty.AddMember <| toStr
-
- ty :> Type
-
- let tyType =
- match schemaObj with
- | Reference path ->
- ns.ReleaseNameReservation tyName
- compileDefinition path
- | Object props -> compileNewObject props
- | _ ->
- ns.MarkTypeAsNameAlias tyName
-
- match schemaObj with
- | Boolean -> typeof
- | Byte -> typeof
- | Int32 -> typeof
- | Int64 -> typeof
- | Float -> typeof
- | Double -> typeof
- | String -> typeof
- | Date ->
- // Use DateOnly only when the target runtime supports it (.NET 6+).
- // We check useDateOnly (derived from cfg.SystemRuntimeAssemblyVersion) rather than
- // probing the design-time host process, which may differ from the consumer's runtime.
- if useDateOnly then
- System.Type.GetType("System.DateOnly")
- |> Option.ofObj
- |> Option.defaultValue typeof
- else
- typeof
- | DateTime -> typeof
- | File -> typeof.MakeArrayType 1
- | Enum(_, "string") -> typeof
- | Enum(_, "boolean") -> typeof
- | Enum _ -> typeof
- | Array eTy -> (compileSchemaObject ns (ns.ReserveUniqueName tyName "Item") eTy true ns.RegisterType).MakeArrayType(1)
- | Dictionary eTy ->
- ProvidedTypeBuilder.MakeGenericType(
- typedefof