dexkit 0.4.1 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c6f6f437fc7f7726b58232820e6f1afd65c5adf674f51c4be07944a43d92a58b
4
- data.tar.gz: 13046423e606ff6e000b6d557ce468efa94d0f13d8aa36530dc5ae69a688e097
3
+ metadata.gz: 4a120052500fd0c1889117f87d0d4260b40eecbc82b31ad50b9e6fc97f99efd9
4
+ data.tar.gz: f140a685dd0825fbd675f5575d1a44d5679598ad7a2d302a65a3f22bae268ce0
5
5
  SHA512:
6
- metadata.gz: d48748c521d0e0c298ab78230797f7a22e45ae194fee6669f0f99669ea0ac1333b59158a8068211319694cbd073660f298babdb0a784b251444b579b898ba1c0
7
- data.tar.gz: 4a574717aa7d2f5f5de9d192b86d7a6151d5b1a8cd2bba04c79e933cb2768e5c4d7cd05d91e22cf3ca9973cfca59467cd1a6972df8626ce90971ca9fec2a365d
6
+ metadata.gz: f2186829d67bb0c19d71e9a81021a94efc56cb90dc943d11ad62a9306833ed08183691eb3196fc8dec950dcd3e7a624be5e67eda00abb3e74a444404b7947267
7
+ data.tar.gz: 5314488039b706abbbf68bc3ca7fb3e2445718286a2b21ce7346dfae60f8cdb5ca68f89369b3b54fe1a756826e95a76f22bac973d75494a10c4605e8210e1d94
data/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## 0.5.0 - 2026-03-05
4
+
5
+ ### Added
6
+
7
+ - **Verified Mongoid support** — operations (transactions, recording, async) and queries now have dedicated Mongoid test coverage running against a MongoDB replica set
8
+ - **CI workflow for Mongoid** — GitHub Actions matrix includes a MongoDB replica-set job that runs Mongoid-specific tests
9
+
10
+ ### Breaking
11
+
12
+ - **`after_commit` now always defers** — non-transactional operations queue callbacks in memory and flush them after the operation pipeline succeeds, matching the behavior of transactional operations. Previously, `after_commit` fired immediately inline when no transaction was active — code that relied on immediate execution (e.g., reading side effects of the callback later in `perform`) must account for the new deferred timing. Callbacks are discarded on `error!` or exception. Nested operations flush once at the outermost successful boundary. Ambient database transactions (e.g., `ActiveRecord::Base.transaction { op.call }`) are still respected via the adapter.
13
+
14
+ ### Fixed
15
+
16
+ - **Mongoid async recording** — `record_id` is now serialized with `.to_s` so BSON::ObjectId values pass through ActiveJob correctly
17
+ - **Mongoid transaction adapter** — simplified nesting logic; the outermost `Mongoid.transaction` block now reliably owns callback flushing, fixing edge cases where nested rollbacks could leak callbacks
18
+
19
+ ## [0.4.1] - 2026-03-04
20
+
21
+ ### Added
22
+
23
+ - **`after_commit` in operations** — `after_commit { ... }` defers a block until the surrounding database transaction commits
24
+ - ActiveRecord adapter uses `ActiveRecord.after_all_transactions_commit` (requires Rails 7.2+)
25
+ - Mongoid adapter manually tracks callbacks and fires them after the outermost `Mongoid.transaction` commits
26
+ - If called outside a transaction, the block executes immediately
27
+
28
+ ## [0.4.0] - 2026-03-04
29
+
30
+ ### Added
31
+
32
+ - **Query objects** — `Dex::Query` base class for encapsulating database queries with filtering, sorting, and parameter binding
33
+ - Typed properties via `prop`/`prop?` DSL (same as Operation and Event)
34
+ - `scope { Model.all }` DSL for declaring the base scope
35
+ - **Filter DSL** — `filter :name, :strategy` with built-in strategies: `eq`, `not_eq`, `contains`, `starts_with`, `ends_with`, `gt`, `gte`, `lt`, `lte`, `in`, `not_in`
36
+ - Custom filter blocks: `filter(:name) { |scope, value| ... }`
37
+ - Optional filters (nilable props) are automatically skipped when `nil`
38
+ - **Sort DSL** — `sort :col1, :col2` for column sorts with automatic `asc`/`desc` via `"-col"` prefix convention
39
+ - Custom sort blocks: `sort(:name) { |scope| ... }`
40
+ - Default sort: `sort :name, default: "-created_at"`
41
+ - **Backend adapters** for both ActiveRecord and Mongoid (auto-detected from scope)
42
+ - `scope:` injection for pre-scoping (e.g., `current_user.posts`)
43
+ - `from_params` for binding from controller params with automatic type coercion and sort validation
44
+ - `to_params` for round-tripping query state back to URL params
45
+ - `param_key` DSL for customizing the params namespace
46
+ - ActiveModel::Naming / ActiveModel::Conversion for Rails form compatibility
47
+ - Convenience class methods: `.call`, `.count`, `.exists?`, `.any?`
48
+ - Inheritance support — filters, sorts, and scope are inherited by subclasses
49
+ - `Dex::Match` is now included in `Dex::Form` — `Ok`/`Err` are available without prefix inside forms
50
+
3
51
  ## [0.3.0] - 2026-03-03
