tapioca_dsl_compiler_store_model 0.1.0
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 +7 -0
- data/README.md +151 -0
- data/Rakefile +10 -0
- data/lib/tapioca/dsl/compilers/store_model.rb +203 -0
- data/lib/tapioca_dsl_compiler_store_model/version.rb +5 -0
- data/lib/tapioca_dsl_compiler_store_model.rb +14 -0
- data/tapioca_dsl_compiler_store_model.gemspec +40 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8599b4a2721338d14a30ce4662dfe880eec4b11b2cee175b4fb23f59e7057c13
|
4
|
+
data.tar.gz: e8076445bf9f432bfe2b6fc667235037c9af89b5d2f9ea64979526190fe03835
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f4f26d03579f5c9a75a6c6816562e756391bf6b99b50fb3a086e6a1dbd1e36095daa26477ed266a473802f06360704ba5c28c303a7f1817981d0ad4afd7d1445
|
7
|
+
data.tar.gz: 1306687309250806d06ef63b9b9cac7e705e96fe97a4abc53670f98b0e5aa1075c805c9c99f423e00093fcf000881c202bfb2a4d00c7fd091f33a271c820ff81
|
data/README.md
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
# Tapioca DSL Compiler for StoreModel
|
2
|
+
|
3
|
+
A [Tapioca](https://github.com/Shopify/tapioca) DSL compiler that generates RBI files for [StoreModel](https://github.com/DmitryTsepelev/store_model) attributes in ActiveRecord models.
|
4
|
+
|
5
|
+
StoreModel adds JSON-backed attributes to ActiveRecord models, and this gem provides Sorbet type signatures for the methods that StoreModel dynamically generates.
|
6
|
+
|
7
|
+
## Features
|
8
|
+
|
9
|
+
- **Automatic RBI Generation**: Generates Sorbet RBI files for StoreModel attributes
|
10
|
+
- **Comprehensive Type Coverage**: Supports both single and array StoreModel types
|
11
|
+
- **Build Methods**: Generates signatures for `build_*` methods created by StoreModel
|
12
|
+
- **Tapioca Integration**: Follows Tapioca's standard compiler patterns and is automatically discovered
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Add this line to your application's Gemfile:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
gem 'tapioca_dsl_compiler_store_model'
|
20
|
+
```
|
21
|
+
|
22
|
+
And then execute:
|
23
|
+
|
24
|
+
```bash
|
25
|
+
$ bundle install
|
26
|
+
```
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
```bash
|
31
|
+
$ gem install tapioca_dsl_compiler_store_model
|
32
|
+
```
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
Once installed, Tapioca will automatically discover and use the `Tapioca::Dsl::Compilers::StoreModel` compiler when generating RBI files for ActiveRecord models that use StoreModel attributes.
|
37
|
+
|
38
|
+
### Example
|
39
|
+
|
40
|
+
Given the following StoreModel setup:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
# app/models/user_settings.rb
|
44
|
+
class UserSettings
|
45
|
+
include StoreModel::Model
|
46
|
+
|
47
|
+
attribute :theme, :string
|
48
|
+
attribute :notifications, :boolean
|
49
|
+
attribute :language, :string
|
50
|
+
end
|
51
|
+
|
52
|
+
# app/models/preference.rb
|
53
|
+
class Preference
|
54
|
+
include StoreModel::Model
|
55
|
+
|
56
|
+
attribute :key, :string
|
57
|
+
attribute :value, :string
|
58
|
+
end
|
59
|
+
|
60
|
+
# app/models/user.rb
|
61
|
+
class User < ActiveRecord::Base
|
62
|
+
attribute :settings, UserSettings.to_type
|
63
|
+
attribute :preferences, Preference.to_array_type
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
Running `bundle exec tapioca dsl` will generate the following RBI file:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
# sorbet/rbi/dsl/user.rbi
|
71
|
+
# typed: strong
|
72
|
+
|
73
|
+
class User
|
74
|
+
sig { returns(T.nilable(UserSettings)) }
|
75
|
+
def settings; end
|
76
|
+
|
77
|
+
sig { params(value: T.nilable(T.any(UserSettings, T::Hash[T.untyped, T.untyped]))).returns(T.nilable(UserSettings)) }
|
78
|
+
def settings=(value); end
|
79
|
+
|
80
|
+
sig { params(attributes: T::Hash[T.untyped, T.untyped]).returns(UserSettings) }
|
81
|
+
def build_settings(attributes: {}); end
|
82
|
+
|
83
|
+
sig { returns(T::Array[Preference]) }
|
84
|
+
def preferences; end
|
85
|
+
|
86
|
+
sig { params(value: T.nilable(T.any(T::Array[Preference], T::Array[T::Hash[T.untyped, T.untyped]]))).returns(T::Array[Preference]) }
|
87
|
+
def preferences=(value); end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
### Supported StoreModel Types
|
92
|
+
|
93
|
+
This compiler supports all StoreModel attribute types:
|
94
|
+
|
95
|
+
- **Single Models**: `Model.to_type` - generates getter, setter, and builder methods
|
96
|
+
- **Array Models**: `Model.to_array_type` - generates getter and setter methods for arrays
|
97
|
+
- **Nested Models**: StoreModel classes that contain other StoreModel attributes
|
98
|
+
|
99
|
+
### Generated Methods
|
100
|
+
|
101
|
+
For each StoreModel attribute, the compiler generates type signatures for:
|
102
|
+
|
103
|
+
1. **Getter method**: Returns the StoreModel instance or array
|
104
|
+
2. **Setter method**: Accepts StoreModel instance(s) or Hash(es)
|
105
|
+
3. **Builder method** (single types only): Creates a new instance with given attributes
|
106
|
+
|
107
|
+
## Limitations
|
108
|
+
|
109
|
+
Currently, this compiler has the following limitations:
|
110
|
+
|
111
|
+
- **Enum Support**: Does not generate RBI signatures for enum methods (e.g., predicate methods like `active?`, bang methods like `status_active!`)
|
112
|
+
- **Nested Attributes**: Does not support `accepts_nested_attributes_for` generated methods
|
113
|
+
- **Custom Types**: Only supports `StoreModel::Types::One` and `StoreModel::Types::Many`, custom types are not detected
|
114
|
+
- **Validation Methods**: Does not generate signatures for StoreModel validation methods
|
115
|
+
|
116
|
+
These features may be added in future versions.
|
117
|
+
|
118
|
+
## Requirements
|
119
|
+
|
120
|
+
- Ruby 2.7+
|
121
|
+
- [Tapioca](https://github.com/Shopify/tapioca) 0.10+
|
122
|
+
- [StoreModel](https://github.com/DmitryTsepelev/store_model) 1.0+
|
123
|
+
- ActiveRecord 6.0+
|
124
|
+
|
125
|
+
## Development
|
126
|
+
|
127
|
+
After checking out the repo, run:
|
128
|
+
|
129
|
+
```bash
|
130
|
+
$ bundle install
|
131
|
+
```
|
132
|
+
|
133
|
+
To run the test suite:
|
134
|
+
|
135
|
+
```bash
|
136
|
+
$ bundle exec rspec
|
137
|
+
```
|
138
|
+
|
139
|
+
To run the linter:
|
140
|
+
|
141
|
+
```bash
|
142
|
+
$ bundle exec rubocop
|
143
|
+
```
|
144
|
+
|
145
|
+
## Contributing
|
146
|
+
|
147
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/speria-jp/tapioca_dsl_compiler_store_model.
|
148
|
+
|
149
|
+
## License
|
150
|
+
|
151
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Tapioca DSL Compiler for StoreModel
|
4
|
+
module Tapioca
|
5
|
+
module Dsl
|
6
|
+
module Compilers
|
7
|
+
class StoreModel < Tapioca::Dsl::Compiler
|
8
|
+
ConstantType = type_member { { fixed: T.class_of(ActiveRecord::Base) } }
|
9
|
+
|
10
|
+
sig { override.returns(T::Enumerable[Module]) }
|
11
|
+
def self.gather_constants
|
12
|
+
return [] unless defined?(::StoreModel)
|
13
|
+
|
14
|
+
::ActiveRecord::Base.descendants.select do |klass|
|
15
|
+
next false unless klass.respond_to?(:attribute_types)
|
16
|
+
|
17
|
+
# Skip classes that can't load their schema or attributes
|
18
|
+
begin
|
19
|
+
attribute_types = klass.attribute_types
|
20
|
+
rescue ActiveRecord::TableNotSpecified, StandardError
|
21
|
+
next false
|
22
|
+
end
|
23
|
+
|
24
|
+
# Check if any attribute types are StoreModel types
|
25
|
+
attribute_types.values.any? { |type| store_model_type?(type) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
sig { override.void }
|
30
|
+
def decorate
|
31
|
+
root.create_path(constant) do |klass|
|
32
|
+
create_store_model_methods(klass)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
sig { params(type: T.untyped).returns(T::Boolean) }
|
37
|
+
def self.store_model_type?(type)
|
38
|
+
return true if type.is_a?(::StoreModel::Types::One)
|
39
|
+
return true if type.is_a?(::StoreModel::Types::Many)
|
40
|
+
return true if store_model_class_type?(type)
|
41
|
+
return true if store_model_one_of_type?(type)
|
42
|
+
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
sig { params(type: T.untyped).returns(T::Boolean) }
|
47
|
+
def self.store_model_class_type?(type)
|
48
|
+
return false unless type.respond_to?(:model_klass)
|
49
|
+
|
50
|
+
model_klass = type.model_klass
|
51
|
+
return false if model_klass.nil?
|
52
|
+
|
53
|
+
model_klass.include?(::StoreModel::Model)
|
54
|
+
end
|
55
|
+
|
56
|
+
sig { params(type: T.untyped).returns(T::Boolean) }
|
57
|
+
def self.store_model_one_of_type?(type)
|
58
|
+
# Check for StoreModel.one_of types (polymorphic types)
|
59
|
+
return true if type.is_a?(::StoreModel::Types::OnePolymorphic)
|
60
|
+
return true if type.is_a?(::StoreModel::Types::ManyPolymorphic)
|
61
|
+
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
sig { params(mod: T.untyped).void }
|
68
|
+
def create_store_model_methods(mod)
|
69
|
+
constant.attribute_types.each do |attribute_name, type|
|
70
|
+
next unless self.class.store_model_type?(type)
|
71
|
+
|
72
|
+
create_attribute_methods(mod, attribute_name, type)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
sig { params(mod: T.untyped, attribute_name: String, type: T.untyped).void }
|
77
|
+
def create_attribute_methods(mod, attribute_name, type)
|
78
|
+
case type
|
79
|
+
when ::StoreModel::Types::One
|
80
|
+
create_single_store_model_methods(mod, attribute_name, type.model_klass)
|
81
|
+
when ::StoreModel::Types::Many
|
82
|
+
create_many_store_model_methods(mod, attribute_name, type.model_klass)
|
83
|
+
else
|
84
|
+
if self.class.store_model_one_of_type?(type)
|
85
|
+
create_one_of_store_model_methods(mod, attribute_name, type)
|
86
|
+
else
|
87
|
+
create_fallback_store_model_methods(mod, attribute_name, type)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
sig { params(mod: T.untyped, attribute_name: String, type: T.untyped).void }
|
93
|
+
def create_fallback_store_model_methods(mod, attribute_name, type)
|
94
|
+
return unless type.respond_to?(:model_klass)
|
95
|
+
return unless type.model_klass&.include?(::StoreModel::Model)
|
96
|
+
|
97
|
+
if array_type?(type)
|
98
|
+
create_many_store_model_methods(mod, attribute_name, type.model_klass)
|
99
|
+
else
|
100
|
+
create_single_store_model_methods(mod, attribute_name, type.model_klass)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
sig { params(type: T.untyped).returns(T::Boolean) }
|
105
|
+
def array_type?(type)
|
106
|
+
type_name = type.class.name
|
107
|
+
type_name&.include?("Many") || type_name&.include?("Array")
|
108
|
+
end
|
109
|
+
|
110
|
+
sig { params(mod: T.untyped, attribute_name: String, type: T.untyped).void }
|
111
|
+
def create_one_of_store_model_methods(mod, attribute_name, type)
|
112
|
+
# OneOf types have dynamic model selection, so we use more generic types
|
113
|
+
if array_type?(type)
|
114
|
+
create_one_of_array_methods(mod, attribute_name)
|
115
|
+
else
|
116
|
+
create_one_of_single_methods(mod, attribute_name)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
sig { params(mod: T.untyped, attribute_name: String).void }
|
121
|
+
def create_one_of_single_methods(mod, attribute_name)
|
122
|
+
# OneOf types are dynamically resolved, so we use generic StoreModel::Model types
|
123
|
+
mod.create_method(
|
124
|
+
attribute_name,
|
125
|
+
return_type: "T.nilable(StoreModel::Model)"
|
126
|
+
)
|
127
|
+
|
128
|
+
mod.create_method(
|
129
|
+
"#{attribute_name}=",
|
130
|
+
parameters: [create_param("value",
|
131
|
+
type: "T.nilable(T.any(StoreModel::Model, T::Hash[T.untyped, T.untyped]))")],
|
132
|
+
return_type: "T.nilable(StoreModel::Model)"
|
133
|
+
)
|
134
|
+
|
135
|
+
mod.create_method(
|
136
|
+
"build_#{attribute_name}",
|
137
|
+
parameters: [create_kw_opt_param("attributes", type: "T::Hash[T.untyped, T.untyped]", default: "{}")],
|
138
|
+
return_type: "StoreModel::Model"
|
139
|
+
)
|
140
|
+
end
|
141
|
+
|
142
|
+
sig { params(mod: T.untyped, attribute_name: String).void }
|
143
|
+
def create_one_of_array_methods(mod, attribute_name)
|
144
|
+
# OneOf array types are dynamically resolved
|
145
|
+
mod.create_method(
|
146
|
+
attribute_name,
|
147
|
+
return_type: "T::Array[StoreModel::Model]"
|
148
|
+
)
|
149
|
+
|
150
|
+
mod.create_method(
|
151
|
+
"#{attribute_name}=",
|
152
|
+
parameters: [create_param("value",
|
153
|
+
type: "T.nilable(T.any(T::Array[StoreModel::Model], " \
|
154
|
+
"T::Array[T::Hash[T.untyped, T.untyped]]))")],
|
155
|
+
return_type: "T::Array[StoreModel::Model]"
|
156
|
+
)
|
157
|
+
end
|
158
|
+
|
159
|
+
sig { params(mod: T.untyped, attribute_name: String, model_klass: T.untyped).void }
|
160
|
+
def create_single_store_model_methods(mod, attribute_name, model_klass)
|
161
|
+
return_type = model_klass.name
|
162
|
+
|
163
|
+
mod.create_method(
|
164
|
+
attribute_name,
|
165
|
+
return_type: "T.nilable(#{return_type})"
|
166
|
+
)
|
167
|
+
|
168
|
+
mod.create_method(
|
169
|
+
"#{attribute_name}=",
|
170
|
+
parameters: [create_param("value",
|
171
|
+
type: "T.nilable(T.any(#{return_type}, T::Hash[T.untyped, T.untyped]))")],
|
172
|
+
return_type: "T.nilable(#{return_type})"
|
173
|
+
)
|
174
|
+
|
175
|
+
mod.create_method(
|
176
|
+
"build_#{attribute_name}",
|
177
|
+
parameters: [create_kw_opt_param("attributes", type: "T::Hash[T.untyped, T.untyped]", default: "{}")],
|
178
|
+
return_type: return_type
|
179
|
+
)
|
180
|
+
end
|
181
|
+
|
182
|
+
sig { params(mod: T.untyped, attribute_name: String, model_klass: T.untyped).void }
|
183
|
+
def create_many_store_model_methods(mod, attribute_name, model_klass)
|
184
|
+
return_type = model_klass.name
|
185
|
+
array_type = "T::Array[#{return_type}]"
|
186
|
+
|
187
|
+
mod.create_method(
|
188
|
+
attribute_name,
|
189
|
+
return_type: array_type
|
190
|
+
)
|
191
|
+
|
192
|
+
mod.create_method(
|
193
|
+
"#{attribute_name}=",
|
194
|
+
parameters: [create_param("value",
|
195
|
+
type: "T.nilable(T.any(#{array_type}, " \
|
196
|
+
"T::Array[T::Hash[T.untyped, T.untyped]]))")],
|
197
|
+
return_type: array_type
|
198
|
+
)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "tapioca_dsl_compiler_store_model/version"
|
4
|
+
|
5
|
+
# Conditionally load required dependencies
|
6
|
+
begin
|
7
|
+
require "tapioca/dsl"
|
8
|
+
require "store_model"
|
9
|
+
rescue LoadError
|
10
|
+
# Do nothing if dependencies are not available
|
11
|
+
end
|
12
|
+
|
13
|
+
# Only load implementation when both Tapioca::Dsl::Compiler and StoreModel are available
|
14
|
+
require_relative "tapioca/dsl/compilers/store_model" if defined?(Tapioca::Dsl::Compiler) && defined?(StoreModel)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/tapioca_dsl_compiler_store_model/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "tapioca_dsl_compiler_store_model"
|
7
|
+
spec.version = TapiocaDslCompilerStoreModel::VERSION
|
8
|
+
spec.authors = ["speria-jp"]
|
9
|
+
|
10
|
+
spec.summary = "Tapioca DSL compiler for StoreModel"
|
11
|
+
spec.description = "Provides Tapioca DSL compiler for generating RBI files for StoreModel gem"
|
12
|
+
spec.homepage = "https://github.com/speria-jp/tapioca_dsl_compiler_store_model"
|
13
|
+
spec.email = ["daichi.sakai@speria.jp"]
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 3.2.0"
|
16
|
+
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
19
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
20
|
+
|
21
|
+
spec.files = Dir.chdir(__dir__) do
|
22
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
23
|
+
(File.expand_path(f) == __FILE__) ||
|
24
|
+
f.start_with?("test/", "spec/", "features/") ||
|
25
|
+
f.start_with?(".github/") ||
|
26
|
+
f == ".gitignore" ||
|
27
|
+
f == ".rspec" ||
|
28
|
+
f == ".rubocop.yml" ||
|
29
|
+
f == "Gemfile" ||
|
30
|
+
f == "Gemfile.lock" ||
|
31
|
+
f == "CLAUDE.md"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
spec.bindir = "exe"
|
35
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
36
|
+
spec.require_paths = ["lib"]
|
37
|
+
|
38
|
+
spec.add_dependency "store_model", ">= 1.0.0"
|
39
|
+
spec.add_dependency "tapioca", ">= 0.11.0"
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tapioca_dsl_compiler_store_model
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- speria-jp
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: store_model
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 1.0.0
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 1.0.0
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: tapioca
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.11.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.11.0
|
40
|
+
description: Provides Tapioca DSL compiler for generating RBI files for StoreModel
|
41
|
+
gem
|
42
|
+
email:
|
43
|
+
- daichi.sakai@speria.jp
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- README.md
|
49
|
+
- Rakefile
|
50
|
+
- lib/tapioca/dsl/compilers/store_model.rb
|
51
|
+
- lib/tapioca_dsl_compiler_store_model.rb
|
52
|
+
- lib/tapioca_dsl_compiler_store_model/version.rb
|
53
|
+
- tapioca_dsl_compiler_store_model.gemspec
|
54
|
+
homepage: https://github.com/speria-jp/tapioca_dsl_compiler_store_model
|
55
|
+
licenses:
|
56
|
+
- MIT
|
57
|
+
metadata:
|
58
|
+
homepage_uri: https://github.com/speria-jp/tapioca_dsl_compiler_store_model
|
59
|
+
source_code_uri: https://github.com/speria-jp/tapioca_dsl_compiler_store_model
|
60
|
+
rubygems_mfa_required: 'true'
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.2.0
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubygems_version: 3.6.7
|
76
|
+
specification_version: 4
|
77
|
+
summary: Tapioca DSL compiler for StoreModel
|
78
|
+
test_files: []
|