Class: StandardId::ProviderRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/standard_id/provider_registry.rb

Defined Under Namespace

Classes: InvalidProviderError, ProviderNotFoundError

Class Method Summary collapse

Class Method Details

.allHash

Get all registered providers

Returns:

  • (Hash)

    Provider name => class mapping



104
105
106
# File 'lib/standard_id/provider_registry.rb', line 104

def all
  providers.each_pair.to_h
end

.declare_config_schema(provider_class) ⇒ Object

Declare one provider's config fields against the social scope.

Thread-safe and idempotent — adding the same field twice is a no-op.

add_field is retroactive: ConfigSchema::Scope#validate! and #[] both consult the schema live (the latter falling back to field_for(...).default_value for an unwritten key), so declaring a field after StandardId.config has been built works exactly as if it had been declared before. That is what makes the existing host-side after_initialize wrappers keep working untouched.

Parameters:

  • provider_class (Class)

    Provider implementation class



80
81
82
83
84
85
86
87
88
89
# File 'lib/standard_id/provider_registry.rb', line 80

def declare_config_schema(provider_class)
  return unless provider_class.respond_to?(:config_schema)

  schema = provider_class.config_schema
  return if schema.nil? || schema.empty?

  schema.each do |field_name, options|
    StandardId::ConfigSchema.add_field(scope: :social, name: field_name, **options)
  end
end

.declare_config_schemas!Array<Class>

Declare the social config fields of every provider class that has been LOADED, whether or not it has been registered yet.

Called by a core Engine initializer that runs before: :load_config_initializers — see StandardId::Engine. It exists because provider plugins register themselves from their Railtie's config.after_initialize, which runs long AFTER the host's config/initializers/standard_id.rb. A host initializer writing c.social.google_client_id therefore hit Scope#[]=validate! before the field existed and raised StandardId::ConfigurationError, with nothing in the message to suggest the cause was ordering. Every consuming app that used a provider plugin independently discovered the same Rails.application.config.after_initialize { ... } wrapper to work around it.

This is safe to do early because provider classes are required at gem-require time (require "standard_id/google/providers/google" in the plugin's entry file), so Providers::Base.subclasses is already populated before any initializer runs.

Only FIELD DECLARATION moves earlier. Full register — which also runs validate_provider! and the provider's setup — deliberately stays in after_initialize, where the host's configuration is complete and setup can rely on it.

Idempotent: ConfigSchema#add_field uses compute_if_absent, so a field already declared here is untouched when the plugin later calls register.

Returns:

  • (Array<Class>)

    the provider classes whose fields were declared



55
56
57
# File 'lib/standard_id/provider_registry.rb', line 55

def declare_config_schemas!
  provider_classes.each { |provider_class| declare_config_schema(provider_class) }
end

.get(name) ⇒ Class

Get provider by name

Parameters:

  • name (Symbol, String)

    Provider identifier

Returns:

  • (Class)

    Provider class

Raises:



95
96
97
98
99
100
# File 'lib/standard_id/provider_registry.rb', line 95

def get(name)
  providers[name.to_s] || raise(
    ProviderNotFoundError,
    "Unknown provider: #{name}. Available providers: #{providers.keys.join(', ')}"
  )
end

.provider_classesArray<Class>

Provider classes known to the process: every loaded subclass of Providers::Base, plus anything already registered (a registered class need not be a direct subclass).

Returns:

  • (Array<Class>)


64
65
66
# File 'lib/standard_id/provider_registry.rb', line 64

def provider_classes
  (StandardId::Providers::Base.subclasses + providers.values).uniq
end

.providersObject



11
12
13
# File 'lib/standard_id/provider_registry.rb', line 11

def providers
  @providers
end

.register(name, provider_class) ⇒ Object

Register a provider

Parameters:

  • name (Symbol, String)

    Provider identifier

  • provider_class (Class)

    Provider implementation class



18
19
20
21
22
23
24
# File 'lib/standard_id/provider_registry.rb', line 18

def register(name, provider_class)
  validate_provider!(provider_class)
  providers[name.to_s] = provider_class
  declare_config_schema(provider_class)
  provider_class.setup if provider_class.respond_to?(:setup)
  provider_class
end

.registered?(name) ⇒ Boolean

Check if provider is registered

Parameters:

  • name (Symbol, String)

    Provider identifier

Returns:

  • (Boolean)


111
112
113
# File 'lib/standard_id/provider_registry.rb', line 111

def registered?(name)
  providers.key?(name.to_s)
end