4
52
 
5
53
  ### Added
data/README.md CHANGED
@@ -9,26 +9,28 @@ Rails patterns toolbelt. Equip to gain +4 DEX.
9
9
  Service objects with typed properties, transactions, error handling, and more.
10
10
 
11
11
  ```ruby
12
- class CreateUser < Dex::Operation
13
- prop :name, String
14
- prop :email, String
12
+ class Order::Place < Dex::Operation
13
+ prop :customer, _Ref(Customer)
14
+ prop :product, _Ref(Product)
15
+ prop :quantity, _Integer(1..)
16
+ prop? :note, String
15
17
 
16
- success _Ref(User)
17
- error :email_taken
18
+ success _Ref(Order)
19
+ error :out_of_stock
18
20
 
19
21
  def perform
20
- error!(:email_taken) if User.exists?(email: email)
22
+ error!(:out_of_stock) unless product.in_stock?
21
23
 
22
- user = User.create!(name: name, email: email)
24
+ order = Order.create!(customer: customer, product: product, quantity: quantity, note: note)
23
25
 
24
- after_commit { WelcomeMailer.with(user: user).deliver_later }
26
+ after_commit { Order::Placed.publish(order_id: order.id, total: order.total) }
25
27
 
26
- user
28
+ order
27
29
  end
28
30
  end
29
31
 
30
- user = CreateUser.call(name: "Alice", email: "alice@example.com")
31
- user.name # => "Alice"
32
+ order = Order::Place.call(customer: 42, product: 7, quantity: 2)
33
+ order.id # => 1
32
34
  ```
33
35
 
34
36
  ### What you get out of the box
