From 188cf313827217286f9872346696dca4e96d8161 Mon Sep 17 00:00:00 2001 From: njlr Date: Wed, 6 Oct 2021 19:30:36 +0100 Subject: [PATCH 1/5] * Introduces decoders concept --- .gitignore | 2 +- .paket/Paket.Restore.targets | 494 -------------- paket.dependencies | 2 + paket.lock | 2 + .../MiddlewareDefinitions.fs | 8 +- .../SchemaDefinitions.fs | 12 +- src/FSharp.Data.GraphQL.Server/Execution.fs | 5 +- src/FSharp.Data.GraphQL.Server/Executor.fs | 125 +++- src/FSharp.Data.GraphQL.Server/Planning.fs | 3 +- src/FSharp.Data.GraphQL.Server/Relay/Node.fs | 6 +- src/FSharp.Data.GraphQL.Server/Values.fs | 158 ++++- src/FSharp.Data.GraphQL.Shared/Decoding.fs | 618 ++++++++++++++++++ .../FSharp.Data.GraphQL.Shared.fsproj | 1 + .../Introspection.fs | 16 +- src/FSharp.Data.GraphQL.Shared/TypeSystem.fs | 499 +++++++++++--- src/FSharp.Data.GraphQL.Shared/Validation.fs | 3 +- .../paket.references | 3 +- .../CoercionTests.fs | 1 - .../DecodingTests.fs | 119 ++++ .../DeferredTests.fs | 10 +- .../FSharp.Data.GraphQL.Tests.fsproj | 1 + .../Relay/NodeTests.fs | 1 + .../VariablesTests.fs | 12 +- 23 files changed, 1465 insertions(+), 636 deletions(-) delete mode 100644 .paket/Paket.Restore.targets create mode 100644 src/FSharp.Data.GraphQL.Shared/Decoding.fs create mode 100644 tests/FSharp.Data.GraphQL.Tests/DecodingTests.fs diff --git a/.gitignore b/.gitignore index ea31e6ff6..e5174110e 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,7 @@ samples/client-provider/js/*.* # Build results -npm-debug.log +npm-debug.log node_modules/ [Dd]ebug/ [Rr]elease/ diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets deleted file mode 100644 index 8d37e28bc..000000000 --- a/.paket/Paket.Restore.targets +++ /dev/null @@ -1,494 +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 - - - False - - $(BaseIntermediateOutputPath.TrimEnd('\').TrimEnd('\/')) - - - - - - - - - $(PaketRootPath)paket - $(PaketToolsPath)paket - - - - - - $(PaketRootPath)paket.exe - $(PaketToolsPath)paket.exe - - - - - - <_DotnetToolsJson Condition="Exists('$(PaketRootPath)/.config/dotnet-tools.json')">$([System.IO.File]::ReadAllText("$(PaketRootPath)/.config/dotnet-tools.json")) - <_ConfigContainsPaket Condition=" '$(_DotnetToolsJson)' != ''">$(_DotnetToolsJson.Contains('"paket"')) - <_ConfigContainsPaket Condition=" '$(_ConfigContainsPaket)' == ''">false - - - - - - - - - - - <_PaketCommand>dotnet paket - - - - - - $(PaketToolsPath)paket - $(PaketBootStrapperExeDir)paket - - - paket - - - - - <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) - <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(_PaketExeExtension)' == '.dll' ">dotnet "$(PaketExePath)" - <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(OS)' != 'Windows_NT' AND '$(_PaketExeExtension)' == '.exe' ">$(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" - <_PaketCommand Condition=" '$(_PaketCommand)' == '' ">"$(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.dependencies b/paket.dependencies index 092d9ae36..f9c88863c 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -18,6 +18,8 @@ group Common nuget Microsoft.Extensions.Http 5 + nuget FsToolkit.ErrorHandling + # Those are needed for the client type provider. github fsprojects/FSharp.TypeProviders.SDK:377d56321ad062985ed5aa19f205c1c4f04ef328 src/ProvidedTypes.fsi github fsprojects/FSharp.TypeProviders.SDK:377d56321ad062985ed5aa19f205c1c4f04ef328 src/ProvidedTypes.fs diff --git a/paket.lock b/paket.lock index 86700f6ee..321874bf0 100644 --- a/paket.lock +++ b/paket.lock @@ -9,6 +9,8 @@ NUGET FParsec (1.1.1) FSharp.Core (>= 4.3.4) FSharp.Core (4.7.2) + FsToolkit.ErrorHandling (2.7) + FSharp.Core (>= 4.6.2) Microsoft.Bcl.AsyncInterfaces (5.0) - restriction: || (&& (== net50) (>= net461)) (&& (== net50) (< netstandard2.1)) (== netstandard2.0) System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net50) (>= net461)) (&& (== net50) (< netcoreapp2.1) (< netstandard2.1)) (== netstandard2.0) Microsoft.Extensions.DependencyInjection (5.0.1) diff --git a/src/FSharp.Data.GraphQL.Server.Middleware/MiddlewareDefinitions.fs b/src/FSharp.Data.GraphQL.Server.Middleware/MiddlewareDefinitions.fs index 658098ff1..b678936ae 100644 --- a/src/FSharp.Data.GraphQL.Server.Middleware/MiddlewareDefinitions.fs +++ b/src/FSharp.Data.GraphQL.Server.Middleware/MiddlewareDefinitions.fs @@ -77,13 +77,18 @@ type internal ObjectListFilterMiddleware<'ObjectType, 'ListType>(reportToMetadat |> Seq.cast ctx.TypeMap.AddTypes(modifiedTypes, overwrite = true) next ctx + let reportMiddleware (ctx : ExecutionContext) (next : ExecutionContext -> AsyncVal) = let rec collectArgs (acc : (string * ObjectListFilter) list) (fields : ExecutionInfo list) = let fieldArgs field = field.Ast.Arguments |> Seq.map (fun x -> match x.Name with - | "filter" -> ObjectListFilter.CoerceInput x.Value + | "filter" -> + // ObjectListFilter.CoerceInput x.Value + match ObjectListFilter.Decoder x.Value with + | Ok t -> Some t + | Error _ -> None | _ -> None) |> Seq.choose id |> Seq.map (fun x -> field.Ast.AliasOrName, x) @@ -109,6 +114,7 @@ type internal ObjectListFilterMiddleware<'ObjectType, 'ListType>(reportToMetadat { ctx with Metadata = ctx.Metadata.Add("filters", collectArgs [] ctx.ExecutionPlan.Fields) } | false -> ctx next ctx + interface IExecutorMiddleware with member __.CompileSchema = Some compileMiddleware member __.PostCompileSchema = None diff --git a/src/FSharp.Data.GraphQL.Server.Middleware/SchemaDefinitions.fs b/src/FSharp.Data.GraphQL.Server.Middleware/SchemaDefinitions.fs index bd9b00799..e57f76b0e 100644 --- a/src/FSharp.Data.GraphQL.Server.Middleware/SchemaDefinitions.fs +++ b/src/FSharp.Data.GraphQL.Server.Middleware/SchemaDefinitions.fs @@ -2,6 +2,7 @@ namespace FSharp.Data.GraphQL.Server.Middleware open FSharp.Data.GraphQL.Types open FSharp.Data.GraphQL.Ast +open FSharp.Data.GraphQL.Decoding /// Contains customized schema definitions for extensibility features. [] @@ -94,5 +95,12 @@ module SchemaDefinitions = Description = Some "The `Filter` scalar type represents a filter on one or more fields of an object in an object list. The filter is represented by a JSON object where the fields are the complemented by specific suffixes to represent a query." - CoerceInput = coerceObjectListFilterInput - CoerceValue = coerceObjectListFilterValue } \ No newline at end of file + // CoerceInput = coerceObjectListFilterInput + Decoder = + (fun (value : Value) -> + match coerceObjectListFilterInput value with + | Some olf -> Ok olf + | None -> + let message = sprintf "Failed to decode %A as an ObjectListFilter" value + Error (DecodeError.reason message)) + CoerceValue = coerceObjectListFilterValue } diff --git a/src/FSharp.Data.GraphQL.Server/Execution.fs b/src/FSharp.Data.GraphQL.Server/Execution.fs index b2f0695ce..c0f61c58e 100644 --- a/src/FSharp.Data.GraphQL.Server/Execution.fs +++ b/src/FSharp.Data.GraphQL.Server/Execution.fs @@ -632,7 +632,8 @@ let private compileObject (objdef: ObjectDef) (executeFields: FieldDef -> unit) fieldDef.Args |> Array.iter (fun arg -> let errMsg = sprintf "Object '%s': field '%s': argument '%s': " objdef.Name fieldDef.Name arg.Name - arg.ExecuteInput <- compileByType errMsg arg.TypeDef)) + arg.ExecuteInput <- compileByType errMsg arg.TypeDef + )) let internal compileSchema (ctx : SchemaCompileContext) = ctx.Schema.TypeMap.ToSeq() @@ -650,7 +651,7 @@ let internal compileSchema (ctx : SchemaCompileContext) = | InputObject indef -> compileInputObject indef | _ -> ()) -let internal coerceVariables (variables: VarDef list) (vars: Map) = +let internal coerceVariables (variables: VarDef list) (vars: Map) = variables |> List.fold (fun acc vardef -> Map.add vardef.Name (coerceVariable vardef vars) acc) Map.empty diff --git a/src/FSharp.Data.GraphQL.Server/Executor.fs b/src/FSharp.Data.GraphQL.Server/Executor.fs index 9e8e14f4d..293a5e4f0 100644 --- a/src/FSharp.Data.GraphQL.Server/Executor.fs +++ b/src/FSharp.Data.GraphQL.Server/Executor.fs @@ -74,7 +74,8 @@ type Executor<'Root>(schema: ISchema<'Root>, middlewares : IExecutorMiddleware s (initialCtx : 'ctx) (onComplete : 'ctx -> 'res) : 'res = - let rec go ctx = function + let rec go (ctx : 'ctx) (middlewares : IExecutorMiddleware list) : 'res = + match middlewares with | [] -> onComplete ctx | m :: ms -> match (phaseSel m) with @@ -90,7 +91,7 @@ type Executor<'Root>(schema: ISchema<'Root>, middlewares : IExecutorMiddleware s | Success -> () | ValidationError errors -> raise (GraphQLException (System.String.Join("\n", errors))) - let eval (executionPlan: ExecutionPlan, data: 'Root option, variables: Map): Async = + let eval (executionPlan: ExecutionPlan, data: 'Root option, variables: Map): Async = let prepareOutput res = let prepareData data (errs: Error list) = let parsedErrors = @@ -129,7 +130,7 @@ type Executor<'Root>(schema: ISchema<'Root>, middlewares : IExecutorMiddleware s return GQLResponse.Invalid(errors, executionPlan.Metadata) } - let execute (executionPlan: ExecutionPlan, data: 'Root option, variables: Map option) = + let execute (executionPlan: ExecutionPlan, data: 'Root option, variables: Map option) = let variables = defaultArg variables Map.empty eval (executionPlan, data, variables) @@ -177,7 +178,7 @@ type Executor<'Root>(schema: ISchema<'Root>, middlewares : IExecutorMiddleware s /// Execution plan for the operation. /// Optional object provided as a root to all top level field resolvers /// Map of all variable values provided by the client request. - member __.AsyncExecute(executionPlan: ExecutionPlan, ?data: 'Root, ?variables: Map): Async = + member __.AsyncExecute(executionPlan: ExecutionPlan, ?data: 'Root, ?variables: Map): Async = execute (executionPlan, data, variables) /// @@ -191,7 +192,7 @@ type Executor<'Root>(schema: ISchema<'Root>, middlewares : IExecutorMiddleware s /// Map of all variable values provided by the client request. /// In case when document consists of many operations, this field describes which of them to execute. /// A plain dictionary of metadata that can be used through execution customizations. - member __.AsyncExecute(ast: Document, ?data: 'Root, ?variables: Map, ?operationName: string, ?meta : Metadata): Async = + member __.AsyncExecute(ast: Document, ?data: 'Root, ?variables: Map, ?operationName: string, ?meta : Metadata): Async = let meta = defaultArg meta Metadata.Empty let executionPlan = createExecutionPlan (ast, operationName, meta) execute (executionPlan, data, variables) @@ -207,7 +208,7 @@ type Executor<'Root>(schema: ISchema<'Root>, middlewares : IExecutorMiddleware s /// Map of all variable values provided by the client request. /// In case when document consists of many operations, this field describes which of them to execute. /// A plain dictionary of metadata that can be used through execution customizations. - member __.AsyncExecute(queryOrMutation: string, ?data: 'Root, ?variables: Map, ?operationName: string, ?meta : Metadata): Async = + member __.AsyncExecute(queryOrMutation: string, ?data: 'Root, ?variables: Map, ?operationName: string, ?meta : Metadata): Async = let meta = defaultArg meta Metadata.Empty let ast = parse queryOrMutation let executionPlan = createExecutionPlan (ast, operationName, meta) @@ -235,3 +236,115 @@ type Executor<'Root>(schema: ISchema<'Root>, middlewares : IExecutorMiddleware s let meta = defaultArg meta Metadata.Empty let ast = parse queryOrMutation createExecutionPlan (ast, operationName, meta) + +[] +module CompatabilityExtensions = + + open System + + module internal Helpers = + + open System.Reflection + open FSharp.Reflection + open FSharp.Data.GraphQL.Ast + + let private (| FSharpListType |) obj = + let t = obj.GetType() + if t.IsGenericType && t.GetGenericTypeDefinition() = typedefof then + // Crafty trick since we can always do `List<'t> :> seq` + // Perhaps not the most efficient way, involves copying + let xs = box obj :?> seq |> List.ofSeq + Some xs + else + None + + let private (| RecordType |) obj = + let t = obj.GetType() + if FSharpType.IsRecord t then + Some t + else + None + + let private (| UnionType |) obj = + let t = obj.GetType() + if FSharpType.IsUnion t then + Some t + else + None + + let private (| EnumType |) obj = + let t = obj.GetType() + if t.IsEnum then + Some t + else + None + + let private (| TupleType |) obj = + let t = obj.GetType() + if FSharpType.IsTuple t then + Some (FSharpValue.GetTupleFields obj) + else + None + + let private (| FSharpOptionType |) obj = + let t = obj.GetType() + if t.IsGenericType && t.GetGenericTypeDefinition() = typedefof then + let _, values = FSharpValue.GetUnionFields(obj, t) + let opt = values |> Seq.tryHead // Some has one field and None has zero + Some opt + else + None + + let rec private objToValue (x : obj) = + match box x with + | null -> NullValue + | :? Value as v -> v + | :? bool as b -> BooleanValue b + | :? int64 as i -> IntValue i + | :? int as i -> IntValue (int64 i) + | :? string as s -> StringValue s + | :? Guid as g -> StringValue (string g) + | :? Map as m -> + m + |> Map.map (fun _ v -> objToValue v) + |> ObjectValue + | FSharpOptionType (Some opt) -> + match opt with + | Some x -> objToValue x + | None -> NullValue + | TupleType (Some fields) -> + fields + |> Seq.map objToValue + |> Seq.toList + |> ListValue + | FSharpListType (Some xs) -> + xs |> List.map objToValue |> ListValue + | RecordType (Some t) -> + let ts = FSharpType.GetRecordFields(t) + let vs = FSharpValue.GetRecordFields(x) + + Map.ofSeq [ + for pi, v in Seq.zip ts vs do + let value = objToValue v + pi.Name, value + ] + |> ObjectValue + | UnionType (Some t) -> + let uci, _ = FSharpValue.GetUnionFields(x, t) + EnumValue uci.Name + | EnumType (Some t) -> + StringValue (t.GetEnumName(x)) + | _ -> failwithf "Error converting %A (type: %s) to an input value" x (x.GetType().FullName) + + let variablesToValues (vars : Map) : Map = + vars + |> Map.map (fun _ v -> objToValue v) + + open Helpers + + type Executor<'Root> with + + [] + member this.AsyncExecute(ast : Document, ?data : 'Root, ?variables : Map, ?operationName : string, ?meta : Metadata): Async = + let variables = variables |> Option.map variablesToValues + this.AsyncExecute(ast, ?data=data, ?variables=variables, ?operationName=operationName, ?meta=meta) diff --git a/src/FSharp.Data.GraphQL.Server/Planning.fs b/src/FSharp.Data.GraphQL.Server/Planning.fs index 1eff69717..aaed6bac7 100644 --- a/src/FSharp.Data.GraphQL.Server/Planning.fs +++ b/src/FSharp.Data.GraphQL.Server/Planning.fs @@ -29,7 +29,8 @@ let TypeMetaFieldDef = Description = None TypeDef = String DefaultValue = None - ExecuteInput = variableOrElse(coerceStringInput >> Option.map box >> Option.toObj) } + ExecuteInput = variableOrElse(coerceStringInput >> Option.map box >> Option.toObj) + } ], resolve = fun ctx (_:obj) -> ctx.Schema.Introspected.Types diff --git a/src/FSharp.Data.GraphQL.Server/Relay/Node.fs b/src/FSharp.Data.GraphQL.Server/Relay/Node.fs index 47543e470..44956fbc5 100644 --- a/src/FSharp.Data.GraphQL.Server/Relay/Node.fs +++ b/src/FSharp.Data.GraphQL.Server/Relay/Node.fs @@ -45,7 +45,7 @@ module GlobalId = static member GlobalIdField (typeName: string, resolve: (ResolveFieldContext -> 'In -> string)) = Define.Field( name = "id", - typedef = ID, + typedef = ID, description = "The ID of an object", resolve = fun ctx value -> toGlobalId typeName (resolve ctx value)) @@ -53,7 +53,7 @@ module GlobalId = static member GlobalIdField (resolve: (ResolveFieldContext -> 'In -> string)) = Define.Field( name = "id", - typedef = ID, + typedef = ID, description = "The ID of an object", resolve = fun ctx value -> toGlobalId ctx.ParentType.Name (resolve ctx value)) @@ -66,7 +66,7 @@ module GlobalId = name = "node", typedef = Nullable nodeDef, description = "Fetches an object given its ID", - args = [ Define.Input("id", ID, description = "Identifier of an object") ], + args = [ Define.Input("id", ID, description = "Identifier of an object") ], resolve = fun ctx value -> let id = ctx.Arg("id") resolve ctx value id) diff --git a/src/FSharp.Data.GraphQL.Server/Values.fs b/src/FSharp.Data.GraphQL.Server/Values.fs index fbc646358..8a74b2ae2 100644 --- a/src/FSharp.Data.GraphQL.Server/Values.fs +++ b/src/FSharp.Data.GraphQL.Server/Values.fs @@ -8,8 +8,54 @@ open System open System.Reflection open System.Collections.Generic open FSharp.Data.GraphQL.Ast +open FSharp.Data.GraphQL.Decoding open FSharp.Data.GraphQL.Types open FSharp.Data.GraphQL.Types.Patterns +open FsToolkit.ErrorHandling + +let private renderDecodeError (error : DecodeError) = + [ + for p in error.Path do + match p with + | AtIndex index -> sprintf "list element %i" index + | InProperty name -> sprintf "in field '%s'" name + | InInputObject typeName -> sprintf "in input object '%s'" typeName + + match error.Reason with + | DecodeErrorReason.TypeMismatch (expected, actual) -> + sprintf "expected value of type %s but got %s" expected actual + | DecodeErrorReason.Failure message -> + message + ] + |> FSharp.Core.String.concat ": " + +let replaceVariables (value : Value) (variables : Map) = + let rec loop (value : Value) (visited : Set) = + match value with + | Variable name -> + if Set.contains name visited then + Error (sprintf "Cycle in variable with name %s" name) + else + match Map.tryFind name variables with + | Some variableValue -> + loop variableValue (Set.add name visited) + | None -> + Error (sprintf "No variable with called %s could be found" name) + | ListValue xs -> + xs + |> List.map (fun listValue -> loop listValue visited) + |> List.sequenceResultM + |> Result.map ListValue + | ObjectValue m -> + m + |> Map.toSeq + |> Seq.map (fun (k, v) -> loop value visited |> Result.map (fun v -> k, v)) + |> Seq.toList + |> List.sequenceResultM + |> Result.map (Map.ofSeq >> ObjectValue) + | _ -> Ok value + + loop value Set.empty /// Tries to convert type defined in AST into one of the type defs known in schema. let inline tryConvertAst schema ast = @@ -33,10 +79,24 @@ let inline tryConvertAst schema ast = let inline private notAssignableMsg (innerDef: InputDef) value : string = sprintf "value of type %s is not assignable from %s" innerDef.Type.Name (value.GetType().Name) -let rec internal compileByType (errMsg: string) (inputDef: InputDef): ExecuteInput = +let rec internal compileByType (errMsg : string) (inputDef : InputDef) : ExecuteInput = match inputDef with | Scalar scalardef -> - variableOrElse (scalardef.CoerceInput >> Option.toObj) + // Value -> Map -> obj + (fun (value : Value) (vars : Map) -> + match value with + | Variable name -> + match Map.tryFind name vars with + | Some o -> o + | None -> null + | _ -> + match scalardef.BoxedDecoder value with + | Ok t -> box t + | Error error -> + failwithf "%A: %A" scalardef error + ) + // variableOrElse (scalardef.CoerceInput >> Option.toObj) + | InputObject objdef -> let objtype = objdef.Type let ctor = ReflectionHelper.matchConstructor objtype (objdef.Fields |> Array.map (fun x -> x.Name)) @@ -76,18 +136,30 @@ let rec internal compileByType (errMsg: string) (inputDef: InputDef): ExecuteInp // try to construct a list from single element let single = inner value variables if single = null then null else cons single nil - | Nullable (Input innerdef) -> - let inner = compileByType errMsg innerdef - let some, none = ReflectionHelper.optionOfType innerdef.Type + | NullableWithWrapper (nullableDef, Input inputDef) -> + // let inner = compileByType errMsg innerdef + // let some, none = ReflectionHelper.optionOfType innerdef.Type + + (fun (value : Value) (vars : Map) -> + match value with + | Variable name -> + match Map.tryFind name vars with + | Some o -> o + | None -> null + | value -> + match nullableDef.BoxedDecoder value with + | Ok t -> t + | Error error -> + raise(GraphQLException (errMsg + (string error)))) + + // let i = inner variables value + // match i with + // | null -> none + // | coerced -> + // let c = some coerced + // if c <> null then c + // else raise(GraphQLException (errMsg + notAssignableMsg innerdef coerced)) - fun variables value -> - let i = inner variables value - match i with - | null -> none - | coerced -> - let c = some coerced - if c <> null then c - else raise(GraphQLException (errMsg + notAssignableMsg innerdef coerced)) | Enum enumdef -> fun value variables -> match value with @@ -165,17 +237,49 @@ and private coerceVariableInputObject (objdef) (vardef: VarDef) (input: obj) err upcast mapped | _ -> input -let internal coerceVariable (vardef: VarDef) (inputs) = - let vname = vardef.Name - match Map.tryFind vname inputs with - | None -> - match vardef.DefaultValue with - | Some defaultValue -> - let errMsg = (sprintf "Variable '%s': " vname) - let executeInput = compileByType errMsg vardef.TypeDef - executeInput defaultValue inputs - | None -> - match vardef.TypeDef with - | Nullable _ -> null - | _ -> raise (GraphQLException (sprintf "Variable '$%s' of required type %s has no value provided." vname (vardef.TypeDef.ToString()))) - | Some input -> coerceVariableValue false vardef.TypeDef vardef input (sprintf "Variable '$%s': " vname) \ No newline at end of file +let internal coerceVariable (varDef : VarDef) (inputs : Map) = + result { + let vname = varDef.Name + + let decoderAllowsNull = Result.isOk (varDef.TypeDef.BoxedDecoder NullValue) + + let! variableValueOrDefault = + (match Map.tryFind vname inputs with + | Some value when decoderAllowsNull || value <> NullValue -> Ok value + | _ -> + match varDef.DefaultValue with + | Some defaultValue -> Ok defaultValue + | None -> + match varDef.TypeDef with + | Nullable _ -> Ok NullValue + |_ -> + let message = sprintf "Variable '$%s': expected value of type %s, but no value was found" vname (varDef.TypeDef.ToString()) + Error message) + + let! decoded = + varDef.TypeDef.BoxedDecoder variableValueOrDefault + |> Result.mapError (fun decodeError -> + sprintf "Variable '$%s': %s" vname (renderDecodeError decodeError)) + + return decoded + + // match Map.tryFind vname inputs with + // | None -> + // match varDef.DefaultValue with + // | Some defaultValue -> + // let errMsg = (sprintf "Variable '%s': " vname) + // let executeInput = compileByType errMsg varDef.TypeDef + // executeInput defaultValue inputs + // | None -> + // match varDef.TypeDef with + // | Nullable _ -> null + // | _ -> raise (GraphQLException (sprintf "Variable '$%s' of required type %s has no value provided." vname (vardef.TypeDef.ToString()))) + // | Some inputValue -> + // varDef.TypeDef.TryDecode inputValue + // // coerceVariableValue false vardef.TypeDef vardef input (sprintf "Variable '$%s': " vname) + } + |> ( + function + | Ok x -> x + | Error error -> + raise (GraphQLException (error))) \ No newline at end of file diff --git a/src/FSharp.Data.GraphQL.Shared/Decoding.fs b/src/FSharp.Data.GraphQL.Shared/Decoding.fs new file mode 100644 index 000000000..7ef503399 --- /dev/null +++ b/src/FSharp.Data.GraphQL.Shared/Decoding.fs @@ -0,0 +1,618 @@ +namespace FSharp.Data.GraphQL.Decoding + +open System +open System.Globalization +open FSharp.Data.GraphQL.Ast +open FsToolkit.ErrorHandling + +type DecodePathSegment = + | AtIndex of int + | InProperty of string + | InInputObject of typeName : string + +type DecodePath = DecodePathSegment list + +[] +type DecodeErrorReason = + | TypeMismatch of expected : string * actual : string + | Failure of string + +type DecodeError = + { + Reason : DecodeErrorReason + Path : DecodePath + } + +type DecodeResult<'t> = Result<'t, DecodeError> + +type Decoder<'t> = Value -> DecodeResult<'t> + +type CasingConvention = + | DropCamelCase // fooBar + | SnakeCase // foo_bar + +[] +type AutoDecoderSettings = + internal { + // If an object property is missing, we can replace it with null instead of an error + ReplaceMissingWithNull : bool + // When matching record fields we can automatically transform the field names to different casing conventions + // e.g. In JavaScript we might have "fooBar" and in .NET "FooBar" + Casing : CasingConvention option + // Mapping from full-type name to a boxed decoder + Customizations : Map> + } + +module DecodeError = + + let typeMismatch (expected : string) (actual : string) = + { + Reason = DecodeErrorReason.TypeMismatch (expected, actual) + Path = [] + } + + let reason (reason : string) = + { + Reason = DecodeErrorReason.Failure reason + Path = [] + } + + let nest (pathSegment : DecodePathSegment) (error : DecodeError) = + { + error with + Path = pathSegment :: error.Path + } + +module Decoder = + + let always (x) : Decoder<'t> = + (fun _ -> x) + + let succeed (x) : Decoder<'t> = + always (Ok x) + + let fail (error) : Decoder<'t> = + always (Error error) + + let map (f : 't -> 'u) (m : Decoder<'t>) : Decoder<'u> = + (fun value -> + match m value with + | Ok t -> Ok (f t) + | Error error -> Error error) + + let mapError (f : DecodeError -> DecodeError) (m : Decoder<'t>) : Decoder<'t> = + (fun value -> + match m value with + | Ok t -> Ok t + | Error error -> Error (f error)) + + let bind (f : 't -> Decoder<'u>) (m : Decoder<'t>) : Decoder<'u> = + (fun value -> + match m value with + | Ok t -> (f t) value + | Error error -> Error error) + + let inline box (d : Decoder<'t>) : Decoder = + map box d + + let inline unbox (d : Decoder) : Decoder<'t> = + map unbox d + +module AutoDecoderSettings = + + let empty = + { + ReplaceMissingWithNull = false + Casing = None + Customizations = Map.empty + } + + let replaceMissingWithNull (flag : bool) (settings : AutoDecoderSettings) = + { + settings with + ReplaceMissingWithNull = flag + } + + let casing (conv : CasingConvention) (settings : AutoDecoderSettings) = + { + settings with + Casing = Some conv + } + + let customize (decoder : Decoder<'t>) (settings : AutoDecoderSettings) = + let t = typeof<'t> + + { + settings with + Customizations = + settings.Customizations + |> Map.add t.FullName (Decoder.box decoder) + } + + let customizeBoxed (t : Type) (decoder : Decoder) (settings : AutoDecoderSettings) = + { + settings with + Customizations = + settings.Customizations + |> Map.add t.FullName (Decoder.box decoder) + } + +module CasingConvention = + + open System.Text.RegularExpressions + + let private charToString (c : char) : string = + String([| c |]) + + let private lowerFirst (name : string) = + if name.Length > 0 + then + if Char.IsUpper name.[0] then + charToString(Char.ToLowerInvariant(name.[0])) + (name.Substring(1)) + else + name + else + name + + let apply (name : string) (conv : CasingConvention) = + match conv with + | DropCamelCase -> lowerFirst name + | SnakeCase -> Regex.Replace(lowerFirst name, "[A-Z]", "_$0").ToLowerInvariant() + +module Decode = + + let nullValue : Decoder = + fun value -> + match value with + | NullValue -> Ok () + | x -> + Error (DecodeError.reason (sprintf "expected None but got %A" x)) + + let field (name : string) (fieldDecoder : Decoder<'t>) : Decoder<'t> = + fun value -> + match value with + | ObjectValue m -> + match m |> Map.tryFind name with + | Some value -> + let fieldDecoder = + fieldDecoder + |> Decoder.mapError (DecodeError.nest (InProperty name)) + + fieldDecoder value + | None -> + let propertiesFound = + m + |> Map.toSeq + |> Seq.map (fst >> (fun x -> "\"" + x + "\"")) + |> String.concat "; " + + let message = sprintf "Missing object property \"%s\", but found the following properties: %s" name propertiesFound + + Error (DecodeError.reason message) + | x -> + Error (DecodeError.reason (sprintf "expected an Object but got %A" x)) + + let stringish : Decoder = + fun value -> + match value with + | StringValue s -> Ok s + | IntValue i -> Ok (string i) + | FloatValue f -> Ok (string f) + | BooleanValue b -> Ok (if b then "true" else "false") + | NullValue -> + Error (DecodeError.reason (sprintf "expected value of type String but got None")) + | x -> + Error (DecodeError.reason (sprintf "expected value of type String but got %A" x)) + + let string : Decoder = + fun value -> + match value with + | StringValue s -> Ok s + | x -> + Error (DecodeError.reason (sprintf "expected value of type String but got %A" x)) + + let intish : Decoder = + fun value -> + match value with + | IntValue i -> Ok (int i) + | BooleanValue true -> Ok 1 + | BooleanValue false -> Ok 0 + | FloatValue f -> Ok (int f) + | StringValue s -> + match Int32.TryParse s with + | (true, i) -> Ok i + | _ -> + Error (DecodeError.reason (sprintf "Expected an int-like value but found the string \"%s\"" s)) + | x -> + Error (DecodeError.reason (sprintf "Expected an int-like value but found %A" x)) + + let int : Decoder = + fun value -> + match value with + | IntValue i -> Ok (int i) + | x -> + Error (DecodeError.reason (sprintf "Expected an int but found %A" x)) + + let floatish : Decoder = + fun value -> + match value with + | IntValue i -> Ok (double i) + | FloatValue f -> Ok f + | StringValue s -> + match Double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture) with + | true, f -> Ok f + | false, _ -> + Error (DecodeError.reason (sprintf "Expected an float-like value but found the string \"%s\"" s)) + | BooleanValue b -> Ok (if b then 1. else 0.) + | x -> + Error (DecodeError.reason (sprintf "Expected a float but found %A" x)) + + let float : Decoder = + fun value -> + match value with + | FloatValue f -> Ok f + | x -> + Error (DecodeError.reason (sprintf "Expected a float but found %A" x)) + + let longish : Decoder = + fun value -> + match value with + | IntValue i -> Ok (int64 i) + | FloatValue f -> Ok (int64 f) + | StringValue s -> + match Int64.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture) with + | true, i -> Ok i + | false, _ -> + Error (DecodeError.reason (sprintf "Expected an long-like value but found the string \"%s\"" s)) + | BooleanValue b -> Ok (if b then 1L else 0L) + | x -> + Error (DecodeError.reason (sprintf "Expected a long-like but found %A" x)) + + let boolish : Decoder = + fun value -> + match value with + | NullValue -> Ok false + | IntValue i -> Ok (i <> 0L) + | FloatValue f -> Ok (f <> 0.) + | BooleanValue b -> Ok b + | StringValue s -> + match Boolean.TryParse s with + | (true, b) -> Ok b + | _ -> + Error (DecodeError.reason (sprintf "Expected an bool-like value but found the string \"%s\"" s)) + | x -> + Error (DecodeError.reason (sprintf "Expected an bool-like value but found %A" x)) + + let bool : Decoder = + fun value -> + match value with + | BooleanValue b -> Ok b + | x -> + Error (DecodeError.reason (sprintf "Expected a bool but found %A" x)) + + let option (decoder : Decoder<'t>) : Decoder<'t option> = + fun value -> + match value with + | NullValue -> Ok None + | value -> + (Decoder.map Some decoder) value + + let list (decoder : Decoder<'t>) : Decoder<'t list> = + fun value -> + match value with + | ListValue xs -> + xs + |> List.mapi (fun i value -> + (decoder |> Decoder.mapError (DecodeError.nest (AtIndex i))) value + ) + |> List.sequenceResultM + | x -> + Error (DecodeError.reason (sprintf "Expected a list but found %A" x)) + + let enum cases : Decoder<'t> = + fun value -> + match value with + | EnumValue e -> + match cases |> Map.tryFind e with + | Some t -> Ok t + | None -> + Error (DecodeError.reason (sprintf "Unexpected value fo enum: %A" e)) + | x -> + Error (DecodeError.reason (sprintf "Expected an enum but found %A" x)) + + let uri : Decoder = + fun value -> + match value with + | StringValue s -> + match Uri.TryCreate(s, UriKind.RelativeOrAbsolute) with + | true, uri -> Ok uri + | false, _ -> + Error (DecodeError.reason (sprintf "Expected a valid URI but found the string \"%s\"" s)) + | x -> + Error (DecodeError.reason (sprintf "Expected a string but found %A" x)) + + let dateTime : Decoder = + fun value -> + match value with + | StringValue s -> + match DateTime.TryParse(s) with + | true, dt -> Ok dt + | false, _ -> + Error (DecodeError.reason (sprintf "Expected a valid date-time but found the string \"%s\"" s)) + | x -> + Error (DecodeError.reason (sprintf "Expected a string but found %A" x)) + + let guid : Decoder = + fun value -> + match value with + | StringValue s -> + match Guid.TryParse(s) with + | true, g -> Ok g + | false, _ -> + Error (DecodeError.reason (sprintf "Expected a valid GUID but found the string \"%s\"" s)) + | x -> + Error (DecodeError.reason (sprintf "Expected a string but found %A" x)) + + open FSharp.Reflection + + let private isReferenceEnum t = + if FSharpType.IsUnion t then + FSharpType.GetUnionCases(t) + |> Seq.forall (fun i -> i.GetFields().Length = 0) + else + false + + let rec autoObj (settings : AutoDecoderSettings) (t : Type) : Decoder = + match Map.tryFind t.FullName settings.Customizations with + | Some decoder -> + decoder + | None -> + if t = typeof then + (fun v -> bool v |> Result.map (fun t -> t |> box)) + elif t = typeof then + (fun v -> string v |> Result.map (fun t -> t |> box)) + elif t = typeof then + (fun v -> int v |> Result.map (fun t -> t |> box)) + elif FSharpType.IsRecord(t, allowAccessToPrivateRepresentation=true) then + autoRecord settings t + elif FSharpType.IsTuple t then + autoTuple settings t + elif t.IsGenericType && t.GetGenericTypeDefinition() = typedefof then + autoOption settings t + elif t.IsGenericType && t.GetGenericTypeDefinition() = typedefof then + autoList settings t + elif t.IsGenericType && t.GetGenericTypeDefinition() = typedefof> then + autoEnumerable settings t + elif isReferenceEnum t then + autoUnionEnum settings t + else + (fun (value : Value) -> + Error (DecodeError.reason (sprintf "We cannot automatically decode %A as type %A" value t))) + + and private autoRecord (settings : AutoDecoderSettings) (t : Type) = + let fields = FSharpType.GetRecordFields(t, allowAccessToPrivateRepresentation=true) + + function + | ObjectValue m -> + result { + let! values = + fields + |> Seq.map (fun field -> + result { + let transformedName = + match settings.Casing with + | Some strat -> CasingConvention.apply field.Name strat + | None -> field.Name + + let! value = + m + |> Map.tryFind transformedName + |> (fun o -> + if settings.ReplaceMissingWithNull then + o + |> Option.defaultValue (NullValue) + |> Some + else + o) + |> Result.requireSome ( + let propertiesFound = + m + |> Map.toSeq + |> Seq.map (fst >> (fun x -> "\"" + x + "\"")) + |> String.concat "; " + + let message = sprintf "Missing object property \"%s\", but found the following properties: %s" transformedName propertiesFound + + DecodeError.reason message) + + let decoder = + autoObj settings field.PropertyType + + let! decodedValue = + decoder value + |> Result.mapError (DecodeError.nest (InProperty field.Name)) + + return box decodedValue + } + ) + |> List.ofSeq + |> List.sequenceResultM + + return FSharpValue.MakeRecord(t, Seq.toArray values, allowAccessToPrivateRepresentation=true) |> box + } + | x -> Error (DecodeError.reason (sprintf "Expected an object but found %A" x)) + + and private autoTuple (settings : AutoDecoderSettings) (t : Type) : Decoder = + let els = FSharpType.GetTupleElements(t) + + if Seq.length els = 1 then + autoObj settings t + else + function + | ListValue xs -> + if List.length xs <> Seq.length els then + let message = sprintf "Incorrect number of tuple elements: expected %i but found %i" (Seq.length els) (List.length xs) + + Error (DecodeError.reason message) + else + result { + let! elements = + xs + |> Seq.zip els + |> Seq.mapi (fun i (t, v) -> + (autoObj settings t) v + |> Result.mapError (DecodeError.nest (AtIndex i)) + ) + |> Seq.toList + |> List.sequenceResultM + + return FSharpValue.MakeTuple(Seq.toArray elements, t) + } + | x -> + Error (DecodeError.reason (sprintf "Expected a list but found %A" x)) + + and private autoUnionEnum (settings : AutoDecoderSettings) (t : Type) : Decoder = + let cases = + FSharpType.GetUnionCases(t) + |> Seq.map (fun uci -> + let transformedName = + match settings.Casing with + | Some casing -> CasingConvention.apply uci.Name casing + | None -> uci.Name + + let value = FSharpValue.MakeUnion(uci, [||], allowAccessToPrivateRepresentation=true) + + transformedName, value + ) + |> Map.ofSeq + + let tryString s = + match Map.tryFind s cases with + | Some case -> Ok case + | None -> + Error (DecodeError.reason (sprintf "Unexpected enum value \"%s\"" s)) + + function + | EnumValue s -> tryString s + | StringValue s -> tryString s + | x -> + Error (DecodeError.reason (sprintf "Expected an enum but found %A" x)) + + and private autoOption (settings : AutoDecoderSettings) (t : Type) : Decoder = + let elementT = t.GenericTypeArguments.[0] + let elementDecoder = autoObj settings elementT + + let ucis = FSharpType.GetUnionCases(t) + + function + | NullValue -> Ok (box None) + | value -> + elementDecoder value + |> Result.map (fun value -> FSharpValue.MakeUnion(ucis.[1], [| value |])) + + and private autoList (settings : AutoDecoderSettings) (t : Type) : Decoder = + let elementT = t.GenericTypeArguments.[0] + let elementDecoder = autoObj settings elementT + + function + | ListValue values -> + let ucis = FSharpType.GetUnionCases(t, allowAccessToPrivateRepresentation=true) + let empty = FSharpValue.MakeUnion(ucis.[0], [||], allowAccessToPrivateRepresentation=true) + + (List.indexed values, Ok empty) + ||> Seq.foldBack (fun (index, value) acc -> + match acc with + | Error _ -> acc + | Ok acc -> + match elementDecoder value with + | Error error -> + Error (DecodeError.nest (AtIndex index) error) + | Ok result -> + FSharpValue.MakeUnion(ucis.[1], [| result; acc |], allowAccessToPrivateRepresentation=true) |> Ok) + | x -> + Error (DecodeError.reason (sprintf "Expected a list but found %A" x)) + + and private autoEnumerable (settings : AutoDecoderSettings) (t : Type) : Decoder = + let elementT = t.GenericTypeArguments.[0] + let objListType = typedefof + let listType = objListType.MakeGenericType(elementT) + + autoList settings listType + + let autoRecordFromFields (settings : AutoDecoderSettings) (fieldDecoders : Map>) : Decoder<'t> = + let t = typeof<'t> + let fields = FSharpType.GetRecordFields(t, allowAccessToPrivateRepresentation=true) + + (fun (value : Value) -> + match value with + | ObjectValue values -> + result { + let! decodedValues = + fields + |> Seq.map (fun field -> + result { + let! fieldDecoder = + fieldDecoders + |> Map.tryFind field.Name + |> Result.requireSome (DecodeError.reason (sprintf "Could not find a decoder for %s" field.Name)) + + let transformedName = + match settings.Casing with + | Some strat -> CasingConvention.apply field.Name strat + | None -> field.Name + + let! value = + values + |> Map.tryFind transformedName + |> (fun o -> + if settings.ReplaceMissingWithNull then + o + |> Option.defaultValue (NullValue) + |> Some + else + o) + |> Result.requireSome (DecodeError.reason (sprintf "Could not find a value for %s" transformedName)) + + let! decodedValue = fieldDecoder value + + return decodedValue + } + |> Result.mapError (DecodeError.nest (InProperty field.Name))) + |> Seq.toList + |> List.sequenceResultM + + let record = + FSharpValue.MakeRecord(t, Seq.toArray decodedValues, allowAccessToPrivateRepresentation=true) + :?> 't + + return record + } + | _ -> + Error (DecodeError.reason (sprintf "Expected an object but found %A" value))) + + let auto<'t> (casing : CasingConvention option) : Decoder<'t> = + let settings = + { + ReplaceMissingWithNull = true + Casing = casing + Customizations = Map.empty + } + + autoObj settings typeof<'t> + |> Decoder.unbox + + let autoWithSettings (settings : AutoDecoderSettings) : Decoder<'t> = + autoObj settings typeof<'t> + |> Decoder.unbox + +[] +module ComputationExpression = + + type DecoderBuilder() = + member this.Bind(m, f) = + Decoder.bind f m + + member this.Return(x) = + Decoder.succeed x + + let decoder = DecoderBuilder() diff --git a/src/FSharp.Data.GraphQL.Shared/FSharp.Data.GraphQL.Shared.fsproj b/src/FSharp.Data.GraphQL.Shared/FSharp.Data.GraphQL.Shared.fsproj index 2a5441633..54ad9fa15 100644 --- a/src/FSharp.Data.GraphQL.Shared/FSharp.Data.GraphQL.Shared.fsproj +++ b/src/FSharp.Data.GraphQL.Shared/FSharp.Data.GraphQL.Shared.fsproj @@ -12,6 +12,7 @@ + diff --git a/src/FSharp.Data.GraphQL.Shared/Introspection.fs b/src/FSharp.Data.GraphQL.Shared/Introspection.fs index 296d0cc2e..728818949 100644 --- a/src/FSharp.Data.GraphQL.Shared/Introspection.fs +++ b/src/FSharp.Data.GraphQL.Shared/Introspection.fs @@ -191,20 +191,20 @@ let rec __Type = | Some name -> let found = findIntrospected ctx name match ctx.TryArg "includeDeprecated" with - | Some true -> found.Fields |> Option.map Array.toSeq - | _ -> found.Fields |> Option.map (fun x -> upcast Array.filter (fun f -> not f.IsDeprecated) x)) + | Some true -> found.Fields |> Option.map Seq.toList + | _ -> found.Fields |> Option.map (fun x -> Seq.filter (fun f -> not f.IsDeprecated) x |> Seq.toList)) Define.Field("interfaces", Nullable (ListOf __Type), resolve = fun ctx t -> match t.Name with | None -> None | Some name -> let found = findIntrospected ctx name - found.Interfaces |> Option.map Array.toSeq ) + found.Interfaces |> Option.map Seq.toList ) Define.Field("possibleTypes", Nullable (ListOf __Type), resolve = fun ctx t -> match t.Name with | None -> None | Some name -> let found = findIntrospected ctx name - found.PossibleTypes |> Option.map Array.toSeq) + found.PossibleTypes |> Option.map Seq.toList) Define.Field("enumValues", Nullable (ListOf __EnumValue), args = [Define.Input("includeDeprecated", Boolean, false) ], resolve = fun ctx t -> match t.Name with @@ -212,14 +212,14 @@ let rec __Type = | Some name -> let found = findIntrospected ctx name match ctx.TryArg "includeDeprecated" with - | None | Some false -> found.EnumValues |> Option.map Array.toSeq - | Some true -> found.EnumValues |> Option.map (fun x -> upcast (x |> Array.filter (fun f -> not f.IsDeprecated)))) + | None | Some false -> found.EnumValues |> Option.map Seq.toList + | Some true -> found.EnumValues |> Option.map (fun x -> x |> Array.filter (fun f -> not f.IsDeprecated) |> Seq.toList)) Define.Field("inputFields", Nullable (ListOf __InputValue), resolve = fun ctx t -> match t.Name with | None -> None | Some name -> let found = findIntrospected ctx name - found.InputFields |> Option.map Array.toSeq) + found.InputFields |> Option.map Seq.toList) Define.Field("ofType", Nullable __Type, resolve = fun _ t -> t.OfType) ]) @@ -248,7 +248,7 @@ and __Field = [ Define.Field("name", String, fun _ f -> f.Name) Define.Field("description", Nullable String, fun _ f -> f.Description) - Define.Field("args", ListOf __InputValue, fun _ f -> f.Args) + Define.Field("args", ListOf __InputValue, fun _ f -> Seq.toList f.Args) Define.Field("type", __Type, fun _ f -> f.Type) Define.Field("isDeprecated", Boolean, resolve = fun _ f -> f.IsDeprecated) Define.Field("deprecationReason", Nullable String, fun _ f -> f.DeprecationReason) diff --git a/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs b/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs index df6dca4d3..03d95bda6 100644 --- a/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs +++ b/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs @@ -11,10 +11,12 @@ open FSharp.Data.GraphQL open FSharp.Data.GraphQL.Validation open FSharp.Data.GraphQL.Ast open FSharp.Data.GraphQL.Extensions +open FSharp.Data.GraphQL.Decoding open FSharp.Quotations open FSharp.Quotations.Patterns open FSharp.Reflection open FSharp.Linq.RuntimeHelpers +open FsToolkit.ErrorHandling /// Enum describing parts of the GraphQL query document AST, where /// related directive is valid to be used. @@ -546,6 +548,8 @@ and TypeDef<'Val> = and InputDef = interface inherit TypeDef + + abstract BoxedDecoder : Decoder end /// Representation of all type defintions, that can be uses as inputs. @@ -556,6 +560,8 @@ and InputDef<'Val> = interface inherit InputDef inherit TypeDef<'Val> + + abstract Decoder : Decoder<'Val> end /// Representation of all type defintions, that can be uses as outputs. @@ -849,7 +855,7 @@ and ExecutionContext = Schema : ISchema /// Boxed value of the top level type, root query/mutation. RootValue : obj - /// Execution plan describing, what fiedls are going to be resolved. + /// Execution plan describing, what fields are going to be resolved. ExecutionPlan : ExecutionPlan /// Collection of variables provided to execute current operation. Variables : Map @@ -960,7 +966,10 @@ and [] internal FieldDefinition<'Val, 'Res> = interface FieldDef<'Val> interface IEquatable with - member x.Equals f = x.Name = f.Name && x.TypeDef :> OutputDef = f.TypeDef && x.Args = f.Args + member x.Equals f = + x.Name = f.Name + && x.TypeDef :> OutputDef = f.TypeDef + && System.Linq.Enumerable.SequenceEqual(x.Args, f.Args) override x.Equals y = match y with @@ -986,7 +995,8 @@ and ScalarDef = /// Optional scalar type description. abstract Description : string option /// A function used to retrieve a .NET object from provided GraphQL query. - abstract CoerceInput : Value -> obj option + // abstract CoerceInput : Value -> obj option + // abstract Decoder : Decoder /// A function used to set a surrogate representation to be /// returned as a query result. abstract CoerceValue : obj -> obj option @@ -1004,32 +1014,57 @@ and [] ScalarDefinition<'Val> = /// Optional type description. Description : string option /// A function used to retrieve a .NET object from provided GraphQL query. - CoerceInput : Value -> 'Val option + // CoerceInput : Value -> 'Val option + Decoder : Decoder<'Val> /// A function used to set a surrogate representation to be /// returned as a query result. CoerceValue : obj -> 'Val option } + member private x.Nullable = + lazy ( + let nullable : NullableDefinition<_> = + { + OfType = x + // Decoder = Decode.option x.Decoder + } + + nullable + ) + + member private x.ListOf = + lazy ( + let list : ListOfDefinition<_,_> = + { + OfType = x + Decoder = Decode.list x.Decoder + } + + list + ) + interface TypeDef with member __.Type = typeof<'Val> member x.MakeNullable() = - let nullable : NullableDefinition<_> = { OfType = x } - upcast nullable + x.Nullable.Force() :> NullableDef member x.MakeList() = - let list: ListOfDefinition<_,_> = { OfType = x } - upcast list + x.ListOf.Force() :> ListOfDef - interface InputDef interface OutputDef + interface InputDef with + member x.BoxedDecoder = Decoder.box x.Decoder + + interface InputDef<'Val> with + member x.Decoder = x.Decoder + interface ScalarDef with member x.Name = x.Name member x.Description = x.Description - member x.CoerceInput input = x.CoerceInput input |> Option.map box + // member x.CoerceInput input = x.CoerceInput input |> Option.map box member x.CoerceValue value = (x.CoerceValue value) |> Option.map box - interface InputDef<'Val> interface OutputDef<'Val> interface LeafDef @@ -1115,20 +1150,46 @@ and internal EnumDefinition<'Val> = /// Optional enum type description. Description : string option /// List of available enum cases. - Options : EnumValue<'Val> [] } - interface InputDef + Options : EnumValue<'Val> [] + Decoder : Decoder<'Val> + } + + member private this.Nullable = + lazy ( + let nullable : NullableDefinition<_> = + { + OfType = this + // Decoder = Decoder.fail (DecodeError.reason "Cannot create a decoder for object types") + } + nullable + ) + + member private this.ListOf = + lazy ( + let list : ListOfDefinition<_,_> = + { + OfType = this + Decoder = Decode.list this.Decoder + } + list + ) + + interface InputDef with + member x.BoxedDecoder = Decoder.box x.Decoder + + interface InputDef<'Val> with + member x.Decoder = x.Decoder + interface OutputDef interface TypeDef with member __.Type = typeof<'Val> member x.MakeNullable() = - let nullable : NullableDefinition<_> = { OfType = x } - upcast nullable + upcast x.Nullable.Force() member x.MakeList() = - let list: ListOfDefinition<_,_> = { OfType = x } - upcast list + upcast x.ListOf.Force() interface EnumDef<'Val> with member x.Options = x.Options @@ -1199,11 +1260,19 @@ and [] internal ObjectDefinition<'Val> = member __.Type = typeof<'Val> member x.MakeNullable() = - let nullable : NullableDefinition<_> = { OfType = x } + let nullable : NullableDefinition<_> = + { + OfType = x + // Decoder = Decoder.fail (DecodeError.reason "Cannot create a decoder for object types") + } upcast nullable member x.MakeList() = - let list: ListOfDefinition<_,_> = { OfType = x } + let list: ListOfDefinition<_,_> = + { + OfType = x + Decoder = Decoder.fail (DecodeError.reason "Cannot create a decoder for object types") + } upcast list interface OutputDef @@ -1280,16 +1349,34 @@ and [] internal InterfaceDefinition<'Val> = /// interface for provided .NET object. ResolveType : (obj -> ObjectDef) option } + member private this.Nullable = + lazy ( + let nullable : NullableDefinition<_> = + { + OfType = this + // Decoder = Decoder.fail (DecodeError.reason "Cannot create a decoder for an interface definition") + } + nullable + ) + + member private this.ListOf = + lazy ( + let list : ListOfDefinition<_,_> = + { + OfType = this + Decoder = Decoder.fail (DecodeError.reason "Cannot create a decoder for an interface definition") + } + list + ) + interface TypeDef with member __.Type = typeof<'Val> member x.MakeNullable() = - let nullable : NullableDefinition<_> = { OfType = x } - upcast nullable + upcast x.Nullable.Force() member x.MakeList() = - let list: ListOfDefinition<_,_> = { OfType = x } - upcast list + upcast x.ListOf.Force() interface OutputDef @@ -1372,16 +1459,34 @@ and [] internal UnionDefinition<'In, 'Out> = /// specific values, that are wrapped in F# discriminated unions. ResolveValue : 'In -> 'Out } + member private this.Nullable = + lazy ( + let nullable : NullableDefinition<_> = + { + OfType = this + // Decoder = Decoder.fail (DecodeError.reason "Cannot create a decoder for UnionDefinition") + } + nullable + ) + + member private this.ListOf = + lazy ( + let list : ListOfDefinition<_,_> = + { + OfType = this + Decoder = Decoder.fail (DecodeError.reason "Cannot create a decoder for UnionDefinition") + } + list + ) + interface TypeDef with member __.Type = typeof<'Out> member x.MakeNullable() = - let nullable : NullableDefinition<_> = { OfType = x } - upcast nullable + upcast x.Nullable.Force() member x.MakeList() = - let list: ListOfDefinition<_,_> = { OfType = x } - upcast list + upcast x.ListOf.Force() interface OutputDef @@ -1433,19 +1538,40 @@ and ListOfDef<'Val, 'Seq when 'Seq :> 'Val seq> = inherit ListOfDef end -and internal ListOfDefinition<'Val, 'Seq when 'Seq :> 'Val seq> = - { OfType : TypeDef<'Val> } - interface InputDef +and [] internal ListOfDefinition<'Val, 'Seq when 'Seq :> 'Val seq> = + { + OfType : TypeDef<'Val> + Decoder : Decoder<'Seq> + } + + member private x.Nullable : Lazy> = + lazy { + OfType = x + } + + member private x.List : Lazy> = + lazy ({ + OfType = x + Decoder = Decode.list ((x :> InputDef<'Seq>).Decoder) + }) + + interface InputDef with + member x.BoxedDecoder = + let decoder = (x :> InputDef<'Seq>).Decoder + Decoder.box decoder + + interface InputDef<'Seq> with + member x.Decoder = + x.Decoder interface TypeDef with member __.Type = typeof<'Seq> + member x.MakeNullable() = - let nullable : NullableDefinition<_> = { OfType = x } - upcast nullable + x.Nullable.Force() :> NullableDef member x.MakeList() = - let list: ListOfDefinition<_, _> = { OfType = x } - upcast list + x.List.Force() :> ListOfDef interface OutputDef @@ -1455,6 +1581,14 @@ and internal ListOfDefinition<'Val, 'Seq when 'Seq :> 'Val seq> = interface ListOfDef<'Val, 'Seq> with member x.OfType = x.OfType + override x.Equals(y : obj) = + Object.ReferenceEquals(x, y) + || ( + match y with + | :? ListOfDefinition<'Val, 'Seq> as o -> x.OfType = o.OfType + | _ -> false + ) + override x.ToString() = "[" + x.OfType.ToString() + "]!" /// GraphQL type definition for nullable/optional types. @@ -1483,18 +1617,61 @@ and NullableDef<'Val> = end and internal NullableDefinition<'Val> = - { OfType : TypeDef<'Val> } - interface InputDef + { + OfType : TypeDef<'Val> + } + + member private x.Decoder = + lazy ( + match box x.OfType with + | :? InputDef<'Val option> as inputDef -> + inputDef.Decoder + | :? InputDef<'Val> as inputDef -> + Decode.option inputDef.Decoder + | _ -> + Decoder.fail (DecodeError.reason (sprintf "Cannot create a decoder for a NullableDefinition %A" x)) + ) + + member private x.List : Lazy> = + lazy ( + let innerDecoder = + match box x with + | :? InputDef<'Val option> as inputDef -> + inputDef.Decoder + | :? InputDef<'Val> as inputDef -> + Decode.option inputDef.Decoder + | _ -> + Decoder.fail (DecodeError.reason (sprintf "Cannot create a decoder for a NullableDefinition %A" x)) + + let list : ListOfDefinition<_, ('Val option) list> = + { + OfType = x + Decoder = Decode.list innerDecoder + + } + + list + ) interface TypeDef with member __.Type = typeof<'Val option> - member x.MakeNullable() = upcast x + member x.MakeNullable() = + upcast x + member x.MakeList() = - let list: ListOfDefinition<_,_> = { OfType = x } - upcast list + x.List.Force() :> ListOfDef interface OutputDef + interface InputDef with + member x.BoxedDecoder = + let decoder = (x :> InputDef<'Val option>).Decoder + Decoder.box decoder + + interface InputDef<'Val option> with + member x.Decoder = + x.Decoder.Force() + interface NullableDef with member x.OfType = upcast x.OfType @@ -1530,8 +1707,34 @@ and InputObjectDefinition<'Val> = Description : string option /// Function used to define field inputs. It must be lazy /// in order to support self-referencing types. - FieldsFn : unit -> InputFieldDef [] } - interface InputDef + FieldsFn : unit -> InputFieldDef [] + Decoder : Decoder<'Val> } + + member private this.Nullable = + lazy ( + let nullable : NullableDefinition<_> = + { + OfType = this + // Decoder = Decode.option this.Decoder + } + + nullable + ) + + member private this.ListOf = + lazy ( + let list : ListOfDefinition<_,_> = + { + OfType = this + Decoder = Decode.list this.Decoder + } + + list + ) + + interface InputDef with + member x.BoxedDecoder = + (Decoder.box x.Decoder) interface InputObjectDef with member x.Name = x.Name @@ -1539,7 +1742,9 @@ and InputObjectDefinition<'Val> = member x.Fields = x.FieldsFn() interface TypeDef<'Val> - interface InputDef<'Val> + interface InputDef<'Val> with + member x.Decoder = + x.Decoder interface NamedDef with member x.Name = x.Name @@ -1548,12 +1753,11 @@ and InputObjectDefinition<'Val> = member __.Type = typeof<'Val> member x.MakeNullable() = - let nullable : NullableDefinition<_> = { OfType = x } - upcast nullable + upcast x.Nullable.Force() member x.MakeList() = - let list: ListOfDefinition<_,_> = { OfType = x } - upcast list + upcast x.ListOf.Force() + /// Function type used for resolving input object field values. and ExecuteInput = Value -> Map -> obj @@ -1588,7 +1792,8 @@ and [] InputFieldDefinition<'In> = DefaultValue : 'In option /// INTERNAL API: input execution function - /// compiled by the runtime. - mutable ExecuteInput : ExecuteInput } + mutable ExecuteInput : ExecuteInput + } interface InputFieldDef with member x.Name = x.Name @@ -1711,11 +1916,19 @@ and [] SubscriptionObjectDefinition<'Val> = member __.Type = typeof<'Val> member x.MakeNullable() = - let nullable : NullableDefinition<_> = { OfType = x } + let nullable : NullableDefinition<_> = + { + OfType = x + // Decoder = Decoder.fail (DecodeError.reason "Cannot create a decoder for SubscriptionObjectDefinition") + } upcast nullable member x.MakeList() = - let list: ListOfDefinition<_,_> = { OfType = x } + let list : ListOfDefinition<_,_> = + { + OfType = x + Decoder = Decoder.fail (DecodeError.reason "Cannot create a decoder for SubscriptionObjectDefinition") + } upcast list interface ObjectDef with member x.Name = x.Name @@ -2222,6 +2435,12 @@ module Patterns = | :? NullableDef as x -> Some x.OfType | _ -> None + /// Active pattern to match GraphQL type defintion with nullable / optional types. + let (|NullableWithWrapper|_|) (tdef : TypeDef) = + match tdef with + | :? NullableDef as x -> Some (x, x.OfType) + | _ -> None + /// Active pattern to match GraphQL type defintion with non-null types. let (|NonNull|_|) (tdef : TypeDef) = match tdef with @@ -2261,7 +2480,7 @@ module Patterns = let rec private named (tdef : TypeDef) = match tdef with | :? NamedDef as n -> Some n - | Nullable inner -> named inner + | Nullable (inner) -> named inner | List inner -> named inner | _ -> None @@ -2516,11 +2735,34 @@ module SchemaDefinitions = /// Wraps a GraphQL type definition, allowing defining field/argument /// to take option of provided value. - let Nullable(innerDef : #TypeDef<'Val>) : NullableDef<'Val> = upcast { NullableDefinition.OfType = innerDef } + let Nullable(innerDef : #TypeDef<'Val>) : NullableDef<'Val> = + upcast { NullableDefinition.OfType = innerDef } + + /// Wraps a GraphQL type definition, allowing defining field/argument + /// to take collection of provided value. + let ListOf(innerDef : #TypeDef<'Val>) : ListOfDef<'Val, 'Seq> = + match box innerDef with + | :? (InputDef<'Val>) as d -> + upcast { + ListOfDefinition.OfType = innerDef + Decoder = + Decode.list d.Decoder + |> Decoder.map (fun xs -> box xs :?> 'Seq) // TODO: Bad idea? + } + | _ -> + upcast { + ListOfDefinition.OfType = innerDef + Decoder = + Decoder.fail (DecodeError.reason "Cannot create a decoder for a TypeDef definition") + } /// Wraps a GraphQL type definition, allowing defining field/argument /// to take collection of provided value. - let ListOf(innerDef : #TypeDef<'Val>) : ListOfDef<'Val, 'Seq> = upcast { ListOfDefinition.OfType = innerDef } + let InputListOf(innerDef : #InputDef<'Val>) : ListOfDef<'Val, 'Val list> = + upcast ({ + ListOfDefinition.OfType = innerDef + Decoder = Decode.list innerDef.Decoder + }) let private ignoreInputResolve (_ : unit) (input : 'T) = () @@ -2529,13 +2771,26 @@ module SchemaDefinitions = | Variable variableName -> Map.tryFind variableName variables |> Option.toObj | v -> other v + // let variableOrElse (decoder : Decoder<'t>) (variables : Map) : Decoder<'t> = + // (fun value -> + // match value with + // | Variable variableName -> + // result { + // let! variableValue = + // Map.tryFind variableName variables + // |> Result.requireSome (DecodeError.reason (sprintf "Missing variable %s" variableName)) + + // return! decoder variableValue + // } + // | v -> decoder v) + /// GraphQL type of int let Int : ScalarDefinition = { Name = "Int" Description = Some "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1." - CoerceInput = coerceIntInput + Decoder = Decode.intish CoerceValue = coerceIntValue } /// GraphQL type of long @@ -2544,14 +2799,14 @@ module SchemaDefinitions = Description = Some "The `Long` scalar type represents non-fractional signed whole numeric values. Long can represent values between -(2^63) and 2^63 - 1." - CoerceInput = coerceLongInput + Decoder = Decode.longish CoerceValue = coerceLongValue } /// GraphQL type of boolean let Boolean : ScalarDefinition = { Name = "Boolean" Description = Some "The `Boolean` scalar type represents `true` or `false`." - CoerceInput = coerceBoolInput + Decoder = Decode.boolish CoerceValue = coerceBoolValue } /// GraphQL type of float @@ -2560,7 +2815,7 @@ module SchemaDefinitions = Description = Some "The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point)." - CoerceInput = coerceFloatInput + Decoder = Decode.floatish CoerceValue = coerceFloatValue } /// GraphQL type of string @@ -2569,7 +2824,7 @@ module SchemaDefinitions = Description = Some "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text." - CoerceInput = coerceStringInput + Decoder = Decode.stringish CoerceValue = coerceStringValue } /// GraphQL type for custom identifier @@ -2578,15 +2833,15 @@ module SchemaDefinitions = Description = Some "The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID." - CoerceInput = coerceIdInput + Decoder = Decode.auto None CoerceValue = coerceIDValue } - let Obj : ScalarDefinition = { + let Obj decoder : ScalarDefinition = { Name = "Object" Description = Some "The `Object` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text." - CoerceInput = (fun (o: Value) -> Some (o:>obj)) + Decoder = decoder CoerceValue = (fun (o: obj) -> Some (o)) } @@ -2596,7 +2851,7 @@ module SchemaDefinitions = Description = Some "The `URI` scalar type represents a string resource identifier compatible with URI standard. The URI type appears in a JSON response as a String." - CoerceInput = coerceUriInput + Decoder = Decode.uri CoerceValue = coerceUriValue } /// GraphQL type for System.DateTime @@ -2605,7 +2860,8 @@ module SchemaDefinitions = Description = Some "The `Date` scalar type represents a Date value with Time component. The Date type appears in a JSON response as a String representation compatible with ISO-8601 format." - CoerceInput = coerceDateInput + // CoerceInput = coerceDateInput + Decoder = Decode.dateTime CoerceValue = coerceDateValue } /// GraphQL type for System.Guid @@ -2614,7 +2870,7 @@ module SchemaDefinitions = Description = Some "The `Guid` scalar type represents a Globaly Unique Identifier value. It's a 128-bit long byte key, that can be serialized to string." - CoerceInput = coerceGuidInput + Decoder = Decode.guid CoerceValue = coerceGuidValue } /// GraphQL @include directive. @@ -2632,7 +2888,9 @@ module SchemaDefinitions = ExecuteInput = variableOrElse (coerceBoolInput >> Option.map box - >> Option.toObj) } |] } + >> Option.toObj) + } + |] } /// GraphQL @skip directive. let SkipDirective : DirectiveDef = @@ -2648,7 +2906,8 @@ module SchemaDefinitions = ExecuteInput = variableOrElse (coerceBoolInput >> Option.map box - >> Option.toObj) } |] } + >> Option.toObj) + } |] } /// GraphQL @defer directive. let DeferDirective : DirectiveDef = @@ -2682,30 +2941,61 @@ module SchemaDefinitions = [] type Define = + [] + static member Scalar(name : string, + coerceInput : Value -> 'T option, + coerceValue : obj -> 'T option, ?description : string) : ScalarDefinition<'T> = + { Name = name + Description = description + Decoder = + (fun value -> + match coerceInput value with + | Some t -> Ok t + | None -> + let t = typeof<'T> + let message = sprintf "coerceInput failed for value %A and type %s" value (t.FullName) + Error (DecodeError.reason message)) + CoerceValue = coerceValue } + /// /// Creates GraphQL type definition for user defined scalars. /// /// Type name. Must be unique in scope of the current schema. - /// Function used to resolve .NET object from GraphQL query AST. + /// Function used to resolve .NET object from GraphQL query AST. /// Function used to cross cast to .NET types. /// Optional scalar description. Usefull for generating documentation. - static member Scalar(name : string, coerceInput : Value -> 'T option, + static member Scalar(name : string, decoder : Decoder<'T>, coerceValue : obj -> 'T option, ?description : string) : ScalarDefinition<'T> = { Name = name Description = description - CoerceInput = coerceInput + Decoder = decoder CoerceValue = coerceValue } + [] + static member Enum(name : string, options : EnumValue<'Val> list, ?description : string) : EnumDef<'Val> = + upcast + { + EnumDefinition.Name = name + Description = description + Options = options |> List.toArray + Decoder = Decode.auto None + } + /// /// Creates GraphQL type definition for user defined enums. /// /// Type name. Must be unique in scope of the current schema. /// List of enum value cases. + /// Function for decoding input values. /// Optional enum description. Usefull for generating documentation. - static member Enum(name : string, options : EnumValue<'Val> list, ?description : string) : EnumDef<'Val> = - upcast { EnumDefinition.Name = name - Description = description - Options = options |> List.toArray } + static member Enum(name : string, options : EnumValue<'Val> list, decoder : Decoder<'Val>, ?description : string) : EnumDef<'Val> = + upcast + { + EnumDefinition.Name = name + Description = description + Options = options |> List.toArray + Decoder = decoder + } /// /// Creates a single enum option to be used as argument in . @@ -2773,6 +3063,35 @@ module SchemaDefinitions = Implements = defaultArg (Option.map List.toArray interfaces) [||] IsTypeOf = isTypeOf } + [] + static member InputObject(name : string, fieldsFn : unit -> InputFieldDef list, ?description : string) : InputObjectDefinition<'Out> = + let decoder : Decoder<'Out> = + (fun value -> + // Here we use the decoders of the fields to customize the automatic decoder for the input object. + // This enables user-provided decoders in the fields to integrate into the automatic decoder! + let fieldDecoders = + fieldsFn () + |> Seq.map (fun inputFieldDef -> + let decoder = inputFieldDef.TypeDef.BoxedDecoder + + inputFieldDef.Name, decoder) + |> Map.ofSeq + + let settings = + AutoDecoderSettings.empty + |> AutoDecoderSettings.replaceMissingWithNull true + + let dec = Decode.autoRecordFromFields settings fieldDecoders + + dec value) + + Define.InputObject(name, fieldsFn, decoder, ?description = description) + + [] + static member InputObject(name : string, fields : InputFieldDef list, ?description : string) : InputObjectDefinition<'Out> = + let fieldsFn = fun () -> fields + Define.InputObject(name, fieldsFn, ?description = description) + /// /// Creates a custom GraphQL input object type. Unlike GraphQL objects, input objects are valid input types, /// that can be included in GraphQL query strings. Input object maps to a .NET type, which can be strandard @@ -2782,11 +3101,17 @@ module SchemaDefinitions = /// /// Function which generates a list of input fields defined by the current input object. Usefull, when object defines recursive dependencies. /// + /// Function for parsing GQL values into strongly-typed representation. /// Optional input object description. Usefull for generating documentation. - static member InputObject(name : string, fieldsFn : unit -> InputFieldDef list, ?description : string) : InputObjectDefinition<'Out> = - { Name = name + static member InputObject(name : string, fieldsFn : unit -> InputFieldDef list, decoder : Decoder<'Out>, ?description : string) : InputObjectDefinition<'Out> = + { + Name = name FieldsFn = fun () -> fieldsFn() |> List.toArray - Description = description } + Description = description + Decoder = + decoder + |> Decoder.mapError (DecodeError.nest (InInputObject name)) + } /// /// Creates a custom GraphQL input object type. Unlike GraphQL objects, input objects are valid input types, @@ -2795,11 +3120,10 @@ module SchemaDefinitions = /// /// Type name. Must be unique in scope of the current schema. /// List of input fields defined by the current input object. + /// Function for parsing GQL values into strongly-typed representation. /// Optional input object description. Usefull for generating documentation. - static member InputObject(name : string, fields : InputFieldDef list, ?description : string) : InputObjectDefinition<'Out> = - { Name = name - Description = description - FieldsFn = fun () -> fields |> List.toArray } + static member InputObject(name : string, fields : InputFieldDef list, decoder : Decoder<'Out>, ?description : string) : InputObjectDefinition<'Out> = + Define.InputObject(name, (fun () -> fields), decoder, ?description = description) /// /// Creates the top level subscription object that holds all of the possible subscriptions as fields. @@ -3017,7 +3341,7 @@ module SchemaDefinitions = static member CustomField(name : string, [] execField : Expr) : FieldDef<'Val> = upcast { FieldDefinition.Name = name Description = None - TypeDef = Obj + TypeDef = Obj (Decoder.fail (DecodeError.reason "TODO")) Resolve = ResolveExpr(execField) Args = [||] DeprecationReason = None @@ -3407,7 +3731,8 @@ module SchemaDefinitions = Description = description TypeDef = typedef DefaultValue = defaultValue - ExecuteInput = Unchecked.defaultof } + ExecuteInput = Unchecked.defaultof + } /// /// Creates a custom GraphQL interface type. It's needs to be implemented by object types and should not be used alone. @@ -3456,3 +3781,15 @@ module SchemaDefinitions = Options = options |> List.toArray ResolveType = resolveType ResolveValue = resolveValue } + +[] +module CompatabilityExtensions = + + type ScalarDef with + [] + member x.CoerceInput (value : Value) = + match x.BoxedDecoder value with + | Ok o -> Some o + | Error e -> + printfn "ScalarDef.CoerceInput FAILURE: %A" e + None diff --git a/src/FSharp.Data.GraphQL.Shared/Validation.fs b/src/FSharp.Data.GraphQL.Shared/Validation.fs index b0dfec196..deacae4f6 100644 --- a/src/FSharp.Data.GraphQL.Shared/Validation.fs +++ b/src/FSharp.Data.GraphQL.Shared/Validation.fs @@ -21,7 +21,8 @@ module Types = match Map.tryFind f.Name objectFields with | None -> (sprintf "'%s' field is defined by interface %s, but not implemented in object %s" f.Name idef.Name objdef.Name)::acc | Some objf when objf = f -> acc - | Some _ -> (sprintf "'%s.%s' field signature does not match it's definition in interface %s" objdef.Name f.Name idef.Name)::acc) [] + | Some _ -> + (sprintf "'%s.%s' field signature does not match it's definition in interface %s" objdef.Name f.Name idef.Name)::acc) [] match errors with | [] -> Success | err -> ValidationError err diff --git a/src/FSharp.Data.GraphQL.Shared/paket.references b/src/FSharp.Data.GraphQL.Shared/paket.references index 4d208e057..649103aac 100644 --- a/src/FSharp.Data.GraphQL.Shared/paket.references +++ b/src/FSharp.Data.GraphQL.Shared/paket.references @@ -1,3 +1,4 @@ group Common FSharp.Core -FParsec \ No newline at end of file +FParsec +FsToolkit.ErrorHandling diff --git a/tests/FSharp.Data.GraphQL.Tests/CoercionTests.fs b/tests/FSharp.Data.GraphQL.Tests/CoercionTests.fs index ecc1c9fe6..8bed6b41c 100644 --- a/tests/FSharp.Data.GraphQL.Tests/CoercionTests.fs +++ b/tests/FSharp.Data.GraphQL.Tests/CoercionTests.fs @@ -19,7 +19,6 @@ let private testCoercion graphQLType (expected: 't) actual = | Some x -> equals expected x | None -> raise (Exception(sprintf "Expected %A to be able to be coerced to %A" actual expected)) - [] let ``Int coerces input`` () = testCoercion Int 123 (IntValue 123L) diff --git a/tests/FSharp.Data.GraphQL.Tests/DecodingTests.fs b/tests/FSharp.Data.GraphQL.Tests/DecodingTests.fs new file mode 100644 index 000000000..4ebf8b28c --- /dev/null +++ b/tests/FSharp.Data.GraphQL.Tests/DecodingTests.fs @@ -0,0 +1,119 @@ +module FSharp.Data.GraphQL.Tests.DecodingTests + +open Xunit +open FSharp.Data.GraphQL.Ast +open FSharp.Data.GraphQL.Decoding + +type private FooBar = + { + Foo : int + Bar : string + } + +type private Qux = + { + Foo : string + Baz : string option + } + +let private checkDecoding decoder input expected = + let actual = decoder input + + // Give better error messages for decoding failures + match expected, actual with + | Ok x, Error error -> + equals (Some x, None) (None, Some error) + | _ -> () + + equals expected actual + +[] +let ``Decode.string works`` () = + checkDecoding Decode.string (StringValue "foo") (Ok "foo") + checkDecoding Decode.string (StringValue "abc") (Ok "abc") + checkDecoding Decode.string (StringValue "") (Ok "") + checkDecoding Decode.string (StringValue "1234") (Ok "1234") + +[] +let ``Decode.auto works for options`` () = + let dec : Decoder = Decode.auto None + + checkDecoding dec (StringValue "foo") (Ok (Some "foo")) + checkDecoding dec (StringValue "") (Ok (Some "")) + checkDecoding dec (StringValue "1234") (Ok (Some "1234")) + checkDecoding dec (NullValue) (Ok None) + +[] +let ``Decode.auto works for simple records`` () = + let dec : Decoder = Decode.auto None + + checkDecoding dec (ObjectValue (Map.ofList [ "Foo", IntValue 1L; "Bar", StringValue "abc" ])) (Ok { Foo = 1; Bar = "abc" }) + +[] +let ``Decode.auto works with customizations 1`` () = + let stringTwiceDecoder : Decoder = Decode.string |> Decoder.map (fun x -> x + x) + let intPlusOneDecoder : Decoder = Decode.int |> Decoder.map (fun x -> x + 1) + + let settings = + AutoDecoderSettings.empty + |> AutoDecoderSettings.customizeBoxed typeof (Decoder.box stringTwiceDecoder) + |> AutoDecoderSettings.customize intPlusOneDecoder + + let dec = Decode.autoWithSettings settings + + checkDecoding dec (ObjectValue (Map.ofList [ "Foo", IntValue 3L; "Bar", StringValue "abc" ])) (Ok { Foo = 4; Bar = "abcabc" }) + +[] +let ``Decode.auto works with customizations 2`` () = + let string : Decoder = Decode.auto None + let stringOption : Decoder = Decode.auto None + + let settings = + AutoDecoderSettings.empty + |> AutoDecoderSettings.customizeBoxed typeof (Decoder.box string) + |> AutoDecoderSettings.customizeBoxed typeof (Decoder.box stringOption) + + let dec : Decoder = Decode.autoWithSettings settings + + checkDecoding dec (ObjectValue (Map.ofList [ "Foo", StringValue "x"; "Baz", NullValue ])) (Ok { Foo = "x"; Baz = None }) + checkDecoding dec (ObjectValue (Map.ofList [ "Foo", StringValue "x"; "Baz", StringValue "y" ])) (Ok { Foo = "x"; Baz = Some "y" }) + +[] +let ``Decode.autoRecordFromFields works`` () = + let dec : Decoder = + Decode.autoRecordFromFields + ( + AutoDecoderSettings.empty + |> AutoDecoderSettings.casing DropCamelCase + ) + ( + Map.ofSeq [ + "Foo", Decoder.box Decode.int + "Bar", Decoder.box Decode.string + ] + ) + + checkDecoding dec (ObjectValue (Map.ofList [ "foo", IntValue 1L; "bar", StringValue "abc" ])) (Ok { Foo = 1; Bar = "abc" }) + +[] +let ``Decode.auto works for Option`` () = + let dec : Decoder> = Decode.auto None + + checkDecoding dec NullValue (Ok None) + checkDecoding dec (ListValue [ StringValue "abc"; StringValue "def" ]) (Ok (Some ("abc", "def"))) + +[] +let ``Decoder Computation Expression works`` () = + let dec = + decoder { + let! foo = Decode.field "foo" Decode.int + let! bar = Decode.field "bar" Decode.string + + return + { + Foo = foo + Bar = bar + } + } + + checkDecoding dec (ObjectValue (Map.ofList [ "foo", IntValue 123L; "bar", StringValue "hello" ])) (Ok { Foo = 123; Bar = "hello" }) diff --git a/tests/FSharp.Data.GraphQL.Tests/DeferredTests.fs b/tests/FSharp.Data.GraphQL.Tests/DeferredTests.fs index 51ace9094..86027333a 100644 --- a/tests/FSharp.Data.GraphQL.Tests/DeferredTests.fs +++ b/tests/FSharp.Data.GraphQL.Tests/DeferredTests.fs @@ -110,14 +110,20 @@ let InterfaceType = let CType = Define.Object( name ="C", - fields = [ Define.Field("id", String, (fun _ (c : C) -> c.id)); Define.Field("value", Nullable String, (fun _ c -> Some c.value)) ], + fields = [ + Define.Field("id", String, (fun _ (c : C) -> c.id)) + Define.Field("value", Nullable String, (fun _ c -> Some c.value)) + ], interfaces = [ InterfaceType ], isTypeOf = (fun o -> o :? C)) let DType = Define.Object( name = "D", - fields = [ Define.Field("id", String, (fun _ (d : D) -> d.id)); Define.Field("value", Nullable String, (fun _ d -> Some d.value)) ], + fields = [ + Define.Field("id", String, (fun _ (d : D) -> d.id)) + Define.Field("value", Nullable String, (fun _ d -> Some d.value)) + ], interfaces = [ InterfaceType ], isTypeOf = (fun o -> o :? D)) diff --git a/tests/FSharp.Data.GraphQL.Tests/FSharp.Data.GraphQL.Tests.fsproj b/tests/FSharp.Data.GraphQL.Tests/FSharp.Data.GraphQL.Tests.fsproj index 35991e465..cba9b6891 100644 --- a/tests/FSharp.Data.GraphQL.Tests/FSharp.Data.GraphQL.Tests.fsproj +++ b/tests/FSharp.Data.GraphQL.Tests/FSharp.Data.GraphQL.Tests.fsproj @@ -26,6 +26,7 @@ + diff --git a/tests/FSharp.Data.GraphQL.Tests/Relay/NodeTests.fs b/tests/FSharp.Data.GraphQL.Tests/Relay/NodeTests.fs index 7edd3e28c..23fac4b0a 100644 --- a/tests/FSharp.Data.GraphQL.Tests/Relay/NodeTests.fs +++ b/tests/FSharp.Data.GraphQL.Tests/Relay/NodeTests.fs @@ -7,6 +7,7 @@ module FSharp.Data.GraphQL.Tests.Relay.NodeTests open System open FSharp.Data.GraphQL +open FSharp.Data.GraphQL.Decoding open FSharp.Data.GraphQL.Types open FSharp.Data.GraphQL.Relay open FSharp.Data.GraphQL.Execution diff --git a/tests/FSharp.Data.GraphQL.Tests/VariablesTests.fs b/tests/FSharp.Data.GraphQL.Tests/VariablesTests.fs index cbaaa8496..a4b3851f7 100644 --- a/tests/FSharp.Data.GraphQL.Tests/VariablesTests.fs +++ b/tests/FSharp.Data.GraphQL.Tests/VariablesTests.fs @@ -25,6 +25,7 @@ type TestInput = { c: string d: string option } + let TestInputObject = Define.InputObject( name = "TestInputObject", @@ -39,6 +40,7 @@ type TestNestedInput = { na: TestInput option nb: string } + let TestNestedInputObject = Define.InputObject( name = "TestNestedInputObject", @@ -178,7 +180,7 @@ let ``Execute handles variables and errors on incorrect type`` () = }""" let params' : Map = Map.ofList ["input", upcast "foo bar"] let actual = sync <| Executor(schema).AsyncExecute(ast, variables = params') - let errMsg = sprintf " Variable '$input': value of type %O is not assignable from %O" typeof typeof + let errMsg = "Variable '$input': in input object 'TestInputObject': Expected an object but found StringValue \"foo bar\"" match actual with | Direct(data, errors) -> hasError errMsg errors @@ -283,7 +285,7 @@ let ``Execute handles non-nullable scalars and does not allow non-nullable input let actual = sync <| Executor(schema).AsyncExecute(ast, variables = Map.ofList [ "value", null ]) match actual with | Direct(data, errors) -> - hasError "Variable '$value': expected value of type String but got None" errors + hasError "Variable '$value': expected value of type String!, but no value was found" errors | _ -> fail "Expected Direct GQResponse" [] @@ -339,7 +341,7 @@ let ``Execute handles list inputs and nullability and allows lists to contain va let ast = parse """query q($input: [String]) { list(input: $input) }""" - let variables = Map.ofList [ "input", box [ "A" ] ] + let variables = Map.ofList [ "input", box [ "A" ] ] let actual = sync <| Executor(schema).AsyncExecute(ast, variables = variables) let expected = NameValueLookup.ofList [ "list", upcast "[\"A\"]" ] match actual with @@ -432,7 +434,7 @@ let ``Execute handles list inputs and nullability and does not allow lists of no let actual = sync <| Executor(schema).AsyncExecute(ast, variables = Map.ofList [ "input", [ "A":> obj; null; "B" :> obj ] :> obj ]) match actual with | Direct(data, errors) -> - hasError "Variable '$input': list element expected value of type String but got None" errors + hasError "Variable '$input': list element 1: expected value of type String but got None" errors | _ -> fail "Expected Direct GQResponse" [] @@ -467,7 +469,7 @@ let ``Execute handles list inputs and nullability and does not allow non-null li let actual = sync <| Executor(schema).AsyncExecute(ast, variables = Map.ofList [ "input", [ "A":> obj; null; "B" :> obj ] :> obj ]) match actual with | Direct(data, errors) -> - hasError "Variable '$input': list element expected value of type String but got None" errors + hasError "Variable '$input': list element 1: expected value of type String but got None" errors | _ -> fail "Expected Direct GQResponse" [] From 1320455b0889f505353ab5ff38a818267cfb0634 Mon Sep 17 00:00:00 2001 From: njlr Date: Wed, 6 Oct 2021 20:31:15 +0000 Subject: [PATCH 2/5] Update src/FSharp.Data.GraphQL.Shared/Decoding.fs Co-authored-by: Andrii Chebukin --- src/FSharp.Data.GraphQL.Shared/Decoding.fs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/FSharp.Data.GraphQL.Shared/Decoding.fs b/src/FSharp.Data.GraphQL.Shared/Decoding.fs index 7ef503399..0fe4d0e65 100644 --- a/src/FSharp.Data.GraphQL.Shared/Decoding.fs +++ b/src/FSharp.Data.GraphQL.Shared/Decoding.fs @@ -58,10 +58,7 @@ module DecodeError = } let nest (pathSegment : DecodePathSegment) (error : DecodeError) = - { - error with - Path = pathSegment :: error.Path - } + { error with Path = pathSegment :: error.Path } module Decoder = From 21ea96bdd2e621ac09c5197b655b595ebd52e49a Mon Sep 17 00:00:00 2001 From: njlr Date: Wed, 6 Oct 2021 20:31:23 +0000 Subject: [PATCH 3/5] Update src/FSharp.Data.GraphQL.Shared/Decoding.fs Co-authored-by: Andrii Chebukin --- src/FSharp.Data.GraphQL.Shared/Decoding.fs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/FSharp.Data.GraphQL.Shared/Decoding.fs b/src/FSharp.Data.GraphQL.Shared/Decoding.fs index 0fe4d0e65..c4cf5e93f 100644 --- a/src/FSharp.Data.GraphQL.Shared/Decoding.fs +++ b/src/FSharp.Data.GraphQL.Shared/Decoding.fs @@ -606,10 +606,7 @@ module Decode = module ComputationExpression = type DecoderBuilder() = - member this.Bind(m, f) = - Decoder.bind f m - - member this.Return(x) = - Decoder.succeed x + member this.Bind(m, f) = Decoder.bind f m + member this.Return(x) = Decoder.succeed x let decoder = DecoderBuilder() From 06d8e08e07e0be3c797019885ff35e384107b120 Mon Sep 17 00:00:00 2001 From: njlr Date: Wed, 6 Oct 2021 20:31:34 +0000 Subject: [PATCH 4/5] Update src/FSharp.Data.GraphQL.Shared/TypeSystem.fs Co-authored-by: Andrii Chebukin --- src/FSharp.Data.GraphQL.Shared/TypeSystem.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs b/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs index 03d95bda6..c854aba80 100644 --- a/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs +++ b/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs @@ -3110,7 +3110,7 @@ module SchemaDefinitions = Description = description Decoder = decoder - |> Decoder.mapError (DecodeError.nest (InInputObject name)) + |> Decoder.mapError (DecodeError.nest <| InInputObject name) } /// From 40306f0ec195c8a57c18483340b4ec39c66d299a Mon Sep 17 00:00:00 2001 From: njlr Date: Thu, 7 Oct 2021 19:15:36 +0100 Subject: [PATCH 5/5] * Updates star-wars to new API * Updates star-wars to new API * Updates star-wars to new API * Updates star-wars to new API * Updates star-wars to new API * Updates star-wars to new API * Updates star-wars to new API * Updates star-wars to new API --- paket.dependencies | 4 + paket.lock | 3 + samples/graphiql-client/package-lock.json | 2095 +++++++++-------- samples/graphiql-client/package.json | 1 - samples/star-wars-api/Deserialize.fs | 71 + ...rp.Data.GraphQL.Samples.StarWarsApi.fsproj | 1 + samples/star-wars-api/HttpHandlers.fs | 57 +- samples/star-wars-api/JsonConverters.fs | 20 +- samples/star-wars-api/Schema.fs | 3 +- samples/star-wars-api/WebSocketMessages.fs | 4 +- src/FSharp.Data.GraphQL.Shared/TypeSystem.fs | 10 +- 11 files changed, 1170 insertions(+), 1099 deletions(-) create mode 100644 samples/star-wars-api/Deserialize.fs diff --git a/paket.dependencies b/paket.dependencies index f9c88863c..f4dd5f028 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -1,10 +1,13 @@ source https://api.nuget.org/v3/index.json +generate_load_scripts: true + nuget NuGet.CommandLine group Common source https://api.nuget.org/v3/index.json frameworks: net5.0, netstandard2.0 + generate_load_scripts: true nuget System.Reactive @@ -27,6 +30,7 @@ group Common group TestsAndSamples source https://api.nuget.org/v3/index.json frameworks: net5.0, netstandard2.0 + generate_load_scripts: true nuget Microsoft.Extensions.Http 5 nuget System.Net.Http 4.3.4 diff --git a/paket.lock b/paket.lock index 321874bf0..224e5f285 100644 --- a/paket.lock +++ b/paket.lock @@ -1,8 +1,10 @@ +GENERATE-LOAD-SCRIPTS: ON NUGET remote: https://api.nuget.org/v3/index.json NuGet.CommandLine (5.8.1) GROUP Common +GENERATE-LOAD-SCRIPTS: ON RESTRICTION: || (== net50) (== netstandard2.0) NUGET remote: https://api.nuget.org/v3/index.json @@ -64,6 +66,7 @@ GITHUB src/ProvidedTypes.fs (377d56321ad062985ed5aa19f205c1c4f04ef328) src/ProvidedTypes.fsi (377d56321ad062985ed5aa19f205c1c4f04ef328) GROUP TestsAndSamples +GENERATE-LOAD-SCRIPTS: ON RESTRICTION: || (== net50) (== netstandard2.0) NUGET remote: https://api.nuget.org/v3/index.json diff --git a/samples/graphiql-client/package-lock.json b/samples/graphiql-client/package-lock.json index fc54a3ff9..2ec6b2935 100644 --- a/samples/graphiql-client/package-lock.json +++ b/samples/graphiql-client/package-lock.json @@ -10,7 +10,7 @@ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "dev": true, "requires": { - "mime-types": "2.1.21", + "mime-types": "~2.1.18", "negotiator": "0.6.1" } }, @@ -26,10 +26,10 @@ "integrity": "sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "align-text": { @@ -38,9 +38,9 @@ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" } }, "amdefine": { @@ -67,8 +67,8 @@ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" } }, "arr-diff": { @@ -77,7 +77,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.1.0" + "arr-flatten": "^1.0.1" } }, "arr-flatten": { @@ -127,7 +127,7 @@ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": "~2.1.0" } }, "assert": { @@ -216,26 +216,26 @@ "integrity": "sha1-VUp+jQxLyTmWeon0FldQ/jiHxSI=", "dev": true, "requires": { - "babel-core": "6.26.3", - "babel-polyfill": "6.26.0", - "babel-register": "6.26.0", - "babel-runtime": "5.8.38", - "bin-version-check": "2.1.0", + "babel-core": "^6.6.5", + "babel-polyfill": "^6.6.0", + "babel-register": "^6.6.5", + "babel-runtime": "^5.0.0", + "bin-version-check": "^2.1.0", "chalk": "1.1.1", - "chokidar": "1.7.0", - "commander": "2.19.0", - "convert-source-map": "1.6.0", - "fs-readdir-recursive": "0.1.2", - "glob": "5.0.15", - "lodash": "3.10.1", - "log-symbols": "1.0.2", - "output-file-sync": "1.1.2", - "path-exists": "1.0.0", - "path-is-absolute": "1.0.1", - "request": "2.88.0", - "slash": "1.0.0", - "source-map": "0.5.7", - "v8flags": "2.1.1" + "chokidar": "^1.0.0", + "commander": "^2.8.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^0.1.0", + "glob": "^5.0.5", + "lodash": "^3.2.0", + "log-symbols": "^1.0.2", + "output-file-sync": "^1.1.0", + "path-exists": "^1.0.0", + "path-is-absolute": "^1.0.0", + "request": "^2.65.0", + "slash": "^1.0.0", + "source-map": "^0.5.0", + "v8flags": "^2.0.10" } }, "babel-code-frame": { @@ -244,9 +244,9 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" }, "dependencies": { "chalk": { @@ -255,11 +255,11 @@ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "js-tokens": { @@ -276,25 +276,25 @@ "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-generator": "6.26.1", - "babel-helpers": "6.24.1", - "babel-messages": "6.23.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "convert-source-map": "1.6.0", - "debug": "2.6.9", - "json5": "0.5.1", - "lodash": "4.17.11", - "minimatch": "3.0.4", - "path-is-absolute": "1.0.1", - "private": "0.1.8", - "slash": "1.0.0", - "source-map": "0.5.7" + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" }, "dependencies": { "babel-runtime": { @@ -303,8 +303,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -327,11 +327,11 @@ "integrity": "sha1-AwZQr4zutOnQ702tuDA/YiNJ6X8=", "dev": true, "requires": { - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash.assign": "3.2.0", - "lodash.pick": "3.1.0" + "babel-traverse": "^6.0.20", + "babel-types": "^6.0.19", + "babylon": "^6.0.18", + "lodash.assign": "^3.2.0", + "lodash.pick": "^3.1.0" } }, "babel-generator": { @@ -340,14 +340,14 @@ "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "dev": true, "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.11", - "source-map": "0.5.7", - "trim-right": "1.0.1" + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" }, "dependencies": { "babel-runtime": { @@ -356,8 +356,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -380,9 +380,9 @@ "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "esutils": "2.0.2" + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "esutils": "^2.0.2" }, "dependencies": { "babel-runtime": { @@ -391,8 +391,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -409,10 +409,10 @@ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "dev": true, "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -421,8 +421,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -439,10 +439,10 @@ "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", "dev": true, "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.11" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" }, "dependencies": { "babel-runtime": { @@ -451,8 +451,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -475,11 +475,11 @@ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "dev": true, "requires": { - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -488,8 +488,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -506,8 +506,8 @@ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -516,8 +516,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -534,8 +534,8 @@ "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -544,8 +544,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -562,8 +562,8 @@ "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -572,8 +572,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -590,9 +590,9 @@ "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.11" + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" }, "dependencies": { "babel-runtime": { @@ -601,8 +601,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -625,12 +625,12 @@ "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", "dev": true, "requires": { - "babel-helper-optimise-call-expression": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -639,8 +639,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -657,8 +657,8 @@ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -667,8 +667,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -685,10 +685,10 @@ "integrity": "sha1-CzQRLVsHSKjc2/Uaz2+b1C1QuMo=", "dev": true, "requires": { - "find-cache-dir": "0.1.1", - "loader-utils": "0.2.17", - "mkdirp": "0.5.1", - "object-assign": "4.1.1" + "find-cache-dir": "^0.1.1", + "loader-utils": "^0.2.16", + "mkdirp": "^0.5.1", + "object-assign": "^4.0.1" } }, "babel-messages": { @@ -697,7 +697,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -706,8 +706,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -724,7 +724,7 @@ "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -733,8 +733,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -757,7 +757,7 @@ "integrity": "sha1-kKXOgdRQ88uhdttfdBKlxdgHJ8A=", "dev": true, "requires": { - "babel-runtime": "5.8.38" + "babel-runtime": "^5.0.0" } }, "babel-plugin-syntax-class-properties": { @@ -790,10 +790,10 @@ "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", "dev": true, "requires": { - "babel-helper-function-name": "6.24.1", - "babel-plugin-syntax-class-properties": "6.13.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -802,8 +802,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -820,7 +820,7 @@ "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -829,8 +829,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -847,7 +847,7 @@ "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -856,8 +856,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -874,11 +874,11 @@ "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.11" + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" }, "dependencies": { "babel-runtime": { @@ -887,8 +887,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -911,15 +911,15 @@ "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", "dev": true, "requires": { - "babel-helper-define-map": "6.26.0", - "babel-helper-function-name": "6.24.1", - "babel-helper-optimise-call-expression": "6.24.1", - "babel-helper-replace-supers": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -928,8 +928,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -946,8 +946,8 @@ "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -956,8 +956,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -974,7 +974,7 @@ "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -983,8 +983,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1001,8 +1001,8 @@ "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1011,8 +1011,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1029,7 +1029,7 @@ "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1038,8 +1038,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1056,9 +1056,9 @@ "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", "dev": true, "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1067,8 +1067,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1085,7 +1085,7 @@ "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1094,8 +1094,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1112,9 +1112,9 @@ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1123,8 +1123,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1141,10 +1141,10 @@ "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", "dev": true, "requires": { - "babel-plugin-transform-strict-mode": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-types": "6.26.0" + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" }, "dependencies": { "babel-runtime": { @@ -1153,8 +1153,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1171,9 +1171,9 @@ "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", "dev": true, "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1182,8 +1182,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1200,9 +1200,9 @@ "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1211,8 +1211,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1229,8 +1229,8 @@ "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", "dev": true, "requires": { - "babel-helper-replace-supers": "6.24.1", - "babel-runtime": "6.26.0" + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1239,8 +1239,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1257,12 +1257,12 @@ "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", "dev": true, "requires": { - "babel-helper-call-delegate": "6.24.1", - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1271,8 +1271,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1289,8 +1289,8 @@ "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1299,8 +1299,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1317,7 +1317,7 @@ "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1326,8 +1326,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1344,9 +1344,9 @@ "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "dev": true, "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1355,8 +1355,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1373,7 +1373,7 @@ "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1382,8 +1382,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1400,7 +1400,7 @@ "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1409,8 +1409,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1427,9 +1427,9 @@ "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", "dev": true, "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "regexpu-core": "2.0.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" }, "dependencies": { "babel-runtime": { @@ -1438,8 +1438,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1456,8 +1456,8 @@ "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", "dev": true, "requires": { - "babel-plugin-syntax-flow": "6.18.0", - "babel-runtime": "6.26.0" + "babel-plugin-syntax-flow": "^6.18.0", + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1466,8 +1466,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1484,8 +1484,8 @@ "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", "dev": true, "requires": { - "babel-plugin-syntax-object-rest-spread": "6.13.0", - "babel-runtime": "6.26.0" + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" }, "dependencies": { "babel-runtime": { @@ -1494,8 +1494,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1512,7 +1512,7 @@ "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1521,8 +1521,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1539,9 +1539,9 @@ "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", "dev": true, "requires": { - "babel-helper-builder-react-jsx": "6.26.0", - "babel-plugin-syntax-jsx": "6.18.0", - "babel-runtime": "6.26.0" + "babel-helper-builder-react-jsx": "^6.24.1", + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1550,8 +1550,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1568,8 +1568,8 @@ "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", "dev": true, "requires": { - "babel-plugin-syntax-jsx": "6.18.0", - "babel-runtime": "6.26.0" + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1578,8 +1578,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1596,8 +1596,8 @@ "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", "dev": true, "requires": { - "babel-plugin-syntax-jsx": "6.18.0", - "babel-runtime": "6.26.0" + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" }, "dependencies": { "babel-runtime": { @@ -1606,8 +1606,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1624,7 +1624,7 @@ "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", "dev": true, "requires": { - "regenerator-transform": "0.10.1" + "regenerator-transform": "^0.10.0" } }, "babel-plugin-transform-strict-mode": { @@ -1633,8 +1633,8 @@ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" }, "dependencies": { "babel-runtime": { @@ -1643,8 +1643,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1661,9 +1661,9 @@ "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "core-js": "2.5.7", - "regenerator-runtime": "0.10.5" + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" }, "dependencies": { "babel-runtime": { @@ -1672,8 +1672,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" }, "dependencies": { "regenerator-runtime": { @@ -1704,30 +1704,30 @@ "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.26.0", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-regenerator": "6.26.0" + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.24.1", + "babel-plugin-transform-es2015-classes": "^6.24.1", + "babel-plugin-transform-es2015-computed-properties": "^6.24.1", + "babel-plugin-transform-es2015-destructuring": "^6.22.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", + "babel-plugin-transform-es2015-for-of": "^6.22.0", + "babel-plugin-transform-es2015-function-name": "^6.24.1", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-umd": "^6.24.1", + "babel-plugin-transform-es2015-object-super": "^6.24.1", + "babel-plugin-transform-es2015-parameters": "^6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", + "babel-plugin-transform-regenerator": "^6.24.1" } }, "babel-preset-flow": { @@ -1736,7 +1736,7 @@ "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", "dev": true, "requires": { - "babel-plugin-transform-flow-strip-types": "6.22.0" + "babel-plugin-transform-flow-strip-types": "^6.22.0" } }, "babel-preset-react": { @@ -1745,12 +1745,12 @@ "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", "dev": true, "requires": { - "babel-plugin-syntax-jsx": "6.18.0", - "babel-plugin-transform-react-display-name": "6.25.0", - "babel-plugin-transform-react-jsx": "6.24.1", - "babel-plugin-transform-react-jsx-self": "6.22.0", - "babel-plugin-transform-react-jsx-source": "6.22.0", - "babel-preset-flow": "6.23.0" + "babel-plugin-syntax-jsx": "^6.3.13", + "babel-plugin-transform-react-display-name": "^6.23.0", + "babel-plugin-transform-react-jsx": "^6.24.1", + "babel-plugin-transform-react-jsx-self": "^6.22.0", + "babel-plugin-transform-react-jsx-source": "^6.22.0", + "babel-preset-flow": "^6.23.0" } }, "babel-register": { @@ -1759,13 +1759,13 @@ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "dev": true, "requires": { - "babel-core": "6.26.3", - "babel-runtime": "6.26.0", - "core-js": "2.5.7", - "home-or-tmp": "2.0.0", - "lodash": "4.17.11", - "mkdirp": "0.5.1", - "source-map-support": "0.4.18" + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" }, "dependencies": { "babel-runtime": { @@ -1774,8 +1774,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1798,7 +1798,7 @@ "integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=", "dev": true, "requires": { - "core-js": "1.2.7" + "core-js": "^1.0.0" } }, "babel-template": { @@ -1807,11 +1807,11 @@ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.11" + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" }, "dependencies": { "babel-runtime": { @@ -1820,8 +1820,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1844,15 +1844,15 @@ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.4", - "lodash": "4.17.11" + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" }, "dependencies": { "babel-runtime": { @@ -1861,8 +1861,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1885,10 +1885,10 @@ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.11", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" }, "dependencies": { "babel-runtime": { @@ -1897,8 +1897,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -1933,13 +1933,13 @@ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -1948,7 +1948,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -1957,7 +1957,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -1966,7 +1966,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -1975,9 +1975,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -2018,7 +2018,7 @@ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "big.js": { @@ -2033,7 +2033,7 @@ "integrity": "sha1-nrSY7m/Xb3q5p8FgQ2+JV5Q1144=", "dev": true, "requires": { - "find-versions": "1.2.1" + "find-versions": "^1.0.0" } }, "bin-version-check": { @@ -2042,10 +2042,10 @@ "integrity": "sha1-5OXfKQuQaffRETJAMe/BP90RpbA=", "dev": true, "requires": { - "bin-version": "1.0.4", - "minimist": "1.2.0", - "semver": "4.3.6", - "semver-truncate": "1.1.2" + "bin-version": "^1.0.0", + "minimist": "^1.1.0", + "semver": "^4.0.3", + "semver-truncate": "^1.0.0" }, "dependencies": { "minimist": { @@ -2069,15 +2069,15 @@ "dev": true, "requires": { "bytes": "3.0.0", - "content-type": "1.0.4", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", + "depd": "~1.1.2", + "http-errors": "~1.6.3", "iconv-lite": "0.4.23", - "on-finished": "2.3.0", + "on-finished": "~2.3.0", "qs": "6.5.2", "raw-body": "2.3.3", - "type-is": "1.6.16" + "type-is": "~1.6.16" }, "dependencies": { "iconv-lite": { @@ -2086,7 +2086,7 @@ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } } } @@ -2097,7 +2097,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -2107,9 +2107,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.3" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "browserify-aes": { @@ -2118,7 +2118,7 @@ "integrity": "sha1-BnFJtmjfMcS1hTPgLQHoBthgjiw=", "dev": true, "requires": { - "inherits": "2.0.3" + "inherits": "^2.0.1" } }, "browserify-zlib": { @@ -2127,7 +2127,7 @@ "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", "dev": true, "requires": { - "pako": "0.2.9" + "pako": "~0.2.0" } }, "buffer": { @@ -2136,9 +2136,9 @@ "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { - "base64-js": "1.3.0", - "ieee754": "1.1.12", - "isarray": "1.0.0" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, "builtin-modules": { @@ -2165,15 +2165,15 @@ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" }, "dependencies": { "isobject": { @@ -2196,8 +2196,8 @@ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" } }, "caseless": { @@ -2212,8 +2212,8 @@ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" } }, "chalk": { @@ -2222,11 +2222,11 @@ "integrity": "sha1-UJr7ZwZudJn36zU1x3RFdyri0Bk=", "dev": true, "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.1.0", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "chokidar": { @@ -2235,15 +2235,15 @@ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "anymatch": "1.3.2", - "async-each": "1.0.1", - "fsevents": "1.2.4", - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.2.1" + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" } }, "class-utils": { @@ -2252,10 +2252,10 @@ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -2264,7 +2264,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "isobject": { @@ -2281,8 +2281,8 @@ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", + "center-align": "^0.1.1", + "right-align": "^0.1.1", "wordwrap": "0.0.2" }, "dependencies": { @@ -2316,8 +2316,8 @@ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "colors": { @@ -2332,7 +2332,7 @@ "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", "dev": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "commander": { @@ -2353,15 +2353,15 @@ "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=", "dev": true, "requires": { - "commander": "2.19.0", - "detective": "4.7.1", - "glob": "5.0.15", - "graceful-fs": "4.1.15", - "iconv-lite": "0.4.24", - "mkdirp": "0.5.1", - "private": "0.1.8", - "q": "1.5.1", - "recast": "0.11.23" + "commander": "^2.5.0", + "detective": "^4.3.1", + "glob": "^5.0.15", + "graceful-fs": "^4.1.2", + "iconv-lite": "^0.4.5", + "mkdirp": "^0.5.0", + "private": "^0.1.6", + "q": "^1.1.2", + "recast": "^0.11.17" } }, "component-emitter": { @@ -2376,7 +2376,7 @@ "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", "dev": true, "requires": { - "mime-db": "1.37.0" + "mime-db": ">= 1.36.0 < 2" } }, "compression": { @@ -2385,13 +2385,13 @@ "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", "dev": true, "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.5", "bytes": "3.0.0", - "compressible": "2.0.15", + "compressible": "~2.0.14", "debug": "2.6.9", - "on-headers": "1.0.1", + "on-headers": "~1.0.1", "safe-buffer": "5.1.2", - "vary": "1.1.2" + "vary": "~1.1.2" } }, "concat-map": { @@ -2412,7 +2412,7 @@ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "dev": true, "requires": { - "date-now": "0.1.4" + "date-now": "^0.1.4" } }, "constants-browserify": { @@ -2439,7 +2439,7 @@ "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.1" } }, "cookie": { @@ -2482,9 +2482,9 @@ "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", "requires": { - "fbjs": "0.8.17", - "loose-envify": "1.4.0", - "object-assign": "4.1.1" + "fbjs": "^0.8.9", + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" } }, "crypto-browserify": { @@ -2505,7 +2505,7 @@ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { - "array-find-index": "1.0.2" + "array-find-index": "^1.0.1" } }, "dashdash": { @@ -2514,7 +2514,7 @@ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "date-now": { @@ -2550,8 +2550,8 @@ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -2560,7 +2560,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2569,7 +2569,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2578,9 +2578,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -2627,7 +2627,7 @@ "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "dev": true, "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "detective": { @@ -2636,8 +2636,8 @@ "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", "dev": true, "requires": { - "acorn": "5.7.3", - "defined": "1.0.0" + "acorn": "^5.2.1", + "defined": "^1.0.0" } }, "domain-browser": { @@ -2652,8 +2652,8 @@ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "requires": { - "jsbn": "0.1.1", - "safer-buffer": "2.1.2" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, "ecstatic": { @@ -2662,10 +2662,10 @@ "integrity": "sha1-Mst7b6LikNWGaGdNEV6PDD1WfWo=", "dev": true, "requires": { - "he": "0.5.0", - "mime": "1.6.0", - "minimist": "1.2.0", - "url-join": "1.1.0" + "he": "^0.5.0", + "mime": "^1.2.11", + "minimist": "^1.1.0", + "url-join": "^1.0.0" }, "dependencies": { "minimist": { @@ -2699,7 +2699,7 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "requires": { - "iconv-lite": "0.4.24" + "iconv-lite": "~0.4.13" } }, "enhanced-resolve": { @@ -2708,9 +2708,9 @@ "integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "memory-fs": "0.2.0", - "tapable": "0.1.10" + "graceful-fs": "^4.1.2", + "memory-fs": "^0.2.0", + "tapable": "^0.1.8" }, "dependencies": { "memory-fs": { @@ -2727,7 +2727,7 @@ "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", "dev": true, "requires": { - "prr": "1.0.1" + "prr": "~1.0.1" } }, "error-ex": { @@ -2736,7 +2736,7 @@ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { - "is-arrayish": "0.2.1" + "is-arrayish": "^0.2.1" } }, "escape-html": { @@ -2787,7 +2787,7 @@ "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", "dev": true, "requires": { - "original": "1.0.2" + "original": "^1.0.0" } }, "expand-brackets": { @@ -2796,7 +2796,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "expand-range": { @@ -2805,7 +2805,7 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "2.2.4" + "fill-range": "^2.1.0" } }, "express": { @@ -2814,36 +2814,36 @@ "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", "dev": true, "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.3", "content-disposition": "0.5.2", - "content-type": "1.0.4", + "content-type": "~1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.4", + "proxy-addr": "~2.0.4", "qs": "6.5.2", - "range-parser": "1.2.0", + "range-parser": "~1.2.0", "safe-buffer": "5.1.2", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", + "statuses": "~1.4.0", + "type-is": "~1.6.16", "utils-merge": "1.0.1", - "vary": "1.1.2" + "vary": "~1.1.2" } }, "extend": { @@ -2858,8 +2858,8 @@ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -2868,7 +2868,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -2879,7 +2879,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "extsprintf": { @@ -2906,7 +2906,7 @@ "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { - "websocket-driver": "0.7.0" + "websocket-driver": ">=0.5.1" } }, "fbjs": { @@ -2914,13 +2914,13 @@ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", "requires": { - "core-js": "1.2.7", - "isomorphic-fetch": "2.2.1", - "loose-envify": "1.4.0", - "object-assign": "4.1.1", - "promise": "7.3.1", - "setimmediate": "1.0.5", - "ua-parser-js": "0.7.19" + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" } }, "filename-regex": { @@ -2935,11 +2935,11 @@ "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "3.1.1", - "repeat-element": "1.1.3", - "repeat-string": "1.6.1" + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" } }, "finalhandler": { @@ -2949,12 +2949,12 @@ "dev": true, "requires": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" } }, "find-cache-dir": { @@ -2963,9 +2963,9 @@ "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", "dev": true, "requires": { - "commondir": "1.0.1", - "mkdirp": "0.5.1", - "pkg-dir": "1.0.0" + "commondir": "^1.0.1", + "mkdirp": "^0.5.1", + "pkg-dir": "^1.0.0" } }, "find-up": { @@ -2974,8 +2974,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" }, "dependencies": { "path-exists": { @@ -2984,7 +2984,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } } } @@ -2995,10 +2995,10 @@ "integrity": "sha1-y96fEuOFdaCvG+G5osXV/Y8Ya2I=", "dev": true, "requires": { - "array-uniq": "1.0.3", - "get-stdin": "4.0.1", - "meow": "3.7.0", - "semver-regex": "1.0.0" + "array-uniq": "^1.0.0", + "get-stdin": "^4.0.1", + "meow": "^3.5.0", + "semver-regex": "^1.0.0" } }, "follow-redirects": { @@ -3007,7 +3007,7 @@ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", "dev": true, "requires": { - "debug": "3.1.0" + "debug": "=3.1.0" }, "dependencies": { "debug": { @@ -3033,7 +3033,7 @@ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { - "for-in": "1.0.2" + "for-in": "^1.0.1" } }, "forever-agent": { @@ -3048,9 +3048,9 @@ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.7", - "mime-types": "2.1.21" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" } }, "forwarded": { @@ -3065,7 +3065,7 @@ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fresh": { @@ -3087,8 +3087,8 @@ "dev": true, "optional": true, "requires": { - "nan": "2.11.1", - "node-pre-gyp": "0.10.0" + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" }, "dependencies": { "abbrev": { @@ -3100,7 +3100,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -3121,12 +3122,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "1.0.0", "concat-map": "0.0.1" @@ -3141,17 +3144,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3268,7 +3274,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3280,6 +3287,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "1.0.1" } @@ -3294,6 +3302,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "1.1.11" } @@ -3301,12 +3310,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "5.1.1", "yallist": "3.0.2" @@ -3325,6 +3336,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3405,7 +3417,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3417,6 +3430,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1.0.2" } @@ -3502,7 +3516,8 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3538,6 +3553,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "1.1.0", "is-fullwidth-code-point": "1.0.0", @@ -3557,6 +3573,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "2.1.1" } @@ -3600,12 +3617,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -3627,7 +3646,7 @@ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "glob": { @@ -3636,11 +3655,11 @@ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "glob-base": { @@ -3649,8 +3668,8 @@ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" } }, "glob-parent": { @@ -3659,7 +3678,7 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "2.0.1" + "is-glob": "^2.0.0" } }, "globals": { @@ -3679,9 +3698,9 @@ "resolved": "http://registry.npmjs.org/graphiql/-/graphiql-0.7.8.tgz", "integrity": "sha1-uHZdVC/2w9UeZzJaJiwy38D0vss=", "requires": { - "codemirror": "5.42.0", - "codemirror-graphql": "0.5.9", - "marked": "0.3.19" + "codemirror": "^5.15.2", + "codemirror-graphql": "^0.5.7", + "marked": "^0.3.5" } }, "graphql": { @@ -3704,8 +3723,8 @@ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "dev": true, "requires": { - "ajv": "6.6.1", - "har-schema": "2.0.0" + "ajv": "^6.5.5", + "har-schema": "^2.0.0" } }, "has-ansi": { @@ -3714,7 +3733,7 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "has-flag": { @@ -3729,9 +3748,9 @@ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" }, "dependencies": { "isobject": { @@ -3748,8 +3767,8 @@ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "is-number": { @@ -3758,7 +3777,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -3767,7 +3786,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -3778,7 +3797,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -3795,8 +3814,8 @@ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "dev": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" } }, "hosted-git-info": { @@ -3811,10 +3830,10 @@ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { - "depd": "1.1.2", + "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", - "statuses": "1.4.0" + "statuses": ">= 1.4.0 < 2" } }, "http-parser-js": { @@ -3829,9 +3848,9 @@ "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "dev": true, "requires": { - "eventemitter3": "3.1.0", - "follow-redirects": "1.5.10", - "requires-port": "1.0.0" + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" } }, "http-proxy-middleware": { @@ -3840,10 +3859,10 @@ "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=", "dev": true, "requires": { - "http-proxy": "1.17.0", - "is-glob": "3.1.0", - "lodash": "4.17.11", - "micromatch": "2.3.11" + "http-proxy": "^1.16.2", + "is-glob": "^3.1.0", + "lodash": "^4.17.2", + "micromatch": "^2.3.11" }, "dependencies": { "is-extglob": { @@ -3858,7 +3877,7 @@ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } }, "lodash": { @@ -3876,13 +3895,13 @@ "dev": true, "requires": { "colors": "1.0.3", - "corser": "2.0.1", - "ecstatic": "1.4.1", - "http-proxy": "1.17.0", - "opener": "1.4.3", - "optimist": "0.6.1", - "portfinder": "0.4.0", - "union": "0.4.6" + "corser": "~2.0.0", + "ecstatic": "^1.4.0", + "http-proxy": "^1.8.1", + "opener": "~1.4.0", + "optimist": "0.6.x", + "portfinder": "0.4.x", + "union": "~0.4.3" } }, "http-signature": { @@ -3891,9 +3910,9 @@ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.15.2" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "https-browserify": { @@ -3907,7 +3926,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "ieee754": { @@ -3922,7 +3941,7 @@ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "indexof": { @@ -3937,8 +3956,8 @@ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -3959,7 +3978,7 @@ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { - "loose-envify": "1.4.0" + "loose-envify": "^1.0.0" } }, "ipaddr.js": { @@ -3974,7 +3993,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-arrayish": { @@ -3989,7 +4008,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.12.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -4004,7 +4023,7 @@ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { - "builtin-modules": "1.1.1" + "builtin-modules": "^1.0.0" } }, "is-data-descriptor": { @@ -4013,7 +4032,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-descriptor": { @@ -4022,9 +4041,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -4047,7 +4066,7 @@ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "2.0.0" + "is-primitive": "^2.0.0" } }, "is-extendable": { @@ -4068,7 +4087,7 @@ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-glob": { @@ -4077,7 +4096,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "is-number": { @@ -4086,7 +4105,7 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-plain-object": { @@ -4095,7 +4114,7 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -4161,8 +4180,8 @@ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "requires": { - "node-fetch": "1.7.3", - "whatwg-fetch": "3.0.0" + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" } }, "isstream": { @@ -4241,11 +4260,11 @@ "integrity": "sha1-CaeJk+CuTU70SH9hVakfYZDLQiM=", "dev": true, "requires": { - "base62": "1.2.8", - "commoner": "0.10.8", - "esprima-fb": "15001.1.0-dev-harmony-fb", - "object-assign": "2.1.1", - "source-map": "0.4.4" + "base62": "^1.1.0", + "commoner": "^0.10.1", + "esprima-fb": "^15001.1.0-dev-harmony-fb", + "object-assign": "^2.0.0", + "source-map": "^0.4.2" }, "dependencies": { "object-assign": { @@ -4260,7 +4279,7 @@ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } @@ -4271,8 +4290,8 @@ "integrity": "sha1-l2f2Q5dcePXlq+upvFeIUpfnMtQ=", "dev": true, "requires": { - "jstransform": "11.0.3", - "loader-utils": "0.2.17" + "jstransform": "11", + "loader-utils": "^0.2.2" } }, "kind-of": { @@ -4281,7 +4300,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "lazy-cache": { @@ -4296,11 +4315,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" } }, "loader-utils": { @@ -4309,10 +4328,10 @@ "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", "dev": true, "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" } }, "lodash": { @@ -4327,8 +4346,8 @@ "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", "dev": true, "requires": { - "lodash._basecopy": "3.0.1", - "lodash.keys": "3.1.2" + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" } }, "lodash._basecopy": { @@ -4343,8 +4362,8 @@ "integrity": "sha1-B3D/gBMa9uNPO1EXlqe6UhTmX/c=", "dev": true, "requires": { - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" } }, "lodash._basefor": { @@ -4365,9 +4384,9 @@ "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=", "dev": true, "requires": { - "lodash._bindcallback": "3.0.1", - "lodash._isiterateecall": "3.0.9", - "lodash.restparam": "3.6.1" + "lodash._bindcallback": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash.restparam": "^3.0.0" } }, "lodash._getnative": { @@ -4394,8 +4413,8 @@ "integrity": "sha1-/2G5oBens699MObFPeKK+hm4dQo=", "dev": true, "requires": { - "lodash._basefor": "3.0.3", - "lodash.keysin": "3.0.8" + "lodash._basefor": "^3.0.0", + "lodash.keysin": "^3.0.0" } }, "lodash.assign": { @@ -4404,9 +4423,9 @@ "integrity": "sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=", "dev": true, "requires": { - "lodash._baseassign": "3.2.0", - "lodash._createassigner": "3.1.1", - "lodash.keys": "3.1.2" + "lodash._baseassign": "^3.0.0", + "lodash._createassigner": "^3.0.0", + "lodash.keys": "^3.0.0" } }, "lodash.isarguments": { @@ -4427,9 +4446,9 @@ "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", "dev": true, "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" } }, "lodash.keysin": { @@ -4438,8 +4457,8 @@ "integrity": "sha1-IsRJPrvtsUJ5YqVLRFssinZ/tH8=", "dev": true, "requires": { - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" } }, "lodash.pick": { @@ -4448,11 +4467,11 @@ "integrity": "sha1-8lKoVbIEa2G805BLJvdr0u/GVVA=", "dev": true, "requires": { - "lodash._baseflatten": "3.1.4", - "lodash._bindcallback": "3.0.1", - "lodash._pickbyarray": "3.0.2", - "lodash._pickbycallback": "3.0.0", - "lodash.restparam": "3.6.1" + "lodash._baseflatten": "^3.0.0", + "lodash._bindcallback": "^3.0.0", + "lodash._pickbyarray": "^3.0.0", + "lodash._pickbycallback": "^3.0.0", + "lodash.restparam": "^3.0.0" } }, "lodash.restparam": { @@ -4467,7 +4486,7 @@ "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", "dev": true, "requires": { - "chalk": "1.1.1" + "chalk": "^1.0.0" } }, "longest": { @@ -4481,7 +4500,7 @@ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "requires": { - "js-tokens": "4.0.0" + "js-tokens": "^3.0.0 || ^4.0.0" } }, "loud-rejection": { @@ -4490,8 +4509,8 @@ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" } }, "map-cache": { @@ -4512,7 +4531,7 @@ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "marked": { @@ -4538,8 +4557,8 @@ "integrity": "sha1-e8xrYp46Q+hx1+Kaymrop/FcuyA=", "dev": true, "requires": { - "errno": "0.1.7", - "readable-stream": "2.3.6" + "errno": "^0.1.3", + "readable-stream": "^2.0.1" } }, "meow": { @@ -4548,16 +4567,16 @@ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { - "camelcase-keys": "2.1.0", - "decamelize": "1.2.0", - "loud-rejection": "1.6.0", - "map-obj": "1.0.1", - "minimist": "1.2.0", - "normalize-package-data": "2.4.0", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" }, "dependencies": { "minimist": { @@ -4586,19 +4605,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } }, "mime": { @@ -4619,7 +4638,7 @@ "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "dev": true, "requires": { - "mime-db": "1.37.0" + "mime-db": "~1.37.0" } }, "minimatch": { @@ -4628,7 +4647,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -4643,8 +4662,8 @@ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "dev": true, "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -4653,7 +4672,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -4686,17 +4705,17 @@ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "arr-diff": { @@ -4730,8 +4749,8 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", "requires": { - "encoding": "0.1.12", - "is-stream": "1.1.0" + "encoding": "^0.1.11", + "is-stream": "^1.0.1" } }, "node-libs-browser": { @@ -4740,28 +4759,28 @@ "integrity": "sha1-PicsCBnjCJNeJmdECNevDhSRuDs=", "dev": true, "requires": { - "assert": "1.4.1", - "browserify-zlib": "0.1.4", - "buffer": "4.9.1", - "console-browserify": "1.1.0", - "constants-browserify": "1.0.0", + "assert": "^1.1.1", + "browserify-zlib": "^0.1.4", + "buffer": "^4.9.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", "crypto-browserify": "3.3.0", - "domain-browser": "1.2.0", - "events": "1.1.1", + "domain-browser": "^1.1.1", + "events": "^1.0.0", "https-browserify": "0.0.1", - "os-browserify": "0.2.1", + "os-browserify": "^0.2.0", "path-browserify": "0.0.0", - "process": "0.11.10", - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "readable-stream": "2.3.6", - "stream-browserify": "2.0.1", - "stream-http": "2.8.3", - "string_decoder": "0.10.31", - "timers-browserify": "2.0.10", + "process": "^0.11.0", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.0.5", + "stream-browserify": "^2.0.1", + "stream-http": "^2.3.1", + "string_decoder": "^0.10.25", + "timers-browserify": "^2.0.2", "tty-browserify": "0.0.0", - "url": "0.11.0", - "util": "0.10.4", + "url": "^0.11.0", + "util": "^0.10.3", "vm-browserify": "0.0.4" }, "dependencies": { @@ -4785,10 +4804,10 @@ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { - "hosted-git-info": "2.7.1", - "is-builtin-module": "1.0.0", - "semver": "4.3.6", - "validate-npm-package-license": "3.0.4" + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, "normalize-path": { @@ -4797,7 +4816,7 @@ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "1.1.0" + "remove-trailing-separator": "^1.0.1" } }, "number-is-nan": { @@ -4823,9 +4842,9 @@ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -4834,7 +4853,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -4845,7 +4864,7 @@ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" }, "dependencies": { "isobject": { @@ -4862,8 +4881,8 @@ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" } }, "object.pick": { @@ -4872,7 +4891,7 @@ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -4904,7 +4923,7 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "open": { @@ -4925,8 +4944,8 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" } }, "original": { @@ -4935,7 +4954,7 @@ "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", "dev": true, "requires": { - "url-parse": "1.4.4" + "url-parse": "^1.4.3" } }, "os-browserify": { @@ -4962,9 +4981,9 @@ "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "mkdirp": "0.5.1", - "object-assign": "4.1.1" + "graceful-fs": "^4.1.4", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.0" } }, "pako": { @@ -4979,10 +4998,10 @@ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" } }, "parse-json": { @@ -4991,7 +5010,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "1.3.2" + "error-ex": "^1.2.0" } }, "parseurl": { @@ -5036,9 +5055,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "pbkdf2-compat": { @@ -5071,7 +5090,7 @@ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" } }, "pkg-dir": { @@ -5080,7 +5099,7 @@ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", "dev": true, "requires": { - "find-up": "1.1.2" + "find-up": "^1.0.0" } }, "portfinder": { @@ -5090,7 +5109,7 @@ "dev": true, "requires": { "async": "0.9.0", - "mkdirp": "0.5.1" + "mkdirp": "0.5.x" } }, "posix-character-classes": { @@ -5128,7 +5147,7 @@ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "requires": { - "asap": "2.0.6" + "asap": "~2.0.3" } }, "prop-types": { @@ -5136,8 +5155,8 @@ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", "requires": { - "loose-envify": "1.4.0", - "object-assign": "4.1.1" + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" } }, "proxy-addr": { @@ -5146,7 +5165,7 @@ "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", "dev": true, "requires": { - "forwarded": "0.1.2", + "forwarded": "~0.1.2", "ipaddr.js": "1.8.0" } }, @@ -5204,9 +5223,9 @@ "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", "dev": true, "requires": { - "is-number": "4.0.0", - "kind-of": "6.0.2", - "math-random": "1.0.1" + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" }, "dependencies": { "is-number": { @@ -5247,7 +5266,7 @@ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } } } @@ -5257,11 +5276,11 @@ "resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz", "integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=", "requires": { - "create-react-class": "15.6.3", - "fbjs": "0.8.17", - "loose-envify": "1.4.0", - "object-assign": "4.1.1", - "prop-types": "15.6.2" + "create-react-class": "^15.6.0", + "fbjs": "^0.8.9", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.0", + "prop-types": "^15.5.10" } }, "react-dom": { @@ -5269,10 +5288,10 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.2.tgz", "integrity": "sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=", "requires": { - "fbjs": "0.8.17", - "loose-envify": "1.4.0", - "object-assign": "4.1.1", - "prop-types": "15.6.2" + "fbjs": "^0.8.9", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.0", + "prop-types": "^15.5.10" } }, "read-pkg": { @@ -5281,9 +5300,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } }, "read-pkg-up": { @@ -5292,8 +5311,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" } }, "readable-stream": { @@ -5302,13 +5321,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -5317,9 +5336,9 @@ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "micromatch": "3.1.10", - "readable-stream": "2.3.6" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" }, "dependencies": { "arr-diff": { @@ -5340,16 +5359,16 @@ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -5358,7 +5377,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -5369,13 +5388,13 @@ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -5384,7 +5403,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -5393,7 +5412,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -5402,7 +5421,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -5411,7 +5430,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -5422,7 +5441,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -5431,7 +5450,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -5442,9 +5461,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" } }, "kind-of": { @@ -5461,14 +5480,14 @@ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -5477,7 +5496,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -5486,7 +5505,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -5497,10 +5516,10 @@ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -5509,7 +5528,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -5520,7 +5539,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -5529,7 +5548,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -5538,9 +5557,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "is-number": { @@ -5549,7 +5568,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -5558,7 +5577,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -5581,19 +5600,19 @@ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } } } @@ -5605,9 +5624,9 @@ "dev": true, "requires": { "ast-types": "0.9.6", - "esprima": "3.1.3", - "private": "0.1.8", - "source-map": "0.5.7" + "esprima": "~3.1.0", + "private": "~0.1.5", + "source-map": "~0.5.0" }, "dependencies": { "esprima": { @@ -5624,8 +5643,8 @@ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" } }, "regenerate": { @@ -5646,9 +5665,9 @@ "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "private": "0.1.8" + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" }, "dependencies": { "babel-runtime": { @@ -5657,8 +5676,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "core-js": { @@ -5675,7 +5694,7 @@ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { - "is-equal-shallow": "0.1.3" + "is-equal-shallow": "^0.1.3" } }, "regex-not": { @@ -5684,8 +5703,8 @@ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "regexpu-core": { @@ -5694,9 +5713,9 @@ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "dev": true, "requires": { - "regenerate": "1.4.0", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" } }, "regjsgen": { @@ -5711,7 +5730,7 @@ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" }, "dependencies": { "jsesc": { @@ -5746,7 +5765,7 @@ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "is-finite": "1.0.2" + "is-finite": "^1.0.0" } }, "request": { @@ -5755,26 +5774,26 @@ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "dev": true, "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.8.0", - "caseless": "0.12.0", - "combined-stream": "1.0.7", - "extend": "3.0.2", - "forever-agent": "0.6.1", - "form-data": "2.3.3", - "har-validator": "5.1.3", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.21", - "oauth-sign": "0.9.0", - "performance-now": "2.1.0", - "qs": "6.5.2", - "safe-buffer": "5.1.2", - "tough-cookie": "2.4.3", - "tunnel-agent": "0.6.0", - "uuid": "3.3.2" + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" } }, "requires-port": { @@ -5801,7 +5820,7 @@ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, "requires": { - "align-text": "0.1.4" + "align-text": "^0.1.1" } }, "ripemd160": { @@ -5822,7 +5841,7 @@ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "safer-buffer": { @@ -5848,7 +5867,7 @@ "integrity": "sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=", "dev": true, "requires": { - "semver": "5.6.0" + "semver": "^5.3.0" }, "dependencies": { "semver": { @@ -5866,18 +5885,18 @@ "dev": true, "requires": { "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.3", + "http-errors": "~1.6.2", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" }, "dependencies": { "mime": { @@ -5894,13 +5913,13 @@ "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", "dev": true, "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.4", "batch": "0.6.1", "debug": "2.6.9", - "escape-html": "1.0.3", - "http-errors": "1.6.3", - "mime-types": "2.1.21", - "parseurl": "1.3.2" + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" } }, "serve-static": { @@ -5909,9 +5928,9 @@ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "dev": true, "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", "send": "0.16.2" } }, @@ -5921,10 +5940,10 @@ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -5933,7 +5952,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -5973,14 +5992,14 @@ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.2", - "use": "3.1.1" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { "define-property": { @@ -5989,7 +6008,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -5998,7 +6017,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -6009,9 +6028,9 @@ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -6020,7 +6039,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -6029,7 +6048,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -6038,7 +6057,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -6047,9 +6066,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -6072,7 +6091,7 @@ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" } }, "sockjs": { @@ -6081,8 +6100,8 @@ "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", "dev": true, "requires": { - "faye-websocket": "0.10.0", - "uuid": "3.3.2" + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" } }, "sockjs-client": { @@ -6091,12 +6110,12 @@ "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", "dev": true, "requires": { - "debug": "3.2.6", - "eventsource": "1.0.7", - "faye-websocket": "0.11.1", - "inherits": "2.0.3", - "json3": "3.3.2", - "url-parse": "1.4.4" + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" }, "dependencies": { "debug": { @@ -6105,7 +6124,7 @@ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "faye-websocket": { @@ -6114,7 +6133,7 @@ "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", "dev": true, "requires": { - "websocket-driver": "0.7.0" + "websocket-driver": ">=0.5.1" } }, "ms": { @@ -6143,11 +6162,11 @@ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "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" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-support": { @@ -6156,7 +6175,7 @@ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, "requires": { - "source-map": "0.5.7" + "source-map": "^0.5.6" } }, "source-map-url": { @@ -6171,8 +6190,8 @@ "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", "dev": true, "requires": { - "spdx-expression-parse": "3.0.0", - "spdx-license-ids": "3.0.2" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { @@ -6187,8 +6206,8 @@ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "requires": { - "spdx-exceptions": "2.2.0", - "spdx-license-ids": "3.0.2" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { @@ -6203,7 +6222,7 @@ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "sshpk": { @@ -6212,15 +6231,15 @@ "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", "dev": true, "requires": { - "asn1": "0.2.4", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.2", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.2", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "safer-buffer": "2.1.2", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" } }, "static-extend": { @@ -6229,8 +6248,8 @@ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -6239,7 +6258,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -6256,8 +6275,8 @@ "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "dev": true, "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.6" + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" } }, "stream-cache": { @@ -6272,11 +6291,11 @@ "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", "dev": true, "requires": { - "builtin-status-codes": "3.0.0", - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "to-arraybuffer": "1.0.1", - "xtend": "4.0.1" + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" } }, "string_decoder": { @@ -6285,7 +6304,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -6294,7 +6313,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -6303,7 +6322,7 @@ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } }, "strip-indent": { @@ -6312,7 +6331,7 @@ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { - "get-stdin": "4.0.1" + "get-stdin": "^4.0.1" } }, "supports-color": { @@ -6339,7 +6358,7 @@ "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", "dev": true, "requires": { - "setimmediate": "1.0.5" + "setimmediate": "^1.0.4" } }, "to-arraybuffer": { @@ -6360,7 +6379,7 @@ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "to-regex": { @@ -6369,10 +6388,10 @@ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -6381,8 +6400,8 @@ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" }, "dependencies": { "is-number": { @@ -6391,7 +6410,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } } } @@ -6402,8 +6421,8 @@ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "dev": true, "requires": { - "psl": "1.1.29", - "punycode": "1.4.1" + "psl": "^1.1.24", + "punycode": "^1.4.1" }, "dependencies": { "punycode": { @@ -6438,7 +6457,7 @@ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -6454,7 +6473,7 @@ "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.21" + "mime-types": "~2.1.18" } }, "ua-parser-js": { @@ -6468,10 +6487,10 @@ "integrity": "sha1-RhLAx7qu4rp8SH3kkErhIgefLKg=", "dev": true, "requires": { - "async": "0.2.10", - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" + "async": "~0.2.6", + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" }, "dependencies": { "async": { @@ -6494,7 +6513,7 @@ "integrity": "sha1-GY+9rrolTniLDvy2MLwR8kopWeA=", "dev": true, "requires": { - "qs": "2.3.3" + "qs": "~2.3.3" }, "dependencies": { "qs": { @@ -6511,10 +6530,10 @@ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" }, "dependencies": { "extend-shallow": { @@ -6523,7 +6542,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "set-value": { @@ -6532,10 +6551,10 @@ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" } } } @@ -6552,8 +6571,8 @@ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -6562,9 +6581,9 @@ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -6598,7 +6617,7 @@ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { - "punycode": "2.1.1" + "punycode": "^2.1.0" } }, "urix": { @@ -6637,8 +6656,8 @@ "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", "dev": true, "requires": { - "querystringify": "2.1.0", - "requires-port": "1.0.0" + "querystringify": "^2.0.0", + "requires-port": "^1.0.0" } }, "use": { @@ -6686,7 +6705,7 @@ "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", "dev": true, "requires": { - "user-home": "1.1.1" + "user-home": "^1.1.1" } }, "validate-npm-package-license": { @@ -6695,8 +6714,8 @@ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "requires": { - "spdx-correct": "3.0.2", - "spdx-expression-parse": "3.0.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, "vary": { @@ -6711,9 +6730,9 @@ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" } }, "vm-browserify": { @@ -6731,9 +6750,9 @@ "integrity": "sha1-Yuqkq15bo1/fwBgnVibjwPXj+ws=", "dev": true, "requires": { - "async": "0.9.0", - "chokidar": "1.7.0", - "graceful-fs": "4.1.15" + "async": "^0.9.0", + "chokidar": "^1.0.0", + "graceful-fs": "^4.1.2" } }, "webpack": { @@ -6742,21 +6761,21 @@ "integrity": "sha1-T/MfU9sDM55VFkqdRo7gMklo/pg=", "dev": true, "requires": { - "acorn": "3.3.0", - "async": "1.5.2", - "clone": "1.0.4", - "enhanced-resolve": "0.9.1", - "interpret": "0.6.6", - "loader-utils": "0.2.17", - "memory-fs": "0.3.0", - "mkdirp": "0.5.1", - "node-libs-browser": "0.7.0", - "optimist": "0.6.1", - "supports-color": "3.2.3", - "tapable": "0.1.10", - "uglify-js": "2.7.5", - "watchpack": "0.2.9", - "webpack-core": "0.6.9" + "acorn": "^3.0.0", + "async": "^1.3.0", + "clone": "^1.0.2", + "enhanced-resolve": "~0.9.0", + "interpret": "^0.6.4", + "loader-utils": "^0.2.11", + "memory-fs": "~0.3.0", + "mkdirp": "~0.5.0", + "node-libs-browser": "^0.7.0", + "optimist": "~0.6.0", + "supports-color": "^3.1.0", + "tapable": "~0.1.8", + "uglify-js": "~2.7.3", + "watchpack": "^0.2.1", + "webpack-core": "~0.6.9" }, "dependencies": { "acorn": { @@ -6777,7 +6796,7 @@ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "has-flag": "1.0.0" + "has-flag": "^1.0.0" } } } @@ -6788,8 +6807,8 @@ "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", "dev": true, "requires": { - "source-list-map": "0.1.8", - "source-map": "0.4.4" + "source-list-map": "~0.1.7", + "source-map": "~0.4.1" }, "dependencies": { "source-map": { @@ -6798,7 +6817,7 @@ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } @@ -6809,11 +6828,11 @@ "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==", "dev": true, "requires": { - "memory-fs": "0.4.1", - "mime": "1.6.0", - "path-is-absolute": "1.0.1", - "range-parser": "1.2.0", - "time-stamp": "2.2.0" + "memory-fs": "~0.4.1", + "mime": "^1.5.0", + "path-is-absolute": "^1.0.0", + "range-parser": "^1.0.3", + "time-stamp": "^2.0.0" }, "dependencies": { "memory-fs": { @@ -6822,8 +6841,8 @@ "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "dev": true, "requires": { - "errno": "0.1.7", - "readable-stream": "2.3.6" + "errno": "^0.1.3", + "readable-stream": "^2.0.1" } } } @@ -6834,19 +6853,19 @@ "integrity": "sha1-DL1fLSrI1OWTqs1clwLnu9XlmJI=", "dev": true, "requires": { - "compression": "1.7.3", - "connect-history-api-fallback": "1.5.0", - "express": "4.16.4", - "http-proxy-middleware": "0.17.4", + "compression": "^1.5.2", + "connect-history-api-fallback": "^1.3.0", + "express": "^4.13.3", + "http-proxy-middleware": "~0.17.1", "open": "0.0.5", - "optimist": "0.6.1", - "serve-index": "1.9.1", - "sockjs": "0.3.19", - "sockjs-client": "1.3.0", - "stream-cache": "0.0.2", - "strip-ansi": "3.0.1", - "supports-color": "3.2.3", - "webpack-dev-middleware": "1.12.2" + "optimist": "~0.6.1", + "serve-index": "^1.7.2", + "sockjs": "^0.3.15", + "sockjs-client": "^1.0.3", + "stream-cache": "~0.0.1", + "strip-ansi": "^3.0.0", + "supports-color": "^3.1.1", + "webpack-dev-middleware": "^1.10.2" }, "dependencies": { "supports-color": { @@ -6855,7 +6874,7 @@ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "has-flag": "1.0.0" + "has-flag": "^1.0.0" } } } @@ -6866,8 +6885,8 @@ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", "dev": true, "requires": { - "http-parser-js": "0.5.0", - "websocket-extensions": "0.1.3" + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" } }, "websocket-extensions": { @@ -6911,9 +6930,9 @@ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", "window-size": "0.1.0" }, "dependencies": { diff --git a/samples/graphiql-client/package.json b/samples/graphiql-client/package.json index 924784a6b..d1b6c6150 100644 --- a/samples/graphiql-client/package.json +++ b/samples/graphiql-client/package.json @@ -5,7 +5,6 @@ "main": "index.js", "scripts": { "start": "npm run serve | npm run dev", - "fsi-start": "'C:\\Program Files (x86)\\Microsoft SDKs\\F#\\4.0\\Framework\\v4.0\\Fsi.exe' server.fsx", "open": "start http://localhost:8090/", "serve": "./node_modules/.bin/http-server -p 8080", "dev": "webpack-dev-server --progress --colors --port 8090" diff --git a/samples/star-wars-api/Deserialize.fs b/samples/star-wars-api/Deserialize.fs new file mode 100644 index 000000000..0704a9423 --- /dev/null +++ b/samples/star-wars-api/Deserialize.fs @@ -0,0 +1,71 @@ +module FSharp.Data.GraphQL.Samples.StarWarsApi.Deserialize + +open System +open Newtonsoft.Json.Linq +open FSharp.Data.GraphQL.Ast + +let rec jTokenToAstValue (j : JToken) = + match j.Type with + | JTokenType.Null -> NullValue + | JTokenType.Boolean -> BooleanValue (j.ToObject()) + | JTokenType.Integer -> IntValue (j.ToObject() |> int64) + | JTokenType.Float -> FloatValue (j.ToObject()) + | JTokenType.String -> StringValue (j.ToObject()) + | JTokenType.Guid -> StringValue (j.ToObject().ToString()) + | JTokenType.Uri -> StringValue (j.ToObject().OriginalString) + | JTokenType.Date -> StringValue (j.ToObject().ToString("o")) + | JTokenType.Array -> + j + |> Seq.map jTokenToAstValue + |> Seq.toList + |> ListValue + | JTokenType.Object -> + (j :?> JObject).Properties() + |> Seq.map (fun prop -> + prop.Name, jTokenToAstValue prop.Value) + |> Map.ofSeq + |> ObjectValue + | _ -> failwithf "Unsupported JToken.Type %A for %A" j.Type j + +let deserializeQueryAndVariables (data : string) = + if String.IsNullOrWhiteSpace(data) + then + None + else + let j = JObject.Parse data + + printfn "%A" data + printfn "%A" (Seq.toList j) + + let query = + try + j.Property("query").ToObject() + with _ -> + failwith "Failure deserializing response. Could not read query - it is not stringified in request." + + printfn "query = %A" query + + let variables = + match j.TryGetValue("variables") with + | (true, v) -> + let variablesString = v.ToObject() + + if String.IsNullOrWhiteSpace variablesString + then + None + else + let j = JToken.Parse(variablesString) + + match j.Type with + | JTokenType.Null -> Some Map.empty + | JTokenType.Object -> + let j = j :?> JObject + + j.Properties() + |> Seq.map (fun x -> x.Name, jTokenToAstValue x.Value) + |> Map.ofSeq + |> Some + | _ -> failwithf "variables property must be a JSON object" + | _ -> None + + Some (query, variables) diff --git a/samples/star-wars-api/FSharp.Data.GraphQL.Samples.StarWarsApi.fsproj b/samples/star-wars-api/FSharp.Data.GraphQL.Samples.StarWarsApi.fsproj index 87cffddde..00f696dbe 100644 --- a/samples/star-wars-api/FSharp.Data.GraphQL.Samples.StarWarsApi.fsproj +++ b/samples/star-wars-api/FSharp.Data.GraphQL.Samples.StarWarsApi.fsproj @@ -13,6 +13,7 @@ + diff --git a/samples/star-wars-api/HttpHandlers.fs b/samples/star-wars-api/HttpHandlers.fs index 916b27331..3425c8e1a 100644 --- a/samples/star-wars-api/HttpHandlers.fs +++ b/samples/star-wars-api/HttpHandlers.fs @@ -9,7 +9,6 @@ open System.IO open FSharp.Data.GraphQL open FSharp.Data.GraphQL.Types open FSharp.Control.Tasks -open Newtonsoft.Json.Linq type HttpHandler = HttpFunc -> HttpContext -> HttpFuncResult @@ -31,64 +30,32 @@ module HttpHandlers = let private graphQL (next : HttpFunc) (ctx : HttpContext) = task { let serialize d = JsonConvert.SerializeObject(d, jsonSettings) - let deserialize (data : string) = - let getMap (token : JToken) = - let rec mapper (name : string) (token : JToken) = - match name, token.Type with - | "variables", JTokenType.Object -> token.Children() |> Seq.map (fun x -> x.Name, mapper x.Name x.Value) |> Map.ofSeq |> box - | name, JTokenType.Array -> token |> Seq.map (fun x -> mapper name x) |> Array.ofSeq |> box - | _ -> (token :?> JValue).Value - token.Children() - |> Seq.map (fun x -> x.Name, mapper x.Name x.Value) - |> Map.ofSeq - if System.String.IsNullOrWhiteSpace(data) - then None - else data |> JToken.Parse |> getMap |> Some - let json = function | Direct (data, _) -> + printfn "%A" data JsonConvert.SerializeObject(data, jsonSettings) | Deferred (data, _, deferred) -> deferred |> Observable.add(fun d -> printfn "Deferred: %s" (serialize d)) JsonConvert.SerializeObject(data, jsonSettings) - | Stream data -> + | Stream data -> data |> Observable.add(fun d -> printfn "Subscription data: %s" (serialize d)) "{}" - + let removeWhitespacesAndLineBreaks (str : string) = str.Trim().Replace("\r\n", " ") - + let readStream (s : Stream) = use ms = new MemoryStream(4096) s.CopyTo(ms) ms.ToArray() - - let data = Encoding.UTF8.GetString(readStream ctx.Request.Body) |> deserialize - - let query = - data |> Option.bind (fun data -> - if data.ContainsKey("query") - then - match data.["query"] with - | :? string as x -> Some x - | _ -> failwith "Failure deserializing repsonse. Could not read query - it is not stringified in request." - else None) - - let variables = - data |> Option.bind (fun data -> - if data.ContainsKey("variables") - then - match data.["variables"] with - | null -> None - | :? string as x -> deserialize x - | :? Map as x -> Some x - | _ -> failwith "Failure deserializing response. Could not read variables - it is not a object in the request." - else None) - + + let data = Encoding.UTF8.GetString(readStream ctx.Request.Body) |> Deserialize.deserializeQueryAndVariables + + let query = data |> Option.map fst + let variables = data |> Option.bind snd + match query, variables with | Some query, Some variables -> - printfn "Received query: %s" query - printfn "Received variables: %A" variables let query = removeWhitespacesAndLineBreaks query let root = { RequestId = System.Guid.NewGuid().ToString() } let result = Schema.executor.AsyncExecute(query, root, variables) |> Async.RunSynchronously @@ -106,7 +73,7 @@ module HttpHandlers = return! okWithStr (json result) next ctx } - let webApp : HttpHandler = + let webApp : HttpHandler = setCorsHeaders - >=> graphQL + >=> graphQL >=> setContentTypeAsJson diff --git a/samples/star-wars-api/JsonConverters.fs b/samples/star-wars-api/JsonConverters.fs index d5e8db6e7..579ffe99d 100644 --- a/samples/star-wars-api/JsonConverters.fs +++ b/samples/star-wars-api/JsonConverters.fs @@ -1,9 +1,11 @@ namespace FSharp.Data.GraphQL.Samples.StarWarsApi +open System open Newtonsoft.Json open Newtonsoft.Json.Linq open Microsoft.FSharp.Reflection open FSharp.Data.GraphQL +open FSharp.Data.GraphQL.Ast open FSharp.Data.GraphQL.Types open FSharp.Data.GraphQL.Types.Patterns @@ -36,14 +38,14 @@ type OptionConverter() = type GraphQLQueryConverter<'a>(executor : Executor<'a>, replacements: Map, ?meta : Metadata) = inherit JsonConverter() - override __.CanConvert(t) = t = typeof - - override __.WriteJson(_, _, _) = failwith "Not supported" + override __.CanConvert(t) = t = typeof + + override __.WriteJson(_, _, _) = failwith "Not supported" override __.ReadJson(reader, _, _, serializer) = let jobj = JObject.Load reader let query = jobj.Property("query").Value.ToString() - let plan = + let plan = match meta with | Some meta -> executor.CreateExecutionPlan(query, meta = meta) | None -> executor.CreateExecutionPlan(query) @@ -54,16 +56,12 @@ type GraphQLQueryConverter<'a>(executor : Executor<'a>, replacements: Map jobj.SelectToken(path).Replace(JObject.FromObject(rep))) replacements let vars = JObject.Parse(jobj.Property("variables").Value.ToString()) - let variables = + let variables = vs - |> List.fold (fun (acc: Map)(vdef: VarDef) -> + |> List.fold (fun (acc: Map)(vdef: VarDef) -> match vars.TryGetValue(vdef.Name) with | true, jval -> - let v = - match jval.Type with - | JTokenType.Null -> null - | JTokenType.String -> jval.ToString() :> obj - | _ -> jval.ToObject(vdef.TypeDef.Type, serializer) + let v = Deserialize.jTokenToAstValue jval Map.add (vdef.Name) v acc | false, _ -> match vdef.DefaultValue, vdef.TypeDef with diff --git a/samples/star-wars-api/Schema.fs b/samples/star-wars-api/Schema.fs index 7ca7d2c71..b1e1ae386 100644 --- a/samples/star-wars-api/Schema.fs +++ b/samples/star-wars-api/Schema.fs @@ -1,6 +1,7 @@ namespace FSharp.Data.GraphQL.Samples.StarWarsApi open FSharp.Data.GraphQL +open FSharp.Data.GraphQL.Decoding open FSharp.Data.GraphQL.Types open FSharp.Data.GraphQL.Server.Middleware @@ -227,7 +228,7 @@ module Schema = let schema : ISchema = upcast Schema(Query, Mutation, Subscription, schemaConfig) - let middlewares = + let middlewares = [ Define.QueryWeightMiddleware(2.0, true) Define.ObjectListFilterMiddleware(true) Define.ObjectListFilterMiddleware(true) diff --git a/samples/star-wars-api/WebSocketMessages.fs b/samples/star-wars-api/WebSocketMessages.fs index 258aaba58..fb8ee8f65 100644 --- a/samples/star-wars-api/WebSocketMessages.fs +++ b/samples/star-wars-api/WebSocketMessages.fs @@ -1,11 +1,13 @@ namespace FSharp.Data.GraphQL.Samples.StarWarsApi +open FSharp.Data.GraphQL.Ast open FSharp.Data.GraphQL.Execution open FSharp.Data.GraphQL.Types type GraphQLQuery = { ExecutionPlan : ExecutionPlan - Variables : Map } + // Variables : Map + Variables : Map } type WebSocketClientMessage = | ConnectionInit diff --git a/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs b/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs index c854aba80..b5479d0ed 100644 --- a/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs +++ b/src/FSharp.Data.GraphQL.Shared/TypeSystem.fs @@ -1589,6 +1589,9 @@ and [] internal ListOfDefinition<'Val, 'Seq when ' | _ -> false ) + override x.GetHashCode() = + hash ("ListOfDef", x.OfType) + override x.ToString() = "[" + x.OfType.ToString() + "]!" /// GraphQL type definition for nullable/optional types. @@ -2971,14 +2974,17 @@ module SchemaDefinitions = Decoder = decoder CoerceValue = coerceValue } - [] static member Enum(name : string, options : EnumValue<'Val> list, ?description : string) : EnumDef<'Val> = upcast { EnumDefinition.Name = name Description = description Options = options |> List.toArray - Decoder = Decode.auto None + Decoder = + Decode.enum ( + options + |> Seq.map (fun opt -> opt.Name, opt.Value) + |> Map.ofSeq) } ///