class GraphQLSwiftGen
Constants
- BUILTIN_SCALARS
- DEFAULT_SCALAR
- RESERVED_WORDS
- SCHEMA_ERB
- TYPE_ERB
- VERSION
Attributes
import_graphql_support[R]
scalars[R]
schema[R]
schema_name[R]
script_name[R]
Public Class Methods
new(schema, custom_scalars: [], nest_under:, script_name: 'graphql_swift_gen gem', import_graphql_support: false)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 9 def initialize(schema, custom_scalars: [], nest_under:, script_name: 'graphql_swift_gen gem', import_graphql_support: false) @schema = schema @schema_name = nest_under @script_name = script_name @scalars = (BUILTIN_SCALARS + custom_scalars).reduce({}) { |hash, scalar| hash[scalar.type_name] = scalar; hash } @scalars.default_proc = ->(hash, key) { DEFAULT_SCALAR } @import_graphql_support = import_graphql_support end
Private Class Methods
erb_for(template_filename)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 43 def erb_for(template_filename) path = File.expand_path("../graphql_swift_gen/templates/#{template_filename}", __FILE__) erb = ERB.new(File.read(path)) erb.filename = path erb end
Public Instance Methods
generate()
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 29 def generate output = {} output["#{schema_name}.swift"] = generate_schema_file schema.types.reject{ |type| type.name.start_with?('__') || type.scalar? }.each do |type| output["#{schema_name}/#{type.name}.swift"] = generate_type(type) end output end
save(path)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 18 def save(path) output = generate begin Dir.mkdir("#{path}/#{schema_name}") rescue Errno::EEXIST end output.each do |relative_path, file_contents| File.write("#{path}/#{relative_path}", file_contents) end end
Private Instance Methods
deserialize_value_code(field_name, expr, type, untyped: true)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 190 def deserialize_value_code(field_name, expr, type, untyped: true) statements = "" if untyped json_type = swift_json_type(type.unwrap_non_null, non_null: true) statements << "if #{expr} is NSNull { return nil }\n" unless type.non_null? statements << <<-SWIFT guard let value = #{expr} as? #{json_type} else { throw SchemaViolationError(type: type(of: self), field: fieldName, value: fieldValue) } SWIFT expr = 'value' end type = type.unwrap_non_null statements << "return " + case type.kind when 'SCALAR' scalars[type.name].deserialize_expr(expr) when 'LIST' rethrow = "try " if %w(OBJECT INTERFACE UNION).include?(type.unwrap.kind) "#{rethrow}#{expr}.map { #{deserialize_value_code(field_name, '$0', type.of_type, untyped: !type.of_type.non_null?)} }" when 'OBJECT' "try #{type.name}(fields: #{expr})" when 'INTERFACE', 'UNION' "try Unknown#{type.name}.create(fields: #{expr})" when 'ENUM' "#{escape_reserved_word(type.name)}(rawValue: #{expr}) ?? .unknownValue" else raise NotImplementedError, "Unexpected #{type.kind} argument type" end end
escape_reserved_word(word)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 99 def escape_reserved_word(word) return word unless RESERVED_WORDS.include?(word) return "`#{word}`" end
generate_append_objects_code(expr, type, non_null: false)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 235 def generate_append_objects_code(expr, type, non_null: false) if type.non_null? non_null = true type = type.of_type end unless non_null return "if let value = #{expr} {\n#{generate_append_objects_code('value', type, non_null: true)}\n}" end return "#{expr}.forEach {\n#{generate_append_objects_code('$0', type.of_type)}\n}" if type.list? abstract_response = type.object? ? expr : "#{expr} as! GraphQL.AbstractResponse" "response.append(#{abstract_response})\n" \ "response.append(contentsOf: #{expr}.childResponseObjectMap())" end
generate_build_input_code(expr, type, wrap: true)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 172 def generate_build_input_code(expr, type, wrap: true) case type.kind when 'SCALAR' scalars[type.name].serialize_expr(expr) when 'ENUM' "\\(#{expr}.rawValue)" when 'LIST' map_block = generate_build_input_code('$0', type.of_type.unwrap_non_null) map_code = map_block == '$0' ? expr : "#{expr}.map{ \"#{map_block}\" }" elements = "#{map_code}.joined(separator: \",\")" "[\\(#{elements})]" when 'INPUT_OBJECT' "\\(#{expr}.serialize())" else raise NotImplementedError, "Unexpected #{type.kind} argument type" end end
generate_schema_file()
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 104 def generate_schema_file reformat(SCHEMA_ERB.result(binding)) end
generate_type(type)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 108 def generate_type(type) reformat(TYPE_ERB.result(binding)) end
reformat(code)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 112 def reformat(code) Reformatter.new(indent: "\t").reformat(code) end
swift_arg_defs(field)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 222 def swift_arg_defs(field) defs = ["aliasSuffix: String? = nil"] field.args.each do |arg| arg_def = "#{escape_reserved_word(arg.name)}: #{swift_input_type(arg.type)}" arg_def << " = nil" unless arg.type.non_null? defs << arg_def end if field.subfields? defs << "_ subfields: (#{field.type.unwrap.name}Query) -> Void" end defs.join(', ') end
swift_attributes(deprecatable)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 250 def swift_attributes(deprecatable) return unless deprecatable.deprecated? if deprecatable.deprecation_reason message_argument = ", message:#{deprecatable.deprecation_reason.inspect}" end "@available(*, deprecated#{message_argument})" end
swift_input_type(type, non_null: false)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 116 def swift_input_type(type, non_null: false) code = case type.kind when 'NON_NULL' return swift_input_type(type.of_type, non_null: true) when 'SCALAR' scalars[type.name].swift_type when 'LIST' "[#{swift_input_type(type.of_type, non_null: true)}]" when 'INPUT_OBJECT', 'ENUM' type.name else raise NotImplementedError, "Unhandled #{type.kind} input type" end code += "?" unless non_null code end
swift_json_type(type, non_null: false)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 133 def swift_json_type(type, non_null: false) if !non_null && !type.non_null? return 'Any' end case type.kind when "NON_NULL" swift_json_type(type.of_type, non_null: true) when 'SCALAR' scalars[type.name].json_type when 'OBJECT', 'INTERFACE', 'UNION' "[String: Any]" when 'LIST' "[#{swift_json_type(type.of_type)}]" when 'ENUM' 'String' else raise NotImplementedError, "Unexpected #{type.kind} response type" end end
swift_output_type(type, non_null: false)
click to toggle source
# File codegen/lib/graphql_swift_gen.rb, line 153 def swift_output_type(type, non_null: false) code = case type.kind when 'NON_NULL' return swift_output_type(type.of_type, non_null: true) when 'SCALAR' scalars[type.name].swift_type when 'LIST' "[#{swift_output_type(type.of_type)}]" when 'OBJECT', 'ENUM' "#{schema_name}.#{type.name}" when 'INTERFACE', 'UNION' type.name else raise NotImplementedError, "Unhandled #{type.kind} response type" end code += "?" unless non_null code end