|
1 | 1 | # frozen_string_literal: true
|
| 2 | +require "graphql/schema/addition" |
2 | 3 | require "graphql/schema/base_64_encoder"
|
3 | 4 | require "graphql/schema/catchall_middleware"
|
4 | 5 | require "graphql/schema/default_parse_error"
|
@@ -1582,10 +1583,7 @@ def directives(*new_directives)
|
1582 | 1583 | # @param new_directive [Class]
|
1583 | 1584 | # @return void
|
1584 | 1585 | def directive(new_directive)
|
1585 |
| - own_directives[new_directive.graphql_name] ||= begin |
1586 |
| - add_type_and_traverse(new_directive, root: false) |
1587 |
| - new_directive |
1588 |
| - end |
| 1586 | + add_type_and_traverse(new_directive, root: false) |
1589 | 1587 | end
|
1590 | 1588 |
|
1591 | 1589 | def default_directives
|
@@ -1709,6 +1707,30 @@ def query_stack_error(query, err)
|
1709 | 1707 |
|
1710 | 1708 | private
|
1711 | 1709 |
|
| 1710 | + # @param t [Module, Array<Module>] |
| 1711 | + # @return [void] |
| 1712 | + def add_type_and_traverse(t, root:) |
| 1713 | + if root |
| 1714 | + @root_types ||= [] |
| 1715 | + @root_types << t |
| 1716 | + end |
| 1717 | + new_types = Array(t) |
| 1718 | + addition = Schema::Addition.new(schema: self, own_types: own_types, new_types: new_types) |
| 1719 | + own_types.merge!(addition.types) |
| 1720 | + own_possible_types.merge!(addition.possible_types) { |key, old_val, new_val| old_val + new_val } |
| 1721 | + own_union_memberships.merge!(addition.union_memberships) |
| 1722 | + |
| 1723 | + addition.references.each { |thing, pointers| |
| 1724 | + pointers.each { |pointer| references_to(thing, from: pointer) } |
| 1725 | + } |
| 1726 | + |
| 1727 | + addition.directives.each { |dir_class| own_directives[dir_class.graphql_name] = dir_class } |
| 1728 | + |
| 1729 | + addition.arguments_with_default_values.each do |arg| |
| 1730 | + arg.validate_default_value |
| 1731 | + end |
| 1732 | + end |
| 1733 | + |
1712 | 1734 | def lazy_methods
|
1713 | 1735 | if !defined?(@lazy_methods)
|
1714 | 1736 | if inherited_map = find_inherited_value(:lazy_methods)
|
@@ -1774,202 +1796,6 @@ def own_middleware
|
1774 | 1796 | def own_multiplex_analyzers
|
1775 | 1797 | @own_multiplex_analyzers ||= []
|
1776 | 1798 | end
|
1777 |
| - |
1778 |
| - # @param t [Module, Array<Module>] |
1779 |
| - # @return [void] |
1780 |
| - def add_type_and_traverse(t, root:) |
1781 |
| - if root |
1782 |
| - @root_types ||= [] |
1783 |
| - @root_types << t |
1784 |
| - end |
1785 |
| - late_types = [] |
1786 |
| - new_types = Array(t) |
1787 |
| - new_types.each { |t| add_type(t, owner: nil, late_types: late_types, path: [t.graphql_name]) } |
1788 |
| - missed_late_types = 0 |
1789 |
| - while (late_type_vals = late_types.shift) |
1790 |
| - type_owner, lt = late_type_vals |
1791 |
| - if lt.is_a?(String) |
1792 |
| - type = Member::BuildType.constantize(lt) |
1793 |
| - # Reset the counter, since we might succeed next go-round |
1794 |
| - missed_late_types = 0 |
1795 |
| - update_type_owner(type_owner, type) |
1796 |
| - add_type(type, owner: type_owner, late_types: late_types, path: [type.graphql_name]) |
1797 |
| - elsif lt.is_a?(LateBoundType) |
1798 |
| - if (type = get_type(lt.graphql_name)) |
1799 |
| - # Reset the counter, since we might succeed next go-round |
1800 |
| - missed_late_types = 0 |
1801 |
| - update_type_owner(type_owner, type) |
1802 |
| - add_type(type, owner: type_owner, late_types: late_types, path: [type.graphql_name]) |
1803 |
| - else |
1804 |
| - missed_late_types += 1 |
1805 |
| - # Add it back to the list, maybe we'll be able to resolve it later. |
1806 |
| - late_types << [type_owner, lt] |
1807 |
| - if missed_late_types == late_types.size |
1808 |
| - # We've looked at all of them and haven't resolved one. |
1809 |
| - raise UnresolvedLateBoundTypeError.new(type: lt) |
1810 |
| - else |
1811 |
| - # Try the next one |
1812 |
| - end |
1813 |
| - end |
1814 |
| - else |
1815 |
| - raise ArgumentError, "Unexpected late type: #{lt.inspect}" |
1816 |
| - end |
1817 |
| - end |
1818 |
| - nil |
1819 |
| - end |
1820 |
| - |
1821 |
| - def update_type_owner(owner, type) |
1822 |
| - case owner |
1823 |
| - when Class |
1824 |
| - if owner.kind.union? |
1825 |
| - # It's a union with possible_types |
1826 |
| - # Replace the item by class name |
1827 |
| - owner.assign_type_membership_object_type(type) |
1828 |
| - own_possible_types[owner.graphql_name] = owner.possible_types |
1829 |
| - elsif type.kind.interface? && owner.kind.object? |
1830 |
| - new_interfaces = [] |
1831 |
| - owner.interfaces.each do |int_t| |
1832 |
| - if int_t.is_a?(String) && int_t == type.graphql_name |
1833 |
| - new_interfaces << type |
1834 |
| - elsif int_t.is_a?(LateBoundType) && int_t.graphql_name == type.graphql_name |
1835 |
| - new_interfaces << type |
1836 |
| - else |
1837 |
| - # Don't re-add proper interface definitions, |
1838 |
| - # they were probably already added, maybe with options. |
1839 |
| - end |
1840 |
| - end |
1841 |
| - owner.implements(*new_interfaces) |
1842 |
| - new_interfaces.each do |int| |
1843 |
| - pt = own_possible_types[int.graphql_name] ||= [] |
1844 |
| - if !pt.include?(owner) |
1845 |
| - pt << owner |
1846 |
| - end |
1847 |
| - end |
1848 |
| - end |
1849 |
| - |
1850 |
| - when nil |
1851 |
| - # It's a root type |
1852 |
| - own_types[type.graphql_name] = type |
1853 |
| - when GraphQL::Schema::Field, GraphQL::Schema::Argument |
1854 |
| - orig_type = owner.type |
1855 |
| - # Apply list/non-null wrapper as needed |
1856 |
| - if orig_type.respond_to?(:of_type) |
1857 |
| - transforms = [] |
1858 |
| - while (orig_type.respond_to?(:of_type)) |
1859 |
| - if orig_type.kind.non_null? |
1860 |
| - transforms << :to_non_null_type |
1861 |
| - elsif orig_type.kind.list? |
1862 |
| - transforms << :to_list_type |
1863 |
| - else |
1864 |
| - raise "Invariant: :of_type isn't non-null or list" |
1865 |
| - end |
1866 |
| - orig_type = orig_type.of_type |
1867 |
| - end |
1868 |
| - transforms.reverse_each { |t| type = type.public_send(t) } |
1869 |
| - end |
1870 |
| - owner.type = type |
1871 |
| - else |
1872 |
| - raise "Unexpected update: #{owner.inspect} #{type.inspect}" |
1873 |
| - end |
1874 |
| - end |
1875 |
| - |
1876 |
| - def add_type(type, owner:, late_types:, path:) |
1877 |
| - if type.respond_to?(:metadata) && type.metadata.is_a?(Hash) |
1878 |
| - type_class = type.metadata[:type_class] |
1879 |
| - if type_class.nil? |
1880 |
| - raise ArgumentError, "Can't add legacy type: #{type} (#{type.class})" |
1881 |
| - else |
1882 |
| - type = type_class |
1883 |
| - end |
1884 |
| - elsif type.is_a?(String) || type.is_a?(GraphQL::Schema::LateBoundType) |
1885 |
| - late_types << [owner, type] |
1886 |
| - return |
1887 |
| - end |
1888 |
| - |
1889 |
| - if owner.is_a?(Class) && owner < GraphQL::Schema::Union |
1890 |
| - um = own_union_memberships[type.graphql_name] ||= [] |
1891 |
| - um << owner |
1892 |
| - end |
1893 |
| - |
1894 |
| - if (prev_type = own_types[type.graphql_name]) |
1895 |
| - if prev_type != type |
1896 |
| - raise DuplicateTypeNamesError.new( |
1897 |
| - type_name: type.graphql_name, |
1898 |
| - first_definition: prev_type, |
1899 |
| - second_definition: type, |
1900 |
| - path: path, |
1901 |
| - ) |
1902 |
| - else |
1903 |
| - # This type was already added |
1904 |
| - end |
1905 |
| - elsif type.is_a?(Class) && type < GraphQL::Schema::Directive |
1906 |
| - type.arguments.each do |name, arg| |
1907 |
| - arg_type = arg.type.unwrap |
1908 |
| - references_to(arg_type, from: arg) |
1909 |
| - add_type(arg_type, owner: arg, late_types: late_types, path: path + [name]) |
1910 |
| - end |
1911 |
| - else |
1912 |
| - own_types[type.graphql_name] = type |
1913 |
| - add_directives_from(type) |
1914 |
| - if type.kind.fields? |
1915 |
| - type.fields.each do |name, field| |
1916 |
| - field_type = field.type.unwrap |
1917 |
| - references_to(field_type, from: field) |
1918 |
| - field_path = path + [name] |
1919 |
| - add_type(field_type, owner: field, late_types: late_types, path: field_path) |
1920 |
| - add_directives_from(field) |
1921 |
| - field.arguments.each do |arg_name, arg| |
1922 |
| - add_directives_from(arg) |
1923 |
| - arg_type = arg.type.unwrap |
1924 |
| - references_to(arg_type, from: arg) |
1925 |
| - add_type(arg_type, owner: arg, late_types: late_types, path: field_path + [arg_name]) |
1926 |
| - end |
1927 |
| - end |
1928 |
| - end |
1929 |
| - if type.kind.input_object? |
1930 |
| - type.arguments.each do |arg_name, arg| |
1931 |
| - add_directives_from(arg) |
1932 |
| - arg_type = arg.type.unwrap |
1933 |
| - references_to(arg_type, from: arg) |
1934 |
| - add_type(arg_type, owner: arg, late_types: late_types, path: path + [arg_name]) |
1935 |
| - end |
1936 |
| - end |
1937 |
| - if type.kind.union? |
1938 |
| - own_possible_types[type.graphql_name] = type.possible_types |
1939 |
| - type.possible_types.each do |t| |
1940 |
| - add_type(t, owner: type, late_types: late_types, path: path + ["possible_types"]) |
1941 |
| - end |
1942 |
| - end |
1943 |
| - if type.kind.interface? |
1944 |
| - type.orphan_types.each do |t| |
1945 |
| - add_type(t, owner: type, late_types: late_types, path: path + ["orphan_types"]) |
1946 |
| - end |
1947 |
| - end |
1948 |
| - if type.kind.object? |
1949 |
| - own_possible_types[type.graphql_name] = [type] |
1950 |
| - type.interface_type_memberships.each do |interface_type_membership| |
1951 |
| - case interface_type_membership |
1952 |
| - when Schema::TypeMembership |
1953 |
| - interface_type = interface_type_membership.abstract_type |
1954 |
| - # We can get these now; we'll have to get late-bound types later |
1955 |
| - if interface_type.is_a?(Module) |
1956 |
| - implementers = own_possible_types[interface_type.graphql_name] ||= [] |
1957 |
| - implementers << type |
1958 |
| - end |
1959 |
| - when String, Schema::LateBoundType |
1960 |
| - interface_type = interface_type_membership |
1961 |
| - else |
1962 |
| - raise ArgumentError, "Invariant: unexpected type membership for #{type.graphql_name}: #{interface_type_membership.class} (#{interface_type_membership.inspect})" |
1963 |
| - end |
1964 |
| - add_type(interface_type, owner: type, late_types: late_types, path: path + ["implements"]) |
1965 |
| - end |
1966 |
| - end |
1967 |
| - end |
1968 |
| - end |
1969 |
| - |
1970 |
| - def add_directives_from(owner) |
1971 |
| - owner.directives.each { |dir| directive(dir.class) } |
1972 |
| - end |
1973 | 1799 | end
|
1974 | 1800 |
|
1975 | 1801 | def dataloader_class
|
|
0 commit comments