operto 0.1.0 → 0.2.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: 0cf8a26aabacf6a653ef155a836d95ef727b29794a0f1fbdf1365d2306ba0a4b
4
- data.tar.gz: 300fc9d056683aa3d1cedc322b887b263b454c4449a84592875484624dafd320
3
+ metadata.gz: 53adc7fd65b6257d17d1e93c2c2123134ac92189bf176d98fb89fb50e364a1ee
4
+ data.tar.gz: 979c8c81475d4a39ff1a12c695b7a5da98de80d5e9260a9f534b9c9faf940481
5
5
  SHA512:
6
- metadata.gz: 12713010ba3c3b7b909e1c54e959bf00411647352f959862446f54c40ad443461af683c141057f0cf59e192191cb8866ee04c82bba929ddad6b7857fa3c2ae4f
7
- data.tar.gz: e609b53f901d429bc8957decbf04029e26b815e7ae266f1929d3d3000810026a10025111c9b2ab3854987d12aded73cdc23d1175a2253d15a10e4a9c12a7beaa
6
+ metadata.gz: c61aa111e25800de6e098490e30a181c202be74cc8b0758c1099f147ea306575f4d7e5b5c7d30529404f3271322fe00dad1768e2b2762d2916de733a15959ab6
7
+ data.tar.gz: 0b09cc302afb111a5dad1120eb55ba19cd9ce7220e3ace9432b6641b1a04293559a7dabddb6a3adc5e54c999b024e07cc27757229b8945a959a2206d50d98421
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 - 2026-08-17
4
+
5
+ - Add RBS type signatures for the public API.
6
+ - Add RubyGems project, changelog, and license metadata.
7
+ - Package the README, changelog, and license with the gem.
8
+ - Bound runtime dependencies to the supported major versions.
9
+
10
+ ## 0.1.0 - 2026-07-23
11
+
12
+ - Initial release of the Operto Teams API client, including the default in-memory token store.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Guestit
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,85 @@
1
+ # Operto
2
+
3
+ A Ruby client for the [Operto Teams](https://teams.operto.com) API. Every call
4
+ is an operation returning a [`Dry::Monads::Result`](https://dry-rb.org/gems/dry-monads/);
5
+ credentials and token storage are injected by the host, so the gem carries no
6
+ framework dependency.
7
+
8
+ ## Installation
9
+
10
+ ```ruby
11
+ # Gemfile
12
+ gem 'operto', '~> 0.2.0'
13
+ ```
14
+
15
+ ```sh
16
+ bundle install
17
+ ```
18
+
19
+ ## Configuration
20
+
21
+ Configure once at boot with your API credentials and a token store. In Rails,
22
+ put this in `config/initializers/operto.rb`:
23
+
24
+ ```ruby
25
+ Rails.application.config.to_prepare do
26
+ Operto.configure do |config|
27
+ config.client_id = Rails.application.credentials.dig(:operto, :client_id)
28
+ config.secret = Rails.application.credentials.dig(:operto, :secret)
29
+ config.token_store = MyTokenStore.new
30
+ end
31
+ end
32
+ ```
33
+
34
+ ### Token store
35
+
36
+ The gem defaults to an in-memory `Operto::MemoryTokenStore` (fine for a single
37
+ long-running process — the token re-issues after a restart). For shared or
38
+ persistent storage, provide your own store: the gem performs the OAuth
39
+ login/refresh and delegates persistence to it via four methods:
40
+
41
+ | Method | Returns / does |
42
+ | --- | --- |
43
+ | `active` | the current non-expired token, or `nil` |
44
+ | `refreshable` | a token whose refresh token is still valid, or `nil` |
45
+ | `save(access_token:, expires_at:, refresh_token: nil, refresh_expires_at: nil)` | persist and return the token |
46
+ | `clear` | drop the cached token (called after a `401`) |
47
+
48
+ A token responds to `access_token`, `refresh_token`, `refresh_expires_at`, and
49
+ `expired?`.
50
+
51
+ ## Usage
52
+
53
+ ```ruby
54
+ Operto::Tasks::Create.new.call(
55
+ attributes: {
56
+ house_id: '110784',
57
+ rule_id: '27986',
58
+ name: 'Deep clean',
59
+ start_date: Time.zone.parse('2026-01-01 09:00'),
60
+ end_date: Time.zone.parse('2026-01-02 09:00')
61
+ }
62
+ )
63
+ # => Success({ task_id: 44683131 })
64
+ ```
65
+
66
+ `#call` returns a `Result`; `#call!` unwraps it and raises the underlying
67
+ failure. Operations are grouped by resource:
68
+
69
+ - `Operto::Tasks::{Create,Update,Index}`
70
+ - `Operto::StaffTasks::{Create,Destroy}` · `Operto::StaffTaskTimes::Index`
71
+ - `Operto::Issues::{Index,Close}` · `Operto::Homes::Index` · `Operto::Staff::Index`
72
+
73
+ ## Development
74
+
75
+ ```sh
76
+ bundle install
77
+ bundle exec rake # spec + rubocop
78
+ ```
79
+
80
+ HTTP interactions are recorded with [VCR](https://github.com/vcr/vcr); specs run
81
+ offline against `spec/fixtures/cassettes`.
82
+
83
+ ## License
84
+
85
+ Released under the [MIT License](LICENSE).
@@ -1,3 +1,3 @@
1
1
  module Operto
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
data/sig/operto.rbs ADDED
@@ -0,0 +1,112 @@
1
+ # Public API of the gem, mirroring the inline `# @rbs` annotations in lib/.
2
+ # Shipped with the gem so host apps pick it up through `rbs collection`.
3
+ module Operto
4
+ VERSION: ::String
5
+
6
+ def self.configure: () { (Config) -> void } -> void
7
+ def self.config: () -> Config
8
+
9
+ class Error < ::StandardError
10
+ end
11
+
12
+ # Raised by operations for malformed arguments before any network call.
13
+ class ArgumentError < Error
14
+ end
15
+
16
+ class Config
17
+ attr_accessor client_id: ::String?
18
+ attr_accessor secret: ::String?
19
+ attr_accessor base_url: ::String
20
+
21
+ # Duck-typed: the host may inject its own store (see MemoryTokenStore).
22
+ attr_accessor token_store: untyped
23
+ end
24
+
25
+ class MemoryTokenStore
26
+ REFRESH_BUFFER: ::Integer
27
+
28
+ def active: () -> untyped
29
+ def refreshable: () -> untyped
30
+ def save: (access_token: ::String, expires_at: ::Time, ?refresh_token: ::String?, ?refresh_expires_at: ::Time?) -> untyped
31
+ def clear: () -> nil
32
+ end
33
+
34
+ module IssueTypes
35
+ ISSUE_TYPES: ::Hash[::Integer, ::String]
36
+ end
37
+
38
+ # #call! returns the same Result as #call, raising the failure instead of
39
+ # wrapping it — hence the `alias call! call` on every operation below.
40
+ module Operation
41
+ def call!: (*untyped, **untyped) -> untyped
42
+ end
43
+
44
+ module AccessTokens
45
+ class Upsert
46
+ def call: () -> ::Dry::Monads::Result[untyped]
47
+ alias call! call
48
+ end
49
+ end
50
+
51
+ module Tasks
52
+ class Create
53
+ def call: (attributes: ::Hash[::Symbol, untyped]) -> ::Dry::Monads::Result[::Hash[::Symbol, untyped]]
54
+ alias call! call
55
+ end
56
+
57
+ class Update
58
+ def call: (task_id: ::String, attributes: ::Hash[::Symbol, untyped]) -> ::Dry::Monads::Result[::Hash[::Symbol, untyped]]
59
+ alias call! call
60
+ end
61
+
62
+ class Index
63
+ def call: (?attributes: ::Hash[::Symbol, untyped], ?skip: ::Integer, ?take: ::Integer) -> ::Dry::Monads::Result[::Hash[::Symbol, untyped]]
64
+ alias call! call
65
+ end
66
+ end
67
+
68
+ module StaffTasks
69
+ class Create
70
+ def call: (task_id: ::String, staff_id: ::String, property_id: ::String) -> ::Dry::Monads::Result[::Hash[::Symbol, untyped]]
71
+ alias call! call
72
+ end
73
+
74
+ class Destroy
75
+ def call: (staff_task_id: ::String) -> ::Dry::Monads::Result[bool]
76
+ alias call! call
77
+ end
78
+ end
79
+
80
+ module StaffTaskTimes
81
+ class Index
82
+ def call: (?attributes: ::Hash[::Symbol, untyped], ?skip: ::Integer, ?take: ::Integer) -> ::Dry::Monads::Result[::Hash[::Symbol, untyped]]
83
+ alias call! call
84
+ end
85
+ end
86
+
87
+ module Issues
88
+ class Index
89
+ def call: (start_date: ::Date, ?skip: ::Integer, ?take: ::Integer) -> ::Dry::Monads::Result[::Hash[::Symbol, untyped]]
90
+ alias call! call
91
+ end
92
+
93
+ class Close
94
+ def call: (issue_id: ::Integer | ::String) -> ::Dry::Monads::Result[::Hash[::Symbol, untyped]]
95
+ alias call! call
96
+ end
97
+ end
98
+
99
+ module Homes
100
+ class Index
101
+ def call: (?skip: ::Integer, ?take: ::Integer) -> ::Dry::Monads::Result[::Hash[::Symbol, untyped]]
102
+ alias call! call
103
+ end
104
+ end
105
+
106
+ module Staff
107
+ class Index
108
+ def call: (?skip: ::Integer, ?take: ::Integer) -> ::Dry::Monads::Result[::Hash[::Symbol, untyped]]
109
+ alias call! call
110
+ end
111
+ end
112
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: operto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guestit
@@ -13,78 +13,81 @@ dependencies:
13
13
  name: activesupport
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - ">="
16
+ - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '0'
18
+ version: '8.1'
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'
25
+ version: '8.1'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: dry-monads
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
- - - ">="
30
+ - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: '0'
32
+ version: '1.10'
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'
39
+ version: '1.10'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: faraday
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - ">="
44
+ - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '0'
46
+ version: '2.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'
53
+ version: '2.14'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: faraday-retry
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - ">="
58
+ - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '0'
60
+ version: '2.4'
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'
67
+ version: '2.4'
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: oj
70
70
  requirement: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - ">="
72
+ - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '0'
74
+ version: '3.17'
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'
81
+ version: '3.17'
82
82
  description: HTTP client and operations for the Operto Teams API, decoupled from the
83
83
  host application.
84
84
  executables: []
85
85
  extensions: []
86
86
  extra_rdoc_files: []
87
87
  files:
88
+ - CHANGELOG.md
89
+ - LICENSE
90
+ - README.md
88
91
  - lib/operto.rb
89
92
  - lib/operto/access_tokens/upsert.rb
90
93
  - lib/operto/client.rb
@@ -106,8 +109,14 @@ files:
106
109
  - lib/operto/tasks/shared.rb
107
110
  - lib/operto/tasks/update.rb
108
111
  - lib/operto/version.rb
109
- licenses: []
112
+ - sig/operto.rbs
113
+ homepage: https://github.com/guestitab/operto-client
114
+ licenses:
115
+ - MIT
110
116
  metadata:
117
+ allowed_push_host: https://rubygems.org
118
+ source_code_uri: https://github.com/guestitab/operto-client
119
+ changelog_uri: https://github.com/guestitab/operto-client/blob/main/CHANGELOG.md
111
120
  rubygems_mfa_required: 'true'
112
121
  rdoc_options: []
113
122
  require_paths:
@@ -123,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
132
  - !ruby/object:Gem::Version
124
133
  version: '0'
125
134
  requirements: []
126
- rubygems_version: 4.0.15
135
+ rubygems_version: 4.0.17
127
136
  specification_version: 4
128
137
  summary: Client for the Operto Teams API
129
138
  test_files: []