Module: Phlex::Reactive::Inspector
- Defined in:
- lib/phlex/reactive/inspector.rb,
lib/phlex/reactive/inspector/report.rb
Overview
The ONE read-only introspection layer (issue #168), consumed by the rake
tasks (phlex_reactive:actions / find), the MCP tools, and Doctor. It
discovers every constant-backed reactive component from the loaded
Streamable registry and, per declared action, its param schema, source
location, full method-definition source (extracted with Prism), and a
heuristic authorization status.
It reports NAMES, PATHS, and declared SCHEMAS only — never tokens, secrets, or runtime state (the instrumentation privacy contract extended to tooling). Like Doctor, it is READ-ONLY: it never mounts a component, mutates state, or touches the default-deny boundary.
Phlex::Reactive::Inspector.components # => [ComponentInfo]
Phlex::Reactive::Inspector.find(query) # => ranked [ComponentInfo]
Defined Under Namespace
Modules: Report Classes: ActionInfo, ComponentInfo
Constant Summary collapse
- DEFAULT_AUTHORIZATION_METHODS =
The authorization method names the heuristic looks for. Reads Phlex::Reactive.authorization_methods when configured (issue #168 phase 2); otherwise the common set (Pundit/CanCanCan/ActionPolicy-style). The manual escape hatch
mark_authorized!always counts. %i[authorize! authorize allowed_to?].freeze
- MANUAL_AUTHORIZATION_MARK =
:mark_authorized!
Class Method Summary collapse
-
.authorization_call?(definition) ⇒ Boolean
Does the method-definition source
definitioncall an authorization method or mark_authorized! anywhere? A Prism scan for a call node whose method name is in the configured set. -
.authorization_method_names ⇒ Object
The configured authorization method names plus the manual mark, as a Set of symbols.
-
.components ⇒ Object
Every constant-backed reactive component, as [ComponentInfo].
-
.constant_backed_component?(klass) ⇒ Boolean
True when a component class is a real, CONSTANT-RESOLVABLE reactive component — its own name round-trips through safe_constantize (exactly how ActionsController#resolve_component rebuilds it from the token).
-
.find(query) ⇒ Object
Ranked fuzzy matches for
query(issue #168). - .reactive_component?(klass) ⇒ Boolean
Class Method Details
.authorization_call?(definition) ⇒ Boolean
Does the method-definition source definition call an authorization
method or mark_authorized! anywhere? A Prism scan for a call node whose
method name is in the configured set. Heuristic; degrades to false on
an unparseable snippet.
104 105 106 107 108 109 110 111 112 |
# File 'lib/phlex/reactive/inspector.rb', line 104 def (definition) result = Prism.parse(definition) return false unless result.success? names = call_names(result.value).any? { names.include?(it) } rescue StandardError false end |
.authorization_method_names ⇒ Object
The configured authorization method names plus the manual mark, as a
Set of symbols. Reads Phlex::Reactive.authorization_methods when it
exists (phase 2), else the default set. Guarded: a misconfigured
authorization_methods (nil, or a single symbol) is coerced through
Array() rather than raising .map on nil — which the caller's rescue
would swallow, silently disabling the heuristic instead of surfacing it.
120 121 122 123 124 125 126 127 128 |
# File 'lib/phlex/reactive/inspector.rb', line 120 def configured = if Phlex::Reactive.respond_to?(:authorization_methods) Phlex::Reactive. || DEFAULT_AUTHORIZATION_METHODS else DEFAULT_AUTHORIZATION_METHODS end (Array(configured).map(&:to_sym) + [MANUAL_AUTHORIZATION_MARK]).to_set end |
.components ⇒ Object
Every constant-backed reactive component, as [ComponentInfo]. Call Rails.application.eager_load! first (the caller / rake task does) so every app component is in the Streamable registry.
64 65 66 |
# File 'lib/phlex/reactive/inspector.rb', line 64 def components reactive_component_classes.map { component_info(it) } end |
.constant_backed_component?(klass) ⇒ Boolean
True when a component class is a real, CONSTANT-RESOLVABLE reactive
component — its own name round-trips through safe_constantize (exactly
how ActionsController#resolve_component rebuilds it from the token). This
also excludes anonymous classes (name nil) and fixtures that fake
def self.name without a matching constant. Moved here from Doctor
(issue #168); Doctor delegates.
88 89 90 91 92 |
# File 'lib/phlex/reactive/inspector.rb', line 88 def constant_backed_component?(klass) reactive_component?(klass) && klass.name && klass.name.safe_constantize.equal?(klass) rescue StandardError false end |
.find(query) ⇒ Object
Ranked fuzzy matches for query (issue #168). Scored on BOTH the
demodulized and the full namespaced name, best of the two:
exact > prefix > substring > subsequence, case-insensitive. Returns []
on no match. No dependency — a ~1-screen scorer.
72 73 74 75 76 77 78 79 80 |
# File 'lib/phlex/reactive/inspector.rb', line 72 def find(query) q = query.to_s.downcase return [] if q.empty? reactive_component_classes .filter_map { score_component(it, q) } .sort_by { |score, name, _klass| [-score, name] } .map { |_score, _name, klass| component_info(klass) } end |