From a65c1768fb11321c32876ac4a79b9c04f0923699 Mon Sep 17 00:00:00 2001 From: Kirill Mokevnin Date: Wed, 2 Sep 2026 13:43:51 -0400 Subject: [PATCH 1/2] Add annotations for the alba gem Alba ships no Sorbet signatures, so tapioca emits its `Alba::Resource` DSL macros sig-less. Annotate the class-level macros used to define a resource. Co-Authored-By: Claude Opus 5 (1M context) --- index.json | 1 + rbi/annotations/alba.rbi | 173 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 rbi/annotations/alba.rbi diff --git a/index.json b/index.json index e215752d..7c27b90f 100644 --- a/index.json +++ b/index.json @@ -46,6 +46,7 @@ "active_support/test_case" ] }, + "alba": {}, "aws-sdk-acm": { "dependencies": [ "nokogiri" diff --git a/rbi/annotations/alba.rbi b/rbi/annotations/alba.rbi new file mode 100644 index 00000000..0b049a8c --- /dev/null +++ b/rbi/annotations/alba.rbi @@ -0,0 +1,173 @@ +# typed: true + +module Alba::Resource::ClassMethods + sig do + params( + name: T.any(String, Symbol), + condition: T.nilable(Proc), + resource: T.nilable(T.any(Module, String, Proc)), + serializer: T.nilable(T.any(Module, String, Proc)), + source: T.nilable(Proc), + key: T.nilable(T.any(String, Symbol)), + with_traits: T.nilable(T.any(Symbol, T::Array[Symbol])), + params: T::Hash[T.untyped, T.untyped], + options: T.untyped, + block: T.nilable(T.proc.bind(T.untyped).void), + ).void + end + def association(name, condition = nil, resource: nil, serializer: nil, source: nil, key: nil, with_traits: nil, params: T.unsafe(nil), **options, &block); end + + sig do + params( + name: T.nilable(T.any(String, Symbol)), + if: T.nilable(T.any(Symbol, Proc)), + name_with_type: T.untyped, + block: T.proc.bind(T.untyped).params(object: T.untyped).returns(T.untyped), + ).void + end + def attribute(name = nil, if: nil, **name_with_type, &block); end + + sig do + params( + attrs: T.any(String, Symbol), + if: T.nilable(T.any(Symbol, Proc)), + attrs_with_types: T.untyped, + ).void + end + def attributes(*attrs, if: nil, **attrs_with_types); end + + sig { params(key: T.any(String, Symbol)).void } + def collection_key(key); end + + sig do + params( + name: T.any(String, Symbol), + condition: T.nilable(Proc), + resource: T.nilable(T.any(Module, String, Proc)), + serializer: T.nilable(T.any(Module, String, Proc)), + source: T.nilable(Proc), + key: T.nilable(T.any(String, Symbol)), + with_traits: T.nilable(T.any(Symbol, T::Array[Symbol])), + params: T::Hash[T.untyped, T.untyped], + options: T.untyped, + block: T.nilable(T.proc.bind(T.untyped).void), + ).void + end + def has_many(name, condition = nil, resource: nil, serializer: nil, source: nil, key: nil, with_traits: nil, params: T.unsafe(nil), **options, &block); end + + sig do + params( + name: T.any(String, Symbol), + condition: T.nilable(Proc), + resource: T.nilable(T.any(Module, String, Proc)), + serializer: T.nilable(T.any(Module, String, Proc)), + source: T.nilable(Proc), + key: T.nilable(T.any(String, Symbol)), + with_traits: T.nilable(T.any(Symbol, T::Array[Symbol])), + params: T::Hash[T.untyped, T.untyped], + options: T.untyped, + block: T.nilable(T.proc.bind(T.untyped).void), + ).void + end + def has_one(name, condition = nil, resource: nil, serializer: nil, source: nil, key: nil, with_traits: nil, params: T.unsafe(nil), **options, &block); end + + sig { params(mod: Module, block: T.nilable(T.proc.bind(T.untyped).void)).void } + def helper(mod = T.unsafe(nil), &block); end + + sig { params(file: T.nilable(String), inline: T.nilable(Proc)).void } + def layout(file: nil, inline: nil); end + + sig do + params( + name: T.any(String, Symbol), + condition: T.nilable(Proc), + resource: T.nilable(T.any(Module, String, Proc)), + serializer: T.nilable(T.any(Module, String, Proc)), + source: T.nilable(Proc), + key: T.nilable(T.any(String, Symbol)), + with_traits: T.nilable(T.any(Symbol, T::Array[Symbol])), + params: T::Hash[T.untyped, T.untyped], + options: T.untyped, + block: T.nilable(T.proc.bind(T.untyped).void), + ).void + end + def many(name, condition = nil, resource: nil, serializer: nil, source: nil, key: nil, with_traits: nil, params: T.unsafe(nil), **options, &block); end + + sig do + params( + key: T.nilable(T.any(String, Symbol)), + block: T.nilable(T.proc.bind(T.untyped).returns(T::Hash[T.untyped, T.untyped])), + ).void + end + def meta(key = :meta, &block); end + + sig do + params( + name: T.any(String, Symbol), + options: T.untyped, + block: T.proc.bind(T.untyped).void, + ).void + end + def nested(name, **options, &block); end + + sig do + params( + name: T.any(String, Symbol), + options: T.untyped, + block: T.proc.bind(T.untyped).void, + ).void + end + def nested_attribute(name, **options, &block); end + + sig do + params( + handler: T.nilable(Symbol), + block: T.nilable(T.proc.params(error: T.untyped, object: T.untyped, key: T.untyped, attribute: T.untyped, resource_class: T.untyped).returns(T::Array[T.untyped])), + ).void + end + def on_error(handler = nil, &block); end + + sig do + params( + block: T.nilable(T.proc.bind(T.untyped).params(object: T.untyped, key: T.untyped, attribute: T.untyped).returns(T.untyped)), + ).void + end + def on_nil(&block); end + + sig do + params( + name: T.any(String, Symbol), + condition: T.nilable(Proc), + resource: T.nilable(T.any(Module, String, Proc)), + serializer: T.nilable(T.any(Module, String, Proc)), + source: T.nilable(Proc), + key: T.nilable(T.any(String, Symbol)), + with_traits: T.nilable(T.any(Symbol, T::Array[Symbol])), + params: T::Hash[T.untyped, T.untyped], + options: T.untyped, + block: T.nilable(T.proc.bind(T.untyped).void), + ).void + end + def one(name, condition = nil, resource: nil, serializer: nil, source: nil, key: nil, with_traits: nil, params: T.unsafe(nil), **options, &block); end + + sig { void } + def prefer_object_method!; end + + sig { void } + def prefer_resource_method!; end + + sig { params(key: T.any(String, Symbol), key_for_collection: T.nilable(T.any(String, Symbol))).void } + def root_key(key, key_for_collection = nil); end + + sig { void } + def root_key!; end + + sig { params(key: T.any(String, Symbol)).void } + def root_key_for_collection(key); end + + sig { params(name: T.any(String, Symbol), block: T.proc.bind(T.untyped).void).void } + def trait(name, &block); end + + sig { params(type: T.any(String, Symbol), root: T::Boolean, cascade: T::Boolean).void } + def transform_keys(type, root: true, cascade: true); end +end From d63f6273f425c40463b665c0cddaee1649261ec4 Mon Sep 17 00:00:00 2001 From: Kirill Mokevnin Date: Wed, 9 Sep 2026 14:02:11 -0400 Subject: [PATCH 2/2] Tighten alba association resource types and on_error block return Address review: resource:/serializer: take a resource class, not any Module, on association and all four aliases; the on_error handler's return value is passed through as-is, so it is not an Array. Co-Authored-By: Claude Opus 5 (1M context) --- rbi/annotations/alba.rbi | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/rbi/annotations/alba.rbi b/rbi/annotations/alba.rbi index 0b049a8c..3764ed43 100644 --- a/rbi/annotations/alba.rbi +++ b/rbi/annotations/alba.rbi @@ -5,8 +5,8 @@ module Alba::Resource::ClassMethods params( name: T.any(String, Symbol), condition: T.nilable(Proc), - resource: T.nilable(T.any(Module, String, Proc)), - serializer: T.nilable(T.any(Module, String, Proc)), + resource: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), + serializer: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), source: T.nilable(Proc), key: T.nilable(T.any(String, Symbol)), with_traits: T.nilable(T.any(Symbol, T::Array[Symbol])), @@ -43,8 +43,8 @@ module Alba::Resource::ClassMethods params( name: T.any(String, Symbol), condition: T.nilable(Proc), - resource: T.nilable(T.any(Module, String, Proc)), - serializer: T.nilable(T.any(Module, String, Proc)), + resource: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), + serializer: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), source: T.nilable(Proc), key: T.nilable(T.any(String, Symbol)), with_traits: T.nilable(T.any(Symbol, T::Array[Symbol])), @@ -59,8 +59,8 @@ module Alba::Resource::ClassMethods params( name: T.any(String, Symbol), condition: T.nilable(Proc), - resource: T.nilable(T.any(Module, String, Proc)), - serializer: T.nilable(T.any(Module, String, Proc)), + resource: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), + serializer: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), source: T.nilable(Proc), key: T.nilable(T.any(String, Symbol)), with_traits: T.nilable(T.any(Symbol, T::Array[Symbol])), @@ -81,8 +81,8 @@ module Alba::Resource::ClassMethods params( name: T.any(String, Symbol), condition: T.nilable(Proc), - resource: T.nilable(T.any(Module, String, Proc)), - serializer: T.nilable(T.any(Module, String, Proc)), + resource: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), + serializer: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), source: T.nilable(Proc), key: T.nilable(T.any(String, Symbol)), with_traits: T.nilable(T.any(Symbol, T::Array[Symbol])), @@ -122,7 +122,7 @@ module Alba::Resource::ClassMethods sig do params( handler: T.nilable(Symbol), - block: T.nilable(T.proc.params(error: T.untyped, object: T.untyped, key: T.untyped, attribute: T.untyped, resource_class: T.untyped).returns(T::Array[T.untyped])), + block: T.nilable(T.proc.params(error: T.untyped, object: T.untyped, key: T.untyped, attribute: T.untyped, resource_class: T.untyped).returns(T.untyped)), ).void end def on_error(handler = nil, &block); end @@ -138,8 +138,8 @@ module Alba::Resource::ClassMethods params( name: T.any(String, Symbol), condition: T.nilable(Proc), - resource: T.nilable(T.any(Module, String, Proc)), - serializer: T.nilable(T.any(Module, String, Proc)), + resource: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), + serializer: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), source: T.nilable(Proc), key: T.nilable(T.any(String, Symbol)), with_traits: T.nilable(T.any(Symbol, T::Array[Symbol])),