composables 0.0.13 → 0.0.14

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: 554939ad797fa9f0c32d52eb887c4face0534b35386a3204b37e9e4a480c5eef
4
- data.tar.gz: 9836e3797c7293361e2201a9c9326997ae267e0b9dad0941f62fc7a717234ca1
3
+ metadata.gz: 47c2141501c416c1ed6f5b106fcd771020d5d1921dba322377150a3391ac9437
4
+ data.tar.gz: bde7c23e3a3912a8e453c8126bd9ccf213d450c0ab6de0d7ef77c4411bcbbc00
5
5
  SHA512:
6
- metadata.gz: 88db2648595fa077ace47438328898f247a38e4493969954286430533c5f31b7bd47b55e3023ce0be119c2dbf978c6d352f01eb46301870cbbb59e6a98e7b5e3
7
- data.tar.gz: 583539b49c993d656c51d335f66e71de4137832c4fcaea087f81bd6339b0cf7c9d47b9981309e16f220b1367c31992f1643bdc470fed1f1ab09e3bd287780d4b
6
+ metadata.gz: c7bd6d31000591425434c14eeed4eee9eff2b3a7dfb6593c3f664c49a6480d241e766267c8c20285cb1ba8c0a1cb308cc94fddb7e26fe24abb9ab25659da1785
7
+ data.tar.gz: 27b0730ef1ff186c24111f32cc7eb97b45f75a09cdf1d0c64980d1f2a5d8d9ef20db391be6331bab7b6ad2bec736a6d1916b8fe1beb8497c6a1b8825ea634da1
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ ## [Unreleased]
2
+
3
+ - Re-audit before release: fix stale verification caches, conditional persistence, non-finite timeouts and Rails-version environment leakage during lockfile refresh.
4
+ - Document the ecosystem and every component with sanitized, tested examples.
5
+ - Require Ruby 3.2+ and Rails integrations 7.2+; refresh compatibility lockfiles.
6
+ - Enforce 100% per-file line and branch coverage across all eight gems and both CI combinations.
7
+ - Audit and harden authentication, tenancy, HTTP transport, dependency loading and release tooling.
8
+
9
+ ## [0.0.1] - 2022-01-19
10
+
11
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 Jairo Vazquez
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,43 +1,96 @@
1
1
  # Composables
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/composables`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ Composables provides small Ruby objects for services, Rails forms, HTTP clients,
4
+ ViewComponent views, tenant context, and passwordless authentication. Each gem can
5
+ be installed independently; `composables` installs the entire ecosystem.
6
+
7
+ ## Ecosystem
8
+
9
+ | Gem | Responsibility | Main interface |
10
+ | --- | --- | --- |
11
+ | [composable-core](composable-core/README.md) | Attributes, command lifecycle, composition, inheritance | `Composable::Core` concerns |
12
+ | [composable-service](composable-service/README.md) | Validated operations with results | `Composable::Service::Command` |
13
+ | [composable-form](composable-form/README.md) | Form objects and record synchronization | `Composable::Form::Command` |
14
+ | [composable-client](composable-client/README.md) | HTTP requests with callbacks | `Composable::Client::Base` |
15
+ | [composable-view](composable-view/README.md) | Validated ViewComponent inputs | `Composable::View::Component` |
16
+ | [composable-tenant](composable-tenant/README.md) | ActiveRecord tenant scopes and execution context | `tenant`, `set_tenant`, `without_tenant` |
17
+ | [composable-pwdless](composable-pwdless/README.md) | Email challenges and single-use verification | Rails engine, authentication and verification forms |
6
18
 
7
19
  ## Installation
8
20
 
9
- Add this line to your application's Gemfile:
21
+ Requires Ruby 3.2 or newer. Rails integrations require Rails/ActiveRecord 7.2 or
22
+ newer; components require ViewComponent 3.21 or newer. The tested combinations
23
+ are Ruby 3.2/Rails 7.2 and Ruby 3.4/Rails 8.1, with ViewComponent 3.x.
24
+
25
+ Add `gem "composables"` to your Gemfile and run `bundle install`. To install only a
26
+ specific capability, use its `composable-*` gem instead. Runtime dependencies are
27
+ declared by each gem; the full ecosystem includes Rails.
10
28
 
11
29
  ```ruby