@@ -36,35 +38,35 @@ user.name # => "Alice"
36
38
  **Typed properties** – powered by [literal](https://github.com/joeldrapper/literal). Plain classes, ranges, unions, arrays, nilable, and model references with auto-find:
37
39
 
38
40
  ```ruby
39
- prop :amount, _Integer(1..)
41
+ prop :quantity, _Integer(1..)
40
42
  prop :currency, _Union("USD", "EUR", "GBP")
41
- prop :user, _Ref(User) # accepts User instance or ID
42
- prop? :note, String # optional (nil by default)
43
+ prop :customer, _Ref(Customer) # accepts Customer instance or ID
44
+ prop? :note, String # optional (nil by default)
43
45
  ```
44
46
 
45
47
  **Structured errors** with `error!`, `assert!`, and `rescue_from`:
46
48
 
47
49
  ```ruby
48
- user = assert!(:not_found) { User.find_by(id: user_id) }
50
+ product = assert!(:not_found) { Product.find_by(id: product_id) }
49
51
 
50
- rescue_from Stripe::CardError, as: :card_declined
52
+ rescue_from Stripe::CardError, as: :payment_declined
51
53
  ```
52
54
 
53
55
  **Ok / Err** – pattern match on operation outcomes with `.safe.call`:
54
56
 
55
57
  ```ruby
56
- case CreateUser.new(email: email).safe.call
57
- in Ok(name:)
58
- puts "Welcome, #{name}!"
59
- in Err(code: :email_taken)
60
- puts "Already registered"
58
+ case Order::Place.new(customer: 42, product: 7, quantity: 2).safe.call
59
+ in Ok => result
60
+ redirect_to order_path(result.id)
61
+ in Err(code: :out_of_stock)
62
+ flash[:error] = "Product is out of stock"
61
63
  end
62
64
  ```
63
65
 
64
66
  **Async execution** via ActiveJob:
65
67
 
66
68
  ```ruby
67
- SendWelcomeEmail.new(user_id: 123).async(queue: "mailers").call
69
+ Order::Fulfill.new(order_id: 123).async(queue: "fulfillment").call
68
70
  ```
69
71
 
70
72
  **Transactions** on by default, **advisory locking**, **recording** to database, **callbacks**, and a customizable **pipeline** – all composable, all optional.
@@ -74,15 +76,16 @@ SendWelcomeEmail.new(user_id: 123).async(queue: "mailers").call
74
76
  First-class test helpers for Minitest:
75
77
 
76
78
  ```ruby
77
- class CreateUserTest < Minitest::Test
78
- testing CreateUser
79
+ class PlaceOrderTest < Minitest::Test
80
+ testing Order::Place
79
81
 
80
- def test_creates_user
81
- assert_operation(name: "Alice", email: "alice@example.com")
82
+ def test_places_order
83
+ assert_operation(customer: customer.id, product: product.id, quantity: 2)
82
84
  end
83
85
 
84
- def test_rejects_duplicate_email
85
- assert_operation_error(:email_taken, name: "Alice", email: "taken@example.com")
86
+ def test_rejects_out_of_stock
87
+ assert_operation_error(:out_of_stock, customer: customer.id,
88
+ product: out_of_stock_product.id, quantity: 1)
86
89
  end
87
90
  end
88
91
  ```
@@ -92,14 +95,14 @@ end
92
95
  Typed, immutable event objects with publish/subscribe, async dispatch, and causality tracing.
93
96
 
94
97
  ```ruby
95
- class OrderPlaced < Dex::Event
98
+ class Order::Placed < Dex::Event
96
99
  prop :order_id, Integer
97
100
  prop :total, BigDecimal
98
101
  prop? :coupon_code, String
99
102
  end
100
103
 
101
104
  class NotifyWarehouse < Dex::Event::Handler
102
- on OrderPlaced
105
+ on Order::Placed
103
106
  retries 3
104
107
 
105
108
  def perform
@@ -107,7 +110,7 @@ class NotifyWarehouse < Dex::Event::Handler
107
110
  end
108
111
  end
109
112
 
110
- OrderPlaced.publish(order_id: 1, total: 99.99)
113
+ Order::Placed.publish(order_id: 1, total: 99.99)
111
114
  ```
112
115
 
113
116
  ### What you get out of the box
@@ -120,7 +123,7 @@ OrderPlaced.publish(order_id: 1, total: 99.99)
120
123
 
121
124
  ```ruby
122
125
  order_placed.trace do
123
- InventoryReserved.publish(order_id: 1)
126
+ Shipment::Reserved.publish(order_id: 1)
124
127
  end
125
128
  ```
126
129
 
@@ -129,13 +132,13 @@ end
129
132
  ### Testing
130
133
 
131
134
  ```ruby
132
- class CreateOrderTest < Minitest::Test
135
+ class PlaceOrderTest < Minitest::Test
133
136
  include Dex::Event::TestHelpers
134
137
 
135
138
  def test_publishes_order_placed
136
139
  capture_events do
137
- CreateOrder.call(item_id: 1)
138
- assert_event_published(OrderPlaced, order_id: 1)
140
+ Order::Place.call(customer: customer.id, product: product.id, quantity: 2)
141
+ assert_event_published(Order::Placed)
139
142
  end
140
143
  end
141
144
  end
@@ -146,8 +149,8 @@ end
146
149
  Form objects with typed attributes, normalization, nested forms, and Rails form builder compatibility.
147
150
 
148
151
  ```ruby
149
- class OnboardingForm < Dex::Form
150
- model User
152
+ class Employee::Form < Dex::Form
153
+ model Employee
151
154
 
152
155
  attribute :first_name, :string
153
156
  attribute :last_name, :string
@@ -165,7 +168,7 @@ class OnboardingForm < Dex::Form
165
168
  end
166
169
  end
167
170
 
168
- form = OnboardingForm.new(email: " ALICE@EXAMPLE.COM ", first_name: "Alice", last_name: "Smith")
171
+ form = Employee::Form.new(email: " ALICE@EXAMPLE.COM ", first_name: "Alice", last_name: "Smith")
169
172
  form.email # => "alice@example.com"
170
173
  form.valid?
171
174
  ```
@@ -177,10 +180,10 @@ form.valid?
177
180
  **Nested forms** — `nested_one` and `nested_many` with automatic Hash coercion, `_destroy` support, and error propagation:
178
181
 
179
182
  ```ruby
180
- nested_many :documents do
181
- attribute :document_type, :string
182
- attribute :document_number, :string
183
- validates :document_type, :document_number, presence: true
183
+ nested_many :emergency_contacts do
184
+ attribute :name, :string
185
+ attribute :phone, :string
186
+ validates :name, :phone, presence: true
184
187
  end
185
188
  ```
186
189
 
@@ -188,7 +191,7 @@ end
188
191
 
189
192
  **Uniqueness validation** against the database, with scope, case-sensitivity, and current-record exclusion.
190
193
 
191
- **Multi-model forms** — when a form spans User, Employee, and Address, define a `.for` convention method to map records and a `#save` method that delegates to a `Dex::Operation`:
194
+ **Multi-model forms** — when a form spans Employee, Department, and Address, define a `.for` convention method to map records and a `#save` method that delegates to a `Dex::Operation`:
192
195
 
193
196
  ```ruby
194
197
  def save
@@ -203,24 +206,24 @@ end
203
206
 
204
207
  ## Queries
205
208
 
206
- Declarative query objects for filtering and sorting ActiveRecord relations.
209
+ Declarative query objects for filtering and sorting ActiveRecord relations and Mongoid criteria.
207
210
 
208
211
  ```ruby
209
- class UserSearch < Dex::Query
210
- scope { User.all }
212
+ class Order::Query < Dex::Query
213
+ scope { Order.all }
211
214
 
212
- prop? :name, String
213
- prop? :role, _Array(String)
214
- prop? :age_min, Integer
215
+ prop? :status, String
216
+ prop? :customer, _Ref(Customer)
217
+ prop? :total_min, Integer
215
218
 
216
- filter :name, :contains
217
- filter :role, :in
218
- filter :age_min, :gte, column: :age
219
+ filter :status
220
+ filter :customer
221
+ filter :total_min, :gte, column: :total
219
222
 
220
- sort :name, :created_at, default: "-created_at"
223
+ sort :created_at, :total, default: "-created_at"
221
224
  end
222
225
 
223
- users = UserSearch.call(name: "ali", role: %w[admin], sort: "name")
226
+ orders = Order::Query.call(status: "pending", sort: "-total")
224
227
  ```
225
228
 
226
229
  ### What you get out of the box
@@ -232,10 +235,10 @@ users = UserSearch.call(name: "ali", role: %w[admin], sort: "name")
232
235
  **`from_params`** — HTTP boundary handling with automatic coercion, blank stripping, and invalid value fallback:
233
236
 
234
237
  ```ruby
235
- class UsersController < ApplicationController
238
+ class OrdersController < ApplicationController
236
239
  def index
237
- query = UserSearch.from_params(params, scope: policy_scope(User))
238
- @users = pagy(query.resolve)
240
+ query = Order::Query.from_params(params, scope: policy_scope(Order))
241
+ @orders = pagy(query.resolve)
239
242
  end
240
243
  end
241
244
  ```
@@ -273,11 +273,18 @@ def perform
273
273
  end
274
274
  ```
275
275
 
276
- On rollback (`error!` or exception), callbacks are discarded. When no transaction is open anywhere, executes immediately. Multiple blocks run in registration order.
276
+ Callbacks are always deferred they run after the outermost operation boundary succeeds:
277
277
 
278
- **ActiveRecord:** fully nesting-aware callbacks are deferred until the outermost transaction commits, even across nested operations or ambient `ActiveRecord::Base.transaction` blocks. Requires Rails 7.2+.
278
+ - **Transactional operations:** deferred until the DB transaction commits.
279
+ - **Non-transactional operations:** queued in memory, flushed after the operation pipeline completes successfully.
280
+ - **Nested operations:** callbacks queue up and flush once at the outermost successful boundary.
281
+ - **On error (`error!` or exception):** queued callbacks are discarded.
279
282
 
280
- **Mongoid:** callbacks are deferred across nested Dex operations. Ambient `Mongoid.transaction` blocks opened outside Dex are not detected — callbacks will fire immediately in that case.
283
+ Multiple blocks run in registration order.
284
+
285
+ **ActiveRecord:** requires Rails 7.2+ (`after_all_transactions_commit`).
286
+
287
+ **Mongoid:** deferred across nested Dex operations. Ambient `Mongoid.transaction` blocks opened outside Dex are not detected — callbacks will fire immediately in that case.
281
288
 
282
289
  ---
283
290
 
@@ -371,6 +378,8 @@ end
371
378
 
372
379
  Not autoloaded — stays out of production. TestLog and stubs are auto-cleared in `setup`.
373
380
 
381
+ For Mongoid-backed operation tests, run against a MongoDB replica set (MongoDB transactions require it).
382
+
374
383
  ### Subject & Execution
375
384
 
376
385
  ```ruby
data/guides/llm/QUERY.md CHANGED
@@ -159,7 +159,7 @@ Only one default per class. Applied when no sort is provided.
159
159
 
160
160
  ### `.call`
161
161
 
162
- Returns an ActiveRecord relation:
162
+ Returns a queryable scope (`ActiveRecord::Relation` or `Mongoid::Criteria`):
163
163
 
164
164
  ```ruby
165
165
  users = UserSearch.call(name: "ali", role: %w[admin], sort: "-name")
@@ -295,7 +295,7 @@ end
295
295
 
296
296
  ## Testing
297
297
 
298
- Queries return standard ActiveRecord relations. Test them with plain Minitest:
298
+ Queries return standard scopes (`ActiveRecord::Relation` or `Mongoid::Criteria`). Test them with plain Minitest:
299
299
 
300
300
  ```ruby
301
301
  class UserSearchTest < Minitest::Test
@@ -32,7 +32,7 @@ module Dex
32
32
  )
33
33
  begin
34
34
  job = apply_options(Operation::RecordJob)
35
- job.perform_later(class_name: operation_class_name, record_id: record.id)
35
+ job.perform_later(class_name: operation_class_name, record_id: record.id.to_s)
36
36
  rescue => e
37
37
  begin
38
38
  record.destroy
@@ -53,10 +53,23 @@ module Dex
53
53
  raise LoadError, "Mongoid is required for transactions"
54
54
  end
55
55
 
56
- outermost = !Thread.current[AFTER_COMMIT_KEY]
57
- Thread.current[AFTER_COMMIT_KEY] ||= []
58
- snapshot = Thread.current[AFTER_COMMIT_KEY].length
56
+ callbacks = Thread.current[AFTER_COMMIT_KEY]
57
+ outermost = callbacks.nil?
58
+
59
+ unless outermost
60
+ snapshot = callbacks.length
61
+ begin
62
+ return block.call
63
+ rescue rollback_exception_class
64
+ callbacks.slice!(snapshot..)
65
+ return nil
66
+ rescue StandardError # rubocop:disable Style/RescueStandardError
67
+ callbacks.slice!(snapshot..)
68
+ raise
69
+ end
70
+ end
59
71
 
72
+ Thread.current[AFTER_COMMIT_KEY] = []
60
73
  block_completed = false
61
74
  result = Mongoid.transaction do
62
75
  value = block.call
@@ -64,17 +77,11 @@ module Dex
64
77
  value
65
78
  end
66
79
 
67
- if outermost && block_completed
80
+ if block_completed
68
81
  Thread.current[AFTER_COMMIT_KEY].each(&:call)
69
- elsif !block_completed
70
- # Mongoid swallowed a Rollback exception — discard callbacks from this level
71
- Thread.current[AFTER_COMMIT_KEY].slice!(snapshot..)
72
82
  end
73
83
 
74
84
  result
75
- rescue StandardError # rubocop:disable Style/RescueStandardError
76
- Thread.current[AFTER_COMMIT_KEY]&.slice!(snapshot..) unless outermost
77
- raise
78
85
  ensure
79
86
  Thread.current[AFTER_COMMIT_KEY] = nil if outermost
80
87
  end
@@ -4,26 +4,37 @@ module Dex
4
4
  module TransactionWrapper
5
5
  extend Dex::Concern
6
6
 
7
+ DEFERRED_CALLBACKS_KEY = :_dex_after_commit_queue
8
+
7
9
  def _transaction_wrap
8
- return yield unless _transaction_enabled?
10
+ deferred = Thread.current[DEFERRED_CALLBACKS_KEY]
11
+ outermost = deferred.nil?
12
+ Thread.current[DEFERRED_CALLBACKS_KEY] = [] if outermost
13
+ snapshot = Thread.current[DEFERRED_CALLBACKS_KEY].length
9
14
 
10
- interceptor = nil
11
- result = _transaction_execute do
12
- interceptor = Operation::HaltInterceptor.new { yield }
13
- raise _transaction_adapter.rollback_exception_class if interceptor.error?
14
- interceptor.result
15
+ result, interceptor = if _transaction_enabled?
16
+ _transaction_run_adapter(snapshot) { yield }
17
+ else
18
+ _transaction_run_deferred(snapshot) { yield }
15
19
  end
16
20
 
21
+ _transaction_flush_deferred if outermost
22
+
17
23
  interceptor&.rethrow!
18
24
  result
25
+ rescue # rubocop:disable Style/RescueStandardError -- explicit for clarity
26
+ Thread.current[DEFERRED_CALLBACKS_KEY]&.slice!(snapshot..)
27
+ raise
28
+ ensure
29
+ Thread.current[DEFERRED_CALLBACKS_KEY] = nil if outermost
19
30
  end
20
31
 
21
32
  def after_commit(&block)
22
33
  raise ArgumentError, "after_commit requires a block" unless block
23
34
 
24
- adapter = _transaction_adapter
25
- if adapter
26
- adapter.after_commit(&block)
35
+ deferred = Thread.current[DEFERRED_CALLBACKS_KEY]
36
+ if deferred
37
+ deferred << block
27
38
  else
28
39
  block.call
29
40
  end
@@ -65,6 +76,33 @@ module Dex
65
76
 
66
77
  private
67
78
 
79
+ def _transaction_run_adapter(snapshot)
80
+ interceptor = nil
81
+ result = _transaction_execute do
82
+ interceptor = Operation::HaltInterceptor.new { yield }
83
+ raise _transaction_adapter.rollback_exception_class if interceptor.error?
84
+ interceptor.result
85
+ end
86
+
87
+ if interceptor&.error?
88
+ Thread.current[DEFERRED_CALLBACKS_KEY]&.slice!(snapshot..)
89
+ interceptor.rethrow!
90
+ end
91
+
92
+ [result, interceptor]
93
+ end
94
+
95
+ def _transaction_run_deferred(snapshot)
96
+ interceptor = Operation::HaltInterceptor.new { yield }
97
+
98
+ if interceptor.error?
99
+ Thread.current[DEFERRED_CALLBACKS_KEY]&.slice!(snapshot..)
100
+ interceptor.rethrow!
101
+ end
102
+
103
+ [interceptor.result, interceptor]
104
+ end
105
+
68
106
  def _transaction_enabled?
69
107
  settings = self.class.settings_for(:transaction)
70
108
  return false unless settings.fetch(:enabled, true)
@@ -78,6 +116,19 @@ module Dex
78
116
  Operation::TransactionAdapter.for(adapter_name)
79
117
  end
80
118
 
119
+ def _transaction_flush_deferred
120
+ callbacks = Thread.current[DEFERRED_CALLBACKS_KEY]
121
+ return if callbacks.empty?
122
+
123
+ flush = -> { callbacks.each(&:call) }
124
+ adapter = _transaction_adapter
125
+ if adapter
126
+ adapter.after_commit(&flush)
127
+ else
128
+ flush.call
129
+ end
130
+ end
131
+
81
132
  def _transaction_execute(&block)
82
133
  _transaction_adapter.wrap(&block)
83
134
  end
data/lib/dex/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dex
4
- VERSION = "0.4.1"
4
+ VERSION = "0.5.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dexkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacek Galanciak
@@ -79,6 +79,20 @@ dependencies:
79
79
  - - ">="
80
80
  - !ruby/object:Gem::Version
81
81
  version: '6.1'
82
+ - !ruby/object:Gem::Dependency
83
+ name: ostruct
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
82
96
  - !ruby/object:Gem::Dependency
83
97
  name: actionpack
84
98
  requirement: !ruby/object:Gem::Requirement
@@ -107,6 +121,20 @@ dependencies:
107
121
  - - ">="
108
122
  - !ruby/object:Gem::Version
109
123
  version: '6.1'
124
+ - !ruby/object:Gem::Dependency
125
+ name: mongoid
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '8.0'
131
+ type: :development
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '8.0'
110
138
  - !ruby/object:Gem::Dependency
111
139
  name: sqlite3
112
140
  requirement: !ruby/object:Gem::Requirement