-
Notifications
You must be signed in to change notification settings - Fork 59
Expand file tree
/
Copy pathProvider.SwaggerClient.fs
More file actions
114 lines (92 loc) · 5.46 KB
/
Provider.SwaggerClient.fs
File metadata and controls
114 lines (92 loc) · 5.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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.FromSeconds 30.0)
/// The Swagger Type Provider.
[<TypeProvider; Obsolete("Use OpenApiClientTypeProvider when possible, it supports v2 & v3 schema formats.")>]
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<ProvidedApiClientBase>.Assembly.GetName().Name = asm.GetName().Name)
let myParamType =
let t =
ProvidedTypeDefinition(asm, ns, "SwaggerClientProvider", Some typeof<obj>, isErased = false)
let staticParams =
[ ProvidedStaticParameter("Schema", typeof<string>)
ProvidedStaticParameter("Headers", typeof<string>, "")
ProvidedStaticParameter("IgnoreOperationId", typeof<bool>, false)
ProvidedStaticParameter("IgnoreControllerPrefix", typeof<bool>, true)
ProvidedStaticParameter("PreferNullable", typeof<bool>, false)
ProvidedStaticParameter("PreferAsync", typeof<bool>, false)
ProvidedStaticParameter("SsrfProtection", typeof<bool>, true) ]
t.AddXmlDoc
"""<summary>Statically typed Swagger provider.</summary>
<param name='Schema'>Url or Path to Swagger schema file.</param>
<param name='Headers'>HTTP Headers requiried to access the schema.</param>
<param name='IgnoreOperationId'>Do not use `operationsId` and generate method names using `path` only. Default value `false`.</param>
<param name='IgnoreControllerPrefix'>Do not parse `operationsId` as `<controllerName>_<methodName>` and generate one client class for all operations. Default value `true`.</param>
<param name='PreferNullable'>Provide `Nullable<_>` for not required properties, instead of `Option<_>`. Defaults value `false`.</param>
<param name='PreferAsync'>Generate async actions of type `Async<'T>` instead of `Task<'T>`. Defaults value `false`.</param>
<param name='SsrfProtection'>Enable SSRF protection (blocks HTTP and localhost). Set to false for development/testing. Default value `true`.</param>"""
t.DefineStaticParameters(
staticParams,
fun typeName args ->
let schemaPathRaw = unbox<string> args.[0]
let headersStr = unbox<string> args.[1]
let ignoreOperationId = unbox<bool> args.[2]
let ignoreControllerPrefix = unbox<bool> args.[3]
let preferNullable = unbox<bool> args.[4]
let preferAsync = unbox<bool> args.[5]
let ssrfProtection = unbox<bool> 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<obj>, 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 ])