@@ -4,27 +4,40 @@ defmodule Absinthe.Phase.Document.Execution.Data do
44 Produces data fit for external encoding from annotated value tree
55 """
66
7- alias Absinthe.Blueprint
7+ alias Absinthe . { Blueprint , Phase }
88 use Absinthe.Phase
99
1010 def run ( blueprint ) do
11- result = blueprint
12- |> Blueprint . current_operation
13- |> process
14- |> clean
11+ result = blueprint |> process
1512 { :ok , result }
1613 end
1714
18- defp process ( % Blueprint.Document.Operation { resolution: tree } ) do
19- { data , errors } = field_data ( tree . fields , [ ] )
20- % { data: data , errors: errors }
15+ defp process ( % Blueprint { } = blueprint ) do
16+ { _ , document_errors } = Blueprint . prewalk ( blueprint , [ ] , & document_errors / 2 )
17+ { data , errors } = case Blueprint . current_operation ( blueprint ) do
18+ nil ->
19+ { nil , document_errors }
20+ op ->
21+ field_data ( op . resolution . fields , document_errors )
22+ end
23+ { :ok , format_result ( data , errors |> Enum . uniq ) }
2124 end
2225
23- defp clean ( % { data: data } = result ) when map_size ( data ) == 0 do
24- Map . delete ( result , :data )
26+ defp format_result ( nil , errors ) do
27+ % { data: % { } , errors: Enum . map ( errors , & format_error / 1 ) }
2528 end
26- defp clean ( % { errors: [ ] } = result ) do
27- Map . delete ( result , :errors )
29+ defp format_result ( data , [ ] ) do
30+ % { data: data }
31+ end
32+ defp format_result ( data , errors ) do
33+ % { data: data , errors: Enum . map ( errors , & format_error / 1 ) }
34+ end
35+
36+ defp document_errors ( % { errors: errs } = node , acc ) do
37+ { node , acc ++ errs }
38+ end
39+ defp document_errors ( node , acc ) do
40+ { node , acc }
2841 end
2942
3043 # Leaf
@@ -38,25 +51,37 @@ defmodule Absinthe.Phase.Document.Execution.Data do
3851
3952 defp list_data ( fields , errors , acc \\ [ ] )
4053 defp list_data ( [ ] , errors , acc ) , do: { :lists . reverse ( acc ) , errors }
41- defp list_data ( [ { :ok , field } | fields ] , errors , acc ) do
54+ defp list_data ( [ % { errors: [ ] } = field | fields ] , errors , acc ) do
4255 { value , errors } = data ( field , errors )
4356 list_data ( fields , errors , [ value | acc ] )
4457 end
45- defp list_data ( [ { :error , error } | fields ] , errors , acc ) do
46- list_data ( fields , List . wrap ( error ) ++ errors , acc )
58+ defp list_data ( [ % { errors: errs } = field | fields ] , errors , acc ) when length ( errs ) > 0 do
59+ list_data ( fields , errs ++ errors , acc )
4760 end
4861
4962 defp field_data ( fields , errors , acc \\ [ ] )
5063 defp field_data ( [ ] , errors , acc ) , do: { :maps . from_list ( acc ) , errors }
51- defp field_data ( [ { :ok , field } | fields ] , errors , acc ) do
64+ defp field_data ( [ % { errors: [ ] } = field | fields ] , errors , acc ) do
5265 { value , errors } = data ( field , errors )
5366 field_data ( fields , errors , [ { field_name ( field ) , value } | acc ] )
5467 end
55- defp field_data ( [ { :error , error } | fields ] , errors , acc ) do
56- field_data ( fields , List . wrap ( error ) ++ errors , acc )
68+ defp field_data ( [ % { errors: errs } = field | fields ] , errors , acc ) when length ( errs ) > 0 do
69+ field_data ( fields , errs ++ errors , acc )
5770 end
5871
5972 defp field_name ( % { emitter: % { alias: nil , name: name } } ) , do: name
6073 defp field_name ( % { emitter: % { alias: name } } ) , do: name
6174 defp field_name ( % { emitter: % { name: name } } ) , do: name
75+
76+ defp format_error ( % Phase.Error { locations: [ ] } = error ) do
77+ % { message: error . message }
78+ end
79+ defp format_error ( % Phase.Error { } = error ) do
80+ % { message: error . message , locations: Enum . map ( error . locations , & format_location / 1 ) }
81+ end
82+
83+ defp format_location ( % { line: line , column: col } ) do
84+ % { line: line || 0 , column: col || 0 }
85+ end
86+
6287end
0 commit comments