tapioca 0.11.9 → 0.11.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/tapioca/dsl/compilers/active_record_fixtures.rb +11 -14
- data/lib/tapioca/dsl/compilers/active_record_store.rb +149 -0
- data/lib/tapioca/dsl/extensions/active_record.rb +9 -0
- data/lib/tapioca/dsl/helpers/active_record_column_type_helper.rb +3 -0
- data/lib/tapioca/dsl/helpers/active_record_constants_helper.rb +1 -0
- data/lib/tapioca/dsl/helpers/graphql_type_helper.rb +0 -2
- data/lib/tapioca/loaders/loader.rb +13 -2
- data/lib/tapioca/static/symbol_loader.rb +9 -1
- data/lib/tapioca/version.rb +1 -1
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84489402f0ea53d60251615f8b40358f946e88fd302d33d2b06adb09bfadfeb6
|
4
|
+
data.tar.gz: 34f1790682595d9f63479463c6a3e76dbff2682e40680e9d0971fb7ce3fd7de8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8defde6f57d9d373d2982e7450ac217e0ba7e3cc2402ec740b124bdd0a7e1def41bf8bc8432699029016c98c83fd0c036248879ec6532869b350facdde4a4bc5
|
7
|
+
data.tar.gz: f8225d925a796ba74424637b6b843c5a53a14fb52de6e5fcce4751a136639f3738d48373f053111cc5958ba55e3bbda055d00259b629b94cd0b80b2f4c815b44
|
@@ -73,20 +73,17 @@ module Tapioca
|
|
73
73
|
sig { returns(T::Class[ActiveRecord::TestFixtures]) }
|
74
74
|
def fixture_loader
|
75
75
|
@fixture_loader ||= T.let(
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end,
|
88
|
-
T::Class[ActiveRecord::TestFixtures],
|
89
|
-
),
|
76
|
+
Class.new do
|
77
|
+
T.unsafe(self).include(ActiveRecord::TestFixtures)
|
78
|
+
|
79
|
+
T.unsafe(self).fixture_path = Rails.root.join("test", "fixtures")
|
80
|
+
# https://github.com/rails/rails/blob/7c70791470fc517deb7c640bead9f1b47efb5539/activerecord/lib/active_record/test_fixtures.rb#L46
|
81
|
+
singleton_class.define_method(:file_fixture_path) do
|
82
|
+
Rails.root.join("test", "fixtures", "files")
|
83
|
+
end
|
84
|
+
|
85
|
+
T.unsafe(self).fixtures(:all)
|
86
|
+
end,
|
90
87
|
T.nilable(T::Class[ActiveRecord::TestFixtures]),
|
91
88
|
)
|
92
89
|
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "active_record"
|
6
|
+
rescue LoadError
|
7
|
+
return
|
8
|
+
end
|
9
|
+
|
10
|
+
require "tapioca/dsl/helpers/active_record_constants_helper"
|
11
|
+
|
12
|
+
module Tapioca
|
13
|
+
module Dsl
|
14
|
+
module Compilers
|
15
|
+
# `Tapioca::Dsl::Compilers::ActiveRecordStore` decorates RBI files for all
|
16
|
+
# classes that use [`ActiveRecord::Store`](https://api.rubyonrails.org/classes/ActiveRecord/Store.html).
|
17
|
+
#
|
18
|
+
# For example, with the following class:
|
19
|
+
#
|
20
|
+
# ~~~rb
|
21
|
+
# class User < ActiveRecord::Base
|
22
|
+
# store :settings, accessors: :theme
|
23
|
+
# store_accessor :settings, :power_source, prefix: :prefs
|
24
|
+
# end
|
25
|
+
# ~~~
|
26
|
+
#
|
27
|
+
# this compiler will produce an RBI file with the following content:
|
28
|
+
# ~~~rbi
|
29
|
+
# # typed: true
|
30
|
+
#
|
31
|
+
# class User
|
32
|
+
# include GeneratedStoredAttributesMethods
|
33
|
+
#
|
34
|
+
# module GeneratedStoredAttributesMethods
|
35
|
+
# sig { returns(T.untyped) }
|
36
|
+
# def prefs_power_source; end
|
37
|
+
#
|
38
|
+
# sig { params(value: T.untyped).returns(T.untyped) }
|
39
|
+
# def prefs_power_source=(value); end
|
40
|
+
#
|
41
|
+
# sig { returns(T.untyped) }
|
42
|
+
# def prefs_power_source_before_last_save; end
|
43
|
+
#
|
44
|
+
# sig { returns(T.untyped) }
|
45
|
+
# def prefs_power_source_change; end
|
46
|
+
#
|
47
|
+
# sig { returns(T::Boolean) }
|
48
|
+
# def prefs_power_source_changed?; end
|
49
|
+
#
|
50
|
+
# sig { returns(T.untyped) }
|
51
|
+
# def prefs_power_source_was; end
|
52
|
+
#
|
53
|
+
# sig { returns(T.untyped) }
|
54
|
+
# def saved_change_to_prefs_power_source; end
|
55
|
+
#
|
56
|
+
# sig { returns(T::Boolean) }
|
57
|
+
# def saved_change_to_prefs_power_source?; end
|
58
|
+
#
|
59
|
+
# sig { returns(T.untyped) }
|
60
|
+
# def saved_change_to_theme; end
|
61
|
+
#
|
62
|
+
# sig { returns(T::Boolean) }
|
63
|
+
# def saved_change_to_theme?; end
|
64
|
+
#
|
65
|
+
# sig { returns(T.untyped) }
|
66
|
+
# def theme; end
|
67
|
+
#
|
68
|
+
# sig { params(value: T.untyped).returns(T.untyped) }
|
69
|
+
# def theme=(value); end
|
70
|
+
#
|
71
|
+
# sig { returns(T.untyped) }
|
72
|
+
# def theme_before_last_save; end
|
73
|
+
#
|
74
|
+
# sig { returns(T.untyped) }
|
75
|
+
# def theme_change; end
|
76
|
+
#
|
77
|
+
# sig { returns(T::Boolean) }
|
78
|
+
# def theme_changed?; end
|
79
|
+
#
|
80
|
+
# sig { returns(T.untyped) }
|
81
|
+
# def theme_was; end
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
# ~~~
|
85
|
+
class ActiveRecordStore < Compiler
|
86
|
+
extend T::Sig
|
87
|
+
include Helpers::ActiveRecordConstantsHelper
|
88
|
+
|
89
|
+
ConstantType = type_member { { fixed: T.all(T.class_of(ActiveRecord::Base), Extensions::ActiveRecord) } }
|
90
|
+
|
91
|
+
sig { override.void }
|
92
|
+
def decorate
|
93
|
+
return if constant.__tapioca_stored_attributes.nil?
|
94
|
+
|
95
|
+
root.create_path(constant) do |klass|
|
96
|
+
klass.create_module(StoredAttributesModuleName) do |mod|
|
97
|
+
constant.__tapioca_stored_attributes.each do |store_attribute, keys, prefix, suffix|
|
98
|
+
accessor_prefix =
|
99
|
+
case prefix
|
100
|
+
when String, Symbol
|
101
|
+
"#{prefix}_"
|
102
|
+
when TrueClass
|
103
|
+
"#{store_attribute}_"
|
104
|
+
else
|
105
|
+
""
|
106
|
+
end
|
107
|
+
accessor_suffix =
|
108
|
+
case suffix
|
109
|
+
when String, Symbol
|
110
|
+
"_#{suffix}"
|
111
|
+
when TrueClass
|
112
|
+
"_#{store_attribute}"
|
113
|
+
else
|
114
|
+
""
|
115
|
+
end
|
116
|
+
|
117
|
+
keys.flatten.map { |key| "#{accessor_prefix}#{key}#{accessor_suffix}" }.each do |accessor_key|
|
118
|
+
mod.create_method(
|
119
|
+
"#{accessor_key}=",
|
120
|
+
parameters: [create_param("value", type: "T.untyped")],
|
121
|
+
return_type: "T.untyped",
|
122
|
+
)
|
123
|
+
mod.create_method(accessor_key, return_type: "T.untyped")
|
124
|
+
mod.create_method("#{accessor_key}_changed?", return_type: "T::Boolean")
|
125
|
+
mod.create_method("#{accessor_key}_change", return_type: "T.untyped")
|
126
|
+
mod.create_method("#{accessor_key}_was", return_type: "T.untyped")
|
127
|
+
mod.create_method("saved_change_to_#{accessor_key}?", return_type: "T::Boolean")
|
128
|
+
mod.create_method("saved_change_to_#{accessor_key}", return_type: "T.untyped")
|
129
|
+
mod.create_method("#{accessor_key}_before_last_save", return_type: "T.untyped")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
klass.create_include(StoredAttributesModuleName)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class << self
|
139
|
+
extend T::Sig
|
140
|
+
|
141
|
+
sig { override.returns(T::Enumerable[Module]) }
|
142
|
+
def gather_constants
|
143
|
+
descendants_of(::ActiveRecord::Base).reject(&:abstract_class?)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -30,6 +30,15 @@ module Tapioca
|
|
30
30
|
super
|
31
31
|
end
|
32
32
|
|
33
|
+
attr_reader :__tapioca_stored_attributes
|
34
|
+
|
35
|
+
def store_accessor(store_attribute, *keys, prefix: nil, suffix: nil)
|
36
|
+
@__tapioca_stored_attributes ||= []
|
37
|
+
@__tapioca_stored_attributes << [store_attribute, keys, prefix, suffix]
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
33
42
|
::ActiveRecord::Base.singleton_class.prepend(self)
|
34
43
|
end
|
35
44
|
end
|
@@ -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::ConnectionAdapters::PostgreSQL::OID::Uuid) &&
|
89
|
+
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Uuid
|
90
|
+
"::String"
|
88
91
|
when defined?(ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Hstore) &&
|
89
92
|
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Hstore
|
90
93
|
"T::Hash[::String, ::String]"
|
@@ -15,6 +15,7 @@ module Tapioca
|
|
15
15
|
AssociationMethodsModuleName = T.let("GeneratedAssociationMethods", String)
|
16
16
|
DelegatedTypesModuleName = T.let("GeneratedDelegatedTypeMethods", String)
|
17
17
|
SecureTokensModuleName = T.let("GeneratedSecureTokenMethods", String)
|
18
|
+
StoredAttributesModuleName = T.let("GeneratedStoredAttributesMethods", String)
|
18
19
|
|
19
20
|
RelationMethodsModuleName = T.let("GeneratedRelationMethods", String)
|
20
21
|
AssociationRelationMethodsModuleName = T.let("GeneratedAssociationRelationMethods", String)
|
@@ -47,8 +47,6 @@ module Tapioca
|
|
47
47
|
end
|
48
48
|
when GraphQL::Schema::InputObject.singleton_class
|
49
49
|
type_for_constant(unwrapped_type)
|
50
|
-
when GraphQL::Schema::NonNull.singleton_class
|
51
|
-
type_for(unwrapped_type.of_type)
|
52
50
|
when Module
|
53
51
|
Runtime::Reflection.qualified_name_of(unwrapped_type) || "T.untyped"
|
54
52
|
else
|
@@ -110,7 +110,7 @@ module Tapioca
|
|
110
110
|
autoloader = Zeitwerk::Loader.new
|
111
111
|
|
112
112
|
engines.each do |engine|
|
113
|
-
engine.
|
113
|
+
eager_load_paths(engine).each do |path|
|
114
114
|
# Zeitwerk only accepts existing directories in `push_dir`.
|
115
115
|
next unless File.directory?(path)
|
116
116
|
# We should not add directories that are already managed by a Zeitwerk loader.
|
@@ -131,7 +131,7 @@ module Tapioca
|
|
131
131
|
# We can't use `Rails::Engine#eager_load!` directly because it will raise as soon as it encounters
|
132
132
|
# an error, which is not what we want. We want to try to load as much as we can.
|
133
133
|
engines.each do |engine|
|
134
|
-
engine.
|
134
|
+
eager_load_paths(engine).each do |load_path|
|
135
135
|
Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
|
136
136
|
require_dependency file
|
137
137
|
end
|
@@ -224,6 +224,17 @@ module Tapioca
|
|
224
224
|
|
225
225
|
require(file)
|
226
226
|
end
|
227
|
+
|
228
|
+
# Rails 7.2 renamed `eager_load_paths` to `all_eager_load_paths`, which maintains the same original functionality.
|
229
|
+
# The `eager_load_paths` method still exists, but doesn't return all paths anymore and causes Tapioca to miss some
|
230
|
+
# engine paths. The following commit is the change:
|
231
|
+
# https://github.com/rails/rails/commit/ebfca905db14020589c22e6937382e6f8f687664
|
232
|
+
sig { params(engine: T.class_of(Rails::Engine)).returns(T::Array[String]) }
|
233
|
+
def eager_load_paths(engine)
|
234
|
+
config = engine.config
|
235
|
+
|
236
|
+
(config.respond_to?(:all_eager_load_paths) && config.all_eager_load_paths) || config.eager_load_paths
|
237
|
+
end
|
227
238
|
end
|
228
239
|
end
|
229
240
|
end
|
@@ -27,7 +27,15 @@ module Tapioca
|
|
27
27
|
|
28
28
|
return Set.new unless gem_engine
|
29
29
|
|
30
|
-
|
30
|
+
# https://github.com/rails/rails/commit/ebfca905db14020589c22e6937382e6f8f687664
|
31
|
+
config = gem_engine.config
|
32
|
+
eager_load_paths = if config.respond_to?(:all_eager_load_paths)
|
33
|
+
config.all_eager_load_paths
|
34
|
+
else
|
35
|
+
config.eager_load_paths
|
36
|
+
end
|
37
|
+
|
38
|
+
paths = eager_load_paths.flat_map do |load_path|
|
31
39
|
Pathname.glob("#{load_path}/**/*.rb")
|
32
40
|
end
|
33
41
|
|
data/lib/tapioca/version.rb
CHANGED
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.
|
4
|
+
version: 0.11.11
|
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: 2023-
|
14
|
+
date: 2023-11-06 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -59,22 +59,22 @@ dependencies:
|
|
59
59
|
name: rbi
|
60
60
|
requirement: !ruby/object:Gem::Requirement
|
61
61
|
requirements:
|
62
|
-
- - "~>"
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: 0.1.0
|
65
62
|
- - ">="
|
66
63
|
- !ruby/object:Gem::Version
|
67
|
-
version: 0.1.
|
64
|
+
version: 0.1.4
|
65
|
+
- - "<"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0.2'
|
68
68
|
type: :runtime
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- - "~>"
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: 0.1.0
|
75
72
|
- - ">="
|
76
73
|
- !ruby/object:Gem::Version
|
77
|
-
version: 0.1.
|
74
|
+
version: 0.1.4
|
75
|
+
- - "<"
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0.2'
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
79
|
name: sorbet-static-and-runtime
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -185,6 +185,7 @@ files:
|
|
185
185
|
- lib/tapioca/dsl/compilers/active_record_relations.rb
|
186
186
|
- lib/tapioca/dsl/compilers/active_record_scope.rb
|
187
187
|
- lib/tapioca/dsl/compilers/active_record_secure_token.rb
|
188
|
+
- lib/tapioca/dsl/compilers/active_record_store.rb
|
188
189
|
- lib/tapioca/dsl/compilers/active_record_typed_store.rb
|
189
190
|
- lib/tapioca/dsl/compilers/active_resource.rb
|
190
191
|
- lib/tapioca/dsl/compilers/active_storage.rb
|
@@ -292,7 +293,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
292
293
|
- !ruby/object:Gem::Version
|
293
294
|
version: '0'
|
294
295
|
requirements: []
|
295
|
-
rubygems_version: 3.4.
|
296
|
+
rubygems_version: 3.4.21
|
296
297
|
signing_key:
|
297
298
|
specification_version: 4
|
298
299
|
summary: A Ruby Interface file generator for gems, core types and the Ruby standard
|