12
- gem 'composables'
13
- ```
30
+ require "composables"
14
31
 
15
- And then execute:
32
+ class CalculateTotal < Composable::Service::Command
33
+ attribute :quantity, type: :integer
34
+ attribute :unit_price, type: :integer
35
+ validates :quantity, :unit_price, numericality: { greater_than: 0 }
16
36
 
17
- $ bundle install
37
+ private
18
38
 
19
- Or install it yourself as:
39
+ def save
40
+ quantity * unit_price
41
+ end
42
+ end
20
43
 
21
- $ gem install composables
44
+ operation = CalculateTotal.call(quantity: "3", unit_price: 20)
45
+ operation.success? # => true
46
+ operation.result # => 60
47
+ ```
22
48
 
23
- ## Usage
49
+ Outside Rails, the aggregate entry point loads core, forms, services and clients.
50
+ It loads Rails, ActiveRecord and ActionView integrations when their corresponding
51
+ constants are already available. Use an individual gem's explicit `require` when
52
+ loading an integration later. See each README for its installation details.
24
53
 
25
- TODO: Write usage instructions here
54
+ ## Shared lifecycle
26
55
 
27
- ## Development
56
+ `.call` returns the command object. Read `.success?`, `.failure?`, `.result`, and
57
+ `.errors`; `.call!` raises on validation failure and propagates execution errors.
58
+ Unrecognized exceptions propagate even with `.call`. Expected exceptions can be
59
+ handled with `rescue_from`; handlers should add errors when the operation fails.
60
+ Before execution, both status predicates return false.
28
61
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
62
+ Validate and authorize user input before performing side effects. Attribute
63
+ selection is not authorization. Supply explicit Rails strong parameters, and
64
+ never log credentials, challenge codes, email bodies, or arbitrary HTTP payloads.
30
65
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
66
+ ## Development and verification
32
67
 
33
- ## Contributing
68
+ ```sh
69
+ bundle install
70
+ bundle exec rake test
71
+ GEM=composable-client bundle exec rake test
72
+ ```
73
+
74
+ The default test database is an isolated SQLite file under `tmp/`. For complete
75
+ verification, including concurrent passwordless requests, use a dedicated
76
+ PostgreSQL database whose name starts with `composables_test`:
34
77
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/jairovm/composables. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/jairovm/composables/tree/main/CODE_OF_CONDUCT.md).
78
+ ```sh
79
+ createdb composables_test
80
+ DATABASE_URL=postgresql://localhost/composables_test bundle exec rake test
81
+ ```
36
82
 
37
- ## License
83
+ Tests rebuild their dedicated database tables. Never point `DATABASE_URL` at an
84
+ application database. Commands for the compatibility matrix and coverage reports
85
+ are in [Testing](docs/testing.md). All eight gems require 100% line and branch
86
+ coverage, with per-file thresholds and no production-code exclusions.
38
87
 
39
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
88
+ Build without publishing using `bundle exec rake build`; inspect outputs under
89
+ `pkg/`. Release tasks are maintainer operations that can commit, push tags and
90
+ publish packages. They are not part of tests or CI validation.
40
91
 
41
- ## Code of Conduct
92
+ ## Security and license
42
93
 
43
- Everyone interacting in the Composables project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jairovm/composables/tree/main/CODE_OF_CONDUCT.md).
94
+ See the [audit report](docs/audit.md) for fixes, evidence and integration limits.
95
+ Examples use synthetic data and reserved example domains. Composables is licensed
96
+ under [MIT](LICENSE.txt).
@@ -9,7 +9,7 @@ module Composables
9
9
  module VERSION
