Module: StandardId::Config::CallableValidator

Defined in:
lib/standard_id/config/callable_validator.rb

Overview

Validates that callables configured on StandardId.config have signatures the engine can actually invoke. Runs once during Rails boot from the engine’s ‘config.after_initialize` block. On mismatch, raises ConfigurationError with a message naming the offending field.

What “matches” means:

  • Positional callables: a configured proc/lambda/method ref must accept the exact number of positional arguments the engine will pass. A lambda with all-optional/splat params (arity < 0) is accepted so long as it can plausibly be called with that many positional args.

  • Keyword callables (custom_claims, claim_resolvers): the callable is invoked via CallableParameterFilter which slices the context hash to the callable’s declared keyword parameters. So keyword callables pass validation as long as every declared keyword name is one the engine actually provides — otherwise the call would ‘ArgumentError` at runtime.

Scope: only validates top-level StandardId.config fields plus the hash entries under ‘oauth.claim_resolvers`. Does NOT modify the StandardConfig DSL (the gem’s schema doesn’t need to know about this).

Constant Summary collapse

CALLABLE_FIELDS =

Each entry: field_path => { signature: “(a, b, c)”, arity: Integer, kind: :positional | :keyword, keywords: [..] } Field path is the method chain on StandardId.config, e.g. “after_sign_in” or “oauth.custom_claims”.

{
  "profile_resolver"        => { signature: "(account, profile_type)",            arity: 2, kind: :positional },
  "sentry_context"          => { signature: "(account, session)",                 arity: 2, kind: :positional },
  "after_account_created"   => { signature: "(account, request, context)",        arity: 3, kind: :positional },
  "before_sign_in"          => { signature: "(account, request, context)",        arity: 3, kind: :positional },
  "after_sign_in"           => { signature: "(account, request, context)",        arity: 3, kind: :positional },
  "passwordless.username_validator" => { signature: "(username, connection_type)", arity: 2, kind: :positional },
  "passwordless.account_factory"    => {
    signature: "(identifier:, params:, request:)",
    kind: :keyword,
    keywords: %i[identifier params request]
  },
  "oauth.custom_claims" => {
    signature: "(account:, client:, request:, audience:)",
    kind: :keyword,
    keywords: %i[account client request audience]
  }
}.freeze
CLAIM_RESOLVER_KEYWORDS =

Keys available to claim_resolvers callables at invocation time.

%i[client account request audience].freeze

Class Method Summary collapse

Class Method Details

.validate!(config = StandardId.config) ⇒ Object



50
51
52
53
54
55
56
57
58
59
# File 'lib/standard_id/config/callable_validator.rb', line 50

def validate!(config = StandardId.config)
  CALLABLE_FIELDS.each do |path, spec|
    callable = fetch(config, path)
    next if callable.nil?
    next unless callable.respond_to?(:call)
    validate_callable!(path, callable, spec)
  end

  validate_claim_resolvers!(config)
end