๐ŸŒŠ A GraphQL implementation in Gleam

feat: sort introspection types alphabetically by name

+2 -1
CHANGELOG.md
··· 1 1 # Changelog 2 2 3 - ## 2.0.1 3 + ## 2.1.0 4 4 5 5 ### Added 6 6 7 7 - Argument type validation: list arguments now produce helpful errors when passed objects instead of lists 8 8 - `isOneOf` field in type introspection for INPUT_OBJECT types (GraphQL spec compliance) 9 + - Introspection types are now returned in alphabetical order by name 9 10 10 11 ## 2.0.0 11 12
+1 -1
gleam.toml
··· 1 1 name = "swell" 2 - version = "2.0.1" 2 + version = "2.1.0" 3 3 description = "๐ŸŒŠ A GraphQL implementation in Gleam" 4 4 licences = ["Apache-2.0"] 5 5 repository = { type = "github", user = "bigmoves", repo = "swell" }
+5 -2
src/swell/introspection.gleam
··· 6 6 import gleam/list 7 7 import gleam/option 8 8 import gleam/result 9 + import gleam/string 9 10 import swell/schema 10 11 import swell/value 11 12 ··· 108 109 fn get_all_types(graphql_schema: schema.Schema) -> List(value.Value) { 109 110 let all_types = get_all_schema_types(graphql_schema) 110 111 111 - // Convert all types to introspection values 112 - list.map(all_types, type_introspection) 112 + // Sort types alphabetically by name, then convert to introspection values 113 + all_types 114 + |> list.sort(fn(a, b) { string.compare(schema.type_name(a), schema.type_name(b)) }) 115 + |> list.map(type_introspection) 113 116 } 114 117 115 118 /// Deduplicate types by name, keeping the version with the most fields
+48
test/introspection_test.gleam
··· 3 3 /// Comprehensive tests for introspection queries 4 4 import gleam/list 5 5 import gleam/option.{None} 6 + import gleam/string 6 7 import gleeunit/should 7 8 import swell/executor 8 9 import swell/schema ··· 674 675 } 675 676 |> should.be_true 676 677 } 678 + 679 + /// Test: Introspection types are returned in alphabetical order 680 + /// Verifies that __schema.types are sorted alphabetically by name 681 + pub fn schema_types_alphabetical_order_test() { 682 + let schema = test_schema() 683 + let query = "{ __schema { types { name } } }" 684 + 685 + let result = executor.execute(query, schema, schema.context(None)) 686 + 687 + should.be_ok(result) 688 + |> fn(response) { 689 + case response { 690 + executor.Response(data: value.Object(fields), errors: []) -> { 691 + case list.key_find(fields, "__schema") { 692 + Ok(value.Object(schema_fields)) -> { 693 + case list.key_find(schema_fields, "types") { 694 + Ok(value.List(types)) -> { 695 + // Extract type names 696 + let names = 697 + list.filter_map(types, fn(type_val) { 698 + case type_val { 699 + value.Object(type_fields) -> { 700 + case list.key_find(type_fields, "name") { 701 + Ok(value.String(name)) -> Ok(name) 702 + _ -> Error(Nil) 703 + } 704 + } 705 + _ -> Error(Nil) 706 + } 707 + }) 708 + 709 + // Check that names are sorted alphabetically 710 + // Expected order: Boolean, Float, ID, Int, Query, String 711 + let sorted_names = list.sort(names, string.compare) 712 + names == sorted_names 713 + } 714 + _ -> False 715 + } 716 + } 717 + _ -> False 718 + } 719 + } 720 + _ -> False 721 + } 722 + } 723 + |> should.be_true 724 + }