10
10
  MAJOR = 0
11
11
  MINOR = 0
12
- TINY = 13
12
+ TINY = 14
13
13
  PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
data/lib/composables.rb CHANGED
@@ -4,7 +4,15 @@ require "composables/version"
4
4
  require "composable/core"
5
5
  require "composable/client"
6
6
  require "composable/form"
7
- require "composable/pwdless" if defined?(Rails)
8
7
  require "composable/service"
9
- require "composable/tenant" if defined?(ActiveRecord)
10
- require "composable/view" if defined?(ActionView)
8
+
9
+ module Composables
10
+ def self.load_integrations
11
+ require "composable/pwdless" if defined?(Rails)
12
+ require "composable/tenant" if defined?(ActiveRecord)
13
+ require "composable/view" if defined?(ActionView)
14
+ end
15
+ private_class_method :load_integrations
16
+ end
17
+
18
+ Composables.send(:load_integrations)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: composables
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.13
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jairo Vazquez
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-08-09 00:00:00.000000000 Z
10
+ date: 2026-10-07 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: composable-core
@@ -15,98 +15,98 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.0.13
18
+ version: 0.0.14
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.0.13
25
+ version: 0.0.14
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: composable-form
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.0.13
32
+ version: 0.0.14
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 0.0.13
39
+ version: 0.0.14
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: composable-pwdless
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - '='
45
45
  - !ruby/object:Gem::Version
46
- version: 0.0.13
46
+ version: 0.0.14
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - '='
52
52
  - !ruby/object:Gem::Version
53
- version: 0.0.13
53
+ version: 0.0.14
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: composable-service
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - '='
59
59
  - !ruby/object:Gem::Version
60
- version: 0.0.13
60
+ version: 0.0.14
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - '='
66
66
  - !ruby/object:Gem::Version
67
- version: 0.0.13
67
+ version: 0.0.14
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: composable-client
70
70
  requirement: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - '='
73
73
  - !ruby/object:Gem::Version
74
- version: 0.0.13
74
+ version: 0.0.14
75
75
  type: :runtime
76
76
  prerelease: false
77
77
  version_requirements: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - '='
80
80
  - !ruby/object:Gem::Version
81
- version: 0.0.13
81
+ version: 0.0.14
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: composable-tenant
84
84
  requirement: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - '='
87
87
  - !ruby/object:Gem::Version
88
- version: 0.0.13
88
+ version: 0.0.14
89
89
  type: :runtime
90
90
  prerelease: false
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - '='
94
94
  - !ruby/object:Gem::Version
95
- version: 0.0.13
95
+ version: 0.0.14
96
96
  - !ruby/object:Gem::Dependency
97
97
  name: composable-view
98
98
  requirement: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - '='
101
101
  - !ruby/object:Gem::Version
102
- version: 0.0.13
102
+ version: 0.0.14
103
103
  type: :runtime
104
104
  prerelease: false
105
105
  version_requirements: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - '='
108
108
  - !ruby/object:Gem::Version
109
- version: 0.0.13
109
+ version: 0.0.14
110
110
  description: Set of composable objects to work with ruby services and forms
111
111
  email:
112
112
  - jairovm20@gmail.com
@@ -114,6 +114,8 @@ executables: []
114
114
  extensions: []
115
115
  extra_rdoc_files: []
116
116
  files:
117
+ - CHANGELOG.md
118
+ - LICENSE.txt
117
119
  - README.md
118
120
  - lib/composables.rb
119
121
  - lib/composables/gem_version.rb
@@ -132,7 +134,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
134
  requirements:
133
135
  - - ">="
134
136
  - !ruby/object:Gem::Version
135
- version: 2.7.0
137
+ version: 3.2.0
136
138
  required_rubygems_version: !ruby/object:Gem::Requirement
137
139
  requirements:
138
140
  - - ">="