class

Analyzer::Elixir::Absinthe

Inherits Analyzer::Elixir::ElixirEngine < FileScanEngine < Analyzer < FileHelper < Reference < Object

Absinthe (https://hexdocs.pm/absinthe) code-first GraphQL schemas. Each root field — field inside a schema's query/mutation/subscription block, an extend object(:query) block, or an object pulled in with import_fields — becomes one endpoint in the shape the SDL analyzers emit.

The root blocks live in the use Absinthe.Schema module while the imported objects usually sit in use Absinthe.Schema.Notation modules in other files, so every file is collected first and the imports are resolved globally afterwards.

Constants

ARG = /^\s*arg\s*\(?\s*:(\w+)(.*)$/
DEFAULT_ROOT_NAMES = {"Query" => "RootQueryType", "Mutation" => "RootMutationType", "Subscription" => "RootSubscriptionType"}

Absinthe.Schema's @default_query_name and siblings.

EXTEND_ROOT = /^\s*extend\s+object\s*\(?\s*:(query|mutation|subscription)\s*\)?\s*do\s*$/

extend object(:query) do / extend object :mutation do.

FIELD = /^\s*(connection\s+)?field\s*\(?\s*:(\w+)(.*)$/

field :posts, … or Absinthe.Relay's connection field :posts, node_type: :post.

FORWARD = /^\s*forward\s*\(?\s*"([^"]*)"\s*,\s*(?:to:\s*)?Absinthe\.Plug\b(?!\.)/

forward "/api", Absinthe.Plug, schema: … (Phoenix) or forward "/api", to: Absinthe.Plug, … (Plug.Router). The GraphiQL plug (Absinthe.Plug.GraphiQL) is the IDE, not the API mount.

IMPORT = /^\s*import_fields\s*\(?\s*:(\w+)/
NAME_OPTION = /\bname:\s*"([^"]+)"/
OBJECT_OPEN = /^\s*object\s*\(?\s*:(\w+)\b.*\bdo\s*$/
RELAY_PAGINATION_ARGS = [{name: "after", type: "String"}, {name: "first", type: "Int"}, {name: "before", type: "String"}, {name: "last", type: "Int"}]

Arguments Absinthe.Relay adds to every connection field.

ROOT_KINDS = {"query" => "Query", "mutation" => "Mutation", "subscription" => "Subscription"}
ROOT_OPEN = /^\s*(query|mutation|subscription)\s*(?:\(?\s*name:\s*\)?\s*)?do\s*$/

query do / query name: "RootQuery" do / mutation(name: "M") do, matched on the string-stripped line (the name is read off the raw one).

SCALARS = {"string" => "String", "integer" => "Int", "float" => "Float", "boolean" => "Boolean", "id" => "ID"}
SCOPE = /^\s*scope\s*\(?\s*"([^"]*)"/
TYPE_TOKEN = /\bnon_null\b|\blist_of\b|:(\w+)|\)/

Class methods

tech_name
Source

Instance methods

analyze
Source
analyze_file(path : String) : Array(Endpoint)

Collection replaces the per-file walk; analyze drives everything.

Source
tech

Instance-side view of the same declaration. The per-file rescues live on this base class, which has no way to name the analyzer that is running inside them, so a skipped file could not be attributed to a tech. Deriving it from analyzer_for keeps the name written exactly once.

Source

Nested types