diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 0ba3927..b549576 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "paket": { - "version": "5.226.0", + "version": "5.247.3", "commands": [ "paket" ] @@ -13,6 +13,12 @@ "commands": [ "fake" ] + }, + "fornax": { + "version": "0.13.1", + "commands": [ + "fornax" + ] } } } \ No newline at end of file diff --git a/.docker/Dockerfile b/.docker/Dockerfile deleted file mode 100644 index 10236bf..0000000 --- a/.docker/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM gitpod/workspace-full:latest - -USER root - -RUN wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb && \ - dpkg -i packages-microsoft-prod.deb && rm -rf packages-microsoft-prod.deb && \ - add-apt-repository universe && \ - apt-get update && apt-get -y -o APT::Install-Suggests="true" install dotnet-sdk-3.1 && \ - apt -y clean; diff --git a/.gitignore b/.gitignore index dcc8ad8..bca3351 100644 --- a/.gitignore +++ b/.gitignore @@ -268,3 +268,4 @@ demos/Thoth\.Elmish\.Demo/output/ \.ionide/ docs_deploy/ +docs/_public/ \ No newline at end of file diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index dcb8eeb..0000000 --- a/.gitpod.yml +++ /dev/null @@ -1,21 +0,0 @@ -image: - file: .docker/Dockerfile - -ports: - - port: 8080 - -tasks: - - before: > - rm -rf paket-files && - ./fake.sh build -t DotnetRestore - -vscode: - extensions: - - christian-kohler.path-intellisense@1.4.2:QnOrf5fk6KiVaQs4cNEP+w== - - wayou.vscode-todo-highlight@1.0.4:8IqxuxCVol2WnScJc5xVzg== - - mrmlnc.vscode-scss@0.9.0:/wXbNRm+2kunH5HbQqfnXA== - - PKief.material-icon-theme@3.9.2:xeHlNzPEF04yFqz/xKCD5w== - - Ionide.Ionide-fsharp@4.5.0:0qxXuhq6eO066etkNQrKCQ== - - zhuangtongfa.material-theme@3.2.2:jGTZwg0ChZg3eEKHC+UO+w== - - mhutchie.git-graph@1.21.0:zoSeoEOMfrwN0BMBC8VvqQ== - - eamodio.gitlens@10.2.0:GNDO73Cmp0fYDiLNxVkbsQ== diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets deleted file mode 100644 index 3632ffe..0000000 --- a/.paket/Paket.Restore.targets +++ /dev/null @@ -1,481 +0,0 @@ - - - - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - $(MSBuildVersion) - 15.0.0 - false - true - - true - $(MSBuildThisFileDirectory) - $(MSBuildThisFileDirectory)..\ - $(PaketRootPath)paket-files\paket.restore.cached - $(PaketRootPath)paket.lock - classic - proj - assembly - native - /Library/Frameworks/Mono.framework/Commands/mono - mono - - - $(PaketRootPath)paket.bootstrapper.exe - $(PaketToolsPath)paket.bootstrapper.exe - $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\ - - "$(PaketBootStrapperExePath)" - $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)" - - - - - true - true - - - True - - $(BaseIntermediateOutputPath.TrimEnd('\').TrimEnd('\/')) - - - - - - - - - - - - - dotnet paket - - - - - - $(PaketRootPath)paket.exe - $(PaketToolsPath)paket.exe - $(PaketToolsPath)paket.exe - $(_PaketBootStrapperExeDir)paket.exe - paket.exe - - - $(PaketRootPath)paket - $(PaketToolsPath)paket - $(PaketToolsPath)paket - - - $(PaketRootPath)paket.exe - $(PaketToolsPath)paket.exe - - - $(PaketBootStrapperExeDir)paket.exe - - - paket - - <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) - dotnet "$(PaketExePath)" - $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" - "$(PaketExePath)" - - - - - - - - - - - - - - - - - - - - - - true - $(NoWarn);NU1603;NU1604;NU1605;NU1608 - false - true - - - - - - - - - $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)')) - - - - - - - $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[0].Replace(`"`, ``).Replace(` `, ``)) - $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[1].Replace(`"`, ``).Replace(` `, ``)) - - - - - %(PaketRestoreCachedKeyValue.Value) - %(PaketRestoreCachedKeyValue.Value) - - - - - true - false - true - - - - - true - - - - - - - - - - - - - - - - - - - $(PaketIntermediateOutputPath)\$(MSBuildProjectFile).paket.references.cached - - $(MSBuildProjectFullPath).paket.references - - $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references - - $(MSBuildProjectDirectory)\paket.references - - false - true - true - references-file-or-cache-not-found - - - - - $([System.IO.File]::ReadAllText('$(PaketReferencesCachedFilePath)')) - $([System.IO.File]::ReadAllText('$(PaketOriginalReferencesFilePath)')) - references-file - false - - - - - false - - - - - true - target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths) - - - - - - - - - - - false - true - - - - - - - - - - - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) - - - %(PaketReferencesFileLinesInfo.PackageVersion) - All - runtime - runtime - true - true - - - - - $(PaketIntermediateOutputPath)/$(MSBuildProjectFile).paket.clitools - - - - - - - - - $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[0]) - $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[1]) - - - %(PaketCliToolFileLinesInfo.PackageVersion) - - - - - - - - - - false - - - - - - <_NuspecFilesNewLocation Include="$(PaketIntermediateOutputPath)\$(Configuration)\*.nuspec"/> - - - - - - $(MSBuildProjectDirectory)/$(MSBuildProjectFile) - true - false - true - false - true - false - true - false - true - $(PaketIntermediateOutputPath)\$(Configuration) - $(PaketIntermediateOutputPath) - - - - <_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.$(PackageVersion.Split(`+`)[0]).nuspec"/> - - - - - - - - - - - - - - - - - - - - - diff --git a/.paket/paket.exe b/.paket/paket.exe deleted file mode 100644 index b98e000..0000000 Binary files a/.paket/paket.exe and /dev/null differ diff --git a/.paket/paket.exe.config b/.paket/paket.exe.config deleted file mode 100644 index 2fc733f..0000000 --- a/.paket/paket.exe.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f0cafc0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.trimTrailingWhitespace": true, + "files.insertFinalNewline": true, + "files.trimFinalNewlines": true +} diff --git a/docs/index.md b/DOCUMENTATION.md similarity index 92% rename from docs/index.md rename to DOCUMENTATION.md index 7ca4a80..000df2c 100644 --- a/docs/index.md +++ b/DOCUMENTATION.md @@ -1,14 +1,28 @@ ---- -title: Thoth.Json ---- - -[[toc]] - -This documentation is for `Thoth.Json` v4, documentation for older versions can be found here: - -- [Thoth.Json v1](/Thoth.Json/legacy/v1.html) -- [Thoth.Json v2](/Thoth.Json/legacy/v2.html) -- [Thoth.Json v3](/Thoth.Json/legacy/v3.html) +# Thoth.JSON documentation + +## Table of contents + + + +- [Table of contents](#table-of-contents) +- [Decoder](#decoder) + - [What is a Decoder?](#what-is-a-decoder) + - [Primitives decoders](#primitives-decoders) + - [Collections](#collections) + - [Decoding Objects](#decoding-objects) +- [Encoder](#encoder) + - [How to use it?](#how-to-use-it) +- [Auto coders](#auto-coders) + - [Auto decoder](#auto-decoder) + - [Auto encoder](#auto-encoder) + - [Extra coders](#extra-coders) + - [Decoding int64, decimal or bigint](#decoding-int64-decimal-or-bigint) + - [Caching](#caching) +- [.Net & NetCore support](#net--netcore-support) + - [Code sample](#code-sample) + - [Giraffe](#giraffe) + + ## Decoder @@ -97,10 +111,10 @@ There are special decoders for the following collections. ```fsharp open Thoth.Json -> Decode.fromString (array int) "[1, 2, 3]" +> Decode.fromString (Decode.array int) "[1, 2, 3]" val it : Result = Ok [|1, 2, 3|] -> Decode.fromString (list string) """["Maxime", "Alfonso", "Vesper"]""" +> Decode.fromString (Decode.list string) """["Maxime", "Alfonso", "Vesper"]""" val it : Result = Ok ["Maxime", "Alfonso", "Vesper"] > Decode.fromString (Decode.index 1 Decode.string) """["maxime", "alfonso", "steffen"]""" diff --git a/Thoth.Json.Projets.sln b/Thoth.Json.Projets.sln new file mode 100644 index 0000000..3a6e286 --- /dev/null +++ b/Thoth.Json.Projets.sln @@ -0,0 +1,81 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29709.97 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Thoth.Json", "src\Thoth.Json.fsproj", "{B967432B-CE16-480B-B364-B5A6B18AB3DC}" +EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Tests.Thoth.Json.FableRuntime", "tests\Tests.Thoth.Json.FableRuntime.fsproj", "{77152A74-CFC7-437C-9415-3FC1F3593DA0}" +EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Tests.Thoth.Json.NetRuntime", "tests\Tests.Thoth.Json.NetRuntime.fsproj", "{BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}" +EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Thoth.Json.FableRuntime", "src\Thoth.Json.FableRuntime.fsproj", "{4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Debug|x64.ActiveCfg = Debug|Any CPU + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Debug|x64.Build.0 = Debug|Any CPU + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Debug|x86.ActiveCfg = Debug|Any CPU + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Debug|x86.Build.0 = Debug|Any CPU + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Release|Any CPU.Build.0 = Release|Any CPU + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Release|x64.ActiveCfg = Release|Any CPU + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Release|x64.Build.0 = Release|Any CPU + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Release|x86.ActiveCfg = Release|Any CPU + {B967432B-CE16-480B-B364-B5A6B18AB3DC}.Release|x86.Build.0 = Release|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Debug|x64.ActiveCfg = Debug|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Debug|x64.Build.0 = Debug|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Debug|x86.ActiveCfg = Debug|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Debug|x86.Build.0 = Debug|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Release|Any CPU.Build.0 = Release|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Release|x64.ActiveCfg = Release|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Release|x64.Build.0 = Release|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Release|x86.ActiveCfg = Release|Any CPU + {77152A74-CFC7-437C-9415-3FC1F3593DA0}.Release|x86.Build.0 = Release|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Debug|x64.ActiveCfg = Debug|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Debug|x64.Build.0 = Debug|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Debug|x86.ActiveCfg = Debug|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Debug|x86.Build.0 = Debug|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Release|Any CPU.Build.0 = Release|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Release|x64.ActiveCfg = Release|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Release|x64.Build.0 = Release|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Release|x86.ActiveCfg = Release|Any CPU + {BC1BD8D5-D518-4C04-89D9-9E62A932D5E6}.Release|x86.Build.0 = Release|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Debug|x64.ActiveCfg = Debug|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Debug|x64.Build.0 = Debug|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Debug|x86.ActiveCfg = Debug|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Debug|x86.Build.0 = Debug|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Release|Any CPU.Build.0 = Release|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Release|x64.ActiveCfg = Release|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Release|x64.Build.0 = Release|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Release|x86.ActiveCfg = Release|Any CPU + {4C938BA5-EF95-4BB0-B1B5-C04F188DB17E}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {138D696D-3E83-4254-99CF-C6A0675E97E7} + EndGlobalSection +EndGlobal diff --git a/_lib/Fornax.Core.dll b/_lib/Fornax.Core.dll new file mode 100644 index 0000000..8e81270 Binary files /dev/null and b/_lib/Fornax.Core.dll differ diff --git a/_lib/Markdig.dll b/_lib/Markdig.dll new file mode 100644 index 0000000..7d72255 Binary files /dev/null and b/_lib/Markdig.dll differ diff --git a/config.fsx b/config.fsx new file mode 100644 index 0000000..5b06627 --- /dev/null +++ b/config.fsx @@ -0,0 +1,42 @@ +#r "_lib/Fornax.Core.dll" + +open Config +open System.IO + +let postPredicate (projectRoot: string, page: string) = + let fileName = Path.Combine(projectRoot,page) + let ext = Path.GetExtension page + if ext = ".md" then + let ctn = File.ReadAllText fileName + ctn.Contains("layout: post") + else + false + +let staticPredicate (projectRoot: string, page: string) = + let ext = Path.GetExtension page + if page.Contains "_public" || + page.Contains "_bin" || + page.Contains "_lib" || + page.Contains "_data" || + page.Contains "_settings" || + page.Contains "_config.yml" || + page.Contains ".sass-cache" || + page.Contains ".git" || + page.Contains ".ionide" || + ext = ".fsx" + then + false + else + true + +let config = { + Generators = [ + {Script = "less.fsx"; Trigger = OnFileExt ".less"; OutputFile = ChangeExtension "css" } + {Script = "sass.fsx"; Trigger = OnFileExt ".scss"; OutputFile = ChangeExtension "css" } + {Script = "post.fsx"; Trigger = OnFilePredicate postPredicate; OutputFile = ChangeExtension "html" } + {Script = "staticfile.fsx"; Trigger = OnFilePredicate staticPredicate; OutputFile = SameFileName } + {Script = "index.fsx"; Trigger = Once; OutputFile = NewFileName "index.html" } + {Script = "about.fsx"; Trigger = Once; OutputFile = NewFileName "about.html" } + {Script = "contact.fsx"; Trigger = Once; OutputFile = NewFileName "contact.html" } + ] +} diff --git a/docs/changelog.md b/docs/changelog.md deleted file mode 100644 index 95524d9..0000000 --- a/docs/changelog.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Changelog -layout: changelog -extra: - changelog_path: ./../../CHANGELOG.md ---- diff --git a/docs/legacy/v1.md b/docs/legacy/v1.md deleted file mode 100644 index 87acd3b..0000000 --- a/docs/legacy/v1.md +++ /dev/null @@ -1,225 +0,0 @@ ---- -title: Thoth.Json ---- - -[[toc]] - -
-
-

Your are looking at version 1 of Thoth.Json and Thoth.Json.Net.

-

Please consider upgrading your project to a newest version.

-
-
- -## Decoder - -Turn JSON values into F# values. - -By using a Decoder instead of Fable `ofJson` function, you will be guaranteed that the JSON structure is correct. -This is especially useful if you use Fable without sharing your domain with the server. - -*This module is inspired by [Json.Decode from Elm](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode) -and [elm-decode-pipeline](http://package.elm-lang.org/packages/NoRedInk/elm-decode-pipeline/latest).* - -As so, to complete this documentation, you can also take a look at the [Elm documentation](https://guide.elm-lang.org/interop/json.html). - -### What is a Decoder ? - -Here is the signature of a `Decoder`: - -```fsharp -type Decoder<'T> = obj -> Result<'T, DecoderError> -``` - -This is taking an "untyped" value and checking if it has the expected structure. If the structure is correct, -then you get an `Ok` result, otherwise an `Error` explaining why the decoder failed. - -### Primitives decoders - -- `string : Decoder` -- `int : Decoder` -- `float : Decoder` -- `bool : Decoder` - -```fsharp -open Thoth.Json.Decode - -> decodeString string "\"maxime\"" -val it : Result = Ok "maxime" - -> decodeString int "25" -val it : Result = Ok 25 - -> decodeString bool "true" -val it : Result = Ok true - -> decodeString float "true" -val it : Result = Err "Expecting a float but instead got: true" -``` - -With these primitives decoders we can handle the basic JSON values. - -### Collections - -There are special decoders for the following collections. - -- `list : Decoder<'value> -> Decoder<'value list>` -- `array : Decoder<'value> -> Decoder<'value array>` - -```fsharp -open Thoth.Json.Decode - -> decodeString (array int) "[1, 2, 3]" -val it : Result = Ok [|1, 2, 3|] - -> decodeString (list string) """["Maxime", "Alfonso", "Vesper"]""" -val it : Result = Ok ["Maxime", "Alfonso", "Vesper"] -``` - -### Decoding Objects - -In order to decode objects, you can use: - -- `field : string -> Decoder<'value> -> Decoder<'value>` - - Decode a JSON object, requiring a particular field. -- `at : string list -> Decoder<'value> -> Decoder<'value>` - - Decode a JSON object, requiring certain path. - -```fsharp -open Thoth.Json.Decode - -> decodeString (field "x" int) """{"x": 10, "y": 21}""" -val it : Result = Ok 10 - -> decodeString (field "y" int) """{"x": 10, "y": 21}""" -val it : Result = Ok 21 -``` - -**Important:** - -These two decoders only take into account the field or path. The object can have other fields/paths with other content. - -#### Map functions - -To get data from several fields and convert them into a record you will need to use the `map` functions -like `map2`, `map3`, ..., `map8`. - -```fsharp -open Thoth.Json.Decode - -type Point = - { X : int - Y : int } - - static member Decoder : Decoder = - map2 (fun x y -> - { X = x - Y = y } : Point) - (field "x" int) - (field "y" int) - -> decodeString Point.Decoder """{"x": 10, "y": 21}""" -val it : Result = Ok { X = 10; Y = 21 } -``` - -#### Pipeline decode style - -When working with a larger object or if you prefer to use the `(|>)` operator, you can use the pipeline helpers. - -```fsharp -open Thoth.Json.Decode - -type Point = - { X : int - Y : int } - - static member Decoder = - decode - (fun x y -> - { X = x - Y = y } : Point) - |> required "x" int - |> required "y" int - -> decodeString Point.Decoder """{"x": 10, "y": 21}""" -val it : Result = Ok { X = 10; Y = 21 } -``` - -## Encoder - -Module for turning F# values into JSON values. - -*This module is inspired by [Json.Encode from Elm](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Encode).* - -### How to use it ? - -```fsharp - open Thoth.Json.Encode - - let person = - object - [ "firstname", string "maxime" - "surname", string "mangel" - "age", int 25 - "address", object - [ "street", string "main street" - "city", string "Bordeaux" ] - ] - - let compact = encode 0 person - // {"firstname":"maxime","surname":"mangel","age":25,"address":{"street":"main street","city":"Bordeaux"}} - - let readable = encode 4 person - // { - // "firstname": "maxime", - // "surname": "mangel", - // "age": 25, - // "address": { - // "street": "main street", - // "city": "Bordeaux" - // } - // } -``` - -## .Net & NetCore support - -You can share your decoders and encoders **between your client and server**. - -In order to use Thoth.Json API on .Net or NetCore you need to use the `Thoth.Json.Net` package. - -### Code sample - -```fsharp -// By adding this condition, you can share your code between your client and server -##if FABLE_COMPILER -open Thoth.Json -##else -open Thoth.Json.Net -##endif - -type User = - { Id : int - Name : string - Email : string - Followers : int } - - static member Decoder = - Decode.decode - (fun id email name followers -> - { Id = id - Name = name - Email = email - Followers = followers }) - |> Decode.required "id" Decode.int - |> Decode.required "email" Decode.string - |> Decode.optional "name" Decode.string "" - |> Decode.hardcoded 0 - - static member Encoder (user : User) = - Encode.object - [ "id", Encode.int user.Id - "name", Encode.string user.Name - "email", Encode.string user.Email - "followers", Encode.int user.Followers - ] -``` diff --git a/docs/legacy/v2.md b/docs/legacy/v2.md deleted file mode 100644 index 5570a3a..0000000 --- a/docs/legacy/v2.md +++ /dev/null @@ -1,359 +0,0 @@ ---- -title: Thoth.Json ---- - -[[toc]] - -:::warning -Your are looking at **version 2** of Thoth.Json and Thoth.Json.Net. - -Please consider upgrading your project to a newest version. -::: - -
-
-Version 2 of Thoth.Json and Thoth.Json.Net only support Fable 2. -
-
- -## Decoder - -Turn JSON values into F# values. - -By using a Decoder, you will be guaranteed that the JSON structure is correct. -This is especially useful if you use Fable without sharing your domain with the server. - -*This module is inspired by [Json.Decode from Elm](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode) -and [elm-decode-pipeline](http://package.elm-lang.org/packages/NoRedInk/elm-decode-pipeline/latest).* - -As so, to complete this documentation, you can also take a look at the [Elm documentation](https://guide.elm-lang.org/interop/json.html). - -### What is a Decoder ? - -Here is the signature of a `Decoder`: - -```fsharp -type Decoder<'T> = string -> obj -> Result<'T, DecoderError> -``` - -This is taking two arguments: - -- the traveled path -- an "untyped" value and checking if it has the expected structure. - -If the structure is correct, then you get an `Ok` result, otherwise an `Error` explaining why and where the decoder failed. - -Example of error: - -```fsharp -Error at: `$.user.firstname` -Expecting an object with path `user.firstname` but instead got: -{ - "user": { - "name": "maxime", - "age": 25 - } -} -Node `firstname` is unknown. -``` - -The path generated is a valid `JSONPath`, so you can use tools like [JSONPath Online Evaluator](http://jsonpath.com/) to explore your JSON. - -### Primitives decoders - -- `string : Decoder` -- `guid : Decoder` -- `int : Decoder` -- `int64 : Decoder` -- `uint64 : Decoder` -- `bigint : Decoder` -- `bool : Decoder` -- `float : Decoder` -- `decimal : Decoder` -- `datetime : Decoder` -- `datetimeOffset : Decoder` - -```fsharp -open Thoth.Json - -> Decode.fromString Decode.string "\"maxime\"" -val it : Result = Ok "maxime" - -> Decode.fromString Decode.int "25" -val it : Result = Ok 25 - -> Decode.fromString Decode.bool "true" -val it : Result = Ok true - -> Decode.fromString Decode.float "true" -val it : Result = Error "Error at: `$$`\n Expecting a float but instead got: true" -``` - -With these primitives decoders we can handle the basic JSON values. - -### Collections - -There are special decoders for the following collections. - -- `list : Decoder<'value> -> Decoder<'value list>` -- `array : Decoder<'value> -> Decoder<'value array>` -- `index : -> int -> Decoder<'value> -> Decoder<'value>` - -```fsharp -open Thoth.Json - -> Decode.fromString (array int) "[1, 2, 3]" -val it : Result = Ok [|1, 2, 3|] - -> Decode.fromString (list string) """["Maxime", "Alfonso", "Vesper"]""" -val it : Result = Ok ["Maxime", "Alfonso", "Vesper"] - -> Decode.fromString (Decode.index 1 Decode.string) """["maxime", "alfonso", "steffen"]""" -val it : Result = Ok("alfonso") -``` - -### Decoding Objects - -In order to decode objects, you can use: - -- `field : string -> Decoder<'value> -> Decoder<'value>` - - Decode a JSON object, requiring a particular field. -- `at : string list -> Decoder<'value> -> Decoder<'value>` - - Decode a JSON object, requiring certain path. - -```fsharp -open Thoth.Json - -> Decode.fromString (field "x" int) """{"x": 10, "y": 21}""" -val it : Result = Ok 10 - -> Decode.fromString (field "y" int) """{"x": 10, "y": 21}""" -val it : Result = Ok 21 -``` - -**Important:** - -These two decoders only take into account the provided field or path. The object can have other fields/paths with other content. - -#### Map functions - -To get data from several fields and convert them into a record you will need to use the `map` functions -like `map2`, `map3`, ..., `map8`. - -```fsharp -open Thoth.Json - -type Point = - { X : int - Y : int } - - static member Decoder : Decode.Decoder = - Decode.map2 (fun x y -> - { X = x - Y = y } : Point) - (Decode.field "x" Decode.int) - (Decode.field "y" Decode.int) - -> Decode.fromString Point.Decoder """{"x": 10, "y": 21}""" -val it : Result = Ok { X = 10; Y = 21 } -``` - -#### Object builder style - -When working with a larger object, you can use the object builder helper. - -```fsharp -open Thoth.Json - -type User = - { Id : int - Name : string - Email : string - Followers : int } - - static member Decoder : Decode.Decoder = - Decode.object - (fun get -> - { Id = get.Required.Field "id" Decode.int - Name = get.Optional.Field "name" Decode.string - |> Option.defaultValue "" - Email = get.Required.Field "email" Decode.string - Followers = 0 } - ) - -> Decode.fromString User.Decoder """{ "id": 67, "email": "user@mail.com" }""" -val it : Result = Ok { Id = 67; Name = ""; Email = "user@mail.com"; Followers = 0 } -``` - -#### Auto decoder - -If your JSON structure is a one to one match, with your F# type, you can use auto decoders. Auto decoders, will generate the decoder at runtime for you and still guarantee that the JSON structure is correct. - -```fsharp -> let json = """{ "Id" : 0, "Name": "maxime", "Email": "mail@domain.com", "Followers": 0 }""" -> Decode.Auto.fromString(json) -val it : Result = Ok { Id = 0; Name = "maxime"; Email = "mail@domain.com"; Followers = 0 } -``` - -Auto decoder accept an optional argument `isCamelCase`: -- if `true`, then the keys in the JSON are considered `camelCase` -- if `false`, then the keys in the JSON are considered `PascalCase` - -```fsharp -> let json = """{ "id" : 0, "name": "maxime", "email": "mail@domain.com", "followers": 0 }""" -> Decode.Auto.fromString(json, isCamelCase=true) -val it : Result = Ok { Id = 0; Name = "maxime"; Email = "mail@domain.com"; Followers = 0 } -``` - -If you prefer not to deal with a `Result<'T, string>` type you can use `Decode.Auto.unsafeFromString`. -- if the decoder succeed, it returns `'T`. -- if the decoder failed, it will throw an exception with the explanation in the `Message` property. - -### Size optimization - -Note auto decoders use reflection info, which in Fable 2 is generated in the call site. If you want to save some bytes in the generated JS code, it's recommended to cache decoders instead of using `Decode.Auto.fromString` directly. - -```fsharp -// Instead of: -let method1 json = - Decode.Auto.fromString json - -let method2 json = - Decode.Auto.fromString json - -// Do this: -let fooDecoder = Decode.Auto.generateDecoder() - -let method1 json = - Decode.fromString fooDecoder json - -let method2 json = - Decode.fromString fooDecoder json -``` - -For similar reasons, when possible it's better to compose decoders instead of generating them automatically. - -```fsharp -// Instead of: -type Group = { foo: Foo; bar: Bar } - -let fooDecoder = Decode.Auto.generateDecoder() -let barDecoder = Decode.Auto.generateDecoder() - -let fooListDecoder = Decode.Auto.generateDecoder() -let groupDecoder = Decode.Auto.generateDecoder() - -// Do this: -let fooListDecoder: Decode.Decoder = - Decode.list fooDecoder - -let groupDecoder: Decode.Decoder = - Decode.object (fun get -> - { foo = get.Required.Field "foo" fooDecoder - bar = get.Required.Field "bar" barDecoder }) -``` - -## Encoder - -Module for turning F# values into JSON values. - -*This module is inspired by [Json.Encode from Elm](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Encode).* - -### How to use it ? - -```fsharp - open Thoth.Json - - let person = - Encode.object - [ "firstname", Encode.string "maxime" - "surname", Encode.string "mangel" - "age", Encode.int 25 - "address", Encode.object - [ "street", Encode.string "main street" - "city", Encode.string "Bordeaux" ] - ] - - let compact = Encode.toString 0 person - // {"firstname":"maxime","surname":"mangel","age":25,"address":{"street":"main street","city":"Bordeaux"}} - - let readable = Encode.toString 4 person - // { - // "firstname": "maxime", - // "surname": "mangel", - // "age": 25, - // "address": { - // "street": "main street", - // "city": "Bordeaux" - // } - // } -``` - -### Auto encoder - -```fsharp -type User = - { Id : int - Name : string - Email : string - Followers : int } - -let user = - { Id = 0 - Name = "maxime" - Email = "mail@domain.com" - Followers = 0 } - -let json = Encode.Auto.toString(4, user) -// { -// "Id": 0, -// "Name": "maxime", -// "Email": "mail@domain.com", -// "Followers": 0 -// } -``` - -## .Net & NetCore support - -You can share your decoders and encoders **between your client and server**. - -In order to use Thoth.Json API on .Net or NetCore you need to use the `Thoth.Json.Net` package. - -### Code sample - -```fsharp -// By adding this condition, you can share your code between your client and server -##if FABLE_COMPILER -open Thoth.Json -##else -open Thoth.Json.Net -##endif - -type User = - { Id : int - Name : string - Email : string - Followers : int } - - static member Decoder : Decode.Decoder = - Decode.object - (fun get -> - { Id = get.Required.Field "id" Decode.int - Name = get.Optional.Field "name" Decode.string - |> Option.defaultValue "" - Email = get.Required.Field "email" Decode.string - Followers = 0 } - ) - - static member Encoder (user : User) = - Encode.object - [ "id", Encode.int user.Id - "name", Encode.string user.Name - "email", Encode.string user.Email - "followers", Encode.int user.Followers - ] -``` - -### Online tool - -Convert a JSON snippet to F# record with Decoders using [JSON to Thoth](https://nojaf.com/redhood/). diff --git a/docs/legacy/v3.md b/docs/legacy/v3.md deleted file mode 100644 index 6df6aaf..0000000 --- a/docs/legacy/v3.md +++ /dev/null @@ -1,370 +0,0 @@ ---- -title: Thoth.Json ---- - -[[toc]] - -:::warning -Your are looking at **version 3** of Thoth.Json and Thoth.Json.Net. - -Please consider upgrading your project to a newest version. -::: - -## Decoder - -Turn JSON values into F# values. - -By using a Decoder, you will be guaranteed that the JSON structure is correct. -This is especially useful if you use Fable without sharing your domain with the server. - -*This module is inspired by [Json.Decode from Elm](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode) -and [elm-decode-pipeline](http://package.elm-lang.org/packages/NoRedInk/elm-decode-pipeline/latest).* - -You can also take a look at the [Elm documentation](https://guide.elm-lang.org/interop/json.html). - -### What is a Decoder? - -Here is the signature of a `Decoder`: - -```fsharp -type Decoder<'T> = string -> obj -> Result<'T, DecoderError> -``` - -This is taking two arguments: - -- the traveled path -- an "untyped" value and checking if it has the expected structure. - -If the structure is correct, then you get an `Ok` result, otherwise an `Error` explaining where and why the decoder failed. - -Example of a decoder error: - -```fsharp -Error at: `$.user.firstname` -Expecting an object with path `user.firstname` but instead got: -{ - "user": { - "name": "maxime", - "age": 25 - } -} -Node `firstname` is unknown. -``` - -The path generated is a valid `JSONPath`, so you can use tools like [JSONPath Online Evaluator](http://jsonpath.com/) to explore your JSON. - -### Primitives decoders - -- `string : Decoder` -- `guid : Decoder` -- `int : Decoder` -- `int64 : Decoder` -- `uint64 : Decoder` -- `bigint : Decoder` -- `bool : Decoder` -- `float : Decoder` -- `decimal : Decoder` -- `datetime : Decoder` -- `datetimeOffset : Decoder` -- `timespan : Decoder` - -```fsharp -open Thoth.Json - -> Decode.fromString Decode.string "\"maxime\"" -val it : Result = Ok "maxime" - -> Decode.fromString Decode.int "25" -val it : Result = Ok 25 - -> Decode.fromString Decode.bool "true" -val it : Result = Ok true - -> Decode.fromString Decode.float "true" -val it : Result = Error "Error at: `$$`\n Expecting a float but instead got: true" -``` - -With these primitives decoders we can handle basic JSON values. - -### Collections - -There are special decoders for the following collections. - -- `list : Decoder<'value> -> Decoder<'value list>` -- `array : Decoder<'value> -> Decoder<'value array>` -- `index : -> int -> Decoder<'value> -> Decoder<'value>` - -```fsharp -open Thoth.Json - -> Decode.fromString (array int) "[1, 2, 3]" -val it : Result = Ok [|1, 2, 3|] - -> Decode.fromString (list string) """["Maxime", "Alfonso", "Vesper"]""" -val it : Result = Ok ["Maxime", "Alfonso", "Vesper"] - -> Decode.fromString (Decode.index 1 Decode.string) """["maxime", "alfonso", "steffen"]""" -val it : Result = Ok("alfonso") -``` - -### Decoding Objects - -In order to decode objects, you can use: - -- `field : string -> Decoder<'value> -> Decoder<'value>` - - Decode a JSON object, requiring a particular field. -- `at : string list -> Decoder<'value> -> Decoder<'value>` - - Decode a JSON object, requiring certain path. - -```fsharp -open Thoth.Json - -> Decode.fromString (field "x" int) """{"x": 10, "y": 21}""" -val it : Result = Ok 10 - -> Decode.fromString (field "y" int) """{"x": 10, "y": 21}""" -val it : Result = Ok 21 -``` - -**Important:** - -These two decoders only take into account the provided field or path. The object can have other fields/paths with other content. - -#### Map functions - -To get data from several fields and convert them into a record you will need to use the `map` functions: -`map2`, `map3`, ..., `map8`. - -```fsharp -open Thoth.Json - -type Point = - { X : int - Y : int } - - static member Decoder : Decoder = - Decode.map2 (fun x y -> - { X = x - Y = y } : Point) - (Decode.field "x" Decode.int) - (Decode.field "y" Decode.int) - -> Decode.fromString Point.Decoder """{"x": 10, "y": 21}""" -val it : Result = Ok { X = 10; Y = 21 } -``` - -#### Object builder style - -When working with larger objects, you can use the object builder helper. - -```fsharp -open Thoth.Json - -type User = - { Id : int - Name : string - Email : string - Followers : int } - - static member Decoder : Decoder = - Decode.object - (fun get -> - { Id = get.Required.Field "id" Decode.int - Name = get.Optional.Field "name" Decode.string - |> Option.defaultValue "" - Email = get.Required.Field "email" Decode.string - Followers = 0 } - ) - -> Decode.fromString User.Decoder """{ "id": 67, "email": "user@mail.com" }""" -val it : Result = Ok { Id = 67; Name = ""; Email = "user@mail.com"; Followers = 0 } -``` - -## Encoder - -Module for turning F# values into JSON values. - -*This module is inspired by [Json.Encode from Elm](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Encode).* - -### How to use it? - -```fsharp - open Thoth.Json - - let person = - Encode.object - [ "firstname", Encode.string "maxime" - "surname", Encode.string "mangel" - "age", Encode.int 25 - "address", Encode.object - [ "street", Encode.string "main street" - "city", Encode.string "Bordeaux" ] - ] - - let compact = Encode.toString 0 person - // {"firstname":"maxime","surname":"mangel","age":25,"address":{"street":"main street","city":"Bordeaux"}} - - let readable = Encode.toString 4 person - // { - // "firstname": "maxime", - // "surname": "mangel", - // "age": 25, - // "address": { - // "street": "main street", - // "city": "Bordeaux" - // } - // } -``` - -## Auto coders - -
-
- -When using **auto coders**, we are referring to both **auto encoders** and **auto decoders**. -
-
- - -If your JSON structure is a one to one match with your F# type, then you can use auto coders. - -### Auto encoder - -Auto decoders will generate the decoder at runtime for you and still guarantee that the JSON structure is correct. - -```fsharp -> let json = """{ "Id" : 0, "Name": "maxime", "Email": "mail@domain.com", "Followers": 0 }""" -> Decode.Auto.fromString(json) -val it : Result = Ok { Id = 0; Name = "maxime"; Email = "mail@domain.com"; Followers = 0 } -``` - -`Decode.Auto` helpers accept an optional argument `isCamelCase`: - -- if `true`, then the keys in the JSON are considered `camelCase` -- if `false`, then the keys in the JSON are considered `PascalCase` - -```fsharp -> let json = """{ "id" : 0, "name": "maxime", "email": "mail@domain.com", "followers": 0 }""" -> Decode.Auto.fromString(json, isCamelCase=true) -val it : Result = Ok { Id = 0; Name = "maxime"; Email = "mail@domain.com"; Followers = 0 } -``` - -### Auto encoder - -Auto decoders will generate the encoder at runtime for you. - -```fsharp -type User = - { Id : int - Name : string - Email : string - Followers : int } - -let user = - { Id = 0 - Name = "maxime" - Email = "mail@domain.com" - Followers = 0 } - -let json = Encode.Auto.toString(4, user) -// { -// "Id": 0, -// "Name": "maxime", -// "Email": "mail@domain.com", -// "Followers": 0 -// } -``` - -### Extra coders - -When generating an auto coder, sometimes you will want to use a manual coder for a type nested in your domain hierarchy. - -In those cases you can pass **extra coders** that will replace the default (or missing) coders. Use the `Extra` module to build the map for extra coders (see example below). - -```fsharp -let myExtraCoders = - Extra.empty - |> Extra.withCustom MyType.Encode MyType.Decode -``` - -### Decoding int64, decimal or bigint - -Coders for `int64`, `decimal` or `bigint` won't be automatically generated by default. If they were, the bundle size would increase significantly even if you don't intend to use these types. - -If required, you can easily include them in your extra coders with the helpers in the `Extra` module: - -```fsharp -let myExtraCoders = - Extra.empty - |> Extra.withInt64 - |> Extra.withDecimal - |> Extra.withCustom MyType.Encode MyType.Decode -``` - -### Caching - -To avoid having to regenerate your auto coders every time you need them, you can use the helpers with the `Cached` suffix instead (please note in these cases you shouldn't change the value of extra parameters like `isCamelCase` or `extra`). - -The easiest way to do it is to include some helpers in your app to easily generate (or retrieve from cache) coders whenever you need them. For example: - -```fsharp -// Note the helpers must be inlined to resolve generic parameters in Fable -let inline encoder<'T> = Encode.Auto.generateEncoderCached<'T>(isCamelCase = true, extra = myExtraCoders) -let inline decoder<'T> = Decode.Auto.generateDecoderCached<'T>(isCamelCase = true, extra = myExtraCoders) -``` - -Now you can easily invoke the helpers whenever you need a coder. Most of the times you can omit the generic argument as it will be inferred. - -```fsharp -let demo(x : RequestType) : ResponseType = - let requestJson = encoder x |> Encode.toString 4 - let responseJson = (* Send JSON to server and receive response *) - Decode.unsafeFromString decoder responseJson -``` - -## .Net & NetCore support - -You can share your decoders and encoders **between your client and server**. - -In order to use Thoth.Json API on .Net or NetCore you need to use the `Thoth.Json.Net` package. - -### Code sample - -```fsharp -// By adding this condition, you can share your code between your client and server -#if FABLE_COMPILER -open Thoth.Json -#else -open Thoth.Json.Net -#endif - -type User = - { Id : int - Name : string - Email : string - Followers : int } - - static member Decoder : Decode.Decoder = - Decode.object - (fun get -> - { Id = get.Required.Field "id" Decode.int - Name = get.Optional.Field "name" Decode.string - |> Option.defaultValue "" - Email = get.Required.Field "email" Decode.string - Followers = 0 } - ) - - static member Encoder (user : User) = - Encode.object - [ "id", Encode.int user.Id - "name", Encode.string user.Name - "email", Encode.string user.Email - "followers", Encode.int user.Followers - ] -``` - -### Giraffe - -If you're using the [Giraffe](https://github.com/giraffe-fsharp/Giraffe) or [Saturn](https://saturnframework.org/) web servers, you can use the `Thoth.Json.Giraffe` package to enable automatic JSON serialization with Thoth in your responses. Check [how to add a custom serializer](https://github.com/giraffe-fsharp/Giraffe/blob/master/DOCUMENTATION.md#using-a-different-json-serializer) to Giraffe. - -> The `ThothSerializer` type also includes some static helpers to deal with JSON directly for request and response streams. diff --git a/docs/style.scss b/docs/style.scss deleted file mode 100644 index c5a4787..0000000 --- a/docs/style.scss +++ /dev/null @@ -1,32 +0,0 @@ -@import "./../node_modules/bulma/sass/utilities/initial-variables"; - -$primary: #2D3947; -$text: #2b2b2b; - -$navbar-item-color: $white; -$navbar-background-color: $primary; -$navbar-item-hover-color: $white; -$navbar-item-hover-background-color: lighten($primary, 8%); - -$toc-item-active-color: $primary; -$toc-item-active-font-weight: bold; - -$body-size: 14px; - -@import "./../node_modules/bulma/bulma.sass"; -@import "./../node_modules/nacara/scss/nacara.scss"; - -input[type="checkbox"], input[type="radio"] { - margin-right: .5em; -} - -// Need to underline the current TOC item because chrome doesn't handle -// font-weight: 1000 and because primary is pretty dark it doesn't work well with a small font-weight -// Underline helps working around this issue -.toc-container { - a { - &.is-active { - text-decoration: underline; - } - } -} diff --git a/global.json b/global.json index e9aac8c..d151b80 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "3.1.100" + "version": "3.1.301" } } diff --git a/nacara.js b/nacara.js deleted file mode 100644 index 3ea8668..0000000 --- a/nacara.js +++ /dev/null @@ -1,96 +0,0 @@ -const standard = require('nacara/dist/layouts/standard/Export').default; -const mdMessage = require('nacara/dist/js/utils').mdMessage; - -module.exports = { - githubURL: "https://github.com/thoth-org/Thoth.Json", - url: "https://thoth-org.github.io/", - source: "docs", - output: "docs_deploy", - baseUrl: "/Thoth.Json/", - editUrl: "https://github.com/thoth-org/Thoth.Json/edit/master/docs", - title: "Thoth.Json", - debug: true, - version: "4.1.0", - navbar: { - showVersion: true, - links: [ - { - href: "/Thoth.Json/index.html", - label: "Documentation", - icon: "fas fa-book" - }, - { - href: "/Thoth.Json/changelog.html", - label: "Changelog", - icon: "fas fa-tasks" - }, - { - href: "https://gitter.im/fable-compiler/Fable", - label: "Support", - icon: "fab fa-gitter", - isExternal: true - }, - { - href: "https://github.com/thoth-org/Thoth.Json", - icon: "fab fa-github", - isExternal: true - }, - { - href: "https://twitter.com/MangelMaxime", - icon: "fab fa-twitter", - isExternal: true, - color: "#55acee" - } - ] - }, - lightner: { - backgroundColor: "#FAFAFA", - textColor: "", - themeFile: "./paket-files/grammars/akamud/vscode-theme-onelight/themes/OneLight.json", - grammars: [ - "./paket-files/grammars/ionide/ionide-fsgrammar/grammar/fsharp.json", - ] - }, - layouts: { - default: standard.Default, - changelog: standard.Changelog, - }, - plugins: { - markdown: [ - { - path: 'markdown-it-container', - args: [ - 'warning', - mdMessage("warning") - ] - }, - { - path: 'markdown-it-container', - args: [ - 'info', - mdMessage("info") - ] - }, - { - path: 'markdown-it-container', - args: [ - 'success', - mdMessage("success") - ] - }, - { - path: 'markdown-it-container', - args: [ - 'danger', - mdMessage("danger") - ] - }, - { - path: 'nacara/dist/js/markdown-it-anchored.js' - }, - { - path: 'nacara/dist/js/markdown-it-toc.js' - } - ] - } -}; diff --git a/package.json b/package.json index f2f3309..461c028 100644 --- a/package.json +++ b/package.json @@ -2,17 +2,17 @@ "private": true, "scripts": {}, "devDependencies": { - "@babel/core": "^7.5.5", - "@babel/preset-env": "^7.5.5", - "@fortawesome/fontawesome-free": "^5.10.0", + "@babel/core": "^7.11.4", + "@babel/preset-env": "^7.11.0", + "@fortawesome/fontawesome-free": "^5.14.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", "fable-compiler": "^2.4.7", - "fable-splitter": "^2.1.10", - "mocha": "^6.2.0", - "gh-pages": "^2.1.1", + "fable-splitter": "^2.2.1", + "gh-pages": "^3.1.0", + "mocha": "^8.1.2", "nacara": "^0.2.1", - "react": "^16.9.0", - "react-dom": "^16.9.0" + "react": "^16.13.1", + "react-dom": "^16.13.1" }, "dependencies": {} } diff --git a/paket.dependencies b/paket.dependencies index e38a278..89f42af 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -1,15 +1,6 @@ -version 5.226.0 +version 5.247.3 source https://www.nuget.org/api/v2 -storage:none - -nuget Fable.Core -nuget FSharp.Core redirects:force - -group Grammars - github akamud/vscode-theme-onelight themes/OneLight.json - github ionide/ionide-fsgrammar grammar/fsharp.json - group netcorebuild source https://www.nuget.org/api/v2 framework: netstandard2.0 diff --git a/paket.lock b/paket.lock index 00eee93..1a38fc0 100644 --- a/paket.lock +++ b/paket.lock @@ -1,17 +1,5 @@ -STORAGE: NONE -NUGET - remote: https://www.nuget.org/api/v2 - Fable.Core (3.1.4) - FSharp.Core (>= 4.7) - restriction: >= netstandard2.0 - FSharp.Core (4.7) - redirects: force -GROUP Grammars -GITHUB - remote: akamud/vscode-theme-onelight - themes/OneLight.json (b6e1a53d5ed5e6bc5878fe2e77513ee5395fb4ea) - remote: ionide/ionide-fsgrammar - grammar/fsharp.json (b4f43aafa6f843707410fabe9f904ec04fa536dc) GROUP netcorebuild STORAGE: NONE RESTRICTION: == netstandard2.0 @@ -20,155 +8,143 @@ NUGET BlackFox.Fake.BuildTask (0.1.3) Fake.Core.Target (>= 5.1) FSharp.Core (>= 4.3.4) - BlackFox.VsWhere (1.0) + BlackFox.VsWhere (1.1) FSharp.Core (>= 4.2.3) - Fake.Api.GitHub (5.19) - FSharp.Core (>= 4.7) - Octokit (>= 0.36) - Fake.Core.CommandLineParsing (5.19) - FParsec (>= 1.0.3) - FSharp.Core (>= 4.7) - Fake.Core.Context (5.19) - FSharp.Core (>= 4.7) - Fake.Core.Environment (5.19) - FSharp.Core (>= 4.7) - Fake.Core.FakeVar (5.19) - Fake.Core.Context (>= 5.19) - FSharp.Core (>= 4.7) - Fake.Core.Process (5.19) - Fake.Core.Environment (>= 5.19) - Fake.Core.FakeVar (>= 5.19) - Fake.Core.String (>= 5.19) - Fake.Core.Trace (>= 5.19) - Fake.IO.FileSystem (>= 5.19) - FSharp.Core (>= 4.7) - System.Diagnostics.Process (>= 4.3) - Fake.Core.ReleaseNotes (5.19) - Fake.Core.SemVer (>= 5.19) - Fake.Core.String (>= 5.19) - FSharp.Core (>= 4.7) - Fake.Core.SemVer (5.19) - FSharp.Core (>= 4.7) - System.Runtime.Numerics (>= 4.3) - Fake.Core.String (5.19) - FSharp.Core (>= 4.7) - Fake.Core.Target (5.19) - Fake.Core.CommandLineParsing (>= 5.19) - Fake.Core.Context (>= 5.19) - Fake.Core.Environment (>= 5.19) - Fake.Core.FakeVar (>= 5.19) - Fake.Core.Process (>= 5.19) - Fake.Core.String (>= 5.19) - Fake.Core.Trace (>= 5.19) - FSharp.Control.Reactive (>= 4.2) - FSharp.Core (>= 4.7) - System.Reactive.Compatibility (>= 4.3.1) - Fake.Core.Tasks (5.19) - Fake.Core.Trace (>= 5.19) - FSharp.Core (>= 4.7) - Fake.Core.Trace (5.19) - Fake.Core.Environment (>= 5.19) - Fake.Core.FakeVar (>= 5.19) - FSharp.Core (>= 4.7) - Fake.Core.Xml (5.19) - Fake.Core.String (>= 5.19) - FSharp.Core (>= 4.7) - System.Xml.ReaderWriter (>= 4.3.1) - System.Xml.XDocument (>= 4.3) - System.Xml.XPath (>= 4.3) - System.Xml.XPath.XDocument (>= 4.3) - System.Xml.XPath.XmlDocument (>= 4.3) - Fake.DotNet.Cli (5.19) - Fake.Core.Environment (>= 5.19) - Fake.Core.Process (>= 5.19) - Fake.Core.String (>= 5.19) - Fake.Core.Trace (>= 5.19) - Fake.DotNet.MsBuild (>= 5.19) - Fake.DotNet.NuGet (>= 5.19) - Fake.IO.FileSystem (>= 5.19) - FSharp.Core (>= 4.7) + Microsoft.Win32.Registry (>= 4.7) + Fake.Api.GitHub (5.20.2) + FSharp.Core (>= 4.7.2) + Octokit (>= 0.48) + Fake.Core.CommandLineParsing (5.20.2) + FParsec (>= 1.1.1) + FSharp.Core (>= 4.7.2) + Fake.Core.Context (5.20.2) + FSharp.Core (>= 4.7.2) + Fake.Core.Environment (5.20.2) + FSharp.Core (>= 4.7.2) + Fake.Core.FakeVar (5.20.2) + Fake.Core.Context (>= 5.20.2) + FSharp.Core (>= 4.7.2) + Fake.Core.Process (5.20.2) + Fake.Core.Environment (>= 5.20.2) + Fake.Core.FakeVar (>= 5.20.2) + Fake.Core.String (>= 5.20.2) + Fake.Core.Trace (>= 5.20.2) + Fake.IO.FileSystem (>= 5.20.2) + FSharp.Core (>= 4.7.2) + System.Collections.Immutable (>= 1.7.1) + Fake.Core.ReleaseNotes (5.20.2) + Fake.Core.SemVer (>= 5.20.2) + Fake.Core.String (>= 5.20.2) + FSharp.Core (>= 4.7.2) + Fake.Core.SemVer (5.20.2) + FSharp.Core (>= 4.7.2) + Fake.Core.String (5.20.2) + FSharp.Core (>= 4.7.2) + Fake.Core.Target (5.20.2) + Fake.Core.CommandLineParsing (>= 5.20.2) + Fake.Core.Context (>= 5.20.2) + Fake.Core.Environment (>= 5.20.2) + Fake.Core.FakeVar (>= 5.20.2) + Fake.Core.Process (>= 5.20.2) + Fake.Core.String (>= 5.20.2) + Fake.Core.Trace (>= 5.20.2) + FSharp.Control.Reactive (>= 4.4) + FSharp.Core (>= 4.7.2) + Fake.Core.Tasks (5.20.2) + Fake.Core.Trace (>= 5.20.2) + FSharp.Core (>= 4.7.2) + Fake.Core.Trace (5.20.2) + Fake.Core.Environment (>= 5.20.2) + Fake.Core.FakeVar (>= 5.20.2) + FSharp.Core (>= 4.7.2) + Fake.Core.Xml (5.20.2) + Fake.Core.String (>= 5.20.2) + FSharp.Core (>= 4.7.2) + Fake.DotNet.Cli (5.20.2) + Fake.Core.Environment (>= 5.20.2) + Fake.Core.Process (>= 5.20.2) + Fake.Core.String (>= 5.20.2) + Fake.Core.Trace (>= 5.20.2) + Fake.DotNet.MSBuild (>= 5.20.2) + Fake.DotNet.NuGet (>= 5.20.2) + Fake.IO.FileSystem (>= 5.20.2) + FSharp.Core (>= 4.7.2) Mono.Posix.NETStandard (>= 1.0) Newtonsoft.Json (>= 12.0.3) - Fake.DotNet.MsBuild (5.19) - BlackFox.VsWhere (>= 1.0) - Fake.Core.Environment (>= 5.19) - Fake.Core.Process (>= 5.19) - Fake.Core.String (>= 5.19) - Fake.Core.Trace (>= 5.19) - Fake.IO.FileSystem (>= 5.19) - FSharp.Core (>= 4.7) - MSBuild.StructuredLogger (>= 2.0.152) - Fake.DotNet.NuGet (5.19) - Fake.Core.Environment (>= 5.19) - Fake.Core.Process (>= 5.19) - Fake.Core.SemVer (>= 5.19) - Fake.Core.String (>= 5.19) - Fake.Core.Tasks (>= 5.19) - Fake.Core.Trace (>= 5.19) - Fake.Core.Xml (>= 5.19) - Fake.IO.FileSystem (>= 5.19) - Fake.Net.Http (>= 5.19) - FSharp.Core (>= 4.7) + Fake.DotNet.MSBuild (5.20.2) + BlackFox.VsWhere (>= 1.1) + Fake.Core.Environment (>= 5.20.2) + Fake.Core.Process (>= 5.20.2) + Fake.Core.String (>= 5.20.2) + Fake.Core.Trace (>= 5.20.2) + Fake.IO.FileSystem (>= 5.20.2) + FSharp.Core (>= 4.7.2) + MSBuild.StructuredLogger (>= 2.1.133) + Fake.DotNet.NuGet (5.20.2) + Fake.Core.Environment (>= 5.20.2) + Fake.Core.Process (>= 5.20.2) + Fake.Core.SemVer (>= 5.20.2) + Fake.Core.String (>= 5.20.2) + Fake.Core.Tasks (>= 5.20.2) + Fake.Core.Trace (>= 5.20.2) + Fake.Core.Xml (>= 5.20.2) + Fake.IO.FileSystem (>= 5.20.2) + Fake.Net.Http (>= 5.20.2) + FSharp.Core (>= 4.7.2) Newtonsoft.Json (>= 12.0.3) - NuGet.Protocol (>= 4.9.4) - System.Net.Http (>= 4.3.4) - Fake.DotNet.Paket (5.19) - Fake.Core.Process (>= 5.19) - Fake.Core.String (>= 5.19) - Fake.Core.Trace (>= 5.19) - Fake.DotNet.Cli (>= 5.19) - Fake.IO.FileSystem (>= 5.19) - FSharp.Core (>= 4.7) - Fake.IO.FileSystem (5.19) - Fake.Core.String (>= 5.19) - FSharp.Core (>= 4.7) - System.Diagnostics.FileVersionInfo (>= 4.3) - System.IO.FileSystem.Watcher (>= 4.3) - Fake.JavaScript.Yarn (5.19) - Fake.Core.Environment (>= 5.19) - Fake.Core.Process (>= 5.19) - FSharp.Core (>= 4.7) - Fake.Net.Http (5.19) - Fake.Core.Trace (>= 5.19) - FSharp.Core (>= 4.7) - System.Net.Http (>= 4.3.4) - Fake.Tools.Git (5.19) - Fake.Core.Environment (>= 5.19) - Fake.Core.Process (>= 5.19) - Fake.Core.SemVer (>= 5.19) - Fake.Core.String (>= 5.19) - Fake.Core.Trace (>= 5.19) - Fake.IO.FileSystem (>= 5.19) - FSharp.Core (>= 4.7) - FParsec (1.1) + NuGet.Protocol (>= 5.6) + Fake.DotNet.Paket (5.20.2) + Fake.Core.Process (>= 5.20.2) + Fake.Core.String (>= 5.20.2) + Fake.Core.Trace (>= 5.20.2) + Fake.DotNet.Cli (>= 5.20.2) + Fake.IO.FileSystem (>= 5.20.2) + FSharp.Core (>= 4.7.2) + Fake.IO.FileSystem (5.20.2) + Fake.Core.String (>= 5.20.2) + FSharp.Core (>= 4.7.2) + Fake.JavaScript.Yarn (5.20.2) + Fake.Core.Environment (>= 5.20.2) + Fake.Core.Process (>= 5.20.2) + FSharp.Core (>= 4.7.2) + Fake.Net.Http (5.20.2) + Fake.Core.Trace (>= 5.20.2) + FSharp.Core (>= 4.7.2) + Fake.Tools.Git (5.20.2) + Fake.Core.Environment (>= 5.20.2) + Fake.Core.Process (>= 5.20.2) + Fake.Core.SemVer (>= 5.20.2) + Fake.Core.String (>= 5.20.2) + Fake.Core.Trace (>= 5.20.2) + Fake.IO.FileSystem (>= 5.20.2) + FSharp.Core (>= 4.7.2) + FParsec (1.1.1) FSharp.Core (>= 4.3.4) - FSharp.Control.Reactive (4.2) - FSharp.Core (>= 4.2.3) - System.Reactive (>= 4.0) - FSharp.Core (4.7) - Microsoft.Build (16.4) - Microsoft.Build.Framework (16.4) - System.Runtime.Serialization.Primitives (>= 4.1.1) - System.Threading.Thread (>= 4.0) - Microsoft.Build.Tasks.Core (16.4) - Microsoft.Build.Framework (>= 16.4) - Microsoft.Build.Utilities.Core (>= 16.4) + FSharp.Control.Reactive (4.4.1) + FSharp.Core (>= 4.7.2) + System.Reactive (>= 4.4.1) + FSharp.Core (4.7.2) + Microsoft.Build (16.6) + Microsoft.Build.Framework (16.6) + System.Security.Permissions (>= 4.7) + Microsoft.Build.Tasks.Core (16.6) + Microsoft.Build.Framework (>= 16.6) + Microsoft.Build.Utilities.Core (>= 16.6) Microsoft.Win32.Registry (>= 4.3) System.CodeDom (>= 4.4) System.Collections.Immutable (>= 1.5) - System.Linq.Parallel (>= 4.0.1) - System.Net.Http (>= 4.3.4) System.Reflection.Metadata (>= 1.6) System.Reflection.TypeExtensions (>= 4.1) System.Resources.Extensions (>= 4.6) - System.Resources.Writer (>= 4.0) + System.Security.Permissions (>= 4.7) System.Threading.Tasks.Dataflow (>= 4.9) - Microsoft.Build.Utilities.Core (16.4) - Microsoft.Build.Framework (>= 16.4) + Microsoft.Build.Utilities.Core (16.6) + Microsoft.Build.Framework (>= 16.6) Microsoft.Win32.Registry (>= 4.3) System.Collections.Immutable (>= 1.5) + System.Security.Permissions (>= 4.7) System.Text.Encoding.CodePages (>= 4.0.1) - Microsoft.NETCore.Platforms (3.1) + Microsoft.NETCore.Platforms (3.1.1) Microsoft.NETCore.Targets (3.1) Microsoft.Win32.Primitives (4.3) Microsoft.NETCore.Platforms (>= 1.1) @@ -180,105 +156,49 @@ NUGET System.Security.AccessControl (>= 4.7) System.Security.Principal.Windows (>= 4.7) Mono.Posix.NETStandard (1.0) - MSBuild.StructuredLogger (2.0.174) - Microsoft.Build (>= 15.8.166) - Microsoft.Build.Framework (>= 15.8.166) - Microsoft.Build.Tasks.Core (>= 15.8.166) - Microsoft.Build.Utilities.Core (>= 15.8.166) + MSBuild.StructuredLogger (2.1.133) + Microsoft.Build (>= 16.4) + Microsoft.Build.Framework (>= 16.4) + Microsoft.Build.Tasks.Core (>= 16.4) + Microsoft.Build.Utilities.Core (>= 16.4) + System.IO.Compression (>= 4.3) Newtonsoft.Json (12.0.3) - NuGet.Common (5.4) - NuGet.Frameworks (>= 5.4) + NuGet.Common (5.6) + NuGet.Frameworks (>= 5.6) System.Diagnostics.Process (>= 4.3) System.Threading.Thread (>= 4.3) - NuGet.Configuration (5.4) - NuGet.Common (>= 5.4) + NuGet.Configuration (5.6) + NuGet.Common (>= 5.6) System.Security.Cryptography.ProtectedData (>= 4.3) - NuGet.Frameworks (5.4) - NuGet.Packaging (5.4) + NuGet.Frameworks (5.6) + NuGet.Packaging (5.6) Newtonsoft.Json (>= 9.0.1) - NuGet.Configuration (>= 5.4) - NuGet.Versioning (>= 5.4) + NuGet.Configuration (>= 5.6) + NuGet.Versioning (>= 5.6) System.Dynamic.Runtime (>= 4.3) - NuGet.Protocol (5.4) - NuGet.Packaging (>= 5.4) + NuGet.Protocol (5.6) + NuGet.Packaging (>= 5.6) System.Dynamic.Runtime (>= 4.3) - NuGet.Versioning (5.4) - Octokit (0.36) - runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.27-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.fedora.28-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + NuGet.Versioning (5.6) + Octokit (0.48) runtime.native.System (4.3.1) Microsoft.NETCore.Platforms (>= 1.1.1) Microsoft.NETCore.Targets (>= 1.1.3) - runtime.native.System.Net.Http (4.3.1) + runtime.native.System.IO.Compression (4.3.2) Microsoft.NETCore.Platforms (>= 1.1.1) Microsoft.NETCore.Targets (>= 1.1.3) - runtime.native.System.Security.Cryptography.Apple (4.3.1) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple (>= 4.3.1) - runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.27-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.fedora.28-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.42.3-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) - runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.opensuse.42.3-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple (4.3.1) - runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - System.Buffers (4.5) + System.Buffers (4.5.1) System.CodeDom (4.7) System.Collections (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Collections.Concurrent (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Diagnostics.Tracing (>= 4.3) - System.Globalization (>= 4.3) - System.Reflection (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Collections.Immutable (1.7) - System.Memory (>= 4.5.3) + System.Collections.Immutable (1.7.1) + System.Memory (>= 4.5.4) System.Diagnostics.Debug (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Diagnostics.DiagnosticSource (4.7) - System.Memory (>= 4.5.3) - System.Diagnostics.FileVersionInfo (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Reflection.Metadata (>= 1.4.1) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.InteropServices (>= 4.3) System.Diagnostics.Process (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.Win32.Primitives (>= 4.3) @@ -301,14 +221,6 @@ NUGET System.Threading.Tasks (>= 4.3) System.Threading.Thread (>= 4.3) System.Threading.ThreadPool (>= 4.3) - System.Diagnostics.Tools (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Diagnostics.Tracing (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) System.Dynamic.Runtime (4.3) System.Collections (>= 4.3) System.Diagnostics.Debug (>= 4.3) @@ -328,23 +240,27 @@ NUGET Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Globalization.Calendars (4.3) + System.IO (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) - System.Globalization (>= 4.3) System.Runtime (>= 4.3) - System.Globalization.Extensions (4.3) + System.Text.Encoding (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.IO.Compression (4.3) Microsoft.NETCore.Platforms (>= 1.1) - System.Globalization (>= 4.3) + runtime.native.System (>= 4.3) + runtime.native.System.IO.Compression (>= 4.3) + System.Buffers (>= 4.3) + System.Collections (>= 4.3) + System.Diagnostics.Debug (>= 4.3) + System.IO (>= 4.3) System.Resources.ResourceManager (>= 4.3) System.Runtime (>= 4.3) System.Runtime.Extensions (>= 4.3) + System.Runtime.Handles (>= 4.3) System.Runtime.InteropServices (>= 4.3) - System.IO (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) System.Text.Encoding (>= 4.3) + System.Threading (>= 4.3) System.Threading.Tasks (>= 4.3) System.IO.FileSystem (4.3) Microsoft.NETCore.Platforms (>= 1.1) @@ -357,23 +273,6 @@ NUGET System.Threading.Tasks (>= 4.3) System.IO.FileSystem.Primitives (4.3) System.Runtime (>= 4.3) - System.IO.FileSystem.Watcher (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.Win32.Primitives (>= 4.3) - runtime.native.System (>= 4.3) - System.Collections (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Overlapped (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Threading.Thread (>= 4.3) System.Linq (4.3) System.Collections (>= 4.3) System.Diagnostics.Debug (>= 4.3) @@ -398,53 +297,10 @@ NUGET System.Runtime (>= 4.3) System.Runtime.Extensions (>= 4.3) System.Threading (>= 4.3) - System.Linq.Parallel (4.3) - System.Collections (>= 4.3) - System.Collections.Concurrent (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Diagnostics.Tracing (>= 4.3) - System.Linq (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Memory (4.5.3) - System.Buffers (>= 4.4) + System.Memory (4.5.4) + System.Buffers (>= 4.5.1) System.Numerics.Vectors (>= 4.4) - System.Runtime.CompilerServices.Unsafe (>= 4.5.2) - System.Net.Http (4.3.4) - Microsoft.NETCore.Platforms (>= 1.1.1) - runtime.native.System (>= 4.3) - runtime.native.System.Net.Http (>= 4.3) - runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Diagnostics.DiagnosticSource (>= 4.3) - System.Diagnostics.Tracing (>= 4.3) - System.Globalization (>= 4.3) - System.Globalization.Extensions (>= 4.3) - System.IO (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.Net.Primitives (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Security.Cryptography.Algorithms (>= 4.3) - System.Security.Cryptography.Encoding (>= 4.3) - System.Security.Cryptography.OpenSsl (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Security.Cryptography.X509Certificates (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Net.Primitives (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1.1) - Microsoft.NETCore.Targets (>= 1.1.3) - System.Runtime (>= 4.3.1) - System.Runtime.Handles (>= 4.3) + System.Runtime.CompilerServices.Unsafe (>= 4.5.3) System.Numerics.Vectors (4.5) System.ObjectModel (4.3) System.Collections (>= 4.3) @@ -452,30 +308,30 @@ NUGET System.Resources.ResourceManager (>= 4.3) System.Runtime (>= 4.3) System.Threading (>= 4.3) - System.Reactive (4.3.2) + System.Reactive (4.4.1) System.Runtime.InteropServices.WindowsRuntime (>= 4.3) - System.Threading.Tasks.Extensions (>= 4.5.3) - System.Reactive.Compatibility (4.3.2) - System.Reactive.Core (>= 4.3.2) - System.Reactive.Interfaces (>= 4.3.2) - System.Reactive.Linq (>= 4.3.2) - System.Reactive.PlatformServices (>= 4.3.2) - System.Reactive.Providers (>= 4.3.2) - System.Reactive.Core (4.3.2) - System.Reactive (>= 4.3.2) - System.Threading.Tasks.Extensions (>= 4.5.3) - System.Reactive.Interfaces (4.3.2) - System.Reactive (>= 4.3.2) - System.Threading.Tasks.Extensions (>= 4.5.3) - System.Reactive.Linq (4.3.2) - System.Reactive (>= 4.3.2) - System.Threading.Tasks.Extensions (>= 4.5.3) - System.Reactive.PlatformServices (4.3.2) - System.Reactive (>= 4.3.2) - System.Threading.Tasks.Extensions (>= 4.5.3) - System.Reactive.Providers (4.3.2) - System.Reactive (>= 4.3.2) - System.Threading.Tasks.Extensions (>= 4.5.3) + System.Threading.Tasks.Extensions (>= 4.5.4) + System.Reactive.Compatibility (4.4.1) + System.Reactive.Core (>= 4.4.1) + System.Reactive.Interfaces (>= 4.4.1) + System.Reactive.Linq (>= 4.4.1) + System.Reactive.PlatformServices (>= 4.4.1) + System.Reactive.Providers (>= 4.4.1) + System.Reactive.Core (4.4.1) + System.Reactive (>= 4.4.1) + System.Threading.Tasks.Extensions (>= 4.5.4) + System.Reactive.Interfaces (4.4.1) + System.Reactive (>= 4.4.1) + System.Threading.Tasks.Extensions (>= 4.5.4) + System.Reactive.Linq (4.4.1) + System.Reactive (>= 4.4.1) + System.Threading.Tasks.Extensions (>= 4.5.4) + System.Reactive.PlatformServices (4.4.1) + System.Reactive (>= 4.4.1) + System.Threading.Tasks.Extensions (>= 4.5.4) + System.Reactive.Providers (4.4.1) + System.Reactive (>= 4.4.1) + System.Threading.Tasks.Extensions (>= 4.5.4) System.Reflection (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) @@ -492,32 +348,25 @@ NUGET Microsoft.NETCore.Targets (>= 1.1) System.Reflection (>= 4.3) System.Runtime (>= 4.3) - System.Reflection.Metadata (1.8) - System.Collections.Immutable (>= 1.7) + System.Reflection.Metadata (1.8.1) + System.Collections.Immutable (>= 1.7.1) System.Reflection.Primitives (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) System.Reflection.TypeExtensions (4.7) - System.Resources.Extensions (4.7) - System.Memory (>= 4.5.3) + System.Resources.Extensions (4.7.1) + System.Memory (>= 4.5.4) System.Resources.ResourceManager (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Globalization (>= 4.3) System.Reflection (>= 4.3) System.Runtime (>= 4.3) - System.Resources.Writer (4.3) - System.Collections (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Text.Encoding (>= 4.3) System.Runtime (4.3.1) Microsoft.NETCore.Platforms (>= 1.1.1) Microsoft.NETCore.Targets (>= 1.1.3) - System.Runtime.CompilerServices.Unsafe (4.7) + System.Runtime.CompilerServices.Unsafe (4.7.1) System.Runtime.Extensions (4.3.1) Microsoft.NETCore.Platforms (>= 1.1.1) Microsoft.NETCore.Targets (>= 1.1.3) @@ -535,203 +384,36 @@ NUGET System.Runtime.Handles (>= 4.3) System.Runtime.InteropServices.WindowsRuntime (4.3) System.Runtime (>= 4.3) - System.Runtime.Numerics (4.3) - System.Globalization (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Serialization.Primitives (4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) System.Security.AccessControl (4.7) System.Security.Principal.Windows (>= 4.7) - System.Security.Cryptography.Algorithms (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1) - runtime.native.System.Security.Cryptography.Apple (>= 4.3.1) - runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) - System.Collections (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Runtime.Numerics (>= 4.3) - System.Security.Cryptography.Encoding (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Security.Cryptography.Cng (4.7) - System.Security.Cryptography.Csp (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - System.IO (>= 4.3) - System.Reflection (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Security.Cryptography.Algorithms (>= 4.3) - System.Security.Cryptography.Encoding (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Security.Cryptography.Encoding (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3) - System.Collections (>= 4.3) - System.Collections.Concurrent (>= 4.3) - System.Linq (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Security.Cryptography.OpenSsl (4.7) - System.Security.Cryptography.Primitives (4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Threading (>= 4.3) - System.Threading.Tasks (>= 4.3) System.Security.Cryptography.ProtectedData (4.7) System.Memory (>= 4.5.3) - System.Security.Cryptography.X509Certificates (4.3.2) - Microsoft.NETCore.Platforms (>= 1.1) - runtime.native.System (>= 4.3) - runtime.native.System.Net.Http (>= 4.3) - runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.Globalization.Calendars (>= 4.3) - System.IO (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Runtime.Numerics (>= 4.3) - System.Security.Cryptography.Algorithms (>= 4.3) - System.Security.Cryptography.Cng (>= 4.3) - System.Security.Cryptography.Csp (>= 4.3) - System.Security.Cryptography.Encoding (>= 4.3) - System.Security.Cryptography.OpenSsl (>= 4.3) - System.Security.Cryptography.Primitives (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) + System.Security.Permissions (4.7) + System.Security.AccessControl (>= 4.7) System.Security.Principal.Windows (4.7) System.Text.Encoding (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Text.Encoding.CodePages (4.7) - System.Runtime.CompilerServices.Unsafe (>= 4.7) + System.Text.Encoding.CodePages (4.7.1) + System.Runtime.CompilerServices.Unsafe (>= 4.7.1) System.Text.Encoding.Extensions (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) System.Text.Encoding (>= 4.3) - System.Text.RegularExpressions (4.3.1) - System.Collections (>= 4.3) - System.Globalization (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3.1) - System.Runtime.Extensions (>= 4.3.1) - System.Threading (>= 4.3) System.Threading (4.3) System.Runtime (>= 4.3) System.Threading.Tasks (>= 4.3) - System.Threading.Overlapped (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Handles (>= 4.3) System.Threading.Tasks (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Threading.Tasks.Dataflow (4.11) - System.Threading.Tasks.Extensions (4.5.3) - System.Runtime.CompilerServices.Unsafe (>= 4.5.2) + System.Threading.Tasks.Dataflow (4.11.1) + System.Threading.Tasks.Extensions (4.5.4) + System.Runtime.CompilerServices.Unsafe (>= 4.5.3) System.Threading.Thread (4.3) System.Runtime (>= 4.3) System.Threading.ThreadPool (4.3) System.Runtime (>= 4.3) System.Runtime.Handles (>= 4.3) - System.Xml.ReaderWriter (4.3.1) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.IO.FileSystem (>= 4.3) - System.IO.FileSystem.Primitives (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Runtime.InteropServices (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Text.Encoding.Extensions (>= 4.3) - System.Text.RegularExpressions (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Threading.Tasks.Extensions (>= 4.3) - System.Xml.XDocument (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Diagnostics.Tools (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Reflection (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Xml.ReaderWriter (>= 4.3) - System.Xml.XmlDocument (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading (>= 4.3) - System.Xml.ReaderWriter (>= 4.3) - System.Xml.XPath (4.3) - System.Collections (>= 4.3) - System.Diagnostics.Debug (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Xml.ReaderWriter (>= 4.3) - System.Xml.XPath.XDocument (4.3) - System.Diagnostics.Debug (>= 4.3) - System.Linq (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Xml.ReaderWriter (>= 4.3) - System.Xml.XDocument (>= 4.3) - System.Xml.XPath (>= 4.3) - System.Xml.XPath.XmlDocument (4.3) - System.Collections (>= 4.3) - System.Globalization (>= 4.3) - System.IO (>= 4.3) - System.Resources.ResourceManager (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Extensions (>= 4.3) - System.Threading (>= 4.3) - System.Xml.ReaderWriter (>= 4.3) - System.Xml.XmlDocument (>= 4.3) - System.Xml.XPath (>= 4.3) diff --git a/src/Decode.fs b/src/Decode.fs index 3e55753..f25e0e2 100644 --- a/src/Decode.fs +++ b/src/Decode.fs @@ -1,253 +1,139 @@ - namespace Thoth.Json -open System.Text.RegularExpressions + +open Thoth.Json.Parser +open System.Globalization [] module Decode = - open System.Globalization - open Fable.Core - open Fable.Core.JsInterop - - module internal Helpers = - [] - let jsTypeof (_ : JsonValue) : string = jsNative - - [] - let isSyntaxError (_ : JsonValue) : bool = jsNative - - let inline getField (fieldName: string) (o: JsonValue) = o?(fieldName) - let inline isString (o: JsonValue) : bool = o :? string - - let inline isBoolean (o: JsonValue) : bool = o :? bool - - let inline isNumber (o: JsonValue) : bool = jsTypeof o = "number" - - let inline isArray (o: JsonValue) : bool = JS.Constructors.Array.isArray(o) - - [] - let isObject (_ : JsonValue) : bool = jsNative - - let inline isNaN (o: JsonValue) : bool = JS.Constructors.Number.isNaN(!!o) - - let inline isNullValue (o: JsonValue): bool = isNull o - - /// is the value an integer? This returns false for 1.1, NaN, Infinite, ... - [] - let isIntegralValue (_: JsonValue) : bool = jsNative - - [] - let isBetweenInclusive(_v: JsonValue, _min: obj, _max: obj) = jsNative - - [] - let isIntFinite (_: JsonValue) : bool = jsNative - - let isUndefined (o: JsonValue): bool = jsTypeof o = "undefined" - - [] - let anyToString (_: JsonValue) : string = jsNative - - let inline isFunction (o: JsonValue) : bool = jsTypeof o = "function" - - let inline objectKeys (o: JsonValue) : string seq = upcast JS.Constructors.Object.keys(o) - let inline asBool (o: JsonValue): bool = unbox o - let inline asInt (o: JsonValue): int = unbox o - let inline asFloat (o: JsonValue): float = unbox o - let inline asFloat32 (o: JsonValue): float32 = unbox o - let inline asString (o: JsonValue): string = unbox o - let inline asArray (o: JsonValue): JsonValue[] = unbox o - - let private genericMsg msg value newLine = - try - "Expecting " - + msg - + " but instead got:" - + (if newLine then "\n" else " ") - + (Helpers.anyToString value) - with - | _ -> - "Expecting " - + msg - + " but decoder failed. Couldn't report given value due to circular structure." - + (if newLine then "\n" else " ") - - let private errorToString (path : string, error) = - let reason = - match error with - | BadPrimitive (msg, value) -> - genericMsg msg value false - | BadType (msg, value) -> - genericMsg msg value true - | BadPrimitiveExtra (msg, value, reason) -> - genericMsg msg value false + "\nReason: " + reason - | BadField (msg, value) -> - genericMsg msg value true - | BadPath (msg, value, fieldName) -> - genericMsg msg value true + ("\nNode `" + fieldName + "` is unkown.") - | TooSmallArray (msg, value) -> - "Expecting " + msg + ".\n" + (Helpers.anyToString value) - | BadOneOf messages -> - "The following errors were found:\n\n" + String.concat "\n\n" messages - | FailMessage msg -> - "The following `failure` occurred with the decoder: " + msg - - match error with - | BadOneOf _ -> - // Don't need to show the path here because each error case will show it's own path - reason - | _ -> - "Error at: `" + path + "`\n" + reason - - /////////////// - // Runners /// - ///////////// - - let fromValue (path : string) (decoder : Decoder<'T>) = - fun value -> - match decoder path value with - | Ok success -> - Ok success - | Error error -> - Error (errorToString error) - - let fromString (decoder : Decoder<'T>) = - fun value -> - try - let json = JS.JSON.parse value - fromValue "$" decoder json - with - | ex when Helpers.isSyntaxError ex -> - Error("Given an invalid JSON: " + ex.Message) - - let unsafeFromString (decoder : Decoder<'T>) = - fun value -> - match fromString decoder value with - | Ok x -> x - | Error msg -> failwith msg - - [] - let decodeValue (path : string) (decoder : Decoder<'T>) = fromValue path decoder - - [] - let decodeString (decoder : Decoder<'T>) = fromString decoder - ////////////////// // Primitives /// //////////////// let string : Decoder = - fun path value -> + fun value -> if Helpers.isString value then Ok(Helpers.asString value) else - (path, BadPrimitive("a string", value)) |> Error + ("", BadPrimitive("a string", value)) |> Error + + let char : Decoder = + fun value -> + if Helpers.isString value then + try + value |> Helpers.asString |> System.Char.Parse |> Ok + with + | _ -> + ("", BadPrimitive("a char", value)) |> Error + else + ("", BadPrimitive("a string", value)) |> Error let guid : Decoder = - fun path value -> + fun value -> if Helpers.isString value then match System.Guid.TryParse (Helpers.asString value) with | true, x -> Ok x - | _ -> (path, BadPrimitive("a guid", value)) |> Error - else (path, BadPrimitive("a guid", value)) |> Error + | _ -> ("", BadPrimitive("a guid", value)) |> Error + else ("", BadPrimitive("a guid", value)) |> Error let unit : Decoder = - fun path value -> + fun value -> if Helpers.isNullValue value then Ok () else - (path, BadPrimitive("null", value)) |> Error + ("", BadPrimitive("null", value)) |> Error let inline private integral (name : string) (tryParse : (string -> bool * 'T)) - (min : 'T) - (max : 'T) - (conv : float -> 'T) : Decoder< 'T > = + (min : unit -> 'T) + (max : unit -> 'T) + (conv : float -> 'T) : Decoder<'T > = - fun path value -> + fun value -> if Helpers.isNumber value then - let value : float = unbox value if Helpers.isIntegralValue value then - if (float min) <= value && value <= (float max) then - Ok(conv value) + let fValue = Helpers.asFloat value + if (float (min())) <= fValue && fValue <= (float (max())) then + Ok(conv fValue) else - (path, BadPrimitiveExtra(name, value, "Value was either too large or too small for " + name)) |> Error + ("", BadPrimitiveExtra(name, value, "Value was either too large or too small for " + name)) |> Error else - (path, BadPrimitiveExtra(name, value, "Value is not an integral value")) |> Error + ("", BadPrimitiveExtra(name, value, "Value is not an integral value")) |> Error elif Helpers.isString value then match tryParse (Helpers.asString value) with | true, x -> Ok x - | _ -> (path, BadPrimitive(name, value)) |> Error + | _ -> ("", BadPrimitive(name, value)) |> Error else - (path, BadPrimitive(name, value)) |> Error + ("", BadPrimitive(name, value)) |> Error - let sbyte : Decoder = + let sbyte<'JsonValue> : Decoder = integral "a sbyte" System.SByte.TryParse - System.SByte.MinValue - System.SByte.MaxValue + (fun () -> System.SByte.MinValue) + (fun () -> System.SByte.MaxValue) sbyte /// Alias to Decode.uint8 - let byte : Decoder = + let byte<'JsonValue> : Decoder = integral "a byte" System.Byte.TryParse - System.Byte.MinValue - System.Byte.MaxValue + (fun () -> System.Byte.MinValue) + (fun () -> System.Byte.MaxValue) byte - let int16 : Decoder = + let int16<'JsonValue> : Decoder = integral "an int16" System.Int16.TryParse - System.Int16.MinValue - System.Int16.MaxValue + (fun () -> System.Int16.MinValue) + (fun () -> System.Int16.MaxValue) int16 - let uint16 : Decoder = + let uint16<'JsonValue> : Decoder = integral "an uint16" System.UInt16.TryParse - System.UInt16.MinValue - System.UInt16.MaxValue + (fun () -> System.UInt16.MinValue) + (fun () -> System.UInt16.MaxValue) uint16 - let int : Decoder = + let int<'JsonValue> : Decoder = integral "an int" System.Int32.TryParse - System.Int32.MinValue - System.Int32.MaxValue + (fun () -> System.Int32.MinValue) + (fun () -> System.Int32.MaxValue) int - let uint32 : Decoder = + let uint32<'JsonValue> : Decoder = integral "an uint32" System.UInt32.TryParse - System.UInt32.MinValue - System.UInt32.MaxValue + (fun () -> System.UInt32.MinValue) + (fun () -> System.UInt32.MaxValue) uint32 - let int64 : Decoder = + let int64<'JsonValue> : Decoder = integral "an int64" System.Int64.TryParse - System.Int64.MinValue - System.Int64.MaxValue + (fun () -> System.Int64.MinValue) + (fun () -> System.Int64.MaxValue) int64 - let uint64 : Decoder = + let uint64<'JsonValue> : Decoder = integral "an uint64" System.UInt64.TryParse - System.UInt64.MinValue - System.UInt64.MaxValue + (fun () -> System.UInt64.MinValue) + (fun () -> System.UInt64.MaxValue) uint64 let bigint : Decoder = - fun path value -> + fun value -> if Helpers.isNumber value then Helpers.asInt value |> bigint |> Ok elif Helpers.isString value then @@ -256,104 +142,108 @@ module Decode = try bigint.Parse (Helpers.asString value) |> Ok with _ -> - (path, BadPrimitive("a bigint", value)) |> Error + ("", BadPrimitive("a bigint", value)) |> Error else - (path, BadPrimitive("a bigint", value)) |> Error + ("", BadPrimitive("a bigint", value)) |> Error let bool : Decoder = - fun path value -> + fun value -> if Helpers.isBoolean value then Ok(Helpers.asBool value) else - (path, BadPrimitive("a boolean", value)) |> Error + ("", BadPrimitive("a boolean", value)) |> Error let float : Decoder = - fun path value -> + fun value -> if Helpers.isNumber value then Ok(Helpers.asFloat value) else - (path, BadPrimitive("a float", value)) |> Error + ("", BadPrimitive("a float", value)) |> Error let float32 : Decoder = - fun path value -> + fun value -> if Helpers.isNumber value then Ok(Helpers.asFloat32 value) else - (path, BadPrimitive("a float32", value)) |> Error + ("", BadPrimitive("a float32", value)) |> Error let decimal : Decoder = - fun path value -> + fun value -> if Helpers.isNumber value then Helpers.asFloat value |> decimal |> Ok elif Helpers.isString value then - match System.Decimal.TryParse (Helpers.asString value) with + // Accept any culture for now + #if THOTH_JSON_NEWTONSOFT || THOTH_JSON && !FABLE_COMPILER + match System.Decimal.TryParse(Helpers.asString value, NumberStyles.Any, CultureInfo.InvariantCulture) with + #else + match System.Decimal.TryParse(Helpers.asString value) with + #endif | true, x -> Ok x - | _ -> (path, BadPrimitive("a decimal", value)) |> Error + | _ -> ("", BadPrimitive("a decimal", value)) |> Error else - (path, BadPrimitive("a decimal", value)) |> Error + ("", BadPrimitive("a decimal", value)) |> Error let datetime : Decoder = - fun path value -> + fun value -> if Helpers.isString value then match System.DateTime.TryParse (Helpers.asString value) with | true, x -> x.ToUniversalTime() |> Ok - | _ -> (path, BadPrimitive("a datetime", value)) |> Error + | _ -> ("", BadPrimitive("a datetime", value)) |> Error else - (path, BadPrimitive("a datetime", value)) |> Error + ("", BadPrimitive("a datetime", value)) |> Error let datetimeOffset : Decoder = - fun path value -> + fun value -> if Helpers.isString value then match System.DateTimeOffset.TryParse(Helpers.asString value) with | true, x -> Ok x - | _ -> (path, BadPrimitive("a datetimeoffset", value)) |> Error + | _ -> ("", BadPrimitive("a datetimeoffset", value)) |> Error else - (path, BadPrimitive("a datetime", value)) |> Error + ("", BadPrimitive("a datetime", value)) |> Error let timespan : Decoder = - fun path value -> + fun value -> if Helpers.isString value then match System.TimeSpan.TryParse(Helpers.asString value) with | true, x -> Ok x - | _ -> (path, BadPrimitive("a timespan", value)) |> Error + | _ -> ("", BadPrimitive("a timespan", value)) |> Error else - (path, BadPrimitive("a timespan", value)) |> Error + ("", BadPrimitive("a timespan", value)) |> Error ///////////////////////// // Object primitives /// /////////////////////// - let private decodeMaybeNull path (decoder : Decoder<'T>) value = - // The decoder may be an option decoder so give it an opportunity to check null values - match decoder path value with - | Ok v -> Ok(Some v) - | Error _ when Helpers.isNullValue value -> Ok None - | Error er -> Error er - let optional (fieldName : string) (decoder : Decoder<'value>) : Decoder<'value option> = - fun path value -> + fun value -> if Helpers.isObject value then let fieldValue = Helpers.getField fieldName value if Helpers.isUndefined fieldValue then Ok None - else decodeMaybeNull (path + "." + fieldName) decoder fieldValue + else + // The decoder may be an option decoder so give it an opportunity to check null values + match decoder fieldValue with + | Ok v -> Ok (Some v) + | Error _ when Helpers.isNullValue fieldValue -> Ok None + | Error er -> + Error(er |> DecoderError.prependPath ("." + fieldName)) else - Error(path, BadType("an object", value)) + Error("", BadType("an object", value)) let private badPathError fieldNames currentPath value = - let currentPath = defaultArg currentPath ("$"::fieldNames |> String.concat ".") + // IMPORTANT: The empty string is normal, this is to prefix by "." the generated path + let currentPath = defaultArg currentPath (""::fieldNames |> String.concat ".") let msg = "an object with path `" + (String.concat "." fieldNames) + "`" Error(currentPath, BadPath (msg, value, List.tryLast fieldNames |> Option.defaultValue "")) let optionalAt (fieldNames : string list) (decoder : Decoder<'value>) : Decoder<'value option> = - fun firstPath firstValue -> - ((firstPath, firstValue, None), fieldNames) + fun firstValue -> + (("", firstValue, None), fieldNames) ||> List.fold (fun (curPath, curValue, res) field -> match res with | Some _ -> curPath, curValue, res | None -> if Helpers.isNullValue curValue then - let res = badPathError fieldNames (Some curPath) firstValue - curPath, curValue, Some res + curPath, curValue, None elif Helpers.isObject curValue then let curValue = Helpers.getField field curValue curPath + "." + field, curValue, None @@ -364,22 +254,31 @@ module Decode = | _, _, Some res -> res | lastPath, lastValue, None -> if Helpers.isUndefined lastValue then Ok None - else decodeMaybeNull lastPath decoder lastValue + else + // The decoder may be an option decoder so give it an opportunity to check null values + match decoder lastValue with + | Ok v -> Ok (Some v) + | Error _ when Helpers.isNullValue lastValue -> Ok None + | Error er -> + Error(er |> DecoderError.prependPath lastPath) let field (fieldName: string) (decoder : Decoder<'value>) : Decoder<'value> = - fun path value -> + fun value -> if Helpers.isObject value then let fieldValue = Helpers.getField fieldName value if Helpers.isUndefined fieldValue then - Error(path, BadField ("an object with a field named `" + fieldName + "`", value)) + Error("", BadField ("an object with a field named `" + fieldName + "`", value)) else - decoder (path + "." + fieldName) fieldValue + match decoder fieldValue with + | Ok _ as ok -> ok + | Error er -> + Error(er |> DecoderError.prependPath ("." + fieldName)) else - Error(path, BadType("an object", value)) + Error("", BadType("an object", value)) let at (fieldNames: string list) (decoder : Decoder<'value>) : Decoder<'value> = - fun firstPath firstValue -> - ((firstPath, firstValue, None), fieldNames) + fun firstValue -> + (("", firstValue, None), fieldNames) ||> List.fold (fun (curPath, curValue, res) field -> match res with | Some _ -> curPath, curValue, res @@ -400,15 +299,18 @@ module Decode = |> function | _, _, Some res -> res | lastPath, lastValue, None -> - decoder lastPath lastValue + match decoder lastValue with + | Ok _ as ok -> ok + | Error er -> + Error(er |> DecoderError.prependPath lastPath) let index (requestedIndex: int) (decoder : Decoder<'value>) : Decoder<'value> = - fun path value -> - let currentPath = path + ".[" + (Operators.string requestedIndex) + "]" + fun value -> if Helpers.isArray value then let vArray = Helpers.asArray value if requestedIndex < vArray.Length then - decoder currentPath (vArray.[requestedIndex]) + decoder (vArray.[requestedIndex]) + |> DecoderError.prependPathToResult (".[" + (Operators.string requestedIndex) + "]") else let msg = "a longer array. Need index `" @@ -417,93 +319,86 @@ module Decode = + (vArray.Length.ToString()) + "` entries" - (currentPath, TooSmallArray(msg, value)) + ("", TooSmallArray(msg, value)) |> Error + |> DecoderError.prependPathToResult (".[" + (Operators.string requestedIndex) + "]") else - (currentPath, BadPrimitive("an array", value)) + ("", BadPrimitive("an array", value)) |> Error + |> DecoderError.prependPathToResult (".[" + (Operators.string requestedIndex) + "]") let option (decoder : Decoder<'value>) : Decoder<'value option> = - fun path value -> - if Helpers.isNullValue value then Ok None - else decoder path value |> Result.map Some + fun value -> + #if THOTH_JSON + if Helpers.isNullValue value || Helpers.isUndefined value then + Ok None + else + decoder value |> Result.map Some + #else + if Helpers.isNullValue value then + Ok None + else + decoder value |> Result.map Some + #endif + ////////////////////// // Data structure /// //////////////////// - let list (decoder : Decoder<'value>) : Decoder<'value list> = - fun path value -> + let private arrayWith expectedMsg (mapping: 'value[] -> 'result) (decoder : Decoder<'value>) : Decoder<'result> = + fun value -> if Helpers.isArray value then let mutable i = -1 let tokens = Helpers.asArray value - (Ok [], tokens) ||> Array.fold (fun acc value -> + let result = Array.zeroCreate tokens.Length + let mutable error : DecoderError option = None + + while i < tokens.Length - 1 && error.IsNone do i <- i + 1 - match acc with - | Error _ -> acc - | Ok acc -> - match decoder (path + ".[" + (i.ToString()) + "]") value with - | Error er -> Error er - | Ok value -> Ok (value::acc)) - |> Result.map List.rev + match decoder tokens.[i] with + | Ok value -> + result.[i] <- value + + | Error err -> + error <- Some (err |> DecoderError.prependPath (".[" + (i.ToString()) + "]")) + + if error.IsNone then + Ok (result |> mapping) + else + Error error.Value + else - (path, BadPrimitive ("a list", value)) + ("", BadPrimitive (expectedMsg, value)) |> Error + let list (decoder : Decoder<'value>) : Decoder<'value list> = + arrayWith "a list" List.ofArray decoder + let seq (decoder : Decoder<'value>) : Decoder<'value seq> = - fun path value -> - if Helpers.isArray value then - let mutable i = -1 - let tokens = Helpers.asArray value - (Ok (seq []), tokens) ||> Array.fold (fun acc value -> - i <- i + 1 - match acc with - | Error _ -> acc - | Ok acc -> - match decoder (path + ".[" + (i.ToString()) + "]") value with - | Error er -> Error er - | Ok value -> Ok (Seq.append [value] acc)) - |> Result.map Seq.rev - else - (path, BadPrimitive ("a seq", value)) - |> Error + arrayWith "a seq" Seq.ofArray decoder let array (decoder : Decoder<'value>) : Decoder<'value array> = - fun path value -> - if Helpers.isArray value then - let mutable i = -1 - let tokens = Helpers.asArray value - let arr = Array.zeroCreate tokens.Length - (Ok arr, tokens) ||> Array.fold (fun acc value -> - i <- i + 1 - match acc with - | Error _ -> acc - | Ok acc -> - match decoder (path + ".[" + (i.ToString()) + "]") value with - | Error er -> Error er - | Ok value -> acc.[i] <- value; Ok acc) - else - (path, BadPrimitive ("an array", value)) - |> Error + arrayWith "an array" id decoder let keys: Decoder = - fun path value -> + fun value -> if Helpers.isObject value then Helpers.objectKeys value |> List.ofSeq |> Ok else - (path, BadPrimitive ("an object", value)) + ("", BadPrimitive ("an object", value)) |> Error let keyValuePairs (decoder : Decoder<'value>) : Decoder<(string * 'value) list> = - fun path value -> - match keys path value with + fun value -> + match keys value with | Ok objectKeys -> (Ok [], objectKeys) ||> List.fold (fun acc prop -> match acc with | Error _ -> acc | Ok acc -> - match Helpers.getField prop value |> decoder path with - | Error er -> Error er + match Helpers.getField prop value |> decoder with + | Error er -> Error (er |> DecoderError.prependPath ( "." + prop)) | Ok value -> (prop, value)::acc |> Ok) |> Result.map List.rev | Error e -> Error e @@ -513,15 +408,16 @@ module Decode = //////////////////////////// let oneOf (decoders : Decoder<'value> list) : Decoder<'value> = - fun path value -> - let rec runner (decoders : Decoder<'value> list) (errors : string list) = + fun value -> + let rec runner (decoders : Decoder<'value> list) (errors : DecoderError list) = match decoders with | head::tail -> - match fromValue path head value with + match head value with | Ok v -> Ok v - | Error error -> runner tail (errors @ [error]) - | [] -> (path, BadOneOf errors) |> Error + | Error error -> + runner tail (errors @ [error]) + | [] -> ("", BadOneOf errors) |> Error runner decoders [] @@ -530,34 +426,34 @@ module Decode = //////////////////// let nil (output : 'a) : Decoder<'a> = - fun path value -> + fun value -> if Helpers.isNullValue value then Ok output else - (path, BadPrimitive("null", value)) |> Error + ("", BadPrimitive("null", value)) |> Error let value _ v = Ok v let succeed (output : 'a) : Decoder<'a> = - fun _ _ -> + fun _ -> Ok output let fail (msg: string) : Decoder<'a> = - fun path _ -> - (path, FailMessage msg) |> Error + fun _ -> + ("", FailMessage msg) |> Error - let andThen (cb: 'a -> Decoder<'b>) (decoder : Decoder<'a>) : Decoder<'b> = - fun path value -> - match decoder path value with + let andThen<'JsonValue, 'a, 'b> (cb: 'a -> Decoder<'b>) (decoder : Decoder<'a>) : Decoder<'b> = + fun value -> + match decoder value with | Error error -> Error error - | Ok result -> cb result path value + | Ok result -> cb result value let all (decoders: Decoder<'a> list): Decoder<'a list> = - fun path value -> + fun value -> let rec runner (decoders: Decoder<'a> list) (values: 'a list) = match decoders with | decoder :: tail -> - match decoder path value with + match decoder value with | Ok value -> runner tail (values @ [ value ]) | Error error -> Error error | [] -> Ok values @@ -571,8 +467,8 @@ module Decode = let map (ctor : 'a -> 'value) (d1 : Decoder<'a>) : Decoder<'value> = - fun path value -> - match d1 path value with + fun value -> + match d1 value with | Ok v1 -> Ok (ctor v1) | Error er -> Error er @@ -580,8 +476,8 @@ module Decode = (ctor : 'a -> 'b -> 'value) (d1 : Decoder<'a>) (d2 : Decoder<'b>) : Decoder<'value> = - fun path value -> - match d1 path value, d2 path value with + fun value -> + match d1 value, d2 value with | Ok v1, Ok v2 -> Ok (ctor v1 v2) | Error er,_ -> Error er | _,Error er -> Error er @@ -591,8 +487,8 @@ module Decode = (d1 : Decoder<'a>) (d2 : Decoder<'b>) (d3 : Decoder<'c>) : Decoder<'value> = - fun path value -> - match d1 path value, d2 path value, d3 path value with + fun value -> + match d1 value, d2 value, d3 value with | Ok v1, Ok v2, Ok v3 -> Ok (ctor v1 v2 v3) | Error er,_,_ -> Error er | _,Error er,_ -> Error er @@ -604,8 +500,8 @@ module Decode = (d2 : Decoder<'b>) (d3 : Decoder<'c>) (d4 : Decoder<'d>) : Decoder<'value> = - fun path value -> - match d1 path value, d2 path value, d3 path value, d4 path value with + fun value -> + match d1 value, d2 value, d3 value, d4 value with | Ok v1, Ok v2, Ok v3, Ok v4 -> Ok (ctor v1 v2 v3 v4) | Error er,_,_,_ -> Error er | _,Error er,_,_ -> Error er @@ -619,8 +515,8 @@ module Decode = (d3 : Decoder<'c>) (d4 : Decoder<'d>) (d5 : Decoder<'e>) : Decoder<'value> = - fun path value -> - match d1 path value, d2 path value, d3 path value, d4 path value, d5 path value with + fun value -> + match d1 value, d2 value, d3 value, d4 value, d5 value with | Ok v1, Ok v2, Ok v3, Ok v4, Ok v5 -> Ok (ctor v1 v2 v3 v4 v5) | Error er,_,_,_,_ -> Error er | _,Error er,_,_,_ -> Error er @@ -636,8 +532,8 @@ module Decode = (d4 : Decoder<'d>) (d5 : Decoder<'e>) (d6 : Decoder<'f>) : Decoder<'value> = - fun path value -> - match d1 path value, d2 path value, d3 path value, d4 path value, d5 path value, d6 path value with + fun value -> + match d1 value, d2 value, d3 value, d4 value, d5 value, d6 value with | Ok v1, Ok v2, Ok v3, Ok v4, Ok v5, Ok v6 -> Ok (ctor v1 v2 v3 v4 v5 v6) | Error er,_,_,_,_,_ -> Error er | _,Error er,_,_,_,_ -> Error er @@ -655,8 +551,8 @@ module Decode = (d5 : Decoder<'e>) (d6 : Decoder<'f>) (d7 : Decoder<'g>) : Decoder<'value> = - fun path value -> - match d1 path value, d2 path value, d3 path value, d4 path value, d5 path value, d6 path value, d7 path value with + fun value -> + match d1 value, d2 value, d3 value, d4 value, d5 value, d6 value, d7 value with | Ok v1, Ok v2, Ok v3, Ok v4, Ok v5, Ok v6, Ok v7 -> Ok (ctor v1 v2 v3 v4 v5 v6 v7) | Error er,_,_,_,_,_,_ -> Error er | _,Error er,_,_,_,_,_ -> Error er @@ -676,8 +572,8 @@ module Decode = (d6 : Decoder<'f>) (d7 : Decoder<'g>) (d8 : Decoder<'h>) : Decoder<'value> = - fun path value -> - match d1 path value, d2 path value, d3 path value, d4 path value, d5 path value, d6 path value, d7 path value, d8 path value with + fun value -> + match d1 value, d2 value, d3 value, d4 value, d5 value, d6 value, d7 value, d8 value with | Ok v1, Ok v2, Ok v3, Ok v4, Ok v5, Ok v6, Ok v7, Ok v8 -> Ok (ctor v1 v2 v3 v4 v5 v6 v7 v8) | Error er,_,_,_,_,_,_,_ -> Error er | _,Error er,_,_,_,_,_,_ -> Error er @@ -688,7 +584,7 @@ module Decode = | _,_,_,_,_,_,Error er,_ -> Error er | _,_,_,_,_,_,_,Error er -> Error er - let dict (decoder : Decoder<'value>) : Decoder> = + let dict<'JsonValue, 'value> (decoder : Decoder<'value>) : Decoder> = map Map.ofList (keyValuePairs decoder) ////////////////////// @@ -696,42 +592,44 @@ module Decode = //////////////////// type IRequiredGetter = - abstract Field : string -> Decoder<'a> -> 'a - abstract At : List -> Decoder<'a> -> 'a - abstract Raw : Decoder<'a> -> 'a + abstract Field : string -> Decoder<'T> -> 'T + abstract At : List -> Decoder<'T> -> 'T + abstract Raw : Decoder<'T> -> 'T type IOptionalGetter = - abstract Field : string -> Decoder<'a> -> 'a option - abstract At : List -> Decoder<'a> -> 'a option - abstract Raw : Decoder<'a> -> 'a option + abstract Field : string -> Decoder<'T> -> 'T option + abstract At : List -> Decoder<'T> -> 'T option + abstract Raw : Decoder<'T> -> 'T option type IGetters = abstract Required: IRequiredGetter abstract Optional: IOptionalGetter - let private unwrapWith (errors: ResizeArray) path (decoder: Decoder<'T>) value: 'T = - match decoder path value with + let private unwrapWith (errors: ResizeArray) (decoder: Decoder<'T>) (value: JsonValue) : 'T = + match decoder value with | Ok v -> v - | Error er -> errors.Add(er); Unchecked.defaultof<'T> + | Error er -> + er |> errors.Add + Unchecked.defaultof<'T> - type Getters<'T>(path: string, v: 'T) = + type Getters<'T>(v: JsonValue) = let mutable errors = ResizeArray() let required = { new IRequiredGetter with member __.Field (fieldName : string) (decoder : Decoder<_>) = - unwrapWith errors path (field fieldName decoder) v + unwrapWith errors (field fieldName decoder) v member __.At (fieldNames : string list) (decoder : Decoder<_>) = - unwrapWith errors path (at fieldNames decoder) v + unwrapWith errors (at fieldNames decoder) v member __.Raw (decoder: Decoder<_>) = - unwrapWith errors path decoder v } + unwrapWith errors decoder v } let optional = { new IOptionalGetter with member __.Field (fieldName : string) (decoder : Decoder<_>) = - unwrapWith errors path (optional fieldName decoder) v + unwrapWith errors (optional fieldName decoder) v member __.At (fieldNames : string list) (decoder : Decoder<_>) = - unwrapWith errors path (optionalAt fieldNames decoder) v + unwrapWith errors (optionalAt fieldNames decoder) v member __.Raw (decoder: Decoder<_>) = - match decoder path v with + match decoder v with | Ok v -> Some v | Error((_, reason) as error) -> match reason with @@ -750,16 +648,19 @@ module Decode = member __.Required = required member __.Optional = optional - let object (builder: IGetters -> 'value) : Decoder<'value> = - fun path v -> - let getters = Getters(path, v) + let object (builder: IGetters -> 'Value) : Decoder<'Value> = + fun v -> + let getters = Getters(v) let result = builder getters match getters.Errors with | [] -> Ok result | fst::_ as errors -> if errors.Length > 1 then - let errors = List.map errorToString errors - (path, BadOneOf errors) |> Error + // let errors = + // errors + // |> List.map ((DecoderError.prependPath "$") >> DecoderError.errorToStringWithPath) + + ("", BadOneOf errors) |> Error else Error fst @@ -927,42 +828,66 @@ module Decode = #if !FABLE_REPL_LIB module Enum = - let inline byte<'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #if FABLE_COMPILER + let inline byte<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #else + let byte<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #endif byte |> andThen (fun value -> LanguagePrimitives.EnumOfValue value |> succeed ) - let inline sbyte<'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #if FABLE_COMPILER + let inline sbyte<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #else + let sbyte<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #endif sbyte |> andThen (fun value -> LanguagePrimitives.EnumOfValue value |> succeed ) - let inline int16<'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #if FABLE_COMPILER + let inline int16<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #else + let int16<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #endif int16 |> andThen (fun value -> LanguagePrimitives.EnumOfValue value |> succeed ) - let inline uint16<'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #if FABLE_COMPILER + let inline uint16<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #else + let uint16<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #endif uint16 |> andThen (fun value -> LanguagePrimitives.EnumOfValue value |> succeed ) - let inline int<'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #if FABLE_COMPILER + let inline int<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #else + let int<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #endif int |> andThen (fun value -> LanguagePrimitives.EnumOfValue value |> succeed ) - let inline uint32<'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #if FABLE_COMPILER + let inline uint32<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #else + let uint32<'JsonValue, 'TEnum when 'TEnum : enum> : Decoder<'TEnum> = + #endif uint32 |> andThen (fun value -> LanguagePrimitives.EnumOfValue value @@ -976,36 +901,93 @@ module Decode = open FSharp.Reflection - // As generics are erased by Fable, let's just do an unsafe cast for performance - let inline boxDecoder (d: Decoder<'T>): BoxedDecoder = - !!d // d >> Result.map box + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + open Fable.Core + #endif - let inline unboxDecoder (d: BoxedDecoder): Decoder<'T> = - !!d // d >> Result.map unbox + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + open System.Collections.Generic + open System.Globalization + #endif - // This is used to force Fable use a generic comparer for map keys - let private toMap<'key, 'value when 'key: comparison> (xs: ('key*'value) seq) = Map.ofSeq xs - let private toSet<'key when 'key: comparison> (xs: 'key seq) = Set.ofSeq xs + type private DecoderCrate<'T>(decoder : Decoder<'T>) = + inherit BoxedDecoder() + + override __.Decode(value) = + match decoder value with + | Ok value -> Ok(box value) + | Error error -> Error error - let private autoObject (decoderInfos: (string * BoxedDecoder)[]) (path : string) (value: JsonValue) = + member __.UnboxedDecoder = decoder + + let boxDecoder (decoder : Decoder<'T>) : BoxedDecoder = + DecoderCrate(decoder) :> BoxedDecoder + + let unboxDecoder<'T> (decoder : BoxedDecoder) : Decoder<'T> = + (decoder :?> DecoderCrate<'T>).UnboxedDecoder + + let private autoObject (decoderInfos : (string * BoxedDecoder) []) (value : JsonValue) = + if (not (Helpers.isObject value)) then + ("", BadPrimitive ("an object", value)) |> Error + else + (decoderInfos, Ok []) + ||> Array.foldBack (fun (name : string, decoder : BoxedDecoder) acc -> + match acc with + | Error _ -> acc // Todo path construction here??? + | Ok result -> + Helpers.getField name value + |> decoder.BoxedDecoder + |> Result.map (fun value -> + value::result + ) + ) + + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + let private autoObjectFromKeyValue (valueDecoder: BoxedDecoder) (value: JsonValue) = if not (Helpers.isObject value) then - (path, BadPrimitive ("an object", value)) |> Error + ("", BadPrimitive ("an object", value)) |> Error else - (decoderInfos, Ok []) ||> Array.foldBack (fun (name, decoder) acc -> + (Ok [], Helpers.objectKeys(value)) + ||> Seq.fold (fun acc name -> + match acc with + | Error _ -> acc + | Ok acc -> + Helpers.getField name value + |> valueDecoder.Decode + |> function + | Error er -> Error (er |> DecoderError.prependPath ("." + name)) + | Ok v -> (name,v)::acc |> Ok + ) + #endif + + let mixedArray (msg : string) + (decoders : BoxedDecoder[]) + (values : JsonValue[]) : Result = + if decoders.Length <> values.Length then + ("", sprintf "Expected %i %s but got %i" decoders.Length msg values.Length |> FailMessage) + |> Error + else + (values, decoders, Ok []) + |||> Array.foldBack2 (fun value decoder acc -> match acc with | Error _ -> acc | Ok result -> - Helpers.getField name value - |> decoder (path + "." + name) - |> Result.map (fun v -> v::result)) + decoder.Decode value + |> Result.map (fun value -> value::result) + ) + + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + // This is used to force Fable use a generic comparer for map keys + let private toMap<'key, 'value when 'key: comparison> (xs: ('key*'value) seq) = Map.ofSeq xs + let private toSet<'key when 'key: comparison> (xs: 'key seq) = Set.ofSeq xs + #endif let inline private enumDecoder<'UnderlineType when 'UnderlineType : equality> (decoder : Decoder<'UnderlineType>) (toString : 'UnderlineType -> string) - (t: System.Type) = - - fun path value -> - match decoder path value with + (t : System.Type) = + fun value -> + match decoder value with | Ok enumValue -> System.Enum.GetValues(t) |> Seq.cast<'UnderlineType> @@ -1015,116 +997,420 @@ module Decode = System.Enum.Parse(t, toString enumValue) |> Ok | false -> - (path, BadPrimitiveExtra(t.FullName, value, "Unkown value provided for the enum")) + ("", BadPrimitiveExtra(t.FullName, value, "Unknown value provided for the enum")) |> Error - | Error msg -> - Error msg + | Error message -> + Error message - let private autoObject2 (keyDecoder: BoxedDecoder) (valueDecoder: BoxedDecoder) (path : string) (value: JsonValue) = - if not (Helpers.isObject value) then - (path, BadPrimitive ("an object", value)) |> Error - else - (Ok [], Helpers.objectKeys(value)) ||> Seq.fold (fun acc name -> - match acc with - | Error _ -> acc - | Ok acc -> - match keyDecoder path name with - | Error er -> Error er - | Ok k -> - Helpers.getField name value - |> valueDecoder (path + "." + name) - |> function - | Error er -> Error er - | Ok v -> (k,v)::acc |> Ok) + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + let private genericOption t (decoder: BoxedDecoder) = + let ucis = FSharpType.GetUnionCases(t) + fun (value: JsonValue) -> + if Helpers.isNullValue value then + Ok (FSharpValue.MakeUnion(ucis.[0], [||])) + else + decoder.Decode(value) + |> Result.map (fun value -> + FSharpValue.MakeUnion(ucis.[1], [| value |]) + ) - let private mixedArray msg (decoders: BoxedDecoder[]) (path: string) (values: JsonValue[]): Result = - if decoders.Length <> values.Length then - (path, sprintf "Expected %i %s but got %i" decoders.Length msg values.Length - |> FailMessage) |> Error - else - (values, decoders, Ok []) - |||> Array.foldBack2 (fun value decoder acc -> - match acc with - | Error _ -> acc - | Ok result -> decoder path value |> Result.map (fun v -> v::result)) - - let rec private makeUnion extra caseStrategy t name (path : string) (values: JsonValue[]) = - let uci = - FSharpType.GetUnionCases(t, allowAccessToPrivateRepresentation=true) - |> Array.tryFind (fun x -> x.Name = name) - match uci with - | None -> (path, FailMessage("Cannot find case " + name + " in " + t.FullName)) |> Error - | Some uci -> + let private genericList t (decoder: BoxedDecoder) = + fun (value: JsonValue) -> + if not (Helpers.isArray value) then + ("", BadPrimitive ("a list", value)) |> Error + else + let values = Helpers.asArray value + let ucis = FSharpType.GetUnionCases(t, allowAccessToPrivateRepresentation=true) + let empty = FSharpValue.MakeUnion(ucis.[0], [||], allowAccessToPrivateRepresentation=true) + (values, Ok empty) + ||> Seq.foldBack (fun value acc -> + match acc with + | Error _ -> acc + | Ok acc -> + match decoder.Decode(value) with + | Error er -> + Error er + + | Ok result -> + FSharpValue.MakeUnion(ucis.[1], [|result; acc|], allowAccessToPrivateRepresentation=true) + |> Ok + ) + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + let private (|StringifiableType|_|) (t: System.Type): (string->obj) option = + let fullName = t.FullName + if fullName = typeof.FullName then + Some box + elif fullName = typeof.FullName then + let ofString = t.GetConstructor([|typeof|]) + Some(fun (v: string) -> ofString.Invoke([|v|])) + else None + #endif + + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + let private toDict<'key, 'value when 'key: comparison> (xs: ('key*'value) seq) = + let dic = System.Collections.Generic.Dictionary<'key, 'value>() + for (k, v) in xs do + dic.Add(k, v) + dic + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + let private toDict (t: System.Type) (keyType: System.Type) (valueType: System.Type) (kvs: obj) = + let dic = System.Activator.CreateInstance(t) + let addMethod = t.GetMethod("Add") + let kvProps = typedefof.MakeGenericType(keyType, valueType).GetProperties() + for kv in kvs :?> System.Collections.IEnumerable do + let k = kvProps.[0].GetValue(kv) + let v = kvProps.[1].GetValue(kv) + addMethod.Invoke(dic, [|k; v|]) |> ignore + dic + #endif + + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + let private toHashSet<'key when 'key: comparison> (xs: 'key seq) = + let set = System.Collections.Generic.HashSet<'key>() + for x in xs do set.Add(x) |> ignore + set + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + let private toHashSet (t: System.Type) (xs: obj) = + let hashSet = System.Activator.CreateInstance(t) + let addMethod = t.GetMethod("Add") + for x in xs :?> System.Collections.IEnumerable do + addMethod.Invoke(hashSet, [|x|]) |> ignore + hashSet + #endif + + let rec inline private genericArray (elementType : System.Type) (decoder : BoxedDecoder) : BoxedDecoder = + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + array decoder.Decode |> boxDecoder + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + boxDecoder(fun value -> + match array decoder.BoxedDecoder value with + | Ok items -> + let result = System.Array.CreateInstance(elementType, items.Length) + for i = 0 to result.Length - 1 do + result.SetValue(items.[i], i) + Ok result + | Error error -> Error error + ) + #endif + + and inline private autoDecodeSetOrHashSet constructor caseStrategy extra (t : System.Type) = + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + let decoder = + t.GenericTypeArguments.[0] + |> autoDecoder extra caseStrategy false + fun value -> + match array decoder.Decode value with + | Error er -> Error er + | Ok ar -> constructor ar |> Ok + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + let keyType = t.GenericTypeArguments.[0] + let decoder = autoDecoder extra caseStrategy false keyType + fun value -> + match array decoder.BoxedDecoder value with + | Ok items -> + let ar = System.Array.CreateInstance(keyType, items.Length) + for i = 0 to ar.Length - 1 do + ar.SetValue(items.[i], i) + constructor t ar |> Ok + | Error er -> Error er + #endif + + and inline private autoDecodeMapOrDict constructor extra caseStrategy (t: System.Type) = + +// // The oneOf needs to be split as for NEWTONSOFT +// #if THOTH_JSON_FABLE +// let keyType = t.GenericTypeArguments.[0] +// let valueType = t.GenericTypeArguments.[1] +// let valueDecoder = autoDecoder extra caseStrategy false valueType +// let keyDecoder = autoDecoder extra caseStrategy false keyType +// +// oneOf [ +// autoObjectFromKeyValue valueDecoder +// list (tuple2 keyDecoder.Decode valueDecoder.Decode) +// ] |> map constructor +// #endif + + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + + // Ugly re-implementation of a combination of oneOf, array, etc. decoders + // oneOf is working for THOTH_JSON_FABLE because we are using obj to alias the JsonValue and others things like that + let keyType = t.GenericTypeArguments.[0] + let valueType = t.GenericTypeArguments.[1] + let valueDecoder = autoDecoder extra caseStrategy false valueType + let keyDecoder = autoDecoder extra caseStrategy false keyType + + let decoderArrayStyle = + fun (value : JsonValue) -> + if Helpers.isArray value then + let values = Helpers.asArray value + + let mutable i = -1 + let result = Array.zeroCreate values.Length + let mutable error : DecoderError option = None + + while i < values.Length - 1 && error.IsNone do + i <- i + 1 + let value = values.[i] + + if not (Helpers.isArray value) then + error <- ("", BadPrimitive ("an array", value)) |> Some + else + let kv = Helpers.asArray value + match keyDecoder.Decode(kv.[0]), valueDecoder.Decode(kv.[1]) with + | Error er, _ -> + let er = + er + |> DecoderError.prependPath ".[0]" + + error <- Some er + + | _, Error er -> + let er = + er + |> DecoderError.prependPath ".[1]" + + error <- Some er + + | Ok key, Ok value -> + result.[i] <- (key, value) + + if error.IsNone then + Ok result + else + Error error.Value + else + #if THOTH_JSON && FABLE_COMPILER + Error ("", BadPrimitive("an array", Json.Null)) + #endif + + #if THOTH_JSON_FABLE + Error ("", BadPrimitive("an array", null)) + #endif + + + + let decoderObjectStyle = + autoObjectFromKeyValue valueDecoder + + fun value -> + match decoderArrayStyle value with + | Ok value -> + value |> unbox |> constructor |> Ok + | Error errorMessage1 -> + match decoderObjectStyle value with + | Ok value -> + value |> unbox |> constructor |> Ok + | Error errorMessage2 -> + Error("", BadOneOf [ errorMessage1; errorMessage2 ]) + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + let keyType = t.GenericTypeArguments.[0] + let valueType = t.GenericTypeArguments.[1] + let valueDecoder = autoDecoder extra caseStrategy false valueType + let keyDecoder = autoDecoder extra caseStrategy false keyType + let tupleType = typedefof.MakeGenericType([|keyType; valueType|]) + let listType = typedefof< ResizeArray >.MakeGenericType([|tupleType|]) + let addMethod = listType.GetMethod("Add") + fun (value: JsonValue) -> + let empty = System.Activator.CreateInstance(listType) + let kvs = + if Helpers.isArray value then + (Ok empty, Helpers.asArray value) ||> Seq.fold (fun acc value -> + match acc with + | Error _ -> acc + | Ok acc -> + if not (Helpers.isArray value) then + ("", BadPrimitive ("an array", value)) |> Error + else + let kv = Helpers.asArray value + match keyDecoder.Decode(kv.[0]), valueDecoder.Decode(kv.[1]) with + | Error er, _ -> + er + |> DecoderError.prependPath ".[0]" + |> Error + | _, Error er -> + er + |> DecoderError.prependPath ".[1]" + |> Error + | Ok key, Ok value -> + addMethod.Invoke(acc, [|FSharpValue.MakeTuple([|key; value|], tupleType)|]) |> ignore + Ok acc) + else + match keyType with + | StringifiableType ofString when Helpers.isObject value -> + (Ok empty, Helpers.objectKeyValues value) + ||> Seq.fold (fun acc (propertyName, propertyValue) -> + match acc with + | Error _ -> acc + | Ok acc -> + match valueDecoder.Decode(propertyValue) with + | Error er -> + er + |> DecoderError.prependPath ("." + propertyName) + |> Error + + | Ok v -> + addMethod.Invoke(acc, [|FSharpValue.MakeTuple([|ofString propertyName; v|], tupleType)|]) |> ignore + Ok acc) + | _ -> + ("", BadPrimitive ("an array or an object", value)) |> Error + kvs |> Result.map (constructor t keyType valueType) + #endif + + and inline private handleRecord (extra : Map>) + (caseStrategy : CaseStrategy) + (t : System.Type) : BoxedDecoder = + let decoders = + FSharpType.GetRecordFields(t, allowAccessToPrivateRepresentation = true) + |> Array.map (fun fieldInfo -> + let name = Util.Casing.convert caseStrategy fieldInfo.Name + name, autoDecoder extra caseStrategy false fieldInfo.PropertyType + ) + + boxDecoder(fun value -> + autoObject decoders value + |> Result.map (fun values -> + FSharpValue.MakeRecord(t, List.toArray values, allowAccessToPrivateRepresentation = true) + ) + ) + + and inline private makeUnion (extra : Map>) + (caseStrategy : CaseStrategy) + (t : System.Type) + (unionCasesInfo : UnionCaseInfo []) + (name :string) + (values : JsonValue []) = + let unionCaseInfo = + #if THOTH_JSON_NEWTONSOFT && !NETFRAMEWORK || THOTH_JSON && !FABLE_COMPILER + match t with + | Util.StringEnum attributeType -> + unionCasesInfo + |> Array.tryFind (fun unionCaseInfo -> + match unionCaseInfo with + | Util.CompiledName compiledName -> + compiledName = name + | _ -> + match attributeType.ConstructorArguments with + | Util.LowerFirst -> + let adaptedName = unionCaseInfo.Name.[..0].ToLowerInvariant() + unionCaseInfo.Name.[1..] + adaptedName = name + | Util.Forward -> + unionCaseInfo.Name = name + ) + | _ -> + #endif + unionCasesInfo + |> Array.tryFind (fun unionCaseInfo -> + unionCaseInfo.Name = name + ) + + match unionCaseInfo with + | None -> + ("", FailMessage("Cannot find case " + name + " in " + t.FullName)) |> Error + + | Some unionCaseInfo -> if values.Length = 0 then - FSharpValue.MakeUnion(uci, [||], allowAccessToPrivateRepresentation=true) |> Ok + FSharpValue.MakeUnion(unionCaseInfo, [||], allowAccessToPrivateRepresentation = true) |> Ok + else + let decoders = + unionCaseInfo.GetFields() + |> Array.map (fun fieldInfo -> + autoDecoder extra caseStrategy false fieldInfo.PropertyType + ) + + mixedArray "union field" decoders values + |> Result.map (fun values -> + FSharpValue.MakeUnion(unionCaseInfo, List.toArray values, allowAccessToPrivateRepresentation = true) + ) + + and inline private handleUnion (extra : Map>) + (caseStrategy : CaseStrategy) + (t : System.Type) : BoxedDecoder = + let unionCasesInfo = FSharpType.GetUnionCases(t, allowAccessToPrivateRepresentation = true) + + let standardUnionCaseBehaviourDecoder value = + if Helpers.isString value then + let name = Helpers.asString value + makeUnion extra caseStrategy t unionCasesInfo name [||] + else if Helpers.isArray value then + let values = Helpers.asArray value + let name = Helpers.asString values.[0] + makeUnion extra caseStrategy t unionCasesInfo name values.[1..] else - let decoders = uci.GetFields() |> Array.map (fun fi -> autoDecoder extra caseStrategy false fi.PropertyType) - mixedArray "union fields" decoders path values - |> Result.map (fun values -> FSharpValue.MakeUnion(uci, List.toArray values, allowAccessToPrivateRepresentation=true)) + ("", BadPrimitive("a string or an array", value)) |> Error + + oneOf [ + fun value -> + match unionCasesInfo.Length with + // Single union case + | 1 -> + let unionCaseInfo = unionCasesInfo.[0] + let propertyInfo = unionCaseInfo.GetFields().[0] + let decoder = autoDecoder extra caseStrategy false propertyInfo.PropertyType + decoder.Decode value + |> Result.map (fun value -> + FSharpValue.MakeUnion(unionCaseInfo, [| value |], allowAccessToPrivateRepresentation = true) + ) + + // Standard union case + | _ -> + standardUnionCaseBehaviourDecoder value - and private autoDecodeRecordsAndUnions extra (caseStrategy : CaseStrategy) (isOptional : bool) (t: System.Type) : BoxedDecoder = + standardUnionCaseBehaviourDecoder + ] |> boxDecoder + + and inline private autoDecodeRecordAndUnions (extra : Map>) + (caseStrategy : CaseStrategy) + (isOptional : bool) + (t : System.Type) : BoxedDecoder = // Add the decoder to extra in case one of the fields is recursive let decoderRef = ref Unchecked.defaultof<_> let extra = extra |> Map.add t.FullName decoderRef let decoder = - if FSharpType.IsRecord(t, allowAccessToPrivateRepresentation=true) then - let decoders = - FSharpType.GetRecordFields(t, allowAccessToPrivateRepresentation=true) - |> Array.map (fun fi -> - let name = Util.Casing.convert caseStrategy fi.Name - name, autoDecoder extra caseStrategy false fi.PropertyType) - fun path value -> - autoObject decoders path value - |> Result.map (fun xs -> FSharpValue.MakeRecord(t, List.toArray xs, allowAccessToPrivateRepresentation=true)) - - elif FSharpType.IsUnion(t, allowAccessToPrivateRepresentation=true) then - fun path (value: JsonValue) -> - if Helpers.isString(value) then - let name = Helpers.asString value - makeUnion extra caseStrategy t name path [||] - elif Helpers.isArray(value) then - let values = Helpers.asArray value - let name = Helpers.asString values.[0] - makeUnion extra caseStrategy t name path values.[1..] - else (path, BadPrimitive("a string or array", value)) |> Error - + if FSharpType.IsRecord(t, allowAccessToPrivateRepresentation = true) then + handleRecord extra caseStrategy t + else if FSharpType.IsUnion(t, allowAccessToPrivateRepresentation = true) then + handleUnion extra caseStrategy t + else if isOptional then + // The error will only happen at runtime if the value is not null + // See https://github.com/MangelMaxime/Thoth/pull/84#issuecomment-444837773 + boxDecoder (fun value -> + Error("", BadType("an extra coder for " + t.FullName, value)) + ) else - if isOptional then - // The error will only happen at runtime if the value is not null - // See https://github.com/MangelMaxime/Thoth/pull/84#issuecomment-444837773 - boxDecoder(fun path value -> Error(path, BadType("an extra coder for " + t.FullName, value))) - else - // Don't use failwithf here, for some reason F#/Fable compiles it as a function - // when the return type is a function too, so it doesn't fail immediately - sprintf "Cannot generate auto decoder for %s. Please pass an extra decoder." t.FullName |> failwith + failwithf "Cannot generate auto decoder for %s. Please pass an extra decoder." t.FullName + decoderRef := decoder decoder - and private autoDecoder (extra: Map>) caseStrategy (isOptional : bool) (t: System.Type) : BoxedDecoder = - let fullname = t.FullName - match Map.tryFind fullname extra with - | Some decoderRef -> fun path value -> decoderRef.contents path value - | None -> - if t.IsArray then - let decoder = t.GetElementType() |> autoDecoder extra caseStrategy false - array decoder |> boxDecoder - elif t.IsEnum then - let enumType = System.Enum.GetUnderlyingType(t).FullName - if enumType = typeof.FullName then - enumDecoder sbyte Operators.string t |> boxDecoder - elif enumType = typeof.FullName then - enumDecoder byte Operators.string t |> boxDecoder - elif enumType = typeof.FullName then - enumDecoder int16 Operators.string t |> boxDecoder - elif enumType = typeof.FullName then - enumDecoder uint16 Operators.string t |> boxDecoder - elif enumType = typeof.FullName then - enumDecoder int Operators.string t |> boxDecoder - elif enumType = typeof.FullName then - enumDecoder uint32 Operators.string t |> boxDecoder - else - failwithf - """Cannot generate auto decoder for %s. + and inline private handleEnum (t : System.Type) = + let enumType = System.Enum.GetUnderlyingType(t).FullName + if enumType = typeof.FullName then + enumDecoder sbyte Operators.string t |> boxDecoder + else if enumType = typeof.FullName then + enumDecoder byte Operators.string t |> boxDecoder + else if enumType = typeof.FullName then + enumDecoder int16 Operators.string t |> boxDecoder + else if enumType = typeof.FullName then + enumDecoder uint16 Operators.string t |> boxDecoder + else if enumType = typeof.FullName then + enumDecoder int Operators.string t |> boxDecoder + else if enumType = typeof.FullName then + enumDecoder uint32 Operators.string t |> boxDecoder + else + failwithf + """Cannot generate auto decoder for %s. Thoth.Json.Net only support the folluwing enum types: - sbyte - byte @@ -1133,114 +1419,280 @@ Thoth.Json.Net only support the folluwing enum types: - int - uint32 If you can't use one of these types, please pass an extra decoder. - """ t.FullName - elif t.IsGenericType then - if FSharpType.IsTuple(t) then - let decoders = FSharpType.GetTupleElements(t) |> Array.map (autoDecoder extra caseStrategy false) - fun path value -> - if Helpers.isArray value then - mixedArray "tuple elements" decoders path (Helpers.asArray value) - |> Result.map (fun xs -> FSharpValue.MakeTuple(List.toArray xs, t)) - else (path, BadPrimitive ("an array", value)) |> Error + """ t.FullName + + and inline private handleTuple (extra : Map>) + (caseStrategy : CaseStrategy) + (t : System.Type) : BoxedDecoder = + let decoders = + FSharpType.GetTupleElements(t) + |> Array.map (autoDecoder extra caseStrategy false) + boxDecoder(fun value -> + if Helpers.isArray value then + mixedArray "tuple elements" decoders (Helpers.asArray value) + |> Result.map (fun xs -> FSharpValue.MakeTuple(List.toArray xs, t)) else - let fullname = t.GetGenericTypeDefinition().FullName - if fullname = typedefof.FullName then - t.GenericTypeArguments.[0] |> (autoDecoder extra caseStrategy true) |> option |> boxDecoder - elif fullname = typedefof.FullName then - t.GenericTypeArguments.[0] |> (autoDecoder extra caseStrategy false) |> list |> boxDecoder - // Disable seq support because I don't know how to implement it on Thoth.Json.Net side - // elif fullname = typedefof.FullName then - // t.GenericTypeArguments.[0] |> (autoDecoder extra caseStrategy false) |> seq |> boxDecoder - elif fullname = typedefof< Map >.FullName then - let keyDecoder = t.GenericTypeArguments.[0] |> autoDecoder extra caseStrategy false - let valueDecoder = t.GenericTypeArguments.[1] |> autoDecoder extra caseStrategy false - oneOf [ - autoObject2 keyDecoder valueDecoder - list (tuple2 keyDecoder valueDecoder) - ] |> map (fun ar -> toMap (unbox ar) |> box) - elif fullname = typedefof< Set >.FullName then - let decoder = t.GenericTypeArguments.[0] |> autoDecoder extra caseStrategy false - fun path value -> - match array decoder path value with - | Error er -> Error er - | Ok ar -> toSet (unbox ar) |> box |> Ok + ("", BadPrimitive ("an array", value)) |> Error + ) + + and inline private handleGeneric (extra : Map>) + (caseStrategy : CaseStrategy) + (isOptional : bool) + (t : System.Type) : BoxedDecoder = + let fullName = t.GetGenericTypeDefinition().FullName + if fullName = typedefof.FullName then + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + let decoder = autoDecoder extra caseStrategy true t.GenericTypeArguments.[0] + + option decoder.Decode + |> boxDecoder + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + autoDecoder extra caseStrategy true t.GenericTypeArguments.[0] + |> genericOption t + |> boxDecoder + #endif + else if fullName = typedefof.FullName then + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + let decoder = autoDecoder extra caseStrategy false t.GenericTypeArguments.[0] + list decoder.Decode + |> boxDecoder + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + autoDecoder extra caseStrategy false t.GenericTypeArguments.[0] + |> genericList t + |> boxDecoder + #endif + else if fullName = typedefof.FullName then + let elemType = t.GenericTypeArguments.[0] + autoDecoder extra caseStrategy false elemType + |> genericArray elemType + else if fullName = typedefof>.FullName then + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + autoDecodeMapOrDict (fun ar -> toMap (unbox ar) |> box) extra caseStrategy t + |> boxDecoder + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + autoDecodeMapOrDict (fun t _ _ kvs -> System.Activator.CreateInstance(t, kvs)) extra caseStrategy t + |> boxDecoder + #endif + else if fullName = typedefof>.FullName then + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + autoDecodeMapOrDict (fun ar -> + // For generic keys, Fable creates a structure with a custom equality comparer. + // Deal with string keys separately to let Fable generate native JS Maps + if t.GenericTypeArguments.[0].FullName = typeof.FullName then + let dic = System.Collections.Generic.Dictionary() + for (k, v) in (unbox ar) do dic.Add(k, v) + box dic else - autoDecodeRecordsAndUnions extra caseStrategy isOptional t + toDict (unbox ar) |> box + ) extra caseStrategy t + |> boxDecoder + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + autoDecodeMapOrDict toDict extra caseStrategy t + |> boxDecoder + #endif + else if fullName = typedefof>.FullName then + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + autoDecodeSetOrHashSet (fun arr -> toSet (unbox arr) |> box) caseStrategy extra t + |> boxDecoder + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + autoDecodeSetOrHashSet (fun t kvs -> System.Activator.CreateInstance(t, kvs)) caseStrategy extra t + |> boxDecoder + #endif + else if fullName = typedefof>.FullName then + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + autoDecodeSetOrHashSet (fun arr -> toHashSet (unbox arr) |> box) caseStrategy extra t + |> boxDecoder + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + autoDecodeSetOrHashSet toHashSet caseStrategy extra t + |> boxDecoder + #endif else - if fullname = typeof.FullName then + autoDecodeRecordAndUnions extra caseStrategy isOptional t + + and private autoDecoder (extra : Map>) + (caseStrategy : CaseStrategy) + (isOptional : bool) + (t : System.Type) : BoxedDecoder = + let fullName = t.FullName + match Map.tryFind fullName extra with + | Some decoderRef -> + boxDecoder(fun value -> decoderRef.contents.BoxedDecoder value) + | None -> + if t.IsArray then + let elementType = t.GetElementType() + autoDecoder extra caseStrategy false elementType + |> genericArray elementType + else if t.IsEnum then + handleEnum t + else if FSharpType.IsTuple(t) then + handleTuple extra caseStrategy t + else if t.IsGenericType then + handleGeneric extra caseStrategy isOptional t + else if fullName = typeof.FullName then boxDecoder bool - elif fullname = typedefof.FullName then + else if fullName = typeof.FullName then + boxDecoder char + else if fullName = typedefof.FullName then boxDecoder unit - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder string - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder sbyte - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder byte - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder int16 - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder uint16 - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder int - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder uint32 - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder float - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder float32 - // These number types require extra libraries in Fable. To prevent penalizing - // all users, extra decoders (withInt64, etc) must be passed when they're needed. - - // elif fullname = typeof.FullName then - // boxDecoder int64 - // elif fullname = typeof.FullName then - // boxDecoder uint64 - // elif fullname = typeof.FullName then - // boxDecoder bigint - // elif fullname = typeof.FullName then - // boxDecoder decimal - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder datetime - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder datetimeOffset - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder timespan - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxDecoder guid - elif fullname = typeof.FullName then - fun _ v -> Ok v - else autoDecodeRecordsAndUnions extra caseStrategy isOptional t + // Allows to decode null values + else if fullName = typeof.FullName then + boxDecoder (fun value -> + #if (THOTH_JSON && FABLE_COMPILER) + if Helpers.isNullValue value then + Ok(null : obj) + else + Ok(box value) + #endif + + #if THOTH_JSON_FABLE + Ok value + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + if Helpers.isNullValue value then + Ok(null: obj) + else + #if THOTh_JSON_NEWTONSOFT + value.Value() |> Ok + #endif + + #if (THOTH_JSON && !FABLE_COMPILER) + Ok(box value) + #endif + #endif + ) + else + autoDecodeRecordAndUnions extra caseStrategy isOptional t let private makeExtra (extra: ExtraCoders option) = match extra with | None -> Map.empty | Some e -> Map.map (fun _ (_,dec) -> ref dec) e.Coders - type Auto = - static member generateDecoderCached<'T>(?caseStrategy : CaseStrategy, ?extra: ExtraCoders, [] ?resolver: ITypeResolver<'T>): Decoder<'T> = - let t = Util.resolveType resolver - let caseStrategy = defaultArg caseStrategy PascalCase + module Auto = - let key = - t.FullName - |> (+) (Operators.string caseStrategy) - |> (+) (extra |> Option.map (fun e -> e.Hash) |> Option.defaultValue "") + /// This API is only implemented inside Thoth.Json.Net for now + /// The goal of this API is to provide better interop when consuming Thoth.Json.Net from a C# project + type LowLevel = + /// ATTENTION: Use this only when other arguments (isCamelCase, extra) don't change + static member generateDecoderCached<'T> (t:System.Type, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders): Decoder<'T> = + let caseStrategy = defaultArg caseStrategy PascalCase - Util.CachedDecoders.GetOrAdd(key, fun _ -> - autoDecoder (makeExtra extra) caseStrategy false t) |> unboxDecoder + let key = + t.FullName + |> (+) (Operators.string caseStrategy) + |> (+) (extra |> Option.map (fun e -> e.Hash) |> Option.defaultValue "") - static member generateDecoder<'T>(?caseStrategy : CaseStrategy, ?extra: ExtraCoders, [] ?resolver: ITypeResolver<'T>): Decoder<'T> = - let caseStrategy = defaultArg caseStrategy PascalCase - Util.resolveType resolver - |> autoDecoder (makeExtra extra) caseStrategy false |> unboxDecoder + let decoderCrate = + Cache.Decoders.Value.GetOrAdd(key, fun _ -> + autoDecoder (makeExtra extra) caseStrategy false t) + + fun value -> + match decoderCrate.Decode(value) with + | Ok x -> Ok(x :?> 'T) + | Error er -> Error er - static member fromString<'T>(json: string, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders, [] ?resolver: ITypeResolver<'T>): Result<'T, string> = + static member generateDecoder<'T> (t: System.Type, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders): Decoder<'T> = + let caseStrategy = defaultArg caseStrategy PascalCase + let decoderCrate = autoDecoder (makeExtra extra) caseStrategy false t + fun value -> + match decoderCrate.Decode(value) with + | Ok x -> Ok(x :?> 'T) + | Error er -> Error er + + static member fromString<'T>(json: string, t: System.Type, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders): Result<'T, string> = + let decoder = LowLevel.generateDecoder(t, ?caseStrategy=caseStrategy, ?extra=extra) + Decode.fromString decoder json + + type Auto = + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + /// ATTENTION: Use this only when other arguments (isCamelCase, extra) don't change + static member generateDecoderCached<'T> (?caseStrategy : CaseStrategy, ?extra: ExtraCoders, [] ?resolver : ITypeResolver<'T>): Decoder<'T> = + let t = resolver.Value.ResolveType() + Auto.LowLevel.generateDecoderCached (t, ?caseStrategy = caseStrategy, ?extra = extra) + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + /// ATTENTION: Use this only when other arguments (isCamelCase, extra) don't change + static member generateDecoderCached<'T> (?caseStrategy : CaseStrategy, ?extra: ExtraCoders): Decoder<'T> = + let t = typeof<'T> + Auto.LowLevel.generateDecoderCached (t, ?caseStrategy = caseStrategy, ?extra = extra) + #endif + + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + static member generateDecoder<'T> (?caseStrategy : CaseStrategy, ?extra: ExtraCoders, [] ?resolver : ITypeResolver<'T>): Decoder<'T> = + let t = resolver.Value.ResolveType() + Auto.LowLevel.generateDecoder(t, ?caseStrategy = caseStrategy, ?extra = extra) + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + static member generateDecoder<'T> (?caseStrategy : CaseStrategy, ?extra: ExtraCoders): Decoder<'T> = + let t = typeof<'T> + Auto.LowLevel.generateDecoder(t, ?caseStrategy = caseStrategy, ?extra = extra) + #endif + + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + static member fromString<'T>(json: string, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders, [] ?resolver : ITypeResolver<'T>): Result<'T, string> = let decoder = Auto.generateDecoder(?caseStrategy=caseStrategy, ?extra=extra, ?resolver=resolver) - fromString decoder json + Decode.fromString decoder json + #endif - static member unsafeFromString<'T>(json: string, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders, [] ?resolver: ITypeResolver<'T>): 'T = + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + static member fromString<'T>(json: string, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders): Result<'T, string> = + let decoder = Auto.generateDecoder(?caseStrategy=caseStrategy, ?extra=extra) + Decode.fromString decoder json + #endif + + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) + static member unsafeFromString<'T>(json: string, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders, [] ?resolver : ITypeResolver<'T>): 'T = let decoder = Auto.generateDecoder(?caseStrategy=caseStrategy, ?extra=extra, ?resolver=resolver) - match fromString decoder json with - | Ok x -> x + match Decode.fromString decoder json with + | Ok v -> v + | Error msg -> failwith msg + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + static member unsafeFromString<'T>(json: string, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders): 'T = + let decoder = Auto.generateDecoder(?caseStrategy=caseStrategy, ?extra=extra) + match Decode.fromString decoder json with + | Ok v -> v | Error msg -> failwith msg + #endif diff --git a/src/Encode.fs b/src/Encode.fs index 1bb9779..efe09eb 100644 --- a/src/Encode.fs +++ b/src/Encode.fs @@ -1,16 +1,24 @@ namespace Thoth.Json -open System.Text.RegularExpressions + +open System.Text +open Thoth.Json.Parser [] module Encode = open System.Collections.Generic open System.Globalization + + open Fable.Core + + #if FABLE_COMPILER open Fable.Core open Fable.Core.JsInterop + #endif - [] - let private arrayFrom(x: JsonValue seq): JsonValue = jsNative + #if !FABLE_COMPILER + open System.IO + #endif ///**Description** /// Encode a string @@ -23,8 +31,17 @@ module Encode = /// ///**Exceptions** /// - let inline string (value : string) : JsonValue = - box value + let string (value : string) : JsonValue = + // If the string is null we represent it using null + // This is similar to what the other runtime do, THOTH_JSON parser is more strict by default + // so we need mix a bit of the Parser logic with the decoder + if value = null then + Json.Null + else + value |> Json.String + + let char (value : char) : JsonValue = + (Operators.string value) |> Json.String ///**Description** /// Encode a GUID @@ -38,7 +55,7 @@ module Encode = ///**Exceptions** /// let guid (value : System.Guid) : JsonValue = - box (value.ToString()) + value.ToString() |> Json.String ///**Description** /// Encode a Float. `Infinity` and `NaN` are encoded as `null`. @@ -52,10 +69,11 @@ module Encode = ///**Exceptions** /// let inline float (value : float) : JsonValue = - box value + value |> Json.Number - let inline float32 (value : float32) : JsonValue = - box value + let float32 (value : float32) : JsonValue = + // I think we are loosing some precision here + Operators.float value |> Json.Number ///**Description** /// Encode a Decimal. @@ -69,7 +87,7 @@ module Encode = ///**Exceptions** /// let decimal (value : decimal) : JsonValue = - value.ToString() |> string + value.ToString(CultureInfo.InvariantCulture) |> Json.String ///**Description** /// Encode null @@ -82,7 +100,7 @@ module Encode = ///**Exceptions** /// let nil : JsonValue = - box null + Json.Null ///**Description** /// Encode a bool @@ -94,8 +112,8 @@ module Encode = /// ///**Exceptions** /// - let inline bool (value : bool) : JsonValue = - box value + let bool (value : bool) : JsonValue = + Json.Bool value ///**Description** /// Encode an object @@ -109,10 +127,9 @@ module Encode = ///**Exceptions** /// let object (values : (string * JsonValue) seq) : JsonValue = - let o = obj() - for (key, value) in values do - o?(key) <- value - box o + values + |> Map.ofSeq + |> Json.Object ///**Description** /// Encode an array @@ -125,8 +142,8 @@ module Encode = /// ///**Exceptions** /// - let inline array (values : JsonValue array) : JsonValue = - box values + let array (values : JsonValue array) : JsonValue = + Json.Array values ///**Description** /// Encode a list @@ -139,11 +156,10 @@ module Encode = ///**Exceptions** /// let list (values : JsonValue list) : JsonValue = - // Don't use List.toArray as it may create a typed array - arrayFrom values + values |> List.toArray |> Json.Array let seq (values : JsonValue seq) : JsonValue = - arrayFrom values + values |> Seq.toArray |> Json.Array ///**Description** /// Encode a dictionary @@ -161,7 +177,22 @@ module Encode = |> object let bigint (value : bigint) : JsonValue = - box (value.ToString()) + value.ToString(CultureInfo.InvariantCulture) |> Json.String + + /// **Description** + /// + /// The DateTime is always encoded using UTC representation + /// + /// **Parameters** + /// * `value` - parameter of type `System.DateTime` + /// + /// **Output Type** + /// * `Value` + /// + /// **Exceptions** + /// + let datetime (value : System.DateTime) : JsonValue = + value.ToString("O", CultureInfo.InvariantCulture) |> string let datetimeOffset (value : System.DateTimeOffset) : JsonValue = value.ToString("O", CultureInfo.InvariantCulture) |> string @@ -180,47 +211,47 @@ module Encode = value.ToString() |> string let sbyte (value : sbyte) : JsonValue = - box (value.ToString(CultureInfo.InvariantCulture)) + value.ToString(CultureInfo.InvariantCulture) |> string let byte (value : byte) : JsonValue = - box (value.ToString(CultureInfo.InvariantCulture)) + value.ToString(CultureInfo.InvariantCulture) |> string let int16 (value : int16) : JsonValue = - box (value.ToString(CultureInfo.InvariantCulture)) + value.ToString(CultureInfo.InvariantCulture) |> string let uint16 (value : uint16) : JsonValue = - box (value.ToString(CultureInfo.InvariantCulture)) + value.ToString(CultureInfo.InvariantCulture) |> string - let inline int (value : int) : JsonValue = - box value + let int (value : int) : JsonValue = + Operators.float value |> Json.Number - let inline uint32 (value : uint32) : JsonValue = - box value + let uint32 (value : uint32) : JsonValue = + Operators.float value |> Json.Number let int64 (value : int64) : JsonValue = - box (value.ToString(CultureInfo.InvariantCulture)) + value.ToString(CultureInfo.InvariantCulture) |> Json.String let uint64 (value : uint64) : JsonValue = - box (value.ToString(CultureInfo.InvariantCulture)) + value.ToString(CultureInfo.InvariantCulture) |> Json.String let unit () : JsonValue = - box null + Json.Null let tuple2 (enc1 : Encoder<'T1>) (enc2 : Encoder<'T2>) (v1, v2) : JsonValue = - box [| enc1 v1 - enc2 v2 |] + [| enc1 v1 + enc2 v2 |] |> array let tuple3 (enc1 : Encoder<'T1>) (enc2 : Encoder<'T2>) (enc3 : Encoder<'T3>) (v1, v2, v3) : JsonValue = - box [| enc1 v1 - enc2 v2 - enc3 v3 |] + [| enc1 v1 + enc2 v2 + enc3 v3 |] |> array let tuple4 (enc1 : Encoder<'T1>) @@ -228,10 +259,10 @@ module Encode = (enc3 : Encoder<'T3>) (enc4 : Encoder<'T4>) (v1, v2, v3, v4) : JsonValue = - box [| enc1 v1 - enc2 v2 - enc3 v3 - enc4 v4 |] + [| enc1 v1 + enc2 v2 + enc3 v3 + enc4 v4 |] |> array let tuple5 (enc1 : Encoder<'T1>) @@ -240,11 +271,11 @@ module Encode = (enc4 : Encoder<'T4>) (enc5 : Encoder<'T5>) (v1, v2, v3, v4, v5) : JsonValue = - box [| enc1 v1 - enc2 v2 - enc3 v3 - enc4 v4 - enc5 v5 |] + [| enc1 v1 + enc2 v2 + enc3 v3 + enc4 v4 + enc5 v5 |] |> array let tuple6 (enc1 : Encoder<'T1>) @@ -254,12 +285,12 @@ module Encode = (enc5 : Encoder<'T5>) (enc6 : Encoder<'T6>) (v1, v2, v3, v4, v5, v6) : JsonValue = - box [| enc1 v1 - enc2 v2 - enc3 v3 - enc4 v4 - enc5 v5 - enc6 v6 |] + [| enc1 v1 + enc2 v2 + enc3 v3 + enc4 v4 + enc5 v5 + enc6 v6 |] |> array let tuple7 (enc1 : Encoder<'T1>) @@ -270,13 +301,13 @@ module Encode = (enc6 : Encoder<'T6>) (enc7 : Encoder<'T7>) (v1, v2, v3, v4, v5, v6, v7) : JsonValue = - box [| enc1 v1 - enc2 v2 - enc3 v3 - enc4 v4 - enc5 v5 - enc6 v6 - enc7 v7 |] + [| enc1 v1 + enc2 v2 + enc3 v3 + enc4 v4 + enc5 v5 + enc6 v6 + enc7 v7 |] |> array let tuple8 (enc1 : Encoder<'T1>) @@ -288,15 +319,14 @@ module Encode = (enc7 : Encoder<'T7>) (enc8 : Encoder<'T8>) (v1, v2, v3, v4, v5, v6, v7, v8) : JsonValue = - box [| enc1 v1 - enc2 v2 - enc3 v3 - enc4 v4 - enc5 v5 - enc6 v6 - enc7 v7 - enc8 v8 |] - + [| enc1 v1 + enc2 v2 + enc3 v3 + enc4 v4 + enc5 v5 + enc6 v6 + enc7 v7 + enc8 v8 |] |> array //////////// // Enum /// @@ -328,21 +358,6 @@ module Encode = LanguagePrimitives.EnumToValue value |> uint32 - /// **Description** - /// - /// The DateTime is always encoded using UTC representation - /// - /// **Parameters** - /// * `value` - parameter of type `System.DateTime` - /// - /// **Output Type** - /// * `Value` - /// - /// **Exceptions** - /// - let datetime (value : System.DateTime) : JsonValue = - value.ToString("O", CultureInfo.InvariantCulture) |> string - ///**Description** /// Convert a `Value` into a prettified string. ///**Parameters** @@ -355,7 +370,16 @@ module Encode = ///**Exceptions** /// let toString (space: int) (value: JsonValue) : string = - JS.JSON.stringify(value, !!null, space) + let builder = new StringBuilder() + let format = + if space = 0 then + JsonSaveOptions.DisableFormatting + else + JsonSaveOptions.Format + + value.Write(builder, format, space) + + builder.ToString() ///**Description** /// Encode an option @@ -367,229 +391,469 @@ module Encode = /// ///**Exceptions** /// - let option (encoder : 'a -> JsonValue) = - Option.map encoder >> Option.defaultWith (fun _ -> nil) + let option (encoder : 'a -> JsonValue) (value : 'a option) = + // Replicate the behaviour of Encode.Auto when dealing with DUs + match value with + | Some value -> + tuple2 + string + encoder + ("Some", value) + + | None -> + string "None" ////////////////// // Reflection /// //////////////// open FSharp.Reflection - open Fable.Core.DynamicExtensions - - // As generics are erased by Fable, let's just do an unsafe cast for performance - let inline boxEncoder (d: Encoder<'T>): BoxedEncoder = - !!d - - let inline unboxEncoder (d: BoxedEncoder): Encoder<'T> = - !!d - let rec private autoEncodeRecordsAndUnions extra (caseStrategy : CaseStrategy) (skipNullField : bool) (t: System.Type) : BoxedEncoder = + type private EncoderCrate<'T>(enc: Encoder<'T>) = + inherit BoxedEncoder() + override __.Encode(value: obj): JsonValue = + enc (unbox value) + member __.UnboxedEncoder = enc + + let boxEncoder (d: Encoder<'T>): BoxedEncoder = + EncoderCrate(d) :> BoxedEncoder + + let unboxEncoder<'T> (d: BoxedEncoder): Encoder<'T> = + (d :?> EncoderCrate<'T>).UnboxedEncoder + + let private (|StringifiableType|_|) (t: System.Type): (obj->string) option = + let fullName = t.FullName + if fullName = typeof.FullName then + Some unbox + elif fullName = typeof.FullName then + Some(fun (v: obj) -> (v :?> System.Guid).ToString()) + else None + + let rec inline private handleRecord (extra : Map>) + (caseStrategy : CaseStrategy) + (skipNullField : bool) + (t : System.Type) : BoxedEncoder = + let setters = + FSharpType.GetRecordFields(t, allowAccessToPrivateRepresentation = true) + |> Array.map (fun propertyInfo -> + let targetKey = Util.Casing.convert caseStrategy propertyInfo.Name + let encoder : BoxedEncoder = autoEncoder extra caseStrategy skipNullField propertyInfo.PropertyType + + fun (source : obj) (res : Map) -> + let value = FSharpValue.GetRecordField(source, propertyInfo) + // Discard null value + if not skipNullField || (skipNullField && not (isNull value)) then + Map.add targetKey (encoder.Encode value) res + else + res + ) + + boxEncoder(fun (value : obj) -> + (Map.empty, setters) + ||> Array.fold (fun res set -> + set value res + ) + |> Json.Object + ) + + and inline private handleUnion (extra : Map>) + (caseStrategy : CaseStrategy) + (skipNullField : bool) + (t : System.Type) : BoxedEncoder = + boxEncoder(fun (value : obj) -> + let unionCasesInfo = FSharpType.GetUnionCases(t, allowAccessToPrivateRepresentation = true) + let info, fields = FSharpValue.GetUnionFields(value, t, allowAccessToPrivateRepresentation = true) + + match unionCasesInfo.Length with + | 1 -> + match fields.Length with + // If there is only one unionCaseInfo and no argument to it output the name of the Case + // Type: type SingleNoArguments = SingleNoArguments + // Value: let value = SingleNoArguments + // JSON: "SingleNoArguments" + | 0 -> + string info.Name + + // If there is only one unionCaseInfo and only one argument output the argument JSON representation directly + // Type: type Email = Email of string + // Value: let value = Email "mail@test.com" + // JSON: "mail@test.com" + | 1 -> + let fieldTypes = info.GetFields() + let encoder : BoxedEncoder = autoEncoder extra caseStrategy skipNullField fieldTypes.[0].PropertyType + encoder.Encode(fields.[0]) + + // If there is only one unionCaseInfo and several arguments output the arguments represented as a tuple + // Type: type User = User of string * {| Role : string; Level : int |} + // Value: let value = User ("maxime", {| Role = "Admin"; Level = 0 |} + // JSON: [ "maxime", { Role = "Admin", Level = 0 } ] + | length -> + let fieldTypes = info.GetFields() + let res = Array.zeroCreate(length) + for i = 0 to length - 1 do + let encoder : BoxedEncoder = autoEncoder extra caseStrategy skipNullField fieldTypes.[i].PropertyType + res.[i] <- encoder.Encode(fields.[i]) + array res + + | _ -> + match fields.Length with + | 0 -> + #if !NETFRAMEWORK && !FABLE_COMPILER + match t with + // Replicate Fable behaviour when using StringEnum + | Util.StringEnum t -> + match info with + | Util.CompiledName name -> string name + | _ -> + match t.ConstructorArguments with + | Util.LowerFirst -> + let name = info.Name.[..0].ToLowerInvariant() + info.Name.[1..] + string name + | Util.Forward -> string info.Name + + | _ -> string info.Name + #else + string info.Name + #endif + + | length -> + let fieldTypes = info.GetFields() + let res = Array.zeroCreate(length + 1) + res.[0] <- string info.Name + for i = 1 to length do + let encoder : BoxedEncoder = autoEncoder extra caseStrategy skipNullField fieldTypes.[i-1].PropertyType + res.[i] <- encoder.Encode(fields.[i-1]) + array res + ) + + and inline private handleRecordAndUnion (extra : Map>) + (caseStrategy : CaseStrategy) + (skipNullField : bool) + (t : System.Type) : BoxedEncoder = // Add the encoder to extra in case one of the fields is recursive let encoderRef = ref Unchecked.defaultof<_> let extra = extra |> Map.add t.FullName encoderRef + let encoder = - if FSharpType.IsRecord(t, allowAccessToPrivateRepresentation=true) then - let setters = - FSharpType.GetRecordFields(t, allowAccessToPrivateRepresentation=true) - |> Array.map (fun fi -> - let targetKey = Util.Casing.convert caseStrategy fi.Name - let encode = autoEncoder extra caseStrategy skipNullField fi.PropertyType - fun (source: obj) (target: JsonValue) -> - let value = FSharpValue.GetRecordField(source, fi) - if not skipNullField || (skipNullField && not (isNull value)) then // Discard null fields - target.[targetKey] <- encode value - target) - fun (source: obj) -> - (JsonValue(), setters) ||> Seq.fold (fun target set -> set source target) - elif FSharpType.IsUnion(t, allowAccessToPrivateRepresentation=true) then - fun (value: obj) -> - let info, fields = FSharpValue.GetUnionFields(value, t, allowAccessToPrivateRepresentation=true) - match fields.Length with - | 0 -> string info.Name - | len -> - let fieldTypes = info.GetFields() - let target = Array.zeroCreate (len + 1) - target.[0] <- string info.Name - for i = 1 to len do - let encode = autoEncoder extra caseStrategy skipNullField fieldTypes.[i-1].PropertyType - target.[i] <- encode fields.[i-1] - array target + if FSharpType.IsRecord(t, allowAccessToPrivateRepresentation = true) then + handleRecord extra caseStrategy skipNullField t + else if FSharpType.IsUnion(t, allowAccessToPrivateRepresentation = true) then + handleUnion extra caseStrategy skipNullField t else - // Don't use failwithf here, for some reason F#/Fable compiles it as a function - // when the return type is a function too, so it doesn't fail immediately - sprintf "Cannot generate auto encoder for %s. Please pass an extra encoder." t.FullName - |> failwith + failwithf "Cannot generate auto encoder for %s. Please pass an extra coder." t.FullName + encoderRef := encoder encoder - and private autoEncoder (extra: Map>) caseStrategy (skipNullField : bool) (t: System.Type) : BoxedEncoder = - let fullname = t.FullName - match Map.tryFind fullname extra with - | Some encoderRef -> fun v -> encoderRef.contents v - | None -> - if t.IsArray then - let encoder = t.GetElementType() |> autoEncoder extra caseStrategy skipNullField - fun (value: obj) -> - value :?> obj seq |> Seq.map encoder |> seq - elif t.IsEnum then - let enumType = System.Enum.GetUnderlyingType(t).FullName - if enumType = typeof.FullName then - boxEncoder sbyte - elif enumType = typeof.FullName then - boxEncoder byte - elif enumType = typeof.FullName then - boxEncoder int16 - elif enumType = typeof.FullName then - boxEncoder uint16 - elif enumType = typeof.FullName then - boxEncoder int - elif enumType = typeof.FullName then - boxEncoder uint32 - else - failwithf - """Cannot generate auto encoder for %s. -Thoth.Json.Net only support the folluwing enum types: + and inline private handleGenericSeq (encoder : BoxedEncoder) = + boxEncoder(fun (elements : obj) -> + let array = ResizeArray() + + for element in elements :?> System.Collections.IEnumerable do + array.Add(encoder.Encode element) + + array.ToArray() |> Json.Array + ) + + and inline private handleEnum (t : System.Type) (fullName : string) = + let enumType = System.Enum.GetUnderlyingType(t).FullName + if enumType = typeof.FullName then + boxEncoder sbyte + else if enumType = typeof.FullName then + boxEncoder byte + else if enumType = typeof.FullName then + boxEncoder int16 + else if enumType = typeof.FullName then + boxEncoder uint16 + else if enumType = typeof.FullName then + boxEncoder int + else if enumType = typeof.FullName then + boxEncoder uint32 + else + failwithf + """Cannot generate auto encoder for %s. +Only the following enum type are supported: - sbyte - byte - int16 - uint16 - int - uint32 -If you can't use one of these types, please pass an extra encoder. - """ t.FullName - elif t.IsGenericType then - if FSharpType.IsTuple(t) then - let encoders = - FSharpType.GetTupleElements(t) - |> Array.map (autoEncoder extra caseStrategy skipNullField) - fun (value: obj) -> - FSharpValue.GetTupleFields(value) - |> Seq.mapi (fun i x -> encoders.[i] x) |> seq - else - let fullname = t.GetGenericTypeDefinition().FullName - if fullname = typedefof.FullName then - // Evaluate lazily so we don't need to generate the encoder for null values - let encoder = lazy - t.GenericTypeArguments.[0] - |> autoEncoder extra caseStrategy skipNullField - |> option - |> boxEncoder - boxEncoder(fun (value: obj) -> - if isNull value then nil - else encoder.Value value) - elif fullname = typedefof.FullName - || fullname = typedefof>.FullName then - // Disable seq support for now because I don't know how to implements to on Thoth.Json.Net - // || fullname = typedefof.FullName then - let encoder = t.GenericTypeArguments.[0] |> autoEncoder extra caseStrategy skipNullField - fun (value: obj) -> - value :?> obj seq |> Seq.map encoder |> seq - elif fullname = typedefof< Map >.FullName then - let keyType = t.GenericTypeArguments.[0] - let valueEncoder = t.GenericTypeArguments.[1] |> autoEncoder extra caseStrategy skipNullField - if keyType.FullName = typeof.FullName - || keyType.FullName = typeof.FullName then - fun value -> - // Fable compiles Guids as strings so this works, but maybe we should make the conversion explicit - // (see dotnet version) in case Fable implementation of Guids change - (JsonValue(), value :?> Map) - ||> Seq.fold (fun target (KeyValue(k,v)) -> - target.[k] <- valueEncoder v - target) - else - let keyEncoder = keyType |> autoEncoder extra caseStrategy skipNullField - fun value -> - value :?> Map |> Seq.map (fun (KeyValue(k,v)) -> - array [|keyEncoder k; valueEncoder v|]) |> seq +If you can't use one of these types, please pass add a new extra coder. + """ + fullName + + and inline private handleTuple (extra : Map>) + (caseStrategy : CaseStrategy) + (skipNullField : bool) + (t : System.Type) : BoxedEncoder = + + let encoders : BoxedEncoder array = + FSharpType.GetTupleElements(t) + |> Array.map (fun typ -> + autoEncoder extra caseStrategy skipNullField typ + ) + + boxEncoder(fun (value : obj) -> + FSharpValue.GetTupleFields(value) + |> Array.mapi (fun i fieldValue -> + encoders.[i].Encode fieldValue + ) + |> seq + ) + + and inline private handleMapOrDict (extra : Map>) + (caseStrategy : CaseStrategy) + (skipNullField : bool) + (t : System.Type) : BoxedEncoder = + let keyType = t.GenericTypeArguments.[0] + let valueType = t.GenericTypeArguments.[1] + let valueEncoder : BoxedEncoder = + valueType + |> autoEncoder extra caseStrategy skipNullField + + match keyType with + | StringifiableType toString -> + boxEncoder(fun (value : obj) -> + #if FABLE_COMPILER + let res = ResizeArray<(string * Json)>() + + // This cast to Map seems to be fine for Fable + // We use the same trick for non stringifiable key + // TODO: Does it works for .NET runtime? + for KeyValue(key, value) in value :?> Map do + res.Add(toString key, valueEncoder.Encode value) + + res.ToArray() + |> Map.ofArray + |> Json.Object + #endif + + #if !FABLE_COMPILER + let res = ResizeArray() + let kvProps = typedefof>.MakeGenericType(keyType, valueType).GetProperties() + + for kv in value :?> System.Collections.IEnumerable do + let k = kvProps.[0].GetValue(kv) + let v = kvProps.[1].GetValue(kv) + res.Add(toString k, valueEncoder.Encode v) + + res + |> Map.ofSeq + |> Json.Object + #endif + ) + + | _ -> + boxEncoder(fun (value : obj) -> + let keyEncoder : BoxedEncoder = + keyType + |> autoEncoder extra caseStrategy skipNullField + + #if FABLE_COMPILER + let res = ResizeArray() + + // This cast to Map seems to be fine for Fable + // We use the same trick for non stringifiable key + for KeyValue(key, value) in value :?> Map do + res.Add(Json.Array [| keyEncoder.Encode key; valueEncoder.Encode value |]) + + res.ToArray() + |> Json.Array + #endif + + #if !FABLE_COMPILER + let res = ResizeArray() + let kvProps = typedefof>.MakeGenericType(keyType, valueType).GetProperties() + + for kv in value :?> System.Collections.IEnumerable do + let k = kvProps.[0].GetValue(kv) + let v = kvProps.[1].GetValue(kv) + + res.Add(Json.Array [| keyEncoder.Encode k; valueEncoder.Encode v |]) + + res.ToArray() + |> Json.Array + #endif + ) + + and inline private handleGeneric (extra : Map>) + (caseStrategy : CaseStrategy) + (skipNullField : bool) + (t : System.Type) : BoxedEncoder = + let fullName = t.GetGenericTypeDefinition().FullName + + if fullName = typedefof.FullName then + #if FABLE_COMPILER + // Evaluate lazily so we don't need to generate the encoder for null values + let encoder = lazy + ((autoEncoder extra caseStrategy skipNullField (t.GenericTypeArguments.[0])).Encode) + |> option + |> boxEncoder + boxEncoder(fun (value: obj) -> + if skipNullField && isNull value then + nil else - autoEncodeRecordsAndUnions extra caseStrategy skipNullField t + encoder.Value.Encode value + ) + #endif + + #if !FABLE_COMPILER + // Evaluate lazily so we don't need to generate the encoder for null values + let encoder = lazy autoEncoder extra caseStrategy skipNullField t.GenericTypeArguments.[0] + boxEncoder(fun (value: obj) -> + if isNull value then + nil + else + let _, fields = FSharpValue.GetUnionFields(value, t, allowAccessToPrivateRepresentation=true) + encoder.Value.Encode fields.[0] + ) + #endif + + else if fullName = typedefof.FullName + || fullName = typedefof>.FullName + || fullName = typedefof>.FullName + || fullName = typedefof.FullName then + t.GenericTypeArguments.[0] + |> autoEncoder extra caseStrategy skipNullField + |> handleGenericSeq + + else if fullName = typedefof>.FullName + || fullName = typedefof>.FullName then + handleMapOrDict extra caseStrategy skipNullField t else - if fullname = typeof.FullName then + handleRecordAndUnion extra caseStrategy skipNullField t + + and private autoEncoder (extra : Map>) + (caseStrategy : CaseStrategy) + (skipNullField : bool) + (t : System.Type) : BoxedEncoder = + let fullName = t.FullName + match Map.tryFind fullName extra with + | Some encoderRef -> + boxEncoder(fun v -> encoderRef.contents.BoxedEncoder v) + + | None -> + if t.IsArray then + t.GetElementType() + |> autoEncoder extra caseStrategy skipNullField + |> handleGenericSeq + else if t.IsEnum then + handleEnum t fullName + else if FSharpType.IsTuple(t) then + handleTuple extra caseStrategy skipNullField t + else if t.IsGenericType then + handleGeneric extra caseStrategy skipNullField t + else if fullName = typeof.FullName then boxEncoder bool - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder unit - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder string - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then + boxEncoder char + else if fullName = typeof.FullName then boxEncoder sbyte - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder byte - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder int16 - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder uint16 - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder int - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder uint32 - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder float - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder float32 - // These number types require extra libraries in Fable. To prevent penalizing - // all users, extra encoders (withInt64, etc) must be passed when they're needed. - - // elif fullname = typeof.FullName then - // boxEncoder int64 - // elif fullname = typeof.FullName then - // boxEncoder uint64 - // elif fullname = typeof.FullName then - // boxEncoder bigint - // elif fullname = typeof.FullName then - // boxEncoder decimal - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder datetime - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder datetimeOffset - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder timespan - elif fullname = typeof.FullName then + else if fullName = typeof.FullName then boxEncoder guid - elif fullname = typeof.FullName then - boxEncoder id + // Allows to encode null values + else if fullName = typeof.FullName then + // If this is used only for Null value it should be ok + boxEncoder(fun (v : obj) -> + Json.Null + ) else - autoEncodeRecordsAndUnions extra caseStrategy skipNullField t + handleRecordAndUnion extra caseStrategy skipNullField t let private makeExtra (extra: ExtraCoders option) = match extra with | None -> Map.empty | Some e -> Map.map (fun _ (enc,_) -> ref enc) e.Coders - type Auto = - static member generateEncoderCached<'T>(?caseStrategy : CaseStrategy, ?extra: ExtraCoders, ?skipNullField: bool, [] ?resolver: ITypeResolver<'T>): Encoder<'T> = - let t = Util.resolveType resolver - let caseStrategy = defaultArg caseStrategy PascalCase - let skipNullField = defaultArg skipNullField true + module Auto = + + /// The goal of this API is to provide better interop when consuming Thoth.Json.Net from a C# project + type LowLevel = + /// ATTENTION: Use this only when other arguments (isCamelCase, extra) don't change + static member generateEncoderCached<'T> (t: System.Type, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders, ?skipNullField: bool): Encoder<'T> = + let caseStrategy = defaultArg caseStrategy PascalCase + let skipNullField = defaultArg skipNullField true + + let key = + t.FullName + |> (+) (Operators.string caseStrategy) + |> (+) (extra |> Option.map (fun e -> e.Hash) |> Option.defaultValue "") + + let encoderCrate = + Cache.Encoders.Value.GetOrAdd(key, fun _ -> + autoEncoder (makeExtra extra) caseStrategy skipNullField t) - let key = - t.FullName - |> (+) (Operators.string caseStrategy) - |> (+) (extra |> Option.map (fun e -> e.Hash) |> Option.defaultValue "") + fun (value: 'T) -> + encoderCrate.Encode value - Util.CachedEncoders.GetOrAdd(key , fun _ -> - autoEncoder (makeExtra extra) caseStrategy skipNullField t) |> unboxEncoder + type Auto = - static member generateEncoder<'T>(?caseStrategy : CaseStrategy, ?extra: ExtraCoders, ?skipNullField: bool, [] ?resolver: ITypeResolver<'T>): Encoder<'T> = + #if FABLE_COMPILER + /// ATTENTION: Use this only when other arguments (caseStrategy, extra) don't change + static member generateEncoderCached<'T>(?caseStrategy : CaseStrategy, ?extra: ExtraCoders, ?skipNullField: bool, [] ?resolver : ITypeResolver<'T>): Encoder<'T> = + let t = resolver.Value.ResolveType() + Auto.LowLevel.generateEncoderCached(t, ?caseStrategy = caseStrategy, ?extra = extra, ?skipNullField=skipNullField) + #endif + + #if !FABLE_COMPILER + /// ATTENTION: Use this only when other arguments (caseStrategy, extra) don't change + static member generateEncoderCached<'T>(?caseStrategy : CaseStrategy, ?extra: ExtraCoders, ?skipNullField: bool): Encoder<'T> = + let t = typeof<'T> + Auto.LowLevel.generateEncoderCached(t, ?caseStrategy = caseStrategy, ?extra = extra, ?skipNullField=skipNullField) + #endif + + #if FABLE_COMPILER + static member generateEncoder<'T>(?caseStrategy : CaseStrategy, ?extra: ExtraCoders, ?skipNullField: bool, [] ?resolver : ITypeResolver<'T>): Encoder<'T> = + let caseStrategy = defaultArg caseStrategy PascalCase + let skipNullField = defaultArg skipNullField true + let t = resolver.Value.ResolveType() + let encoderCrate = autoEncoder (makeExtra extra) caseStrategy skipNullField t + fun (value: 'T) -> + encoderCrate.Encode value + #endif + + #if !FABLE_COMPILER + static member generateEncoder<'T>(?caseStrategy : CaseStrategy, ?extra: ExtraCoders, ?skipNullField: bool): Encoder<'T> = let caseStrategy = defaultArg caseStrategy PascalCase let skipNullField = defaultArg skipNullField true - Util.resolveType resolver - |> autoEncoder (makeExtra extra) caseStrategy skipNullField |> unboxEncoder + let encoderCrate = autoEncoder (makeExtra extra) caseStrategy skipNullField typeof<'T> + fun (value: 'T) -> + encoderCrate.Encode value + #endif - static member toString(space : int, value : 'T, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders, ?skipNullField: bool, [] ?resolver: ITypeResolver<'T>) : string = + #if FABLE_COMPILER + static member toString(space : int, value : 'T, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders, ?skipNullField: bool, [] ?resolver : ITypeResolver<'T>) : string = let encoder = Auto.generateEncoder(?caseStrategy=caseStrategy, ?extra=extra, ?skipNullField=skipNullField, ?resolver=resolver) encoder value |> toString space + #endif - ///**Description** - /// Convert a `Value` into a prettified string. - ///**Parameters** - /// * `space` - parameter of type `int` - Amount of indentation - /// * `value` - parameter of type `obj` - Value to convert - /// - ///**Output Type** - /// * `string` - /// - ///**Exceptions** - /// - [] - let encode (space: int) (value: JsonValue) : string = toString space value + #if !FABLE_COMPILER + static member toString(space : int, value : 'T, ?caseStrategy : CaseStrategy, ?extra: ExtraCoders, ?skipNullField: bool) : string = + let encoder = Auto.generateEncoder(?caseStrategy=caseStrategy, ?extra=extra, ?skipNullField=skipNullField) + encoder value |> toString space + #endif diff --git a/src/Extra.fs b/src/Extra.fs index 741c3f5..3644524 100644 --- a/src/Extra.fs +++ b/src/Extra.fs @@ -1,31 +1,41 @@ -[] -module Thoth.Json.Extra +#if THOTH_JSON +namespace Thoth.Json +#endif + +#if THOTH_JSON_FABLE +namespace Thoth.Json.Fable +#endif -open Fable.Core +#if THOTH_JSON_NEWTONSOFT +namespace Thoth.Json.Newtonsoft +#endif + +[] +module Extra = -#if !FABLE_REPL_LIB -let empty: ExtraCoders = - { Hash = "" - Coders = Map.empty } + let empty: ExtraCoders = + { Hash = "" + Coders = Map.empty } -let inline internal withCustomAndKey (encoder: Encoder<'Value>) (decoder: Decoder<'Value>) - (extra: ExtraCoders): ExtraCoders = - { extra with - Hash = System.Guid.NewGuid().ToString() - Coders = - extra.Coders |> Map.add typeof<'Value>.FullName (Encode.boxEncoder encoder, Decode.boxDecoder decoder) } + let inline internal withCustomAndKey (encoder: Encoder<'Value>) (decoder: Decoder<'Value>) + (extra: ExtraCoders): ExtraCoders = + { extra with + Hash = System.Guid.NewGuid().ToString() + Coders = + extra.Coders + |> Map.add typeof<'Value>.FullName (Encode.boxEncoder encoder, Decode.boxDecoder decoder) + } -let inline withCustom (encoder: Encoder<'Value>) (decoder: Decoder<'Value>) (extra: ExtraCoders): ExtraCoders = - withCustomAndKey encoder decoder extra + let inline withCustom (encoder: Encoder<'Value>) (decoder: Decoder<'Value>) (extra: ExtraCoders): ExtraCoders = + withCustomAndKey encoder decoder extra -let inline withInt64 (extra: ExtraCoders): ExtraCoders = withCustomAndKey Encode.int64 Decode.int64 extra + let inline withInt64 (extra: ExtraCoders): ExtraCoders = withCustomAndKey Encode.int64 Decode.int64 extra -let inline withUInt64 (extra: ExtraCoders): ExtraCoders = - withCustomAndKey Encode.uint64 Decode.uint64 extra + let inline withUInt64 (extra: ExtraCoders): ExtraCoders = + withCustomAndKey Encode.uint64 Decode.uint64 extra -let inline withDecimal (extra: ExtraCoders): ExtraCoders = - withCustomAndKey Encode.decimal Decode.decimal extra + let inline withDecimal (extra: ExtraCoders): ExtraCoders = + withCustomAndKey Encode.decimal Decode.decimal extra -let inline withBigInt (extra: ExtraCoders): ExtraCoders = - withCustomAndKey Encode.bigint Decode.bigint extra -#endif \ No newline at end of file + let inline withBigInt (extra: ExtraCoders): ExtraCoders = + withCustomAndKey Encode.bigint Decode.bigint extra diff --git a/src/Parser.fs b/src/Parser.fs new file mode 100644 index 0000000..cbb1041 --- /dev/null +++ b/src/Parser.fs @@ -0,0 +1,377 @@ +module Thoth.Json.Parser + +open System +open System.Text +open System.Globalization + + +// This code has been heavily inspired by https://github.com/fsharp/FSharp.Data/blob/master/src/Json/JsonValue.fs +// I want to create a parser library but still lack the time and energy to do it + +module internal UnicodeHelper = + + // used http://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF as a guide below + let getUnicodeSurrogatePair num = + // only code points U+010000 to U+10FFFF supported + // for conversion to UTF16 surrogate pair + let codePoint = num - 0x010000u + let HIGH_TEN_BIT_MASK = 0xFFC00u // 1111|1111|1100|0000|0000 + let LOW_TEN_BIT_MASK = 0x003FFu // 0000|0000|0011|1111|1111 + let leadSurrogate = (codePoint &&& HIGH_TEN_BIT_MASK >>> 10) + 0xD800u + let trailSurrogate = (codePoint &&& LOW_TEN_BIT_MASK) + 0xDC00u + char leadSurrogate, char trailSurrogate + +[] +type JsonSaveOptions = + // Indent the Json + | Format = 0 + // Don't format the Json and print it in one line in a compact way + | DisableFormatting = 1 + +type StringBuilder with + member this.Write(text : string) = + this.Append(text) |> ignore + +[] +type Json = + | Number of float + | String of string + | Bool of bool + | Null + | Array of Json array + | Object of Map + // Not a real JSON type + // It is used to have a concrete type to represent when a value is missing + // For example, when trying to access property "name" in object { "age": 25 } + | Undefined + + member this.Write(builder : StringBuilder, saveOptions : JsonSaveOptions, baseIndentation : int) = + let newLine = + if saveOptions = JsonSaveOptions.Format then + fun indentation plus -> + // Don't use the default System newline because it breaks the Unit Tests... + builder.Write("\n") + System.String(' ', indentation + plus) + |> builder.Write + |> ignore + else + fun _ _ -> () + + let propSep = + if saveOptions = JsonSaveOptions.Format then + "\": " + else + "\":" + + let rec serialize indentation = function + | Json.Null -> + builder.Write "null" + + | Json.Bool b -> + builder.Write(if b then "true" else "false") + + | Json.Number number -> + builder.Write(string number) + + | Json.Number v when Double.IsInfinity v || Double.IsNaN v -> + builder.Write "null" + + | Json.Number number -> + builder.Write(string number) + + | Json.String s -> + builder.Write "\"" + Json.JsonStringEncodeTo builder s + builder.Write "\"" + + | Json.Object properties -> + builder.Write "{" + let properties = Map.toArray properties + for i = 0 to properties.Length - 1 do + let k,v = properties.[i] + if i > 0 then builder.Write "," + newLine indentation baseIndentation + builder.Write "\"" + Json.JsonStringEncodeTo builder k + builder.Write propSep + serialize (indentation + baseIndentation) v + if properties.Length <> 0 then + newLine indentation 0 + builder.Write "}" + + | Json.Undefined -> + () + + | Json.Array elements -> + builder.Write "[" + for i = 0 to elements.Length - 1 do + if i > 0 then builder.Write "," + newLine indentation baseIndentation + serialize (indentation + baseIndentation) elements.[i] + if elements.Length > 0 then + newLine indentation 0 + builder.Write "]" + + serialize 0 this + + // Encode characters that are not valid in JS string. The implementation is based + // on https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs + static member internal JsonStringEncodeTo (builder : StringBuilder) (value:string) = + if not (String.IsNullOrEmpty value) then + for i = 0 to value.Length - 1 do + let c = value.[i] + let ci = int c + + if ci >= 0 && ci <= 7 || ci = 11 || ci >= 14 && ci <= 31 then + System.String.Format("\\u{0:x4}", ci) + |> builder.Write + else + match c with + | '\b' -> + builder.Write "\\b" + + | '\t' -> + builder.Write "\\t" + + | '\n' -> + builder.Write "\\n" + + | '\f' -> + builder.Write "\\f" + + | '\r' -> + builder.Write "\\r" + + | '"' -> + builder.Write "\\\"" + + | '\\' -> + builder.Write "\\\\" + + | _ -> + builder.Write (string c) + +exception JsonParserError of string + +type private JsonParser(jsonText : string) = + + let mutable position = 0 + let text = jsonText.Replace("\r\n", "\n") + + let buffer = StringBuilder() // Pre-allocate buffers for strings + + let skipWhiteSpace () = + while position < text.Length && Char.IsWhiteSpace text.[position] do + position <- position + 1 + + let isNumChar (c : char) = + Char.IsDigit c || c = '.' || c = 'e' || c = 'E' || c = '+' || c = '-' + + let throw () = + let msg = + "Invalid JSON starting at character " + + string position + + ", snippet =\n-----\n" + + (jsonText.[(max 0 (position-10))..(min (jsonText.Length-1) (position+10))]) + + "\n-----\njson =\n-----\n" + + (if jsonText.Length > 1000 then jsonText.Substring(0, 1000) else jsonText) + + "\n-----" + + raise (JsonParserError msg) + + let ensure (condition : bool) = + if not condition then + throw() + + // Recursive descent parser for JSON that uses global mutable index + let rec parseValue() = + skipWhiteSpace() + ensure(position < text.Length) + match text.[position] with + | '"' -> + Json.String(parseString()) + + | '-' -> + parseNumber() + + | c when Char.IsDigit(c) -> + parseNumber() + + | '{' -> + parseObject() + + | '[' -> + parseArray() + // If a value start with 't' we know that it can only be the boolean value true + | 't' -> + parseLiteral("true", Json.Bool true) + // If a value start with 'f' we know that it can only be the boolean value false + | 'f' -> + parseLiteral("false", Json.Bool false) + // If a value start with 'n' we know that it can only be 'null' + | 'n' -> + parseLiteral("null", Json.Null) + + | _ -> throw() + + and parseString () = + // Make sure this is a valid start for a string + ensure(position < text.Length && text.[position] = '"') + position <- position + 1 + + while position < text.Length && text.[position] <> '"' do + if text.[position] = '\\' then + ensure(position + 1 < text.Length) + + match text.[position + 1] with + | 'b' -> + buffer.Append('\b') |> ignore + + | 'f' -> + buffer.Append('\f') |> ignore + + | 'n' -> + buffer.Append('\n') |> ignore + + | 't' -> + buffer.Append('\t') |> ignore + + | 'r' -> + buffer.Append('\r') |> ignore + + | '\\' -> + buffer.Append('\\') |> ignore + + | '/' -> + buffer.Append('/') |> ignore + + | '"' -> + buffer.Append('"') |> ignore + + | 'u' -> + ensure(position + 5 < text.Length) + let hexDigit d = + if d >= '0' && d <= '9' then int32 d - int32 '0' + elif d >= 'a' && d <= 'f' then int32 d - int32 'a' + 10 + elif d >= 'A' && d <= 'F' then int32 d - int32 'A' + 10 + else failwith "hexDigit" + + let unicodeChar (s:string) = + if s.Length <> 4 then failwith "unicodeChar"; + char (hexDigit s.[0] * 4096 + hexDigit s.[1] * 256 + hexDigit s.[2] * 16 + hexDigit s.[3]) + + let ch = unicodeChar (text.Substring(position + 2, 4)) + + buffer.Append(ch) |> ignore + position <- position + 4 // the \ and u will also be skipped past further below + + | 'U' -> + ensure(position + 9 < text.Length) + let unicodeChar (s:string) = + if s.Length <> 8 then failwith "unicodeChar"; + if s.[0..1] <> "00" then failwith "unicodeChar"; + UnicodeHelper.getUnicodeSurrogatePair <| UInt32.Parse(text, NumberStyles.HexNumber) + let lead, trail = unicodeChar (text.Substring(position + 2, 8)) + buffer.Append(lead) |> ignore + buffer.Append(trail) |> ignore + position <- position + 8 // the \ and u will also be skipped past further below + + | _ -> throw() + position <- position + 2 // skip past \ and next char + else + buffer.Append(text.[position]) |> ignore + position <- position + 1 + + ensure(position < text.Length && text.[position] = '"') + position <- position + 1 + let str = buffer.ToString() + buffer.Clear() |> ignore + str + + and parseNumber () = + let start = position + while position < text.Length && (isNumChar text.[position]) do + position <- position + 1 + + let len = position - start + let subText = text.Substring(start, len) + + match Double.TryParse(subText, NumberStyles.Any, CultureInfo.InvariantCulture) with + | true, value -> + Json.Number value + + | _ -> + throw() + + and parsePair () = + let key = parseString() + skipWhiteSpace() + ensure(position < text.Length && text.[position] = ':') + position <- position + 1 + skipWhiteSpace() + key, parseValue() + + and parseObject () = + ensure(position < text.Length && text.[position] = '{') + position <- position + 1 + skipWhiteSpace() + let pairs = ResizeArray<_>() + + if position < text.Length && text.[position] = '"' then + pairs.Add(parsePair()) + skipWhiteSpace() + while position < text.Length && text.[position] = ',' do + position <- position + 1 + skipWhiteSpace() + pairs.Add(parsePair()) + skipWhiteSpace() + + ensure(position < text.Length && text.[position] = '}') + position <- position + 1 + + pairs.ToArray() + |> Map.ofArray + |> Json.Object + + and parseArray () = + ensure(position < text.Length && text.[position] = '[') + position <- position + 1 + skipWhiteSpace() + let values = ResizeArray<_>() + + if position < text.Length && text.[position] <> ']' then + values.Add(parseValue()) + skipWhiteSpace() + + while position < text.Length && text.[position] = ',' do + position <- position + 1 + skipWhiteSpace() + values.Add(parseValue()) + skipWhiteSpace() + + ensure(position < text.Length && text.[position] = ']') + position <- position + 1 + + Json.Array(values.ToArray()) + + and parseLiteral(expected : string, result : Json) = + // Check that the string is long enough + ensure(position + expected.Length <= text.Length) + // Check that each char as the expected value + for charRank in 0 .. expected.Length - 1 do + ensure(text.[position + charRank] = expected.[charRank]) + + position <- position + expected.Length + result + + member this.Parse() = + let value = parseValue() + skipWhiteSpace() + // Check that we consume all the JSON string + // If not then the JSON is not valid + if position <> text.Length then + throw() + value + +let parse (jsonText : string) = + JsonParser(jsonText).Parse() diff --git a/src/Prelude.fs b/src/Prelude.fs new file mode 100644 index 0000000..43bc765 --- /dev/null +++ b/src/Prelude.fs @@ -0,0 +1,126 @@ +namespace Thoth.Json + +open System.Text +open Fable.Core +open System +open Thoth.Json.Parser + +type JsonValue = Json + +module Helpers = + + let anyToString(value: JsonValue): string = + let builder = StringBuilder() + value.Write(builder, JsonSaveOptions.Format, 4) + builder.ToString() + + let asArray(value: JsonValue): JsonValue [] = + match value with + | Json.Array values -> + values + | _ -> + failwith "Given JSON values is not an array" + + let asBool(value: JsonValue): bool = + match value with + | Json.Bool value -> + value + | _ -> + failwith "Given JSON values is not a boolean" + + let asFloat(value: JsonValue): float = + match value with + | Json.Number value -> + value + | _ -> + failwith "Given JSON values is not a number" + + let asFloat32(value: JsonValue): float32 = + match value with + | Json.Number value -> + float32 value + | _ -> + failwith "Given JSON values is not a number" + + let asInt(value: JsonValue): int = + match value with + | Json.Number value -> + int value + | _ -> + failwith "Given JSON values is not a number" + + let asString(value: JsonValue): string = + match value with + | Json.String value -> + value + | _ -> + failwith "Given JSON values is not a string" + + let getField(fieldName: string) (value: JsonValue): JsonValue = + match value with + | Json.Object properties -> + match Map.tryFind fieldName properties with + | Some value -> value + | None -> + Json.Undefined + | _ -> + failwith "Given JSON values is not a number" + + let isArray(value: JsonValue): bool = + match value with + | Json.Array _ -> true + | _ -> false + + let isBoolean(value: JsonValue): bool = + match value with + | Json.Bool _ -> true + | _ -> false + + let isIntegralValue(value: JsonValue): bool = + match value with + | Json.Number value -> + // Mimic Thoth.Json.Fable implementation + Math.Floor(value) = value + | _ -> false + + let isNullValue(value: JsonValue): bool = + match value with + | Json.Null + | Json.Undefined -> true + | _ -> false + + let isNumber(value: JsonValue): bool = + match value with + | Json.Number _ -> true + | _ -> false + + let isObject(value: JsonValue): bool = + match value with + | Json.Object _ -> true + | _ -> false + + let isString(value: JsonValue): bool = + match value with + | Json.String _ -> true + | _ -> false + + let isUndefined(value: JsonValue): bool = + // Is it the correct way? Or should I use "undefined" for JavaScript runtime and isNull for .NET runtime? + value = Json.Undefined + + let objectKeys(value: JsonValue): seq = + match value with + | Json.Object properties -> + properties + |> Map.toSeq + |> Seq.map fst + | _ -> + failwith "Given JSON values is not an object" + + let objectKeyValues(value: JsonValue): seq = + match value with + | Json.Object properties -> + properties + |> Map.toSeq + | _ -> + failwith "Given JSON values is not an object" diff --git a/src/Runners.fs b/src/Runners.fs new file mode 100644 index 0000000..b08a806 --- /dev/null +++ b/src/Runners.fs @@ -0,0 +1,37 @@ +namespace Thoth.Json + +open Fable.Core + +[] +module Extensions = + + [] + module Decode = + + let fromValue (decoder : Decoder<'T>) = + fun value -> + match decoder value with + | Ok success -> + Ok success + | Error error -> + let finalError = error |> DecoderError.prependPath "$" + Error (DecoderError.errorToStringWithPath finalError) + + let fromString (decoder : Decoder<'T>) = + fun value -> + try + let json = Parser.parse value + match decoder json with + | Ok success -> Ok success + | Error error -> + let finalError = error |> DecoderError.prependPath "$" + Error (DecoderError.errorToStringWithPath finalError) + with + | Parser.JsonParserError msg -> + Error("Given an invalid JSON: " + msg) + + let unsafeFromString (decoder : Decoder<'T>) = + fun value -> + match fromString decoder value with + | Ok x -> x + | Error msg -> failwith msg diff --git a/src/Thoth.Json.FableRuntime.fsproj b/src/Thoth.Json.FableRuntime.fsproj new file mode 100644 index 0000000..9696a3e --- /dev/null +++ b/src/Thoth.Json.FableRuntime.fsproj @@ -0,0 +1,32 @@ + + + + + This project is here only to provide intellisense when working against Fable runtime + + Maxime Mangel + 0.0.0 + false + false + + + netstandard2.0 + true + THOTH_JSON;FABLE_COMPILER + + + + + + + + + + + + + + + + + diff --git a/src/Thoth.Json.fsproj b/src/Thoth.Json.fsproj index e8797d7..6a2a395 100644 --- a/src/Thoth.Json.fsproj +++ b/src/Thoth.Json.fsproj @@ -1,30 +1,36 @@ - - -Elm-inspired encoder and decoder for JSON, this package is intended to be use on Fable side only. + + + Elm-inspired encoder and decoder for JSON, this package is intended to be use on Fable side only. -If you are interested on using it against .NET Core or .NET Framework, please use Thoth.Json.Net. - - https://github.com/thoth-org/Thoth.Json - https://github.com/thoth-org/Thoth.Json/blob/master/LICENSE.md - https://github.com/thoth-org/Thoth.Json - fable;fsharp;json - Maxime Mangel - 4.1.0 - - - netstandard2.0 - true - - - - - - - - - - - + If you are interested on using it against .NET Core or .NET Framework, please use Thoth.Json.Net. + + https://github.com/thoth-org/Thoth.Json.Core + https://github.com/thoth-org/Thoth.Json.Core/blob/master/LICENSE.md + https://github.com/thoth-org/Thoth.Json.Core + fable;fsharp;json + Maxime Mangel + 0.0.0 + + + netstandard2.0 + true + THOTH_JSON + + + + + + + + + + + + + + + + diff --git a/src/Types.fs b/src/Types.fs index ac9efcc..044152e 100644 --- a/src/Types.fs +++ b/src/Types.fs @@ -1,7 +1,9 @@ namespace Thoth.Json -open System.Text.RegularExpressions -type JsonValue = obj +type CaseStrategy = + | PascalCase + | CamelCase + | SnakeCase type ErrorReason = | BadPrimitive of string * JsonValue @@ -11,28 +13,89 @@ type ErrorReason = | BadPath of string * JsonValue * string | TooSmallArray of string * JsonValue | FailMessage of string - | BadOneOf of string list - -type CaseStrategy = - | PascalCase - | CamelCase - | SnakeCase + | BadOneOf of DecoderError list -type DecoderError = string * ErrorReason +and DecoderError = string * ErrorReason -type Decoder<'T> = string -> JsonValue -> Result<'T, DecoderError> +type Decoder<'T> = JsonValue -> Result<'T, DecoderError> type Encoder<'T> = 'T -> JsonValue -type BoxedDecoder = Decoder +module DecoderError = + + let prependPath (path: string) (err: DecoderError): DecoderError = + let (oldPath, reason) = err + (path + oldPath, reason) + + let inline prependPathToResult<'T> (path: string) (res: Result<'T, DecoderError>) = + res |> Result.mapError(prependPath path) + + let genericMsg (msg : string) (value : JsonValue) (newLine : bool) = + try + "Expecting " + + msg + + " but instead got:" + + (if newLine then "\n" else " ") + + (Helpers.anyToString value) + with + | _ -> + "Expecting " + + msg + + " but decoder failed. Couldn't report given value due to circular structure." + + (if newLine then "\n" else " ") -type BoxedEncoder = Encoder + let rec errorToString (path : string, error) = + match error with + | BadPrimitive (msg, value) -> + genericMsg msg value false + | BadType (msg, value) -> + genericMsg msg value true + | BadPrimitiveExtra (msg, value, reason) -> + genericMsg msg value false + "\nReason: " + reason + | BadField (msg, value) -> + genericMsg msg value true + | BadPath (msg, value, fieldName) -> + genericMsg msg value true + ("\nNode `" + fieldName + "` is unknown.") + | TooSmallArray (msg, value) -> + "Expecting " + msg + ".\n" + (Helpers.anyToString value) + | BadOneOf messages -> + let messages = + messages + |> List.map (fun (subPath, subError) -> + "Error at: `" + (path + subPath) + "`\n" + errorToString (subPath, subError) + ) + "The following errors were found:\n\n" + String.concat "\n\n" messages + | FailMessage msg -> + "The following `failure` occurred with the decoder: " + msg + + let errorToStringWithPath (path : string, error) = + match error with + | BadOneOf _ -> + errorToString (path, error) + | _ -> + "Error at: `" + path + "`\n" + errorToString (path, error) + +[] +type BoxedDecoder() = + abstract Decode : value : JsonValue -> Result + member this.BoxedDecoder : Decoder = + fun value -> this.Decode(value) + +[] +type BoxedEncoder() = + abstract Encode : value : obj -> JsonValue + member this.BoxedEncoder : Encoder = + this.Encode type ExtraCoders = - { Hash: string - Coders: Map } + { + Hash : string + Coders : Map + } -module internal Util = +module internal Cache = + + #if THOTH_JSON_FABLE || (THOTH_JSON && FABLE_COMPILER) open System.Collections.Generic type Cache<'Value>() = @@ -47,23 +110,65 @@ module internal Util = // Tree shaking will remove this if not used // so no need to make them lazy in Fable - let CachedEncoders = Cache() - let CachedDecoders = Cache() + let Encoders = lazy Cache() + let Decoders = lazy Cache() + #endif + + #if THOTH_JSON_NEWTONSOFT || (THOTH_JSON && !FABLE_COMPILER) + open System.Collections.Concurrent + + type Cache<'Value>() = + let cache = ConcurrentDictionary() + member __.GetOrAdd(key: string, factory: string->'Value) = + cache.GetOrAdd(key, factory) + + let Encoders = lazy Cache() + let Decoders = lazy Cache() + #endif - /// If used from .NET the type resolver won't be injected, - /// throw a more informative error than just a null reference. - let inline resolveType (resolver: Fable.Core.ITypeResolver<'T> option): System.Type = -#if !FABLE_COMPILER - failwith "Thoth.Json is only compatible with Fable, use Thoth.Json.Net" -#else - resolver.Value.ResolveType() -#endif +module Util = + open System.Text.RegularExpressions + open FSharp.Reflection + open System.Collections.Generic module Casing = let lowerFirst (str : string) = str.[..0].ToLowerInvariant() + str.[1..] let convert caseStrategy fieldName = match caseStrategy with - | CamelCase -> lowerFirst fieldName + | CamelCase -> lowerFirst fieldName | SnakeCase -> Regex.Replace(lowerFirst fieldName, "[A-Z]","_$0").ToLowerInvariant() - | PascalCase -> fieldName \ No newline at end of file + | PascalCase -> fieldName + + #if !NETFRAMEWORK && !THOTH_JSON_FABLE && !(THOTH_JSON && FABLE_COMPILER) + let (|StringEnum|_|) (typ : System.Type) = + typ.CustomAttributes + |> Seq.tryPick (function + | attr when attr.AttributeType.FullName = typeof.FullName -> Some attr + | _ -> None + ) + + let (|CompiledName|_|) (caseInfo : UnionCaseInfo) = + caseInfo.GetCustomAttributes() + |> Seq.tryPick (function + | :? CompiledNameAttribute as att -> Some att.CompiledName + | _ -> None) + + let (|LowerFirst|Forward|) (args : IList) = + args + |> Seq.tryPick (function + | rule when rule.ArgumentType.FullName = typeof.FullName -> Some rule + | _ -> None + ) + |> function + | Some rule -> + match rule.Value with + | :? int as value -> + match value with + | 0 -> Forward + | 1 -> LowerFirst + | _ -> LowerFirst // should not happen + | _ -> LowerFirst // should not happen + | None -> + LowerFirst + #endif diff --git a/src/paket.references b/src/paket.references deleted file mode 100644 index b344bc3..0000000 --- a/src/paket.references +++ /dev/null @@ -1,2 +0,0 @@ -FSharp.Core -Fable.Core diff --git a/tests/Decoders.Auto.fs b/tests/Decoders.Auto.fs new file mode 100644 index 0000000..581faad --- /dev/null +++ b/tests/Decoders.Auto.fs @@ -0,0 +1,712 @@ +module Tests.Decoders.Auto + +#if FABLE_COMPILER +open Thoth.Json +open Fable.Mocha +open Fable.Core.JsInterop +#endif + +#if !FABLE_COMPILER +open Thoth.Json +open Expecto +#endif + +open Tests.Types +open System + +type RecordWithPrivateConstructor = private { Foo1: int; Foo2: float } + +type UnionWithPrivateConstructor = private Bar of string | Baz + +let tests = + testList "Auto" [ + testCase "Auto.Decode.fromString works" <| fun _ -> + let now = DateTime.Now + let value : Record9 = + { + a = 5 + b = "bar" + c = [false, 3; true, 5; false, 10] + d = [|Some(Foo 14); None|] + e = Map [("oh", { a = 2.; b = 2. }); ("ah", { a = -1.5; b = 0. })] + f = now + g = set [{ a = 2.; b = 2. }; { a = -1.5; b = 0. }] + h = TimeSpan.FromSeconds(5.) + i = 120y + j = 120uy + k = 250s + l = 250us + m = 99u + n = 99L + o = 999UL + p = () + r = 'r' + s = Guid("2e053897-15a9-4647-a005-e954666e24d3") + t = seq [ "item n°1"; "item n°2"] + u = SeveralArgs (10, {| Name = "maxime"; Age = 28 |}) + } + let extra = + Extra.empty + |> Extra.withInt64 + |> Extra.withUInt64 + let json = Encode.Auto.toString(4, value, extra = extra) + // printfn "AUTO ENCODED %s" json + let r2 = Decode.Auto.unsafeFromString(json, extra = extra) + Expect.equal 5 r2.a "" + Expect.equal "bar" r2.b "" + Expect.equal [false, 3; true, 5; false, 10] r2.c "" + Expect.equal (Some(Foo 14)) r2.d.[0] "" + Expect.equal None r2.d.[1] "" + Expect.equal -1.5 (Map.find "ah" r2.e).a "" + Expect.equal 2. (Map.find "oh" r2.e).b "" + Expect.equal (now.ToString()) (value.f.ToString()) "" + Expect.equal true (Set.contains { a = -1.5; b = 0. } r2.g) "" + Expect.equal false (Set.contains { a = 1.5; b = 0. } r2.g) "" + Expect.equal 5000. value.h.TotalMilliseconds "" + Expect.equal 120y r2.i "" + Expect.equal 120uy r2.j "" + Expect.equal 250s r2.k "" + Expect.equal 250us r2.l "" + Expect.equal 99u r2.m "" + Expect.equal 99L r2.n "" + Expect.equal 999UL r2.o "" + Expect.equal () r2.p "" + Expect.equal 'r' r2.r "" + Expect.equal (Guid("2e053897-15a9-4647-a005-e954666e24d3")) r2.s "" + Expect.equal ((seq [ "item n°1"; "item n°2"]) |> Seq.toList) (r2.t |> Seq.toList) "" + + testCase "Auto serialization works with recursive types" <| fun _ -> + let len xs = + let rec lenInner acc = function + | Cons(_,rest) -> lenInner (acc + 1) rest + | Nil -> acc + lenInner 0 xs + let li = Cons(1, Cons(2, Cons(3, Nil))) + let json = Encode.Auto.toString(4, li) + // printfn "AUTO ENCODED MYLIST %s" json + let li2 = Decode.Auto.unsafeFromString>(json) + Expect.equal (len li2) 3 "" + let actual = + match li with + | Cons(i1, Cons(i2, Cons(i3, Nil))) -> i1 + i2 + i3 + | Cons(i,_) -> i + | Nil -> 0 + Expect.equal actual 6 "" + + testCase "Auto decoders works for string" <| fun _ -> + let value = "maxime" + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works for guid" <| fun _ -> + let value = Guid.NewGuid() + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works for int" <| fun _ -> + let value = 12 + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works for int64" <| fun _ -> + let extra = Extra.empty |> Extra.withInt64 + let value = 9999999999L + let json = Encode.Auto.toString(4, value, extra=extra) + let res = Decode.Auto.unsafeFromString(json, extra=extra) + Expect.equal res value "" + + testCase "Auto decoders works for uint32" <| fun _ -> + let value = 12u + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works for uint64" <| fun _ -> + let extra = Extra.empty |> Extra.withUInt64 + let value = 9999999999999999999UL + let json = Encode.Auto.toString(4, value, extra=extra) + let res = Decode.Auto.unsafeFromString(json, extra=extra) + Expect.equal res value "" + + testCase "Auto decoders works for bigint" <| fun _ -> + let extra = Extra.empty |> Extra.withBigInt + let value = 99999999999999999999999I + let json = Encode.Auto.toString(4, value, extra=extra) + let res = Decode.Auto.unsafeFromString(json, extra=extra) + Expect.equal res value "" + + testCase "Auto decoders works for bool" <| fun _ -> + let value = false + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works for float" <| fun _ -> + let value = 12. + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works for decimal" <| fun _ -> + let extra = Extra.empty |> Extra.withDecimal + let value = 0.7833M + let json = Encode.Auto.toString(4, value, extra=extra) + let res = Decode.Auto.unsafeFromString(json, extra=extra) + Expect.equal res value "" + + // testCase "Auto decoders works for datetime" <| fun _ -> + // let value = DateTime.Now + // let json = Encode.Auto.toString(4, value) + // let res = Decode.Auto.unsafeFromString(json) + // Expect.equal res.Date value.Date "" + // Expect.equal res.Hour value.Hour "" + // Expect.equal res.Minute value.Minute "" + // Expect.equal res.Second value.Second "" + + testCase "Auto decoders works for datetime UTC" <| fun _ -> + let value = DateTime.UtcNow + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res.Date value.Date "" + Expect.equal res.Hour value.Hour "" + Expect.equal res.Minute value.Minute "" + Expect.equal res.Second value.Second "" + + testCase "Auto decoders works for datetimeOffset" <| fun _ -> + let value = DateTimeOffset.Now + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json).ToLocalTime() + Expect.equal res.Date value.Date "" + Expect.equal res.Hour value.Hour "" + Expect.equal res.Minute value.Minute "" + Expect.equal res.Second value.Second "" + + testCase "Auto decoders works for datetimeOffset UTC" <| fun _ -> + let value = DateTimeOffset.UtcNow + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json).ToUniversalTime() + // printfn "SOURCE %A JSON %s OUTPUT %A" value json res + Expect.equal res.Date value.Date "" + Expect.equal res.Hour value.Hour "" + Expect.equal res.Minute value.Minute "" + Expect.equal res.Second value.Second "" + + testCase "Auto decoders works for TimeSpan" <| fun _ -> + let value = TimeSpan(1,2,3,4,5) + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res.Days value.Days "" + Expect.equal res.Hours value.Hours "" + Expect.equal res.Minutes value.Minutes "" + Expect.equal res.Seconds value.Seconds "" + Expect.equal res.Milliseconds value.Milliseconds "" + + testCase "Auto decoders works for list" <| fun _ -> + let value = [1; 2; 3; 4] + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works for array" <| fun _ -> + let value = [| 1; 2; 3; 4 |] + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works for seq" <| fun _ -> + let value = [1; 2; 3; 4] + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + // Comparing directly against a seq won't work, because + // res is actually an array in disguise + Expect.equal value (List.ofSeq res) "" + + testCase "Auto decoders works for option None" <| fun _ -> + let value = None + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works for option Some" <| fun _ -> + let value = Some 5 + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works for Unit" <| fun _ -> + let value = () + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works for enum" <| fun _ -> + let res = Decode.Auto.unsafeFromString("99") + Expect.equal res Enum_Int8.NinetyNine "" + + testCase "Auto decoders for enum returns an error if the Enum value is invalid" <| fun _ -> +#if FABLE_COMPILER + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types.Enum_Int8[System.SByte] but instead got: 2 +Reason: Unknown value provided for the enum + """.Trim()) +#else + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types+Enum_Int8 but instead got: 2 +Reason: Unknown value provided for the enum + """.Trim()) +#endif + + let res = Decode.Auto.fromString("2") + Expect.equal res value "" + + testCase "Auto decoders works for enum" <| fun _ -> + let res = Decode.Auto.unsafeFromString("99") + Expect.equal res Enum_UInt8.NinetyNine "" + + testCase "Auto decoders for enum returns an error if the Enum value is invalid" <| fun _ -> +#if FABLE_COMPILER + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types.Enum_UInt8[System.Byte] but instead got: 2 +Reason: Unknown value provided for the enum + """.Trim()) +#else + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types+Enum_UInt8 but instead got: 2 +Reason: Unknown value provided for the enum + """.Trim()) +#endif + + let res = Decode.Auto.fromString("2") + Expect.equal res value "" + + testCase "Auto decoders works for enum" <| fun _ -> + let res = Decode.Auto.unsafeFromString("99") + Expect.equal res Enum_Int16.NinetyNine "" + + testCase "Auto decoders for enum returns an error if the Enum value is invalid" <| fun _ -> +#if FABLE_COMPILER + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types.Enum_Int16[System.Int16] but instead got: 2 +Reason: Unknown value provided for the enum + """.Trim()) +#else + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types+Enum_Int16 but instead got: 2 +Reason: Unknown value provided for the enum + """.Trim()) +#endif + + let res = Decode.Auto.fromString("2") + Expect.equal res value "" + + testCase "Auto decoders works for enum" <| fun _ -> + let res = Decode.Auto.unsafeFromString("99") + Expect.equal res Enum_UInt16.NinetyNine "" + + testCase "Auto decoders for enum returns an error if the Enum value is invalid" <| fun _ -> +#if FABLE_COMPILER + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types.Enum_UInt16[System.UInt16] but instead got: 2 +Reason: Unknown value provided for the enum + """.Trim()) +#else + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types+Enum_UInt16 but instead got: 2 +Reason: Unknown value provided for the enum + """.Trim()) +#endif + + let res = Decode.Auto.fromString("2") + Expect.equal res value "" + + testCase "Auto decoders works for enum" <| fun _ -> + let res = Decode.Auto.unsafeFromString("1") + Expect.equal res Enum_Int.One "" + + testCase "Auto decoders for enum returns an error if the Enum value is invalid" <| fun _ -> +#if FABLE_COMPILER + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types.Enum_Int[System.Int32] but instead got: 4 +Reason: Unknown value provided for the enum + """.Trim()) +#else + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types+Enum_Int but instead got: 4 +Reason: Unknown value provided for the enum + """.Trim()) +#endif + + let res = Decode.Auto.fromString("4") + Expect.equal res value "" + + testCase "Auto decoders works for enum" <| fun _ -> + let res = Decode.Auto.unsafeFromString("99") + Expect.equal res Enum_UInt32.NinetyNine "" + + testCase "Auto decoders for enum returns an error if the Enum value is invalid" <| fun _ -> +#if FABLE_COMPILER + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types.Enum_UInt32[System.UInt32] but instead got: 2 +Reason: Unknown value provided for the enum + """.Trim()) +#else + let value = + Error( + """ +Error at: `$` +Expecting Tests.Types+Enum_UInt32 but instead got: 2 +Reason: Unknown value provided for the enum + """.Trim()) +#endif + + let res = Decode.Auto.fromString("2") + Expect.equal res value "" + +(* + #if NETFRAMEWORK + testCase "Auto decoders works with char based Enums" <| fun _ -> + let value = CharEnum.A + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + #endif +*) + testCase "Auto decoders works for null" <| fun _ -> + let value = null + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res value "" + + testCase "Auto decoders works even if type is determined by the compiler" <| fun _ -> + let value = [1; 2; 3; 4] + let json = Encode.Auto.toString(4, value) + let res = Decode.Auto.unsafeFromString<_>(json) + Expect.equal res value "" + + testCase "Auto.unsafeFromString works with camelCase" <| fun _ -> + let json = """{ "id" : 0, "name": "maxime", "email": "mail@domain.com", "followers": 0 }""" + let user = Decode.Auto.unsafeFromString(json, caseStrategy=CamelCase) + Expect.equal user.Name "maxime" "" + Expect.equal user.Id 0 "" + Expect.equal user.Followers 0 "" + Expect.equal user.Email "mail@domain.com" "" + + testCase "Auto.fromString works with snake_case" <| fun _ -> + let json = """{ "one" : 1, "two_part": 2, "three_part_field": 3 }""" + let decoded = Decode.Auto.fromString(json, caseStrategy=SnakeCase) + let expected = Ok { One = 1; TwoPart = 2; ThreePartField = 3 } + Expect.equal decoded expected "" + + testCase "Auto.fromString works with camelCase" <| fun _ -> + let json = """{ "id" : 0, "name": "maxime", "email": "mail@domain.com", "followers": 0 }""" + let user = Decode.Auto.fromString(json, caseStrategy=CamelCase) + let expected = Ok { Id = 0; Name = "maxime"; Email = "mail@domain.com"; Followers = 0 } + Expect.equal user expected "" + + testCase "Auto.fromString works for records with an actual value for the optional field value" <| fun _ -> + let json = """{ "maybe" : "maybe value", "must": "must value"}""" + let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) + let expected = + Ok ({ Maybe = Some "maybe value" + Must = "must value" } : TestMaybeRecord) + Expect.equal actual expected "" + + testCase "Auto.fromString works for records with `null` for the optional field value" <| fun _ -> + let json = """{ "maybe" : null, "must": "must value"}""" + let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) + let expected = + Ok ({ Maybe = None + Must = "must value" } : TestMaybeRecord) + Expect.equal actual expected "" + + testCase "Auto.fromString works for records with `null` for the optional field value on classes" <| fun _ -> + let json = """{ "maybeClass" : null, "must": "must value"}""" + let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) + let expected = + Ok ({ MaybeClass = None + Must = "must value" } : RecordWithOptionalClass) + Expect.equal actual expected "" + + testCase "Auto.fromString works for records missing optional field value on classes" <| fun _ -> + let json = """{ "must": "must value"}""" + let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) + let expected = + Ok ({ MaybeClass = None + Must = "must value" } : RecordWithOptionalClass) + Expect.equal actual expected "" + + testCase "Auto.generateDecoder throws for field using a non optional class" <| fun _ -> + let expected = "Cannot generate auto decoder for Tests.Types.BaseClass. Please pass an extra decoder." + let errorMsg = + try + let decoder = Decode.Auto.generateDecoder(caseStrategy=CamelCase) + "" + with ex -> + ex.Message + Expect.equal (errorMsg.Replace("+", ".")) expected "" + + testCase "Auto.fromString works for Class marked as optional" <| fun _ -> + let json = """null""" + + let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) + let expected = Ok None + Expect.equal actual expected "" + + testCase "Auto.generateDecoder throws for Class" <| fun _ -> + let expected = "Cannot generate auto decoder for Tests.Types.BaseClass. Please pass an extra decoder." + let errorMsg = + try + let decoder = Decode.Auto.generateDecoder(caseStrategy=CamelCase) + "" + with ex -> + ex.Message + Expect.equal (errorMsg.Replace("+", ".")) expected "" + + testCase "Auto.fromString works for records missing an optional field" <| fun _ -> + let json = """{ "must": "must value"}""" + let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) + let expected = + Ok ({ Maybe = None + Must = "must value" } : TestMaybeRecord) + Expect.equal actual expected "" + + testCase "Auto.fromString works with maps encoded as objects" <| fun _ -> + let expected = Map [("oh", { a = 2.; b = 2. }); ("ah", { a = -1.5; b = 0. })] + let json = """{"ah":{"a":-1.5,"b":0},"oh":{"a":2,"b":2}}""" + let actual = Decode.Auto.fromString json + Expect.equal actual (Ok expected) "" + + testCase "Auto.fromString works with maps encoded as arrays" <| fun _ -> + let expected = Map [({ a = 2.; b = 2. }, "oh"); ({ a = -1.5; b = 0. }, "ah")] + let json = """[[{"a":-1.5,"b":0},"ah"],[{"a":2,"b":2},"oh"]]""" + let actual = Decode.Auto.fromString json + Expect.equal actual (Ok expected) "" + + testCase "Auto.unsafeFromString works with mutable dictionaries" <| fun _ -> + let expected = System.Collections.Generic.Dictionary() + expected.Add("oh", { a = 2.; b = 2. }) + expected.Add("ah", { a = -1.5; b = 0. }) + let json = """{"ah":{"a":-1.5,"b":0},"oh":{"a":2,"b":2}}""" + let actual: System.Collections.Generic.Dictionary<_,_> = + Decode.Auto.unsafeFromString json + for (KeyValue(k, v)) in expected do + Expect.equal actual.[k] v "" + Expect.equal actual.["ah"].a -1.5 "" + actual.["ah"] <- { a = 0.; b = 0. } + Expect.equal actual.["ah"].a 0. "" + testCase "Auto.unsafeFromString works with mutable dictionaires with non simples keys" <| fun _ -> + let json = """[[{"ComplexKey":1},1],[{"ComplexKey":2},2]]""" + let d = System.Collections.Generic.Dictionary() + d.Add({| ComplexKey = 1 |}, 1) + d.Add({| ComplexKey = 2 |}, 2) + let actual : Collections.Generic.Dictionary<{| ComplexKey : int |}, int> = Decode.Auto.unsafeFromString json + Expect.equal actual.[{| ComplexKey = 1 |}] 1 "" + Expect.equal actual.[{| ComplexKey = 2 |}] 2 "" + + testCase "Auto.unsafeFromString works with mutable hashsets" <| fun _ -> + let expected = System.Collections.Generic.HashSet() + expected.Add({ a = 2.; b = 2. }) |> ignore + expected.Add({ a = -1.5; b = 0. }) |> ignore + let json = """[{"a":2,"b":2},{"a":-1.5,"b":0}]""" + let actual: System.Collections.Generic.HashSet<_> = Decode.Auto.unsafeFromString json + for x in expected do + Expect.equal (actual.Contains(x)) true "" + actual.Add({ a = 3.; b = 3. }) |> ignore + Expect.equal actual.Count 3 "" + actual.Add({ a = 2.; b = 2. }) |> ignore + Expect.equal actual.Count 3 "" + + testCase "Decoder.Auto.toString works with bigint extra" <| fun _ -> + let extra = Extra.empty |> Extra.withBigInt + let expected = { bigintField = 9999999999999999999999I } + let actual = Decode.Auto.fromString("""{"bigintField":"9999999999999999999999"}""", extra=extra) + Expect.equal actual (Ok expected) "" + + testCase "Decoder.Auto.toString works with custom extra" <| fun _ -> + let extra = Extra.empty |> Extra.withCustom ChildType.Encode ChildType.Decoder + let expected = { ParentField = { ChildField = "bumbabon" } } + let actual = Decode.Auto.fromString("""{"ParentField":"bumbabon"}""", extra=extra) + Expect.equal actual (Ok expected) "" + + testCase "Auto.fromString works with records with private constructors" <| fun _ -> + let json = """{ "foo1": 5, "foo2": 7.8 }""" + let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) + let expected = Ok ({ Foo1 = 5; Foo2 = 7.8 }: RecordWithPrivateConstructor) + Expect.equal actual expected "" + + testCase "Auto.fromString works with unions with private constructors" <| fun _ -> + let json = """[ "Baz", ["Bar", "foo"]]""" + let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) + let expected = Ok [Baz; Bar "foo"] + Expect.equal actual expected "" + + testCase "Auto.generateDecoderCached works" <| fun _ -> + let expected = Ok { Id = 0; Name = "maxime"; Email = "mail@domain.com"; Followers = 0 } + let json = """{ "id" : 0, "name": "maxime", "email": "mail@domain.com", "followers": 0 }""" + let decoder1 = Decode.Auto.generateDecoderCached(caseStrategy=CamelCase) + let decoder2 = Decode.Auto.generateDecoderCached(caseStrategy=CamelCase) + let actual1 = Decode.fromString decoder1 json + let actual2 = Decode.fromString decoder2 json + Expect.equal actual1 expected "" + Expect.equal actual2 expected "" + Expect.equal actual1 actual2 "" + + testCase "Auto.fromString works with strange types if they are None" <| fun _ -> + let json = """{"Id":0}""" + let actual = Decode.Auto.fromString(json) + let expected = Ok { Id = 0; Thread = None } + Expect.equal actual expected "" + + testCase "Auto.fromString works with recursive types" <| fun _ -> + let vater = + { Name = "Alfonso" + Children = [ { Name = "Narumi"; Children = [] } + { Name = "Takumi"; Children = [] } ] } + let json = """{"Name":"Alfonso","Children":[{"Name":"Narumi","Children":[]},{"Name":"Takumi","Children":[]}]}""" + let actual = Decode.Auto.fromString(json) + let expected = Ok vater + Expect.equal actual expected "" + + testCase "Auto.unsafeFromString works for unit" <| fun _ -> + let json = Encode.unit () |> Encode.toString 4 + let res = Decode.Auto.unsafeFromString(json) + Expect.equal res () "" + +// testCase "Erased single-case DUs works" <| fun _ -> +// let expected = NoAllocAttributeSingleCaseDU (Guid.NewGuid()) +// let json = Encode.Auto.toString(4, expected) +// let actual = Decode.Auto.unsafeFromString(json) +// Expect.equal actual expected "" + + testCase "Single case unions generates simplify JSON" <| fun _ -> + let expected = SingleCaseDUSimple "Maxime" + let json = "\"Maxime\"" + let actual = Decode.Auto.unsafeFromString(json) + Expect.equal actual expected "" + + testCase "Single case unions generates simplify JSON and works with complex types" <| fun _ -> + let expected = SingleCaseDUComplex {| FirstName = "Maxime"; Age = 28 |} + let json = + """ +{ + "Age": 28, + "FirstName": "Maxime" +} + """.Trim() + let actual = Decode.Auto.unsafeFromString json + Expect.equal actual expected "" + + testCase "Old style of single case unions is supported" <| fun _ -> + let expected = SingleCaseDUSimple "Maxime" + let json = + """ +[ + "SingleCaseDUSimple", + "Maxime" +] + """.Trim() + let actual = Decode.Auto.unsafeFromString(json) + Expect.equal actual expected "" + + testCase "Auto.unsafeFromString works with HTML inside of a string" <| fun _ -> + let expected = + { + FeedName = "Ars" + Content = "
\"How

Enlarge (credit: Getty / Aurich Lawson)

In 2005, Apple contacted Qualcomm as a potential supplier for modem chips in the first iPhone. Qualcomm's response was unusual: a letter demanding that Apple sign a patent licensing agreement before Qualcomm would even consider supplying chips.

\"I'd spent 20 years in the industry, I had never seen a letter like this,\" said Tony Blevins, Apple's vice president of procurement.

Most suppliers are eager to talk to new customers—especially customers as big and prestigious as Apple. But Qualcomm wasn't like other suppliers; it enjoyed a dominant position in the market for cellular chips. That gave Qualcomm a lot of leverage, and the company wasn't afraid to use it.

Read 70 remaining paragraphs | Comments

" + } + + let articleJson = + """ + { + "FeedName": "Ars", + "Content": "
\"How

Enlarge (credit: Getty / Aurich Lawson)

In 2005, Apple contacted Qualcomm as a potential supplier for modem chips in the first iPhone. Qualcomm's response was unusual: a letter demanding that Apple sign a patent licensing agreement before Qualcomm would even consider supplying chips.

\"I'd spent 20 years in the industry, I had never seen a letter like this,\" said Tony Blevins, Apple's vice president of procurement.

Most suppliers are eager to talk to new customers—especially customers as big and prestigious as Apple. But Qualcomm wasn't like other suppliers; it enjoyed a dominant position in the market for cellular chips. That gave Qualcomm a lot of leverage, and the company wasn't afraid to use it.

Read 70 remaining paragraphs | Comments

" + } + """ + + let actual : TestStringWithHTML = Decode.Auto.unsafeFromString(articleJson) + Expect.equal actual expected "" + + testCase "Decode.Auto.fromString allows to customize default known types" <| fun _ -> + let customizedIntEncoder (value : int) = + Encode.object [ + "type", Encode.string "int" + "value", Encode.int value + ] + + let customizedIntDecoder = + Decode.field "type" Decode.string + |> Decode.andThen(function + | "int" -> + Decode.field "value" Decode.int + | invalid -> + sprintf "`%s` is not a valid type value for customizedInt" invalid + |> Decode.fail + ) + + let extra = + Extra.empty + |> Extra.withCustom customizedIntEncoder customizedIntDecoder + + let json = "{\"type\":\"int\",\"value\":99}" + let actual = Decode.Auto.unsafeFromString(json, extra = extra) + + Expect.equal actual 99 "" + + #if !NETFRAMEWORK + testCase "Decode.Auto.fromString works with []" <| fun _ -> + let expected = Camera.FirstPerson + let actual = Decode.Auto.unsafeFromString("\"firstPerson\"") + Expect.equal actual expected "" + + testCase "Decode.Auto.fromString works with [" <| fun _ -> + let expected = Framework.React + let actual = Decode.Auto.unsafeFromString("\"react\"") + Expect.equal actual expected "" + + testCase "Decode.Auto.fromString works with []" <| fun _ -> + let expected = Language.Fsharp + let actual = Decode.Auto.unsafeFromString("\"Fsharp\"") + Expect.equal actual expected "" + + testCase "Decode.Auto.fromString works with [] + []" <| fun _ -> + let expected = Language.Csharp + let actual = Decode.Auto.unsafeFromString("\"C#\"") + Expect.equal actual expected "" + #endif + ] diff --git a/tests/Decoders.fs b/tests/Decoders.Manual.fs similarity index 63% rename from tests/Decoders.fs rename to tests/Decoders.Manual.fs index 3f13d12..f4af75a 100644 --- a/tests/Decoders.fs +++ b/tests/Decoders.Manual.fs @@ -1,12 +1,21 @@ -module Tests.Decoders +module Tests.Decoders.Manual #if !NETFRAMEWORK open Fable.Core #endif +#if FABLE_COMPILER +open Thoth.Json +open Fable.Mocha open Fable.Core.JsInterop +#endif + +#if !FABLE_COMPILER open Thoth.Json -open Util.Testing +open Expecto +#endif + +open Tests.Types open System let jsonRecord = @@ -29,16 +38,14 @@ let jsonRecordInvalid = "g": "invalid_a_field", "h": "invalid_a_field" }""" -open Tests.Types - type RecordWithPrivateConstructor = private { Foo1: int; Foo2: float } type UnionWithPrivateConstructor = private Bar of string | Baz -let tests : Test = +let tests = testList "Thoth.Json.Decode" [ testList "Errors" [ - #if FABLE_COMPILER + #if THTOH_JSON_FABLE testCase "circular structure are supported when reporting error" <| fun _ -> let a = createObj [ ] @@ -47,26 +54,23 @@ let tests : Test = b?child <- a let expected : Result = Error "Error at: `$`\nExpecting a float but decoder failed. Couldn\'t report given value due to circular structure. " - let actual = Decode.fromValue "$" Decode.float b + let actual = Decode.fromValue Decode.float b - equal expected actual + Expect.equal actual expected "" #endif testCase "invalid json" <| fun _ -> - #if FABLE_COMPILER - let expected : Result = Error "Given an invalid JSON: Unexpected token m in JSON at position 0" - #else - let expected : Result = Error "Given an invalid JSON: Unexpected character encountered while parsing value: m. Path '', line 0, position 0." - #endif + let expected : Result = Error "Given an invalid JSON: Invalid JSON starting at character 0, snippet =\n-----\nmaxime\n-----\njson =\n-----\nmaxime\n-----" + let actual = Decode.fromString Decode.float "maxime" - equal expected actual + Expect.equal actual expected "" testCase "user exceptions are not captured by the decoders" <| fun _ -> let expected = true let decoder = - (fun _ _ -> + (fun _ -> raise CustomException ) @@ -79,7 +83,7 @@ let tests : Test = | CustomException -> true - equal expected actual + Expect.equal actual expected "" ] testList "Primitives" [ @@ -89,78 +93,84 @@ let tests : Test = let actual = Decode.fromString Decode.unit "null" - equal expected actual + Expect.equal actual expected "" testCase "a string works" <| fun _ -> let expected = Ok("maxime") let actual = Decode.fromString Decode.string "\"maxime\"" - equal expected actual + Expect.equal actual expected "" + + testCase "a char works" <| fun _ -> + let expected = Ok('c') + let actual = + Decode.fromString Decode.char"\"c\"" + + Expect.equal actual expected "" testCase "a float works" <| fun _ -> let expected = Ok(1.2) let actual = Decode.fromString Decode.float "1.2" - equal expected actual + Expect.equal actual expected "" testCase "a float from int works" <| fun _ -> let expected = Ok(1.0) let actual = Decode.fromString Decode.float "1" - equal expected actual + Expect.equal actual expected "" testCase "a bool works" <| fun _ -> let expected = Ok(true) let actual = Decode.fromString Decode.bool "true" - equal expected actual + Expect.equal actual expected "" testCase "an invalid bool output an error" <| fun _ -> let expected = Error("Error at: `$`\nExpecting a boolean but instead got: 2") let actual = Decode.fromString Decode.bool "2" - equal expected actual + Expect.equal actual expected "" testCase "an int works" <| fun _ -> let expected = Ok(25) let actual = Decode.fromString Decode.int "25" - equal expected actual + Expect.equal actual expected "" testCase "an invalid int [invalid range: too big] output an error" <| fun _ -> let expected = Error("Error at: `$`\nExpecting an int but instead got: 2147483648\nReason: Value was either too large or too small for an int") let actual = Decode.fromString Decode.int "2147483648" - equal expected actual - + Expect.equal actual expected "" testCase "an invalid int [invalid range: too small] output an error" <| fun _ -> let expected = Error("Error at: `$`\nExpecting an int but instead got: -2147483649\nReason: Value was either too large or too small for an int") let actual = Decode.fromString Decode.int "-2147483649" - equal expected actual + Expect.equal actual expected "" testCase "an int16 works from number" <| fun _ -> let expected = Ok(int16 25) let actual = Decode.fromString Decode.int16 "25" - equal expected actual + Expect.equal actual expected "" testCase "an int16 works from string" <| fun _ -> let expected = Ok(int16 -25) let actual = Decode.fromString Decode.int16 "\"-25\"" - equal expected actual + Expect.equal actual expected "" testCase "an int16 output an error if value is too big" <| fun _ -> let expected = @@ -173,7 +183,7 @@ Reason: Value was either too large or too small for an int16 let actual = Decode.fromString Decode.int16 "32768" - equal expected actual + Expect.equal actual expected "" testCase "an int16 output an error if value is too small" <| fun _ -> let expected = @@ -186,7 +196,7 @@ Reason: Value was either too large or too small for an int16 let actual = Decode.fromString Decode.int16 "-32769" - equal expected actual + Expect.equal actual expected "" testCase "an int16 output an error if incorrect string" <| fun _ -> let expected = @@ -198,21 +208,21 @@ Expecting an int16 but instead got: "maxime" let actual = Decode.fromString Decode.int16 "\"maxime\"" - equal expected actual + Expect.equal actual expected "" testCase "an uint16 works from number" <| fun _ -> let expected = Ok(uint16 25) let actual = Decode.fromString Decode.uint16 "25" - equal expected actual + Expect.equal actual expected "" testCase "an uint16 works from string" <| fun _ -> let expected = Ok(uint16 25) let actual = Decode.fromString Decode.uint16 "\"25\"" - equal expected actual + Expect.equal actual expected "" testCase "an uint16 output an error if value is too big" <| fun _ -> let expected = @@ -225,7 +235,7 @@ Reason: Value was either too large or too small for an uint16 let actual = Decode.fromString Decode.uint16 "65536" - equal expected actual + Expect.equal actual expected "" testCase "an uint16 output an error if value is too small" <| fun _ -> let expected = @@ -238,7 +248,7 @@ Reason: Value was either too large or too small for an uint16 let actual = Decode.fromString Decode.uint16 "-1" - equal expected actual + Expect.equal actual expected "" testCase "an uint16 output an error if incorrect string" <| fun _ -> let expected = @@ -250,21 +260,21 @@ Expecting an uint16 but instead got: "maxime" let actual = Decode.fromString Decode.uint16 "\"maxime\"" - equal expected actual + Expect.equal actual expected "" testCase "an int64 works from number" <| fun _ -> let expected = Ok 1000L let actual = Decode.fromString Decode.int64 "1000" - equal expected actual + Expect.equal actual expected "" testCase "an int64 works from string" <| fun _ -> let expected = Ok 99L let actual = Decode.fromString Decode.int64 "\"99\"" - equal expected actual + Expect.equal actual expected "" testCase "an int64 works output an error if incorrect string" <| fun _ -> let expected = @@ -276,21 +286,21 @@ Expecting an int64 but instead got: "maxime" let actual = Decode.fromString Decode.int64 "\"maxime\"" - equal expected actual + Expect.equal actual expected "" testCase "an uint32 works from number" <| fun _ -> let expected = Ok 1000u let actual = Decode.fromString Decode.uint32 "1000" - equal expected actual + Expect.equal actual expected "" testCase "an uint32 works from string" <| fun _ -> let expected = Ok 1000u let actual = Decode.fromString Decode.uint32 "\"1000\"" - equal expected actual + Expect.equal actual expected "" testCase "an uint32 output an error if incorrect string" <| fun _ -> let expected = @@ -303,21 +313,21 @@ Expecting an uint32 but instead got: "maxime" let actual = Decode.fromString Decode.uint32 "\"maxime\"" - equal expected actual + Expect.equal actual expected "" testCase "an uint64 works from number" <| fun _ -> let expected = Ok 1000UL let actual = Decode.fromString Decode.uint64 "1000" - equal expected actual + Expect.equal actual expected "" testCase "an uint64 works from string" <| fun _ -> let expected = Ok 1000UL let actual = Decode.fromString Decode.uint64 "\"1000\"" - equal expected actual + Expect.equal actual expected "" testCase "an uint64 output an error if incorrect string" <| fun _ -> let expected = @@ -330,21 +340,21 @@ Expecting an uint64 but instead got: "maxime" let actual = Decode.fromString Decode.uint64 "\"maxime\"" - equal expected actual + Expect.equal actual expected "" testCase "a byte works from number" <| fun _ -> let expected = Ok 25uy let actual = Decode.fromString Decode.byte "25" - equal expected actual + Expect.equal actual expected "" testCase "a byte works from string" <| fun _ -> let expected = Ok 25uy let actual = Decode.fromString Decode.byte "\"25\"" - equal expected actual + Expect.equal actual expected "" testCase "a byte output an error if value is too big" <| fun _ -> let expected = @@ -357,7 +367,7 @@ Reason: Value was either too large or too small for a byte let actual = Decode.fromString Decode.byte "256" - equal expected actual + Expect.equal actual expected "" testCase "a byte output an error if value is too small" <| fun _ -> let expected = @@ -370,7 +380,7 @@ Reason: Value was either too large or too small for a byte let actual = Decode.fromString Decode.byte "-1" - equal expected actual + Expect.equal actual expected "" testCase "a byte output an error if incorrect string" <| fun _ -> let expected = @@ -382,22 +392,21 @@ Expecting a byte but instead got: "maxime" let actual = Decode.fromString Decode.byte "\"maxime\"" - equal expected actual - + Expect.equal actual expected "" testCase "a sbyte works from number" <| fun _ -> let expected = Ok 25y let actual = Decode.fromString Decode.sbyte "25" - equal expected actual + Expect.equal actual expected "" testCase "a sbyte works from string" <| fun _ -> let expected = Ok -25y let actual = Decode.fromString Decode.sbyte "\"-25\"" - equal expected actual + Expect.equal actual expected "" testCase "a sbyte output an error if value is too big" <| fun _ -> let expected = @@ -410,7 +419,7 @@ Reason: Value was either too large or too small for a sbyte let actual = Decode.fromString Decode.sbyte "128" - equal expected actual + Expect.equal actual expected "" testCase "a sbyte output an error if value is too small" <| fun _ -> let expected = @@ -423,7 +432,7 @@ Reason: Value was either too large or too small for a sbyte let actual = Decode.fromString Decode.sbyte "-129" - equal expected actual + Expect.equal actual expected "" testCase "a sbyte output an error if incorrect string" <| fun _ -> let expected = @@ -435,21 +444,21 @@ Expecting a sbyte but instead got: "maxime" let actual = Decode.fromString Decode.sbyte "\"maxime\"" - equal expected actual + Expect.equal actual expected "" testCase "an bigint works from number" <| fun _ -> let expected = Ok 12I let actual = Decode.fromString Decode.bigint "12" - equal expected actual + Expect.equal actual expected "" testCase "an bigint works from string" <| fun _ -> let expected = Ok 12I let actual = Decode.fromString Decode.bigint "\"12\"" - equal expected actual + Expect.equal actual expected "" testCase "an bigint output an error if invalid string" <| fun _ -> let expected = @@ -461,21 +470,30 @@ Expecting a bigint but instead got: "maxime" let actual = Decode.fromString Decode.bigint "\"maxime\"" - equal expected actual + Expect.equal actual expected "" testCase "a string representing a DateTime should be accepted as a string" <| fun _ -> let expected = "2018-10-01T11:12:55.00Z" let actual = Decode.fromString Decode.string "\"2018-10-01T11:12:55.00Z\"" - equal (Ok expected) actual + Expect.equal actual (Ok expected) "" + + testCase "a decimal works2" <| fun _ -> + + let expected = 0.7833M + let actual = + Decode.fromString Decode.decimal "\"0.7833\"" + + + Expect.equal actual (Ok expected) "" testCase "a datetime works" <| fun _ -> let expected = new DateTime(2018, 10, 1, 11, 12, 55, DateTimeKind.Utc) let actual = Decode.fromString Decode.datetime "\"2018-10-01T11:12:55.00Z\"" - equal (Ok expected) actual + Expect.equal (Ok expected) actual "" testCase "a datetime output an error if invalid string" <| fun _ -> let expected = @@ -488,7 +506,7 @@ Expecting a datetime but instead got: "invalid_string" let actual = Decode.fromString Decode.datetime "\"invalid_string\"" - equal expected actual + Expect.equal actual expected "" testCase "a datetime works with TimeZone" <| fun _ -> let localDate = DateTime(2018, 10, 1, 11, 12, 55, DateTimeKind.Local) @@ -498,7 +516,7 @@ Expecting a datetime but instead got: "invalid_string" let actual = Decode.fromString Decode.datetime json - equal expected actual + Expect.equal actual expected "" testCase "a datetimeOffset works" <| fun _ -> let expected = @@ -507,7 +525,7 @@ Expecting a datetime but instead got: "invalid_string" let json = "\"2018-07-02T12:23:45+02:00\"" let actual = Decode.fromString Decode.datetimeOffset json - equal expected actual + Expect.equal actual expected "" testCase "a datetimeOffset returns Error if invalid format" <| fun _ -> let expected = @@ -520,7 +538,7 @@ Expecting a datetimeoffset but instead got: "NOT A DATETIMEOFFSET" let actual = Decode.fromString Decode.datetimeOffset json - equal expected actual + Expect.equal actual expected "" testCase "a timespan works" <| fun _ -> let expected = @@ -529,7 +547,7 @@ Expecting a datetimeoffset but instead got: "NOT A DATETIMEOFFSET" let json = "\"23:45:00\"" let actual = Decode.fromString Decode.timespan json - equal expected actual + Expect.equal actual expected "" testCase "a timespan returns Error if invalid format" <| fun _ -> let expected = @@ -542,49 +560,49 @@ Expecting a timespan but instead got: "NOT A TimeSpan" let actual = Decode.fromString Decode.timespan json - equal expected actual + Expect.equal actual expected "" testCase "an enum works" <| fun _ -> let expected = Ok Enum_Int8.NinetyNine let actual = Decode.fromString Decode.Enum.sbyte "99" - equal expected actual + Expect.equal actual expected "" testCase "an enum works" <| fun _ -> let expected = Ok Enum_UInt8.NinetyNine let actual = Decode.fromString Decode.Enum.byte "99" - equal expected actual + Expect.equal actual expected "" testCase "an enum works" <| fun _ -> let expected = Ok Enum_Int.One let actual = Decode.fromString Decode.Enum.int "1" - equal expected actual + Expect.equal actual expected "" testCase "an enum works" <| fun _ -> let expected = Ok Enum_UInt32.NinetyNine let actual = Decode.fromString Decode.Enum.uint32 "99" - equal expected actual + Expect.equal actual expected "" testCase "an enum works" <| fun _ -> let expected = Ok Enum_Int16.NinetyNine let actual = Decode.fromString Decode.Enum.int16 "99" - equal expected actual + Expect.equal actual expected "" testCase "an enum works" <| fun _ -> let expected = Ok Enum_UInt16.NinetyNine let actual = Decode.fromString Decode.Enum.uint16 "99" - equal expected actual + Expect.equal actual expected "" ] @@ -596,7 +614,7 @@ Expecting a timespan but instead got: "NOT A TimeSpan" let actual = Decode.fromString (Decode.tuple2 Decode.int Decode.string) json - equal expected actual + Expect.equal actual expected "" testCase "tuple3 works" <| fun _ -> let json = """[1, "maxime", 2.5]""" @@ -609,7 +627,7 @@ Expecting a timespan but instead got: "NOT A TimeSpan" Decode.string Decode.float) json - equal expected actual + Expect.equal actual expected "" testCase "tuple4 works" <| fun _ -> let json = """[1, "maxime", 2.5, { "fieldA" : "test" }]""" @@ -623,7 +641,7 @@ Expecting a timespan but instead got: "NOT A TimeSpan" Decode.float SmallRecord.Decoder) json - equal expected actual + Expect.equal actual expected "" testCase "tuple5 works" <| fun _ -> let json = """[1, "maxime", 2.5, { "fieldA" : "test" }, false]""" @@ -638,7 +656,7 @@ Expecting a timespan but instead got: "NOT A TimeSpan" SmallRecord.Decoder Decode.bool) json - equal expected actual + Expect.equal actual expected "" testCase "tuple6 works" <| fun _ -> let json = """[1, "maxime", 2.5, { "fieldA" : "test" }, false, null]""" @@ -654,7 +672,7 @@ Expecting a timespan but instead got: "NOT A TimeSpan" Decode.bool (Decode.nil null)) json - equal expected actual + Expect.equal actual expected "" testCase "tuple7 works" <| fun _ -> let json = """[1, "maxime", 2.5, { "fieldA" : "test" }, false, null, 56]""" @@ -671,7 +689,7 @@ Expecting a timespan but instead got: "NOT A TimeSpan" (Decode.nil null) Decode.int) json - equal expected actual + Expect.equal actual expected "" testCase "tuple8 works" <| fun _ -> let json = """[1, "maxime", 2.5, { "fieldA" : "test" }, false, null, true, 98]""" @@ -689,7 +707,7 @@ Expecting a timespan but instead got: "NOT A TimeSpan" Decode.bool Decode.int) json - equal expected actual + Expect.equal actual expected "" testCase "tuple2 returns an error if invalid json" <| fun _ -> let json = """[1, false, "unused value"]""" @@ -706,7 +724,7 @@ Expecting a string but instead got: false Decode.int Decode.string) json - equal expected actual + Expect.equal actual expected "" testCase "tuple3 returns an error if invalid json" <| fun _ -> let json = """[1, "maxime", false]""" @@ -724,7 +742,7 @@ Expecting a float but instead got: false Decode.string Decode.float) json - equal expected actual + Expect.equal actual expected "" testCase "tuple4 returns an error if invalid json (missing index)" <| fun _ -> let json = """[1, "maxime", 2.5]""" @@ -748,7 +766,7 @@ Expecting a longer array. Need index `3` but there are only `3` entries. Decode.float SmallRecord.Decoder) json - equal expected actual + Expect.equal actual expected "" testCase "tuple4 returns an error if invalid json (error in the nested object)" <| fun _ -> let json = """[1, "maxime", 2.5, { "fieldA" : false }]""" @@ -767,7 +785,7 @@ Expecting a string but instead got: false Decode.float SmallRecord.Decoder) json - equal expected actual + Expect.equal actual expected "" testCase "tuple5 returns an error if invalid json" <| fun _ -> let json = """[1, "maxime", 2.5, { "fieldA" : "test" }, false]""" @@ -787,7 +805,7 @@ Expecting a datetime but instead got: false SmallRecord.Decoder Decode.datetime) json - equal expected actual + Expect.equal actual expected "" testCase "tuple6 returns an error if invalid json" <| fun _ -> let json = """[1, "maxime", 2.5, { "fieldA" : "test" }, "2018-10-01T11:12:55.00Z", false]""" @@ -808,7 +826,7 @@ Expecting null but instead got: false Decode.datetime (Decode.nil null)) json - equal expected actual + Expect.equal actual expected "" testCase "tuple7 returns an error if invalid json" <| fun _ -> let json = """[1, "maxime", 2.5, { "fieldA" : "test" }, "2018-10-01T11:12:55.00Z", null, false]""" @@ -830,7 +848,7 @@ Expecting an int but instead got: false (Decode.nil null) Decode.int) json - equal expected actual + Expect.equal actual expected "" testCase "tuple8 returns an error if invalid json" <| fun _ -> let json = """[1, "maxime", 2.5, { "fieldA" : "test" }, "2018-10-01T11:12:55.00Z", null, 56, "maxime"]""" @@ -853,20 +871,20 @@ Expecting an int but instead got: "maxime" Decode.int Decode.int) json - equal expected actual + Expect.equal actual expected "" ] testList "Object primitives" [ testCase "field works" <| fun _ -> - let json = """{ "name": "maxime", "age": 25 }""" + let json = """{ "age": 25, "name": "maxime" }""" let expected = Ok("maxime") let actual = Decode.fromString (Decode.field "name" Decode.string) json - equal expected actual + Expect.equal actual expected "" testCase "field output an error explaining why the value is considered invalid" <| fun _ -> let json = """{ "name": null, "age": 25 }""" @@ -881,25 +899,25 @@ Expecting an int but instead got: null let actual = Decode.fromString (Decode.field "name" Decode.int) json - equal expected actual + Expect.equal actual expected "" testCase "field output an error when field is missing" <| fun _ -> - let json = """{ "name": "maxime", "age": 25 }""" + let json = """{ "age": 25, "name": "maxime" }""" let expected = Error( """ Error at: `$` Expecting an object with a field named `height` but instead got: { - "name": "maxime", - "age": 25 + "age": 25, + "name": "maxime" } """.Trim()) let actual = Decode.fromString (Decode.field "height" Decode.float) json - equal expected actual + Expect.equal actual expected "" testCase "at works" <| fun _ -> @@ -909,10 +927,10 @@ Expecting an object with a field named `height` but instead got: let actual = Decode.fromString (Decode.at ["user"; "name"] Decode.string) json - equal expected actual + Expect.equal actual expected "" testCase "at output an error if the path failed" <| fun _ -> - let json = """{ "user": { "name": "maxime", "age": 25 } }""" + let json = """{ "user": { "age": 25, "name": "maxime" } }""" let expected = Error( """ @@ -920,17 +938,17 @@ Error at: `$.user.firstname` Expecting an object with path `user.firstname` but instead got: { "user": { - "name": "maxime", - "age": 25 + "age": 25, + "name": "maxime" } } -Node `firstname` is unkown. +Node `firstname` is unknown. """.Trim()) let actual = Decode.fromString (Decode.at ["user"; "firstname"] Decode.string) json - equal expected actual + Expect.equal actual expected "" testCase "at output an error explaining why the value is considered invalid" <| fun _ -> let json = """{ "name": null, "age": 25 }""" @@ -945,7 +963,7 @@ Expecting an int but instead got: null let actual = Decode.fromString (Decode.at [ "name" ] Decode.int) json - equal expected actual + Expect.equal actual expected "" testCase "index works" <| fun _ -> let json = """["maxime", "alfonso", "steffen"]""" @@ -954,7 +972,7 @@ Expecting an int but instead got: null let actual = Decode.fromString (Decode.index 1 Decode.string) json - equal expected actual + Expect.equal actual expected "" testCase "index output an error if array is to small" <| fun _ -> let json = """["maxime", "alfonso", "steffen"]""" @@ -973,7 +991,7 @@ Expecting a longer array. Need index `5` but there are only `3` entries. let actual = Decode.fromString (Decode.index 5 Decode.string) json - equal expected actual + Expect.equal actual expected "" testCase "index output an error if value isn't an array" <| fun _ -> let json = "1" @@ -987,11 +1005,10 @@ Expecting an array but instead got: 1 let actual = Decode.fromString (Decode.index 5 Decode.string) json - equal expected actual + Expect.equal actual expected "" ] - testList "Data structure" [ testCase "list works" <| fun _ -> @@ -1000,18 +1017,18 @@ Expecting an array but instead got: 1 let actual = Decode.fromString (Decode.list Decode.int) "[1, 2, 3]" - equal expected actual + Expect.equal actual expected "" - testCase "nested lists work" <| fun _ -> - [ [ "maxime2" ] ] - |> List.map (fun d -> - d - |> List.map Encode.string - |> Encode.list) - |> Encode.list - |> Encode.toString 4 - |> Decode.fromString (Decode.list (Decode.list Decode.string)) - |> function Ok v -> equal [["maxime2"]] v | Error er -> failwith er + // testCase "nested lists work" <| fun _ -> + // [ [ "maxime2" ] ] + // |> List.map (fun d -> + // d + // |> List.map Encode.string + // |> Encode.list) + // |> Encode.list + // |> Encode.toString 4 + // |> Decode.fromString (Decode.list (Decode.list Decode.string)) + // |> function Ok v -> Expect.equal [["maxime2"]] v "" | Error er -> failwith er testCase "an invalid list output an error" <| fun _ -> let expected = Error("Error at: `$`\nExpecting a list but instead got: 1") @@ -1019,7 +1036,7 @@ Expecting an array but instead got: 1 let actual = Decode.fromString (Decode.list Decode.int) "1" - equal expected actual + Expect.equal actual expected "" testCase "array works" <| fun _ -> // Need to pass by a list otherwise Fable use: @@ -1032,7 +1049,7 @@ Expecting an array but instead got: 1 let actual = Decode.fromString (Decode.array Decode.int) "[1, 2, 3]" - equal expected actual + Expect.equal actual expected "" testCase "an invalid array output an error" <| fun _ -> let expected = Error("Error at: `$`\nExpecting an array but instead got: 1") @@ -1040,7 +1057,7 @@ Expecting an array but instead got: 1 let actual = Decode.fromString (Decode.array Decode.int) "1" - equal expected actual + Expect.equal actual expected "" testCase "keys works" <| fun _ -> let expected = Ok(["a"; "b"; "c"]) @@ -1048,7 +1065,7 @@ Expecting an array but instead got: 1 let actual = Decode.fromString Decode.keys """{ "a": 1, "b": 2, "c": 3 }""" - equal expected actual + Expect.equal actual expected "" testCase "keys returns an error for invalid objects" <| fun _ -> let expected = Error("Error at: `$`\nExpecting an object but instead got: 1") @@ -1056,7 +1073,7 @@ Expecting an array but instead got: 1 let actual = Decode.fromString Decode.keys "1" - equal expected actual + Expect.equal actual expected "" testCase "keyValuePairs works" <| fun _ -> let expected = Ok([("a", 1) ; ("b", 2) ; ("c", 3)]) @@ -1064,7 +1081,7 @@ Expecting an array but instead got: 1 let actual = Decode.fromString (Decode.keyValuePairs Decode.int) """{ "a": 1, "b": 2, "c": 3 }""" - equal expected actual + Expect.equal actual expected "" testCase "dict works" <| fun _ -> let expected = Ok(Map.ofList([("a", 1) ; ("b", 2) ; ("c", 3)])) @@ -1072,7 +1089,7 @@ Expecting an array but instead got: 1 let actual = Decode.fromString (Decode.dict Decode.int) """{ "a": 1, "b": 2, "c": 3 }""" - equal expected actual + Expect.equal actual expected "" testCase "dict with custom decoder works" <| fun _ -> let expected = Ok(Map.ofList([("a", Record2.Create 1. 1.) ; ("b", Record2.Create 2. 2.) ; ("c", Record2.Create 3. 3.)])) @@ -1104,7 +1121,7 @@ Expecting an array but instead got: 1 } """ - equal expected actual + Expect.equal actual expected "" testCase "an invalid dict output an error" <| fun _ -> let expected = Error("Error at: `$`\nExpecting an object but instead got: 1") @@ -1112,7 +1129,7 @@ Expecting an array but instead got: 1 let actual = Decode.fromString (Decode.dict Decode.int) "1" - equal expected actual + Expect.equal actual expected "" ] @@ -1127,7 +1144,7 @@ Expecting an array but instead got: 1 let actual = Decode.fromString (Decode.list badInt) "[1,2,null,4]" - equal expected actual + Expect.equal actual expected "" testCase "oneOf works in combination with object builders" <| fun _ -> let json = """{ "Bar": { "name": "maxime", "age": 25 } }""" @@ -1146,7 +1163,7 @@ Expecting an array but instead got: 1 let actual = Decode.fromString decoder2 json - equal expected actual + Expect.equal actual expected "" testCase "oneOf works with optional" <| fun _ -> let decoder = @@ -1157,10 +1174,17 @@ Expecting an array but instead got: 1 Decode.field "Zero" Decode.bool |> Decode.map (fun _ -> Zero) ] - """{"Normal": 4.5}""" |> Decode.fromString decoder |> equal (Ok(Normal 4.5)) - """{"Reduced": 4.5}""" |> Decode.fromString decoder |> equal (Ok(Reduced(Some 4.5))) - """{"Reduced": null}""" |> Decode.fromString decoder |> equal (Ok(Reduced None)) - """{"Zero": true}""" |> Decode.fromString decoder |> equal (Ok Zero) + let a = """{"Normal": 4.5}""" |> Decode.fromString decoder + Expect.equal (Ok(Normal 4.5)) a "" + + let b = """{"Reduced": 4.5}""" |> Decode.fromString decoder + Expect.equal (Ok(Reduced(Some 4.5))) b "" + + let c = """{"Reduced": null}""" |> Decode.fromString decoder + Expect.equal (Ok(Reduced None)) c "" + + let d = """{"Zero": true}""" |> Decode.fromString decoder + Expect.equal (Ok Zero) d "" testCase "oneOf output errors if all case fails" <| fun _ -> let expected = @@ -1182,7 +1206,7 @@ Expecting an object but instead got: let actual = Decode.fromString (Decode.list badInt) "[1,2,null,4]" - equal expected actual + Expect.equal actual expected "" testCase "optional works" <| fun _ -> let json = """{ "name": "maxime", "age": 25, "something_undefined": null }""" @@ -1191,7 +1215,7 @@ Expecting an object but instead got: let actualValid = Decode.fromString (Decode.optional "name" Decode.string) json - equal expectedValid actualValid + Expect.equal expectedValid actualValid "" match Decode.fromString (Decode.optional "name" Decode.int) json with | Error _ -> () @@ -1201,13 +1225,13 @@ Expecting an object but instead got: let actualMissingField = Decode.fromString (Decode.optional "height" Decode.int) json - equal expectedMissingField actualMissingField + Expect.equal expectedMissingField actualMissingField "" let expectedUndefinedField = Ok(None) let actualUndefinedField = Decode.fromString (Decode.optional "something_undefined" Decode.string) json - equal expectedUndefinedField actualUndefinedField + Expect.equal expectedUndefinedField actualUndefinedField "" testCase "optional returns Error value if decoder fails" <| fun _ -> let json = """{ "name": 12, "age": 25 }""" @@ -1221,7 +1245,7 @@ Expecting a string but instead got: 12 let actual = Decode.fromString (Decode.optional "name" Decode.string) json - equal expected actual + Expect.equal actual expected "" testCase "optionalAt works" <| fun _ -> let json = """{ "data" : { "name": "maxime", "age": 25, "something_undefined": null } }""" @@ -1230,7 +1254,7 @@ Expecting a string but instead got: 12 let actualValid = Decode.fromString (Decode.optionalAt [ "data"; "name" ] Decode.string) json - equal expectedValid actualValid + Expect.equal expectedValid actualValid "" match Decode.fromString (Decode.optionalAt [ "data"; "name" ] Decode.int) json with | Error _ -> () @@ -1240,22 +1264,34 @@ Expecting a string but instead got: 12 let actualMissingField = Decode.fromString (Decode.optionalAt [ "data"; "height" ] Decode.int) json - equal expectedMissingField actualMissingField + Expect.equal expectedMissingField actualMissingField "" let expectedUndefinedField = Ok(None) let actualUndefinedField = Decode.fromString (Decode.optionalAt [ "data"; "something_undefined" ] Decode.string) json - equal expectedUndefinedField actualUndefinedField + Expect.equal expectedUndefinedField actualUndefinedField "" + + let expectedUndefinedField = Ok(None) + let actualUndefinedField = + Decode.fromString (Decode.optionalAt [ "data"; "something_undefined"; "name" ] Decode.string) json + + Expect.equal expectedUndefinedField actualUndefinedField "" + + testCase "Decode.option works" <| fun _ -> + let expected= Ok(Some "maxime") + let actual = + Decode.fromString (Decode.option Decode.string) "\"maxime\"" + Expect.equal expected actual "" testCase "combining field and option decoders works" <| fun _ -> - let json = """{ "name": "maxime", "age": 25, "something_undefined": null }""" + let json = """{ "age": 25, "name": "maxime", "something_undefined": null }""" let expectedValid = Ok(Some "maxime") let actualValid = Decode.fromString (Decode.field "name" (Decode.option Decode.string)) json - equal expectedValid actualValid + Expect.equal actualValid expectedValid "" match Decode.fromString (Decode.field "name" (Decode.option Decode.int)) json with | Error msg -> @@ -1264,7 +1300,7 @@ Expecting a string but instead got: 12 Error at: `$.name` Expecting an int but instead got: "maxime" """.Trim() - equal expected msg + Expect.equal msg expected "" | Ok _ -> failwith "Expected type error for `name` field #1" match Decode.fromString (Decode.field "this_field_do_not_exist" (Decode.option Decode.int)) json with @@ -1274,18 +1310,18 @@ Expecting an int but instead got: "maxime" Error at: `$` Expecting an object with a field named `this_field_do_not_exist` but instead got: { - "name": "maxime", "age": 25, + "name": "maxime", "something_undefined": null } """.Trim() - equal expected msg + Expect.equal msg expected "" | Ok _ -> failwith "Expected type error for `name` field #2" match Decode.fromString (Decode.field "something_undefined" (Decode.option Decode.int)) json with | Error _ -> failwith """`Decode.field "something_undefined" (Decode.option Decode.int)` test should pass""" - | Ok result -> equal None result + | Ok result -> Expect.equal None result "" // Same tests as before but we are calling `option` then `field` @@ -1293,7 +1329,7 @@ Expecting an object with a field named `this_field_do_not_exist` but instead got let actualValid2 = Decode.fromString (Decode.option (Decode.field "name" Decode.string)) json - equal expectedValid2 actualValid2 + Expect.equal actualValid2 expectedValid2 "" match Decode.fromString (Decode.option (Decode.field "name" Decode.int)) json with | Error msg -> @@ -1302,7 +1338,7 @@ Expecting an object with a field named `this_field_do_not_exist` but instead got Error at: `$.name` Expecting an int but instead got: "maxime" """.Trim() - equal expected msg + Expect.equal msg expected "" | Ok _ -> failwith "Expected type error for `name` field #3" match Decode.fromString (Decode.option (Decode.field "this_field_do_not_exist" Decode.int)) json with @@ -1312,12 +1348,12 @@ Expecting an int but instead got: "maxime" Error at: `$` Expecting an object with a field named `this_field_do_not_exist` but instead got: { - "name": "maxime", "age": 25, + "name": "maxime", "something_undefined": null } """.Trim() - equal expected msg + Expect.equal msg expected "" | Ok _ -> failwith "Expected type error for `name` field #4" match Decode.fromString (Decode.option (Decode.field "something_undefined" Decode.int)) json with @@ -1327,7 +1363,7 @@ Expecting an object with a field named `this_field_do_not_exist` but instead got Error at: `$.something_undefined` Expecting an int but instead got: null """.Trim() - equal expected msg + Expect.equal msg expected "" | Ok _ -> failwith "Expected type error for `name` field" /// Alfonso: Should this test pass? We should use Decode.optional instead @@ -1348,13 +1384,13 @@ Expecting an int but instead got: null Error at: `$` Expecting an object with a field named `height` but instead got: { - "name": "maxime", "age": 25, + "name": "maxime", "something_undefined": null } """.Trim() - equal expected msg + Expect.equal msg expected "" | Ok _ -> failwith "Expected type error for `height` field" @@ -1362,7 +1398,7 @@ Expecting an object with a field named `height` but instead got: let actualUndefinedField = Decode.fromString (Decode.field "something_undefined" (Decode.option Decode.string)) json - equal expectedUndefinedField actualUndefinedField + Expect.equal expectedUndefinedField actualUndefinedField "" ] @@ -1373,32 +1409,40 @@ Expecting an object with a field named `height` but instead got: let actual = Decode.fromString (Decode.nil 20) "null" - equal expected actual + Expect.equal actual expected "" testCase "null works (test on a boolean)" <| fun _ -> let expected = Ok(false) let actual = Decode.fromString (Decode.nil false) "null" - equal expected actual + Expect.equal actual expected "" testCase "succeed works" <| fun _ -> let expected = Ok(7) let actual = Decode.fromString (Decode.succeed 7) "true" - equal expected actual + Expect.equal actual expected "" testCase "succeed output an error if the JSON is invalid" <| fun _ -> - #if FABLE_COMPILER - let expected = Error("Given an invalid JSON: Unexpected token m in JSON at position 0") - #else - let expected = Error("Given an invalid JSON: Unexpected character encountered while parsing value: m. Path '', line 0, position 0.") - #endif + let expected = + Error( + """ +Given an invalid JSON: Invalid JSON starting at character 0, snippet = +----- +maxime +----- +json = +----- +maxime +----- + """.Trim()) + let actual = Decode.fromString (Decode.succeed 7) "maxime" - equal expected actual + Expect.equal actual expected "" testCase "fail works" <| fun _ -> let msg = "Failing because it's fun" @@ -1406,7 +1450,7 @@ Expecting an object with a field named `height` but instead got: let actual = Decode.fromString (Decode.fail msg) "true" - equal expected actual + Expect.equal actual expected "" testCase "andThen works" <| fun _ -> let expected = Ok 1 @@ -1426,8 +1470,7 @@ Expecting an object with a field named `height` but instead got: let actual = Decode.fromString info """{ "version": 3, "data": 2 }""" - equal expected actual - + Expect.equal actual expected "" testCase "andThen generate an error if an error occuered" <| fun _ -> let expected = @@ -1436,8 +1479,8 @@ Expecting an object with a field named `height` but instead got: Error at: `$` Expecting an object with a field named `version` but instead got: { - "info": 3, - "data": 2 + "data": 3, + "info": 2 } """.Trim()) let infoHelp version : Decoder = @@ -1454,10 +1497,9 @@ Expecting an object with a field named `version` but instead got: |> Decode.andThen infoHelp let actual = - Decode.fromString info """{ "info": 3, "data": 2 }""" - - equal expected actual + Decode.fromString info """{ "data": 3, "info": 2 }""" + Expect.equal actual expected "" testCase "all works" <| fun _ -> let expected = Ok [1; 2; 3] @@ -1470,7 +1512,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decodeAll "{}" - equal expected actual + Expect.equal actual expected "" testCase "combining Decode.all and Decode.keys works" <| fun _ -> let expected = Ok [1; 2; 3] @@ -1485,7 +1527,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decoder """{ "a": 1, "b": 2, "c": 3 }""" - equal expected actual + Expect.equal actual expected "" testCase "all succeeds on empty lists" <| fun _ -> let expected = Ok [] @@ -1494,8 +1536,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decodeNone "{}" - equal expected actual - + Expect.equal actual expected "" testCase "all fails when one decoder fails" <| fun _ -> let expected = Error("Error at: `$`\nExpecting an int but instead got: {}") @@ -1508,7 +1549,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decodeAll "{}" - equal expected actual + Expect.equal actual expected "" ] testList "Mapping" [ @@ -1520,8 +1561,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString stringLength "\"maxime\"" - equal expected actual - + Expect.equal actual expected "" testCase "map2 works" <| fun _ -> let expected = Ok({a = 1.; b = 2.} : Record2) @@ -1534,7 +1574,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decodePoint jsonRecord - equal expected actual + Expect.equal actual expected "" testCase "map3 works" <| fun _ -> let expected = Ok({ a = 1. @@ -1550,7 +1590,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decodePoint jsonRecord - equal expected actual + Expect.equal actual expected "" testCase "map4 works" <| fun _ -> let expected = Ok({ a = 1. @@ -1568,7 +1608,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decodePoint jsonRecord - equal expected actual + Expect.equal actual expected "" testCase "map5 works" <| fun _ -> let expected = Ok({ a = 1. @@ -1588,7 +1628,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decodePoint jsonRecord - equal expected actual + Expect.equal actual expected "" testCase "map6 works" <| fun _ -> let expected = Ok({ a = 1. @@ -1610,7 +1650,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decodePoint jsonRecord - equal expected actual + Expect.equal actual expected "" testCase "map7 works" <| fun _ -> let expected = Ok({ a = 1. @@ -1634,7 +1674,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decodePoint jsonRecord - equal expected actual + Expect.equal actual expected "" testCase "map8 works" <| fun _ -> let expected = Ok({ a = 1. @@ -1660,7 +1700,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decodePoint jsonRecord - equal expected actual + Expect.equal actual expected "" testCase "map2 generate an error if invalid" <| fun _ -> let expected = Error("Error at: `$.a`\nExpecting a float but instead got: \"invalid_a_field\"") @@ -1673,14 +1713,14 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decodePoint jsonRecordInvalid - equal expected actual + Expect.equal actual expected "" ] testList "object builder" [ testCase "get.Required.Field works" <| fun _ -> - let json = """{ "name": "maxime", "age": 25 }""" + let json = """{ "age": 25, "name": "maxime" }""" let expected = Ok({ fieldA = "maxime" }) let decoder = @@ -1692,7 +1732,7 @@ Expecting an object with a field named `version` but instead got: let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Required.Field returns Error if field is missing" <| fun _ -> let json = """{ "age": 25 }""" @@ -1715,7 +1755,7 @@ Expecting an object with a field named `name` but instead got: let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Required.Field returns Error if type is incorrect" <| fun _ -> let json = """{ "name": 12, "age": 25 }""" @@ -1735,10 +1775,10 @@ Expecting a string but instead got: 12 let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.Field works" <| fun _ -> - let json = """{ "name": "maxime", "age": 25 }""" + let json = """{ "age": 25, "name": "maxime" }""" let expected = Ok({ optionalField = Some "maxime" }) let decoder = @@ -1750,7 +1790,7 @@ Expecting a string but instead got: 12 let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.Field returns None value if field is missing" <| fun _ -> let json = """{ "age": 25 }""" @@ -1765,7 +1805,7 @@ Expecting a string but instead got: 12 let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.Field returns None if field is null" <| fun _ -> let json = """{ "name": null, "age": 25 }""" @@ -1780,7 +1820,7 @@ Expecting a string but instead got: 12 let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.Field returns Error value if decoder fails" <| fun _ -> let json = """{ "name": 12, "age": 25 }""" @@ -1796,7 +1836,7 @@ Expecting a string but instead got: 12 let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "nested get.Optional.Field > get.Required.Field returns None if field is null" <| fun _ -> let json = """{ "user": null, "field2": 25 }""" @@ -1821,7 +1861,7 @@ Expecting a string but instead got: 12 let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.Field returns Error if type is incorrect" <| fun _ -> let json = """{ "name": 12, "age": 25 }""" @@ -1841,8 +1881,7 @@ Expecting a string but instead got: 12 let actual = Decode.fromString decoder json - equal expected actual - + Expect.equal actual expected "" testCase "get.Required.At works" <| fun _ -> @@ -1858,7 +1897,7 @@ Expecting a string but instead got: 12 let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Required.At returns Error if non-object in path" <| fun _ -> let json = """{ "user": "maxime" }""" @@ -1879,10 +1918,10 @@ Expecting an object but instead got: let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Required.At returns Error if field missing" <| fun _ -> - let json = """{ "user": { "name": "maxime", "age": 25 } }""" + let json = """{ "user": { "age": 25, "name": "maxime" } }""" let expected = Error( """ @@ -1890,11 +1929,11 @@ Error at: `$.user.firstname` Expecting an object with path `user.firstname` but instead got: { "user": { - "name": "maxime", - "age": 25 + "age": 25, + "name": "maxime" } } -Node `firstname` is unkown. +Node `firstname` is unknown. """.Trim()) let decoder = @@ -1906,7 +1945,7 @@ Node `firstname` is unkown. let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Required.At returns Error if type is incorrect" <| fun _ -> let json = """{ "user": { "name": 12, "age": 25 } }""" @@ -1926,7 +1965,7 @@ Expecting a string but instead got: 12 let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.At works" <| fun _ -> @@ -1942,7 +1981,7 @@ Expecting a string but instead got: 12 let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.At returns 'type error' if non-object in path" <| fun _ -> let json = """{ "user": "maxime" }""" @@ -1964,7 +2003,7 @@ Expecting an object but instead got: let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.At returns None if field missing" <| fun _ -> let json = """{ "user": { "name": "maxime", "age": 25 } }""" @@ -1979,7 +2018,7 @@ Expecting an object but instead got: let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.At returns Error if type is incorrect" <| fun _ -> let json = """{ "user": { "name": 12, "age": 25 } }""" @@ -1999,7 +2038,7 @@ Expecting a string but instead got: 12 let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" testCase "complex object builder works" <| fun _ -> let expected = @@ -2008,11 +2047,13 @@ Expecting a string but instead got: 12 let userDecoder = Decode.object (fun get -> - { Id = get.Required.Field "id" Decode.int - Name = get.Optional.Field "name" Decode.string + { + Id = get.Required.Field "id" Decode.int + Name = get.Optional.Field "name" Decode.string |> Option.defaultValue "" - Email = get.Required.Field "email" Decode.string - Followers = 0 } + Email = get.Required.Field "email" Decode.string + Followers = 0 + } ) let actual = @@ -2020,12 +2061,12 @@ Expecting a string but instead got: 12 userDecoder """{ "id": 67, "email": "user@mail.com" }""" - equal expected actual + Expect.equal actual expected "" testCase "get.Field.Raw works" <| fun _ -> let json = """{ "enabled": true, - "shape": "circle", +"shape": "circle", "radius": 20 }""" let shapeDecoder = @@ -2040,8 +2081,10 @@ Expecting a string but instead got: 12 let decoder = Decode.object (fun get -> - { Enabled = get.Required.Field "enabled" Decode.bool - Shape = get.Required.Raw shapeDecoder } : MyObj + { + Enabled = get.Required.Field "enabled" Decode.bool + Shape = get.Required.Raw shapeDecoder + } : MyObj ) let actual = @@ -2050,15 +2093,18 @@ Expecting a string but instead got: 12 json let expected = - Ok ({ Enabled = true - Shape = Circle 20 } : MyObj) + Ok ( + { + Enabled = true + Shape = Circle 20 + } : MyObj) - equal expected actual + Expect.equal actual expected "" testCase "get.Field.Raw returns Error if a decoder fail" <| fun _ -> let json = """{ "enabled": true, - "shape": "custom_shape", +"shape": "custom_shape", "radius": 20 }""" let shapeDecoder = @@ -2073,8 +2119,10 @@ Expecting a string but instead got: 12 let decoder = Decode.object (fun get -> - { Enabled = get.Required.Field "enabled" Decode.bool - Shape = get.Required.Raw shapeDecoder } : MyObj + { + Enabled = get.Required.Field "enabled" Decode.bool + Shape = get.Required.Raw shapeDecoder + } : MyObj ) let actual = @@ -2085,12 +2133,12 @@ Expecting a string but instead got: 12 let expected = Error "Error at: `$`\nThe following `failure` occurred with the decoder: Unknown shape type custom_shape" - equal expected actual + Expect.equal actual expected "" testCase "get.Field.Raw returns Error if a field is missing in the 'raw decoder'" <| fun _ -> let json = """{ "enabled": true, - "shape": "circle" +"shape": "circle" }""" let shapeDecoder = Decode.field "shape" Decode.string @@ -2104,8 +2152,10 @@ Expecting a string but instead got: 12 let decoder = Decode.object (fun get -> - { Enabled = get.Required.Field "enabled" Decode.bool - Shape = get.Required.Raw shapeDecoder } : MyObj + { + Enabled = get.Required.Field "enabled" Decode.bool + Shape = get.Required.Raw shapeDecoder + } : MyObj ) let actual = @@ -2123,12 +2173,12 @@ Expecting an object with a field named `radius` but instead got: "shape": "circle" } """.Trim()) - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.Raw works" <| fun _ -> let json = """{ "enabled": true, - "shape": "circle", +"shape": "circle", "radius": 20 }""" let shapeDecoder = @@ -2143,8 +2193,10 @@ Expecting an object with a field named `radius` but instead got: let decoder = Decode.object (fun get -> - { Enabled = get.Required.Field "enabled" Decode.bool - Shape = get.Optional.Raw shapeDecoder } + { + Enabled = get.Required.Field "enabled" Decode.bool + Shape = get.Optional.Raw shapeDecoder + } ) let actual = @@ -2153,15 +2205,18 @@ Expecting an object with a field named `radius` but instead got: json let expected = - Ok { Enabled = true - Shape = Some (Circle 20) } + Ok + { + Enabled = true + Shape = Some (Circle 20) + } - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.Raw returns None if a field is missing" <| fun _ -> let json = """{ "enabled": true, - "shape": "circle" + "shape": "circle" }""" let shapeDecoder = Decode.field "shape" Decode.string @@ -2175,8 +2230,10 @@ Expecting an object with a field named `radius` but instead got: let decoder = Decode.object (fun get -> - { Enabled = get.Required.Field "enabled" Decode.bool - Shape = get.Optional.Raw shapeDecoder } + { + Enabled = get.Required.Field "enabled" Decode.bool + Shape = get.Optional.Raw shapeDecoder + } ) let actual = @@ -2185,16 +2242,19 @@ Expecting an object with a field named `radius` but instead got: json let expected = - Ok { Enabled = true - Shape = None } + Ok + { + Enabled = true + Shape = None + } - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.Raw returns an Error if a decoder fail" <| fun _ -> let json = """{ "enabled": true, - "shape": "invalid_shape" -}""" + "shape": "invalid_shape" + }""" let shapeDecoder = Decode.field "shape" Decode.string |> Decode.andThen (function @@ -2207,8 +2267,10 @@ Expecting an object with a field named `radius` but instead got: let decoder = Decode.object (fun get -> - { Enabled = get.Required.Field "enabled" Decode.bool - Shape = get.Optional.Raw shapeDecoder } + { + Enabled = get.Required.Field "enabled" Decode.bool + Shape = get.Optional.Raw shapeDecoder + } ) let actual = @@ -2219,45 +2281,45 @@ Expecting an object with a field named `radius` but instead got: let expected = Error "Error at: `$`\nThe following `failure` occurred with the decoder: Unknown shape type invalid_shape" - equal expected actual + Expect.equal actual expected "" testCase "get.Optional.Raw returns an Error if the type is invalid" <| fun _ -> - let json = """{ - "enabled": true, - "shape": "circle", - "radius": "maxime" -}""" - let shapeDecoder = - Decode.field "shape" Decode.string - |> Decode.andThen (function - | "circle" -> - Shape.DecoderCircle - | "rectangle" -> - Shape.DecoderRectangle - | shape -> - Decode.fail (sprintf "Unknown shape type %s" shape)) - - let decoder = - Decode.object (fun get -> - { Enabled = get.Required.Field "enabled" Decode.bool - Shape = get.Optional.Raw shapeDecoder } - ) - - let actual = - Decode.fromString - decoder - json - - let expected = - Error "Error at: `$.radius`\nExpecting an int but instead got: \"maxime\"" - - equal expected actual + let json = """{ + "enabled": true, + "shape": "circle", + "radius": "maxime" + }""" + let shapeDecoder = + Decode.field "shape" Decode.string + |> Decode.andThen (function + | "circle" -> + Shape.DecoderCircle + | "rectangle" -> + Shape.DecoderRectangle + | shape -> + Decode.fail (sprintf "Unknown shape type %s" shape)) + + let decoder = + Decode.object (fun get -> + { Enabled = get.Required.Field "enabled" Decode.bool + Shape = get.Optional.Raw shapeDecoder } + ) + + let actual = + Decode.fromString + decoder + json + + let expected = + Error "Error at: `$.radius`\nExpecting an int but instead got: \"maxime\"" + + Expect.equal actual expected "" testCase "get.Optional.Raw returns None if a decoder fails with null" <| fun _ -> let json = """{ - "enabled": true, - "shape": null -}""" + "enabled": true, + "shape": null + }""" let shapeDecoder = Decode.field "shape" Decode.string |> Decode.andThen (function @@ -2270,8 +2332,10 @@ Expecting an object with a field named `radius` but instead got: let decoder = Decode.object (fun get -> - { Enabled = get.Required.Field "enabled" Decode.bool - Shape = get.Optional.Raw shapeDecoder } + { + Enabled = get.Required.Field "enabled" Decode.bool + Shape = get.Optional.Raw shapeDecoder + } ) let actual = @@ -2280,10 +2344,13 @@ Expecting an object with a field named `radius` but instead got: json let expected = - Ok { Enabled = true - Shape = None } + Ok + { + Enabled = true + Shape = None + } - equal expected actual + Expect.equal actual expected "" testCase "Object builders returns all the Errors" <| fun _ -> let json = """{ "age": 25, "fieldC": "not_a_number", "fieldD": { "sub_field": "not_a_boolean" } }""" @@ -2311,7 +2378,7 @@ Expecting an object with path `missing_field_2.sub_field` but instead got: "sub_field": "not_a_boolean" } } -Node `sub_field` is unkown. +Node `sub_field` is unknown. Error at: `$.fieldC` Expecting an int but instead got: "not_a_number" @@ -2333,569 +2400,8 @@ Expecting a boolean but instead got: "not_a_boolean" let actual = Decode.fromString decoder json - equal expected actual + Expect.equal actual expected "" ] - testList "Auto" [ - testCase "Auto.Decode.fromString works" <| fun _ -> - let now = DateTime.Now - let value : Record9 = - { - a = 5 - b = "bar" - c = [false, 3; true, 5; false, 10] - d = [|Some(Foo 14); None|] - e = Map [("oh", { a = 2.; b = 2. }); ("ah", { a = -1.5; b = 0. })] - f = now - g = set [{ a = 2.; b = 2. }; { a = -1.5; b = 0. }] - h = TimeSpan.FromSeconds(5.) - i = 120y - j = 120uy - k = 250s - l = 250us - m = 99u - n = 99L - o = 999UL - p = () - // r = seq [ "item n°1"; "item n°2"] - } - let extra = - Extra.empty - |> Extra.withInt64 - |> Extra.withUInt64 - let json = Encode.Auto.toString(4, value, extra = extra) - // printfn "AUTO ENCODED %s" json - let r2 = Decode.Auto.unsafeFromString(json, extra = extra) - equal 5 r2.a - equal "bar" r2.b - equal [false, 3; true, 5; false, 10] r2.c - equal (Some(Foo 14)) r2.d.[0] - equal None r2.d.[1] - equal -1.5 (Map.find "ah" r2.e).a - equal 2. (Map.find "oh" r2.e).b - equal (now.ToString()) (value.f.ToString()) - equal true (Set.contains { a = -1.5; b = 0. } r2.g) - equal false (Set.contains { a = 1.5; b = 0. } r2.g) - equal 5000. value.h.TotalMilliseconds - equal 120y r2.i - equal 120uy r2.j - equal 250s r2.k - equal 250us r2.l - equal 99u r2.m - equal 99L r2.n - equal 999UL r2.o - equal () r2.p - // equal ((seq [ "item n°1"; "item n°2"]) |> Seq.toList) (r2.r |> Seq.toList) - - testCase "Auto serialization works with recursive types" <| fun _ -> - let len xs = - let rec lenInner acc = function - | Cons(_,rest) -> lenInner (acc + 1) rest - | Nil -> acc - lenInner 0 xs - let li = Cons(1, Cons(2, Cons(3, Nil))) - let json = Encode.Auto.toString(4, li) - // printfn "AUTO ENCODED MYLIST %s" json - let li2 = Decode.Auto.unsafeFromString>(json) - len li2 |> equal 3 - match li with - | Cons(i1, Cons(i2, Cons(i3, Nil))) -> i1 + i2 + i3 - | Cons(i,_) -> i - | Nil -> 0 - |> equal 6 - - testCase "Auto decoders works for string" <| fun _ -> - let value = "maxime" - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works for guid" <| fun _ -> - let value = Guid.NewGuid() - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works for int" <| fun _ -> - let value = 12 - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works for int64" <| fun _ -> - let extra = Extra.empty |> Extra.withInt64 - let value = 9999999999L - let json = Encode.Auto.toString(4, value, extra=extra) - let res = Decode.Auto.unsafeFromString(json, extra=extra) - equal value res - - testCase "Auto decoders works for uint32" <| fun _ -> - let value = 12u - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works for uint64" <| fun _ -> - let extra = Extra.empty |> Extra.withUInt64 - let value = 9999999999999999999UL - let json = Encode.Auto.toString(4, value, extra=extra) - let res = Decode.Auto.unsafeFromString(json, extra=extra) - equal value res - - testCase "Auto decoders works for bigint" <| fun _ -> - let extra = Extra.empty |> Extra.withBigInt - let value = 99999999999999999999999I - let json = Encode.Auto.toString(4, value, extra=extra) - let res = Decode.Auto.unsafeFromString(json, extra=extra) - equal value res - - testCase "Auto decoders works for bool" <| fun _ -> - let value = false - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works for float" <| fun _ -> - let value = 12. - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works for decimal" <| fun _ -> - let extra = Extra.empty |> Extra.withDecimal - let value = 0.7833M - let json = Encode.Auto.toString(4, value, extra=extra) - let res = Decode.Auto.unsafeFromString(json, extra=extra) - equal value res - - // testCase "Auto decoders works for datetime" <| fun _ -> - // let value = DateTime.Now - // let json = Encode.Auto.toString(4, value) - // let res = Decode.Auto.unsafeFromString(json) - // equal value.Date res.Date - // equal value.Hour res.Hour - // equal value.Minute res.Minute - // equal value.Second res.Second - - testCase "Auto decoders works for datetime UTC" <| fun _ -> - let value = DateTime.UtcNow - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value.Date res.Date - equal value.Hour res.Hour - equal value.Minute res.Minute - equal value.Second res.Second - - testCase "Auto decoders works for datetimeOffset" <| fun _ -> - let value = DateTimeOffset.Now - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json).ToLocalTime() - equal value.Date res.Date - equal value.Hour res.Hour - equal value.Minute res.Minute - equal value.Second res.Second - - testCase "Auto decoders works for datetimeOffset UTC" <| fun _ -> - let value = DateTimeOffset.UtcNow - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json).ToUniversalTime() - // printfn "SOURCE %A JSON %s OUTPUT %A" value json res - equal value.Date res.Date - equal value.Hour res.Hour - equal value.Minute res.Minute - equal value.Second res.Second - - testCase "Auto decoders works for TimeSpan" <| fun _ -> - let value = TimeSpan(1,2,3,4,5) - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value.Days res.Days - equal value.Hours res.Hours - equal value.Minutes res.Minutes - equal value.Seconds res.Seconds - equal value.Milliseconds res.Milliseconds - - testCase "Auto decoders works for list" <| fun _ -> - let value = [1; 2; 3; 4] - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works for array" <| fun _ -> - let value = [| 1; 2; 3; 4 |] - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works for option None" <| fun _ -> - let value = None - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works for option Some" <| fun _ -> - let value = Some 5 - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works for Unit" <| fun _ -> - let value = () - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works for enum" <| fun _ -> - let res = Decode.Auto.unsafeFromString("99") - equal Enum_Int8.NinetyNine res - - testCase "Auto decoders for enum returns an error if the Enum value is invalid" <| fun _ -> -#if FABLE_COMPILER - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types.Enum_Int8[System.SByte] but instead got: 2 -Reason: Unkown value provided for the enum - """.Trim()) -#else - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types+Enum_Int8 but instead got: 2 -Reason: Unkown value provided for the enum - """.Trim()) -#endif - - let res = Decode.Auto.fromString("2") - equal value res - - testCase "Auto decoders works for enum" <| fun _ -> - let res = Decode.Auto.unsafeFromString("99") - equal Enum_UInt8.NinetyNine res - - testCase "Auto decoders for enum returns an error if the Enum value is invalid" <| fun _ -> -#if FABLE_COMPILER - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types.Enum_UInt8[System.Byte] but instead got: 2 -Reason: Unkown value provided for the enum - """.Trim()) -#else - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types+Enum_UInt8 but instead got: 2 -Reason: Unkown value provided for the enum - """.Trim()) -#endif - - let res = Decode.Auto.fromString("2") - equal value res - - testCase "Auto decoders works for enum" <| fun _ -> - let res = Decode.Auto.unsafeFromString("99") - equal Enum_Int16.NinetyNine res - - testCase "Auto decoders for enum returns an error if the Enum value is invalid" <| fun _ -> -#if FABLE_COMPILER - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types.Enum_Int16[System.Int16] but instead got: 2 -Reason: Unkown value provided for the enum - """.Trim()) -#else - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types+Enum_Int16 but instead got: 2 -Reason: Unkown value provided for the enum - """.Trim()) -#endif - - let res = Decode.Auto.fromString("2") - equal value res - - testCase "Auto decoders works for enum" <| fun _ -> - let res = Decode.Auto.unsafeFromString("99") - equal Enum_UInt16.NinetyNine res - - testCase "Auto decoders for enum<ºint16> returns an error if the Enum value is invalid" <| fun _ -> -#if FABLE_COMPILER - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types.Enum_UInt16[System.UInt16] but instead got: 2 -Reason: Unkown value provided for the enum - """.Trim()) -#else - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types+Enum_UInt16 but instead got: 2 -Reason: Unkown value provided for the enum - """.Trim()) -#endif - - let res = Decode.Auto.fromString("2") - equal value res - - testCase "Auto decoders works for enum" <| fun _ -> - let res = Decode.Auto.unsafeFromString("1") - equal Enum_Int.One res - - testCase "Auto decoders for enum returns an error if the Enum value is invalid" <| fun _ -> -#if FABLE_COMPILER - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types.Enum_Int[System.Int32] but instead got: 4 -Reason: Unkown value provided for the enum - """.Trim()) -#else - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types+Enum_Int but instead got: 4 -Reason: Unkown value provided for the enum - """.Trim()) -#endif - - let res = Decode.Auto.fromString("4") - equal value res - - testCase "Auto decoders works for enum" <| fun _ -> - let res = Decode.Auto.unsafeFromString("99") - equal Enum_UInt32.NinetyNine res - - testCase "Auto decoders for enum returns an error if the Enum value is invalid" <| fun _ -> -#if FABLE_COMPILER - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types.Enum_UInt32[System.UInt32] but instead got: 2 -Reason: Unkown value provided for the enum - """.Trim()) -#else - let value = - Error( - """ -Error at: `$` -Expecting Tests.Types+Enum_UInt32 but instead got: 2 -Reason: Unkown value provided for the enum - """.Trim()) -#endif - - let res = Decode.Auto.fromString("2") - equal value res - - (* - #if NETFRAMEWORK - testCase "Auto decoders works with char based Enums" <| fun _ -> - let value = CharEnum.A - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - #endif - *) - testCase "Auto decoders works for null" <| fun _ -> - let value = null - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString(json) - equal value res - - testCase "Auto decoders works even if type is determined by the compiler" <| fun _ -> - let value = [1; 2; 3; 4] - let json = Encode.Auto.toString(4, value) - let res = Decode.Auto.unsafeFromString<_>(json) - equal value res - - testCase "Auto.unsafeFromString works with camelCase" <| fun _ -> - let json = """{ "id" : 0, "name": "maxime", "email": "mail@domain.com", "followers": 0 }""" - let user = Decode.Auto.unsafeFromString(json, caseStrategy=CamelCase) - equal "maxime" user.Name - equal 0 user.Id - equal 0 user.Followers - equal "mail@domain.com" user.Email - - testCase "Auto.fromString works with snake_case" <| fun _ -> - let json = """{ "one" : 1, "two_part": 2, "three_part_field": 3 }""" - let decoded = Decode.Auto.fromString(json, caseStrategy=SnakeCase) - let expected = Ok { One = 1; TwoPart = 2; ThreePartField = 3 } - equal expected decoded - - testCase "Auto.fromString works with camelCase" <| fun _ -> - let json = """{ "id" : 0, "name": "maxime", "email": "mail@domain.com", "followers": 0 }""" - let user = Decode.Auto.fromString(json, caseStrategy=CamelCase) - let expected = Ok { Id = 0; Name = "maxime"; Email = "mail@domain.com"; Followers = 0 } - equal expected user - - testCase "Auto.fromString works for records with an actual value for the optional field value" <| fun _ -> - let json = """{ "maybe" : "maybe value", "must": "must value"}""" - let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) - let expected = - Ok ({ Maybe = Some "maybe value" - Must = "must value" } : TestMaybeRecord) - equal expected actual - - testCase "Auto.fromString works for records with `null` for the optional field value" <| fun _ -> - let json = """{ "maybe" : null, "must": "must value"}""" - let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) - let expected = - Ok ({ Maybe = None - Must = "must value" } : TestMaybeRecord) - equal expected actual - - testCase "Auto.fromString works for records with `null` for the optional field value on classes" <| fun _ -> - let json = """{ "maybeClass" : null, "must": "must value"}""" - let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) - let expected = - Ok ({ MaybeClass = None - Must = "must value" } : RecordWithOptionalClass) - equal expected actual - - testCase "Auto.fromString works for records missing optional field value on classes" <| fun _ -> - let json = """{ "must": "must value"}""" - let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) - let expected = - Ok ({ MaybeClass = None - Must = "must value" } : RecordWithOptionalClass) - equal expected actual - - testCase "Auto.generateDecoder throws for field using a non optional class" <| fun _ -> - let expected = "Cannot generate auto decoder for Tests.Types.BaseClass. Please pass an extra decoder." - let errorMsg = - try - let decoder = Decode.Auto.generateDecoder(caseStrategy=CamelCase) - "" - with ex -> - ex.Message - errorMsg.Replace("+", ".") |> equal expected - - testCase "Auto.fromString works for Class marked as optional" <| fun _ -> - let json = """null""" - - let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) - let expected = Ok None - equal expected actual - - testCase "Auto.generateDecoder throws for Class" <| fun _ -> - let expected = "Cannot generate auto decoder for Tests.Types.BaseClass. Please pass an extra decoder." - let errorMsg = - try - let decoder = Decode.Auto.generateDecoder(caseStrategy=CamelCase) - "" - with ex -> - ex.Message - errorMsg.Replace("+", ".") |> equal expected - - testCase "Auto.fromString works for records missing an optional field" <| fun _ -> - let json = """{ "must": "must value"}""" - let actual = Decode.Auto.fromString(json, caseStrategy=CamelCase) - let expected = - Ok ({ Maybe = None - Must = "must value" } : TestMaybeRecord) - equal expected actual - - testCase "Auto.fromString works with maps encoded as objects" <| fun _ -> - let expected = Map [("oh", { a = 2.; b = 2. }); ("ah", { a = -1.5; b = 0. })] - let json = """{"ah":{"a":-1.5,"b":0},"oh":{"a":2,"b":2}}""" - let actual = Decode.Auto.fromString json - equal (Ok expected) actual - - testCase "Auto.fromString works with maps encoded as arrays" <| fun _ -> - let expected = Map [({ a = 2.; b = 2. }, "oh"); ({ a = -1.5; b = 0. }, "ah")] - let json = """[[{"a":-1.5,"b":0},"ah"],[{"a":2,"b":2},"oh"]]""" - let actual = Decode.Auto.fromString json - equal (Ok expected) actual - - testCase "Decoder.Auto.toString works with bigint extra" <| fun _ -> - let extra = Extra.empty |> Extra.withBigInt - let expected = { bigintField = 9999999999999999999999I } - let actual = Decode.Auto.fromString("""{"bigintField":"9999999999999999999999"}""", extra=extra) - equal (Ok expected) actual - - testCase "Decoder.Auto.toString works with custom extra" <| fun _ -> - let extra = Extra.empty |> Extra.withCustom ChildType.Encode ChildType.Decoder - let expected = { ParentField = { ChildField = "bumbabon" } } - let actual = Decode.Auto.fromString("""{"ParentField":"bumbabon"}""", extra=extra) - equal (Ok expected) actual - - testCase "Auto.fromString works with records with private constructors" <| fun _ -> - let json = """{ "foo1": 5, "foo2": 7.8 }""" - Decode.Auto.fromString(json, caseStrategy=CamelCase) - |> equal (Ok ({ Foo1 = 5; Foo2 = 7.8 }: RecordWithPrivateConstructor)) - - testCase "Auto.fromString works with unions with private constructors" <| fun _ -> - let json = """[ "Baz", ["Bar", "foo"]]""" - Decode.Auto.fromString(json, caseStrategy=CamelCase) - |> equal (Ok [Baz; Bar "foo"]) - - testCase "Auto.generateDecoderCached works" <| fun _ -> - let expected = Ok { Id = 0; Name = "maxime"; Email = "mail@domain.com"; Followers = 0 } - let json = """{ "id" : 0, "name": "maxime", "email": "mail@domain.com", "followers": 0 }""" - let decoder1 = Decode.Auto.generateDecoderCached(caseStrategy=CamelCase) - let decoder2 = Decode.Auto.generateDecoderCached(caseStrategy=CamelCase) - let actual1 = Decode.fromString decoder1 json - let actual2 = Decode.fromString decoder2 json - equal expected actual1 - equal expected actual2 - equal actual1 actual2 - - testCase "Auto.fromString works with strange types if they are None" <| fun _ -> - let json = """{"Id":0}""" - Decode.Auto.fromString(json) - |> equal (Ok { Id = 0; Thread = None }) - - testCase "Auto.fromString works with recursive types" <| fun _ -> - let vater = - { Name = "Alfonso" - Children = [ { Name = "Narumi"; Children = [] } - { Name = "Takumi"; Children = [] } ] } - let json = """{"Name":"Alfonso","Children":[{"Name":"Narumi","Children":[]},{"Name":"Takumi","Children":[]}]}""" - Decode.Auto.fromString(json) - |> equal (Ok vater) - - testCase "Auto.unsafeFromString works for unit" <| fun _ -> - let json = Encode.unit () |> Encode.toString 4 - let res = Decode.Auto.unsafeFromString(json) - equal () res - - testCase "Erased single-case DUs works" <| fun _ -> - let expected = NoAllocAttributeId (Guid.NewGuid()) - let json = Encode.Auto.toString(4, expected) - let actual = Decode.Auto.unsafeFromString(json) - equal expected actual - - testCase "Auto.unsafeFromString works with HTML inside of a string" <| fun _ -> - let expected = - { - FeedName = "Ars" - Content = "
\"How

Enlarge (credit: Getty / Aurich Lawson)

In 2005, Apple contacted Qualcomm as a potential supplier for modem chips in the first iPhone. Qualcomm's response was unusual: a letter demanding that Apple sign a patent licensing agreement before Qualcomm would even consider supplying chips.

\"I'd spent 20 years in the industry, I had never seen a letter like this,\" said Tony Blevins, Apple's vice president of procurement.

Most suppliers are eager to talk to new customers—especially customers as big and prestigious as Apple. But Qualcomm wasn't like other suppliers; it enjoyed a dominant position in the market for cellular chips. That gave Qualcomm a lot of leverage, and the company wasn't afraid to use it.

Read 70 remaining paragraphs | Comments

" - } - - let articleJson = - """ - { - "FeedName": "Ars", - "Content": "
\"How

Enlarge (credit: Getty / Aurich Lawson)

In 2005, Apple contacted Qualcomm as a potential supplier for modem chips in the first iPhone. Qualcomm's response was unusual: a letter demanding that Apple sign a patent licensing agreement before Qualcomm would even consider supplying chips.

\"I'd spent 20 years in the industry, I had never seen a letter like this,\" said Tony Blevins, Apple's vice president of procurement.

Most suppliers are eager to talk to new customers—especially customers as big and prestigious as Apple. But Qualcomm wasn't like other suppliers; it enjoyed a dominant position in the market for cellular chips. That gave Qualcomm a lot of leverage, and the company wasn't afraid to use it.

Read 70 remaining paragraphs | Comments

" - } - """ - - let actual : TestStringWithHTML = Decode.Auto.unsafeFromString(articleJson) - equal expected actual - ] ] diff --git a/tests/Encoders.Auto.fs b/tests/Encoders.Auto.fs new file mode 100644 index 0000000..b09f72e --- /dev/null +++ b/tests/Encoders.Auto.fs @@ -0,0 +1,412 @@ +module Tests.Encoders.Auto + +#if !NETFRAMEWORK +open Fable.Core +#endif + +#if FABLE_COMPILER +open Thoth.Json +open Fable.Mocha +open Fable.Core.JsInterop +#endif + +#if !FABLE_COMPILER +open Thoth.Json +open Expecto +#endif + +open Tests.Types +open System + +type RecordWithPrivateConstructor = private { Foo1: int; Foo2: float } + +type UnionWithPrivateConstructor = private Bar of string | Baz + +let tests = + testList "Thoth.Json.Encode" [ + testList "Encode.Auto" [ + testCase "by default, we keep the case defined in type" <| fun _ -> + let expected = + """{"Email":"mail@test.com","Id":0,"Name":"Maxime","followers":33}""" + + let value : UserCaseSensitive = + { + Email = "mail@test.com" + followers = 33 + Id = 0 + Name = "Maxime" + } + + let actual = Encode.Auto.toString(0, value) + Expect.equal actual expected "" + + testCase "force_snake_case works" <| fun _ -> + let expected = + """{"one":1,"three_part_field":3,"two_part":2}""" + let value = { One = 1; ThreePartField = 3; TwoPart = 2 } + let actual = Encode.Auto.toString(0, value, SnakeCase) + Expect.equal actual expected "" + + testCase "forceCamelCase works" <| fun _ -> + let expected = + """{"email":"mail@test.com","followers":33,"id":0,"name":"Maxime"}""" + let value : UserCaseSensitive = + { + Email = "mail@test.com" + followers = 33 + Id = 0 + Name = "Maxime" + } + + let actual = Encode.Auto.toString(0, value, CamelCase) + Expect.equal actual expected "" + + testCase "Encode.Auto.generateEncoder works" <| fun _ -> + let value = + { + a = 5 + b = "bar" + c = [false, 3; true, 5; false, 10] + d = [|Some(Foo 14); None|] + e = Map [("oh", { a = 2.; b = 2. }); ("ah", { a = -1.5; b = 0. })] + f = DateTime(2018, 11, 28, 11, 10, 29, DateTimeKind.Utc) + g = set [{ a = 2.; b = 2. }; { a = -1.5; b = 0. }] + h = TimeSpan.FromSeconds(5.) + i = 120y + j = 120uy + k = 250s + l = 250us + m = 99u + n = 99L + o = 999UL + p = () + r = 'p' + s = Guid("2e053897-15a9-4647-a005-e954666e24d3") + t = seq [ "item n°1"; "item n°2"] + u = SeveralArgs (10, {| Name = "maxime"; Age = 28 |}) + } + let extra = + Extra.empty + |> Extra.withInt64 + |> Extra.withUInt64 + let encoder = Encode.Auto.generateEncoder(extra = extra) + let actual = encoder value |> Encode.toString 0 + let expected = """{"a":5,"b":"bar","c":[[false,3],[true,5],[false,10]],"d":[14,null],"e":{"ah":{"a":-1.5,"b":0},"oh":{"a":2,"b":2}},"f":"2018-11-28T11:10:29Z","g":[{"a":-1.5,"b":0},{"a":2,"b":2}],"h":"00:00:05","i":"120","j":"120","k":"250","l":"250","m":99,"n":"99","o":"999","r":"p","s":"2e053897-15a9-4647-a005-e954666e24d3","t":["item n°1","item n°2"]}""" + // Don't fail because of non-meaningful decimal digits ("2" vs "2.0") + let actual = System.Text.RegularExpressions.Regex.Replace(actual, @"\.0+(?!\d)", "") + Expect.equal actual expected "" + + testCase "Encode.Auto.generateEncoderCached works" <| fun _ -> + let value = + { + a = 5 + b = "bar" + c = [false, 3; true, 5; false, 10] + d = [|Some(Foo 14); None|] + e = Map [("oh", { a = 2.; b = 2. }); ("ah", { a = -1.5; b = 0. })] + f = DateTime(2018, 11, 28, 11, 10, 29, DateTimeKind.Utc) + g = set [{ a = 2.; b = 2. }; { a = -1.5; b = 0. }] + h = TimeSpan.FromSeconds(5.) + i = 120y + j = 120uy + k = 250s + l = 250us + m = 99u + n = 99L + o = 999UL + p = () + r = 'p' + s = Guid("2e053897-15a9-4647-a005-e954666e24d3") + t = seq [ "item n°1"; "item n°2"] + u = SeveralArgs (10, {| Name = "maxime"; Age = 28 |}) + } + let extra = + Extra.empty + |> Extra.withInt64 + |> Extra.withUInt64 + let encoder1 = Encode.Auto.generateEncoderCached(extra = extra) + let encoder2 = Encode.Auto.generateEncoderCached(extra = extra) + let actual1 = encoder1 value |> Encode.toString 0 + let actual2 = encoder2 value |> Encode.toString 0 + let expected = """{"a":5,"b":"bar","c":[[false,3],[true,5],[false,10]],"d":[14,null],"e":{"ah":{"a":-1.5,"b":0},"oh":{"a":2,"b":2}},"f":"2018-11-28T11:10:29Z","g":[{"a":-1.5,"b":0},{"a":2,"b":2}],"h":"00:00:05","i":"120","j":"120","k":"250","l":"250","m":99,"n":"99","o":"999","r":"p","s":"2e053897-15a9-4647-a005-e954666e24d3","t":["item n°1","item n°2"]}""" + // Don't fail because of non-meaningful decimal digits ("2" vs "2.0") + let actual1 = System.Text.RegularExpressions.Regex.Replace(actual1, @"\.0+(?!\d)", "") + let actual2 = System.Text.RegularExpressions.Regex.Replace(actual2, @"\.0+(?!\d)", "") + Expect.equal expected actual1 "" + Expect.equal expected actual2 "" + Expect.equal actual1 actual2 "" + + testCase "Encode.Auto.toString emit null field if set for" <| fun _ -> + let value = { fieldA = null } + let expected = """{"fieldA":null}""" + let actual = Encode.Auto.toString(0, value, skipNullField = false) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString works with bigint extra" <| fun _ -> + let extra = + Extra.empty + |> Extra.withBigInt + let expected = """{"bigintField":"9999999999999999999999"}""" + let value = { bigintField = 9999999999999999999999I } + let actual = Encode.Auto.toString(0, value, extra=extra) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString works with custom extra" <| fun _ -> + let extra = + Extra.empty + |> Extra.withCustom ChildType.Encode ChildType.Decoder + let expected = """{"ParentField":"bumbabon"}""" + let value = { ParentField = { ChildField = "bumbabon" } } + let actual = Encode.Auto.toString(0, value, extra=extra) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString serializes maps with Guid keys as JSON objects" <| fun _ -> + let m = Map [Guid.NewGuid(), 1; Guid.NewGuid(), 2] + let json = Encode.Auto.toString(0, m) + Expect.equal true (json.[0] = '{') "" + + testCase "Encode.Auto.toString works with records with private constructors" <| fun _ -> + let expected = """{"foo1":5,"foo2":7.8}""" + let x = { Foo1 = 5; Foo2 = 7.8 }: RecordWithPrivateConstructor + let actual = Encode.Auto.toString(0, x, caseStrategy=CamelCase) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString works with unions with private constructors" <| fun _ -> + let expected = """["Baz",["Bar","foo"]]""" + let x = [Baz; Bar "foo"] + let actual = Encode.Auto.toString(0, x, caseStrategy=CamelCase) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString works with strange types if they are None" <| fun _ -> + let expected = + """{"Id":0}""" + + let value = + { Id = 0 + Thread = None } + + let actual = Encode.Auto.toString(0, value) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString works with interfaces if they are None" <| fun _ -> + let expected = + """{"Id":0}""" + + let value = + { Id = 0 + Interface = None } + + let actual = Encode.Auto.toString(0, value) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString works with recursive types" <| fun _ -> + let vater = + { + Children = + [ + { Children = [] ; Name = "Narumi" } + { Children = [] ; Name = "Takumi" } + ] + Name = "Alfonso" + } + + let json = """{"Children":[{"Children":[],"Name":"Narumi"},{"Children":[],"Name":"Takumi"}],"Name":"Alfonso"}""" + let actual = Encode.Auto.toString(0, vater) + Expect.equal actual json "" + + #if !NETFRAMEWORK + testCase "Encode.Auto.toString works with []" <| fun _ -> + let expected = "\"firstPerson\"" + let actual = Encode.Auto.toString(0, Camera.FirstPerson) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString works with []" <| fun _ -> + let expected = "\"react\"" + let actual = Encode.Auto.toString(0, Framework.React) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString works with []" <| fun _ -> + let expected = "\"Fsharp\"" + let actual = Encode.Auto.toString(0, Language.Fsharp) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString works with [] + []" <| fun _ -> + let expected = "\"C#\"" + let actual = Encode.Auto.toString(0, Language.Csharp) + Expect.equal actual expected "" + #endif + + testCase "Encode.Auto.toString works with normal Enums" <| fun _ -> + let expected = "2" + let actual = Encode.Auto.toString(0, Enum_Int.Two) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString works with System.DayOfWeek" <| fun _ -> + let expected = "2" + let actual = Encode.Auto.toString(0, DayOfWeek.Tuesday) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString generate `null` if skipNullField is true and the optional field value of type classes is None" <| fun _ -> + let value = + { + MaybeClass = None + Must = "must value" + } : RecordWithOptionalClass + + let actual = Encode.Auto.toString(0, value, caseStrategy = CamelCase, skipNullField = false) + let expected = + """{"maybeClass":null,"must":"must value"}""" + Expect.equal actual expected "" + + testCase "Encode.Auto.toString doesn't generate the optional field of type classe if it's value is None" <| fun _ -> + let value = + { + MaybeClass = None + Must = "must value" + } : RecordWithOptionalClass + + let actual = Encode.Auto.toString(0, value, caseStrategy = CamelCase) + let expected = + """{"must":"must value"}""" + Expect.equal actual expected "" + + testCase "Encode.Auto.generateEncoder throws for field using a non optional class" <| fun _ -> + let expected = "Cannot generate auto encoder for Tests.Types.BaseClass. Please pass an extra coder." + let errorMsg = + try + let encoder = Encode.Auto.generateEncoder(caseStrategy = CamelCase) + "" + with ex -> + ex.Message + let actual = errorMsg.Replace("+", ".") + + Expect.equal actual expected "" + + (* + #if NETFRAMEWORK + testCase "Encode.Auto.toString works with char based Enums" <| fun _ -> + let expected = ((int) 'A').ToString() // "65" + let actual = Encode.Auto.toString(0, CharEnum.A) + Expect.equal actual expected "" + #endif + *) + + testCase "Encode.Auto.toString allows to customize default known types" <| fun _ -> + let customizedIntEncoder (value : int) = + Encode.object [ + "type", Encode.string "int" + "value", Encode.int value + ] + + let customizedIntDecoder = + Decode.field "type" Decode.string + |> Decode.andThen(function + | "int" -> + Decode.field "value" Decode.int + | invalid -> + sprintf "`%s` is not a valid type value for customizedInt" invalid + |> Decode.fail + ) + + let extra = + Extra.empty + |> Extra.withCustom customizedIntEncoder customizedIntDecoder + + let json = Encode.Auto.toString(0, 99, extra=extra) + + Expect.equal json "{\"type\":\"int\",\"value\":99}" "" + +// It doesn't work on Fable because F# doesn't generate type information for erased types +// testCase "Erased single-case DUs works" <| fun _ -> +// let expected = "\"2e053897-15a9-4647-a005-e954666e24d3\"" +// let actual = Encode.Auto.toString(4, NoAllocAttributeSingleCaseDU (Guid("2e053897-15a9-4647-a005-e954666e24d3"))) +// Expect.equal actual expected "" + + testCase "Single case unions generates simplify JSON" <| fun _ -> + let expected = "\"Maxime\"" + let actual = Encode.Auto.toString(4, SingleCaseDUSimple "Maxime") + Expect.equal actual expected "" + + testCase "Single case unions generates simplify JSON and works with complex types" <| fun _ -> + let expected = + """ +{ + "Age": 28, + "FirstName": "Maxime" +} + """.Trim() + let actual = Encode.Auto.toString(4, SingleCaseDUComplex {| FirstName = "Maxime"; Age = 28 |}) + Expect.equal actual expected "" + + testCase "Union case with several case are encoding as array or string" <| fun _ -> + let circleExpected = + """ +[ + "Circle", + 10 +] + """.Trim() + let circleActual = Encode.Auto.toString(4, Shape.Circle 10) + Expect.equal circleActual circleExpected "" + + let voidExpected = "\"Void\"" + let voidActual = Encode.Auto.toString(4, Shape.Void) + Expect.equal voidActual voidExpected "" + + testCase "Encode.Auto.toString serializes mutable hashsets" <| fun _ -> + let s = System.Collections.Generic.HashSet() + s.Add(1) |> ignore + s.Add(1) |> ignore + s.Add(2) |> ignore + let actual = Encode.Auto.toString(0, s) + Expect.equal actual """[1,2]""" "" + + testCase "Encode.Auto.toString works with seq" <| fun _ -> + let value = seq { yield 1; yield 2 } + let expected = """[1,2]""" + let actual = Encode.Auto.toString(0, value, skipNullField = false) + Expect.equal actual expected "" + + testCase "Encode.Auto.toString serializes mutable dictionaries" <| fun _ -> + let d = System.Collections.Generic.Dictionary() + d.Add("Bar", 2) + d.Add("Foo", 1) + let actual = Encode.Auto.toString(0, d) + Expect.equal actual """{"Bar":2,"Foo":1}""" "" + + testCase "Encode.Auto.toString serializes mutable dictionaries with non simple keys" <| fun _ -> + let d = System.Collections.Generic.Dictionary() + d.Add({| ComplexKey = 1 |}, 1) + d.Add({| ComplexKey = 2 |}, 2) + let actual = Encode.Auto.toString(0, d) + Expect.equal actual """[[{"ComplexKey":1},1],[{"ComplexKey":2},2]]""" "" + + testCase "Encode.Auto.toString works the same for option as for other DUs" <| fun _ -> + // Check Some case of primitive type + let realOptionSome : Option<_> = Some "maxime" + let fakeOptionSome : Fake.FakeOption<_> = Fake.FakeOption.Some "maxime" + + let realOptionSomeJson = Encode.Auto.toString(0, realOptionSome) + let fakeOptionSomeJson = Encode.Auto.toString(0, fakeOptionSome) + + Expect.equal realOptionSomeJson fakeOptionSomeJson "" + + // Check None case + let realOptionNone : Option<_> = None + let fakeOptionNone : Fake.FakeOption<_> = Fake.FakeOption.None + + let realOptionNoneJson = Encode.Auto.toString(0, realOptionNone) + let fakeOptionNoneJson = Encode.Auto.toString(0, fakeOptionNone) + + Expect.equal realOptionNoneJson fakeOptionNoneJson "" + + // Check Some case of complex type + let realOptionSomeComplex : Option<_> = Some {| Firstname = "maxime"; Age = 28 |} + let fakeOptionSomeComplex : Fake.FakeOption<_> = Fake.FakeOption.Some {| Firstname = "maxime"; Age = 28 |} + + let realOptionSomeComplexJson = Encode.Auto.toString(0, realOptionSomeComplex) + let fakeOptionSomeComplexJson = Encode.Auto.toString(0, fakeOptionSomeComplex) + + Expect.equal realOptionSomeComplexJson fakeOptionSomeComplexJson "" + ] + ] diff --git a/tests/Encoders.Manual.fs b/tests/Encoders.Manual.fs new file mode 100644 index 0000000..d41ab2a --- /dev/null +++ b/tests/Encoders.Manual.fs @@ -0,0 +1,426 @@ +module Tests.Encoders.Manual + +#if !NETFRAMEWORK +open Fable.Core +#endif + +#if FABLE_COMPILER +open Thoth.Json +open Fable.Mocha +open Fable.Core.JsInterop +#endif + +#if !FABLE_COMPILER +open Thoth.Json +open Expecto +#endif + +open Tests.Types +open System + +let tests = + testList "Thoth.Json.Encode" [ + + testList "Basic" [ + + testCase "a string works" <| fun _ -> + let expected = "\"maxime\"" + let actual = + Encode.string "maxime" + |> Encode.toString 0 + Expect.equal actual expected "" + + testCase "a char works" <| fun _ -> + let expected = "\"m\"" + let actual = + Encode.char 'm' + |> Encode.toString 0 + Expect.equal actual expected "" + + testCase "an int works" <| fun _ -> + let expected = "1" + let actual = + Encode.int 1 + |> Encode.toString 0 + Expect.equal actual expected "" + + testCase "a float works" <| fun _ -> + let expected = "1.2" + let actual = + Encode.float 1.2 + |> Encode.toString 0 + Expect.equal actual expected "" + + testCase "an array works" <| fun _ -> + let expected = + """["maxime",2]""" + let actual = + Encode.array + [| Encode.string "maxime" + Encode.int 2 + |] |> Encode.toString 0 + Expect.equal actual expected "" + + testCase "a list works" <| fun _ -> + let expected = + """["maxime",2]""" + let actual = + Encode.list + [ Encode.string "maxime" + Encode.int 2 + ] |> Encode.toString 0 + Expect.equal actual expected "" + + testCase "a bool works" <| fun _ -> + let expected = "false" + let actual = + Encode.bool false + |> Encode.toString 0 + Expect.equal actual expected "" + + testCase "a null works" <| fun _ -> + let expected = "null" + let actual = + Encode.nil + |> Encode.toString 0 + Expect.equal actual expected "" + + testCase "unit works" <| fun _ -> + let expected = "null" + let actual = + Encode.unit () + |> Encode.toString 0 + Expect.equal actual expected "" + + testCase "an object works" <| fun _ -> + let expected = + """{"age":25,"firstname":"maxime"}""" + let actual = + Encode.object + [ ("firstname", Encode.string "maxime") + ("age", Encode.int 25) + ] |> Encode.toString 0 + Expect.equal actual expected "" + + testCase "a dict works" <| fun _ -> + let expected = + """{"a":1,"b":2,"c":3}""" + let actual = + Map.ofList + [ ("a", Encode.int 1) + ("b", Encode.int 2) + ("c", Encode.int 3) + ] + |> Encode.dict + |> Encode.toString 0 + Expect.equal actual expected "" + + testCase "a bigint works" <| fun _ -> + let expected = "\"12\"" + let actual = + Encode.bigint 12I + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "a datetime works" <| fun _ -> + #if FABLE_COMPILER + let expected = "\"2018-10-01T11:12:55.000Z\"" + #else + let expected = "\"2018-10-01T11:12:55.0000000Z\"" + #endif + let actual = + DateTime(2018, 10, 1, 11, 12, 55, DateTimeKind.Utc) + |> Encode.datetime + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "a datetimeOffset works" <| fun _ -> + #if FABLE_COMPILER + let expected = "\"2018-07-02T12:23:45.000+02:00\"" + #else + let expected = "\"2018-07-02T12:23:45.0000000+02:00\"" + #endif + let actual = + DateTimeOffset(2018, 7, 2, 12, 23, 45, 0, TimeSpan.FromHours(2.)) + |> Encode.datetimeOffset + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "a timeSpan works" <| fun _ -> + let expected = "\"1.02:03:04.0050000\"" + let actual = + TimeSpan(1, 2, 3, 4, 5) + |> Encode.timespan + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "a decimal works" <| fun _ -> + let expected = "\"0.7833\"" + let actual = + 0.7833M + |> Encode.decimal + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "a guid works" <| fun _ -> + let expected = "\"1e5dee25-8558-4392-a9fb-aae03f81068f\"" + let actual = + Guid.Parse("1e5dee25-8558-4392-a9fb-aae03f81068f") + |> Encode.guid + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "an byte works" <| fun _ -> + let expected = "\"99\"" + let actual = + 99uy + |> Encode.byte + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "an sbyte works" <| fun _ -> + let expected = "\"99\"" + let actual = + 99y + |> Encode.sbyte + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "an int16 works" <| fun _ -> + let expected = "\"99\"" + let actual = + 99s + |> Encode.int16 + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "an uint16 works" <| fun _ -> + let expected = "\"99\"" + let actual = + 99us + |> Encode.uint16 + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "an int64 works" <| fun _ -> + let expected = "\"7923209\"" + let actual = + 7923209L + |> Encode.int64 + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "an uint64 works" <| fun _ -> + let expected = "\"7923209\"" + let actual = + 7923209UL + |> Encode.uint64 + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "an enum works" <| fun _ -> + let expected = "\"99\"" + let actual = + Encode.toString 0 (Encode.Enum.sbyte Enum_Int8.NinetyNine) + + Expect.equal actual expected "" + + testCase "an enum works" <| fun _ -> + let expected = "\"99\"" + let actual = + Encode.toString 0 (Encode.Enum.byte Enum_UInt8.NinetyNine) + + Expect.equal actual expected "" + + testCase "an enum works" <| fun _ -> + let expected = "1" + let actual = + Encode.toString 0 (Encode.Enum.int Enum_Int.One) + + Expect.equal actual expected "" + + testCase "an enum works" <| fun _ -> + let expected = "99" + let actual = + Encode.toString 0 (Encode.Enum.uint32 Enum_UInt32.NinetyNine) + + Expect.equal actual expected "" + + testCase "an enum works" <| fun _ -> + let expected = "\"99\"" + let actual = + Encode.toString 0 (Encode.Enum.int16 Enum_Int16.NinetyNine) + + Expect.equal actual expected "" + + testCase "an enum works" <| fun _ -> + let expected = "\"99\"" + let actual = + Encode.toString 0 (Encode.Enum.uint16 Enum_UInt16.NinetyNine) + + Expect.equal actual expected "" + + testCase "a tuple2 works" <| fun _ -> + let expected = """[1,"maxime"]""" + let actual = + Encode.tuple2 + Encode.int + Encode.string + (1, "maxime") + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "a tuple3 works" <| fun _ -> + let expected = """[1,"maxime",2.5]""" + let actual = + Encode.tuple3 + Encode.int + Encode.string + Encode.float + (1, "maxime", 2.5) + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "a tuple4 works" <| fun _ -> + let expected = """[1,"maxime",2.5,{"fieldA":"test"}]""" + let actual = + Encode.tuple4 + Encode.int + Encode.string + Encode.float + SmallRecord.Encoder + (1, "maxime", 2.5, { fieldA = "test" }) + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "a tuple5 works" <| fun _ -> + #if FABLE_COMPILER + let expected = """[1,"maxime",2.5,{"fieldA":"test"},"2018-10-01T11:12:55.000Z"]""" + #else + let expected = """[1,"maxime",2.5,{"fieldA":"test"},"2018-10-01T11:12:55.0000000Z"]""" + #endif + let actual = + Encode.tuple5 + Encode.int + Encode.string + Encode.float + SmallRecord.Encoder + Encode.datetime + (1, "maxime", 2.5, { fieldA = "test" }, DateTime(2018, 10, 1, 11, 12, 55, DateTimeKind.Utc)) + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "a tuple6 works" <| fun _ -> + let expected = """[1,"maxime",2.5,{"fieldA":"test"},false,null]""" + let actual = + Encode.tuple6 + Encode.int + Encode.string + Encode.float + SmallRecord.Encoder + Encode.bool + (fun _ -> Encode.nil) + (1, "maxime", 2.5, { fieldA = "test" }, false, null) + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "a tuple7 works" <| fun _ -> + let expected = """[1,"maxime",2.5,{"fieldA":"test"},false,null,true]""" + let actual = + Encode.tuple7 + Encode.int + Encode.string + Encode.float + SmallRecord.Encoder + Encode.bool + (fun _ -> Encode.nil) + Encode.bool + (1, "maxime", 2.5, { fieldA = "test" }, false, null, true) + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "a tuple8 works" <| fun _ -> + let expected = """[1,"maxime",2.5,{"fieldA":"test"},false,null,true,98]""" + let actual = + Encode.tuple8 + Encode.int + Encode.string + Encode.float + SmallRecord.Encoder + Encode.bool + (fun _ -> Encode.nil) + Encode.bool + Encode.int + (1, "maxime", 2.5, { fieldA = "test" }, false, null, true, 98) + |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "using pretty space works" <| fun _ -> + let expected = "{\n \"age\": 25,\n \"firstname\": \"maxime\"\n}" + + let actual = + Encode.object + [ ("firstname", Encode.string "maxime") + ("age", Encode.int 25) + ] |> Encode.toString 4 + Expect.equal actual expected "" + + testCase "complex structure works" <| fun _ -> + let expected = + "{\n \"address\": {\n \"city\": \"Bordeaux\",\n \"street\": \"main road\"\n },\n \"age\": 25,\n \"firstname\": \"maxime\"\n}" + + let actual = + Encode.object + [ ("firstname", Encode.string "maxime") + ("age", Encode.int 25) + ("address", Encode.object + [ "street", Encode.string "main road" + "city", Encode.string "Bordeaux" + ]) + ] |> Encode.toString 4 + Expect.equal actual expected "" + + testCase "option with a value `Some ...` works" <| fun _ -> + let expected = """{"id":1,"operator":{"$Case$":"Some","$Value$":"maxime"}}""" + + let actual = + Encode.object + [ ("id", Encode.int 1) + ("operator", Encode.option Encode.string (Some "maxime")) + ] |> Encode.toString 0 + + Expect.equal actual expected "" + + testCase "option without a value `None` works" <| fun _ -> + let expected = """{"id":1,"operator":{"$Case$":"None"}}""" + + let actual = + Encode.object + [ ("id", Encode.int 1) + ("operator", Encode.option Encode.string None) + ] |> Encode.toString 0 + + Expect.equal actual expected "" + + ] + + ] diff --git a/tests/Encoders.fs b/tests/Encoders.fs deleted file mode 100644 index 48ece67..0000000 --- a/tests/Encoders.fs +++ /dev/null @@ -1,655 +0,0 @@ -module Tests.Encoders - -open Thoth.Json -open Util.Testing -open System -open Tests.Types - -type RecordWithPrivateConstructor = private { Foo1: int; Foo2: float } -type UnionWithPrivateConstructor = private Bar of string | Baz - -let tests : Test = - testList "Thoth.Json.Encode" [ - - testList "Basic" [ - - testCase "a string works" <| fun _ -> - let expected = "\"maxime\"" - let actual = - Encode.string "maxime" - |> Encode.toString 0 - equal expected actual - - testCase "an int works" <| fun _ -> - let expected = "1" - let actual = - Encode.int 1 - |> Encode.toString 0 - equal expected actual - - testCase "a float works" <| fun _ -> - let expected = "1.2" - let actual = - Encode.float 1.2 - |> Encode.toString 0 - equal expected actual - - testCase "an array works" <| fun _ -> - let expected = - """["maxime",2]""" - let actual = - Encode.array - [| Encode.string "maxime" - Encode.int 2 - |] |> Encode.toString 0 - equal expected actual - - testCase "a list works" <| fun _ -> - let expected = - """["maxime",2]""" - let actual = - Encode.list - [ Encode.string "maxime" - Encode.int 2 - ] |> Encode.toString 0 - equal expected actual - - testCase "a bool works" <| fun _ -> - let expected = "false" - let actual = - Encode.bool false - |> Encode.toString 0 - equal expected actual - - testCase "a null works" <| fun _ -> - let expected = "null" - let actual = - Encode.nil - |> Encode.toString 0 - equal expected actual - - testCase "unit works" <| fun _ -> - let expected = "null" - let actual = - Encode.unit () - |> Encode.toString 0 - equal expected actual - - testCase "an object works" <| fun _ -> - let expected = - """{"firstname":"maxime","age":25}""" - let actual = - Encode.object - [ ("firstname", Encode.string "maxime") - ("age", Encode.int 25) - ] |> Encode.toString 0 - equal expected actual - - testCase "a dict works" <| fun _ -> - let expected = - """{"a":1,"b":2,"c":3}""" - let actual = - Map.ofList - [ ("a", Encode.int 1) - ("b", Encode.int 2) - ("c", Encode.int 3) - ] - |> Encode.dict - |> Encode.toString 0 - equal expected actual - - testCase "a bigint works" <| fun _ -> - let expected = "\"12\"" - let actual = - Encode.bigint 12I - |> Encode.toString 0 - - equal expected actual - - testCase "a datetime works" <| fun _ -> - #if FABLE_COMPILER - let expected = "\"2018-10-01T11:12:55.000Z\"" - #else - let expected = "\"2018-10-01T11:12:55.0000000Z\"" - #endif - let actual = - DateTime(2018, 10, 1, 11, 12, 55, DateTimeKind.Utc) - |> Encode.datetime - |> Encode.toString 0 - - equal expected actual - - testCase "a datetimeOffset works" <| fun _ -> - #if FABLE_COMPILER - let expected = "\"2018-07-02T12:23:45.000+02:00\"" - #else - let expected = "\"2018-07-02T12:23:45.0000000+02:00\"" - #endif - let actual = - DateTimeOffset(2018, 7, 2, 12, 23, 45, 0, TimeSpan.FromHours(2.)) - |> Encode.datetimeOffset - |> Encode.toString 0 - - equal expected actual - - testCase "a timeSpan works" <| fun _ -> - let expected = "\"1.02:03:04.0050000\"" - let actual = - TimeSpan(1, 2, 3, 4, 5) - |> Encode.timespan - |> Encode.toString 0 - - equal expected actual - - testCase "a decimal works" <| fun _ -> - let expected = "\"0.7833\"" - let actual = - 0.7833M - |> Encode.decimal - |> Encode.toString 0 - - equal expected actual - - testCase "a guid works" <| fun _ -> - let expected = "\"1e5dee25-8558-4392-a9fb-aae03f81068f\"" - let actual = - Guid.Parse("1e5dee25-8558-4392-a9fb-aae03f81068f") - |> Encode.guid - |> Encode.toString 0 - - equal expected actual - - testCase "an byte works" <| fun _ -> - let expected = "\"99\"" - let actual = - 99uy - |> Encode.byte - |> Encode.toString 0 - - equal expected actual - - testCase "an sbyte works" <| fun _ -> - let expected = "\"99\"" - let actual = - 99y - |> Encode.sbyte - |> Encode.toString 0 - - equal expected actual - - testCase "an int16 works" <| fun _ -> - let expected = "\"99\"" - let actual = - 99s - |> Encode.int16 - |> Encode.toString 0 - - equal expected actual - - testCase "an uint16 works" <| fun _ -> - let expected = "\"99\"" - let actual = - 99us - |> Encode.uint16 - |> Encode.toString 0 - - equal expected actual - - testCase "an int64 works" <| fun _ -> - let expected = "\"7923209\"" - let actual = - 7923209L - |> Encode.int64 - |> Encode.toString 0 - - equal expected actual - - testCase "an uint64 works" <| fun _ -> - let expected = "\"7923209\"" - let actual = - 7923209UL - |> Encode.uint64 - |> Encode.toString 0 - - equal expected actual - - testCase "an enum works" <| fun _ -> - let expected = "\"99\"" - let actual = - Encode.toString 0 (Encode.Enum.sbyte Enum_Int8.NinetyNine) - - equal expected actual - - testCase "an enum works" <| fun _ -> - let expected = "\"99\"" - let actual = - Encode.toString 0 (Encode.Enum.byte Enum_UInt8.NinetyNine) - - equal expected actual - - testCase "an enum works" <| fun _ -> - let expected = "1" - let actual = - Encode.toString 0 (Encode.Enum.int Enum_Int.One) - - equal expected actual - - testCase "an enum works" <| fun _ -> - let expected = "99" - let actual = - Encode.toString 0 (Encode.Enum.uint32 Enum_UInt32.NinetyNine) - - equal expected actual - - testCase "an enum works" <| fun _ -> - let expected = "\"99\"" - let actual = - Encode.toString 0 (Encode.Enum.int16 Enum_Int16.NinetyNine) - - equal expected actual - - testCase "an enum works" <| fun _ -> - let expected = "\"99\"" - let actual = - Encode.toString 0 (Encode.Enum.uint16 Enum_UInt16.NinetyNine) - - equal expected actual - - testCase "a tuple2 works" <| fun _ -> - let expected = """[1,"maxime"]""" - let actual = - Encode.tuple2 - Encode.int - Encode.string - (1, "maxime") - |> Encode.toString 0 - - equal expected actual - - testCase "a tuple3 works" <| fun _ -> - let expected = """[1,"maxime",2.5]""" - let actual = - Encode.tuple3 - Encode.int - Encode.string - Encode.float - (1, "maxime", 2.5) - |> Encode.toString 0 - - equal expected actual - - testCase "a tuple4 works" <| fun _ -> - let expected = """[1,"maxime",2.5,{"fieldA":"test"}]""" - let actual = - Encode.tuple4 - Encode.int - Encode.string - Encode.float - SmallRecord.Encoder - (1, "maxime", 2.5, { fieldA = "test" }) - |> Encode.toString 0 - - equal expected actual - - testCase "a tuple5 works" <| fun _ -> - #if FABLE_COMPILER - let expected = """[1,"maxime",2.5,{"fieldA":"test"},"2018-10-01T11:12:55.000Z"]""" - #else - let expected = """[1,"maxime",2.5,{"fieldA":"test"},"2018-10-01T11:12:55.0000000Z"]""" - #endif - let actual = - Encode.tuple5 - Encode.int - Encode.string - Encode.float - SmallRecord.Encoder - Encode.datetime - (1, "maxime", 2.5, { fieldA = "test" }, DateTime(2018, 10, 1, 11, 12, 55, DateTimeKind.Utc)) - |> Encode.toString 0 - - equal expected actual - - testCase "a tuple6 works" <| fun _ -> - let expected = """[1,"maxime",2.5,{"fieldA":"test"},false,null]""" - let actual = - Encode.tuple6 - Encode.int - Encode.string - Encode.float - SmallRecord.Encoder - Encode.bool - (fun _ -> Encode.nil) - (1, "maxime", 2.5, { fieldA = "test" }, false, null) - |> Encode.toString 0 - - equal expected actual - - testCase "a tuple7 works" <| fun _ -> - let expected = """[1,"maxime",2.5,{"fieldA":"test"},false,null,true]""" - let actual = - Encode.tuple7 - Encode.int - Encode.string - Encode.float - SmallRecord.Encoder - Encode.bool - (fun _ -> Encode.nil) - Encode.bool - (1, "maxime", 2.5, { fieldA = "test" }, false, null, true) - |> Encode.toString 0 - - equal expected actual - - testCase "a tuple8 works" <| fun _ -> - let expected = """[1,"maxime",2.5,{"fieldA":"test"},false,null,true,98]""" - let actual = - Encode.tuple8 - Encode.int - Encode.string - Encode.float - SmallRecord.Encoder - Encode.bool - (fun _ -> Encode.nil) - Encode.bool - Encode.int - (1, "maxime", 2.5, { fieldA = "test" }, false, null, true, 98) - |> Encode.toString 0 - - equal expected actual - - testCase "using pretty space works" <| fun _ -> - let expected = "{\n \"firstname\": \"maxime\",\n \"age\": 25\n}" - - let actual = - Encode.object - [ ("firstname", Encode.string "maxime") - ("age", Encode.int 25) - ] |> Encode.toString 4 - equal expected actual - - testCase "complex structure works" <| fun _ -> - let expected = - "{\n \"firstname\": \"maxime\",\n \"age\": 25,\n \"address\": {\n \"street\": \"main road\",\n \"city\": \"Bordeaux\"\n }\n}" - - let actual = - Encode.object - [ ("firstname", Encode.string "maxime") - ("age", Encode.int 25) - ("address", Encode.object - [ "street", Encode.string "main road" - "city", Encode.string "Bordeaux" - ]) - ] |> Encode.toString 4 - equal expected actual - - testCase "option with a value `Some ...` works" <| fun _ -> - let expected = """{"id":1,"operator":"maxime"}""" - - let actual = - Encode.object - [ ("id", Encode.int 1) - ("operator", Encode.option Encode.string (Some "maxime")) - ] |> Encode.toString 0 - - equal expected actual - - testCase "option without a value `None` works" <| fun _ -> - let expected = """{"id":1,"operator":null}""" - - let actual = - Encode.object - [ ("id", Encode.int 1) - ("operator", Encode.option Encode.string None) - ] |> Encode.toString 0 - - equal expected actual - - testCase "by default, we keep the case defined in type" <| fun _ -> - let expected = - """{"Id":0,"Name":"Maxime","Email":"mail@test.com","followers":33}""" - let value = - { Id = 0 - Name = "Maxime" - Email = "mail@test.com" - followers = 33 } - - let actual = Encode.Auto.toString(0, value) - equal expected actual - - testCase "force_snake_case works" <| fun _ -> - let expected = - """{"one":1,"two_part":2,"three_part_field":3}""" - let value = { One = 1; TwoPart = 2; ThreePartField = 3 } - let actual = Encode.Auto.toString(0, value, SnakeCase) - equal expected actual - - testCase "forceCamelCase works" <| fun _ -> - let expected = - """{"id":0,"name":"Maxime","email":"mail@test.com","followers":33}""" - let value = - { Id = 0 - Name = "Maxime" - Email = "mail@test.com" - followers = 33 } - - let actual = Encode.Auto.toString(0, value, CamelCase) - equal expected actual - - testCase "Encode.Auto.generateEncoder works" <| fun _ -> - let value = - { - a = 5 - b = "bar" - c = [false, 3; true, 5; false, 10] - d = [|Some(Foo 14); None|] - e = Map [("oh", { a = 2.; b = 2. }); ("ah", { a = -1.5; b = 0. })] - f = DateTime(2018, 11, 28, 11, 10, 29, DateTimeKind.Utc) - g = set [{ a = 2.; b = 2. }; { a = -1.5; b = 0. }] - h = TimeSpan.FromSeconds(5.) - i = 120y - j = 120uy - k = 250s - l = 250us - m = 99u - n = 99L - o = 999UL - p = () - // r = seq [ "item n°1"; "item n°2"] - } - let extra = - Extra.empty - |> Extra.withInt64 - |> Extra.withUInt64 - let encoder = Encode.Auto.generateEncoder(extra = extra) - let actual = encoder value |> Encode.toString 0 - let expected = """{"a":5,"b":"bar","c":[[false,3],[true,5],[false,10]],"d":[["Foo",14],null],"e":{"ah":{"a":-1.5,"b":0},"oh":{"a":2,"b":2}},"f":"2018-11-28T11:10:29Z","g":[{"a":-1.5,"b":0},{"a":2,"b":2}],"h":"00:00:05","i":"120","j":"120","k":"250","l":"250","m":99,"n":"99","o":"999"}""" - // Don't fail because of non-meaningful decimal digits ("2" vs "2.0") - let actual = System.Text.RegularExpressions.Regex.Replace(actual, @"\.0+(?!\d)", "") - equal expected actual - - testCase "Encode.Auto.generateEncoderCached works" <| fun _ -> - let value = - { - a = 5 - b = "bar" - c = [false, 3; true, 5; false, 10] - d = [|Some(Foo 14); None|] - e = Map [("oh", { a = 2.; b = 2. }); ("ah", { a = -1.5; b = 0. })] - f = DateTime(2018, 11, 28, 11, 10, 29, DateTimeKind.Utc) - g = set [{ a = 2.; b = 2. }; { a = -1.5; b = 0. }] - h = TimeSpan.FromSeconds(5.) - i = 120y - j = 120uy - k = 250s - l = 250us - m = 99u - n = 99L - o = 999UL - p = () - // r = seq [ "item n°1"; "item n°2"] - } - let extra = - Extra.empty - |> Extra.withInt64 - |> Extra.withUInt64 - let encoder1 = Encode.Auto.generateEncoderCached(extra = extra) - let encoder2 = Encode.Auto.generateEncoderCached(extra = extra) - let actual1 = encoder1 value |> Encode.toString 0 - let actual2 = encoder2 value |> Encode.toString 0 - let expected = """{"a":5,"b":"bar","c":[[false,3],[true,5],[false,10]],"d":[["Foo",14],null],"e":{"ah":{"a":-1.5,"b":0},"oh":{"a":2,"b":2}},"f":"2018-11-28T11:10:29Z","g":[{"a":-1.5,"b":0},{"a":2,"b":2}],"h":"00:00:05","i":"120","j":"120","k":"250","l":"250","m":99,"n":"99","o":"999"}""" - // Don't fail because of non-meaningful decimal digits ("2" vs "2.0") - let actual1 = System.Text.RegularExpressions.Regex.Replace(actual1, @"\.0+(?!\d)", "") - let actual2 = System.Text.RegularExpressions.Regex.Replace(actual2, @"\.0+(?!\d)", "") - equal expected actual1 - equal expected actual2 - equal actual1 actual2 - - testCase "Encode.Auto.toString emit null field if setted for" <| fun _ -> - let value = { fieldA = null } - let expected = """{"fieldA":null}""" - let actual = Encode.Auto.toString(0, value, skipNullField = false) - equal expected actual - - testCase "Encode.Auto.toString works with bigint extra" <| fun _ -> - let extra = - Extra.empty - |> Extra.withBigInt - let expected = """{"bigintField":"9999999999999999999999"}""" - let value = { bigintField = 9999999999999999999999I } - let actual = Encode.Auto.toString(0, value, extra=extra) - equal expected actual - - testCase "Encode.Auto.toString works with custom extra" <| fun _ -> - let extra = - Extra.empty - |> Extra.withCustom ChildType.Encode ChildType.Decoder - let expected = """{"ParentField":"bumbabon"}""" - let value = { ParentField = { ChildField = "bumbabon" } } - let actual = Encode.Auto.toString(0, value, extra=extra) - equal expected actual - - testCase "Encode.Auto.toString serializes maps with Guid keys as JSON objects" <| fun _ -> - let m = Map [Guid.NewGuid(), 1; Guid.NewGuid(), 2] - let json = Encode.Auto.toString(0, m) - json.[0] = '{' |> equal true - - testCase "Encode.Auto.toString works with records with private constructors" <| fun _ -> - let expected = """{"foo1":5,"foo2":7.8}""" - let x = { Foo1 = 5; Foo2 = 7.8 }: RecordWithPrivateConstructor - Encode.Auto.toString(0, x, caseStrategy=CamelCase) - |> equal expected - - testCase "Encode.Auto.toString works with unions with private constructors" <| fun _ -> - let expected = """["Baz",["Bar","foo"]]""" - let x = [Baz; Bar "foo"] - Encode.Auto.toString(0, x, caseStrategy=CamelCase) - |> equal expected - - testCase "Encode.Auto.toString works with strange types if they are None" <| fun _ -> - let expected = - """{"Id":0}""" - - let value = - { Id = 0 - Thread = None } - - Encode.Auto.toString(0, value) - |> equal expected - - testCase "Encode.Auto.toString works with interfaces if they are None" <| fun _ -> - let expected = - """{"Id":0}""" - - let value = - { Id = 0 - Interface = None } - - Encode.Auto.toString(0, value) - |> equal expected - - testCase "Encode.Auto.toString works with recursive types" <| fun _ -> - let vater = - { Name = "Alfonso" - Children = [ { Name = "Narumi"; Children = [] } - { Name = "Takumi"; Children = [] } ] } - let json = """{"Name":"Alfonso","Children":[{"Name":"Narumi","Children":[]},{"Name":"Takumi","Children":[]}]}""" - Encode.Auto.toString(0, vater) - |> equal json - - #if !NETFRAMEWORK - testCase "Encode.Auto.toString works with []" <| fun _ -> - let expected = "\"firstPerson\"" - let actual = Encode.Auto.toString(0, Camera.FirstPerson) - equal expected actual - - testCase "Encode.Auto.toString works with []" <| fun _ -> - let expected = "\"react\"" - let actual = Encode.Auto.toString(0, Framework.React) - equal expected actual - - testCase "Encode.Auto.toString works with []" <| fun _ -> - let expected = "\"Fsharp\"" - let actual = Encode.Auto.toString(0, Language.Fsharp) - equal expected actual - - testCase "Encode.Auto.toString works with [] + []" <| fun _ -> - let expected = "\"C#\"" - let actual = Encode.Auto.toString(0, Language.Csharp) - equal expected actual - #endif - - testCase "Encode.Auto.toString works with normal Enums" <| fun _ -> - let expected = "2" - let actual = Encode.Auto.toString(0, Enum_Int.Two) - equal expected actual - - testCase "Encode.Auto.toString works with System.DayOfWeek" <| fun _ -> - let expected = "2" - let actual = Encode.Auto.toString(0, DayOfWeek.Tuesday) - equal expected actual - - testCase "Encode.Auto.toString generate `null` if skipNullField is true and the optional field value of type classes is None" <| fun _ -> - let value = - { - MaybeClass = None - Must = "must value" - } : RecordWithOptionalClass - - let actual = Encode.Auto.toString(0, value, caseStrategy = CamelCase, skipNullField = false) - let expected = - """{"maybeClass":null,"must":"must value"}""" - equal expected actual - - testCase "Encode.Auto.toString doesn't generate the optional field of type classe if it's value is None" <| fun _ -> - let value = - { - MaybeClass = None - Must = "must value" - } : RecordWithOptionalClass - - let actual = Encode.Auto.toString(0, value, caseStrategy = CamelCase) - let expected = - """{"must":"must value"}""" - equal expected actual - - testCase "Encode.Auto.generateEncoder throws for field using a non optional class" <| fun _ -> - let expected = "Cannot generate auto encoder for Tests.Types.BaseClass. Please pass an extra encoder." - let errorMsg = - try - let encoder = Encode.Auto.generateEncoder(caseStrategy = CamelCase) - "" - with ex -> - ex.Message - errorMsg.Replace("+", ".") |> equal expected - - (* - #if NETFRAMEWORK - testCase "Encode.Auto.toString works with char based Enums" <| fun _ -> - let expected = ((int) 'A').ToString() // "65" - let actual = Encode.Auto.toString(0, CharEnum.A) - equal expected actual - #endif - *) - ] - - ] diff --git a/tests/ExtraCoders.fs b/tests/ExtraCoders.fs deleted file mode 100644 index 888291e..0000000 --- a/tests/ExtraCoders.fs +++ /dev/null @@ -1,208 +0,0 @@ -module Tests.ExtraCoders - -open Thoth.Json -open Util.Testing -#if !NETFRAMEWORK -open Fable.Core -#endif - -type Data = - { Id : int - Text : string } - -let camelCaseCoder = Extra.withCustom - (fun (c:Data) -> - Encode.object - [ "id", Encode.int c.Id - "text", Encode.string c.Text]) - (Decode.object (fun get -> - { Id = get.Required.Field "id" Decode.int - Text = get.Required.Field "text" Decode.string })) - Extra.empty - -let pascalCaseCoder = Extra.withCustom - (fun (c:Data) -> - Encode.object - [ "Id", Encode.int c.Id - "Text", Encode.string c.Text]) - (Decode.object (fun get -> - { Id = get.Required.Field "Id" Decode.int - Text = get.Required.Field "Text" Decode.string })) - Extra.empty -#if FABLE_COMPILER -type CachedCoder = - static member internal encode<'Data>(data:'Data, ?caseStrategy:CaseStrategy, ?extra:ExtraCoders, []?dataResolver: ITypeResolver<'Data>) = - let encode = Encode.Auto.generateEncoderCached<'Data>(?caseStrategy = caseStrategy, ?extra = extra, ?resolver = dataResolver) - encode data |> Encode.toString 0 - - static member internal decode<'Response>(value:string, ?caseStrategy:CaseStrategy, ?extra:ExtraCoders, []?responseResolver: ITypeResolver<'Response>) = - let decoder = Decode.Auto.generateDecoderCached<'Response>(?caseStrategy = caseStrategy, ?extra = extra, ?resolver = responseResolver) - Decode.unsafeFromString decoder value -#else -type CachedCoder = - static member internal encode<'Data>(data:'Data, ?caseStrategy:CaseStrategy, ?extra:ExtraCoders) = - let encode = Encode.Auto.generateEncoderCached<'Data>(?caseStrategy = caseStrategy, ?extra = extra) - encode data |> Encode.toString 0 - - static member internal decode<'Response>(value:string, ?caseStrategy:CaseStrategy, ?extra:ExtraCoders) = - let decoder = Decode.Auto.generateDecoderCached<'Response>(?caseStrategy = caseStrategy, ?extra = extra) - Decode.unsafeFromString decoder value -#endif - -let tests : Test = - testList "Thoth.Json.ExtraCoder" [ - testList "Basic Tests (uncached)" [ - testCase "coder in camelCase works" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - - let actual = - Encode.Auto.toString (0, data, extra = camelCaseCoder) - |> fun json -> - Decode.Auto.unsafeFromString (json,extra = camelCaseCoder) - - equal expected actual - - testCase "auto coder are working in camelCase" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - - let actual = - Encode.Auto.toString (0, data, caseStrategy = CamelCase) - |> fun json -> - Decode.Auto.unsafeFromString (json, caseStrategy = CamelCase) - equal expected actual - - testCase "coder in PasalCase works'" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - - let actual = - Encode.Auto.toString (0, data, extra = pascalCaseCoder) - |> fun json -> - Decode.Auto.unsafeFromString (json, extra = pascalCaseCoder) - equal expected actual - - testCase "auto coder are working in PascalCase" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - - let actual = - Encode.Auto.toString (0, data, caseStrategy = PascalCase) - |> fun json -> - Decode.Auto.unsafeFromString (json, caseStrategy = PascalCase) - - equal expected actual - ] - testList "Cached Coders" [ - testCase "coder in camelCase works" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - CachedCoder.encode ( data, extra = camelCaseCoder) - |> fun json -> - CachedCoder.decode (json, extra = camelCaseCoder) - equal expected actual - - testCase "auto coder are working in camelCase" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - CachedCoder.encode ( data, caseStrategy = CamelCase) - |> fun json -> - CachedCoder.decode (json, caseStrategy = CamelCase) - equal expected actual - - testCase "coder in PascalCase works" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - CachedCoder.encode ( data, extra = pascalCaseCoder) - |> fun json -> - CachedCoder.decode (json, extra = pascalCaseCoder) - equal expected actual - - testCase "auto coder are working in PascalCase" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - CachedCoder.encode ( data, caseStrategy = PascalCase) - |> fun json -> - CachedCoder.decode (json, caseStrategy = PascalCase) - equal expected actual - ] - testList "Cached encoding/ normal decoding" [ - testCase "coder in camelCase works" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - CachedCoder.encode ( data, extra = camelCaseCoder) - |> fun json -> - Decode.Auto.unsafeFromString (json, extra = camelCaseCoder) - equal expected actual - - testCase "auto coder are working in camelCase" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - CachedCoder.encode ( data, caseStrategy = CamelCase) - |> fun json -> - Decode.Auto.unsafeFromString (json, caseStrategy = CamelCase) - equal expected actual - - testCase "coder in PascalCase works" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - CachedCoder.encode ( data, extra = pascalCaseCoder) - |> fun json -> - Decode.Auto.unsafeFromString (json, extra = pascalCaseCoder) - equal expected actual - - testCase "auto coder are working in PascalCase" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - CachedCoder.encode ( data, caseStrategy = PascalCase) - |> fun json -> - Decode.Auto.unsafeFromString (json, caseStrategy = PascalCase) - equal expected actual - ] - testList "Normal encoding/ cached decoding" [ - testCase "coder in camelCase works" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - Encode.Auto.toString (0, data, extra = camelCaseCoder) - |> fun json -> - CachedCoder.decode (json, extra = camelCaseCoder) - equal expected actual - - testCase "auto coder are working in camelCase" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - Encode.Auto.toString (0, data, caseStrategy = CamelCase) - |> fun json -> - CachedCoder.decode (json, caseStrategy = CamelCase) - equal expected actual - - testCase "coder in PascalCase works" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - Encode.Auto.toString (0, data, extra = pascalCaseCoder) - |> fun json -> - CachedCoder.decode (json, extra = pascalCaseCoder) - equal expected actual - - testCase "auto coder are working in PascalCase" <| fun _ -> - let data = {Id = 1; Text ="Text"} - let expected = data - let actual = - Encode.Auto.toString (0, data, caseStrategy = PascalCase) - |> fun json -> - CachedCoder.decode (json, caseStrategy = PascalCase) - equal expected actual - ] - ] diff --git a/tests/Main.fs b/tests/Main.fs index 3fa5243..3b594e8 100644 --- a/tests/Main.fs +++ b/tests/Main.fs @@ -1,21 +1,125 @@ module Tests.Main -open Fable.Core +#if FABLE_COMPILER +open Thoth.Json +open Fable.Mocha +#endif -let [] describe (name: string) (f: unit->unit) = jsNative -let [] it (msg: string) (f: unit->unit) = jsNative +#if !FABLE_COMPILER +open Thoth.Json +open Expecto +#endif -let run () = - let tests = [ Tests.Decoders.tests - Tests.Encoders.tests - Tests.ExtraCoders.tests - ] :> Util.Testing.Test seq +open Types - for (moduleName, moduleTests) in tests do - describe moduleName <| fun () -> - for (name, tests) in moduleTests do - describe name <| fun _ -> - for (msg, test) in tests do - it msg test +type Temp = { Name : string; Age : int } -run() +type SeveralArgumentDus2 = SeveralArgs2 of int * Temp + +type SingleNoArguments = SingleNoArguments + +type SeveralArgumentDus3 = + | SeveralArgs3 of int * Temp + | CustomTest1 of string + +//let x = CustomTest1 +// +//let y = SeveralArgs3 +// +//let inline testDuEncoder<'DU, 'Args> (ctor : 'Args -> 'DU) (args : 'Args) : 'DU = +// ctor args +// +//let v1 = testDuEncoder SeveralArgs3 (1, { Name = "maxime"; Age = 11 }) +// +//let inline testDuEncoder2<'DU, 'Args> (dctor : 'DU -> 'Args option) (v : 'DU) : 'Args option = +// dctor v +// +//let dctorTest = +// testDuEncoder2 +// (function SeveralArgs3 (args1, args2) -> Some (args1, args2) | _ -> None ) +// (SeveralArgs3 (1, { Name = "maxime"; Age = 11 })) + +let quicktests = + testList "QuickTest" [ + testList "Fake category" [ + testCase "QuickTest: #1" <| fun _ -> + let value = SeveralArgs (10, {| Name = "maxime"; Age = 28 |}) + let json = Encode.Auto.toString(4, value) + printfn "%A" json + + let value = SeveralArgs2 (10, { Name = "maxime"; Age = 28 }) + let json = Encode.Auto.toString(4, value) + printfn "%A" json + + let value = Foo 11 + let json = Encode.Auto.toString(4, value) + printfn "%A" json + + let value = SingleNoArguments + let json = Encode.Auto.toString(4, value) + printfn "%A" json + + let value = SeveralArgs3 (10, { Name = "maxime"; Age = 28 }) + let json = Encode.Auto.toString(4, value) + printfn "%A" json + +// let value = FakeOption.Some 10 +// let json = Encode.Auto.toString(4, value) +// printfn "%A" json +// +// let value = FakeOption.None +// let json = Encode.Auto.toString(4, value) +// printfn "%A" json + +// let value = CustomTest1 "maxi" +// let json = Encode.Auto.toString(4, value) +// printfn "%A" json + + // Check Some case of primitive type + let realOptionSome : Option<_> = Some "maxime" + let fakeOptionSome : Fake.FakeOption<_> = Fake.FakeOption.Some "maxime" + + let realOptionSomeJson = Encode.Auto.toString(0, realOptionSome) + let fakeOptionSomeJson = Encode.Auto.toString(0, fakeOptionSome) + + Expect.equal realOptionSomeJson fakeOptionSomeJson "" + + // Check None case + let realOptionNone : Option<_> = None + let fakeOptionNone : Fake.FakeOption<_> = Fake.FakeOption.None + + let realOptionNoneJson = Encode.Auto.toString(0, realOptionNone, skipNullField = false) + let fakeOptionNoneJson = Encode.Auto.toString(0, fakeOptionNone, skipNullField = false) + + Expect.equal realOptionNoneJson fakeOptionNoneJson "" + + // Check Some case of complex type + let realOptionSomeComplex : Option<_> = Some {| Firstname = "maxime"; Age = 28 |} + let fakeOptionSomeComplex : Fake.FakeOption<_> = Fake.FakeOption.Some {| Firstname = "maxime"; Age = 28 |} + + let realOptionSomeComplexJson = Encode.Auto.toString(0, realOptionSomeComplex) + let fakeOptionSomeComplexJson = Encode.Auto.toString(0, fakeOptionSomeComplex) + + Expect.equal realOptionSomeComplexJson fakeOptionSomeComplexJson "" + () + ] + ] + +[] +let main args = + let allTests = + testList "All" [ +// Decoders.Manual.tests +// Decoders.Auto.tests +// Encoders.Manual.tests +// Encoders.Auto.tests +// // Uncomment this line if you want to use the quicktests useful +// // when prototyping or trying to reproduce an issue + quicktests + ] + + #if FABLE_COMPILER + Mocha.runTests allTests + #else + runTestsWithArgs defaultConfig args allTests + #endif diff --git a/tests/Tests.Thoth.Json.FableRuntime.fsproj b/tests/Tests.Thoth.Json.FableRuntime.fsproj new file mode 100644 index 0000000..ab0893c --- /dev/null +++ b/tests/Tests.Thoth.Json.FableRuntime.fsproj @@ -0,0 +1,20 @@ + + + netstandard2.0 + THOTH_JSON;FABLE_COMPILER + + + + + + + + + + + + + + + + diff --git a/tests/Tests.Thoth.Json.NetRuntime.fsproj b/tests/Tests.Thoth.Json.NetRuntime.fsproj new file mode 100644 index 0000000..77b4908 --- /dev/null +++ b/tests/Tests.Thoth.Json.NetRuntime.fsproj @@ -0,0 +1,21 @@ + + + netcoreapp3.0 + THOTH_JSON + Exe + + + + + + + + + + + + + + + + diff --git a/tests/Thoth.Tests.fsproj b/tests/Thoth.Tests.fsproj deleted file mode 100644 index a475574..0000000 --- a/tests/Thoth.Tests.fsproj +++ /dev/null @@ -1,17 +0,0 @@ - - - netstandard2.0 - - - - - - - - - - - - - - diff --git a/tests/Types.fs b/tests/Types.fs index 09ad7d3..846550d 100644 --- a/tests/Types.fs +++ b/tests/Types.fs @@ -1,6 +1,7 @@ module Tests.Types open Thoth.Json + open System.Threading #if !NETFRAMEWORK open Fable.Core @@ -106,6 +107,16 @@ type Record8 = type MyUnion = Foo of int +type SeveralArgumentDus = SeveralArgs of int * {| Name : string; Age : int |} + +// Use a module to not pollute the namespaces +module Fake = + + [] + type FakeOption<'Value> = + | Some of 'Value + | None + type Record9 = { a: int @@ -124,7 +135,10 @@ type Record9 = n: int64 o: uint64 p: unit - // r: string seq + r: char + s: System.Guid + t: string seq + u: SeveralArgumentDus } type User = @@ -184,10 +198,10 @@ type RecordWithRequiredClass = { Class : BaseClass Must : string } - type Shape = | Circle of radius: int | Rectangle of width: int * height: int + | Void static member DecoderCircle = Decode.field "radius" Decode.int @@ -200,22 +214,32 @@ type Shape = |> Decode.map Rectangle type MyObj = - { Enabled: bool - Shape: Shape } + { + Enabled: bool + Shape: Shape + } type MyObj2 = - { Enabled: bool - Shape: Shape option } + { + Enabled: bool + Shape: Shape option + } exception CustomException type BigIntRecord = - { bigintField: bigint } + { + bigintField: bigint + } type ChildType = - { ChildField: string } + { + ChildField: string + } + static member Encode(x: ChildType) = Encode.string x.ChildField + static member Decoder = Decode.string |> Decode.map (fun x -> { ChildField = x }) @@ -227,16 +251,15 @@ type Price = | Reduced of float option | Zero - type RecordWithStrangeType = { Id : int Thread : Thread option } type UserCaseSensitive = - { Id : int - Name : string - Email : string - followers : int } + { Email : string + followers : int + Id : int + Name : string } type IAmAnInterface = abstract member DoIt : unit -> unit @@ -246,8 +269,10 @@ type RecordWithInterface = Interface : IAmAnInterface option } type MyRecType = - { Name: string - Children: MyRecType List } + { + Children: MyRecType List + Name: string + } #if !NETFRAMEWORK [] @@ -292,14 +317,22 @@ type Enum_UInt32 = | Zero = 0u | NinetyNine = 99u -#if FABLE_COMPILER -type NoAlloc = Fable.Core.EraseAttribute -#else -type NoAlloc = StructAttribute -#endif +//Disable no alloc test because it doesn't work on Fable runtime +// Fable doesn't generate the type information for Erased type so reflection doesn't work and we get `System.Object` +// all the time. + +//#if FABLE_COMPILER +//type NoAlloc = Fable.Core.EraseAttribute +//#else +//type NoAlloc = StructAttribute +//#endif + +//[] +//type NoAllocAttributeSingleCaseDU = NoAllocAttributeSingleCaseDU of System.Guid + +type SingleCaseDUSimple = SingleCaseDUSimple of string -[] -type NoAllocAttributeId = NoAllocAttributeId of System.Guid +type SingleCaseDUComplex = SingleCaseDUComplex of {| FirstName : string; Age : int |} type TestStringWithHTML = { @@ -307,4 +340,4 @@ type TestStringWithHTML = Content : string } -type RecordForCharacterCase = { One : int; TwoPart : int; ThreePartField : int } +type RecordForCharacterCase = { One : int; ThreePartField : int; TwoPart : int } diff --git a/tests/Util.fs b/tests/Util.fs deleted file mode 100644 index 587e2e2..0000000 --- a/tests/Util.fs +++ /dev/null @@ -1,11 +0,0 @@ -module Util.Testing - -open Fable.Core.Testing - -let testList (name : string) (tests: seq<'b>) = name, tests -let testCase (msg : string) (test : obj -> unit) = msg, test - -let equal expected actual: unit = - Assert.AreEqual(actual, expected) - -type Test = string * seq unit)>> diff --git a/tests/paket.references b/tests/paket.references deleted file mode 100644 index b344bc3..0000000 --- a/tests/paket.references +++ /dev/null @@ -1,2 +0,0 @@ -FSharp.Core -Fable.Core diff --git a/tests/splitter.config.js b/tests/splitter.config.js index f235c4f..d50fd69 100644 --- a/tests/splitter.config.js +++ b/tests/splitter.config.js @@ -1,8 +1,11 @@ module.exports = { - entry: resolve("./Thoth.Tests.fsproj"), + entry: resolve("./Tests.Thoth.Json.FableRuntime.fsproj"), outDir: resolve("./bin"), babel: { plugins: ["transform-es2015-modules-commonjs"], + }, + fable: { + define: [ "THOTH_JSON" ] } }; diff --git a/yarn.lock b/yarn.lock index 4d1f2a0..78358c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,770 +2,955 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" - integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== - dependencies: - "@babel/highlight" "^7.0.0" - -"@babel/core@^7.1.6", "@babel/core@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" - integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== - dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.5.5" - "@babel/helpers" "^7.5.5" - "@babel/parser" "^7.5.5" - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" - convert-source-map "^1.1.0" +"@babel/code-frame@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/compat-data@^7.10.4", "@babel/compat-data@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.11.0.tgz#e9f73efe09af1355b723a7f39b11bad637d7c99c" + integrity sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ== + dependencies: + browserslist "^4.12.0" + invariant "^2.2.4" + semver "^5.5.0" + +"@babel/core@^7.11.4", "@babel/core@^7.5.5", "@babel/core@^7.9.6": + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.4.tgz#4301dfdfafa01eeb97f1896c5501a3f0655d4229" + integrity sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.4" + "@babel/helper-module-transforms" "^7.11.0" + "@babel/helpers" "^7.10.4" + "@babel/parser" "^7.11.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.11.0" + "@babel/types" "^7.11.0" + convert-source-map "^1.7.0" debug "^4.1.0" - json5 "^2.1.0" - lodash "^4.17.13" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.19" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf" - integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ== +"@babel/generator@^7.11.0", "@babel/generator@^7.11.4": + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.4.tgz#1ec7eec00defba5d6f83e50e3ee72ae2fee482be" + integrity sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g== dependencies: - "@babel/types" "^7.5.5" + "@babel/types" "^7.11.0" jsesc "^2.5.1" - lodash "^4.17.13" source-map "^0.5.0" - trim-right "^1.0.1" -"@babel/helper-annotate-as-pure@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" - integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== +"@babel/helper-annotate-as-pure@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" + integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.10.4" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" - integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" + integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== dependencies: - "@babel/helper-explode-assignable-expression" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-explode-assignable-expression" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-builder-react-jsx@^7.3.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz#a1ac95a5d2b3e88ae5e54846bf462eeb81b318a4" - integrity sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw== +"@babel/helper-builder-react-jsx-experimental@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.5.tgz#f35e956a19955ff08c1258e44a515a6d6248646b" + integrity sha512-Buewnx6M4ttG+NLkKyt7baQn7ScC/Td+e99G914fRU8fGIUivDDgVIQeDHFa5e4CRSJQt58WpNHhsAZgtzVhsg== dependencies: - "@babel/types" "^7.3.0" - esutils "^2.0.0" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/types" "^7.10.5" -"@babel/helper-call-delegate@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz#87c1f8ca19ad552a736a7a27b1c1fcf8b1ff1f43" - integrity sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ== +"@babel/helper-builder-react-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz#8095cddbff858e6fa9c326daee54a2f2732c1d5d" + integrity sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg== dependencies: - "@babel/helper-hoist-variables" "^7.4.4" - "@babel/traverse" "^7.4.4" - "@babel/types" "^7.4.4" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz#769711acca889be371e9bc2eb68641d55218021f" - integrity sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng== +"@babel/helper-compilation-targets@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz#804ae8e3f04376607cc791b9d47d540276332bd2" + integrity sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-member-expression-to-functions" "^7.5.5" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" - "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/compat-data" "^7.10.4" + browserslist "^4.12.0" + invariant "^2.2.4" + levenary "^1.1.1" + semver "^5.5.0" -"@babel/helper-define-map@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" - integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.5.5" - lodash "^4.17.13" +"@babel/helper-create-class-features-plugin@^7.10.4", "@babel/helper-create-class-features-plugin@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d" + integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.10.5" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + +"@babel/helper-create-regexp-features-plugin@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" + integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-regex" "^7.10.4" + regexpu-core "^4.7.0" + +"@babel/helper-define-map@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" + integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/types" "^7.10.5" + lodash "^4.17.19" + +"@babel/helper-explode-assignable-expression@^7.10.4": + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz#2d8e3470252cc17aba917ede7803d4a7a276a41b" + integrity sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-function-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" + integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== + dependencies: + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-get-function-arity@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" + integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-hoist-variables@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" + integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.10.5": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" + integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-module-imports@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" + integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" + integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/template" "^7.10.4" + "@babel/types" "^7.11.0" + lodash "^4.17.19" + +"@babel/helper-optimise-call-expression@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" + integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" + integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== + +"@babel/helper-regex@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0" + integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg== + dependencies: + lodash "^4.17.19" + +"@babel/helper-remap-async-to-generator@^7.10.4": + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz#4474ea9f7438f18575e30b0cac784045b402a12d" + integrity sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-wrap-function" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-replace-supers@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" + integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-simple-access@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" + integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== + dependencies: + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-skip-transparent-expression-wrappers@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz#eec162f112c2f58d3af0af125e3bb57665146729" + integrity sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" + integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-validator-identifier@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" + integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== + +"@babel/helper-wrap-function@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" + integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helpers@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" + integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== + dependencies: + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/highlight@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" + integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + chalk "^2.0.0" + js-tokens "^4.0.0" -"@babel/helper-explode-assignable-expression@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" - integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== - dependencies: - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" +"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.4": + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.4.tgz#6fa1a118b8b0d80d0267b719213dc947e88cc0ca" + integrity sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA== -"@babel/helper-function-name@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" - integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== +"@babel/plugin-proposal-async-generator-functions@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" + integrity sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg== dependencies: - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" + "@babel/plugin-syntax-async-generators" "^7.8.0" -"@babel/helper-get-function-arity@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" - integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== +"@babel/plugin-proposal-class-properties@^7.10.4", "@babel/plugin-proposal-class-properties@^7.5.5": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807" + integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg== dependencies: - "@babel/types" "^7.0.0" + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/helper-hoist-variables@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a" - integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w== +"@babel/plugin-proposal-dynamic-import@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" + integrity sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ== dependencies: - "@babel/types" "^7.4.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" -"@babel/helper-member-expression-to-functions@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590" - integrity sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA== +"@babel/plugin-proposal-export-namespace-from@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz#570d883b91031637b3e2958eea3c438e62c05f54" + integrity sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg== dependencies: - "@babel/types" "^7.5.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/helper-module-imports@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" - integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== +"@babel/plugin-proposal-json-strings@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" + integrity sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw== dependencies: - "@babel/types" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.0" -"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a" - integrity sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw== +"@babel/plugin-proposal-logical-assignment-operators@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz#9f80e482c03083c87125dee10026b58527ea20c8" + integrity sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q== dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/template" "^7.4.4" - "@babel/types" "^7.5.5" - lodash "^4.17.13" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/helper-optimise-call-expression@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" - integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" + integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-plugin-utils@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" - integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" -"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351" - integrity sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw== +"@babel/plugin-proposal-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz#ce1590ff0a65ad12970a609d78855e9a4c1aef06" + integrity sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA== dependencies: - lodash "^4.17.13" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/helper-remap-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" - integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-wrap-function" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-replace-supers@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2" - integrity sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.5.5" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" - -"@babel/helper-simple-access@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" - integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== +"@babel/plugin-proposal-object-rest-spread@^7.11.0", "@babel/plugin-proposal-object-rest-spread@^7.5.5": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz#bd81f95a1f746760ea43b6c2d3d62b11790ad0af" + integrity sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA== dependencies: - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.10.4" -"@babel/helper-split-export-declaration@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" - integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q== +"@babel/plugin-proposal-optional-catch-binding@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" + integrity sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g== dependencies: - "@babel/types" "^7.4.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/helper-wrap-function@^7.1.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" - integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== +"@babel/plugin-proposal-optional-chaining@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz#de5866d0646f6afdaab8a566382fe3a221755076" + integrity sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/helpers@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" - integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g== +"@babel/plugin-proposal-private-methods@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz#b160d972b8fdba5c7d111a145fc8c421fc2a6909" + integrity sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw== dependencies: - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/highlight@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" - integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== +"@babel/plugin-proposal-unicode-property-regex@^7.10.4", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d" + integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA== dependencies: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^4.0.0" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/parser@^7.4.4", "@babel/parser@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" - integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== - -"@babel/plugin-proposal-async-generator-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" - integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== +"@babel/plugin-syntax-async-generators@^7.8.0": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" - "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-proposal-class-properties@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4" - integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A== +"@babel/plugin-syntax-class-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz#6644e6a0baa55a61f9e3231f6c9eeb6ee46c124c" + integrity sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.5" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-dynamic-import@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz#e532202db4838723691b10a67b8ce509e397c506" - integrity sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw== +"@babel/plugin-syntax-dynamic-import@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-proposal-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" - integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" + "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-proposal-object-rest-spread@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" - integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== +"@babel/plugin-syntax-json-strings@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-proposal-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" - integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== +"@babel/plugin-syntax-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz#39abaae3cbf710c4373d8429484e6ba21340166c" + integrity sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78" - integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA== +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-async-generators@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" - integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-dynamic-import@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612" - integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w== +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" - integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== +"@babel/plugin-syntax-object-rest-spread@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7" - integrity sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw== +"@babel/plugin-syntax-optional-catch-binding@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-object-rest-spread@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" - integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== +"@babel/plugin-syntax-optional-chaining@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" - integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== +"@babel/plugin-syntax-top-level-await@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz#4bbeb8917b54fcf768364e0a81f560e33a3ef57d" + integrity sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-typescript@^7.2.0": - version "7.3.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz#a7cc3f66119a9f7ebe2de5383cce193473d65991" - integrity sha512-dGwbSMA1YhVS8+31CnPR7LB4pcbrzcV99wQzby4uAfrkZPYZlQ7ImwdpzLqi6Z6IL02b8IAL379CaMwo0x5Lag== +"@babel/plugin-syntax-typescript@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.10.4.tgz#2f55e770d3501e83af217d782cb7517d7bb34d25" + integrity sha512-oSAEz1YkBCAKr5Yiq8/BNtvSAPwkp/IyUnwZogd8p+F0RuYQQrLeRUzIQhueQTTBy/F+a40uS7OFKxnkRvmvFQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-arrow-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" - integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== +"@babel/plugin-transform-arrow-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" + integrity sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-async-to-generator@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e" - integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg== +"@babel/plugin-transform-async-to-generator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz#41a5017e49eb6f3cda9392a51eef29405b245a37" + integrity sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ== dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" -"@babel/plugin-transform-block-scoped-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" - integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== +"@babel/plugin-transform-block-scoped-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz#1afa595744f75e43a91af73b0d998ecfe4ebc2e8" + integrity sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-block-scoping@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce" - integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg== +"@babel/plugin-transform-block-scoping@^7.10.4": + version "7.11.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz#5b7efe98852bef8d652c0b28144cd93a9e4b5215" + integrity sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.13" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-classes@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9" - integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg== +"@babel/plugin-transform-classes@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz#405136af2b3e218bc4a1926228bc917ab1a0adc7" + integrity sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.5.5" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" - "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-define-map" "^7.10.4" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" - integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== +"@babel/plugin-transform-computed-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz#9ded83a816e82ded28d52d4b4ecbdd810cdfc0eb" + integrity sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-destructuring@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a" - integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ== +"@babel/plugin-transform-destructuring@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" + integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" - integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg== +"@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee" + integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-duplicate-keys@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853" - integrity sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ== +"@babel/plugin-transform-duplicate-keys@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz#697e50c9fee14380fe843d1f306b295617431e47" + integrity sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-exponentiation-operator@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" - integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== +"@babel/plugin-transform-exponentiation-operator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" + integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-for-of@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556" - integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ== +"@babel/plugin-transform-for-of@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz#c08892e8819d3a5db29031b115af511dbbfebae9" + integrity sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-function-name@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad" - integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA== +"@babel/plugin-transform-function-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz#6a467880e0fc9638514ba369111811ddbe2644b7" + integrity sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" - integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== +"@babel/plugin-transform-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz#9f42ba0841100a135f22712d0e391c462f571f3c" + integrity sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" - integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA== +"@babel/plugin-transform-member-expression-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz#b1ec44fcf195afcb8db2c62cd8e551c881baf8b7" + integrity sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-modules-amd@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91" - integrity sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg== +"@babel/plugin-transform-modules-amd@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1" + integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw== dependencies: - "@babel/helper-module-transforms" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" + "@babel/helper-module-transforms" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.1.0", "@babel/plugin-transform-modules-commonjs@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74" - integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ== +"@babel/plugin-transform-modules-commonjs@^7.10.4", "@babel/plugin-transform-modules-commonjs@^7.9.6": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" + integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w== dependencies: - "@babel/helper-module-transforms" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" - babel-plugin-dynamic-import-node "^2.3.0" + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249" - integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg== +"@babel/plugin-transform-modules-systemjs@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz#6270099c854066681bae9e05f87e1b9cadbe8c85" + integrity sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw== dependencies: - "@babel/helper-hoist-variables" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" + "@babel/helper-hoist-variables" "^7.10.4" + "@babel/helper-module-transforms" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" - integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== +"@babel/plugin-transform-modules-umd@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz#9a8481fe81b824654b3a0b65da3df89f3d21839e" + integrity sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA== dependencies: - "@babel/helper-module-transforms" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-named-capturing-groups-regex@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106" - integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz#78b4d978810b6f3bcf03f9e318f2fc0ed41aecb6" + integrity sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA== dependencies: - regexp-tree "^0.1.6" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" -"@babel/plugin-transform-new-target@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5" - integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA== +"@babel/plugin-transform-new-target@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz#9097d753cb7b024cb7381a3b2e52e9513a9c6888" + integrity sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-object-super@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9" - integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ== +"@babel/plugin-transform-object-super@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz#d7146c4d139433e7a6526f888c667e314a093894" + integrity sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" -"@babel/plugin-transform-parameters@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16" - integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw== +"@babel/plugin-transform-parameters@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz#59d339d58d0b1950435f4043e74e2510005e2c4a" + integrity sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw== dependencies: - "@babel/helper-call-delegate" "^7.4.4" - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-property-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" - integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ== +"@babel/plugin-transform-property-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz#f6fe54b6590352298785b83edd815d214c42e3c0" + integrity sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-display-name@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz#ebfaed87834ce8dc4279609a4f0c324c156e3eb0" - integrity sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A== +"@babel/plugin-transform-react-display-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.4.tgz#b5795f4e3e3140419c3611b7a2a3832b9aef328d" + integrity sha512-Zd4X54Mu9SBfPGnEcaGcOrVAYOtjT2on8QZkLKEq1S/tHexG39d9XXGZv19VfRrDjPJzFmPfTAqOQS1pfFOujw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-jsx-self@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz#461e21ad9478f1031dd5e276108d027f1b5240ba" - integrity sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg== +"@babel/plugin-transform-react-jsx-development@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.4.tgz#6ec90f244394604623880e15ebc3c34c356258ba" + integrity sha512-RM3ZAd1sU1iQ7rI2dhrZRZGv0aqzNQMbkIUCS1txYpi9wHQ2ZHNjo5TwX+UD6pvFW4AbWqLVYvKy5qJSAyRGjQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-builder-react-jsx-experimental" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" -"@babel/plugin-transform-react-jsx-source@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.5.0.tgz#583b10c49cf057e237085bcbd8cc960bd83bd96b" - integrity sha512-58Q+Jsy4IDCZx7kqEZuSDdam/1oW8OdDX8f+Loo6xyxdfg1yF0GE2XNJQSTZCaMol93+FBzpWiPEwtbMloAcPg== +"@babel/plugin-transform-react-jsx-self@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.4.tgz#cd301a5fed8988c182ed0b9d55e9bd6db0bd9369" + integrity sha512-yOvxY2pDiVJi0axdTWHSMi5T0DILN+H+SaeJeACHKjQLezEzhLx9nEF9xgpBLPtkZsks9cnb5P9iBEi21En3gg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" -"@babel/plugin-transform-react-jsx@^7.0.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz#f2cab99026631c767e2745a5368b331cfe8f5290" - integrity sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg== +"@babel/plugin-transform-react-jsx-source@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.5.tgz#34f1779117520a779c054f2cdd9680435b9222b4" + integrity sha512-wTeqHVkN1lfPLubRiZH3o73f4rfon42HpgxUSs86Nc+8QIcm/B9s8NNVXu/gwGcOyd7yDib9ikxoDLxJP0UiDA== dependencies: - "@babel/helper-builder-react-jsx" "^7.3.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" -"@babel/plugin-transform-regenerator@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f" - integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA== +"@babel/plugin-transform-react-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz#673c9f913948764a4421683b2bef2936968fddf2" + integrity sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A== dependencies: - regenerator-transform "^0.14.0" + "@babel/helper-builder-react-jsx" "^7.10.4" + "@babel/helper-builder-react-jsx-experimental" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" -"@babel/plugin-transform-reserved-words@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz#4792af87c998a49367597d07fedf02636d2e1634" - integrity sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw== +"@babel/plugin-transform-react-pure-annotations@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.4.tgz#3eefbb73db94afbc075f097523e445354a1c6501" + integrity sha512-+njZkqcOuS8RaPakrnR9KvxjoG1ASJWpoIv/doyWngId88JoFlPlISenGXjrVacZUIALGUr6eodRs1vmPnF23A== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-shorthand-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" - integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== +"@babel/plugin-transform-regenerator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" + integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + regenerator-transform "^0.14.2" -"@babel/plugin-transform-spread@^7.2.0": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" - integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== +"@babel/plugin-transform-reserved-words@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz#8f2682bcdcef9ed327e1b0861585d7013f8a54dd" + integrity sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-sticky-regex@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" - integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== +"@babel/plugin-transform-shorthand-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" + integrity sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-template-literals@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0" - integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g== +"@babel/plugin-transform-spread@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz#fa84d300f5e4f57752fe41a6d1b3c554f13f17cc" + integrity sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" -"@babel/plugin-transform-typeof-symbol@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" - integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== +"@babel/plugin-transform-sticky-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" + integrity sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-regex" "^7.10.4" -"@babel/plugin-transform-typescript@^7.5.5": - version "7.6.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.3.tgz#dddb50cf3b8b2ef70b22e5326e9a91f05a1db13b" - integrity sha512-aiWINBrPMSC3xTXRNM/dfmyYuPNKY/aexYqBgh0HBI5Y+WO5oRAqW/oROYeYHrF4Zw12r9rK4fMk/ZlAmqx/FQ== +"@babel/plugin-transform-template-literals@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz#78bc5d626a6642db3312d9d0f001f5e7639fde8c" + integrity sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.6.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-typescript" "^7.2.0" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-unicode-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f" - integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA== +"@babel/plugin-transform-typeof-symbol@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz#9509f1a7eec31c4edbffe137c16cc33ff0bc5bfc" + integrity sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/preset-env@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.5.tgz#bc470b53acaa48df4b8db24a570d6da1fef53c9a" - integrity sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A== +"@babel/plugin-transform-typescript@^7.5.5": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.11.0.tgz#2b4879676af37342ebb278216dd090ac67f13abb" + integrity sha512-edJsNzTtvb3MaXQwj8403B7mZoGu9ElDJQZOKjGUnvilquxBA3IQoEIOvkX/1O8xfAsnHS/oQhe2w/IXrr+w0w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-typescript" "^7.10.4" + +"@babel/plugin-transform-unicode-escapes@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz#feae523391c7651ddac115dae0a9d06857892007" + integrity sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-unicode-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz#e56d71f9282fac6db09c82742055576d5e6d80a8" + integrity sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.5.5": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.0.tgz#860ee38f2ce17ad60480c2021ba9689393efb796" + integrity sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg== + dependencies: + "@babel/compat-data" "^7.11.0" + "@babel/helper-compilation-targets" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-proposal-async-generator-functions" "^7.10.4" + "@babel/plugin-proposal-class-properties" "^7.10.4" + "@babel/plugin-proposal-dynamic-import" "^7.10.4" + "@babel/plugin-proposal-export-namespace-from" "^7.10.4" + "@babel/plugin-proposal-json-strings" "^7.10.4" + "@babel/plugin-proposal-logical-assignment-operators" "^7.11.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" + "@babel/plugin-proposal-numeric-separator" "^7.10.4" + "@babel/plugin-proposal-object-rest-spread" "^7.11.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" + "@babel/plugin-proposal-optional-chaining" "^7.11.0" + "@babel/plugin-proposal-private-methods" "^7.10.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-class-properties" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.10.4" + "@babel/plugin-transform-arrow-functions" "^7.10.4" + "@babel/plugin-transform-async-to-generator" "^7.10.4" + "@babel/plugin-transform-block-scoped-functions" "^7.10.4" + "@babel/plugin-transform-block-scoping" "^7.10.4" + "@babel/plugin-transform-classes" "^7.10.4" + "@babel/plugin-transform-computed-properties" "^7.10.4" + "@babel/plugin-transform-destructuring" "^7.10.4" + "@babel/plugin-transform-dotall-regex" "^7.10.4" + "@babel/plugin-transform-duplicate-keys" "^7.10.4" + "@babel/plugin-transform-exponentiation-operator" "^7.10.4" + "@babel/plugin-transform-for-of" "^7.10.4" + "@babel/plugin-transform-function-name" "^7.10.4" + "@babel/plugin-transform-literals" "^7.10.4" + "@babel/plugin-transform-member-expression-literals" "^7.10.4" + "@babel/plugin-transform-modules-amd" "^7.10.4" + "@babel/plugin-transform-modules-commonjs" "^7.10.4" + "@babel/plugin-transform-modules-systemjs" "^7.10.4" + "@babel/plugin-transform-modules-umd" "^7.10.4" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" + "@babel/plugin-transform-new-target" "^7.10.4" + "@babel/plugin-transform-object-super" "^7.10.4" + "@babel/plugin-transform-parameters" "^7.10.4" + "@babel/plugin-transform-property-literals" "^7.10.4" + "@babel/plugin-transform-regenerator" "^7.10.4" + "@babel/plugin-transform-reserved-words" "^7.10.4" + "@babel/plugin-transform-shorthand-properties" "^7.10.4" + "@babel/plugin-transform-spread" "^7.11.0" + "@babel/plugin-transform-sticky-regex" "^7.10.4" + "@babel/plugin-transform-template-literals" "^7.10.4" + "@babel/plugin-transform-typeof-symbol" "^7.10.4" + "@babel/plugin-transform-unicode-escapes" "^7.10.4" + "@babel/plugin-transform-unicode-regex" "^7.10.4" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.11.0" + browserslist "^4.12.0" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/preset-modules@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" + integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== dependencies: - "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.2.0" - "@babel/plugin-proposal-dynamic-import" "^7.5.0" - "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.5.5" - "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-syntax-async-generators" "^7.2.0" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" - "@babel/plugin-syntax-object-rest-spread" "^7.2.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" - "@babel/plugin-transform-arrow-functions" "^7.2.0" - "@babel/plugin-transform-async-to-generator" "^7.5.0" - "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.5.5" - "@babel/plugin-transform-classes" "^7.5.5" - "@babel/plugin-transform-computed-properties" "^7.2.0" - "@babel/plugin-transform-destructuring" "^7.5.0" "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/plugin-transform-duplicate-keys" "^7.5.0" - "@babel/plugin-transform-exponentiation-operator" "^7.2.0" - "@babel/plugin-transform-for-of" "^7.4.4" - "@babel/plugin-transform-function-name" "^7.4.4" - "@babel/plugin-transform-literals" "^7.2.0" - "@babel/plugin-transform-member-expression-literals" "^7.2.0" - "@babel/plugin-transform-modules-amd" "^7.5.0" - "@babel/plugin-transform-modules-commonjs" "^7.5.0" - "@babel/plugin-transform-modules-systemjs" "^7.5.0" - "@babel/plugin-transform-modules-umd" "^7.2.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5" - "@babel/plugin-transform-new-target" "^7.4.4" - "@babel/plugin-transform-object-super" "^7.5.5" - "@babel/plugin-transform-parameters" "^7.4.4" - "@babel/plugin-transform-property-literals" "^7.2.0" - "@babel/plugin-transform-regenerator" "^7.4.5" - "@babel/plugin-transform-reserved-words" "^7.2.0" - "@babel/plugin-transform-shorthand-properties" "^7.2.0" - "@babel/plugin-transform-spread" "^7.2.0" - "@babel/plugin-transform-sticky-regex" "^7.2.0" - "@babel/plugin-transform-template-literals" "^7.4.4" - "@babel/plugin-transform-typeof-symbol" "^7.2.0" - "@babel/plugin-transform-unicode-regex" "^7.4.4" - "@babel/types" "^7.5.5" - browserslist "^4.6.0" - core-js-compat "^3.1.1" - invariant "^2.2.2" - js-levenshtein "^1.1.3" - semver "^5.5.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" "@babel/preset-react@^7.0.0": - version "7.6.3" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.6.3.tgz#d5242c828322520205ae4eda5d4f4f618964e2f6" - integrity sha512-07yQhmkZmRAfwREYIQgW0HEwMY9GBJVuPY4Q12UC72AbfaawuupVWa8zQs2tlL+yun45Nv/1KreII/0PLfEsgA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-self" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.10.4.tgz#92e8a66d816f9911d11d4cc935be67adfc82dbcf" + integrity sha512-BrHp4TgOIy4M19JAfO1LhycVXOPWdDbTRep7eVyatf174Hff+6Uk53sDyajqZPu8W1qXRBiYOfIamek6jA7YVw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-react-display-name" "^7.10.4" + "@babel/plugin-transform-react-jsx" "^7.10.4" + "@babel/plugin-transform-react-jsx-development" "^7.10.4" + "@babel/plugin-transform-react-jsx-self" "^7.10.4" + "@babel/plugin-transform-react-jsx-source" "^7.10.4" + "@babel/plugin-transform-react-pure-annotations" "^7.10.4" "@babel/register@^7.5.5": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.6.2.tgz#25765a922202cb06f8bdac5a3b1e70cd6bf3dd45" - integrity sha512-xgZk2LRZvt6i2SAUWxc7ellk4+OYRgS3Zpsnr13nMS1Qo25w21Uu8o6vTOAqNaxiqrnv30KTYzh9YWY2k21CeQ== + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.10.5.tgz#354f3574895f1307f79efe37a51525e52fd38d89" + integrity sha512-eYHdLv43nyvmPn9bfNfrcC4+iYNwdQ8Pxk1MFJuU/U5LpSYl/PH4dFMazCYZDFVi8ueG3shvO+AQfLrxpYulQw== dependencies: find-cache-dir "^2.0.0" - lodash "^4.17.13" - mkdirp "^0.5.1" + lodash "^4.17.19" + make-dir "^2.1.0" pirates "^4.0.0" - source-map-support "^0.5.9" - -"@babel/template@^7.1.0", "@babel/template@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" - integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.4.4" - "@babel/types" "^7.4.4" - -"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" - integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ== - dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.5.5" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.5.5" - "@babel/types" "^7.5.5" + source-map-support "^0.5.16" + +"@babel/runtime@^7.8.4": + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" + integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" + integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/parser" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24" + integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.0" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/parser" "^7.11.0" + "@babel/types" "^7.11.0" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.13" + lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" - integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw== +"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.4.4": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d" + integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA== dependencies: - esutils "^2.0.2" - lodash "^4.17.13" + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" to-fast-properties "^2.0.0" -"@babel/types@^7.3.0": - version "7.6.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.3.tgz#3f07d96f854f98e2fbd45c64b0cb942d11e8ba09" - integrity sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA== - dependencies: - esutils "^2.0.2" - lodash "^4.17.13" - to-fast-properties "^2.0.0" +"@fortawesome/fontawesome-free@^5.10.2", "@fortawesome/fontawesome-free@^5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.14.0.tgz#a371e91029ebf265015e64f81bfbf7d228c9681f" + integrity sha512-OfdMsF+ZQgdKHP9jUbmDcRrP0eX90XXrsXIdyjLbkmSBzmMXPABB8eobUJtivaupucYaByz6WNe1PI1JuYm3qA== -"@fortawesome/fontawesome-free@^5.10.0": - version "5.10.0" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.10.0.tgz#dbfb34093c87c9516f03ee1db3385adae3ae9461" - integrity sha512-XX16koDMY/tkJmec0VFfKF7RYZOze/203B1iyLnRaAySm3ZPhKaeyIpf73Yh8xhrMk3Fj4TeH3FC01qyFTyg8g== - -"@fortawesome/fontawesome-free@^5.10.2": - version "5.11.2" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.11.2.tgz#8644bc25b19475779a7b7c1fc104bc0a794f4465" - integrity sha512-XiUPoS79r1G7PcpnNtq85TJ7inJWe0v+b5oZJZKb0pGHNIV6+UiNeQWiFGmuQ0aj7GEhnD/v9iqxIsjuRKtEnQ== - -abbrev@1: +"@types/color-name@^1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== accepts@~1.3.4: version "1.3.7" @@ -775,10 +960,10 @@ accepts@~1.3.4: mime-types "~2.1.24" negotiator "0.6.2" -ansi-colors@3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" - integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-regex@^2.0.0: version "2.1.1" @@ -800,13 +985,21 @@ ansi-styles@^2.2.1: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" +ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -824,29 +1017,16 @@ anymatch@~3.1.1: picomatch "^2.0.4" apache-crypt@^1.1.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/apache-crypt/-/apache-crypt-1.2.1.tgz#d6fc72aa6d27d99c95a94fd188d731eefffa663c" - integrity sha1-1vxyqm0n2ZyVqU/RiNcx7v/6Zjw= + version "1.2.4" + resolved "https://registry.yarnpkg.com/apache-crypt/-/apache-crypt-1.2.4.tgz#fc0aacb7877d64d26420cadf923bcd53e79fb34e" + integrity sha512-Icze5ny5W5uv3xgMgl8U+iGmRCC0iIDrb2PVPuRBtL3Zy1Y5TMewXP1Vtc4r5X9eNNBEk7KYPu0Qby9m/PmcHg== dependencies: - unix-crypt-td-js "^1.0.0" + unix-crypt-td-js "^1.1.4" apache-md5@^1.0.6: - version "1.1.2" - resolved "https://registry.yarnpkg.com/apache-md5/-/apache-md5-1.1.2.tgz#ee49736b639b4f108b6e9e626c6da99306b41692" - integrity sha1-7klza2ObTxCLbp5ibG2pkwa0FpI= - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" + resolved "https://registry.yarnpkg.com/apache-md5/-/apache-md5-1.1.5.tgz#5d6365ece2ccc32b612f886b2b292e1c96ff3ffb" + integrity sha512-sbLEIMQrkV7RkIruqTPXxeCMkAAycv4yzTkBzRgOR1BrR5UB7qZtupqxkersTJSf0HZ3sbaNRrNV80TnnM7cUw== argparse@^1.0.7: version "1.0.10" @@ -887,6 +1067,16 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +array.prototype.map@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.2.tgz#9a4159f416458a23e9483078de1106b2ef68f8ec" + integrity sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.4" + assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" @@ -904,7 +1094,7 @@ async@^2.6.1: dependencies: lodash "^4.17.14" -atob@^2.1.1: +atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== @@ -925,10 +1115,10 @@ babel-messages@^6.23.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-dynamic-import-node@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" - integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== dependencies: object.assign "^4.1.0" @@ -1017,7 +1207,7 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -basic-auth@~2.0.0: +basic-auth@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== @@ -1040,9 +1230,16 @@ binary-extensions@^1.0.0: integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== binary-extensions@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" - integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + version "2.1.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" + integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" brace-expansion@^1.1.7: version "1.1.11" @@ -1080,14 +1277,15 @@ browser-stdout@1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserslist@^4.6.0, browserslist@^4.6.2: - version "4.6.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" - integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== +browserslist@^4.12.0, browserslist@^4.8.5: + version "4.14.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.0.tgz#2908951abfe4ec98737b72f34c3bcedc8d43b000" + integrity sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ== dependencies: - caniuse-lite "^1.0.30000984" - electron-to-chromium "^1.3.191" - node-releases "^1.1.25" + caniuse-lite "^1.0.30001111" + electron-to-chromium "^1.3.523" + escalade "^3.0.2" + node-releases "^1.1.60" buffer-from@^1.0.0: version "1.1.1" @@ -1119,15 +1317,15 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -camelcase@^5.0.0: +camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30000984: - version "1.0.30000987" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000987.tgz#bc6b47217afd8226a2b1964635c6bff62cdf5738" - integrity sha512-O3VrjtRMTxoU5Cn5/QSmXeIR1gkVps4j9jqfIm4FLaQ5JzqBlVjMUG1xWnoYFv8N+H3Lp++aa05TekyIbjHL7g== +caniuse-lite@^1.0.30001111: + version "1.0.30001118" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001118.tgz#116a9a670e5264aec895207f5e918129174c6f62" + integrity sha512-RNKPLojZo74a0cP7jFMidQI7nvLER40HgNfgKQEJ2PFm225L0ectUungNQoK3Xk3StQcFbpBPNEvoWD59436Hg== chalk@^1.1.3: version "1.1.3" @@ -1140,7 +1338,7 @@ chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1149,10 +1347,18 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -"chokidar@>=2.0.0 <4.0.0", chokidar@^3.0.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.2.2.tgz#a433973350021e09f2b853a2287781022c0dc935" - integrity sha512-bw3pm7kZ2Wa6+jQWYP/c7bAZy3i4GwiIiMO2EeRjrE48l8vBqC/WvFhSF0xyM8fQiPEGvwMY/5bqDG7sSEOuhg== +chalk@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@3.4.2, "chokidar@>=2.0.0 <4.0.0", chokidar@^3.0.2: + version "3.4.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" + integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A== dependencies: anymatch "~3.1.1" braces "~3.0.2" @@ -1160,14 +1366,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2: is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.2.0" + readdirp "~3.4.0" optionalDependencies: - fsevents "~2.1.1" + fsevents "~2.1.2" chokidar@^2.0.4: - version "2.1.6" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" - integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== dependencies: anymatch "^2.0.0" async-each "^1.0.1" @@ -1183,11 +1389,6 @@ chokidar@^2.0.4: optionalDependencies: fsevents "^1.2.7" -chownr@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" - integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== - class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -1198,14 +1399,14 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" code-lightner@^0.3.0: version "0.3.0" @@ -1216,11 +1417,6 @@ code-lightner@^0.3.0: fast-plist "^0.1.2" vscode-textmate "^4.0.1" -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -1236,11 +1432,23 @@ color-convert@^1.9.0: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + colors@^1.3.1, colors@latest: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" @@ -1276,15 +1484,10 @@ connect@^3.6.6: parseurl "~1.3.3" utils-merge "1.0.1" -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -convert-source-map@^1.1.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== +convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== dependencies: safe-buffer "~5.1.1" @@ -1293,29 +1496,23 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-compat@^3.1.1: - version "3.1.4" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.1.4.tgz#e4d0c40fbd01e65b1d457980fe4112d4358a7408" - integrity sha512-Z5zbO9f1d0YrJdoaQhphVAnKPimX92D6z8lCGphH89MNRxlL1prI9ExJPqVwP0/kgkQCv8c4GJGT8X16yUncOg== +core-js-compat@^3.6.2: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" + integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== dependencies: - browserslist "^4.6.2" - core-js-pure "3.1.4" - semver "^6.1.1" - -core-js-pure@3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.4.tgz#5fa17dc77002a169a3566cc48dc774d2e13e3769" - integrity sha512-uJ4Z7iPNwiu1foygbcZYJsJs1jiXrTTCvxfLDXNhI/I+NHbSIEyr548y4fcsCEyWY0XgfAG/qqaunJ1SThHenA== + browserslist "^4.8.5" + semver "7.0.0" core-js@^2.4.0: - version "2.6.9" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" - integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== + version "2.6.11" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" + integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== core-js@^3.2.1: - version "3.3.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.3.3.tgz#b7048d3c6c1a52b5fe55a729c1d4ccdffe0891bb" - integrity sha512-0xmD4vUJRY8nfLyV9zcpC17FtSie5STXzw+HyYw2t8IIvmDnbq7RJUULECCo+NstpJtwK9kx8S+898iyqgeUow== + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" + integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== core-util-is@~1.0.0: version "1.0.2" @@ -1330,17 +1527,6 @@ cors@latest: object-assign "^4" vary "^1" -cross-spawn@^6.0.0: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -1348,14 +1534,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: dependencies: ms "2.0.0" -debug@3.2.6, debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.0: +debug@4.1.1, debug@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -1372,12 +1551,7 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -define-properties@^1.1.2: +define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -1406,45 +1580,40 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -diff@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== duplexer@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.191: - version "1.3.205" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.205.tgz#084835a5ecca0765a805acb50a0fddc23d8d530e" - integrity sha512-VV+f2FVeFI5D/slUD7A3V1lTMDkQTUGWYH2dZGAijIutN5Aga4Fn/Hv4Gc+60OpXFVLYIq5HpXb2cG6NrGGQaA== +electron-to-chromium@^1.3.523: + version "1.3.549" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.549.tgz#bf500c8eb75a7286a895e34f41aa144384ac613b" + integrity sha512-q09qZdginlqDH3+Y1P6ch5UDTW8nZ1ijwMkxFs15J/DAWOwqolIx8HZH1UP0vReByBigk/dPlU22xS1MaZ+kpQ== email-addresses@^3.0.1: version "3.1.0" @@ -1461,45 +1630,71 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== - dependencies: - once "^1.4.0" - entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== -es-abstract@^1.5.1: - version "1.13.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" - integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== +es-abstract@^1.17.0-next.1, es-abstract@^1.17.4, es-abstract@^1.17.5: + version "1.17.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" + integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== dependencies: - es-to-primitive "^1.2.0" + es-to-primitive "^1.2.1" function-bind "^1.1.1" has "^1.0.3" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-keys "^1.0.12" + has-symbols "^1.0.1" + is-callable "^1.2.0" + is-regex "^1.1.0" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" -es-to-primitive@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== +es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + +es-get-iterator@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8" + integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ== + dependencies: + es-abstract "^1.17.4" + has-symbols "^1.0.1" + is-arguments "^1.0.4" + is-map "^2.0.1" + is-set "^2.0.1" + is-string "^1.0.5" + isarray "^2.0.5" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" is-date-object "^1.0.1" is-symbol "^1.0.2" +escalade@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" + integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -1509,16 +1704,11 @@ esprima@^4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esutils@^2.0.0: +esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= - etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" @@ -1537,19 +1727,6 @@ event-stream@3.3.4: stream-combiner "~0.0.4" through "~2.3.1" -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -1592,26 +1769,26 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -fable-babel-plugins@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/fable-babel-plugins/-/fable-babel-plugins-2.2.0.tgz#2c61be1bd1afb1f03da4e66ccaa1bfecf92063a3" - integrity sha512-4g8CIyXCILk5LLiwNPtvtrPy3YuV5eJV18SYJCZxu3A1BSKNvPGHLSg5YcFJ2zt4qmBvSkBewlQ2bVQYG+TnrQ== +fable-babel-plugins@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/fable-babel-plugins/-/fable-babel-plugins-2.3.0.tgz#cb4f652bbe78bd8e4a34e17c851d940fa6f3fa44" + integrity sha512-alGBNw5HZJzTEznXKfypFEkD5aWsspbCcoVDu9j8Mqdi77dgp4BSjhYSg61mQEg9UluIAZxRM5lhGARYbU97DQ== fable-compiler@^2.4.7: - version "2.4.7" - resolved "https://registry.yarnpkg.com/fable-compiler/-/fable-compiler-2.4.7.tgz#2e2db532cd62d2488c163c9b0d4a029f4347be79" - integrity sha512-zpEYIDuZtcUKYmkTWQAEUTyHs+Z7oGC+FWtepNmkuzpKxlsvRRKuuSAiCGHHe52drhLuXX+EzzfsWCAKSrWHQw== + version "2.11.0" + resolved "https://registry.yarnpkg.com/fable-compiler/-/fable-compiler-2.11.0.tgz#59ea4d82f85258d54983b60a4123798e6670c41a" + integrity sha512-u+GCzGP4gADffVnAKHniF0bUCFlh233ZWqizuzomKtZx9WReMGv90ICv/3GmE/51ypTz5HnzgesNh+PXx3wVIA== -fable-splitter@^2.1.10: - version "2.1.10" - resolved "https://registry.yarnpkg.com/fable-splitter/-/fable-splitter-2.1.10.tgz#b99eb470793bd4c1c996ad53af7e7dfac2a30e94" - integrity sha512-yQeBh+63iv8mRHkMvxB2RHZyxYclIUj6Er/bKZdnEBmoV0eNqtulbbV1OrdIcCLkgeSA8050JUAvp494otWhUw== +fable-splitter@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/fable-splitter/-/fable-splitter-2.2.1.tgz#99477eb259c03684cc8d065d1167c4579ca8697f" + integrity sha512-pr51yTrpX9qVEWW5/ahIlF7Qy0e1j/JxF1La+cQVd10EmtNvenL7E2g/XOl7JvmRNbFx/64MWF9RQP+vJ2aQLA== dependencies: - "@babel/core" "^7.1.6" - "@babel/plugin-transform-modules-commonjs" "^7.1.0" + "@babel/core" "^7.9.6" + "@babel/plugin-transform-modules-commonjs" "^7.9.6" chalk "^2.4.1" chokidar "^2.0.4" - fable-babel-plugins "^2.2.0" + fable-babel-plugins "^2.3.0" fs-extra "^7.0.0" fast-plist@^0.1.2: @@ -1626,6 +1803,11 @@ faye-websocket@0.11.x: dependencies: websocket-driver ">=0.5.1" +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + filename-reserved-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz#e61cf805f0de1c984567d0386dc5df50ee5af7e4" @@ -1687,13 +1869,38 @@ find-cache-dir@^2.0.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-up@3.0.0, find-up@^3.0.0: +find-cache-dir@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== dependencies: locate-path "^3.0.0" +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + flat@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" @@ -1724,9 +1931,9 @@ from@~0: integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= front-matter@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/front-matter/-/front-matter-3.0.2.tgz#2401cd05fcf22bd0de48a104ffb4efb1ff5c8465" - integrity sha512-iBGZaWyzqgsrPGsqrXZP6N4hp5FzSKDi18nfAoYpgz3qK5sAwFv/ojmn3VS60SOgLvq6CtojNqy0y6ZNz05IzQ== + version "3.2.1" + resolved "https://registry.yarnpkg.com/front-matter/-/front-matter-3.2.1.tgz#88be839638f397bbbcb0d61ac03bd08abb4f0a40" + integrity sha512-YUhgEhbL6tG+Ok3vTGIoSDKqcr47aSDvyhEqIv8B+YuBJFsPnOiArNXTPp2yO07NL+a0L4+2jXlKlKqyVcsRRA== dependencies: js-yaml "^3.13.1" @@ -1739,12 +1946,14 @@ fs-extra@^7.0.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-minipass@^1.2.5: - version "1.2.6" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" - integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ== +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== dependencies: - minipass "^2.2.1" + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" fs.realpath@^1.0.0: version "1.0.0" @@ -1752,72 +1961,50 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.7: - version "1.2.9" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" - integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== dependencies: + bindings "^1.5.0" nan "^2.12.1" - node-pre-gyp "^0.12.0" -fsevents@~2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.1.tgz#74c64e21df71721845d0c44fe54b7f56b82995a9" - integrity sha512-4FRPXWETxtigtJW/gxzEDsX1LVbPAM93VleB83kZB+ellqbHMkyt2aJfuzNLRvFPnGi6bcE5SvfxgbXPeKteJw== +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -gh-pages@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-2.1.1.tgz#5be70a92f9cb70404bafabd8bb149c0e9a8c264b" - integrity sha512-yNW2SFp9xGRP/8Sk2WXuLI/Gn92oOL4HBgudn6PsqAnuWT90Y1tozJoTfX1WdrDSW5Rb90kLVOf5mm9KJ/2fDw== +gh-pages@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-3.1.0.tgz#ec3ed0f6a6e3fc3d888758fa018f08191c96bd55" + integrity sha512-3b1rly9kuf3/dXsT8+ZxP0UhNLOo1CItj+3e31yUVcaph/yDsJ9RzD7JOw5o5zpBTJVQLlJAASNkUfepi9fe2w== dependencies: async "^2.6.1" commander "^2.18.0" email-addresses "^3.0.1" filenamify-url "^1.0.0" - fs-extra "^7.0.0" + find-cache-dir "^3.3.1" + fs-extra "^8.1.0" globby "^6.1.0" - graceful-fs "^4.1.11" - rimraf "^2.6.2" glob-parent@^3.1.0: version "3.1.0" @@ -1828,40 +2015,16 @@ glob-parent@^3.1.0: path-dirname "^1.0.0" glob-parent@~5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" - integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw== + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== dependencies: is-glob "^4.0.1" -glob@7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.3: - version "7.1.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0" - integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.3: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== +glob@7.1.6, glob@^7.0.3: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -1891,10 +2054,10 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.2.0" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" - integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== growl@1.10.5: version "1.10.5" @@ -1913,15 +2076,15 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= -has-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== has-value@^0.3.1: version "0.3.1" @@ -1954,7 +2117,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.1, has@^1.0.3: +has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== @@ -1997,10 +2160,10 @@ http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -"http-parser-js@>=0.4.0 <0.4.11": - version "0.4.10" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" - integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= +http-parser-js@>=0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.2.tgz#da2e31d237b393aae72ace43882dd7e270a8ff77" + integrity sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ== humanize-url@^1.0.0: version "1.0.1" @@ -2010,20 +2173,6 @@ humanize-url@^1.0.0: normalize-url "^1.0.0" strip-url-auth "^1.0.0" -iconv-lite@^0.4.4: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== - dependencies: - minimatch "^3.0.4" - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -2042,23 +2191,13 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -invariant@^2.2.2: +invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== dependencies: loose-envify "^1.0.0" -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -2073,6 +2212,11 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -2093,14 +2237,14 @@ is-buffer@^1.1.5: integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-buffer@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" - integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" + integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== -is-callable@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== +is-callable@^1.1.4, is-callable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" + integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== is-data-descriptor@^0.1.4: version "0.1.4" @@ -2117,9 +2261,9 @@ is-data-descriptor@^1.0.0: kind-of "^6.0.0" is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== is-descriptor@^0.1.0: version "0.1.6" @@ -2156,13 +2300,6 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -2182,6 +2319,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-map@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" + integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -2194,7 +2336,7 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-plain-obj@^1.0.0: +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= @@ -2206,24 +2348,29 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= +is-regex@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" + integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== dependencies: - has "^1.0.1" + has-symbols "^1.0.1" -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-set@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43" + integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA== + +is-string@^1.0.4, is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== is-symbol@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== dependencies: - has-symbols "^1.0.0" + has-symbols "^1.0.1" is-windows@^1.0.2: version "1.0.2" @@ -2240,6 +2387,11 @@ isarray@1.0.0, isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2257,10 +2409,18 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -js-levenshtein@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" - integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== +iterate-iterator@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6" + integrity sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw== + +iterate-value@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" + integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== + dependencies: + es-get-iterator "^1.0.2" + iterate-iterator "^1.0.1" "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -2272,10 +2432,10 @@ js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-yaml@3.13.1, js-yaml@^3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== +js-yaml@3.14.0, js-yaml@^3.13.1: + version "3.14.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" + integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -2290,12 +2450,12 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= -json5@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" - integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== dependencies: - minimist "^1.2.0" + minimist "^1.2.5" jsonfile@^4.0.0: version "4.0.0" @@ -2324,16 +2484,21 @@ kind-of@^5.0.0: integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levenary@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" + integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== dependencies: - invert-kv "^2.0.0" + leven "^3.1.0" linkify-it@^2.0.0: version "2.2.0" @@ -2369,17 +2534,31 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" -log-symbols@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: - chalk "^2.0.1" + p-locate "^5.0.0" + +lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.4: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + +log-symbols@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" + integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== + dependencies: + chalk "^4.0.0" loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" @@ -2388,7 +2567,7 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -make-dir@^2.0.0: +make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -2396,12 +2575,12 @@ make-dir@^2.0.0: pify "^4.0.1" semver "^5.6.0" -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: - p-defer "^1.0.0" + semver "^6.0.0" map-cache@^0.2.2: version "0.2.2" @@ -2441,15 +2620,6 @@ mdurl@^1.0.1: resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -2469,28 +2639,23 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -mime-db@1.40.0: - version "1.40.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" - integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== mime-types@~2.1.17, mime-types@~2.1.24: - version "2.1.24" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" - integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== dependencies: - mime-db "1.40.0" + mime-db "1.44.0" mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mimic-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -2498,30 +2663,10 @@ minimatch@3.0.4, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minipass@^2.2.1, minipass@^2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== - dependencies: - minipass "^2.2.1" +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== mixin-deep@^1.2.0: version "1.3.2" @@ -2531,52 +2676,47 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -mocha@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.0.tgz#f896b642843445d1bb8bca60eabd9206b8916e56" - integrity sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ== +mocha@^8.1.2: + version "8.1.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.1.2.tgz#d67fad13300e4f5cd48135a935ea566f96caf827" + integrity sha512-I8FRAcuACNMLQn3lS4qeWLxXqLvGf6r2CaLstDpZmMUUSmvW6Cnm1AuHxgbc7ctZVRcfwspCRbDHymPsi3dkJw== dependencies: - ansi-colors "3.2.3" + ansi-colors "4.1.1" browser-stdout "1.3.1" - debug "3.2.6" - diff "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" + chokidar "3.4.2" + debug "4.1.1" + diff "4.0.2" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.1.6" growl "1.10.5" he "1.2.0" - js-yaml "3.13.1" - log-symbols "2.2.0" + js-yaml "3.14.0" + log-symbols "4.0.0" minimatch "3.0.4" - mkdirp "0.5.1" - ms "2.1.1" - node-environment-flags "1.0.5" + ms "2.1.2" object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" + promise.allsettled "1.0.2" + serialize-javascript "4.0.0" + strip-json-comments "3.0.1" + supports-color "7.1.0" + which "2.0.2" wide-align "1.1.3" - yargs "13.2.2" - yargs-parser "13.0.0" - yargs-unparser "1.5.0" + workerpool "6.0.0" + yargs "13.3.2" + yargs-parser "13.1.2" + yargs-unparser "1.6.1" morgan@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" - integrity sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA== + version "1.10.0" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" + integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== dependencies: - basic-auth "~2.0.0" + basic-auth "~2.0.1" debug "2.6.9" - depd "~1.1.2" + depd "~2.0.0" on-finished "~2.3.0" - on-headers "~1.0.1" + on-headers "~1.0.2" ms@2.0.0: version "2.0.0" @@ -2588,7 +2728,7 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@^2.1.1: +ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -2622,9 +2762,9 @@ nacara@^0.2.1: slugify "^1.3.4" nan@^2.12.1, nan@^2.14.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + version "2.14.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" + integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== nanomatch@^1.2.9: version "1.2.13" @@ -2643,68 +2783,20 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -needle@^2.2.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" - integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -node-environment-flags@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" - integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - node-modules-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-pre-gyp@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" - integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -node-releases@^1.1.25: - version "1.1.26" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.26.tgz#f30563edc5c7dc20cf524cc8652ffa7be0762937" - integrity sha512-fZPsuhhUHMTlfkhDLGtfY80DSJTjOcx+qD1j5pqPkuhUHVS7xHZIg9EE4DHK8O3f0zTxXHX5VIkDG8pu98/wfQ== - dependencies: - semver "^5.3.0" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" +node-releases@^1.1.60: + version "1.1.60" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084" + integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA== normalize-path@^2.1.1: version "2.1.1" @@ -2728,41 +2820,6 @@ normalize-url@^1.0.0: query-string "^4.1.0" sort-keys "^1.0.0" -npm-bundled@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" - integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== - -npm-packlist@^1.1.6: - version "1.4.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.4.tgz#866224233850ac534b63d1a6e76050092b5d2f44" - integrity sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1, object-assign@latest: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2777,7 +2834,12 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-keys@^1.0.11, object-keys@^1.0.12: +object-inspect@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" + integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -2799,14 +2861,6 @@ object.assign@4.1.0, object.assign@^4.1.0: has-symbols "^1.0.0" object-keys "^1.0.11" -object.getownpropertydescriptors@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= - dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.1" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -2821,12 +2875,12 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -on-headers@~1.0.1: +on-headers@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -2834,9 +2888,9 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: wrappy "1" oniguruma@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/oniguruma/-/oniguruma-7.2.0.tgz#c9a59c1ea7b9fe67e237a02e02139b638856f3af" - integrity sha512-bh+ZLdykY1sdIx8jBp2zpLbVFDBc3XmKH4Ceo2lijNaN1WhEqtnpqFlmtCbRuDB17nJ58RAUStVwfW8e8uEbnA== + version "7.2.1" + resolved "https://registry.yarnpkg.com/oniguruma/-/oniguruma-7.2.1.tgz#51775834f7819b6e31aa878706aa7f65ad16b07f" + integrity sha512-WPS/e1uzhswPtJSe+Zls/kAj27+lEqZjCmRSjnYk/Z4L2Mu+lJC2JWtkZhPJe4kZeTQfz7ClcLyXlI4J68MG2w== dependencies: nan "^2.14.0" @@ -2847,52 +2901,17 @@ opn@latest: dependencies: is-wsl "^1.1.0" -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^3.0.0, os-locale@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -os-tmpdir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + p-try "^2.0.0" -p-limit@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" - integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== +p-limit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" + integrity sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg== dependencies: p-try "^2.0.0" @@ -2903,6 +2922,20 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2928,16 +2961,16 @@ path-exists@^3.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -2950,10 +2983,10 @@ pause-stream@0.0.11: dependencies: through "~2.3" -picomatch@^2.0.4: - version "2.0.7" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" - integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== pify@^2.0.0: version "2.3.0" @@ -2991,6 +3024,13 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -3001,16 +3041,22 @@ prepend-http@^1.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -private@^0.1.6: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== - process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +promise.allsettled@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.2.tgz#d66f78fbb600e83e863d893e98b3d4376a9c47c9" + integrity sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg== + dependencies: + array.prototype.map "^1.0.1" + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + iterate-value "^1.0.0" + prop-types@^15.6.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" @@ -3025,14 +3071,6 @@ proxy-middleware@latest: resolved "https://registry.yarnpkg.com/proxy-middleware/-/proxy-middleware-0.15.0.tgz#a3fdf1befb730f951965872ac2f6074c61477a56" integrity sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY= -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - query-string@^4.1.0: version "4.3.4" resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" @@ -3041,49 +3079,46 @@ query-string@^4.1.0: object-assign "^4.1.0" strict-uri-encode "^1.0.0" +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -react-dom@^16.9.0: - version "16.11.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.11.0.tgz#7e7c4a5a85a569d565c2462f5d345da2dd849af5" - integrity sha512-nrRyIUE1e7j8PaXSPtyRKtz+2y9ubW/ghNgqKFHHAHaeP0fpF5uXR+sq8IMRHC+ZUxw7W9NyCDTBtwWxvkb0iA== +react-dom@^16.13.1, react-dom@^16.9.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" + integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.17.0" + scheduler "^0.19.1" react-is@^16.8.1: - version "16.11.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.11.0.tgz#b85dfecd48ad1ce469ff558a882ca8e8313928fa" - integrity sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw== + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react@^16.9.0: - version "16.11.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.11.0.tgz#d294545fe62299ccee83363599bf904e4a07fdbb" - integrity sha512-M5Y8yITaLmU0ynd0r1Yvfq98Rmll6q8AxaEe88c8e7LxO8fZ2cNgmFt0aGAS9wzf1Ao32NKXtCl+/tVVtkxq6g== +react@^16.13.1, react@^16.9.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" + integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" -readable-stream@^2.0.2, readable-stream@^2.0.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== +readable-stream@^2.0.2: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -3102,36 +3137,41 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -readdirp@~3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" - integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== +readdirp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" + integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== dependencies: - picomatch "^2.0.4" + picomatch "^2.2.1" -regenerate-unicode-properties@^8.0.2: - version "8.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" - integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== dependencies: regenerate "^1.4.0" regenerate@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + version "1.4.1" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" + integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== -regenerator-transform@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb" - integrity sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ== +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== dependencies: - private "^0.1.6" + "@babel/runtime" "^7.8.4" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" @@ -3141,32 +3181,27 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp-tree@^0.1.6: - version "0.1.11" - resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.11.tgz#c9c7f00fcf722e0a56c7390983a7a63dd6c272f3" - integrity sha512-7/l/DgapVVDzZobwMCCgMlqiqyLFJ0cduo/j+3BcDJIB+yJdsYCfKuI3l/04NV+H/rfNRdPIDbXNZHM9XvQatg== - -regexpu-core@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" - integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== +regexpu-core@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" + integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== dependencies: regenerate "^1.4.0" - regenerate-unicode-properties "^8.0.2" - regjsgen "^0.5.0" - regjsparser "^0.6.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.1.0" + unicode-match-property-value-ecmascript "^1.2.0" -regjsgen@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" - integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== +regjsgen@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== -regjsparser@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" - integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== dependencies: jsesc "~0.5.0" @@ -3190,11 +3225,6 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" @@ -3206,9 +3236,9 @@ resolve-url@^0.2.1: integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.3.2: - version "1.11.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" - integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== dependencies: path-parse "^1.0.6" @@ -3217,29 +3247,15 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rimraf@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -rimraf@^2.6.2: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@>=5.1.0, safe-buffer@^5.1.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== +safe-buffer@>=5.1.0, safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-regex@^1.1.0: version "1.1.0" @@ -3248,42 +3264,32 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - sass@^1.23.0-module.beta.1: - version "1.23.1" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.23.1.tgz#0e5b72ba2bd9f0229a637d33f8dd5bf2d810beb3" - integrity sha512-zQzJ3UETUWOMd/pJJGH/zvRsBVO97m11RcpfUhcQUHEXf0yHUBgOIE/Nw8aK0m1XyVJPeq228iIK7gVxsJ/Puw== + version "1.26.10" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.26.10.tgz#851d126021cdc93decbf201d1eca2a20ee434760" + integrity sha512-bzN0uvmzfsTvjz0qwccN1sPm2HxxpNI/Xa+7PlUEMS+nQvbyuEK7Y0qFqxlPHhiNHb1Ze8WQJtU31olMObkAMw== dependencies: chokidar ">=2.0.0 <4.0.0" -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -scheduler@^0.17.0: - version "0.17.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.17.0.tgz#7c9c673e4ec781fac853927916d1c426b6f3ddfe" - integrity sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA== +scheduler@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" + integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" -semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.7.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" - integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^5.6.0: +semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^6.1.1: +semver@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -3307,6 +3313,13 @@ send@latest: range-parser "~1.2.1" statuses "~1.5.0" +serialize-javascript@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + serve-index@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" @@ -3320,7 +3333,7 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -3345,27 +3358,10 @@ setprototypeof@1.1.1: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - slugify@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.3.5.tgz#90210678818b6d533cb060083aed0e8238133508" - integrity sha512-5VCnH7aS13b0UqWOs7Ef3E5rkhFe8Od+cp7wybFv5mv/sYSRkucZlJX0bamAJky7b2TTtGvrJBWVdpdEicsSrA== + version "1.4.5" + resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.4.5.tgz#a7517acf5f4c02a4df41e735354b660a4ed1efcf" + integrity sha512-WpECLAgYaxHoEAJ8Q1Lo8HOs1ngn7LN7QjXgOLbmmfkcWvosyk4ZTXkTzKyhngK640USTZUlgoQJfED1kz5fnQ== snapdragon-node@^2.0.1: version "2.1.1" @@ -3405,20 +3401,20 @@ sort-keys@^1.0.0: is-plain-obj "^1.0.0" source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== dependencies: - atob "^2.1.1" + atob "^2.1.2" decode-uri-component "^0.2.0" resolve-url "^0.2.1" source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.5.9: - version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== +source-map-support@^0.5.16: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -3482,16 +3478,7 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2": version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -3499,7 +3486,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^3.0.0: +string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== @@ -3508,6 +3495,22 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" +string.prototype.trimend@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimstart@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -3515,7 +3518,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.0, strip-ansi@^3.0.1: +strip-ansi@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= @@ -3529,22 +3532,17 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.1.0: +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== dependencies: ansi-regex "^4.1.0" -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-json-comments@2.0.1, strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +strip-json-comments@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== strip-outer@^1.0.0: version "1.0.1" @@ -3558,12 +3556,12 @@ strip-url-auth@^1.0.0: resolved "https://registry.yarnpkg.com/strip-url-auth/-/strip-url-auth-1.0.1.tgz#22b0fa3a41385b33be3f331551bbb837fa0cd7ae" integrity sha1-IrD6OkE4WzO+PzMVUbu4N/oM164= -supports-color@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" - integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== +supports-color@7.1.0, supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== dependencies: - has-flag "^3.0.0" + has-flag "^4.0.0" supports-color@^2.0.0: version "2.0.0" @@ -3577,19 +3575,6 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -tar@^4: - version "4.4.10" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" - integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.3.5" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" - through@2, through@~2.3, through@~2.3.1: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -3649,11 +3634,6 @@ trim-repeated@^1.0.0: dependencies: escape-string-regexp "^1.0.2" -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= - uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" @@ -3672,15 +3652,15 @@ unicode-match-property-ecmascript@^1.0.4: unicode-canonical-property-names-ecmascript "^1.0.4" unicode-property-aliases-ecmascript "^1.0.4" -unicode-match-property-value-ecmascript@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" - integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== unicode-property-aliases-ecmascript@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" - integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== union-value@^1.0.0: version "1.0.1" @@ -3697,7 +3677,7 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== -unix-crypt-td-js@^1.0.0: +unix-crypt-td-js@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz#4912dfad1c8aeb7d20fa0a39e4c31918c1d5d5dd" integrity sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw== @@ -3716,9 +3696,9 @@ unset-value@^1.0.0: isobject "^3.0.0" upath@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" - integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== urix@^0.1.0: version "0.1.0" @@ -3741,9 +3721,9 @@ utils-merge@1.0.1: integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= uuid@^3.0.0: - version "3.3.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" - integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== vary@^1: version "1.1.2" @@ -3751,132 +3731,125 @@ vary@^1: integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= vscode-textmate@^4.0.1: - version "4.2.2" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.2.2.tgz#0b4dabc69a6fba79a065cb6b615f66eac07c8f4c" - integrity sha512-1U4ih0E/KP1zNK/EbpUqyYtI7PY+Ccd2nDGTtiMR/UalLFnmaYkwoWhN1oI7B91ptBN8NdVwWuvyUnvJAulCUw== + version "4.4.0" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.4.0.tgz#14032afeb50152e8f53258c95643e555f2948305" + integrity sha512-dFpm2eK0HwEjeFSD1DDh3j0q47bDSVuZt20RiJWxGqjtm73Wu2jip3C2KaZI3dQx/fSeeXCr/uEN4LNaNj7Ytw== dependencies: oniguruma "^7.2.0" websocket-driver@>=0.5.1: - version "0.7.3" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" - integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg== + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== dependencies: - http-parser-js ">=0.4.0 <0.4.11" + http-parser-js ">=0.5.1" safe-buffer ">=5.1.0" websocket-extensions ">=0.1.1" websocket-extensions@>=0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" - integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@1.3.1, which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== +which@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@1.1.3, wide-align@^1.1.0: +wide-align@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: string-width "^1.0.2 || 2" -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= +workerpool@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.0.0.tgz#85aad67fa1a2c8ef9386a1b43539900f61d03d58" + integrity sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA== + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: +y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== -yallist@^3.0.0, yallist@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== - -yargs-parser@13.0.0: - version "13.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.0.0.tgz#3fc44f3e76a8bdb1cc3602e860108602e5ccde8b" - integrity sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw== +yargs-parser@13.1.2, yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== +yargs-parser@^15.0.1: + version "15.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.1.tgz#54786af40b820dcb2fb8025b11b4d659d76323b3" + integrity sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^13.0.0: - version "13.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" - integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== +yargs-unparser@1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.1.tgz#bd4b0ee05b4c94d058929c32cb09e3fce71d3c5f" + integrity sha512-qZV14lK9MWsGCmcr7u5oXGH0dbGqZAIxTDrWXZDo5zUr6b6iUmelNKO6x6R1dQT24AH3LgRxJpr8meWy2unolA== dependencies: - camelcase "^5.0.0" + camelcase "^5.3.1" decamelize "^1.2.0" - -yargs-unparser@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.5.0.tgz#f2bb2a7e83cbc87bb95c8e572828a06c9add6e0d" - integrity sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw== - dependencies: flat "^4.1.0" - lodash "^4.17.11" - yargs "^12.0.5" + is-plain-obj "^1.1.0" + yargs "^14.2.3" -yargs@13.2.2: - version "13.2.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993" - integrity sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA== +yargs@13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== dependencies: - cliui "^4.0.0" + cliui "^5.0.0" find-up "^3.0.0" get-caller-file "^2.0.1" - os-locale "^3.1.0" require-directory "^2.1.1" require-main-filename "^2.0.0" set-blocking "^2.0.0" string-width "^3.0.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^13.0.0" + yargs-parser "^13.1.2" -yargs@^12.0.5: - version "12.0.5" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== +yargs@^14.2.3: + version "14.2.3" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414" + integrity sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg== dependencies: - cliui "^4.0.0" + cliui "^5.0.0" decamelize "^1.2.0" find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" + get-caller-file "^2.0.1" require-directory "^2.1.1" - require-main-filename "^1.0.1" + require-main-filename "^2.0.0" set-blocking "^2.0.0" - string-width "^2.0.0" + string-width "^3.0.0" which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" + y18n "^4.0.0" + yargs-parser "^15.0.1"