tapioca 0.11.15 → 0.11.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f089694c098df2b42355826c7622448368a7f766bd44de3cd2ece4242ebc0fa
4
- data.tar.gz: 0140650be1098b51150d5a74fac1f349e9a8da6400fcc5ad3ed1e0da84fb7a91
3
+ metadata.gz: 38dec6aff4cfc2907111dda6a6ee1411d5ae7bf58f467a7e8a47094a606f7593
4
+ data.tar.gz: aa5c4ce427eb9e33513ef4b42f69572030c21be2ea12367abc1755fda0c76202
5
5
  SHA512:
6
- metadata.gz: 95bbca796e14a6af94dbbaa9f15a3cd15c46d414472b03385ab7ff6b8ab495ba885ee362e7349bbdc7ed0c60639d22fb2db52e0d901faab582fca96a93dfd408
7
- data.tar.gz: 179e7b4ef4c30819d7a3e1c3cb856b800ffc17c63d20419341002b4273b56c9cec2d9d06e03d28678275ac2c9e8e82030f7cfb2d8f5bf4bdc99ead5e361d001a
6
+ metadata.gz: 1640eb00441de0826936170a8e40010ab5bf3567329ad64e283d8cad4161a37ff16cf02cea1e41eba50816a6f315af8db69be70b65249b61b015532d86c6da05
7
+ data.tar.gz: 410060c7ef464f8fe07b28582cef2a86875fa80ff319051aaea31946cd96ad1e40b07c56165421e99b0d300ea19223a3f20756a520a2cb6bd9c76bf16abca230
@@ -0,0 +1,100 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ begin
5
+ require "action_text"
6
+ rescue LoadError
7
+ return
8
+ end
9
+
10
+ module Tapioca
11
+ module Dsl
12
+ module Compilers
13
+ # `Tapioca::Dsl::Compilers::ActionText` decorates RBI files for subclasses of
14
+ # `ActiveRecord::Base` that declare [has_rich_text](https://edgeguides.rubyonrails.org/action_text_overview.html#creating-rich-text-content)
15
+ #
16
+ # For example, with the following `ActiveRecord::Base` subclass:
17
+ #
18
+ # ~~~rb
19
+ # class Post < ApplicationRecord
20
+ # has_rich_text :body
21
+ # has_rich_text :title, encrypted: true
22
+ # end
23
+ # ~~~
24
+ #
25
+ # this compiler will produce the RBI file `post.rbi` with the following content:
26
+ #
27
+ # ~~~rbi
28
+ # # typed: strong
29
+ #
30
+ # class Post
31
+ # sig { returns(ActionText::RichText) }
32
+ # def body; end
33
+ #
34
+ # sig { params(value: T.nilable(T.any(ActionText::RichText, String))).returns(T.untyped) }
35
+ # def body=(value); end
36
+ #
37
+ # sig { returns(T::Boolean) }
38
+ # def body?; end
39
+ #
40
+ # sig { returns(ActionText::EncryptedRichText) }
41
+ # def title; end
42
+ #
43
+ # sig { params(value: T.nilable(T.any(ActionText::EncryptedRichText, String))).returns(T.untyped) }
44
+ # def title=(value); end
45
+ #
46
+ # sig { returns(T::Boolean) }
47
+ # def title?; end
48
+ # end
49
+ # ~~~
50
+ class ActionText < Compiler
51
+ extend T::Sig
52
+
53
+ ConstantType = type_member { { fixed: T.class_of(::ActiveRecord::Base) } }
54
+
55
+ sig { override.void }
56
+ def decorate
57
+ root.create_path(constant) do |scope|
58
+ self.class.action_text_associations(constant).each do |name|
59
+ reflection = constant.reflections.fetch(name)
60
+ type = reflection.options.fetch(:class_name)
61
+ name = reflection.name.to_s.sub("rich_text_", "")
62
+ scope.create_method(
63
+ name,
64
+ return_type: type,
65
+ )
66
+ scope.create_method(
67
+ "#{name}?",
68
+ return_type: "T::Boolean",
69
+ )
70
+ scope.create_method(
71
+ "#{name}=",
72
+ parameters: [create_param("value", type: "T.nilable(T.any(#{type}, String))")],
73
+ return_type: "T.untyped",
74
+ )
75
+ end
76
+ end
77
+ end
78
+
79
+ class << self
80
+ extend T::Sig
81
+
82
+ sig { params(constant: T.class_of(::ActiveRecord::Base)).returns(T::Array[String]) }
83
+ def action_text_associations(constant)
84
+ # Implementation copied from https://github.com/rails/rails/blob/31052d0e518b9da103eea2f79d250242ed1e3705/actiontext/lib/action_text/attribute.rb#L66
85
+ constant.reflect_on_all_associations(:has_one)
86
+ .map(&:name).map(&:to_s)
87
+ .select { |n| n.start_with?("rich_text_") }
88
+ end
89
+
90
+ sig { override.returns(T::Enumerable[Module]) }
91
+ def gather_constants
92
+ descendants_of(::ActiveRecord::Base)
93
+ .reject(&:abstract_class?)
94
+ .select { |c| action_text_associations(c).any? }
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -83,6 +83,7 @@ module Tapioca
83
83
  end
84
84
  def perform_later_parameters(parameters, constant_name)
85
85
  if ::Gem::Requirement.new(">= 7.0").satisfied_by?(::ActiveJob.gem_version)
