mirror of
https://github.com/Smaug123/WoofWare.Myriad
synced 2025-10-05 20:18:43 +00:00
Compare commits
55 Commits
WoofWare.M
...
WoofWare.M
Author | SHA1 | Date | |
---|---|---|---|
|
4fe4e3f277 | ||
|
9473a080ff | ||
|
e6867572b7 | ||
|
5a92d86ad1 | ||
|
fbfd7131f3 | ||
|
ca72b07c33 | ||
|
cdaa46fe00 | ||
|
c70c68b15b | ||
|
17cbaf4a85 | ||
|
e48c5209c7 | ||
|
cc8e3205b1 | ||
|
34cb74dc7b | ||
|
099d14b0b1 | ||
|
96908a5fa6 | ||
|
3e39e187df | ||
|
9f4245341c | ||
|
de58f5ed1f | ||
|
e8571553c4 | ||
|
19761db983 | ||
|
f30a73fd4f | ||
|
b2d64562bf | ||
|
e7e629613e | ||
|
4560138b59 | ||
|
425d5313b4 | ||
|
0fe97da788 | ||
|
f944953384 | ||
|
7930039ad1 | ||
|
8d275f0047 | ||
|
682b12fdb2 | ||
|
325f8634a4 | ||
|
3e5d663544 | ||
|
bb88f80c85 | ||
|
71f26930c6 | ||
|
680728a06e | ||
|
cdc6f2d511 | ||
|
3be487c328 | ||
|
a5f4d169ca | ||
|
ce634efff2 | ||
|
1529dd1fb2 | ||
|
59558b0766 | ||
|
8602894efc | ||
|
51d349b365 | ||
|
120df84bbf | ||
|
603f875a12 | ||
|
2df41555de | ||
|
49e31e52b5 | ||
|
277a186fda | ||
|
129687ec1c | ||
|
c7fea55e28 | ||
|
ded7b32771 | ||
|
b272f8b645 | ||
|
b8d60aec90 | ||
|
0e3510e1e5 | ||
|
8a1edd90d5 | ||
|
74fdd7c0a9 |
@@ -3,13 +3,13 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"fantomas": {
|
||||
"version": "6.3.16",
|
||||
"version": "7.0.2",
|
||||
"commands": [
|
||||
"fantomas"
|
||||
]
|
||||
},
|
||||
"fsharp-analyzers": {
|
||||
"version": "0.28.0",
|
||||
"version": "0.31.0",
|
||||
"commands": [
|
||||
"fsharp-analyzers"
|
||||
]
|
||||
|
26
.github/workflows/dotnet.yaml
vendored
26
.github/workflows/dotnet.yaml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v30
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v30
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v30
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v30
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -97,7 +97,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v30
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -116,7 +116,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v30
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -129,7 +129,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v30
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -142,7 +142,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v30
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -156,7 +156,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0 # so that NerdBank.GitVersioning has access to history
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v30
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -254,7 +254,7 @@ jobs:
|
||||
name: nuget-package-attribute
|
||||
path: packed
|
||||
- name: Attest Build Provenance
|
||||
uses: actions/attest-build-provenance@7668571508540a607bdfd90a87a560489fe372eb # v2.1.0
|
||||
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
|
||||
with:
|
||||
subject-path: "packed/*.nupkg"
|
||||
|
||||
@@ -273,7 +273,7 @@ jobs:
|
||||
name: nuget-package-plugin
|
||||
path: packed
|
||||
- name: Attest Build Provenance
|
||||
uses: actions/attest-build-provenance@7668571508540a607bdfd90a87a560489fe372eb # v2.1.0
|
||||
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
|
||||
with:
|
||||
subject-path: "packed/*.nupkg"
|
||||
|
||||
@@ -289,7 +289,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v30
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -322,7 +322,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v30
|
||||
uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
|
5
.github/workflows/flake_update.yaml
vendored
5
.github/workflows/flake_update.yaml
vendored
@@ -34,18 +34,19 @@ jobs:
|
||||
|
||||
- name: Create token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@v1
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
# https://github.com/actions/create-github-app-token/issues/136
|
||||
app-id: ${{ secrets.APP_ID }}
|
||||
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Raise pull request
|
||||
uses: Smaug123/commit-action@cc25e6d80a796c49669dda4a0aa36c54c573983d
|
||||
uses: Smaug123/commit-action@d34807f26cb52c7a05bbd80efe9f964cdf29bc87
|
||||
id: cpr
|
||||
with:
|
||||
bearer-token: ${{ steps.generate-token.outputs.token }}
|
||||
pr-title: "Upgrade Nix flake and deps"
|
||||
branch-name: "auto-pr"
|
||||
|
||||
- name: Enable Pull Request Automerge
|
||||
if: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
|
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,5 +1,32 @@
|
||||
Notable changes are recorded here.
|
||||
|
||||
# WoofWare.Myriad.Plugins 8.0.3
|
||||
|
||||
The RestEase-style HTTP client generator now automatically adds the `application/json` content type header to requests which are POSTing a body that is known to be JSON-serialised.
|
||||
You can override this by setting the `[<RestEase.Header ("Content-Type", "desired content type")>]` header manually on any affected member.
|
||||
|
||||
# WoofWare.Myriad.Plugins 7.0.1
|
||||
|
||||
All generators should now be compatible with `<Nullable>enable</Nullable>`.
|
||||
|
||||
**Please test the results and let me know of unexpected failures.**
|
||||
There are a number of heuristics in this code, because:
|
||||
|
||||
* `System.Text.Json.Nodes` is an unfathomably weird API which simply requires us to make educated guesses about whether a user-provided type is supposed to be nullable, despite this being irrelevant to the operation of `System.Text.Json`;
|
||||
* Some types (like `Uri` and `String`) have `ToString` methods which can't return `null`, but in general `Object.ToString` can of course return `null`, and as far as I can tell there is simply no way to know from the source alone whether a given type will have a nullable `ToString`.
|
||||
|
||||
# WoofWare.Myriad.Plugins 6.0.1
|
||||
|
||||
The `ArgParser` generator's type signatures have changed.
|
||||
The `parse'` method no longer takes `getEnvironmentVariable : string -> string`; it's now `getEnvironmentVariable : string -> string option`.
|
||||
This is to permit satisfying the `<Nullable>enable</Nullable>` compiler setting.
|
||||
If you're calling `parse'`, give it `Environment.GetEnvironmentVariable >> Option.ofObj` instead.
|
||||
|
||||
# WoofWare.Myriad.Plugins 5.0.1
|
||||
|
||||
We now enforce non-nullability on more types during JSON parse.
|
||||
We have always expected you to consume nullable types wrapped in an `option`, but now we enforce this in more cases by throwing `ArgumentNullException`.
|
||||
|
||||
# WoofWare.Myriad.Plugins 3.0.1
|
||||
|
||||
Semantics of `HttpClient`'s URI component composition changed:
|
||||
|
@@ -4,6 +4,7 @@
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<OtherFlags>--reflectionfree $(OtherFlags)</OtherFlags>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<MyriadSdkGenerator Include="$(MSBuildThisFileDirectory)..\WoofWare.Myriad.Plugins\bin\$(Configuration)\net6.0\WoofWare.Myriad.Plugins.dll"/>
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@ module BasicNoPositionals =
|
||||
/// Waiting to receive a value for the key we've already consumed
|
||||
| AwaitingValue of key : string
|
||||
|
||||
let parse' (getEnvironmentVariable : string -> string) (args : string list) : BasicNoPositionals =
|
||||
let parse' (getEnvironmentVariable : string -> string option) (args : string list) : BasicNoPositionals =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -223,7 +223,7 @@ module BasicNoPositionals =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
let parse (args : string list) : BasicNoPositionals =
|
||||
parse' System.Environment.GetEnvironmentVariable args
|
||||
parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -239,7 +239,7 @@ module Basic =
|
||||
/// Waiting to receive a value for the key we've already consumed
|
||||
| AwaitingValue of key : string
|
||||
|
||||
let parse' (getEnvironmentVariable : string -> string) (args : string list) : Basic =
|
||||
let parse' (getEnvironmentVariable : string -> string option) (args : string list) : Basic =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -430,7 +430,7 @@ module Basic =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
let parse (args : string list) : Basic =
|
||||
parse' System.Environment.GetEnvironmentVariable args
|
||||
parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -446,7 +446,7 @@ module BasicWithIntPositionals =
|
||||
/// Waiting to receive a value for the key we've already consumed
|
||||
| AwaitingValue of key : string
|
||||
|
||||
let parse' (getEnvironmentVariable : string -> string) (args : string list) : BasicWithIntPositionals =
|
||||
let parse' (getEnvironmentVariable : string -> string option) (args : string list) : BasicWithIntPositionals =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -633,7 +633,7 @@ module BasicWithIntPositionals =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
let parse (args : string list) : BasicWithIntPositionals =
|
||||
parse' System.Environment.GetEnvironmentVariable args
|
||||
parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -649,7 +649,7 @@ module LoadsOfTypes =
|
||||
/// Waiting to receive a value for the key we've already consumed
|
||||
| AwaitingValue of key : string
|
||||
|
||||
let parse' (getEnvironmentVariable : string -> string) (args : string list) : LoadsOfTypes =
|
||||
let parse' (getEnvironmentVariable : string -> string option) (args : string list) : LoadsOfTypes =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -1038,7 +1038,7 @@ module LoadsOfTypes =
|
||||
match arg_10 with
|
||||
| None ->
|
||||
match "CONSUMEPLUGIN_THINGS" |> getEnvironmentVariable with
|
||||
| null ->
|
||||
| None ->
|
||||
sprintf
|
||||
"No value was supplied for %s, nor was environment variable %s set"
|
||||
(sprintf "--%s" "yet-another-optional-thing")
|
||||
@@ -1046,7 +1046,7 @@ module LoadsOfTypes =
|
||||
|> ArgParser_errors.Add
|
||||
|
||||
Unchecked.defaultof<_>
|
||||
| x -> x |> (fun x -> x)
|
||||
| Some x -> x |> (fun x -> x)
|
||||
|> Choice2Of2
|
||||
| Some x -> Choice1Of2 x
|
||||
|
||||
@@ -1068,7 +1068,7 @@ module LoadsOfTypes =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
let parse (args : string list) : LoadsOfTypes =
|
||||
parse' System.Environment.GetEnvironmentVariable args
|
||||
parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -1084,7 +1084,7 @@ module LoadsOfTypesNoPositionals =
|
||||
/// Waiting to receive a value for the key we've already consumed
|
||||
| AwaitingValue of key : string
|
||||
|
||||
let parse' (getEnvironmentVariable : string -> string) (args : string list) : LoadsOfTypesNoPositionals =
|
||||
let parse' (getEnvironmentVariable : string -> string option) (args : string list) : LoadsOfTypesNoPositionals =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -1476,7 +1476,7 @@ module LoadsOfTypesNoPositionals =
|
||||
match arg_9 with
|
||||
| None ->
|
||||
match "CONSUMEPLUGIN_THINGS" |> getEnvironmentVariable with
|
||||
| null ->
|
||||
| None ->
|
||||
sprintf
|
||||
"No value was supplied for %s, nor was environment variable %s set"
|
||||
(sprintf "--%s" "yet-another-optional-thing")
|
||||
@@ -1484,7 +1484,7 @@ module LoadsOfTypesNoPositionals =
|
||||
|> ArgParser_errors.Add
|
||||
|
||||
Unchecked.defaultof<_>
|
||||
| x -> x |> (fun x -> x)
|
||||
| Some x -> x |> (fun x -> x)
|
||||
|> Choice2Of2
|
||||
| Some x -> Choice1Of2 x
|
||||
|
||||
@@ -1505,7 +1505,7 @@ module LoadsOfTypesNoPositionals =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
let parse (args : string list) : LoadsOfTypesNoPositionals =
|
||||
parse' System.Environment.GetEnvironmentVariable args
|
||||
parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -1524,7 +1524,7 @@ module DatesAndTimesArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type DatesAndTimes with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : DatesAndTimes =
|
||||
static member parse' (getEnvironmentVariable : string -> string option) (args : string list) : DatesAndTimes =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -1787,7 +1787,7 @@ module DatesAndTimesArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : DatesAndTimes =
|
||||
DatesAndTimes.parse' System.Environment.GetEnvironmentVariable args
|
||||
DatesAndTimes.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -1806,7 +1806,7 @@ module ParentRecordArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ParentRecord with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ParentRecord =
|
||||
static member parse' (getEnvironmentVariable : string -> string option) (args : string list) : ParentRecord =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2016,7 +2016,7 @@ module ParentRecordArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ParentRecord =
|
||||
ParentRecord.parse' System.Environment.GetEnvironmentVariable args
|
||||
ParentRecord.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2035,7 +2035,11 @@ module ParentRecordChildPosArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ParentRecordChildPos with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ParentRecordChildPos =
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ParentRecordChildPos
|
||||
=
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2209,7 +2213,7 @@ module ParentRecordChildPosArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ParentRecordChildPos =
|
||||
ParentRecordChildPos.parse' System.Environment.GetEnvironmentVariable args
|
||||
ParentRecordChildPos.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2228,7 +2232,11 @@ module ParentRecordSelfPosArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ParentRecordSelfPos with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ParentRecordSelfPos =
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ParentRecordSelfPos
|
||||
=
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2388,7 +2396,7 @@ module ParentRecordSelfPosArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ParentRecordSelfPos =
|
||||
ParentRecordSelfPos.parse' System.Environment.GetEnvironmentVariable args
|
||||
ParentRecordSelfPos.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2407,7 +2415,11 @@ module ChoicePositionalsArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ChoicePositionals with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ChoicePositionals =
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ChoicePositionals
|
||||
=
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2502,7 +2514,7 @@ module ChoicePositionalsArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ChoicePositionals =
|
||||
ChoicePositionals.parse' System.Environment.GetEnvironmentVariable args
|
||||
ChoicePositionals.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2521,7 +2533,11 @@ module ContainsBoolEnvVarArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ContainsBoolEnvVar with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ContainsBoolEnvVar =
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ContainsBoolEnvVar
|
||||
=
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2653,7 +2669,7 @@ module ContainsBoolEnvVarArgParse =
|
||||
match arg_0 with
|
||||
| None ->
|
||||
match "CONSUMEPLUGIN_THINGS" |> getEnvironmentVariable with
|
||||
| null ->
|
||||
| None ->
|
||||
sprintf
|
||||
"No value was supplied for %s, nor was environment variable %s set"
|
||||
(sprintf "--%s" "bool-var")
|
||||
@@ -2661,7 +2677,7 @@ module ContainsBoolEnvVarArgParse =
|
||||
|> ArgParser_errors.Add
|
||||
|
||||
Unchecked.defaultof<_>
|
||||
| x ->
|
||||
| Some x ->
|
||||
if System.String.Equals (x, "1", System.StringComparison.OrdinalIgnoreCase) then
|
||||
true
|
||||
else if System.String.Equals (x, "0", System.StringComparison.OrdinalIgnoreCase) then
|
||||
@@ -2679,7 +2695,7 @@ module ContainsBoolEnvVarArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ContainsBoolEnvVar =
|
||||
ContainsBoolEnvVar.parse' System.Environment.GetEnvironmentVariable args
|
||||
ContainsBoolEnvVar.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2698,7 +2714,7 @@ module WithFlagDuArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type WithFlagDu with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : WithFlagDu =
|
||||
static member parse' (getEnvironmentVariable : string -> string option) (args : string list) : WithFlagDu =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -2852,7 +2868,7 @@ module WithFlagDuArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : WithFlagDu =
|
||||
WithFlagDu.parse' System.Environment.GetEnvironmentVariable args
|
||||
WithFlagDu.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -2871,7 +2887,11 @@ module ContainsFlagEnvVarArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ContainsFlagEnvVar with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ContainsFlagEnvVar =
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ContainsFlagEnvVar
|
||||
=
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -3018,7 +3038,7 @@ module ContainsFlagEnvVarArgParse =
|
||||
match arg_0 with
|
||||
| None ->
|
||||
match "CONSUMEPLUGIN_THINGS" |> getEnvironmentVariable with
|
||||
| null ->
|
||||
| None ->
|
||||
sprintf
|
||||
"No value was supplied for %s, nor was environment variable %s set"
|
||||
(sprintf "--%s" "dry-run")
|
||||
@@ -3026,7 +3046,7 @@ module ContainsFlagEnvVarArgParse =
|
||||
|> ArgParser_errors.Add
|
||||
|
||||
Unchecked.defaultof<_>
|
||||
| x ->
|
||||
| Some x ->
|
||||
if System.String.Equals (x, "1", System.StringComparison.OrdinalIgnoreCase) then
|
||||
if true = Consts.FALSE then
|
||||
DryRunMode.Wet
|
||||
@@ -3056,7 +3076,7 @@ module ContainsFlagEnvVarArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ContainsFlagEnvVar =
|
||||
ContainsFlagEnvVar.parse' System.Environment.GetEnvironmentVariable args
|
||||
ContainsFlagEnvVar.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -3076,7 +3096,7 @@ module ContainsFlagDefaultValueArgParse =
|
||||
type ContainsFlagDefaultValue with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: ContainsFlagDefaultValue
|
||||
=
|
||||
@@ -3239,7 +3259,7 @@ module ContainsFlagDefaultValueArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ContainsFlagDefaultValue =
|
||||
ContainsFlagDefaultValue.parse' System.Environment.GetEnvironmentVariable args
|
||||
ContainsFlagDefaultValue.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -3258,7 +3278,7 @@ module ManyLongFormsArgParse =
|
||||
/// Extension methods for argument parsing
|
||||
type ManyLongForms with
|
||||
|
||||
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ManyLongForms =
|
||||
static member parse' (getEnvironmentVariable : string -> string option) (args : string list) : ManyLongForms =
|
||||
let ArgParser_errors = ResizeArray ()
|
||||
|
||||
let helpText () =
|
||||
@@ -3504,7 +3524,7 @@ module ManyLongFormsArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : ManyLongForms =
|
||||
ManyLongForms.parse' System.Environment.GetEnvironmentVariable args
|
||||
ManyLongForms.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -3524,7 +3544,7 @@ module FlagsIntoPositionalArgsArgParse =
|
||||
type FlagsIntoPositionalArgs with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: FlagsIntoPositionalArgs
|
||||
=
|
||||
@@ -3668,7 +3688,7 @@ module FlagsIntoPositionalArgsArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : FlagsIntoPositionalArgs =
|
||||
FlagsIntoPositionalArgs.parse' System.Environment.GetEnvironmentVariable args
|
||||
FlagsIntoPositionalArgs.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -3688,7 +3708,7 @@ module FlagsIntoPositionalArgsChoiceArgParse =
|
||||
type FlagsIntoPositionalArgsChoice with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: FlagsIntoPositionalArgsChoice
|
||||
=
|
||||
@@ -3832,7 +3852,7 @@ module FlagsIntoPositionalArgsChoiceArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : FlagsIntoPositionalArgsChoice =
|
||||
FlagsIntoPositionalArgsChoice.parse' System.Environment.GetEnvironmentVariable args
|
||||
FlagsIntoPositionalArgsChoice.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -3852,7 +3872,7 @@ module FlagsIntoPositionalArgsIntArgParse =
|
||||
type FlagsIntoPositionalArgsInt with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: FlagsIntoPositionalArgsInt
|
||||
=
|
||||
@@ -3996,7 +4016,7 @@ module FlagsIntoPositionalArgsIntArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : FlagsIntoPositionalArgsInt =
|
||||
FlagsIntoPositionalArgsInt.parse' System.Environment.GetEnvironmentVariable args
|
||||
FlagsIntoPositionalArgsInt.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -4016,7 +4036,7 @@ module FlagsIntoPositionalArgsIntChoiceArgParse =
|
||||
type FlagsIntoPositionalArgsIntChoice with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: FlagsIntoPositionalArgsIntChoice
|
||||
=
|
||||
@@ -4160,7 +4180,7 @@ module FlagsIntoPositionalArgsIntChoiceArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : FlagsIntoPositionalArgsIntChoice =
|
||||
FlagsIntoPositionalArgsIntChoice.parse' System.Environment.GetEnvironmentVariable args
|
||||
FlagsIntoPositionalArgsIntChoice.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
namespace ConsumePlugin
|
||||
|
||||
open System
|
||||
@@ -4180,7 +4200,7 @@ module FlagsIntoPositionalArgs'ArgParse =
|
||||
type FlagsIntoPositionalArgs' with
|
||||
|
||||
static member parse'
|
||||
(getEnvironmentVariable : string -> string)
|
||||
(getEnvironmentVariable : string -> string option)
|
||||
(args : string list)
|
||||
: FlagsIntoPositionalArgs'
|
||||
=
|
||||
@@ -4324,4 +4344,4 @@ module FlagsIntoPositionalArgs'ArgParse =
|
||||
ArgParser_errors |> String.concat "\n" |> failwithf "Errors during parse!\n%s"
|
||||
|
||||
static member parse (args : string list) : FlagsIntoPositionalArgs' =
|
||||
FlagsIntoPositionalArgs'.parse' System.Environment.GetEnvironmentVariable args
|
||||
FlagsIntoPositionalArgs'.parse' (System.Environment.GetEnvironmentVariable >> Option.ofObj) args
|
||||
|
@@ -14,7 +14,24 @@ module internal InternalTypeNotExtensionSerial =
|
||||
/// Serialize to a JSON node
|
||||
let toJsonNode (input : InternalTypeNotExtensionSerial) : System.Text.Json.Nodes.JsonNode =
|
||||
let node = System.Text.Json.Nodes.JsonObject ()
|
||||
do node.Add ((Literals.something), (input.InternalThing2 |> System.Text.Json.Nodes.JsonValue.Create<string>))
|
||||
|
||||
do
|
||||
node.Add (
|
||||
(Literals.something),
|
||||
(input.InternalThing2
|
||||
|> (fun field ->
|
||||
let field = System.Text.Json.Nodes.JsonValue.Create<string> field
|
||||
|
||||
(match field with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected type string to be non-null, but received a null value when serialising"
|
||||
)
|
||||
| field -> field)
|
||||
))
|
||||
)
|
||||
|
||||
node :> _
|
||||
namespace ConsumePlugin
|
||||
|
||||
@@ -29,7 +46,24 @@ module internal InternalTypeExtensionJsonSerializeExtension =
|
||||
/// Serialize to a JSON node
|
||||
static member toJsonNode (input : InternalTypeExtension) : System.Text.Json.Nodes.JsonNode =
|
||||
let node = System.Text.Json.Nodes.JsonObject ()
|
||||
do node.Add ((Literals.something), (input.ExternalThing |> System.Text.Json.Nodes.JsonValue.Create<string>))
|
||||
|
||||
do
|
||||
node.Add (
|
||||
(Literals.something),
|
||||
(input.ExternalThing
|
||||
|> (fun field ->
|
||||
let field = System.Text.Json.Nodes.JsonValue.Create<string> field
|
||||
|
||||
(match field with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected type string to be non-null, but received a null value when serialising"
|
||||
)
|
||||
| field -> field)
|
||||
))
|
||||
)
|
||||
|
||||
node :> _
|
||||
|
||||
namespace ConsumePlugin
|
||||
@@ -40,16 +74,14 @@ module InnerType =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : InnerType =
|
||||
let arg_0 =
|
||||
(match node.[(Literals.something)] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.[(Literals.something)] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
Thing = arg_0
|
||||
@@ -62,79 +94,97 @@ module JsonRecordType =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JsonRecordType =
|
||||
let arg_5 =
|
||||
(match node.["f"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("f")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.Int32> ())
|
||||
|> Array.ofSeq
|
||||
match node.["f"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("f")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type int32) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.Int32> ())
|
||||
)
|
||||
|> Array.ofSeq
|
||||
|
||||
let arg_4 =
|
||||
(match node.["e"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("e")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|
||||
|> Array.ofSeq
|
||||
match node.["e"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("e")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type string) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> Array.ofSeq
|
||||
|
||||
let arg_3 =
|
||||
InnerType.jsonParse (
|
||||
match node.["d"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("d")
|
||||
)
|
||||
match node.["d"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("d")
|
||||
)
|
||||
| v -> v
|
||||
)
|
||||
)
|
||||
| Some node -> InnerType.jsonParse node
|
||||
|
||||
let arg_2 =
|
||||
(match node.["hi"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("hi")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.Int32> ())
|
||||
|> List.ofSeq
|
||||
match node.["hi"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("hi")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type int32) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.Int32> ())
|
||||
)
|
||||
|> List.ofSeq
|
||||
|
||||
let arg_1 =
|
||||
(match node.["another-thing"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("another-thing")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["another-thing"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("another-thing")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_0 =
|
||||
(match node.["a"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("a")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["a"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("a")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
{
|
||||
A = arg_0
|
||||
@@ -152,16 +202,14 @@ module internal InternalTypeNotExtension =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : InternalTypeNotExtension =
|
||||
let arg_0 =
|
||||
(match node.[(Literals.something)] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.[(Literals.something)] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
InternalThing = arg_0
|
||||
@@ -177,16 +225,14 @@ module internal InternalTypeExtensionJsonParseExtension =
|
||||
/// Parse from a JSON node.
|
||||
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : InternalTypeExtension =
|
||||
let arg_0 =
|
||||
(match node.[(Literals.something)] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.[(Literals.something)] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
ExternalThing = arg_0
|
||||
@@ -201,248 +247,215 @@ module ToGetExtensionMethodJsonParseExtension =
|
||||
|
||||
/// Parse from a JSON node.
|
||||
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : ToGetExtensionMethod =
|
||||
let arg_20 = System.Numerics.BigInteger.Parse (node.["whiskey"].ToJsonString ())
|
||||
let arg_20 =
|
||||
match node.["whiskey"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("whiskey")
|
||||
)
|
||||
)
|
||||
| Some node -> System.Numerics.BigInteger.Parse (node.ToJsonString ())
|
||||
|
||||
let arg_19 =
|
||||
(match node.["victor"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("victor")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Char> ()
|
||||
match node.["victor"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("victor")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Char> ()
|
||||
|
||||
let arg_18 =
|
||||
(match node.["uniform"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("uniform")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Decimal> ()
|
||||
match node.["uniform"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("uniform")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Decimal> ()
|
||||
|
||||
let arg_17 =
|
||||
(match node.["tango"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("tango")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.SByte> ()
|
||||
match node.["tango"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("tango")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.SByte> ()
|
||||
|
||||
let arg_16 =
|
||||
(match node.["quebec"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("quebec")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Byte> ()
|
||||
match node.["quebec"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("quebec")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Byte> ()
|
||||
|
||||
let arg_15 =
|
||||
(match node.["papa"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("papa")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Byte> ()
|
||||
match node.["papa"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("papa")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Byte> ()
|
||||
|
||||
let arg_14 =
|
||||
(match node.["oscar"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("oscar")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.SByte> ()
|
||||
match node.["oscar"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("oscar")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.SByte> ()
|
||||
|
||||
let arg_13 =
|
||||
(match node.["november"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("november")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.UInt16> ()
|
||||
match node.["november"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("november")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.UInt16> ()
|
||||
|
||||
let arg_12 =
|
||||
(match node.["mike"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("mike")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int16> ()
|
||||
match node.["mike"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("mike")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int16> ()
|
||||
|
||||
let arg_11 =
|
||||
(match node.["lima"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lima")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.UInt32> ()
|
||||
match node.["lima"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lima")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.UInt32> ()
|
||||
|
||||
let arg_10 =
|
||||
(match node.["kilo"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("kilo")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["kilo"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("kilo")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_9 =
|
||||
(match node.["juliette"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("juliette")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.UInt32> ()
|
||||
match node.["juliette"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("juliette")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.UInt32> ()
|
||||
|
||||
let arg_8 =
|
||||
(match node.["india"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("india")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["india"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("india")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_7 =
|
||||
(match node.["hotel"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("hotel")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.UInt64> ()
|
||||
match node.["hotel"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("hotel")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.UInt64> ()
|
||||
|
||||
let arg_6 =
|
||||
(match node.["golf"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("golf")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int64> ()
|
||||
match node.["golf"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("golf")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int64> ()
|
||||
|
||||
let arg_5 =
|
||||
(match node.["foxtrot"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("foxtrot")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Double> ()
|
||||
match node.["foxtrot"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("foxtrot")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Double> ()
|
||||
|
||||
let arg_4 =
|
||||
(match node.["echo"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("echo")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Single> ()
|
||||
match node.["echo"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("echo")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Single> ()
|
||||
|
||||
let arg_3 =
|
||||
(match node.["delta"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("delta")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Single> ()
|
||||
match node.["delta"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("delta")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Single> ()
|
||||
|
||||
let arg_2 =
|
||||
(match node.["charlie"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("charlie")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Double> ()
|
||||
match node.["charlie"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("charlie")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Double> ()
|
||||
|
||||
let arg_1 =
|
||||
(match node.["bravo"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("bravo")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<string> ()
|
||||
|> System.Uri
|
||||
match node.["bravo"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("bravo")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<string> () |> System.Uri
|
||||
|
||||
let arg_0 =
|
||||
(match node.["alpha"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("alpha")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["alpha"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("alpha")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
Alpha = arg_0
|
||||
|
@@ -206,3 +206,34 @@ type internal TypeWithInterfaceMock =
|
||||
|
||||
interface System.IDisposable with
|
||||
member this.Dispose () : unit = this.Dispose ()
|
||||
namespace SomeNamespace
|
||||
|
||||
open System
|
||||
open WoofWare.Myriad.Plugins
|
||||
|
||||
/// Mock record type for an interface
|
||||
type internal TypeWithPropertiesMock =
|
||||
{
|
||||
/// Implementation of IDisposable.Dispose
|
||||
Dispose : unit -> unit
|
||||
Prop1 : unit -> int
|
||||
Prop2 : unit -> unit Async
|
||||
Mem1 : string option -> string[] Async
|
||||
}
|
||||
|
||||
/// An implementation where every method throws.
|
||||
static member Empty : TypeWithPropertiesMock =
|
||||
{
|
||||
Dispose = (fun () -> ())
|
||||
Prop1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Prop1"))
|
||||
Prop2 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Prop2"))
|
||||
Mem1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem1"))
|
||||
}
|
||||
|
||||
interface TypeWithProperties with
|
||||
member this.Mem1 arg_0_0 = this.Mem1 (arg_0_0)
|
||||
member this.Prop1 = this.Prop1 ()
|
||||
member this.Prop2 = this.Prop2 ()
|
||||
|
||||
interface System.IDisposable with
|
||||
member this.Dispose () : unit = this.Dispose ()
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -48,7 +48,27 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
return jsonNode.AsArray () |> Seq.map (fun elt -> Gym.jsonParse elt) |> List.ofSeq
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Gym list"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return
|
||||
jsonNode.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type Gym) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> Gym.jsonParse elt)
|
||||
)
|
||||
|> List.ofSeq
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
|
||||
@@ -82,6 +102,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type GymAttendance"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return GymAttendance.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -116,6 +145,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type GymAttendance"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return GymAttendance.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -146,6 +184,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Member"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return Member.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -160,8 +207,7 @@ module PureGymApi =
|
||||
| null -> System.Uri "https://whatnot.com/"
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"v1/gyms/{gym}"
|
||||
.Replace ("{gym}", gym.ToString () |> System.Uri.EscapeDataString),
|
||||
"v1/gyms/{gym}".Replace ("{gym}", gym.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
@@ -180,6 +226,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Gym"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return Gym.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -210,6 +265,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type MemberActivityDto"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return MemberActivityDto.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -240,6 +304,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type UriThing"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return UriThing.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -267,23 +340,44 @@ module PureGymApi =
|
||||
foo
|
||||
|> (fun field ->
|
||||
match field with
|
||||
| None -> null :> System.Text.Json.Nodes.JsonNode
|
||||
| None -> None
|
||||
| Some field ->
|
||||
((fun field ->
|
||||
let ret = System.Text.Json.Nodes.JsonObject ()
|
||||
(field
|
||||
|> (fun field ->
|
||||
let ret = System.Text.Json.Nodes.JsonObject ()
|
||||
|
||||
for (KeyValue (key, value)) in field do
|
||||
ret.Add (
|
||||
key.ToString (),
|
||||
System.Text.Json.Nodes.JsonValue.Create<string> value
|
||||
)
|
||||
for (KeyValue (key, value)) in field do
|
||||
let key = key.ToString ()
|
||||
|
||||
ret
|
||||
)
|
||||
field)
|
||||
ret.Add (
|
||||
key,
|
||||
(fun field ->
|
||||
let field =
|
||||
System.Text.Json.Nodes.JsonValue.Create<string> field
|
||||
|
||||
(match field with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected type string to be non-null, but received a null value when serialising"
|
||||
)
|
||||
| field -> field)
|
||||
)
|
||||
value
|
||||
)
|
||||
|
||||
ret
|
||||
))
|
||||
:> System.Text.Json.Nodes.JsonNode
|
||||
|> Some
|
||||
)
|
||||
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
|
||||
|> (fun node ->
|
||||
match node with
|
||||
| None -> "null"
|
||||
| Some node -> node.ToJsonString ()
|
||||
),
|
||||
null,
|
||||
"application/json"
|
||||
)
|
||||
|
||||
do httpMessage.Content <- queryParams
|
||||
@@ -295,15 +389,25 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode = jsonNode |> Option.ofObj
|
||||
|
||||
return
|
||||
match jsonNode with
|
||||
| null -> None
|
||||
| v ->
|
||||
| None -> None
|
||||
| Some v ->
|
||||
v.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> Map.ofSeq
|
||||
|> Some
|
||||
@@ -347,6 +451,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Sessions"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return Sessions.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -388,6 +501,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Sessions"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return Sessions.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -547,9 +669,9 @@ module PureGymApi =
|
||||
|
||||
let queryParams =
|
||||
new System.Net.Http.StringContent (
|
||||
user
|
||||
|> PureGym.Member.toJsonNode
|
||||
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
|
||||
user |> PureGym.Member.toJsonNode |> (fun node -> node.ToJsonString ()),
|
||||
null,
|
||||
"application/json"
|
||||
)
|
||||
|
||||
do httpMessage.Content <- queryParams
|
||||
@@ -581,8 +703,20 @@ module PureGymApi =
|
||||
let queryParams =
|
||||
new System.Net.Http.StringContent (
|
||||
user
|
||||
|> System.Text.Json.Nodes.JsonValue.Create<Uri>
|
||||
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
|
||||
|> (fun field ->
|
||||
let field = System.Text.Json.Nodes.JsonValue.Create<Uri> field
|
||||
|
||||
(match field with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected type URI to be non-null, but received a null value when serialising"
|
||||
)
|
||||
| field -> field)
|
||||
)
|
||||
|> (fun node -> node.ToJsonString ()),
|
||||
null,
|
||||
"application/json"
|
||||
)
|
||||
|
||||
do httpMessage.Content <- queryParams
|
||||
@@ -614,8 +748,20 @@ module PureGymApi =
|
||||
let queryParams =
|
||||
new System.Net.Http.StringContent (
|
||||
user
|
||||
|> System.Text.Json.Nodes.JsonValue.Create<int>
|
||||
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
|
||||
|> (fun field ->
|
||||
let field = System.Text.Json.Nodes.JsonValue.Create<int> field
|
||||
|
||||
(match field with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected type int32 to be non-null, but received a null value when serialising"
|
||||
)
|
||||
| field -> field)
|
||||
)
|
||||
|> (fun node -> node.ToJsonString ()),
|
||||
null,
|
||||
"application/json"
|
||||
)
|
||||
|
||||
do httpMessage.Content <- queryParams
|
||||
@@ -879,6 +1025,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Response<MemberActivityDto>"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return
|
||||
new RestEase.Response<_> (
|
||||
responseString,
|
||||
@@ -915,6 +1070,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type RestEase.Response<MemberActivityDto>"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return
|
||||
new RestEase.Response<_> (
|
||||
responseString,
|
||||
@@ -951,6 +1115,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type Response<MemberActivityDto>"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return
|
||||
new RestEase.Response<_> (
|
||||
responseString,
|
||||
@@ -987,6 +1160,15 @@ module PureGymApi =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type RestEase.Response<MemberActivityDto>"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return
|
||||
new RestEase.Response<_> (
|
||||
responseString,
|
||||
@@ -1627,3 +1809,174 @@ module ApiWithHeaders2 =
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
}
|
||||
namespace PureGym
|
||||
|
||||
open System
|
||||
open System.Threading
|
||||
open System.Threading.Tasks
|
||||
open System.IO
|
||||
open System.Net
|
||||
open System.Net.Http
|
||||
open RestEase
|
||||
|
||||
/// Module for constructing a REST client.
|
||||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix) ; RequireQualifiedAccess>]
|
||||
module ClientWithJsonBody =
|
||||
/// Create a REST client.
|
||||
let make (client : System.Net.Http.HttpClient) : IClientWithJsonBody =
|
||||
{ new IClientWithJsonBody with
|
||||
member _.GetPathParam (parameter : string, mem : PureGym.Member, ct : CancellationToken option) =
|
||||
async {
|
||||
let! ct = Async.CancellationToken
|
||||
|
||||
let uri =
|
||||
System.Uri (
|
||||
(match client.BaseAddress with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException (
|
||||
nameof (client.BaseAddress),
|
||||
"No base address was supplied on the type, and no BaseAddress was on the HttpClient."
|
||||
)
|
||||
)
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
|
||||
let httpMessage =
|
||||
new System.Net.Http.HttpRequestMessage (
|
||||
Method = System.Net.Http.HttpMethod.Post,
|
||||
RequestUri = uri
|
||||
)
|
||||
|
||||
let queryParams =
|
||||
new System.Net.Http.StringContent (
|
||||
mem |> PureGym.Member.toJsonNode |> (fun node -> node.ToJsonString ()),
|
||||
null,
|
||||
"application/json"
|
||||
)
|
||||
|
||||
do httpMessage.Content <- queryParams
|
||||
let! response = client.SendAsync (httpMessage, ct) |> Async.AwaitTask
|
||||
let response = response.EnsureSuccessStatusCode ()
|
||||
let! responseString = response.Content.ReadAsStringAsync ct |> Async.AwaitTask
|
||||
return responseString
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
}
|
||||
namespace PureGym
|
||||
|
||||
open System
|
||||
open System.Threading
|
||||
open System.Threading.Tasks
|
||||
open System.IO
|
||||
open System.Net
|
||||
open System.Net.Http
|
||||
open RestEase
|
||||
|
||||
/// Module for constructing a REST client.
|
||||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix) ; RequireQualifiedAccess>]
|
||||
module ClientWithJsonBodyOverridden =
|
||||
/// Create a REST client.
|
||||
let make (client : System.Net.Http.HttpClient) : IClientWithJsonBodyOverridden =
|
||||
{ new IClientWithJsonBodyOverridden with
|
||||
member _.GetPathParam (parameter : string, mem : PureGym.Member, ct : CancellationToken option) =
|
||||
async {
|
||||
let! ct = Async.CancellationToken
|
||||
|
||||
let uri =
|
||||
System.Uri (
|
||||
(match client.BaseAddress with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException (
|
||||
nameof (client.BaseAddress),
|
||||
"No base address was supplied on the type, and no BaseAddress was on the HttpClient."
|
||||
)
|
||||
)
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
|
||||
let httpMessage =
|
||||
new System.Net.Http.HttpRequestMessage (
|
||||
Method = System.Net.Http.HttpMethod.Post,
|
||||
RequestUri = uri
|
||||
)
|
||||
|
||||
let queryParams =
|
||||
new System.Net.Http.StringContent (
|
||||
mem |> PureGym.Member.toJsonNode |> (fun node -> node.ToJsonString ()),
|
||||
null,
|
||||
"application/ecmascript"
|
||||
)
|
||||
|
||||
do httpMessage.Content <- queryParams
|
||||
let! response = client.SendAsync (httpMessage, ct) |> Async.AwaitTask
|
||||
let response = response.EnsureSuccessStatusCode ()
|
||||
let! responseString = response.Content.ReadAsStringAsync ct |> Async.AwaitTask
|
||||
return responseString
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
}
|
||||
namespace PureGym
|
||||
|
||||
open System
|
||||
open System.Threading
|
||||
open System.Threading.Tasks
|
||||
open System.IO
|
||||
open System.Net
|
||||
open System.Net.Http
|
||||
open RestEase
|
||||
|
||||
/// Module for constructing a REST client.
|
||||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix) ; RequireQualifiedAccess>]
|
||||
module ClientWithStringBody =
|
||||
/// Create a REST client.
|
||||
let make (client : System.Net.Http.HttpClient) : IClientWithStringBody =
|
||||
{ new IClientWithStringBody with
|
||||
member _.GetPathParam (parameter : string, mem : string, ct : CancellationToken option) =
|
||||
async {
|
||||
let! ct = Async.CancellationToken
|
||||
|
||||
let uri =
|
||||
System.Uri (
|
||||
(match client.BaseAddress with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException (
|
||||
nameof (client.BaseAddress),
|
||||
"No base address was supplied on the type, and no BaseAddress was on the HttpClient."
|
||||
)
|
||||
)
|
||||
| v -> v),
|
||||
System.Uri (
|
||||
"endpoint/{param}"
|
||||
.Replace ("{param}", parameter.ToString () |> System.Uri.EscapeDataString),
|
||||
System.UriKind.Relative
|
||||
)
|
||||
)
|
||||
|
||||
let httpMessage =
|
||||
new System.Net.Http.HttpRequestMessage (
|
||||
Method = System.Net.Http.HttpMethod.Post,
|
||||
RequestUri = uri
|
||||
)
|
||||
|
||||
let queryParams = new System.Net.Http.StringContent (mem)
|
||||
do httpMessage.Content <- queryParams
|
||||
let! response = client.SendAsync (httpMessage, ct) |> Async.AwaitTask
|
||||
let response = response.EnsureSuccessStatusCode ()
|
||||
let! responseString = response.Content.ReadAsStringAsync ct |> Async.AwaitTask
|
||||
return responseString
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -3423,7 +3423,7 @@ type IGitea =
|
||||
[<RestEase.Path "id">] id : int * ?ct : System.Threading.CancellationToken -> Hook System.Threading.Tasks.Task
|
||||
|
||||
/// Update a hook
|
||||
[<RestEase.Post "admin/hooks/{id}">]
|
||||
[<RestEase.Patch "admin/hooks/{id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract AdminEditHook :
|
||||
[<RestEase.Path "id">] id : int *
|
||||
@@ -3494,7 +3494,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit an existing user
|
||||
[<RestEase.Post "admin/users/{username}">]
|
||||
[<RestEase.Patch "admin/users/{username}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract AdminEditUser :
|
||||
[<RestEase.Path "username">] username : string *
|
||||
@@ -3601,7 +3601,7 @@ type IGitea =
|
||||
NotificationThread System.Threading.Tasks.Task
|
||||
|
||||
/// Mark notification thread as read by ID
|
||||
[<RestEase.Post "notifications/threads/{id}">]
|
||||
[<RestEase.Patch "notifications/threads/{id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract NotifyReadThread :
|
||||
[<RestEase.Path "id">] id : string *
|
||||
@@ -3649,7 +3649,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit an organization
|
||||
[<RestEase.Post "orgs/{org}">]
|
||||
[<RestEase.Patch "orgs/{org}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract OrgEdit :
|
||||
[<RestEase.Path "org">] org : string *
|
||||
@@ -3695,7 +3695,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Update a hook
|
||||
[<RestEase.Post "orgs/{org}/hooks/{id}">]
|
||||
[<RestEase.Patch "orgs/{org}/hooks/{id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract OrgEditHook :
|
||||
[<RestEase.Path "org">] org : string *
|
||||
@@ -3742,7 +3742,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Update a label
|
||||
[<RestEase.Post "orgs/{org}/labels/{id}">]
|
||||
[<RestEase.Patch "orgs/{org}/labels/{id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract OrgEditLabel :
|
||||
[<RestEase.Path "org">] org : string *
|
||||
@@ -3984,7 +3984,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit a repository's properties. Only fields that are set will be changed.
|
||||
[<RestEase.Post "repos/{owner}/{repo}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract RepoEdit :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -4052,7 +4052,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit a branch protections for a repository. Only fields that are set will be changed
|
||||
[<RestEase.Post "repos/{owner}/{repo}/branch_protections/{name}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/branch_protections/{name}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract RepoEditBranchProtection :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -4425,7 +4425,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit a Git hook in a repository
|
||||
[<RestEase.Post "repos/{owner}/{repo}/hooks/git/{id}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/hooks/git/{id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract RepoEditGitHook :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -4456,7 +4456,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit a hook in a repository
|
||||
[<RestEase.Post "repos/{owner}/{repo}/hooks/{id}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/hooks/{id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract RepoEditHook :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -4573,7 +4573,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit a comment attachment
|
||||
[<RestEase.Post "repos/{owner}/{repo}/issues/comments/{id}/assets/{attachment_id}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/issues/comments/{id}/assets/{attachment_id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract IssueEditIssueCommentAttachment :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -4626,7 +4626,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit an issue. If using deadline only the date will be taken into account, and time of day ignored.
|
||||
[<RestEase.Post "repos/{owner}/{repo}/issues/{index}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/issues/{index}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract IssueEditIssue :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -4669,7 +4669,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit an issue attachment
|
||||
[<RestEase.Post "repos/{owner}/{repo}/issues/{index}/assets/{attachment_id}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/issues/{index}/assets/{attachment_id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract IssueEditIssueAttachment :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -4999,7 +4999,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Update a label
|
||||
[<RestEase.Post "repos/{owner}/{repo}/labels/{id}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/labels/{id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract IssueEditLabel :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -5073,7 +5073,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Update a milestone
|
||||
[<RestEase.Post "repos/{owner}/{repo}/milestones/{id}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/milestones/{id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract IssueEditMilestone :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -5157,7 +5157,7 @@ type IGitea =
|
||||
PullRequest System.Threading.Tasks.Task
|
||||
|
||||
/// Update a pull request. If using deadline only the date will be taken into account, and time of day ignored.
|
||||
[<RestEase.Post "repos/{owner}/{repo}/pulls/{index}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/pulls/{index}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract RepoEditPullRequest :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -5495,7 +5495,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Update a release
|
||||
[<RestEase.Post "repos/{owner}/{repo}/releases/{id}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/releases/{id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract RepoEditRelease :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -5538,7 +5538,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit a release attachment
|
||||
[<RestEase.Post "repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract RepoEditReleaseAttachment :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -5845,7 +5845,7 @@ type IGitea =
|
||||
unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit a wiki page
|
||||
[<RestEase.Post "repos/{owner}/{repo}/wiki/page/{pageName}">]
|
||||
[<RestEase.Patch "repos/{owner}/{repo}/wiki/page/{pageName}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract RepoEditWikiPage :
|
||||
[<RestEase.Path "owner">] owner : string *
|
||||
@@ -5936,7 +5936,7 @@ type IGitea =
|
||||
[<RestEase.Path "id">] id : int * ?ct : System.Threading.CancellationToken -> unit System.Threading.Tasks.Task
|
||||
|
||||
/// Edit a team
|
||||
[<RestEase.Post "teams/{id}">]
|
||||
[<RestEase.Patch "teams/{id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract OrgEditTeam :
|
||||
[<RestEase.Path "id">] id : int *
|
||||
@@ -6066,7 +6066,7 @@ type IGitea =
|
||||
[<RestEase.Path "id">] id : int * ?ct : System.Threading.CancellationToken -> unit System.Threading.Tasks.Task
|
||||
|
||||
/// update an OAuth2 Application, this includes regenerating the client secret
|
||||
[<RestEase.Post "user/applications/oauth2/{id}">]
|
||||
[<RestEase.Patch "user/applications/oauth2/{id}">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract UserUpdateOAuth2Application :
|
||||
[<RestEase.Path "id">] id : int *
|
||||
@@ -6204,7 +6204,7 @@ type IGitea =
|
||||
abstract GetUserSettings : ?ct : System.Threading.CancellationToken -> UserSettings list System.Threading.Tasks.Task
|
||||
|
||||
/// Update user settings
|
||||
[<RestEase.Post "user/settings">]
|
||||
[<RestEase.Patch "user/settings">]
|
||||
[<RestEase.Header("Content-Type", "json")>]
|
||||
abstract UpdateUserSettings :
|
||||
[<RestEase.Body>] body : UserSettingsOptions * ?ct : System.Threading.CancellationToken ->
|
||||
|
@@ -13,139 +13,147 @@ module JwtVaultAuthResponse =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JwtVaultAuthResponse =
|
||||
let arg_10 =
|
||||
(match node.["num_uses"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("num_uses")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["num_uses"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("num_uses")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_9 =
|
||||
(match node.["orphan"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("orphan")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Boolean> ()
|
||||
match node.["orphan"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("orphan")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Boolean> ()
|
||||
|
||||
let arg_8 =
|
||||
(match node.["entity_id"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("entity_id")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["entity_id"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("entity_id")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_7 =
|
||||
(match node.["token_type"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("token_type")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["token_type"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("token_type")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_6 =
|
||||
(match node.["renewable"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Boolean> ()
|
||||
match node.["renewable"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Boolean> ()
|
||||
|
||||
let arg_5 =
|
||||
(match node.["lease_duration"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["lease_duration"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_4 =
|
||||
(match node.["identity_policies"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("identity_policies")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|
||||
|> List.ofSeq
|
||||
match node.["identity_policies"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("identity_policies")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type string) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> List.ofSeq
|
||||
|
||||
let arg_3 =
|
||||
(match node.["token_policies"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("token_policies")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|
||||
|> List.ofSeq
|
||||
match node.["token_policies"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("token_policies")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type string) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> List.ofSeq
|
||||
|
||||
let arg_2 =
|
||||
(match node.["policies"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("policies")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsArray ()
|
||||
|> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|
||||
|> List.ofSeq
|
||||
match node.["policies"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("policies")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsArray ()
|
||||
|> Seq.map (fun elt ->
|
||||
(match elt with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected element of array (element type string) to be non-null, but found a null element"
|
||||
)
|
||||
| elt -> elt.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> List.ofSeq
|
||||
|
||||
let arg_1 =
|
||||
(match node.["accessor"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("accessor")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["accessor"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("accessor")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_0 =
|
||||
(match node.["client_token"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("client_token")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["client_token"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("client_token")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
ClientToken = arg_0
|
||||
@@ -168,64 +176,54 @@ module JwtVaultResponse =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JwtVaultResponse =
|
||||
let arg_4 =
|
||||
JwtVaultAuthResponse.jsonParse (
|
||||
match node.["auth"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("auth")
|
||||
)
|
||||
match node.["auth"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("auth")
|
||||
)
|
||||
| v -> v
|
||||
)
|
||||
)
|
||||
| Some node -> JwtVaultAuthResponse.jsonParse node
|
||||
|
||||
let arg_3 =
|
||||
(match node.["lease_duration"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["lease_duration"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_2 =
|
||||
(match node.["renewable"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Boolean> ()
|
||||
match node.["renewable"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Boolean> ()
|
||||
|
||||
let arg_1 =
|
||||
(match node.["lease_id"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_id")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["lease_id"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_id")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_0 =
|
||||
(match node.["request_id"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("request_id")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["request_id"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("request_id")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
RequestId = arg_0
|
||||
@@ -242,190 +240,246 @@ module JwtSecretResponse =
|
||||
/// Parse from a JSON node.
|
||||
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JwtSecretResponse =
|
||||
let arg_11 =
|
||||
(match node.["data8"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data8")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<string> () |> System.Uri
|
||||
key, value
|
||||
)
|
||||
|> Seq.map System.Collections.Generic.KeyValuePair
|
||||
|> System.Collections.Generic.Dictionary
|
||||
match node.["data8"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data8")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type URI to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<string> () |> System.Uri)
|
||||
)
|
||||
|> Seq.map System.Collections.Generic.KeyValuePair
|
||||
|> System.Collections.Generic.Dictionary
|
||||
|
||||
let arg_10 =
|
||||
(match node.["data7"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data7")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.Int32> ()
|
||||
key, value
|
||||
)
|
||||
|> Map.ofSeq
|
||||
match node.["data7"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data7")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type int32 to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.Int32> ())
|
||||
)
|
||||
|> Map.ofSeq
|
||||
|
||||
let arg_9 =
|
||||
(match node.["data6"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data6")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key) |> System.Uri
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> dict
|
||||
match node.["data6"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data6")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key) |> System.Uri
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> dict
|
||||
|
||||
let arg_8 =
|
||||
(match node.["data5"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data5")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key) |> System.Uri
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> readOnlyDict
|
||||
match node.["data5"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data5")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key) |> System.Uri
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> readOnlyDict
|
||||
|
||||
let arg_7 =
|
||||
(match node.["data4"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data4")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> Map.ofSeq
|
||||
match node.["data4"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data4")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> Map.ofSeq
|
||||
|
||||
let arg_6 =
|
||||
(match node.["data3"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data3")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> Seq.map System.Collections.Generic.KeyValuePair
|
||||
|> System.Collections.Generic.Dictionary
|
||||
match node.["data3"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data3")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> Seq.map System.Collections.Generic.KeyValuePair
|
||||
|> System.Collections.Generic.Dictionary
|
||||
|
||||
let arg_5 =
|
||||
(match node.["data2"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data2")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> dict
|
||||
match node.["data2"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data2")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> dict
|
||||
|
||||
let arg_4 =
|
||||
(match node.["data"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = (kvp.Value).AsValue().GetValue<System.String> ()
|
||||
key, value
|
||||
)
|
||||
|> readOnlyDict
|
||||
match node.["data"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("data")
|
||||
)
|
||||
)
|
||||
| Some node ->
|
||||
node.AsObject ()
|
||||
|> Seq.map (fun kvp ->
|
||||
let key = (kvp.Key)
|
||||
let value = kvp.Value
|
||||
|
||||
key,
|
||||
(match value with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Expected dictionary value of type string to be non-null, but it was null"
|
||||
)
|
||||
| value -> value.AsValue().GetValue<System.String> ())
|
||||
)
|
||||
|> readOnlyDict
|
||||
|
||||
let arg_3 =
|
||||
(match node.["lease_duration"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Int32> ()
|
||||
match node.["lease_duration"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Int32> ()
|
||||
|
||||
let arg_2 =
|
||||
(match node.["renewable"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.Boolean> ()
|
||||
match node.["renewable"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("renewable")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.Boolean> ()
|
||||
|
||||
let arg_1 =
|
||||
(match node.["lease_id"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_id")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["lease_id"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("lease_id")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
let arg_0 =
|
||||
(match node.["request_id"] with
|
||||
| null ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("request_id")
|
||||
)
|
||||
)
|
||||
| v -> v)
|
||||
.AsValue()
|
||||
.GetValue<System.String> ()
|
||||
match node.["request_id"] |> Option.ofObj with
|
||||
| None ->
|
||||
raise (
|
||||
System.Collections.Generic.KeyNotFoundException (
|
||||
sprintf "Required key '%s' not found on JSON object" ("request_id")
|
||||
)
|
||||
)
|
||||
| Some node -> node.AsValue().GetValue<System.String> ()
|
||||
|
||||
{
|
||||
RequestId = arg_0
|
||||
@@ -496,6 +550,15 @@ module VaultClient =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtSecretResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtSecretResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -532,6 +595,15 @@ module VaultClient =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtVaultResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtVaultResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -590,6 +662,15 @@ module VaultClientNonExtensionMethod =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtSecretResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtSecretResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -626,6 +707,15 @@ module VaultClientNonExtensionMethod =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtVaultResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtVaultResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -687,6 +777,15 @@ module VaultClientExtensionMethodHttpClientExtension =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtSecretResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtSecretResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
@@ -723,6 +822,15 @@ module VaultClientExtensionMethodHttpClientExtension =
|
||||
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let jsonNode =
|
||||
(match jsonNode with
|
||||
| null ->
|
||||
raise (
|
||||
System.ArgumentNullException
|
||||
"Response from server was the JSON null object; expected a non-nullable type JwtVaultResponse"
|
||||
)
|
||||
| jsonNode -> jsonNode)
|
||||
|
||||
return JwtVaultResponse.jsonParse jsonNode
|
||||
}
|
||||
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
|
||||
|
@@ -48,3 +48,10 @@ type TypeWithInterface =
|
||||
inherit IDisposable
|
||||
abstract Mem1 : string option -> string[] Async
|
||||
abstract Mem2 : unit -> string[] Async
|
||||
|
||||
[<GenerateMock>]
|
||||
type TypeWithProperties =
|
||||
inherit IDisposable
|
||||
abstract Mem1 : string option -> string[] Async
|
||||
abstract Prop1 : int
|
||||
abstract Prop2 : unit Async
|
||||
|
@@ -203,3 +203,35 @@ type IApiWithHeaders2 =
|
||||
[<Get "endpoint/{param}">]
|
||||
abstract GetPathParam :
|
||||
[<WoofWare.Myriad.Plugins.RestEase.Path "param">] parameter : string * ?ct : CancellationToken -> Task<string>
|
||||
|
||||
[<WoofWare.Myriad.Plugins.HttpClient>]
|
||||
type IClientWithJsonBody =
|
||||
// As a POST request of a JSON-serialised body, we automatically set Content-Type: application/json.
|
||||
[<Post "endpoint/{param}">]
|
||||
abstract GetPathParam :
|
||||
[<RestEase.Path "param">] parameter : string *
|
||||
[<WoofWare.Myriad.Plugins.RestEase.Body>] mem : PureGym.Member *
|
||||
?ct : CancellationToken ->
|
||||
Task<string>
|
||||
|
||||
[<WoofWare.Myriad.Plugins.HttpClient>]
|
||||
type IClientWithJsonBodyOverridden =
|
||||
// As a POST request of a JSON-serialised body, we *would* automatically set Content-Type: application/json,
|
||||
// but this method has overridden it.
|
||||
[<Post "endpoint/{param}">]
|
||||
[<Header("Content-Type", "application/ecmascript")>]
|
||||
abstract GetPathParam :
|
||||
[<RestEase.Path "param">] parameter : string *
|
||||
[<WoofWare.Myriad.Plugins.RestEase.Body>] mem : PureGym.Member *
|
||||
?ct : CancellationToken ->
|
||||
Task<string>
|
||||
|
||||
[<WoofWare.Myriad.Plugins.HttpClient>]
|
||||
type IClientWithStringBody =
|
||||
// As a POST request of a bare string body, we don't override the Content-Type.
|
||||
[<Post "endpoint/{param}">]
|
||||
abstract GetPathParam :
|
||||
[<RestEase.Path "param">] parameter : string *
|
||||
[<WoofWare.Myriad.Plugins.RestEase.Body>] mem : string *
|
||||
?ct : CancellationToken ->
|
||||
Task<string>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
<WarnOn>FS3388,FS3559</WarnOn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Nerdbank.GitVersioning" Version="3.7.115" PrivateAssets="all"/>
|
||||
<PackageReference Include="Nerdbank.GitVersioning" Version="3.8.38-alpha" PrivateAssets="all"/>
|
||||
<SourceLinkGitHubHost Include="github.com" ContentUrl="https://raw.githubusercontent.com"/>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(GITHUB_ACTION)' != ''">
|
||||
|
@@ -136,7 +136,7 @@ module InnerTypeWithBoth =
|
||||
ret.Add (key.ToString (), System.Text.Json.Nodes.JsonValue.Create<Uri> value)
|
||||
|
||||
ret
|
||||
) input.Map
|
||||
) input.ReadOnlyDict
|
||||
)
|
||||
|
||||
node
|
||||
|
@@ -26,6 +26,11 @@ type ArgParserAttribute (isExtensionMethod : bool) =
|
||||
/// an argument which looks like a flag but which we don't recognise.)
|
||||
/// We will still interpret `--help` as requesting help, unless it comes after
|
||||
/// a standalone `--` separator.
|
||||
///
|
||||
/// If the type of the PositionalArgs field is `Choice<'a, 'a>`, then we will
|
||||
/// tell you whether each arg came before or after a standalone `--` separator.
|
||||
/// For example, `MyApp foo bar -- baz` with PositionalArgs of `Choice<string, string>`
|
||||
/// would yield `Choice1Of2 foo, Choice1Of2 bar, Choice2Of2 baz`.
|
||||
type PositionalArgsAttribute (includeFlagLike : bool) =
|
||||
inherit Attribute ()
|
||||
|
||||
|
@@ -17,10 +17,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ApiSurface" Version="4.1.16" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
|
||||
<PackageReference Include="ApiSurface" Version="4.1.21" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
|
||||
<PackageReference Include="NUnit" Version="4.3.2"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -68,7 +68,7 @@ module TestArgParser =
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envCalls |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let args = [ "--foo=3" ; "--non-existent" ; "--bar=4" ; "--baz=true" ]
|
||||
|
||||
@@ -91,7 +91,7 @@ module TestArgParser =
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envCalls |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let property (args : (int * bool) list) (afterDoubleDash : int list option) =
|
||||
let flatArgs =
|
||||
@@ -127,7 +127,7 @@ module TestArgParser =
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envCalls |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let args = [ "--foo=3" ; "--rest" ; "7" ; "--bar=4" ; "--baz=true" ; "--rest=8" ]
|
||||
|
||||
@@ -150,7 +150,7 @@ module TestArgParser =
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envCalls |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let args = [ "--foo=3" ; "--foo" ; "9" ; "--bar=4" ; "--baz=true" ; "--baz=false" ]
|
||||
|
||||
@@ -171,7 +171,7 @@ Argument '--baz' was supplied multiple times: True and false"""
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envCalls |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let args = [ "--" ; "--foo=3" ; "--bar=4" ; "--baz=true" ]
|
||||
|
||||
@@ -191,7 +191,7 @@ Required argument '--baz' received no value"""
|
||||
let ``Help text`` () =
|
||||
let getEnvVar (s : string) =
|
||||
s |> shouldEqual "CONSUMEPLUGIN_THINGS"
|
||||
"hi!"
|
||||
Some "hi!"
|
||||
|
||||
let exc =
|
||||
Assert.Throws<exn> (fun () -> Basic.parse' getEnvVar [ "--help" ] |> ignore<Basic>)
|
||||
@@ -210,7 +210,7 @@ Required argument '--baz' received no value"""
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment envVars |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let exc =
|
||||
Assert.Throws<exn> (fun () -> LoadsOfTypes.parse' getEnvVar [ "--help" ] |> ignore<LoadsOfTypes>)
|
||||
@@ -236,7 +236,7 @@ Required argument '--baz' received no value"""
|
||||
let ``Default values`` () =
|
||||
let getEnvVar (s : string) =
|
||||
s |> shouldEqual "CONSUMEPLUGIN_THINGS"
|
||||
"hi!"
|
||||
Some "hi!"
|
||||
|
||||
let args =
|
||||
[
|
||||
@@ -264,7 +264,7 @@ Required argument '--baz' received no value"""
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment count |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let exc =
|
||||
Assert.Throws<exn> (fun () -> DatesAndTimes.parse' getEnvVar [ "--help" ] |> ignore<DatesAndTimes>)
|
||||
@@ -285,7 +285,7 @@ Required argument '--baz' received no value"""
|
||||
|
||||
let getEnvVar (_ : string) =
|
||||
Interlocked.Increment count |> ignore<int>
|
||||
""
|
||||
None
|
||||
|
||||
let parsed =
|
||||
DatesAndTimes.parse'
|
||||
@@ -448,7 +448,7 @@ Required argument '--exact' received no value"""
|
||||
let ``Bool env vars can be populated`` (envValue : string, boolValue : bool) =
|
||||
let getEnvVar (s : string) =
|
||||
s |> shouldEqual "CONSUMEPLUGIN_THINGS"
|
||||
envValue
|
||||
Some envValue
|
||||
|
||||
ContainsBoolEnvVar.parse' getEnvVar []
|
||||
|> shouldEqual
|
||||
@@ -470,7 +470,7 @@ Required argument '--exact' received no value"""
|
||||
let ``Flag DUs can be parsed from env var`` (envValue : string, boolValue : bool) =
|
||||
let getEnvVar (s : string) =
|
||||
s |> shouldEqual "CONSUMEPLUGIN_THINGS"
|
||||
envValue
|
||||
Some envValue
|
||||
|
||||
let boolValue = if boolValue then DryRunMode.Dry else DryRunMode.Wet
|
||||
|
||||
|
@@ -3,10 +3,12 @@ namespace WoofWare.Myriad.Plugins.Test
|
||||
open System
|
||||
open System.Net
|
||||
open System.Net.Http
|
||||
open System.Text.Json.Nodes
|
||||
open System.Threading
|
||||
open NUnit.Framework
|
||||
open FsUnitTyped
|
||||
open PureGym
|
||||
open WoofWare.Expect
|
||||
|
||||
[<TestFixture>]
|
||||
module TestVariableHeader =
|
||||
@@ -50,15 +52,17 @@ module TestVariableHeader =
|
||||
someHeaderCount.Value |> shouldEqual 10
|
||||
someOtherHeaderCount.Value |> shouldEqual -100
|
||||
|
||||
api.GetPathParam("param").Result.Split "\n"
|
||||
|> Array.sort
|
||||
|> shouldEqual
|
||||
[|
|
||||
"Authorization: -99"
|
||||
"Header-Name: Header-Value"
|
||||
"Something-Else: val"
|
||||
"X-Foo: 11"
|
||||
|]
|
||||
expect {
|
||||
snapshotJson
|
||||
@"[
|
||||
""Authorization: -99"",
|
||||
""Header-Name: Header-Value"",
|
||||
""Something-Else: val"",
|
||||
""X-Foo: 11""
|
||||
]"
|
||||
|
||||
return api.GetPathParam("param").Result.Split "\n" |> Array.sort
|
||||
}
|
||||
|
||||
someHeaderCount.Value |> shouldEqual 11
|
||||
someOtherHeaderCount.Value |> shouldEqual -99
|
||||
@@ -102,25 +106,156 @@ module TestVariableHeader =
|
||||
someHeaderCount.Value |> shouldEqual 10
|
||||
someOtherHeaderCount.Value |> shouldEqual -100
|
||||
|
||||
api.GetPathParam("param").Result.Split "\n"
|
||||
|> Array.sort
|
||||
|> shouldEqual
|
||||
[|
|
||||
"Authorization: -99"
|
||||
"Header-Name: Header-Value"
|
||||
"Something-Else: val"
|
||||
"X-Foo: 11"
|
||||
|]
|
||||
expect {
|
||||
snapshotJson
|
||||
@"[
|
||||
""Authorization: -99"",
|
||||
""Header-Name: Header-Value"",
|
||||
""Something-Else: val"",
|
||||
""X-Foo: 11""
|
||||
]"
|
||||
|
||||
api.GetPathParam("param").Result.Split "\n"
|
||||
|> Array.sort
|
||||
|> shouldEqual
|
||||
[|
|
||||
"Authorization: -98"
|
||||
"Header-Name: Header-Value"
|
||||
"Something-Else: val"
|
||||
"X-Foo: 12"
|
||||
|]
|
||||
return api.GetPathParam("param").Result.Split "\n" |> Array.sort
|
||||
}
|
||||
|
||||
expect {
|
||||
snapshotJson
|
||||
@"[
|
||||
""Authorization: -98"",
|
||||
""Header-Name: Header-Value"",
|
||||
""Something-Else: val"",
|
||||
""X-Foo: 12""
|
||||
]"
|
||||
|
||||
return api.GetPathParam("param").Result.Split "\n" |> Array.sort
|
||||
}
|
||||
|
||||
someHeaderCount.Value |> shouldEqual 12
|
||||
someOtherHeaderCount.Value |> shouldEqual -98
|
||||
|
||||
let pureGymMember =
|
||||
{
|
||||
Id = 3
|
||||
CompoundMemberId = "compound"
|
||||
FirstName = "Patrick"
|
||||
LastName = "Stevens"
|
||||
HomeGymId = 1223
|
||||
HomeGymName = "Arnie's Temple o' Gainz"
|
||||
EmailAddress = "patrick@home"
|
||||
GymAccessPin = "1234"
|
||||
DateOfBirth = DateOnly (1992, 03, 04)
|
||||
MobileNumber = "number"
|
||||
Postcode = "postcode"
|
||||
MembershipName = "member"
|
||||
MembershipLevel = 9999
|
||||
SuspendedReason = -1
|
||||
MemberStatus = 100
|
||||
}
|
||||
|
||||
[<Test>]
|
||||
let ``Content-Type header is automatically inserted`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Post
|
||||
|
||||
message.RequestUri.ToString ()
|
||||
|> shouldEqual "https://example.com/endpoint/param"
|
||||
|
||||
let headers =
|
||||
[
|
||||
for h in message.Content.Headers do
|
||||
yield $"%s{h.Key}: %s{Seq.exactlyOne h.Value}"
|
||||
]
|
||||
|> String.concat "\n"
|
||||
|
||||
let! ct = Async.CancellationToken
|
||||
let! content = message.Content.ReadAsStringAsync ct |> Async.AwaitTask
|
||||
content |> JsonNode.Parse |> Member.jsonParse |> shouldEqual pureGymMember
|
||||
|
||||
let content = new StringContent (headers)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
|
||||
let api = ClientWithJsonBody.make client
|
||||
let result = api.GetPathParam ("param", pureGymMember) |> _.Result
|
||||
|
||||
expect {
|
||||
snapshot @"Content-Type: application/json; charset=utf-8"
|
||||
return result
|
||||
}
|
||||
|
||||
[<Test>]
|
||||
let ``Content-Type header is respected if overridden`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Post
|
||||
|
||||
message.RequestUri.ToString ()
|
||||
|> shouldEqual "https://example.com/endpoint/param"
|
||||
|
||||
let headers =
|
||||
[
|
||||
for h in message.Content.Headers do
|
||||
yield $"%s{h.Key}: %s{Seq.exactlyOne h.Value}"
|
||||
]
|
||||
|> String.concat "\n"
|
||||
|
||||
let! ct = Async.CancellationToken
|
||||
let! content = message.Content.ReadAsStringAsync ct |> Async.AwaitTask
|
||||
content |> JsonNode.Parse |> Member.jsonParse |> shouldEqual pureGymMember
|
||||
|
||||
let content = new StringContent (headers)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
|
||||
let api = ClientWithJsonBodyOverridden.make client
|
||||
let result = api.GetPathParam ("param", pureGymMember) |> _.Result
|
||||
|
||||
expect {
|
||||
snapshot @"Content-Type: application/ecmascript; charset=utf-8"
|
||||
return result
|
||||
}
|
||||
|
||||
[<Test>]
|
||||
let ``Content-Type header is the default for strings`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Post
|
||||
|
||||
message.RequestUri.ToString ()
|
||||
|> shouldEqual "https://example.com/endpoint/param"
|
||||
|
||||
let headers =
|
||||
[
|
||||
for h in message.Content.Headers do
|
||||
yield $"%s{h.Key}: %s{Seq.exactlyOne h.Value}"
|
||||
]
|
||||
|> String.concat "\n"
|
||||
|
||||
let! ct = Async.CancellationToken
|
||||
let! content = message.Content.ReadAsStringAsync ct |> Async.AwaitTask
|
||||
content |> shouldEqual "hello!"
|
||||
|
||||
let content = new StringContent (headers)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
|
||||
let api = ClientWithStringBody.make client
|
||||
let result = api.GetPathParam ("param", "hello!") |> _.Result
|
||||
|
||||
expect {
|
||||
snapshot @"Content-Type: text/plain; charset=utf-8"
|
||||
return result
|
||||
}
|
||||
|
@@ -34,3 +34,16 @@ module TestMockGenerator =
|
||||
mock.Mem1 3 'a' |> shouldEqual "aaa"
|
||||
mock.Mem2 (3, "hi") 'a' |> shouldEqual "hiahiahi"
|
||||
mock.Mem3 (3, "hi") 'a' |> shouldEqual "hiahiahi"
|
||||
|
||||
[<Test>]
|
||||
let ``Example of use: properties`` () =
|
||||
let mock : TypeWithProperties =
|
||||
{ TypeWithPropertiesMock.Empty with
|
||||
Mem1 = fun i -> async { return Option.toArray i }
|
||||
Prop1 = fun () -> 44
|
||||
}
|
||||
:> _
|
||||
|
||||
mock.Mem1 (Some "hi") |> Async.RunSynchronously |> shouldEqual [| "hi" |]
|
||||
|
||||
mock.Prop1 |> shouldEqual 44
|
||||
|
@@ -3,7 +3,7 @@ namespace WoofWare.Myriad.Plugins.Test
|
||||
open System.Text.Json.Nodes
|
||||
open NUnit.Framework
|
||||
open FsUnitTyped
|
||||
open WoofWare.Myriad.Plugins
|
||||
open WoofWare.Myriad.Plugins.SwaggerV2
|
||||
|
||||
[<TestFixture>]
|
||||
module TestSwaggerParse =
|
||||
|
@@ -9,6 +9,7 @@
|
||||
I have not yet seen a single instance where I care about this warning
|
||||
-->
|
||||
<NoWarn>$(NoWarn),NU1903</NoWarn>
|
||||
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -41,12 +42,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ApiSurface" Version="4.1.16"/>
|
||||
<PackageReference Include="FsCheck" Version="3.0.0"/>
|
||||
<PackageReference Include="FsUnit" Version="6.0.1"/>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
|
||||
<PackageReference Include="ApiSurface" Version="4.1.21"/>
|
||||
<PackageReference Include="FsCheck" Version="3.3.0"/>
|
||||
<PackageReference Include="FsUnit" Version="7.0.1"/>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
|
||||
<PackageReference Include="NUnit" Version="4.3.2"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0"/>
|
||||
<PackageReference Include="WoofWare.Expect" Version="0.4.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
@@ -673,7 +673,7 @@ module internal ArgParserGenerator =
|
||||
args
|
||||
|> Map.toList
|
||||
|> List.map (fun (ident, expr) -> SynLongIdent.create [ Ident.create ident ], expr)
|
||||
|> AstHelper.instantiateRecord
|
||||
|> SynExpr.createRecord None
|
||||
)
|
||||
|
||||
tree, counter
|
||||
@@ -1396,7 +1396,7 @@ module internal ArgParserGenerator =
|
||||
|
||||
[
|
||||
SynMatchClause.create
|
||||
SynPat.createNull
|
||||
(SynPat.named "None")
|
||||
(SynExpr.sequential
|
||||
[
|
||||
errorMessage
|
||||
@@ -1406,7 +1406,7 @@ module internal ArgParserGenerator =
|
||||
unchecked
|
||||
])
|
||||
|
||||
SynMatchClause.create (SynPat.named "x") parser
|
||||
SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "x" ]) parser
|
||||
]
|
||||
|> SynExpr.createMatch result
|
||||
| ArgumentDefaultSpec.FunctionCall name ->
|
||||
@@ -1694,7 +1694,7 @@ module internal ArgParserGenerator =
|
||||
[ Ident.create "parse'" ]
|
||||
[
|
||||
SynPat.named "getEnvironmentVariable"
|
||||
|> SynPat.annotateType (SynType.funFromDomain SynType.string SynType.string)
|
||||
|> SynPat.annotateType (SynType.funFromDomain SynType.string (SynType.option SynType.string))
|
||||
argsParam
|
||||
]
|
||||
|> SynBinding.withReturnAnnotation (SynType.createLongIdent [ taggedType.Name ])
|
||||
@@ -1708,7 +1708,12 @@ module internal ArgParserGenerator =
|
||||
|
||||
let parse =
|
||||
SynExpr.createLongIdent' parsePrimeCall
|
||||
|> SynExpr.applyTo (SynExpr.createLongIdent [ "System" ; "Environment" ; "GetEnvironmentVariable" ])
|
||||
|> SynExpr.applyTo (
|
||||
SynExpr.paren (
|
||||
SynExpr.createLongIdent [ "System" ; "Environment" ; "GetEnvironmentVariable" ]
|
||||
|> SynExpr.composeWith (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
)
|
||||
)
|
||||
|> SynExpr.applyTo (SynExpr.createIdent "args")
|
||||
|> SynBinding.basic [ Ident.create "parse" ] [ argsParam ]
|
||||
|> SynBinding.withReturnAnnotation (SynType.createLongIdent [ taggedType.Name ])
|
||||
|
6
WoofWare.Myriad.Plugins/AssemblyInfo.fs
Normal file
6
WoofWare.Myriad.Plugins/AssemblyInfo.fs
Normal file
@@ -0,0 +1,6 @@
|
||||
module internal WoofWare.Myriad.Plugins.AssemblyInfo
|
||||
|
||||
open System.Runtime.CompilerServices
|
||||
|
||||
[<assembly : InternalsVisibleTo("WoofWare.Myriad.Plugins.Test")>]
|
||||
do ()
|
@@ -36,13 +36,6 @@ module internal AstHelper =
|
||||
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Enum _, _) -> true
|
||||
| _ -> false
|
||||
|
||||
let instantiateRecord (fields : (SynLongIdent * SynExpr) list) : SynExpr =
|
||||
let fields =
|
||||
fields
|
||||
|> List.map (fun (rfn, synExpr) -> SynExprRecordField ((rfn, true), Some range0, Some synExpr, None))
|
||||
|
||||
SynExpr.Record (None, None, fields, range0)
|
||||
|
||||
let defineRecordType (record : RecordType) : SynTypeDefn =
|
||||
let name =
|
||||
SynComponentInfo.create record.Name
|
||||
|
@@ -1174,28 +1174,30 @@ module internal CataGenerator =
|
||||
]
|
||||
|> SynModuleOrNamespace.createNamespace ns
|
||||
|
||||
/// This function comes from Myriad, and is therefore derived from an Apache 2.0-licenced work.
|
||||
/// https://github.com/MoiraeSoftware/myriad/blob/3c9818faabf9d508c10c28d5ecd26e66fafb48a1/src/Myriad.Core/Ast.fs#L160
|
||||
/// A copy of the Apache 2.0 licence is at ApacheLicence.txt.
|
||||
/// For each namespace/module, grab the types which are defined in consecutive `and`-knots in that namespace/module,
|
||||
/// and also return the fully-qualified namespace/module name alongside that group of types.
|
||||
/// A given module LongIdent may show up many times in the output: once for each recursive knot.
|
||||
// Function originally inspired by https://github.com/MoiraeSoftware/myriad/blob/3c9818faabf9d508c10c28d5ecd26e66fafb48a1/src/Myriad.Core/Ast.fs#L160
|
||||
// but there's really only one reasonable implementation of this type signature and semantics.
|
||||
let groupedTypeDefns (ast : ParsedInput) : (LongIdent * SynTypeDefn list) list =
|
||||
let rec extractTypes (moduleDecls : SynModuleDecl list) (ns : LongIdent) =
|
||||
[
|
||||
for moduleDecl in moduleDecls do
|
||||
match moduleDecl with
|
||||
| SynModuleDecl.Types (types, _) -> yield (ns, types)
|
||||
| SynModuleDecl.NestedModule (SynComponentInfo (_, _, _, longId, _, _, _, _), _, decls, _, _, _) ->
|
||||
let combined = longId |> List.append ns
|
||||
yield! (extractTypes decls combined)
|
||||
| _ -> ()
|
||||
]
|
||||
let rec extractTypes (decls : SynModuleDecl list) (ns : LongIdent) =
|
||||
decls
|
||||
|> List.collect (fun moduleDecl ->
|
||||
match moduleDecl with
|
||||
| SynModuleDecl.Types (types, _) -> [ ns, types ]
|
||||
| SynModuleDecl.NestedModule (SynComponentInfo (_, _, _, longId, _, _, _, _), _, decls, _, _, _) ->
|
||||
let combined = longId |> List.append ns
|
||||
extractTypes decls combined
|
||||
| _ -> []
|
||||
)
|
||||
|
||||
[
|
||||
match ast with
|
||||
| ParsedInput.ImplFile (ParsedImplFileInput (_, _, _, _, _, modules, _, _, _)) ->
|
||||
for SynModuleOrNamespace (namespaceId, _, _, moduleDecls, _, _, _, _, _) in modules do
|
||||
yield! extractTypes moduleDecls namespaceId
|
||||
| _ -> ()
|
||||
]
|
||||
match ast with
|
||||
| ParsedInput.ImplFile (ParsedImplFileInput (_, _, _, _, _, contents, _, _, _)) ->
|
||||
contents
|
||||
|> List.collect (fun (SynModuleOrNamespace (namespaceId, _, _, moduleDecls, _, _, _, _, _)) ->
|
||||
extractTypes moduleDecls namespaceId
|
||||
)
|
||||
| _ -> []
|
||||
|
||||
open Myriad.Core
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open System.IO
|
||||
open System.Net.Http
|
||||
open Fantomas.FCS.Syntax
|
||||
open WoofWare.Whippet.Fantomas
|
||||
@@ -14,17 +13,6 @@ type internal HttpClientGeneratorOutputSpec =
|
||||
module internal HttpClientGenerator =
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
let outputFile = FileInfo "/tmp/output.txt"
|
||||
|
||||
// do
|
||||
// use _ = File.Create outputFile.FullName
|
||||
// ()
|
||||
|
||||
let log (line : string) =
|
||||
// use w = outputFile.AppendText ()
|
||||
// w.WriteLine line
|
||||
()
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type PathSpec =
|
||||
| Verbatim of string
|
||||
@@ -82,7 +70,7 @@ module internal HttpClientGenerator =
|
||||
if m = HttpMethod.Get then "Get"
|
||||
elif m = HttpMethod.Post then "Post"
|
||||
elif m = HttpMethod.Delete then "Delete"
|
||||
elif m = HttpMethod.Patch then "Post"
|
||||
elif m = HttpMethod.Patch then "Patch"
|
||||
elif m = HttpMethod.Options then "Options"
|
||||
elif m = HttpMethod.Head then "Head"
|
||||
elif m = HttpMethod.Put then "Put"
|
||||
@@ -409,42 +397,76 @@ module internal HttpClientGenerator =
|
||||
| String -> SynExpr.createIdent "responseString"
|
||||
| Stream -> SynExpr.createIdent "responseStream"
|
||||
| RestEaseResponseType contents ->
|
||||
let deserialiser =
|
||||
JsonParseGenerator.parseNode
|
||||
match JsonNodeWithNullability.Identify contents with
|
||||
| CannotBeNull ->
|
||||
let deserialiser =
|
||||
JsonParseGenerator.parseNonNullableNode
|
||||
None
|
||||
JsonParseGenerator.JsonParseOption.None
|
||||
contents
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.createThunk
|
||||
|
||||
// new RestEase.Response (content : string, response : HttpResponseMessage, deserialiser : unit -> 'T)
|
||||
SynExpr.createNew
|
||||
(SynType.app' (SynType.createLongIdent' [ "RestEase" ; "Response" ]) [ SynType.Anon range0 ])
|
||||
(SynExpr.tupleNoParen
|
||||
[
|
||||
SynExpr.createIdent "responseString"
|
||||
SynExpr.createIdent "response"
|
||||
deserialiser
|
||||
])
|
||||
| Nullable ->
|
||||
let deserialiser =
|
||||
JsonParseGenerator.parseNullableNode
|
||||
None
|
||||
JsonParseGenerator.JsonParseOption.None
|
||||
contents
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.createThunk
|
||||
|
||||
// new RestEase.Response (content : string, response : HttpResponseMessage, deserialiser : unit -> 'T)
|
||||
SynExpr.createNew
|
||||
(SynType.app' (SynType.createLongIdent' [ "RestEase" ; "Response" ]) [ SynType.Anon range0 ])
|
||||
(SynExpr.tupleNoParen
|
||||
[
|
||||
SynExpr.createIdent "responseString"
|
||||
SynExpr.createIdent "response"
|
||||
deserialiser
|
||||
])
|
||||
| retType ->
|
||||
match JsonNodeWithNullability.Identify retType with
|
||||
| Nullable ->
|
||||
JsonParseGenerator.parseNullableNode
|
||||
None
|
||||
JsonParseGenerator.JsonParseOption.None
|
||||
contents
|
||||
retType
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
| CannotBeNull ->
|
||||
JsonParseGenerator.parseNonNullableNode
|
||||
None
|
||||
JsonParseGenerator.JsonParseOption.None
|
||||
retType
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.createThunk
|
||||
|
||||
// new RestEase.Response (content : string, response : HttpResponseMessage, deserialiser : unit -> 'T)
|
||||
SynExpr.createNew
|
||||
(SynType.app' (SynType.createLongIdent' [ "RestEase" ; "Response" ]) [ SynType.Anon range0 ])
|
||||
(SynExpr.tupleNoParen
|
||||
[
|
||||
SynExpr.createIdent "responseString"
|
||||
SynExpr.createIdent "response"
|
||||
deserialiser
|
||||
])
|
||||
| retType ->
|
||||
JsonParseGenerator.parseNode
|
||||
None
|
||||
JsonParseGenerator.JsonParseOption.None
|
||||
retType
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
|
||||
let contentTypeHeader, memberHeaders =
|
||||
info.Headers
|
||||
|> List.partition (fun (headerName, headerValue) ->
|
||||
|> List.partition (fun (headerName, _headerValue) ->
|
||||
match headerName |> SynExpr.stripOptionalParen with
|
||||
| SynExpr.Const (SynConst.String ("Content-Type", _, _), _) -> true
|
||||
| SynExpr.Const (SynConst.String (s, _, _), _) ->
|
||||
System.String.Equals (s, "Content-Type", System.StringComparison.OrdinalIgnoreCase)
|
||||
| _ -> false
|
||||
)
|
||||
|
||||
let contentTypeHeader =
|
||||
match contentTypeHeader with
|
||||
| [] -> None
|
||||
| [] ->
|
||||
// Set application/json if we *know* we're sending JSON
|
||||
match bodyParam with
|
||||
| Some (BodyParamMethods.Serialise _, _) -> Some (SynExpr.CreateConst "application/json")
|
||||
| _ -> None
|
||||
| [ _, ct ] -> Some (SynExpr.stripOptionalParen ct)
|
||||
| _ -> failwith "Unexpectedly got multiple Content-Type headers"
|
||||
|
||||
@@ -505,23 +527,45 @@ module internal HttpClientGenerator =
|
||||
)
|
||||
]
|
||||
| BodyParamMethods.Serialise ty ->
|
||||
let isNullable =
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| CannotBeNull -> false
|
||||
| Nullable -> true
|
||||
|
||||
[
|
||||
Let (
|
||||
"queryParams",
|
||||
createStringContent (
|
||||
SynExpr.createIdent' bodyParamName
|
||||
|> SynExpr.pipeThroughFunction (fst (JsonSerializeGenerator.serializeNode ty))
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
fst (
|
||||
(if isNullable then
|
||||
JsonSerializeGenerator.serializeNodeNullable
|
||||
else
|
||||
JsonSerializeGenerator.serializeNodeNonNullable)
|
||||
ty
|
||||
)
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLambda
|
||||
"node"
|
||||
(SynExpr.ifThenElse
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createIdent "isNull")
|
||||
(SynExpr.createIdent "node"))
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "node" ; "ToJsonString" ])
|
||||
(SynExpr.CreateConst ()))
|
||||
(SynExpr.CreateConst "null"))
|
||||
(if isNullable then
|
||||
SynExpr.createMatch
|
||||
(SynExpr.createIdent "node")
|
||||
[
|
||||
SynMatchClause.create
|
||||
(SynPat.named "None")
|
||||
(SynExpr.CreateConst "null")
|
||||
SynMatchClause.create
|
||||
(SynPat.nameWithArgs "Some" [ SynPat.named "node" ])
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "node" ; "ToJsonString" ])
|
||||
(SynExpr.CreateConst ()))
|
||||
]
|
||||
else
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "node" ; "ToJsonString" ])
|
||||
(SynExpr.CreateConst ())))
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -568,6 +612,24 @@ module internal HttpClientGenerator =
|
||||
)
|
||||
)
|
||||
|
||||
let jsonNodeWithoutNull =
|
||||
match JsonNodeWithNullability.Identify info.TaskReturnType with
|
||||
| Nullable ->
|
||||
Let (
|
||||
"jsonNode",
|
||||
SynExpr.createIdent "jsonNode"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
)
|
||||
| CannotBeNull ->
|
||||
Let (
|
||||
"jsonNode",
|
||||
JsonSerializeGenerator.assertNotNull
|
||||
(Ident.create "jsonNode")
|
||||
(SynExpr.CreateConst
|
||||
$"Response from server was the JSON null object; expected a non-nullable type %s{SynType.toHumanReadableString info.TaskReturnType}")
|
||||
(SynExpr.createIdent "jsonNode")
|
||||
)
|
||||
|
||||
let setVariableHeaders =
|
||||
variableHeaders
|
||||
|> List.map (fun (headerName, callToGetValue) ->
|
||||
@@ -642,6 +704,7 @@ module internal HttpClientGenerator =
|
||||
yield responseString
|
||||
yield responseStream
|
||||
yield jsonNode
|
||||
yield jsonNodeWithoutNull
|
||||
| String -> yield responseString
|
||||
| Stream -> yield responseStream
|
||||
| UnitType ->
|
||||
@@ -650,6 +713,7 @@ module internal HttpClientGenerator =
|
||||
| _ ->
|
||||
yield responseStream
|
||||
yield jsonNode
|
||||
yield jsonNodeWithoutNull
|
||||
]
|
||||
|> SynExpr.createCompExpr "async" returnExpr
|
||||
|> SynExpr.startAsTask cancellationTokenArg
|
||||
|
66
WoofWare.Myriad.Plugins/HttpMethod.fs
Normal file
66
WoofWare.Myriad.Plugins/HttpMethod.fs
Normal file
@@ -0,0 +1,66 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open System
|
||||
|
||||
/// An HTTP method. This is System.Net.Http.HttpMethod, but
|
||||
/// a proper discriminated union.
|
||||
type HttpMethod =
|
||||
/// HTTP Get
|
||||
| Get
|
||||
/// HTTP Post
|
||||
| Post
|
||||
/// HTTP Delete
|
||||
| Delete
|
||||
/// HTTP Patch
|
||||
| Patch
|
||||
/// HTTP Options
|
||||
| Options
|
||||
/// HTTP Head
|
||||
| Head
|
||||
/// HTTP Put
|
||||
| Put
|
||||
/// HTTP Trace
|
||||
| Trace
|
||||
|
||||
/// Convert to the standard library's enum type.
|
||||
member this.ToDotNet () : System.Net.Http.HttpMethod =
|
||||
match this with
|
||||
| HttpMethod.Get -> System.Net.Http.HttpMethod.Get
|
||||
| HttpMethod.Post -> System.Net.Http.HttpMethod.Post
|
||||
| HttpMethod.Delete -> System.Net.Http.HttpMethod.Delete
|
||||
| HttpMethod.Patch -> System.Net.Http.HttpMethod.Patch
|
||||
| HttpMethod.Options -> System.Net.Http.HttpMethod.Options
|
||||
| HttpMethod.Head -> System.Net.Http.HttpMethod.Head
|
||||
| HttpMethod.Put -> System.Net.Http.HttpMethod.Put
|
||||
| HttpMethod.Trace -> System.Net.Http.HttpMethod.Trace
|
||||
|
||||
/// Human-readable string representation.
|
||||
override this.ToString () : string =
|
||||
match this with
|
||||
| HttpMethod.Get -> "Get"
|
||||
| HttpMethod.Post -> "Post"
|
||||
| HttpMethod.Delete -> "Delete"
|
||||
| HttpMethod.Patch -> "Patch"
|
||||
| HttpMethod.Options -> "Options"
|
||||
| HttpMethod.Head -> "Head"
|
||||
| HttpMethod.Put -> "Put"
|
||||
| HttpMethod.Trace -> "Trace"
|
||||
|
||||
/// Throws on invalid inputs.
|
||||
static member Parse (s : string) : HttpMethod =
|
||||
if String.Equals (s, "get", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Get
|
||||
elif String.Equals (s, "post", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Post
|
||||
elif String.Equals (s, "patch", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Patch
|
||||
elif String.Equals (s, "delete", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Delete
|
||||
elif String.Equals (s, "head", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Head
|
||||
elif String.Equals (s, "options", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Options
|
||||
elif String.Equals (s, "put", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Put
|
||||
else
|
||||
failwith $"Unrecognised method: %s{s}"
|
@@ -89,7 +89,7 @@ module internal InterfaceMockGenerator =
|
||||
[]
|
||||
else
|
||||
[ SynPat.unit ])
|
||||
(AstHelper.instantiateRecord constructorFields)
|
||||
(SynExpr.createRecord None constructorFields)
|
||||
|> SynBinding.withXmlDoc (PreXmlDoc.create "An implementation where every method throws.")
|
||||
|> SynBinding.withReturnAnnotation constructorReturnType
|
||||
|> SynMemberDefn.staticMember
|
||||
@@ -159,6 +159,15 @@ module internal InterfaceMockGenerator =
|
||||
|> SynMemberDefn.memberImplementation
|
||||
)
|
||||
|
||||
let properties =
|
||||
interfaceType.Properties
|
||||
|> List.map (fun pi ->
|
||||
SynExpr.createLongIdent' [ Ident.create "this" ; pi.Identifier ]
|
||||
|> SynExpr.applyTo (SynExpr.CreateConst ())
|
||||
|> SynBinding.basic [ Ident.create "this" ; pi.Identifier ] []
|
||||
|> SynMemberDefn.memberImplementation
|
||||
)
|
||||
|
||||
let interfaceName =
|
||||
let baseName = SynType.createLongIdent interfaceType.Name
|
||||
|
||||
@@ -174,7 +183,7 @@ module internal InterfaceMockGenerator =
|
||||
|
||||
SynType.app' baseName generics
|
||||
|
||||
SynMemberDefn.Interface (interfaceName, Some range0, Some members, range0)
|
||||
SynMemberDefn.Interface (interfaceName, Some range0, Some (members @ properties), range0)
|
||||
|
||||
let access =
|
||||
match interfaceType.Accessibility, spec.IsInternal with
|
||||
@@ -248,6 +257,15 @@ module internal InterfaceMockGenerator =
|
||||
|> SynField.make
|
||||
|> SynField.withDocString (mem.XmlDoc |> Option.defaultValue PreXmlDoc.Empty)
|
||||
|
||||
let constructProperty (prop : PropertyInfo) : SynField =
|
||||
{
|
||||
Attrs = []
|
||||
Ident = Some prop.Identifier
|
||||
Type = SynType.toFun [ SynType.unit ] prop.Type
|
||||
}
|
||||
|> SynField.make
|
||||
|> SynField.withDocString (prop.XmlDoc |> Option.defaultValue PreXmlDoc.Empty)
|
||||
|
||||
let createRecord
|
||||
(namespaceId : LongIdent)
|
||||
(opens : SynOpenDeclTarget list)
|
||||
@@ -255,7 +273,12 @@ module internal InterfaceMockGenerator =
|
||||
: SynModuleOrNamespace
|
||||
=
|
||||
let interfaceType = AstHelper.parseInterface interfaceType
|
||||
let fields = interfaceType.Members |> List.map constructMember
|
||||
|
||||
let fields =
|
||||
interfaceType.Members
|
||||
|> List.map constructMember
|
||||
|> List.append (interfaceType.Properties |> List.map constructProperty)
|
||||
|
||||
let docString = PreXmlDoc.create "Mock record type for an interface"
|
||||
|
||||
let name =
|
||||
|
48
WoofWare.Myriad.Plugins/JsonHelpers.fs
Normal file
48
WoofWare.Myriad.Plugins/JsonHelpers.fs
Normal file
@@ -0,0 +1,48 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open System.Text.Json.Nodes
|
||||
|
||||
[<AutoOpen>]
|
||||
module internal JsonHelpers =
|
||||
let inline asString (n : JsonNode) (key : string) : string =
|
||||
match n.[key] with
|
||||
| null -> failwith $"Expected node to have a key '%s{key}', but it did not: %s{n.ToJsonString ()}"
|
||||
| s -> s.GetValue<string> ()
|
||||
|
||||
[<RequiresExplicitTypeArguments>]
|
||||
let inline asOpt<'ret> (n : JsonNode) (key : string) : 'ret option =
|
||||
match n.[key] with
|
||||
| null -> None
|
||||
| s -> s.GetValue<'ret> () |> Some
|
||||
|
||||
let inline asObj (n : JsonNode) (key : string) : JsonObject =
|
||||
match n.[key] with
|
||||
| null -> failwith $"Expected node to have a key '%s{key}', but it did not: %s{n.ToJsonString ()}"
|
||||
| o -> o.AsObject ()
|
||||
|
||||
let inline asObjOpt (n : JsonNode) (key : string) : JsonObject option =
|
||||
match n.[key] with
|
||||
| null -> None
|
||||
| o -> o.AsObject () |> Some
|
||||
|
||||
let inline asArr (n : JsonNode) (key : string) : JsonArray =
|
||||
match n.[key] with
|
||||
| null -> failwith $"Expected node to have a key '%s{key}', but it did not: %s{n.ToJsonString ()}"
|
||||
| o -> o.AsArray ()
|
||||
|
||||
let inline asArrOpt (n : JsonNode) (key : string) : JsonArray option =
|
||||
match n.[key] with
|
||||
| null -> None
|
||||
| o -> o.AsArray () |> Some
|
||||
|
||||
[<RequiresExplicitTypeArguments>]
|
||||
let inline asArr'<'v> (n : JsonNode) (key : string) : 'v list =
|
||||
match n.[key] with
|
||||
| null -> failwith $"Expected node to have a key '%s{key}', but it did not: %s{n.ToJsonString ()}"
|
||||
| o -> o.AsArray () |> Seq.map (fun v -> v.GetValue<'v> ()) |> Seq.toList
|
||||
|
||||
[<RequiresExplicitTypeArguments>]
|
||||
let inline asArrOpt'<'v> (n : JsonNode) (key : string) : 'v list option =
|
||||
match n.[key] with
|
||||
| null -> None
|
||||
| o -> o.AsArray () |> Seq.map (fun v -> v.GetValue<'v> ()) |> Seq.toList |> Some
|
@@ -26,7 +26,7 @@ module internal JsonParseGenerator =
|
||||
}
|
||||
|
||||
/// (match {indexed} with | null -> raise (System.Collections.Generic.KeyNotFoundException ({propertyName} not found)) | v -> v)
|
||||
let assertNotNull (propertyName : SynExpr) (indexed : SynExpr) =
|
||||
let assertPropertyExists (propertyName : SynExpr) (indexed : SynExpr) =
|
||||
let raiseExpr =
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createIdent "sprintf")
|
||||
@@ -40,34 +40,34 @@ module internal JsonParseGenerator =
|
||||
|> SynExpr.applyFunction (SynExpr.createIdent "raise")
|
||||
|
||||
[
|
||||
SynMatchClause.create SynPat.createNull raiseExpr
|
||||
SynMatchClause.create (SynPat.named "v") (SynExpr.createIdent "v")
|
||||
SynMatchClause.create (SynPat.named "None") raiseExpr
|
||||
SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "v" ]) (SynExpr.createIdent "v")
|
||||
]
|
||||
|> SynExpr.createMatch indexed
|
||||
|> SynExpr.paren
|
||||
|
||||
/// {node}.AsValue().GetValue<{typeName}> ()
|
||||
/// If `propertyName` is Some, uses `assertNotNull {node}` instead of `{node}`.
|
||||
/// If `propertyName` is Some, uses `assertPropertyExists {node}` instead of `{node}`.
|
||||
let asValueGetValue (propertyName : SynExpr option) (typeName : string) (node : SynExpr) : SynExpr =
|
||||
match propertyName with
|
||||
| None -> node
|
||||
| Some propertyName -> assertNotNull propertyName node
|
||||
| Some propertyName -> assertPropertyExists propertyName node
|
||||
|> SynExpr.callMethod "AsValue"
|
||||
|> SynExpr.callGenericMethod' "GetValue" typeName
|
||||
|
||||
let asValueGetValueIdent (propertyName : SynExpr option) (typeName : LongIdent) (node : SynExpr) : SynExpr =
|
||||
match propertyName with
|
||||
| None -> node
|
||||
| Some propertyName -> assertNotNull propertyName node
|
||||
| Some propertyName -> assertPropertyExists propertyName node
|
||||
|> SynExpr.callMethod "AsValue"
|
||||
|> SynExpr.callGenericMethod (SynLongIdent.createS "GetValue") [ SynType.createLongIdent typeName ]
|
||||
|
||||
/// {node}.AsObject()
|
||||
/// If `propertyName` is Some, uses `assertNotNull {node}` instead of `{node}`.
|
||||
/// If `propertyName` is Some, uses `assertPropertyExists {node}` instead of `{node}`.
|
||||
let asObject (propertyName : SynExpr option) (node : SynExpr) : SynExpr =
|
||||
match propertyName with
|
||||
| None -> node
|
||||
| Some propertyName -> assertNotNull propertyName node
|
||||
| Some propertyName -> assertPropertyExists propertyName node
|
||||
|> SynExpr.callMethod "AsObject"
|
||||
|
||||
/// {type}.jsonParse {node}
|
||||
@@ -77,11 +77,12 @@ module internal JsonParseGenerator =
|
||||
|
||||
/// collectionType is e.g. "List"; we'll be calling `ofSeq` on it.
|
||||
/// body is the body of a lambda which takes a parameter `elt`.
|
||||
/// {assertNotNull node}.AsArray()
|
||||
/// |> Seq.map (fun elt -> {body})
|
||||
/// {assertPropertyExists node}.AsArray()
|
||||
/// |> Seq.map (fun elt -> {assertNotNull} {body})
|
||||
/// |> {collectionType}.ofSeq
|
||||
let asArrayMapped
|
||||
(propertyName : SynExpr option)
|
||||
(elementType : SynType)
|
||||
(collectionType : string)
|
||||
(node : SynExpr)
|
||||
(body : SynExpr)
|
||||
@@ -89,10 +90,23 @@ module internal JsonParseGenerator =
|
||||
=
|
||||
match propertyName with
|
||||
| None -> node
|
||||
| Some propertyName -> assertNotNull propertyName node
|
||||
| Some propertyName -> assertPropertyExists propertyName node
|
||||
|> SynExpr.callMethod "AsArray"
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction (SynExpr.createLongIdent [ "Seq" ; "map" ]) (SynExpr.createLambda "elt" body)
|
||||
body
|
||||
|> JsonSerializeGenerator.assertNotNull
|
||||
(Ident.create "elt")
|
||||
(match propertyName with
|
||||
| None ->
|
||||
SynExpr.CreateConst
|
||||
$"Expected element of array (element type %s{SynType.toHumanReadableString elementType}) to be non-null, but found a null element"
|
||||
| Some propertyName ->
|
||||
SynExpr.CreateConst
|
||||
$"Expected element of array (element type %s{SynType.toHumanReadableString elementType}) to be non-null, but found a null element, at %%s"
|
||||
|> SynExpr.applyFunction (SynExpr.createIdent "sprintf")
|
||||
|> SynExpr.applyTo propertyName)
|
||||
|> SynExpr.createLambda "elt"
|
||||
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ collectionType ; "ofSeq" ])
|
||||
|
||||
@@ -101,14 +115,41 @@ module internal JsonParseGenerator =
|
||||
|
||||
/// fun kvp -> let key = {key(kvp)} in let value = {value(kvp)} in (key, value))
|
||||
/// The inputs will be fed with appropriate SynExprs to apply them to the `kvp.Key` and `kvp.Value` args.
|
||||
let dictionaryMapper (key : SynExpr -> SynExpr) (value : SynExpr -> SynExpr) : SynExpr =
|
||||
let dictionaryMapper
|
||||
(propertyName : SynExpr option)
|
||||
(valueTypeIsNullable : bool)
|
||||
(key : SynExpr -> SynExpr)
|
||||
(valueType : SynType)
|
||||
(value : SynExpr -> SynExpr)
|
||||
: SynExpr
|
||||
=
|
||||
let keyArg = SynExpr.createLongIdent [ "kvp" ; "Key" ] |> SynExpr.paren
|
||||
|
||||
let valueArg = SynExpr.createLongIdent [ "kvp" ; "Value" ] |> SynExpr.paren
|
||||
let valueArg = SynExpr.createLongIdent [ "kvp" ; "Value" ]
|
||||
|
||||
let value =
|
||||
if valueTypeIsNullable then
|
||||
(value (SynExpr.createIdent "value"))
|
||||
else
|
||||
let errorMessage =
|
||||
match propertyName with
|
||||
| None ->
|
||||
SynExpr.CreateConst
|
||||
$"Expected dictionary value of type %s{SynType.toHumanReadableString valueType} to be non-null, but it was null"
|
||||
| Some propertyName ->
|
||||
SynExpr.CreateConst
|
||||
$"Expected dictionary value of type %s{SynType.toHumanReadableString valueType} to be non-null, but it was null, at key %%s"
|
||||
|> SynExpr.applyFunction (SynExpr.createIdent "sprintf")
|
||||
|> SynExpr.applyTo propertyName
|
||||
|
||||
JsonSerializeGenerator.assertNotNull
|
||||
(Ident.create "value")
|
||||
errorMessage
|
||||
(value (SynExpr.createIdent "value"))
|
||||
|
||||
// No need to paren here, we're on the LHS of a `let`
|
||||
SynExpr.tupleNoParen [ SynExpr.createIdent "key" ; SynExpr.createIdent "value" ]
|
||||
|> SynExpr.createLet [ SynBinding.basic [ Ident.create "value" ] [] (value valueArg) ]
|
||||
SynExpr.tupleNoParen [ SynExpr.createIdent "key" ; value ]
|
||||
|> SynExpr.createLet [ SynBinding.basic [ Ident.create "value" ] [] valueArg ]
|
||||
|> SynExpr.createLet [ SynBinding.basic [ Ident.create "key" ] [] (key keyArg) ]
|
||||
|> SynExpr.createLambda "kvp"
|
||||
|
||||
@@ -165,10 +206,61 @@ module internal JsonParseGenerator =
|
||||
))
|
||||
handler
|
||||
|
||||
let rec parseNullableNode
|
||||
// TODO: unused?!
|
||||
(propertyName : SynExpr option)
|
||||
(options : JsonParseOption)
|
||||
(fieldType : SynType)
|
||||
(node : SynExpr)
|
||||
: SynExpr
|
||||
=
|
||||
match fieldType with
|
||||
| OptionType ty ->
|
||||
match ty with
|
||||
| OptionType _
|
||||
| NullableType _ ->
|
||||
failwith
|
||||
$"Nested nullable types are not supported, because we can't distinguish between None and Some None. %s{SynType.toHumanReadableString ty}"
|
||||
| _ ->
|
||||
|
||||
let someClause =
|
||||
parseNonNullableNode None options ty (SynExpr.createIdent "v")
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|
||||
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "v" ])
|
||||
|
||||
[
|
||||
SynMatchClause.create (SynPat.named "None") (SynExpr.createIdent "None")
|
||||
someClause
|
||||
]
|
||||
|> SynExpr.createMatch node
|
||||
| NullableType ty ->
|
||||
match ty with
|
||||
| OptionType _
|
||||
| NullableType _ ->
|
||||
failwith
|
||||
$"Nested nullable types are not supported, because we can't distinguish between None and Some None. %s{SynType.toHumanReadableString ty}"
|
||||
| _ ->
|
||||
|
||||
let someClause =
|
||||
parseNonNullableNode None options ty (SynExpr.createIdent "v")
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ])
|
||||
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "v" ])
|
||||
|
||||
[
|
||||
SynMatchClause.create
|
||||
(SynPat.named "None")
|
||||
(SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ]) (SynExpr.CreateConst ()))
|
||||
someClause
|
||||
]
|
||||
|> SynExpr.createMatch node
|
||||
| _ ->
|
||||
failwith
|
||||
$"Encountered type %s{SynType.toHumanReadableString fieldType} which is expected to be nullable, but couldn't identify it"
|
||||
|
||||
/// Given `node.["town"]`, for example, choose how to obtain a JSON value from it.
|
||||
/// The property name is used in error messages at runtime to show where a JSON
|
||||
/// parse error occurred; supply `None` to indicate "don't validate".
|
||||
let rec parseNode
|
||||
and parseNonNullableNode
|
||||
(propertyName : SynExpr option)
|
||||
(options : JsonParseOption)
|
||||
(fieldType : SynType)
|
||||
@@ -177,101 +269,184 @@ module internal JsonParseGenerator =
|
||||
=
|
||||
// TODO: parsing format for DateTime etc
|
||||
match fieldType with
|
||||
| OptionType _
|
||||
| NullableType _ ->
|
||||
failwith
|
||||
$"Unexpectedly parsing nullable type %s{SynType.toHumanReadableString fieldType} as if it were non-nullable."
|
||||
// Struct types
|
||||
| DateOnly ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateOnly" ; "Parse" ])
|
||||
| Uri ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Uri" ])
|
||||
| Guid ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Guid" ; "Parse" ])
|
||||
| DateTime ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTime" ; "Parse" ])
|
||||
| NumberType typeName -> parseNumberType options propertyName node typeName
|
||||
| Guid ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Guid" ; "Parse" ])
|
||||
// Reference types
|
||||
| Uri ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Uri" ])
|
||||
| DateTimeOffset ->
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTimeOffset" ; "Parse" ])
|
||||
| NumberType typeName -> parseNumberType options propertyName node typeName
|
||||
| PrimitiveType typeName -> asValueGetValueIdent propertyName typeName node
|
||||
| OptionType ty ->
|
||||
let someClause =
|
||||
parseNode None options ty (SynExpr.createIdent "v")
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|
||||
|> SynMatchClause.create (SynPat.named "v")
|
||||
|
||||
[
|
||||
SynMatchClause.create SynPat.createNull (SynExpr.createIdent "None")
|
||||
someClause
|
||||
]
|
||||
|> SynExpr.createMatch node
|
||||
| NullableType ty ->
|
||||
let someClause =
|
||||
parseNode None options ty (SynExpr.createIdent "v")
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ])
|
||||
|> SynMatchClause.create (SynPat.named "v")
|
||||
|
||||
[
|
||||
SynMatchClause.create
|
||||
SynPat.createNull
|
||||
(SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ]) (SynExpr.CreateConst ()))
|
||||
someClause
|
||||
]
|
||||
|> SynExpr.createMatch node
|
||||
| ListType ty ->
|
||||
parseNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName "List" node
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| CannotBeNull ->
|
||||
parseNonNullableNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName ty "List" node
|
||||
| Nullable ->
|
||||
parseNullableNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName ty "List" node
|
||||
| ArrayType ty ->
|
||||
parseNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName "Array" node
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| CannotBeNull ->
|
||||
parseNonNullableNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName ty "Array" node
|
||||
| Nullable ->
|
||||
parseNullableNode None options ty (SynExpr.createIdent "elt")
|
||||
|> asArrayMapped propertyName ty "Array" node
|
||||
| IDictionaryType (keyType, valueType) ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "dict")
|
||||
match JsonNodeWithNullability.Identify valueType with
|
||||
| CannotBeNull ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
false
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNonNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "dict")
|
||||
| Nullable ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
true
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "dict")
|
||||
| DictionaryType (keyType, valueType) ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "KeyValuePair" ])
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "Dictionary" ]
|
||||
)
|
||||
match JsonNodeWithNullability.Identify valueType with
|
||||
| CannotBeNull ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
false
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNonNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "KeyValuePair" ])
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "Dictionary" ]
|
||||
)
|
||||
| Nullable ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
true
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "KeyValuePair" ])
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "Dictionary" ]
|
||||
)
|
||||
| IReadOnlyDictionaryType (keyType, valueType) ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "readOnlyDict")
|
||||
match JsonNodeWithNullability.Identify valueType with
|
||||
| CannotBeNull ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
false
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNonNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "readOnlyDict")
|
||||
| Nullable ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
true
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "readOnlyDict")
|
||||
| MapType (keyType, valueType) ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Map" ; "ofSeq" ])
|
||||
match JsonNodeWithNullability.Identify valueType with
|
||||
| CannotBeNull ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
false
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNonNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Map" ; "ofSeq" ])
|
||||
| Nullable ->
|
||||
node
|
||||
|> asObject propertyName
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "Seq" ; "map" ])
|
||||
(dictionaryMapper
|
||||
propertyName
|
||||
true
|
||||
(parseKeyString keyType)
|
||||
valueType
|
||||
(parseNullableNode None options valueType))
|
||||
)
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Map" ; "ofSeq" ])
|
||||
| BigInt ->
|
||||
node
|
||||
|> SynExpr.callMethod "ToJsonString"
|
||||
@@ -282,7 +457,7 @@ module internal JsonParseGenerator =
|
||||
|> SynExpr.pipeThroughFunction (Measure.getLanguagePrimitivesMeasure primType)
|
||||
| JsonNode -> node
|
||||
| UnitType -> SynExpr.CreateConst ()
|
||||
| _ ->
|
||||
| fieldType ->
|
||||
// Let's just hope that we've also got our own type annotation!
|
||||
let typeName =
|
||||
match fieldType with
|
||||
@@ -291,14 +466,45 @@ module internal JsonParseGenerator =
|
||||
|
||||
match propertyName with
|
||||
| None -> node
|
||||
| Some propertyName -> assertNotNull propertyName node
|
||||
| Some propertyName -> assertPropertyExists propertyName node
|
||||
|> typeJsonParse typeName
|
||||
|
||||
/// propertyName is probably a string literal, but it could be a [<Literal>] variable
|
||||
/// The result of this function is the body of a let-binding (not including the LHS of that let-binding).
|
||||
let createParseRhs (options : JsonParseOption) (propertyName : SynExpr) (fieldType : SynType) : SynExpr =
|
||||
let objectToParse = SynExpr.createIdent "node" |> SynExpr.index propertyName
|
||||
parseNode (Some propertyName) options fieldType objectToParse
|
||||
match JsonNodeWithNullability.Identify fieldType with
|
||||
| Nullable ->
|
||||
let objectToParse =
|
||||
SynExpr.createIdent "node"
|
||||
|> SynExpr.index propertyName
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
|
||||
parseNullableNode (Some propertyName) options fieldType objectToParse
|
||||
| CannotBeNull ->
|
||||
[
|
||||
SynMatchClause.create
|
||||
(SynPat.named "None")
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createIdent "raise")
|
||||
(SynExpr.paren (
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent
|
||||
[ "System" ; "Collections" ; "Generic" ; "KeyNotFoundException" ])
|
||||
(SynExpr.applyFunction
|
||||
(SynExpr.createIdent "sprintf")
|
||||
(SynExpr.CreateConst "Required key '%s' not found on JSON object")
|
||||
|> SynExpr.applyTo (SynExpr.paren propertyName)
|
||||
|> SynExpr.paren)
|
||||
)))
|
||||
SynMatchClause.create
|
||||
(SynPat.nameWithArgs "Some" [ SynPat.named "node" ])
|
||||
(parseNonNullableNode None options fieldType (SynExpr.createIdent "node"))
|
||||
]
|
||||
|> SynExpr.createMatch (
|
||||
SynExpr.createIdent "node"
|
||||
|> SynExpr.index propertyName
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
)
|
||||
|
||||
let isJsonNumberHandling (literal : LongIdent) : bool =
|
||||
match List.rev literal |> List.map (fun ident -> ident.idText) with
|
||||
@@ -351,10 +557,7 @@ module internal JsonParseGenerator =
|
||||
let getParseOptions (fieldAttrs : SynAttribute list) =
|
||||
(JsonParseOption.None, fieldAttrs)
|
||||
||> List.fold (fun options attr ->
|
||||
if
|
||||
(SynLongIdent.toString attr.TypeName)
|
||||
.EndsWith ("JsonNumberHandling", StringComparison.Ordinal)
|
||||
then
|
||||
if (SynLongIdent.toString attr.TypeName).EndsWith ("JsonNumberHandling", StringComparison.Ordinal) then
|
||||
let qualifiedEnumValue =
|
||||
match SynExpr.stripOptionalParen attr.ArgExpr with
|
||||
| SynExpr.LongIdent (_, SynLongIdent (ident, _, _), _, _) when isJsonNumberHandling ident ->
|
||||
@@ -384,15 +587,13 @@ module internal JsonParseGenerator =
|
||||
let propertyNameAttr =
|
||||
fieldData.Attrs
|
||||
|> List.tryFind (fun attr ->
|
||||
(SynLongIdent.toString attr.TypeName)
|
||||
.EndsWith ("JsonPropertyName", StringComparison.Ordinal)
|
||||
(SynLongIdent.toString attr.TypeName).EndsWith ("JsonPropertyName", StringComparison.Ordinal)
|
||||
)
|
||||
|
||||
let extensionDataAttr =
|
||||
fieldData.Attrs
|
||||
|> List.tryFind (fun attr ->
|
||||
(SynLongIdent.toString attr.TypeName)
|
||||
.EndsWith ("JsonExtensionData", StringComparison.Ordinal)
|
||||
(SynLongIdent.toString attr.TypeName).EndsWith ("JsonExtensionData", StringComparison.Ordinal)
|
||||
)
|
||||
|
||||
let propertyName =
|
||||
@@ -485,7 +686,7 @@ module internal JsonParseGenerator =
|
||||
let finalConstruction =
|
||||
fields
|
||||
|> List.mapi (fun i fieldData -> SynLongIdent.createI fieldData.Ident, SynExpr.createIdent $"arg_%i{i}")
|
||||
|> AstHelper.instantiateRecord
|
||||
|> SynExpr.createRecord None
|
||||
|
||||
(finalConstruction, assignments)
|
||||
||> List.fold (fun final assignment -> SynExpr.createLet [ assignment ] final)
|
||||
@@ -510,7 +711,8 @@ module internal JsonParseGenerator =
|
||||
|> SynExpr.createLet
|
||||
[
|
||||
SynExpr.index (SynExpr.CreateConst "data") (SynExpr.createIdent "node")
|
||||
|> assertNotNull (SynExpr.CreateConst "data")
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
|> assertPropertyExists (SynExpr.CreateConst "data")
|
||||
|> SynBinding.basic [ Ident.create "node" ] []
|
||||
]
|
||||
|
||||
@@ -558,7 +760,8 @@ module internal JsonParseGenerator =
|
||||
|
||||
SynExpr.createIdent "node"
|
||||
|> SynExpr.index property
|
||||
|> assertNotNull property
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|
||||
|> assertPropertyExists property
|
||||
|> SynExpr.pipeThroughFunction (
|
||||
SynExpr.createLambda "v" (SynExpr.callGenericMethod' "GetValue" "string" (SynExpr.createIdent "v"))
|
||||
)
|
||||
|
@@ -10,24 +10,100 @@ type internal JsonSerializeOutputSpec =
|
||||
ExtensionMethods : bool
|
||||
}
|
||||
|
||||
/// https://github.com/Smaug123/WoofWare.Myriad/issues/364
|
||||
/// The insane design of System.Text.Json is finally causing us to
|
||||
/// do vast amounts of coding rather than merely being very annoying.
|
||||
type internal JsonNodeWithNullability =
|
||||
| CannotBeNull
|
||||
| Nullable
|
||||
|
||||
static member Identify (ty : SynType) : JsonNodeWithNullability =
|
||||
match ty with
|
||||
| OptionType _
|
||||
| NullableType _ -> JsonNodeWithNullability.Nullable
|
||||
| _ -> JsonNodeWithNullability.CannotBeNull
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal JsonSerializeGenerator =
|
||||
open Fantomas.FCS.Text.Range
|
||||
|
||||
|
||||
// The absolutely galaxy-brained implementation of JsonValue has `JsonValue.Parse "null"`
|
||||
// identically equal to null. We have to work around this later, but we might as well just
|
||||
// be efficient here and whip up the null directly.
|
||||
let private jsonNull () =
|
||||
SynExpr.createNull ()
|
||||
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|
||||
// identically equal to null, so it's hard to use that type. We use `None` instead to represent
|
||||
// the JSON null value.
|
||||
let private jsonNull () = SynExpr.createIdent "None"
|
||||
|
||||
let assertNotNull (boundIdent : Ident) (message : SynExpr) (body : SynExpr) : SynExpr =
|
||||
let raiseExpr =
|
||||
message
|
||||
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "ArgumentNullException" ])
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.applyFunction (SynExpr.createIdent "raise")
|
||||
|
||||
[
|
||||
SynMatchClause.create SynPat.createNull raiseExpr
|
||||
SynMatchClause.create (SynPat.namedI boundIdent) body
|
||||
]
|
||||
|> SynExpr.createMatch (SynExpr.createIdent' boundIdent)
|
||||
|> SynExpr.paren
|
||||
|
||||
/// The output of this will be an *optional* JsonNode.
|
||||
let rec serializeNodeNullable (fieldType : SynType) : SynExpr * bool =
|
||||
match fieldType with
|
||||
| NullableType ty ->
|
||||
// fun field -> if field.HasValue then {serializeNode ty} field.Value else JsonValue.Create null
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| JsonNodeWithNullability.Nullable ->
|
||||
failwith
|
||||
$"We don't support nested nullable types, because we can't tell the difference between None and Some None: %s{SynType.toHumanReadableString ty}"
|
||||
| JsonNodeWithNullability.CannotBeNull ->
|
||||
|
||||
let inner, innerIsJsonNode = serializeNodeNonNullable ty
|
||||
|
||||
SynExpr.applyFunction inner (SynExpr.createLongIdent [ "field" ; "Value" ])
|
||||
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|
||||
|> SynExpr.ifThenElse (SynExpr.createLongIdent [ "field" ; "HasValue" ]) (jsonNull ())
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, innerIsJsonNode
|
||||
| OptionType ty ->
|
||||
// fun field -> match field with | None -> None | Some v -> {serializeNode ty} field |> Some
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| JsonNodeWithNullability.Nullable ->
|
||||
failwith
|
||||
$"We don't support nested nullable types, because we can't tell the difference between None and Some None: %s{SynType.toHumanReadableString ty}"
|
||||
| JsonNodeWithNullability.CannotBeNull ->
|
||||
|
||||
let noneClause = jsonNull () |> SynMatchClause.create (SynPat.named "None")
|
||||
|
||||
let someClause =
|
||||
let inner, innerIsJsonNode = serializeNodeNonNullable ty
|
||||
let target = SynExpr.pipeThroughFunction inner (SynExpr.createIdent "field")
|
||||
|
||||
if innerIsJsonNode then
|
||||
target
|
||||
else
|
||||
target
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|
||||
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "field" ])
|
||||
|
||||
[ noneClause ; someClause ]
|
||||
|> SynExpr.createMatch (SynExpr.createIdent "field")
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, true
|
||||
| _ -> failwith $"Did not recognise type %s{SynType.toHumanReadableString fieldType} as nullable"
|
||||
|
||||
/// Given `input.Ident`, for example, choose how to add it to the ambient `node`.
|
||||
/// The result is a line like `(fun ident -> InnerType.toJsonNode ident)` or `(fun ident -> JsonValue.Create ident)`.
|
||||
/// Returns also a bool which is true if the resulting SynExpr represents something of type JsonNode.
|
||||
let rec serializeNode (fieldType : SynType) : SynExpr * bool =
|
||||
and serializeNodeNonNullable (fieldType : SynType) : SynExpr * bool =
|
||||
// TODO: serialization format for DateTime etc
|
||||
match fieldType with
|
||||
| OptionType _
|
||||
| NullableType _ ->
|
||||
failwith $"Tried to treat the type %s{SynType.toHumanReadableString fieldType} as non-nullable"
|
||||
| DateOnly
|
||||
| DateTime
|
||||
| NumberType _
|
||||
@@ -36,8 +112,21 @@ module internal JsonSerializeGenerator =
|
||||
| Guid
|
||||
| Uri ->
|
||||
// JsonValue.Create<type>
|
||||
SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
|
||||
|> SynExpr.typeApp [ fieldType ]
|
||||
(SynExpr.createIdent "field")
|
||||
|> assertNotNull
|
||||
(Ident.create "field")
|
||||
(SynExpr.CreateConst
|
||||
$"Expected type %s{SynType.toHumanReadableString fieldType} to be non-null, but received a null value when serialising")
|
||||
|> SynExpr.createLet
|
||||
[
|
||||
SynBinding.basic
|
||||
[ Ident.create "field" ]
|
||||
[]
|
||||
(SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
|
||||
|> SynExpr.typeApp [ fieldType ]
|
||||
|> SynExpr.applyTo (SynExpr.createIdent "field"))
|
||||
]
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, false
|
||||
| DateTimeOffset ->
|
||||
// fun field -> field.ToString("o") |> JsonValue.Create<string>
|
||||
@@ -50,41 +139,17 @@ module internal JsonSerializeGenerator =
|
||||
|> SynExpr.pipeThroughFunction create
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, false
|
||||
| NullableType ty ->
|
||||
// fun field -> if field.HasValue then {serializeNode ty} field.Value else JsonValue.Create null
|
||||
let inner, innerIsJsonNode = serializeNode ty
|
||||
|
||||
SynExpr.applyFunction inner (SynExpr.createLongIdent [ "field" ; "Value" ])
|
||||
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|
||||
|> SynExpr.ifThenElse (SynExpr.createLongIdent [ "field" ; "HasValue" ]) (jsonNull ())
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, innerIsJsonNode
|
||||
| OptionType ty ->
|
||||
// fun field -> match field with | None -> JsonValue.Create null | Some v -> {serializeNode ty} field
|
||||
let noneClause = jsonNull () |> SynMatchClause.create (SynPat.named "None")
|
||||
|
||||
let someClause =
|
||||
let inner, innerIsJsonNode = serializeNode ty
|
||||
let target = SynExpr.applyFunction inner (SynExpr.createIdent "field")
|
||||
|
||||
if innerIsJsonNode then
|
||||
target
|
||||
else
|
||||
target
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|
||||
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "field" ])
|
||||
|
||||
[ noneClause ; someClause ]
|
||||
|> SynExpr.createMatch (SynExpr.createIdent "field")
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, true
|
||||
| ArrayType ty
|
||||
| ListType ty ->
|
||||
// fun field ->
|
||||
// let arr = JsonArray ()
|
||||
// for mem in field do arr.Add ({serializeNode} mem)
|
||||
// arr
|
||||
let isNullableChild =
|
||||
match JsonNodeWithNullability.Identify ty with
|
||||
| CannotBeNull -> false
|
||||
| Nullable -> true
|
||||
|
||||
[
|
||||
SynExpr.ForEach (
|
||||
DebugPointAtFor.Yes range0,
|
||||
@@ -95,7 +160,17 @@ module internal JsonSerializeGenerator =
|
||||
SynExpr.createIdent "field",
|
||||
SynExpr.applyFunction
|
||||
(SynExpr.createLongIdent [ "arr" ; "Add" ])
|
||||
(SynExpr.paren (SynExpr.applyFunction (fst (serializeNode ty)) (SynExpr.createIdent "mem"))),
|
||||
(SynExpr.paren (
|
||||
SynExpr.applyFunction
|
||||
(fst (
|
||||
(if isNullableChild then
|
||||
serializeNodeNullable
|
||||
else
|
||||
serializeNodeNonNullable)
|
||||
ty
|
||||
))
|
||||
(SynExpr.createIdent "mem")
|
||||
)),
|
||||
range0
|
||||
)
|
||||
SynExpr.createIdent "arr"
|
||||
@@ -109,15 +184,28 @@ module internal JsonSerializeGenerator =
|
||||
]
|
||||
|> SynExpr.createLambda "field"
|
||||
|> fun e -> e, false
|
||||
| IDictionaryType (_keyType, valueType)
|
||||
| DictionaryType (_keyType, valueType)
|
||||
| IReadOnlyDictionaryType (_keyType, valueType)
|
||||
| MapType (_keyType, valueType) ->
|
||||
| IDictionaryType (keyType, valueType)
|
||||
| DictionaryType (keyType, valueType)
|
||||
| IReadOnlyDictionaryType (keyType, valueType)
|
||||
| MapType (keyType, valueType) ->
|
||||
// fun field ->
|
||||
// let ret = JsonObject ()
|
||||
// for (KeyValue(key, value)) in field do
|
||||
// ret.Add (key.ToString (), {serializeNode} value)
|
||||
// ret
|
||||
let isNullableValueField =
|
||||
match JsonNodeWithNullability.Identify valueType with
|
||||
| CannotBeNull -> false
|
||||
| Nullable -> true
|
||||
|
||||
// TODO: this is a bit dubious, because user-defined types will
|
||||
// by default have non-null ToString
|
||||
let keyTypeHasNonNullToString =
|
||||
match keyType with
|
||||
| String
|
||||
| Uri -> true
|
||||
| _ -> false
|
||||
|
||||
[
|
||||
SynExpr.ForEach (
|
||||
DebugPointAtFor.Yes range0,
|
||||
@@ -130,10 +218,33 @@ module internal JsonSerializeGenerator =
|
||||
(SynExpr.createLongIdent [ "ret" ; "Add" ])
|
||||
(SynExpr.tuple
|
||||
[
|
||||
SynExpr.createLongIdent [ "key" ; "ToString" ]
|
||||
|> SynExpr.applyTo (SynExpr.CreateConst ())
|
||||
SynExpr.applyFunction (fst (serializeNode valueType)) (SynExpr.createIdent "value")
|
||||
]),
|
||||
SynExpr.createIdent "key"
|
||||
|> if keyTypeHasNonNullToString then
|
||||
id
|
||||
else
|
||||
assertNotNull
|
||||
(Ident.create "key")
|
||||
(SynExpr.CreateConst
|
||||
"A map key unexpectedly yielded null when we `ToString`'ed it. Map keys must yield non-null strings on `ToString`.")
|
||||
|
||||
SynExpr.applyFunction
|
||||
(fst (
|
||||
(if isNullableValueField then
|
||||
serializeNodeNullable
|
||||
else
|
||||
serializeNodeNonNullable)
|
||||
valueType
|
||||
))
|
||||
(SynExpr.createIdent "value")
|
||||
])
|
||||
|> SynExpr.createLet
|
||||
[
|
||||
SynBinding.basic
|
||||
[ Ident.create "key" ]
|
||||
[]
|
||||
(SynExpr.createLongIdent [ "key" ; "ToString" ]
|
||||
|> SynExpr.applyTo (SynExpr.CreateConst ()))
|
||||
],
|
||||
range0
|
||||
)
|
||||
SynExpr.createIdent "ret"
|
||||
@@ -166,13 +277,24 @@ module internal JsonSerializeGenerator =
|
||||
/// propertyName is probably a string literal, but it could be a [<Literal>] variable
|
||||
/// `node.Add ({propertyName}, {toJsonNode})`
|
||||
let createSerializeRhsRecord (propertyName : SynExpr) (fieldId : Ident) (fieldType : SynType) : SynExpr =
|
||||
[
|
||||
propertyName
|
||||
SynExpr.pipeThroughFunction
|
||||
(fst (serializeNode fieldType))
|
||||
(SynExpr.createLongIdent' [ Ident.create "input" ; fieldId ])
|
||||
|> SynExpr.paren
|
||||
]
|
||||
let isNullableField =
|
||||
match JsonNodeWithNullability.Identify fieldType with
|
||||
| CannotBeNull -> false
|
||||
| Nullable -> true
|
||||
|
||||
let serialised =
|
||||
if isNullableField then
|
||||
let value =
|
||||
serializeNodeNullable fieldType
|
||||
|> fst
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "toObj" ])
|
||||
|
||||
SynExpr.pipeThroughFunction value (SynExpr.createLongIdent' [ Ident.create "input" ; fieldId ])
|
||||
else
|
||||
let value = serializeNodeNonNullable fieldType |> fst
|
||||
SynExpr.pipeThroughFunction value (SynExpr.createLongIdent' [ Ident.create "input" ; fieldId ])
|
||||
|
||||
[ propertyName ; SynExpr.paren serialised ]
|
||||
|> SynExpr.tuple
|
||||
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "node" ; "Add" ])
|
||||
|
||||
@@ -180,8 +302,7 @@ module internal JsonSerializeGenerator =
|
||||
let propertyNameAttr =
|
||||
attrs
|
||||
|> List.tryFind (fun attr ->
|
||||
(SynLongIdent.toString attr.TypeName)
|
||||
.EndsWith ("JsonPropertyName", StringComparison.Ordinal)
|
||||
(SynLongIdent.toString attr.TypeName).EndsWith ("JsonPropertyName", StringComparison.Ordinal)
|
||||
)
|
||||
|
||||
match propertyNameAttr with
|
||||
@@ -198,8 +319,7 @@ module internal JsonSerializeGenerator =
|
||||
let getIsJsonExtension (attrs : SynAttribute list) : bool =
|
||||
attrs
|
||||
|> List.tryFind (fun attr ->
|
||||
(SynLongIdent.toString attr.TypeName)
|
||||
.EndsWith ("JsonExtensionData", StringComparison.Ordinal)
|
||||
(SynLongIdent.toString attr.TypeName).EndsWith ("JsonExtensionData", StringComparison.Ordinal)
|
||||
)
|
||||
|> Option.isSome
|
||||
|
||||
@@ -280,7 +400,10 @@ module internal JsonSerializeGenerator =
|
||||
| DictionaryType (String, v) -> v
|
||||
| _ -> failwith "Expected JsonExtensionData to be a Dictionary<string, something>"
|
||||
|
||||
let serialise = fst (serializeNode valType)
|
||||
let serialise =
|
||||
match JsonNodeWithNullability.Identify valType with
|
||||
| CannotBeNull -> fst (serializeNodeNonNullable valType)
|
||||
| Nullable -> fst (serializeNodeNullable valType)
|
||||
|
||||
SynExpr.createIdent "node"
|
||||
|> SynExpr.callMethodArg
|
||||
@@ -345,7 +468,15 @@ module internal JsonSerializeGenerator =
|
||||
let propertyName = getPropertyName (Option.get fieldData.Ident) fieldData.Attrs
|
||||
|
||||
let node =
|
||||
SynExpr.applyFunction (fst (serializeNode fieldData.Type)) (SynExpr.createIdent caseName)
|
||||
match JsonNodeWithNullability.Identify fieldData.Type with
|
||||
| CannotBeNull ->
|
||||
SynExpr.applyFunction
|
||||
(fst (serializeNodeNonNullable fieldData.Type))
|
||||
(SynExpr.createIdent caseName)
|
||||
| Nullable ->
|
||||
SynExpr.applyFunction
|
||||
(fst (serializeNodeNullable fieldData.Type))
|
||||
(SynExpr.createIdent caseName)
|
||||
|
||||
[ propertyName ; node ]
|
||||
|> SynExpr.tuple
|
||||
|
504
WoofWare.Myriad.Plugins/OpenApi3.fs
Normal file
504
WoofWare.Myriad.Plugins/OpenApi3.fs
Normal file
@@ -0,0 +1,504 @@
|
||||
module internal WoofWare.Myriad.Plugins.OpenApi3
|
||||
|
||||
open System
|
||||
open System.Text.Json.Nodes
|
||||
|
||||
type ExternalDocumentation =
|
||||
{
|
||||
/// A short description of the target documentation, possibly in CommonMark.
|
||||
Description : string option
|
||||
/// The URL for the target documentation.
|
||||
Url : Uri
|
||||
}
|
||||
|
||||
type Schema = | Schema of unit
|
||||
|
||||
type Example =
|
||||
{
|
||||
/// Short description for the example.
|
||||
Summary : string option
|
||||
/// Long description for the example, possibly CommonMark.
|
||||
Description : string option
|
||||
Value : Choice<JsonNode, Uri> option
|
||||
}
|
||||
|
||||
type Reference =
|
||||
{
|
||||
/// The reference string.
|
||||
Ref : string
|
||||
}
|
||||
|
||||
type Tag =
|
||||
{
|
||||
/// The name of the tag.
|
||||
Name : string
|
||||
/// A short description for the tag, possibly CommonMark.
|
||||
Description : string option
|
||||
/// Additional external documentation for this tag.
|
||||
ExternalDocs : ExternalDocumentation option
|
||||
}
|
||||
|
||||
type ServerVariable =
|
||||
{
|
||||
/// An enumeration of string values to be used if the substitution options are from a limited set.
|
||||
Enum : string list option
|
||||
/// The default value to use for substitution, and to send, if an alternate value is not supplied.
|
||||
/// Unlike the Schema Object’s default, this value MUST be provided by the consumer.
|
||||
Default : string
|
||||
/// An optional description for the server variable, possibly in CommonMark.
|
||||
Description : string option
|
||||
}
|
||||
|
||||
type Server =
|
||||
{
|
||||
/// A URL to the target host.
|
||||
/// This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the OpenAPI document is being served.
|
||||
/// Variable substitutions will be made when a variable is named in {brackets}.
|
||||
Url : Uri
|
||||
/// Describes the host designated by the URL, possibly with CommonMark.
|
||||
Description : string option
|
||||
/// Used for substituting in the Url.
|
||||
Variables : Map<string, ServerVariable> option
|
||||
}
|
||||
|
||||
type StringFormat =
|
||||
/// base64-encoded characters
|
||||
| Byte
|
||||
/// any sequence of octets
|
||||
| Binary
|
||||
/// As defined by full-date - RFC3339 Section 5.6
|
||||
| Date
|
||||
/// As defined by date-time - RFC3339 Section 5.6
|
||||
| DateTime
|
||||
/// A hint to UIs to obscure input
|
||||
| Password
|
||||
| Verbatim of string
|
||||
|
||||
type IntegerFormat =
|
||||
/// Signed 32 bits
|
||||
| Int32
|
||||
/// Signed 64 bits
|
||||
| Int64
|
||||
| Verbatim of string
|
||||
|
||||
type NumberFormat =
|
||||
| Float
|
||||
| Double
|
||||
| Verbatim of string
|
||||
|
||||
type DataFormat =
|
||||
| Integer of IntegerFormat option
|
||||
| Number of NumberFormat option
|
||||
| String of StringFormat option
|
||||
| Boolean of format : string option
|
||||
|
||||
type Contact =
|
||||
{
|
||||
/// The identifying name of the contact person/organization.
|
||||
Name : string option
|
||||
/// The URL pointing to the contact information.
|
||||
Url : Uri option
|
||||
/// This MUST be in email address format.
|
||||
Email : string option
|
||||
}
|
||||
|
||||
type License =
|
||||
{
|
||||
/// The license name used for the API.
|
||||
Name : string
|
||||
/// A URL to the license used for the API.
|
||||
Url : Uri option
|
||||
}
|
||||
|
||||
type OpenApiInfo =
|
||||
{
|
||||
/// Title of the application
|
||||
Title : string
|
||||
/// Short description of the application, might be in CommonMark
|
||||
Description : string option
|
||||
/// Link to the ToS of the application
|
||||
TermsOfService : Uri option
|
||||
/// The contact information for the exposed API.
|
||||
Contact : Contact option
|
||||
/// The license information for the exposed API.
|
||||
License : License option
|
||||
/// The version of the OpenAPI document (which is distinct from the OpenAPI Specification version or the API implementation version).
|
||||
Version : string
|
||||
}
|
||||
|
||||
type Encoding =
|
||||
{
|
||||
/// The Content-Type for encoding a specific property.
|
||||
/// Default value depends on the property type:
|
||||
/// for string with format being binary – application/octet-stream;
|
||||
/// for other primitive types – text/plain;
|
||||
/// for object - application/json;
|
||||
/// for array – the default is defined based on the inner type.
|
||||
/// The value can be a specific media type (e.g. application/json), a wildcard media type (e.g. image/*), or a comma-separated list of the two types.
|
||||
ContentType : string option
|
||||
/// A map allowing additional information to be provided as headers, for example Content-Disposition.
|
||||
/// Content-Type is described separately and SHALL be ignored in this section.
|
||||
/// This property SHALL be ignored if the request body media type is not a multipart.
|
||||
Headers : Map<string, Choice<Header, Reference>> option
|
||||
/// Describes how a specific property value will be serialized depending on its type.
|
||||
/// See Parameter Object for details on the style property.
|
||||
/// The behavior follows the same values as query parameters, including default values.
|
||||
/// This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded.
|
||||
Style : string option
|
||||
/// When this is true, property values of type array or object generate separate parameters for each value of the array, or key-value-pair of the map.
|
||||
/// For other types of properties this property has no effect.
|
||||
/// When style is form, the default value is true.
|
||||
/// For all other styles, the default value is false.
|
||||
/// This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded.
|
||||
Explode : bool option
|
||||
/// Determines whether the parameter value SHOULD allow reserved characters, as defined by [RFC3986] Section 2.2 :/?#[]@!$&'()*+,;=
|
||||
/// to be included without percent-encoding.
|
||||
/// The default value is false.
|
||||
/// This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded.
|
||||
AllowReserved : bool option
|
||||
}
|
||||
|
||||
and MediaType =
|
||||
{
|
||||
/// The schema defining the type used for the request body.
|
||||
Schema : Choice<Schema, Reference> option
|
||||
Example : Choice<JsonNode, Map<string, Choice<Example, Reference>>> option
|
||||
/// A map between a property name and its encoding information.
|
||||
/// The key, being the property name, MUST exist in the schema as a property.
|
||||
/// The encoding object SHALL only apply to requestBody objects when the media type is multipart or application/x-www-form-urlencoded.
|
||||
Encoding : Map<string, Encoding> option
|
||||
}
|
||||
|
||||
/// The Header Object basically follows the structure of the Parameter Object.
|
||||
/// All traits that are affected by the location MUST be applicable to a location of header (for example, style).
|
||||
and Header =
|
||||
{
|
||||
/// A brief description of the header, possibly CommonMark.
|
||||
Description : string option
|
||||
/// Determines whether this header is mandatory.
|
||||
/// If the header location is “path”, this property is REQUIRED and its value MUST be true.
|
||||
/// Otherwise, the property MAY be included and its default value is false.
|
||||
Required : bool option
|
||||
/// Specifies that a header is deprecated and SHOULD be transitioned out of usage.
|
||||
Deprecated : bool option
|
||||
/// Sets the ability to pass empty-valued headers.
|
||||
/// This is valid only for query headers and allows sending a header with an empty value.
|
||||
/// Default value is false.
|
||||
/// If style is used, and if behavior is n/a (cannot be serialized), the value of allowEmptyValue SHALL be ignored.
|
||||
AllowEmptyValue : bool option
|
||||
/// Describes how the header value will be serialized depending on the type of the header value.
|
||||
/// Default values (based on value of in): for query - form; for path - simple; for header - simple; for cookie - form.
|
||||
Style : string option
|
||||
/// When this is true, header values of type array or object generate separate headers for each value of the array or key-value pair of the map.
|
||||
/// For other types of headers this property has no effect.
|
||||
/// When style is form, the default value is true.
|
||||
/// For all other styles, the default value is false.
|
||||
Explode : bool option
|
||||
/// Determines whether the header value SHOULD allow reserved characters, as defined by [RFC3986] Section 2.2 :/?#[]@!$&'()*+,;=
|
||||
/// to be included without percent-encoding.
|
||||
/// This property only applies to headers with an in value of query.
|
||||
/// The default value is false.
|
||||
AllowReserved : bool option
|
||||
/// The schema defining the type used for the header.
|
||||
Schema : Choice<Schema, Reference> option
|
||||
Example : Choice<JsonNode, Map<string, Choice<Example, Reference>>> option
|
||||
/// A map containing the representations for the header.
|
||||
/// The key is the media type and the value describes it.
|
||||
/// The map MUST only contain one entry.
|
||||
Content : Map<string, MediaType> option
|
||||
}
|
||||
|
||||
type LinkOperation =
|
||||
/// A relative or absolute reference to an OAS operation.
|
||||
/// This field is mutually exclusive of the operationId field, and MUST point to an Operation Object.
|
||||
/// Relative operationRef values MAY be used to locate an existing Operation Object in the OpenAPI definition.
|
||||
| Ref of string
|
||||
/// The name of an existing, resolvable OAS operation, as defined with a unique operationId.
|
||||
/// This field is mutually exclusive of the operationRef field.
|
||||
| Id of string
|
||||
|
||||
type RuntimeExpression = | RuntimeExpression of unit
|
||||
|
||||
type Link =
|
||||
{
|
||||
/// A relative or absolute reference to an OAS operation.
|
||||
/// This field is mutually exclusive of the operationId field, and MUST point to an Operation Object. Relative operationRef values MAY be used to locate an existing Operation Object in the OpenAPI definition.
|
||||
Operation : LinkOperation option
|
||||
/// A map representing parameters to pass to an operation as specified with operationId or identified via operationRef.
|
||||
/// The key is the parameter name to be used, whereas the value can be a constant or an expression to be evaluated and passed to the linked operation.
|
||||
/// The parameter name can be qualified using the parameter location [{in}.]{name} for operations that use the same parameter name in different locations (e.g. path.id).
|
||||
Parameters : Map<string, Choice<JsonNode, RuntimeExpression>> option
|
||||
/// A literal value or {expression} to use as a request body when calling the target operation.
|
||||
RequestBody : Choice<JsonNode, RuntimeExpression> option
|
||||
/// A description of the link, possibly CommonMark.
|
||||
Description : string option
|
||||
/// A server object to be used by the target operation.
|
||||
Server : Server option
|
||||
}
|
||||
|
||||
type Response =
|
||||
{
|
||||
/// A short description of the response, possibly CommonMark.
|
||||
Description : string
|
||||
/// Maps a header name to its definition.
|
||||
/// [RFC7230] Page 22 states header names are case insensitive.
|
||||
/// If a response header is defined with the name "Content-Type", it SHALL be ignored.
|
||||
Headers : Map<string, Choice<Header, Reference>> option
|
||||
/// A map containing descriptions of potential response payloads.
|
||||
/// The key is a media type or media type range, see [RFC7231] Appendix D, and the value describes it.
|
||||
/// For responses that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/*
|
||||
Content : Map<string, MediaType> option
|
||||
/// A map of operations links that can be followed from the response.
|
||||
/// The key of the map is a short name for the link, following the naming constraints of the names for Component Objects.
|
||||
Links : Map<string, Choice<Link, Reference>> option
|
||||
}
|
||||
|
||||
type Responses =
|
||||
{
|
||||
/// The documentation of responses other than the ones declared for specific HTTP response codes.
|
||||
/// Use this field to cover undeclared responses.
|
||||
Default : Choice<Response, Reference> option
|
||||
/// Map from HTTP status code to expected response.
|
||||
/// The keys are allowed to be "2XX" for example, hence being strings and not ints.
|
||||
Patterns : Map<string, Choice<Response, Reference>> option
|
||||
}
|
||||
|
||||
type SecuritySchemeIn =
|
||||
| Query
|
||||
| Header
|
||||
| Cookie
|
||||
|
||||
type OauthFlow =
|
||||
{
|
||||
/// The authorization URL to be used for this flow.
|
||||
AuthorizationUrl : Uri
|
||||
/// The token URL to be used for this flow.
|
||||
TokenUrl : Uri
|
||||
/// The URL to be used for obtaining refresh tokens.
|
||||
RefreshUrl : Uri option
|
||||
/// The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it.
|
||||
Scopes : Map<string, string>
|
||||
}
|
||||
|
||||
type SecurityRequirement =
|
||||
{
|
||||
/// Each name MUST correspond to a security scheme which is declared in the Security Schemes under the Components Object.
|
||||
/// If the security scheme is of type "oauth2" or "openIdConnect", then the value is a list of scope names required for the execution.
|
||||
/// For other security scheme types, the array MUST be empty.
|
||||
Fields : Map<string, string list> option
|
||||
}
|
||||
|
||||
type OauthFlows =
|
||||
{
|
||||
/// Configuration for the OAuth Implicit flow
|
||||
Implicit : OauthFlow
|
||||
/// Configuration for the OAuth Resource Owner Password flow
|
||||
Password : OauthFlow
|
||||
/// Configuration for the OAuth Client Credentials flow.
|
||||
ClientCredentials : OauthFlow
|
||||
/// Configuration for the OAuth Authorization Code flow.
|
||||
AuthorizationCode : OauthFlow
|
||||
}
|
||||
|
||||
type SecurityScheme =
|
||||
| ApiKey of description : string option * name : string * inValue : SecuritySchemeIn
|
||||
| Http of description : string option * scheme : string * bearerFormat : string option
|
||||
| Oauth2 of description : string option * OauthFlows
|
||||
| OpenIdConnect of description : string option * url : Uri
|
||||
|
||||
type ParameterIn =
|
||||
/// Used together with Path Templating, where the parameter value is actually part of the operation’s URL.
|
||||
/// This does not include the host or base path of the API.
|
||||
/// For example, in /items/{itemId}, the path parameter is itemId.
|
||||
| Path
|
||||
/// Custom headers that are expected as part of the request.
|
||||
/// Note that [RFC7230] Page 22 states header names are case insensitive.
|
||||
| Header
|
||||
/// Parameters that are appended to the URL. For example, in /items?id=###, the query parameter is id.
|
||||
| Query
|
||||
/// Used to pass a specific cookie value to the API.
|
||||
| Cookie
|
||||
|
||||
/// A unique parameter is defined by a combination of a name and location.
|
||||
type Parameter =
|
||||
{
|
||||
/// Name of the parameter, case sensitive.
|
||||
/// If in is "path", the name field MUST correspond to the associated path segment from the path field in the Paths Object.
|
||||
/// See Path Templating for further information.
|
||||
/// If in is "header" and the name field is "Accept", "Content-Type" or "Authorization", the parameter definition SHALL be ignored.
|
||||
/// For all other cases, the name corresponds to the parameter name used by the in property.
|
||||
Name : string
|
||||
/// The location of the parameter.
|
||||
In : ParameterIn
|
||||
/// A brief description of the parameter, possibly CommonMark.
|
||||
Description : string option
|
||||
/// Determines whether this parameter is mandatory.
|
||||
/// If the parameter location is “path”, this property is REQUIRED and its value MUST be true.
|
||||
/// Otherwise, the property MAY be included and its default value is false.
|
||||
Required : bool option
|
||||
/// Specifies that a parameter is deprecated and SHOULD be transitioned out of usage.
|
||||
Deprecated : bool option
|
||||
/// Sets the ability to pass empty-valued parameters.
|
||||
/// This is valid only for query parameters and allows sending a parameter with an empty value.
|
||||
/// Default value is false.
|
||||
/// If style is used, and if behavior is n/a (cannot be serialized), the value of allowEmptyValue SHALL be ignored.
|
||||
AllowEmptyValue : bool option
|
||||
/// Describes how the parameter value will be serialized depending on the type of the parameter value.
|
||||
/// Default values (based on value of in): for query - form; for path - simple; for header - simple; for cookie - form.
|
||||
Style : string option
|
||||
/// When this is true, parameter values of type array or object generate separate parameters for each value of the array or key-value pair of the map.
|
||||
/// For other types of parameters this property has no effect.
|
||||
/// When style is form, the default value is true.
|
||||
/// For all other styles, the default value is false.
|
||||
Explode : bool option
|
||||
/// Determines whether the parameter value SHOULD allow reserved characters, as defined by [RFC3986] Section 2.2 :/?#[]@!$&'()*+,;=
|
||||
/// to be included without percent-encoding.
|
||||
/// This property only applies to parameters with an in value of query.
|
||||
/// The default value is false.
|
||||
AllowReserved : bool option
|
||||
/// The schema defining the type used for the parameter.
|
||||
Schema : Choice<Schema, Reference> option
|
||||
Example : Choice<JsonNode, Map<string, Choice<Example, Reference>>> option
|
||||
/// A map containing the representations for the parameter.
|
||||
/// The key is the media type and the value describes it.
|
||||
/// The map MUST only contain one entry.
|
||||
Content : Map<string, MediaType> option
|
||||
}
|
||||
|
||||
type RequestBody =
|
||||
{
|
||||
/// A brief description of the request body. This could contain examples of use.
|
||||
/// Possibly CommonMark.
|
||||
Description : string option
|
||||
/// The content of the request body.
|
||||
/// The key is a media type or media type range, see [RFC7231] Appendix D, and the value describes it.
|
||||
/// For requests that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/*
|
||||
Content : Map<string, MediaType>
|
||||
/// Determines if the request body is required in the request. Defaults to false.
|
||||
Required : bool option
|
||||
}
|
||||
|
||||
type Callback =
|
||||
{
|
||||
/// For the semantics of the keys, see https://spec.openapis.org/oas/v3.0.0#key-expression
|
||||
Patterns : Map<string, PathItem> option
|
||||
}
|
||||
|
||||
and Operation =
|
||||
{
|
||||
/// A list of tags for API documentation control.
|
||||
/// Tags can be used for logical grouping of operations by resources or any other qualifier.
|
||||
Tags : string list option
|
||||
/// A short summary of what the operation does.
|
||||
Summary : string option
|
||||
/// A verbose explanation of the operation behavior, possibly in CommonMark.
|
||||
Description : string option
|
||||
/// Additional external documentation for this operation.
|
||||
ExternalDocs : ExternalDocumentation
|
||||
/// Unique string used to identify the operation.
|
||||
/// The id MUST be unique among all operations described in the API.
|
||||
/// Tools and libraries MAY use the operationId to uniquely identify an operation, therefore,
|
||||
/// it is RECOMMENDED to follow common programming naming conventions.
|
||||
OperationId : string option
|
||||
/// A list of parameters that are applicable for this operation.
|
||||
/// If a parameter is already defined at the Path Item, the new definition will override it but can never remove it.
|
||||
/// The list MUST NOT include duplicated parameters.
|
||||
/// A unique parameter is defined by a combination of a name and location.
|
||||
/// The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object’s components/parameters.
|
||||
Parameters : Choice<Parameter, Reference> list option
|
||||
/// The request body applicable for this operation.
|
||||
/// The requestBody is only supported in HTTP methods where the HTTP 1.1 specification [RFC7231] Section 4.3.1 has explicitly defined semantics for request bodies.
|
||||
/// In other cases where the HTTP spec is vague, requestBody SHALL be ignored by consumers.
|
||||
RequestBody : Choice<RequestBody, Reference> option
|
||||
/// The list of possible responses as they are returned from executing this operation.
|
||||
Responses : Responses
|
||||
/// A map of possible out-of band callbacks related to the parent operation.
|
||||
/// The key is a unique identifier for the Callback Object.
|
||||
/// Each value in the map is a Callback Object that describes a request that may be initiated by the API provider and the expected responses.
|
||||
/// The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.
|
||||
Callbacks : Map<string, Choice<Callback, Reference>> option
|
||||
/// Default value is "false".
|
||||
Deprecated : bool option
|
||||
/// A declaration of which security mechanisms can be used for this operation.
|
||||
/// The list of values includes alternative security requirement objects that can be used.
|
||||
/// Only one of the security requirement objects need to be satisfied to authorize a request.
|
||||
/// This definition overrides any declared top-level security.
|
||||
/// To remove a top-level security declaration, an empty array can be used.
|
||||
Security : SecurityRequirement list option
|
||||
/// An alternative server array to service this operation.
|
||||
/// If an alternative server object is specified at the Path Item Object or Root level, it will be overridden by this value.
|
||||
Servers : Server list option
|
||||
}
|
||||
|
||||
and PathItem =
|
||||
{
|
||||
/// Allows for an external definition of this path item.
|
||||
/// The referenced structure MUST be in the format of a Path Item Object.
|
||||
/// If there are conflicts between the referenced definition and this Path Item’s definition, the behavior is undefined.
|
||||
Ref : string option
|
||||
/// A string summary, intended to apply to all operations in this path.
|
||||
Summary : string option
|
||||
/// A string description, intended to apply to all operations in this path, possibly in CommonMark
|
||||
Description : string option
|
||||
/// A definition of a GET operation on this path.
|
||||
Get : Operation option
|
||||
/// A definition of a PUT operation on this path.
|
||||
Put : Operation option
|
||||
/// A definition of a POST operation on this path.
|
||||
Post : Operation option
|
||||
/// A definition of a DELETE operation on this path.
|
||||
Delete : Operation option
|
||||
/// A definition of an OPTIONS operation on this path.
|
||||
Options : Operation option
|
||||
/// A definition of a HEAD operation on this path.
|
||||
Head : Operation option
|
||||
/// A definition of a PATCH operation on this path.
|
||||
Patch : Operation option
|
||||
/// A definition of a TRACE operation on this path.
|
||||
Trace : Operation option
|
||||
/// An alternative server array to service all operations in this path.
|
||||
Servers : Server list option
|
||||
/// A list of parameters that are applicable for all the operations described under this path.
|
||||
/// These parameters can be overridden at the operation level, but cannot be removed there.
|
||||
/// The list MUST NOT include duplicated parameters.
|
||||
/// A unique parameter is defined by a combination of a name and location.
|
||||
/// The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object’s components/parameters.
|
||||
Parameters : Choice<Parameter, Reference> list option
|
||||
}
|
||||
|
||||
type Paths =
|
||||
{
|
||||
/// A relative path to an individual endpoint.
|
||||
/// The field name MUST begin with a slash.
|
||||
/// The path is appended (no relative URL resolution) to the expanded URL from the Server Object’s url field in order to construct the full URL.
|
||||
/// Path templating is allowed.
|
||||
/// When matching URLs, concrete (non-templated) paths would be matched before their templated counterparts.
|
||||
/// Templated paths with the same hierarchy but different templated names MUST NOT exist as they are identical.
|
||||
/// In case of ambiguous matching, it’s up to the tooling to decide which one to use.
|
||||
Fields : Map<string, PathItem> option
|
||||
}
|
||||
|
||||
type Components =
|
||||
{
|
||||
Schemas : Map<string, Choice<Schema, Reference>>
|
||||
Responses : Map<string, Choice<Response, Reference>>
|
||||
Parameters : Map<string, Choice<Parameter, Reference>>
|
||||
Examples : Map<string, Choice<Example, Reference>>
|
||||
RequestBodies : Map<string, Choice<RequestBody, Reference>>
|
||||
Headers : Map<string, Choice<Header, Reference>>
|
||||
SecuritySchemes : Map<string, Choice<SecurityScheme, Reference>>
|
||||
Links : Map<string, Choice<Link, Reference>>
|
||||
Callbacks : Map<string, Choice<Callback, Reference>>
|
||||
}
|
||||
|
||||
type OpenApiSpec =
|
||||
{
|
||||
OpenApi : Version
|
||||
Info : OpenApiInfo
|
||||
Servers : Server list option
|
||||
Paths : Paths
|
||||
Components : Components option
|
||||
Security : SecurityRequirement list option
|
||||
Tags : Tag list option
|
||||
ExternalDocs : ExternalDocumentation option
|
||||
}
|
@@ -97,7 +97,7 @@ module internal RemoveOptionsGenerator =
|
||||
|
||||
SynLongIdent.createI fieldData.Ident, body
|
||||
)
|
||||
|> AstHelper.instantiateRecord
|
||||
|> SynExpr.createRecord None
|
||||
|
||||
SynBinding.basic
|
||||
[ functionName ]
|
||||
|
@@ -1,84 +1,7 @@
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties inherit obj, implements WoofWare.Myriad.Plugins.AdditionalProperties System.IEquatable, System.Collections.IStructuralEquatable - union type with 2 cases
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties+Constrained inherit WoofWare.Myriad.Plugins.AdditionalProperties
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties+Constrained.get_Item [method]: unit -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties+Constrained.Item [property]: [read-only] WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties+Tags inherit obj
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties+Tags.Constrained [static field]: int = 1
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties+Tags.Never [static field]: int = 0
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties.Equals [method]: (WoofWare.Myriad.Plugins.AdditionalProperties, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties.get_IsConstrained [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties.get_IsNever [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties.get_Never [static method]: unit -> WoofWare.Myriad.Plugins.AdditionalProperties
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties.get_Tag [method]: unit -> int
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties.IsConstrained [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties.IsNever [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties.Never [static property]: [read-only] WoofWare.Myriad.Plugins.AdditionalProperties
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties.NewConstrained [static method]: WoofWare.Myriad.Plugins.Definition -> WoofWare.Myriad.Plugins.AdditionalProperties
|
||||
WoofWare.Myriad.Plugins.AdditionalProperties.Tag [property]: [read-only] int
|
||||
WoofWare.Myriad.Plugins.ArgParserGenerator inherit obj, implements Myriad.Core.IMyriadGenerator
|
||||
WoofWare.Myriad.Plugins.ArgParserGenerator..ctor [constructor]: unit
|
||||
WoofWare.Myriad.Plugins.ArrayTypeDefinition inherit obj, implements WoofWare.Myriad.Plugins.ArrayTypeDefinition System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.Myriad.Plugins.ArrayTypeDefinition..ctor [constructor]: WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.ArrayTypeDefinition.Equals [method]: (WoofWare.Myriad.Plugins.ArrayTypeDefinition, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.ArrayTypeDefinition.get_Items [method]: unit -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.ArrayTypeDefinition.Items [property]: [read-only] WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.ArrayTypeDefinition.Parse [static method]: System.Text.Json.Nodes.JsonNode -> WoofWare.Myriad.Plugins.ArrayTypeDefinition
|
||||
WoofWare.Myriad.Plugins.CreateCatamorphismGenerator inherit obj, implements Myriad.Core.IMyriadGenerator
|
||||
WoofWare.Myriad.Plugins.CreateCatamorphismGenerator..ctor [constructor]: unit
|
||||
WoofWare.Myriad.Plugins.Definition inherit obj, implements WoofWare.Myriad.Plugins.Definition System.IEquatable, System.Collections.IStructuralEquatable - union type with 8 cases
|
||||
WoofWare.Myriad.Plugins.Definition+Array inherit WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition+Array.get_Item [method]: unit -> WoofWare.Myriad.Plugins.ArrayTypeDefinition
|
||||
WoofWare.Myriad.Plugins.Definition+Array.Item [property]: [read-only] WoofWare.Myriad.Plugins.ArrayTypeDefinition
|
||||
WoofWare.Myriad.Plugins.Definition+Handle inherit WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition+Handle.get_Item [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.Definition+Handle.Item [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.Definition+Integer inherit WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition+Integer.format [property]: [read-only] string option
|
||||
WoofWare.Myriad.Plugins.Definition+Integer.get_format [method]: unit -> string option
|
||||
WoofWare.Myriad.Plugins.Definition+Object inherit WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition+Object.get_Item [method]: unit -> WoofWare.Myriad.Plugins.ObjectTypeDefinition
|
||||
WoofWare.Myriad.Plugins.Definition+Object.Item [property]: [read-only] WoofWare.Myriad.Plugins.ObjectTypeDefinition
|
||||
WoofWare.Myriad.Plugins.Definition+Tags inherit obj
|
||||
WoofWare.Myriad.Plugins.Definition+Tags.Array [static field]: int = 2
|
||||
WoofWare.Myriad.Plugins.Definition+Tags.Boolean [static field]: int = 4
|
||||
WoofWare.Myriad.Plugins.Definition+Tags.File [static field]: int = 7
|
||||
WoofWare.Myriad.Plugins.Definition+Tags.Handle [static field]: int = 0
|
||||
WoofWare.Myriad.Plugins.Definition+Tags.Integer [static field]: int = 6
|
||||
WoofWare.Myriad.Plugins.Definition+Tags.Object [static field]: int = 1
|
||||
WoofWare.Myriad.Plugins.Definition+Tags.String [static field]: int = 3
|
||||
WoofWare.Myriad.Plugins.Definition+Tags.Unspecified [static field]: int = 5
|
||||
WoofWare.Myriad.Plugins.Definition.Boolean [static property]: [read-only] WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.Equals [method]: (WoofWare.Myriad.Plugins.Definition, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.Definition.File [static property]: [read-only] WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.get_Boolean [static method]: unit -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.get_File [static method]: unit -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.get_IsArray [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.Definition.get_IsBoolean [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.Definition.get_IsFile [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.Definition.get_IsHandle [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.Definition.get_IsInteger [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.Definition.get_IsObject [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.Definition.get_IsString [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.Definition.get_IsUnspecified [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.Definition.get_String [static method]: unit -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.get_Tag [method]: unit -> int
|
||||
WoofWare.Myriad.Plugins.Definition.get_Unspecified [static method]: unit -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.IsArray [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.Definition.IsBoolean [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.Definition.IsFile [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.Definition.IsHandle [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.Definition.IsInteger [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.Definition.IsObject [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.Definition.IsString [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.Definition.IsUnspecified [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.Definition.NewArray [static method]: WoofWare.Myriad.Plugins.ArrayTypeDefinition -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.NewHandle [static method]: string -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.NewInteger [static method]: string option -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.NewObject [static method]: WoofWare.Myriad.Plugins.ObjectTypeDefinition -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.Parse [static method]: System.Text.Json.Nodes.JsonObject -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.String [static property]: [read-only] WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Definition.Tag [property]: [read-only] int
|
||||
WoofWare.Myriad.Plugins.Definition.Unspecified [static property]: [read-only] WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.HttpClientGenerator inherit obj, implements Myriad.Core.IMyriadGenerator
|
||||
WoofWare.Myriad.Plugins.HttpClientGenerator..ctor [constructor]: unit
|
||||
WoofWare.Myriad.Plugins.HttpMethod inherit obj, implements WoofWare.Myriad.Plugins.HttpMethod System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.Myriad.Plugins.HttpMethod System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 8 cases
|
||||
@@ -134,162 +57,7 @@ WoofWare.Myriad.Plugins.JsonParseGenerator inherit obj, implements Myriad.Core.I
|
||||
WoofWare.Myriad.Plugins.JsonParseGenerator..ctor [constructor]: unit
|
||||
WoofWare.Myriad.Plugins.JsonSerializeGenerator inherit obj, implements Myriad.Core.IMyriadGenerator
|
||||
WoofWare.Myriad.Plugins.JsonSerializeGenerator..ctor [constructor]: unit
|
||||
WoofWare.Myriad.Plugins.MimeType inherit obj, implements WoofWare.Myriad.Plugins.MimeType System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.Myriad.Plugins.MimeType System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 1 cases
|
||||
WoofWare.Myriad.Plugins.MimeType.Equals [method]: (WoofWare.Myriad.Plugins.MimeType, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.MimeType.get_Item [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.MimeType.get_Tag [method]: unit -> int
|
||||
WoofWare.Myriad.Plugins.MimeType.Item [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.MimeType.NewMimeType [static method]: string -> WoofWare.Myriad.Plugins.MimeType
|
||||
WoofWare.Myriad.Plugins.MimeType.Tag [property]: [read-only] int
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition inherit obj, implements WoofWare.Myriad.Plugins.ObjectTypeDefinition System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition..ctor [constructor]: (string option, Map<string, WoofWare.Myriad.Plugins.Definition> option, Map<string, System.Text.Json.Nodes.JsonNode>, string list option, WoofWare.Myriad.Plugins.AdditionalProperties option, System.Text.Json.Nodes.JsonObject option)
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.AdditionalProperties [property]: [read-only] WoofWare.Myriad.Plugins.AdditionalProperties option
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.Description [property]: [read-only] string option
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.Equals [method]: (WoofWare.Myriad.Plugins.ObjectTypeDefinition, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.Example [property]: [read-only] System.Text.Json.Nodes.JsonObject option
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.Extras [property]: [read-only] Map<string, System.Text.Json.Nodes.JsonNode>
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.get_AdditionalProperties [method]: unit -> WoofWare.Myriad.Plugins.AdditionalProperties option
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.get_Description [method]: unit -> string option
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.get_Example [method]: unit -> System.Text.Json.Nodes.JsonObject option
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.get_Extras [method]: unit -> Map<string, System.Text.Json.Nodes.JsonNode>
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.get_Properties [method]: unit -> Map<string, WoofWare.Myriad.Plugins.Definition> option
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.get_Required [method]: unit -> string list option
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.Parse [static method]: System.Text.Json.Nodes.JsonObject -> WoofWare.Myriad.Plugins.ObjectTypeDefinition
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.Properties [property]: [read-only] Map<string, WoofWare.Myriad.Plugins.Definition> option
|
||||
WoofWare.Myriad.Plugins.ObjectTypeDefinition.Required [property]: [read-only] string list option
|
||||
WoofWare.Myriad.Plugins.OperationId inherit obj, implements WoofWare.Myriad.Plugins.OperationId System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.Myriad.Plugins.OperationId System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 1 cases
|
||||
WoofWare.Myriad.Plugins.OperationId.Equals [method]: (WoofWare.Myriad.Plugins.OperationId, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.OperationId.get_Item [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.OperationId.get_Tag [method]: unit -> int
|
||||
WoofWare.Myriad.Plugins.OperationId.Item [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.OperationId.NewOperationId [static method]: string -> WoofWare.Myriad.Plugins.OperationId
|
||||
WoofWare.Myriad.Plugins.OperationId.Tag [property]: [read-only] int
|
||||
WoofWare.Myriad.Plugins.ParameterIn inherit obj, implements WoofWare.Myriad.Plugins.ParameterIn System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.Myriad.Plugins.ParameterIn System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 4 cases
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Path inherit WoofWare.Myriad.Plugins.ParameterIn
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Path.get_name [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Path.name [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Query inherit WoofWare.Myriad.Plugins.ParameterIn
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Query.get_name [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Query.name [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Tags inherit obj
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Tags.Body [static field]: int = 2
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Tags.Path [static field]: int = 0
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Tags.Query [static field]: int = 1
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Tags.Unrecognised [static field]: int = 3
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Unrecognised inherit WoofWare.Myriad.Plugins.ParameterIn
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Unrecognised.get_name [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Unrecognised.get_op [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Unrecognised.name [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.ParameterIn+Unrecognised.op [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.ParameterIn.Body [static property]: [read-only] WoofWare.Myriad.Plugins.ParameterIn
|
||||
WoofWare.Myriad.Plugins.ParameterIn.Equals [method]: (WoofWare.Myriad.Plugins.ParameterIn, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.ParameterIn.get_Body [static method]: unit -> WoofWare.Myriad.Plugins.ParameterIn
|
||||
WoofWare.Myriad.Plugins.ParameterIn.get_IsBody [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.ParameterIn.get_IsPath [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.ParameterIn.get_IsQuery [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.ParameterIn.get_IsUnrecognised [method]: unit -> bool
|
||||
WoofWare.Myriad.Plugins.ParameterIn.get_Tag [method]: unit -> int
|
||||
WoofWare.Myriad.Plugins.ParameterIn.IsBody [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.ParameterIn.IsPath [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.ParameterIn.IsQuery [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.ParameterIn.IsUnrecognised [property]: [read-only] bool
|
||||
WoofWare.Myriad.Plugins.ParameterIn.NewPath [static method]: string -> WoofWare.Myriad.Plugins.ParameterIn
|
||||
WoofWare.Myriad.Plugins.ParameterIn.NewQuery [static method]: string -> WoofWare.Myriad.Plugins.ParameterIn
|
||||
WoofWare.Myriad.Plugins.ParameterIn.NewUnrecognised [static method]: (string, string) -> WoofWare.Myriad.Plugins.ParameterIn
|
||||
WoofWare.Myriad.Plugins.ParameterIn.Tag [property]: [read-only] int
|
||||
WoofWare.Myriad.Plugins.RemoveOptionsGenerator inherit obj, implements Myriad.Core.IMyriadGenerator
|
||||
WoofWare.Myriad.Plugins.RemoveOptionsGenerator..ctor [constructor]: unit
|
||||
WoofWare.Myriad.Plugins.Response inherit obj, implements WoofWare.Myriad.Plugins.Response System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.Myriad.Plugins.Response..ctor [constructor]: (string, WoofWare.Myriad.Plugins.Definition)
|
||||
WoofWare.Myriad.Plugins.Response.Description [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.Response.Equals [method]: (WoofWare.Myriad.Plugins.Response, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.Response.get_Description [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.Response.get_Schema [method]: unit -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Response.Parse [static method]: System.Text.Json.Nodes.JsonObject -> WoofWare.Myriad.Plugins.Response
|
||||
WoofWare.Myriad.Plugins.Response.Schema [property]: [read-only] WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.Scheme inherit obj, implements WoofWare.Myriad.Plugins.Scheme System.IEquatable, System.Collections.IStructuralEquatable, WoofWare.Myriad.Plugins.Scheme System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 1 cases
|
||||
WoofWare.Myriad.Plugins.Scheme.Equals [method]: (WoofWare.Myriad.Plugins.Scheme, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.Scheme.get_Item [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.Scheme.get_Tag [method]: unit -> int
|
||||
WoofWare.Myriad.Plugins.Scheme.Item [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.Scheme.NewScheme [static method]: string -> WoofWare.Myriad.Plugins.Scheme
|
||||
WoofWare.Myriad.Plugins.Scheme.Tag [property]: [read-only] int
|
||||
WoofWare.Myriad.Plugins.Swagger inherit obj, implements WoofWare.Myriad.Plugins.Swagger System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.Myriad.Plugins.Swagger..ctor [constructor]: (WoofWare.Myriad.Plugins.MimeType list, WoofWare.Myriad.Plugins.MimeType list, WoofWare.Myriad.Plugins.Scheme list, System.Version, WoofWare.Myriad.Plugins.SwaggerInfo, string, Map<string, Map<WoofWare.Myriad.Plugins.HttpMethod, WoofWare.Myriad.Plugins.SwaggerEndpoint>>, Map<string, WoofWare.Myriad.Plugins.Definition>, Map<string, WoofWare.Myriad.Plugins.Response>)
|
||||
WoofWare.Myriad.Plugins.Swagger.BasePath [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.Swagger.Consumes [property]: [read-only] WoofWare.Myriad.Plugins.MimeType list
|
||||
WoofWare.Myriad.Plugins.Swagger.Definitions [property]: [read-only] Map<string, WoofWare.Myriad.Plugins.Definition>
|
||||
WoofWare.Myriad.Plugins.Swagger.Equals [method]: (WoofWare.Myriad.Plugins.Swagger, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.Swagger.get_BasePath [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.Swagger.get_Consumes [method]: unit -> WoofWare.Myriad.Plugins.MimeType list
|
||||
WoofWare.Myriad.Plugins.Swagger.get_Definitions [method]: unit -> Map<string, WoofWare.Myriad.Plugins.Definition>
|
||||
WoofWare.Myriad.Plugins.Swagger.get_Info [method]: unit -> WoofWare.Myriad.Plugins.SwaggerInfo
|
||||
WoofWare.Myriad.Plugins.Swagger.get_Paths [method]: unit -> Map<string, Map<WoofWare.Myriad.Plugins.HttpMethod, WoofWare.Myriad.Plugins.SwaggerEndpoint>>
|
||||
WoofWare.Myriad.Plugins.Swagger.get_Produces [method]: unit -> WoofWare.Myriad.Plugins.MimeType list
|
||||
WoofWare.Myriad.Plugins.Swagger.get_Responses [method]: unit -> Map<string, WoofWare.Myriad.Plugins.Response>
|
||||
WoofWare.Myriad.Plugins.Swagger.get_Schemes [method]: unit -> WoofWare.Myriad.Plugins.Scheme list
|
||||
WoofWare.Myriad.Plugins.Swagger.get_Swagger [method]: unit -> System.Version
|
||||
WoofWare.Myriad.Plugins.Swagger.Info [property]: [read-only] WoofWare.Myriad.Plugins.SwaggerInfo
|
||||
WoofWare.Myriad.Plugins.Swagger.Paths [property]: [read-only] Map<string, Map<WoofWare.Myriad.Plugins.HttpMethod, WoofWare.Myriad.Plugins.SwaggerEndpoint>>
|
||||
WoofWare.Myriad.Plugins.Swagger.Produces [property]: [read-only] WoofWare.Myriad.Plugins.MimeType list
|
||||
WoofWare.Myriad.Plugins.Swagger.Responses [property]: [read-only] Map<string, WoofWare.Myriad.Plugins.Response>
|
||||
WoofWare.Myriad.Plugins.Swagger.Schemes [property]: [read-only] WoofWare.Myriad.Plugins.Scheme list
|
||||
WoofWare.Myriad.Plugins.Swagger.Swagger [property]: [read-only] System.Version
|
||||
WoofWare.Myriad.Plugins.SwaggerClientGenerator inherit obj, implements Myriad.Core.IMyriadGenerator
|
||||
WoofWare.Myriad.Plugins.SwaggerClientGenerator..ctor [constructor]: unit
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint inherit obj, implements WoofWare.Myriad.Plugins.SwaggerEndpoint System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint..ctor [constructor]: (WoofWare.Myriad.Plugins.MimeType list option, WoofWare.Myriad.Plugins.MimeType list option, string list, string, WoofWare.Myriad.Plugins.OperationId, WoofWare.Myriad.Plugins.SwaggerParameter list option, Map<int, WoofWare.Myriad.Plugins.Definition>)
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.Consumes [property]: [read-only] WoofWare.Myriad.Plugins.MimeType list option
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.Equals [method]: (WoofWare.Myriad.Plugins.SwaggerEndpoint, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.get_Consumes [method]: unit -> WoofWare.Myriad.Plugins.MimeType list option
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.get_OperationId [method]: unit -> WoofWare.Myriad.Plugins.OperationId
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.get_Parameters [method]: unit -> WoofWare.Myriad.Plugins.SwaggerParameter list option
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.get_Produces [method]: unit -> WoofWare.Myriad.Plugins.MimeType list option
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.get_Responses [method]: unit -> Map<int, WoofWare.Myriad.Plugins.Definition>
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.get_Summary [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.get_Tags [method]: unit -> string list
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.OperationId [property]: [read-only] WoofWare.Myriad.Plugins.OperationId
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.Parameters [property]: [read-only] WoofWare.Myriad.Plugins.SwaggerParameter list option
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.Parse [static method]: System.Text.Json.Nodes.JsonObject -> WoofWare.Myriad.Plugins.SwaggerEndpoint
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.Produces [property]: [read-only] WoofWare.Myriad.Plugins.MimeType list option
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.Responses [property]: [read-only] Map<int, WoofWare.Myriad.Plugins.Definition>
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.Summary [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.SwaggerEndpoint.Tags [property]: [read-only] string list
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo inherit obj, implements WoofWare.Myriad.Plugins.SwaggerInfo System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo..ctor [constructor]: (string, string, WoofWare.Myriad.Plugins.SwaggerLicense, System.Version)
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo.Description [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo.Equals [method]: (WoofWare.Myriad.Plugins.SwaggerInfo, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo.get_Description [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo.get_License [method]: unit -> WoofWare.Myriad.Plugins.SwaggerLicense
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo.get_Title [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo.get_Version [method]: unit -> System.Version
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo.License [property]: [read-only] WoofWare.Myriad.Plugins.SwaggerLicense
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo.Parse [static method]: System.Text.Json.Nodes.JsonObject -> WoofWare.Myriad.Plugins.SwaggerInfo
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo.Title [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.SwaggerInfo.Version [property]: [read-only] System.Version
|
||||
WoofWare.Myriad.Plugins.SwaggerLicense inherit obj, implements WoofWare.Myriad.Plugins.SwaggerLicense System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.Myriad.Plugins.SwaggerLicense..ctor [constructor]: (string, System.Uri option, string option)
|
||||
WoofWare.Myriad.Plugins.SwaggerLicense.Equals [method]: (WoofWare.Myriad.Plugins.SwaggerLicense, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.SwaggerLicense.get_Identifier [method]: unit -> string option
|
||||
WoofWare.Myriad.Plugins.SwaggerLicense.get_Name [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.SwaggerLicense.get_Url [method]: unit -> System.Uri option
|
||||
WoofWare.Myriad.Plugins.SwaggerLicense.Identifier [property]: [read-only] string option
|
||||
WoofWare.Myriad.Plugins.SwaggerLicense.Name [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.SwaggerLicense.Parse [static method]: System.Text.Json.Nodes.JsonObject -> WoofWare.Myriad.Plugins.SwaggerLicense
|
||||
WoofWare.Myriad.Plugins.SwaggerLicense.Url [property]: [read-only] System.Uri option
|
||||
WoofWare.Myriad.Plugins.SwaggerModule inherit obj
|
||||
WoofWare.Myriad.Plugins.SwaggerModule.parse [static method]: string -> WoofWare.Myriad.Plugins.Swagger
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter inherit obj, implements WoofWare.Myriad.Plugins.SwaggerParameter System.IEquatable, System.Collections.IStructuralEquatable
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter..ctor [constructor]: (WoofWare.Myriad.Plugins.Definition, string option, WoofWare.Myriad.Plugins.ParameterIn, string, bool option)
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.Description [property]: [read-only] string option
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.Equals [method]: (WoofWare.Myriad.Plugins.SwaggerParameter, System.Collections.IEqualityComparer) -> bool
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.get_Description [method]: unit -> string option
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.get_In [method]: unit -> WoofWare.Myriad.Plugins.ParameterIn
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.get_Name [method]: unit -> string
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.get_Required [method]: unit -> bool option
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.get_Type [method]: unit -> WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.In [property]: [read-only] WoofWare.Myriad.Plugins.ParameterIn
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.Name [property]: [read-only] string
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.Parse [static method]: System.Text.Json.Nodes.JsonObject -> WoofWare.Myriad.Plugins.SwaggerParameter
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.Required [property]: [read-only] bool option
|
||||
WoofWare.Myriad.Plugins.SwaggerParameter.Type [property]: [read-only] WoofWare.Myriad.Plugins.Definition
|
||||
WoofWare.Myriad.Plugins.SwaggerClientGenerator..ctor [constructor]: unit
|
@@ -1,7 +1,6 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open System.Collections.Generic
|
||||
open System.IO
|
||||
open System.Threading
|
||||
open Fantomas.FCS.Syntax
|
||||
open Fantomas.FCS.Xml
|
||||
@@ -19,15 +18,16 @@ type internal SwaggerClientConfig =
|
||||
type internal Produces =
|
||||
// TODO: this will cope with decoding JSON, plain text, etc
|
||||
| Produces of string
|
||||
| OctetStream
|
||||
|
||||
type internal Endpoint =
|
||||
{
|
||||
DocString : PreXmlDoc
|
||||
Produces : Produces
|
||||
ReturnType : Definition
|
||||
ReturnType : SwaggerV2.Definition
|
||||
Method : WoofWare.Myriad.Plugins.HttpMethod
|
||||
Operation : OperationId
|
||||
Parameters : SwaggerParameter list
|
||||
Operation : SwaggerV2.OperationId
|
||||
Parameters : SwaggerV2.SwaggerParameter list
|
||||
Endpoint : string
|
||||
}
|
||||
|
||||
@@ -42,49 +42,41 @@ type internal TypeEntry =
|
||||
type internal Types =
|
||||
{
|
||||
ByHandle : IReadOnlyDictionary<string, TypeEntry>
|
||||
ByDefinition : IReadOnlyDictionary<Definition, TypeEntry>
|
||||
ByDefinition : IReadOnlyDictionary<SwaggerV2.Definition, TypeEntry>
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SwaggerClientGenerator =
|
||||
let outputFile = FileInfo "/tmp/output.txt"
|
||||
|
||||
// do
|
||||
// use _ = File.Create outputFile.FullName
|
||||
// ()
|
||||
let internal log (_ : string) = ()
|
||||
|
||||
let log (line : string) =
|
||||
// use w = outputFile.AppendText ()
|
||||
// w.WriteLine line
|
||||
()
|
||||
|
||||
let renderType (types : Types) (defn : Definition) : SynType option =
|
||||
let renderType (types : Types) (defn : SwaggerV2.Definition) : SynType option =
|
||||
match types.ByDefinition.TryGetValue defn with
|
||||
| true, v -> Some v.Signature
|
||||
| false, _ ->
|
||||
|
||||
match defn with
|
||||
| Definition.Handle h ->
|
||||
| SwaggerV2.Definition.Handle h ->
|
||||
match types.ByHandle.TryGetValue h with
|
||||
| false, _ -> None
|
||||
| true, v -> Some v.Signature
|
||||
| Definition.Object _ -> failwith "should not hit"
|
||||
| Definition.Array _ -> failwith "should not hit"
|
||||
| Definition.Unspecified -> failwith "should not hit"
|
||||
| Definition.String -> SynType.string |> Some
|
||||
| Definition.Boolean -> SynType.bool |> Some
|
||||
| Definition.Integer _ -> SynType.int |> Some
|
||||
| Definition.File -> SynType.createLongIdent' [ "System" ; "IO" ; "Stream" ] |> Some
|
||||
| SwaggerV2.Definition.Object _ -> failwith "should not hit"
|
||||
| SwaggerV2.Definition.Array _ -> failwith "should not hit"
|
||||
| SwaggerV2.Definition.Unspecified -> failwith "should not hit"
|
||||
| SwaggerV2.Definition.String -> SynType.string |> Some
|
||||
| SwaggerV2.Definition.Boolean -> SynType.bool |> Some
|
||||
| SwaggerV2.Definition.Integer _ -> SynType.int |> Some
|
||||
| SwaggerV2.Definition.File -> SynType.createLongIdent' [ "System" ; "IO" ; "Stream" ] |> Some
|
||||
|
||||
/// Returns None if we lacked the information required to do this.
|
||||
/// bigCache is a map of e.g. {"securityDefinition": {Defn : F# type}}.
|
||||
let rec defnToType
|
||||
(anonymousTypeCount : int ref)
|
||||
(handlesMap : Dictionary<string, TypeEntry>)
|
||||
(bigCache : Dictionary<string, Dictionary<Definition, TypeEntry>>)
|
||||
(bigCache : Dictionary<string, Dictionary<SwaggerV2.Definition, TypeEntry>>)
|
||||
(thisKey : string)
|
||||
(typeName : string option)
|
||||
(d : Definition)
|
||||
(d : SwaggerV2.Definition)
|
||||
: TypeEntry option
|
||||
=
|
||||
let cache =
|
||||
@@ -119,7 +111,7 @@ module internal SwaggerClientGenerator =
|
||||
|
||||
let result =
|
||||
match d with
|
||||
| Definition.Object obj ->
|
||||
| SwaggerV2.Definition.Object obj ->
|
||||
let requiredFields = obj.Required |> Option.defaultValue [] |> Set.ofList
|
||||
|
||||
let namedProperties =
|
||||
@@ -131,7 +123,7 @@ module internal SwaggerClientGenerator =
|
||||
// Special case for when this is a reference to this very type
|
||||
let isOurself =
|
||||
match defn with
|
||||
| Definition.Handle h ->
|
||||
| SwaggerV2.Definition.Handle h ->
|
||||
match h.Split '/' with
|
||||
| [| "#" ; location ; ty |] when location = thisKey && Some ty = typeName ->
|
||||
SynType.named ty |> Some
|
||||
@@ -206,8 +198,8 @@ module internal SwaggerClientGenerator =
|
||||
|> SynField.make
|
||||
|> List.singleton
|
||||
|> Some
|
||||
| Some AdditionalProperties.Never -> Some []
|
||||
| Some (AdditionalProperties.Constrained defn) ->
|
||||
| Some SwaggerV2.AdditionalProperties.Never -> Some []
|
||||
| Some (SwaggerV2.AdditionalProperties.Constrained defn) ->
|
||||
let defn' = defnToType anonymousTypeCount handlesMap bigCache thisKey None defn
|
||||
|
||||
match defn' with
|
||||
@@ -285,7 +277,7 @@ module internal SwaggerClientGenerator =
|
||||
|
||||
defn |> Some
|
||||
|
||||
| Definition.Array elt ->
|
||||
| SwaggerV2.Definition.Array elt ->
|
||||
let child = defnToType anonymousTypeCount handlesMap bigCache thisKey None elt.Items
|
||||
|
||||
match child with
|
||||
@@ -298,37 +290,37 @@ module internal SwaggerClientGenerator =
|
||||
}
|
||||
|
||||
Some defn
|
||||
| Definition.String ->
|
||||
| SwaggerV2.Definition.String ->
|
||||
{
|
||||
Signature = SynType.string
|
||||
FSharpDefinition = None
|
||||
}
|
||||
|> Some
|
||||
| Definition.Boolean ->
|
||||
| SwaggerV2.Definition.Boolean ->
|
||||
{
|
||||
Signature = SynType.bool
|
||||
FSharpDefinition = None
|
||||
}
|
||||
|> Some
|
||||
| Definition.Unspecified ->
|
||||
| SwaggerV2.Definition.Unspecified ->
|
||||
{
|
||||
Signature = SynType.unit
|
||||
FSharpDefinition = None
|
||||
}
|
||||
|> Some
|
||||
| Definition.Integer _ ->
|
||||
| SwaggerV2.Definition.Integer _ ->
|
||||
{
|
||||
Signature = SynType.createLongIdent' [ "int" ]
|
||||
FSharpDefinition = None
|
||||
}
|
||||
|> Some
|
||||
| Definition.File ->
|
||||
| SwaggerV2.Definition.File ->
|
||||
{
|
||||
Signature = SynType.createLongIdent' [ "System" ; "IO" ; "Stream" ]
|
||||
FSharpDefinition = None
|
||||
}
|
||||
|> Some
|
||||
| Definition.Handle s ->
|
||||
| SwaggerV2.Definition.Handle s ->
|
||||
let split = s.Split '/' |> List.ofArray
|
||||
|
||||
match split with
|
||||
@@ -390,14 +382,14 @@ module internal SwaggerClientGenerator =
|
||||
|> List.map (fun par ->
|
||||
let inParam =
|
||||
match par.In with
|
||||
| ParameterIn.Unrecognised (f, name) ->
|
||||
| SwaggerV2.ParameterIn.Unrecognised (f, name) ->
|
||||
log
|
||||
$"Skipping %O{ep.Operation} at %s{ep.Endpoint}: unrecognised In parameter %s{f} with name %s{name}"
|
||||
|
||||
None
|
||||
| ParameterIn.Body -> Some IsIn.Body
|
||||
| ParameterIn.Query name -> Some (IsIn.Query name)
|
||||
| ParameterIn.Path name -> Some (IsIn.Path name)
|
||||
| SwaggerV2.ParameterIn.Body -> Some IsIn.Body
|
||||
| SwaggerV2.ParameterIn.Query name -> Some (IsIn.Query name)
|
||||
| SwaggerV2.ParameterIn.Path name -> Some (IsIn.Path name)
|
||||
|
||||
match inParam with
|
||||
| None -> None
|
||||
@@ -477,6 +469,15 @@ module internal SwaggerClientGenerator =
|
||||
(SynLongIdent.createS' [ "RestEase" ; "Header" ])
|
||||
// Gitea, at least, starts with a `/`, which `Uri` then takes to indicate an absolute path.
|
||||
(SynExpr.tuple [ SynExpr.CreateConst "Content-Type" ; SynExpr.CreateConst contentType ])
|
||||
| Produces.OctetStream ->
|
||||
SynAttribute.create
|
||||
(SynLongIdent.createS' [ "RestEase" ; "Header" ])
|
||||
// Gitea, at least, starts with a `/`, which `Uri` then takes to indicate an absolute path.
|
||||
(SynExpr.tuple
|
||||
[
|
||||
SynExpr.CreateConst "Content-Type"
|
||||
SynExpr.CreateConst "application/octet-stream"
|
||||
])
|
||||
]
|
||||
|
||||
returnType
|
||||
@@ -512,6 +513,201 @@ module internal SwaggerClientGenerator =
|
||||
|> List.singleton
|
||||
|
||||
open Myriad.Core
|
||||
open System.IO
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal SwaggerV2Generator =
|
||||
let generate (pars : Map<string, string>) (contents : SwaggerV2.SwaggerV2) : Output =
|
||||
let scheme =
|
||||
let preferred = SwaggerV2.Scheme "https"
|
||||
|
||||
if List.isEmpty contents.Schemes then
|
||||
failwith "no schemes specified in API spec!"
|
||||
|
||||
if List.contains preferred contents.Schemes then
|
||||
preferred
|
||||
else
|
||||
List.head contents.Schemes
|
||||
|
||||
let clientDocstring = contents.Info.Description |> PreXmlDoc.create
|
||||
|
||||
let basePath = contents.BasePath
|
||||
|
||||
let typeDefs =
|
||||
let bigCache = Dictionary<_, Dictionary<_, _>> ()
|
||||
|
||||
let countAll () =
|
||||
(0, bigCache) ||> Seq.fold (fun count (KeyValue (_, v)) -> count + v.Count)
|
||||
|
||||
let byHandle = Dictionary ()
|
||||
let anonymousTypeCount = ref 0
|
||||
|
||||
let rec go (contents : ((string * SwaggerV2.Definition) * string) list) =
|
||||
let lastRound = countAll ()
|
||||
|
||||
contents
|
||||
|> List.filter (fun ((name, defn), defnClass) ->
|
||||
let doIt =
|
||||
SwaggerClientGenerator.defnToType
|
||||
anonymousTypeCount
|
||||
byHandle
|
||||
bigCache
|
||||
defnClass
|
||||
(Some name)
|
||||
defn
|
||||
|
||||
match doIt with
|
||||
| None -> true
|
||||
| Some _ -> false
|
||||
)
|
||||
|> fun remaining ->
|
||||
if not remaining.IsEmpty then
|
||||
let currentCount = countAll ()
|
||||
|
||||
if currentCount = lastRound then
|
||||
for (name, remaining), kind in remaining do
|
||||
SwaggerClientGenerator.log $"Remaining: %s{name} (%s{kind})"
|
||||
|
||||
SwaggerClientGenerator.log "--------"
|
||||
|
||||
for KeyValue (handle, defn) in byHandle do
|
||||
SwaggerClientGenerator.log $"Known: %s{handle} %O{defn}"
|
||||
|
||||
// TODO: ohh noooooo the Gitea spec is genuinely circular,
|
||||
// it's impossible to construct a Repository type
|
||||
// we're going to have to somehow detect this case and break the cycle
|
||||
// by artificially making a property optional
|
||||
// :sob: Gitea why are you like this
|
||||
// failwith "Made no further progress rendering types"
|
||||
()
|
||||
else
|
||||
go remaining
|
||||
|
||||
seq {
|
||||
for defnClass in [ "definitions" ; "responses" ] do
|
||||
match defnClass with
|
||||
| "definitions" ->
|
||||
for KeyValue (k, v) in contents.Definitions do
|
||||
yield (k, v), defnClass
|
||||
| "responses" ->
|
||||
for KeyValue (k, v) in contents.Responses do
|
||||
yield (k, v.Schema), defnClass
|
||||
| _ -> failwith "oh no"
|
||||
}
|
||||
|> Seq.toList
|
||||
|> go
|
||||
|
||||
let result = Dictionary ()
|
||||
|
||||
for KeyValue (_container, types) in bigCache do
|
||||
for KeyValue (defn, rendered) in types do
|
||||
result.TryAdd (defn, rendered) |> ignore<bool>
|
||||
|
||||
{
|
||||
ByHandle = byHandle
|
||||
ByDefinition = result :> IReadOnlyDictionary<_, _>
|
||||
}
|
||||
|
||||
let summary =
|
||||
contents.Paths
|
||||
|> Seq.collect (fun (KeyValue (path, endpoints)) ->
|
||||
endpoints
|
||||
|> Seq.choose (fun (KeyValue (method, endpoint)) ->
|
||||
let docstring = endpoint.Summary |> PreXmlDoc.create
|
||||
|
||||
let produces =
|
||||
match endpoint.Produces with
|
||||
| None -> Produces.Produces "json"
|
||||
| Some [] -> failwith $"API specified empty Produces: %s{path} (%O{method})"
|
||||
| Some [ SwaggerV2.MimeType "application/octet-stream" ] -> Produces.OctetStream
|
||||
| Some [ SwaggerV2.MimeType "application/json" ] -> Produces.Produces "json"
|
||||
| Some [ SwaggerV2.MimeType (StartsWith "text/" t) ] -> Produces.Produces t
|
||||
| Some [ SwaggerV2.MimeType s ] ->
|
||||
failwithf
|
||||
$"we don't support non-JSON Produces right now, got: %s{s} (%s{path} %O{method})"
|
||||
| Some (_ :: _) ->
|
||||
failwith $"we don't support multiple Produces right now, at %s{path} (%O{method})"
|
||||
|
||||
let returnType =
|
||||
endpoint.Responses
|
||||
|> Seq.choose (fun (KeyValue (response, defn)) ->
|
||||
if 200 <= response && response < 300 then
|
||||
Some defn
|
||||
else
|
||||
None
|
||||
)
|
||||
|> Seq.toList
|
||||
|
||||
let returnType =
|
||||
match returnType with
|
||||
| [ t ] -> Some t
|
||||
| [] -> failwith $"got no successful response results, %s{path} %O{method}"
|
||||
| _ ->
|
||||
SwaggerClientGenerator.log
|
||||
$"Ignoring %s{path} %O{method} due to multiple success responses"
|
||||
// can't be bothered to work out how to deal with multiple success
|
||||
// results right now
|
||||
None
|
||||
|
||||
match returnType with
|
||||
| None -> None
|
||||
| Some returnType ->
|
||||
|
||||
{
|
||||
Method = method
|
||||
Produces = produces
|
||||
DocString = docstring
|
||||
ReturnType = returnType
|
||||
Operation = endpoint.OperationId
|
||||
Parameters = endpoint.Parameters |> Option.defaultValue []
|
||||
Endpoint = path
|
||||
}
|
||||
|> Some
|
||||
)
|
||||
|> Seq.toList
|
||||
)
|
||||
|> Seq.toList
|
||||
|
||||
let config =
|
||||
let createMock =
|
||||
match Map.tryFind "GENERATEMOCKVISIBILITY" pars with
|
||||
| None -> None
|
||||
| Some v ->
|
||||
match v.ToLowerInvariant () with
|
||||
| "internal" -> Some true
|
||||
| "public" -> Some false
|
||||
| _ ->
|
||||
failwith
|
||||
$"Expected GenerateMockVisibility parameter to be 'internal' or 'public', but was: '%s{v.ToLowerInvariant ()}'"
|
||||
|
||||
let className =
|
||||
match Map.tryFind "CLASSNAME" pars with
|
||||
| None -> failwith "You must supply the <ClassName /> parameter in <MyriadParams />."
|
||||
| Some v -> v
|
||||
|
||||
{
|
||||
CreateMock = createMock
|
||||
ClassName = className
|
||||
}
|
||||
|
||||
let ty =
|
||||
SwaggerClientGenerator.computeType config basePath typeDefs clientDocstring summary
|
||||
|
||||
[
|
||||
yield
|
||||
SynModuleDecl.Open (
|
||||
SynOpenDeclTarget.ModuleOrNamespace (
|
||||
SynLongIdent.createS' [ "WoofWare" ; "Myriad" ; "Plugins" ],
|
||||
range0
|
||||
),
|
||||
range0
|
||||
)
|
||||
yield SwaggerClientGenerator.instantiateRequiredTypes typeDefs
|
||||
yield! ty
|
||||
]
|
||||
|> SynModuleOrNamespace.createNamespace [ Ident.create config.ClassName ]
|
||||
|> List.singleton
|
||||
|> Output.Ast
|
||||
|
||||
/// Myriad generator that stamps out an interface and class to access a Swagger-specified API.
|
||||
[<MyriadGenerator("swagger-client")>]
|
||||
@@ -521,205 +717,19 @@ type SwaggerClientGenerator () =
|
||||
member _.ValidInputExtensions = [ ".json" ]
|
||||
|
||||
member _.Generate (context : GeneratorContext) =
|
||||
let contents = File.ReadAllText context.InputFilename |> Swagger.parse
|
||||
let pars = MyriadParamParser.render context.AdditionalParameters
|
||||
|
||||
let scheme =
|
||||
let preferred = Scheme "https"
|
||||
let pars =
|
||||
pars
|
||||
|> Map.toSeq
|
||||
|> Seq.map (fun (k, v) -> k.ToUpperInvariant (), v)
|
||||
|> Map.ofSeq
|
||||
|
||||
if List.isEmpty contents.Schemes then
|
||||
failwith "no schemes specified in API spec!"
|
||||
if pars.IsEmpty then
|
||||
failwith "No parameters given. You must supply the <ClassName /> parameter in <MyriadParams />."
|
||||
|
||||
if List.contains preferred contents.Schemes then
|
||||
preferred
|
||||
else
|
||||
List.head contents.Schemes
|
||||
let contents = File.ReadAllText context.InputFilename |> SwaggerV2.parse
|
||||
|
||||
let clientDocstring = contents.Info.Description |> PreXmlDoc.create
|
||||
|
||||
let basePath = contents.BasePath
|
||||
|
||||
let typeDefs =
|
||||
let bigCache = Dictionary<_, Dictionary<_, _>> ()
|
||||
|
||||
let countAll () =
|
||||
(0, bigCache) ||> Seq.fold (fun count (KeyValue (_, v)) -> count + v.Count)
|
||||
|
||||
let byHandle = Dictionary ()
|
||||
let anonymousTypeCount = ref 0
|
||||
|
||||
let rec go (contents : ((string * Definition) * string) list) =
|
||||
let lastRound = countAll ()
|
||||
|
||||
contents
|
||||
|> List.filter (fun ((name, defn), defnClass) ->
|
||||
let doIt =
|
||||
SwaggerClientGenerator.defnToType
|
||||
anonymousTypeCount
|
||||
byHandle
|
||||
bigCache
|
||||
defnClass
|
||||
(Some name)
|
||||
defn
|
||||
|
||||
match doIt with
|
||||
| None -> true
|
||||
| Some _ -> false
|
||||
)
|
||||
|> fun remaining ->
|
||||
if not remaining.IsEmpty then
|
||||
let currentCount = countAll ()
|
||||
|
||||
if currentCount = lastRound then
|
||||
for (name, remaining), kind in remaining do
|
||||
SwaggerClientGenerator.log $"Remaining: %s{name} (%s{kind})"
|
||||
|
||||
SwaggerClientGenerator.log "--------"
|
||||
|
||||
for KeyValue (handle, defn) in byHandle do
|
||||
SwaggerClientGenerator.log $"Known: %s{handle} %O{defn}"
|
||||
|
||||
// TODO: ohh noooooo the Gitea spec is genuinely circular,
|
||||
// it's impossible to construct a Repository type
|
||||
// we're going to have to somehow detect this case and break the cycle
|
||||
// by artificially making a property optional
|
||||
// :sob: Gitea why are you like this
|
||||
// failwith "Made no further progress rendering types"
|
||||
()
|
||||
else
|
||||
go remaining
|
||||
|
||||
seq {
|
||||
for defnClass in [ "definitions" ; "responses" ] do
|
||||
match defnClass with
|
||||
| "definitions" ->
|
||||
for KeyValue (k, v) in contents.Definitions do
|
||||
yield (k, v), defnClass
|
||||
| "responses" ->
|
||||
for KeyValue (k, v) in contents.Responses do
|
||||
yield (k, v.Schema), defnClass
|
||||
| _ -> failwith "oh no"
|
||||
}
|
||||
|> Seq.toList
|
||||
|> go
|
||||
|
||||
let result = Dictionary ()
|
||||
|
||||
for KeyValue (_container, types) in bigCache do
|
||||
for KeyValue (defn, rendered) in types do
|
||||
result.TryAdd (defn, rendered) |> ignore<bool>
|
||||
|
||||
{
|
||||
ByHandle = byHandle
|
||||
ByDefinition = result :> IReadOnlyDictionary<_, _>
|
||||
}
|
||||
|
||||
let summary =
|
||||
contents.Paths
|
||||
|> Seq.collect (fun (KeyValue (path, endpoints)) ->
|
||||
endpoints
|
||||
|> Seq.choose (fun (KeyValue (method, endpoint)) ->
|
||||
let docstring = endpoint.Summary |> PreXmlDoc.create
|
||||
|
||||
let produces =
|
||||
match endpoint.Produces with
|
||||
| None -> Produces "json"
|
||||
| Some [] -> failwith $"API specified empty Produces: %s{path} (%O{method})"
|
||||
| Some [ MimeType "application/json" ] -> Produces "json"
|
||||
| Some [ MimeType (StartsWith "text/" t) ] -> Produces t
|
||||
| Some [ MimeType s ] ->
|
||||
failwithf
|
||||
$"we don't support non-JSON Produces right now, got: %s{s} (%s{path} %O{method})"
|
||||
| Some (_ :: _) ->
|
||||
failwith $"we don't support multiple Produces right now, at %s{path} (%O{method})"
|
||||
|
||||
let returnType =
|
||||
endpoint.Responses
|
||||
|> Seq.choose (fun (KeyValue (response, defn)) ->
|
||||
if 200 <= response && response < 300 then
|
||||
Some defn
|
||||
else
|
||||
None
|
||||
)
|
||||
|> Seq.toList
|
||||
|
||||
let returnType =
|
||||
match returnType with
|
||||
| [ t ] -> Some t
|
||||
| [] -> failwith $"got no successful response results, %s{path} %O{method}"
|
||||
| _ ->
|
||||
SwaggerClientGenerator.log
|
||||
$"Ignoring %s{path} %O{method} due to multiple success responses"
|
||||
// can't be bothered to work out how to deal with multiple success
|
||||
// results right now
|
||||
None
|
||||
|
||||
match returnType with
|
||||
| None -> None
|
||||
| Some returnType ->
|
||||
|
||||
{
|
||||
Method = method
|
||||
Produces = produces
|
||||
DocString = docstring
|
||||
ReturnType = returnType
|
||||
Operation = endpoint.OperationId
|
||||
Parameters = endpoint.Parameters |> Option.defaultValue []
|
||||
Endpoint = path
|
||||
}
|
||||
|> Some
|
||||
)
|
||||
|> Seq.toList
|
||||
)
|
||||
|> Seq.toList
|
||||
|
||||
let config =
|
||||
let pars = MyriadParamParser.render context.AdditionalParameters
|
||||
|
||||
let pars =
|
||||
pars
|
||||
|> Map.toSeq
|
||||
|> Seq.map (fun (k, v) -> k.ToUpperInvariant (), v)
|
||||
|> Map.ofSeq
|
||||
|
||||
if pars.IsEmpty then
|
||||
failwith "No parameters given. You must supply the <ClassName /> parameter in <MyriadParams />."
|
||||
|
||||
let createMock =
|
||||
match Map.tryFind "GENERATEMOCKVISIBILITY" pars with
|
||||
| None -> None
|
||||
| Some v ->
|
||||
match v.ToLowerInvariant () with
|
||||
| "internal" -> Some true
|
||||
| "public" -> Some false
|
||||
| _ ->
|
||||
failwith
|
||||
$"Expected GenerateMockVisibility parameter to be 'internal' or 'public', but was: '%s{v.ToLowerInvariant ()}'"
|
||||
|
||||
let className =
|
||||
match Map.tryFind "CLASSNAME" pars with
|
||||
| None -> failwith "You must supply the <ClassName /> parameter in <MyriadParams />."
|
||||
| Some v -> v
|
||||
|
||||
{
|
||||
CreateMock = createMock
|
||||
ClassName = className
|
||||
}
|
||||
|
||||
let ty =
|
||||
SwaggerClientGenerator.computeType config basePath typeDefs clientDocstring summary
|
||||
|
||||
[
|
||||
yield
|
||||
SynModuleDecl.Open (
|
||||
SynOpenDeclTarget.ModuleOrNamespace (
|
||||
SynLongIdent.createS' [ "WoofWare" ; "Myriad" ; "Plugins" ],
|
||||
range0
|
||||
),
|
||||
range0
|
||||
)
|
||||
yield SwaggerClientGenerator.instantiateRequiredTypes typeDefs
|
||||
yield! ty
|
||||
]
|
||||
|> SynModuleOrNamespace.createNamespace [ Ident.create config.ClassName ]
|
||||
|> List.singleton
|
||||
|> Output.Ast
|
||||
match contents with
|
||||
| Ok contents -> SwaggerV2Generator.generate pars contents
|
||||
| Error node -> failwith "Input was not a Swagger 2 spec"
|
||||
|
@@ -1,53 +1,8 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
module internal WoofWare.Myriad.Plugins.SwaggerV2
|
||||
|
||||
open System
|
||||
open System.Text.Json.Nodes
|
||||
|
||||
[<AutoOpen>]
|
||||
module internal JsonHelpers =
|
||||
let inline asString (n : JsonNode) (key : string) : string =
|
||||
match n.[key] with
|
||||
| null -> failwith $"Expected node to have a key '%s{key}', but it did not: %s{n.ToJsonString ()}"
|
||||
| s -> s.GetValue<string> ()
|
||||
|
||||
[<RequiresExplicitTypeArguments>]
|
||||
let inline asOpt<'ret> (n : JsonNode) (key : string) : 'ret option =
|
||||
match n.[key] with
|
||||
| null -> None
|
||||
| s -> s.GetValue<'ret> () |> Some
|
||||
|
||||
let inline asObj (n : JsonNode) (key : string) : JsonObject =
|
||||
match n.[key] with
|
||||
| null -> failwith $"Expected node to have a key '%s{key}', but it did not: %s{n.ToJsonString ()}"
|
||||
| o -> o.AsObject ()
|
||||
|
||||
let inline asObjOpt (n : JsonNode) (key : string) : JsonObject option =
|
||||
match n.[key] with
|
||||
| null -> None
|
||||
| o -> o.AsObject () |> Some
|
||||
|
||||
let inline asArr (n : JsonNode) (key : string) : JsonArray =
|
||||
match n.[key] with
|
||||
| null -> failwith $"Expected node to have a key '%s{key}', but it did not: %s{n.ToJsonString ()}"
|
||||
| o -> o.AsArray ()
|
||||
|
||||
let inline asArrOpt (n : JsonNode) (key : string) : JsonArray option =
|
||||
match n.[key] with
|
||||
| null -> None
|
||||
| o -> o.AsArray () |> Some
|
||||
|
||||
[<RequiresExplicitTypeArguments>]
|
||||
let inline asArr'<'v> (n : JsonNode) (key : string) : 'v list =
|
||||
match n.[key] with
|
||||
| null -> failwith $"Expected node to have a key '%s{key}', but it did not: %s{n.ToJsonString ()}"
|
||||
| o -> o.AsArray () |> Seq.map (fun v -> v.GetValue<'v> ()) |> Seq.toList
|
||||
|
||||
[<RequiresExplicitTypeArguments>]
|
||||
let inline asArrOpt'<'v> (n : JsonNode) (key : string) : 'v list option =
|
||||
match n.[key] with
|
||||
| null -> None
|
||||
| o -> o.AsArray () |> Seq.map (fun v -> v.GetValue<'v> ()) |> Seq.toList |> Some
|
||||
|
||||
/// A MIME type, like "application/json"
|
||||
type MimeType =
|
||||
/// A MIME type, like "application/json"
|
||||
@@ -198,7 +153,14 @@ and ObjectTypeDefinition =
|
||||
|> Map.ofSeq
|
||||
|> Some
|
||||
|
||||
let example = asObjOpt node "example"
|
||||
let example =
|
||||
match node.["example"] with
|
||||
| null -> None
|
||||
| :? JsonObject as o -> Some o
|
||||
| _ ->
|
||||
// Gitea returns a stringified and malformed JSON object here.
|
||||
// Don't throw; just omit.
|
||||
None
|
||||
|
||||
let required = asArrOpt'<string> node "required"
|
||||
|
||||
@@ -427,71 +389,8 @@ type Response =
|
||||
Schema = schema
|
||||
}
|
||||
|
||||
/// An HTTP method. This is System.Net.Http.HttpMethod, but
|
||||
/// a proper discriminated union.
|
||||
type HttpMethod =
|
||||
/// HTTP Get
|
||||
| Get
|
||||
/// HTTP Post
|
||||
| Post
|
||||
/// HTTP Delete
|
||||
| Delete
|
||||
/// HTTP Patch
|
||||
| Patch
|
||||
/// HTTP Options
|
||||
| Options
|
||||
/// HTTP Head
|
||||
| Head
|
||||
/// HTTP Put
|
||||
| Put
|
||||
/// HTTP Trace
|
||||
| Trace
|
||||
|
||||
/// Convert to the standard library's enum type.
|
||||
member this.ToDotNet () : System.Net.Http.HttpMethod =
|
||||
match this with
|
||||
| HttpMethod.Get -> System.Net.Http.HttpMethod.Get
|
||||
| HttpMethod.Post -> System.Net.Http.HttpMethod.Post
|
||||
| HttpMethod.Delete -> System.Net.Http.HttpMethod.Delete
|
||||
| HttpMethod.Patch -> System.Net.Http.HttpMethod.Patch
|
||||
| HttpMethod.Options -> System.Net.Http.HttpMethod.Options
|
||||
| HttpMethod.Head -> System.Net.Http.HttpMethod.Head
|
||||
| HttpMethod.Put -> System.Net.Http.HttpMethod.Put
|
||||
| HttpMethod.Trace -> System.Net.Http.HttpMethod.Trace
|
||||
|
||||
/// Human-readable string representation.
|
||||
override this.ToString () : string =
|
||||
match this with
|
||||
| HttpMethod.Get -> "Get"
|
||||
| HttpMethod.Post -> "Post"
|
||||
| HttpMethod.Delete -> "Delete"
|
||||
| HttpMethod.Patch -> "Post"
|
||||
| HttpMethod.Options -> "Options"
|
||||
| HttpMethod.Head -> "Head"
|
||||
| HttpMethod.Put -> "Put"
|
||||
| HttpMethod.Trace -> "Trace"
|
||||
|
||||
/// Throws on invalid inputs.
|
||||
static member Parse (s : string) : HttpMethod =
|
||||
if String.Equals (s, "get", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Get
|
||||
elif String.Equals (s, "post", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Post
|
||||
elif String.Equals (s, "patch", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Patch
|
||||
elif String.Equals (s, "delete", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Delete
|
||||
elif String.Equals (s, "head", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Head
|
||||
elif String.Equals (s, "options", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Options
|
||||
elif String.Equals (s, "put", StringComparison.OrdinalIgnoreCase) then
|
||||
HttpMethod.Put
|
||||
else
|
||||
failwith $"Unrecognised method: %s{s}"
|
||||
|
||||
/// A Swagger API specification.
|
||||
type Swagger =
|
||||
type SwaggerV2 =
|
||||
{
|
||||
/// Global collection of MIME types which any endpoint expects to consume its inputs in.
|
||||
/// This may be overridden on any individual endpoint by that endpoint.
|
||||
@@ -519,58 +418,63 @@ type Swagger =
|
||||
Responses : Map<string, Response>
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module Swagger =
|
||||
/// Parse a JSON-schema-based specification of a Swagger 2.0 API and
|
||||
/// build the strongly-typed version. Throws on invalid inputs.
|
||||
let parse (s : string) : Swagger =
|
||||
let node = JsonNode.Parse s
|
||||
let consumes = asArr'<string> node "consumes" |> List.map MimeType
|
||||
let produces = asArr'<string> node "produces" |> List.map MimeType
|
||||
let schemes = asArr'<string> node "schemes" |> List.map Scheme
|
||||
let swagger = asString node "swagger" |> Version.Parse
|
||||
let info = asObj node "info" |> SwaggerInfo.Parse
|
||||
let basePath = asString node "basePath"
|
||||
/// Parse a JSON-schema-based specification of a Swagger 2.0 API and
|
||||
/// build the strongly-typed version. Throws on invalid inputs; returns Error if the input is JSON but has a Swagger
|
||||
/// version that is not in the 2.0 series.
|
||||
let parse (s : string) : Result<SwaggerV2, JsonNode> =
|
||||
let node = JsonNode.Parse s
|
||||
let swagger = asString node "swagger" |> Version.Parse
|
||||
|
||||
let definitions =
|
||||
asObj node "definitions"
|
||||
|> Seq.map (fun (KeyValue (key, value)) ->
|
||||
let value = value.AsObject ()
|
||||
key, Definition.Parse value
|
||||
)
|
||||
|> Map.ofSeq
|
||||
if swagger.Major <> 2 then
|
||||
Error node
|
||||
else
|
||||
|
||||
let paths =
|
||||
asObj node "paths"
|
||||
|> Seq.map (fun (KeyValue (key, value)) ->
|
||||
let contents =
|
||||
value.AsObject ()
|
||||
|> Seq.map (fun (KeyValue (endpoint, contents)) ->
|
||||
let contents = contents.AsObject ()
|
||||
HttpMethod.Parse endpoint, SwaggerEndpoint.Parse contents
|
||||
)
|
||||
|> Map.ofSeq
|
||||
let consumes = asArr'<string> node "consumes" |> List.map MimeType
|
||||
let produces = asArr'<string> node "produces" |> List.map MimeType
|
||||
let schemes = asArr'<string> node "schemes" |> List.map Scheme
|
||||
let info = asObj node "info" |> SwaggerInfo.Parse
|
||||
let basePath = asString node "basePath"
|
||||
|
||||
key, contents
|
||||
)
|
||||
|> Map.ofSeq
|
||||
let definitions =
|
||||
asObj node "definitions"
|
||||
|> Seq.map (fun (KeyValue (key, value)) ->
|
||||
let value = value.AsObject ()
|
||||
key, Definition.Parse value
|
||||
)
|
||||
|> Map.ofSeq
|
||||
|
||||
let responses =
|
||||
asObj node "responses"
|
||||
|> Seq.map (fun (KeyValue (key, value)) ->
|
||||
let value = value.AsObject ()
|
||||
key, Response.Parse value
|
||||
)
|
||||
|> Map.ofSeq
|
||||
let paths =
|
||||
asObj node "paths"
|
||||
|> Seq.map (fun (KeyValue (key, value)) ->
|
||||
let contents =
|
||||
value.AsObject ()
|
||||
|> Seq.map (fun (KeyValue (endpoint, contents)) ->
|
||||
let contents = contents.AsObject ()
|
||||
HttpMethod.Parse endpoint, SwaggerEndpoint.Parse contents
|
||||
)
|
||||
|> Map.ofSeq
|
||||
|
||||
{
|
||||
Consumes = consumes
|
||||
Produces = produces
|
||||
Schemes = schemes
|
||||
Swagger = swagger
|
||||
Info = info
|
||||
BasePath = basePath
|
||||
Paths = paths
|
||||
Definitions = definitions
|
||||
Responses = responses
|
||||
}
|
||||
key, contents
|
||||
)
|
||||
|> Map.ofSeq
|
||||
|
||||
let responses =
|
||||
asObj node "responses"
|
||||
|> Seq.map (fun (KeyValue (key, value)) ->
|
||||
let value = value.AsObject ()
|
||||
key, Response.Parse value
|
||||
)
|
||||
|> Map.ofSeq
|
||||
|
||||
{
|
||||
Consumes = consumes
|
||||
Produces = produces
|
||||
Schemes = schemes
|
||||
Swagger = swagger
|
||||
Info = info
|
||||
BasePath = basePath
|
||||
Paths = paths
|
||||
Definitions = definitions
|
||||
Responses = responses
|
||||
}
|
||||
|> Ok
|
@@ -22,12 +22,13 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Myriad.Core" Version="0.8.3" />
|
||||
<PackageReference Include="TypeEquality" Version="0.3.0" />
|
||||
<PackageReference Include="WoofWare.Whippet.Fantomas" Version="0.3.1" />
|
||||
<PackageReference Include="WoofWare.Whippet.Fantomas" Version="0.6.3" />
|
||||
<!-- the lowest version allowed by Myriad.Core -->
|
||||
<PackageReference Update="FSharp.Core" Version="6.0.1" PrivateAssets="all"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.fs" />
|
||||
<Compile Include="List.fs"/>
|
||||
<Compile Include="Text.fs" />
|
||||
<Compile Include="Measure.fs" />
|
||||
@@ -41,9 +42,11 @@
|
||||
<Compile Include="HttpClientGenerator.fs"/>
|
||||
<Compile Include="CataGenerator.fs" />
|
||||
<Compile Include="ArgParserGenerator.fs" />
|
||||
<Compile Include="Swagger.fs" />
|
||||
<Compile Include="JsonHelpers.fs" />
|
||||
<Compile Include="HttpMethod.fs" />
|
||||
<Compile Include="SwaggerV2.fs" />
|
||||
<Compile Include="OpenApi3.fs" />
|
||||
<Compile Include="SwaggerClientGenerator.fs" />
|
||||
<None Include="ApacheLicence.txt" />
|
||||
<EmbeddedResource Include="version.json"/>
|
||||
<EmbeddedResource Include="SurfaceBaseline.txt"/>
|
||||
<None Include="..\README.md">
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "4.0",
|
||||
"version": "8.0",
|
||||
"publicReleaseRefSpec": [
|
||||
"^refs/heads/main$"
|
||||
],
|
||||
|
@@ -10,7 +10,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageDownload Include="G-Research.FSharp.Analyzers" Version="[0.12.0]" />
|
||||
<PackageDownload Include="G-Research.FSharp.Analyzers" Version="[0.15.0]" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
6
flake.lock
generated
6
flake.lock
generated
@@ -20,11 +20,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1736420959,
|
||||
"narHash": "sha256-dMGNa5UwdtowEqQac+Dr0d2tFO/60ckVgdhZU9q2E2o=",
|
||||
"lastModified": 1749903597,
|
||||
"narHash": "sha256-jp0D4vzBcRKwNZwfY4BcWHemLGUs4JrS3X9w5k/JYDA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "32af3611f6f05655ca166a0b1f47b57c762b5192",
|
||||
"rev": "41da1e3ea8e23e094e5e3eeb1e6b830468a7399e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
166
nix/deps.json
166
nix/deps.json
@@ -1,13 +1,13 @@
|
||||
[
|
||||
{
|
||||
"pname": "ApiSurface",
|
||||
"version": "4.1.16",
|
||||
"hash": "sha256-3F+dY2nZMFukUjIGrvB/h3ZsZYdLJ9jvQKRxX33qk2E="
|
||||
"version": "4.1.21",
|
||||
"hash": "sha256-v2adBYoE9NZPaQR3u2qq9r/9PxAM/wqi2Uiky0xGq+E="
|
||||
},
|
||||
{
|
||||
"pname": "fantomas",
|
||||
"version": "6.3.16",
|
||||
"hash": "sha256-4tRdYf+/Q1iedx+DDuIKVGlIWQdr6erM51VdKzZkhCs="
|
||||
"version": "7.0.2",
|
||||
"hash": "sha256-BAaENIm/ksTiXrUImRgKoIXTGIlgsX7ch6ayoFjhJXA="
|
||||
},
|
||||
{
|
||||
"pname": "Fantomas.Core",
|
||||
@@ -21,29 +21,19 @@
|
||||
},
|
||||
{
|
||||
"pname": "FsCheck",
|
||||
"version": "3.0.0",
|
||||
"hash": "sha256-/5FqiNeTVFairRtInS0cjQ3uGlqVfVJG2FsKIo8mdZ4="
|
||||
"version": "3.3.0",
|
||||
"hash": "sha256-TFDR/uAGv4OqrMX8/reQ4faaAhH9hxTHr1T/YkNPCCU="
|
||||
},
|
||||
{
|
||||
"pname": "fsharp-analyzers",
|
||||
"version": "0.28.0",
|
||||
"hash": "sha256-BqGk9MzHHA3oRPNfWuANcM1YELsdhzWI+kLF4mUDUx8="
|
||||
"version": "0.31.0",
|
||||
"hash": "sha256-PoAvaXbXsmvVw870UsnqdD20HoBHO7u4bzoaz5DXfzM="
|
||||
},
|
||||
{
|
||||
"pname": "FSharp.Core",
|
||||
"version": "4.3.4",
|
||||
"hash": "sha256-styyo+6mJy+yxE0NZG/b1hxkAjPOnJfMgd9zWzCJ5uk="
|
||||
},
|
||||
{
|
||||
"pname": "FSharp.Core",
|
||||
"version": "4.5.0",
|
||||
"hash": "sha256-7+B+8rsm/dMKvNBty8z5qB+kOxMwUzExy0F04xM88sk="
|
||||
},
|
||||
{
|
||||
"pname": "FSharp.Core",
|
||||
"version": "5.0.2",
|
||||
"hash": "sha256-YOoosLEiszPsOOaNAkWhFGU04JJKDOFVoA/ggrZMN10="
|
||||
},
|
||||
{
|
||||
"pname": "FSharp.Core",
|
||||
"version": "6.0.1",
|
||||
@@ -51,13 +41,23 @@
|
||||
},
|
||||
{
|
||||
"pname": "FSharp.Core",
|
||||
"version": "9.0.100",
|
||||
"hash": "sha256-V1q3CjbRvWZqxpi6cXD/R0F7pyXGGtH83M5Z/ITDrp8="
|
||||
"version": "9.0.202",
|
||||
"hash": "sha256-64Gub0qemmCoMa1tDus6TeTuB1+5sHfE6KD2j4o84mA="
|
||||
},
|
||||
{
|
||||
"pname": "FSharp.SystemTextJson",
|
||||
"version": "1.4.36",
|
||||
"hash": "sha256-zZEhjP0mdc5E3fBPS4/lqD7sxoaoT5SOspP546RWYdc="
|
||||
},
|
||||
{
|
||||
"pname": "FsUnit",
|
||||
"version": "6.0.1",
|
||||
"hash": "sha256-vka/aAgWhDCl5tu+kgO7GtSaHOOvlSaWxG+tExwGXpI="
|
||||
"version": "7.0.1",
|
||||
"hash": "sha256-K85CIdxMeFSHEKZk6heIXp/oFjWAn7dBILKrw49pJUY="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.ApplicationInsights",
|
||||
"version": "2.22.0",
|
||||
"hash": "sha256-mUQ63atpT00r49ca50uZu2YCiLg3yd6r3HzTryqcuEA="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.AspNetCore.App.Ref",
|
||||
@@ -86,13 +86,13 @@
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.CodeCoverage",
|
||||
"version": "17.12.0",
|
||||
"hash": "sha256-lGjifppD0OBMBp28pjUfPipaeXg739n8cPhtHWoo5RE="
|
||||
"version": "17.14.1",
|
||||
"hash": "sha256-f8QytG8GvRoP47rO2KEmnDLxIpyesaq26TFjDdW40Gs="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NET.Test.Sdk",
|
||||
"version": "17.12.0",
|
||||
"hash": "sha256-DKFEbhh2wPzahNeHdEoFig8tZh/LEVrFc5+zpT43Btg="
|
||||
"version": "17.14.1",
|
||||
"hash": "sha256-mZUzDFvFp7x1nKrcnRd0hhbNu5g8EQYt8SKnRgdhT/A="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NETCore.App.Host.linux-arm64",
|
||||
@@ -164,15 +164,45 @@
|
||||
"version": "1.1.3",
|
||||
"hash": "sha256-WLsf1NuUfRWyr7C7Rl9jiua9jximnVvzy6nk2D2bVRc="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Extensions.Telemetry",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-bIXwPSa3jkr2b6xINOqMUs6/uj/r4oVFM7xq3uVIZDU="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Extensions.TrxReport.Abstractions",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-IfMRfcyaIKEMRtx326ICKtinDBEfGw/Sv8ZHawJ96Yc="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Extensions.VSTestBridge",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-XpM/yFjhLSsuzyDV+xKubs4V1zVVYiV05E0+N4S1h0g="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Platform",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-y61Iih6w5D79dmrj2V675mcaeIiHoj1HSa1FRit2BLM="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Testing.Platform.MSBuild",
|
||||
"version": "1.5.3",
|
||||
"hash": "sha256-YspvjE5Jfi587TAfsvfDVJXNrFOkx1B3y1CKV6m7YLY="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.TestPlatform.ObjectModel",
|
||||
"version": "17.12.0",
|
||||
"hash": "sha256-3XBHBSuCxggAIlHXmKNQNlPqMqwFlM952Av6RrLw1/w="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.TestPlatform.ObjectModel",
|
||||
"version": "17.14.1",
|
||||
"hash": "sha256-QMf6O+w0IT+16Mrzo7wn+N20f3L1/mDhs/qjmEo1rYs="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.TestPlatform.TestHost",
|
||||
"version": "17.12.0",
|
||||
"hash": "sha256-rf8Sh0fQq44Sneuvs64unkkIHg8kOjDGWE35j9iLx5I="
|
||||
"version": "17.14.1",
|
||||
"hash": "sha256-1cxHWcvHRD7orQ3EEEPPxVGEkTpxom1/zoICC9SInJs="
|
||||
},
|
||||
{
|
||||
"pname": "Myriad.Core",
|
||||
@@ -186,8 +216,8 @@
|
||||
},
|
||||
{
|
||||
"pname": "Nerdbank.GitVersioning",
|
||||
"version": "3.7.115",
|
||||
"hash": "sha256-sqn+i7vvBgBUtm7j82mH+SpApgI2hsmL5DYfLm1Z7gw="
|
||||
"version": "3.8.38-alpha",
|
||||
"hash": "sha256-gPMrVbjOZxXoofczF/pn6eVkLhjVSJIyQrLO2oljrDc="
|
||||
},
|
||||
{
|
||||
"pname": "NETStandard.Library",
|
||||
@@ -206,38 +236,33 @@
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Common",
|
||||
"version": "6.12.1",
|
||||
"hash": "sha256-k6JAFqHFinTakwNuW666aXYPhR7TpI/rb+KbHm1S2TM="
|
||||
"version": "6.14.0",
|
||||
"hash": "sha256-jDOwt3veI1GSG8CfBnf2+dJxD3E/Nmlc+vHtD4J76Ms="
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Configuration",
|
||||
"version": "6.12.1",
|
||||
"hash": "sha256-e/4lvyl7o7g4aWTAtr9S2yiGgk7V0E9p6DXpsy7GgVw="
|
||||
"version": "6.14.0",
|
||||
"hash": "sha256-1PN9s6fhCw3wd2260U6hQ4vG3jIvcG8GIn1oQgxMXA0="
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Frameworks",
|
||||
"version": "6.12.1",
|
||||
"hash": "sha256-GGpkbas+PNLx35vvr3nyAVz5lY/aeoMx6qjmT368Lpg="
|
||||
"version": "6.14.0",
|
||||
"hash": "sha256-3ViM3R1ucQMEL2hQYsivT86kI6veMQK2xDsiAcFcVQk="
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Packaging",
|
||||
"version": "6.12.1",
|
||||
"hash": "sha256-3h8Nmjpt383+dCg9GJ1BJ26UirwEQsWCPcTiT0+wGeI="
|
||||
"version": "6.14.0",
|
||||
"hash": "sha256-Yafbnxs3maj55bJ1oKQiZ0QkntFUzXdhorL94YEUOhY="
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Protocol",
|
||||
"version": "6.12.1",
|
||||
"hash": "sha256-l+CHnAcit6Y9OjBxereRP5JzOuWbuZZQYkFOKsUkdQ8="
|
||||
"version": "6.14.0",
|
||||
"hash": "sha256-uLDKfs+QN1MdnuQtTES8qfNzzsmYKM6XB9pwJc4G+eo="
|
||||
},
|
||||
{
|
||||
"pname": "NuGet.Versioning",
|
||||
"version": "6.12.1",
|
||||
"hash": "sha256-f/ejCuzCAwKs4N4Ec6yf2RovrhBT0nj0hRDP+03/Iy4="
|
||||
},
|
||||
{
|
||||
"pname": "NUnit",
|
||||
"version": "4.0.1",
|
||||
"hash": "sha256-jd1CD5nHVXkpvBNpVDJcJyfTggCHLyDBySVSvtrA8Uk="
|
||||
"version": "6.14.0",
|
||||
"hash": "sha256-DqdOJgsphKxSvqB8b60zNPCaiLfbiu3WnUJ/90feLrY="
|
||||
},
|
||||
{
|
||||
"pname": "NUnit",
|
||||
@@ -246,8 +271,8 @@
|
||||
},
|
||||
{
|
||||
"pname": "NUnit3TestAdapter",
|
||||
"version": "4.6.0",
|
||||
"hash": "sha256-9Yav2fYhC4w0OgsyUwU4/5rDy4FVDTpKnWHuwl/uKJQ="
|
||||
"version": "5.0.0",
|
||||
"hash": "sha256-7jZM4qAbIzne3AcdFfMbvbgogqpxvVe6q2S7Ls8xQy0="
|
||||
},
|
||||
{
|
||||
"pname": "RestEase",
|
||||
@@ -269,6 +294,16 @@
|
||||
"version": "4.3.0",
|
||||
"hash": "sha256-c5tXWhE/fYbJVl9rXs0uHh3pTsg44YD1dJvyOA0WoMs="
|
||||
},
|
||||
{
|
||||
"pname": "System.Collections.Immutable",
|
||||
"version": "8.0.0",
|
||||
"hash": "sha256-F7OVjKNwpqbUh8lTidbqJWYi476nsq9n+6k0+QVRo3w="
|
||||
},
|
||||
{
|
||||
"pname": "System.Diagnostics.DiagnosticSource",
|
||||
"version": "5.0.0",
|
||||
"hash": "sha256-6mW3N6FvcdNH/pB58pl+pFSCGWgyaP4hfVtC/SMWDV4="
|
||||
},
|
||||
{
|
||||
"pname": "System.Diagnostics.DiagnosticSource",
|
||||
"version": "7.0.0",
|
||||
@@ -279,11 +314,6 @@
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-KaMHgIRBF7Nf3VwOo+gJS1DcD+41cJDPWFh+TDQ8ee8="
|
||||
},
|
||||
{
|
||||
"pname": "System.Formats.Asn1",
|
||||
"version": "8.0.1",
|
||||
"hash": "sha256-may/Wg+esmm1N14kQTG4ESMBi+GQKPp0ZrrBo/o6OXM="
|
||||
},
|
||||
{
|
||||
"pname": "System.IO.Abstractions",
|
||||
"version": "4.2.13",
|
||||
@@ -306,8 +336,8 @@
|
||||
},
|
||||
{
|
||||
"pname": "System.Reflection.Metadata",
|
||||
"version": "1.6.0",
|
||||
"hash": "sha256-JJfgaPav7UfEh4yRAQdGhLZF1brr0tUWPl6qmfNWq/E="
|
||||
"version": "8.0.0",
|
||||
"hash": "sha256-dQGC30JauIDWNWXMrSNOJncVa1umR1sijazYwUDdSIE="
|
||||
},
|
||||
{
|
||||
"pname": "System.Runtime",
|
||||
@@ -340,23 +370,33 @@
|
||||
"hash": "sha256-BkUYNguz0e4NJp1kkW7aJBn3dyH9STwB5N8XqnlCsmY="
|
||||
},
|
||||
{
|
||||
"pname": "System.Text.Encodings.Web",
|
||||
"version": "8.0.0",
|
||||
"hash": "sha256-IUQkQkV9po1LC0QsqrilqwNzPvnc+4eVvq+hCvq8fvE="
|
||||
"pname": "System.Text.Json",
|
||||
"version": "6.0.10",
|
||||
"hash": "sha256-UijYh0dxFjFinMPSTJob96oaRkNm+Wsa+7Ffg6mRnsc="
|
||||
},
|
||||
{
|
||||
"pname": "System.Text.Json",
|
||||
"version": "8.0.4",
|
||||
"hash": "sha256-g5oT7fbXxQ9Iah1nMCr4UUX/a2l+EVjJyTrw3FTbIaI="
|
||||
"version": "8.0.5",
|
||||
"hash": "sha256-yKxo54w5odWT6nPruUVsaX53oPRe+gKzGvLnnxtwP68="
|
||||
},
|
||||
{
|
||||
"pname": "System.Text.Json",
|
||||
"version": "9.0.0",
|
||||
"hash": "sha256-aM5Dh4okLnDv940zmoFAzRmqZre83uQBtGOImJpoIqk="
|
||||
},
|
||||
{
|
||||
"pname": "TypeEquality",
|
||||
"version": "0.3.0",
|
||||
"hash": "sha256-V50xAOzzyUJrY+MYPRxtnqW5MVeATXCes89wPprv1r4="
|
||||
},
|
||||
{
|
||||
"pname": "WoofWare.Expect",
|
||||
"version": "0.4.2",
|
||||
"hash": "sha256-CaVcj9Fo0VSMgfKIukM9WHGufPWHDqMO1D4VYVdJKJk="
|
||||
},
|
||||
{
|
||||
"pname": "WoofWare.Whippet.Fantomas",
|
||||
"version": "0.3.1",
|
||||
"hash": "sha256-i5oiqcrxzM90Ocuq5MIu2Ha5lV0aYu5nCvuwmFqp6NA="
|
||||
"version": "0.6.3",
|
||||
"hash": "sha256-FkW/HtVp8/HE2k6d7yFpnJcnP3FNNe9kGlkoIWmNgDw="
|
||||
}
|
||||
]
|
||||
|
Reference in New Issue
Block a user