Class: Woods::Extractors::GraphQLExtractor
- Inherits:
-
Object
- Object
- Woods::Extractors::GraphQLExtractor
- Includes:
- SharedDependencyScanner, SharedUtilityMethods
- Defined in:
- lib/woods/extractors/graphql_extractor.rb
Overview
GraphQLExtractor handles graphql-ruby type and mutation extraction.
GraphQL schemas are rich in structure — types, fields, arguments, resolvers, and mutations form a typed API layer over the domain. We extract these with runtime introspection when available (via ‘GraphQL::Schema.types`) and fall back to file-based discovery when the schema isn’t fully loadable.
We extract:
-
Object types, input types, enum types, interface types, union types, scalar types
-
Mutations and their arguments/return fields
-
Query fields and resolvers
-
Standalone resolver classes
-
Field-level metadata (types, descriptions, complexity, arguments)
-
Authorization patterns (authorized?, pundit, cancan)
-
Dependencies on models, services, jobs, and other GraphQL types
Constant Summary collapse
- GRAPHQL_DIRECTORY =
Standard directory for graphql-ruby applications
'app/graphql'- CHUNK_THRESHOLD =
Token threshold for chunking large types
1500
Constants included from SharedDependencyScanner
SharedDependencyScanner::FORM_ACTION_HELPER, SharedDependencyScanner::ROUTE_HELPER_PATTERN
Instance Method Summary collapse
-
#extract_all ⇒ Array<ExtractedUnit>
Extract all GraphQL types, mutations, queries, and resolvers.
-
#extract_graphql_file(file_path) ⇒ ExtractedUnit?
Extract a single GraphQL file.
-
#initialize ⇒ GraphQLExtractor
constructor
A new instance of GraphQLExtractor.
Methods included from SharedDependencyScanner
#extract_constantize_targets, #scan_common_dependencies, #scan_form_dependencies, #scan_job_dependencies, #scan_mailer_dependencies, #scan_model_dependencies, #scan_navigation_dependencies, #scan_service_dependencies
Methods included from SharedUtilityMethods
#app_source?, #condition_label, #count_loc, #detect_entry_points, #extract_action_filter_actions, #extract_callback_conditions, #extract_class_methods, #extract_custom_errors, #extract_initialize_params, #extract_namespace, #extract_public_methods, #resolve_source_location, #skip_file?
Constructor Details
#initialize ⇒ GraphQLExtractor
Returns a new instance of GraphQLExtractor.
40 41 42 43 44 |
# File 'lib/woods/extractors/graphql_extractor.rb', line 40 def initialize @graphql_dir = defined?(Rails) ? Rails.root.join(GRAPHQL_DIRECTORY) : nil @schema_class = find_schema_class @runtime_types = load_runtime_types end |
Instance Method Details
#extract_all ⇒ Array<ExtractedUnit>
Extract all GraphQL types, mutations, queries, and resolvers
Returns an empty array if graphql-ruby is not installed or no GraphQL files are found.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/woods/extractors/graphql_extractor.rb', line 52 def extract_all return [] unless graphql_available? units = [] seen_identifiers = Set.new # First pass: runtime introspection (most accurate) if @runtime_types.any? @runtime_types.each_value do |type_class| unit = extract_from_runtime_type(type_class) next unless unit next if seen_identifiers.include?(unit.identifier) seen_identifiers << unit.identifier units << unit end end # Second pass: file-based discovery (catches everything) if @graphql_dir&.directory? Dir[@graphql_dir.join('**/*.rb')].each do |file_path| unit = extract_graphql_file(file_path) next unless unit next if seen_identifiers.include?(unit.identifier) seen_identifiers << unit.identifier units << unit end end units.compact end |
#extract_graphql_file(file_path) ⇒ ExtractedUnit?
Extract a single GraphQL file
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/woods/extractors/graphql_extractor.rb', line 90 def extract_graphql_file(file_path) source = File.read(file_path) class_name = extract_class_name(file_path, source) return nil unless class_name return nil unless graphql_class?(source) unit_type = classify_unit_type(file_path, source) runtime_class = class_name.safe_constantize unit = ExtractedUnit.new( type: unit_type, identifier: class_name, file_path: file_path ) unit.namespace = extract_namespace(class_name) unit.source_code = build_annotated_source(source, class_name, unit_type, runtime_class) unit. = (source, class_name, unit_type, runtime_class) unit.dependencies = extract_dependencies(source, class_name) unit.chunks = build_chunks(unit, runtime_class) if unit.needs_chunking?(threshold: CHUNK_THRESHOLD) unit rescue StandardError => e Rails.logger.error("Failed to extract GraphQL file #{file_path}: #{e.}") if defined?(Rails) nil end |