86
+ parameters.reject! { |typed_param| RBI::BlockParam === typed_param.param }
86
87
  parameters + [create_block_param(
87
88
  "block",
88
89
  type: "T.nilable(T.proc.params(job: #{constant_name}).void)",
@@ -55,7 +55,10 @@ module Tapioca
55
55
  root.create_path(constant) do |input_object|
56
56
  arguments.each do |argument|
57
57
  name = argument.keyword.to_s
58
- input_object.create_method(name, return_type: Helpers::GraphqlTypeHelper.type_for(argument, constant))
58
+ input_object.create_method(
59
+ name,
60
+ return_type: Helpers::GraphqlTypeHelper.type_for_argument(argument, constant),
61
+ )
59
62
  end
60
63
  end
61
64
  end
@@ -76,7 +76,7 @@ module Tapioca
76
76
  def argument_type(argument, constant)
77
77
  return "T.untyped" unless argument
78
78
 
79
- Helpers::GraphqlTypeHelper.type_for(argument, constant)
79
+ Helpers::GraphqlTypeHelper.type_for_argument(argument, constant)
80
80
  end
81
81
 
82
82
  class << self
@@ -85,6 +85,9 @@ module Tapioca
85
85
  "::String"
86
86
  when ActiveRecord::Type::Serialized
87
87
  serialized_column_type(column_type)
88
+ when defined?(ActiveRecord::Normalization::NormalizedValueType) &&
89
+ ActiveRecord::Normalization::NormalizedValueType
90
+ type_for_activerecord_value(column_type.cast_type)
88
91
  when defined?(ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Uuid) &&
89
92
  ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Uuid
90
93
  "::String"
@@ -15,7 +15,7 @@ module Tapioca
15
15
  constant: T.any(T.class_of(GraphQL::Schema::Mutation), T.class_of(GraphQL::Schema::InputObject)),
16
16
  ).returns(String)
17
17
  end
18
- def type_for(argument, constant)
18
+ def type_for_argument(argument, constant)
19
19
  type = if argument.loads
20
20
  loads_type = ::GraphQL::Schema::Wrapper.new(argument.loads)
21
21
  loads_type = loads_type.to_list_type if argument.type.list?
@@ -25,6 +25,36 @@ module Tapioca
25
25
  argument.type
26
26
  end
27
27
 
28
+ prepare = argument.prepare
29
+ prepare_method = if prepare
30
+ if constant.respond_to?(prepare)
31
+ constant.method(prepare)
32
+ end
33
+ end
34
+
35
+ type_for(
36
+ type,
37
+ ignore_nilable_wrapper: has_replaceable_default?(argument),
38
+ prepare_method: prepare_method,
39
+ )
40
+ end
41
+
42
+ sig do
43
+ params(
44
+ type: T.any(
45
+ GraphQL::Schema::Wrapper,
46
+ T.class_of(GraphQL::Schema::Scalar),
47
+ T.class_of(GraphQL::Schema::Enum),
48
+ T.class_of(GraphQL::Schema::Union),
49
+ T.class_of(GraphQL::Schema::Object),
50
+ T.class_of(GraphQL::Schema::Interface),
51
+ T.class_of(GraphQL::Schema::InputObject),
52
+ ),
53
+ ignore_nilable_wrapper: T::Boolean,
54
+ prepare_method: T.nilable(Method),
55
+ ).returns(String)
56
+ end
57
+ def type_for(type, ignore_nilable_wrapper: false, prepare_method: nil)
28
58
  unwrapped_type = type.unwrap
29
59
 
30
60
  parsed_type = case unwrapped_type
@@ -65,14 +95,11 @@ module Tapioca
65
95
  "T.untyped"
66
96
  end
67
97
 
68
- if argument.prepare.is_a?(Symbol) || argument.prepare.is_a?(String)
69
- if constant.respond_to?(argument.prepare)
70
- prepare_method = constant.method(argument.prepare)
71
- prepare_signature = Runtime::Reflection.signature_of(prepare_method)
72
-
73
- if valid_return_type?(prepare_signature&.return_type)
74
- parsed_type = prepare_signature.return_type&.to_s
75
- end
98
+ if prepare_method
99
+ prepare_signature = Runtime::Reflection.signature_of(prepare_method)
100
+ prepare_return_type = prepare_signature&.return_type
101
+ if valid_return_type?(prepare_return_type)
102
+ parsed_type = prepare_return_type&.to_s
76
103
  end
77
104
  end
78
105
 
@@ -80,7 +107,7 @@ module Tapioca
80
107
  parsed_type = "T::Array[#{parsed_type}]"
81
108
  end
82
109
 
83
- unless type.non_null? || has_replaceable_default?(argument)
110
+ unless type.non_null? || ignore_nilable_wrapper
84
111
  parsed_type = RBIHelper.as_nilable_type(parsed_type)
85
112
  end
86
113
 
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Tapioca
5
- VERSION = "0.11.15"
5
+ VERSION = "0.11.16"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tapioca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.15
4
+ version: 0.11.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ufuk Kayserilioglu
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2024-01-08 00:00:00.000000000 Z
14
+ date: 2024-01-12 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -173,6 +173,7 @@ files:
173
173
  - lib/tapioca/dsl/compilers/aasm.rb
174
174
  - lib/tapioca/dsl/compilers/action_controller_helpers.rb
175
175
  - lib/tapioca/dsl/compilers/action_mailer.rb
176
+ - lib/tapioca/dsl/compilers/action_text.rb
176
177
  - lib/tapioca/dsl/compilers/active_job.rb
177
178
  - lib/tapioca/dsl/compilers/active_model_attributes.rb
178
179
  - lib/tapioca/dsl/compilers/active_model_secure_password.rb