fino-solid 1.4.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2a58a6b231e01407c065d6512bf369ff01b59cf31e8a4572a0f5b10c6f713ae1
4
+ data.tar.gz: 60a3d6bcceb5803271a61756aa0c466ebc3463e4356143118438d145427084d0
5
+ SHA512:
6
+ metadata.gz: 11e09a0f69092545b9ff9c97f47e55660c823d4774aa34f878bb6a2f15db4669b7bf9974479a3c8a93ec301071942673ec0204d42d998f75fac0ec97aba3be2c
7
+ data.tar.gz: bab475d8c0590a1475fa096b25f60d161c2f0acd4fba7dfed42ad72e2c8a8233470cb1556286917c44b53f3571f17f53a94fc7aa0ef54d0a34ab4f1b5f755336
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Egor Iskrenkov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,196 @@
1
+ # Fino
2
+
3
+ ⚠️ Fino in active development phase at wasn't properly battle tested in production just yet. Give us a star and stay tuned for Production test results and new features
4
+
5
+ Fino is a dynamic settings engine for Ruby and Rails
6
+
7
+ ## Usage
8
+
9
+ ### Define settings via DSL
10
+
11
+ ```ruby
12
+ require "fino-redis"
13
+
14
+ Fino.configure do
15
+ adapter do
16
+ Fino::Redis::Adapter.new(
17
+ Redis.new(**Rails.application.config_for(:redis))
18
+ )
19
+ end
20
+
21
+ cache { Fino::Cache::Memory.new(expires_in: 3.seconds) }
22
+
23
+ settings do
24
+ setting :maintenance_mode, :boolean, default: false
25
+
26
+ setting :api_rate_limit,
27
+ :integer,
28
+ default: 1000,
29
+ description: "Maximum API requests per minute per user to prevent abuse"
30
+
31
+ section :openai, label: "OpenAI" do
32
+ setting :model,
33
+ :string,
34
+ default: "gpt-5",
35
+ description: "OpenAI model"
36
+
37
+ setting :temperature,
38
+ :float,
39
+ default: 0.7,
40
+ description: "Model temperature"
41
+ end
42
+
43
+ section :feature_toggles, label: "Feature Toggles" do
44
+ setting :new_ui, :boolean, default: true
45
+ setting :beta_functionality, :boolean, default: false
46
+ end
47
+
48
+ section :my_micro_service, label: "My Micro Service" do
49
+ setting :http_read_timeout, :integer, default: 200 # in ms
50
+ setting :http_open_timeout, :integer, default: 100 # in ms
51
+ end
52
+ end
53
+ end
54
+ ```
55
+
56
+ ### Work with settings
57
+
58
+ ```ruby
59
+ Fino.value(:model, at: :openai) #=> "gpt-5"
60
+ Fino.value(:temperature, at: :openai) #=> 0.7
61
+
62
+ Fino.values(:model, :temperature, at: :openai) #=> ["gpt-4", 0.7]
63
+
64
+ Fino.set(model: "gpt-5", at: :openai)
65
+ Fino.value(:model, at: :openai) #=> "gpt-5"
66
+ ```
67
+
68
+ ### Overrides
69
+
70
+ ```ruby
71
+ Fino.value(:model, at: :openai) #=> "gpt-5"
72
+
73
+ Fino.set(model: "gpt-5", at: :openai, overrides: { "qa" => "our_local_model_not_to_pay_to_sam_altman" })
74
+
75
+ Fino.value(:model, at: :openai) #=> "gpt-5"
76
+ Fino.value(:model, at: :openai, for: "qa") #=> "our_local_model_not_to_pay_to_sam_altman"
77
+ ```
78
+
79
+ ### A/B testing
80
+
81
+ ```ruby
82
+ Fino.value(:model, at: :openai) #=> "gpt-5"
83
+
84
+ # "gpt-5" becomes the control variant value and a 20.0% variant is created with value "gpt-6"
85
+ Fino.set(model: "gpt-5", at: :openai, variants: { 20.0 => "gpt-6" })
86
+
87
+ Fino.setting(:model, at: :openai).experiment.variant(for: "user_1") #=> #<Fino::AbTesting::Variant percentage: 20.0, value: "gpt-6">
88
+
89
+ # Picked variant is sticked to the user
90
+ Fino.value(:model, at: :openai, for: "user_1") #=> "gpt-6"
91
+ Fino.value(:model, at: :openai, for: "user_1") #=> "gpt-6"
92
+
93
+ Fino.value(:model, at: :openai, for: "user_2") #=> "gpt-5"
94
+ ```
95
+
96
+ ## Rails integration
97
+
98
+ Fino easily integrates with Rails. Just add the gem to your Gemfile:
99
+
100
+ ```
101
+ gem "fino-rails", require: false
102
+ ```
103
+
104
+ to get built-in UI engine for your settings!
105
+
106
+ ### UI engine
107
+
108
+ Mount Fino Rails engine in your `config/routes.rb`:
109
+
110
+ ```ruby
111
+ Rails.application.routes.draw do
112
+ mount Fino::Rails::Engine, at: "/fino"
113
+ end
114
+ ```
115
+
116
+ ### Configuration
117
+
118
+ ```ruby
119
+ Rails.application.configure do
120
+ config.fino.instrument = true
121
+ config.fino.log = true
122
+ config.fino.cache_within_request = false
123
+ config.fino.preload_before_request = true
124
+ end
125
+ ```
126
+
127
+ <img width="1493" height="676" alt="Screenshot 2025-09-19 at 13 09 06" src="https://github.com/user-attachments/assets/19b6147a-e18c-41cf-aac7-99111efcc9d5" />
128
+
129
+ <img width="1775" height="845" alt="Screenshot 2025-09-19 at 13 09 33" src="https://github.com/user-attachments/assets/c0010abd-285d-43d0-ae5d-ce0edb781309" />
130
+
131
+ ## Performance tweaks
132
+
133
+ 1. In Memory cache
134
+
135
+ Fino provides in-memory settings caching functionality which will store settings received from adaper in memory for
136
+ a very quick access. As this kind of cache is not distributed between machines, but belongs to each process
137
+ separately, it's impossible to invalidate all at once, so be aware that setting update application time will depend
138
+ on cache TTL you configure
139
+
140
+ ```ruby
141
+ Fino.configure do
142
+ # ...
143
+ cache { Fino::Cache::Memory.new(expires_in: 3.seconds) }
144
+ # ...
145
+ end
146
+ ```
147
+
148
+ 2. Request scoped cache
149
+
150
+ When using Fino in Rails context it's possible to cache settings within request, in current thread storage. This is
151
+ safe way to cache settings as it's lifetime is limited, thus it is enabled by default
152
+
153
+ ```ruby
154
+ Rails.application.configure do
155
+ config.fino.cache_within_request = true
156
+ end
157
+ ```
158
+
159
+ 3. Preloading
160
+
161
+ In Rails context it is possible to tell Fino to preload multiple settings before processing request in a single
162
+ adapter call. Preloading is recommended for requests that use multiple different settings in their logic
163
+
164
+ ```ruby
165
+ # Preload all settings
166
+ Rails.application.configure do
167
+ config.fino.preload_before_request = true
168
+ end
169
+
170
+ # Preload specific subset of settings depending on request
171
+ Rails.application.configure do
172
+ config.fino.preload_before_request = ->(request) {
173
+ case request.path
174
+ when "request/using/all/settings"
175
+ true
176
+ when "request/not/using/settings"
177
+ false
178
+ when "request/using/specific/settings"
179
+ [
180
+ :api_rate_limit,
181
+ openai: [:model, :temperature]
182
+ ]
183
+ end
184
+ }
185
+ end
186
+ ```
187
+
188
+ ## Releasing
189
+
190
+ `rake release`
191
+
192
+ ## Contributing
193
+
194
+ 1. Fork it
195
+ 2. Do contribution
196
+ 6. Create Pull Request into this repo
@@ -0,0 +1,284 @@
1
+ # Fino::Solid
2
+
3
+ ActiveRecord adapter for [Fino](https://github.com/eiskrenkov/fino) settings engine, inspired by solid_queue.
4
+
5
+ ## Features
6
+
7
+ - **Database-backed persistence** using ActiveRecord
8
+ - **Efficient read performance** with single-table design
9
+ - **Multi-database support** (SQLite, PostgreSQL, MySQL)
10
+ - **Rails integration** with migration generators
11
+ - **Supports all Fino features**: overrides, A/B testing, sections
12
+ - **Thread-safe** and production-ready
13
+
14
+ ## Installation
15
+
16
+ Add to your Gemfile:
17
+
18
+ ```ruby
19
+ gem "fino-solid"
20
+ ```
21
+
22
+ Then run:
23
+
24
+ ```bash
25
+ bundle install
26
+ ```
27
+
28
+ ## Setup
29
+
30
+ ### Rails Applications
31
+
32
+ 1. Generate the migration:
33
+
34
+ ```bash
35
+ bin/rails generate fino:solid:install
36
+ ```
37
+
38
+ 2. Run the migration:
39
+
40
+ ```bash
41
+ bin/rails db:migrate
42
+ ```
43
+
44
+ 3. Configure Fino to use the Solid adapter:
45
+
46
+ ```ruby
47
+ # config/initializers/fino.rb
48
+ require "fino-solid"
49
+
50
+ Fino.configure do
51
+ adapter { Fino::Solid::Adapter.new }
52
+
53
+ settings do
54
+ setting :maintenance_mode, :boolean, default: false
55
+ # ... your settings
56
+ end
57
+ end
58
+ ```
59
+
60
+ ### Non-Rails Applications
61
+
62
+ 1. Create the migration manually:
63
+
64
+ ```ruby
65
+ class CreateFinoSettings < ActiveRecord::Migration[7.0]
66
+ def change
67
+ create_table :fino_settings do |t|
68
+ t.string :key, null: false
69
+ t.text :data
70
+ t.timestamps
71
+ end
72
+
73
+ add_index :fino_settings, :key, unique: true
74
+ end
75
+ end
76
+ ```
77
+
78
+ 2. Configure the adapter:
79
+
80
+ ```ruby
81
+ require "fino-solid"
82
+ require "active_record"
83
+
84
+ ActiveRecord::Base.establish_connection(
85
+ adapter: "sqlite3",
86
+ database: "db/fino.sqlite3"
87
+ )
88
+
89
+ Fino.configure do
90
+ adapter { Fino::Solid::Adapter.new }
91
+
92
+ settings do
93
+ # ... your settings
94
+ end
95
+ end
96
+ ```
97
+
98
+ ## Configuration
99
+
100
+ ### Multi-Database Setup
101
+
102
+ If you're using Rails multi-database configuration (like solid_queue), you can configure Fino::Solid to use a specific database:
103
+
104
+ ```ruby
105
+ # config/initializers/fino.rb
106
+ Fino::Solid.configure do
107
+ self.connects_to = { database: { writing: :settings } }
108
+ end
109
+ ```
110
+
111
+ Then configure your database.yml:
112
+
113
+ ```yaml
114
+ production:
115
+ primary:
116
+ <<: *default
117
+ database: my_app_production
118
+ settings:
119
+ <<: *default
120
+ database: my_app_settings_production
121
+ migrations_paths: db/settings_migrate
122
+ ```
123
+
124
+ ## Database Schema
125
+
126
+ The adapter uses a simple, efficient single-table design:
127
+
128
+ ```ruby
129
+ create_table :fino_settings do |t|
130
+ t.string :key, null: false # "api_rate_limit" or "openai/model"
131
+ t.text :data # JSON: {"v": "value", "s/scope/v": "override", ...}
132
+ t.timestamps
133
+ end
134
+
135
+ add_index :fino_settings, :key, unique: true
136
+ ```
137
+
138
+ ### Data Structure
139
+
140
+ Settings are stored as JSON with this structure:
141
+
142
+ ```json
143
+ {
144
+ "v": "serialized_value",
145
+ "s/qa/v": "override_for_qa_scope",
146
+ "s/admin/v": "override_for_admin_scope",
147
+ "v/20.0/v": "variant_value_for_20_percent",
148
+ "v/30.0/v": "variant_value_for_30_percent"
149
+ }
150
+ ```
151
+
152
+ This mirrors the Redis adapter structure for consistency.
153
+
154
+ ## Performance
155
+
156
+ ### Read Performance
157
+
158
+ - **Single setting**: 1 query (`SELECT * FROM fino_settings WHERE key = ?`)
159
+ - **Multiple settings**: 1 query (`SELECT * FROM fino_settings WHERE key IN (?, ?, ?)`)
160
+ - **All settings**: 1 query (`SELECT * FROM fino_settings`)
161
+
162
+ ### Write Performance
163
+
164
+ - Uses ActiveRecord's `upsert` for atomic write operations
165
+ - Single transaction per setting update
166
+
167
+ ### Optimization Tips
168
+
169
+ 1. **Use in-memory cache** to reduce database queries:
170
+
171
+ ```ruby
172
+ Fino.configure do
173
+ adapter { Fino::Solid::Adapter.new }
174
+ cache { Fino::Cache::Memory.new(expires_in: 3.seconds) }
175
+ end
176
+ ```
177
+
178
+ 2. **Batch reads** with `read_multi`:
179
+
180
+ ```ruby
181
+ # In Rails:
182
+ Fino.values(:maintenance_mode, :api_rate_limit) # 1 query instead of 2
183
+ ```
184
+
185
+ 3. **Preload settings** in Rails:
186
+
187
+ ```ruby
188
+ Rails.application.configure do
189
+ config.fino.preload_before_request = true
190
+ end
191
+ ```
192
+
193
+ ## Supported Databases
194
+
195
+ - **SQLite** 3.38+ (with JSON support)
196
+ - **PostgreSQL** 9.4+ (with JSON/JSONB)
197
+ - **MySQL** 5.7+ (with JSON support)
198
+
199
+ ## Examples
200
+
201
+ ### Basic Usage
202
+
203
+ ```ruby
204
+ # Set a value
205
+ Fino.set(api_rate_limit: 1000)
206
+
207
+ # Read a value
208
+ Fino.value(:api_rate_limit) # => 1000
209
+ ```
210
+
211
+ ### With Overrides
212
+
213
+ ```ruby
214
+ # Set value with scope overrides
215
+ Fino.set(
216
+ api_rate_limit: 1000,
217
+ overrides: {
218
+ "premium" => 5000,
219
+ "enterprise" => 10000
220
+ }
221
+ )
222
+
223
+ # Read with scope
224
+ Fino.value(:api_rate_limit) # => 1000
225
+ Fino.value(:api_rate_limit, for: "premium") # => 5000
226
+ Fino.value(:api_rate_limit, for: "enterprise") # => 10000
227
+ ```
228
+
229
+ ### With A/B Testing
230
+
231
+ ```ruby
232
+ # Create an experiment
233
+ Fino.set(
234
+ api_rate_limit: 1000,
235
+ variants: {
236
+ 20.0 => 2000, # 20% of users get 2000
237
+ 30.0 => 3000 # 30% of users get 3000
238
+ }
239
+ # Remaining 50% get control value (1000)
240
+ )
241
+
242
+ # Users are deterministically assigned to variants
243
+ Fino.value(:api_rate_limit, for: "user_123") # => 2000 (always same)
244
+ Fino.value(:api_rate_limit, for: "user_456") # => 1000 (control)
245
+ ```
246
+
247
+ ## Comparison with Redis Adapter
248
+
249
+ | Feature | Fino::Solid | Fino::Redis |
250
+ |---------|-------------|-------------|
251
+ | Persistence | SQL Database | Redis |
252
+ | Read Performance | Excellent (indexed) | Excellent (in-memory) |
253
+ | Write Performance | Good (ACID) | Excellent |
254
+ | Durability | ACID compliant | Depends on Redis config |
255
+ | Multi-database | Native support | Namespace support |
256
+ | Backup/Restore | Standard DB tools | Redis tools |
257
+ | Query Flexibility | SQL available | Limited |
258
+ | Setup Complexity | Low (Rails) | Medium |
259
+
260
+ ## Testing
261
+
262
+ The gem includes comprehensive integration tests using shared examples:
263
+
264
+ ```bash
265
+ # Run Solid adapter tests
266
+ bundle exec rspec spec/integration/solid_adapter_spec.rb
267
+
268
+ # Test all databases
269
+ DATABASE=sqlite bundle exec rspec spec/integration/solid_adapter_spec.rb
270
+ DATABASE=postgresql bundle exec rspec spec/integration/solid_adapter_spec.rb
271
+ DATABASE=mysql bundle exec rspec spec/integration/solid_adapter_spec.rb
272
+ ```
273
+
274
+ ## Contributing
275
+
276
+ 1. Fork it
277
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
278
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
279
+ 4. Push to the branch (`git push origin my-new-feature`)
280
+ 5. Create new Pull Request
281
+
282
+ ## License
283
+
284
+ MIT
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fino
4
+ module Solid
5
+ class Adapter
6
+ include Fino::Adapter
7
+
8
+ SCOPE_PREFIX = "s"
9
+ VARIANT_PREFIX = "v"
10
+ VALUE_KEY = "v"
11
+
12
+ def read(setting_key)
13
+ setting = Fino::Solid::Setting.find_by(key: setting_key)
14
+ setting&.data || {}
15
+ end
16
+
17
+ def read_multi(setting_keys)
18
+ settings_by_key = Fino::Solid::Setting.where(key: setting_keys).index_by(&:key)
19
+
20
+ setting_keys.map { |key| settings_by_key[key]&.data || {} }
21
+ end
22
+
23
+ def write(setting_definition, value, overrides, variants)
24
+ serialize_value = ->(raw_value) { setting_definition.type_class.serialize(raw_value) }
25
+
26
+ data = { VALUE_KEY => serialize_value.call(value) }
27
+
28
+ overrides.each do |scope, scope_value|
29
+ data["#{SCOPE_PREFIX}/#{scope}/#{VALUE_KEY}"] = serialize_value.call(scope_value)
30
+ end
31
+
32
+ variants.each do |variant|
33
+ next if variant.value == Fino::AbTesting::Variant::CONTROL_VALUE
34
+
35
+ data["#{VARIANT_PREFIX}/#{variant.percentage}/#{VALUE_KEY}"] = serialize_value.call(variant.value)
36
+ end
37
+
38
+ Fino::Solid::Setting.upsert(
39
+ { key: setting_definition.key, data: data },
40
+ unique_by: :key
41
+ )
42
+ end
43
+
44
+ def read_persisted_setting_keys
45
+ Fino::Solid::Setting.pluck(:key)
46
+ end
47
+
48
+ def clear(setting_key)
49
+ Fino::Solid::Setting.where(key: setting_key).delete_all > 0
50
+ end
51
+
52
+ def fetch_value_from(raw_adapter_data)
53
+ raw_adapter_data.key?(VALUE_KEY) ? raw_adapter_data.delete(VALUE_KEY) : Fino::EMPTINESS
54
+ end
55
+
56
+ def fetch_raw_overrides_from(raw_adapter_data)
57
+ raw_adapter_data.each_with_object({}) do |(key, value), memo|
58
+ next unless key.start_with?("#{SCOPE_PREFIX}/")
59
+
60
+ scope = key.split("/", 3)[1]
61
+ memo[scope] = value
62
+ end
63
+ end
64
+
65
+ def fetch_raw_variants_from(raw_adapter_data)
66
+ raw_adapter_data.each_with_object([]) do |(key, value), memo|
67
+ next unless key.start_with?("#{VARIANT_PREFIX}/")
68
+
69
+ percentage = key.split("/", 3)[1]
70
+
71
+ memo << { percentage: percentage.to_f, value: value }
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Installs Fino::Solid adapter by creating necessary database migration.
3
+
4
+ Example:
5
+ bin/rails generate fino:solid:install
6
+
7
+ This will create:
8
+ db/migrate/[timestamp]_create_fino_settings.rb
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+ require "rails/generators/active_record"
5
+
6
+ module Fino
7
+ module Solid
8
+ module Generators
9
+ class InstallGenerator < ::Rails::Generators::Base
10
+ include ::ActiveRecord::Generators::Migration
11
+
12
+ source_root File.expand_path("templates", __dir__)
13
+
14
+ def copy_migration
15
+ migration_template "create_fino_settings.rb.tt", File.join(db_migrate_path, "create_fino_settings.rb")
16
+ end
17
+
18
+ private
19
+
20
+ def db_migrate_path
21
+ "db/migrate"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ class CreateFinoSettings < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
2
+ def change
3
+ create_table :fino_settings do |t|
4
+ t.string :key, null: false
5
+ t.text :data
6
+
7
+ t.timestamps
8
+ end
9
+
10
+ add_index :fino_settings, :key, unique: true
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fino
4
+ module Solid
5
+ class Railtie < ::Rails::Railtie
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fino
4
+ module Solid
5
+ class Record < ActiveRecord::Base
6
+ self.abstract_class = true
7
+
8
+ connects_to(**Fino::Solid.connects_to) if Fino::Solid.connects_to
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fino
4
+ module Solid
5
+ class Setting < Record
6
+ self.table_name = "fino_settings"
7
+
8
+ serialize :data, coder: JSON
9
+
10
+ validates :key, presence: true, uniqueness: true
11
+ end
12
+ end
13
+ end
data/lib/fino/solid.rb ADDED
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+
5
+ module Fino
6
+ module Solid
7
+ mattr_accessor :connects_to
8
+
9
+ class << self
10
+ def configure(&block)
11
+ instance_eval(&block)
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ require "fino/solid/record"
18
+ require "fino/solid/setting"
19
+ require "fino/solid/adapter"
20
+ require "fino/solid/railtie" if defined?(Rails::Railtie)
21
+
22
+ if defined?(Rails) && defined?(Rails::Generators)
23
+ require "rails/generators"
24
+ require_relative "solid/generators/install/install_generator"
25
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fino
4
+ VERSION = "1.4.0"
5
+ REQUIRED_RUBY_VERSION = ">= 3.0.0"
6
+ end
data/lib/fino-solid.rb ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fino"
4
+ require "fino/solid"
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fino-solid
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Egor Iskrenkov
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: fino
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 1.4.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.4.0
26
+ - !ruby/object:Gem::Dependency
27
+ name: activerecord
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '6.1'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '6.1'
40
+ - !ruby/object:Gem::Dependency
41
+ name: sqlite3
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '1.4'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '1.4'
54
+ - !ruby/object:Gem::Dependency
55
+ name: pg
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '1.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '1.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: mysql2
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0.5'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0.5'
82
+ email:
83
+ - egor@iskrenkov.me
84
+ executables: []
85
+ extensions: []
86
+ extra_rdoc_files: []
87
+ files:
88
+ - LICENSE
89
+ - README.md
90
+ - lib/fino-solid.rb
91
+ - lib/fino/solid.rb
92
+ - lib/fino/solid/README.md
93
+ - lib/fino/solid/adapter.rb
94
+ - lib/fino/solid/generators/install/USAGE
95
+ - lib/fino/solid/generators/install/install_generator.rb
96
+ - lib/fino/solid/generators/install/templates/create_fino_settings.rb.tt
97
+ - lib/fino/solid/railtie.rb
98
+ - lib/fino/solid/record.rb
99
+ - lib/fino/solid/setting.rb
100
+ - lib/fino/version.rb
101
+ homepage: https://github.com/eiskrenkov/fino
102
+ licenses:
103
+ - MIT
104
+ metadata:
105
+ source_code_uri: https://github.com/eiskrenkov/fino
106
+ bug_tracker_uri: https://github.com/eiskrenkov/fino/issues
107
+ rubygems_mfa_required: 'true'
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: 3.0.0
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubygems_version: 3.6.9
123
+ specification_version: 4
124
+ summary: ActiveRecord adapter for Fino settings engine
125
+ test_files: []