composables 0.0.12 → 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: 0cb0dcded73ea2d659f134196e651320ddfdc71d97099ba533ae2a30dc7d46db
4
- data.tar.gz: e44386c8c869cedecd904aa70163e32a0f2300382ac63e8821da85f76611a887
3
+ metadata.gz: 47c2141501c416c1ed6f5b106fcd771020d5d1921dba322377150a3391ac9437
4
+ data.tar.gz: bde7c23e3a3912a8e453c8126bd9ccf213d450c0ab6de0d7ef77c4411bcbbc00
5
5
  SHA512:
6
- metadata.gz: 57c97d8a2669ef0fe67e75a77b3702e2dc47f5922b24e6779be0d864c495c39f082c521be45bb6a1d9e9906d1a911c665a4a3c56a7ff68130084a40bc0e83434
7
- data.tar.gz: 378f9f0a0356bf0b52db61112897f6a90e058e5b4265a24fd9ebf297f310eb237bccdadee338c2ca30f084e13ec4f244bb3eba3c6d63a455bf921c81a18e8c43
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 = 12
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,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: composables
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jairo Vazquez
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-03-02 00:00:00.000000000 Z
10
+ date: 2026-10-07 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: composable-core
@@ -16,98 +15,98 @@ dependencies:
16
15
  requirements:
17
16
  - - '='
18
17
  - !ruby/object:Gem::Version
19
- version: 0.0.12
18
+ version: 0.0.14
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - '='
25
24
  - !ruby/object:Gem::Version
26
- version: 0.0.12
25
+ version: 0.0.14
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: composable-form
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - '='
32
31
  - !ruby/object:Gem::Version
33
- version: 0.0.12
32
+ version: 0.0.14
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - '='
39
38
  - !ruby/object:Gem::Version
40
- version: 0.0.12
39
+ version: 0.0.14
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: composable-pwdless
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
44
  - - '='
46
45
  - !ruby/object:Gem::Version
47
- version: 0.0.12
46
+ version: 0.0.14
48
47
  type: :runtime
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
51
  - - '='
53
52
  - !ruby/object:Gem::Version
54
- version: 0.0.12
53
+ version: 0.0.14
55
54
  - !ruby/object:Gem::Dependency
56
55
  name: composable-service
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
58
  - - '='
60
59
  - !ruby/object:Gem::Version
61
- version: 0.0.12
60
+ version: 0.0.14
62
61
  type: :runtime
63
62
  prerelease: false
64
63
  version_requirements: !ruby/object:Gem::Requirement
65
64
  requirements:
66
65
  - - '='
67
66
  - !ruby/object:Gem::Version
68
- version: 0.0.12
67
+ version: 0.0.14
69
68
  - !ruby/object:Gem::Dependency
70
69
  name: composable-client
71
70
  requirement: !ruby/object:Gem::Requirement
72
71
  requirements:
73
72
  - - '='
74
73
  - !ruby/object:Gem::Version
75
- version: 0.0.12
74
+ version: 0.0.14
76
75
  type: :runtime
77
76
  prerelease: false
78
77
  version_requirements: !ruby/object:Gem::Requirement
79
78
  requirements:
80
79
  - - '='
81
80
  - !ruby/object:Gem::Version
82
- version: 0.0.12
81
+ version: 0.0.14
83
82
  - !ruby/object:Gem::Dependency
84
83
  name: composable-tenant
85
84
  requirement: !ruby/object:Gem::Requirement
86
85
  requirements:
87
86
  - - '='
88
87
  - !ruby/object:Gem::Version
89
- version: 0.0.12
88
+ version: 0.0.14
90
89
  type: :runtime
91
90
  prerelease: false
92
91
  version_requirements: !ruby/object:Gem::Requirement
93
92
  requirements:
94
93
  - - '='
95
94
  - !ruby/object:Gem::Version
96
- version: 0.0.12
95
+ version: 0.0.14
97
96
  - !ruby/object:Gem::Dependency
98
97
  name: composable-view
99
98
  requirement: !ruby/object:Gem::Requirement
100
99
  requirements:
101
100
  - - '='
102
101
  - !ruby/object:Gem::Version
103
- version: 0.0.12
102
+ version: 0.0.14
104
103
  type: :runtime
105
104
  prerelease: false
106
105
  version_requirements: !ruby/object:Gem::Requirement
107
106
  requirements:
108
107
  - - '='
109
108
  - !ruby/object:Gem::Version
110
- version: 0.0.12
109
+ version: 0.0.14
111
110
  description: Set of composable objects to work with ruby services and forms
112
111
  email:
113
112
  - jairovm20@gmail.com
@@ -115,6 +114,8 @@ executables: []
115
114
  extensions: []
116
115
  extra_rdoc_files: []
117
116
  files:
117
+ - CHANGELOG.md
118
+ - LICENSE.txt
118
119
  - README.md
119
120
  - lib/composables.rb
120
121
  - lib/composables/gem_version.rb
@@ -126,7 +127,6 @@ metadata:
126
127
  homepage_uri: https://github.com/jairovm/composables
127
128
  source_code_uri: https://github.com/jairovm/composables
128
129
  changelog_uri: https://github.com/jairovm/composables/tree/main/CHANGELOG.md
129
- post_install_message:
130
130
  rdoc_options: []
131
131
  require_paths:
132
132
  - lib
@@ -134,15 +134,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - ">="
136
136
  - !ruby/object:Gem::Version
137
- version: 2.7.0
137
+ version: 3.2.0
138
138
  required_rubygems_version: !ruby/object:Gem::Requirement
139
139
  requirements:
140
140
  - - ">="
141
141
  - !ruby/object:Gem::Version
142
142
  version: '0'
143
143
  requirements: []
144
- rubygems_version: 3.5.5
145
- signing_key:
144
+ rubygems_version: 3.6.2
146
145
  specification_version: 4
147
146
  summary: Composable ActiveModel Objects
148
147
  test_files: []